* [PATCH] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection
@ 2011-10-06 19:11 ` Paul Walmsley
0 siblings, 0 replies; 22+ messages in thread
From: Paul Walmsley @ 2011-10-06 19:11 UTC (permalink / raw)
To: linux-omap, linux-arm-kernel; +Cc: khilman, dhylands, sakoman
The way that we detect which OMAP3 chips support I/O wakeup and
software I/O chain clock control is broken.
Currently, I/O wakeup is marked as present for all OMAP3 SoCs other
than the AM3505/3517. The TI81xx family of SoCs are at present
considered to be OMAP3 SoCs, but don't support I/O wakeup. To resolve
this, convert the existing blacklist approach to an explicit,
whitelist support, in which only SoCs which are known to support I/O
wakeup are listed. (At present, this only includes OMAP34xx,
OMAP3503, OMAP3515, OMAP3525, OMAP3530, and OMAP36xx.)
Also, the current code incorrectly detects the presence of a
software-controllable I/O chain clock on several chips that don't
support it. This results in writes to reserved bitfields, unnecessary
delays, and console messages on kernels running on those chips:
http://www.spinics.net/lists/linux-omap/msg58735.html
Convert this test to a feature test with a chip-by-chip whitelist.
Thanks to Dave Hylands <dhylands@gmail.com> for reporting this problem
and doing some testing to help isolate the cause.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>
Cc: Dave Hylands <dhylands@gmail.com>
Cc: Steve Sakoman <sakoman@gmail.com>
---
arch/arm/mach-omap2/id.c | 6 +++-
arch/arm/mach-omap2/pm34xx.c | 44 +++++++++++++++++---------------
arch/arm/plat-omap/include/plat/cpu.h | 17 +++++++++---
3 files changed, 40 insertions(+), 27 deletions(-)
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 37efb86..eb1b8e4 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -201,8 +201,12 @@ static void __init omap3_check_features(void)
OMAP3_CHECK_FEATURE(status, ISP);
if (cpu_is_omap3630())
omap_features |= OMAP3_HAS_192MHZ_CLK;
- if (!cpu_is_omap3505() && !cpu_is_omap3517())
+ if (cpu_is_omap3430() || cpu_is_omap3630())
omap_features |= OMAP3_HAS_IO_WAKEUP;
+ if ((omap_rev() == OMAP3430_REV_ES3_1 &&
+ omap_rev() == OMAP3430_REV_ES3_1_2) ||
+ cpu_is_omap3630())
+ omap_features |= OMAP3_HAS_IO_CHAIN_CTRL;
omap_features |= OMAP3_HAS_SDRC;
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 7255d9b..a6156bd 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -99,31 +99,28 @@ static void omap3_enable_io_chain(void)
{
int timeout = 0;
- if (omap_rev() >= OMAP3430_REV_ES3_1) {
- omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
- PM_WKEN);
- /* Do a readback to assure write has been done */
- omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
-
- while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) &
- OMAP3430_ST_IO_CHAIN_MASK)) {
- timeout++;
- if (timeout > 1000) {
- printk(KERN_ERR "Wake up daisy chain "
- "activation failed.\n");
- return;
- }
- omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK,
- WKUP_MOD, PM_WKEN);
+ omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
+ PM_WKEN);
+ /* Do a readback to assure write has been done */
+ omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
+
+ while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) &
+ OMAP3430_ST_IO_CHAIN_MASK)) {
+ timeout++;
+ if (timeout > 1000) {
+ printk(KERN_ERR "Wake up daisy chain "
+ "activation failed.\n");
+ return;
}
+ omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK,
+ WKUP_MOD, PM_WKEN);
}
}
static void omap3_disable_io_chain(void)
{
- if (omap_rev() >= OMAP3430_REV_ES3_1)
- omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
- PM_WKEN);
+ omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
+ PM_WKEN);
}
static void omap3_core_save_context(void)
@@ -376,7 +373,8 @@ void omap_sram_idle(void)
(per_next_state < PWRDM_POWER_ON ||
core_next_state < PWRDM_POWER_ON)) {
omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN);
- omap3_enable_io_chain();
+ if (omap3_has_io_chain_ctrl())
+ omap3_enable_io_chain();
}
/* Block console output in case it is on one of the OMAP UARTs */
@@ -475,7 +473,8 @@ console_still_active:
core_next_state < PWRDM_POWER_ON)) {
omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
PM_WKEN);
- omap3_disable_io_chain();
+ if (omap3_has_io_chain_ctrl())
+ omap3_disable_io_chain();
}
pwrdm_post_transition();
@@ -870,6 +869,9 @@ static int __init omap3_pm_init(void)
if (!cpu_is_omap34xx())
return -ENODEV;
+ if (!omap3_has_io_chain_ctrl())
+ pr_warning("PM: no software I/O chain control; some wakeups may be lost\n");
+
pm_errata_configure();
/* XXX prcm_setup_regs needs to be before enabling hw
diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h
index 67b3d75..3a280aa 100644
--- a/arch/arm/plat-omap/include/plat/cpu.h
+++ b/arch/arm/plat-omap/include/plat/cpu.h
@@ -477,6 +477,13 @@ void omap2_check_revision(void);
/*
* Runtime detection of OMAP3 features
+ *
+ * OMAP3_HAS_IO_CHAIN_CTRL: Some later members of the OMAP3 chip
+ * family have OS-level control over the I/O chain clock. This is
+ * to avoid a window during which wakeups could potentially be lost
+ * during powerdomain transitions. If this bit is set, it
+ * indicates that the chip does support OS-level control of this
+ * feature.
*/
extern u32 omap_features;
@@ -488,9 +495,10 @@ extern u32 omap_features;
#define OMAP3_HAS_192MHZ_CLK BIT(5)
#define OMAP3_HAS_IO_WAKEUP BIT(6)
#define OMAP3_HAS_SDRC BIT(7)
-#define OMAP4_HAS_MPU_1GHZ BIT(8)
-#define OMAP4_HAS_MPU_1_2GHZ BIT(9)
-#define OMAP4_HAS_MPU_1_5GHZ BIT(10)
+#define OMAP3_HAS_IO_CHAIN_CTRL BIT(8)
+#define OMAP4_HAS_MPU_1GHZ BIT(9)
+#define OMAP4_HAS_MPU_1_2GHZ BIT(10)
+#define OMAP4_HAS_MPU_1_5GHZ BIT(11)
#define OMAP3_HAS_FEATURE(feat,flag) \
@@ -507,12 +515,11 @@ OMAP3_HAS_FEATURE(isp, ISP)
OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK)
OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP)
OMAP3_HAS_FEATURE(sdrc, SDRC)
+OMAP3_HAS_FEATURE(io_chain_ctrl, IO_CHAIN_CTRL)
/*
* Runtime detection of OMAP4 features
*/
-extern u32 omap_features;
-
#define OMAP4_HAS_FEATURE(feat, flag) \
static inline unsigned int omap4_has_ ##feat(void) \
{ \
--
1.7.6.3
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCH] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection @ 2011-10-06 19:11 ` Paul Walmsley 0 siblings, 0 replies; 22+ messages in thread From: Paul Walmsley @ 2011-10-06 19:11 UTC (permalink / raw) To: linux-arm-kernel The way that we detect which OMAP3 chips support I/O wakeup and software I/O chain clock control is broken. Currently, I/O wakeup is marked as present for all OMAP3 SoCs other than the AM3505/3517. The TI81xx family of SoCs are at present considered to be OMAP3 SoCs, but don't support I/O wakeup. To resolve this, convert the existing blacklist approach to an explicit, whitelist support, in which only SoCs which are known to support I/O wakeup are listed. (At present, this only includes OMAP34xx, OMAP3503, OMAP3515, OMAP3525, OMAP3530, and OMAP36xx.) Also, the current code incorrectly detects the presence of a software-controllable I/O chain clock on several chips that don't support it. This results in writes to reserved bitfields, unnecessary delays, and console messages on kernels running on those chips: http://www.spinics.net/lists/linux-omap/msg58735.html Convert this test to a feature test with a chip-by-chip whitelist. Thanks to Dave Hylands <dhylands@gmail.com> for reporting this problem and doing some testing to help isolate the cause. Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: Kevin Hilman <khilman@ti.com> Cc: Dave Hylands <dhylands@gmail.com> Cc: Steve Sakoman <sakoman@gmail.com> --- arch/arm/mach-omap2/id.c | 6 +++- arch/arm/mach-omap2/pm34xx.c | 44 +++++++++++++++++--------------- arch/arm/plat-omap/include/plat/cpu.h | 17 +++++++++--- 3 files changed, 40 insertions(+), 27 deletions(-) diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 37efb86..eb1b8e4 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -201,8 +201,12 @@ static void __init omap3_check_features(void) OMAP3_CHECK_FEATURE(status, ISP); if (cpu_is_omap3630()) omap_features |= OMAP3_HAS_192MHZ_CLK; - if (!cpu_is_omap3505() && !cpu_is_omap3517()) + if (cpu_is_omap3430() || cpu_is_omap3630()) omap_features |= OMAP3_HAS_IO_WAKEUP; + if ((omap_rev() == OMAP3430_REV_ES3_1 && + omap_rev() == OMAP3430_REV_ES3_1_2) || + cpu_is_omap3630()) + omap_features |= OMAP3_HAS_IO_CHAIN_CTRL; omap_features |= OMAP3_HAS_SDRC; diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 7255d9b..a6156bd 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -99,31 +99,28 @@ static void omap3_enable_io_chain(void) { int timeout = 0; - if (omap_rev() >= OMAP3430_REV_ES3_1) { - omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, - PM_WKEN); - /* Do a readback to assure write has been done */ - omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); - - while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & - OMAP3430_ST_IO_CHAIN_MASK)) { - timeout++; - if (timeout > 1000) { - printk(KERN_ERR "Wake up daisy chain " - "activation failed.\n"); - return; - } - omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, - WKUP_MOD, PM_WKEN); + omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, + PM_WKEN); + /* Do a readback to assure write has been done */ + omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); + + while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & + OMAP3430_ST_IO_CHAIN_MASK)) { + timeout++; + if (timeout > 1000) { + printk(KERN_ERR "Wake up daisy chain " + "activation failed.\n"); + return; } + omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, + WKUP_MOD, PM_WKEN); } } static void omap3_disable_io_chain(void) { - if (omap_rev() >= OMAP3430_REV_ES3_1) - omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, - PM_WKEN); + omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, + PM_WKEN); } static void omap3_core_save_context(void) @@ -376,7 +373,8 @@ void omap_sram_idle(void) (per_next_state < PWRDM_POWER_ON || core_next_state < PWRDM_POWER_ON)) { omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); - omap3_enable_io_chain(); + if (omap3_has_io_chain_ctrl()) + omap3_enable_io_chain(); } /* Block console output in case it is on one of the OMAP UARTs */ @@ -475,7 +473,8 @@ console_still_active: core_next_state < PWRDM_POWER_ON)) { omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); - omap3_disable_io_chain(); + if (omap3_has_io_chain_ctrl()) + omap3_disable_io_chain(); } pwrdm_post_transition(); @@ -870,6 +869,9 @@ static int __init omap3_pm_init(void) if (!cpu_is_omap34xx()) return -ENODEV; + if (!omap3_has_io_chain_ctrl()) + pr_warning("PM: no software I/O chain control; some wakeups may be lost\n"); + pm_errata_configure(); /* XXX prcm_setup_regs needs to be before enabling hw diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 67b3d75..3a280aa 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -477,6 +477,13 @@ void omap2_check_revision(void); /* * Runtime detection of OMAP3 features + * + * OMAP3_HAS_IO_CHAIN_CTRL: Some later members of the OMAP3 chip + * family have OS-level control over the I/O chain clock. This is + * to avoid a window during which wakeups could potentially be lost + * during powerdomain transitions. If this bit is set, it + * indicates that the chip does support OS-level control of this + * feature. */ extern u32 omap_features; @@ -488,9 +495,10 @@ extern u32 omap_features; #define OMAP3_HAS_192MHZ_CLK BIT(5) #define OMAP3_HAS_IO_WAKEUP BIT(6) #define OMAP3_HAS_SDRC BIT(7) -#define OMAP4_HAS_MPU_1GHZ BIT(8) -#define OMAP4_HAS_MPU_1_2GHZ BIT(9) -#define OMAP4_HAS_MPU_1_5GHZ BIT(10) +#define OMAP3_HAS_IO_CHAIN_CTRL BIT(8) +#define OMAP4_HAS_MPU_1GHZ BIT(9) +#define OMAP4_HAS_MPU_1_2GHZ BIT(10) +#define OMAP4_HAS_MPU_1_5GHZ BIT(11) #define OMAP3_HAS_FEATURE(feat,flag) \ @@ -507,12 +515,11 @@ OMAP3_HAS_FEATURE(isp, ISP) OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK) OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP) OMAP3_HAS_FEATURE(sdrc, SDRC) +OMAP3_HAS_FEATURE(io_chain_ctrl, IO_CHAIN_CTRL) /* * Runtime detection of OMAP4 features */ -extern u32 omap_features; - #define OMAP4_HAS_FEATURE(feat, flag) \ static inline unsigned int omap4_has_ ##feat(void) \ { \ -- 1.7.6.3 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection 2011-10-06 19:11 ` Paul Walmsley @ 2011-10-06 19:42 ` Steve Sakoman -1 siblings, 0 replies; 22+ messages in thread From: Steve Sakoman @ 2011-10-06 19:42 UTC (permalink / raw) To: Paul Walmsley; +Cc: linux-omap, linux-arm-kernel, khilman, dhylands On Thu, Oct 6, 2011 at 12:11 PM, Paul Walmsley <paul@pwsan.com> wrote: > > The way that we detect which OMAP3 chips support I/O wakeup and > software I/O chain clock control is broken. > > Currently, I/O wakeup is marked as present for all OMAP3 SoCs other > than the AM3505/3517. The TI81xx family of SoCs are at present > considered to be OMAP3 SoCs, but don't support I/O wakeup. To resolve > this, convert the existing blacklist approach to an explicit, > whitelist support, in which only SoCs which are known to support I/O > wakeup are listed. (At present, this only includes OMAP34xx, > OMAP3503, OMAP3515, OMAP3525, OMAP3530, and OMAP36xx.) > > Also, the current code incorrectly detects the presence of a > software-controllable I/O chain clock on several chips that don't > support it. This results in writes to reserved bitfields, unnecessary > delays, and console messages on kernels running on those chips: > > http://www.spinics.net/lists/linux-omap/msg58735.html > > Convert this test to a feature test with a chip-by-chip whitelist. > > Thanks to Dave Hylands <dhylands@gmail.com> for reporting this problem > and doing some testing to help isolate the cause. Thanks for doing this patch so quickly! > Signed-off-by: Paul Walmsley <paul@pwsan.com> > Cc: Kevin Hilman <khilman@ti.com> > Cc: Dave Hylands <dhylands@gmail.com> > Cc: Steve Sakoman <sakoman@gmail.com> > --- > arch/arm/mach-omap2/id.c | 6 +++- > arch/arm/mach-omap2/pm34xx.c | 44 +++++++++++++++++--------------- > arch/arm/plat-omap/include/plat/cpu.h | 17 +++++++++--- > 3 files changed, 40 insertions(+), 27 deletions(-) > > diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c > index 37efb86..eb1b8e4 100644 > --- a/arch/arm/mach-omap2/id.c > +++ b/arch/arm/mach-omap2/id.c > @@ -201,8 +201,12 @@ static void __init omap3_check_features(void) > OMAP3_CHECK_FEATURE(status, ISP); > if (cpu_is_omap3630()) > omap_features |= OMAP3_HAS_192MHZ_CLK; > - if (!cpu_is_omap3505() && !cpu_is_omap3517()) > + if (cpu_is_omap3430() || cpu_is_omap3630()) > omap_features |= OMAP3_HAS_IO_WAKEUP; > + if ((omap_rev() == OMAP3430_REV_ES3_1 && > + omap_rev() == OMAP3430_REV_ES3_1_2) || Perhaps I'm confused but shouldn't it be an || instead of &&? We're testing for ES3.1 *or* ES3.12? Otherwise looks good. I'll test on my old Overo COMs. Steve > + cpu_is_omap3630()) > + omap_features |= OMAP3_HAS_IO_CHAIN_CTRL; > > omap_features |= OMAP3_HAS_SDRC; > > diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c > index 7255d9b..a6156bd 100644 > --- a/arch/arm/mach-omap2/pm34xx.c > +++ b/arch/arm/mach-omap2/pm34xx.c > @@ -99,31 +99,28 @@ static void omap3_enable_io_chain(void) > { > int timeout = 0; > > - if (omap_rev() >= OMAP3430_REV_ES3_1) { > - omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, > - PM_WKEN); > - /* Do a readback to assure write has been done */ > - omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); > - > - while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & > - OMAP3430_ST_IO_CHAIN_MASK)) { > - timeout++; > - if (timeout > 1000) { > - printk(KERN_ERR "Wake up daisy chain " > - "activation failed.\n"); > - return; > - } > - omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, > - WKUP_MOD, PM_WKEN); > + omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, > + PM_WKEN); > + /* Do a readback to assure write has been done */ > + omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); > + > + while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & > + OMAP3430_ST_IO_CHAIN_MASK)) { > + timeout++; > + if (timeout > 1000) { > + printk(KERN_ERR "Wake up daisy chain " > + "activation failed.\n"); > + return; > } > + omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, > + WKUP_MOD, PM_WKEN); > } > } > > static void omap3_disable_io_chain(void) > { > - if (omap_rev() >= OMAP3430_REV_ES3_1) > - omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, > - PM_WKEN); > + omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, > + PM_WKEN); > } > > static void omap3_core_save_context(void) > @@ -376,7 +373,8 @@ void omap_sram_idle(void) > (per_next_state < PWRDM_POWER_ON || > core_next_state < PWRDM_POWER_ON)) { > omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); > - omap3_enable_io_chain(); > + if (omap3_has_io_chain_ctrl()) > + omap3_enable_io_chain(); > } > > /* Block console output in case it is on one of the OMAP UARTs */ > @@ -475,7 +473,8 @@ console_still_active: > core_next_state < PWRDM_POWER_ON)) { > omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, > PM_WKEN); > - omap3_disable_io_chain(); > + if (omap3_has_io_chain_ctrl()) > + omap3_disable_io_chain(); > } > > pwrdm_post_transition(); > @@ -870,6 +869,9 @@ static int __init omap3_pm_init(void) > if (!cpu_is_omap34xx()) > return -ENODEV; > > + if (!omap3_has_io_chain_ctrl()) > + pr_warning("PM: no software I/O chain control; some wakeups may be lost\n"); > + > pm_errata_configure(); > > /* XXX prcm_setup_regs needs to be before enabling hw > diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h > index 67b3d75..3a280aa 100644 > --- a/arch/arm/plat-omap/include/plat/cpu.h > +++ b/arch/arm/plat-omap/include/plat/cpu.h > @@ -477,6 +477,13 @@ void omap2_check_revision(void); > > /* > * Runtime detection of OMAP3 features > + * > + * OMAP3_HAS_IO_CHAIN_CTRL: Some later members of the OMAP3 chip > + * family have OS-level control over the I/O chain clock. This is > + * to avoid a window during which wakeups could potentially be lost > + * during powerdomain transitions. If this bit is set, it > + * indicates that the chip does support OS-level control of this > + * feature. > */ > extern u32 omap_features; > > @@ -488,9 +495,10 @@ extern u32 omap_features; > #define OMAP3_HAS_192MHZ_CLK BIT(5) > #define OMAP3_HAS_IO_WAKEUP BIT(6) > #define OMAP3_HAS_SDRC BIT(7) > -#define OMAP4_HAS_MPU_1GHZ BIT(8) > -#define OMAP4_HAS_MPU_1_2GHZ BIT(9) > -#define OMAP4_HAS_MPU_1_5GHZ BIT(10) > +#define OMAP3_HAS_IO_CHAIN_CTRL BIT(8) > +#define OMAP4_HAS_MPU_1GHZ BIT(9) > +#define OMAP4_HAS_MPU_1_2GHZ BIT(10) > +#define OMAP4_HAS_MPU_1_5GHZ BIT(11) > > > #define OMAP3_HAS_FEATURE(feat,flag) \ > @@ -507,12 +515,11 @@ OMAP3_HAS_FEATURE(isp, ISP) > OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK) > OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP) > OMAP3_HAS_FEATURE(sdrc, SDRC) > +OMAP3_HAS_FEATURE(io_chain_ctrl, IO_CHAIN_CTRL) > > /* > * Runtime detection of OMAP4 features > */ > -extern u32 omap_features; > - > #define OMAP4_HAS_FEATURE(feat, flag) \ > static inline unsigned int omap4_has_ ##feat(void) \ > { \ > -- > 1.7.6.3 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-omap" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection @ 2011-10-06 19:42 ` Steve Sakoman 0 siblings, 0 replies; 22+ messages in thread From: Steve Sakoman @ 2011-10-06 19:42 UTC (permalink / raw) To: linux-arm-kernel On Thu, Oct 6, 2011 at 12:11 PM, Paul Walmsley <paul@pwsan.com> wrote: > > The way that we detect which OMAP3 chips support I/O wakeup and > software I/O chain clock control is broken. > > Currently, I/O wakeup is marked as present for all OMAP3 SoCs other > than the AM3505/3517. ?The TI81xx family of SoCs are at present > considered to be OMAP3 SoCs, but don't support I/O wakeup. ?To resolve > this, convert the existing blacklist approach to an explicit, > whitelist support, in which only SoCs which are known to support I/O > wakeup are listed. ?(At present, this only includes OMAP34xx, > OMAP3503, OMAP3515, OMAP3525, OMAP3530, and OMAP36xx.) > > Also, the current code incorrectly detects the presence of a > software-controllable I/O chain clock on several chips that don't > support it. ?This results in writes to reserved bitfields, unnecessary > delays, and console messages on kernels running on those chips: > > ? ?http://www.spinics.net/lists/linux-omap/msg58735.html > > Convert this test to a feature test with a chip-by-chip whitelist. > > Thanks to Dave Hylands <dhylands@gmail.com> for reporting this problem > and doing some testing to help isolate the cause. Thanks for doing this patch so quickly! > Signed-off-by: Paul Walmsley <paul@pwsan.com> > Cc: Kevin Hilman <khilman@ti.com> > Cc: Dave Hylands <dhylands@gmail.com> > Cc: Steve Sakoman <sakoman@gmail.com> > --- > ?arch/arm/mach-omap2/id.c ? ? ? ? ? ? ?| ? ?6 +++- > ?arch/arm/mach-omap2/pm34xx.c ? ? ? ? ?| ? 44 +++++++++++++++++--------------- > ?arch/arm/plat-omap/include/plat/cpu.h | ? 17 +++++++++--- > ?3 files changed, 40 insertions(+), 27 deletions(-) > > diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c > index 37efb86..eb1b8e4 100644 > --- a/arch/arm/mach-omap2/id.c > +++ b/arch/arm/mach-omap2/id.c > @@ -201,8 +201,12 @@ static void __init omap3_check_features(void) > ? ? ? ?OMAP3_CHECK_FEATURE(status, ISP); > ? ? ? ?if (cpu_is_omap3630()) > ? ? ? ? ? ? ? ?omap_features |= OMAP3_HAS_192MHZ_CLK; > - ? ? ? if (!cpu_is_omap3505() && !cpu_is_omap3517()) > + ? ? ? if (cpu_is_omap3430() || cpu_is_omap3630()) > ? ? ? ? ? ? ? ?omap_features |= OMAP3_HAS_IO_WAKEUP; > + ? ? ? if ((omap_rev() == OMAP3430_REV_ES3_1 && > + ? ? ? ? ? ?omap_rev() == OMAP3430_REV_ES3_1_2) || Perhaps I'm confused but shouldn't it be an || instead of &&? We're testing for ES3.1 *or* ES3.12? Otherwise looks good. I'll test on my old Overo COMs. Steve > + ? ? ? ? ? cpu_is_omap3630()) > + ? ? ? ? ? ? ? omap_features |= OMAP3_HAS_IO_CHAIN_CTRL; > > ? ? ? ?omap_features |= OMAP3_HAS_SDRC; > > diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c > index 7255d9b..a6156bd 100644 > --- a/arch/arm/mach-omap2/pm34xx.c > +++ b/arch/arm/mach-omap2/pm34xx.c > @@ -99,31 +99,28 @@ static void omap3_enable_io_chain(void) > ?{ > ? ? ? ?int timeout = 0; > > - ? ? ? if (omap_rev() >= OMAP3430_REV_ES3_1) { > - ? ? ? ? ? ? ? omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?PM_WKEN); > - ? ? ? ? ? ? ? /* Do a readback to assure write has been done */ > - ? ? ? ? ? ? ? omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); > - > - ? ? ? ? ? ? ? while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & > - ? ? ? ? ? ? ? ? ? ? ? ?OMAP3430_ST_IO_CHAIN_MASK)) { > - ? ? ? ? ? ? ? ? ? ? ? timeout++; > - ? ? ? ? ? ? ? ? ? ? ? if (timeout > 1000) { > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? printk(KERN_ERR "Wake up daisy chain " > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"activation failed.\n"); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return; > - ? ? ? ? ? ? ? ? ? ? ? } > - ? ? ? ? ? ? ? ? ? ? ? omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?WKUP_MOD, PM_WKEN); > + ? ? ? omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?PM_WKEN); > + ? ? ? /* Do a readback to assure write has been done */ > + ? ? ? omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); > + > + ? ? ? while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & > + ? ? ? ? ? ? ? ?OMAP3430_ST_IO_CHAIN_MASK)) { > + ? ? ? ? ? ? ? timeout++; > + ? ? ? ? ? ? ? if (timeout > 1000) { > + ? ? ? ? ? ? ? ? ? ? ? printk(KERN_ERR "Wake up daisy chain " > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"activation failed.\n"); > + ? ? ? ? ? ? ? ? ? ? ? return; > ? ? ? ? ? ? ? ?} > + ? ? ? ? ? ? ? omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?WKUP_MOD, PM_WKEN); > ? ? ? ?} > ?} > > ?static void omap3_disable_io_chain(void) > ?{ > - ? ? ? if (omap_rev() >= OMAP3430_REV_ES3_1) > - ? ? ? ? ? ? ? omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?PM_WKEN); > + ? ? ? omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?PM_WKEN); > ?} > > ?static void omap3_core_save_context(void) > @@ -376,7 +373,8 @@ void omap_sram_idle(void) > ? ? ? ? ? ?(per_next_state < PWRDM_POWER_ON || > ? ? ? ? ? ? core_next_state < PWRDM_POWER_ON)) { > ? ? ? ? ? ? ? ?omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); > - ? ? ? ? ? ? ? omap3_enable_io_chain(); > + ? ? ? ? ? ? ? if (omap3_has_io_chain_ctrl()) > + ? ? ? ? ? ? ? ? ? ? ? omap3_enable_io_chain(); > ? ? ? ?} > > ? ? ? ?/* Block console output in case it is on one of the OMAP UARTs */ > @@ -475,7 +473,8 @@ console_still_active: > ? ? ? ? ? ? core_next_state < PWRDM_POWER_ON)) { > ? ? ? ? ? ? ? ?omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PM_WKEN); > - ? ? ? ? ? ? ? omap3_disable_io_chain(); > + ? ? ? ? ? ? ? if (omap3_has_io_chain_ctrl()) > + ? ? ? ? ? ? ? ? ? ? ? omap3_disable_io_chain(); > ? ? ? ?} > > ? ? ? ?pwrdm_post_transition(); > @@ -870,6 +869,9 @@ static int __init omap3_pm_init(void) > ? ? ? ?if (!cpu_is_omap34xx()) > ? ? ? ? ? ? ? ?return -ENODEV; > > + ? ? ? if (!omap3_has_io_chain_ctrl()) > + ? ? ? ? ? ? ? pr_warning("PM: no software I/O chain control; some wakeups may be lost\n"); > + > ? ? ? ?pm_errata_configure(); > > ? ? ? ?/* XXX prcm_setup_regs needs to be before enabling hw > diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h > index 67b3d75..3a280aa 100644 > --- a/arch/arm/plat-omap/include/plat/cpu.h > +++ b/arch/arm/plat-omap/include/plat/cpu.h > @@ -477,6 +477,13 @@ void omap2_check_revision(void); > > ?/* > ?* Runtime detection of OMAP3 features > + * > + * OMAP3_HAS_IO_CHAIN_CTRL: Some later members of the OMAP3 chip > + * ? ?family have OS-level control over the I/O chain clock. ?This is > + * ? ?to avoid a window during which wakeups could potentially be lost > + * ? ?during powerdomain transitions. ?If this bit is set, it > + * ? ?indicates that the chip does support OS-level control of this > + * ? ?feature. > ?*/ > ?extern u32 omap_features; > > @@ -488,9 +495,10 @@ extern u32 omap_features; > ?#define OMAP3_HAS_192MHZ_CLK ? ? ? ? ? BIT(5) > ?#define OMAP3_HAS_IO_WAKEUP ? ? ? ? ? ?BIT(6) > ?#define OMAP3_HAS_SDRC ? ? ? ? ? ? ? ? BIT(7) > -#define OMAP4_HAS_MPU_1GHZ ? ? ? ? ? ? BIT(8) > -#define OMAP4_HAS_MPU_1_2GHZ ? ? ? ? ? BIT(9) > -#define OMAP4_HAS_MPU_1_5GHZ ? ? ? ? ? BIT(10) > +#define OMAP3_HAS_IO_CHAIN_CTRL ? ? ? ? ? ? ? ?BIT(8) > +#define OMAP4_HAS_MPU_1GHZ ? ? ? ? ? ? BIT(9) > +#define OMAP4_HAS_MPU_1_2GHZ ? ? ? ? ? BIT(10) > +#define OMAP4_HAS_MPU_1_5GHZ ? ? ? ? ? BIT(11) > > > ?#define OMAP3_HAS_FEATURE(feat,flag) ? ? ? ? ? ? ? ? ? \ > @@ -507,12 +515,11 @@ OMAP3_HAS_FEATURE(isp, ISP) > ?OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK) > ?OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP) > ?OMAP3_HAS_FEATURE(sdrc, SDRC) > +OMAP3_HAS_FEATURE(io_chain_ctrl, IO_CHAIN_CTRL) > > ?/* > ?* Runtime detection of OMAP4 features > ?*/ > -extern u32 omap_features; > - > ?#define OMAP4_HAS_FEATURE(feat, flag) ? ? ? ? ? ? ? ? ?\ > ?static inline unsigned int omap4_has_ ##feat(void) ? ? \ > ?{ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\ > -- > 1.7.6.3 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-omap" in > the body of a message to majordomo at vger.kernel.org > More majordomo info at ?http://vger.kernel.org/majordomo-info.html > ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection 2011-10-06 19:42 ` Steve Sakoman @ 2011-10-06 19:46 ` Paul Walmsley -1 siblings, 0 replies; 22+ messages in thread From: Paul Walmsley @ 2011-10-06 19:46 UTC (permalink / raw) To: Steve Sakoman; +Cc: linux-omap, linux-arm-kernel, khilman, dhylands On Thu, 6 Oct 2011, Steve Sakoman wrote: > Perhaps I'm confused but shouldn't it be an || instead of &&? > > We're testing for ES3.1 *or* ES3.12? You're correct - thanks for catching this. v2 on its way. - Paul ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection @ 2011-10-06 19:46 ` Paul Walmsley 0 siblings, 0 replies; 22+ messages in thread From: Paul Walmsley @ 2011-10-06 19:46 UTC (permalink / raw) To: linux-arm-kernel On Thu, 6 Oct 2011, Steve Sakoman wrote: > Perhaps I'm confused but shouldn't it be an || instead of &&? > > We're testing for ES3.1 *or* ES3.12? You're correct - thanks for catching this. v2 on its way. - Paul ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection 2011-10-06 19:42 ` Steve Sakoman @ 2011-10-06 19:47 ` Paul Walmsley -1 siblings, 0 replies; 22+ messages in thread From: Paul Walmsley @ 2011-10-06 19:47 UTC (permalink / raw) To: Steve Sakoman; +Cc: linux-omap, linux-arm-kernel, khilman, dhylands The way that we detect which OMAP3 chips support I/O wakeup and software I/O chain clock control is broken. Currently, I/O wakeup is marked as present for all OMAP3 SoCs other than the AM3505/3517. The TI81xx family of SoCs are at present considered to be OMAP3 SoCs, but don't support I/O wakeup. To resolve this, convert the existing blacklist approach to an explicit, whitelist support, in which only SoCs which are known to support I/O wakeup are listed. (At present, this only includes OMAP34xx, OMAP3503, OMAP3515, OMAP3525, OMAP3530, and OMAP36xx.) Also, the current code incorrectly detects the presence of a software-controllable I/O chain clock on several chips that don't support it. This results in writes to reserved bitfields, unnecessary delays, and console messages on kernels running on those chips: http://www.spinics.net/lists/linux-omap/msg58735.html Convert this test to a feature test with a chip-by-chip whitelist. Thanks to Dave Hylands <dhylands@gmail.com> for reporting this problem and doing some testing to help isolate the cause. Thanks to Steve Sakoman <sakoman@gmail.com> for catching a bug in the first version of this patch. Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: Kevin Hilman <khilman@ti.com> Cc: Dave Hylands <dhylands@gmail.com> Cc: Steve Sakoman <sakoman@gmail.com> --- arch/arm/mach-omap2/id.c | 6 +++- arch/arm/mach-omap2/pm34xx.c | 44 +++++++++++++++++--------------- arch/arm/plat-omap/include/plat/cpu.h | 17 +++++++++--- 3 files changed, 40 insertions(+), 27 deletions(-) diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 37efb86..707fbb1 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -201,8 +201,12 @@ static void __init omap3_check_features(void) OMAP3_CHECK_FEATURE(status, ISP); if (cpu_is_omap3630()) omap_features |= OMAP3_HAS_192MHZ_CLK; - if (!cpu_is_omap3505() && !cpu_is_omap3517()) + if (cpu_is_omap3430() || cpu_is_omap3630()) omap_features |= OMAP3_HAS_IO_WAKEUP; + if ((omap_rev() == OMAP3430_REV_ES3_1 || + omap_rev() == OMAP3430_REV_ES3_1_2) || + cpu_is_omap3630()) + omap_features |= OMAP3_HAS_IO_CHAIN_CTRL; omap_features |= OMAP3_HAS_SDRC; diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 7255d9b..a6156bd 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -99,31 +99,28 @@ static void omap3_enable_io_chain(void) { int timeout = 0; - if (omap_rev() >= OMAP3430_REV_ES3_1) { - omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, - PM_WKEN); - /* Do a readback to assure write has been done */ - omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); - - while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & - OMAP3430_ST_IO_CHAIN_MASK)) { - timeout++; - if (timeout > 1000) { - printk(KERN_ERR "Wake up daisy chain " - "activation failed.\n"); - return; - } - omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, - WKUP_MOD, PM_WKEN); + omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, + PM_WKEN); + /* Do a readback to assure write has been done */ + omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); + + while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & + OMAP3430_ST_IO_CHAIN_MASK)) { + timeout++; + if (timeout > 1000) { + printk(KERN_ERR "Wake up daisy chain " + "activation failed.\n"); + return; } + omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, + WKUP_MOD, PM_WKEN); } } static void omap3_disable_io_chain(void) { - if (omap_rev() >= OMAP3430_REV_ES3_1) - omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, - PM_WKEN); + omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, + PM_WKEN); } static void omap3_core_save_context(void) @@ -376,7 +373,8 @@ void omap_sram_idle(void) (per_next_state < PWRDM_POWER_ON || core_next_state < PWRDM_POWER_ON)) { omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); - omap3_enable_io_chain(); + if (omap3_has_io_chain_ctrl()) + omap3_enable_io_chain(); } /* Block console output in case it is on one of the OMAP UARTs */ @@ -475,7 +473,8 @@ console_still_active: core_next_state < PWRDM_POWER_ON)) { omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); - omap3_disable_io_chain(); + if (omap3_has_io_chain_ctrl()) + omap3_disable_io_chain(); } pwrdm_post_transition(); @@ -870,6 +869,9 @@ static int __init omap3_pm_init(void) if (!cpu_is_omap34xx()) return -ENODEV; + if (!omap3_has_io_chain_ctrl()) + pr_warning("PM: no software I/O chain control; some wakeups may be lost\n"); + pm_errata_configure(); /* XXX prcm_setup_regs needs to be before enabling hw diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 67b3d75..3a280aa 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -477,6 +477,13 @@ void omap2_check_revision(void); /* * Runtime detection of OMAP3 features + * + * OMAP3_HAS_IO_CHAIN_CTRL: Some later members of the OMAP3 chip + * family have OS-level control over the I/O chain clock. This is + * to avoid a window during which wakeups could potentially be lost + * during powerdomain transitions. If this bit is set, it + * indicates that the chip does support OS-level control of this + * feature. */ extern u32 omap_features; @@ -488,9 +495,10 @@ extern u32 omap_features; #define OMAP3_HAS_192MHZ_CLK BIT(5) #define OMAP3_HAS_IO_WAKEUP BIT(6) #define OMAP3_HAS_SDRC BIT(7) -#define OMAP4_HAS_MPU_1GHZ BIT(8) -#define OMAP4_HAS_MPU_1_2GHZ BIT(9) -#define OMAP4_HAS_MPU_1_5GHZ BIT(10) +#define OMAP3_HAS_IO_CHAIN_CTRL BIT(8) +#define OMAP4_HAS_MPU_1GHZ BIT(9) +#define OMAP4_HAS_MPU_1_2GHZ BIT(10) +#define OMAP4_HAS_MPU_1_5GHZ BIT(11) #define OMAP3_HAS_FEATURE(feat,flag) \ @@ -507,12 +515,11 @@ OMAP3_HAS_FEATURE(isp, ISP) OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK) OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP) OMAP3_HAS_FEATURE(sdrc, SDRC) +OMAP3_HAS_FEATURE(io_chain_ctrl, IO_CHAIN_CTRL) /* * Runtime detection of OMAP4 features */ -extern u32 omap_features; - #define OMAP4_HAS_FEATURE(feat, flag) \ static inline unsigned int omap4_has_ ##feat(void) \ { \ -- 1.7.6.3 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection @ 2011-10-06 19:47 ` Paul Walmsley 0 siblings, 0 replies; 22+ messages in thread From: Paul Walmsley @ 2011-10-06 19:47 UTC (permalink / raw) To: linux-arm-kernel The way that we detect which OMAP3 chips support I/O wakeup and software I/O chain clock control is broken. Currently, I/O wakeup is marked as present for all OMAP3 SoCs other than the AM3505/3517. The TI81xx family of SoCs are at present considered to be OMAP3 SoCs, but don't support I/O wakeup. To resolve this, convert the existing blacklist approach to an explicit, whitelist support, in which only SoCs which are known to support I/O wakeup are listed. (At present, this only includes OMAP34xx, OMAP3503, OMAP3515, OMAP3525, OMAP3530, and OMAP36xx.) Also, the current code incorrectly detects the presence of a software-controllable I/O chain clock on several chips that don't support it. This results in writes to reserved bitfields, unnecessary delays, and console messages on kernels running on those chips: http://www.spinics.net/lists/linux-omap/msg58735.html Convert this test to a feature test with a chip-by-chip whitelist. Thanks to Dave Hylands <dhylands@gmail.com> for reporting this problem and doing some testing to help isolate the cause. Thanks to Steve Sakoman <sakoman@gmail.com> for catching a bug in the first version of this patch. Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: Kevin Hilman <khilman@ti.com> Cc: Dave Hylands <dhylands@gmail.com> Cc: Steve Sakoman <sakoman@gmail.com> --- arch/arm/mach-omap2/id.c | 6 +++- arch/arm/mach-omap2/pm34xx.c | 44 +++++++++++++++++--------------- arch/arm/plat-omap/include/plat/cpu.h | 17 +++++++++--- 3 files changed, 40 insertions(+), 27 deletions(-) diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 37efb86..707fbb1 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -201,8 +201,12 @@ static void __init omap3_check_features(void) OMAP3_CHECK_FEATURE(status, ISP); if (cpu_is_omap3630()) omap_features |= OMAP3_HAS_192MHZ_CLK; - if (!cpu_is_omap3505() && !cpu_is_omap3517()) + if (cpu_is_omap3430() || cpu_is_omap3630()) omap_features |= OMAP3_HAS_IO_WAKEUP; + if ((omap_rev() == OMAP3430_REV_ES3_1 || + omap_rev() == OMAP3430_REV_ES3_1_2) || + cpu_is_omap3630()) + omap_features |= OMAP3_HAS_IO_CHAIN_CTRL; omap_features |= OMAP3_HAS_SDRC; diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 7255d9b..a6156bd 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -99,31 +99,28 @@ static void omap3_enable_io_chain(void) { int timeout = 0; - if (omap_rev() >= OMAP3430_REV_ES3_1) { - omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, - PM_WKEN); - /* Do a readback to assure write has been done */ - omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); - - while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & - OMAP3430_ST_IO_CHAIN_MASK)) { - timeout++; - if (timeout > 1000) { - printk(KERN_ERR "Wake up daisy chain " - "activation failed.\n"); - return; - } - omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, - WKUP_MOD, PM_WKEN); + omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, + PM_WKEN); + /* Do a readback to assure write has been done */ + omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); + + while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & + OMAP3430_ST_IO_CHAIN_MASK)) { + timeout++; + if (timeout > 1000) { + printk(KERN_ERR "Wake up daisy chain " + "activation failed.\n"); + return; } + omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, + WKUP_MOD, PM_WKEN); } } static void omap3_disable_io_chain(void) { - if (omap_rev() >= OMAP3430_REV_ES3_1) - omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, - PM_WKEN); + omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, + PM_WKEN); } static void omap3_core_save_context(void) @@ -376,7 +373,8 @@ void omap_sram_idle(void) (per_next_state < PWRDM_POWER_ON || core_next_state < PWRDM_POWER_ON)) { omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); - omap3_enable_io_chain(); + if (omap3_has_io_chain_ctrl()) + omap3_enable_io_chain(); } /* Block console output in case it is on one of the OMAP UARTs */ @@ -475,7 +473,8 @@ console_still_active: core_next_state < PWRDM_POWER_ON)) { omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); - omap3_disable_io_chain(); + if (omap3_has_io_chain_ctrl()) + omap3_disable_io_chain(); } pwrdm_post_transition(); @@ -870,6 +869,9 @@ static int __init omap3_pm_init(void) if (!cpu_is_omap34xx()) return -ENODEV; + if (!omap3_has_io_chain_ctrl()) + pr_warning("PM: no software I/O chain control; some wakeups may be lost\n"); + pm_errata_configure(); /* XXX prcm_setup_regs needs to be before enabling hw diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 67b3d75..3a280aa 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -477,6 +477,13 @@ void omap2_check_revision(void); /* * Runtime detection of OMAP3 features + * + * OMAP3_HAS_IO_CHAIN_CTRL: Some later members of the OMAP3 chip + * family have OS-level control over the I/O chain clock. This is + * to avoid a window during which wakeups could potentially be lost + * during powerdomain transitions. If this bit is set, it + * indicates that the chip does support OS-level control of this + * feature. */ extern u32 omap_features; @@ -488,9 +495,10 @@ extern u32 omap_features; #define OMAP3_HAS_192MHZ_CLK BIT(5) #define OMAP3_HAS_IO_WAKEUP BIT(6) #define OMAP3_HAS_SDRC BIT(7) -#define OMAP4_HAS_MPU_1GHZ BIT(8) -#define OMAP4_HAS_MPU_1_2GHZ BIT(9) -#define OMAP4_HAS_MPU_1_5GHZ BIT(10) +#define OMAP3_HAS_IO_CHAIN_CTRL BIT(8) +#define OMAP4_HAS_MPU_1GHZ BIT(9) +#define OMAP4_HAS_MPU_1_2GHZ BIT(10) +#define OMAP4_HAS_MPU_1_5GHZ BIT(11) #define OMAP3_HAS_FEATURE(feat,flag) \ @@ -507,12 +515,11 @@ OMAP3_HAS_FEATURE(isp, ISP) OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK) OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP) OMAP3_HAS_FEATURE(sdrc, SDRC) +OMAP3_HAS_FEATURE(io_chain_ctrl, IO_CHAIN_CTRL) /* * Runtime detection of OMAP4 features */ -extern u32 omap_features; - #define OMAP4_HAS_FEATURE(feat, flag) \ static inline unsigned int omap4_has_ ##feat(void) \ { \ -- 1.7.6.3 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v2] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection 2011-10-06 19:47 ` Paul Walmsley @ 2011-10-06 21:22 ` Steve Sakoman -1 siblings, 0 replies; 22+ messages in thread From: Steve Sakoman @ 2011-10-06 21:22 UTC (permalink / raw) To: Paul Walmsley; +Cc: linux-omap, linux-arm-kernel, khilman, dhylands On Thu, Oct 6, 2011 at 12:47 PM, Paul Walmsley <paul@pwsan.com> wrote: > > The way that we detect which OMAP3 chips support I/O wakeup and > software I/O chain clock control is broken. > > Currently, I/O wakeup is marked as present for all OMAP3 SoCs other > than the AM3505/3517. The TI81xx family of SoCs are at present > considered to be OMAP3 SoCs, but don't support I/O wakeup. To resolve > this, convert the existing blacklist approach to an explicit, > whitelist support, in which only SoCs which are known to support I/O > wakeup are listed. (At present, this only includes OMAP34xx, > OMAP3503, OMAP3515, OMAP3525, OMAP3530, and OMAP36xx.) > > Also, the current code incorrectly detects the presence of a > software-controllable I/O chain clock on several chips that don't > support it. This results in writes to reserved bitfields, unnecessary > delays, and console messages on kernels running on those chips: > > http://www.spinics.net/lists/linux-omap/msg58735.html > > Convert this test to a feature test with a chip-by-chip whitelist. > > Thanks to Dave Hylands <dhylands@gmail.com> for reporting this problem > and doing some testing to help isolate the cause. Thanks to Steve > Sakoman <sakoman@gmail.com> for catching a bug in the first version of > this patch. > > Signed-off-by: Paul Walmsley <paul@pwsan.com> > Cc: Kevin Hilman <khilman@ti.com> > Cc: Dave Hylands <dhylands@gmail.com> > Cc: Steve Sakoman <sakoman@gmail.com> I just tested a Linux 3.0 version of the patch on both ES2.1 and ES3.1 and it works just fine. So here is my: Tested-by: Steve Sakoman <steve@sakoman.com> -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection @ 2011-10-06 21:22 ` Steve Sakoman 0 siblings, 0 replies; 22+ messages in thread From: Steve Sakoman @ 2011-10-06 21:22 UTC (permalink / raw) To: linux-arm-kernel On Thu, Oct 6, 2011 at 12:47 PM, Paul Walmsley <paul@pwsan.com> wrote: > > The way that we detect which OMAP3 chips support I/O wakeup and > software I/O chain clock control is broken. > > Currently, I/O wakeup is marked as present for all OMAP3 SoCs other > than the AM3505/3517. ?The TI81xx family of SoCs are at present > considered to be OMAP3 SoCs, but don't support I/O wakeup. ?To resolve > this, convert the existing blacklist approach to an explicit, > whitelist support, in which only SoCs which are known to support I/O > wakeup are listed. ?(At present, this only includes OMAP34xx, > OMAP3503, OMAP3515, OMAP3525, OMAP3530, and OMAP36xx.) > > Also, the current code incorrectly detects the presence of a > software-controllable I/O chain clock on several chips that don't > support it. ?This results in writes to reserved bitfields, unnecessary > delays, and console messages on kernels running on those chips: > > ? ?http://www.spinics.net/lists/linux-omap/msg58735.html > > Convert this test to a feature test with a chip-by-chip whitelist. > > Thanks to Dave Hylands <dhylands@gmail.com> for reporting this problem > and doing some testing to help isolate the cause. ?Thanks to Steve > Sakoman <sakoman@gmail.com> for catching a bug in the first version of > this patch. > > Signed-off-by: Paul Walmsley <paul@pwsan.com> > Cc: Kevin Hilman <khilman@ti.com> > Cc: Dave Hylands <dhylands@gmail.com> > Cc: Steve Sakoman <sakoman@gmail.com> I just tested a Linux 3.0 version of the patch on both ES2.1 and ES3.1 and it works just fine. So here is my: Tested-by: Steve Sakoman <steve@sakoman.com> ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v3] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection 2011-10-06 21:22 ` Steve Sakoman @ 2011-10-06 21:25 ` Paul Walmsley -1 siblings, 0 replies; 22+ messages in thread From: Paul Walmsley @ 2011-10-06 21:25 UTC (permalink / raw) To: Steve Sakoman; +Cc: linux-omap, linux-arm-kernel, khilman, dhylands >From 253cd48082df008c8e952fe8a4b8c0388c37d334 Mon Sep 17 00:00:00 2001 From: Paul Walmsley <paul@pwsan.com> Date: Thu, 6 Oct 2011 12:29:46 -0600 Subject: [PATCH] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection The way that we detect which OMAP3 chips support I/O wakeup and software I/O chain clock control is broken. Currently, I/O wakeup is marked as present for all OMAP3 SoCs other than the AM3505/3517. The TI81xx family of SoCs are at present considered to be OMAP3 SoCs, but don't support I/O wakeup. To resolve this, convert the existing blacklist approach to an explicit, whitelist support, in which only SoCs which are known to support I/O wakeup are listed. (At present, this only includes OMAP34xx, OMAP3503, OMAP3515, OMAP3525, OMAP3530, and OMAP36xx.) Also, the current code incorrectly detects the presence of a software-controllable I/O chain clock on several chips that don't support it. This results in writes to reserved bitfields, unnecessary delays, and console messages on kernels running on those chips: http://www.spinics.net/lists/linux-omap/msg58735.html Convert this test to a feature test with a chip-by-chip whitelist. Thanks to Dave Hylands <dhylands@gmail.com> for reporting this problem and doing some testing to help isolate the cause. Thanks to Steve Sakoman <sakoman@gmail.com> for catching a bug in the first version of this patch. Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: Kevin Hilman <khilman@ti.com> Cc: Dave Hylands <dhylands@gmail.com> Cc: Steve Sakoman <sakoman@gmail.com> Tested-by: Steve Sakoman <sakoman@gmail.com> --- This version adds Steve's Tested-by:. arch/arm/mach-omap2/id.c | 6 +++- arch/arm/mach-omap2/pm34xx.c | 44 +++++++++++++++++--------------- arch/arm/plat-omap/include/plat/cpu.h | 17 +++++++++--- 3 files changed, 40 insertions(+), 27 deletions(-) diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 37efb86..707fbb1 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -201,8 +201,12 @@ static void __init omap3_check_features(void) OMAP3_CHECK_FEATURE(status, ISP); if (cpu_is_omap3630()) omap_features |= OMAP3_HAS_192MHZ_CLK; - if (!cpu_is_omap3505() && !cpu_is_omap3517()) + if (cpu_is_omap3430() || cpu_is_omap3630()) omap_features |= OMAP3_HAS_IO_WAKEUP; + if ((omap_rev() == OMAP3430_REV_ES3_1 || + omap_rev() == OMAP3430_REV_ES3_1_2) || + cpu_is_omap3630()) + omap_features |= OMAP3_HAS_IO_CHAIN_CTRL; omap_features |= OMAP3_HAS_SDRC; diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 7255d9b..a6156bd 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -99,31 +99,28 @@ static void omap3_enable_io_chain(void) { int timeout = 0; - if (omap_rev() >= OMAP3430_REV_ES3_1) { - omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, - PM_WKEN); - /* Do a readback to assure write has been done */ - omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); - - while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & - OMAP3430_ST_IO_CHAIN_MASK)) { - timeout++; - if (timeout > 1000) { - printk(KERN_ERR "Wake up daisy chain " - "activation failed.\n"); - return; - } - omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, - WKUP_MOD, PM_WKEN); + omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, + PM_WKEN); + /* Do a readback to assure write has been done */ + omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); + + while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & + OMAP3430_ST_IO_CHAIN_MASK)) { + timeout++; + if (timeout > 1000) { + printk(KERN_ERR "Wake up daisy chain " + "activation failed.\n"); + return; } + omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, + WKUP_MOD, PM_WKEN); } } static void omap3_disable_io_chain(void) { - if (omap_rev() >= OMAP3430_REV_ES3_1) - omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, - PM_WKEN); + omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, + PM_WKEN); } static void omap3_core_save_context(void) @@ -376,7 +373,8 @@ void omap_sram_idle(void) (per_next_state < PWRDM_POWER_ON || core_next_state < PWRDM_POWER_ON)) { omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); - omap3_enable_io_chain(); + if (omap3_has_io_chain_ctrl()) + omap3_enable_io_chain(); } /* Block console output in case it is on one of the OMAP UARTs */ @@ -475,7 +473,8 @@ console_still_active: core_next_state < PWRDM_POWER_ON)) { omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); - omap3_disable_io_chain(); + if (omap3_has_io_chain_ctrl()) + omap3_disable_io_chain(); } pwrdm_post_transition(); @@ -870,6 +869,9 @@ static int __init omap3_pm_init(void) if (!cpu_is_omap34xx()) return -ENODEV; + if (!omap3_has_io_chain_ctrl()) + pr_warning("PM: no software I/O chain control; some wakeups may be lost\n"); + pm_errata_configure(); /* XXX prcm_setup_regs needs to be before enabling hw diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 67b3d75..3a280aa 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -477,6 +477,13 @@ void omap2_check_revision(void); /* * Runtime detection of OMAP3 features + * + * OMAP3_HAS_IO_CHAIN_CTRL: Some later members of the OMAP3 chip + * family have OS-level control over the I/O chain clock. This is + * to avoid a window during which wakeups could potentially be lost + * during powerdomain transitions. If this bit is set, it + * indicates that the chip does support OS-level control of this + * feature. */ extern u32 omap_features; @@ -488,9 +495,10 @@ extern u32 omap_features; #define OMAP3_HAS_192MHZ_CLK BIT(5) #define OMAP3_HAS_IO_WAKEUP BIT(6) #define OMAP3_HAS_SDRC BIT(7) -#define OMAP4_HAS_MPU_1GHZ BIT(8) -#define OMAP4_HAS_MPU_1_2GHZ BIT(9) -#define OMAP4_HAS_MPU_1_5GHZ BIT(10) +#define OMAP3_HAS_IO_CHAIN_CTRL BIT(8) +#define OMAP4_HAS_MPU_1GHZ BIT(9) +#define OMAP4_HAS_MPU_1_2GHZ BIT(10) +#define OMAP4_HAS_MPU_1_5GHZ BIT(11) #define OMAP3_HAS_FEATURE(feat,flag) \ @@ -507,12 +515,11 @@ OMAP3_HAS_FEATURE(isp, ISP) OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK) OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP) OMAP3_HAS_FEATURE(sdrc, SDRC) +OMAP3_HAS_FEATURE(io_chain_ctrl, IO_CHAIN_CTRL) /* * Runtime detection of OMAP4 features */ -extern u32 omap_features; - #define OMAP4_HAS_FEATURE(feat, flag) \ static inline unsigned int omap4_has_ ##feat(void) \ { \ -- 1.7.6.3 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v3] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection @ 2011-10-06 21:25 ` Paul Walmsley 0 siblings, 0 replies; 22+ messages in thread From: Paul Walmsley @ 2011-10-06 21:25 UTC (permalink / raw) To: linux-arm-kernel ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v3] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection 2011-10-06 21:25 ` Paul Walmsley @ 2011-10-06 23:46 ` Kevin Hilman -1 siblings, 0 replies; 22+ messages in thread From: Kevin Hilman @ 2011-10-06 23:46 UTC (permalink / raw) To: Paul Walmsley; +Cc: Steve Sakoman, linux-omap, linux-arm-kernel, dhylands Paul Walmsley <paul@pwsan.com> writes: > The way that we detect which OMAP3 chips support I/O wakeup and > software I/O chain clock control is broken. > > Currently, I/O wakeup is marked as present for all OMAP3 SoCs other > than the AM3505/3517. The TI81xx family of SoCs are at present > considered to be OMAP3 SoCs, but don't support I/O wakeup. To resolve > this, convert the existing blacklist approach to an explicit, > whitelist support, in which only SoCs which are known to support I/O > wakeup are listed. (At present, this only includes OMAP34xx, > OMAP3503, OMAP3515, OMAP3525, OMAP3530, and OMAP36xx.) > > Also, the current code incorrectly detects the presence of a > software-controllable I/O chain clock on several chips that don't > support it. This results in writes to reserved bitfields, unnecessary > delays, and console messages on kernels running on those chips: > > http://www.spinics.net/lists/linux-omap/msg58735.html > > Convert this test to a feature test with a chip-by-chip whitelist. > > Thanks to Dave Hylands <dhylands@gmail.com> for reporting this problem > and doing some testing to help isolate the cause. Thanks to Steve > Sakoman <sakoman@gmail.com> for catching a bug in the first version of > this patch. Based on the comments from Russell, I made a couple minor changes. Here's the updated version (also in my for_3.1/pm-fixes-3 branch.) Other than that, it looks like a good cleanup, queueing for v3.2 and will submit to stable as well. Tony, do you think we can still queue this as a fix for v3.1? Kevin >From 65740eada5a5552edc01e706af0670218815c048 Mon Sep 17 00:00:00 2001 From: Paul Walmsley <paul@pwsan.com> Date: Thu, 6 Oct 2011 15:25:52 -0600 Subject: [PATCH] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection The way that we detect which OMAP3 chips support I/O wakeup and software I/O chain clock control is broken. Currently, I/O wakeup is marked as present for all OMAP3 SoCs other than the AM3505/3517. The TI81xx family of SoCs are at present considered to be OMAP3 SoCs, but don't support I/O wakeup. To resolve this, convert the existing blacklist approach to an explicit, whitelist support, in which only SoCs which are known to support I/O wakeup are listed. (At present, this only includes OMAP34xx, OMAP3503, OMAP3515, OMAP3525, OMAP3530, and OMAP36xx.) Also, the current code incorrectly detects the presence of a software-controllable I/O chain clock on several chips that don't support it. This results in writes to reserved bitfields, unnecessary delays, and console messages on kernels running on those chips: http://www.spinics.net/lists/linux-omap/msg58735.html Convert this test to a feature test with a chip-by-chip whitelist. Thanks to Dave Hylands <dhylands@gmail.com> for reporting this problem and doing some testing to help isolate the cause. Thanks to Steve Sakoman <sakoman@gmail.com> for catching a bug in the first version of this patch. Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: Dave Hylands <dhylands@gmail.com> Cc: Steve Sakoman <sakoman@gmail.com> Tested-by: Steve Sakoman <sakoman@gmail.com> [khilman@ti.com: unwrapped printk, removed extra braces around conditional as suggessted by Russell King.] Signed-off-by: Kevin Hilman <khilman@ti.com> --- arch/arm/mach-omap2/id.c | 6 +++- arch/arm/mach-omap2/pm34xx.c | 44 +++++++++++++++++--------------- arch/arm/plat-omap/include/plat/cpu.h | 17 +++++++++--- 3 files changed, 40 insertions(+), 27 deletions(-) diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 37efb86..1c93462 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -201,8 +201,12 @@ static void __init omap3_check_features(void) OMAP3_CHECK_FEATURE(status, ISP); if (cpu_is_omap3630()) omap_features |= OMAP3_HAS_192MHZ_CLK; - if (!cpu_is_omap3505() && !cpu_is_omap3517()) + if (cpu_is_omap3430() || cpu_is_omap3630()) omap_features |= OMAP3_HAS_IO_WAKEUP; + if (omap_rev() == OMAP3430_REV_ES3_1 || + omap_rev() == OMAP3430_REV_ES3_1_2 || + cpu_is_omap3630()) + omap_features |= OMAP3_HAS_IO_CHAIN_CTRL; omap_features |= OMAP3_HAS_SDRC; diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 7255d9b..43536b2 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -99,31 +99,28 @@ static void omap3_enable_io_chain(void) { int timeout = 0; - if (omap_rev() >= OMAP3430_REV_ES3_1) { - omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, - PM_WKEN); - /* Do a readback to assure write has been done */ - omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); - - while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & - OMAP3430_ST_IO_CHAIN_MASK)) { - timeout++; - if (timeout > 1000) { - printk(KERN_ERR "Wake up daisy chain " - "activation failed.\n"); - return; - } - omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, - WKUP_MOD, PM_WKEN); + omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, + PM_WKEN); + /* Do a readback to assure write has been done */ + omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); + + while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & + OMAP3430_ST_IO_CHAIN_MASK)) { + timeout++; + if (timeout > 1000) { + printk(KERN_ERR + "Wake up daisy chain activation failed.\n"); + return; } + omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, + WKUP_MOD, PM_WKEN); } } static void omap3_disable_io_chain(void) { - if (omap_rev() >= OMAP3430_REV_ES3_1) - omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, - PM_WKEN); + omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, + PM_WKEN); } static void omap3_core_save_context(void) @@ -376,7 +373,8 @@ void omap_sram_idle(void) (per_next_state < PWRDM_POWER_ON || core_next_state < PWRDM_POWER_ON)) { omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); - omap3_enable_io_chain(); + if (omap3_has_io_chain_ctrl()) + omap3_enable_io_chain(); } /* Block console output in case it is on one of the OMAP UARTs */ @@ -475,7 +473,8 @@ console_still_active: core_next_state < PWRDM_POWER_ON)) { omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); - omap3_disable_io_chain(); + if (omap3_has_io_chain_ctrl()) + omap3_disable_io_chain(); } pwrdm_post_transition(); @@ -870,6 +869,9 @@ static int __init omap3_pm_init(void) if (!cpu_is_omap34xx()) return -ENODEV; + if (!omap3_has_io_chain_ctrl()) + pr_warning("PM: no software I/O chain control; some wakeups may be lost\n"); + pm_errata_configure(); /* XXX prcm_setup_regs needs to be before enabling hw diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 67b3d75..3a280aa 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -477,6 +477,13 @@ void omap2_check_revision(void); /* * Runtime detection of OMAP3 features + * + * OMAP3_HAS_IO_CHAIN_CTRL: Some later members of the OMAP3 chip + * family have OS-level control over the I/O chain clock. This is + * to avoid a window during which wakeups could potentially be lost + * during powerdomain transitions. If this bit is set, it + * indicates that the chip does support OS-level control of this + * feature. */ extern u32 omap_features; @@ -488,9 +495,10 @@ extern u32 omap_features; #define OMAP3_HAS_192MHZ_CLK BIT(5) #define OMAP3_HAS_IO_WAKEUP BIT(6) #define OMAP3_HAS_SDRC BIT(7) -#define OMAP4_HAS_MPU_1GHZ BIT(8) -#define OMAP4_HAS_MPU_1_2GHZ BIT(9) -#define OMAP4_HAS_MPU_1_5GHZ BIT(10) +#define OMAP3_HAS_IO_CHAIN_CTRL BIT(8) +#define OMAP4_HAS_MPU_1GHZ BIT(9) +#define OMAP4_HAS_MPU_1_2GHZ BIT(10) +#define OMAP4_HAS_MPU_1_5GHZ BIT(11) #define OMAP3_HAS_FEATURE(feat,flag) \ @@ -507,12 +515,11 @@ OMAP3_HAS_FEATURE(isp, ISP) OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK) OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP) OMAP3_HAS_FEATURE(sdrc, SDRC) +OMAP3_HAS_FEATURE(io_chain_ctrl, IO_CHAIN_CTRL) /* * Runtime detection of OMAP4 features */ -extern u32 omap_features; - #define OMAP4_HAS_FEATURE(feat, flag) \ static inline unsigned int omap4_has_ ##feat(void) \ { \ -- 1.7.6 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v3] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection @ 2011-10-06 23:46 ` Kevin Hilman 0 siblings, 0 replies; 22+ messages in thread From: Kevin Hilman @ 2011-10-06 23:46 UTC (permalink / raw) To: linux-arm-kernel Paul Walmsley <paul@pwsan.com> writes: > The way that we detect which OMAP3 chips support I/O wakeup and > software I/O chain clock control is broken. > > Currently, I/O wakeup is marked as present for all OMAP3 SoCs other > than the AM3505/3517. The TI81xx family of SoCs are at present > considered to be OMAP3 SoCs, but don't support I/O wakeup. To resolve > this, convert the existing blacklist approach to an explicit, > whitelist support, in which only SoCs which are known to support I/O > wakeup are listed. (At present, this only includes OMAP34xx, > OMAP3503, OMAP3515, OMAP3525, OMAP3530, and OMAP36xx.) > > Also, the current code incorrectly detects the presence of a > software-controllable I/O chain clock on several chips that don't > support it. This results in writes to reserved bitfields, unnecessary > delays, and console messages on kernels running on those chips: > > http://www.spinics.net/lists/linux-omap/msg58735.html > > Convert this test to a feature test with a chip-by-chip whitelist. > > Thanks to Dave Hylands <dhylands@gmail.com> for reporting this problem > and doing some testing to help isolate the cause. Thanks to Steve > Sakoman <sakoman@gmail.com> for catching a bug in the first version of > this patch. Based on the comments from Russell, I made a couple minor changes. Here's the updated version (also in my for_3.1/pm-fixes-3 branch.) Other than that, it looks like a good cleanup, queueing for v3.2 and will submit to stable as well. Tony, do you think we can still queue this as a fix for v3.1? Kevin ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection 2011-10-06 19:47 ` Paul Walmsley @ 2011-10-06 22:29 ` Russell King - ARM Linux -1 siblings, 0 replies; 22+ messages in thread From: Russell King - ARM Linux @ 2011-10-06 22:29 UTC (permalink / raw) To: Paul Walmsley Cc: Steve Sakoman, khilman, dhylands, linux-omap, linux-arm-kernel On Thu, Oct 06, 2011 at 01:47:22PM -0600, Paul Walmsley wrote: > + if ((omap_rev() == OMAP3430_REV_ES3_1 || > + omap_rev() == OMAP3430_REV_ES3_1_2) || > + cpu_is_omap3630()) > + omap_features |= OMAP3_HAS_IO_CHAIN_CTRL; (a || b) || c === a || b || c IOW, no need for the additional parens. > diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c > index 7255d9b..a6156bd 100644 > --- a/arch/arm/mach-omap2/pm34xx.c > +++ b/arch/arm/mach-omap2/pm34xx.c > @@ -99,31 +99,28 @@ static void omap3_enable_io_chain(void) > { > int timeout = 0; > > - if (omap_rev() >= OMAP3430_REV_ES3_1) { > - omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, > - PM_WKEN); > - /* Do a readback to assure write has been done */ > - omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); > - > - while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & > - OMAP3430_ST_IO_CHAIN_MASK)) { > - timeout++; > - if (timeout > 1000) { > - printk(KERN_ERR "Wake up daisy chain " > - "activation failed.\n"); > - return; > - } > - omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, > - WKUP_MOD, PM_WKEN); > + omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, > + PM_WKEN); > + /* Do a readback to assure write has been done */ > + omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); > + > + while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & > + OMAP3430_ST_IO_CHAIN_MASK)) { > + timeout++; > + if (timeout > 1000) { > + printk(KERN_ERR "Wake up daisy chain " > + "activation failed.\n"); > + return; > } > + omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, > + WKUP_MOD, PM_WKEN); > } This should've been caught before. Two things: 1. Do you know how long it takes this to time out? 2. Don't wrap error printks, it prevents them being grepped for. ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection @ 2011-10-06 22:29 ` Russell King - ARM Linux 0 siblings, 0 replies; 22+ messages in thread From: Russell King - ARM Linux @ 2011-10-06 22:29 UTC (permalink / raw) To: linux-arm-kernel On Thu, Oct 06, 2011 at 01:47:22PM -0600, Paul Walmsley wrote: > + if ((omap_rev() == OMAP3430_REV_ES3_1 || > + omap_rev() == OMAP3430_REV_ES3_1_2) || > + cpu_is_omap3630()) > + omap_features |= OMAP3_HAS_IO_CHAIN_CTRL; (a || b) || c === a || b || c IOW, no need for the additional parens. > diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c > index 7255d9b..a6156bd 100644 > --- a/arch/arm/mach-omap2/pm34xx.c > +++ b/arch/arm/mach-omap2/pm34xx.c > @@ -99,31 +99,28 @@ static void omap3_enable_io_chain(void) > { > int timeout = 0; > > - if (omap_rev() >= OMAP3430_REV_ES3_1) { > - omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, > - PM_WKEN); > - /* Do a readback to assure write has been done */ > - omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); > - > - while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & > - OMAP3430_ST_IO_CHAIN_MASK)) { > - timeout++; > - if (timeout > 1000) { > - printk(KERN_ERR "Wake up daisy chain " > - "activation failed.\n"); > - return; > - } > - omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, > - WKUP_MOD, PM_WKEN); > + omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, > + PM_WKEN); > + /* Do a readback to assure write has been done */ > + omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); > + > + while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & > + OMAP3430_ST_IO_CHAIN_MASK)) { > + timeout++; > + if (timeout > 1000) { > + printk(KERN_ERR "Wake up daisy chain " > + "activation failed.\n"); > + return; > } > + omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, > + WKUP_MOD, PM_WKEN); > } This should've been caught before. Two things: 1. Do you know how long it takes this to time out? 2. Don't wrap error printks, it prevents them being grepped for. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection 2011-10-06 22:29 ` Russell King - ARM Linux @ 2011-10-06 23:07 ` Paul Walmsley -1 siblings, 0 replies; 22+ messages in thread From: Paul Walmsley @ 2011-10-06 23:07 UTC (permalink / raw) To: Russell King - ARM Linux Cc: Steve Sakoman, khilman, dhylands, linux-omap, linux-arm-kernel On Thu, 6 Oct 2011, Russell King - ARM Linux wrote: > On Thu, Oct 06, 2011 at 01:47:22PM -0600, Paul Walmsley wrote: > > + if ((omap_rev() == OMAP3430_REV_ES3_1 || > > + omap_rev() == OMAP3430_REV_ES3_1_2) || > > + cpu_is_omap3630()) > > + omap_features |= OMAP3_HAS_IO_CHAIN_CTRL; > > (a || b) || c === a || b || c > > IOW, no need for the additional parens. Thanks; patch updated. > > diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c > > index 7255d9b..a6156bd 100644 > > --- a/arch/arm/mach-omap2/pm34xx.c > > +++ b/arch/arm/mach-omap2/pm34xx.c > > @@ -99,31 +99,28 @@ static void omap3_enable_io_chain(void) > > { > > int timeout = 0; > > > > - if (omap_rev() >= OMAP3430_REV_ES3_1) { > > - omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, > > - PM_WKEN); > > - /* Do a readback to assure write has been done */ > > - omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); > > - > > - while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & > > - OMAP3430_ST_IO_CHAIN_MASK)) { > > - timeout++; > > - if (timeout > 1000) { > > - printk(KERN_ERR "Wake up daisy chain " > > - "activation failed.\n"); > > - return; > > - } > > - omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, > > - WKUP_MOD, PM_WKEN); > > + omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, > > + PM_WKEN); > > + /* Do a readback to assure write has been done */ > > + omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); > > + > > + while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & > > + OMAP3430_ST_IO_CHAIN_MASK)) { > > + timeout++; > > + if (timeout > 1000) { > > + printk(KERN_ERR "Wake up daisy chain " > > + "activation failed.\n"); > > + return; > > } > > + omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, > > + WKUP_MOD, PM_WKEN); > > } > > This should've been caught before. Two things: > > 1. Do you know how long it takes this to time out? No, I don't; and I doubt the original author did either. Really there should be at least a udelay(1) in that code; since as it stands right now, there's at least a partial CPU/interconnect/high frequency oscillator speed dependency in that loop. But this patch was intended to be a minimal fix, avoiding code changes that are unrelated to the I/O chain feature detection change. Those lines just showed up due to the indentation level change... > 2. Don't wrap error printks, it prevents them being grepped for. Thanks; patch updated. - Paul ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection @ 2011-10-06 23:07 ` Paul Walmsley 0 siblings, 0 replies; 22+ messages in thread From: Paul Walmsley @ 2011-10-06 23:07 UTC (permalink / raw) To: linux-arm-kernel On Thu, 6 Oct 2011, Russell King - ARM Linux wrote: > On Thu, Oct 06, 2011 at 01:47:22PM -0600, Paul Walmsley wrote: > > + if ((omap_rev() == OMAP3430_REV_ES3_1 || > > + omap_rev() == OMAP3430_REV_ES3_1_2) || > > + cpu_is_omap3630()) > > + omap_features |= OMAP3_HAS_IO_CHAIN_CTRL; > > (a || b) || c === a || b || c > > IOW, no need for the additional parens. Thanks; patch updated. > > diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c > > index 7255d9b..a6156bd 100644 > > --- a/arch/arm/mach-omap2/pm34xx.c > > +++ b/arch/arm/mach-omap2/pm34xx.c > > @@ -99,31 +99,28 @@ static void omap3_enable_io_chain(void) > > { > > int timeout = 0; > > > > - if (omap_rev() >= OMAP3430_REV_ES3_1) { > > - omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, > > - PM_WKEN); > > - /* Do a readback to assure write has been done */ > > - omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); > > - > > - while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & > > - OMAP3430_ST_IO_CHAIN_MASK)) { > > - timeout++; > > - if (timeout > 1000) { > > - printk(KERN_ERR "Wake up daisy chain " > > - "activation failed.\n"); > > - return; > > - } > > - omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, > > - WKUP_MOD, PM_WKEN); > > + omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, > > + PM_WKEN); > > + /* Do a readback to assure write has been done */ > > + omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); > > + > > + while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & > > + OMAP3430_ST_IO_CHAIN_MASK)) { > > + timeout++; > > + if (timeout > 1000) { > > + printk(KERN_ERR "Wake up daisy chain " > > + "activation failed.\n"); > > + return; > > } > > + omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, > > + WKUP_MOD, PM_WKEN); > > } > > This should've been caught before. Two things: > > 1. Do you know how long it takes this to time out? No, I don't; and I doubt the original author did either. Really there should be at least a udelay(1) in that code; since as it stands right now, there's at least a partial CPU/interconnect/high frequency oscillator speed dependency in that loop. But this patch was intended to be a minimal fix, avoiding code changes that are unrelated to the I/O chain feature detection change. Those lines just showed up due to the indentation level change... > 2. Don't wrap error printks, it prevents them being grepped for. Thanks; patch updated. - Paul ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v3] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection 2011-10-06 22:29 ` Russell King - ARM Linux @ 2011-10-06 23:18 ` Paul Walmsley -1 siblings, 0 replies; 22+ messages in thread From: Paul Walmsley @ 2011-10-06 23:18 UTC (permalink / raw) To: Russell King - ARM Linux Cc: Steve Sakoman, khilman, dhylands, linux-omap, linux-arm-kernel The way that we detect which OMAP3 chips support I/O wakeup and software I/O chain clock control is broken. Currently, I/O wakeup is marked as present for all OMAP3 SoCs other than the AM3505/3517. The TI81xx family of SoCs are at present considered to be OMAP3 SoCs, but don't support I/O wakeup. To resolve this, convert the existing blacklist approach to an explicit, whitelist support, in which only SoCs which are known to support I/O wakeup are listed. (At present, this only includes OMAP34xx, OMAP3503, OMAP3515, OMAP3525, OMAP3530, and OMAP36xx.) Also, the current code incorrectly detects the presence of a software-controllable I/O chain clock on several chips that don't support it. This results in writes to reserved bitfields, unnecessary delays, and console messages on kernels running on those chips: http://www.spinics.net/lists/linux-omap/msg58735.html Convert this test to a feature test with a chip-by-chip whitelist. Thanks to Dave Hylands <dhylands@gmail.com> for reporting this problem and doing some testing to help isolate the cause. Thanks to Steve Sakoman <sakoman@gmail.com> for catching a bug in the first version of this patch. Thanks to Russell King <linux@arm.linux.org.uk> for comments. Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: Kevin Hilman <khilman@ti.com> Cc: Dave Hylands <dhylands@gmail.com> Cc: Steve Sakoman <sakoman@gmail.com> Tested-by: Steve Sakoman <sakoman@gmail.com> Cc: Russell King - ARM Linux <linux@arm.linux.org.uk> --- This version incorporates some comments from RMK - an unnecessary set of parentheses are removed and a two-part error message string is joined. Also, the printk(KERN_ERR has been converted into a pr_err(. arch/arm/mach-omap2/id.c | 5 +++- arch/arm/mach-omap2/pm34xx.c | 43 +++++++++++++++++---------------- arch/arm/plat-omap/include/plat/cpu.h | 17 +++++++++---- 3 files changed, 38 insertions(+), 27 deletions(-) diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 37efb86..a1ccb66 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -201,8 +201,11 @@ static void __init omap3_check_features(void) OMAP3_CHECK_FEATURE(status, ISP); if (cpu_is_omap3630()) omap_features |= OMAP3_HAS_192MHZ_CLK; - if (!cpu_is_omap3505() && !cpu_is_omap3517()) + if (cpu_is_omap3430() || cpu_is_omap3630()) omap_features |= OMAP3_HAS_IO_WAKEUP; + if (cpu_is_omap3630() || omap_rev() == OMAP3430_REV_ES3_1 || + omap_rev() == OMAP3430_REV_ES3_1_2) + omap_features |= OMAP3_HAS_IO_CHAIN_CTRL; omap_features |= OMAP3_HAS_SDRC; diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 7255d9b..979ed39 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -99,31 +99,27 @@ static void omap3_enable_io_chain(void) { int timeout = 0; - if (omap_rev() >= OMAP3430_REV_ES3_1) { - omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, - PM_WKEN); - /* Do a readback to assure write has been done */ - omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); - - while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & - OMAP3430_ST_IO_CHAIN_MASK)) { - timeout++; - if (timeout > 1000) { - printk(KERN_ERR "Wake up daisy chain " - "activation failed.\n"); - return; - } - omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, - WKUP_MOD, PM_WKEN); + omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, + PM_WKEN); + /* Do a readback to assure write has been done */ + omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); + + while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & + OMAP3430_ST_IO_CHAIN_MASK)) { + timeout++; + if (timeout > 1000) { + pr_err("Wake up daisy chain activation failed.\n"); + return; } + omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, + WKUP_MOD, PM_WKEN); } } static void omap3_disable_io_chain(void) { - if (omap_rev() >= OMAP3430_REV_ES3_1) - omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, - PM_WKEN); + omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, + PM_WKEN); } static void omap3_core_save_context(void) @@ -376,7 +372,8 @@ void omap_sram_idle(void) (per_next_state < PWRDM_POWER_ON || core_next_state < PWRDM_POWER_ON)) { omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); - omap3_enable_io_chain(); + if (omap3_has_io_chain_ctrl()) + omap3_enable_io_chain(); } /* Block console output in case it is on one of the OMAP UARTs */ @@ -475,7 +472,8 @@ console_still_active: core_next_state < PWRDM_POWER_ON)) { omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); - omap3_disable_io_chain(); + if (omap3_has_io_chain_ctrl()) + omap3_disable_io_chain(); } pwrdm_post_transition(); @@ -870,6 +868,9 @@ static int __init omap3_pm_init(void) if (!cpu_is_omap34xx()) return -ENODEV; + if (!omap3_has_io_chain_ctrl()) + pr_warning("PM: no software I/O chain control; some wakeups may be lost\n"); + pm_errata_configure(); /* XXX prcm_setup_regs needs to be before enabling hw diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 67b3d75..3a280aa 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -477,6 +477,13 @@ void omap2_check_revision(void); /* * Runtime detection of OMAP3 features + * + * OMAP3_HAS_IO_CHAIN_CTRL: Some later members of the OMAP3 chip + * family have OS-level control over the I/O chain clock. This is + * to avoid a window during which wakeups could potentially be lost + * during powerdomain transitions. If this bit is set, it + * indicates that the chip does support OS-level control of this + * feature. */ extern u32 omap_features; @@ -488,9 +495,10 @@ extern u32 omap_features; #define OMAP3_HAS_192MHZ_CLK BIT(5) #define OMAP3_HAS_IO_WAKEUP BIT(6) #define OMAP3_HAS_SDRC BIT(7) -#define OMAP4_HAS_MPU_1GHZ BIT(8) -#define OMAP4_HAS_MPU_1_2GHZ BIT(9) -#define OMAP4_HAS_MPU_1_5GHZ BIT(10) +#define OMAP3_HAS_IO_CHAIN_CTRL BIT(8) +#define OMAP4_HAS_MPU_1GHZ BIT(9) +#define OMAP4_HAS_MPU_1_2GHZ BIT(10) +#define OMAP4_HAS_MPU_1_5GHZ BIT(11) #define OMAP3_HAS_FEATURE(feat,flag) \ @@ -507,12 +515,11 @@ OMAP3_HAS_FEATURE(isp, ISP) OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK) OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP) OMAP3_HAS_FEATURE(sdrc, SDRC) +OMAP3_HAS_FEATURE(io_chain_ctrl, IO_CHAIN_CTRL) /* * Runtime detection of OMAP4 features */ -extern u32 omap_features; - #define OMAP4_HAS_FEATURE(feat, flag) \ static inline unsigned int omap4_has_ ##feat(void) \ { \ -- 1.7.6.3 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v3] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection @ 2011-10-06 23:18 ` Paul Walmsley 0 siblings, 0 replies; 22+ messages in thread From: Paul Walmsley @ 2011-10-06 23:18 UTC (permalink / raw) To: linux-arm-kernel The way that we detect which OMAP3 chips support I/O wakeup and software I/O chain clock control is broken. Currently, I/O wakeup is marked as present for all OMAP3 SoCs other than the AM3505/3517. The TI81xx family of SoCs are at present considered to be OMAP3 SoCs, but don't support I/O wakeup. To resolve this, convert the existing blacklist approach to an explicit, whitelist support, in which only SoCs which are known to support I/O wakeup are listed. (At present, this only includes OMAP34xx, OMAP3503, OMAP3515, OMAP3525, OMAP3530, and OMAP36xx.) Also, the current code incorrectly detects the presence of a software-controllable I/O chain clock on several chips that don't support it. This results in writes to reserved bitfields, unnecessary delays, and console messages on kernels running on those chips: http://www.spinics.net/lists/linux-omap/msg58735.html Convert this test to a feature test with a chip-by-chip whitelist. Thanks to Dave Hylands <dhylands@gmail.com> for reporting this problem and doing some testing to help isolate the cause. Thanks to Steve Sakoman <sakoman@gmail.com> for catching a bug in the first version of this patch. Thanks to Russell King <linux@arm.linux.org.uk> for comments. Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: Kevin Hilman <khilman@ti.com> Cc: Dave Hylands <dhylands@gmail.com> Cc: Steve Sakoman <sakoman@gmail.com> Tested-by: Steve Sakoman <sakoman@gmail.com> Cc: Russell King - ARM Linux <linux@arm.linux.org.uk> --- This version incorporates some comments from RMK - an unnecessary set of parentheses are removed and a two-part error message string is joined. Also, the printk(KERN_ERR has been converted into a pr_err(. arch/arm/mach-omap2/id.c | 5 +++- arch/arm/mach-omap2/pm34xx.c | 43 +++++++++++++++++---------------- arch/arm/plat-omap/include/plat/cpu.h | 17 +++++++++---- 3 files changed, 38 insertions(+), 27 deletions(-) diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 37efb86..a1ccb66 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -201,8 +201,11 @@ static void __init omap3_check_features(void) OMAP3_CHECK_FEATURE(status, ISP); if (cpu_is_omap3630()) omap_features |= OMAP3_HAS_192MHZ_CLK; - if (!cpu_is_omap3505() && !cpu_is_omap3517()) + if (cpu_is_omap3430() || cpu_is_omap3630()) omap_features |= OMAP3_HAS_IO_WAKEUP; + if (cpu_is_omap3630() || omap_rev() == OMAP3430_REV_ES3_1 || + omap_rev() == OMAP3430_REV_ES3_1_2) + omap_features |= OMAP3_HAS_IO_CHAIN_CTRL; omap_features |= OMAP3_HAS_SDRC; diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 7255d9b..979ed39 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -99,31 +99,27 @@ static void omap3_enable_io_chain(void) { int timeout = 0; - if (omap_rev() >= OMAP3430_REV_ES3_1) { - omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, - PM_WKEN); - /* Do a readback to assure write has been done */ - omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); - - while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & - OMAP3430_ST_IO_CHAIN_MASK)) { - timeout++; - if (timeout > 1000) { - printk(KERN_ERR "Wake up daisy chain " - "activation failed.\n"); - return; - } - omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, - WKUP_MOD, PM_WKEN); + omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, + PM_WKEN); + /* Do a readback to assure write has been done */ + omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); + + while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & + OMAP3430_ST_IO_CHAIN_MASK)) { + timeout++; + if (timeout > 1000) { + pr_err("Wake up daisy chain activation failed.\n"); + return; } + omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, + WKUP_MOD, PM_WKEN); } } static void omap3_disable_io_chain(void) { - if (omap_rev() >= OMAP3430_REV_ES3_1) - omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, - PM_WKEN); + omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, + PM_WKEN); } static void omap3_core_save_context(void) @@ -376,7 +372,8 @@ void omap_sram_idle(void) (per_next_state < PWRDM_POWER_ON || core_next_state < PWRDM_POWER_ON)) { omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); - omap3_enable_io_chain(); + if (omap3_has_io_chain_ctrl()) + omap3_enable_io_chain(); } /* Block console output in case it is on one of the OMAP UARTs */ @@ -475,7 +472,8 @@ console_still_active: core_next_state < PWRDM_POWER_ON)) { omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); - omap3_disable_io_chain(); + if (omap3_has_io_chain_ctrl()) + omap3_disable_io_chain(); } pwrdm_post_transition(); @@ -870,6 +868,9 @@ static int __init omap3_pm_init(void) if (!cpu_is_omap34xx()) return -ENODEV; + if (!omap3_has_io_chain_ctrl()) + pr_warning("PM: no software I/O chain control; some wakeups may be lost\n"); + pm_errata_configure(); /* XXX prcm_setup_regs needs to be before enabling hw diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 67b3d75..3a280aa 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -477,6 +477,13 @@ void omap2_check_revision(void); /* * Runtime detection of OMAP3 features + * + * OMAP3_HAS_IO_CHAIN_CTRL: Some later members of the OMAP3 chip + * family have OS-level control over the I/O chain clock. This is + * to avoid a window during which wakeups could potentially be lost + * during powerdomain transitions. If this bit is set, it + * indicates that the chip does support OS-level control of this + * feature. */ extern u32 omap_features; @@ -488,9 +495,10 @@ extern u32 omap_features; #define OMAP3_HAS_192MHZ_CLK BIT(5) #define OMAP3_HAS_IO_WAKEUP BIT(6) #define OMAP3_HAS_SDRC BIT(7) -#define OMAP4_HAS_MPU_1GHZ BIT(8) -#define OMAP4_HAS_MPU_1_2GHZ BIT(9) -#define OMAP4_HAS_MPU_1_5GHZ BIT(10) +#define OMAP3_HAS_IO_CHAIN_CTRL BIT(8) +#define OMAP4_HAS_MPU_1GHZ BIT(9) +#define OMAP4_HAS_MPU_1_2GHZ BIT(10) +#define OMAP4_HAS_MPU_1_5GHZ BIT(11) #define OMAP3_HAS_FEATURE(feat,flag) \ @@ -507,12 +515,11 @@ OMAP3_HAS_FEATURE(isp, ISP) OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK) OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP) OMAP3_HAS_FEATURE(sdrc, SDRC) +OMAP3_HAS_FEATURE(io_chain_ctrl, IO_CHAIN_CTRL) /* * Runtime detection of OMAP4 features */ -extern u32 omap_features; - #define OMAP4_HAS_FEATURE(feat, flag) \ static inline unsigned int omap4_has_ ##feat(void) \ { \ -- 1.7.6.3 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v3] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection 2011-10-06 23:18 ` Paul Walmsley @ 2011-10-07 20:40 ` Kevin Hilman -1 siblings, 0 replies; 22+ messages in thread From: Kevin Hilman @ 2011-10-07 20:40 UTC (permalink / raw) To: Paul Walmsley Cc: Steve Sakoman, dhylands, linux-omap, Russell King - ARM Linux, linux-arm-kernel Paul Walmsley <paul@pwsan.com> writes: > The way that we detect which OMAP3 chips support I/O wakeup and > software I/O chain clock control is broken. > > Currently, I/O wakeup is marked as present for all OMAP3 SoCs other > than the AM3505/3517. The TI81xx family of SoCs are at present > considered to be OMAP3 SoCs, but don't support I/O wakeup. To resolve > this, convert the existing blacklist approach to an explicit, > whitelist support, in which only SoCs which are known to support I/O > wakeup are listed. (At present, this only includes OMAP34xx, > OMAP3503, OMAP3515, OMAP3525, OMAP3530, and OMAP36xx.) > > Also, the current code incorrectly detects the presence of a > software-controllable I/O chain clock on several chips that don't > support it. This results in writes to reserved bitfields, unnecessary > delays, and console messages on kernels running on those chips: > > http://www.spinics.net/lists/linux-omap/msg58735.html > > Convert this test to a feature test with a chip-by-chip whitelist. > > Thanks to Dave Hylands <dhylands@gmail.com> for reporting this problem > and doing some testing to help isolate the cause. Thanks to Steve > Sakoman <sakoman@gmail.com> for catching a bug in the first version of > this patch. Thanks to Russell King <linux@arm.linux.org.uk> for > comments. > > Signed-off-by: Paul Walmsley <paul@pwsan.com> > Cc: Kevin Hilman <khilman@ti.com> > Cc: Dave Hylands <dhylands@gmail.com> > Cc: Steve Sakoman <sakoman@gmail.com> > Tested-by: Steve Sakoman <sakoman@gmail.com> > Cc: Russell King - ARM Linux <linux@arm.linux.org.uk> > --- > > This version incorporates some comments from RMK - an unnecessary > set of parentheses are removed and a two-part error message string is > joined. Also, the printk(KERN_ERR has been converted into a pr_err(. OK, looks like we made some parallel changes. Dropping my version and will queue this one (branch: for_3.2/pm-cleanup-2) Kevin ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v3] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection @ 2011-10-07 20:40 ` Kevin Hilman 0 siblings, 0 replies; 22+ messages in thread From: Kevin Hilman @ 2011-10-07 20:40 UTC (permalink / raw) To: linux-arm-kernel Paul Walmsley <paul@pwsan.com> writes: > The way that we detect which OMAP3 chips support I/O wakeup and > software I/O chain clock control is broken. > > Currently, I/O wakeup is marked as present for all OMAP3 SoCs other > than the AM3505/3517. The TI81xx family of SoCs are at present > considered to be OMAP3 SoCs, but don't support I/O wakeup. To resolve > this, convert the existing blacklist approach to an explicit, > whitelist support, in which only SoCs which are known to support I/O > wakeup are listed. (At present, this only includes OMAP34xx, > OMAP3503, OMAP3515, OMAP3525, OMAP3530, and OMAP36xx.) > > Also, the current code incorrectly detects the presence of a > software-controllable I/O chain clock on several chips that don't > support it. This results in writes to reserved bitfields, unnecessary > delays, and console messages on kernels running on those chips: > > http://www.spinics.net/lists/linux-omap/msg58735.html > > Convert this test to a feature test with a chip-by-chip whitelist. > > Thanks to Dave Hylands <dhylands@gmail.com> for reporting this problem > and doing some testing to help isolate the cause. Thanks to Steve > Sakoman <sakoman@gmail.com> for catching a bug in the first version of > this patch. Thanks to Russell King <linux@arm.linux.org.uk> for > comments. > > Signed-off-by: Paul Walmsley <paul@pwsan.com> > Cc: Kevin Hilman <khilman@ti.com> > Cc: Dave Hylands <dhylands@gmail.com> > Cc: Steve Sakoman <sakoman@gmail.com> > Tested-by: Steve Sakoman <sakoman@gmail.com> > Cc: Russell King - ARM Linux <linux@arm.linux.org.uk> > --- > > This version incorporates some comments from RMK - an unnecessary > set of parentheses are removed and a two-part error message string is > joined. Also, the printk(KERN_ERR has been converted into a pr_err(. OK, looks like we made some parallel changes. Dropping my version and will queue this one (branch: for_3.2/pm-cleanup-2) Kevin ^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2011-10-07 20:40 UTC | newest] Thread overview: 22+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-10-06 19:11 [PATCH] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection Paul Walmsley 2011-10-06 19:11 ` Paul Walmsley 2011-10-06 19:42 ` Steve Sakoman 2011-10-06 19:42 ` Steve Sakoman 2011-10-06 19:46 ` Paul Walmsley 2011-10-06 19:46 ` Paul Walmsley 2011-10-06 19:47 ` [PATCH v2] " Paul Walmsley 2011-10-06 19:47 ` Paul Walmsley 2011-10-06 21:22 ` Steve Sakoman 2011-10-06 21:22 ` Steve Sakoman 2011-10-06 21:25 ` [PATCH v3] " Paul Walmsley 2011-10-06 21:25 ` Paul Walmsley 2011-10-06 23:46 ` Kevin Hilman 2011-10-06 23:46 ` Kevin Hilman 2011-10-06 22:29 ` [PATCH v2] " Russell King - ARM Linux 2011-10-06 22:29 ` Russell King - ARM Linux 2011-10-06 23:07 ` Paul Walmsley 2011-10-06 23:07 ` Paul Walmsley 2011-10-06 23:18 ` [PATCH v3] " Paul Walmsley 2011-10-06 23:18 ` Paul Walmsley 2011-10-07 20:40 ` Kevin Hilman 2011-10-07 20:40 ` Kevin Hilman
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.