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