📄 ddipu_sdc.cpp
字号:
}
queueOptions.bReadAccess = FALSE; // we need write-access to msgqueue
// Create write handles for queues
m_hWritePPOverlayQueue = OpenMsgQueue(GetCurrentProcess(), m_hReadPPOverlayQueue, &queueOptions);
if (!m_hWritePPOverlayQueue)
{
DEBUGMSG(GPE_ZONE_ERROR,
(TEXT("%s: Error opening PP overlay queue for writing. Initialization failed! \r\n"), __WFUNCTION__));
}
// Variable used to determine how frequently to update UI for TV
m_iLastOverlayUpdateTime = 0;
if (m_bTVSupported)
{
// Initialize event to synchronize TV update with SDC BG EOF
m_hSDCBGEOFEvent = CreateEvent(NULL, FALSE, FALSE, IPU_SDC_BG_INTR_EVENT);
if (m_hSDCBGEOFEvent == NULL)
{
DEBUGMSG(GPE_ZONE_ERROR,
(TEXT("%s: CreateEvent failed for SDC BG Interrupt\r\n"), __WFUNCTION__));
result = FALSE;
goto _done;
}
// Initialize event to signal request to update the TV buffer
m_hTVUpdateRequest = CreateEvent(NULL, FALSE, FALSE, NULL);
if (m_hTVUpdateRequest == NULL)
{
DEBUGMSG(GPE_ZONE_ERROR,
(TEXT("%s: CreateEvent failed for TV update event\r\n"), __WFUNCTION__));
result = FALSE;
goto _done;
}
// Initialize Dirty Rectangle object
m_pDirtyRect = new DirtyRect(320, 240, 320, 40);
m_iNumDirtyRegions = 320/320 * 240/40;
// Start TV out thread
// Initialize thread for TV out updating
// pThreadAttributes = NULL (must be NULL)
// dwStackSize = 0 => default stack size determined by linker
// lpStartAddress = CspiProcessQueue => thread entry point
// lpParameter = NULL => point to thread parameter
// dwCreationFlags = 0 => no flags
// lpThreadId = NULL => thread ID is not returned
m_hTVUpdateThread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TVUpdateThread, this, 0, NULL);
if (m_hTVUpdateThread == NULL)
{
DEBUGMSG(GPE_ZONE_ERROR,(TEXT("%s: CreateThread failed!\r\n"), __WFUNCTION__));
result = FALSE;
goto _done;
}
else
{
DEBUGMSG(GPE_ZONE_INIT, (TEXT("%s: create TV update thread success\r\n"), __WFUNCTION__));
CeSetThreadPriority(m_hTVUpdateThread, 100);//THREAD_PRIORITY_TIME_CRITICAL);
}
}
_done:
DEBUGMSG(GPE_ZONE_INIT, (TEXT("IPU_SDC 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 DDIPU_SDC::InitHardware(VOID)
{
BOOL result = TRUE;
PHYSICAL_ADDRESS physAddr;
DEBUGMSG(GPE_ZONE_INIT, (TEXT("+%s()\r\n"), __WFUNCTION__));
BSPInitializeLCD();
// Initialize IPU SDC.
if (InitializeSDC(m_CurrentPanel, m_nScreenBpp) != TRUE)
{
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("Failed to initialise IPU SDC")));
result = FALSE;
goto _done;
}
physAddr.QuadPart = m_nLAWPhysical;
// Set buffer for SDC
BackgroundSetSrcBuffer(&physAddr);
if (m_bTVModeActive)
{
// Initialize and turn on TV Out
if (!BSPInitializeTVOut(m_bTVNTSCOut))
{
DEBUGMSG(1, (TEXT("Failed to initialize TV out")));
//result = FALSE;
//goto _done;
}
// Turn off LCD if TV Out is active
BSPDisableLCD();
}
else
{
// Enable LCD
BSPEnableLCD();
// Disable TV Out if LCD active
if (!BSPDeinitializeTVOut())
{
DEBUGMSG(1, (TEXT("Failed to initialize TV out")));
//result = FALSE;
//goto _done;
}
}
// Enable SDC, start normal operation.
EnableSDC();
DEBUGMSG(GPE_ZONE_INIT, (TEXT("-%s()\r\n"), __WFUNCTION__));
_done:
return result;
}
//------------------------------------------------------------------------------
//
// Function: SetupVideoMemory
//
// Setup the video memory buffer and other related buffers.
//
// Parameters:
// None.
//
// Returns:
// TRUE successful
// FALSE failed
//
//------------------------------------------------------------------------------
BOOL DDIPU_SDC::SetupVideoMemory(VOID)
{
SCODE sc;
BOOL result = TRUE;
int maxOverlayWidth, maxOverlayHeight;
// Allocate video memory
/*
* IMPORTANT: There is no dedicated video memory for i.MX31
* processor, therefore, we have to share from
* system memory.
*/
GetVMemSizeFromRegistry();
// Allocate contiguous physical memory to set Linear
// Address Window Physical Address
m_pVideoMemory = AllocPhysMem(m_nVideoMemorySize, PAGE_EXECUTE_READWRITE, 0, 0, (ULONG *) &m_nLAWPhysical);
// Check if virtual mapping failed
if (!m_pVideoMemory)
{
DEBUGMSG(GPE_ZONE_ERROR,
(TEXT("%s(): MmMapIoSpace failed!\r\n"), __WFUNCTION__));
result = FALSE;
goto _done;
}
// 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("IPU_SDC 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);
// Update the Framebuffer to be cached, write-through
VirtualSetAttributes(m_pLAW, m_nVideoMemorySize, 0x8, 0xC, NULL);
// Clear the virtual memory
memset((PUCHAR)m_pLAW, 0, m_nVideoMemorySize);
// Create video memory heap
if (!m_pVideoMemoryHeap)
m_pVideoMemoryHeap = new SurfaceHeap(m_nVideoMemorySize, NULL, NULL, NULL);
// We need to reallocate surfaces in case the dimensions have changed
// with the new mode
if (m_pPrimarySurface)
{
delete m_pPrimarySurface;
}
// Create primary surface
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("IPU_SDC SetMode: Couldn't allocate primary surface\r\n")));
return sc;
}
maxOverlayWidth = m_bTVSupported ? SCREEN_PIX_WIDTH_VGA : m_nScreenWidthSave;
maxOverlayHeight = m_bTVSupported ? SCREEN_PIX_HEIGHT_VGA : m_nScreenHeightSave;
if (m_pPpOverlaySurface1)
{
delete m_pPpOverlaySurface1;
}
// Create Post-processing surface
// Create the largest possible PP surface. I.e., screen width,
// screen height, 32-bit format
if (!m_pPpOverlaySurface1)
{
if (FAILED(sc = AllocSurface((DDGPESurf **) &m_pPpOverlaySurface1, maxOverlayWidth,
maxOverlayHeight, m_pMode->format, m_pModeEx->ePixelFormat,
GPE_REQUIRE_VIDEO_MEMORY)))
{
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("%s: Can't allocate Post-processor surface 1. Use default blt.\r\n"), __WFUNCTION__));
return S_FALSE;
}
}
if (m_pPpOverlaySurface2)
{
delete m_pPpOverlaySurface2;
}
// Create Post-processing surface
// Create the largest possible PP surface. I.e., screen width,
// screen height, 32-bit format
if (!m_pPpOverlaySurface2)
{
if (FAILED(sc = AllocSurface((DDGPESurf **) &m_pPpOverlaySurface2, maxOverlayWidth,
maxOverlayHeight, m_pMode->format, m_pModeEx->ePixelFormat,
GPE_REQUIRE_VIDEO_MEMORY)))
{
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("%s: Can't allocate Post-processor surface 2. Use default blt.\r\n"), __WFUNCTION__));
return S_FALSE;
}
}
// If TV mode is supported, we must allocate 2 buffers to receive
// upsized VGA data.
if (m_bTVSupported)
{
if (FAILED(sc = AllocSurface((DDGPESurf **) &m_pTVBuffer1, 640,
480, gpe16Bpp, ddgpePixelFormat_565, GPE_REQUIRE_VIDEO_MEMORY)))
{
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("%s: Can't allocate TV Buffer 1.\r\n"), __WFUNCTION__));
return S_FALSE;
}
}
// 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(DisplayPlane_0);
LoadFreescaleLogo(m_pPrimarySurface);
}
if(!result)
{
DEBUGMSG(GPE_ZONE_ERROR, (TEXT("IPU_SDC SetupVideoMemory: failed at VirtualCopy(), error[%d]\r\n"), m_nVideoMemorySize, GetLastError()));
result = FALSE;
goto _done;
}
_done:
if(result)
{
DEBUGMSG(GPE_ZONE_INIT, (TEXT("IPU_SDC SetupVideoMemory: \r\n")));
DEBUGMSG(GPE_ZONE_INIT, (TEXT("\t\tVirtual address: 0x%08x\r\n"), m_pLAW));
DEBUGMSG(GPE_ZONE_INIT, (TEXT("\t\tPhysical address: 0x%08x\r\n"), m_nLAWPhysical));
DEBUGMSG(GPE_ZONE_INIT, (TEXT("\t\tSize: 0x%08x\r\n"), m_nVideoMemorySize));
}
return result;
}
//------------------------------------------------------------------------------
//
// Function: Cleanup
//
// Release all resouces for either failed initialization
// or driver unloading.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
VOID DDIPU_SDC::Cleanup(VOID)
{
#ifdef PLAT_PMC
// Deinitialize display power management
DISPLDeinitPM();
#endif
// De-initialize TV out
if (!BSPDeinitializeTVOut())
{
DEBUGMSG(1, (TEXT("Failed to de-initialize TV out")));
}
// Disable SDC and turn off LCD
DisableSDC();
BSPDisableLCD();
// Stop Post-processing driver and close handle
PPStop(m_hPP);
PPCloseHandle(m_hPP);
// Close handle to PP EOF event
CloseHandle(m_hPPEOFEvent);
m_hPPEOFEvent = NULL;
DeleteCriticalSection(&m_csPPLock);
// Destroy surface objects
if(m_pPrimarySurface)
delete m_pPrimarySurface;
if(m_pPpOverlaySurface1)
delete m_pPpOverlaySurface1;
if(m_pPpOverlaySurface2)
delete m_pPpOverlaySurface2;
// Release the shared vidoe memory
if (m_pLAW)
UnmapViewOfFile(m_pLAW);
if (m_hLAWMapping)
CloseHandle(m_hLAWMapping);
// Release video memory
if(m_pVideoMemory)
{
FreePhysMem(m_pVideoMemory);
m_pVideoMemory = NULL;
m_nLAWPhysical = 0;
}
// Release the overlay operator
if(m_pOverlaySurfaceOp)
{
free(m_pOverlaySurfaceOp);
m_pOverlaySurfaceOp = NULL;
}
// Release Panel structure Here.
if(m_CurrentPanel)
{
VirtualFree(m_CurrentPanel,0,MEM_RELEASE); // deallocate the memory here.
m_CurrentPanel = NULL;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -