clock34xx.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. /*
  2. * OMAP3-specific clock framework functions
  3. *
  4. * Copyright (C) 2007-2008 Texas Instruments, Inc.
  5. * Copyright (C) 2007-2009 Nokia Corporation
  6. *
  7. * Written by Paul Walmsley
  8. * Testing and integration fixes by Jouni Högander
  9. *
  10. * Parts of this code are based on code written by
  11. * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
  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 version 2 as
  15. * published by the Free Software Foundation.
  16. */
  17. #undef DEBUG
  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. #include <linux/io.h>
  26. #include <linux/limits.h>
  27. #include <linux/bitops.h>
  28. #include <plat/cpu.h>
  29. #include <plat/clock.h>
  30. #include <plat/sram.h>
  31. #include <plat/sdrc.h>
  32. #include <asm/div64.h>
  33. #include <asm/clkdev.h>
  34. #include "clock.h"
  35. #include "clock34xx.h"
  36. #include "sdrc.h"
  37. #include "prm.h"
  38. #include "prm-regbits-34xx.h"
  39. #include "cm.h"
  40. #include "cm-regbits-34xx.h"
  41. #define CYCLES_PER_MHZ 1000000
  42. /*
  43. * DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks
  44. * that are sourced by DPLL5, and both of these require this clock
  45. * to be at 120 MHz for proper operation.
  46. */
  47. #define DPLL5_FREQ_FOR_USBHOST 120000000
  48. /* needed by omap3_core_dpll_m2_set_rate() */
  49. struct clk *sdrc_ick_p, *arm_fck_p;
  50. /**
  51. * omap3430es2_clk_ssi_find_idlest - return CM_IDLEST info for SSI
  52. * @clk: struct clk * being enabled
  53. * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
  54. * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
  55. *
  56. * The OMAP3430ES2 SSI target CM_IDLEST bit is at a different shift
  57. * from the CM_{I,F}CLKEN bit. Pass back the correct info via
  58. * @idlest_reg and @idlest_bit. No return value.
  59. */
  60. static void omap3430es2_clk_ssi_find_idlest(struct clk *clk,
  61. void __iomem **idlest_reg,
  62. u8 *idlest_bit)
  63. {
  64. u32 r;
  65. r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
  66. *idlest_reg = (__force void __iomem *)r;
  67. *idlest_bit = OMAP3430ES2_ST_SSI_IDLE_SHIFT;
  68. }
  69. const struct clkops clkops_omap3430es2_ssi_wait = {
  70. .enable = omap2_dflt_clk_enable,
  71. .disable = omap2_dflt_clk_disable,
  72. .find_idlest = omap3430es2_clk_ssi_find_idlest,
  73. .find_companion = omap2_clk_dflt_find_companion,
  74. };
  75. /**
  76. * omap3430es2_clk_dss_usbhost_find_idlest - CM_IDLEST info for DSS, USBHOST
  77. * @clk: struct clk * being enabled
  78. * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
  79. * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
  80. *
  81. * Some OMAP modules on OMAP3 ES2+ chips have both initiator and
  82. * target IDLEST bits. For our purposes, we are concerned with the
  83. * target IDLEST bits, which exist at a different bit position than
  84. * the *CLKEN bit position for these modules (DSS and USBHOST) (The
  85. * default find_idlest code assumes that they are at the same
  86. * position.) No return value.
  87. */
  88. static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk *clk,
  89. void __iomem **idlest_reg,
  90. u8 *idlest_bit)
  91. {
  92. u32 r;
  93. r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
  94. *idlest_reg = (__force void __iomem *)r;
  95. /* USBHOST_IDLE has same shift */
  96. *idlest_bit = OMAP3430ES2_ST_DSS_IDLE_SHIFT;
  97. }
  98. const struct clkops clkops_omap3430es2_dss_usbhost_wait = {
  99. .enable = omap2_dflt_clk_enable,
  100. .disable = omap2_dflt_clk_disable,
  101. .find_idlest = omap3430es2_clk_dss_usbhost_find_idlest,
  102. .find_companion = omap2_clk_dflt_find_companion,
  103. };
  104. /**
  105. * omap3430es2_clk_hsotgusb_find_idlest - return CM_IDLEST info for HSOTGUSB
  106. * @clk: struct clk * being enabled
  107. * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
  108. * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
  109. *
  110. * The OMAP3430ES2 HSOTGUSB target CM_IDLEST bit is at a different
  111. * shift from the CM_{I,F}CLKEN bit. Pass back the correct info via
  112. * @idlest_reg and @idlest_bit. No return value.
  113. */
  114. static void omap3430es2_clk_hsotgusb_find_idlest(struct clk *clk,
  115. void __iomem **idlest_reg,
  116. u8 *idlest_bit)
  117. {
  118. u32 r;
  119. r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
  120. *idlest_reg = (__force void __iomem *)r;
  121. *idlest_bit = OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT;
  122. }
  123. const struct clkops clkops_omap3430es2_hsotgusb_wait = {
  124. .enable = omap2_dflt_clk_enable,
  125. .disable = omap2_dflt_clk_disable,
  126. .find_idlest = omap3430es2_clk_hsotgusb_find_idlest,
  127. .find_companion = omap2_clk_dflt_find_companion,
  128. };
  129. const struct clkops clkops_noncore_dpll_ops = {
  130. .enable = omap3_noncore_dpll_enable,
  131. .disable = omap3_noncore_dpll_disable,
  132. };
  133. int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
  134. {
  135. /*
  136. * According to the 12-5 CDP code from TI, "Limitation 2.5"
  137. * on 3430ES1 prevents us from changing DPLL multipliers or dividers
  138. * on DPLL4.
  139. */
  140. if (omap_rev() == OMAP3430_REV_ES1_0) {
  141. printk(KERN_ERR "clock: DPLL4 cannot change rate due to "
  142. "silicon 'Limitation 2.5' on 3430ES1.\n");
  143. return -EINVAL;
  144. }
  145. return omap3_noncore_dpll_set_rate(clk, rate);
  146. }
  147. /*
  148. * CORE DPLL (DPLL3) rate programming functions
  149. *
  150. * These call into SRAM code to do the actual CM writes, since the SDRAM
  151. * is clocked from DPLL3.
  152. */
  153. /**
  154. * omap3_core_dpll_m2_set_rate - set CORE DPLL M2 divider
  155. * @clk: struct clk * of DPLL to set
  156. * @rate: rounded target rate
  157. *
  158. * Program the DPLL M2 divider with the rounded target rate. Returns
  159. * -EINVAL upon error, or 0 upon success.
  160. */
  161. int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
  162. {
  163. u32 new_div = 0;
  164. u32 unlock_dll = 0;
  165. u32 c;
  166. unsigned long validrate, sdrcrate, _mpurate;
  167. struct omap_sdrc_params *sdrc_cs0;
  168. struct omap_sdrc_params *sdrc_cs1;
  169. int ret;
  170. if (!clk || !rate)
  171. return -EINVAL;
  172. validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
  173. if (validrate != rate)
  174. return -EINVAL;
  175. sdrcrate = sdrc_ick_p->rate;
  176. if (rate > clk->rate)
  177. sdrcrate <<= ((rate / clk->rate) >> 1);
  178. else
  179. sdrcrate >>= ((clk->rate / rate) >> 1);
  180. ret = omap2_sdrc_get_params(sdrcrate, &sdrc_cs0, &sdrc_cs1);
  181. if (ret)
  182. return -EINVAL;
  183. if (sdrcrate < MIN_SDRC_DLL_LOCK_FREQ) {
  184. pr_debug("clock: will unlock SDRC DLL\n");
  185. unlock_dll = 1;
  186. }
  187. /*
  188. * XXX This only needs to be done when the CPU frequency changes
  189. */
  190. _mpurate = arm_fck_p->rate / CYCLES_PER_MHZ;
  191. c = (_mpurate << SDRC_MPURATE_SCALE) >> SDRC_MPURATE_BASE_SHIFT;
  192. c += 1; /* for safety */
  193. c *= SDRC_MPURATE_LOOPS;
  194. c >>= SDRC_MPURATE_SCALE;
  195. if (c == 0)
  196. c = 1;
  197. pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
  198. validrate);
  199. pr_debug("clock: SDRC CS0 timing params used:"
  200. " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
  201. sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
  202. sdrc_cs0->actim_ctrlb, sdrc_cs0->mr);
  203. if (sdrc_cs1)
  204. pr_debug("clock: SDRC CS1 timing params used: "
  205. " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
  206. sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
  207. sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
  208. if (sdrc_cs1)
  209. omap3_configure_core_dpll(
  210. new_div, unlock_dll, c, rate > clk->rate,
  211. sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
  212. sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
  213. sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
  214. sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
  215. else
  216. omap3_configure_core_dpll(
  217. new_div, unlock_dll, c, rate > clk->rate,
  218. sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
  219. sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
  220. 0, 0, 0, 0);
  221. return 0;
  222. }
  223. /* Common clock code */
  224. /*
  225. * As it is structured now, this will prevent an OMAP2/3 multiboot
  226. * kernel from compiling. This will need further attention.
  227. */
  228. #if defined(CONFIG_ARCH_OMAP3)
  229. struct clk_functions omap2_clk_functions = {
  230. .clk_enable = omap2_clk_enable,
  231. .clk_disable = omap2_clk_disable,
  232. .clk_round_rate = omap2_clk_round_rate,
  233. .clk_set_rate = omap2_clk_set_rate,
  234. .clk_set_parent = omap2_clk_set_parent,
  235. .clk_disable_unused = omap2_clk_disable_unused,
  236. };
  237. /*
  238. * Set clocks for bypass mode for reboot to work.
  239. */
  240. void omap2_clk_prepare_for_reboot(void)
  241. {
  242. /* REVISIT: Not ready for 343x */
  243. #if 0
  244. u32 rate;
  245. if (vclk == NULL || sclk == NULL)
  246. return;
  247. rate = clk_get_rate(sclk);
  248. clk_set_rate(vclk, rate);
  249. #endif
  250. }
  251. void omap3_clk_lock_dpll5(void)
  252. {
  253. struct clk *dpll5_clk;
  254. struct clk *dpll5_m2_clk;
  255. dpll5_clk = clk_get(NULL, "dpll5_ck");
  256. clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST);
  257. clk_enable(dpll5_clk);
  258. /* Enable autoidle to allow it to enter low power bypass */
  259. omap3_dpll_allow_idle(dpll5_clk);
  260. /* Program dpll5_m2_clk divider for no division */
  261. dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck");
  262. clk_enable(dpll5_m2_clk);
  263. clk_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST);
  264. clk_disable(dpll5_m2_clk);
  265. clk_disable(dpll5_clk);
  266. return;
  267. }
  268. /* REVISIT: Move this init stuff out into clock.c */
  269. /*
  270. * Switch the MPU rate if specified on cmdline.
  271. * We cannot do this early until cmdline is parsed.
  272. */
  273. static int __init omap2_clk_arch_init(void)
  274. {
  275. struct clk *osc_sys_ck, *dpll1_ck, *arm_fck, *core_ck;
  276. unsigned long osc_sys_rate;
  277. if (!mpurate)
  278. return -EINVAL;
  279. /* XXX test these for success */
  280. dpll1_ck = clk_get(NULL, "dpll1_ck");
  281. arm_fck = clk_get(NULL, "arm_fck");
  282. core_ck = clk_get(NULL, "core_ck");
  283. osc_sys_ck = clk_get(NULL, "osc_sys_ck");
  284. /* REVISIT: not yet ready for 343x */
  285. if (clk_set_rate(dpll1_ck, mpurate))
  286. printk(KERN_ERR "*** Unable to set MPU rate\n");
  287. recalculate_root_clocks();
  288. osc_sys_rate = clk_get_rate(osc_sys_ck);
  289. pr_info("Switched to new clocking rate (Crystal/Core/MPU): "
  290. "%ld.%01ld/%ld/%ld MHz\n",
  291. (osc_sys_rate / 1000000),
  292. ((osc_sys_rate / 100000) % 10),
  293. (clk_get_rate(core_ck) / 1000000),
  294. (clk_get_rate(arm_fck) / 1000000));
  295. calibrate_delay();
  296. return 0;
  297. }
  298. arch_initcall(omap2_clk_arch_init);
  299. #endif