clkt_dflt.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. /*
  2. * Default clock type
  3. *
  4. * Copyright (C) 2005-2008, 2015 Texas Instruments, Inc.
  5. * Copyright (C) 2004-2010 Nokia Corporation
  6. *
  7. * Contacts:
  8. * Richard Woodruff <r-woodruff2@ti.com>
  9. * Paul Walmsley
  10. * Tero Kristo <t-kristo@ti.com>
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License version 2 as
  14. * published by the Free Software Foundation.
  15. *
  16. * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  17. * kind, whether express or implied; without even the implied warranty
  18. * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. */
  21. #include <linux/kernel.h>
  22. #include <linux/errno.h>
  23. #include <linux/clk-provider.h>
  24. #include <linux/io.h>
  25. #include <linux/clk/ti.h>
  26. #include <linux/delay.h>
  27. #include "clock.h"
  28. /*
  29. * MAX_MODULE_ENABLE_WAIT: maximum of number of microseconds to wait
  30. * for a module to indicate that it is no longer in idle
  31. */
  32. #define MAX_MODULE_ENABLE_WAIT 100000
  33. /*
  34. * CM module register offsets, used for calculating the companion
  35. * register addresses.
  36. */
  37. #define CM_FCLKEN 0x0000
  38. #define CM_ICLKEN 0x0010
  39. /**
  40. * _wait_idlest_generic - wait for a module to leave the idle state
  41. * @clk: module clock to wait for (needed for register offsets)
  42. * @reg: virtual address of module IDLEST register
  43. * @mask: value to mask against to determine if the module is active
  44. * @idlest: idle state indicator (0 or 1) for the clock
  45. * @name: name of the clock (for printk)
  46. *
  47. * Wait for a module to leave idle, where its idle-status register is
  48. * not inside the CM module. Returns 1 if the module left idle
  49. * promptly, or 0 if the module did not leave idle before the timeout
  50. * elapsed. XXX Deprecated - should be moved into drivers for the
  51. * individual IP block that the IDLEST register exists in.
  52. */
  53. static int _wait_idlest_generic(struct clk_hw_omap *clk, void __iomem *reg,
  54. u32 mask, u8 idlest, const char *name)
  55. {
  56. int i = 0, ena = 0;
  57. ena = (idlest) ? 0 : mask;
  58. /* Wait until module enters enabled state */
  59. for (i = 0; i < MAX_MODULE_ENABLE_WAIT; i++) {
  60. if ((ti_clk_ll_ops->clk_readl(reg) & mask) == ena)
  61. break;
  62. udelay(1);
  63. }
  64. if (i < MAX_MODULE_ENABLE_WAIT)
  65. pr_debug("omap clock: module associated with clock %s ready after %d loops\n",
  66. name, i);
  67. else
  68. pr_err("omap clock: module associated with clock %s didn't enable in %d tries\n",
  69. name, MAX_MODULE_ENABLE_WAIT);
  70. return (i < MAX_MODULE_ENABLE_WAIT) ? 1 : 0;
  71. }
  72. /**
  73. * _omap2_module_wait_ready - wait for an OMAP module to leave IDLE
  74. * @clk: struct clk * belonging to the module
  75. *
  76. * If the necessary clocks for the OMAP hardware IP block that
  77. * corresponds to clock @clk are enabled, then wait for the module to
  78. * indicate readiness (i.e., to leave IDLE). This code does not
  79. * belong in the clock code and will be moved in the medium term to
  80. * module-dependent code. No return value.
  81. */
  82. static void _omap2_module_wait_ready(struct clk_hw_omap *clk)
  83. {
  84. void __iomem *companion_reg, *idlest_reg;
  85. u8 other_bit, idlest_bit, idlest_val, idlest_reg_id;
  86. s16 prcm_mod;
  87. int r;
  88. /* Not all modules have multiple clocks that their IDLEST depends on */
  89. if (clk->ops->find_companion) {
  90. clk->ops->find_companion(clk, &companion_reg, &other_bit);
  91. if (!(ti_clk_ll_ops->clk_readl(companion_reg) &
  92. (1 << other_bit)))
  93. return;
  94. }
  95. clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit, &idlest_val);
  96. r = ti_clk_ll_ops->cm_split_idlest_reg(idlest_reg, &prcm_mod,
  97. &idlest_reg_id);
  98. if (r) {
  99. /* IDLEST register not in the CM module */
  100. _wait_idlest_generic(clk, idlest_reg, (1 << idlest_bit),
  101. idlest_val, clk_hw_get_name(&clk->hw));
  102. } else {
  103. ti_clk_ll_ops->cm_wait_module_ready(0, prcm_mod, idlest_reg_id,
  104. idlest_bit);
  105. }
  106. }
  107. /**
  108. * omap2_clk_dflt_find_companion - find companion clock to @clk
  109. * @clk: struct clk * to find the companion clock of
  110. * @other_reg: void __iomem ** to return the companion clock CM_*CLKEN va in
  111. * @other_bit: u8 ** to return the companion clock bit shift in
  112. *
  113. * Note: We don't need special code here for INVERT_ENABLE for the
  114. * time being since INVERT_ENABLE only applies to clocks enabled by
  115. * CM_CLKEN_PLL
  116. *
  117. * Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes it's
  118. * just a matter of XORing the bits.
  119. *
  120. * Some clocks don't have companion clocks. For example, modules with
  121. * only an interface clock (such as MAILBOXES) don't have a companion
  122. * clock. Right now, this code relies on the hardware exporting a bit
  123. * in the correct companion register that indicates that the
  124. * nonexistent 'companion clock' is active. Future patches will
  125. * associate this type of code with per-module data structures to
  126. * avoid this issue, and remove the casts. No return value.
  127. */
  128. void omap2_clk_dflt_find_companion(struct clk_hw_omap *clk,
  129. void __iomem **other_reg, u8 *other_bit)
  130. {
  131. u32 r;
  132. /*
  133. * Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes
  134. * it's just a matter of XORing the bits.
  135. */
  136. r = ((__force u32)clk->enable_reg ^ (CM_FCLKEN ^ CM_ICLKEN));
  137. *other_reg = (__force void __iomem *)r;
  138. *other_bit = clk->enable_bit;
  139. }
  140. /**
  141. * omap2_clk_dflt_find_idlest - find CM_IDLEST reg va, bit shift for @clk
  142. * @clk: struct clk * to find IDLEST info for
  143. * @idlest_reg: void __iomem ** to return the CM_IDLEST va in
  144. * @idlest_bit: u8 * to return the CM_IDLEST bit shift in
  145. * @idlest_val: u8 * to return the idle status indicator
  146. *
  147. * Return the CM_IDLEST register address and bit shift corresponding
  148. * to the module that "owns" this clock. This default code assumes
  149. * that the CM_IDLEST bit shift is the CM_*CLKEN bit shift, and that
  150. * the IDLEST register address ID corresponds to the CM_*CLKEN
  151. * register address ID (e.g., that CM_FCLKEN2 corresponds to
  152. * CM_IDLEST2). This is not true for all modules. No return value.
  153. */
  154. void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk,
  155. void __iomem **idlest_reg, u8 *idlest_bit,
  156. u8 *idlest_val)
  157. {
  158. u32 r;
  159. r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
  160. *idlest_reg = (__force void __iomem *)r;
  161. *idlest_bit = clk->enable_bit;
  162. /*
  163. * 24xx uses 0 to indicate not ready, and 1 to indicate ready.
  164. * 34xx reverses this, just to keep us on our toes
  165. * AM35xx uses both, depending on the module.
  166. */
  167. *idlest_val = ti_clk_get_features()->cm_idlest_val;
  168. }
  169. /**
  170. * omap2_dflt_clk_enable - enable a clock in the hardware
  171. * @hw: struct clk_hw * of the clock to enable
  172. *
  173. * Enable the clock @hw in the hardware. We first call into the OMAP
  174. * clockdomain code to "enable" the corresponding clockdomain if this
  175. * is the first enabled user of the clockdomain. Then program the
  176. * hardware to enable the clock. Then wait for the IP block that uses
  177. * this clock to leave idle (if applicable). Returns the error value
  178. * from clkdm_clk_enable() if it terminated with an error, or -EINVAL
  179. * if @hw has a null clock enable_reg, or zero upon success.
  180. */
  181. int omap2_dflt_clk_enable(struct clk_hw *hw)
  182. {
  183. struct clk_hw_omap *clk;
  184. u32 v;
  185. int ret = 0;
  186. bool clkdm_control;
  187. if (ti_clk_get_features()->flags & TI_CLK_DISABLE_CLKDM_CONTROL)
  188. clkdm_control = false;
  189. else
  190. clkdm_control = true;
  191. clk = to_clk_hw_omap(hw);
  192. if (clkdm_control && clk->clkdm) {
  193. ret = ti_clk_ll_ops->clkdm_clk_enable(clk->clkdm, hw->clk);
  194. if (ret) {
  195. WARN(1,
  196. "%s: could not enable %s's clockdomain %s: %d\n",
  197. __func__, clk_hw_get_name(hw),
  198. clk->clkdm_name, ret);
  199. return ret;
  200. }
  201. }
  202. if (IS_ERR(clk->enable_reg)) {
  203. pr_err("%s: %s missing enable_reg\n", __func__,
  204. clk_hw_get_name(hw));
  205. ret = -EINVAL;
  206. goto err;
  207. }
  208. /* FIXME should not have INVERT_ENABLE bit here */
  209. v = ti_clk_ll_ops->clk_readl(clk->enable_reg);
  210. if (clk->flags & INVERT_ENABLE)
  211. v &= ~(1 << clk->enable_bit);
  212. else
  213. v |= (1 << clk->enable_bit);
  214. ti_clk_ll_ops->clk_writel(v, clk->enable_reg);
  215. v = ti_clk_ll_ops->clk_readl(clk->enable_reg); /* OCP barrier */
  216. if (clk->ops && clk->ops->find_idlest)
  217. _omap2_module_wait_ready(clk);
  218. return 0;
  219. err:
  220. if (clkdm_control && clk->clkdm)
  221. ti_clk_ll_ops->clkdm_clk_disable(clk->clkdm, hw->clk);
  222. return ret;
  223. }
  224. /**
  225. * omap2_dflt_clk_disable - disable a clock in the hardware
  226. * @hw: struct clk_hw * of the clock to disable
  227. *
  228. * Disable the clock @hw in the hardware, and call into the OMAP
  229. * clockdomain code to "disable" the corresponding clockdomain if all
  230. * clocks/hwmods in that clockdomain are now disabled. No return
  231. * value.
  232. */
  233. void omap2_dflt_clk_disable(struct clk_hw *hw)
  234. {
  235. struct clk_hw_omap *clk;
  236. u32 v;
  237. clk = to_clk_hw_omap(hw);
  238. if (IS_ERR(clk->enable_reg)) {
  239. /*
  240. * 'independent' here refers to a clock which is not
  241. * controlled by its parent.
  242. */
  243. pr_err("%s: independent clock %s has no enable_reg\n",
  244. __func__, clk_hw_get_name(hw));
  245. return;
  246. }
  247. v = ti_clk_ll_ops->clk_readl(clk->enable_reg);
  248. if (clk->flags & INVERT_ENABLE)
  249. v |= (1 << clk->enable_bit);
  250. else
  251. v &= ~(1 << clk->enable_bit);
  252. ti_clk_ll_ops->clk_writel(v, clk->enable_reg);
  253. /* No OCP barrier needed here since it is a disable operation */
  254. if (!(ti_clk_get_features()->flags & TI_CLK_DISABLE_CLKDM_CONTROL) &&
  255. clk->clkdm)
  256. ti_clk_ll_ops->clkdm_clk_disable(clk->clkdm, hw->clk);
  257. }
  258. /**
  259. * omap2_dflt_clk_is_enabled - is clock enabled in the hardware?
  260. * @hw: struct clk_hw * to check
  261. *
  262. * Return 1 if the clock represented by @hw is enabled in the
  263. * hardware, or 0 otherwise. Intended for use in the struct
  264. * clk_ops.is_enabled function pointer.
  265. */
  266. int omap2_dflt_clk_is_enabled(struct clk_hw *hw)
  267. {
  268. struct clk_hw_omap *clk = to_clk_hw_omap(hw);
  269. u32 v;
  270. v = ti_clk_ll_ops->clk_readl(clk->enable_reg);
  271. if (clk->flags & INVERT_ENABLE)
  272. v ^= BIT(clk->enable_bit);
  273. v &= BIT(clk->enable_bit);
  274. return v ? 1 : 0;
  275. }
  276. const struct clk_hw_omap_ops clkhwops_wait = {
  277. .find_idlest = omap2_clk_dflt_find_idlest,
  278. .find_companion = omap2_clk_dflt_find_companion,
  279. };