// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/*
 * Copyright (c) 2023 MediaTek Inc.
 */

#ifndef _DEMURA_H_
#define _DEMURA_H_


#define max_(a,b)        ((a>b) ? a : b)
#define min_(a,b)        ((a<b) ? a : b)
#define minmax_(a,b,c)   (max_((min_(a,c)),b))
#define posi_blk(CurV,CurH)     (CurV*block_width+CurH)

#define Get_Demura_Inv             0
#define DEMURA_MAX_LAYER_NUM       8
#define DEMURA_MAX_CHANNEL_NUM     4    // R/G/B/W


#define sw8Byte(x) \
    ((MS_U64)( \
        (((MS_U64)(x) & (MS_U64)0x00000000000000ff) << 56) | \
        (((MS_U64)(x) & (MS_U64)0x000000000000ff00) << 40) | \
        (((MS_U64)(x) & (MS_U64)0x0000000000ff0000) << 24) | \
        (((MS_U64)(x) & (MS_U64)0x00000000ff000000) << 8) | \
        (((MS_U64)(x) & (MS_U64)0x000000ff00000000) >> 8) | \
        (((MS_U64)(x) & (MS_U64)0x0000ff0000000000) >> 24) | \
        (((MS_U64)(x) & (MS_U64)0x00ff000000000000) >> 40) | \
        (((MS_U64)(x) & (MS_U64)0xff00000000000000) >> 56)))

#define sw5Byte(x) \
    ((MS_U64)( \
        (((MS_U64)(x) & (MS_U64)0x00000000ff) << 32) | \
        (((MS_U64)(x) & (MS_U64)0x000000ff00) << 16) | \
        ((MS_U64)(x) & (MS_U64)0x0000ff0000) | \
        (((MS_U64)(x) & (MS_U64)0x00ff000000) >> 16) | \
        (((MS_U64)(x) & (MS_U64)0xff00000000) >> 32)))

#define sw4Byte(x) \
    ((MS_U32)( \
        (((MS_U32)(x) & (MS_U32)0x000000ff) << 24) | \
        (((MS_U32)(x) & (MS_U32)0x0000ff00) << 8) | \
        (((MS_U32)(x) & (MS_U32)0x00ff0000) >> 8) | \
        (((MS_U32)(x) & (MS_U32)0xff000000) >> 24)))

#define sw2Byte(x) \
    ((MS_U16)( \
        (((MS_U16)(x) & (MS_U16)0x00ff) << 8) | \
        (((MS_U16)(x) & (MS_U16)0xff00) >> 8)))

#define BinVersion           ((0 << 8) + 7)
#define DllVersion           ((0 << 8) + 3)
#define HNodeCount           481
#define VNodeCount           271
#define HNodeCount_U10       241
#define VNodeCount_U10       136
#define MAX_INX_BIN_LENGTH   (512 * 1024) //512k

#define MAX_BIN_LENGTH       (6 *1024 * 1024) // 6MB

#define Aligned_Value        16

#define BlockHSize  8
#define BlockVSize  8

#define CusDataSize 0 //0x100

#define DMC_GET_LUT_SHIFT(reg, size, lut_size) \
({ \
    for (shift = 2; shift <= 6; shift++) \
    { \
        if ((((lut_size) - 1) << shift) == size) \
        { \
            reg = shift; \
            break; \
        } \
    } \
})

//----------------------- Chip device ID start -----------------------//
#define ID_CHIP_U9          0x003D  // Ursa  9 (Unicorn)
#define ID_CHIP_U10         0x0090  // Ursa 10 (Uniqlo)
#define ID_CHIP_U11         0x0094  // Ursa 11 (Ultrasonic)
#define ID_CHIP_U12         0x008F  // Ursa 12 (UBike)
#define ID_CHIP_TERRA       0x005F  // Tcon Terra
#define ID_CHIP_MORTON      0x00E9    //Morton
//TO_DO_CHECK #define ID_CHIP_MERLIN      ??    //Merlin
//----------------------- Chip device ID end -----------------------//

