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

📄 regctrl_g2d.cpp

📁 SMDK2416_BSP
💻 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 S3C2450 FIMGSE-2D

Functions:

Notes:

--*/

#include "precomp.h"
#include "regctrl_g2d.h"

RegCtrlG2D::RegCtrlG2D() : m_pG2DReg(NULL)
{
	m_pG2DReg = (volatile S3C2450_G2D_REG *)VirtualAlloc(0, sizeof(S3C2450_G2D_REG), MEM_RESERVE, PAGE_NOACCESS);
	if (!m_pG2DReg)
	{
		RETAILMSG(1, (TEXT("#####G2D::MapVirtualAddress VirtualAlloc failed!\r\n")));
	}
	if (!VirtualCopy((PVOID)m_pG2DReg, (PVOID)(S3C2450_BASE_REG_PA_G2D>>8), sizeof(S3C2450_G2D_REG), PAGE_READWRITE | PAGE_NOCACHE | PAGE_PHYSICAL ))
	{
		RETAILMSG(1, (TEXT("#####G2D::MapVirtualAddress VirtualCopy failed!\r\n")));
	}
}

RegCtrlG2D::~RegCtrlG2D()
{
       if (m_pG2DReg != NULL)
       {
    		VirtualFree((PVOID)m_pG2DReg, 0, MEM_RELEASE);    
       }	
}
/**
*	@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)
{
	m_pG2DReg->INTEN = (0x1<<9);// + (0x1<<8) + (0x1);				//Enable Interrupt
	m_pG2DReg->INTC_PEND = 0x80000000;		//
}

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 + -