]>
git.ipfire.org Git - thirdparty/u-boot.git/blob - arch/arm/mach-imx/imx8ulp/cgc.c
1 // SPDX-License-Identifier: GPL-2.0+
10 #include <asm/arch/imx-regs.h>
11 #include <asm/arch/cgc.h>
12 #include <asm/arch/clock.h>
13 #include <asm/arch/sys_proto.h>
14 #include <asm/global_data.h>
15 #include <linux/delay.h>
18 DECLARE_GLOBAL_DATA_PTR
;
20 static struct cgc1_regs
*cgc1_regs
= (struct cgc1_regs
*)0x292C0000UL
;
21 static struct cgc2_regs
*cgc2_regs
= (struct cgc2_regs
*)0x2da60000UL
;
23 void cgc1_soscdiv_init(void)
25 /* Configure SOSC/FRO DIV1 ~ DIV3 */
26 clrbits_le32(&cgc1_regs
->soscdiv
, BIT(7));
27 clrbits_le32(&cgc1_regs
->soscdiv
, BIT(15));
28 clrbits_le32(&cgc1_regs
->soscdiv
, BIT(23));
29 clrbits_le32(&cgc1_regs
->soscdiv
, BIT(31));
31 clrbits_le32(&cgc1_regs
->frodiv
, BIT(7));
34 void cgc1_pll2_init(ulong freq
)
38 if (readl(&cgc1_regs
->pll2csr
) & BIT(23))
39 clrbits_le32(&cgc1_regs
->pll2csr
, BIT(23));
42 clrbits_le32(&cgc1_regs
->pll2csr
, BIT(0));
45 /* wait valid bit false */
46 while ((readl(&cgc1_regs
->pll2csr
) & BIT(24)))
49 /* Select SOSC as source */
50 reg
= (freq
/ MHZ(24)) << 16;
51 writel(reg
, &cgc1_regs
->pll2cfg
);
54 setbits_le32(&cgc1_regs
->pll2csr
, BIT(0));
56 /* Wait for PLL2 clock ready */
57 while (!(readl(&cgc1_regs
->pll2csr
) & BIT(24)))
61 static void cgc1_set_a35_clk(u32 clk_src
, u32 div_core
)
66 if (readl(&cgc1_regs
->ca35clk
) & BIT(31))
67 clrbits_le32(&cgc1_regs
->ca35clk
, BIT(31));
69 reg
= readl(&cgc1_regs
->ca35clk
);
70 reg
&= ~GENMASK(29, 21);
71 reg
|= ((clk_src
& 0x3) << 28);
72 reg
|= (((div_core
- 1) & 0x3f) << 21);
73 writel(reg
, &cgc1_regs
->ca35clk
);
75 while (!(readl(&cgc1_regs
->ca35clk
) & BIT(27)))
79 void cgc1_init_core_clk(ulong freq
)
81 u32 reg
= readl(&cgc1_regs
->ca35clk
);
83 /* if already selected to PLL2, switch to FRO firstly */
84 if (((reg
>> 28) & 0x3) == 0x1)
85 cgc1_set_a35_clk(0, 1);
89 /* Set A35 clock to pll2 */
90 cgc1_set_a35_clk(1, 1);
93 void cgc1_enet_stamp_sel(u32 clk_src
)
95 writel((clk_src
& 0x7) << 24, &cgc1_regs
->enetstamp
);
98 void cgc1_pll3_init(ulong freq
)
101 setbits_le32(&cgc1_regs
->pll3div_vco
, BIT(7));
104 clrbits_le32(&cgc1_regs
->pll3csr
, BIT(0));
106 /* Gate off PFDxDIV */
107 setbits_le32(&cgc1_regs
->pll3div_pfd0
, BIT(7) | BIT(15) | BIT(23) | BIT(31));
108 setbits_le32(&cgc1_regs
->pll3div_pfd1
, BIT(7) | BIT(15) | BIT(23) | BIT(31));
111 setbits_le32(&cgc1_regs
->pll3pfdcfg
, BIT(7));
112 setbits_le32(&cgc1_regs
->pll3pfdcfg
, BIT(15));
113 setbits_le32(&cgc1_regs
->pll3pfdcfg
, BIT(23));
114 setbits_le32(&cgc1_regs
->pll3pfdcfg
, BIT(31));
116 /* Select SOSC as source */
117 clrbits_le32(&cgc1_regs
->pll3cfg
, BIT(0));
121 writel(0x16 << 16, &cgc1_regs
->pll3cfg
);
122 writel(0x16e3600, &cgc1_regs
->pll3denom
);
123 writel(0xc15c00, &cgc1_regs
->pll3num
);
130 setbits_le32(&cgc1_regs
->pll3csr
, BIT(0));
132 /* Wait for PLL3 clock ready */
133 while (!(readl(&cgc1_regs
->pll3csr
) & BIT(24)))
136 clrbits_le32(&cgc1_regs
->pll3div_vco
, BIT(7));
138 clrbits_le32(&cgc1_regs
->pll3pfdcfg
, 0x3F);
140 if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE
)) {
141 setbits_le32(&cgc1_regs
->pll3pfdcfg
, 25 << 0);
142 clrsetbits_le32(&cgc1_regs
->nicclk
, GENMASK(26, 21), 3 << 21); /* 195M */
143 } else if (IS_ENABLED(CONFIG_IMX8ULP_ND_MODE
)) {
144 setbits_le32(&cgc1_regs
->pll3pfdcfg
, 21 << 0);
145 clrsetbits_le32(&cgc1_regs
->nicclk
, GENMASK(26, 21), 1 << 21); /* 231M */
147 setbits_le32(&cgc1_regs
->pll3pfdcfg
, 30 << 0); /* 324M */
150 clrbits_le32(&cgc1_regs
->pll3pfdcfg
, BIT(7));
151 while (!(readl(&cgc1_regs
->pll3pfdcfg
) & BIT(6)))
154 clrbits_le32(&cgc1_regs
->pll3pfdcfg
, 0x3F << 8);
155 setbits_le32(&cgc1_regs
->pll3pfdcfg
, 25 << 8);
156 clrbits_le32(&cgc1_regs
->pll3pfdcfg
, BIT(15));
157 while (!(readl(&cgc1_regs
->pll3pfdcfg
) & BIT(14)))
160 clrbits_le32(&cgc1_regs
->pll3pfdcfg
, 0x3F << 16);
161 setbits_le32(&cgc1_regs
->pll3pfdcfg
, 25 << 16);
162 clrbits_le32(&cgc1_regs
->pll3pfdcfg
, BIT(23));
163 while (!(readl(&cgc1_regs
->pll3pfdcfg
) & BIT(22)))
166 clrbits_le32(&cgc1_regs
->pll3pfdcfg
, 0x3F << 24);
167 setbits_le32(&cgc1_regs
->pll3pfdcfg
, 29 << 24);
168 clrbits_le32(&cgc1_regs
->pll3pfdcfg
, BIT(31));
169 while (!(readl(&cgc1_regs
->pll3pfdcfg
) & BIT(30)))
172 clrbits_le32(&cgc1_regs
->pll3div_pfd0
, BIT(7));
173 clrbits_le32(&cgc1_regs
->pll3div_pfd0
, BIT(15));
174 clrbits_le32(&cgc1_regs
->pll3div_pfd0
, BIT(23));
175 clrbits_le32(&cgc1_regs
->pll3div_pfd0
, BIT(31));
177 clrbits_le32(&cgc1_regs
->pll3div_pfd1
, BIT(7));
178 clrbits_le32(&cgc1_regs
->pll3div_pfd1
, BIT(15));
179 clrbits_le32(&cgc1_regs
->pll3div_pfd1
, BIT(23));
180 clrbits_le32(&cgc1_regs
->pll3div_pfd1
, BIT(31));
182 if (!IS_ENABLED(CONFIG_IMX8ULP_LD_MODE
) && !IS_ENABLED(CONFIG_IMX8ULP_ND_MODE
)) {
183 /* nicclk select pll3 pfd0 */
184 clrsetbits_le32(&cgc1_regs
->nicclk
, GENMASK(29, 28), BIT(28));
185 while (!(readl(&cgc1_regs
->nicclk
) & BIT(27)))
190 void cgc2_pll4_init(bool pll4_reset
)
192 /* Check the NICLPAV first to ensure not from PLL4 PFD1 clock */
193 if ((readl(&cgc2_regs
->niclpavclk
) & GENMASK(29, 28)) == BIT(28)) {
194 /* switch to FRO 192 first */
195 clrbits_le32(&cgc2_regs
->niclpavclk
, GENMASK(29, 28));
196 while (!(readl(&cgc2_regs
->niclpavclk
) & BIT(27)))
200 /* Disable PFD DIV and clear DIV */
201 writel(0x80808080, &cgc2_regs
->pll4div_pfd0
);
202 writel(0x80808080, &cgc2_regs
->pll4div_pfd1
);
204 /* Gate off and clear PFD */
205 writel(0x80808080, &cgc2_regs
->pll4pfdcfg
);
209 writel(0x0, &cgc2_regs
->pll4csr
);
211 /* Configure PLL4 to 528Mhz and clock source from SOSC */
212 writel(22 << 16, &cgc2_regs
->pll4cfg
);
213 writel(0x1, &cgc2_regs
->pll4csr
);
215 /* wait for PLL4 output valid */
216 while (!(readl(&cgc2_regs
->pll4csr
) & BIT(24)))
220 /* Enable all 4 PFDs */
221 setbits_le32(&cgc2_regs
->pll4pfdcfg
, 18 << 0); /* 528 */
222 if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE
)) {
223 setbits_le32(&cgc2_regs
->pll4pfdcfg
, 24 << 8);
224 /* 99Mhz for NIC_LPAV */
225 clrsetbits_le32(&cgc2_regs
->niclpavclk
, GENMASK(26, 21), 3 << 21);
226 } else if (IS_ENABLED(CONFIG_IMX8ULP_ND_MODE
)) {
227 setbits_le32(&cgc2_regs
->pll4pfdcfg
, 24 << 8);
228 /* 198Mhz for NIC_LPAV */
229 clrsetbits_le32(&cgc2_regs
->niclpavclk
, GENMASK(26, 21), 1 << 21);
231 setbits_le32(&cgc2_regs
->pll4pfdcfg
, 30 << 8); /* 316.8Mhz for NIC_LPAV */
232 clrbits_le32(&cgc2_regs
->niclpavclk
, GENMASK(26, 21));
234 setbits_le32(&cgc2_regs
->pll4pfdcfg
, 12 << 16); /* 792 */
235 setbits_le32(&cgc2_regs
->pll4pfdcfg
, 24 << 24); /* 396 */
237 clrbits_le32(&cgc2_regs
->pll4pfdcfg
, BIT(7) | BIT(15) | BIT(23) | BIT(31));
239 while ((readl(&cgc2_regs
->pll4pfdcfg
) & (BIT(30) | BIT(22) | BIT(14) | BIT(6)))
240 != (BIT(30) | BIT(22) | BIT(14) | BIT(6)))
244 clrbits_le32(&cgc2_regs
->pll4div_pfd0
, BIT(7) | BIT(15) | BIT(23) | BIT(31));
245 clrbits_le32(&cgc2_regs
->pll4div_pfd1
, BIT(7) | BIT(15) | BIT(23) | BIT(31));
247 clrsetbits_le32(&cgc2_regs
->niclpavclk
, GENMASK(29, 28), BIT(28));
248 while (!(readl(&cgc2_regs
->niclpavclk
) & BIT(27)))
252 void cgc2_pll4_pfd_config(enum cgc_clk pllpfd
, u32 pfd
)
254 void __iomem
*reg
= &cgc2_regs
->pll4div_pfd0
;
255 u32 halt_mask
= BIT(7) | BIT(15);
256 u32 pfd_shift
= (pllpfd
- PLL4_PFD0
) * 8;
259 if (pllpfd
< PLL4_PFD0
|| pllpfd
> PLL4_PFD3
)
262 if ((pllpfd
- PLL4_PFD0
) >> 1)
263 reg
= &cgc2_regs
->pll4div_pfd1
;
265 halt_mask
= halt_mask
<< (((pllpfd
- PLL4_PFD0
) & 0x1) * 16);
268 setbits_le32(reg
, halt_mask
);
271 setbits_le32(&cgc2_regs
->pll4pfdcfg
, BIT(7) << pfd_shift
);
273 val
= readl(&cgc2_regs
->pll4pfdcfg
);
274 val
&= ~(0x3f << pfd_shift
);
275 val
|= (pfd
<< pfd_shift
);
276 writel(val
, &cgc2_regs
->pll4pfdcfg
);
279 clrbits_le32(&cgc2_regs
->pll4pfdcfg
, BIT(7) << pfd_shift
);
282 while ((readl(&cgc2_regs
->pll4pfdcfg
) & (BIT(6) << pfd_shift
))
283 != (BIT(6) << pfd_shift
))
287 clrbits_le32(reg
, halt_mask
);
290 void cgc2_pll4_pfddiv_config(enum cgc_clk pllpfddiv
, u32 div
)
292 void __iomem
*reg
= &cgc2_regs
->pll4div_pfd0
;
293 u32 shift
= ((pllpfddiv
- PLL4_PFD0_DIV1
) & 0x3) * 8;
295 if (pllpfddiv
< PLL4_PFD0_DIV1
|| pllpfddiv
> PLL4_PFD3_DIV2
)
298 if ((pllpfddiv
- PLL4_PFD0_DIV1
) >> 2)
299 reg
= &cgc2_regs
->pll4div_pfd1
;
302 setbits_le32(reg
, BIT(7) << shift
);
305 clrbits_le32(reg
, 0x3f << shift
);
308 setbits_le32(reg
, div
<< shift
);
311 clrbits_le32(reg
, BIT(7) << shift
);
314 void cgc2_ddrclk_config(u32 src
, u32 div
)
316 /* If reg lock is set, wait until unlock by HW */
317 /* This lock is triggered by div updating and ddrclk halt status change, */
318 while ((readl(&cgc2_regs
->ddrclk
) & BIT(31)))
321 writel((src
<< 28) | (div
<< 21), &cgc2_regs
->ddrclk
);
322 /* wait for DDRCLK switching done */
323 while (!(readl(&cgc2_regs
->ddrclk
) & BIT(27)))
327 void cgc2_ddrclk_wait_unlock(void)
329 while ((readl(&cgc2_regs
->ddrclk
) & BIT(31)))
333 void cgc2_lpav_init(enum cgc_clk clk
)
336 const enum cgc_clk src
[] = {FRO
, PLL4_PFD1
, SOSC
, LVDS
};
338 reg
= readl(&cgc2_regs
->niclpavclk
);
339 scs
= (reg
>> 28) & 0x3;
341 for (i
= 0; i
< 4; i
++) {
349 writel(reg
, &cgc2_regs
->niclpavclk
);
355 printf("Invalid clock source [%u] for LPAV\n", clk
);
358 u32
cgc2_nic_get_rate(enum cgc_clk clk
)
361 u32 scs
, lpav_axi_clk
, lpav_ahb_clk
, lpav_bus_clk
;
362 const enum cgc_clk src
[] = {FRO
, PLL4_PFD1
, SOSC
, LVDS
};
364 reg
= readl(&cgc2_regs
->niclpavclk
);
365 scs
= (reg
>> 28) & 0x3;
366 lpav_axi_clk
= ((reg
>> 21) & 0x3f) + 1;
367 lpav_ahb_clk
= ((reg
>> 14) & 0x3f) + 1;
368 lpav_bus_clk
= ((reg
>> 7) & 0x3f) + 1;
370 rate
= cgc_clk_get_rate(src
[scs
]);
374 rate
= rate
/ lpav_axi_clk
;
377 rate
= rate
/ (lpav_axi_clk
* lpav_ahb_clk
);
380 rate
= rate
/ (lpav_axi_clk
* lpav_bus_clk
);
389 u32
decode_pll(enum cgc_clk pll
)
391 u32 reg
, infreq
, mult
;
396 * Alought there are four choices for the bypass src,
397 * we choose SOSC 24M which is the default set in ROM.
398 * TODO: check more the comments
402 reg
= readl(&cgc1_regs
->pll2csr
);
403 if (!(reg
& BIT(24)))
406 reg
= readl(&cgc1_regs
->pll2cfg
);
407 mult
= (reg
>> 16) & 0x7F;
408 denom
= readl(&cgc1_regs
->pll2denom
) & 0x3FFFFFFF;
409 num
= readl(&cgc1_regs
->pll2num
) & 0x3FFFFFFF;
411 return (u64
)infreq
* mult
+ (u64
)infreq
* num
/ denom
;
413 reg
= readl(&cgc1_regs
->pll3csr
);
414 if (!(reg
& BIT(24)))
417 reg
= readl(&cgc1_regs
->pll3cfg
);
418 mult
= (reg
>> 16) & 0x7F;
419 denom
= readl(&cgc1_regs
->pll3denom
) & 0x3FFFFFFF;
420 num
= readl(&cgc1_regs
->pll3num
) & 0x3FFFFFFF;
422 return (u64
)infreq
* mult
+ (u64
)infreq
* num
/ denom
;
424 reg
= readl(&cgc2_regs
->pll4csr
);
425 if (!(reg
& BIT(24)))
428 reg
= readl(&cgc2_regs
->pll4cfg
);
429 mult
= (reg
>> 16) & 0x7F;
430 denom
= readl(&cgc2_regs
->pll4denom
) & 0x3FFFFFFF;
431 num
= readl(&cgc2_regs
->pll4num
) & 0x3FFFFFFF;
433 return (u64
)infreq
* mult
+ (u64
)infreq
* num
/ denom
;
435 printf("Unsupported pll clocks %d\n", pll
);
442 u32
cgc_pll_vcodiv_rate(enum cgc_clk clk
)
445 void __iomem
*plldiv_vco
;
448 if (clk
== PLL3_VCODIV
) {
449 plldiv_vco
= &cgc1_regs
->pll3div_vco
;
452 plldiv_vco
= &cgc2_regs
->pll4div_vco
;
456 reg
= readl(plldiv_vco
);
460 return gate
? 0 : decode_pll(pll
) / (div
+ 1);
463 u32
cgc_pll_pfd_rate(enum cgc_clk clk
)
465 u32 index
, gate
, vld
, reg
;
466 void __iomem
*pllpfdcfg
;
474 index
= clk
- PLL3_PFD0
;
475 pllpfdcfg
= &cgc1_regs
->pll3pfdcfg
;
482 index
= clk
- PLL4_PFD0
;
483 pllpfdcfg
= &cgc2_regs
->pll4pfdcfg
;
490 reg
= readl(pllpfdcfg
);
491 gate
= reg
& (BIT(7) << (index
* 8));
492 vld
= reg
& (BIT(6) << (index
* 8));
497 return (u64
)decode_pll(pll
) * 18 / ((reg
>> (index
* 8)) & 0x3F);
500 u32
cgc_pll_pfd_div(enum cgc_clk clk
)
503 u32 pfd
, index
, gate
, reg
;
508 base
= &cgc1_regs
->pll3div_pfd0
;
510 index
= clk
- PLL3_PFD0_DIV1
;
514 base
= &cgc1_regs
->pll3div_pfd0
;
516 index
= clk
- PLL3_PFD0_DIV1
;
520 base
= &cgc1_regs
->pll3div_pfd1
;
522 index
= clk
- PLL3_PFD2_DIV1
;
526 base
= &cgc1_regs
->pll3div_pfd1
;
528 index
= clk
- PLL3_PFD2_DIV1
;
532 base
= &cgc2_regs
->pll4div_pfd0
;
534 index
= clk
- PLL4_PFD0_DIV1
;
538 base
= &cgc2_regs
->pll4div_pfd0
;
540 index
= clk
- PLL4_PFD0_DIV1
;
544 base
= &cgc2_regs
->pll4div_pfd1
;
546 index
= clk
- PLL4_PFD2_DIV1
;
550 base
= &cgc2_regs
->pll4div_pfd1
;
552 index
= clk
- PLL4_PFD2_DIV1
;
559 gate
= reg
& (BIT(7) << (index
* 8));
564 return cgc_pll_pfd_rate(pfd
) / (((reg
>> (index
* 8)) & 0x3F) + 1);
567 u32
cgc1_nic_get_rate(enum cgc_clk clk
)
570 u32 scs
, nic_ad_divplat
, nic_per_divplat
;
571 u32 xbar_ad_divplat
, xbar_divbus
, ad_slow
;
572 const enum cgc_clk src
[] = {FRO
, PLL3_PFD0
, SOSC
, LVDS
};
574 reg
= readl(&cgc1_regs
->nicclk
);
575 scs
= (reg
>> 28) & 0x3;
576 nic_ad_divplat
= ((reg
>> 21) & 0x3f) + 1;
577 nic_per_divplat
= ((reg
>> 14) & 0x3f) + 1;
579 reg
= readl(&cgc1_regs
->xbarclk
);
580 xbar_ad_divplat
= ((reg
>> 14) & 0x3f) + 1;
581 xbar_divbus
= ((reg
>> 7) & 0x3f) + 1;
582 ad_slow
= (reg
& 0x3f) + 1;
584 rate
= cgc_clk_get_rate(src
[scs
]);
588 rate
= rate
/ nic_ad_divplat
;
591 rate
= rate
/ (nic_ad_divplat
* nic_per_divplat
);
594 rate
= rate
/ (nic_ad_divplat
* xbar_ad_divplat
);
597 rate
= rate
/ (nic_ad_divplat
* xbar_ad_divplat
* xbar_divbus
);
600 rate
= rate
/ (nic_ad_divplat
* xbar_ad_divplat
* ad_slow
);
609 u32
cgc1_sosc_div(enum cgc_clk clk
)
611 u32 reg
, gate
, index
;
629 reg
= readl(&cgc1_regs
->soscdiv
);
630 gate
= reg
& (BIT(7) << (index
* 8));
635 return 24000000 / (((reg
>> (index
* 8)) & 0x3F) + 1);
638 u32
cgc1_fro_div(enum cgc_clk clk
)
640 u32 reg
, gate
, vld
, index
;
658 reg
= readl(&cgc1_regs
->frodiv
);
659 gate
= reg
& (BIT(7) << (index
* 8));
660 vld
= reg
& (BIT(6) << (index
* 8));
665 return 24000000 / (((reg
>> (index
* 8)) & 0x3F) + 1);
668 u32
cgc_clk_get_rate(enum cgc_clk clk
)
672 return 0; /* No external LVDS clock used */
677 return cgc1_sosc_div(clk
);
682 return cgc1_fro_div(clk
);
686 return decode_pll(clk
);
689 return cgc_pll_vcodiv_rate(clk
);
698 return cgc_pll_pfd_rate(clk
);
715 return cgc_pll_pfd_div(clk
);
721 return cgc1_nic_get_rate(clk
);
725 return cgc2_nic_get_rate(clk
);
727 printf("Unsupported cgc clock: %d\n", clk
);