From dcf0072a917d055db474fa4e3ad30cf104625667 Mon Sep 17 00:00:00 2001
From: Vivek Dhande <a0132295@ti.com>
Date: Thu, 13 May 2021 20:34:07 +0530
Subject: [PATCH 1/1] [DSS CSL-FL][Bug Fix][PDK-9681]DSS displays corrupted
 data OR w/o colors on the screen

- E2E thread:
    - https://e2eprivate.ti.com/magneti_marelli/digitalcluster-geely_-_magneti_marelli/f/digitalcluster-geely---magneti-marelli---forum/17134/354-17134-j7-smartcamera-multi-camera-display-issue-with-2560x1440-resolution?pifragment-896723=4#pifragment-896723=3
- Issue:
    - Frames displayed on the screen does not color components
    - This happens only when resolution is 2560x1440 and does not occur with 1920x1080
    - Frame format is NV12
- Root-cause:
    - This is happening due to wrong programming of resize factor of horizontal up/down-sampling of video window
    - This is wrongly programmed only for Y component and not for UV
    - This happens due to overflow condition happening in the code while calculating above factor
        - During multiplication of (width x 0x200000), result is stored into 32 bit integer
        - since constant is 21 bits wide, width can only be up to 11 bits
        - i.e. horizontal resolution can be up to only 2047 in order to contain in multiplication result with 32 bits
    - This does not happen for UV components as width and height is halved before multiplication for NV12
- Resolution:
    - Perform multiplication and division operations on 64 bit integers and then store final result back to 32 bit number

- Additional changes:
    - Fixed the same m2m/wb CSL-FL

Signed-off-by: Vivek Dhande <a0132295@ti.com>
Signed-off-by: Brijesh Jadav <brijesh.jadav@ti.com>
---
 src/ip/dss/V4/priv/csl_dssVideoPipe.c | 14 ++++++++++----
 src/ip/dss/V4/priv/csl_dssWbPipe.c    | 14 ++++++++++----
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/src/ip/dss/V4/priv/csl_dssVideoPipe.c b/src/ip/dss/V4/priv/csl_dssVideoPipe.c
index 5ec831ef9..e42b23ba5 100755
--- a/src/ip/dss/V4/priv/csl_dssVideoPipe.c
+++ b/src/ip/dss/V4/priv/csl_dssVideoPipe.c
@@ -1537,10 +1537,13 @@ static void CSL_dssVidPipeSetFir(CSL_dss_pipeRegs *pipeRegs,
                                  uint32_t outSizeX,
                                  uint32_t outSizeY)
 {
+    uint64_t tempFirHinc, tempFirVinc;
     uint32_t firHinc, firVinc, regVal;
 
-    firHinc = (0x200000U * (inSizeX)) / (outSizeX);
-    firVinc = (0x200000U * (inSizeY)) / (outSizeY);
+    tempFirHinc = ((0x200000U * ((uint64_t)inSizeX)) / ((uint64_t)outSizeX));
+    tempFirVinc = ((0x200000U * ((uint64_t)inSizeY)) / ((uint64_t)outSizeY));
+    firHinc = (uint32_t)tempFirHinc;
+    firVinc = (uint32_t)tempFirVinc;
     regVal = CSL_REG32_RD(&pipeRegs->FIRH);
     CSL_FINS(regVal,
              DSS_VID1_FIRH_FIRHINC,
@@ -1559,10 +1562,13 @@ static void CSL_dssVidPipeSetFir2(CSL_dss_pipeRegs *pipeRegs,
                                   uint32_t outSizeX,
                                   uint32_t outSizeY)
 {
+    uint64_t tempFirHinc, tempFirVinc;
     uint32_t firHinc, firVinc, regVal;
 
-    firHinc = (0x200000U * (inSizeX)) / (outSizeX);
-    firVinc = (0x200000U * (inSizeY)) / (outSizeY);
+    tempFirHinc = ((0x200000U * ((uint64_t)inSizeX)) / ((uint64_t)outSizeX));
+    tempFirVinc = ((0x200000U * ((uint64_t)inSizeY)) / ((uint64_t)outSizeY));
+    firHinc = (uint32_t)tempFirHinc;
+    firVinc = (uint32_t)tempFirVinc;
     regVal = CSL_REG32_RD(&pipeRegs->FIRH2);
     CSL_FINS(regVal,
              DSS_VID1_FIRH2_FIRHINC,
diff --git a/src/ip/dss/V4/priv/csl_dssWbPipe.c b/src/ip/dss/V4/priv/csl_dssWbPipe.c
index 82edaaff3..524cf457b 100755
--- a/src/ip/dss/V4/priv/csl_dssWbPipe.c
+++ b/src/ip/dss/V4/priv/csl_dssWbPipe.c
@@ -1512,10 +1512,13 @@ static void CSL_dssWbPipeSetFir(CSL_dss_wbRegs *wbRegs,
                                  uint32_t outSizeX,
                                  uint32_t outSizeY)
 {
+    uint64_t tempFirHinc, tempFirVinc;
     uint32_t firHinc, firVinc, regVal;
 
-    firHinc = (0x200000U * (inSizeX)) / (outSizeX);
-    firVinc = (0x200000U * (inSizeY)) / (outSizeY);
+    tempFirHinc = ((0x200000U * ((uint64_t)inSizeX)) / ((uint64_t)outSizeX));
+    tempFirVinc = ((0x200000U * ((uint64_t)inSizeY)) / ((uint64_t)outSizeY));
+    firHinc = (uint32_t)tempFirHinc;
+    firVinc = (uint32_t)tempFirVinc;
     regVal = CSL_REG32_RD(&wbRegs->FIRH);
     CSL_FINS(regVal,
              DSS_WB_FIRH_FIRHINC,
@@ -1534,10 +1537,13 @@ static void CSL_dssWbPipeSetFir2(CSL_dss_wbRegs *wbRegs,
                                   uint32_t outSizeX,
                                   uint32_t outSizeY)
 {
+    uint64_t tempFirHinc, tempFirVinc;
     uint32_t firHinc, firVinc, regVal;
 
-    firHinc = (0x200000U * (inSizeX)) / (outSizeX);
-    firVinc = (0x200000U * (inSizeY)) / (outSizeY);
+    tempFirHinc = ((0x200000U * ((uint64_t)inSizeX)) / ((uint64_t)outSizeX));
+    tempFirVinc = ((0x200000U * ((uint64_t)inSizeY)) / ((uint64_t)outSizeY));
+    firHinc = (uint32_t)tempFirHinc;
+    firVinc = (uint32_t)tempFirVinc;
     regVal = CSL_REG32_RD(&wbRegs->FIRH2);
     CSL_FINS(regVal,
              DSS_WB_FIRH2_FIRHINC,
-- 
2.17.1

