8026-cpufreq-qoriq-Don-t-look-at-clock-implementation-det.patch 7.3 KB

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