omap3530/beagle_drivers/lcd/lcd.cpp
changeset 0 6663340f3fc9
child 25 524118fd998f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omap3530/beagle_drivers/lcd/lcd.cpp	Thu Oct 15 12:59:54 2009 +0100
@@ -0,0 +1,1241 @@
+// Copyright (c) 2004-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:
+// omap3530/beagle_drivers/lcd/lcd.cpp
+// Implementation of an LCD driver. 
+// This file is part of the Beagle Base port
+// N.B. This sample code assumes that the display supports setting the backlight on or off, 
+// as well as adjusting the contrast and the brightness.
+//
+
+
+
+
+
+#include <videodriver.h>
+#include <platform.h>
+#include <nkern.h>
+#include <kernel.h>
+#include <kern_priv.h>
+#include <kpower.h>
+#include <assp/omap3530_assp/omap3530_assp_priv.h>
+#include <assp/omap3530_assp/omap3530_hardware_base.h>
+#include <assp/omap3530_assp/omap3530_prcm.h>
+
+#define DSS_SYSCONFIG				0x48050010
+#define DISPC_SYSSTATUS				0x48050414
+
+#define DISPC_SYSCONFIG				0x48050410
+#define DISPC_CONFIG				0x48050444
+#define DISPC_DEFAULT_COLOR0		0x4805044c
+#define DISPC_TRANS_COLOR0			0x48050454
+
+#define DISPC_TIMING_H				0x48050464
+#define DISPC_TIMING_V				0x48050468
+#define DISPC_POL_FREQ				0x4805046c
+#define DISPC_DIVISOR				0x48050470
+#define DISPC_SIZE_LCD				0x4805047c
+
+#define DISPC_GFX_BA1				0x48050480
+#define DISPC_GFX_BA2				0x48050484
+#define DISPC_GFX_POSITION			0x48050488
+#define DISPC_GFX_SIZE				0x4805048c
+#define DISPC_GFX_ATTRIBUTES		0x480504a0
+
+#define DISPC_GFX_FIFO_THRESHOLD	0x480504a4
+#define DISPC_GFX_FIFO_SIZE_STATUS	0x480504a8
+#define DISPC_GFX_ROW_INC			0x480504ac
+#define DISPC_GFX_PIXEL_INC			0x480504b0
+#define DISPC_GFX_WINDOW_SKIP		0x480504b4
+#define DISPC_GFX_TABLE_BA			0x480504b8
+
+#define DISPC_CONTROL				0x48050440
+
+#define GET_REGISTER(Reg)		*( (TUint *) Omap3530HwBase::TVirtual<Reg>::Value )
+#define SET_REGISTER(Reg,Val)	*( (TUint *) Omap3530HwBase::TVirtual<Reg>::Value ) = Val
+
+#define _MODE_1280x1024_
+//#define _MODE_1024x768_
+#ifdef _MODE_800x600_
+// ModeLine       "800x600@60" 40.0 800 840 968 1056 600 601 605 628 +hsync +vsync
+// Decoded by: http://www.tkk.fi/Misc/Electronics/faq/vga2rgb/calc.html
+#	define PIXEL_CLK	40000
+#	define H_DISP		800
+#	define H_FPORCH	40
+#	define H_SYNC		128
+#	define H_BPORCH	88
+#	define H_SYNC_POL	1
+#	define V_DISP		600
+#	define V_FPORCH	1
+#	define V_SYNC		4
+#	define V_BPORCH	23
+#	define V_SYNC_POL	1
+#	define INTERLACE_ENABLE	0
+#endif
+#ifdef _MODE_1024x768_
+// ModeLine       "1024x768@60" 65.0 1024 1048 1184 1344 768 771 777 806 -hsync -vsync
+// Decoded by: http://www.tkk.fi/Misc/Electronics/faq/vga2rgb/calc.html
+#	define PIXEL_CLK	65000
+#	define H_DISP		1024
+#	define H_FPORCH	24
+#	define H_SYNC		136
+#	define H_BPORCH	160
+#	define H_SYNC_POL	0
+#	define V_DISP		768
+#	define V_FPORCH	3
+#	define V_SYNC		6
+#	define V_BPORCH	29
+#	define V_SYNC_POL	0
+#	define INTERLACE_ENABLE	0
+#endif
+#ifdef _MODE_1280x1024_
+// ModeLine "1280x1024@60" 108.0 1280 1328 1440 1688 1024 1025 1028 1066 +hsync +vsync
+// Decoded by: http://www.tkk.fi/Misc/Electronics/faq/vga2rgb/calc.html
+#	define PIXEL_CLK	108000
+#	define H_DISP		1280
+#	define H_FPORCH	48
+#	define H_SYNC		112
+#	define H_BPORCH	248
+#	define H_SYNC_POL	1
+#	define V_DISP		1024
+#	define V_FPORCH	1
+#	define V_SYNC		3
+#	define V_BPORCH	38
+#	define V_SYNC_POL	1
+#	define INTERLACE_ENABLE	0
+#endif
+
+
+
+// TO DO: (mandatory)
+// If the display supports Contrast and/or Brightness control then supply the following defines:
+// This is only example code... you may need to modify it for your hardware
+const TInt KConfigInitialDisplayContrast	= 128;
+const TInt KConfigLcdMinDisplayContrast		= 1;
+const TInt KConfigLcdMaxDisplayContrast		= 255;
+const TInt KConfigInitialDisplayBrightness	= 128;
+const TInt KConfigLcdMinDisplayBrightness	= 1;
+const TInt KConfigLcdMaxDisplayBrightness	= 255;
+
+// TO DO: (mandatory)
+// define a macro to calculate the screen buffer size
+// This is only example code... you may need to modify it for your hardware
+// 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*aPpl*aLpp)/8	
+																
+
+// TO DO: (mandatory)
+// define the physical screen dimensions
+// This is only example code... you need to modify it for your hardware
+const TUint	KConfigLcdWidth					= 360;//640;		// 640 pixels per line
+const TUint	KConfigLcdHeight				= 640;//480;		// 480 lines per panel
+
+// TO DO: (mandatory)
+// define the characteristics of the LCD display
+// This is only example code... you need to modify it for your hardware
+const TBool	KConfigLcdIsMono				= EFalse;
+const TBool	KConfigLcdPixelOrderLandscape	= ETrue;
+const TBool	KConfigLcdPixelOrderRGB			= ETrue;
+const TInt	KConfigLcdMaxDisplayColors		= 65536;	//24bit: 16777216;
+
+
+// TO DO: (mandatory)
+// define the display dimensions in TWIPs
+// A TWIP is a 20th of a point.  A point is a 72nd of an inch
+// Therefore a TWIP is a 1440th of an inch
+// This is only example code... you need to modify it for your hardware
+const TInt	KConfigLcdWidthInTwips			= 9638;//10800;		// = 6.69 inches	//15*1440;
+const TInt	KConfigLcdHeightInTwips			= 7370;//11232;//5616;		// = 5.11 inches	//12*1440;
+
+// TO DO: (mandatory)
+// define the available display modes
+// This is only example code... you need to modify it for your hardware
+const TInt  KConfigLcdNumberOfDisplayModes	= 1;
+const TInt  KConfigLcdInitialDisplayMode	= 0;
+struct SLcdConfig
+	{
+	TInt iMode;
+	TInt iOffsetToFirstVideoBuffer;
+	TInt iLenghtOfVideoBufferInBytes;
+	TInt iOffsetBetweenLines;
+	TBool iIsPalettized;
+	TInt iBitsPerPixel;
+	};
+static const SLcdConfig Lcd_Mode_Config[KConfigLcdNumberOfDisplayModes]=
+	{
+		{
+		0,								// iMode
+		0,								// iOffsetToFirstVideoBuffer
+		FRAME_BUFFER_SIZE(16, KConfigLcdWidth, KConfigLcdHeight),	// iLenghtOfVideoBufferInBytes
+		KConfigLcdWidth*2,				// iOffsetBetweenLines
+		EFalse,							// iIsPalettized
+		16								// iBitsPerPixel
+		}
+	};	
+
+
+
+_LIT(KLitLcd,"LCD");
+
+//
+// TO DO: (optional)
+//
+// Add any private functions and data you require
+//
+NONSHARABLE_CLASS(DLcdPowerHandler) : public DPowerHandler
+	{
+public: 
+	DLcdPowerHandler();
+	
+	// from DPowerHandler
+	void PowerDown(TPowerState);
+	void PowerUp();
+
+	void PowerUpDfc();
+	void PowerDownDfc();
+
+	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();
+	void SwitchDisplay(TBool aSecure);
+
+	void SetBacklightState(TBool aState);
+	void BacklightOn();
+	void BacklightOff();
+	TInt SetContrast(TInt aContrast);
+	TInt SetBrightness(TInt aBrightness);
+
+private:
+	TInt SetPaletteEntry(TInt aEntry, TInt aColor);
+	TInt GetPaletteEntry(TInt aEntry, TInt* aColor);
+	TInt NumberOfPaletteEntries();
+	TInt GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure);
+	TInt GetSpecifiedDisplayModeInfo(TInt aMode, TVideoInfoV01& aInfo);
+	TInt SetDisplayMode(TInt aMode);
+	void SplashScreen();
+	TInt GetDisplayColors(TInt* aColors);
+
+private:
+	TBool iIsPalettized;
+	TBool iDisplayOn;				// to prevent a race condition with WServer trying to power up/down at the same time
+	DPlatChunkHw* iChunk;
+	DPlatChunkHw* iSecureChunk;
+	TBool iWsSwitchOnScreen;
+ 	TBool iSecureDisplay;
+	TDfcQue* iDfcQ;
+	TMessageQue iMsgQ;
+	TDfc iPowerUpDfc;
+	TDfc iPowerDownDfc;	
+	TVideoInfoV01 iVideoInfo;
+	TVideoInfoV01 iSecureVideoInfo;
+	NFastMutex iLock;				// protects against being preempted whilst manipulating iVideoInfo/iSecureVideoInfo
+	TPhysAddr ivRamPhys;
+	TPhysAddr iSecurevRamPhys;
+	
+	TBool iBacklightOn;
+	TInt iContrast;
+	TInt iBrightness;
+	};
+
+
+/**
+HAL handler function
+
+@param	aPtr a pointer to an instance of DLcdPowerHandler
+@param	aFunction the function number
+@param	a1 an arbitrary parameter
+@param	a2 an arbitrary parameter
+*/
+LOCAL_C TInt halFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2)
+	{
+	DLcdPowerHandler* pH=(DLcdPowerHandler*)aPtr;
+	return pH->HalFunction(aFunction,a1,a2);
+	}
+
+/**
+DFC for receiving messages from the power handler
+@param	aPtr a pointer to an instance of DLcdPowerHandler
+*/
+void rxMsg(TAny* aPtr)
+	{
+	DLcdPowerHandler& h=*(DLcdPowerHandler*)aPtr;
+	h.HandleMsg();
+	}
+
+/**
+DFC for powering up the device
+
+@param aPtr	aPtr a pointer to an instance of DLcdPowerHandler
+*/
+void power_up_dfc(TAny* aPtr)
+	{
+	((DLcdPowerHandler*)aPtr)->PowerUpDfc();
+	}
+
+/**
+DFC for powering down the device
+
+@param aPtr	aPtr a pointer to an instance of DLcdPowerHandler
+*/
+void power_down_dfc(TAny* aPtr)
+	{
+	((DLcdPowerHandler*)aPtr)->PowerDownDfc();
+	}
+
+
+/**
+Default constructor
+*/
+DLcdPowerHandler::DLcdPowerHandler() :
+		DPowerHandler(KLitLcd),
+		iMsgQ(rxMsg,this,NULL,1),
+		iPowerUpDfc(&power_up_dfc,this,6),
+		iPowerDownDfc(&power_down_dfc,this,7),
+		iBacklightOn(EFalse),
+		iContrast(KConfigInitialDisplayContrast),
+		iBrightness(KConfigInitialDisplayBrightness)
+	{
+	}
+
+
+/**
+Second-phase constructor 
+
+Called by factory function at ordinal 0
+*/
+TInt DLcdPowerHandler::Create()
+	{
+	iDfcQ=Kern::DfcQue0();	// use low priority DFC queue for this driver 
+
+	// map the video RAM
+	
+	//TPhysAddr videoRamPhys;
+	TInt vSize = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iLenghtOfVideoBufferInBytes; //KConfigLcdWidth*KConfigLcdHeight*3; //VideoRamSize();
+	TInt r = Epoc::AllocPhysicalRam( 2*vSize, ivRamPhys );
+	if ( r!=KErrNone )
+		{
+		Kern::Fault( "AllocVRam", r );
+		}
+	
+	//TInt vSize = ((Omap3530BoardAssp*)Arch::TheAsic())->VideoRamSize();
+	//ivRamPhys = TOmap3530Assp::VideoRamPhys();				// EXAMPLE ONLY: assume TOmap3530Assp interface class
+	r = DPlatChunkHw::New(iChunk,ivRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC);
+	if (r != KErrNone)
+		return r;	
+	
+	//create "secure" screen immediately after normal one
+	iSecurevRamPhys =  ivRamPhys + vSize;
+	TInt r2 = DPlatChunkHw::New(iSecureChunk,iSecurevRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC);
+	if (r2 != KErrNone)
+		return r2;
+	
+	TUint* pV=(TUint*)iChunk->LinearAddress();	
+	
+	__KTRACE_OPT(KEXTENSION,Kern::Printf("DLcdPowerHandler::Create: VideoRamSize=%x, VideoRamPhys=%08x, VideoRamLin=%08x",vSize,ivRamPhys,pV));
+	
+	// TO DO: (mandatory)
+	// initialise the palette for the initial display mode
+	// NOTE: the palette could either be a buffer allocated in system RAM (usually contiguous to Video buffer)
+	//		 or could be offered as part of the hardware block that implemenst the lcd control
+	//
+
+	TUint* pV2=(TUint*)iSecureChunk->LinearAddress();
+
+	__KTRACE_OPT(KEXTENSION,Kern::Printf("DLcdPowerHandler::Create: Secure display VideoRamSize=%x, VideoRamPhys=%08x, VideoRamLin=%08x",vSize,iSecurevRamPhys,pV2));
+
+	// TO DO: (mandatory)
+	// initialise the secure screen's palette for the initial display mode
+	//
+	
+	// setup the video info structure, this'll be used to remember the video settings
+	iVideoInfo.iDisplayMode = KConfigLcdInitialDisplayMode;
+	iVideoInfo.iOffsetToFirstPixel = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iOffsetToFirstVideoBuffer;
+	iVideoInfo.iIsPalettized = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iIsPalettized;
+	iVideoInfo.iOffsetBetweenLines = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iOffsetBetweenLines;
+	iVideoInfo.iBitsPerPixel = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iBitsPerPixel;
+
+	iVideoInfo.iSizeInPixels.iWidth = KConfigLcdWidth;
+	iVideoInfo.iSizeInPixels.iHeight = KConfigLcdHeight;
+	iVideoInfo.iSizeInTwips.iWidth = KConfigLcdWidthInTwips;
+	iVideoInfo.iSizeInTwips.iHeight = KConfigLcdHeightInTwips;
+	iVideoInfo.iIsMono = KConfigLcdIsMono;
+	iVideoInfo.iVideoAddress=(TInt)pV;
+	iVideoInfo.iIsPixelOrderLandscape = KConfigLcdPixelOrderLandscape;
+	iVideoInfo.iIsPixelOrderRGB = KConfigLcdPixelOrderRGB;
+
+	iSecureVideoInfo = iVideoInfo;
+	iSecureVideoInfo.iVideoAddress = (TInt)pV2;
+
+	iDisplayOn = EFalse;
+	iSecureDisplay = EFalse;
+
+	// install the HAL function
+	r=Kern::AddHalEntry(EHalGroupDisplay, halFunction, this);
+	if (r!=KErrNone)
+		return r;
+
+	iPowerUpDfc.SetDfcQ(iDfcQ);
+	iPowerDownDfc.SetDfcQ(iDfcQ);
+	iMsgQ.SetDfcQ(iDfcQ);
+	iMsgQ.Receive();
+
+	// install the power handler
+	// power up the screen
+	Add();
+	DisplayOn();
+	
+	SplashScreen();
+	
+	return KErrNone;
+	}
+
+/**
+Turn the display on
+May be called as a result of a power transition or from the HAL
+If called from HAL, then the display may be already be on (iDisplayOn == ETrue)
+*/
+void DLcdPowerHandler::DisplayOn()
+	{
+	__KTRACE_OPT(KBOOT, Kern::Printf("DisplayOn %d", iDisplayOn));
+	if (!iDisplayOn)				// may have been powered up already
+		{
+		iDisplayOn = ETrue;
+		PowerUpLcd(iSecureDisplay);
+		SetContrast(iContrast);
+		SetBrightness(iBrightness);
+		}
+	}
+
+/**
+Turn the display off
+May be called as a result of a power transition or from the HAL
+If called from Power Manager, then the display may be already be off (iDisplayOn == EFalse)
+if the platform is in silent running mode
+*/
+void DLcdPowerHandler::DisplayOff()
+	{
+	__KTRACE_OPT(KBOOT, Kern::Printf("DisplayOff %d", iDisplayOn));
+	if (iDisplayOn)
+		{
+		iDisplayOn = EFalse;
+		PowerDownLcd();
+		}
+	}
+
+/**
+Switch between secure and non-secure displays
+
+@param aSecure ETrue if switching to secure display
+*/
+void DLcdPowerHandler::SwitchDisplay(TBool aSecure)
+ 	{
+ 	if (aSecure)
+ 		{
+ 		if (!iSecureDisplay)
+ 			{
+ 			//switch to secure display
+ 			DisplayOff();
+ 			iSecureDisplay = ETrue;
+ 			DisplayOn();
+ 			}
+ 		}
+ 	else
+ 		{
+ 		if (iSecureDisplay)
+ 			{
+ 			//switch from secure display
+ 			DisplayOff();
+ 			iSecureDisplay = EFalse;
+ 			DisplayOn();
+ 			}
+ 		}
+ 	}
+
+/**
+DFC to power up the display
+*/
+void DLcdPowerHandler::PowerUpDfc()
+	{
+	__KTRACE_OPT(KPOWER, Kern::Printf("PowerUpDfc"));
+	DisplayOn();
+
+	PowerUpDone();				// must be called from a different thread than PowerUp()
+	}
+
+/**
+DFC to power down the display
+*/
+void DLcdPowerHandler::PowerDownDfc()
+	{
+	__KTRACE_OPT(KPOWER, Kern::Printf("PowerDownDfc"));
+	DisplayOff();
+	PowerDownDone();			// must be called from a different thread than PowerUp()
+	}
+
+/**
+Schedule the power-down DFC
+*/
+void DLcdPowerHandler::PowerDown(TPowerState)
+	{
+	iPowerDownDfc.Enque();		// schedules DFC to execute on this driver's thread
+	}
+
+/**
+Schedule the power-up DFC
+*/
+void DLcdPowerHandler::PowerUp()
+	{
+	iPowerUpDfc.Enque();		// schedules DFC to execute on this driver's thread
+	}
+
+/**
+Power up the display
+
+@param aSecure ETrue if powering up the secure display
+*/
+void DLcdPowerHandler::PowerUpLcd(TBool aSecure)
+    {
+	
+	TUint32 l = 0x0;
+	
+	// Set up the Display Subsystem to control a DVI monitor
+	
+    // The following four lines need to be replaced by a call to the GPIO driver which should call the PowerClock driver
+//	PowerClock::GpioActive(0, PowerClock::E1s, PowerClock::ECpu10, PowerClock::EBus10);
+//	PowerClock::GpioAccess(0, PowerClock::EAuto);
+	Prcm::SetClockState( Prcm::EClkGpio1_F, Prcm::EClkOn );
+	Prcm::SetClockState( Prcm::EClkGpio1_I, Prcm::EClkAuto );
+	*( (TUint *) Omap3530HwBase::TVirtual<0x48310034>::Value ) = 0xfefffedf;		//GPIO1 output enable	p3336
+	*( (TUint *) Omap3530HwBase::TVirtual<0x48310094>::Value ) = 0x01000120;		//GPIO1 set data out	p3336
+//	const TUint KCM_CLKSEL_DSS = Omap3530HwBase::TVirtual<0x48004E40>::Value;
+//	Prcm::Set(KCM_CLKSEL_DSS, 0xffffffffu, 0x00001006);
+
+	Prcm::SetDivider( Prcm::EClkDss1_F, 2 );
+	Prcm::SetDivider( Prcm::EClkTv_F, 1 );
+	
+	
+	SET_REGISTER( DSS_SYSCONFIG, 0x00000010 );			// Display Subsystem reset
+	while ( !( GET_REGISTER( DISPC_SYSSTATUS ) & 1 ) );	// Spin until reset complete
+	
+	TInt8 MIDLEMODE		= 0x2;	// Smart Standby. MStandby is asserted based on the internal activity of the module.
+	TInt8 CLOCKACTIVITY = 0x0;	// interface and functional clocks can be switched off.
+	TInt8 SIDLEMODE		= 0x2;	// Smart idle. Idle request is acknowledged based on the internal activity of the module
+	TInt8 ENWAKEUP		= 0x1;	// Wakeup is enabled.
+	TInt8 SOFTRESET		= 0x0;	// Normal mode
+	TInt8 AUTOIDLE		= 0x1;	// Automatic L3 and L4 interface clock gating strategy is applied based on interface activity
+	l = MIDLEMODE<<12 | CLOCKACTIVITY<<8 | SIDLEMODE<<3 | ENWAKEUP<<2 | SOFTRESET<<1 | AUTOIDLE;
+	SET_REGISTER( DISPC_SYSCONFIG, l );
+	
+	TInt8 LOADMOAD = 0x2; 		//Frame data only loaded every frame
+	l = LOADMOAD<<1;
+	SET_REGISTER( DISPC_CONFIG, l );
+	
+	SET_REGISTER( DISPC_DEFAULT_COLOR0, 0xFFFFFFFF );
+	SET_REGISTER( DISPC_TRANS_COLOR0, 0x00000000 );
+	
+	TUint8 hbp = H_BPORCH - 1;	// Horizontal Back Porch
+	TUint8 hfp = H_FPORCH - 1;	// Horizontal front porch
+	TUint8 hsw = H_SYNC - 1;	// Horizontal synchronization pulse width
+	if ( hsw > 63 )
+		{
+		hsw = 63;
+		Kern::Printf("[LCD] H_SYNC too big");
+		}
+	l = hbp<<20 | hfp<<8 | hsw;
+	SET_REGISTER( DISPC_TIMING_H, l );
+	
+	TUint8 vbp = V_BPORCH;		// Vertical back porch
+	TUint8 vfp = V_FPORCH;		// Vertical front porch
+	TUint8 vsw = V_SYNC;		// Vertical synchronization pulse width
+	__ASSERT_ALWAYS( vbp<=255, Kern::Fault("LCD", 1) );
+	__ASSERT_ALWAYS( vfp<=255, Kern::Fault("LCD", 1) );
+	__ASSERT_ALWAYS( vsw>=1 && vsw<=255, Kern::Fault("LCD", 1) );
+	l = vbp<<20 | vfp<<8 | vsw;
+	SET_REGISTER( DISPC_TIMING_V, l );
+	
+	TUint8 onoff= 0;
+	TUint8 rf	= 0;
+	TUint8 ieo 	= 0;
+	TUint8 ipc	= 1;			// Invert Pixel Clock
+	TUint8 ihs	= H_SYNC_POL ? 0 : 1;	// Invert HSYNC (0: Positive Sync polarity, 1: Negative Sync polarity)
+	TUint8 ivs	= V_SYNC_POL ? 0 : 1;	// Invert VSYNC (0: Positive Sync polarity, 1: Negative Sync polarity)
+	TUint8 acbi	= 0;
+	TUint16 acb	= 0x28;			// AC-bias pin frequency
+	l = onoff<<17 | rf<<16 | ieo<<15 | ipc<<14 | ihs<<13 | ivs<<12 | acbi<<8 | acb;
+	SET_REGISTER( DISPC_POL_FREQ, l );
+	
+	TUint8 lcd = 1;				// Display Controller Logic Clock Divisor
+	TUint8 pcd = ( 432000 + (PIXEL_CLK - 1) ) / PIXEL_CLK; // Pixel Clock Divisor - add (PIXEL_CLK - 1) to avoid rounding error
+	__ASSERT_ALWAYS( lcd>=1 && lcd<=255, Kern::Fault("LCD", 1) );
+	__ASSERT_ALWAYS( pcd>=2 && pcd<=255, Kern::Fault("LCD", 1) );
+	l = lcd<<16 | pcd;
+	SET_REGISTER( DISPC_DIVISOR, l );
+	
+	TUint16 ppl = H_DISP - 1;	// Pixels per line
+	TUint16 llp = V_DISP - 1;	// Lines per panel
+	__ASSERT_ALWAYS( ppl>=1 && ppl<=2048, Kern::Fault("LCD", 1) );
+	__ASSERT_ALWAYS( llp>=1 && llp<=2048, Kern::Fault("LCD", 1) );
+	l = llp<<16 | ppl;
+	SET_REGISTER( DISPC_SIZE_LCD, l );
+	
+	
+	// Setup a graphics region (GFX)
+	
+	// Set GFX frame buffer
+	SET_REGISTER( DISPC_GFX_BA1, ivRamPhys );
+	
+	// Center the GFX
+	TInt16 gfxposy	= ( V_DISP - KConfigLcdHeight ) / 2;
+	TInt16 gfxposx	= ( H_DISP - KConfigLcdWidth ) / 2;
+	l = ( gfxposy << 16 ) | gfxposx;
+	SET_REGISTER( DISPC_GFX_POSITION, l );
+	
+	// Set the GFX dimensions
+	TInt16 gfxsizey = KConfigLcdHeight - 1;
+	TInt16 gfxsizex = KConfigLcdWidth - 1;
+	l = gfxsizey<<16 | gfxsizex;
+	SET_REGISTER( DISPC_GFX_SIZE, l );
+	
+	TInt8 GFXSELFREFRESH		= 0x0;
+	TInt8 GFXARBITRATION		= 0x0;
+	TInt8 GFXROTATION			= 0x0;
+	TInt8 GFXFIFOPRELOAD		= 0x0;
+	TInt8 GFXENDIANNESS			= 0x0;
+	TInt8 GFXNIBBLEMODE			= 0x0;
+	TInt8 GFXCHANNELOUT			= 0x0;
+	TInt8 GFXBURSTSIZE			= 0x2;	// 16x32bit bursts
+	TInt8 GFXREPLICATIONENABLE	= 0x0;	// Disable Graphics replication logic
+	TInt8 GFXFORMAT				= 0x6;	// RGB16=0x6, RGB24-unpacked=0x8, RGB24-packed=0x9
+	TInt8 GFXENABLE				= 0x1;	// Graphics enabled
+	l = GFXSELFREFRESH<<15 | GFXARBITRATION<<14 | GFXROTATION<<12 | GFXFIFOPRELOAD<<11 | GFXENDIANNESS<<10 | GFXNIBBLEMODE<<9 | GFXCHANNELOUT<8 | GFXBURSTSIZE<<6 | GFXREPLICATIONENABLE<<5 | GFXFORMAT<<1 | GFXENABLE;
+	SET_REGISTER( DISPC_GFX_ATTRIBUTES, l );
+	
+	TInt16 GFXFIFOHIGHTHRESHOLD	= 0x3fc;	// Graphics FIFO High Threshold
+	TInt16 GFXFIFOLOWTHRESHOLD	= 0x3BC;	// Graphics FIFO Low Threshold
+	l = GFXFIFOHIGHTHRESHOLD<<16 | GFXFIFOLOWTHRESHOLD;
+	SET_REGISTER(DISPC_GFX_FIFO_THRESHOLD, l);
+	
+	TInt16 GFXFIFOSIZE = 0x400;	// Number of bytes defining the FIFO value
+	l = GFXFIFOSIZE;
+	SET_REGISTER(DISPC_GFX_FIFO_SIZE_STATUS, l);
+	
+	TInt32 GFXROWINC	= 0x1;
+	l = GFXROWINC;
+	SET_REGISTER(DISPC_GFX_ROW_INC, l);
+	
+	TInt16	GFXPIXELINC	= 0x1;
+	l = GFXPIXELINC;
+	SET_REGISTER(DISPC_GFX_PIXEL_INC, l);
+	
+	TInt32 GFXWINDOWSKIP = 0x0;
+	l = GFXWINDOWSKIP;
+	SET_REGISTER(DISPC_GFX_WINDOW_SKIP, l);
+	
+	// TO DO: Sort out the Gamma table + pallets
+	TInt32 GFXTABLEBA	= 0x807ff000;
+	l = GFXTABLEBA;
+	SET_REGISTER(DISPC_GFX_TABLE_BA, l);
+	
+	
+	// Propigate all the shadowed registers 
+	
+	TInt8 SPATIALTEMPORALDITHERINGFRAMES	= 0;
+	TInt8 LCDENABLEPOL			= 0;
+	TInt8 LCDENABLESIGNAL		= 0;
+	TInt8 PCKFREEENABLE			= 0;
+	TInt8 TDMUNUSEDBITS			= 0;
+	TInt8 TDMCYCLEFORMAT		= 0;
+	TInt8 TDMPARALLELMODE		= 0;
+	TInt8 TDMENABLE				= 0;
+	TInt8 HT					= 0;
+	TInt8 GPOUT1				= 1;
+	TInt8 GPOUT0				= 1;
+	TInt8 GPIN1					= 0;
+	TInt8 GPIN0					= 0;
+	TInt8 OVERLAYOPTIMIZATION	= 0;
+	TInt8 RFBIMODE				= 0;
+	TInt8 SECURE				= 0;
+	TInt8 TFTDATALINES			= 0x3;
+	TInt8 STDITHERENABLE		= 0;
+	TInt8 GODIGITAL				= 1;
+	TInt8 GOLCD					= 1;
+	TInt8 M8B					= 0;
+	TInt8 STNTFT				= 1;
+	TInt8 MONOCOLOR				= 0;
+	TInt8 DIGITALENABLE			= 1;
+	TInt8 LCDENABLE				= 1;	
+	l = SPATIALTEMPORALDITHERINGFRAMES<<30 | LCDENABLEPOL<<29 | LCDENABLESIGNAL<<28 | PCKFREEENABLE<<27 | 
+		TDMUNUSEDBITS<<25 | TDMCYCLEFORMAT<<23 | TDMPARALLELMODE<<21 | TDMENABLE<<20 | HT<<17 | GPOUT1<<16 | 
+			GPOUT0<<15 | GPIN1<<14 | GPIN0<<13 | OVERLAYOPTIMIZATION<<12 | 	RFBIMODE<<11 | SECURE<<10 |
+				TFTDATALINES<<8 | STDITHERENABLE<<7 | GODIGITAL<<6 | GOLCD<<5 | M8B<<4 | STNTFT<<3 |
+					MONOCOLOR<<2 | DIGITALENABLE<<1 | LCDENABLE;
+	NKern::Sleep(1);
+	SET_REGISTER(DISPC_CONTROL, l);
+	NKern::Sleep(1);
+	
+    }
+
+
+/**
+Power down the display and the backlight
+*/
+void DLcdPowerHandler::PowerDownLcd()
+    {
+	SetBacklightState(EFalse);
+
+	// TO DO: (mandatory)
+	// Power down the display & disable LCD DMA.
+	// May need to wait until the current frame has been output
+	//
+	
+	SET_REGISTER(DISPC_CONTROL, 0);
+	
+    }
+
+/**
+Set the Lcd contrast
+
+@param aValue the contrast setting
+*/
+TInt DLcdPowerHandler::SetContrast(TInt aValue)
+	{
+	__KTRACE_OPT(KEXTENSION,Kern::Printf("SetContrast(%d)", aValue));
+
+	if (aValue >= KConfigLcdMinDisplayContrast && aValue <= KConfigLcdMaxDisplayContrast)
+		{
+		iContrast=aValue;
+		
+		// TO DO: (mandatory)
+		// set the contrast
+		//
+		return KErrNone;
+		}
+
+	return KErrArgument;
+	}
+
+/**
+Set the Lcd brightness
+
+@param aValue the brightness setting
+*/
+TInt DLcdPowerHandler::SetBrightness(TInt aValue)
+	{
+	__KTRACE_OPT(KEXTENSION,Kern::Printf("SetBrightness(%d)", aValue));
+
+	if (aValue >= KConfigLcdMinDisplayBrightness && aValue <= KConfigLcdMaxDisplayBrightness)
+		{
+		iBrightness=aValue;
+
+		// TO DO: (mandatory)
+		// set the brightness
+		//
+		return KErrNone;
+		}
+	return KErrArgument;
+	}
+
+/**
+Turn the backlight on
+*/
+void DLcdPowerHandler::BacklightOn()
+    {
+	// TO DO: (mandatory)
+	// turn the backlight on
+	//
+    }
+
+/**
+Turn the backlight off
+*/
+void DLcdPowerHandler::BacklightOff()
+    {
+	// TO DO: (mandatory)
+	// turn the backlight off
+	//
+    }
+
+/**
+Set the state of the backlight
+
+@param aState ETrue if setting the backlight on
+*/
+void DLcdPowerHandler::SetBacklightState(TBool aState)
+	{
+	iBacklightOn=aState;
+	if (iBacklightOn)
+		BacklightOn();
+	else
+		BacklightOff();
+	}
+
+void DLcdPowerHandler::ScreenInfo(TScreenInfoV01& anInfo)
+	{
+	__KTRACE_OPT(KEXTENSION,Kern::Printf("DLcdPowerHandler::ScreenInfo"));
+	anInfo.iWindowHandleValid=EFalse;
+	anInfo.iWindowHandle=NULL;
+	anInfo.iScreenAddressValid=ETrue;
+	anInfo.iScreenAddress=(TAny *)(iChunk->LinearAddress());
+	anInfo.iScreenSize.iWidth=KConfigLcdWidth;
+	anInfo.iScreenSize.iHeight=KConfigLcdHeight;
+	}
+
+/**
+Handle a message from the power handler
+*/
+void DLcdPowerHandler::HandleMsg(void)
+	{
+	
+	TMessageBase* msg = iMsgQ.iMessage;
+	if (msg == NULL)
+		return;
+
+	if (msg->iValue)
+		DisplayOn();
+	else
+		DisplayOff();
+	msg->Complete(KErrNone,ETrue);
+	}
+
+/**
+Send a message to the power-handler message queue to turn the display on
+*/
+void DLcdPowerHandler::WsSwitchOnScreen()
+	{
+	TThreadMessage& m=Kern::Message();
+	m.iValue = ETrue;
+	m.SendReceive(&iMsgQ);		// send a message and block Client thread until keyboard has been powered up
+	}
+
+/**
+Send a message to the power-handler message queue to turn the display off
+*/
+void DLcdPowerHandler::WsSwitchOffScreen()
+	{
+	TThreadMessage& m=Kern::Message();
+	m.iValue = EFalse;
+	m.SendReceive(&iMsgQ);		// send a message and block Client thread until keyboard has been powered down
+	}
+
+/**
+Return information about the current display mode
+
+@param	aInfo a structure supplied by the caller to be filled by this function.
+@param	aSecure ETrue if requesting information about the secure display
+@return	KErrNone if successful
+*/
+TInt DLcdPowerHandler::GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure)
+	{
+	__KTRACE_OPT(KEXTENSION,Kern::Printf("GetCurrentDisplayModeInfo"));
+	NKern::FMWait(&iLock);
+	if (aSecure)
+ 		aInfo = iSecureVideoInfo;
+ 	else
+ 		aInfo = iVideoInfo;
+	NKern::FMSignal(&iLock);
+	return KErrNone;
+	}
+
+/**
+Return information about the specified display mode
+
+@param	aMode the display mode to query
+@param	aInfo a structure supplied by the caller to be filled by this function.
+@return	KErrNone if successful
+*/
+TInt DLcdPowerHandler::GetSpecifiedDisplayModeInfo(TInt aMode, TVideoInfoV01& aInfo)
+	{
+	__KTRACE_OPT(KEXTENSION,Kern::Printf("GetSpecifiedDisplayModeInfo mode is %d",aMode));
+
+	if (aMode < 0 || aMode >= KConfigLcdNumberOfDisplayModes)
+		return KErrArgument;
+
+	NKern::FMWait(&iLock);
+	aInfo = iVideoInfo;
+	NKern::FMSignal(&iLock);
+
+	if (aMode != aInfo.iDisplayMode)
+		{
+		aInfo.iOffsetToFirstPixel=Lcd_Mode_Config[aMode].iOffsetToFirstVideoBuffer;
+		aInfo.iIsPalettized = Lcd_Mode_Config[aMode].iIsPalettized;
+		aInfo.iOffsetBetweenLines=Lcd_Mode_Config[aMode].iOffsetBetweenLines;
+		aInfo.iBitsPerPixel = Lcd_Mode_Config[aMode].iBitsPerPixel;
+		}
+	return KErrNone;
+	}
+
+/**
+Set the display mode
+
+@param	aMode the display mode to set
+*/
+TInt DLcdPowerHandler::SetDisplayMode(TInt aMode)
+	{
+
+	__KTRACE_OPT(KEXTENSION,Kern::Printf("SetDisplayMode = %d", aMode));
+
+	if (aMode < 0 || aMode >= KConfigLcdNumberOfDisplayModes)
+		return KErrArgument;
+
+	NKern::FMWait(&iLock);
+
+	// store the current mode
+	iVideoInfo.iDisplayMode = aMode;
+	iVideoInfo.iOffsetToFirstPixel = Lcd_Mode_Config[aMode].iOffsetToFirstVideoBuffer;
+	iVideoInfo.iIsPalettized = Lcd_Mode_Config[aMode].iIsPalettized;
+	iVideoInfo.iOffsetBetweenLines = Lcd_Mode_Config[aMode].iOffsetBetweenLines;
+	iVideoInfo.iBitsPerPixel = Lcd_Mode_Config[aMode].iBitsPerPixel;
+
+	// store the current mode for secure screen
+	iSecureVideoInfo.iDisplayMode = aMode;
+	iSecureVideoInfo.iOffsetToFirstPixel = Lcd_Mode_Config[aMode].iOffsetToFirstVideoBuffer;
+	iSecureVideoInfo.iIsPalettized = Lcd_Mode_Config[aMode].iIsPalettized;
+	iSecureVideoInfo.iOffsetBetweenLines = Lcd_Mode_Config[aMode].iOffsetBetweenLines;
+	iSecureVideoInfo.iBitsPerPixel = Lcd_Mode_Config[aMode].iBitsPerPixel;
+	
+	// TO DO: (mandatory)
+	// set bits per pixel on hardware
+	// May need to reconfigure DMA if video buffer size and location have changed
+	//
+	NKern::FMSignal(&iLock);
+
+	__KTRACE_OPT(KEXTENSION,Kern::Printf("SetDisplayMode mode = %d, otfp = %d, palettized = %d, bpp = %d, obl = %d",
+		aMode, iVideoInfo.iOffsetToFirstPixel, iVideoInfo.iIsPalettized, iVideoInfo.iBitsPerPixel, iVideoInfo.iOffsetBetweenLines));
+
+	return KErrNone;
+	}
+
+/**
+Fill the video memory with an initial pattern or image
+This will be displayed on boot-up
+*/
+void DLcdPowerHandler::SplashScreen()
+	{
+	// TO DO: (optional)
+	// replace the example code below to display a different spash screen
+	
+	__KTRACE_OPT(KEXTENSION,Kern::Printf("Splash SCreen +"));
+	TUint* pV=(TUint*)(iVideoInfo.iVideoAddress + iVideoInfo.iOffsetToFirstPixel);
+	__KTRACE_OPT(KEXTENSION,Kern::Printf("Splash SCreen FB @ %x",pV));
+	
+	//Fill the framebuffer with bars
+	
+	for (TInt y = 0; y<KConfigLcdHeight; ++y)
+		{
+		for(TInt x = 0; x<KConfigLcdHeight; ++x)
+			{
+			TUint8 r = 0x00;
+			TUint8 g = 0x00;
+			TUint8 b = 0x00;
+			TUint16 rgb = ((r&0xf8) << 8) | ((g&0xfc) << 3) | ((b&0xf8) >> 3);
+			
+			TUint16* px = reinterpret_cast<TUint16*>(pV) + y*KConfigLcdWidth + x;
+			*px = rgb;
+			}
+		}
+	
+	__KTRACE_OPT(KEXTENSION,Kern::Printf("Splash SCreen -"));
+	}
+
+
+/**
+Get the size of the pallete
+
+@return	the number of pallete entries
+*/
+TInt DLcdPowerHandler::NumberOfPaletteEntries()		//only call when holding mutex
+	{
+	// TO DO: (mandatory)
+	// Calculate the number of Palette entries - this is normally 
+	// calculated from the bits per-pixel.
+	// This is only example code... you may need to modify it for your hardware
+	//
+	TInt num = iVideoInfo.iIsPalettized ? 1<<iVideoInfo.iBitsPerPixel : 0;
+
+	__KTRACE_OPT(KEXTENSION,Kern::Printf("NumberOfPaletteEntries = %d", num));
+
+	return num;
+	}
+
+
+/** 
+Retrieve the palette entry at a particular offset
+
+@param	aEntry the palette index
+@param	aColor a caller-supplied pointer to a location where the returned RGB color is to be stored
+@return	KErrNone if successful
+		KErrNotSupported if the current vide mode does not support a palette
+		KErrArgument if aEntry is out of range
+*/
+TInt DLcdPowerHandler::GetPaletteEntry(TInt aEntry, TInt* aColor)
+	{
+	NKern::FMWait(&iLock);
+	if (!iVideoInfo.iIsPalettized)
+		{
+		NKern::FMSignal(&iLock);
+		return KErrNotSupported;
+		}
+
+	if ((aEntry < 0) || (aEntry >= NumberOfPaletteEntries()))
+		{
+		NKern::FMSignal(&iLock);
+		return KErrArgument;
+		}
+
+	// TO DO: (mandatory)
+	// read the RGB value of the palette entry into aColor
+	// NOTE: the palette could either be a buffer allocated in system RAM (usually contiguous to Video buffer)
+	//		 or could be offered as part of the hardware block that implemenst the lcd control
+	//
+	NKern::FMSignal(&iLock);
+
+	__KTRACE_OPT(KEXTENSION,Kern::Printf("GetPaletteEntry %d color 0x%x", aEntry, aColor));
+
+	return KErrNone;
+	}
+
+/** 
+Set the palette entry at a particular offset
+
+@param	aEntry the palette index
+@param	aColor the RGB color to store
+@return	KErrNone if successful
+		KErrNotSupported if the current vide mode does not support a palette
+		KErrArgument if aEntry is out of range
+*/
+TInt DLcdPowerHandler::SetPaletteEntry(TInt aEntry, TInt aColor)
+	{
+
+	NKern::FMWait(&iLock);
+	if (!iVideoInfo.iIsPalettized)
+		{
+		NKern::FMSignal(&iLock);
+		return KErrNotSupported;
+		}
+
+	if ((aEntry < 0) || (aEntry >= NumberOfPaletteEntries()))	//check entry in range
+		{
+		NKern::FMSignal(&iLock);
+		return KErrArgument;
+		}
+
+	// TO DO: (mandatory)
+	// update the palette entry for the secure and non-secure screen
+	// NOTE: the palette could either be a buffer allocated in system RAM (usually contiguous to Video buffer)
+	//		 or could be offered as part of the hardware block that implemenst the lcd control
+	//
+	__KTRACE_OPT(KEXTENSION,Kern::Printf("SetPaletteEntry %d to 0x%x", aEntry, aColor ));
+
+	return KErrNone;
+	}
+
+/**
+a HAL entry handling function for HAL group attribute EHalGroupDisplay
+
+@param	a1 an arbitrary argument
+@param	a2 an arbitrary argument
+@return	KErrNone if successful
+*/
+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 EDisplayHalMaxDisplayContrast:
+			{
+			TInt mc=KConfigLcdMaxDisplayContrast;
+			kumemput32(a1,&mc,sizeof(mc));
+			break;
+			}
+		case EDisplayHalSetDisplayContrast:
+			__KTRACE_OPT(KEXTENSION,Kern::Printf("EDisplayHalSetDisplayContrast"));
+			if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetDisplayContrast")))
+				return KErrPermissionDenied;
+			r=SetContrast(TInt(a1));
+			break;
+		
+		case EDisplayHalDisplayContrast:
+			kumemput32(a1,&iContrast,sizeof(iContrast));
+			break;
+
+		case EDisplayHalMaxDisplayBrightness:
+			{
+			TInt mc=KConfigLcdMaxDisplayBrightness;
+			kumemput32(a1,&mc,sizeof(mc));
+			break;
+			}
+		
+		case EDisplayHalSetDisplayBrightness:
+			__KTRACE_OPT(KEXTENSION,Kern::Printf("EDisplayHalSetDisplayBrightness"));
+			if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetDisplayBrightness")))
+				return KErrPermissionDenied;
+			r=SetBrightness(TInt(a1));
+			break;
+		
+		case EDisplayHalDisplayBrightness:
+			kumemput32(a1,&iBrightness,sizeof(iBrightness));
+			break;
+		
+		case EDisplayHalSetBacklightOn:
+			if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetBacklightOn")))
+				return KErrPermissionDenied;
+			if (Kern::MachinePowerStatus()<ELow)
+				r=KErrBadPower;
+			else
+				SetBacklightState(TBool(a1));
+			break;
+		
+		case EDisplayHalBacklightOn:
+			kumemput32(a1,&iBacklightOn,sizeof(TInt));
+			break;
+
+		case EDisplayHalModeCount:
+			{
+			TInt ndm = KConfigLcdNumberOfDisplayModes;
+			kumemput32(a1, &ndm, sizeof(ndm));
+			break;
+			}
+		
+		case EDisplayHalSetMode:
+			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));
+			break;
+
+		case EDisplayHalSetPaletteEntry:
+			if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetPaletteEntry")))
+				return KErrPermissionDenied;
+			r = SetPaletteEntry((TInt)a1, (TInt)a2);
+			break;
+		
+		case EDisplayHalPaletteEntry:
+			{
+			TInt entry;
+			kumemget32(&entry, a1, sizeof(TInt));
+			TInt x;
+			r = GetPaletteEntry(entry, &x);
+			if (r == KErrNone)
+				kumemput32(a2, &x, sizeof(x));
+			break;
+			}
+		
+		case EDisplayHalSetState:
+			{
+			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 = KConfigLcdMaxDisplayColors;
+			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:
+			{
+			if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetSecure")))
+				return KErrPermissionDenied;
+			SwitchDisplay((TBool)a1);
+			}
+			break;
+
+		default:
+			r=KErrNotSupported;
+			break;
+		}
+	return r;
+	}
+
+
+DECLARE_STANDARD_EXTENSION()
+	{
+	__KTRACE_OPT(KPOWER,Kern::Printf("Starting LCD power manager"));
+
+	// create LCD power handler
+	TInt r=KErrNoMemory;
+	DLcdPowerHandler* pH=new DLcdPowerHandler;
+	if (pH)
+		r=pH->Create();
+
+	__KTRACE_OPT(KPOWER,Kern::Printf("Returns %d",r));
+	return r;
+	}
+