aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorScott Wood <oss@buserror.net>2016-10-17 14:42:23 -0400
committerStephen Boyd <sboyd@codeaurora.org>2016-11-01 20:26:15 -0400
commit7c1c5413a7bdf1c9adc8d979521f1b8286366aef (patch)
tree91e4786a854b7b2b1372d7e427436f2006e008b0
parentc7129375312732f006ba9054c12ae4d4097d5519 (diff)
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>
-rw-r--r--drivers/clk/clk-qoriq.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c
index 20b105584f82..80ae2a51452d 100644
--- a/drivers/clk/clk-qoriq.c
+++ b/drivers/clk/clk-qoriq.c
@@ -700,6 +700,7 @@ static struct clk * __init create_mux_common(struct clockgen *cg,
700 struct mux_hwclock *hwc, 700 struct mux_hwclock *hwc,
701 const struct clk_ops *ops, 701 const struct clk_ops *ops,
702 unsigned long min_rate, 702 unsigned long min_rate,
703 unsigned long max_rate,
703 unsigned long pct80_rate, 704 unsigned long pct80_rate,
704 const char *fmt, int idx) 705 const char *fmt, int idx)
705{ 706{
@@ -728,6 +729,8 @@ static struct clk * __init create_mux_common(struct clockgen *cg,
728 continue; 729 continue;
729 if (rate < min_rate) 730 if (rate < min_rate)
730 continue; 731 continue;
732 if (rate > max_rate)
733 continue;
731 734
732 parent_names[j] = div->name; 735 parent_names[j] = div->name;
733 hwc->parent_to_clksel[j] = i; 736 hwc->parent_to_clksel[j] = i;
@@ -759,7 +762,7 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx)
759 struct mux_hwclock *hwc; 762 struct mux_hwclock *hwc;
760 const struct clockgen_pll_div *div; 763 const struct clockgen_pll_div *div;
761 unsigned long plat_rate, min_rate; 764 unsigned long plat_rate, min_rate;
762 u64 pct80_rate; 765 u64 max_rate, pct80_rate;
763 u32 clksel; 766 u32 clksel;
764 767
765 hwc = kzalloc(sizeof(*hwc), GFP_KERNEL); 768 hwc = kzalloc(sizeof(*hwc), GFP_KERNEL);
@@ -787,8 +790,8 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx)
787 return NULL; 790 return NULL;
788 } 791 }
789 792
790 pct80_rate = clk_get_rate(div->clk); 793 max_rate = clk_get_rate(div->clk);
791 pct80_rate *= 8; 794 pct80_rate = max_rate * 8;
792 do_div(pct80_rate, 10); 795 do_div(pct80_rate, 10);
793 796
794 plat_rate = clk_get_rate(cg->pll[PLATFORM_PLL].div[PLL_DIV1].clk); 797 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 else 801 else
799 min_rate = plat_rate / 2; 802 min_rate = plat_rate / 2;
800 803
801 return create_mux_common(cg, hwc, &cmux_ops, min_rate, 804 return create_mux_common(cg, hwc, &cmux_ops, min_rate, max_rate,
802 pct80_rate, "cg-cmux%d", idx); 805 pct80_rate, "cg-cmux%d", idx);
803} 806}
804 807
@@ -813,7 +816,7 @@ static struct clk * __init create_one_hwaccel(struct clockgen *cg, int idx)
813 hwc->reg = cg->regs + 0x20 * idx + 0x10; 816 hwc->reg = cg->regs + 0x20 * idx + 0x10;
814 hwc->info = cg->info.hwaccel[idx]; 817 hwc->info = cg->info.hwaccel[idx];
815 818
816 return create_mux_common(cg, hwc, &hwaccel_ops, 0, 0, 819 return create_mux_common(cg, hwc, &hwaccel_ops, 0, ULONG_MAX, 0,
817 "cg-hwaccel%d", idx); 820 "cg-hwaccel%d", idx);
818} 821}
819 822