clk-mtk.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2014 MediaTek Inc.
  4. * Author: James Liao <jamesjj.liao@mediatek.com>
  5. */
  6. #include <linux/of.h>
  7. #include <linux/of_address.h>
  8. #include <linux/err.h>
  9. #include <linux/io.h>
  10. #include <linux/slab.h>
  11. #include <linux/delay.h>
  12. #include <linux/clkdev.h>
  13. #include <linux/mfd/syscon.h>
  14. #include <linux/device.h>
  15. #include "clk-mtk.h"
  16. #include "clk-gate.h"
  17. struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num)
  18. {
  19. int i;
  20. struct clk_onecell_data *clk_data;
  21. clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
  22. if (!clk_data)
  23. return NULL;
  24. clk_data->clks = kcalloc(clk_num, sizeof(*clk_data->clks), GFP_KERNEL);
  25. if (!clk_data->clks)
  26. goto err_out;
  27. clk_data->clk_num = clk_num;
  28. for (i = 0; i < clk_num; i++)
  29. clk_data->clks[i] = ERR_PTR(-ENOENT);
  30. return clk_data;
  31. err_out:
  32. kfree(clk_data);
  33. return NULL;
  34. }
  35. void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
  36. int num, struct clk_onecell_data *clk_data)
  37. {
  38. int i;
  39. struct clk *clk;
  40. for (i = 0; i < num; i++) {
  41. const struct mtk_fixed_clk *rc = &clks[i];
  42. if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[rc->id]))
  43. continue;
  44. clk = clk_register_fixed_rate(NULL, rc->name, rc->parent, 0,
  45. rc->rate);
  46. if (IS_ERR(clk)) {
  47. pr_err("Failed to register clk %s: %ld\n",
  48. rc->name, PTR_ERR(clk));
  49. continue;
  50. }
  51. if (clk_data)
  52. clk_data->clks[rc->id] = clk;
  53. }
  54. }
  55. void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
  56. int num, struct clk_onecell_data *clk_data)
  57. {
  58. int i;
  59. struct clk *clk;
  60. for (i = 0; i < num; i++) {
  61. const struct mtk_fixed_factor *ff = &clks[i];
  62. if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[ff->id]))
  63. continue;
  64. clk = clk_register_fixed_factor(NULL, ff->name, ff->parent_name,
  65. CLK_SET_RATE_PARENT, ff->mult, ff->div);
  66. if (IS_ERR(clk)) {
  67. pr_err("Failed to register clk %s: %ld\n",
  68. ff->name, PTR_ERR(clk));
  69. continue;
  70. }
  71. if (clk_data)
  72. clk_data->clks[ff->id] = clk;
  73. }
  74. }
  75. int mtk_clk_register_gates_with_dev(struct device_node *node,
  76. const struct mtk_gate *clks,
  77. int num, struct clk_onecell_data *clk_data,
  78. struct device *dev)
  79. {
  80. int i;
  81. struct clk *clk;
  82. struct regmap *regmap;
  83. if (!clk_data)
  84. return -ENOMEM;
  85. regmap = syscon_node_to_regmap(node);
  86. if (IS_ERR(regmap)) {
  87. pr_err("Cannot find regmap for %pOF: %ld\n", node,
  88. PTR_ERR(regmap));
  89. return PTR_ERR(regmap);
  90. }
  91. for (i = 0; i < num; i++) {
  92. const struct mtk_gate *gate = &clks[i];
  93. if (!IS_ERR_OR_NULL(clk_data->clks[gate->id]))
  94. continue;
  95. clk = mtk_clk_register_gate(gate->name, gate->parent_name,
  96. regmap,
  97. gate->regs->set_ofs,
  98. gate->regs->clr_ofs,
  99. gate->regs->sta_ofs,
  100. gate->shift, gate->ops, gate->flags, dev);
  101. if (IS_ERR(clk)) {
  102. pr_err("Failed to register clk %s: %ld\n",
  103. gate->name, PTR_ERR(clk));
  104. continue;
  105. }
  106. clk_data->clks[gate->id] = clk;
  107. }
  108. return 0;
  109. }
  110. int mtk_clk_register_gates(struct device_node *node,
  111. const struct mtk_gate *clks,
  112. int num, struct clk_onecell_data *clk_data)
  113. {
  114. return mtk_clk_register_gates_with_dev(node,
  115. clks, num, clk_data, NULL);
  116. }
  117. struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
  118. void __iomem *base, spinlock_t *lock)
  119. {
  120. struct clk *clk;
  121. struct clk_mux *mux = NULL;
  122. struct clk_gate *gate = NULL;
  123. struct clk_divider *div = NULL;
  124. struct clk_hw *mux_hw = NULL, *gate_hw = NULL, *div_hw = NULL;
  125. const struct clk_ops *mux_ops = NULL, *gate_ops = NULL, *div_ops = NULL;
  126. const char * const *parent_names;
  127. const char *parent;
  128. int num_parents;
  129. int ret;
  130. if (mc->mux_shift >= 0) {
  131. mux = kzalloc(sizeof(*mux), GFP_KERNEL);
  132. if (!mux)
  133. return ERR_PTR(-ENOMEM);
  134. mux->reg = base + mc->mux_reg;
  135. mux->mask = BIT(mc->mux_width) - 1;
  136. mux->shift = mc->mux_shift;
  137. mux->lock = lock;
  138. mux->flags = mc->mux_flags;
  139. mux_hw = &mux->hw;
  140. mux_ops = &clk_mux_ops;
  141. parent_names = mc->parent_names;
  142. num_parents = mc->num_parents;
  143. } else {
  144. parent = mc->parent;
  145. parent_names = &parent;
  146. num_parents = 1;
  147. }
  148. if (mc->gate_shift >= 0) {
  149. gate = kzalloc(sizeof(*gate), GFP_KERNEL);
  150. if (!gate) {
  151. ret = -ENOMEM;
  152. goto err_out;
  153. }
  154. gate->reg = base + mc->gate_reg;
  155. gate->bit_idx = mc->gate_shift;
  156. gate->flags = CLK_GATE_SET_TO_DISABLE;
  157. gate->lock = lock;
  158. gate_hw = &gate->hw;
  159. gate_ops = &clk_gate_ops;
  160. }
  161. if (mc->divider_shift >= 0) {
  162. div = kzalloc(sizeof(*div), GFP_KERNEL);
  163. if (!div) {
  164. ret = -ENOMEM;
  165. goto err_out;
  166. }
  167. div->reg = base + mc->divider_reg;
  168. div->shift = mc->divider_shift;
  169. div->width = mc->divider_width;
  170. div->lock = lock;
  171. div_hw = &div->hw;
  172. div_ops = &clk_divider_ops;
  173. }
  174. clk = clk_register_composite(NULL, mc->name, parent_names, num_parents,
  175. mux_hw, mux_ops,
  176. div_hw, div_ops,
  177. gate_hw, gate_ops,
  178. mc->flags);
  179. if (IS_ERR(clk)) {
  180. ret = PTR_ERR(clk);
  181. goto err_out;
  182. }
  183. return clk;
  184. err_out:
  185. kfree(div);
  186. kfree(gate);
  187. kfree(mux);
  188. return ERR_PTR(ret);
  189. }
  190. void mtk_clk_register_composites(const struct mtk_composite *mcs,
  191. int num, void __iomem *base, spinlock_t *lock,
  192. struct clk_onecell_data *clk_data)
  193. {
  194. struct clk *clk;
  195. int i;
  196. for (i = 0; i < num; i++) {
  197. const struct mtk_composite *mc = &mcs[i];
  198. if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[mc->id]))
  199. continue;
  200. clk = mtk_clk_register_composite(mc, base, lock);
  201. if (IS_ERR(clk)) {
  202. pr_err("Failed to register clk %s: %ld\n",
  203. mc->name, PTR_ERR(clk));
  204. continue;
  205. }
  206. if (clk_data)
  207. clk_data->clks[mc->id] = clk;
  208. }
  209. }
  210. void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
  211. int num, void __iomem *base, spinlock_t *lock,
  212. struct clk_onecell_data *clk_data)
  213. {
  214. struct clk *clk;
  215. int i;
  216. for (i = 0; i < num; i++) {
  217. const struct mtk_clk_divider *mcd = &mcds[i];
  218. if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[mcd->id]))
  219. continue;
  220. clk = clk_register_divider(NULL, mcd->name, mcd->parent_name,
  221. mcd->flags, base + mcd->div_reg, mcd->div_shift,
  222. mcd->div_width, mcd->clk_divider_flags, lock);
  223. if (IS_ERR(clk)) {
  224. pr_err("Failed to register clk %s: %ld\n",
  225. mcd->name, PTR_ERR(clk));
  226. continue;
  227. }
  228. if (clk_data)
  229. clk_data->clks[mcd->id] = clk;
  230. }
  231. }