summaryrefslogtreecommitdiff
path: root/sgx/services4/system/omap4
diff options
context:
space:
mode:
authorRicardo Salveti de Araujo <ricardo.salveti@linaro.org>2012-07-18 00:30:31 -0300
committerRicardo Salveti de Araujo <ricardo.salveti@linaro.org>2012-07-18 00:30:31 -0300
commit0f9b9d9e1f16d454b12921d3429eced6dc1095d4 (patch)
tree21eaffbd85393a9e53889bbd868a255c7f6c24fc /sgx/services4/system/omap4
parent50fa520ba5f68fa76173493c44715d4542007120 (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.h77
-rw-r--r--sgx/services4/system/omap4/sysconfig.c552
-rw-r--r--sgx/services4/system/omap4/sysconfig.h101
-rw-r--r--sgx/services4/system/omap4/sysinfo.h78
-rw-r--r--sgx/services4/system/omap4/syslocal.h129
-rw-r--r--sgx/services4/system/omap4/sysutils.c70
-rw-r--r--sgx/services4/system/omap4/sysutils_linux.c514
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