Root/
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 | |
85 | #include <linux/kernel.h> |
86 | #include <linux/list.h> |
87 | #include <linux/errno.h> |
88 | #include <linux/device.h> |
89 | #include <linux/err.h> |
90 | #include <linux/clk.h> |
91 | #include <linux/amba/bus.h> |
92 | #include <linux/amba/clcd.h> |
93 | |
94 | #include <mach/hardware.h> |
95 | #include <asm/clkdev.h> |
96 | #include <mach/clkdev.h> |
97 | #include <mach/platform.h> |
98 | #include "clock.h" |
99 | #include "common.h" |
100 | |
101 | static struct clk clk_armpll; |
102 | static struct clk clk_usbpll; |
103 | static DEFINE_MUTEX(clkm_lock); |
104 | |
105 | /* |
106 | * Post divider values for PLLs based on selected register value |
107 | */ |
108 | static const u32 pll_postdivs[4] = {1, 2, 4, 8}; |
109 | |
110 | static unsigned long local_return_parent_rate(struct clk *clk) |
111 | { |
112 | /* |
113 | * If a clock has a rate of 0, then it inherits it's parent |
114 | * clock rate |
115 | */ |
116 | while (clk->rate == 0) |
117 | clk = clk->parent; |
118 | |
119 | return clk->rate; |
120 | } |
121 | |
122 | /* 32KHz clock has a fixed rate and is not stoppable */ |
123 | static struct clk osc_32KHz = { |
124 | .rate = LPC32XX_CLOCK_OSC_FREQ, |
125 | .get_rate = local_return_parent_rate, |
126 | }; |
127 | |
128 | static int local_pll397_enable(struct clk *clk, int enable) |
129 | { |
130 | u32 reg; |
131 | unsigned long timeout = 1 + msecs_to_jiffies(10); |
132 | |
133 | reg = __raw_readl(LPC32XX_CLKPWR_PLL397_CTRL); |
134 | |
135 | if (enable == 0) { |
136 | reg |= LPC32XX_CLKPWR_SYSCTRL_PLL397_DIS; |
137 | __raw_writel(reg, LPC32XX_CLKPWR_PLL397_CTRL); |
138 | } else { |
139 | /* Enable PLL397 */ |
140 | reg &= ~LPC32XX_CLKPWR_SYSCTRL_PLL397_DIS; |
141 | __raw_writel(reg, LPC32XX_CLKPWR_PLL397_CTRL); |
142 | |
143 | /* Wait for PLL397 lock */ |
144 | while (((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) & |
145 | LPC32XX_CLKPWR_SYSCTRL_PLL397_STS) == 0) && |
146 | (timeout > jiffies)) |
147 | cpu_relax(); |
148 | |
149 | if ((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) & |
150 | LPC32XX_CLKPWR_SYSCTRL_PLL397_STS) == 0) |
151 | return -ENODEV; |
152 | } |
153 | |
154 | return 0; |
155 | } |
156 | |
157 | static int local_oscmain_enable(struct clk *clk, int enable) |
158 | { |
159 | u32 reg; |
160 | unsigned long timeout = 1 + msecs_to_jiffies(10); |
161 | |
162 | reg = __raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL); |
163 | |
164 | if (enable == 0) { |
165 | reg |= LPC32XX_CLKPWR_MOSC_DISABLE; |
166 | __raw_writel(reg, LPC32XX_CLKPWR_MAIN_OSC_CTRL); |
167 | } else { |
168 | /* Enable main oscillator */ |
169 | reg &= ~LPC32XX_CLKPWR_MOSC_DISABLE; |
170 | __raw_writel(reg, LPC32XX_CLKPWR_MAIN_OSC_CTRL); |
171 | |
172 | /* Wait for main oscillator to start */ |
173 | while (((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) & |
174 | LPC32XX_CLKPWR_MOSC_DISABLE) != 0) && |
175 | (timeout > jiffies)) |
176 | cpu_relax(); |
177 | |
178 | if ((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) & |
179 | LPC32XX_CLKPWR_MOSC_DISABLE) != 0) |
180 | return -ENODEV; |
181 | } |
182 | |
183 | return 0; |
184 | } |
185 | |
186 | static struct clk osc_pll397 = { |
187 | .parent = &osc_32KHz, |
188 | .enable = local_pll397_enable, |
189 | .rate = LPC32XX_CLOCK_OSC_FREQ * 397, |
190 | .get_rate = local_return_parent_rate, |
191 | }; |
192 | |
193 | static struct clk osc_main = { |
194 | .enable = local_oscmain_enable, |
195 | .rate = LPC32XX_MAIN_OSC_FREQ, |
196 | .get_rate = local_return_parent_rate, |
197 | }; |
198 | |
199 | static struct clk clk_sys; |
200 | |
201 | /* |
202 | * Convert a PLL register value to a PLL output frequency |
203 | */ |
204 | u32 clk_get_pllrate_from_reg(u32 inputclk, u32 regval) |
205 | { |
206 | struct clk_pll_setup pllcfg; |
207 | |
208 | pllcfg.cco_bypass_b15 = 0; |
209 | pllcfg.direct_output_b14 = 0; |
210 | pllcfg.fdbk_div_ctrl_b13 = 0; |
211 | if ((regval & LPC32XX_CLKPWR_HCLKPLL_CCO_BYPASS) != 0) |
212 | pllcfg.cco_bypass_b15 = 1; |
213 | if ((regval & LPC32XX_CLKPWR_HCLKPLL_POSTDIV_BYPASS) != 0) |
214 | pllcfg.direct_output_b14 = 1; |
215 | if ((regval & LPC32XX_CLKPWR_HCLKPLL_FDBK_SEL_FCLK) != 0) |
216 | pllcfg.fdbk_div_ctrl_b13 = 1; |
217 | pllcfg.pll_m = 1 + ((regval >> 1) & 0xFF); |
218 | pllcfg.pll_n = 1 + ((regval >> 9) & 0x3); |
219 | pllcfg.pll_p = pll_postdivs[((regval >> 11) & 0x3)]; |
220 | |
221 | return clk_check_pll_setup(inputclk, &pllcfg); |
222 | } |
223 | |
224 | /* |
225 | * Setup the HCLK PLL with a PLL structure |
226 | */ |
227 | static u32 local_clk_pll_setup(struct clk_pll_setup *PllSetup) |
228 | { |
229 | u32 tv, tmp = 0; |
230 | |
231 | if (PllSetup->analog_on != 0) |
232 | tmp |= LPC32XX_CLKPWR_HCLKPLL_POWER_UP; |
233 | if (PllSetup->cco_bypass_b15 != 0) |
234 | tmp |= LPC32XX_CLKPWR_HCLKPLL_CCO_BYPASS; |
235 | if (PllSetup->direct_output_b14 != 0) |
236 | tmp |= LPC32XX_CLKPWR_HCLKPLL_POSTDIV_BYPASS; |
237 | if (PllSetup->fdbk_div_ctrl_b13 != 0) |
238 | tmp |= LPC32XX_CLKPWR_HCLKPLL_FDBK_SEL_FCLK; |
239 | |
240 | tv = ffs(PllSetup->pll_p) - 1; |
241 | if ((!is_power_of_2(PllSetup->pll_p)) || (tv > 3)) |
242 | return 0; |
243 | |
244 | tmp |= LPC32XX_CLKPWR_HCLKPLL_POSTDIV_2POW(tv); |
245 | tmp |= LPC32XX_CLKPWR_HCLKPLL_PREDIV_PLUS1(PllSetup->pll_n - 1); |
246 | tmp |= LPC32XX_CLKPWR_HCLKPLL_PLLM(PllSetup->pll_m - 1); |
247 | |
248 | return tmp; |
249 | } |
250 | |
251 | /* |
252 | * Update the ARM core PLL frequency rate variable from the actual PLL setting |
253 | */ |
254 | static void local_update_armpll_rate(void) |
255 | { |
256 | u32 clkin, pllreg; |
257 | |
258 | clkin = clk_armpll.parent->rate; |
259 | pllreg = __raw_readl(LPC32XX_CLKPWR_HCLKPLL_CTRL) & 0x1FFFF; |
260 | |
261 | clk_armpll.rate = clk_get_pllrate_from_reg(clkin, pllreg); |
262 | } |
263 | |
264 | /* |
265 | * Find a PLL configuration for the selected input frequency |
266 | */ |
267 | static u32 local_clk_find_pll_cfg(u32 pllin_freq, u32 target_freq, |
268 | struct clk_pll_setup *pllsetup) |
269 | { |
270 | u32 ifreq, freqtol, m, n, p, fclkout; |
271 | |
272 | /* Determine frequency tolerance limits */ |
273 | freqtol = target_freq / 250; |
274 | ifreq = pllin_freq; |
275 | |
276 | /* Is direct bypass mode possible? */ |
277 | if (abs(pllin_freq - target_freq) <= freqtol) { |
278 | pllsetup->analog_on = 0; |
279 | pllsetup->cco_bypass_b15 = 1; |
280 | pllsetup->direct_output_b14 = 1; |
281 | pllsetup->fdbk_div_ctrl_b13 = 1; |
282 | pllsetup->pll_p = pll_postdivs[0]; |
283 | pllsetup->pll_n = 1; |
284 | pllsetup->pll_m = 1; |
285 | return clk_check_pll_setup(ifreq, pllsetup); |
286 | } else if (target_freq <= ifreq) { |
287 | pllsetup->analog_on = 0; |
288 | pllsetup->cco_bypass_b15 = 1; |
289 | pllsetup->direct_output_b14 = 0; |
290 | pllsetup->fdbk_div_ctrl_b13 = 1; |
291 | pllsetup->pll_n = 1; |
292 | pllsetup->pll_m = 1; |
293 | for (p = 0; p <= 3; p++) { |
294 | pllsetup->pll_p = pll_postdivs[p]; |
295 | fclkout = clk_check_pll_setup(ifreq, pllsetup); |
296 | if (abs(target_freq - fclkout) <= freqtol) |
297 | return fclkout; |
298 | } |
299 | } |
300 | |
301 | /* Is direct mode possible? */ |
302 | pllsetup->analog_on = 1; |
303 | pllsetup->cco_bypass_b15 = 0; |
304 | pllsetup->direct_output_b14 = 1; |
305 | pllsetup->fdbk_div_ctrl_b13 = 0; |
306 | pllsetup->pll_p = pll_postdivs[0]; |
307 | for (m = 1; m <= 256; m++) { |
308 | for (n = 1; n <= 4; n++) { |
309 | /* Compute output frequency for this value */ |
310 | pllsetup->pll_n = n; |
311 | pllsetup->pll_m = m; |
312 | fclkout = clk_check_pll_setup(ifreq, |
313 | pllsetup); |
314 | if (abs(target_freq - fclkout) <= |
315 | freqtol) |
316 | return fclkout; |
317 | } |
318 | } |
319 | |
320 | /* Is integer mode possible? */ |
321 | pllsetup->analog_on = 1; |
322 | pllsetup->cco_bypass_b15 = 0; |
323 | pllsetup->direct_output_b14 = 0; |
324 | pllsetup->fdbk_div_ctrl_b13 = 1; |
325 | for (m = 1; m <= 256; m++) { |
326 | for (n = 1; n <= 4; n++) { |
327 | for (p = 0; p < 4; p++) { |
328 | /* Compute output frequency */ |
329 | pllsetup->pll_p = pll_postdivs[p]; |
330 | pllsetup->pll_n = n; |
331 | pllsetup->pll_m = m; |
332 | fclkout = clk_check_pll_setup( |
333 | ifreq, pllsetup); |
334 | if (abs(target_freq - fclkout) <= freqtol) |
335 | return fclkout; |
336 | } |
337 | } |
338 | } |
339 | |
340 | /* Try non-integer mode */ |
341 | pllsetup->analog_on = 1; |
342 | pllsetup->cco_bypass_b15 = 0; |
343 | pllsetup->direct_output_b14 = 0; |
344 | pllsetup->fdbk_div_ctrl_b13 = 0; |
345 | for (m = 1; m <= 256; m++) { |
346 | for (n = 1; n <= 4; n++) { |
347 | for (p = 0; p < 4; p++) { |
348 | /* Compute output frequency */ |
349 | pllsetup->pll_p = pll_postdivs[p]; |
350 | pllsetup->pll_n = n; |
351 | pllsetup->pll_m = m; |
352 | fclkout = clk_check_pll_setup( |
353 | ifreq, pllsetup); |
354 | if (abs(target_freq - fclkout) <= freqtol) |
355 | return fclkout; |
356 | } |
357 | } |
358 | } |
359 | |
360 | return 0; |
361 | } |
362 | |
363 | static struct clk clk_armpll = { |
364 | .parent = &clk_sys, |
365 | .get_rate = local_return_parent_rate, |
366 | }; |
367 | |
368 | /* |
369 | * Setup the USB PLL with a PLL structure |
370 | */ |
371 | static u32 local_clk_usbpll_setup(struct clk_pll_setup *pHCLKPllSetup) |
372 | { |
373 | u32 reg, tmp = local_clk_pll_setup(pHCLKPllSetup); |
374 | |
375 | reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL) & ~0x1FFFF; |
376 | reg |= tmp; |
377 | __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); |
378 | |
379 | return clk_check_pll_setup(clk_usbpll.parent->rate, |
380 | pHCLKPllSetup); |
381 | } |
382 | |
383 | static int local_usbpll_enable(struct clk *clk, int enable) |
384 | { |
385 | u32 reg; |
386 | int ret = -ENODEV; |
387 | unsigned long timeout = 1 + msecs_to_jiffies(10); |
388 | |
389 | reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); |
390 | |
391 | if (enable == 0) { |
392 | reg &= ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN1 | |
393 | LPC32XX_CLKPWR_USBCTRL_CLK_EN2); |
394 | __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); |
395 | } else if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP) { |
396 | reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN1; |
397 | __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); |
398 | |
399 | /* Wait for PLL lock */ |
400 | while ((timeout > jiffies) & (ret == -ENODEV)) { |
401 | reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); |
402 | if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_STS) |
403 | ret = 0; |
404 | } |
405 | |
406 | if (ret == 0) { |
407 | reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN2; |
408 | __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); |
409 | } |
410 | } |
411 | |
412 | return ret; |
413 | } |
414 | |
415 | static unsigned long local_usbpll_round_rate(struct clk *clk, |
416 | unsigned long rate) |
417 | { |
418 | u32 clkin, usbdiv; |
419 | struct clk_pll_setup pllsetup; |
420 | |
421 | /* |
422 | * Unlike other clocks, this clock has a KHz input rate, so bump |
423 | * it up to work with the PLL function |
424 | */ |
425 | rate = rate * 1000; |
426 | |
427 | clkin = clk->parent->rate; |
428 | usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) & |
429 | LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1; |
430 | clkin = clkin / usbdiv; |
431 | |
432 | /* Try to find a good rate setup */ |
433 | if (local_clk_find_pll_cfg(clkin, rate, &pllsetup) == 0) |
434 | return 0; |
435 | |
436 | return clk_check_pll_setup(clkin, &pllsetup); |
437 | } |
438 | |
439 | static int local_usbpll_set_rate(struct clk *clk, unsigned long rate) |
440 | { |
441 | u32 clkin, reg, usbdiv; |
442 | struct clk_pll_setup pllsetup; |
443 | |
444 | /* |
445 | * Unlike other clocks, this clock has a KHz input rate, so bump |
446 | * it up to work with the PLL function |
447 | */ |
448 | rate = rate * 1000; |
449 | |
450 | clkin = clk->get_rate(clk); |
451 | usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) & |
452 | LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1; |
453 | clkin = clkin / usbdiv; |
454 | |
455 | /* Try to find a good rate setup */ |
456 | if (local_clk_find_pll_cfg(clkin, rate, &pllsetup) == 0) |
457 | return -EINVAL; |
458 | |
459 | local_usbpll_enable(clk, 0); |
460 | |
461 | reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); |
462 | reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN1; |
463 | __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); |
464 | |
465 | pllsetup.analog_on = 1; |
466 | local_clk_usbpll_setup(&pllsetup); |
467 | |
468 | clk->rate = clk_check_pll_setup(clkin, &pllsetup); |
469 | |
470 | reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); |
471 | reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN2; |
472 | __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); |
473 | |
474 | return 0; |
475 | } |
476 | |
477 | static struct clk clk_usbpll = { |
478 | .parent = &osc_main, |
479 | .set_rate = local_usbpll_set_rate, |
480 | .enable = local_usbpll_enable, |
481 | .rate = 48000, /* In KHz */ |
482 | .get_rate = local_return_parent_rate, |
483 | .round_rate = local_usbpll_round_rate, |
484 | }; |
485 | |
486 | static u32 clk_get_hclk_div(void) |
487 | { |
488 | static const u32 hclkdivs[4] = {1, 2, 4, 4}; |
489 | return hclkdivs[LPC32XX_CLKPWR_HCLKDIV_DIV_2POW( |
490 | __raw_readl(LPC32XX_CLKPWR_HCLK_DIV))]; |
491 | } |
492 | |
493 | static struct clk clk_hclk = { |
494 | .parent = &clk_armpll, |
495 | .get_rate = local_return_parent_rate, |
496 | }; |
497 | |
498 | static struct clk clk_pclk = { |
499 | .parent = &clk_armpll, |
500 | .get_rate = local_return_parent_rate, |
501 | }; |
502 | |
503 | static int local_onoff_enable(struct clk *clk, int enable) |
504 | { |
505 | u32 tmp; |
506 | |
507 | tmp = __raw_readl(clk->enable_reg); |
508 | |
509 | if (enable == 0) |
510 | tmp &= ~clk->enable_mask; |
511 | else |
512 | tmp |= clk->enable_mask; |
513 | |
514 | __raw_writel(tmp, clk->enable_reg); |
515 | |
516 | return 0; |
517 | } |
518 | |
519 | /* Peripheral clock sources */ |
520 | static struct clk clk_timer0 = { |
521 | .parent = &clk_pclk, |
522 | .enable = local_onoff_enable, |
523 | .enable_reg = LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1, |
524 | .enable_mask = LPC32XX_CLKPWR_TMRPWMCLK_TIMER0_EN, |
525 | .get_rate = local_return_parent_rate, |
526 | }; |
527 | static struct clk clk_timer1 = { |
528 | .parent = &clk_pclk, |
529 | .enable = local_onoff_enable, |
530 | .enable_reg = LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1, |
531 | .enable_mask = LPC32XX_CLKPWR_TMRPWMCLK_TIMER1_EN, |
532 | .get_rate = local_return_parent_rate, |
533 | }; |
534 | static struct clk clk_timer2 = { |
535 | .parent = &clk_pclk, |
536 | .enable = local_onoff_enable, |
537 | .enable_reg = LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1, |
538 | .enable_mask = LPC32XX_CLKPWR_TMRPWMCLK_TIMER2_EN, |
539 | .get_rate = local_return_parent_rate, |
540 | }; |
541 | static struct clk clk_timer3 = { |
542 | .parent = &clk_pclk, |
543 | .enable = local_onoff_enable, |
544 | .enable_reg = LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1, |
545 | .enable_mask = LPC32XX_CLKPWR_TMRPWMCLK_TIMER3_EN, |
546 | .get_rate = local_return_parent_rate, |
547 | }; |
548 | static struct clk clk_wdt = { |
549 | .parent = &clk_pclk, |
550 | .enable = local_onoff_enable, |
551 | .enable_reg = LPC32XX_CLKPWR_TIMER_CLK_CTRL, |
552 | .enable_mask = LPC32XX_CLKPWR_PWMCLK_WDOG_EN, |
553 | .get_rate = local_return_parent_rate, |
554 | }; |
555 | static struct clk clk_vfp9 = { |
556 | .parent = &clk_pclk, |
557 | .enable = local_onoff_enable, |
558 | .enable_reg = LPC32XX_CLKPWR_DEBUG_CTRL, |
559 | .enable_mask = LPC32XX_CLKPWR_VFP_CLOCK_ENABLE_BIT, |
560 | .get_rate = local_return_parent_rate, |
561 | }; |
562 | static struct clk clk_dma = { |
563 | .parent = &clk_hclk, |
564 | .enable = local_onoff_enable, |
565 | .enable_reg = LPC32XX_CLKPWR_DMA_CLK_CTRL, |
566 | .enable_mask = LPC32XX_CLKPWR_DMACLKCTRL_CLK_EN, |
567 | .get_rate = local_return_parent_rate, |
568 | }; |
569 | |
570 | static struct clk clk_uart3 = { |
571 | .parent = &clk_pclk, |
572 | .enable = local_onoff_enable, |
573 | .enable_reg = LPC32XX_CLKPWR_UART_CLK_CTRL, |
574 | .enable_mask = LPC32XX_CLKPWR_UARTCLKCTRL_UART3_EN, |
575 | .get_rate = local_return_parent_rate, |
576 | }; |
577 | |
578 | static struct clk clk_uart4 = { |
579 | .parent = &clk_pclk, |
580 | .enable = local_onoff_enable, |
581 | .enable_reg = LPC32XX_CLKPWR_UART_CLK_CTRL, |
582 | .enable_mask = LPC32XX_CLKPWR_UARTCLKCTRL_UART4_EN, |
583 | .get_rate = local_return_parent_rate, |
584 | }; |
585 | |
586 | static struct clk clk_uart5 = { |
587 | .parent = &clk_pclk, |
588 | .enable = local_onoff_enable, |
589 | .enable_reg = LPC32XX_CLKPWR_UART_CLK_CTRL, |
590 | .enable_mask = LPC32XX_CLKPWR_UARTCLKCTRL_UART5_EN, |
591 | .get_rate = local_return_parent_rate, |
592 | }; |
593 | |
594 | static struct clk clk_uart6 = { |
595 | .parent = &clk_pclk, |
596 | .enable = local_onoff_enable, |
597 | .enable_reg = LPC32XX_CLKPWR_UART_CLK_CTRL, |
598 | .enable_mask = LPC32XX_CLKPWR_UARTCLKCTRL_UART6_EN, |
599 | .get_rate = local_return_parent_rate, |
600 | }; |
601 | |
602 | static struct clk clk_i2c0 = { |
603 | .parent = &clk_hclk, |
604 | .enable = local_onoff_enable, |
605 | .enable_reg = LPC32XX_CLKPWR_I2C_CLK_CTRL, |
606 | .enable_mask = LPC32XX_CLKPWR_I2CCLK_I2C1CLK_EN, |
607 | .get_rate = local_return_parent_rate, |
608 | }; |
609 | |
610 | static struct clk clk_i2c1 = { |
611 | .parent = &clk_hclk, |
612 | .enable = local_onoff_enable, |
613 | .enable_reg = LPC32XX_CLKPWR_I2C_CLK_CTRL, |
614 | .enable_mask = LPC32XX_CLKPWR_I2CCLK_I2C2CLK_EN, |
615 | .get_rate = local_return_parent_rate, |
616 | }; |
617 | |
618 | static struct clk clk_i2c2 = { |
619 | .parent = &clk_pclk, |
620 | .enable = local_onoff_enable, |
621 | .enable_reg = io_p2v(LPC32XX_USB_BASE + 0xFF4), |
622 | .enable_mask = 0x4, |
623 | .get_rate = local_return_parent_rate, |
624 | }; |
625 | |
626 | static struct clk clk_ssp0 = { |
627 | .parent = &clk_hclk, |
628 | .enable = local_onoff_enable, |
629 | .enable_reg = LPC32XX_CLKPWR_SSP_CLK_CTRL, |
630 | .enable_mask = LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN, |
631 | .get_rate = local_return_parent_rate, |
632 | }; |
633 | |
634 | static struct clk clk_ssp1 = { |
635 | .parent = &clk_hclk, |
636 | .enable = local_onoff_enable, |
637 | .enable_reg = LPC32XX_CLKPWR_SSP_CLK_CTRL, |
638 | .enable_mask = LPC32XX_CLKPWR_SSPCTRL_SSPCLK1_EN, |
639 | .get_rate = local_return_parent_rate, |
640 | }; |
641 | |
642 | static struct clk clk_kscan = { |
643 | .parent = &osc_32KHz, |
644 | .enable = local_onoff_enable, |
645 | .enable_reg = LPC32XX_CLKPWR_KEY_CLK_CTRL, |
646 | .enable_mask = LPC32XX_CLKPWR_KEYCLKCTRL_CLK_EN, |
647 | .get_rate = local_return_parent_rate, |
648 | }; |
649 | |
650 | static struct clk clk_nand = { |
651 | .parent = &clk_hclk, |
652 | .enable = local_onoff_enable, |
653 | .enable_reg = LPC32XX_CLKPWR_NAND_CLK_CTRL, |
654 | .enable_mask = LPC32XX_CLKPWR_NANDCLK_SLCCLK_EN, |
655 | .get_rate = local_return_parent_rate, |
656 | }; |
657 | |
658 | static struct clk clk_i2s0 = { |
659 | .parent = &clk_hclk, |
660 | .enable = local_onoff_enable, |
661 | .enable_reg = LPC32XX_CLKPWR_I2S_CLK_CTRL, |
662 | .enable_mask = LPC32XX_CLKPWR_I2SCTRL_I2SCLK0_EN, |
663 | .get_rate = local_return_parent_rate, |
664 | }; |
665 | |
666 | static struct clk clk_i2s1 = { |
667 | .parent = &clk_hclk, |
668 | .enable = local_onoff_enable, |
669 | .enable_reg = LPC32XX_CLKPWR_I2S_CLK_CTRL, |
670 | .enable_mask = LPC32XX_CLKPWR_I2SCTRL_I2SCLK1_EN, |
671 | .get_rate = local_return_parent_rate, |
672 | }; |
673 | |
674 | static struct clk clk_net = { |
675 | .parent = &clk_hclk, |
676 | .enable = local_onoff_enable, |
677 | .enable_reg = LPC32XX_CLKPWR_MACCLK_CTRL, |
678 | .enable_mask = (LPC32XX_CLKPWR_MACCTRL_DMACLK_EN | |
679 | LPC32XX_CLKPWR_MACCTRL_MMIOCLK_EN | |
680 | LPC32XX_CLKPWR_MACCTRL_HRCCLK_EN), |
681 | .get_rate = local_return_parent_rate, |
682 | }; |
683 | |
684 | static struct clk clk_rtc = { |
685 | .parent = &osc_32KHz, |
686 | .rate = 1, /* 1 Hz */ |
687 | .get_rate = local_return_parent_rate, |
688 | }; |
689 | |
690 | static struct clk clk_usbd = { |
691 | .parent = &clk_usbpll, |
692 | .enable = local_onoff_enable, |
693 | .enable_reg = LPC32XX_CLKPWR_USB_CTRL, |
694 | .enable_mask = LPC32XX_CLKPWR_USBCTRL_HCLK_EN, |
695 | .get_rate = local_return_parent_rate, |
696 | }; |
697 | |
698 | static int tsc_onoff_enable(struct clk *clk, int enable) |
699 | { |
700 | u32 tmp; |
701 | |
702 | /* Make sure 32KHz clock is the selected clock */ |
703 | tmp = __raw_readl(LPC32XX_CLKPWR_ADC_CLK_CTRL_1); |
704 | tmp &= ~LPC32XX_CLKPWR_ADCCTRL1_PCLK_SEL; |
705 | __raw_writel(tmp, LPC32XX_CLKPWR_ADC_CLK_CTRL_1); |
706 | |
707 | if (enable == 0) |
708 | __raw_writel(0, clk->enable_reg); |
709 | else |
710 | __raw_writel(clk->enable_mask, clk->enable_reg); |
711 | |
712 | return 0; |
713 | } |
714 | |
715 | static struct clk clk_tsc = { |
716 | .parent = &osc_32KHz, |
717 | .enable = tsc_onoff_enable, |
718 | .enable_reg = LPC32XX_CLKPWR_ADC_CLK_CTRL, |
719 | .enable_mask = LPC32XX_CLKPWR_ADC32CLKCTRL_CLK_EN, |
720 | .get_rate = local_return_parent_rate, |
721 | }; |
722 | |
723 | static int mmc_onoff_enable(struct clk *clk, int enable) |
724 | { |
725 | u32 tmp; |
726 | |
727 | tmp = __raw_readl(LPC32XX_CLKPWR_MS_CTRL) & |
728 | ~LPC32XX_CLKPWR_MSCARD_SDCARD_EN; |
729 | |
730 | /* If rate is 0, disable clock */ |
731 | if (enable != 0) |
732 | tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_EN; |
733 | |
734 | __raw_writel(tmp, LPC32XX_CLKPWR_MS_CTRL); |
735 | |
736 | return 0; |
737 | } |
738 | |
739 | static unsigned long mmc_get_rate(struct clk *clk) |
740 | { |
741 | u32 div, rate, oldclk; |
742 | |
743 | /* The MMC clock must be on when accessing an MMC register */ |
744 | oldclk = __raw_readl(LPC32XX_CLKPWR_MS_CTRL); |
745 | __raw_writel(oldclk | LPC32XX_CLKPWR_MSCARD_SDCARD_EN, |
746 | LPC32XX_CLKPWR_MS_CTRL); |
747 | div = __raw_readl(LPC32XX_CLKPWR_MS_CTRL); |
748 | __raw_writel(oldclk, LPC32XX_CLKPWR_MS_CTRL); |
749 | |
750 | /* Get the parent clock rate */ |
751 | rate = clk->parent->get_rate(clk->parent); |
752 | |
753 | /* Get the MMC controller clock divider value */ |
754 | div = div & LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(0xf); |
755 | |
756 | if (!div) |
757 | div = 1; |
758 | |
759 | return rate / div; |
760 | } |
761 | |
762 | static unsigned long mmc_round_rate(struct clk *clk, unsigned long rate) |
763 | { |
764 | unsigned long div, prate; |
765 | |
766 | /* Get the parent clock rate */ |
767 | prate = clk->parent->get_rate(clk->parent); |
768 | |
769 | if (rate >= prate) |
770 | return prate; |
771 | |
772 | div = prate / rate; |
773 | if (div > 0xf) |
774 | div = 0xf; |
775 | |
776 | return prate / div; |
777 | } |
778 | |
779 | static int mmc_set_rate(struct clk *clk, unsigned long rate) |
780 | { |
781 | u32 oldclk, tmp; |
782 | unsigned long prate, div, crate = mmc_round_rate(clk, rate); |
783 | |
784 | prate = clk->parent->get_rate(clk->parent); |
785 | |
786 | div = prate / crate; |
787 | |
788 | /* The MMC clock must be on when accessing an MMC register */ |
789 | oldclk = __raw_readl(LPC32XX_CLKPWR_MS_CTRL); |
790 | __raw_writel(oldclk | LPC32XX_CLKPWR_MSCARD_SDCARD_EN, |
791 | LPC32XX_CLKPWR_MS_CTRL); |
792 | tmp = __raw_readl(LPC32XX_CLKPWR_MS_CTRL) & |
793 | ~LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(0xf); |
794 | tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(div); |
795 | __raw_writel(tmp, LPC32XX_CLKPWR_MS_CTRL); |
796 | |
797 | __raw_writel(oldclk, LPC32XX_CLKPWR_MS_CTRL); |
798 | |
799 | return 0; |
800 | } |
801 | |
802 | static struct clk clk_mmc = { |
803 | .parent = &clk_armpll, |
804 | .set_rate = mmc_set_rate, |
805 | .get_rate = mmc_get_rate, |
806 | .round_rate = mmc_round_rate, |
807 | .enable = mmc_onoff_enable, |
808 | .enable_reg = LPC32XX_CLKPWR_MS_CTRL, |
809 | .enable_mask = LPC32XX_CLKPWR_MSCARD_SDCARD_EN, |
810 | }; |
811 | |
812 | static unsigned long clcd_get_rate(struct clk *clk) |
813 | { |
814 | u32 tmp, div, rate, oldclk; |
815 | |
816 | /* The LCD clock must be on when accessing an LCD register */ |
817 | oldclk = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL); |
818 | __raw_writel(oldclk | LPC32XX_CLKPWR_LCDCTRL_CLK_EN, |
819 | LPC32XX_CLKPWR_LCDCLK_CTRL); |
820 | tmp = __raw_readl(io_p2v(LPC32XX_LCD_BASE + CLCD_TIM2)); |
821 | __raw_writel(oldclk, LPC32XX_CLKPWR_LCDCLK_CTRL); |
822 | |
823 | rate = clk->parent->get_rate(clk->parent); |
824 | |
825 | /* Only supports internal clocking */ |
826 | if (tmp & TIM2_BCD) |
827 | return rate; |
828 | |
829 | div = (tmp & 0x1F) | ((tmp & 0xF8) >> 22); |
830 | tmp = rate / (2 + div); |
831 | |
832 | return tmp; |
833 | } |
834 | |
835 | static int clcd_set_rate(struct clk *clk, unsigned long rate) |
836 | { |
837 | u32 tmp, prate, div, oldclk; |
838 | |
839 | /* The LCD clock must be on when accessing an LCD register */ |
840 | oldclk = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL); |
841 | __raw_writel(oldclk | LPC32XX_CLKPWR_LCDCTRL_CLK_EN, |
842 | LPC32XX_CLKPWR_LCDCLK_CTRL); |
843 | |
844 | tmp = __raw_readl(io_p2v(LPC32XX_LCD_BASE + CLCD_TIM2)) | TIM2_BCD; |
845 | prate = clk->parent->get_rate(clk->parent); |
846 | |
847 | if (rate < prate) { |
848 | /* Find closest divider */ |
849 | div = prate / rate; |
850 | if (div >= 2) { |
851 | div -= 2; |
852 | tmp &= ~TIM2_BCD; |
853 | } |
854 | |
855 | tmp &= ~(0xF800001F); |
856 | tmp |= (div & 0x1F); |
857 | tmp |= (((div >> 5) & 0x1F) << 27); |
858 | } |
859 | |
860 | __raw_writel(tmp, io_p2v(LPC32XX_LCD_BASE + CLCD_TIM2)); |
861 | __raw_writel(oldclk, LPC32XX_CLKPWR_LCDCLK_CTRL); |
862 | |
863 | return 0; |
864 | } |
865 | |
866 | static unsigned long clcd_round_rate(struct clk *clk, unsigned long rate) |
867 | { |
868 | u32 prate, div; |
869 | |
870 | prate = clk->parent->get_rate(clk->parent); |
871 | |
872 | if (rate >= prate) |
873 | rate = prate; |
874 | else { |
875 | div = prate / rate; |
876 | if (div > 0x3ff) |
877 | div = 0x3ff; |
878 | |
879 | rate = prate / div; |
880 | } |
881 | |
882 | return rate; |
883 | } |
884 | |
885 | static struct clk clk_lcd = { |
886 | .parent = &clk_hclk, |
887 | .set_rate = clcd_set_rate, |
888 | .get_rate = clcd_get_rate, |
889 | .round_rate = clcd_round_rate, |
890 | .enable = local_onoff_enable, |
891 | .enable_reg = LPC32XX_CLKPWR_LCDCLK_CTRL, |
892 | .enable_mask = LPC32XX_CLKPWR_LCDCTRL_CLK_EN, |
893 | }; |
894 | |
895 | static inline void clk_lock(void) |
896 | { |
897 | mutex_lock(&clkm_lock); |
898 | } |
899 | |
900 | static inline void clk_unlock(void) |
901 | { |
902 | mutex_unlock(&clkm_lock); |
903 | } |
904 | |
905 | static void local_clk_disable(struct clk *clk) |
906 | { |
907 | WARN_ON(clk->usecount == 0); |
908 | |
909 | /* Don't attempt to disable clock if it has no users */ |
910 | if (clk->usecount > 0) { |
911 | clk->usecount--; |
912 | |
913 | /* Only disable clock when it has no more users */ |
914 | if ((clk->usecount == 0) && (clk->enable)) |
915 | clk->enable(clk, 0); |
916 | |
917 | /* Check parent clocks, they may need to be disabled too */ |
918 | if (clk->parent) |
919 | local_clk_disable(clk->parent); |
920 | } |
921 | } |
922 | |
923 | static int local_clk_enable(struct clk *clk) |
924 | { |
925 | int ret = 0; |
926 | |
927 | /* Enable parent clocks first and update use counts */ |
928 | if (clk->parent) |
929 | ret = local_clk_enable(clk->parent); |
930 | |
931 | if (!ret) { |
932 | /* Only enable clock if it's currently disabled */ |
933 | if ((clk->usecount == 0) && (clk->enable)) |
934 | ret = clk->enable(clk, 1); |
935 | |
936 | if (!ret) |
937 | clk->usecount++; |
938 | else if (clk->parent) |
939 | local_clk_disable(clk->parent); |
940 | } |
941 | |
942 | return ret; |
943 | } |
944 | |
945 | /* |
946 | * clk_enable - inform the system when the clock source should be running. |
947 | */ |
948 | int clk_enable(struct clk *clk) |
949 | { |
950 | int ret; |
951 | |
952 | clk_lock(); |
953 | ret = local_clk_enable(clk); |
954 | clk_unlock(); |
955 | |
956 | return ret; |
957 | } |
958 | EXPORT_SYMBOL(clk_enable); |
959 | |
960 | /* |
961 | * clk_disable - inform the system when the clock source is no longer required |
962 | */ |
963 | void clk_disable(struct clk *clk) |
964 | { |
965 | clk_lock(); |
966 | local_clk_disable(clk); |
967 | clk_unlock(); |
968 | } |
969 | EXPORT_SYMBOL(clk_disable); |
970 | |
971 | /* |
972 | * clk_get_rate - obtain the current clock rate (in Hz) for a clock source |
973 | */ |
974 | unsigned long clk_get_rate(struct clk *clk) |
975 | { |
976 | unsigned long rate; |
977 | |
978 | clk_lock(); |
979 | rate = clk->get_rate(clk); |
980 | clk_unlock(); |
981 | |
982 | return rate; |
983 | } |
984 | EXPORT_SYMBOL(clk_get_rate); |
985 | |
986 | /* |
987 | * clk_set_rate - set the clock rate for a clock source |
988 | */ |
989 | int clk_set_rate(struct clk *clk, unsigned long rate) |
990 | { |
991 | int ret = -EINVAL; |
992 | |
993 | /* |
994 | * Most system clocks can only be enabled or disabled, with |
995 | * the actual rate set as part of the peripheral dividers |
996 | * instead of high level clock control |
997 | */ |
998 | if (clk->set_rate) { |
999 | clk_lock(); |
1000 | ret = clk->set_rate(clk, rate); |
1001 | clk_unlock(); |
1002 | } |
1003 | |
1004 | return ret; |
1005 | } |
1006 | EXPORT_SYMBOL(clk_set_rate); |
1007 | |
1008 | /* |
1009 | * clk_round_rate - adjust a rate to the exact rate a clock can provide |
1010 | */ |
1011 | long clk_round_rate(struct clk *clk, unsigned long rate) |
1012 | { |
1013 | clk_lock(); |
1014 | |
1015 | if (clk->round_rate) |
1016 | rate = clk->round_rate(clk, rate); |
1017 | else |
1018 | rate = clk->get_rate(clk); |
1019 | |
1020 | clk_unlock(); |
1021 | |
1022 | return rate; |
1023 | } |
1024 | EXPORT_SYMBOL(clk_round_rate); |
1025 | |
1026 | /* |
1027 | * clk_set_parent - set the parent clock source for this clock |
1028 | */ |
1029 | int clk_set_parent(struct clk *clk, struct clk *parent) |
1030 | { |
1031 | /* Clock re-parenting is not supported */ |
1032 | return -EINVAL; |
1033 | } |
1034 | EXPORT_SYMBOL(clk_set_parent); |
1035 | |
1036 | /* |
1037 | * clk_get_parent - get the parent clock source for this clock |
1038 | */ |
1039 | struct clk *clk_get_parent(struct clk *clk) |
1040 | { |
1041 | return clk->parent; |
1042 | } |
1043 | EXPORT_SYMBOL(clk_get_parent); |
1044 | |
1045 | #define _REGISTER_CLOCK(d, n, c) \ |
1046 | { \ |
1047 | .dev_id = (d), \ |
1048 | .con_id = (n), \ |
1049 | .clk = &(c), \ |
1050 | }, |
1051 | |
1052 | static struct clk_lookup lookups[] = { |
1053 | _REGISTER_CLOCK(NULL, "osc_32KHz", osc_32KHz) |
1054 | _REGISTER_CLOCK(NULL, "osc_pll397", osc_pll397) |
1055 | _REGISTER_CLOCK(NULL, "osc_main", osc_main) |
1056 | _REGISTER_CLOCK(NULL, "sys_ck", clk_sys) |
1057 | _REGISTER_CLOCK(NULL, "arm_pll_ck", clk_armpll) |
1058 | _REGISTER_CLOCK(NULL, "ck_pll5", clk_usbpll) |
1059 | _REGISTER_CLOCK(NULL, "hclk_ck", clk_hclk) |
1060 | _REGISTER_CLOCK(NULL, "pclk_ck", clk_pclk) |
1061 | _REGISTER_CLOCK(NULL, "timer0_ck", clk_timer0) |
1062 | _REGISTER_CLOCK(NULL, "timer1_ck", clk_timer1) |
1063 | _REGISTER_CLOCK(NULL, "timer2_ck", clk_timer2) |
1064 | _REGISTER_CLOCK(NULL, "timer3_ck", clk_timer3) |
1065 | _REGISTER_CLOCK(NULL, "vfp9_ck", clk_vfp9) |
1066 | _REGISTER_CLOCK(NULL, "clk_dmac", clk_dma) |
1067 | _REGISTER_CLOCK("pnx4008-watchdog", NULL, clk_wdt) |
1068 | _REGISTER_CLOCK(NULL, "uart3_ck", clk_uart3) |
1069 | _REGISTER_CLOCK(NULL, "uart4_ck", clk_uart4) |
1070 | _REGISTER_CLOCK(NULL, "uart5_ck", clk_uart5) |
1071 | _REGISTER_CLOCK(NULL, "uart6_ck", clk_uart6) |
1072 | _REGISTER_CLOCK("pnx-i2c.0", NULL, clk_i2c0) |
1073 | _REGISTER_CLOCK("pnx-i2c.1", NULL, clk_i2c1) |
1074 | _REGISTER_CLOCK("pnx-i2c.2", NULL, clk_i2c2) |
1075 | _REGISTER_CLOCK("dev:ssp0", NULL, clk_ssp0) |
1076 | _REGISTER_CLOCK("dev:ssp1", NULL, clk_ssp1) |
1077 | _REGISTER_CLOCK("lpc32xx_keys.0", NULL, clk_kscan) |
1078 | _REGISTER_CLOCK("lpc32xx-nand.0", "nand_ck", clk_nand) |
1079 | _REGISTER_CLOCK("tbd", "i2s0_ck", clk_i2s0) |
1080 | _REGISTER_CLOCK("tbd", "i2s1_ck", clk_i2s1) |
1081 | _REGISTER_CLOCK("lpc32xx-ts", NULL, clk_tsc) |
1082 | _REGISTER_CLOCK("dev:mmc0", "MCLK", clk_mmc) |
1083 | _REGISTER_CLOCK("lpc-net.0", NULL, clk_net) |
1084 | _REGISTER_CLOCK("dev:clcd", NULL, clk_lcd) |
1085 | _REGISTER_CLOCK("lpc32xx_udc", "ck_usbd", clk_usbd) |
1086 | _REGISTER_CLOCK("lpc32xx_rtc", NULL, clk_rtc) |
1087 | }; |
1088 | |
1089 | static int __init clk_init(void) |
1090 | { |
1091 | int i; |
1092 | |
1093 | for (i = 0; i < ARRAY_SIZE(lookups); i++) |
1094 | clkdev_add(&lookups[i]); |
1095 | |
1096 | /* |
1097 | * Setup muxed SYSCLK for HCLK PLL base -this selects the |
1098 | * parent clock used for the ARM PLL and is used to derive |
1099 | * the many system clock rates in the device. |
1100 | */ |
1101 | if (clk_is_sysclk_mainosc() != 0) |
1102 | clk_sys.parent = &osc_main; |
1103 | else |
1104 | clk_sys.parent = &osc_pll397; |
1105 | |
1106 | clk_sys.rate = clk_sys.parent->rate; |
1107 | |
1108 | /* Compute the current ARM PLL and USB PLL frequencies */ |
1109 | local_update_armpll_rate(); |
1110 | |
1111 | /* Compute HCLK and PCLK bus rates */ |
1112 | clk_hclk.rate = clk_hclk.parent->rate / clk_get_hclk_div(); |
1113 | clk_pclk.rate = clk_pclk.parent->rate / clk_get_pclk_div(); |
1114 | |
1115 | /* |
1116 | * Enable system clocks - this step is somewhat formal, as the |
1117 | * clocks are already running, but it does get the clock data |
1118 | * inline with the actual system state. Never disable these |
1119 | * clocks as they will only stop if the system is going to sleep. |
1120 | * In that case, the chip/system power management functions will |
1121 | * handle clock gating. |
1122 | */ |
1123 | if (clk_enable(&clk_hclk) || clk_enable(&clk_pclk)) |
1124 | printk(KERN_ERR "Error enabling system HCLK and PCLK\n"); |
1125 | |
1126 | /* |
1127 | * Timers 0 and 1 were enabled and are being used by the high |
1128 | * resolution tick function prior to this driver being initialized. |
1129 | * Tag them now as used. |
1130 | */ |
1131 | if (clk_enable(&clk_timer0) || clk_enable(&clk_timer1)) |
1132 | printk(KERN_ERR "Error enabling timer tick clocks\n"); |
1133 | |
1134 | return 0; |
1135 | } |
1136 | core_initcall(clk_init); |
1137 | |
1138 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9