Simplify omap2_clk_wait_ready() to use the new idlest_bit field in struct clk, rather than a hunk of conditionals. Others who have contributed to the patches in this rollup by reporting bugs, testing, or reviewing include: - Anand Gadiyar <gadiyar@xxxxxx> - Koen Kooi <k.kooi@xxxxxxxxxxxxxxxxxx> - Dirk Behme <dirk.behme@xxxxxxxxxxxxxx> - Igor Stoppa <igor.stoppa@xxxxxxxxx> - Richard Woodruff <r-woodruff2@xxxxxx> - Jouni Högander <jouni.hogander@xxxxxxxxx> More information can be found at the original source commits below. linux-omap source commits are 999ccb505e4fa5720add74589fe747affcd7aa81, f4c458db2b615037f7c1fd91d238f6420e7b8f77, e2d8a430aab87fdc47b7f01de804e17b8960042d, 201fb6b950b41a798aa54ee78588ac68aed28a0a, 205f37af718984ec67444bccc888cd575531bce1, 0fe3bd3fb03ab35063b1d17070b24bfa007896c3, 3fa8636974ca1c04797781fb300c2e29ec18c3a8, 6f55ed7c13d655189da305207cf323041e4bcc4d, and fd183f64d5325d727124d88c50b401a7da9c89c1. Signed-off-by: Paul Walmsley <paul@xxxxxxxxx> Signed-off-by: Tony Lindgren <tony@xxxxxxxxxxx> Cc: Anand Gadiyar <gadiyar@xxxxxx> Cc: Koen Kooi <k.kooi@xxxxxxxxxxxxxxxxxx> Cc: Dirk Behme <dirk.behme@xxxxxxxxxxxxxx> Cc: Igor Stoppa <igor.stoppa@xxxxxxxxx> Cc: Richard Woodruff <r-woodruff2@xxxxxx> Cc: Jouni Högander <jouni.hogander@xxxxxxxxx> --- arch/arm/mach-omap2/clock.c | 93 ++++++++++++++++++++------------------- arch/arm/mach-omap2/clock.h | 3 + arch/arm/mach-omap2/clock24xx.c | 10 ---- 3 files changed, 51 insertions(+), 55 deletions(-) diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index dff4eaa..0cd4761 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -70,6 +70,13 @@ #define DPLL_FINT_UNDERFLOW -1 #define DPLL_FINT_INVALID -2 +/* Bitmask to isolate the register type of clk.enable_reg */ +#define PRCM_REGTYPE_MASK 0xf0 +/* various CM register type options */ +#define CM_FCLKEN_REGTYPE 0x00 +#define CM_ICLKEN_REGTYPE 0x10 +#define CM_IDLEST_REGTYPE 0x20 + u8 cpu_mask; /*------------------------------------------------------------------------- @@ -300,17 +307,18 @@ void omap2_fixed_divisor_recalc(struct clk *clk) /** * omap2_wait_clock_ready - wait for clock to enable - * @reg: physical address of clock IDLEST register + * @prcm_mod: CM submodule offset from CM_BASE (e.g., "MPU_MOD") + * @reg_index: offset of CM register address from prcm_mod * @mask: value to mask against to determine if the clock is active * @name: name of the clock (for printk) * * Returns 1 if the clock enabled in time, or 0 if it failed to enable * in roughly MAX_CLOCK_ENABLE_WAIT microseconds. */ -int omap2_wait_clock_ready(void __iomem *reg, u32 mask, const char *name) +int omap2_wait_clock_ready(s16 prcm_mod, u16 reg_index, u32 mask, + const char *name) { - int i = 0; - int ena = 0; + int i = 0, ena = 0; /* * 24xx uses 0 to indicate not ready, and 1 to indicate ready. @@ -322,7 +330,7 @@ int omap2_wait_clock_ready(void __iomem *reg, u32 mask, const char *name) ena = 0; /* Wait for lock */ - while (((__raw_readl(reg) & mask) != ena) && + while (((cm_read_mod_reg(prcm_mod, reg_index) & mask) != ena) && (i++ < MAX_CLOCK_ENABLE_WAIT)) { udelay(1); } @@ -333,61 +341,56 @@ int omap2_wait_clock_ready(void __iomem *reg, u32 mask, const char *name) printk(KERN_ERR "Clock %s didn't enable in %d tries\n", name, MAX_CLOCK_ENABLE_WAIT); - return (i < MAX_CLOCK_ENABLE_WAIT) ? 1 : 0; }; /* - * Note: We don't need special code here for INVERT_ENABLE - * for the time being since INVERT_ENABLE only applies to clocks enabled by - * CM_CLKEN_PLL + * omap2_clk_wait_ready - wait for a OMAP module to come out of target idle + * @clk: struct clk * recently enabled to indicate the module to test + * + * Wait for an OMAP module with a target idle state bit to come out of + * idle once both its interface clock and primary functional clock are + * both enabled. Any register read or write to the device before it + * returns from idle will cause an abort. Not all modules have target + * idle state bits (for example, DSS and CAM on OMAP24xx); so we don't + * wait for those. No return value. + * + * We don't need special code here for INVERT_ENABLE for the time + * being since INVERT_ENABLE only applies to clocks enabled by + * CM_CLKEN_PLL. + * + * REVISIT: This function is misnamed: it should be something like + * "omap2_module_wait_ready", and in the long-term, it does not belong + * in the clock framework. It also shouldn't be doing register + * arithmetic to determine the companion clock. */ static void omap2_clk_wait_ready(struct clk *clk) { - void __iomem *other_reg, *st_reg; - u16 reg; - u32 bit; + u16 other_reg, idlest_reg; + u32 other_bit; - /* - * REVISIT: This code is pretty ugly. It would be nice to generalize - * it and pull it into struct clk itself somehow. - */ - reg = clk->enable_reg; - if (((reg & 0xff) >= CM_FCLKEN1) && - ((reg & 0xff) <= OMAP24XX_CM_FCLKEN2)) - other_reg = (void __iomem *)((reg & ~0xf0) | 0x10); /* CM_ICLKEN* */ - else if (((reg & 0xff) >= CM_ICLKEN1) && - ((reg & 0xff) <= OMAP24XX_CM_ICLKEN4)) - other_reg = (void __iomem *)((reg & ~0xf0) | 0x00); /* CM_FCLKEN* */ - else + if (!(clk->flags & WAIT_READY)) return; - /* REVISIT: What are the appropriate exclusions for 34XX? */ - /* No check for DSS or cam clocks */ - if (cpu_is_omap24xx() && (reg & 0x0f) == 0) { /* CM_{F,I}CLKEN1 */ - if (clk->enable_bit == OMAP24XX_EN_DSS2_SHIFT || - clk->enable_bit == OMAP24XX_EN_DSS1_SHIFT || - clk->enable_bit == OMAP24XX_EN_CAM_SHIFT) - return; - } + /* If we are enabling an iclk, also test the fclk; and vice versa */ + other_bit = 1 << clk->enable_bit; + other_reg = clk->enable_reg & ~PRCM_REGTYPE_MASK; - /* REVISIT: What are the appropriate exclusions for 34XX? */ - /* OMAP3: ignore DSS-mod clocks */ - if (cpu_is_omap34xx() && - ((reg & ~0xff) == cm_read_mod_reg(OMAP3430_DSS_MOD, 0) || - (((reg & ~0xff) == cm_read_mod_reg(CORE_MOD, 0)) && - clk->enable_bit == OMAP3430_EN_SSI_SHIFT))) - return; + if (clk->enable_reg & CM_ICLKEN_REGTYPE) + other_reg |= CM_FCLKEN_REGTYPE; + else + other_reg |= CM_ICLKEN_REGTYPE; - /* Check if both functional and interface clocks - * are running. */ - bit = 1 << clk->enable_bit; - if (!(__raw_readl(other_reg) & bit)) + /* Ensure functional and interface clocks are running. */ + if (!(cm_read_mod_reg(clk->prcm_mod, other_reg) & other_bit)) return; - st_reg = (void __iomem *)(((u32)other_reg & ~0xf0) | 0x20); /* CM_IDLEST* */ - omap2_wait_clock_ready(st_reg, bit, clk->name); + idlest_reg = other_reg & ~PRCM_REGTYPE_MASK; + idlest_reg |= CM_IDLEST_REGTYPE; + + omap2_wait_clock_ready(clk->prcm_mod, idlest_reg, 1 << clk->idlest_bit, + clk->name); } /* Enables clock without considering parent dependencies or use count diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index 4dbd582..faff95e 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -64,7 +64,8 @@ void omap2_fixed_divisor_recalc(struct clk *clk); long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate); int omap2_clksel_set_rate(struct clk *clk, unsigned long rate); u32 omap2_get_dpll_rate(struct clk *clk); -int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name); +int omap2_wait_clock_ready(s16 prcm_mod, u16 idlest_reg, u32 cval, + const char *name); void omap2_clk_prepare_for_reboot(void); extern u8 cpu_mask; diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c index 2047c06..e66287f 100644 --- a/arch/arm/mach-omap2/clock24xx.c +++ b/arch/arm/mach-omap2/clock24xx.c @@ -107,7 +107,6 @@ static void omap2_disable_osc_ck(struct clk *clk) static int omap2_clk_fixed_enable(struct clk *clk) { u32 cval, apll_mask; - void __iomem *idlest; apll_mask = EN_APLL_LOCKED << clk->enable_bit; @@ -125,14 +124,7 @@ static int omap2_clk_fixed_enable(struct clk *clk) else if (clk == &apll54_ck) cval = OMAP24XX_ST_54M_APLL; - if (cpu_is_omap242x()) - idlest = (__force void __iomem *)OMAP2420_CM_REGADDR(PLL_MOD, - CM_IDLEST); - else - idlest = (__force void __iomem *)OMAP2430_CM_REGADDR(PLL_MOD, - CM_IDLEST); - - omap2_wait_clock_ready(idlest, cval, clk->name); + omap2_wait_clock_ready(PLL_MOD, CM_IDLEST, cval, clk->name); /* * REVISIT: Should we return an error code if omap2_wait_clock_ready() -- 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