blob: a7a43f69b9b3004d60169ee48ba08fa584214e2e [file] [log] [blame]
Dzmitry Sankouski038f2b92021-10-17 13:44:30 +03001// SPDX-License-Identifier: BSD-3-Clause
2/*
3 * Clock drivers for Qualcomm SDM845
4 *
5 * (C) Copyright 2017 Jorge Ramirez Ortiz <jorge.ramirez-ortiz@linaro.org>
6 * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com>
7 *
8 * Based on Little Kernel driver, simplified
9 */
10
11#include <common.h>
12#include <clk-uclass.h>
13#include <dm.h>
14#include <errno.h>
15#include <asm/io.h>
16#include <linux/bitops.h>
Sumit Garg8bdffc32022-07-12 12:42:06 +053017#include <dt-bindings/clock/qcom,gcc-sdm845.h>
Konrad Dybcio6c0b8442023-11-07 12:41:01 +000018
Caleb Connolly878b26a2023-11-07 12:40:59 +000019#include "clock-qcom.h"
Dzmitry Sankouski038f2b92021-10-17 13:44:30 +030020
21#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
22
23struct freq_tbl {
24 uint freq;
25 uint src;
26 u8 pre_div;
27 u16 m;
28 u16 n;
29};
30
31static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
32 F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625),
33 F(14745600, CFG_CLK_SRC_GPLL0_EVEN, 1, 768, 15625),
34 F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
35 F(29491200, CFG_CLK_SRC_GPLL0_EVEN, 1, 1536, 15625),
36 F(32000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 75),
37 F(48000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 25),
38 F(64000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 16, 75),
39 F(80000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 15),
40 F(96000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 25),
41 F(100000000, CFG_CLK_SRC_GPLL0_EVEN, 3, 0, 0),
42 F(102400000, CFG_CLK_SRC_GPLL0_EVEN, 1, 128, 375),
43 F(112000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 28, 75),
44 F(117964800, CFG_CLK_SRC_GPLL0_EVEN, 1, 6144, 15625),
45 F(120000000, CFG_CLK_SRC_GPLL0_EVEN, 2.5, 0, 0),
46 F(128000000, CFG_CLK_SRC_GPLL0, 1, 16, 75),
47 { }
48};
49
50static const struct bcr_regs uart2_regs = {
51 .cfg_rcgr = SE9_UART_APPS_CFG_RCGR,
52 .cmd_rcgr = SE9_UART_APPS_CMD_RCGR,
53 .M = SE9_UART_APPS_M,
54 .N = SE9_UART_APPS_N,
55 .D = SE9_UART_APPS_D,
56};
57
58const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate)
59{
60 if (!f)
61 return NULL;
62
63 if (!f->freq)
64 return f;
65
66 for (; f->freq; f++)
67 if (rate <= f->freq)
68 return f;
69
70 /* Default to our fastest rate */
71 return f - 1;
72}
73
74static int clk_init_uart(struct msm_clk_priv *priv, uint rate)
75{
76 const struct freq_tbl *freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate);
77
78 clk_rcg_set_rate_mnd(priv->base, &uart2_regs,
79 freq->pre_div, freq->m, freq->n, freq->src);
80
81 return 0;
82}
83
84ulong msm_set_rate(struct clk *clk, ulong rate)
85{
86 struct msm_clk_priv *priv = dev_get_priv(clk->dev);
87
88 switch (clk->id) {
Sumit Garg8bdffc32022-07-12 12:42:06 +053089 case GCC_QUPV3_WRAP1_S1_CLK: /*UART2*/
Dzmitry Sankouski038f2b92021-10-17 13:44:30 +030090 return clk_init_uart(priv, rate);
91 default:
92 return 0;
93 }
94}
Sumit Garg1d1ca6e2022-08-04 19:57:14 +053095
96int msm_enable(struct clk *clk)
97{
98 return 0;
99}
Konrad Dybcio6c0b8442023-11-07 12:41:01 +0000100
101static const struct qcom_reset_map sdm845_gcc_resets[] = {
102 [GCC_QUPV3_WRAPPER_0_BCR] = { 0x17000 },
103 [GCC_QUPV3_WRAPPER_1_BCR] = { 0x18000 },
104 [GCC_QUSB2PHY_PRIM_BCR] = { 0x12000 },
105 [GCC_QUSB2PHY_SEC_BCR] = { 0x12004 },
106 [GCC_SDCC2_BCR] = { 0x14000 },
107 [GCC_SDCC4_BCR] = { 0x16000 },
108 [GCC_UFS_CARD_BCR] = { 0x75000 },
109 [GCC_UFS_PHY_BCR] = { 0x77000 },
110 [GCC_USB30_PRIM_BCR] = { 0xf000 },
111 [GCC_USB30_SEC_BCR] = { 0x10000 },
112 [GCC_USB3_PHY_PRIM_BCR] = { 0x50000 },
113 [GCC_USB3PHY_PHY_PRIM_BCR] = { 0x50004 },
114 [GCC_USB3_DP_PHY_PRIM_BCR] = { 0x50008 },
115 [GCC_USB3_PHY_SEC_BCR] = { 0x5000c },
116 [GCC_USB3PHY_PHY_SEC_BCR] = { 0x50010 },
117 [GCC_USB3_DP_PHY_SEC_BCR] = { 0x50014 },
118 [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 },
119};
120
121static const struct msm_clk_data qcs404_gcc_data = {
122 .resets = sdm845_gcc_resets,
123 .num_resets = ARRAY_SIZE(sdm845_gcc_resets),
124};
125
126static const struct udevice_id gcc_sdm845_of_match[] = {
127 {
128 .compatible = "qcom,gcc-sdm845",
129 .data = (ulong)&qcs404_gcc_data,
130 },
131 { }
132};
133
134U_BOOT_DRIVER(gcc_sdm845) = {
135 .name = "gcc_sdm845",
136 .id = UCLASS_NOP,
137 .of_match = gcc_sdm845_of_match,
138 .bind = qcom_cc_bind,
139 .flags = DM_FLAG_PRE_RELOC,
140};