clk.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /*
  2. * Copyright (c) 2014 MundoReader S.L.
  3. * Author: Heiko Stuebner <heiko@sntech.de>
  4. *
  5. * based on
  6. *
  7. * samsung/clk.c
  8. * Copyright (c) 2013 Samsung Electronics Co., Ltd.
  9. * Copyright (c) 2013 Linaro Ltd.
  10. * Author: Thomas Abraham <thomas.ab@samsung.com>
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. * the Free Software Foundation; either version 2 of the License, or
  15. * (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. */
  22. #include <linux/slab.h>
  23. #include <linux/clk.h>
  24. #include <linux/clk-provider.h>
  25. #include <linux/mfd/syscon.h>
  26. #include <linux/regmap.h>
  27. #include "clk.h"
  28. /**
  29. * Register a clock branch.
  30. * Most clock branches have a form like
  31. *
  32. * src1 --|--\
  33. * |M |--[GATE]-[DIV]-
  34. * src2 --|--/
  35. *
  36. * sometimes without one of those components.
  37. */
  38. struct clk *rockchip_clk_register_branch(const char *name,
  39. const char **parent_names, u8 num_parents, void __iomem *base,
  40. int muxdiv_offset, u8 mux_shift, u8 mux_width, u8 mux_flags,
  41. u8 div_shift, u8 div_width, u8 div_flags,
  42. struct clk_div_table *div_table, int gate_offset,
  43. u8 gate_shift, u8 gate_flags, unsigned long flags,
  44. spinlock_t *lock)
  45. {
  46. struct clk *clk;
  47. struct clk_mux *mux = NULL;
  48. struct clk_gate *gate = NULL;
  49. struct clk_divider *div = NULL;
  50. const struct clk_ops *mux_ops = NULL, *div_ops = NULL,
  51. *gate_ops = NULL;
  52. if (num_parents > 1) {
  53. mux = kzalloc(sizeof(*mux), GFP_KERNEL);
  54. if (!mux)
  55. return ERR_PTR(-ENOMEM);
  56. mux->reg = base + muxdiv_offset;
  57. mux->shift = mux_shift;
  58. mux->mask = BIT(mux_width) - 1;
  59. mux->flags = mux_flags;
  60. mux->lock = lock;
  61. mux_ops = (mux_flags & CLK_MUX_READ_ONLY) ? &clk_mux_ro_ops
  62. : &clk_mux_ops;
  63. }
  64. if (gate_offset >= 0) {
  65. gate = kzalloc(sizeof(*gate), GFP_KERNEL);
  66. if (!gate)
  67. return ERR_PTR(-ENOMEM);
  68. gate->flags = gate_flags;
  69. gate->reg = base + gate_offset;
  70. gate->bit_idx = gate_shift;
  71. gate->lock = lock;
  72. gate_ops = &clk_gate_ops;
  73. }
  74. if (div_width > 0) {
  75. div = kzalloc(sizeof(*div), GFP_KERNEL);
  76. if (!div)
  77. return ERR_PTR(-ENOMEM);
  78. div->flags = div_flags;
  79. div->reg = base + muxdiv_offset;
  80. div->shift = div_shift;
  81. div->width = div_width;
  82. div->lock = lock;
  83. div->table = div_table;
  84. div_ops = (div_flags & CLK_DIVIDER_READ_ONLY)
  85. ? &clk_divider_ro_ops
  86. : &clk_divider_ops;
  87. }
  88. clk = clk_register_composite(NULL, name, parent_names, num_parents,
  89. mux ? &mux->hw : NULL, mux_ops,
  90. div ? &div->hw : NULL, div_ops,
  91. gate ? &gate->hw : NULL, gate_ops,
  92. flags);
  93. return clk;
  94. }
  95. static DEFINE_SPINLOCK(clk_lock);
  96. static struct clk **clk_table;
  97. static void __iomem *reg_base;
  98. static struct clk_onecell_data clk_data;
  99. static struct device_node *cru_node;
  100. static struct regmap *grf;
  101. void __init rockchip_clk_init(struct device_node *np, void __iomem *base,
  102. unsigned long nr_clks)
  103. {
  104. reg_base = base;
  105. cru_node = np;
  106. grf = ERR_PTR(-EPROBE_DEFER);
  107. clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL);
  108. if (!clk_table)
  109. pr_err("%s: could not allocate clock lookup table\n", __func__);
  110. clk_data.clks = clk_table;
  111. clk_data.clk_num = nr_clks;
  112. of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
  113. }
  114. struct regmap *rockchip_clk_get_grf(void)
  115. {
  116. if (IS_ERR(grf))
  117. grf = syscon_regmap_lookup_by_phandle(cru_node, "rockchip,grf");
  118. return grf;
  119. }
  120. void rockchip_clk_add_lookup(struct clk *clk, unsigned int id)
  121. {
  122. if (clk_table && id)
  123. clk_table[id] = clk;
  124. }
  125. void __init rockchip_clk_register_plls(struct rockchip_pll_clock *list,
  126. unsigned int nr_pll, int grf_lock_offset)
  127. {
  128. struct clk *clk;
  129. int idx;
  130. for (idx = 0; idx < nr_pll; idx++, list++) {
  131. clk = rockchip_clk_register_pll(list->type, list->name,
  132. list->parent_names, list->num_parents,
  133. reg_base, list->con_offset, grf_lock_offset,
  134. list->lock_shift, list->mode_offset,
  135. list->mode_shift, list->rate_table, &clk_lock);
  136. if (IS_ERR(clk)) {
  137. pr_err("%s: failed to register clock %s\n", __func__,
  138. list->name);
  139. continue;
  140. }
  141. rockchip_clk_add_lookup(clk, list->id);
  142. }
  143. }
  144. void __init rockchip_clk_register_branches(
  145. struct rockchip_clk_branch *list,
  146. unsigned int nr_clk)
  147. {
  148. struct clk *clk = NULL;
  149. unsigned int idx;
  150. unsigned long flags;
  151. for (idx = 0; idx < nr_clk; idx++, list++) {
  152. flags = list->flags;
  153. /* catch simple muxes */
  154. switch (list->branch_type) {
  155. case branch_mux:
  156. clk = clk_register_mux(NULL, list->name,
  157. list->parent_names, list->num_parents,
  158. flags, reg_base + list->muxdiv_offset,
  159. list->mux_shift, list->mux_width,
  160. list->mux_flags, &clk_lock);
  161. break;
  162. case branch_divider:
  163. if (list->div_table)
  164. clk = clk_register_divider_table(NULL,
  165. list->name, list->parent_names[0],
  166. flags, reg_base + list->muxdiv_offset,
  167. list->div_shift, list->div_width,
  168. list->div_flags, list->div_table,
  169. &clk_lock);
  170. else
  171. clk = clk_register_divider(NULL, list->name,
  172. list->parent_names[0], flags,
  173. reg_base + list->muxdiv_offset,
  174. list->div_shift, list->div_width,
  175. list->div_flags, &clk_lock);
  176. break;
  177. case branch_fraction_divider:
  178. /* unimplemented */
  179. continue;
  180. break;
  181. case branch_gate:
  182. flags |= CLK_SET_RATE_PARENT;
  183. /* keep all gates untouched for now */
  184. flags |= CLK_IGNORE_UNUSED;
  185. clk = clk_register_gate(NULL, list->name,
  186. list->parent_names[0], flags,
  187. reg_base + list->gate_offset,
  188. list->gate_shift, list->gate_flags, &clk_lock);
  189. break;
  190. case branch_composite:
  191. /* keep all gates untouched for now */
  192. flags |= CLK_IGNORE_UNUSED;
  193. clk = rockchip_clk_register_branch(list->name,
  194. list->parent_names, list->num_parents,
  195. reg_base, list->muxdiv_offset, list->mux_shift,
  196. list->mux_width, list->mux_flags,
  197. list->div_shift, list->div_width,
  198. list->div_flags, list->div_table,
  199. list->gate_offset, list->gate_shift,
  200. list->gate_flags, flags, &clk_lock);
  201. break;
  202. }
  203. /* none of the cases above matched */
  204. if (!clk) {
  205. pr_err("%s: unknown clock type %d\n",
  206. __func__, list->branch_type);
  207. continue;
  208. }
  209. if (IS_ERR(clk)) {
  210. pr_err("%s: failed to register clock %s: %ld\n",
  211. __func__, list->name, PTR_ERR(clk));
  212. continue;
  213. }
  214. rockchip_clk_add_lookup(clk, list->id);
  215. }
  216. }