* [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
0 siblings, 1 reply; 11+ 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] 11+ messages in thread* [PATCH] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection
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:42 ` Steve Sakoman
2011-10-06 19:46 ` Paul Walmsley
2011-10-06 19:47 ` [PATCH v2] " Paul Walmsley
0 siblings, 2 replies; 11+ 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] 11+ 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
@ 2011-10-06 19:46 ` Paul Walmsley
2011-10-06 19:47 ` [PATCH v2] " Paul Walmsley
1 sibling, 0 replies; 11+ 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] 11+ 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:46 ` Paul Walmsley
@ 2011-10-06 19:47 ` Paul Walmsley
2011-10-06 21:22 ` Steve Sakoman
2011-10-06 22:29 ` [PATCH v2] " Russell King - ARM Linux
1 sibling, 2 replies; 11+ 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] 11+ messages in thread* [PATCH v2] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection
2011-10-06 19:47 ` [PATCH v2] " Paul Walmsley
@ 2011-10-06 21:22 ` Steve Sakoman
2011-10-06 21:25 ` [PATCH v3] " Paul Walmsley
2011-10-06 22:29 ` [PATCH v2] " Russell King - ARM Linux
1 sibling, 1 reply; 11+ 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] 11+ 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
2011-10-06 23:46 ` Kevin Hilman
0 siblings, 1 reply; 11+ messages in thread
From: Paul Walmsley @ 2011-10-06 21:25 UTC (permalink / raw)
To: linux-arm-kernel
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v3] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection
2011-10-06 21:25 ` [PATCH v3] " Paul Walmsley
@ 2011-10-06 23:46 ` Kevin Hilman
0 siblings, 0 replies; 11+ 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] 11+ messages in thread
* [PATCH v2] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection
2011-10-06 19:47 ` [PATCH v2] " Paul Walmsley
2011-10-06 21:22 ` Steve Sakoman
@ 2011-10-06 22:29 ` Russell King - ARM Linux
2011-10-06 23:07 ` Paul Walmsley
2011-10-06 23:18 ` [PATCH v3] " Paul Walmsley
1 sibling, 2 replies; 11+ 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] 11+ messages in thread* [PATCH v2] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection
2011-10-06 22:29 ` [PATCH v2] " Russell King - ARM Linux
@ 2011-10-06 23:07 ` Paul Walmsley
2011-10-06 23:18 ` [PATCH v3] " Paul Walmsley
1 sibling, 0 replies; 11+ 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] 11+ messages in thread* [PATCH v3] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection
2011-10-06 22:29 ` [PATCH v2] " Russell King - ARM Linux
2011-10-06 23:07 ` Paul Walmsley
@ 2011-10-06 23:18 ` Paul Walmsley
2011-10-07 20:40 ` Kevin Hilman
1 sibling, 1 reply; 11+ 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] 11+ messages in thread* [PATCH v3] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection
2011-10-06 23:18 ` [PATCH v3] " Paul Walmsley
@ 2011-10-07 20:40 ` Kevin Hilman
0 siblings, 0 replies; 11+ 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] 11+ messages in thread
end of thread, other threads:[~2011-10-07 20:40 UTC | newest]
Thread overview: 11+ 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:42 ` Steve Sakoman
2011-10-06 19:46 ` Paul Walmsley
2011-10-06 19:47 ` [PATCH v2] " Paul Walmsley
2011-10-06 21:22 ` Steve Sakoman
2011-10-06 21:25 ` [PATCH v3] " Paul Walmsley
2011-10-06 23:46 ` Kevin Hilman
2011-10-06 22:29 ` [PATCH v2] " Russell King - ARM Linux
2011-10-06 23:07 ` Paul Walmsley
2011-10-06 23:18 ` [PATCH v3] " Paul Walmsley
2011-10-07 20:40 ` Kevin Hilman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).