layerscape: add linux 4.9 support
[oweals/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 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