mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-07 10:03:24 +00:00
ARM: OMAP3+: DPLL: use determine_rate() and set_rate_and_parent()
Currently, DPLLs are hiding the gory details of switching parent within set_rate, which confuses the common clock code and is wrong. Fixed by applying the new determine_rate() and set_rate_and_parent() functionality to any clock-ops previously using the broken approach. This patch also removes the broken legacy code. Signed-off-by: Tero Kristo <t-kristo@ti.com> Signed-off-by: Paul Walmsley <paul@pwsan.com>
This commit is contained in:
parent
e3ab6013ab
commit
2e1a7b014f
@ -257,6 +257,9 @@ static const struct clk_ops dpll1_ck_ops = {
|
|||||||
.get_parent = &omap2_init_dpll_parent,
|
.get_parent = &omap2_init_dpll_parent,
|
||||||
.recalc_rate = &omap3_dpll_recalc,
|
.recalc_rate = &omap3_dpll_recalc,
|
||||||
.set_rate = &omap3_noncore_dpll_set_rate,
|
.set_rate = &omap3_noncore_dpll_set_rate,
|
||||||
|
.set_parent = &omap3_noncore_dpll_set_parent,
|
||||||
|
.set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
|
||||||
|
.determine_rate = &omap3_noncore_dpll_determine_rate,
|
||||||
.round_rate = &omap2_dpll_round_rate,
|
.round_rate = &omap2_dpll_round_rate,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -367,6 +370,9 @@ static const struct clk_ops dpll4_ck_ops = {
|
|||||||
.get_parent = &omap2_init_dpll_parent,
|
.get_parent = &omap2_init_dpll_parent,
|
||||||
.recalc_rate = &omap3_dpll_recalc,
|
.recalc_rate = &omap3_dpll_recalc,
|
||||||
.set_rate = &omap3_dpll4_set_rate,
|
.set_rate = &omap3_dpll4_set_rate,
|
||||||
|
.set_parent = &omap3_noncore_dpll_set_parent,
|
||||||
|
.set_rate_and_parent = &omap3_dpll4_set_rate_and_parent,
|
||||||
|
.determine_rate = &omap3_noncore_dpll_determine_rate,
|
||||||
.round_rate = &omap2_dpll_round_rate,
|
.round_rate = &omap2_dpll_round_rate,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -459,93 +459,6 @@ void omap3_noncore_dpll_disable(struct clk_hw *hw)
|
|||||||
|
|
||||||
/* Non-CORE DPLL rate set code */
|
/* Non-CORE DPLL rate set code */
|
||||||
|
|
||||||
/**
|
|
||||||
* omap3_noncore_dpll_set_rate - set non-core DPLL rate
|
|
||||||
* @clk: struct clk * of DPLL to set
|
|
||||||
* @rate: rounded target rate
|
|
||||||
*
|
|
||||||
* Set the DPLL CLKOUT to the target rate. If the DPLL can enter
|
|
||||||
* low-power bypass, and the target rate is the bypass source clock
|
|
||||||
* rate, then configure the DPLL for bypass. Otherwise, round the
|
|
||||||
* target rate if it hasn't been done already, then program and lock
|
|
||||||
* the DPLL. Returns -EINVAL upon error, or 0 upon success.
|
|
||||||
*/
|
|
||||||
int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
|
|
||||||
unsigned long parent_rate)
|
|
||||||
{
|
|
||||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
|
||||||
struct clk *new_parent = NULL;
|
|
||||||
unsigned long rrate;
|
|
||||||
u16 freqsel = 0;
|
|
||||||
struct dpll_data *dd;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!hw || !rate)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
dd = clk->dpll_data;
|
|
||||||
if (!dd)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (__clk_get_rate(dd->clk_bypass) == rate &&
|
|
||||||
(dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
|
|
||||||
pr_debug("%s: %s: set rate: entering bypass.\n",
|
|
||||||
__func__, __clk_get_name(hw->clk));
|
|
||||||
|
|
||||||
__clk_prepare(dd->clk_bypass);
|
|
||||||
clk_enable(dd->clk_bypass);
|
|
||||||
ret = _omap3_noncore_dpll_bypass(clk);
|
|
||||||
if (!ret)
|
|
||||||
new_parent = dd->clk_bypass;
|
|
||||||
clk_disable(dd->clk_bypass);
|
|
||||||
__clk_unprepare(dd->clk_bypass);
|
|
||||||
} else {
|
|
||||||
__clk_prepare(dd->clk_ref);
|
|
||||||
clk_enable(dd->clk_ref);
|
|
||||||
|
|
||||||
/* XXX this check is probably pointless in the CCF context */
|
|
||||||
if (dd->last_rounded_rate != rate) {
|
|
||||||
rrate = __clk_round_rate(hw->clk, rate);
|
|
||||||
if (rrate != rate) {
|
|
||||||
pr_warn("%s: %s: final rate %lu does not match desired rate %lu\n",
|
|
||||||
__func__, __clk_get_name(hw->clk),
|
|
||||||
rrate, rate);
|
|
||||||
rate = rrate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dd->last_rounded_rate == 0)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
/* Freqsel is available only on OMAP343X devices */
|
|
||||||
if (ti_clk_features.flags & TI_CLK_DPLL_HAS_FREQSEL) {
|
|
||||||
freqsel = _omap3_dpll_compute_freqsel(clk,
|
|
||||||
dd->last_rounded_n);
|
|
||||||
WARN_ON(!freqsel);
|
|
||||||
}
|
|
||||||
|
|
||||||
pr_debug("%s: %s: set rate: locking rate to %lu.\n",
|
|
||||||
__func__, __clk_get_name(hw->clk), rate);
|
|
||||||
|
|
||||||
ret = omap3_noncore_dpll_program(clk, freqsel);
|
|
||||||
if (!ret)
|
|
||||||
new_parent = dd->clk_ref;
|
|
||||||
clk_disable(dd->clk_ref);
|
|
||||||
__clk_unprepare(dd->clk_ref);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* FIXME - this is all wrong. common code handles reparenting and
|
|
||||||
* migrating prepare/enable counts. dplls should be a multiplexer
|
|
||||||
* clock and this should be a set_parent operation so that all of that
|
|
||||||
* stuff is inherited for free
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!ret && clk_get_parent(hw->clk) != new_parent)
|
|
||||||
__clk_reparent(hw->clk, new_parent);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* omap3_noncore_dpll_determine_rate - determine rate for a DPLL
|
* omap3_noncore_dpll_determine_rate - determine rate for a DPLL
|
||||||
* @hw: pointer to the clock to determine rate for
|
* @hw: pointer to the clock to determine rate for
|
||||||
@ -611,7 +524,7 @@ int omap3_noncore_dpll_set_parent(struct clk_hw *hw, u8 index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* omap3_noncore_dpll_set_rate_new - set rate for a DPLL clock
|
* omap3_noncore_dpll_set_rate - set rate for a DPLL clock
|
||||||
* @hw: pointer to the clock to set parent for
|
* @hw: pointer to the clock to set parent for
|
||||||
* @rate: target rate for the clock
|
* @rate: target rate for the clock
|
||||||
* @parent_rate: rate of the parent clock
|
* @parent_rate: rate of the parent clock
|
||||||
@ -621,8 +534,7 @@ int omap3_noncore_dpll_set_parent(struct clk_hw *hw, u8 index)
|
|||||||
* changed) and proceeds with the rate change operation. Returns 0
|
* changed) and proceeds with the rate change operation. Returns 0
|
||||||
* with success, negative error value otherwise.
|
* with success, negative error value otherwise.
|
||||||
*/
|
*/
|
||||||
static int omap3_noncore_dpll_set_rate_new(struct clk_hw *hw,
|
int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||||
unsigned long rate,
|
|
||||||
unsigned long parent_rate)
|
unsigned long parent_rate)
|
||||||
{
|
{
|
||||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||||
@ -688,7 +600,7 @@ int omap3_noncore_dpll_set_rate_and_parent(struct clk_hw *hw,
|
|||||||
if (index)
|
if (index)
|
||||||
ret = omap3_noncore_dpll_set_parent(hw, index);
|
ret = omap3_noncore_dpll_set_parent(hw, index);
|
||||||
else
|
else
|
||||||
ret = omap3_noncore_dpll_set_rate_new(hw, rate, parent_rate);
|
ret = omap3_noncore_dpll_set_rate(hw, rate, parent_rate);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,9 @@ static const struct clk_ops dpll_m4xen_ck_ops = {
|
|||||||
.recalc_rate = &omap4_dpll_regm4xen_recalc,
|
.recalc_rate = &omap4_dpll_regm4xen_recalc,
|
||||||
.round_rate = &omap4_dpll_regm4xen_round_rate,
|
.round_rate = &omap4_dpll_regm4xen_round_rate,
|
||||||
.set_rate = &omap3_noncore_dpll_set_rate,
|
.set_rate = &omap3_noncore_dpll_set_rate,
|
||||||
|
.set_parent = &omap3_noncore_dpll_set_parent,
|
||||||
|
.set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
|
||||||
|
.determine_rate = &omap4_dpll_regm4xen_determine_rate,
|
||||||
.get_parent = &omap2_init_dpll_parent,
|
.get_parent = &omap2_init_dpll_parent,
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
@ -53,6 +56,9 @@ static const struct clk_ops dpll_ck_ops = {
|
|||||||
.recalc_rate = &omap3_dpll_recalc,
|
.recalc_rate = &omap3_dpll_recalc,
|
||||||
.round_rate = &omap2_dpll_round_rate,
|
.round_rate = &omap2_dpll_round_rate,
|
||||||
.set_rate = &omap3_noncore_dpll_set_rate,
|
.set_rate = &omap3_noncore_dpll_set_rate,
|
||||||
|
.set_parent = &omap3_noncore_dpll_set_parent,
|
||||||
|
.set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
|
||||||
|
.determine_rate = &omap3_noncore_dpll_determine_rate,
|
||||||
.get_parent = &omap2_init_dpll_parent,
|
.get_parent = &omap2_init_dpll_parent,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -61,6 +67,9 @@ static const struct clk_ops dpll_no_gate_ck_ops = {
|
|||||||
.get_parent = &omap2_init_dpll_parent,
|
.get_parent = &omap2_init_dpll_parent,
|
||||||
.round_rate = &omap2_dpll_round_rate,
|
.round_rate = &omap2_dpll_round_rate,
|
||||||
.set_rate = &omap3_noncore_dpll_set_rate,
|
.set_rate = &omap3_noncore_dpll_set_rate,
|
||||||
|
.set_parent = &omap3_noncore_dpll_set_parent,
|
||||||
|
.set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
|
||||||
|
.determine_rate = &omap3_noncore_dpll_determine_rate,
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
static const struct clk_ops dpll_core_ck_ops = {};
|
static const struct clk_ops dpll_core_ck_ops = {};
|
||||||
@ -97,6 +106,9 @@ static const struct clk_ops omap3_dpll_ck_ops = {
|
|||||||
.get_parent = &omap2_init_dpll_parent,
|
.get_parent = &omap2_init_dpll_parent,
|
||||||
.recalc_rate = &omap3_dpll_recalc,
|
.recalc_rate = &omap3_dpll_recalc,
|
||||||
.set_rate = &omap3_noncore_dpll_set_rate,
|
.set_rate = &omap3_noncore_dpll_set_rate,
|
||||||
|
.set_parent = &omap3_noncore_dpll_set_parent,
|
||||||
|
.set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
|
||||||
|
.determine_rate = &omap3_noncore_dpll_determine_rate,
|
||||||
.round_rate = &omap2_dpll_round_rate,
|
.round_rate = &omap2_dpll_round_rate,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -106,6 +118,9 @@ static const struct clk_ops omap3_dpll_per_ck_ops = {
|
|||||||
.get_parent = &omap2_init_dpll_parent,
|
.get_parent = &omap2_init_dpll_parent,
|
||||||
.recalc_rate = &omap3_dpll_recalc,
|
.recalc_rate = &omap3_dpll_recalc,
|
||||||
.set_rate = &omap3_dpll4_set_rate,
|
.set_rate = &omap3_dpll4_set_rate,
|
||||||
|
.set_parent = &omap3_noncore_dpll_set_parent,
|
||||||
|
.set_rate_and_parent = &omap3_dpll4_set_rate_and_parent,
|
||||||
|
.determine_rate = &omap3_noncore_dpll_determine_rate,
|
||||||
.round_rate = &omap2_dpll_round_rate,
|
.round_rate = &omap2_dpll_round_rate,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user