////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2019, 2024 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camxifepdaf20titan480.h
/// @brief IFE PDAF20 register setting for Titan480
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef CAMXIFEPDAF20TITAN480_H
#define CAMXIFEPDAF20TITAN480_H

#include "camxdefs.h"
#include "camxisphwsetting.h"
#include "camxispiqmodule.h"

CAMX_NAMESPACE_BEGIN

CAMX_BEGIN_PACKED

const INT32 MinBlockSide                        = 4;
const INT32 MaxBlockSide                        = 64;
const INT32 MinSADPixels                        = 16;
const INT32 MinFIRPadding                       = 2;    // 2 (For an FIR filter of length 5, 2 additional pixels will be
                                                        // required both on the left and the right side)
const INT32 LineExtractorMaxLinePerBlock        = 16 - 1;
const INT32 LineExtractorMaxBlockHeight         = 128 - 1;
const INT32 LineExtractorMaxHorizontalOffset    = (5808/4) - 1;
const INT32 PixelSeparatorMapRows               = 4;
const INT32 PixelSeparatorMapColumns            = 32;
const INT32 PixelSeparatorMaxRowPerBlock        = 16 - 1;
const INT32 PixelSeparatorMaxPixelsPerBlock     = 16 - 1;
const INT32 PixelSeparatorMaxOutputHeight       = PixelSeparatorMapRows - 1;
const INT32 PixelSeparatorMaxOutputWidth        = PixelSeparatorMapColumns - 1;
const INT16 PixelSeparatorMaxSpanValue          = 8;
const INT32 ResamplerMaxInHeight                = 4 - 1;
const INT32 ResamplerMaxInWidth                 = 32 - 1;
const INT32 ResamplerMaxOutWidth                = 32 - 1;
const INT32 ResamplerMaxOutSize                 = 32 - 1;
const INT32 GainMaxNumberHorizontalGrids        = 15;
const INT32 GainMaxNumberVeritcalGrids          = 11;
const INT32 SADMaxNumberOfPhases                = 32;
const INT32 SADMaxNumberOfRegions               = 20;
const INT32 PDMaxPackingDensity                 = 2;   // Worst case value. Sensor should be able to provide this data.
                                                       // Pending verification of calculation
const FLOAT HDRMaxExposureRatio                 = 32.0f;
const INT32 BinMaxLineNumber                    = 15;
const INT32 DecimateMaxLineNumber               = 15;

/// @brief Pixel Separator LUT
struct IFEPDAF20PixelSeparatorMapLUT
{
    UINT32 rightPixelIndex  : 8;  ///< Right Pixel Index
    UINT32 leftPixelIndex   : 8;  ///< Left Pixel  Index
    UINT32 UNUSED           : 16; ///< UNUSED bits
} CAMX_PACKED;

/// @brief Resampler Pixel LUT
struct IFEPDAF20SparsePDResamplerPixelLUT
{
    UINT32 pixel0X : 7;  ///< Pixel0 X Coordinate
    UINT32 pixel0Y : 4;  ///< Pixel0 Y Coordinate
    UINT32 pixel1X : 7;  ///< Pixel1 X Coordinate
    UINT32 pixel1Y : 4;  ///< Pixel1 Y coordinate
    UINT32 pixel2X : 7;  ///< Pixel2 X Coordinate
    UINT32 pixel2Y : 4;  ///< Pixel2 Y Coordinate
    UINT32 pixel3X : 7;  ///< Pixel3 X Coordinate
    UINT32 pixel3Y : 4;  ///< Pixel3 Y Coordinate
    UINT32 UNUSED  : 20; ///< UNUSED BITS
} CAMX_PACKED;

