0013-ARM-qcom-Add-SMP-support-for-KPSSv1.patch 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. From 8e843640b3c4a43b963332fdc7b233948ad25a5b Mon Sep 17 00:00:00 2001
  2. From: Rohit Vaswani <[email protected]>
  3. Date: Tue, 21 May 2013 19:13:50 -0700
  4. Subject: [PATCH 013/182] ARM: qcom: Add SMP support for KPSSv1
  5. Implement support for the Krait CPU release sequence when the
  6. CPUs are part of the first version of the krait processor
  7. subsystem.
  8. Signed-off-by: Rohit Vaswani <[email protected]>
  9. Signed-off-by: Stephen Boyd <[email protected]>
  10. Signed-off-by: Kumar Gala <[email protected]>
  11. ---
  12. arch/arm/mach-qcom/platsmp.c | 106 +++++++++++++++++++++++++++++++++++++++++
  13. arch/arm/mach-qcom/scm-boot.h | 8 ++--
  14. 2 files changed, 111 insertions(+), 3 deletions(-)
  15. --- a/arch/arm/mach-qcom/platsmp.c
  16. +++ b/arch/arm/mach-qcom/platsmp.c
  17. @@ -26,6 +26,16 @@
  18. #define SCSS_CPU1CORE_RESET 0x2d80
  19. #define SCSS_DBG_STATUS_CORE_PWRDUP 0x2e64
  20. +#define APCS_CPU_PWR_CTL 0x04
  21. +#define PLL_CLAMP BIT(8)
  22. +#define CORE_PWRD_UP BIT(7)
  23. +#define COREPOR_RST BIT(5)
  24. +#define CORE_RST BIT(4)
  25. +#define L2DT_SLP BIT(3)
  26. +#define CLAMP BIT(0)
  27. +
  28. +#define APCS_SAW2_VCTL 0x14
  29. +
  30. extern void secondary_startup(void);
  31. static DEFINE_SPINLOCK(boot_lock);
  32. @@ -71,6 +81,85 @@ static int scss_release_secondary(unsign
  33. return 0;
  34. }
  35. +static int kpssv1_release_secondary(unsigned int cpu)
  36. +{
  37. + int ret = 0;
  38. + void __iomem *reg, *saw_reg;
  39. + struct device_node *cpu_node, *acc_node, *saw_node;
  40. + u32 val;
  41. +
  42. + cpu_node = of_get_cpu_node(cpu, NULL);
  43. + if (!cpu_node)
  44. + return -ENODEV;
  45. +
  46. + acc_node = of_parse_phandle(cpu_node, "qcom,acc", 0);
  47. + if (!acc_node) {
  48. + ret = -ENODEV;
  49. + goto out_acc;
  50. + }
  51. +
  52. + saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0);
  53. + if (!saw_node) {
  54. + ret = -ENODEV;
  55. + goto out_saw;
  56. + }
  57. +
  58. + reg = of_iomap(acc_node, 0);
  59. + if (!reg) {
  60. + ret = -ENOMEM;
  61. + goto out_acc_map;
  62. + }
  63. +
  64. + saw_reg = of_iomap(saw_node, 0);
  65. + if (!saw_reg) {
  66. + ret = -ENOMEM;
  67. + goto out_saw_map;
  68. + }
  69. +
  70. + /* Turn on CPU rail */
  71. + writel_relaxed(0xA4, saw_reg + APCS_SAW2_VCTL);
  72. + mb();
  73. + udelay(512);
  74. +
  75. + /* Krait bring-up sequence */
  76. + val = PLL_CLAMP | L2DT_SLP | CLAMP;
  77. + writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
  78. + val &= ~L2DT_SLP;
  79. + writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
  80. + mb();
  81. + ndelay(300);
  82. +
  83. + val |= COREPOR_RST;
  84. + writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
  85. + mb();
  86. + udelay(2);
  87. +
  88. + val &= ~CLAMP;
  89. + writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
  90. + mb();
  91. + udelay(2);
  92. +
  93. + val &= ~COREPOR_RST;
  94. + writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
  95. + mb();
  96. + udelay(100);
  97. +
  98. + val |= CORE_PWRD_UP;
  99. + writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
  100. + mb();
  101. +
  102. + iounmap(saw_reg);
  103. +out_saw_map:
  104. + iounmap(reg);
  105. +out_acc_map:
  106. + of_node_put(saw_node);
  107. +out_saw:
  108. + of_node_put(acc_node);
  109. +out_acc:
  110. + of_node_put(cpu_node);
  111. + return ret;
  112. +}
  113. +
  114. static DEFINE_PER_CPU(int, cold_boot_done);
  115. static int qcom_boot_secondary(unsigned int cpu, int (*func)(unsigned int))
  116. @@ -110,6 +199,11 @@ static int msm8660_boot_secondary(unsign
  117. return qcom_boot_secondary(cpu, scss_release_secondary);
  118. }
  119. +static int kpssv1_boot_secondary(unsigned int cpu, struct task_struct *idle)
  120. +{
  121. + return qcom_boot_secondary(cpu, kpssv1_release_secondary);
  122. +}
  123. +
  124. static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
  125. {
  126. int cpu, map;
  127. @@ -117,6 +211,8 @@ static void __init qcom_smp_prepare_cpus
  128. static const int cold_boot_flags[] = {
  129. 0,
  130. SCM_FLAG_COLDBOOT_CPU1,
  131. + SCM_FLAG_COLDBOOT_CPU2,
  132. + SCM_FLAG_COLDBOOT_CPU3,
  133. };
  134. for_each_present_cpu(cpu) {
  135. @@ -147,3 +243,13 @@ static struct smp_operations smp_msm8660
  136. #endif
  137. };
  138. CPU_METHOD_OF_DECLARE(qcom_smp, "qcom,gcc-msm8660", &smp_msm8660_ops);
  139. +
  140. +static struct smp_operations qcom_smp_kpssv1_ops __initdata = {
  141. + .smp_prepare_cpus = qcom_smp_prepare_cpus,
  142. + .smp_secondary_init = qcom_secondary_init,
  143. + .smp_boot_secondary = kpssv1_boot_secondary,
  144. +#ifdef CONFIG_HOTPLUG_CPU
  145. + .cpu_die = qcom_cpu_die,
  146. +#endif
  147. +};
  148. +CPU_METHOD_OF_DECLARE(qcom_smp_kpssv1, "qcom,kpss-acc-v1", &qcom_smp_kpssv1_ops);
  149. --- a/arch/arm/mach-qcom/scm-boot.h
  150. +++ b/arch/arm/mach-qcom/scm-boot.h
  151. @@ -13,9 +13,11 @@
  152. #define __MACH_SCM_BOOT_H
  153. #define SCM_BOOT_ADDR 0x1
  154. -#define SCM_FLAG_COLDBOOT_CPU1 0x1
  155. -#define SCM_FLAG_WARMBOOT_CPU1 0x2
  156. -#define SCM_FLAG_WARMBOOT_CPU0 0x4
  157. +#define SCM_FLAG_COLDBOOT_CPU1 0x01
  158. +#define SCM_FLAG_COLDBOOT_CPU2 0x08
  159. +#define SCM_FLAG_COLDBOOT_CPU3 0x20
  160. +#define SCM_FLAG_WARMBOOT_CPU0 0x04
  161. +#define SCM_FLAG_WARMBOOT_CPU1 0x02
  162. int scm_set_boot_addr(phys_addr_t addr, int flags);