From: Rohit Vaswani <rvasw...@codeaurora.org>

Implement support for the Krait CPU release sequence when the
CPUs are part of the first version of the krait processor
subsystem.

Signed-off-by: Rohit Vaswani <rvasw...@codeaurora.org>
Signed-off-by: Stephen Boyd <sb...@codeaurora.org>
---
 arch/arm/mach-msm/platsmp.c  | 106 +++++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-msm/scm-boot.h |   8 ++--
 2 files changed, 111 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index 11c6239..4b13cd8 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -30,6 +30,16 @@
 #define SCSS_CPU1CORE_RESET            0x2d80
 #define SCSS_DBG_STATUS_CORE_PWRDUP    0x2e64
 
+#define APCS_CPU_PWR_CTL       0x04
+#define PLL_CLAMP              BIT(8)
+#define CORE_PWRD_UP           BIT(7)
+#define COREPOR_RST            BIT(5)
+#define CORE_RST               BIT(4)
+#define L2DT_SLP               BIT(3)
+#define CLAMP                  BIT(0)
+
+#define APCS_SAW2_VCTL         0x14
+
 extern void secondary_startup(void);
 
 static DEFINE_SPINLOCK(boot_lock);
@@ -68,6 +78,85 @@ static int scss_release_secondary(unsigned int cpu)
        return 0;
 }
 
+static int kpssv1_release_secondary(unsigned int cpu)
+{
+       int ret = 0;
+       void __iomem *reg, *saw_reg;
+       struct device_node *cpu_node, *acc_node, *saw_node;
+       u32 val;
+
+       cpu_node = of_get_cpu_node(cpu, NULL);
+       if (!cpu_node)
+               return -ENODEV;
+
+       acc_node = of_parse_phandle(cpu_node, "qcom,acc", 0);
+       if (!acc_node) {
+               ret = -ENODEV;
+               goto out_acc;
+       }
+
+       saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0);
+       if (!saw_node) {
+               ret = -ENODEV;
+               goto out_saw;
+       }
+
+       reg = of_iomap(acc_node, 0);
+       if (!reg) {
+               ret = -ENOMEM;
+               goto out_acc_map;
+       }
+
+       saw_reg = of_iomap(saw_node, 0);
+       if (!saw_reg) {
+               ret = -ENOMEM;
+               goto out_saw_map;
+       }
+
+       /* Turn on CPU rail */
+       writel_relaxed(0xA4, saw_reg + APCS_SAW2_VCTL);
+       mb();
+       udelay(512);
+
+       /* Krait bring-up sequence */
+       val = PLL_CLAMP | L2DT_SLP | CLAMP;
+       writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+       val &= ~L2DT_SLP;
+       writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+       mb();
+       ndelay(300);
+
+       val |= COREPOR_RST;
+       writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+       mb();
+       udelay(2);
+
+       val &= ~CLAMP;
+       writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+       mb();
+       udelay(2);
+
+       val &= ~COREPOR_RST;
+       writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+       mb();
+       udelay(100);
+
+       val |= CORE_PWRD_UP;
+       writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
+       mb();
+
+       iounmap(saw_reg);
+out_saw_map:
+       iounmap(reg);
+out_acc_map:
+       of_node_put(saw_node);
+out_saw:
+       of_node_put(acc_node);
+out_acc:
+       of_node_put(cpu_node);
+       return ret;
+}
+
 static DEFINE_PER_CPU(int, cold_boot_done);
 
 static int msm_boot_secondary(unsigned int cpu, int (*func)(unsigned int))
@@ -107,6 +196,11 @@ static int msm8660_boot_secondary(unsigned int cpu, struct 
task_struct *idle)
        return msm_boot_secondary(cpu, scss_release_secondary);
 }
 
+static int kpssv1_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+       return msm_boot_secondary(cpu, kpssv1_release_secondary);
+}
+
 static void __init msm_smp_prepare_cpus(unsigned int max_cpus)
 {
        int cpu, map;
@@ -114,6 +208,8 @@ static void __init msm_smp_prepare_cpus(unsigned int 
max_cpus)
        static const int cold_boot_flags[] = {
                0,
                SCM_FLAG_COLDBOOT_CPU1,
+               SCM_FLAG_COLDBOOT_CPU2,
+               SCM_FLAG_COLDBOOT_CPU3,
        };
 
        for_each_present_cpu(cpu) {
@@ -144,3 +240,13 @@ static struct smp_operations msm_smp_8660_ops __initdata = 
{
 #endif
 };
 CPU_METHOD_OF_DECLARE(msm_smp, "qcom,gcc-msm8660", &msm_smp_8660_ops);
+
+static struct smp_operations msm_smp_kpssv1_ops __initdata = {
+       .smp_prepare_cpus       = msm_smp_prepare_cpus,
+       .smp_secondary_init     = msm_secondary_init,
+       .smp_boot_secondary     = kpssv1_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+       .cpu_die                = msm_cpu_die,
+#endif
+};
+CPU_METHOD_OF_DECLARE(msm_smp_kpssv1, "qcom,kpss-acc-v1", &msm_smp_kpssv1_ops);
diff --git a/arch/arm/mach-msm/scm-boot.h b/arch/arm/mach-msm/scm-boot.h
index 7be32ff..6aabb24 100644
--- a/arch/arm/mach-msm/scm-boot.h
+++ b/arch/arm/mach-msm/scm-boot.h
@@ -13,9 +13,11 @@
 #define __MACH_SCM_BOOT_H
 
 #define SCM_BOOT_ADDR                  0x1
-#define SCM_FLAG_COLDBOOT_CPU1         0x1
-#define SCM_FLAG_WARMBOOT_CPU1         0x2
-#define SCM_FLAG_WARMBOOT_CPU0         0x4
+#define SCM_FLAG_COLDBOOT_CPU1         0x01
+#define SCM_FLAG_COLDBOOT_CPU2         0x08
+#define SCM_FLAG_COLDBOOT_CPU3         0x20
+#define SCM_FLAG_WARMBOOT_CPU0         0x04
+#define SCM_FLAG_WARMBOOT_CPU1         0x02
 
 int scm_set_boot_addr(phys_addr_t addr, int flags);
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to