///@ brief Resampler Coefficients LUT
struct IFEPDAF20SparsePDResamplerCoefficientLUT
{
    UINT32 OP0K0 : 6; ///< K0 in OP0
    UINT32 OP0K1 : 6; ///< K1 in OP0
    UINT32 OP0K2 : 6; ///< K2 in OP0
    UINT32 OP0K3 : 6; ///< K3 in OP0
    UINT32 OP1K0 : 6; ///< K0 in OP1
    UINT32 OP1K1 : 6; ///< K1 in OP1
    UINT32 OP1K2 : 6; ///< K2 in OP1
    UINT32 OP1K3 : 6; ///< K3 in OP1
    UINT32 OP2K0 : 6; ///< K0 in OP2
    UINT32 OP2K1 : 6; ///< K1 in OP2
    UINT32 OP2K2 : 6; ///< K2 in OP2
    UINT32 OP2K3 : 6; ///< K3 in OP2
    UINT32 OP3K0 : 6; ///< K0 in OP3
    UINT32 OP3K1 : 6; ///< K1 in OP3
    UINT32 OP3K2 : 6; ///< K2 in OP3
    UINT32 OP3K3 : 6; ///< K3 in OP3
} CAMX_PACKED;

CAMX_END_PACKED

static const UINT PDAF20LUTBank0 = 0;
static const UINT PDAF20LUTBank1 = 1;

// Gain Map has 221 entries ( 17 rows x 13 colomns)
static const UINT32 IFEPDAF20GainMapLutTableRow    = 17;
static const UINT32 IFEPDAF20GainMapLutTableColumn = 13;
static const UINT32 IFEPDAF20GainMapLutTableSize   = (IFEPDAF20GainMapLutTableRow * IFEPDAF20GainMapLutTableColumn);
static const UINT32 IFEPDAF20GainMapDMILengthWord  = IFEPDAF20GainMapLutTableSize * sizeof(UINT32);

// Pixel Separator has 128 entries
static const UINT32 IFEPDAF20PixelSeparatorMapTableEntries = 128;
static const UINT32 IFEPDAF20PixelSepartorMapDMILengthWord = sizeof(IFEPDAF20PixelSeparatorMapLUT)  *
                                                             IFEPDAF20PixelSeparatorMapTableEntries;

// Resampler pixel map has 32 entries
static const UINT32 IFEPDAF20ResamplerPixelLutEntries       = 32;
static const UINT32 IFEPDAF20ResamplerPixelMapDMILengthWord = sizeof(IFEPDAF20SparsePDResamplerPixelLUT) *
                                                              IFEPDAF20ResamplerPixelLutEntries;

// Resampler Coefficients LUT has 32 entries
static const UINT32 IFEPDAF20ResamplerCoefficientLutEntries    = 32;
static const UINT32 IFEPDAF20ResamplerCoefficientDMILengthWord = sizeof(IFEPDAF20SparsePDResamplerCoefficientLUT) *
                                                                 IFEPDAF20ResamplerCoefficientLutEntries;

// CSID Pixel Map Entries has 64 entries
static const UINT32 IFEPDAF20CSIDPixelExtractorRows             = 64;
static const UINT32 IFEPDAF20CSIDPixelExtractorColomns          = 64;
static const UINT32 IFEPDAF20CSIDPixelExtractorEntries          = 64;
static const UINT32 IFEPDAF20CSIDPixelExtracionMapDMILengthWord = IFEPDAF20CSIDPixelExtractorEntries * sizeof(UINT64) * 2;
static const UINT32 IFEPDAF20CSIDSkipDMIValueOffset             = 4;

// PDAF20 DMI LUT SIZE
static const UINT32 IFEPDAF20DMILutSize      = IFEPDAF20GainMapDMILengthWord               +
                                               IFEPDAF20PixelSepartorMapDMILengthWord      +
                                               IFEPDAF20ResamplerPixelMapDMILengthWord     +
                                               IFEPDAF20ResamplerCoefficientDMILengthWord  +
                                               IFEPDAF20CSIDPixelExtracionMapDMILengthWord;
static const UINT32 IFEPDAF20DMILutSizeDword = IFEPDAF20DMILutSize / sizeof(UINT32);

