📄 ddlcdc.cpp
字号:
if(m_pMode->modeId == DISPLAY_MODE_SHPQVGA) // SHARP
{
m_bTVModeActive = FALSE;
m_nPanelTYPE = 0;
}
if(m_pMode->modeId == DISPLAY_MODE_NECVGA) // NEC
{
m_bTVModeActive = FALSE;
m_nPanelTYPE = 1;
}
if(m_pMode->modeId == DISPLAY_MODE_PAL)
{
m_bTVModeActive = TRUE;
m_bTVNTSCOut = FALSE; //PAL
}
if(m_pMode->modeId == DISPLAY_MODE_NTSC)
{
m_bTVModeActive = TRUE;
m_bTVNTSCOut = TRUE; //NTSC
}
if(!bModeGot)
{
// No suitable display mode found, default display mode is used
DEBUGMSG(GPE_ZONE_INIT, (TEXT("MX27DDLcdc Init: Default display mode is used!\r\n")));
m_nScreenWidth = m_pMode->width;
m_nScreenHeight = m_pMode->height;
m_nScreenBpp = m_pMode->Bpp;
}
// Setup surface alignment as required by the LCDC of i.MX27 for 4 bytes
m_nSurfacePixelAlign = 4 / (m_pMode->Bpp / 8);
// Sanity Check for screen width
if(m_pMode->width & (m_nSurfacePixelAlign - 1))
{
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdc Init: Screen width (%d) is not aligned for %d bytes!\r\n"), m_pMode->width, m_nSurfacePixelAlign));
result = FALSE;
goto _done;
}
// The line stride of i.MX27 LCDC is 32-bits (4 bytes) aligned
m_nScreenStride = ((m_nScreenWidth * (m_nScreenBpp / 8) + 3) >> 2) << 2;
DEBUGMSG(GPE_ZONE_INIT, (TEXT("MX27DDLcdc Init: Current display mode:\r\n")));
DEBUGMSG(GPE_ZONE_INIT, (TEXT("\t\tm_nScreenWidth: %d\r\n"), m_nScreenWidth));
DEBUGMSG(GPE_ZONE_INIT, (TEXT("\t\tm_nScreenHeight: %d\r\n"), m_nScreenHeight));
DEBUGMSG(GPE_ZONE_INIT, (TEXT("\t\tm_nScreenStride: %d\r\n"), m_nScreenStride));
DEBUGMSG(GPE_ZONE_INIT, (TEXT("\t\tm_nScreenBpp: %d\r\n"), m_nScreenBpp));
// Setup other DDGPE mode informations
nBPP = m_pMode->Bpp/8 - 1;
switch (m_pMode->Bpp)
{
case 8:
case 16:
case 24:
case 32:
m_pModeEx->ePixelFormat = ePixelFormat[nBPP];
m_pModeEx->lPitch = m_nScreenStride;
m_pModeEx->dwRBitMask = BitMasks[nBPP][0];
m_pModeEx->dwGBitMask = BitMasks[nBPP][1];
m_pModeEx->dwBBitMask = BitMasks[nBPP][2];
break;
default:
DEBUGMSG(GPE_ZONE_ERROR,(TEXT("MX27DDLcdc Init: Invalid BPP value passed to driver - Bpp = %d\r\n"), m_pMode->Bpp));
m_pMode->format = gpeUndefined;
result = FALSE;
goto _done;
}
// Setup Rotation
m_nScreenHeightSave = m_pMode->height;
m_nScreenWidthSave = m_pMode->width;
m_iRotate = GetRotateModeFromReg();
SetRotateParams();
m_nScreenWidth = m_pMode->width;
m_nScreenHeight = m_pMode->height;
// Pre-initialize the graphic window operator for overlay
m_pOverlaySurfaceOp = (pOverlaySurf_t)malloc(sizeof(overlaySurf_t));
if(m_pOverlaySurfaceOp)
{
memset(m_pOverlaySurfaceOp, 0x00, sizeof(overlaySurf_t));
}
else
{
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdc Init: failed to allocate memory for graphic windower operator, error(%d)\r\n"), GetLastError()));
result = FALSE;
goto _done;
}
_done:
DEBUGMSG(GPE_ZONE_INIT, (TEXT("MX27DDLcdc Init %s.\r\n"), result ? L"succeeds" : L"fails"));
return result;
}
//------------------------------------------------------------------------------
//
// Function: InitHardware
//
// Initialize the hardware resources for the driver.
//
// Parameters:
// None.
//
// Returns:
// TRUE successful
// FALSE failed
//
//------------------------------------------------------------------------------
BOOL MX27DDLcdc::InitHardware(VOID)
{
BOOL result = TRUE;
PHYSICAL_ADDRESS phyAddr;
//Mem maps the LCDC module space for user access
phyAddr.QuadPart = CSP_BASE_REG_PA_LCDC;
m_pLcdcReg = (CSP_LCDC_REGS *)MmMapIoSpace(phyAddr, sizeof(CSP_LCDC_REGS), FALSE);
if (m_pLcdcReg == NULL)
{
DEBUGMSG (GPE_ZONE_ERROR, (TEXT("LcdcClass: VirtualAlloc failed!\r\n")) );
result = FALSE;
goto _done;
}
// Initialze LCDC interrupt
m_hSyncEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if(NULL == m_hSyncEvent)
{
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdc InitHardware: fail to create the intr event, error[%d]!\r\n"), GetLastError()));
result = FALSE;
goto _done;
}
DWORD irq = IRQ_LCDC;
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &irq, sizeof(DWORD),
&g_dwlcdcSysintr, sizeof(DWORD), NULL)){
DEBUGMSG(GPE_ZONE_ERROR, (_T("Failed to obtain sysintr value!\r\n")));
return 0;
}
if(!InterruptInitialize(g_dwlcdcSysintr, m_hSyncEvent, NULL, NULL))
{
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdc InitHardware: fail to initialize the interrupt, error[%d]!\r\n"), GetLastError()));
result = FALSE;
goto _done;
}
m_hSyncThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MX27DDLcdcIntr, this, 0, NULL);
if(NULL == m_hSyncThread)
{
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdc InitHardware: fail to initiate the interrupt thread, error[%d]!\r\n"), GetLastError()));
result = FALSE;
goto _done;
}
// Initialze a critical section to protect interrupt status flag update violation
InitializeCriticalSection(&m_CriticalSection);
// Configure LCDC of i.MX27 processor
if(!SetModeHardware(m_pMode->modeId))
{
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdc InitHardware: fail to initialize hardware!\r\n"), GetLastError()));
result = FALSE;
goto _done;
}
_done:
return result;
}
//------------------------------------------------------------------------------
//
// Function: SetupVideoMemory
//
// Setup the video memory buffer and other related buffers.
//
// Parameters:
// None.
//
// Returns:
// TRUE successful
// FALSE failed
//
//------------------------------------------------------------------------------
BOOL MX27DDLcdc::SetupVideoMemory(VOID)
{
SCODE sc;
PHYSICAL_ADDRESS phyAddr;
BOOL result = TRUE;
DWORD iFrameSize = m_nScreenStride * m_nScreenHeightSave;
// Allocate video memory
/*
* IMPORTANT: There is dedicated video memory for i.MX27
* processor, therefore, we should not share from
* system memory.
*/
// The video memory should be more than three frame size:
// - one for primary surface // primary
// - one for a blank surface used when OS goes to power suspension // blank
// - one for general use in DirectDraw applications
//iFrameSize = m_LcdcCtx.VideoFrameWidth * m_LcdcCtx.VideoFrameHight * BSPGetPixelSizeInByte();
m_nVideoMemorySize = m_LcdcCtx.VideoMemorySize;
// m_nVideoMemorySize = max3(m_nVideoMemorySize, 3*iFrameSize, DEFAULT_VIDEO_MEM_SIZE);
phyAddr.QuadPart = m_LcdcCtx.VideoMemoryPhyAdd;
m_pVideoMemory = (UINT8 *)MmMapIoSpace(phyAddr, m_nVideoMemorySize, FALSE);
if (m_pVideoMemory == NULL)
{
DEBUGMSG (GPE_ZONE_ERROR, (TEXT("Frame Buffer MmMapIoSpace failed!\r\n")) );
result = FALSE;
goto _done;
}
m_nLAWPhysical = m_LcdcCtx.VideoMemoryPhyAdd;
//Allocate Frame Buffer Space in shared memory
m_hLAWMapping = CreateFileMapping(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
m_nVideoMemorySize,
NULL);
if (m_hLAWMapping != NULL)
{
m_pLAW = (unsigned char *)MapViewOfFile(
m_hLAWMapping,
FILE_MAP_WRITE,
0,
0,
0);
}
else
{
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdc SetupVideoMemory: failed at MapViewOfFile(), error[%d]\r\n"), m_nVideoMemorySize, GetLastError()));
result = FALSE;
goto _done;
}
result = VirtualCopy(
m_pLAW,
(LPVOID)(m_nLAWPhysical >> 8),
m_nVideoMemorySize,
PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL);
if(!result)
{
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdc SetupVideoMemory: failed at VirtualCopy(), error[%d]\r\n"), m_nVideoMemorySize, GetLastError()));
result = FALSE;
goto _done;
}
// Create video memory heap
if (!m_pVideoMemoryHeap)
m_pVideoMemoryHeap = new SurfaceHeap(m_nVideoMemorySize, NULL, NULL, NULL);
// Create primary surface and blank surface
if (!m_pPrimarySurface)
{
if (FAILED(sc = AllocSurface((DDGPESurf **) &m_pPrimarySurface, m_nScreenWidthSave,
m_nScreenHeightSave, m_pMode->format, m_pModeEx->ePixelFormat,
GPE_REQUIRE_VIDEO_MEMORY)))
{
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdc SetMode: Couldn't allocate primary surface\r\n")));
result = FALSE;
goto _done;
}
}
// Load freescale logo onto screen in case that the primary surface is not at the starting point of video memory.
if(m_pPrimarySurface->OffsetInVideoMemory())
{
WaitForNotBusy();
//LoadFreescaleLogo(m_pPrimarySurface);
}
m_pPrimarySurface->SetRotation(m_nScreenWidth, m_nScreenHeight, m_iRotate);
_done:
if(result)
{
DEBUGMSG(GPE_ZONE_INIT, (TEXT("MX27DDLcdc SetupVideoMemory: \r\n")));
DEBUGMSG(GPE_ZONE_INIT, (TEXT("\tVirtual address mapped access window: 0x%08x\r\n"), m_pLAW));
DEBUGMSG(GPE_ZONE_INIT, (TEXT("\tVirtual address of video memory: 0x%08x\r\n"), m_pVideoMemory));
DEBUGMSG(GPE_ZONE_INIT, (TEXT("\tPhysical address of video memory: 0x%08x\r\n"), m_LcdcCtx.VideoMemoryPhyAdd));
DEBUGMSG(GPE_ZONE_INIT, (TEXT("\tSize: 0x%08x\r\n"), m_nVideoMemorySize));
}
return result;
}
//------------------------------------------------------------------------------
//
// FUNCTION: SetModeHardware
//
// DESCRIPTION: Setup hardware LCDC for current display mode
//
// PARAMETERS:
//
// RETURNS:
// TRUE: successful
// FALSE: failed
//
//------------------------------------------------------------------------------
BOOL MX27DDLcdc::SetModeHardware(int modeNo)
{
BOOL result = FALSE;
if(!InitializeLCDC(m_bTVModeActive, m_bTVNTSCOut, m_nPanelTYPE))
{
DEBUGMSG(1, (TEXT("InitializeLCDC Failed")));
goto _done;
}
// Pre-setup framebuffer address
// Load Freescale logo at the starting point of the video memory
//LoadFreescaleLogo(m_pLAW);
result = TRUE;
_done:
return result;
}
//------------------------------------------------------------------------------
//
// Function: Cleanup
//
// Release all resouces for either failed initialization
// or driver unloading.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
VOID MX27DDLcdc::Cleanup(VOID)
{
DDK_GPIO_CFG cfg;
m_nMask = 0; // for flicker
BSPTurnOffLCD();
BSPDeinitLCDC(&m_LcdcCtx);
// Release LCDC register map
if(m_pLcdcReg)
{
// disable LCDC
INSREG32BF(&m_pLcdcReg->RMCR, LCDC_RMCR_SELF_REF, LCDC_RMCR_SELF_REF_DISABLE);
MmUnmapIoSpace(m_pLcdcReg, sizeof(CSP_LCDC_REGS));
m_pLcdcReg = NULL;
}
// Disable LCDC module pins
DDK_GPIO_SET_CONFIG(cfg, LCDC);
DDKGpioDisable(&cfg);
// Disable LCDC hw clocks
DDKClockSetGatingMode(DDK_CLOCK_GATE_INDEX_LCDC, DDK_CLOCK_GATE_MODE_DISABLE);
// Destroy surface objects
if(m_pPrimarySurface)
{
delete m_pPrimarySurface;
m_pPrimarySurface = NULL;
}
if(m_pBlankSurface)
{
delete m_pBlankSurface;
m_pBlankSurface = NULL;
}
// Release the shared vidoe memory
if (m_pLAW)
{
UnmapViewOfFile(m_pLAW);
m_pLAW = NULL;
}
if (m_hLAWMapping)
{
CloseHandle(m_hLAWMapping);
m_hLAWMapping = NULL;
}
//Not need release memory because of reserved physical memory
/*
// Release video memory
if(m_pVideoMemory)
{
FreePhysMem(m_pVideoMemory);
m_pVideoMemory = NULL;
}
*/
// Release the overlay operator
if(m_pOverlaySurfaceOp)
{
free(m_pOverlaySurfaceOp);
m_pOverlaySurfaceOp = NULL;
}
// Disable interrupt source and release interrupt event
InterruptDisable(g_dwlcdcSysintr);
// Release SYSINTR
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &g_dwlcdcSysintr, sizeof(DWORD), NULL, 0, NULL);
g_dwlcdcSysintr = SYSINTR_UNDEFINED;
if(m_hSyncEvent)
{
CloseHandle(m_hSyncEvent);
m_hSyncEvent= NULL;
}
// Terminate interrupt thread
if(m_hSyncThread)
{
TerminateThread(m_hSyncThread, 0);
CloseHandle(m_hSyncThread);
m_hSyncThread = NULL;
}
DeleteCriticalSection(&m_CriticalSection);
}
//------------------------------------------------------------------------------
//
// FUNCTION: IntrProc
//
// DESCRIPTION: This function is interrupt handler.
//
// NOTE:
//
// PARAMETERS:
//
// RETURNS:
// A double word value for ExitThread()
//
//------------------------------------------------------------------------------
DWORD MX27DDLcdc::IntrProc(VOID)
{
while(TRUE)
{
if (WaitForSingleObject(m_hSyncEvent, INFINITE) != WAIT_OBJECT_0)
{
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdc IntrProc: interrupt error [%d]\r\n"), GetLastError()));
continue;
}
EnterCriticalSection(&m_CriticalSection);
m_nPreIntrStatus = m_pLcdcReg->ISR;
LeaveCriticalSection(&m_CriticalSection);
InterruptDone(g_dwlcdcSysintr);
}
return 0;
}
//------------------------------------------------------------------------------
//
// FUNCTION: MX27DDLcdcIntr
//
// DESCRIPTION: This function is entry point of the interrupt thread.
//
// NOTE:
//
// PARAMETERS:
//
// RETURNS:
// A double word value for ExitThread()
//
//------------------------------------------------------------------------------
DWORD MX27DDLcdcIntr(MX27DDLcdc * pClass)
{
pClass->IntrProc();
// We shouldn't come to here
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdcIntr: Exiting interrupt thread... error[%d]\r\n"), GetLastError()));
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -