Skip to content

Commit

Permalink
Merge tag 'for-v3.14-rc/omap-fixes-a' of git://git.kernel.org/pub/scm…
Browse files Browse the repository at this point in the history
…/linux/kernel/git/pjw/omap-pending into omap-for-v3.14/fixes

Several OMAP clock/PM/device data fixes for v3.14-rc.  There's an OMAP5
reboot fix in there, plus a clock fix for rate computations involving
x2 multipliers.

Basic build, boot, and PM test logs are available here:

http://www.pwsan.com/omap/testlogs/prcm-fixes-a-v3.14-rc/20140219131753/

Note that most full-chip PM is broken since the v3.14 merge; it's
not caused by this series.
  • Loading branch information
Tony Lindgren committed Feb 21, 2014
2 parents 8842446 + 994c41e commit 915a155
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 31 deletions.
2 changes: 2 additions & 0 deletions arch/arm/mach-omap2/cclock3xxx_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,9 @@ static const struct clk_ops dpll4_m5x2_ck_ops = {
.enable = &omap2_dflt_clk_enable,
.disable = &omap2_dflt_clk_disable,
.is_enabled = &omap2_dflt_clk_is_enabled,
.set_rate = &omap3_clkoutx2_set_rate,
.recalc_rate = &omap3_clkoutx2_recalc,
.round_rate = &omap3_clkoutx2_round_rate,
};

static const struct clk_ops dpll4_m5x2_ck_3630_ops = {
Expand Down
92 changes: 77 additions & 15 deletions arch/arm/mach-omap2/dpll3xxx.c
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,32 @@ void omap3_dpll_deny_idle(struct clk_hw_omap *clk)

/* Clock control for DPLL outputs */

/* Find the parent DPLL for the given clkoutx2 clock */
static struct clk_hw_omap *omap3_find_clkoutx2_dpll(struct clk_hw *hw)
{
struct clk_hw_omap *pclk = NULL;
struct clk *parent;

/* Walk up the parents of clk, looking for a DPLL */
do {
do {
parent = __clk_get_parent(hw->clk);
hw = __clk_get_hw(parent);
} while (hw && (__clk_get_flags(hw->clk) & CLK_IS_BASIC));
if (!hw)
break;
pclk = to_clk_hw_omap(hw);
} while (pclk && !pclk->dpll_data);

/* clk does not have a DPLL as a parent? error in the clock data */
if (!pclk) {
WARN_ON(1);
return NULL;
}

return pclk;
}

/**
* omap3_clkoutx2_recalc - recalculate DPLL X2 output virtual clock rate
* @clk: DPLL output struct clk
Expand All @@ -637,27 +663,14 @@ unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
unsigned long rate;
u32 v;
struct clk_hw_omap *pclk = NULL;
struct clk *parent;

if (!parent_rate)
return 0;

/* Walk up the parents of clk, looking for a DPLL */
do {
do {
parent = __clk_get_parent(hw->clk);
hw = __clk_get_hw(parent);
} while (hw && (__clk_get_flags(hw->clk) & CLK_IS_BASIC));
if (!hw)
break;
pclk = to_clk_hw_omap(hw);
} while (pclk && !pclk->dpll_data);
pclk = omap3_find_clkoutx2_dpll(hw);

/* clk does not have a DPLL as a parent? error in the clock data */
if (!pclk) {
WARN_ON(1);
if (!pclk)
return 0;
}

dd = pclk->dpll_data;

Expand All @@ -672,6 +685,55 @@ unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
return rate;
}

int omap3_clkoutx2_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
return 0;
}

long omap3_clkoutx2_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
const struct dpll_data *dd;
u32 v;
struct clk_hw_omap *pclk = NULL;

if (!*prate)
return 0;

pclk = omap3_find_clkoutx2_dpll(hw);

if (!pclk)
return 0;

dd = pclk->dpll_data;

