dove-divider.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*
  2. * Marvell Dove PMU Core PLL divider driver
  3. *
  4. * Cleaned up by substantially rewriting, and converted to DT by
  5. * Russell King. Origin is not known.
  6. */
  7. #include <linux/clk-provider.h>
  8. #include <linux/delay.h>
  9. #include <linux/io.h>
  10. #include <linux/kernel.h>
  11. #include <linux/of.h>
  12. #include <linux/of_address.h>
  13. #include "dove-divider.h"
  14. struct dove_clk {
  15. const char *name;
  16. struct clk_hw hw;
  17. void __iomem *base;
  18. spinlock_t *lock;
  19. u8 div_bit_start;
  20. u8 div_bit_end;
  21. u8 div_bit_load;
  22. u8 div_bit_size;
  23. u32 *divider_table;
  24. };
  25. enum {
  26. DIV_CTRL0 = 0,
  27. DIV_CTRL1 = 4,
  28. DIV_CTRL1_N_RESET_MASK = BIT(10),
  29. };
  30. #define to_dove_clk(hw) container_of(hw, struct dove_clk, hw)
  31. static void dove_load_divider(void __iomem *base, u32 val, u32 mask, u32 load)
  32. {
  33. u32 v;
  34. v = readl_relaxed(base + DIV_CTRL1) | DIV_CTRL1_N_RESET_MASK;
  35. writel_relaxed(v, base + DIV_CTRL1);
  36. v = (readl_relaxed(base + DIV_CTRL0) & ~(mask | load)) | val;
  37. writel_relaxed(v, base + DIV_CTRL0);
  38. writel_relaxed(v | load, base + DIV_CTRL0);
  39. ndelay(250);
  40. writel_relaxed(v, base + DIV_CTRL0);
  41. }
  42. static unsigned int dove_get_divider(struct dove_clk *dc)
  43. {
  44. unsigned int divider;
  45. u32 val;
  46. val = readl_relaxed(dc->base + DIV_CTRL0);
  47. val >>= dc->div_bit_start;
  48. divider = val & ~(~0 << dc->div_bit_size);
  49. if (dc->divider_table)
  50. divider = dc->divider_table[divider];
  51. return divider;
  52. }
  53. static int dove_calc_divider(const struct dove_clk *dc, unsigned long rate,
  54. unsigned long parent_rate, bool set)
  55. {
  56. unsigned int divider, max;
  57. divider = DIV_ROUND_CLOSEST(parent_rate, rate);
  58. if (dc->divider_table) {
  59. unsigned int i;
  60. for (i = 0; dc->divider_table[i]; i++)
  61. if (divider == dc->divider_table[i]) {
  62. divider = i;
  63. break;
  64. }
  65. if (!dc->divider_table[i])
  66. return -EINVAL;
  67. } else {
  68. max = 1 << dc->div_bit_size;
  69. if (set && (divider == 0 || divider >= max))
  70. return -EINVAL;
  71. if (divider >= max)
  72. divider = max - 1;
  73. else if (divider == 0)
  74. divider = 1;
  75. }
  76. return divider;
  77. }
  78. static unsigned long dove_recalc_rate(struct clk_hw *hw, unsigned long parent)
  79. {
  80. struct dove_clk *dc = to_dove_clk(hw);
  81. unsigned int divider = dove_get_divider(dc);
  82. unsigned long rate = DIV_ROUND_CLOSEST(parent, divider);
  83. pr_debug("%s(): %s divider=%u parent=%lu rate=%lu\n",
  84. __func__, dc->name, divider, parent, rate);
  85. return rate;
  86. }
  87. static long dove_round_rate(struct clk_hw *hw, unsigned long rate,
  88. unsigned long *parent)
  89. {
  90. struct dove_clk *dc = to_dove_clk(hw);
  91. unsigned long parent_rate = *parent;
  92. int divider;
  93. divider = dove_calc_divider(dc, rate, parent_rate, false);
  94. if (divider < 0)
  95. return divider;
  96. rate = DIV_ROUND_CLOSEST(parent_rate, divider);
  97. pr_debug("%s(): %s divider=%u parent=%lu rate=%lu\n",
  98. __func__, dc->name, divider, parent_rate, rate);
  99. return rate;
  100. }
  101. static int dove_set_clock(struct clk_hw *hw, unsigned long rate,
  102. unsigned long parent_rate)
  103. {
  104. struct dove_clk *dc = to_dove_clk(hw);
  105. u32 mask, load, div;
  106. int divider;
  107. divider = dove_calc_divider(dc, rate, parent_rate, true);
  108. if (divider < 0)
  109. return divider;
  110. pr_debug("%s(): %s divider=%u parent=%lu rate=%lu\n",
  111. __func__, dc->name, divider, parent_rate, rate);
  112. div = (u32)divider << dc->div_bit_start;
  113. mask = ~(~0 << dc->div_bit_size) << dc->div_bit_start;
  114. load = BIT(dc->div_bit_load);
  115. spin_lock(dc->lock);
  116. dove_load_divider(dc->base, div, mask, load);
  117. spin_unlock(dc->lock);
  118. return 0;
  119. }
  120. static const struct clk_ops dove_divider_ops = {
  121. .set_rate = dove_set_clock,
  122. .round_rate = dove_round_rate,
  123. .recalc_rate = dove_recalc_rate,
  124. };
  125. static struct clk *clk_register_dove_divider(struct device *dev,
  126. struct dove_clk *dc, const char **parent_names, size_t num_parents,
  127. void __iomem *base)
  128. {
  129. char name[32];
  130. struct clk_init_data init = {
  131. .name = name,
  132. .ops = &dove_divider_ops,
  133. .parent_names = parent_names,
  134. .num_parents = num_parents,
  135. };
  136. strlcpy(name, dc->name, sizeof(name));
  137. dc->hw.init = &init;
  138. dc->base = base;
  139. dc->div_bit_size = dc->div_bit_end - dc->div_bit_start + 1;
  140. return clk_register(dev, &dc->hw);
  141. }
  142. static DEFINE_SPINLOCK(dove_divider_lock);
  143. static u32 axi_divider[] = {-1, 2, 1, 3, 4, 6, 5, 7, 8, 10, 9, 0};
  144. static struct dove_clk dove_hw_clocks[4] = {
  145. {
  146. .name = "axi",
  147. .lock = &dove_divider_lock,
  148. .div_bit_start = 1,
  149. .div_bit_end = 6,
  150. .div_bit_load = 7,
  151. .divider_table = axi_divider,
  152. }, {
  153. .name = "gpu",
  154. .lock = &dove_divider_lock,
  155. .div_bit_start = 8,
  156. .div_bit_end = 13,
  157. .div_bit_load = 14,
  158. }, {
  159. .name = "vmeta",
  160. .lock = &dove_divider_lock,
  161. .div_bit_start = 15,
  162. .div_bit_end = 20,
  163. .div_bit_load = 21,
  164. }, {
  165. .name = "lcd",
  166. .lock = &dove_divider_lock,
  167. .div_bit_start = 22,
  168. .div_bit_end = 27,
  169. .div_bit_load = 28,
  170. },
  171. };
  172. static const char *core_pll[] = {
  173. "core-pll",
  174. };
  175. static int dove_divider_init(struct device *dev, void __iomem *base,
  176. struct clk **clks)
  177. {
  178. struct clk *clk;
  179. int i;
  180. /*
  181. * Create the core PLL clock. We treat this as a fixed rate
  182. * clock as we don't know any better, and documentation is sparse.
  183. */
  184. clk = clk_register_fixed_rate(dev, core_pll[0], NULL, 0, 2000000000UL);
  185. if (IS_ERR(clk))
  186. return PTR_ERR(clk);
  187. for (i = 0; i < ARRAY_SIZE(dove_hw_clocks); i++)
  188. clks[i] = clk_register_dove_divider(dev, &dove_hw_clocks[i],
  189. core_pll,
  190. ARRAY_SIZE(core_pll), base);
  191. return 0;
  192. }
  193. static struct clk *dove_divider_clocks[4];
  194. static struct clk_onecell_data dove_divider_data = {
  195. .clks = dove_divider_clocks,
  196. .clk_num = ARRAY_SIZE(dove_divider_clocks),
  197. };
  198. void __init dove_divider_clk_init(struct device_node *np)
  199. {
  200. void __iomem *base;
  201. base = of_iomap(np, 0);
  202. if (WARN_ON(!base))
  203. return;
  204. if (WARN_ON(dove_divider_init(NULL, base, dove_divider_clocks))) {
  205. iounmap(base);
  206. return;
  207. }
  208. of_clk_add_provider(np, of_clk_src_onecell_get, &dove_divider_data);
  209. }