⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 regctrl_g2d.cpp

📁 SAMSUNG S3C6410 CPU BSP for winmobile6
💻 CPP
字号:
//
// 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:    regctrl_g2d.cpp

Abstract:        implementation of register controller for S3C6410 FIMGSE-2D

Functions:

Notes:

--*/

#include <windows.h>
#include <s3c6410_base_regs.h>
#include <DrvLib.h>
#include "regctrl_g2d.h"

RegCtrlG2D::RegCtrlG2D() : m_pG2DReg(NULL)
{
    m_pG2DReg = (G2D_REG *)DrvLib_MapIoSpace(S3C6410_BASE_REG_PA_2DGRAPHICS, sizeof(G2D_REG), FALSE);
    if (m_pG2DReg == NULL)
    {
        RETAILMSG(1, (_T("[DISPDRV:ERR] RegCtrlG2D() : m_pG2DReg DrvLib_MapIoSpace() Failed \n\r")));
    }
}

RegCtrlG2D::~RegCtrlG2D()
{
    if (m_pG2DReg != NULL)
    {
        DrvLib_UnmapIoSpace((PVOID)m_pG2DReg);
        m_pG2DReg = NULL;
    }
}

/**
*    @fn    RegCtrlG2D::Reset(void)
*    @brief    This function reset 2D IP that clear register set of G2D
*
*/
void RegCtrlG2D::Reset(void)
{
    m_pG2DReg->CONTROL = 1;  //assert G2D reset, automatic clear
//  m_pG2DReg->CONTROL = 0;  //deassert G2D reset
}

/**
*    @fn        void RegCtrlG2D::SetEndian(bool bEndian)
*    @brief    Set both Source and Destination data Endian
*    @param    bEndian    Endian setting 1: Big Endian, 0: Little Endian
*/
void RegCtrlG2D::SetEndian(bool bEndian)
{
    CheckFifo(1);
    m_pG2DReg->ENDIAN = ( (bEndian<<1) | (bEndian<<0) );
}

/**
*    Interrupt Block
*/
void RegCtrlG2D::IntEnable(void)
{
    IntPendingClear();
    //    m_pG2DReg->INTC_PEND = 0x80000000;        //
    m_pG2DReg->INTEN = (0x1<<9);// + (0x1<<8) + (0x1);                //Enable Interrupt
}

void RegCtrlG2D::IntDisable(void)
{
    m_pG2DReg->INTEN &= ~((1<<9) /*+(1<<8) + 1*/);//Disable Interrupt
}

void RegCtrlG2D::IntPendingClear(void)
{
    m_pG2DReg->INTC_PEND = 0x80000701;        // Level Interrupt (Interupt Clear Enable)    // 0x80000401;??
    m_pG2DReg->INTC_PEND = 0x80000000;        // Level Interrupt (Interupt Clear Enable)    
}

/**
*    The below codes is legacy codes, this will be no more used.
**/
void RegCtrlG2D::IntEnableForDeEngineFinish(void)
{
    m_pG2DReg->INTEN = (m_pG2DReg->INTEN)&~(0x7<<8) | (1<<10);
    m_pG2DReg->INTC_PEND = (0x80000000|(7<<8));
    m_pG2DReg->INTC_PEND = 0x80000000;
}
void RegCtrlG2D::IntEnableForCmdFinish(void)
{
    m_pG2DReg->INTEN = ((m_pG2DReg->INTEN)&~(0x7<<8)) | (1<<9);
    m_pG2DReg->INTC_PEND = 0x80000000;
}
void RegCtrlG2D::IntEnableForOverflow(bool bFifo, BYTE ucFifoLevel)
{
    if(bFifo) {
//        m_pG2DReg->INTEN = ((m_pG2DReg->INTEN)&~(0x7<<8))|(1<<8)|1;
        m_pG2DReg->INTEN = ((m_pG2DReg->INTEN)&~(0x7<<8))|1;
        m_pG2DReg->FIFO_INTC = ucFifoLevel;
    }    
    else
    {
        m_pG2DReg->INTEN = ((m_pG2DReg->INTEN)&~(0x7<<8))|(1<<8);
    }
    m_pG2DReg->INTC_PEND = 0x80000000;
}
void RegCtrlG2D::InterruptDisAll(void)
{
//    printf("The total number of interrupts occured:[Expected:%d], [Real:%d]\n",  (m_uMaxDx+1)*(m_uMaxDy+1),uIntCnt);
    m_pG2DReg->INTEN = (m_pG2DReg->INTEN)&~((3<<8)|1);
}

void RegCtrlG2D::WaitForIdleStatus(void)
{
    while(1)
    {
        if((m_pG2DReg->FIFO_STATUS & G2D_DE_STATUS_FA_BIT))
        {
            break;
        }
    }
}