/* TYPE J does not have a clkoutx2 */
if (dd->flags & DPLL_J_TYPE) {
*prate = __clk_round_rate(__clk_get_parent(pclk->hw.clk), rate);
return *prate;
}

WARN_ON(!dd->enable_mask);

v = omap2_clk_readl(pclk, dd->control_reg) & dd->enable_mask;
v >>= __ffs(dd->enable_mask);

/* If in bypass, the rate is fixed to the bypass rate*/
if (v != OMAP3XXX_EN_DPLL_LOCKED)
return *prate;

if (__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT) {
unsigned long best_parent;

best_parent = (rate / 2);
*prate = __clk_round_rate(__clk_get_parent(hw->clk),
best_parent);
}

return *prate * 2;
}

/* OMAP3/4 non-CORE DPLL clkops */
const struct clk_hw_omap_ops clkhwops_omap3_dpll = {
.allow_idle = omap3_dpll_allow_idle,
Expand Down
20 changes: 11 additions & 9 deletions arch/arm/mach-omap2/omap_hwmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -1946,30 +1946,32 @@ static int _ocp_softreset(struct omap_hwmod *oh)
if (ret)
goto dis_opt_clks;

_write_sysconfig(v, oh);
ret = _clear_softreset(oh, &v);
if (ret)
goto dis_opt_clks;

_write_sysconfig(v, oh);

if (oh->class->sysc->srst_udelay)
udelay(oh->class->sysc->srst_udelay);

c = _wait_softreset_complete(oh);
if (c == MAX_MODULE_SOFTRESET_WAIT)
if (c == MAX_MODULE_SOFTRESET_WAIT) {
pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n",
oh->name, MAX_MODULE_SOFTRESET_WAIT);
else
ret = -ETIMEDOUT;
goto dis_opt_clks;
} else {
pr_debug("omap_hwmod: %s: softreset in %d usec\n", oh->name, c);
}

ret = _clear_softreset(oh, &v);
if (ret)
goto dis_opt_clks;

_write_sysconfig(v, oh);

/*
* XXX add _HWMOD_STATE_WEDGED for modules that don't come back from
* _wait_target_ready() or _reset()
*/

ret = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0;

dis_opt_clks:
if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
_disable_optional_clocks(oh);
Expand Down
9 changes: 4 additions & 5 deletions arch/arm/mach-omap2/omap_hwmod_7xx_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -1365,11 +1365,10 @@ static struct omap_hwmod_class_sysconfig dra7xx_spinlock_sysc = {
.rev_offs = 0x0000,
.sysc_offs = 0x0010,
.syss_offs = 0x0014,
.sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
SIDLE_SMART_WKUP),
.sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP |
SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
SYSS_HAS_RESET_STATUS),
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
.sysc_fields = &omap_hwmod_sysc_type1,
};

Expand Down
4 changes: 2 additions & 2 deletions arch/arm/mach-omap2/prminst44xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,11 +183,11 @@ void omap4_prminst_global_warm_sw_reset(void)
OMAP4_PRM_RSTCTRL_OFFSET);
v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK;
omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION,
OMAP4430_PRM_DEVICE_INST,
dev_inst,
OMAP4_PRM_RSTCTRL_OFFSET);

/* OCP barrier */
v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
OMAP4430_PRM_DEVICE_INST,
dev_inst,
OMAP4_PRM_RSTCTRL_OFFSET);
}
4 changes: 4 additions & 0 deletions include/linux/clk/ti.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,10 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
void omap2_init_clk_clkdm(struct clk_hw *clk);
unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
unsigned long parent_rate);
int omap3_clkoutx2_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate);
long omap3_clkoutx2_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate);
int omap2_clkops_enable_clkdm(struct clk_hw *hw);
void omap2_clkops_disable_clkdm(struct clk_hw *hw);
int omap2_clk_disable_autoidle_all(void);
Expand Down

0 comments on commit 915a155

Please sign in to comment.