From a5912f41ecef1df4c4c46a665751d9b030ef31c0 Mon Sep 17 00:00:00 2001 From: Shunzhou Jiang Date: Fri, 16 Nov 2018 15:54:52 +0800 Subject: [PATCH] clk: g12a/g12b: fix 32bit set mpll clk overflow [1/1] PD#SWPL-1933 Problem: 32bit system clk overflow Solution: let mpll clock not overflow Verify: g12b Change-Id: Ie1c7c611e637776348bb35a3e0c1624cee57716f Signed-off-by: shunzhou.jiang --- drivers/amlogic/clk/g12a/g12a_clk-mpll.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/amlogic/clk/g12a/g12a_clk-mpll.c b/drivers/amlogic/clk/g12a/g12a_clk-mpll.c index 1d62f34..abd74ea 100644 --- a/drivers/amlogic/clk/g12a/g12a_clk-mpll.c +++ b/drivers/amlogic/clk/g12a/g12a_clk-mpll.c @@ -28,7 +28,7 @@ #include "../clkc.h" /* #undef pr_debug */ /* #define pr_debug pr_info */ -#define SDM_MAX 16384 +#define SDM_MAX 16384ULL #define MAX_RATE 500000000 #define MIN_RATE 3920000 @@ -87,6 +87,7 @@ static int mpll_set_rate(struct clk_hw *hw, unsigned long rate, struct parm *p; unsigned long reg, sdm, n2; unsigned long flags = 0; + uint64_t rate64 = parent_rate; if ((rate > MAX_RATE) || (rate < MIN_RATE)) { pr_err("Err: can not set rate to %lu!\n", rate); @@ -98,8 +99,12 @@ static int mpll_set_rate(struct clk_hw *hw, unsigned long rate, spin_lock_irqsave(mpll->lock, flags); /* calculate new n2 and sdm */ - n2 = parent_rate / rate; - sdm = DIV_ROUND_UP((parent_rate - n2 * rate) * SDM_MAX, rate); + do_div(rate64, rate); + n2 = rate64; + + rate64 = (parent_rate - n2 * rate) * SDM_MAX + rate - 1; + do_div(rate64, rate); + sdm = rate64; if (sdm >= SDM_MAX) sdm = SDM_MAX - 1; -- 2.7.4