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