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