clk.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  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 <linux/reboot.h>
  28. #include "clk.h"
  29. /**
  30. * Register a clock branch.
  31. * Most clock branches have a form like
  32. *
  33. * src1 --|--\
  34. * |M |--[GATE]-[DIV]-
  35. * src2 --|--/
  36. *
  37. * sometimes without one of those components.
  38. */
  39. static struct clk *rockchip_clk_register_branch(const char *name,
  40. const char *const *parent_names, u8 num_parents, void __iomem *base,
  41. int muxdiv_offset, u8 mux_shift, u8 mux_width, u8 mux_flags,
  42. u8 div_shift, u8 div_width, u8 div_flags,
  43. struct clk_div_table *div_table, int gate_offset,
  44. u8 gate_shift, u8 gate_flags, unsigned long flags,
  45. spinlock_t *lock)
  46. {
  47. struct clk *clk;
  48. struct clk_mux *mux = NULL;
  49. struct clk_gate *gate = NULL;
  50. struct clk_divider *div = NULL;
  51. const struct clk_ops *mux_ops = NULL, *div_ops = NULL,
  52. *gate_ops = NULL;
  53. if (num_parents > 1) {
  54. mux = kzalloc(sizeof(*mux), GFP_KERNEL);
  55. if (!mux)
  56. return ERR_PTR(-ENOMEM);
  57. mux->reg = base + muxdiv_offset;
  58. mux->shift = mux_shift;
  59. mux->mask = BIT(mux_width) - 1;
  60. mux->flags = mux_flags;
  61. mux->lock = lock;
  62. mux_ops = (mux_flags & CLK_MUX_READ_ONLY) ? &clk_mux_ro_ops
  63. : &clk_mux_ops;
  64. }
  65. if (gate_offset >= 0) {
  66. gate = kzalloc(sizeof(*gate), GFP_KERNEL);
  67. if (!gate)
  68. goto err_gate;
  69. gate->flags = gate_flags;
  70. gate->reg = base + gate_offset;
  71. gate->bit_idx = gate_shift;
  72. gate->lock = lock;
  73. gate_ops = &clk_gate_ops;
  74. }
  75. if (div_width > 0) {
  76. div = kzalloc(sizeof(*div), GFP_KERNEL);
  77. if (!div)
  78. goto err_div;
  79. div->flags = div_flags;
  80. div->reg = base + muxdiv_offset;
  81. div->shift = div_shift;
  82. div->width = div_width;
  83. div->lock = lock;
  84. div->table = div_table;
  85. div_ops = (div_flags & CLK_DIVIDER_READ_ONLY)
  86. ? &clk_divider_ro_ops
  87. : &clk_divider_ops;
  88. }
  89. clk = clk_register_composite(NULL, name, parent_names, num_parents,
  90. mux ? &mux->hw : NULL, mux_ops,
  91. div ? &div->hw : NULL, div_ops,
  92. gate ? &gate->hw : NULL, gate_ops,
  93. flags);
  94. return clk;
  95. err_div:
  96. kfree(gate);
  97. err_gate:
  98. kfree(mux);
  99. return ERR_PTR(-ENOMEM);
  100. }
  101. static struct clk *rockchip_clk_register_frac_branch(const char *name,
  102. const char *const *parent_names, u8 num_parents,
  103. void __iomem *base, int muxdiv_offset, u8 div_flags,
  104. int gate_offset, u8 gate_shift, u8 gate_flags,
  105. unsigned long flags, spinlock_t *lock)
  106. {
  107. struct clk *clk;
  108. struct clk_gate *gate = NULL;
  109. struct clk_fractional_divider *div = NULL;
  110. const struct clk_ops *div_ops = NULL, *gate_ops = NULL;
  111. if (gate_offset >= 0) {
  112. gate = kzalloc(sizeof(*gate), GFP_KERNEL);
  113. if (!gate)
  114. return ERR_PTR(-ENOMEM);
  115. gate->flags = gate_flags;
  116. gate->reg = base + gate_offset;
  117. gate->bit_idx = gate_shift;
  118. gate->lock = lock;
  119. gate_ops = &clk_gate_ops;
  120. }
  121. if (muxdiv_offset < 0)
  122. return ERR_PTR(-EINVAL);
  123. div = kzalloc(sizeof(*div), GFP_KERNEL);
  124. if (!div)
  125. return ERR_PTR(-ENOMEM);
  126. div->flags = div_flags;
  127. div->reg = base + muxdiv_offset;
  128. div->mshift = 16;
  129. div->mwidth = 16;
  130. div->mmask = GENMASK(div->mwidth - 1, 0) << div->mshift;
  131. div->nshift = 0;
  132. div->nwidth = 16;
  133. div->nmask = GENMASK(div->nwidth - 1, 0) << div->nshift;
  134. div->lock = lock;
  135. div_ops = &clk_fractional_divider_ops;
  136. clk = clk_register_composite(NULL, name, parent_names, num_parents,
  137. NULL, NULL,
  138. &div->hw, div_ops,
  139. gate ? &gate->hw : NULL, gate_ops,
  140. flags);
  141. return clk;
  142. }
  143. static DEFINE_SPINLOCK(clk_lock);
  144. static struct clk **clk_table;
  145. static void __iomem *reg_base;
  146. static struct clk_onecell_data clk_data;
  147. static struct device_node *cru_node;
  148. static struct regmap *grf;
  149. void __init rockchip_clk_init(struct device_node *np, void __iomem *base,
  150. unsigned long nr_clks)
  151. {
  152. reg_base = base;
  153. cru_node = np;
  154. grf = ERR_PTR(-EPROBE_DEFER);
  155. clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL);
  156. if (!clk_table)
  157. pr_err("%s: could not allocate clock lookup table\n", __func__);
  158. clk_data.clks = clk_table;
  159. clk_data.clk_num = nr_clks;
  160. of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
  161. }
  162. struct regmap *rockchip_clk_get_grf(void)
  163. {
  164. if (IS_ERR(grf))
  165. grf = syscon_regmap_lookup_by_phandle(cru_node, "rockchip,grf");
  166. return grf;
  167. }
  168. void rockchip_clk_add_lookup(struct clk *clk, unsigned int id)
  169. {
  170. if (clk_table && id)
  171. clk_table[id] = clk;
  172. }
  173. void __init rockchip_clk_register_plls(struct rockchip_pll_clock *list,
  174. unsigned int nr_pll, int grf_lock_offset)
  175. {
  176. struct clk *clk;
  177. int idx;
  178. for (idx = 0; idx < nr_pll; idx++, list++) {
  179. clk = rockchip_clk_register_pll(list->type, list->name,
  180. list->parent_names, list->num_parents,
  181. reg_base, list->con_offset, grf_lock_offset,
  182. list->lock_shift, list->mode_offset,
  183. list->mode_shift, list->rate_table,
  184. list->pll_flags, &clk_lock);
  185. if (IS_ERR(clk)) {
  186. pr_err("%s: failed to register clock %s\n", __func__,
  187. list->name);
  188. continue;
  189. }
  190. rockchip_clk_add_lookup(clk, list->id);
  191. }
  192. }
  193. void __init rockchip_clk_register_branches(
  194. struct rockchip_clk_branch *list,
  195. unsigned int nr_clk)
  196. {
  197. struct clk *clk = NULL;
  198. unsigned int idx;
  199. unsigned long flags;
  200. for (idx = 0; idx < nr_clk; idx++, list++) {
  201. flags = list->flags;
  202. /* catch simple muxes */
  203. switch (list->branch_type) {
  204. case branch_mux:
  205. clk = clk_register_mux(NULL, list->name,
  206. list->parent_names, list->num_parents,
  207. flags, reg_base + list->muxdiv_offset,
  208. list->mux_shift, list->mux_width,
  209. list->mux_flags, &clk_lock);
  210. break;
  211. case branch_divider:
  212. if (list->div_table)
  213. clk = clk_register_divider_table(NULL,
  214. list->name, list->parent_names[0],
  215. flags, reg_base + list->muxdiv_offset,
  216. list->div_shift, list->div_width,
  217. list->div_flags, list->div_table,
  218. &clk_lock);
  219. else
  220. clk = clk_register_divider(NULL, list->name,
  221. list->parent_names[0], flags,
  222. reg_base + list->muxdiv_offset,
  223. list->div_shift, list->div_width,
  224. list->div_flags, &clk_lock);
  225. break;
  226. case branch_fraction_divider:
  227. clk = rockchip_clk_register_frac_branch(list->name,
  228. list->parent_names, list->num_parents,
  229. reg_base, list->muxdiv_offset, list->div_flags,
  230. list->gate_offset, list->gate_shift,
  231. list->gate_flags, flags, &clk_lock);
  232. break;
  233. case branch_gate:
  234. flags |= CLK_SET_RATE_PARENT;
  235. clk = clk_register_gate(NULL, list->name,
  236. list->parent_names[0], flags,
  237. reg_base + list->gate_offset,
  238. list->gate_shift, list->gate_flags, &clk_lock);
  239. break;
  240. case branch_composite:
  241. clk = rockchip_clk_register_branch(list->name,
  242. list->parent_names, list->num_parents,
  243. reg_base, list->muxdiv_offset, list->mux_shift,
  244. list->mux_width, list->mux_flags,
  245. list->div_shift, list->div_width,
  246. list->div_flags, list->div_table,
  247. list->gate_offset, list->gate_shift,
  248. list->gate_flags, flags, &clk_lock);
  249. break;
  250. case branch_mmc:
  251. clk = rockchip_clk_register_mmc(
  252. list->name,
  253. list->parent_names, list->num_parents,
  254. reg_base + list->muxdiv_offset,
  255. list->div_shift
  256. );
  257. break;
  258. case branch_inverter:
  259. clk = rockchip_clk_register_inverter(
  260. list->name, list->parent_names,
  261. list->num_parents,
  262. reg_base + list->muxdiv_offset,
  263. list->div_shift, list->div_flags, &clk_lock);
  264. break;
  265. }
  266. /* none of the cases above matched */
  267. if (!clk) {
  268. pr_err("%s: unknown clock type %d\n",
  269. __func__, list->branch_type);
  270. continue;
  271. }
  272. if (IS_ERR(clk)) {
  273. pr_err("%s: failed to register clock %s: %ld\n",
  274. __func__, list->name, PTR_ERR(clk));
  275. continue;
  276. }
  277. rockchip_clk_add_lookup(clk, list->id);
  278. }
  279. }
  280. void __init rockchip_clk_register_armclk(unsigned int lookup_id,
  281. const char *name, const char *const *parent_names,
  282. u8 num_parents,
  283. const struct rockchip_cpuclk_reg_data *reg_data,
  284. const struct rockchip_cpuclk_rate_table *rates,
  285. int nrates)
  286. {
  287. struct clk *clk;
  288. clk = rockchip_clk_register_cpuclk(name, parent_names, num_parents,
  289. reg_data, rates, nrates, reg_base,
  290. &clk_lock);
  291. if (IS_ERR(clk)) {
  292. pr_err("%s: failed to register clock %s: %ld\n",
  293. __func__, name, PTR_ERR(clk));
  294. return;
  295. }
  296. rockchip_clk_add_lookup(clk, lookup_id);
  297. }
  298. void __init rockchip_clk_protect_critical(const char *const clocks[],
  299. int nclocks)
  300. {
  301. int i;
  302. /* Protect the clocks that needs to stay on */
  303. for (i = 0; i < nclocks; i++) {
  304. struct clk *clk = __clk_lookup(clocks[i]);
  305. if (clk)
  306. clk_prepare_enable(clk);
  307. }
  308. }
  309. static unsigned int reg_restart;
  310. static int rockchip_restart_notify(struct notifier_block *this,
  311. unsigned long mode, void *cmd)
  312. {
  313. writel(0xfdb9, reg_base + reg_restart);
  314. return NOTIFY_DONE;
  315. }
  316. static struct notifier_block rockchip_restart_handler = {
  317. .notifier_call = rockchip_restart_notify,
  318. .priority = 128,
  319. };
  320. void __init rockchip_register_restart_notifier(unsigned int reg)
  321. {
  322. int ret;
  323. reg_restart = reg;
  324. ret = register_restart_handler(&rockchip_restart_handler);
  325. if (ret)
  326. pr_err("%s: cannot register restart handler, %d\n",
  327. __func__, ret);
  328. }