static const UINT32 IFEPDAF20GainMapDMIOffset               = 0;
static const UINT32 IFEPDAF20PixelSeparatorMapDMIOffset     = IFEPDAF20GainMapDMIOffset + IFEPDAF20GainMapDMILengthWord;
static const UINT32 IFEPDAF20ResamplerPixelMapDMIOffset     = IFEPDAF20PixelSeparatorMapDMIOffset +
                                                              IFEPDAF20PixelSepartorMapDMILengthWord;
static const UINT32 IFEPDAF20ResamplerCoefficientDMIOffset  = IFEPDAF20ResamplerPixelMapDMIOffset +
                                                              IFEPDAF20ResamplerPixelMapDMILengthWord;
static const UINT32 IFEPDAF20CSIDPixelExtracionMapDMIOffset = IFEPDAF20ResamplerCoefficientDMIOffset +
                                                              IFEPDAF20ResamplerCoefficientDMILengthWord;
static const UINT32 IFEPDAF20PixelSeparatorLUTSelect = 1;
static const UINT32 IFEPDAF20ResamplerPixelLUTSelect = 2;
static const UINT32 IFEPDAF20ResamplerCoeffLUTSelect = 3;
static const UINT32 IFEPDAF20GainMapLUTSelect        = 4;

static const UINT32 IFEPDAF20CSIDPixelExtractorDMISelect = 1;

#define FLOAT_TO_Q(exp, f) \
    (static_cast<INT32>(((f)*(1<<(exp))) + (((f)<0) ? -0.5 : 0.5)))

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief IFE PDAF20 register setting for Titan480
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class IFEPDAF20Titan480 final : public ISPHWSetting
{
public:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// CreateCmdList
    ///
    /// @brief  Generate the Command List
    ///
    /// @param  pInputData       Pointer to the Inputdata
    /// @param  pDMIBufferOffset Pointer for DMI Buffer
    ///
    /// @return CamxResultSuccess if successful.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult CreateCmdList(
        VOID*   pInputData,
        UINT32* pDMIBufferOffset);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// PackIQRegisterSetting
    ///
    /// @brief  Calculate register settings based on common library result
    ///
    /// @param  pInput       Pointer to the Input data to the module for calculation
    /// @param  pOutput      Pointer to the Output data to the module for DMI buffer
    ///
    /// @return Return CamxResult.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult PackIQRegisterSetting(
        VOID* pInput,
        VOID* pOutput);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ~IFEPDAF20Titan480
    ///
    /// @brief  Constructor
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual ~IFEPDAF20Titan480();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IFEPDAF20Titan480
    ///
    /// @brief  Constructor
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    IFEPDAF20Titan480();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// DumpRegConfig
    ///
    /// @brief  Print register configuration of Crop module for debug
    ///
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID DumpRegConfig();

private:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ConfigureSparsePD
    ///
    /// @brief  Calculate register settings based on common library result
    ///
    /// @param  pHWConfig    Pointer to the PD HW Config
    /// @param  pOutput      Pointer to the Output data to the module for DMI buffer
    ///
    /// @return Return CamxResult.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult ConfigureSparsePD(
        PDHwConfig* pHWConfig,
        VOID*       pOutput);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ConfigureDualPD
    ///
    /// @brief  Calculate register settings based on common library result
    ///
    /// @param  pHWConfig    Pointer to the PD HW Config
    /// @param  pOutput      Pointer to the Output data to the module for DMI buffer
    /// @param  pInputData   Pointer to the Inputdata
    ///
    /// @return Return CamxResult.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult ConfigureDualPD(
        PDHwConfig*   pHWConfig,
        VOID*         pOutput,
        ISPInputData* pInputData);

    VOID*           m_pRegCmd;      ///< Register List of this Module
    UINT32          m_bankSelect;   ///< The DMI bank select

    IFEPDAF20Titan480(const IFEPDAF20Titan480&)            = delete; ///< Disallow the copy constructor
    IFEPDAF20Titan480& operator=(const IFEPDAF20Titan480&) = delete; ///< Disallow assignment operator
};

CAMX_NAMESPACE_END

#endif // CAMXIFEPDAF20TITAN480_H
