From fe7ea0062f2f846bb68447c7b813b9230285dbeb Mon Sep 17 00:00:00 2001 From: Mohan V Date: Fri, 22 Jun 2012 08:40:02 -0600 Subject: ARM: OMAP3: PM: correct enable/disable of daisy io chain Currently the enabling and disabling of IO Daisy chain is not according to the TRM. The below steps are followed to enable/ disable the IO chain, based loosely on the "Sec 3.5.7.2.2 I/O Wake-Up Mechanism" section in OMAP3630 Public TRM[1]. Steps to enable IO chain: [a] Set PM_WKEN_WKUP.EN_IO bit [b] Set the PM_WKEN_WKUP.EN_IO_CHAIN bit [c] Poll for PM_WKST_WKUP.ST_IO_CHAIN. [d] When ST_IO_CHAIN bit set to 1, clear PM_WKEN_WKUP.EN_IO_CHAIN [e] Clear ST_IO_CHAIN bit. Steps to disable IO chain: [a] Clear PM_WKEN_WKUP.EN_IO_CHAIN bit [b] Clear PM_WKEN_WKUP.EN_IO bit [c] Clear PM_WKST_WKUP.ST_IO bit by writing 1 to it. Step [e] & [c] in each case can be skipped, as these are handled by the PRCM interrupt handler later. [1] http://focus.ti.com/pdfs/wtbu/OMAP36xx_ES1.x_PUBLIC_TRM_vV.zip Signed-off-by: Mohan V Signed-off-by: Vishwanath BS [paul@pwsan.com: modified commit message to clarify that these steps are based loosely on the TRM section, rather than documented exactly] Reviewed-by: Rajendra Nayak [paul@pwsan.com: resolved new warnings from checkpatch] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/pm34xx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'arch/arm/mach-omap2/pm34xx.c') diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index a34023d0ca7c..6d7f0d8a3103 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -81,16 +81,17 @@ static void omap3_enable_io_chain(void) /* Do a readback to assure write has been done */ omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); - while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & + while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) & OMAP3430_ST_IO_CHAIN_MASK)) { timeout++; if (timeout > 1000) { pr_err("Wake up daisy chain activation failed.\n"); return; } - omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, - WKUP_MOD, PM_WKEN); } + omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, + PM_WKEN); + } static void omap3_disable_io_chain(void) -- cgit v1.2.3 From 09659fa72bf638ae986b8b80cf99309768dd0b32 Mon Sep 17 00:00:00 2001 From: Vishwanath BS Date: Fri, 22 Jun 2012 08:40:02 -0600 Subject: ARM: OMAP3: PM: Move IO Daisychain function to omap3 prm file Since IO Daisychain modifies only PRM registers, it makes sense to move it to PRM File. Also changed the timeout value for IO chain enable to 100us and added a wait for status disable at the end. Thanks to Nishanth Menon for contributing a fix to the timeout code waiting for WUCLKOUT to go high. Signed-off-by: Vishwanath BS Signed-off-by: Tero Kristo Cc: Nishanth Menon Reviewed-by: Rajendra Nayak [paul@pwsan.com: renamed omap3_trigger_io_chain() to better describe the end result and to match other PRM functions; removed omap3_disable_io_chain(); moved MAX_IOPAD_LATCH_TIME to prcm-common as it will also be used by the OMAP4 code; removed unnecessary barrier; added kerneldoc; added credit for fix from Nishanth] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/pm34xx.c | 35 ++--------------------------------- 1 file changed, 2 insertions(+), 33 deletions(-) (limited to 'arch/arm/mach-omap2/pm34xx.c') diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 6d7f0d8a3103..9d6cb7cc94ab 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -72,34 +72,6 @@ static struct powerdomain *mpu_pwrdm, *neon_pwrdm; static struct powerdomain *core_pwrdm, *per_pwrdm; static struct powerdomain *cam_pwrdm; -static void omap3_enable_io_chain(void) -{ - int timeout = 0; - - omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, - PM_WKEN); - /* Do a readback to assure write has been done */ - omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); - - while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) & - OMAP3430_ST_IO_CHAIN_MASK)) { - timeout++; - if (timeout > 1000) { - pr_err("Wake up daisy chain activation failed.\n"); - return; - } - } - omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, - PM_WKEN); - -} - -static void omap3_disable_io_chain(void) -{ - omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, - PM_WKEN); -} - static void omap3_core_save_context(void) { omap3_ctrl_save_padconf(); @@ -305,7 +277,7 @@ void omap_sram_idle(void) core_next_state < PWRDM_POWER_ON)) { omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); if (omap3_has_io_chain_ctrl()) - omap3_enable_io_chain(); + omap3xxx_prm_reconfigure_io_chain(); } pwrdm_pre_transition(); @@ -382,12 +354,9 @@ void omap_sram_idle(void) /* Disable IO-PAD and IO-CHAIN wakeup */ if (omap3_has_io_wakeup() && (per_next_state < PWRDM_POWER_ON || - core_next_state < PWRDM_POWER_ON)) { + core_next_state < PWRDM_POWER_ON)) omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); - if (omap3_has_io_chain_ctrl()) - omap3_disable_io_chain(); - } clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]); } -- cgit v1.2.3 From fafcdd53220f44d7ae2f06a9ce20c8d550df2d9b Mon Sep 17 00:00:00 2001 From: Vishwanath BS Date: Wed, 2 May 2012 02:44:40 -0600 Subject: ARM: OMAP3: PM: Remove IO Daisychain control from cpuidle As IO Daisy chain sequence is triggered via hwmod mux, there is no need to control it from cpuidle path for OMAP3. Also as omap3_disable_io_chain is no longer being used, just remove the function. Signed-off-by: Vishwanath BS Signed-off-by: Tero Kristo Reviewed-by: Rajendra Nayak Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/pm34xx.c | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'arch/arm/mach-omap2/pm34xx.c') diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 9d6cb7cc94ab..9d8258f16666 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -272,13 +272,6 @@ void omap_sram_idle(void) /* Enable IO-PAD and IO-CHAIN wakeups */ per_next_state = pwrdm_read_next_pwrst(per_pwrdm); core_next_state = pwrdm_read_next_pwrst(core_pwrdm); - if (omap3_has_io_wakeup() && - (per_next_state < PWRDM_POWER_ON || - core_next_state < PWRDM_POWER_ON)) { - omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); - if (omap3_has_io_chain_ctrl()) - omap3xxx_prm_reconfigure_io_chain(); - } pwrdm_pre_transition(); @@ -351,13 +344,6 @@ void omap_sram_idle(void) if (per_next_state < PWRDM_POWER_ON) omap2_gpio_resume_after_idle(); - /* Disable IO-PAD and IO-CHAIN wakeup */ - if (omap3_has_io_wakeup() && - (per_next_state < PWRDM_POWER_ON || - core_next_state < PWRDM_POWER_ON)) - omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, - PM_WKEN); - clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]); } -- cgit v1.2.3 From e055548953355b6e69c56f9e54388845b29b4e97 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Fri, 11 May 2012 16:00:24 -0700 Subject: ARM: OMAP2+: powerdomain: allow pre/post transtion to be per pwrdm Iteration over all power domains in the idle path is unnecessary since only power domains that are transitioning need to be accounted for. Also PRCM register accesses are known to be expensive, so the additional latency added to the idle path is signficiant. In order allow the pre/post transitions to be isolated and called per-pwrdm, change the API so passing in a specific power domain will trigger the pre/post transtion accounting for only that specific power domain. Passing NULL means iterating over all power domains as is current behavior. Reviewed-by: Santosh Shilimkar Tested-by: Santosh Shilimkar Tested-by: Grazvydas Ignotas Acked-by: Paul Walmsley Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm34xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-omap2/pm34xx.c') diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index e67d898433fb..0bbbc8c82fd8 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -273,7 +273,7 @@ void omap_sram_idle(void) per_next_state = pwrdm_read_next_pwrst(per_pwrdm); core_next_state = pwrdm_read_next_pwrst(core_pwrdm); - pwrdm_pre_transition(); + pwrdm_pre_transition(NULL); /* PER */ if (per_next_state < PWRDM_POWER_ON) { @@ -338,7 +338,7 @@ void omap_sram_idle(void) } omap3_intc_resume_idle(); - pwrdm_post_transition(); + pwrdm_post_transition(NULL); /* PER */ if (per_next_state < PWRDM_POWER_ON) -- cgit v1.2.3 From 58f0829b7186150318c79515f0e0850c5e7a9c89 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Fri, 11 May 2012 15:47:17 -0700 Subject: ARM: OMAP3: PM: call pre/post transition per powerdomain We only need to call the pre/post transtion methods when we know the power state is changing. First, split up the pre/post transition calls to be per-powerdomain, and then make them conditional on whether the power domain is actually changing states. Reviewed-by: Santosh Shilimkar Tested-by: Santosh Shilimkar Tested-by: Grazvydas Ignotas Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm34xx.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'arch/arm/mach-omap2/pm34xx.c') diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 0bbbc8c82fd8..dec2d55d7182 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -273,16 +273,21 @@ void omap_sram_idle(void) per_next_state = pwrdm_read_next_pwrst(per_pwrdm); core_next_state = pwrdm_read_next_pwrst(core_pwrdm); - pwrdm_pre_transition(NULL); + if (mpu_next_state < PWRDM_POWER_ON) { + pwrdm_pre_transition(mpu_pwrdm); + pwrdm_pre_transition(neon_pwrdm); + } /* PER */ if (per_next_state < PWRDM_POWER_ON) { + pwrdm_pre_transition(per_pwrdm); per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0; omap2_gpio_prepare_for_idle(per_going_off); } /* CORE */ if (core_next_state < PWRDM_POWER_ON) { + pwrdm_pre_transition(core_pwrdm); if (core_next_state == PWRDM_POWER_OFF) { omap3_core_save_context(); omap3_cm_save_context(); @@ -335,14 +340,20 @@ void omap_sram_idle(void) omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK, OMAP3430_GR_MOD, OMAP3_PRM_VOLTCTRL_OFFSET); + pwrdm_post_transition(core_pwrdm); } omap3_intc_resume_idle(); - pwrdm_post_transition(NULL); - /* PER */ - if (per_next_state < PWRDM_POWER_ON) + if (per_next_state < PWRDM_POWER_ON) { omap2_gpio_resume_after_idle(); + pwrdm_post_transition(per_pwrdm); + } + + if (mpu_next_state < PWRDM_POWER_ON) { + pwrdm_post_transition(mpu_pwrdm); + pwrdm_post_transition(neon_pwrdm); + } clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]); } -- cgit v1.2.3 From 34059a878f5cb20652cbc937f35c925f2b378831 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Tue, 19 Jun 2012 09:54:38 -0700 Subject: ARM: OMAP3: PM: cleanup cam_pwrdm leftovers commit e7410cf7 (OMAP3: PM: move device-specific special cases from PM core into CPUidle) moved mangement of cam_pwrdm to CPUidle but left some remnants behind, namely the call to clkcm_allo_idle() for the clockdomains in the MPU pwrdm. Remove these since they are not necessary and cause unwanted latency in the idle path. Acked-by: Tero Kristo Reviewed-by: Santosh Shilimkar Tested-by: Santosh Shilimkar Tested-by: Grazvydas Ignotas Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm34xx.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch/arm/mach-omap2/pm34xx.c') diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index dec2d55d7182..e63fdd02c6f5 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -70,7 +70,6 @@ void (*omap3_do_wfi_sram)(void); static struct powerdomain *mpu_pwrdm, *neon_pwrdm; static struct powerdomain *core_pwrdm, *per_pwrdm; -static struct powerdomain *cam_pwrdm; static void omap3_core_save_context(void) { @@ -354,8 +353,6 @@ void omap_sram_idle(void) pwrdm_post_transition(mpu_pwrdm); pwrdm_post_transition(neon_pwrdm); } - - clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]); } static void omap3_pm_idle(void) @@ -716,7 +713,6 @@ int __init omap3_pm_init(void) neon_pwrdm = pwrdm_lookup("neon_pwrdm"); per_pwrdm = pwrdm_lookup("per_pwrdm"); core_pwrdm = pwrdm_lookup("core_pwrdm"); - cam_pwrdm = pwrdm_lookup("cam_pwrdm"); neon_clkdm = clkdm_lookup("neon_clkdm"); mpu_clkdm = clkdm_lookup("mpu_clkdm"); -- cgit v1.2.3