clk: g12a/g12b: fix syspll overflow when freq larger than 2.1g [1/1]
authorShunzhou Jiang <shunzhou.jiang@amlogic.com>
Fri, 22 Feb 2019 09:18:36 +0000 (17:18 +0800)
committerLuan Yuan <luan.yuan@amlogic.com>
Wed, 13 Mar 2019 12:22:28 +0000 (20:22 +0800)
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 <shunzhou.jiang@amlogic.com>
drivers/amlogic/clk/g12a/g12a_clk-pll.c

index 858a088..194ba7d 100644 (file)
@@ -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;