openwrt/target/linux/ipq806x/patches/0013-ARM-qcom-Add-SMP-support-for-KPSSv1.patch
John Crispin 3c1f6e358d ipq806x: Add support for IPQ806x chip family
Patches are generated using the "format-patch" command from the
following location:
*https://www.codeaurora.org/cgit/quic/kernel/galak-msm/log/?h=apq_ipq_base
*rev=0771849495b4128cac2faf7d49c85c729fc48b20
Patches numbered 76/77/102/103 have already been integrated in 3.14.12,
so they're not in this list.

All these patches are either integrated are pending integration into
kernel.org, therefore these patches should go away once the kernel
gets upgraded to 3.16.

Support is currently limited to AP148 board but can be extended to other
platforms in the future.

These changes do not cover ethernet connectivity.

Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>

SVN-Revision: 42334
2014-08-30 09:32:58 +00:00

182 lines
4.7 KiB
Diff

From 8e843640b3c4a43b963332fdc7b233948ad25a5b Mon Sep 17 00:00:00 2001
From: Rohit Vaswani <rvaswani@codeaurora.org>
Date: Tue, 21 May 2013 19:13:50 -0700
Subject: [PATCH 013/182] ARM: qcom: Add SMP support for KPSSv1
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 <rvaswani@codeaurora.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Kumar Gala <galak@codeaurora.org>
---
arch/arm/mach-qcom/platsmp.c | 106 +++++++++++++++++++++++++++++++++++++++++
arch/arm/mach-qcom/scm-boot.h | 8 ++--
2 files changed, 111 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c
index ec8604d..cb0783f 100644
--- a/arch/arm/mach-qcom/platsmp.c
+++ b/arch/arm/mach-qcom/platsmp.c
@@ -26,6 +26,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);
@@ -71,6 +81,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 qcom_boot_secondary(unsigned int cpu, int (*func)(unsigned int))
@@ -110,6 +199,11 @@ static int msm8660_boot_secondary(unsigned int cpu, struct task_struct *idle)
return qcom_boot_secondary(cpu, scss_release_secondary);
}
+static int kpssv1_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ return qcom_boot_secondary(cpu, kpssv1_release_secondary);
+}
+
static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
{
int cpu, map;
@@ -117,6 +211,8 @@ static void __init qcom_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) {
@@ -147,3 +243,13 @@ static struct smp_operations smp_msm8660_ops __initdata = {
#endif
};
CPU_METHOD_OF_DECLARE(qcom_smp, "qcom,gcc-msm8660", &smp_msm8660_ops);
+
+static struct smp_operations qcom_smp_kpssv1_ops __initdata = {
+ .smp_prepare_cpus = qcom_smp_prepare_cpus,
+ .smp_secondary_init = qcom_secondary_init,
+ .smp_boot_secondary = kpssv1_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = qcom_cpu_die,
+#endif
+};
+CPU_METHOD_OF_DECLARE(qcom_smp_kpssv1, "qcom,kpss-acc-v1", &qcom_smp_kpssv1_ops);
diff --git a/arch/arm/mach-qcom/scm-boot.h b/arch/arm/mach-qcom/scm-boot.h
index 7be32ff..6aabb24 100644
--- a/arch/arm/mach-qcom/scm-boot.h
+++ b/arch/arm/mach-qcom/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);
--
1.7.10.4