diff options
author | Ricardo Salveti de Araujo <ricardo.salveti@linaro.org> | 2012-07-18 00:30:31 -0300 |
---|---|---|
committer | Ricardo Salveti de Araujo <ricardo.salveti@linaro.org> | 2012-07-18 00:30:31 -0300 |
commit | 0f9b9d9e1f16d454b12921d3429eced6dc1095d4 (patch) | |
tree | 21eaffbd85393a9e53889bbd868a255c7f6c24fc /sgx/services4/system/omap4 | |
parent | 50fa520ba5f68fa76173493c44715d4542007120 (diff) |
Imported Upstream version 1.9.0.4.1.1 (ARMHF)upstream/1.9.0.4.1.1
Signed-off-by: Ricardo Salveti de Araujo <ricardo.salveti@linaro.org>
Diffstat (limited to 'sgx/services4/system/omap4')
-rw-r--r-- | sgx/services4/system/omap4/oemfuncs.h | 77 | ||||
-rw-r--r-- | sgx/services4/system/omap4/sysconfig.c | 552 | ||||
-rw-r--r-- | sgx/services4/system/omap4/sysconfig.h | 101 | ||||
-rw-r--r-- | sgx/services4/system/omap4/sysinfo.h | 78 | ||||
-rw-r--r-- | sgx/services4/system/omap4/syslocal.h | 129 | ||||
-rw-r--r-- | sgx/services4/system/omap4/sysutils.c | 70 | ||||
-rw-r--r-- | sgx/services4/system/omap4/sysutils_linux.c | 514 |
7 files changed, 1184 insertions, 337 deletions
diff --git a/sgx/services4/system/omap4/oemfuncs.h b/sgx/services4/system/omap4/oemfuncs.h index c8eea1e..1a84eb3 100644 --- a/sgx/services4/system/omap4/oemfuncs.h +++ b/sgx/services4/system/omap4/oemfuncs.h @@ -1,28 +1,44 @@ -/********************************************************************** - * - * 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 - * - ******************************************************************************/ +/*************************************************************************/ /*! +@Title SGX kernel/client driver interface structures and prototypes +@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved +@License Dual MIT/GPLv2 + +The contents of this file are subject to the MIT license as set out below. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Alternatively, the contents of this file may be used under the terms of +the GNU General Public License Version 2 ("GPL") in which case the provisions +of GPL are applicable instead of those above. + +If you wish to allow use of your version of this file only under the terms of +GPL, and not to allow others to use your version of this file under the terms +of the MIT license, indicate your decision by deleting the provisions above +and replace them with the notice and other provisions required by GPL as set +out in the file called "GPL-COPYING" included in this distribution. If you do +not delete the provisions above, a recipient may use your version of this file +under the terms of either the MIT license or GPL. + +This License is also included in this distribution in the file called +"MIT-COPYING". + +EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS +PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ /**************************************************************************/ #if !defined(__OEMFUNCS_H__) #define __OEMFUNCS_H__ @@ -31,12 +47,16 @@ extern "C" { #endif +/* function in/out data structures: */ typedef IMG_UINT32 (*PFN_SRV_BRIDGEDISPATCH)( IMG_UINT32 Ioctl, IMG_BYTE *pInBuf, IMG_UINT32 InBufLen, IMG_BYTE *pOutBuf, IMG_UINT32 OutBufLen, IMG_UINT32 *pdwBytesTransferred); +/* + Function table for kernel 3rd party driver to kernel services +*/ typedef struct PVRSRV_DC_OEM_JTABLE_TAG { PFN_SRV_BRIDGEDISPATCH pfnOEMBridgeDispatch; @@ -52,5 +72,10 @@ typedef struct PVRSRV_DC_OEM_JTABLE_TAG } #endif -#endif +#endif /* __OEMFUNCS_H__ */ + +/***************************************************************************** + End of file (oemfuncs.h) +*****************************************************************************/ + diff --git a/sgx/services4/system/omap4/sysconfig.c b/sgx/services4/system/omap4/sysconfig.c index e860643..e8b41cb 100644 --- a/sgx/services4/system/omap4/sysconfig.c +++ b/sgx/services4/system/omap4/sysconfig.c @@ -1,28 +1,45 @@ -/********************************************************************** - * - * 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 - * - ******************************************************************************/ +/*************************************************************************/ /*! +@Title System Configuration +@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved +@Description System Configuration functions +@License Dual MIT/GPLv2 + +The contents of this file are subject to the MIT license as set out below. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Alternatively, the contents of this file may be used under the terms of +the GNU General Public License Version 2 ("GPL") in which case the provisions +of GPL are applicable instead of those above. + +If you wish to allow use of your version of this file only under the terms of +GPL, and not to allow others to use your version of this file under the terms +of the MIT license, indicate your decision by deleting the provisions above +and replace them with the notice and other provisions required by GPL as set +out in the file called "GPL-COPYING" included in this distribution. If you do +not delete the provisions above, a recipient may use your version of this file +under the terms of either the MIT license or GPL. + +This License is also included in this distribution in the file called +"MIT-COPYING". + +EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS +PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ /**************************************************************************/ #include "sysconfig.h" #include "services_headers.h" @@ -34,17 +51,18 @@ #include "ocpdefs.h" +/* top level system data anchor point*/ SYS_DATA* gpsSysData = (SYS_DATA*)IMG_NULL; SYS_DATA gsSysData; static SYS_SPECIFIC_DATA gsSysSpecificData; SYS_SPECIFIC_DATA *gpsSysSpecificData; -static IMG_UINT32 gui32SGXDeviceID; -static SGX_DEVICE_MAP gsSGXDeviceMap; -static PVRSRV_DEVICE_NODE *gpsSGXDevNode; +/* SGX structures */ +static IMG_UINT32 gui32SGXDeviceID; +static SGX_DEVICE_MAP gsSGXDeviceMap; +static PVRSRV_DEVICE_NODE *gpsSGXDevNode; -#define DEVICE_SGX_INTERRUPT (1 << 0) #if defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) static IMG_CPU_VIRTADDR gsSGXRegsCPUVAddr; @@ -79,14 +97,14 @@ static PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData) return eError; } -#else +#else /* defined(SGX_OCP_REGS_ENABLED) */ static INLINE PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData) { return EnableSGXClocks(psSysData); } -#endif +#endif /* defined(SGX_OCP_REGS_ENABLED) */ static INLINE PVRSRV_ERROR EnableSystemClocksWrap(SYS_DATA *psSysData) { @@ -95,7 +113,10 @@ static INLINE PVRSRV_ERROR EnableSystemClocksWrap(SYS_DATA *psSysData) #if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) if(eError == PVRSRV_OK) { - + /* + * The SGX Clocks are enabled separately if active power + * management is enabled. + */ eError = EnableSGXClocksWrap(psSysData); if (eError != PVRSRV_OK) { @@ -107,6 +128,18 @@ static INLINE PVRSRV_ERROR EnableSystemClocksWrap(SYS_DATA *psSysData) return eError; } +/*! +****************************************************************************** + + @Function SysLocateDevices + + @Description Specifies devices in the systems memory map + + @Input psSysData - sys data + + @Return PVRSRV_ERROR + +******************************************************************************/ static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData) { #if defined(NO_HARDWARE) @@ -121,12 +154,16 @@ static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData) PVR_UNREFERENCED_PARAMETER(psSysData); - + /* SGX Device: */ gsSGXDeviceMap.ui32Flags = 0x0; #if defined(NO_HARDWARE) - - + /* + * For no hardware, allocate some contiguous memory for the + * register block. + */ + + /* Registers */ gsSGXDeviceMap.ui32RegsSize = SYS_OMAP4430_SGX_REGS_SIZE; eError = OSBaseAllocContigMemory(gsSGXDeviceMap.ui32RegsSize, @@ -139,23 +176,27 @@ static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData) gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr; gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase); #if defined(__linux__) - + /* Indicate the registers are already mapped */ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; #else - + /* + * FIXME: Could we just use the virtual address returned by + * OSBaseAllocContigMemory? + */ gsSGXDeviceMap.pvRegsCpuVBase = IMG_NULL; #endif OSMemSet(gsSGXRegsCPUVAddr, 0, gsSGXDeviceMap.ui32RegsSize); - - - + /* + device interrupt IRQ + Note: no interrupts available on no hardware system + */ gsSGXDeviceMap.ui32IRQ = 0; -#else +#else /* defined(NO_HARDWARE) */ #if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) - + /* get the resource and IRQ through platform resource API */ dev_res = platform_get_resource(gpsPVRLDMDev, IORESOURCE_MEM, 0); if (dev_res == NULL) { @@ -180,14 +221,14 @@ static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData) gsSGXDeviceMap.ui32IRQ = dev_irq; PVR_TRACE(("SGX IRQ: %d", gsSGXDeviceMap.ui32IRQ)); -#else +#else /* defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) */ gsSGXDeviceMap.sRegsSysPBase.uiAddr = SYS_OMAP4430_SGX_REGS_SYS_PHYS_BASE; gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); gsSGXDeviceMap.ui32RegsSize = SYS_OMAP4430_SGX_REGS_SIZE; gsSGXDeviceMap.ui32IRQ = SYS_OMAP4430_SGX_IRQ; -#endif +#endif /* defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) */ #if defined(SGX_OCP_REGS_ENABLED) gsSGXRegsCPUVAddr = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase, gsSGXDeviceMap.ui32RegsSize, @@ -200,27 +241,37 @@ static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData) return PVRSRV_ERROR_BAD_MAPPING; } - + /* Indicate the registers are already mapped */ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; gpvOCPRegsLinAddr = gsSGXRegsCPUVAddr; #endif -#endif +#endif /* defined(NO_HARDWARE) */ #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 SysCreateVersionString + + @Description Read the version string + + @Return IMG_CHAR * : Version string + +******************************************************************************/ static IMG_CHAR *SysCreateVersionString(void) { static IMG_CHAR aszVersionString[100]; @@ -273,6 +324,16 @@ static IMG_CHAR *SysCreateVersionString(void) } +/*! +****************************************************************************** + + @Function SysInitialise + + @Description Initialises kernel services at 'driver load' time + + @Return PVRSRV_ERROR : + +******************************************************************************/ PVRSRV_ERROR SysInitialise(IMG_VOID) { IMG_UINT32 i; @@ -304,7 +365,7 @@ PVRSRV_ERROR SysInitialise(IMG_VOID) gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT; - + /* init device ID's */ for(i=0; i<SYS_DEVICE_COUNT; i++) { gpsSysData->sDeviceID[i].uiID = i; @@ -324,7 +385,7 @@ PVRSRV_ERROR SysInitialise(IMG_VOID) } #if !defined(SGX_DYNAMIC_TIMING_INFO) - + /* Set up timing information*/ psTimingInfo = &gsSGXDeviceMap.sTimingInfo; psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; @@ -332,19 +393,21 @@ PVRSRV_ERROR SysInitialise(IMG_VOID) psTimingInfo->bEnableActivePM = IMG_TRUE; #else psTimingInfo->bEnableActivePM = IMG_FALSE; -#endif +#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; #endif - - + /* + Setup the Source Clock Divider value + */ gpsSysSpecificData->ui32SrcClockDiv = 3; - - - - + /* + 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) { @@ -365,9 +428,20 @@ PVRSRV_ERROR SysInitialise(IMG_VOID) } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME); - - + eError = SysDvfsInitialize(gpsSysSpecificData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialize DVFS")); + (IMG_VOID)SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_DVFS_INIT); + /* + Register devices with the system + This also sets up their memory maps/heaps + */ eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice, DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID); if (eError != PVRSRV_OK) @@ -379,14 +453,14 @@ PVRSRV_ERROR SysInitialise(IMG_VOID) } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REGDEV); - - - - + /* + 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: @@ -394,16 +468,17 @@ PVRSRV_ERROR SysInitialise(IMG_VOID) DEVICE_MEMORY_INFO *psDevMemoryInfo; DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; - - - + /* + 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; - + /* useful pointers */ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; - + /* specify the backing store for all SGX heaps */ for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++) { psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG; @@ -419,7 +494,7 @@ PVRSRV_ERROR SysInitialise(IMG_VOID) return PVRSRV_ERROR_INIT_FAILURE; } - + /* advance to next device */ psDeviceNode = psDeviceNode->psNext; } @@ -441,7 +516,7 @@ PVRSRV_ERROR SysInitialise(IMG_VOID) gpsSysData = IMG_NULL; return eError; } -#endif +#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ eError = PVRSRVInitialiseDevice(gui32SGXDeviceID); if (eError != PVRSRV_OK) @@ -454,9 +529,9 @@ PVRSRV_ERROR SysInitialise(IMG_VOID) SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV); #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) - + /* SGX defaults to D3 power state */ DisableSGXClocks(gpsSysData); -#endif +#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ #if !defined(PVR_NO_OMAP_TIMER) #if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) @@ -471,15 +546,27 @@ PVRSRV_ERROR SysInitialise(IMG_VOID) OSReservePhys(TimerRegPhysBase, 4, PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, + IMG_NULL, (IMG_VOID **)&gpsSysData->pvSOCTimerRegisterKM, &gpsSysData->hSOCTimerRegisterOSMemHandle); } -#endif +#endif /* !defined(PVR_NO_OMAP_TIMER) */ + return PVRSRV_OK; } +/*! +****************************************************************************** + + @Function SysFinalise + + @Description Final part of initialisation at 'driver load' time + + @Return PVRSRV_ERROR : + +******************************************************************************/ PVRSRV_ERROR SysFinalise(IMG_VOID) { PVRSRV_ERROR eError = PVRSRV_OK; @@ -491,7 +578,7 @@ PVRSRV_ERROR SysFinalise(IMG_VOID) PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to Enable SGX clocks (%d)", eError)); return eError; } -#endif +#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ eError = OSInstallMISR(gpsSysData); if (eError != PVRSRV_OK) @@ -502,7 +589,7 @@ PVRSRV_ERROR SysFinalise(IMG_VOID) SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR); #if defined(SYS_USING_INTERRUPTS) - + /* install a Device ISR */ eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); if (eError != PVRSRV_OK) { @@ -510,10 +597,12 @@ PVRSRV_ERROR SysFinalise(IMG_VOID) return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); -#endif - +#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + SysEnableSGXInterrupts(gpsSysData); +#endif +#endif /* defined(SYS_USING_INTERRUPTS) */ #if defined(__linux__) - + /* Create a human readable version string for this system */ gpsSysData->pszVersionString = SysCreateVersionString(); if (!gpsSysData->pszVersionString) { @@ -527,9 +616,9 @@ PVRSRV_ERROR SysFinalise(IMG_VOID) #endif #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) - + /* SGX defaults to D3 power state */ DisableSGXClocks(gpsSysData); -#endif +#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ gpsSysSpecificData->bSGXInitComplete = IMG_TRUE; @@ -537,10 +626,22 @@ PVRSRV_ERROR SysFinalise(IMG_VOID) } +/*! +****************************************************************************** + + @Function SysDeinitialise + + @Description De-initialises kernel services at 'driver unload' time + + @Return PVRSRV_ERROR + +******************************************************************************/ PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) { PVRSRV_ERROR eError; + PVR_UNREFERENCED_PARAMETER(psSysData); + if(gpsSysData->pvSOCTimerRegisterKM) { OSUnReservePhys(gpsSysData->pvSOCTimerRegisterKM, @@ -549,10 +650,11 @@ PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) gpsSysData->hSOCTimerRegisterOSMemHandle); } + #if defined(SYS_USING_INTERRUPTS) if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) { - eError = OSUninstallDeviceLISR(psSysData); + eError = OSUninstallDeviceLISR(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallDeviceLISR failed")); @@ -563,7 +665,7 @@ PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR)) { - eError = OSUninstallMISR(psSysData); + eError = OSUninstallMISR(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallMISR failed")); @@ -575,16 +677,16 @@ PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) { #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) PVR_ASSERT(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)); - + /* Reenable SGX clocks whilst SGX is being deinitialised. */ eError = EnableSGXClocksWrap(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: EnableSGXClocks failed")); return eError; } -#endif +#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ - + /* Deinitialise SGX */ eError = PVRSRVDeinitialiseDevice (gui32SGXDeviceID); if (eError != PVRSRV_OK) { @@ -593,6 +695,17 @@ PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) } } + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_DVFS_INIT)) + { + eError = SysDvfsDeinitialize(gpsSysSpecificData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: Failed to de-init DVFS")); + gpsSysData = IMG_NULL; + return eError; + } + } + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME)) { eError = SysPMRuntimeUnregister(); @@ -604,8 +717,9 @@ PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) } } - - + /* + Disable system clocks - must happen after last access to hardware. + */ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) { DisableSystemClocks(gpsSysData); @@ -627,7 +741,7 @@ PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) if(gsSGXRegsCPUVAddr != IMG_NULL) { #if defined(NO_HARDWARE) - + /* Free hardware resources. */ OSBaseFreeContigMemory(SYS_OMAP4430_SGX_REGS_SIZE, gsSGXRegsCPUVAddr, gsSGXDeviceMap.sRegsCpuPBase); #else #if defined(SGX_OCP_REGS_ENABLED) @@ -638,11 +752,11 @@ PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) gpvOCPRegsLinAddr = IMG_NULL; #endif -#endif +#endif /* defined(NO_HARDWARE) */ gsSGXRegsCPUVAddr = IMG_NULL; gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; } -#endif +#endif /* defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) */ gpsSysSpecificData->ui32SysSpecificData = 0; @@ -654,6 +768,19 @@ PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) } +/*! +****************************************************************************** + + @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) { @@ -662,7 +789,7 @@ PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType, { case PVRSRV_DEVICE_TYPE_SGX: { - + /* just return a pointer to the structure */ *ppvDeviceMap = (IMG_VOID*)&gsSGXDeviceMap; break; @@ -676,6 +803,20 @@ PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType, } +/*! +****************************************************************************** + @Function SysCpuPAddrToDevPAddr + + @Description Compute a device physical address from a cpu physical + address. Relevant when + + @Input cpu_paddr - cpu physical address. + @Input eDeviceType - device type required if DevPAddr + address spaces vary across devices + in the same system + @Return device physical address. + +******************************************************************************/ IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_CPU_PHYADDR CpuPAddr) { @@ -683,98 +824,205 @@ IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, PVR_UNREFERENCED_PARAMETER(eDeviceType); - + /* Note: for UMA system we assume DevP == CpuP */ DevPAddr.uiAddr = CpuPAddr.uiAddr; return DevPAddr; } +/*! +****************************************************************************** + @Function SysSysPAddrToCpuPAddr + + @Description Compute a cpu physical address from a system physical + address. + + @Input sys_paddr - system physical address. + @Return 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 + + @Description Compute a system physical address from a cpu physical + address. + + @Input cpu_paddr - cpu physical address. + @Return 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 + + @Description Compute a device physical address from a system physical + address. + + @Input SysPAddr - system physical address. + @Input eDeviceType - device type required if DevPAddr + address spaces vary across devices + in the same system + + @Return 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 UMA system we assume DevP == CpuP */ DevPAddr.uiAddr = SysPAddr.uiAddr; return DevPAddr; } +/*! +****************************************************************************** + @Function SysDevPAddrToSysPAddr + + @Description Compute a device physical address from a system physical + address. + + @Input DevPAddr - device physical address. + @Input eDeviceType - device type required if DevPAddr + address spaces vary across devices + in the same system + + @Return 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 UMA system we assume DevP == SysP */ SysPAddr.uiAddr = DevPAddr.uiAddr; return SysPAddr; } +/***************************************************************************** + @Function SysRegisterExternalDevice + + @Description Called when a 3rd party device registers with services + + @Input psDeviceNode - the new device node. + + @Return IMG_VOID +*****************************************************************************/ IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) { PVR_UNREFERENCED_PARAMETER(psDeviceNode); } +/***************************************************************************** + @Function SysRemoveExternalDevice + + @Description Called when a 3rd party device unregisters from services + + @Input psDeviceNode - the device node being removed. + + @Return IMG_VOID +*****************************************************************************/ IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) { PVR_UNREFERENCED_PARAMETER(psDeviceNode); } +/*! +****************************************************************************** + @Function SysGetInterruptSource + + @Description Returns System specific information about the device(s) that + generated the interrupt in the system + + @Input psSysData + @Input psDeviceNode + @Return System specific information indicating which device(s) + generated the interrupt + +******************************************************************************/ IMG_UINT32 SysGetInterruptSource(SYS_DATA *psSysData, PVRSRV_DEVICE_NODE *psDeviceNode) { PVR_UNREFERENCED_PARAMETER(psSysData); #if defined(NO_HARDWARE) - + /* no interrupts in no_hw system just return all bits */ return 0xFFFFFFFF; #else - + /* Not a shared irq, so we know this is an interrupt for this device */ return psDeviceNode->ui32SOCInterruptBit; #endif } +/*! +****************************************************************************** + @Function SysClearInterrupts + + @Description Clears specified system interrupts + + @Input psSysData + @Input ui32ClearBits + + @Return IMG_VOID + +******************************************************************************/ IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits) { PVR_UNREFERENCED_PARAMETER(ui32ClearBits); -#if defined(NO_HARDWARE) PVR_UNREFERENCED_PARAMETER(psSysData); -#else +#if !defined(NO_HARDWARE) #if defined(SGX_OCP_NO_INT_BYPASS) OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQSTATUS_2, 0x1); #endif - + /* Flush posted writes */ OSReadHWReg(((PVRSRV_SGXDEV_INFO *)gpsSGXDevNode->pvDevice)->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR); -#endif +#endif /* defined(NO_HARDWARE) */ } #if defined(SGX_OCP_NO_INT_BYPASS) +/*! +****************************************************************************** + @Function SysEnableSGXInterrupts + + @Description Enables SGX interrupts + + @Input psSysData + + @Return IMG_VOID + +******************************************************************************/ IMG_VOID SysEnableSGXInterrupts(SYS_DATA *psSysData) { SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData; @@ -786,6 +1034,17 @@ IMG_VOID SysEnableSGXInterrupts(SYS_DATA *psSysData) } } +/*! +****************************************************************************** + @Function SysDisableSGXInterrupts + + @Description Disables SGX interrupts + + @Input psSysData + + @Return IMG_VOID + +******************************************************************************/ IMG_VOID SysDisableSGXInterrupts(SYS_DATA *psSysData) { SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData; @@ -796,8 +1055,20 @@ IMG_VOID SysDisableSGXInterrupts(SYS_DATA *psSysData) SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED); } } -#endif +#endif /* defined(SGX_OCP_NO_INT_BYPASS) */ +/*! +****************************************************************************** + + @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) { PVRSRV_ERROR eError = PVRSRV_OK; @@ -842,6 +1113,18 @@ PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState) } +/*! +****************************************************************************** + + @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) { PVRSRV_ERROR eError = PVRSRV_OK; @@ -890,6 +1173,21 @@ PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState) } +/*! +****************************************************************************** + + @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) @@ -907,13 +1205,28 @@ PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex, PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePrePowerState: SGX Entering state D3")); DisableSGXClocks(gpsSysData); } -#else +#else /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ PVR_UNREFERENCED_PARAMETER(eNewPowerState ); -#endif +#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ 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) @@ -933,14 +1246,33 @@ PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex, PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePostPowerState: SGX Leaving state D3")); eError = EnableSGXClocksWrap(gpsSysData); } -#else +#else /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); -#endif +#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ return eError; } +#if defined(SYS_SUPPORTS_SGX_IDLE_CALLBACK) + +IMG_VOID SysSGXIdleTransition(IMG_BOOL bSGXIdle) +{ + PVR_DPF((PVR_DBG_MESSAGE, "SysSGXIdleTransition switch to %u", bSGXIdle)); +} + +#endif /* defined(SYS_SUPPORTS_SGX_IDLE_CALLBACK) */ + +/***************************************************************************** + @Function SysOEMFunction + + @Description marshalling function for custom OEM functions + + @Input ui32ID - function ID + @Input pvIn - in data + @Output pvOut - out data + @Return PVRSRV_ERROR +*****************************************************************************/ PVRSRV_ERROR SysOEMFunction ( IMG_UINT32 ui32ID, IMG_VOID *pvIn, IMG_UINT32 ulInSize, @@ -956,7 +1288,6 @@ PVRSRV_ERROR SysOEMFunction ( IMG_UINT32 ui32ID, 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; @@ -964,3 +1295,6 @@ PVRSRV_ERROR SysOEMFunction ( IMG_UINT32 ui32ID, return PVRSRV_ERROR_INVALID_PARAMS; } +/****************************************************************************** + End of file (sysconfig.c) +******************************************************************************/ diff --git a/sgx/services4/system/omap4/sysconfig.h b/sgx/services4/system/omap4/sysconfig.h index f094b9b..808562a 100644 --- a/sgx/services4/system/omap4/sysconfig.h +++ b/sgx/services4/system/omap4/sysconfig.h @@ -1,28 +1,45 @@ -/********************************************************************** - * - * 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 - * - ******************************************************************************/ +/*************************************************************************/ /*! +@Title System Description Header +@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved +@Description This header provides system-specific declarations and macros +@License Dual MIT/GPLv2 + +The contents of this file are subject to the MIT license as set out below. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Alternatively, the contents of this file may be used under the terms of +the GNU General Public License Version 2 ("GPL") in which case the provisions +of GPL are applicable instead of those above. + +If you wish to allow use of your version of this file only under the terms of +GPL, and not to allow others to use your version of this file under the terms +of the MIT license, indicate your decision by deleting the provisions above +and replace them with the notice and other provisions required by GPL as set +out in the file called "GPL-COPYING" included in this distribution. If you do +not delete the provisions above, a recipient may use your version of this file +under the terms of either the MIT license or GPL. + +This License is also included in this distribution in the file called +"MIT-COPYING". + +EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS +PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ /**************************************************************************/ #if !defined(__SOCCONFIG_H__) #define __SOCCONFIG_H__ @@ -35,27 +52,51 @@ #define SYS_SGX_CLOCK_SPEED 304742400 #endif -#define SYS_SGX_HWRECOVERY_TIMEOUT_FREQ (100) -#define SYS_SGX_PDS_TIMER_FREQ (1000) +#define SYS_SGX_HWRECOVERY_TIMEOUT_FREQ (100) // 10ms (100hz) +#define SYS_SGX_PDS_TIMER_FREQ (1000) // 1ms (1000hz) +/* Allow the AP latency to be overridden in the build config */ #if !defined(SYS_SGX_ACTIVE_POWER_LATENCY_MS) #define SYS_SGX_ACTIVE_POWER_LATENCY_MS (2) #endif #define SYS_OMAP4430_SGX_REGS_SYS_PHYS_BASE 0x56000000 - #define SYS_OMAP4430_SGX_REGS_SIZE 0xFFFF -#define SYS_OMAP4430_SGX_IRQ 53 +#define SYS_OMAP4430_SGX_IRQ 53 /* OMAP4 IRQ's are offset by 32 */ + +#define SYS_OMAP4430_DSS_REGS_SYS_PHYS_BASE 0x58000000 +#define SYS_OMAP4430_DSS_REGS_SIZE 0x7000 + +#define SYS_OMAP4430_DSS_HDMI_INTERRUPT_STATUS_REG 0x6028 +#define SYS_OMAP4430_DSS_HDMI_INTERRUPT_ENABLE_REG 0x602c + +#define SYS_OMAP4430_DSS_HDMI_INTERRUPT_VSYNC_ENABLE_MASK 0x10000 +#define SYS_OMAP4430_DSS_HDMI_INTERRUPT_VSYNC_STATUS_MASK 0x10000 + +#define SYS_OMAP4430_DSS_LCD_INTERRUPT_STATUS_REG 0x1018 +#define SYS_OMAP4430_DSS_LCD_INTERRUPT_ENABLE_REG 0x101c + +#define SYS_OMAP4430_DSS_LCD_INTERRUPT_VSYNC_ENABLE_MASK 0x40002 +#define SYS_OMAP4430_DSS_LCD_INTERRUPT_VSYNC_STATUS_MASK 0x40002 + #define SYS_OMAP4430_GP11TIMER_ENABLE_SYS_PHYS_BASE 0x48088038 #define SYS_OMAP4430_GP11TIMER_REGS_SYS_PHYS_BASE 0x4808803C #define SYS_OMAP4430_GP11TIMER_TSICR_SYS_PHYS_BASE 0x48088054 +/* Interrupt bits */ +#define DEVICE_SGX_INTERRUPT (1<<0) +#define DEVICE_MSVDX_INTERRUPT (1<<1) +#define DEVICE_DISP_INTERRUPT (1<<2) + #if defined(__linux__) #define SYS_SGX_DEV_NAME "omapdrm_pvr" #endif +/***************************************************************************** + * system specific data structures + *****************************************************************************/ -#endif +#endif /* __SYSCONFIG_H__ */ diff --git a/sgx/services4/system/omap4/sysinfo.h b/sgx/services4/system/omap4/sysinfo.h index b6d3f5a..4c9ac80 100644 --- a/sgx/services4/system/omap4/sysinfo.h +++ b/sgx/services4/system/omap4/sysinfo.h @@ -1,33 +1,57 @@ -/********************************************************************** - * - * 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 - * - ******************************************************************************/ +/*************************************************************************/ /*! +@Title System Description Header +@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved +@Description This header provides system-specific declarations and macros +@License Dual MIT/GPLv2 + +The contents of this file are subject to the MIT license as set out below. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Alternatively, the contents of this file may be used under the terms of +the GNU General Public License Version 2 ("GPL") in which case the provisions +of GPL are applicable instead of those above. + +If you wish to allow use of your version of this file only under the terms of +GPL, and not to allow others to use your version of this file under the terms +of the MIT license, indicate your decision by deleting the provisions above +and replace them with the notice and other provisions required by GPL as set +out in the file called "GPL-COPYING" included in this distribution. If you do +not delete the provisions above, a recipient may use your version of this file +under the terms of either the MIT license or GPL. + +This License is also included in this distribution in the file called +"MIT-COPYING". + +EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS +PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ /**************************************************************************/ #if !defined(__SYSINFO_H__) #define __SYSINFO_H__ +/*!< System specific poll/timeout details */ #if defined(PVR_LINUX_USING_WORKQUEUES) +/* + * The workqueue based 3rd party display driver may be blocked for up + * to 500ms waiting for a vsync when the screen goes blank, so we + * need to wait longer for the hardware if a flush of the swap chain is + * required. + */ #define MAX_HW_TIME_US (1000000) #define WAIT_TRY_COUNT (20000) #else @@ -36,6 +60,6 @@ #endif -#define SYS_DEVICE_COUNT 15 +#define SYS_DEVICE_COUNT 15 /* SGX, DISPLAYCLASS (external), BUFFERCLASS (external) */ -#endif +#endif /* __SYSINFO_H__ */ diff --git a/sgx/services4/system/omap4/syslocal.h b/sgx/services4/system/omap4/syslocal.h index d30a616..c88ad14 100644 --- a/sgx/services4/system/omap4/syslocal.h +++ b/sgx/services4/system/omap4/syslocal.h @@ -1,28 +1,45 @@ -/********************************************************************** - * - * 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 - * - ******************************************************************************/ +/*************************************************************************/ /*! +@Title Local system definitions +@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved +@Description This header provides local system declarations and macros +@License Dual MIT/GPLv2 + +The contents of this file are subject to the MIT license as set out below. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Alternatively, the contents of this file may be used under the terms of +the GNU General Public License Version 2 ("GPL") in which case the provisions +of GPL are applicable instead of those above. + +If you wish to allow use of your version of this file only under the terms of +GPL, and not to allow others to use your version of this file under the terms +of the MIT license, indicate your decision by deleting the provisions above +and replace them with the notice and other provisions required by GPL as set +out in the file called "GPL-COPYING" included in this distribution. If you do +not delete the provisions above, a recipient may use your version of this file +under the terms of either the MIT license or GPL. + +This License is also included in this distribution in the file called +"MIT-COPYING". + +EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS +PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ /**************************************************************************/ #if !defined(__SYSLOCAL_H__) #define __SYSLOCAL_H__ @@ -41,12 +58,12 @@ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) #include <linux/semaphore.h> #include <linux/resource.h> -#else +#else /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) */ #include <asm/semaphore.h> #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) #include <asm/arch/resource.h> -#endif -#endif +#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) */ +#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) @@ -60,6 +77,10 @@ #if ((defined(DEBUG) || defined(TIMING)) && \ (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,34))) && \ !defined(PVR_NO_OMAP_TIMER) +/* + * We need to explicitly enable the GPTIMER11 clocks, or we'll get an + * abort when we try to access the timer registers. + */ #define PVR_OMAP4_TIMING_PRCM #endif @@ -74,28 +95,35 @@ #if !defined(PVR_NO_OMAP_TIMER) #define PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA #endif -#endif +#endif /* defined(__linux__) */ #if !defined(NO_HARDWARE) && \ - defined(SYS_USING_INTERRUPTS) && \ - defined(SGX540) + defined(SYS_USING_INTERRUPTS) #define SGX_OCP_REGS_ENABLED #endif #if 0 /* need to avoid defining SGX_OCP_NO_INT_BYPASS otherwise we get not irqs */ #if defined(__linux__) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) && defined(SGX_OCP_REGS_ENABLED) +/* FIXME: Temporary workaround for OMAP4470 */ +#if !defined(SGX544) #define SGX_OCP_NO_INT_BYPASS #endif #endif #endif - +#endif #if defined (__cplusplus) extern "C" { #endif +/***************************************************************************** + * system specific data structures + *****************************************************************************/ +/***************************************************************************** + * system specific function prototypes + *****************************************************************************/ IMG_VOID DisableSystemClocks(SYS_DATA *psSysData); PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData); @@ -103,6 +131,10 @@ PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData); IMG_VOID DisableSGXClocks(SYS_DATA *psSysData); PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData); +/* + * Various flags to indicate what has been initialised, and what + * has been temporarily deinitialised for power management purposes. + */ #define SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS 0x00000001 #define SYS_SPECIFIC_DATA_ENABLE_LISR 0x00000002 #define SYS_SPECIFIC_DATA_ENABLE_MISR 0x00000004 @@ -117,9 +149,8 @@ PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData); #define SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS 0x00000400 #define SYS_SPECIFIC_DATA_ENABLE_OCPREGS 0x00000800 #define SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME 0x00001000 -#if defined(SGX_OCP_REGS_ENABLED) && defined(SGX_OCP_NO_INT_BYPASS) #define SYS_SPECIFIC_DATA_IRQ_ENABLED 0x00002000 -#endif +#define SYS_SPECIFIC_DATA_DVFS_INIT 0x00004000 #define SYS_SPECIFIC_DATA_SET(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData |= (flag))) @@ -159,7 +190,10 @@ typedef struct _SYS_SPECIFIC_DATA_TAG_ #if defined(PVR_OMAP_USE_DM_TIMER_API) struct omap_dm_timer *psGPTimer; #endif -#endif + IMG_UINT32 ui32SGXFreqListSize; + IMG_UINT32 *pui32SGXFreqList; + IMG_UINT32 ui32SGXFreqListIndex; +#endif /* defined(__linux__) */ } SYS_SPECIFIC_DATA; extern SYS_SPECIFIC_DATA *gpsSysSpecificData; @@ -182,7 +216,10 @@ IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData); PVRSRV_ERROR SysPMRuntimeRegister(void); PVRSRV_ERROR SysPMRuntimeUnregister(void); -#else +PVRSRV_ERROR SysDvfsInitialize(SYS_SPECIFIC_DATA *psSysSpecificData); +PVRSRV_ERROR SysDvfsDeinitialize(SYS_SPECIFIC_DATA *psSysSpecificData); + +#else /* defined(__linux__) */ #ifdef INLINE_IS_PRAGMA #pragma inline(SysPMRuntimeRegister) @@ -200,12 +237,28 @@ static INLINE PVRSRV_ERROR SysPMRuntimeUnregister(void) return PVRSRV_OK; } -#endif +#ifdef INLINE_IS_PRAGMA +#pragma inline(SysDvfsInitialize) +#endif +static INLINE PVRSRV_ERROR SysDvfsInitialize(void) +{ + return PVRSRV_OK; +} + +#ifdef INLINE_IS_PRAGMA +#pragma inline(SysDvfsDeinitialize) +#endif +static INLINE PVRSRV_ERROR SysDvfsDeinitialize(void) +{ + return PVRSRV_OK; +} + +#endif /* defined(__linux__) */ #if defined(__cplusplus) } #endif -#endif +#endif /* __SYSLOCAL_H__ */ diff --git a/sgx/services4/system/omap4/sysutils.c b/sgx/services4/system/omap4/sysutils.c index 8736fcc..eeb06e7 100644 --- a/sgx/services4/system/omap4/sysutils.c +++ b/sgx/services4/system/omap4/sysutils.c @@ -1,30 +1,50 @@ -/********************************************************************** - * - * 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 - * - ******************************************************************************/ +/*************************************************************************/ /*! +@Title Shared (User/kernel) and System dependent utilities +@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved +@Description Provides system-specific functions +@License Dual MIT/GPLv2 + +The contents of this file are subject to the MIT license as set out below. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Alternatively, the contents of this file may be used under the terms of +the GNU General Public License Version 2 ("GPL") in which case the provisions +of GPL are applicable instead of those above. + +If you wish to allow use of your version of this file only under the terms of +GPL, and not to allow others to use your version of this file under the terms +of the MIT license, indicate your decision by deleting the provisions above +and replace them with the notice and other provisions required by GPL as set +out in the file called "GPL-COPYING" included in this distribution. If you do +not delete the provisions above, a recipient may use your version of this file +under the terms of either the MIT license or GPL. + +This License is also included in this distribution in the file called +"MIT-COPYING". + +EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS +PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ /**************************************************************************/ + +/* Pull in the correct system dependent sysutils source */ #if defined(__linux__) #include "sysutils_linux.c" #endif + diff --git a/sgx/services4/system/omap4/sysutils_linux.c b/sgx/services4/system/omap4/sysutils_linux.c index 84ac221..8d0d958 100644 --- a/sgx/services4/system/omap4/sysutils_linux.c +++ b/sgx/services4/system/omap4/sysutils_linux.c @@ -1,34 +1,51 @@ -/********************************************************************** - * - * 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 - * - ******************************************************************************/ - +/*************************************************************************/ /*! +@Title System dependent utilities +@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved +@Description Provides system-specific functions +@License Dual MIT/GPLv2 + +The contents of this file are subject to the MIT license as set out below. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Alternatively, the contents of this file may be used under the terms of +the GNU General Public License Version 2 ("GPL") in which case the provisions +of GPL are applicable instead of those above. + +If you wish to allow use of your version of this file only under the terms of +GPL, and not to allow others to use your version of this file under the terms +of the MIT license, indicate your decision by deleting the provisions above +and replace them with the notice and other provisions required by GPL as set +out in the file called "GPL-COPYING" included in this distribution. If you do +not delete the provisions above, a recipient may use your version of this file +under the terms of either the MIT license or GPL. + +This License is also included in this distribution in the file called +"MIT-COPYING". + +EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS +PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ /**************************************************************************/ #include <linux/version.h> #include <linux/clk.h> #include <linux/err.h> #include <linux/hardirq.h> #include <linux/mutex.h> +#include <linux/slab.h> #include "sgxdefs.h" #include "services_headers.h" @@ -42,6 +59,19 @@ #include <linux/pm_runtime.h> #include <plat/omap_device.h> +#if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) +#include <linux/opp.h> +#endif + +#if defined(SUPPORT_DRI_DRM_PLUGIN) +#include <drm/drmP.h> +#include <drm/drm.h> + +#include <linux/omap_gpu.h> + +#include "pvr_drm.h" +#endif + #define ONE_MHZ 1000000 #define HZ_TO_MHZ(m) ((m) / ONE_MHZ) @@ -102,6 +132,15 @@ IMG_VOID SysPowerLockUnwrap(IMG_VOID) PowerLockUnwrap(psSysData->pvSysSpecificData); } +/* + * This function should be called to unwrap the Services power lock, prior + * to calling any function that might sleep. + * This function shouldn't be called prior to calling EnableSystemClocks + * or DisableSystemClocks, as those functions perform their own power lock + * unwrapping. + * If the function returns IMG_TRUE, UnwrapSystemPowerChange must be + * called to rewrap the power lock, prior to returning to Services. + */ IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) { return IMG_TRUE; @@ -111,51 +150,46 @@ IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) { } -static inline IMG_UINT32 scale_by_rate(IMG_UINT32 val, IMG_UINT32 rate1, IMG_UINT32 rate2) -{ - if (rate1 >= rate2) - { - return val * (rate1 / rate2); - } - - return val / (rate2 / rate1); -} - -static inline IMG_UINT32 scale_prop_to_SGX_clock(IMG_UINT32 val, IMG_UINT32 rate) -{ - return scale_by_rate(val, rate, SYS_SGX_CLOCK_SPEED); -} - -static inline IMG_UINT32 scale_inv_prop_to_SGX_clock(IMG_UINT32 val, IMG_UINT32 rate) -{ - return scale_by_rate(val, SYS_SGX_CLOCK_SPEED, rate); -} - +/* + * Return SGX timining information to caller. + */ IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psTimingInfo) { - IMG_UINT32 rate; - - rate = SYS_SGX_CLOCK_SPEED; #if !defined(NO_HARDWARE) PVR_ASSERT(atomic_read(&gpsSysSpecificData->sSGXClocksEnabled) != 0); #endif - psTimingInfo->ui32CoreClockSpeed = rate; - psTimingInfo->ui32HWRecoveryFreq = scale_prop_to_SGX_clock(SYS_SGX_HWRECOVERY_TIMEOUT_FREQ, rate); - psTimingInfo->ui32uKernelFreq = scale_prop_to_SGX_clock(SYS_SGX_PDS_TIMER_FREQ, rate); +#if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) + psTimingInfo->ui32CoreClockSpeed = + gpsSysSpecificData->pui32SGXFreqList[gpsSysSpecificData->ui32SGXFreqListIndex]; +#else /* defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) */ + psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; +#endif + psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; + psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) psTimingInfo->bEnableActivePM = IMG_TRUE; #else psTimingInfo->bEnableActivePM = IMG_FALSE; -#endif +#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; } +/*! +****************************************************************************** + + @Function EnableSGXClocks + + @Description Enable SGX clocks + + @Return PVRSRV_ERROR + +******************************************************************************/ PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData) { #if !defined(NO_HARDWARE) SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; - + /* SGX clocks already enabled? */ if (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0) { return PVRSRV_OK; @@ -164,7 +198,49 @@ PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData) PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: Enabling SGX Clocks")); #if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) +#if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) { + struct gpu_platform_data *pdata; + IMG_UINT32 max_freq_index; + int res; + + pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data; + max_freq_index = psSysSpecData->ui32SGXFreqListSize - 2; + + /* + * Request maximum frequency from DVFS layer if not already set. DVFS may + * report busy if early in initialization, but all other errors are + * considered serious. Upon any error we proceed assuming our safe frequency + * value to be in use as indicated by the "unknown" index. + */ + if (psSysSpecData->ui32SGXFreqListIndex != max_freq_index) + { + PVR_ASSERT(pdata->device_scale != IMG_NULL); + res = pdata->device_scale(&gpsPVRLDMDev->dev, + &gpsPVRLDMDev->dev, + psSysSpecData->pui32SGXFreqList[max_freq_index]); + if (res == 0) + { + psSysSpecData->ui32SGXFreqListIndex = max_freq_index; + } + else if (res == -EBUSY) + { + PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: Unable to scale SGX frequency (EBUSY)")); + psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; + } + else if (res < 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Unable to scale SGX frequency (%d)", res)); + psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; + } + } + } +#endif /* defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) */ + { + /* + * pm_runtime_get_sync returns 1 after the module has + * been reloaded. + */ int res = pm_runtime_get_sync(&gpsPVRLDMDev->dev); if (res < 0) { @@ -172,26 +248,37 @@ PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData) return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK; } } -#endif +#endif /* defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) */ + SysEnableSGXInterrupts(psSysData); - + /* Indicate that the SGX clocks are enabled */ atomic_set(&psSysSpecData->sSGXClocksEnabled, 1); -#else +#else /* !defined(NO_HARDWARE) */ PVR_UNREFERENCED_PARAMETER(psSysData); -#endif +#endif /* !defined(NO_HARDWARE) */ return PVRSRV_OK; } +/*! +****************************************************************************** + + @Function DisableSGXClocks + + @Description Disable SGX clocks. + + @Return none + +******************************************************************************/ IMG_VOID DisableSGXClocks(SYS_DATA *psSysData) { #if 0 #if !defined(NO_HARDWARE) SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; - + /* SGX clocks already disabled? */ if (atomic_read(&psSysSpecData->sSGXClocksEnabled) == 0) { return; @@ -209,25 +296,76 @@ IMG_VOID DisableSGXClocks(SYS_DATA *psSysData) PVR_DPF((PVR_DBG_ERROR, "DisableSGXClocks: pm_runtime_put_sync failed (%d)", -res)); } } -#endif +#if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) + { + struct gpu_platform_data *pdata; + int res; - + pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data; + + /* + * Request minimum frequency (list index 0) from DVFS layer if not already + * set. DVFS may report busy if early in initialization, but all other errors + * are considered serious. Upon any error we proceed assuming our safe frequency + * value to be in use as indicated by the "unknown" index. + */ + if (psSysSpecData->ui32SGXFreqListIndex != 0) + { + PVR_ASSERT(pdata->device_scale != IMG_NULL); + res = pdata->device_scale(&gpsPVRLDMDev->dev, + &gpsPVRLDMDev->dev, + psSysSpecData->pui32SGXFreqList[0]); + if (res == 0) + { + psSysSpecData->ui32SGXFreqListIndex = 0; + } + else if (res == -EBUSY) + { + PVR_DPF((PVR_DBG_WARNING, "DisableSGXClocks: Unable to scale SGX frequency (EBUSY)")); + psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; + } + else if (res < 0) + { + PVR_DPF((PVR_DBG_ERROR, "DisableSGXClocks: Unable to scale SGX frequency (%d)", res)); + psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; + } + } + } +#endif /* defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) */ +#endif /* defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) */ + + /* Indicate that the SGX clocks are disabled */ atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); -#else +#else /* !defined(NO_HARDWARE) */ PVR_UNREFERENCED_PARAMETER(psSysData); -#endif +#endif /* !defined(NO_HARDWARE) */ #endif } #if (defined(DEBUG) || defined(TIMING)) && !defined(PVR_NO_OMAP_TIMER) #if defined(PVR_OMAP_USE_DM_TIMER_API) #define GPTIMER_TO_USE 11 +/*! +****************************************************************************** + + @Function AcquireGPTimer + + @Description Acquire a GP timer + + @Return PVRSRV_ERROR + +******************************************************************************/ static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) { PVR_ASSERT(psSysSpecData->psGPTimer == NULL); - + /* + * This code could try requesting registers 9, 10, and 11, + * stopping at the first succesful request. We'll stick with + * 11 for now, as it avoids having to hard code yet more + * physical addresses into the code. + */ psSysSpecData->psGPTimer = omap_dm_timer_request_specific(GPTIMER_TO_USE); if (psSysSpecData->psGPTimer == NULL) { @@ -236,26 +374,39 @@ static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) return PVRSRV_ERROR_CLOCK_REQUEST_FAILED; } - + /* Set timer source to system clock */ omap_dm_timer_set_source(psSysSpecData->psGPTimer, OMAP_TIMER_SRC_SYS_CLK); omap_dm_timer_enable(psSysSpecData->psGPTimer); - + /* Set autoreload, and start value of 0 */ omap_dm_timer_set_load_start(psSysSpecData->psGPTimer, 1, 0); omap_dm_timer_start(psSysSpecData->psGPTimer); - + /* + * The DM timer API doesn't have a mechansim for obtaining the + * physical address of the counter register. + */ psSysSpecData->sTimerRegPhysBase.uiAddr = SYS_OMAP4430_GP11TIMER_REGS_SYS_PHYS_BASE; return PVRSRV_OK; } +/*! +****************************************************************************** + + @Function ReleaseGPTimer + + @Description Release a GP timer + + @Return PVRSRV_ERROR + +******************************************************************************/ static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) { if (psSysSpecData->psGPTimer != NULL) { - + /* Always returns 0 */ (void) omap_dm_timer_stop(psSysSpecData->psGPTimer); omap_dm_timer_disable(psSysSpecData->psGPTimer); @@ -268,7 +419,17 @@ static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) } } -#else +#else /* PVR_OMAP_USE_DM_TIMER_API */ +/*! +****************************************************************************** + + @Function AcquireGPTimer + + @Description Acquire a GP timer + + @Return PVRSRV_ERROR + +******************************************************************************/ static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) { #if defined(PVR_OMAP4_TIMING_PRCM) @@ -286,7 +447,7 @@ static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) PVR_ASSERT(psSysSpecData->sTimerRegPhysBase.uiAddr == 0); #if defined(PVR_OMAP4_TIMING_PRCM) - + /* assert our dependence on the GPTIMER11 module */ psCLK = clk_get(NULL, "gpt11_fck"); if (IS_ERR(psCLK)) { @@ -337,9 +498,9 @@ static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 interface clock (%d)", res)); goto ExitDisableGPT11FCK; } -#endif +#endif /* defined(PVR_OMAP4_TIMING_PRCM) */ - + /* Set the timer to non-posted mode */ sTimerRegPhysBase.uiAddr = SYS_OMAP4430_GP11TIMER_TSICR_SYS_PHYS_BASE; pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase, 4, @@ -356,7 +517,7 @@ static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) { PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)")); - + /* Set posted mode */ *pui32TimerEnable |= 4; } @@ -365,7 +526,7 @@ static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, hTimerEnable); - + /* Enable the timer */ sTimerRegPhysBase.uiAddr = SYS_OMAP4430_GP11TIMER_ENABLE_SYS_PHYS_BASE; pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase, 4, @@ -378,7 +539,7 @@ static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) goto ExitDisableGPT11ICK; } - + /* Enable and set autoreload on overflow */ *pui32TimerEnable = 3; OSUnMapPhysToLin(pui32TimerEnable, @@ -398,12 +559,22 @@ ExitDisableGPT11ICK: ExitDisableGPT11FCK: clk_disable(psSysSpecData->psGPT11_FCK); ExitError: -#endif +#endif /* defined(PVR_OMAP4_TIMING_PRCM) */ eError = PVRSRV_ERROR_CLOCK_REQUEST_FAILED; Exit: return eError; } +/*! +****************************************************************************** + + @Function ReleaseGPTimer + + @Description Release a GP timer + + @Return PVRSRV_ERROR + +******************************************************************************/ static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) { IMG_HANDLE hTimerDisable; @@ -414,7 +585,7 @@ static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) return; } - + /* Disable the timer */ pui32TimerDisable = OSMapPhysToLin(psSysSpecData->sTimerRegPhysBase, 4, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, @@ -440,10 +611,10 @@ static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) clk_disable(psSysSpecData->psGPT11_ICK); clk_disable(psSysSpecData->psGPT11_FCK); -#endif +#endif /* defined(PVR_OMAP4_TIMING_PRCM) */ } -#endif -#else +#endif /* PVR_OMAP_USE_DM_TIMER_API */ +#else /* (DEBUG || TIMING) && !PVR_NO_OMAP_TIMER */ static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) { PVR_UNREFERENCED_PARAMETER(psSysSpecData); @@ -454,8 +625,18 @@ static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) { PVR_UNREFERENCED_PARAMETER(psSysSpecData); } -#endif +#endif /* (DEBUG || TIMING) && !PVR_NO_OMAP_TIMER */ + +/*! +****************************************************************************** + + @Function EnableSystemClocks + @Description Setup up the clocks for the graphics device to work. + + @Return PVRSRV_ERROR + +******************************************************************************/ PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData) { SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; @@ -502,13 +683,27 @@ PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData) return AcquireGPTimer(psSysSpecData); } +/*! +****************************************************************************** + + @Function DisableSystemClocks + + @Description Disable the graphics clocks. + + @Return none + +******************************************************************************/ IMG_VOID DisableSystemClocks(SYS_DATA *psSysData) { SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; PVR_TRACE(("DisableSystemClocks: Disabling System Clocks")); - + /* + * Always disable the SGX clocks when the system clocks are disabled. + * This saves having to make an explicit call to DisableSGXClocks if + * active power management is enabled. + */ DisableSGXClocks(psSysData); ReleaseGPTimer(psSysSpecData); @@ -529,3 +724,158 @@ PVRSRV_ERROR SysPMRuntimeUnregister(void) #endif return PVRSRV_OK; } + +PVRSRV_ERROR SysDvfsInitialize(SYS_SPECIFIC_DATA *psSysSpecificData) +{ +#if !defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) + PVR_UNREFERENCED_PARAMETER(psSysSpecificData); +#else /* !defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) */ + IMG_UINT32 i, *freq_list; + IMG_INT32 opp_count; + unsigned long freq; + struct opp *opp; + + /* + * We query and store the list of SGX frequencies just this once under the + * assumption that they are unchanging, e.g. no disabling of high frequency + * option for thermal management. This is currently valid for 4430 and 4460. + */ + rcu_read_lock(); + opp_count = opp_get_opp_count(&gpsPVRLDMDev->dev); + if (opp_count < 1) + { + rcu_read_unlock(); + PVR_DPF((PVR_DBG_ERROR, "SysDvfsInitialize: Could not retrieve opp count")); + return PVRSRV_ERROR_NOT_SUPPORTED; + } + + /* + * Allocate the frequency list with a slot for each available frequency plus + * one additional slot to hold a designated frequency value to assume when in + * an unknown frequency state. + */ + freq_list = kmalloc((opp_count + 1) * sizeof(IMG_UINT32), GFP_ATOMIC); + if (!freq_list) + { + rcu_read_unlock(); + PVR_DPF((PVR_DBG_ERROR, "SysDvfsInitialize: Could not allocate frequency list")); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + /* + * Fill in frequency list from lowest to highest then finally the "unknown" + * frequency value. We use the highest available frequency as our assumed value + * when in an unknown state, because it is safer for APM and hardware recovery + * timers to be longer than intended rather than shorter. + */ + freq = 0; + for (i = 0; i < opp_count; i++) + { + opp = opp_find_freq_ceil(&gpsPVRLDMDev->dev, &freq); + if (IS_ERR_OR_NULL(opp)) + { + rcu_read_unlock(); + PVR_DPF((PVR_DBG_ERROR, "SysDvfsInitialize: Could not retrieve opp level %d", i)); + kfree(freq_list); + return PVRSRV_ERROR_NOT_SUPPORTED; + } + freq_list[i] = (IMG_UINT32)freq; + freq++; + } + rcu_read_unlock(); + freq_list[opp_count] = freq_list[opp_count - 1]; + + psSysSpecificData->ui32SGXFreqListSize = opp_count + 1; + psSysSpecificData->pui32SGXFreqList = freq_list; + + /* Start in unknown state - no frequency request to DVFS yet made */ + psSysSpecificData->ui32SGXFreqListIndex = opp_count; +#endif /* !defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) */ + + return PVRSRV_OK; +} + +PVRSRV_ERROR SysDvfsDeinitialize(SYS_SPECIFIC_DATA *psSysSpecificData) +{ +#if !defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) + PVR_UNREFERENCED_PARAMETER(psSysSpecificData); +#else /* !defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) */ + /* + * We assume this function is only called if SysDvfsInitialize() was + * completed successfully before. + * + * The DVFS interface does not allow us to actually unregister as a + * user of SGX, so we do the next best thing which is to lower our + * required frequency to the minimum if not already set. DVFS may + * report busy if early in initialization, but all other errors are + * considered serious. + */ + if (psSysSpecificData->ui32SGXFreqListIndex != 0) + { + struct gpu_platform_data *pdata; + IMG_INT32 res; + + pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data; + + PVR_ASSERT(pdata->device_scale != IMG_NULL); + res = pdata->device_scale(&gpsPVRLDMDev->dev, + &gpsPVRLDMDev->dev, + psSysSpecificData->pui32SGXFreqList[0]); + if (res == -EBUSY) + { + PVR_DPF((PVR_DBG_WARNING, "SysDvfsDeinitialize: Unable to scale SGX frequency (EBUSY)")); + } + else if (res < 0) + { + PVR_DPF((PVR_DBG_ERROR, "SysDvfsDeinitialize: Unable to scale SGX frequency (%d)", res)); + } + + psSysSpecificData->ui32SGXFreqListIndex = 0; + } + + kfree(psSysSpecificData->pui32SGXFreqList); + psSysSpecificData->pui32SGXFreqList = 0; + psSysSpecificData->ui32SGXFreqListSize = 0; +#endif /* !defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) */ + + return PVRSRV_OK; +} + +#if defined(SUPPORT_DRI_DRM_PLUGIN) +static struct omap_gpu_plugin sOMAPGPUPlugin; + +#define SYS_DRM_SET_PLUGIN_FIELD(d, s, f) (d)->f = (s)->f +int +SysDRMRegisterPlugin(PVRSRV_DRM_PLUGIN *psDRMPlugin) +{ + int iRes; + + SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, name); + SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, open); + SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, load); + SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, unload); + SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, release); + SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, mmap); + SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, ioctls); + SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, num_ioctls); + SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, ioctl_start); + + iRes = omap_gpu_register_plugin(&sOMAPGPUPlugin); + if (iRes != 0) + { + PVR_DPF((PVR_DBG_ERROR, "%s: omap_gpu_register_plugin failed (%d)", __FUNCTION__, iRes)); + } + + return iRes; +} + +void +SysDRMUnregisterPlugin(PVRSRV_DRM_PLUGIN *psDRMPlugin) +{ + int iRes = omap_gpu_unregister_plugin(&sOMAPGPUPlugin); + if (iRes != 0) + { + PVR_DPF((PVR_DBG_ERROR, "%s: omap_gpu_unregister_plugin failed (%d)", __FUNCTION__, iRes)); + } +} +#endif |