diff options
author | seonkon.choi <seonkon.choi@ti.com> | 2011-05-31 09:25:17 +0100 |
---|---|---|
committer | Andy Green <andy.green@linaro.org> | 2011-05-31 11:06:51 +0100 |
commit | 282ecd7d0d856e0f6062d8678551c04c2eb4ae55 (patch) | |
tree | 0d27fc0e3206670389119a0e595abc585f550dcb /drivers | |
parent | 7e0942c87b248c3d2102becf6726cf7b8f7dfd6d (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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/pvr/omap3/sysconfig.c | 237 | ||||
-rw-r--r-- | drivers/gpu/pvr/omap3/sysconfig.h | 11 | ||||
-rw-r--r-- | drivers/gpu/pvr/omap3/syslocal.h | 88 | ||||
-rw-r--r-- | drivers/gpu/pvr/omap3/sysutils_linux_wqueue_compat.c | 367 |
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; } |