fixes for bc_cat
[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 <linux/platform_device.h>
28
29 #include "services_headers.h"
30 #include "kerneldisplay.h"
31 #include "oemfuncs.h"
32 #include "sgxinfo.h"
33 #include "pvr_pdump.h"
34 #include "sgxinfokm.h"
35 #include "syslocal.h"
36 #include "sysconfig.h"
37 #include "syscommon.h"
38 #include "img_types.h"
39 #include "ocpdefs.h"
40 #include "pvr_bridge_km.h"
41
42 struct SYS_DATA *gpsSysData;
43 static struct SYS_DATA gsSysData;
44
45 static struct SYS_SPECIFIC_DATA gsSysSpecificData;
46 struct SYS_SPECIFIC_DATA *gpsSysSpecificData;
47
48 static u32 gui32SGXDeviceID;
49 static struct SGX_DEVICE_MAP gsSGXDeviceMap;
50 static struct PVRSRV_DEVICE_NODE *gpsSGXDevNode;
51
52 #define DEVICE_SGX_INTERRUPT    (1 << 0)
53
54 #if defined(NO_HARDWARE)
55 static void *gsSGXRegsCPUVAddr;
56 #endif
57
58 static void __iomem *ocp_base;
59
60 static enum PVRSRV_ERROR SysLocateDevices(struct SYS_DATA *psSysData)
61 {
62 #if defined(NO_HARDWARE)
63         enum PVRSRV_ERROR eError;
64         struct IMG_CPU_PHYADDR sCpuPAddr;
65 #endif
66
67         PVR_UNREFERENCED_PARAMETER(psSysData);
68
69         gsSGXDeviceMap.ui32Flags = 0x0;
70
71 #if defined(NO_HARDWARE)
72
73         eError = OSBaseAllocContigMemory(SYS_OMAP3430_SGX_REGS_SIZE,
74                                          &gsSGXRegsCPUVAddr, &sCpuPAddr);
75         if (eError != PVRSRV_OK)
76                 return eError;
77         gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr;
78         gsSGXDeviceMap.sRegsSysPBase =
79             SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase);
80         gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE;
81
82         gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr;
83
84         OSMemSet(gsSGXRegsCPUVAddr, 0, SYS_OMAP3430_SGX_REGS_SIZE);
85
86         gsSGXDeviceMap.ui32IRQ = 0;
87
88 #else
89
90         gsSGXDeviceMap.sRegsSysPBase.uiAddr =
91             SYS_OMAP3430_SGX_REGS_SYS_PHYS_BASE;
92         gsSGXDeviceMap.sRegsCpuPBase =
93             SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase);
94         gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE;
95
96         gsSGXDeviceMap.ui32IRQ = SYS_OMAP3430_SGX_IRQ;
97
98 #endif
99
100         return PVRSRV_OK;
101 }
102
103 #ifndef NO_HARDWARE
104 u32 sgx_get_rev(void)
105 {
106         /*
107          * Ugly solution, used until we have proper per device instances
108          * passed to functions and get rid of most if not all globals.
109          */
110         struct SYS_SPECIFIC_DATA *sysd = gpsSysSpecificData;
111         void __iomem *regs;
112         static u32 rev = -1UL;
113         int err;
114
115         if (rev != -1UL)
116                 return rev;
117
118         regs = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase,
119                                SYS_OMAP3430_SGX_REGS_SIZE,
120                                PVRSRV_HAP_UNCACHED | PVRSRV_HAP_KERNEL_ONLY,
121                                NULL);
122         if (!regs)
123                 return 0;
124
125         err = clk_enable(sysd->psSGX_FCK);
126         BUG_ON(err);
127         err = clk_enable(sysd->psSGX_ICK);
128         BUG_ON(err);
129
130         rev = OSReadHWReg(regs, EUR_CR_CORE_REVISION);
131
132         clk_disable(sysd->psSGX_ICK);
133         clk_disable(sysd->psSGX_FCK);
134
135         OSUnMapPhysToLin(regs, SYS_OMAP3430_SGX_REGS_SIZE,
136                          PVRSRV_HAP_UNCACHED | PVRSRV_HAP_KERNEL_ONLY, NULL);
137
138         return rev;
139 }
140
141 unsigned long sgx_get_max_freq(void)
142 {
143         struct SYS_SPECIFIC_DATA *sysd = gpsSysSpecificData;
144
145         BUG_ON(!sysd);
146
147         if (sysd->sgx_fck_max)
148                 return sysd->sgx_fck_max;
149
150         /*
151          * In case there's no board specific setting for this, return
152          * some revision specific defaults.
153          */
154         if (sgx_is_530()) {
155                 switch (sgx_get_rev()) {
156                 case EUR_CR_CORE_MAKE_REV(1, 2, 1):
157                         return SYS_SGX_MAX_FREQ_530R121;
158                 case EUR_CR_CORE_MAKE_REV(1, 2, 5):
159                         return SYS_SGX_MAX_FREQ_530R125;
160                 }
161         }
162         BUG();
163
164         return 0;
165 }
166
167 #else
168
169 u32 sgx_get_rev(void)
170 {
171         return 0;
172 }
173
174 unsigned long sgx_get_max_freq()
175 {
176         return SYS_SGX_MAX_FREQ_NO_HW;
177 }
178
179 #endif
180
181 bool sgx_is_530(void)
182 {
183 #ifdef SGX530
184         return true;
185 #endif
186         return false;
187 }
188
189 char *SysCreateVersionString(struct IMG_CPU_PHYADDR sRegRegion)
190 {
191         static char aszVersionString[100];
192         struct SYS_DATA *psSysData;
193         u32 ui32SGXRevision;
194         s32 i32Count;
195
196         if (SysAcquireData(&psSysData) != PVRSRV_OK)
197                 return NULL;
198
199         ui32SGXRevision = sgx_get_rev();
200
201         i32Count = OSSNPrintf(aszVersionString, 100,
202                               "SGX revision = %u.%u.%u",
203                               (unsigned)((ui32SGXRevision &
204                                      EUR_CR_CORE_REVISION_MAJOR_MASK)
205                                     >> EUR_CR_CORE_REVISION_MAJOR_SHIFT),
206                               (unsigned)((ui32SGXRevision &
207                                      EUR_CR_CORE_REVISION_MINOR_MASK)
208                                     >> EUR_CR_CORE_REVISION_MINOR_SHIFT),
209                               (unsigned)((ui32SGXRevision &
210                                      EUR_CR_CORE_REVISION_MAINTENANCE_MASK)
211                                     >> EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT)
212             );
213
214         if (i32Count == -1)
215                 return NULL;
216
217         return aszVersionString;
218 }
219
220 static int sgx_ocp_init(void)
221 {
222         struct IMG_SYS_PHYADDR sys_pbase;
223         struct IMG_CPU_PHYADDR cpu_pbase;
224
225         sys_pbase.uiAddr = SYS_OMAP3430_OCP_REGS_SYS_PHYS_BASE;
226         cpu_pbase = SysSysPAddrToCpuPAddr(sys_pbase);
227
228         ocp_base = OSMapPhysToLin(cpu_pbase, SYS_OMAP3430_OCP_REGS_SIZE,
229                                   PVRSRV_HAP_UNCACHED | PVRSRV_HAP_KERNEL_ONLY,
230                                   NULL);
231
232         if (!ocp_base) {
233                 PVR_DPF(PVR_DBG_ERROR, "%s: Failed to map OCP registers",
234                         __func__);
235                 return -ENOMEM;
236         }
237
238         return 0;
239 }
240
241 static void sgx_ocp_cleanup(void)
242 {
243         OSUnMapPhysToLin(ocp_base, SYS_OMAP3430_OCP_REGS_SIZE,
244                          PVRSRV_HAP_UNCACHED | PVRSRV_HAP_KERNEL_ONLY, NULL);
245 }
246
247 void sgx_ocp_write_reg(u32 reg, u32 val)
248 {
249         BUG_ON(!ocp_base);
250
251         /* OCP offsets are based at EUR_CR_OCP_REVISION */
252         reg -= EUR_CR_OCP_REVISION;
253         OSWriteHWReg(ocp_base, reg, val);
254 }
255
256 enum PVRSRV_ERROR SysInitialise(struct platform_device *pdev)
257 {
258         u32 i;
259         enum PVRSRV_ERROR eError;
260         struct PVRSRV_DEVICE_NODE *psDeviceNode;
261         struct IMG_CPU_PHYADDR TimerRegPhysBase;
262         struct sgx_platform_data *spd;
263
264         gpsSysData = &gsSysData;
265
266         gpsSysSpecificData = &gsSysSpecificData;
267
268         gpsSysData->pvSysSpecificData = gpsSysSpecificData;
269
270         spd = pdev->dev.platform_data;
271         if (spd)
272                 gpsSysSpecificData->sgx_fck_max = spd->fclock_max;
273
274         eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData);
275         if (eError != PVRSRV_OK) {
276                 PVR_DPF(PVR_DBG_ERROR,
277                          "SysInitialise: Failed to setup env structure");
278                 SysDeinitialise(gpsSysData);
279                 gpsSysData = NULL;
280                 return eError;
281         }
282         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
283                               SYS_SPECIFIC_DATA_ENABLE_ENVDATA);
284
285         gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT;
286
287         for (i = 0; i < SYS_DEVICE_COUNT; i++) {
288                 gpsSysData->sDeviceID[i].uiID = i;
289                 gpsSysData->sDeviceID[i].bInUse = IMG_FALSE;
290         }
291
292         gpsSysData->psDeviceNodeList = NULL;
293         gpsSysData->psQueueList = NULL;
294
295         eError = SysInitialiseCommon(gpsSysData);
296         if (eError != PVRSRV_OK) {
297                 PVR_DPF(PVR_DBG_ERROR,
298                          "SysInitialise: Failed in SysInitialiseCommon");
299                 SysDeinitialise(gpsSysData);
300                 gpsSysData = NULL;
301                 return eError;
302         }
303
304         TimerRegPhysBase.uiAddr =
305             SYS_OMAP3430_GP11TIMER_PHYS_BASE + SYS_OMAP3430_GPTIMER_REGS;
306         gpsSysData->pvSOCTimerRegisterKM = NULL;
307         gpsSysData->hSOCTimerRegisterOSMemHandle = NULL;
308         eError = OSReservePhys(TimerRegPhysBase, 4,
309                       PVRSRV_HAP_MULTI_PROCESS | PVRSRV_HAP_UNCACHED,
310                       (void **)&gpsSysData->pvSOCTimerRegisterKM,
311                       &gpsSysData->hSOCTimerRegisterOSMemHandle);
312         if (eError != PVRSRV_OK) {
313                 PVR_DPF(PVR_DBG_ERROR, "%s: OSReservePhys failed");
314                 SysDeinitialise(gpsSysData);
315                 gpsSysData = NULL;
316                 return eError;
317         }
318
319         gpsSysSpecificData->ui32SrcClockDiv = 3;
320
321         eError = SysLocateDevices(gpsSysData);
322         if (eError != PVRSRV_OK) {
323                 PVR_DPF(PVR_DBG_ERROR,
324                          "SysInitialise: Failed to locate devices");
325                 SysDeinitialise(gpsSysData);
326                 gpsSysData = NULL;
327                 return eError;
328         }
329         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
330                               SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV);
331
332         if (sgx_ocp_init() < 0) {
333                 SysDeinitialise(gpsSysData);
334                 gpsSysData = NULL;
335
336                 return PVRSRV_ERROR_GENERIC;
337         }
338
339         eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice,
340                                       DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID);
341         if (eError != PVRSRV_OK) {
342                 PVR_DPF(PVR_DBG_ERROR,
343                          "SysInitialise: Failed to register device!");
344                 SysDeinitialise(gpsSysData);
345                 gpsSysData = NULL;
346                 return eError;
347         }
348         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
349                               SYS_SPECIFIC_DATA_ENABLE_REGDEV);
350
351         psDeviceNode = gpsSysData->psDeviceNodeList;
352         while (psDeviceNode) {
353                 switch (psDeviceNode->sDevId.eDeviceType) {
354                 case PVRSRV_DEVICE_TYPE_SGX:
355                         {
356                                 struct DEVICE_MEMORY_INFO *psDevMemoryInfo;
357                                 struct DEVICE_MEMORY_HEAP_INFO
358                                                         *psDeviceMemoryHeap;
359
360                                 psDeviceNode->psLocalDevMemArena = NULL;
361
362                                 psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
363                                 psDeviceMemoryHeap =
364                                     psDevMemoryInfo->psDeviceMemoryHeap;
365
366                                 for (i = 0; i < psDevMemoryInfo->ui32HeapCount;
367                                      i++)
368                                         psDeviceMemoryHeap[i].ui32Attribs |=
369                                            PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG;
370
371                                 gpsSGXDevNode = psDeviceNode;
372                                 gsSysSpecificData.psSGXDevNode = psDeviceNode;
373
374                                 break;
375                         }
376                 default:
377                         PVR_DPF(PVR_DBG_ERROR, "SysInitialise: "
378                                         "Failed to find SGX device node!");
379                         return PVRSRV_ERROR_INIT_FAILURE;
380                 }
381
382                 psDeviceNode = psDeviceNode->psNext;
383         }
384
385         PDUMPINIT();
386         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
387                               SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT);
388
389         eError = InitSystemClocks(gpsSysData);
390         if (eError != PVRSRV_OK) {
391                 PVR_DPF(PVR_DBG_ERROR,
392                          "SysInitialise: Failed to init system clocks (%d)",
393                          eError);
394                 SysDeinitialise(gpsSysData);
395                 gpsSysData = NULL;
396                 return eError;
397         }
398
399         eError = EnableSystemClocks(gpsSysData);
400         if (eError != PVRSRV_OK) {
401                 PVR_DPF(PVR_DBG_ERROR,
402                          "SysInitialise: Failed to Enable system clocks (%d)",
403                          eError);
404                 SysDeinitialise(gpsSysData);
405                 gpsSysData = NULL;
406                 return eError;
407         }
408         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
409                               SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS);
410
411         eError = OSInitPerf(gpsSysData);
412         if (eError != PVRSRV_OK) {
413                 PVR_DPF(PVR_DBG_ERROR,
414                          "SysInitialise: Failed to init DVFS (%d)", eError);
415                 SysDeinitialise(gpsSysData);
416                 gpsSysData = NULL;
417                 return eError;
418         }
419         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
420                               SYS_SPECIFIC_DATA_ENABLE_PERF);
421
422         eError = EnableSGXClocks(gpsSysData);
423         if (eError != PVRSRV_OK) {
424                 PVR_DPF(PVR_DBG_ERROR,
425                          "SysInitialise: Failed to Enable SGX clocks (%d)",
426                          eError);
427                 SysDeinitialise(gpsSysData);
428                 gpsSysData = NULL;
429                 return eError;
430         }
431
432         eError = PVRSRVInitialiseDevice(gui32SGXDeviceID);
433         if (eError != PVRSRV_OK) {
434                 PVR_DPF(PVR_DBG_ERROR,
435                          "SysInitialise: Failed to initialise device!");
436                 SysDeinitialise(gpsSysData);
437                 gpsSysData = NULL;
438                 return eError;
439         }
440         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
441                               SYS_SPECIFIC_DATA_ENABLE_INITDEV);
442
443         gpsSysData->pszVersionString =
444             SysCreateVersionString(gsSGXDeviceMap.sRegsCpuPBase);
445         if (!gpsSysData->pszVersionString)
446                 PVR_DPF(PVR_DBG_ERROR,
447                 "SysFinalise: Failed to create a system version string");
448         else
449                 PVR_DPF(PVR_DBG_WARNING, "SysFinalise: Version string: %s",
450                          gpsSysData->pszVersionString);
451
452         DisableSGXClocks(gpsSysData);
453
454         return PVRSRV_OK;
455 }
456
457 enum PVRSRV_ERROR SysFinalise(void)
458 {
459         enum PVRSRV_ERROR eError = PVRSRV_OK;
460
461         eError = EnableSGXClocks(gpsSysData);
462         if (eError != PVRSRV_OK) {
463                 PVR_DPF(PVR_DBG_ERROR,
464                          "SysInitialise: Failed to Enable SGX clocks (%d)",
465                          eError);
466                 SysDeinitialise(gpsSysData);
467                 gpsSysData = NULL;
468                 return eError;
469         }
470
471
472         eError = OSInstallMISR(gpsSysData);
473         if (eError != PVRSRV_OK) {
474                 PVR_DPF(PVR_DBG_ERROR, "SysFinalise: Failed to install MISR");
475                 SysDeinitialise(gpsSysData);
476                 gpsSysData = NULL;
477                 return eError;
478         }
479         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
480                               SYS_SPECIFIC_DATA_ENABLE_MISR);
481
482         eError =
483             OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR",
484                                 gpsSGXDevNode);
485         if (eError != PVRSRV_OK) {
486                 PVR_DPF(PVR_DBG_ERROR, "SysFinalise: Failed to install ISR");
487                 SysDeinitialise(gpsSysData);
488                 gpsSysData = NULL;
489                 return eError;
490         }
491         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
492                               SYS_SPECIFIC_DATA_ENABLE_LISR);
493
494         DisableSGXClocks(gpsSysData);
495
496         gpsSysSpecificData->bSGXInitComplete = IMG_TRUE;
497
498         return eError;
499 }
500
501 enum PVRSRV_ERROR SysDeinitialise(struct SYS_DATA *psSysData)
502 {
503         enum PVRSRV_ERROR eError;
504
505         if (SYS_SPECIFIC_DATA_TEST
506             (gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) {
507                 eError = OSUninstallDeviceLISR(psSysData);
508                 if (eError != PVRSRV_OK) {
509                         PVR_DPF(PVR_DBG_ERROR, "SysDeinitialise: "
510                                         "OSUninstallDeviceLISR failed");
511                         return eError;
512                 }
513         }
514
515         if (SYS_SPECIFIC_DATA_TEST
516             (gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR)) {
517                 eError = OSUninstallMISR(psSysData);
518                 if (eError != PVRSRV_OK) {
519                         PVR_DPF(PVR_DBG_ERROR, "SysDeinitialise: "
520                                                 "OSUninstallMISR failed");
521                         return eError;
522                 }
523         }
524
525         if (SYS_SPECIFIC_DATA_TEST
526             (gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV)) {
527                 PVR_ASSERT(SYS_SPECIFIC_DATA_TEST
528                            (gpsSysSpecificData,
529                             SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS));
530
531                 eError = EnableSGXClocks(gpsSysData);
532                 if (eError != PVRSRV_OK) {
533                         PVR_DPF(PVR_DBG_ERROR,
534                                  "SysDeinitialise: EnableSGXClocks failed");
535                         return eError;
536                 }
537
538                 eError = PVRSRVDeinitialiseDevice(gui32SGXDeviceID);
539
540                 DisableSGXClocks(gpsSysData);
541
542                 if (eError != PVRSRV_OK) {
543                         PVR_DPF(PVR_DBG_ERROR, "SysDeinitialise: "
544                                         "failed to de-init the device");
545                         return eError;
546                 }
547         }
548
549         if (SYS_SPECIFIC_DATA_TEST
550             (gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS))
551                 DisableSystemClocks(gpsSysData);
552
553         CleanupSystemClocks(gpsSysData);
554
555         if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData,
556                                    SYS_SPECIFIC_DATA_ENABLE_PERF)) {
557                 eError = OSCleanupPerf(psSysData);
558                 if (eError != PVRSRV_OK) {
559                         PVR_DPF(PVR_DBG_ERROR,
560                                  "SysDeinitialise: OSCleanupDvfs failed");
561                         return eError;
562                 }
563         }
564
565         sgx_ocp_cleanup();
566
567         if (SYS_SPECIFIC_DATA_TEST
568             (gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA)) {
569                 eError = OSDeInitEnvData(gpsSysData->pvEnvSpecificData);
570                 if (eError != PVRSRV_OK) {
571                         PVR_DPF(PVR_DBG_ERROR,
572                         "SysDeinitialise: failed to de-init env structure");
573                         return eError;
574                 }
575         }
576
577         if (gpsSysData->pvSOCTimerRegisterKM)
578                 OSUnReservePhys(gpsSysData->pvSOCTimerRegisterKM, 4,
579                                 PVRSRV_HAP_MULTI_PROCESS | PVRSRV_HAP_UNCACHED,
580                                 gpsSysData->hSOCTimerRegisterOSMemHandle);
581
582         SysDeinitialiseCommon(gpsSysData);
583
584 #if defined(NO_HARDWARE)
585         if (SYS_SPECIFIC_DATA_TEST
586             (gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV))
587
588                 OSBaseFreeContigMemory(SYS_OMAP3430_SGX_REGS_SIZE,
589                                        gsSGXRegsCPUVAddr,
590                                        gsSGXDeviceMap.sRegsCpuPBase);
591 #endif
592
593         if (SYS_SPECIFIC_DATA_TEST
594             (gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT))
595                 PDUMPDEINIT();
596
597         gpsSysSpecificData->ui32SysSpecificData = 0;
598         gpsSysSpecificData->bSGXInitComplete = IMG_FALSE;
599
600         gpsSysData = NULL;
601
602         return PVRSRV_OK;
603 }
604
605 enum PVRSRV_ERROR SysGetDeviceMemoryMap(enum PVRSRV_DEVICE_TYPE eDeviceType,
606                                    void **ppvDeviceMap)
607 {
608         switch (eDeviceType) {
609         case PVRSRV_DEVICE_TYPE_SGX:
610                 *ppvDeviceMap = (void *) &gsSGXDeviceMap;
611                 break;
612         default:
613                 PVR_DPF(PVR_DBG_ERROR, "SysGetDeviceMemoryMap: "
614                                         "unsupported device type");
615         }
616         return PVRSRV_OK;
617 }
618
619 struct IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr(
620                                 enum PVRSRV_DEVICE_TYPE eDeviceType,
621                                 struct IMG_CPU_PHYADDR CpuPAddr)
622 {
623         struct IMG_DEV_PHYADDR DevPAddr;
624
625         PVR_UNREFERENCED_PARAMETER(eDeviceType);
626
627         DevPAddr.uiAddr = CpuPAddr.uiAddr;
628
629         return DevPAddr;
630 }
631
632 struct IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr(struct IMG_SYS_PHYADDR sys_paddr)
633 {
634         struct IMG_CPU_PHYADDR cpu_paddr;
635
636         cpu_paddr.uiAddr = sys_paddr.uiAddr;
637         return cpu_paddr;
638 }
639
640 struct IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr(struct IMG_CPU_PHYADDR cpu_paddr)
641 {
642         struct IMG_SYS_PHYADDR sys_paddr;
643
644         sys_paddr.uiAddr = cpu_paddr.uiAddr;
645         return sys_paddr;
646 }
647
648 struct IMG_DEV_PHYADDR SysSysPAddrToDevPAddr(
649                                 enum PVRSRV_DEVICE_TYPE eDeviceType,
650                                 struct IMG_SYS_PHYADDR SysPAddr)
651 {
652         struct IMG_DEV_PHYADDR DevPAddr;
653
654         PVR_UNREFERENCED_PARAMETER(eDeviceType);
655
656         DevPAddr.uiAddr = SysPAddr.uiAddr;
657
658         return DevPAddr;
659 }
660
661 struct IMG_SYS_PHYADDR SysDevPAddrToSysPAddr(
662                                       enum PVRSRV_DEVICE_TYPE eDeviceType,
663                                       struct IMG_DEV_PHYADDR DevPAddr)
664 {
665         struct IMG_SYS_PHYADDR SysPAddr;
666
667         PVR_UNREFERENCED_PARAMETER(eDeviceType);
668
669         SysPAddr.uiAddr = DevPAddr.uiAddr;
670
671         return SysPAddr;
672 }
673
674 void SysRegisterExternalDevice(struct PVRSRV_DEVICE_NODE *psDeviceNode)
675 {
676         PVR_UNREFERENCED_PARAMETER(psDeviceNode);
677 }
678
679 void SysRemoveExternalDevice(struct PVRSRV_DEVICE_NODE *psDeviceNode)
680 {
681         PVR_UNREFERENCED_PARAMETER(psDeviceNode);
682 }
683
684 u32 SysGetInterruptSource(struct SYS_DATA *psSysData,
685                                  struct PVRSRV_DEVICE_NODE *psDeviceNode)
686 {
687         PVR_UNREFERENCED_PARAMETER(psSysData);
688 #if defined(NO_HARDWARE)
689
690         return 0xFFFFFFFF;
691 #else
692
693         return psDeviceNode->ui32SOCInterruptBit;
694 #endif
695 }
696
697 void SysClearInterrupts(struct SYS_DATA *psSysData, u32 ui32ClearBits)
698 {
699         PVR_UNREFERENCED_PARAMETER(psSysData);
700         PVR_UNREFERENCED_PARAMETER(ui32ClearBits);
701
702         OSReadHWReg(((struct PVRSRV_SGXDEV_INFO *)gpsSGXDevNode->pvDevice)->
703                     pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR);
704 }
705
706 enum PVRSRV_ERROR SysSystemPrePowerState(enum PVR_POWER_STATE eNewPowerState)
707 {
708         enum PVRSRV_ERROR eError = PVRSRV_OK;
709
710         if (eNewPowerState == PVRSRV_POWER_STATE_D3) {
711                 PVR_TRACE("SysSystemPrePowerState: Entering state D3");
712
713                 if (SYS_SPECIFIC_DATA_TEST
714                     (&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) {
715                         eError = OSUninstallDeviceLISR(gpsSysData);
716                         if (eError != PVRSRV_OK) {
717                                 PVR_DPF(PVR_DBG_ERROR,
718                                                 "SysSystemPrePowerState: "
719                                                 "OSUninstallDeviceLISR failed "
720                                                 "(%d)",
721                                          eError);
722                                 return eError;
723                         }
724                         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
725                                         SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR);
726                         SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData,
727                                         SYS_SPECIFIC_DATA_ENABLE_LISR);
728                 }
729
730                 if (SYS_SPECIFIC_DATA_TEST
731                     (&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) {
732                         DisableSystemClocks(gpsSysData);
733
734                         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
735                                 SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS);
736                         SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData,
737                                 SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS);
738                 }
739         }
740
741         return eError;
742 }
743
744 enum PVRSRV_ERROR SysSystemPostPowerState(enum PVR_POWER_STATE eNewPowerState)
745 {
746         enum PVRSRV_ERROR eError = PVRSRV_OK;
747
748         if (eNewPowerState == PVRSRV_POWER_STATE_D0) {
749                 PVR_TRACE("SysSystemPostPowerState: Entering state D0");
750
751                 if (SYS_SPECIFIC_DATA_TEST
752                     (&gsSysSpecificData,
753                      SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS)) {
754                         eError = EnableSystemClocks(gpsSysData);
755                         if (eError != PVRSRV_OK) {
756                                 PVR_DPF(PVR_DBG_ERROR,
757                                         "SysSystemPostPowerState: "
758                                         "EnableSystemClocks failed (%d)",
759                                          eError);
760                                 return eError;
761                         }
762                         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
763                                         SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS);
764                         SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData,
765                                         SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS);
766                 }
767                 if (SYS_SPECIFIC_DATA_TEST
768                     (&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR)) {
769                         eError =
770                             OSInstallDeviceLISR(gpsSysData,
771                                                 gsSGXDeviceMap.ui32IRQ,
772                                                 "SGX ISR", gpsSGXDevNode);
773                         if (eError != PVRSRV_OK) {
774                                 PVR_DPF(PVR_DBG_ERROR,
775                                                 "SysSystemPostPowerState: "
776                                                 "OSInstallDeviceLISR failed "
777                                                 "to install ISR (%d)",
778                                          eError);
779                                 return eError;
780                         }
781                         SYS_SPECIFIC_DATA_SET(&gsSysSpecificData,
782                                 SYS_SPECIFIC_DATA_ENABLE_LISR);
783                         SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData,
784                                 SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR);
785                 }
786         }
787         return eError;
788 }
789
790 enum PVRSRV_ERROR SysDevicePrePowerState(u32 ui32DeviceIndex,
791                                     enum PVR_POWER_STATE eNewPowerState,
792                                     enum PVR_POWER_STATE eCurrentPowerState)
793 {
794         PVR_UNREFERENCED_PARAMETER(eCurrentPowerState);
795
796         if (ui32DeviceIndex != gui32SGXDeviceID)
797                 return PVRSRV_OK;
798         if (eNewPowerState == PVRSRV_POWER_STATE_D3) {
799                 PVR_DPF(PVR_DBG_MESSAGE,
800                          "SysDevicePrePowerState: SGX Entering state D3");
801                 DisableSGXClocks(gpsSysData);
802         }
803         return PVRSRV_OK;
804 }
805
806 enum PVRSRV_ERROR SysDevicePostPowerState(u32 ui32DeviceIndex,
807                                      enum PVR_POWER_STATE eNewPowerState,
808                                      enum PVR_POWER_STATE eCurrentPowerState)
809 {
810         enum PVRSRV_ERROR eError = PVRSRV_OK;
811
812         PVR_UNREFERENCED_PARAMETER(eNewPowerState);
813
814         if (ui32DeviceIndex != gui32SGXDeviceID)
815                 return eError;
816         if (eCurrentPowerState == PVRSRV_POWER_STATE_D3) {
817                 PVR_DPF(PVR_DBG_MESSAGE,
818                          "SysDevicePostPowerState: SGX Leaving state D3");
819                 eError = EnableSGXClocks(gpsSysData);
820         }
821
822         return eError;
823 }
824
825 enum PVRSRV_ERROR SysOEMFunction(u32 ui32ID, void *pvIn, u32 ulInSize,
826                             void *pvOut, u32 ulOutSize)
827 {
828         PVR_UNREFERENCED_PARAMETER(ui32ID);
829         PVR_UNREFERENCED_PARAMETER(pvIn);
830         PVR_UNREFERENCED_PARAMETER(ulInSize);
831         PVR_UNREFERENCED_PARAMETER(pvOut);
832         PVR_UNREFERENCED_PARAMETER(ulOutSize);
833
834         if ((ui32ID == OEM_GET_EXT_FUNCS) &&
835             (ulOutSize == sizeof(struct PVRSRV_DC_OEM_JTABLE))) {
836
837                 struct PVRSRV_DC_OEM_JTABLE *psOEMJTable =
838                     (struct PVRSRV_DC_OEM_JTABLE *)pvOut;
839                 psOEMJTable->pfnOEMBridgeDispatch = &PVRSRV_BridgeDispatchKM;
840                 return PVRSRV_OK;
841         }
842
843         return PVRSRV_ERROR_INVALID_PARAMS;
844 }