Add required patch to use original Krait specific WFI idle state.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
};
};
-&CPU_SPC {
- status = "disabled";
-};
-
&gsbi5 {
status = "okay";
};
};
-&CPU_SPC {
- status = "disabled";
-};
-
&adm_dma {
status = "okay";
};
reg = <0x40000000 0x20000000>;
};
- cpus {
- idle-states {
- CPU_SPC: spc {
- status = "disabled";
- };
- };
- };
-
chosen {
bootargs-append = " console=ttyMSM0,115200n8 ubi.mtd=ubi ubi.mtd=art";
};
};
};
- cpus {
- idle-states {
- CPU_SPC: spc {
- status = "disabled";
- };
- };
- };
-
aliases {
serial1 = &gsbi1_serial;
ethernet0 = &gmac2;
saw0: regulator@2089000 {
- compatible = "qcom,saw2";
-+ compatible = "qcom,saw2", "qcom,apq8064-saw2-v1.1-cpu", "syscon";
++ compatible = "qcom,saw2", "qcom,ipq8064-saw2-v1.1-boot-cpu", "syscon";
reg = <0x02089000 0x1000>, <0x02009000 0x1000>;
regulator;
};
saw1: regulator@2099000 {
- compatible = "qcom,saw2";
-+ compatible = "qcom,saw2", "qcom,apq8064-saw2-v1.1-cpu", "syscon";
++ compatible = "qcom,saw2", "qcom,ipq8064-saw2-v1.1-nonboot-cpu", "syscon";
reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
regulator;
};
+ cooling-min-state = <0>;
+ cooling-max-state = <10>;
+ #cooling-cells = <2>;
-+ cpu-idle-states = <&CPU_SPC>;
++ cpu-idle-states = <&CPU_WFI>;
};
cpu1: cpu@1 {
-@@ -40,11 +49,35 @@
+@@ -40,11 +49,34 @@
next-level-cache = <&L2>;
qcom,acc = <&acc1>;
qcom,saw = <&saw1>;
+ cooling-min-state = <0>;
+ cooling-max-state = <10>;
+ #cooling-cells = <2>;
-+ cpu-idle-states = <&CPU_SPC>;
++ cpu-idle-states = <&CPU_WFI>;
+ };
+
+ idle-states {
-+ CPU_SPC: spc {
-+ compatible = "qcom,idle-state-spc";
-+ status = "disabled";
-+ entry-latency-us = <400>;
-+ exit-latency-us = <900>;
-+ min-residency-us = <3000>;
++ CPU_WFI: wfi {
++ compatible = "qcom,idle-state-wfi";
++ entry-latency-us = <1>;
++ exit-latency-us = <1>;
++ min-residency-us = <1>;
+ };
};
--- /dev/null
+From 923ab10f11a493f458d8ac069d76da6d56e7b194 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Mon, 19 Sep 2022 14:36:21 +0200
+Subject: [PATCH 1/3] soc: qcom: spm: Add ipq8064 CPU data
+
+Add ipq8064 CPU data for boot and non-boot CPU. Load only the WFI
+sequence as some SoC seems to be broken with SPC sequence and seems to
+be not supported on this platform.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/soc/qcom/spm.c | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/drivers/soc/qcom/spm.c b/drivers/soc/qcom/spm.c
+index 484b42b7454e..d822ea6dee38 100644
+--- a/drivers/soc/qcom/spm.c
++++ b/drivers/soc/qcom/spm.c
+@@ -151,6 +151,30 @@ static const struct spm_reg_data spm_reg_8064_cpu = {
+ .start_index[PM_SLEEP_MODE_SPC] = 2,
+ };
+
++/* SPM register data for ipq8064 boot cpu */
++static const struct spm_reg_data spm_reg_ipq8064_boot_cpu = {
++ .reg_offset = spm_reg_offset_v1_1,
++ .spm_cfg = 0x1F,
++ .pmic_dly = 0x03020004,
++ .pmic_data[0] = 0x0084009C,
++ .pmic_data[1] = 0x00A4001C,
++ .seq = { 0x03, 0x0F,
++ },
++ .start_index[PM_SLEEP_MODE_STBY] = 0,
++};
++
++/* SPM register data for ipq8064 non boot cpu */
++static const struct spm_reg_data spm_reg_ipq8064_nonboot_cpu = {
++ .reg_offset = spm_reg_offset_v1_1,
++ .spm_cfg = 0x1F,
++ .pmic_dly = 0x02020004,
++ .pmic_data[0] = 0x0060009C,
++ .pmic_data[1] = 0x0000001C,
++ .seq = { 0x03, 0x0F,
++ },
++ .start_index[PM_SLEEP_MODE_STBY] = 0,
++};
++
+ static inline void spm_register_write(struct spm_driver_data *drv,
+ enum spm_reg reg, u32 val)
+ {
+@@ -221,6 +245,10 @@ static const struct of_device_id spm_match_table[] = {
+ .data = &spm_reg_8974_8084_cpu },
+ { .compatible = "qcom,apq8064-saw2-v1.1-cpu",
+ .data = &spm_reg_8064_cpu },
++ { .compatible = "qcom,ipq8064-saw2-v1.1-boot-cpu",
++ .data = &spm_reg_ipq8064_boot_cpu },
++ { .compatible = "qcom,ipq8064-saw2-v1.1-nonboot-cpu",
++ .data = &spm_reg_ipq8064_nonboot_cpu },
+ { },
+ };
+ MODULE_DEVICE_TABLE(of, spm_match_table);
+--
+2.37.2
+
--- /dev/null
+From 50523bace0af72bf488c26359bc0d7e054c3f1be Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Mon, 19 Sep 2022 14:49:02 +0200
+Subject: [PATCH 2/3] ARM: mach-qcom: Add krait CPU specific idle
+
+Add krait CPU specific idle that does extra save while in WFI.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ arch/arm/include/asm/mach/krait-idle.h | 11 +++++++++
+ arch/arm/mach-qcom/Kconfig | 3 +++
+ arch/arm/mach-qcom/Makefile | 1 +
+ arch/arm/mach-qcom/krait-idle.S | 34 ++++++++++++++++++++++++++
+ 4 files changed, 49 insertions(+)
+ create mode 100644 arch/arm/include/asm/mach/krait-idle.h
+ create mode 100644 arch/arm/mach-qcom/krait-idle.S
+
+diff --git a/arch/arm/include/asm/mach/krait-idle.h b/arch/arm/include/asm/mach/krait-idle.h
+new file mode 100644
+index 000000000000..c8da6b3fb792
+--- /dev/null
++++ b/arch/arm/include/asm/mach/krait-idle.h
+@@ -0,0 +1,11 @@
++#ifndef __ASSEMBLY__
++
++#ifdef ARCH_KRAIT_IDLE
++extern void arm_krait_idle(void);
++#else
++static void arm_krait_idle(void) {
++ cpu_do_idle();
++}
++#endif
++
++#endif /* __ASSEMBLY__ */
+\ No newline at end of file
+diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
+index 12a812e61c16..ae26bca49b39 100644
+--- a/arch/arm/mach-qcom/Kconfig
++++ b/arch/arm/mach-qcom/Kconfig
+@@ -46,4 +46,7 @@ config ARCH_MDM9615
+ bool "Enable support for MDM9615"
+ select CLKSRC_QCOM
+
++config ARCH_KRAIT_IDLE
++ bool "Enable Krait Idle specific WFI"
++
+ endif
+diff --git a/arch/arm/mach-qcom/Makefile b/arch/arm/mach-qcom/Makefile
+index b839201c9802..fc828b60def0 100644
+--- a/arch/arm/mach-qcom/Makefile
++++ b/arch/arm/mach-qcom/Makefile
+@@ -1,2 +1,3 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+ obj-$(CONFIG_SMP) += platsmp.o
++obj-$(CONFIG_ARCH_KRAIT_IDLE) += krait-idle.o
+diff --git a/arch/arm/mach-qcom/krait-idle.S b/arch/arm/mach-qcom/krait-idle.S
+new file mode 100644
+index 000000000000..005b5d511e69
+--- /dev/null
++++ b/arch/arm/mach-qcom/krait-idle.S
+@@ -0,0 +1,34 @@
++#include <linux/linkage.h>
++#include <asm/assembler.h>
++#include <asm/mach/krait-idle.h>
++
++ENTRY(arm_krait_idle)
++ mrc p15, 0, r0, c0, c0, 0
++ bic r1, r0, #0xff
++ movw r2, #0x0400
++ movt r2, #0x511F
++ movw r3, #0x0600
++ movt r3, #0x510F
++ cmp r2, r1
++ cmpne r3, r1
++ bne go_wfi
++
++ mrs r0, cpsr
++ cpsid if
++
++ mrc p15, 7, r1, c15, c0, 5
++ bic r2, r1, #0x20000
++ mcr p15, 7, r2, c15, c0, 5
++ isb
++
++go_wfi:
++ wfi
++ bne wfi_done
++ mcr p15, 7, r1, c15, c0, 5
++ isb
++ msr cpsr_c, r0
++
++wfi_done:
++ bx lr
++ENDPROC(arm_krait_idle)
++
+--
+2.37.2
+
--- /dev/null
+From cf3614dd0e87f8ef6936c3100be1b0a37e007a6c Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Mon, 19 Sep 2022 14:56:35 +0200
+Subject: [PATCH 3/3] cpuidle: qcom-spm: add krait specific wfi
+
+Add krait specific wfi cpuidle that use the specific krait idle code.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ drivers/cpuidle/cpuidle-qcom-spm.c | 35 +++++++++++++++++++++++++-----
+ 1 file changed, 30 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/cpuidle/cpuidle-qcom-spm.c b/drivers/cpuidle/cpuidle-qcom-spm.c
+index beedf22cbe78..0c3f67265d5e 100644
+--- a/drivers/cpuidle/cpuidle-qcom-spm.c
++++ b/drivers/cpuidle/cpuidle-qcom-spm.c
+@@ -25,6 +25,8 @@
+
+ #include "dt_idle_states.h"
+
++#include <asm/mach/krait-idle.h>
++
+ struct cpuidle_qcom_spm_data {
+ struct cpuidle_driver cpuidle_driver;
+ struct spm_driver_data *spm;
+@@ -58,7 +60,7 @@ static int qcom_cpu_spc(struct spm_driver_data *drv)
+ return ret;
+ }
+
+-static int spm_enter_idle_state(struct cpuidle_device *dev,
++static int spm_enter_idle_state_spc(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int idx)
+ {
+ struct cpuidle_qcom_spm_data *data = container_of(drv, struct cpuidle_qcom_spm_data,
+@@ -67,11 +69,18 @@ static int spm_enter_idle_state(struct cpuidle_device *dev,
+ return CPU_PM_CPU_IDLE_ENTER_PARAM(qcom_cpu_spc, idx, data->spm);
+ }
+
+-static struct cpuidle_driver qcom_spm_idle_driver = {
++static int spm_enter_idle_state_wfi(struct cpuidle_device *dev,
++ struct cpuidle_driver *drv, int idx)
++{
++ arm_krait_idle();
++ return idx;
++}
++
++static struct cpuidle_driver qcom_spm_idle_driver_spc = {
+ .name = "qcom_spm",
+ .owner = THIS_MODULE,
+ .states[0] = {
+- .enter = spm_enter_idle_state,
++ .enter = spm_enter_idle_state_spc,
+ .exit_latency = 1,
+ .target_residency = 1,
+ .power_usage = UINT_MAX,
+@@ -80,13 +89,28 @@ static struct cpuidle_driver qcom_spm_idle_driver = {
+ }
+ };
+
++static struct cpuidle_driver qcom_spm_idle_driver_wfi = {
++ .name = "qcom_spm",
++ .owner = THIS_MODULE,
++ .states[0] = {
++ .enter = spm_enter_idle_state_wfi,
++ .exit_latency = 1,
++ .target_residency = 1,
++ .power_usage = UINT_MAX,
++ .name = "WFI",
++ .desc = "Krait WFI",
++ }
++};
++
+ static const struct of_device_id qcom_idle_state_match[] = {
+- { .compatible = "qcom,idle-state-spc", .data = spm_enter_idle_state },
++ { .compatible = "qcom,idle-state-spc", .data = &qcom_spm_idle_driver_spc },
++ { .compatible = "qcom,idle-state-wfi", .data = &qcom_spm_idle_driver_wfi },
+ { },
+ };
+
+ static int spm_cpuidle_register(struct device *cpuidle_dev, int cpu)
+ {
++ struct cpuidle_driver *driver;
+ struct platform_device *pdev = NULL;
+ struct device_node *cpu_node, *saw_node;
+ struct cpuidle_qcom_spm_data *data = NULL;
+@@ -114,7 +138,8 @@ static int spm_cpuidle_register(struct device *cpuidle_dev, int cpu)
+ if (!data->spm)
+ return -EINVAL;
+
+- data->cpuidle_driver = qcom_spm_idle_driver;
++ driver = device_get_match_data(cpuidle_dev);
++ data->cpuidle_driver = *driver;
+ data->cpuidle_driver.cpumask = (struct cpumask *)cpumask_of(cpu);
+
+ ret = dt_init_idle_driver(&data->cpuidle_driver,
+--
+2.37.2
+