|
1 /* |
|
2 * Copyright (c) 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 the License "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: Minimalistic frame buffer driver |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <syborg_priv.h> |
|
19 #include "syborg_fb.h" |
|
20 |
|
21 TPhysAddr Syborg::VideoRamPhys; |
|
22 TPhysAddr Syborg::VideoRamPhysSecure; // Secure display memory |
|
23 |
|
24 TPhysAddr TSyborg::VideoRamPhys() |
|
25 { |
|
26 __KTRACE_OPT(KEXTENSION,Kern::Printf("TSyborg::VideoRamPhys: VideoRamPhys=0x%x", Syborg::VideoRamPhys)); |
|
27 return Syborg::VideoRamPhys; |
|
28 } |
|
29 |
|
30 TPhysAddr TSyborg::VideoRamPhysSecure() |
|
31 { |
|
32 return Syborg::VideoRamPhysSecure; |
|
33 } |
|
34 |
|
35 LOCAL_C TInt DoHalFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2) |
|
36 { |
|
37 DLcdPowerHandler* pH=(DLcdPowerHandler*)aPtr; |
|
38 return pH->HalFunction(aFunction,a1,a2); |
|
39 } |
|
40 |
|
41 static void rxMsg(TAny* aPtr) |
|
42 { |
|
43 DLcdPowerHandler& h=*(DLcdPowerHandler*)aPtr; |
|
44 TMessageBase* pM = h.iMsgQ.iMessage; |
|
45 if(pM) |
|
46 h.HandleMsg(pM); |
|
47 } |
|
48 |
|
49 static void power_up_dfc(TAny* aPtr) |
|
50 { |
|
51 ((DLcdPowerHandler*)aPtr)->PowerUpDfc(); |
|
52 } |
|
53 |
|
54 void power_down_dfc(TAny* aPtr) |
|
55 { |
|
56 ((DLcdPowerHandler*)aPtr)->PowerDownDfc(); |
|
57 } |
|
58 |
|
59 void DLcdPowerHandler::DisplayOn() |
|
60 { |
|
61 PowerUpLcd(iSecureDisplay); |
|
62 iDisplayOn = ETrue; |
|
63 } |
|
64 |
|
65 void DLcdPowerHandler::DisplayOff() |
|
66 { |
|
67 PowerDownLcd(); |
|
68 iDisplayOn = EFalse; |
|
69 } |
|
70 |
|
71 void DLcdPowerHandler::SwitchDisplay(TBool aSecure) |
|
72 { |
|
73 if(aSecure) |
|
74 { |
|
75 if(!iSecureDisplay) |
|
76 { |
|
77 DisplayOff(); |
|
78 iSecureDisplay = ETrue; |
|
79 DisplayOn(); |
|
80 } |
|
81 } |
|
82 else |
|
83 { |
|
84 if(iSecureDisplay) |
|
85 { |
|
86 DisplayOff(); |
|
87 iSecureDisplay = EFalse; |
|
88 DisplayOn(); |
|
89 } |
|
90 } |
|
91 } |
|
92 |
|
93 void DLcdPowerHandler::PowerUpDfc() |
|
94 { |
|
95 DisplayOn(); |
|
96 PowerUpDone(); |
|
97 } |
|
98 |
|
99 void DLcdPowerHandler::PowerDownDfc() |
|
100 { |
|
101 DisplayOff(); |
|
102 PowerDownDone(); |
|
103 } |
|
104 |
|
105 void DLcdPowerHandler::PowerDown(TPowerState) |
|
106 { |
|
107 iPowerDownDfc.Enque(); |
|
108 } |
|
109 |
|
110 void DLcdPowerHandler::PowerUp() |
|
111 { |
|
112 iPowerUpDfc.Enque(); |
|
113 } |
|
114 |
|
115 void DLcdPowerHandler::PowerUpLcd(TBool aSecure) |
|
116 { |
|
117 #if 1 |
|
118 WriteReg(iPortAddr, FB_ENABLED, 0); |
|
119 WriteReg(iPortAddr, FB_BASE, aSecure ? iSecurevRamPhys : ivRamPhys); |
|
120 WriteReg(iPortAddr, FB_WIDTH, iVideoInfo.iSizeInPixels.iWidth); |
|
121 WriteReg(iPortAddr, FB_BLANK, 0); |
|
122 WriteReg(iPortAddr, FB_BPP, 32); |
|
123 WriteReg(iPortAddr, FB_COLOR_ORDER, 0); |
|
124 WriteReg(iPortAddr, FB_BYTE_ORDER, 0); |
|
125 WriteReg(iPortAddr, FB_PIXEL_ORDER, 0); |
|
126 WriteReg(iPortAddr, FB_INT_MASK, 0); |
|
127 WriteReg(iPortAddr, FB_ENABLED, 1); |
|
128 WriteReg(iPortAddr, FB_HEIGHT, iVideoInfo.iSizeInPixels.iHeight); |
|
129 #endif |
|
130 } |
|
131 |
|
132 void DLcdPowerHandler::PowerDownLcd() |
|
133 { |
|
134 WriteReg(iPortAddr, FB_BLANK, 1); |
|
135 } |
|
136 |
|
137 DLcdPowerHandler::DLcdPowerHandler() |
|
138 : DPowerHandler(KLitLcd), |
|
139 iMsgQ(rxMsg,this,NULL,1), |
|
140 iPowerUpDfc(&power_up_dfc,this,6), |
|
141 iPowerDownDfc(&power_down_dfc,this,7) |
|
142 { |
|
143 } |
|
144 |
|
145 void DLcdPowerHandler::ScreenInfo(TScreenInfoV01& anInfo) |
|
146 { |
|
147 anInfo.iWindowHandleValid = EFalse; |
|
148 anInfo.iWindowHandle = NULL; |
|
149 anInfo.iScreenAddressValid = ETrue; |
|
150 anInfo.iScreenAddress = (TAny *)(iChunk->LinearAddress()); |
|
151 anInfo.iScreenSize.iWidth = iVideoInfo.iSizeInPixels.iWidth; |
|
152 anInfo.iScreenSize.iHeight = iVideoInfo.iSizeInPixels.iHeight; |
|
153 } |
|
154 |
|
155 void DLcdPowerHandler::HandleMsg(TMessageBase* aMsg) |
|
156 { |
|
157 if(aMsg->iValue) |
|
158 DisplayOn(); |
|
159 else |
|
160 DisplayOff(); |
|
161 aMsg->Complete(KErrNone,ETrue); |
|
162 } |
|
163 |
|
164 void DLcdPowerHandler::WsSwitchOnScreen() |
|
165 { |
|
166 TThreadMessage& m = Kern::Message(); |
|
167 m.iValue = ETrue; |
|
168 m.SendReceive(&iMsgQ); |
|
169 } |
|
170 |
|
171 void DLcdPowerHandler::WsSwitchOffScreen() |
|
172 { |
|
173 TThreadMessage& m = Kern::Message(); |
|
174 m.iValue = EFalse; |
|
175 m.SendReceive(&iMsgQ); |
|
176 } |
|
177 |
|
178 TInt DLcdPowerHandler::GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure) |
|
179 { |
|
180 NKern::FMWait(&iLock); |
|
181 if(aSecure) |
|
182 aInfo = iSecureVideoInfo; |
|
183 else |
|
184 aInfo = iVideoInfo; |
|
185 NKern::FMSignal(&iLock); |
|
186 return KErrNone; |
|
187 } |
|
188 |
|
189 TInt DLcdPowerHandler::GetSpecifiedDisplayModeInfo(TInt aMode, TVideoInfoV01& aInfo) |
|
190 { |
|
191 if(aMode < 0 || aMode >= KConfigLcdNumberOfDisplayModes) |
|
192 return KErrArgument; |
|
193 |
|
194 NKern::FMWait(&iLock); |
|
195 aInfo = iVideoInfo; |
|
196 NKern::FMSignal(&iLock); |
|
197 |
|
198 if(aMode != aInfo.iDisplayMode) |
|
199 { |
|
200 aInfo.iOffsetToFirstPixel = KCOnfigOffsetToFirstPixel; |
|
201 aInfo.iIsPalettized = KConfigIsPalettized; |
|
202 aInfo.iOffsetBetweenLines = KCOnfigOffsetBetweenLines; |
|
203 aInfo.iBitsPerPixel = KConfigBitsPerPixel; |
|
204 } |
|
205 return KErrNone; |
|
206 } |
|
207 |
|
208 TInt DLcdPowerHandler::AllocateFrameBuffer() |
|
209 { |
|
210 // Allocate physical RAM for video |
|
211 TInt vSize = TSyborg::VideoRamSize(); |
|
212 |
|
213 NKern::ThreadEnterCS(); |
|
214 TInt r = Epoc::AllocPhysicalRam(vSize,Syborg::VideoRamPhys); |
|
215 if (r != KErrNone) |
|
216 { |
|
217 NKern::ThreadLeaveCS(); |
|
218 Kern::Fault("AllocVideoRam",r); |
|
219 } |
|
220 |
|
221 // Map the video RAM |
|
222 ivRamPhys = TSyborg::VideoRamPhys(); |
|
223 |
|
224 r = DPlatChunkHw::New(iChunk,ivRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC); |
|
225 |
|
226 NKern::ThreadLeaveCS(); |
|
227 |
|
228 if(r != KErrNone) |
|
229 return r; |
|
230 |
|
231 TUint* pV = (TUint*)iChunk->LinearAddress(); |
|
232 |
|
233 // Allocate physical RAM for secure display |
|
234 NKern::ThreadEnterCS(); |
|
235 r = Epoc::AllocPhysicalRam(vSize,Syborg::VideoRamPhysSecure); |
|
236 if (r != KErrNone) |
|
237 { |
|
238 NKern::ThreadLeaveCS(); |
|
239 Kern::Fault("AllocVideoRam 2",r); |
|
240 } |
|
241 iSecurevRamPhys = ivRamPhys + vSize; |
|
242 TInt r2 = DPlatChunkHw::New(iSecureChunk,iSecurevRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC); |
|
243 |
|
244 NKern::ThreadLeaveCS(); |
|
245 |
|
246 if(r2 != KErrNone) |
|
247 return r2; |
|
248 |
|
249 TUint* pV2 = (TUint*)iSecureChunk->LinearAddress(); |
|
250 |
|
251 iVideoInfo.iSizeInPixels.iWidth = KConfigLcdWidth; |
|
252 iVideoInfo.iSizeInPixels.iHeight = KConfigLcdHeight; |
|
253 iVideoInfo.iDisplayMode = KConfigLcdDisplayMode; |
|
254 iVideoInfo.iOffsetToFirstPixel = KCOnfigOffsetToFirstPixel; |
|
255 iVideoInfo.iOffsetBetweenLines = KCOnfigOffsetBetweenLines; |
|
256 iVideoInfo.iIsPalettized = KConfigIsPalettized; |
|
257 iVideoInfo.iBitsPerPixel = KConfigBitsPerPixel; |
|
258 iVideoInfo.iSizeInTwips.iWidth = KConfigLcdWidthInTwips; |
|
259 iVideoInfo.iSizeInTwips.iHeight = KConfigLcdHeightInTwips; |
|
260 iVideoInfo.iIsMono = KConfigIsMono; |
|
261 iVideoInfo.iVideoAddress = (TInt)pV; |
|
262 iVideoInfo.iIsPixelOrderLandscape = KConfigPixelOrderLandscape; |
|
263 iVideoInfo.iIsPixelOrderRGB = KConfigPixelOrderRGB; |
|
264 |
|
265 iSecureVideoInfo = iVideoInfo; |
|
266 iSecureVideoInfo.iVideoAddress = (TInt)pV2; |
|
267 |
|
268 #if 0 |
|
269 WriteReg(iPortAddr, FB_ENABLED, 0); |
|
270 WriteReg(IPortAddr, FB_INT_MASK, 0); |
|
271 WriteReg(iPortAddr, FB_BASE, iSecureDisplay ? iSecurevRamPhys : ivRamPhys); |
|
272 WriteReg(iPortAddr, FB_WIDTH, iVideoInfo.iSizeInPixels.iWidth); |
|
273 WriteReg(iPortAddr, FB_HEIGHT, iVideoInfo.iSizeInPixels.iHeight); |
|
274 WriteReg(iPortAddr, FB_BLANK, 0); |
|
275 WriteReg(iPortAddr, FB_ENABLED, 1); |
|
276 #endif |
|
277 |
|
278 return KErrNone; |
|
279 } |
|
280 |
|
281 |
|
282 TInt DLcdPowerHandler::SetDisplayMode(TInt aMode) |
|
283 { |
|
284 if(aMode < 0 || aMode >= KConfigLcdNumberOfDisplayModes) |
|
285 return KErrArgument; |
|
286 |
|
287 // store the current mode |
|
288 iVideoInfo.iDisplayMode = aMode; |
|
289 |
|
290 // store the current mode for secure screen |
|
291 iSecureVideoInfo.iDisplayMode = aMode; |
|
292 |
|
293 return KErrNone; |
|
294 } |
|
295 |
|
296 TInt DLcdPowerHandler::HalFunction(TInt aFunction, TAny* a1, TAny* a2) |
|
297 { |
|
298 TInt r=KErrNone; |
|
299 switch(aFunction) |
|
300 { |
|
301 case EDisplayHalScreenInfo: |
|
302 { |
|
303 TPckgBuf<TScreenInfoV01> vPckg; |
|
304 ScreenInfo(vPckg()); |
|
305 Kern::InfoCopy(*(TDes8*)a1,vPckg); |
|
306 break; |
|
307 } |
|
308 case EDisplayHalWsRegisterSwitchOnScreenHandling: |
|
309 { |
|
310 iWsSwitchOnScreen=(TBool)a1; |
|
311 break; |
|
312 } |
|
313 case EDisplayHalWsSwitchOnScreen: |
|
314 { |
|
315 WsSwitchOnScreen(); |
|
316 break; |
|
317 } |
|
318 case EDisplayHalModeCount: |
|
319 { |
|
320 TInt ndm = KConfigLcdNumberOfDisplayModes; |
|
321 kumemput32(a1, &ndm, sizeof(ndm)); |
|
322 break; |
|
323 } |
|
324 case EDisplayHalSetMode: |
|
325 { |
|
326 __KTRACE_OPT(KEXTENSION,Kern::Printf("EDisplayHalSetMode")); |
|
327 __SECURE_KERNEL( |
|
328 if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetMode"))) |
|
329 return KErrPermissionDenied; |
|
330 ) |
|
331 r = SetDisplayMode((TInt)a1); |
|
332 break; |
|
333 } |
|
334 case EDisplayHalMode: |
|
335 { |
|
336 kumemput32(a1, &iVideoInfo.iDisplayMode, sizeof(iVideoInfo.iDisplayMode)); |
|
337 r = KErrNone; |
|
338 break; |
|
339 } |
|
340 case EDisplayHalSetPaletteEntry: |
|
341 { |
|
342 __SECURE_KERNEL( |
|
343 if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetPaletteEntry"))) |
|
344 return KErrPermissionDenied; |
|
345 ) |
|
346 r = KErrNotSupported; |
|
347 break; |
|
348 } |
|
349 case EDisplayHalPaletteEntry: |
|
350 { |
|
351 TInt entry; |
|
352 kumemget32(&entry, a1, sizeof(TInt)); |
|
353 r = KErrNotSupported; |
|
354 break; |
|
355 } |
|
356 case EDisplayHalSetState: |
|
357 { |
|
358 __SECURE_KERNEL( |
|
359 if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetState"))) |
|
360 return KErrPermissionDenied; |
|
361 ) |
|
362 if((TBool)a1) |
|
363 WsSwitchOnScreen(); |
|
364 else |
|
365 WsSwitchOffScreen(); |
|
366 break; |
|
367 } |
|
368 case EDisplayHalState: |
|
369 { |
|
370 kumemput32(a1, &iDisplayOn, sizeof(TBool)); |
|
371 break; |
|
372 } |
|
373 case EDisplayHalColors: |
|
374 { |
|
375 TInt mdc = 1<<24; |
|
376 kumemput32(a1, &mdc, sizeof(mdc)); |
|
377 break; |
|
378 } |
|
379 case EDisplayHalCurrentModeInfo: |
|
380 { |
|
381 TPckgBuf<TVideoInfoV01> vPckg; |
|
382 r = GetCurrentDisplayModeInfo(vPckg(), (TBool)a2); |
|
383 if(KErrNone == r) |
|
384 Kern::InfoCopy(*(TDes8*)a1,vPckg); |
|
385 break; |
|
386 } |
|
387 case EDisplayHalSpecifiedModeInfo: |
|
388 { |
|
389 TPckgBuf<TVideoInfoV01> vPckg; |
|
390 TInt mode; |
|
391 kumemget32(&mode, a1, sizeof(mode)); |
|
392 r = GetSpecifiedDisplayModeInfo(mode, vPckg()); |
|
393 if(KErrNone == r) |
|
394 Kern::InfoCopy(*(TDes8*)a2,vPckg); |
|
395 break; |
|
396 } |
|
397 case EDisplayHalSecure: |
|
398 { |
|
399 kumemput32(a1, &iSecureDisplay, sizeof(TBool)); |
|
400 break; |
|
401 } |
|
402 case EDisplayHalSetSecure: |
|
403 { |
|
404 __SECURE_KERNEL( |
|
405 if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetSecure"))) |
|
406 return KErrPermissionDenied; |
|
407 ) |
|
408 SwitchDisplay((TBool)a1); |
|
409 break; |
|
410 } |
|
411 default: |
|
412 { |
|
413 r = KErrNotSupported; |
|
414 break; |
|
415 } |
|
416 } |
|
417 return r; |
|
418 } |
|
419 |
|
420 TInt DLcdPowerHandler::Create() |
|
421 { |
|
422 iDfcQ = Kern::DfcQue0(); // use low priority DFC queue for this driver |
|
423 |
|
424 iPortAddr = KHwBaseClcd; |
|
425 |
|
426 // !@! |
|
427 #if 0 |
|
428 // Map the video RAM |
|
429 TInt vSize = TSyborg::VideoRamSize(); |
|
430 ivRamPhys = TSyborg::VideoRamPhys(); |
|
431 |
|
432 TInt r = DPlatChunkHw::New(iChunk,ivRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC); |
|
433 if(r != KErrNone) |
|
434 return r; |
|
435 |
|
436 TUint* pV = (TUint*)iChunk->LinearAddress(); |
|
437 |
|
438 iSecurevRamPhys = ivRamPhys + vSize; |
|
439 TInt r2 = DPlatChunkHw::New(iSecureChunk,iSecurevRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC); |
|
440 if(r2 != KErrNone) |
|
441 return r2; |
|
442 |
|
443 TUint* pV2 = (TUint*)iSecureChunk->LinearAddress(); |
|
444 #endif |
|
445 |
|
446 iVideoInfo.iSizeInPixels.iWidth = KConfigLcdWidth; |
|
447 iVideoInfo.iSizeInPixels.iHeight = KConfigLcdHeight; |
|
448 iVideoInfo.iDisplayMode = KConfigLcdDisplayMode; |
|
449 iVideoInfo.iOffsetToFirstPixel = KCOnfigOffsetToFirstPixel; |
|
450 iVideoInfo.iOffsetBetweenLines = KCOnfigOffsetBetweenLines; |
|
451 iVideoInfo.iIsPalettized = KConfigIsPalettized; |
|
452 iVideoInfo.iBitsPerPixel = KConfigBitsPerPixel; |
|
453 iVideoInfo.iSizeInTwips.iWidth = KConfigLcdWidthInTwips; |
|
454 iVideoInfo.iSizeInTwips.iHeight = KConfigLcdHeightInTwips; |
|
455 iVideoInfo.iIsMono = KConfigIsMono; |
|
456 // !@! iVideoInfo.iVideoAddress = (TInt)pV; |
|
457 iVideoInfo.iIsPixelOrderLandscape = KConfigPixelOrderLandscape; |
|
458 iVideoInfo.iIsPixelOrderRGB = KConfigPixelOrderRGB; |
|
459 |
|
460 iSecureVideoInfo = iVideoInfo; |
|
461 // !@! iSecureVideoInfo.iVideoAddress = (TInt)pV2; |
|
462 |
|
463 AllocateFrameBuffer(); |
|
464 TInt r = Kern::AddHalEntry(EHalGroupDisplay,DoHalFunction,this); |
|
465 if(r != KErrNone) |
|
466 return r; |
|
467 |
|
468 iPowerUpDfc.SetDfcQ(iDfcQ); |
|
469 iPowerDownDfc.SetDfcQ(iDfcQ); |
|
470 iMsgQ.SetDfcQ(iDfcQ); |
|
471 iMsgQ.Receive(); |
|
472 |
|
473 Add(); |
|
474 DisplayOn(); |
|
475 |
|
476 return KErrNone; |
|
477 } |
|
478 |
|
479 DECLARE_STANDARD_EXTENSION() |
|
480 { |
|
481 TInt r = KErrNoMemory; |
|
482 DLcdPowerHandler* pH=new DLcdPowerHandler; |
|
483 if(pH) |
|
484 r = pH->Create(); |
|
485 |
|
486 return r; |
|
487 } |