]> git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arm/cpu/arm1176/tnetv107x/clock.c
16876aeea87f1117d55c6d1348bb7a49dde5650d
[people/ms/u-boot.git] / arch / arm / cpu / arm1176 / tnetv107x / clock.c
1 /*
2 * TNETV107X: Clock management APIs
3 *
4 * See file CREDITS for list of people who contributed to this
5 * project.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include <common.h>
23 #include <asm-generic/errno.h>
24 #include <asm/io.h>
25 #include <asm/processor.h>
26 #include <asm/arch/clock.h>
27
28 #define CLOCK_BASE TNETV107X_CLOCK_CONTROL_BASE
29 #define PSC_BASE TNETV107X_PSC_BASE
30
31 #define BIT(x) (1 << (x))
32
33 #define MAX_PREDIV 64
34 #define MAX_POSTDIV 8
35 #define MAX_MULT 512
36 #define MAX_DIV (MAX_PREDIV * MAX_POSTDIV)
37
38 /* LPSC registers */
39 #define PSC_PTCMD 0x120
40 #define PSC_PTSTAT 0x128
41 #define PSC_MDSTAT(n) (0x800 + (n) * 4)
42 #define PSC_MDCTL(n) (0xA00 + (n) * 4)
43
44 #define PSC_MDCTL_LRSTZ BIT(8)
45
46 #define psc_reg_read(reg) __raw_readl((u32 *)(PSC_BASE + (reg)))
47 #define psc_reg_write(reg, val) __raw_writel(val, (u32 *)(PSC_BASE + (reg)))
48
49 /* SSPLL registers */
50 struct sspll_regs {
51 u32 modes;
52 u32 postdiv;
53 u32 prediv;
54 u32 mult_factor;
55 u32 divider_range;
56 u32 bw_divider;
57 u32 spr_amount;
58 u32 spr_rate_div;
59 u32 diag;
60 };
61
62 /* SSPLL base addresses */
63 static struct sspll_regs *sspll_regs[] = {
64 (struct sspll_regs *)(CLOCK_BASE + 0x040),
65 (struct sspll_regs *)(CLOCK_BASE + 0x080),
66 (struct sspll_regs *)(CLOCK_BASE + 0x0c0),
67 };
68
69 #define sspll_reg(pll, reg) (&(sspll_regs[pll]->reg))
70 #define sspll_reg_read(pll, reg) __raw_readl(sspll_reg(pll, reg))
71 #define sspll_reg_write(pll, reg, val) __raw_writel(val, sspll_reg(pll, reg))
72
73
74 /* PLL Control Registers */
75 struct pllctl_regs {
76 u32 ctl; /* 00 */
77 u32 ocsel; /* 04 */
78 u32 secctl; /* 08 */
79 u32 __pad0;
80 u32 mult; /* 10 */
81 u32 prediv; /* 14 */
82 u32 div1; /* 18 */
83 u32 div2; /* 1c */
84 u32 div3; /* 20 */
85 u32 oscdiv1; /* 24 */
86 u32 postdiv; /* 28 */
87 u32 bpdiv; /* 2c */
88 u32 wakeup; /* 30 */
89 u32 __pad1;
90 u32 cmd; /* 38 */
91 u32 stat; /* 3c */
92 u32 alnctl; /* 40 */
93 u32 dchange; /* 44 */
94 u32 cken; /* 48 */
95 u32 ckstat; /* 4c */
96 u32 systat; /* 50 */
97 u32 ckctl; /* 54 */
98 u32 __pad2[2];
99 u32 div4; /* 60 */
100 u32 div5; /* 64 */
101 u32 div6; /* 68 */
102 u32 div7; /* 6c */
103 u32 div8; /* 70 */
104 };
105
106 struct lpsc_map {
107 int pll, div;
108 };
109
110 static struct pllctl_regs *pllctl_regs[] = {
111 (struct pllctl_regs *)(CLOCK_BASE + 0x700),
112 (struct pllctl_regs *)(CLOCK_BASE + 0x300),
113 (struct pllctl_regs *)(CLOCK_BASE + 0x500),
114 };
115
116 #define pllctl_reg(pll, reg) (&(pllctl_regs[pll]->reg))
117 #define pllctl_reg_read(pll, reg) __raw_readl(pllctl_reg(pll, reg))
118 #define pllctl_reg_write(pll, reg, val) __raw_writel(val, pllctl_reg(pll, reg))
119
120 #define pllctl_reg_rmw(pll, reg, mask, val) \
121 pllctl_reg_write(pll, reg, \
122 (pllctl_reg_read(pll, reg) & ~(mask)) | val)
123
124 #define pllctl_reg_setbits(pll, reg, mask) \
125 pllctl_reg_rmw(pll, reg, 0, mask)
126
127 #define pllctl_reg_clrbits(pll, reg, mask) \
128 pllctl_reg_rmw(pll, reg, mask, 0)
129
130 /* PLLCTL Bits */
131 #define PLLCTL_CLKMODE BIT(8)
132 #define PLLCTL_PLLSELB BIT(7)
133 #define PLLCTL_PLLENSRC BIT(5)
134 #define PLLCTL_PLLDIS BIT(4)
135 #define PLLCTL_PLLRST BIT(3)
136 #define PLLCTL_PLLPWRDN BIT(1)
137 #define PLLCTL_PLLEN BIT(0)
138
139 #define PLLDIV_ENABLE BIT(15)
140
141 static int pll_div_offset[] = {
142 #define div_offset(reg) offsetof(struct pllctl_regs, reg)
143 div_offset(div1), div_offset(div2), div_offset(div3),
144 div_offset(div4), div_offset(div5), div_offset(div6),
145 div_offset(div7), div_offset(div8),
146 };
147
148 static unsigned long pll_bypass_mask[] = { 1, 4, 2 };
149 static unsigned long pll_div_mask[] = { 0x01ff, 0x00ff, 0x00ff };
150
151 /* Mappings from PLL+DIV to subsystem clocks */
152 #define sys_arm1176_clk {SYS_PLL, 0}
153 #define sys_dsp_clk {SYS_PLL, 1}
154 #define sys_ddr_clk {SYS_PLL, 2}
155 #define sys_full_clk {SYS_PLL, 3}
156 #define sys_lcd_clk {SYS_PLL, 4}
157 #define sys_vlynq_ref_clk {SYS_PLL, 5}
158 #define sys_tsc_clk {SYS_PLL, 6}
159 #define sys_half_clk {SYS_PLL, 7}
160
161 #define eth_clk_5 {ETH_PLL, 0}
162 #define eth_clk_50 {ETH_PLL, 1}
163 #define eth_clk_125 {ETH_PLL, 2}
164 #define eth_clk_250 {ETH_PLL, 3}
165 #define eth_clk_25 {ETH_PLL, 4}
166
167 #define tdm_clk {TDM_PLL, 0}
168 #define tdm_extra_clk {TDM_PLL, 1}
169 #define tdm1_clk {TDM_PLL, 2}
170
171 static const struct lpsc_map lpsc_clk_map[] = {
172 [TNETV107X_LPSC_ARM] = sys_arm1176_clk,
173 [TNETV107X_LPSC_GEM] = sys_dsp_clk,
174 [TNETV107X_LPSC_DDR2_PHY] = sys_ddr_clk,
175 [TNETV107X_LPSC_TPCC] = sys_full_clk,
176 [TNETV107X_LPSC_TPTC0] = sys_full_clk,
177 [TNETV107X_LPSC_TPTC1] = sys_full_clk,
178 [TNETV107X_LPSC_RAM] = sys_full_clk,
179 [TNETV107X_LPSC_MBX_LITE] = sys_arm1176_clk,
180 [TNETV107X_LPSC_LCD] = sys_lcd_clk,
181 [TNETV107X_LPSC_ETHSS] = eth_clk_125,
182 [TNETV107X_LPSC_AEMIF] = sys_full_clk,
183 [TNETV107X_LPSC_CHIP_CFG] = sys_half_clk,
184 [TNETV107X_LPSC_TSC] = sys_tsc_clk,
185 [TNETV107X_LPSC_ROM] = sys_half_clk,
186 [TNETV107X_LPSC_UART2] = sys_half_clk,
187 [TNETV107X_LPSC_PKTSEC] = sys_half_clk,
188 [TNETV107X_LPSC_SECCTL] = sys_half_clk,
189 [TNETV107X_LPSC_KEYMGR] = sys_half_clk,
190 [TNETV107X_LPSC_KEYPAD] = sys_half_clk,
191 [TNETV107X_LPSC_GPIO] = sys_half_clk,
192 [TNETV107X_LPSC_MDIO] = sys_half_clk,
193 [TNETV107X_LPSC_SDIO0] = sys_half_clk,
194 [TNETV107X_LPSC_UART0] = sys_half_clk,
195 [TNETV107X_LPSC_UART1] = sys_half_clk,
196 [TNETV107X_LPSC_TIMER0] = sys_half_clk,
197 [TNETV107X_LPSC_TIMER1] = sys_half_clk,
198 [TNETV107X_LPSC_WDT_ARM] = sys_half_clk,
199 [TNETV107X_LPSC_WDT_DSP] = sys_half_clk,
200 [TNETV107X_LPSC_SSP] = sys_half_clk,
201 [TNETV107X_LPSC_TDM0] = tdm_clk,
202 [TNETV107X_LPSC_VLYNQ] = sys_vlynq_ref_clk,
203 [TNETV107X_LPSC_MCDMA] = sys_half_clk,
204 [TNETV107X_LPSC_USB0] = sys_half_clk,
205 [TNETV107X_LPSC_TDM1] = tdm1_clk,
206 [TNETV107X_LPSC_DEBUGSS] = sys_half_clk,
207 [TNETV107X_LPSC_ETHSS_RGMII] = eth_clk_250,
208 [TNETV107X_LPSC_SYSTEM] = sys_half_clk,
209 [TNETV107X_LPSC_IMCOP] = sys_dsp_clk,
210 [TNETV107X_LPSC_SPARE] = sys_half_clk,
211 [TNETV107X_LPSC_SDIO1] = sys_half_clk,
212 [TNETV107X_LPSC_USB1] = sys_half_clk,
213 [TNETV107X_LPSC_USBSS] = sys_half_clk,
214 [TNETV107X_LPSC_DDR2_EMIF1_VRST] = sys_ddr_clk,
215 [TNETV107X_LPSC_DDR2_EMIF2_VCTL_RST] = sys_ddr_clk,
216 };
217
218 static const unsigned long pll_ext_freq[] = {
219 [SYS_PLL] = CONFIG_PLL_SYS_EXT_FREQ,
220 [ETH_PLL] = CONFIG_PLL_ETH_EXT_FREQ,
221 [TDM_PLL] = CONFIG_PLL_TDM_EXT_FREQ,
222 };
223
224 static unsigned long pll_freq_get(int pll)
225 {
226 unsigned long mult = 1, prediv = 1, postdiv = 1;
227 unsigned long ref = CONFIG_SYS_INT_OSC_FREQ;
228 unsigned long ret;
229 u32 bypass;
230
231 bypass = __raw_readl((u32 *)(CLOCK_BASE));
232 if (!(bypass & pll_bypass_mask[pll])) {
233 mult = sspll_reg_read(pll, mult_factor);
234 prediv = sspll_reg_read(pll, prediv) + 1;
235 postdiv = sspll_reg_read(pll, postdiv) + 1;
236 }
237
238 if (pllctl_reg_read(pll, ctl) & PLLCTL_CLKMODE)
239 ref = pll_ext_freq[pll];
240
241 if (!(pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN))
242 return ref;
243
244 ret = (unsigned long)(ref + ((unsigned long long)ref * mult) / 256);
245 ret /= (prediv * postdiv);
246
247 return ret;
248 }
249
250 static unsigned long __pll_div_freq_get(int pll, unsigned int fpll,
251 int div)
252 {
253 int divider = 1;
254 unsigned long divreg;
255
256 divreg = __raw_readl((void *)pllctl_regs[pll] + pll_div_offset[div]);
257
258 if (divreg & PLLDIV_ENABLE)
259 divider = (divreg & pll_div_mask[pll]) + 1;
260
261 return fpll / divider;
262 }
263
264 static unsigned long pll_div_freq_get(int pll, int div)
265 {
266 unsigned int fpll = pll_freq_get(pll);
267
268 return __pll_div_freq_get(pll, fpll, div);
269 }
270
271 static void __pll_div_freq_set(int pll, unsigned int fpll, int div,
272 unsigned long hz)
273 {
274 int divider = (fpll / hz - 1);
275
276 divider &= pll_div_mask[pll];
277 divider |= PLLDIV_ENABLE;
278
279 __raw_writel(divider, (void *)pllctl_regs[pll] + pll_div_offset[div]);
280 pllctl_reg_setbits(pll, alnctl, (1 << div));
281 pllctl_reg_setbits(pll, dchange, (1 << div));
282 }
283
284 static unsigned long pll_div_freq_set(int pll, int div, unsigned long hz)
285 {
286 unsigned int fpll = pll_freq_get(pll);
287
288 __pll_div_freq_set(pll, fpll, div, hz);
289
290 pllctl_reg_write(pll, cmd, 1);
291
292 /* Wait until new divider takes effect */
293 while (pllctl_reg_read(pll, stat) & 0x01);
294
295 return __pll_div_freq_get(pll, fpll, div);
296 }
297
298 unsigned long clk_get_rate(unsigned int clk)
299 {
300 return pll_div_freq_get(lpsc_clk_map[clk].pll, lpsc_clk_map[clk].div);
301 }
302
303 unsigned long clk_round_rate(unsigned int clk, unsigned long hz)
304 {
305 unsigned long fpll, divider, pll;
306
307 pll = lpsc_clk_map[clk].pll;
308 fpll = pll_freq_get(pll);
309 divider = (fpll / hz - 1);
310 divider &= pll_div_mask[pll];
311
312 return fpll / (divider + 1);
313 }
314
315 int clk_set_rate(unsigned int clk, unsigned long _hz)
316 {
317 unsigned long hz;
318
319 hz = clk_round_rate(clk, _hz);
320 if (hz != _hz)
321 return -EINVAL; /* Cannot set to target freq */
322
323 pll_div_freq_set(lpsc_clk_map[clk].pll, lpsc_clk_map[clk].div, hz);
324 return 0;
325 }
326
327 void lpsc_control(int mod, unsigned long state, int lrstz)
328 {
329 u32 mdctl;
330
331 mdctl = psc_reg_read(PSC_MDCTL(mod));
332 mdctl &= ~0x1f;
333 mdctl |= state;
334
335 if (lrstz == 0)
336 mdctl &= ~PSC_MDCTL_LRSTZ;
337 else if (lrstz == 1)
338 mdctl |= PSC_MDCTL_LRSTZ;
339
340 psc_reg_write(PSC_MDCTL(mod), mdctl);
341
342 psc_reg_write(PSC_PTCMD, 1);
343
344 /* wait for power domain transition to end */
345 while (psc_reg_read(PSC_PTSTAT) & 1);
346
347 /* Wait for module state change */
348 while ((psc_reg_read(PSC_MDSTAT(mod)) & 0x1f) != state);
349 }
350
351 int lpsc_status(unsigned int id)
352 {
353 return psc_reg_read(PSC_MDSTAT(id)) & 0x1f;
354 }
355
356 static void init_pll(const struct pll_init_data *data)
357 {
358 unsigned long fpll;
359 unsigned long best_pre = 0, best_post = 0, best_mult = 0;
360 unsigned long div, prediv, postdiv, mult;
361 unsigned long delta, actual;
362 long best_delta = -1;
363 int i;
364 u32 tmp;
365
366 if (data->pll == SYS_PLL)
367 return; /* cannot reconfigure system pll on the fly */
368
369 tmp = pllctl_reg_read(data->pll, ctl);
370 if (data->internal_osc) {
371 tmp &= ~PLLCTL_CLKMODE;
372 fpll = CONFIG_SYS_INT_OSC_FREQ;
373 } else {
374 tmp |= PLLCTL_CLKMODE;
375 fpll = pll_ext_freq[data->pll];
376 }
377 pllctl_reg_write(data->pll, ctl, tmp);
378
379 mult = data->pll_freq / fpll;
380 for (mult = MAX(mult, 1); mult <= MAX_MULT; mult++) {
381 div = (fpll * mult) / data->pll_freq;
382 if (div < 1 || div > MAX_DIV)
383 continue;
384
385 for (postdiv = 1; postdiv <= min(div, MAX_POSTDIV); postdiv++) {
386 prediv = div / postdiv;
387 if (prediv < 1 || prediv > MAX_PREDIV)
388 continue;
389
390 actual = (fpll / prediv) * (mult / postdiv);
391 delta = (actual - data->pll_freq);
392 if (delta < 0)
393 delta = -delta;
394 if ((delta < best_delta) || (best_delta == -1)) {
395 best_delta = delta;
396 best_mult = mult;
397 best_pre = prediv;
398 best_post = postdiv;
399 if (delta == 0)
400 goto done;
401 }
402 }
403 }
404 done:
405
406 if (best_delta == -1) {
407 printf("pll cannot derive %lu from %lu\n",
408 data->pll_freq, fpll);
409 return;
410 }
411
412 fpll = fpll * best_mult;
413 fpll /= best_pre * best_post;
414
415 pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLENSRC);
416 pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLEN);
417
418 pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLRST);
419
420 pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLPWRDN);
421 pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLDIS);
422
423 sspll_reg_write(data->pll, mult_factor, (best_mult - 1) << 8);
424 sspll_reg_write(data->pll, prediv, best_pre - 1);
425 sspll_reg_write(data->pll, postdiv, best_post - 1);
426
427 for (i = 0; i < 10; i++)
428 if (data->div_freq[i])
429 __pll_div_freq_set(data->pll, fpll, i,
430 data->div_freq[i]);
431
432 pllctl_reg_write(data->pll, cmd, 1);
433
434 /* Wait until pll "go" operation completes */
435 while (pllctl_reg_read(data->pll, stat) & 0x01);
436
437 pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLRST);
438 pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLEN);
439 }
440
441 void init_plls(int num_pll, struct pll_init_data *config)
442 {
443 int i;
444
445 for (i = 0; i < num_pll; i++)
446 init_pll(&config[i]);
447 }