clk-mtk.c 6.1 KB

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