diff options
Diffstat (limited to 'drivers/gpu/pvr/omap3/sysconfig.c')
-rw-r--r-- | drivers/gpu/pvr/omap3/sysconfig.c | 963 |
1 files changed, 963 insertions, 0 deletions
diff --git a/drivers/gpu/pvr/omap3/sysconfig.c b/drivers/gpu/pvr/omap3/sysconfig.c new file mode 100644 index 0000000..d503661 --- /dev/null +++ b/drivers/gpu/pvr/omap3/sysconfig.c @@ -0,0 +1,963 @@ +/********************************************************************** + * + * 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. <gpl-support@imgtec.com> + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#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 +#endif + +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; + +#define DEVICE_SGX_INTERRUPT (1 << 0) + +#if defined(NO_HARDWARE) +static IMG_CPU_VIRTADDR gsSGXRegsCPUVAddr; +#endif + +IMG_UINT32 PVRSRV_BridgeDispatchKM(IMG_UINT32 Ioctl, + IMG_BYTE *pInBuf, + IMG_UINT32 InBufLen, + IMG_BYTE *pOutBuf, + IMG_UINT32 OutBufLen, + IMG_UINT32 *pdwBytesTransferred); + +#if defined(DEBUG) && defined(DUMP_OMAP34xx_CLOCKS) && defined(__linux__) + +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#include <mach/clock.h> + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) +#include <../mach-omap2/clock_34xx.h> +#define ONCHIP_CLKS onchip_clks +#else +#include <../mach-omap2/clock34xx.h> +#define ONCHIP_CLKS onchip_34xx_clks +#endif + +static void omap3_clk_recalc(struct clk *clk) {} +static void omap3_followparent_recalc(struct clk *clk) {} +static void omap3_propagate_rate(struct clk *clk) {} +static void omap3_table_recalc(struct clk *clk) {} +static long omap3_round_to_table_rate(struct clk *clk, unsigned long rate) { return 0; } +static int omap3_select_table_rate(struct clk *clk, unsigned long rate) { return 0; } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) +static void omap3_dpll_recalc(struct clk *clk, unsigned long parent_rate, + u8 rate_storage) {} +static void omap3_clkoutx2_recalc(struct clk *clk, unsigned long parent_rate, + u8 rate_storage) {} +static void omap3_dpll_allow_idle(struct clk *clk) {} +static void omap3_dpll_deny_idle(struct clk *clk) {} +static u32 omap3_dpll_autoidle_read(struct clk *clk) { return 0; } +static int omap3_noncore_dpll_enable(struct clk *clk) { return 0; } +static void omap3_noncore_dpll_disable(struct clk *clk) {} +static int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate) { return 0; } +static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate) { return 0; } +void followparent_recalc(struct clk *clk, unsigned long new_parent_rate, + u8 rate_storage) {} +long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate) { return 0; } +void omap2_clksel_recalc(struct clk *clk, unsigned long new_parent_rate, + u8 rate_storage) {} +long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate) { return 0; } +int omap2_clksel_set_rate(struct clk *clk, unsigned long rate) { return 0; } +void omap2_fixed_divisor_recalc(struct clk *clk, unsigned long new_parent_rate, + u8 rate_storage) {} +void omap2_init_clksel_parent(struct clk *clk) {} +#endif + +static void dump_omap34xx_clocks(void) +{ + struct clk **c; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) + struct vdd_prcm_config *t1 = vdd1_rate_table; + struct vdd_prcm_config *t2 = vdd2_rate_table; + + t1 = t1; + t2 = t2; +#else + + omap3_dpll_allow_idle(0); + omap3_dpll_deny_idle(0); + omap3_dpll_autoidle_read(0); + omap3_clk_recalc(0); + omap3_followparent_recalc(0); + omap3_propagate_rate(0); + omap3_table_recalc(0); + omap3_round_to_table_rate(0, 0); + omap3_select_table_rate(0, 0); +#endif + + for(c = ONCHIP_CLKS; c < ONCHIP_CLKS + ARRAY_SIZE(ONCHIP_CLKS); c++) + { + struct clk *cp = *c, *copy; + unsigned long rate; + copy = clk_get(NULL, cp->name); + if(!copy) + continue; + rate = clk_get_rate(copy); + if (rate < 1000000) + { + PVR_DPF((PVR_DBG_ERROR, "%s: clock %s is %lu KHz (%lu Hz)", __func__, cp->name, rate/1000, rate)); + } + else + { + PVR_DPF((PVR_DBG_ERROR, "%s: clock %s is %lu MHz (%lu Hz)", __func__, cp->name, rate/1000000, rate)); + } + } +} + +#else + +static INLINE void dump_omap34xx_clocks(void) {} + +#endif + +#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(eError == PVRSRV_OK) + { + OSWriteHWReg(gpvOCPRegsLinAddr, + EUR_CR_OCP_DEBUG_CONFIG - EUR_CR_OCP_REVISION, + EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_MASK); + } + + return eError; +} + +#else + +static INLINE PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData) +{ + return EnableSGXClocks(psSysData); +} + +#endif + +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); + } +#endif + + return eError; +} + +static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData) +{ +#if defined(NO_HARDWARE) + PVRSRV_ERROR eError; + IMG_CPU_PHYADDR sCpuPAddr; +#endif + + PVR_UNREFERENCED_PARAMETER(psSysData); + + + gsSGXDeviceMap.ui32Flags = 0x0; + +#if defined(NO_HARDWARE) + + + eError = OSBaseAllocContigMemory(SYS_OMAP3430_SGX_REGS_SIZE, + &gsSGXRegsCPUVAddr, + &sCpuPAddr); + if(eError != PVRSRV_OK) + { + return eError; + } + gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr; + gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase); + gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE; +#if defined(__linux__) + + gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; +#else + + gsSGXDeviceMap.pvRegsCpuVBase = IMG_NULL; +#endif + + OSMemSet(gsSGXRegsCPUVAddr, 0, SYS_OMAP3430_SGX_REGS_SIZE); + + + + + gsSGXDeviceMap.ui32IRQ = 0; + +#else + + gsSGXDeviceMap.sRegsSysPBase.uiAddr = SYS_OMAP3430_SGX_REGS_SYS_PHYS_BASE; + gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); + gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE; + + gsSGXDeviceMap.ui32IRQ = SYS_OMAP3430_SGX_IRQ; + +#endif + +#if defined(PDUMP) + { + static IMG_CHAR pszPDumpDevName[] = "SGXMEM"; + gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName; + } +#endif + + + return PVRSRV_OK; +} + + +IMG_CHAR *SysCreateVersionString(IMG_CPU_PHYADDR sRegRegion) +{ + static IMG_CHAR aszVersionString[100]; + SYS_DATA *psSysData; + IMG_UINT32 ui32SGXRevision; + IMG_INT32 i32Count; +#if !defined(NO_HARDWARE) + IMG_VOID *pvRegsLinAddr; + + pvRegsLinAddr = OSMapPhysToLin(sRegRegion, + SYS_OMAP3430_SGX_REGS_SIZE, + PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, + IMG_NULL); + if(!pvRegsLinAddr) + { + return IMG_NULL; + } + + ui32SGXRevision = OSReadHWReg((IMG_PVOID)((IMG_PBYTE)pvRegsLinAddr), + EUR_CR_CORE_REVISION); +#else + ui32SGXRevision = 0; +#endif + + SysAcquireData(&psSysData); + + i32Count = OSSNPrintf(aszVersionString, 100, + "SGX revision = %u.%u.%u", + (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAJOR_MASK) + >> EUR_CR_CORE_REVISION_MAJOR_SHIFT), + (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MINOR_MASK) + >> EUR_CR_CORE_REVISION_MINOR_SHIFT), + (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAINTENANCE_MASK) + >> EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT) + ); + +#if !defined(NO_HARDWARE) + OSUnMapPhysToLin(pvRegsLinAddr, + SYS_OMAP3430_SGX_REGS_SIZE, + PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, + IMG_NULL); +#endif + + if(i32Count == -1) + { + return IMG_NULL; + } + + return aszVersionString; +} + + +PVRSRV_ERROR SysInitialise(IMG_VOID) +{ + IMG_UINT32 i; + PVRSRV_ERROR eError; + PVRSRV_DEVICE_NODE *psDeviceNode; + IMG_CPU_PHYADDR TimerRegPhysBase; +#if !defined(SGX_DYNAMIC_TIMING_INFO) + SGX_TIMING_INFORMATION* psTimingInfo; +#endif + gpsSysData = &gsSysData; + OSMemSet(gpsSysData, 0, sizeof(SYS_DATA)); + + gpsSysSpecificData = &gsSysSpecificData; + OSMemSet(gpsSysSpecificData, 0, sizeof(SYS_SPECIFIC_DATA)); + + gpsSysData->pvSysSpecificData = gpsSysSpecificData; + + eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure")); + (IMG_VOID)SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA); + + gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT; + + + for(i=0; i<SYS_DEVICE_COUNT; i++) + { + gpsSysData->sDeviceID[i].uiID = i; + gpsSysData->sDeviceID[i].bInUse = IMG_FALSE; + } + + gpsSysData->psDeviceNodeList = IMG_NULL; + gpsSysData->psQueueList = IMG_NULL; + + eError = SysInitialiseCommon(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon")); + (IMG_VOID)SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + 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; + psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; + psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + psTimingInfo->bEnableActivePM = IMG_TRUE; +#else + psTimingInfo->bEnableActivePM = IMG_FALSE; +#endif + psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; + psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; +#endif + + + + gpsSysSpecificData->ui32SrcClockDiv = 3; + + + + + + eError = SysLocateDevices(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices")); + (IMG_VOID)SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV); + +#if defined(SGX_OCP_REGS_ENABLED) + { + 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); + } +#endif + + + eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice, + DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!")); + (IMG_VOID)SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REGDEV); + + + + + + psDeviceNode = gpsSysData->psDeviceNodeList; + while(psDeviceNode) + { + + switch(psDeviceNode->sDevId.eDeviceType) + { + case PVRSRV_DEVICE_TYPE_SGX: + { + DEVICE_MEMORY_INFO *psDevMemoryInfo; + DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; + + + + + psDeviceNode->psLocalDevMemArena = IMG_NULL; + + + psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; + psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; + + + for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++) + { + psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG; + } + + gpsSGXDevNode = psDeviceNode; + gsSysSpecificData.psSGXDevNode = psDeviceNode; + + break; + } + default: + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!")); + return PVRSRV_ERROR_INIT_FAILURE; + } + + + psDeviceNode = psDeviceNode->psNext; + } + + eError = EnableSystemClocksWrap(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable system clocks (%d)", eError)); + (IMG_VOID)SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + eError = EnableSGXClocksWrap(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError)); + (IMG_VOID)SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } +#endif + + dump_omap34xx_clocks(); + + eError = PVRSRVInitialiseDevice(gui32SGXDeviceID); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!")); + (IMG_VOID)SysDeinitialise(gpsSysData); + gpsSysData = IMG_NULL; + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV); + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + + DisableSGXClocks(gpsSysData); +#endif + + return PVRSRV_OK; +} + + +PVRSRV_ERROR SysFinalise(IMG_VOID) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + eError = EnableSGXClocksWrap(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError)); + return eError; + } +#endif + + eError = OSInstallMISR(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install MISR")); + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR); + +#if defined(SYS_USING_INTERRUPTS) + + eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install ISR")); + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); +#endif + + + gpsSysData->pszVersionString = SysCreateVersionString(gsSGXDeviceMap.sRegsCpuPBase); + 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)); + } + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + + DisableSGXClocks(gpsSysData); +#endif + + gpsSysSpecificData->bSGXInitComplete = IMG_TRUE; + + return eError; +} + + +PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) +{ + PVRSRV_ERROR eError; + +#if defined(SYS_USING_INTERRUPTS) + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) + { + eError = OSUninstallDeviceLISR(psSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallDeviceLISR failed")); + return eError; + } + } +#endif + + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR)) + { + eError = OSUninstallMISR(psSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallMISR failed")); + return eError; + } + } + + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV)) + { +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + PVR_ASSERT(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)); + + eError = EnableSGXClocksWrap(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: EnableSGXClocks failed")); + return eError; + } +#endif + + + eError = PVRSRVDeinitialiseDevice (gui32SGXDeviceID); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init the device")); + return eError; + } + } + +#if defined(SGX_OCP_REGS_ENABLED) + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_OCPREGS)) + { + OSUnMapPhysToLin(gpvOCPRegsLinAddr, + SYS_OMAP3430_OCP_REGS_SIZE, + PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, + IMG_NULL); + } +#endif + + + + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) + { + DisableSystemClocks(gpsSysData); + } + + if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA)) + { + eError = OSDeInitEnvData(gpsSysData->pvEnvSpecificData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init env structure")); + return eError; + } + } + + 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)) + { + + OSBaseFreeContigMemory(SYS_OMAP3430_SGX_REGS_SIZE, gsSGXRegsCPUVAddr, gsSGXDeviceMap.sRegsCpuPBase); + } +#endif + + + gpsSysSpecificData->ui32SysSpecificData = 0; + gpsSysSpecificData->bSGXInitComplete = IMG_FALSE; + + gpsSysData = IMG_NULL; + + return PVRSRV_OK; +} + + +PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType, + IMG_VOID **ppvDeviceMap) +{ + + switch(eDeviceType) + { + case PVRSRV_DEVICE_TYPE_SGX: + { + + *ppvDeviceMap = (IMG_VOID*)&gsSGXDeviceMap; + + break; + } + default: + { + PVR_DPF((PVR_DBG_ERROR,"SysGetDeviceMemoryMap: unsupported device type")); + } + } + return PVRSRV_OK; +} + + +IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, + IMG_CPU_PHYADDR CpuPAddr) +{ + IMG_DEV_PHYADDR DevPAddr; + + PVR_UNREFERENCED_PARAMETER(eDeviceType); + + + DevPAddr.uiAddr = CpuPAddr.uiAddr; + + return DevPAddr; +} + +IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR sys_paddr) +{ + IMG_CPU_PHYADDR cpu_paddr; + + + cpu_paddr.uiAddr = sys_paddr.uiAddr; + return cpu_paddr; +} + +IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr) +{ + IMG_SYS_PHYADDR sys_paddr; + + + sys_paddr.uiAddr = cpu_paddr.uiAddr; + return sys_paddr; +} + + +IMG_DEV_PHYADDR SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr) +{ + IMG_DEV_PHYADDR DevPAddr; + + PVR_UNREFERENCED_PARAMETER(eDeviceType); + + + DevPAddr.uiAddr = SysPAddr.uiAddr; + + return DevPAddr; +} + + +IMG_SYS_PHYADDR SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR DevPAddr) +{ + IMG_SYS_PHYADDR SysPAddr; + + PVR_UNREFERENCED_PARAMETER(eDeviceType); + + + SysPAddr.uiAddr = DevPAddr.uiAddr; + + return SysPAddr; +} + + +IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) +{ + PVR_UNREFERENCED_PARAMETER(psDeviceNode); +} + + +IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) +{ + PVR_UNREFERENCED_PARAMETER(psDeviceNode); +} + + +IMG_UINT32 SysGetInterruptSource(SYS_DATA *psSysData, + PVRSRV_DEVICE_NODE *psDeviceNode) +{ + PVR_UNREFERENCED_PARAMETER(psSysData); +#if defined(NO_HARDWARE) + + return 0xFFFFFFFF; +#else + + return psDeviceNode->ui32SOCInterruptBit; +#endif +} + + +IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits) +{ + PVR_UNREFERENCED_PARAMETER(psSysData); + PVR_UNREFERENCED_PARAMETER(ui32ClearBits); + + + OSReadHWReg(((PVRSRV_SGXDEV_INFO *)gpsSGXDevNode->pvDevice)->pvRegsBaseKM, + EUR_CR_EVENT_HOST_CLEAR); +} + + +PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + if (eNewPowerState == PVRSRV_SYS_POWER_STATE_D3) + { + PVR_TRACE(("SysSystemPrePowerState: Entering state D3")); + +#if defined(SYS_USING_INTERRUPTS) + if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) + { +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) + IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData); +#endif + eError = OSUninstallDeviceLISR(gpsSysData); +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) + if (bWrapped) + { + UnwrapSystemPowerChange(&gsSysSpecificData); + } +#endif + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysSystemPrePowerState: OSUninstallDeviceLISR failed (%d)", eError)); + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); + SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); + } +#endif + + if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) + { + DisableSystemClocks(gpsSysData); + + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS); + SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); + } + } + + return eError; +} + + +PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + if (eNewPowerState == PVRSRV_SYS_POWER_STATE_D0) + { + PVR_TRACE(("SysSystemPostPowerState: Entering state D0")); + + if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS)) + { + eError = EnableSystemClocksWrap(gpsSysData); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: EnableSystemClocksWrap failed (%d)", eError)); + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); + SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS); + } + +#if defined(SYS_USING_INTERRUPTS) + if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR)) + { +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) + IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData); +#endif + + eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); +#if defined(SYS_CUSTOM_POWERLOCK_WRAP) + if (bWrapped) + { + UnwrapSystemPowerChange(&gsSysSpecificData); + } +#endif + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: OSInstallDeviceLISR failed to install ISR (%d)", eError)); + return eError; + } + SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); + SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); + } +#endif + } + return eError; +} + + +PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex, + PVRSRV_DEV_POWER_STATE eNewPowerState, + PVRSRV_DEV_POWER_STATE eCurrentPowerState) +{ + PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); + + if (ui32DeviceIndex != gui32SGXDeviceID) + { + return PVRSRV_OK; + } + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF) + { + PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePrePowerState: SGX Entering state D3")); + DisableSGXClocks(gpsSysData); + } +#else + PVR_UNREFERENCED_PARAMETER(eNewPowerState ); +#endif + return PVRSRV_OK; +} + + +PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex, + PVRSRV_DEV_POWER_STATE eNewPowerState, + PVRSRV_DEV_POWER_STATE eCurrentPowerState) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + + PVR_UNREFERENCED_PARAMETER(eNewPowerState); + + if (ui32DeviceIndex != gui32SGXDeviceID) + { + return eError; + } + +#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) + if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF) + { + PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePostPowerState: SGX Leaving state D3")); + eError = EnableSGXClocksWrap(gpsSysData); + } +#else + PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); +#endif + + return eError; +} + + +PVRSRV_ERROR SysOEMFunction ( IMG_UINT32 ui32ID, + IMG_VOID *pvIn, + IMG_UINT32 ulInSize, + IMG_VOID *pvOut, + IMG_UINT32 ulOutSize) +{ + PVR_UNREFERENCED_PARAMETER(ui32ID); + PVR_UNREFERENCED_PARAMETER(pvIn); + PVR_UNREFERENCED_PARAMETER(ulInSize); + PVR_UNREFERENCED_PARAMETER(pvOut); + PVR_UNREFERENCED_PARAMETER(ulOutSize); + + 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; + } + + return PVRSRV_ERROR_INVALID_PARAMS; +} |