xref: /openbmc/linux/arch/arm/mach-omap1/clock.c (revision b6dcefde)
1 /*
2  *  linux/arch/arm/mach-omap1/clock.c
3  *
4  *  Copyright (C) 2004 - 2005, 2009 Nokia corporation
5  *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
6  *
7  *  Modified to use omap shared clock framework by
8  *  Tony Lindgren <tony@atomide.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  */
14 #include <linux/module.h>
15 #include <linux/kernel.h>
16 #include <linux/list.h>
17 #include <linux/errno.h>
18 #include <linux/err.h>
19 #include <linux/clk.h>
20 #include <linux/io.h>
21 
22 #include <asm/mach-types.h>
23 #include <asm/clkdev.h>
24 
25 #include <plat/cpu.h>
26 #include <plat/usb.h>
27 #include <plat/clock.h>
28 #include <plat/sram.h>
29 #include <plat/clkdev_omap.h>
30 
31 #include "clock.h"
32 #include "opp.h"
33 
34 __u32 arm_idlect1_mask;
35 struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;
36 
37 /*-------------------------------------------------------------------------
38  * Omap1 specific clock functions
39  *-------------------------------------------------------------------------*/
40 
41 static int clk_omap1_dummy_enable(struct clk *clk)
42 {
43 	return 0;
44 }
45 
46 static void clk_omap1_dummy_disable(struct clk *clk)
47 {
48 }
49 
50 const struct clkops clkops_dummy = {
51 	.enable		= clk_omap1_dummy_enable,
52 	.disable	= clk_omap1_dummy_disable,
53 };
54 
55 /* XXX can be replaced with a fixed_divisor_recalc */
56 unsigned long omap1_watchdog_recalc(struct clk *clk)
57 {
58 	return clk->parent->rate / 14;
59 }
60 
61 unsigned long omap1_uart_recalc(struct clk *clk)
62 {
63 	unsigned int val = __raw_readl(clk->enable_reg);
64 	return val & clk->enable_bit ? 48000000 : 12000000;
65 }
66 
67 unsigned long omap1_sossi_recalc(struct clk *clk)
68 {
69 	u32 div = omap_readl(MOD_CONF_CTRL_1);
70 
71 	div = (div >> 17) & 0x7;
72 	div++;
73 
74 	return clk->parent->rate / div;
75 }
76 
77 static void omap1_clk_allow_idle(struct clk *clk)
78 {
79 	struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;
80 
81 	if (!(clk->flags & CLOCK_IDLE_CONTROL))
82 		return;
83 
84 	if (iclk->no_idle_count > 0 && !(--iclk->no_idle_count))
85 		arm_idlect1_mask |= 1 << iclk->idlect_shift;
86 }
87 
88 static void omap1_clk_deny_idle(struct clk *clk)
89 {
90 	struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;
91 
92 	if (!(clk->flags & CLOCK_IDLE_CONTROL))
93 		return;
94 
95 	if (iclk->no_idle_count++ == 0)
96 		arm_idlect1_mask &= ~(1 << iclk->idlect_shift);
97 }
98 
99 static __u16 verify_ckctl_value(__u16 newval)
100 {
101 	/* This function checks for following limitations set
102 	 * by the hardware (all conditions must be true):
103 	 * DSPMMU_CK == DSP_CK  or  DSPMMU_CK == DSP_CK/2
104 	 * ARM_CK >= TC_CK
105 	 * DSP_CK >= TC_CK
106 	 * DSPMMU_CK >= TC_CK
107 	 *
108 	 * In addition following rules are enforced:
109 	 * LCD_CK <= TC_CK
110 	 * ARMPER_CK <= TC_CK
111 	 *
112 	 * However, maximum frequencies are not checked for!
113 	 */
114 	__u8 per_exp;
115 	__u8 lcd_exp;
116 	__u8 arm_exp;
117 	__u8 dsp_exp;
118 	__u8 tc_exp;
119 	__u8 dspmmu_exp;
120 
121 	per_exp = (newval >> CKCTL_PERDIV_OFFSET) & 3;
122 	lcd_exp = (newval >> CKCTL_LCDDIV_OFFSET) & 3;
123 	arm_exp = (newval >> CKCTL_ARMDIV_OFFSET) & 3;
124 	dsp_exp = (newval >> CKCTL_DSPDIV_OFFSET) & 3;
125 	tc_exp = (newval >> CKCTL_TCDIV_OFFSET) & 3;
126 	dspmmu_exp = (newval >> CKCTL_DSPMMUDIV_OFFSET) & 3;
127 
128 	if (dspmmu_exp < dsp_exp)
129 		dspmmu_exp = dsp_exp;
130 	if (dspmmu_exp > dsp_exp+1)
131 		dspmmu_exp = dsp_exp+1;
132 	if (tc_exp < arm_exp)
133 		tc_exp = arm_exp;
134 	if (tc_exp < dspmmu_exp)
135 		tc_exp = dspmmu_exp;
136 	if (tc_exp > lcd_exp)
137 		lcd_exp = tc_exp;
138 	if (tc_exp > per_exp)
139 		per_exp = tc_exp;
140 
141 	newval &= 0xf000;
142 	newval |= per_exp << CKCTL_PERDIV_OFFSET;
143 	newval |= lcd_exp << CKCTL_LCDDIV_OFFSET;
144 	newval |= arm_exp << CKCTL_ARMDIV_OFFSET;
145 	newval |= dsp_exp << CKCTL_DSPDIV_OFFSET;
146 	newval |= tc_exp << CKCTL_TCDIV_OFFSET;
147 	newval |= dspmmu_exp << CKCTL_DSPMMUDIV_OFFSET;
148 
149 	return newval;
150 }
151 
152 static int calc_dsor_exp(struct clk *clk, unsigned long rate)
153 {
154 	/* Note: If target frequency is too low, this function will return 4,
155 	 * which is invalid value. Caller must check for this value and act
156 	 * accordingly.
157 	 *
158 	 * Note: This function does not check for following limitations set
159 	 * by the hardware (all conditions must be true):
160 	 * DSPMMU_CK == DSP_CK  or  DSPMMU_CK == DSP_CK/2
161 	 * ARM_CK >= TC_CK
162 	 * DSP_CK >= TC_CK
163 	 * DSPMMU_CK >= TC_CK
164 	 */
165 	unsigned long realrate;
166 	struct clk * parent;
167 	unsigned  dsor_exp;
168 
169 	parent = clk->parent;
170 	if (unlikely(parent == NULL))
171 		return -EIO;
172 
173 	realrate = parent->rate;
174 	for (dsor_exp=0; dsor_exp<4; dsor_exp++) {
175 		if (realrate <= rate)
176 			break;
177 
178 		realrate /= 2;
179 	}
180 
181 	return dsor_exp;
182 }
183 
184 unsigned long omap1_ckctl_recalc(struct clk *clk)
185 {
186 	/* Calculate divisor encoded as 2-bit exponent */
187 	int dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
188 
189 	return clk->parent->rate / dsor;
190 }
191 
192 unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk)
193 {
194 	int dsor;
195 
196 	/* Calculate divisor encoded as 2-bit exponent
197 	 *
198 	 * The clock control bits are in DSP domain,
199 	 * so api_ck is needed for access.
200 	 * Note that DSP_CKCTL virt addr = phys addr, so
201 	 * we must use __raw_readw() instead of omap_readw().
202 	 */
203 	omap1_clk_enable(api_ck_p);
204 	dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset));
205 	omap1_clk_disable(api_ck_p);
206 
207 	return clk->parent->rate / dsor;
208 }
209 
210 /* MPU virtual clock functions */
211 int omap1_select_table_rate(struct clk *clk, unsigned long rate)
212 {
213 	/* Find the highest supported frequency <= rate and switch to it */
214 	struct mpu_rate * ptr;
215 	unsigned long dpll1_rate, ref_rate;
216 
217 	dpll1_rate = ck_dpll1_p->rate;
218 	ref_rate = ck_ref_p->rate;
219 
220 	for (ptr = omap1_rate_table; ptr->rate; ptr++) {
221 		if (ptr->xtal != ref_rate)
222 			continue;
223 
224 		/* DPLL1 cannot be reprogrammed without risking system crash */
225 		if (likely(dpll1_rate != 0) && ptr->pll_rate != dpll1_rate)
226 			continue;
227 
228 		/* Can check only after xtal frequency check */
229 		if (ptr->rate <= rate)
230 			break;
231 	}
232 
233 	if (!ptr->rate)
234 		return -EINVAL;
235 
236 	/*
237 	 * In most cases we should not need to reprogram DPLL.
238 	 * Reprogramming the DPLL is tricky, it must be done from SRAM.
239 	 * (on 730, bit 13 must always be 1)
240 	 */
241 	if (cpu_is_omap7xx())
242 		omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val | 0x2000);
243 	else
244 		omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val);
245 
246 	/* XXX Do we need to recalculate the tree below DPLL1 at this point? */
247 	ck_dpll1_p->rate = ptr->pll_rate;
248 
249 	return 0;
250 }
251 
252 int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate)
253 {
254 	int dsor_exp;
255 	u16 regval;
256 
257 	dsor_exp = calc_dsor_exp(clk, rate);
258 	if (dsor_exp > 3)
259 		dsor_exp = -EINVAL;
260 	if (dsor_exp < 0)
261 		return dsor_exp;
262 
263 	regval = __raw_readw(DSP_CKCTL);
264 	regval &= ~(3 << clk->rate_offset);
265 	regval |= dsor_exp << clk->rate_offset;
266 	__raw_writew(regval, DSP_CKCTL);
267 	clk->rate = clk->parent->rate / (1 << dsor_exp);
268 
269 	return 0;
270 }
271 
272 long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate)
273 {
274 	int dsor_exp = calc_dsor_exp(clk, rate);
275 	if (dsor_exp < 0)
276 		return dsor_exp;
277 	if (dsor_exp > 3)
278 		dsor_exp = 3;
279 	return clk->parent->rate / (1 << dsor_exp);
280 }
281 
282 int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate)
283 {
284 	int dsor_exp;
285 	u16 regval;
286 
287 	dsor_exp = calc_dsor_exp(clk, rate);
288 	if (dsor_exp > 3)
289 		dsor_exp = -EINVAL;
290 	if (dsor_exp < 0)
291 		return dsor_exp;
292 
293 	regval = omap_readw(ARM_CKCTL);
294 	regval &= ~(3 << clk->rate_offset);
295 	regval |= dsor_exp << clk->rate_offset;
296 	regval = verify_ckctl_value(regval);
297 	omap_writew(regval, ARM_CKCTL);
298 	clk->rate = clk->parent->rate / (1 << dsor_exp);
299 	return 0;
300 }
301 
302 long omap1_round_to_table_rate(struct clk *clk, unsigned long rate)
303 {
304 	/* Find the highest supported frequency <= rate */
305 	struct mpu_rate * ptr;
306 	long highest_rate;
307 	unsigned long ref_rate;
308 
309 	ref_rate = ck_ref_p->rate;
310 
311 	highest_rate = -EINVAL;
312 
313 	for (ptr = omap1_rate_table; ptr->rate; ptr++) {
314 		if (ptr->xtal != ref_rate)
315 			continue;
316 
317 		highest_rate = ptr->rate;
318 
319 		/* Can check only after xtal frequency check */
320 		if (ptr->rate <= rate)
321 			break;
322 	}
323 
324 	return highest_rate;
325 }
326 
327 static unsigned calc_ext_dsor(unsigned long rate)
328 {
329 	unsigned dsor;
330 
331 	/* MCLK and BCLK divisor selection is not linear:
332 	 * freq = 96MHz / dsor
333 	 *
334 	 * RATIO_SEL range: dsor <-> RATIO_SEL
335 	 * 0..6: (RATIO_SEL+2) <-> (dsor-2)
336 	 * 6..48:  (8+(RATIO_SEL-6)*2) <-> ((dsor-8)/2+6)
337 	 * Minimum dsor is 2 and maximum is 96. Odd divisors starting from 9
338 	 * can not be used.
339 	 */
340 	for (dsor = 2; dsor < 96; ++dsor) {
341 		if ((dsor & 1) && dsor > 8)
342 			continue;
343 		if (rate >= 96000000 / dsor)
344 			break;
345 	}
346 	return dsor;
347 }
348 
349 /* XXX Only needed on 1510 */
350 int omap1_set_uart_rate(struct clk *clk, unsigned long rate)
351 {
352 	unsigned int val;
353 
354 	val = __raw_readl(clk->enable_reg);
355 	if (rate == 12000000)
356 		val &= ~(1 << clk->enable_bit);
357 	else if (rate == 48000000)
358 		val |= (1 << clk->enable_bit);
359 	else
360 		return -EINVAL;
361 	__raw_writel(val, clk->enable_reg);
362 	clk->rate = rate;
363 
364 	return 0;
365 }
366 
367 /* External clock (MCLK & BCLK) functions */
368 int omap1_set_ext_clk_rate(struct clk *clk, unsigned long rate)
369 {
370 	unsigned dsor;
371 	__u16 ratio_bits;
372 
373 	dsor = calc_ext_dsor(rate);
374 	clk->rate = 96000000 / dsor;
375 	if (dsor > 8)
376 		ratio_bits = ((dsor - 8) / 2 + 6) << 2;
377 	else
378 		ratio_bits = (dsor - 2) << 2;
379 
380 	ratio_bits |= __raw_readw(clk->enable_reg) & ~0xfd;
381 	__raw_writew(ratio_bits, clk->enable_reg);
382 
383 	return 0;
384 }
385 
386 int omap1_set_sossi_rate(struct clk *clk, unsigned long rate)
387 {
388 	u32 l;
389 	int div;
390 	unsigned long p_rate;
391 
392 	p_rate = clk->parent->rate;
393 	/* Round towards slower frequency */
394 	div = (p_rate + rate - 1) / rate;
395 	div--;
396 	if (div < 0 || div > 7)
397 		return -EINVAL;
398 
399 	l = omap_readl(MOD_CONF_CTRL_1);
400 	l &= ~(7 << 17);
401 	l |= div << 17;
402 	omap_writel(l, MOD_CONF_CTRL_1);
403 
404 	clk->rate = p_rate / (div + 1);
405 
406 	return 0;
407 }
408 
409 long omap1_round_ext_clk_rate(struct clk *clk, unsigned long rate)
410 {
411 	return 96000000 / calc_ext_dsor(rate);
412 }
413 
414 void omap1_init_ext_clk(struct clk *clk)
415 {
416 	unsigned dsor;
417 	__u16 ratio_bits;
418 
419 	/* Determine current rate and ensure clock is based on 96MHz APLL */
420 	ratio_bits = __raw_readw(clk->enable_reg) & ~1;
421 	__raw_writew(ratio_bits, clk->enable_reg);
422 
423 	ratio_bits = (ratio_bits & 0xfc) >> 2;
424 	if (ratio_bits > 6)
425 		dsor = (ratio_bits - 6) * 2 + 8;
426 	else
427 		dsor = ratio_bits + 2;
428 
429 	clk-> rate = 96000000 / dsor;
430 }
431 
432 int omap1_clk_enable(struct clk *clk)
433 {
434 	int ret = 0;
435 
436 	if (clk->usecount++ == 0) {
437 		if (clk->parent) {
438 			ret = omap1_clk_enable(clk->parent);
439 			if (ret)
440 				goto err;
441 
442 			if (clk->flags & CLOCK_NO_IDLE_PARENT)
443 				omap1_clk_deny_idle(clk->parent);
444 		}
445 
446 		ret = clk->ops->enable(clk);
447 		if (ret) {
448 			if (clk->parent)
449 				omap1_clk_disable(clk->parent);
450 			goto err;
451 		}
452 	}
453 	return ret;
454 
455 err:
456 	clk->usecount--;
457 	return ret;
458 }
459 
460 void omap1_clk_disable(struct clk *clk)
461 {
462 	if (clk->usecount > 0 && !(--clk->usecount)) {
463 		clk->ops->disable(clk);
464 		if (likely(clk->parent)) {
465 			omap1_clk_disable(clk->parent);
466 			if (clk->flags & CLOCK_NO_IDLE_PARENT)
467 				omap1_clk_allow_idle(clk->parent);
468 		}
469 	}
470 }
471 
472 static int omap1_clk_enable_generic(struct clk *clk)
473 {
474 	__u16 regval16;
475 	__u32 regval32;
476 
477 	if (unlikely(clk->enable_reg == NULL)) {
478 		printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
479 		       clk->name);
480 		return -EINVAL;
481 	}
482 
483 	if (clk->flags & ENABLE_REG_32BIT) {
484 		regval32 = __raw_readl(clk->enable_reg);
485 		regval32 |= (1 << clk->enable_bit);
486 		__raw_writel(regval32, clk->enable_reg);
487 	} else {
488 		regval16 = __raw_readw(clk->enable_reg);
489 		regval16 |= (1 << clk->enable_bit);
490 		__raw_writew(regval16, clk->enable_reg);
491 	}
492 
493 	return 0;
494 }
495 
496 static void omap1_clk_disable_generic(struct clk *clk)
497 {
498 	__u16 regval16;
499 	__u32 regval32;
500 
501 	if (clk->enable_reg == NULL)
502 		return;
503 
504 	if (clk->flags & ENABLE_REG_32BIT) {
505 		regval32 = __raw_readl(clk->enable_reg);
506 		regval32 &= ~(1 << clk->enable_bit);
507 		__raw_writel(regval32, clk->enable_reg);
508 	} else {
509 		regval16 = __raw_readw(clk->enable_reg);
510 		regval16 &= ~(1 << clk->enable_bit);
511 		__raw_writew(regval16, clk->enable_reg);
512 	}
513 }
514 
515 const struct clkops clkops_generic = {
516 	.enable		= omap1_clk_enable_generic,
517 	.disable	= omap1_clk_disable_generic,
518 };
519 
520 static int omap1_clk_enable_dsp_domain(struct clk *clk)
521 {
522 	int retval;
523 
524 	retval = omap1_clk_enable(api_ck_p);
525 	if (!retval) {
526 		retval = omap1_clk_enable_generic(clk);
527 		omap1_clk_disable(api_ck_p);
528 	}
529 
530 	return retval;
531 }
532 
533 static void omap1_clk_disable_dsp_domain(struct clk *clk)
534 {
535 	if (omap1_clk_enable(api_ck_p) == 0) {
536 		omap1_clk_disable_generic(clk);
537 		omap1_clk_disable(api_ck_p);
538 	}
539 }
540 
541 const struct clkops clkops_dspck = {
542 	.enable		= omap1_clk_enable_dsp_domain,
543 	.disable	= omap1_clk_disable_dsp_domain,
544 };
545 
546 static int omap1_clk_enable_uart_functional(struct clk *clk)
547 {
548 	int ret;
549 	struct uart_clk *uclk;
550 
551 	ret = omap1_clk_enable_generic(clk);
552 	if (ret == 0) {
553 		/* Set smart idle acknowledgement mode */
554 		uclk = (struct uart_clk *)clk;
555 		omap_writeb((omap_readb(uclk->sysc_addr) & ~0x10) | 8,
556 			    uclk->sysc_addr);
557 	}
558 
559 	return ret;
560 }
561 
562 static void omap1_clk_disable_uart_functional(struct clk *clk)
563 {
564 	struct uart_clk *uclk;
565 
566 	/* Set force idle acknowledgement mode */
567 	uclk = (struct uart_clk *)clk;
568 	omap_writeb((omap_readb(uclk->sysc_addr) & ~0x18), uclk->sysc_addr);
569 
570 	omap1_clk_disable_generic(clk);
571 }
572 
573 const struct clkops clkops_uart = {
574 	.enable		= omap1_clk_enable_uart_functional,
575 	.disable	= omap1_clk_disable_uart_functional,
576 };
577 
578 long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
579 {
580 	if (clk->flags & RATE_FIXED)
581 		return clk->rate;
582 
583 	if (clk->round_rate != NULL)
584 		return clk->round_rate(clk, rate);
585 
586 	return clk->rate;
587 }
588 
589 int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
590 {
591 	int  ret = -EINVAL;
592 
593 	if (clk->set_rate)
594 		ret = clk->set_rate(clk, rate);
595 	return ret;
596 }
597 
598 /*-------------------------------------------------------------------------
599  * Omap1 clock reset and init functions
600  *-------------------------------------------------------------------------*/
601 
602 #ifdef CONFIG_OMAP_RESET_CLOCKS
603 
604 void __init omap1_clk_disable_unused(struct clk *clk)
605 {
606 	__u32 regval32;
607 
608 	/* Clocks in the DSP domain need api_ck. Just assume bootloader
609 	 * has not enabled any DSP clocks */
610 	if (clk->enable_reg == DSP_IDLECT2) {
611 		printk(KERN_INFO "Skipping reset check for DSP domain "
612 		       "clock \"%s\"\n", clk->name);
613 		return;
614 	}
615 
616 	/* Is the clock already disabled? */
617 	if (clk->flags & ENABLE_REG_32BIT)
618 		regval32 = __raw_readl(clk->enable_reg);
619 	else
620 		regval32 = __raw_readw(clk->enable_reg);
621 
622 	if ((regval32 & (1 << clk->enable_bit)) == 0)
623 		return;
624 
625 	printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name);
626 	clk->ops->disable(clk);
627 	printk(" done\n");
628 }
629 
630 #endif
631