diff -r 000000000000 -r ffa851df0825 baseport/src/cedar/generic/base/syborg/fb/syborg_fb.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/src/cedar/generic/base/syborg/fb/syborg_fb.cpp Fri Jul 31 14:43:15 2009 +0100 @@ -0,0 +1,487 @@ +/* +* 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 +#include "syborg_fb.h" + +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; + +#if 0 + WriteReg(iPortAddr, FB_ENABLED, 0); + WriteReg(IPortAddr, FB_INT_MASK, 0); + WriteReg(iPortAddr, FB_BASE, iSecureDisplay ? iSecurevRamPhys : ivRamPhys); + WriteReg(iPortAddr, FB_WIDTH, iVideoInfo.iSizeInPixels.iWidth); + WriteReg(iPortAddr, FB_HEIGHT, iVideoInfo.iSizeInPixels.iHeight); + WriteReg(iPortAddr, FB_BLANK, 0); + WriteReg(iPortAddr, FB_ENABLED, 1); +#endif + + 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 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 vPckg; + r = GetCurrentDisplayModeInfo(vPckg(), (TBool)a2); + if(KErrNone == r) + Kern::InfoCopy(*(TDes8*)a1,vPckg); + break; + } + case EDisplayHalSpecifiedModeInfo: + { + TPckgBuf 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() +{ + iDfcQ = Kern::DfcQue0(); // use low priority DFC queue for this driver + + iPortAddr = KHwBaseClcd; + + // !@! +#if 0 + // Map the video RAM + TInt vSize = TSyborg::VideoRamSize(); + ivRamPhys = TSyborg::VideoRamPhys(); + + TInt r = DPlatChunkHw::New(iChunk,ivRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC); + if(r != KErrNone) + return r; + + TUint* pV = (TUint*)iChunk->LinearAddress(); + + iSecurevRamPhys = ivRamPhys + vSize; + TInt r2 = DPlatChunkHw::New(iSecureChunk,iSecurevRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC); + if(r2 != KErrNone) + return r2; + + TUint* pV2 = (TUint*)iSecureChunk->LinearAddress(); +#endif + + 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; + + AllocateFrameBuffer(); + TInt r = Kern::AddHalEntry(EHalGroupDisplay,DoHalFunction,this); + if(r != KErrNone) + return r; + + iPowerUpDfc.SetDfcQ(iDfcQ); + iPowerDownDfc.SetDfcQ(iDfcQ); + iMsgQ.SetDfcQ(iDfcQ); + iMsgQ.Receive(); + + Add(); + DisplayOn(); + + return KErrNone; +} + +DECLARE_STANDARD_EXTENSION() +{ + TInt r = KErrNoMemory; + DLcdPowerHandler* pH=new DLcdPowerHandler; + if(pH) + r = pH->Create(); + + return r; +}