Fixes for omap PM for making omap3 DT only
Subsystems (9)
Tony Lindgren
maintainercover Fixes for omap PM for making omap3 DT only
Hi all,
As we're planning to make omap3 device tree only soon, I was poking around and noticed that PM is not working properly. As we're planning to drop about 20k lines of code, I just had to try to fix this so we know what is going on and don't have to go back. I was pretty bummed out to find that we've had non-working PM code in mainline for really long time.
Anyways, I got the voltage scaling and N900 debug leds working, so with those we can notice any future regressions immediately :)
These are against v3.14, then you might want to also apply the following two patches:
[PATCH] of/platform: Fix no irq domain found errors when populating interrupts
https://lkml.org/lkml/2014/4/10/620
[PATCH] serial: omap: Fix missing pm_runtime_resume handling by simplifying code
http://www.spinics.net/lists/linux-omap/msg104782.html
Note that for the actual voltage scaling to happen, the twl4030 PMIC scripts are also needed. I have some uncleaned patches to load those based on the compatible flag, will post those separately. This series alone fixes the idle state signaling to the PMIC, so we can monitor sys_clkreq and sys_off_idle pins properly.
Please review, comment and test,
Tony
Tero Kristo (1):
ARM: OMAP3: PM: remove access to PRM_VOLTCTRL register
Tony Lindgren (10):
ARM: OMAP3: Fix idle mode signaling for sys_clkreq and sys_off_mode
ARM: OMAP3: Disable broken omap3_set_off_timings function
ARM: OMAP3: Fix voltage control for deeper idle states
ARM: dts: Configure omap3 twl4030 I2C4 pins by default
ARM: OMAP2+: Fix voltage scaling init for device tree
ARM: dts: Enable N900 keybaord sleep leds by default
ARM: dts: Fix omap serial wake-up when booted with device tree
ARM: OMAP2+: Enable CPUidle in omap2plus_defconfig
mfd: twl-core: Fix idle mode signaling for omaps when booted with
device tree
pinctrl: single: Clear pin interrupts enabled by bootloader
arch/arm/boot/dts/omap3-evm-37xx.dts | 9 ++ arch/arm/boot/dts/omap3-n900.dts | 19 +++ arch/arm/boot/dts/omap3.dtsi | 6 +- arch/arm/boot/dts/omap4-panda-common.dtsi | 15 +++ arch/arm/boot/dts/omap4-sdp.dts | 6 + arch/arm/boot/dts/omap4.dtsi | 6 +- arch/arm/boot/dts/twl4030_omap3.dtsi | 19 ++- arch/arm/configs/omap2plus_defconfig | 7 + arch/arm/mach-omap2/omap_twl.c | 60 --------- arch/arm/mach-omap2/pm.c | 28 ++-- arch/arm/mach-omap2/pm34xx.c | 6 +- arch/arm/mach-omap2/prm-regbits-34xx.h | 11 +- arch/arm/mach-omap2/vc.c | 212 +++++++++++++++++++----------- arch/arm/mach-omap2/vc.h | 2 + drivers/mfd/twl-core.c | 15 +++ drivers/pinctrl/pinctrl-single.c | 13 ++ include/dt-bindings/pinctrl/omap.h | 12 ++ 17 files changed, 281 insertions(+), 165 deletions(-)
Signature · 1 line
1.8.1.1
Tony Lindgren
maintainerPATCH 1/11 ARM: OMAP3: PM: remove access to PRM_VOLTCTRL register
From: Tero Kristo <[email protected]>
There is a solitary write to this register every wakeup from off-mode, which isn't doing anything, so remove it.
Also note that modifying this register trashes any attempted voltage scaling configuration and the change probably should never have gotten merged in the first place.
--- arch/arm/mach-omap2/pm34xx.c | 4 ---- 1 file changed, 4 deletions(-)
arch/arm/mach-omap2/pm34xx.c +0 -4
@@ -330,10 +330,6 @@ void omap_sram_idle(void)omap3_sram_restore_context ();omap2_sms_restore_context (); } -if (core_next_state ==PWRDM_POWER_OFF ) -omap2_prm_clear_mod_reg_bits (OMAP3430_AUTO_OFF_MASK , -OMAP3430_GR_MOD , -OMAP3_PRM_VOLTCTRL_OFFSET ); }omap3_intc_resume_idle ();
Signature · 1 line
1.8.1.1
Tony Lindgren
maintainerPATCH 2/11 ARM: OMAP3: Fix idle mode signaling for sys_clkreq and sys_off_mode
In reply to Tony LindgrenWhile debugging legacy mode vs device tree booted PM regressions, I noticed that omap3 is not toggling sys_clkreq and sys_off_mode pins like it should.
The sys_clkreq and sys_off_mode pins are not toggling because of the following issues:
1. The default polarity for the sys_off_mode pin is wrong. OFFMODE_POL needs to be cleared for sys_off_mode to go down when hitting off-idle, while CLKREQ_POL needs to be set so sys_clkreq goes down when hitting retention.
2. The values for voltctrl register need to be updated dynamically. We need to set either the retention idle bits, or off idle bits in the voltctrl register depending the idle mode we're targeting to hit.
Let's fix these two issues as otherwise the system will just hang if any twl4030 PMIC idle scripts are loaded. The only case where the system does not hang is if only retention idle over I2C4 is configured by the bootloader.
Note that even without the twl4030 PMIC scripts, these fixes will do the proper signaling of sys_clkreq and sys_off_mode pins, so the fixes are needed to fix monitoring of PM states with LEDs or an oscilloscope.
--- arch/arm/mach-omap2/pm34xx.c | 2 + arch/arm/mach-omap2/prm-regbits-34xx.h | 11 ++++- arch/arm/mach-omap2/vc.c | 75 +++++++++++++++++++++++++++++++++- arch/arm/mach-omap2/vc.h | 2 + 4 files changed, 87 insertions(+), 3 deletions(-)
arch/arm/mach-omap2/pm34xx.c +2 -0
@@ -50,6 +50,7 @@#include "sdrc.h" #include "sram.h" #include "control.h" +#include "vc.h" /* pm34xx errata defined in pm.h */ u16 pm34xx_errata;
@@ -282,6 +283,7 @@ void omap_sram_idle(void)/* CORE */ if (core_next_state <PWRDM_POWER_ON ) { +omap3_vc_set_pmic_signaling (core_next_state);if (core_next_state ==PWRDM_POWER_OFF ) {omap3_core_save_context ();omap3_cm_save_context ();
arch/arm/mach-omap2/prm-regbits-34xx.h +9 -2
@@ -123,8 +123,15 @@#define OMAP3430_GLOBAL_SW_RST_SHIFT 1#define OMAP3430_GLOBAL_COLD_RST_SHIFT 0#define OMAP3430_GLOBAL_COLD_RST_MASK (1 << 0) -#define OMAP3430_SEL_OFF_MASK (1 << 3) -#define OMAP3430_AUTO_OFF_MASK (1 << 2) +#define OMAP3430_PRM_VOLTCTRL_SEL_VMODE (1 << 4) +#define OMAP3430_PRM_VOLTCTRL_SEL_OFF (1 << 3) +#define OMAP3430_PRM_VOLTCTRL_AUTO_OFF (1 << 2) +#define OMAP3430_PRM_VOLTCTRL_AUTO_RET (1 << 1) +#define OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP (1 << 0)#define OMAP3430_SETUP_TIME2_MASK (0xffff << 16)#define OMAP3430_SETUP_TIME1_MASK (0xffff << 0) +#define OMAP3430_PRM_POLCTRL_OFFMODE_POL (1 << 3) +#define OMAP3430_PRM_POLCTRL_CLKOUT_POL (1 << 2) +#define OMAP3430_PRM_POLCTRL_CLKREQ_POL (1 << 1) +#define OMAP3430_PRM_POLCTRL_EXTVOL_POL (1 << 0)#endif
arch/arm/mach-omap2/vc.c +74 -1
93 lines not on this page · raw message
arch/arm/mach-omap2/vc.h +2 -0
@@ -117,6 +117,8 @@ extern struct omap_vc_param omap4_mpu_vc_data;extern struct omap_vc_param omap4_iva_vc_data;extern struct omap_vc_param omap4_core_vc_data; +void omap3_vc_set_pmic_signaling (int core_next_state); +void omap_vc_init_channel (struct voltagedomain *voltdm); int omap_vc_pre_scale(struct voltagedomain *voltdm, unsigned long target_volt,
Signature · 1 line
1.8.1.1
PATCH 2/11 ARM: OMAP3: Fix idle mode signaling for sys_clkreq and sys_off_mode
On 04/11/2014 02:47 AM, Tony Lindgren wrote:> While debugging legacy mode vs device tree booted PM regressions,
Quoted 31 lines
I noticed that omap3 is not toggling
sys_clkreqandsys_off_modepins like it should.The
sys_clkreqandsys_off_modepins are not toggling because of the following issues:1. The default polarity for the
sys_off_modepin is wrong.OFFMODE_POLneeds to be cleared forsys_off_modeto go down when hitting off-idle, whileCLKREQ_POLneeds to be set sosys_clkreqgoes down when hitting retention.2. The values for voltctrl register need to be updated dynamically. We need to set either the retention idle bits, or off idle bits in the voltctrl register depending the idle mode we're targeting to hit.
Let's fix these two issues as otherwise the system will just hang if any twl4030 PMIC idle scripts are loaded. The only case where the system does not hang is if only retention idle over I2C4 is configured by the bootloader.
Note that even without the twl4030 PMIC scripts, these fixes will do the proper signaling of
sys_clkreqandsys_off_modepins, so the fixes are needed to fix monitoring of PM states with LEDs or an oscilloscope.Cc Kevin Hilman <[email protected]>Cc Nishanth Menon <[email protected]>Cc Paul Walmsley <[email protected]>Cc Tero Kristo <[email protected]>Signed-off-by Tony Lindgren <[email protected]>
Quoted 4 lines
--- arch/arm/mach-omap2/pm34xx.c | 2 + arch/arm/mach-omap2/prm-regbits-34xx.h | 11 ++++- arch/arm/mach-omap2/vc.c | 75
+++++++++++++++++++++++++++++++++-
Quoted 16 lines
arch/arm/mach-omap2/vc.h | 2 + 4 files changed, 87 insertions(+), 3 deletions(-)arch/arm/mach-omap2/pm34xx.c +1
-0@@ -50,6 +50,7 @@#include "sdrc.h" #include "sram.h" #include "control.h" +#include "vc.h" /* pm34xx errata defined in pm.h */ u16 pm34xx_errata;
arch/arm/mach-omap2/pm34xx.c void omap_sram_idle(void) · line 289
Quoted 7 lines
arch/arm/mach-omap2/pm34xx.c +1
-0@@ -282,6 +283,7 @@ void omap_sram_idle(void)/* CORE */ if (core_next_state <PWRDM_POWER_ON ) { +omap3_vc_set_pmic_signaling (core_next_state);if (core_next_state ==PWRDM_POWER_OFF ) {omap3_core_save_context ();omap3_cm_save_context ();
I think this implementation is sub-optimal, as it only scales voltages if core is entering idle state. MPU only idle is possible, however you do not scale voltages in this case.
Review
Quoted 1 line
(quoted diff) +0
-0
b/arch/arm/mach-omap2/prm-regbits-34xx.h
Quoted 26 lines
index cebad56..106132d 100644
arch/arm/mach-omap2/prm-regbits-34xx.h +9
-2@@ -123,8 +123,15 @@#define OMAP3430_GLOBAL_SW_RST_SHIFT 1#define OMAP3430_GLOBAL_COLD_RST_SHIFT 0#define OMAP3430_GLOBAL_COLD_RST_MASK (1 << 0) -#define OMAP3430_SEL_OFF_MASK (1 << 3) -#define OMAP3430_AUTO_OFF_MASK (1 << 2) +#define OMAP3430_PRM_VOLTCTRL_SEL_VMODE (1 << 4) +#define OMAP3430_PRM_VOLTCTRL_SEL_OFF (1 << 3) +#define OMAP3430_PRM_VOLTCTRL_AUTO_OFF (1 << 2) +#define OMAP3430_PRM_VOLTCTRL_AUTO_RET (1 << 1) +#define OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP (1 << 0)#define OMAP3430_SETUP_TIME2_MASK (0xffff << 16)#define OMAP3430_SETUP_TIME1_MASK (0xffff << 0) +#define OMAP3430_PRM_POLCTRL_OFFMODE_POL (1 << 3) +#define OMAP3430_PRM_POLCTRL_CLKOUT_POL (1 << 2) +#define OMAP3430_PRM_POLCTRL_CLKREQ_POL (1 << 1) +#define OMAP3430_PRM_POLCTRL_EXTVOL_POL (1 << 0)#endif arch/arm/mach-omap2/vc.c +0
-0
arch/arm/mach-omap2/vc.c static inline u32 omap_usec_to_32k(u32 usec) · line 228
Quoted 9 lines
arch/arm/mach-omap2/vc.c +6
-0@@ -220,6 +220,78 @@ static inline u32 omap_usec_to_32k(u32 usec)return DIV_ROUND_UP_ULL (32768ULL * (u64 )usec,1000000ULL ); } +void omap3_vc_set_pmic_signaling (int core_next_state) +{ +u32 voltctrl; + + voltctrl =omap2_prm_read_mod_reg (OMAP3430_GR_MOD , +OMAP3_PRM_VOLTCTRL_OFFSET );
Just a note here, I am currently working on trying to get rid of all the direct prm_read/write calls outside PRCM drivers, this and rest should use voltdm->read/write.
Quoted 31 lines
arch/arm/mach-omap2/vc.c +31
-0+switch (core_next_state) { +case PWRDM_POWER_OFF : + voltctrl &= ~(OMAP3430_PRM_VOLTCTRL_AUTO_RET | +OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP ); + voltctrl |=OMAP3430_PRM_VOLTCTRL_AUTO_OFF ; +break ; +case PWRDM_POWER_RET : + voltctrl &= ~(OMAP3430_PRM_VOLTCTRL_AUTO_OFF | +OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP ); + voltctrl |=OMAP3430_PRM_VOLTCTRL_AUTO_RET ; +break ; +default : + voltctrl &= ~(OMAP3430_PRM_VOLTCTRL_AUTO_OFF | +OMAP3430_PRM_VOLTCTRL_AUTO_RET ); + voltctrl |=OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP ; +break ; + } +omap2_prm_write_mod_reg (voltctrl,OMAP3430_GR_MOD , +OMAP3_PRM_VOLTCTRL_OFFSET ); +} + +/* +* Configure signal polarity for sys_clkreq and sys_off_mode pins +* as the default values are wrong and can cause the system to hang +* if any twl4030 sccripts are loaded. +*/ +static void __init omap3_vc_init_pmic_signaling (void ) +{ +u32 val, old; + + val = omap2_prm_read_mod_reg(OMAP3430_GR_MOD,
arch/arm/mach-omap2/vc.c static inline u32 omap_usec_to_32k(u32 usec)
Quoted 10 lines
arch/arm/mach-omap2/vc.c +10
-0+ OMAP3_PRM_POLCTRL_OFFSET); + old = val; + +if (old &OMAP3430_PRM_POLCTRL_CLKREQ_POL ) + val |=OMAP3430_PRM_POLCTRL_CLKREQ_POL ; +if (old &OMAP3430_PRM_POLCTRL_OFFMODE_POL ) + val &= ~OMAP3430_PRM_POLCTRL_OFFMODE_POL ; + +if (val != old) { + pr_debug("PM: fixing sys_clkreq and sys_off_mode polarity 0x%x ->
0x%x\n",
Quoted 6 lines
arch/arm/mach-omap2/vc.c +6
-0+ old, val); + } +omap2_prm_write_mod_reg (val,OMAP3430_GR_MOD , +OMAP3_PRM_POLCTRL_OFFSET ); + +/*
arch/arm/mach-omap2/vc.c static inline u32 omap_usec_to_32k(u32 usec) · line 285
Quoted 10 lines
arch/arm/mach-omap2/vc.c +10
-0+* 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 will happen unless the +* board specific twl4030 PMIC scripts are loaded. +*/ + val =omap2_prm_read_mod_reg (OMAP3430_GR_MOD , +OMAP3_PRM_VOLTCTRL_OFFSET );
Why not use the I2C4 signalling for off-mode? This way the voltages can be scaled to 0.6V even without any board specific scripts.
-Tero
arch/arm/mach-omap2/vc.c static void omap3_set_off_timings(struct
Quoted 13 lines
arch/arm/mach-omap2/vc.c +9
-0+ old = val; + val |=OMAP3430_PRM_VOLTCTRL_SEL_OFF ; +pr_debug ("PM: enabling voltctrl sys_off_mode signaling 0x%x -> 0x%x\n" , + old, val); +omap2_prm_write_mod_reg (val,OMAP3430_GR_MOD , +OMAP3_PRM_VOLTCTRL_OFFSET ); +omap3_vc_set_pmic_signaling (PWRDM_POWER_ON ); +} +/* Set oscillator setup time for omap3 */ static void omap3_set_clksetup (u32 usec,struct voltagedomain *voltdm) {@@ -292,7 +364,7 @@ static void omap3_set_off_timings(struct
voltagedomain *voltdm)
arch/arm/mach-omap2/vc.c static void omap3_set_off_timings(struct
Quoted 9 lines
arch/arm/mach-omap2/vc.c +1
-1/* check if sys_off_mode is used to control off-mode voltages */ val = voltdm->read (OMAP3_PRM_VOLTCTRL_OFFSET ); -if (!(val &OMAP3430_SEL_OFF_MASK )) { +if (!(val &OMAP3430_PRM_VOLTCTRL_SEL_OFF )) {/* No, omap is controlling them over I2C */ omap3_set_i2c_timings (voltdm, true);return ;@@ -337,6 +409,7 @@ static void omap3_set_off_timings(struct
voltagedomain *voltdm)
Quoted 21 lines
arch/arm/mach-omap2/vc.c +1
-0static void __init omap3_vc_init_channel (struct voltagedomain *voltdm) { +omap3_vc_init_pmic_signaling ();omap3_set_off_timings (voltdm); }arch/arm/mach-omap2/vc.h +2
-0@@ -117,6 +117,8 @@ extern struct omap_vc_param omap4_mpu_vc_data;extern struct omap_vc_param omap4_iva_vc_data;extern struct omap_vc_param omap4_core_vc_data; +void omap3_vc_set_pmic_signaling (int core_next_state); +void omap_vc_init_channel (struct voltagedomain *voltdm); int omap_vc_pre_scale(struct voltagedomain *voltdm, unsigned long target_volt,
Tony Lindgren
maintainerPATCH 2/11 ARM: OMAP3: Fix idle mode signaling for sys_clkreq and sys_off_mode
Quoted 13 lines · Tero Kristo
On 04/11/2014 02:47 AM, Tony Lindgren wrote:>
arch/arm/mach-omap2/pm34xx.c void omap_sram_idle(void) · line 289
Quoted 8 lines
arch/arm/mach-omap2/pm34xx.c +1
-0@@ -282,6 +283,7 @@ void omap_sram_idle(void)/* CORE */ if (core_next_state <PWRDM_POWER_ON ) { +omap3_vc_set_pmic_signaling (core_next_state);if (core_next_state ==PWRDM_POWER_OFF ) {omap3_core_save_context ();omap3_cm_save_context ();I think this implementation is sub-optimal, as it only scales voltages if core is entering idle state. MPU only idle is possible, however you do not scale voltages in this case.
Hmm that's same as PWRDM_POWER_RET? That's working too. Or do you have something else in mind that I'm not aware of?
Quoted 4 lines
Quoted 4 lines
arch/arm/mach-omap2/vc.c +0
-0@@ -220,6 +220,78 @@ static inline u32 omap_usec_to_32k(u32 usec)return DIV_ROUND_UP_ULL (32768ULL * (u64 )usec,1000000ULL ); }
Quoted 10 lines
arch/arm/mach-omap2/vc.c static inline u32 omap_usec_to_32k(u32 usec) · line 228
Quoted 6 lines
arch/arm/mach-omap2/vc.c +6
-0+void omap3_vc_set_pmic_signaling (int core_next_state) +{ +u32 voltctrl; + + voltctrl =omap2_prm_read_mod_reg (OMAP3430_GR_MOD , +OMAP3_PRM_VOLTCTRL_OFFSET );Just a note here, I am currently working on trying to get rid of all the direct prm_read/write calls outside PRCM drivers, this and rest should use voltdm->read/write.
OK, sounds like you already have a patch for that in your 3.14-rc4-cm-prm-driver-wip branch?
Let's do the fixes first, then it's going to be a lot easier for us to test the rest of the PRMC changes.
Quoted 6 lines
Quoted 6 lines
arch/arm/mach-omap2/vc.c +6
-0+/* +* 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.
Quoted 8 lines
arch/arm/mach-omap2/vc.c static inline u32 omap_usec_to_32k(u32 usec) · line 285
Quoted 5 lines
arch/arm/mach-omap2/vc.c +5
-0+* Note that no actual voltage scaling will happen unless the +* board specific twl4030 PMIC scripts are loaded. +*/ + val =omap2_prm_read_mod_reg (OMAP3430_GR_MOD , +OMAP3_PRM_VOLTCTRL_OFFSET );Why not use the I2C4 signalling for off-mode? This way the voltages can be scaled to 0.6V even without any board specific scripts.
Using I2C4 works too, we're just missing a place to set and clear OMAP3430_PRM_VOLTCTRL_SEL_OFF bit currently. Sounds like eventually we should allow changing it dynamically somewhere.
But for now, SEL_OFF should be enabled as it allows debugging PM by looking at the sys_clkreq and sys_off_mode pins no matter if there are board specific scripts or not. The sys_off_mode won't toggle if things are configured to use I2C4, which is confusing.
Regards,
Tony
PATCH 2/11 ARM: OMAP3: Fix idle mode signaling for sys_clkreq and sys_off_mode
Quoted 15 lines · Tony Lindgren
Quoted 13 lines · Tero Kristo
On 04/11/2014 02:47 AM, Tony Lindgren wrote:>
arch/arm/mach-omap2/pm34xx.c void omap_sram_idle(void) · line 289
Quoted 8 lines
arch/arm/mach-omap2/pm34xx.c +1
-0@@ -282,6 +283,7 @@ void omap_sram_idle(void)/* CORE */ if (core_next_state <PWRDM_POWER_ON ) { +omap3_vc_set_pmic_signaling (core_next_state);if (core_next_state ==PWRDM_POWER_OFF ) {omap3_core_save_context ();omap3_cm_save_context ();I think this implementation is sub-optimal, as it only scales voltages if core is entering idle state. MPU only idle is possible, however you do not scale voltages in this case.
Quoted 3 lines
Hmm that's same as
PWRDM_POWER_RET? That's working too. Or do you have something else in mind that I'm not aware of?
No, I mean the case where core_next_state == PWRDM_POWER_ON, but mpu_next_state <= PWRDM_POWER_RET. You could scale MPU voltage in this case but you don't with this implementation.
Quoted 16 lines
Quoted 5 lines
Quoted 5 lines
arch/arm/mach-omap2/vc.c +0
-0@@ -220,6 +220,78 @@ static inline u32 omap_usec_to_32k(u32 usec)return DIV_ROUND_UP_ULL (32768ULL * (u64 )usec,1000000ULL ); }Quoted 10 lines
arch/arm/mach-omap2/vc.c static inline u32 omap_usec_to_32k(u32 usec) · line 228
Quoted 6 lines
arch/arm/mach-omap2/vc.c +6
-0+void omap3_vc_set_pmic_signaling (int core_next_state) +{ +u32 voltctrl; + + voltctrl =omap2_prm_read_mod_reg (OMAP3430_GR_MOD , +OMAP3_PRM_VOLTCTRL_OFFSET );Just a note here, I am currently working on trying to get rid of all the direct prm_read/write calls outside PRCM drivers, this and rest should use voltdm->read/write.
Quoted 2 lines
OK, sounds like you already have a patch for that in your 3.14-rc4-cm-prm-driver-wip branch?
Yes, there is a patch for that.
Quoted 19 lines
Let's do the fixes first, then it's going to be a lot easier for us to test the rest of the PRMC changes.
Quoted 6 lines
Quoted 6 lines
arch/arm/mach-omap2/vc.c +6
-0+/* +* 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. Quoted 8 lines
arch/arm/mach-omap2/vc.c static inline u32 omap_usec_to_32k(u32 usec) · line 285
Quoted 5 lines
arch/arm/mach-omap2/vc.c +5
-0+* Note that no actual voltage scaling will happen unless the +* board specific twl4030 PMIC scripts are loaded. +*/ + val =omap2_prm_read_mod_reg (OMAP3430_GR_MOD , +OMAP3_PRM_VOLTCTRL_OFFSET );Why not use the I2C4 signalling for off-mode? This way the voltages can be scaled to 0.6V even without any board specific scripts.
Quoted 3 lines
Using I2C4 works too, we're just missing a place to set and clear
OMAP3430_PRM_VOLTCTRL_SEL_OFFbit currently. Sounds like eventually we should allow changing it dynamically somewhere.
You can't check the presence of the scripts here?
Quoted 4 lines
But for now,
SEL_OFFshould be enabled as it allows debugging PM by looking at thesys_clkreqandsys_off_modepins no matter if there are board specific scripts or not. Thesys_off_modewon't toggle if things are configured to use I2C4, which is confusing.
You can always measure the voltage rails directly also, but yea, it is more convenient to just look at the led.
-Tero
Tony Lindgren
maintainerPATCH 2/11 ARM: OMAP3: Fix idle mode signaling for sys_clkreq and sys_off_mode
Quoted 16 lines · Tero Kristo
Quoted 15 lines · Tony Lindgren
Quoted 13 lines · Tero Kristo
On 04/11/2014 02:47 AM, Tony Lindgren wrote:>
arch/arm/mach-omap2/pm34xx.c void omap_sram_idle(void) · line 289
Quoted 8 lines
arch/arm/mach-omap2/pm34xx.c +1
-0@@ -282,6 +283,7 @@ void omap_sram_idle(void)/* CORE */ if (core_next_state <PWRDM_POWER_ON ) { +omap3_vc_set_pmic_signaling (core_next_state);if (core_next_state ==PWRDM_POWER_OFF ) {omap3_core_save_context ();omap3_cm_save_context ();I think this implementation is sub-optimal, as it only scales voltages if core is entering idle state. MPU only idle is possible, however you do not scale voltages in this case.
Quoted 7 lines
Quoted 3 lines
Hmm that's same as
PWRDM_POWER_RET? That's working too. Or do you have something else in mind that I'm not aware of?No, I mean the case where
core_next_state==PWRDM_POWER_ON, butmpu_next_state<=PWRDM_POWER_RET. You could scale MPU voltage in this case but you don't with this implementation.
OK makes sense to pass both mpu_next_state and core_next_state to the function then.
Quoted 15 lines
Quoted 15 lines
Quoted 14 lines
arch/arm/mach-omap2/vc.c static inline u32 omap_usec_to_32k(u32 usec) · line 228
Quoted 10 lines
arch/arm/mach-omap2/vc.c +6
-0@@ -220,6 +220,78 @@ static inline u32 omap_usec_to_32k(u32 usec)return DIV_ROUND_UP_ULL (32768ULL * (u64 )usec,1000000ULL ); } +void omap3_vc_set_pmic_signaling (int core_next_state) +{ +u32 voltctrl; + + voltctrl =omap2_prm_read_mod_reg (OMAP3430_GR_MOD , +OMAP3_PRM_VOLTCTRL_OFFSET );Just a note here, I am currently working on trying to get rid of all the direct prm_read/write calls outside PRCM drivers, this and rest should use voltdm->read/write.
Quoted 4 lines
Quoted 2 lines
OK, sounds like you already have a patch for that in your 3.14-rc4-cm-prm-driver-wip branch?
Yes, there is a patch for that.
OK I'll pick it from there.
Quoted 18 lines
Quoted 18 lines
Let's do the fixes first, then it's going to be a lot easier for us to test the rest of the PRMC changes.
Quoted 14 lines
arch/arm/mach-omap2/vc.c static inline u32 omap_usec_to_32k(u32 usec) · line 285
Quoted 11 lines
arch/arm/mach-omap2/vc.c +11
-0+/* +* 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 will happen unless the +* board specific twl4030 PMIC scripts are loaded. +*/ + val =omap2_prm_read_mod_reg (OMAP3430_GR_MOD , +OMAP3_PRM_VOLTCTRL_OFFSET );Why not use the I2C4 signalling for off-mode? This way the voltages can be scaled to 0.6V even without any board specific scripts.
Quoted 5 lines
Quoted 3 lines
Using I2C4 works too, we're just missing a place to set and clear
OMAP3430_PRM_VOLTCTRL_SEL_OFFbit currently. Sounds like eventually we should allow changing it dynamically somewhere.You can't check the presence of the scripts here?
I guess we could eventually add something for that :)
Quoted 7 lines
Quoted 4 lines
But for now,
SEL_OFFshould be enabled as it allows debugging PM by looking at thesys_clkreqandsys_off_modepins no matter if there are board specific scripts or not. Thesys_off_modewon't toggle if things are configured to use I2C4, which is confusing.You can always measure the voltage rails directly also, but yea, it is more convenient to just look at the led.
And works for making sure we don't get new PM kernel regressions even if twl4030 is not working properly :)
Regards,
Tony
Tony Lindgren
maintainerPATCH 2/11 ARM: OMAP3: Fix idle mode signaling for sys_clkreq and sys_off_mode
Quoted 21 lines · Tony Lindgren
Quoted 20 lines · Tero Kristo
Quoted 18 lines · Tony Lindgren
Quoted 13 lines · Tero Kristo
On 04/11/2014 02:47 AM, Tony Lindgren wrote:>
Review void omap_sram_idle(void) · line 289
Quoted 8 lines
(quoted diff) +1
-0@@ -282,6 +283,7 @@ void omap_sram_idle(void) /* CORE */ if (core_next_state < PWRDM_POWER_ON) { + omap3_vc_set_pmic_signaling(core_next_state); if (core_next_state == PWRDM_POWER_OFF) { omap3_core_save_context(); omap3_cm_save_context();I think this implementation is sub-optimal, as it only scales voltages if core is entering idle state. MPU only idle is possible, however you do not scale voltages in this case.
Hmm that's same as
PWRDM_POWER_RET? That's working too. Or do you have something else in mind that I'm not aware of?
Quoted 6 lines
Quoted 3 lines
No, I mean the case where
core_next_state==PWRDM_POWER_ON, butmpu_next_state<=PWRDM_POWER_RET. You could scale MPU voltage in this case but you don't with this implementation.OK makes sense to pass both
mpu_next_stateandcore_next_stateto the function then.
I've changed things around to implement the register caching Grazvydas suggested, and calling omap3_vc_set_pmic_signaling() always omap_sram_idle(). The default signaling is to use I2C4 control except for core-off that uses the sys_off_mode, so there should not be any blockers for core-on + mpu-off.
And after playing with enable_off_mode I'm seeing at least all cpuidle states being hit.
# cat /sys/devices/system/cpu/cpu0/cpuidle/state*/usage 603 7378 7087 342 17 1 45
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines
OK, sounds like you already have a patch for that in your 3.14-rc4-cm-prm-driver-wip branch?
Yes, there is a patch for that.
OK I'll pick it from there.
I ended up doing the read/write in a slightly different way as we can pass the pwrdm to the init function.
Regards,
Tony
8< --------------------
From: Tony Lindgren <[email protected]>
Date: Mon, 5 May 2014 17:27:35 -0700
Subject: [PATCH] ARM: OMAP3: Fix idle mode signaling for sys_clkreq and sys_off_mode
While debugging legacy mode vs device tree booted PM regressions, I noticed that omap3 is not toggling sys_clkreq and sys_off_mode pins like it should.
The sys_clkreq and sys_off_mode pins are not toggling because of the following issues:
1. The default polarity for the sys_off_mode pin is wrong. OFFMODE_POL needs to be cleared for sys_off_mode to go down when hitting off-idle, while CLKREQ_POL needs to be set so sys_clkreq goes down when hitting retention.
2. The values for voltctrl register need to be updated dynamically. We need to set either the retention idle bits, or off idle bits in the voltctrl register depending the idle mode we're targeting to hit.
Let's fix these two issues as otherwise the system will just hang if any twl4030 PMIC idle scripts are loaded. The only case where the system does not hang is if only retention idle over I2C4 is configured by the bootloader.
Note that even without the twl4030 PMIC scripts, these fixes will do the proper signaling of sys_clkreq and sys_off_mode pins, so the fixes are needed to fix monitoring of PM states with LEDs or an oscilloscope.
arch/arm/mach-omap2/pm34xx.c +4 -0
@@ -50,6 +50,7 @@#include "sdrc.h" #include "sram.h" #include "control.h" +#include "vc.h" /* pm34xx errata defined in pm.h */ u16 pm34xx_errata;
@@ -288,6 +289,9 @@ void omap_sram_idle(void) } } +/* Configure PMIC signaling for I2C4 or sys_off_mode */ +omap3_vc_set_pmic_signaling (core_next_state); +omap3_intc_prepare_idle ();/*
arch/arm/mach-omap2/prm-regbits-34xx.h +9 -2
@@ -123,8 +123,15 @@#define OMAP3430_GLOBAL_SW_RST_SHIFT 1#define OMAP3430_GLOBAL_COLD_RST_SHIFT 0#define OMAP3430_GLOBAL_COLD_RST_MASK (1 << 0) -#define OMAP3430_SEL_OFF_MASK (1 << 3) -#define OMAP3430_AUTO_OFF_MASK (1 << 2) +#define OMAP3430_PRM_VOLTCTRL_SEL_VMODE (1 << 4) +#define OMAP3430_PRM_VOLTCTRL_SEL_OFF (1 << 3) +#define OMAP3430_PRM_VOLTCTRL_AUTO_OFF (1 << 2) +#define OMAP3430_PRM_VOLTCTRL_AUTO_RET (1 << 1) +#define OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP (1 << 0)#define OMAP3430_SETUP_TIME2_MASK (0xffff << 16)#define OMAP3430_SETUP_TIME1_MASK (0xffff << 0) +#define OMAP3430_PRM_POLCTRL_OFFMODE_POL (1 << 3) +#define OMAP3430_PRM_POLCTRL_CLKOUT_POL (1 << 2) +#define OMAP3430_PRM_POLCTRL_CLKREQ_POL (1 << 1) +#define OMAP3430_PRM_POLCTRL_EXTVOL_POL (1 << 0)#endif
arch/arm/mach-omap2/vc.c +83 -1
102 lines not on this page · raw message
arch/arm/mach-omap2/vc.h +3 -0
@@ -117,6 +117,9 @@ extern struct omap_vc_param omap4_mpu_vc_data;extern struct omap_vc_param omap4_iva_vc_data;extern struct omap_vc_param omap4_core_vc_data; +void omap3_vc_set_pmic_signaling (int core_next_state); + +void omap_vc_init_channel (struct voltagedomain *voltdm); int omap_vc_pre_scale(struct voltagedomain *voltdm, unsigned long target_volt,
PATCH 2/11 ARM: OMAP3: Fix idle mode signaling for sys_clkreq and sys_off_mode
In reply to Tony LindgrenQuoted 52 lines · Tony Lindgren
While debugging legacy mode vs device tree booted PM regressions, I noticed that omap3 is not toggling
sys_clkreqandsys_off_modepins like it should.The
sys_clkreqandsys_off_modepins are not toggling because of the following issues:1. The default polarity for the
sys_off_modepin is wrong.OFFMODE_POLneeds to be cleared forsys_off_modeto go down when hitting off-idle, whileCLKREQ_POLneeds to be set sosys_clkreqgoes down when hitting retention.2. The values for voltctrl register need to be updated dynamically. We need to set either the retention idle bits, or off idle bits in the voltctrl register depending the idle mode we're targeting to hit.
Let's fix these two issues as otherwise the system will just hang if any twl4030 PMIC idle scripts are loaded. The only case where the system does not hang is if only retention idle over I2C4 is configured by the bootloader.
Note that even without the twl4030 PMIC scripts, these fixes will do the proper signaling of
sys_clkreqandsys_off_modepins, so the fixes are needed to fix monitoring of PM states with LEDs or an oscilloscope.Cc Kevin Hilman <[email protected]>Cc Nishanth Menon <[email protected]>Cc Paul Walmsley <[email protected]>Cc Tero Kristo <[email protected]>Signed-off-by Tony Lindgren <[email protected]>--- arch/arm/mach-omap2/pm34xx.c | 2 + arch/arm/mach-omap2/prm-regbits-34xx.h | 11 ++++- arch/arm/mach-omap2/vc.c | 75 +++++++++++++++++++++++++++++++++- arch/arm/mach-omap2/vc.h | 2 + 4 files changed, 87 insertions(+), 3 deletions(-)arch/arm/mach-omap2/pm34xx.c +1
-0@@ -50,6 +50,7 @@#include "sdrc.h" #include "sram.h" #include "control.h" +#include "vc.h" /* pm34xx errata defined in pm.h */ u16 pm34xx_errata;
arch/arm/mach-omap2/pm34xx.c void omap_sram_idle(void) · line 286
Quoted 4 lines
arch/arm/mach-omap2/pm34xx.c +1
-0@@ -282,6 +283,7 @@ void omap_sram_idle(void)/* CORE */ if (core_next_state <PWRDM_POWER_ON ) { +omap3_vc_set_pmic_signaling (core_next_state);
I wonder how is it going to affect latencies, adding stuff to suspend path hurts things like NAND transfers, which consist of lots of small blocks with an interrupt after each..
Quoted 48 lines
arch/arm/mach-omap2/pm34xx.c +0
-0if (core_next_state ==PWRDM_POWER_OFF ) {omap3_core_save_context ();omap3_cm_save_context ();arch/arm/mach-omap2/prm-regbits-34xx.h +9
-2@@ -123,8 +123,15 @@#define OMAP3430_GLOBAL_SW_RST_SHIFT 1#define OMAP3430_GLOBAL_COLD_RST_SHIFT 0#define OMAP3430_GLOBAL_COLD_RST_MASK (1 << 0) -#define OMAP3430_SEL_OFF_MASK (1 << 3) -#define OMAP3430_AUTO_OFF_MASK (1 << 2) +#define OMAP3430_PRM_VOLTCTRL_SEL_VMODE (1 << 4) +#define OMAP3430_PRM_VOLTCTRL_SEL_OFF (1 << 3) +#define OMAP3430_PRM_VOLTCTRL_AUTO_OFF (1 << 2) +#define OMAP3430_PRM_VOLTCTRL_AUTO_RET (1 << 1) +#define OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP (1 << 0)#define OMAP3430_SETUP_TIME2_MASK (0xffff << 16)#define OMAP3430_SETUP_TIME1_MASK (0xffff << 0) +#define OMAP3430_PRM_POLCTRL_OFFMODE_POL (1 << 3) +#define OMAP3430_PRM_POLCTRL_CLKOUT_POL (1 << 2) +#define OMAP3430_PRM_POLCTRL_CLKREQ_POL (1 << 1) +#define OMAP3430_PRM_POLCTRL_EXTVOL_POL (1 << 0)#endif arch/arm/mach-omap2/vc.c +15
-0@@ -220,6 +220,78 @@ static inline u32 omap_usec_to_32k(u32 usec)return DIV_ROUND_UP_ULL (32768ULL * (u64 )usec,1000000ULL ); } +void omap3_vc_set_pmic_signaling (int core_next_state) +{ +u32 voltctrl; + + voltctrl =omap2_prm_read_mod_reg (OMAP3430_GR_MOD , +OMAP3_PRM_VOLTCTRL_OFFSET ); +switch (core_next_state) { +case PWRDM_POWER_OFF : + voltctrl &= ~(OMAP3430_PRM_VOLTCTRL_AUTO_RET | +OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP ); + voltctrl |=OMAP3430_PRM_VOLTCTRL_AUTO_OFF ; +break ; +case PWRDM_POWER_RET : + voltctrl &= ~(OMAP3430_PRM_VOLTCTRL_AUTO_OFF | +OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP );
arch/arm/mach-omap2/vc.c static inline u32 omap_usec_to_32k(u32 usec) · line 247
Quoted 10 lines
arch/arm/mach-omap2/vc.c +10
-0+ voltctrl |=OMAP3430_PRM_VOLTCTRL_AUTO_RET ; +break ; +default : + voltctrl &= ~(OMAP3430_PRM_VOLTCTRL_AUTO_OFF | +OMAP3430_PRM_VOLTCTRL_AUTO_RET ); + voltctrl |=OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP ; +break ; + } +omap2_prm_write_mod_reg (voltctrl,OMAP3430_GR_MOD , +OMAP3_PRM_VOLTCTRL_OFFSET );
Could it only write if the value changed? Caching register value would be great too to avoid slow register accesses.
arch/arm/mach-omap2/vc.c static inline u32 omap_usec_to_32k(u32 usec) · line 253
Quoted 6 lines
arch/arm/mach-omap2/vc.c +6
-0+} + +/* +* Configure signal polarity for sys_clkreq and sys_off_mode pins +* as the default values are wrong and can cause the system to hang +* if any twl4030 sccripts are loaded.
s/sccripts/scripts
arch/arm/mach-omap2/vc.c static inline u32 omap_usec_to_32k(u32 usec) · line 264
Quoted 11 lines
arch/arm/mach-omap2/vc.c +11
-0+*/ +static void __init omap3_vc_init_pmic_signaling (void ) +{ +u32 val, old; + + val =omap2_prm_read_mod_reg (OMAP3430_GR_MOD , +OMAP3_PRM_POLCTRL_OFFSET ); + old = val; + +if (old &OMAP3430_PRM_POLCTRL_CLKREQ_POL ) + val |=OMAP3430_PRM_POLCTRL_CLKREQ_POL ;
Are these 2 lines actually doing anything?
arch/arm/mach-omap2/vc.c static inline u32 omap_usec_to_32k(u32 usec) · line 266
Quoted 2 lines
arch/arm/mach-omap2/vc.c +2
-0+if (old &OMAP3430_PRM_POLCTRL_OFFMODE_POL ) + val &= ~OMAP3430_PRM_POLCTRL_OFFMODE_POL ;
Why not just clear the bit unconditionally?
arch/arm/mach-omap2/vc.c static inline u32 omap_usec_to_32k(u32 usec) · line 273
Quoted 7 lines
arch/arm/mach-omap2/vc.c +7
-0+ +if (val != old) { +pr_debug ("PM: fixing sys_clkreq and sys_off_mode polarity 0x%x -> 0x%x\n" , + old, val); + } +omap2_prm_write_mod_reg (val,OMAP3430_GR_MOD , +OMAP3_PRM_POLCTRL_OFFSET );
Maybe move this write inside the block just above it?
Signature · 1 line
Gra?vydas
Tony Lindgren
maintainerPATCH 2/11 ARM: OMAP3: Fix idle mode signaling for sys_clkreq and sys_off_mode
Quoted 10 lines · Grazvydas Ignotas
arch/arm/mach-omap2/pm34xx.c void omap_sram_idle(void) · line 286
Quoted 5 lines · Tony Lindgren
arch/arm/mach-omap2/pm34xx.c +1
-0@@ -282,6 +283,7 @@ void omap_sram_idle(void)/* CORE */ if (core_next_state <PWRDM_POWER_ON ) { +omap3_vc_set_pmic_signaling (core_next_state);I wonder how is it going to affect latencies, adding stuff to suspend path hurts things like NAND transfers, which consist of lots of small blocks with an interrupt after each..
For most part this is the completely idle path, so there should not be much of hurry. Most devices should already block the deeper idle states for the devices listed in cm_idlest_per, cm_idlest1_core and cm_idlest3_core registers. So it should be mostly automatic with runtime PM.
No idea what happens with GPMC though for NAND transfers :) Might be worth checking.
Quoted 20 lines
Quoted 20 lines
arch/arm/mach-omap2/vc.c +20
-0+void omap3_vc_set_pmic_signaling (int core_next_state) +{ +u32 voltctrl; + + voltctrl =omap2_prm_read_mod_reg (OMAP3430_GR_MOD , +OMAP3_PRM_VOLTCTRL_OFFSET ); +switch (core_next_state) { +case PWRDM_POWER_OFF : + voltctrl &= ~(OMAP3430_PRM_VOLTCTRL_AUTO_RET | +OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP ); + voltctrl |=OMAP3430_PRM_VOLTCTRL_AUTO_OFF ; +break ; +case PWRDM_POWER_RET : + voltctrl &= ~(OMAP3430_PRM_VOLTCTRL_AUTO_OFF | +OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP ); + voltctrl |=OMAP3430_PRM_VOLTCTRL_AUTO_RET ; +break ; +default : + voltctrl &= ~(OMAP3430_PRM_VOLTCTRL_AUTO_OFF | +OMAP3430_PRM_VOLTCTRL_AUTO_RET );
Quoted 8 lines
arch/arm/mach-omap2/vc.c static inline u32 omap_usec_to_32k(u32 usec) · line 247
Quoted 5 lines
arch/arm/mach-omap2/vc.c +5
-0+ voltctrl |=OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP ; +break ; + } +omap2_prm_write_mod_reg (voltctrl,OMAP3430_GR_MOD , +OMAP3_PRM_VOLTCTRL_OFFSET );Could it only write if the value changed? Caching register value would be great too to avoid slow register accesses.
Yeah sure makes sense, I'll take a look at that. We should not need to check for voltctrl constantly.
Quoted 8 lines
arch/arm/mach-omap2/vc.c static inline u32 omap_usec_to_32k(u32 usec) · line 253
Quoted 6 lines
arch/arm/mach-omap2/vc.c +6
-0+} + +/* +* Configure signal polarity for sys_clkreq and sys_off_mode pins +* as the default values are wrong and can cause the system to hang +* if any twl4030 sccripts are loaded. s/sccripts/scripts
Will fix.
Quoted 5 lines
Quoted 5 lines
+ */
arch/arm/mach-omap2/vc.c +4
-0+static void __init omap3_vc_init_pmic_signaling (void ) +{ +u32 val, old; +
Quoted 8 lines
arch/arm/mach-omap2/vc.c static inline u32 omap_usec_to_32k(u32 usec) · line 264
Quoted 6 lines
arch/arm/mach-omap2/vc.c +6
-0+ val =omap2_prm_read_mod_reg (OMAP3430_GR_MOD , +OMAP3_PRM_POLCTRL_OFFSET ); + old = val; + +if (old &OMAP3430_PRM_POLCTRL_CLKREQ_POL ) + val |=OMAP3430_PRM_POLCTRL_CLKREQ_POL ;Are these 2 lines actually doing anything?
Nope :) It should be if (!(old & OMAP3430_PRM_POLCTRL_CLKREQ_POL))...
Quoted 4 lines
arch/arm/mach-omap2/vc.c static inline u32 omap_usec_to_32k(u32 usec) · line 266
Quoted 2 lines
arch/arm/mach-omap2/vc.c +2
-0+if (old &OMAP3430_PRM_POLCTRL_OFFMODE_POL ) + val &= ~OMAP3430_PRM_POLCTRL_OFFMODE_POL ;Why not just clear the bit unconditionally?
Mostly for producing some kind of debug message of what's going on in case somebody has a PMIC with different polarity. If we agree that's not needed, then that's not needed.
Quoted 8 lines
arch/arm/mach-omap2/vc.c static inline u32 omap_usec_to_32k(u32 usec) · line 273
Quoted 6 lines
arch/arm/mach-omap2/vc.c +6
-0+if (val != old) { +pr_debug ("PM: fixing sys_clkreq and sys_off_mode polarity 0x%x -> 0x%x\n" , + old, val); + } +omap2_prm_write_mod_reg (val,OMAP3430_GR_MOD , +OMAP3_PRM_POLCTRL_OFFSET );Maybe move this write inside the block just above it?
Makes sense.
Tony
PATCH 2/11 ARM: OMAP3: Fix idle mode signaling for sys_clkreq and sys_off_mode
Quoted 12 lines · Tony Lindgren
Quoted 10 lines · Grazvydas Ignotas
arch/arm/mach-omap2/pm34xx.c void omap_sram_idle(void) · line 286
Quoted 5 lines · Tony Lindgren
arch/arm/mach-omap2/pm34xx.c +1
-0@@ -282,6 +283,7 @@ void omap_sram_idle(void)/* CORE */ if (core_next_state <PWRDM_POWER_ON ) { +omap3_vc_set_pmic_signaling (core_next_state);I wonder how is it going to affect latencies, adding stuff to suspend path hurts things like NAND transfers, which consist of lots of small blocks with an interrupt after each..
Quoted 8 lines
For most part this is the completely idle path, so there should not be much of hurry. Most devices should already block the deeper idle states for the devices listed in
cm_idlest_per,cm_idlest1_coreandcm_idlest3_coreregisters. So it should be mostly automatic with runtime PM.No idea what happens with GPMC though for NAND transfers :) Might be worth checking.
What happens there is that the interrupt arrives shortly after the transfer was issued, but arm_pm_idle() would already be entered and interrupts disabled, so it then has to go through all those slow register accesses in omap_sram_idle(), which is just useless work in such particular case (WFI will just return) and cause interrupt response latency and loss of throughput. But this is mostly a problem caused by pwrdm_pre_transition() and pwrdm_post_transition() calls (they were optimized a bit at one point but later reverted), core_next_state would probably stay ON and your function wouldn't be called here, yes.
Signature · 1 line
Gra?vydas
Tony Lindgren
maintainerPATCH 2/11 ARM: OMAP3: Fix idle mode signaling for sys_clkreq and sys_off_mode
Quoted 22 lines · Grazvydas Ignotas
Quoted 12 lines · Tony Lindgren
Quoted 10 lines · Grazvydas Ignotas
arch/arm/mach-omap2/pm34xx.c void omap_sram_idle(void) · line 286
Quoted 5 lines · Tony Lindgren
arch/arm/mach-omap2/pm34xx.c +1
-0@@ -282,6 +283,7 @@ void omap_sram_idle(void)/* CORE */ if (core_next_state <PWRDM_POWER_ON ) { +omap3_vc_set_pmic_signaling (core_next_state);I wonder how is it going to affect latencies, adding stuff to suspend path hurts things like NAND transfers, which consist of lots of small blocks with an interrupt after each..
Quoted 8 lines
For most part this is the completely idle path, so there should not be much of hurry. Most devices should already block the deeper idle states for the devices listed in
cm_idlest_per,cm_idlest1_coreandcm_idlest3_coreregisters. So it should be mostly automatic with runtime PM.No idea what happens with GPMC though for NAND transfers :) Might be worth checking.
Quoted 10 lines
What happens there is that the interrupt arrives shortly after the transfer was issued, but
arm_pm_idle()would already be entered and interrupts disabled, so it then has to go through all those slow register accesses inomap_sram_idle(), which is just useless work in such particular case (WFI will just return) and cause interrupt response latency and loss of throughput. But this is mostly a problem caused bypwrdm_pre_transition()andpwrdm_post_transition()calls (they were optimized a bit at one point but later reverted),core_next_statewould probably stay ON and your function wouldn't be called here, yes.
OK. There may be a way to block idle state transitions with runtime PM or CPUidle in general to avoid that.
Ideally the NAND driver would use DMA for transferring the data from the memory mapped buffer with cyclic DMA triggered by the external DMA request pins sys_ndmareq[0..5] if they are wired. Then the DMA would keep system from hitting any deeper idle states automatically. But that might quite a project to debug and implement :)
And I don't know if cyclic DMA is supported for NAND, there may be various things to check between transferring each block. But in theory at least onenNAND should be able to use the cyclic DMA transfers.
Regards,
Tony
Tony Lindgren
maintainerPATCH 3/11 ARM: OMAP3: Disable broken omap3_set_off_timings function
In reply to Tony LindgrenCommit c589eb3869a8 (ARM: OMAP3: VC: calculate ramp times) started using regulator slew rates for calculating the idle mode start-up times. This works fine for I2C4 controlled regulator scaling as the regulators are never completely turned off.
For sys_off_mode pin controlled PMIC scripts, the slew rate based calculations won't work at all as the regulators are completely turned off and the start-up time is much longer.
This means currently omap3_set_off_timings currently has zero chance of working on any real hardare. The current code is broken in at least the following ways:
1. It attempts to use the default ULONG_MAX value for the oscillator start-up value as we're currently never initializing the start-up value.
2. It relies on a magic number potentially set by the bootloader for volsetup2 register.
3. If no magic value is passed, it attempts to calculate voltsetup2 register based on the regulator slew rate. This won't work as there is roughly at least five times the delay needed for turning on vdd1 and vdd2 regulators.
4. It does duplicate register write to OMAP3_PRM_VOLTOFFSET
5. It duplicates the code for omap_usec_to_32k unnecessarily
6. It initialized global registers twice, once for each channel
Let's just remove the broken code and call omap3_set_i2c_timings directly, we're better off with this function doing nothing until it's fixed. And otherwise further fixes to omap3_set_off_timings will be unreadable.
And let's get rid of omap3_set_clksetup as that's not needed for off-idle controlled by I2C4 as in that case the oscillator is never shut down.
--- arch/arm/mach-omap2/vc.c | 62 +----------------------------------------------- 1 file changed, 1 insertion(+), 61 deletions(-)
arch/arm/mach-omap2/vc.c +1 -61
@@ -292,12 +292,6 @@ static void __init omap3_vc_init_pmic_signaling(void)omap3_vc_set_pmic_signaling (PWRDM_POWER_ON ); } -/* Set oscillator setup time for omap3 */ -static void omap3_set_clksetup (u32 usec,struct voltagedomain *voltdm) -{ - voltdm->write (omap_usec_to_32k (usec),OMAP3_PRM_CLKSETUP_OFFSET ); -} -/** * omap3_set_i2c_timings - sets i2c sleep timings for a channel * @voltdm: channel to configure
@@ -314,12 +308,6 @@ static void omap3_set_i2c_timings(struct voltagedomain *voltdm, bool off_mode)unsigned long voltsetup1;u32 tgt_volt; -/* -* Oscillator is shut down only if we are using sys_off_mode pad, -* thus we set a minimal setup time here -*/ -omap3_set_clksetup (1 , voltdm); -if (off_mode) tgt_volt = voltdm->vc_param->off;else
@@ -356,61 +344,13 @@ static void omap3_set_i2c_timings(struct voltagedomain *voltdm, bool off_mode)*/ static void omap3_set_off_timings (struct voltagedomain *voltdm) { -unsigned long clksetup; -unsigned long voltsetup2; -unsigned long voltsetup2_old; -u32 val; -u32 tstart, tshut; - -/* check if sys_off_mode is used to control off-mode voltages */ - val = voltdm->read (OMAP3_PRM_VOLTCTRL_OFFSET ); -if (!(val &OMAP3430_PRM_VOLTCTRL_SEL_OFF )) { -/* No, omap is controlling them over I2C */ -omap3_set_i2c_timings (voltdm, true); -return ; - } - -omap_pm_get_oscillator (&tstart, &tshut); -omap3_set_clksetup (tstart, voltdm); - - clksetup = voltdm->read (OMAP3_PRM_CLKSETUP_OFFSET ); - -/* voltsetup 2 in us */ - voltsetup2 = voltdm->vc_param->on / voltdm->pmic->slew_rate; - -/* convert to 32k clk cycles */ - voltsetup2 =DIV_ROUND_UP (voltsetup2 *32768 ,1000000 ); - - voltsetup2_old = voltdm->read (OMAP3_PRM_VOLTSETUP2_OFFSET ); - -/* -* Update voltsetup2 if higher than current value (needed because -* we have multiple channels with different ramp times), also -* update voltoffset always to value recommended by TRM -*/ -if (voltsetup2 > voltsetup2_old) { - voltdm->write (voltsetup2,OMAP3_PRM_VOLTSETUP2_OFFSET ); - voltdm->write (clksetup - voltsetup2, -OMAP3_PRM_VOLTOFFSET_OFFSET ); - }else - voltdm->write (clksetup - voltsetup2_old, -OMAP3_PRM_VOLTOFFSET_OFFSET ); - -/* -* omap is not controlling voltage scaling during off-mode, -* thus set voltsetup1 to 0 -*/ - voltdm->rmw (voltdm->vfsm->voltsetup_mask,0 , - voltdm->vfsm->voltsetup_reg); - -/* voltoffset must be clksetup minus voltsetup2 according to TRM */ - voltdm->write (clksetup - voltsetup2,OMAP3_PRM_VOLTOFFSET_OFFSET ); }static void __init omap3_vc_init_channel (struct voltagedomain *voltdm) {omap3_vc_init_pmic_signaling ();omap3_set_off_timings (voltdm); +omap3_set_i2c_timings (voltdm, true); }/**
Signature · 1 line
1.8.1.1
Tony Lindgren
maintainerPATCH 4/11 ARM: OMAP3: Fix voltage control for deeper idle states
In reply to Tony LindgrenCurrently we're attempting to use a static value for the voltctrl register that only works for controlling the PMIC over I2C4. For using sys_off_mode signaling, we need to update update clksetup, voltsetup1, voltsetup2 and voltctrl registers dynamically depending on the idle state.
So let's fix this by configuring things for I2C4 controlled idle and sys_off_mode pin controlled idle, and then write the configured register values depending on the idle state. This is similar what N900 kernel is doing too.
--- arch/arm/mach-omap2/vc.c | 99 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 73 insertions(+), 26 deletions(-)
arch/arm/mach-omap2/vc.c +73 -26
@@ -220,8 +220,18 @@ static inline u32 omap_usec_to_32k(u32 usec)return DIV_ROUND_UP_ULL (32768ULL * (u64 )usec,1000000ULL ); } +struct omap3_vc_config { +u32 clksetup; +u32 voltsetup1; +u32 voltsetup2; +u32 voltctrl; +}; + +static struct omap3_vc_config omap3_vc_timings[2 ]; +void omap3_vc_set_pmic_signaling (int core_next_state) { +struct omap3_vc_config *c = omap3_vc_timings;u32 voltctrl; voltctrl = omap2_prm_read_mod_reg(OMAP3430_GR_MOD,
@@ -231,11 +241,20 @@ void omap3_vc_set_pmic_signaling(int core_next_state) voltctrl &= ~(OMAP3430_PRM_VOLTCTRL_AUTO_RET |OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP ); voltctrl |=OMAP3430_PRM_VOLTCTRL_AUTO_OFF ; +if (voltctrl &OMAP3430_PRM_VOLTCTRL_SEL_OFF ) +omap2_prm_write_mod_reg (c->voltsetup2,OMAP3430_GR_MOD , +OMAP3_PRM_VOLTSETUP2_OFFSET ); +else +omap2_prm_write_mod_reg (c->voltsetup1,OMAP3430_GR_MOD , +OMAP3_PRM_VOLTSETUP1_OFFSET );break ;case PWRDM_POWER_RET : + c++; voltctrl &= ~(OMAP3430_PRM_VOLTCTRL_AUTO_OFF |OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP ); voltctrl |=OMAP3430_PRM_VOLTCTRL_AUTO_RET ; +omap2_prm_write_mod_reg (c->voltsetup1,OMAP3430_GR_MOD , +OMAP3_PRM_VOLTSETUP1_OFFSET );break ;default : voltctrl &= ~(OMAP3430_PRM_VOLTCTRL_AUTO_OFF |
@@ -292,6 +311,18 @@ static void __init omap3_vc_init_pmic_signaling(void)omap3_vc_set_pmic_signaling (PWRDM_POWER_ON ); } +static void omap3_init_voltsetup1 (struct voltagedomain *voltdm, +struct omap3_vc_config *c,u32 idle) +{ +unsigned long val; + + val = (voltdm->vc_param->on - idle) / voltdm->pmic->slew_rate; + val *= voltdm->sys_clk.rate /8 /1000000 +1 ; + val <<=__ffs (voltdm->vfsm->voltsetup_mask); + c->voltsetup1 &= ~voltdm->vfsm->voltsetup_mask; + c->voltsetup1 |= val; +} +/** * omap3_set_i2c_timings - sets i2c sleep timings for a channel * @voltdm: channel to configure
@@ -302,31 +333,21 @@ static void __init omap3_vc_init_pmic_signaling(void)* or retention. Off mode has additionally an option to use sys_off_mode * pad, which uses a global signal to program the whole power IC to * off-mode. +* +* Note that pmic is not controlling the voltage scaling during +* retention signaled over I2C4, so we can keep voltsetup2 as 0. +* And the oscillator is not shut off over I2C4, so no need to +* set clksetup. */ -static void omap3_set_i2c_timings (struct voltagedomain *voltdm,bool off_mode) +static void omap3_set_i2c_timings (struct voltagedomain *voltdm) { -unsigned long voltsetup1; -u32 tgt_volt; - -if (off_mode) - tgt_volt = voltdm->vc_param->off; -else - tgt_volt = voltdm->vc_param->ret; - - voltsetup1 = (voltdm->vc_param->on - tgt_volt) / - voltdm->pmic->slew_rate; - - voltsetup1 = voltsetup1 * voltdm->sys_clk.rate /8 /1000000 +1 ; +struct omap3_vc_config *c = omap3_vc_timings; - voltdm->rmw (voltdm->vfsm->voltsetup_mask, - voltsetup1 <<__ffs (voltdm->vfsm->voltsetup_mask), - voltdm->vfsm->voltsetup_reg); - -/* -* pmic is not controlling the voltage scaling during retention, -* thus set voltsetup2 to 0 -*/ - voltdm->write (0 ,OMAP3_PRM_VOLTSETUP2_OFFSET ); +/* Configure PRWDM_POWER_OFF over I2C4 */ +omap3_init_voltsetup1 (voltdm, c, voltdm->vc_param->off); + c++; +/* Configure PRWDM_POWER_RET over I2C4 */ +omap3_init_voltsetup1 (voltdm, c, voltdm->vc_param->ret); }/**
@@ -335,22 +356,48 @@ static void omap3_set_i2c_timings(struct voltagedomain *voltdm, bool off_mode)* * Calculates and sets up off-mode timings for a channel. Off-mode * can use either I2C based voltage scaling, or alternatively -* sys_off_mode pad can be used to send a global command to power IC. -* This function first checks which mode is being used, and calls -* omap3_set_i2c_timings() if the system is using I2C control mode. +* sys_off_mode pad can be used to send a global command to power IC.n, * sys_off_mode has the additional benefit that voltages can be * scaled to zero volt level with TWL4030 / TWL5030, I2C can only * scale to 600mV. +* +* Note that omap is not controlling the voltage scaling during +* off idle signaled by sys_off_mode, so we can keep voltsetup1 +* as 0. */ static void omap3_set_off_timings (struct voltagedomain *voltdm) { +struct omap3_vc_config *c = omap3_vc_timings; +u32 tstart, tshut, voltoffset; + +if (c->clksetup) +return ; + +omap_pm_get_oscillator (&tstart, &tshut); +if (tstart ==ULONG_MAX ) { +pr_debug ("PM: oscillator start-up time not initialized, using 10ms\n" ); + c->clksetup =omap_usec_to_32k (10000 ); + }else { + c->clksetup =omap_usec_to_32k (tstart); + } + +/* +* For twl4030 errata 27, we need to allow minimum ~488.32 us wait to +* switch from HFCLKIN to internal oscillator. That means timings +* have voltoffset fixed to 0xa in rounded up 32 KiHz cycles. And +* that means we can calculate the value based on the oscillator +* start-up time since voltoffset2 = clksetup - voltoffset. +*/ + voltoffset =omap_usec_to_32k (488 ); + c->voltsetup2 = c->clksetup - voltoffset; + voltdm->write (voltoffset,OMAP3_PRM_VOLTOFFSET_OFFSET ); }static void __init omap3_vc_init_channel (struct voltagedomain *voltdm) {omap3_vc_init_pmic_signaling ();omap3_set_off_timings (voltdm); -omap3_set_i2c_timings (voltdm, true); +omap3_set_i2c_timings (voltdm); }/**
Signature · 1 line
1.8.1.1
Tony Lindgren
maintainerPATCH 4/11 ARM: OMAP3: Fix voltage control for deeper idle states
Review static inline u32 omap_usec_to_32k(u32 usec) · line 228
Quoted 10 lines · Tony Lindgren
(quoted diff) +6
-0@@ -220,8 +220,18 @@ static inline u32 omap_usec_to_32k(u32 usec) return DIV_ROUND_UP_ULL(32768ULL * (u64)usec, 1000000ULL); } +struct omap3_vc_config { + u32 clksetup; + u32 voltsetup1; + u32 voltsetup2; + u32 voltctrl; +};
It seems we can keep just voltsetup1 and voltsetup2 here. The others need to be initialized just once it seems.
Quoted 16 lines
(quoted diff) +14
-0static void omap3_set_off_timings(struct voltagedomain *voltdm) { + struct omap3_vc_config *c = omap3_vc_timings; + u32 tstart, tshut, voltoffset; + + if (c->clksetup) + return; + + omap_pm_get_oscillator(&tstart, &tshut); + if (tstart == ULONG_MAX) { + pr_debug("PM: oscillator start-up time not initialized, using 10ms\n"); + c->clksetup = omap_usec_to_32k(10000); + } else { + c->clksetup = omap_usec_to_32k(tstart); + } +
Review static inline u32 omap_usec_to_32k(u32 usec)
Quoted 10 lines
(quoted diff) +10
-0+ /* + * For twl4030 errata 27, we need to allow minimum ~488.32 us wait to + * switch from HFCLKIN to internal oscillator. That means timings + * have voltoffset fixed to 0xa in rounded up 32 KiHz cycles. And + * that means we can calculate the value based on the oscillator + * start-up time since voltoffset2 = clksetup - voltoffset. + */ + voltoffset = omap_usec_to_32k(488); + c->voltsetup2 = c->clksetup - voltoffset; + voltdm->write(voltoffset, OMAP3_PRM_VOLTOFFSET_OFFSET);
And here we're missing a write to clksetup, without that the off idle timings are not correct.. Below is an incremental diff on top of this patch.
Regards,
Tony
8< -------------------------------
arch/arm/mach-omap2/vc.c +6 -7
@@ -221,10 +221,8 @@ static inline u32 omap_usec_to_32k(u32 usec) }struct omap3_vc_config { -u32 clksetup;u32 voltsetup1;u32 voltsetup2; -u32 voltctrl; };static struct omap3_vc_config omap3_vc_timings[2 ];
@@ -368,17 +366,17 @@ static void omap3_set_i2c_timings(struct voltagedomain *voltdm)static void omap3_set_off_timings (struct voltagedomain *voltdm) {struct omap3_vc_config *c = omap3_vc_timings; -u32 tstart, tshut, voltoffset; +u32 tstart, tshut, clksetup, voltoffset; -if (c->clksetup) +if (c->voltsetup2)return ;omap_pm_get_oscillator (&tstart, &tshut);if (tstart ==ULONG_MAX ) {pr_debug ("PM: oscillator start-up time not initialized, using 10ms\n" ); - c->clksetup =omap_usec_to_32k (10000 ); + clksetup =omap_usec_to_32k (10000 ); }else { - c->clksetup =omap_usec_to_32k (tstart); + clksetup =omap_usec_to_32k (tstart); }/*
@@ -389,7 +387,8 @@ static void omap3_set_off_timings(struct voltagedomain *voltdm)* start-up time since voltoffset2 = clksetup - voltoffset. */ voltoffset =omap_usec_to_32k (488 ); - c->voltsetup2 = c->clksetup - voltoffset; + c->voltsetup2 = clksetup - voltoffset; + voltdm->write (clksetup,OMAP3_PRM_CLKSETUP_OFFSET ); voltdm->write (voltoffset,OMAP3_PRM_VOLTOFFSET_OFFSET ); }
Tony Lindgren
maintainerPATCH 4/11 ARM: OMAP3: Fix voltage control for deeper idle states
Quoted 4 lines · Tony Lindgren
* Tony Lindgren <[email protected]> [140410 16:52]:
And here we're missing a write to clksetup, without that the off idle timings are not correct.. Below is an incremental diff on top of this patch.
Here's this one updated to the changes made in patch 2 of this series.
Regards,
Tony
8< --------------------
From: Tony Lindgren <[email protected]>
Date: Mon, 5 May 2014 17:27:36 -0700
Subject: [PATCH] ARM: OMAP3: Fix voltage control for deeper idle states
Currently we're attempting to use a static value for the voltctrl register that only works for controlling the PMIC over I2C4. For using sys_off_mode signaling, we need to update update clksetup, voltsetup1, voltsetup2 and voltctrl registers dynamically depending on the idle state.
So let's fix this by configuring things for I2C4 controlled idle and sys_off_mode pin controlled idle, and then write the configured register values depending on the idle state. This is similar what N900 kernel is doing too.
arch/arm/mach-omap2/vc.c +85 -27
@@ -220,35 +220,64 @@ static inline u32 omap_usec_to_32k(u32 usec)return DIV_ROUND_UP_ULL (32768ULL * (u64 )usec,1000000ULL ); } +struct omap3_vc_timings { +u32 voltsetup1; +u32 voltsetup2; +}; +struct omap3_vc {struct voltagedomain *vd;u32 voltctrl; +u32 voltsetup1; +u32 voltsetup2; +struct omap3_vc_timings timings[2 ]; };static struct omap3_vc vc;void omap3_vc_set_pmic_signaling (int core_next_state) {struct voltagedomain *vd = vc.vd; -u32 voltctrl; +struct omap3_vc_timings *c = vc.timings; +u32 voltctrl, voltsetup1, voltsetup2; voltctrl = vc.voltctrl; + voltsetup1 = vc.voltsetup1; + voltsetup2 = vc.voltsetup2; +switch (core_next_state) {case PWRDM_POWER_OFF : voltctrl &= ~(OMAP3430_PRM_VOLTCTRL_AUTO_RET |OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP ); voltctrl |=OMAP3430_PRM_VOLTCTRL_AUTO_OFF ; +if (voltctrl &OMAP3430_PRM_VOLTCTRL_SEL_OFF ) + voltsetup2 = c->voltsetup2; +else + voltsetup1 = c->voltsetup1;break ;case PWRDM_POWER_RET :default : + c++; voltctrl &= ~(OMAP3430_PRM_VOLTCTRL_AUTO_OFF |OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP ); voltctrl |=OMAP3430_PRM_VOLTCTRL_AUTO_RET ; + voltsetup1 = c->voltsetup1;break ; } +if (voltctrl != vc.voltctrl) { vd->write (voltctrl,OMAP3_PRM_VOLTCTRL_OFFSET ); vc.voltctrl = voltctrl; } +if (voltsetup1 != vc.voltsetup1) { + vd->write (c->voltsetup1, +OMAP3_PRM_VOLTSETUP1_OFFSET ); + vc.voltsetup1 = voltsetup1; + } +if (voltsetup2 != vc.voltsetup2) { + vd->write (c->voltsetup2, +OMAP3_PRM_VOLTSETUP2_OFFSET ); + vc.voltsetup2 = voltsetup2; + } }#define PRM_POLCTRL_TWL_MASK (OMAP3430_PRM_POLCTRL_CLKREQ_POL | \
@@ -301,6 +330,18 @@ static void __init omap3_vc_init_pmic_signaling(struct voltagedomain *voltdm)omap3_vc_set_pmic_signaling (PWRDM_POWER_ON ); } +static void omap3_init_voltsetup1 (struct voltagedomain *voltdm, +struct omap3_vc_timings *c,u32 idle) +{ +unsigned long val; + + val = (voltdm->vc_param->on - idle) / voltdm->pmic->slew_rate; + val *= voltdm->sys_clk.rate /8 /1000000 +1 ; + val <<=__ffs (voltdm->vfsm->voltsetup_mask); + c->voltsetup1 &= ~voltdm->vfsm->voltsetup_mask; + c->voltsetup1 |= val; +} +/** * omap3_set_i2c_timings - sets i2c sleep timings for a channel * @voltdm: channel to configure
@@ -311,31 +352,21 @@ static void __init omap3_vc_init_pmic_signaling(struct voltagedomain *voltdm)* or retention. Off mode has additionally an option to use sys_off_mode * pad, which uses a global signal to program the whole power IC to * off-mode. +* +* Note that pmic is not controlling the voltage scaling during +* retention signaled over I2C4, so we can keep voltsetup2 as 0. +* And the oscillator is not shut off over I2C4, so no need to +* set clksetup. */ -static void omap3_set_i2c_timings (struct voltagedomain *voltdm,bool off_mode) +static void omap3_set_i2c_timings (struct voltagedomain *voltdm) { -unsigned long voltsetup1; -u32 tgt_volt; - -if (off_mode) - tgt_volt = voltdm->vc_param->off; -else - tgt_volt = voltdm->vc_param->ret; - - voltsetup1 = (voltdm->vc_param->on - tgt_volt) / - voltdm->pmic->slew_rate; +struct omap3_vc_timings *c = vc.timings; - voltsetup1 = voltsetup1 * voltdm->sys_clk.rate /8 /1000000 +1 ; - - voltdm->rmw (voltdm->vfsm->voltsetup_mask, - voltsetup1 <<__ffs (voltdm->vfsm->voltsetup_mask), - voltdm->vfsm->voltsetup_reg); - -/* -* pmic is not controlling the voltage scaling during retention, -* thus set voltsetup2 to 0 -*/ - voltdm->write (0 ,OMAP3_PRM_VOLTSETUP2_OFFSET ); +/* Configure PRWDM_POWER_OFF over I2C4 */ +omap3_init_voltsetup1 (voltdm, c, voltdm->vc_param->off); + c++; +/* Configure PRWDM_POWER_RET over I2C4 */ +omap3_init_voltsetup1 (voltdm, c, voltdm->vc_param->ret); }/**
@@ -344,22 +375,49 @@ static void omap3_set_i2c_timings(struct voltagedomain *voltdm, bool off_mode)* * Calculates and sets up off-mode timings for a channel. Off-mode * can use either I2C based voltage scaling, or alternatively -* sys_off_mode pad can be used to send a global command to power IC. -* This function first checks which mode is being used, and calls -* omap3_set_i2c_timings() if the system is using I2C control mode. +* sys_off_mode pad can be used to send a global command to power IC.n, * sys_off_mode has the additional benefit that voltages can be * scaled to zero volt level with TWL4030 / TWL5030, I2C can only * scale to 600mV. +* +* Note that omap is not controlling the voltage scaling during +* off idle signaled by sys_off_mode, so we can keep voltsetup1 +* as 0. */ static void omap3_set_off_timings (struct voltagedomain *voltdm) { +struct omap3_vc_timings *c = vc.timings; +u32 tstart, tshut, clksetup, voltoffset; + +if (c->voltsetup2) +return ; + +omap_pm_get_oscillator (&tstart, &tshut); +if (tstart ==ULONG_MAX ) { +pr_debug ("PM: oscillator start-up time not initialized, using 10ms\n" ); + clksetup =omap_usec_to_32k (10000 ); + }else { + clksetup =omap_usec_to_32k (tstart); + } + +/* +* For twl4030 errata 27, we need to allow minimum ~488.32 us wait to +* switch from HFCLKIN to internal oscillator. That means timings +* have voltoffset fixed to 0xa in rounded up 32 KiHz cycles. And +* that means we can calculate the value based on the oscillator +* start-up time since voltoffset2 = clksetup - voltoffset. +*/ + voltoffset =omap_usec_to_32k (488 ); + c->voltsetup2 = clksetup - voltoffset; + voltdm->write (clksetup,OMAP3_PRM_CLKSETUP_OFFSET ); + voltdm->write (voltoffset,OMAP3_PRM_VOLTOFFSET_OFFSET ); }static void __init omap3_vc_init_channel (struct voltagedomain *voltdm) {omap3_vc_init_pmic_signaling (voltdm);omap3_set_off_timings (voltdm); -omap3_set_i2c_timings (voltdm, true); +omap3_set_i2c_timings (voltdm); }/**
Tony Lindgren
maintainerPATCH 5/11 ARM: dts: Configure omap3 twl4030 I2C4 pins by default
In reply to Tony LindgrenAlmost certainly any sane board has the twl4030 has the I2C4 pins connected as those are needed for voltage control during idle. If the I2C4 lines are not properly muxed, any voltage scaling over I2C4 will fail.
Let's mux those pins by default, the boards that are not using them can still configure things separately.
--- arch/arm/boot/dts/twl4030_omap3.dtsi | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
arch/arm/boot/dts/twl4030_omap3.dtsi +18 -1
@@ -8,7 +8,7 @@ &twl { pinctrl-names = "default"; - pinctrl-0 = <&twl4030_pins>; + pinctrl-0 = <&twl4030_pins &twl4030_vpins>; }; &omap3_pmx_core {
@@ -23,3 +23,20 @@ >; }; }; + +/* + * If your board is not using the I2C4 pins with twl4030, then don't include + * this file. For proper idle mode signaling with sys_clkreq and sys_off_mode + * pins we need to configure I2C4, or else use the legacy sys_nvmode1 and + * sys_nvmode2 signaling. + */ +&omap3_pmx_wkup { + twl4030_vpins: pinmux_twl4030_vpins { + pinctrl-single,pins = < + OMAP3_WKUP_IOPAD(0x2a00, PIN_INPUT | MUX_MODE0) /* i2c4_scl.i2c4_scl */ + OMAP3_WKUP_IOPAD(0x2a02, PIN_INPUT | MUX_MODE0) /* i2c4_sda.i2c4_sda */ + OMAP3_WKUP_IOPAD(0x2a06, PIN_OUTPUT | MUX_MODE0) /* sys_clkreq.sys_clkreq */ + OMAP3_WKUP_IOPAD(0x2a18, PIN_OUTPUT | MUX_MODE0) /* sys_off_mode.sys_off_mode */ + >; + }; +};
Signature · 1 line
1.8.1.1
Tony Lindgren
maintainerPATCH 6/11 ARM: OMAP2+: Fix voltage scaling init for device tree
In reply to Tony LindgrenWe are currently disabling the init of voltage scaling for device tree. With the voltage scaling problems fixed for omap3 in general, there's no need to disable the voltage scaling init for device tree based booting.
--- arch/arm/mach-omap2/pm.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-)
arch/arm/mach-omap2/pm.c +12 -16
@@ -287,25 +287,21 @@ omap_postcore_initcall(omap2_common_pm_init);int __init omap2_common_pm_late_init (void ) { -/* -* In the case of DT, the PMIC and SR initialization will be done using -* a completely different mechanism. -* Disable this part if a DT blob is available. -*/ -if (!of_have_populated_dt ()) { - -/* Init the voltage layer */ -omap_pmic_late_init (); -omap_voltage_late_init (); +if (of_have_populated_dt ()) { +omap3_twl_init (); +omap4_twl_init (); + } -/* Initialize the voltages */ -omap3_init_voltages (); -omap4_init_voltages (); +/* Init the voltage layer */ +omap_pmic_late_init (); +omap_voltage_late_init (); -/* Smartreflex device init */ -omap_devinit_smartreflex (); +/* Initialize the voltages */ +omap3_init_voltages (); +omap4_init_voltages (); - } +/* Smartreflex device init */ +omap_devinit_smartreflex ();/* cpufreq dummy device instantiation */ omap_init_cpufreq ();
Signature · 1 line
1.8.1.1
PATCH 6/11 ARM: OMAP2+: Fix voltage scaling init for device tree
Hi Tony,
If found this patch in your omap-for-v3.16/pm-signed tag and tested it on top of Linus master + omap 3.16 dt + Tomi fbdev omap. I assumed it's going upstream for 3.16(?).
First of all; is this safe on OMAP4460?
As far as I understand voltage scaling on 4460 has never been mainline, but this code enables voltage scaling for all omap4 parts. More below.
Quoted 47 lines · Tony Lindgren
We are currently disabling the init of voltage scaling for device tree. With the voltage scaling problems fixed for omap3 in general, there's no need to disable the voltage scaling init for device tree based booting.
Cc Kevin Hilman <[email protected]>Cc Nishanth Menon <[email protected]>Cc Paul Walmsley <[email protected]>Cc Tero Kristo <[email protected]>Signed-off-by Tony Lindgren <[email protected]>--- arch/arm/mach-omap2/pm.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-)arch/arm/mach-omap2/pm.c +8
-15@@ -287,25 +287,21 @@ omap_postcore_initcall(omap2_common_pm_init);int __init omap2_common_pm_late_init (void ) { -/* -* In the case of DT, the PMIC and SR initialization will be done using -* a completely different mechanism. -* Disable this part if a DT blob is available. -*/ -if (!of_have_populated_dt ()) { - -/* Init the voltage layer */ -omap_pmic_late_init (); -omap_voltage_late_init (); +if (of_have_populated_dt ()) { +omap3_twl_init (); +omap4_twl_init (); + } -/* Initialize the voltages */ -omap3_init_voltages (); -omap4_init_voltages (); +/* Init the voltage layer */ +omap_pmic_late_init (); +omap_voltage_late_init (); -/* Smartreflex device init */ -omap_devinit_smartreflex (); +/* Initialize the voltages */
arch/arm/mach-omap2/pm.c omap_postcore_initcall(omap2_common_pm_init);
Quoted 10 lines
arch/arm/mach-omap2/pm.c +4
-2+omap3_init_voltages (); +omap4_init_voltages (); - } +/* Smartreflex device init */ +omap_devinit_smartreflex ();/* cpufreq dummy device instantiation */ omap_init_cpufreq (); --
In omap4_twl_init() we have:
if (!cpu_is_omap44xx())
return -ENODEV;
voltdm = voltdm_lookup("mpu"); omap_voltage_register_pmic(voltdm, &omap4_mpu_pmic);
voltdm = voltdm_lookup("iva"); omap_voltage_register_pmic(voltdm, &omap4_iva_pmic);
voltdm = voltdm_lookup("core"); omap_voltage_register_pmic(voltdm, &omap4_core_pmic);
As far as I understand the setup above is only valid for 4430 and not 4460 since it is hook up to the twl in diffent way. External switcher (TPS62361) for mpu rail and the other rails are used differently.
I also get the following messages on boot now:
[ 2.458740] twl: not initialized [ 2.462127] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.470581] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.479003] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.487457] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.495880] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.504302] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.512725] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1410000 Vs max 1316660 [ 2.521179] omap2_set_init_voltage: unable to find boot up OPP for vdd_mpu [ 2.528411] omap2_set_init_voltage: unable to set vdd_mpu [ 2.534088] omap2_set_init_voltage: unable to find boot up OPP for vdd_core [ 2.541412] omap2_set_init_voltage: unable to set vdd_core [ 2.547210] omap2_set_init_voltage: unable to find boot up OPP for vdd_iva [ 2.554443] omap2_set_init_voltage: unable to set vdd_iva
It doesn't seem too happy on my 4460.
regards
Joachim Eastwood
Tony Lindgren
maintainerPATCH 6/11 ARM: OMAP2+: Fix voltage scaling init for device tree
Quoted 5 lines · Joachim Eastwood
Hi Tony,
If found this patch in your omap-for-v3.16/pm-signed tag and tested it on top of Linus master + omap 3.16 dt + Tomi fbdev omap. I assumed it's going upstream for 3.16(?).
Yes.
Quoted 4 lines
First of all; is this safe on OMAP4460?
As far as I understand voltage scaling on 4460 has never been mainline, but this code enables voltage scaling for all omap4 parts. More below.
Sounds like something's not right then. This should just restore the earlier code path we had for legacy booting for omap4.
Quoted 69 lines · Tony Lindgren
Quoted 47 lines
We are currently disabling the init of voltage scaling for device tree. With the voltage scaling problems fixed for omap3 in general, there's no need to disable the voltage scaling init for device tree based booting.
Cc Kevin Hilman <[email protected]>Cc Nishanth Menon <[email protected]>Cc Paul Walmsley <[email protected]>Cc Tero Kristo <[email protected]>Signed-off-by Tony Lindgren <[email protected]>--- arch/arm/mach-omap2/pm.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-)arch/arm/mach-omap2/pm.c +8
-15@@ -287,25 +287,21 @@ omap_postcore_initcall(omap2_common_pm_init);int __init omap2_common_pm_late_init (void ) { -/* -* In the case of DT, the PMIC and SR initialization will be done using -* a completely different mechanism. -* Disable this part if a DT blob is available. -*/ -if (!of_have_populated_dt ()) { - -/* Init the voltage layer */ -omap_pmic_late_init (); -omap_voltage_late_init (); +if (of_have_populated_dt ()) { +omap3_twl_init (); +omap4_twl_init (); + } -/* Initialize the voltages */ -omap3_init_voltages (); -omap4_init_voltages (); +/* Init the voltage layer */ +omap_pmic_late_init (); +omap_voltage_late_init (); -/* Smartreflex device init */ -omap_devinit_smartreflex (); +/* Initialize the voltages */ arch/arm/mach-omap2/pm.c omap_postcore_initcall(omap2_common_pm_init);
Quoted 10 lines
arch/arm/mach-omap2/pm.c +4
-2+omap3_init_voltages (); +omap4_init_voltages (); - } +/* Smartreflex device init */ +omap_devinit_smartreflex ();/* cpufreq dummy device instantiation */ omap_init_cpufreq (); --In
omap4_twl_init()we have:
if (!cpu_is_omap44xx())return -ENODEV;voltdm =
voltdm_lookup("mpu");omap_voltage_register_pmic(voltdm, &omap4_mpu_pmic);voltdm =
voltdm_lookup("iva");omap_voltage_register_pmic(voltdm, &omap4_iva_pmic);
Quoted 6 lines
voltdm =
voltdm_lookup("core");omap_voltage_register_pmic(voltdm, &omap4_core_pmic);As far as I understand the setup above is only valid for 4430 and not 4460 since it is hook up to the twl in diffent way. External switcher (TPS62361) for mpu rail and the other rails are used differently.
Hmm interesting, I think we had this enabled with legacy booting?
Quoted 23 lines
I also get the following messages on boot now:
[ 2.458740] twl: not initialized [ 2.462127] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.470581] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.479003] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.487457] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.495880] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.504302] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.512725] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1410000 Vs max 1316660 [ 2.521179] omap2_set_init_voltage: unable to find boot up OPP for vdd_mpu [ 2.528411] omap2_set_init_voltage: unable to set vdd_mpu [ 2.534088] omap2_set_init_voltage: unable to find boot up OPP for vdd_core [ 2.541412] omap2_set_init_voltage: unable to set vdd_core [ 2.547210] omap2_set_init_voltage: unable to find boot up OPP for vdd_iva [ 2.554443] omap2_set_init_voltage: unable to set vdd_iva
Quoted 1 line
It doesn't seem too happy on my 4460.
Indeed, we need to fix it. Nishant, any comments on how we should deal with this one?
Regards,
Tony
PATCH 6/11 ARM: OMAP2+: Fix voltage scaling init for device tree
Quoted 118 lines · Tony Lindgren
Quoted 5 lines · Joachim Eastwood
Hi Tony,
If found this patch in your omap-for-v3.16/pm-signed tag and tested it on top of Linus master + omap 3.16 dt + Tomi fbdev omap. I assumed it's going upstream for 3.16(?).
Yes.
Quoted 4 lines
First of all; is this safe on OMAP4460?
As far as I understand voltage scaling on 4460 has never been mainline, but this code enables voltage scaling for all omap4 parts. More below.Sounds like something's not right then. This should just restore the earlier code path we had for legacy booting for omap4.
Quoted 69 lines · Tony Lindgren
Quoted 47 lines
We are currently disabling the init of voltage scaling for device tree. With the voltage scaling problems fixed for omap3 in general, there's no need to disable the voltage scaling init for device tree based booting.
Cc Kevin Hilman <[email protected]>Cc Nishanth Menon <[email protected]>Cc Paul Walmsley <[email protected]>Cc Tero Kristo <[email protected]>Signed-off-by Tony Lindgren <[email protected]>--- arch/arm/mach-omap2/pm.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-)arch/arm/mach-omap2/pm.c +8
-15@@ -287,25 +287,21 @@ omap_postcore_initcall(omap2_common_pm_init);int __init omap2_common_pm_late_init (void ) { -/* -* In the case of DT, the PMIC and SR initialization will be done using -* a completely different mechanism. -* Disable this part if a DT blob is available. -*/ -if (!of_have_populated_dt ()) { - -/* Init the voltage layer */ -omap_pmic_late_init (); -omap_voltage_late_init (); +if (of_have_populated_dt ()) { +omap3_twl_init (); +omap4_twl_init (); + } -/* Initialize the voltages */ -omap3_init_voltages (); -omap4_init_voltages (); +/* Init the voltage layer */ +omap_pmic_late_init (); +omap_voltage_late_init (); -/* Smartreflex device init */ -omap_devinit_smartreflex (); +/* Initialize the voltages */ arch/arm/mach-omap2/pm.c omap_postcore_initcall(omap2_common_pm_init);
Quoted 10 lines
arch/arm/mach-omap2/pm.c +4
-2+omap3_init_voltages (); +omap4_init_voltages (); - } +/* Smartreflex device init */ +omap_devinit_smartreflex ();/* cpufreq dummy device instantiation */ omap_init_cpufreq (); --In
omap4_twl_init()we have:
if (!cpu_is_omap44xx())return -ENODEV;voltdm =
voltdm_lookup("mpu");omap_voltage_register_pmic(voltdm, &omap4_mpu_pmic);voltdm =
voltdm_lookup("iva");omap_voltage_register_pmic(voltdm, &omap4_iva_pmic);Quoted 6 lines
voltdm =
voltdm_lookup("core");omap_voltage_register_pmic(voltdm, &omap4_core_pmic);As far as I understand the setup above is only valid for 4430 and not 4460 since it is hook up to the twl in diffent way. External switcher (TPS62361) for mpu rail and the other rails are used differently.
Hmm interesting, I think we had this enabled with legacy booting?
Quoted 23 lines
I also get the following messages on boot now:
[ 2.458740] twl: not initialized [ 2.462127] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.470581] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.479003] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.487457] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.495880] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.504302] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.512725] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1410000 Vs max 1316660 [ 2.521179] omap2_set_init_voltage: unable to find boot up OPP for vdd_mpu [ 2.528411] omap2_set_init_voltage: unable to set vdd_mpu [ 2.534088] omap2_set_init_voltage: unable to find boot up OPP for vdd_core [ 2.541412] omap2_set_init_voltage: unable to set vdd_core [ 2.547210] omap2_set_init_voltage: unable to find boot up OPP for vdd_iva [ 2.554443] omap2_set_init_voltage: unable to set vdd_iva
Quoted 4 lines
Quoted 1 line
It doesn't seem too happy on my 4460.
Indeed, we need to fix it. Nishant, any comments on how we should deal with this one?
we can add TPS data here for 4460 mpu (panda-ES) if that is interesting to us - given that the common voltage domain/VC/VP stuff so far has gone in no positive direction in our discussions last year.
Regards,
Nishanth Menon
PATCH 6/11 ARM: OMAP2+: Fix voltage scaling init for device tree
Quoted 121 lines · Nishanth Menon
Quoted 120 lines · Tony Lindgren
Quoted 5 lines · Joachim Eastwood
Hi Tony,
If found this patch in your omap-for-v3.16/pm-signed tag and tested it on top of Linus master + omap 3.16 dt + Tomi fbdev omap. I assumed it's going upstream for 3.16(?).
Yes.
Quoted 4 lines
First of all; is this safe on OMAP4460?
As far as I understand voltage scaling on 4460 has never been mainline, but this code enables voltage scaling for all omap4 parts. More below.Sounds like something's not right then. This should just restore the earlier code path we had for legacy booting for omap4.
Quoted 69 lines · Tony Lindgren
Quoted 47 lines
We are currently disabling the init of voltage scaling for device tree. With the voltage scaling problems fixed for omap3 in general, there's no need to disable the voltage scaling init for device tree based booting.
Cc Kevin Hilman <[email protected]>Cc Nishanth Menon <[email protected]>Cc Paul Walmsley <[email protected]>Cc Tero Kristo <[email protected]>Signed-off-by Tony Lindgren <[email protected]>--- arch/arm/mach-omap2/pm.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-)arch/arm/mach-omap2/pm.c +8
-15@@ -287,25 +287,21 @@ omap_postcore_initcall(omap2_common_pm_init);int __init omap2_common_pm_late_init (void ) { -/* -* In the case of DT, the PMIC and SR initialization will be done using -* a completely different mechanism. -* Disable this part if a DT blob is available. -*/ -if (!of_have_populated_dt ()) { - -/* Init the voltage layer */ -omap_pmic_late_init (); -omap_voltage_late_init (); +if (of_have_populated_dt ()) { +omap3_twl_init (); +omap4_twl_init (); + } -/* Initialize the voltages */ -omap3_init_voltages (); -omap4_init_voltages (); +/* Init the voltage layer */ +omap_pmic_late_init (); +omap_voltage_late_init (); -/* Smartreflex device init */ -omap_devinit_smartreflex (); +/* Initialize the voltages */ arch/arm/mach-omap2/pm.c omap_postcore_initcall(omap2_common_pm_init);
Quoted 10 lines
arch/arm/mach-omap2/pm.c +4
-2+omap3_init_voltages (); +omap4_init_voltages (); - } +/* Smartreflex device init */ +omap_devinit_smartreflex ();/* cpufreq dummy device instantiation */ omap_init_cpufreq (); --In
omap4_twl_init()we have:
if (!cpu_is_omap44xx())return -ENODEV;voltdm =
voltdm_lookup("mpu");omap_voltage_register_pmic(voltdm, &omap4_mpu_pmic);voltdm =
voltdm_lookup("iva");omap_voltage_register_pmic(voltdm, &omap4_iva_pmic);Quoted 6 lines
voltdm =
voltdm_lookup("core");omap_voltage_register_pmic(voltdm, &omap4_core_pmic);As far as I understand the setup above is only valid for 4430 and not 4460 since it is hook up to the twl in diffent way. External switcher (TPS62361) for mpu rail and the other rails are used differently.
Hmm interesting, I think we had this enabled with legacy booting?
Quoted 24 lines
I also get the following messages on boot now:
[ 2.458740] twl: not initialized [ 2.462127] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.470581] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.479003] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.487457] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.495880] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.504302] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.512725] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1410000 Vs max 1316660 [ 2.521179] omap2_set_init_voltage: unable to find boot up OPP for vdd_mpu [ 2.528411] omap2_set_init_voltage: unable to set vdd_mpu [ 2.534088] omap2_set_init_voltage: unable to find boot up OPP for vdd_core [ 2.541412] omap2_set_init_voltage: unable to set vdd_core [ 2.547210] omap2_set_init_voltage: unable to find boot up OPP for vdd_iva [ 2.554443] omap2_set_init_voltage: unable to set vdd_ivaIt doesn't seem too happy on my 4460.
Quoted 8 lines
Quoted 2 lines
Indeed, we need to fix it. Nishant, any comments on how we should deal with this one?
we can add TPS data here for 4460 mpu (panda-ES) if that is interesting to us - given that the common voltage domain/VC/VP stuff so far has gone in no positive direction in our discussions last year.
If this means that voltage scaling and 1.5GHz would work for 4460 it would make me very happy :)
But I assume that would bring lots of more code into mach-omap2 which wouldn't be good either. Escaping the old 3.4 kernel would be nice, though.
regards
Joachim Eastwood
PATCH 6/11 ARM: OMAP2+: Fix voltage scaling init for device tree
On 05/19/2014 01:48 PM, Joachim Eastwood wrote:
[...]
Quoted 9 lines
Quoted 3 lines
we can add TPS data here for 4460 mpu (panda-ES) if that is interesting to us - given that the common voltage domain/VC/VP stuff so far has gone in no positive direction in our discussions last year.
If this means that voltage scaling and 1.5GHz would work for 4460 it would make me very happy :)
But I assume that would bring lots of more code into mach-omap2 which wouldn't be good either. Escaping the old 3.4 kernel would be nice, though.
Not really.. we cannot make 1.5GHz work without ABB integration into the transition sequence[1] - what we can try to do is make basic dvfs work. the approach we'd be taking (if we introduce tps handlers) is to do exactly what we did in 3.0/3.4 kernels. I am not too happy with that. instead, I would prefer we skip dvfs for 4460(which was never working in upstream) and do it the *right* way - which ever the upstream maintainers want it to be. that is my personal 2 cents.
[1] last attempt:
http://marc.info/?l=linux-omap&m=139275579731801&w=2 (patch 1-5). Blocked at:
http://marc.info/?l=linux-arm-kernel&m=139526861215152&w=2
Signature · 2 lines
Regards, Nishanth Menon
Tony Lindgren
maintainerPATCH 6/11 ARM: OMAP2+: Fix voltage scaling init for device tree
In reply to Nishanth MenonQuoted 32 lines · Nishanth Menon
Quoted 31 lines · Tony Lindgren
Quoted 4 lines · Joachim Eastwood
As far as I understand the setup above is only valid for 4430 and not 4460 since it is hook up to the twl in diffent way. External switcher (TPS62361) for mpu rail and the other rails are used differently.
Hmm interesting, I think we had this enabled with legacy booting?
Quoted 23 lines
I also get the following messages on boot now:
[ 2.458740] twl: not initialized [ 2.462127] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.470581] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.479003] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.487457] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.495880] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.504302] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1375000 Vs max 1316660 [ 2.512725] twl6030_uv_to_vsel:OUT OF RANGE! non mapped vsel for 1410000 Vs max 1316660 [ 2.521179] omap2_set_init_voltage: unable to find boot up OPP for vdd_mpu [ 2.528411] omap2_set_init_voltage: unable to set vdd_mpu [ 2.534088] omap2_set_init_voltage: unable to find boot up OPP for vdd_core [ 2.541412] omap2_set_init_voltage: unable to set vdd_core [ 2.547210] omap2_set_init_voltage: unable to find boot up OPP for vdd_iva [ 2.554443] omap2_set_init_voltage: unable to set vdd_iva
Quoted 8 lines
Quoted 4 lines
Quoted 1 line
It doesn't seem too happy on my 4460.
Indeed, we need to fix it. Nishant, any comments on how we should deal with this one?
we can add TPS data here for 4460 mpu (panda-ES) if that is interesting to us - given that the common voltage domain/VC/VP stuff so far has gone in no positive direction in our discussions last year.
Makes sense to me. That way we have things back working after all these device tree related changes.
Regards,
Tony
Tony Lindgren
maintainerPATCH 7/11 ARM: dts: Enable N900 keybaord sleep leds by default
In reply to Tony LindgrenOn N900 there are nice LEDs that show the state of the sys_clkreq and sys_off_mode pins.
These LEDs go low when the system enters deeper idle states. The left LED shows the state of the sys_clkreq pin, and goes off during retention idle. The right LED shows the state of sys_off_mode pin and both go off during off idle.
As N900 is a battery operated device, these LEDs should be off most of the time. So let's enable them by default so we can make sure the system is mostly idle.
This allows the maintainers to also immediately test patches for PM regressions by looking at the LEDs, which certainly makes my life easier.
The LED can naturally be disabled during runtime with:
# echo none > /sys/class/leds/debug::sleep/trigger
Note that we don't currently have support for omap3 errata 1.158 that remuxes GPIO pins to INPUT_PULLUP | MUX_MODE7 for the duration of idle. This means that the GPIO pins set high will go down during off idle. In this case it does not matter as the sys_off_mode goes down too, but there's still a slim chance of false off idle LED signals. If in doubt, false LED signals can be verified by the sys_off_mode or vdd_core values.
Also note that to allow the UARTs to autoidle, the following needs to be run on N900 to enable off idle:
#!/bin/sh
uarts=$(find /sys/class/tty/ttyO*/device/power/ -type d) for uart in $uarts; do
echo 3000 > $uart/autosuspend_delay_ms
done
uarts=$(find /sys/class/tty/ttyO*/power/ -type d) for uart in $uarts; do
echo enabled > $uart/wakeup
echo auto > $uart/control
done
echo 1 > /sys/kernel/debug/pm_debug/enable_off_mode
For retention idle, change the above to set 0 to enable_off_mode.
Also note that without the twl4030 PM scripts the actual voltage scaling won't happen for off idle so we only get voltage scaling over I2C4 for retention idle. I'll do some device tree patches for those also a bit later on.
--- arch/arm/boot/dts/omap3-n900.dts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
arch/arm/boot/dts/omap3-n900.dts +17 -0
@@ -21,6 +21,17 @@ }; }; + leds { + compatible = "gpio-leds"; + heartbeat { + label = "debug::sleep"; + gpios = <&gpio6 2 GPIO_ACTIVE_HIGH>; /* gpio162 */ + linux,default-trigger = "default-on"; + pinctrl-names = "default"; + pinctrl-0 = <&debug_leds>; + }; + }; + memory { device_type = "memory"; reg = <0x80000000 0x10000000>; /* 256 MB */
@@ -114,6 +125,12 @@ >; }; + debug_leds: pinmux_debug_led_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x2198, PIN_OUTPUT | MUX_MODE4) /* mcbsp1_clkx.gpio_162 */ + >; + }; + mmc1_pins: pinmux_mmc1_pins { pinctrl-single,pins = < 0x114 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk */
Signature · 1 line
1.8.1.1
Tony Lindgren
maintainerPATCH 7/11 ARM: dts: Enable N900 keybaord sleep leds by default
Quoted 2 lines · Tony Lindgren
On N900 there are nice LEDs that show the state of the
sys_clkreqandsys_off_modepins.
Here's a work in progress related twl4030 script for N900 to play with, I think it can be made more generic though. This scales vdd_core to zero during off idle for me with this series.
Regards,
Tony
8< ----------------------------
Documentation/devicetree/bindings/mfd/twl4030-power.txt +3 -1
@@ -5,7 +5,9 @@ to control the power resources, including power scripts. For now, the binding only supports the complete shutdown of the system after poweroff. Required properties: -- compatible : must be "ti,twl4030-power" +- compatible : Needs to be one of the following + "ti,twl4030-power-n900" + "ti,twl4030-power" Optional properties: - ti,use_poweroff: With this flag, the chip will initiates an ACTIVE-to-OFF or
arch/arm/boot/dts/omap3-n900.dts +5 -0
@@ -269,6 +269,11 @@ compatible = "ti,twl4030-audio"; ti,enable-vibra = <1>; }; + + twl_power: power { + compatible = "ti,twl4030-power-n900"; + ti,use_poweroff; + }; }; &twl_gpio {
drivers/mfd/twl4030-power.c +229 -13
288 lines not on this page · raw message
Aaro Koskinen
maintainerPATCH 7/11 ARM: dts: Enable N900 keybaord sleep leds by default
In reply to Tony LindgrenHi,
arch/arm/boot/dts/omap3-n900.dts line 29
Quoted 6 lines · Tony Lindgren
arch/arm/boot/dts/omap3-n900.dts +6
-0+ leds { + compatible = "gpio-leds"; + heartbeat { + label = "debug::sleep"; + gpios = <&gpio6 2 GPIO_ACTIVE_HIGH>; /* gpio162 */ + linux,default-trigger = "default-on";
Just some very minor nits, spaces should be converted to TABs here for indent, and patch title should say "keyboard" instead of "keybaord".
arch/arm/boot/dts/omap3-n900.dts line 33
Quoted 4 lines
arch/arm/boot/dts/omap3-n900.dts +4
-0+ pinctrl-names = "default"; + pinctrl-0 = <&debug_leds>; + }; + };
A.
Tony Lindgren
maintainerPATCH 7/11 ARM: dts: Enable N900 keybaord sleep leds by default
Quoted 10 lines · Aaro Koskinen
Hi,
Review
Quoted 6 lines · Tony Lindgren
(quoted diff) +6
-0+ leds { + compatible = "gpio-leds"; + heartbeat { + label = "debug::sleep"; + gpios = <&gpio6 2 GPIO_ACTIVE_HIGH>; /* gpio162 */ + linux,default-trigger = "default-on";
Quoted 4 lines
Just some very minor nits, spaces should be converted to TABs here for indent, and patch title should say "keyboard" instead of "keybaord".
Acked-by Aaro Koskinen <[email protected]>
Thanks and sorry for the delay, got sidetracked with some GPMC bugs. Here's the updated version of this patch.
Tony
8< ------------------------
From: Tony Lindgren <[email protected]>
Date: Wed, 23 Apr 2014 13:59:24 -0700
Subject: [PATCH] ARM: dts: Enable N900 keyboard sleep leds by default
On N900 there are nice LEDs that show the state of the sys_clkreq and sys_off_mode pins.
These LEDs go low when the system enters deeper idle states. The left LED shows the state of the sys_clkreq pin, and goes off during retention idle. The right LED shows the state of sys_off_mode pin and both go off during off idle.
As N900 is a battery operated device, these LEDs should be off most of the time. So let's enable them by default so we can make sure the system is mostly idle.
This allows the maintainers to also immediately test patches for PM regressions by looking at the LEDs, which certainly makes my life easier.
The LED can naturally be disabled during runtime with:
# echo none > /sys/class/leds/debug::sleep/trigger
Note that we don't currently have support for omap3 errata 1.158 that remuxes GPIO pins to INPUT_PULLUP | MUX_MODE7 for the duration of idle. This means that the GPIO pins set high will go down during off idle. In this case it does not matter as the sys_off_mode goes down too, but there's still a slim chance of false off idle LED signals. If in doubt, false LED signals can be verified by the sys_off_mode or vdd_core values.
Also note that to allow the UARTs to autoidle, the following needs to be run on N900 to enable off idle:
#!/bin/sh
uarts=$(find /sys/class/tty/ttyO*/device/power/ -type d) for uart in $uarts; do
echo 3000 > $uart/autosuspend_delay_ms
done
uarts=$(find /sys/class/tty/ttyO*/power/ -type d) for uart in $uarts; do
echo enabled > $uart/wakeup
echo auto > $uart/control
done
echo 1 > /sys/kernel/debug/pm_debug/enable_off_mode
For retention idle, change the above to set 0 to enable_off_mode.
Also note that without the twl4030 PM scripts the actual voltage scaling won't happen for off idle so we only get voltage scaling over I2C4 for retention idle. I'll do some device tree patches for those also a bit later on.
arch/arm/boot/dts/omap3-n900.dts +17 -0
@@ -21,6 +21,17 @@ }; }; + leds { + compatible = "gpio-leds"; + heartbeat { + label = "debug::sleep"; + gpios = <&gpio6 2 GPIO_ACTIVE_HIGH>; /* gpio162 */ + linux,default-trigger = "default-on"; + pinctrl-names = "default"; + pinctrl-0 = <&debug_leds>; + }; + }; + memory { device_type = "memory"; reg = <0x80000000 0x10000000>; /* 256 MB */
@@ -114,6 +125,12 @@ >; }; + debug_leds: pinmux_debug_led_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x2198, PIN_OUTPUT | MUX_MODE4) /* mcbsp1_clkx.gpio_162 */ + >; + }; + mmc1_pins: pinmux_mmc1_pins { pinctrl-single,pins = < 0x114 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk */
Tony Lindgren
maintainerPATCH 8/11 ARM: dts: Fix omap serial wake-up when booted with device tree
In reply to Tony LindgrenWe've had deeper idle states working on omaps for few years now, but only in the legacy mode. When booted with device tree, the wake-up events did not have a chance to work until commit 3e6cee1786a1 (pinctrl: single: Add support for wake-up interrupts) that recently got merged. In addition to that we also needed commit 79d9701559a9 (of/irq: create interrupts-extended property) that's now also merged.
So let's fix the wake-up events for some selected omaps so devices booted in device tree mode won't just hang if deeper power states are enabled, and so systems can wake up from suspend to the serial port event.
Note that there's no longer need to specify the wake-up bit in the pinctrl settings, the request_irq on the wake-up pin takes care of that.
Note that there will be new harmless warnings in dmesg output without patch "of/platform: Fix no irq domain found errors when populating interrupts":
https://lkml.org/lkml/2014/4/10/620
--- arch/arm/boot/dts/omap3-evm-37xx.dts | 9 +++++++++ arch/arm/boot/dts/omap3-n900.dts | 2 ++ arch/arm/boot/dts/omap3.dtsi | 6 +++--- arch/arm/boot/dts/omap4-panda-common.dtsi | 15 +++++++++++++++ arch/arm/boot/dts/omap4-sdp.dts | 6 ++++++ arch/arm/boot/dts/omap4.dtsi | 6 +++--- include/dt-bindings/pinctrl/omap.h | 12 ++++++++++++ 7 files changed, 50 insertions(+), 6 deletions(-)
arch/arm/boot/dts/omap3-evm-37xx.dts +9 -0
@@ -89,7 +89,16 @@ status = "disabled"; }; +&uart1 { + interrupts-extended = <&intc 72 &omap3_pmx_core OMAP3_UART1_RX>; +}; + +&uart2 { + interrupts-extended = <&intc 73 &omap3_pmx_core OMAP3_UART2_RX>; +}; + &uart3 { + interrupts-extended = <&intc 74 &omap3_pmx_core OMAP3_UART3_RX>; pinctrl-names = "default"; pinctrl-0 = <&uart3_pins>; };
arch/arm/boot/dts/omap3-n900.dts +2 -0
@@ -512,11 +512,13 @@ }; &uart2 { + interrupts-extended = <&intc 73 &omap3_pmx_core OMAP3_UART2_RX>; pinctrl-names = "default"; pinctrl-0 = <&uart2_pins>; }; &uart3 { + interrupts-extended = <&intc 74 &omap3_pmx_core OMAP3_UART3_RX>; pinctrl-names = "default"; pinctrl-0 = <&uart3_pins>; };
arch/arm/boot/dts/omap3.dtsi +3 -3
@@ -246,7 +246,7 @@ uart1: serial at 4806a000 { compatible = "ti,omap3-uart"; reg = <0x4806a000 0x2000>; - interrupts = <72>; + interrupts-extended = <&intc 72>; dmas = <&sdma 49 &sdma 50>; dma-names = "tx", "rx"; ti,hwmods = "uart1";
@@ -256,7 +256,7 @@ uart2: serial at 4806c000 { compatible = "ti,omap3-uart"; reg = <0x4806c000 0x400>; - interrupts = <73>; + interrupts-extended = <&intc 73>; dmas = <&sdma 51 &sdma 52>; dma-names = "tx", "rx"; ti,hwmods = "uart2";
@@ -266,7 +266,7 @@ uart3: serial at 49020000 { compatible = "ti,omap3-uart"; reg = <0x49020000 0x400>; - interrupts = <74>; + interrupts-extended = <&intc 74>; dmas = <&sdma 53 &sdma 54>; dma-names = "tx", "rx"; ti,hwmods = "uart3";
arch/arm/boot/dts/omap4-panda-common.dtsi +15 -0
@@ -396,6 +396,21 @@ usb-supply = <&vusb>; }; +&uart2 { + interrupts-extended = <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH + &omap4_pmx_core OMAP4_UART2_RX>; +}; + +&uart3 { + interrupts-extended = <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH + &omap4_pmx_core OMAP4_UART3_RX>; +}; + +&uart4 { + interrupts-extended = <&gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH + &omap4_pmx_core OMAP4_UART4_RX>; +}; + &usb_otg_hs { interface-type = <1>; mode = <3>;
arch/arm/boot/dts/omap4-sdp.dts +6 -0
@@ -523,16 +523,22 @@ }; &uart2 { + interrupts-extended = <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH + &omap4_pmx_core OMAP4_UART2_RX>; pinctrl-names = "default"; pinctrl-0 = <&uart2_pins>; }; &uart3 { + interrupts-extended = <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH + &omap4_pmx_core OMAP4_UART3_RX>; pinctrl-names = "default"; pinctrl-0 = <&uart3_pins>; }; &uart4 { + interrupts-extended = <&gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH + &omap4_pmx_core OMAP4_UART4_RX>; pinctrl-names = "default"; pinctrl-0 = <&uart4_pins>; };
arch/arm/boot/dts/omap4.dtsi +3 -3
@@ -288,7 +288,7 @@ uart2: serial at 4806c000 { compatible = "ti,omap4-uart"; reg = <0x4806c000 0x100>; - interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts-extended = <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart2"; clock-frequency = <48000000>; };
@@ -296,7 +296,7 @@ uart3: serial at 48020000 { compatible = "ti,omap4-uart"; reg = <0x48020000 0x100>; - interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; + interrupts-extended = <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart3"; clock-frequency = <48000000>; };
@@ -304,7 +304,7 @@ uart4: serial at 4806e000 { compatible = "ti,omap4-uart"; reg = <0x4806e000 0x100>; - interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; + interrupts-extended = <&gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart4"; clock-frequency = <48000000>; };
include/dt-bindings/pinctrl/omap.h +12 -0
@@ -69,5 +69,17 @@#define OMAP5_WKUP_IOPAD (pa, val) OMAP_IOPAD_OFFSET((pa), 0xc840) (val)#define DRA7XX_CORE_IOPAD (pa, val) OMAP_IOPAD_OFFSET((pa), 0x3400) (val) +/* +* Define some commonly used pins configured by the boards. +* Note that some boards use alternative pins, so check +* the schematics before using these. +*/ +#define OMAP3_UART1_RX 0x152 +#define OMAP3_UART2_RX 0x14a +#define OMAP3_UART3_RX 0x16e +#define OMAP4_UART2_RX 0xdc +#define OMAP4_UART3_RX 0x104 +#define OMAP4_UART4_RX 0x11c +#endif
Signature · 1 line
1.8.1.1
Tony Lindgren
maintainerPATCH 9/11 ARM: OMAP2+: Enable CPUidle in omap2plus_defconfig
In reply to Tony LindgrenEnable CPUidle so it's easier for maintainers to notice if some future code changes cause regressions.
--- arch/arm/configs/omap2plus_defconfig | 7 +++++++ 1 file changed, 7 insertions(+)
arch/arm/configs/omap2plus_defconfig +7 -0
@@ -21,6 +21,8 @@ CONFIG_MODULE_SRCVERSION_ALL=y # CONFIG_BLK_DEV_BSG is not set CONFIG_PARTITION_ADVANCED=y CONFIG_ARCH_MULTI_V6=y +CONFIG_POWER_AVS_OMAP=y +CONFIG_POWER_AVS_OMAP_CLASS3=y CONFIG_OMAP_RESET_CLOCKS=y CONFIG_OMAP_MUX_DEBUG=y CONFIG_ARCH_OMAP2=y
@@ -41,6 +43,7 @@ CONFIG_ARM_ATAG_DTB_COMPAT=y CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200" CONFIG_KEXEC=y CONFIG_FPE_NWFPE=y +CONFIG_CPU_IDLE=y CONFIG_BINFMT_MISC=y CONFIG_PM_DEBUG=y CONFIG_NET=y
@@ -158,11 +161,14 @@ CONFIG_GPIO_SYSFS=y CONFIG_GPIO_TWL4030=y CONFIG_W1=y CONFIG_POWER_SUPPLY=y +CONFIG_POWER_AVS=y CONFIG_SENSORS_LM75=m CONFIG_THERMAL=y CONFIG_THERMAL_GOV_FAIR_SHARE=y CONFIG_THERMAL_GOV_USER_SPACE=y +CONFIG_CPU_THERMAL=y CONFIG_TI_SOC_THERMAL=y +CONFIG_TI_THERMAL=y CONFIG_OMAP4_THERMAL=y CONFIG_OMAP5_THERMAL=y CONFIG_DRA752_THERMAL=y
@@ -175,6 +181,7 @@ CONFIG_MFD_TPS65910=y CONFIG_TWL6040_CORE=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_PALMAS=y +CONFIG_REGULATOR_TI_ABB=y CONFIG_REGULATOR_TPS65023=y CONFIG_REGULATOR_TPS6507X=y CONFIG_REGULATOR_TPS65217=y
Signature · 1 line
1.8.1.1
Tony Lindgren
maintainerPATCH 10/11 mfd: twl-core: Fix idle mode signaling for omaps when booted with device tree
In reply to Tony LindgrenI noticed a regression where the omap sys_clkreq signal will never trigger for omap3 when booted with device tree while it triggers when booted in legacy mode. This means voltage scaling does not do anything when booted with device tree.
Turns out the reason is we fail to initialize the SmartReflex enable bit in twl4030 with the following error:
twl: not initialized
And that happens because we are wrongly tinkering with the twl4030 registers in arch/arm/mach-omap2/omap_twl.c before the driver is initialized. Looking at the the SmartReflex bit enable code in omap_twl.c, we need to always set it.
So let's fix the issue by always enabling the twl4030 SmartReflex bit in the drivers/mfd/twl-core.c probe, and drop the related code in omap_twl.c.
Note that we still have some twl4030 tinkering left in omap_twl.c for the twl6030 case, but that's a different patch.
--- arch/arm/mach-omap2/omap_twl.c | 60 ------------------------------------------ drivers/mfd/twl-core.c | 15 +++++++++++ 2 files changed, 15 insertions(+), 60 deletions(-)
arch/arm/mach-omap2/omap_twl.c +0 -60
@@ -46,15 +46,8 @@static bool is_offset_valid;static u8 smps_offset; -/* -* Flag to ensure Smartreflex bit in TWL -* being cleared in board file is not overwritten. -*/ -static bool __initdata twl_sr_enable_autoinit; -#define TWL4030_DCDC_GLOBAL_CFG 0x06#define REG_SMPS_OFFSET 0xE0 -#define SMARTREFLEX_ENABLE BIT(3)static unsigned long twl4030_vsel_to_uv (const u8 vsel) {
@@ -251,18 +244,6 @@ int __init omap3_twl_init(void)if (!cpu_is_omap34xx ())return -ENODEV ; -/* -* The smartreflex bit on twl4030 specifies if the setting of voltage -* is done over the I2C_SR path. Since this setting is independent of -* the actual usage of smartreflex AVS module, we enable TWL SR bit -* by default irrespective of whether smartreflex AVS module is enabled -* on the OMAP side or not. This is because without this bit enabled, -* the voltage scaling through vp forceupdate/bypass mechanism of -* voltage scaling will not function on TWL over I2C_SR. -*/ -if (!twl_sr_enable_autoinit) -omap3_twl_set_sr_bit (true); - voltdm =voltdm_lookup ("mpu_iva" );omap_voltage_register_pmic (voltdm, &omap3_mpu_pmic);
@@ -271,44 +252,3 @@ int __init omap3_twl_init(void)return 0 ; } - -/** -* omap3_twl_set_sr_bit() - Set/Clear SR bit on TWL -* @enable: enable SR mode in twl or not -* -* If 'enable' is true, enables Smartreflex bit on TWL 4030 to make sure -* voltage scaling through OMAP SR works. Else, the smartreflex bit -* on twl4030 is cleared as there are platforms which use OMAP3 and T2 but -* use Synchronized Scaling Hardware Strategy (ENABLE_VMODE=1) and Direct -* Strategy Software Scaling Mode (ENABLE_VMODE=0), for setting the voltages, -* in those scenarios this bit is to be cleared (enable = false). -* -* Returns 0 on success, error is returned if I2C read/write fails. -*/ -int __init omap3_twl_set_sr_bit (bool enable) -{ -u8 temp; -int ret; -if (twl_sr_enable_autoinit) -pr_warning ("%s: unexpected multiple calls\n" , __func__); - - ret =twl_i2c_read_u8 (TWL_MODULE_PM_RECEIVER , &temp, -TWL4030_DCDC_GLOBAL_CFG ); -if (ret) - goto err; - -if (enable) - temp |=SMARTREFLEX_ENABLE ; -else - temp &= ~SMARTREFLEX_ENABLE ; - - ret =twl_i2c_write_u8 (TWL_MODULE_PM_RECEIVER , temp, -TWL4030_DCDC_GLOBAL_CFG ); -if (!ret) { - twl_sr_enable_autoinit = true; -return 0 ; - } -err: -pr_err ("%s: Error access to TWL4030 (%d)\n" , __func__, ret); -return ret; -}
drivers/mfd/twl-core.c +15 -0
@@ -98,7 +98,11 @@#define TWL4030_BASEADD_BACKUP 0x0014#define TWL4030_BASEADD_INT 0x002E#define TWL4030_BASEADD_PM_MASTER 0x0036 +#define TWL4030_BASEADD_PM_RECEIVER 0x005B +#define TWL4030_DCDC_GLOBAL_CFG 0x06 +#define SMARTREFLEX_ENABLE BIT(3) +#define TWL4030_BASEADD_RTC 0x001C#define TWL4030_BASEADD_SECURED_REG 0x0000
@@ -1204,6 +1208,11 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)* Disable TWL4030/TWL5030 I2C Pull-up on I2C1 and I2C4(SR) interface. * Program I2C_SCL_CTRL_PU(bit 0)=0, I2C_SDA_CTRL_PU (bit 2)=0, * SR_I2C_SCL_CTRL_PU(bit 4)=0 and SR_I2C_SDA_CTRL_PU(bit 6)=0. +* +* Also, always enable SmartReflex bit as that's needed for omaps to +* to do anything over I2C4 for voltage scaling even if SmartReflex +* is disabled. Without the SmartReflex bit omap sys_clkreq idle +* signal will never trigger for retention idle. */ if (twl_class_is_4030 ()) {u8 temp;
@@ -1212,6 +1221,12 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) temp &= ~(SR_I2C_SDA_CTRL_PU |SR_I2C_SCL_CTRL_PU | \I2C_SDA_CTRL_PU |I2C_SCL_CTRL_PU );twl_i2c_write_u8 (TWL4030_MODULE_INTBR , temp,REG_GPPUPDCTR1 ); + +twl_i2c_read_u8 (TWL_MODULE_PM_RECEIVER , &temp, +TWL4030_DCDC_GLOBAL_CFG ); + temp |=SMARTREFLEX_ENABLE ; +twl_i2c_write_u8 (TWL_MODULE_PM_RECEIVER , temp, +TWL4030_DCDC_GLOBAL_CFG ); }if (node) {
Signature · 1 line
1.8.1.1
PATCH 10/11 mfd: twl-core: Fix idle mode signaling for omaps when booted with device tree
Quoted 29 lines
I noticed a regression where the omap
sys_clkreqsignal will never trigger for omap3 when booted with device tree while it triggers when booted in legacy mode. This means voltage scaling does not do anything when booted with device tree.Turns out the reason is we fail to initialize the SmartReflex enable bit in twl4030 with the following error:
twl: not initialized
And that happens because we are wrongly tinkering with the twl4030 registers in
arch/arm/mach-omap2/omap_twl.cbefore the driver is initialized. Looking at the the SmartReflex bit enable code inomap_twl.c, we need to always set it.So let's fix the issue by always enabling the twl4030 SmartReflex bit in the
drivers/mfd/twl-core.cprobe, and drop the related code inomap_twl.c.Note that we still have some twl4030 tinkering left in
omap_twl.cfor the twl6030 case, but that's a different patch.Cc Kevin Hilman <[email protected]>Cc Lee Jones <[email protected]>Cc Nishanth Menon <[email protected]>Cc Samuel Ortiz <[email protected]>Cc Paul Walmsley <[email protected]>Cc Tero Kristo <[email protected]>Signed-off-by Tony Lindgren <[email protected]>
Quoted 4 lines
--- arch/arm/mach-omap2/omap_twl.c | 60 ------------------------------------------ drivers/mfd/twl-core.c | 15 +++++++++++ 2 files changed, 15 insertions(+), 60 deletions(-)
Patch looks okay to me, and removes lots of code which is nice to see. How do you want to handle this patch? How about if I set up an MFD-OMAP immutable branch for us to use leading up to the v3.16 merge window?
Signature · 4 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org ? Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog
Tony Lindgren
maintainerPATCH 10/11 mfd: twl-core: Fix idle mode signaling for omaps when booted with device tree
Quoted 34 lines · Lee Jones
Quoted 29 lines
I noticed a regression where the omap
sys_clkreqsignal will never trigger for omap3 when booted with device tree while it triggers when booted in legacy mode. This means voltage scaling does not do anything when booted with device tree.Turns out the reason is we fail to initialize the SmartReflex enable bit in twl4030 with the following error:
twl: not initialized
And that happens because we are wrongly tinkering with the twl4030 registers in
arch/arm/mach-omap2/omap_twl.cbefore the driver is initialized. Looking at the the SmartReflex bit enable code inomap_twl.c, we need to always set it.So let's fix the issue by always enabling the twl4030 SmartReflex bit in the
drivers/mfd/twl-core.cprobe, and drop the related code inomap_twl.c.Note that we still have some twl4030 tinkering left in
omap_twl.cfor the twl6030 case, but that's a different patch.Cc Kevin Hilman <[email protected]>Cc Lee Jones <[email protected]>Cc Nishanth Menon <[email protected]>Cc Samuel Ortiz <[email protected]>Cc Paul Walmsley <[email protected]>Cc Tero Kristo <[email protected]>Signed-off-by Tony Lindgren <[email protected]>Quoted 4 lines
--- arch/arm/mach-omap2/omap_twl.c | 60 ------------------------------------------ drivers/mfd/twl-core.c | 15 +++++++++++ 2 files changed, 15 insertions(+), 60 deletions(-)
Quoted 4 lines
Patch looks okay to me, and removes lots of code which is nice to see. How do you want to handle this patch? How about if I set up an MFD-OMAP immutable branch for us to use leading up to the v3.16 merge window?
Yes, that would be good thanks. Can you please set up the immutable branch against v3.14 for this, that should merge just fine against v3.15-rc AFAIK.
I have also DT support coming up for drivers/mfd/twl4030-power.c generic configuration that can then go into the same branch when ready.
Regards,
Tony
Quoted 7 lines
Acked-by Lee Jones <[email protected]>Signature · 4 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org ? Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog
[GIT PULL] arm: omap: Immutable branch between MFD and ARM OMAP due for the v3.16 merge-window
Hi Tony,
Sorry for the delay - I've been snowed under recently.
As requested, you patch based on v3.14 ( for some reason :) ).
The following changes since commit 455c6fdbd219161bd09b1165f11699d6d73de11c:
Linux 3.14 (2014-03-30 20:40:15 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git tags/ib-mfd-omap-3.16
for you to fetch changes up to a613b739b8c08eab811e677810045cc0522fc3e6:
mfd: twl-core: Fix idle mode signaling for omaps when booted with device tree (2014-04-23 15:31:05 +0100)
----------------------------------------------------------------
Immutable branch between MFD and ARM OMAP due for v3.16 merge-window.
----------------------------------------------------------------
Tony Lindgren (1):
mfd: twl-core: Fix idle mode signaling for omaps when booted with device tree
arch/arm/mach-omap2/omap_twl.c | 60 ------------------------------------------------------------ drivers/mfd/twl-core.c | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 60 deletions(-)
Signature · 4 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org ? Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog
Tony Lindgren
maintainer[GIT PULL] arm: omap: Immutable branch between MFD and ARM OMAP due for the v3.16 merge-window
Quoted 5 lines · Lee Jones
Hi Tony,
Sorry for the delay - I've been snowed under recently.
As requested, you patch based on v3.14 ( for some reason :) ).
Thanks, I just got tired of chasing regressions with the -rc cycle while trying to work on some PM changes :)
Regards,
Tony
Quoted 28 lines
The following changes since commit
455c6fdbd219161bd09b1165f11699d6d73de11c:Linux 3.14 (2014-03-30 20:40:15 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.gittags/ib-mfd-omap-3.16for you to fetch changes up to
a613b739b8c08eab811e677810045cc0522fc3e6:mfd: twl-core: Fix idle mode signaling for omaps when booted with device tree (2014-04-23 15:31:05 +0100)
----------------------------------------------------------------
Immutable branch between MFD and ARM OMAP due for v3.16 merge-window.----------------------------------------------------------------
Tony Lindgren (1):
mfd: twl-core: Fix idle mode signaling for omaps when booted with device treearch/arm/mach-omap2/omap_twl.c | 60 ------------------------------------------------------------ drivers/mfd/twl-core.c | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 60 deletions(-)Signature · 4 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org ? Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog
Tony Lindgren
maintainerPATCH 11/11 pinctrl: single: Clear pin interrupts enabled by bootloader
In reply to Tony LindgrenSince we set up device wake-up interrupts as pinctrl-single interrupts, we now must use the standard request_irq and related functions to manage them.
If the pin interrupts are enabled for some pins at boot, the wake-up events can show up as constantly pending at least on omaps and will hang the system unless the related device driver clears the event at the device.
To fix this, let's clear the interrupt flags during init, and print out a warning so the board maintainers can update their drivers to do proper request_irq for the driver specific wake-up events.
--- drivers/pinctrl/pinctrl-single.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
drivers/pinctrl/pinctrl-single.c +13 -0
@@ -808,6 +808,7 @@ static const struct pinconf_ops pcs_pinconf_ops = {static int pcs_add_pin (struct pcs_device *pcs,unsigned offset,unsigned pin_pos) { +struct pcs_soc_data *pcs_soc = &pcs->socdata;struct pinctrl_pin_desc *pin;struct pcs_name *pn;int i;
@@ -819,6 +820,18 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset,return -ENOMEM ; } +if (pcs_soc->irq_enable_mask) { +unsigned val; + + val = pcs->read (pcs->base + offset); +if (val & pcs_soc->irq_enable_mask) { +dev_dbg (pcs->dev,"irq enabled at boot for pin at %lx (%x), clearing\n" , + (unsigned long )pcs->res->start + offset, val); + val &= ~pcs_soc->irq_enable_mask; + pcs->write (val, pcs->base + offset); + } + } + pin = &pcs->pins.pa[i]; pn = &pcs->names[i]; sprintf(pn->name, "%lx.%d",
Signature · 1 line
1.8.1.1
PATCH 11/11 pinctrl: single: Clear pin interrupts enabled by bootloader
Quoted 9 lines · Tony Lindgren
Since we set up device wake-up interrupts as pinctrl-single interrupts, we now must use the standard
request_irqand related functions to manage them.If the pin interrupts are enabled for some pins at boot, the wake-up events can show up as constantly pending at least on omaps and will hang the system unless the related device driver clears the event at the device.
Quoted 8 lines
To fix this, let's clear the interrupt flags during init, and print out a warning so the board maintainers can update their drivers to do proper
request_irqfor the driver specific wake-up events.Cc Haojian Zhuang <[email protected]>Cc Linus Walleij <[email protected]>Signed-off-by Tony Lindgren <[email protected]>
Looks clean.
Shall I apply this patch or will you funnel it through ARM SoC due to deps?
Yours,
Linus Walleij
Tony Lindgren
maintainerPATCH 11/11 pinctrl: single: Clear pin interrupts enabled by bootloader
Quoted 20 lines · Linus Walleij
Quoted 9 lines · Tony Lindgren
Since we set up device wake-up interrupts as pinctrl-single interrupts, we now must use the standard
request_irqand related functions to manage them.If the pin interrupts are enabled for some pins at boot, the wake-up events can show up as constantly pending at least on omaps and will hang the system unless the related device driver clears the event at the device.
Quoted 8 lines
To fix this, let's clear the interrupt flags during init, and print out a warning so the board maintainers can update their drivers to do proper
request_irqfor the driver specific wake-up events.Cc Haojian Zhuang <[email protected]>Cc Linus Walleij <[email protected]>Signed-off-by Tony Lindgren <[email protected]>
Quoted 6 lines
Looks clean.
Acked-by Linus Walleij <[email protected]>Shall I apply this patch or will you funnel it through ARM SoC due to deps?
No deps except boards hanging without it.. Please feel free to take this one, prererrably as a fix for the -rc series if no objections.
Regards,
Tony
PATCH 11/11 pinctrl: single: Clear pin interrupts enabled by bootloader
Quoted 6 lines · Tony Lindgren
Quoted 2 lines
Shall I apply this patch or will you funnel it through ARM SoC due to deps?
No deps except boards hanging without it.. Please feel free to take this one, prererrably as a fix for the -rc series if no objections.
Yes this is -rc material. Queued for fixes. Thanks!
Yours,
Linus Walleij
cover Fixes for omap PM for making omap3 DT only
In reply to Tony LindgrenHi Tony,
Quoted 9 lines · Tony Lindgren
As we're planning to make omap3 device tree only soon, I was poking around and noticed that PM is not working properly. As we're planning to drop about 20k lines of code, I just had to try to fix this so we know what is going on and don't have to go back. I was pretty bummed out to find that we've had non-working PM code in mainline for really long time.
Anyways, I got the voltage scaling and N900 debug leds working, so with those we can notice any future regressions immediately :)
cool :)
Quoted 9 lines
These are against v3.14, then you might want to also apply the following two patches:
[PATCH] of/platform: Fix no irq domain found errors when populating interrupts
https://lkml.org/lkml/2014/4/10/620[PATCH] serial: omap: Fix missing
pm_runtime_resumehandling by simplifying code
http://www.spinics.net/lists/linux-omap/msg104782.html
Quoted 8 lines
Note that for the actual voltage scaling to happen, the twl4030 PMIC scripts are also needed. I have some uncleaned patches to load those based on the compatible flag, will post those separately. This series alone fixes the idle state signaling to the PMIC, so we can monitor
sys_clkreqandsys_off_idlepins properly.Please review, comment and test,
I'm on vacation from tomorrow until next week's weekend, but I will have a look the week after next (if still needed).
I have not yet read much of TWL/OMAP PM documentation, but I wonder if it makes sense to move the powerscripting stuff into the DTS file somehow. On a first look the added N900 tables in drivers/mfd/twl4030-power.c seem like a step back to me.
-- Sebastian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140411/b58efdb5/attachment.sig>
Tony Lindgren
maintainercover Fixes for omap PM for making omap3 DT only
Quoted 3 lines · Sebastian Reichel
I'm on vacation from tomorrow until next week's weekend, but I will have a look the week after next (if still needed).
OK
Quoted 4 lines
I have not yet read much of TWL/OMAP PM documentation, but I wonder if it makes sense to move the powerscripting stuff into the DTS file somehow. On a first look the added N900 tables in
drivers/mfd/twl4030-power.cseem like a step back to me.
Need to think about it a bit more, but I think we can have generic scripts based on the tables in "Recommended Sleep Sequences for the Zoom Platform" pdf at:
http://omappedia.com/wiki/File:Recommended_Sleep_Sequences_Zoom.pdf
Then we can have a function that patches in board specific stuff as needed as changes to the generic rconfig table.
I'll take a look at that, let's see how that works. If that works, the board specific increments to the generic data should be pretty small and the data can easily live in the twl4030-power.c with no need to stuff it into the .dts files.
BTW, the situation is also a bit different from the original N900 kernel as we now have runtime PM and drivers can easily manage their regulators.
Regards,
Tony