//----------------------- Customer ID start -----------------------//
#define ID_CUS_MSTAR        0x0000
#define ID_CUS_AUO          0x0100
#define ID_CUS_INL          0x0200
#define ID_CUS_HISENSE      0x0300
#define ID_CUS_BOE          0x1100
#define ID_CUS_PANDA        0x1200
//----------------------- Customer ID end -----------------------//


typedef struct rgb_struct
{
    int r;
    int g;
    int b;
    double dbr;
    double dbg;
    double dbb;
}strgb_structInfo, *LPrgb_structInfo;

typedef struct layer_info_struct
{
    int dram_h_size;
    int dram_v_size;
    int block_h_size;
    int block_v_size;
    int dmc_plane_num;
    int dmc_rgb_mode;
    int real_dram_h_size;
    int real_dram_v_size;
}stlayer_info_structInfo, *LPlayer_info_structInfo;

typedef struct
{
    int address;
    int mask;
    int value;
    char *description;
}reg_struct;

typedef struct
{
    reg_struct Bit07_00;
}_08bits;

typedef struct
{
    reg_struct Bit07_00;
    reg_struct Bit15_08;
}_16bits;

typedef struct
{
    reg_struct Bit07_00;
    reg_struct Bit15_08;
    reg_struct Bit23_16;
}_24bits;

typedef struct
{
    MS_U64 addr;
    MS_U16 val;
    MS_U32 mask;
}demura_reg;


