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