bool RegCtrlG2D::WaitForFinish(void)
{
    volatile unsigned uPendVal;
//    static DWORD pending_count = 0;

    uPendVal = m_pG2DReg->INTC_PEND;
/*
    pending_count ++;
    if(pending_count >50)
    {
         RETAILMSG (0, (TEXT("uPendVal : %x\r\n"),uPendVal));            
    }
*/
    if( (uPendVal>>8) & 0x7){
        switch( (uPendVal>>8) & 0x7) {
            case 1:
                m_pG2DReg->INTC_PEND = ((1<<31)|(1<<8));        // Overflow
                 RETAILMSG (0, (TEXT("OV\r\n"),uPendVal));                            
                break;
            case 2:
                m_pG2DReg->INTC_PEND = ((1<<31)|(1<<9));        // Command All Finish, Engine IDLE
                 RETAILMSG (0, (TEXT("EI\r\n"),uPendVal));
                break;
            case 4:
                m_pG2DReg->INTC_PEND = ((1<<31)|(1<<10));    // Drawing Engine Finish
                 RETAILMSG (0, (TEXT("EF\r\n"),uPendVal));                
                return false;
            default:
                m_pG2DReg->INTC_PEND = ((1<<31)|(0x7<<8));    // All Clear
                break;
        }
        m_pG2DReg->INTC_PEND = (DWORD)(1<<31); // Victor gave us a guidance such this line to clear pending.        

//        pending_count = 0;

        return true;
    }
    return false;
}

/**
*    Command Block
*/

/**
*    @fn    RegCtrlG2D::CheckFifo(DWORD uEmptyFifo)
*    @param    uEmptyFifo    Requested Empty FIFO size
*    @return    int        Return Available FIFO Size
*    @note This function will do busy-waiting until requested fifo is empty.
*/
int RegCtrlG2D::CheckFifo(DWORD uEmptyFifo)
{
    if(uEmptyFifo > G2D_COMMANDFIFO_SIZE)
    {
        RETAILMSG(1, (TEXT("[G2D] Requested Empty fifo is exceeded over maxium value, this will be set maxium value")));
        uEmptyFifo = G2D_COMMANDFIFO_SIZE;
    }
    while( (((m_pG2DReg->FIFO_STATUS)& (0x3f<<1))>>1) > (G2D_COMMANDFIFO_SIZE - uEmptyFifo) ); 
    
    RETAILMSG(0,(TEXT("Occupied FIFO: %d\n"),((m_pG2DReg->FIFO_STATUS)& (0x3f<<1))>>1 ));    
    return (G2D_COMMANDFIFO_SIZE - (((m_pG2DReg->FIFO_STATUS)& (0x3f<<1))>>1));

}


/*
 *     @fn    void RegCtrlG2D::SetFirstBitBLTData(DWORD uFirstData)
 *    @brief    Set First Source Data to FIMG2D HW Register using CMD register 2, Next Data must be issued by CMD Register 3 continously
 *    @param    uFirstData    32bit surface Surface data
 */
void RegCtrlG2D::SetFirstBitBLTData(DWORD uFirstData)
{
    CheckFifo(1);
    m_pG2DReg->CMDR2 = uFirstData;
}

/*
 *     @fn    void RegCtrlG2D::SetNextBitBLTData(DWORD uFirstData)
 *    @brief    Set Next Source Data to FIMG2D HW Register using CMD register 2, Next Data must be issued by CMD Register 3
 *    @param    uNextData    32bit surface Surface data
 */
void RegCtrlG2D::SetNextBitBLTData(DWORD uNextData)
{
    CheckFifo(1);
    m_pG2DReg->CMDR3 = uNextData;
}

/**
*    @fn    void RegCtrlG2D::SetRotationMode(DWORD uRotationType)
*    @param    uRotationType    This is register value for each rotation. It can handle 0, 90, 180, 270, Xflip, Yflip
*    @note G2D's Rotation Register has only 1 bit as enabling.
*/
void RegCtrlG2D::SetRotationMode(ROT_TYPE uRotationType)
{
    CheckFifo(1);
    m_pG2DReg->ROT_MODE = ((m_pG2DReg->ROT_MODE) & ~0x3f)|(uRotationType);    
}

/**
*    @fn    void RegCtrlG2D::SetRotationOrg(WORD usRotOrg, WORD usRotOrgY)
*    @param    usRotOrgX    X value of Rotation Origin.
*    @param    usRotOrgY    Y value of Rotation Origin.
*    @sa    SetRotationOrgX()
*    @sa SetRotationOrgY()
*    @brief    this function sets rotation origin.
*/
void RegCtrlG2D::SetRotationOrg(WORD usRotOrgX, WORD usRotOrgY)
{
    SetRotationOrgX(usRotOrgX);
    SetRotationOrgY(usRotOrgY);
}

