]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/mach-omap2/clock.c
omap2 clock: use the struct clk round_rate field for clksel rate rounding code
[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  *  Copyright (C) 2007 Texas Instruments, Inc.
12  *  Copyright (C) 2007 Nokia Corporation
13  *  Paul Walmsley
14  *
15  *  Based on omap1 clock.c, Copyright (C) 2004 - 2005 Nokia corporation
16  *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
17  *
18  * This program is free software; you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License version 2 as
20  * published by the Free Software Foundation.
21  */
22 #include <linux/module.h>
23 #include <linux/kernel.h>
24 #include <linux/device.h>
25 #include <linux/list.h>
26 #include <linux/errno.h>
27 #include <linux/delay.h>
28 #include <linux/clk.h>
29
30 #include <asm/io.h>
31
32 #include <asm/arch/clock.h>
33 #include <asm/arch/sram.h>
34 #include <asm/div64.h>
35
36 #include "memory.h"
37 #include "clock.h"
38 #include "prm.h"
39 #include "prm_regbits_24xx.h"
40 #include "cm.h"
41 #include "cm_regbits_24xx.h"
42
43 #undef DEBUG
44
45 /* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
46 #define EN_APLL_STOPPED                 0
47 #define EN_APLL_LOCKED                  3
48
49 /* CM_CLKSEL1_PLL.APLLS_CLKIN options (24XX) */
50 #define APLLS_CLKIN_19_2MHZ             0
51 #define APLLS_CLKIN_13MHZ               2
52 #define APLLS_CLKIN_12MHZ               3
53
54 #define MAX_PLL_LOCK_WAIT               100000
55
56 //#define DOWN_VARIABLE_DPLL 1                  /* Experimental */
57
58 static struct prcm_config *curr_prcm_set;
59 static struct clk *vclk;
60 static struct clk *sclk;
61 static u8 cpu_mask;
62
63 /*-------------------------------------------------------------------------
64  * Omap2 specific clock functions
65  *-------------------------------------------------------------------------*/
66
67 static inline u8 mask_to_shift(u32 mask)
68 {
69         return ffs(mask) - 1;
70 }
71
72 /**
73  * omap2_init_clksel_parent - set a clksel clk's parent field from the hardware
74  * @clk: OMAP clock struct ptr to use
75  *
76  * Given a pointer to a source-selectable struct clk, read the hardware
77  * register and determine what its parent is currently set to.  Update the
78  * clk->parent field with the appropriate clk ptr.
79  */
80 static void omap2_init_clksel_parent(struct clk *clk)
81 {
82         const struct clksel *clks;
83         const struct clksel_rate *clkr;
84         u32 r, found = 0;
85
86         if (!clk->clksel)
87                 return;
88
89         /* XXX Should be __raw_readl for non-CM 3430 clocks ? */
90         r = cm_read_reg(clk->clksel_reg) & clk->clksel_mask;
91         r >>= mask_to_shift(clk->clksel_mask);
92
93         for (clks = clk->clksel; clks->parent && !found; clks++) {
94                 for (clkr = clks->rates; clkr->div && !found; clkr++) {
95                         if ((clkr->flags & cpu_mask) && (clkr->val == r)) {
96                                 if (clk->parent != clks->parent) {
97                                         pr_debug("clock: inited %s parent "
98                                                  "to %s (was %s)\n",
99                                                  clk->name, clks->parent->name,
100                                                  ((clk->parent->name) ?
101                                                   clk->parent->name : "NULL"));
102                                         clk->parent = clks->parent;
103                                 };
104                                 found = 1;
105                         }
106                 }
107         }
108
109         if (!found)
110                 printk(KERN_ERR "clock: init parent: could not find "
111                        "regval %0x for clock %s\n", r,  clk->name);
112
113         return;
114 }
115
116 /* Recalculate SYST_CLK */
117 static void omap2_sys_clk_recalc(struct clk * clk)
118 {
119         u32 div;
120
121         if (!cpu_is_omap34xx()) {
122                 div = prm_read_reg(OMAP24XX_PRCM_CLKSRC_CTRL);
123                 /* Test if ext clk divided by 1 or 2 */
124                 div &= OMAP_SYSCLKDIV_MASK;
125                 div >>= OMAP_SYSCLKDIV_SHIFT;
126                 clk->rate = (clk->parent->rate / div);
127         }
128         propagate_rate(clk);
129 }
130
131 static u32 omap2_get_dpll_rate(struct clk * tclk)
132 {
133         long long dpll_clk;
134         int dpll_mult, dpll_div, amult;
135         u32 dpll;
136
137         dpll = cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
138
139         dpll_mult = dpll & OMAP24XX_DPLL_MULT_MASK;
140         dpll_mult >>= OMAP24XX_DPLL_MULT_SHIFT;         /* 10 bits */
141         dpll_div = dpll & OMAP24XX_DPLL_DIV_MASK;
142         dpll_div >>= OMAP24XX_DPLL_DIV_SHIFT;           /* 4 bits */
143         dpll_clk = (long long)tclk->parent->rate * dpll_mult;
144         do_div(dpll_clk, dpll_div + 1);
145         amult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
146         amult &= OMAP24XX_CORE_CLK_SRC_MASK;
147         dpll_clk *= amult;
148
149         return dpll_clk;
150 }
151
152 /*
153  * Used for clocks that have the same value as the parent clock,
154  * divided by some factor
155  */
156 static void omap2_fixed_divisor_recalc(struct clk *clk)
157 {
158         WARN_ON(!clk->fixed_div);
159
160         clk->rate = clk->parent->rate / clk->fixed_div;
161
162         if (clk->flags & RATE_PROPAGATES)
163                 propagate_rate(clk);
164 }
165
166 static void omap2_set_osc_ck(int enable)
167 {
168         u32 pcc;
169
170         pcc = prm_read_reg(OMAP24XX_PRCM_CLKSRC_CTRL);
171
172         if (enable)
173                 prm_write_reg(pcc & ~OMAP_AUTOEXTCLKMODE_MASK,
174                               OMAP24XX_PRCM_CLKSRC_CTRL);
175         else
176                 prm_write_reg(pcc | OMAP_AUTOEXTCLKMODE_MASK,
177                               OMAP24XX_PRCM_CLKSRC_CTRL);
178 }
179
180 /*
181  * omap2_wait_clock_ready - wait for PLL to lock
182  *
183  * Returns 1 if the PLL locked, 0 if it failed to lock.
184  */
185 static int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name)
186 {
187         int i = 0;
188
189         /* Wait for lock */
190         while (!(cm_read_reg(reg) & cval)) {
191                 ++i;
192                 udelay(1);
193                 if (i == MAX_PLL_LOCK_WAIT) {
194                         printk(KERN_ERR "Clock %s didn't lock in %d tries\n",
195                                name, MAX_PLL_LOCK_WAIT);
196                         break;
197                 }
198         }
199
200         if (i)
201                 pr_debug("Clock %s stable after %d loops\n", name, i);
202
203         return (i < MAX_PLL_LOCK_WAIT) ? 1 : 0;
204 };
205
206
207 /* Enable an APLL if off */
208 static void omap2_clk_fixed_enable(struct clk *clk)
209 {
210         u32 cval, apll_mask;
211
212         apll_mask = EN_APLL_LOCKED << clk->enable_bit;
213
214         cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);
215
216         if ((cval & apll_mask) == apll_mask)
217                 return;   /* apll already enabled */
218
219         cval &= ~apll_mask;
220         cval |= apll_mask;
221         cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
222
223         if (clk == &apll96_ck)
224                 cval = OMAP24XX_ST_96M_APLL;
225         else if (clk == &apll54_ck)
226                 cval = OMAP24XX_ST_54M_CLK;
227
228         omap2_wait_clock_ready(OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), cval,
229                             clk->name);
230 }
231
232 static void omap2_clk_wait_ready(struct clk *clk)
233 {
234         void __iomem *reg, *other_reg, *st_reg;
235         u32 bit;
236
237         reg = clk->enable_reg;
238         if (reg == OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1) ||
239             reg == OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2))
240                 other_reg = (void __iomem *)(((u32)reg & ~0xf0) | 0x10); /* CM_ICLKEN* */
241         else if (reg == OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1) ||
242                  reg == OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2))
243                 other_reg = (void __iomem *)(((u32)reg & ~0xf0) | 0x00); /* CM_FCLKEN* */
244         else
245                 return;
246
247         /* No check for DSS or cam clocks */
248         if (((u32)reg & 0x0f) == 0) { /* CM_{F,I}CLKEN1 */
249                 if (clk->enable_bit == OMAP24XX_EN_DSS2_SHIFT ||
250                     clk->enable_bit == OMAP24XX_EN_DSS1_SHIFT ||
251                     clk->enable_bit == OMAP24XX_EN_CAM_SHIFT)
252                         return;
253         }
254
255         /* Check if both functional and interface clocks
256          * are running. */
257         bit = 1 << clk->enable_bit;
258         if (!(cm_read_reg(other_reg) & bit))
259                 return;
260         st_reg = (void __iomem *)(((u32)other_reg & ~0xf0) | 0x20); /* CM_IDLEST* */
261
262         omap2_wait_clock_ready(st_reg, bit, clk->name);
263 }
264
265 /* Enables clock without considering parent dependencies or use count
266  * REVISIT: Maybe change this to use clk->enable like on omap1?
267  */
268 static int _omap2_clk_enable(struct clk * clk)
269 {
270         u32 regval32;
271
272         if (clk->flags & (ALWAYS_ENABLED | PARENT_CONTROLS_CLOCK))
273                 return 0;
274
275         if (unlikely(clk == &osc_ck)) {
276                 omap2_set_osc_ck(1);
277                 return 0;
278         }
279
280         if (unlikely(clk->enable_reg == 0)) {
281                 printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
282                        clk->name);
283                 return -EINVAL;
284         }
285
286         if (clk->enable_reg == OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN)) {
287                 omap2_clk_fixed_enable(clk);
288                 return 0;
289         }
290
291         regval32 = cm_read_reg(clk->enable_reg);
292         regval32 |= (1 << clk->enable_bit);
293         cm_write_reg(regval32, clk->enable_reg);
294         wmb();
295
296         omap2_clk_wait_ready(clk);
297
298         return 0;
299 }
300
301 /* Stop APLL */
302 static void omap2_clk_fixed_disable(struct clk *clk)
303 {
304         u32 cval;
305
306         cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);
307         cval &= ~(EN_APLL_LOCKED << clk->enable_bit);
308         cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
309 }
310
311 /* Disables clock without considering parent dependencies or use count */
312 static void _omap2_clk_disable(struct clk *clk)
313 {
314         u32 regval32;
315
316         if (clk->flags & (ALWAYS_ENABLED | PARENT_CONTROLS_CLOCK))
317                 return;
318
319         if (unlikely(clk == &osc_ck)) {
320                 omap2_set_osc_ck(0);
321                 return;
322         }
323
324         if (clk->enable_reg == 0) {
325                 /*
326                  * 'Independent' here refers to a clock which is not
327                  * controlled by its parent.
328                  */
329                 printk(KERN_ERR "clock: clk_disable called on independent "
330                        "clock %s which has no enable_reg\n", clk->name);
331                 return;
332         }
333
334         if (clk->enable_reg == OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN)) {
335                 omap2_clk_fixed_disable(clk);
336                 return;
337         }
338
339         regval32 = cm_read_reg(clk->enable_reg);
340         regval32 &= ~(1 << clk->enable_bit);
341         cm_write_reg(regval32, clk->enable_reg);
342         wmb();
343 }
344
345 static int omap2_clk_enable(struct clk *clk)
346 {
347         int ret = 0;
348
349         if (clk->usecount++ == 0) {
350                 if (likely((u32)clk->parent))
351                         ret = omap2_clk_enable(clk->parent);
352
353                 if (unlikely(ret != 0)) {
354                         clk->usecount--;
355                         return ret;
356                 }
357
358                 ret = _omap2_clk_enable(clk);
359
360                 if (unlikely(ret != 0) && clk->parent) {
361                         omap2_clk_disable(clk->parent);
362                         clk->usecount--;
363                 }
364         }
365
366         return ret;
367 }
368
369 static void omap2_clk_disable(struct clk *clk)
370 {
371         if (clk->usecount > 0 && !(--clk->usecount)) {
372                 _omap2_clk_disable(clk);
373                 if (likely((u32)clk->parent))
374                         omap2_clk_disable(clk->parent);
375         }
376 }
377
378 /*
379  * Uses the current prcm set to tell if a rate is valid.
380  * You can go slower, but not faster within a given rate set.
381  */
382 static u32 omap2_dpll_round_rate(unsigned long target_rate)
383 {
384         u32 high, low, core_clk_src;
385
386         core_clk_src = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
387         core_clk_src &= OMAP24XX_CORE_CLK_SRC_MASK;
388
389         if (core_clk_src == CORE_CLK_SRC_DPLL) {        /* DPLL clockout */
390                 high = curr_prcm_set->dpll_speed * 2;
391                 low = curr_prcm_set->dpll_speed;
392         } else {                                /* DPLL clockout x 2 */
393                 high = curr_prcm_set->dpll_speed;
394                 low = curr_prcm_set->dpll_speed / 2;
395         }
396
397 #ifdef DOWN_VARIABLE_DPLL
398         if (target_rate > high)
399                 return high;
400         else
401                 return target_rate;
402 #else
403         if (target_rate > low)
404                 return high;
405         else
406                 return low;
407 #endif
408
409 }
410
411 static void omap2_dpll_recalc(struct clk *clk)
412 {
413         clk->rate = omap2_get_dpll_rate(clk);
414
415         propagate_rate(clk);
416 }
417
418 /*
419  * Used for clocks that are part of CLKSEL_xyz governed clocks.
420  * REVISIT: Maybe change to use clk->enable() functions like on omap1?
421  */
422 static void omap2_clksel_recalc(struct clk * clk)
423 {
424         u32 div = 0;
425
426         pr_debug("clock: recalc'ing clksel clk %s\n", clk->name);
427
428         div = omap2_clksel_get_divisor(clk);
429         if (div == 0)
430                 return;
431
432         if (unlikely(clk->rate == clk->parent->rate / div))
433                 return;
434         clk->rate = clk->parent->rate / div;
435
436         pr_debug("clock: new clock rate is %ld (div %d)\n", clk->rate, div);
437
438         if (unlikely(clk->flags & RATE_PROPAGATES))
439                 propagate_rate(clk);
440 }
441
442 /**
443  * omap2_get_clksel_by_parent - return clksel struct for a given clk & parent
444  * @clk: OMAP struct clk ptr to inspect
445  * @src_clk: OMAP struct clk ptr of the parent clk to search for
446  *
447  * Scan the struct clksel array associated with the clock to find
448  * the element associated with the supplied parent clock address.
449  * Returns a pointer to the struct clksel on success or NULL on error.
450  */
451 const static struct clksel *omap2_get_clksel_by_parent(struct clk *clk,
452                                                        struct clk *src_clk)
453 {
454         const struct clksel *clks;
455
456         if (!clk->clksel)
457                 return NULL;
458
459         for (clks = clk->clksel; clks->parent; clks++) {
460                 if (clks->parent == src_clk)
461                         break; /* Found the requested parent */
462         }
463
464         if (!clks->parent) {
465                 printk(KERN_ERR "clock: Could not find parent clock %s in "
466                        "clksel array of clock %s\n", src_clk->name,
467                        clk->name);
468                 return NULL;
469         }
470
471         return clks;
472 }
473
474 /**
475  * omap2_clksel_round_rate_div - find divisor for the given clock and rate
476  * @clk: OMAP struct clk to use
477  * @target_rate: desired clock rate
478  * @new_div: ptr to where we should store the divisor
479  *
480  * Finds 'best' divider value in an array based on the source and target
481  * rates.  The divider array must be sorted with smallest divider first.
482  * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT,
483  * they are only settable as part of virtual_prcm set.
484  *
485  * Returns the rounded clock rate or returns 0xffffffff on error.
486  */
487 static u32 omap2_clksel_round_rate_div(struct clk *clk,
488                                        unsigned long target_rate,
489                                        u32 *new_div)
490 {
491         unsigned long test_rate;
492         const struct clksel *clks;
493         const struct clksel_rate *clkr;
494         u32 last_div = 0;
495
496         printk(KERN_INFO "clock: clksel_round_rate_div: %s target_rate %ld\n",
497                clk->name, target_rate);
498
499         *new_div = 1;
500
501         clks = omap2_get_clksel_by_parent(clk, clk->parent);
502         if (clks == NULL)
503                 return ~0;
504
505         for (clkr = clks->rates; clkr->div; clkr++) {
506                 if (!(clkr->flags & cpu_mask))
507                     continue;
508
509                 /* Sanity check */
510                 if (clkr->div <= last_div)
511                         printk(KERN_ERR "clock: clksel_rate table not sorted "
512                                "for clock %s", clk->name);
513
514                 last_div = clkr->div;
515
516                 test_rate = clk->parent->rate / clkr->div;
517
518                 if (test_rate <= target_rate)
519                         break; /* found it */
520         }
521
522         if (!clkr->div) {
523                 printk(KERN_ERR "clock: Could not find divisor for target "
524                        "rate %ld for clock %s parent %s\n", target_rate,
525                        clk->name, clk->parent->name);
526                 return ~0;
527         }
528
529         *new_div = clkr->div;
530
531         printk(KERN_INFO "clock: new_div = %d, new_rate = %ld\n", *new_div,
532                (clk->parent->rate / clkr->div));
533
534         return (clk->parent->rate / clkr->div);
535 }
536
537 /**
538  * omap2_clksel_round_rate - find rounded rate for the given clock and rate
539  * @clk: OMAP struct clk to use
540  * @target_rate: desired clock rate
541  *
542  * Compatibility wrapper for OMAP clock framework
543  * Finds best target rate based on the source clock and possible dividers.
544  * rates. The divider array must be sorted with smallest divider first.
545  * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT,
546  * they are only settable as part of virtual_prcm set.
547  *
548  * Returns the rounded clock rate or returns 0xffffffff on error.
549  */
550 static long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate)
551 {
552         u32 new_div;
553
554         return omap2_clksel_round_rate_div(clk, target_rate, &new_div);
555 }
556
557
558 /* Given a clock and a rate apply a clock specific rounding function */
559 static long omap2_clk_round_rate(struct clk *clk, unsigned long rate)
560 {
561         if (clk->round_rate != 0)
562                 return clk->round_rate(clk, rate);
563
564         if (clk->flags & RATE_FIXED)
565                 printk(KERN_ERR "clock: generic omap2_clk_round_rate called "
566                        "on fixed-rate clock %s\n", clk->name);
567
568         return clk->rate;
569 }
570
571 static int omap2_reprogram_dpll(struct clk * clk, unsigned long rate)
572 {
573         u32 flags, cur_rate, low, mult, div, valid_rate, done_rate;
574         u32 bypass = 0;
575         struct prcm_config tmpset;
576         int ret = -EINVAL;
577
578         local_irq_save(flags);
579         cur_rate = omap2_get_dpll_rate(&dpll_ck);
580         mult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
581         mult &= OMAP24XX_CORE_CLK_SRC_MASK;
582
583         if ((rate == (cur_rate / 2)) && (mult == 2)) {
584                 omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL, 1);
585         } else if ((rate == (cur_rate * 2)) && (mult == 1)) {
586                 omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1);
587         } else if (rate != cur_rate) {
588                 valid_rate = omap2_dpll_round_rate(rate);
589                 if (valid_rate != rate)
590                         goto dpll_exit;
591
592                 if (mult == 1)
593                         low = curr_prcm_set->dpll_speed;
594                 else
595                         low = curr_prcm_set->dpll_speed / 2;
596
597                 tmpset.cm_clksel1_pll = cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
598                 tmpset.cm_clksel1_pll &= ~(OMAP24XX_DPLL_MULT_MASK |
599                                            OMAP24XX_DPLL_DIV_MASK);
600                 div = ((curr_prcm_set->xtal_speed / 1000000) - 1);
601                 tmpset.cm_clksel2_pll = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
602                 tmpset.cm_clksel2_pll &= ~OMAP24XX_CORE_CLK_SRC_MASK;
603                 if (rate > low) {
604                         tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL_X2;
605                         mult = ((rate / 2) / 1000000);
606                         done_rate = CORE_CLK_SRC_DPLL_X2;
607                 } else {
608                         tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL;
609                         mult = (rate / 1000000);
610                         done_rate = CORE_CLK_SRC_DPLL;
611                 }
612                 tmpset.cm_clksel1_pll |= (div << OMAP24XX_DPLL_DIV_SHIFT);
613                 tmpset.cm_clksel1_pll |= (mult << OMAP24XX_DPLL_MULT_SHIFT);
614
615                 /* Worst case */
616                 tmpset.base_sdrc_rfr = V24XX_SDRC_RFR_CTRL_BYPASS;
617
618                 if (rate == curr_prcm_set->xtal_speed)  /* If asking for 1-1 */
619                         bypass = 1;
620
621                 omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1); /* For init_mem */
622
623                 /* Force dll lock mode */
624                 omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr,
625                                bypass);
626
627                 /* Errata: ret dll entry state */
628                 omap2_init_memory_params(omap2_dll_force_needed());
629                 omap2_reprogram_sdrc(done_rate, 0);
630         }
631         omap2_dpll_recalc(&dpll_ck);
632         ret = 0;
633
634 dpll_exit:
635         local_irq_restore(flags);
636         return(ret);
637 }
638
639 /**
640  * omap2_table_mpu_recalc - just return the MPU speed
641  * @clk: virt_prcm_set struct clk
642  *
643  * Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set.
644  */
645 static void omap2_table_mpu_recalc(struct clk *clk)
646 {
647         clk->rate = curr_prcm_set->mpu_speed;
648 }
649
650 /*
651  * Look for a rate equal or less than the target rate given a configuration set.
652  *
653  * What's not entirely clear is "which" field represents the key field.
654  * Some might argue L3-DDR, others ARM, others IVA. This code is simple and
655  * just uses the ARM rates.
656  */
657 static long omap2_round_to_table_rate(struct clk * clk, unsigned long rate)
658 {
659         struct prcm_config * ptr;
660         long highest_rate;
661
662         if (clk != &virt_prcm_set)
663                 return -EINVAL;
664
665         highest_rate = -EINVAL;
666
667         for (ptr = rate_table; ptr->mpu_speed; ptr++) {
668                 if (!(ptr->flags & cpu_mask))
669                         continue;
670                 if (ptr->xtal_speed != sys_ck.rate)
671                         continue;
672
673                 highest_rate = ptr->mpu_speed;
674
675                 /* Can check only after xtal frequency check */
676                 if (ptr->mpu_speed <= rate)
677                         break;
678         }
679         return highest_rate;
680 }
681
682 /**
683  * omap2_clksel_to_divisor() - turn clksel field value into integer divider
684  * @clk: OMAP struct clk to use
685  * @field_val: register field value to find
686  *
687  * Given a struct clk of a rate-selectable clksel clock, and a register field
688  * value to search for, find the corresponding clock divisor.  The register
689  * field value should be pre-masked and shifted down so the LSB is at bit 0
690  * before calling.  Returns 0 on error
691  */
692 static u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val)
693 {
694         const struct clksel *clks;
695         const struct clksel_rate *clkr;
696
697         clks = omap2_get_clksel_by_parent(clk, clk->parent);
698         if (clks == NULL)
699                 return 0;
700
701         for (clkr = clks->rates; clkr->div; clkr++) {
702                 if ((clkr->flags & cpu_mask) && (clkr->val == field_val))
703                         break;
704         }
705
706         if (!clkr->div) {
707                 printk(KERN_ERR "clock: Could not find fieldval %d for "
708                        "clock %s parent %s\n", field_val, clk->name,
709                        clk->parent->name);
710                 return 0;
711         }
712
713         return clkr->div;
714 }
715
716 /**
717  * omap2_divisor_to_clksel() - turn clksel integer divisor into a field value
718  * @clk: OMAP struct clk to use
719  * @div: integer divisor to search for
720  *
721  * Given a struct clk of a rate-selectable clksel clock, and a clock divisor,
722  * find the corresponding register field value.  The return register value is
723  * the value before left-shifting.  Returns 0xffffffff on error
724  */
725 static u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
726 {
727         const struct clksel *clks;
728         const struct clksel_rate *clkr;
729
730         /* should never happen */
731         WARN_ON(div == 0);
732
733         clks = omap2_get_clksel_by_parent(clk, clk->parent);
734         if (clks == NULL)
735                 return 0;
736
737         for (clkr = clks->rates; clkr->div; clkr++) {
738                 if ((clkr->flags & cpu_mask) && (clkr->div == div))
739                         break;
740         }
741
742         if (!clkr->div) {
743                 printk(KERN_ERR "clock: Could not find divisor %d for "
744                        "clock %s parent %s\n", div, clk->name,
745                        clk->parent->name);
746                 return 0;
747         }
748
749         return clkr->val;
750 }
751
752 /**
753  * omap2_get_clksel - find clksel register addr & field mask for a clk
754  * @clk: struct clk to use
755  * @field_mask: ptr to u32 to store the register field mask
756  *
757  * Returns the address of the clksel register upon success or NULL on error.
758  */
759 static void __iomem *omap2_get_clksel(struct clk *clk, u32 *field_mask)
760 {
761         if (unlikely((clk->clksel_reg == 0) || (clk->clksel_mask == 0)))
762                 return NULL;
763
764         *field_mask = clk->clksel_mask;
765
766         return clk->clksel_reg;
767 }
768
769 /**
770  * omap2_clksel_get_divisor - get current divider applied to parent clock.
771  * @clk: OMAP struct clk to use.
772  *
773  * Returns the integer divisor upon success or 0 on error.
774  */
775 static u32 omap2_clksel_get_divisor(struct clk *clk)
776 {
777         u32 field_mask, field_val;
778         void __iomem *div_addr;
779
780         div_addr = omap2_get_clksel(clk, &field_mask);
781         if (div_addr == 0)
782                 return 0;
783
784         field_val = cm_read_reg(div_addr) & field_mask;
785         field_val >>= mask_to_shift(field_mask);
786
787         return omap2_clksel_to_divisor(clk, field_val);
788 }
789
790 /* Set the clock rate for a clock source */
791 static int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
792 {
793         int ret = -EINVAL;
794         u32 field_mask, field_val, reg_val, new_div = 0;
795         unsigned long validrate;
796         void __iomem *div_addr;
797
798         if (!(clk->flags & CONFIG_PARTICIPANT) && (clk->flags & RATE_CKCTL)) {
799                 if (clk == &dpll_ck)
800                         return omap2_reprogram_dpll(clk, rate);
801
802                 validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
803                 if (validrate != rate)
804                         return ret;
805
806                 div_addr = omap2_get_clksel(clk, &field_mask);
807                 if (div_addr == 0)
808                         return ret;
809
810                 field_val = omap2_divisor_to_clksel(clk, new_div);
811                 if (field_val == ~0)
812                         return ret;
813
814                 reg_val = cm_read_reg(div_addr);
815                 reg_val &= ~field_mask;
816                 reg_val |= (field_val << mask_to_shift(field_mask));
817                 cm_write_reg(reg_val, div_addr);
818                 wmb();
819                 clk->rate = clk->parent->rate / new_div;
820
821                 if (clk->flags & DELAYED_APP) {
822                         prm_write_reg(OMAP24XX_VALID_CONFIG,
823                                       OMAP24XX_PRCM_CLKCFG_CTRL);
824                         wmb();
825                 }
826                 ret = 0;
827         } else if (clk->set_rate != 0) {
828                 ret = clk->set_rate(clk, rate);
829         }
830
831         if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
832                 propagate_rate(clk);
833
834         return ret;
835 }
836
837 /*
838  * Converts encoded control register address into a full address
839  * On error, *src_addr will be returned as 0.
840  */
841 static u32 omap2_clksel_get_src_field(void __iomem **src_addr,
842                                       struct clk *src_clk, u32 *field_mask,
843                                       struct clk *clk, u32 *parent_div)
844 {
845         const struct clksel *clks;
846         const struct clksel_rate *clkr;
847
848         *parent_div = 0;
849         *src_addr = 0;
850
851         clks = omap2_get_clksel_by_parent(clk, src_clk);
852         if (clks == NULL)
853                 return 0;
854
855         for (clkr = clks->rates; clkr->div; clkr++) {
856                 if (clkr->flags & (cpu_mask | DEFAULT_RATE))
857                         break; /* Found the default rate for this platform */
858         }
859
860         if (!clkr->div) {
861                 printk(KERN_ERR "clock: Could not find default rate for "
862                        "clock %s parent %s\n", clk->name,
863                        src_clk->parent->name);
864                 return 0;
865         }
866
867         /* Should never happen.  Add a clksel mask to the struct clk. */
868         WARN_ON(clk->clksel_mask == 0);
869
870         *field_mask = clk->clksel_mask;
871         *src_addr = clk->clksel_reg;
872         *parent_div = clkr->div;
873
874         return clkr->val;
875 }
876
877 static int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
878 {
879         void __iomem *src_addr;
880         u32 field_val, field_mask, reg_val, parent_div;
881
882         if (unlikely(clk->flags & CONFIG_PARTICIPANT))
883                 return -EINVAL;
884
885         if (unlikely(!(clk->flags & SRC_SEL_MASK)))
886                 return -EINVAL;
887
888         field_val = omap2_clksel_get_src_field(&src_addr, new_parent,
889                                                &field_mask, clk, &parent_div);
890         if (src_addr == 0)
891                 return -EINVAL;
892
893         if (clk->usecount > 0)
894                 _omap2_clk_disable(clk);
895
896         /* Set new source value (previous dividers if any in effect) */
897         reg_val = __raw_readl(src_addr) & ~field_mask;
898         reg_val |= (field_val << mask_to_shift(field_mask));
899         __raw_writel(reg_val, src_addr);
900         wmb();
901
902         if (clk->flags & DELAYED_APP) {
903                 prm_write_reg(OMAP24XX_VALID_CONFIG,
904                               OMAP24XX_PRCM_CLKCFG_CTRL);
905                 wmb();
906         }
907
908         if (clk->usecount > 0)
909                 _omap2_clk_enable(clk);
910
911         clk->parent = new_parent;
912
913         /* SRC_RATE_SEL_MASK clocks follow their parents rates.*/
914         clk->rate = new_parent->rate;
915
916         if (parent_div > 0)
917                 clk->rate /= parent_div;
918
919         pr_debug("clock: set parent of %s to %s (new rate %ld)\n",
920                  clk->name, clk->parent->name, clk->rate);
921
922         if (unlikely(clk->flags & RATE_PROPAGATES))
923                 propagate_rate(clk);
924
925         return 0;
926 }
927
928 /* Sets basic clocks based on the specified rate */
929 static int omap2_select_table_rate(struct clk * clk, unsigned long rate)
930 {
931         u32 flags, cur_rate, done_rate, bypass = 0, tmp;
932         struct prcm_config *prcm;
933         unsigned long found_speed = 0;
934
935         if (clk != &virt_prcm_set)
936                 return -EINVAL;
937
938         for (prcm = rate_table; prcm->mpu_speed; prcm++) {
939                 if (!(prcm->flags & cpu_mask))
940                         continue;
941
942                 if (prcm->xtal_speed != sys_ck.rate)
943                         continue;
944
945                 if (prcm->mpu_speed <= rate) {
946                         found_speed = prcm->mpu_speed;
947                         break;
948                 }
949         }
950
951         if (!found_speed) {
952                 printk(KERN_INFO "Could not set MPU rate to %luMHz\n",
953                        rate / 1000000);
954                 return -EINVAL;
955         }
956
957         curr_prcm_set = prcm;
958         cur_rate = omap2_get_dpll_rate(&dpll_ck);
959
960         if (prcm->dpll_speed == cur_rate / 2) {
961                 omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL, 1);
962         } else if (prcm->dpll_speed == cur_rate * 2) {
963                 omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1);
964         } else if (prcm->dpll_speed != cur_rate) {
965                 local_irq_save(flags);
966
967                 if (prcm->dpll_speed == prcm->xtal_speed)
968                         bypass = 1;
969
970                 if ((prcm->cm_clksel2_pll & OMAP24XX_CORE_CLK_SRC_MASK) ==
971                     CORE_CLK_SRC_DPLL_X2)
972                         done_rate = CORE_CLK_SRC_DPLL_X2;
973                 else
974                         done_rate = CORE_CLK_SRC_DPLL;
975
976                 /* MPU divider */
977                 cm_write_mod_reg(prcm->cm_clksel_mpu, MPU_MOD, CM_CLKSEL);
978
979                 /* dsp + iva1 div(2420), iva2.1(2430) */
980                 cm_write_mod_reg(prcm->cm_clksel_dsp,
981                                  OMAP24XX_DSP_MOD, CM_CLKSEL);
982
983                 cm_write_mod_reg(prcm->cm_clksel_gfx, GFX_MOD, CM_CLKSEL);
984
985                 /* Major subsystem dividers */
986                 tmp = cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK;
987                 cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD, CM_CLKSEL1);
988                 if (cpu_is_omap2430())
989                         cm_write_mod_reg(prcm->cm_clksel_mdm,
990                                          OMAP2430_MDM_MOD, CM_CLKSEL);
991
992                 /* x2 to enter init_mem */
993                 omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1);
994
995                 omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr,
996                                bypass);
997
998                 omap2_init_memory_params(omap2_dll_force_needed());
999                 omap2_reprogram_sdrc(done_rate, 0);
1000
1001                 local_irq_restore(flags);
1002         }
1003         omap2_dpll_recalc(&dpll_ck);
1004
1005         return 0;
1006 }
1007
1008 /*-------------------------------------------------------------------------
1009  * Omap2 clock reset and init functions
1010  *-------------------------------------------------------------------------*/
1011
1012 #ifdef CONFIG_OMAP_RESET_CLOCKS
1013 static void __init omap2_clk_disable_unused(struct clk *clk)
1014 {
1015         u32 regval32;
1016
1017         regval32 = cm_read_reg(clk->enable_reg);
1018         if ((regval32 & (1 << clk->enable_bit)) == 0)
1019                 return;
1020
1021         printk(KERN_INFO "Disabling unused clock \"%s\"\n", clk->name);
1022         _omap2_clk_disable(clk);
1023 }
1024 #else
1025 #define omap2_clk_disable_unused        NULL
1026 #endif
1027
1028 static struct clk_functions omap2_clk_functions = {
1029         .clk_enable             = omap2_clk_enable,
1030         .clk_disable            = omap2_clk_disable,
1031         .clk_round_rate         = omap2_clk_round_rate,
1032         .clk_set_rate           = omap2_clk_set_rate,
1033         .clk_set_parent         = omap2_clk_set_parent,
1034         .clk_disable_unused     = omap2_clk_disable_unused,
1035 };
1036
1037 static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys)
1038 {
1039         u32 div, aplls, sclk = 13000000;
1040
1041         aplls = cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
1042         aplls &= OMAP24XX_APLLS_CLKIN_MASK;
1043         aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT;
1044
1045         if (aplls == APLLS_CLKIN_19_2MHZ)
1046                 sclk = 19200000;
1047         else if (aplls == APLLS_CLKIN_13MHZ)
1048                 sclk = 13000000;
1049         else if (aplls == APLLS_CLKIN_12MHZ)
1050                 sclk = 12000000;
1051
1052         div = prm_read_reg(OMAP24XX_PRCM_CLKSRC_CTRL);
1053         div &= OMAP_SYSCLKDIV_MASK;
1054         div >>= OMAP_SYSCLKDIV_SHIFT;
1055
1056         osc->rate = sclk * div;
1057         sys->rate = sclk;
1058 }
1059
1060 /*
1061  * Set clocks for bypass mode for reboot to work.
1062  */
1063 void omap2_clk_prepare_for_reboot(void)
1064 {
1065         u32 rate;
1066
1067         if (vclk == NULL || sclk == NULL)
1068                 return;
1069
1070         rate = clk_get_rate(sclk);
1071         clk_set_rate(vclk, rate);
1072 }
1073
1074 /*
1075  * Switch the MPU rate if specified on cmdline.
1076  * We cannot do this early until cmdline is parsed.
1077  */
1078 static int __init omap2_clk_arch_init(void)
1079 {
1080         if (!mpurate)
1081                 return -EINVAL;
1082
1083         if (omap2_select_table_rate(&virt_prcm_set, mpurate))
1084                 printk(KERN_ERR "Could not find matching MPU rate\n");
1085
1086         recalculate_root_clocks();
1087
1088         printk(KERN_INFO "Switched to new clocking rate (Crystal/DPLL/MPU): "
1089                "%ld.%01ld/%ld/%ld MHz\n",
1090                (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
1091                (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;
1092
1093         return 0;
1094 }
1095 arch_initcall(omap2_clk_arch_init);
1096
1097 int __init omap2_clk_init(void)
1098 {
1099         struct prcm_config *prcm;
1100         struct clk ** clkp;
1101         u32 clkrate;
1102
1103         if (cpu_is_omap242x())
1104                 cpu_mask = RATE_IN_242X;
1105         else if (cpu_is_omap2430())
1106                 cpu_mask = RATE_IN_243X;
1107
1108         clk_init(&omap2_clk_functions);
1109         omap2_get_crystal_rate(&osc_ck, &sys_ck);
1110
1111         for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
1112              clkp++) {
1113
1114                 if ((*clkp)->flags & CLOCK_IN_OMAP242X && cpu_is_omap2420()) {
1115                         clk_register(*clkp);
1116                         continue;
1117                 }
1118
1119                 if ((*clkp)->flags & CLOCK_IN_OMAP243X && (cpu_is_omap2430() || cpu_is_omap34xx())) {
1120                         clk_register(*clkp);
1121                         continue;
1122                 }
1123         }
1124
1125         /* Check the MPU rate set by bootloader */
1126         clkrate = omap2_get_dpll_rate(&dpll_ck);
1127         for (prcm = rate_table; prcm->mpu_speed; prcm++) {
1128                 if (!(prcm->flags & cpu_mask))
1129                         continue;
1130                 if (prcm->xtal_speed != sys_ck.rate)
1131                         continue;
1132                 if (prcm->dpll_speed <= clkrate)
1133                          break;
1134         }
1135         curr_prcm_set = prcm;
1136
1137         recalculate_root_clocks();
1138
1139         printk(KERN_INFO "Clocking rate (Crystal/DPLL/MPU): "
1140                "%ld.%01ld/%ld/%ld MHz\n",
1141                (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
1142                (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;
1143
1144         /*
1145          * Only enable those clocks we will need, let the drivers
1146          * enable other clocks as necessary
1147          */
1148         clk_enable(&sync_32k_ick);
1149         clk_enable(&omapctrl_ick);
1150
1151         /* Force the APLLs always active. The clocks are idled
1152          * automatically by hardware. */
1153         clk_enable(&apll96_ck);
1154         clk_enable(&apll54_ck);
1155
1156         if (cpu_is_omap2430())
1157                 clk_enable(&sdrc_ick);
1158
1159         /* Avoid sleeping sleeping during omap2_clk_prepare_for_reboot() */
1160         vclk = clk_get(NULL, "virt_prcm_set");
1161         sclk = clk_get(NULL, "sys_ck");
1162
1163         return 0;
1164 }