0054-clk-mediatek-Export-CPU-mux-clocks-for-CPU-frequency.patch 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. From 1387d4f0ebf4b48c09f2ea0d27a02936c3fa0010 Mon Sep 17 00:00:00 2001
  2. From: John Crispin <blogic@openwrt.org>
  3. Date: Thu, 31 Mar 2016 02:26:37 +0200
  4. Subject: [PATCH 054/102] clk: mediatek: Export CPU mux clocks for CPU
  5. frequency control
  6. This patch adds CPU mux clocks which are used by Mediatek cpufreq driver
  7. for intermediate clock source switching.
  8. Signed-off-by: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
  9. ---
  10. drivers/clk/mediatek/Makefile | 2 +-
  11. drivers/clk/mediatek/clk-cpumux.c | 127 ++++++++++++++++++++++++++++++++
  12. drivers/clk/mediatek/clk-cpumux.h | 22 ++++++
  13. drivers/clk/mediatek/clk-mt2701.c | 8 ++
  14. drivers/clk/mediatek/clk-mt8173.c | 23 ++++++
  15. include/dt-bindings/clock/mt2701-clk.h | 3 +-
  16. include/dt-bindings/clock/mt8173-clk.h | 4 +-
  17. 7 files changed, 186 insertions(+), 3 deletions(-)
  18. create mode 100644 drivers/clk/mediatek/clk-cpumux.c
  19. create mode 100644 drivers/clk/mediatek/clk-cpumux.h
  20. --- a/drivers/clk/mediatek/Makefile
  21. +++ b/drivers/clk/mediatek/Makefile
  22. @@ -1,4 +1,4 @@
  23. -obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o
  24. +obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o
  25. obj-$(CONFIG_RESET_CONTROLLER) += reset.o
  26. obj-$(CONFIG_COMMON_CLK_MT2701) += clk-mt2701.o
  27. obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
  28. --- /dev/null
  29. +++ b/drivers/clk/mediatek/clk-cpumux.c
  30. @@ -0,0 +1,127 @@
  31. +/*
  32. + * Copyright (c) 2015 Linaro Ltd.
  33. + * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
  34. + *
  35. + * This program is free software; you can redistribute it and/or modify
  36. + * it under the terms of the GNU General Public License version 2 as
  37. + * published by the Free Software Foundation.
  38. + *
  39. + * This program is distributed in the hope that it will be useful,
  40. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  41. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  42. + * GNU General Public License for more details.
  43. + */
  44. +
  45. +#include <linux/clk-provider.h>
  46. +#include <linux/mfd/syscon.h>
  47. +#include <linux/slab.h>
  48. +
  49. +#include "clk-mtk.h"
  50. +#include "clk-cpumux.h"
  51. +
  52. +struct mtk_clk_cpumux {
  53. + struct clk_hw hw;
  54. + struct regmap *regmap;
  55. + u32 reg;
  56. + u32 mask;
  57. + u8 shift;
  58. +};
  59. +
  60. +static inline struct mtk_clk_cpumux *to_clk_mux(struct clk_hw *_hw)
  61. +{
  62. + return container_of(_hw, struct mtk_clk_cpumux, hw);
  63. +}
  64. +
  65. +static u8 clk_cpumux_get_parent(struct clk_hw *hw)
  66. +{
  67. + struct mtk_clk_cpumux *mux = to_clk_mux(hw);
  68. + int num_parents = clk_hw_get_num_parents(hw);
  69. + unsigned int val;
  70. +
  71. + regmap_read(mux->regmap, mux->reg, &val);
  72. +
  73. + val >>= mux->shift;
  74. + val &= mux->mask;
  75. +
  76. + if (val >= num_parents)
  77. + return -EINVAL;
  78. +
  79. + return val;
  80. +}
  81. +
  82. +static int clk_cpumux_set_parent(struct clk_hw *hw, u8 index)
  83. +{
  84. + struct mtk_clk_cpumux *mux = to_clk_mux(hw);
  85. + u32 mask, val;
  86. +
  87. + val = index << mux->shift;
  88. + mask = mux->mask << mux->shift;
  89. +
  90. + return regmap_update_bits(mux->regmap, mux->reg, mask, val);
  91. +}
  92. +
  93. +static const struct clk_ops clk_cpumux_ops = {
  94. + .get_parent = clk_cpumux_get_parent,
  95. + .set_parent = clk_cpumux_set_parent,
  96. +};
  97. +
  98. +static struct clk __init *mtk_clk_register_cpumux(const struct mtk_composite *mux,
  99. + struct regmap *regmap)
  100. +{
  101. + struct mtk_clk_cpumux *cpumux;
  102. + struct clk *clk;
  103. + struct clk_init_data init;
  104. +
  105. + cpumux = kzalloc(sizeof(*cpumux), GFP_KERNEL);
  106. + if (!cpumux)
  107. + return ERR_PTR(-ENOMEM);
  108. +
  109. + init.name = mux->name;
  110. + init.ops = &clk_cpumux_ops;
  111. + init.parent_names = mux->parent_names;
  112. + init.num_parents = mux->num_parents;
  113. + init.flags = mux->flags;
  114. +
  115. + cpumux->reg = mux->mux_reg;
  116. + cpumux->shift = mux->mux_shift;
  117. + cpumux->mask = BIT(mux->mux_width) - 1;
  118. + cpumux->regmap = regmap;
  119. + cpumux->hw.init = &init;
  120. +
  121. + clk = clk_register(NULL, &cpumux->hw);
  122. + if (IS_ERR(clk))
  123. + kfree(cpumux);
  124. +
  125. + return clk;
  126. +}
  127. +
  128. +int __init mtk_clk_register_cpumuxes(struct device_node *node,
  129. + const struct mtk_composite *clks, int num,
  130. + struct clk_onecell_data *clk_data)
  131. +{
  132. + int i;
  133. + struct clk *clk;
  134. + struct regmap *regmap;
  135. +
  136. + regmap = syscon_node_to_regmap(node);
  137. + if (IS_ERR(regmap)) {
  138. + pr_err("Cannot find regmap for %s: %ld\n", node->full_name,
  139. + PTR_ERR(regmap));
  140. + return PTR_ERR(regmap);
  141. + }
  142. +
  143. + for (i = 0; i < num; i++) {
  144. + const struct mtk_composite *mux = &clks[i];
  145. +
  146. + clk = mtk_clk_register_cpumux(mux, regmap);
  147. + if (IS_ERR(clk)) {
  148. + pr_err("Failed to register clk %s: %ld\n",
  149. + mux->name, PTR_ERR(clk));
  150. + continue;
  151. + }
  152. +
  153. + clk_data->clks[mux->id] = clk;
  154. + }
  155. +
  156. + return 0;
  157. +}
  158. --- /dev/null
  159. +++ b/drivers/clk/mediatek/clk-cpumux.h
  160. @@ -0,0 +1,22 @@
  161. +/*
  162. + * Copyright (c) 2015 Linaro Ltd.
  163. + * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
  164. + *
  165. + * This program is free software; you can redistribute it and/or modify
  166. + * it under the terms of the GNU General Public License version 2 as
  167. + * published by the Free Software Foundation.
  168. + *
  169. + * This program is distributed in the hope that it will be useful,
  170. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  171. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  172. + * GNU General Public License for more details.
  173. + */
  174. +
  175. +#ifndef __DRV_CLK_CPUMUX_H
  176. +#define __DRV_CLK_CPUMUX_H
  177. +
  178. +int mtk_clk_register_cpumuxes(struct device_node *node,
  179. + const struct mtk_composite *clks, int num,
  180. + struct clk_onecell_data *clk_data);
  181. +
  182. +#endif /* __DRV_CLK_CPUMUX_H */
  183. --- a/drivers/clk/mediatek/clk-mt2701.c
  184. +++ b/drivers/clk/mediatek/clk-mt2701.c
  185. @@ -18,6 +18,7 @@
  186. #include "clk-mtk.h"
  187. #include "clk-gate.h"
  188. +#include "clk-cpumux.h"
  189. #include <dt-bindings/clock/mt2701-clk.h>
  190. @@ -465,6 +466,10 @@ static const char * const cpu_parents[]
  191. "mmpll"
  192. };
  193. +static const struct mtk_composite cpu_muxes[] __initconst = {
  194. + MUX(CLK_INFRA_CPUSEL, "infra_cpu_sel", cpu_parents, 0x0000, 2, 2),
  195. +};
  196. +
  197. static const struct mtk_composite top_muxes[] __initconst = {
  198. MUX_GATE(CLK_TOP_AXI_SEL, "axi_sel", axi_parents,
  199. 0x0040, 0, 3, INVALID_MUX_GATE_BIT),
  200. @@ -677,6 +682,9 @@ static void __init mtk_infrasys_init(str
  201. mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
  202. clk_data);
  203. + mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
  204. + clk_data);
  205. +
  206. r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
  207. if (r)
  208. pr_err("%s(): could not register clock provider: %d\n",
  209. --- a/drivers/clk/mediatek/clk-mt8173.c
  210. +++ b/drivers/clk/mediatek/clk-mt8173.c
  211. @@ -18,6 +18,7 @@
  212. #include "clk-mtk.h"
  213. #include "clk-gate.h"
  214. +#include "clk-cpumux.h"
  215. #include <dt-bindings/clock/mt8173-clk.h>
  216. @@ -526,6 +527,25 @@ static const char * const i2s3_b_ck_pare
  217. "apll2_div5"
  218. };
  219. +static const char * const ca53_parents[] __initconst = {
  220. + "clk26m",
  221. + "armca7pll",
  222. + "mainpll",
  223. + "univpll"
  224. +};
  225. +
  226. +static const char * const ca57_parents[] __initconst = {
  227. + "clk26m",
  228. + "armca15pll",
  229. + "mainpll",
  230. + "univpll"
  231. +};
  232. +
  233. +static const struct mtk_composite cpu_muxes[] __initconst = {
  234. + MUX(CLK_INFRA_CA53SEL, "infra_ca53_sel", ca53_parents, 0x0000, 0, 2),
  235. + MUX(CLK_INFRA_CA57SEL, "infra_ca57_sel", ca57_parents, 0x0000, 2, 2),
  236. +};
  237. +
  238. static const struct mtk_composite top_muxes[] __initconst = {
  239. /* CLK_CFG_0 */
  240. MUX(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, 0x0040, 0, 3),
  241. @@ -945,6 +965,9 @@ static void __init mtk_infrasys_init(str
  242. clk_data);
  243. mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data);
  244. + mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
  245. + clk_data);
  246. +
  247. r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
  248. if (r)
  249. pr_err("%s(): could not register clock provider: %d\n",
  250. --- a/include/dt-bindings/clock/mt2701-clk.h
  251. +++ b/include/dt-bindings/clock/mt2701-clk.h
  252. @@ -217,7 +217,8 @@
  253. #define CLK_INFRA_PMICWRAP 17
  254. #define CLK_INFRA_DDCCI 18
  255. #define CLK_INFRA_CLK_13M 19
  256. -#define CLK_INFRA_NR 20
  257. +#define CLK_INFRA_CPUSEL 20
  258. +#define CLK_INFRA_NR 21
  259. /* PERICFG */
  260. --- a/include/dt-bindings/clock/mt8173-clk.h
  261. +++ b/include/dt-bindings/clock/mt8173-clk.h
  262. @@ -192,7 +192,9 @@
  263. #define CLK_INFRA_PMICSPI 10
  264. #define CLK_INFRA_PMICWRAP 11
  265. #define CLK_INFRA_CLK_13M 12
  266. -#define CLK_INFRA_NR_CLK 13
  267. +#define CLK_INFRA_CA53SEL 13
  268. +#define CLK_INFRA_CA57SEL 14
  269. +#define CLK_INFRA_NR_CLK 15
  270. /* PERI_SYS */