typedef struct
{   //Align to reg_sc_0406.xls
    demura_reg reg_dmc_black_limit;            // 12bit
    demura_reg reg_dmc_plane_level1;           // 12bit
    demura_reg reg_dmc_plane_level2;           // 12bit
    demura_reg reg_dmc_plane_level3;           // 12bit
    demura_reg reg_dmc_plane_level4;           // 12bit
    demura_reg reg_dmc_plane_level5;           // 12bit
    demura_reg reg_dmc_plane_level6;           // 12bit
    demura_reg reg_dmc_plane_level7;           // 12bit
    demura_reg reg_dmc_plane_level8;           // 12bit
    demura_reg reg_dmc_white_limit;            // 12bit
    demura_reg reg_dmc_data_r_mag4;            // 3 bit
    demura_reg reg_dmc_data_r_mag3;            // 3 bit
    demura_reg reg_dmc_data_r_mag2;            // 3 bit
    demura_reg reg_dmc_data_r_mag1;            // 3 bit
    demura_reg reg_dmc_data_r_mag8;            // 3 bit
    demura_reg reg_dmc_data_r_mag7;            // 3 bit
    demura_reg reg_dmc_data_r_mag6;            // 3 bit
    demura_reg reg_dmc_data_r_mag5;            // 3 bit
    demura_reg reg_dmc_data_g_mag4;            // 3 bit
    demura_reg reg_dmc_data_g_mag3;            // 3 bit
    demura_reg reg_dmc_data_g_mag2;            // 3 bit
    demura_reg reg_dmc_data_g_mag1;            // 3 bit
    demura_reg reg_dmc_data_g_mag8;            // 3 bit
    demura_reg reg_dmc_data_g_mag7;            // 3 bit
    demura_reg reg_dmc_data_g_mag6;            // 3 bit
    demura_reg reg_dmc_data_g_mag5;            // 3 bit
    demura_reg reg_dmc_data_b_mag4;            // 3 bit
    demura_reg reg_dmc_data_b_mag3;            // 3 bit
    demura_reg reg_dmc_data_b_mag2;            // 3 bit
    demura_reg reg_dmc_data_b_mag1;            // 3 bit
    demura_reg reg_dmc_data_b_mag8;            // 3 bit
    demura_reg reg_dmc_data_b_mag7;            // 3 bit
    demura_reg reg_dmc_data_b_mag6;            // 3 bit
    demura_reg reg_dmc_data_b_mag5;            // 3 bit
    demura_reg reg_dmc_plane_b1_coef;          // 14bit
    demura_reg reg_dmc_plane_12_coef;          // 14bit
    demura_reg reg_dmc_plane_23_coef;          // 14bit
    demura_reg reg_dmc_plane_34_coef;          // 14bit
    demura_reg reg_dmc_plane_45_coef;          // 14bit
    demura_reg reg_dmc_plane_56_coef;          // 14bit
    demura_reg reg_dmc_plane_67_coef;          // 14bit
    demura_reg reg_dmc_plane_78_coef;          // 14bit
    demura_reg reg_dmc_plane_9w_coef;          // 14bit
    demura_reg reg_dmc_plane_9w_ks22;          // 1 bit
    demura_reg reg_dmc_plane_89_ks22;          // 1 bit
    demura_reg reg_dmc_plane_78_ks22;          // 1 bit
    demura_reg reg_dmc_plane_67_ks22;          // 1 bit
    demura_reg reg_dmc_plane_56_ks22;          // 1 bit
    demura_reg reg_dmc_plane_45_ks22;          // 1 bit
    demura_reg reg_dmc_plane_34_ks22;          // 1 bit
    demura_reg reg_dmc_plane_23_ks22;          // 1 bit
    demura_reg reg_dmc_plane_12_ks22;          // 1 bit
    demura_reg reg_dmc_plane_b1_ks22;          // 1 bit
    demura_reg reg_dmc_h_block;                // 3 bit
    demura_reg reg_dmc_v_block;                // 3 bit
    demura_reg reg_dmc_rgb_mode;               // 1 bit
    demura_reg reg_dmc_block_size;             // 2 bit
    demura_reg reg_dmc_plane_num;              // 4 bit
    demura_reg reg_dmc_h_lut_num;              // 11bit
    demura_reg reg_dmc_v_lut_num;              // 11bit
    demura_reg reg_dmc_dummy1;                 // 16bit
    demura_reg reg_dmc_dummy2;                 // 16bit
    demura_reg reg_dmc_dither_rst_e_4_frame;   // 1 bit
    demura_reg reg_dmc_dither_pse_rst_num;     // 2 bit
    demura_reg reg_dmc_pos_af_gamma;           // 1 bit
    demura_reg reg_dmc_bypass;                 // 1 bit
    demura_reg reg_dmc_dither_en;              // 2 bit
    demura_reg reg_dmc_db_en;                  // 1 bit
    demura_reg reg_dmc_r_en;                   // 1 bit
    demura_reg reg_dmc_g_en;                   // 1 bit
    demura_reg reg_dmc_b_en;                   // 1 bit
    demura_reg reg_dmc_data_r_offset1;         // 16bit
    demura_reg reg_dmc_data_r_offset2;         // 16bit
    demura_reg reg_dmc_data_r_offset3;         // 16bit
    demura_reg reg_dmc_data_r_offset4;         // 16bit
    demura_reg reg_dmc_data_r_offset5;         // 16bit
    demura_reg reg_dmc_data_r_offset6;         // 16bit
    demura_reg reg_dmc_data_r_offset7;         // 16bit
    demura_reg reg_dmc_data_r_offset8;         // 16bit
    demura_reg reg_dmc_data_g_offset1;         // 16bit
    demura_reg reg_dmc_data_g_offset2;         // 16bit
    demura_reg reg_dmc_data_g_offset3;         // 16bit
    demura_reg reg_dmc_data_g_offset4;         // 16bit
    demura_reg reg_dmc_data_g_offset5;         // 16bit
    demura_reg reg_dmc_data_g_offset6;         // 16bit
    demura_reg reg_dmc_data_g_offset7;         // 16bit
    demura_reg reg_dmc_data_g_offset8;         // 16bit
    demura_reg reg_dmc_data_b_offset1;         // 16bit
    demura_reg reg_dmc_data_b_offset2;         // 16bit
    demura_reg reg_dmc_data_b_offset3;         // 16bit
    demura_reg reg_dmc_data_b_offset4;         // 16bit
    demura_reg reg_dmc_data_b_offset5;         // 16bit
    demura_reg reg_dmc_data_b_offset6;         // 16bit
    demura_reg reg_dmc_data_b_offset7;         // 16bit
    demura_reg reg_dmc_data_b_offset8;         // 16bit
    demura_reg reg_dmc_panel_h_size;           // 13bit
    demura_reg reg_dmc_preload_line;           // 13bit
//    demura_reg reg_dmc_r_h_r;                  // 5 bit
//    demura_reg reg_dmc_q_h_r;                  // 8 bit
//    demura_reg reg_dmc_grid_line_en;           // 1 bit
//    demura_reg reg_dmc_grid_line_size;         // 3 bit
//    demura_reg reg_dmc_grid_line_color;        // 8 bit
    demura_reg reg_dmc_flow_ctrl_en;           // 1 bit
    demura_reg reg_dmc_flow_len;               // 11bit
 // demura_reg reg_dmc_bist_fail;              // 16bit
 // demura_reg reg_adl_checksum_xp;            // 3 bit
 // demura_reg reg_adl_checksum_lr;            // 1 bit
 // demura_reg reg_adl_checksum_en;            // 1 bit
  demura_reg reg_dmc_guard_band_size;        // 8 bit
    demura_reg reg_dmc_plane_level9;           // 12bit
    demura_reg reg_dmc_data_r_mag9;            // 3 bit
    demura_reg reg_dmc_data_g_mag9;            // 3 bit
    demura_reg reg_dmc_data_b_mag9;            // 3 bit
    demura_reg reg_dmc_plane_89_coef;          // 14bit
    demura_reg reg_dmc_data_r_offset9;         // 16bit
    demura_reg reg_dmc_data_g_offset9;         // 16bit
    demura_reg reg_dmc_data_b_offset9;         // 16bit
    demura_reg reg_dmc_delta_low_limit;        // 16bit
    demura_reg reg_dmc_delta_high_limit;       // 16bit
    demura_reg reg_dmc_pos_v_offset;           // 4 bit
    demura_reg reg_dmc_pos_h_offset;           // 4 bit
    demura_reg reg_dmc_l1_eq_0_en;             // 1 bit
    demura_reg reg_dmc_flow_rest;              // 11bit
//  demura_reg reg_dmc_bist_fail_0;            // 7 bit
//  demura_reg reg_dmc_bist_fail_1;            // 7 bit
//  demura_reg reg_dmc_bist_fail_2;            // 7 bit
}registers;

