Commit | Line | Data |
---|---|---|
b9cc4bf6 KW |
1 | /* |
2 | * arch/arm/mach-lpc32xx/clock.c | |
3 | * | |
4 | * Author: Kevin Wells <kevin.wells@nxp.com> | |
5 | * | |
6 | * Copyright (C) 2010 NXP Semiconductors | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License as published by | |
10 | * the Free Software Foundation; either version 2 of the License, or | |
11 | * (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | */ | |
18 | ||
19 | /* | |
20 | * LPC32xx clock management driver overview | |
21 | * | |
22 | * The LPC32XX contains a number of high level system clocks that can be | |
23 | * generated from different sources. These system clocks are used to | |
24 | * generate the CPU and bus rates and the individual peripheral clocks in | |
25 | * the system. When Linux is started by the boot loader, the system | |
26 | * clocks are already running. Stopping a system clock during normal | |
27 | * Linux operation should never be attempted, as peripherals that require | |
28 | * those clocks will quit working (ie, DRAM). | |
29 | * | |
30 | * The LPC32xx high level clock tree looks as follows. Clocks marked with | |
31 | * an asterisk are always on and cannot be disabled. Clocks marked with | |
32 | * an ampersand can only be disabled in CPU suspend mode. Clocks marked | |
33 | * with a caret are always on if it is the selected clock for the SYSCLK | |
34 | * source. The clock that isn't used for SYSCLK can be enabled and | |
35 | * disabled normally. | |
36 | * 32KHz oscillator* | |
37 | * / | \ | |
38 | * RTC* PLL397^ TOUCH | |
39 | * / | |
40 | * Main oscillator^ / | |
41 | * | \ / | |
42 | * | SYSCLK& | |
43 | * | \ | |
44 | * | \ | |
45 | * USB_PLL HCLK_PLL& | |
46 | * | | | | |
47 | * USB host/device PCLK& | | |
48 | * | | | |
49 | * Peripherals | |
50 | * | |
51 | * The CPU and chip bus rates are derived from the HCLK PLL, which can | |
52 | * generate various clock rates up to 266MHz and beyond. The internal bus | |
53 | * rates (PCLK and HCLK) are generated from dividers based on the HCLK | |
54 | * PLL rate. HCLK can be a ratio of 1:1, 1:2, or 1:4 or HCLK PLL rate, | |
55 | * while PCLK can be 1:1 to 1:32 of HCLK PLL rate. Most peripherals high | |
56 | * level clocks are based on either HCLK or PCLK, but have their own | |
57 | * dividers as part of the IP itself. Because of this, the system clock | |
58 | * rates should not be changed. | |
59 | * | |
60 | * The HCLK PLL is clocked from SYSCLK, which can be derived from the | |
61 | * main oscillator or PLL397. PLL397 generates a rate that is 397 times | |
62 | * the 32KHz oscillator rate. The main oscillator runs at the selected | |
63 | * oscillator/crystal rate on the mosc_in pin of the LPC32xx. This rate | |
64 | * is normally 13MHz, but depends on the selection of external crystals | |
65 | * or oscillators. If USB operation is required, the main oscillator must | |
66 | * be used in the system. | |
67 | * | |
68 | * Switching SYSCLK between sources during normal Linux operation is not | |
69 | * supported. SYSCLK is preset in the bootloader. Because of the | |
70 | * complexities of clock management during clock frequency changes, | |
71 | * there are some limitations to the clock driver explained below: | |
72 | * - The PLL397 and main oscillator can be enabled and disabled by the | |
73 | * clk_enable() and clk_disable() functions unless SYSCLK is based | |
74 | * on that clock. This allows the other oscillator that isn't driving | |
75 | * the HCLK PLL to be used as another system clock that can be routed | |
76 | * to an external pin. | |
77 | * - The muxed SYSCLK input and HCLK_PLL rate cannot be changed with | |
78 | * this driver. | |
79 | * - HCLK and PCLK rates cannot be changed as part of this driver. | |
80 | * - Most peripherals have their own dividers are part of the peripheral | |
81 | * block. Changing SYSCLK, HCLK PLL, HCLK, or PCLK sources or rates | |
82 | * will also impact the individual peripheral rates. | |
83 | */ | |
84 | ||
8998316c | 85 | #include <linux/export.h> |
b9cc4bf6 KW |
86 | #include <linux/kernel.h> |
87 | #include <linux/list.h> | |
88 | #include <linux/errno.h> | |
89 | #include <linux/device.h> | |
48a5dedf | 90 | #include <linux/delay.h> |
b9cc4bf6 KW |
91 | #include <linux/err.h> |
92 | #include <linux/clk.h> | |
93 | #include <linux/amba/bus.h> | |
94 | #include <linux/amba/clcd.h> | |
6d803ba7 | 95 | #include <linux/clkdev.h> |
b9cc4bf6 KW |
96 | |
97 | #include <mach/hardware.h> | |
b9cc4bf6 KW |
98 | #include <mach/platform.h> |
99 | #include "clock.h" | |
100 | #include "common.h" | |
101 | ||
b8451862 RS |
102 | static DEFINE_SPINLOCK(global_clkregs_lock); |
103 | ||
48a5dedf RS |
104 | static int usb_pll_enable, usb_pll_valid; |
105 | ||
b9cc4bf6 KW |
106 | static struct clk clk_armpll; |
107 | static struct clk clk_usbpll; | |
b9cc4bf6 KW |
108 | |
109 | /* | |
110 | * Post divider values for PLLs based on selected register value | |
111 | */ | |
112 | static const u32 pll_postdivs[4] = {1, 2, 4, 8}; | |
113 | ||
114 | static unsigned long local_return_parent_rate(struct clk *clk) | |
115 | { | |
116 | /* | |
117 | * If a clock has a rate of 0, then it inherits it's parent | |
118 | * clock rate | |
119 | */ | |
120 | while (clk->rate == 0) | |
121 | clk = clk->parent; | |
122 | ||
123 | return clk->rate; | |
124 | } | |
125 | ||
126 | /* 32KHz clock has a fixed rate and is not stoppable */ | |
127 | static struct clk osc_32KHz = { | |
128 | .rate = LPC32XX_CLOCK_OSC_FREQ, | |
129 | .get_rate = local_return_parent_rate, | |
130 | }; | |
131 | ||
132 | static int local_pll397_enable(struct clk *clk, int enable) | |
133 | { | |
134 | u32 reg; | |
f40a6818 | 135 | unsigned long timeout = jiffies + msecs_to_jiffies(10); |
b9cc4bf6 KW |
136 | |
137 | reg = __raw_readl(LPC32XX_CLKPWR_PLL397_CTRL); | |
138 | ||
139 | if (enable == 0) { | |
140 | reg |= LPC32XX_CLKPWR_SYSCTRL_PLL397_DIS; | |
141 | __raw_writel(reg, LPC32XX_CLKPWR_PLL397_CTRL); | |
142 | } else { | |
143 | /* Enable PLL397 */ | |
144 | reg &= ~LPC32XX_CLKPWR_SYSCTRL_PLL397_DIS; | |
145 | __raw_writel(reg, LPC32XX_CLKPWR_PLL397_CTRL); | |
146 | ||
147 | /* Wait for PLL397 lock */ | |
148 | while (((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) & | |
149 | LPC32XX_CLKPWR_SYSCTRL_PLL397_STS) == 0) && | |
f40a6818 | 150 | time_before(jiffies, timeout)) |
b9cc4bf6 KW |
151 | cpu_relax(); |
152 | ||
153 | if ((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) & | |
154 | LPC32XX_CLKPWR_SYSCTRL_PLL397_STS) == 0) | |
155 | return -ENODEV; | |
156 | } | |
157 | ||
158 | return 0; | |
159 | } | |
160 | ||
161 | static int local_oscmain_enable(struct clk *clk, int enable) | |
162 | { | |
163 | u32 reg; | |
f40a6818 | 164 | unsigned long timeout = jiffies + msecs_to_jiffies(10); |
b9cc4bf6 KW |
165 | |
166 | reg = __raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL); | |
167 | ||
168 | if (enable == 0) { | |
169 | reg |= LPC32XX_CLKPWR_MOSC_DISABLE; | |
170 | __raw_writel(reg, LPC32XX_CLKPWR_MAIN_OSC_CTRL); | |
171 | } else { | |
172 | /* Enable main oscillator */ | |
173 | reg &= ~LPC32XX_CLKPWR_MOSC_DISABLE; | |
174 | __raw_writel(reg, LPC32XX_CLKPWR_MAIN_OSC_CTRL); | |
175 | ||
176 | /* Wait for main oscillator to start */ | |
177 | while (((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) & | |
178 | LPC32XX_CLKPWR_MOSC_DISABLE) != 0) && | |
f40a6818 | 179 | time_before(jiffies, timeout)) |
b9cc4bf6 KW |
180 | cpu_relax(); |
181 | ||
182 | if ((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) & | |
183 | LPC32XX_CLKPWR_MOSC_DISABLE) != 0) | |
184 | return -ENODEV; | |
185 | } | |
186 | ||
187 | return 0; | |
188 | } | |
189 | ||
190 | static struct clk osc_pll397 = { | |
191 | .parent = &osc_32KHz, | |
192 | .enable = local_pll397_enable, | |
193 | .rate = LPC32XX_CLOCK_OSC_FREQ * 397, | |
194 | .get_rate = local_return_parent_rate, | |
195 | }; | |
196 | ||
197 | static struct clk osc_main = { | |
198 | .enable = local_oscmain_enable, | |
199 | .rate = LPC32XX_MAIN_OSC_FREQ, | |
200 | .get_rate = local_return_parent_rate, | |
201 | }; | |
202 | ||
203 | static struct clk clk_sys; | |
204 | ||
205 | /* | |
206 | * Convert a PLL register value to a PLL output frequency | |
207 | */ | |
208 | u32 clk_get_pllrate_from_reg(u32 inputclk, u32 regval) | |
209 | { | |
210 | struct clk_pll_setup pllcfg; | |
211 | ||
212 | pllcfg.cco_bypass_b15 = 0; | |
213 | pllcfg.direct_output_b14 = 0; | |
214 | pllcfg.fdbk_div_ctrl_b13 = 0; | |
215 | if ((regval & LPC32XX_CLKPWR_HCLKPLL_CCO_BYPASS) != 0) | |
216 | pllcfg.cco_bypass_b15 = 1; | |
217 | if ((regval & LPC32XX_CLKPWR_HCLKPLL_POSTDIV_BYPASS) != 0) | |
218 | pllcfg.direct_output_b14 = 1; | |
219 | if ((regval & LPC32XX_CLKPWR_HCLKPLL_FDBK_SEL_FCLK) != 0) | |
220 | pllcfg.fdbk_div_ctrl_b13 = 1; | |
221 | pllcfg.pll_m = 1 + ((regval >> 1) & 0xFF); | |
222 | pllcfg.pll_n = 1 + ((regval >> 9) & 0x3); | |
223 | pllcfg.pll_p = pll_postdivs[((regval >> 11) & 0x3)]; | |
224 | ||
225 | return clk_check_pll_setup(inputclk, &pllcfg); | |
226 | } | |
227 | ||
228 | /* | |
229 | * Setup the HCLK PLL with a PLL structure | |
230 | */ | |
231 | static u32 local_clk_pll_setup(struct clk_pll_setup *PllSetup) | |
232 | { | |
233 | u32 tv, tmp = 0; | |
234 | ||
235 | if (PllSetup->analog_on != 0) | |
236 | tmp |= LPC32XX_CLKPWR_HCLKPLL_POWER_UP; | |
237 | if (PllSetup->cco_bypass_b15 != 0) | |
238 | tmp |= LPC32XX_CLKPWR_HCLKPLL_CCO_BYPASS; | |
239 | if (PllSetup->direct_output_b14 != 0) | |
240 | tmp |= LPC32XX_CLKPWR_HCLKPLL_POSTDIV_BYPASS; | |
241 | if (PllSetup->fdbk_div_ctrl_b13 != 0) | |
242 | tmp |= LPC32XX_CLKPWR_HCLKPLL_FDBK_SEL_FCLK; | |
243 | ||
244 | tv = ffs(PllSetup->pll_p) - 1; | |
245 | if ((!is_power_of_2(PllSetup->pll_p)) || (tv > 3)) | |
246 | return 0; | |
247 | ||
248 | tmp |= LPC32XX_CLKPWR_HCLKPLL_POSTDIV_2POW(tv); | |
249 | tmp |= LPC32XX_CLKPWR_HCLKPLL_PREDIV_PLUS1(PllSetup->pll_n - 1); | |
250 | tmp |= LPC32XX_CLKPWR_HCLKPLL_PLLM(PllSetup->pll_m - 1); | |
251 | ||
252 | return tmp; | |
253 | } | |
254 | ||
255 | /* | |
256 | * Update the ARM core PLL frequency rate variable from the actual PLL setting | |
257 | */ | |
258 | static void local_update_armpll_rate(void) | |
259 | { | |
260 | u32 clkin, pllreg; | |
261 | ||
262 | clkin = clk_armpll.parent->rate; | |
263 | pllreg = __raw_readl(LPC32XX_CLKPWR_HCLKPLL_CTRL) & 0x1FFFF; | |
264 | ||
265 | clk_armpll.rate = clk_get_pllrate_from_reg(clkin, pllreg); | |
266 | } | |
267 | ||
268 | /* | |
269 | * Find a PLL configuration for the selected input frequency | |
270 | */ | |
271 | static u32 local_clk_find_pll_cfg(u32 pllin_freq, u32 target_freq, | |
272 | struct clk_pll_setup *pllsetup) | |
273 | { | |
274 | u32 ifreq, freqtol, m, n, p, fclkout; | |
275 | ||
276 | /* Determine frequency tolerance limits */ | |
277 | freqtol = target_freq / 250; | |
278 | ifreq = pllin_freq; | |
279 | ||
280 | /* Is direct bypass mode possible? */ | |
281 | if (abs(pllin_freq - target_freq) <= freqtol) { | |
282 | pllsetup->analog_on = 0; | |
283 | pllsetup->cco_bypass_b15 = 1; | |
284 | pllsetup->direct_output_b14 = 1; | |
285 | pllsetup->fdbk_div_ctrl_b13 = 1; | |
286 | pllsetup->pll_p = pll_postdivs[0]; | |
287 | pllsetup->pll_n = 1; | |
288 | pllsetup->pll_m = 1; | |
289 | return clk_check_pll_setup(ifreq, pllsetup); | |
290 | } else if (target_freq <= ifreq) { | |
291 | pllsetup->analog_on = 0; | |
292 | pllsetup->cco_bypass_b15 = 1; | |
293 | pllsetup->direct_output_b14 = 0; | |
294 | pllsetup->fdbk_div_ctrl_b13 = 1; | |
295 | pllsetup->pll_n = 1; | |
296 | pllsetup->pll_m = 1; | |
297 | for (p = 0; p <= 3; p++) { | |
298 | pllsetup->pll_p = pll_postdivs[p]; | |
299 | fclkout = clk_check_pll_setup(ifreq, pllsetup); | |
300 | if (abs(target_freq - fclkout) <= freqtol) | |
301 | return fclkout; | |
302 | } | |
303 | } | |
304 | ||
305 | /* Is direct mode possible? */ | |
306 | pllsetup->analog_on = 1; | |
307 | pllsetup->cco_bypass_b15 = 0; | |
308 | pllsetup->direct_output_b14 = 1; | |
309 | pllsetup->fdbk_div_ctrl_b13 = 0; | |
310 | pllsetup->pll_p = pll_postdivs[0]; | |
311 | for (m = 1; m <= 256; m++) { | |
312 | for (n = 1; n <= 4; n++) { | |
313 | /* Compute output frequency for this value */ | |
314 | pllsetup->pll_n = n; | |
315 | pllsetup->pll_m = m; | |
316 | fclkout = clk_check_pll_setup(ifreq, | |
317 | pllsetup); | |
318 | if (abs(target_freq - fclkout) <= | |
319 | freqtol) | |
320 | return fclkout; | |
321 | } | |
322 | } | |
323 | ||
324 | /* Is integer mode possible? */ | |
325 | pllsetup->analog_on = 1; | |
326 | pllsetup->cco_bypass_b15 = 0; | |
327 | pllsetup->direct_output_b14 = 0; | |
328 | pllsetup->fdbk_div_ctrl_b13 = 1; | |
329 | for (m = 1; m <= 256; m++) { | |
330 | for (n = 1; n <= 4; n++) { | |
331 | for (p = 0; p < 4; p++) { | |
332 | /* Compute output frequency */ | |
333 | pllsetup->pll_p = pll_postdivs[p]; | |
334 | pllsetup->pll_n = n; | |
335 | pllsetup->pll_m = m; | |
336 | fclkout = clk_check_pll_setup( | |
337 | ifreq, pllsetup); | |
338 | if (abs(target_freq - fclkout) <= freqtol) | |
339 | return fclkout; | |
340 | } | |
341 | } | |
342 | } | |
343 | ||
344 | /* Try non-integer mode */ | |
345 | pllsetup->analog_on = 1; | |
346 | pllsetup->cco_bypass_b15 = 0; | |
347 | pllsetup->direct_output_b14 = 0; | |
348 | pllsetup->fdbk_div_ctrl_b13 = 0; | |
349 | for (m = 1; m <= 256; m++) { | |
350 | for (n = 1; n <= 4; n++) { | |
351 | for (p = 0; p < 4; p++) { | |
352 | /* Compute output frequency */ | |
353 | pllsetup->pll_p = pll_postdivs[p]; | |
354 | pllsetup->pll_n = n; | |
355 | pllsetup->pll_m = m; | |
356 | fclkout = clk_check_pll_setup( | |
357 | ifreq, pllsetup); | |
358 | if (abs(target_freq - fclkout) <= freqtol) | |
359 | return fclkout; | |
360 | } | |
361 | } | |
362 | } | |
363 | ||
364 | return 0; | |
365 | } | |
366 | ||
367 | static struct clk clk_armpll = { | |
368 | .parent = &clk_sys, | |
369 | .get_rate = local_return_parent_rate, | |
370 | }; | |
371 | ||
372 | /* | |
373 | * Setup the USB PLL with a PLL structure | |
374 | */ | |
375 | static u32 local_clk_usbpll_setup(struct clk_pll_setup *pHCLKPllSetup) | |
376 | { | |
377 | u32 reg, tmp = local_clk_pll_setup(pHCLKPllSetup); | |
378 | ||
379 | reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL) & ~0x1FFFF; | |
380 | reg |= tmp; | |
381 | __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); | |
382 | ||
383 | return clk_check_pll_setup(clk_usbpll.parent->rate, | |
384 | pHCLKPllSetup); | |
385 | } | |
386 | ||
387 | static int local_usbpll_enable(struct clk *clk, int enable) | |
388 | { | |
389 | u32 reg; | |
48a5dedf RS |
390 | int ret = 0; |
391 | unsigned long timeout = jiffies + msecs_to_jiffies(20); | |
b9cc4bf6 KW |
392 | |
393 | reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); | |
394 | ||
48a5dedf RS |
395 | __raw_writel(reg & ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN2 | |
396 | LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP), | |
397 | LPC32XX_CLKPWR_USB_CTRL); | |
398 | __raw_writel(reg & ~LPC32XX_CLKPWR_USBCTRL_CLK_EN1, | |
399 | LPC32XX_CLKPWR_USB_CTRL); | |
400 | ||
401 | if (enable && usb_pll_valid && usb_pll_enable) { | |
402 | ret = -ENODEV; | |
403 | /* | |
404 | * If the PLL rate has been previously set, then the rate | |
405 | * in the PLL register is valid and can be enabled here. | |
406 | * Otherwise, it needs to be enabled as part of setrate. | |
407 | */ | |
408 | ||
409 | /* | |
410 | * Gate clock into PLL | |
411 | */ | |
b9cc4bf6 KW |
412 | reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN1; |
413 | __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); | |
414 | ||
48a5dedf RS |
415 | /* |
416 | * Enable PLL | |
417 | */ | |
418 | reg |= LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP; | |
419 | __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); | |
420 | ||
421 | /* | |
422 | * Wait for PLL to lock | |
423 | */ | |
f40a6818 | 424 | while (time_before(jiffies, timeout) && (ret == -ENODEV)) { |
b9cc4bf6 KW |
425 | reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); |
426 | if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_STS) | |
427 | ret = 0; | |
48a5dedf RS |
428 | else |
429 | udelay(10); | |
b9cc4bf6 KW |
430 | } |
431 | ||
48a5dedf RS |
432 | /* |
433 | * Gate clock from PLL if PLL is locked | |
434 | */ | |
b9cc4bf6 | 435 | if (ret == 0) { |
48a5dedf RS |
436 | __raw_writel(reg | LPC32XX_CLKPWR_USBCTRL_CLK_EN2, |
437 | LPC32XX_CLKPWR_USB_CTRL); | |
438 | } else { | |
439 | __raw_writel(reg & ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN1 | | |
440 | LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP), | |
441 | LPC32XX_CLKPWR_USB_CTRL); | |
b9cc4bf6 | 442 | } |
48a5dedf RS |
443 | } else if ((enable == 0) && usb_pll_valid && usb_pll_enable) { |
444 | usb_pll_valid = 0; | |
445 | usb_pll_enable = 0; | |
b9cc4bf6 KW |
446 | } |
447 | ||
448 | return ret; | |
449 | } | |
450 | ||
451 | static unsigned long local_usbpll_round_rate(struct clk *clk, | |
452 | unsigned long rate) | |
453 | { | |
454 | u32 clkin, usbdiv; | |
455 | struct clk_pll_setup pllsetup; | |
456 | ||
457 | /* | |
458 | * Unlike other clocks, this clock has a KHz input rate, so bump | |
459 | * it up to work with the PLL function | |
460 | */ | |
461 | rate = rate * 1000; | |
462 | ||
48a5dedf | 463 | clkin = clk->get_rate(clk); |
b9cc4bf6 KW |
464 | usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) & |
465 | LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1; | |
466 | clkin = clkin / usbdiv; | |
467 | ||
468 | /* Try to find a good rate setup */ | |
469 | if (local_clk_find_pll_cfg(clkin, rate, &pllsetup) == 0) | |
470 | return 0; | |
471 | ||
472 | return clk_check_pll_setup(clkin, &pllsetup); | |
473 | } | |
474 | ||
475 | static int local_usbpll_set_rate(struct clk *clk, unsigned long rate) | |
476 | { | |
48a5dedf RS |
477 | int ret = -ENODEV; |
478 | u32 clkin, usbdiv; | |
b9cc4bf6 KW |
479 | struct clk_pll_setup pllsetup; |
480 | ||
481 | /* | |
482 | * Unlike other clocks, this clock has a KHz input rate, so bump | |
483 | * it up to work with the PLL function | |
484 | */ | |
485 | rate = rate * 1000; | |
486 | ||
48a5dedf | 487 | clkin = clk->get_rate(clk->parent); |
b9cc4bf6 KW |
488 | usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) & |
489 | LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1; | |
490 | clkin = clkin / usbdiv; | |
491 | ||
492 | /* Try to find a good rate setup */ | |
493 | if (local_clk_find_pll_cfg(clkin, rate, &pllsetup) == 0) | |
494 | return -EINVAL; | |
495 | ||
48a5dedf RS |
496 | /* |
497 | * Disable PLL clocks during PLL change | |
498 | */ | |
b9cc4bf6 | 499 | local_usbpll_enable(clk, 0); |
48a5dedf | 500 | pllsetup.analog_on = 0; |
b9cc4bf6 KW |
501 | local_clk_usbpll_setup(&pllsetup); |
502 | ||
48a5dedf RS |
503 | /* |
504 | * Start USB PLL and check PLL status | |
505 | */ | |
506 | ||
507 | usb_pll_valid = 1; | |
508 | usb_pll_enable = 1; | |
b9cc4bf6 | 509 | |
48a5dedf RS |
510 | ret = local_usbpll_enable(clk, 1); |
511 | if (ret >= 0) | |
512 | clk->rate = clk_check_pll_setup(clkin, &pllsetup); | |
b9cc4bf6 | 513 | |
48a5dedf | 514 | return ret; |
b9cc4bf6 KW |
515 | } |
516 | ||
517 | static struct clk clk_usbpll = { | |
518 | .parent = &osc_main, | |
519 | .set_rate = local_usbpll_set_rate, | |
520 | .enable = local_usbpll_enable, | |
521 | .rate = 48000, /* In KHz */ | |
522 | .get_rate = local_return_parent_rate, | |
523 | .round_rate = local_usbpll_round_rate, | |
524 | }; | |
525 | ||
526 | static u32 clk_get_hclk_div(void) | |
527 | { | |
528 | static const u32 hclkdivs[4] = {1, 2, 4, 4}; | |
529 | return hclkdivs[LPC32XX_CLKPWR_HCLKDIV_DIV_2POW( | |
530 | __raw_readl(LPC32XX_CLKPWR_HCLK_DIV))]; | |
531 | } | |
532 | ||
533 | static struct clk clk_hclk = { | |
534 | .parent = &clk_armpll, | |
535 | .get_rate = local_return_parent_rate, | |
536 | }; | |
537 | ||
538 | static struct clk clk_pclk = { | |
539 | .parent = &clk_armpll, | |
540 | .get_rate = local_return_parent_rate, | |
541 | }; | |
542 | ||
543 | static int local_onoff_enable(struct clk *clk, int enable) | |
544 | { | |
545 | u32 tmp; | |
546 | ||
547 | tmp = __raw_readl(clk->enable_reg); | |
548 | ||
549 | if (enable == 0) | |
550 | tmp &= ~clk->enable_mask; | |
551 | else | |
552 | tmp |= clk->enable_mask; | |
553 | ||
554 | __raw_writel(tmp, clk->enable_reg); | |
555 | ||
556 | return 0; | |
557 | } | |
558 | ||
559 | /* Peripheral clock sources */ | |
560 | static struct clk clk_timer0 = { | |
561 | .parent = &clk_pclk, | |
562 | .enable = local_onoff_enable, | |
563 | .enable_reg = LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1, | |
564 | .enable_mask = LPC32XX_CLKPWR_TMRPWMCLK_TIMER0_EN, | |
565 | .get_rate = local_return_parent_rate, | |
566 | }; | |
567 | static struct clk clk_timer1 = { | |
568 | .parent = &clk_pclk, | |
569 | .enable = local_onoff_enable, | |
570 | .enable_reg = LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1, | |
571 | .enable_mask = LPC32XX_CLKPWR_TMRPWMCLK_TIMER1_EN, | |
572 | .get_rate = local_return_parent_rate, | |
573 | }; | |
574 | static struct clk clk_timer2 = { | |
575 | .parent = &clk_pclk, | |
576 | .enable = local_onoff_enable, | |
577 | .enable_reg = LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1, | |
578 | .enable_mask = LPC32XX_CLKPWR_TMRPWMCLK_TIMER2_EN, | |
579 | .get_rate = local_return_parent_rate, | |
580 | }; | |
581 | static struct clk clk_timer3 = { | |
582 | .parent = &clk_pclk, | |
583 | .enable = local_onoff_enable, | |
584 | .enable_reg = LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1, | |
585 | .enable_mask = LPC32XX_CLKPWR_TMRPWMCLK_TIMER3_EN, | |
586 | .get_rate = local_return_parent_rate, | |
587 | }; | |
588 | static struct clk clk_wdt = { | |
589 | .parent = &clk_pclk, | |
590 | .enable = local_onoff_enable, | |
591 | .enable_reg = LPC32XX_CLKPWR_TIMER_CLK_CTRL, | |
592 | .enable_mask = LPC32XX_CLKPWR_PWMCLK_WDOG_EN, | |
593 | .get_rate = local_return_parent_rate, | |
594 | }; | |
595 | static struct clk clk_vfp9 = { | |
596 | .parent = &clk_pclk, | |
597 | .enable = local_onoff_enable, | |
598 | .enable_reg = LPC32XX_CLKPWR_DEBUG_CTRL, | |
599 | .enable_mask = LPC32XX_CLKPWR_VFP_CLOCK_ENABLE_BIT, | |
600 | .get_rate = local_return_parent_rate, | |
601 | }; | |
602 | static struct clk clk_dma = { | |
603 | .parent = &clk_hclk, | |
604 | .enable = local_onoff_enable, | |
605 | .enable_reg = LPC32XX_CLKPWR_DMA_CLK_CTRL, | |
606 | .enable_mask = LPC32XX_CLKPWR_DMACLKCTRL_CLK_EN, | |
607 | .get_rate = local_return_parent_rate, | |
608 | }; | |
609 | ||
1f37a3a3 APS |
610 | static struct clk clk_pwm = { |
611 | .parent = &clk_pclk, | |
612 | .enable = local_onoff_enable, | |
613 | .enable_reg = LPC32XX_CLKPWR_PWM_CLK_CTRL, | |
614 | .enable_mask = LPC32XX_CLKPWR_PWMCLK_PWM1CLK_EN | | |
615 | LPC32XX_CLKPWR_PWMCLK_PWM1SEL_PCLK | | |
616 | LPC32XX_CLKPWR_PWMCLK_PWM1_DIV(1) | | |
617 | LPC32XX_CLKPWR_PWMCLK_PWM2CLK_EN | | |
618 | LPC32XX_CLKPWR_PWMCLK_PWM2SEL_PCLK | | |
619 | LPC32XX_CLKPWR_PWMCLK_PWM2_DIV(1), | |
620 | .get_rate = local_return_parent_rate, | |
621 | }; | |
622 | ||
b9cc4bf6 KW |
623 | static struct clk clk_uart3 = { |
624 | .parent = &clk_pclk, | |
625 | .enable = local_onoff_enable, | |
626 | .enable_reg = LPC32XX_CLKPWR_UART_CLK_CTRL, | |
627 | .enable_mask = LPC32XX_CLKPWR_UARTCLKCTRL_UART3_EN, | |
628 | .get_rate = local_return_parent_rate, | |
629 | }; | |
630 | ||
631 | static struct clk clk_uart4 = { | |
632 | .parent = &clk_pclk, | |
633 | .enable = local_onoff_enable, | |
634 | .enable_reg = LPC32XX_CLKPWR_UART_CLK_CTRL, | |
635 | .enable_mask = LPC32XX_CLKPWR_UARTCLKCTRL_UART4_EN, | |
636 | .get_rate = local_return_parent_rate, | |
637 | }; | |
638 | ||
639 | static struct clk clk_uart5 = { | |
640 | .parent = &clk_pclk, | |
641 | .enable = local_onoff_enable, | |
642 | .enable_reg = LPC32XX_CLKPWR_UART_CLK_CTRL, | |
643 | .enable_mask = LPC32XX_CLKPWR_UARTCLKCTRL_UART5_EN, | |
644 | .get_rate = local_return_parent_rate, | |
645 | }; | |
646 | ||
647 | static struct clk clk_uart6 = { | |
648 | .parent = &clk_pclk, | |
649 | .enable = local_onoff_enable, | |
650 | .enable_reg = LPC32XX_CLKPWR_UART_CLK_CTRL, | |
651 | .enable_mask = LPC32XX_CLKPWR_UARTCLKCTRL_UART6_EN, | |
652 | .get_rate = local_return_parent_rate, | |
653 | }; | |
654 | ||
655 | static struct clk clk_i2c0 = { | |
656 | .parent = &clk_hclk, | |
657 | .enable = local_onoff_enable, | |
658 | .enable_reg = LPC32XX_CLKPWR_I2C_CLK_CTRL, | |
659 | .enable_mask = LPC32XX_CLKPWR_I2CCLK_I2C1CLK_EN, | |
660 | .get_rate = local_return_parent_rate, | |
661 | }; | |
662 | ||
663 | static struct clk clk_i2c1 = { | |
664 | .parent = &clk_hclk, | |
665 | .enable = local_onoff_enable, | |
666 | .enable_reg = LPC32XX_CLKPWR_I2C_CLK_CTRL, | |
667 | .enable_mask = LPC32XX_CLKPWR_I2CCLK_I2C2CLK_EN, | |
668 | .get_rate = local_return_parent_rate, | |
669 | }; | |
670 | ||
671 | static struct clk clk_i2c2 = { | |
672 | .parent = &clk_pclk, | |
673 | .enable = local_onoff_enable, | |
674 | .enable_reg = io_p2v(LPC32XX_USB_BASE + 0xFF4), | |
675 | .enable_mask = 0x4, | |
676 | .get_rate = local_return_parent_rate, | |
677 | }; | |
678 | ||
679 | static struct clk clk_ssp0 = { | |
680 | .parent = &clk_hclk, | |
681 | .enable = local_onoff_enable, | |
682 | .enable_reg = LPC32XX_CLKPWR_SSP_CLK_CTRL, | |
683 | .enable_mask = LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN, | |
684 | .get_rate = local_return_parent_rate, | |
685 | }; | |
686 | ||
687 | static struct clk clk_ssp1 = { | |
688 | .parent = &clk_hclk, | |
689 | .enable = local_onoff_enable, | |
690 | .enable_reg = LPC32XX_CLKPWR_SSP_CLK_CTRL, | |
691 | .enable_mask = LPC32XX_CLKPWR_SSPCTRL_SSPCLK1_EN, | |
692 | .get_rate = local_return_parent_rate, | |
693 | }; | |
694 | ||
695 | static struct clk clk_kscan = { | |
696 | .parent = &osc_32KHz, | |
697 | .enable = local_onoff_enable, | |
698 | .enable_reg = LPC32XX_CLKPWR_KEY_CLK_CTRL, | |
699 | .enable_mask = LPC32XX_CLKPWR_KEYCLKCTRL_CLK_EN, | |
700 | .get_rate = local_return_parent_rate, | |
701 | }; | |
702 | ||
703 | static struct clk clk_nand = { | |
704 | .parent = &clk_hclk, | |
705 | .enable = local_onoff_enable, | |
706 | .enable_reg = LPC32XX_CLKPWR_NAND_CLK_CTRL, | |
b27f4822 RS |
707 | .enable_mask = LPC32XX_CLKPWR_NANDCLK_SLCCLK_EN | |
708 | LPC32XX_CLKPWR_NANDCLK_SEL_SLC, | |
b9cc4bf6 KW |
709 | .get_rate = local_return_parent_rate, |
710 | }; | |
711 | ||
b27f4822 RS |
712 | static struct clk clk_nand_mlc = { |
713 | .parent = &clk_hclk, | |
714 | .enable = local_onoff_enable, | |
715 | .enable_reg = LPC32XX_CLKPWR_NAND_CLK_CTRL, | |
716 | .enable_mask = LPC32XX_CLKPWR_NANDCLK_MLCCLK_EN | | |
717 | LPC32XX_CLKPWR_NANDCLK_DMA_INT | | |
718 | LPC32XX_CLKPWR_NANDCLK_INTSEL_MLC, | |
719 | .get_rate = local_return_parent_rate, | |
720 | }; | |
721 | ||
b9cc4bf6 KW |
722 | static struct clk clk_i2s0 = { |
723 | .parent = &clk_hclk, | |
724 | .enable = local_onoff_enable, | |
725 | .enable_reg = LPC32XX_CLKPWR_I2S_CLK_CTRL, | |
726 | .enable_mask = LPC32XX_CLKPWR_I2SCTRL_I2SCLK0_EN, | |
727 | .get_rate = local_return_parent_rate, | |
728 | }; | |
729 | ||
730 | static struct clk clk_i2s1 = { | |
731 | .parent = &clk_hclk, | |
732 | .enable = local_onoff_enable, | |
733 | .enable_reg = LPC32XX_CLKPWR_I2S_CLK_CTRL, | |
df072717 APS |
734 | .enable_mask = LPC32XX_CLKPWR_I2SCTRL_I2SCLK1_EN | |
735 | LPC32XX_CLKPWR_I2SCTRL_I2S1_USE_DMA, | |
b9cc4bf6 KW |
736 | .get_rate = local_return_parent_rate, |
737 | }; | |
738 | ||
739 | static struct clk clk_net = { | |
740 | .parent = &clk_hclk, | |
741 | .enable = local_onoff_enable, | |
742 | .enable_reg = LPC32XX_CLKPWR_MACCLK_CTRL, | |
743 | .enable_mask = (LPC32XX_CLKPWR_MACCTRL_DMACLK_EN | | |
744 | LPC32XX_CLKPWR_MACCTRL_MMIOCLK_EN | | |
745 | LPC32XX_CLKPWR_MACCTRL_HRCCLK_EN), | |
746 | .get_rate = local_return_parent_rate, | |
747 | }; | |
748 | ||
749 | static struct clk clk_rtc = { | |
750 | .parent = &osc_32KHz, | |
751 | .rate = 1, /* 1 Hz */ | |
752 | .get_rate = local_return_parent_rate, | |
753 | }; | |
754 | ||
a408e8f4 APS |
755 | static int local_usb_enable(struct clk *clk, int enable) |
756 | { | |
757 | u32 tmp; | |
758 | ||
759 | if (enable) { | |
760 | /* Set up I2C pull levels */ | |
761 | tmp = __raw_readl(LPC32XX_CLKPWR_I2C_CLK_CTRL); | |
762 | tmp |= LPC32XX_CLKPWR_I2CCLK_USBI2CHI_DRIVE; | |
763 | __raw_writel(tmp, LPC32XX_CLKPWR_I2C_CLK_CTRL); | |
764 | } | |
765 | ||
766 | return local_onoff_enable(clk, enable); | |
767 | } | |
768 | ||
b9cc4bf6 KW |
769 | static struct clk clk_usbd = { |
770 | .parent = &clk_usbpll, | |
a408e8f4 | 771 | .enable = local_usb_enable, |
b9cc4bf6 KW |
772 | .enable_reg = LPC32XX_CLKPWR_USB_CTRL, |
773 | .enable_mask = LPC32XX_CLKPWR_USBCTRL_HCLK_EN, | |
774 | .get_rate = local_return_parent_rate, | |
775 | }; | |
776 | ||
a408e8f4 APS |
777 | #define OTG_ALWAYS_MASK (LPC32XX_USB_OTG_OTG_CLOCK_ON | \ |
778 | LPC32XX_USB_OTG_I2C_CLOCK_ON) | |
779 | ||
780 | static int local_usb_otg_enable(struct clk *clk, int enable) | |
781 | { | |
782 | int to = 1000; | |
783 | ||
784 | if (enable) { | |
785 | __raw_writel(clk->enable_mask, clk->enable_reg); | |
786 | ||
787 | while (((__raw_readl(LPC32XX_USB_OTG_CLK_STAT) & | |
788 | clk->enable_mask) != clk->enable_mask) && (to > 0)) | |
789 | to--; | |
790 | } else { | |
791 | __raw_writel(OTG_ALWAYS_MASK, clk->enable_reg); | |
792 | ||
793 | while (((__raw_readl(LPC32XX_USB_OTG_CLK_STAT) & | |
794 | OTG_ALWAYS_MASK) != OTG_ALWAYS_MASK) && (to > 0)) | |
795 | to--; | |
796 | } | |
797 | ||
798 | if (to) | |
799 | return 0; | |
800 | else | |
801 | return -1; | |
802 | } | |
803 | ||
804 | static struct clk clk_usb_otg_dev = { | |
805 | .parent = &clk_usbpll, | |
806 | .enable = local_usb_otg_enable, | |
807 | .enable_reg = LPC32XX_USB_OTG_CLK_CTRL, | |
808 | .enable_mask = LPC32XX_USB_OTG_AHB_M_CLOCK_ON | | |
809 | LPC32XX_USB_OTG_OTG_CLOCK_ON | | |
810 | LPC32XX_USB_OTG_DEV_CLOCK_ON | | |
811 | LPC32XX_USB_OTG_I2C_CLOCK_ON, | |
812 | .get_rate = local_return_parent_rate, | |
813 | }; | |
814 | ||
815 | static struct clk clk_usb_otg_host = { | |
816 | .parent = &clk_usbpll, | |
817 | .enable = local_usb_otg_enable, | |
818 | .enable_reg = LPC32XX_USB_OTG_CLK_CTRL, | |
819 | .enable_mask = LPC32XX_USB_OTG_AHB_M_CLOCK_ON | | |
820 | LPC32XX_USB_OTG_OTG_CLOCK_ON | | |
821 | LPC32XX_USB_OTG_HOST_CLOCK_ON | | |
822 | LPC32XX_USB_OTG_I2C_CLOCK_ON, | |
823 | .get_rate = local_return_parent_rate, | |
824 | }; | |
825 | ||
b9cc4bf6 KW |
826 | static int tsc_onoff_enable(struct clk *clk, int enable) |
827 | { | |
828 | u32 tmp; | |
829 | ||
830 | /* Make sure 32KHz clock is the selected clock */ | |
831 | tmp = __raw_readl(LPC32XX_CLKPWR_ADC_CLK_CTRL_1); | |
832 | tmp &= ~LPC32XX_CLKPWR_ADCCTRL1_PCLK_SEL; | |
833 | __raw_writel(tmp, LPC32XX_CLKPWR_ADC_CLK_CTRL_1); | |
834 | ||
835 | if (enable == 0) | |
836 | __raw_writel(0, clk->enable_reg); | |
837 | else | |
838 | __raw_writel(clk->enable_mask, clk->enable_reg); | |
839 | ||
840 | return 0; | |
841 | } | |
842 | ||
843 | static struct clk clk_tsc = { | |
844 | .parent = &osc_32KHz, | |
845 | .enable = tsc_onoff_enable, | |
846 | .enable_reg = LPC32XX_CLKPWR_ADC_CLK_CTRL, | |
847 | .enable_mask = LPC32XX_CLKPWR_ADC32CLKCTRL_CLK_EN, | |
848 | .get_rate = local_return_parent_rate, | |
849 | }; | |
850 | ||
678a0222 RS |
851 | static int adc_onoff_enable(struct clk *clk, int enable) |
852 | { | |
853 | u32 tmp; | |
854 | u32 divider; | |
855 | ||
856 | /* Use PERIPH_CLOCK */ | |
857 | tmp = __raw_readl(LPC32XX_CLKPWR_ADC_CLK_CTRL_1); | |
858 | tmp |= LPC32XX_CLKPWR_ADCCTRL1_PCLK_SEL; | |
859 | /* | |
860 | * Set clock divider so that we have equal to or less than | |
861 | * 4.5MHz clock at ADC | |
862 | */ | |
863 | divider = clk->get_rate(clk) / 4500000 + 1; | |
864 | tmp |= divider; | |
865 | __raw_writel(tmp, LPC32XX_CLKPWR_ADC_CLK_CTRL_1); | |
866 | ||
867 | /* synchronize rate of this clock w/ actual HW setting */ | |
868 | clk->rate = clk->get_rate(clk->parent) / divider; | |
869 | ||
870 | if (enable == 0) | |
871 | __raw_writel(0, clk->enable_reg); | |
872 | else | |
873 | __raw_writel(clk->enable_mask, clk->enable_reg); | |
874 | ||
875 | return 0; | |
876 | } | |
877 | ||
878 | static struct clk clk_adc = { | |
879 | .parent = &clk_pclk, | |
880 | .enable = adc_onoff_enable, | |
881 | .enable_reg = LPC32XX_CLKPWR_ADC_CLK_CTRL, | |
882 | .enable_mask = LPC32XX_CLKPWR_ADC32CLKCTRL_CLK_EN, | |
883 | .get_rate = local_return_parent_rate, | |
884 | }; | |
885 | ||
b9cc4bf6 KW |
886 | static int mmc_onoff_enable(struct clk *clk, int enable) |
887 | { | |
888 | u32 tmp; | |
889 | ||
890 | tmp = __raw_readl(LPC32XX_CLKPWR_MS_CTRL) & | |
5df5d01d | 891 | ~(LPC32XX_CLKPWR_MSCARD_SDCARD_EN | |
b0d9ef0e RS |
892 | LPC32XX_CLKPWR_MSCARD_MSDIO_PU_EN | |
893 | LPC32XX_CLKPWR_MSCARD_MSDIO_PIN_DIS | | |
894 | LPC32XX_CLKPWR_MSCARD_MSDIO0_DIS | | |
895 | LPC32XX_CLKPWR_MSCARD_MSDIO1_DIS | | |
896 | LPC32XX_CLKPWR_MSCARD_MSDIO23_DIS); | |
b9cc4bf6 KW |
897 | |
898 | /* If rate is 0, disable clock */ | |
899 | if (enable != 0) | |
5df5d01d RS |
900 | tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_EN | |
901 | LPC32XX_CLKPWR_MSCARD_MSDIO_PU_EN; | |
b9cc4bf6 KW |
902 | |
903 | __raw_writel(tmp, LPC32XX_CLKPWR_MS_CTRL); | |
904 | ||
905 | return 0; | |
906 | } | |
907 | ||
908 | static unsigned long mmc_get_rate(struct clk *clk) | |
909 | { | |
910 | u32 div, rate, oldclk; | |
911 | ||
912 | /* The MMC clock must be on when accessing an MMC register */ | |
913 | oldclk = __raw_readl(LPC32XX_CLKPWR_MS_CTRL); | |
914 | __raw_writel(oldclk | LPC32XX_CLKPWR_MSCARD_SDCARD_EN, | |
915 | LPC32XX_CLKPWR_MS_CTRL); | |
916 | div = __raw_readl(LPC32XX_CLKPWR_MS_CTRL); | |
917 | __raw_writel(oldclk, LPC32XX_CLKPWR_MS_CTRL); | |
918 | ||
919 | /* Get the parent clock rate */ | |
920 | rate = clk->parent->get_rate(clk->parent); | |
921 | ||
922 | /* Get the MMC controller clock divider value */ | |
923 | div = div & LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(0xf); | |
924 | ||
925 | if (!div) | |
926 | div = 1; | |
927 | ||
928 | return rate / div; | |
929 | } | |
930 | ||
931 | static unsigned long mmc_round_rate(struct clk *clk, unsigned long rate) | |
932 | { | |
933 | unsigned long div, prate; | |
934 | ||
935 | /* Get the parent clock rate */ | |
936 | prate = clk->parent->get_rate(clk->parent); | |
937 | ||
938 | if (rate >= prate) | |
939 | return prate; | |
940 | ||
941 | div = prate / rate; | |
942 | if (div > 0xf) | |
943 | div = 0xf; | |
944 | ||
945 | return prate / div; | |
946 | } | |
947 | ||
948 | static int mmc_set_rate(struct clk *clk, unsigned long rate) | |
949 | { | |
a0a30b6a | 950 | u32 tmp; |
b9cc4bf6 KW |
951 | unsigned long prate, div, crate = mmc_round_rate(clk, rate); |
952 | ||
953 | prate = clk->parent->get_rate(clk->parent); | |
954 | ||
955 | div = prate / crate; | |
956 | ||
957 | /* The MMC clock must be on when accessing an MMC register */ | |
b9cc4bf6 KW |
958 | tmp = __raw_readl(LPC32XX_CLKPWR_MS_CTRL) & |
959 | ~LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(0xf); | |
a0a30b6a RS |
960 | tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(div) | |
961 | LPC32XX_CLKPWR_MSCARD_SDCARD_EN; | |
b9cc4bf6 KW |
962 | __raw_writel(tmp, LPC32XX_CLKPWR_MS_CTRL); |
963 | ||
b9cc4bf6 KW |
964 | return 0; |
965 | } | |
966 | ||
967 | static struct clk clk_mmc = { | |
968 | .parent = &clk_armpll, | |
969 | .set_rate = mmc_set_rate, | |
970 | .get_rate = mmc_get_rate, | |
971 | .round_rate = mmc_round_rate, | |
972 | .enable = mmc_onoff_enable, | |
973 | .enable_reg = LPC32XX_CLKPWR_MS_CTRL, | |
974 | .enable_mask = LPC32XX_CLKPWR_MSCARD_SDCARD_EN, | |
975 | }; | |
976 | ||
977 | static unsigned long clcd_get_rate(struct clk *clk) | |
978 | { | |
979 | u32 tmp, div, rate, oldclk; | |
980 | ||
981 | /* The LCD clock must be on when accessing an LCD register */ | |
982 | oldclk = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL); | |
983 | __raw_writel(oldclk | LPC32XX_CLKPWR_LCDCTRL_CLK_EN, | |
984 | LPC32XX_CLKPWR_LCDCLK_CTRL); | |
985 | tmp = __raw_readl(io_p2v(LPC32XX_LCD_BASE + CLCD_TIM2)); | |
986 | __raw_writel(oldclk, LPC32XX_CLKPWR_LCDCLK_CTRL); | |
987 | ||
988 | rate = clk->parent->get_rate(clk->parent); | |
989 | ||
990 | /* Only supports internal clocking */ | |
991 | if (tmp & TIM2_BCD) | |
992 | return rate; | |
993 | ||
994 | div = (tmp & 0x1F) | ((tmp & 0xF8) >> 22); | |
995 | tmp = rate / (2 + div); | |
996 | ||
997 | return tmp; | |
998 | } | |
999 | ||
1000 | static int clcd_set_rate(struct clk *clk, unsigned long rate) | |
1001 | { | |
1002 | u32 tmp, prate, div, oldclk; | |
1003 | ||
1004 | /* The LCD clock must be on when accessing an LCD register */ | |
1005 | oldclk = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL); | |
1006 | __raw_writel(oldclk | LPC32XX_CLKPWR_LCDCTRL_CLK_EN, | |
1007 | LPC32XX_CLKPWR_LCDCLK_CTRL); | |
1008 | ||
1009 | tmp = __raw_readl(io_p2v(LPC32XX_LCD_BASE + CLCD_TIM2)) | TIM2_BCD; | |
1010 | prate = clk->parent->get_rate(clk->parent); | |
1011 | ||
1012 | if (rate < prate) { | |
1013 | /* Find closest divider */ | |
1014 | div = prate / rate; | |
1015 | if (div >= 2) { | |
1016 | div -= 2; | |
1017 | tmp &= ~TIM2_BCD; | |
1018 | } | |
1019 | ||
1020 | tmp &= ~(0xF800001F); | |
1021 | tmp |= (div & 0x1F); | |
1022 | tmp |= (((div >> 5) & 0x1F) << 27); | |
1023 | } | |
1024 | ||
1025 | __raw_writel(tmp, io_p2v(LPC32XX_LCD_BASE + CLCD_TIM2)); | |
1026 | __raw_writel(oldclk, LPC32XX_CLKPWR_LCDCLK_CTRL); | |
1027 | ||
1028 | return 0; | |
1029 | } | |
1030 | ||
1031 | static unsigned long clcd_round_rate(struct clk *clk, unsigned long rate) | |
1032 | { | |
1033 | u32 prate, div; | |
1034 | ||
1035 | prate = clk->parent->get_rate(clk->parent); | |
1036 | ||
1037 | if (rate >= prate) | |
1038 | rate = prate; | |
1039 | else { | |
1040 | div = prate / rate; | |
1041 | if (div > 0x3ff) | |
1042 | div = 0x3ff; | |
1043 | ||
1044 | rate = prate / div; | |
1045 | } | |
1046 | ||
1047 | return rate; | |
1048 | } | |
1049 | ||
1050 | static struct clk clk_lcd = { | |
1051 | .parent = &clk_hclk, | |
1052 | .set_rate = clcd_set_rate, | |
1053 | .get_rate = clcd_get_rate, | |
1054 | .round_rate = clcd_round_rate, | |
1055 | .enable = local_onoff_enable, | |
1056 | .enable_reg = LPC32XX_CLKPWR_LCDCLK_CTRL, | |
1057 | .enable_mask = LPC32XX_CLKPWR_LCDCTRL_CLK_EN, | |
1058 | }; | |
1059 | ||
b9cc4bf6 KW |
1060 | static void local_clk_disable(struct clk *clk) |
1061 | { | |
b9cc4bf6 KW |
1062 | /* Don't attempt to disable clock if it has no users */ |
1063 | if (clk->usecount > 0) { | |
1064 | clk->usecount--; | |
1065 | ||
1066 | /* Only disable clock when it has no more users */ | |
1067 | if ((clk->usecount == 0) && (clk->enable)) | |
1068 | clk->enable(clk, 0); | |
1069 | ||
1070 | /* Check parent clocks, they may need to be disabled too */ | |
1071 | if (clk->parent) | |
1072 | local_clk_disable(clk->parent); | |
1073 | } | |
1074 | } | |
1075 | ||
1076 | static int local_clk_enable(struct clk *clk) | |
1077 | { | |
1078 | int ret = 0; | |
1079 | ||
1080 | /* Enable parent clocks first and update use counts */ | |
1081 | if (clk->parent) | |
1082 | ret = local_clk_enable(clk->parent); | |
1083 | ||
1084 | if (!ret) { | |
1085 | /* Only enable clock if it's currently disabled */ | |
1086 | if ((clk->usecount == 0) && (clk->enable)) | |
1087 | ret = clk->enable(clk, 1); | |
1088 | ||
1089 | if (!ret) | |
1090 | clk->usecount++; | |
1091 | else if (clk->parent) | |
1092 | local_clk_disable(clk->parent); | |
1093 | } | |
1094 | ||
1095 | return ret; | |
1096 | } | |
1097 | ||
1098 | /* | |
1099 | * clk_enable - inform the system when the clock source should be running. | |
1100 | */ | |
1101 | int clk_enable(struct clk *clk) | |
1102 | { | |
1103 | int ret; | |
b8451862 | 1104 | unsigned long flags; |
b9cc4bf6 | 1105 | |
b8451862 | 1106 | spin_lock_irqsave(&global_clkregs_lock, flags); |
b9cc4bf6 | 1107 | ret = local_clk_enable(clk); |
b8451862 | 1108 | spin_unlock_irqrestore(&global_clkregs_lock, flags); |
b9cc4bf6 KW |
1109 | |
1110 | return ret; | |
1111 | } | |
1112 | EXPORT_SYMBOL(clk_enable); | |
1113 | ||
1114 | /* | |
1115 | * clk_disable - inform the system when the clock source is no longer required | |
1116 | */ | |
1117 | void clk_disable(struct clk *clk) | |
1118 | { | |
b8451862 RS |
1119 | unsigned long flags; |
1120 | ||
1121 | spin_lock_irqsave(&global_clkregs_lock, flags); | |
b9cc4bf6 | 1122 | local_clk_disable(clk); |
b8451862 | 1123 | spin_unlock_irqrestore(&global_clkregs_lock, flags); |
b9cc4bf6 KW |
1124 | } |
1125 | EXPORT_SYMBOL(clk_disable); | |
1126 | ||
1127 | /* | |
1128 | * clk_get_rate - obtain the current clock rate (in Hz) for a clock source | |
1129 | */ | |
1130 | unsigned long clk_get_rate(struct clk *clk) | |
1131 | { | |
b8451862 | 1132 | return clk->get_rate(clk); |
b9cc4bf6 KW |
1133 | } |
1134 | EXPORT_SYMBOL(clk_get_rate); | |
1135 | ||
1136 | /* | |
1137 | * clk_set_rate - set the clock rate for a clock source | |
1138 | */ | |
1139 | int clk_set_rate(struct clk *clk, unsigned long rate) | |
1140 | { | |
1141 | int ret = -EINVAL; | |
1142 | ||
1143 | /* | |
1144 | * Most system clocks can only be enabled or disabled, with | |
1145 | * the actual rate set as part of the peripheral dividers | |
1146 | * instead of high level clock control | |
1147 | */ | |
b8451862 | 1148 | if (clk->set_rate) |
b9cc4bf6 | 1149 | ret = clk->set_rate(clk, rate); |
b9cc4bf6 KW |
1150 | |
1151 | return ret; | |
1152 | } | |
1153 | EXPORT_SYMBOL(clk_set_rate); | |
1154 | ||
1155 | /* | |
1156 | * clk_round_rate - adjust a rate to the exact rate a clock can provide | |
1157 | */ | |
1158 | long clk_round_rate(struct clk *clk, unsigned long rate) | |
1159 | { | |
b9cc4bf6 KW |
1160 | if (clk->round_rate) |
1161 | rate = clk->round_rate(clk, rate); | |
1162 | else | |
1163 | rate = clk->get_rate(clk); | |
1164 | ||
b9cc4bf6 KW |
1165 | return rate; |
1166 | } | |
1167 | EXPORT_SYMBOL(clk_round_rate); | |
1168 | ||
1169 | /* | |
1170 | * clk_set_parent - set the parent clock source for this clock | |
1171 | */ | |
1172 | int clk_set_parent(struct clk *clk, struct clk *parent) | |
1173 | { | |
1174 | /* Clock re-parenting is not supported */ | |
1175 | return -EINVAL; | |
1176 | } | |
1177 | EXPORT_SYMBOL(clk_set_parent); | |
1178 | ||
1179 | /* | |
1180 | * clk_get_parent - get the parent clock source for this clock | |
1181 | */ | |
1182 | struct clk *clk_get_parent(struct clk *clk) | |
1183 | { | |
1184 | return clk->parent; | |
1185 | } | |
1186 | EXPORT_SYMBOL(clk_get_parent); | |
1187 | ||
b9cc4bf6 | 1188 | static struct clk_lookup lookups[] = { |
5dfdb0a0 RS |
1189 | CLKDEV_INIT(NULL, "osc_32KHz", &osc_32KHz), |
1190 | CLKDEV_INIT(NULL, "osc_pll397", &osc_pll397), | |
1191 | CLKDEV_INIT(NULL, "osc_main", &osc_main), | |
1192 | CLKDEV_INIT(NULL, "sys_ck", &clk_sys), | |
1193 | CLKDEV_INIT(NULL, "arm_pll_ck", &clk_armpll), | |
1194 | CLKDEV_INIT(NULL, "ck_pll5", &clk_usbpll), | |
1195 | CLKDEV_INIT(NULL, "hclk_ck", &clk_hclk), | |
1196 | CLKDEV_INIT(NULL, "pclk_ck", &clk_pclk), | |
1197 | CLKDEV_INIT(NULL, "timer0_ck", &clk_timer0), | |
1198 | CLKDEV_INIT(NULL, "timer1_ck", &clk_timer1), | |
1199 | CLKDEV_INIT(NULL, "timer2_ck", &clk_timer2), | |
1200 | CLKDEV_INIT(NULL, "timer3_ck", &clk_timer3), | |
1201 | CLKDEV_INIT(NULL, "vfp9_ck", &clk_vfp9), | |
171b0a4f RS |
1202 | CLKDEV_INIT("pl08xdmac", NULL, &clk_dma), |
1203 | CLKDEV_INIT("4003c000.watchdog", NULL, &clk_wdt), | |
1f37a3a3 | 1204 | CLKDEV_INIT("4005c000.pwm", NULL, &clk_pwm), |
5dfdb0a0 RS |
1205 | CLKDEV_INIT(NULL, "uart3_ck", &clk_uart3), |
1206 | CLKDEV_INIT(NULL, "uart4_ck", &clk_uart4), | |
1207 | CLKDEV_INIT(NULL, "uart5_ck", &clk_uart5), | |
1208 | CLKDEV_INIT(NULL, "uart6_ck", &clk_uart6), | |
171b0a4f RS |
1209 | CLKDEV_INIT("400a0000.i2c", NULL, &clk_i2c0), |
1210 | CLKDEV_INIT("400a8000.i2c", NULL, &clk_i2c1), | |
1211 | CLKDEV_INIT("31020300.i2c", NULL, &clk_i2c2), | |
5dfdb0a0 RS |
1212 | CLKDEV_INIT("dev:ssp0", NULL, &clk_ssp0), |
1213 | CLKDEV_INIT("dev:ssp1", NULL, &clk_ssp1), | |
821e7edd | 1214 | CLKDEV_INIT("40050000.key", NULL, &clk_kscan), |
b27f4822 RS |
1215 | CLKDEV_INIT("20020000.flash", NULL, &clk_nand), |
1216 | CLKDEV_INIT("200a8000.flash", NULL, &clk_nand_mlc), | |
171b0a4f | 1217 | CLKDEV_INIT("40048000.adc", NULL, &clk_adc), |
5dfdb0a0 RS |
1218 | CLKDEV_INIT(NULL, "i2s0_ck", &clk_i2s0), |
1219 | CLKDEV_INIT(NULL, "i2s1_ck", &clk_i2s1), | |
171b0a4f RS |
1220 | CLKDEV_INIT("40048000.tsc", NULL, &clk_tsc), |
1221 | CLKDEV_INIT("20098000.sd", NULL, &clk_mmc), | |
1222 | CLKDEV_INIT("31060000.ethernet", NULL, &clk_net), | |
5dfdb0a0 | 1223 | CLKDEV_INIT("dev:clcd", NULL, &clk_lcd), |
171b0a4f | 1224 | CLKDEV_INIT("31020000.usbd", "ck_usbd", &clk_usbd), |
a408e8f4 APS |
1225 | CLKDEV_INIT("31020000.ohci", "ck_usbd", &clk_usbd), |
1226 | CLKDEV_INIT("31020000.usbd", "ck_usb_otg", &clk_usb_otg_dev), | |
1227 | CLKDEV_INIT("31020000.ohci", "ck_usb_otg", &clk_usb_otg_host), | |
5dfdb0a0 | 1228 | CLKDEV_INIT("lpc32xx_rtc", NULL, &clk_rtc), |
b9cc4bf6 KW |
1229 | }; |
1230 | ||
1231 | static int __init clk_init(void) | |
1232 | { | |
1233 | int i; | |
1234 | ||
1235 | for (i = 0; i < ARRAY_SIZE(lookups); i++) | |
1236 | clkdev_add(&lookups[i]); | |
1237 | ||
1238 | /* | |
1239 | * Setup muxed SYSCLK for HCLK PLL base -this selects the | |
1240 | * parent clock used for the ARM PLL and is used to derive | |
1241 | * the many system clock rates in the device. | |
1242 | */ | |
1243 | if (clk_is_sysclk_mainosc() != 0) | |
1244 | clk_sys.parent = &osc_main; | |
1245 | else | |
1246 | clk_sys.parent = &osc_pll397; | |
1247 | ||
1248 | clk_sys.rate = clk_sys.parent->rate; | |
1249 | ||
1250 | /* Compute the current ARM PLL and USB PLL frequencies */ | |
1251 | local_update_armpll_rate(); | |
1252 | ||
1253 | /* Compute HCLK and PCLK bus rates */ | |
1254 | clk_hclk.rate = clk_hclk.parent->rate / clk_get_hclk_div(); | |
1255 | clk_pclk.rate = clk_pclk.parent->rate / clk_get_pclk_div(); | |
1256 | ||
1257 | /* | |
1258 | * Enable system clocks - this step is somewhat formal, as the | |
1259 | * clocks are already running, but it does get the clock data | |
1260 | * inline with the actual system state. Never disable these | |
1261 | * clocks as they will only stop if the system is going to sleep. | |
1262 | * In that case, the chip/system power management functions will | |
1263 | * handle clock gating. | |
1264 | */ | |
1265 | if (clk_enable(&clk_hclk) || clk_enable(&clk_pclk)) | |
1266 | printk(KERN_ERR "Error enabling system HCLK and PCLK\n"); | |
1267 | ||
1268 | /* | |
1269 | * Timers 0 and 1 were enabled and are being used by the high | |
1270 | * resolution tick function prior to this driver being initialized. | |
1271 | * Tag them now as used. | |
1272 | */ | |
1273 | if (clk_enable(&clk_timer0) || clk_enable(&clk_timer1)) | |
1274 | printk(KERN_ERR "Error enabling timer tick clocks\n"); | |
1275 | ||
1276 | return 0; | |
1277 | } | |
1278 | core_initcall(clk_init); | |
1279 |