--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/baseport/syborg/svpframebuffer/svpframebuffer.cpp Wed Jan 27 14:42:12 2010 +0000
@@ -0,0 +1,1055 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Minimalistic frame buffer driver
+*
+*/
+#include <videodriver.h>
+#include "platform.h"
+#include <nkern.h>
+#include <kernel/kernel.h>
+#include <kernel/kern_priv.h>
+#include <kernel/kpower.h>
+
+#include <syborg_priv.h>
+#include "svpframebuffer.h"
+
+DLcdPowerHandler * DLcdPowerHandler::pLcd = NULL;
+
+TPhysAddr Syborg::VideoRamPhys;
+TPhysAddr Syborg::VideoRamPhysSecure; // Secure display memory
+
+TPhysAddr TSyborg::VideoRamPhys()
+{
+ __KTRACE_OPT(KEXTENSION,Kern::Printf("TSyborg::VideoRamPhys: VideoRamPhys=0x%x", Syborg::VideoRamPhys));
+ return Syborg::VideoRamPhys;
+}
+
+TPhysAddr TSyborg::VideoRamPhysSecure()
+{
+ return Syborg::VideoRamPhysSecure;
+}
+
+LOCAL_C TInt DoHalFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2)
+{
+ DLcdPowerHandler* pH=(DLcdPowerHandler*)aPtr;
+ return pH->HalFunction(aFunction,a1,a2);
+}
+
+static void rxMsg(TAny* aPtr)
+{
+ DLcdPowerHandler& h=*(DLcdPowerHandler*)aPtr;
+ TMessageBase* pM = h.iMsgQ.iMessage;
+ if(pM)
+ h.HandleMsg(pM);
+}
+
+static void power_up_dfc(TAny* aPtr)
+{
+ ((DLcdPowerHandler*)aPtr)->PowerUpDfc();
+}
+
+void power_down_dfc(TAny* aPtr)
+{
+ ((DLcdPowerHandler*)aPtr)->PowerDownDfc();
+}
+
+void DLcdPowerHandler::DisplayOn()
+{
+ PowerUpLcd(iSecureDisplay);
+ iDisplayOn = ETrue;
+}
+
+void DLcdPowerHandler::DisplayOff()
+{
+ PowerDownLcd();
+ iDisplayOn = EFalse;
+}
+
+void DLcdPowerHandler::SwitchDisplay(TBool aSecure)
+ {
+ if(aSecure)
+ {
+ if(!iSecureDisplay)
+ {
+ DisplayOff();
+ iSecureDisplay = ETrue;
+ DisplayOn();
+ }
+ }
+ else
+ {
+ if(iSecureDisplay)
+ {
+ DisplayOff();
+ iSecureDisplay = EFalse;
+ DisplayOn();
+ }
+ }
+ }
+
+void DLcdPowerHandler::PowerUpDfc()
+{
+ DisplayOn();
+ PowerUpDone();
+}
+
+void DLcdPowerHandler::PowerDownDfc()
+{
+ DisplayOff();
+ PowerDownDone();
+}
+
+void DLcdPowerHandler::PowerDown(TPowerState)
+{
+ iPowerDownDfc.Enque();
+}
+
+void DLcdPowerHandler::PowerUp()
+{
+ iPowerUpDfc.Enque();
+}
+
+void DLcdPowerHandler::PowerUpLcd(TBool aSecure)
+{
+#if 1
+ WriteReg(iPortAddr, FB_ENABLED, 0);
+ WriteReg(iPortAddr, FB_BASE, aSecure ? iSecurevRamPhys : ivRamPhys);
+ WriteReg(iPortAddr, FB_WIDTH, iVideoInfo.iSizeInPixels.iWidth);
+ WriteReg(iPortAddr, FB_BLANK, 0);
+ WriteReg(iPortAddr, FB_BPP, 32);
+ WriteReg(iPortAddr, FB_COLOR_ORDER, 0);
+ WriteReg(iPortAddr, FB_BYTE_ORDER, 0);
+ WriteReg(iPortAddr, FB_PIXEL_ORDER, 0);
+ WriteReg(iPortAddr, FB_INT_MASK, 0);
+ WriteReg(iPortAddr, FB_ENABLED, 1);
+ WriteReg(iPortAddr, FB_HEIGHT, iVideoInfo.iSizeInPixels.iHeight);
+#endif
+}
+
+void DLcdPowerHandler::PowerDownLcd()
+{
+ WriteReg(iPortAddr, FB_BLANK, 1);
+}
+
+DLcdPowerHandler::DLcdPowerHandler()
+ : DPowerHandler(KLitLcd),
+ iMsgQ(rxMsg,this,NULL,1),
+ iPowerUpDfc(&power_up_dfc,this,6),
+ iPowerDownDfc(&power_down_dfc,this,7)
+{
+}
+
+void DLcdPowerHandler::ScreenInfo(TScreenInfoV01& anInfo)
+{
+ anInfo.iWindowHandleValid = EFalse;
+ anInfo.iWindowHandle = NULL;
+ anInfo.iScreenAddressValid = ETrue;
+ anInfo.iScreenAddress = (TAny *)(iChunk->LinearAddress());
+ anInfo.iScreenSize.iWidth = iVideoInfo.iSizeInPixels.iWidth;
+ anInfo.iScreenSize.iHeight = iVideoInfo.iSizeInPixels.iHeight;
+}
+
+void DLcdPowerHandler::HandleMsg(TMessageBase* aMsg)
+{
+ if(aMsg->iValue)
+ DisplayOn();
+ else
+ DisplayOff();
+ aMsg->Complete(KErrNone,ETrue);
+}
+
+void DLcdPowerHandler::WsSwitchOnScreen()
+{
+ TThreadMessage& m = Kern::Message();
+ m.iValue = ETrue;
+ m.SendReceive(&iMsgQ);
+}
+
+void DLcdPowerHandler::WsSwitchOffScreen()
+{
+ TThreadMessage& m = Kern::Message();
+ m.iValue = EFalse;
+ m.SendReceive(&iMsgQ);
+}
+
+TInt DLcdPowerHandler::GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure)
+{
+ NKern::FMWait(&iLock);
+ if(aSecure)
+ aInfo = iSecureVideoInfo;
+ else
+ aInfo = iVideoInfo;
+ NKern::FMSignal(&iLock);
+ return KErrNone;
+}
+
+TInt DLcdPowerHandler::GetSpecifiedDisplayModeInfo(TInt aMode, TVideoInfoV01& aInfo)
+{
+ if(aMode < 0 || aMode >= KConfigLcdNumberOfDisplayModes)
+ return KErrArgument;
+
+ NKern::FMWait(&iLock);
+ aInfo = iVideoInfo;
+ NKern::FMSignal(&iLock);
+
+ if(aMode != aInfo.iDisplayMode)
+ {
+ aInfo.iOffsetToFirstPixel = KCOnfigOffsetToFirstPixel;
+ aInfo.iIsPalettized = KConfigIsPalettized;
+ aInfo.iOffsetBetweenLines = KCOnfigOffsetBetweenLines;
+ aInfo.iBitsPerPixel = KConfigBitsPerPixel;
+ }
+ return KErrNone;
+}
+
+TInt DLcdPowerHandler::AllocateFrameBuffer()
+{
+ // Allocate physical RAM for video
+ TInt vSize = TSyborg::VideoRamSize();
+
+ NKern::ThreadEnterCS();
+ TInt r = Epoc::AllocPhysicalRam(vSize,Syborg::VideoRamPhys);
+ if (r != KErrNone)
+ {
+ NKern::ThreadLeaveCS();
+ Kern::Fault("AllocVideoRam",r);
+ }
+
+ // Map the video RAM
+ ivRamPhys = TSyborg::VideoRamPhys();
+
+ r = DPlatChunkHw::New(iChunk,ivRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC);
+
+ NKern::ThreadLeaveCS();
+
+ if(r != KErrNone)
+ return r;
+
+ TUint* pV = (TUint*)iChunk->LinearAddress();
+
+ // Allocate physical RAM for secure display
+ NKern::ThreadEnterCS();
+ r = Epoc::AllocPhysicalRam(vSize,Syborg::VideoRamPhysSecure);
+ if (r != KErrNone)
+ {
+ NKern::ThreadLeaveCS();
+ Kern::Fault("AllocVideoRam 2",r);
+ }
+ iSecurevRamPhys = ivRamPhys + vSize;
+ TInt r2 = DPlatChunkHw::New(iSecureChunk,iSecurevRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC);
+
+ NKern::ThreadLeaveCS();
+
+ if(r2 != KErrNone)
+ return r2;
+
+ TUint* pV2 = (TUint*)iSecureChunk->LinearAddress();
+
+ iVideoInfo.iSizeInPixels.iWidth = KConfigLcdWidth;
+ iVideoInfo.iSizeInPixels.iHeight = KConfigLcdHeight;
+ iVideoInfo.iDisplayMode = KConfigLcdDisplayMode;
+ iVideoInfo.iOffsetToFirstPixel = KCOnfigOffsetToFirstPixel;
+ iVideoInfo.iOffsetBetweenLines = KCOnfigOffsetBetweenLines;
+ iVideoInfo.iIsPalettized = KConfigIsPalettized;
+ iVideoInfo.iBitsPerPixel = KConfigBitsPerPixel;
+ iVideoInfo.iSizeInTwips.iWidth = KConfigLcdWidthInTwips;
+ iVideoInfo.iSizeInTwips.iHeight = KConfigLcdHeightInTwips;
+ iVideoInfo.iIsMono = KConfigIsMono;
+ iVideoInfo.iVideoAddress = (TInt)pV;
+ iVideoInfo.iIsPixelOrderLandscape = KConfigPixelOrderLandscape;
+ iVideoInfo.iIsPixelOrderRGB = KConfigPixelOrderRGB;
+
+ iSecureVideoInfo = iVideoInfo;
+ iSecureVideoInfo.iVideoAddress = (TInt)pV2;
+
+ // Alloc Physical RAM for the Composition Buffers used by the GCE
+ iSize = 4*480*640;//FRAME_BUFFER_SIZE( iVideoInfo.iBitsPerPixel, iVideoInfo.iSizeInPixels.iWidth, iVideoInfo.iSizeInPixels.iHeight);
+ __GCE_DEBUG_PRINT2("DLcdPowerHandler.iSize = %d\n", iSize );
+ // double and round the page size
+ TUint round = 2*Kern::RoundToPageSize(iSize);
+
+ r=Epoc::AllocPhysicalRam(round , iCompositionPhysical);
+ if(r!=KErrNone)
+ {
+ return r;
+ }
+
+ return KErrNone;
+}
+
+
+TInt DLcdPowerHandler::SetDisplayMode(TInt aMode)
+{
+ if(aMode < 0 || aMode >= KConfigLcdNumberOfDisplayModes)
+ return KErrArgument;
+
+ // store the current mode
+ iVideoInfo.iDisplayMode = aMode;
+
+ // store the current mode for secure screen
+ iSecureVideoInfo.iDisplayMode = aMode;
+
+ return KErrNone;
+}
+
+TInt DLcdPowerHandler::HalFunction(TInt aFunction, TAny* a1, TAny* a2)
+{
+ TInt r=KErrNone;
+ switch(aFunction)
+ {
+ case EDisplayHalScreenInfo:
+ {
+ TPckgBuf<TScreenInfoV01> vPckg;
+ ScreenInfo(vPckg());
+ Kern::InfoCopy(*(TDes8*)a1,vPckg);
+ break;
+ }
+ case EDisplayHalWsRegisterSwitchOnScreenHandling:
+ {
+ iWsSwitchOnScreen=(TBool)a1;
+ break;
+ }
+ case EDisplayHalWsSwitchOnScreen:
+ {
+ WsSwitchOnScreen();
+ break;
+ }
+ case EDisplayHalModeCount:
+ {
+ TInt ndm = KConfigLcdNumberOfDisplayModes;
+ kumemput32(a1, &ndm, sizeof(ndm));
+ break;
+ }
+ case EDisplayHalSetMode:
+ {
+ __KTRACE_OPT(KEXTENSION,Kern::Printf("EDisplayHalSetMode"));
+ __SECURE_KERNEL(
+ if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetMode")))
+ return KErrPermissionDenied;
+ )
+ r = SetDisplayMode((TInt)a1);
+ break;
+ }
+ case EDisplayHalMode:
+ {
+ kumemput32(a1, &iVideoInfo.iDisplayMode, sizeof(iVideoInfo.iDisplayMode));
+ r = KErrNone;
+ break;
+ }
+ case EDisplayHalSetPaletteEntry:
+ {
+ __SECURE_KERNEL(
+ if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetPaletteEntry")))
+ return KErrPermissionDenied;
+ )
+ r = KErrNotSupported;
+ break;
+ }
+ case EDisplayHalPaletteEntry:
+ {
+ TInt entry;
+ kumemget32(&entry, a1, sizeof(TInt));
+ r = KErrNotSupported;
+ break;
+ }
+ case EDisplayHalSetState:
+ {
+ __SECURE_KERNEL(
+ if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetState")))
+ return KErrPermissionDenied;
+ )
+ if((TBool)a1)
+ WsSwitchOnScreen();
+ else
+ WsSwitchOffScreen();
+ break;
+ }
+ case EDisplayHalState:
+ {
+ kumemput32(a1, &iDisplayOn, sizeof(TBool));
+ break;
+ }
+ case EDisplayHalColors:
+ {
+ TInt mdc = 1<<24;
+ kumemput32(a1, &mdc, sizeof(mdc));
+ break;
+ }
+ case EDisplayHalCurrentModeInfo:
+ {
+ TPckgBuf<TVideoInfoV01> vPckg;
+ r = GetCurrentDisplayModeInfo(vPckg(), (TBool)a2);
+ if(KErrNone == r)
+ Kern::InfoCopy(*(TDes8*)a1,vPckg);
+ break;
+ }
+ case EDisplayHalSpecifiedModeInfo:
+ {
+ TPckgBuf<TVideoInfoV01> vPckg;
+ TInt mode;
+ kumemget32(&mode, a1, sizeof(mode));
+ r = GetSpecifiedDisplayModeInfo(mode, vPckg());
+ if(KErrNone == r)
+ Kern::InfoCopy(*(TDes8*)a2,vPckg);
+ break;
+ }
+ case EDisplayHalSecure:
+ {
+ kumemput32(a1, &iSecureDisplay, sizeof(TBool));
+ break;
+ }
+ case EDisplayHalSetSecure:
+ {
+ __SECURE_KERNEL(
+ if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetSecure")))
+ return KErrPermissionDenied;
+ )
+ SwitchDisplay((TBool)a1);
+ break;
+ }
+ default:
+ {
+ r = KErrNotSupported;
+ break;
+ }
+ }
+ return r;
+}
+
+TInt DLcdPowerHandler::Create()
+{
+ __KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::Create") );
+ pLcd = this;
+
+ iPortAddr = KHwBaseClcd;
+
+ iVideoInfo.iSizeInPixels.iWidth = KConfigLcdWidth;
+ iVideoInfo.iSizeInPixels.iHeight = KConfigLcdHeight;
+ iVideoInfo.iDisplayMode = KConfigLcdDisplayMode;
+ iVideoInfo.iOffsetToFirstPixel = KCOnfigOffsetToFirstPixel;
+ iVideoInfo.iOffsetBetweenLines = KCOnfigOffsetBetweenLines;
+ iVideoInfo.iIsPalettized = KConfigIsPalettized;
+ iVideoInfo.iBitsPerPixel = KConfigBitsPerPixel;
+ iVideoInfo.iSizeInTwips.iWidth = KConfigLcdWidthInTwips;
+ iVideoInfo.iSizeInTwips.iHeight = KConfigLcdHeightInTwips;
+ iVideoInfo.iIsMono = KConfigIsMono;
+ // !@! iVideoInfo.iVideoAddress = (TInt)pV;
+ iVideoInfo.iIsPixelOrderLandscape = KConfigPixelOrderLandscape;
+ iVideoInfo.iIsPixelOrderRGB = KConfigPixelOrderRGB;
+
+ iSecureVideoInfo = iVideoInfo;
+ // !@! iSecureVideoInfo.iVideoAddress = (TInt)pV2;
+
+ TInt r = AllocateFrameBuffer();
+ if(r == KErrNone)
+ {
+ r = Kern::AddHalEntry(EHalGroupDisplay,DoHalFunction,this);
+ }
+
+ if(r != KErrNone)
+ {
+ __KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::Create failed %d", r) );
+ return r;
+ }
+
+ iPowerUpDfc.SetDfcQ(iDfcQ);
+ iPowerDownDfc.SetDfcQ(iDfcQ);
+ iMsgQ.SetDfcQ(iDfcQ);
+ iMsgQ.Receive();
+
+ Add();
+ DisplayOn();
+
+ return KErrNone;
+}
+
+/**
+ * Register the call back function.
+ * Components interested in receiving notification of the Vsync interrupt should register a callback function.
+ */
+EXPORT_C TInt DLcdPowerHandler::RegisterCallback(TLcdUserCallBack* aCbPtr)
+{
+ __KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::RegisterCallBack %08x\n",aCbPtr->iCbFn) );
+
+ TInt irq=__SPIN_LOCK_IRQSAVE(callbackLock);
+
+ if(aCbPtr != NULL)
+ {
+ if ( pLcd->iAppCallBk[0] == NULL )
+ {
+ pLcd->iAppCallBk[0] = aCbPtr;
+ }
+ else
+ {
+ if((pLcd->iAppCallBk[1] == NULL) && (pLcd->iAppCallBk[0]->iCbFn != aCbPtr->iCbFn))
+ {
+ pLcd->iAppCallBk[1] = aCbPtr;
+ }
+ else
+ {
+ __SPIN_UNLOCK_IRQRESTORE(callbackLock,irq);
+ return KErrInUse;
+ }
+ }
+
+ __SPIN_UNLOCK_IRQRESTORE(callbackLock,irq);
+ __KTRACE_OPT(KEXTENSION ,Kern::Printf("<DLcdPowerHandler::RegisterCallBack ok %08x\n",aCbPtr->iCbFn) );
+ return KErrNone;
+ }
+ else
+ {
+ __SPIN_UNLOCK_IRQRESTORE(callbackLock,irq);
+ __KTRACE_OPT(KEXTENSION, Kern::Printf("Error: The supplied listener's callback is NULL"));
+ return KErrArgument;
+ }
+}
+
+
+/**
+ *DeRegister the call back function
+ */
+EXPORT_C void DLcdPowerHandler::DeRegisterCallback(TLcdUserCallBack* aCbPtr)
+{
+ __KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::DeRegisterCallBack %08x\n ",aCbPtr->iCbFn) );
+
+ TInt irq=__SPIN_LOCK_IRQSAVE(callbackLock);
+ if(aCbPtr != NULL)
+ {
+ if( pLcd->iAppCallBk[0] != NULL)
+ {
+ if ( (pLcd->iAppCallBk[0]->iDataPtr == aCbPtr->iDataPtr) && (pLcd->iAppCallBk[0]->iCbFn == aCbPtr->iCbFn) )
+ {
+ pLcd->iAppCallBk[0] = NULL;
+ }
+ }
+
+ if( pLcd->iAppCallBk[1] != NULL)
+ {
+ if ( (pLcd->iAppCallBk[1]->iDataPtr == aCbPtr->iDataPtr) && (pLcd->iAppCallBk[1]->iCbFn == aCbPtr->iCbFn) )
+ {
+ pLcd->iAppCallBk[1] = NULL;
+ }
+ }
+ }
+ __SPIN_UNLOCK_IRQRESTORE(callbackLock,irq);
+ __KTRACE_OPT(KEXTENSION ,Kern::Printf("<DLcdPowerHandler::DeRegisterCallBack %08x\n ",aCbPtr->iCbFn) );
+}
+
+/**
+ Constructor
+*/
+DDisplayPddSyborg::DDisplayPddSyborg():
+ iPendingBuffer(NULL),
+ iActiveBuffer(NULL),
+ iChunk(NULL),
+ iLcdCallback(NULL),
+ iVSyncDfc(&VSyncDfcFn, this, KVSyncDfcPriority)
+ {
+ __GCE_DEBUG_PRINT("DDisplayPddSyborg::DDisplayPddSyborg\n");
+
+ iPostFlag = EFalse;
+ }
+
+/**
+ Destructor
+*/
+DDisplayPddSyborg::~DDisplayPddSyborg()
+ {
+ __GCE_DEBUG_PRINT("DDisplayPddSyborg::~DDisplayPddSyborg() \n");
+
+ if(iLcdCallback)
+ {
+ DLcdPowerHandler::pLcd->DeRegisterCallback(iLcdCallback) ;
+ delete iLcdCallback;
+ iLcdCallback = NULL;
+ }
+
+ //The DFC Queue is owned by DLcdPowerHandler so we shouldn't call Destroy() at this point.
+ if (iDfcQ)
+ {
+ iDfcQ=NULL;
+ }
+
+ DChunk* chunk = (DChunk*) __e32_atomic_swp_ord_ptr(&iChunk, 0);
+
+ if(chunk)
+ {
+ Kern::ChunkClose(chunk);
+ }
+
+ }
+
+/**
+ Set the Legacy Mode by setting the appropriate Frame control value.
+
+*/
+TInt DDisplayPddSyborg::SetLegacyMode()
+ {
+ __GCE_DEBUG_PRINT("DDisplayPddSyborg::SetLegacyMode()\n");
+
+ return KErrNone;
+ }
+
+/**
+ Set the GCE mode by posting a composition buffer.
+
+*/
+TInt DDisplayPddSyborg::SetGceMode()
+ {
+ __GCE_DEBUG_PRINT("DDisplayPddSyborg::SetGceMode()\n");
+
+ PostCompositionBuffer(&iLdd->iCompositionBuffer[0]);
+ return KErrNone;
+ }
+
+/**
+ @param aDegOfRot The requested rotation
+ @return KErrNone
+*/
+TInt DDisplayPddSyborg::SetRotation(TInt aDegOfRot)
+ {
+ return KErrNone;
+ }
+
+/**
+ Remove any previous post operations, set the appropriate layer as the next layer to be displayed( This value is updated in synchronization
+ with V Sync so it will take affect in the next V Sync after that) and also set the buffer provided as the buffer to
+ be posted next. Layer 3 is associated with user buffers.
+
+ @param aNode Pointer to the User buffer to post.
+*/
+TInt DDisplayPddSyborg::PostUserBuffer(TBufferNode* aNode)
+ {
+
+ __GCE_DEBUG_PRINT2("DDisplayPddSyborg::PostUserBuffer : aNode->iAddress = %08x\n", aNode->iAddress);
+
+ if(iPendingBuffer)
+ {
+ iPendingBuffer->iState = EBufferFree;
+ if (!(iPendingBuffer->iType == EBufferTypeUser) )
+ {
+ iPendingBuffer->iFree = ETrue;
+ }
+ }
+
+ aNode->iState = EBufferPending;
+ iPendingBuffer = aNode;
+ iPostFlag = ETrue;
+
+ // Activate the posted buffer
+ TUint32 physicalAddress = Epoc::LinearToPhysical( aNode->iAddress );
+ WriteReg(DLcdPowerHandler::pLcd->iPortAddr, DLcdPowerHandler::FB_BASE, physicalAddress );
+ /* Queue a DFC to complete the request*/
+ iVSyncDfc.Enque();
+
+ return KErrNone;
+ }
+
+/**
+ Remove any previous post operations, set the appropriate layer as the next layer to be displayed( This value is updated in synchronization
+ with V Sync so it will take affect in the next V Sync after that) and also set the buffer provided as the buffer to
+ be posted next. Layer 1 and 2 are associated with composition buffers 0 and 1 respectively.
+
+ @param aNode Pointer to the Composition buffer to post.
+*/
+TInt DDisplayPddSyborg::PostCompositionBuffer(TBufferNode* aNode)
+ {
+
+ __GCE_DEBUG_PRINT2("DDisplayPddSyborg::PostCompositionBuffer : aNode->iAddress = %08x\n", aNode->iAddress);
+
+ if(iPendingBuffer)
+ {
+ iPendingBuffer->iState = EBufferFree;
+ if (iPendingBuffer->iType == EBufferTypeUser)
+ {
+ RequestComplete(RDisplayChannel::EReqPostUserBuffer, KErrCancel);
+ }
+ else
+ {
+ iPendingBuffer->iFree = ETrue;
+ }
+ }
+ aNode->iState = EBufferPending;
+ aNode->iFree = EFalse;
+ iPendingBuffer = aNode;
+ iPostFlag = ETrue;
+
+ // Activate the posted buffer
+ TUint32 physicalAddress = Epoc::LinearToPhysical( aNode->iAddress );
+ WriteReg(DLcdPowerHandler::pLcd->iPortAddr, DLcdPowerHandler::FB_BASE, physicalAddress );
+
+ /* Queue a DFC to complete the request*/
+ iVSyncDfc.Enque();
+
+ return KErrNone;
+ }
+
+/**
+ Remove any previous post operations, set the appropriate layer as the next layer to be displayed( This value is updated in synchronization
+ with V Sync so it will take affect in the next V Sync after that) and also set the Legacy Buffer as the buffer to
+ be posted next.Layer 0 is associated with legacy buffer.
+
+ @param aNode Pointer to the Composition buffer to post.
+*/
+TInt DDisplayPddSyborg::PostLegacyBuffer()
+ {
+ __GCE_DEBUG_PRINT("DDisplayPddSyborg::PostLegacyBuffer() \n");
+
+ if(iPendingBuffer)
+ {
+ iPendingBuffer->iState = EBufferFree;
+ if (iPendingBuffer->iType == EBufferTypeUser)
+ {
+
+ RequestComplete(RDisplayChannel::EReqPostUserBuffer, KErrCancel);
+ }
+ else
+ {
+ iPendingBuffer->iFree = ETrue;
+ }
+ }
+
+
+ iLdd->iLegacyBuffer[0].iState = EBufferPending;
+ iLdd->iLegacyBuffer[0].iFree = EFalse;
+ iPendingBuffer = &iLdd->iLegacyBuffer[0];
+ iPostFlag = ETrue;
+
+ // Activate the posted buffer
+ WriteReg(DLcdPowerHandler::pLcd->iPortAddr, DLcdPowerHandler::FB_BASE, TSyborg::VideoRamPhys() );
+
+ /* Queue a DFC to complete the request*/
+ iVSyncDfc.Enque();
+
+ return KErrNone;
+ }
+
+/**
+ Handles device specific operations when a close message has been sent to the Logical Channel.
+
+*/
+TInt DDisplayPddSyborg::CloseMsg()
+ {
+ __GCE_DEBUG_PRINT("DDisplayPddSyborg::CloseMsg()\n");
+
+ iPendingBuffer = NULL;
+ iActiveBuffer = NULL;
+
+ iVSyncDfc.Cancel();
+ return KErrNone;
+ }
+
+/**
+ Called by the LDD's DoCreate function to handle the device specific part of opening the channel.
+ (DoCreate is called by RDisplayChannel::Open)
+
+ @param aUnit The screen unit
+
+ @return KErrNone if successful; or one of the other system wide error codes.
+*/
+TInt DDisplayPddSyborg::CreateChannelSetup(TInt aUnit)
+ {
+ __GCE_DEBUG_PRINT("DDisplayPddSyborg::CreateChannelSetup\n");
+
+ iScreenInfo = DLcdPowerHandler::pLcd->iVideoInfo;
+ iLdd->iUnit = aUnit;
+
+ iLdd->iDisplayInfo.iAvailableRotations = RDisplayChannel::ERotationNormal;
+ iLdd->iDisplayInfo.iNormal.iOffsetBetweenLines = iScreenInfo.iOffsetBetweenLines;
+ iLdd->iDisplayInfo.iNormal.iHeight = iScreenInfo.iSizeInPixels.iHeight;
+ iLdd->iDisplayInfo.iNormal.iWidth = iScreenInfo.iSizeInPixels.iWidth;
+ iLdd->iDisplayInfo.iNumCompositionBuffers = KDisplayCBMax;
+ iLdd->iDisplayInfo.iBitsPerPixel = iScreenInfo.iBitsPerPixel;
+ iLdd->iDisplayInfo.iRefreshRateHz = 60;
+
+
+ switch (iScreenInfo.iBitsPerPixel)
+ {
+ case 16:
+ iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatRGB_565;
+ break;
+ case 24:
+ iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatRGB_888;
+ break;
+ case 32:
+ iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatARGB_8888;
+ break;
+ default:
+ iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatUnknown;
+ break;
+ }
+
+ iLdd->iCurrentRotation = RDisplayChannel::ERotationNormal;
+
+ // Open shared chunk to the composition framebuffer
+
+ DChunk* chunk = 0;
+ TLinAddr chunkKernelAddr = 0;
+ TUint32 chunkMapAttr = 0;
+
+ // round to twice the page size
+ TUint round = 2*Kern::RoundToPageSize(DLcdPowerHandler::pLcd->iSize);
+
+ __GCE_DEBUG_PRINT2("DDisplayPddSyborg::CreateChannelSetup DLcdPowerHandler::pLcd->iSize = %d\n", DLcdPowerHandler::pLcd->iSize );
+
+ TChunkCreateInfo info;
+ info.iType = TChunkCreateInfo::ESharedKernelMultiple;
+ info.iMaxSize = round;
+ info.iMapAttr = EMapAttrFullyBlocking;
+ info.iOwnsMemory = EFalse;
+ info.iDestroyedDfc = 0;
+
+ TInt r = Kern::ChunkCreate(info, chunk, chunkKernelAddr, chunkMapAttr);
+
+ __GCE_DEBUG_PRINT2("CreateChannelSetup:ChunkCreate called for composition chunk. Set iChunkKernelAddr = %08x\n", chunkKernelAddr );
+
+ if( r == KErrNone)
+ {
+ // map our chunk
+ r = Kern::ChunkCommitPhysical(chunk, 0,round , DLcdPowerHandler::pLcd->iCompositionPhysical);
+ __GCE_DEBUG_PRINT2("Mapping chunk %d", r);
+ if(r != KErrNone)
+ {
+ Kern::ChunkClose(chunk);
+ }
+ }
+
+ if ( r!= KErrNone)
+ {
+ return r;
+ }
+
+ iChunk = chunk;
+
+ // init CB 0
+ iLdd->iCompositionBuffer[0].iType = EBufferTypeComposition;
+ iLdd->iCompositionBuffer[0].iBufferId = 0;
+ iLdd->iCompositionBuffer[0].iFree = ETrue;
+ iLdd->iCompositionBuffer[0].iState = EBufferFree;
+ iLdd->iCompositionBuffer[0].iAddress = chunkKernelAddr;
+ iLdd->iCompositionBuffer[0].iPhysicalAddress = Epoc::LinearToPhysical(chunkKernelAddr);
+ iLdd->iCompositionBuffer[0].iChunk = chunk;
+ iLdd->iCompositionBuffer[0].iHandle = 0;
+ iLdd->iCompositionBuffer[0].iOffset = 0;
+ iLdd->iCompositionBuffer[0].iSize = DLcdPowerHandler::pLcd->iSize;
+ iLdd->iCompositionBuffer[0].iPendingRequest = 0;
+
+ // init CB 1
+ iLdd->iCompositionBuffer[1].iType = EBufferTypeComposition;
+ iLdd->iCompositionBuffer[1].iBufferId = 1;
+ iLdd->iCompositionBuffer[1].iFree = ETrue;
+ iLdd->iCompositionBuffer[1].iState = EBufferFree;
+ iLdd->iCompositionBuffer[1].iAddress = chunkKernelAddr + DLcdPowerHandler::pLcd->iSize;
+ iLdd->iCompositionBuffer[1].iPhysicalAddress = Epoc::LinearToPhysical(chunkKernelAddr + DLcdPowerHandler::pLcd->iSize);
+ iLdd->iCompositionBuffer[1].iChunk = chunk;
+ iLdd->iCompositionBuffer[1].iHandle = 0;
+ iLdd->iCompositionBuffer[1].iOffset = DLcdPowerHandler::pLcd->iSize;
+ iLdd->iCompositionBuffer[1].iSize = DLcdPowerHandler::pLcd->iSize;
+ iLdd->iCompositionBuffer[1].iPendingRequest = 0;
+
+ iLdd->iCompositionBuffIdx = 0;
+ //Use the same DFC queue created by the DLcdPowerHandler so all hardware accesses are executed under the same DFC thread.
+ iDfcQ= DLcdPowerHandler::pLcd->iDfcQ;
+
+ // Set the Post DFC.
+ iVSyncDfc.SetDfcQ(iDfcQ);
+
+
+ return KErrNone;
+ }
+
+/**
+Detect whether a post operation is pending
+*/
+TBool DDisplayPddSyborg::PostPending()
+ {
+ return (iPendingBuffer != NULL);
+ }
+
+/**
+ Return the DFC queue to be used for this device.
+ */
+TDfcQue * DDisplayPddSyborg::DfcQ(TInt aUnit)
+ {
+ return iDfcQ;
+ }
+
+void DDisplayPddSyborg::VSyncDfcFn(TAny* aChannel)
+ {
+ DDisplayPddSyborg * channel =(DDisplayPddSyborg*)aChannel;
+
+ if (channel->iPostFlag)
+ {
+ channel->iPostFlag = EFalse;
+
+ if (channel->iActiveBuffer)
+ {
+ //When a User buffer is registered its iFree member becomes EFalse and Deregister sets it
+ //back to ETrue. Composition and Legacy buffers are not free when they are in the pending or
+ //active state.
+ if (channel->iActiveBuffer->iType == EBufferTypeUser)
+ {
+ channel->RequestComplete(RDisplayChannel::EReqPostUserBuffer, KErrNone);
+ }
+ else
+ {
+ channel->iActiveBuffer->iFree = ETrue;
+ }
+
+ channel->iActiveBuffer->iState = EBufferFree;
+
+
+ //If no buffer was available during a call to GetCompositionBuffer the active buffer has
+ //been returned as the next available one, so we must set the buffer to the proper state before we
+ //send the notification.
+ if(channel->iLdd->iPendingReq[RDisplayChannel::EReqGetCompositionBuffer].iStatus)
+ {
+ channel->iActiveBuffer->iState = EBufferCompose;
+ channel->RequestComplete(RDisplayChannel::EReqGetCompositionBuffer, KErrNone);
+
+ }
+
+ channel->iActiveBuffer = NULL;
+ }
+
+ if (channel->iPendingBuffer)
+ {
+ __GCE_DEBUG_PRINT2("DDisplayPddSyborg::VSyncDfcFn moving pending buffer at address %08x to the active state\n", channel->iPendingBuffer->iAddress);
+ channel->iActiveBuffer = channel->iPendingBuffer;
+ channel->iActiveBuffer->iState = EBufferActive;
+ channel->iPendingBuffer = NULL;
+
+ channel->RequestComplete(RDisplayChannel::EReqWaitForPost, KErrNone);
+ }
+ }
+ }
+//*****************************************************************
+//DDisplayPddFactory
+//*****************************************************************/
+
+
+/**
+ Constructor
+*/
+DDisplayPddFactory::DDisplayPddFactory()
+ {
+ __GCE_DEBUG_PRINT("DDisplayPddFactory::DDisplayPddFactory()\n");
+
+ iVersion = TVersion(KDisplayChMajorVersionNumber,
+ KDisplayChMinorVersionNumber,
+ KDisplayChBuildVersionNumber);
+ }
+
+/**
+ PDD factory function. Creates a PDD object.
+
+ @param aChannel A pointer to an PDD channel object which will be initialised on return.
+
+ @return KErrNone if object successfully allocated, KErrNoMemory if not.
+*/
+TInt DDisplayPddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer)
+ {
+ DDisplayPddSyborg *device= new DDisplayPddSyborg() ;
+ aChannel=device;
+ if (!device)
+ {
+ return KErrNoMemory;
+ }
+ return KErrNone;
+ }
+
+
+/**
+ Set the Pdd name and return error code
+*/
+TInt DDisplayPddFactory::Install()
+ {
+ __GCE_DEBUG_PRINT("DDisplayPddFactory::Install() \n");
+
+ TBuf<32> name(RDisplayChannel::Name());
+ _LIT(KPddExtension,".pdd");
+ name.Append(KPddExtension);
+ return SetName(&name);
+ }
+
+
+void DDisplayPddFactory::GetCaps(TDes8& /*aDes*/) const
+ {
+ //Not supported
+ }
+
+
+/**
+ Validate version and number of units.
+*/
+TInt DDisplayPddFactory::Validate(TInt aUnit, const TDesC8* /*anInfo*/, const TVersion& aVer)
+ {
+ if (!Kern::QueryVersionSupported(iVersion,aVer))
+ {
+ return KErrNotSupported;
+ }
+
+ if (aUnit != 0)
+ {
+ return KErrNotSupported;
+ }
+
+ return KErrNone;
+ }
+
+DECLARE_EXTENSION_PDD()
+/**
+ "Standard PDD" entrypoint.Creates PDD factory when Kern::InstallPhysicalDevice is called
+
+ @return pointer to the PDD factory object.
+*/
+ {
+ __GCE_DEBUG_PRINT("DECLARE_EXTENSION_PDD()\n");
+ return new DDisplayPddFactory ;
+ }
+
+
+DECLARE_STANDARD_EXTENSION()
+{
+ TInt r = KErrNoMemory;
+ DLcdPowerHandler* pH=new DLcdPowerHandler;
+ if(pH)
+ {
+ r = pH->Create();
+ if ( r == KErrNone)
+ {
+ pH->iDfcQ = Kern::DfcQue0(); // use low priority DFC queue for this driver
+
+ DDisplayPddFactory * device = new DDisplayPddFactory;
+
+ if (device==NULL)
+ {
+ r=KErrNoMemory;
+ }
+ else
+ {
+ r=Kern::InstallPhysicalDevice(device);
+ }
+
+ #ifdef CPU_AFFINITY_ANY
+ NKern::ThreadSetCpuAffinity((NThread*) pH->iDfcQ->iThread, KCpuAffinityAny);
+ #endif
+
+ __KTRACE_OPT(KEXTENSION,Kern::Printf("Installing the display device from the kernel extension returned with error code %d",r));
+
+ }
+ }
+
+ return r;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/baseport/syborg/svpframebuffer/svpframebuffer.h Wed Jan 27 14:42:12 2010 +0000
@@ -0,0 +1,297 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Minimalistic frame buffer driver
+*
+*/
+
+#ifndef _SVPFRAMEBUFFER_H
+#define _SVPFRAMEBUFFER_H
+
+#include <display.h>
+
+#include <videodriver.h>
+#include <system.h>
+
+#define __SVPFRAMEBUFFER_DEBUG
+
+#ifdef __SVPFRAMEBUFFER_DEBUG
+
+#define __GCE_DEBUG_PRINT(a) Kern::Printf(a)
+#define __GCE_DEBUG_PRINT2(a,b) Kern::Printf(a,b)
+
+#else
+
+#define __GCE_DEBUG_PRINT(a)
+#define __GCE_DEBUG_PRINT2(a,b)
+
+#endif
+
+// Macro to calculate the screen buffer size
+// aBpp is the number of bits-per-pixel, aPpl is the number of pixels per line and aLpp number of lines per panel
+#define FRAME_BUFFER_SIZE(aBpp,aPpl,aLpp) ((aBpp/8)*aPpl*aLpp)
+
+_LIT(KLitLcd,"SYBORG_FB");
+
+const TUint KConfigLcdWidth = 640;
+const TUint KConfigLcdHeight = 480;
+const TInt KConfigLcdWidthInTwips = 9638;
+const TInt KConfigLcdHeightInTwips = 7370;
+const TBool KConfigIsMono = 0;
+const TBool KConfigIsPalettized = 0;
+const TInt KCOnfigOffsetToFirstPixel = 0;
+const TBool KConfigPixelOrderRGB = 0;
+const TBool KConfigPixelOrderLandscape = 1;
+const TInt KConfigLcdDisplayMode = 2;
+//const TInt KConfigLcdDisplayMode = 1;
+const TInt KConfigLcdNumberOfDisplayModes = 3;
+
+
+const TInt KConfigBitsPerPixel = 24;
+const TInt KCOnfigOffsetBetweenLines = 2560;
+
+const TInt KVSyncDfcPriority = 7 ; //priority of DFC within the queue (0 to 7, where 7 is highest)
+
+/********************************************************************/
+/* Class Definition */
+/********************************************************************/
+/**
+ * This class defines a callback mechanism that is used by a resource user to specify its callback. It contains a
+ * function pointer and data pointer. The function pointer specifies the user callback function to be invoked by the
+ * resource while the data pointer specifies the data to be passed to the callback function.
+ */
+class TLcdUserCallBack
+ {
+public:
+ // The constructor for the callback mechanism.
+ TLcdUserCallBack(TInt (*aFunction)(TUint aResID, TAny* aPtr), TAny* aPtr)
+
+ {
+ iCbFn = aFunction;
+ iDataPtr = aPtr;
+ }
+
+public:
+ // The callback function pointer.
+ TInt (*iCbFn)(TUint aResID, TAny* aPtr);
+
+ // Pointer to the data structure to be passed to the callback function.
+ TAny *iDataPtr;
+ };
+
+class DLcdPowerHandler : public DPowerHandler
+{
+public: // from DPowerHandler
+ void PowerDown(TPowerState);
+ void PowerUp();
+public: // to prevent a race condition with WServer trying to power up/down at the same time
+ void PowerUpDfc();
+ void PowerDownDfc();
+public:
+ DLcdPowerHandler();
+ TInt Create();
+ void DisplayOn();
+ void DisplayOff();
+ TInt HalFunction(TInt aFunction, TAny* a1, TAny* a2);
+
+ void PowerUpLcd(TBool aSecure);
+ void PowerDownLcd();
+
+ void ScreenInfo(TScreenInfoV01& aInfo);
+ void WsSwitchOnScreen();
+ void WsSwitchOffScreen();
+ void HandleMsg(TMessageBase* aMsg);
+ void SwitchDisplay(TBool aSecure);
+
+private:
+ TInt GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure);
+ TInt GetSpecifiedDisplayModeInfo(TInt aMode, TVideoInfoV01& aInfo);
+ TInt SetDisplayMode(TInt aMode);
+ TInt AllocateFrameBuffer();
+
+public:
+ IMPORT_C static TInt RegisterCallback(TLcdUserCallBack* aCbPtr);
+ IMPORT_C static void DeRegisterCallback(TLcdUserCallBack* aCbPtr);
+
+private:
+ TBool iDisplayOn;
+ DPlatChunkHw* iChunk;
+ DPlatChunkHw* iSecureChunk;
+ TBool iWsSwitchOnScreen;
+ TBool iSecureDisplay;
+
+public:
+ TDfcQue* iDfcQ;
+ TMessageQue iMsgQ; // to prevent a race condition with Power Manager trying to power up/down at the same time
+ TDfc iPowerUpDfc;
+ TDfc iPowerDownDfc;
+
+private:
+ NFastMutex iLock;
+ TPhysAddr ivRamPhys;
+ TPhysAddr iSecurevRamPhys;
+ TLcdUserCallBack * iAppCallBk[2];
+
+public:
+ TVideoInfoV01 iVideoInfo;
+ TVideoInfoV01 iSecureVideoInfo;
+ TInt iSize;
+ TLinAddr iPortAddr;
+ TPhysAddr iCompositionPhysical;
+ static DLcdPowerHandler * pLcd;
+
+enum {
+ FB_ID = 0,
+ FB_BASE = 1,
+ FB_HEIGHT = 2,
+ FB_WIDTH = 3,
+ FB_ORIENTATION = 4,
+ FB_BLANK = 5,
+ FB_INT_MASK = 6,
+ /* begin new interface */
+ FB_INTERRUPT_CAUSE = 7,
+ FB_BPP = 8,
+ FB_COLOR_ORDER = 9,
+ FB_BYTE_ORDER = 10,
+ FB_PIXEL_ORDER = 11,
+ FB_ROW_PITCH = 12,
+ FB_ENABLED = 13,
+ FB_PALETTE_START = 0x400 >> 2,
+ FB_PALETTE_END = FB_PALETTE_START+256-1,
+ /* end new interface */
+ };
+
+#define FB_INT_VSYNC (1U << 0)
+#define FB_INT_BASE_UPDATE_DONE (1U << 1)
+
+};
+
+class DDisplayPddSyborg : public DDisplayPdd
+ {
+
+ public:
+ DDisplayPddSyborg();
+ ~DDisplayPddSyborg();
+
+ /**
+ Called by the LDD to handle the device specific part of switching to Legacy mode.
+
+ @return KErrNone if successful; or one of the other system wide error codes.
+ */
+ virtual TInt SetLegacyMode();
+
+ /**
+ Called by the LDD to handle the device specific part of switching to GCE mode.
+
+ @return KErrNone if successful; or one of the other system wide error codes.
+ */
+ virtual TInt SetGceMode();
+
+ /**
+ Called by the LDD to handle the device specific part of setting the rotation.
+
+ @return KErrNone if successful; or one of the other system wide error codes.
+ */
+ virtual TInt SetRotation(TInt aRotation);
+
+ /**
+ Called by the LDD to handle the device specific part of posting a User Buffer.
+
+ @return KErrNone if successful; or one of the other system wide error codes.
+ */
+ virtual TInt PostUserBuffer(TBufferNode* aNode);
+
+ /**
+ Called by the LDD to handle the device specific part of posting a Composition Buffer
+
+ @return KErrNone if successful; or one of the other system wide error codes.
+ */
+ virtual TInt PostCompositionBuffer(TBufferNode* aNode);
+
+ /**
+ Called by the LDD to handle the device specific part of posting the Legacy Buffuer
+
+ @return KErrNone if successful; or one of the other system wide error codes.
+ */
+ virtual TInt PostLegacyBuffer();
+
+ /**
+ Called by the LDD to handle device specific cleanup operations when a channel is closed.
+
+ @return KErrNone if successful; or one of the other system wide error codes.
+ */
+ virtual TInt CloseMsg();
+
+ /**
+ Called by the LDD to handle device specific initialisation tasks when a channel is opened.
+
+ @param aUnit The screen/hardware unit number.
+ @return KErrNone if successful; or one of the other system wide error codes.
+ */
+ virtual TInt CreateChannelSetup(TInt aUnit);
+
+ /**
+ Called by the LDD in order to detect whether a post operation is pending. This type of
+ information is specific to the actual physical device.
+
+ @return ETrue if a Post operation is pending otherwise EFalse.
+ */
+ virtual TBool PostPending();
+
+ /**
+ Called by the LDD to retrieve the DFC Queue created in the PDD.
+
+ @param aUnit The screen/hardware unit number.
+ @return A pointer to the TDfcQue object created in the PDD.
+ */
+ virtual TDfcQue* DfcQ(TInt aUnit);
+
+public:
+ static void VSyncDfcFn(TAny* aChannel);
+
+private:
+ TDfcQue* iDfcQ;
+
+ //generic display info
+ TVideoInfoV01 iScreenInfo;
+
+ //Pointer to a buffer in the Pending state
+ TBufferNode* iPendingBuffer;
+
+ //Pointer to a buffer in the Active state
+ TBufferNode* iActiveBuffer;
+
+ DChunk * iChunk;
+ TLcdUserCallBack* iLcdCallback;
+
+ public:
+ TDfc iVSyncDfc;
+ };
+
+
+/**
+ PDD Factory class
+ */
+
+class DDisplayPddFactory : public DPhysicalDevice
+ {
+public:
+ DDisplayPddFactory();
+
+ virtual TInt Install();
+ virtual void GetCaps(TDes8& aDes) const;
+ virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer);
+ virtual TInt Validate(TInt aDeviceType, const TDesC8* anInfo, const TVersion& aVer);
+ };
+
+#endif