From patchwork Wed Mar 9 08:07:21 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 594878 X-Patchwork-Delegate: agust@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 1BF79140082 for ; Wed, 9 Mar 2016 19:22:55 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=erLBIqZ2; dkim-atps=neutral Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 8D860A770A; Wed, 9 Mar 2016 09:22:53 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id xLBbrid0fud5; Wed, 9 Mar 2016 09:22:53 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id D3FBDA76FC; Wed, 9 Mar 2016 09:22:52 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 8CF7BA76FC for ; Wed, 9 Mar 2016 09:22:50 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id h0LXyEYkdhZQ for ; Wed, 9 Mar 2016 09:22:50 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-pa0-f67.google.com (mail-pa0-f67.google.com [209.85.220.67]) by theia.denx.de (Postfix) with ESMTPS id 1A431A76FB for ; Wed, 9 Mar 2016 09:22:46 +0100 (CET) Received: by mail-pa0-f67.google.com with SMTP id hj7so2768219pac.1 for ; Wed, 09 Mar 2016 00:22:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=HZ2rlEYpaea0oqrpPHZlfemozqpeZt7cjpTbBrZOADI=; b=erLBIqZ2PDajRy+K3FVj8nfkfk7V9bEgZtuo78Iy8JUw1RcL0e252+UEMK2e2G2rL2 UEJsql2tsdkN/5gsl0xERjkzTmapVHKDwM6GDbZ5nlz2SA3q55G8ufa0VYnwB1mgkXNH cuVgIeZO8UsBdipSFa1ZtocNBHxRK/tMb/+R6hcqMZZAYhrGpP5qoSkHWWfevQSMUrur AZUGqvmDi1+7wByJuT78T6qe70TIKuHKKTKmJ+8eu4ZKqKZP5taJzjGQ0B+7EoNQI44L wO9DkZg0SfhtwvMMr+FQm1qQsMIPR5leE+2MsA2EBU6Jtd4KGm530rVSB3sYt0fQt0FD 0YVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=HZ2rlEYpaea0oqrpPHZlfemozqpeZt7cjpTbBrZOADI=; b=OeFfgFmuGwgxBLEJhI/aMTP7wct4rpwc/P7ywmUSg6npPgMJVZ4zNIOOm4+QjAWKOr Bjm3olzPxmHSo4kLIYJ+B0Lzyn1dMBnQ51lG9eikVDLi9MqjthCI2QF/tnSbNze1twcP 5nmNvYuCHIbdDADrF1ncLAldzMPFytCdt35pFjhswWnfiV29yt/FFqNLwOOY7aoVC6hA HG49OTI3XQEOTG6MvBSZO4qkjvU/GyFp/CNA3pUYtwj42TLtbTlUWGkC6QOPwkfNFED9 ruAH/DK06huD3Ge3AGVD413og10XB3fY4wbyZBDG0fNgvMPOF3/JPrmhSMpEpU4Q6pw3 xIRQ== X-Gm-Message-State: AD7BkJK/ebPOuJULoV0B1agAhhz8wvwGodnGKv50/wVg6ViOfupUaIct2ZxkIf1Nb4ZWtw== X-Received: by 10.66.255.39 with SMTP id an7mr48321237pad.2.1457511765260; Wed, 09 Mar 2016 00:22:45 -0800 (PST) Received: from linux-7smt.suse (gate-zmy3.freescale.com. [192.88.167.1]) by smtp.gmail.com with ESMTPSA id i11sm10224436pfi.55.2016.03.09.00.22.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 09 Mar 2016 00:22:44 -0800 (PST) From: Peng Fan To: sbabic@denx.de, agust@denx.de Date: Wed, 9 Mar 2016 16:07:21 +0800 Message-Id: <1457510843-6535-1-git-send-email-van.freenix@gmail.com> X-Mailer: git-send-email 2.6.2 Cc: u-boot@lists.denx.de, Fabio Estevam , Sandor Yu Subject: [U-Boot] [PATCH 1/3] video: ipu: avoid overflow issue X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Multiplication, as "clk->parent->rate * 16" may overflow. So use do_div to avoid such issue. Signed-off-by: Peng Fan Signed-off-by: Sandor Yu Cc: Anatolij Gustschin Cc: Stefano Babic Cc: Fabio Estevam --- drivers/video/ipu_common.c | 73 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 19 deletions(-) diff --git a/drivers/video/ipu_common.c b/drivers/video/ipu_common.c index 9f85102..36d4b23 100644 --- a/drivers/video/ipu_common.c +++ b/drivers/video/ipu_common.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "ipu.h" #include "ipu_regs.h" @@ -275,50 +276,84 @@ static inline void ipu_ch_param_set_buffer(uint32_t ch, int bufNum, static void ipu_pixel_clk_recalc(struct clk *clk) { - u32 div = __raw_readl(DI_BS_CLKGEN0(clk->id)); - if (div == 0) - clk->rate = 0; - else - clk->rate = (clk->parent->rate * 16) / div; + 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; + } } static unsigned long ipu_pixel_clk_round_rate(struct clk *clk, unsigned long rate) { - u32 div, div1; - u32 tmp; + u64 div, final_rate; + u32 remainder; + u64 parent_rate = (unsigned long long)clk->parent->rate * 16; + /* * Calculate divider * Fractional part is 4 bits, * so simply multiply by 2^4 to get fractional part. */ - tmp = (clk->parent->rate * 16); - div = tmp / rate; - + div = parent_rate; + remainder = do_div(div, rate); + /* Round the divider value */ + if (remainder > (rate / 2)) + div++; if (div < 0x10) /* Min DI disp clock divider is 1 */ div = 0x10; if (div & ~0xFEF) div &= 0xFF8; else { - div1 = div & 0xFE0; - if ((tmp/div1 - tmp/div) < rate / 4) - div = div1; - else - div &= 0xFF8; + /* Round up divider if it gets us closer to desired pix clk */ + if ((div & 0xC) == 0xC) { + div += 0x10; + div &= ~0xF; + } } - return (clk->parent->rate * 16) / div; + final_rate = parent_rate; + do_div(final_rate, div); + + return final_rate; } static int ipu_pixel_clk_set_rate(struct clk *clk, unsigned long rate) { - u32 div = (clk->parent->rate * 16) / 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); __raw_writel(div, DI_BS_CLKGEN0(clk->id)); - /* Setup pixel clock timing */ + /* + * Setup pixel clock timing + * Down time is half of period + */ __raw_writel((div / 16) << 16, DI_BS_CLKGEN1(clk->id)); - clk->rate = (clk->parent->rate * 16) / div; + clk->rate = (u64)(clk->parent->rate * 16) / div; + return 0; }