aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2011-10-06 19:18:45 -0400
committerKevin Hilman <khilman@ti.com>2011-10-07 16:41:49 -0400
commitb02b917211d50ad5dc13e49c933ef916b10e0d00 (patch)
tree138707c1aab31b0263cb1bd02ba4678c6a7d80f5 /arch/arm
parentff2f8e5ffb23de6e2284f31651447cb80a4c9d1b (diff)
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. Thanks to Russell King <linux@arm.linux.org.uk> for comments. 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> Cc: Russell King - ARM Linux <linux@arm.linux.org.uk> Signed-off-by: Kevin Hilman <khilman@ti.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-omap2/id.c5
-rw-r--r--arch/arm/mach-omap2/pm34xx.c43
-rw-r--r--arch/arm/plat-omap/include/plat/cpu.h17
3 files changed, 38 insertions, 27 deletions
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 37efb869692..a1ccb66fbe7 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)
201 OMAP3_CHECK_FEATURE(status, ISP); 201 OMAP3_CHECK_FEATURE(status, ISP);
202 if (cpu_is_omap3630()) 202 if (cpu_is_omap3630())
203 omap_features |= OMAP3_HAS_192MHZ_CLK; 203 omap_features |= OMAP3_HAS_192MHZ_CLK;
204 if (!cpu_is_omap3505() && !cpu_is_omap3517()) 204 if (cpu_is_omap3430() || cpu_is_omap3630())
205 omap_features |= OMAP3_HAS_IO_WAKEUP; 205 omap_features |= OMAP3_HAS_IO_WAKEUP;
206 if (cpu_is_omap3630() || omap_rev() == OMAP3430_REV_ES3_1 ||
207 omap_rev() == OMAP3430_REV_ES3_1_2)
208 omap_features |= OMAP3_HAS_IO_CHAIN_CTRL;
206 209
207 omap_features |= OMAP3_HAS_SDRC; 210 omap_features |= OMAP3_HAS_SDRC;
208 211
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 1915050e940..bfa8b8c8171 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)
99{ 99{
100 int timeout = 0; 100 int timeout = 0;
101 101
102 if (omap_rev() >= OMAP3430_REV_ES3_1) { 102 omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
103 omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, 103 PM_WKEN);
104 PM_WKEN); 104 /* Do a readback to assure write has been done */
105 /* Do a readback to assure write has been done */ 105 omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
106 omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN); 106
107 107 while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) &
108 while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) & 108 OMAP3430_ST_IO_CHAIN_MASK)) {
109 OMAP3430_ST_IO_CHAIN_MASK)) { 109 timeout++;
110 timeout++; 110 if (timeout > 1000) {
111 if (timeout > 1000) { 111 pr_err("Wake up daisy chain activation failed.\n");
112 printk(KERN_ERR "Wake up daisy chain " 112 return;
113 "activation failed.\n");
114 return;
115 }
116 omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK,
117 WKUP_MOD, PM_WKEN);
118 } 113 }
114 omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK,
115 WKUP_MOD, PM_WKEN);
119 } 116 }
120} 117}
121 118
122static void omap3_disable_io_chain(void) 119static void omap3_disable_io_chain(void)
123{ 120{
124 if (omap_rev() >= OMAP3430_REV_ES3_1) 121 omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
125 omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD, 122 PM_WKEN);
126 PM_WKEN);
127} 123}
128 124
129static void omap3_core_save_context(void) 125static void omap3_core_save_context(void)
@@ -375,7 +371,8 @@ void omap_sram_idle(void)
375 (per_next_state < PWRDM_POWER_ON || 371 (per_next_state < PWRDM_POWER_ON ||
376 core_next_state < PWRDM_POWER_ON)) { 372 core_next_state < PWRDM_POWER_ON)) {
377 omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); 373 omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN);
378 omap3_enable_io_chain(); 374 if (omap3_has_io_chain_ctrl())
375 omap3_enable_io_chain();
379 } 376 }
380 377
381 /* Block console output in case it is on one of the OMAP UARTs */ 378 /* Block console output in case it is on one of the OMAP UARTs */
@@ -478,7 +475,8 @@ console_still_active:
478 core_next_state < PWRDM_POWER_ON)) { 475 core_next_state < PWRDM_POWER_ON)) {
479 omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, 476 omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
480 PM_WKEN); 477 PM_WKEN);
481 omap3_disable_io_chain(); 478 if (omap3_has_io_chain_ctrl())
479 omap3_disable_io_chain();
482 } 480 }
483 481
484 clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]); 482 clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]);
@@ -871,6 +869,9 @@ static int __init omap3_pm_init(void)
871 if (!cpu_is_omap34xx()) 869 if (!cpu_is_omap34xx())
872 return -ENODEV; 870 return -ENODEV;
873 871
872 if (!omap3_has_io_chain_ctrl())
873 pr_warning("PM: no software I/O chain control; some wakeups may be lost\n");
874
874 pm_errata_configure(); 875 pm_errata_configure();
875 876
876 /* XXX prcm_setup_regs needs to be before enabling hw 877 /* 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 67b3d75884c..3a280aaf967 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);
477 477
478/* 478/*
479 * Runtime detection of OMAP3 features 479 * Runtime detection of OMAP3 features
480 *
481 * OMAP3_HAS_IO_CHAIN_CTRL: Some later members of the OMAP3 chip
482 * family have OS-level control over the I/O chain clock. This is
483 * to avoid a window during which wakeups could potentially be lost
484 * during powerdomain transitions. If this bit is set, it
485 * indicates that the chip does support OS-level control of this
486 * feature.
480 */ 487 */
481extern u32 omap_features; 488extern u32 omap_features;
482 489
@@ -488,9 +495,10 @@ extern u32 omap_features;
488#define OMAP3_HAS_192MHZ_CLK BIT(5) 495#define OMAP3_HAS_192MHZ_CLK BIT(5)
489#define OMAP3_HAS_IO_WAKEUP BIT(6) 496#define OMAP3_HAS_IO_WAKEUP BIT(6)
490#define OMAP3_HAS_SDRC BIT(7) 497#define OMAP3_HAS_SDRC BIT(7)
491#define OMAP4_HAS_MPU_1GHZ BIT(8) 498#define OMAP3_HAS_IO_CHAIN_CTRL BIT(8)
492#define OMAP4_HAS_MPU_1_2GHZ BIT(9) 499#define OMAP4_HAS_MPU_1GHZ BIT(9)
493#define OMAP4_HAS_MPU_1_5GHZ BIT(10) 500#define OMAP4_HAS_MPU_1_2GHZ BIT(10)
501#define OMAP4_HAS_MPU_1_5GHZ BIT(11)
494 502
495 503
496#define OMAP3_HAS_FEATURE(feat,flag) \ 504#define OMAP3_HAS_FEATURE(feat,flag) \
@@ -507,12 +515,11 @@ OMAP3_HAS_FEATURE(isp, ISP)
507OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK) 515OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK)
508OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP) 516OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP)
509OMAP3_HAS_FEATURE(sdrc, SDRC) 517OMAP3_HAS_FEATURE(sdrc, SDRC)
518OMAP3_HAS_FEATURE(io_chain_ctrl, IO_CHAIN_CTRL)
510 519
511/* 520/*
512 * Runtime detection of OMAP4 features 521 * Runtime detection of OMAP4 features
513 */ 522 */
514extern u32 omap_features;
515
516#define OMAP4_HAS_FEATURE(feat, flag) \ 523#define OMAP4_HAS_FEATURE(feat, flag) \
517static inline unsigned int omap4_has_ ##feat(void) \ 524static inline unsigned int omap4_has_ ##feat(void) \
518{ \ 525{ \