clkt_dflt.c 8.9 KB

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