3640fce8821d57df336e3470145f5f4d54dcc4cc
[oweals/u-boot.git] / arch / arm / mach-at91 / armv7 / clock.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * [origin: Linux kernel linux/arch/arm/mach-at91/clock.c]
4  *
5  * Copyright (C) 2005 David Brownell
6  * Copyright (C) 2005 Ivan Kokshaysky
7  * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
8  * Copyright (C) 2013 Bo Shen <voice.shen@atmel.com>
9  * Copyright (C) 2015 Wenyou Yang <wenyou.yang@atmel.com>
10  */
11
12 #include <common.h>
13 #include <linux/errno.h>
14 #include <asm/io.h>
15 #include <asm/arch/hardware.h>
16 #include <asm/arch/at91_pmc.h>
17 #include <asm/arch/clk.h>
18
19 #if !defined(CONFIG_AT91FAMILY)
20 # error You need to define CONFIG_AT91FAMILY in your board config!
21 #endif
22
23 DECLARE_GLOBAL_DATA_PTR;
24
25 static unsigned long at91_css_to_rate(unsigned long css)
26 {
27         switch (css) {
28         case AT91_PMC_MCKR_CSS_SLOW:
29                 return CONFIG_SYS_AT91_SLOW_CLOCK;
30         case AT91_PMC_MCKR_CSS_MAIN:
31                 return gd->arch.main_clk_rate_hz;
32         case AT91_PMC_MCKR_CSS_PLLA:
33                 return gd->arch.plla_rate_hz;
34         }
35
36         return 0;
37 }
38
39 static u32 at91_pll_rate(u32 freq, u32 reg)
40 {
41         unsigned mul, div;
42
43         div = reg & 0xff;
44         mul = (reg >> 18) & 0x7f;
45         if (div && mul) {
46                 freq /= div;
47                 freq *= mul + 1;
48         } else {
49                 freq = 0;
50         }
51
52         return freq;
53 }
54
55 int at91_clock_init(unsigned long main_clock)
56 {
57         unsigned freq, mckr;
58         struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
59 #ifndef CONFIG_SYS_AT91_MAIN_CLOCK
60         unsigned tmp;
61         /*
62          * When the bootloader initialized the main oscillator correctly,
63          * there's no problem using the cycle counter.  But if it didn't,
64          * or when using oscillator bypass mode, we must be told the speed
65          * of the main clock.
66          */
67         if (!main_clock) {
68                 do {
69                         tmp = readl(&pmc->mcfr);
70                 } while (!(tmp & AT91_PMC_MCFR_MAINRDY));
71                 tmp &= AT91_PMC_MCFR_MAINF_MASK;
72                 main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16);
73         }
74 #endif
75         gd->arch.main_clk_rate_hz = main_clock;
76
77         /* report if PLLA is more than mildly overclocked */
78         gd->arch.plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar));
79
80         /*
81          * MCK and CPU derive from one of those primary clocks.
82          * For now, assume this parentage won't change.
83          */
84         mckr = readl(&pmc->mckr);
85
86         /* plla divisor by 2 */
87         if (mckr & (1 << 12))
88                 gd->arch.plla_rate_hz >>= 1;
89
90         gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK);
91         freq = gd->arch.mck_rate_hz;
92
93         /* prescale */
94         freq >>= mckr & AT91_PMC_MCKR_PRES_MASK;
95
96         switch (mckr & AT91_PMC_MCKR_MDIV_MASK) {
97         case AT91_PMC_MCKR_MDIV_2:
98                 gd->arch.mck_rate_hz = freq / 2;
99                 break;
100         case AT91_PMC_MCKR_MDIV_3:
101                 gd->arch.mck_rate_hz = freq / 3;
102                 break;
103         case AT91_PMC_MCKR_MDIV_4:
104                 gd->arch.mck_rate_hz = freq / 4;
105                 break;
106         default:
107                 break;
108         }
109
110         gd->arch.cpu_clk_rate_hz = freq;
111
112         return 0;
113 }
114
115 void at91_plla_init(u32 pllar)
116 {
117         struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
118
119         writel(pllar, &pmc->pllar);
120         while (!(readl(&pmc->sr) & (AT91_PMC_LOCKA | AT91_PMC_MCKRDY)))
121                 ;
122 }
123
124 void at91_mck_init(u32 mckr)
125 {
126         struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
127         u32 tmp;
128
129         tmp = readl(&pmc->mckr);
130         tmp &= ~(AT91_PMC_MCKR_CSS_MASK  |
131                  AT91_PMC_MCKR_PRES_MASK |
132                  AT91_PMC_MCKR_MDIV_MASK |
133                  AT91_PMC_MCKR_PLLADIV_2);
134 #ifdef CPU_HAS_H32MXDIV
135         tmp &= ~AT91_PMC_MCKR_H32MXDIV;
136 #endif
137
138         tmp |= mckr & (AT91_PMC_MCKR_CSS_MASK  |
139                        AT91_PMC_MCKR_PRES_MASK |
140                        AT91_PMC_MCKR_MDIV_MASK |
141                        AT91_PMC_MCKR_PLLADIV_2);
142 #ifdef CPU_HAS_H32MXDIV
143         tmp |= mckr & AT91_PMC_MCKR_H32MXDIV;
144 #endif
145
146         writel(tmp, &pmc->mckr);
147
148         while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY))
149                 ;
150 }
151
152 /*
153  * For the Master Clock Controller Register(MCKR), while switching
154  * to a lower clock source, we must switch the clock source first
155  * instead of last. Otherwise, we could end up with too high frequency
156  * on the internal bus and peripherals.
157  */
158 void at91_mck_init_down(u32 mckr)
159 {
160         struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
161         u32 tmp;
162
163         tmp = readl(&pmc->mckr);
164         tmp &= (~AT91_PMC_MCKR_CSS_MASK);
165         tmp |= (mckr & AT91_PMC_MCKR_CSS_MASK);
166         writel(tmp, &pmc->mckr);
167
168         while (!(readl(&pmc->sr) & AT91_PMC_MCKRDY))
169                 ;
170
171 #ifdef CPU_HAS_H32MXDIV
172         tmp = readl(&pmc->mckr);
173         tmp &= (~AT91_PMC_MCKR_H32MXDIV);
174         tmp |= (mckr & AT91_PMC_MCKR_H32MXDIV);
175         writel(tmp, &pmc->mckr);
176 #endif
177
178         tmp = readl(&pmc->mckr);
179         tmp &= (~AT91_PMC_MCKR_PLLADIV_MASK);
180         tmp |= (mckr & AT91_PMC_MCKR_PLLADIV_MASK);
181         writel(tmp, &pmc->mckr);
182
183         tmp = readl(&pmc->mckr);
184         tmp &= (~AT91_PMC_MCKR_MDIV_MASK);
185         tmp |= (mckr & AT91_PMC_MCKR_MDIV_MASK);
186         writel(tmp, &pmc->mckr);
187
188         tmp = readl(&pmc->mckr);
189         tmp &= (~AT91_PMC_MCKR_PRES_MASK);
190         tmp |= (mckr & AT91_PMC_MCKR_PRES_MASK);
191         writel(tmp, &pmc->mckr);
192 }
193
194 int at91_enable_periph_generated_clk(u32 id, u32 clk_source, u32 div)
195 {
196         struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
197         u32 regval, status;
198         u32 timeout = 1000;
199
200         if (id > AT91_PMC_PCR_PID_MASK)
201                 return -EINVAL;
202
203         if (div > 0xff)
204                 return -EINVAL;
205
206         if (clk_source == GCK_CSS_UPLL_CLK) {
207                 if (at91_upll_clk_enable())
208                         return -ENODEV;
209         }
210
211         writel(id, &pmc->pcr);
212         regval = readl(&pmc->pcr);
213         regval &= ~AT91_PMC_PCR_GCKCSS;
214         regval &= ~AT91_PMC_PCR_GCKDIV;
215
216         switch (clk_source) {
217         case GCK_CSS_SLOW_CLK:
218                 regval |= AT91_PMC_PCR_GCKCSS_SLOW_CLK;
219                 break;
220         case GCK_CSS_MAIN_CLK:
221                 regval |= AT91_PMC_PCR_GCKCSS_MAIN_CLK;
222                 break;
223         case GCK_CSS_PLLA_CLK:
224                 regval |= AT91_PMC_PCR_GCKCSS_PLLA_CLK;
225                 break;
226         case GCK_CSS_UPLL_CLK:
227                 regval |= AT91_PMC_PCR_GCKCSS_UPLL_CLK;
228                 break;
229         case GCK_CSS_MCK_CLK:
230                 regval |= AT91_PMC_PCR_GCKCSS_MCK_CLK;
231                 break;
232         case GCK_CSS_AUDIO_CLK:
233                 regval |= AT91_PMC_PCR_GCKCSS_AUDIO_CLK;
234                 break;
235         default:
236                 printf("Error GCK clock source selection!\n");
237                 return -EINVAL;
238         }
239
240         regval |= AT91_PMC_PCR_CMD_WRITE |
241                   AT91_PMC_PCR_GCKDIV_(div) |
242                   AT91_PMC_PCR_GCKEN;
243
244         writel(regval, &pmc->pcr);
245
246         do {
247                 udelay(1);
248                 status = readl(&pmc->sr);
249         } while ((!!(--timeout)) && (!(status & AT91_PMC_GCKRDY)));
250
251         if (!timeout)
252                 printf("Timeout waiting for GCK ready!\n");
253
254         return 0;
255 }
256
257 u32 at91_get_periph_generated_clk(u32 id)
258 {
259         struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
260         u32 regval, clk_source, div;
261         u32 freq;
262
263         if (id > AT91_PMC_PCR_PID_MASK)
264                 return 0;
265
266         writel(id, &pmc->pcr);
267         regval = readl(&pmc->pcr);
268
269         clk_source = regval & AT91_PMC_PCR_GCKCSS;
270         switch (clk_source) {
271         case AT91_PMC_PCR_GCKCSS_SLOW_CLK:
272                 freq = CONFIG_SYS_AT91_SLOW_CLOCK;
273                 break;
274         case AT91_PMC_PCR_GCKCSS_MAIN_CLK:
275                 freq = gd->arch.main_clk_rate_hz;
276                 break;
277         case AT91_PMC_PCR_GCKCSS_PLLA_CLK:
278                 freq = gd->arch.plla_rate_hz;
279                 break;
280         case AT91_PMC_PCR_GCKCSS_UPLL_CLK:
281                 freq = AT91_UTMI_PLL_CLK_FREQ;
282                 break;
283         case AT91_PMC_PCR_GCKCSS_MCK_CLK:
284                 freq = gd->arch.mck_rate_hz;
285                 break;
286         default:
287                 printf("Improper GCK clock source selection!\n");
288                 freq = 0;
289                 break;
290         }
291
292         div = ((regval & AT91_PMC_PCR_GCKDIV) >> AT91_PMC_PCR_GCKDIV_OFFSET);
293         div += 1;
294
295         return freq / div;
296 }