berlin2-div.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2014 Marvell Technology Group Ltd.
  4. *
  5. * Alexandre Belloni <[email protected]>
  6. * Sebastian Hesselbarth <[email protected]>
  7. */
  8. #include <linux/bitops.h>
  9. #include <linux/clk-provider.h>
  10. #include <linux/io.h>
  11. #include <linux/of.h>
  12. #include <linux/of_address.h>
  13. #include <linux/slab.h>
  14. #include <linux/spinlock.h>
  15. #include "berlin2-div.h"
  16. /*
  17. * Clock dividers in Berlin2 SoCs comprise a complex cell to select
  18. * input pll and divider. The virtual structure as it is used in Marvell
  19. * BSP code can be seen as:
  20. *
  21. * +---+
  22. * pll0 --------------->| 0 | +---+
  23. * +---+ |(B)|--+--------------->| 0 | +---+
  24. * pll1.0 -->| 0 | +-->| 1 | | +--------+ |(E)|----->| 0 | +---+
  25. * pll1.1 -->| 1 | | +---+ +-->|(C) 1:M |-->| 1 | |(F)|-->|(G)|->
  26. * ... -->|(A)|--+ | +--------+ +---+ +-->| 1 | +---+
  27. * ... -->| | +-->|(D) 1:3 |----------+ +---+
  28. * pll1.N -->| N | +---------
  29. * +---+
  30. *
  31. * (A) input pll clock mux controlled by <PllSelect[1:n]>
  32. * (B) input pll bypass mux controlled by <PllSwitch>
  33. * (C) programmable clock divider controlled by <Select[1:n]>
  34. * (D) constant div-by-3 clock divider
  35. * (E) programmable clock divider bypass controlled by <Switch>
  36. * (F) constant div-by-3 clock mux controlled by <D3Switch>
  37. * (G) clock gate controlled by <Enable>
  38. *
  39. * For whatever reason, above control signals come in two flavors:
  40. * - single register dividers with all bits in one register
  41. * - shared register dividers with bits spread over multiple registers
  42. * (including signals for the same cell spread over consecutive registers)
  43. *
  44. * Also, clock gate and pll mux is not available on every div cell, so
  45. * we have to deal with those, too. We reuse common clock composite driver
  46. * for it.
  47. */
  48. #define PLL_SELECT_MASK 0x7
  49. #define DIV_SELECT_MASK 0x7
  50. struct berlin2_div {
  51. struct clk_hw hw;
  52. void __iomem *base;
  53. struct berlin2_div_map map;
  54. spinlock_t *lock;
  55. };
  56. #define to_berlin2_div(hw) container_of(hw, struct berlin2_div, hw)
  57. static u8 clk_div[] = { 1, 2, 4, 6, 8, 12, 1, 1 };
  58. static int berlin2_div_is_enabled(struct clk_hw *hw)
  59. {
  60. struct berlin2_div *div = to_berlin2_div(hw);
  61. struct berlin2_div_map *map = &div->map;
  62. u32 reg;
  63. if (div->lock)
  64. spin_lock(div->lock);
  65. reg = readl_relaxed(div->base + map->gate_offs);
  66. reg >>= map->gate_shift;
  67. if (div->lock)
  68. spin_unlock(div->lock);
  69. return (reg & 0x1);
  70. }
  71. static int berlin2_div_enable(struct clk_hw *hw)
  72. {
  73. struct berlin2_div *div = to_berlin2_div(hw);
  74. struct berlin2_div_map *map = &div->map;
  75. u32 reg;
  76. if (div->lock)
  77. spin_lock(div->lock);
  78. reg = readl_relaxed(div->base + map->gate_offs);
  79. reg |= BIT(map->gate_shift);
  80. writel_relaxed(reg, div->base + map->gate_offs);
  81. if (div->lock)
  82. spin_unlock(div->lock);
  83. return 0;
  84. }
  85. static void berlin2_div_disable(struct clk_hw *hw)
  86. {
  87. struct berlin2_div *div = to_berlin2_div(hw);
  88. struct berlin2_div_map *map = &div->map;
  89. u32 reg;
  90. if (div->lock)
  91. spin_lock(div->lock);
  92. reg = readl_relaxed(div->base + map->gate_offs);
  93. reg &= ~BIT(map->gate_shift);
  94. writel_relaxed(reg, div->base + map->gate_offs);
  95. if (div->lock)
  96. spin_unlock(div->lock);
  97. }
  98. static int berlin2_div_set_parent(struct clk_hw *hw, u8 index)
  99. {
  100. struct berlin2_div *div = to_berlin2_div(hw);
  101. struct berlin2_div_map *map = &div->map;
  102. u32 reg;
  103. if (div->lock)
  104. spin_lock(div->lock);
  105. /* index == 0 is PLL_SWITCH */
  106. reg = readl_relaxed(div->base + map->pll_switch_offs);
  107. if (index == 0)
  108. reg &= ~BIT(map->pll_switch_shift);
  109. else
  110. reg |= BIT(map->pll_switch_shift);
  111. writel_relaxed(reg, div->base + map->pll_switch_offs);
  112. /* index > 0 is PLL_SELECT */
  113. if (index > 0) {
  114. reg = readl_relaxed(div->base + map->pll_select_offs);
  115. reg &= ~(PLL_SELECT_MASK << map->pll_select_shift);
  116. reg |= (index - 1) << map->pll_select_shift;
  117. writel_relaxed(reg, div->base + map->pll_select_offs);
  118. }
  119. if (div->lock)
  120. spin_unlock(div->lock);
  121. return 0;
  122. }
  123. static u8 berlin2_div_get_parent(struct clk_hw *hw)
  124. {
  125. struct berlin2_div *div = to_berlin2_div(hw);
  126. struct berlin2_div_map *map = &div->map;
  127. u32 reg;
  128. u8 index = 0;
  129. if (div->lock)
  130. spin_lock(div->lock);
  131. /* PLL_SWITCH == 0 is index 0 */
  132. reg = readl_relaxed(div->base + map->pll_switch_offs);
  133. reg &= BIT(map->pll_switch_shift);
  134. if (reg) {
  135. reg = readl_relaxed(div->base + map->pll_select_offs);
  136. reg >>= map->pll_select_shift;
  137. reg &= PLL_SELECT_MASK;
  138. index = 1 + reg;
  139. }
  140. if (div->lock)
  141. spin_unlock(div->lock);
  142. return index;
  143. }
  144. static unsigned long berlin2_div_recalc_rate(struct clk_hw *hw,
  145. unsigned long parent_rate)
  146. {
  147. struct berlin2_div *div = to_berlin2_div(hw);
  148. struct berlin2_div_map *map = &div->map;
  149. u32 divsw, div3sw, divider = 1;
  150. if (div->lock)
  151. spin_lock(div->lock);
  152. divsw = readl_relaxed(div->base + map->div_switch_offs) &
  153. (1 << map->div_switch_shift);
  154. div3sw = readl_relaxed(div->base + map->div3_switch_offs) &
  155. (1 << map->div3_switch_shift);
  156. /* constant divide-by-3 (dominant) */
  157. if (div3sw != 0) {
  158. divider = 3;
  159. /* divider can be bypassed with DIV_SWITCH == 0 */
  160. } else if (divsw == 0) {
  161. divider = 1;
  162. /* clock divider determined by DIV_SELECT */
  163. } else {
  164. u32 reg;
  165. reg = readl_relaxed(div->base + map->div_select_offs);
  166. reg >>= map->div_select_shift;
  167. reg &= DIV_SELECT_MASK;
  168. divider = clk_div[reg];
  169. }
  170. if (div->lock)
  171. spin_unlock(div->lock);
  172. return parent_rate / divider;
  173. }
  174. static const struct clk_ops berlin2_div_rate_ops = {
  175. .recalc_rate = berlin2_div_recalc_rate,
  176. };
  177. static const struct clk_ops berlin2_div_gate_ops = {
  178. .is_enabled = berlin2_div_is_enabled,
  179. .enable = berlin2_div_enable,
  180. .disable = berlin2_div_disable,
  181. };
  182. static const struct clk_ops berlin2_div_mux_ops = {
  183. .set_parent = berlin2_div_set_parent,
  184. .get_parent = berlin2_div_get_parent,
  185. };
  186. struct clk_hw * __init
  187. berlin2_div_register(const struct berlin2_div_map *map,
  188. void __iomem *base, const char *name, u8 div_flags,
  189. const char **parent_names, int num_parents,
  190. unsigned long flags, spinlock_t *lock)
  191. {
  192. const struct clk_ops *mux_ops = &berlin2_div_mux_ops;
  193. const struct clk_ops *rate_ops = &berlin2_div_rate_ops;
  194. const struct clk_ops *gate_ops = &berlin2_div_gate_ops;
  195. struct berlin2_div *div;
  196. div = kzalloc(sizeof(*div), GFP_KERNEL);
  197. if (!div)
  198. return ERR_PTR(-ENOMEM);
  199. /* copy div_map to allow __initconst */
  200. memcpy(&div->map, map, sizeof(*map));
  201. div->base = base;
  202. div->lock = lock;
  203. if ((div_flags & BERLIN2_DIV_HAS_GATE) == 0)
  204. gate_ops = NULL;
  205. if ((div_flags & BERLIN2_DIV_HAS_MUX) == 0)
  206. mux_ops = NULL;
  207. return clk_hw_register_composite(NULL, name, parent_names, num_parents,
  208. &div->hw, mux_ops, &div->hw, rate_ops,
  209. &div->hw, gate_ops, flags);
  210. }