xref: /openbmc/linux/arch/arm/mach-omap2/clock.c (revision fde0fd49)
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 #include <linux/clk.h>
26 
27 #include <asm/io.h>
28 
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_enable(struct clk *clk)
171 {
172 	int ret = 0;
173 
174 	if (clk->usecount++ == 0) {
175 		if (likely((u32)clk->parent))
176 			ret = omap2_clk_enable(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_disable(clk->parent);
187 			clk->usecount--;
188 		}
189 	}
190 
191 	return ret;
192 }
193 
194 static void omap2_clk_disable(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_disable(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_round_rate		= omap2_clk_round_rate,
1003 	.clk_set_rate		= omap2_clk_set_rate,
1004 	.clk_set_parent		= omap2_clk_set_parent,
1005 };
1006 
1007 static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys)
1008 {
1009 	u32 div, aplls, sclk = 13000000;
1010 
1011 	aplls = CM_CLKSEL1_PLL;
1012 	aplls &= ((1 << 23) | (1 << 24) | (1 << 25));
1013 	aplls >>= 23;			/* Isolate field, 0,2,3 */
1014 
1015 	if (aplls == 0)
1016 		sclk = 19200000;
1017 	else if (aplls == 2)
1018 		sclk = 13000000;
1019 	else if (aplls == 3)
1020 		sclk = 12000000;
1021 
1022 	div = PRCM_CLKSRC_CTRL;
1023 	div &= ((1 << 7) | (1 << 6));
1024 	div >>= sys->rate_offset;
1025 
1026 	osc->rate = sclk * div;
1027 	sys->rate = sclk;
1028 }
1029 
1030 #ifdef CONFIG_OMAP_RESET_CLOCKS
1031 static void __init omap2_disable_unused_clocks(void)
1032 {
1033 	struct clk *ck;
1034 	u32 regval32;
1035 
1036 	list_for_each_entry(ck, &clocks, node) {
1037 		if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) ||
1038 			ck->enable_reg == 0)
1039 			continue;
1040 
1041 		regval32 = __raw_readl(ck->enable_reg);
1042 		if ((regval32 & (1 << ck->enable_bit)) == 0)
1043 			continue;
1044 
1045 		printk(KERN_INFO "Disabling unused clock \"%s\"\n", ck->name);
1046 		_omap2_clk_disable(ck);
1047 	}
1048 }
1049 late_initcall(omap2_disable_unused_clocks);
1050 #endif
1051 
1052 /*
1053  * Switch the MPU rate if specified on cmdline.
1054  * We cannot do this early until cmdline is parsed.
1055  */
1056 static int __init omap2_clk_arch_init(void)
1057 {
1058 	if (!mpurate)
1059 		return -EINVAL;
1060 
1061 	if (omap2_select_table_rate(&virt_prcm_set, mpurate))
1062 		printk(KERN_ERR "Could not find matching MPU rate\n");
1063 
1064 	propagate_rate(&osc_ck);		/* update main root fast */
1065 	propagate_rate(&func_32k_ck);		/* update main root slow */
1066 
1067 	printk(KERN_INFO "Switched to new clocking rate (Crystal/DPLL/MPU): "
1068 	       "%ld.%01ld/%ld/%ld MHz\n",
1069 	       (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
1070 	       (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;
1071 
1072 	return 0;
1073 }
1074 arch_initcall(omap2_clk_arch_init);
1075 
1076 int __init omap2_clk_init(void)
1077 {
1078 	struct prcm_config *prcm;
1079 	struct clk ** clkp;
1080 	u32 clkrate;
1081 
1082 	clk_init(&omap2_clk_functions);
1083 	omap2_get_crystal_rate(&osc_ck, &sys_ck);
1084 
1085 	for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
1086 	     clkp++) {
1087 
1088 		if ((*clkp)->flags & CLOCK_IN_OMAP242X && cpu_is_omap2420()) {
1089 			clk_register(*clkp);
1090 			continue;
1091 		}
1092 
1093 		if ((*clkp)->flags & CLOCK_IN_OMAP243X && cpu_is_omap2430()) {
1094 			clk_register(*clkp);
1095 			continue;
1096 		}
1097 	}
1098 
1099 	/* Check the MPU rate set by bootloader */
1100 	clkrate = omap2_get_dpll_rate(&dpll_ck);
1101 	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
1102 		if (prcm->xtal_speed != sys_ck.rate)
1103 			continue;
1104 		if (prcm->dpll_speed <= clkrate)
1105 			 break;
1106 	}
1107 	curr_prcm_set = prcm;
1108 
1109 	propagate_rate(&osc_ck);		/* update main root fast */
1110 	propagate_rate(&func_32k_ck);		/* update main root slow */
1111 
1112 	printk(KERN_INFO "Clocking rate (Crystal/DPLL/MPU): "
1113 	       "%ld.%01ld/%ld/%ld MHz\n",
1114 	       (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
1115 	       (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;
1116 
1117 	/*
1118 	 * Only enable those clocks we will need, let the drivers
1119 	 * enable other clocks as necessary
1120 	 */
1121 	clk_enable(&sync_32k_ick);
1122 	clk_enable(&omapctrl_ick);
1123 	if (cpu_is_omap2430())
1124 		clk_enable(&sdrc_ick);
1125 
1126 	return 0;
1127 }
1128