//
// Copyright (c) Samsung Electronics. Co. LTD.  All rights reserved.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:    fimgse2d.h

Abstract:       defines for FIMGSE-2D Graphics Accelerator
                header to define the FIMGSE-2D class.
Functions:

Notes:          This version is made for FIMGSE-2D v3.0

--*/

#ifndef __FIMGSE2D_H__
#define __FIMGSE2D_H__

#include "Display_main.h"
#include "Priv_context.h"
#include <g2d_reg.h>

//#define FIMG_C_MODEL
//#define USE_OALFLUSH
//#define COPYCLONEBUFFER_ASM_OPTIMIZE

// Select Register
#define NORMAL_MODE 0
#define FOREGROUND_IMAGE 1
#define BACKGROUND_IMAGE 2

// Third Operand Selection Register
#define IDX_MASKED_SELECT 4
#define THIRD_PATTERN 0
#define THIRD_FOREGROUND 1
#define THIRD_BACKGROUND 2

//
#define CLONETOSURF     0
#define SURFTOCLONE     1

#define MAX_2DHW_WIDTH  (8000)
#define MAX_2DHW_HEIGHT (8000)
#define MAX_2DHW_XCOORD (8000)
#define MAX_2DHW_YCOORD (8000)

#define G2D_COLOR_RGB_565       ((0<<4)|2) // 0x02
#define G2D_COLOR_RGBA_5551     ((1<<4)|3) // 0x13
#define G2D_COLOR_ARGB_1555     ((0<<4)|4) // 0x04
#define G2D_COLOR_RGBA_8888     ((1<<4)|1) // 0x11
#define G2D_COLOR_ARGB_8888     ((0<<4)|1) // 0x01
#define G2D_COLOR_XRGB_8888     ((0<<4)|0) // 0x00
#define G2D_COLOR_RGBX_8888     ((1<<4)|0) // 0x10
#define G2D_COLOR_XRGB_1555     ((0<<4)|3) // 0x03
#define G2D_COLOR_RGBX_5551     ((1<<4)|3) // 0x03
#define G2D_COLOR_BGRX_5551     ((3<<4)|3) // 0x03
#define G2D_COLOR_XBGR_1555     ((2<<4)|3) // 0x03
#define G2D_COLOR_PACKED_RGB_888    ((0<<4)|7) // 0x03    

#define G2D_COLOR_UNUSED        (0xff)

#define ABS(v)                  (((v)>=0) ? (v):(-(v)))
#define SWAP(x,y, _type)        { _type i; i = x; x = y; y = i; }

#define G2D_INTERRUPT_TIMEOUT_VALUE 10      // ms
#define G2D_POLLING_TIMEOUT_COUNT 100000    // For loop count value


typedef enum
{
    SRC_BUFFER = 0,
    DST_BUFFER = 1,
    PAT_BUFFER = 2,
    MSK_BUFFER = 3,
} G2D_BUFFER_TYPE;

typedef enum
{
    POSITIVE_DIRECTION = 0,            
    NEGATIVE_DIRECTION = 1,            
} G2D_DIRECTION;

typedef enum
{
    NO_OVERLAPPED = 0,
    LEFT_DOWN_DIRECTION = 1,
    RIGHT_DOWN_DIRECTION = 2,   
    LEFT_UP_DIRECTION = 3,         
    RIGHT_UP_DIRECTION = 4,
} G2D_OVERLAP_DIRECTION;

typedef enum
{
    ROTATE_FALSE = 0,
    ROTATE_TRUE = 1,
} G2D_ROTATION;

typedef enum
{
    INVALIDATE = 0,
    CLEAN = 1, 
    CLEAN_AND_INVALIDATE = 2,
} CACHE_OP_TYPE;

typedef struct
{
    DWORD    dwBaseaddr;
    DWORD    *pdwBaseaddr;
    DWORD    dwPhyBaseaddr;
    DWORD    dwHoriRes;
    DWORD    dwVertRes;
    DWORD    dwStride;
    DWORD    dwColorMode;
    RECTL    sRcl;
} SURFACE_DESCRIPTOR, *PSURFACE_DESCRIPTOR;

typedef struct
{
    DWORD   dwSrcNonPreBlendMode;
    DWORD   dwAlphaBlendMode;
    DWORD   dwColorKeyMode;
    DWORD   dwTransParentMode;
    DWORD   dwCWEn;
    DWORD   dwStretchEn;
    DWORD   dwMaskEn;
} CMD_REG, *PCMD_REG;

