Commit 7c1c5413 authored by Scott Wood's avatar Scott Wood Committed by Stephen Boyd

clk: qoriq: Don't allow CPU clocks higher than starting value

The boot-time frequency of a CPU is considered its rated maximum, as we
have no other source of such information.  However, this was previously
only used for chips with 80% restrictions on secondary PLLs.  This
usually wasn't a problem because most chips/configs boot with a divider
of /1, with other dividers being used only for dynamic frequency
reduction.  However, at least one config (LS1021A at less than 1 GHz)
uses a different divider for top speed.  This was causing cpufreq to set
a frequency beyond the chip's rated speed.

This is fixed by applying a 100%-of-initial-speed limit to all CPU PLLs,
similar to the existing 80% limit that only applied to some.
Signed-off-by: default avatarScott Wood <oss@buserror.net>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarStephen Boyd <sboyd@codeaurora.org>
parent c7129375
...@@ -700,6 +700,7 @@ static struct clk * __init create_mux_common(struct clockgen *cg, ...@@ -700,6 +700,7 @@ static struct clk * __init create_mux_common(struct clockgen *cg,
struct mux_hwclock *hwc, struct mux_hwclock *hwc,
const struct clk_ops *ops, const struct clk_ops *ops,
unsigned long min_rate, unsigned long min_rate,
unsigned long max_rate,
unsigned long pct80_rate, unsigned long pct80_rate,
const char *fmt, int idx) const char *fmt, int idx)
{ {
...@@ -728,6 +729,8 @@ static struct clk * __init create_mux_common(struct clockgen *cg, ...@@ -728,6 +729,8 @@ static struct clk * __init create_mux_common(struct clockgen *cg,
continue; continue;
if (rate < min_rate) if (rate < min_rate)
continue; continue;
if (rate > max_rate)
continue;
parent_names[j] = div->name; parent_names[j] = div->name;
hwc->parent_to_clksel[j] = i; hwc->parent_to_clksel[j] = i;
...@@ -759,7 +762,7 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx) ...@@ -759,7 +762,7 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx)
struct mux_hwclock *hwc; struct mux_hwclock *hwc;
const struct clockgen_pll_div *div; const struct clockgen_pll_div *div;
unsigned long plat_rate, min_rate; unsigned long plat_rate, min_rate;
u64 pct80_rate; u64 max_rate, pct80_rate;
u32 clksel; u32 clksel;
hwc = kzalloc(sizeof(*hwc), GFP_KERNEL); hwc = kzalloc(sizeof(*hwc), GFP_KERNEL);
...@@ -787,8 +790,8 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx) ...@@ -787,8 +790,8 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx)
return NULL; return NULL;
} }
pct80_rate = clk_get_rate(div->clk); max_rate = clk_get_rate(div->clk);
pct80_rate *= 8; pct80_rate = max_rate * 8;
do_div(pct80_rate, 10); do_div(pct80_rate, 10);
plat_rate = clk_get_rate(cg->pll[PLATFORM_PLL].div[PLL_DIV1].clk); plat_rate = clk_get_rate(cg->pll[PLATFORM_PLL].div[PLL_DIV1].clk);
...@@ -798,7 +801,7 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx) ...@@ -798,7 +801,7 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx)
else else
min_rate = plat_rate / 2; min_rate = plat_rate / 2;
return create_mux_common(cg, hwc, &cmux_ops, min_rate, return create_mux_common(cg, hwc, &cmux_ops, min_rate, max_rate,
pct80_rate, "cg-cmux%d", idx); pct80_rate, "cg-cmux%d", idx);
} }
...@@ -813,7 +816,7 @@ static struct clk * __init create_one_hwaccel(struct clockgen *cg, int idx) ...@@ -813,7 +816,7 @@ static struct clk * __init create_one_hwaccel(struct clockgen *cg, int idx)
hwc->reg = cg->regs + 0x20 * idx + 0x10; hwc->reg = cg->regs + 0x20 * idx + 0x10;
hwc->info = cg->info.hwaccel[idx]; hwc->info = cg->info.hwaccel[idx];
return create_mux_common(cg, hwc, &hwaccel_ops, 0, 0, return create_mux_common(cg, hwc, &hwaccel_ops, 0, ULONG_MAX, 0,
"cg-hwaccel%d", idx); "cg-hwaccel%d", idx);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment