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
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.
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.
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
26 Signed-off-by: Scott Wood <scottwood@freescale.com>
27 Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
29 drivers/cpufreq/qoriq-cpufreq.c | 138 ++++++++++++---------------------------
30 1 file changed, 41 insertions(+), 97 deletions(-)
32 --- a/drivers/cpufreq/qoriq-cpufreq.c
33 +++ b/drivers/cpufreq/qoriq-cpufreq.c
35 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
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;
47 + * Don't use cpufreq on this SoC -- used when the SoC would have otherwise
48 + * matched a more generic compatible.
50 +#define SOC_BLACKLIST 1
53 * struct soc_data - SoC specific data
54 - * @freq_mask: mask the disallowed frequencies
55 - * @flag: unique flags
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},
70 - { /* used by p5020 */
71 - .freq_mask = {0x8, 0x2},
74 - { /* used by p4080, p5040 */
82 - * the minimum allowed core frequency, in Hz
83 - * for chassis v1.0, >= platform frequency
84 - * for chassis v2.0, >= platform frequency / 2
86 -static u32 min_cpufreq;
87 -static const u32 *fmask;
89 -#if defined(CONFIG_ARM)
90 -static int get_cpu_physical_id(int cpu)
92 - return topology_core_id(cpu);
95 -static int get_cpu_physical_id(int cpu)
97 - return get_hard_smp_processor_id(cpu);
101 static u32 get_bus_freq(void)
103 struct device_node *soc;
104 @@ -99,9 +67,10 @@ static u32 get_bus_freq(void)
108 -static struct device_node *cpu_to_clk_node(int cpu)
109 +static struct clk *cpu_to_clk(int cpu)
111 - struct device_node *np, *clk_np;
112 + struct device_node *np;
115 if (!cpu_present(cpu))
117 @@ -110,37 +79,28 @@ static struct device_node *cpu_to_clk_no
121 - clk_np = of_parse_phandle(np, "clocks", 0);
125 + clk = of_clk_get(np, 0);
132 /* traverse cpu nodes to get cpu mask of sharing clock wire */
133 static void set_affected_cpus(struct cpufreq_policy *policy)
135 - struct device_node *np, *clk_np;
136 struct cpumask *dstp = policy->cpus;
140 - np = cpu_to_clk_node(policy->cpu);
144 for_each_present_cpu(i) {
145 - clk_np = cpu_to_clk_node(i);
147 + clk = cpu_to_clk(i);
149 + pr_err("%s: no clock for cpu %d\n", __func__, i);
154 + if (clk_is_match(policy->clk, clk))
155 cpumask_set_cpu(i, dstp);
157 - of_node_put(clk_np);
162 /* reduce the duplicated frequencies in frequency table */
163 @@ -198,7 +158,7 @@ static int qoriq_cpufreq_cpu_init(struct
165 struct device_node *np, *pnode;
170 struct cpufreq_frequency_table *table;
171 struct cpu_data *data;
172 @@ -219,17 +179,12 @@ static int qoriq_cpufreq_cpu_init(struct
176 - pnode = of_parse_phandle(np, "clocks", 0);
178 - pr_err("%s: could not get clock information\n", __func__);
181 + count = clk_get_num_parents(policy->clk);
183 - count = of_property_count_strings(pnode, "clock-names");
184 data->pclk = kcalloc(count, sizeof(struct clk *), GFP_KERNEL);
186 pr_err("%s: no memory\n", __func__);
191 table = kcalloc(count + 1, sizeof(*table), GFP_KERNEL);
192 @@ -238,23 +193,11 @@ static int qoriq_cpufreq_cpu_init(struct
197 - mask = fmask[get_cpu_physical_id(cpu)];
201 for (i = 0; i < count; i++) {
202 - clk = of_clk_get(pnode, i);
203 + clk = clk_get_parent_by_index(policy->clk, i);
205 freq = clk_get_rate(clk);
207 - * the clock is valid if its frequency is not masked
208 - * and large than minimum allowed frequency.
210 - if (freq < min_cpufreq || (mask & (1 << i)))
211 - table[i].frequency = CPUFREQ_ENTRY_INVALID;
213 - table[i].frequency = freq / 1000;
214 + table[i].frequency = freq / 1000;
215 table[i].driver_data = i;
217 freq_table_redup(table, count);
218 @@ -288,10 +231,7 @@ err_nomem1:
223 - of_node_put(pnode);
225 - policy->driver_data = NULL;
229 @@ -332,12 +272,20 @@ static struct cpufreq_driver qoriq_cpufr
230 .attr = cpufreq_generic_attr,
233 +static const struct soc_data blacklist = {
234 + .flags = SOC_BLACKLIST,
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 },
249 + { .compatible = "fsl,ls1021a-clockgen", },
250 + { .compatible = "fsl,p4080-clockgen", },
251 + { .compatible = "fsl,qoriq-clockgen-1.0", },
252 { .compatible = "fsl,qoriq-clockgen-2.0", },
255 @@ -355,16 +303,12 @@ static int __init qoriq_cpufreq_init(voi
257 match = of_match_node(node_matches, np);
261 - fmask = data->freq_mask;
262 - min_cpufreq = get_bus_freq();
264 - min_cpufreq = get_bus_freq() / 2;
269 + if (data && data->flags & SOC_BLACKLIST)
272 ret = cpufreq_register_driver(&qoriq_cpufreq_driver);
274 pr_info("Freescale QorIQ CPU frequency scaling driver\n");