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: Scott Wood <oss@buserror.net> Cc: stable@vger.kernel.org Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
This commit is contained in:
Родитель
c712937531
Коммит
7c1c5413a7
|
@ -700,6 +700,7 @@ static struct clk * __init create_mux_common(struct clockgen *cg,
|
|||
struct mux_hwclock *hwc,
|
||||
const struct clk_ops *ops,
|
||||
unsigned long min_rate,
|
||||
unsigned long max_rate,
|
||||
unsigned long pct80_rate,
|
||||
const char *fmt, int idx)
|
||||
{
|
||||
|
@ -728,6 +729,8 @@ static struct clk * __init create_mux_common(struct clockgen *cg,
|
|||
continue;
|
||||
if (rate < min_rate)
|
||||
continue;
|
||||
if (rate > max_rate)
|
||||
continue;
|
||||
|
||||
parent_names[j] = div->name;
|
||||
hwc->parent_to_clksel[j] = i;
|
||||
|
@ -759,7 +762,7 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx)
|
|||
struct mux_hwclock *hwc;
|
||||
const struct clockgen_pll_div *div;
|
||||
unsigned long plat_rate, min_rate;
|
||||
u64 pct80_rate;
|
||||
u64 max_rate, pct80_rate;
|
||||
u32 clksel;
|
||||
|
||||
hwc = kzalloc(sizeof(*hwc), GFP_KERNEL);
|
||||
|
@ -787,8 +790,8 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
pct80_rate = clk_get_rate(div->clk);
|
||||
pct80_rate *= 8;
|
||||
max_rate = clk_get_rate(div->clk);
|
||||
pct80_rate = max_rate * 8;
|
||||
do_div(pct80_rate, 10);
|
||||
|
||||
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)
|
|||
else
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -813,7 +816,7 @@ static struct clk * __init create_one_hwaccel(struct clockgen *cg, int idx)
|
|||
hwc->reg = cg->regs + 0x20 * idx + 0x10;
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче