aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-pnx4008/clock.c
diff options
context:
space:
mode:
authorVitaly Wool <vwool@ru.mvista.com>2006-05-16 06:54:37 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-06-18 11:16:55 -0400
commit78818e477bf785391b02672d053fdbb2e111fb50 (patch)
treed1a43ddfb1b966fe981c10c874bae4faad070f29 /arch/arm/mach-pnx4008/clock.c
parenta5a503038e71a6b7d4bd9e596ac13087274e60c7 (diff)
[ARM] 3466/1: [2/3] Support for Philips PNX4008 platform: chip support
Patch from Vitaly Wool This patch adds basic chip support for PNX4008 ARM platform. It's basically the same as the previous one, but with the rmk's comments taken into account. Signed-off-by: Vitaly Wool <vwool@ru.mvista.com> Signed-off-by: Dmitry Pervushin <dpervushin@gmail.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-pnx4008/clock.c')
-rw-r--r--arch/arm/mach-pnx4008/clock.c1010
1 files changed, 1010 insertions, 0 deletions
diff --git a/arch/arm/mach-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c
new file mode 100644
index 000000000000..285b22f631e9
--- /dev/null
+++ b/arch/arm/mach-pnx4008/clock.c
@@ -0,0 +1,1010 @@
1/*
2 * arch/arm/mach-pnx4008/clock.c
3 *
4 * Clock control driver for PNX4008
5 *
6 * Authors: Vitaly Wool, Dmitry Chigirev <source@mvista.com>
7 * Generic clock management functions are partially based on:
8 * linux/arch/arm/mach-omap/clock.c
9 *
10 * 2005-2006 (c) MontaVista Software, Inc. This file is licensed under
11 * the terms of the GNU General Public License version 2. This program
12 * is licensed "as is" without any warranty of any kind, whether express
13 * or implied.
14 */
15
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/list.h>
19#include <linux/errno.h>
20#include <linux/device.h>
21#include <linux/err.h>
22#include <linux/delay.h>
23
24#include <asm/semaphore.h>
25#include <asm/hardware.h>
26#include <asm/io.h>
27
28#include <asm/arch/clock.h>
29#include "clock.h"
30
31/*forward declaration*/
32static struct clk per_ck;
33static struct clk hclk_ck;
34static struct clk ck_1MHz;
35static struct clk ck_13MHz;
36static struct clk ck_pll1;
37static int local_set_rate(struct clk *clk, u32 rate);
38
39static inline void clock_lock(void)
40{
41 local_irq_disable();
42}
43
44static inline void clock_unlock(void)
45{
46 local_irq_enable();
47}
48
49static void propagate_rate(struct clk *clk)
50{
51 struct clk *tmp_clk;
52
53 tmp_clk = clk;
54 while (tmp_clk->propagate_next) {
55 tmp_clk = tmp_clk->propagate_next;
56 local_set_rate(tmp_clk, tmp_clk->user_rate);
57 }
58}
59
60static inline void clk_reg_disable(struct clk *clk)
61{
62 if (clk->enable_reg)
63 __raw_writel(__raw_readl(clk->enable_reg) &
64 ~(1 << clk->enable_shift), clk->enable_reg);
65}
66
67static inline void clk_reg_enable(struct clk *clk)
68{
69 if (clk->enable_reg)
70 __raw_writel(__raw_readl(clk->enable_reg) |
71 (1 << clk->enable_shift), clk->enable_reg);
72}
73
74static inline void clk_reg_disable1(struct clk *clk)
75{
76 if (clk->enable_reg1)
77 __raw_writel(__raw_readl(clk->enable_reg1) &
78 ~(1 << clk->enable_shift1), clk->enable_reg1);
79}
80
81static inline void clk_reg_enable1(struct clk *clk)
82{
83 if (clk->enable_reg1)
84 __raw_writel(__raw_readl(clk->enable_reg1) |
85 (1 << clk->enable_shift1), clk->enable_reg1);
86}
87
88static int clk_wait_for_pll_lock(struct clk *clk)
89{
90 int i;
91 i = 0;
92 while (i++ < 0xFFF && !(__raw_readl(clk->scale_reg) & 1)) ; /*wait for PLL to lock */
93
94 if (!(__raw_readl(clk->scale_reg) & 1)) {
95 printk(KERN_ERR
96 "%s ERROR: failed to lock, scale reg data: %x\n",
97 clk->name, __raw_readl(clk->scale_reg));
98 return -1;
99 }
100 return 0;
101}
102
103static int switch_to_dirty_13mhz(struct clk *clk)
104{
105 int i;
106 int ret;
107 u32 tmp_reg;
108
109 ret = 0;
110
111 if (!clk->rate)
112 clk_reg_enable1(clk);
113
114 tmp_reg = __raw_readl(clk->parent_switch_reg);
115 /*if 13Mhz clock selected, select 13'MHz (dirty) source from OSC */
116 if (!(tmp_reg & 1)) {
117 tmp_reg |= (1 << 1); /* Trigger switch to 13'MHz (dirty) clock */
118 __raw_writel(tmp_reg, clk->parent_switch_reg);
119 i = 0;
120 while (i++ < 0xFFF && !(__raw_readl(clk->parent_switch_reg) & 1)) ; /*wait for 13'MHz selection status */
121
122 if (!(__raw_readl(clk->parent_switch_reg) & 1)) {
123 printk(KERN_ERR
124 "%s ERROR: failed to select 13'MHz, parent sw reg data: %x\n",
125 clk->name, __raw_readl(clk->parent_switch_reg));
126 ret = -1;
127 }
128 }
129
130 if (!clk->rate)
131 clk_reg_disable1(clk);
132
133 return ret;
134}
135
136static int switch_to_clean_13mhz(struct clk *clk)
137{
138 int i;
139 int ret;
140 u32 tmp_reg;
141
142 ret = 0;
143
144 if (!clk->rate)
145 clk_reg_enable1(clk);
146
147 tmp_reg = __raw_readl(clk->parent_switch_reg);
148 /*if 13'Mhz clock selected, select 13MHz (clean) source from OSC */
149 if (tmp_reg & 1) {
150 tmp_reg &= ~(1 << 1); /* Trigger switch to 13MHz (clean) clock */
151 __raw_writel(tmp_reg, clk->parent_switch_reg);
152 i = 0;
153 while (i++ < 0xFFF && (__raw_readl(clk->parent_switch_reg) & 1)) ; /*wait for 13MHz selection status */
154
155 if (__raw_readl(clk->parent_switch_reg) & 1) {
156 printk(KERN_ERR
157 "%s ERROR: failed to select 13MHz, parent sw reg data: %x\n",
158 clk->name, __raw_readl(clk->parent_switch_reg));
159 ret = -1;
160 }
161 }
162
163 if (!clk->rate)
164 clk_reg_disable1(clk);
165
166 return ret;
167}
168
169static int set_13MHz_parent(struct clk *clk, struct clk *parent)
170{
171 int ret = -EINVAL;
172
173 if (parent == &ck_13MHz)
174 ret = switch_to_clean_13mhz(clk);
175 else if (parent == &ck_pll1)
176 ret = switch_to_dirty_13mhz(clk);
177
178 return ret;
179}
180
181#define PLL160_MIN_FCCO 156000
182#define PLL160_MAX_FCCO 320000
183
184/*
185 * Calculate pll160 settings.
186 * Possible input: up to 320MHz with step of clk->parent->rate.
187 * In PNX4008 parent rate for pll160s may be either 1 or 13MHz.
188 * Ignored paths: "feedback" (bit 13 set), "div-by-N".
189 * Setting ARM PLL4 rate to 0 will put CPU into direct run mode.
190 * Setting PLL5 and PLL3 rate to 0 will disable USB and DSP clock input.
191 * Please refer to PNX4008 IC manual for details.
192 */
193
194static int pll160_set_rate(struct clk *clk, u32 rate)
195{
196 u32 tmp_reg, tmp_m, tmp_2p, i;
197 u32 parent_rate;
198 int ret = -EINVAL;
199
200 parent_rate = clk->parent->rate;
201
202 if (!parent_rate)
203 goto out;
204
205 /* set direct run for ARM or disable output for others */
206 clk_reg_disable(clk);
207
208 /* disable source input as well (ignored for ARM) */
209 clk_reg_disable1(clk);
210
211 tmp_reg = __raw_readl(clk->scale_reg);
212 tmp_reg &= ~0x1ffff; /*clear all settings, power down */
213 __raw_writel(tmp_reg, clk->scale_reg);
214
215 rate -= rate % parent_rate; /*round down the input */
216
217 if (rate > PLL160_MAX_FCCO)
218 rate = PLL160_MAX_FCCO;
219
220 if (!rate) {
221 clk->rate = 0;
222 ret = 0;
223 goto out;
224 }
225
226 clk_reg_enable1(clk);
227 tmp_reg = __raw_readl(clk->scale_reg);
228
229 if (rate == parent_rate) {
230 /*enter direct bypass mode */
231 tmp_reg |= ((1 << 14) | (1 << 15));
232 __raw_writel(tmp_reg, clk->scale_reg);
233 clk->rate = parent_rate;
234 clk_reg_enable(clk);
235 ret = 0;
236 goto out;
237 }
238
239 i = 0;
240 for (tmp_2p = 1; tmp_2p < 16; tmp_2p <<= 1) {
241 if (rate * tmp_2p >= PLL160_MIN_FCCO)
242 break;
243 i++;
244 }
245
246 if (tmp_2p > 1)
247 tmp_reg |= ((i - 1) << 11);
248 else
249 tmp_reg |= (1 << 14); /*direct mode, no divide */
250
251 tmp_m = rate * tmp_2p;
252 tmp_m /= parent_rate;
253
254 tmp_reg |= (tmp_m - 1) << 1; /*calculate M */
255 tmp_reg |= (1 << 16); /*power up PLL */
256 __raw_writel(tmp_reg, clk->scale_reg);
257
258 if (clk_wait_for_pll_lock(clk) < 0) {
259 clk_reg_disable(clk);
260 clk_reg_disable1(clk);
261
262 tmp_reg = __raw_readl(clk->scale_reg);
263 tmp_reg &= ~0x1ffff; /*clear all settings, power down */
264 __raw_writel(tmp_reg, clk->scale_reg);
265 clk->rate = 0;
266 ret = -EFAULT;
267 goto out;
268 }
269
270 clk->rate = (tmp_m * parent_rate) / tmp_2p;
271
272 if (clk->flags & RATE_PROPAGATES)
273 propagate_rate(clk);
274
275 clk_reg_enable(clk);
276 ret = 0;
277
278out:
279 return ret;
280}
281
282/*configure PER_CLK*/
283static int per_clk_set_rate(struct clk *clk, u32 rate)
284{
285 u32 tmp;
286
287 tmp = __raw_readl(clk->scale_reg);
288 tmp &= ~(0x1f << 2);
289 tmp |= ((clk->parent->rate / clk->rate) - 1) << 2;
290 __raw_writel(tmp, clk->scale_reg);
291 clk->rate = rate;
292 return 0;
293}
294
295/*configure HCLK*/
296static int hclk_set_rate(struct clk *clk, u32 rate)
297{
298 u32 tmp;
299 tmp = __raw_readl(clk->scale_reg);
300 tmp = tmp & ~0x3;
301 switch (rate) {
302 case 1:
303 break;
304 case 2:
305 tmp |= 1;
306 break;
307 case 4:
308 tmp |= 2;
309 break;
310 }
311
312 __raw_writel(tmp, clk->scale_reg);
313 clk->rate = rate;
314 return 0;
315}
316
317static u32 hclk_round_rate(struct clk *clk, u32 rate)
318{
319 switch (rate) {
320 case 1:
321 case 4:
322 return rate;
323 }
324 return 2;
325}
326
327static u32 per_clk_round_rate(struct clk *clk, u32 rate)
328{
329 return CLK_RATE_13MHZ;
330}
331
332static int on_off_set_rate(struct clk *clk, u32 rate)
333{
334 if (rate) {
335 clk_reg_enable(clk);
336 clk->rate = 1;
337 } else {
338 clk_reg_disable(clk);
339 clk->rate = 0;
340 }
341 return 0;
342}
343
344static int on_off_inv_set_rate(struct clk *clk, u32 rate)
345{
346 if (rate) {
347 clk_reg_disable(clk); /*enable bit is inverted */
348 clk->rate = 1;
349 } else {
350 clk_reg_enable(clk);
351 clk->rate = 0;
352 }
353 return 0;
354}
355
356static u32 on_off_round_rate(struct clk *clk, u32 rate)
357{
358 return (rate ? 1 : 0);
359}
360
361static u32 pll4_round_rate(struct clk *clk, u32 rate)
362{
363 if (rate > CLK_RATE_208MHZ)
364 rate = CLK_RATE_208MHZ;
365 if (rate == CLK_RATE_208MHZ && hclk_ck.user_rate == 1)
366 rate = CLK_RATE_208MHZ - CLK_RATE_13MHZ;
367 return (rate - (rate % (hclk_ck.user_rate * CLK_RATE_13MHZ)));
368}
369
370static u32 pll3_round_rate(struct clk *clk, u32 rate)
371{
372 if (rate > CLK_RATE_208MHZ)
373 rate = CLK_RATE_208MHZ;
374 return (rate - rate % CLK_RATE_13MHZ);
375}
376
377static u32 pll5_round_rate(struct clk *clk, u32 rate)
378{
379 return (rate ? CLK_RATE_48MHZ : 0);
380}
381
382static u32 ck_13MHz_round_rate(struct clk *clk, u32 rate)
383{
384 return (rate ? CLK_RATE_13MHZ : 0);
385}
386
387static int ck_13MHz_set_rate(struct clk *clk, u32 rate)
388{
389 if (rate) {
390 clk_reg_disable(clk); /*enable bit is inverted */
391 udelay(500);
392 clk->rate = CLK_RATE_13MHZ;
393 ck_1MHz.rate = CLK_RATE_1MHZ;
394 } else {
395 clk_reg_enable(clk);
396 clk->rate = 0;
397 ck_1MHz.rate = 0;
398 }
399 return 0;
400}
401
402static int pll1_set_rate(struct clk *clk, u32 rate)
403{
404#if 0 /* doesn't work on some boards, probably a HW BUG */
405 if (rate) {
406 clk_reg_disable(clk); /*enable bit is inverted */
407 if (!clk_wait_for_pll_lock(clk)) {
408 clk->rate = CLK_RATE_13MHZ;
409 } else {
410 clk_reg_enable(clk);
411 clk->rate = 0;
412 }
413
414 } else {
415 clk_reg_enable(clk);
416 clk->rate = 0;
417 }
418#endif
419 return 0;
420}
421
422/* Clock sources */
423
424static struct clk osc_13MHz = {
425 .name = "osc_13MHz",
426 .flags = FIXED_RATE,
427 .rate = CLK_RATE_13MHZ,
428};
429
430static struct clk ck_13MHz = {
431 .name = "ck_13MHz",
432 .parent = &osc_13MHz,
433 .flags = NEEDS_INITIALIZATION,
434 .round_rate = &ck_13MHz_round_rate,
435 .set_rate = &ck_13MHz_set_rate,
436 .enable_reg = OSC13CTRL_REG,
437 .enable_shift = 0,
438 .rate = CLK_RATE_13MHZ,
439};
440
441static struct clk osc_32KHz = {
442 .name = "osc_32KHz",
443 .flags = FIXED_RATE,
444 .rate = CLK_RATE_32KHZ,
445};
446
447/*attached to PLL5*/
448static struct clk ck_1MHz = {
449 .name = "ck_1MHz",
450 .flags = FIXED_RATE | PARENT_SET_RATE,
451 .parent = &ck_13MHz,
452};
453
454/* PLL1 (397) - provides 13' MHz clock */
455static struct clk ck_pll1 = {
456 .name = "ck_pll1",
457 .parent = &osc_32KHz,
458 .flags = NEEDS_INITIALIZATION,
459 .round_rate = &ck_13MHz_round_rate,
460 .set_rate = &pll1_set_rate,
461 .enable_reg = PLLCTRL_REG,
462 .enable_shift = 1,
463 .scale_reg = PLLCTRL_REG,
464 .rate = CLK_RATE_13MHZ,
465};
466
467/* CPU/Bus PLL */
468static struct clk ck_pll4 = {
469 .name = "ck_pll4",
470 .parent = &ck_pll1,
471 .flags = RATE_PROPAGATES | NEEDS_INITIALIZATION,
472 .propagate_next = &per_ck,
473 .round_rate = &pll4_round_rate,
474 .set_rate = &pll160_set_rate,
475 .rate = CLK_RATE_208MHZ,
476 .scale_reg = HCLKPLLCTRL_REG,
477 .enable_reg = PWRCTRL_REG,
478 .enable_shift = 2,
479 .parent_switch_reg = SYSCLKCTRL_REG,
480 .set_parent = &set_13MHz_parent,
481};
482
483/* USB PLL */
484static struct clk ck_pll5 = {
485 .name = "ck_pll5",
486 .parent = &ck_1MHz,
487 .flags = NEEDS_INITIALIZATION,
488 .round_rate = &pll5_round_rate,
489 .set_rate = &pll160_set_rate,
490 .scale_reg = USBCTRL_REG,
491 .enable_reg = USBCTRL_REG,
492 .enable_shift = 18,
493 .enable_reg1 = USBCTRL_REG,
494 .enable_shift1 = 17,
495};
496
497/* XPERTTeak DSP PLL */
498static struct clk ck_pll3 = {
499 .name = "ck_pll3",
500 .parent = &ck_pll1,
501 .flags = NEEDS_INITIALIZATION,
502 .round_rate = &pll3_round_rate,
503 .set_rate = &pll160_set_rate,
504 .scale_reg = DSPPLLCTRL_REG,
505 .enable_reg = DSPCLKCTRL_REG,
506 .enable_shift = 3,
507 .enable_reg1 = DSPCLKCTRL_REG,
508 .enable_shift1 = 2,
509 .parent_switch_reg = DSPCLKCTRL_REG,
510 .set_parent = &set_13MHz_parent,
511};
512
513static struct clk hclk_ck = {
514 .name = "hclk_ck",
515 .parent = &ck_pll4,
516 .flags = PARENT_SET_RATE,
517 .set_rate = &hclk_set_rate,
518 .round_rate = &hclk_round_rate,
519 .scale_reg = HCLKDIVCTRL_REG,
520 .rate = 2,
521 .user_rate = 2,
522};
523
524static struct clk per_ck = {
525 .name = "per_ck",
526 .parent = &ck_pll4,
527 .flags = FIXED_RATE,
528 .propagate_next = &hclk_ck,
529 .set_rate = &per_clk_set_rate,
530 .round_rate = &per_clk_round_rate,
531 .scale_reg = HCLKDIVCTRL_REG,
532 .rate = CLK_RATE_13MHZ,
533 .user_rate = CLK_RATE_13MHZ,
534};
535
536static struct clk m2hclk_ck = {
537 .name = "m2hclk_ck",
538 .parent = &hclk_ck,
539 .flags = NEEDS_INITIALIZATION,
540 .round_rate = &on_off_round_rate,
541 .set_rate = &on_off_inv_set_rate,
542 .rate = 1,
543 .enable_shift = 6,
544 .enable_reg = PWRCTRL_REG,
545};
546
547static struct clk vfp9_ck = {
548 .name = "vfp9_ck",
549 .parent = &ck_pll4,
550 .flags = NEEDS_INITIALIZATION,
551 .round_rate = &on_off_round_rate,
552 .set_rate = &on_off_set_rate,
553 .rate = 1,
554 .enable_shift = 4,
555 .enable_reg = VFP9CLKCTRL_REG,
556};
557
558static struct clk keyscan_ck = {
559 .name = "keyscan_ck",
560 .parent = &osc_32KHz,
561 .flags = NEEDS_INITIALIZATION,
562 .round_rate = &on_off_round_rate,
563 .set_rate = &on_off_set_rate,
564 .enable_shift = 0,
565 .enable_reg = KEYCLKCTRL_REG,
566};
567
568static struct clk touch_ck = {
569 .name = "touch_ck",
570 .parent = &osc_32KHz,
571 .flags = NEEDS_INITIALIZATION,
572 .round_rate = &on_off_round_rate,
573 .set_rate = &on_off_set_rate,
574 .enable_shift = 0,
575 .enable_reg = TSCLKCTRL_REG,
576};
577
578static struct clk pwm1_ck = {
579 .name = "pwm1_ck",
580 .parent = &osc_32KHz,
581 .flags = NEEDS_INITIALIZATION,
582 .round_rate = &on_off_round_rate,
583 .set_rate = &on_off_set_rate,
584 .enable_shift = 0,
585 .enable_reg = PWMCLKCTRL_REG,
586};
587
588static struct clk pwm2_ck = {
589 .name = "pwm2_ck",
590 .parent = &osc_32KHz,
591 .flags = NEEDS_INITIALIZATION,
592 .round_rate = &on_off_round_rate,
593 .set_rate = &on_off_set_rate,
594 .enable_shift = 2,
595 .enable_reg = PWMCLKCTRL_REG,
596};
597
598static struct clk jpeg_ck = {
599 .name = "jpeg_ck",
600 .parent = &hclk_ck,
601 .flags = NEEDS_INITIALIZATION,
602 .round_rate = &on_off_round_rate,
603 .set_rate = &on_off_set_rate,
604 .enable_shift = 0,
605 .enable_reg = JPEGCLKCTRL_REG,
606};
607
608static struct clk ms_ck = {
609 .name = "ms_ck",
610 .parent = &ck_pll4,
611 .flags = NEEDS_INITIALIZATION,
612 .round_rate = &on_off_round_rate,
613 .set_rate = &on_off_set_rate,
614 .enable_shift = 5,
615 .enable_reg = MSCTRL_REG,
616};
617
618static struct clk dum_ck = {
619 .name = "dum_ck",
620 .parent = &hclk_ck,
621 .flags = NEEDS_INITIALIZATION,
622 .round_rate = &on_off_round_rate,
623 .set_rate = &on_off_set_rate,
624 .enable_shift = 0,
625 .enable_reg = DUMCLKCTRL_REG,
626};
627
628static struct clk flash_ck = {
629 .name = "flash_ck",
630 .parent = &hclk_ck,
631 .round_rate = &on_off_round_rate,
632 .set_rate = &on_off_set_rate,
633 .enable_shift = 1, /* Only MLC clock supported */
634 .enable_reg = FLASHCLKCTRL_REG,
635};
636
637static struct clk i2c0_ck = {
638 .name = "i2c0_ck",
639 .parent = &per_ck,
640 .flags = NEEDS_INITIALIZATION,
641 .round_rate = &on_off_round_rate,
642 .set_rate = &on_off_set_rate,
643 .enable_shift = 0,
644 .enable_reg = I2CCLKCTRL_REG,
645};
646
647static struct clk i2c1_ck = {
648 .name = "i2c1_ck",
649 .parent = &per_ck,
650 .flags = NEEDS_INITIALIZATION,
651 .round_rate = &on_off_round_rate,
652 .set_rate = &on_off_set_rate,
653 .enable_shift = 1,
654 .enable_reg = I2CCLKCTRL_REG,
655};
656
657static struct clk i2c2_ck = {
658 .name = "i2c2_ck",
659 .parent = &per_ck,
660 .flags = NEEDS_INITIALIZATION,
661 .round_rate = &on_off_round_rate,
662 .set_rate = &on_off_set_rate,
663 .enable_shift = 2,
664 .enable_reg = USB_OTG_CLKCTRL_REG,
665};
666
667static struct clk spi0_ck = {
668 .name = "spi0_ck",
669 .parent = &hclk_ck,
670 .flags = NEEDS_INITIALIZATION,
671 .round_rate = &on_off_round_rate,
672 .set_rate = &on_off_set_rate,
673 .enable_shift = 0,
674 .enable_reg = SPICTRL_REG,
675};
676
677static struct clk spi1_ck = {
678 .name = "spi1_ck",
679 .parent = &hclk_ck,
680 .flags = NEEDS_INITIALIZATION,
681 .round_rate = &on_off_round_rate,
682 .set_rate = &on_off_set_rate,
683 .enable_shift = 4,
684 .enable_reg = SPICTRL_REG,
685};
686
687static struct clk dma_ck = {
688 .name = "dma_ck",
689 .parent = &hclk_ck,
690 .round_rate = &on_off_round_rate,
691 .set_rate = &on_off_set_rate,
692 .enable_shift = 0,
693 .enable_reg = DMACLKCTRL_REG,
694};
695
696static struct clk uart3_ck = {
697 .name = "uart3_ck",
698 .parent = &per_ck,
699 .flags = NEEDS_INITIALIZATION,
700 .round_rate = &on_off_round_rate,
701 .set_rate = &on_off_set_rate,
702 .rate = 1,
703 .enable_shift = 0,
704 .enable_reg = UARTCLKCTRL_REG,
705};
706
707static struct clk uart4_ck = {
708 .name = "uart4_ck",
709 .parent = &per_ck,
710 .flags = NEEDS_INITIALIZATION,
711 .round_rate = &on_off_round_rate,
712 .set_rate = &on_off_set_rate,
713 .enable_shift = 1,
714 .enable_reg = UARTCLKCTRL_REG,
715};
716
717static struct clk uart5_ck = {
718 .name = "uart5_ck",
719 .parent = &per_ck,
720 .flags = NEEDS_INITIALIZATION,
721 .round_rate = &on_off_round_rate,
722 .set_rate = &on_off_set_rate,
723 .rate = 1,
724 .enable_shift = 2,
725 .enable_reg = UARTCLKCTRL_REG,
726};
727
728static struct clk uart6_ck = {
729 .name = "uart6_ck",
730 .parent = &per_ck,
731 .flags = NEEDS_INITIALIZATION,
732 .round_rate = &on_off_round_rate,
733 .set_rate = &on_off_set_rate,
734 .enable_shift = 3,
735 .enable_reg = UARTCLKCTRL_REG,
736};
737
738/* These clocks are visible outside this module
739 * and can be initialized
740 */
741static struct clk *onchip_clks[] = {
742 &ck_13MHz,
743 &ck_pll1,
744 &ck_pll4,
745 &ck_pll5,
746 &ck_pll3,
747 &vfp9_ck,
748 &m2hclk_ck,
749 &hclk_ck,
750 &dma_ck,
751 &flash_ck,
752 &dum_ck,
753 &keyscan_ck,
754 &pwm1_ck,
755 &pwm2_ck,
756 &jpeg_ck,
757 &ms_ck,
758 &touch_ck,
759 &i2c0_ck,
760 &i2c1_ck,
761 &i2c2_ck,
762 &spi0_ck,
763 &spi1_ck,
764 &uart3_ck,
765 &uart4_ck,
766 &uart5_ck,
767 &uart6_ck,
768};
769
770static int local_set_rate(struct clk *clk, u32 rate)
771{
772 int ret = -EINVAL;
773 if (clk->set_rate) {
774
775 if (clk->user_rate == clk->rate && clk->parent->rate) {
776 /* if clock enabled or rate not set */
777 clk->user_rate = clk->round_rate(clk, rate);
778 ret = clk->set_rate(clk, clk->user_rate);
779 } else
780 clk->user_rate = clk->round_rate(clk, rate);
781 ret = 0;
782 }
783 return ret;
784}
785
786int clk_set_rate(struct clk *clk, unsigned long rate)
787{
788 int ret = -EINVAL;
789
790 if (clk->flags & FIXED_RATE)
791 goto out;
792
793 clock_lock();
794 if ((clk->flags & PARENT_SET_RATE) && clk->parent) {
795
796 clk->user_rate = clk->round_rate(clk, rate);
797 /* parent clock needs to be refreshed
798 for the setting to take effect */
799 } else {
800 ret = local_set_rate(clk, rate);
801 }
802 ret = 0;
803 clock_unlock();
804
805out:
806 return ret;
807}
808
809EXPORT_SYMBOL(clk_set_rate);
810
811struct clk *clk_get(struct device *dev, const char *id)
812{
813 struct clk *clk = ERR_PTR(-ENOENT);
814 struct clk **clkp;
815
816 clock_lock();
817 for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
818 clkp++) {
819 if (strcmp(id, (*clkp)->name) == 0
820 && try_module_get((*clkp)->owner)) {
821 clk = (*clkp);
822 break;
823 }
824 }
825 clock_unlock();
826
827 return clk;
828}
829EXPORT_SYMBOL(clk_get);
830
831void clk_put(struct clk *clk)
832{
833 clock_lock();
834 if (clk && !IS_ERR(clk))
835 module_put(clk->owner);
836 clock_unlock();
837}
838EXPORT_SYMBOL(clk_put);
839
840unsigned long clk_get_rate(struct clk *clk)
841{
842 unsigned long ret;
843 clock_lock();
844 ret = clk->rate;
845 clock_unlock();
846 return ret;
847}
848EXPORT_SYMBOL(clk_get_rate);
849
850static int local_clk_enable(struct clk *clk)
851{
852 int ret = 0;
853
854 if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate
855 && clk->user_rate)
856 ret = clk->set_rate(clk, clk->user_rate);
857 return ret;
858}
859
860static void local_clk_disable(struct clk *clk)
861{
862 if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate)
863 clk->set_rate(clk, 0);
864}
865
866int clk_enable(struct clk *clk)
867{
868 int ret = 0;
869
870 clock_lock();
871 ret = local_clk_enable(clk);
872 clock_unlock();
873 return ret;
874}
875
876EXPORT_SYMBOL(clk_enable);
877
878void clk_disable(struct clk *clk)
879{
880 clock_lock();
881 local_clk_disable(clk);
882 clock_unlock();
883}
884
885EXPORT_SYMBOL(clk_disable);
886
887static void local_clk_unuse(struct clk *clk)
888{
889 if (clk->usecount > 0 && !(--clk->usecount)) {
890 local_clk_disable(clk);
891 if (clk->parent)
892 local_clk_unuse(clk->parent);
893 }
894}
895
896static int local_clk_use(struct clk *clk)
897{
898 int ret = 0;
899 if (clk->usecount++ == 0) {
900 if (clk->parent)
901 ret = local_clk_use(clk->parent);
902
903 if (ret != 0) {
904 clk->usecount--;
905 goto out;
906 }
907
908 ret = local_clk_enable(clk);
909
910 if (ret != 0 && clk->parent) {
911 local_clk_unuse(clk->parent);
912 clk->usecount--;
913 }
914 }
915out:
916 return ret;
917}
918
919/* The main purpose of clk_use ans clk_unuse functions
920 * is to control switching 13MHz oscillator and PLL1 (13'MHz),
921 * so that they are disabled whenever none of PLL2-5 is using them.
922 * Although in theory these functions should work with any clock,
923 * please use them only on PLL2 - PLL5 to avoid confusion.
924 */
925int clk_use(struct clk *clk)
926{
927 int ret = 0;
928
929 clock_lock();
930 ret = local_clk_use(clk);
931 clock_unlock();
932 return ret;
933}
934EXPORT_SYMBOL(clk_use);
935
936void clk_unuse(struct clk *clk)
937{
938
939 clock_lock();
940 local_clk_unuse(clk);
941 clock_unlock();
942}
943
944EXPORT_SYMBOL(clk_unuse);
945
946long clk_round_rate(struct clk *clk, unsigned long rate)
947{
948 long ret;
949 clock_lock();
950 if (clk->round_rate)
951 ret = clk->round_rate(clk, rate);
952 else
953 ret = clk->rate;
954 clock_unlock();
955 return ret;
956}
957
958EXPORT_SYMBOL(clk_round_rate);
959
960int clk_set_parent(struct clk *clk, struct clk *parent)
961{
962 int ret = -ENODEV;
963 if (!clk->set_parent)
964 goto out;
965
966 clock_lock();
967 ret = clk->set_parent(clk, parent);
968 if (!ret)
969 clk->parent = parent;
970 clock_unlock();
971
972out:
973 return ret;
974}
975
976EXPORT_SYMBOL(clk_set_parent);
977
978static int __init clk_init(void)
979{
980 struct clk **clkp;
981
982 /* Disable autoclocking, as it doesn't seem to work */
983 __raw_writel(0xff, AUTOCLK_CTRL);
984
985 for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
986 clkp++) {
987 if (((*clkp)->flags & NEEDS_INITIALIZATION)
988 && ((*clkp)->set_rate)) {
989 (*clkp)->user_rate = (*clkp)->rate;
990 local_set_rate((*clkp), (*clkp)->user_rate);
991 if ((*clkp)->set_parent)
992 (*clkp)->set_parent((*clkp), (*clkp)->parent);
993 }
994 pr_debug("%s: clock %s, rate %ld\n",
995 __FUNCTION__, (*clkp)->name, (*clkp)->rate);
996 }
997
998 clk_use(&ck_pll4);
999
1000 /* if ck_13MHz is not used, disable it. */
1001 if (ck_13MHz.usecount == 0)
1002 local_clk_disable(&ck_13MHz);
1003
1004 /* Disable autoclocking */
1005 __raw_writeb(0xff, AUTOCLK_CTRL);
1006
1007 return 0;
1008}
1009
1010arch_initcall(clk_init);