clk: qoriq: Don't allow CPU clocks higher than starting value
Subsystems (2)
PATCH 1/1 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.
--- drivers/clk/clk-qoriq.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/clk/clk-qoriq.c +8 -5
@@ -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); }
Signature · 1 line
2.7.4
PATCH 1/1 clk: qoriq: Don't allow CPU clocks higher than starting value
Quoted 9 lines · Scott Wood
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.
Quoted 6 lines
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 <[email protected]>Cc stable at vger.kernel.org---
All silence, so I applied to clk-fixes because presumably this is some sort of badness we need to fix quickly.
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project