diff options
Diffstat (limited to 'drivers/gpu/pvr/s5pc110/sysconfig.c')
-rw-r--r-- | drivers/gpu/pvr/s5pc110/sysconfig.c | 1031 |
1 files changed, 1031 insertions, 0 deletions
diff --git a/drivers/gpu/pvr/s5pc110/sysconfig.c b/drivers/gpu/pvr/s5pc110/sysconfig.c new file mode 100644 index 0000000..bc675bd --- /dev/null +++ b/drivers/gpu/pvr/s5pc110/sysconfig.c @@ -0,0 +1,1031 @@ +/********************************************************************** + * + * 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. <gpl-support@imgtec.com> + * 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 <linux/platform_device.h> +#include <linux/regulator/consumer.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/cpufreq.h> + +#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; + +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, +}; + +static PVRSRV_ERROR EnableSGXClocks(void) +{ + regulator_enable(g3d_pd_regulator); + clk_enable(g3d_clock); + cpufreq_update_policy(current_thread_info()->cpu); + + return PVRSRV_OK; +} + +static PVRSRV_ERROR DisableSGXClocks(void) +{ + clk_disable(g3d_clock); + regulator_disable(g3d_pd_regulator); + cpufreq_update_policy(current_thread_info()->cpu); + + 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; i<SYS_DEVICE_COUNT; i++) + { + gpsSysData->sDeviceID[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; i<psDevMemoryInfo->ui32HeapCount; 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(); + cpufreq_register_notifier(&cpufreq_limit_notifier, + CPUFREQ_POLICY_NOTIFIER); +#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. */ + cpufreq_unregister_notifier(&cpufreq_limit_notifier, + CPUFREQ_POLICY_NOTIFIER); + cpufreq_update_policy(current_thread_info()->cpu); +#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> + 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. + +</function> +------------------------------------------------------------------------------*/ +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> + FUNCTION: SysSysPAddrToCpuPAddr + + PURPOSE: Compute a cpu physical address from a system physical + address. + + PARAMETERS: In: sys_paddr - system physical address. + RETURNS: cpu physical address. + +</function> +------------------------------------------------------------------------------*/ +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> + FUNCTION: SysCpuPAddrToSysPAddr + + PURPOSE: Compute a system physical address from a cpu physical + address. + + PARAMETERS: In: cpu_paddr - cpu physical address. + RETURNS: device physical address. + +</function> +------------------------------------------------------------------------------*/ +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> + 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. + +</function> +-----------------------------------------------------------------------------*/ +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> + 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. + +</function> +-----------------------------------------------------------------------------*/ +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> + 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 + +</function> +-----------------------------------------------------------------------------*/ +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> + FUNCTION: SysGetInterruptSource + + PURPOSE: Clears specified system interrupts + + PARAMETERS: psSysData + ui32ClearBits + + RETURNS: IMG_VOID + +</function> +-----------------------------------------------------------------------------*/ +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) +******************************************************************************/ |