typedef struct
{

    int reg_dmc_plane_num;       //  4 bit
    int reg_dmc_h_block;         //  3 bit
    int reg_dmc_v_block;         //  3 bit
    int reg_dmc_rgb_mode;        //  1 bit
    int reg_dmc_panel_h_size;    // 13 bit
    int reg_dmc_r_en;            //  1 bit
    int reg_dmc_g_en;            //  1 bit
    int reg_dmc_b_en;            //  1 bit
    //int reg_dmc_w_en;            //  1 bit
    //int reg_dmc_dga_en;          //  1 bit

    int reg_dmc_black_limit;     // 12 bit
    int reg_dmc_plane_level1;    // 12 bit
    int reg_dmc_plane_level2;    // 12 bit
    int reg_dmc_plane_level3;    // 12 bit
    int reg_dmc_plane_level4;    // 12 bit
    int reg_dmc_plane_level5;    // 12 bit
    int reg_dmc_plane_level6;    // 12 bit
    int reg_dmc_plane_level7;    // 12 bit
    int reg_dmc_plane_level8;    // 12 bit
    int reg_dmc_plane_level9;    // 12 bit
    int reg_dmc_white_limit;     // 12 bit

    int reg_dmc_dither_rst_e_4_frame; //  1 bit
    int reg_dmc_dither_pse_rst_num;   //  2 bit
    int reg_dmc_dither_en;            //  2 bit

    MS_BOOL bROI_en;              // 1 bit
    int  iROI_hor_start_offset;
    int  iROI_hor_end_offset;
    int  iROI_ver_start_offset;
    int  iROI_ver_end_offset;


    strgb_structInfo *Lut_in[8];
    //int    **Lut_out;
    //double **Lut_out_inv;

}interface_info;

