022-ARM-BCM-Clean-up-SMP-support-for-Broadcom-Kona.patch 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. From b5989f783de046577067fe356b1bb76cae07e867 Mon Sep 17 00:00:00 2001
  2. From: Kapil Hali <kapilh@broadcom.com>
  3. Date: Sat, 5 Dec 2015 06:53:41 -0500
  4. Subject: [PATCH] ARM: BCM: Clean up SMP support for Broadcom Kona
  5. These changes cleans up SMP implementaion for Broadcom's
  6. Kona SoC which are required for handling SMP for iProc
  7. family of SoCs at a single place for BCM NSP and BCM Kona.
  8. Signed-off-by: Kapil Hali <kapilh@broadcom.com>
  9. Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
  10. ---
  11. .../bindings/arm/bcm/brcm,bcm11351-cpu-method.txt | 12 ++--
  12. arch/arm/boot/dts/bcm11351.dtsi | 4 +-
  13. arch/arm/boot/dts/bcm21664.dtsi | 4 +-
  14. arch/arm/mach-bcm/kona_smp.c | 82 ++++++++++++++--------
  15. 4 files changed, 64 insertions(+), 38 deletions(-)
  16. --- a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm11351-cpu-method.txt
  17. +++ b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm11351-cpu-method.txt
  18. @@ -1,17 +1,17 @@
  19. Broadcom Kona Family CPU Enable Method
  20. --------------------------------------
  21. This binding defines the enable method used for starting secondary
  22. -CPUs in the following Broadcom SoCs:
  23. +CPU in the following Broadcom SoCs:
  24. BCM11130, BCM11140, BCM11351, BCM28145, BCM28155, BCM21664
  25. The enable method is specified by defining the following required
  26. -properties in the "cpus" device tree node:
  27. +properties in the corresponding secondary "cpu" device tree node:
  28. - enable-method = "brcm,bcm11351-cpu-method";
  29. - secondary-boot-reg = <...>;
  30. The secondary-boot-reg property is a u32 value that specifies the
  31. -physical address of the register used to request the ROM holding pen
  32. -code release a secondary CPU. The value written to the register is
  33. +physical address of the register used to request the ROM code
  34. +release a secondary CPU. The value written to the register is
  35. formed by encoding the target CPU id into the low bits of the
  36. physical start address it should jump to.
  37. @@ -19,8 +19,6 @@ Example:
  38. cpus {
  39. #address-cells = <1>;
  40. #size-cells = <0>;
  41. - enable-method = "brcm,bcm11351-cpu-method";
  42. - secondary-boot-reg = <0x3500417c>;
  43. cpu0: cpu@0 {
  44. device_type = "cpu";
  45. @@ -31,6 +29,8 @@ Example:
  46. cpu1: cpu@1 {
  47. device_type = "cpu";
  48. compatible = "arm,cortex-a9";
  49. + enable-method = "brcm,bcm11351-cpu-method";
  50. + secondary-boot-reg = <0x3500417c>;
  51. reg = <1>;
  52. };
  53. };
  54. --- a/arch/arm/boot/dts/bcm11351.dtsi
  55. +++ b/arch/arm/boot/dts/bcm11351.dtsi
  56. @@ -30,8 +30,6 @@
  57. cpus {
  58. #address-cells = <1>;
  59. #size-cells = <0>;
  60. - enable-method = "brcm,bcm11351-cpu-method";
  61. - secondary-boot-reg = <0x3500417c>;
  62. cpu0: cpu@0 {
  63. device_type = "cpu";
  64. @@ -42,6 +40,8 @@
  65. cpu1: cpu@1 {
  66. device_type = "cpu";
  67. compatible = "arm,cortex-a9";
  68. + enable-method = "brcm,bcm11351-cpu-method";
  69. + secondary-boot-reg = <0x3500417c>;
  70. reg = <1>;
  71. };
  72. };
  73. --- a/arch/arm/boot/dts/bcm21664.dtsi
  74. +++ b/arch/arm/boot/dts/bcm21664.dtsi
  75. @@ -30,8 +30,6 @@
  76. cpus {
  77. #address-cells = <1>;
  78. #size-cells = <0>;
  79. - enable-method = "brcm,bcm11351-cpu-method";
  80. - secondary-boot-reg = <0x35004178>;
  81. cpu0: cpu@0 {
  82. device_type = "cpu";
  83. @@ -42,6 +40,8 @@
  84. cpu1: cpu@1 {
  85. device_type = "cpu";
  86. compatible = "arm,cortex-a9";
  87. + enable-method = "brcm,bcm11351-cpu-method";
  88. + secondary-boot-reg = <0x35004178>;
  89. reg = <1>;
  90. };
  91. };
  92. --- a/arch/arm/mach-bcm/kona_smp.c
  93. +++ b/arch/arm/mach-bcm/kona_smp.c
  94. @@ -1,5 +1,5 @@
  95. /*
  96. - * Copyright (C) 2014 Broadcom Corporation
  97. + * Copyright (C) 2014-2015 Broadcom Corporation
  98. * Copyright 2014 Linaro Limited
  99. *
  100. * This program is free software; you can redistribute it and/or
  101. @@ -30,9 +30,10 @@
  102. /* Name of device node property defining secondary boot register location */
  103. #define OF_SECONDARY_BOOT "secondary-boot-reg"
  104. +#define MPIDR_CPUID_BITMASK 0x3
  105. /* I/O address of register used to coordinate secondary core startup */
  106. -static u32 secondary_boot;
  107. +static u32 secondary_boot_addr;
  108. /*
  109. * Enable the Cortex A9 Snoop Control Unit
  110. @@ -78,44 +79,68 @@ static int __init scu_a9_enable(void)
  111. static void __init bcm_smp_prepare_cpus(unsigned int max_cpus)
  112. {
  113. static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 };
  114. - struct device_node *node;
  115. + struct device_node *cpus_node = NULL;
  116. + struct device_node *cpu_node = NULL;
  117. int ret;
  118. - BUG_ON(secondary_boot); /* We're called only once */
  119. -
  120. /*
  121. * This function is only called via smp_ops->smp_prepare_cpu().
  122. * That only happens if a "/cpus" device tree node exists
  123. * and has an "enable-method" property that selects the SMP
  124. * operations defined herein.
  125. */
  126. - node = of_find_node_by_path("/cpus");
  127. - BUG_ON(!node);
  128. -
  129. - /*
  130. - * Our secondary enable method requires a "secondary-boot-reg"
  131. - * property to specify a register address used to request the
  132. - * ROM code boot a secondary code. If we have any trouble
  133. - * getting this we fall back to uniprocessor mode.
  134. - */
  135. - if (of_property_read_u32(node, OF_SECONDARY_BOOT, &secondary_boot)) {
  136. - pr_err("%s: missing/invalid " OF_SECONDARY_BOOT " property\n",
  137. - node->name);
  138. - ret = -ENOENT; /* Arrange to disable SMP */
  139. - goto out;
  140. + cpus_node = of_find_node_by_path("/cpus");
  141. + if (!cpus_node)
  142. + return;
  143. +
  144. + for_each_child_of_node(cpus_node, cpu_node) {
  145. + u32 cpuid;
  146. +
  147. + if (of_node_cmp(cpu_node->type, "cpu"))
  148. + continue;
  149. +
  150. + if (of_property_read_u32(cpu_node, "reg", &cpuid)) {
  151. + pr_debug("%s: missing reg property\n",
  152. + cpu_node->full_name);
  153. + ret = -ENOENT;
  154. + goto out;
  155. + }
  156. +
  157. + /*
  158. + * "secondary-boot-reg" property should be defined only
  159. + * for secondary cpu
  160. + */
  161. + if ((cpuid & MPIDR_CPUID_BITMASK) == 1) {
  162. + /*
  163. + * Our secondary enable method requires a
  164. + * "secondary-boot-reg" property to specify a register
  165. + * address used to request the ROM code boot a secondary
  166. + * core. If we have any trouble getting this we fall
  167. + * back to uniprocessor mode.
  168. + */
  169. + if (of_property_read_u32(cpu_node,
  170. + OF_SECONDARY_BOOT,
  171. + &secondary_boot_addr)) {
  172. + pr_warn("%s: no" OF_SECONDARY_BOOT "property\n",
  173. + cpu_node->name);
  174. + ret = -ENOENT;
  175. + goto out;
  176. + }
  177. + }
  178. }
  179. /*
  180. - * Enable the SCU on Cortex A9 based SoCs. If -ENOENT is
  181. + * Enable the SCU on Cortex A9 based SoCs. If -ENOENT is
  182. * returned, the SoC reported a uniprocessor configuration.
  183. * We bail on any other error.
  184. */
  185. ret = scu_a9_enable();
  186. out:
  187. - of_node_put(node);
  188. + of_node_put(cpu_node);
  189. + of_node_put(cpus_node);
  190. +
  191. if (ret) {
  192. /* Update the CPU present map to reflect uniprocessor mode */
  193. - BUG_ON(ret != -ENOENT);
  194. pr_warn("disabling SMP\n");
  195. init_cpu_present(&only_cpu_0);
  196. }
  197. @@ -139,7 +164,7 @@ out:
  198. * - Wait for the secondary boot register to be re-written, which
  199. * indicates the secondary core has started.
  200. */
  201. -static int bcm_boot_secondary(unsigned int cpu, struct task_struct *idle)
  202. +static int kona_boot_secondary(unsigned int cpu, struct task_struct *idle)
  203. {
  204. void __iomem *boot_reg;
  205. phys_addr_t boot_func;
  206. @@ -154,15 +179,16 @@ static int bcm_boot_secondary(unsigned i
  207. return -EINVAL;
  208. }
  209. - if (!secondary_boot) {
  210. + if (!secondary_boot_addr) {
  211. pr_err("required secondary boot register not specified\n");
  212. return -EINVAL;
  213. }
  214. - boot_reg = ioremap_nocache((phys_addr_t)secondary_boot, sizeof(u32));
  215. + boot_reg = ioremap_nocache(
  216. + (phys_addr_t)secondary_boot_addr, sizeof(u32));
  217. if (!boot_reg) {
  218. pr_err("unable to map boot register for cpu %u\n", cpu_id);
  219. - return -ENOSYS;
  220. + return -ENOMEM;
  221. }
  222. /*
  223. @@ -191,12 +217,12 @@ static int bcm_boot_secondary(unsigned i
  224. pr_err("timeout waiting for cpu %u to start\n", cpu_id);
  225. - return -ENOSYS;
  226. + return -ENXIO;
  227. }
  228. static struct smp_operations bcm_smp_ops __initdata = {
  229. .smp_prepare_cpus = bcm_smp_prepare_cpus,
  230. - .smp_boot_secondary = bcm_boot_secondary,
  231. + .smp_boot_secondary = kona_boot_secondary,
  232. };
  233. CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method",
  234. &bcm_smp_ops);