1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
4 #include <device/mmio.h>
6 #include <commonlib/helpers.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
[] = {
16 .src
= SRC_GPLL0_MAIN_800MHZ
,
25 .src
= SRC_GPLL0_MAIN_800MHZ
,
33 struct clock_config i2c_cfg
[] = {
37 .src
= SRC_XO_19_2MHZ
,
43 .src
= SRC_GPLL0_MAIN_800MHZ
,
48 struct clock_config spi_cfg
[] = {
52 .src
= SRC_XO_19_2MHZ
,
57 .src
= SRC_GPLL0_MAIN_800MHZ
,
66 .src
= SRC_XO_19_2MHZ
,
72 .src
= SRC_XO_19_2MHZ
,
78 .src
= SRC_GPLL0_MAIN_800MHZ
,
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
);
94 static int clock_configure_mnd(struct qcs405_clock
*clk
, uint32_t m
, uint32_t n
,
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
);
112 static int clock_configure(struct qcs405_clock
*clk
,
113 struct clock_config
*clk_cfg
,
114 uint32_t hz
, uint32_t num_perfs
)
119 for (idx
= 0; idx
< num_perfs
; idx
++)
120 if (hz
<= clk_cfg
[idx
].hz
)
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
,
133 /* Commit config to RCG*/
134 setbits32(&clk
->rcg
.cmd
, BIT(CLK_CTL_CMD_UPDATE_SHFT
));
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
,
147 /* Set clock vote bit */
148 setbits32(vote_addr
, BIT(vote_bit
));
150 /* Ensure clock is enabled */
151 while (clock_is_off(cbcr_addr
));
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
))
168 static int clock_disable(void *cbcr_addr
)
170 /* Set clock enable bit */
171 clrbits32(cbcr_addr
, BIT(CLK_CTL_CBC_CLK_EN_SHFT
));
175 int clock_reset_bcr(void *bcr_addr
, bool reset
)
177 struct qcs405_bcr
*bcr
= bcr_addr
;
180 setbits32(&bcr
->bcr
, BIT(CLK_CTL_BCR_BLK_ARES_SHFT
));
182 clrbits32(&bcr
->bcr
, BIT(CLK_CTL_BCR_BLK_ARES_SHFT
));
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;
202 spi_clk
= (struct qcs405_clock
*)
203 &gcc
->blsp1_qup0_spi_clk
;
206 spi_clk
= (struct qcs405_clock
*)
207 &gcc
->blsp1_qup1_spi_clk
;
210 spi_clk
= (struct qcs405_clock
*)
211 &gcc
->blsp1_qup2_spi_clk
;
214 spi_clk
= (struct qcs405_clock
*)
215 &gcc
->blsp1_qup3_spi_clk
;
218 spi_clk
= (struct qcs405_clock
*)
219 &gcc
->blsp1_qup4_spi_clk
;
222 printk(BIOS_ERR
, "Invalid QUP %d\n", qup
);
225 } else if (blsp
== 2) {
226 spi_clk
= (struct qcs405_clock
*)&gcc
->blsp2_qup0_spi_clk
;
228 printk(BIOS_ERR
, "BLSP %d not supported\n", blsp
);
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
)
258 clock_enable(&gcc
->blsp1_qup0_spi_apps_cbcr
);
261 clock_enable(&gcc
->blsp1_qup1_spi_apps_cbcr
);
264 clock_enable(&gcc
->blsp1_qup2_spi_apps_cbcr
);
267 clock_enable(&gcc
->blsp1_qup3_spi_apps_cbcr
);
270 clock_enable(&gcc
->blsp1_qup4_spi_apps_cbcr
);
273 } else if (blsp
== 2)
274 clock_enable(&gcc
->blsp2_qup0_spi_apps_cbcr
);
276 printk(BIOS_ERR
, "BLSP%d not supported\n", blsp
);
279 void clock_disable_spi(int blsp
, int qup
)
284 clock_enable(&gcc
->blsp1_qup0_spi_apps_cbcr
);
287 clock_enable(&gcc
->blsp1_qup1_spi_apps_cbcr
);
290 clock_enable(&gcc
->blsp1_qup2_spi_apps_cbcr
);
293 clock_enable(&gcc
->blsp1_qup3_spi_apps_cbcr
);
296 clock_enable(&gcc
->blsp1_qup4_spi_apps_cbcr
);
299 } else if (blsp
== 2)
300 clock_enable(&gcc
->blsp2_qup0_spi_apps_cbcr
);
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
,
322 clock_enable_vote(&gcc
->blsp2_ahb_cbcr
,
323 &gcc
->gcc_apcs_clock_branch_en_vote
,