From a89df5ec9e1e8cc0fe12de745c7cf8534e631302 Mon Sep 17 00:00:00 2001 From: Shunzhou Jiang Date: Fri, 22 Feb 2019 17:18:36 +0800 Subject: [PATCH] clk: g12a/g12b: fix syspll overflow when freq larger than 2.1g [1/1] PD#SWPL-5076 Problem: syspll overflow Solution: div 1000 when round rate Verify: test pass on g12a skt/w400 Change-Id: I021a1e8fd1280b27e21e5b4c8983b91fb89e84ba Signed-off-by: Shunzhou Jiang --- drivers/amlogic/clk/g12a/g12a_clk-pll.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/amlogic/clk/g12a/g12a_clk-pll.c b/drivers/amlogic/clk/g12a/g12a_clk-pll.c index 858a088f4daf..194ba7dc1769 100644 --- a/drivers/amlogic/clk/g12a/g12a_clk-pll.c +++ b/drivers/amlogic/clk/g12a/g12a_clk-pll.c @@ -179,14 +179,23 @@ static long meson_g12a_pll_round_rate(struct clk_hw *hw, unsigned long rate, struct meson_clk_pll *pll = to_meson_clk_pll(hw); const struct pll_rate_table *rate_table = pll->rate_table; int i; + u64 ret_rate = 0; for (i = 0; i < pll->rate_count; i++) { - if (rate <= rate_table[i].rate) - return rate_table[i].rate; + if (rate <= rate_table[i].rate) { + ret_rate = rate_table[i].rate; + if (!strcmp(clk_hw_get_name(hw), "sys_pll") + || !strcmp(clk_hw_get_name(hw), "sys1_pll")) + do_div(ret_rate, 1000); + return ret_rate; + } } /* else return the smallest value */ - return rate_table[0].rate; + ret_rate = rate_table[0].rate; + if (!strcmp(clk_hw_get_name(hw), "sys_pll")) + do_div(ret_rate, 1000); + return ret_rate; } static const struct pll_rate_table *meson_g12a_get_pll_settings @@ -233,6 +242,9 @@ static int meson_g12a_pll_set_rate(struct clk_hw *hw, unsigned long rate, if (parent_rate == 0 || rate == 0) return -EINVAL; + if (!strcmp(clk_hw_get_name(hw), "sys_pll") + || !strcmp(clk_hw_get_name(hw), "sys1_pll")) + rate *= 1000; old_rate = rate;