diff options
Diffstat (limited to 'drivers/gpu/pvr/power.c')
-rw-r--r-- | drivers/gpu/pvr/power.c | 727 |
1 files changed, 727 insertions, 0 deletions
diff --git a/drivers/gpu/pvr/power.c b/drivers/gpu/pvr/power.c new file mode 100644 index 00000000000..ba0eced9ba1 --- /dev/null +++ b/drivers/gpu/pvr/power.c | |||
@@ -0,0 +1,727 @@ | |||
1 | /********************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful but, except | ||
10 | * as otherwise stated in writing, without any warranty; without even the | ||
11 | * implied warranty of merchantability or fitness for a particular purpose. | ||
12 | * See the GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in | ||
19 | * the file called "COPYING". | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * Imagination Technologies Ltd. <gpl-support@imgtec.com> | ||
23 | * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK | ||
24 | * | ||
25 | ******************************************************************************/ | ||
26 | |||
27 | #include "services_headers.h" | ||
28 | #include "pdump_km.h" | ||
29 | |||
30 | #include "lists.h" | ||
31 | |||
32 | static IMG_BOOL gbInitServerRunning = IMG_FALSE; | ||
33 | static IMG_BOOL gbInitServerRan = IMG_FALSE; | ||
34 | static IMG_BOOL gbInitSuccessful = IMG_FALSE; | ||
35 | |||
36 | IMG_EXPORT | ||
37 | PVRSRV_ERROR PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState, IMG_BOOL bState) | ||
38 | { | ||
39 | |||
40 | switch(eInitServerState) | ||
41 | { | ||
42 | case PVRSRV_INIT_SERVER_RUNNING: | ||
43 | gbInitServerRunning = bState; | ||
44 | break; | ||
45 | case PVRSRV_INIT_SERVER_RAN: | ||
46 | gbInitServerRan = bState; | ||
47 | break; | ||
48 | case PVRSRV_INIT_SERVER_SUCCESSFUL: | ||
49 | gbInitSuccessful = bState; | ||
50 | break; | ||
51 | default: | ||
52 | PVR_DPF((PVR_DBG_ERROR, | ||
53 | "PVRSRVSetInitServerState : Unknown state %x", eInitServerState)); | ||
54 | return PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE; | ||
55 | } | ||
56 | |||
57 | return PVRSRV_OK; | ||
58 | } | ||
59 | |||
60 | IMG_EXPORT | ||
61 | IMG_BOOL PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState) | ||
62 | { | ||
63 | IMG_BOOL bReturnVal; | ||
64 | |||
65 | switch(eInitServerState) | ||
66 | { | ||
67 | case PVRSRV_INIT_SERVER_RUNNING: | ||
68 | bReturnVal = gbInitServerRunning; | ||
69 | break; | ||
70 | case PVRSRV_INIT_SERVER_RAN: | ||
71 | bReturnVal = gbInitServerRan; | ||
72 | break; | ||
73 | case PVRSRV_INIT_SERVER_SUCCESSFUL: | ||
74 | bReturnVal = gbInitSuccessful; | ||
75 | break; | ||
76 | default: | ||
77 | PVR_DPF((PVR_DBG_ERROR, | ||
78 | "PVRSRVGetInitServerState : Unknown state %x", eInitServerState)); | ||
79 | bReturnVal = IMG_FALSE; | ||
80 | } | ||
81 | |||
82 | return bReturnVal; | ||
83 | } | ||
84 | |||
85 | static IMG_BOOL _IsSystemStatePowered(PVRSRV_SYS_POWER_STATE eSystemPowerState) | ||
86 | { | ||
87 | return (IMG_BOOL)(eSystemPowerState < PVRSRV_SYS_POWER_STATE_D2); | ||
88 | } | ||
89 | |||
90 | |||
91 | IMG_EXPORT | ||
92 | PVRSRV_ERROR PVRSRVPowerLock(IMG_UINT32 ui32CallerID, | ||
93 | IMG_BOOL bSystemPowerEvent) | ||
94 | { | ||
95 | PVRSRV_ERROR eError; | ||
96 | SYS_DATA *psSysData; | ||
97 | IMG_UINT32 ui32Timeout = 1000000; | ||
98 | |||
99 | #if defined(SUPPORT_LMA) | ||
100 | |||
101 | ui32Timeout *= 60; | ||
102 | #endif | ||
103 | |||
104 | SysAcquireData(&psSysData); | ||
105 | |||
106 | #if defined(SYS_CUSTOM_POWERLOCK_WRAP) | ||
107 | eError = SysPowerLockWrap(psSysData); | ||
108 | if (eError != PVRSRV_OK) | ||
109 | { | ||
110 | return eError; | ||
111 | } | ||
112 | #endif | ||
113 | do | ||
114 | { | ||
115 | eError = OSLockResource(&psSysData->sPowerStateChangeResource, | ||
116 | ui32CallerID); | ||
117 | if (eError == PVRSRV_OK) | ||
118 | { | ||
119 | break; | ||
120 | } | ||
121 | else if (ui32CallerID == ISR_ID) | ||
122 | { | ||
123 | |||
124 | |||
125 | eError = PVRSRV_ERROR_RETRY; | ||
126 | break; | ||
127 | } | ||
128 | |||
129 | OSWaitus(1); | ||
130 | ui32Timeout--; | ||
131 | } while (ui32Timeout > 0); | ||
132 | |||
133 | #if defined(SYS_CUSTOM_POWERLOCK_WRAP) | ||
134 | if (eError != PVRSRV_OK) | ||
135 | { | ||
136 | SysPowerLockUnwrap(psSysData); | ||
137 | } | ||
138 | #endif | ||
139 | |||
140 | if ((eError == PVRSRV_OK) && | ||
141 | !bSystemPowerEvent && | ||
142 | !_IsSystemStatePowered(psSysData->eCurrentPowerState)) | ||
143 | { | ||
144 | |||
145 | PVRSRVPowerUnlock(ui32CallerID); | ||
146 | eError = PVRSRV_ERROR_RETRY; | ||
147 | } | ||
148 | |||
149 | return eError; | ||
150 | } | ||
151 | |||
152 | |||
153 | IMG_EXPORT | ||
154 | IMG_VOID PVRSRVPowerUnlock(IMG_UINT32 ui32CallerID) | ||
155 | { | ||
156 | OSUnlockResource(&gpsSysData->sPowerStateChangeResource, ui32CallerID); | ||
157 | #if defined(SYS_CUSTOM_POWERLOCK_WRAP) | ||
158 | SysPowerLockUnwrap(gpsSysData); | ||
159 | #endif | ||
160 | } | ||
161 | |||
162 | |||
163 | static PVRSRV_ERROR PVRSRVDevicePrePowerStateKM_AnyVaCb(PVRSRV_POWER_DEV *psPowerDevice, va_list va) | ||
164 | { | ||
165 | PVRSRV_DEV_POWER_STATE eNewDevicePowerState; | ||
166 | PVRSRV_ERROR eError; | ||
167 | |||
168 | |||
169 | IMG_BOOL bAllDevices; | ||
170 | IMG_UINT32 ui32DeviceIndex; | ||
171 | PVRSRV_DEV_POWER_STATE eNewPowerState; | ||
172 | |||
173 | |||
174 | bAllDevices = va_arg(va, IMG_BOOL); | ||
175 | ui32DeviceIndex = va_arg(va, IMG_UINT32); | ||
176 | eNewPowerState = va_arg(va, PVRSRV_DEV_POWER_STATE); | ||
177 | |||
178 | if (bAllDevices || (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex)) | ||
179 | { | ||
180 | eNewDevicePowerState = (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) ? | ||
181 | psPowerDevice->eDefaultPowerState : eNewPowerState; | ||
182 | |||
183 | if (psPowerDevice->eCurrentPowerState != eNewDevicePowerState) | ||
184 | { | ||
185 | if (psPowerDevice->pfnPrePower != IMG_NULL) | ||
186 | { | ||
187 | |||
188 | eError = psPowerDevice->pfnPrePower(psPowerDevice->hDevCookie, | ||
189 | eNewDevicePowerState, | ||
190 | psPowerDevice->eCurrentPowerState); | ||
191 | if (eError != PVRSRV_OK) | ||
192 | { | ||
193 | return eError; | ||
194 | } | ||
195 | } | ||
196 | |||
197 | |||
198 | eError = SysDevicePrePowerState(psPowerDevice->ui32DeviceIndex, | ||
199 | eNewDevicePowerState, | ||
200 | psPowerDevice->eCurrentPowerState); | ||
201 | if (eError != PVRSRV_OK) | ||
202 | { | ||
203 | return eError; | ||
204 | } | ||
205 | } | ||
206 | } | ||
207 | |||
208 | return PVRSRV_OK; | ||
209 | } | ||
210 | |||
211 | static | ||
212 | PVRSRV_ERROR PVRSRVDevicePrePowerStateKM(IMG_BOOL bAllDevices, | ||
213 | IMG_UINT32 ui32DeviceIndex, | ||
214 | PVRSRV_DEV_POWER_STATE eNewPowerState) | ||
215 | { | ||
216 | PVRSRV_ERROR eError; | ||
217 | SYS_DATA *psSysData; | ||
218 | |||
219 | SysAcquireData(&psSysData); | ||
220 | |||
221 | |||
222 | eError = List_PVRSRV_POWER_DEV_PVRSRV_ERROR_Any_va(psSysData->psPowerDeviceList, | ||
223 | &PVRSRVDevicePrePowerStateKM_AnyVaCb, | ||
224 | bAllDevices, | ||
225 | ui32DeviceIndex, | ||
226 | eNewPowerState); | ||
227 | |||
228 | return eError; | ||
229 | } | ||
230 | |||
231 | static PVRSRV_ERROR PVRSRVDevicePostPowerStateKM_AnyVaCb(PVRSRV_POWER_DEV *psPowerDevice, va_list va) | ||
232 | { | ||
233 | PVRSRV_DEV_POWER_STATE eNewDevicePowerState; | ||
234 | PVRSRV_ERROR eError; | ||
235 | |||
236 | |||
237 | IMG_BOOL bAllDevices; | ||
238 | IMG_UINT32 ui32DeviceIndex; | ||
239 | PVRSRV_DEV_POWER_STATE eNewPowerState; | ||
240 | |||
241 | |||
242 | bAllDevices = va_arg(va, IMG_BOOL); | ||
243 | ui32DeviceIndex = va_arg(va, IMG_UINT32); | ||
244 | eNewPowerState = va_arg(va, PVRSRV_DEV_POWER_STATE); | ||
245 | |||
246 | if (bAllDevices || (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex)) | ||
247 | { | ||
248 | eNewDevicePowerState = (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) ? | ||
249 | psPowerDevice->eDefaultPowerState : eNewPowerState; | ||
250 | |||
251 | if (psPowerDevice->eCurrentPowerState != eNewDevicePowerState) | ||
252 | { | ||
253 | |||
254 | eError = SysDevicePostPowerState(psPowerDevice->ui32DeviceIndex, | ||
255 | eNewDevicePowerState, | ||
256 | psPowerDevice->eCurrentPowerState); | ||
257 | if (eError != PVRSRV_OK) | ||
258 | { | ||
259 | return eError; | ||
260 | } | ||
261 | |||
262 | if (psPowerDevice->pfnPostPower != IMG_NULL) | ||
263 | { | ||
264 | |||
265 | eError = psPowerDevice->pfnPostPower(psPowerDevice->hDevCookie, | ||
266 | eNewDevicePowerState, | ||
267 | psPowerDevice->eCurrentPowerState); | ||
268 | if (eError != PVRSRV_OK) | ||
269 | { | ||
270 | return eError; | ||
271 | } | ||
272 | } | ||
273 | |||
274 | psPowerDevice->eCurrentPowerState = eNewDevicePowerState; | ||
275 | } | ||
276 | } | ||
277 | return PVRSRV_OK; | ||
278 | } | ||
279 | |||
280 | static | ||
281 | PVRSRV_ERROR PVRSRVDevicePostPowerStateKM(IMG_BOOL bAllDevices, | ||
282 | IMG_UINT32 ui32DeviceIndex, | ||
283 | PVRSRV_DEV_POWER_STATE eNewPowerState) | ||
284 | { | ||
285 | PVRSRV_ERROR eError; | ||
286 | SYS_DATA *psSysData; | ||
287 | |||
288 | SysAcquireData(&psSysData); | ||
289 | |||
290 | |||
291 | eError = List_PVRSRV_POWER_DEV_PVRSRV_ERROR_Any_va(psSysData->psPowerDeviceList, | ||
292 | &PVRSRVDevicePostPowerStateKM_AnyVaCb, | ||
293 | bAllDevices, | ||
294 | ui32DeviceIndex, | ||
295 | eNewPowerState); | ||
296 | |||
297 | return eError; | ||
298 | } | ||
299 | |||
300 | |||
301 | IMG_EXPORT | ||
302 | PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(IMG_UINT32 ui32DeviceIndex, | ||
303 | PVRSRV_DEV_POWER_STATE eNewPowerState, | ||
304 | IMG_UINT32 ui32CallerID, | ||
305 | IMG_BOOL bRetainMutex) | ||
306 | { | ||
307 | PVRSRV_ERROR eError; | ||
308 | SYS_DATA *psSysData; | ||
309 | |||
310 | SysAcquireData(&psSysData); | ||
311 | |||
312 | eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE); | ||
313 | if(eError != PVRSRV_OK) | ||
314 | { | ||
315 | return eError; | ||
316 | } | ||
317 | |||
318 | #if defined(PDUMP) | ||
319 | if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) | ||
320 | { | ||
321 | |||
322 | |||
323 | |||
324 | |||
325 | eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON); | ||
326 | if(eError != PVRSRV_OK) | ||
327 | { | ||
328 | goto Exit; | ||
329 | } | ||
330 | |||
331 | eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON); | ||
332 | |||
333 | if (eError != PVRSRV_OK) | ||
334 | { | ||
335 | goto Exit; | ||
336 | } | ||
337 | |||
338 | PDUMPSUSPEND(); | ||
339 | } | ||
340 | #endif | ||
341 | |||
342 | eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState); | ||
343 | if(eError != PVRSRV_OK) | ||
344 | { | ||
345 | if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) | ||
346 | { | ||
347 | PDUMPRESUME(); | ||
348 | } | ||
349 | goto Exit; | ||
350 | } | ||
351 | |||
352 | eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState); | ||
353 | |||
354 | if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) | ||
355 | { | ||
356 | PDUMPRESUME(); | ||
357 | } | ||
358 | |||
359 | Exit: | ||
360 | |||
361 | if(eError != PVRSRV_OK) | ||
362 | { | ||
363 | PVR_DPF((PVR_DBG_ERROR, | ||
364 | "PVRSRVSetDevicePowerStateKM : Transition to %d FAILED 0x%x", eNewPowerState, eError)); | ||
365 | } | ||
366 | |||
367 | if (!bRetainMutex || (eError != PVRSRV_OK)) | ||
368 | { | ||
369 | PVRSRVPowerUnlock(ui32CallerID); | ||
370 | } | ||
371 | |||
372 | return eError; | ||
373 | } | ||
374 | |||
375 | |||
376 | IMG_EXPORT | ||
377 | PVRSRV_ERROR PVRSRVSystemPrePowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState) | ||
378 | { | ||
379 | PVRSRV_ERROR eError; | ||
380 | SYS_DATA *psSysData; | ||
381 | PVRSRV_DEV_POWER_STATE eNewDevicePowerState; | ||
382 | |||
383 | SysAcquireData(&psSysData); | ||
384 | |||
385 | |||
386 | eError = PVRSRVPowerLock(KERNEL_ID, IMG_TRUE); | ||
387 | if(eError != PVRSRV_OK) | ||
388 | { | ||
389 | return eError; | ||
390 | } | ||
391 | |||
392 | if (_IsSystemStatePowered(eNewSysPowerState) != | ||
393 | _IsSystemStatePowered(psSysData->eCurrentPowerState)) | ||
394 | { | ||
395 | if (_IsSystemStatePowered(eNewSysPowerState)) | ||
396 | { | ||
397 | |||
398 | eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_DEFAULT; | ||
399 | } | ||
400 | else | ||
401 | { | ||
402 | eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_OFF; | ||
403 | } | ||
404 | |||
405 | |||
406 | eError = PVRSRVDevicePrePowerStateKM(IMG_TRUE, 0, eNewDevicePowerState); | ||
407 | if (eError != PVRSRV_OK) | ||
408 | { | ||
409 | goto ErrorExit; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | if (eNewSysPowerState != psSysData->eCurrentPowerState) | ||
414 | { | ||
415 | |||
416 | eError = SysSystemPrePowerState(eNewSysPowerState); | ||
417 | if (eError != PVRSRV_OK) | ||
418 | { | ||
419 | goto ErrorExit; | ||
420 | } | ||
421 | } | ||
422 | |||
423 | return eError; | ||
424 | |||
425 | ErrorExit: | ||
426 | |||
427 | PVR_DPF((PVR_DBG_ERROR, | ||
428 | "PVRSRVSystemPrePowerStateKM: Transition from %d to %d FAILED 0x%x", | ||
429 | psSysData->eCurrentPowerState, eNewSysPowerState, eError)); | ||
430 | |||
431 | |||
432 | psSysData->eFailedPowerState = eNewSysPowerState; | ||
433 | |||
434 | PVRSRVPowerUnlock(KERNEL_ID); | ||
435 | |||
436 | return eError; | ||
437 | } | ||
438 | |||
439 | |||
440 | IMG_EXPORT | ||
441 | PVRSRV_ERROR PVRSRVSystemPostPowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState) | ||
442 | { | ||
443 | PVRSRV_ERROR eError = PVRSRV_OK; | ||
444 | SYS_DATA *psSysData; | ||
445 | PVRSRV_DEV_POWER_STATE eNewDevicePowerState; | ||
446 | |||
447 | SysAcquireData(&psSysData); | ||
448 | |||
449 | if (eNewSysPowerState != psSysData->eCurrentPowerState) | ||
450 | { | ||
451 | |||
452 | eError = SysSystemPostPowerState(eNewSysPowerState); | ||
453 | if (eError != PVRSRV_OK) | ||
454 | { | ||
455 | goto Exit; | ||
456 | } | ||
457 | } | ||
458 | |||
459 | if (_IsSystemStatePowered(eNewSysPowerState) != | ||
460 | _IsSystemStatePowered(psSysData->eCurrentPowerState)) | ||
461 | { | ||
462 | if (_IsSystemStatePowered(eNewSysPowerState)) | ||
463 | { | ||
464 | |||
465 | eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_DEFAULT; | ||
466 | } | ||
467 | else | ||
468 | { | ||
469 | eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_OFF; | ||
470 | } | ||
471 | |||
472 | |||
473 | eError = PVRSRVDevicePostPowerStateKM(IMG_TRUE, 0, eNewDevicePowerState); | ||
474 | if (eError != PVRSRV_OK) | ||
475 | { | ||
476 | goto Exit; | ||
477 | } | ||
478 | } | ||
479 | |||
480 | PVR_DPF((PVR_DBG_MESSAGE, | ||
481 | "PVRSRVSystemPostPowerStateKM: System Power Transition from %d to %d OK", | ||
482 | psSysData->eCurrentPowerState, eNewSysPowerState)); | ||
483 | |||
484 | psSysData->eCurrentPowerState = eNewSysPowerState; | ||
485 | |||
486 | Exit: | ||
487 | |||
488 | PVRSRVPowerUnlock(KERNEL_ID); | ||
489 | |||
490 | |||
491 | if (_IsSystemStatePowered(eNewSysPowerState) && | ||
492 | PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL)) | ||
493 | { | ||
494 | |||
495 | |||
496 | |||
497 | PVRSRVScheduleDeviceCallbacks(); | ||
498 | } | ||
499 | |||
500 | return eError; | ||
501 | } | ||
502 | |||
503 | |||
504 | IMG_EXPORT | ||
505 | PVRSRV_ERROR PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState) | ||
506 | { | ||
507 | PVRSRV_ERROR eError; | ||
508 | SYS_DATA *psSysData; | ||
509 | |||
510 | SysAcquireData(&psSysData); | ||
511 | |||
512 | eError = PVRSRVSystemPrePowerStateKM(eNewSysPowerState); | ||
513 | if(eError != PVRSRV_OK) | ||
514 | { | ||
515 | goto ErrorExit; | ||
516 | } | ||
517 | |||
518 | eError = PVRSRVSystemPostPowerStateKM(eNewSysPowerState); | ||
519 | if(eError != PVRSRV_OK) | ||
520 | { | ||
521 | goto ErrorExit; | ||
522 | } | ||
523 | |||
524 | |||
525 | psSysData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified; | ||
526 | |||
527 | return PVRSRV_OK; | ||
528 | |||
529 | ErrorExit: | ||
530 | |||
531 | PVR_DPF((PVR_DBG_ERROR, | ||
532 | "PVRSRVSetPowerStateKM: Transition from %d to %d FAILED 0x%x", | ||
533 | psSysData->eCurrentPowerState, eNewSysPowerState, eError)); | ||
534 | |||
535 | |||
536 | psSysData->eFailedPowerState = eNewSysPowerState; | ||
537 | |||
538 | return eError; | ||
539 | } | ||
540 | |||
541 | |||
542 | PVRSRV_ERROR PVRSRVRegisterPowerDevice(IMG_UINT32 ui32DeviceIndex, | ||
543 | PFN_PRE_POWER pfnPrePower, | ||
544 | PFN_POST_POWER pfnPostPower, | ||
545 | PFN_PRE_CLOCKSPEED_CHANGE pfnPreClockSpeedChange, | ||
546 | PFN_POST_CLOCKSPEED_CHANGE pfnPostClockSpeedChange, | ||
547 | IMG_HANDLE hDevCookie, | ||
548 | PVRSRV_DEV_POWER_STATE eCurrentPowerState, | ||
549 | PVRSRV_DEV_POWER_STATE eDefaultPowerState) | ||
550 | { | ||
551 | PVRSRV_ERROR eError; | ||
552 | SYS_DATA *psSysData; | ||
553 | PVRSRV_POWER_DEV *psPowerDevice; | ||
554 | |||
555 | if (pfnPrePower == IMG_NULL && | ||
556 | pfnPostPower == IMG_NULL) | ||
557 | { | ||
558 | return PVRSRVRemovePowerDevice(ui32DeviceIndex); | ||
559 | } | ||
560 | |||
561 | SysAcquireData(&psSysData); | ||
562 | |||
563 | eError = OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, | ||
564 | sizeof(PVRSRV_POWER_DEV), | ||
565 | (IMG_VOID **)&psPowerDevice, IMG_NULL, | ||
566 | "Power Device"); | ||
567 | if(eError != PVRSRV_OK) | ||
568 | { | ||
569 | PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterPowerDevice: Failed to alloc PVRSRV_POWER_DEV")); | ||
570 | return eError; | ||
571 | } | ||
572 | |||
573 | |||
574 | psPowerDevice->pfnPrePower = pfnPrePower; | ||
575 | psPowerDevice->pfnPostPower = pfnPostPower; | ||
576 | psPowerDevice->pfnPreClockSpeedChange = pfnPreClockSpeedChange; | ||
577 | psPowerDevice->pfnPostClockSpeedChange = pfnPostClockSpeedChange; | ||
578 | psPowerDevice->hDevCookie = hDevCookie; | ||
579 | psPowerDevice->ui32DeviceIndex = ui32DeviceIndex; | ||
580 | psPowerDevice->eCurrentPowerState = eCurrentPowerState; | ||
581 | psPowerDevice->eDefaultPowerState = eDefaultPowerState; | ||
582 | |||
583 | |||
584 | List_PVRSRV_POWER_DEV_Insert(&(psSysData->psPowerDeviceList), psPowerDevice); | ||
585 | |||
586 | return (PVRSRV_OK); | ||
587 | } | ||
588 | |||
589 | |||
590 | PVRSRV_ERROR PVRSRVRemovePowerDevice (IMG_UINT32 ui32DeviceIndex) | ||
591 | { | ||
592 | SYS_DATA *psSysData; | ||
593 | PVRSRV_POWER_DEV *psPowerDev; | ||
594 | |||
595 | SysAcquireData(&psSysData); | ||
596 | |||
597 | |||
598 | psPowerDev = (PVRSRV_POWER_DEV*) | ||
599 | List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList, | ||
600 | &MatchPowerDeviceIndex_AnyVaCb, | ||
601 | ui32DeviceIndex); | ||
602 | |||
603 | if (psPowerDev) | ||
604 | { | ||
605 | List_PVRSRV_POWER_DEV_Remove(psPowerDev); | ||
606 | OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_POWER_DEV), psPowerDev, IMG_NULL); | ||
607 | |||
608 | } | ||
609 | |||
610 | return (PVRSRV_OK); | ||
611 | } | ||
612 | |||
613 | |||
614 | IMG_EXPORT | ||
615 | IMG_BOOL PVRSRVIsDevicePowered(IMG_UINT32 ui32DeviceIndex) | ||
616 | { | ||
617 | SYS_DATA *psSysData; | ||
618 | PVRSRV_POWER_DEV *psPowerDevice; | ||
619 | |||
620 | SysAcquireData(&psSysData); | ||
621 | |||
622 | |||
623 | if (OSIsResourceLocked(&psSysData->sPowerStateChangeResource, KERNEL_ID) || | ||
624 | OSIsResourceLocked(&psSysData->sPowerStateChangeResource, ISR_ID)) | ||
625 | { | ||
626 | return IMG_FALSE; | ||
627 | } | ||
628 | |||
629 | psPowerDevice = (PVRSRV_POWER_DEV*) | ||
630 | List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList, | ||
631 | &MatchPowerDeviceIndex_AnyVaCb, | ||
632 | ui32DeviceIndex); | ||
633 | return (psPowerDevice && (psPowerDevice->eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON)) | ||
634 | ? IMG_TRUE : IMG_FALSE; | ||
635 | } | ||
636 | |||
637 | |||
638 | PVRSRV_ERROR PVRSRVDevicePreClockSpeedChange(IMG_UINT32 ui32DeviceIndex, | ||
639 | IMG_BOOL bIdleDevice, | ||
640 | IMG_VOID *pvInfo) | ||
641 | { | ||
642 | PVRSRV_ERROR eError = PVRSRV_OK; | ||
643 | SYS_DATA *psSysData; | ||
644 | PVRSRV_POWER_DEV *psPowerDevice; | ||
645 | |||
646 | PVR_UNREFERENCED_PARAMETER(pvInfo); | ||
647 | |||
648 | SysAcquireData(&psSysData); | ||
649 | |||
650 | if (bIdleDevice) | ||
651 | { | ||
652 | |||
653 | eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE); | ||
654 | if (eError != PVRSRV_OK) | ||
655 | { | ||
656 | PVR_DPF((PVR_DBG_ERROR, "PVRSRVDevicePreClockSpeedChange : failed to acquire lock, error:0x%x", eError)); | ||
657 | return eError; | ||
658 | } | ||
659 | } | ||
660 | |||
661 | |||
662 | psPowerDevice = (PVRSRV_POWER_DEV*) | ||
663 | List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList, | ||
664 | &MatchPowerDeviceIndex_AnyVaCb, | ||
665 | ui32DeviceIndex); | ||
666 | |||
667 | if (psPowerDevice && psPowerDevice->pfnPostClockSpeedChange) | ||
668 | { | ||
669 | eError = psPowerDevice->pfnPreClockSpeedChange(psPowerDevice->hDevCookie, | ||
670 | bIdleDevice, | ||
671 | psPowerDevice->eCurrentPowerState); | ||
672 | if (eError != PVRSRV_OK) | ||
673 | { | ||
674 | PVR_DPF((PVR_DBG_ERROR, | ||
675 | "PVRSRVDevicePreClockSpeedChange : Device %u failed, error:0x%x", | ||
676 | ui32DeviceIndex, eError)); | ||
677 | } | ||
678 | } | ||
679 | |||
680 | if (bIdleDevice && eError != PVRSRV_OK) | ||
681 | { | ||
682 | PVRSRVPowerUnlock(KERNEL_ID); | ||
683 | } | ||
684 | |||
685 | return eError; | ||
686 | } | ||
687 | |||
688 | |||
689 | IMG_VOID PVRSRVDevicePostClockSpeedChange(IMG_UINT32 ui32DeviceIndex, | ||
690 | IMG_BOOL bIdleDevice, | ||
691 | IMG_VOID *pvInfo) | ||
692 | { | ||
693 | PVRSRV_ERROR eError; | ||
694 | SYS_DATA *psSysData; | ||
695 | PVRSRV_POWER_DEV *psPowerDevice; | ||
696 | |||
697 | PVR_UNREFERENCED_PARAMETER(pvInfo); | ||
698 | |||
699 | SysAcquireData(&psSysData); | ||
700 | |||
701 | |||
702 | psPowerDevice = (PVRSRV_POWER_DEV*) | ||
703 | List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList, | ||
704 | &MatchPowerDeviceIndex_AnyVaCb, | ||
705 | ui32DeviceIndex); | ||
706 | |||
707 | if (psPowerDevice && psPowerDevice->pfnPostClockSpeedChange) | ||
708 | { | ||
709 | eError = psPowerDevice->pfnPostClockSpeedChange(psPowerDevice->hDevCookie, | ||
710 | bIdleDevice, | ||
711 | psPowerDevice->eCurrentPowerState); | ||
712 | if (eError != PVRSRV_OK) | ||
713 | { | ||
714 | PVR_DPF((PVR_DBG_ERROR, | ||
715 | "PVRSRVDevicePostClockSpeedChange : Device %u failed, error:0x%x", | ||
716 | ui32DeviceIndex, eError)); | ||
717 | } | ||
718 | } | ||
719 | |||
720 | |||
721 | if (bIdleDevice) | ||
722 | { | ||
723 | |||
724 | PVRSRVPowerUnlock(KERNEL_ID); | ||
725 | } | ||
726 | } | ||
727 | |||