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

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.
Hello ,TI expert
May I ask if the LSC module driver issue that occurred on the AM62 platform before has been resolved?

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,
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.