]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/mach-omap2/clock.c
302d5a796340c2ab9acf4fa32b19aee3bbc4d8a1
[linux-2.6-omap-h63xx.git] / arch / arm / mach-omap2 / clock.c
1 /*
2  *  linux/arch/arm/mach-omap2/clock.c
3  *
4  *  Copyright (C) 2005 Texas Instruments Inc.
5  *  Richard Woodruff <r-woodruff2@ti.com>
6  *  Created for OMAP2.
7  *
8  *  Cleaned up and modified to use omap shared clock framework by
9  *  Tony Lindgren <tony@atomide.com>
10  *
11  *  Based on omap1 clock.c, Copyright (C) 2004 - 2005 Nokia corporation
12  *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License version 2 as
16  * published by the Free Software Foundation.
17  */
18 #include <linux/module.h>
19 #include <linux/kernel.h>
20 #include <linux/device.h>
21 #include <linux/list.h>
22 #include <linux/errno.h>
23 #include <linux/delay.h>
24 #include <linux/clk.h>
25
26 #include <asm/io.h>
27
28 #include <asm/arch/clock.h>
29 #include <asm/arch/sram.h>
30
31 #include "prcm-regs.h"
32 #include "memory.h"
33 #include "clock.h"
34
35 //#define DOWN_VARIABLE_DPLL 1                  /* Experimental */
36
37 static struct prcm_config *curr_prcm_set;
38 static u32 curr_perf_level = PRCM_FULL_SPEED;
39 static struct clk *vclk;
40 static struct clk *sclk;
41
42 /*-------------------------------------------------------------------------
43  * Omap2 specific clock functions
44  *-------------------------------------------------------------------------*/
45
46 /* Recalculate SYST_CLK */
47 static void omap2_sys_clk_recalc(struct clk * clk)
48 {
49         u32 div = PRCM_CLKSRC_CTRL;
50         div &= (1 << 7) | (1 << 6);     /* Test if ext clk divided by 1 or 2 */
51         div >>= clk->rate_offset;
52         clk->rate = (clk->parent->rate / div);
53         propagate_rate(clk);
54 }
55
56 static u32 omap2_get_dpll_rate(struct clk * tclk)
57 {
58         long long dpll_clk;
59         int dpll_mult, dpll_div, amult;
60
61         dpll_mult = (CM_CLKSEL1_PLL >> 12) & 0x03ff;    /* 10 bits */
62         dpll_div = (CM_CLKSEL1_PLL >> 8) & 0x0f;        /* 4 bits */
63         dpll_clk = (long long)tclk->parent->rate * dpll_mult;
64         do_div(dpll_clk, dpll_div + 1);
65         amult = CM_CLKSEL2_PLL & 0x3;
66         dpll_clk *= amult;
67
68         return dpll_clk;
69 }
70
71 static void omap2_followparent_recalc(struct clk *clk)
72 {
73         followparent_recalc(clk);
74 }
75
76 static void omap2_propagate_rate(struct clk * clk)
77 {
78         if (!(clk->flags & RATE_FIXED))
79                 clk->rate = clk->parent->rate;
80
81         propagate_rate(clk);
82 }
83
84 /* Enable an APLL if off */
85 static void omap2_clk_fixed_enable(struct clk *clk)
86 {
87         u32 cval, i=0;
88
89         if (clk->enable_bit == 0xff)                    /* Parent will do it */
90                 return;
91
92         cval = CM_CLKEN_PLL;
93
94         if ((cval & (0x3 << clk->enable_bit)) == (0x3 << clk->enable_bit))
95                 return;
96
97         cval &= ~(0x3 << clk->enable_bit);
98         cval |= (0x3 << clk->enable_bit);
99         CM_CLKEN_PLL = cval;
100
101         if (clk == &apll96_ck)
102                 cval = (1 << 8);
103         else if (clk == &apll54_ck)
104                 cval = (1 << 6);
105
106         while (!(CM_IDLEST_CKGEN & cval)) {             /* Wait for lock */
107                 ++i;
108                 udelay(1);
109                 if (i == 100000)
110                         break;
111         }
112 }
113
114 /* Enables clock without considering parent dependencies or use count
115  * REVISIT: Maybe change this to use clk->enable like on omap1?
116  */
117 static int _omap2_clk_enable(struct clk * clk)
118 {
119         u32 regval32;
120
121         if (clk->flags & ALWAYS_ENABLED)
122                 return 0;
123
124         if (unlikely(clk->enable_reg == 0)) {
125                 printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
126                        clk->name);
127                 return 0;
128         }
129
130         if (clk->enable_reg == (void __iomem *)&CM_CLKEN_PLL) {
131                 omap2_clk_fixed_enable(clk);
132                 return 0;
133         }
134
135         regval32 = __raw_readl(clk->enable_reg);
136         regval32 |= (1 << clk->enable_bit);
137         __raw_writel(regval32, clk->enable_reg);
138         wmb();
139
140         return 0;
141 }
142
143 /* Stop APLL */
144 static void omap2_clk_fixed_disable(struct clk *clk)
145 {
146         u32 cval;
147
148         if(clk->enable_bit == 0xff)             /* let parent off do it */
149                 return;
150
151         cval = CM_CLKEN_PLL;
152         cval &= ~(0x3 << clk->enable_bit);
153         CM_CLKEN_PLL = cval;
154 }
155
156 /* Disables clock without considering parent dependencies or use count */
157 static void _omap2_clk_disable(struct clk *clk)
158 {
159         u32 regval32;
160
161         if (clk->enable_reg == 0)
162                 return;
163
164         if (clk->enable_reg == (void __iomem *)&CM_CLKEN_PLL) {
165                 omap2_clk_fixed_disable(clk);
166                 return;
167         }
168
169         regval32 = __raw_readl(clk->enable_reg);
170         regval32 &= ~(1 << clk->enable_bit);
171         __raw_writel(regval32, clk->enable_reg);
172         wmb();
173 }
174
175 static int omap2_clk_enable(struct clk *clk)
176 {
177         int ret = 0;
178
179         if (clk->usecount++ == 0) {
180                 if (likely((u32)clk->parent))
181                         ret = omap2_clk_enable(clk->parent);
182
183                 if (unlikely(ret != 0)) {
184                         clk->usecount--;
185                         return ret;
186                 }
187
188                 ret = _omap2_clk_enable(clk);
189
190                 if (unlikely(ret != 0) && clk->parent) {
191                         omap2_clk_disable(clk->parent);
192                         clk->usecount--;
193                 }
194         }
195
196         return ret;
197 }
198
199 static void omap2_clk_disable(struct clk *clk)
200 {
201         if (clk->usecount > 0 && !(--clk->usecount)) {
202                 _omap2_clk_disable(clk);
203                 if (likely((u32)clk->parent))
204                         omap2_clk_disable(clk->parent);
205         }
206 }
207
208 /*
209  * Uses the current prcm set to tell if a rate is valid.
210  * You can go slower, but not faster within a given rate set.
211  */
212 static u32 omap2_dpll_round_rate(unsigned long target_rate)
213 {
214         u32 high, low;
215
216         if ((CM_CLKSEL2_PLL & 0x3) == 1) {      /* DPLL clockout */
217                 high = curr_prcm_set->dpll_speed * 2;
218                 low = curr_prcm_set->dpll_speed;
219         } else {                                /* DPLL clockout x 2 */
220                 high = curr_prcm_set->dpll_speed;
221                 low = curr_prcm_set->dpll_speed / 2;
222         }
223
224 #ifdef DOWN_VARIABLE_DPLL
225         if (target_rate > high)
226                 return high;
227         else
228                 return target_rate;
229 #else
230         if (target_rate > low)
231                 return high;
232         else
233                 return low;
234 #endif
235
236 }
237
238 /*
239  * Used for clocks that are part of CLKSEL_xyz governed clocks.
240  * REVISIT: Maybe change to use clk->enable() functions like on omap1?
241  */
242 static void omap2_clksel_recalc(struct clk * clk)
243 {
244         u32 fixed = 0, div = 0;
245
246         if (clk == &dpll_ck) {
247                 clk->rate = omap2_get_dpll_rate(clk);
248                 fixed = 1;
249                 div = 0;
250         }
251
252         if (clk == &iva1_mpu_int_ifck) {
253                 div = 2;
254                 fixed = 1;
255         }
256
257         if ((clk == &dss1_fck) && ((CM_CLKSEL1_CORE & (0x1f << 8)) == 0)) {
258                 clk->rate = sys_ck.rate;
259                 return;
260         }
261
262         if (!fixed) {
263                 div = omap2_clksel_get_divisor(clk);
264                 if (div == 0)
265                         return;
266         }
267
268         if (div != 0) {
269                 if (unlikely(clk->rate == clk->parent->rate / div))
270                         return;
271                 clk->rate = clk->parent->rate / div;
272         }
273
274         if (unlikely(clk->flags & RATE_PROPAGATES))
275                 propagate_rate(clk);
276 }
277
278 /*
279  * Finds best divider value in an array based on the source and target
280  * rates. The divider array must be sorted with smallest divider first.
281  */
282 static inline u32 omap2_divider_from_table(u32 size, u32 *div_array,
283                                            u32 src_rate, u32 tgt_rate)
284 {
285         int i, test_rate;
286
287         if (div_array == NULL)
288                 return ~1;
289
290         for (i=0; i < size; i++) {
291                 test_rate = src_rate / *div_array;
292                 if (test_rate <= tgt_rate)
293                         return *div_array;
294                 ++div_array;
295         }
296
297         return ~0;      /* No acceptable divider */
298 }
299
300 /*
301  * Find divisor for the given clock and target rate.
302  *
303  * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT,
304  * they are only settable as part of virtual_prcm set.
305  */
306 static u32 omap2_clksel_round_rate(struct clk *tclk, u32 target_rate,
307         u32 *new_div)
308 {
309         u32 gfx_div[] = {2, 3, 4};
310         u32 sysclkout_div[] = {1, 2, 4, 8, 16};
311         u32 dss1_div[] = {1, 2, 3, 4, 5, 6, 8, 9, 12, 16};
312         u32 vylnq_div[] = {1, 2, 3, 4, 6, 8, 9, 12, 16, 18};
313         u32 best_div = ~0, asize = 0;
314         u32 *div_array = NULL;
315
316         switch (tclk->flags & SRC_RATE_SEL_MASK) {
317         case CM_GFX_SEL1:
318                 asize = 3;
319                 div_array = gfx_div;
320                 break;
321         case CM_PLL_SEL1:
322                 return omap2_dpll_round_rate(target_rate);
323         case CM_SYSCLKOUT_SEL1:
324                 asize = 5;
325                 div_array = sysclkout_div;
326                 break;
327         case CM_CORE_SEL1:
328                 if(tclk == &dss1_fck){
329                         if(tclk->parent == &core_ck){
330                                 asize = 10;
331                                 div_array = dss1_div;
332                         } else {
333                                 *new_div = 0; /* fixed clk */
334                                 return(tclk->parent->rate);
335                         }
336                 } else if((tclk == &vlynq_fck) && cpu_is_omap2420()){
337                         if(tclk->parent == &core_ck){
338                                 asize = 10;
339                                 div_array = vylnq_div;
340                         } else {
341                                 *new_div = 0; /* fixed clk */
342                                 return(tclk->parent->rate);
343                         }
344                 }
345                 break;
346         }
347
348         best_div = omap2_divider_from_table(asize, div_array,
349          tclk->parent->rate, target_rate);
350         if (best_div == ~0){
351                 *new_div = 1;
352                 return best_div; /* signal error */
353         }
354
355         *new_div = best_div;
356         return (tclk->parent->rate / best_div);
357 }
358
359 /* Given a clock and a rate apply a clock specific rounding function */
360 static long omap2_clk_round_rate(struct clk *clk, unsigned long rate)
361 {
362         u32 new_div = 0;
363         int valid_rate;
364
365         if (clk->flags & RATE_FIXED)
366                 return clk->rate;
367
368         if (clk->flags & RATE_CKCTL) {
369                 valid_rate = omap2_clksel_round_rate(clk, rate, &new_div);
370                 return valid_rate;
371         }
372
373         if (clk->round_rate != 0)
374                 return clk->round_rate(clk, rate);
375
376         return clk->rate;
377 }
378
379 /*
380  * Check the DLL lock state, and return tue if running in unlock mode.
381  * This is needed to compenste for the shifted DLL value in unlock mode.
382  */
383 static u32 omap2_dll_force_needed(void)
384 {
385         u32 dll_state = SDRC_DLLA_CTRL;         /* dlla and dllb are a set */
386
387         if ((dll_state & (1 << 2)) == (1 << 2))
388                 return 1;
389         else
390                 return 0;
391 }
392
393 static u32 omap2_reprogram_sdrc(u32 level, u32 force)
394 {
395         u32 slow_dll_ctrl, fast_dll_ctrl, m_type;
396         u32 prev = curr_perf_level, flags;
397
398         if ((curr_perf_level == level) && !force)
399                 return prev;
400
401         m_type = omap2_memory_get_type();
402         slow_dll_ctrl = omap2_memory_get_slow_dll_ctrl();
403         fast_dll_ctrl = omap2_memory_get_fast_dll_ctrl();
404
405         if (level == PRCM_HALF_SPEED) {
406                 local_irq_save(flags);
407                 PRCM_VOLTSETUP = 0xffff;
408                 omap2_sram_reprogram_sdrc(PRCM_HALF_SPEED,
409                                           slow_dll_ctrl, m_type);
410                 curr_perf_level = PRCM_HALF_SPEED;
411                 local_irq_restore(flags);
412         }
413         if (level == PRCM_FULL_SPEED) {
414                 local_irq_save(flags);
415                 PRCM_VOLTSETUP = 0xffff;
416                 omap2_sram_reprogram_sdrc(PRCM_FULL_SPEED,
417                                           fast_dll_ctrl, m_type);
418                 curr_perf_level = PRCM_FULL_SPEED;
419                 local_irq_restore(flags);
420         }
421
422         return prev;
423 }
424
425 static int omap2_reprogram_dpll(struct clk * clk, unsigned long rate)
426 {
427         u32 flags, cur_rate, low, mult, div, valid_rate, done_rate;
428         u32 bypass = 0;
429         struct prcm_config tmpset;
430         int ret = -EINVAL;
431
432         local_irq_save(flags);
433         cur_rate = omap2_get_dpll_rate(&dpll_ck);
434         mult = CM_CLKSEL2_PLL & 0x3;
435
436         if ((rate == (cur_rate / 2)) && (mult == 2)) {
437                 omap2_reprogram_sdrc(PRCM_HALF_SPEED, 1);
438         } else if ((rate == (cur_rate * 2)) && (mult == 1)) {
439                 omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1);
440         } else if (rate != cur_rate) {
441                 valid_rate = omap2_dpll_round_rate(rate);
442                 if (valid_rate != rate)
443                         goto dpll_exit;
444
445                 if ((CM_CLKSEL2_PLL & 0x3) == 1)
446                         low = curr_prcm_set->dpll_speed;
447                 else
448                         low = curr_prcm_set->dpll_speed / 2;
449
450                 tmpset.cm_clksel1_pll = CM_CLKSEL1_PLL;
451                 tmpset.cm_clksel1_pll &= ~(0x3FFF << 8);
452                 div = ((curr_prcm_set->xtal_speed / 1000000) - 1);
453                 tmpset.cm_clksel2_pll = CM_CLKSEL2_PLL;
454                 tmpset.cm_clksel2_pll &= ~0x3;
455                 if (rate > low) {
456                         tmpset.cm_clksel2_pll |= 0x2;
457                         mult = ((rate / 2) / 1000000);
458                         done_rate = PRCM_FULL_SPEED;
459                 } else {
460                         tmpset.cm_clksel2_pll |= 0x1;
461                         mult = (rate / 1000000);
462                         done_rate = PRCM_HALF_SPEED;
463                 }
464                 tmpset.cm_clksel1_pll |= ((div << 8) | (mult << 12));
465
466                 /* Worst case */
467                 tmpset.base_sdrc_rfr = V24XX_SDRC_RFR_CTRL_BYPASS;
468
469                 if (rate == curr_prcm_set->xtal_speed)  /* If asking for 1-1 */
470                         bypass = 1;
471
472                 omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1); /* For init_mem */
473
474                 /* Force dll lock mode */
475                 omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr,
476                                bypass);
477
478                 /* Errata: ret dll entry state */
479                 omap2_init_memory_params(omap2_dll_force_needed());
480                 omap2_reprogram_sdrc(done_rate, 0);
481         }
482         omap2_clksel_recalc(&dpll_ck);
483         ret = 0;
484
485 dpll_exit:
486         local_irq_restore(flags);
487         return(ret);
488 }
489
490 /* Just return the MPU speed */
491 static void omap2_mpu_recalc(struct clk * clk)
492 {
493         clk->rate = curr_prcm_set->mpu_speed;
494 }
495
496 /*
497  * Look for a rate equal or less than the target rate given a configuration set.
498  *
499  * What's not entirely clear is "which" field represents the key field.
500  * Some might argue L3-DDR, others ARM, others IVA. This code is simple and
501  * just uses the ARM rates.
502  */
503 static long omap2_round_to_table_rate(struct clk * clk, unsigned long rate)
504 {
505         struct prcm_config * ptr;
506         long highest_rate;
507
508         if (clk != &virt_prcm_set)
509                 return -EINVAL;
510
511         highest_rate = -EINVAL;
512
513         for (ptr = rate_table; ptr->mpu_speed; ptr++) {
514                 if (ptr->xtal_speed != sys_ck.rate)
515                         continue;
516
517                 highest_rate = ptr->mpu_speed;
518
519                 /* Can check only after xtal frequency check */
520                 if (ptr->mpu_speed <= rate)
521                         break;
522         }
523         return highest_rate;
524 }
525
526 /*
527  * omap2_convert_field_to_div() - turn field value into integer divider
528  */
529 static u32 omap2_clksel_to_divisor(u32 div_sel, u32 field_val)
530 {
531         u32 i;
532         u32 clkout_array[] = {1, 2, 4, 8, 16};
533
534         if ((div_sel & SRC_RATE_SEL_MASK) == CM_SYSCLKOUT_SEL1) {
535                 for (i = 0; i < 5; i++) {
536                         if (field_val == i)
537                                 return clkout_array[i];
538                 }
539                 return ~0;
540         } else
541                 return field_val;
542 }
543
544 /*
545  * Returns the CLKSEL divider register value
546  * REVISIT: This should be cleaned up to work nicely with void __iomem *
547  */
548 static u32 omap2_get_clksel(u32 *div_sel, u32 *field_mask,
549                             struct clk *clk)
550 {
551         int ret = ~0;
552         u32 reg_val, div_off;
553         u32 div_addr = 0;
554         u32 mask = ~0;
555
556         div_off = clk->rate_offset;
557
558         switch ((*div_sel & SRC_RATE_SEL_MASK)) {
559         case CM_MPU_SEL1:
560                 div_addr = (u32)&CM_CLKSEL_MPU;
561                 mask = 0x1f;
562                 break;
563         case CM_DSP_SEL1:
564                 div_addr = (u32)&CM_CLKSEL_DSP;
565                 if (cpu_is_omap2420()) {
566                         if ((div_off == 0) || (div_off == 8))
567                                 mask = 0x1f;
568                         else if (div_off == 5)
569                                 mask = 0x3;
570                 } else if (cpu_is_omap2430()) {
571                         if (div_off == 0)
572                                 mask = 0x1f;
573                         else if (div_off == 5)
574                                 mask = 0x3;
575                 }
576                 break;
577         case CM_GFX_SEL1:
578                 div_addr = (u32)&CM_CLKSEL_GFX;
579                 if (div_off == 0)
580                         mask = 0x7;
581                 break;
582         case CM_MODEM_SEL1:
583                 div_addr = (u32)&CM_CLKSEL_MDM;
584                 if (div_off == 0)
585                         mask = 0xf;
586                 break;
587         case CM_SYSCLKOUT_SEL1:
588                 div_addr = (u32)&PRCM_CLKOUT_CTRL;
589                 if ((div_off == 3) || (div_off = 11))
590                         mask= 0x3;
591                 break;
592         case CM_CORE_SEL1:
593                 div_addr = (u32)&CM_CLKSEL1_CORE;
594                 switch (div_off) {
595                 case 0:                                 /* l3 */
596                 case 8:                                 /* dss1 */
597                 case 15:                                /* vylnc-2420 */
598                 case 20:                                /* ssi */
599                         mask = 0x1f; break;
600                 case 5:                                 /* l4 */
601                         mask = 0x3; break;
602                 case 13:                                /* dss2 */
603                         mask = 0x1; break;
604                 case 25:                                /* usb */
605                         mask = 0x7; break;
606                 }
607         }
608
609         *field_mask = mask;
610
611         if (unlikely(mask == ~0))
612                 div_addr = 0;
613
614         *div_sel = div_addr;
615
616         if (unlikely(div_addr == 0))
617                 return ret;
618
619         /* Isolate field */
620         reg_val = __raw_readl((void __iomem *)div_addr) & (mask << div_off);
621
622         /* Normalize back to divider value */
623         reg_val >>= div_off;
624
625         return reg_val;
626 }
627
628 /*
629  * Return divider to be applied to parent clock.
630  * Return 0 on error.
631  */
632 static u32 omap2_clksel_get_divisor(struct clk *clk)
633 {
634         int ret = 0;
635         u32 div, div_sel, div_off, field_mask, field_val;
636
637         /* isolate control register */
638         div_sel = (SRC_RATE_SEL_MASK & clk->flags);
639
640         div_off = clk->rate_offset;
641         field_val = omap2_get_clksel(&div_sel, &field_mask, clk);
642         if (div_sel == 0)
643                 return ret;
644
645         div_sel = (SRC_RATE_SEL_MASK & clk->flags);
646         div = omap2_clksel_to_divisor(div_sel, field_val);
647
648         return div;
649 }
650
651 /* Set the clock rate for a clock source */
652 static int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
653
654 {
655         int ret = -EINVAL;
656         void __iomem * reg;
657         u32 div_sel, div_off, field_mask, field_val, reg_val, validrate;
658         u32 new_div = 0;
659
660         if (!(clk->flags & CONFIG_PARTICIPANT) && (clk->flags & RATE_CKCTL)) {
661                 if (clk == &dpll_ck)
662                         return omap2_reprogram_dpll(clk, rate);
663
664                 /* Isolate control register */
665                 div_sel = (SRC_RATE_SEL_MASK & clk->flags);
666                 div_off = clk->rate_offset;
667
668                 validrate = omap2_clksel_round_rate(clk, rate, &new_div);
669                 if (validrate != rate)
670                         return(ret);
671
672                 field_val = omap2_get_clksel(&div_sel, &field_mask, clk);
673                 if (div_sel == 0)
674                         return ret;
675
676                 if (clk->flags & CM_SYSCLKOUT_SEL1) {
677                         switch (new_div) {
678                         case 16:
679                                 field_val = 4;
680                                 break;
681                         case 8:
682                                 field_val = 3;
683                                 break;
684                         case 4:
685                                 field_val = 2;
686                                 break;
687                         case 2:
688                                 field_val = 1;
689                                 break;
690                         case 1:
691                                 field_val = 0;
692                                 break;
693                         }
694                 } else
695                         field_val = new_div;
696
697                 reg = (void __iomem *)div_sel;
698
699                 reg_val = __raw_readl(reg);
700                 reg_val &= ~(field_mask << div_off);
701                 reg_val |= (field_val << div_off);
702                 __raw_writel(reg_val, reg);
703                 wmb();
704                 clk->rate = clk->parent->rate / field_val;
705
706                 if (clk->flags & DELAYED_APP) {
707                         __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL);
708                         wmb();
709                 }
710                 ret = 0;
711         } else if (clk->set_rate != 0)
712                 ret = clk->set_rate(clk, rate);
713
714         if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
715                 propagate_rate(clk);
716
717         return ret;
718 }
719
720 /* Converts encoded control register address into a full address */
721 static u32 omap2_get_src_field(u32 *type_to_addr, u32 reg_offset,
722                                struct clk *src_clk, u32 *field_mask)
723 {
724         u32 val = ~0, src_reg_addr = 0, mask = 0;
725
726         /* Find target control register.*/
727         switch ((*type_to_addr & SRC_RATE_SEL_MASK)) {
728         case CM_CORE_SEL1:
729                 src_reg_addr = (u32)&CM_CLKSEL1_CORE;
730                 if (reg_offset == 13) {                 /* DSS2_fclk */
731                         mask = 0x1;
732                         if (src_clk == &sys_ck)
733                                 val = 0;
734                         if (src_clk == &func_48m_ck)
735                                 val = 1;
736                 } else if (reg_offset == 8) {           /* DSS1_fclk */
737                         mask = 0x1f;
738                         if (src_clk == &sys_ck)
739                                 val = 0;
740                         else if (src_clk == &core_ck)   /* divided clock */
741                                 val = 0x10;             /* rate needs fixing */
742                 } else if ((reg_offset == 15) && cpu_is_omap2420()){ /*vlnyq*/
743                         mask = 0x1F;
744                         if(src_clk == &func_96m_ck)
745                                 val = 0;
746                         else if (src_clk == &core_ck)
747                                 val = 0x10;
748                 }
749                 break;
750         case CM_CORE_SEL2:
751                 src_reg_addr = (u32)&CM_CLKSEL2_CORE;
752                 mask = 0x3;
753                 if (src_clk == &func_32k_ck)
754                         val = 0x0;
755                 if (src_clk == &sys_ck)
756                         val = 0x1;
757                 if (src_clk == &alt_ck)
758                         val = 0x2;
759                 break;
760         case CM_WKUP_SEL1:
761                 src_reg_addr = (u32)&CM_CLKSEL_WKUP;
762                 mask = 0x3;
763                 if (src_clk == &func_32k_ck)
764                         val = 0x0;
765                 if (src_clk == &sys_ck)
766                         val = 0x1;
767                 if (src_clk == &alt_ck)
768                         val = 0x2;
769                 break;
770         case CM_PLL_SEL1:
771                 src_reg_addr = (u32)&CM_CLKSEL1_PLL;
772                 mask = 0x1;
773                 if (reg_offset == 0x3) {
774                         if (src_clk == &apll96_ck)
775                                 val = 0;
776                         if (src_clk == &alt_ck)
777                                 val = 1;
778                 }
779                 else if (reg_offset == 0x5) {
780                         if (src_clk == &apll54_ck)
781                                 val = 0;
782                         if (src_clk == &alt_ck)
783                                 val = 1;
784                 }
785                 break;
786         case CM_PLL_SEL2:
787                 src_reg_addr = (u32)&CM_CLKSEL2_PLL;
788                 mask = 0x3;
789                 if (src_clk == &func_32k_ck)
790                         val = 0x0;
791                 if (src_clk == &dpll_ck)
792                         val = 0x2;
793                 break;
794         case CM_SYSCLKOUT_SEL1:
795                 src_reg_addr = (u32)&PRCM_CLKOUT_CTRL;
796                 mask = 0x3;
797                 if (src_clk == &dpll_ck)
798                         val = 0;
799                 if (src_clk == &sys_ck)
800                         val = 1;
801                 if (src_clk == &func_96m_ck)
802                         val = 2;
803                 if (src_clk == &func_54m_ck)
804                         val = 3;
805                 break;
806         }
807
808         if (val == ~0)                  /* Catch errors in offset */
809                 *type_to_addr = 0;
810         else
811                 *type_to_addr = src_reg_addr;
812         *field_mask = mask;
813
814         return val;
815 }
816
817 static int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
818 {
819         void __iomem * reg;
820         u32 src_sel, src_off, field_val, field_mask, reg_val, rate;
821         int ret = -EINVAL;
822
823         if (unlikely(clk->flags & CONFIG_PARTICIPANT))
824                 return ret;
825
826         if (clk->flags & SRC_SEL_MASK) {        /* On-chip SEL collection */
827                 src_sel = (SRC_RATE_SEL_MASK & clk->flags);
828                 src_off = clk->src_offset;
829
830                 if (src_sel == 0)
831                         goto set_parent_error;
832
833                 field_val = omap2_get_src_field(&src_sel, src_off, new_parent,
834                                                 &field_mask);
835
836                 reg = (void __iomem *)src_sel;
837
838                 if (clk->usecount > 0)
839                         _omap2_clk_disable(clk);
840
841                 /* Set new source value (previous dividers if any in effect) */
842                 reg_val = __raw_readl(reg) & ~(field_mask << src_off);
843                 reg_val |= (field_val << src_off);
844                 __raw_writel(reg_val, reg);
845                 wmb();
846
847                 if (clk->flags & DELAYED_APP) {
848                         __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL);
849                         wmb();
850                 }
851                 if (clk->usecount > 0)
852                         _omap2_clk_enable(clk);
853
854                 clk->parent = new_parent;
855
856                 /* SRC_RATE_SEL_MASK clocks follow their parents rates.*/
857                 if ((new_parent == &core_ck) && (clk == &dss1_fck))
858                         clk->rate = new_parent->rate / 0x10;
859                 else
860                         clk->rate = new_parent->rate;
861
862                 if (unlikely(clk->flags & RATE_PROPAGATES))
863                         propagate_rate(clk);
864
865                 return 0;
866         } else {
867                 clk->parent = new_parent;
868                 rate = new_parent->rate;
869                 omap2_clk_set_rate(clk, rate);
870                 ret = 0;
871         }
872
873  set_parent_error:
874         return ret;
875 }
876
877 /* Sets basic clocks based on the specified rate */
878 static int omap2_select_table_rate(struct clk * clk, unsigned long rate)
879 {
880         u32 flags, cur_rate, done_rate, bypass = 0;
881         u8 cpu_mask = 0;
882         struct prcm_config *prcm;
883         unsigned long found_speed = 0;
884
885         if (clk != &virt_prcm_set)
886                 return -EINVAL;
887
888         /* FIXME: Change cpu_is_omap2420() to cpu_is_omap242x() */
889         if (cpu_is_omap2420())
890                 cpu_mask = RATE_IN_242X;
891         else if (cpu_is_omap2430())
892                 cpu_mask = RATE_IN_243X;
893
894         for (prcm = rate_table; prcm->mpu_speed; prcm++) {
895                 if (!(prcm->flags & cpu_mask))
896                         continue;
897
898                 if (prcm->xtal_speed != sys_ck.rate)
899                         continue;
900
901                 if (prcm->mpu_speed <= rate) {
902                         found_speed = prcm->mpu_speed;
903                         break;
904                 }
905         }
906
907         if (!found_speed) {
908                 printk(KERN_INFO "Could not set MPU rate to %luMHz\n",
909          rate / 1000000);
910                 return -EINVAL;
911         }
912
913         curr_prcm_set = prcm;
914         cur_rate = omap2_get_dpll_rate(&dpll_ck);
915
916         if (prcm->dpll_speed == cur_rate / 2) {
917                 omap2_reprogram_sdrc(PRCM_HALF_SPEED, 1);
918         } else if (prcm->dpll_speed == cur_rate * 2) {
919                 omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1);
920         } else if (prcm->dpll_speed != cur_rate) {
921                 local_irq_save(flags);
922
923                 if (prcm->dpll_speed == prcm->xtal_speed)
924                         bypass = 1;
925
926                 if ((prcm->cm_clksel2_pll & 0x3) == 2)
927                         done_rate = PRCM_FULL_SPEED;
928                 else
929                         done_rate = PRCM_HALF_SPEED;
930
931                 /* MPU divider */
932                 CM_CLKSEL_MPU = prcm->cm_clksel_mpu;
933
934                 /* dsp + iva1 div(2420), iva2.1(2430) */
935                 CM_CLKSEL_DSP = prcm->cm_clksel_dsp;
936
937                 CM_CLKSEL_GFX = prcm->cm_clksel_gfx;
938
939                 /* Major subsystem dividers */
940                 CM_CLKSEL1_CORE = prcm->cm_clksel1_core;
941                 if (cpu_is_omap2430())
942                         CM_CLKSEL_MDM = prcm->cm_clksel_mdm;
943
944                 /* x2 to enter init_mem */
945                 omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1);
946
947                 omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr,
948                                bypass);
949
950                 omap2_init_memory_params(omap2_dll_force_needed());
951                 omap2_reprogram_sdrc(done_rate, 0);
952
953                 local_irq_restore(flags);
954         }
955         omap2_clksel_recalc(&dpll_ck);
956
957         return 0;
958 }
959
960 /*-------------------------------------------------------------------------
961  * Omap2 clock reset and init functions
962  *-------------------------------------------------------------------------*/
963
964 static struct clk_functions omap2_clk_functions = {
965         .clk_enable             = omap2_clk_enable,
966         .clk_disable            = omap2_clk_disable,
967         .clk_round_rate         = omap2_clk_round_rate,
968         .clk_set_rate           = omap2_clk_set_rate,
969         .clk_set_parent         = omap2_clk_set_parent,
970 };
971
972 static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys)
973 {
974         u32 div, aplls, sclk = 13000000;
975
976         aplls = CM_CLKSEL1_PLL;
977         aplls &= ((1 << 23) | (1 << 24) | (1 << 25));
978         aplls >>= 23;                   /* Isolate field, 0,2,3 */
979
980         if (aplls == 0)
981                 sclk = 19200000;
982         else if (aplls == 2)
983                 sclk = 13000000;
984         else if (aplls == 3)
985                 sclk = 12000000;
986
987         div = PRCM_CLKSRC_CTRL;
988         div &= ((1 << 7) | (1 << 6));
989         div >>= sys->rate_offset;
990
991         osc->rate = sclk * div;
992         sys->rate = sclk;
993 }
994
995 /*
996  * Set clocks for bypass mode for reboot to work.
997  */
998 void omap2_clk_prepare_for_reboot(void)
999 {
1000         u32 rate;
1001
1002         if (vclk == NULL || sclk == NULL)
1003                 return;
1004
1005         rate = clk_get_rate(sclk);
1006         clk_set_rate(vclk, rate);
1007 }
1008
1009 #ifdef CONFIG_OMAP_RESET_CLOCKS
1010 static void __init omap2_disable_unused_clocks(void)
1011 {
1012         struct clk *ck;
1013         u32 regval32;
1014
1015         list_for_each_entry(ck, &clocks, node) {
1016                 if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) ||
1017                         ck->enable_reg == 0)
1018                         continue;
1019
1020                 regval32 = __raw_readl(ck->enable_reg);
1021                 if ((regval32 & (1 << ck->enable_bit)) == 0)
1022                         continue;
1023
1024                 printk(KERN_INFO "Disabling unused clock \"%s\"\n", ck->name);
1025                 _omap2_clk_disable(ck);
1026         }
1027 }
1028 late_initcall(omap2_disable_unused_clocks);
1029 #endif
1030
1031 /*
1032  * Switch the MPU rate if specified on cmdline.
1033  * We cannot do this early until cmdline is parsed.
1034  */
1035 static int __init omap2_clk_arch_init(void)
1036 {
1037         if (!mpurate)
1038                 return -EINVAL;
1039
1040         if (omap2_select_table_rate(&virt_prcm_set, mpurate))
1041                 printk(KERN_ERR "Could not find matching MPU rate\n");
1042
1043         propagate_rate(&osc_ck);                /* update main root fast */
1044         propagate_rate(&func_32k_ck);           /* update main root slow */
1045
1046         printk(KERN_INFO "Switched to new clocking rate (Crystal/DPLL/MPU): "
1047                "%ld.%01ld/%ld/%ld MHz\n",
1048                (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
1049                (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;
1050
1051         return 0;
1052 }
1053 arch_initcall(omap2_clk_arch_init);
1054
1055 int __init omap2_clk_init(void)
1056 {
1057         struct prcm_config *prcm;
1058         struct clk ** clkp;
1059         u32 clkrate;
1060
1061         clk_init(&omap2_clk_functions);
1062         omap2_get_crystal_rate(&osc_ck, &sys_ck);
1063
1064         for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
1065              clkp++) {
1066
1067                 if ((*clkp)->flags & CLOCK_IN_OMAP242X && cpu_is_omap2420()) {
1068                         clk_register(*clkp);
1069                         continue;
1070                 }
1071
1072                 if ((*clkp)->flags & CLOCK_IN_OMAP243X && cpu_is_omap2430()) {
1073                         clk_register(*clkp);
1074                         continue;
1075                 }
1076         }
1077
1078         /* Check the MPU rate set by bootloader */
1079         clkrate = omap2_get_dpll_rate(&dpll_ck);
1080         for (prcm = rate_table; prcm->mpu_speed; prcm++) {
1081                 if (prcm->xtal_speed != sys_ck.rate)
1082                         continue;
1083                 if (prcm->dpll_speed <= clkrate)
1084                          break;
1085         }
1086         curr_prcm_set = prcm;
1087
1088         propagate_rate(&osc_ck);                /* update main root fast */
1089         propagate_rate(&func_32k_ck);           /* update main root slow */
1090
1091         printk(KERN_INFO "Clocking rate (Crystal/DPLL/MPU): "
1092                "%ld.%01ld/%ld/%ld MHz\n",
1093                (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
1094                (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;
1095
1096         /*
1097          * Only enable those clocks we will need, let the drivers
1098          * enable other clocks as necessary
1099          */
1100         clk_enable(&sync_32k_ick);
1101         clk_enable(&omapctrl_ick);
1102         if (cpu_is_omap2430())
1103                 clk_enable(&sdrc_ick);
1104
1105         /* Avoid sleeping sleeping during omap2_clk_prepare_for_reboot() */
1106         vclk = clk_get(NULL, "virt_prcm_set");
1107         sclk = clk_get(NULL, "sys_ck");
1108
1109         return 0;
1110 }