2 * [origin: Linux kernel linux/arch/arm/mach-at91/clock.c]
4 * Copyright (C) 2005 David Brownell
5 * Copyright (C) 2005 Ivan Kokshaysky
6 * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
7 * Copyright (C) 2013 Bo Shen <voice.shen@atmel.com>
8 * Copyright (C) 2015 Wenyou Yang <wenyou.yang@atmel.com>
10 * SPDX-License-Identifier: GPL-2.0+
14 #include <linux/errno.h>
16 #include <asm/arch/hardware.h>
17 #include <asm/arch/at91_pmc.h>
18 #include <asm/arch/clk.h>
20 #if !defined(CONFIG_AT91FAMILY)
21 # error You need to define CONFIG_AT91FAMILY in your board config!
24 DECLARE_GLOBAL_DATA_PTR
;
26 static unsigned long at91_css_to_rate(unsigned long css
)
29 case AT91_PMC_MCKR_CSS_SLOW
:
30 return CONFIG_SYS_AT91_SLOW_CLOCK
;
31 case AT91_PMC_MCKR_CSS_MAIN
:
32 return gd
->arch
.main_clk_rate_hz
;
33 case AT91_PMC_MCKR_CSS_PLLA
:
34 return gd
->arch
.plla_rate_hz
;
40 static u32
at91_pll_rate(u32 freq
, u32 reg
)
45 mul
= (reg
>> 18) & 0x7f;
56 int at91_clock_init(unsigned long main_clock
)
59 struct at91_pmc
*pmc
= (struct at91_pmc
*)ATMEL_BASE_PMC
;
60 #ifndef CONFIG_SYS_AT91_MAIN_CLOCK
63 * When the bootloader initialized the main oscillator correctly,
64 * there's no problem using the cycle counter. But if it didn't,
65 * or when using oscillator bypass mode, we must be told the speed
70 tmp
= readl(&pmc
->mcfr
);
71 } while (!(tmp
& AT91_PMC_MCFR_MAINRDY
));
72 tmp
&= AT91_PMC_MCFR_MAINF_MASK
;
73 main_clock
= tmp
* (CONFIG_SYS_AT91_SLOW_CLOCK
/ 16);
76 gd
->arch
.main_clk_rate_hz
= main_clock
;
78 /* report if PLLA is more than mildly overclocked */
79 gd
->arch
.plla_rate_hz
= at91_pll_rate(main_clock
, readl(&pmc
->pllar
));
82 * MCK and CPU derive from one of those primary clocks.
83 * For now, assume this parentage won't change.
85 mckr
= readl(&pmc
->mckr
);
87 /* plla divisor by 2 */
89 gd
->arch
.plla_rate_hz
>>= 1;
91 gd
->arch
.mck_rate_hz
= at91_css_to_rate(mckr
& AT91_PMC_MCKR_CSS_MASK
);
92 freq
= gd
->arch
.mck_rate_hz
;
95 freq
>>= mckr
& AT91_PMC_MCKR_PRES_MASK
;
97 switch (mckr
& AT91_PMC_MCKR_MDIV_MASK
) {
98 case AT91_PMC_MCKR_MDIV_2
:
99 gd
->arch
.mck_rate_hz
= freq
/ 2;
101 case AT91_PMC_MCKR_MDIV_3
:
102 gd
->arch
.mck_rate_hz
= freq
/ 3;
104 case AT91_PMC_MCKR_MDIV_4
:
105 gd
->arch
.mck_rate_hz
= freq
/ 4;
111 gd
->arch
.cpu_clk_rate_hz
= freq
;
116 void at91_plla_init(u32 pllar
)
118 struct at91_pmc
*pmc
= (struct at91_pmc
*)ATMEL_BASE_PMC
;
120 writel(pllar
, &pmc
->pllar
);
121 while (!(readl(&pmc
->sr
) & (AT91_PMC_LOCKA
| AT91_PMC_MCKRDY
)))
125 void at91_mck_init(u32 mckr
)
127 struct at91_pmc
*pmc
= (struct at91_pmc
*)ATMEL_BASE_PMC
;
130 tmp
= readl(&pmc
->mckr
);
131 tmp
&= ~(AT91_PMC_MCKR_CSS_MASK
|
132 AT91_PMC_MCKR_PRES_MASK
|
133 AT91_PMC_MCKR_MDIV_MASK
|
134 AT91_PMC_MCKR_PLLADIV_2
);
135 #ifdef CPU_HAS_H32MXDIV
136 tmp
&= ~AT91_PMC_MCKR_H32MXDIV
;
139 tmp
|= mckr
& (AT91_PMC_MCKR_CSS_MASK
|
140 AT91_PMC_MCKR_PRES_MASK
|
141 AT91_PMC_MCKR_MDIV_MASK
|
142 AT91_PMC_MCKR_PLLADIV_2
);
143 #ifdef CPU_HAS_H32MXDIV
144 tmp
|= mckr
& AT91_PMC_MCKR_H32MXDIV
;
147 writel(tmp
, &pmc
->mckr
);
149 while (!(readl(&pmc
->sr
) & AT91_PMC_MCKRDY
))
153 int at91_enable_periph_generated_clk(u32 id
, u32 clk_source
, u32 div
)
155 struct at91_pmc
*pmc
= (struct at91_pmc
*)ATMEL_BASE_PMC
;
159 if (id
> AT91_PMC_PCR_PID_MASK
)
165 if (clk_source
== GCK_CSS_UPLL_CLK
) {
166 if (at91_upll_clk_enable())
170 writel(id
, &pmc
->pcr
);
171 regval
= readl(&pmc
->pcr
);
172 regval
&= ~AT91_PMC_PCR_GCKCSS
;
173 regval
&= ~AT91_PMC_PCR_GCKDIV
;
175 switch (clk_source
) {
176 case GCK_CSS_SLOW_CLK
:
177 regval
|= AT91_PMC_PCR_GCKCSS_SLOW_CLK
;
179 case GCK_CSS_MAIN_CLK
:
180 regval
|= AT91_PMC_PCR_GCKCSS_MAIN_CLK
;
182 case GCK_CSS_PLLA_CLK
:
183 regval
|= AT91_PMC_PCR_GCKCSS_PLLA_CLK
;
185 case GCK_CSS_UPLL_CLK
:
186 regval
|= AT91_PMC_PCR_GCKCSS_UPLL_CLK
;
188 case GCK_CSS_MCK_CLK
:
189 regval
|= AT91_PMC_PCR_GCKCSS_MCK_CLK
;
191 case GCK_CSS_AUDIO_CLK
:
192 regval
|= AT91_PMC_PCR_GCKCSS_AUDIO_CLK
;
195 printf("Error GCK clock source selection!\n");
199 regval
|= AT91_PMC_PCR_CMD_WRITE
|
200 AT91_PMC_PCR_GCKDIV_(div
) |
203 writel(regval
, &pmc
->pcr
);
207 status
= readl(&pmc
->sr
);
208 } while ((!!(--timeout
)) && (!(status
& AT91_PMC_GCKRDY
)));
211 printf("Timeout waiting for GCK ready!\n");
216 u32
at91_get_periph_generated_clk(u32 id
)
218 struct at91_pmc
*pmc
= (struct at91_pmc
*)ATMEL_BASE_PMC
;
219 u32 regval
, clk_source
, div
;
222 if (id
> AT91_PMC_PCR_PID_MASK
)
225 writel(id
, &pmc
->pcr
);
226 regval
= readl(&pmc
->pcr
);
228 clk_source
= regval
& AT91_PMC_PCR_GCKCSS
;
229 switch (clk_source
) {
230 case AT91_PMC_PCR_GCKCSS_SLOW_CLK
:
231 freq
= CONFIG_SYS_AT91_SLOW_CLOCK
;
233 case AT91_PMC_PCR_GCKCSS_MAIN_CLK
:
234 freq
= gd
->arch
.main_clk_rate_hz
;
236 case AT91_PMC_PCR_GCKCSS_PLLA_CLK
:
237 freq
= gd
->arch
.plla_rate_hz
;
239 case AT91_PMC_PCR_GCKCSS_UPLL_CLK
:
240 freq
= AT91_UTMI_PLL_CLK_FREQ
;
242 case AT91_PMC_PCR_GCKCSS_MCK_CLK
:
243 freq
= gd
->arch
.mck_rate_hz
;
246 printf("Improper GCK clock source selection!\n");
251 div
= ((regval
& AT91_PMC_PCR_GCKDIV
) >> AT91_PMC_PCR_GCKDIV_OFFSET
);