OMAP2+: clock: remove the DPLL rate tolerance code
Remove the DPLL rate tolerance code that is called during rate rounding. As far as I know, this code is never used, since it's been more important for callers of the DPLL round_rate()/set_rate() functions to obtain an exact rate than it is to save a relatively small amount of power. Signed-off-by: Paul Walmsley <paul@pwsan.com>
This commit is contained in:
@@ -178,12 +178,11 @@ void omap2_init_dpll_parent(struct clk *clk)
|
|||||||
if (!dd)
|
if (!dd)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Return bypass rate if DPLL is bypassed */
|
|
||||||
v = __raw_readl(dd->control_reg);
|
v = __raw_readl(dd->control_reg);
|
||||||
v &= dd->enable_mask;
|
v &= dd->enable_mask;
|
||||||
v >>= __ffs(dd->enable_mask);
|
v >>= __ffs(dd->enable_mask);
|
||||||
|
|
||||||
/* Reparent in case the dpll is in bypass */
|
/* Reparent the struct clk in case the dpll is in bypass */
|
||||||
if (cpu_is_omap24xx()) {
|
if (cpu_is_omap24xx()) {
|
||||||
if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
|
if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
|
||||||
v == OMAP2XXX_EN_DPLL_FRBYPASS)
|
v == OMAP2XXX_EN_DPLL_FRBYPASS)
|
||||||
@@ -259,51 +258,23 @@ u32 omap2_get_dpll_rate(struct clk *clk)
|
|||||||
|
|
||||||
/* DPLL rate rounding code */
|
/* DPLL rate rounding code */
|
||||||
|
|
||||||
/**
|
|
||||||
* omap2_dpll_set_rate_tolerance: set the error tolerance during rate rounding
|
|
||||||
* @clk: struct clk * of the DPLL
|
|
||||||
* @tolerance: maximum rate error tolerance
|
|
||||||
*
|
|
||||||
* Set the maximum DPLL rate error tolerance for the rate rounding
|
|
||||||
* algorithm. The rate tolerance is an attempt to balance DPLL power
|
|
||||||
* saving (the least divider value "n") vs. rate fidelity (the least
|
|
||||||
* difference between the desired DPLL target rate and the rounded
|
|
||||||
* rate out of the algorithm). So, increasing the tolerance is likely
|
|
||||||
* to decrease DPLL power consumption and increase DPLL rate error.
|
|
||||||
* Returns -EINVAL if provided a null clock ptr or a clk that is not a
|
|
||||||
* DPLL; or 0 upon success.
|
|
||||||
*/
|
|
||||||
int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance)
|
|
||||||
{
|
|
||||||
if (!clk || !clk->dpll_data)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
clk->dpll_data->rate_tolerance = tolerance;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* omap2_dpll_round_rate - round a target rate for an OMAP DPLL
|
* omap2_dpll_round_rate - round a target rate for an OMAP DPLL
|
||||||
* @clk: struct clk * for a DPLL
|
* @clk: struct clk * for a DPLL
|
||||||
* @target_rate: desired DPLL clock rate
|
* @target_rate: desired DPLL clock rate
|
||||||
*
|
*
|
||||||
* Given a DPLL, a desired target rate, and a rate tolerance, round
|
* Given a DPLL and a desired target rate, round the target rate to a
|
||||||
* the target rate to a possible, programmable rate for this DPLL.
|
* possible, programmable rate for this DPLL. Attempts to select the
|
||||||
* Rate tolerance is assumed to be set by the caller before this
|
* minimum possible n. Stores the computed (m, n) in the DPLL's
|
||||||
* function is called. Attempts to select the minimum possible n
|
* dpll_data structure so set_rate() will not need to call this
|
||||||
* within the tolerance to reduce power consumption. Stores the
|
* (expensive) function again. Returns ~0 if the target rate cannot
|
||||||
* computed (m, n) in the DPLL's dpll_data structure so set_rate()
|
* be rounded, or the rounded rate upon success.
|
||||||
* will not need to call this (expensive) function again. Returns ~0
|
|
||||||
* if the target rate cannot be rounded, either because the rate is
|
|
||||||
* too low or because the rate tolerance is set too tightly; or the
|
|
||||||
* rounded rate upon success.
|
|
||||||
*/
|
*/
|
||||||
long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
|
long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
|
||||||
{
|
{
|
||||||
int m, n, r, e, scaled_max_m;
|
int m, n, r, scaled_max_m;
|
||||||
unsigned long scaled_rt_rp, new_rate;
|
unsigned long scaled_rt_rp;
|
||||||
int min_e = -1, min_e_m = -1, min_e_n = -1;
|
unsigned long new_rate = 0;
|
||||||
struct dpll_data *dd;
|
struct dpll_data *dd;
|
||||||
|
|
||||||
if (!clk || !clk->dpll_data)
|
if (!clk || !clk->dpll_data)
|
||||||
@@ -311,8 +282,8 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
|
|||||||
|
|
||||||
dd = clk->dpll_data;
|
dd = clk->dpll_data;
|
||||||
|
|
||||||
pr_debug("clock: starting DPLL round_rate for clock %s, target rate "
|
pr_debug("clock: %s: starting DPLL round_rate, target rate %ld\n",
|
||||||
"%ld\n", clk->name, target_rate);
|
clk->name, target_rate);
|
||||||
|
|
||||||
scaled_rt_rp = target_rate / (dd->clk_ref->rate / DPLL_SCALE_FACTOR);
|
scaled_rt_rp = target_rate / (dd->clk_ref->rate / DPLL_SCALE_FACTOR);
|
||||||
scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;
|
scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;
|
||||||
@@ -347,39 +318,23 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
|
|||||||
if (r == DPLL_MULT_UNDERFLOW)
|
if (r == DPLL_MULT_UNDERFLOW)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
e = target_rate - new_rate;
|
pr_debug("clock: %s: m = %d: n = %d: new_rate = %ld\n",
|
||||||
pr_debug("clock: n = %d: m = %d: rate error is %d "
|
clk->name, m, n, new_rate);
|
||||||
"(new_rate = %ld)\n", n, m, e, new_rate);
|
|
||||||
|
|
||||||
if (min_e == -1 ||
|
if (target_rate == new_rate) {
|
||||||
min_e >= (int)(abs(e) - dd->rate_tolerance)) {
|
dd->last_rounded_m = m;
|
||||||
min_e = e;
|
dd->last_rounded_n = n;
|
||||||
min_e_m = m;
|
dd->last_rounded_rate = target_rate;
|
||||||
min_e_n = n;
|
break;
|
||||||
|
|
||||||
pr_debug("clock: found new least error %d\n", min_e);
|
|
||||||
|
|
||||||
/* We found good settings -- bail out now */
|
|
||||||
if (min_e <= dd->rate_tolerance)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (min_e < 0) {
|
if (target_rate != new_rate) {
|
||||||
pr_debug("clock: error: target rate or tolerance too low\n");
|
pr_debug("clock: %s: cannot round to rate %ld\n", clk->name,
|
||||||
|
target_rate);
|
||||||
return ~0;
|
return ~0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dd->last_rounded_m = min_e_m;
|
return target_rate;
|
||||||
dd->last_rounded_n = min_e_n;
|
|
||||||
dd->last_rounded_rate = _dpll_compute_new_rate(dd->clk_ref->rate,
|
|
||||||
min_e_m, min_e_n);
|
|
||||||
|
|
||||||
pr_debug("clock: final least error: e = %d, m = %d, n = %d\n",
|
|
||||||
min_e, min_e_m, min_e_n);
|
|
||||||
pr_debug("clock: final rate: %ld (target rate: %ld)\n",
|
|
||||||
dd->last_rounded_rate, target_rate);
|
|
||||||
|
|
||||||
return dd->last_rounded_rate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -18,9 +18,6 @@
|
|||||||
|
|
||||||
#include <plat/clock.h>
|
#include <plat/clock.h>
|
||||||
|
|
||||||
/* The maximum error between a target DPLL rate and the rounded rate in Hz */
|
|
||||||
#define DEFAULT_DPLL_RATE_TOLERANCE 50000
|
|
||||||
|
|
||||||
/* CM_CLKSEL2_PLL.CORE_CLK_SRC bits (2XXX) */
|
/* CM_CLKSEL2_PLL.CORE_CLK_SRC bits (2XXX) */
|
||||||
#define CORE_CLK_SRC_32K 0x0
|
#define CORE_CLK_SRC_32K 0x0
|
||||||
#define CORE_CLK_SRC_DPLL 0x1
|
#define CORE_CLK_SRC_DPLL 0x1
|
||||||
@@ -55,7 +52,6 @@ void omap2_clk_disable(struct clk *clk);
|
|||||||
long omap2_clk_round_rate(struct clk *clk, unsigned long rate);
|
long omap2_clk_round_rate(struct clk *clk, unsigned long rate);
|
||||||
int omap2_clk_set_rate(struct clk *clk, unsigned long rate);
|
int omap2_clk_set_rate(struct clk *clk, unsigned long rate);
|
||||||
int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent);
|
int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent);
|
||||||
int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance);
|
|
||||||
long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate);
|
long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate);
|
||||||
unsigned long omap3_dpll_recalc(struct clk *clk);
|
unsigned long omap3_dpll_recalc(struct clk *clk);
|
||||||
unsigned long omap3_clkoutx2_recalc(struct clk *clk);
|
unsigned long omap3_clkoutx2_recalc(struct clk *clk);
|
||||||
|
@@ -116,7 +116,6 @@ static struct dpll_data dpll_dd = {
|
|||||||
.max_multiplier = 1023,
|
.max_multiplier = 1023,
|
||||||
.min_divider = 1,
|
.min_divider = 1,
|
||||||
.max_divider = 16,
|
.max_divider = 16,
|
||||||
.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -116,7 +116,6 @@ static struct dpll_data dpll_dd = {
|
|||||||
.max_multiplier = 1023,
|
.max_multiplier = 1023,
|
||||||
.min_divider = 1,
|
.min_divider = 1,
|
||||||
.max_divider = 16,
|
.max_divider = 16,
|
||||||
.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -291,7 +291,6 @@ static struct dpll_data dpll1_dd = {
|
|||||||
.max_multiplier = OMAP3_MAX_DPLL_MULT,
|
.max_multiplier = OMAP3_MAX_DPLL_MULT,
|
||||||
.min_divider = 1,
|
.min_divider = 1,
|
||||||
.max_divider = OMAP3_MAX_DPLL_DIV,
|
.max_divider = OMAP3_MAX_DPLL_DIV,
|
||||||
.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk dpll1_ck = {
|
static struct clk dpll1_ck = {
|
||||||
@@ -364,7 +363,6 @@ static struct dpll_data dpll2_dd = {
|
|||||||
.max_multiplier = OMAP3_MAX_DPLL_MULT,
|
.max_multiplier = OMAP3_MAX_DPLL_MULT,
|
||||||
.min_divider = 1,
|
.min_divider = 1,
|
||||||
.max_divider = OMAP3_MAX_DPLL_DIV,
|
.max_divider = OMAP3_MAX_DPLL_DIV,
|
||||||
.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk dpll2_ck = {
|
static struct clk dpll2_ck = {
|
||||||
@@ -424,7 +422,6 @@ static struct dpll_data dpll3_dd = {
|
|||||||
.max_multiplier = OMAP3_MAX_DPLL_MULT,
|
.max_multiplier = OMAP3_MAX_DPLL_MULT,
|
||||||
.min_divider = 1,
|
.min_divider = 1,
|
||||||
.max_divider = OMAP3_MAX_DPLL_DIV,
|
.max_divider = OMAP3_MAX_DPLL_DIV,
|
||||||
.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk dpll3_ck = {
|
static struct clk dpll3_ck = {
|
||||||
@@ -583,7 +580,6 @@ static struct dpll_data dpll4_dd_34xx __initdata = {
|
|||||||
.max_multiplier = OMAP3_MAX_DPLL_MULT,
|
.max_multiplier = OMAP3_MAX_DPLL_MULT,
|
||||||
.min_divider = 1,
|
.min_divider = 1,
|
||||||
.max_divider = OMAP3_MAX_DPLL_DIV,
|
.max_divider = OMAP3_MAX_DPLL_DIV,
|
||||||
.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct dpll_data dpll4_dd_3630 __initdata = {
|
static struct dpll_data dpll4_dd_3630 __initdata = {
|
||||||
@@ -607,7 +603,6 @@ static struct dpll_data dpll4_dd_3630 __initdata = {
|
|||||||
.max_multiplier = OMAP3630_MAX_JTYPE_DPLL_MULT,
|
.max_multiplier = OMAP3630_MAX_JTYPE_DPLL_MULT,
|
||||||
.min_divider = 1,
|
.min_divider = 1,
|
||||||
.max_divider = OMAP3_MAX_DPLL_DIV,
|
.max_divider = OMAP3_MAX_DPLL_DIV,
|
||||||
.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE,
|
|
||||||
.flags = DPLL_J_TYPE
|
.flags = DPLL_J_TYPE
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -939,7 +934,6 @@ static struct dpll_data dpll5_dd = {
|
|||||||
.max_multiplier = OMAP3_MAX_DPLL_MULT,
|
.max_multiplier = OMAP3_MAX_DPLL_MULT,
|
||||||
.min_divider = 1,
|
.min_divider = 1,
|
||||||
.max_divider = OMAP3_MAX_DPLL_DIV,
|
.max_divider = OMAP3_MAX_DPLL_DIV,
|
||||||
.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk dpll5_ck = {
|
static struct clk dpll5_ck = {
|
||||||
|
@@ -109,7 +109,6 @@ struct clksel {
|
|||||||
* @clk_ref: struct clk pointer to the clock's reference clock input
|
* @clk_ref: struct clk pointer to the clock's reference clock input
|
||||||
* @control_reg: register containing the DPLL mode bitfield
|
* @control_reg: register containing the DPLL mode bitfield
|
||||||
* @enable_mask: mask of the DPLL mode bitfield in @control_reg
|
* @enable_mask: mask of the DPLL mode bitfield in @control_reg
|
||||||
* @rate_tolerance: maximum variance allowed from target rate (in Hz)
|
|
||||||
* @last_rounded_rate: cache of the last rate result of omap2_dpll_round_rate()
|
* @last_rounded_rate: cache of the last rate result of omap2_dpll_round_rate()
|
||||||
* @last_rounded_m: cache of the last M result of omap2_dpll_round_rate()
|
* @last_rounded_m: cache of the last M result of omap2_dpll_round_rate()
|
||||||
* @max_multiplier: maximum valid non-bypass multiplier value (actual)
|
* @max_multiplier: maximum valid non-bypass multiplier value (actual)
|
||||||
@@ -135,12 +134,9 @@ struct clksel {
|
|||||||
* XXX Some DPLLs have multiple bypass inputs, so it's not technically
|
* XXX Some DPLLs have multiple bypass inputs, so it's not technically
|
||||||
* correct to only have one @clk_bypass pointer.
|
* correct to only have one @clk_bypass pointer.
|
||||||
*
|
*
|
||||||
* XXX @rate_tolerance should probably be deprecated - currently there
|
|
||||||
* don't seem to be any usecases for DPLL rounding that is not exact.
|
|
||||||
*
|
|
||||||
* XXX The runtime-variable fields (@last_rounded_rate, @last_rounded_m,
|
* XXX The runtime-variable fields (@last_rounded_rate, @last_rounded_m,
|
||||||
* @last_rounded_n) should be separated from the runtime-fixed fields
|
* @last_rounded_n) should be separated from the runtime-fixed fields
|
||||||
* and placed into a differenct structure, so that the runtime-fixed data
|
* and placed into a different structure, so that the runtime-fixed data
|
||||||
* can be placed into read-only space.
|
* can be placed into read-only space.
|
||||||
*/
|
*/
|
||||||
struct dpll_data {
|
struct dpll_data {
|
||||||
@@ -151,7 +147,6 @@ struct dpll_data {
|
|||||||
struct clk *clk_ref;
|
struct clk *clk_ref;
|
||||||
void __iomem *control_reg;
|
void __iomem *control_reg;
|
||||||
u32 enable_mask;
|
u32 enable_mask;
|
||||||
unsigned int rate_tolerance;
|
|
||||||
unsigned long last_rounded_rate;
|
unsigned long last_rounded_rate;
|
||||||
u16 last_rounded_m;
|
u16 last_rounded_m;
|
||||||
u16 max_multiplier;
|
u16 max_multiplier;
|
||||||
|
Reference in New Issue
Block a user