navienginebsp/naviengine_assp/lcdgce/lcdgce.cpp
changeset 0 5de814552237
child 5 bf4661c6bc44
equal deleted inserted replaced
-1:000000000000 0:5de814552237
       
     1 /*
       
     2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 * \hwip_nec_naviengine\naviengine_assp\lcdgce\lcdgce.cpp
       
    16 * Implementation of an LCD driver with GCE support.
       
    17 * This file is part of the NE1_TBVariant Base port
       
    18 * N.B. This sample code assumes that the display supports setting the backlight on or off,
       
    19 * as well as adjusting the contrast and the brightness.
       
    20 *
       
    21 */
       
    22 
       
    23 
       
    24 
       
    25 /**
       
    26  @file Implementation of an LCD driver with GCE support.
       
    27  @internalTechnology
       
    28  @prototype
       
    29 */
       
    30 
       
    31 #include <videodriver.h>
       
    32 #include "platform.h"
       
    33 #include <nkern.h>
       
    34 #include <kernel/kernel.h>
       
    35 #include <kernel/kern_priv.h>
       
    36 #include <kernel/kpower.h>
       
    37 #include <naviengine_priv.h>
       
    38 #include "lcdgce.h"
       
    39 #include <naviengine_lcd.h>
       
    40 #include "powerresources.h"
       
    41 #include <resourcecontrol.h>
       
    42 
       
    43 // define the characteristics of the LCD display
       
    44 // This is only example code... you need to modify it for your hardware
       
    45 const TBool	KConfigLcdIsMono				= EFalse;
       
    46 const TBool	KConfigLcdPixelOrderLandscape	= ETrue;
       
    47 const TBool	KConfigLcdPixelOrderRGB			= ETrue;
       
    48 const TInt	KConfigLcdMaxDisplayColors		= 65536;
       
    49 const TUint32 KShiftBitsPerByte				= 3;
       
    50 const TInt	KConfigBitsPerPixel16			= 16;
       
    51 const TInt	KConfigBitsPerPixel32			= 32;
       
    52 
       
    53 #define RESOLUTION_AND_CYCLE		DISPLAY_RESOLUTION_AND_CYCLE(Lcd_Mode_Config[iInitialMode].iConfigLcdHeight, Lcd_Mode_Config[iInitialMode].iConfigLcdWidth, Lcd_Mode_Config[iInitialMode].iLinesInFrame, Lcd_Mode_Config[iInitialMode].iPixelsInLine)
       
    54 
       
    55 #define SCREEN_UNIT					0
       
    56 #define SCREEN_UNIT_COUNT			1
       
    57 
       
    58 struct SLcdConfig
       
    59 	{
       
    60 	TInt    iOffsetToFirstVideoBuffer;
       
    61 	TInt    iConfigLcdWidth;    // The width of the physical display
       
    62 	TInt    iConfigLcdHeight;   // The height of the physical display
       
    63 	TBool   iIsPalettized;
       
    64 	TInt    iBitsPerPixel;
       
    65 	TUint64 iPulseWidth;
       
    66 	TUint   iLinesInFrame;      // This appears to be a magic number that has no resemblence to the height
       
    67 	TUint   iPixelsInLine;      // This appears to be a magic number that has no resemblence to the width
       
    68 	TInt    iReportedLcdWidth;  // The width reported to the higher levels of software
       
    69 	TInt    iReportedLcdHeight; // The height reported to the higher levels of software
       
    70 	};
       
    71 
       
    72 static const SLcdConfig Lcd_Mode_Config[]=
       
    73 	{
       
    74 	// 0: DISPLAY_MODE_ANALOG_VGA: No LCD, Landscape VGA 640x480
       
    75 		{ 0, 640, 480, EFalse, KConfigBitsPerPixel32, KPulseWidthVga,    525, 800,  640, 480, },
       
    76 	// 1: DISPLAY_MODE_HITACHI_VGA: Hitachi LCD, Portrait VGA 480x640 (for this mode, SW4-1 should be turned OFF on the LCD panel)
       
    77 		{ 0, 480, 640, EFalse, KConfigBitsPerPixel32, KPulseWidthVgaLCD, 650, 650,  480, 640, },
       
    78 	// 2: DISPLAY_MODE_ANALOG_QVGA_LANDSCAPE_OLD: No LCD, Landscape QVGA 320x240
       
    79 		{ 0, 320, 240, EFalse, KConfigBitsPerPixel32, KPulseWidthVga,    525, 800,  320, 240, },
       
    80 	// 3: DISPLAY_MODE_HITACHI_QVGA: Hitachi LCD, Portrait QVGA 240x320
       
    81 		{ 0, 240, 320, EFalse, KConfigBitsPerPixel32, KPulseWidth,       525, 800,  240, 320, },
       
    82 	// 4: DISPLAY_MODE_NEC_WVGA: NEC LCD, Landscape WVGA
       
    83 		{ 0, 800, 480, EFalse, KConfigBitsPerPixel32, KPulseWidthWvga,   525, 1024, 800, 480, },
       
    84 	// 5: DISPLAY_MODE_ANALOG_QVGA_PORTRAIT: No LCD, Portrait QVGA 240x320
       
    85 	// Note! this screen mode reports different dimensions than the real panel size
       
    86 		{ 0, 640, 480, EFalse, KConfigBitsPerPixel16, KPulseWidthVga,    525, 800,  240, 320, },
       
    87 	// 6: DISPLAY_MODE_ANALOG_QVGA_LANDSCAPE: No LCD, Landscape QVGA 320x240
       
    88 		{ 0, 640, 480, EFalse, KConfigBitsPerPixel16, KPulseWidthVga,    525, 800,  320, 240, },
       
    89 	};
       
    90 
       
    91 // Hack function to convert pixels to TWIPS
       
    92 // Twips are screen-independent units to ensure that the proportion of screen elements
       
    93 // are the same on all display systems. A twip is defined as being 1/20th of a point.
       
    94 inline TInt PixelsToTwips(TInt aPixels)
       
    95 	{
       
    96 	return (119*aPixels)/10;
       
    97 	}
       
    98 
       
    99 DLcdPowerHandler	*  DLcdPowerHandler::pLcd			= NULL;
       
   100 
       
   101 
       
   102 const TInt   KDisplay0ThreadPriority					= 26;
       
   103 
       
   104 const TInt   KVSyncDfcPriority							= 7 ;   //priority of DFC within the queue (0 to 7, where 7 is highest)
       
   105 
       
   106 
       
   107 _LIT(KLitLcd,"LCD");
       
   108 _LIT(KDisplay0DfcThread,"Display0DfcThread-");
       
   109 
       
   110 TInt vsync_irq_callback(TUint a, TAny* b);
       
   111 
       
   112 #ifdef __SMP__
       
   113 static TSpinLock callbackLock = TSpinLock(TSpinLock::EOrderGenericIrqHigh0);
       
   114 #endif
       
   115 
       
   116 
       
   117 /**********************************************
       
   118 *    Class DDisplayPddNaviEng
       
   119 ***********************************************/
       
   120 
       
   121 void DDisplayPddNaviEng::VSyncDfcFn(TAny* aChannel)
       
   122 	{
       
   123 	DDisplayPddNaviEng * channel =(DDisplayPddNaviEng*)aChannel;
       
   124 
       
   125 	if (channel->iPostFlag)
       
   126 		{
       
   127 		 channel->iPostFlag = EFalse;
       
   128 
       
   129 					
       
   130 		if (channel->iActiveBuffer)
       
   131 			{					 		 	 		 		
       
   132 	 		//When a User buffer is registered its iFree member becomes EFalse and Deregister sets it 
       
   133 	 		//back to ETrue. Composition and Legacy buffers are not free when they are in the pending or 
       
   134 	 		//active state. 		
       
   135 			if (channel->iActiveBuffer->iType == EBufferTypeUser)
       
   136 				{
       
   137 				//If a subsequent PostUserRequest has occured,so there is a pending user buffer which has 
       
   138 				//cancelled the previous post( the one that  queued the current active buffer), calling 
       
   139 				//RequestComplete would mistakenly complete the latest PostUserRequest. 
       
   140 				
       
   141 				if (!(channel->iPendingBuffer && channel->iPendingBuffer->iType == EBufferTypeUser) )
       
   142 					{	
       
   143 					channel->RequestComplete(RDisplayChannel::EReqPostUserBuffer, KErrNone);	
       
   144 					}
       
   145 				
       
   146 				}
       
   147 			else
       
   148 				{
       
   149 				channel->iActiveBuffer->iFree	= ETrue;
       
   150 				}
       
   151 			
       
   152 			channel->iActiveBuffer->iState		= EBufferFree;
       
   153 							
       
   154 			
       
   155 			if (channel->iActiveBuffer->iType == EBufferTypeComposition)
       
   156 				{
       
   157 				//If no buffer was available during a call to GetCompositionBuffer the active buffer has  
       
   158 				//been returned as the next available one, so we must set the buffer to the proper state before we 
       
   159 				//send the notification.
       
   160 				TInt pendingIndex = channel->iLdd->iPendingIndex[RDisplayChannel::EReqGetCompositionBuffer];
       
   161 				if( channel->iLdd->iPendingReq[RDisplayChannel::EReqGetCompositionBuffer][pendingIndex].iTClientReq)
       
   162 					{
       
   163 					if(channel->iLdd->iPendingReq[RDisplayChannel::EReqGetCompositionBuffer][pendingIndex].iTClientReq->IsReady() )
       
   164 						{
       
   165 						channel->iActiveBuffer->iState	= EBufferCompose;
       
   166 						channel->RequestComplete(RDisplayChannel::EReqGetCompositionBuffer, KErrNone);
       
   167 						}
       
   168 					}			
       
   169 				}
       
   170 													              
       
   171 			channel->iActiveBuffer				= NULL;            							
       
   172 			}					
       
   173 		
       
   174 		if (channel->iPendingBuffer)
       
   175 			{
       
   176 			__GCE_DEBUG_PRINT2("DDisplayPddNaviEng::VSyncDfcFn moving pending buffer at address %08x to the active state\n", channel->iPendingBuffer->iAddress);		
       
   177 			channel->iActiveBuffer			= channel->iPendingBuffer;
       
   178 			channel->iActiveBuffer->iState	= EBufferActive;
       
   179 			channel->iPendingBuffer			= NULL; 
       
   180 
       
   181 			channel->RequestComplete(RDisplayChannel::EReqWaitForPost,  KErrNone);
       
   182 			}
       
   183 		}
       
   184 		
       
   185 	}
       
   186 
       
   187 
       
   188 
       
   189 /**
       
   190 	Constructor
       
   191 */
       
   192 DDisplayPddNaviEng::DDisplayPddNaviEng():
       
   193 	iPendingBuffer(NULL),
       
   194 	iActiveBuffer(NULL),
       
   195 	iChunk(NULL),
       
   196 	iLcdCallback(NULL),
       
   197 	iVSyncDfc(&VSyncDfcFn, this, KVSyncDfcPriority)
       
   198 	{
       
   199 	__GCE_DEBUG_PRINT("DDisplayPddNaviEng::DDisplayPddNaviEng\n");
       
   200 
       
   201 	iPostFlag = EFalse;
       
   202 	}
       
   203 
       
   204 /**
       
   205 	Destructor
       
   206 */
       
   207 DDisplayPddNaviEng::~DDisplayPddNaviEng()
       
   208 	{
       
   209 	__GCE_DEBUG_PRINT("DDisplayPddNaviEng::~DDisplayPddNaviEng()  \n");
       
   210 
       
   211 	if(iLcdCallback)
       
   212 		{
       
   213 		DLcdPowerHandler::pLcd->DeRegisterCallback(iLcdCallback) ;
       
   214 		delete iLcdCallback;
       
   215 		iLcdCallback = NULL;
       
   216 		}
       
   217 
       
   218 	//The DFC Queue is owned by DLcdPowerHandler so we shouldn't call Destroy() at this point.
       
   219 	if (iDfcQ)
       
   220 		{
       
   221 		iDfcQ=NULL;
       
   222 		}
       
   223 
       
   224 	DChunk* chunk = (DChunk*) __e32_atomic_swp_ord_ptr(&iChunk, 0);
       
   225 
       
   226 	if(chunk)
       
   227 		{
       
   228 		Kern::ChunkClose(chunk);
       
   229 		}
       
   230 
       
   231 	}
       
   232 
       
   233 
       
   234 /**
       
   235     Called by the LDD's DoCreate function to handle the device specific part of opening the channel.
       
   236     (DoCreate is called by RDisplayChannel::Open)
       
   237 
       
   238 	@param aUnit	The screen unit
       
   239 
       
   240     @return KErrNone if successful; or one of the other system wide error codes.
       
   241 */
       
   242 TInt DDisplayPddNaviEng::CreateChannelSetup(TInt aUnit)
       
   243 	{
       
   244 	__GCE_DEBUG_PRINT("DDisplayPddNaviEng::CreateChannelSetup\n");
       
   245 
       
   246 	iScreenInfo = DLcdPowerHandler::pLcd->iVideoInfo;
       
   247 	iLdd->iUnit = aUnit;
       
   248 
       
   249 	iLdd->iDisplayInfo.iAvailableRotations			= RDisplayChannel::ERotationNormal;
       
   250 	iLdd->iDisplayInfo.iNormal.iOffsetBetweenLines	= iScreenInfo.iOffsetBetweenLines;
       
   251 	iLdd->iDisplayInfo.iNormal.iHeight				= iScreenInfo.iSizeInPixels.iHeight;
       
   252 	iLdd->iDisplayInfo.iNormal.iWidth				= iScreenInfo.iSizeInPixels.iWidth;
       
   253 	iLdd->iDisplayInfo.iNumCompositionBuffers		= KDisplayCBMax;
       
   254 	iLdd->iDisplayInfo.iBitsPerPixel				= iScreenInfo.iBitsPerPixel;
       
   255     iLdd->iDisplayInfo.iRefreshRateHz = 60;
       
   256 
       
   257 
       
   258 	switch (iScreenInfo.iBitsPerPixel)
       
   259 		{
       
   260 		case 16:
       
   261 			iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatRGB_565;
       
   262 			break;
       
   263 		case 24:
       
   264 			iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatRGB_888;
       
   265 			break;
       
   266 		case 32:
       
   267 			iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatARGB_8888;
       
   268 			break;
       
   269 		default:
       
   270 			iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatUnknown;
       
   271 			break;
       
   272 		}
       
   273 
       
   274 	iLdd->iCurrentRotation = RDisplayChannel::ERotationNormal;
       
   275 
       
   276 	// Open shared chunk to the composition framebuffer
       
   277 
       
   278 	DChunk* chunk = 0;
       
   279 	TLinAddr chunkKernelAddr  = 0;
       
   280 	TUint32 chunkMapAttr = 0;
       
   281 
       
   282 	// round to twice the page size
       
   283 	TUint round  =  Kern::RoundToPageSize(2*DLcdPowerHandler::pLcd->iSize);
       
   284 
       
   285 	__GCE_DEBUG_PRINT2("DDisplayPddNaviEng::CreateChannelSetup DLcdPowerHandler::pLcd->iSize  = %d\n", DLcdPowerHandler::pLcd->iSize );
       
   286 
       
   287 	TChunkCreateInfo info;
       
   288 	info.iType					 = TChunkCreateInfo::ESharedKernelMultiple;
       
   289 	info.iMaxSize				 = round;
       
   290 	info.iMapAttr				 = EMapAttrFullyBlocking;
       
   291 	info.iOwnsMemory			 = EFalse;
       
   292 	info.iDestroyedDfc			 = 0;
       
   293 
       
   294 	TInt r = Kern::ChunkCreate(info, chunk, chunkKernelAddr, chunkMapAttr);
       
   295 
       
   296 	__GCE_DEBUG_PRINT2("CreateChannelSetup:ChunkCreate called for composition chunk. Set iChunkKernelAddr  = %08x\n", chunkKernelAddr );
       
   297 
       
   298 	if( r == KErrNone)
       
   299 		{
       
   300 		// map our chunk
       
   301 		r = Kern::ChunkCommitPhysical(chunk, 0,round , DLcdPowerHandler::pLcd->iCompositionPhysical);
       
   302 		if(r != KErrNone)
       
   303 			{
       
   304 			Kern::ChunkClose(chunk);
       
   305 			}
       
   306 		}
       
   307 
       
   308 	if ( r!= KErrNone)
       
   309 		{
       
   310 		return r;
       
   311 		}
       
   312 
       
   313 	iChunk	= chunk;
       
   314 
       
   315 	// init CB 0
       
   316 	iLdd->iCompositionBuffer[0].iType			= EBufferTypeComposition;
       
   317 	iLdd->iCompositionBuffer[0].iBufferId		= 0;
       
   318 	iLdd->iCompositionBuffer[0].iFree			= ETrue;
       
   319 	iLdd->iCompositionBuffer[0].iState			= EBufferFree;
       
   320 	iLdd->iCompositionBuffer[0].iAddress		= chunkKernelAddr;
       
   321 	iLdd->iCompositionBuffer[0].iChunk			= chunk;
       
   322 	iLdd->iCompositionBuffer[0].iHandle			= 0;
       
   323 	iLdd->iCompositionBuffer[0].iOffset			= 0;
       
   324 	iLdd->iCompositionBuffer[0].iSize			= DLcdPowerHandler::pLcd->iSize;
       
   325 	iLdd->iCompositionBuffer[0].iPendingRequest = 0;
       
   326 
       
   327 	// init CB 1
       
   328 	iLdd->iCompositionBuffer[1].iType			= EBufferTypeComposition;
       
   329 	iLdd->iCompositionBuffer[1].iBufferId		= 1;
       
   330 	iLdd->iCompositionBuffer[1].iFree			= ETrue;
       
   331 	iLdd->iCompositionBuffer[1].iState			= EBufferFree;
       
   332 	iLdd->iCompositionBuffer[1].iAddress		= chunkKernelAddr + DLcdPowerHandler::pLcd->iSize;
       
   333 	iLdd->iCompositionBuffer[1].iChunk			= chunk;
       
   334 	iLdd->iCompositionBuffer[1].iHandle			= 0;
       
   335 	iLdd->iCompositionBuffer[1].iOffset			= DLcdPowerHandler::pLcd->iSize;
       
   336 	iLdd->iCompositionBuffer[1].iSize			= DLcdPowerHandler::pLcd->iSize;
       
   337 	iLdd->iCompositionBuffer[1].iPendingRequest = 0;
       
   338 
       
   339 	iLdd->iCompositionBuffIdx					= 0;
       
   340 
       
   341 	TUint64 reg64 = AsspRegister::Read64(KHwDisplayMemoryFrameAddress);
       
   342 
       
   343 	//set up Start address for frames 0 and 1 (The actual Physical addresses must be passed)
       
   344 	AsspRegister::Write64(KHwDisplayMemoryFrameAddress , ( (TUint64)DLcdPowerHandler::pLcd->iCompositionPhysical<<32  | reg64 ) );
       
   345 
       
   346 	//set up layer 2
       
   347     TUint64 layer2Physical =  DLcdPowerHandler::pLcd->iCompositionPhysical+ DLcdPowerHandler::pLcd->iSize ;
       
   348     AsspRegister::Write64(KHwDisplayMemoryFrameAddress + KHex8,layer2Physical ) ;
       
   349 
       
   350 	//Use the same DFC queue created by the DLcdPowerHandler so all hardware accesses are executed under the same DFC thread.
       
   351 	iDfcQ= DLcdPowerHandler::pLcd->iDfcQ;
       
   352 
       
   353 	// Set the Post DFC.
       
   354 	iVSyncDfc.SetDfcQ(iDfcQ);
       
   355 
       
   356 	//Register callback function. The function will be called when V Sync is triggered
       
   357 	iLcdCallback = new TLcdUserCallBack(vsync_irq_callback, (TAny*)this);
       
   358 
       
   359 	r = KErrNoMemory;
       
   360 	if (iLcdCallback)
       
   361 		{
       
   362 		r = DLcdPowerHandler::pLcd->RegisterCallback(iLcdCallback) ;
       
   363 		}
       
   364 
       
   365 	if( r!= KErrNone)
       
   366 		{
       
   367 		delete iLcdCallback ;
       
   368 		iLcdCallback = NULL ;
       
   369 		return r;
       
   370 		}
       
   371 
       
   372 	return KErrNone;
       
   373 	}
       
   374 
       
   375 
       
   376 /**
       
   377 	Called by the Vsync callback method and queues the corresponding DFC.
       
   378  */
       
   379 void DDisplayPddNaviEng::VSyncIsr()
       
   380 	{
       
   381 	iVSyncDfc.Add();
       
   382 	}
       
   383 
       
   384 
       
   385 /**
       
   386 	Return the DFC queue to be used for this device.
       
   387  */
       
   388 TDfcQue * DDisplayPddNaviEng:: DfcQ(TInt aUnit)
       
   389 	{
       
   390 	return iDfcQ;
       
   391 	}
       
   392 
       
   393 
       
   394 /**
       
   395     Handles device specific operations when a close message has been sent to the Logical Channel.
       
   396 
       
   397 */
       
   398 TInt DDisplayPddNaviEng::CloseMsg()
       
   399 	{
       
   400 	__GCE_DEBUG_PRINT("DDisplayPddNaviEng::CloseMsg()\n");
       
   401 
       
   402 	iPendingBuffer  = NULL;
       
   403 	iActiveBuffer	= NULL;
       
   404 
       
   405 	iVSyncDfc.Cancel();
       
   406     return KErrNone;
       
   407 	}
       
   408 
       
   409 
       
   410 /**
       
   411     Set the GCE mode by posting a composition buffer.
       
   412 
       
   413 */
       
   414 TInt DDisplayPddNaviEng::SetGceMode()
       
   415 	{
       
   416 	__GCE_DEBUG_PRINT("DDisplayPddNaviEng::SetGceMode()\n");
       
   417 
       
   418     PostCompositionBuffer(&iLdd->iCompositionBuffer[0]);
       
   419     return KErrNone;
       
   420 	}
       
   421 
       
   422 
       
   423 /**
       
   424     Set the Legacy Mode by setting the appropriate Frame control value.
       
   425 
       
   426 */
       
   427 TInt DDisplayPddNaviEng::SetLegacyMode()
       
   428 	{
       
   429 	__GCE_DEBUG_PRINT("DDisplayPddNaviEng::SetLegacyMode()\n");
       
   430 
       
   431 	//Set the default frame 0 which corresponds to the Legacy Buffer.
       
   432 	AsspRegister::Write64(KHwDisplayDisplayFrameControl, KDisplayFrameControlValue);
       
   433     return KErrNone;
       
   434 	}
       
   435 
       
   436 
       
   437 /**
       
   438 	If the specified rotation is supported set it as the current rotation.  The NaviEngine
       
   439 	version supports only the RDisplayChannel::ERotationNormal rotation.
       
   440 
       
   441 	@param  aDegOfRot The requested rotation to be set.
       
   442 
       
   443 	@return KErrNone if the rotation is supported else KErrArgument.
       
   444 */
       
   445 TInt DDisplayPddNaviEng::SetRotation(RDisplayChannel::TDisplayRotation aDegOfRot)
       
   446 	{
       
   447 	TInt r;
       
   448 
       
   449 	switch (aDegOfRot)
       
   450 		{
       
   451 		case RDisplayChannel::ERotationNormal:
       
   452 			r = KErrNone;
       
   453 			break;
       
   454 		default:
       
   455 			r = KErrArgument;
       
   456 		}
       
   457 
       
   458 	return r;
       
   459 	}
       
   460 
       
   461 
       
   462 /**
       
   463     Remove any previous post operations, set the appropriate layer as the next layer to be displayed( This value is updated in synchronization
       
   464     with V Sync so it will take affect in the next V Sync after that) and also set the buffer provided as the buffer to
       
   465     be posted next. Layer 3 is associated with user buffers.
       
   466 
       
   467 	@param	aNode  Pointer to the User buffer to post.
       
   468 */
       
   469 TInt DDisplayPddNaviEng::PostUserBuffer(TBufferNode* aNode)
       
   470 	{
       
   471 
       
   472 	__GCE_DEBUG_PRINT2("PostUserBuffer :  aNode->iAddress = %08x\n", aNode->iAddress);
       
   473 
       
   474 	if(iPendingBuffer)
       
   475 		{
       
   476 		iPendingBuffer->iState = EBufferFree;
       
   477 		if (!(iPendingBuffer->iType == EBufferTypeUser) )
       
   478 			{
       
   479 			iPendingBuffer->iFree  = ETrue;
       
   480 			}
       
   481 		}
       
   482 
       
   483 	//Set the Physical address for layer3 and then set layer3 as the frame to be displayed.
       
   484 	AsspRegister::Write64(KHwDisplayMemoryFrameAddress + KHex8 ,(TUint64)aNode->iPhysicalAddress<<32 );
       
   485 	AsspRegister::Write64(KHwDisplayDisplayFrameControl, KDisplayFrame3ControlValue);
       
   486 
       
   487 	aNode->iState   = EBufferPending;
       
   488 	iPendingBuffer	= aNode;
       
   489 	iPostFlag		= ETrue;
       
   490 
       
   491 	TUint64 reg64 = AsspRegister::Read64(KHwDisplayInterruptEnable);
       
   492 	reg64 |= KVSyncEnable;
       
   493 	AsspRegister::Write64(KHwDisplayInterruptEnable , reg64 ); //Enable Vsync
       
   494 
       
   495 	return KErrNone;
       
   496 	}
       
   497 
       
   498 
       
   499 /**
       
   500     Remove any previous post operations, set the appropriate layer as the next layer to be displayed( This value is updated in synchronization
       
   501     with V Sync so it will take affect in the next V Sync after that) and also set the buffer provided as the buffer to
       
   502     be posted next. Layer 1 and 2 are associated with composition buffers 0 and 1 respectively.
       
   503 
       
   504 	@param	aNode  Pointer to the Composition buffer to post.
       
   505 */
       
   506 TInt DDisplayPddNaviEng::PostCompositionBuffer(TBufferNode* aNode)
       
   507 	{
       
   508 
       
   509 	__GCE_DEBUG_PRINT2("PostCompositionBuffer :  aNode->iAddress = %08x\n", aNode->iAddress);
       
   510 
       
   511 	if(iPendingBuffer)
       
   512 		{
       
   513 		iPendingBuffer->iState = EBufferFree;
       
   514 		if (iPendingBuffer->iType == EBufferTypeUser)
       
   515 			{
       
   516 			RequestComplete(RDisplayChannel::EReqPostUserBuffer, KErrCancel);
       
   517 			}
       
   518 		else
       
   519 			{
       
   520 			iPendingBuffer->iFree  = ETrue;
       
   521 			}
       
   522 		}
       
   523 
       
   524 	if ( aNode->iBufferId == 0)
       
   525 		{
       
   526 		// Display frame control registers	(Layer 1)
       
   527 		AsspRegister::Write64(KHwDisplayDisplayFrameControl , KDisplayFrame1ControlValue );
       
   528 		}
       
   529 	else if	( aNode->iBufferId == 1)
       
   530 		{
       
   531 		// Display frame control registers	(Layer 2)
       
   532 		AsspRegister::Write64(KHwDisplayDisplayFrameControl , KDisplayFrame2ControlValue);
       
   533 
       
   534 		//Reset Layer2 ( The value might have been overwriten by a PostUserBuffer operation).
       
   535 		AsspRegister::Write64(KHwDisplayMemoryFrameAddress + KHex8, DLcdPowerHandler::pLcd->iCompositionPhysical + DLcdPowerHandler::pLcd->iSize);
       
   536 		}
       
   537 
       
   538 	aNode->iState	= EBufferPending;
       
   539 	aNode->iFree	= EFalse;
       
   540 	iPendingBuffer	= aNode;
       
   541 	iPostFlag		= ETrue;
       
   542 
       
   543 	TUint64 reg64 = AsspRegister::Read64(KHwDisplayInterruptEnable);
       
   544 	reg64 |= KVSyncEnable;
       
   545 	AsspRegister::Write64(KHwDisplayInterruptEnable , reg64 ); //Enable Vsync
       
   546 
       
   547 	return KErrNone;
       
   548 	}
       
   549 
       
   550 
       
   551 /**
       
   552     Remove any previous post operations, set the appropriate layer as the next layer to be displayed( This value is updated in synchronization
       
   553     with V Sync so it will take affect in the next V Sync after that) and also set the Legacy Buffer as the buffer to
       
   554     be posted next.Layer 0 is associated with legacy buffer.
       
   555 
       
   556 	@param	aNode  Pointer to the Composition buffer to post.
       
   557 */
       
   558 TInt DDisplayPddNaviEng::PostLegacyBuffer()
       
   559 	{
       
   560 	__GCE_DEBUG_PRINT("PostLegacyBuffer() \n");
       
   561 
       
   562 	if(iPendingBuffer)
       
   563 		{
       
   564 		iPendingBuffer->iState = EBufferFree;
       
   565 		if (iPendingBuffer->iType == EBufferTypeUser)
       
   566 			{
       
   567 
       
   568 			RequestComplete(RDisplayChannel::EReqPostUserBuffer, KErrCancel);
       
   569 			}
       
   570 		else
       
   571 			{
       
   572 			iPendingBuffer->iFree  = ETrue;
       
   573 			}
       
   574 		}
       
   575 
       
   576 
       
   577 	AsspRegister::Write64(KHwDisplayDisplayFrameControl, KDisplayFrameControlValue);
       
   578 
       
   579 	iLdd->iLegacyBuffer[0].iState		= EBufferPending;
       
   580 	iLdd->iLegacyBuffer[0].iFree		= EFalse;
       
   581 	iPendingBuffer						= &iLdd->iLegacyBuffer[0];
       
   582 	iPostFlag		= ETrue;
       
   583 
       
   584 	TUint64 reg64 = AsspRegister::Read64(KHwDisplayInterruptEnable);
       
   585 	reg64 |= KVSyncEnable;
       
   586 	AsspRegister::Write64(KHwDisplayInterruptEnable , reg64 ); //Enable Vsync
       
   587 
       
   588 	return KErrNone;
       
   589 	}
       
   590 
       
   591 /**
       
   592 Detect whether a post operation is pending
       
   593 */
       
   594 TBool DDisplayPddNaviEng::PostPending()
       
   595 	{
       
   596 	return (iPendingBuffer != NULL);
       
   597 	}
       
   598 
       
   599 /**
       
   600 VSync Callback function
       
   601  */
       
   602 TInt vsync_irq_callback(TUint a, TAny* ch)
       
   603 	{
       
   604 	// get channel
       
   605 	if(ch)
       
   606 		{
       
   607 		DDisplayPddNaviEng * channel=(DDisplayPddNaviEng*)ch;
       
   608 		channel->VSyncIsr();
       
   609 		}
       
   610 	return KErrNone;
       
   611 	}
       
   612 
       
   613 
       
   614 //*****************************************************************
       
   615 //DDisplayPddFactory
       
   616 //*****************************************************************/
       
   617 
       
   618 
       
   619 /**
       
   620 	Constructor
       
   621 */
       
   622 DDisplayPddFactory::DDisplayPddFactory()
       
   623 	{
       
   624 	__GCE_DEBUG_PRINT("DDisplayPddFactory::DDisplayPddFactory()\n");
       
   625 
       
   626 	iVersion		= TVersion(KDisplayChMajorVersionNumber,
       
   627                       KDisplayChMinorVersionNumber,
       
   628                       KDisplayChBuildVersionNumber);
       
   629 	}
       
   630 
       
   631 /**
       
   632 	PDD factory function. Creates a PDD object.
       
   633 
       
   634 	@param  aChannel  A pointer to an PDD channel object which will be initialised on return.
       
   635 
       
   636 	@return KErrNone  if object successfully allocated, KErrNoMemory if not.
       
   637 */
       
   638 TInt DDisplayPddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer)
       
   639 	{
       
   640 	DDisplayPddNaviEng *device= new DDisplayPddNaviEng() ;
       
   641 	aChannel=device;
       
   642 	if (!device)
       
   643 		{
       
   644 		return KErrNoMemory;
       
   645 		}
       
   646 	return KErrNone;
       
   647 	}
       
   648 
       
   649 
       
   650 /**
       
   651     Set the Pdd name and return error code
       
   652 */
       
   653 TInt DDisplayPddFactory::Install()
       
   654 	{
       
   655 	__GCE_DEBUG_PRINT("DDisplayPddFactory::Install() \n");
       
   656 
       
   657 	TBuf<32> name(RDisplayChannel::Name());
       
   658 	_LIT(KPddExtension,".pdd");
       
   659 	name.Append(KPddExtension);
       
   660 	return SetName(&name);
       
   661 	}
       
   662 
       
   663 
       
   664 void DDisplayPddFactory::GetCaps(TDes8& /*aDes*/) const
       
   665 	{
       
   666 	//Not supported
       
   667 	}
       
   668 
       
   669 
       
   670 /**
       
   671     Validate version and number of units.
       
   672 */
       
   673 TInt DDisplayPddFactory::Validate(TInt aUnit, const TDesC8* /*anInfo*/, const TVersion& aVer)
       
   674 	{
       
   675 	if (!Kern::QueryVersionSupported(iVersion,aVer))
       
   676 		{
       
   677 		return KErrNotSupported;
       
   678 		}
       
   679 
       
   680 	if (aUnit != 0)
       
   681 		{
       
   682 		return KErrNotSupported;
       
   683 		}
       
   684 
       
   685 	return KErrNone;
       
   686 	}
       
   687 
       
   688 DECLARE_EXTENSION_PDD()
       
   689 /**
       
   690 	"Standard PDD" entrypoint.Creates PDD factory when Kern::InstallPhysicalDevice is called
       
   691 
       
   692 	@return pointer to the PDD factory object.
       
   693 */
       
   694 	{
       
   695 	__GCE_DEBUG_PRINT("DECLARE_EXTENSION_PDD()\n");
       
   696 	return new DDisplayPddFactory ;
       
   697 	}
       
   698 
       
   699 
       
   700 /**
       
   701 HAL handler function
       
   702 
       
   703 @param	aPtr a pointer to an instance of DLcdPowerHandler
       
   704 @param	aFunction the function number
       
   705 @param	a1 an arbitrary parameter
       
   706 @param	a2 an arbitrary parameter
       
   707 */
       
   708 LOCAL_C TInt halFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2)
       
   709 	{
       
   710 	DLcdPowerHandler* pH=(DLcdPowerHandler*)aPtr;
       
   711 	return pH->HalFunction(aFunction,a1,a2);
       
   712 	}
       
   713 
       
   714 /**
       
   715 DFC for receiving messages from the power handler
       
   716 @param	aPtr a pointer to an instance of DLcdPowerHandler
       
   717 */
       
   718 void rxMsg(TAny* aPtr)
       
   719 	{
       
   720 	DLcdPowerHandler& h=*(DLcdPowerHandler*)aPtr;
       
   721 	TMessageBase* pM=h.iMsgQ.iMessage;
       
   722 	if (pM)
       
   723 		{
       
   724 		h.HandleMsg(pM);
       
   725 		}
       
   726 	}
       
   727 
       
   728 /**
       
   729 DFC for powering up the device
       
   730 
       
   731 @param aPtr	aPtr a pointer to an instance of DLcdPowerHandler
       
   732 */
       
   733 void power_up_dfc(TAny* aPtr)
       
   734 	{
       
   735 	((DLcdPowerHandler*)aPtr)->PowerUpDfc();
       
   736 	}
       
   737 
       
   738 /**
       
   739 DFC for powering down the device
       
   740 
       
   741 @param aPtr	aPtr a pointer to an instance of DLcdPowerHandler
       
   742 */
       
   743 void power_down_dfc(TAny* aPtr)
       
   744 	{
       
   745 	((DLcdPowerHandler*)aPtr)->PowerDownDfc();
       
   746 	}
       
   747 
       
   748 
       
   749 /**
       
   750 Default constructor
       
   751 */
       
   752 DLcdPowerHandler::DLcdPowerHandler() :
       
   753 		DPowerHandler(KLitLcd),
       
   754 		iPowerUpDfc(&power_up_dfc,this,6),
       
   755 		iPowerDownDfc(&power_down_dfc,this,7),
       
   756 		iBacklightOn(EFalse),
       
   757 		iContrast(KConfigInitialDisplayContrast),
       
   758 		iBrightness(KConfigInitialDisplayBrightness),
       
   759 		iMsgQ(rxMsg,this,NULL,1)
       
   760 	{
       
   761 	}
       
   762 
       
   763 
       
   764 TInt DLcdPowerHandler::InitialiseController()
       
   765 	{
       
   766 	// Call Power Resource Manager to set clk value, immediately after it initialises the resource
       
   767 	DPowerResourceController::PostBootLevel(ENE1_TBDisplayDclkResource,	EDisplayDclk24937KHz);
       
   768 
       
   769 	//Set up layers 0-3 needed by the GCE.
       
   770 	//Layer 0 is associated with legacy buffer.
       
   771 	//Layer 1 and 2 are associated with composition buffers 0 and 1 respectively.
       
   772 	//Layer 3 is associated with user buffers.
       
   773 
       
   774 	// Memory Frame control registers
       
   775 	AsspRegister::Write64(KHwDisplayEndianConversion,	KEndianConversionValue);
       
   776 
       
   777 	// Default to 32bpp
       
   778 	TUint64 PixelFormatValue = KPixelFormatValue32bpp;
       
   779 	if (iVideoInfo.iBitsPerPixel == 32)
       
   780 		{
       
   781 		PixelFormatValue = KPixelFormatValue32bpp;
       
   782 		}
       
   783 	else if (iVideoInfo.iBitsPerPixel == 16)
       
   784 		{
       
   785 		PixelFormatValue = KPixelFormatValue16bpp;
       
   786 		}
       
   787 
       
   788 	AsspRegister::Write64(KHwDisplayPixelFormat, PixelFormatValue<<48 | PixelFormatValue<<32 | PixelFormatValue<<16 | PixelFormatValue);
       
   789 
       
   790 	//Set up the the memory frame 0 start address to be the one of the Legacy Buffer
       
   791 	AsspRegister::Write64(KHwDisplayMemoryFrameAddress, ivRamPhys);
       
   792 
       
   793 	//Memory frame 0-3 size H
       
   794 	TInt HValue		= Lcd_Mode_Config[iInitialMode].iConfigLcdWidth-1 ;
       
   795 	AsspRegister::Write64(KHwDisplayMemoryFrameSizeH,  (TUint64) HValue<<48  | (TUint64) HValue<<32 | HValue<<16 | HValue ) ;
       
   796 
       
   797 	//Memory frame 0-3 size V
       
   798 	TInt VValue		= Lcd_Mode_Config[iInitialMode].iConfigLcdHeight-1 ;
       
   799 	AsspRegister::Write64(KHwDisplayMemoryFrameSizeV,  (TUint64) VValue<<48 | (TUint64) VValue<<32 | VValue<<16 | VValue ) ;
       
   800 
       
   801 	//0 for all layers
       
   802     AsspRegister::Write64(KHwDisplayMemoryFrameStartPointX, 0);
       
   803 	AsspRegister::Write64(KHwDisplayMemoryFrameStartPointY, 0);
       
   804 
       
   805 	//Memory frame 0-3 display frame size H
       
   806 	HValue			= Lcd_Mode_Config[iInitialMode].iConfigLcdWidth-1 ;
       
   807 	AsspRegister::Write64(KHwDisplayMemoryFrameDisplayFrameSizeH, (TUint64) HValue<<48 | (TUint64) HValue<<32 | HValue<<16 | HValue );
       
   808 
       
   809 	//Memory frame 1-3 display frame size V
       
   810 	VValue			= Lcd_Mode_Config[iInitialMode].iConfigLcdHeight-1 ;
       
   811 	AsspRegister::Write64(KHwDisplayMemoryFrameDisplayFrameSizeV,  (TUint64) VValue<<48 |(TUint64) VValue<<32 | VValue<<16 | VValue);
       
   812 
       
   813 
       
   814 	// Display frame control registers ( Frame 0 is associated to the Legacy buffer)
       
   815 	AsspRegister::Write64(KHwDisplayDisplayFrameControl, KDisplayFrameControlValue);
       
   816 
       
   817 	//0 for all layers
       
   818 	AsspRegister::Write64(KHwDisplayDisplayFrameStartPointX, 1);
       
   819 	AsspRegister::Write64(KHwDisplayDisplayFrameStartPointY, 0);
       
   820 
       
   821 	// Display frames 1-3 size H - Sets the horizontal size to be displayed in pixel units
       
   822 	TInt width		= Lcd_Mode_Config[iInitialMode].iConfigLcdWidth-1;
       
   823 	AsspRegister::Write64(KHwDisplayDisplayFrameSizeH,  (TUint64) width<<48 | (TUint64) width<<32 | width<<16 | width   );
       
   824 
       
   825 
       
   826 	 // Display frames 0-3 size V - Sets the vertical  size to be displayed in pixel units
       
   827 	TInt height       = Lcd_Mode_Config[iInitialMode].iConfigLcdHeight-1;
       
   828 	AsspRegister::Write64(KHwDisplayDisplayFrameSizeV,  (TUint64)height<<48 |(TUint64) height<<32 | height<<16 | height   );
       
   829 
       
   830 
       
   831 	// Display frames    0-3 Constant color R - G - B
       
   832 	AsspRegister::Write64(KHwDisplayDisplayFrameConstantColour,         (TUint64) 0x404<<32 | 0x404  );
       
   833 	AsspRegister::Write64(KHwDisplayDisplayFrameConstantColour + KHex8, (TUint64) 0x404<<32 | 0x404  );
       
   834 	AsspRegister::Write64(KHwDisplayDisplayFrameBackgroundColour,	    0x404);
       
   835 
       
   836 	// Display control registers
       
   837 	AsspRegister::Write64(KHwDisplayResolutionAndCycle,  RESOLUTION_AND_CYCLE);
       
   838 	AsspRegister::Write64(KHwDisplayPulseWidth,          Lcd_Mode_Config[iInitialMode].iPulseWidth);
       
   839 
       
   840 	AsspRegister::Write64(KHwDisplaySettings,	   KDisplaySettingsValue);
       
   841 	AsspRegister::Write64(KHwDisplayBrightness,   KDisplayBrightnessVal);
       
   842 
       
   843 	// Interface control registers
       
   844 
       
   845 	AsspRegister::Write64(KHwDisplayInterfaceControl, KInterfaceControlValue); //sends signals out
       
   846 
       
   847 	// Set DCLK frequency:
       
   848 	AsspRegister::Write32(KHwSystemCtrlBase+KHoSCUDisplayDCLKCtrl, 11);
       
   849 
       
   850 	return KErrNone;
       
   851 	}
       
   852 
       
   853 /**
       
   854 Second-phase constructor
       
   855 
       
   856 Called by factory function at ordinal 0
       
   857 */
       
   858 TInt DLcdPowerHandler::Create()
       
   859 	{
       
   860 	pLcd			= this;
       
   861 
       
   862 	// map the video RAM
       
   863 	TInt vSize		= ((NaviEngineAssp*)Arch::TheAsic())->VideoRamSize();
       
   864 	ivRamPhys		= TNaviEngine::VideoRamPhys();
       
   865 	TInt r			= DPlatChunkHw::New(iChunk,ivRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC);
       
   866 	if (r != KErrNone)
       
   867 		return r;
       
   868 
       
   869 	//create "secure" screen immediately after normal one
       
   870 	iSecurevRamPhys = ivRamPhys + vSize;
       
   871 	TInt r2 = DPlatChunkHw::New(iSecureChunk,iSecurevRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC);
       
   872 	if (r2 != KErrNone)
       
   873 		return r2;
       
   874 
       
   875 	TUint* pV		= (TUint*)iChunk->LinearAddress();
       
   876 
       
   877 	__KTRACE_OPT(KEXTENSION,Kern::Printf("DLcdPowerHandler::Create: VideoRamSize=%x, VideoRamPhys=%08x, VideoRamLin=%08x",vSize,ivRamPhys,pV));
       
   878 
       
   879 	TUint* pV2		= (TUint*)iSecureChunk->LinearAddress();
       
   880 
       
   881 	__KTRACE_OPT(KEXTENSION,Kern::Printf("DLcdPowerHandler::Create: Secure display VideoRamSize=%x, VideoRamPhys=%08x, VideoRamLin=%08x",vSize,iSecurevRamPhys,pV2));
       
   882 
       
   883 	// Read display mode set with DIP switches 7 & 8
       
   884 	// to get the requested LCD display mode
       
   885 	iInitialMode = ReadDipSwitchDisplayMode();
       
   886 
       
   887 	// setup the video info structure, this'll be used to remember the video settings
       
   888 	iVideoInfo.iDisplayMode				= SCREEN_UNIT;
       
   889 	iVideoInfo.iOffsetToFirstPixel		= Lcd_Mode_Config[iInitialMode].iOffsetToFirstVideoBuffer;
       
   890 	iVideoInfo.iIsPalettized			= Lcd_Mode_Config[iInitialMode].iIsPalettized;
       
   891 	iVideoInfo.iOffsetBetweenLines		= Lcd_Mode_Config[iInitialMode].iConfigLcdWidth * (Lcd_Mode_Config[iInitialMode].iBitsPerPixel >> KShiftBitsPerByte);
       
   892 	iVideoInfo.iBitsPerPixel			= Lcd_Mode_Config[iInitialMode].iBitsPerPixel;
       
   893 	iVideoInfo.iSizeInPixels.iWidth		= Lcd_Mode_Config[iInitialMode].iReportedLcdWidth;
       
   894 	iVideoInfo.iSizeInPixels.iHeight	= Lcd_Mode_Config[iInitialMode].iReportedLcdHeight;
       
   895 	iVideoInfo.iSizeInTwips.iWidth		= PixelsToTwips(iVideoInfo.iSizeInPixels.iWidth);
       
   896 	iVideoInfo.iSizeInTwips.iHeight		= PixelsToTwips(iVideoInfo.iSizeInPixels.iHeight);
       
   897 	iVideoInfo.iIsMono					= KConfigLcdIsMono;
       
   898 	iVideoInfo.iVideoAddress			= (TInt)pV;
       
   899 	iVideoInfo.iIsPixelOrderLandscape	= KConfigLcdPixelOrderLandscape;
       
   900 	iVideoInfo.iIsPixelOrderRGB			= KConfigLcdPixelOrderRGB;
       
   901 
       
   902 	iSecureVideoInfo					= iVideoInfo;
       
   903 	iSecureVideoInfo.iVideoAddress		= (TInt)pV2;
       
   904 
       
   905 	iDisplayOn							= EFalse;
       
   906 	iSecureDisplay						= EFalse;
       
   907 
       
   908 	// install the HAL function
       
   909 	r=Kern::AddHalEntry(EHalGroupDisplay, halFunction, this);
       
   910 	if (r!=KErrNone)
       
   911 		return r;
       
   912 
       
   913 	iPowerUpDfc.SetDfcQ(iDfcQ);
       
   914 	iPowerDownDfc.SetDfcQ(iDfcQ);
       
   915 	iMsgQ.SetDfcQ(iDfcQ);
       
   916 	iMsgQ.Receive();
       
   917 
       
   918 	// Alloc Physical RAM for the Composition Buffers used by the GCE
       
   919 	iSize = FRAME_BUFFER_SIZE(Lcd_Mode_Config[iInitialMode].iBitsPerPixel, Lcd_Mode_Config[iInitialMode].iConfigLcdWidth, Lcd_Mode_Config[iInitialMode].iConfigLcdHeight);
       
   920 	// double and round the page size
       
   921 	TUint round = Kern::RoundToPageSize(2*iSize);
       
   922 
       
   923 	r=Epoc::AllocPhysicalRam(round , iCompositionPhysical);
       
   924 	if(r!=KErrNone)
       
   925 		{
       
   926 		return r;
       
   927 		}
       
   928 
       
   929 	// clear interrupts
       
   930 	AsspRegister::Write64(KHwDisplayInterruptClear, 0x7f);
       
   931 
       
   932 	//Set up V Sync interrupt.
       
   933 	//Bind Interrupt
       
   934 	TInt interruptId= Interrupt::Bind(EIntDisp0,Service,this);
       
   935 
       
   936 	if (interruptId<0)
       
   937 		{
       
   938 		return interruptId;
       
   939 		}
       
   940 
       
   941 	Interrupt::Enable(interruptId);
       
   942 
       
   943 	//In case more display related interrupts are enabled KHwDisplayInterruptEnableSelection
       
   944 	// should be changed appropriately
       
   945 
       
   946 	AsspRegister::Write64(KHwDisplayInterruptEnableSelection , KVSyncSelectToChannel1 );
       
   947 
       
   948 	// install the power handler
       
   949 	// power up the screen
       
   950 	Add();
       
   951 	DisplayOn();
       
   952 
       
   953 	InitialiseController();
       
   954 
       
   955 	__KTRACE_OPT(KEXTENSION, Kern::Printf(
       
   956 				"Lcd_Mode_Config: mode = %d, iInitialMode %d, physical %dx%d, reporting %dx%d, bpp %d, obl %d",
       
   957 				iVideoInfo.iDisplayMode, iInitialMode, Lcd_Mode_Config[iInitialMode].iConfigLcdWidth, Lcd_Mode_Config[iInitialMode].iConfigLcdHeight,
       
   958 				iVideoInfo.iSizeInPixels.iWidth, iVideoInfo.iSizeInPixels.iHeight, iVideoInfo.iBitsPerPixel, iVideoInfo.iOffsetBetweenLines)
       
   959 	);
       
   960 
       
   961 	SplashScreen();
       
   962 
       
   963 	return KErrNone;
       
   964 	}
       
   965 
       
   966 
       
   967 
       
   968 /**
       
   969  * Dispatch interrupts received by the display subsystem
       
   970  * @param aPtr Argument passed to the ISR
       
   971  */
       
   972 void DLcdPowerHandler::Service(TAny* aPtr)
       
   973 	{
       
   974 	DLcdPowerHandler& display = *(DLcdPowerHandler*)aPtr;
       
   975 
       
   976 	TInt irq=__SPIN_LOCK_IRQSAVE(callbackLock);
       
   977 
       
   978 	TUint64 dispStatus = AsspRegister::Read64(KHwDisplayInterruptStatus);
       
   979 	TUint64 dispEnable = AsspRegister::Read64(KHwDisplayInterruptEnable);
       
   980 
       
   981 	TUint64 reg64 =  dispEnable;
       
   982 
       
   983 	//disable VSYNC
       
   984 	reg64 &= KVSyncDisable;
       
   985 	AsspRegister::Write64(KHwDisplayInterruptEnable , reg64 );
       
   986 
       
   987 	//V sync interrupt signal has been received
       
   988 	if(  ((dispStatus & KVSyncStatus) == KVSyncStatus ) && ( ( dispEnable & KVSyncEnable ) == KVSyncEnable  )    )
       
   989 		{
       
   990 		// Call the GCE call back function in case of VSync
       
   991 		if ((display.iAppCallBk[0] != NULL) && (display.iAppCallBk[0]->iCbFn != NULL))
       
   992 			{
       
   993 			(*(display.iAppCallBk[0]->iCbFn))(0,display.iAppCallBk[0]->iDataPtr);
       
   994 			}
       
   995 		if((display.iAppCallBk[1] != NULL) && (display.iAppCallBk[1]->iCbFn != NULL))
       
   996 			{
       
   997 			(*(display.iAppCallBk[1]->iCbFn))(1,display.iAppCallBk[1]->iDataPtr);
       
   998 			}
       
   999 		}
       
  1000 
       
  1001 	__SPIN_UNLOCK_IRQRESTORE(callbackLock,irq);
       
  1002 
       
  1003 	reg64 = AsspRegister::Read64(KHwDisplayInterruptClear);
       
  1004 	AsspRegister::Write64(KHwDisplayInterruptClear, reg64 | KVSyncClear);   //CLear Vsync interrupt bit
       
  1005 
       
  1006 	}
       
  1007 
       
  1008 
       
  1009 /**
       
  1010  * Register the call back function.
       
  1011  * Components interested in receiving notification of the Vsync interrupt should register a callback function.
       
  1012  */
       
  1013 EXPORT_C TInt DLcdPowerHandler::RegisterCallback(TLcdUserCallBack* aCbPtr)
       
  1014 {
       
  1015 	__KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::RegisterCallBack %08x\n",aCbPtr->iCbFn) );
       
  1016 
       
  1017 	TInt irq=__SPIN_LOCK_IRQSAVE(callbackLock);
       
  1018 
       
  1019 	if(aCbPtr != NULL)
       
  1020 		{
       
  1021 		if ( pLcd->iAppCallBk[0] == NULL  )
       
  1022 			{
       
  1023 			pLcd->iAppCallBk[0] = aCbPtr;
       
  1024 			}
       
  1025 		else
       
  1026 			{
       
  1027 			if((pLcd->iAppCallBk[1] == NULL) && (pLcd->iAppCallBk[0]->iCbFn != aCbPtr->iCbFn))
       
  1028 				{
       
  1029 				pLcd->iAppCallBk[1] = aCbPtr;
       
  1030 				}
       
  1031 			else
       
  1032 				{
       
  1033 				__SPIN_UNLOCK_IRQRESTORE(callbackLock,irq);
       
  1034 				return KErrInUse;
       
  1035 				}
       
  1036 			}
       
  1037 
       
  1038 		__SPIN_UNLOCK_IRQRESTORE(callbackLock,irq);
       
  1039 		return KErrNone;
       
  1040 		}
       
  1041 	else
       
  1042 		{
       
  1043 		__SPIN_UNLOCK_IRQRESTORE(callbackLock,irq);
       
  1044 		__KTRACE_OPT(KEXTENSION, Kern::Printf("Error: The supplied listener's callback is NULL"));
       
  1045 		return KErrArgument;
       
  1046 		}
       
  1047 }
       
  1048 
       
  1049 
       
  1050 /**
       
  1051  *DeRegister the call back function
       
  1052  */
       
  1053 EXPORT_C void DLcdPowerHandler::DeRegisterCallback(TLcdUserCallBack* aCbPtr)
       
  1054 {
       
  1055 	__KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::DeRegisterCallBack %08x\n ",aCbPtr->iCbFn)  );
       
  1056 
       
  1057 	TInt irq=__SPIN_LOCK_IRQSAVE(callbackLock);
       
  1058 	if(aCbPtr != NULL)
       
  1059 		{
       
  1060 	    if( pLcd->iAppCallBk[0] != NULL)
       
  1061 			{
       
  1062 			if ( (pLcd->iAppCallBk[0]->iDataPtr == aCbPtr->iDataPtr) && (pLcd->iAppCallBk[0]->iCbFn == aCbPtr->iCbFn) )
       
  1063 				{
       
  1064 				pLcd->iAppCallBk[0] = NULL;
       
  1065 				}
       
  1066 			}
       
  1067 
       
  1068 		if( pLcd->iAppCallBk[1] != NULL)
       
  1069 			{
       
  1070 			if ( (pLcd->iAppCallBk[1]->iDataPtr == aCbPtr->iDataPtr) && (pLcd->iAppCallBk[1]->iCbFn == aCbPtr->iCbFn) )
       
  1071 				{
       
  1072 				pLcd->iAppCallBk[1] = NULL;
       
  1073 				}
       
  1074 			}
       
  1075 		}
       
  1076 	__SPIN_UNLOCK_IRQRESTORE(callbackLock,irq);
       
  1077 }
       
  1078 
       
  1079 
       
  1080 /**
       
  1081 Turn the display on
       
  1082 May be called as a result of a power transition or from the HAL
       
  1083 If called from HAL, then the display may be already be on (iDisplayOn == ETrue)
       
  1084 */
       
  1085 void DLcdPowerHandler::DisplayOn()
       
  1086 	{
       
  1087 	__KTRACE_OPT(KPOWER, Kern::Printf("DisplayOn %d", iDisplayOn));
       
  1088 	if (!iDisplayOn)				// may have been powered up already
       
  1089 		{
       
  1090 		iDisplayOn = ETrue;
       
  1091 		PowerUpLcd(iSecureDisplay);
       
  1092 		SetContrast(iContrast);
       
  1093 		SetBrightness(iBrightness);
       
  1094 		}
       
  1095 	}
       
  1096 
       
  1097 /**
       
  1098 Turn the display off
       
  1099 May be called as a result of a power transition or from the HAL
       
  1100 If called from Power Manager, then the display may be already be off (iDisplayOn == EFalse)
       
  1101 if the platform is in silent running mode
       
  1102 */
       
  1103 void DLcdPowerHandler::DisplayOff()
       
  1104 	{
       
  1105 	__KTRACE_OPT(KPOWER, Kern::Printf("DisplayOff %d", iDisplayOn));
       
  1106 	if (iDisplayOn)
       
  1107 		{
       
  1108 		iDisplayOn = EFalse;
       
  1109 		PowerDownLcd();
       
  1110 		}
       
  1111 	}
       
  1112 
       
  1113 /**
       
  1114 Switch between secure and non-secure displays
       
  1115 
       
  1116 @param aSecure ETrue if switching to secure display
       
  1117 */
       
  1118 void DLcdPowerHandler::SwitchDisplay(TBool aSecure)
       
  1119 	{
       
  1120 	if (aSecure)
       
  1121 		{
       
  1122 		if (!iSecureDisplay)
       
  1123 			{
       
  1124 			TThreadMessage& m=Kern::Message();
       
  1125 			m.iValue = EDisplayHalSetSecure;
       
  1126 			m.SendReceive(&iMsgQ);		// send a message and block Client thread until secure display has been enabled.
       
  1127 			}
       
  1128 		}
       
  1129 	else
       
  1130 		{
       
  1131 		if (iSecureDisplay)
       
  1132 			{
       
  1133 			TThreadMessage& m=Kern::Message();
       
  1134 			m.iValue = -EDisplayHalSetSecure;
       
  1135 			m.SendReceive(&iMsgQ);		// send a message and block Client thread until secure display has been disabled.
       
  1136 			}
       
  1137 		}
       
  1138 	}
       
  1139 
       
  1140 
       
  1141 /**
       
  1142 Switch to secure display
       
  1143 
       
  1144 */
       
  1145 void DLcdPowerHandler::SwitchToSecureDisplay()
       
  1146 	{
       
  1147 	DisplayOff();
       
  1148 	iSecureDisplay = ETrue;
       
  1149 	DisplayOn();
       
  1150 	}
       
  1151 
       
  1152 
       
  1153 /**
       
  1154 Switch from secure display
       
  1155 
       
  1156 */
       
  1157 void DLcdPowerHandler::SwitchFromSecureDisplay()
       
  1158 	{
       
  1159 	DisplayOff();
       
  1160 	iSecureDisplay = EFalse;
       
  1161 	DisplayOn();
       
  1162 	}
       
  1163 
       
  1164 
       
  1165 /**
       
  1166 DFC to power up the display
       
  1167 */
       
  1168 void DLcdPowerHandler::PowerUpDfc()
       
  1169 	{
       
  1170 	__KTRACE_OPT(KPOWER, Kern::Printf("PowerUpDfc"));
       
  1171 	DisplayOn();
       
  1172 
       
  1173 	PowerUpDone();				// must be called from a different thread than PowerUp()
       
  1174 	}
       
  1175 
       
  1176 /**
       
  1177 DFC to power down the display
       
  1178 */
       
  1179 void DLcdPowerHandler::PowerDownDfc()
       
  1180 	{
       
  1181 	__KTRACE_OPT(KPOWER, Kern::Printf("PowerDownDfc"));
       
  1182 	DisplayOff();
       
  1183 	PowerDownDone();			// must be called from a different thread than PowerUp()
       
  1184 	}
       
  1185 
       
  1186 /**
       
  1187 Schedule the power-down DFC
       
  1188 */
       
  1189 void DLcdPowerHandler::PowerDown(TPowerState)
       
  1190 	{
       
  1191 	iPowerDownDfc.Enque();		// schedules DFC to execute on this driver's thread
       
  1192 	}
       
  1193 
       
  1194 /**
       
  1195 Schedule the power-up DFC
       
  1196 */
       
  1197 void DLcdPowerHandler::PowerUp()
       
  1198 	{
       
  1199 	iPowerUpDfc.Enque();		// schedules DFC to execute on this driver's thread
       
  1200 	}
       
  1201 
       
  1202 /**
       
  1203 Power up the display
       
  1204 
       
  1205 @param aSecure ETrue if powering up the secure display
       
  1206 */
       
  1207 void DLcdPowerHandler::PowerUpLcd(TBool aSecure)
       
  1208 	{
       
  1209 	AsspRegister::Write16(KHwLCDDispBase,0x140); //power-up board and backlight
       
  1210 	}
       
  1211 
       
  1212 /**
       
  1213 Power down the display and the backlight
       
  1214 */
       
  1215 void DLcdPowerHandler::PowerDownLcd()
       
  1216 	{
       
  1217 	SetBacklightState(EFalse);
       
  1218 	AsspRegister::Write16(KHwLCDDispBase, 0x143); //power-down board and backlight
       
  1219 	}
       
  1220 
       
  1221 /**
       
  1222 Set the Lcd contrast
       
  1223 
       
  1224 @param aValue the contrast setting
       
  1225 */
       
  1226 TInt DLcdPowerHandler::SetContrast(TInt aValue)
       
  1227 	{
       
  1228 	__KTRACE_OPT(KEXTENSION,Kern::Printf("SetContrast(%d)", aValue));
       
  1229 
       
  1230 	if (aValue >= KConfigLcdMinDisplayContrast && aValue <= KConfigLcdMaxDisplayContrast)
       
  1231 		{
       
  1232 		iContrast=aValue;
       
  1233 		return KErrNone;
       
  1234 		}
       
  1235 
       
  1236 	return KErrArgument;
       
  1237 	}
       
  1238 
       
  1239 /**
       
  1240 Queue a message to set the Lcd Contrast
       
  1241 
       
  1242 @param aValue the contrast setting
       
  1243 */
       
  1244 TInt DLcdPowerHandler::HalSetContrast(TInt aValue)
       
  1245 	{
       
  1246 	__KTRACE_OPT(KEXTENSION,Kern::Printf("HalSetContrast(%d)", aValue));
       
  1247 
       
  1248 	TThreadMessage& m=Kern::Message();
       
  1249 	m.iValue = EDisplayHalSetDisplayContrast;
       
  1250 	m.iArg[0] = (TAny *) aValue;
       
  1251 
       
  1252 	return ( m.SendReceive(&iMsgQ) );		// send a message and block Client thread until contrast has been set.
       
  1253 	}
       
  1254 
       
  1255 
       
  1256 
       
  1257 /**
       
  1258 Set the Lcd brightness
       
  1259 
       
  1260 @param aValue the brightness setting
       
  1261 */
       
  1262 TInt DLcdPowerHandler::SetBrightness(TInt aValue)
       
  1263 	{
       
  1264 	__KTRACE_OPT(KEXTENSION,Kern::Printf("SetBrightness(%d)", aValue));
       
  1265 
       
  1266 	if (aValue >= KConfigLcdMinDisplayBrightness && aValue <= KConfigLcdMaxDisplayBrightness)
       
  1267 		{
       
  1268 		iBrightness=aValue;
       
  1269 
       
  1270 		return KErrNone;
       
  1271 		}
       
  1272 	return KErrArgument;
       
  1273 	}
       
  1274 
       
  1275 /**
       
  1276 Queue a message to set the Lcd brightness
       
  1277 
       
  1278 @param aValue the brightness setting
       
  1279 */
       
  1280 TInt DLcdPowerHandler::HalSetBrightness(TInt aValue)
       
  1281 	{
       
  1282 	__KTRACE_OPT(KEXTENSION,Kern::Printf("HalSetBrightness(%d)", aValue));
       
  1283 
       
  1284 	TThreadMessage& m=Kern::Message();
       
  1285 	m.iValue = EDisplayHalSetDisplayBrightness;
       
  1286 	m.iArg[0]= (TAny *) aValue;
       
  1287 
       
  1288 	return (m.SendReceive(&iMsgQ));		// send a message and block Client thread until brightness has been set.
       
  1289 	}
       
  1290 
       
  1291 
       
  1292 /**
       
  1293 Turn the backlight on
       
  1294 */
       
  1295 void DLcdPowerHandler::BacklightOn()
       
  1296 	{
       
  1297 	// turn the backlight on
       
  1298 	AsspRegister::Write16(KHwLCDDispBase, 0x140);
       
  1299 	}
       
  1300 
       
  1301 /**
       
  1302 Turn the backlight off
       
  1303 */
       
  1304 void DLcdPowerHandler::BacklightOff()
       
  1305 	{
       
  1306 	// turn the backlight off
       
  1307 	AsspRegister::Write16(KHwLCDDispBase, 0x142);
       
  1308 	}
       
  1309 
       
  1310 /**
       
  1311 Set the state of the backlight
       
  1312 
       
  1313 @param aState ETrue if setting the backlight on
       
  1314 */
       
  1315 void DLcdPowerHandler::SetBacklightState(TBool aState)
       
  1316 	{
       
  1317 	iBacklightOn=aState;
       
  1318 	if (iBacklightOn)
       
  1319 		BacklightOn();
       
  1320 	else
       
  1321 		BacklightOff();
       
  1322 	}
       
  1323 
       
  1324 void DLcdPowerHandler::ScreenInfo(TScreenInfoV01& anInfo)
       
  1325 	{
       
  1326 	__KTRACE_OPT(KEXTENSION,Kern::Printf("DLcdPowerHandler::ScreenInfo"));
       
  1327 
       
  1328 	anInfo.iWindowHandleValid	 = EFalse;
       
  1329 	anInfo.iWindowHandle		 = NULL;
       
  1330 	anInfo.iScreenAddressValid	 = ETrue;
       
  1331 	anInfo.iScreenAddress		 = (TAny *)(iChunk->LinearAddress());
       
  1332 	anInfo.iScreenSize.iWidth	 = Lcd_Mode_Config[iInitialMode].iReportedLcdWidth;
       
  1333 	anInfo.iScreenSize.iHeight	 = Lcd_Mode_Config[iInitialMode].iReportedLcdHeight;
       
  1334 	}
       
  1335 
       
  1336 /**
       
  1337 Handle a message from the power handler
       
  1338 */
       
  1339 void DLcdPowerHandler::HandleMsg(TMessageBase* aMsg)
       
  1340 {
       
  1341 	TInt r = KErrNone;
       
  1342 	TThreadMessage& m=*(TThreadMessage*)aMsg;
       
  1343 	switch(m.iValue)
       
  1344 		{
       
  1345 		case EDisplayHalWsSwitchOnScreen:
       
  1346 			DisplayOn();
       
  1347 			break;
       
  1348 		case (-EDisplayHalWsSwitchOnScreen):
       
  1349 			DisplayOff();
       
  1350 			break;
       
  1351 		case EDisplayHalSetSecure:
       
  1352 			SwitchToSecureDisplay();
       
  1353 			break;
       
  1354 		case (-EDisplayHalSetSecure):
       
  1355 			SwitchFromSecureDisplay();
       
  1356 			break;
       
  1357 		case EDisplayHalSetDisplayContrast:
       
  1358 			{
       
  1359 			r = SetContrast(m.Int0());
       
  1360 			break;
       
  1361 			}
       
  1362 		case EDisplayHalSetDisplayBrightness:
       
  1363 			{
       
  1364 			r = SetBrightness(m.Int0());
       
  1365 			break;
       
  1366 		default:
       
  1367 			r = KErrNotSupported;
       
  1368 			__KTRACE_OPT(KHARDWARE,Kern::Printf("DLcdPowerHandler::HalFunction %d defaulted", m.iValue));
       
  1369 			break;
       
  1370 			}
       
  1371 		}
       
  1372 
       
  1373 	m.Complete(r, ETrue);
       
  1374 	}
       
  1375 
       
  1376 /**
       
  1377 Send a message to the power-handler message queue to turn the display on
       
  1378 */
       
  1379 void DLcdPowerHandler::WsSwitchOnScreen()
       
  1380 	{
       
  1381 	TThreadMessage& m=Kern::Message();
       
  1382 	m.iValue = EDisplayHalWsSwitchOnScreen;
       
  1383 	m.SendReceive(&iMsgQ);		// send a message and block Client thread until keyboard has been powered up
       
  1384 	}
       
  1385 
       
  1386 /**
       
  1387 Send a message to the power-handler message queue to turn the display off
       
  1388 */
       
  1389 void DLcdPowerHandler::WsSwitchOffScreen()
       
  1390 	{
       
  1391 	TThreadMessage& m=Kern::Message();
       
  1392 	m.iValue = -EDisplayHalWsSwitchOnScreen;
       
  1393 	m.SendReceive(&iMsgQ);		// send a message and block Client thread until keyboard has been powered down
       
  1394 	}
       
  1395 
       
  1396 /**
       
  1397 Return information about the current display mode
       
  1398 
       
  1399 @param	aInfo a structure supplied by the caller to be filled by this function.
       
  1400 @param	aSecure ETrue if requesting information about the secure display
       
  1401 @return	KErrNone if successful
       
  1402 */
       
  1403 TInt DLcdPowerHandler::GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure)
       
  1404 	{
       
  1405 	__KTRACE_OPT(KEXTENSION,Kern::Printf("GetCurrentDisplayModeInfo"));
       
  1406 	NKern::FMWait(&iLock);
       
  1407 	if (aSecure)
       
  1408 		aInfo = iSecureVideoInfo;
       
  1409 	else
       
  1410 		aInfo = iVideoInfo;
       
  1411 	NKern::FMSignal(&iLock);
       
  1412 	return KErrNone;
       
  1413 	}
       
  1414 
       
  1415 /**
       
  1416 Return information about the specified display mode
       
  1417 
       
  1418 @param	aScreenNumber the screen number to query
       
  1419 @param	aInfo a structure supplied by the caller to be filled by this function.
       
  1420 @return	KErrNone if successful
       
  1421 */
       
  1422 TInt DLcdPowerHandler::GetSpecifiedDisplayModeInfo(TInt aScreenNumber, TVideoInfoV01& aInfo)
       
  1423 	{
       
  1424 	__KTRACE_OPT(KEXTENSION, Kern::Printf("GetSpecifiedDisplayModeInfo screen unit is %d",aScreenNumber));
       
  1425 
       
  1426 	if (aScreenNumber < 0 || aScreenNumber >= SCREEN_UNIT_COUNT)
       
  1427 		return KErrArgument;
       
  1428 
       
  1429 	NKern::FMWait(&iLock);
       
  1430 	aInfo = iVideoInfo;
       
  1431 	NKern::FMSignal(&iLock);
       
  1432 
       
  1433 	return KErrNone;
       
  1434 	}
       
  1435 
       
  1436 /**
       
  1437 Set the display mode
       
  1438 
       
  1439 @param	aScreenNumber the screen number to set
       
  1440 */
       
  1441 TInt DLcdPowerHandler::SetDisplayMode(TInt aScreenNumber)
       
  1442 	{
       
  1443 	__KTRACE_OPT(KEXTENSION,Kern::Printf("SetDisplayMode ( screen unit) = %d", aScreenNumber));
       
  1444 
       
  1445 	if (aScreenNumber < 0 || aScreenNumber >= SCREEN_UNIT_COUNT)
       
  1446 		return KErrArgument;
       
  1447 
       
  1448 	NKern::FMWait(&iLock);
       
  1449 
       
  1450 	// store the current mode
       
  1451 	iVideoInfo.iDisplayMode					= SCREEN_UNIT;
       
  1452 	iVideoInfo.iOffsetToFirstPixel			= Lcd_Mode_Config[iInitialMode].iOffsetToFirstVideoBuffer;
       
  1453 	iVideoInfo.iIsPalettized				= Lcd_Mode_Config[iInitialMode].iIsPalettized;
       
  1454 	iVideoInfo.iOffsetBetweenLines			= Lcd_Mode_Config[iInitialMode].iConfigLcdWidth * (Lcd_Mode_Config[iInitialMode].iBitsPerPixel >> KShiftBitsPerByte);
       
  1455 	iVideoInfo.iBitsPerPixel				= Lcd_Mode_Config[iInitialMode].iBitsPerPixel;
       
  1456 
       
  1457 	// store the current mode for secure screen
       
  1458 	iSecureVideoInfo.iDisplayMode			= SCREEN_UNIT;
       
  1459 	iSecureVideoInfo.iOffsetToFirstPixel	= Lcd_Mode_Config[iInitialMode].iOffsetToFirstVideoBuffer;
       
  1460 	iSecureVideoInfo.iIsPalettized			= Lcd_Mode_Config[iInitialMode].iIsPalettized;
       
  1461 	iSecureVideoInfo.iOffsetBetweenLines	= Lcd_Mode_Config[iInitialMode].iConfigLcdWidth * (Lcd_Mode_Config[iInitialMode].iBitsPerPixel >> KShiftBitsPerByte);
       
  1462 	iSecureVideoInfo.iBitsPerPixel			= Lcd_Mode_Config[iInitialMode].iBitsPerPixel;
       
  1463 
       
  1464 	NKern::FMSignal(&iLock);
       
  1465 
       
  1466 	__KTRACE_OPT(KEXTENSION,Kern::Printf("SetDisplayMode screenNumber = %d, otfp = %d, palettized = %d, bpp = %d, obl = %d",
       
  1467 		aScreenNumber, iVideoInfo.iOffsetToFirstPixel, iVideoInfo.iIsPalettized, iVideoInfo.iBitsPerPixel, iVideoInfo.iOffsetBetweenLines));
       
  1468 
       
  1469 	return KErrNone;
       
  1470 	}
       
  1471 
       
  1472 /**
       
  1473 Fill the video memory with an initial pattern or image
       
  1474 This will be displayed on boot-up
       
  1475 */
       
  1476 const TInt KGranularity = 4;
       
  1477 
       
  1478 void DLcdPowerHandler::SplashScreen()
       
  1479 	{
       
  1480 	//initialise the video ram to be a splash screen
       
  1481 
       
  1482 	__KTRACE_OPT(KEXTENSION,Kern::Printf("SplashScreen"));
       
  1483 
       
  1484 	TInt xres, yres, bpp, bpl, ofp;
       
  1485 	TLinAddr addr;
       
  1486 	addr = (TLinAddr)iVideoInfo.iVideoAddress;
       
  1487 	xres = iVideoInfo.iSizeInPixels.iWidth;
       
  1488 	yres = iVideoInfo.iSizeInPixels.iHeight;
       
  1489 	bpp  = iVideoInfo.iBitsPerPixel;
       
  1490 	bpl  = iVideoInfo.iOffsetBetweenLines;
       
  1491 	ofp  = iVideoInfo.iOffsetToFirstPixel;
       
  1492 
       
  1493 	TInt xb, yb;
       
  1494 
       
  1495 	for (yb=0; yb<yres/KGranularity; ++yb)
       
  1496 		{
       
  1497 		for (xb=0; xb<xres/KGranularity; ++xb)
       
  1498 			{
       
  1499 			TUint c=((xb*xb+yb*yb)>>1)%251;
       
  1500 			c^=0xff;
       
  1501 			TUint r=c&7;
       
  1502 			TUint g=(c>>3)&7;
       
  1503 			TUint b=(c>>6);
       
  1504 			TUint c16=(b<<14)|(g<<8)|(r<<2);
       
  1505 			c16 |= (c16<<16);
       
  1506 			TUint c8=c|(c<<8);
       
  1507 			c8 |= (c8<<16);
       
  1508 			TUint c32=(b<<22)|(g<<13)|(r<<5);
       
  1509 			TInt baddr=addr+ofp+yb*KGranularity*bpl+xb*KGranularity*bpp/8;
       
  1510 			TInt l;
       
  1511 			for (l=0; l<KGranularity; ++l, baddr+=bpl)
       
  1512 				{
       
  1513 				TUint32* p=(TUint32*)baddr;
       
  1514 				if (bpp==8)
       
  1515 					*p++=c8;
       
  1516 				else if (bpp==16)
       
  1517 					*p++=c16, *p++=c16;
       
  1518 				else
       
  1519 					{
       
  1520 					*p++=c32+0x0;
       
  1521 					*p++=c32+0x4;
       
  1522 					*p++=c32+0x8;
       
  1523 					*p++=c32+0xc;
       
  1524 					c32+=0x100;
       
  1525 					}
       
  1526 				}
       
  1527 			}
       
  1528 		}
       
  1529 
       
  1530 	// Secure screen
       
  1531 	TUint8* linePtr = (TUint8*)iSecureVideoInfo.iVideoAddress+
       
  1532 					   iSecureVideoInfo.iOffsetToFirstPixel;
       
  1533 	TInt pixelSize  = iSecureVideoInfo.iBitsPerPixel;
       
  1534 	if(pixelSize>8)
       
  1535 		pixelSize = (pixelSize+7)&~7; // Round up to whole number of bytes
       
  1536 	TInt bytesPerLine = (pixelSize*iSecureVideoInfo.iSizeInPixels.iWidth) >> 3;
       
  1537 	for(TInt y=0; y<iSecureVideoInfo.iSizeInPixels.iHeight; y++)
       
  1538 		{
       
  1539 		for(TInt x=0; x<bytesPerLine; x++)
       
  1540 			linePtr[x] = x+y;
       
  1541 		linePtr += iSecureVideoInfo.iOffsetBetweenLines;
       
  1542 		}
       
  1543 	}
       
  1544 
       
  1545 
       
  1546 
       
  1547 /**
       
  1548 Get the size of the pallete
       
  1549 
       
  1550 @return	the number of pallete entries
       
  1551 */
       
  1552 TInt DLcdPowerHandler::NumberOfPaletteEntries()
       
  1553 	{
       
  1554 	TInt num = iVideoInfo.iIsPalettized ? 1<<iVideoInfo.iBitsPerPixel : 0;
       
  1555 
       
  1556 	__KTRACE_OPT(KEXTENSION,Kern::Printf("NumberOfPaletteEntries = %d", num));
       
  1557 
       
  1558 	return num;
       
  1559 	}
       
  1560 
       
  1561 
       
  1562 /**
       
  1563 Retrieve the palette entry at a particular offset
       
  1564 
       
  1565 @param	aEntry the palette index
       
  1566 @param	aColor a caller-supplied pointer to a location where the returned RGB color is to be stored
       
  1567 @return	KErrNone if successful
       
  1568 		KErrNotSupported if the current vide mode does not support a palette
       
  1569 		KErrArgument if aEntry is out of range
       
  1570 */
       
  1571 TInt DLcdPowerHandler::GetPaletteEntry(TInt aEntry, TInt* aColor)
       
  1572 	{
       
  1573 	NKern::FMWait(&iLock);
       
  1574 	if (!iVideoInfo.iIsPalettized)
       
  1575 		{
       
  1576 		NKern::FMSignal(&iLock);
       
  1577 		return KErrNotSupported;
       
  1578 		}
       
  1579 
       
  1580 	if ((aEntry < 0) || (aEntry >= NumberOfPaletteEntries()))
       
  1581 		{
       
  1582 		NKern::FMSignal(&iLock);
       
  1583 		return KErrArgument;
       
  1584 		}
       
  1585 
       
  1586 	NKern::FMSignal(&iLock);
       
  1587 
       
  1588 	__KTRACE_OPT(KEXTENSION,Kern::Printf("GetPaletteEntry %d color 0x%x", aEntry, aColor));
       
  1589 
       
  1590 	return KErrNone;
       
  1591 	}
       
  1592 
       
  1593 /**
       
  1594 Set the palette entry at a particular offset
       
  1595 
       
  1596 @param	aEntry the palette index
       
  1597 @param	aColor the RGB color to store
       
  1598 @return	KErrNone if successful
       
  1599 		KErrNotSupported if the current vide mode does not support a palette
       
  1600 		KErrArgument if aEntry is out of range
       
  1601 */
       
  1602 TInt DLcdPowerHandler::SetPaletteEntry(TInt aEntry, TInt aColor)
       
  1603 	{
       
  1604 
       
  1605 	NKern::FMWait(&iLock);
       
  1606 	if (!iVideoInfo.iIsPalettized)
       
  1607 		{
       
  1608 		NKern::FMSignal(&iLock);
       
  1609 		return KErrNotSupported;
       
  1610 		}
       
  1611 
       
  1612 	if ((aEntry < 0) || (aEntry >= NumberOfPaletteEntries()))	//check entry in range
       
  1613 		{
       
  1614 		NKern::FMSignal(&iLock);
       
  1615 		return KErrArgument;
       
  1616 		}
       
  1617 
       
  1618 	NKern::FMSignal(&iLock);
       
  1619 	__KTRACE_OPT(KEXTENSION,Kern::Printf("SetPaletteEntry %d to 0x%x", aEntry, aColor ));
       
  1620 
       
  1621 	return KErrNone;
       
  1622 	}
       
  1623 
       
  1624 /**
       
  1625 a HAL entry handling function for HAL group attribute EHalGroupDisplay.
       
  1626 The HalFunction is called in the context of the user thread which is
       
  1627 requesting the particular HAL display function.
       
  1628 
       
  1629 @param	a1 an arbitrary argument
       
  1630 @param	a2 an arbitrary argument
       
  1631 @return	KErrNone if successful
       
  1632 */
       
  1633 TInt DLcdPowerHandler::HalFunction(TInt aFunction, TAny* a1, TAny* a2)
       
  1634 	{
       
  1635 	TInt r=KErrNone;
       
  1636 	switch(aFunction)
       
  1637 		{
       
  1638 		case EDisplayHalScreenInfo:
       
  1639 			{
       
  1640 			TPckgBuf<TScreenInfoV01> vPckg;
       
  1641 			ScreenInfo(vPckg());
       
  1642 			Kern::InfoCopy(*(TDes8*)a1,vPckg);
       
  1643 			break;
       
  1644 			}
       
  1645 
       
  1646 		case EDisplayHalWsRegisterSwitchOnScreenHandling:
       
  1647 			iWsSwitchOnScreen=(TBool)a1;
       
  1648 			break;
       
  1649 
       
  1650 		case EDisplayHalWsSwitchOnScreen:
       
  1651 			WsSwitchOnScreen();
       
  1652 			break;
       
  1653 
       
  1654 		case EDisplayHalMaxDisplayContrast:
       
  1655 			{
       
  1656 			TInt mc=KConfigLcdMaxDisplayContrast;
       
  1657 			kumemput32(a1,&mc,sizeof(mc));
       
  1658 			break;
       
  1659 			}
       
  1660 		case EDisplayHalSetDisplayContrast:
       
  1661 			if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetDisplayContrast")))
       
  1662 				return KErrPermissionDenied;
       
  1663 			r=HalSetContrast(TInt(a1));
       
  1664 			break;
       
  1665 
       
  1666 		case EDisplayHalDisplayContrast:
       
  1667 			kumemput32(a1,&iContrast,sizeof(iContrast));
       
  1668 			break;
       
  1669 
       
  1670 		case EDisplayHalMaxDisplayBrightness:
       
  1671 			{
       
  1672 			TInt mc=KConfigLcdMaxDisplayBrightness;
       
  1673 			kumemput32(a1,&mc,sizeof(mc));
       
  1674 			break;
       
  1675 			}
       
  1676 
       
  1677 		case EDisplayHalSetDisplayBrightness:
       
  1678 			if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetDisplayBrightness")))
       
  1679 				return KErrPermissionDenied;
       
  1680 			r=HalSetBrightness(TInt(a1));
       
  1681 			break;
       
  1682 
       
  1683 		case EDisplayHalDisplayBrightness:
       
  1684 			kumemput32(a1,&iBrightness,sizeof(iBrightness));
       
  1685 			break;
       
  1686 
       
  1687 		case EDisplayHalSetBacklightOn:
       
  1688 			if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetBacklightOn")))
       
  1689 				return KErrPermissionDenied;
       
  1690 			if (Kern::MachinePowerStatus()<ELow)
       
  1691 				r=KErrBadPower;
       
  1692 			else
       
  1693 				SetBacklightState(TBool(a1));
       
  1694 			break;
       
  1695 
       
  1696 		case EDisplayHalBacklightOn:
       
  1697 			kumemput32(a1,&iBacklightOn,sizeof(TInt));
       
  1698 			break;
       
  1699 
       
  1700 		case EDisplayHalModeCount:
       
  1701 			{
       
  1702 			TInt ndm = SCREEN_UNIT_COUNT;
       
  1703 			kumemput32(a1, &ndm, sizeof(ndm));
       
  1704 			break;
       
  1705 			}
       
  1706 
       
  1707 		case EDisplayHalSetMode:
       
  1708 			if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetMode")))
       
  1709 				return KErrPermissionDenied;
       
  1710 			r = SetDisplayMode((TInt)a1);
       
  1711 			break;
       
  1712 
       
  1713 		case EDisplayHalMode:
       
  1714 			kumemput32(a1, &iVideoInfo.iDisplayMode, sizeof(iVideoInfo.iDisplayMode));
       
  1715 			break;
       
  1716 
       
  1717 		case EDisplayHalSetPaletteEntry:
       
  1718 			if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetPaletteEntry")))
       
  1719 				return KErrPermissionDenied;
       
  1720 			r = SetPaletteEntry((TInt)a1, (TInt)a2);
       
  1721 			break;
       
  1722 
       
  1723 		case EDisplayHalPaletteEntry:
       
  1724 			{
       
  1725 			TInt entry;
       
  1726 			kumemget32(&entry, a1, sizeof(TInt));
       
  1727 			TInt x;
       
  1728 			r = GetPaletteEntry(entry, &x);
       
  1729 			if (r == KErrNone)
       
  1730 				kumemput32(a2, &x, sizeof(x));
       
  1731 			break;
       
  1732 			}
       
  1733 
       
  1734 		case EDisplayHalSetState:
       
  1735 			{
       
  1736 			if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetState")))
       
  1737 				return KErrPermissionDenied;
       
  1738 			if ((TBool)a1)
       
  1739 				{
       
  1740 				WsSwitchOnScreen();
       
  1741 				}
       
  1742 			else
       
  1743 				{
       
  1744 				WsSwitchOffScreen();
       
  1745 				}
       
  1746 			break;
       
  1747 			}
       
  1748 
       
  1749 		case EDisplayHalState:
       
  1750 			kumemput32(a1, &iDisplayOn, sizeof(TBool));
       
  1751 			break;
       
  1752 
       
  1753 		case EDisplayHalColors:
       
  1754 			{
       
  1755 			TInt mdc = KConfigLcdMaxDisplayColors;
       
  1756 			kumemput32(a1, &mdc, sizeof(mdc));
       
  1757 			break;
       
  1758 			}
       
  1759 
       
  1760 		case EDisplayHalCurrentModeInfo:
       
  1761 			{
       
  1762 			TPckgBuf<TVideoInfoV01> vPckg;
       
  1763 			r = GetCurrentDisplayModeInfo(vPckg(), (TBool)a2);
       
  1764 			if (KErrNone == r)
       
  1765 				Kern::InfoCopy(*(TDes8*)a1,vPckg);
       
  1766 			}
       
  1767 			break;
       
  1768 
       
  1769 		case EDisplayHalSpecifiedModeInfo:
       
  1770 			{
       
  1771 			TPckgBuf<TVideoInfoV01> vPckg;
       
  1772 			TInt screenNumber;
       
  1773 			kumemget32(&screenNumber, a1, sizeof(screenNumber));
       
  1774 			r = GetSpecifiedDisplayModeInfo(screenNumber, vPckg());
       
  1775 			if (KErrNone == r)
       
  1776 				Kern::InfoCopy(*(TDes8*)a2,vPckg);
       
  1777 			}
       
  1778 			break;
       
  1779 
       
  1780 		case EDisplayHalSecure:
       
  1781 			kumemput32(a1, &iSecureDisplay, sizeof(TBool));
       
  1782 			break;
       
  1783 
       
  1784 		case EDisplayHalSetSecure:
       
  1785 			{
       
  1786 			if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetSecure")))
       
  1787 				return KErrPermissionDenied;
       
  1788 			SwitchDisplay((TBool)a1);
       
  1789 			}
       
  1790 			break;
       
  1791 
       
  1792 		default:
       
  1793 			r=KErrNotSupported;
       
  1794 			break;
       
  1795 		}
       
  1796 	return r;
       
  1797 	}
       
  1798 
       
  1799 
       
  1800 DECLARE_STANDARD_EXTENSION()
       
  1801 	{
       
  1802 	__KTRACE_OPT(KPOWER,Kern::Printf("Starting LCD power manager"));
       
  1803 
       
  1804 	// create LCD power handler
       
  1805 	TInt r=KErrNoMemory;
       
  1806 	DLcdPowerHandler* pH=new DLcdPowerHandler;
       
  1807 	if (pH)
       
  1808 		{
       
  1809 		//The same DFC queue will be used by both the LCD extension and GCE PDD
       
  1810 		r= Kern::DfcQCreate( pH->iDfcQ, KDisplay0ThreadPriority, &KDisplay0DfcThread );
       
  1811 		if ( r == KErrNone)
       
  1812 			{
       
  1813 			 r =pH->Create();
       
  1814 			__KTRACE_OPT(KPOWER,Kern::Printf("Returns %d",r));
       
  1815 
       
  1816 			if ( r == KErrNone)
       
  1817 				{
       
  1818 				DDisplayPddFactory * device = new DDisplayPddFactory;
       
  1819 
       
  1820 				if (device==NULL)
       
  1821 					{
       
  1822 					r=KErrNoMemory;
       
  1823 					}
       
  1824 				else
       
  1825 					{
       
  1826 					r=Kern::InstallPhysicalDevice(device);
       
  1827 					}
       
  1828 
       
  1829 				#ifdef CPU_AFFINITY_ANY
       
  1830                 NKern::ThreadSetCpuAffinity((NThread*) pH->iDfcQ->iThread, KCpuAffinityAny);
       
  1831 				#endif
       
  1832 
       
  1833 				__KTRACE_OPT(KEXTENSION,Kern::Printf("Installing the display device from the kernel extension returned with error code %d",r));
       
  1834 
       
  1835 				}
       
  1836 			}
       
  1837 
       
  1838 		}
       
  1839 	return r;
       
  1840 	}
       
  1841