composite.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * TI composite clock support
  4. *
  5. * Copyright (C) 2013 Texas Instruments, Inc.
  6. *
  7. * Tero Kristo <[email protected]>
  8. */
  9. #include <linux/clk-provider.h>
  10. #include <linux/slab.h>
  11. #include <linux/io.h>
  12. #include <linux/of.h>
  13. #include <linux/of_address.h>
  14. #include <linux/clk/ti.h>
  15. #include <linux/list.h>
  16. #include "clock.h"
  17. #undef pr_fmt
  18. #define pr_fmt(fmt) "%s: " fmt, __func__
  19. static unsigned long ti_composite_recalc_rate(struct clk_hw *hw,
  20. unsigned long parent_rate)
  21. {
  22. return ti_clk_divider_ops.recalc_rate(hw, parent_rate);
  23. }
  24. static long ti_composite_round_rate(struct clk_hw *hw, unsigned long rate,
  25. unsigned long *prate)
  26. {
  27. return -EINVAL;
  28. }
  29. static int ti_composite_set_rate(struct clk_hw *hw, unsigned long rate,
  30. unsigned long parent_rate)
  31. {
  32. return -EINVAL;
  33. }
  34. static const struct clk_ops ti_composite_divider_ops = {
  35. .recalc_rate = &ti_composite_recalc_rate,
  36. .round_rate = &ti_composite_round_rate,
  37. .set_rate = &ti_composite_set_rate,
  38. };
  39. static const struct clk_ops ti_composite_gate_ops = {
  40. .enable = &omap2_dflt_clk_enable,
  41. .disable = &omap2_dflt_clk_disable,
  42. .is_enabled = &omap2_dflt_clk_is_enabled,
  43. };
  44. struct component_clk {
  45. int num_parents;
  46. const char **parent_names;
  47. struct device_node *node;
  48. int type;
  49. struct clk_hw *hw;
  50. struct list_head link;
  51. };
  52. static const char * const component_clk_types[] __initconst = {
  53. "gate", "divider", "mux"
  54. };
  55. static LIST_HEAD(component_clks);
  56. static struct device_node *_get_component_node(struct device_node *node, int i)
  57. {
  58. int rc;
  59. struct of_phandle_args clkspec;
  60. rc = of_parse_phandle_with_args(node, "clocks", "#clock-cells", i,
  61. &clkspec);
  62. if (rc)
  63. return NULL;
  64. return clkspec.np;
  65. }
  66. static struct component_clk *_lookup_component(struct device_node *node)
  67. {
  68. struct component_clk *comp;
  69. list_for_each_entry(comp, &component_clks, link) {
  70. if (comp->node == node)
  71. return comp;
  72. }
  73. return NULL;
  74. }
  75. struct clk_hw_omap_comp {
  76. struct clk_hw hw;
  77. struct device_node *comp_nodes[CLK_COMPONENT_TYPE_MAX];
  78. struct component_clk *comp_clks[CLK_COMPONENT_TYPE_MAX];
  79. };
  80. static inline struct clk_hw *_get_hw(struct clk_hw_omap_comp *clk, int idx)
  81. {
  82. if (!clk)
  83. return NULL;
  84. if (!clk->comp_clks[idx])
  85. return NULL;
  86. return clk->comp_clks[idx]->hw;
  87. }
  88. #define to_clk_hw_comp(_hw) container_of(_hw, struct clk_hw_omap_comp, hw)
  89. static void __init _register_composite(void *user,
  90. struct device_node *node)
  91. {
  92. struct clk_hw *hw = user;
  93. struct clk *clk;
  94. struct clk_hw_omap_comp *cclk = to_clk_hw_comp(hw);
  95. struct component_clk *comp;
  96. int num_parents = 0;
  97. const char **parent_names = NULL;
  98. const char *name;
  99. int i;
  100. int ret;
  101. /* Check for presence of each component clock */
  102. for (i = 0; i < CLK_COMPONENT_TYPE_MAX; i++) {
  103. if (!cclk->comp_nodes[i])
  104. continue;
  105. comp = _lookup_component(cclk->comp_nodes[i]);
  106. if (!comp) {
  107. pr_debug("component %s not ready for %pOFn, retry\n",
  108. cclk->comp_nodes[i]->name, node);
  109. if (!ti_clk_retry_init(node, hw,
  110. _register_composite))
  111. return;
  112. goto cleanup;
  113. }
  114. if (cclk->comp_clks[comp->type] != NULL) {
  115. pr_err("duplicate component types for %pOFn (%s)!\n",
  116. node, component_clk_types[comp->type]);
  117. goto cleanup;
  118. }
  119. cclk->comp_clks[comp->type] = comp;
  120. /* Mark this node as found */
  121. cclk->comp_nodes[i] = NULL;
  122. }
  123. /* All components exists, proceed with registration */
  124. for (i = CLK_COMPONENT_TYPE_MAX - 1; i >= 0; i--) {
  125. comp = cclk->comp_clks[i];
  126. if (!comp)
  127. continue;
  128. if (comp->num_parents) {
  129. num_parents = comp->num_parents;
  130. parent_names = comp->parent_names;
  131. break;
  132. }
  133. }
  134. if (!num_parents) {
  135. pr_err("%s: no parents found for %pOFn!\n", __func__, node);
  136. goto cleanup;
  137. }
  138. name = ti_dt_clk_name(node);
  139. clk = clk_register_composite(NULL, name,
  140. parent_names, num_parents,
  141. _get_hw(cclk, CLK_COMPONENT_TYPE_MUX),
  142. &ti_clk_mux_ops,
  143. _get_hw(cclk, CLK_COMPONENT_TYPE_DIVIDER),
  144. &ti_composite_divider_ops,
  145. _get_hw(cclk, CLK_COMPONENT_TYPE_GATE),
  146. &ti_composite_gate_ops, 0);
  147. if (!IS_ERR(clk)) {
  148. ret = ti_clk_add_alias(clk, name);
  149. if (ret) {
  150. clk_unregister(clk);
  151. goto cleanup;
  152. }
  153. of_clk_add_provider(node, of_clk_src_simple_get, clk);
  154. }
  155. cleanup:
  156. /* Free component clock list entries */
  157. for (i = 0; i < CLK_COMPONENT_TYPE_MAX; i++) {
  158. if (!cclk->comp_clks[i])
  159. continue;
  160. list_del(&cclk->comp_clks[i]->link);
  161. kfree(cclk->comp_clks[i]->parent_names);
  162. kfree(cclk->comp_clks[i]);
  163. }
  164. kfree(cclk);
  165. }
  166. static void __init of_ti_composite_clk_setup(struct device_node *node)
  167. {
  168. unsigned int num_clks;
  169. int i;
  170. struct clk_hw_omap_comp *cclk;
  171. /* Number of component clocks to be put inside this clock */
  172. num_clks = of_clk_get_parent_count(node);
  173. if (!num_clks) {
  174. pr_err("composite clk %pOFn must have component(s)\n", node);
  175. return;
  176. }
  177. cclk = kzalloc(sizeof(*cclk), GFP_KERNEL);
  178. if (!cclk)
  179. return;
  180. /* Get device node pointers for each component clock */
  181. for (i = 0; i < num_clks; i++)
  182. cclk->comp_nodes[i] = _get_component_node(node, i);
  183. _register_composite(&cclk->hw, node);
  184. }
  185. CLK_OF_DECLARE(ti_composite_clock, "ti,composite-clock",
  186. of_ti_composite_clk_setup);
  187. /**
  188. * ti_clk_add_component - add a component clock to the pool
  189. * @node: device node of the component clock
  190. * @hw: hardware clock definition for the component clock
  191. * @type: type of the component clock
  192. *
  193. * Adds a component clock to the list of available components, so that
  194. * it can be registered by a composite clock.
  195. */
  196. int __init ti_clk_add_component(struct device_node *node, struct clk_hw *hw,
  197. int type)
  198. {
  199. unsigned int num_parents;
  200. const char **parent_names;
  201. struct component_clk *clk;
  202. num_parents = of_clk_get_parent_count(node);
  203. if (!num_parents) {
  204. pr_err("component-clock %pOFn must have parent(s)\n", node);
  205. return -EINVAL;
  206. }
  207. parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL);
  208. if (!parent_names)
  209. return -ENOMEM;
  210. of_clk_parent_fill(node, parent_names, num_parents);
  211. clk = kzalloc(sizeof(*clk), GFP_KERNEL);
  212. if (!clk) {
  213. kfree(parent_names);
  214. return -ENOMEM;
  215. }
  216. clk->num_parents = num_parents;
  217. clk->parent_names = parent_names;
  218. clk->hw = hw;
  219. clk->node = node;
  220. clk->type = type;
  221. list_add(&clk->link, &component_clks);
  222. return 0;
  223. }