/********************************************************************** * * Copyright (C) Imagination Technologies Ltd. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful but, except * as otherwise stated in writing, without any warranty; without even the * implied warranty of merchantability or fitness for a particular purpose. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * * The full GNU General Public License is included in this distribution in * the file called "COPYING". * * Contact Information: * Imagination Technologies Ltd. * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK * ******************************************************************************/ #include "sgxdefs.h" #include "services_headers.h" #include "kerneldisplay.h" #include "oemfuncs.h" #include "sgxinfo.h" #include "sgxinfokm.h" #include #include #include #include #ifdef CONFIG_DVFS_LIMIT #include #else #include #endif #define REAL_HARDWARE 1 #define SGX540_BASEADDR 0xf3000000 #define MAPPING_SIZE 0x10000 #define SGX540_IRQ IRQ_3D #define SYS_SGX_CLOCK_SPEED (200000000) #define SYS_SGX_HWRECOVERY_TIMEOUT_FREQ (100) // 10ms (100hz) #define SYS_SGX_PDS_TIMER_FREQ (1000) // 1ms (1000hz) #ifndef SYS_SGX_ACTIVE_POWER_LATENCY_MS #define SYS_SGX_ACTIVE_POWER_LATENCY_MS (500) #endif typedef struct _SYS_SPECIFIC_DATA_TAG_ { IMG_UINT32 ui32SysSpecificData; } SYS_SPECIFIC_DATA; #define SYS_SPECIFIC_DATA_ENABLE_IRQ 0x00000001UL #define SYS_SPECIFIC_DATA_ENABLE_LISR 0x00000002UL #define SYS_SPECIFIC_DATA_ENABLE_MISR 0x00000004UL SYS_SPECIFIC_DATA gsSysSpecificData; /* top level system data anchor point*/ SYS_DATA* gpsSysData = (SYS_DATA*)IMG_NULL; SYS_DATA gsSysData; /* SGX structures */ static IMG_UINT32 gui32SGXDeviceID; static SGX_DEVICE_MAP gsSGXDeviceMap; /* mimic slaveport and register block with contiguous memory */ IMG_CPU_VIRTADDR gsSGXRegsCPUVAddr; IMG_CPU_VIRTADDR gsSGXSPCPUVAddr; static char gszVersionString[] = "SGX540 S5PC110"; IMG_UINT32 PVRSRV_BridgeDispatchKM( IMG_UINT32 Ioctl, IMG_BYTE *pInBuf, IMG_UINT32 InBufLen, IMG_BYTE *pOutBuf, IMG_UINT32 OutBufLen, IMG_UINT32 *pdwBytesTransferred); #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) /* * We need to keep the memory bus speed up when the GPU is active. * On the S5PV210, it is bound to the CPU freq. * In arch/arm/mach-s5pv210/cpufreq.c, the bus speed is only lowered when the * CPU freq is below 200MHz. */ #define MIN_CPU_KHZ_FREQ 200000 static struct clk *g3d_clock; static struct regulator *g3d_pd_regulator; #ifndef CONFIG_DVFS_LIMIT static int limit_adjust_cpufreq_notifier(struct notifier_block *nb, unsigned long event, void *data) { struct cpufreq_policy *policy = data; if (event != CPUFREQ_ADJUST) return 0; /* This is our indicator of GPU activity */ if (regulator_is_enabled(g3d_pd_regulator)) cpufreq_verify_within_limits(policy, MIN_CPU_KHZ_FREQ, policy->cpuinfo.max_freq); return 0; } static struct notifier_block cpufreq_limit_notifier = { .notifier_call = limit_adjust_cpufreq_notifier, }; #endif static PVRSRV_ERROR EnableSGXClocks(void) { #ifdef CONFIG_DVFS_LIMIT s5pv210_lock_dvfs_high_level(DVFS_LOCK_TOKEN_PVR, L3); /* 200 MHz */ #endif regulator_enable(g3d_pd_regulator); clk_enable(g3d_clock); #ifndef CONFIG_DVFS_LIMIT cpufreq_update_policy(current_thread_info()->cpu); #endif return PVRSRV_OK; } static PVRSRV_ERROR DisableSGXClocks(void) { clk_disable(g3d_clock); regulator_disable(g3d_pd_regulator); #ifdef CONFIG_DVFS_LIMIT s5pv210_unlock_dvfs_high_level(DVFS_LOCK_TOKEN_PVR); #else cpufreq_update_policy(current_thread_info()->cpu); #endif return PVRSRV_OK; } #endif /* defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) */ /*! ****************************************************************************** @Function SysLocateDevices @Description specifies devices in the systems memory map @Input psSysData - sys data @Return PVRSRV_ERROR : ******************************************************************************/ static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData) { PVR_UNREFERENCED_PARAMETER(psSysData); gsSGXDeviceMap.sRegsSysPBase.uiAddr = SGX540_BASEADDR; gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); gsSGXDeviceMap.ui32RegsSize = SGX_REG_SIZE; gsSGXDeviceMap.ui32IRQ = SGX540_IRQ; #if defined(SGX_FEATURE_HOST_PORT) /* HostPort: */ gsSGXDeviceMap.sHPSysPBase.uiAddr = 0; gsSGXDeviceMap.sHPCpuPBase.uiAddr = 0; gsSGXDeviceMap.ui32HPSize = 0; #endif /* Local Device Memory Region: (not present) Note: the device doesn't need to know about its memory but keep info here for now */ gsSGXDeviceMap.sLocalMemSysPBase.uiAddr = 0; gsSGXDeviceMap.sLocalMemDevPBase.uiAddr = 0; gsSGXDeviceMap.sLocalMemCpuPBase.uiAddr = 0; gsSGXDeviceMap.ui32LocalMemSize = 0; /* device interrupt IRQ Note: no interrupts available on No HW system */ gsSGXDeviceMap.ui32IRQ = SGX540_IRQ; #if defined(PDUMP) { /* initialise memory region name for pdumping */ static IMG_CHAR pszPDumpDevName[] = "SGXMEM"; gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName; } #endif /* add other devices here: */ return PVRSRV_OK; } /*! ****************************************************************************** @Function SysInitialise @Description Initialises kernel services at 'driver load' time @Return PVRSRV_ERROR : ******************************************************************************/ PVRSRV_ERROR SysInitialise(IMG_VOID) { IMG_UINT32 i; PVRSRV_ERROR eError; PVRSRV_DEVICE_NODE *psDeviceNode; SGX_TIMING_INFORMATION* psTimingInfo; gpsSysData = &gsSysData; OSMemSet(gpsSysData, 0, sizeof(SYS_DATA)); #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) { extern struct platform_device *gpsPVRLDMDev; g3d_pd_regulator = regulator_get(&gpsPVRLDMDev->dev, "pd"); if (IS_ERR(g3d_pd_regulator)) { PVR_DPF((PVR_DBG_ERROR, "G3D failed to find g3d power domain")); return PVRSRV_ERROR_INIT_FAILURE; } g3d_clock = clk_get(&gpsPVRLDMDev->dev, "sclk"); if (IS_ERR(g3d_clock)) { PVR_DPF((PVR_DBG_ERROR, "G3D failed to find g3d clock source-enable")); return PVRSRV_ERROR_INIT_FAILURE; } EnableSGXClocks(); } #endif eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure")); SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } gpsSysData->pvSysSpecificData = (IMG_PVOID)&gsSysSpecificData; OSMemSet(&gsSGXDeviceMap, 0, sizeof(SGX_DEVICE_MAP)); /* Set up timing information*/ psTimingInfo = &gsSGXDeviceMap.sTimingInfo; psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) psTimingInfo->bEnableActivePM = IMG_TRUE; #else psTimingInfo->bEnableActivePM = IMG_FALSE; #endif gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT; /* init device ID's */ for(i=0; isDeviceID[i].uiID = i; gpsSysData->sDeviceID[i].bInUse = IMG_FALSE; } gpsSysData->psDeviceNodeList = IMG_NULL; gpsSysData->psQueueList = IMG_NULL; eError = SysInitialiseCommon(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon")); SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } /* Locate the devices within the system, specifying the physical addresses of each devices components (regs, mem, ports etc.) */ eError = SysLocateDevices(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices")); SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } /* Register devices with the system This also sets up their memory maps/heaps */ eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice, 1, &gui32SGXDeviceID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!")); SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } /* Once all devices are registered, specify the backing store and, if required, customise the memory heap config */ psDeviceNode = gpsSysData->psDeviceNodeList; while(psDeviceNode) { /* perform any OEM SOC address space customisations here */ switch(psDeviceNode->sDevId.eDeviceType) { case PVRSRV_DEVICE_TYPE_SGX: { DEVICE_MEMORY_INFO *psDevMemoryInfo; DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; IMG_UINT32 ui32MemConfig; if(gpsSysData->apsLocalDevMemArena[0] != IMG_NULL) { /* specify the backing store to use for the device's MMU PT/PDs */ psDeviceNode->psLocalDevMemArena = gpsSysData->apsLocalDevMemArena[0]; ui32MemConfig = PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG; } else { /* specify the backing store to use for the devices MMU PT/PDs - the PT/PDs are always UMA in this system */ psDeviceNode->psLocalDevMemArena = IMG_NULL; ui32MemConfig = PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG; } /* useful pointers */ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; /* specify the backing store for all SGX heaps */ for(i=0; iui32HeapCount; i++) { #if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE) IMG_CHAR *pStr; switch(psDeviceMemoryHeap[i].ui32HeapID) { case HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_HEAP_ID): { pStr = "GeneralHeapPageSize"; break; } case HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_MAPPING_HEAP_ID): { pStr = "GeneralMappingHeapPageSize"; break; } case HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_TADATA_HEAP_ID): { pStr = "TADataHeapPageSize"; break; } case HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_CODE_HEAP_ID): { pStr = "KernelCodeHeapPageSize"; break; } case HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_DATA_HEAP_ID): { pStr = "KernelDataHeapPageSize"; break; } case HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_PIXELSHADER_HEAP_ID): { pStr = "PixelShaderHeapPageSize"; break; } case HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_VERTEXSHADER_HEAP_ID): { pStr = "VertexShaderHeapPageSize"; break; } case HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_PDSPIXEL_CODEDATA_HEAP_ID): { pStr = "PDSPixelHeapPageSize"; break; } case HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_PDSVERTEX_CODEDATA_HEAP_ID): { pStr = "PDSVertexHeapPageSize"; break; } case HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_SYNCINFO_HEAP_ID): { pStr = "SyncInfoHeapPageSize"; break; } case HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_3DPARAMETERS_HEAP_ID): { pStr = "3DParametersHeapPageSize"; break; } default: { /* not interested in other heaps */ pStr = IMG_NULL; break; } } if (pStr && OSReadRegistryDWORDFromString(0, PVRSRV_REGISTRY_ROOT, pStr, &psDeviceMemoryHeap[i].ui32DataPageSize) == IMG_TRUE) { PVR_DPF((PVR_DBG_VERBOSE,"SysInitialise: set Heap %s page size to %d", pStr, psDeviceMemoryHeap[i].ui32DataPageSize)); } #endif /* map the device memory allocator(s) onto the device memory heaps as required */ psDeviceMemoryHeap[i].psLocalDevMemArena = gpsSysData->apsLocalDevMemArena[0]; /* set the memory config (uma | non-uma) */ psDeviceMemoryHeap[i].ui32Attribs |= ui32MemConfig; } break; } default: PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!")); return PVRSRV_ERROR_INIT_FAILURE; } /* advance to next device */ psDeviceNode = psDeviceNode->psNext; } /* Initialise all devices 'managed' by services: */ eError = PVRSRVInitialiseDevice (gui32SGXDeviceID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!")); SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) DisableSGXClocks(); #endif return PVRSRV_OK; } /*! ****************************************************************************** @Function SysFinalise @Description Final part of initialisation @Return PVRSRV_ERROR : ******************************************************************************/ PVRSRV_ERROR SysFinalise(IMG_VOID) { PVRSRV_ERROR eError; #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) eError = EnableSGXClocks(); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError)); (IMG_VOID)SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } #endif eError = OSInstallMISR(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"OSInstallMISR: Failed to install MISR")); SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } gsSysSpecificData.ui32SysSpecificData |= SYS_SPECIFIC_DATA_ENABLE_MISR; #if defined(SYS_USING_INTERRUPTS) /* install a system ISR */ eError = OSInstallSystemLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"OSInstallSystemLISR: Failed to install ISR")); OSUninstallMISR(gpsSysData); SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } gsSysSpecificData.ui32SysSpecificData |= SYS_SPECIFIC_DATA_ENABLE_LISR; gsSysSpecificData.ui32SysSpecificData |= SYS_SPECIFIC_DATA_ENABLE_IRQ; #endif /* defined(SYS_USING_INTERRUPTS) */ /* Create a human readable version string for this system */ gpsSysData->pszVersionString = gszVersionString; if (!gpsSysData->pszVersionString) { PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to create a system version string")); } else { PVR_DPF((PVR_DBG_WARNING, "SysFinalise: Version string: %s", gpsSysData->pszVersionString)); } #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) DisableSGXClocks(); #ifndef CONFIG_DVFS_LIMIT cpufreq_register_notifier(&cpufreq_limit_notifier, CPUFREQ_POLICY_NOTIFIER); #endif #endif return PVRSRV_OK; } /*! ****************************************************************************** @Function SysDeinitialise @Description De-initialises kernel services at 'driver unload' time @Return PVRSRV_ERROR : ******************************************************************************/ PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) { SYS_SPECIFIC_DATA * psSysSpecData; PVRSRV_ERROR eError; if (psSysData == IMG_NULL) { PVR_DPF((PVR_DBG_ERROR, "SysDeinitialise: Called with NULL SYS_DATA pointer. Probably called before.")); return PVRSRV_OK; } psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) /* TODO: regulator and clk put. */ #ifdef CONFIG_DVFS_LIMIT s5pv210_unlock_dvfs_high_level(DVFS_LOCK_TOKEN_PVR); #else cpufreq_unregister_notifier(&cpufreq_limit_notifier, CPUFREQ_POLICY_NOTIFIER); cpufreq_update_policy(current_thread_info()->cpu); #endif #endif #if defined(SYS_USING_INTERRUPTS) if (psSysSpecData->ui32SysSpecificData & SYS_SPECIFIC_DATA_ENABLE_LISR) { eError = OSUninstallSystemLISR(psSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallSystemLISR failed")); return eError; } } #endif if (psSysSpecData->ui32SysSpecificData & SYS_SPECIFIC_DATA_ENABLE_MISR) { eError = OSUninstallMISR(psSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallMISR failed")); return eError; } } /* de-initialise all services managed devices */ eError = PVRSRVDeinitialiseDevice (gui32SGXDeviceID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init the device")); return eError; } eError = OSDeInitEnvData(gpsSysData->pvEnvSpecificData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init env structure")); return eError; } SysDeinitialiseCommon(gpsSysData); gpsSysData = IMG_NULL; return PVRSRV_OK; } /*! ****************************************************************************** @Function SysGetDeviceMemoryMap @Description returns a device address map for the specified device @Input eDeviceType - device type @Input ppvDeviceMap - void ptr to receive device specific info. @Return PVRSRV_ERROR ******************************************************************************/ PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType, IMG_VOID **ppvDeviceMap) { switch(eDeviceType) { case PVRSRV_DEVICE_TYPE_SGX: { /* just return a pointer to the structure */ *ppvDeviceMap = (IMG_VOID*)&gsSGXDeviceMap; break; } default: { PVR_DPF((PVR_DBG_ERROR,"SysGetDeviceMemoryMap: unsupported device type")); } } return PVRSRV_OK; } /*---------------------------------------------------------------------------- FUNCTION: SysCpuPAddrToDevPAddr PURPOSE: Compute a device physical address from a cpu physical address. Relevant when PARAMETERS: In: cpu_paddr - cpu physical address. In: eDeviceType - device type required if DevPAddr address spaces vary across devices in the same system RETURNS: device physical address. ------------------------------------------------------------------------------*/ IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_CPU_PHYADDR CpuPAddr) { IMG_DEV_PHYADDR DevPAddr; PVR_UNREFERENCED_PARAMETER(eDeviceType); /* Note: for no HW UMA system we assume DevP == CpuP */ DevPAddr.uiAddr = CpuPAddr.uiAddr; return DevPAddr; } /*---------------------------------------------------------------------------- FUNCTION: SysSysPAddrToCpuPAddr PURPOSE: Compute a cpu physical address from a system physical address. PARAMETERS: In: sys_paddr - system physical address. RETURNS: cpu physical address. ------------------------------------------------------------------------------*/ IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR sys_paddr) { IMG_CPU_PHYADDR cpu_paddr; /* This would only be an inequality if the CPU's MMU did not point to sys address 0, ie. multi CPU system */ cpu_paddr.uiAddr = sys_paddr.uiAddr; return cpu_paddr; } /*---------------------------------------------------------------------------- FUNCTION: SysCpuPAddrToSysPAddr PURPOSE: Compute a system physical address from a cpu physical address. PARAMETERS: In: cpu_paddr - cpu physical address. RETURNS: device physical address. ------------------------------------------------------------------------------*/ IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr) { IMG_SYS_PHYADDR sys_paddr; /* This would only be an inequality if the CPU's MMU did not point to sys address 0, ie. multi CPU system */ sys_paddr.uiAddr = cpu_paddr.uiAddr; return sys_paddr; } /*---------------------------------------------------------------------------- FUNCTION: SysSysPAddrToDevPAddr PURPOSE: Compute a device physical address from a system physical address. PARAMETERS: In: SysPAddr - system physical address. In: eDeviceType - device type required if DevPAddr address spaces vary across devices in the same system RETURNS: Device physical address. -----------------------------------------------------------------------------*/ IMG_DEV_PHYADDR SysSysPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr) { IMG_DEV_PHYADDR DevPAddr; PVR_UNREFERENCED_PARAMETER(eDeviceType); /* Note: for no HW UMA system we assume DevP == CpuP */ DevPAddr.uiAddr = SysPAddr.uiAddr; return DevPAddr; } /*---------------------------------------------------------------------------- FUNCTION: SysDevPAddrToSysPAddr PURPOSE: Compute a device physical address from a system physical address. PARAMETERS: In: DevPAddr - device physical address. In: eDeviceType - device type required if DevPAddr address spaces vary across devices in the same system RETURNS: System physical address. -----------------------------------------------------------------------------*/ IMG_SYS_PHYADDR SysDevPAddrToSysPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR DevPAddr) { IMG_SYS_PHYADDR SysPAddr; PVR_UNREFERENCED_PARAMETER(eDeviceType); /* Note: for no HW UMA system we assume DevP == SysP */ SysPAddr.uiAddr = DevPAddr.uiAddr; return SysPAddr; } /***************************************************************************** FUNCTION : SysRegisterExternalDevice PURPOSE : Called when a 3rd party device registers with services PARAMETERS: In: psDeviceNode - the new device node. RETURNS : IMG_VOID *****************************************************************************/ IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) { PVR_UNREFERENCED_PARAMETER(psDeviceNode); } /***************************************************************************** FUNCTION : SysRemoveExternalDevice PURPOSE : Called when a 3rd party device unregisters from services PARAMETERS: In: psDeviceNode - the device node being removed. RETURNS : IMG_VOID *****************************************************************************/ IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) { PVR_UNREFERENCED_PARAMETER(psDeviceNode); } /*---------------------------------------------------------------------------- FUNCTION: SysGetInterruptSource PURPOSE: Returns System specific information about the device(s) that generated the interrupt in the system PARAMETERS: In: psSysData In: psDeviceNode RETURNS: System specific information indicating which device(s) generated the interrupt -----------------------------------------------------------------------------*/ IMG_UINT32 SysGetInterruptSource(SYS_DATA* psSysData, PVRSRV_DEVICE_NODE *psDeviceNode) { PVR_UNREFERENCED_PARAMETER(psSysData); PVR_UNREFERENCED_PARAMETER(psDeviceNode); #if defined(NO_HARDWARE) /* no interrupts in no_hw system just return all bits */ return 0xFFFFFFFF; #else return 0x1; #endif } /*---------------------------------------------------------------------------- FUNCTION: SysGetInterruptSource PURPOSE: Clears specified system interrupts PARAMETERS: psSysData ui32ClearBits RETURNS: IMG_VOID -----------------------------------------------------------------------------*/ IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits) { PVR_UNREFERENCED_PARAMETER(psSysData); PVR_UNREFERENCED_PARAMETER(ui32ClearBits); /* no interrupts in no_hw system, nothing to do */ } /*! ****************************************************************************** @Function SysSystemPrePowerState @Description Perform system-level processing required before a power transition @Input eNewPowerState : @Return PVRSRV_ERROR : ******************************************************************************/ PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState) { PVR_UNREFERENCED_PARAMETER(eNewPowerState); return PVRSRV_OK; } /*! ****************************************************************************** @Function SysSystemPostPowerState @Description Perform system-level processing required after a power transition @Input eNewPowerState : @Return PVRSRV_ERROR : ******************************************************************************/ PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState) { PVR_UNREFERENCED_PARAMETER(eNewPowerState); return PVRSRV_OK; } /*! ****************************************************************************** @Function SysDevicePrePowerState @Description Perform system-level processing required before a device power transition @Input ui32DeviceIndex : @Input eNewPowerState : @Input eCurrentPowerState : @Return PVRSRV_ERROR ******************************************************************************/ PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex, PVRSRV_DEV_POWER_STATE eNewPowerState, PVRSRV_DEV_POWER_STATE eCurrentPowerState) { PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); if (ui32DeviceIndex != gui32SGXDeviceID) { return PVRSRV_OK; } #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF) { PVRSRVSetDCState(DC_STATE_FLUSH_COMMANDS); PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePrePowerState: SGX Entering state D3")); DisableSGXClocks(); PVRSRVSetDCState(DC_STATE_NO_FLUSH_COMMANDS); } #else PVR_UNREFERENCED_PARAMETER(eNewPowerState); #endif return PVRSRV_OK; } /*! ****************************************************************************** @Function SysDevicePostPowerState @Description Perform system-level processing required after a device power transition @Input ui32DeviceIndex : @Input eNewPowerState : @Input eCurrentPowerState : @Return PVRSRV_ERROR ******************************************************************************/ PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex, PVRSRV_DEV_POWER_STATE eNewPowerState, PVRSRV_DEV_POWER_STATE eCurrentPowerState) { PVRSRV_ERROR eError = PVRSRV_OK; PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); if (ui32DeviceIndex != gui32SGXDeviceID) { return eError; } #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) if (eNewPowerState == PVRSRV_DEV_POWER_STATE_ON) { PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePostPowerState: SGX Leaving state D3")); eError = EnableSGXClocks(); } #else PVR_UNREFERENCED_PARAMETER(eNewPowerState); #endif return eError; } /***************************************************************************** FUNCTION : SysOEMFunction PURPOSE : marshalling function for custom OEM functions PARAMETERS : ui32ID - function ID pvIn - in data pvOut - out data RETURNS : PVRSRV_ERROR *****************************************************************************/ PVRSRV_ERROR SysOEMFunction(IMG_UINT32 ui32ID, IMG_VOID *pvIn, IMG_UINT32 ulInSize, IMG_VOID *pvOut, IMG_UINT32 ulOutSize) { PVR_UNREFERENCED_PARAMETER(ulInSize); PVR_UNREFERENCED_PARAMETER(pvIn); if ((ui32ID == OEM_GET_EXT_FUNCS) && (ulOutSize == sizeof(PVRSRV_DC_OEM_JTABLE))) { PVRSRV_DC_OEM_JTABLE *psOEMJTable = (PVRSRV_DC_OEM_JTABLE*)pvOut; psOEMJTable->pfnOEMBridgeDispatch = &PVRSRV_BridgeDispatchKM; return PVRSRV_OK; } return PVRSRV_ERROR_INVALID_PARAMS; } PVRSRV_ERROR SysPowerLockWrap(IMG_BOOL bTryLock) { /* FIXME: This should not be empty */ PVR_UNREFERENCED_PARAMETER(bTryLock); return PVRSRV_OK; } IMG_VOID SysPowerLockUnwrap(IMG_VOID) { /* FIXME: This should not be empty */ } /****************************************************************************** End of file (sysconfig.c) ******************************************************************************/