xref: /openbmc/u-boot/arch/arm/mach-at91/armv7/clock.c (revision 87a62bce)
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 }
297