void RegCtrlG2D::SetRotationOrgX(WORD usRotOrgX)
{
    CheckFifo(1);
    m_pG2DReg->ROT_OC_X = (DWORD) (usRotOrgX & 0x000007FF);
}

void RegCtrlG2D::SetRotationOrgY(WORD usRotOrgY)
{
    CheckFifo(1);
    m_pG2DReg->ROT_OC_Y = (DWORD) (usRotOrgY & 0x000007FF);
}

/**
*    @fn        void RegCtrlG2D::SetCoordinateSrcBlockEndian(DWORD uStartX, DWORD uStartY, DWORD uEndX, DWORD uEndY)
*    @brief    Set Source Data Area that will be read
*    @param    uStartX    left X 
*            uStartY    top Y
*            uEndX    right X
*            uEndY    bottom Y
*/
void RegCtrlG2D::SetCoordinateSrcBlock(DWORD uStartX, DWORD uStartY, DWORD uEndX, DWORD uEndY)
{
    CheckFifo(4);
    m_pG2DReg->COORD0_X = uStartX;
    m_pG2DReg->COORD0_Y = uStartY;
    m_pG2DReg->COORD1_X = uEndX;
    m_pG2DReg->COORD1_Y = uEndY;    
}

/**
*    @fn        void RegCtrlG2D::SetCoordinateDstBlockEndian(DWORD uStartX, DWORD uStartY, DWORD uEndX, DWORD uEndY)
*    @brief    Set Destination Data Area that will be written
*    @param    uStartX    left X 
*            uStartY    top Y
*            uEndX    right X
*            uEndY    bottom Y
*/
void RegCtrlG2D::SetCoordinateDstBlock(DWORD uStartX, DWORD uStartY, DWORD uEndX, DWORD uEndY)
{
    CheckFifo(4);
    m_pG2DReg->COORD2_X = uStartX;
    m_pG2DReg->COORD2_Y = uStartY;
    m_pG2DReg->COORD3_X = uEndX;
    m_pG2DReg->COORD3_Y = uEndY;    
}

/**
*    @fn        void RegCtrlG2D::SetRoptype(DWORD uRopVal)
*    @note    Set Ternary Raster Operation into G2D register directly
*/
void RegCtrlG2D::SetRopValue(DWORD uRopVal)
{
    CheckFifo(1);
    m_pG2DReg->ROP = ((m_pG2DReg->ROP)&(~0xff)) | uRopVal;
    RETAILMSG(0,(TEXT("ROPRegAddr : 0x%x, ROP : 0x%x\r\n"),&(m_pG2DReg->ROP), uRopVal));    
}

/**
*    @fn        void RegCtrlG2D::Set3rdOperand(G2D_OPERAND3 e3rdOp)
*    @brief    Set thrid operand as Pattern or Foreground color
*    @param    e3rdOp can be pattern or foreground color
*/
void RegCtrlG2D::Set3rdOperand(G2D_OPERAND3 e3rdOp)
{
    CheckFifo(1);
    DWORD u3rdOpSel =
        (e3rdOp == G2D_OPERAND3_PAT) ? G2D_OPERAND3_PAT_BIT :
        (e3rdOp == G2D_OPERAND3_FG) ? G2D_OPERAND3_FG_BIT :     0xffffffff;

    if (u3rdOpSel == 0xffffffff) 
        Assert(0); // UnSupported Third Operand!

    m_pG2DReg->ROP = ((m_pG2DReg->ROP) & ~(0x1<<13)) | u3rdOpSel;
}

/**
*    @fn        void RegCtrlG2D::SetClipWindow(PRECTL prtClipWindow)
*    @brief    Set Clipping Data Area that will be not cropped.
*    @param    uStartX    left X 
*            uStartY    top Y
*            uEndX    right X
*            uEndY    bottom Y
*/
void RegCtrlG2D::SetClipWindow(PRECTL prtClipWindow)
{
    CheckFifo(4);
    RETAILMSG(0,(TEXT("cl:%d, ct:%d, cr:%d, cb:%d\r\n"), prtClipWindow->left, prtClipWindow->top, prtClipWindow->right, prtClipWindow->bottom));
    m_pG2DReg->CW_LEFT_TOP_X = prtClipWindow->left;
    m_pG2DReg->CW_LEFT_TOP_Y =  prtClipWindow->top;
    m_pG2DReg->CW_RIGHT_BOTTOM_X = prtClipWindow->right;
    m_pG2DReg->CW_RIGHT_BOTTOM_Y = prtClipWindow->bottom;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -