mb/system76/cml-u/dt: Make use of chipset devicetree
[coreboot.git] / src / soc / qualcomm / qcs405 / clock.c
bloba3a41c739b0c00e17a8b647f9b7f6b811b035e11
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
4 #include <device/mmio.h>
5 #include <types.h>
6 #include <commonlib/helpers.h>
7 #include <soc/clock.h>
9 #define DIV(div) (div ? (2*div - 1) : 0)
10 #define HALF_DIVIDER(div2x) (div2x ? (div2x - 1) : 0)
12 struct clock_config uart_cfg[] = {
14 .hz = 1843200,
15 .hw_ctl = 0x0,
16 .src = SRC_GPLL0_MAIN_800MHZ,
17 .div = DIV(0),
18 .m = 36,
19 .n = 15625,
20 .d_2 = 15625,
23 .hz = 3686400,
24 .hw_ctl = 0x0,
25 .src = SRC_GPLL0_MAIN_800MHZ,
26 .div = DIV(0),
27 .m = 72,
28 .n = 15625,
29 .d_2 = 15625,
33 struct clock_config i2c_cfg[] = {
35 .hz = 19200000,
36 .hw_ctl = 0x0,
37 .src = SRC_XO_19_2MHZ,
38 .div = DIV(0),
41 .hz = 50000000,
42 .hw_ctl = 0x0,
43 .src = SRC_GPLL0_MAIN_800MHZ,
44 .div = DIV(32),
48 struct clock_config spi_cfg[] = {
50 .hz = 1000000,
51 .hw_ctl = 0x0,
52 .src = SRC_XO_19_2MHZ,
53 .div = DIV(48),
56 .hz = 7372800,
57 .src = SRC_GPLL0_MAIN_800MHZ,
58 .div = DIV(1),
59 .m = 144,
60 .n = 15625,
61 .d_2 = 15625,
64 .hz = 19200000,
65 .hw_ctl = 0x0,
66 .src = SRC_XO_19_2MHZ,
67 .div = DIV(0),
70 .hz = 30000000,
71 .hw_ctl = 0x0,
72 .src = SRC_XO_19_2MHZ,
73 .div = DIV(0),
76 .hz = 50000000,
77 .hw_ctl = 0x0,
78 .src = SRC_GPLL0_MAIN_800MHZ,
79 .div = DIV(32),
83 static int clock_configure_gpll0(void)
85 /* Keep existing GPLL0 configuration, in RUN mode @800Mhz. */
86 setbits32(&gcc->gpll0.user_ctl,
87 1 << CLK_CTL_GPLL_PLLOUT_LV_EARLY_SHFT |
88 1 << CLK_CTL_GPLL_PLLOUT_AUX2_SHFT |
89 1 << CLK_CTL_GPLL_PLLOUT_AUX_SHFT |
90 1 << CLK_CTL_GPLL_PLLOUT_MAIN_SHFT);
91 return 0;
94 static int clock_configure_mnd(struct qcs405_clock *clk, uint32_t m, uint32_t n,
95 uint32_t d_2)
97 uint32_t reg_val;
99 /* Configure Root Clock Generator(RCG) for Dual Edge Mode */
100 reg_val = read32(&clk->rcg.cfg);
101 reg_val |= (2 << CLK_CTL_CFG_MODE_SHFT);
102 write32(&clk->rcg.cfg, reg_val);
104 /* Set M/N/D config */
105 write32(&clk->m, m & CLK_CTL_RCG_MND_BMSK);
106 write32(&clk->n, ~(n-m) & CLK_CTL_RCG_MND_BMSK);
107 write32(&clk->d_2, ~(d_2) & CLK_CTL_RCG_MND_BMSK);
109 return 0;
112 static int clock_configure(struct qcs405_clock *clk,
113 struct clock_config *clk_cfg,
114 uint32_t hz, uint32_t num_perfs)
116 uint32_t reg_val;
117 uint32_t idx;
119 for (idx = 0; idx < num_perfs; idx++)
120 if (hz <= clk_cfg[idx].hz)
121 break;
123 reg_val = (clk_cfg[idx].src << CLK_CTL_CFG_SRC_SEL_SHFT) |
124 (clk_cfg[idx].div << CLK_CTL_CFG_SRC_DIV_SHFT);
126 /* Set clock config */
127 write32(&clk->rcg.cfg, reg_val);
129 if (clk_cfg[idx].m != 0)
130 clock_configure_mnd(clk, clk_cfg[idx].m, clk_cfg[idx].n,
131 clk_cfg[idx].d_2);
133 /* Commit config to RCG*/
134 setbits32(&clk->rcg.cmd, BIT(CLK_CTL_CMD_UPDATE_SHFT));
136 return 0;
139 static bool clock_is_off(void *cbcr_addr)
141 return (read32(cbcr_addr) & CLK_CTL_CBC_CLK_OFF_BMSK);
144 static int clock_enable_vote(void *cbcr_addr, void *vote_addr,
145 uint32_t vote_bit)
147 /* Set clock vote bit */
148 setbits32(vote_addr, BIT(vote_bit));
150 /* Ensure clock is enabled */
151 while (clock_is_off(cbcr_addr));
153 return 0;
156 static int clock_enable(void *cbcr_addr)
158 /* Set clock enable bit */
159 setbits32(cbcr_addr, BIT(CLK_CTL_CBC_CLK_EN_SHFT));
161 /* Ensure clock is enabled */
162 while (clock_is_off(cbcr_addr))
165 return 0;
168 static int clock_disable(void *cbcr_addr)
170 /* Set clock enable bit */
171 clrbits32(cbcr_addr, BIT(CLK_CTL_CBC_CLK_EN_SHFT));
172 return 0;
175 int clock_reset_bcr(void *bcr_addr, bool reset)
177 struct qcs405_bcr *bcr = bcr_addr;
179 if (reset)
180 setbits32(&bcr->bcr, BIT(CLK_CTL_BCR_BLK_ARES_SHFT));
181 else
182 clrbits32(&bcr->bcr, BIT(CLK_CTL_BCR_BLK_ARES_SHFT));
184 return 0;
187 void clock_configure_uart(uint32_t hz)
189 struct qcs405_clock *uart_clk = (struct qcs405_clock *)
190 &gcc->blsp1_uart2_apps_clk;
192 clock_configure(uart_clk, uart_cfg, hz, ARRAY_SIZE(uart_cfg));
195 void clock_configure_spi(int blsp, int qup, uint32_t hz)
197 struct qcs405_clock *spi_clk = 0;
199 if (blsp == 1) {
200 switch (qup) {
201 case 0:
202 spi_clk = (struct qcs405_clock *)
203 &gcc->blsp1_qup0_spi_clk;
204 break;
205 case 1:
206 spi_clk = (struct qcs405_clock *)
207 &gcc->blsp1_qup1_spi_clk;
208 break;
209 case 2:
210 spi_clk = (struct qcs405_clock *)
211 &gcc->blsp1_qup2_spi_clk;
212 break;
213 case 3:
214 spi_clk = (struct qcs405_clock *)
215 &gcc->blsp1_qup3_spi_clk;
216 break;
217 case 4:
218 spi_clk = (struct qcs405_clock *)
219 &gcc->blsp1_qup4_spi_clk;
220 break;
221 default:
222 printk(BIOS_ERR, "Invalid QUP %d\n", qup);
223 return;
225 } else if (blsp == 2) {
226 spi_clk = (struct qcs405_clock *)&gcc->blsp2_qup0_spi_clk;
227 } else {
228 printk(BIOS_ERR, "BLSP %d not supported\n", blsp);
229 return;
232 clock_configure(spi_clk, spi_cfg, hz, ARRAY_SIZE(spi_cfg));
235 void clock_configure_i2c(uint32_t hz)
237 struct qcs405_clock *i2c_clk =
238 (struct qcs405_clock *)&gcc->blsp1_qup1_i2c_clk;
240 clock_configure(i2c_clk, i2c_cfg, hz, ARRAY_SIZE(i2c_cfg));
243 void clock_enable_uart(void)
245 clock_enable(&gcc->blsp1_uart2_apps_cbcr);
248 void clock_disable_uart(void)
250 clock_disable(&gcc->blsp1_uart2_apps_cbcr);
253 void clock_enable_spi(int blsp, int qup)
255 if (blsp == 1) {
256 switch (qup) {
257 case 0:
258 clock_enable(&gcc->blsp1_qup0_spi_apps_cbcr);
259 break;
260 case 1:
261 clock_enable(&gcc->blsp1_qup1_spi_apps_cbcr);
262 break;
263 case 2:
264 clock_enable(&gcc->blsp1_qup2_spi_apps_cbcr);
265 break;
266 case 3:
267 clock_enable(&gcc->blsp1_qup3_spi_apps_cbcr);
268 break;
269 case 4:
270 clock_enable(&gcc->blsp1_qup4_spi_apps_cbcr);
271 break;
273 } else if (blsp == 2)
274 clock_enable(&gcc->blsp2_qup0_spi_apps_cbcr);
275 else
276 printk(BIOS_ERR, "BLSP%d not supported\n", blsp);
279 void clock_disable_spi(int blsp, int qup)
281 if (blsp == 1) {
282 switch (qup) {
283 case 0:
284 clock_enable(&gcc->blsp1_qup0_spi_apps_cbcr);
285 break;
286 case 1:
287 clock_enable(&gcc->blsp1_qup1_spi_apps_cbcr);
288 break;
289 case 2:
290 clock_enable(&gcc->blsp1_qup2_spi_apps_cbcr);
291 break;
292 case 3:
293 clock_enable(&gcc->blsp1_qup3_spi_apps_cbcr);
294 break;
295 case 4:
296 clock_enable(&gcc->blsp1_qup4_spi_apps_cbcr);
297 break;
299 } else if (blsp == 2)
300 clock_enable(&gcc->blsp2_qup0_spi_apps_cbcr);
301 else
302 printk(BIOS_ERR, "BLSP%d not supported\n", blsp);
305 void clock_enable_i2c(void)
307 clock_enable(&gcc->blsp1_qup1_i2c_apps_cbcr);
310 void clock_disable_i2c(void)
312 clock_disable(&gcc->blsp1_qup1_i2c_apps_cbcr);
315 void clock_init(void)
317 clock_configure_gpll0();
318 clock_enable_vote(&gcc->blsp1_ahb_cbcr,
319 &gcc->gcc_apcs_clock_branch_en_vote,
320 BLSP1_AHB_CLK_ENA);
322 clock_enable_vote(&gcc->blsp2_ahb_cbcr,
323 &gcc->gcc_apcs_clock_branch_en_vote,
324 BLSP2_AHB_CLK_ENA);