On OMAP3430ES2+, SSI has both an initiator standby CM_IDLEST bit, and a target idle CM_IDLEST bit. This is a departure from previous silicon, which only had an initiator standby bit. This means that omap2_clk_wait_ready() needs to wait for the SSI module to indicate readiness after both SSI interface and functional clocks are enabled. Thanks to Igor Stoppa <igor.stoppa@xxxxxxxxx>, Richard Woodruff <r-woodruff2@xxxxxx>, and Jouni Högander <jouni.hogander@xxxxxxxxx> for help with this portion of the patch. Signed-off-by: Paul Walmsley <paul@xxxxxxxxx> --- arch/arm/mach-omap2/clock.c | 59 ++++++++++++++++++++------------- arch/arm/mach-omap2/cm-regbits-34xx.h | 3 +- 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 343477b..59b042f 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -246,28 +246,31 @@ static void omap2_clk_wait_ready(struct clk *clk) } /* REVISIT: What are the appropriate exclusions for 34XX? */ - if (cpu_is_omap34xx() && - prcm_mod == OMAP34XX_CM_REGADDR(OMAP3430_DSS_MOD, 0)) { + if (cpu_is_omap34xx()) { - /* 3430ES1 DSS has no target idlest bits */ - if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0)) + /* SSI */ + if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0) && + prcm_mod == OMAP34XX_CM_REGADDR(CORE_MOD, 0) && + (reg & 0x0f) == 0 && + clk->enable_bit == OMAP3430_EN_SSI_SHIFT) return; - /* - * For 3430ES2+ DSS, only wait once (dss1_alwon_fclk, - * dss_l3_iclk, dss_l4_iclk) are enabled - */ - if (clk->enable_bit != OMAP3430_EN_DSS1_SHIFT) - return; + /* DSS */ + if (prcm_mod == OMAP34XX_CM_REGADDR(OMAP3430_DSS_MOD, 0)) { - } + /* 3430ES1 DSS has no target idlest bits */ + if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0)) + return; - /* REVISIT: SSI has a target idlest bit on OMAP3 */ - /* REVISIT: This could accidentally exclude other clocks also */ - if (cpu_is_omap34xx() && - prcm_mod == OMAP34XX_CM_REGADDR(CORE_MOD, 0) && - clk->enable_bit == OMAP3430_EN_SSI_SHIFT) - return; + /* + * For 3430ES2+ DSS, only wait once (dss1_alwon_fclk, + * dss_l3_iclk, dss_l4_iclk) are enabled + */ + if (clk->enable_bit != OMAP3430_EN_DSS1_SHIFT) + return; + } + + } /* Check if both functional and interface clocks * are running. */ @@ -276,13 +279,23 @@ static void omap2_clk_wait_ready(struct clk *clk) return; /* - * OMAP3430ES2 DSS target idlest bit is at a different shift than - * the corresponding {I,F}CLKEN bits + * OMAP3430ES2+ has target idlest bits at unusual offsets for + * modules with both initiator and target agents */ - if (cpu_is_omap34xx() && - prcm_mod == OMAP34XX_CM_REGADDR(OMAP3430_DSS_MOD, 0) && - clk->enable_bit == OMAP3430_EN_DSS1_SHIFT) - bit = OMAP3430ES2_ST_DSS_IDLE; + if (cpu_is_omap34xx()) { + + /* SSI */ + if (prcm_mod == OMAP34XX_CM_REGADDR(CORE_MOD, 0) && + (reg & 0x0f) == 0 && + clk->enable_bit == OMAP3430_EN_SSI_SHIFT) + bit = OMAP3430ES2_ST_SSI_IDLE; + + /* DSS */ + if (prcm_mod == OMAP34XX_CM_REGADDR(OMAP3430_DSS_MOD, 0) && + clk->enable_bit == OMAP3430_EN_DSS1_SHIFT) + bit = OMAP3430ES2_ST_DSS_IDLE; + + } st_reg = ((other_reg & ~0xf0) | 0x20); /* CM_IDLEST* */ diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h index 946c552..971b9ad 100644 --- a/arch/arm/mach-omap2/cm-regbits-34xx.h +++ b/arch/arm/mach-omap2/cm-regbits-34xx.h @@ -190,11 +190,12 @@ #define OMAP3430_ST_MSPRO (1 << 23) #define OMAP3430_ST_HDQ (1 << 22) #define OMAP3430ES1_ST_FAC (1 << 8) +#define OMAP3430ES2_ST_SSI_IDLE (1 << 8) #define OMAP3430ES1_ST_MAILBOXES (1 << 7) #define OMAP3430_ST_OMAPCTRL (1 << 6) #define OMAP3430_ST_SDMA (1 << 2) #define OMAP3430_ST_SDRC (1 << 1) -#define OMAP3430_ST_SSI (1 << 0) +#define OMAP3430_ST_SSI_STDBY (1 << 0) /* CM_IDLEST2_CORE */ #define OMAP3430_ST_PKA (1 << 4) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html