From d0c5ac609ca8c4c2eed36fca380202b62bb4451e Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Wed, 27 Apr 2016 17:00:10 +0100 Subject: [PATCH] Revert "video: ipu: avoid overflow issue" This reverts commit 3cb4f25cc702db17455583599d0940c81337a17a. --- drivers/video/ipu_common.c | 73 ++++++++++++---------------------------------- 1 file changed, 19 insertions(+), 54 deletions(-) diff --git a/drivers/video/ipu_common.c b/drivers/video/ipu_common.c index 36d4b23..9f85102 100644 --- a/drivers/video/ipu_common.c +++ b/drivers/video/ipu_common.c @@ -19,7 +19,6 @@ #include #include #include -#include #include "ipu.h" #include "ipu_regs.h" @@ -276,84 +275,50 @@ static inline void ipu_ch_param_set_buffer(uint32_t ch, int bufNum, static void ipu_pixel_clk_recalc(struct clk *clk) { - u32 div; - u64 final_rate = (unsigned long long)clk->parent->rate * 16; - - div = __raw_readl(DI_BS_CLKGEN0(clk->id)); - debug("read BS_CLKGEN0 div:%d, final_rate:%lld, prate:%ld\n", - div, final_rate, clk->parent->rate); - - clk->rate = 0; - if (div != 0) { - do_div(final_rate, div); - clk->rate = final_rate; - } + u32 div = __raw_readl(DI_BS_CLKGEN0(clk->id)); + if (div == 0) + clk->rate = 0; + else + clk->rate = (clk->parent->rate * 16) / div; } static unsigned long ipu_pixel_clk_round_rate(struct clk *clk, unsigned long rate) { - u64 div, final_rate; - u32 remainder; - u64 parent_rate = (unsigned long long)clk->parent->rate * 16; - + u32 div, div1; + u32 tmp; /* * Calculate divider * Fractional part is 4 bits, * so simply multiply by 2^4 to get fractional part. */ - div = parent_rate; - remainder = do_div(div, rate); - /* Round the divider value */ - if (remainder > (rate / 2)) - div++; + tmp = (clk->parent->rate * 16); + div = tmp / rate; + if (div < 0x10) /* Min DI disp clock divider is 1 */ div = 0x10; if (div & ~0xFEF) div &= 0xFF8; else { - /* Round up divider if it gets us closer to desired pix clk */ - if ((div & 0xC) == 0xC) { - div += 0x10; - div &= ~0xF; - } + div1 = div & 0xFE0; + if ((tmp/div1 - tmp/div) < rate / 4) + div = div1; + else + div &= 0xFF8; } - final_rate = parent_rate; - do_div(final_rate, div); - - return final_rate; + return (clk->parent->rate * 16) / div; } static int ipu_pixel_clk_set_rate(struct clk *clk, unsigned long rate) { - u64 div, parent_rate; - u32 remainder; - - parent_rate = (unsigned long long)clk->parent->rate * 16; - div = parent_rate; - remainder = do_div(div, rate); - /* Round the divider value */ - if (remainder > (rate / 2)) - div++; - - /* Round up divider if it gets us closer to desired pix clk */ - if ((div & 0xC) == 0xC) { - div += 0x10; - div &= ~0xF; - } - if (div > 0x1000) - debug("Overflow, DI_BS_CLKGEN0 div:0x%x\n", (u32)div); + u32 div = (clk->parent->rate * 16) / rate; __raw_writel(div, DI_BS_CLKGEN0(clk->id)); - /* - * Setup pixel clock timing - * Down time is half of period - */ + /* Setup pixel clock timing */ __raw_writel((div / 16) << 16, DI_BS_CLKGEN1(clk->id)); - clk->rate = (u64)(clk->parent->rate * 16) / div; - + clk->rate = (clk->parent->rate * 16) / div; return 0; } -- 2.7.4