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