/** * omap2430_clk_i2chs_find_idlest - return CM_IDLEST info for 2430 I2CHS * @clk: struct clk * being enabled * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into * * OMAP2430 I2CHS CM_IDLEST bits are in CM_IDLEST1_CORE, but the * CM_*CLKEN bits are in CM_{I,F}CLKEN2_CORE. This custom function * passes back the correct CM_IDLEST register address for I2CHS * modules. No return value. */ static void omap2430_clk_i2chs_find_idlest(struct clk *clk, void __iomem **idlest_reg, u8 *idlest_bit) { *idlest_reg = OMAP_CM_REGADDR(CORE_MOD, CM_IDLEST); *idlest_bit = clk->enable_bit; }
/* Enable an APLL if off */ static int omap2_clk_fixed_enable(struct clk *clk) { u32 cval, apll_mask; apll_mask = EN_APLL_LOCKED << clk->enable_bit; cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN); if ((cval & apll_mask) == apll_mask) return 0; /* apll already enabled */ cval &= ~apll_mask; cval |= apll_mask; cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN); if (clk == &apll96_ck) cval = OMAP24XX_ST_96M_APLL; else if (clk == &apll54_ck) cval = OMAP24XX_ST_54M_APLL; omap2_wait_clock_ready(OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), cval, clk->name); /* * REVISIT: Should we return an error code if omap2_wait_clock_ready() * fails? */ return 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 */ static void omap2_clk_wait_ready(struct clk *clk) { void __iomem *reg, *other_reg, *st_reg; u32 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 ((((u32)reg & 0xff) >= CM_FCLKEN1) && (((u32)reg & 0xff) <= OMAP24XX_CM_FCLKEN2)) other_reg = (void __iomem *)(((u32)reg & ~0xf0) | 0x10); /* CM_ICLKEN* */ else if ((((u32)reg & 0xff) >= CM_ICLKEN1) && (((u32)reg & 0xff) <= OMAP24XX_CM_ICLKEN4)) other_reg = (void __iomem *)(((u32)reg & ~0xf0) | 0x00); /* CM_FCLKEN* */ else return; /* REVISIT: What are the appropriate exclusions for 34XX? */ /* No check for DSS or cam clocks */ if (cpu_is_omap24xx() && ((u32)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; } /* REVISIT: What are the appropriate exclusions for 34XX? */ /* OMAP3: ignore DSS-mod clocks */ if (cpu_is_omap34xx() && (((u32)reg & ~0xff) == (u32)OMAP_CM_REGADDR(OMAP3430_DSS_MOD, 0) || ((((u32)reg & ~0xff) == (u32)OMAP_CM_REGADDR(CORE_MOD, 0)) && clk->enable_bit == OMAP3430_EN_SSI_SHIFT))) return; /* Check if both functional and interface clocks * are running. */ bit = 1 << clk->enable_bit; if (!(__raw_readl(other_reg) & bit)) return; st_reg = (void __iomem *)(((u32)other_reg & ~0xf0) | 0x20); /* CM_IDLEST* */ omap2_wait_clock_ready(st_reg, bit, clk->name); }
/* Enable an APLL if off */ static int omap2_clk_apll_enable(struct clk *clk, u32 status_mask) { u32 cval, apll_mask; apll_mask = EN_APLL_LOCKED << clk->enable_bit; cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN); if ((cval & apll_mask) == apll_mask) return 0; /* apll already enabled */ cval &= ~apll_mask; cval |= apll_mask; cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN); omap2_cm_wait_idlest(OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), status_mask, clk->name); /* * REVISIT: Should we return an error code if omap2_wait_clock_ready() * fails? */ return 0; }