blob: 3ad694e15968ca4561ed7b46e5aa282a6643ba5a [file] [log] [blame]
Vitaly Wool78818e42006-05-16 11:54:37 +01001/*
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>
Russell Kingfced80c2008-09-06 12:10:45 +010023#include <linux/io.h>
Vitaly Wool78818e42006-05-16 11:54:37 +010024
Russell King6985a5a2009-11-20 10:32:41 +000025#include <asm/clkdev.h>
Vitaly Wool78818e42006-05-16 11:54:37 +010026
Russell King6985a5a2009-11-20 10:32:41 +000027#include <mach/hardware.h>
Russell Kinga09e64f2008-08-05 16:14:15 +010028#include <mach/clock.h>
Vitaly Wool78818e42006-05-16 11:54:37 +010029#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
Russell King0c452df2009-11-20 11:28:59 +000060static void clk_reg_disable(struct clk *clk)
Vitaly Wool78818e42006-05-16 11:54:37 +010061{
62 if (clk->enable_reg)
63 __raw_writel(__raw_readl(clk->enable_reg) &
64 ~(1 << clk->enable_shift), clk->enable_reg);
65}
66
Russell King0c452df2009-11-20 11:28:59 +000067static int clk_reg_enable(struct clk *clk)
Vitaly Wool78818e42006-05-16 11:54:37 +010068{
69 if (clk->enable_reg)
70 __raw_writel(__raw_readl(clk->enable_reg) |
71 (1 << clk->enable_shift), clk->enable_reg);
Russell King0c452df2009-11-20 11:28:59 +000072 return 0;
Vitaly Wool78818e42006-05-16 11:54:37 +010073}
74
75static inline void clk_reg_disable1(struct clk *clk)
76{
77 if (clk->enable_reg1)
78 __raw_writel(__raw_readl(clk->enable_reg1) &
79 ~(1 << clk->enable_shift1), clk->enable_reg1);
80}
81
82static inline void clk_reg_enable1(struct clk *clk)
83{
84 if (clk->enable_reg1)
85 __raw_writel(__raw_readl(clk->enable_reg1) |
86 (1 << clk->enable_shift1), clk->enable_reg1);
87}
88
89static int clk_wait_for_pll_lock(struct clk *clk)
90{
91 int i;
92 i = 0;
93 while (i++ < 0xFFF && !(__raw_readl(clk->scale_reg) & 1)) ; /*wait for PLL to lock */
94
95 if (!(__raw_readl(clk->scale_reg) & 1)) {
96 printk(KERN_ERR
97 "%s ERROR: failed to lock, scale reg data: %x\n",
98 clk->name, __raw_readl(clk->scale_reg));
99 return -1;
100 }
101 return 0;
102}
103
104static int switch_to_dirty_13mhz(struct clk *clk)
105{
106 int i;
107 int ret;
108 u32 tmp_reg;
109
110 ret = 0;
111
112 if (!clk->rate)
113 clk_reg_enable1(clk);
114
115 tmp_reg = __raw_readl(clk->parent_switch_reg);
116 /*if 13Mhz clock selected, select 13'MHz (dirty) source from OSC */
117 if (!(tmp_reg & 1)) {
118 tmp_reg |= (1 << 1); /* Trigger switch to 13'MHz (dirty) clock */
119 __raw_writel(tmp_reg, clk->parent_switch_reg);
120 i = 0;
121 while (i++ < 0xFFF && !(__raw_readl(clk->parent_switch_reg) & 1)) ; /*wait for 13'MHz selection status */
122
123 if (!(__raw_readl(clk->parent_switch_reg) & 1)) {
124 printk(KERN_ERR
125 "%s ERROR: failed to select 13'MHz, parent sw reg data: %x\n",
126 clk->name, __raw_readl(clk->parent_switch_reg));
127 ret = -1;
128 }
129 }
130
131 if (!clk->rate)
132 clk_reg_disable1(clk);
133
134 return ret;
135}
136
137static int switch_to_clean_13mhz(struct clk *clk)
138{
139 int i;
140 int ret;
141 u32 tmp_reg;
142
143 ret = 0;
144
145 if (!clk->rate)
146 clk_reg_enable1(clk);
147
148 tmp_reg = __raw_readl(clk->parent_switch_reg);
149 /*if 13'Mhz clock selected, select 13MHz (clean) source from OSC */
150 if (tmp_reg & 1) {
151 tmp_reg &= ~(1 << 1); /* Trigger switch to 13MHz (clean) clock */
152 __raw_writel(tmp_reg, clk->parent_switch_reg);
153 i = 0;
154 while (i++ < 0xFFF && (__raw_readl(clk->parent_switch_reg) & 1)) ; /*wait for 13MHz selection status */
155
156 if (__raw_readl(clk->parent_switch_reg) & 1) {
157 printk(KERN_ERR
158 "%s ERROR: failed to select 13MHz, parent sw reg data: %x\n",
159 clk->name, __raw_readl(clk->parent_switch_reg));
160 ret = -1;
161 }
162 }
163
164 if (!clk->rate)
165 clk_reg_disable1(clk);
166
167 return ret;
168}
169
170static int set_13MHz_parent(struct clk *clk, struct clk *parent)
171{
172 int ret = -EINVAL;
173
174 if (parent == &ck_13MHz)
175 ret = switch_to_clean_13mhz(clk);
176 else if (parent == &ck_pll1)
177 ret = switch_to_dirty_13mhz(clk);
178
179 return ret;
180}
181
182#define PLL160_MIN_FCCO 156000
183#define PLL160_MAX_FCCO 320000
184
185/*
186 * Calculate pll160 settings.
187 * Possible input: up to 320MHz with step of clk->parent->rate.
188 * In PNX4008 parent rate for pll160s may be either 1 or 13MHz.
189 * Ignored paths: "feedback" (bit 13 set), "div-by-N".
190 * Setting ARM PLL4 rate to 0 will put CPU into direct run mode.
191 * Setting PLL5 and PLL3 rate to 0 will disable USB and DSP clock input.
192 * Please refer to PNX4008 IC manual for details.
193 */
194
195static int pll160_set_rate(struct clk *clk, u32 rate)
196{
197 u32 tmp_reg, tmp_m, tmp_2p, i;
198 u32 parent_rate;
199 int ret = -EINVAL;
200
201 parent_rate = clk->parent->rate;
202
203 if (!parent_rate)
204 goto out;
205
206 /* set direct run for ARM or disable output for others */
207 clk_reg_disable(clk);
208
209 /* disable source input as well (ignored for ARM) */
210 clk_reg_disable1(clk);
211
212 tmp_reg = __raw_readl(clk->scale_reg);
213 tmp_reg &= ~0x1ffff; /*clear all settings, power down */
214 __raw_writel(tmp_reg, clk->scale_reg);
215
216 rate -= rate % parent_rate; /*round down the input */
217
218 if (rate > PLL160_MAX_FCCO)
219 rate = PLL160_MAX_FCCO;
220
221 if (!rate) {
222 clk->rate = 0;
223 ret = 0;
224 goto out;
225 }
226
227 clk_reg_enable1(clk);
228 tmp_reg = __raw_readl(clk->scale_reg);
229
230 if (rate == parent_rate) {
231 /*enter direct bypass mode */
232 tmp_reg |= ((1 << 14) | (1 << 15));
233 __raw_writel(tmp_reg, clk->scale_reg);
234 clk->rate = parent_rate;
235 clk_reg_enable(clk);
236 ret = 0;
237 goto out;
238 }
239
240 i = 0;
241 for (tmp_2p = 1; tmp_2p < 16; tmp_2p <<= 1) {
242 if (rate * tmp_2p >= PLL160_MIN_FCCO)
243 break;
244 i++;
245 }
246
247 if (tmp_2p > 1)
248 tmp_reg |= ((i - 1) << 11);
249 else
250 tmp_reg |= (1 << 14); /*direct mode, no divide */
251
252 tmp_m = rate * tmp_2p;
253 tmp_m /= parent_rate;
254
255 tmp_reg |= (tmp_m - 1) << 1; /*calculate M */
256 tmp_reg |= (1 << 16); /*power up PLL */
257 __raw_writel(tmp_reg, clk->scale_reg);
258
259 if (clk_wait_for_pll_lock(clk) < 0) {
260 clk_reg_disable(clk);
261 clk_reg_disable1(clk);
262
263 tmp_reg = __raw_readl(clk->scale_reg);
264 tmp_reg &= ~0x1ffff; /*clear all settings, power down */
265 __raw_writel(tmp_reg, clk->scale_reg);
266 clk->rate = 0;
267 ret = -EFAULT;
268 goto out;
269 }
270
271 clk->rate = (tmp_m * parent_rate) / tmp_2p;
272
273 if (clk->flags & RATE_PROPAGATES)
274 propagate_rate(clk);
275
276 clk_reg_enable(clk);
277 ret = 0;
278
279out:
280 return ret;
281}
282
283/*configure PER_CLK*/
284static int per_clk_set_rate(struct clk *clk, u32 rate)
285{
286 u32 tmp;
287
288 tmp = __raw_readl(clk->scale_reg);
289 tmp &= ~(0x1f << 2);
290 tmp |= ((clk->parent->rate / clk->rate) - 1) << 2;
291 __raw_writel(tmp, clk->scale_reg);
292 clk->rate = rate;
293 return 0;
294}
295
296/*configure HCLK*/
297static int hclk_set_rate(struct clk *clk, u32 rate)
298{
299 u32 tmp;
300 tmp = __raw_readl(clk->scale_reg);
301 tmp = tmp & ~0x3;
302 switch (rate) {
303 case 1:
304 break;
305 case 2:
306 tmp |= 1;
307 break;
308 case 4:
309 tmp |= 2;
310 break;
311 }
312
313 __raw_writel(tmp, clk->scale_reg);
314 clk->rate = rate;
315 return 0;
316}
317
318static u32 hclk_round_rate(struct clk *clk, u32 rate)
319{
320 switch (rate) {
321 case 1:
322 case 4:
323 return rate;
324 }
325 return 2;
326}
327
328static u32 per_clk_round_rate(struct clk *clk, u32 rate)
329{
330 return CLK_RATE_13MHZ;
331}
332
333static int on_off_set_rate(struct clk *clk, u32 rate)
334{
335 if (rate) {
336 clk_reg_enable(clk);
337 clk->rate = 1;
338 } else {
339 clk_reg_disable(clk);
340 clk->rate = 0;
341 }
342 return 0;
343}
344
345static int on_off_inv_set_rate(struct clk *clk, u32 rate)
346{
347 if (rate) {
348 clk_reg_disable(clk); /*enable bit is inverted */
349 clk->rate = 1;
350 } else {
351 clk_reg_enable(clk);
352 clk->rate = 0;
353 }
354 return 0;
355}
356
357static u32 on_off_round_rate(struct clk *clk, u32 rate)
358{
359 return (rate ? 1 : 0);
360}
361
362static u32 pll4_round_rate(struct clk *clk, u32 rate)
363{
364 if (rate > CLK_RATE_208MHZ)
365 rate = CLK_RATE_208MHZ;
366 if (rate == CLK_RATE_208MHZ && hclk_ck.user_rate == 1)
367 rate = CLK_RATE_208MHZ - CLK_RATE_13MHZ;
368 return (rate - (rate % (hclk_ck.user_rate * CLK_RATE_13MHZ)));
369}
370
371static u32 pll3_round_rate(struct clk *clk, u32 rate)
372{
373 if (rate > CLK_RATE_208MHZ)
374 rate = CLK_RATE_208MHZ;
375 return (rate - rate % CLK_RATE_13MHZ);
376}
377
378static u32 pll5_round_rate(struct clk *clk, u32 rate)
379{
380 return (rate ? CLK_RATE_48MHZ : 0);
381}
382
383static u32 ck_13MHz_round_rate(struct clk *clk, u32 rate)
384{
385 return (rate ? CLK_RATE_13MHZ : 0);
386}
387
388static int ck_13MHz_set_rate(struct clk *clk, u32 rate)
389{
390 if (rate) {
391 clk_reg_disable(clk); /*enable bit is inverted */
392 udelay(500);
393 clk->rate = CLK_RATE_13MHZ;
394 ck_1MHz.rate = CLK_RATE_1MHZ;
395 } else {
396 clk_reg_enable(clk);
397 clk->rate = 0;
398 ck_1MHz.rate = 0;
399 }
400 return 0;
401}
402
403static int pll1_set_rate(struct clk *clk, u32 rate)
404{
405#if 0 /* doesn't work on some boards, probably a HW BUG */
406 if (rate) {
407 clk_reg_disable(clk); /*enable bit is inverted */
408 if (!clk_wait_for_pll_lock(clk)) {
409 clk->rate = CLK_RATE_13MHZ;
410 } else {
411 clk_reg_enable(clk);
412 clk->rate = 0;
413 }
414
415 } else {
416 clk_reg_enable(clk);
417 clk->rate = 0;
418 }
419#endif
420 return 0;
421}
422
423/* Clock sources */
424
425static struct clk osc_13MHz = {
426 .name = "osc_13MHz",
427 .flags = FIXED_RATE,
428 .rate = CLK_RATE_13MHZ,
429};
430
431static struct clk ck_13MHz = {
432 .name = "ck_13MHz",
433 .parent = &osc_13MHz,
434 .flags = NEEDS_INITIALIZATION,
435 .round_rate = &ck_13MHz_round_rate,
436 .set_rate = &ck_13MHz_set_rate,
437 .enable_reg = OSC13CTRL_REG,
438 .enable_shift = 0,
439 .rate = CLK_RATE_13MHZ,
440};
441
442static struct clk osc_32KHz = {
443 .name = "osc_32KHz",
444 .flags = FIXED_RATE,
445 .rate = CLK_RATE_32KHZ,
446};
447
448/*attached to PLL5*/
449static struct clk ck_1MHz = {
450 .name = "ck_1MHz",
451 .flags = FIXED_RATE | PARENT_SET_RATE,
452 .parent = &ck_13MHz,
453};
454
455/* PLL1 (397) - provides 13' MHz clock */
456static struct clk ck_pll1 = {
457 .name = "ck_pll1",
458 .parent = &osc_32KHz,
459 .flags = NEEDS_INITIALIZATION,
460 .round_rate = &ck_13MHz_round_rate,
461 .set_rate = &pll1_set_rate,
462 .enable_reg = PLLCTRL_REG,
463 .enable_shift = 1,
464 .scale_reg = PLLCTRL_REG,
465 .rate = CLK_RATE_13MHZ,
466};
467
468/* CPU/Bus PLL */
469static struct clk ck_pll4 = {
470 .name = "ck_pll4",
471 .parent = &ck_pll1,
472 .flags = RATE_PROPAGATES | NEEDS_INITIALIZATION,
473 .propagate_next = &per_ck,
474 .round_rate = &pll4_round_rate,
475 .set_rate = &pll160_set_rate,
476 .rate = CLK_RATE_208MHZ,
477 .scale_reg = HCLKPLLCTRL_REG,
478 .enable_reg = PWRCTRL_REG,
479 .enable_shift = 2,
480 .parent_switch_reg = SYSCLKCTRL_REG,
481 .set_parent = &set_13MHz_parent,
482};
483
484/* USB PLL */
485static struct clk ck_pll5 = {
486 .name = "ck_pll5",
487 .parent = &ck_1MHz,
488 .flags = NEEDS_INITIALIZATION,
489 .round_rate = &pll5_round_rate,
490 .set_rate = &pll160_set_rate,
491 .scale_reg = USBCTRL_REG,
492 .enable_reg = USBCTRL_REG,
493 .enable_shift = 18,
494 .enable_reg1 = USBCTRL_REG,
495 .enable_shift1 = 17,
496};
497
498/* XPERTTeak DSP PLL */
499static struct clk ck_pll3 = {
500 .name = "ck_pll3",
501 .parent = &ck_pll1,
502 .flags = NEEDS_INITIALIZATION,
503 .round_rate = &pll3_round_rate,
504 .set_rate = &pll160_set_rate,
505 .scale_reg = DSPPLLCTRL_REG,
506 .enable_reg = DSPCLKCTRL_REG,
507 .enable_shift = 3,
508 .enable_reg1 = DSPCLKCTRL_REG,
509 .enable_shift1 = 2,
510 .parent_switch_reg = DSPCLKCTRL_REG,
511 .set_parent = &set_13MHz_parent,
512};
513
514static struct clk hclk_ck = {
515 .name = "hclk_ck",
516 .parent = &ck_pll4,
517 .flags = PARENT_SET_RATE,
518 .set_rate = &hclk_set_rate,
519 .round_rate = &hclk_round_rate,
520 .scale_reg = HCLKDIVCTRL_REG,
521 .rate = 2,
522 .user_rate = 2,
523};
524
525static struct clk per_ck = {
526 .name = "per_ck",
527 .parent = &ck_pll4,
528 .flags = FIXED_RATE,
529 .propagate_next = &hclk_ck,
530 .set_rate = &per_clk_set_rate,
531 .round_rate = &per_clk_round_rate,
532 .scale_reg = HCLKDIVCTRL_REG,
533 .rate = CLK_RATE_13MHZ,
534 .user_rate = CLK_RATE_13MHZ,
535};
536
537static struct clk m2hclk_ck = {
538 .name = "m2hclk_ck",
539 .parent = &hclk_ck,
540 .flags = NEEDS_INITIALIZATION,
541 .round_rate = &on_off_round_rate,
542 .set_rate = &on_off_inv_set_rate,
543 .rate = 1,
544 .enable_shift = 6,
545 .enable_reg = PWRCTRL_REG,
546};
547
548static struct clk vfp9_ck = {
549 .name = "vfp9_ck",
550 .parent = &ck_pll4,
551 .flags = NEEDS_INITIALIZATION,
552 .round_rate = &on_off_round_rate,
553 .set_rate = &on_off_set_rate,
554 .rate = 1,
555 .enable_shift = 4,
556 .enable_reg = VFP9CLKCTRL_REG,
557};
558
559static struct clk keyscan_ck = {
560 .name = "keyscan_ck",
561 .parent = &osc_32KHz,
562 .flags = NEEDS_INITIALIZATION,
563 .round_rate = &on_off_round_rate,
564 .set_rate = &on_off_set_rate,
565 .enable_shift = 0,
566 .enable_reg = KEYCLKCTRL_REG,
567};
568
569static struct clk touch_ck = {
570 .name = "touch_ck",
571 .parent = &osc_32KHz,
572 .flags = NEEDS_INITIALIZATION,
573 .round_rate = &on_off_round_rate,
574 .set_rate = &on_off_set_rate,
575 .enable_shift = 0,
576 .enable_reg = TSCLKCTRL_REG,
577};
578
579static struct clk pwm1_ck = {
580 .name = "pwm1_ck",
581 .parent = &osc_32KHz,
582 .flags = NEEDS_INITIALIZATION,
583 .round_rate = &on_off_round_rate,
584 .set_rate = &on_off_set_rate,
585 .enable_shift = 0,
586 .enable_reg = PWMCLKCTRL_REG,
587};
588
589static struct clk pwm2_ck = {
590 .name = "pwm2_ck",
591 .parent = &osc_32KHz,
592 .flags = NEEDS_INITIALIZATION,
593 .round_rate = &on_off_round_rate,
594 .set_rate = &on_off_set_rate,
595 .enable_shift = 2,
596 .enable_reg = PWMCLKCTRL_REG,
597};
598
599static struct clk jpeg_ck = {
600 .name = "jpeg_ck",
601 .parent = &hclk_ck,
602 .flags = NEEDS_INITIALIZATION,
603 .round_rate = &on_off_round_rate,
604 .set_rate = &on_off_set_rate,
605 .enable_shift = 0,
606 .enable_reg = JPEGCLKCTRL_REG,
607};
608
609static struct clk ms_ck = {
610 .name = "ms_ck",
611 .parent = &ck_pll4,
612 .flags = NEEDS_INITIALIZATION,
613 .round_rate = &on_off_round_rate,
614 .set_rate = &on_off_set_rate,
615 .enable_shift = 5,
616 .enable_reg = MSCTRL_REG,
617};
618
619static struct clk dum_ck = {
620 .name = "dum_ck",
621 .parent = &hclk_ck,
622 .flags = NEEDS_INITIALIZATION,
623 .round_rate = &on_off_round_rate,
624 .set_rate = &on_off_set_rate,
625 .enable_shift = 0,
626 .enable_reg = DUMCLKCTRL_REG,
627};
628
629static struct clk flash_ck = {
630 .name = "flash_ck",
631 .parent = &hclk_ck,
632 .round_rate = &on_off_round_rate,
633 .set_rate = &on_off_set_rate,
634 .enable_shift = 1, /* Only MLC clock supported */
635 .enable_reg = FLASHCLKCTRL_REG,
636};
637
638static struct clk i2c0_ck = {
639 .name = "i2c0_ck",
640 .parent = &per_ck,
641 .flags = NEEDS_INITIALIZATION,
642 .round_rate = &on_off_round_rate,
643 .set_rate = &on_off_set_rate,
644 .enable_shift = 0,
645 .enable_reg = I2CCLKCTRL_REG,
646};
647
648static struct clk i2c1_ck = {
649 .name = "i2c1_ck",
650 .parent = &per_ck,
651 .flags = NEEDS_INITIALIZATION,
652 .round_rate = &on_off_round_rate,
653 .set_rate = &on_off_set_rate,
654 .enable_shift = 1,
655 .enable_reg = I2CCLKCTRL_REG,
656};
657
658static struct clk i2c2_ck = {
659 .name = "i2c2_ck",
660 .parent = &per_ck,
661 .flags = NEEDS_INITIALIZATION,
662 .round_rate = &on_off_round_rate,
663 .set_rate = &on_off_set_rate,
664 .enable_shift = 2,
665 .enable_reg = USB_OTG_CLKCTRL_REG,
666};
667
668static struct clk spi0_ck = {
669 .name = "spi0_ck",
670 .parent = &hclk_ck,
671 .flags = NEEDS_INITIALIZATION,
672 .round_rate = &on_off_round_rate,
673 .set_rate = &on_off_set_rate,
674 .enable_shift = 0,
675 .enable_reg = SPICTRL_REG,
676};
677
678static struct clk spi1_ck = {
679 .name = "spi1_ck",
680 .parent = &hclk_ck,
681 .flags = NEEDS_INITIALIZATION,
682 .round_rate = &on_off_round_rate,
683 .set_rate = &on_off_set_rate,
684 .enable_shift = 4,
685 .enable_reg = SPICTRL_REG,
686};
687
688static struct clk dma_ck = {
689 .name = "dma_ck",
690 .parent = &hclk_ck,
691 .round_rate = &on_off_round_rate,
692 .set_rate = &on_off_set_rate,
693 .enable_shift = 0,
694 .enable_reg = DMACLKCTRL_REG,
695};
696
697static struct clk uart3_ck = {
698 .name = "uart3_ck",
699 .parent = &per_ck,
700 .flags = NEEDS_INITIALIZATION,
701 .round_rate = &on_off_round_rate,
702 .set_rate = &on_off_set_rate,
703 .rate = 1,
704 .enable_shift = 0,
705 .enable_reg = UARTCLKCTRL_REG,
706};
707
708static struct clk uart4_ck = {
709 .name = "uart4_ck",
710 .parent = &per_ck,
711 .flags = NEEDS_INITIALIZATION,
712 .round_rate = &on_off_round_rate,
713 .set_rate = &on_off_set_rate,
714 .enable_shift = 1,
715 .enable_reg = UARTCLKCTRL_REG,
716};
717
718static struct clk uart5_ck = {
719 .name = "uart5_ck",
720 .parent = &per_ck,
721 .flags = NEEDS_INITIALIZATION,
722 .round_rate = &on_off_round_rate,
723 .set_rate = &on_off_set_rate,
724 .rate = 1,
725 .enable_shift = 2,
726 .enable_reg = UARTCLKCTRL_REG,
727};
728
729static struct clk uart6_ck = {
730 .name = "uart6_ck",
731 .parent = &per_ck,
732 .flags = NEEDS_INITIALIZATION,
733 .round_rate = &on_off_round_rate,
734 .set_rate = &on_off_set_rate,
735 .enable_shift = 3,
736 .enable_reg = UARTCLKCTRL_REG,
737};
738
Vitaly Wool9325fa362006-06-26 19:31:49 +0400739static struct clk wdt_ck = {
740 .name = "wdt_ck",
741 .parent = &per_ck,
742 .flags = NEEDS_INITIALIZATION,
743 .round_rate = &on_off_round_rate,
744 .set_rate = &on_off_set_rate,
745 .enable_shift = 0,
746 .enable_reg = TIMCLKCTRL_REG,
747};
748
Vitaly Wool78818e42006-05-16 11:54:37 +0100749/* These clocks are visible outside this module
750 * and can be initialized
751 */
Russell King6985a5a2009-11-20 10:32:41 +0000752static struct clk *onchip_clks[] __initdata = {
Vitaly Wool78818e42006-05-16 11:54:37 +0100753 &ck_13MHz,
754 &ck_pll1,
755 &ck_pll4,
756 &ck_pll5,
757 &ck_pll3,
758 &vfp9_ck,
759 &m2hclk_ck,
760 &hclk_ck,
761 &dma_ck,
762 &flash_ck,
763 &dum_ck,
764 &keyscan_ck,
765 &pwm1_ck,
766 &pwm2_ck,
767 &jpeg_ck,
768 &ms_ck,
769 &touch_ck,
770 &i2c0_ck,
771 &i2c1_ck,
772 &i2c2_ck,
773 &spi0_ck,
774 &spi1_ck,
775 &uart3_ck,
776 &uart4_ck,
777 &uart5_ck,
778 &uart6_ck,
Vitaly Wool9325fa362006-06-26 19:31:49 +0400779 &wdt_ck,
Vitaly Wool78818e42006-05-16 11:54:37 +0100780};
781
Russell King6985a5a2009-11-20 10:32:41 +0000782static struct clk_lookup onchip_clkreg[] = {
783 { .clk = &ck_13MHz, .con_id = "ck_13MHz" },
784 { .clk = &ck_pll1, .con_id = "ck_pll1" },
785 { .clk = &ck_pll4, .con_id = "ck_pll4" },
786 { .clk = &ck_pll5, .con_id = "ck_pll5" },
787 { .clk = &ck_pll3, .con_id = "ck_pll3" },
788 { .clk = &vfp9_ck, .con_id = "vfp9_ck" },
789 { .clk = &m2hclk_ck, .con_id = "m2hclk_ck" },
790 { .clk = &hclk_ck, .con_id = "hclk_ck" },
791 { .clk = &dma_ck, .con_id = "dma_ck" },
792 { .clk = &flash_ck, .con_id = "flash_ck" },
793 { .clk = &dum_ck, .con_id = "dum_ck" },
794 { .clk = &keyscan_ck, .con_id = "keyscan_ck" },
795 { .clk = &pwm1_ck, .con_id = "pwm1_ck" },
796 { .clk = &pwm2_ck, .con_id = "pwm2_ck" },
797 { .clk = &jpeg_ck, .con_id = "jpeg_ck" },
798 { .clk = &ms_ck, .con_id = "ms_ck" },
799 { .clk = &touch_ck, .con_id = "touch_ck" },
800 { .clk = &i2c0_ck, .con_id = "i2c0_ck" },
801 { .clk = &i2c1_ck, .con_id = "i2c1_ck" },
802 { .clk = &i2c2_ck, .con_id = "i2c2_ck" },
803 { .clk = &spi0_ck, .con_id = "spi0_ck" },
804 { .clk = &spi1_ck, .con_id = "spi1_ck" },
805 { .clk = &uart3_ck, .con_id = "uart3_ck" },
806 { .clk = &uart4_ck, .con_id = "uart4_ck" },
807 { .clk = &uart5_ck, .con_id = "uart5_ck" },
808 { .clk = &uart6_ck, .con_id = "uart6_ck" },
809 { .clk = &wdt_ck, .con_id = "wdt_ck" },
810};
811
Russell King5413f742009-11-20 11:25:44 +0000812static void local_clk_disable(struct clk *clk)
813{
814 if (WARN_ON(clk->usecount == 0))
815 return;
816
817 if (!(--clk->usecount)) {
Russell King0c452df2009-11-20 11:28:59 +0000818 if (clk->disable)
819 clk->disable(clk);
820 else if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate)
Russell King5413f742009-11-20 11:25:44 +0000821 clk->set_rate(clk, 0);
822 if (clk->parent)
823 local_clk_disable(clk->parent);
824 }
825}
826
Vitaly Woole9931b52006-06-22 10:26:20 +0100827static int local_clk_enable(struct clk *clk)
828{
829 int ret = 0;
830
Russell King5413f742009-11-20 11:25:44 +0000831 if (clk->usecount == 0) {
832 if (clk->parent) {
833 ret = local_clk_enable(clk->parent);
834 if (ret != 0)
835 goto out;
836 }
Vitaly Woole9931b52006-06-22 10:26:20 +0100837
Russell King0c452df2009-11-20 11:28:59 +0000838 if (clk->enable)
839 ret = clk->enable(clk);
840 else if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate
841 && clk->user_rate)
Russell King5413f742009-11-20 11:25:44 +0000842 ret = clk->set_rate(clk, clk->user_rate);
Vitaly Woole9931b52006-06-22 10:26:20 +0100843
Russell King5413f742009-11-20 11:25:44 +0000844 if (ret != 0 && clk->parent) {
845 local_clk_disable(clk->parent);
Vitaly Woole9931b52006-06-22 10:26:20 +0100846 goto out;
847 }
848
Russell King5413f742009-11-20 11:25:44 +0000849 clk->usecount++;
Vitaly Woole9931b52006-06-22 10:26:20 +0100850 }
851out:
852 return ret;
853}
854
Vitaly Wool78818e42006-05-16 11:54:37 +0100855static int local_set_rate(struct clk *clk, u32 rate)
856{
857 int ret = -EINVAL;
858 if (clk->set_rate) {
859
860 if (clk->user_rate == clk->rate && clk->parent->rate) {
861 /* if clock enabled or rate not set */
862 clk->user_rate = clk->round_rate(clk, rate);
863 ret = clk->set_rate(clk, clk->user_rate);
864 } else
865 clk->user_rate = clk->round_rate(clk, rate);
866 ret = 0;
867 }
868 return ret;
869}
870
871int clk_set_rate(struct clk *clk, unsigned long rate)
872{
873 int ret = -EINVAL;
874
875 if (clk->flags & FIXED_RATE)
876 goto out;
877
878 clock_lock();
879 if ((clk->flags & PARENT_SET_RATE) && clk->parent) {
880
881 clk->user_rate = clk->round_rate(clk, rate);
882 /* parent clock needs to be refreshed
883 for the setting to take effect */
884 } else {
885 ret = local_set_rate(clk, rate);
886 }
887 ret = 0;
888 clock_unlock();
889
890out:
891 return ret;
892}
893
894EXPORT_SYMBOL(clk_set_rate);
895
Vitaly Wool78818e42006-05-16 11:54:37 +0100896unsigned long clk_get_rate(struct clk *clk)
897{
898 unsigned long ret;
899 clock_lock();
900 ret = clk->rate;
901 clock_unlock();
902 return ret;
903}
904EXPORT_SYMBOL(clk_get_rate);
905
Vitaly Wool78818e42006-05-16 11:54:37 +0100906int clk_enable(struct clk *clk)
907{
Russell King5413f742009-11-20 11:25:44 +0000908 int ret;
Vitaly Wool78818e42006-05-16 11:54:37 +0100909
910 clock_lock();
Russell King5413f742009-11-20 11:25:44 +0000911 ret = local_clk_enable(clk);
Vitaly Wool78818e42006-05-16 11:54:37 +0100912 clock_unlock();
913 return ret;
914}
915
916EXPORT_SYMBOL(clk_enable);
917
918void clk_disable(struct clk *clk)
919{
920 clock_lock();
Russell King5413f742009-11-20 11:25:44 +0000921 local_clk_disable(clk);
Vitaly Wool78818e42006-05-16 11:54:37 +0100922 clock_unlock();
923}
924
Vitaly Woole9931b52006-06-22 10:26:20 +0100925EXPORT_SYMBOL(clk_disable);
Vitaly Wool78818e42006-05-16 11:54:37 +0100926
927long clk_round_rate(struct clk *clk, unsigned long rate)
928{
929 long ret;
930 clock_lock();
931 if (clk->round_rate)
932 ret = clk->round_rate(clk, rate);
933 else
934 ret = clk->rate;
935 clock_unlock();
936 return ret;
937}
938
939EXPORT_SYMBOL(clk_round_rate);
940
941int clk_set_parent(struct clk *clk, struct clk *parent)
942{
943 int ret = -ENODEV;
944 if (!clk->set_parent)
945 goto out;
946
947 clock_lock();
948 ret = clk->set_parent(clk, parent);
949 if (!ret)
950 clk->parent = parent;
951 clock_unlock();
952
953out:
954 return ret;
955}
956
957EXPORT_SYMBOL(clk_set_parent);
958
959static int __init clk_init(void)
960{
961 struct clk **clkp;
962
963 /* Disable autoclocking, as it doesn't seem to work */
964 __raw_writel(0xff, AUTOCLK_CTRL);
965
966 for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
967 clkp++) {
Russell King0c452df2009-11-20 11:28:59 +0000968 struct clk *clk = *clkp;
969 if (clk->flags & NEEDS_INITIALIZATION) {
970 if (clk->set_rate) {
971 clk->user_rate = clk->rate;
972 local_set_rate(clk, clk->user_rate);
973 if (clk->set_parent)
974 clk->set_parent(clk, clk->parent);
975 }
976 if (clk->enable && clk->usecount)
977 clk->enable(clk);
978 if (clk->disable && !clk->usecount)
979 clk->disable(clk);
Vitaly Wool78818e42006-05-16 11:54:37 +0100980 }
981 pr_debug("%s: clock %s, rate %ld\n",
Russell King0c452df2009-11-20 11:28:59 +0000982 __func__, clk->name, clk->rate);
Vitaly Wool78818e42006-05-16 11:54:37 +0100983 }
984
Russell King5413f742009-11-20 11:25:44 +0000985 local_clk_enable(&ck_pll4);
Vitaly Wool78818e42006-05-16 11:54:37 +0100986
987 /* if ck_13MHz is not used, disable it. */
988 if (ck_13MHz.usecount == 0)
989 local_clk_disable(&ck_13MHz);
990
991 /* Disable autoclocking */
992 __raw_writeb(0xff, AUTOCLK_CTRL);
993
Russell King6985a5a2009-11-20 10:32:41 +0000994 clkdev_add_table(onchip_clkreg, ARRAY_SIZE(onchip_clkreg));
995
Vitaly Wool78818e42006-05-16 11:54:37 +0100996 return 0;
997}
998
999arch_initcall(clk_init);