| /********************************************************************** |
| * |
| * 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; |
| } |