* [PATCH 0/3] omap5 cpu off mode support @ 2017-08-17 23:01 ` Tony Lindgren 0 siblings, 0 replies; 18+ messages in thread From: Tony Lindgren @ 2017-08-17 23:01 UTC (permalink / raw) To: linux-omap Cc: Nishanth Menon, Tero Kristo, Santosh Shilimkar, linux-arm-kernel, Dave Gerlach Hi all, Here are few patches to enable omap5 cpu off mode similar to what we do for omap4. This seems to save about 0.2W power on omap5-uevm while idle compared to retention idle. Note that this won't work for dra7 as it does not support deeper idle modes. Regards, Tony clone of "next-bak-2017-07-17-20170717-001945" Santosh Shilimkar (1): ARM: OMAP5: Add cpuidle assembly code Tony Lindgren (2): ARM: OMAP2+: Separate dra7 cpuidle from omap5 ARM: OMAP5: Enable CPU off idle states arch/arm/mach-omap2/common.h | 11 +++ arch/arm/mach-omap2/cpuidle44xx.c | 56 ++++++++++++ arch/arm/mach-omap2/omap-mpuss-lowpower.c | 8 +- arch/arm/mach-omap2/omap-secure.h | 6 ++ arch/arm/mach-omap2/omap-wakeupgen.c | 5 +- arch/arm/mach-omap2/pm44xx.c | 2 +- arch/arm/mach-omap2/powerdomains54xx_data.c | 10 +- arch/arm/mach-omap2/sleep44xx.S | 137 ++++++++++++++++++++++++++++ 8 files changed, 226 insertions(+), 9 deletions(-) -- 2.14.1 ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 0/3] omap5 cpu off mode support @ 2017-08-17 23:01 ` Tony Lindgren 0 siblings, 0 replies; 18+ messages in thread From: Tony Lindgren @ 2017-08-17 23:01 UTC (permalink / raw) To: linux-arm-kernel Hi all, Here are few patches to enable omap5 cpu off mode similar to what we do for omap4. This seems to save about 0.2W power on omap5-uevm while idle compared to retention idle. Note that this won't work for dra7 as it does not support deeper idle modes. Regards, Tony clone of "next-bak-2017-07-17-20170717-001945" Santosh Shilimkar (1): ARM: OMAP5: Add cpuidle assembly code Tony Lindgren (2): ARM: OMAP2+: Separate dra7 cpuidle from omap5 ARM: OMAP5: Enable CPU off idle states arch/arm/mach-omap2/common.h | 11 +++ arch/arm/mach-omap2/cpuidle44xx.c | 56 ++++++++++++ arch/arm/mach-omap2/omap-mpuss-lowpower.c | 8 +- arch/arm/mach-omap2/omap-secure.h | 6 ++ arch/arm/mach-omap2/omap-wakeupgen.c | 5 +- arch/arm/mach-omap2/pm44xx.c | 2 +- arch/arm/mach-omap2/powerdomains54xx_data.c | 10 +- arch/arm/mach-omap2/sleep44xx.S | 137 ++++++++++++++++++++++++++++ 8 files changed, 226 insertions(+), 9 deletions(-) -- 2.14.1 ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 1/3] ARM: OMAP2+: Separate dra7 cpuidle from omap5 2017-08-17 23:01 ` Tony Lindgren @ 2017-08-17 23:01 ` Tony Lindgren -1 siblings, 0 replies; 18+ messages in thread From: Tony Lindgren @ 2017-08-17 23:01 UTC (permalink / raw) To: linux-omap Cc: Nishanth Menon, Tero Kristo, Santosh Shilimkar, linux-arm-kernel, Dave Gerlach As omap5 supports deeper idle states compared to dra7, let's separate dra7 from omap5 in preparation for adding more support for omap5. Cc: Dave Gerlach <d-gerlach@ti.com> Cc: Nishanth Menon <nm@ti.com> Cc: Santosh Shilimkar <santosh.shilimkar@oracle.com> Cc: Tero Kristo <t-kristo@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/mach-omap2/cpuidle44xx.c | 42 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -65,6 +65,19 @@ static struct idle_statedata omap5_idle_data[] = { }, }; +static struct idle_statedata dra7_idle_data[] = { + { + .cpu_state = PWRDM_POWER_ON, + .mpu_state = PWRDM_POWER_ON, + .mpu_logic_state = PWRDM_POWER_ON, + }, + { + .cpu_state = PWRDM_POWER_RET, + .mpu_state = PWRDM_POWER_RET, + .mpu_logic_state = PWRDM_POWER_RET, + }, +}; + static struct powerdomain *mpu_pd, *cpu_pd[MAX_CPUS]; static struct clockdomain *cpu_clkdm[MAX_CPUS]; @@ -288,6 +301,32 @@ static struct cpuidle_driver omap5_idle_driver = { .safe_state_index = 0, }; +static struct cpuidle_driver dra7_idle_driver = { + .name = "dra7_idle", + .owner = THIS_MODULE, + .states = { + { + /* C1 - CPU0 ON + CPU1 ON + MPU ON */ + .exit_latency = 2 + 2, + .target_residency = 5, + .enter = omap_enter_idle_simple, + .name = "C1", + .desc = "CPUx WFI, MPUSS ON" + }, + { + /* C2 - CPU0 RET + CPU1 RET + MPU CSWR */ + .exit_latency = 48 + 60, + .target_residency = 100, + .flags = CPUIDLE_FLAG_TIMER_STOP, + .enter = omap_enter_idle_smp, + .name = "C2", + .desc = "CPUx CSWR, MPUSS CSWR", + }, + }, + .state_count = ARRAY_SIZE(dra7_idle_data), + .safe_state_index = 0, +}; + /* Public functions */ /** @@ -303,6 +342,9 @@ int __init omap4_idle_init(void) if (soc_is_omap54xx()) { state_ptr = &omap5_idle_data[0]; idle_driver = &omap5_idle_driver; + } else if (soc_is_dra7xx()) { + state_ptr = &dra7_idle_data[0]; + idle_driver = &dra7_idle_driver; } else { state_ptr = &omap4_idle_data[0]; idle_driver = &omap4_idle_driver; -- 2.14.1 ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 1/3] ARM: OMAP2+: Separate dra7 cpuidle from omap5 @ 2017-08-17 23:01 ` Tony Lindgren 0 siblings, 0 replies; 18+ messages in thread From: Tony Lindgren @ 2017-08-17 23:01 UTC (permalink / raw) To: linux-arm-kernel As omap5 supports deeper idle states compared to dra7, let's separate dra7 from omap5 in preparation for adding more support for omap5. Cc: Dave Gerlach <d-gerlach@ti.com> Cc: Nishanth Menon <nm@ti.com> Cc: Santosh Shilimkar <santosh.shilimkar@oracle.com> Cc: Tero Kristo <t-kristo@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/mach-omap2/cpuidle44xx.c | 42 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -65,6 +65,19 @@ static struct idle_statedata omap5_idle_data[] = { }, }; +static struct idle_statedata dra7_idle_data[] = { + { + .cpu_state = PWRDM_POWER_ON, + .mpu_state = PWRDM_POWER_ON, + .mpu_logic_state = PWRDM_POWER_ON, + }, + { + .cpu_state = PWRDM_POWER_RET, + .mpu_state = PWRDM_POWER_RET, + .mpu_logic_state = PWRDM_POWER_RET, + }, +}; + static struct powerdomain *mpu_pd, *cpu_pd[MAX_CPUS]; static struct clockdomain *cpu_clkdm[MAX_CPUS]; @@ -288,6 +301,32 @@ static struct cpuidle_driver omap5_idle_driver = { .safe_state_index = 0, }; +static struct cpuidle_driver dra7_idle_driver = { + .name = "dra7_idle", + .owner = THIS_MODULE, + .states = { + { + /* C1 - CPU0 ON + CPU1 ON + MPU ON */ + .exit_latency = 2 + 2, + .target_residency = 5, + .enter = omap_enter_idle_simple, + .name = "C1", + .desc = "CPUx WFI, MPUSS ON" + }, + { + /* C2 - CPU0 RET + CPU1 RET + MPU CSWR */ + .exit_latency = 48 + 60, + .target_residency = 100, + .flags = CPUIDLE_FLAG_TIMER_STOP, + .enter = omap_enter_idle_smp, + .name = "C2", + .desc = "CPUx CSWR, MPUSS CSWR", + }, + }, + .state_count = ARRAY_SIZE(dra7_idle_data), + .safe_state_index = 0, +}; + /* Public functions */ /** @@ -303,6 +342,9 @@ int __init omap4_idle_init(void) if (soc_is_omap54xx()) { state_ptr = &omap5_idle_data[0]; idle_driver = &omap5_idle_driver; + } else if (soc_is_dra7xx()) { + state_ptr = &dra7_idle_data[0]; + idle_driver = &dra7_idle_driver; } else { state_ptr = &omap4_idle_data[0]; idle_driver = &omap4_idle_driver; -- 2.14.1 ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 1/3] ARM: OMAP2+: Separate dra7 cpuidle from omap5 2017-08-17 23:01 ` Tony Lindgren @ 2017-08-17 23:42 ` Tony Lindgren -1 siblings, 0 replies; 18+ messages in thread From: Tony Lindgren @ 2017-08-17 23:42 UTC (permalink / raw) To: linux-omap Cc: Nishanth Menon, Tero Kristo, Santosh Shilimkar, linux-arm-kernel, Dave Gerlach * Tony Lindgren <tony@atomide.com> [170817 16:01]: > As omap5 supports deeper idle states compared to dra7, let's > separate dra7 from omap5 in preparation for adding more support > for omap5. Oops, sorry this first patch can be ignored. I forgot we already separated out things for dra7 when we added omap5 cpu retention mode support earlir. So there's nothing left to move away for dra7. > @@ -303,6 +342,9 @@ int __init omap4_idle_init(void) > if (soc_is_omap54xx()) { > state_ptr = &omap5_idle_data[0]; > idle_driver = &omap5_idle_driver; > + } else if (soc_is_dra7xx()) { > + state_ptr = &dra7_idle_data[0]; > + idle_driver = &dra7_idle_driver; > } else { > state_ptr = &omap4_idle_data[0]; > idle_driver = &omap4_idle_driver; And then this part now wrongly enables things for dra7 while it can't be done. Regards, Tony ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 1/3] ARM: OMAP2+: Separate dra7 cpuidle from omap5 @ 2017-08-17 23:42 ` Tony Lindgren 0 siblings, 0 replies; 18+ messages in thread From: Tony Lindgren @ 2017-08-17 23:42 UTC (permalink / raw) To: linux-arm-kernel * Tony Lindgren <tony@atomide.com> [170817 16:01]: > As omap5 supports deeper idle states compared to dra7, let's > separate dra7 from omap5 in preparation for adding more support > for omap5. Oops, sorry this first patch can be ignored. I forgot we already separated out things for dra7 when we added omap5 cpu retention mode support earlir. So there's nothing left to move away for dra7. > @@ -303,6 +342,9 @@ int __init omap4_idle_init(void) > if (soc_is_omap54xx()) { > state_ptr = &omap5_idle_data[0]; > idle_driver = &omap5_idle_driver; > + } else if (soc_is_dra7xx()) { > + state_ptr = &dra7_idle_data[0]; > + idle_driver = &dra7_idle_driver; > } else { > state_ptr = &omap4_idle_data[0]; > idle_driver = &omap4_idle_driver; And then this part now wrongly enables things for dra7 while it can't be done. Regards, Tony ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 2/3] ARM: OMAP5: Add cpuidle assembly code 2017-08-17 23:01 ` Tony Lindgren @ 2017-08-17 23:01 ` Tony Lindgren -1 siblings, 0 replies; 18+ messages in thread From: Tony Lindgren @ 2017-08-17 23:01 UTC (permalink / raw) To: linux-omap Cc: Nishanth Menon, Dave Gerlach, Santosh Shilimkar, Tero Kristo, Santosh Shilimkar, linux-arm-kernel From: Santosh Shilimkar <santosh.shilimkar@ti.com> In order to support CPU off modes during idle like omap4 already does, we need to add the assembly code needed for restoring the CPU state from off mode. The code is a combination of the following earlier patches done by Santosh Shilimkar <santosh.shilimkar@oracle.com> in TI Linux kernel tree: 881603c3f97f ("ARM: OMAP5: PM: Add CPU power off mode support") 411533444365 ("ARM: OMAP5: PM: Add MPU Open Switch Retention support") 3f9ea63594c3 ("ARM: OMAP5: PM: Add L2 memory power down support") Cc: Dave Gerlach <d-gerlach@ti.com> Cc: Nishanth Menon <nm@ti.com> Cc: Tero Kristo <t-kristo@ti.com> Cc: Santosh Shilimkar <santosh.shilimkar@oracle.com> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> [tony@atomide.com: updated against mainline kernel] Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/mach-omap2/common.h | 11 +++ arch/arm/mach-omap2/omap-mpuss-lowpower.c | 8 +- arch/arm/mach-omap2/omap-secure.h | 6 ++ arch/arm/mach-omap2/omap-wakeupgen.c | 5 +- arch/arm/mach-omap2/sleep44xx.S | 137 ++++++++++++++++++++++++++++++ 5 files changed, 164 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -318,6 +318,8 @@ static inline void omap4_cpu_resume(void) #if defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX) void omap5_secondary_startup(void); void omap5_secondary_hyp_startup(void); +int omap5_finish_suspend(unsigned long cpu_state); +void omap5_cpu_resume(void); #else static inline void omap5_secondary_startup(void) { @@ -326,6 +328,15 @@ static inline void omap5_secondary_startup(void) static inline void omap5_secondary_hyp_startup(void) { } + +static inline int omap5_finish_suspend(unsigned long cpu_state) +{ + return 0; +} + +static inline void omap5_cpu_resume(void) +{ +} #endif void pdata_quirks_init(const struct of_device_id *); diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -439,7 +439,13 @@ int __init omap4_mpuss_init(void) omap_pm_ops.scu_prepare = scu_pwrst_prepare; omap_pm_ops.hotplug_restart = omap4_secondary_startup; cpu_context_offset = OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET; - } else if (soc_is_omap54xx() || soc_is_dra7xx()) { + } else if (soc_is_omap54xx()) { + omap_pm_ops.finish_suspend = omap5_finish_suspend; + omap_pm_ops.resume = omap5_cpu_resume; + omap_pm_ops.hotplug_restart = omap5_secondary_startup; + cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET; + enable_mercury_retention_mode(); + } else if (soc_is_dra7xx()) { cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET; enable_mercury_retention_mode(); } diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h --- a/arch/arm/mach-omap2/omap-secure.h +++ b/arch/arm/mach-omap2/omap-secure.h @@ -36,6 +36,10 @@ #define OMAP4_HAL_SAVEHW_INDEX 0x1b #define OMAP4_HAL_SAVEALL_INDEX 0x1c #define OMAP4_HAL_SAVEGIC_INDEX 0x1d +#define OMAP5_HAL_SAVESECURERAM_INDEX 0x1c +#define OMAP5_HAL_SAVEHW_INDEX 0x1d +#define OMAP5_HAL_SAVEALL_INDEX 0x1e +#define OMAP5_HAL_SAVEGIC_INDEX 0x1f /* Secure Monitor mode APIs */ #define OMAP4_MON_SCU_PWR_INDEX 0x108 @@ -44,6 +48,8 @@ #define OMAP4_MON_L2X0_AUXCTRL_INDEX 0x109 #define OMAP4_MON_L2X0_PREFETCH_INDEX 0x113 +#define OMAP5_MON_CACHES_CLEAN_INDEX 0x103 +#define OMAP5_MON_L2AUX_CTRL_INDEX 0x104 #define OMAP5_DRA7_MON_SET_CNTFRQ_INDEX 0x109 #define OMAP5_MON_AMBA_IF_INDEX 0x108 #define OMAP5_DRA7_MON_SET_ACR_INDEX 0x107 diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -56,7 +56,7 @@ static DEFINE_RAW_SPINLOCK(wakeupgen_lock); static unsigned int irq_target_cpu[MAX_IRQS]; static unsigned int irq_banks = DEFAULT_NR_REG_BANKS; static unsigned int max_irqs = DEFAULT_IRQS; -static unsigned int omap_secure_apis; +static unsigned int omap_secure_apis, secure_api_index; #ifdef CONFIG_CPU_PM static unsigned int wakeupgen_context[MAX_NR_REG_BANKS]; @@ -345,7 +345,7 @@ static void irq_restore_context(void) static void irq_save_secure_context(void) { u32 ret; - ret = omap_secure_dispatcher(OMAP4_HAL_SAVEGIC_INDEX, + ret = omap_secure_dispatcher(secure_api_index, FLAG_START_CRITICAL, 0, 0, 0, 0, 0); if (ret != API_HAL_RET_VALUE_OK) @@ -549,6 +549,7 @@ static int __init wakeupgen_init(struct device_node *node, wakeupgen_ops = &omap4_wakeupgen_ops; } else if (soc_is_omap54xx()) { wakeupgen_ops = &omap5_wakeupgen_ops; + secure_api_index = OMAP5_HAL_SAVEGIC_INDEX; } else if (soc_is_am43xx()) { irq_banks = AM43XX_NR_REG_BANKS; max_irqs = AM43XX_IRQS; diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S --- a/arch/arm/mach-omap2/sleep44xx.S +++ b/arch/arm/mach-omap2/sleep44xx.S @@ -20,6 +20,7 @@ #include "common.h" #include "omap44xx.h" #include "omap4-sar-layout.h" +#include "omap-secure.h" #if defined(CONFIG_SMP) && defined(CONFIG_PM) @@ -331,6 +332,142 @@ ppa_por_params_offset: ENDPROC(omap4_cpu_resume) #endif /* CONFIG_ARCH_OMAP4 */ +#if defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX) + +/* + * ================================ + * == OMAP5 CPU suspend finisher == + * ================================ + * + * OMAP5 MPUSS states for the context save: + * save_state = + * 0 - Nothing lost and no need to save: MPUSS INA/CSWR + * 1 - CPUx L1 and logic lost: CPU OFF, MPUSS INA/CSWR + * 2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR + * 3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF + */ +ENTRY(omap5_finish_suspend) + stmfd sp!, {r4-r12, lr} + cmp r0, #0x0 + beq do_wfi @ No lowpower state, jump to WFI + + /* + * Flush all data from the L1 data cache before disabling + * SCTLR.C bit. + */ + bl omap4_get_sar_ram_base + ldr r9, [r0, #OMAP_TYPE_OFFSET] + cmp r9, #0x1 @ Check for HS device + bne skip_secure_l1_clean_op + mov r0, #0 @ Clean secure L1 + stmfd r13!, {r4-r12, r14} + ldr r12, =OMAP5_MON_CACHES_CLEAN_INDEX + DO_SMC + ldmfd r13!, {r4-r12, r14} +skip_secure_l1_clean_op: + bl v7_flush_dcache_louis + + /* + * Clear the SCTLR.C bit to prevent further data cache + * allocation. Clearing SCTLR.C would make all the data accesses + * strongly ordered and would not hit the cache. + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #(1 << 2) @ Disable the C bit + mcr p15, 0, r0, c1, c0, 0 + isb + + /* Clean and Invalidate L1 data cache. */ + bl v7_flush_dcache_louis + + /* + * Take CPU out of Symmetric Multiprocessing (SMP) mode and thus + * preventing the CPU from receiving cache, TLB, or BTB + * maintenance operations broadcast by other CPUs in the cluster. + */ + mrc p15, 0, r0, c1, c1, 2 @ Read NSACR data + tst r0, #(1 << 18) + mrcne p15, 0, r0, c1, c0, 1 + bicne r0, r0, #(1 << 6) @ Disable SMP bit + mcrne p15, 0, r0, c1, c0, 1 + isb + dsb + + bl omap4_get_sar_ram_base + mov r8, r0 + mrc p15, 0, r5, c0, c0, 5 @ Read MPIDR + ands r5, r5, #0x0f + ldreq r0, [r8, #L2X0_SAVE_OFFSET0] @ Retrieve L2 state + ldrne r0, [r8, #L2X0_SAVE_OFFSET1] + cmp r0, #3 + bne do_wfi + bl omap4_get_sar_ram_base + ldr r9, [r0, #OMAP_TYPE_OFFSET] + cmp r9, #0x1 @ Check for HS device + bne skip_secure_l2_clean_op + mov r0, #1 @ Clean secure L2 + stmfd r13!, {r4-r12, r14} + ldr r12, =OMAP5_MON_CACHES_CLEAN_INDEX + DO_SMC + ldmfd r13!, {r4-r12, r14} +skip_secure_l2_clean_op: + mov r0, #2 @ Flush L2 + bl v7_flush_dcache_all + +do_wfi: + bl omap_do_wfi + + /* + * CPU is here when it failed to enter OFF/DORMANT or + * no low power state was attempted. + */ + mrc p15, 0, r0, c1, c0, 0 + tst r0, #(1 << 2) @ Check C bit enabled? + orreq r0, r0, #(1 << 2) @ Enable the C bit + mcreq p15, 0, r0, c1, c0, 0 + isb + mrc p15, 0, r0, c1, c0, 1 + tst r0, #(1 << 6) @ Check SMP bit enabled? + orreq r0, r0, #(1 << 6) + mcreq p15, 0, r0, c1, c0, 1 + isb + dsb + ldmfd sp!, {r4-r12, pc} +ENDPROC(omap5_finish_suspend) + +ENTRY(omap5_cpu_resume) +#ifdef CONFIG_ARM_ERRATA_761171 + /* + * Work around for errata for 761171. Streaming write that will not + * allocate in L2 could lead to data corruption. + */ + mrc p15, 0, r0, c0, c0, 0 @ read main ID register + and r5, r0, #0x00f00000 @ variant + and r6, r0, #0x0000000f @ revision + orr r6, r6, r5, lsr #20-4 @ combine variant and revision + cmp r6, #0x03 @ Present before r0p3 + bgt 1f + mrc p15, 0, r0, c1, c0, 1 @ Read Auxctrl + orr r0, r0, #0x3 << 27 @ bits[28:27]-L1_mode3_threshold + ldr r12, =OMAP5_MON_AUX_CTRL_INDEX + dsb + smc #0 + dsb +1: +#endif + mrc p15, 1, r0, c15, c0, 0 @ Read L2 ACTLR + cmp r0, #0x118 @ Check if it is already set + beq skip_sec_l2 + ldr r0, =0x118 @ Setup L2 ACTLR = 0x118 + ldr r12, =OMAP5_MON_L2AUX_CTRL_INDEX + dsb + smc #0 + dsb +skip_sec_l2: + b cpu_resume @ Jump to generic resume +ENDPROC(omap5_cpu_resume) +#endif + #endif /* defined(CONFIG_SMP) && defined(CONFIG_PM) */ ENTRY(omap_do_wfi) -- 2.14.1 ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 2/3] ARM: OMAP5: Add cpuidle assembly code @ 2017-08-17 23:01 ` Tony Lindgren 0 siblings, 0 replies; 18+ messages in thread From: Tony Lindgren @ 2017-08-17 23:01 UTC (permalink / raw) To: linux-arm-kernel From: Santosh Shilimkar <santosh.shilimkar@ti.com> In order to support CPU off modes during idle like omap4 already does, we need to add the assembly code needed for restoring the CPU state from off mode. The code is a combination of the following earlier patches done by Santosh Shilimkar <santosh.shilimkar@oracle.com> in TI Linux kernel tree: 881603c3f97f ("ARM: OMAP5: PM: Add CPU power off mode support") 411533444365 ("ARM: OMAP5: PM: Add MPU Open Switch Retention support") 3f9ea63594c3 ("ARM: OMAP5: PM: Add L2 memory power down support") Cc: Dave Gerlach <d-gerlach@ti.com> Cc: Nishanth Menon <nm@ti.com> Cc: Tero Kristo <t-kristo@ti.com> Cc: Santosh Shilimkar <santosh.shilimkar@oracle.com> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> [tony at atomide.com: updated against mainline kernel] Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/mach-omap2/common.h | 11 +++ arch/arm/mach-omap2/omap-mpuss-lowpower.c | 8 +- arch/arm/mach-omap2/omap-secure.h | 6 ++ arch/arm/mach-omap2/omap-wakeupgen.c | 5 +- arch/arm/mach-omap2/sleep44xx.S | 137 ++++++++++++++++++++++++++++++ 5 files changed, 164 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -318,6 +318,8 @@ static inline void omap4_cpu_resume(void) #if defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX) void omap5_secondary_startup(void); void omap5_secondary_hyp_startup(void); +int omap5_finish_suspend(unsigned long cpu_state); +void omap5_cpu_resume(void); #else static inline void omap5_secondary_startup(void) { @@ -326,6 +328,15 @@ static inline void omap5_secondary_startup(void) static inline void omap5_secondary_hyp_startup(void) { } + +static inline int omap5_finish_suspend(unsigned long cpu_state) +{ + return 0; +} + +static inline void omap5_cpu_resume(void) +{ +} #endif void pdata_quirks_init(const struct of_device_id *); diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -439,7 +439,13 @@ int __init omap4_mpuss_init(void) omap_pm_ops.scu_prepare = scu_pwrst_prepare; omap_pm_ops.hotplug_restart = omap4_secondary_startup; cpu_context_offset = OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET; - } else if (soc_is_omap54xx() || soc_is_dra7xx()) { + } else if (soc_is_omap54xx()) { + omap_pm_ops.finish_suspend = omap5_finish_suspend; + omap_pm_ops.resume = omap5_cpu_resume; + omap_pm_ops.hotplug_restart = omap5_secondary_startup; + cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET; + enable_mercury_retention_mode(); + } else if (soc_is_dra7xx()) { cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET; enable_mercury_retention_mode(); } diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h --- a/arch/arm/mach-omap2/omap-secure.h +++ b/arch/arm/mach-omap2/omap-secure.h @@ -36,6 +36,10 @@ #define OMAP4_HAL_SAVEHW_INDEX 0x1b #define OMAP4_HAL_SAVEALL_INDEX 0x1c #define OMAP4_HAL_SAVEGIC_INDEX 0x1d +#define OMAP5_HAL_SAVESECURERAM_INDEX 0x1c +#define OMAP5_HAL_SAVEHW_INDEX 0x1d +#define OMAP5_HAL_SAVEALL_INDEX 0x1e +#define OMAP5_HAL_SAVEGIC_INDEX 0x1f /* Secure Monitor mode APIs */ #define OMAP4_MON_SCU_PWR_INDEX 0x108 @@ -44,6 +48,8 @@ #define OMAP4_MON_L2X0_AUXCTRL_INDEX 0x109 #define OMAP4_MON_L2X0_PREFETCH_INDEX 0x113 +#define OMAP5_MON_CACHES_CLEAN_INDEX 0x103 +#define OMAP5_MON_L2AUX_CTRL_INDEX 0x104 #define OMAP5_DRA7_MON_SET_CNTFRQ_INDEX 0x109 #define OMAP5_MON_AMBA_IF_INDEX 0x108 #define OMAP5_DRA7_MON_SET_ACR_INDEX 0x107 diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -56,7 +56,7 @@ static DEFINE_RAW_SPINLOCK(wakeupgen_lock); static unsigned int irq_target_cpu[MAX_IRQS]; static unsigned int irq_banks = DEFAULT_NR_REG_BANKS; static unsigned int max_irqs = DEFAULT_IRQS; -static unsigned int omap_secure_apis; +static unsigned int omap_secure_apis, secure_api_index; #ifdef CONFIG_CPU_PM static unsigned int wakeupgen_context[MAX_NR_REG_BANKS]; @@ -345,7 +345,7 @@ static void irq_restore_context(void) static void irq_save_secure_context(void) { u32 ret; - ret = omap_secure_dispatcher(OMAP4_HAL_SAVEGIC_INDEX, + ret = omap_secure_dispatcher(secure_api_index, FLAG_START_CRITICAL, 0, 0, 0, 0, 0); if (ret != API_HAL_RET_VALUE_OK) @@ -549,6 +549,7 @@ static int __init wakeupgen_init(struct device_node *node, wakeupgen_ops = &omap4_wakeupgen_ops; } else if (soc_is_omap54xx()) { wakeupgen_ops = &omap5_wakeupgen_ops; + secure_api_index = OMAP5_HAL_SAVEGIC_INDEX; } else if (soc_is_am43xx()) { irq_banks = AM43XX_NR_REG_BANKS; max_irqs = AM43XX_IRQS; diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S --- a/arch/arm/mach-omap2/sleep44xx.S +++ b/arch/arm/mach-omap2/sleep44xx.S @@ -20,6 +20,7 @@ #include "common.h" #include "omap44xx.h" #include "omap4-sar-layout.h" +#include "omap-secure.h" #if defined(CONFIG_SMP) && defined(CONFIG_PM) @@ -331,6 +332,142 @@ ppa_por_params_offset: ENDPROC(omap4_cpu_resume) #endif /* CONFIG_ARCH_OMAP4 */ +#if defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX) + +/* + * ================================ + * == OMAP5 CPU suspend finisher == + * ================================ + * + * OMAP5 MPUSS states for the context save: + * save_state = + * 0 - Nothing lost and no need to save: MPUSS INA/CSWR + * 1 - CPUx L1 and logic lost: CPU OFF, MPUSS INA/CSWR + * 2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR + * 3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF + */ +ENTRY(omap5_finish_suspend) + stmfd sp!, {r4-r12, lr} + cmp r0, #0x0 + beq do_wfi @ No lowpower state, jump to WFI + + /* + * Flush all data from the L1 data cache before disabling + * SCTLR.C bit. + */ + bl omap4_get_sar_ram_base + ldr r9, [r0, #OMAP_TYPE_OFFSET] + cmp r9, #0x1 @ Check for HS device + bne skip_secure_l1_clean_op + mov r0, #0 @ Clean secure L1 + stmfd r13!, {r4-r12, r14} + ldr r12, =OMAP5_MON_CACHES_CLEAN_INDEX + DO_SMC + ldmfd r13!, {r4-r12, r14} +skip_secure_l1_clean_op: + bl v7_flush_dcache_louis + + /* + * Clear the SCTLR.C bit to prevent further data cache + * allocation. Clearing SCTLR.C would make all the data accesses + * strongly ordered and would not hit the cache. + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #(1 << 2) @ Disable the C bit + mcr p15, 0, r0, c1, c0, 0 + isb + + /* Clean and Invalidate L1 data cache. */ + bl v7_flush_dcache_louis + + /* + * Take CPU out of Symmetric Multiprocessing (SMP) mode and thus + * preventing the CPU from receiving cache, TLB, or BTB + * maintenance operations broadcast by other CPUs in the cluster. + */ + mrc p15, 0, r0, c1, c1, 2 @ Read NSACR data + tst r0, #(1 << 18) + mrcne p15, 0, r0, c1, c0, 1 + bicne r0, r0, #(1 << 6) @ Disable SMP bit + mcrne p15, 0, r0, c1, c0, 1 + isb + dsb + + bl omap4_get_sar_ram_base + mov r8, r0 + mrc p15, 0, r5, c0, c0, 5 @ Read MPIDR + ands r5, r5, #0x0f + ldreq r0, [r8, #L2X0_SAVE_OFFSET0] @ Retrieve L2 state + ldrne r0, [r8, #L2X0_SAVE_OFFSET1] + cmp r0, #3 + bne do_wfi + bl omap4_get_sar_ram_base + ldr r9, [r0, #OMAP_TYPE_OFFSET] + cmp r9, #0x1 @ Check for HS device + bne skip_secure_l2_clean_op + mov r0, #1 @ Clean secure L2 + stmfd r13!, {r4-r12, r14} + ldr r12, =OMAP5_MON_CACHES_CLEAN_INDEX + DO_SMC + ldmfd r13!, {r4-r12, r14} +skip_secure_l2_clean_op: + mov r0, #2 @ Flush L2 + bl v7_flush_dcache_all + +do_wfi: + bl omap_do_wfi + + /* + * CPU is here when it failed to enter OFF/DORMANT or + * no low power state was attempted. + */ + mrc p15, 0, r0, c1, c0, 0 + tst r0, #(1 << 2) @ Check C bit enabled? + orreq r0, r0, #(1 << 2) @ Enable the C bit + mcreq p15, 0, r0, c1, c0, 0 + isb + mrc p15, 0, r0, c1, c0, 1 + tst r0, #(1 << 6) @ Check SMP bit enabled? + orreq r0, r0, #(1 << 6) + mcreq p15, 0, r0, c1, c0, 1 + isb + dsb + ldmfd sp!, {r4-r12, pc} +ENDPROC(omap5_finish_suspend) + +ENTRY(omap5_cpu_resume) +#ifdef CONFIG_ARM_ERRATA_761171 + /* + * Work around for errata for 761171. Streaming write that will not + * allocate in L2 could lead to data corruption. + */ + mrc p15, 0, r0, c0, c0, 0 @ read main ID register + and r5, r0, #0x00f00000 @ variant + and r6, r0, #0x0000000f @ revision + orr r6, r6, r5, lsr #20-4 @ combine variant and revision + cmp r6, #0x03 @ Present before r0p3 + bgt 1f + mrc p15, 0, r0, c1, c0, 1 @ Read Auxctrl + orr r0, r0, #0x3 << 27 @ bits[28:27]-L1_mode3_threshold + ldr r12, =OMAP5_MON_AUX_CTRL_INDEX + dsb + smc #0 + dsb +1: +#endif + mrc p15, 1, r0, c15, c0, 0 @ Read L2 ACTLR + cmp r0, #0x118 @ Check if it is already set + beq skip_sec_l2 + ldr r0, =0x118 @ Setup L2 ACTLR = 0x118 + ldr r12, =OMAP5_MON_L2AUX_CTRL_INDEX + dsb + smc #0 + dsb +skip_sec_l2: + b cpu_resume @ Jump to generic resume +ENDPROC(omap5_cpu_resume) +#endif + #endif /* defined(CONFIG_SMP) && defined(CONFIG_PM) */ ENTRY(omap_do_wfi) -- 2.14.1 ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/3] ARM: OMAP5: Add cpuidle assembly code 2017-08-17 23:01 ` Tony Lindgren @ 2017-08-18 1:38 ` Nishanth Menon -1 siblings, 0 replies; 18+ messages in thread From: Nishanth Menon @ 2017-08-18 1:38 UTC (permalink / raw) To: Tony Lindgren, linux-omap Cc: Tero Kristo, Santosh Shilimkar, linux-arm-kernel, Dave Gerlach On 08/17/2017 06:01 PM, Tony Lindgren wrote: > From: Santosh Shilimkar <santosh.shilimkar@ti.com> > > In order to support CPU off modes during idle like omap4 already > does, we need to add the assembly code needed for restoring the > CPU state from off mode. > > The code is a combination of the following earlier patches done > by Santosh Shilimkar <santosh.shilimkar@oracle.com> in TI Linux > kernel tree: > > 881603c3f97f ("ARM: OMAP5: PM: Add CPU power off mode support") > 411533444365 ("ARM: OMAP5: PM: Add MPU Open Switch Retention support") > 3f9ea63594c3 ("ARM: OMAP5: PM: Add L2 memory power down support") Ref: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9f5dc91b691cf296c49aedf0a671fd659a70f737 and the fact that OSWR and OFF both have been descoped in production silicon, is again the reason why TI has not posted these preproduction experimentation patches upstream. NAK once again. Sorry. PS: deleting Santosh's old TI ID which should unfortunately be bouncing now. -- Regards, Nishanth Menon ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 2/3] ARM: OMAP5: Add cpuidle assembly code @ 2017-08-18 1:38 ` Nishanth Menon 0 siblings, 0 replies; 18+ messages in thread From: Nishanth Menon @ 2017-08-18 1:38 UTC (permalink / raw) To: linux-arm-kernel On 08/17/2017 06:01 PM, Tony Lindgren wrote: > From: Santosh Shilimkar <santosh.shilimkar@ti.com> > > In order to support CPU off modes during idle like omap4 already > does, we need to add the assembly code needed for restoring the > CPU state from off mode. > > The code is a combination of the following earlier patches done > by Santosh Shilimkar <santosh.shilimkar@oracle.com> in TI Linux > kernel tree: > > 881603c3f97f ("ARM: OMAP5: PM: Add CPU power off mode support") > 411533444365 ("ARM: OMAP5: PM: Add MPU Open Switch Retention support") > 3f9ea63594c3 ("ARM: OMAP5: PM: Add L2 memory power down support") Ref: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9f5dc91b691cf296c49aedf0a671fd659a70f737 and the fact that OSWR and OFF both have been descoped in production silicon, is again the reason why TI has not posted these preproduction experimentation patches upstream. NAK once again. Sorry. PS: deleting Santosh's old TI ID which should unfortunately be bouncing now. -- Regards, Nishanth Menon ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 3/3] ARM: OMAP5: Enable CPU off idle states 2017-08-17 23:01 ` Tony Lindgren @ 2017-08-17 23:01 ` Tony Lindgren -1 siblings, 0 replies; 18+ messages in thread From: Tony Lindgren @ 2017-08-17 23:01 UTC (permalink / raw) To: linux-omap Cc: Nishanth Menon, Tero Kristo, Santosh Shilimkar, linux-arm-kernel, Dave Gerlach With the idle code in place needed for supporting off mode for cpus, let's enable it. This seems to save about 0.2W of power compared to CPU retention states based on quick measurement on omap5-uevm. Some parts of the code is based on an earlier patch done by Santosh Shilimkar <santosh.shilimkar@oracle.com> in TI Linux kernel tree as commit 7e3035cf0e9b ("ARM: OMAP4+: CPUidle: Add OMAP5 idle driver support") Cc: Dave Gerlach <d-gerlach@ti.com> Cc: Nishanth Menon <nm@ti.com> Cc: Santosh Shilimkar <santosh.shilimkar@oracle.com> Cc: Tero Kristo <t-kristo@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/mach-omap2/cpuidle44xx.c | 14 ++++++++++++++ arch/arm/mach-omap2/pm44xx.c | 2 +- arch/arm/mach-omap2/powerdomains54xx_data.c | 10 +++++----- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -63,6 +63,11 @@ static struct idle_statedata omap5_idle_data[] = { .mpu_state = PWRDM_POWER_RET, .mpu_logic_state = PWRDM_POWER_RET, }, + { + .cpu_state = PWRDM_POWER_OFF, + .mpu_state = PWRDM_POWER_RET, + .mpu_logic_state = PWRDM_POWER_OFF, + }, }; static struct idle_statedata dra7_idle_data[] = { @@ -296,6 +301,15 @@ static struct cpuidle_driver omap5_idle_driver = { .name = "C2", .desc = "CPUx CSWR, MPUSS CSWR", }, + { + /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ + .exit_latency = 460 + 518, + .target_residency = 1100, + .flags = CPUIDLE_FLAG_TIMER_STOP | CPUIDLE_FLAG_COUPLED, + .enter = omap_enter_idle_coupled, + .name = "C3", + .desc = "CPUx OFF, MPUSS OSWR", + }, }, .state_count = ARRAY_SIZE(omap5_idle_data), .safe_state_index = 0, diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -225,7 +225,7 @@ int __init omap4_pm_init_early(void) if (cpu_is_omap446x()) pm44xx_errata |= PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD; - if (soc_is_omap54xx() || soc_is_dra7xx()) + if (soc_is_dra7xx()) pm44xx_errata |= PM_OMAP4_CPU_OSWR_DISABLE; return 0; diff --git a/arch/arm/mach-omap2/powerdomains54xx_data.c b/arch/arm/mach-omap2/powerdomains54xx_data.c --- a/arch/arm/mach-omap2/powerdomains54xx_data.c +++ b/arch/arm/mach-omap2/powerdomains54xx_data.c @@ -107,8 +107,8 @@ static struct powerdomain cpu0_54xx_pwrdm = { .voltdm = { .name = "mpu" }, .prcm_offs = OMAP54XX_PRCM_MPU_PRM_C0_INST, .prcm_partition = OMAP54XX_PRCM_MPU_PARTITION, - .pwrsts = PWRSTS_RET_ON, - .pwrsts_logic_ret = PWRSTS_RET, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, .banks = 1, .pwrsts_mem_ret = { [0] = PWRSTS_OFF_RET, /* cpu0_l1 */ @@ -124,8 +124,8 @@ static struct powerdomain cpu1_54xx_pwrdm = { .voltdm = { .name = "mpu" }, .prcm_offs = OMAP54XX_PRCM_MPU_PRM_C1_INST, .prcm_partition = OMAP54XX_PRCM_MPU_PARTITION, - .pwrsts = PWRSTS_RET_ON, - .pwrsts_logic_ret = PWRSTS_RET, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, .banks = 1, .pwrsts_mem_ret = { [0] = PWRSTS_OFF_RET, /* cpu1_l1 */ @@ -158,7 +158,7 @@ static struct powerdomain mpu_54xx_pwrdm = { .prcm_offs = OMAP54XX_PRM_MPU_INST, .prcm_partition = OMAP54XX_PRM_PARTITION, .pwrsts = PWRSTS_RET_ON, - .pwrsts_logic_ret = PWRSTS_RET, + .pwrsts_logic_ret = PWRSTS_OFF_RET, .banks = 2, .pwrsts_mem_ret = { [0] = PWRSTS_OFF_RET, /* mpu_l2 */ -- 2.14.1 ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 3/3] ARM: OMAP5: Enable CPU off idle states @ 2017-08-17 23:01 ` Tony Lindgren 0 siblings, 0 replies; 18+ messages in thread From: Tony Lindgren @ 2017-08-17 23:01 UTC (permalink / raw) To: linux-arm-kernel With the idle code in place needed for supporting off mode for cpus, let's enable it. This seems to save about 0.2W of power compared to CPU retention states based on quick measurement on omap5-uevm. Some parts of the code is based on an earlier patch done by Santosh Shilimkar <santosh.shilimkar@oracle.com> in TI Linux kernel tree as commit 7e3035cf0e9b ("ARM: OMAP4+: CPUidle: Add OMAP5 idle driver support") Cc: Dave Gerlach <d-gerlach@ti.com> Cc: Nishanth Menon <nm@ti.com> Cc: Santosh Shilimkar <santosh.shilimkar@oracle.com> Cc: Tero Kristo <t-kristo@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/mach-omap2/cpuidle44xx.c | 14 ++++++++++++++ arch/arm/mach-omap2/pm44xx.c | 2 +- arch/arm/mach-omap2/powerdomains54xx_data.c | 10 +++++----- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -63,6 +63,11 @@ static struct idle_statedata omap5_idle_data[] = { .mpu_state = PWRDM_POWER_RET, .mpu_logic_state = PWRDM_POWER_RET, }, + { + .cpu_state = PWRDM_POWER_OFF, + .mpu_state = PWRDM_POWER_RET, + .mpu_logic_state = PWRDM_POWER_OFF, + }, }; static struct idle_statedata dra7_idle_data[] = { @@ -296,6 +301,15 @@ static struct cpuidle_driver omap5_idle_driver = { .name = "C2", .desc = "CPUx CSWR, MPUSS CSWR", }, + { + /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ + .exit_latency = 460 + 518, + .target_residency = 1100, + .flags = CPUIDLE_FLAG_TIMER_STOP | CPUIDLE_FLAG_COUPLED, + .enter = omap_enter_idle_coupled, + .name = "C3", + .desc = "CPUx OFF, MPUSS OSWR", + }, }, .state_count = ARRAY_SIZE(omap5_idle_data), .safe_state_index = 0, diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -225,7 +225,7 @@ int __init omap4_pm_init_early(void) if (cpu_is_omap446x()) pm44xx_errata |= PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD; - if (soc_is_omap54xx() || soc_is_dra7xx()) + if (soc_is_dra7xx()) pm44xx_errata |= PM_OMAP4_CPU_OSWR_DISABLE; return 0; diff --git a/arch/arm/mach-omap2/powerdomains54xx_data.c b/arch/arm/mach-omap2/powerdomains54xx_data.c --- a/arch/arm/mach-omap2/powerdomains54xx_data.c +++ b/arch/arm/mach-omap2/powerdomains54xx_data.c @@ -107,8 +107,8 @@ static struct powerdomain cpu0_54xx_pwrdm = { .voltdm = { .name = "mpu" }, .prcm_offs = OMAP54XX_PRCM_MPU_PRM_C0_INST, .prcm_partition = OMAP54XX_PRCM_MPU_PARTITION, - .pwrsts = PWRSTS_RET_ON, - .pwrsts_logic_ret = PWRSTS_RET, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, .banks = 1, .pwrsts_mem_ret = { [0] = PWRSTS_OFF_RET, /* cpu0_l1 */ @@ -124,8 +124,8 @@ static struct powerdomain cpu1_54xx_pwrdm = { .voltdm = { .name = "mpu" }, .prcm_offs = OMAP54XX_PRCM_MPU_PRM_C1_INST, .prcm_partition = OMAP54XX_PRCM_MPU_PARTITION, - .pwrsts = PWRSTS_RET_ON, - .pwrsts_logic_ret = PWRSTS_RET, + .pwrsts = PWRSTS_OFF_RET_ON, + .pwrsts_logic_ret = PWRSTS_OFF_RET, .banks = 1, .pwrsts_mem_ret = { [0] = PWRSTS_OFF_RET, /* cpu1_l1 */ @@ -158,7 +158,7 @@ static struct powerdomain mpu_54xx_pwrdm = { .prcm_offs = OMAP54XX_PRM_MPU_INST, .prcm_partition = OMAP54XX_PRM_PARTITION, .pwrsts = PWRSTS_RET_ON, - .pwrsts_logic_ret = PWRSTS_RET, + .pwrsts_logic_ret = PWRSTS_OFF_RET, .banks = 2, .pwrsts_mem_ret = { [0] = PWRSTS_OFF_RET, /* mpu_l2 */ -- 2.14.1 ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 3/3] ARM: OMAP5: Enable CPU off idle states 2017-08-17 23:01 ` Tony Lindgren @ 2017-08-18 1:29 ` Nishanth Menon -1 siblings, 0 replies; 18+ messages in thread From: Nishanth Menon @ 2017-08-18 1:29 UTC (permalink / raw) To: Tony Lindgren, linux-omap Cc: Tero Kristo, Santosh Shilimkar, linux-arm-kernel, Dave Gerlach On 08/17/2017 06:01 PM, Tony Lindgren wrote: > With the idle code in place needed for supporting off mode for cpus, > let's enable it. This seems to save about 0.2W of power compared to > CPU retention states based on quick measurement on omap5-uevm. That makes sense since the Silicon you probably have is pre-production silicon. > > Some parts of the code is based on an earlier patch done by Santosh > Shilimkar <santosh.shilimkar@oracle.com> in TI Linux kernel tree as > commit 7e3035cf0e9b ("ARM: OMAP4+: CPUidle: Add OMAP5 idle driver > support") > unfortunately, you have been looking at some preproduction code which was being developed prior to the silicon going into production (also the reason why I have'nt upstreamed those changes). > diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c > --- a/arch/arm/mach-omap2/pm44xx.c > +++ b/arch/arm/mach-omap2/pm44xx.c > @@ -225,7 +225,7 @@ int __init omap4_pm_init_early(void) > if (cpu_is_omap446x()) > pm44xx_errata |= PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD; > > - if (soc_is_omap54xx() || soc_is_dra7xx()) > + if (soc_is_dra7xx()) > pm44xx_errata |= PM_OMAP4_CPU_OSWR_DISABLE; > > return 0; > diff --git a/arch/arm/mach-omap2/powerdomains54xx_data.c b/arch/arm/mach-omap2/powerdomains54xx_data.c > --- a/arch/arm/mach-omap2/powerdomains54xx_data.c > +++ b/arch/arm/mach-omap2/powerdomains54xx_data.c > @@ -107,8 +107,8 @@ static struct powerdomain cpu0_54xx_pwrdm = { > .voltdm = { .name = "mpu" }, > .prcm_offs = OMAP54XX_PRCM_MPU_PRM_C0_INST, > .prcm_partition = OMAP54XX_PRCM_MPU_PARTITION, > - .pwrsts = PWRSTS_RET_ON, > - .pwrsts_logic_ret = PWRSTS_RET, > + .pwrsts = PWRSTS_OFF_RET_ON, > + .pwrsts_logic_ret = PWRSTS_OFF_RET, > .banks = 1, > .pwrsts_mem_ret = { > [0] = PWRSTS_OFF_RET, /* cpu0_l1 */ > @@ -124,8 +124,8 @@ static struct powerdomain cpu1_54xx_pwrdm = { > .voltdm = { .name = "mpu" }, > .prcm_offs = OMAP54XX_PRCM_MPU_PRM_C1_INST, > .prcm_partition = OMAP54XX_PRCM_MPU_PARTITION, > - .pwrsts = PWRSTS_RET_ON, > - .pwrsts_logic_ret = PWRSTS_RET, > + .pwrsts = PWRSTS_OFF_RET_ON, > + .pwrsts_logic_ret = PWRSTS_OFF_RET, > .banks = 1, > .pwrsts_mem_ret = { > [0] = PWRSTS_OFF_RET, /* cpu1_l1 */ > @@ -158,7 +158,7 @@ static struct powerdomain mpu_54xx_pwrdm = { > .prcm_offs = OMAP54XX_PRM_MPU_INST, > .prcm_partition = OMAP54XX_PRM_PARTITION, > .pwrsts = PWRSTS_RET_ON, > - .pwrsts_logic_ret = PWRSTS_RET, > + .pwrsts_logic_ret = PWRSTS_OFF_RET, > .banks = 2, > .pwrsts_mem_ret = { > [0] = PWRSTS_OFF_RET, /* mpu_l2 */ > unfortunately, I have to NAK this patch. https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9f5dc91b691cf296c49aedf0a671fd659a70f737 as per Technical Reference Manual SWPU282AF–May 2012–Revised August 2016, PM_MPU_PWRSTCTRL can only support: ON INA, RET. (CSWR only). Same applies to CPUs as well. which was the reason in the first place for me to send the patch upstream. -- Regards, Nishanth Menon _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 3/3] ARM: OMAP5: Enable CPU off idle states @ 2017-08-18 1:29 ` Nishanth Menon 0 siblings, 0 replies; 18+ messages in thread From: Nishanth Menon @ 2017-08-18 1:29 UTC (permalink / raw) To: linux-arm-kernel On 08/17/2017 06:01 PM, Tony Lindgren wrote: > With the idle code in place needed for supporting off mode for cpus, > let's enable it. This seems to save about 0.2W of power compared to > CPU retention states based on quick measurement on omap5-uevm. That makes sense since the Silicon you probably have is pre-production silicon. > > Some parts of the code is based on an earlier patch done by Santosh > Shilimkar <santosh.shilimkar@oracle.com> in TI Linux kernel tree as > commit 7e3035cf0e9b ("ARM: OMAP4+: CPUidle: Add OMAP5 idle driver > support") > unfortunately, you have been looking at some preproduction code which was being developed prior to the silicon going into production (also the reason why I have'nt upstreamed those changes). > diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c > --- a/arch/arm/mach-omap2/pm44xx.c > +++ b/arch/arm/mach-omap2/pm44xx.c > @@ -225,7 +225,7 @@ int __init omap4_pm_init_early(void) > if (cpu_is_omap446x()) > pm44xx_errata |= PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD; > > - if (soc_is_omap54xx() || soc_is_dra7xx()) > + if (soc_is_dra7xx()) > pm44xx_errata |= PM_OMAP4_CPU_OSWR_DISABLE; > > return 0; > diff --git a/arch/arm/mach-omap2/powerdomains54xx_data.c b/arch/arm/mach-omap2/powerdomains54xx_data.c > --- a/arch/arm/mach-omap2/powerdomains54xx_data.c > +++ b/arch/arm/mach-omap2/powerdomains54xx_data.c > @@ -107,8 +107,8 @@ static struct powerdomain cpu0_54xx_pwrdm = { > .voltdm = { .name = "mpu" }, > .prcm_offs = OMAP54XX_PRCM_MPU_PRM_C0_INST, > .prcm_partition = OMAP54XX_PRCM_MPU_PARTITION, > - .pwrsts = PWRSTS_RET_ON, > - .pwrsts_logic_ret = PWRSTS_RET, > + .pwrsts = PWRSTS_OFF_RET_ON, > + .pwrsts_logic_ret = PWRSTS_OFF_RET, > .banks = 1, > .pwrsts_mem_ret = { > [0] = PWRSTS_OFF_RET, /* cpu0_l1 */ > @@ -124,8 +124,8 @@ static struct powerdomain cpu1_54xx_pwrdm = { > .voltdm = { .name = "mpu" }, > .prcm_offs = OMAP54XX_PRCM_MPU_PRM_C1_INST, > .prcm_partition = OMAP54XX_PRCM_MPU_PARTITION, > - .pwrsts = PWRSTS_RET_ON, > - .pwrsts_logic_ret = PWRSTS_RET, > + .pwrsts = PWRSTS_OFF_RET_ON, > + .pwrsts_logic_ret = PWRSTS_OFF_RET, > .banks = 1, > .pwrsts_mem_ret = { > [0] = PWRSTS_OFF_RET, /* cpu1_l1 */ > @@ -158,7 +158,7 @@ static struct powerdomain mpu_54xx_pwrdm = { > .prcm_offs = OMAP54XX_PRM_MPU_INST, > .prcm_partition = OMAP54XX_PRM_PARTITION, > .pwrsts = PWRSTS_RET_ON, > - .pwrsts_logic_ret = PWRSTS_RET, > + .pwrsts_logic_ret = PWRSTS_OFF_RET, > .banks = 2, > .pwrsts_mem_ret = { > [0] = PWRSTS_OFF_RET, /* mpu_l2 */ > unfortunately, I have to NAK this patch. https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9f5dc91b691cf296c49aedf0a671fd659a70f737 as per Technical Reference Manual SWPU282AF?May 2012?Revised August 2016, PM_MPU_PWRSTCTRL can only support: ON INA, RET. (CSWR only). Same applies to CPUs as well. which was the reason in the first place for me to send the patch upstream. -- Regards, Nishanth Menon ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 3/3] ARM: OMAP5: Enable CPU off idle states 2017-08-18 1:29 ` Nishanth Menon @ 2017-08-18 15:26 ` Tony Lindgren -1 siblings, 0 replies; 18+ messages in thread From: Tony Lindgren @ 2017-08-18 15:26 UTC (permalink / raw) To: Nishanth Menon Cc: Tero Kristo, linux-omap, Santosh Shilimkar, linux-arm-kernel, Dave Gerlach * Nishanth Menon <nm@ti.com> [170817 18:30]: > On 08/17/2017 06:01 PM, Tony Lindgren wrote: > > With the idle code in place needed for supporting off mode for cpus, > > let's enable it. This seems to save about 0.2W of power compared to > > CPU retention states based on quick measurement on omap5-uevm. > > That makes sense since the Silicon you probably have is pre-production > silicon. It seems to be es2.0, the measurement was just based on a glance of the power supply after rmmod of ehci-omap and ohci-platform modules. > unfortunately, you have been looking at some preproduction code which was > being developed prior to the silicon going into production (also the reason > why I have'nt upstreamed those changes). Oh I did not know that, I was just looking at the old ti-linux-3-8-y-kernel that the igepv5 kernel tree is based on. > unfortunately, I have to NAK this patch. > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9f5dc91b691cf296c49aedf0a671fd659a70f737 > as per Technical Reference Manual SWPU282AF–May 2012–Revised August 2016, > PM_MPU_PWRSTCTRL can only support: ON INA, RET. (CSWR only). > > Same applies to CPUs as well. which was the reason in the first place for me > to send the patch upstream. OK, is there some hardware errata issued on that? I also noticed these patches won't work when booted with LPAE enabled kernel for some reason. Regards, Tony _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 3/3] ARM: OMAP5: Enable CPU off idle states @ 2017-08-18 15:26 ` Tony Lindgren 0 siblings, 0 replies; 18+ messages in thread From: Tony Lindgren @ 2017-08-18 15:26 UTC (permalink / raw) To: linux-arm-kernel * Nishanth Menon <nm@ti.com> [170817 18:30]: > On 08/17/2017 06:01 PM, Tony Lindgren wrote: > > With the idle code in place needed for supporting off mode for cpus, > > let's enable it. This seems to save about 0.2W of power compared to > > CPU retention states based on quick measurement on omap5-uevm. > > That makes sense since the Silicon you probably have is pre-production > silicon. It seems to be es2.0, the measurement was just based on a glance of the power supply after rmmod of ehci-omap and ohci-platform modules. > unfortunately, you have been looking at some preproduction code which was > being developed prior to the silicon going into production (also the reason > why I have'nt upstreamed those changes). Oh I did not know that, I was just looking at the old ti-linux-3-8-y-kernel that the igepv5 kernel tree is based on. > unfortunately, I have to NAK this patch. > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9f5dc91b691cf296c49aedf0a671fd659a70f737 > as per Technical Reference Manual SWPU282AF?May 2012?Revised August 2016, > PM_MPU_PWRSTCTRL can only support: ON INA, RET. (CSWR only). > > Same applies to CPUs as well. which was the reason in the first place for me > to send the patch upstream. OK, is there some hardware errata issued on that? I also noticed these patches won't work when booted with LPAE enabled kernel for some reason. Regards, Tony ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 3/3] ARM: OMAP5: Enable CPU off idle states 2017-08-18 15:26 ` Tony Lindgren @ 2017-08-18 22:27 ` Nishanth Menon -1 siblings, 0 replies; 18+ messages in thread From: Nishanth Menon @ 2017-08-18 22:27 UTC (permalink / raw) To: Tony Lindgren Cc: Tero Kristo, linux-omap, Santosh Shilimkar, linux-arm-kernel, Dave Gerlach On 08/18/2017 10:26 AM, Tony Lindgren wrote: > * Nishanth Menon <nm@ti.com> [170817 18:30]: >> On 08/17/2017 06:01 PM, Tony Lindgren wrote: >>> With the idle code in place needed for supporting off mode for cpus, >>> let's enable it. This seems to save about 0.2W of power compared to >>> CPU retention states based on quick measurement on omap5-uevm. >> >> That makes sense since the Silicon you probably have is pre-production >> silicon. > > It seems to be es2.0, the measurement was just based on a glance > of the power supply after rmmod of ehci-omap and ohci-platform > modules. yeah -> ES2.0 did have two stages prior to being approved for production. > >> unfortunately, you have been looking at some preproduction code which was >> being developed prior to the silicon going into production (also the reason >> why I have'nt upstreamed those changes). > > Oh I did not know that, I was just looking at the old > ti-linux-3-8-y-kernel that the igepv5 kernel tree is > based on. > unfortunately so. >> unfortunately, I have to NAK this patch. >> >> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9f5dc91b691cf296c49aedf0a671fd659a70f737 >> as per Technical Reference Manual SWPU282AF–May 2012–Revised August 2016, >> PM_MPU_PWRSTCTRL can only support: ON INA, RET. (CSWR only). >> >> Same applies to CPUs as well. which was the reason in the first place for me >> to send the patch upstream. > > OK, is there some hardware errata issued on that? To my knowledge, errata is only when TRM is not updated (feature that is supposed to work, but does'nt). TRM's version history indicates descope. At least to my information all production customers should have been informed about this as well. > > I also noticed these patches won't work when booted with LPAE > enabled kernel for some reason. > Obviously, I dont think I am interested in chasing any further down this road. SoC descope is a severe decision that has been taken after a lot of internal and customer considerations. there is no point in trying to enable a descoped feature when even if it worked on 10 boards means nothing from a production device perspective, and there are devices out there in production with OMAP5. -- Regards, Nishanth Menon _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 3/3] ARM: OMAP5: Enable CPU off idle states @ 2017-08-18 22:27 ` Nishanth Menon 0 siblings, 0 replies; 18+ messages in thread From: Nishanth Menon @ 2017-08-18 22:27 UTC (permalink / raw) To: linux-arm-kernel On 08/18/2017 10:26 AM, Tony Lindgren wrote: > * Nishanth Menon <nm@ti.com> [170817 18:30]: >> On 08/17/2017 06:01 PM, Tony Lindgren wrote: >>> With the idle code in place needed for supporting off mode for cpus, >>> let's enable it. This seems to save about 0.2W of power compared to >>> CPU retention states based on quick measurement on omap5-uevm. >> >> That makes sense since the Silicon you probably have is pre-production >> silicon. > > It seems to be es2.0, the measurement was just based on a glance > of the power supply after rmmod of ehci-omap and ohci-platform > modules. yeah -> ES2.0 did have two stages prior to being approved for production. > >> unfortunately, you have been looking at some preproduction code which was >> being developed prior to the silicon going into production (also the reason >> why I have'nt upstreamed those changes). > > Oh I did not know that, I was just looking at the old > ti-linux-3-8-y-kernel that the igepv5 kernel tree is > based on. > unfortunately so. >> unfortunately, I have to NAK this patch. >> >> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9f5dc91b691cf296c49aedf0a671fd659a70f737 >> as per Technical Reference Manual SWPU282AF?May 2012?Revised August 2016, >> PM_MPU_PWRSTCTRL can only support: ON INA, RET. (CSWR only). >> >> Same applies to CPUs as well. which was the reason in the first place for me >> to send the patch upstream. > > OK, is there some hardware errata issued on that? To my knowledge, errata is only when TRM is not updated (feature that is supposed to work, but does'nt). TRM's version history indicates descope. At least to my information all production customers should have been informed about this as well. > > I also noticed these patches won't work when booted with LPAE > enabled kernel for some reason. > Obviously, I dont think I am interested in chasing any further down this road. SoC descope is a severe decision that has been taken after a lot of internal and customer considerations. there is no point in trying to enable a descoped feature when even if it worked on 10 boards means nothing from a production device perspective, and there are devices out there in production with OMAP5. -- Regards, Nishanth Menon ^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2017-08-18 22:27 UTC | newest] Thread overview: 18+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-08-17 23:01 [PATCH 0/3] omap5 cpu off mode support Tony Lindgren 2017-08-17 23:01 ` Tony Lindgren 2017-08-17 23:01 ` [PATCH 1/3] ARM: OMAP2+: Separate dra7 cpuidle from omap5 Tony Lindgren 2017-08-17 23:01 ` Tony Lindgren 2017-08-17 23:42 ` Tony Lindgren 2017-08-17 23:42 ` Tony Lindgren 2017-08-17 23:01 ` [PATCH 2/3] ARM: OMAP5: Add cpuidle assembly code Tony Lindgren 2017-08-17 23:01 ` Tony Lindgren 2017-08-18 1:38 ` Nishanth Menon 2017-08-18 1:38 ` Nishanth Menon 2017-08-17 23:01 ` [PATCH 3/3] ARM: OMAP5: Enable CPU off idle states Tony Lindgren 2017-08-17 23:01 ` Tony Lindgren 2017-08-18 1:29 ` Nishanth Menon 2017-08-18 1:29 ` Nishanth Menon 2017-08-18 15:26 ` Tony Lindgren 2017-08-18 15:26 ` Tony Lindgren 2017-08-18 22:27 ` Nishanth Menon 2017-08-18 22:27 ` Nishanth Menon
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.