/*brown
typedef enum
{
    TOOL_PACKING = 0,
    IC_DRAM = 1,
    COMPRESSED_IC_DRAM = 2,
} LAYER_DATA_TYPE;
*/

typedef enum
{
    TYPE_MSTAR = 0,
    TYPE_INX = 256,
} DEMURA_TYPE;

typedef enum
{
    CRC16 = sizeof(MS_U16),
    CRC32 = sizeof(MS_U32),
    CRC64 = sizeof(MS_U64),
} CRC_TYPE;

typedef struct
{
  MS_U16   nBlackType;
  MS_U16   nBlackChecksum;
  MS_U32   nBlackStartAddr;
  MS_U32   nBlackDataLength;
} BlackHeader;

typedef struct
{
  MS_U64   nIdentification : 8;
  MS_U64   nASIC : 40;
  MS_U64   nVersion : 8;
  MS_U64   nAlgorithm : 8;
  MS_U32   nDate;
  MS_U8    nBlackStructure;
  MS_U8    nDefination;
  MS_U16   nReserved;
  BlackHeader nBlack1;
  BlackHeader nBlack2;
  BlackHeader nBlack3;
  BlackHeader nBlack4;
  MS_U64   nReserved1;
  MS_U64   nReserved2;
  MS_U64   nReserved3;
  MS_U64   nReserved4;
  MS_U64   nReserved5;
  MS_U64   nReserved6;
  MS_U64   nReserved7;
  MS_U32   nReserved8;
  MS_U16   nReserved9;
  MS_U16   nCheckSum;
} DemuraHeader;


#define MHAL_HEADER_GAIN_NUM (8)
#define MHAL_HEADER_OFFSET_NUM (8)
#define MHAL_HEADER_PLANE_NUM (8)
#define MHAL_HEADER_NODE_NUM (8)
#define MHAL_HEADER_FORMAT_NUM (16)
#define MHAL_HEADER_PADDING_NUM (27)
#define MHAL_HEADER_U32_BYTES (4)
#define MHAL_HEADER_U16_BYTES (2)

typedef struct
{
    MS_U8 format[MHAL_HEADER_FORMAT_NUM];
    MS_U8 version[MHAL_HEADER_U32_BYTES];
    MS_U8 header_size[MHAL_HEADER_U32_BYTES]; /* 20 ~ 23 */
    MS_U8 lut_size[MHAL_HEADER_U32_BYTES];  /* 24 ~ 27 */
    MS_U8 h_size[MHAL_HEADER_U16_BYTES]; /* 28 29  need to remap */
    MS_U8 v_size[MHAL_HEADER_U16_BYTES]; /* 30 31  need to remap */
    MS_U8 mode; /* 32 */
    MS_U8 plane_num; /* 33 */
    MS_U8 gain_r[MHAL_HEADER_GAIN_NUM]; /* 34 ~ 41 */
    MS_U8 gain_g[MHAL_HEADER_GAIN_NUM]; /* 42 ~ 49 */
    MS_U8 gain_b[MHAL_HEADER_GAIN_NUM]; /* 50 ~ 57 */
    MS_U8 offset_r[MHAL_HEADER_OFFSET_NUM][MHAL_HEADER_U16_BYTES]; /* 58 ~ 73 */
    MS_U8 offset_g[MHAL_HEADER_OFFSET_NUM][MHAL_HEADER_U16_BYTES]; /* 74 ~ 89 */
    MS_U8 offset_b[MHAL_HEADER_OFFSET_NUM][MHAL_HEADER_U16_BYTES]; /* 90 ~ 105 */
    MS_U8 h_blk_size; /* 106 */
    MS_U8 v_blk_size; /* 107 */
    MS_U8 black_limit[MHAL_HEADER_U16_BYTES]; /* 108 ~ 109 */
    MS_U8 plane[MHAL_HEADER_PLANE_NUM][MHAL_HEADER_U16_BYTES]; /* 110 ~ 125 */
    MS_U8 white_limit[MHAL_HEADER_U16_BYTES]; /* 126 ~ 127 */
    MS_U8 dither_en; /* 128 */
    MS_U8 padding[MHAL_HEADER_PADDING_NUM]; /* 129 ~ 155 */
    MS_U8 header_crc[MHAL_HEADER_U32_BYTES]; /* offset DMC_BIN_HEADER_CRC_OFFSET : 156 ~ 159  need to remap */
#if 0
    u32 lut_data; /* 160 ~ 163 */
    u8 node[HEADER_NODE_NUM]; /* 164 ~ 16*/
#endif
}DemuraSubBinHeaderUFC;

