summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorseonkon.choi <seonkon.choi@ti.com>2011-05-31 09:25:17 +0100
committerAndy Green <andy.green@linaro.org>2011-05-31 11:06:51 +0100
commit282ecd7d0d856e0f6062d8678551c04c2eb4ae55 (patch)
tree0d27fc0e3206670389119a0e595abc585f550dcb
parent7e0942c87b248c3d2102becf6726cf7b8f7dfd6d (diff)
OMAP3: SGX-KM: Modified for DDK 1.7.17.4403
support dmtimer, pm_runtime and resources of I/O and IRQ on OMAP3. based on Id3a713fa22a227dbcd0ec098589d62b350802247. Change-Id: Ib16a7029d2462a819ed7e45f8ca0d62b8e10b7b8 Signed-off-by: seonkon.choi <seonkon.choi@ti.com>
-rw-r--r--drivers/gpu/pvr/omap3/sysconfig.c237
-rw-r--r--drivers/gpu/pvr/omap3/sysconfig.h11
-rw-r--r--drivers/gpu/pvr/omap3/syslocal.h88
-rw-r--r--drivers/gpu/pvr/omap3/sysutils_linux_wqueue_compat.c367
4 files changed, 463 insertions, 240 deletions
diff --git a/drivers/gpu/pvr/omap3/sysconfig.c b/drivers/gpu/pvr/omap3/sysconfig.c
index d5036613ce3..e107e327ddf 100644
--- a/drivers/gpu/pvr/omap3/sysconfig.c
+++ b/drivers/gpu/pvr/omap3/sysconfig.c
@@ -24,24 +24,22 @@
*
******************************************************************************/
+#include "sysconfig.h"
#include "services_headers.h"
#include "kerneldisplay.h"
#include "oemfuncs.h"
#include "sgxinfo.h"
#include "sgxinfokm.h"
#include "syslocal.h"
-#include "sysconfig.h"
#include "ocpdefs.h"
-#if !defined(NO_HARDWARE) && \
- defined(SYS_USING_INTERRUPTS) && \
- defined(SGX530) && (SGX_CORE_REV == 125)
-#define SGX_OCP_REGS_ENABLED
+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI)
+#include <plat/omap_device.h>
#endif
SYS_DATA* gpsSysData = (SYS_DATA*)IMG_NULL;
-SYS_DATA gsSysData;
+static SYS_DATA gsSysData;
static SYS_SPECIFIC_DATA gsSysSpecificData;
SYS_SPECIFIC_DATA *gpsSysSpecificData;
@@ -52,10 +50,14 @@ static PVRSRV_DEVICE_NODE *gpsSGXDevNode;
#define DEVICE_SGX_INTERRUPT (1 << 0)
-#if defined(NO_HARDWARE)
+#if defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED)
static IMG_CPU_VIRTADDR gsSGXRegsCPUVAddr;
#endif
+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI)
+extern struct platform_device *gpsPVRLDMDev;
+#endif
+
IMG_UINT32 PVRSRV_BridgeDispatchKM(IMG_UINT32 Ioctl,
IMG_BYTE *pInBuf,
IMG_UINT32 InBufLen,
@@ -156,22 +158,18 @@ static INLINE void dump_omap34xx_clocks(void) {}
#if defined(SGX_OCP_REGS_ENABLED)
-#define SYS_OMAP3430_OCP_REGS_SYS_PHYS_BASE (SYS_OMAP3430_SGX_REGS_SYS_PHYS_BASE + EUR_CR_OCP_REVISION)
-#define SYS_OMAP3430_OCP_REGS_SIZE 0x110
-
static IMG_CPU_VIRTADDR gpvOCPRegsLinAddr;
static PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData)
{
PVRSRV_ERROR eError = EnableSGXClocks(psSysData);
+#if !defined(SGX_OCP_NO_INT_BYPASS)
if(eError == PVRSRV_OK)
{
- OSWriteHWReg(gpvOCPRegsLinAddr,
- EUR_CR_OCP_DEBUG_CONFIG - EUR_CR_OCP_REVISION,
- EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_MASK);
+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_DEBUG_CONFIG, EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_MASK);
}
-
+#endif
return eError;
}
@@ -188,13 +186,15 @@ static INLINE PVRSRV_ERROR EnableSystemClocksWrap(SYS_DATA *psSysData)
{
PVRSRV_ERROR eError = EnableSystemClocks(psSysData);
-#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
if(eError == PVRSRV_OK)
{
- EnableSGXClocksWrap(psSysData);
+ eError = EnableSGXClocksWrap(psSysData);
+ if (eError != PVRSRV_OK)
+ {
+ DisableSystemClocks(psSysData);
+ }
}
-#endif
return eError;
}
@@ -204,6 +204,11 @@ static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData)
#if defined(NO_HARDWARE)
PVRSRV_ERROR eError;
IMG_CPU_PHYADDR sCpuPAddr;
+#else
+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO)
+ struct resource *dev_res;
+ int dev_irq;
+#endif
#endif
PVR_UNREFERENCED_PARAMETER(psSysData);
@@ -214,7 +219,9 @@ static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData)
#if defined(NO_HARDWARE)
- eError = OSBaseAllocContigMemory(SYS_OMAP3430_SGX_REGS_SIZE,
+ gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE;
+
+ eError = OSBaseAllocContigMemory(gsSGXDeviceMap.ui32RegsSize,
&gsSGXRegsCPUVAddr,
&sCpuPAddr);
if(eError != PVRSRV_OK)
@@ -223,7 +230,6 @@ static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData)
}
gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr;
gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase);
- gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE;
#if defined(__linux__)
gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr;
@@ -232,7 +238,7 @@ static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData)
gsSGXDeviceMap.pvRegsCpuVBase = IMG_NULL;
#endif
- OSMemSet(gsSGXRegsCPUVAddr, 0, SYS_OMAP3430_SGX_REGS_SIZE);
+ OSMemSet(gsSGXRegsCPUVAddr, 0, gsSGXDeviceMap.ui32RegsSize);
@@ -240,7 +246,33 @@ static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData)
gsSGXDeviceMap.ui32IRQ = 0;
#else
+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO)
+
+ dev_res = platform_get_resource(gpsPVRLDMDev, IORESOURCE_MEM, 0);
+ if (dev_res == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: platform_get_resource failed", __FUNCTION__));
+ return PVRSRV_ERROR_INVALID_DEVICE;
+ }
+
+ dev_irq = platform_get_irq(gpsPVRLDMDev, 0);
+ if (dev_irq < 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: platform_get_irq failed (%d)", __FUNCTION__, -dev_irq));
+ return PVRSRV_ERROR_INVALID_DEVICE;
+ }
+ gsSGXDeviceMap.sRegsSysPBase.uiAddr = dev_res->start;
+ gsSGXDeviceMap.sRegsCpuPBase =
+ SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase);
+ PVR_TRACE(("SGX register base: 0x%lx", (unsigned long)gsSGXDeviceMap.sRegsCpuPBase.uiAddr));
+
+ gsSGXDeviceMap.ui32RegsSize = (unsigned int)(dev_res->end - dev_res->start);
+ PVR_TRACE(("SGX register size: %d",gsSGXDeviceMap.ui32RegsSize));
+
+ gsSGXDeviceMap.ui32IRQ = dev_irq;
+ PVR_TRACE(("SGX IRQ: %d", gsSGXDeviceMap.ui32IRQ));
+#else
gsSGXDeviceMap.sRegsSysPBase.uiAddr = SYS_OMAP3430_SGX_REGS_SYS_PHYS_BASE;
gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase);
gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE;
@@ -248,6 +280,23 @@ static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData)
gsSGXDeviceMap.ui32IRQ = SYS_OMAP3430_SGX_IRQ;
#endif
+#if defined(SGX_OCP_REGS_ENABLED)
+ gsSGXRegsCPUVAddr = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase,
+ gsSGXDeviceMap.ui32RegsSize,
+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
+ IMG_NULL);
+
+ if (gsSGXRegsCPUVAddr == IMG_NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysLocateDevices: Failed to map SGX registers"));
+ return PVRSRV_ERROR_BAD_MAPPING;
+ }
+
+
+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr;
+ gpvOCPRegsLinAddr = gsSGXRegsCPUVAddr;
+#endif
+#endif
#if defined(PDUMP)
{
@@ -261,7 +310,7 @@ static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData)
}
-IMG_CHAR *SysCreateVersionString(IMG_CPU_PHYADDR sRegRegion)
+static IMG_CHAR *SysCreateVersionString(void)
{
static IMG_CHAR aszVersionString[100];
SYS_DATA *psSysData;
@@ -270,8 +319,8 @@ IMG_CHAR *SysCreateVersionString(IMG_CPU_PHYADDR sRegRegion)
#if !defined(NO_HARDWARE)
IMG_VOID *pvRegsLinAddr;
- pvRegsLinAddr = OSMapPhysToLin(sRegRegion,
- SYS_OMAP3430_SGX_REGS_SIZE,
+ pvRegsLinAddr = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase,
+ gsSGXDeviceMap.ui32RegsSize,
PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
IMG_NULL);
if(!pvRegsLinAddr)
@@ -322,6 +371,7 @@ PVRSRV_ERROR SysInitialise(IMG_VOID)
#if !defined(SGX_DYNAMIC_TIMING_INFO)
SGX_TIMING_INFORMATION* psTimingInfo;
#endif
+
gpsSysData = &gsSysData;
OSMemSet(gpsSysData, 0, sizeof(SYS_DATA));
@@ -361,15 +411,6 @@ PVRSRV_ERROR SysInitialise(IMG_VOID)
return eError;
}
- TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE;
- gpsSysData->pvSOCTimerRegisterKM = IMG_NULL;
- gpsSysData->hSOCTimerRegisterOSMemHandle = 0;
- OSReservePhys(TimerRegPhysBase,
- 4,
- PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED,
- (IMG_VOID **)&gpsSysData->pvSOCTimerRegisterKM,
- &gpsSysData->hSOCTimerRegisterOSMemHandle);
-
#if !defined(SGX_DYNAMIC_TIMING_INFO)
psTimingInfo = &gsSGXDeviceMap.sTimingInfo;
@@ -402,28 +443,15 @@ PVRSRV_ERROR SysInitialise(IMG_VOID)
}
SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV);
-#if defined(SGX_OCP_REGS_ENABLED)
+ eError = SysPMRuntimeRegister();
+ if (eError != PVRSRV_OK)
{
- IMG_SYS_PHYADDR sOCPRegsSysPBase;
- IMG_CPU_PHYADDR sOCPRegsCpuPBase;
-
- sOCPRegsSysPBase.uiAddr = SYS_OMAP3430_OCP_REGS_SYS_PHYS_BASE;
- sOCPRegsCpuPBase = SysSysPAddrToCpuPAddr(sOCPRegsSysPBase);
-
- gpvOCPRegsLinAddr = OSMapPhysToLin(sOCPRegsCpuPBase,
- SYS_OMAP3430_OCP_REGS_SIZE,
- PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
- IMG_NULL);
-
- if (gpvOCPRegsLinAddr == IMG_NULL)
- {
- PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to map OCP registers"));
- return PVRSRV_ERROR_BAD_MAPPING;
- }
- SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_OCPREGS);
+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register with OSPM!"));
+ (IMG_VOID)SysDeinitialise(gpsSysData);
+ gpsSysData = IMG_NULL;
+ return eError;
}
-#endif
-
+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME);
eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice,
DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID);
@@ -517,6 +545,24 @@ PVRSRV_ERROR SysInitialise(IMG_VOID)
DisableSGXClocks(gpsSysData);
#endif
+#if !defined(PVR_NO_OMAP_TIMER)
+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA)
+ TimerRegPhysBase = gsSysSpecificData.sTimerRegPhysBase;
+#else
+ TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE;
+#endif
+ gpsSysData->pvSOCTimerRegisterKM = IMG_NULL;
+ gpsSysData->hSOCTimerRegisterOSMemHandle = 0;
+ if (TimerRegPhysBase.uiAddr != 0)
+ {
+ OSReservePhys(TimerRegPhysBase,
+ 4,
+ PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED,
+ (IMG_VOID **)&gpsSysData->pvSOCTimerRegisterKM,
+ &gpsSysData->hSOCTimerRegisterOSMemHandle);
+ }
+#endif
+
return PVRSRV_OK;
}
@@ -553,16 +599,17 @@ PVRSRV_ERROR SysFinalise(IMG_VOID)
SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR);
#endif
-
- gpsSysData->pszVersionString = SysCreateVersionString(gsSGXDeviceMap.sRegsCpuPBase);
+#if defined(__linux__)
+ gpsSysData->pszVersionString = SysCreateVersionString();
if (!gpsSysData->pszVersionString)
{
PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to create a system version string"));
}
else
{
- PVR_DPF((PVR_DBG_WARNING, "SysFinalise: Version string: %s", gpsSysData->pszVersionString));
+ PVR_TRACE(("SysFinalise: Version string: %s", gpsSysData->pszVersionString));
}
+#endif
#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT)
@@ -579,6 +626,14 @@ PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData)
{
PVRSRV_ERROR eError;
+ if(gpsSysData->pvSOCTimerRegisterKM)
+ {
+ OSUnReservePhys(gpsSysData->pvSOCTimerRegisterKM,
+ 4,
+ PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED,
+ gpsSysData->hSOCTimerRegisterOSMemHandle);
+ }
+
#if defined(SYS_USING_INTERRUPTS)
if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR))
{
@@ -623,15 +678,16 @@ PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData)
}
}
-#if defined(SGX_OCP_REGS_ENABLED)
- if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_OCPREGS))
+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME))
{
- OSUnMapPhysToLin(gpvOCPRegsLinAddr,
- SYS_OMAP3430_OCP_REGS_SIZE,
- PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
- IMG_NULL);
+ eError = SysPMRuntimeUnregister();
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: Failed to unregister with OSPM!"));
+ gpsSysData = IMG_NULL;
+ return eError;
+ }
}
-#endif
@@ -650,21 +706,27 @@ PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData)
}
}
- if(gpsSysData->pvSOCTimerRegisterKM)
- {
- OSUnReservePhys(gpsSysData->pvSOCTimerRegisterKM,
- 4,
- PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED,
- gpsSysData->hSOCTimerRegisterOSMemHandle);
- }
SysDeinitialiseCommon(gpsSysData);
-#if defined(NO_HARDWARE)
- if(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV))
+#if defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED)
+ if(gsSGXRegsCPUVAddr != IMG_NULL)
{
+#if defined(NO_HARDWARE)
OSBaseFreeContigMemory(SYS_OMAP3430_SGX_REGS_SIZE, gsSGXRegsCPUVAddr, gsSGXDeviceMap.sRegsCpuPBase);
+#else
+#if defined(SGX_OCP_REGS_ENABLED)
+ OSUnMapPhysToLin(gsSGXRegsCPUVAddr,
+ gsSGXDeviceMap.ui32RegsSize,
+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY,
+ IMG_NULL);
+
+ gpvOCPRegsLinAddr = IMG_NULL;
+#endif
+#endif
+ gsSGXRegsCPUVAddr = IMG_NULL;
+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr;
}
#endif
@@ -786,14 +848,41 @@ IMG_UINT32 SysGetInterruptSource(SYS_DATA *psSysData,
IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits)
{
- PVR_UNREFERENCED_PARAMETER(psSysData);
PVR_UNREFERENCED_PARAMETER(ui32ClearBits);
+#if defined(NO_HARDWARE)
+ PVR_UNREFERENCED_PARAMETER(psSysData);
+#else
+#if defined(SGX_OCP_NO_INT_BYPASS)
+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQSTATUS_2, 0x1);
+#endif
+ OSReadHWReg(((PVRSRV_SGXDEV_INFO *)gpsSGXDevNode->pvDevice)->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR);
+#endif
+}
- OSReadHWReg(((PVRSRV_SGXDEV_INFO *)gpsSGXDevNode->pvDevice)->pvRegsBaseKM,
- EUR_CR_EVENT_HOST_CLEAR);
+#if defined(SGX_OCP_NO_INT_BYPASS)
+IMG_VOID SysEnableSGXInterrupts(SYS_DATA *psSysData)
+{
+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData;
+ if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_ENABLE_LISR) && !SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED))
+ {
+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQSTATUS_2, 0x1);
+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQENABLE_SET_2, 0x1);
+ SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED);
+ }
}
+IMG_VOID SysDisableSGXInterrupts(SYS_DATA *psSysData)
+{
+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData;
+
+ if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED))
+ {
+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQENABLE_CLR_2, 0x1);
+ SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED);
+ }
+}
+#endif
PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState)
{
diff --git a/drivers/gpu/pvr/omap3/sysconfig.h b/drivers/gpu/pvr/omap3/sysconfig.h
index dd8a07d988d..60a53cf9f71 100644
--- a/drivers/gpu/pvr/omap3/sysconfig.h
+++ b/drivers/gpu/pvr/omap3/sysconfig.h
@@ -27,8 +27,6 @@
#if !defined(__SOCCONFIG_H__)
#define __SOCCONFIG_H__
-#include "syscommon.h"
-
#define VS_PRODUCT_NAME "OMAP3"
#if defined(SGX530) && (SGX_CORE_REV == 125)
@@ -51,9 +49,12 @@
#define SYS_OMAP3430_SGX_IRQ 21
-#define SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE 0x48088024
-#define SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE 0x48088028
-#define SYS_OMAP3430_GP11TIMER_TSICR_SYS_PHYS_BASE 0x48088040
+#define SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE 0x48088024
+#define SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE 0x48088028
+#define SYS_OMAP3430_GP11TIMER_TSICR_SYS_PHYS_BASE 0x48088040
+#if defined(__linux__)
+#define SYS_SGX_DEV_NAME "omap_gpu"
+#endif
#endif
diff --git a/drivers/gpu/pvr/omap3/syslocal.h b/drivers/gpu/pvr/omap3/syslocal.h
index 5b0894fc004..484f3d351a2 100644
--- a/drivers/gpu/pvr/omap3/syslocal.h
+++ b/drivers/gpu/pvr/omap3/syslocal.h
@@ -48,6 +48,44 @@
#endif
#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+#if !defined(LDM_PLATFORM)
+#error "LDM_PLATFORM must be set"
+#endif
+#define PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO
+#include <linux/platform_device.h>
+#endif
+
+#if ((defined(DEBUG) || defined(TIMING)) && \
+ (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,34))) && \
+ !defined(PVR_NO_OMAP_TIMER)
+#define PVR_OMAP3_TIMING_PRCM
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+#include <plat/gpu.h>
+#if !defined(PVR_NO_OMAP_TIMER)
+#define PVR_OMAP_USE_DM_TIMER_API
+#include <plat/dmtimer.h>
+#endif
+#endif
+
+#if !defined(PVR_NO_OMAP_TIMER)
+#define PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA
+#endif
+#endif
+
+#if !defined(NO_HARDWARE) && \
+ defined(SYS_USING_INTERRUPTS) && \
+ defined(SGX530)
+#define SGX_OCP_REGS_ENABLED
+#endif
+
+#if defined(__linux__)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) && defined(SGX_OCP_REGS_ENABLED)
+#define SGX_OCP_NO_INT_BYPASS
+#endif
#endif
#if defined (__cplusplus)
@@ -56,8 +94,6 @@ extern "C" {
-IMG_CHAR *SysCreateVersionString(IMG_CPU_PHYADDR sRegRegion);
-
IMG_VOID DisableSystemClocks(SYS_DATA *psSysData);
PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData);
@@ -77,6 +113,10 @@ PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData);
#define SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR 0x00000200
#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_SET(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData |= (flag)))
@@ -89,6 +129,9 @@ typedef struct _SYS_SPECIFIC_DATA_TAG_
IMG_UINT32 ui32SysSpecificData;
PVRSRV_DEVICE_NODE *psSGXDevNode;
IMG_BOOL bSGXInitComplete;
+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA)
+ IMG_CPU_PHYADDR sTimerRegPhysBase;
+#endif
#if !defined(__linux__)
IMG_BOOL bSGXClocksEnabled;
#endif
@@ -106,27 +149,56 @@ typedef struct _SYS_SPECIFIC_DATA_TAG_
atomic_t sNotifyLockCPU;
IMG_BOOL bCallVDD2PostFunc;
#endif
- struct clk *psCORE_CK;
- struct clk *psSGX_FCK;
- struct clk *psSGX_ICK;
- struct clk *psMPU_CK;
#if defined(DEBUG) || defined(TIMING)
struct clk *psGPT11_FCK;
struct clk *psGPT11_ICK;
#endif
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22))
- struct constraint_handle *pVdd2Handle;
+#if defined(PVR_OMAP_USE_DM_TIMER_API)
+ struct omap_dm_timer *psGPTimer;
#endif
#endif
} SYS_SPECIFIC_DATA;
extern SYS_SPECIFIC_DATA *gpsSysSpecificData;
+#if defined(SGX_OCP_REGS_ENABLED) && defined(SGX_OCP_NO_INT_BYPASS)
+IMG_VOID SysEnableSGXInterrupts(SYS_DATA* psSysData);
+IMG_VOID SysDisableSGXInterrupts(SYS_DATA* psSysData);
+#else
+#define SysEnableSGXInterrupts(psSysData)
+#define SysDisableSGXInterrupts(psSysData)
+#endif
+
#if defined(SYS_CUSTOM_POWERLOCK_WRAP)
IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData);
IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData);
#endif
+#if defined(__linux__)
+
+PVRSRV_ERROR SysPMRuntimeRegister(void);
+PVRSRV_ERROR SysPMRuntimeUnregister(void);
+
+#else
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysPMRuntimeRegister)
+#endif
+static INLINE PVRSRV_ERROR SysPMRuntimeRegister(void)
+{
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SysPMRuntimeUnregister)
+#endif
+static INLINE PVRSRV_ERROR SysPMRuntimeUnregister(void)
+{
+ return PVRSRV_OK;
+}
+
+#endif
+
#if defined(__cplusplus)
}
#endif
diff --git a/drivers/gpu/pvr/omap3/sysutils_linux_wqueue_compat.c b/drivers/gpu/pvr/omap3/sysutils_linux_wqueue_compat.c
index 481b7c61158..c0ecfb9f452 100644
--- a/drivers/gpu/pvr/omap3/sysutils_linux_wqueue_compat.c
+++ b/drivers/gpu/pvr/omap3/sysutils_linux_wqueue_compat.c
@@ -30,7 +30,7 @@
#include <linux/hardirq.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
-#include <plat/omap-pm.h>
+#include <linux/pm_runtime.h>
#include "sgxdefs.h"
#include "services_headers.h"
@@ -40,8 +40,8 @@
#include "sgxinfokm.h"
#include "syslocal.h"
-#if !defined(PVR_LINUX_USING_WORKQUEUES)
-#error "PVR_LINUX_USING_WORKQUEUES must be defined"
+#if !defined(LDM_PLATFORM) || !defined(CONFIG_OMAP2_DSS_USE_DSI_PLL)
+#undef SYS_OMAP3430_PIN_MEMORY_BUS_CLOCK
#endif
#define ONE_MHZ 1000000
@@ -53,7 +53,10 @@
#define SGX_PARENT_CLOCK "core_ck"
#endif
+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI)
extern struct platform_device *gpsPVRLDMDev;
+#endif
+
#if defined(SGX530) && (SGX_CORE_REV == 125)
#define OMAP_MEMORY_BUS_CLOCK_MAX 800000
#else
@@ -130,13 +133,9 @@ IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psTimingInfo)
{
IMG_UINT32 rate;
-#if defined(NO_HARDWARE)
rate = SYS_SGX_CLOCK_SPEED;
-#else
+#if !defined(NO_HARDWARE)
PVR_ASSERT(atomic_read(&gpsSysSpecificData->sSGXClocksEnabled) != 0);
-
- rate = clk_get_rate(gpsSysSpecificData->psSGX_FCK);
- PVR_ASSERT(rate != 0);
#endif
psTimingInfo->ui32CoreClockSpeed = rate;
psTimingInfo->ui32HWRecoveryFreq = scale_prop_to_SGX_clock(SYS_SGX_HWRECOVERY_TIMEOUT_FREQ, rate);
@@ -153,10 +152,6 @@ PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData)
{
#if !defined(NO_HARDWARE)
SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
- long lNewRate;
- long lRate;
- IMG_INT res;
-
if (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0)
{
return PVRSRV_OK;
@@ -164,57 +159,21 @@ PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData)
PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: Enabling SGX Clocks"));
-#if defined(DEBUG)
- {
- IMG_UINT32 rate = clk_get_rate(psSysSpecData->psMPU_CK);
- PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: CPU Clock is %dMhz", HZ_TO_MHZ(rate)));
- }
+#if defined(SYS_OMAP3430_PIN_MEMORY_BUS_CLOCK)
+ omap_pm_set_min_bus_tput(&gpsPVRLDMDev->dev, OCP_INITIATOR_AGENT, OMAP_MEMORY_BUS_CLOCK_MAX);
#endif
- res = clk_enable(psSysSpecData->psSGX_FCK);
- if (res < 0)
- {
- PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't enable SGX functional clock (%d)", res));
- return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK;
- }
-
- res = clk_enable(psSysSpecData->psSGX_ICK);
- if (res < 0)
- {
- PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't enable SGX interface clock (%d)", res));
-
- clk_disable(psSysSpecData->psSGX_FCK);
- return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK;
- }
-
- lNewRate = clk_round_rate(psSysSpecData->psSGX_FCK, SYS_SGX_CLOCK_SPEED + ONE_MHZ);
- if (lNewRate <= 0)
- {
- PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't round SGX functional clock rate"));
- return PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE;
- }
-
- lRate = clk_get_rate(psSysSpecData->psSGX_FCK);
- if (lRate != lNewRate)
+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI)
{
- res = clk_set_rate(psSysSpecData->psSGX_FCK, lNewRate);
+ int res = pm_runtime_get_sync(&gpsPVRLDMDev->dev);
if (res < 0)
{
- PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: Couldn't set SGX functional clock rate (%d)", res));
+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: pm_runtime_get_sync failed (%d)", -res));
+ return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK;
}
}
-
-#if defined(DEBUG)
- {
- IMG_UINT32 rate = clk_get_rate(psSysSpecData->psSGX_FCK);
- PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: SGX Functional Clock is %dMhz", HZ_TO_MHZ(rate)));
- }
-#endif
-
-#if defined(SYS_OMAP3430_PIN_MEMORY_BUS_CLOCK)
- omap_pm_set_min_bus_tput(&gpsPVRLDMDev->dev, OCP_INITIATOR_AGENT, OMAP_MEMORY_BUS_CLOCK_MAX);
#endif
-
+ SysEnableSGXInterrupts(psSysData);
atomic_set(&psSysSpecData->sSGXClocksEnabled, 1);
@@ -237,117 +196,117 @@ IMG_VOID DisableSGXClocks(SYS_DATA *psSysData)
PVR_DPF((PVR_DBG_MESSAGE, "DisableSGXClocks: Disabling SGX Clocks"));
- if (psSysSpecData->psSGX_ICK)
- {
- clk_disable(psSysSpecData->psSGX_ICK);
- }
+ SysDisableSGXInterrupts(psSysData);
- if (psSysSpecData->psSGX_FCK)
+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI)
{
- clk_disable(psSysSpecData->psSGX_FCK);
+ int res = pm_runtime_put_sync(&gpsPVRLDMDev->dev);
+ if (res < 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "DisableSGXClocks: pm_runtime_put_sync failed (%d)", -res));
+ }
}
+#endif
#if defined(SYS_OMAP3430_PIN_MEMORY_BUS_CLOCK)
omap_pm_set_min_bus_tput(&gpsPVRLDMDev->dev, OCP_INITIATOR_AGENT, 0);
#endif
atomic_set(&psSysSpecData->sSGXClocksEnabled, 0);
-
#else
PVR_UNREFERENCED_PARAMETER(psSysData);
#endif
}
-PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData)
+
+#if (defined(DEBUG) || defined(TIMING)) && !defined(PVR_NO_OMAP_TIMER)
+#if defined(PVR_OMAP_USE_DM_TIMER_API)
+#define GPTIMER_TO_USE 11
+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData)
{
- SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
- struct clk *psCLK;
- IMG_INT res;
- PVRSRV_ERROR eError;
+ PVR_ASSERT(psSysSpecData->psGPTimer == NULL);
-#if defined(DEBUG) || defined(TIMING)
- IMG_INT rate;
- struct clk *sys_ck;
- IMG_CPU_PHYADDR TimerRegPhysBase;
- IMG_HANDLE hTimerEnable;
- IMG_UINT32 *pui32TimerEnable;
-#endif
+ psSysSpecData->psGPTimer = omap_dm_timer_request_specific(GPTIMER_TO_USE);
+ if (psSysSpecData->psGPTimer == NULL)
+ {
- PVR_TRACE(("EnableSystemClocks: Enabling System Clocks"));
+ PVR_DPF((PVR_DBG_WARNING, "%s: omap_dm_timer_request_specific failed", __FUNCTION__));
+ return PVRSRV_ERROR_CLOCK_REQUEST_FAILED;
+ }
- if (!psSysSpecData->bSysClocksOneTimeInit)
+
+ omap_dm_timer_set_source(psSysSpecData->psGPTimer, OMAP_TIMER_SRC_SYS_CLK);
+ omap_dm_timer_enable(psSysSpecData->psGPTimer);
+
+
+ omap_dm_timer_set_load_start(psSysSpecData->psGPTimer, 1, 0);
+
+ omap_dm_timer_start(psSysSpecData->psGPTimer);
+
+
+ psSysSpecData->sTimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE;
+
+ return PVRSRV_OK;
+}
+
+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData)
+{
+ if (psSysSpecData->psGPTimer != NULL)
{
- mutex_init(&psSysSpecData->sPowerLock);
- atomic_set(&psSysSpecData->sSGXClocksEnabled, 0);
+ (void) omap_dm_timer_stop(psSysSpecData->psGPTimer);
- psCLK = clk_get(NULL, SGX_PARENT_CLOCK);
- if (IS_ERR(psCLK))
- {
- PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get Core Clock"));
- goto ExitError;
- }
- psSysSpecData->psCORE_CK = psCLK;
+ omap_dm_timer_disable(psSysSpecData->psGPTimer);
- psCLK = clk_get(NULL, "sgx_fck");
- if (IS_ERR(psCLK))
- {
- PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get SGX Functional Clock"));
- goto ExitError;
- }
- psSysSpecData->psSGX_FCK = psCLK;
+ omap_dm_timer_free(psSysSpecData->psGPTimer);
- psCLK = clk_get(NULL, "sgx_ick");
- if (IS_ERR(psCLK))
- {
- PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get SGX Interface Clock"));
- goto ExitError;
- }
- psSysSpecData->psSGX_ICK = psCLK;
+ psSysSpecData->sTimerRegPhysBase.uiAddr = 0;
-#if defined(DEBUG)
- psCLK = clk_get(NULL, "mpu_ck");
- if (IS_ERR(psCLK))
- {
- PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get MPU Clock"));
- goto ExitError;
- }
- psSysSpecData->psMPU_CK = psCLK;
+ psSysSpecData->psGPTimer = NULL;
+ }
+
+}
+#else
+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData)
+{
+#if defined(PVR_OMAP3_TIMING_PRCM)
+ struct clk *psCLK;
+ IMG_INT res;
+ struct clk *sys_ck;
+ IMG_INT rate;
#endif
- res = clk_set_parent(psSysSpecData->psSGX_FCK, psSysSpecData->psCORE_CK);
- if (res < 0)
- {
- PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set SGX parent clock (%d)", res));
- goto ExitError;
- }
+ PVRSRV_ERROR eError;
- psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE;
- }
+ IMG_CPU_PHYADDR sTimerRegPhysBase;
+ IMG_HANDLE hTimerEnable;
+ IMG_UINT32 *pui32TimerEnable;
+
+ PVR_ASSERT(psSysSpecData->sTimerRegPhysBase.uiAddr == 0);
-#if defined(DEBUG) || defined(TIMING)
+#if defined(PVR_OMAP3_TIMING_PRCM)
psCLK = clk_get(NULL, "gpt11_fck");
if (IS_ERR(psCLK))
{
- PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock"));
- goto ExitUnRegisterConstraintNotifications;
+ PVR_DPF((PVR_DBG_ERROR, "AcquireGPTimer: Couldn't get GPTIMER11 functional clock"));
+ goto ExitError;
}
psSysSpecData->psGPT11_FCK = psCLK;
psCLK = clk_get(NULL, "gpt11_ick");
if (IS_ERR(psCLK))
{
- PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 interface clock"));
- goto ExitUnRegisterConstraintNotifications;
+ PVR_DPF((PVR_DBG_ERROR, "AcquireGPTimer: Couldn't get GPTIMER11 interface clock"));
+ goto ExitError;
}
psSysSpecData->psGPT11_ICK = psCLK;
sys_ck = clk_get(NULL, "sys_ck");
if (IS_ERR(sys_ck))
{
- PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get System clock"));
- goto ExitUnRegisterConstraintNotifications;
+ PVR_DPF((PVR_DBG_ERROR, "AcquireGPTimer: Couldn't get System clock"));
+ goto ExitError;
}
if(clk_get_parent(psSysSpecData->psGPT11_FCK) != sys_ck)
@@ -356,8 +315,8 @@ PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData)
res = clk_set_parent(psSysSpecData->psGPT11_FCK, sys_ck);
if (res < 0)
{
- PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set GPTIMER11 parent clock (%d)", res));
- goto ExitUnRegisterConstraintNotifications;
+ PVR_DPF((PVR_DBG_ERROR, "AcquireGPTimer: Couldn't set GPTIMER11 parent clock (%d)", res));
+ goto ExitError;
}
}
@@ -367,37 +326,37 @@ PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData)
res = clk_enable(psSysSpecData->psGPT11_FCK);
if (res < 0)
{
- PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 functional clock (%d)", res));
- goto ExitUnRegisterConstraintNotifications;
+ PVR_DPF((PVR_DBG_ERROR, "AcquireGPTimer: Couldn't enable GPTIMER11 functional clock (%d)", res));
+ goto ExitError;
}
res = clk_enable(psSysSpecData->psGPT11_ICK);
if (res < 0)
{
- PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 interface clock (%d)", res));
+ PVR_DPF((PVR_DBG_ERROR, "AcquireGPTimer: Couldn't enable GPTIMER11 interface clock (%d)", res));
goto ExitDisableGPT11FCK;
}
+#endif
- TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_TSICR_SYS_PHYS_BASE;
- pui32TimerEnable = OSMapPhysToLin(TimerRegPhysBase,
+ sTimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_TSICR_SYS_PHYS_BASE;
+ pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase,
4,
PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
&hTimerEnable);
if (pui32TimerEnable == IMG_NULL)
{
- PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed"));
+ PVR_DPF((PVR_DBG_ERROR, "AcquireGPTimer: OSMapPhysToLin failed"));
goto ExitDisableGPT11ICK;
}
- rate = *pui32TimerEnable;
- if(!(rate & 4))
+ if(!(*pui32TimerEnable & 4))
{
PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)"));
- *pui32TimerEnable = rate | 4;
+ *pui32TimerEnable |= 4;
}
OSUnMapPhysToLin(pui32TimerEnable,
@@ -406,15 +365,15 @@ PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData)
hTimerEnable);
- TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE;
- pui32TimerEnable = OSMapPhysToLin(TimerRegPhysBase,
+ sTimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE;
+ pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase,
4,
PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
&hTimerEnable);
if (pui32TimerEnable == IMG_NULL)
{
- PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed"));
+ PVR_DPF((PVR_DBG_ERROR, "AcquireGPTimer: OSMapPhysToLin failed"));
goto ExitDisableGPT11ICK;
}
@@ -426,42 +385,36 @@ PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData)
PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
hTimerEnable);
-#endif
+ psSysSpecData->sTimerRegPhysBase = sTimerRegPhysBase;
eError = PVRSRV_OK;
+
goto Exit;
-#if defined(DEBUG) || defined(TIMING)
ExitDisableGPT11ICK:
+#if defined(PVR_OMAP3_TIMING_PRCM)
clk_disable(psSysSpecData->psGPT11_ICK);
ExitDisableGPT11FCK:
clk_disable(psSysSpecData->psGPT11_FCK);
-ExitUnRegisterConstraintNotifications:
-#endif
ExitError:
- eError = PVRSRV_ERROR_DISABLE_CLOCK_FAILURE;
+#endif
+ eError = PVRSRV_ERROR_CLOCK_REQUEST_FAILED;
Exit:
return eError;
}
-IMG_VOID DisableSystemClocks(SYS_DATA *psSysData)
+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData)
{
-#if defined(DEBUG) || defined(TIMING)
- SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
- IMG_CPU_PHYADDR TimerRegPhysBase;
IMG_HANDLE hTimerDisable;
IMG_UINT32 *pui32TimerDisable;
-#endif
-
- PVR_TRACE(("DisableSystemClocks: Disabling System Clocks"));
+ if (psSysSpecData->sTimerRegPhysBase.uiAddr == 0)
+ {
+ return;
+ }
- DisableSGXClocks(psSysData);
-
-#if defined(DEBUG) || defined(TIMING)
- TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE;
- pui32TimerDisable = OSMapPhysToLin(TimerRegPhysBase,
+ pui32TimerDisable = OSMapPhysToLin(psSysSpecData->sTimerRegPhysBase,
4,
PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED,
&hTimerDisable);
@@ -480,9 +433,117 @@ IMG_VOID DisableSystemClocks(SYS_DATA *psSysData)
hTimerDisable);
}
+ psSysSpecData->sTimerRegPhysBase.uiAddr = 0;
+
+#if defined(PVR_OMAP3_TIMING_PRCM)
clk_disable(psSysSpecData->psGPT11_ICK);
clk_disable(psSysSpecData->psGPT11_FCK);
+#endif
+}
+#endif
+#else
+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData)
+{
+ PVR_UNREFERENCED_PARAMETER(psSysSpecData);
+
+ return PVRSRV_OK;
+}
+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData)
+{
+ PVR_UNREFERENCED_PARAMETER(psSysSpecData);
+}
+#endif
+
+PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData)
+{
+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
+
+ PVR_TRACE(("EnableSystemClocks: Enabling System Clocks"));
+
+ if (!psSysSpecData->bSysClocksOneTimeInit)
+ {
+ int res;
+ long rate;
+ struct clk *parent_clk, *sgx_fck;
+
+ parent_clk = clk_get(NULL, SGX_PARENT_CLOCK);
+ if (IS_ERR(parent_clk))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get Core Clock"));
+ return PVRSRV_ERROR_CLOCK_REQUEST_FAILED;
+ }
+ sgx_fck = clk_get(NULL, "sgx_fck");
+ if (IS_ERR(sgx_fck))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get SGX Functional Clock"));
+ clk_put(parent_clk);
+ return PVRSRV_ERROR_CLOCK_REQUEST_FAILED;
+ }
+
+ res = clk_set_parent(sgx_fck, parent_clk);
+ clk_put(parent_clk);
+ if (res < 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set SGX parent clock (%d)", res));
+ clk_put(sgx_fck);
+ return PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK;
+ }
+
+ clk_enable(sgx_fck);
+ rate = clk_round_rate(sgx_fck, SYS_SGX_CLOCK_SPEED + ONE_MHZ);
+ if (rate <= 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't round SGX functional clock rate"));
+ clk_disable(sgx_fck);
+ clk_put(sgx_fck);
+ return PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE;
+ }
+
+ res = clk_set_rate(sgx_fck, rate);
+ if (res < 0)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: Couldn't set SGX functional clock rate (%d)", res));
+ }
+
+ clk_disable(sgx_fck);
+ clk_put(sgx_fck);
+
+ mutex_init(&psSysSpecData->sPowerLock);
+
+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 0);
+
+ psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE;
+ }
+
+ return AcquireGPTimer(psSysSpecData);
+}
+
+IMG_VOID DisableSystemClocks(SYS_DATA *psSysData)
+{
+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData;
+
+ PVR_TRACE(("DisableSystemClocks: Disabling System Clocks"));
+
+
+ DisableSGXClocks(psSysData);
+
+ ReleaseGPTimer(psSysSpecData);
+}
+
+PVRSRV_ERROR SysPMRuntimeRegister(void)
+{
+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI)
+ pm_runtime_enable(&gpsPVRLDMDev->dev);
#endif
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR SysPMRuntimeUnregister(void)
+{
+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI)
+ pm_runtime_disable(&gpsPVRLDMDev->dev);
+#endif
+ return PVRSRV_OK;
}