881e3848b475c266d58214da62be967e33d4cc39
[openwrt/staging/hauke.git] / target / linux / layerscape / patches-4.9 / 802-clk-support-layerscape.patch
1 From bd3df6d053a28d5aa630524c9087c21def30e764 Mon Sep 17 00:00:00 2001
2 From: Yangbo Lu <yangbo.lu@nxp.com>
3 Date: Mon, 25 Sep 2017 12:09:35 +0800
4 Subject: [PATCH] clk: support layerscape
5
6 This is a integrated patch for layerscape clock support.
7
8 Signed-off-by: Yuantian Tang <andy.tang@nxp.com>
9 Signed-off-by: Mingkai Hu <mingkai.hu@nxp.com>
10 Signed-off-by: Scott Wood <oss@buserror.net>
11 Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
12 ---
13 drivers/clk/clk-qoriq.c | 170 ++++++++++++++++++++++++++++++++++++++++++++----
14 1 file changed, 156 insertions(+), 14 deletions(-)
15
16 diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c
17 index 80ae2a51..0e7de00a 100644
18 --- a/drivers/clk/clk-qoriq.c
19 +++ b/drivers/clk/clk-qoriq.c
20 @@ -12,6 +12,7 @@
21
22 #include <linux/clk.h>
23 #include <linux/clk-provider.h>
24 +#include <linux/clkdev.h>
25 #include <linux/fsl/guts.h>
26 #include <linux/io.h>
27 #include <linux/kernel.h>
28 @@ -87,7 +88,7 @@ struct clockgen {
29 struct device_node *node;
30 void __iomem *regs;
31 struct clockgen_chipinfo info; /* mutable copy */
32 - struct clk *sysclk;
33 + struct clk *sysclk, *coreclk;
34 struct clockgen_pll pll[6];
35 struct clk *cmux[NUM_CMUX];
36 struct clk *hwaccel[NUM_HWACCEL];
37 @@ -266,6 +267,39 @@ static const struct clockgen_muxinfo ls1043a_hwa2 = {
38 },
39 };
40
41 +static const struct clockgen_muxinfo ls1046a_hwa1 = {
42 + {
43 + {},
44 + {},
45 + { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
46 + { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
47 + { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 },
48 + { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
49 + { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
50 + { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
51 + },
52 +};
53 +
54 +static const struct clockgen_muxinfo ls1046a_hwa2 = {
55 + {
56 + {},
57 + { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
58 + { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
59 + { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
60 + {},
61 + {},
62 + { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
63 + },
64 +};
65 +
66 +static const struct clockgen_muxinfo ls1012a_cmux = {
67 + {
68 + [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
69 + {},
70 + [2] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
71 + }
72 +};
73 +
74 static const struct clockgen_muxinfo t1023_hwa1 = {
75 {
76 {},
77 @@ -488,6 +522,42 @@ static const struct clockgen_chipinfo chipinfo[] = {
78 .pll_mask = 0x07,
79 .flags = CG_PLL_8BIT,
80 },
81 + {
82 + .compat = "fsl,ls1046a-clockgen",
83 + .init_periph = t2080_init_periph,
84 + .cmux_groups = {
85 + &t1040_cmux
86 + },
87 + .hwaccel = {
88 + &ls1046a_hwa1, &ls1046a_hwa2
89 + },
90 + .cmux_to_group = {
91 + 0, -1
92 + },
93 + .pll_mask = 0x07,
94 + .flags = CG_PLL_8BIT,
95 + },
96 + {
97 + .compat = "fsl,ls1088a-clockgen",
98 + .cmux_groups = {
99 + &clockgen2_cmux_cga12
100 + },
101 + .cmux_to_group = {
102 + 0, 0, -1
103 + },
104 + .pll_mask = 0x07,
105 + .flags = CG_VER3 | CG_LITTLE_ENDIAN,
106 + },
107 + {
108 + .compat = "fsl,ls1012a-clockgen",
109 + .cmux_groups = {
110 + &ls1012a_cmux
111 + },
112 + .cmux_to_group = {
113 + 0, -1
114 + },
115 + .pll_mask = 0x03,
116 + },
117 {
118 .compat = "fsl,ls2080a-clockgen",
119 .cmux_groups = {
120 @@ -846,7 +916,12 @@ static void __init create_muxes(struct clockgen *cg)
121
122 static void __init clockgen_init(struct device_node *np);
123
124 -/* Legacy nodes may get probed before the parent clockgen node */
125 +/*
126 + * Legacy nodes may get probed before the parent clockgen node.
127 + * It is assumed that device trees with legacy nodes will not
128 + * contain a "clocks" property -- otherwise the input clocks may
129 + * not be initialized at this point.
130 + */
131 static void __init legacy_init_clockgen(struct device_node *np)
132 {
133 if (!clockgen.node)
134 @@ -887,18 +962,13 @@ static struct clk __init
135 return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
136 }
137
138 -static struct clk *sysclk_from_parent(const char *name)
139 +static struct clk __init *input_clock(const char *name, struct clk *clk)
140 {
141 - struct clk *clk;
142 - const char *parent_name;
143 -
144 - clk = of_clk_get(clockgen.node, 0);
145 - if (IS_ERR(clk))
146 - return clk;
147 + const char *input_name;
148
149 /* Register the input clock under the desired name. */
150 - parent_name = __clk_get_name(clk);
151 - clk = clk_register_fixed_factor(NULL, name, parent_name,
152 + input_name = __clk_get_name(clk);
153 + clk = clk_register_fixed_factor(NULL, name, input_name,
154 0, 1, 1);
155 if (IS_ERR(clk))
156 pr_err("%s: Couldn't register %s: %ld\n", __func__, name,
157 @@ -907,6 +977,29 @@ static struct clk *sysclk_from_parent(const char *name)
158 return clk;
159 }
160
161 +static struct clk __init *input_clock_by_name(const char *name,
162 + const char *dtname)
163 +{
164 + struct clk *clk;
165 +
166 + clk = of_clk_get_by_name(clockgen.node, dtname);
167 + if (IS_ERR(clk))
168 + return clk;
169 +
170 + return input_clock(name, clk);
171 +}
172 +
173 +static struct clk __init *input_clock_by_index(const char *name, int idx)
174 +{
175 + struct clk *clk;
176 +
177 + clk = of_clk_get(clockgen.node, 0);
178 + if (IS_ERR(clk))
179 + return clk;
180 +
181 + return input_clock(name, clk);
182 +}
183 +
184 static struct clk * __init create_sysclk(const char *name)
185 {
186 struct device_node *sysclk;
187 @@ -916,7 +1009,11 @@ static struct clk * __init create_sysclk(const char *name)
188 if (!IS_ERR(clk))
189 return clk;
190
191 - clk = sysclk_from_parent(name);
192 + clk = input_clock_by_name(name, "sysclk");
193 + if (!IS_ERR(clk))
194 + return clk;
195 +
196 + clk = input_clock_by_index(name, 0);
197 if (!IS_ERR(clk))
198 return clk;
199
200 @@ -927,7 +1024,27 @@ static struct clk * __init create_sysclk(const char *name)
201 return clk;
202 }
203
204 - pr_err("%s: No input clock\n", __func__);
205 + pr_err("%s: No input sysclk\n", __func__);
206 + return NULL;
207 +}
208 +
209 +static struct clk * __init create_coreclk(const char *name)
210 +{
211 + struct clk *clk;
212 +
213 + clk = input_clock_by_name(name, "coreclk");
214 + if (!IS_ERR(clk))
215 + return clk;
216 +
217 + /*
218 + * This indicates a mix of legacy nodes with the new coreclk
219 + * mechanism, which should never happen. If this error occurs,
220 + * don't use the wrong input clock just because coreclk isn't
221 + * ready yet.
222 + */
223 + if (WARN_ON(PTR_ERR(clk) == -EPROBE_DEFER))
224 + return clk;
225 +
226 return NULL;
227 }
228
229 @@ -950,11 +1067,19 @@ static void __init create_one_pll(struct clockgen *cg, int idx)
230 u32 __iomem *reg;
231 u32 mult;
232 struct clockgen_pll *pll = &cg->pll[idx];
233 + const char *input = "cg-sysclk";
234 int i;
235
236 if (!(cg->info.pll_mask & (1 << idx)))
237 return;
238
239 + if (cg->coreclk && idx != PLATFORM_PLL) {
240 + if (IS_ERR(cg->coreclk))
241 + return;
242 +
243 + input = "cg-coreclk";
244 + }
245 +
246 if (cg->info.flags & CG_VER3) {
247 switch (idx) {
248 case PLATFORM_PLL:
249 @@ -1000,12 +1125,13 @@ static void __init create_one_pll(struct clockgen *cg, int idx)
250
251 for (i = 0; i < ARRAY_SIZE(pll->div); i++) {
252 struct clk *clk;
253 + int ret;
254
255 snprintf(pll->div[i].name, sizeof(pll->div[i].name),
256 "cg-pll%d-div%d", idx, i + 1);
257
258 clk = clk_register_fixed_factor(NULL,
259 - pll->div[i].name, "cg-sysclk", 0, mult, i + 1);
260 + pll->div[i].name, input, 0, mult, i + 1);
261 if (IS_ERR(clk)) {
262 pr_err("%s: %s: register failed %ld\n",
263 __func__, pll->div[i].name, PTR_ERR(clk));
264 @@ -1013,6 +1139,11 @@ static void __init create_one_pll(struct clockgen *cg, int idx)
265 }
266
267 pll->div[i].clk = clk;
268 + ret = clk_register_clkdev(clk, pll->div[i].name, NULL);
269 + if (ret != 0)
270 + pr_err("%s: %s: register to lookup table failed %ld\n",
271 + __func__, pll->div[i].name, PTR_ERR(clk));
272 +
273 }
274 }
275
276 @@ -1142,6 +1273,13 @@ static struct clk *clockgen_clk_get(struct of_phandle_args *clkspec, void *data)
277 goto bad_args;
278 clk = pll->div[idx].clk;
279 break;
280 + case 5:
281 + if (idx != 0)
282 + goto bad_args;
283 + clk = cg->coreclk;
284 + if (IS_ERR(clk))
285 + clk = NULL;
286 + break;
287 default:
288 goto bad_args;
289 }
290 @@ -1253,6 +1391,7 @@ static void __init clockgen_init(struct device_node *np)
291 clockgen.info.flags |= CG_CMUX_GE_PLAT;
292
293 clockgen.sysclk = create_sysclk("cg-sysclk");
294 + clockgen.coreclk = create_coreclk("cg-coreclk");
295 create_plls(&clockgen);
296 create_muxes(&clockgen);
297
298 @@ -1273,8 +1412,11 @@ static void __init clockgen_init(struct device_node *np)
299
300 CLK_OF_DECLARE(qoriq_clockgen_1, "fsl,qoriq-clockgen-1.0", clockgen_init);
301 CLK_OF_DECLARE(qoriq_clockgen_2, "fsl,qoriq-clockgen-2.0", clockgen_init);
302 +CLK_OF_DECLARE(qoriq_clockgen_ls1012a, "fsl,ls1012a-clockgen", clockgen_init);
303 CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init);
304 CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init);
305 +CLK_OF_DECLARE(qoriq_clockgen_ls1046a, "fsl,ls1046a-clockgen", clockgen_init);
306 +CLK_OF_DECLARE(qoriq_clockgen_ls1088a, "fsl,ls1088a-clockgen", clockgen_init);
307 CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init);
308
309 /* Legacy nodes */
310 --
311 2.14.1
312