cpufreq.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. /*
  2. * cpu.c: clock scaling for the iMX
  3. *
  4. * Copyright (C) 2000 2001, The Delft University of Technology
  5. * Copyright (c) 2004 Sascha Hauer <sascha@saschahauer.de>
  6. * Copyright (C) 2006 Inky Lung <ilung@cwlinux.com>
  7. * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com>
  8. *
  9. * Based on SA1100 version written by:
  10. * - Johan Pouwelse (J.A.Pouwelse@its.tudelft.nl): initial version
  11. * - Erik Mouw (J.A.K.Mouw@its.tudelft.nl):
  12. *
  13. * This program is free software; you can redistribute it and/or modify
  14. * it under the terms of the GNU General Public License as published by
  15. * the Free Software Foundation; either version 2 of the License, or
  16. * (at your option) any later version.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program; if not, write to the Free Software
  25. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  26. *
  27. */
  28. /*#define DEBUG*/
  29. #include <linux/kernel.h>
  30. #include <linux/types.h>
  31. #include <linux/init.h>
  32. #include <linux/cpufreq.h>
  33. #include <asm/system.h>
  34. #include <asm/hardware.h>
  35. #include "generic.h"
  36. #ifndef __val2mfld
  37. #define __val2mfld(mask,val) (((mask)&~((mask)<<1))*(val)&(mask))
  38. #endif
  39. #ifndef __mfld2val
  40. #define __mfld2val(mask,val) (((val)&(mask))/((mask)&~((mask)<<1)))
  41. #endif
  42. #define CR_920T_CLOCK_MODE 0xC0000000
  43. #define CR_920T_FASTBUS_MODE 0x00000000
  44. #define CR_920T_ASYNC_MODE 0xC0000000
  45. static u32 mpctl0_at_boot;
  46. static u32 bclk_div_at_boot;
  47. static void imx_set_async_mode(void)
  48. {
  49. adjust_cr(CR_920T_CLOCK_MODE, CR_920T_ASYNC_MODE);
  50. }
  51. static void imx_set_fastbus_mode(void)
  52. {
  53. adjust_cr(CR_920T_CLOCK_MODE, CR_920T_FASTBUS_MODE);
  54. }
  55. static void imx_set_mpctl0(u32 mpctl0)
  56. {
  57. unsigned long flags;
  58. if (mpctl0 == 0) {
  59. local_irq_save(flags);
  60. CSCR &= ~CSCR_MPEN;
  61. local_irq_restore(flags);
  62. return;
  63. }
  64. local_irq_save(flags);
  65. MPCTL0 = mpctl0;
  66. CSCR |= CSCR_MPEN;
  67. local_irq_restore(flags);
  68. }
  69. /**
  70. * imx_compute_mpctl - compute new PLL parameters
  71. * @new_mpctl: pointer to location assigned by new PLL control register value
  72. * @cur_mpctl: current PLL control register parameters
  73. * @f_ref: reference source frequency Hz
  74. * @freq: required frequency in Hz
  75. * @relation: is one of %CPUFREQ_RELATION_L (supremum)
  76. * and %CPUFREQ_RELATION_H (infimum)
  77. */
  78. long imx_compute_mpctl(u32 *new_mpctl, u32 cur_mpctl, u32 f_ref, unsigned long freq, int relation)
  79. {
  80. u32 mfi;
  81. u32 mfn;
  82. u32 mfd;
  83. u32 pd;
  84. unsigned long long ll;
  85. long l;
  86. long quot;
  87. /* Fdppl=2*Fref*(MFI+MFN/(MFD+1))/(PD+1) */
  88. /* PD=<0,15>, MFD=<1,1023>, MFI=<5,15> MFN=<0,1022> */
  89. if (cur_mpctl) {
  90. mfd = ((cur_mpctl >> 16) & 0x3ff) + 1;
  91. pd = ((cur_mpctl >> 26) & 0xf) + 1;
  92. } else {
  93. pd=2; mfd=313;
  94. }
  95. /* pd=2; mfd=313; mfi=8; mfn=183; */
  96. /* (MFI+MFN/(MFD)) = Fdppl / (2*Fref) * (PD); */
  97. quot = (f_ref + (1 << 9)) >> 10;
  98. l = (freq * pd + quot) / (2 * quot);
  99. mfi = l >> 10;
  100. mfn = ((l & ((1 << 10) - 1)) * mfd + (1 << 9)) >> 10;
  101. mfd -= 1;
  102. pd -= 1;
  103. *new_mpctl = ((mfi & 0xf) << 10) | (mfn & 0x3ff) | ((mfd & 0x3ff) << 16)
  104. | ((pd & 0xf) << 26);
  105. ll = 2 * (unsigned long long)f_ref * ( (mfi<<16) + (mfn<<16) / (mfd+1) );
  106. quot = (pd+1) * (1<<16);
  107. ll += quot / 2;
  108. do_div(ll, quot);
  109. freq = ll;
  110. pr_debug(KERN_DEBUG "imx: new PLL parameters pd=%d mfd=%d mfi=%d mfn=%d, freq=%ld\n",
  111. pd, mfd, mfi, mfn, freq);
  112. return freq;
  113. }
  114. static int imx_verify_speed(struct cpufreq_policy *policy)
  115. {
  116. if (policy->cpu != 0)
  117. return -EINVAL;
  118. cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq);
  119. return 0;
  120. }
  121. static unsigned int imx_get_speed(unsigned int cpu)
  122. {
  123. unsigned int freq;
  124. unsigned int cr;
  125. unsigned int cscr;
  126. unsigned int bclk_div;
  127. if (cpu)
  128. return 0;
  129. cscr = CSCR;
  130. bclk_div = __mfld2val(CSCR_BCLK_DIV, cscr) + 1;
  131. cr = get_cr();
  132. if((cr & CR_920T_CLOCK_MODE) == CR_920T_FASTBUS_MODE) {
  133. freq = imx_get_system_clk();
  134. freq = (freq + bclk_div/2) / bclk_div;
  135. } else {
  136. freq = imx_get_mcu_clk();
  137. if (cscr & CSCR_MPU_PRESC)
  138. freq /= 2;
  139. }
  140. freq = (freq + 500) / 1000;
  141. return freq;
  142. }
  143. static int imx_set_target(struct cpufreq_policy *policy,
  144. unsigned int target_freq,
  145. unsigned int relation)
  146. {
  147. struct cpufreq_freqs freqs;
  148. u32 mpctl0 = 0;
  149. u32 cscr;
  150. unsigned long flags;
  151. long freq;
  152. long sysclk;
  153. unsigned int bclk_div = bclk_div_at_boot;
  154. /*
  155. * Some governors do not respects CPU and policy lower limits
  156. * which leads to bad things (division by zero etc), ensure
  157. * that such things do not happen.
  158. */
  159. if(target_freq < policy->cpuinfo.min_freq)
  160. target_freq = policy->cpuinfo.min_freq;
  161. if(target_freq < policy->min)
  162. target_freq = policy->min;
  163. freq = target_freq * 1000;
  164. pr_debug(KERN_DEBUG "imx: requested frequency %ld Hz, mpctl0 at boot 0x%08x\n",
  165. freq, mpctl0_at_boot);
  166. sysclk = imx_get_system_clk();
  167. if (freq > sysclk / bclk_div_at_boot + 1000000) {
  168. freq = imx_compute_mpctl(&mpctl0, mpctl0_at_boot, CLK32 * 512, freq, relation);
  169. if (freq < 0) {
  170. printk(KERN_WARNING "imx: target frequency %ld Hz cannot be set\n", freq);
  171. return -EINVAL;
  172. }
  173. } else {
  174. if(freq + 1000 < sysclk) {
  175. if (relation == CPUFREQ_RELATION_L)
  176. bclk_div = (sysclk - 1000) / freq;
  177. else
  178. bclk_div = (sysclk + freq + 1000) / freq;
  179. if(bclk_div > 16)
  180. bclk_div = 16;
  181. if(bclk_div < bclk_div_at_boot)
  182. bclk_div = bclk_div_at_boot;
  183. }
  184. freq = (sysclk + bclk_div / 2) / bclk_div;
  185. }
  186. freqs.old = imx_get_speed(0);
  187. freqs.new = (freq + 500) / 1000;
  188. freqs.cpu = 0;
  189. freqs.flags = 0;
  190. cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
  191. local_irq_save(flags);
  192. imx_set_fastbus_mode();
  193. imx_set_mpctl0(mpctl0);
  194. cscr = CSCR;
  195. cscr &= ~CSCR_BCLK_DIV;
  196. cscr |= __val2mfld(CSCR_BCLK_DIV, bclk_div - 1);
  197. CSCR = cscr;
  198. if(mpctl0) {
  199. CSCR |= CSCR_MPLL_RESTART;
  200. /* Wait until MPLL is stabilized */
  201. while( CSCR & CSCR_MPLL_RESTART );
  202. imx_set_async_mode();
  203. }
  204. local_irq_restore(flags);
  205. cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
  206. pr_debug(KERN_INFO "imx: set frequency %ld Hz, running from %s\n",
  207. freq, mpctl0? "MPLL": "SPLL");
  208. return 0;
  209. }
  210. static int __init imx_cpufreq_driver_init(struct cpufreq_policy *policy)
  211. {
  212. printk(KERN_INFO "i.MX cpu freq change driver v1.0\n");
  213. if (policy->cpu != 0)
  214. return -EINVAL;
  215. policy->cur = policy->min = policy->max = imx_get_speed(0);
  216. policy->cpuinfo.min_freq = 8000;
  217. policy->cpuinfo.max_freq = 200000;
  218. /* Manual states, that PLL stabilizes in two CLK32 periods */
  219. policy->cpuinfo.transition_latency = 4 * 1000000000LL / CLK32;
  220. return 0;
  221. }
  222. static struct cpufreq_driver imx_driver = {
  223. .flags = CPUFREQ_STICKY,
  224. .verify = imx_verify_speed,
  225. .target = imx_set_target,
  226. .get = imx_get_speed,
  227. .init = imx_cpufreq_driver_init,
  228. .name = "imx",
  229. };
  230. static int __init imx_cpufreq_init(void)
  231. {
  232. bclk_div_at_boot = __mfld2val(CSCR_BCLK_DIV, CSCR) + 1;
  233. mpctl0_at_boot = 0;
  234. if((CSCR & CSCR_MPEN) &&
  235. ((get_cr() & CR_920T_CLOCK_MODE) != CR_920T_FASTBUS_MODE))
  236. mpctl0_at_boot = MPCTL0;
  237. return cpufreq_register_driver(&imx_driver);
  238. }
  239. arch_initcall(imx_cpufreq_init);