From 10544db2e8800cd0f7c9b48d50ecc2070a9ed019 Mon Sep 17 00:00:00 2001 From: Rodrigo Obregon Date: Thu, 25 Aug 2011 08:00:15 +0100 Subject: OMAP4: SGX-KM: Update DDK version to 1.7.17.3556 This patch updates the DDK to version 1.7.17.3556 The corresponding change in the user side most be in place for this DDK to work. Change-Id: I57ab5c29e7cf89bfce2388428914cc1f1474be6d Signed-off-by: Rodrigo Obregon --- drivers/gpu/pvr/omap4/sysutils_linux.c | 537 +++++++++++++++++++++++++++++++++ 1 file changed, 537 insertions(+) create mode 100644 drivers/gpu/pvr/omap4/sysutils_linux.c (limited to 'drivers/gpu/pvr/omap4/sysutils_linux.c') diff --git a/drivers/gpu/pvr/omap4/sysutils_linux.c b/drivers/gpu/pvr/omap4/sysutils_linux.c new file mode 100644 index 00000000000..40b2cc35ccc --- /dev/null +++ b/drivers/gpu/pvr/omap4/sysutils_linux.c @@ -0,0 +1,537 @@ +/********************************************************************** + * + * Copyright(c) 2008 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. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include +#include +#include +#include +#include + +#include "sgxdefs.h" +#include "services_headers.h" +#include "sysinfo.h" +#include "sgxapi_km.h" +#include "sysconfig.h" +#include "sgxinfokm.h" +#include "syslocal.h" + +#include +#include + +#if !defined(PVR_LINUX_USING_WORKQUEUES) +#error "PVR_LINUX_USING_WORKQUEUES must be defined" +#endif + +#if ((defined(DEBUG) || defined(TIMING)) && \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))) && \ + !defined(PVR_NO_OMAP_TIMER) +#define PVR_OMAP4_TIMING_PRCM +#endif + +#define ONE_MHZ 1000000 +#define HZ_TO_MHZ(m) ((m) / ONE_MHZ) + +#if defined(SUPPORT_OMAP3430_SGXFCLK_96M) +#define SGX_PARENT_CLOCK "cm_96m_fck" +#else +#define SGX_PARENT_CLOCK "core_ck" +#endif + +#if defined(LDM_PLATFORM) && !defined(SUPPORT_DRI_DRM) +extern struct platform_device *gpsPVRLDMDev; +#endif + +static IMG_VOID PowerLockWrap(SYS_SPECIFIC_DATA *psSysSpecData) +{ + if (!in_interrupt()) + { + mutex_lock(&psSysSpecData->sPowerLock); + + } +} + +static IMG_VOID PowerLockUnwrap(SYS_SPECIFIC_DATA *psSysSpecData) +{ + if (!in_interrupt()) + { + mutex_unlock(&psSysSpecData->sPowerLock); + } +} + +PVRSRV_ERROR SysPowerLockWrap(IMG_VOID) +{ + SYS_DATA *psSysData; + + SysAcquireData(&psSysData); + + PowerLockWrap(psSysData->pvSysSpecificData); + + return PVRSRV_OK; +} + +IMG_VOID SysPowerLockUnwrap(IMG_VOID) +{ + SYS_DATA *psSysData; + + SysAcquireData(&psSysData); + + PowerLockUnwrap(psSysData->pvSysSpecificData); +} + +IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) +{ + return IMG_TRUE; +} + +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); +} + +IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psTimingInfo) +{ + IMG_UINT32 rate; + +#if defined(NO_HARDWARE) + rate = SYS_SGX_CLOCK_SPEED; +#else + PVR_ASSERT(atomic_read(&gpsSysSpecificData->sSGXClocksEnabled) != 0); + +#if defined(OMAP4_PRCM_ENABLE) + rate = clk_get_rate(gpsSysSpecificData->psSGX_FCK); +#else + rate = SYS_SGX_CLOCK_SPEED; +#endif + PVR_ASSERT(rate != 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(SUPPORT_ACTIVE_POWER_MANAGEMENT) + psTimingInfo->bEnableActivePM = IMG_TRUE; +#else + psTimingInfo->bEnableActivePM = IMG_FALSE; +#endif + psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; +} + +PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData) +{ +#if !defined(NO_HARDWARE) + SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; +#if defined(OMAP4_PRCM_ENABLE) + long lNewRate; + long lRate; + IMG_INT res; +#endif + + + if (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0) + { + return PVRSRV_OK; + } + + PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: Enabling SGX Clocks")); + +#if defined(LDM_PLATFORM) && !defined(SUPPORT_DRI_DRM) + pm_runtime_get_sync(&gpsPVRLDMDev->dev); +#endif + +#if defined(OMAP4_PRCM_ENABLE) + +#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))); + } +#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) + { + res = clk_set_rate(psSysSpecData->psSGX_FCK, lNewRate); + if (res < 0) + { + PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: Couldn't set SGX functional clock rate (%d)", res)); + } + } + +#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 + +#endif + + + atomic_set(&psSysSpecData->sSGXClocksEnabled, 1); + +#else + PVR_UNREFERENCED_PARAMETER(psSysData); +#endif + return PVRSRV_OK; +} + + +IMG_VOID DisableSGXClocks(SYS_DATA *psSysData) +{ +#if !defined(NO_HARDWARE) + SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; + + + if (atomic_read(&psSysSpecData->sSGXClocksEnabled) == 0) + { + return; + } + + PVR_DPF((PVR_DBG_MESSAGE, "DisableSGXClocks: Disabling SGX Clocks")); + +#if defined(LDM_PLATFORM) && !defined(SUPPORT_DRI_DRM) + pm_runtime_put_sync(&gpsPVRLDMDev->dev); +#endif + +#if defined(OMAP4_PRCM_ENABLE) + if (psSysSpecData->psSGX_ICK) + { + clk_disable(psSysSpecData->psSGX_ICK); + } + + if (psSysSpecData->psSGX_FCK) + { + clk_disable(psSysSpecData->psSGX_FCK); + } +#endif + + + atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); + +#else + PVR_UNREFERENCED_PARAMETER(psSysData); +#endif +} + +PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData) +{ + SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; +#if (defined(OMAP4_PRCM_ENABLE) || defined(PVR_OMAP4_TIMING_PRCM)) + struct clk *psCLK; + IMG_INT res; +#endif +#if defined(PVR_OMAP4_TIMING_PRCM) + struct clk *sys_ck; + IMG_INT rate; +#endif + PVRSRV_ERROR eError; + +#if (defined(DEBUG) || defined(TIMING)) && !defined(PVR_NO_OMAP_TIMER) + IMG_CPU_PHYADDR TimerRegPhysBase; + IMG_HANDLE hTimerEnable; + IMG_UINT32 *pui32TimerEnable; +#endif + + PVR_TRACE(("EnableSystemClocks: Enabling System Clocks")); + + if (!psSysSpecData->bSysClocksOneTimeInit) + { + mutex_init(&psSysSpecData->sPowerLock); + + atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); + +#if defined(OMAP4_PRCM_ENABLE) + 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; + + 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; + + 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; + +#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; +#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; + } +#endif + + psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE; + } + +#if (defined(DEBUG) || defined(TIMING)) && !defined(PVR_NO_OMAP_TIMER) +#if defined(PVR_OMAP4_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; + } + 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; + } + psSysSpecData->psGPT11_ICK = psCLK; + + sys_ck = clk_get(NULL, "sys_clkin_ck"); + if (IS_ERR(sys_ck)) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get System clock")); + goto ExitUnRegisterConstraintNotifications; + } + + if(clk_get_parent(psSysSpecData->psGPT11_FCK) != sys_ck) + { + PVR_TRACE(("Setting GPTIMER11 parent to System Clock")); + 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; + } + } + + rate = clk_get_rate(psSysSpecData->psGPT11_FCK); + PVR_TRACE(("GPTIMER11 clock is %dMHz", HZ_TO_MHZ(rate))); + + 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; + } + + res = clk_enable(psSysSpecData->psGPT11_ICK); + if (res < 0) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 interface clock (%d)", res)); + goto ExitDisableGPT11FCK; + } +#endif + + + TimerRegPhysBase.uiAddr = SYS_OMAP4430_GP11TIMER_TSICR_SYS_PHYS_BASE; + pui32TimerEnable = OSMapPhysToLin(TimerRegPhysBase, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + &hTimerEnable); + + if (pui32TimerEnable == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed")); + goto ExitDisableGPT11ICK; + } + + if(!(*pui32TimerEnable & 4)) + { + PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)")); + + + *pui32TimerEnable |= 4; + } + + OSUnMapPhysToLin(pui32TimerEnable, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + hTimerEnable); + + + TimerRegPhysBase.uiAddr = SYS_OMAP4430_GP11TIMER_ENABLE_SYS_PHYS_BASE; + pui32TimerEnable = OSMapPhysToLin(TimerRegPhysBase, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + &hTimerEnable); + + if (pui32TimerEnable == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed")); + goto ExitDisableGPT11ICK; + } + + + *pui32TimerEnable = 3; + + OSUnMapPhysToLin(pui32TimerEnable, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + hTimerEnable); + +#endif + + eError = PVRSRV_OK; + goto Exit; + +#if (defined(DEBUG) || defined(TIMING)) && !defined(PVR_NO_OMAP_TIMER) +ExitDisableGPT11ICK: +#if defined(PVR_OMAP4_TIMING_PRCM) + clk_disable(psSysSpecData->psGPT11_ICK); +ExitDisableGPT11FCK: + clk_disable(psSysSpecData->psGPT11_FCK); +ExitUnRegisterConstraintNotifications: +#endif +#endif +#if defined(OMAP4_PRCM_ENABLE) +ExitError: +#endif + eError = PVRSRV_ERROR_DISABLE_CLOCK_FAILURE; +Exit: + return eError; +} + +IMG_VOID DisableSystemClocks(SYS_DATA *psSysData) +{ +#if (defined(DEBUG) || defined(TIMING)) && !defined(PVR_NO_OMAP_TIMER) +#if defined(PVR_OMAP4_TIMING_PRCM) + SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; +#endif + IMG_CPU_PHYADDR TimerRegPhysBase; + IMG_HANDLE hTimerDisable; + IMG_UINT32 *pui32TimerDisable; +#endif + + PVR_TRACE(("DisableSystemClocks: Disabling System Clocks")); + + + DisableSGXClocks(psSysData); + +#if (defined(DEBUG) || defined(TIMING)) && !defined(PVR_NO_OMAP_TIMER) + + TimerRegPhysBase.uiAddr = SYS_OMAP4430_GP11TIMER_ENABLE_SYS_PHYS_BASE; + pui32TimerDisable = OSMapPhysToLin(TimerRegPhysBase, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + &hTimerDisable); + + if (pui32TimerDisable == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "DisableSystemClocks: OSMapPhysToLin failed")); + } + else + { + *pui32TimerDisable = 0; + + OSUnMapPhysToLin(pui32TimerDisable, + 4, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + hTimerDisable); + } + +#if defined(PVR_OMAP4_TIMING_PRCM) + clk_disable(psSysSpecData->psGPT11_ICK); + + clk_disable(psSysSpecData->psGPT11_FCK); +#endif +#endif +} + +PVRSRV_ERROR SysPMRuntimeRegister(void) +{ +#if defined(LDM_PLATFORM) && !defined(SUPPORT_DRI_DRM) + pm_runtime_enable(&gpsPVRLDMDev->dev); +#endif + return PVRSRV_OK; +} + +PVRSRV_ERROR SysPMRuntimeUnregister(void) +{ +#if defined(LDM_PLATFORM) && !defined(SUPPORT_DRI_DRM) + pm_runtime_disable(&gpsPVRLDMDev->dev); +#endif + return PVRSRV_OK; +} -- cgit v1.2.2