layerscape: add 64b/32b target for ls1043ardb device
[openwrt/openwrt.git] / target / linux / layerscape / patches-4.4 / 8026-cpufreq-qoriq-Don-t-look-at-clock-implementation-det.patch
1 From 8f3768a7c649526f821a6a4cd32cc44a8e7fa317 Mon Sep 17 00:00:00 2001
2 From: Scott Wood <scottwood@freescale.com>
3 Date: Fri, 15 Jan 2016 07:34:33 +0000
4 Subject: [PATCH 26/70] cpufreq: qoriq: Don't look at clock implementation
5 details
6
7 Get the CPU clock's potential parent clocks from the clock interface
8 itself, rather than manually parsing the clocks property to find a
9 phandle, looking at the clock-names property of that, and assuming that
10 those are valid parent clocks for the cpu clock.
11
12 This is necessary now that the clocks are generated based on the clock
13 driver's knowledge of the chip rather than a fragile device-tree
14 description of the mux options.
15
16 We can now rely on the clock driver to ensure that the mux only exposes
17 options that are valid. The cpufreq driver was currently being overly
18 conservative in some cases -- for example, the "min_cpufreq =
19 get_bus_freq()" restriction only applies to chips with erratum
20 A-004510, and whether the freq_mask used on p5020 is needed depends on
21 the actual frequencies of the PLLs (FWIW, p5040 has a similar
22 limitation but its .freq_mask was zero) -- and the frequency mask
23 mechanism made assumptions about particular parent clock indices that
24 are no longer valid.
25
26 Signed-off-by: Scott Wood <scottwood@freescale.com>
27 Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
28 ---
29 drivers/cpufreq/qoriq-cpufreq.c | 138 ++++++++++++---------------------------
30 1 file changed, 41 insertions(+), 97 deletions(-)
31
32 --- a/drivers/cpufreq/qoriq-cpufreq.c
33 +++ b/drivers/cpufreq/qoriq-cpufreq.c
34 @@ -11,6 +11,7 @@
35 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
36
37 #include <linux/clk.h>
38 +#include <linux/clk-provider.h>
39 #include <linux/cpufreq.h>
40 #include <linux/errno.h>
41 #include <linux/init.h>
42 @@ -35,53 +36,20 @@ struct cpu_data {
43 struct cpufreq_frequency_table *table;
44 };
45
46 +/*
47 + * Don't use cpufreq on this SoC -- used when the SoC would have otherwise
48 + * matched a more generic compatible.
49 + */
50 +#define SOC_BLACKLIST 1
51 +
52 /**
53 * struct soc_data - SoC specific data
54 - * @freq_mask: mask the disallowed frequencies
55 - * @flag: unique flags
56 + * @flags: SOC_xxx
57 */
58 struct soc_data {
59 - u32 freq_mask[4];
60 - u32 flag;
61 -};
62 -
63 -#define FREQ_MASK 1
64 -/* see hardware specification for the allowed frqeuencies */
65 -static const struct soc_data sdata[] = {
66 - { /* used by p2041 and p3041 */
67 - .freq_mask = {0x8, 0x8, 0x2, 0x2},
68 - .flag = FREQ_MASK,
69 - },
70 - { /* used by p5020 */
71 - .freq_mask = {0x8, 0x2},
72 - .flag = FREQ_MASK,
73 - },
74 - { /* used by p4080, p5040 */
75 - .freq_mask = {0},
76 - .flag = 0,
77 - },
78 + u32 flags;
79 };
80
81 -/*
82 - * the minimum allowed core frequency, in Hz
83 - * for chassis v1.0, >= platform frequency
84 - * for chassis v2.0, >= platform frequency / 2
85 - */
86 -static u32 min_cpufreq;
87 -static const u32 *fmask;
88 -
89 -#if defined(CONFIG_ARM)
90 -static int get_cpu_physical_id(int cpu)
91 -{
92 - return topology_core_id(cpu);
93 -}
94 -#else
95 -static int get_cpu_physical_id(int cpu)
96 -{
97 - return get_hard_smp_processor_id(cpu);
98 -}
99 -#endif
100 -
101 static u32 get_bus_freq(void)
102 {
103 struct device_node *soc;
104 @@ -99,9 +67,10 @@ static u32 get_bus_freq(void)
105 return sysfreq;
106 }
107
108 -static struct device_node *cpu_to_clk_node(int cpu)
109 +static struct clk *cpu_to_clk(int cpu)
110 {
111 - struct device_node *np, *clk_np;
112 + struct device_node *np;
113 + struct clk *clk;
114
115 if (!cpu_present(cpu))
116 return NULL;
117 @@ -110,37 +79,28 @@ static struct device_node *cpu_to_clk_no
118 if (!np)
119 return NULL;
120
121 - clk_np = of_parse_phandle(np, "clocks", 0);
122 - if (!clk_np)
123 - return NULL;
124 -
125 + clk = of_clk_get(np, 0);
126 of_node_put(np);
127 -
128 - return clk_np;
129 + return clk;
130 }
131
132 /* traverse cpu nodes to get cpu mask of sharing clock wire */
133 static void set_affected_cpus(struct cpufreq_policy *policy)
134 {
135 - struct device_node *np, *clk_np;
136 struct cpumask *dstp = policy->cpus;
137 + struct clk *clk;
138 int i;
139
140 - np = cpu_to_clk_node(policy->cpu);
141 - if (!np)
142 - return;
143 -
144 for_each_present_cpu(i) {
145 - clk_np = cpu_to_clk_node(i);
146 - if (!clk_np)
147 + clk = cpu_to_clk(i);
148 + if (IS_ERR(clk)) {
149 + pr_err("%s: no clock for cpu %d\n", __func__, i);
150 continue;
151 + }
152
153 - if (clk_np == np)
154 + if (clk_is_match(policy->clk, clk))
155 cpumask_set_cpu(i, dstp);
156 -
157 - of_node_put(clk_np);
158 }
159 - of_node_put(np);
160 }
161
162 /* reduce the duplicated frequencies in frequency table */
163 @@ -198,7 +158,7 @@ static int qoriq_cpufreq_cpu_init(struct
164 {
165 struct device_node *np, *pnode;
166 int i, count, ret;
167 - u32 freq, mask;
168 + u32 freq;
169 struct clk *clk;
170 struct cpufreq_frequency_table *table;
171 struct cpu_data *data;
172 @@ -219,17 +179,12 @@ static int qoriq_cpufreq_cpu_init(struct
173 goto err_nomem2;
174 }
175
176 - pnode = of_parse_phandle(np, "clocks", 0);
177 - if (!pnode) {
178 - pr_err("%s: could not get clock information\n", __func__);
179 - goto err_nomem2;
180 - }
181 + count = clk_get_num_parents(policy->clk);
182
183 - count = of_property_count_strings(pnode, "clock-names");
184 data->pclk = kcalloc(count, sizeof(struct clk *), GFP_KERNEL);
185 if (!data->pclk) {
186 pr_err("%s: no memory\n", __func__);
187 - goto err_node;
188 + goto err_nomem2;
189 }
190
191 table = kcalloc(count + 1, sizeof(*table), GFP_KERNEL);
192 @@ -238,23 +193,11 @@ static int qoriq_cpufreq_cpu_init(struct
193 goto err_pclk;
194 }
195
196 - if (fmask)
197 - mask = fmask[get_cpu_physical_id(cpu)];
198 - else
199 - mask = 0x0;
200 -
201 for (i = 0; i < count; i++) {
202 - clk = of_clk_get(pnode, i);
203 + clk = clk_get_parent_by_index(policy->clk, i);
204 data->pclk[i] = clk;
205 freq = clk_get_rate(clk);
206 - /*
207 - * the clock is valid if its frequency is not masked
208 - * and large than minimum allowed frequency.
209 - */
210 - if (freq < min_cpufreq || (mask & (1 << i)))
211 - table[i].frequency = CPUFREQ_ENTRY_INVALID;
212 - else
213 - table[i].frequency = freq / 1000;
214 + table[i].frequency = freq / 1000;
215 table[i].driver_data = i;
216 }
217 freq_table_redup(table, count);
218 @@ -288,10 +231,7 @@ err_nomem1:
219 kfree(table);
220 err_pclk:
221 kfree(data->pclk);
222 -err_node:
223 - of_node_put(pnode);
224 err_nomem2:
225 - policy->driver_data = NULL;
226 kfree(data);
227 err_np:
228 of_node_put(np);
229 @@ -332,12 +272,20 @@ static struct cpufreq_driver qoriq_cpufr
230 .attr = cpufreq_generic_attr,
231 };
232
233 +static const struct soc_data blacklist = {
234 + .flags = SOC_BLACKLIST,
235 +};
236 +
237 static const struct of_device_id node_matches[] __initconst = {
238 - { .compatible = "fsl,p2041-clockgen", .data = &sdata[0], },
239 - { .compatible = "fsl,p3041-clockgen", .data = &sdata[0], },
240 - { .compatible = "fsl,p5020-clockgen", .data = &sdata[1], },
241 - { .compatible = "fsl,p4080-clockgen", .data = &sdata[2], },
242 - { .compatible = "fsl,p5040-clockgen", .data = &sdata[2], },
243 + /* e6500 cannot use cpufreq due to erratum A-008083 */
244 + { .compatible = "fsl,b4420-clockgen", &blacklist },
245 + { .compatible = "fsl,b4860-clockgen", &blacklist },
246 + { .compatible = "fsl,t2080-clockgen", &blacklist },
247 + { .compatible = "fsl,t4240-clockgen", &blacklist },
248 +
249 + { .compatible = "fsl,ls1021a-clockgen", },
250 + { .compatible = "fsl,p4080-clockgen", },
251 + { .compatible = "fsl,qoriq-clockgen-1.0", },
252 { .compatible = "fsl,qoriq-clockgen-2.0", },
253 {}
254 };
255 @@ -355,16 +303,12 @@ static int __init qoriq_cpufreq_init(voi
256
257 match = of_match_node(node_matches, np);
258 data = match->data;
259 - if (data) {
260 - if (data->flag)
261 - fmask = data->freq_mask;
262 - min_cpufreq = get_bus_freq();
263 - } else {
264 - min_cpufreq = get_bus_freq() / 2;
265 - }
266
267 of_node_put(np);
268
269 + if (data && data->flags & SOC_BLACKLIST)
270 + return -ENODEV;
271 +
272 ret = cpufreq_register_driver(&qoriq_cpufreq_driver);
273 if (!ret)
274 pr_info("Freescale QorIQ CPU frequency scaling driver\n");