clk-pxa.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /*
  2. * Marvell PXA family clocks
  3. *
  4. * Copyright (C) 2014 Robert Jarzmik
  5. *
  6. * Common clock code for PXA clocks ("CKEN" type clocks + DT)
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; version 2 of the License.
  11. *
  12. */
  13. #include <linux/clk.h>
  14. #include <linux/clk-provider.h>
  15. #include <linux/clkdev.h>
  16. #include <linux/of.h>
  17. #include <dt-bindings/clock/pxa-clock.h>
  18. #include "clk-pxa.h"
  19. #define KHz 1000
  20. #define MHz (1000 * 1000)
  21. #define MDREFR_K0DB4 (1 << 29) /* SDCLK0 Divide by 4 Control/Status */
  22. #define MDREFR_K2FREE (1 << 25) /* SDRAM Free-Running Control */
  23. #define MDREFR_K1FREE (1 << 24) /* SDRAM Free-Running Control */
  24. #define MDREFR_K0FREE (1 << 23) /* SDRAM Free-Running Control */
  25. #define MDREFR_SLFRSH (1 << 22) /* SDRAM Self-Refresh Control/Status */
  26. #define MDREFR_APD (1 << 20) /* SDRAM/SSRAM Auto-Power-Down Enable */
  27. #define MDREFR_K2DB2 (1 << 19) /* SDCLK2 Divide by 2 Control/Status */
  28. #define MDREFR_K2RUN (1 << 18) /* SDCLK2 Run Control/Status */
  29. #define MDREFR_K1DB2 (1 << 17) /* SDCLK1 Divide by 2 Control/Status */
  30. #define MDREFR_K1RUN (1 << 16) /* SDCLK1 Run Control/Status */
  31. #define MDREFR_E1PIN (1 << 15) /* SDCKE1 Level Control/Status */
  32. #define MDREFR_K0DB2 (1 << 14) /* SDCLK0 Divide by 2 Control/Status */
  33. #define MDREFR_K0RUN (1 << 13) /* SDCLK0 Run Control/Status */
  34. #define MDREFR_E0PIN (1 << 12) /* SDCKE0 Level Control/Status */
  35. #define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2)
  36. #define MDREFR_DRI_MASK 0xFFF
  37. static DEFINE_SPINLOCK(pxa_clk_lock);
  38. static struct clk *pxa_clocks[CLK_MAX];
  39. static struct clk_onecell_data onecell_data = {
  40. .clks = pxa_clocks,
  41. .clk_num = CLK_MAX,
  42. };
  43. struct pxa_clk {
  44. struct clk_hw hw;
  45. struct clk_fixed_factor lp;
  46. struct clk_fixed_factor hp;
  47. struct clk_gate gate;
  48. bool (*is_in_low_power)(void);
  49. };
  50. #define to_pxa_clk(_hw) container_of(_hw, struct pxa_clk, hw)
  51. static unsigned long cken_recalc_rate(struct clk_hw *hw,
  52. unsigned long parent_rate)
  53. {
  54. struct pxa_clk *pclk = to_pxa_clk(hw);
  55. struct clk_fixed_factor *fix;
  56. if (!pclk->is_in_low_power || pclk->is_in_low_power())
  57. fix = &pclk->lp;
  58. else
  59. fix = &pclk->hp;
  60. __clk_hw_set_clk(&fix->hw, hw);
  61. return clk_fixed_factor_ops.recalc_rate(&fix->hw, parent_rate);
  62. }
  63. static struct clk_ops cken_rate_ops = {
  64. .recalc_rate = cken_recalc_rate,
  65. };
  66. static u8 cken_get_parent(struct clk_hw *hw)
  67. {
  68. struct pxa_clk *pclk = to_pxa_clk(hw);
  69. if (!pclk->is_in_low_power)
  70. return 0;
  71. return pclk->is_in_low_power() ? 0 : 1;
  72. }
  73. static struct clk_ops cken_mux_ops = {
  74. .get_parent = cken_get_parent,
  75. .set_parent = dummy_clk_set_parent,
  76. };
  77. void __init clkdev_pxa_register(int ckid, const char *con_id,
  78. const char *dev_id, struct clk *clk)
  79. {
  80. if (!IS_ERR(clk) && (ckid != CLK_NONE))
  81. pxa_clocks[ckid] = clk;
  82. if (!IS_ERR(clk))
  83. clk_register_clkdev(clk, con_id, dev_id);
  84. }
  85. int __init clk_pxa_cken_init(const struct desc_clk_cken *clks, int nb_clks)
  86. {
  87. int i;
  88. struct pxa_clk *pxa_clk;
  89. struct clk *clk;
  90. for (i = 0; i < nb_clks; i++) {
  91. pxa_clk = kzalloc(sizeof(*pxa_clk), GFP_KERNEL);
  92. pxa_clk->is_in_low_power = clks[i].is_in_low_power;
  93. pxa_clk->lp = clks[i].lp;
  94. pxa_clk->hp = clks[i].hp;
  95. pxa_clk->gate = clks[i].gate;
  96. pxa_clk->gate.lock = &pxa_clk_lock;
  97. clk = clk_register_composite(NULL, clks[i].name,
  98. clks[i].parent_names, 2,
  99. &pxa_clk->hw, &cken_mux_ops,
  100. &pxa_clk->hw, &cken_rate_ops,
  101. &pxa_clk->gate.hw, &clk_gate_ops,
  102. clks[i].flags);
  103. clkdev_pxa_register(clks[i].ckid, clks[i].con_id,
  104. clks[i].dev_id, clk);
  105. }
  106. return 0;
  107. }
  108. void __init clk_pxa_dt_common_init(struct device_node *np)
  109. {
  110. of_clk_add_provider(np, of_clk_src_onecell_get, &onecell_data);
  111. }
  112. void pxa2xx_core_turbo_switch(bool on)
  113. {
  114. unsigned long flags;
  115. unsigned int unused, clkcfg;
  116. local_irq_save(flags);
  117. asm("mrc p14, 0, %0, c6, c0, 0" : "=r" (clkcfg));
  118. clkcfg &= ~CLKCFG_TURBO & ~CLKCFG_HALFTURBO;
  119. if (on)
  120. clkcfg |= CLKCFG_TURBO;
  121. clkcfg |= CLKCFG_FCS;
  122. asm volatile(
  123. " b 2f\n"
  124. " .align 5\n"
  125. "1: mcr p14, 0, %1, c6, c0, 0\n"
  126. " b 3f\n"
  127. "2: b 1b\n"
  128. "3: nop\n"
  129. : "=&r" (unused) : "r" (clkcfg));
  130. local_irq_restore(flags);
  131. }
  132. void pxa2xx_cpll_change(struct pxa2xx_freq *freq,
  133. u32 (*mdrefr_dri)(unsigned int), void __iomem *mdrefr,
  134. void __iomem *cccr)
  135. {
  136. unsigned int clkcfg = freq->clkcfg;
  137. unsigned int unused, preset_mdrefr, postset_mdrefr;
  138. unsigned long flags;
  139. local_irq_save(flags);
  140. /* Calculate the next MDREFR. If we're slowing down the SDRAM clock
  141. * we need to preset the smaller DRI before the change. If we're
  142. * speeding up we need to set the larger DRI value after the change.
  143. */
  144. preset_mdrefr = postset_mdrefr = readl(mdrefr);
  145. if ((preset_mdrefr & MDREFR_DRI_MASK) > mdrefr_dri(freq->membus_khz)) {
  146. preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK);
  147. preset_mdrefr |= mdrefr_dri(freq->membus_khz);
  148. }
  149. postset_mdrefr =
  150. (postset_mdrefr & ~MDREFR_DRI_MASK) |
  151. mdrefr_dri(freq->membus_khz);
  152. /* If we're dividing the memory clock by two for the SDRAM clock, this
  153. * must be set prior to the change. Clearing the divide must be done
  154. * after the change.
  155. */
  156. if (freq->div2) {
  157. preset_mdrefr |= MDREFR_DB2_MASK;
  158. postset_mdrefr |= MDREFR_DB2_MASK;
  159. } else {
  160. postset_mdrefr &= ~MDREFR_DB2_MASK;
  161. }
  162. /* Set new the CCCR and prepare CLKCFG */
  163. writel(freq->cccr, cccr);
  164. asm volatile(
  165. " ldr r4, [%1]\n"
  166. " b 2f\n"
  167. " .align 5\n"
  168. "1: str %3, [%1] /* preset the MDREFR */\n"
  169. " mcr p14, 0, %2, c6, c0, 0 /* set CLKCFG[FCS] */\n"
  170. " str %4, [%1] /* postset the MDREFR */\n"
  171. " b 3f\n"
  172. "2: b 1b\n"
  173. "3: nop\n"
  174. : "=&r" (unused)
  175. : "r" (mdrefr), "r" (clkcfg), "r" (preset_mdrefr),
  176. "r" (postset_mdrefr)
  177. : "r4", "r5");
  178. local_irq_restore(flags);
  179. }
  180. int pxa2xx_determine_rate(struct clk_rate_request *req,
  181. struct pxa2xx_freq *freqs, int nb_freqs)
  182. {
  183. int i, closest_below = -1, closest_above = -1;
  184. unsigned long rate;
  185. for (i = 0; i < nb_freqs; i++) {
  186. rate = freqs[i].cpll;
  187. if (rate == req->rate)
  188. break;
  189. if (rate < req->min_rate)
  190. continue;
  191. if (rate > req->max_rate)
  192. continue;
  193. if (rate <= req->rate)
  194. closest_below = i;
  195. if ((rate >= req->rate) && (closest_above == -1))
  196. closest_above = i;
  197. }
  198. req->best_parent_hw = NULL;
  199. if (i < nb_freqs) {
  200. rate = req->rate;
  201. } else if (closest_below >= 0) {
  202. rate = freqs[closest_below].cpll;
  203. } else if (closest_above >= 0) {
  204. rate = freqs[closest_above].cpll;
  205. } else {
  206. pr_debug("%s(rate=%lu) no match\n", __func__, req->rate);
  207. return -EINVAL;
  208. }
  209. pr_debug("%s(rate=%lu) rate=%lu\n", __func__, req->rate, rate);
  210. req->rate = rate;
  211. return 0;
  212. }