// BIN header structure (37 bytes)
typedef struct
{
  MS_U32   nAllBinCheckSum;                                               // 4
  MS_U32   nHeaderCheckSum;                                               // 8
  MS_U32   nHeaderSize;                                                   // 12
  MS_U32   nAllBinSize;                                                   // 16
  MS_U64   nDemuraIdH;                                                    // 24
  MS_U64   nDemuraIdL;                                                    // 32
  MS_U16   nBinVersion;                                                   // 34
  MS_U8    nDataFormat;                                                   // 35
  MS_U8    bR_ch_Enable : 1;                                              // 36
  MS_U8    bG_ch_Enable : 1;
  MS_U8    bB_ch_Enable : 1;
  MS_U8    bW_ch_Enable : 1;
  MS_U8    nReserved : 4;
  MS_U16   nHNodeCount;                                                   // 38
  MS_U16   nVNodeCount;                                                   // 40
  MS_U8    nLayerStart : 4; //Bits[3:0]: Start layer number               // 41
  MS_U8    nLayerEnd : 4;   //Bits[7:4]: End layer number
  MS_U8    bSeparate;       //0: Y channel, 1: Separate R/G/B channels    // 42
  MS_U32   nLDataStartAddr;                                               // 46
  MS_U32   nLDataOriginalSize;                                            // 50
  MS_U32   nLDataFlashSize;                                               // 54
  MS_U32   nRegisterStartAddr;                                            // 58
  MS_U32   nRegisterCount;                                                // 62
  MS_U16   nDllVersion;                                                   // 64
  MS_U32   nProjectID;                                                    // 68
  MS_U32   nCusDataStartAddr;                                             // 72
  MS_U32   nCusDataSize;                                                  // 76
  MS_U32   nDate;                                                         // 80
  MS_U8    nHBlockSize;                                                   // 81
  MS_U8    nVBlockSize;                                                   // 82
  MS_U8    nPacketSize;                                                   // 83
} __attribute__((packed)) MstarSubBinHeader;  //83 byte for DMC



typedef struct
{
  MS_U32   RegAddr : 24;
  MS_U32   RegValue : 8;
  MS_U8    RegMask;
}  __attribute__((packed)) RegData;

/*brown
typedef enum
{
    EN_DEMURA_ID_INVLID  = 0x00,
    EN_DEMURA_ID_MSTAR   = 0x01,
    EN_DEMURA_ID_AUO     = 0x02,
    EN_DEMURA_ID_CSOT    = 0x03,
    EN_DEMURA_ID_INX     = 0x04,
    EN_DEMURA_ID_LGD     = 0x05,
    EN_DEMURA_ID_MAX     = 0x06,
}EN_DEMURA_ID;

typedef struct
{
    MS_U32           project_id;
    MS_U32           reg_base_addr;
    LAYER_DATA_TYPE  data_type;
    MS_U32           HNode;
    MS_U32           VNode;
    MS_U32           Blk_h_size;
    MS_U32           Blk_v_size;
    MS_U32           Gain_type;
    MS_U32           Sep_type;   // 1 : R/G/B sperate ;  0 : R/G/B share.
    MS_U32           LevelCount;
    MS_U32           Build_Date;
    EN_DEMURA_ID     Vendor_ID;

    MS_BOOL          channel_enable[4];   // R/G/B/W channel
    MS_U8            *bin_buf;            // pointer to malloc_buffer
    MS_U32           bin_size;
}BinOutputInfo;
*/

#endif
