]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/mach-omap2/clock34xx.c
OMAP2/3 clock: use standard set_rate fn in omap2_clk_arch_init()
[linux-2.6-omap-h63xx.git] / arch / arm / mach-omap2 / clock34xx.c
1 /*
2  * OMAP3-specific clock framework functions
3  *
4  * Copyright (C) 2007-2008 Texas Instruments, Inc.
5  * Copyright (C) 2007-2008 Nokia Corporation
6  *
7  * Written by Paul Walmsley
8  * Testing and integration fixes by Jouni Högander
9  *
10  * Parts of this code are based on code written by
11  * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License version 2 as
15  * published by the Free Software Foundation.
16  */
17 #undef DEBUG
18
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 #include <linux/clk.h>
26 #include <linux/io.h>
27 #include <linux/limits.h>
28 #include <linux/bitops.h>
29
30 #include <mach/clock.h>
31 #include <mach/sram.h>
32 #include <asm/div64.h>
33
34 #include <mach/sdrc.h>
35 #include "clock.h"
36 #include "clock34xx.h"
37 #include "prm.h"
38 #include "prm-regbits-34xx.h"
39 #include "cm.h"
40 #include "cm-regbits-34xx.h"
41
42 /* CM_AUTOIDLE_PLL*.AUTO_* bit values */
43 #define DPLL_AUTOIDLE_DISABLE                   0x0
44 #define DPLL_AUTOIDLE_LOW_POWER_STOP            0x1
45
46 #define MAX_DPLL_WAIT_TRIES             1000000
47
48 /**
49  * omap3_dpll_recalc - recalculate DPLL rate
50  * @clk: DPLL struct clk
51  *
52  * Recalculate and propagate the DPLL rate.
53  */
54 static void omap3_dpll_recalc(struct clk *clk)
55 {
56         clk->rate = omap2_get_dpll_rate(clk);
57
58         propagate_rate(clk);
59 }
60
61 /* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */
62 static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits)
63 {
64         const struct dpll_data *dd;
65         u32 v;
66
67         dd = clk->dpll_data;
68
69         v = cm_read_mod_reg(clk->prcm_mod, dd->control_reg);
70         v &= ~dd->enable_mask;
71         v |= clken_bits << __ffs(dd->enable_mask);
72         cm_write_mod_reg(v, clk->prcm_mod, dd->control_reg);
73 }
74
75 /* _omap3_wait_dpll_status: wait for a DPLL to enter a specific state */
76 static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
77 {
78         const struct dpll_data *dd;
79         int i = 0;
80         int ret = -EINVAL;
81
82         dd = clk->dpll_data;
83
84         state <<= __ffs(dd->idlest_mask);
85
86         while (((cm_read_mod_reg(clk->prcm_mod, dd->idlest_reg)
87                  & dd->idlest_mask) != state) &&
88                i < MAX_DPLL_WAIT_TRIES) {
89                 i++;
90                 udelay(1);
91         }
92
93         if (i == MAX_DPLL_WAIT_TRIES) {
94                 printk(KERN_ERR "clock: %s failed transition to '%s'\n",
95                        clk->name, (state) ? "locked" : "bypassed");
96         } else {
97                 pr_debug("clock: %s transition to '%s' in %d loops\n",
98                          clk->name, (state) ? "locked" : "bypassed", i);
99
100                 ret = 0;
101         }
102
103         return ret;
104 }
105
106 /* From 3430 TRM ES2 4.7.6.2 */
107 static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n)
108 {
109         unsigned long fint;
110         u16 f = 0;
111
112         fint = clk->parent->rate / (n + 1);
113
114         pr_debug("clock: fint is %lu\n", fint);
115
116         if (fint >= 750000 && fint <= 1000000)
117                 f = 0x3;
118         else if (fint > 1000000 && fint <= 1250000)
119                 f = 0x4;
120         else if (fint > 1250000 && fint <= 1500000)
121                 f = 0x5;
122         else if (fint > 1500000 && fint <= 1750000)
123                 f = 0x6;
124         else if (fint > 1750000 && fint <= 2100000)
125                 f = 0x7;
126         else if (fint > 7500000 && fint <= 10000000)
127                 f = 0xB;
128         else if (fint > 10000000 && fint <= 12500000)
129                 f = 0xC;
130         else if (fint > 12500000 && fint <= 15000000)
131                 f = 0xD;
132         else if (fint > 15000000 && fint <= 17500000)
133                 f = 0xE;
134         else if (fint > 17500000 && fint <= 21000000)
135                 f = 0xF;
136         else
137                 pr_debug("clock: unknown freqsel setting for %d\n", n);
138
139         return f;
140 }
141
142 /* Non-CORE DPLL (e.g., DPLLs that do not control SDRC) clock functions */
143
144 /*
145  * _omap3_noncore_dpll_lock - instruct a DPLL to lock and wait for readiness
146  * @clk: pointer to a DPLL struct clk
147  *
148  * Instructs a non-CORE DPLL to lock.  Waits for the DPLL to report
149  * readiness before returning.  Will save and restore the DPLL's
150  * autoidle state across the enable, per the CDP code.  If the DPLL
151  * locked successfully, return 0; if the DPLL did not lock in the time
152  * allotted, or DPLL3 was passed in, return -EINVAL.
153  */
154 static int _omap3_noncore_dpll_lock(struct clk *clk)
155 {
156         u8 ai;
157         int r;
158
159         if (clk == &dpll3_ck)
160                 return -EINVAL;
161
162         pr_debug("clock: locking DPLL %s\n", clk->name);
163
164         ai = omap3_dpll_autoidle_read(clk);
165
166         omap3_dpll_deny_idle(clk);
167
168         _omap3_dpll_write_clken(clk, DPLL_LOCKED);
169
170         r = _omap3_wait_dpll_status(clk, 1);
171
172         if (ai)
173                 omap3_dpll_allow_idle(clk);
174
175         return r;
176 }
177
178 /*
179  * _omap3_noncore_dpll_bypass - instruct a DPLL to bypass and wait for readiness
180  * @clk: pointer to a DPLL struct clk
181  *
182  * Instructs a non-CORE DPLL to enter low-power bypass mode.  In
183  * bypass mode, the DPLL's rate is set equal to its parent clock's
184  * rate.  Waits for the DPLL to report readiness before returning.
185  * Will save and restore the DPLL's autoidle state across the enable,
186  * per the CDP code.  If the DPLL entered bypass mode successfully,
187  * return 0; if the DPLL did not enter bypass in the time allotted, or
188  * DPLL3 was passed in, or the DPLL does not support low-power bypass,
189  * return -EINVAL.
190  */
191 static int _omap3_noncore_dpll_bypass(struct clk *clk)
192 {
193         int r;
194         u8 ai;
195
196         if (clk == &dpll3_ck)
197                 return -EINVAL;
198
199         if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS)))
200                 return -EINVAL;
201
202         pr_debug("clock: configuring DPLL %s for low-power bypass\n",
203                  clk->name);
204
205         ai = omap3_dpll_autoidle_read(clk);
206
207         _omap3_dpll_write_clken(clk, DPLL_LOW_POWER_BYPASS);
208
209         r = _omap3_wait_dpll_status(clk, 0);
210
211         if (ai)
212                 omap3_dpll_allow_idle(clk);
213         else
214                 omap3_dpll_deny_idle(clk);
215
216         return r;
217 }
218
219 /*
220  * _omap3_noncore_dpll_stop - instruct a DPLL to stop
221  * @clk: pointer to a DPLL struct clk
222  *
223  * Instructs a non-CORE DPLL to enter low-power stop. Will save and
224  * restore the DPLL's autoidle state across the stop, per the CDP
225  * code.  If DPLL3 was passed in, or the DPLL does not support
226  * low-power stop, return -EINVAL; otherwise, return 0.
227  */
228 static int _omap3_noncore_dpll_stop(struct clk *clk)
229 {
230         u8 ai;
231
232         if (clk == &dpll3_ck)
233                 return -EINVAL;
234
235         if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_STOP)))
236                 return -EINVAL;
237
238         pr_debug("clock: stopping DPLL %s\n", clk->name);
239
240         ai = omap3_dpll_autoidle_read(clk);
241
242         _omap3_dpll_write_clken(clk, DPLL_LOW_POWER_STOP);
243
244         if (ai)
245                 omap3_dpll_allow_idle(clk);
246         else
247                 omap3_dpll_deny_idle(clk);
248
249         return 0;
250 }
251
252 /**
253  * omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode
254  * @clk: pointer to a DPLL struct clk
255  *
256  * Instructs a non-CORE DPLL to enable, e.g., to enter bypass or lock.
257  * The choice of modes depends on the DPLL's programmed rate: if it is
258  * the same as the DPLL's parent clock, it will enter bypass;
259  * otherwise, it will enter lock.  This code will wait for the DPLL to
260  * indicate readiness before returning, unless the DPLL takes too long
261  * to enter the target state.  Intended to be used as the struct clk's
262  * enable function.  If DPLL3 was passed in, or the DPLL does not
263  * support low-power stop, or if the DPLL took too long to enter
264  * bypass or lock, return -EINVAL; otherwise, return 0.
265  */
266 static int omap3_noncore_dpll_enable(struct clk *clk)
267 {
268         int r;
269         struct dpll_data *dd;
270
271         if (clk == &dpll3_ck)
272                 return -EINVAL;
273
274         dd = clk->dpll_data;
275         if (!dd)
276                 return -EINVAL;
277
278         if (clk->rate == dd->bypass_clk->rate)
279                 r = _omap3_noncore_dpll_bypass(clk);
280         else
281                 r = _omap3_noncore_dpll_lock(clk);
282
283         if (!r)
284                 clk->rate = omap2_get_dpll_rate(clk);
285
286         return r;
287 }
288
289 /**
290  * omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode
291  * @clk: pointer to a DPLL struct clk
292  *
293  * Instructs a non-CORE DPLL to enable, e.g., to enter bypass or lock.
294  * The choice of modes depends on the DPLL's programmed rate: if it is
295  * the same as the DPLL's parent clock, it will enter bypass;
296  * otherwise, it will enter lock.  This code will wait for the DPLL to
297  * indicate readiness before returning, unless the DPLL takes too long
298  * to enter the target state.  Intended to be used as the struct clk's
299  * enable function.  If DPLL3 was passed in, or the DPLL does not
300  * support low-power stop, or if the DPLL took too long to enter
301  * bypass or lock, return -EINVAL; otherwise, return 0.
302  */
303 static void omap3_noncore_dpll_disable(struct clk *clk)
304 {
305         if (clk == &dpll3_ck)
306                 return;
307
308         _omap3_noncore_dpll_stop(clk);
309 }
310
311
312 /* Non-CORE DPLL rate set code */
313
314 /*
315  * omap3_noncore_dpll_program - set non-core DPLL M,N values directly
316  * @clk: struct clk * of DPLL to set
317  * @m: DPLL multiplier to set
318  * @n: DPLL divider to set
319  * @freqsel: FREQSEL value to set
320  *
321  * Program the DPLL with the supplied M, N values, and wait for the DPLL to
322  * lock..  Returns -EINVAL upon error, or 0 upon success.
323  */
324 static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
325 {
326         struct dpll_data *dd;
327         u32 v;
328
329         if (!clk)
330                 return -EINVAL;
331
332         dd = clk->dpll_data;
333         if (!dd)
334                 return -EINVAL;
335
336         /*
337          * According to the 12-5 CDP code from TI, "Limitation 2.5"
338          * on 3430ES1 prevents us from changing DPLL multipliers or dividers
339          * on DPLL4.
340          */
341         if (omap_rev() == OMAP3430_REV_ES1_0 &&
342             !strcmp("dpll4_ck", clk->name)) {
343                 printk(KERN_ERR "clock: DPLL4 cannot change rate due to "
344                        "silicon 'Limitation 2.5' on 3430ES1.\n");
345                 return -EINVAL;
346         }
347
348         /* 3430 ES2 TRM: 4.7.6.9 DPLL Programming Sequence */
349         _omap3_noncore_dpll_bypass(clk);
350
351         /* Set jitter correction */
352         v = cm_read_mod_reg(clk->prcm_mod, dd->control_reg);
353         v &= ~dd->freqsel_mask;
354         v |= freqsel << __ffs(dd->freqsel_mask);
355         cm_write_mod_reg(v, clk->prcm_mod, dd->control_reg);
356
357         /* Set DPLL multiplier, divider */
358         v = cm_read_mod_reg(clk->prcm_mod, dd->mult_div1_reg);
359         v &= ~(dd->mult_mask | dd->div1_mask);
360         v |= m << __ffs(dd->mult_mask);
361         v |= (n - 1) << __ffs(dd->div1_mask);
362         cm_write_mod_reg(v, clk->prcm_mod, dd->mult_div1_reg);
363
364         /* We let the clock framework set the other output dividers later */
365
366         /* REVISIT: Set ramp-up delay? */
367
368         _omap3_noncore_dpll_lock(clk);
369
370         return 0;
371 }
372
373 /**
374  * omap3_noncore_dpll_set_rate - set non-core DPLL rate
375  * @clk: struct clk * of DPLL to set
376  * @rate: rounded target rate
377  *
378  * Set the DPLL CLKOUT to the target rate.  If the DPLL can enter
379  * low-power bypass, and the target rate is the bypass source clock
380  * rate, then configure the DPLL for bypass.  Otherwise, round the
381  * target rate if it hasn't been done already, then program and lock
382  * the DPLL.  Returns -EINVAL upon error, or 0 upon success.
383  */
384 static int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
385 {
386         u16 freqsel;
387         struct dpll_data *dd;
388         int ret;
389
390         if (!clk || !rate)
391                 return -EINVAL;
392
393         dd = clk->dpll_data;
394         if (!dd)
395                 return -EINVAL;
396
397         if (rate == omap2_get_dpll_rate(clk))
398                 return 0;
399
400         if (dd->bypass_clk->rate == rate &&
401             (clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
402
403                 pr_debug("clock: %s: set rate: entering bypass.\n", clk->name);
404
405                 ret = _omap3_noncore_dpll_bypass(clk);
406                 if (!ret)
407                         clk->rate = rate;
408
409         } else {
410
411                 if (dd->last_rounded_rate != rate)
412                         omap2_dpll_round_rate(clk, rate);
413
414                 if (dd->last_rounded_rate == 0)
415                         return -EINVAL;
416
417                 freqsel = _omap3_dpll_compute_freqsel(clk, dd->last_rounded_n);
418                 if (!freqsel)
419                         WARN_ON(1);
420
421                 pr_debug("clock: %s: set rate: locking rate to %lu.\n",
422                          clk->name, rate);
423
424                 ret = omap3_noncore_dpll_program(clk, dd->last_rounded_m,
425                                                  dd->last_rounded_n, freqsel);
426
427                 if (!ret)
428                         clk->rate = rate;
429
430         }
431
432         omap3_dpll_recalc(clk);
433
434         return 0;
435 }
436
437
438 /*
439  * CORE DPLL (DPLL3) rate programming functions
440  *
441  * These call into SRAM code to do the actual CM writes, since the SDRAM
442  * is clocked from DPLL3.
443  */
444
445 /**
446  * omap3_core_dpll_m2_set_rate - set CORE DPLL M2 divider
447  * @clk: struct clk * of DPLL to set
448  * @rate: rounded target rate
449  *
450  * Program the DPLL M2 divider with the rounded target rate.  Returns
451  * -EINVAL upon error, or 0 upon success.
452  */
453 static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
454 {
455         u32 new_div = 0;
456         unsigned long validrate, sdrcrate;
457         struct omap_sdrc_params *sp;
458
459         if (!clk || !rate)
460                 return -EINVAL;
461
462         if (clk != &dpll3_m2_ck)
463                 return -EINVAL;
464
465         if (rate == clk->rate)
466                 return 0;
467
468         validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
469         if (validrate != rate)
470                 return -EINVAL;
471
472         sdrcrate = sdrc_ick.rate;
473         if (rate > clk->rate)
474                 sdrcrate <<= ((rate / clk->rate) - 1);
475         else
476                 sdrcrate >>= ((clk->rate / rate) - 1);
477
478         sp = omap2_sdrc_get_params(sdrcrate);
479         if (!sp)
480                 return -EINVAL;
481
482         pr_info("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
483                 validrate);
484         pr_info("clock: SDRC timing params used: %08x %08x %08x\n",
485                 sp->rfr_ctrl, sp->actim_ctrla, sp->actim_ctrlb);
486
487         /* REVISIT: SRAM code doesn't support other M2 divisors yet */
488         WARN_ON(new_div != 1 && new_div != 2);
489
490         /* REVISIT: Add SDRC_MR changing to this code also */
491         local_irq_disable();
492         omap3_configure_core_dpll(sp->rfr_ctrl, sp->actim_ctrla,
493                                   sp->actim_ctrlb, new_div);
494         local_irq_enable();
495
496         omap2_clksel_recalc(clk);
497
498         return 0;
499 }
500
501
502 /* DPLL autoidle read/set code */
503
504
505 /**
506  * omap3_dpll_autoidle_read - read a DPLL's autoidle bits
507  * @clk: struct clk * of the DPLL to read
508  *
509  * Return the DPLL's autoidle bits, shifted down to bit 0.  Returns
510  * -EINVAL if passed a null pointer or if the struct clk does not
511  * appear to refer to a DPLL.
512  */
513 static u32 omap3_dpll_autoidle_read(struct clk *clk)
514 {
515         const struct dpll_data *dd;
516         u32 v;
517
518         if (!clk || !clk->dpll_data)
519                 return -EINVAL;
520
521         dd = clk->dpll_data;
522
523         v = cm_read_mod_reg(clk->prcm_mod, dd->autoidle_reg);
524         v &= dd->autoidle_mask;
525         v >>= __ffs(dd->autoidle_mask);
526
527         return v;
528 }
529
530 /**
531  * omap3_dpll_allow_idle - enable DPLL autoidle bits
532  * @clk: struct clk * of the DPLL to operate on
533  *
534  * Enable DPLL automatic idle control.  This automatic idle mode
535  * switching takes effect only when the DPLL is locked, at least on
536  * OMAP3430.  The DPLL will enter low-power stop when its downstream
537  * clocks are gated.  No return value.
538  */
539 static void omap3_dpll_allow_idle(struct clk *clk)
540 {
541         const struct dpll_data *dd;
542         u32 v;
543
544         if (!clk || !clk->dpll_data)
545                 return;
546
547         dd = clk->dpll_data;
548
549         /*
550          * REVISIT: CORE DPLL can optionally enter low-power bypass
551          * by writing 0x5 instead of 0x1.  Add some mechanism to
552          * optionally enter this mode.
553          */
554         v = cm_read_mod_reg(clk->prcm_mod, dd->autoidle_reg);
555         v &= ~dd->autoidle_mask;
556         v |= DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask);
557         cm_write_mod_reg(v, clk->prcm_mod, dd->autoidle_reg);
558 }
559
560 /**
561  * omap3_dpll_deny_idle - prevent DPLL from automatically idling
562  * @clk: struct clk * of the DPLL to operate on
563  *
564  * Disable DPLL automatic idle control.  No return value.
565  */
566 static void omap3_dpll_deny_idle(struct clk *clk)
567 {
568         const struct dpll_data *dd;
569         u32 v;
570
571         if (!clk || !clk->dpll_data)
572                 return;
573
574         dd = clk->dpll_data;
575
576         v = cm_read_mod_reg(clk->prcm_mod, dd->autoidle_reg);
577         v &= ~dd->autoidle_mask;
578         v |= DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask);
579         cm_write_mod_reg(v, clk->prcm_mod, dd->autoidle_reg);
580 }
581
582 /* Clock control for DPLL outputs */
583
584 /**
585  * omap3_clkoutx2_recalc - recalculate DPLL X2 output virtual clock rate
586  * @clk: DPLL output struct clk
587  *
588  * Using parent clock DPLL data, look up DPLL state.  If locked, set our
589  * rate to the dpll_clk * 2; otherwise, just use dpll_clk.
590  */
591 static void omap3_clkoutx2_recalc(struct clk *clk)
592 {
593         const struct dpll_data *dd;
594         u32 v;
595         struct clk *pclk;
596
597         /* Walk up the parents of clk, looking for a DPLL */
598         pclk = clk->parent;
599         while (pclk && !pclk->dpll_data)
600                 pclk = pclk->parent;
601
602         /* clk does not have a DPLL as a parent? */
603         WARN_ON(!pclk);
604
605         dd = pclk->dpll_data;
606
607         WARN_ON(!dd->enable_mask);
608
609         v = cm_read_mod_reg(pclk->prcm_mod, dd->control_reg) & dd->enable_mask;
610         v >>= __ffs(dd->enable_mask);
611         if (v != OMAP3XXX_EN_DPLL_LOCKED)
612                 clk->rate = clk->parent->rate;
613         else
614                 clk->rate = clk->parent->rate * 2;
615
616         if (clk->flags & RATE_PROPAGATES)
617                 propagate_rate(clk);
618 }
619
620 /* Common clock code */
621
622 /*
623  * As it is structured now, this will prevent an OMAP2/3 multiboot
624  * kernel from compiling.  This will need further attention.
625  */
626 #if defined(CONFIG_ARCH_OMAP3)
627
628 static struct clk_functions omap2_clk_functions = {
629         .clk_enable             = omap2_clk_enable,
630         .clk_disable            = omap2_clk_disable,
631         .clk_round_rate         = omap2_clk_round_rate,
632         .clk_set_rate           = omap2_clk_set_rate,
633         .clk_set_parent         = omap2_clk_set_parent,
634         .clk_get_parent         = omap2_clk_get_parent,
635         .clk_disable_unused     = omap2_clk_disable_unused,
636 };
637
638 /*
639  * Set clocks for bypass mode for reboot to work.
640  */
641 void omap2_clk_prepare_for_reboot(void)
642 {
643         /* REVISIT: Not ready for 343x */
644 #if 0
645         u32 rate;
646
647         if (vclk == NULL || sclk == NULL)
648                 return;
649
650         rate = clk_get_rate(sclk);
651         clk_set_rate(vclk, rate);
652 #endif
653 }
654
655 /* REVISIT: Move this init stuff out into clock.c */
656
657 /*
658  * Switch the MPU rate if specified on cmdline.
659  * We cannot do this early until cmdline is parsed.
660  */
661 static int __init omap2_clk_arch_init(void)
662 {
663         if (!mpurate)
664                 return -EINVAL;
665
666         /* REVISIT: not yet ready for 343x */
667 #if 0
668         if (clk_set_rate(&virt_prcm_set, mpurate))
669                 printk(KERN_ERR "Could not find matching MPU rate\n");
670 #endif
671
672         recalculate_root_clocks();
673
674         printk(KERN_INFO "Switched to new clocking rate (Crystal/DPLL3/MPU): "
675                "%ld.%01ld/%ld/%ld MHz\n",
676                (osc_sys_ck.rate / 1000000), (osc_sys_ck.rate / 100000) % 10,
677                (core_ck.rate / 1000000), (dpll1_fck.rate / 1000000)) ;
678
679         return 0;
680 }
681 arch_initcall(omap2_clk_arch_init);
682
683 int __init omap2_clk_init(void)
684 {
685         /* struct prcm_config *prcm; */
686         struct clk **clkp;
687         /* u32 clkrate; */
688         u32 cpu_clkflg;
689
690         /* REVISIT: Ultimately this will be used for multiboot */
691 #if 0
692         if (cpu_is_omap242x()) {
693                 cpu_mask = RATE_IN_242X;
694                 cpu_clkflg = CLOCK_IN_OMAP242X;
695                 clkp = onchip_24xx_clks;
696         } else if (cpu_is_omap2430()) {
697                 cpu_mask = RATE_IN_243X;
698                 cpu_clkflg = CLOCK_IN_OMAP243X;
699                 clkp = onchip_24xx_clks;
700         }
701 #endif
702         if (cpu_is_omap34xx()) {
703                 cpu_mask = RATE_IN_343X;
704                 cpu_clkflg = CLOCK_IN_OMAP343X;
705                 clkp = onchip_34xx_clks;
706
707                 /*
708                  * Update this if there are further clock changes between ES2
709                  * and production parts
710                  */
711                 if (omap_rev() == OMAP3430_REV_ES1_0) {
712                         /* No 3430ES1-only rates exist, so no RATE_IN_3430ES1 */
713                         cpu_clkflg |= CLOCK_IN_OMAP3430ES1;
714                 } else {
715                         cpu_mask |= RATE_IN_3430ES2;
716                         cpu_clkflg |= CLOCK_IN_OMAP3430ES2;
717                 }
718         }
719
720         clk_init(&omap2_clk_functions);
721
722         for (clkp = onchip_34xx_clks;
723              clkp < onchip_34xx_clks + ARRAY_SIZE(onchip_34xx_clks);
724              clkp++) {
725                 if ((*clkp)->flags & cpu_clkflg) {
726                         clk_register(*clkp);
727                         omap2_init_clk_clkdm(*clkp);
728                 }
729         }
730
731         /* REVISIT: Not yet ready for OMAP3 */
732 #if 0
733         /* Check the MPU rate set by bootloader */
734         clkrate = omap2_get_dpll_rate_24xx(&dpll_ck);
735         for (prcm = rate_table; prcm->mpu_speed; prcm++) {
736                 if (!(prcm->flags & cpu_mask))
737                         continue;
738                 if (prcm->xtal_speed != sys_ck.rate)
739                         continue;
740                 if (prcm->dpll_speed <= clkrate)
741                          break;
742         }
743         curr_prcm_set = prcm;
744 #endif
745
746         recalculate_root_clocks();
747
748         printk(KERN_INFO "Clocking rate (Crystal/DPLL/ARM core): "
749                "%ld.%01ld/%ld/%ld MHz\n",
750                (osc_sys_ck.rate / 1000000), (osc_sys_ck.rate / 100000) % 10,
751                (core_ck.rate / 1000000), (arm_fck.rate / 1000000));
752
753         /*
754          * Only enable those clocks we will need, let the drivers
755          * enable other clocks as necessary
756          */
757         clk_enable_init_clocks();
758
759         /* Avoid sleeping during omap2_clk_prepare_for_reboot() */
760         /* REVISIT: not yet ready for 343x */
761 #if 0
762         vclk = clk_get(NULL, "virt_prcm_set");
763         sclk = clk_get(NULL, "sys_ck");
764 #endif
765         return 0;
766 }
767
768 #endif