📄 dispdrvr.c
字号:
break;
case LQ035Q7DB02: //add by hzh
{
PCD = 10;
RETAILMSG(1, (TEXT("InitLCDController:LQ035Q7DB02 display type, PCD=%d\r\n"), PCD));
// Configure the TMED dithering engine
// Use the magic number described in the Cotulla EAS, 0x00AA5500;
v_pLcdRegs->TRGBR = LCD_TRS(0x00) | LCD_TGS(0x55) | LCD_TBS(0xAA);
// Use the magic number described in the Cotulla EAS, 0x0000754F;
v_pLcdRegs->TCR = LCD_TM2S | LCD_TM1S | LCD_TM2En | LCD_TM1En |
LCD_TVBS(0x04) | LCD_THBS(0x05) | LCD_TSCS(0x03) |
LCD_TED;
v_pLcdRegs->LCCR1 = ( LCD_PPL(239) | LCD_HSW(2) |
LCD_ELW(10) | LCD_BLW(10) );
v_pLcdRegs->LCCR2 = ( LCD_LPP(319) | LCD_VSW(2) |
LCD_EFW(5) | LCD_BFW(5) );
v_pLcdRegs->LCCR3 = ( LCD_PCD(PCD) | LCD_BPP(BPP) | LCD_PCP | LCD_ACB(255) );
v_pLcdRegs->LCCR0 = ( LCD_LDM | LCD_SFM | LCD_IUM |
LCD_EFM | LCD_PAS | LCD_QDM | LCD_BM | LCD_OUM /*| LCD_BLE*/);
}
break;
case LQ10D321: //add by hzh
{
PCD = 4;
RETAILMSG(1, (TEXT("InitLCDController:LQ10D321 display type, PCD=%d\r\n"), PCD));
// Configure the TMED dithering engine
// Use the magic number described in the Cotulla EAS, 0x00AA5500;
v_pLcdRegs->TRGBR = LCD_TRS(0x00) | LCD_TGS(0x55) | LCD_TBS(0xAA);
// Use the magic number described in the Cotulla EAS, 0x0000754F;
v_pLcdRegs->TCR = LCD_TM2S | LCD_TM1S | LCD_TM2En | LCD_TM1En |
LCD_TVBS(0x04) | LCD_THBS(0x05) | LCD_TSCS(0x03) |
LCD_TED;
v_pLcdRegs->LCCR1 = ( LCD_PPL(639) | LCD_HSW(8) |
LCD_ELW(8) | LCD_BLW(24) );
v_pLcdRegs->LCCR2 = ( LCD_LPP(479) | LCD_VSW(2) |
LCD_EFW(4) | LCD_BFW(34) );
v_pLcdRegs->LCCR3 = ( LCD_PCD(PCD) | LCD_BPP(BPP) | LCD_ACB(255) );
v_pLcdRegs->LCCR0 = ( LCD_LDM | LCD_SFM | LCD_IUM |
LCD_EFM | LCD_PAS | LCD_QDM | LCD_BM | LCD_OUM /*| LCD_BLE*/);
}
break;
default:
{
RETAILMSG(0, (TEXT("No display type detected!")));
}
break;
}
}
void InitCursor()
{
gDrawCursorFlag = FALSE;
gCursorRect.left = (DispDrvr_cxScreen - CURSOR_XSIZE) >> 1;
gCursorRect.right = gCursorRect.left + CURSOR_XSIZE;
gCursorRect.top = (DispDrvr_cyScreen - CURSOR_YSIZE) >> 1;
gCursorRect.bottom = gCursorRect.top + CURSOR_YSIZE;
gxHot = gyHot = 0;
memset ((BYTE *)gCursorMask, 0xFF, sizeof(gCursorMask));
}
BOOL MapVirtualAddress()
{
v_pLcdRegs = (volatile SA2lcdregs *)VirtualAllocCopy(sizeof(SA2lcdregs),"DispDrvrInitialize : v_pLcdRegs",(PVOID)(LCD_BASE_U_VIRTUAL));
if (!v_pLcdRegs)
{
Cleanup();
return FALSE;
}
v_pClkRegs = (volatile CLKMAN_REGS *)VirtualAllocCopy(sizeof(CLKMAN_REGS),"DispDrvrInitialize : v_pClkRegs",(PVOID)(CLK_BASE_U_VIRTUAL));
if (!v_pClkRegs)
{
Cleanup();
return FALSE;
}
v_pGPIORegs = (volatile GPIO_REGS *)VirtualAllocCopy(sizeof(GPIO_REGS),"DispDrvrInitialize : v_pGPIORegs",(PVOID)(GPIO_BASE_U_VIRTUAL));
if (!v_pGPIORegs)
{
Cleanup();
return FALSE;
}
frameDescriptorCh0fd1 = (volatile LCD_FRAME_DESCRIPTOR *)VirtualAllocCopy(sizeof(LCD_FRAME_DESCRIPTOR), "DispDrvrInitialize : lcdFrameDescriptor", (PVOID)(DMA_CHANNEL_0_FRAME_DESCRIPTOR_BASE_VIRTUAL));
if (!frameDescriptorCh0fd1)
{
Cleanup();
return FALSE;
}
frameDescriptorCh0fd2 = (volatile LCD_FRAME_DESCRIPTOR *)VirtualAllocCopy(sizeof(LCD_FRAME_DESCRIPTOR), "DispDrvrInitialize : lcdFrameDescriptor", (PVOID)(DMA_CHANNEL_0_ALT_FRAME_DESCRIPTOR_BASE_VIRTUAL));
if (!frameDescriptorCh0fd2)
{
Cleanup();
return FALSE;
}
frameDescriptorCh1 = (volatile LCD_FRAME_DESCRIPTOR *)VirtualAllocCopy(sizeof(LCD_FRAME_DESCRIPTOR), "DispDrvrInitialize : lcdFrameDescriptor", (PVOID)(DMA_CHANNEL_1_FRAME_DESCRIPTOR_BASE_VIRTUAL));
if (!frameDescriptorCh1)
{
Cleanup();
return FALSE;
}
frameDescriptorPalette = (volatile LCD_FRAME_DESCRIPTOR *)VirtualAllocCopy(sizeof(LCD_FRAME_DESCRIPTOR), "DispDrvrInitialize : lcdFrameDescriptor", (PVOID)(PALETTE_FRAME_DESCRIPTOR_BASE_VIRTUAL));
if (!frameDescriptorPalette)
{
Cleanup();
return FALSE;
}
v_pPaletteBuffer=(volatile LCD_PALETTE *)VirtualAllocCopy(sizeof(LCD_PALETTE),"DispDrvrInitialize : v_pPaletteBuffer",(PVOID)PALETTE_BUFFER_BASE_VIRTUAL);
if (!v_pPaletteBuffer)
{
Cleanup();
return FALSE;
}
// For Merlin builds, we have the option of using a section mapped address or a page
// mapped address to access the frame buffer. Using a section mapped address has less
// overhead and therefore provides higher performance. We'll configure the bufferable
// attribute for either the section descriptor or the page descriptors as applicable.
#ifdef OSV_LOCAL_MERLIN
// Enter into Kernel mode to enable us to modify the section descriptor
// so that we may set the bufferable bit. This enables write coalescing
// for frame buffer writes when using the section mapped address.
//
// GAPI uses the section mapped address always. We'll configure that section
// descriptor for bufferable operating regardless of the "DISPLAY_DRIVER_USES_SECTION_DESCRIPTOR"
// environment variable.
SetKMode(TRUE);
// Now configure the frame buffer's section descriptor.
// The function GetDescriptorAddress shows how to obtain the correct descriptor address.
// It currently returns a descriptor address of 0xfffd28f4 for the current memory map.
// This descriptor is one of two descriptors that map the the frame buffer.
// The first descriptor found maps the cached virtual address, while the second
// descriptor found maps the uncached virtual address. We want to modify the
// second descriptor, that which maps the uncached virtual address since the uncached virtual
// address is the address we've chosen to use throughout the codebase.
//
// NOTE:
// There's no need to run this dynamically each boot, so it's been left only as an example
// of how to obtain the descriptor address. It could be called as shown below to determine
// the descriptor address dynamically.
// ConfigureFrameBufferSectionDescriptor(GetDescriptorAddress(DMA_CHANNEL_0_FRAME_DESCRIPTOR_BASE_PHYSICAL));
//
// NOTE:
// The section descriptor covers a 1MB section. If the frame buffer ever exceeds 1MB
// in size, you'll need to modify additional section descriptors.
//
ConfigureFrameBufferSectionDescriptor(0xfffd28f4); // Using the descriptor that maps the uncached, virtual address.
#ifdef DISPLAY_DRIVER_USES_SECTION_DESCRIPTOR
// The GDI will use the section mapped address for the frame buffer.
// The bufferable attribute is configured above in the call to ConfigureFrameBufferSectionDescriptor().
gFrameBuffer = (PBYTE)(FRAME_BUFFER_0_BASE_VIRTUAL);
#else // using a page mapped frame buffer for GDI
// The GDI will use a page mapped address for the frame buffer.
// The frame buffer is specifically page mapped via VirtualAllocCopy.
// The bufferable attribute is configured via VirtualSetAttributes.
gFrameBuffer = (PBYTE)VirtualAllocCopy(frameBufferSize*NUM_FRAME_BUFFERS,"gFrameBuffer",(PVOID)(FRAME_BUFFER_0_BASE_VIRTUAL));
if (!gFrameBuffer)
{
Cleanup();
return FALSE;
}
// Set the bufferable bit attribute to the frame buffer to enable write coalescing
// This setting achieves highest performance when drawing to the frame buffer.
VirtualSetAttributes(gFrameBuffer, frameBufferSize*NUM_FRAME_BUFFERS, 4, 4, NULL);
#endif
#else // Not a MERLIN system, so we'll page map the address and won't be setting the bufferable attribute.
// If your version of WinCE.NET supports VirtualSetAttributes(), apply the bufferable setting as above.
// gFrameBuffer = (PBYTE)VirtualAllocCopy(frameBufferSize*NUM_FRAME_BUFFERS,"gFrameBuffer",(PVOID)(FRAME_BUFFER_0_BASE_VIRTUAL));
{
PVOID pVirtAddr;
unsigned offset, size;
pVirtAddr = (PVOID)(FRAME_BUFFER_0_BASE_VIRTUAL);
size = frameBufferSize*NUM_FRAME_BUFFERS;
offset = (unsigned)pVirtAddr & (0x1000 - 1);
size += (offset ? 0x1000 : 0);
pVirtAddr = (PVOID)((unsigned)pVirtAddr - offset);
if (size >= 1024*1024*2)
{
gFrameBuffer = (PBYTE)VirtualAlloc(NULL,size,MEM_RESERVE,PAGE_NOACCESS);
}
else
{
gFrameBuffer = (PBYTE)VirtualAlloc(NULL,1024*1024*2,MEM_RESERVE,PAGE_NOACCESS);
}
if (!VirtualCopy(gFrameBuffer,pVirtAddr,size,PAGE_READWRITE|PAGE_NOCACHE))
{
gFrameBuffer = NULL;
}
else
{
gFrameBuffer += offset;
}
}
if (!gFrameBuffer)
{
Cleanup();
return FALSE;
}
// Set the bufferable bit attribute to the frame buffer to enable write coalescing
// This setting achieves highest performance when drawing to the frame buffer.
VirtualSetAttributes(gFrameBuffer, frameBufferSize*NUM_FRAME_BUFFERS, 4, 4, NULL);
#endif
gBlankFrameBuffer = (PBYTE) VirtualAlloc(0, frameBufferSize, MEM_RESERVE | MEM_COMMIT,PAGE_READWRITE);
if (!gBlankFrameBuffer)
{
Cleanup();
return FALSE;
}
#ifdef PLAT_LUBBOCK
v_pBoardLevelRegister=(volatile BLR_REGS *)VirtualAllocCopy(sizeof(BLR_REGS),"DispDrvrInitialize : v_pPaletteBuffer",(PVOID)FPGA_REGS_BASE_U_VIRTUAL);
if (!v_pBoardLevelRegister)
{
Cleanup();
return FALSE;
}
#endif
#ifdef PLAT_SANDGATE
v_pPWMRegs=(volatile PWM_REGS *)VirtualAllocCopy(sizeof(PWM_REGS),"DispDrvrInitialize : v_pPaletteBuffer",(PVOID)PWM0_BASE_U_VIRTUAL);
if (!v_pPWMRegs)
{
Cleanup();
return FALSE;
}
#endif
return TRUE;
}
// Free all the global memory resources
void Cleanup(void)
{
if (v_pLcdRegs)
{
VirtualFree((PVOID)v_pLcdRegs,0,MEM_RELEASE);
v_pLcdRegs = NULL;
}
if (v_pClkRegs)
{
VirtualFree((PVOID)v_pClkRegs,0,MEM_RELEASE);
v_pLcdRegs = NULL;
}
if (v_pGPIORegs)
{
VirtualFree((PVOID)v_pGPIORegs,0,MEM_RELEASE);
v_pGPIORegs = NULL;
}
if (frameDescriptorCh0fd1)
{
VirtualFree((PVOID)frameDescriptorCh0fd1,0,MEM_RELEASE);
frameDescriptorCh0fd1 = NULL;
}
if (frameDescriptorCh0fd2)
{
VirtualFree((PVOID)frameDescriptorCh0fd2,0,MEM_RELEASE);
frameDescriptorCh0fd2 = NULL;
}
if (frameDescriptorCh1)
{
VirtualFree((PVOID)frameDescriptorCh1,0,MEM_RELEASE);
frameDescriptorCh1 = NULL;
}
if (frameDescriptorPalette)
{
VirtualFree((PVOID)frameDescriptorPalette,0,MEM_RELEASE);
frameDescriptorPalette = NULL;
}
if (v_pPaletteBuffer)
{
VirtualFree((PVOID)v_pPaletteBuffer,0,MEM_RELEASE);
v_pPaletteBuffer = NULL;
}
// If using the section descriptor, there's no memory to free, so don't do the VirtualFree.
if ((gFrameBuffer) && (gFrameBuffer != (PBYTE)FRAME_BUFFER_0_BASE_VIRTUAL))
{
VirtualFree((PVOID)gFrameBuffer,0,MEM_RELEASE);
gFrameBuffer = NULL;
}
#ifdef PLAT_LUBBOCK
if (v_pBoardLevelRegister)
{
VirtualFree((PVOID)v_pBoardLevelRegister,0,MEM_RELEASE);
v_pBoardLevelRegister = NULL;
}
#endif
#ifdef PLAT_SANDGATE
if (v_pPWMRegs)
{
VirtualFree((PVOID)v_pPWMRegs,0,MEM_RELEASE);
v_pPWMRegs = NULL;
}
#endif
}
void DispDrvrPowerHandler(BOOL bOff)
{
if(bOff)
{
DisableLCDController();
}
else
{
// Copy the original frame buffer back in.
CopyFrameBuffer(FALSE);
// Initialize the GPIO registers for proper LCD Controller operation
LcdSetupGPIOs();
// Initialize the LCD Controller and Board Control Register
InitLCDController();
// Clear LCD Controller status register
LCDClearStatusReg();
// Enable the LCD controller
EnableLCDController();
}
}
void CopyFrameBuffer(BOOL gDirection)
{
DWORD i;
unsigned *cfbp;
unsigned *fbp;
cfbp=(unsigned *)gBlankFrameBuffer;
fbp=(unsigned *)gFrameBuffer+(activeFrameBuffer*frameBufferSize);
for(i=0;i<(DispDrvr_cxScreen*DispDrvr_cyScreen*(bpp/8)/4);i++)
{
if (gDirection)
*cfbp++ = *fbp++;
else
*fbp++ = *cfbp++;
}
}
void ClearFrameBuffer(BOOL color)
{
DWORD i;
unsigned *fbp;
fbp=(unsigned *)gFrameBuffer+(activeFrameBuffer*frameBufferSize);
for(i=0;i<(DispDrvr_cxScreen*DispDrvr_cyScreen*(bpp/8)/4);i++)
{
if (color)
*fbp++ = 0xFFFFFFFF; // Ones turn it white
else
*fbp++ = 0x000000000; // Zeros turn it black
}
}
//**********************************************************************
//
//DispDrvrContrastControl:
//
// Modify the contrast according to the Cmd parameter.
// Not supported
//
BOOL DispDrvrContrastControl(int Cmd,DWORD *pValue)
{
// currently does not support changing contrast in software.
return TRUE;
}
void DirtyRectDumpPortraitLoop_C(BYTE *pDstBuf, BYTE *pSrcBuf, DWORD yTop, DWORD yBottom,
DWORD srcWidthB, DWORD bytesPerRow, DWORD bytesPerPixel,
DWORD srcMarginWidth, DWORD dstMarginWidth)
{
DWORD row,i,j;
if ( bytesPerPixel != 2 ) {
//not 16-bit
for (i=0;i<srcWidthB/bytesPerPixel;i++) {
for (row=yTop;row < yBottom;row++) {
for (j=0;j<bytesPerPixel;j++) {
*pDstBuf++=*(pSrcBuf+j);
}
pSrcBuf-=bytesPerRow;
}
pDstBuf+=dstMarginWidth;
pSrcBuf+=srcMarginWidth+2;
}
}else {
WORD *pwDst, *pwSrc;
int rowLen;
//16-bit
srcWidthB >>= 1;
pwDst = (WORD *)pDstBuf;
pwSrc = (WORD *)pSrcBuf;
//first row for pwSrc, then column for pwDst
rowLen = yBottom - yTop;
#ifndef _OPT_ASM
bytesPerRow >>=1;
dstMarginWidth >>=1;
srcMarginWidth >>=1;
for (i=0;i<srcWidthB;i++) {
for (row=0;row < (rowLen >>2);row++) {
*pwDst ++ = *pwSrc;
pwSrc-=bytesPerRow;
*pwDst ++ = *pwSrc;
pwSrc-=bytesPerRow;
*pwDst ++ = *pwSrc;
pwSrc-=bytesPerRow;
*pwDst ++ = *pwSrc;
pwSrc-=bytesPerRow;
}
for (row=0;row < (rowLen & 0x3);row++) {
*pwDst ++ = *pwSrc;
pwSrc-=bytesPerRow;
}
pwDst +=dstMarginWidth;
pwSrc +=srcMarginWidth+1;
}
#else
dirtyRectDump_core_ASM(pwSrc, pwDst, rowLen, srcWidthB, bytesPerRow, srcMarginWidth, dstMarginWidth);
#endif
}
}
void DispDrvrDirtyRectDump(LPCRECT prc)
{
BYTE *pDstBuf,*pSrcBuf,*pSrcMask;
DWORD xLeft,yTop,xRight,yBottom;
DWORD bytesPerRow,bytesPerPixel,srcBytesPerRow;
DWORD row,i,j;
DWORD srcWidthB,srcMarginWidth,clipWidthB,dstMarginWidth,cursorWidthB;
DWORD srcStartRow,dstStartRow;
if (bAllowOSFrameBufferUpdates)
{
bytesPerPixel=bpp/8;
xLeft = prc->left < 0 ? 0 : prc->left;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -