This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM62A7: LSC driver issue on AM62 platform

Part Number: AM62A7


Hello ,TI expert

May I ask if the LSC module driver issue that occurred on the AM62 platform before has been resolved?

  • Hi enrui,

    I have filed a bug for this and let me check the status.

    I suppose it will be fixed in 9.2 release.

  • Hi,Gang

    Can you provide us with a patch after fixing the LSC module?

  • Hi enrui,

    Yes, we will let you know once it is fixed.

  • Hi enrui,

    In csl_rawfe.c, it looks like line 613 "val = *lutAddr;" shall be deleted.

     596     if (FVID2_SOK == status)
     597     {
     598         if ((uint32_t)TRUE == cfg->enable)
     599         {
     600             regAddr = lscLutAddr;
     601             lutAddr = cfg->tableAddr;
     602
     603             for (cnt = 0U; cnt < cfg->numTblEntry/4; cnt ++)
     604             {
     605                 val = (*lutAddr) & 0xFFu;
     606                 lutAddr ++;
     607                 val |= ((*lutAddr) & 0xFFu) << 8u;
     608                 lutAddr ++;
     609                 val |= ((*lutAddr) & 0xFFu) << 16u;
     610                 lutAddr ++;
     611                 val |= ((*lutAddr) & 0xFFu) << 24u;
     612
     613                 val = *lutAddr;
     614                 lutAddr ++;
     615                 CSL_REG32_WR(regAddr, val);
     616
     617                 regAddr ++;
     618             }
     619
     620             regVal = 0;

  • Hi,Gang

    I deleted the content of line 613, but the issue above has not been fixed

    /**
     *   Copyright (c) Texas Instruments Incorporated 2018
     *   All rights reserved.
     *
     *  Redistribution and use in source and binary forms, with or without
     *  modification, are permitted provided that the following conditions
     *  are met:
     *
     *    Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     *    Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the
     *    distribution.
     *
     *    Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /**
     *  \file csl_rawfe.c
     *
     *  \brief VISS RAW FE Csl file, setting up different modules of RAW FE
     *
     */
    
    
    /* ========================================================================== */
    /*                             Include Files                                  */
    /* ========================================================================== */
    
    #include <src/csl/include/csl_rawfe.h>
    
    /* ========================================================================== */
    /*                           Macros & Typedefs                                */
    /* ========================================================================== */
    
    /* WDR Merge register offsets, there are two instances of the WDR Merge block.
     * These offsets are same in both the modules and used for configuring
     * both the modules
     */
    #define RFE_WDRMRG_CFG                          (CSL_RAWFE_CFG_WDRMRG1_CFG - \
        CSL_RAWFE_CFG_WDRMRG1_CFG)
    #define RFE_WDRMRG_GAIN                         (CSL_RAWFE_CFG_WDRMRG1_GAIN - \
        CSL_RAWFE_CFG_WDRMRG1_CFG)
    #define RFE_WDRMRG_LBLK12                       (CSL_RAWFE_CFG_WDRMRG1_LBLK12 -\
        CSL_RAWFE_CFG_WDRMRG1_CFG)
    #define RFE_WDRMRG_LBLK34                       (CSL_RAWFE_CFG_WDRMRG1_LBLK34 -\
        CSL_RAWFE_CFG_WDRMRG1_CFG)
    #define RFE_WDRMRG_SBLK12                       (CSL_RAWFE_CFG_WDRMRG1_SBLK12 -\
        CSL_RAWFE_CFG_WDRMRG1_CFG)
    #define RFE_WDRMRG_SBLK34                       (CSL_RAWFE_CFG_WDRMRG1_SBLK34 -\
        CSL_RAWFE_CFG_WDRMRG1_CFG)
    #define RFE_WDRMRG_LWB12                        (CSL_RAWFE_CFG_WDRMRG1_LWB12 - \
        CSL_RAWFE_CFG_WDRMRG1_CFG)
    #define RFE_WDRMRG_LWB34                        (CSL_RAWFE_CFG_WDRMRG1_LWB34 - \
        CSL_RAWFE_CFG_WDRMRG1_CFG)
    #define RFE_WDRMRG_SWB12                        (CSL_RAWFE_CFG_WDRMRG1_SWB12 - \
        CSL_RAWFE_CFG_WDRMRG1_CFG)
    #define RFE_WDRMRG_SWB34                        (CSL_RAWFE_CFG_WDRMRG1_SWB34 - \
        CSL_RAWFE_CFG_WDRMRG1_CFG)
    #define RFE_WDRMRG_WDRTHR_BF                    (                              \
        CSL_RAWFE_CFG_WDRMRG1_WDRTHR_BF - CSL_RAWFE_CFG_WDRMRG1_CFG)
    #define RFE_WDRMRG_AF                           (CSL_RAWFE_CFG_WDRMRG1_AF -    \
        CSL_RAWFE_CFG_WDRMRG1_CFG)
    #define RFE_WDRMRG_MA                           (CSL_RAWFE_CFG_WDRMRG1_MA -    \
        CSL_RAWFE_CFG_WDRMRG1_CFG)
    #define RFE_WDRMRG_CLIP_SFT                                                    \
        (CSL_RAWFE_CFG_WDRMRG1_CLIP_SFT - CSL_RAWFE_CFG_WDRMRG1_CFG)
    
    /* PWL register offsets, there are three instances of the PWL modules.
     * These offsets are same in both the modules and used for configuring
     * both the modules
     */
    #define RFE_PWL_MASK_SH                         (CSL_RAWFE_CFG_PWL1_MASK_SH -  \
        CSL_RAWFE_CFG_PWL1_MASK_SH)
    #define RFE_PWL_EN                              (CSL_RAWFE_CFG_PWL1_EN -       \
        CSL_RAWFE_CFG_PWL1_MASK_SH)
    #define RFE_PWL_THRX12                          (CSL_RAWFE_CFG_PWL1_THRX12 -   \
        CSL_RAWFE_CFG_PWL1_MASK_SH)
    #define RFE_PWL_THRX3                           (CSL_RAWFE_CFG_PWL1_THRX3 -    \
        CSL_RAWFE_CFG_PWL1_MASK_SH)
    #define RFE_PWL_THRY1                           (CSL_RAWFE_CFG_PWL1_THRY1 -    \
        CSL_RAWFE_CFG_PWL1_MASK_SH)
    #define RFE_PWL_THRY2                           (CSL_RAWFE_CFG_PWL1_THRY2 -    \
        CSL_RAWFE_CFG_PWL1_MASK_SH)
    #define RFE_PWL_THRY3                           (CSL_RAWFE_CFG_PWL1_THRY3 -    \
        CSL_RAWFE_CFG_PWL1_MASK_SH)
    #define RFE_PWL_SLP12                           (CSL_RAWFE_CFG_PWL1_SLP12 -    \
        CSL_RAWFE_CFG_PWL1_MASK_SH)
    #define RFE_PWL_SLP34                           (CSL_RAWFE_CFG_PWL1_SLP34 -    \
        CSL_RAWFE_CFG_PWL1_MASK_SH)
    #define RFE_PWL_SLPSH_CLIP                                                     \
        (CSL_RAWFE_CFG_PWL1_SLPSH_CLIP - CSL_RAWFE_CFG_PWL1_MASK_SH)
    #define RFE_PWL1_OFF1                           (CSL_RAWFE_CFG_PWL1_OFF1 -     \
        CSL_RAWFE_CFG_PWL1_MASK_SH)
    #define RFE_PWL1_OFF2                           (CSL_RAWFE_CFG_PWL1_OFF2 -     \
        CSL_RAWFE_CFG_PWL1_MASK_SH)
    #define RFE_PWL1_OFF3                           (CSL_RAWFE_CFG_PWL1_OFF3 -     \
        CSL_RAWFE_CFG_PWL1_MASK_SH)
    #define RFE_PWL1_OFF4                           (CSL_RAWFE_CFG_PWL1_OFF4 -     \
        CSL_RAWFE_CFG_PWL1_MASK_SH)
    #define RFE_PWL23_OFF1                          (CSL_RAWFE_CFG_PWL2_OFF1 -     \
        CSL_RAWFE_CFG_PWL2_MASK_SH)
    #define RFE_PWL23_OFF2                          (CSL_RAWFE_CFG_PWL2_OFF2 -     \
        CSL_RAWFE_CFG_PWL2_MASK_SH)
    #define RFE_PWL23_OFF3                          (CSL_RAWFE_CFG_PWL2_OFF3 -     \
        CSL_RAWFE_CFG_PWL2_MASK_SH)
    #define RFE_PWL23_OFF4                          (CSL_RAWFE_CFG_PWL2_OFF4 -     \
        CSL_RAWFE_CFG_PWL2_MASK_SH)
    #define RFE_PWL1_WB12                           (CSL_RAWFE_CFG_PWL1_WB_GAIN12 -\
        CSL_RAWFE_CFG_PWL1_MASK_SH)
    #define RFE_PWL1_WB34                           (CSL_RAWFE_CFG_PWL1_WB_GAIN34 -\
        CSL_RAWFE_CFG_PWL1_MASK_SH)
    #define RFE_PWL23_WB12                          (CSL_RAWFE_CFG_PWL2_WB_GAIN12 -\
        CSL_RAWFE_CFG_PWL2_MASK_SH)
    #define RFE_PWL23_WB34                          (CSL_RAWFE_CFG_PWL2_WB_GAIN34 -\
        CSL_RAWFE_CFG_PWL2_MASK_SH)
    #define RFE_PWL1_LUT                            (CSL_RAWFE_CFG_PWL1_LUT -      \
        CSL_RAWFE_CFG_PWL1_MASK_SH)
    #define RFE_PWL1_LUTCLIP                        (CSL_RAWFE_CFG_PWL1_LUTCLIP -  \
        CSL_RAWFE_CFG_PWL1_MASK_SH)
    #define RFE_PWL23_LUT                           (CSL_RAWFE_CFG_PWL2_LUT -      \
        CSL_RAWFE_CFG_PWL2_MASK_SH)
    #define RFE_PWL23_LUTCLIP                       (CSL_RAWFE_CFG_PWL2_LUTCLIP -  \
        CSL_RAWFE_CFG_PWL2_MASK_SH)
    
    #define RAWFE_MAX_INPUT_WIDTH                                                  \
        (CSL_RAWFE_CFG_IMAGE_CFG_WIDTH_MASK >> CSL_RAWFE_CFG_IMAGE_CFG_WIDTH_SHIFT)
    #define RAWFE_MAX_INPUT_HEIGHT                                                 \
        (CSL_RAWFE_CFG_IMAGE_CFG_HEIGHT_MASK >> CSL_RAWFE_CFG_IMAGE_CFG_HEIGHT_SHIFT)
    
    /* ========================================================================== */
    /*                         Structure Declarations                             */
    /* ========================================================================== */
    
    /* None */
    
    /* ========================================================================== */
    /*                          Function Declarations                             */
    /* ========================================================================== */
    
    /**
     *  \brief Local function to set Companding Lut configuration in the register
     *
     *  \param rfeRegs          RFE Base Address,
     *                          This parameter should not be 0.
     *  \param lutAddr          MMR address of the companding lut.
     *                          This parameter should not be 0
     *                          if companding lut is enabled.
     *  \param config           Pointer to #Vhwa_LutConfig structure
     *                          containing Lut configuration.
     *                          This parameter should not be NULL.
     *  \return                 Returns 0 on success else returns error value
     */
    static void RfeSetMergeLut(CSL_rawfe_cfgRegs *rfeRegs, uint32_t *lutAddr,
        const Vhwa_LutConfig *cfg);
    
    /**
     *  \brief Local function to set decompanding Lut configuration in the register
     *
     *  \param rfeRegs          RFE Base Address,
     *                          This parameter should not be 0.
     *  \param lutAddr          MMR address of the decompading lut.
     *                          This parameter should not be 0
     *                          if decompanding lut is enabled.
     *  \param lutModule        Decompanding module to be enabled/disabled.
     *                          Valid values are RFE_MODULE_DECOMP_LUT1,
     *                          RFE_MODULE_DECOMP_LUT2, RFE_MODULE_DECOMP_LUT3
     *  \param config           Pointer to Vhwa_LutConfig structure
     *                          containing companding configuration.
     *                          This parameter should not be NULL.
     *  \return                 Returns 0 on success else returns error value
     */
    static void RfeSetPwlLut(CSL_rawfe_cfgRegs *rfeRegs, uint32_t *lutAddr,
        uint32_t lutModule, const Vhwa_LutConfig *cfg);
    
    /* ========================================================================== */
    /*                            Global Variables                                */
    /* ========================================================================== */
    
    /* None */
    
    /* ========================================================================== */
    /*                          Function Definitions                              */
    /* ========================================================================== */
    
    
    /**
     *  Sets the common configuration to the RAW FE registers.
     */
    int32_t CSL_rfeSetFrameConfig(CSL_rawfe_cfgRegs *rfeRegs,
        const CslRfe_FrameConfig *cfg)
    {
        int32_t  status = FVID2_SOK;
        volatile uint32_t regVal;
    
        if ((NULL == cfg) || (NULL == rfeRegs))
        {
            status = FVID2_EBADARGS;
        }
        else
        {
            if ((RAWFE_MAX_INPUT_HEIGHT < cfg->height) ||
                (RAWFE_MAX_INPUT_WIDTH < cfg->width))
            {
                status = FVID2_EINVALID_PARAMS;
            }
        }
    
        if (FVID2_SOK == status)
        {
            regVal = 0;
            CSL_FINS(regVal, RAWFE_CFG_IMAGE_CFG_HEIGHT, cfg->height);
            CSL_FINS(regVal, RAWFE_CFG_IMAGE_CFG_WIDTH, cfg->width);
            CSL_REG32_WR(&rfeRegs->IMAGE_CFG, regVal);
        }
    
        return (status);
    }
    
    /* Sets WDR Merge Settings */
    int32_t CSL_rfeSetWdrConfig(const CSL_rawfe_cfgRegs *rfeRegs,
        uint32_t wdrModule, const Rfe_WdrConfig *cfg)
    {
        int32_t  status = FVID2_SOK;
        volatile uint32_t regVal;
        uint32_t wdrBaseAddr;
    
        if ((NULL == cfg) || (NULL == rfeRegs) ||
            ((RFE_MODULE_WDR_MERGE_MA1 != wdrModule) &&
                (RFE_MODULE_WDR_MERGE_MA2 != wdrModule)))
        {
            status = FVID2_EBADARGS;
        }
    
        if (FVID2_SOK == status)
        {
            if (RFE_MODULE_WDR_MERGE_MA1 == wdrModule)
            {
                wdrBaseAddr = (uint32_t)&rfeRegs->WDRMRG1_CFG;
            }
            else
            {
                wdrBaseAddr = (uint32_t)&rfeRegs->WDRMRG2_CFG;
            }
    
            if ((uint32_t)TRUE == cfg->enable)
            {
                /* Set the WDR Merge Gains */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_GAIN_GSHORT, cfg->gshort);
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_GAIN_GLONG, cfg->glong);
                CSL_REG32_WR((wdrBaseAddr + RFE_WDRMRG_GAIN), regVal);
    
                /* Set Black Level for the long exposure */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_LBLK12_LBK00, cfg->lbk[0U]);
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_LBLK12_LBK01, cfg->lbk[1U]);
                CSL_REG32_WR((wdrBaseAddr + RFE_WDRMRG_LBLK12), regVal);
    
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_LBLK34_LBK10, cfg->lbk[2U]);
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_LBLK34_LBK11, cfg->lbk[3U]);
                CSL_REG32_WR((wdrBaseAddr + RFE_WDRMRG_LBLK34), regVal);
    
                /* Set Black Level for the short exposure */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_SBLK12_SBK00, cfg->sbk[0U]);
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_SBLK12_SBK01, cfg->sbk[1U]);
                CSL_REG32_WR((wdrBaseAddr + RFE_WDRMRG_SBLK12), regVal);
    
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_SBLK34_SBK10, cfg->sbk[2U]);
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_SBLK34_SBK11, cfg->sbk[3U]);
                CSL_REG32_WR((wdrBaseAddr + RFE_WDRMRG_SBLK34), regVal);
    
                /* WDR merge WB gain 1 and 2 for long frame */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_LWB12_WB00, cfg->lwb[0U]);
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_LWB12_WB01, cfg->lwb[1U]);
                CSL_REG32_WR((wdrBaseAddr + RFE_WDRMRG_LWB12), regVal);
    
                /* WDR merge WB gain 3 and 4 for long frame */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_LWB34_WB10, cfg->lwb[2U]);
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_LWB34_WB11, cfg->lwb[3U]);
                CSL_REG32_WR((wdrBaseAddr + RFE_WDRMRG_LWB34), regVal);
    
                /* WDR merge WB gain 1 and 2 for short frame */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_SWB12_WB00, cfg->swb[0U]);
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_SWB12_WB01, cfg->swb[1U]);
                CSL_REG32_WR((wdrBaseAddr + RFE_WDRMRG_SWB12), regVal);
    
                /* WDR merge WB gain 3 and 4 for short frame */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_SWB34_WB10, cfg->swb[2U]);
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_SWB34_WB11, cfg->swb[3U]);
                CSL_REG32_WR((wdrBaseAddr + RFE_WDRMRG_SWB34), regVal);
    
                /* Set the WDR merge parameter WDRTHR and BF */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_WDRTHR_BF_WDRTHR, cfg->wdrThr);
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_WDRTHR_BF_BF, cfg->bf);
                CSL_REG32_WR((wdrBaseAddr + RFE_WDRMRG_WDRTHR_BF), regVal);
    
                /* Set the WDR merge parameter AF */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_AF_AFM, cfg->afm);
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_AF_AFE, cfg->afe);
                CSL_REG32_WR((wdrBaseAddr + RFE_WDRMRG_AF), regVal);
    
                /* Set WDR merge parameter MA */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_MA_MAD, cfg->mad);
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_MA_MAS, cfg->mas);
                CSL_REG32_WR((wdrBaseAddr + RFE_WDRMRG_MA), regVal);
    
                /* Set WDR merge clip value and shift before weight block */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_CLIP_SFT_CLIP, cfg->mergeClip);
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_CLIP_SFT_WTSFT, cfg->mergeShift);
                CSL_REG32_WR((wdrBaseAddr + RFE_WDRMRG_CLIP_SFT), regVal);
            }
    
            if ((uint32_t)TRUE == cfg->enable)
            {
                /* Set WDR Merge configuration */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_CFG_CFG_SBIT, cfg->sbit);
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_CFG_CFG_LBIT, cfg->lbit);
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_CFG_CFG_DST, cfg->dst);
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_CFG_CFG_WGT_SEL,
                    cfg->useShortExpForWgtCalc);
                CSL_FINS(regVal, RAWFE_CFG_WDRMRG1_CFG_CFG_EN, 1U);
                CSL_REG32_WR((wdrBaseAddr + RFE_WDRMRG_CFG), regVal);
            }
            else
            {
                /* Disable/bypass the merge block */
                CSL_REG32_FINS((wdrBaseAddr + RFE_WDRMRG_CFG),
                    RAWFE_CFG_WDRMRG1_CFG_CFG_EN, 0U);
            }
        }
    
        return (status);
    }
    
    /* Sets PWL Decompanding Settings */
    int32_t CSL_rfeSetPwlConfig(const CSL_rawfe_cfgRegs *rfeRegs,
        uint32_t pwlModule, const Rfe_PwlConfig *cfg)
    {
        int32_t  status = FVID2_SOK;
        volatile uint32_t regVal, pwlBaseAddr;
    
        if ((NULL == cfg) || (NULL == rfeRegs) ||
            ((RFE_MODULE_PWL1 != pwlModule) &&
                (RFE_MODULE_PWL2 != pwlModule) &&
                (RFE_MODULE_PWL3 != pwlModule)))
        {
            status = FVID2_EBADARGS;
        }
    
        if (FVID2_SOK == status)
        {
            /* Assuming
                PWL1 is for VS input
                PWL2 is for Short input
                PWL3 is for Long input
               TODO: Confirm this understanding
             */
            if (RFE_MODULE_PWL3 == pwlModule)
            {
                pwlBaseAddr = (uint32_t)&rfeRegs->PWL3_MASK_SH;
            }
            else if (RFE_MODULE_PWL2 == pwlModule)
            {
                pwlBaseAddr = (uint32_t)&rfeRegs->PWL2_MASK_SH;
            }
            else
            {
                pwlBaseAddr = (uint32_t)&rfeRegs->PWL1_MASK_SH;
            }
    
            /* Set Shift/Mask and DC Sub even if PWL is disabled */
            regVal = 0;
            CSL_FINS(regVal, RAWFE_CFG_PWL1_MASK_SH_MASK, cfg->mask);
            CSL_FINS(regVal, RAWFE_CFG_PWL1_MASK_SH_SHIFT, cfg->shift);
            CSL_REG32_WR((pwlBaseAddr + RFE_PWL_MASK_SH), regVal);
    
            if (RFE_MODULE_PWL1 == pwlModule)
            {
                /* White Balance Gains */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_PWL3_WB_GAIN12_WB_GAIN00, cfg->gain[0U]);
                CSL_FINS(regVal, RAWFE_CFG_PWL3_WB_GAIN12_WB_GAIN01, cfg->gain[1U]);
                CSL_REG32_WR((pwlBaseAddr + RFE_PWL1_WB12), regVal);
    
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_PWL3_WB_GAIN34_WB_GAIN10, cfg->gain[2U]);
                CSL_FINS(regVal, RAWFE_CFG_PWL3_WB_GAIN34_WB_GAIN11, cfg->gain[3U]);
                CSL_REG32_WR((pwlBaseAddr + RFE_PWL1_WB34), regVal);
    
                /* Set Black level in DC Sub register */
                CSL_REG32_FINS((pwlBaseAddr + RFE_PWL1_OFF1),
                    RAWFE_CFG_PWL1_OFF1_OFST00, cfg->offset[0U]);
                CSL_REG32_FINS((pwlBaseAddr + RFE_PWL1_OFF2),
                    RAWFE_CFG_PWL1_OFF2_OFST01, cfg->offset[1U]);
                CSL_REG32_FINS((pwlBaseAddr + RFE_PWL1_OFF3),
                    RAWFE_CFG_PWL1_OFF3_OFST10, cfg->offset[2U]);
                CSL_REG32_FINS((pwlBaseAddr + RFE_PWL1_OFF4),
                    RAWFE_CFG_PWL1_OFF4_OFST11, cfg->offset[3U]);
            }
            else
            {
                /* White Balance Gains */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_PWL3_WB_GAIN12_WB_GAIN00, cfg->gain[0U]);
                CSL_FINS(regVal, RAWFE_CFG_PWL3_WB_GAIN12_WB_GAIN01, cfg->gain[1U]);
                CSL_REG32_WR((pwlBaseAddr + RFE_PWL23_WB12), regVal);
    
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_PWL3_WB_GAIN34_WB_GAIN10, cfg->gain[2U]);
                CSL_FINS(regVal, RAWFE_CFG_PWL3_WB_GAIN34_WB_GAIN11, cfg->gain[3U]);
                CSL_REG32_WR((pwlBaseAddr + RFE_PWL23_WB34), regVal);
    
                /* Set Black level in DC Sub register */
                CSL_REG32_FINS((pwlBaseAddr + RFE_PWL23_OFF1),
                    RAWFE_CFG_PWL1_OFF1_OFST00, cfg->offset[0U]);
                CSL_REG32_FINS((pwlBaseAddr + RFE_PWL23_OFF2),
                    RAWFE_CFG_PWL1_OFF2_OFST01, cfg->offset[1U]);
                CSL_REG32_FINS((pwlBaseAddr + RFE_PWL23_OFF3),
                    RAWFE_CFG_PWL1_OFF3_OFST10, cfg->offset[2U]);
                CSL_REG32_FINS((pwlBaseAddr + RFE_PWL23_OFF4),
                    RAWFE_CFG_PWL1_OFF4_OFST11, cfg->offset[3U]);
            }
    
            {
                /* Set PWL threshold X1 and X2 - Unsigned */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_PWL1_THRX12_THR_X1, cfg->xthr1);
                CSL_FINS(regVal, RAWFE_CFG_PWL1_THRX12_THR_X2, cfg->xthr2);
                CSL_REG32_WR((pwlBaseAddr + RFE_PWL_THRX12), regVal);
    
                /* Set PWL threshold X3 - Unsigned */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_PWL1_THRX3_THR_X3, cfg->xthr3);
                CSL_REG32_WR((pwlBaseAddr + RFE_PWL_THRX3), regVal);
    
                /* Set PWL threshold Y1, Y2 and Y3 - Unsigned */
                CSL_REG32_FINS((pwlBaseAddr + RFE_PWL_THRY1),
                    RAWFE_CFG_PWL1_THRY1_THR_Y1, cfg->ythr1);
                CSL_REG32_FINS((pwlBaseAddr + RFE_PWL_THRY2),
                    RAWFE_CFG_PWL1_THRY2_THR_Y2, cfg->ythr2);
                CSL_REG32_FINS((pwlBaseAddr + RFE_PWL_THRY3),
                    RAWFE_CFG_PWL1_THRY3_THR_Y3, cfg->ythr3);
    
                /* Set the PWL slope 1 and 2 - Unsigned */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_PWL1_SLP12_SLOPE_1, cfg->slope1);
                CSL_FINS(regVal, RAWFE_CFG_PWL1_SLP12_SLOPE_2, cfg->slope2);
                CSL_REG32_WR((pwlBaseAddr + RFE_PWL_SLP12), regVal);
    
                /* Set the PWL slope 3 and 4 - Unsigned */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_PWL1_SLP34_SLOPE_3, cfg->slope3);
                CSL_FINS(regVal, RAWFE_CFG_PWL1_SLP34_SLOPE_4, cfg->slope4);
                CSL_REG32_WR((pwlBaseAddr + RFE_PWL_SLP34), regVal);
    
                /* PWL slope shift and clip */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_PWL1_SLPSH_CLIP_SLOPE_SHIFT,
                    cfg->slopeShift);
                CSL_FINS(regVal, RAWFE_CFG_PWL1_SLPSH_CLIP_CLIP, cfg->outClip);
                CSL_REG32_WR((pwlBaseAddr + RFE_PWL_SLPSH_CLIP), regVal);
            }
    
            if ((uint32_t)TRUE == cfg->enable)
            {
                /* Enable PWL Module */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_PWL1_EN_ENABLE, 1U);
                CSL_REG32_WR((pwlBaseAddr + RFE_PWL_EN), regVal);
            }
            else
            {
                /* Disable/Bypass the module */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_PWL1_EN_ENABLE, 0U);
                CSL_REG32_WR((pwlBaseAddr + RFE_PWL_EN), regVal);
            }
        }
    
        return (status);
    }
    
    /**
     *  \brief Sets Companding LUT Settings
     *
     *  \param rfeRegs          RFE Base Address,
     *                          This parameter should not be 0.
     *  \param lutModule        ID of the Lut module instance
     *                          Only valid values are
     *                          #RFE_MODULE_DECOMP_LUT_LONG,
     *                          #RFE_MODULE_DECOMP_LUT_SHORT_LONG or
     *                          #RFE_MODULE_DECOMP_LUT_VSHORT_SHORT
     *                          #RFE_MODULE_COMP_LUT
     *  \param cfg              Pointer to Vhwa_LutConfig structure
     *                          containing the RAWFE Lut configurations.
     *                          This parameter should not be NULL.
     *  \return                 Returns 0 on success else returns error value
     */
    int32_t CSL_rfeSetLutConfig(CSL_rawfe_cfgRegs *rfeRegs, uint32_t *lutAddr,
        uint32_t lutModule, const Vhwa_LutConfig *cfg)
    {
        int32_t  status = FVID2_SOK;
    
        if ((NULL == cfg) || (NULL == rfeRegs) ||
            ((RFE_MODULE_DECOMP_LUT1 != lutModule) &&
                (RFE_MODULE_DECOMP_LUT2 != lutModule) &&
                (RFE_MODULE_DECOMP_LUT3 != lutModule) &&
                (RFE_MODULE_COMP_LUT != lutModule)))
        {
            status = FVID2_EBADARGS;
        }
        else
        {
            if ((uint32_t)TRUE == cfg->enable)
            {
                if ((NULL == lutAddr) || (NULL == cfg->tableAddr))
                {
                    status = FVID2_EBADARGS;
                }
            }
        }
    
        if (FVID2_SOK == status)
        {
            if (RFE_MODULE_COMP_LUT == lutModule)
            {
                RfeSetMergeLut(rfeRegs, lutAddr, cfg);
            }
            else
            {
                RfeSetPwlLut(rfeRegs, lutAddr, lutModule, cfg);
            }
        }
    
        return (status);
    }
    
    /* Sets LSC Settings */
    int32_t CSL_rfeSetLscConfig(CSL_rawfe_cfgRegs *rfeRegs,
        uint32_t *lscLutAddr, const Rfe_LscConfig *cfg)
    {
        int32_t  status = FVID2_SOK;
        uint32_t cnt, val;
        volatile uint32_t regVal, *regAddr;
        uint32_t *lutAddr;
    
        if ((NULL == cfg) || (NULL == rfeRegs))
        {
            status = FVID2_EBADARGS;
        }
        else
        {
            if ((uint32_t)TRUE == cfg->enable)
            {
               if (cfg->numTblEntry > RFE_LSC_TBL_SIZE)
               {
                   status = FVID2_EINVALID_PARAMS;
               }
               if (NULL == lscLutAddr)
               {
                   status = FVID2_EBADARGS;
               }
            }
        }
    
        if (FVID2_SOK == status)
        {
            if ((uint32_t)TRUE == cfg->enable)
            {
                regAddr = lscLutAddr;
                lutAddr = cfg->tableAddr;
    
                for (cnt = 0U; cnt < cfg->numTblEntry/4; cnt ++)
                {
                    val = (*lutAddr) & 0xFFu;
                    lutAddr ++;
                    val |= ((*lutAddr) & 0xFFu) << 8u;
                    lutAddr ++;
                    val |= ((*lutAddr) & 0xFFu) << 16u;
                    lutAddr ++;
                    val |= ((*lutAddr) & 0xFFu) << 24u;
    
                    //val = *lutAddr;
                    lutAddr ++;
                    CSL_REG32_WR(regAddr, val);
    
                    regAddr ++;
                }
    
                regVal = 0;
    
                CSL_FINS(regVal, RAWFE_CFG_LSC_CFG_CHN_MODE, (uint32_t)cfg->chn_mode);
                CSL_FINS(regVal, RAWFE_CFG_LSC_CFG_GAIN_FORMAT, (uint32_t)cfg->gainFmt);
                CSL_FINS(regVal, RAWFE_CFG_LSC_CFG_MODE_M, (uint32_t)cfg->horzDsFactor);
                CSL_FINS(regVal, RAWFE_CFG_LSC_CFG_MODE_N, (uint32_t)cfg->vertDsFactor);
                CSL_FINS(regVal, RAWFE_CFG_LSC_CFG_EN, 1U);
                CSL_REG32_WR(&rfeRegs->LSC_CFG, regVal);
    
                /* Set LUT MAP values */
                regAddr = &rfeRegs->LSC_LUT_MAP07;
                for (cnt = 0U; cnt < RFE_DPC_OTF_LUT_SIZE/4; cnt ++)
                {
                    regVal = 0;
                    /* Using Mask and offset from MAP07 register as they are
                        the same for MAP815 */
                    CSL_FINS(regVal, RAWFE_CFG_LSC_LUT_MAP07_MAP0, cfg->lut_map[cnt*8 + 0]);
                    CSL_FINS(regVal, RAWFE_CFG_LSC_LUT_MAP07_MAP1, cfg->lut_map[cnt*8 + 1]);
                    CSL_FINS(regVal, RAWFE_CFG_LSC_LUT_MAP07_MAP2, cfg->lut_map[cnt*8 + 2]);
                    CSL_FINS(regVal, RAWFE_CFG_LSC_LUT_MAP07_MAP3, cfg->lut_map[cnt*8 + 3]);
                    CSL_FINS(regVal, RAWFE_CFG_LSC_LUT_MAP07_MAP4, cfg->lut_map[cnt*8 + 4]);
                    CSL_FINS(regVal, RAWFE_CFG_LSC_LUT_MAP07_MAP5, cfg->lut_map[cnt*8 + 5]);
                    CSL_FINS(regVal, RAWFE_CFG_LSC_LUT_MAP07_MAP6, cfg->lut_map[cnt*8 + 6]);
                    CSL_FINS(regVal, RAWFE_CFG_LSC_LUT_MAP07_MAP7, cfg->lut_map[cnt*8 + 7]);
                    CSL_REG32_WR(regAddr, regVal);
    
                    regAddr++;
                }
            }
            else
            {
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_LSC_CFG_EN, 0U);
                CSL_REG32_WR(&rfeRegs->LSC_CFG, regVal);
            }
        }
    
        return (status);
    }
    
    /* Sets DPC Otf Settings */
    int32_t CSL_rfeSetDpcOtfConfig(CSL_rawfe_cfgRegs *rfeRegs,
        const Rfe_DpcOtfConfig *cfg)
    {
        int32_t  status = FVID2_SOK;
        uint32_t cnt;
        volatile uint32_t regVal, *regAddr;
    
        if ((NULL == cfg) || (NULL == rfeRegs))
        {
            status = FVID2_EBADARGS;
        }
    
        if (FVID2_SOK == status)
        {
            if ((uint32_t)TRUE == cfg->enable)
            {
                regAddr = &rfeRegs->OTFDPC_THRSLP1;
    
                for (cnt = 0U; cnt < RFE_DPC_OTF_LUT_SIZE; cnt ++)
                {
                    regVal = 0;
                    /* Using Mask and offset from THRSLP1 register as they are
                       same for all thresholds and slopes */
                    CSL_FINS(regVal, RAWFE_CFG_OTFDPC_THRSLP1_THR1, cfg->threshold[cnt]);
                    CSL_FINS(regVal, RAWFE_CFG_OTFDPC_THRSLP1_SLP1, cfg->slope[cnt]);
                    CSL_REG32_WR(regAddr, regVal);
    
                    regAddr = regAddr + 1U;
                }
    
                /* RAWFE CFA CFG*/
                regVal = 0;
                regAddr = &rfeRegs->CFA_CFG;
                CSL_FINS(regVal, RAWFE_CFG_CFA_CFG_PHASE, cfg->cfa_phase);
                CSL_FINS(regVal, RAWFE_CFG_CFA_CFG_MODE, cfg->cfa_mode);
                CSL_REG32_WR(regAddr, regVal);
    
                /* THRX */
                regAddr = &rfeRegs->OTFDPC_THRX12;
                for (cnt = 0U; cnt < RFE_DPC_OTF_LUT_SIZE/2; cnt ++)
                {
                    regVal = 0;
                    CSL_FINS(regVal, RAWFE_CFG_OTFDPC_THRX12_THRX1, cfg->thrx[cnt*2]);
                    CSL_FINS(regVal, RAWFE_CFG_OTFDPC_THRX12_THRX2, cfg->thrx[cnt*2 + 1]);
                    CSL_REG32_WR(regAddr, regVal);
    
                    regAddr = regAddr + 1U;
                }
    
                /* LUT2 threshold and slope */
                regAddr = &rfeRegs->OTFDPC_LUT2_THRSLP1;
                for (cnt = 0U; cnt < RFE_DPC_OTF_LUT_SIZE; cnt ++)
                {
                    regVal = 0;
                    /* Using Mask and offset from THRSLP1 register as they are
                       same for all thresholds and slopes */
                    CSL_FINS(regVal, RAWFE_CFG_OTFDPC_LUT2_THRSLP1_THR1, cfg->lut2_threshold[cnt]);
                    CSL_FINS(regVal, RAWFE_CFG_OTFDPC_LUT2_THRSLP1_SLP1, cfg->lut2_slope[cnt]);
                    CSL_REG32_WR(regAddr, regVal);
    
                    regAddr = regAddr + 1U;
                }
    
                /* LUT2 THRX */
                regAddr = &rfeRegs->OTFDPC_LUT2_THRX12;
                for (cnt = 0U; cnt < RFE_DPC_OTF_LUT_SIZE/2; cnt ++)
                {
                    regVal = 0;
                    CSL_FINS(regVal, RAWFE_CFG_OTFDPC_LUT2_THRX12_THRX1, cfg->lut2_thrx[cnt*2]);
                    CSL_FINS(regVal, RAWFE_CFG_OTFDPC_LUT2_THRX12_THRX2, cfg->lut2_thrx[cnt*2 + 1]);
                    CSL_REG32_WR(regAddr, regVal);
    
                    regAddr = regAddr + 1U;
                }
    
                /* Enable DPC OTF and LUT MAP */
                regAddr = &rfeRegs->OTFDPC_EN;
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_OTFDPC_EN_EN, 1U);
                CSL_FINS(regVal, RAWFE_CFG_OTFDPC_EN_STATS_CFG, 1U);
                CSL_FINS(regVal, RAWFE_CFG_OTFDPC_EN_LUT_MAP, cfg->lut_map);
                CSL_REG32_WR(regAddr, regVal);
            }
            else
            {
                /* Disable DPC OTF */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_OTFDPC_EN_EN, 0U);
                CSL_REG32_WR(&rfeRegs->OTFDPC_EN, regVal);
            }
        }
    
        return (status);
    }
    
    /* Sets DPC Lut Settings */
    int32_t CSL_rfeSetDpcLutConfig(CSL_rawfe_cfgRegs *rfeRegs, uint32_t *dpcLutAddr,
        const Rfe_DpcLutConfig *cfg)
    {
        int32_t  status = FVID2_SOK;
        uint32_t cnt;
        uint32_t *pDpcLutAddr = NULL;
        volatile uint32_t regVal;
    
        if ((NULL == cfg) || (NULL == rfeRegs))
        {
            status = FVID2_EBADARGS;
        }
        else
        {
            if ((uint32_t)TRUE == cfg->enable)
            {
                if ((cfg->maxDefectPixels > RFE_DPC_LUT_SIZE) ||
                    (0U == cfg->maxDefectPixels))
                {
                    status = FVID2_EINVALID_PARAMS;
                }
                if (NULL == dpcLutAddr)
                {
                    status = FVID2_EBADARGS;
                }
                else
                {
                    pDpcLutAddr = dpcLutAddr;
                }
            }
        }
    
        if (FVID2_SOK == status)
        {
            if ((uint32_t)TRUE == cfg->enable)
            {
                /* Set the defective pixels Lookup table */
                for (cnt = 0U; cnt < cfg->maxDefectPixels; cnt ++)
                {
                    CSL_REG32_FINS(pDpcLutAddr, RAWFE_DPC_LUT_RAM_RAM1_DATA,
                        cfg->table[cnt]);
    
                    /* Go to next Lut address */
                    pDpcLutAddr = pDpcLutAddr + 1U;
                }
    
                /* Set the other configuration */
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_LUTDPC_CFG_SIZE, cfg->maxDefectPixels - 1U);
                CSL_FINS(regVal, RAWFE_CFG_LUTDPC_CFG_SEL, cfg->isReplaceWhite);
                CSL_FINS(regVal, RAWFE_CFG_LUTDPC_CFG_EN, 1U);
                CSL_REG32_WR(&rfeRegs->LUTDPC_CFG, regVal);
            }
            else
            {
                /* Disable DPC Lut */
                CSL_REG32_FINS(&rfeRegs->LUTDPC_CFG, RAWFE_CFG_LUTDPC_CFG_EN, 0U);
            }
        }
    
        return (status);
    }
    
    /* Sets WB Gain Settings */
    int32_t CSL_rfeSetWbConfig(CSL_rawfe_cfgRegs *rfeRegs,
        const Rfe_GainOfstConfig *cfg)
    {
        int32_t  status = FVID2_SOK;
        volatile uint32_t regVal;
    
        if ((NULL == cfg) || (NULL == rfeRegs))
        {
            status = FVID2_EBADARGS;
        }
        else
        {
            /* Set offset 0 and 1 in WB register */
            regVal = 0;
            CSL_FINS(regVal, RAWFE_CFG_WB2_OFFSET12_WB_OFST00, cfg->offset[0U]);
            CSL_FINS(regVal, RAWFE_CFG_WB2_OFFSET12_WB_OFST01, cfg->offset[1U]);
            CSL_REG32_WR(&rfeRegs->WB2_OFFSET12, regVal);
    
            /* Set offset 2 and 3 in WB register */
            regVal = 0;
            CSL_FINS(regVal, RAWFE_CFG_WB2_OFFSET34_WB_OFST10, cfg->offset[2U]);
            CSL_FINS(regVal, RAWFE_CFG_WB2_OFFSET34_WB_OFST11, cfg->offset[3U]);
            CSL_REG32_WR(&rfeRegs->WB2_OFFSET34, regVal);
    
            /* Set gains 0 and 1 in WB register */
            regVal = 0;
            CSL_FINS(regVal, RAWFE_CFG_WB2_GAIN12_WB_GAIN00, cfg->gain[0U]);
            CSL_FINS(regVal, RAWFE_CFG_WB2_GAIN12_WB_GAIN01, cfg->gain[1U]);
            CSL_REG32_WR(&rfeRegs->WB2_GAIN12, regVal);
    
            /* Set gains 2 and 3 in WB register */
            regVal = 0;
            CSL_FINS(regVal, RAWFE_CFG_WB2_GAIN34_WB_GAIN10, cfg->gain[2U]);
            CSL_FINS(regVal, RAWFE_CFG_WB2_GAIN34_WB_GAIN11, cfg->gain[3U]);
            CSL_REG32_WR(&rfeRegs->WB2_GAIN34, regVal);
        }
    
        return (status);
    }
    
    int32_t CSL_rfeSetH3aConfig(CSL_rawfe_cfgRegs *rfeRegs,
        const Rfe_H3aInConfig *cfg)
    {
        int32_t  status = FVID2_SOK;
        volatile uint32_t regVal = 0U;
    
        if ((NULL == cfg) || (NULL == rfeRegs))
        {
            status = FVID2_EBADARGS;
        }
        else
        {
            regVal = 0;
            if (cfg->inSel == RFE_H3A_IN_SEL_PCID_OUT_FRAME)
            {
                CSL_FINS(regVal, RAWFE_CFG_H3AMUX_CFG_PCIDSEL, 1U);
                CSL_FINS(regVal, RAWFE_CFG_H3AMUX_CFG_SEL, 0U);
            }
            else
            {
                CSL_FINS(regVal, RAWFE_CFG_H3AMUX_CFG_SEL, (uint32_t)cfg->inSel);
            }
    
            CSL_FINS(regVal, RAWFE_CFG_H3AMUX_CFG_SHIFT, cfg->shift);
            CSL_REG32_WR(&rfeRegs->H3AMUX_CFG, regVal);
        }
    
        return (status);
    }
    
    int32_t CSL_rfeSetH3aLutConfig(CSL_rawfe_cfgRegs *rfeRegs, uint32_t *h3aLutAddr,
        const Vhwa_LutConfig *lCfg)
    {
        int32_t  status = FVID2_SOK;
        uint32_t cnt;
        volatile uint32_t regVal = 0U;
        volatile uint32_t *tempLutAddr = NULL;
        uint32_t          *pH3aLutAddr = NULL;
    
        if ((NULL == lCfg) || (NULL == rfeRegs))
        {
            status = FVID2_EBADARGS;
        }
        else
        {
            if ((uint32_t)TRUE == lCfg->enable)
            {
                if (NULL == lCfg->tableAddr)
                {
                    status = FVID2_EBADARGS;
                }
                if (NULL == h3aLutAddr)
                {
                    status = FVID2_EBADARGS;
                }
                else
                {
                    pH3aLutAddr = h3aLutAddr;
                }
            }
        }
    
        if (FVID2_SOK == status)
        {
            if ((uint32_t)TRUE == lCfg->enable)
            {
                tempLutAddr = lCfg->tableAddr;
                for (cnt = 0U; cnt < RFE_H3A_COMP_LUT_SIZE; cnt += 2U)
                {
                    regVal = 0U;
    
                    CSL_FINS(regVal, RAWFE_H3A_LUT_RAM_RAM1_DATA_L,
                        tempLutAddr[cnt]);
    
                    if ((cnt + 1U) < RFE_H3A_COMP_LUT_SIZE)
                    {
                        CSL_FINS(regVal, RAWFE_H3A_LUT_RAM_RAM1_DATA_U,
                            tempLutAddr[cnt + 1U]);
                    }
    
                    CSL_REG32_WR(pH3aLutAddr, regVal);
    
                    pH3aLutAddr ++;
                }
    
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_H3ALUT_CFG_CLIP, lCfg->clip);
                CSL_FINS(regVal, RAWFE_CFG_H3ALUT_CFG_BITS, lCfg->inputBits);
                CSL_FINS(regVal, RAWFE_CFG_H3ALUT_CFG_EN, 1U);
                CSL_REG32_WR(&rfeRegs->H3ALUT_CFG, regVal);
            }
            else
            {
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_H3ALUT_CFG_EN, 0U);
                CSL_REG32_WR(&rfeRegs->H3ALUT_CFG, regVal);
            }
        }
    
        return (status);
    }
    
    /* -------------------------------------------------------------------------- */
    /*                 Internal Function Definitions                              */
    /* -------------------------------------------------------------------------- */
    
    static void RfeSetMergeLut(CSL_rawfe_cfgRegs *rfeRegs, uint32_t *lutAddr,
        const Vhwa_LutConfig *cfg)
    {
        uint32_t              cnt;
        volatile uint32_t     regVal = 0U;
        volatile uint32_t     *tempLutAddr = NULL;
        uint32_t              *pLutAddr = NULL;
    
        if ((NULL != rfeRegs) && (NULL != cfg))
        {
            if ((uint32_t)TRUE == cfg->enable)
            {
                tempLutAddr = cfg->tableAddr;
                pLutAddr = lutAddr;
                for (cnt = 0U; cnt < RFE_COMP_DECOMP_LUT_SIZE; cnt += 2U)
                {
                    regVal = 0U;
    
                    CSL_FINS(regVal, RAWFE_WDR_LUT_RAM_RAM1_DATA_L,
                        tempLutAddr[cnt]);
    
                    if ((cnt + 1U) < RFE_COMP_DECOMP_LUT_SIZE)
                    {
                        CSL_FINS(regVal, RAWFE_WDR_LUT_RAM_RAM1_DATA_U,
                            tempLutAddr[cnt + 1U]);
                    }
    
                    CSL_REG32_WR(pLutAddr, regVal);
    
                    pLutAddr ++;
                }
    
                regVal = 0;
                CSL_FINS(regVal, RAWFE_CFG_MRGLUT_CFG_CLIP, cfg->clip);
                CSL_FINS(regVal, RAWFE_CFG_MRGLUT_CFG_BITS, cfg->inputBits);
                CSL_FINS(regVal, RAWFE_CFG_MRGLUT_CFG_EN, 1U);
                CSL_REG32_WR(&rfeRegs->MRGLUT_CFG, regVal);
            }
            else
            {
                regVal = CSL_REG32_RD(&rfeRegs->MRGLUT_CFG);
                CSL_FINS(regVal, RAWFE_CFG_MRGLUT_CFG_CLIP, cfg->clip);
                CSL_FINS(regVal, RAWFE_CFG_MRGLUT_CFG_BITS, cfg->inputBits);
                CSL_FINS(regVal, RAWFE_CFG_MRGLUT_CFG_EN, 0U);
                CSL_REG32_WR(&rfeRegs->MRGLUT_CFG, regVal);
            }
        }
    }
    
    static void RfeSetPwlLut(CSL_rawfe_cfgRegs *rfeRegs, uint32_t *lutAddr,
        uint32_t lutModule, const Vhwa_LutConfig *cfg)
    {
        uint32_t                cnt;
        volatile uint32_t       regVal, *regAddrLut, *regAddrLutClip;
        uint32_t                *tempLutAddr = NULL;
        uint32_t                *pLutAddr = NULL;
    
        if ((NULL != rfeRegs) && (NULL != cfg))
        {
            /* Assuming
                PWL1 is for VS input
                PWL2 is for Short input
                PWL3 is for Long input
               TODO: Confirm this understanding
             */
            if (RFE_MODULE_DECOMP_LUT3 == lutModule)
            {
                regAddrLut = &rfeRegs->PWL3_LUT;
                regAddrLutClip = &rfeRegs->PWL3_LUTCLIP;
            }
            else if (RFE_MODULE_DECOMP_LUT2 == lutModule)
            {
                regAddrLut = &rfeRegs->PWL2_LUT;
                regAddrLutClip = &rfeRegs->PWL2_LUTCLIP;
            }
            else /* PWL for Very Short input */
            {
                regAddrLut = &rfeRegs->PWL1_LUT;
                regAddrLutClip = &rfeRegs->PWL1_LUTCLIP;
            }
    
            if ((uint32_t)TRUE == cfg->enable)
            {
                tempLutAddr = cfg->tableAddr;
                pLutAddr = lutAddr;
                for (cnt = 0U; cnt < RFE_COMP_DECOMP_LUT_SIZE; cnt += 2U)
                {
                    regVal = 0U;
    
                    CSL_FINS(regVal, RAWFE_PWL_LUT1_RAM_RAM1_DATA_L,
                        tempLutAddr[cnt]);
    
                    if ((cnt + 1U) < RFE_COMP_DECOMP_LUT_SIZE)
                    {
                        CSL_FINS(regVal, RAWFE_PWL_LUT1_RAM_RAM1_DATA_U,
                            tempLutAddr[cnt + 1U]);
                    }
    
                    CSL_REG32_WR(pLutAddr, regVal);
    
                    pLutAddr ++;
                }
    
                CSL_REG32_FINS(regAddrLutClip, RAWFE_CFG_PWL1_LUTCLIP_LUTCLIP,
                    cfg->clip);
    
                regVal = CSL_REG32_RD(regAddrLut);
                CSL_FINS(regVal, RAWFE_CFG_PWL1_LUT_LUT_BITS, cfg->inputBits);
                CSL_FINS(regVal, RAWFE_CFG_PWL1_LUT_LUT_EN, 1U);
                CSL_REG32_WR(regAddrLut, regVal);
            }
            else
            {
                regVal = CSL_REG32_RD(regAddrLut);
                CSL_FINS(regVal, RAWFE_CFG_PWL1_LUT_LUT_BITS, cfg->inputBits);
                CSL_FINS(regVal, RAWFE_CFG_PWL1_LUT_LUT_EN, 0U);
                CSL_REG32_WR(regAddrLut, regVal);
            }
        }
    }
    
    

  • Hi enrui,

    Thank you very much for the update!

    I will check internally to see if there is any other S/W bug on AM62A.

  • Hi enrui,

    Could you please check the LSC mode in your system?

    There seems some compatibility issue with the code below.
    If you work with RGGB sensor (not 4x4 sensors), the LSC mode "lscCfg->chn_mode" shall be set to 0 for backward compatibility.
    When that is 0, VPAC3L LSC shall behave in the same way as VPAC1/VPAC3 LSC.
    You force it to 0 if you work with RGGB 2x2 sensors (we can improve the code by checking if VPAC3L LSC settings are available in DCC input).

    static void tivxVpacVissDccMapLscParams(tivxVpacVissObj *vissObj)
    {
        if (NULL != vissObj)
        {
            Rfe_LscConfig *lscCfg = &vissObj->vissCfg.lscCfg;
            lscCfg->tableAddr = vissObj->dcc_table_ptr.lsc_lut;
            lscCfg->enable = 0;
            if (1U == vissObj->dcc_out_prms.vissLscCfg.lsc_params.enable)
            {
                viss_lsc_dcc_cfg_t * dcc_cfg = &vissObj->dcc_out_prms.vissLscCfg;
    #if defined(VPAC3L)
                viss_lsc_ext_dcc_cfg_t *dcc_ext_cfg = &vissObj->dcc_out_prms.vissLscExtCfg;
    #endif
                int32_t len = dcc_cfg->lsc_params.lut_size_in_bytes;
    
                lscCfg->numTblEntry  = len / 4;
                lscCfg->enable       = dcc_cfg->lsc_params.enable;
                lscCfg->gainFmt      = dcc_cfg->lsc_params.gain_mode_format;
                lscCfg->horzDsFactor = dcc_cfg->lsc_params.gain_mode_m;
                lscCfg->vertDsFactor = dcc_cfg->lsc_params.gain_mode_n;
    
    #if defined(VPAC3L)
                lscCfg->chn_mode     = dcc_ext_cfg->lsc_cfg_mode; 
                for(int i=0; i<RFE_LSC_LUT_MAP_SIZE; i++)
                {
                    lscCfg->lut_map[i] = (uint32_t)dcc_ext_cfg->lsc_ch2lut_map[i];
                }
    #endif
    

    The patch below separates VPAC1/VPAC3 LSC mode and VPAC3L LSC mode.

    diff --git a/soc/V2/csl_rawfe.c b/soc/V2/csl_rawfe.c
    index 6eb159a..b91e4c6 100755
    --- a/soc/V2/csl_rawfe.c
    +++ b/soc/V2/csl_rawfe.c
    @@ -599,18 +599,39 @@ int32_t CSL_rfeSetLscConfig(CSL_rawfe_cfgRegs *rfeRegs,
             {
                 regAddr = lscLutAddr;
                 lutAddr = cfg->tableAddr;
    +            uint32_t table_entry = cfg->numTblEntry;
     
    -            for (cnt = 0U; cnt < cfg->numTblEntry/4; cnt ++)
    +            #if defined (IP_VERSION_VPAC_V4)/* For VPAC3L the table entries are to be packed if channel mode is not 0*/
    +            if(cfg->chn_mode == RFE_LSC_CHNMODE_4_LEGACY)
                 {
    -                val = (*lutAddr) & 0xFFu;
    -                lutAddr ++;
    -                val |= ((*lutAddr) & 0xFFu) << 8u;
    -                lutAddr ++;
    -                val |= ((*lutAddr) & 0xFFu) << 16u;
    -                lutAddr ++;
    -                val |= ((*lutAddr) & 0xFFu) << 24u;
    -
    -                val = *lutAddr;
    +                /* Do nothing */
    +            }
    +            else
    +            {
    +                table_entry = table_entry/4;
    +            }
    +            #endif
    + 
    +            for (cnt = 0U; cnt < table_entry; cnt ++)
    +            {
    +                #if defined (IP_VERSION_VPAC_V4)/* For VPAC3L the table entries are to be packed if channel mode is not 0*/
    +                if(cfg->chn_mode == RFE_LSC_CHNMODE_4_LEGACY)
    +                {
    +                    val = *lutAddr;
    +                }
    +                else
    +                {
    +                    val = (*lutAddr) & 0xFFu;
    +                    lutAddr ++;
    +                    val |= ((*lutAddr) & 0xFFu) << 8u;
    +                    lutAddr ++;
    +                    val |= ((*lutAddr) & 0xFFu) << 16u;
    +                    lutAddr ++;
    +                    val |= ((*lutAddr) & 0xFFu) << 24u;
    +                }
    +                #else
    +                    val = *lutAddr;
    +                #endif
                     lutAddr ++;
                     CSL_REG32_WR(regAddr, val);
     
    

    Please let me know if you can get LSC to work in VPAC1/VPAC3 mode and get the correct output.

  • Hi enrui,

    Please let me know what types of sensor (2x2 or 4x4) you work on and have trouble with.

    If I recall correctly, tuning tool shall pack the LSC LUT properly and we don't really need the up-packing in driver code.

  • Hello,Gang

    I am using the X5B sensor, and before adding a patch, there were issues with either mode. After adding a patch, the problem was resolved and I chose the 2x2 color pattern. Thank you very much

  • Hi enrui,

    Thanks for the confirmation!

    We also have tested it on AM62A for 9.2 release.
    I will close this thread.