1 /*************************************************************************/ /*!
3 @Title System Configuration
4 @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
5 @Description System Configuration functions
6 @License Dual MIT/GPLv2
8 The contents of this file are subject to the MIT license as set out below.
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files (the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
17 The above copyright notice and this permission notice shall be included in
18 all copies or substantial portions of the Software.
20 Alternatively, the contents of this file may be used under the terms of
21 the GNU General Public License Version 2 ("GPL") in which case the provisions
22 of GPL are applicable instead of those above.
24 If you wish to allow use of your version of this file only under the terms of
25 GPL, and not to allow others to use your version of this file under the terms
26 of the MIT license, indicate your decision by deleting the provisions above
27 and replace them with the notice and other provisions required by GPL as set
28 out in the file called "GPL-COPYING" included in this distribution. If you do
29 not delete the provisions above, a recipient may use your version of this file
30 under the terms of either the MIT license or GPL.
32 This License is also included in this distribution in the file called
35 EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
36 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
37 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
38 PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
39 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
40 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
41 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42 */ /**************************************************************************/
45 #include "apollo_regs.h"
47 #include "pvrsrv_device.h"
48 #include "rgxdevice.h"
49 #include "syscommon.h"
51 #include "pvr_debug.h"
53 #if defined(SUPPORT_ION)
54 #include PVR_ANDROID_ION_HEADER
55 #include "ion_support.h"
59 #include "apollo_drv.h"
61 #include <linux/platform_device.h>
64 #error Apollo only supports LMA at the minute
67 /* Valid values for the TC_MEMORY_CONFIG configuration option */
68 #define TC_MEMORY_LOCAL (1)
69 #define TC_MEMORY_HOST (2)
70 #define TC_MEMORY_HYBRID (3)
72 #if TC_MEMORY_CONFIG != TC_MEMORY_LOCAL
73 #error Apollo only supports TC_MEMORY_LOCAL at the minute
76 /* These must be consecutive */
77 #define PHYS_HEAP_IDX_GENERAL 0
78 #define PHYS_HEAP_IDX_DMABUF 1
79 #define PHYS_HEAP_IDX_COUNT 2
81 #define SYS_RGX_ACTIVE_POWER_LATENCY_MS (10)
83 #if defined(PVR_DVFS) || defined(SUPPORT_PDVFS)
85 /* Dummy DVFS configuration used purely for testing purposes */
87 static const IMG_OPP asOPPTable[] =
95 #define LEVEL_COUNT (sizeof(asOPPTable) / sizeof(IMG_OPP))
97 static void SetFrequency(IMG_UINT32 ui32Frequency)
99 PVR_DPF((PVR_DBG_ERROR, "SetFrequency %u", ui32Frequency));
102 static void SetVoltage(IMG_UINT32 ui32Voltage)
104 PVR_DPF((PVR_DBG_ERROR, "SetVoltage %u", ui32Voltage));
109 static void TCLocalCpuPAddrToDevPAddr(IMG_HANDLE hPrivData,
110 IMG_UINT32 ui32NumOfAddr,
111 IMG_DEV_PHYADDR *psDevPAddr,
112 IMG_CPU_PHYADDR *psCpuPAddr);
114 static void TCLocalDevPAddrToCpuPAddr(IMG_HANDLE hPrivData,
115 IMG_UINT32 ui32NumOfAddr,
116 IMG_CPU_PHYADDR *psCpuPAddr,
117 IMG_DEV_PHYADDR *psDevPAddr);
119 static IMG_UINT32 TCLocalGetRegionId(IMG_HANDLE hPrivData,
120 PVRSRV_MEMALLOCFLAGS_T uiAllocFlags);
122 static PHYS_HEAP_FUNCTIONS gsLocalPhysHeapFuncs =
124 .pfnCpuPAddrToDevPAddr = TCLocalCpuPAddrToDevPAddr,
125 .pfnDevPAddrToCpuPAddr = TCLocalDevPAddrToCpuPAddr,
126 .pfnGetRegionId = TCLocalGetRegionId,
129 static void TCIonCpuPAddrToDevPAddr(IMG_HANDLE hPrivData,
130 IMG_UINT32 ui32NumOfAddr,
131 IMG_DEV_PHYADDR *psDevPAddr,
132 IMG_CPU_PHYADDR *psCpuPAddr);
134 static void TCIonDevPAddrToCpuPAddr(IMG_HANDLE hPrivData,
135 IMG_UINT32 ui32NumOfAddr,
136 IMG_CPU_PHYADDR *psCpuPAddr,
137 IMG_DEV_PHYADDR *psDevPAddr);
139 static IMG_UINT32 TCIonGetRegionId(IMG_HANDLE hPrivData,
140 PVRSRV_MEMALLOCFLAGS_T uiAllocFlags);
142 static PHYS_HEAP_FUNCTIONS gsIonPhysHeapFuncs =
144 .pfnCpuPAddrToDevPAddr = TCIonCpuPAddrToDevPAddr,
145 .pfnDevPAddrToCpuPAddr = TCIonDevPAddrToCpuPAddr,
146 .pfnGetRegionId = TCIonGetRegionId,
149 /* BIF Tiling mode configuration */
150 static RGXFWIF_BIFTILINGMODE geBIFTilingMode = RGXFWIF_BIFTILINGMODE_256x16;
152 /* Default BIF tiling heap x-stride configurations. */
153 static IMG_UINT32 gauiBIFTilingHeapXStrides[RGXFWIF_NUM_BIF_TILING_CONFIGS] =
155 0, /* BIF tiling heap 1 x-stride */
156 1, /* BIF tiling heap 2 x-stride */
157 2, /* BIF tiling heap 3 x-stride */
158 3 /* BIF tiling heap 4 x-stride */
161 typedef struct _SYS_DATA_ SYS_DATA;
165 struct platform_device *pdev;
167 struct apollo_rogue_platform_data *pdata;
169 struct resource *registers;
171 #if defined(SUPPORT_ION)
172 struct ion_client *ion_client;
173 struct ion_handle *ion_rogue_allocation;
177 #define SYSTEM_INFO_FORMAT_STRING "FPGA Revision: %s\tTCF Core Revision: %s\tTCF Core Target Build ID: %s\tPCI Version: %s\tMacro Version: %s"
178 static IMG_CHAR *GetDeviceVersionString(SYS_DATA *psSysData)
181 char str_fpga_rev[12];
182 char str_tcf_core_rev[12];
183 char str_tcf_core_target_build_id[4];
185 char str_macro_ver[8];
187 IMG_CHAR *pszVersion;
188 IMG_UINT32 ui32StringLength;
190 err = apollo_sys_strings(psSysData->pdev->dev.parent,
191 str_fpga_rev, sizeof(str_fpga_rev),
192 str_tcf_core_rev, sizeof(str_tcf_core_rev),
193 str_tcf_core_target_build_id, sizeof(str_tcf_core_target_build_id),
194 str_pci_ver, sizeof(str_pci_ver),
195 str_macro_ver, sizeof(str_macro_ver));
201 ui32StringLength = OSStringLength(SYSTEM_INFO_FORMAT_STRING);
202 ui32StringLength += OSStringLength(str_fpga_rev);
203 ui32StringLength += OSStringLength(str_tcf_core_rev);
204 ui32StringLength += OSStringLength(str_tcf_core_target_build_id);
205 ui32StringLength += OSStringLength(str_pci_ver);
206 ui32StringLength += OSStringLength(str_macro_ver);
208 /* Create the version string */
209 pszVersion = OSAllocZMem(ui32StringLength * sizeof(IMG_CHAR));
212 OSSNPrintf(&pszVersion[0], ui32StringLength,
213 SYSTEM_INFO_FORMAT_STRING,
216 str_tcf_core_target_build_id,
224 #if defined(SUPPORT_ION)
225 static SYS_DATA *gpsIonPrivateData;
227 PVRSRV_ERROR IonInit(void *pvPrivateData)
229 PVRSRV_ERROR eError = PVRSRV_OK;
230 SYS_DATA *psSysData = pvPrivateData;
231 gpsIonPrivateData = psSysData;
233 psSysData->ion_client = ion_client_create(psSysData->pdata->ion_device, SYS_RGX_DEV_NAME);
234 if (IS_ERR(psSysData->ion_client))
236 PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create ION client (%ld)", __func__, PTR_ERR(psSysData->ion_client)));
237 /* FIXME: Find a better matching error code */
238 eError = PVRSRV_ERROR_PCI_CALL_FAILED;
241 /* Allocate the whole rogue ion heap and pass that to services to manage */
242 psSysData->ion_rogue_allocation = ion_alloc(psSysData->ion_client, psSysData->pdata->rogue_heap_memory_size, 4096, (1 << psSysData->pdata->ion_heap_id), 0);
243 if (IS_ERR(psSysData->ion_rogue_allocation))
245 PVR_DPF((PVR_DBG_ERROR, "%s: Failed to allocate ION rogue buffer (%ld)", __func__, PTR_ERR(psSysData->ion_rogue_allocation)));
246 /* FIXME: Find a better matching error code */
247 eError = PVRSRV_ERROR_PCI_CALL_FAILED;
248 goto err_destroy_client;
254 ion_client_destroy(psSysData->ion_client);
255 psSysData->ion_client = NULL;
262 SYS_DATA *psSysData = gpsIonPrivateData;
263 ion_free(psSysData->ion_client, psSysData->ion_rogue_allocation);
264 psSysData->ion_rogue_allocation = NULL;
265 ion_client_destroy(psSysData->ion_client);
266 psSysData->ion_client = NULL;
269 struct ion_device *IonDevAcquire(void)
271 return gpsIonPrivateData->pdata->ion_device;
274 void IonDevRelease(struct ion_device *ion_device)
276 PVR_ASSERT(ion_device == gpsIonPrivateData->pdata->ion_device);
278 #endif /* defined(SUPPORT_ION) */
280 static void TCLocalCpuPAddrToDevPAddr(IMG_HANDLE hPrivData,
281 IMG_UINT32 ui32NumOfAddr,
282 IMG_DEV_PHYADDR *psDevPAddr,
283 IMG_CPU_PHYADDR *psCpuPAddr)
285 PVRSRV_DEVICE_CONFIG *psDevConfig = (PVRSRV_DEVICE_CONFIG *)hPrivData;
287 /* Optimise common case */
288 psDevPAddr[0].uiAddr = psCpuPAddr[0].uiAddr - psDevConfig->pasPhysHeaps[0].pasRegions[0].sStartAddr.uiAddr;
289 if (ui32NumOfAddr > 1)
292 for (ui32Idx = 1; ui32Idx < ui32NumOfAddr; ++ui32Idx)
294 psDevPAddr[ui32Idx].uiAddr = psCpuPAddr[ui32Idx].uiAddr - psDevConfig->pasPhysHeaps[0].pasRegions[0].sStartAddr.uiAddr;
299 static void TCLocalDevPAddrToCpuPAddr(IMG_HANDLE hPrivData,
300 IMG_UINT32 ui32NumOfAddr,
301 IMG_CPU_PHYADDR *psCpuPAddr,
302 IMG_DEV_PHYADDR *psDevPAddr)
304 PVRSRV_DEVICE_CONFIG *psDevConfig = (PVRSRV_DEVICE_CONFIG *)hPrivData;
306 /* Optimise common case */
307 psCpuPAddr[0].uiAddr = psDevPAddr[0].uiAddr + psDevConfig->pasPhysHeaps[0].pasRegions[0].sStartAddr.uiAddr;
308 if (ui32NumOfAddr > 1)
311 for (ui32Idx = 1; ui32Idx < ui32NumOfAddr; ++ui32Idx)
313 psCpuPAddr[ui32Idx].uiAddr = psDevPAddr[ui32Idx].uiAddr + psDevConfig->pasPhysHeaps[0].pasRegions[0].sStartAddr.uiAddr;
318 static IMG_UINT32 TCLocalGetRegionId(IMG_HANDLE hPrivData,
319 PVRSRV_MEMALLOCFLAGS_T uiAllocFlags)
321 /* Return first region which is always valid */
325 static void TCIonCpuPAddrToDevPAddr(IMG_HANDLE hPrivData,
326 IMG_UINT32 ui32NumOfAddr,
327 IMG_DEV_PHYADDR *psDevPAddr,
328 IMG_CPU_PHYADDR *psCpuPAddr)
330 PVRSRV_DEVICE_CONFIG *psDevConfig = (PVRSRV_DEVICE_CONFIG *)hPrivData;
331 SYS_DATA *psSysData = psDevConfig->hSysData;
333 /* Optimise common case */
334 psDevPAddr[0].uiAddr = psCpuPAddr[0].uiAddr - psSysData->pdata->apollo_memory_base;
335 if (ui32NumOfAddr > 1)
338 for (ui32Idx = 1; ui32Idx < ui32NumOfAddr; ++ui32Idx)
340 psDevPAddr[ui32Idx].uiAddr = psCpuPAddr[ui32Idx].uiAddr - psSysData->pdata->apollo_memory_base;
345 static void TCIonDevPAddrToCpuPAddr(IMG_HANDLE hPrivData,
346 IMG_UINT32 ui32NumOfAddr,
347 IMG_CPU_PHYADDR *psCpuPAddr,
348 IMG_DEV_PHYADDR *psDevPAddr)
350 PVRSRV_DEVICE_CONFIG *psDevConfig = (PVRSRV_DEVICE_CONFIG *)hPrivData;
351 SYS_DATA *psSysData = psDevConfig->hSysData;
353 /* Optimise common case */
354 psCpuPAddr[0].uiAddr = psDevPAddr[0].uiAddr + psSysData->pdata->apollo_memory_base;
355 if (ui32NumOfAddr > 1)
358 for (ui32Idx = 1; ui32Idx < ui32NumOfAddr; ++ui32Idx)
360 psCpuPAddr[ui32Idx].uiAddr = psDevPAddr[ui32Idx].uiAddr + psSysData->pdata->apollo_memory_base;
365 static IMG_UINT32 TCIonGetRegionId(IMG_HANDLE hPrivData,
366 PVRSRV_MEMALLOCFLAGS_T uiAllocFlags)
368 /* Return first region which is always valid */
372 static PVRSRV_ERROR PhysHeapsCreate(SYS_DATA *psSysData,
374 PHYS_HEAP_CONFIG **ppasPhysHeapsOut,
375 IMG_UINT32 *puiPhysHeapCountOut)
377 static IMG_UINT32 uiHeapIDBase = 0;
378 PHYS_HEAP_CONFIG *pasPhysHeaps;
379 PHYS_HEAP_REGION *psRegion;
382 pasPhysHeaps = OSAllocMem(sizeof(*pasPhysHeaps) * PHYS_HEAP_IDX_COUNT);
385 return PVRSRV_ERROR_OUT_OF_MEMORY;
388 psRegion = OSAllocMem(sizeof(*psRegion));
391 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
392 goto ErrorFreePhysHeaps;
395 psRegion->sStartAddr.uiAddr = psSysData->pdata->rogue_heap_memory_base;
396 psRegion->sCardBase.uiAddr = 0;
397 psRegion->uiSize = psSysData->pdata->rogue_heap_memory_size;
399 pasPhysHeaps[PHYS_HEAP_IDX_GENERAL].ui32PhysHeapID =
400 uiHeapIDBase + PHYS_HEAP_IDX_GENERAL;
401 pasPhysHeaps[PHYS_HEAP_IDX_GENERAL].eType = PHYS_HEAP_TYPE_LMA;
402 pasPhysHeaps[PHYS_HEAP_IDX_GENERAL].pszPDumpMemspaceName = "LMA";
403 pasPhysHeaps[PHYS_HEAP_IDX_GENERAL].psMemFuncs = &gsLocalPhysHeapFuncs;
404 pasPhysHeaps[PHYS_HEAP_IDX_GENERAL].pasRegions = psRegion;
405 pasPhysHeaps[PHYS_HEAP_IDX_GENERAL].ui32NumOfRegions = 1;
406 pasPhysHeaps[PHYS_HEAP_IDX_GENERAL].hPrivData = pvPrivData;
408 psRegion = OSAllocMem(sizeof(*psRegion));
411 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
412 goto ErrorGeneralPhysHeapDestroy;
415 psRegion->sStartAddr.uiAddr = psSysData->pdata->pdp_heap_memory_base;
416 psRegion->sCardBase.uiAddr = 0;
417 psRegion->uiSize = psSysData->pdata->pdp_heap_memory_size;
419 pasPhysHeaps[PHYS_HEAP_IDX_DMABUF].ui32PhysHeapID =
420 uiHeapIDBase + PHYS_HEAP_IDX_DMABUF;
421 pasPhysHeaps[PHYS_HEAP_IDX_DMABUF].eType = PHYS_HEAP_TYPE_LMA;
422 pasPhysHeaps[PHYS_HEAP_IDX_DMABUF].pszPDumpMemspaceName = "LMA";
423 pasPhysHeaps[PHYS_HEAP_IDX_DMABUF].psMemFuncs = &gsIonPhysHeapFuncs;
424 pasPhysHeaps[PHYS_HEAP_IDX_DMABUF].pasRegions = psRegion;
425 pasPhysHeaps[PHYS_HEAP_IDX_DMABUF].ui32NumOfRegions = 1;
426 pasPhysHeaps[PHYS_HEAP_IDX_DMABUF].hPrivData = pvPrivData;
428 uiHeapIDBase += PHYS_HEAP_IDX_COUNT;
430 *ppasPhysHeapsOut = pasPhysHeaps;
431 *puiPhysHeapCountOut = PHYS_HEAP_IDX_COUNT;
435 ErrorGeneralPhysHeapDestroy:
436 OSFreeMem(pasPhysHeaps[PHYS_HEAP_IDX_GENERAL].pasRegions);
439 OSFreeMem(pasPhysHeaps);
443 static void PhysHeapsDestroy(PHYS_HEAP_CONFIG *pasPhysHeaps,
444 IMG_UINT32 uiPhysHeapCount)
448 for (i = 0; i < uiPhysHeapCount; i++)
450 if (pasPhysHeaps[i].pasRegions)
452 OSFreeMem(pasPhysHeaps[i].pasRegions);
456 OSFreeMem(pasPhysHeaps);
459 static PVRSRV_ERROR DeviceConfigCreate(SYS_DATA *psSysData,
460 PVRSRV_DEVICE_CONFIG **ppsDevConfigOut)
462 PVRSRV_DEVICE_CONFIG *psDevConfig;
464 RGX_TIMING_INFORMATION *psRGXTimingInfo;
465 PHYS_HEAP_CONFIG *pasPhysHeaps;
466 IMG_UINT32 uiPhysHeapCount;
469 psDevConfig = OSAllocZMem(sizeof(*psDevConfig) +
471 sizeof(*psRGXTimingInfo));
474 return PVRSRV_ERROR_OUT_OF_MEMORY;
477 psRGXData = (RGX_DATA *)((IMG_CHAR *)psDevConfig + sizeof(*psDevConfig));
478 psRGXTimingInfo = (RGX_TIMING_INFORMATION *)((IMG_CHAR *)psRGXData + sizeof(*psRGXData));
480 eError = PhysHeapsCreate(psSysData, psDevConfig, &pasPhysHeaps, &uiPhysHeapCount);
481 if (eError != PVRSRV_OK)
483 goto ErrorFreeDevConfig;
486 /* Setup RGX specific timing data */
487 psRGXTimingInfo->ui32CoreClockSpeed = apollo_core_clock_speed(&psSysData->pdev->dev) * 6;
488 psRGXTimingInfo->bEnableActivePM = IMG_FALSE;
489 psRGXTimingInfo->bEnableRDPowIsland = IMG_FALSE;
490 psRGXTimingInfo->ui32ActivePMLatencyms = SYS_RGX_ACTIVE_POWER_LATENCY_MS;
492 /* Set up the RGX data */
493 psRGXData->psRGXTimingInfo = psRGXTimingInfo;
495 /* Setup the device config */
496 psDevConfig->pvOSDevice = &psSysData->pdev->dev;
497 psDevConfig->pszName = "apollo";
498 psDevConfig->pszVersion = GetDeviceVersionString(psSysData);
500 psDevConfig->sRegsCpuPBase.uiAddr = psSysData->registers->start;
501 psDevConfig->ui32RegsSize = resource_size(psSysData->registers);
503 psDevConfig->ui32IRQ = APOLLO_INTERRUPT_EXT;
505 psDevConfig->eCacheSnoopingMode = PVRSRV_DEVICE_SNOOP_NONE;
507 psDevConfig->pasPhysHeaps = pasPhysHeaps;
508 psDevConfig->ui32PhysHeapCount = uiPhysHeapCount;
510 psDevConfig->aui32PhysHeapID[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL] =
511 pasPhysHeaps[PHYS_HEAP_IDX_GENERAL].ui32PhysHeapID;
512 psDevConfig->aui32PhysHeapID[PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL] =
513 pasPhysHeaps[PHYS_HEAP_IDX_GENERAL].ui32PhysHeapID;
514 psDevConfig->aui32PhysHeapID[PVRSRV_DEVICE_PHYS_HEAP_FW_LOCAL] =
515 pasPhysHeaps[PHYS_HEAP_IDX_GENERAL].ui32PhysHeapID;
517 psDevConfig->eBIFTilingMode = geBIFTilingMode;
518 psDevConfig->pui32BIFTilingHeapConfigs = &gauiBIFTilingHeapXStrides[0];
519 psDevConfig->ui32BIFTilingHeapCount = IMG_ARR_NUM_ELEMS(gauiBIFTilingHeapXStrides);
521 psDevConfig->hDevData = psRGXData;
522 psDevConfig->hSysData = psSysData;
524 #if defined(PVR_DVFS) || defined(SUPPORT_PDVFS)
525 /* Dummy DVFS configuration used purely for testing purposes */
526 psDevConfig->sDVFS.sDVFSDeviceCfg.pasOPPTable = asOPPTable;
527 psDevConfig->sDVFS.sDVFSDeviceCfg.ui32OPPTableSize = LEVEL_COUNT;
528 psDevConfig->sDVFS.sDVFSDeviceCfg.pfnSetFrequency = SetFrequency;
529 psDevConfig->sDVFS.sDVFSDeviceCfg.pfnSetVoltage = SetVoltage;
531 #if defined(PVR_DVFS)
532 psDevConfig->sDVFS.sDVFSDeviceCfg.ui32PollMs = 1000;
533 psDevConfig->sDVFS.sDVFSDeviceCfg.bIdleReq = IMG_TRUE;
534 psDevConfig->sDVFS.sDVFSGovernorCfg.ui32UpThreshold = 90;
535 psDevConfig->sDVFS.sDVFSGovernorCfg.ui32DownDifferential = 10;
538 *ppsDevConfigOut = psDevConfig;
543 OSFreeMem(psDevConfig);
547 static void DeviceConfigDestroy(PVRSRV_DEVICE_CONFIG *psDevConfig)
549 if (psDevConfig->pszVersion)
551 OSFreeMem(psDevConfig->pszVersion);
554 PhysHeapsDestroy(psDevConfig->pasPhysHeaps, psDevConfig->ui32PhysHeapCount);
556 OSFreeMem(psDevConfig);
559 PVRSRV_ERROR SysDevInit(void *pvOSDevice, PVRSRV_DEVICE_CONFIG **ppsDevConfig)
561 PVRSRV_DEVICE_CONFIG *psDevConfig;
563 resource_size_t uiRegistersSize;
567 PVR_ASSERT(pvOSDevice);
569 psSysData = OSAllocZMem(sizeof(*psSysData));
570 if (psSysData == NULL)
572 return PVRSRV_ERROR_OUT_OF_MEMORY;
575 psSysData->pdev = to_platform_device((struct device *)pvOSDevice);
576 psSysData->pdata = psSysData->pdev->dev.platform_data;
578 err = apollo_enable(psSysData->pdev->dev.parent);
581 PVR_DPF((PVR_DBG_ERROR, "%s: Failed to enable PCI device (%d)", __func__, err));
582 eError = PVRSRV_ERROR_PCI_CALL_FAILED;
586 psSysData->registers = platform_get_resource_byname(psSysData->pdev,
589 if (!psSysData->registers)
591 PVR_DPF((PVR_DBG_ERROR,
592 "%s: Failed to get Rogue register information",
594 eError = PVRSRV_ERROR_PCI_REGION_UNAVAILABLE;
595 goto ErrorDevDisable;
598 /* Check the address range is large enough. */
599 uiRegistersSize = resource_size(psSysData->registers);
600 if (uiRegistersSize < SYS_RGX_REG_REGION_SIZE)
602 PVR_DPF((PVR_DBG_ERROR,
603 "%s: Rogue register region isn't big enough (was %pa, required 0x%08x)",
604 __FUNCTION__, &uiRegistersSize, SYS_RGX_REG_REGION_SIZE));
606 eError = PVRSRV_ERROR_PCI_REGION_TOO_SMALL;
607 goto ErrorDevDisable;
610 /* Reserve the address range */
611 if (!request_mem_region(psSysData->registers->start,
612 resource_size(psSysData->registers),
615 PVR_DPF((PVR_DBG_ERROR, "%s: Rogue register memory region not available", __FUNCTION__));
616 eError = PVRSRV_ERROR_PCI_CALL_FAILED;
618 goto ErrorDevDisable;
621 eError = DeviceConfigCreate(psSysData, &psDevConfig);
622 if (eError != PVRSRV_OK)
624 goto ErrorReleaseMemRegion;
627 #if defined(SUPPORT_ION)
628 eError = IonInit(psSysData);
629 if (eError != PVRSRV_OK)
631 PVR_DPF((PVR_DBG_ERROR, "%s: Failed to initialise ION", __func__));
632 goto ErrorDeviceConfigDestroy;
636 *ppsDevConfig = psDevConfig;
640 #if defined(SUPPORT_ION)
641 ErrorDeviceConfigDestroy:
642 DeviceConfigDestroy(psDevConfig);
644 ErrorReleaseMemRegion:
645 release_mem_region(psSysData->registers->start,
646 resource_size(psSysData->registers));
648 apollo_disable(psSysData->pdev->dev.parent);
650 OSFreeMem(psSysData);
654 void SysDevDeInit(PVRSRV_DEVICE_CONFIG *psDevConfig)
656 SYS_DATA *psSysData = (SYS_DATA *)psDevConfig->hSysData;
658 #if defined(SUPPORT_ION)
662 DeviceConfigDestroy(psDevConfig);
664 release_mem_region(psSysData->registers->start,
665 resource_size(psSysData->registers));
666 apollo_disable(psSysData->pdev->dev.parent);
668 OSFreeMem(psSysData);
671 PVRSRV_ERROR SysDebugInfo(PVRSRV_DEVICE_CONFIG *psDevConfig,
672 DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
673 void *pvDumpDebugFile)
675 #if defined(TC_APOLLO_TCF5)
676 PVR_UNREFERENCED_PARAMETER(psDevConfig);
677 PVR_UNREFERENCED_PARAMETER(pfnDumpDebugPrintf);
680 SYS_DATA *psSysData = psDevConfig->hSysData;
681 PVRSRV_ERROR eError = PVRSRV_OK;
685 PVR_DUMPDEBUG_LOG("------[ rgx_tc system debug ]------");
687 if (apollo_sys_info(psSysData->pdev->dev.parent, &tmp, &pll))
691 PVR_DUMPDEBUG_LOG("Chip temperature: %d degrees C", tmp);
692 PVR_DUMPDEBUG_LOG("PLL status: %x", pll);
701 struct device *psDev;
707 static void ApolloInterruptHandler(void* pvData)
709 LISR_DATA *psLISRData = pvData;
710 psLISRData->pfnLISR(psLISRData->pvData);
713 PVRSRV_ERROR SysInstallDeviceLISR(IMG_HANDLE hSysData,
715 const IMG_CHAR *pszName,
718 IMG_HANDLE *phLISRData)
720 SYS_DATA *psSysData = (SYS_DATA *)hSysData;
721 LISR_DATA *psLISRData;
725 if (ui32IRQ != APOLLO_INTERRUPT_EXT)
727 PVR_DPF((PVR_DBG_ERROR, "%s: No device matching IRQ %d", __func__, ui32IRQ));
728 return PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR;
731 psLISRData = OSAllocZMem(sizeof(*psLISRData));
734 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
738 psLISRData->pfnLISR = pfnLISR;
739 psLISRData->pvData = pvData;
740 psLISRData->iInterruptID = ui32IRQ;
741 psLISRData->psDev = psSysData->pdev->dev.parent;
743 err = apollo_set_interrupt_handler(psLISRData->psDev, psLISRData->iInterruptID, ApolloInterruptHandler, psLISRData);
746 PVR_DPF((PVR_DBG_ERROR, "%s: apollo_set_interrupt_handler() failed (%d)", __func__, err));
747 eError = PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR;
751 err = apollo_enable_interrupt(psLISRData->psDev, psLISRData->iInterruptID);
754 PVR_DPF((PVR_DBG_ERROR, "%s: apollo_enable_interrupt() failed (%d)", __func__, err));
755 eError = PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR;
756 goto err_unset_interrupt_handler;
759 *phLISRData = psLISRData;
762 PVR_TRACE(("Installed device LISR %pf to irq %u", pfnLISR, ui32IRQ));
766 err_unset_interrupt_handler:
767 apollo_set_interrupt_handler(psLISRData->psDev, psLISRData->iInterruptID, NULL, NULL);
769 OSFreeMem(psLISRData);
773 PVRSRV_ERROR SysUninstallDeviceLISR(IMG_HANDLE hLISRData)
775 LISR_DATA *psLISRData = (LISR_DATA *) hLISRData;
778 err = apollo_disable_interrupt(psLISRData->psDev, psLISRData->iInterruptID);
781 PVR_DPF((PVR_DBG_ERROR, "%s: apollo_enable_interrupt() failed (%d)", __func__, err));
784 err = apollo_set_interrupt_handler(psLISRData->psDev, psLISRData->iInterruptID, NULL, NULL);
787 PVR_DPF((PVR_DBG_ERROR, "%s: apollo_set_interrupt_handler() failed (%d)", __func__, err));
790 PVR_TRACE(("Uninstalled device LISR %pf from irq %u", psLISRData->pfnLISR, psLISRData->iInterruptID));
792 OSFreeMem(psLISRData);