ARM: OMAP2+: Fix omap3 off idle power consumption creeping up
Subsystems (4)
Tony Lindgren
maintainerPATCH 1/1 ARM: OMAP2+: Fix omap3 off idle power consumption creeping up
If we use a combination of VMODE and I2C4 for retention modes, eventually the off idle power consumption will creep up by about 23mW, even during off mode with I2C4 always staying enabled.
Looks like the only way to fix the extra power consumption is to disable I2C4 usage by setting SEL_VMODE for both off idle and retention idle. Let's also update the comments accordingly.
--- arch/arm/mach-omap2/vc.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-)
arch/arm/mach-omap2/vc.c +14 -10
@@ -284,6 +284,9 @@ void omap3_vc_set_pmic_signaling(int core_next_state) OMAP3430_PRM_POLCTRL_CLKREQ_POL)#define PRM_POLCTRL_TWL_VAL OMAP3430_PRM_POLCTRL_CLKREQ_POL +#define OMAP3_VOLTCTRL_CFG (OMAP3430_PRM_VOLTCTRL_SEL_VMODE | \ + OMAP3430_PRM_VOLTCTRL_SEL_OFF) +/* * Configure signal polarity for sys_clkreq and sys_off_mode pins * as the default values are wrong and can cause the system to hang
@@ -309,18 +312,19 @@ static void __init omap3_vc_init_pmic_signaling(struct voltagedomain *voltdm) }/* -* By default let's use I2C4 signaling for retention idle -* and sys_off_mode pin signaling for off idle. This way we -* have sys_clk_req pin go down for retention and both -* sys_clk_req and sys_off_mode pins will go down for off -* idle. And we can also scale voltages to zero for off-idle. -* Note that no actual voltage scaling during off-idle will -* happen unless the board specific twl4030 PMIC scripts are -* loaded. +* By default let's use pin based (VMODE) signaling for retention +* idle and off idle. Trying to use both VMODE and I2C4 will cause +* the I2C4 to eventually stay always on consuming extra 23mW even in +* off idle. With VMODE based configuration, we have sys_clk_req pin +* go down for retention and both sys_clk_req and sys_off_mode pins +* will go down for off idle. And we can also scale voltages to zero +* for off-idle, while I2C4 configuration can only scale down to 0.6V. +* Note that no actual voltage scaling during off-idle will happen +* unless the board specific twl4030 PMIC scripts are loaded. */ val = voltdm->read (OMAP3_PRM_VOLTCTRL_OFFSET ); -if (!(val &OMAP3430_PRM_VOLTCTRL_SEL_OFF )) { - val |=OMAP3430_PRM_VOLTCTRL_SEL_OFF ; +if (!(val &OMAP3_VOLTCTRL_CFG )) { + val |=OMAP3_VOLTCTRL_CFG ;pr_debug ("PM: setting voltctrl sys_off_mode signaling to 0x%x\n" , val); voltdm->write (val,OMAP3_PRM_VOLTCTRL_OFFSET );
Signature · 1 line
2.1.4
Tony Lindgren
maintainerPATCH 1/1 ARM: OMAP2+: Fix omap3 off idle power consumption creeping up
Quoted 7 lines · Tony Lindgren
If we use a combination of VMODE and I2C4 for retention modes, eventually the off idle power consumption will creep up by about 23mW, even during off mode with I2C4 always staying enabled.
Looks like the only way to fix the extra power consumption is to disable I2C4 usage by setting
SEL_VMODEfor both off idle and retention idle. Let's also update the comments accordingly.
Thanks Nishanth for pointing me to the related SmartReflex I2C4 erratum. No need to disable I2C4 with the SREN workaround :)
Better patch below, presumably this only affects omap3?
Regards,
Tony
8< ------------------------------
From: Tony Lindgren <[email protected]>
Date: Tue, 21 Apr 2015 14:31:23 -0700
Subject: [PATCH] ARM: OMAP2+: Fix omap3 off idle power consumption creeping up
If we use a combination of VMODE and I2C4 for retention modes, eventually the off idle power consumption will creep up by about 23mW, even during off mode with I2C4 always staying enabled.
Turns out this is because of erratum 2.11 "Extra Power Consumed When Repeated Start Operation Mode Is Enabled on I2C Interface Dedicated for Smart Reflex (I2C4)" as pointed out by Nishanth Menon <[email protected]>.
Let's fix the issue by adding i2c_cfg_clear_mask for the bits to clear when initializing the I2C4 adapter so we can clear SREN bit that drives the I2C4 lines low otherwise when there is no traffic.
sys_clkreq and sys_off_mode")
arch/arm/mach-omap2/prm-regbits-34xx.h +1 -0
@@ -112,6 +112,7 @@#define OMAP3430_VC_CMD_ONLP_SHIFT 16#define OMAP3430_VC_CMD_RET_SHIFT 8#define OMAP3430_VC_CMD_OFF_SHIFT 0 +#define OMAP3430_SREN_MASK (1 << 4)#define OMAP3430_HSEN_MASK (1 << 3)#define OMAP3430_MCODE_MASK (0x7 << 0)#define OMAP3430_VALID_MASK (1 << 24)
arch/arm/mach-omap2/vc.c +10 -2
@@ -316,7 +316,8 @@ static void __init omap3_vc_init_pmic_signaling(struct voltagedomain *voltdm)* idle. And we can also scale voltages to zero for off-idle. * Note that no actual voltage scaling during off-idle will * happen unless the board specific twl4030 PMIC scripts are -* loaded. +* loaded. See also omap_vc_i2c_init for comments regarding +* erratum 2.11. */ val = voltdm->read (OMAP3_PRM_VOLTCTRL_OFFSET );if (!(val &OMAP3430_PRM_VOLTCTRL_SEL_OFF )) {
@@ -704,9 +705,16 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm)return ; } +/* +* Note that for omap3 OMAP3430_SREN_MASK clears SREN to work around +* erratum 2.11 "Extra Power Consumed When Repeated Start Operation +* Mode Is Enabled on I2C Interface Dedicated for Smart Reflex (I2C4)". +* Otherwise I2C4 eventually leads into about 23mW extran power being +* consumed even during off idle using VMODE. +*/ i2c_high_speed = voltdm->pmic->i2c_high_speed;if (i2c_high_speed) - voltdm->rmw (vc->common->i2c_cfg_hsen_mask, + voltdm->rmw (vc->common->i2c_cfg_clear_mask, vc->common->i2c_cfg_hsen_mask, vc->common->i2c_cfg_reg);
arch/arm/mach-omap2/vc.h +2 -0
@@ -34,6 +34,7 @@ struct voltagedomain;* @cmd_ret_shift: RET field shift in PRM_VC_CMD_VAL_* register * @cmd_off_shift: OFF field shift in PRM_VC_CMD_VAL_* register * @i2c_cfg_reg: I2C configuration register offset +* @i2c_cfg_clear_mask: high-speed mode bit clear mask in I2C config register * @i2c_cfg_hsen_mask: high-speed mode bit field mask in I2C config register * @i2c_mcode_mask: MCODE field mask for I2C config register *
@@ -52,6 +53,7 @@ struct omap_vc_common {u8 cmd_ret_shift;u8 cmd_off_shift;u8 i2c_cfg_reg; +u8 i2c_cfg_clear_mask;u8 i2c_cfg_hsen_mask;u8 i2c_mcode_mask; };
arch/arm/mach-omap2/vc3xxx_data.c +2 -0
@@ -28,6 +28,7 @@/* * VC data common to 34xx/36xx chips * XXX This stuff presumably belongs in the vc3xxx.c or vc.c file. +* Note that we must clear SREN to work around erratum 2.11. */ static struct omap_vc_common omap3_vc_common = { .bypass_val_reg =OMAP3_PRM_VC_BYPASS_VAL_OFFSET ,
@@ -40,6 +41,7 @@ static struct omap_vc_common omap3_vc_common = { .cmd_onlp_shift = OMAP3430_VC_CMD_ONLP_SHIFT, .cmd_ret_shift = OMAP3430_VC_CMD_RET_SHIFT, .cmd_off_shift = OMAP3430_VC_CMD_OFF_SHIFT, + .i2c_cfg_clear_mask = OMAP3430_SREN_MASK, .i2c_cfg_hsen_mask = OMAP3430_HSEN_MASK, .i2c_cfg_reg = OMAP3_PRM_VC_I2C_CFG_OFFSET, .i2c_mcode_mask = OMAP3430_MCODE_MASK,
arch/arm/mach-omap2/vc44xx_data.c +1 -0
@@ -42,6 +42,7 @@ static const struct omap_vc_common omap4_vc_common = { .cmd_ret_shift = OMAP4430_RET_SHIFT, .cmd_off_shift = OMAP4430_OFF_SHIFT, .i2c_cfg_reg = OMAP4_PRM_VC_CFG_I2C_MODE_OFFSET, + .i2c_cfg_clear_mask = 0, .i2c_cfg_hsen_mask = OMAP4430_HSMODEEN_MASK, .i2c_mcode_mask = OMAP4430_HSMCODE_MASK, };
PATCH 1/1 ARM: OMAP2+: Fix omap3 off idle power consumption creeping up
Quoted 5 lines · Tony Lindgren
Quoted 4 lines · Tony Lindgren
If we use a combination of VMODE and I2C4 for retention modes, eventually the off idle power consumption will creep up by about 23mW, even during off mode with I2C4 always staying enabled.
Quoted 8 lines
Quoted 3 lines
Looks like the only way to fix the extra power consumption is to disable I2C4 usage by setting
SEL_VMODEfor both off idle and retention idle. Let's also update the comments accordingly.Thanks Nishanth for pointing me to the related SmartReflex I2C4 erratum. No need to disable I2C4 with the SREN workaround :)
Better patch below, presumably this only affects omap3?
SREN applies to both OMAP3 and 4 - so, the patch looks right.
Quoted 10 lines
Regards,
Tony
8< ------------------------------
From: Tony Lindgren <[email protected]>
Date: Tue, 21 Apr 2015 14:31:23 -0700
Subject: [PATCH] ARM: OMAP2+: Fix omap3 off idle power consumption creeping up
Quoted 5 lines
If we use a combination of VMODE and I2C4 for retention modes, eventually the off idle power consumption will creep up by about 23mW, even during off mode with I2C4 always staying enabled.
Turns out this is because of erratum 2.11 "Extra Power Consumed
I suggest using the unique ID
i531 - that remains constant across SoCs.
Quoted 29 lines
When Repeated Start Operation Mode Is Enabled on I2C Interface Dedicated for Smart Reflex (I2C4)" as pointed out by Nishanth Menon <[email protected]>.
Let's fix the issue by adding
i2c_cfg_clear_maskfor the bits to clear when initializing the I2C4 adapter so we can clear SREN bit that drives the I2C4 lines low otherwise when there is no traffic.Fixes 3b8c4ebb7630 ("ARM: OMAP3: Fix idle mode signaling for
sys_clkreqandsys_off_mode")Cc Kevin Hilman <[email protected]>Cc Nishanth Menon <[email protected]>Cc Tero Kristo <[email protected]>Signed-off-by Tony Lindgren <[email protected]>arch/arm/mach-omap2/prm-regbits-34xx.h +1
-0@@ -112,6 +112,7 @@#define OMAP3430_VC_CMD_ONLP_SHIFT 16#define OMAP3430_VC_CMD_RET_SHIFT 8#define OMAP3430_VC_CMD_OFF_SHIFT 0 +#define OMAP3430_SREN_MASK (1 << 4)#define OMAP3430_HSEN_MASK (1 << 3)#define OMAP3430_MCODE_MASK (0x7 << 0)#define OMAP3430_VALID_MASK (1 << 24)
arch/arm/mach-omap2/vc.c static void __init omap3_vc_init_pmic_signaling(struct voltagedomain *voltdm) · line 320
Quoted 6 lines
arch/arm/mach-omap2/vc.c +2
-1@@ -316,7 +316,8 @@ static void __init omap3_vc_init_pmic_signaling(struct voltagedomain *voltdm)* idle. And we can also scale voltages to zero for off-idle. * Note that no actual voltage scaling during off-idle will * happen unless the board specific twl4030 PMIC scripts are -* loaded. +* loaded. See also omap_vc_i2c_init for comments regarding +* erratum 2.11.
^^ here as well. 2.11 on 3630 is 2.3 on OMAP3430 etc..
Quoted 67 lines
arch/arm/mach-omap2/vc.c +8
-1*/ val = voltdm->read (OMAP3_PRM_VOLTCTRL_OFFSET );if (!(val &OMAP3430_PRM_VOLTCTRL_SEL_OFF )) {@@ -704,9 +705,16 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm)return ; } +/* +* Note that for omap3 OMAP3430_SREN_MASK clears SREN to work around +* erratum 2.11 "Extra Power Consumed When Repeated Start Operation +* Mode Is Enabled on I2C Interface Dedicated for Smart Reflex (I2C4)". +* Otherwise I2C4 eventually leads into about 23mW extran power being +* consumed even during off idle using VMODE. +*/ i2c_high_speed = voltdm->pmic->i2c_high_speed;if (i2c_high_speed) - voltdm->rmw (vc->common->i2c_cfg_hsen_mask, + voltdm->rmw (vc->common->i2c_cfg_clear_mask, vc->common->i2c_cfg_hsen_mask, vc->common->i2c_cfg_reg);arch/arm/mach-omap2/vc.h +2
-0@@ -34,6 +34,7 @@ struct voltagedomain;* @cmd_ret_shift: RET field shift in PRM_VC_CMD_VAL_* register * @cmd_off_shift: OFF field shift in PRM_VC_CMD_VAL_* register * @i2c_cfg_reg: I2C configuration register offset +* @i2c_cfg_clear_mask: high-speed mode bit clear mask in I2C config register * @i2c_cfg_hsen_mask: high-speed mode bit field mask in I2C config register * @i2c_mcode_mask: MCODE field mask for I2C config register * @@ -52,6 +53,7 @@ struct omap_vc_common {u8 cmd_ret_shift;u8 cmd_off_shift;u8 i2c_cfg_reg; +u8 i2c_cfg_clear_mask;u8 i2c_cfg_hsen_mask;u8 i2c_mcode_mask; };arch/arm/mach-omap2/vc3xxx_data.c +2
-0@@ -28,6 +28,7 @@/* * VC data common to 34xx/36xx chips * XXX This stuff presumably belongs in the vc3xxx.c or vc.c file. +* Note that we must clear SREN to work around erratum 2.11. */ static struct omap_vc_common omap3_vc_common = { .bypass_val_reg =OMAP3_PRM_VC_BYPASS_VAL_OFFSET ,@@ -40,6 +41,7 @@ static struct omap_vc_common omap3_vc_common = { .cmd_onlp_shift = OMAP3430_VC_CMD_ONLP_SHIFT, .cmd_ret_shift = OMAP3430_VC_CMD_RET_SHIFT, .cmd_off_shift = OMAP3430_VC_CMD_OFF_SHIFT, + .i2c_cfg_clear_mask = OMAP3430_SREN_MASK, .i2c_cfg_hsen_mask = OMAP3430_HSEN_MASK, .i2c_cfg_reg = OMAP3_PRM_VC_I2C_CFG_OFFSET, .i2c_mcode_mask = OMAP3430_MCODE_MASK,arch/arm/mach-omap2/vc44xx_data.c +1
-0@@ -42,6 +42,7 @@ static const struct omap_vc_common omap4_vc_common = { .cmd_ret_shift = OMAP4430_RET_SHIFT, .cmd_off_shift = OMAP4430_OFF_SHIFT, .i2c_cfg_reg = OMAP4_PRM_VC_CFG_I2C_MODE_OFFSET, + .i2c_cfg_clear_mask = 0, .i2c_cfg_hsen_mask = OMAP4430_HSMODEEN_MASK, .i2c_mcode_mask = OMAP4430_HSMCODE_MASK, };
Signature · 2 lines
Regards, Nishanth Menon
Tony Lindgren
maintainerPATCH 1/1 ARM: OMAP2+: Fix omap3 off idle power consumption creeping up
Quoted 10 lines · Nishanth Menon
Quoted 9 lines · Tony Lindgren
Quoted 7 lines · Tony Lindgren
If we use a combination of VMODE and I2C4 for retention modes, eventually the off idle power consumption will creep up by about 23mW, even during off mode with I2C4 always staying enabled.
Looks like the only way to fix the extra power consumption is to disable I2C4 usage by setting
SEL_VMODEfor both off idle and retention idle. Let's also update the comments accordingly.
Quoted 6 lines
Quoted 4 lines
Thanks Nishanth for pointing me to the related SmartReflex I2C4 erratum. No need to disable I2C4 with the SREN workaround :)
Better patch below, presumably this only affects omap3?
SREN applies to both OMAP3 and 4 - so, the patch looks right.
Oh OK, I was missing setting the clear bit for omap4. I've added it now.
Quoted 8 lines
Quoted 5 lines
If we use a combination of VMODE and I2C4 for retention modes, eventually the off idle power consumption will creep up by about 23mW, even during off mode with I2C4 always staying enabled.
Turns out this is because of erratum 2.11 "Extra Power Consumed
I suggest using the unique ID
i531 - that remains constant across SoCs.
OK thanks, updated patch below.
Regards,
Tony
8< ------------------
From: Tony Lindgren <[email protected]>
Date: Tue, 21 Apr 2015 14:31:23 -0700
Subject: [PATCH] ARM: OMAP2+: Fix omap off idle power consumption creeping up
If we use a combination of VMODE and I2C4 for retention modes, eventually the off idle power consumption will creep up by about 23mW, even during off mode with I2C4 always staying enabled.
Turns out this is because of erratum i531 "Extra Power Consumed When Repeated Start Operation Mode Is Enabled on I2C Interface Dedicated for Smart Reflex (I2C4)" as pointed out by Nishanth Menon <[email protected]>.
Let's fix the issue by adding i2c_cfg_clear_mask for the bits to clear when initializing the I2C4 adapter so we can clear SREN bit that drives the I2C4 lines low otherwise when there is no traffic.
sys_clkreq and sys_off_mode")
arch/arm/mach-omap2/prm-regbits-34xx.h +1 -0
@@ -112,6 +112,7 @@#define OMAP3430_VC_CMD_ONLP_SHIFT 16#define OMAP3430_VC_CMD_RET_SHIFT 8#define OMAP3430_VC_CMD_OFF_SHIFT 0 +#define OMAP3430_SREN_MASK (1 << 4)#define OMAP3430_HSEN_MASK (1 << 3)#define OMAP3430_MCODE_MASK (0x7 << 0)#define OMAP3430_VALID_MASK (1 << 24)
arch/arm/mach-omap2/prm-regbits-44xx.h +1 -0
@@ -35,6 +35,7 @@#define OMAP4430_GLOBAL_WARM_SW_RST_SHIFT 1#define OMAP4430_GLOBAL_WUEN_MASK (1 << 16)#define OMAP4430_HSMCODE_MASK (0x7 << 0) +#define OMAP4430_SRMODEEN_MASK (1 << 4)#define OMAP4430_HSMODEEN_MASK (1 << 3)#define OMAP4430_HSSCLL_SHIFT 24#define OMAP4430_ICEPICK_RST_SHIFT 9
arch/arm/mach-omap2/vc.c +10 -2
@@ -316,7 +316,8 @@ static void __init omap3_vc_init_pmic_signaling(struct voltagedomain *voltdm)* idle. And we can also scale voltages to zero for off-idle. * Note that no actual voltage scaling during off-idle will * happen unless the board specific twl4030 PMIC scripts are -* loaded. +* loaded. See also omap_vc_i2c_init for comments regarding +* erratum i531. */ val = voltdm->read (OMAP3_PRM_VOLTCTRL_OFFSET );if (!(val &OMAP3430_PRM_VOLTCTRL_SEL_OFF )) {
@@ -704,9 +705,16 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm)return ; } +/* +* Note that for omap3 OMAP3430_SREN_MASK clears SREN to work around +* erratum i531 "Extra Power Consumed When Repeated Start Operation +* Mode Is Enabled on I2C Interface Dedicated for Smart Reflex (I2C4)". +* Otherwise I2C4 eventually leads into about 23mW extran power being +* consumed even during off idle using VMODE. +*/ i2c_high_speed = voltdm->pmic->i2c_high_speed;if (i2c_high_speed) - voltdm->rmw (vc->common->i2c_cfg_hsen_mask, + voltdm->rmw (vc->common->i2c_cfg_clear_mask, vc->common->i2c_cfg_hsen_mask, vc->common->i2c_cfg_reg);
arch/arm/mach-omap2/vc.h +2 -0
@@ -34,6 +34,7 @@ struct voltagedomain;* @cmd_ret_shift: RET field shift in PRM_VC_CMD_VAL_* register * @cmd_off_shift: OFF field shift in PRM_VC_CMD_VAL_* register * @i2c_cfg_reg: I2C configuration register offset +* @i2c_cfg_clear_mask: high-speed mode bit clear mask in I2C config register * @i2c_cfg_hsen_mask: high-speed mode bit field mask in I2C config register * @i2c_mcode_mask: MCODE field mask for I2C config register *
@@ -52,6 +53,7 @@ struct omap_vc_common {u8 cmd_ret_shift;u8 cmd_off_shift;u8 i2c_cfg_reg; +u8 i2c_cfg_clear_mask;u8 i2c_cfg_hsen_mask;u8 i2c_mcode_mask; };
arch/arm/mach-omap2/vc3xxx_data.c +1 -0
@@ -40,6 +40,7 @@ static struct omap_vc_common omap3_vc_common = { .cmd_onlp_shift = OMAP3430_VC_CMD_ONLP_SHIFT, .cmd_ret_shift = OMAP3430_VC_CMD_RET_SHIFT, .cmd_off_shift = OMAP3430_VC_CMD_OFF_SHIFT, + .i2c_cfg_clear_mask = OMAP3430_SREN_MASK, .i2c_cfg_hsen_mask = OMAP3430_HSEN_MASK, .i2c_cfg_reg = OMAP3_PRM_VC_I2C_CFG_OFFSET, .i2c_mcode_mask = OMAP3430_MCODE_MASK,
arch/arm/mach-omap2/vc44xx_data.c +1 -0
@@ -42,6 +42,7 @@ static const struct omap_vc_common omap4_vc_common = { .cmd_ret_shift = OMAP4430_RET_SHIFT, .cmd_off_shift = OMAP4430_OFF_SHIFT, .i2c_cfg_reg = OMAP4_PRM_VC_CFG_I2C_MODE_OFFSET, + .i2c_cfg_clear_mask = OMAP4430_SRMODEEN_MASK, .i2c_cfg_hsen_mask = OMAP4430_HSMODEEN_MASK, .i2c_mcode_mask = OMAP4430_HSMCODE_MASK, };
PATCH 1/1 ARM: OMAP2+: Fix omap3 off idle power consumption creeping up
Quoted 95 lines · Tony Lindgren
Quoted 10 lines · Nishanth Menon
Quoted 9 lines · Tony Lindgren
Quoted 7 lines · Tony Lindgren
If we use a combination of VMODE and I2C4 for retention modes, eventually the off idle power consumption will creep up by about 23mW, even during off mode with I2C4 always staying enabled.
Looks like the only way to fix the extra power consumption is to disable I2C4 usage by setting
SEL_VMODEfor both off idle and retention idle. Let's also update the comments accordingly.Quoted 6 lines
Quoted 4 lines
Thanks Nishanth for pointing me to the related SmartReflex I2C4 erratum. No need to disable I2C4 with the SREN workaround :)
Better patch below, presumably this only affects omap3?
SREN applies to both OMAP3 and 4 - so, the patch looks right.
Oh OK, I was missing setting the clear bit for omap4. I've added it now.
Quoted 8 lines
Quoted 5 lines
If we use a combination of VMODE and I2C4 for retention modes, eventually the off idle power consumption will creep up by about 23mW, even during off mode with I2C4 always staying enabled.
Turns out this is because of erratum 2.11 "Extra Power Consumed
I suggest using the unique ID
i531 - that remains constant across SoCs.
OK thanks, updated patch below.
Regards,
Tony
8< ------------------
From: Tony Lindgren <[email protected]>
Date: Tue, 21 Apr 2015 14:31:23 -0700
Subject: [PATCH] ARM: OMAP2+: Fix omap off idle power consumption creeping upIf we use a combination of VMODE and I2C4 for retention modes, eventually the off idle power consumption will creep up by about 23mW, even during off mode with I2C4 always staying enabled.
Turns out this is because of erratum i531 "Extra Power Consumed When Repeated Start Operation Mode Is Enabled on I2C Interface Dedicated for Smart Reflex (I2C4)" as pointed out by Nishanth Menon <[email protected]>.
Let's fix the issue by adding
i2c_cfg_clear_maskfor the bits to clear when initializing the I2C4 adapter so we can clear SREN bit that drives the I2C4 lines low otherwise when there is no traffic.Fixes 3b8c4ebb7630 ("ARM: OMAP3: Fix idle mode signaling for
sys_clkreqandsys_off_mode")Cc Kevin Hilman <[email protected]>Cc Nishanth Menon <[email protected]>Cc Tero Kristo <[email protected]>Signed-off-by Tony Lindgren <[email protected]>arch/arm/mach-omap2/prm-regbits-34xx.h +1
-0@@ -112,6 +112,7 @@#define OMAP3430_VC_CMD_ONLP_SHIFT 16#define OMAP3430_VC_CMD_RET_SHIFT 8#define OMAP3430_VC_CMD_OFF_SHIFT 0 +#define OMAP3430_SREN_MASK (1 << 4)#define OMAP3430_HSEN_MASK (1 << 3)#define OMAP3430_MCODE_MASK (0x7 << 0)#define OMAP3430_VALID_MASK (1 << 24)arch/arm/mach-omap2/prm-regbits-44xx.h +1
-0@@ -35,6 +35,7 @@#define OMAP4430_GLOBAL_WARM_SW_RST_SHIFT 1#define OMAP4430_GLOBAL_WUEN_MASK (1 << 16)#define OMAP4430_HSMCODE_MASK (0x7 << 0) +#define OMAP4430_SRMODEEN_MASK (1 << 4)#define OMAP4430_HSMODEEN_MASK (1 << 3)#define OMAP4430_HSSCLL_SHIFT 24#define OMAP4430_ICEPICK_RST_SHIFT 9arch/arm/mach-omap2/vc.c +2
-1@@ -316,7 +316,8 @@ static void __init omap3_vc_init_pmic_signaling(struct voltagedomain *voltdm)* idle. And we can also scale voltages to zero for off-idle. * Note that no actual voltage scaling during off-idle will * happen unless the board specific twl4030 PMIC scripts are -* loaded. +* loaded. See also omap_vc_i2c_init for comments regarding +* erratum i531. */ val = voltdm->read (OMAP3_PRM_VOLTCTRL_OFFSET );if (!(val &OMAP3430_PRM_VOLTCTRL_SEL_OFF )) {
arch/arm/mach-omap2/vc.c static void __init omap_vc_i2c_init(struct voltagedomain *voltdm) · line 712
Quoted 8 lines
arch/arm/mach-omap2/vc.c +5
-0@@ -704,9 +705,16 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm)return ; } +/* +* Note that for omap3 OMAP3430_SREN_MASK clears SREN to work around +* erratum i531 "Extra Power Consumed When Repeated Start Operation +* Mode Is Enabled on I2C Interface Dedicated for Smart Reflex (I2C4)". +* Otherwise I2C4 eventually leads into about 23mW extran power being
nitpick: extran ;)
Quoted 30 lines
arch/arm/mach-omap2/vc.c +3
-1+* consumed even during off idle using VMODE. +*/ i2c_high_speed = voltdm->pmic->i2c_high_speed;if (i2c_high_speed) - voltdm->rmw (vc->common->i2c_cfg_hsen_mask, + voltdm->rmw (vc->common->i2c_cfg_clear_mask, vc->common->i2c_cfg_hsen_mask, vc->common->i2c_cfg_reg);arch/arm/mach-omap2/vc.h +2
-0@@ -34,6 +34,7 @@ struct voltagedomain;* @cmd_ret_shift: RET field shift in PRM_VC_CMD_VAL_* register * @cmd_off_shift: OFF field shift in PRM_VC_CMD_VAL_* register * @i2c_cfg_reg: I2C configuration register offset +* @i2c_cfg_clear_mask: high-speed mode bit clear mask in I2C config register * @i2c_cfg_hsen_mask: high-speed mode bit field mask in I2C config register * @i2c_mcode_mask: MCODE field mask for I2C config register * @@ -52,6 +53,7 @@ struct omap_vc_common {u8 cmd_ret_shift;u8 cmd_off_shift;u8 i2c_cfg_reg; +u8 i2c_cfg_clear_mask;u8 i2c_cfg_hsen_mask;u8 i2c_mcode_mask; };
arch/arm/mach-omap2/vc3xxx_data.c static struct omap_vc_common omap3_vc_common = { · line 43
Quoted 4 lines
arch/arm/mach-omap2/vc3xxx_data.c +1
-0@@ -40,6 +40,7 @@ static struct omap_vc_common omap3_vc_common = { .cmd_onlp_shift = OMAP3430_VC_CMD_ONLP_SHIFT, .cmd_ret_shift = OMAP3430_VC_CMD_RET_SHIFT, .cmd_off_shift = OMAP3430_VC_CMD_OFF_SHIFT, + .i2c_cfg_clear_mask = OMAP3430_SREN_MASK,
I know that the prminst rmw current code does:
v &= ~mask;
v |= bits;
and not
v &= ~mask;
v |= (bits & mask);
but to maintain legacy behavior in case the PRCM cleanup sequences change anything..
.i2c_cfg_clear_mask = OMAP3430_SREN_MASK | OMAP3430_HSEN_MASK, ? or voltdm->rmw(vc->common->i2c_cfg_clear_mask |
vc->common->i2c_cfg_hsen_mask, vc->common->i2c_cfg_hsen_mask, vc->common->i2c_cfg_reg);
no strong feelings though...
Quoted 7 lines
arch/arm/mach-omap2/vc3xxx_data.c +0
-0.i2c_cfg_hsen_mask = OMAP3430_HSEN_MASK, .i2c_cfg_reg = OMAP3_PRM_VC_I2C_CFG_OFFSET, .i2c_mcode_mask = OMAP3430_MCODE_MASK,
arch/arm/mach-omap2/vc44xx_data.c static const struct omap_vc_common omap4_vc_common = { · line 48
Quoted 7 lines
arch/arm/mach-omap2/vc44xx_data.c +1
-0@@ -42,6 +42,7 @@ static const struct omap_vc_common omap4_vc_common = { .cmd_ret_shift = OMAP4430_RET_SHIFT, .cmd_off_shift = OMAP4430_OFF_SHIFT, .i2c_cfg_reg = OMAP4_PRM_VC_CFG_I2C_MODE_OFFSET, + .i2c_cfg_clear_mask = OMAP4430_SRMODEEN_MASK, .i2c_cfg_hsen_mask = OMAP4430_HSMODEEN_MASK, .i2c_mcode_mask = OMAP4430_HSMCODE_MASK, };
otherwise, please feel to add:
Signature · 2 lines
Regards, Nishanth Menon
Tony Lindgren
maintainerPATCH 1/1 ARM: OMAP2+: Fix omap3 off idle power consumption creeping up
Quoted 8 lines · Nishanth Menon
Review
Quoted 5 lines · Tony Lindgren
(quoted diff) +5
-0+ /* + * Note that for omap3 OMAP3430_SREN_MASK clears SREN to work around + * erratum i531 "Extra Power Consumed When Repeated Start Operation + * Mode Is Enabled on I2C Interface Dedicated for Smart Reflex (I2C4)". + * Otherwise I2C4 eventually leads into about 23mW extran power beingnitpick: extran ;)
Thanks fixed.
Quoted 19 lines
Review static struct omap_vc_common omap3_vc_common = { · line 43
Quoted 5 lines
(quoted diff) +1
-0@@ -40,6 +40,7 @@ static struct omap_vc_common omap3_vc_common = { .cmd_onlp_shift = OMAP3430_VC_CMD_ONLP_SHIFT, .cmd_ret_shift = OMAP3430_VC_CMD_RET_SHIFT, .cmd_off_shift = OMAP3430_VC_CMD_OFF_SHIFT, + .i2c_cfg_clear_mask = OMAP3430_SREN_MASK,I know that the prminst rmw current code does:
v &= ~mask;
v |= bits;
and not
v &= ~mask;
v |= (bits & mask);
but to maintain legacy behavior in case the PRCM cleanup sequences change anything...i2c_cfg_clear_mask = OMAP3430_SREN_MASK | OMAP3430_HSEN_MASK, ? or voltdm->rmw(vc->common->i2c_cfg_clear_mask |
Quoted 5 lines
vc->common->i2c_cfg_hsen_mask,vc->common->i2c_cfg_hsen_mask,vc->common->i2c_cfg_reg);no strong feelings though...
OK updated to use OMAP3430_SREN_MASK | OMAP3430_HSEN_MASK.
Quoted 2 lines
otherwise, please feel to add:
Reviewed-by Nishanth Menon <[email protected]>
Thanks added updated patch below.
Regards,
Tony
8< ----------------------
From: Tony Lindgren <[email protected]>
Date: Tue, 21 Apr 2015 14:31:23 -0700
Subject: [PATCH] ARM: OMAP2+: Fix omap off idle power consumption creeping up
If we use a combination of VMODE and I2C4 for retention modes, eventually the off idle power consumption will creep up by about 23mW, even during off mode with I2C4 always staying enabled.
Turns out this is because of erratum i531 "Extra Power Consumed When Repeated Start Operation Mode Is Enabled on I2C Interface Dedicated for Smart Reflex (I2C4)" as pointed out by Nishanth Menon <[email protected]>.
Let's fix the issue by adding i2c_cfg_clear_mask for the bits to clear when initializing the I2C4 adapter so we can clear SREN bit that drives the I2C4 lines low otherwise when there is no traffic.
sys_clkreq and sys_off_mode")
arch/arm/mach-omap2/prm-regbits-34xx.h +1 -0
@@ -112,6 +112,7 @@#define OMAP3430_VC_CMD_ONLP_SHIFT 16#define OMAP3430_VC_CMD_RET_SHIFT 8#define OMAP3430_VC_CMD_OFF_SHIFT 0 +#define OMAP3430_SREN_MASK (1 << 4)#define OMAP3430_HSEN_MASK (1 << 3)#define OMAP3430_MCODE_MASK (0x7 << 0)#define OMAP3430_VALID_MASK (1 << 24)
arch/arm/mach-omap2/prm-regbits-44xx.h +1 -0
@@ -35,6 +35,7 @@#define OMAP4430_GLOBAL_WARM_SW_RST_SHIFT 1#define OMAP4430_GLOBAL_WUEN_MASK (1 << 16)#define OMAP4430_HSMCODE_MASK (0x7 << 0) +#define OMAP4430_SRMODEEN_MASK (1 << 4)#define OMAP4430_HSMODEEN_MASK (1 << 3)#define OMAP4430_HSSCLL_SHIFT 24#define OMAP4430_ICEPICK_RST_SHIFT 9
arch/arm/mach-omap2/vc.c +10 -2
@@ -316,7 +316,8 @@ static void __init omap3_vc_init_pmic_signaling(struct voltagedomain *voltdm)* idle. And we can also scale voltages to zero for off-idle. * Note that no actual voltage scaling during off-idle will * happen unless the board specific twl4030 PMIC scripts are -* loaded. +* loaded. See also omap_vc_i2c_init for comments regarding +* erratum i531. */ val = voltdm->read (OMAP3_PRM_VOLTCTRL_OFFSET );if (!(val &OMAP3430_PRM_VOLTCTRL_SEL_OFF )) {
@@ -704,9 +705,16 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm)return ; } +/* +* Note that for omap3 OMAP3430_SREN_MASK clears SREN to work around +* erratum i531 "Extra Power Consumed When Repeated Start Operation +* Mode Is Enabled on I2C Interface Dedicated for Smart Reflex (I2C4)". +* Otherwise I2C4 eventually leads into about 23mW extra power being +* consumed even during off idle using VMODE. +*/ i2c_high_speed = voltdm->pmic->i2c_high_speed;if (i2c_high_speed) - voltdm->rmw (vc->common->i2c_cfg_hsen_mask, + voltdm->rmw (vc->common->i2c_cfg_clear_mask, vc->common->i2c_cfg_hsen_mask, vc->common->i2c_cfg_reg);
arch/arm/mach-omap2/vc.h +2 -0
@@ -34,6 +34,7 @@ struct voltagedomain;* @cmd_ret_shift: RET field shift in PRM_VC_CMD_VAL_* register * @cmd_off_shift: OFF field shift in PRM_VC_CMD_VAL_* register * @i2c_cfg_reg: I2C configuration register offset +* @i2c_cfg_clear_mask: high-speed mode bit clear mask in I2C config register * @i2c_cfg_hsen_mask: high-speed mode bit field mask in I2C config register * @i2c_mcode_mask: MCODE field mask for I2C config register *
@@ -52,6 +53,7 @@ struct omap_vc_common {u8 cmd_ret_shift;u8 cmd_off_shift;u8 i2c_cfg_reg; +u8 i2c_cfg_clear_mask;u8 i2c_cfg_hsen_mask;u8 i2c_mcode_mask; };
arch/arm/mach-omap2/vc3xxx_data.c +1 -0
@@ -40,6 +40,7 @@ static struct omap_vc_common omap3_vc_common = { .cmd_onlp_shift = OMAP3430_VC_CMD_ONLP_SHIFT, .cmd_ret_shift = OMAP3430_VC_CMD_RET_SHIFT, .cmd_off_shift = OMAP3430_VC_CMD_OFF_SHIFT, + .i2c_cfg_clear_mask = OMAP3430_SREN_MASK | OMAP3430_HSEN_MASK, .i2c_cfg_hsen_mask = OMAP3430_HSEN_MASK, .i2c_cfg_reg = OMAP3_PRM_VC_I2C_CFG_OFFSET, .i2c_mcode_mask = OMAP3430_MCODE_MASK,
arch/arm/mach-omap2/vc44xx_data.c +1 -0
@@ -42,6 +42,7 @@ static const struct omap_vc_common omap4_vc_common = { .cmd_ret_shift = OMAP4430_RET_SHIFT, .cmd_off_shift = OMAP4430_OFF_SHIFT, .i2c_cfg_reg = OMAP4_PRM_VC_CFG_I2C_MODE_OFFSET, + .i2c_cfg_clear_mask = OMAP4430_SRMODEEN_MASK | OMAP4430_HSMODEEN_MASK, .i2c_cfg_hsen_mask = OMAP4430_HSMODEEN_MASK, .i2c_mcode_mask = OMAP4430_HSMCODE_MASK, };