📄 pdp.c
字号:
/*!****************************************************************************
@File pdp.c
@Title PDP Device specific routines
@Author Dave Bartlett
@date 18 / 9 / 03
@Copyright Copyright 2003-2004 by Imagination Technologies Limited.
All rights reserved. No part of this software, either
material or conceptual may be copied or distributed,
transmitted, transcribed, stored in a retrieval system
or translated into any human or computer language in any
form by any means, electronic, mechanical, manual or
other-wise, or disclosed to third parties without the
express written permission of Imagination Technologies
Limited, Unit 8, HomePark Industrial Estate,
King's Langley, Hertfordshire, WD4 8LZ, U.K.
@Platform generic
@Description Device specific functions
@DoxygenVer
******************************************************************************/
/******************************************************************************
Modifications :-
$Log: pdp.c $
*****************************************************************************/
#include "services_headers.h"
#include "hostfunc.h"
#include "pvr_debug.h"
#include "pdp.h"
#include "pdpdefs.h"
#include "queue.h"
IMG_VOID ProcessFlip (PVRSRV_DEV_INFO *psDevInfo,
PVRSRV_QUEUE_INFO *psQueue,
PVRSRV_FLIP_CMD_INFO *psFlipCmd);
IMG_VOID ProcessFlipOverlay (PVRSRV_DEV_INFO *psDevInfo,
PVRSRV_QUEUE_INFO *psQueue,
PVRSRV_FLIP_OVERLAY_CMD_INFO *psFlipCmd);
IMG_VOID ProcessUpdateDisplay(PVRSRV_DEV_INFO *psDevInfo,
PVRSRV_QUEUE_INFO *psQueue,
PVRSRV_UPDATE_CMD_INFO *psFlipCmd);
/*!
******************************************************************************
@Function DevInitPDP
@Description
Reset and initialise Chip
@Input psDevInfo : devinfo
@Return PVRSRV_ERROR :
******************************************************************************/
PVRSRV_ERROR DevInitPDP(PVRSRV_DEV_INFO *psDevInfo)
{
IMG_PVOID pvRegsBase = psDevInfo->sDevLocation.pvRegsBaseKM;
/*
Disable all interrupts
- interrupts are enabled on flip command Q insertion
- interrupts are disabled when the internal vsync flip Q is empty
*/
SysDisableDeviceInterrupts(psDevInfo, pvRegsBase, PDP_INTERRUPT_ALL);
/* Clear interrupt */
SysClearDeviceInterrupts(psDevInfo, pvRegsBase, PDP_INTERRUPT_VBLANK);
PDUMPREG (IMG_NULL, PDUMPTAGS_REG_PDP, PDP_INTSTATUS, PDP_INTERRUPT_VBLANK);
/* Init the internal vsync flip queue */
InitVsyncFlipQueue(psDevInfo);
/*
Install device functions
*/
psDevInfo->pfnInitDevice = DevInitPDP;
psDevInfo->pfnDeInitDevice = DevDeInitPDP;
psDevInfo->pfnDeviceISR = PDPIsr;
psDevInfo->sDeviceSpecific.sDisplay.pfnFlipDisplay = PDPFlipDisplay;
psDevInfo->sDeviceSpecific.sDisplay.pfnFlipOverlay = PDPFlipOverlay;
psDevInfo->sDeviceSpecific.sDisplay.pfnUpdateDisplay = PDPUpdateDisplay;
psDevInfo->pfnProcessCommands = DevProcessCommandsPDP;
psDevInfo->pfnDummyProcessCommands = DevDummyProcessCommandsPDP;
#ifdef SUPPORT_POWER_STATE
psDevInfo->pfnSetPowerState = IMG_NULL; /* FIXME: DevPowerStateMBX does display for free? */
#endif
return(PVRSRV_OK);
}
/*!
******************************************************************************
@Function DevDeInitPDP
@Description
Reset and deinitialise Chip
@Input psDevInfo : devinfo
@Return PVRSRV_ERROR :
******************************************************************************/
PVRSRV_ERROR DevDeInitPDP(PVRSRV_DEV_INFO *psDevInfo)
{
IMG_PVOID pvRegsBase = psDevInfo->sDevLocation.pvRegsBaseKM;
/* Disable all interrupts */
SysDisableDeviceInterrupts(psDevInfo, pvRegsBase, PDP_INTERRUPT_ALL);
/* Deinit the internal vsync flip queue */
DeInitVsyncFlipQueue(psDevInfo);
return(PVRSRV_OK);
}
/*!
******************************************************************************
@Function DevProcessCommandsPDP
@Description
processes commands for this device
@Input psDevInfo : devinfo
@Input psQueue
@Input psCmdHeader
@Return PVRSRV_ERROR :
******************************************************************************/
IMG_VOID DevProcessCommandsPDP (PVRSRV_DEV_INFO *psDevInfo,
PVRSRV_QUEUE_INFO *psQueue,
PVRSRV_CMD_HEADER *psCmdHeader)
{
switch (psCmdHeader->ui32CommandID)
{
case PVRSRV_CMD_ID_FLIP:
ProcessFlip (psDevInfo, psQueue, (PVRSRV_FLIP_CMD_INFO *)psCmdHeader);
break;
case PVRSRV_CMD_ID_FLIP_OVERLAY:
ProcessFlipOverlay (psDevInfo, psQueue, (PVRSRV_FLIP_OVERLAY_CMD_INFO *)psCmdHeader);
break;
case PVRSRV_CMD_ID_UPDATE:
ProcessUpdateDisplay(psDevInfo,psQueue,(PVRSRV_UPDATE_CMD_INFO *) psCmdHeader);
break;
}
}
/*!
******************************************************************************
@Function DevDummyProcessCommandsPDP
@Description
does dummy command processing for pdp
@Input psDevInfo : devinfo
@Input psQueue
@Input psCmdHeader
@Return PVRSRV_ERROR :
******************************************************************************/
IMG_VOID DevDummyProcessCommandsPDP (PVRSRV_DEV_INFO *psDevInfo,
PVRSRV_QUEUE_INFO *psQueue,
PVRSRV_CMD_HEADER *psCmdHeader)
{
switch (psCmdHeader->ui32CommandID)
{
case PVRSRV_CMD_ID_FLIP:
((PVRSRV_FLIP_CMD_INFO*)psCmdHeader)->psFromSyncInfoKM->ui32ReadOpsComplete++;
UPDATE_QUEUE_ROFF(psQueue, psCmdHeader->ui32Size);
break;
case PVRSRV_CMD_ID_UPDATE:
((PVRSRV_UPDATE_CMD_INFO*)psCmdHeader)->psDestSyncInfoKM->ui32ReadOpsComplete++;
UPDATE_QUEUE_ROFF(psQueue, psCmdHeader->ui32Size);
break;
default: /* any internal flips to deal with? */
if(psDevInfo->sDeviceSpecific.sDisplay.bProcVsyncFlip)
{
ProcessVsyncFlip (psDevInfo);
}
break;
}
}
/*!
******************************************************************************
@Function PDPDFlipDisplay
@Description
flips the display
@Input psDevInfo : devinfo
@Input ui32PhysAddr
@Return PVRSRV_ERROR :
******************************************************************************/
IMG_VOID PDPFlipDisplay(PVRSRV_DEV_INFO *psDevInfo, IMG_UINT32 ui32PhysAddr)
{
IMG_UINT32 ui32Str1Base = ReadHWReg(psDevInfo->sDevLocation.pvRegsBaseKM, PDP_STR1BASE);
WriteHWReg (psDevInfo->sDevLocation.pvRegsBaseKM,
PDP_STR1BASE,
(ui32Str1Base & 0xff800000) | (ui32PhysAddr>>4));
PDPUpdateDisplay(psDevInfo);
}
/***********************************************************************************
Function Name : PDPFlipOverlay
Inputs : psDevInfo
psFlipCmd
Outputs : psDevInfo
Returns : void
Description : Flip the overlay surface.
************************************************************************************/
IMG_VOID PDPFlipOverlay(PVRSRV_DEV_INFO* psDevInfo, IMG_VOID* pvInfo)
{
VSYNC_FLIP_CMD_INFO* psFlipCmd = (VSYNC_FLIP_CMD_INFO*) pvInfo;
IMG_UINT32 ui32RegisterAddress;
IMG_UINT32 ui32RegisterData;
IMG_UINT32 ui32Index;
IMG_UINT32* pui32OverlayConfig = psFlipCmd->pui32OverlayConfig;
IMG_UINT32 ui32OverlayConfigSize = psFlipCmd->ui32OverlayConfigSize;
for (ui32Index = 0; ui32Index < ui32OverlayConfigSize; ui32Index += 2)
{
ui32RegisterAddress = *pui32OverlayConfig++;
ui32RegisterData = *pui32OverlayConfig++;
WriteHWReg (psDevInfo->sDevLocation.pvRegsBaseKM, ui32RegisterAddress, ui32RegisterData);
}
PDPUpdateDisplay(psDevInfo);
}
/*!
******************************************************************************
@Function PDPUpdateDisplay
@Description
Updates the display
@Input psDevInfo : devinfo
@Return PVRSRV_ERROR :
******************************************************************************/
IMG_VOID PDPUpdateDisplay(PVRSRV_DEV_INFO *psDevInfo)
{
IMG_UINT32 ui32UpdateCtrl = ReadHWReg(psDevInfo->sDevLocation.pvRegsBaseKM, PDP_UPDATECTRL);
psDevInfo->sDeviceSpecific.sDisplay.bIsDirty=IMG_TRUE;
WriteHWReg (psDevInfo->sDevLocation.pvRegsBaseKM, PDP_UPDATECTRL, 1);
}
/*!
******************************************************************************
@Function PDPIsr
@Description
display interrupt handler
@Input psDevInfo : devinfo
@Return PVRSRV_ERROR :
******************************************************************************/
IMG_VOID PDPIsr(PVRSRV_DEV_INFO *psDevInfo)
{
IMG_UINT32 ui32IntStatus;
IMG_UINT32 ui32IntEnable;
IMG_PVOID pvRegsBase = psDevInfo->sDevLocation.pvRegsBaseKM;
PVR_DPF((PVR_DBG_MESSAGE,"Inside PDPDisplay Isr"));
ui32IntEnable = SysDisableDeviceInterrupts(psDevInfo, pvRegsBase, PDP_INTERRUPT_ALL);
ui32IntStatus = SysDecodeDeviceInterrupts(psDevInfo, pvRegsBase);
/*
pre-conditions:
if in Vsync and Vsync Enabled - process internal Q
if in Vsync and Q is not empty - process internal Q
*/
/* VBLANK interrupt */
if (ui32IntStatus & PDP_INTERRUPT_VBLANK)
{
/* clear interrupt */
SysClearDeviceInterrupts (psDevInfo, pvRegsBase, ui32IntStatus & ~PDP_INTERRUPT_VBLANK);
if(psDevInfo->sDeviceSpecific.sDisplay.bProcVsyncFlip)
{
ProcessVsyncFlip (psDevInfo);
}
}
PVRSRVProcessQueues(psDevInfo);
if(psDevInfo->sDeviceSpecific.sDisplay.bProcVsyncFlip)
{
SysEnableDeviceInterrupts(psDevInfo, pvRegsBase, ui32IntEnable | PDP_INTERRUPT_VBLANK);
}
else
{
SysEnableDeviceInterrupts(psDevInfo, pvRegsBase, ui32IntEnable & ~PDP_INTERRUPT_VBLANK);
}
}
/*****************************************************************************
End of file (pdp.c)
*****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -