ARM: OMAP3PLUS PM: Add IO DaisyChain support via hwmod mux
Subsystems (6)
v2 cover ARM: OMAP3PLUS PM: Add IO DaisyChain support via hwmod mux
The following patch series provides IO Daisychain feature via omap hwmod mux framework. The patch series has been generated against Tero's V11 irq chaining series [1].
Testing Performed:
OMAP3:
Tested for Retention and OFF mode in suspend/cpuidle path on OMAP3430 SDP and ZOOM3. Also tested against latest UART Runtime + Chain Handler patches[2] for Ret/OFF in cpuidle/suspend path.
OMAP4:
Boot tested on OMAP4430 SDP. Also tested for Suspend/resume with CSWR using custom OMAP4 kernel as Core PM is not yet supported in mainline.
Thanks to Govind for testing the series with UART Runtime patches on various OMAP3 platforms.
Patch series is available here[3].
[1]: git://gitorious.org/~kristo/omap-pm/omap-pm-work.git chain-prcm-v11
[2]: git://gitorious.org/runtime_3-0/runtime_3-0.git
for_3_3/tmp_rc4_uart_pm_intg
[3]: git://gitorious.org/omap-pm/linux.git for_3.3/io_daisy_chain_rebased
Mohan V (1):
ARM: OMAP3 PM: correct enable/disable of daisy io chain
Rajendra Nayak (1):
ARM: OMAP4 PM: Add IO Daisychain support
Vishwanath BS (5):
ARM: OMAP3 PM: Move IO Daisychain function to omap3 prm file
ARM: OMAP3 PM: Enable IO Wake up
ARM: OMAP3PLUS PM: Add IO Daisychain support via hwmod mux
ARM: OMAP3 PM: Remove IO Daisychain control from cpuidle
ARM: OMAP3 PM: Enable IO Daisychain for supported chips
arch/arm/mach-omap2/omap_hwmod.c | 9 +++++- arch/arm/mach-omap2/pm.c | 11 ++++++++ arch/arm/mach-omap2/pm.h | 1 + arch/arm/mach-omap2/pm34xx.c | 47 ++--------------------------------- arch/arm/mach-omap2/prm2xxx_3xxx.c | 27 ++++++++++++++++++++ arch/arm/mach-omap2/prm2xxx_3xxx.h | 7 +++++ arch/arm/mach-omap2/prm44xx.c | 30 +++++++++++++++++++++++ arch/arm/mach-omap2/prm44xx.h | 1 + 8 files changed, 87 insertions(+), 46 deletions(-)
PATCH v2 1/7 ARM: OMAP3 PM: correct enable/disable of daisy io chain
From: Mohan V <[email protected]>
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 according to the "Sec 3.5.7.2.2 I/O Wake-Up Mechanism" 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
--- arch/arm/mach-omap2/pm34xx.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-)
arch/arm/mach-omap2/pm34xx.c +4 -3
@@ -105,16 +105,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 )
Signature · 1 line
1.7.0.4
PATCH v2 2/7 ARM: OMAP3 PM: Move IO Daisychain function to omap3 prm file
In reply to Vishwanath BSSince IO Daisychain modifies only PRM registers, it makes sense to move it to PRM File.
--- arch/arm/mach-omap2/pm34xx.c | 30 +----------------------------- arch/arm/mach-omap2/prm2xxx_3xxx.c | 33 +++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/prm2xxx_3xxx.h | 14 ++++++++++++++ 3 files changed, 48 insertions(+), 29 deletions(-)
arch/arm/mach-omap2/pm34xx.c +1 -29
@@ -96,34 +96,6 @@ static inline void omap3_per_restore_context(void)omap_gpio_restore_context (); } -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 ();
@@ -335,7 +307,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 (); +omap3_trigger_wuclk_ctrl (); }/* Block console output in case it is on one of the OMAP UARTs */
arch/arm/mach-omap2/prm2xxx_3xxx.c +33 -0
@@ -227,6 +227,39 @@ u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)return omap2_prm_rmw_mod_reg_bits (mask, bits,OMAP3430_GR_MOD , offset); } +/** +* Maximum time(us) it takes to output the signal WUCLKOUT of the last pad of +* the I/O ring after asserting WUCLKIN high +*/ +#define MAX_IOPAD_LATCH_TIME 1000 + +/* OMAP3 Daisychain trigger sequence */ +void omap3_trigger_wuclk_ctrl (void ) +{ +int i =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 ); + +omap_test_timeout ( + (((omap2_prm_read_mod_reg (WKUP_MOD ,PM_WKST ) & +OMAP3430_ST_IO_CHAIN_MASK ) ==1 )), +MAX_IOPAD_LATCH_TIME , i); + +omap2_prm_clear_mod_reg_bits (OMAP3430_EN_IO_CHAIN_MASK ,WKUP_MOD , +PM_WKEN ); +} + +/* OMAP3 Daisychain disable sequence */ +void omap3_disable_io_chain (void ) +{ +if (omap_rev () >=OMAP3430_REV_ES3_1 ) +omap2_prm_clear_mod_reg_bits (OMAP3430_EN_IO_CHAIN_MASK ,WKUP_MOD , +PM_WKEN ); +} +static int __init omap3xxx_prcm_init (void ) {if (cpu_is_omap34xx ())
arch/arm/mach-omap2/prm2xxx_3xxx.h +14 -0
@@ -289,6 +289,18 @@ static inline int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, "not suppose to be used on omap4\n"); return 0; } +static inline void omap3_trigger_wuclk_ctrl (void ) +{ +WARN (1 ,"prm: omap2xxx/omap3xxx specific function and " +"not suppose to be used on omap4\n" ); +return 0 ; +} +static inline void omap3_disable_io_chain (void ) +{ +WARN (1 ,"prm: omap2xxx/omap3xxx specific function and " +"not suppose to be used on omap4\n" ); +return 0 ; +}#else /* Power/reset management domain register get/set */ extern u32 omap2_prm_read_mod_reg (s16 module,u16 idx);
@@ -302,6 +314,8 @@ extern u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask);extern int omap2_prm_is_hardreset_asserted (s16 prm_mod,u8 shift);extern int omap2_prm_assert_hardreset (s16 prm_mod,u8 shift);extern int omap2_prm_deassert_hardreset (s16 prm_mod,u8 rst_shift,u8 st_shift); +extern void omap3_trigger_wuclk_ctrl (void ); +extern void omap3_disable_io_chain (void );/* OMAP3-specific VP functions */ u32 omap3_prm_vp_check_txdone (u8 vp_id);
Signature · 1 line
1.7.0.4
PATCH v2 2/7 ARM: OMAP3 PM: Move IO Daisychain function to omap3 prm file
Quoted 2 lines · Vishwanath BS
Since IO Daisychain modifies only PRM registers, it makes sense to move it to PRM File.
You also rename the function but don't describe why or what the new name means or where it comes from. An only the 'enable' version is renamed, but the 'disable' version stays the same. Confusing.
Also, please fix checkpatch warning:
WARNING: line over 80 characters
#103: FILE: arch/arm/mach-omap2/prm2xxx_3xxx.c:259:
+ omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
[...]
Quoted 4 lines
arch/arm/mach-omap2/prm2xxx_3xxx.c +4
-0+/* OMAP3 Daisychain trigger sequence */ +void omap3_trigger_wuclk_ctrl (void ) +{ +int i =0 ;
arch/arm/mach-omap2/prm2xxx_3xxx.c u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset) · line 249
Quoted 10 lines
arch/arm/mach-omap2/prm2xxx_3xxx.c +10
-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 ); + +omap_test_timeout ( + (((omap2_prm_read_mod_reg (WKUP_MOD ,PM_WKST ) & +OMAP3430_ST_IO_CHAIN_MASK ) ==1 )), +MAX_IOPAD_LATCH_TIME , i);
indentation is messy
arch/arm/mach-omap2/prm2xxx_3xxx.c u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset) · line 253
Quoted 4 lines
arch/arm/mach-omap2/prm2xxx_3xxx.c +4
-0+ +omap2_prm_clear_mod_reg_bits (OMAP3430_EN_IO_CHAIN_MASK ,WKUP_MOD , +PM_WKEN ); +}
Kevin
PATCH v2 3/7 ARM: OMAP4 PM: Add IO Daisychain support
In reply to Vishwanath BSFrom: Rajendra Nayak <[email protected]>
patch adds IO Daisychain support for OMAP4 as per section 3.9.4 in OMAP4430 Public TRM.
--- arch/arm/mach-omap2/prm44xx.c | 30 ++++++++++++++++++++++++++++++ arch/arm/mach-omap2/prm44xx.h | 1 + 2 files changed, 31 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/prm44xx.c +30 -0
@@ -142,3 +142,33 @@ static int __init omap4xxx_prcm_init(void)return omap_prcm_register_chain_handler (&omap4_prcm_irq_setup);return 0 ; } + +/** +* Maximum time(us) it takes to output the signal WUCLKOUT of the last pad of +* the I/O ring after asserting WUCLKIN high +*/ +#define MAX_IOPAD_LATCH_TIME 1000 + +/* OMAP4 IO Daisychain trigger sequence */ +void omap4_trigger_wuclk_ctrl (void ) +{ +int i =0 ; + +/* Enable GLOBAL_WUEN */ +if (!(omap4_prm_read_inst_reg (OMAP4430_PRM_DEVICE_INST ,OMAP4_PRM_IO_PMCTRL_OFFSET ) + &OMAP4430_GLOBAL_WUEN_MASK )) +omap4_prm_rmw_inst_reg_bits (OMAP4430_GLOBAL_WUEN_MASK , +OMAP4430_GLOBAL_WUEN_MASK ,OMAP4430_PRM_DEVICE_INST , +OMAP4_PRM_IO_PMCTRL_OFFSET ); + +/* Trigger WUCLKIN enable */ +omap4_prm_rmw_inst_reg_bits (OMAP4430_WUCLK_CTRL_MASK ,OMAP4430_WUCLK_CTRL_MASK , +OMAP4430_PRM_DEVICE_INST ,OMAP4_PRM_IO_PMCTRL_OFFSET ); +omap_test_timeout ( + ((omap4_prm_read_inst_reg (OMAP4430_PRM_DEVICE_INST ,OMAP4_PRM_IO_PMCTRL_OFFSET ) + >>OMAP4430_WUCLK_STATUS_SHIFT ) ==1 ),MAX_IOPAD_LATCH_TIME , i); +/* Trigger WUCLKIN disable */ +omap4_prm_rmw_inst_reg_bits (OMAP4430_WUCLK_CTRL_MASK ,0x0 , +OMAP4430_PRM_DEVICE_INST ,OMAP4_PRM_IO_PMCTRL_OFFSET ); +return ; +}
arch/arm/mach-omap2/prm44xx.h +1 -0
@@ -750,6 +750,7 @@extern u32 omap4_prm_read_inst_reg (s16 inst,u16 idx);extern void omap4_prm_write_inst_reg (u32 val,s16 inst,u16 idx);extern u32 omap4_prm_rmw_inst_reg_bits (u32 mask,u32 bits,s16 inst,s16 idx); +extern void omap4_trigger_wuclk_ctrl (void );/* OMAP4-specific VP functions */ u32 omap4_prm_vp_check_txdone (u8 vp_id);
Signature · 1 line
1.7.0.4
PATCH v2 3/7 ARM: OMAP4 PM: Add IO Daisychain support
Quoted 8 lines · Vishwanath BS
From: Rajendra Nayak <[email protected]>
patch adds IO Daisychain support for OMAP4 as per section 3.9.4 in OMAP4430 Public TRM.
Signed-off-by Rajendra Nayak <[email protected]>Signed-off-by Vishwanath BS <[email protected]>Tested-by Govindraj.R <[email protected]>
One of my least favorite things to have to remind others to do, but:
Please fix checkpatch warnings:
WARNING: line over 80 characters
#43: FILE: arch/arm/mach-omap2/prm44xx.c:158:
+ if (!(omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IO_PMCTRL_OFFSET)
WARNING: line over 80 characters
#46: FILE: arch/arm/mach-omap2/prm44xx.c:161:
+ OMAP4430_GLOBAL_WUEN_MASK, OMAP4430_PRM_DEVICE_INST,
WARNING: line over 80 characters
#50: FILE: arch/arm/mach-omap2/prm44xx.c:165:
+ omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, OMAP4430_WUCLK_CTRL_MASK,
WARNING: line over 80 characters
#53: FILE: arch/arm/mach-omap2/prm44xx.c:168:
+ ((omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IO_PMCTRL_OFFSET)
PATCH v2 4/7 ARM: OMAP3 PM: Enable IO Wake up
In reply to Vishwanath BSEnable IO Wake up for OMAP3 as part of PM Init.
Currently this has been managed in cpuidle path which is not the right place. Subsequent patch will remove IO Daisy chain handling in cpuidle path once daisy chain is handled as part of hwmod mux.
--- arch/arm/mach-omap2/pm34xx.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/pm34xx.c +3 -0
@@ -836,6 +836,9 @@ static int __init omap3_pm_init(void) goto err1; } +if (omap3_has_io_wakeup ()) +omap2_prm_set_mod_reg_bits (OMAP3430_EN_IO_MASK ,WKUP_MOD ,PM_WKEN ); + ret =pwrdm_for_each (pwrdms_setup,NULL );if (ret) {printk (KERN_ERR "Failed to setup powerdomains\n" );
Signature · 1 line
1.7.0.4
PATCH v2 4/7 ARM: OMAP3 PM: Enable IO Wake up
Quoted 7 lines · Vishwanath BS
Enable IO Wake up for OMAP3 as part of PM Init.
Currently this has been managed in cpuidle path which is not the right place. Subsequent patch will remove IO Daisy chain handling in cpuidle path once daisy chain is handled as part of hwmod mux.Signed-off-by Vishwanath BS <[email protected]>Tested-by Govindraj.R <[email protected]>
WARNING: line over 80 characters
#27: FILE: arch/arm/mach-omap2/pm34xx.c:840:
+ omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN);
PATCH v2 5/7 ARM: OMAP3PLUS PM: Add IO Daisychain support via hwmod mux
In reply to Vishwanath BSIO Daisychain feature has to be triggered whenever there is a change in device's mux configuration (See section 3.9.4 in OMAP4 Public TRM vP).
Now devices can idle independent of the powerdomain, there can be a window where device is idled and corresponding powerdomain can be ON/INACTIVE state. In such situations, since both module wake up is enabled at padlevel as well as io daisychain sequence is triggered, there will be 2 PRCM interrupts (Module async wake up via swakeup and IO Pad interrupt). But as PRCM Interrupt handler clears the Module Padlevel WKST bit in the first interrupt, module specific interrupt handler will not triggered for the second time
Also look at detailed explanation given by Rajendra at
http://www.spinics.net/lists/linux-serial/msg04480.html
--- arch/arm/mach-omap2/omap_hwmod.c | 9 +++++++-- arch/arm/mach-omap2/pm.c | 11 +++++++++++ arch/arm/mach-omap2/pm.h | 1 + 3 files changed, 19 insertions(+), 2 deletions(-)
arch/arm/mach-omap2/omap_hwmod.c +7 -2
@@ -151,6 +151,7 @@#include "prm44xx.h" #include "prminst44xx.h" #include "mux.h" +#include "pm.h" /* Maximum microseconds to wait for OMAP module to softreset */ #define MAX_MODULE_SOFTRESET_WAIT 10000
@@ -1462,8 +1463,10 @@ static int _enable(struct omap_hwmod *oh)/* Mux pins for device runtime if populated */ if (oh->mux && (!oh->mux->enabled || ((oh->_state == _HWMOD_STATE_IDLE) && - oh->mux->pads_dynamic))) + oh->mux->pads_dynamic))) {omap_hwmod_mux (oh->mux, _HWMOD_STATE_ENABLED); +omap_trigger_wuclk_ctrl (); + }_add_initiator_dep (oh, mpu_oh);
@@ -1553,8 +1556,10 @@ static int _idle(struct omap_hwmod *oh)clkdm_hwmod_disable (oh->clkdm, oh);/* Mux pins for device idle if populated */ -if (oh->mux && oh->mux->pads_dynamic) +if (oh->mux && oh->mux->pads_dynamic) {omap_hwmod_mux (oh->mux, _HWMOD_STATE_IDLE); +omap_trigger_wuclk_ctrl (); + } oh->_state = _HWMOD_STATE_IDLE;
arch/arm/mach-omap2/pm.c +11 -0
@@ -25,6 +25,8 @@#include "clockdomain.h" #include "pm.h" #include "twl-common.h" +#include "prm2xxx_3xxx.h" +#include "prm44xx.h" static struct omap_device_pm_latency *pm_lats;
@@ -64,6 +66,15 @@ static void omap2_init_processor_devices(void) } } +void omap_trigger_wuclk_ctrl (void ) +{ +if (cpu_is_omap34xx ()) +omap3_trigger_wuclk_ctrl (); + +if (cpu_is_omap44xx ()) +omap4_trigger_wuclk_ctrl (); +} +/* Types of sleep_switch used in omap_set_pwrdm_state */ #define FORCEWAKEUP_SWITCH 0#define LOWPOWERSTATE_SWITCH 1
arch/arm/mach-omap2/pm.h +1 -0
@@ -21,6 +21,7 @@ extern void omap_sram_idle(void);extern int omap3_can_sleep (void );extern int omap_set_pwrdm_state (struct powerdomain *pwrdm,u32 state);extern int omap3_idle_init (void ); +void omap_trigger_wuclk_ctrl (void );#if defined(CONFIG_PM_OPP )extern int omap3_opp_init (void );
Signature · 1 line
1.7.0.4
PATCH v2 5/7 ARM: OMAP3PLUS PM: Add IO Daisychain support via hwmod mux
Quoted 2 lines · Vishwanath BS
IO Daisychain feature has to be triggered whenever there is a change in device's mux configuration (See section 3.9.4 in OMAP4 Public TRM vP).
...in addition to the triggering still happening in the idle path,
right? IIUC, after this series, there's still a call in omap_sram_idle().
Quoted 12 lines
Now devices can idle independent of the powerdomain, there can be a window where device is idled and corresponding powerdomain can be ON/INACTIVE state. In such situations, since both module wake up is enabled at padlevel as well as io daisychain sequence is triggered, there will be 2 PRCM interrupts (Module async wake up via swakeup and IO Pad interrupt). But as PRCM Interrupt handler clears the Module Padlevel WKST bit in the first interrupt, module specific interrupt handler will not triggered for the second time
Also look at detailed explanation given by Rajendra at
http://www.spinics.net/lists/linux-serial/msg04480.htmlSigned-off-by Vishwanath BS <[email protected]>Tested-by Govindraj.R <[email protected]>
[...]
arch/arm/mach-omap2/pm.c static void omap2_init_processor_devices(void) · line 76
Quoted 8 lines
arch/arm/mach-omap2/pm.c +8
-0+void omap_trigger_wuclk_ctrl (void ) +{ +if (cpu_is_omap34xx ()) +omap3_trigger_wuclk_ctrl (); + +if (cpu_is_omap44xx ()) +omap4_trigger_wuclk_ctrl (); +}
cpu_is_* usage is only acceptable at init time. Please use a function pointer initialized at init time for this.
Kevin
PATCH v2 5/7 ARM: OMAP3PLUS PM: Add IO Daisychain support via hwmod mux
Quoted 7 lines · Kevin Hilman
Quoted 2 lines · Vishwanath BS
Quoted 2 lines
IO Daisychain feature has to be triggered whenever there is a change in device's mux configuration (See section 3.9.4 in OMAP4 Public TRM vP).
...in addition to the triggering still happening in the idle path,
right? IIUC, after this series, there's still a call inomap_sram_idle().
oops, please ignore this comment. I see the answer in PATCH 6/7.
Sorry for the noise.
Kevin
PATCH v2 5/7 ARM: OMAP3PLUS PM: Add IO Daisychain support via hwmod mux
In reply to Vishwanath BSQuoted 34 lines · Vishwanath BS
IO Daisychain feature has to be triggered whenever there is a change in device's mux configuration (See section 3.9.4 in OMAP4 Public TRM vP).
Now devices can idle independent of the powerdomain, there can be a window where device is idled and corresponding powerdomain can be ON/INACTIVE state. In such situations, since both module wake up is enabled at padlevel as well as io daisychain sequence is triggered, there will be 2 PRCM interrupts (Module async wake up via swakeup and IO Pad interrupt). But as PRCM Interrupt handler clears the Module Padlevel WKST bit in the first interrupt, module specific interrupt handler will not triggered for the second time
Also look at detailed explanation given by Rajendra at
http://www.spinics.net/lists/linux-serial/msg04480.htmlSigned-off-by Vishwanath BS <[email protected]>Tested-by Govindraj.R <[email protected]>--- arch/arm/mach-omap2/omap_hwmod.c | 9 +++++++-- arch/arm/mach-omap2/pm.c | 11 +++++++++++ arch/arm/mach-omap2/pm.h | 1 + 3 files changed, 19 insertions(+), 2 deletions(-)arch/arm/mach-omap2/omap_hwmod.c +1
-0@@ -151,6 +151,7 @@#include "prm44xx.h" #include "prminst44xx.h" #include "mux.h" +#include "pm.h" /* Maximum microseconds to wait for OMAP module to softreset */ #define MAX_MODULE_SOFTRESET_WAIT 10000
arch/arm/mach-omap2/omap_hwmod.c static int _enable(struct omap_hwmod *oh) · line 1469
Quoted 8 lines
arch/arm/mach-omap2/omap_hwmod.c +3
-1@@ -1462,8 +1463,10 @@ static int _enable(struct omap_hwmod *oh)/* Mux pins for device runtime if populated */ if (oh->mux && (!oh->mux->enabled || ((oh->_state == _HWMOD_STATE_IDLE) && - oh->mux->pads_dynamic))) + oh->mux->pads_dynamic))) {omap_hwmod_mux (oh->mux, _HWMOD_STATE_ENABLED); +omap_trigger_wuclk_ctrl (); + }
Why is the IO chain enabled during hwmod _enable()?
arch/arm/mach-omap2/omap_hwmod.c static int _idle(struct omap_hwmod *oh) · line 1562
Quoted 11 lines
arch/arm/mach-omap2/omap_hwmod.c +3
-1_add_initiator_dep (oh, mpu_oh);@@ -1553,8 +1556,10 @@ static int _idle(struct omap_hwmod *oh)clkdm_hwmod_disable (oh->clkdm, oh);/* Mux pins for device idle if populated */ -if (oh->mux && oh->mux->pads_dynamic) +if (oh->mux && oh->mux->pads_dynamic) {omap_hwmod_mux (oh->mux, _HWMOD_STATE_IDLE); +omap_trigger_wuclk_ctrl (); + }
Since this is now happening in idle for every hwmod with dynamic pads, the underlying function should probably cache the current value so it doesn't have to do a multiple PRCM register accesses it's only going to set a bit that's already set.
Kevin
Quoted 43 lines
arch/arm/mach-omap2/omap_hwmod.c +0
-0oh->_state = _HWMOD_STATE_IDLE;arch/arm/mach-omap2/pm.c +11
-0@@ -25,6 +25,8 @@#include "clockdomain.h" #include "pm.h" #include "twl-common.h" +#include "prm2xxx_3xxx.h" +#include "prm44xx.h" static struct omap_device_pm_latency *pm_lats;@@ -64,6 +66,15 @@ static void omap2_init_processor_devices(void) } } +void omap_trigger_wuclk_ctrl (void ) +{ +if (cpu_is_omap34xx ()) +omap3_trigger_wuclk_ctrl (); + +if (cpu_is_omap44xx ()) +omap4_trigger_wuclk_ctrl (); +} +/* Types of sleep_switch used in omap_set_pwrdm_state */ #define FORCEWAKEUP_SWITCH 0#define LOWPOWERSTATE_SWITCH 1arch/arm/mach-omap2/pm.h +1
-0@@ -21,6 +21,7 @@ extern void omap_sram_idle(void);extern int omap3_can_sleep (void );extern int omap_set_pwrdm_state (struct powerdomain *pwrdm,u32 state);extern int omap3_idle_init (void ); +void omap_trigger_wuclk_ctrl (void );#if defined(CONFIG_PM_OPP )extern int omap3_opp_init (void );
PATCH v2 6/7 ARM: OMAP3 PM: Remove IO Daisychain control from cpuidle
In reply to Vishwanath BSAs 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.
--- arch/arm/mach-omap2/pm34xx.c | 17 ----------------- arch/arm/mach-omap2/prm2xxx_3xxx.c | 8 -------- arch/arm/mach-omap2/prm2xxx_3xxx.h | 7 ------- 3 files changed, 0 insertions(+), 32 deletions(-)
arch/arm/mach-omap2/pm34xx.c +0 -17
@@ -302,13 +302,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 ()) -omap3_trigger_wuclk_ctrl (); - }/* Block console output in case it is on one of the OMAP UARTs */ if (!is_suspending ())
@@ -406,16 +399,6 @@ void omap_sram_idle(void)console_unlock (); console_still_active: -/* 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 ); -if (omap3_has_io_chain_ctrl ()) -omap3_disable_io_chain (); - } -clkdm_allow_idle (mpu_pwrdm->pwrdm_clkdms[0 ]); }
arch/arm/mach-omap2/prm2xxx_3xxx.c +0 -8
@@ -252,14 +252,6 @@ void omap3_trigger_wuclk_ctrl(void) PM_WKEN); } -/* OMAP3 Daisychain disable sequence */ -void omap3_disable_io_chain (void ) -{ -if (omap_rev () >=OMAP3430_REV_ES3_1 ) -omap2_prm_clear_mod_reg_bits (OMAP3430_EN_IO_CHAIN_MASK ,WKUP_MOD , -PM_WKEN ); -} -static int __init omap3xxx_prcm_init (void ) {if (cpu_is_omap34xx ())
arch/arm/mach-omap2/prm2xxx_3xxx.h +0 -7
@@ -295,12 +295,6 @@ static inline void omap3_trigger_wuclk_ctrl(void) "not suppose to be used on omap4\n"); return 0; } -static inline void omap3_disable_io_chain (void ) -{ -WARN (1 ,"prm: omap2xxx/omap3xxx specific function and " -"not suppose to be used on omap4\n" ); -return 0 ; -}#else /* Power/reset management domain register get/set */ extern u32 omap2_prm_read_mod_reg (s16 module,u16 idx);
@@ -315,7 +309,6 @@ extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift);extern int omap2_prm_assert_hardreset (s16 prm_mod,u8 shift);extern int omap2_prm_deassert_hardreset (s16 prm_mod,u8 rst_shift,u8 st_shift);extern void omap3_trigger_wuclk_ctrl (void ); -extern void omap3_disable_io_chain (void );/* OMAP3-specific VP functions */ u32 omap3_prm_vp_check_txdone (u8 vp_id);
Signature · 1 line
1.7.0.4
PATCH v2 6/7 ARM: OMAP3 PM: Remove IO Daisychain control from cpuidle
Quoted 7 lines · Vishwanath BS
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_chainis no longer being used, just remove the function.Signed-off-by Vishwanath BS <[email protected]>Tested-by Govindraj.R <[email protected]>
In the TRM (4460 public TRM vM) it says:
"The software must enable the I/O wakeup prior entering a low-power
mode and disable it following a wake-up event."
but after this series, once it's enabled, it is never disabled. What
am I missing?
Kevin
PATCH v2 7/7 ARM: OMAP3 PM: Enable IO Daisychain for supported chips
In reply to Vishwanath BSIO Daisychain has to be enabled only if the corresponding omap has io chain wake up capability.
--- arch/arm/mach-omap2/prm2xxx_3xxx.c | 26 ++++++++++++++------------ 1 files changed, 14 insertions(+), 12 deletions(-)
arch/arm/mach-omap2/prm2xxx_3xxx.c +14 -12
@@ -238,18 +238,20 @@ void omap3_trigger_wuclk_ctrl(void) {int i =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 ); - -omap_test_timeout ( - (((omap2_prm_read_mod_reg (WKUP_MOD ,PM_WKST ) & -OMAP3430_ST_IO_CHAIN_MASK ) ==1 )), -MAX_IOPAD_LATCH_TIME , i); - -omap2_prm_clear_mod_reg_bits (OMAP3430_EN_IO_CHAIN_MASK ,WKUP_MOD , -PM_WKEN ); +if (omap3_has_io_chain_ctrl ()) { +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 ); + +omap_test_timeout ( + (((omap2_prm_read_mod_reg (WKUP_MOD ,PM_WKST ) & +OMAP3430_ST_IO_CHAIN_MASK ) ==1 )), +MAX_IOPAD_LATCH_TIME , i); + +omap2_prm_clear_mod_reg_bits (OMAP3430_EN_IO_CHAIN_MASK ,WKUP_MOD , +PM_WKEN ); + } }static int __init omap3xxx_prcm_init (void )
Signature · 1 line
1.7.0.4
v2 cover ARM: OMAP3PLUS PM: Add IO DaisyChain support via hwmod mux
In reply to Vishwanath BSQuoted 2 lines · Vishwanath BS
The following patch series provides IO Daisychain feature via omap hwmod mux framework. The patch series has been generated against Tero's V11 irq chaining series [1].
Tero's series has now been reworked a bit by Paul for merging in v3.3.
Can you rebase and retest this against Tony's 'uart' branch which now includes the reworked PRCM handler as well as the UART runtime PM series that is queued for v3.3.
Thanks,
Kevin