omap3530/beagle_drivers/lcd/lcd.cpp
changeset 0 6663340f3fc9
child 21 524118fd998f
equal deleted inserted replaced
-1:000000000000 0:6663340f3fc9
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // omap3530/beagle_drivers/lcd/lcd.cpp
       
    15 // Implementation of an LCD driver. 
       
    16 // This file is part of the Beagle Base port
       
    17 // N.B. This sample code assumes that the display supports setting the backlight on or off, 
       
    18 // as well as adjusting the contrast and the brightness.
       
    19 //
       
    20 
       
    21 
       
    22 
       
    23 
       
    24 
       
    25 #include <videodriver.h>
       
    26 #include <platform.h>
       
    27 #include <nkern.h>
       
    28 #include <kernel.h>
       
    29 #include <kern_priv.h>
       
    30 #include <kpower.h>
       
    31 #include <assp/omap3530_assp/omap3530_assp_priv.h>
       
    32 #include <assp/omap3530_assp/omap3530_hardware_base.h>
       
    33 #include <assp/omap3530_assp/omap3530_prcm.h>
       
    34 
       
    35 #define DSS_SYSCONFIG				0x48050010
       
    36 #define DISPC_SYSSTATUS				0x48050414
       
    37 
       
    38 #define DISPC_SYSCONFIG				0x48050410
       
    39 #define DISPC_CONFIG				0x48050444
       
    40 #define DISPC_DEFAULT_COLOR0		0x4805044c
       
    41 #define DISPC_TRANS_COLOR0			0x48050454
       
    42 
       
    43 #define DISPC_TIMING_H				0x48050464
       
    44 #define DISPC_TIMING_V				0x48050468
       
    45 #define DISPC_POL_FREQ				0x4805046c
       
    46 #define DISPC_DIVISOR				0x48050470
       
    47 #define DISPC_SIZE_LCD				0x4805047c
       
    48 
       
    49 #define DISPC_GFX_BA1				0x48050480
       
    50 #define DISPC_GFX_BA2				0x48050484
       
    51 #define DISPC_GFX_POSITION			0x48050488
       
    52 #define DISPC_GFX_SIZE				0x4805048c
       
    53 #define DISPC_GFX_ATTRIBUTES		0x480504a0
       
    54 
       
    55 #define DISPC_GFX_FIFO_THRESHOLD	0x480504a4
       
    56 #define DISPC_GFX_FIFO_SIZE_STATUS	0x480504a8
       
    57 #define DISPC_GFX_ROW_INC			0x480504ac
       
    58 #define DISPC_GFX_PIXEL_INC			0x480504b0
       
    59 #define DISPC_GFX_WINDOW_SKIP		0x480504b4
       
    60 #define DISPC_GFX_TABLE_BA			0x480504b8
       
    61 
       
    62 #define DISPC_CONTROL				0x48050440
       
    63 
       
    64 #define GET_REGISTER(Reg)		*( (TUint *) Omap3530HwBase::TVirtual<Reg>::Value )
       
    65 #define SET_REGISTER(Reg,Val)	*( (TUint *) Omap3530HwBase::TVirtual<Reg>::Value ) = Val
       
    66 
       
    67 #define _MODE_1280x1024_
       
    68 //#define _MODE_1024x768_
       
    69 #ifdef _MODE_800x600_
       
    70 // ModeLine       "800x600@60" 40.0 800 840 968 1056 600 601 605 628 +hsync +vsync
       
    71 // Decoded by: http://www.tkk.fi/Misc/Electronics/faq/vga2rgb/calc.html
       
    72 #	define PIXEL_CLK	40000
       
    73 #	define H_DISP		800
       
    74 #	define H_FPORCH	40
       
    75 #	define H_SYNC		128
       
    76 #	define H_BPORCH	88
       
    77 #	define H_SYNC_POL	1
       
    78 #	define V_DISP		600
       
    79 #	define V_FPORCH	1
       
    80 #	define V_SYNC		4
       
    81 #	define V_BPORCH	23
       
    82 #	define V_SYNC_POL	1
       
    83 #	define INTERLACE_ENABLE	0
       
    84 #endif
       
    85 #ifdef _MODE_1024x768_
       
    86 // ModeLine       "1024x768@60" 65.0 1024 1048 1184 1344 768 771 777 806 -hsync -vsync
       
    87 // Decoded by: http://www.tkk.fi/Misc/Electronics/faq/vga2rgb/calc.html
       
    88 #	define PIXEL_CLK	65000
       
    89 #	define H_DISP		1024
       
    90 #	define H_FPORCH	24
       
    91 #	define H_SYNC		136
       
    92 #	define H_BPORCH	160
       
    93 #	define H_SYNC_POL	0
       
    94 #	define V_DISP		768
       
    95 #	define V_FPORCH	3
       
    96 #	define V_SYNC		6
       
    97 #	define V_BPORCH	29
       
    98 #	define V_SYNC_POL	0
       
    99 #	define INTERLACE_ENABLE	0
       
   100 #endif
       
   101 #ifdef _MODE_1280x1024_
       
   102 // ModeLine "1280x1024@60" 108.0 1280 1328 1440 1688 1024 1025 1028 1066 +hsync +vsync
       
   103 // Decoded by: http://www.tkk.fi/Misc/Electronics/faq/vga2rgb/calc.html
       
   104 #	define PIXEL_CLK	108000
       
   105 #	define H_DISP		1280
       
   106 #	define H_FPORCH	48
       
   107 #	define H_SYNC		112
       
   108 #	define H_BPORCH	248
       
   109 #	define H_SYNC_POL	1
       
   110 #	define V_DISP		1024
       
   111 #	define V_FPORCH	1
       
   112 #	define V_SYNC		3
       
   113 #	define V_BPORCH	38
       
   114 #	define V_SYNC_POL	1
       
   115 #	define INTERLACE_ENABLE	0
       
   116 #endif
       
   117 
       
   118 
       
   119 
       
   120 // TO DO: (mandatory)
       
   121 // If the display supports Contrast and/or Brightness control then supply the following defines:
       
   122 // This is only example code... you may need to modify it for your hardware
       
   123 const TInt KConfigInitialDisplayContrast	= 128;
       
   124 const TInt KConfigLcdMinDisplayContrast		= 1;
       
   125 const TInt KConfigLcdMaxDisplayContrast		= 255;
       
   126 const TInt KConfigInitialDisplayBrightness	= 128;
       
   127 const TInt KConfigLcdMinDisplayBrightness	= 1;
       
   128 const TInt KConfigLcdMaxDisplayBrightness	= 255;
       
   129 
       
   130 // TO DO: (mandatory)
       
   131 // define a macro to calculate the screen buffer size
       
   132 // This is only example code... you may need to modify it for your hardware
       
   133 // aBpp is the number of bits-per-pixel, aPpl is the number of pixels per line and 
       
   134 // aLpp number of lines per panel
       
   135 #define FRAME_BUFFER_SIZE(aBpp,aPpl,aLpp)	(aBpp*aPpl*aLpp)/8	
       
   136 																
       
   137 
       
   138 // TO DO: (mandatory)
       
   139 // define the physical screen dimensions
       
   140 // This is only example code... you need to modify it for your hardware
       
   141 const TUint	KConfigLcdWidth					= 360;//640;		// 640 pixels per line
       
   142 const TUint	KConfigLcdHeight				= 640;//480;		// 480 lines per panel
       
   143 
       
   144 // TO DO: (mandatory)
       
   145 // define the characteristics of the LCD display
       
   146 // This is only example code... you need to modify it for your hardware
       
   147 const TBool	KConfigLcdIsMono				= EFalse;
       
   148 const TBool	KConfigLcdPixelOrderLandscape	= ETrue;
       
   149 const TBool	KConfigLcdPixelOrderRGB			= ETrue;
       
   150 const TInt	KConfigLcdMaxDisplayColors		= 65536;	//24bit: 16777216;
       
   151 
       
   152 
       
   153 // TO DO: (mandatory)
       
   154 // define the display dimensions in TWIPs
       
   155 // A TWIP is a 20th of a point.  A point is a 72nd of an inch
       
   156 // Therefore a TWIP is a 1440th of an inch
       
   157 // This is only example code... you need to modify it for your hardware
       
   158 const TInt	KConfigLcdWidthInTwips			= 9638;//10800;		// = 6.69 inches	//15*1440;
       
   159 const TInt	KConfigLcdHeightInTwips			= 7370;//11232;//5616;		// = 5.11 inches	//12*1440;
       
   160 
       
   161 // TO DO: (mandatory)
       
   162 // define the available display modes
       
   163 // This is only example code... you need to modify it for your hardware
       
   164 const TInt  KConfigLcdNumberOfDisplayModes	= 1;
       
   165 const TInt  KConfigLcdInitialDisplayMode	= 0;
       
   166 struct SLcdConfig
       
   167 	{
       
   168 	TInt iMode;
       
   169 	TInt iOffsetToFirstVideoBuffer;
       
   170 	TInt iLenghtOfVideoBufferInBytes;
       
   171 	TInt iOffsetBetweenLines;
       
   172 	TBool iIsPalettized;
       
   173 	TInt iBitsPerPixel;
       
   174 	};
       
   175 static const SLcdConfig Lcd_Mode_Config[KConfigLcdNumberOfDisplayModes]=
       
   176 	{
       
   177 		{
       
   178 		0,								// iMode
       
   179 		0,								// iOffsetToFirstVideoBuffer
       
   180 		FRAME_BUFFER_SIZE(16, KConfigLcdWidth, KConfigLcdHeight),	// iLenghtOfVideoBufferInBytes
       
   181 		KConfigLcdWidth*2,				// iOffsetBetweenLines
       
   182 		EFalse,							// iIsPalettized
       
   183 		16								// iBitsPerPixel
       
   184 		}
       
   185 	};	
       
   186 
       
   187 
       
   188 
       
   189 _LIT(KLitLcd,"LCD");
       
   190 
       
   191 //
       
   192 // TO DO: (optional)
       
   193 //
       
   194 // Add any private functions and data you require
       
   195 //
       
   196 NONSHARABLE_CLASS(DLcdPowerHandler) : public DPowerHandler
       
   197 	{
       
   198 public: 
       
   199 	DLcdPowerHandler();
       
   200 	
       
   201 	// from DPowerHandler
       
   202 	void PowerDown(TPowerState);
       
   203 	void PowerUp();
       
   204 
       
   205 	void PowerUpDfc();
       
   206 	void PowerDownDfc();
       
   207 
       
   208 	TInt Create();
       
   209 	void DisplayOn();
       
   210 	void DisplayOff();
       
   211 	TInt HalFunction(TInt aFunction, TAny* a1, TAny* a2);
       
   212 
       
   213 	void PowerUpLcd(TBool aSecure);
       
   214 	void PowerDownLcd();
       
   215 
       
   216 	void ScreenInfo(TScreenInfoV01& aInfo);
       
   217 	void WsSwitchOnScreen();
       
   218 	void WsSwitchOffScreen();
       
   219 	void HandleMsg();
       
   220 	void SwitchDisplay(TBool aSecure);
       
   221 
       
   222 	void SetBacklightState(TBool aState);
       
   223 	void BacklightOn();
       
   224 	void BacklightOff();
       
   225 	TInt SetContrast(TInt aContrast);
       
   226 	TInt SetBrightness(TInt aBrightness);
       
   227 
       
   228 private:
       
   229 	TInt SetPaletteEntry(TInt aEntry, TInt aColor);
       
   230 	TInt GetPaletteEntry(TInt aEntry, TInt* aColor);
       
   231 	TInt NumberOfPaletteEntries();
       
   232 	TInt GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure);
       
   233 	TInt GetSpecifiedDisplayModeInfo(TInt aMode, TVideoInfoV01& aInfo);
       
   234 	TInt SetDisplayMode(TInt aMode);
       
   235 	void SplashScreen();
       
   236 	TInt GetDisplayColors(TInt* aColors);
       
   237 
       
   238 private:
       
   239 	TBool iIsPalettized;
       
   240 	TBool iDisplayOn;				// to prevent a race condition with WServer trying to power up/down at the same time
       
   241 	DPlatChunkHw* iChunk;
       
   242 	DPlatChunkHw* iSecureChunk;
       
   243 	TBool iWsSwitchOnScreen;
       
   244  	TBool iSecureDisplay;
       
   245 	TDfcQue* iDfcQ;
       
   246 	TMessageQue iMsgQ;
       
   247 	TDfc iPowerUpDfc;
       
   248 	TDfc iPowerDownDfc;	
       
   249 	TVideoInfoV01 iVideoInfo;
       
   250 	TVideoInfoV01 iSecureVideoInfo;
       
   251 	NFastMutex iLock;				// protects against being preempted whilst manipulating iVideoInfo/iSecureVideoInfo
       
   252 	TPhysAddr ivRamPhys;
       
   253 	TPhysAddr iSecurevRamPhys;
       
   254 	
       
   255 	TBool iBacklightOn;
       
   256 	TInt iContrast;
       
   257 	TInt iBrightness;
       
   258 	};
       
   259 
       
   260 
       
   261 /**
       
   262 HAL handler function
       
   263 
       
   264 @param	aPtr a pointer to an instance of DLcdPowerHandler
       
   265 @param	aFunction the function number
       
   266 @param	a1 an arbitrary parameter
       
   267 @param	a2 an arbitrary parameter
       
   268 */
       
   269 LOCAL_C TInt halFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2)
       
   270 	{
       
   271 	DLcdPowerHandler* pH=(DLcdPowerHandler*)aPtr;
       
   272 	return pH->HalFunction(aFunction,a1,a2);
       
   273 	}
       
   274 
       
   275 /**
       
   276 DFC for receiving messages from the power handler
       
   277 @param	aPtr a pointer to an instance of DLcdPowerHandler
       
   278 */
       
   279 void rxMsg(TAny* aPtr)
       
   280 	{
       
   281 	DLcdPowerHandler& h=*(DLcdPowerHandler*)aPtr;
       
   282 	h.HandleMsg();
       
   283 	}
       
   284 
       
   285 /**
       
   286 DFC for powering up the device
       
   287 
       
   288 @param aPtr	aPtr a pointer to an instance of DLcdPowerHandler
       
   289 */
       
   290 void power_up_dfc(TAny* aPtr)
       
   291 	{
       
   292 	((DLcdPowerHandler*)aPtr)->PowerUpDfc();
       
   293 	}
       
   294 
       
   295 /**
       
   296 DFC for powering down the device
       
   297 
       
   298 @param aPtr	aPtr a pointer to an instance of DLcdPowerHandler
       
   299 */
       
   300 void power_down_dfc(TAny* aPtr)
       
   301 	{
       
   302 	((DLcdPowerHandler*)aPtr)->PowerDownDfc();
       
   303 	}
       
   304 
       
   305 
       
   306 /**
       
   307 Default constructor
       
   308 */
       
   309 DLcdPowerHandler::DLcdPowerHandler() :
       
   310 		DPowerHandler(KLitLcd),
       
   311 		iMsgQ(rxMsg,this,NULL,1),
       
   312 		iPowerUpDfc(&power_up_dfc,this,6),
       
   313 		iPowerDownDfc(&power_down_dfc,this,7),
       
   314 		iBacklightOn(EFalse),
       
   315 		iContrast(KConfigInitialDisplayContrast),
       
   316 		iBrightness(KConfigInitialDisplayBrightness)
       
   317 	{
       
   318 	}
       
   319 
       
   320 
       
   321 /**
       
   322 Second-phase constructor 
       
   323 
       
   324 Called by factory function at ordinal 0
       
   325 */
       
   326 TInt DLcdPowerHandler::Create()
       
   327 	{
       
   328 	iDfcQ=Kern::DfcQue0();	// use low priority DFC queue for this driver 
       
   329 
       
   330 	// map the video RAM
       
   331 	
       
   332 	//TPhysAddr videoRamPhys;
       
   333 	TInt vSize = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iLenghtOfVideoBufferInBytes; //KConfigLcdWidth*KConfigLcdHeight*3; //VideoRamSize();
       
   334 	TInt r = Epoc::AllocPhysicalRam( 2*vSize, ivRamPhys );
       
   335 	if ( r!=KErrNone )
       
   336 		{
       
   337 		Kern::Fault( "AllocVRam", r );
       
   338 		}
       
   339 	
       
   340 	//TInt vSize = ((Omap3530BoardAssp*)Arch::TheAsic())->VideoRamSize();
       
   341 	//ivRamPhys = TOmap3530Assp::VideoRamPhys();				// EXAMPLE ONLY: assume TOmap3530Assp interface class
       
   342 	r = DPlatChunkHw::New(iChunk,ivRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC);
       
   343 	if (r != KErrNone)
       
   344 		return r;	
       
   345 	
       
   346 	//create "secure" screen immediately after normal one
       
   347 	iSecurevRamPhys =  ivRamPhys + vSize;
       
   348 	TInt r2 = DPlatChunkHw::New(iSecureChunk,iSecurevRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC);
       
   349 	if (r2 != KErrNone)
       
   350 		return r2;
       
   351 	
       
   352 	TUint* pV=(TUint*)iChunk->LinearAddress();	
       
   353 	
       
   354 	__KTRACE_OPT(KEXTENSION,Kern::Printf("DLcdPowerHandler::Create: VideoRamSize=%x, VideoRamPhys=%08x, VideoRamLin=%08x",vSize,ivRamPhys,pV));
       
   355 	
       
   356 	// TO DO: (mandatory)
       
   357 	// initialise the palette for the initial display mode
       
   358 	// NOTE: the palette could either be a buffer allocated in system RAM (usually contiguous to Video buffer)
       
   359 	//		 or could be offered as part of the hardware block that implemenst the lcd control
       
   360 	//
       
   361 
       
   362 	TUint* pV2=(TUint*)iSecureChunk->LinearAddress();
       
   363 
       
   364 	__KTRACE_OPT(KEXTENSION,Kern::Printf("DLcdPowerHandler::Create: Secure display VideoRamSize=%x, VideoRamPhys=%08x, VideoRamLin=%08x",vSize,iSecurevRamPhys,pV2));
       
   365 
       
   366 	// TO DO: (mandatory)
       
   367 	// initialise the secure screen's palette for the initial display mode
       
   368 	//
       
   369 	
       
   370 	// setup the video info structure, this'll be used to remember the video settings
       
   371 	iVideoInfo.iDisplayMode = KConfigLcdInitialDisplayMode;
       
   372 	iVideoInfo.iOffsetToFirstPixel = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iOffsetToFirstVideoBuffer;
       
   373 	iVideoInfo.iIsPalettized = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iIsPalettized;
       
   374 	iVideoInfo.iOffsetBetweenLines = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iOffsetBetweenLines;
       
   375 	iVideoInfo.iBitsPerPixel = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iBitsPerPixel;
       
   376 
       
   377 	iVideoInfo.iSizeInPixels.iWidth = KConfigLcdWidth;
       
   378 	iVideoInfo.iSizeInPixels.iHeight = KConfigLcdHeight;
       
   379 	iVideoInfo.iSizeInTwips.iWidth = KConfigLcdWidthInTwips;
       
   380 	iVideoInfo.iSizeInTwips.iHeight = KConfigLcdHeightInTwips;
       
   381 	iVideoInfo.iIsMono = KConfigLcdIsMono;
       
   382 	iVideoInfo.iVideoAddress=(TInt)pV;
       
   383 	iVideoInfo.iIsPixelOrderLandscape = KConfigLcdPixelOrderLandscape;
       
   384 	iVideoInfo.iIsPixelOrderRGB = KConfigLcdPixelOrderRGB;
       
   385 
       
   386 	iSecureVideoInfo = iVideoInfo;
       
   387 	iSecureVideoInfo.iVideoAddress = (TInt)pV2;
       
   388 
       
   389 	iDisplayOn = EFalse;
       
   390 	iSecureDisplay = EFalse;
       
   391 
       
   392 	// install the HAL function
       
   393 	r=Kern::AddHalEntry(EHalGroupDisplay, halFunction, this);
       
   394 	if (r!=KErrNone)
       
   395 		return r;
       
   396 
       
   397 	iPowerUpDfc.SetDfcQ(iDfcQ);
       
   398 	iPowerDownDfc.SetDfcQ(iDfcQ);
       
   399 	iMsgQ.SetDfcQ(iDfcQ);
       
   400 	iMsgQ.Receive();
       
   401 
       
   402 	// install the power handler
       
   403 	// power up the screen
       
   404 	Add();
       
   405 	DisplayOn();
       
   406 	
       
   407 	SplashScreen();
       
   408 	
       
   409 	return KErrNone;
       
   410 	}
       
   411 
       
   412 /**
       
   413 Turn the display on
       
   414 May be called as a result of a power transition or from the HAL
       
   415 If called from HAL, then the display may be already be on (iDisplayOn == ETrue)
       
   416 */
       
   417 void DLcdPowerHandler::DisplayOn()
       
   418 	{
       
   419 	__KTRACE_OPT(KBOOT, Kern::Printf("DisplayOn %d", iDisplayOn));
       
   420 	if (!iDisplayOn)				// may have been powered up already
       
   421 		{
       
   422 		iDisplayOn = ETrue;
       
   423 		PowerUpLcd(iSecureDisplay);
       
   424 		SetContrast(iContrast);
       
   425 		SetBrightness(iBrightness);
       
   426 		}
       
   427 	}
       
   428 
       
   429 /**
       
   430 Turn the display off
       
   431 May be called as a result of a power transition or from the HAL
       
   432 If called from Power Manager, then the display may be already be off (iDisplayOn == EFalse)
       
   433 if the platform is in silent running mode
       
   434 */
       
   435 void DLcdPowerHandler::DisplayOff()
       
   436 	{
       
   437 	__KTRACE_OPT(KBOOT, Kern::Printf("DisplayOff %d", iDisplayOn));
       
   438 	if (iDisplayOn)
       
   439 		{
       
   440 		iDisplayOn = EFalse;
       
   441 		PowerDownLcd();
       
   442 		}
       
   443 	}
       
   444 
       
   445 /**
       
   446 Switch between secure and non-secure displays
       
   447 
       
   448 @param aSecure ETrue if switching to secure display
       
   449 */
       
   450 void DLcdPowerHandler::SwitchDisplay(TBool aSecure)
       
   451  	{
       
   452  	if (aSecure)
       
   453  		{
       
   454  		if (!iSecureDisplay)
       
   455  			{
       
   456  			//switch to secure display
       
   457  			DisplayOff();
       
   458  			iSecureDisplay = ETrue;
       
   459  			DisplayOn();
       
   460  			}
       
   461  		}
       
   462  	else
       
   463  		{
       
   464  		if (iSecureDisplay)
       
   465  			{
       
   466  			//switch from secure display
       
   467  			DisplayOff();
       
   468  			iSecureDisplay = EFalse;
       
   469  			DisplayOn();
       
   470  			}
       
   471  		}
       
   472  	}
       
   473 
       
   474 /**
       
   475 DFC to power up the display
       
   476 */
       
   477 void DLcdPowerHandler::PowerUpDfc()
       
   478 	{
       
   479 	__KTRACE_OPT(KPOWER, Kern::Printf("PowerUpDfc"));
       
   480 	DisplayOn();
       
   481 
       
   482 	PowerUpDone();				// must be called from a different thread than PowerUp()
       
   483 	}
       
   484 
       
   485 /**
       
   486 DFC to power down the display
       
   487 */
       
   488 void DLcdPowerHandler::PowerDownDfc()
       
   489 	{
       
   490 	__KTRACE_OPT(KPOWER, Kern::Printf("PowerDownDfc"));
       
   491 	DisplayOff();
       
   492 	PowerDownDone();			// must be called from a different thread than PowerUp()
       
   493 	}
       
   494 
       
   495 /**
       
   496 Schedule the power-down DFC
       
   497 */
       
   498 void DLcdPowerHandler::PowerDown(TPowerState)
       
   499 	{
       
   500 	iPowerDownDfc.Enque();		// schedules DFC to execute on this driver's thread
       
   501 	}
       
   502 
       
   503 /**
       
   504 Schedule the power-up DFC
       
   505 */
       
   506 void DLcdPowerHandler::PowerUp()
       
   507 	{
       
   508 	iPowerUpDfc.Enque();		// schedules DFC to execute on this driver's thread
       
   509 	}
       
   510 
       
   511 /**
       
   512 Power up the display
       
   513 
       
   514 @param aSecure ETrue if powering up the secure display
       
   515 */
       
   516 void DLcdPowerHandler::PowerUpLcd(TBool aSecure)
       
   517     {
       
   518 	
       
   519 	TUint32 l = 0x0;
       
   520 	
       
   521 	// Set up the Display Subsystem to control a DVI monitor
       
   522 	
       
   523     // The following four lines need to be replaced by a call to the GPIO driver which should call the PowerClock driver
       
   524 //	PowerClock::GpioActive(0, PowerClock::E1s, PowerClock::ECpu10, PowerClock::EBus10);
       
   525 //	PowerClock::GpioAccess(0, PowerClock::EAuto);
       
   526 	Prcm::SetClockState( Prcm::EClkGpio1_F, Prcm::EClkOn );
       
   527 	Prcm::SetClockState( Prcm::EClkGpio1_I, Prcm::EClkAuto );
       
   528 	*( (TUint *) Omap3530HwBase::TVirtual<0x48310034>::Value ) = 0xfefffedf;		//GPIO1 output enable	p3336
       
   529 	*( (TUint *) Omap3530HwBase::TVirtual<0x48310094>::Value ) = 0x01000120;		//GPIO1 set data out	p3336
       
   530 //	const TUint KCM_CLKSEL_DSS = Omap3530HwBase::TVirtual<0x48004E40>::Value;
       
   531 //	Prcm::Set(KCM_CLKSEL_DSS, 0xffffffffu, 0x00001006);
       
   532 
       
   533 	Prcm::SetDivider( Prcm::EClkDss1_F, 2 );
       
   534 	Prcm::SetDivider( Prcm::EClkTv_F, 1 );
       
   535 	
       
   536 	
       
   537 	SET_REGISTER( DSS_SYSCONFIG, 0x00000010 );			// Display Subsystem reset
       
   538 	while ( !( GET_REGISTER( DISPC_SYSSTATUS ) & 1 ) );	// Spin until reset complete
       
   539 	
       
   540 	TInt8 MIDLEMODE		= 0x2;	// Smart Standby. MStandby is asserted based on the internal activity of the module.
       
   541 	TInt8 CLOCKACTIVITY = 0x0;	// interface and functional clocks can be switched off.
       
   542 	TInt8 SIDLEMODE		= 0x2;	// Smart idle. Idle request is acknowledged based on the internal activity of the module
       
   543 	TInt8 ENWAKEUP		= 0x1;	// Wakeup is enabled.
       
   544 	TInt8 SOFTRESET		= 0x0;	// Normal mode
       
   545 	TInt8 AUTOIDLE		= 0x1;	// Automatic L3 and L4 interface clock gating strategy is applied based on interface activity
       
   546 	l = MIDLEMODE<<12 | CLOCKACTIVITY<<8 | SIDLEMODE<<3 | ENWAKEUP<<2 | SOFTRESET<<1 | AUTOIDLE;
       
   547 	SET_REGISTER( DISPC_SYSCONFIG, l );
       
   548 	
       
   549 	TInt8 LOADMOAD = 0x2; 		//Frame data only loaded every frame
       
   550 	l = LOADMOAD<<1;
       
   551 	SET_REGISTER( DISPC_CONFIG, l );
       
   552 	
       
   553 	SET_REGISTER( DISPC_DEFAULT_COLOR0, 0xFFFFFFFF );
       
   554 	SET_REGISTER( DISPC_TRANS_COLOR0, 0x00000000 );
       
   555 	
       
   556 	TUint8 hbp = H_BPORCH - 1;	// Horizontal Back Porch
       
   557 	TUint8 hfp = H_FPORCH - 1;	// Horizontal front porch
       
   558 	TUint8 hsw = H_SYNC - 1;	// Horizontal synchronization pulse width
       
   559 	if ( hsw > 63 )
       
   560 		{
       
   561 		hsw = 63;
       
   562 		Kern::Printf("[LCD] H_SYNC too big");
       
   563 		}
       
   564 	l = hbp<<20 | hfp<<8 | hsw;
       
   565 	SET_REGISTER( DISPC_TIMING_H, l );
       
   566 	
       
   567 	TUint8 vbp = V_BPORCH;		// Vertical back porch
       
   568 	TUint8 vfp = V_FPORCH;		// Vertical front porch
       
   569 	TUint8 vsw = V_SYNC;		// Vertical synchronization pulse width
       
   570 	__ASSERT_ALWAYS( vbp<=255, Kern::Fault("LCD", 1) );
       
   571 	__ASSERT_ALWAYS( vfp<=255, Kern::Fault("LCD", 1) );
       
   572 	__ASSERT_ALWAYS( vsw>=1 && vsw<=255, Kern::Fault("LCD", 1) );
       
   573 	l = vbp<<20 | vfp<<8 | vsw;
       
   574 	SET_REGISTER( DISPC_TIMING_V, l );
       
   575 	
       
   576 	TUint8 onoff= 0;
       
   577 	TUint8 rf	= 0;
       
   578 	TUint8 ieo 	= 0;
       
   579 	TUint8 ipc	= 1;			// Invert Pixel Clock
       
   580 	TUint8 ihs	= H_SYNC_POL ? 0 : 1;	// Invert HSYNC (0: Positive Sync polarity, 1: Negative Sync polarity)
       
   581 	TUint8 ivs	= V_SYNC_POL ? 0 : 1;	// Invert VSYNC (0: Positive Sync polarity, 1: Negative Sync polarity)
       
   582 	TUint8 acbi	= 0;
       
   583 	TUint16 acb	= 0x28;			// AC-bias pin frequency
       
   584 	l = onoff<<17 | rf<<16 | ieo<<15 | ipc<<14 | ihs<<13 | ivs<<12 | acbi<<8 | acb;
       
   585 	SET_REGISTER( DISPC_POL_FREQ, l );
       
   586 	
       
   587 	TUint8 lcd = 1;				// Display Controller Logic Clock Divisor
       
   588 	TUint8 pcd = ( 432000 + (PIXEL_CLK - 1) ) / PIXEL_CLK; // Pixel Clock Divisor - add (PIXEL_CLK - 1) to avoid rounding error
       
   589 	__ASSERT_ALWAYS( lcd>=1 && lcd<=255, Kern::Fault("LCD", 1) );
       
   590 	__ASSERT_ALWAYS( pcd>=2 && pcd<=255, Kern::Fault("LCD", 1) );
       
   591 	l = lcd<<16 | pcd;
       
   592 	SET_REGISTER( DISPC_DIVISOR, l );
       
   593 	
       
   594 	TUint16 ppl = H_DISP - 1;	// Pixels per line
       
   595 	TUint16 llp = V_DISP - 1;	// Lines per panel
       
   596 	__ASSERT_ALWAYS( ppl>=1 && ppl<=2048, Kern::Fault("LCD", 1) );
       
   597 	__ASSERT_ALWAYS( llp>=1 && llp<=2048, Kern::Fault("LCD", 1) );
       
   598 	l = llp<<16 | ppl;
       
   599 	SET_REGISTER( DISPC_SIZE_LCD, l );
       
   600 	
       
   601 	
       
   602 	// Setup a graphics region (GFX)
       
   603 	
       
   604 	// Set GFX frame buffer
       
   605 	SET_REGISTER( DISPC_GFX_BA1, ivRamPhys );
       
   606 	
       
   607 	// Center the GFX
       
   608 	TInt16 gfxposy	= ( V_DISP - KConfigLcdHeight ) / 2;
       
   609 	TInt16 gfxposx	= ( H_DISP - KConfigLcdWidth ) / 2;
       
   610 	l = ( gfxposy << 16 ) | gfxposx;
       
   611 	SET_REGISTER( DISPC_GFX_POSITION, l );
       
   612 	
       
   613 	// Set the GFX dimensions
       
   614 	TInt16 gfxsizey = KConfigLcdHeight - 1;
       
   615 	TInt16 gfxsizex = KConfigLcdWidth - 1;
       
   616 	l = gfxsizey<<16 | gfxsizex;
       
   617 	SET_REGISTER( DISPC_GFX_SIZE, l );
       
   618 	
       
   619 	TInt8 GFXSELFREFRESH		= 0x0;
       
   620 	TInt8 GFXARBITRATION		= 0x0;
       
   621 	TInt8 GFXROTATION			= 0x0;
       
   622 	TInt8 GFXFIFOPRELOAD		= 0x0;
       
   623 	TInt8 GFXENDIANNESS			= 0x0;
       
   624 	TInt8 GFXNIBBLEMODE			= 0x0;
       
   625 	TInt8 GFXCHANNELOUT			= 0x0;
       
   626 	TInt8 GFXBURSTSIZE			= 0x2;	// 16x32bit bursts
       
   627 	TInt8 GFXREPLICATIONENABLE	= 0x0;	// Disable Graphics replication logic
       
   628 	TInt8 GFXFORMAT				= 0x6;	// RGB16=0x6, RGB24-unpacked=0x8, RGB24-packed=0x9
       
   629 	TInt8 GFXENABLE				= 0x1;	// Graphics enabled
       
   630 	l = GFXSELFREFRESH<<15 | GFXARBITRATION<<14 | GFXROTATION<<12 | GFXFIFOPRELOAD<<11 | GFXENDIANNESS<<10 | GFXNIBBLEMODE<<9 | GFXCHANNELOUT<8 | GFXBURSTSIZE<<6 | GFXREPLICATIONENABLE<<5 | GFXFORMAT<<1 | GFXENABLE;
       
   631 	SET_REGISTER( DISPC_GFX_ATTRIBUTES, l );
       
   632 	
       
   633 	TInt16 GFXFIFOHIGHTHRESHOLD	= 0x3fc;	// Graphics FIFO High Threshold
       
   634 	TInt16 GFXFIFOLOWTHRESHOLD	= 0x3BC;	// Graphics FIFO Low Threshold
       
   635 	l = GFXFIFOHIGHTHRESHOLD<<16 | GFXFIFOLOWTHRESHOLD;
       
   636 	SET_REGISTER(DISPC_GFX_FIFO_THRESHOLD, l);
       
   637 	
       
   638 	TInt16 GFXFIFOSIZE = 0x400;	// Number of bytes defining the FIFO value
       
   639 	l = GFXFIFOSIZE;
       
   640 	SET_REGISTER(DISPC_GFX_FIFO_SIZE_STATUS, l);
       
   641 	
       
   642 	TInt32 GFXROWINC	= 0x1;
       
   643 	l = GFXROWINC;
       
   644 	SET_REGISTER(DISPC_GFX_ROW_INC, l);
       
   645 	
       
   646 	TInt16	GFXPIXELINC	= 0x1;
       
   647 	l = GFXPIXELINC;
       
   648 	SET_REGISTER(DISPC_GFX_PIXEL_INC, l);
       
   649 	
       
   650 	TInt32 GFXWINDOWSKIP = 0x0;
       
   651 	l = GFXWINDOWSKIP;
       
   652 	SET_REGISTER(DISPC_GFX_WINDOW_SKIP, l);
       
   653 	
       
   654 	// TO DO: Sort out the Gamma table + pallets
       
   655 	TInt32 GFXTABLEBA	= 0x807ff000;
       
   656 	l = GFXTABLEBA;
       
   657 	SET_REGISTER(DISPC_GFX_TABLE_BA, l);
       
   658 	
       
   659 	
       
   660 	// Propigate all the shadowed registers 
       
   661 	
       
   662 	TInt8 SPATIALTEMPORALDITHERINGFRAMES	= 0;
       
   663 	TInt8 LCDENABLEPOL			= 0;
       
   664 	TInt8 LCDENABLESIGNAL		= 0;
       
   665 	TInt8 PCKFREEENABLE			= 0;
       
   666 	TInt8 TDMUNUSEDBITS			= 0;
       
   667 	TInt8 TDMCYCLEFORMAT		= 0;
       
   668 	TInt8 TDMPARALLELMODE		= 0;
       
   669 	TInt8 TDMENABLE				= 0;
       
   670 	TInt8 HT					= 0;
       
   671 	TInt8 GPOUT1				= 1;
       
   672 	TInt8 GPOUT0				= 1;
       
   673 	TInt8 GPIN1					= 0;
       
   674 	TInt8 GPIN0					= 0;
       
   675 	TInt8 OVERLAYOPTIMIZATION	= 0;
       
   676 	TInt8 RFBIMODE				= 0;
       
   677 	TInt8 SECURE				= 0;
       
   678 	TInt8 TFTDATALINES			= 0x3;
       
   679 	TInt8 STDITHERENABLE		= 0;
       
   680 	TInt8 GODIGITAL				= 1;
       
   681 	TInt8 GOLCD					= 1;
       
   682 	TInt8 M8B					= 0;
       
   683 	TInt8 STNTFT				= 1;
       
   684 	TInt8 MONOCOLOR				= 0;
       
   685 	TInt8 DIGITALENABLE			= 1;
       
   686 	TInt8 LCDENABLE				= 1;	
       
   687 	l = SPATIALTEMPORALDITHERINGFRAMES<<30 | LCDENABLEPOL<<29 | LCDENABLESIGNAL<<28 | PCKFREEENABLE<<27 | 
       
   688 		TDMUNUSEDBITS<<25 | TDMCYCLEFORMAT<<23 | TDMPARALLELMODE<<21 | TDMENABLE<<20 | HT<<17 | GPOUT1<<16 | 
       
   689 			GPOUT0<<15 | GPIN1<<14 | GPIN0<<13 | OVERLAYOPTIMIZATION<<12 | 	RFBIMODE<<11 | SECURE<<10 |
       
   690 				TFTDATALINES<<8 | STDITHERENABLE<<7 | GODIGITAL<<6 | GOLCD<<5 | M8B<<4 | STNTFT<<3 |
       
   691 					MONOCOLOR<<2 | DIGITALENABLE<<1 | LCDENABLE;
       
   692 	NKern::Sleep(1);
       
   693 	SET_REGISTER(DISPC_CONTROL, l);
       
   694 	NKern::Sleep(1);
       
   695 	
       
   696     }
       
   697 
       
   698 
       
   699 /**
       
   700 Power down the display and the backlight
       
   701 */
       
   702 void DLcdPowerHandler::PowerDownLcd()
       
   703     {
       
   704 	SetBacklightState(EFalse);
       
   705 
       
   706 	// TO DO: (mandatory)
       
   707 	// Power down the display & disable LCD DMA.
       
   708 	// May need to wait until the current frame has been output
       
   709 	//
       
   710 	
       
   711 	SET_REGISTER(DISPC_CONTROL, 0);
       
   712 	
       
   713     }
       
   714 
       
   715 /**
       
   716 Set the Lcd contrast
       
   717 
       
   718 @param aValue the contrast setting
       
   719 */
       
   720 TInt DLcdPowerHandler::SetContrast(TInt aValue)
       
   721 	{
       
   722 	__KTRACE_OPT(KEXTENSION,Kern::Printf("SetContrast(%d)", aValue));
       
   723 
       
   724 	if (aValue >= KConfigLcdMinDisplayContrast && aValue <= KConfigLcdMaxDisplayContrast)
       
   725 		{
       
   726 		iContrast=aValue;
       
   727 		
       
   728 		// TO DO: (mandatory)
       
   729 		// set the contrast
       
   730 		//
       
   731 		return KErrNone;
       
   732 		}
       
   733 
       
   734 	return KErrArgument;
       
   735 	}
       
   736 
       
   737 /**
       
   738 Set the Lcd brightness
       
   739 
       
   740 @param aValue the brightness setting
       
   741 */
       
   742 TInt DLcdPowerHandler::SetBrightness(TInt aValue)
       
   743 	{
       
   744 	__KTRACE_OPT(KEXTENSION,Kern::Printf("SetBrightness(%d)", aValue));
       
   745 
       
   746 	if (aValue >= KConfigLcdMinDisplayBrightness && aValue <= KConfigLcdMaxDisplayBrightness)
       
   747 		{
       
   748 		iBrightness=aValue;
       
   749 
       
   750 		// TO DO: (mandatory)
       
   751 		// set the brightness
       
   752 		//
       
   753 		return KErrNone;
       
   754 		}
       
   755 	return KErrArgument;
       
   756 	}
       
   757 
       
   758 /**
       
   759 Turn the backlight on
       
   760 */
       
   761 void DLcdPowerHandler::BacklightOn()
       
   762     {
       
   763 	// TO DO: (mandatory)
       
   764 	// turn the backlight on
       
   765 	//
       
   766     }
       
   767 
       
   768 /**
       
   769 Turn the backlight off
       
   770 */
       
   771 void DLcdPowerHandler::BacklightOff()
       
   772     {
       
   773 	// TO DO: (mandatory)
       
   774 	// turn the backlight off
       
   775 	//
       
   776     }
       
   777 
       
   778 /**
       
   779 Set the state of the backlight
       
   780 
       
   781 @param aState ETrue if setting the backlight on
       
   782 */
       
   783 void DLcdPowerHandler::SetBacklightState(TBool aState)
       
   784 	{
       
   785 	iBacklightOn=aState;
       
   786 	if (iBacklightOn)
       
   787 		BacklightOn();
       
   788 	else
       
   789 		BacklightOff();
       
   790 	}
       
   791 
       
   792 void DLcdPowerHandler::ScreenInfo(TScreenInfoV01& anInfo)
       
   793 	{
       
   794 	__KTRACE_OPT(KEXTENSION,Kern::Printf("DLcdPowerHandler::ScreenInfo"));
       
   795 	anInfo.iWindowHandleValid=EFalse;
       
   796 	anInfo.iWindowHandle=NULL;
       
   797 	anInfo.iScreenAddressValid=ETrue;
       
   798 	anInfo.iScreenAddress=(TAny *)(iChunk->LinearAddress());
       
   799 	anInfo.iScreenSize.iWidth=KConfigLcdWidth;
       
   800 	anInfo.iScreenSize.iHeight=KConfigLcdHeight;
       
   801 	}
       
   802 
       
   803 /**
       
   804 Handle a message from the power handler
       
   805 */
       
   806 void DLcdPowerHandler::HandleMsg(void)
       
   807 	{
       
   808 	
       
   809 	TMessageBase* msg = iMsgQ.iMessage;
       
   810 	if (msg == NULL)
       
   811 		return;
       
   812 
       
   813 	if (msg->iValue)
       
   814 		DisplayOn();
       
   815 	else
       
   816 		DisplayOff();
       
   817 	msg->Complete(KErrNone,ETrue);
       
   818 	}
       
   819 
       
   820 /**
       
   821 Send a message to the power-handler message queue to turn the display on
       
   822 */
       
   823 void DLcdPowerHandler::WsSwitchOnScreen()
       
   824 	{
       
   825 	TThreadMessage& m=Kern::Message();
       
   826 	m.iValue = ETrue;
       
   827 	m.SendReceive(&iMsgQ);		// send a message and block Client thread until keyboard has been powered up
       
   828 	}
       
   829 
       
   830 /**
       
   831 Send a message to the power-handler message queue to turn the display off
       
   832 */
       
   833 void DLcdPowerHandler::WsSwitchOffScreen()
       
   834 	{
       
   835 	TThreadMessage& m=Kern::Message();
       
   836 	m.iValue = EFalse;
       
   837 	m.SendReceive(&iMsgQ);		// send a message and block Client thread until keyboard has been powered down
       
   838 	}
       
   839 
       
   840 /**
       
   841 Return information about the current display mode
       
   842 
       
   843 @param	aInfo a structure supplied by the caller to be filled by this function.
       
   844 @param	aSecure ETrue if requesting information about the secure display
       
   845 @return	KErrNone if successful
       
   846 */
       
   847 TInt DLcdPowerHandler::GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure)
       
   848 	{
       
   849 	__KTRACE_OPT(KEXTENSION,Kern::Printf("GetCurrentDisplayModeInfo"));
       
   850 	NKern::FMWait(&iLock);
       
   851 	if (aSecure)
       
   852  		aInfo = iSecureVideoInfo;
       
   853  	else
       
   854  		aInfo = iVideoInfo;
       
   855 	NKern::FMSignal(&iLock);
       
   856 	return KErrNone;
       
   857 	}
       
   858 
       
   859 /**
       
   860 Return information about the specified display mode
       
   861 
       
   862 @param	aMode the display mode to query
       
   863 @param	aInfo a structure supplied by the caller to be filled by this function.
       
   864 @return	KErrNone if successful
       
   865 */
       
   866 TInt DLcdPowerHandler::GetSpecifiedDisplayModeInfo(TInt aMode, TVideoInfoV01& aInfo)
       
   867 	{
       
   868 	__KTRACE_OPT(KEXTENSION,Kern::Printf("GetSpecifiedDisplayModeInfo mode is %d",aMode));
       
   869 
       
   870 	if (aMode < 0 || aMode >= KConfigLcdNumberOfDisplayModes)
       
   871 		return KErrArgument;
       
   872 
       
   873 	NKern::FMWait(&iLock);
       
   874 	aInfo = iVideoInfo;
       
   875 	NKern::FMSignal(&iLock);
       
   876 
       
   877 	if (aMode != aInfo.iDisplayMode)
       
   878 		{
       
   879 		aInfo.iOffsetToFirstPixel=Lcd_Mode_Config[aMode].iOffsetToFirstVideoBuffer;
       
   880 		aInfo.iIsPalettized = Lcd_Mode_Config[aMode].iIsPalettized;
       
   881 		aInfo.iOffsetBetweenLines=Lcd_Mode_Config[aMode].iOffsetBetweenLines;
       
   882 		aInfo.iBitsPerPixel = Lcd_Mode_Config[aMode].iBitsPerPixel;
       
   883 		}
       
   884 	return KErrNone;
       
   885 	}
       
   886 
       
   887 /**
       
   888 Set the display mode
       
   889 
       
   890 @param	aMode the display mode to set
       
   891 */
       
   892 TInt DLcdPowerHandler::SetDisplayMode(TInt aMode)
       
   893 	{
       
   894 
       
   895 	__KTRACE_OPT(KEXTENSION,Kern::Printf("SetDisplayMode = %d", aMode));
       
   896 
       
   897 	if (aMode < 0 || aMode >= KConfigLcdNumberOfDisplayModes)
       
   898 		return KErrArgument;
       
   899 
       
   900 	NKern::FMWait(&iLock);
       
   901 
       
   902 	// store the current mode
       
   903 	iVideoInfo.iDisplayMode = aMode;
       
   904 	iVideoInfo.iOffsetToFirstPixel = Lcd_Mode_Config[aMode].iOffsetToFirstVideoBuffer;
       
   905 	iVideoInfo.iIsPalettized = Lcd_Mode_Config[aMode].iIsPalettized;
       
   906 	iVideoInfo.iOffsetBetweenLines = Lcd_Mode_Config[aMode].iOffsetBetweenLines;
       
   907 	iVideoInfo.iBitsPerPixel = Lcd_Mode_Config[aMode].iBitsPerPixel;
       
   908 
       
   909 	// store the current mode for secure screen
       
   910 	iSecureVideoInfo.iDisplayMode = aMode;
       
   911 	iSecureVideoInfo.iOffsetToFirstPixel = Lcd_Mode_Config[aMode].iOffsetToFirstVideoBuffer;
       
   912 	iSecureVideoInfo.iIsPalettized = Lcd_Mode_Config[aMode].iIsPalettized;
       
   913 	iSecureVideoInfo.iOffsetBetweenLines = Lcd_Mode_Config[aMode].iOffsetBetweenLines;
       
   914 	iSecureVideoInfo.iBitsPerPixel = Lcd_Mode_Config[aMode].iBitsPerPixel;
       
   915 	
       
   916 	// TO DO: (mandatory)
       
   917 	// set bits per pixel on hardware
       
   918 	// May need to reconfigure DMA if video buffer size and location have changed
       
   919 	//
       
   920 	NKern::FMSignal(&iLock);
       
   921 
       
   922 	__KTRACE_OPT(KEXTENSION,Kern::Printf("SetDisplayMode mode = %d, otfp = %d, palettized = %d, bpp = %d, obl = %d",
       
   923 		aMode, iVideoInfo.iOffsetToFirstPixel, iVideoInfo.iIsPalettized, iVideoInfo.iBitsPerPixel, iVideoInfo.iOffsetBetweenLines));
       
   924 
       
   925 	return KErrNone;
       
   926 	}
       
   927 
       
   928 /**
       
   929 Fill the video memory with an initial pattern or image
       
   930 This will be displayed on boot-up
       
   931 */
       
   932 void DLcdPowerHandler::SplashScreen()
       
   933 	{
       
   934 	// TO DO: (optional)
       
   935 	// replace the example code below to display a different spash screen
       
   936 	
       
   937 	__KTRACE_OPT(KEXTENSION,Kern::Printf("Splash SCreen +"));
       
   938 	TUint* pV=(TUint*)(iVideoInfo.iVideoAddress + iVideoInfo.iOffsetToFirstPixel);
       
   939 	__KTRACE_OPT(KEXTENSION,Kern::Printf("Splash SCreen FB @ %x",pV));
       
   940 	
       
   941 	//Fill the framebuffer with bars
       
   942 	
       
   943 	for (TInt y = 0; y<KConfigLcdHeight; ++y)
       
   944 		{
       
   945 		for(TInt x = 0; x<KConfigLcdHeight; ++x)
       
   946 			{
       
   947 			TUint8 r = 0x00;
       
   948 			TUint8 g = 0x00;
       
   949 			TUint8 b = 0x00;
       
   950 			TUint16 rgb = ((r&0xf8) << 8) | ((g&0xfc) << 3) | ((b&0xf8) >> 3);
       
   951 			
       
   952 			TUint16* px = reinterpret_cast<TUint16*>(pV) + y*KConfigLcdWidth + x;
       
   953 			*px = rgb;
       
   954 			}
       
   955 		}
       
   956 	
       
   957 	__KTRACE_OPT(KEXTENSION,Kern::Printf("Splash SCreen -"));
       
   958 	}
       
   959 
       
   960 
       
   961 /**
       
   962 Get the size of the pallete
       
   963 
       
   964 @return	the number of pallete entries
       
   965 */
       
   966 TInt DLcdPowerHandler::NumberOfPaletteEntries()		//only call when holding mutex
       
   967 	{
       
   968 	// TO DO: (mandatory)
       
   969 	// Calculate the number of Palette entries - this is normally 
       
   970 	// calculated from the bits per-pixel.
       
   971 	// This is only example code... you may need to modify it for your hardware
       
   972 	//
       
   973 	TInt num = iVideoInfo.iIsPalettized ? 1<<iVideoInfo.iBitsPerPixel : 0;
       
   974 
       
   975 	__KTRACE_OPT(KEXTENSION,Kern::Printf("NumberOfPaletteEntries = %d", num));
       
   976 
       
   977 	return num;
       
   978 	}
       
   979 
       
   980 
       
   981 /** 
       
   982 Retrieve the palette entry at a particular offset
       
   983 
       
   984 @param	aEntry the palette index
       
   985 @param	aColor a caller-supplied pointer to a location where the returned RGB color is to be stored
       
   986 @return	KErrNone if successful
       
   987 		KErrNotSupported if the current vide mode does not support a palette
       
   988 		KErrArgument if aEntry is out of range
       
   989 */
       
   990 TInt DLcdPowerHandler::GetPaletteEntry(TInt aEntry, TInt* aColor)
       
   991 	{
       
   992 	NKern::FMWait(&iLock);
       
   993 	if (!iVideoInfo.iIsPalettized)
       
   994 		{
       
   995 		NKern::FMSignal(&iLock);
       
   996 		return KErrNotSupported;
       
   997 		}
       
   998 
       
   999 	if ((aEntry < 0) || (aEntry >= NumberOfPaletteEntries()))
       
  1000 		{
       
  1001 		NKern::FMSignal(&iLock);
       
  1002 		return KErrArgument;
       
  1003 		}
       
  1004 
       
  1005 	// TO DO: (mandatory)
       
  1006 	// read the RGB value of the palette entry into aColor
       
  1007 	// NOTE: the palette could either be a buffer allocated in system RAM (usually contiguous to Video buffer)
       
  1008 	//		 or could be offered as part of the hardware block that implemenst the lcd control
       
  1009 	//
       
  1010 	NKern::FMSignal(&iLock);
       
  1011 
       
  1012 	__KTRACE_OPT(KEXTENSION,Kern::Printf("GetPaletteEntry %d color 0x%x", aEntry, aColor));
       
  1013 
       
  1014 	return KErrNone;
       
  1015 	}
       
  1016 
       
  1017 /** 
       
  1018 Set the palette entry at a particular offset
       
  1019 
       
  1020 @param	aEntry the palette index
       
  1021 @param	aColor the RGB color to store
       
  1022 @return	KErrNone if successful
       
  1023 		KErrNotSupported if the current vide mode does not support a palette
       
  1024 		KErrArgument if aEntry is out of range
       
  1025 */
       
  1026 TInt DLcdPowerHandler::SetPaletteEntry(TInt aEntry, TInt aColor)
       
  1027 	{
       
  1028 
       
  1029 	NKern::FMWait(&iLock);
       
  1030 	if (!iVideoInfo.iIsPalettized)
       
  1031 		{
       
  1032 		NKern::FMSignal(&iLock);
       
  1033 		return KErrNotSupported;
       
  1034 		}
       
  1035 
       
  1036 	if ((aEntry < 0) || (aEntry >= NumberOfPaletteEntries()))	//check entry in range
       
  1037 		{
       
  1038 		NKern::FMSignal(&iLock);
       
  1039 		return KErrArgument;
       
  1040 		}
       
  1041 
       
  1042 	// TO DO: (mandatory)
       
  1043 	// update the palette entry for the secure and non-secure screen
       
  1044 	// NOTE: the palette could either be a buffer allocated in system RAM (usually contiguous to Video buffer)
       
  1045 	//		 or could be offered as part of the hardware block that implemenst the lcd control
       
  1046 	//
       
  1047 	__KTRACE_OPT(KEXTENSION,Kern::Printf("SetPaletteEntry %d to 0x%x", aEntry, aColor ));
       
  1048 
       
  1049 	return KErrNone;
       
  1050 	}
       
  1051 
       
  1052 /**
       
  1053 a HAL entry handling function for HAL group attribute EHalGroupDisplay
       
  1054 
       
  1055 @param	a1 an arbitrary argument
       
  1056 @param	a2 an arbitrary argument
       
  1057 @return	KErrNone if successful
       
  1058 */
       
  1059 TInt DLcdPowerHandler::HalFunction(TInt aFunction, TAny* a1, TAny* a2)
       
  1060 	{
       
  1061 	TInt r=KErrNone;
       
  1062 	switch(aFunction)
       
  1063 		{
       
  1064 		case EDisplayHalScreenInfo:
       
  1065 			{
       
  1066 			TPckgBuf<TScreenInfoV01> vPckg;
       
  1067 			ScreenInfo(vPckg());
       
  1068 			Kern::InfoCopy(*(TDes8*)a1,vPckg);
       
  1069 			break;
       
  1070 			}
       
  1071 
       
  1072 		case EDisplayHalWsRegisterSwitchOnScreenHandling:
       
  1073 			iWsSwitchOnScreen=(TBool)a1;
       
  1074 			break;
       
  1075 		
       
  1076 		case EDisplayHalWsSwitchOnScreen:
       
  1077 			WsSwitchOnScreen();
       
  1078 			break;
       
  1079 
       
  1080 		case EDisplayHalMaxDisplayContrast:
       
  1081 			{
       
  1082 			TInt mc=KConfigLcdMaxDisplayContrast;
       
  1083 			kumemput32(a1,&mc,sizeof(mc));
       
  1084 			break;
       
  1085 			}
       
  1086 		case EDisplayHalSetDisplayContrast:
       
  1087 			__KTRACE_OPT(KEXTENSION,Kern::Printf("EDisplayHalSetDisplayContrast"));
       
  1088 			if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetDisplayContrast")))
       
  1089 				return KErrPermissionDenied;
       
  1090 			r=SetContrast(TInt(a1));
       
  1091 			break;
       
  1092 		
       
  1093 		case EDisplayHalDisplayContrast:
       
  1094 			kumemput32(a1,&iContrast,sizeof(iContrast));
       
  1095 			break;
       
  1096 
       
  1097 		case EDisplayHalMaxDisplayBrightness:
       
  1098 			{
       
  1099 			TInt mc=KConfigLcdMaxDisplayBrightness;
       
  1100 			kumemput32(a1,&mc,sizeof(mc));
       
  1101 			break;
       
  1102 			}
       
  1103 		
       
  1104 		case EDisplayHalSetDisplayBrightness:
       
  1105 			__KTRACE_OPT(KEXTENSION,Kern::Printf("EDisplayHalSetDisplayBrightness"));
       
  1106 			if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetDisplayBrightness")))
       
  1107 				return KErrPermissionDenied;
       
  1108 			r=SetBrightness(TInt(a1));
       
  1109 			break;
       
  1110 		
       
  1111 		case EDisplayHalDisplayBrightness:
       
  1112 			kumemput32(a1,&iBrightness,sizeof(iBrightness));
       
  1113 			break;
       
  1114 		
       
  1115 		case EDisplayHalSetBacklightOn:
       
  1116 			if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetBacklightOn")))
       
  1117 				return KErrPermissionDenied;
       
  1118 			if (Kern::MachinePowerStatus()<ELow)
       
  1119 				r=KErrBadPower;
       
  1120 			else
       
  1121 				SetBacklightState(TBool(a1));
       
  1122 			break;
       
  1123 		
       
  1124 		case EDisplayHalBacklightOn:
       
  1125 			kumemput32(a1,&iBacklightOn,sizeof(TInt));
       
  1126 			break;
       
  1127 
       
  1128 		case EDisplayHalModeCount:
       
  1129 			{
       
  1130 			TInt ndm = KConfigLcdNumberOfDisplayModes;
       
  1131 			kumemput32(a1, &ndm, sizeof(ndm));
       
  1132 			break;
       
  1133 			}
       
  1134 		
       
  1135 		case EDisplayHalSetMode:
       
  1136 			if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetMode")))
       
  1137 				return KErrPermissionDenied;
       
  1138 			r = SetDisplayMode((TInt)a1);
       
  1139 			break;
       
  1140 		
       
  1141 		case EDisplayHalMode:
       
  1142 			kumemput32(a1, &iVideoInfo.iDisplayMode, sizeof(iVideoInfo.iDisplayMode));
       
  1143 			break;
       
  1144 
       
  1145 		case EDisplayHalSetPaletteEntry:
       
  1146 			if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetPaletteEntry")))
       
  1147 				return KErrPermissionDenied;
       
  1148 			r = SetPaletteEntry((TInt)a1, (TInt)a2);
       
  1149 			break;
       
  1150 		
       
  1151 		case EDisplayHalPaletteEntry:
       
  1152 			{
       
  1153 			TInt entry;
       
  1154 			kumemget32(&entry, a1, sizeof(TInt));
       
  1155 			TInt x;
       
  1156 			r = GetPaletteEntry(entry, &x);
       
  1157 			if (r == KErrNone)
       
  1158 				kumemput32(a2, &x, sizeof(x));
       
  1159 			break;
       
  1160 			}
       
  1161 		
       
  1162 		case EDisplayHalSetState:
       
  1163 			{
       
  1164 			if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetState")))
       
  1165 				return KErrPermissionDenied;
       
  1166 			if ((TBool)a1)
       
  1167 				{
       
  1168 				WsSwitchOnScreen();
       
  1169 				}
       
  1170 			else
       
  1171 				{
       
  1172 				WsSwitchOffScreen();
       
  1173 				}
       
  1174 			break;
       
  1175 			}
       
  1176 
       
  1177 		case EDisplayHalState:
       
  1178 			kumemput32(a1, &iDisplayOn, sizeof(TBool));
       
  1179 			break;
       
  1180 
       
  1181 		case EDisplayHalColors:
       
  1182 			{
       
  1183 			TInt mdc = KConfigLcdMaxDisplayColors;
       
  1184 			kumemput32(a1, &mdc, sizeof(mdc));
       
  1185 			break;
       
  1186 			}
       
  1187 
       
  1188 		case EDisplayHalCurrentModeInfo:
       
  1189 			{
       
  1190 			TPckgBuf<TVideoInfoV01> vPckg;
       
  1191 			r = GetCurrentDisplayModeInfo(vPckg(), (TBool)a2);
       
  1192 			if (KErrNone == r)
       
  1193 				Kern::InfoCopy(*(TDes8*)a1,vPckg);
       
  1194 			}
       
  1195 			break;
       
  1196 
       
  1197 		case EDisplayHalSpecifiedModeInfo:
       
  1198 			{
       
  1199 			TPckgBuf<TVideoInfoV01> vPckg;
       
  1200 			TInt mode;
       
  1201 			kumemget32(&mode, a1, sizeof(mode));
       
  1202 			r = GetSpecifiedDisplayModeInfo(mode, vPckg());
       
  1203 			if (KErrNone == r)
       
  1204 				Kern::InfoCopy(*(TDes8*)a2,vPckg);
       
  1205 			}
       
  1206 			break;
       
  1207 			
       
  1208 		case EDisplayHalSecure:
       
  1209 			kumemput32(a1, &iSecureDisplay, sizeof(TBool));
       
  1210 			break;
       
  1211 
       
  1212 		case EDisplayHalSetSecure:
       
  1213 			{
       
  1214 			if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetSecure")))
       
  1215 				return KErrPermissionDenied;
       
  1216 			SwitchDisplay((TBool)a1);
       
  1217 			}
       
  1218 			break;
       
  1219 
       
  1220 		default:
       
  1221 			r=KErrNotSupported;
       
  1222 			break;
       
  1223 		}
       
  1224 	return r;
       
  1225 	}
       
  1226 
       
  1227 
       
  1228 DECLARE_STANDARD_EXTENSION()
       
  1229 	{
       
  1230 	__KTRACE_OPT(KPOWER,Kern::Printf("Starting LCD power manager"));
       
  1231 
       
  1232 	// create LCD power handler
       
  1233 	TInt r=KErrNoMemory;
       
  1234 	DLcdPowerHandler* pH=new DLcdPowerHandler;
       
  1235 	if (pH)
       
  1236 		r=pH->Create();
       
  1237 
       
  1238 	__KTRACE_OPT(KPOWER,Kern::Printf("Returns %d",r));
       
  1239 	return r;
       
  1240 	}
       
  1241