Loading arch/arm/mach-omap2/clkt_dpll.c +45 −53 Original line number Diff line number Diff line Loading @@ -21,10 +21,7 @@ #include <asm/div64.h> #include "soc.h" #include "clock.h" #include "cm-regbits-24xx.h" #include "cm-regbits-34xx.h" /* DPLL rate rounding: minimum DPLL multiplier, divider values */ #define DPLL_MIN_MULTIPLIER 2 Loading @@ -44,20 +41,12 @@ #define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \ (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE)) /* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */ #define OMAP3430_DPLL_FINT_BAND1_MIN 750000 #define OMAP3430_DPLL_FINT_BAND1_MAX 2100000 #define OMAP3430_DPLL_FINT_BAND2_MIN 7500000 #define OMAP3430_DPLL_FINT_BAND2_MAX 21000000 /* * DPLL valid Fint frequency range for OMAP36xx and OMAP4xxx. * From device data manual section 4.3 "DPLL and DLL Specifications". */ #define OMAP3PLUS_DPLL_FINT_JTYPE_MIN 500000 #define OMAP3PLUS_DPLL_FINT_JTYPE_MAX 2500000 #define OMAP3PLUS_DPLL_FINT_MIN 32000 #define OMAP3PLUS_DPLL_FINT_MAX 52000000 /* _dpll_test_fint() return codes */ #define DPLL_FINT_UNDERFLOW -1 Loading Loading @@ -87,33 +76,31 @@ static int _dpll_test_fint(struct clk_hw_omap *clk, unsigned int n) /* DPLL divider must result in a valid jitter correction val */ fint = __clk_get_rate(__clk_get_parent(clk->hw.clk)) / n; if (cpu_is_omap24xx()) { /* Should not be called for OMAP2, so warn if it is called */ WARN(1, "No fint limits available for OMAP2!\n"); return DPLL_FINT_INVALID; } else if (cpu_is_omap3430()) { fint_min = OMAP3430_DPLL_FINT_BAND1_MIN; fint_max = OMAP3430_DPLL_FINT_BAND2_MAX; } else if (dd->flags & DPLL_J_TYPE) { if (dd->flags & DPLL_J_TYPE) { fint_min = OMAP3PLUS_DPLL_FINT_JTYPE_MIN; fint_max = OMAP3PLUS_DPLL_FINT_JTYPE_MAX; } else { fint_min = OMAP3PLUS_DPLL_FINT_MIN; fint_max = OMAP3PLUS_DPLL_FINT_MAX; fint_min = ti_clk_features.fint_min; fint_max = ti_clk_features.fint_max; } if (fint < fint_min) { if (!fint_min || !fint_max) { WARN(1, "No fint limits available!\n"); return DPLL_FINT_INVALID; } if (fint < ti_clk_features.fint_min) { pr_debug("rejecting n=%d due to Fint failure, lowering max_divider\n", n); dd->max_divider = n; ret = DPLL_FINT_UNDERFLOW; } else if (fint > fint_max) { } else if (fint > ti_clk_features.fint_max) { pr_debug("rejecting n=%d due to Fint failure, boosting min_divider\n", n); dd->min_divider = n; ret = DPLL_FINT_INVALID; } else if (cpu_is_omap3430() && fint > OMAP3430_DPLL_FINT_BAND1_MAX && fint < OMAP3430_DPLL_FINT_BAND2_MIN) { } else if (fint > ti_clk_features.fint_band1_max && fint < ti_clk_features.fint_band2_min) { pr_debug("rejecting n=%d due to Fint failure\n", n); ret = DPLL_FINT_INVALID; } Loading Loading @@ -185,6 +172,34 @@ static int _dpll_test_mult(int *m, int n, unsigned long *new_rate, return r; } /** * _omap2_dpll_is_in_bypass - check if DPLL is in bypass mode or not * @v: bitfield value of the DPLL enable * * Checks given DPLL enable bitfield to see whether the DPLL is in bypass * mode or not. Returns 1 if the DPLL is in bypass, 0 otherwise. */ static int _omap2_dpll_is_in_bypass(u32 v) { u8 mask, val; mask = ti_clk_features.dpll_bypass_vals; /* * Each set bit in the mask corresponds to a bypass value equal * to the bitshift. Go through each set-bit in the mask and * compare against the given register value. */ while (mask) { val = __ffs(mask); mask ^= (1 << val); if (v == val) return 1; } return 0; } /* Public functions */ u8 omap2_init_dpll_parent(struct clk_hw *hw) { Loading @@ -201,20 +216,9 @@ u8 omap2_init_dpll_parent(struct clk_hw *hw) v >>= __ffs(dd->enable_mask); /* Reparent the struct clk in case the dpll is in bypass */ if (cpu_is_omap24xx()) { if (v == OMAP2XXX_EN_DPLL_LPBYPASS || v == OMAP2XXX_EN_DPLL_FRBYPASS) return 1; } else if (cpu_is_omap34xx()) { if (v == OMAP3XXX_EN_DPLL_LPBYPASS || v == OMAP3XXX_EN_DPLL_FRBYPASS) if (_omap2_dpll_is_in_bypass(v)) return 1; } else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx()) { if (v == OMAP4XXX_EN_DPLL_LPBYPASS || v == OMAP4XXX_EN_DPLL_FRBYPASS || v == OMAP4XXX_EN_DPLL_MNBYPASS) return 1; } return 0; } Loading Loading @@ -247,20 +251,8 @@ unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk) v &= dd->enable_mask; v >>= __ffs(dd->enable_mask); if (cpu_is_omap24xx()) { if (v == OMAP2XXX_EN_DPLL_LPBYPASS || v == OMAP2XXX_EN_DPLL_FRBYPASS) if (_omap2_dpll_is_in_bypass(v)) return __clk_get_rate(dd->clk_bypass); } else if (cpu_is_omap34xx()) { if (v == OMAP3XXX_EN_DPLL_LPBYPASS || v == OMAP3XXX_EN_DPLL_FRBYPASS) return __clk_get_rate(dd->clk_bypass); } else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx()) { if (v == OMAP4XXX_EN_DPLL_LPBYPASS || v == OMAP4XXX_EN_DPLL_FRBYPASS || v == OMAP4XXX_EN_DPLL_MNBYPASS) return __clk_get_rate(dd->clk_bypass); } v = omap2_clk_readl(clk, dd->mult_div1_reg); dpll_mult = v & dd->mult_mask; Loading arch/arm/mach-omap2/clkt_iclk.c +4 −4 Original line number Diff line number Diff line Loading @@ -14,11 +14,11 @@ #include <linux/clk-provider.h> #include <linux/io.h> #include "clock.h" #include "clock2xxx.h" #include "cm2xxx_3xxx.h" #include "cm-regbits-24xx.h" /* Register offsets */ #define CM_AUTOIDLE 0x30 #define CM_ICLKEN 0x10 /* Private functions */ Loading arch/arm/mach-omap2/clock.c +69 −7 Original line number Diff line number Diff line Loading @@ -46,6 +46,24 @@ u16 cpu_mask; /* * Clock features setup. Used instead of CPU type checks. */ struct ti_clk_features ti_clk_features; /* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */ #define OMAP3430_DPLL_FINT_BAND1_MIN 750000 #define OMAP3430_DPLL_FINT_BAND1_MAX 2100000 #define OMAP3430_DPLL_FINT_BAND2_MIN 7500000 #define OMAP3430_DPLL_FINT_BAND2_MAX 21000000 /* * DPLL valid Fint frequency range for OMAP36xx and OMAP4xxx. * From device data manual section 4.3 "DPLL and DLL Specifications". */ #define OMAP3PLUS_DPLL_FINT_MIN 32000 #define OMAP3PLUS_DPLL_FINT_MAX 52000000 /* * clkdm_control: if true, then when a clock is enabled in the * hardware, its clockdomain will first be enabled; and when a clock Loading Loading @@ -287,13 +305,7 @@ void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk, * 34xx reverses this, just to keep us on our toes * AM35xx uses both, depending on the module. */ if (cpu_is_omap24xx()) *idlest_val = OMAP24XX_CM_IDLEST_VAL; else if (cpu_is_omap34xx()) *idlest_val = OMAP34XX_CM_IDLEST_VAL; else BUG(); *idlest_val = ti_clk_features.cm_idlest_val; } /** Loading Loading @@ -731,3 +743,53 @@ void __init omap2_clk_print_new_rates(const char *hfclkin_ck_name, (clk_get_rate(core_ck) / 1000000), (clk_get_rate(mpu_ck) / 1000000)); } /** * ti_clk_init_features - init clock features struct for the SoC * * Initializes the clock features struct based on the SoC type. */ void __init ti_clk_init_features(void) { /* Fint setup for DPLLs */ if (cpu_is_omap3430()) { ti_clk_features.fint_min = OMAP3430_DPLL_FINT_BAND1_MIN; ti_clk_features.fint_max = OMAP3430_DPLL_FINT_BAND2_MAX; ti_clk_features.fint_band1_max = OMAP3430_DPLL_FINT_BAND1_MAX; ti_clk_features.fint_band2_min = OMAP3430_DPLL_FINT_BAND2_MIN; } else { ti_clk_features.fint_min = OMAP3PLUS_DPLL_FINT_MIN; ti_clk_features.fint_max = OMAP3PLUS_DPLL_FINT_MAX; } /* Bypass value setup for DPLLs */ if (cpu_is_omap24xx()) { ti_clk_features.dpll_bypass_vals |= (1 << OMAP2XXX_EN_DPLL_LPBYPASS) | (1 << OMAP2XXX_EN_DPLL_FRBYPASS); } else if (cpu_is_omap34xx()) { ti_clk_features.dpll_bypass_vals |= (1 << OMAP3XXX_EN_DPLL_LPBYPASS) | (1 << OMAP3XXX_EN_DPLL_FRBYPASS); } else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx() || soc_is_omap54xx() || soc_is_dra7xx()) { ti_clk_features.dpll_bypass_vals |= (1 << OMAP4XXX_EN_DPLL_LPBYPASS) | (1 << OMAP4XXX_EN_DPLL_FRBYPASS) | (1 << OMAP4XXX_EN_DPLL_MNBYPASS); } /* Jitter correction only available on OMAP343X */ if (cpu_is_omap343x()) ti_clk_features.flags |= TI_CLK_DPLL_HAS_FREQSEL; /* Idlest value for interface clocks. * 24xx uses 0 to indicate not ready, and 1 to indicate ready. * 34xx reverses this, just to keep us on our toes * AM35xx uses both, depending on the module. */ if (cpu_is_omap24xx()) ti_clk_features.cm_idlest_val = OMAP24XX_CM_IDLEST_VAL; else if (cpu_is_omap34xx()) ti_clk_features.cm_idlest_val = OMAP34XX_CM_IDLEST_VAL; } arch/arm/mach-omap2/clock.h +19 −25 Original line number Diff line number Diff line Loading @@ -101,31 +101,6 @@ struct clockdomain; }; \ DEFINE_STRUCT_CLK(_name, _parent_names, _ops); #define DEFINE_CLK_OMAP_HSDIVIDER(_name, _parent_name, \ _parent_ptr, _flags, \ _clksel_reg, _clksel_mask) \ static const struct clksel _name##_div[] = { \ { \ .parent = _parent_ptr, \ .rates = div31_1to31_rates \ }, \ { .parent = NULL }, \ }; \ static struct clk _name; \ static const char *_name##_parent_names[] = { \ _parent_name, \ }; \ static struct clk_hw_omap _name##_hw = { \ .hw = { \ .clk = &_name, \ }, \ .clksel = _name##_div, \ .clksel_reg = _clksel_reg, \ .clksel_mask = _clksel_mask, \ .ops = &clkhwops_omap4_dpllmx, \ }; \ DEFINE_STRUCT_CLK(_name, _name##_parent_names, omap_hsdivider_ops); /* struct clksel_rate.flags possibilities */ #define RATE_IN_242X (1 << 0) #define RATE_IN_243X (1 << 1) Loading Loading @@ -248,6 +223,23 @@ void omap2_clk_writel(u32 val, struct clk_hw_omap *clk, void __iomem *reg); extern u16 cpu_mask; /* * Clock features setup. Used instead of CPU type checks. */ struct ti_clk_features { u32 flags; long fint_min; long fint_max; long fint_band1_max; long fint_band2_min; u8 dpll_bypass_vals; u8 cm_idlest_val; }; #define TI_CLK_DPLL_HAS_FREQSEL (1 << 0) extern struct ti_clk_features ti_clk_features; extern const struct clkops clkops_omap2_dflt_wait; extern const struct clkops clkops_dummy; extern const struct clkops clkops_omap2_dflt; Loading Loading @@ -286,4 +278,6 @@ extern int omap2_clkops_enable_clkdm(struct clk_hw *hw); extern void omap2_clkops_disable_clkdm(struct clk_hw *hw); extern void omap_clocks_register(struct omap_clk *oclks, int cnt); void __init ti_clk_init_features(void); #endif arch/arm/mach-omap2/control.c +45 −15 Original line number Diff line number Diff line Loading @@ -44,8 +44,7 @@ struct omap3_scratchpad { }; struct omap3_scratchpad_prcm_block { u32 prm_clksrc_ctrl; u32 prm_clksel; u32 prm_contents[2]; u32 cm_contents[11]; u32 prcm_block_size; }; Loading Loading @@ -282,13 +281,9 @@ void omap3_clear_scratchpad_contents(void) void __iomem *v_addr; u32 offset = 0; v_addr = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD_ROM); if (omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP3_PRM_RSTST_OFFSET) & OMAP3430_GLOBAL_COLD_RST_MASK) { if (omap3xxx_prm_clear_global_cold_reset()) { for ( ; offset <= max_offset; offset += 0x4) writel_relaxed(0x0, (v_addr + offset)); omap2_prm_set_mod_reg_bits(OMAP3430_GLOBAL_COLD_RST_MASK, OMAP3430_GR_MOD, OMAP3_PRM_RSTST_OFFSET); } } Loading Loading @@ -331,13 +326,7 @@ void omap3_save_scratchpad_contents(void) scratchpad_contents.sdrc_block_offset = 0x64; /* Populate the PRCM block contents */ prcm_block_contents.prm_clksrc_ctrl = omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP3_PRM_CLKSRC_CTRL_OFFSET); prcm_block_contents.prm_clksel = omap2_prm_read_mod_reg(OMAP3430_CCR_MOD, OMAP3_PRM_CLKSEL_OFFSET); omap3_prm_save_scratchpad_contents(prcm_block_contents.prm_contents); omap3_cm_save_scratchpad_contents(prcm_block_contents.cm_contents); prcm_block_contents.prcm_block_size = 0x0; Loading Loading @@ -575,9 +564,50 @@ int omap3_ctrl_save_padconf(void) * Sets the bootmode for IVA2 to idle. This is needed by the PM code to * force disable IVA2 so that it does not prevent any low-power states. */ void omap3_ctrl_set_iva_bootmode_idle(void) static void __init omap3_ctrl_set_iva_bootmode_idle(void) { omap_ctrl_writel(OMAP3_IVA2_BOOTMOD_IDLE, OMAP343X_CONTROL_IVA2_BOOTMOD); } /** * omap3_ctrl_setup_d2d_padconf - setup stacked modem pads for idle * * Sets up the pads controlling the stacked modem in such way that the * device can enter idle. */ static void __init omap3_ctrl_setup_d2d_padconf(void) { u16 mask, padconf; /* * In a stand alone OMAP3430 where there is not a stacked * modem for the D2D Idle Ack and D2D MStandby must be pulled * high. S CONTROL_PADCONF_SAD2D_IDLEACK and * CONTROL_PADCONF_SAD2D_MSTDBY to have a pull up. */ mask = (1 << 4) | (1 << 3); /* pull-up, enabled */ padconf = omap_ctrl_readw(OMAP3_PADCONF_SAD2D_MSTANDBY); padconf |= mask; omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_MSTANDBY); padconf = omap_ctrl_readw(OMAP3_PADCONF_SAD2D_IDLEACK); padconf |= mask; omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_IDLEACK); } /** * omap3_ctrl_init - does static initializations for control module * * Initializes system control module. This sets up the sysconfig autoidle, * and sets up modem and iva2 so that they can be idled properly. */ void __init omap3_ctrl_init(void) { omap_ctrl_writel(OMAP3430_AUTOIDLE_MASK, OMAP2_CONTROL_SYSCONFIG); omap3_ctrl_set_iva_bootmode_idle(); omap3_ctrl_setup_d2d_padconf(); } #endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */ Loading
arch/arm/mach-omap2/clkt_dpll.c +45 −53 Original line number Diff line number Diff line Loading @@ -21,10 +21,7 @@ #include <asm/div64.h> #include "soc.h" #include "clock.h" #include "cm-regbits-24xx.h" #include "cm-regbits-34xx.h" /* DPLL rate rounding: minimum DPLL multiplier, divider values */ #define DPLL_MIN_MULTIPLIER 2 Loading @@ -44,20 +41,12 @@ #define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \ (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE)) /* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */ #define OMAP3430_DPLL_FINT_BAND1_MIN 750000 #define OMAP3430_DPLL_FINT_BAND1_MAX 2100000 #define OMAP3430_DPLL_FINT_BAND2_MIN 7500000 #define OMAP3430_DPLL_FINT_BAND2_MAX 21000000 /* * DPLL valid Fint frequency range for OMAP36xx and OMAP4xxx. * From device data manual section 4.3 "DPLL and DLL Specifications". */ #define OMAP3PLUS_DPLL_FINT_JTYPE_MIN 500000 #define OMAP3PLUS_DPLL_FINT_JTYPE_MAX 2500000 #define OMAP3PLUS_DPLL_FINT_MIN 32000 #define OMAP3PLUS_DPLL_FINT_MAX 52000000 /* _dpll_test_fint() return codes */ #define DPLL_FINT_UNDERFLOW -1 Loading Loading @@ -87,33 +76,31 @@ static int _dpll_test_fint(struct clk_hw_omap *clk, unsigned int n) /* DPLL divider must result in a valid jitter correction val */ fint = __clk_get_rate(__clk_get_parent(clk->hw.clk)) / n; if (cpu_is_omap24xx()) { /* Should not be called for OMAP2, so warn if it is called */ WARN(1, "No fint limits available for OMAP2!\n"); return DPLL_FINT_INVALID; } else if (cpu_is_omap3430()) { fint_min = OMAP3430_DPLL_FINT_BAND1_MIN; fint_max = OMAP3430_DPLL_FINT_BAND2_MAX; } else if (dd->flags & DPLL_J_TYPE) { if (dd->flags & DPLL_J_TYPE) { fint_min = OMAP3PLUS_DPLL_FINT_JTYPE_MIN; fint_max = OMAP3PLUS_DPLL_FINT_JTYPE_MAX; } else { fint_min = OMAP3PLUS_DPLL_FINT_MIN; fint_max = OMAP3PLUS_DPLL_FINT_MAX; fint_min = ti_clk_features.fint_min; fint_max = ti_clk_features.fint_max; } if (fint < fint_min) { if (!fint_min || !fint_max) { WARN(1, "No fint limits available!\n"); return DPLL_FINT_INVALID; } if (fint < ti_clk_features.fint_min) { pr_debug("rejecting n=%d due to Fint failure, lowering max_divider\n", n); dd->max_divider = n; ret = DPLL_FINT_UNDERFLOW; } else if (fint > fint_max) { } else if (fint > ti_clk_features.fint_max) { pr_debug("rejecting n=%d due to Fint failure, boosting min_divider\n", n); dd->min_divider = n; ret = DPLL_FINT_INVALID; } else if (cpu_is_omap3430() && fint > OMAP3430_DPLL_FINT_BAND1_MAX && fint < OMAP3430_DPLL_FINT_BAND2_MIN) { } else if (fint > ti_clk_features.fint_band1_max && fint < ti_clk_features.fint_band2_min) { pr_debug("rejecting n=%d due to Fint failure\n", n); ret = DPLL_FINT_INVALID; } Loading Loading @@ -185,6 +172,34 @@ static int _dpll_test_mult(int *m, int n, unsigned long *new_rate, return r; } /** * _omap2_dpll_is_in_bypass - check if DPLL is in bypass mode or not * @v: bitfield value of the DPLL enable * * Checks given DPLL enable bitfield to see whether the DPLL is in bypass * mode or not. Returns 1 if the DPLL is in bypass, 0 otherwise. */ static int _omap2_dpll_is_in_bypass(u32 v) { u8 mask, val; mask = ti_clk_features.dpll_bypass_vals; /* * Each set bit in the mask corresponds to a bypass value equal * to the bitshift. Go through each set-bit in the mask and * compare against the given register value. */ while (mask) { val = __ffs(mask); mask ^= (1 << val); if (v == val) return 1; } return 0; } /* Public functions */ u8 omap2_init_dpll_parent(struct clk_hw *hw) { Loading @@ -201,20 +216,9 @@ u8 omap2_init_dpll_parent(struct clk_hw *hw) v >>= __ffs(dd->enable_mask); /* Reparent the struct clk in case the dpll is in bypass */ if (cpu_is_omap24xx()) { if (v == OMAP2XXX_EN_DPLL_LPBYPASS || v == OMAP2XXX_EN_DPLL_FRBYPASS) return 1; } else if (cpu_is_omap34xx()) { if (v == OMAP3XXX_EN_DPLL_LPBYPASS || v == OMAP3XXX_EN_DPLL_FRBYPASS) if (_omap2_dpll_is_in_bypass(v)) return 1; } else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx()) { if (v == OMAP4XXX_EN_DPLL_LPBYPASS || v == OMAP4XXX_EN_DPLL_FRBYPASS || v == OMAP4XXX_EN_DPLL_MNBYPASS) return 1; } return 0; } Loading Loading @@ -247,20 +251,8 @@ unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk) v &= dd->enable_mask; v >>= __ffs(dd->enable_mask); if (cpu_is_omap24xx()) { if (v == OMAP2XXX_EN_DPLL_LPBYPASS || v == OMAP2XXX_EN_DPLL_FRBYPASS) if (_omap2_dpll_is_in_bypass(v)) return __clk_get_rate(dd->clk_bypass); } else if (cpu_is_omap34xx()) { if (v == OMAP3XXX_EN_DPLL_LPBYPASS || v == OMAP3XXX_EN_DPLL_FRBYPASS) return __clk_get_rate(dd->clk_bypass); } else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx()) { if (v == OMAP4XXX_EN_DPLL_LPBYPASS || v == OMAP4XXX_EN_DPLL_FRBYPASS || v == OMAP4XXX_EN_DPLL_MNBYPASS) return __clk_get_rate(dd->clk_bypass); } v = omap2_clk_readl(clk, dd->mult_div1_reg); dpll_mult = v & dd->mult_mask; Loading
arch/arm/mach-omap2/clkt_iclk.c +4 −4 Original line number Diff line number Diff line Loading @@ -14,11 +14,11 @@ #include <linux/clk-provider.h> #include <linux/io.h> #include "clock.h" #include "clock2xxx.h" #include "cm2xxx_3xxx.h" #include "cm-regbits-24xx.h" /* Register offsets */ #define CM_AUTOIDLE 0x30 #define CM_ICLKEN 0x10 /* Private functions */ Loading
arch/arm/mach-omap2/clock.c +69 −7 Original line number Diff line number Diff line Loading @@ -46,6 +46,24 @@ u16 cpu_mask; /* * Clock features setup. Used instead of CPU type checks. */ struct ti_clk_features ti_clk_features; /* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */ #define OMAP3430_DPLL_FINT_BAND1_MIN 750000 #define OMAP3430_DPLL_FINT_BAND1_MAX 2100000 #define OMAP3430_DPLL_FINT_BAND2_MIN 7500000 #define OMAP3430_DPLL_FINT_BAND2_MAX 21000000 /* * DPLL valid Fint frequency range for OMAP36xx and OMAP4xxx. * From device data manual section 4.3 "DPLL and DLL Specifications". */ #define OMAP3PLUS_DPLL_FINT_MIN 32000 #define OMAP3PLUS_DPLL_FINT_MAX 52000000 /* * clkdm_control: if true, then when a clock is enabled in the * hardware, its clockdomain will first be enabled; and when a clock Loading Loading @@ -287,13 +305,7 @@ void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk, * 34xx reverses this, just to keep us on our toes * AM35xx uses both, depending on the module. */ if (cpu_is_omap24xx()) *idlest_val = OMAP24XX_CM_IDLEST_VAL; else if (cpu_is_omap34xx()) *idlest_val = OMAP34XX_CM_IDLEST_VAL; else BUG(); *idlest_val = ti_clk_features.cm_idlest_val; } /** Loading Loading @@ -731,3 +743,53 @@ void __init omap2_clk_print_new_rates(const char *hfclkin_ck_name, (clk_get_rate(core_ck) / 1000000), (clk_get_rate(mpu_ck) / 1000000)); } /** * ti_clk_init_features - init clock features struct for the SoC * * Initializes the clock features struct based on the SoC type. */ void __init ti_clk_init_features(void) { /* Fint setup for DPLLs */ if (cpu_is_omap3430()) { ti_clk_features.fint_min = OMAP3430_DPLL_FINT_BAND1_MIN; ti_clk_features.fint_max = OMAP3430_DPLL_FINT_BAND2_MAX; ti_clk_features.fint_band1_max = OMAP3430_DPLL_FINT_BAND1_MAX; ti_clk_features.fint_band2_min = OMAP3430_DPLL_FINT_BAND2_MIN; } else { ti_clk_features.fint_min = OMAP3PLUS_DPLL_FINT_MIN; ti_clk_features.fint_max = OMAP3PLUS_DPLL_FINT_MAX; } /* Bypass value setup for DPLLs */ if (cpu_is_omap24xx()) { ti_clk_features.dpll_bypass_vals |= (1 << OMAP2XXX_EN_DPLL_LPBYPASS) | (1 << OMAP2XXX_EN_DPLL_FRBYPASS); } else if (cpu_is_omap34xx()) { ti_clk_features.dpll_bypass_vals |= (1 << OMAP3XXX_EN_DPLL_LPBYPASS) | (1 << OMAP3XXX_EN_DPLL_FRBYPASS); } else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx() || soc_is_omap54xx() || soc_is_dra7xx()) { ti_clk_features.dpll_bypass_vals |= (1 << OMAP4XXX_EN_DPLL_LPBYPASS) | (1 << OMAP4XXX_EN_DPLL_FRBYPASS) | (1 << OMAP4XXX_EN_DPLL_MNBYPASS); } /* Jitter correction only available on OMAP343X */ if (cpu_is_omap343x()) ti_clk_features.flags |= TI_CLK_DPLL_HAS_FREQSEL; /* Idlest value for interface clocks. * 24xx uses 0 to indicate not ready, and 1 to indicate ready. * 34xx reverses this, just to keep us on our toes * AM35xx uses both, depending on the module. */ if (cpu_is_omap24xx()) ti_clk_features.cm_idlest_val = OMAP24XX_CM_IDLEST_VAL; else if (cpu_is_omap34xx()) ti_clk_features.cm_idlest_val = OMAP34XX_CM_IDLEST_VAL; }
arch/arm/mach-omap2/clock.h +19 −25 Original line number Diff line number Diff line Loading @@ -101,31 +101,6 @@ struct clockdomain; }; \ DEFINE_STRUCT_CLK(_name, _parent_names, _ops); #define DEFINE_CLK_OMAP_HSDIVIDER(_name, _parent_name, \ _parent_ptr, _flags, \ _clksel_reg, _clksel_mask) \ static const struct clksel _name##_div[] = { \ { \ .parent = _parent_ptr, \ .rates = div31_1to31_rates \ }, \ { .parent = NULL }, \ }; \ static struct clk _name; \ static const char *_name##_parent_names[] = { \ _parent_name, \ }; \ static struct clk_hw_omap _name##_hw = { \ .hw = { \ .clk = &_name, \ }, \ .clksel = _name##_div, \ .clksel_reg = _clksel_reg, \ .clksel_mask = _clksel_mask, \ .ops = &clkhwops_omap4_dpllmx, \ }; \ DEFINE_STRUCT_CLK(_name, _name##_parent_names, omap_hsdivider_ops); /* struct clksel_rate.flags possibilities */ #define RATE_IN_242X (1 << 0) #define RATE_IN_243X (1 << 1) Loading Loading @@ -248,6 +223,23 @@ void omap2_clk_writel(u32 val, struct clk_hw_omap *clk, void __iomem *reg); extern u16 cpu_mask; /* * Clock features setup. Used instead of CPU type checks. */ struct ti_clk_features { u32 flags; long fint_min; long fint_max; long fint_band1_max; long fint_band2_min; u8 dpll_bypass_vals; u8 cm_idlest_val; }; #define TI_CLK_DPLL_HAS_FREQSEL (1 << 0) extern struct ti_clk_features ti_clk_features; extern const struct clkops clkops_omap2_dflt_wait; extern const struct clkops clkops_dummy; extern const struct clkops clkops_omap2_dflt; Loading Loading @@ -286,4 +278,6 @@ extern int omap2_clkops_enable_clkdm(struct clk_hw *hw); extern void omap2_clkops_disable_clkdm(struct clk_hw *hw); extern void omap_clocks_register(struct omap_clk *oclks, int cnt); void __init ti_clk_init_features(void); #endif
arch/arm/mach-omap2/control.c +45 −15 Original line number Diff line number Diff line Loading @@ -44,8 +44,7 @@ struct omap3_scratchpad { }; struct omap3_scratchpad_prcm_block { u32 prm_clksrc_ctrl; u32 prm_clksel; u32 prm_contents[2]; u32 cm_contents[11]; u32 prcm_block_size; }; Loading Loading @@ -282,13 +281,9 @@ void omap3_clear_scratchpad_contents(void) void __iomem *v_addr; u32 offset = 0; v_addr = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD_ROM); if (omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP3_PRM_RSTST_OFFSET) & OMAP3430_GLOBAL_COLD_RST_MASK) { if (omap3xxx_prm_clear_global_cold_reset()) { for ( ; offset <= max_offset; offset += 0x4) writel_relaxed(0x0, (v_addr + offset)); omap2_prm_set_mod_reg_bits(OMAP3430_GLOBAL_COLD_RST_MASK, OMAP3430_GR_MOD, OMAP3_PRM_RSTST_OFFSET); } } Loading Loading @@ -331,13 +326,7 @@ void omap3_save_scratchpad_contents(void) scratchpad_contents.sdrc_block_offset = 0x64; /* Populate the PRCM block contents */ prcm_block_contents.prm_clksrc_ctrl = omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP3_PRM_CLKSRC_CTRL_OFFSET); prcm_block_contents.prm_clksel = omap2_prm_read_mod_reg(OMAP3430_CCR_MOD, OMAP3_PRM_CLKSEL_OFFSET); omap3_prm_save_scratchpad_contents(prcm_block_contents.prm_contents); omap3_cm_save_scratchpad_contents(prcm_block_contents.cm_contents); prcm_block_contents.prcm_block_size = 0x0; Loading Loading @@ -575,9 +564,50 @@ int omap3_ctrl_save_padconf(void) * Sets the bootmode for IVA2 to idle. This is needed by the PM code to * force disable IVA2 so that it does not prevent any low-power states. */ void omap3_ctrl_set_iva_bootmode_idle(void) static void __init omap3_ctrl_set_iva_bootmode_idle(void) { omap_ctrl_writel(OMAP3_IVA2_BOOTMOD_IDLE, OMAP343X_CONTROL_IVA2_BOOTMOD); } /** * omap3_ctrl_setup_d2d_padconf - setup stacked modem pads for idle * * Sets up the pads controlling the stacked modem in such way that the * device can enter idle. */ static void __init omap3_ctrl_setup_d2d_padconf(void) { u16 mask, padconf; /* * In a stand alone OMAP3430 where there is not a stacked * modem for the D2D Idle Ack and D2D MStandby must be pulled * high. S CONTROL_PADCONF_SAD2D_IDLEACK and * CONTROL_PADCONF_SAD2D_MSTDBY to have a pull up. */ mask = (1 << 4) | (1 << 3); /* pull-up, enabled */ padconf = omap_ctrl_readw(OMAP3_PADCONF_SAD2D_MSTANDBY); padconf |= mask; omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_MSTANDBY); padconf = omap_ctrl_readw(OMAP3_PADCONF_SAD2D_IDLEACK); padconf |= mask; omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_IDLEACK); } /** * omap3_ctrl_init - does static initializations for control module * * Initializes system control module. This sets up the sysconfig autoidle, * and sets up modem and iva2 so that they can be idled properly. */ void __init omap3_ctrl_init(void) { omap_ctrl_writel(OMAP3430_AUTOIDLE_MASK, OMAP2_CONTROL_SYSCONFIG); omap3_ctrl_set_iva_bootmode_idle(); omap3_ctrl_setup_d2d_padconf(); } #endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */