* [PATCH] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection
@ 2011-10-06 18:29 Paul Walmsley
0 siblings, 0 replies; 5+ messages in thread
From: Paul Walmsley @ 2011-10-06 18:29 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>
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] 5+ 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
2011-10-06 19:42 ` Steve Sakoman
0 siblings, 1 reply; 5+ 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] 5+ 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
@ 2011-10-06 19:42 ` Steve Sakoman
2011-10-06 19:46 ` Paul Walmsley
0 siblings, 1 reply; 5+ 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] 5+ 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
0 siblings, 0 replies; 5+ 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] 5+ messages in thread
* [PATCH] 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; 5+ messages in thread
From: Paul Walmsley @ 2011-10-06 21:25 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: Dave Hylands <dhylands@gmail.com>
Cc: Steve Sakoman <sakoman@gmail.com>
Tested-by: Steve Sakoman <sakoman@gmail.com>
[khilman at 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] 5+ messages in thread
end of thread, other threads:[~2011-10-06 21:25 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-10-06 18:29 [PATCH] ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection Paul Walmsley
-- strict thread matches above, loose matches on Subject: below --
2011-10-06 19:11 Paul Walmsley
2011-10-06 19:42 ` Steve Sakoman
2011-10-06 19:46 ` Paul Walmsley
2011-10-06 21:25 Paul Walmsley
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).