0009-ARM-qcom-Re-organize-platsmp-to-make-it-extensible.patch 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. From 391848e75f8b0ba14816da1ac8f2d838fd0d5744 Mon Sep 17 00:00:00 2001
  2. From: Rohit Vaswani <[email protected]>
  3. Date: Tue, 21 May 2013 19:13:29 -0700
  4. Subject: [PATCH 009/182] ARM: qcom: Re-organize platsmp to make it extensible
  5. This makes it easy to add SMP support for new devices by keying
  6. on a device node for the release sequence. We add the
  7. enable-method property for the cpus property to specify that we
  8. want to use the gcc-msm8660 release sequence (which is going to
  9. look for the global clock controller device node to map some
  10. Scorpion specific power and control registers). We also remove
  11. the nr_cpus detection code as that is done generically in the DT
  12. CPU detection code.
  13. Signed-off-by: Rohit Vaswani <[email protected]>
  14. [sboyd: Port to CPU_METHOD_OF_DECLARE]
  15. Signed-off-by: Stephen Boyd <[email protected]>
  16. Signed-off-by: Kumar Gala <[email protected]>
  17. ---
  18. arch/arm/mach-msm/common.h | 2 -
  19. arch/arm/mach-qcom/board.c | 14 -----
  20. arch/arm/mach-qcom/platsmp.c | 118 +++++++++++++++++++++++-------------------
  21. 3 files changed, 65 insertions(+), 69 deletions(-)
  22. --- a/arch/arm/mach-msm/common.h
  23. +++ b/arch/arm/mach-msm/common.h
  24. @@ -23,8 +23,6 @@ extern void msm_map_qsd8x50_io(void);
  25. extern void __iomem *__msm_ioremap_caller(phys_addr_t phys_addr, size_t size,
  26. unsigned int mtype, void *caller);
  27. -extern struct smp_operations msm_smp_ops;
  28. -
  29. struct msm_mmc_platform_data;
  30. extern void msm_add_devices(void);
  31. --- a/arch/arm/mach-qcom/board.c
  32. +++ b/arch/arm/mach-qcom/board.c
  33. @@ -11,30 +11,16 @@
  34. */
  35. #include <linux/init.h>
  36. -#include <linux/of.h>
  37. -#include <linux/of_platform.h>
  38. #include <asm/mach/arch.h>
  39. -#include <asm/mach/map.h>
  40. -
  41. -extern struct smp_operations qcom_smp_ops;
  42. static const char * const qcom_dt_match[] __initconst = {
  43. "qcom,msm8660-surf",
  44. "qcom,msm8960-cdp",
  45. - NULL
  46. -};
  47. -
  48. -static const char * const apq8074_dt_match[] __initconst = {
  49. "qcom,apq8074-dragonboard",
  50. NULL
  51. };
  52. DT_MACHINE_START(QCOM_DT, "Qualcomm (Flattened Device Tree)")
  53. - .smp = smp_ops(qcom_smp_ops),
  54. .dt_compat = qcom_dt_match,
  55. MACHINE_END
  56. -
  57. -DT_MACHINE_START(APQ_DT, "Qualcomm (Flattened Device Tree)")
  58. - .dt_compat = apq8074_dt_match,
  59. -MACHINE_END
  60. --- a/arch/arm/mach-qcom/platsmp.c
  61. +++ b/arch/arm/mach-qcom/platsmp.c
  62. @@ -13,17 +13,18 @@
  63. #include <linux/errno.h>
  64. #include <linux/delay.h>
  65. #include <linux/device.h>
  66. +#include <linux/of.h>
  67. +#include <linux/of_address.h>
  68. #include <linux/smp.h>
  69. #include <linux/io.h>
  70. -#include <asm/cputype.h>
  71. #include <asm/smp_plat.h>
  72. #include "scm-boot.h"
  73. -#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
  74. -#define SCSS_CPU1CORE_RESET 0xD80
  75. -#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
  76. +#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x35a0
  77. +#define SCSS_CPU1CORE_RESET 0x2d80
  78. +#define SCSS_DBG_STATUS_CORE_PWRDUP 0x2e64
  79. extern void secondary_startup(void);
  80. @@ -36,12 +37,6 @@ static void __ref qcom_cpu_die(unsigned
  81. }
  82. #endif
  83. -static inline int get_core_count(void)
  84. -{
  85. - /* 1 + the PART[1:0] field of MIDR */
  86. - return ((read_cpuid_id() >> 4) & 3) + 1;
  87. -}
  88. -
  89. static void qcom_secondary_init(unsigned int cpu)
  90. {
  91. /*
  92. @@ -51,33 +46,41 @@ static void qcom_secondary_init(unsigned
  93. spin_unlock(&boot_lock);
  94. }
  95. -static void prepare_cold_cpu(unsigned int cpu)
  96. +static int scss_release_secondary(unsigned int cpu)
  97. {
  98. - int ret;
  99. - ret = scm_set_boot_addr(virt_to_phys(secondary_startup),
  100. - SCM_FLAG_COLDBOOT_CPU1);
  101. - if (ret == 0) {
  102. - void __iomem *sc1_base_ptr;
  103. - sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2);
  104. - if (sc1_base_ptr) {
  105. - writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
  106. - writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET);
  107. - writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP);
  108. - iounmap(sc1_base_ptr);
  109. - }
  110. - } else
  111. - printk(KERN_DEBUG "Failed to set secondary core boot "
  112. - "address\n");
  113. + struct device_node *node;
  114. + void __iomem *base;
  115. +
  116. + node = of_find_compatible_node(NULL, NULL, "qcom,gcc-msm8660");
  117. + if (!node) {
  118. + pr_err("%s: can't find node\n", __func__);
  119. + return -ENXIO;
  120. + }
  121. +
  122. + base = of_iomap(node, 0);
  123. + of_node_put(node);
  124. + if (!base)
  125. + return -ENOMEM;
  126. +
  127. + writel_relaxed(0, base + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
  128. + writel_relaxed(0, base + SCSS_CPU1CORE_RESET);
  129. + writel_relaxed(3, base + SCSS_DBG_STATUS_CORE_PWRDUP);
  130. + mb();
  131. + iounmap(base);
  132. +
  133. + return 0;
  134. }
  135. -static int qcom_boot_secondary(unsigned int cpu, struct task_struct *idle)
  136. +static DEFINE_PER_CPU(int, cold_boot_done);
  137. +
  138. +static int qcom_boot_secondary(unsigned int cpu, int (*func)(unsigned int))
  139. {
  140. - static int cold_boot_done;
  141. + int ret = 0;
  142. - /* Only need to bring cpu out of reset this way once */
  143. - if (cold_boot_done == false) {
  144. - prepare_cold_cpu(cpu);
  145. - cold_boot_done = true;
  146. + if (!per_cpu(cold_boot_done, cpu)) {
  147. + ret = func(cpu);
  148. + if (!ret)
  149. + per_cpu(cold_boot_done, cpu) = true;
  150. }
  151. /*
  152. @@ -99,39 +102,48 @@ static int qcom_boot_secondary(unsigned
  153. */
  154. spin_unlock(&boot_lock);
  155. - return 0;
  156. + return ret;
  157. }
  158. -/*
  159. - * Initialise the CPU possible map early - this describes the CPUs
  160. - * which may be present or become present in the system. The msm8x60
  161. - * does not support the ARM SCU, so just set the possible cpu mask to
  162. - * NR_CPUS.
  163. - */
  164. -static void __init qcom_smp_init_cpus(void)
  165. -{
  166. - unsigned int i, ncores = get_core_count();
  167. -
  168. - if (ncores > nr_cpu_ids) {
  169. - pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
  170. - ncores, nr_cpu_ids);
  171. - ncores = nr_cpu_ids;
  172. - }
  173. -
  174. - for (i = 0; i < ncores; i++)
  175. - set_cpu_possible(i, true);
  176. +static int msm8660_boot_secondary(unsigned int cpu, struct task_struct *idle)
  177. +{
  178. + return qcom_boot_secondary(cpu, scss_release_secondary);
  179. }
  180. static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
  181. {
  182. + int cpu, map;
  183. + unsigned int flags = 0;
  184. + static const int cold_boot_flags[] = {
  185. + 0,
  186. + SCM_FLAG_COLDBOOT_CPU1,
  187. + };
  188. +
  189. + for_each_present_cpu(cpu) {
  190. + map = cpu_logical_map(cpu);
  191. + if (WARN_ON(map >= ARRAY_SIZE(cold_boot_flags))) {
  192. + set_cpu_present(cpu, false);
  193. + continue;
  194. + }
  195. + flags |= cold_boot_flags[map];
  196. + }
  197. +
  198. + if (scm_set_boot_addr(virt_to_phys(secondary_startup), flags)) {
  199. + for_each_present_cpu(cpu) {
  200. + if (cpu == smp_processor_id())
  201. + continue;
  202. + set_cpu_present(cpu, false);
  203. + }
  204. + pr_warn("Failed to set CPU boot address, disabling SMP\n");
  205. + }
  206. }
  207. -struct smp_operations qcom_smp_ops __initdata = {
  208. - .smp_init_cpus = qcom_smp_init_cpus,
  209. +static struct smp_operations smp_msm8660_ops __initdata = {
  210. .smp_prepare_cpus = qcom_smp_prepare_cpus,
  211. .smp_secondary_init = qcom_secondary_init,
  212. - .smp_boot_secondary = qcom_boot_secondary,
  213. + .smp_boot_secondary = msm8660_boot_secondary,
  214. #ifdef CONFIG_HOTPLUG_CPU
  215. .cpu_die = qcom_cpu_die,
  216. #endif
  217. };
  218. +CPU_METHOD_OF_DECLARE(qcom_smp, "qcom,gcc-msm8660", &smp_msm8660_ops);