20094102.3+0m5
[sgx.git] / pvr / sysconfig.c
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 "kerneldisplay.h"
29 #include "oemfuncs.h"
30 #include "sgxinfo.h"
31 #include "pdump_km.h"
32 #include "sgxinfokm.h"
33 #include "syslocal.h"
34 #include "sysconfig.h"
35
36 SYS_DATA *gpsSysData = (SYS_DATA *) IMG_NULL;
37 SYS_DATA gsSysData;
38
39 static SYS_SPECIFIC_DATA gsSysSpecificData;
40 SYS_SPECIFIC_DATA *gpsSysSpecificData;
41
42 static IMG_UINT32 gui32SGXDeviceID;
43 static SGX_DEVICE_MAP gsSGXDeviceMap;
44 static PVRSRV_DEVICE_NODE *gpsSGXDevNode;
45
46 #define DEVICE_SGX_INTERRUPT (1 << 0)
47
48
49 IMG_UINT32 PVRSRV_BridgeDispatchKM(IMG_UINT32 Ioctl,
50                                    IMG_BYTE * pInBuf,
51                                    IMG_UINT32 InBufLen,
52                                    IMG_BYTE * pOutBuf,
53                                    IMG_UINT32 OutBufLen,
54                                    IMG_UINT32 * pdwBytesTransferred);
55
56 static PVRSRV_ERROR SysLocateDevices(SYS_DATA * psSysData)
57 {
58
59         PVR_UNREFERENCED_PARAMETER(psSysData);
60
61         gsSGXDeviceMap.ui32Flags = 0x0;
62
63
64         gsSGXDeviceMap.sRegsSysPBase.uiAddr =
65             SYS_OMAP3430_SGX_REGS_SYS_PHYS_BASE;
66         gsSGXDeviceMap.sRegsCpuPBase =
67             SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase);
68         gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE;
69
70         gsSGXDeviceMap.ui32IRQ = SYS_OMAP3430_SGX_IRQ;
71
72
73         return PVRSRV_OK;
74 }
75
76 IMG_CHAR *SysCreateVersionString(IMG_CPU_PHYADDR sRegRegion)
77 {
78         static IMG_CHAR aszVersionString[100];
79         SYS_DATA *psSysData;
80         IMG_UINT32 ui32SGXRevision;
81         IMG_INT32 i32Count;
82         IMG_VOID *pvRegsLinAddr;
83
84         pvRegsLinAddr = OSMapPhysToLin(sRegRegion,
85                                        SYS_OMAP3430_SGX_REGS_SIZE,
86                                        PVRSRV_HAP_UNCACHED |
87                                        PVRSRV_HAP_KERNEL_ONLY, IMG_NULL);
88         if (!pvRegsLinAddr) {
89                 return IMG_NULL;
90         }
91
92         ui32SGXRevision = OSReadHWReg((IMG_PVOID) ((IMG_PBYTE) pvRegsLinAddr),
93                                       EUR_CR_CORE_REVISION);
94
95         if (SysAcquireData(&psSysData) != PVRSRV_OK) {
96                 return IMG_NULL;
97         }
98
99         i32Count = OSSNPrintf(aszVersionString, 100,
100                               "SGX revision = %u.%u.%u",
101                               (unsigned
102                                int)((ui32SGXRevision &
103                                      EUR_CR_CORE_REVISION_MAJOR_MASK)
104                                     >> EUR_CR_CORE_REVISION_MAJOR_SHIFT),
105                               (unsigned
106                                int)((ui32SGXRevision &
107                                      EUR_CR_CORE_REVISION_MINOR_MASK)
108                                     >> EUR_CR_CORE_REVISION_MINOR_SHIFT),
109                               (unsigned
110                                int)((ui32SGXRevision &
111                                      EUR_CR_CORE_REVISION_MAINTENANCE_MASK)
112                                     >> EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT)
113             );
114
115         OSUnMapPhysToLin(pvRegsLinAddr,
116                          SYS_OMAP3430_SGX_REGS_SIZE,
117                          PVRSRV_HAP_UNCACHED | PVRSRV_HAP_KERNEL_ONLY,
118                          IMG_NULL);
119
120         if (i32Count == -1) {
121                 return IMG_NULL;
122         }
123
124         return aszVersionString;
125 }
126
127 PVRSRV_ERROR SysInitialise(IMG_VOID)
128 {
129         IMG_UINT32 i;
130         PVRSRV_ERROR eError;
131         PVRSRV_DEVICE_NODE *psDeviceNode;
132         IMG_CPU_PHYADDR TimerRegPhysBase;
133
134         gpsSysData = &gsSysData;
135         OSMemSet(gpsSysData, 0, sizeof(SYS_DATA));
136
137         gpsSysSpecificData = &gsSysSpecificData;
138         OSMemSet(gpsSysSpecificData, 0, sizeof(SYS_SPECIFIC_DATA));
139
140         gpsSysData->pvSysSpecificData = gpsSysSpecificData;
141
142         eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData);
143         if (eError != PVRSRV_OK) {
144                 PVR_DPF((PVR_DBG_ERROR,
145                          "SysInitialise: Failed to setup env structure"));
146                 SysDeinitialise(gpsSysData);
147                 gpsSysData = IMG_NULL;
148                 return eError;
149         }
150         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
151                               SYS_SPECIFIC_DATA_ENABLE_ENVDATA);
152
153         gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT;
154
155         for (i = 0; i < SYS_DEVICE_COUNT; i++) {
156                 gpsSysData->sDeviceID[i].uiID = i;
157                 gpsSysData->sDeviceID[i].bInUse = IMG_FALSE;
158         }
159
160         gpsSysData->psDeviceNodeList = IMG_NULL;
161         gpsSysData->psQueueList = IMG_NULL;
162
163         eError = SysInitialiseCommon(gpsSysData);
164         if (eError != PVRSRV_OK) {
165                 PVR_DPF((PVR_DBG_ERROR,
166                          "SysInitialise: Failed in SysInitialiseCommon"));
167                 SysDeinitialise(gpsSysData);
168                 gpsSysData = IMG_NULL;
169                 return eError;
170         }
171
172         TimerRegPhysBase.uiAddr =
173             SYS_OMAP3430_GP11TIMER_PHYS_BASE + SYS_OMAP3430_GPTIMER_REGS;
174         gpsSysData->pvSOCTimerRegisterKM = IMG_NULL;
175         gpsSysData->hSOCTimerRegisterOSMemHandle = 0;
176         OSReservePhys(TimerRegPhysBase,
177                       4,
178                       PVRSRV_HAP_MULTI_PROCESS | PVRSRV_HAP_UNCACHED,
179                       (IMG_VOID **) & gpsSysData->pvSOCTimerRegisterKM,
180                       &gpsSysData->hSOCTimerRegisterOSMemHandle);
181
182
183         eError = SysLocateDevices(gpsSysData);
184         if (eError != PVRSRV_OK) {
185                 PVR_DPF((PVR_DBG_ERROR,
186                          "SysInitialise: Failed to locate devices"));
187                 SysDeinitialise(gpsSysData);
188                 gpsSysData = IMG_NULL;
189                 return eError;
190         }
191         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
192                               SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV);
193
194         eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice,
195                                       DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID);
196         if (eError != PVRSRV_OK) {
197                 PVR_DPF((PVR_DBG_ERROR,
198                          "SysInitialise: Failed to register device!"));
199                 SysDeinitialise(gpsSysData);
200                 gpsSysData = IMG_NULL;
201                 return eError;
202         }
203         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
204                               SYS_SPECIFIC_DATA_ENABLE_REGDEV);
205
206         psDeviceNode = gpsSysData->psDeviceNodeList;
207         while (psDeviceNode) {
208
209                 switch (psDeviceNode->sDevId.eDeviceType) {
210                 case PVRSRV_DEVICE_TYPE_SGX:
211                         {
212                                 DEVICE_MEMORY_INFO *psDevMemoryInfo;
213                                 DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
214
215                                 psDeviceNode->psLocalDevMemArena = IMG_NULL;
216
217                                 psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
218                                 psDeviceMemoryHeap =
219                                     psDevMemoryInfo->psDeviceMemoryHeap;
220
221                                 for (i = 0; i < psDevMemoryInfo->ui32HeapCount;
222                                      i++) {
223                                         psDeviceMemoryHeap[i].ui32Attribs |=
224                                             PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG;
225                                 }
226
227                                 gpsSGXDevNode = psDeviceNode;
228                                 gsSysSpecificData.psSGXDevNode = psDeviceNode;
229
230                                 break;
231                         }
232                 default:
233                         PVR_DPF((PVR_DBG_ERROR,
234                                  "SysInitialise: Failed to find SGX device node!"));
235                         return PVRSRV_ERROR_INIT_FAILURE;
236                 }
237
238                 psDeviceNode = psDeviceNode->psNext;
239         }
240
241         PDUMPINIT();
242         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
243                               SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT);
244
245         eError = InitSystemClocks(gpsSysData);
246         if (eError != PVRSRV_OK) {
247                 PVR_DPF((PVR_DBG_ERROR,
248                          "SysInitialise: Failed to init system clocks (%d)",
249                          eError));
250                 SysDeinitialise(gpsSysData);
251                 gpsSysData = IMG_NULL;
252                 return eError;
253         }
254
255         eError = EnableSystemClocks(gpsSysData);
256         if (eError != PVRSRV_OK) {
257                 PVR_DPF((PVR_DBG_ERROR,
258                          "SysInitialise: Failed to Enable system clocks (%d)",
259                          eError));
260                 SysDeinitialise(gpsSysData);
261                 gpsSysData = IMG_NULL;
262                 return eError;
263         }
264         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
265                               SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS);
266
267         eError = OSInitPerf(gpsSysData);
268         if (eError != PVRSRV_OK) {
269                 PVR_DPF((PVR_DBG_ERROR,
270                          "SysInitialise: Failed to init DVFS (%d)", eError));
271                 SysDeinitialise(gpsSysData);
272                 gpsSysData = IMG_NULL;
273                 return eError;
274         }
275         eError = EnableSGXClocks(gpsSysData);
276         if (eError != PVRSRV_OK) {
277                 PVR_DPF((PVR_DBG_ERROR,
278                          "SysInitialise: Failed to Enable SGX clocks (%d)",
279                          eError));
280                 SysDeinitialise(gpsSysData);
281                 gpsSysData = IMG_NULL;
282                 return eError;
283         }
284
285         eError = PVRSRVInitialiseDevice(gui32SGXDeviceID);
286         if (eError != PVRSRV_OK) {
287                 PVR_DPF((PVR_DBG_ERROR,
288                          "SysInitialise: Failed to initialise device!"));
289                 SysDeinitialise(gpsSysData);
290                 gpsSysData = IMG_NULL;
291                 return eError;
292         }
293         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
294                               SYS_SPECIFIC_DATA_ENABLE_INITDEV);
295
296
297         DisableSGXClocks(gpsSysData);
298
299         return PVRSRV_OK;
300 }
301
302 PVRSRV_ERROR SysFinalise(IMG_VOID)
303 {
304         PVRSRV_ERROR eError = PVRSRV_OK;
305
306         eError = EnableSGXClocks(gpsSysData);
307         if (eError != PVRSRV_OK) {
308                 PVR_DPF((PVR_DBG_ERROR,
309                          "SysInitialise: Failed to Enable SGX clocks (%d)",
310                          eError));
311                 SysDeinitialise(gpsSysData);
312                 gpsSysData = IMG_NULL;
313                 return eError;
314         }
315
316
317         eError = OSInstallMISR(gpsSysData);
318         if (eError != PVRSRV_OK) {
319                 PVR_DPF((PVR_DBG_ERROR, "SysFinalise: Failed to install MISR"));
320                 SysDeinitialise(gpsSysData);
321                 gpsSysData = IMG_NULL;
322                 return eError;
323         }
324         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
325                               SYS_SPECIFIC_DATA_ENABLE_MISR);
326
327         eError =
328             OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR",
329                                 gpsSGXDevNode);
330         if (eError != PVRSRV_OK) {
331                 PVR_DPF((PVR_DBG_ERROR, "SysFinalise: Failed to install ISR"));
332                 SysDeinitialise(gpsSysData);
333                 gpsSysData = IMG_NULL;
334                 return eError;
335         }
336         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
337                               SYS_SPECIFIC_DATA_ENABLE_LISR);
338
339         gpsSysData->pszVersionString =
340             SysCreateVersionString(gsSGXDeviceMap.sRegsCpuPBase);
341         if (!gpsSysData->pszVersionString) {
342                 PVR_DPF((PVR_DBG_ERROR,
343                          "SysFinalise: Failed to create a system version string"));
344         } else {
345                 PVR_DPF((PVR_DBG_WARNING, "SysFinalise: Version string: %s",
346                          gpsSysData->pszVersionString));
347         }
348
349
350         DisableSGXClocks(gpsSysData);
351
352         gpsSysSpecificData->bSGXInitComplete = IMG_TRUE;
353
354         return eError;
355 }
356
357 PVRSRV_ERROR SysDeinitialise(SYS_DATA * psSysData)
358 {
359         PVRSRV_ERROR eError;
360
361         PVR_UNREFERENCED_PARAMETER(psSysData);
362
363         if (SYS_SPECIFIC_DATA_TEST
364             (gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) {
365                 eError = OSUninstallDeviceLISR(psSysData);
366                 if (eError != PVRSRV_OK) {
367                         PVR_DPF((PVR_DBG_ERROR,
368                                  "SysDeinitialise: OSUninstallDeviceLISR failed"));
369                         return eError;
370                 }
371         }
372
373         if (SYS_SPECIFIC_DATA_TEST
374             (gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR)) {
375                 eError = OSUninstallMISR(psSysData);
376                 if (eError != PVRSRV_OK) {
377                         PVR_DPF((PVR_DBG_ERROR,
378                                  "SysDeinitialise: OSUninstallMISR failed"));
379                         return eError;
380                 }
381         }
382
383         eError = OSCleanupPerf(psSysData);
384         if (eError != PVRSRV_OK) {
385                 PVR_DPF((PVR_DBG_ERROR,
386                          "SysDeinitialise: OSCleanupDvfs failed"));
387                 return eError;
388         }
389
390         if (SYS_SPECIFIC_DATA_TEST
391             (gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV)) {
392                 PVR_ASSERT(SYS_SPECIFIC_DATA_TEST
393                            (gpsSysSpecificData,
394                             SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS));
395
396                 eError = EnableSGXClocks(gpsSysData);
397                 if (eError != PVRSRV_OK) {
398                         PVR_DPF((PVR_DBG_ERROR,
399                                  "SysDeinitialise: EnableSGXClocks failed"));
400                         return eError;
401                 }
402
403                 eError = PVRSRVDeinitialiseDevice(gui32SGXDeviceID);
404                 if (eError != PVRSRV_OK) {
405                         PVR_DPF((PVR_DBG_ERROR,
406                                  "SysDeinitialise: failed to de-init the device"));
407                         return eError;
408                 }
409         }
410
411         if (SYS_SPECIFIC_DATA_TEST
412             (gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) {
413                 DisableSystemClocks(gpsSysData);
414         }
415
416         CleanupSystemClocks(gpsSysData);
417
418         if (SYS_SPECIFIC_DATA_TEST
419             (gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA)) {
420                 eError = OSDeInitEnvData(gpsSysData->pvEnvSpecificData);
421                 if (eError != PVRSRV_OK) {
422                         PVR_DPF((PVR_DBG_ERROR,
423                                  "SysDeinitialise: failed to de-init env structure"));
424                         return eError;
425                 }
426         }
427
428         if (gpsSysData->pvSOCTimerRegisterKM) {
429                 OSUnReservePhys(gpsSysData->pvSOCTimerRegisterKM,
430                                 4,
431                                 PVRSRV_HAP_MULTI_PROCESS | PVRSRV_HAP_UNCACHED,
432                                 gpsSysData->hSOCTimerRegisterOSMemHandle);
433         }
434
435         SysDeinitialiseCommon(gpsSysData);
436
437
438         if (SYS_SPECIFIC_DATA_TEST
439             (gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT)) {
440                 PDUMPDEINIT();
441         }
442
443         gpsSysSpecificData->ui32SysSpecificData = 0;
444         gpsSysSpecificData->bSGXInitComplete = IMG_FALSE;
445
446         gpsSysData = IMG_NULL;
447
448         return PVRSRV_OK;
449 }
450
451 PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType,
452                                    IMG_VOID ** ppvDeviceMap)
453 {
454
455         switch (eDeviceType) {
456         case PVRSRV_DEVICE_TYPE_SGX:
457                 {
458
459                         *ppvDeviceMap = (IMG_VOID *) & gsSGXDeviceMap;
460
461                         break;
462                 }
463         default:
464                 {
465                         PVR_DPF((PVR_DBG_ERROR,
466                                  "SysGetDeviceMemoryMap: unsupported device type"));
467                 }
468         }
469         return PVRSRV_OK;
470 }
471
472 IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType,
473                                       IMG_CPU_PHYADDR CpuPAddr)
474 {
475         IMG_DEV_PHYADDR DevPAddr;
476
477         PVR_UNREFERENCED_PARAMETER(eDeviceType);
478
479         DevPAddr.uiAddr = CpuPAddr.uiAddr;
480
481         return DevPAddr;
482 }
483
484 IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr(IMG_SYS_PHYADDR sys_paddr)
485 {
486         IMG_CPU_PHYADDR cpu_paddr;
487
488         cpu_paddr.uiAddr = sys_paddr.uiAddr;
489         return cpu_paddr;
490 }
491
492 IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr(IMG_CPU_PHYADDR cpu_paddr)
493 {
494         IMG_SYS_PHYADDR sys_paddr;
495
496         sys_paddr.uiAddr = cpu_paddr.uiAddr;
497         return sys_paddr;
498 }
499
500 IMG_DEV_PHYADDR SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType,
501                                       IMG_SYS_PHYADDR SysPAddr)
502 {
503         IMG_DEV_PHYADDR DevPAddr;
504
505         PVR_UNREFERENCED_PARAMETER(eDeviceType);
506
507         DevPAddr.uiAddr = SysPAddr.uiAddr;
508
509         return DevPAddr;
510 }
511
512 IMG_SYS_PHYADDR SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE eDeviceType,
513                                       IMG_DEV_PHYADDR DevPAddr)
514 {
515         IMG_SYS_PHYADDR SysPAddr;
516
517         PVR_UNREFERENCED_PARAMETER(eDeviceType);
518
519         SysPAddr.uiAddr = DevPAddr.uiAddr;
520
521         return SysPAddr;
522 }
523
524 IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE * psDeviceNode)
525 {
526         PVR_UNREFERENCED_PARAMETER(psDeviceNode);
527 }
528
529 IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE * psDeviceNode)
530 {
531         PVR_UNREFERENCED_PARAMETER(psDeviceNode);
532 }
533
534 IMG_UINT32 SysGetInterruptSource(SYS_DATA * psSysData,
535                                  PVRSRV_DEVICE_NODE * psDeviceNode)
536 {
537         PVR_UNREFERENCED_PARAMETER(psSysData);
538
539         return psDeviceNode->ui32SOCInterruptBit;
540 }
541
542 IMG_VOID SysClearInterrupts(SYS_DATA * psSysData, IMG_UINT32 ui32ClearBits)
543 {
544         PVR_UNREFERENCED_PARAMETER(psSysData);
545         PVR_UNREFERENCED_PARAMETER(ui32ClearBits);
546
547         /* Flush posted write for the irq status to avoid spurious interrupts */
548         OSReadHWReg(((PVRSRV_SGXDEV_INFO *) gpsSGXDevNode->pvDevice)->
549                     pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR);
550 }
551
552 PVRSRV_ERROR SysSystemPrePowerState(PVR_POWER_STATE eNewPowerState)
553 {
554         PVRSRV_ERROR eError = PVRSRV_OK;
555
556         if (eNewPowerState == PVRSRV_POWER_STATE_D3) {
557                 PVR_TRACE(("SysSystemPrePowerState: Entering state D3"));
558
559                 if (SYS_SPECIFIC_DATA_TEST
560                     (&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) {
561                         eError = OSUninstallDeviceLISR(gpsSysData);
562                         if (eError != PVRSRV_OK) {
563                                 PVR_DPF((PVR_DBG_ERROR,
564                                          "SysSystemPrePowerState: OSUninstallDeviceLISR failed (%d)",
565                                          eError));
566                                 return eError;
567                         }
568                         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
569                                               SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR);
570                         SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData,
571                                                 SYS_SPECIFIC_DATA_ENABLE_LISR);
572                 }
573
574                 if (SYS_SPECIFIC_DATA_TEST
575                     (&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) {
576                         DisableSystemClocks(gpsSysData);
577
578                         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
579                                               SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS);
580                         SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData,
581                                                 SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS);
582                 }
583         }
584
585         return eError;
586 }
587
588 PVRSRV_ERROR SysSystemPostPowerState(PVR_POWER_STATE eNewPowerState)
589 {
590         PVRSRV_ERROR eError = PVRSRV_OK;
591
592         if (eNewPowerState == PVRSRV_POWER_STATE_D0) {
593                 PVR_TRACE(("SysSystemPostPowerState: Entering state D0"));
594
595                 if (SYS_SPECIFIC_DATA_TEST
596                     (&gsSysSpecificData,
597                      SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS)) {
598                         eError = EnableSystemClocks(gpsSysData);
599                         if (eError != PVRSRV_OK) {
600                                 PVR_DPF((PVR_DBG_ERROR,
601                                          "SysSystemPostPowerState: EnableSystemClocks failed (%d)",
602                                          eError));
603                                 return eError;
604                         }
605                         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
606                                               SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS);
607                         SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData,
608                                                 SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS);
609                 }
610                 if (SYS_SPECIFIC_DATA_TEST
611                     (&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR)) {
612                         eError =
613                             OSInstallDeviceLISR(gpsSysData,
614                                                 gsSGXDeviceMap.ui32IRQ,
615                                                 "SGX ISR", gpsSGXDevNode);
616                         if (eError != PVRSRV_OK) {
617                                 PVR_DPF((PVR_DBG_ERROR,
618                                          "SysSystemPostPowerState: OSInstallDeviceLISR failed to install ISR (%d)",
619                                          eError));
620                                 return eError;
621                         }
622                         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
623                                               SYS_SPECIFIC_DATA_ENABLE_LISR);
624                         SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData,
625                                                 SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR);
626                 }
627         }
628         return eError;
629 }
630
631 PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex,
632                                     PVR_POWER_STATE eNewPowerState,
633                                     PVR_POWER_STATE eCurrentPowerState)
634 {
635         PVR_UNREFERENCED_PARAMETER(eCurrentPowerState);
636
637         if (ui32DeviceIndex != gui32SGXDeviceID) {
638                 return PVRSRV_OK;
639         }
640         if (eNewPowerState == PVRSRV_POWER_STATE_D3) {
641                 PVR_TRACE(("SysDevicePrePowerState: SGX Entering state D3"));
642                 DisableSGXClocks(gpsSysData);
643         }
644         return PVRSRV_OK;
645 }
646
647 PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex,
648                                      PVR_POWER_STATE eNewPowerState,
649                                      PVR_POWER_STATE eCurrentPowerState)
650 {
651         PVRSRV_ERROR eError = PVRSRV_OK;
652
653         PVR_UNREFERENCED_PARAMETER(eNewPowerState);
654
655         if (ui32DeviceIndex != gui32SGXDeviceID) {
656                 return eError;
657         }
658         if (eCurrentPowerState == PVRSRV_POWER_STATE_D3) {
659                 PVR_TRACE(("SysDevicePostPowerState: SGX Leaving state D3"));
660                 eError = EnableSGXClocks(gpsSysData);
661         }
662
663         return eError;
664 }
665
666 PVRSRV_ERROR SysOEMFunction(IMG_UINT32 ui32ID,
667                             IMG_VOID * pvIn,
668                             IMG_UINT32 ulInSize,
669                             IMG_VOID * pvOut, IMG_UINT32 ulOutSize)
670 {
671         PVR_UNREFERENCED_PARAMETER(ui32ID);
672         PVR_UNREFERENCED_PARAMETER(pvIn);
673         PVR_UNREFERENCED_PARAMETER(ulInSize);
674         PVR_UNREFERENCED_PARAMETER(pvOut);
675         PVR_UNREFERENCED_PARAMETER(ulOutSize);
676
677         if ((ui32ID == OEM_GET_EXT_FUNCS) &&
678             (ulOutSize == sizeof(PVRSRV_DC_OEM_JTABLE))) {
679
680                 PVRSRV_DC_OEM_JTABLE *psOEMJTable =
681                     (PVRSRV_DC_OEM_JTABLE *) pvOut;
682                 psOEMJTable->pfnOEMBridgeDispatch = &PVRSRV_BridgeDispatchKM;
683                 return PVRSRV_OK;
684         }
685
686         return PVRSRV_ERROR_INVALID_PARAMS;
687 }