1
2
3
4
5
6
7
8
9
10
11#include <linux/module.h>
12#include <linux/kernel.h>
13#include <linux/list.h>
14#include <linux/errno.h>
15#include <linux/err.h>
16
17#include <asm/semaphore.h>
18#include <asm/hardware/clock.h>
19#include <asm/arch/board.h>
20
21#include "clock.h"
22
23static LIST_HEAD(clocks);
24static DECLARE_MUTEX(clocks_sem);
25static DEFINE_SPINLOCK(clockfw_lock);
26static void propagate_rate(struct clk * clk);
27
28static int select_table_rate(unsigned long rate);
29static long round_to_table_rate(unsigned long rate);
30void clk_setdpll(__u16, __u16);
31
32struct mpu_rate rate_table[] = {
33
34
35
36#if defined(CONFIG_OMAP_ARM_216MHZ) && defined(CONFIG_ARCH_OMAP16XX)
37 { 216000000, 12000000, 216000000, 0x050d, 0x2910 },
38#endif
39#if defined(CONFIG_OMAP_ARM_195MHZ) && defined(CONFIG_ARCH_OMAP730)
40 { 195000000, 13000000, 195000000, 0x050e, 0x2790 },
41#endif
42#if defined(CONFIG_OMAP_ARM_192MHZ) && defined(CONFIG_ARCH_OMAP16XX)
43 { 192000000, 19200000, 192000000, 0x050f, 0x2510 },
44 { 192000000, 12000000, 192000000, 0x050f, 0x2810 },
45 { 96000000, 12000000, 192000000, 0x055f, 0x2810 },
46 { 48000000, 12000000, 192000000, 0x0ccf, 0x2810 },
47 { 24000000, 12000000, 192000000, 0x0fff, 0x2810 },
48#endif
49#if defined(CONFIG_OMAP_ARM_182MHZ) && defined(CONFIG_ARCH_OMAP730)
50 { 182000000, 13000000, 182000000, 0x050e, 0x2710 },
51#endif
52#if defined(CONFIG_OMAP_ARM_168MHZ)
53 { 168000000, 12000000, 168000000, 0x010f, 0x2710 },
54#endif
55#if defined(CONFIG_OMAP_ARM_120MHZ)
56 { 120000000, 12000000, 120000000, 0x010a, 0x2510 },
57#endif
58#if defined(CONFIG_OMAP_ARM_96MHZ)
59 { 96000000, 12000000, 96000000, 0x0005, 0x2410 },
60#endif
61#if defined(CONFIG_OMAP_ARM_60MHZ)
62 { 60000000, 12000000, 60000000, 0x0005, 0x2290 },
63#endif
64#if defined(CONFIG_OMAP_ARM_30MHZ)
65 { 30000000, 12000000, 60000000, 0x0555, 0x2290 },
66#endif
67 { 0, 0, 0, 0, 0 },
68};
69
70
71static void ckctl_recalc(struct clk * clk)
72{
73 int dsor;
74
75
76 dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
77 if (unlikely(clk->rate == clk->parent->rate / dsor))
78 return;
79 clk->rate = clk->parent->rate / dsor;
80
81 if (unlikely(clk->flags & RATE_PROPAGATES))
82 propagate_rate(clk);
83}
84
85
86static void followparent_recalc(struct clk * clk)
87{
88 clk->rate = clk->parent->rate;
89}
90
91
92static void watchdog_recalc(struct clk * clk)
93{
94 clk->rate = clk->parent->rate / 14;
95}
96
97
98static struct clk ck_ref = {
99 .name = "ck_ref",
100 .rate = 12000000,
101 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
102 ALWAYS_ENABLED,
103};
104
105static struct clk ck_dpll1 = {
106 .name = "ck_dpll1",
107 .parent = &ck_ref,
108 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
109 RATE_PROPAGATES | ALWAYS_ENABLED,
110};
111
112static struct clk ck_dpll1out = {
113 .name = "ck_dpll1out",
114 .parent = &ck_dpll1,
115 .flags = CLOCK_IN_OMAP16XX,
116 .enable_reg = ARM_IDLECT2,
117 .enable_bit = EN_CKOUT_ARM,
118 .recalc = &followparent_recalc,
119};
120
121static struct clk arm_ck = {
122 .name = "arm_ck",
123 .parent = &ck_dpll1,
124 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
125 RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
126 .rate_offset = CKCTL_ARMDIV_OFFSET,
127 .recalc = &ckctl_recalc,
128};
129
130static struct clk armper_ck = {
131 .name = "armper_ck",
132 .parent = &ck_dpll1,
133 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
134 RATE_CKCTL,
135 .enable_reg = ARM_IDLECT2,
136 .enable_bit = EN_PERCK,
137 .rate_offset = CKCTL_PERDIV_OFFSET,
138 .recalc = &ckctl_recalc,
139};
140
141static struct clk arm_gpio_ck = {
142 .name = "arm_gpio_ck",
143 .parent = &ck_dpll1,
144 .flags = CLOCK_IN_OMAP1510,
145 .enable_reg = ARM_IDLECT2,
146 .enable_bit = EN_GPIOCK,
147 .recalc = &followparent_recalc,
148};
149
150static struct clk armxor_ck = {
151 .name = "armxor_ck",
152 .parent = &ck_ref,
153 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
154 .enable_reg = ARM_IDLECT2,
155 .enable_bit = EN_XORPCK,
156 .recalc = &followparent_recalc,
157};
158
159static struct clk armtim_ck = {
160 .name = "armtim_ck",
161 .parent = &ck_ref,
162 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
163 .enable_reg = ARM_IDLECT2,
164 .enable_bit = EN_TIMCK,
165 .recalc = &followparent_recalc,
166};
167
168static struct clk armwdt_ck = {
169 .name = "armwdt_ck",
170 .parent = &ck_ref,
171 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
172 .enable_reg = ARM_IDLECT2,
173 .enable_bit = EN_WDTCK,
174 .recalc = &watchdog_recalc,
175};
176
177static struct clk arminth_ck1610 = {
178 .name = "arminth_ck",
179 .parent = &arm_ck,
180 .flags = CLOCK_IN_OMAP16XX,
181 .recalc = &followparent_recalc,
182
183
184
185
186
187};
188
189static struct clk dsp_ck = {
190 .name = "dsp_ck",
191 .parent = &ck_dpll1,
192 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
193 RATE_CKCTL,
194 .enable_reg = ARM_CKCTL,
195 .enable_bit = EN_DSPCK,
196 .rate_offset = CKCTL_DSPDIV_OFFSET,
197 .recalc = &ckctl_recalc,
198};
199
200static struct clk dspmmu_ck = {
201 .name = "dspmmu_ck",
202 .parent = &ck_dpll1,
203 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
204 RATE_CKCTL | ALWAYS_ENABLED,
205 .rate_offset = CKCTL_DSPMMUDIV_OFFSET,
206 .recalc = &ckctl_recalc,
207};
208
209static struct clk tc_ck = {
210 .name = "tc_ck",
211 .parent = &ck_dpll1,
212 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
213 RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
214 .rate_offset = CKCTL_TCDIV_OFFSET,
215 .recalc = &ckctl_recalc,
216};
217
218static struct clk arminth_ck1510 = {
219 .name = "arminth_ck",
220 .parent = &tc_ck,
221 .flags = CLOCK_IN_OMAP1510,
222 .recalc = &followparent_recalc,
223
224
225
226
227};
228
229static struct clk tipb_ck = {
230 .name = "tibp_ck",
231 .parent = &tc_ck,
232 .flags = CLOCK_IN_OMAP1510,
233 .recalc = &followparent_recalc,
234};
235
236static struct clk l3_ocpi_ck = {
237 .name = "l3_ocpi_ck",
238 .parent = &tc_ck,
239 .flags = CLOCK_IN_OMAP16XX,
240 .enable_reg = ARM_IDLECT3,
241 .enable_bit = EN_OCPI_CK,
242 .recalc = &followparent_recalc,
243};
244
245static struct clk tc1_ck = {
246 .name = "tc1_ck",
247 .parent = &tc_ck,
248 .flags = CLOCK_IN_OMAP16XX,
249 .enable_reg = ARM_IDLECT3,
250 .enable_bit = EN_TC1_CK,
251 .recalc = &followparent_recalc,
252};
253
254static struct clk tc2_ck = {
255 .name = "tc2_ck",
256 .parent = &tc_ck,
257 .flags = CLOCK_IN_OMAP16XX,
258 .enable_reg = ARM_IDLECT3,
259 .enable_bit = EN_TC2_CK,
260 .recalc = &followparent_recalc,
261};
262
263static struct clk dma_ck = {
264 .name = "dma_ck",
265 .parent = &tc_ck,
266 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
267 .recalc = &followparent_recalc,
268};
269
270static struct clk dma_lcdfree_ck = {
271 .name = "dma_lcdfree_ck",
272 .parent = &tc_ck,
273 .flags = CLOCK_IN_OMAP16XX,
274 .recalc = &followparent_recalc,
275};
276
277static struct clk api_ck = {
278 .name = "api_ck",
279 .parent = &tc_ck,
280 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
281 .enable_reg = ARM_IDLECT2,
282 .enable_bit = EN_APICK,
283 .recalc = &followparent_recalc,
284};
285
286static struct clk lb_ck = {
287 .name = "lb_ck",
288 .parent = &tc_ck,
289 .flags = CLOCK_IN_OMAP1510,
290 .enable_reg = ARM_IDLECT2,
291 .enable_bit = EN_LBCK,
292 .recalc = &followparent_recalc,
293};
294
295static struct clk rhea1_ck = {
296 .name = "rhea1_ck",
297 .parent = &tc_ck,
298 .flags = CLOCK_IN_OMAP16XX,
299 .recalc = &followparent_recalc,
300};
301
302static struct clk rhea2_ck = {
303 .name = "rhea2_ck",
304 .parent = &tc_ck,
305 .flags = CLOCK_IN_OMAP16XX,
306 .recalc = &followparent_recalc,
307};
308
309static struct clk lcd_ck = {
310 .name = "lcd_ck",
311 .parent = &ck_dpll1,
312 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
313 RATE_CKCTL,
314 .enable_reg = ARM_IDLECT2,
315 .enable_bit = EN_LCDCK,
316 .rate_offset = CKCTL_LCDDIV_OFFSET,
317 .recalc = &ckctl_recalc,
318};
319
320static struct clk uart1_ck = {
321 .name = "uart1_ck",
322
323 .rate = 48000000,
324 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
325 RATE_FIXED | ENABLE_REG_32BIT,
326 .enable_reg = MOD_CONF_CTRL_0,
327 .enable_bit = 29,
328
329
330
331};
332
333static struct clk uart2_ck = {
334 .name = "uart2_ck",
335
336 .rate = 48000000,
337 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
338 RATE_FIXED | ENABLE_REG_32BIT,
339 .enable_reg = MOD_CONF_CTRL_0,
340 .enable_bit = 30,
341
342
343
344};
345
346static struct clk uart3_ck = {
347 .name = "uart3_ck",
348
349 .rate = 48000000,
350 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
351 RATE_FIXED | ENABLE_REG_32BIT,
352 .enable_reg = MOD_CONF_CTRL_0,
353 .enable_bit = 31,
354
355
356
357};
358
359static struct clk usb_ck1610 = {
360 .name = "usb_ck",
361
362 .rate = 48000000,
363 .flags = CLOCK_IN_OMAP16XX |
364 RATE_FIXED | ENABLE_REG_32BIT,
365 .enable_reg = ULPD_CLOCK_CTRL,
366 .enable_bit = USB_MCLK_EN,
367};
368
369static struct clk usb_ck1510 = {
370 .name = "usb_ck",
371
372 .rate = 48000000,
373 .flags = CLOCK_IN_OMAP1510 | RATE_FIXED,
374};
375
376static struct clk usb_hhc_ck = {
377 .name = "usb_hhc_ck",
378
379 .rate = 48000000,
380 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
381 RATE_FIXED | ENABLE_REG_32BIT,
382 .enable_reg = MOD_CONF_CTRL_0,
383 .enable_bit = USB_HOST_HHC_UHOST_EN,
384};
385
386
387
388
389
390
391
392
393
394
395
396static struct clk mmc1_ck = {
397 .name = "mmc1_ck",
398
399 .parent = &armper_ck,
400 .rate = 48000000,
401 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
402 RATE_FIXED | ENABLE_REG_32BIT,
403 .enable_reg = MOD_CONF_CTRL_0,
404 .enable_bit = 23,
405};
406
407static struct clk mmc2_ck = {
408 .name = "mmc2_ck",
409
410 .parent = &armper_ck,
411 .rate = 48000000,
412 .flags = CLOCK_IN_OMAP16XX |
413 RATE_FIXED | ENABLE_REG_32BIT,
414 .enable_reg = MOD_CONF_CTRL_0,
415 .enable_bit = 20,
416};
417
418static struct clk virtual_ck_mpu = {
419 .name = "mpu",
420 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
421 VIRTUAL_CLOCK | ALWAYS_ENABLED,
422 .parent = &arm_ck,
423 .recalc = &followparent_recalc,
424 .set_rate = &select_table_rate,
425 .round_rate = &round_to_table_rate,
426};
427
428
429static struct clk * onchip_clks[] = {
430
431 &ck_ref,
432 &ck_dpll1,
433
434 &ck_dpll1out,
435 &arm_ck,
436 &armper_ck,
437 &arm_gpio_ck,
438 &armxor_ck,
439 &armtim_ck,
440 &armwdt_ck,
441 &arminth_ck1510,
442 &arminth_ck1610,
443
444 &dsp_ck,
445 &dspmmu_ck,
446
447 &tc_ck,
448 &tipb_ck,
449 &l3_ocpi_ck,
450 &tc1_ck,
451 &tc2_ck,
452 &dma_ck,
453 &dma_lcdfree_ck,
454 &api_ck,
455 &lb_ck,
456 &rhea1_ck,
457 &rhea2_ck,
458 &lcd_ck,
459
460 &uart1_ck,
461 &uart2_ck,
462 &uart3_ck,
463 &usb_ck1510,
464 &usb_ck1610,
465 &usb_hhc_ck,
466
467
468
469
470 &mmc1_ck,
471 &mmc2_ck,
472
473 &virtual_ck_mpu,
474};
475
476struct clk *clk_get(struct device *dev, const char *id)
477{
478 struct clk *p, *clk = ERR_PTR(-ENOENT);
479
480 down(&clocks_sem);
481 list_for_each_entry(p, &clocks, node) {
482 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
483 clk = p;
484 break;
485 }
486 }
487 up(&clocks_sem);
488
489 return clk;
490}
491EXPORT_SYMBOL(clk_get);
492
493
494void clk_put(struct clk *clk)
495{
496 if (clk && !IS_ERR(clk))
497 module_put(clk->owner);
498}
499EXPORT_SYMBOL(clk_put);
500
501
502int __clk_enable(struct clk *clk)
503{
504 __u16 regval16;
505 __u32 regval32;
506
507 if (clk->flags & ALWAYS_ENABLED)
508 return 0;
509
510 if (unlikely(clk->enable_reg == 0)) {
511 printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
512 clk->name);
513 return 0;
514 }
515
516 if (clk->flags & ENABLE_REG_32BIT) {
517 regval32 = omap_readl(clk->enable_reg);
518 regval32 |= (1 << clk->enable_bit);
519 omap_writel(regval32, clk->enable_reg);
520 } else {
521 regval16 = omap_readw(clk->enable_reg);
522 regval16 |= (1 << clk->enable_bit);
523 omap_writew(regval16, clk->enable_reg);
524 }
525
526 return 0;
527}
528
529
530void __clk_disable(struct clk *clk)
531{
532 __u16 regval16;
533 __u32 regval32;
534
535 if (clk->enable_reg == 0)
536 return;
537
538 if (clk->flags & ENABLE_REG_32BIT) {
539 regval32 = omap_readl(clk->enable_reg);
540 regval32 &= ~(1 << clk->enable_bit);
541 omap_writel(regval32, clk->enable_reg);
542 } else {
543 regval16 = omap_readw(clk->enable_reg);
544 regval16 &= ~(1 << clk->enable_bit);
545 omap_writew(regval16, clk->enable_reg);
546 }
547}
548
549
550void __clk_unuse(struct clk *clk)
551{
552 if (clk->usecount > 0 && !(--clk->usecount)) {
553 __clk_disable(clk);
554 if (likely(clk->parent))
555 __clk_unuse(clk->parent);
556 }
557}
558
559
560int __clk_use(struct clk *clk)
561{
562 int ret = 0;
563 if (clk->usecount++ == 0) {
564 if (likely(clk->parent))
565 ret = __clk_use(clk->parent);
566
567 if (unlikely(ret != 0)) {
568 clk->usecount--;
569 return ret;
570 }
571
572 ret = __clk_enable(clk);
573
574 if (unlikely(ret != 0) && clk->parent) {
575 __clk_unuse(clk->parent);
576 clk->usecount--;
577 }
578 }
579
580 return ret;
581}
582
583
584int clk_enable(struct clk *clk)
585{
586 unsigned long flags;
587 int ret;
588
589 spin_lock_irqsave(&clockfw_lock, flags);
590 ret = __clk_enable(clk);
591 spin_unlock_irqrestore(&clockfw_lock, flags);
592 return ret;
593}
594EXPORT_SYMBOL(clk_enable);
595
596
597void clk_disable(struct clk *clk)
598{
599 unsigned long flags;
600
601 spin_lock_irqsave(&clockfw_lock, flags);
602 __clk_disable(clk);
603 spin_unlock_irqrestore(&clockfw_lock, flags);
604}
605EXPORT_SYMBOL(clk_disable);
606
607
608int clk_use(struct clk *clk)
609{
610 unsigned long flags;
611 int ret = 0;
612
613 spin_lock_irqsave(&clockfw_lock, flags);
614 ret = __clk_use(clk);
615 spin_unlock_irqrestore(&clockfw_lock, flags);
616 return ret;
617}
618EXPORT_SYMBOL(clk_use);
619
620
621void clk_unuse(struct clk *clk)
622{
623 unsigned long flags;
624
625 spin_lock_irqsave(&clockfw_lock, flags);
626 __clk_unuse(clk);
627 spin_unlock_irqrestore(&clockfw_lock, flags);
628}
629EXPORT_SYMBOL(clk_unuse);
630
631
632unsigned long clk_get_rate(struct clk *clk)
633{
634 return clk->rate;
635}
636EXPORT_SYMBOL(clk_get_rate);
637
638
639static __u16 verify_ckctl_value(__u16 newval)
640{
641
642
643
644
645
646
647
648
649
650
651
652
653
654 __u8 per_exp;
655 __u8 lcd_exp;
656 __u8 arm_exp;
657 __u8 dsp_exp;
658 __u8 tc_exp;
659 __u8 dspmmu_exp;
660
661 per_exp = (newval >> CKCTL_PERDIV_OFFSET) & 3;
662 lcd_exp = (newval >> CKCTL_LCDDIV_OFFSET) & 3;
663 arm_exp = (newval >> CKCTL_ARMDIV_OFFSET) & 3;
664 dsp_exp = (newval >> CKCTL_DSPDIV_OFFSET) & 3;
665 tc_exp = (newval >> CKCTL_TCDIV_OFFSET) & 3;
666 dspmmu_exp = (newval >> CKCTL_DSPMMUDIV_OFFSET) & 3;
667
668 if (dspmmu_exp < dsp_exp)
669 dspmmu_exp = dsp_exp;
670 if (dspmmu_exp > dsp_exp+1)
671 dspmmu_exp = dsp_exp+1;
672 if (tc_exp < arm_exp)
673 tc_exp = arm_exp;
674 if (tc_exp < dspmmu_exp)
675 tc_exp = dspmmu_exp;
676 if (tc_exp > lcd_exp)
677 lcd_exp = tc_exp;
678 if (tc_exp > per_exp)
679 per_exp = tc_exp;
680
681 newval &= 0xf000;
682 newval |= per_exp << CKCTL_PERDIV_OFFSET;
683 newval |= lcd_exp << CKCTL_LCDDIV_OFFSET;
684 newval |= arm_exp << CKCTL_ARMDIV_OFFSET;
685 newval |= dsp_exp << CKCTL_DSPDIV_OFFSET;
686 newval |= tc_exp << CKCTL_TCDIV_OFFSET;
687 newval |= dspmmu_exp << CKCTL_DSPMMUDIV_OFFSET;
688
689 return newval;
690}
691
692
693static int calc_dsor_exp(struct clk *clk, unsigned long rate)
694{
695
696
697
698
699
700
701
702
703
704
705
706 unsigned long realrate;
707 struct clk * parent;
708 unsigned dsor_exp;
709
710 if (unlikely(!(clk->flags & RATE_CKCTL)))
711 return -EINVAL;
712
713 parent = clk->parent;
714 if (unlikely(parent == 0))
715 return -EIO;
716
717 realrate = parent->rate;
718 for (dsor_exp=0; dsor_exp<4; dsor_exp++) {
719 if (realrate <= rate)
720 break;
721
722 realrate /= 2;
723 }
724
725 return dsor_exp;
726}
727
728long clk_round_rate(struct clk *clk, unsigned long rate)
729{
730 int dsor_exp;
731
732 if (clk->flags & RATE_FIXED)
733 return clk->rate;
734
735 if (clk->flags & RATE_CKCTL) {
736 dsor_exp = calc_dsor_exp(clk, rate);
737 if (dsor_exp < 0)
738 return dsor_exp;
739 if (dsor_exp > 3)
740 dsor_exp = 3;
741 return clk->parent->rate / (1 << dsor_exp);
742 }
743
744 if(clk->round_rate != 0)
745 return clk->round_rate(rate);
746
747 return clk->rate;
748}
749EXPORT_SYMBOL(clk_round_rate);
750
751
752static void propagate_rate(struct clk * clk)
753{
754 struct clk ** clkp;
755
756 for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {
757 if (likely((*clkp)->parent != clk)) continue;
758 if (likely((*clkp)->recalc))
759 (*clkp)->recalc(*clkp);
760 }
761}
762
763
764static int select_table_rate(unsigned long rate)
765{
766
767 struct mpu_rate * ptr;
768
769 for (ptr = rate_table; ptr->rate; ptr++) {
770 if (ptr->xtal != ck_ref.rate)
771 continue;
772
773
774 if (likely(ck_dpll1.rate!=0) && ptr->pll_rate != ck_dpll1.rate)
775 continue;
776
777
778 if (ptr->rate <= rate)
779 break;
780 }
781
782 if (!ptr->rate)
783 return -EINVAL;
784
785 if (unlikely(ck_dpll1.rate == 0)) {
786 omap_writew(ptr->dpllctl_val, DPLL_CTL);
787 ck_dpll1.rate = ptr->pll_rate;
788 }
789 omap_writew(ptr->ckctl_val, ARM_CKCTL);
790 propagate_rate(&ck_dpll1);
791 return 0;
792}
793
794
795static long round_to_table_rate(unsigned long rate)
796{
797
798 struct mpu_rate * ptr;
799 long highest_rate;
800
801 highest_rate = -EINVAL;
802
803 for (ptr = rate_table; ptr->rate; ptr++) {
804 if (ptr->xtal != ck_ref.rate)
805 continue;
806
807 highest_rate = ptr->rate;
808
809
810 if (ptr->rate <= rate)
811 break;
812 }
813
814 return highest_rate;
815}
816
817
818int clk_set_rate(struct clk *clk, unsigned long rate)
819{
820 int ret = -EINVAL;
821 int dsor_exp;
822 __u16 regval;
823 unsigned long flags;
824
825 if (clk->flags & RATE_CKCTL) {
826 dsor_exp = calc_dsor_exp(clk, rate);
827 if (dsor_exp > 3)
828 dsor_exp = -EINVAL;
829 if (dsor_exp < 0)
830 return dsor_exp;
831
832 spin_lock_irqsave(&clockfw_lock, flags);
833 regval = omap_readw(ARM_CKCTL);
834 regval &= ~(3 << clk->rate_offset);
835 regval |= dsor_exp << clk->rate_offset;
836 regval = verify_ckctl_value(regval);
837 omap_writew(regval, ARM_CKCTL);
838 clk->rate = clk->parent->rate / (1 << dsor_exp);
839 spin_unlock_irqrestore(&clockfw_lock, flags);
840 ret = 0;
841 } else if(clk->set_rate != 0) {
842 spin_lock_irqsave(&clockfw_lock, flags);
843 ret = clk->set_rate(rate);
844 spin_unlock_irqrestore(&clockfw_lock, flags);
845 }
846
847 if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
848 propagate_rate(clk);
849
850 return ret;
851}
852EXPORT_SYMBOL(clk_set_rate);
853
854
855int clk_register(struct clk *clk)
856{
857 down(&clocks_sem);
858 list_add(&clk->node, &clocks);
859 up(&clocks_sem);
860 return 0;
861}
862EXPORT_SYMBOL(clk_register);
863
864void clk_unregister(struct clk *clk)
865{
866 down(&clocks_sem);
867 list_del(&clk->node);
868 up(&clocks_sem);
869}
870EXPORT_SYMBOL(clk_unregister);
871
872
873
874int __init clk_init(void)
875{
876 struct clk ** clkp;
877 const struct omap_clock_config *info;
878 int crystal_type = 0;
879
880 for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {
881 if (((*clkp)->flags &CLOCK_IN_OMAP1510) && cpu_is_omap1510()) {
882 clk_register(*clkp);
883 continue;
884 }
885
886 if (((*clkp)->flags &CLOCK_IN_OMAP16XX) && cpu_is_omap16xx()) {
887 clk_register(*clkp);
888 continue;
889 }
890 }
891
892 info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
893 if (info != NULL) {
894 if (!cpu_is_omap1510())
895 crystal_type = info->system_clock_type;
896 }
897
898#if defined(CONFIG_ARCH_OMAP730)
899 ck_ref.rate = 13000000;
900#elif defined(CONFIG_ARCH_OMAP16XX)
901 if (crystal_type == 2)
902 ck_ref.rate = 19200000;
903#endif
904
905
906 omap_writew(0x1000, ARM_SYSST);
907
908
909 if (select_table_rate(~0)) {
910 printk(KERN_ERR "System frequencies not set. Check your config.\n");
911
912 omap_writew(0x2290, DPLL_CTL);
913 omap_writew(0x1005, ARM_CKCTL);
914 ck_dpll1.rate = 60000000;
915 propagate_rate(&ck_dpll1);
916 printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): %ld/%ld/%ld\n",
917 ck_ref.rate, ck_dpll1.rate, arm_ck.rate);
918 }
919
920
921 propagate_rate(&ck_ref);
922
923#ifdef CONFIG_MACH_OMAP_PERSEUS2
924
925 omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);
926#endif
927
928
929 omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL);
930
931
932 omap_writew(0, ARM_RSTCT1);
933 omap_writew(1, ARM_RSTCT2);
934 omap_writew(0x400, ARM_IDLECT1);
935
936
937
938
939
940
941 omap_writew(0x0000, ARM_IDLECT2);
942
943
944
945
946
947 clk_use(&armper_ck);
948 clk_use(&armxor_ck);
949 clk_use(&armtim_ck);
950
951 if (cpu_is_omap1510())
952 clk_enable(&arm_gpio_ck);
953
954 return 0;
955}
956