typedef struct
{
    DWORD   dwSrc_Phy;
    DWORD   dwDst_Phy;
    DWORD   dwPat_Phy;
    DWORD   dwMsk_Phy;
    DWORD   *pdwSrc_Vir;
    DWORD   *pdwDst_Vir;
    DWORD   *pdwPat_Vir;
    DWORD   *pdwMsk_Vir;
} CLONE_BUFFER, *PCLONE_BUFFER;


class FIMG2D
{
    private:
        volatile G2D_REG * m_pG2DReg;

        DWORD   m_dwSrcDirectionX;
        DWORD   m_dwSrcDirectionY;
        DWORD   m_dwDstDirectionX;
        DWORD   m_dwDstDirectionY;
        DWORD   m_dwMaskDirectionY;
        DWORD   m_dwMaskDirectionX;
        DWORD   m_dwBrushDirectionY;
        DWORD   m_dwBrushDirectionX;

        DWORD   m_dwEnableRotate90;
        BOOL    m_InitAA;

        CMD_REG m_sCMD;

        // for Interrupt
        DWORD   m_dwSysIntr2D;     
        HANDLE  m_hInterrupt2D;

        G2D_ACCEL_CONTROL_ARGS m_G2DAccelArgs;

        void InitClk(void);
        void CacheFlush(VOID *pAddress, DWORD width_byte, DWORD height, DWORD stride, DWORD left_byte, DWORD flags);
        void IntEnable(void);
        void IntDisable(void);
        void SoftReset(void);
        void IntPendingClear(void);
        BOOL WaitForIdlePolling(DWORD dwPollingCnt);
        void StartBlt(void);
        BOOL StartG2D(DWORD dwProcessingType);
        void SurfCacheClear(void);
        DWORD Is_Overlapped_Rect(GPEBltParms *pBltParms, PRECTL prclDst, PRECTL prclSrc);
        void RotateRectl(RECTL *prcl, GPESurf *orgSurf);
        SCODE Calculate_Directions(GPEBltParms *pBltParms, PRECTL prclDst, PRECTL prclSrc);
        DWORD GetRelativeDegree(DWORD SrcDegree, DWORD DstDegree);
        BOOL SetSourceSurf(GPEBltParms *pBltParms, RECTL rcl);
        BOOL SetDestinationSurf(GPEBltParms *pBltParms, RECTL rcl);
        BOOL SetPatternSurf(GPEBltParms *pBltParms);
        BOOL SetMaskSurf(GPEBltParms *pBltParms);
        BOOL SetClipRectl(PRECTL prclClip, RECTL rclDst);
        BOOL CreateCloneBuffer(GPESurf* orgSurf, SURFACE_DESCRIPTOR *descSurf, PRECTL prcl, DWORD bType);
        BOOL CopyCloneBuffer(GPESurf* orgSurf, SURFACE_DESCRIPTOR descSurf, RECTL prcl, BOOL bDirection);
        BOOL ReleaseCloneBuffer(void);
        void CacheFlushForSurf(GPEBltParms *pBltParms, PRECTL rclSrc, PRECTL rclDst, PRECTL rclClip, G2D_ACCEL_CONTROL_ARGS m_G2DAccelArgs);

#ifndef FIMG_C_MODEL
        void g2d_wd_reg (DWORD Addr, DWORD Data);
        DWORD g2d_rd_reg(DWORD Addr);
#endif

    public:

        SURFACE_DESCRIPTOR m_descSrcSurface;    // 2D HW Source Surface Information
        SURFACE_DESCRIPTOR m_descDstSurface;    // 2D HW Destination Surface Information
        SURFACE_DESCRIPTOR m_descBrushSurface;  // 2D HW Pattern Surface Information
        SURFACE_DESCRIPTOR m_descMaskSurface;   // 2D HW Mask Surface Information

        CLONE_BUFFER m_sCloneBuffer;
        DWORD m_dwProcessType;
      
        FIMG2D();
        virtual ~FIMG2D();
        void Init();
        BOOL InitializeInterrupt(void);
       
        void DeinitInterrupt(void);

        DWORD GetHWColorFormat(GPESurf *pSurf);
        SCODE BitBlt(GPEBltParms *pBltParms, G2D_ACCEL_CONTROL_ARGS m_G2DControlArgs);
       
        BOOL GetPhyAddress(DWORD * pdwVirtual, DWORD * pdwPhysical);
        BOOL IsRunning(void);
        void WaitForIdle() {WaitForIdlePolling(G2D_POLLING_TIMEOUT_COUNT);}
        BOOL WaitForIdleInterrupt(void);
};

#endif
