static IMG_VOID Init_IRQ_CTRL(PLAT_DATA *psPlatData) { IMG_CPU_PHYADDR sICRCpuPBase; IMG_VOID *pvICRCpuVBase; IMG_UINT32 ui32Value; /* Map into CPU address space */ sICRCpuPBase.uiAddr = IMG_CAST_TO_CPUPHYADDR_UINT(psPlatData->uiICRCpuPAddr); pvICRCpuVBase = OSMapPhysToLin(sICRCpuPBase, psPlatData->uiICRSize, 0); /* Configure IRQ_CTRL: For Rogue, enable IRQ, set sense to active low */ ui32Value = OSReadHWReg32(pvICRCpuVBase, EMULATOR_RGX_ICR_REG_IRQ_CTRL); ui32Value &= ~EMULATOR_RGX_ICR_REG_IRQ_CTRL_IRQ_HINLO; ui32Value |= EMULATOR_RGX_ICR_REG_IRQ_CTRL_IRQ_EN; OSWriteHWReg32(pvICRCpuVBase,EMULATOR_RGX_ICR_REG_IRQ_CTRL, ui32Value); /* Flush register write */ (void) OSReadHWReg32(pvICRCpuVBase, EMULATOR_RGX_ICR_REG_IRQ_CTRL); OSWaitus(10); PVR_TRACE(("Emulator FPGA image version (ICR_REG_CORE_REVISION): 0x%08x", OSReadHWReg32(pvICRCpuVBase, EMULATOR_RGX_ICR_REG_CORE_REVISION))); /* Unmap from CPU address space */ OSUnMapPhysToLin(pvICRCpuVBase, psPlatData->uiICRSize, 0); }
/*! ****************************************************************************** @Function SysCreateVersionString @Description Read the version string @Return IMG_CHAR * : Version string ******************************************************************************/ static IMG_CHAR *SysCreateVersionString(void) { static IMG_CHAR aszVersionString[100]; SYS_DATA *psSysData; IMG_UINT32 ui32SGXRevision; IMG_INT32 i32Count; #if !defined(NO_HARDWARE) IMG_VOID *pvRegsLinAddr; pvRegsLinAddr = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase, gsSGXDeviceMap.ui32RegsSize, PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, IMG_NULL); if(!pvRegsLinAddr) { return IMG_NULL; } #if SGX_CORE_REV == 105 ui32SGXRevision = 0x10005; #else ui32SGXRevision = OSReadHWReg((IMG_PVOID)((IMG_PBYTE)pvRegsLinAddr), EUR_CR_CORE_REVISION); #endif #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_OMAP5430_SGX_REGS_SIZE, PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, IMG_NULL); #endif if(i32Count == -1) { return IMG_NULL; } return aszVersionString; }
IMG_VOID DisableSystemClocks(SYS_DATA *psSysData) { SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; IMG_BOOL bPowerLock; #if defined(DEBUG) || defined(TIMING) IMG_CPU_PHYADDR TimerRegPhysBase; IMG_HANDLE hTimerDisable; IMG_UINT32 *pui32TimerDisable; #endif PVR_TRACE(("DisableSystemClocks: Disabling System Clocks")); DisableSGXClocks(psSysData); bPowerLock = PowerLockWrappedOnCPU(psSysSpecData); if (bPowerLock) { PowerLockUnwrap(psSysSpecData); } #if defined(DEBUG) || defined(TIMING) TimerRegPhysBase.uiAddr = SYS_OMAP3430_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); } clk_disable(psSysSpecData->psGPT11_ICK); clk_disable(psSysSpecData->psGPT11_FCK); #endif if (bPowerLock) { PowerLockWrap(psSysSpecData); } }
/*! ****************************************************************************** @Function ReleaseGPTimer @Description Release a GP timer @Return PVRSRV_ERROR ******************************************************************************/ static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) { IMG_HANDLE hTimerDisable; IMG_UINT32 *pui32TimerDisable; IMG_CPU_PHYADDR TimerRegPhysBase; #if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) if (psSysSpecData->sTimerRegPhysBase.uiAddr == 0) { return; } #endif /* Disable the timer */ 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_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) psSysSpecData->sTimerRegPhysBase.uiAddr = 0; #endif #if defined(PVR_OMAP4_TIMING_PRCM) #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) clk_disable(psSysSpecData->psGPT11_ICK); #endif clk_disable(psSysSpecData->psGPT11_FCK); #endif /* defined(PVR_OMAP4_TIMING_PRCM) */ }
PVRSRV_ERROR SysDebugInfo(PVRSRV_SYSTEM_CONFIG *psSysConfig) { PVRSRV_DEVICE_CONFIG *psDevice; IMG_CPU_PHYADDR sWrapperRegsCpuPBase; IMG_VOID *pvWrapperRegs; psDevice = &sSysConfig.pasDevices[0]; sWrapperRegsCpuPBase.uiAddr = psDevice->sRegsCpuPBase.uiAddr + EMULATOR_RGX_REG_WRAPPER_OFFSET; /* map emu registers */ pvWrapperRegs = OSMapPhysToLin(sWrapperRegsCpuPBase, EMULATOR_RGX_REG_WRAPPER_SIZE, 0); if (pvWrapperRegs == IMG_NULL) { PVR_DPF((PVR_DBG_ERROR,"SysDebugDump: Failed to create wrapper register mapping\n")); return PVRSRV_ERROR_BAD_MAPPING; } PVR_LOG(("------[ System Debug ]------")); #define SYS_EMU_DBG_R32(R) PVR_LOG(("%-25s 0x%08X", #R ":", OSReadHWReg32(pvWrapperRegs, R))) #define SYS_EMU_DBG_R64(R) PVR_LOG(("%-25s 0x%010llX", #R ":", OSReadHWReg64(pvWrapperRegs, R))) SYS_EMU_DBG_R32(EMU_CR_PCI_MASTER); SYS_EMU_DBG_R64(EMU_CR_WRAPPER_ERROR); SYS_EMU_DBG_R32(EMU_CR_BANK_OUTSTANDING0); SYS_EMU_DBG_R32(EMU_CR_BANK_OUTSTANDING1); SYS_EMU_DBG_R32(EMU_CR_BANK_OUTSTANDING2); SYS_EMU_DBG_R32(EMU_CR_BANK_OUTSTANDING3); SYS_EMU_DBG_R32(EMU_CR_MEMORY_LATENCY); /* remove mapping */ OSUnMapPhysToLin(pvWrapperRegs, EMULATOR_RGX_REG_WRAPPER_SIZE, 0); return PVRSRV_OK; }
static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) { IMG_HANDLE hTimerDisable; IMG_UINT32 *pui32TimerDisable; IMG_CPU_PHYADDR TimerRegPhysBase; #if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) if (psSysSpecData->sTimerRegPhysBase.uiAddr == 0) { return; } #endif TimerRegPhysBase.uiAddr = SYS_TI335x_GP7TIMER_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_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) psSysSpecData->sTimerRegPhysBase.uiAddr = 0; #endif #if defined(PVR_OMAP3_TIMING_PRCM) clk_disable(psSysSpecData->psGPT11_ICK); clk_disable(psSysSpecData->psGPT11_FCK); #endif }
static PVRSRV_ERROR SysMapInRegisters(IMG_VOID) { PVRSRV_DEVICE_NODE *psDeviceNodeList; /* Map the Atlas and PDP registers. */ gpsSysData->pvSOCRegsBase = OSMapPhysToLin(gsSOCRegsCpuPBase, SYS_ATLAS_REG_REGION_SIZE, PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, IMG_NULL); if (gpsSysData->pvSOCRegsBase == IMG_NULL) { PVR_DPF((PVR_DBG_ERROR,"SysPrePowerState: Failed to map SOC Register base")); return PVRSRV_ERROR_REGISTER_BASE_NOT_SET; } psDeviceNodeList = gpsSysData->psDeviceNodeList; while (psDeviceNodeList) { PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNodeList->pvDevice; if (psDeviceNodeList->sDevId.eDeviceType == PVRSRV_DEVICE_TYPE_SGX) { #if defined(NO_HARDWARE) && defined(__linux__) /* * SysLocateDevices will have reallocated the dummy * registers. */ PVR_ASSERT(gsSGXRegsCPUVAddr); psDevInfo->pvRegsBaseKM = gsSGXRegsCPUVAddr; #else if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS)) { /* Remap Regs */ psDevInfo->pvRegsBaseKM = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase, gsSGXDeviceMap.ui32RegsSize, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); if (!psDevInfo->pvRegsBaseKM) { PVR_DPF((PVR_DBG_ERROR,"SysMapInRegisters : Failed to map in regs\n")); return PVRSRV_ERROR_BAD_MAPPING; } SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS); } #endif /* #if defined(NO_HARDWARE) && defined(__linux__) */ psDevInfo->ui32RegSize = gsSGXDeviceMap.ui32RegsSize; psDevInfo->sRegsPhysBase = gsSGXDeviceMap.sRegsSysPBase; #if defined(SGX_FEATURE_HOST_PORT) if (gsSGXDeviceMap.ui32Flags & SGX_HOSTPORT_PRESENT) { if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_HP)) { /* Map Host Port */ psDevInfo->pvHostPortBaseKM = OSMapPhysToLin(gsSGXDeviceMap.sHPCpuPBase, gsSGXDeviceMap.ui32HPSize, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); if (!psDevInfo->pvHostPortBaseKM) { PVR_DPF((PVR_DBG_ERROR,"SysMapInRegisters : Failed to map in host port\n")); return PVRSRV_ERROR_BAD_MAPPING; } SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_HP); } psDevInfo->ui32HPSize = gsSGXDeviceMap.ui32HPSize; psDevInfo->sHPSysPAddr = gsSGXDeviceMap.sHPSysPBase; } #endif /* #if defined(SGX_FEATURE_HOST_PORT) */ } psDeviceNodeList = psDeviceNodeList->psNext; } return PVRSRV_OK; }
/*! ****************************************************************************** @Function AcquireGPTimer @Description Acquire a GP timer @Return PVRSRV_ERROR ******************************************************************************/ static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) { #if defined(PVR_OMAP4_TIMING_PRCM) struct clk *psCLK; IMG_INT res; struct clk *sys_ck; IMG_INT rate; #endif PVRSRV_ERROR eError; IMG_CPU_PHYADDR sTimerRegPhysBase; IMG_HANDLE hTimerEnable; IMG_UINT32 *pui32TimerEnable; PVR_ASSERT(psSysSpecData->sTimerRegPhysBase.uiAddr == 0); psCLK = clk_get(NULL, "sgx_fck"); if (IS_ERR(psCLK)) { PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get SGX Interface Clock")); return; } clk_enable(psCLK); psCLK = clk_get(NULL, "sgx_ick"); if (IS_ERR(psCLK)) { PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get SGX Interface Clock")); return; } clk_enable(psCLK); #if defined(PVR_OMAP4_TIMING_PRCM) psCLK = clk_get(NULL, "gpt6_fck"); if (IS_ERR(psCLK)) { PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock")); goto ExitError; } psSysSpecData->psGPT11_FCK = psCLK; psCLK = clk_get(NULL, "gpt6_ick"); if (IS_ERR(psCLK)) { PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: 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 ExitError; } 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 ExitError; } } 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 ExitError; } 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 /* defined(PVR_OMAP4_TIMING_PRCM) */ /* Set the timer to non-posted mode */ sTimerRegPhysBase.uiAddr = SYS_OMAP4430_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")); goto ExitDisableGPT11ICK; } if(!(*pui32TimerEnable & 4)) { PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)")); /* Set posted mode */ *pui32TimerEnable |= 4; } OSUnMapPhysToLin(pui32TimerEnable, 4, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, hTimerEnable); /* Enable the timer */ sTimerRegPhysBase.uiAddr = SYS_OMAP4430_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")); goto ExitDisableGPT11ICK; } /* Enable and set autoreload on overflow */ *pui32TimerEnable = 3; OSUnMapPhysToLin(pui32TimerEnable, 4, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, hTimerEnable); psSysSpecData->sTimerRegPhysBase = sTimerRegPhysBase; eError = PVRSRV_OK; goto Exit; ExitDisableGPT11ICK: #if defined(PVR_OMAP4_TIMING_PRCM) clk_disable(psSysSpecData->psGPT11_ICK); ExitDisableGPT11FCK: clk_disable(psSysSpecData->psGPT11_FCK); ExitError: #endif /* defined(PVR_OMAP4_TIMING_PRCM) */ eError = PVRSRV_ERROR_CLOCK_REQUEST_FAILED; Exit: return eError; }
static IMG_BOOL _DeferredAllocPagetables(struct MMU_HEAP *pMMUHeap, struct IMG_DEV_VIRTADDR DevVAddr, u32 ui32Size) { u32 ui32PTPageCount; u32 ui32PDIndex; u32 i; u32 *pui32PDEntry; struct MMU_PT_INFO **ppsPTInfoList; struct SYS_DATA *psSysData; struct IMG_DEV_VIRTADDR sHighDevVAddr; PVR_ASSERT(DevVAddr.uiAddr < (1 << SGX_FEATURE_ADDRESS_SPACE_SIZE)); if (SysAcquireData(&psSysData) != PVRSRV_OK) return IMG_FALSE; ui32PDIndex = DevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); if ((UINT32_MAX_VALUE - DevVAddr.uiAddr) < (ui32Size + (1 << (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT)) - 1)) { sHighDevVAddr.uiAddr = UINT32_MAX_VALUE; } else { sHighDevVAddr.uiAddr = DevVAddr.uiAddr + ui32Size + (1 << (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT)) - 1; } ui32PTPageCount = sHighDevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); ui32PTPageCount -= ui32PDIndex; pui32PDEntry = (u32 *) pMMUHeap->psMMUContext->pvPDCpuVAddr; pui32PDEntry += ui32PDIndex; ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex]; PDUMPCOMMENT("Alloc page table (page count == %08X)", ui32PTPageCount); PDUMPCOMMENT("Page directory mods (page count == %08X)", ui32PTPageCount); for (i = 0; i < ui32PTPageCount; i++) { if (ppsPTInfoList[i] == NULL) { if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct MMU_PT_INFO), (void **) &ppsPTInfoList[i], NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "_DeferredAllocPagetables: " "ERROR call to OSAllocMem failed"); return IMG_FALSE; } OSMemSet(ppsPTInfoList[i], 0, sizeof(struct MMU_PT_INFO)); } if (ppsPTInfoList[i]->hPTPageOSMemHandle == NULL && ppsPTInfoList[i]->PTPageCpuVAddr == NULL) { struct IMG_CPU_PHYADDR sCpuPAddr; struct IMG_DEV_PHYADDR sDevPAddr; PVR_ASSERT(pui32PDEntry[i] == 0); if (pMMUHeap->psDevArena->psDeviceMemoryHeapInfo-> psLocalDevMemArena == NULL) { if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, SGX_MMU_PAGE_SIZE, SGX_MMU_PAGE_SIZE, (void **)&ppsPTInfoList[i]-> PTPageCpuVAddr, &ppsPTInfoList[i]-> hPTPageOSMemHandle) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "_DeferredAllocPagetables: " "ERROR call to OSAllocPages failed"); return IMG_FALSE; } if (ppsPTInfoList[i]->PTPageCpuVAddr) { sCpuPAddr = OSMapLinToCPUPhys(ppsPTInfoList[i]-> PTPageCpuVAddr); } else { sCpuPAddr = OSMemHandleToCpuPAddr( ppsPTInfoList[i]-> hPTPageOSMemHandle, 0); } sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); } else { struct IMG_SYS_PHYADDR sSysPAddr; if (RA_Alloc(pMMUHeap->psDevArena-> psDeviceMemoryHeapInfo->psLocalDevMemArena, SGX_MMU_PAGE_SIZE, NULL, 0, SGX_MMU_PAGE_SIZE, &(sSysPAddr.uiAddr)) != IMG_TRUE) { PVR_DPF(PVR_DBG_ERROR, "_DeferredAllocPagetables: " "ERROR call to RA_Alloc failed"); return IMG_FALSE; } sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); ppsPTInfoList[i]->PTPageCpuVAddr = (void __force *) OSMapPhysToLin(sCpuPAddr, SGX_MMU_PAGE_SIZE, PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, &ppsPTInfoList[i]-> hPTPageOSMemHandle); if (!ppsPTInfoList[i]->PTPageCpuVAddr) { PVR_DPF(PVR_DBG_ERROR, "_DeferredAllocPagetables: " "ERROR failed to map page tables"); return IMG_FALSE; } sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); } OSMemSet(ppsPTInfoList[i]->PTPageCpuVAddr, 0, SGX_MMU_PAGE_SIZE); PDUMPMALLOCPAGETABLE(ppsPTInfoList[i]->PTPageCpuVAddr, PDUMP_PT_UNIQUETAG); PDUMPPAGETABLE(ppsPTInfoList[i]->PTPageCpuVAddr, SGX_MMU_PAGE_SIZE, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG); switch (pMMUHeap->psDevArena->DevMemHeapType) { case DEVICE_MEMORY_HEAP_SHARED: case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: { struct MMU_CONTEXT *psMMUContext = (struct MMU_CONTEXT *)pMMUHeap-> psMMUContext->psDevInfo-> pvMMUContextList; while (psMMUContext) { pui32PDEntry = (u32 *)psMMUContext-> pvPDCpuVAddr; pui32PDEntry += ui32PDIndex; pui32PDEntry[i] = sDevPAddr.uiAddr | SGX_MMU_PDE_VALID; PDUMPPAGETABLE ((void *)&pui32PDEntry[i], sizeof(u32), IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); psMMUContext = psMMUContext->psNext; } break; } case DEVICE_MEMORY_HEAP_PERCONTEXT: case DEVICE_MEMORY_HEAP_KERNEL: { pui32PDEntry[i] = sDevPAddr.uiAddr | SGX_MMU_PDE_VALID; PDUMPPAGETABLE((void *)&pui32PDEntry[i], sizeof(u32), IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); break; } default: { PVR_DPF(PVR_DBG_ERROR, "_DeferredAllocPagetables: " "ERROR invalid heap type"); return IMG_FALSE; } } MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext-> psDevInfo); } else { PVR_ASSERT(pui32PDEntry[i] != 0); } } return IMG_TRUE; }
static IMG_BOOL ZeroBuf(BM_BUF *pBuf, BM_MAPPING *pMapping, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags) { IMG_VOID *pvCpuVAddr; if(pBuf->CpuVAddr) { OSMemSet(pBuf->CpuVAddr, 0, ui32Bytes); } else if(pMapping->eCpuMemoryOrigin == hm_contiguous || pMapping->eCpuMemoryOrigin == hm_wrapped) { pvCpuVAddr = OSMapPhysToLin(pBuf->CpuPAddr, ui32Bytes, PVRSRV_HAP_KERNEL_ONLY | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK), IMG_NULL); if(!pvCpuVAddr) { PVR_DPF((PVR_DBG_ERROR, "ZeroBuf: OSMapPhysToLin for contiguous buffer failed")); return IMG_FALSE; } OSMemSet(pvCpuVAddr, 0, ui32Bytes); OSUnMapPhysToLin(pvCpuVAddr, ui32Bytes, PVRSRV_HAP_KERNEL_ONLY | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK), IMG_NULL); } else { IMG_SIZE_T ui32BytesRemaining = ui32Bytes; IMG_SIZE_T ui32CurrentOffset = 0; IMG_CPU_PHYADDR CpuPAddr; PVR_ASSERT(pBuf->hOSMemHandle); while(ui32BytesRemaining > 0) { IMG_SIZE_T ui32BlockBytes = MIN(ui32BytesRemaining, HOST_PAGESIZE()); CpuPAddr = OSMemHandleToCpuPAddr(pBuf->hOSMemHandle, ui32CurrentOffset); if(CpuPAddr.uiAddr & (HOST_PAGESIZE() -1)) { ui32BlockBytes = MIN(ui32BytesRemaining, (IMG_UINT32)(HOST_PAGEALIGN(CpuPAddr.uiAddr) - CpuPAddr.uiAddr)); } pvCpuVAddr = OSMapPhysToLin(CpuPAddr, ui32BlockBytes, PVRSRV_HAP_KERNEL_ONLY | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK), IMG_NULL); if(!pvCpuVAddr) { PVR_DPF((PVR_DBG_ERROR, "ZeroBuf: OSMapPhysToLin while zeroing non-contiguous memory FAILED")); return IMG_FALSE; } OSMemSet(pvCpuVAddr, 0, ui32BlockBytes); OSUnMapPhysToLin(pvCpuVAddr, ui32BlockBytes, PVRSRV_HAP_KERNEL_ONLY | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK), IMG_NULL); ui32BytesRemaining -= ui32BlockBytes; ui32CurrentOffset += ui32BlockBytes; } } return IMG_TRUE; }
PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData) { SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; struct clk *psCLK; IMG_INT res; PVRSRV_ERROR eError; #if defined(DEBUG) || defined(TIMING) IMG_INT rate; struct clk *sys_ck; 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); 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; } psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE; } #if defined(DEBUG) || defined(TIMING) 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_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; } TimerRegPhysBase.uiAddr = SYS_TI81xx_GP7TIMER_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; } rate = *pui32TimerEnable; if(!(rate & 4)) { PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)")); *pui32TimerEnable = rate | 4; } OSUnMapPhysToLin(pui32TimerEnable, 4, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, hTimerEnable); TimerRegPhysBase.uiAddr = SYS_TI81xx_GP7TIMER_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) ExitDisableGPT11ICK: clk_disable(psSysSpecData->psGPT11_ICK); ExitDisableGPT11FCK: clk_disable(psSysSpecData->psGPT11_FCK); ExitUnRegisterConstraintNotifications: #endif ExitError: eError = PVRSRV_ERROR_DISABLE_CLOCK_FAILURE; Exit: return eError; }
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; if (mpu_opps[vdd1_max_level].rate == MAX_FREQ_ES_1_2) { psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED_ES_1_2; } else { 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; }
/*! ****************************************************************************** @Function PVRSRVSaveRestoreLiveSegments @Input pArena - the arena the segment was originally allocated from. pbyBuffer - the system memory buffer set to null to get the size needed. puiBufSize - size of system memory buffer. bSave - IMG_TRUE if a save is required @Description Function to save or restore Resources Live segments ******************************************************************************/ PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer, IMG_SIZE_T *puiBufSize, IMG_BOOL bSave) { IMG_SIZE_T uiBytesSaved = 0; IMG_PVOID pvLocalMemCPUVAddr; RA_SEGMENT_DETAILS sSegDetails; if (hArena == IMG_NULL) { return (PVRSRV_ERROR_INVALID_PARAMS); } sSegDetails.uiSize = 0; sSegDetails.sCpuPhyAddr.uiAddr = 0; sSegDetails.hSegment = 0; /* walk the arena segments and write live one to the buffer */ while (RA_GetNextLiveSegment(hArena, &sSegDetails)) { if (pbyBuffer == IMG_NULL) { /* calc buffer required */ uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize; } else { if ((uiBytesSaved + sizeof(sSegDetails.uiSize) + sSegDetails.uiSize) > *puiBufSize) { return (PVRSRV_ERROR_OUT_OF_MEMORY); } PVR_DPF(( PVR_DBG_MESSAGE, "PVRSRVSaveRestoreLiveSegments: Base " CPUPADDR_FMT " size %" SIZE_T_FMT_LEN "x", sSegDetails.sCpuPhyAddr.uiAddr, sSegDetails.uiSize)); /* Map the device's local memory area onto the host. */ pvLocalMemCPUVAddr = OSMapPhysToLin(sSegDetails.sCpuPhyAddr, sSegDetails.uiSize, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); if (pvLocalMemCPUVAddr == IMG_NULL) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Failed to map local memory to host")); return (PVRSRV_ERROR_OUT_OF_MEMORY); } if (bSave) { /* write segment size then segment data */ OSMemCopy(pbyBuffer, &sSegDetails.uiSize, sizeof(sSegDetails.uiSize)); pbyBuffer += sizeof(sSegDetails.uiSize); OSMemCopy(pbyBuffer, pvLocalMemCPUVAddr, sSegDetails.uiSize); pbyBuffer += sSegDetails.uiSize; } else { IMG_UINT32 uiSize; /* reag segment size and validate */ OSMemCopy(&uiSize, pbyBuffer, sizeof(sSegDetails.uiSize)); if (uiSize != sSegDetails.uiSize) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Segment size error")); } else { pbyBuffer += sizeof(sSegDetails.uiSize); OSMemCopy(pvLocalMemCPUVAddr, pbyBuffer, sSegDetails.uiSize); pbyBuffer += sSegDetails.uiSize; } } uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize; OSUnMapPhysToLin(pvLocalMemCPUVAddr, sSegDetails.uiSize, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); } } if (pbyBuffer == IMG_NULL) { *puiBufSize = uiBytesSaved; } return (PVRSRV_OK); }
enum PVRSRV_ERROR PVRSRVSaveRestoreLiveSegments(void *hArena, u8 *pbyBuffer, u32 *puiBufSize, IMG_BOOL bSave) { u32 uiBytesSaved = 0; void *pvLocalMemCPUVAddr; struct RA_SEGMENT_DETAILS sSegDetails; if (hArena == NULL) return PVRSRV_ERROR_INVALID_PARAMS; sSegDetails.uiSize = 0; sSegDetails.sCpuPhyAddr.uiAddr = 0; sSegDetails.hSegment = NULL; while (RA_GetNextLiveSegment(hArena, &sSegDetails)) if (pbyBuffer == NULL) { uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize; } else { if ((uiBytesSaved + sizeof(sSegDetails.uiSize) + sSegDetails.uiSize) > *puiBufSize) return PVRSRV_ERROR_OUT_OF_MEMORY; PVR_DPF(PVR_DBG_MESSAGE, "PVRSRVSaveRestoreLiveSegments: " "Base %08x size %08x", sSegDetails.sCpuPhyAddr.uiAddr, sSegDetails.uiSize); pvLocalMemCPUVAddr = (void __force *) OSMapPhysToLin(sSegDetails.sCpuPhyAddr, sSegDetails.uiSize, PVRSRV_HAP_KERNEL_ONLY | PVRSRV_HAP_UNCACHED, NULL); if (pvLocalMemCPUVAddr == NULL) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: " "Failed to map local memory to host"); return PVRSRV_ERROR_OUT_OF_MEMORY; } if (bSave) { OSMemCopy(pbyBuffer, &sSegDetails.uiSize, sizeof(sSegDetails.uiSize)); pbyBuffer += sizeof(sSegDetails.uiSize); OSMemCopy(pbyBuffer, pvLocalMemCPUVAddr, sSegDetails.uiSize); pbyBuffer += sSegDetails.uiSize; } else { u32 uiSize; OSMemCopy(&uiSize, pbyBuffer, sizeof(sSegDetails.uiSize)); if (uiSize != sSegDetails.uiSize) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments:" " Segment size error"); } else { pbyBuffer += sizeof(sSegDetails.uiSize); OSMemCopy(pvLocalMemCPUVAddr, pbyBuffer, sSegDetails.uiSize); pbyBuffer += sSegDetails.uiSize; } } uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize; OSUnMapPhysToLin((void __force __iomem *) pvLocalMemCPUVAddr, sSegDetails.uiSize, PVRSRV_HAP_KERNEL_ONLY | PVRSRV_HAP_UNCACHED, NULL); } if (pbyBuffer == NULL) *puiBufSize = uiBytesSaved; return PVRSRV_OK; }
IMG_VOID DisableSystemClocks(SYS_DATA *psSysData) { SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; IMG_BOOL bPowerLock; #if defined(DEBUG) || defined(TIMING) IMG_CPU_PHYADDR TimerRegPhysBase; IMG_HANDLE hTimerDisable; IMG_UINT32 *pui32TimerDisable; #endif PVR_TRACE(("DisableSystemClocks: Disabling System Clocks")); DisableSGXClocks(psSysData); bPowerLock = PowerLockWrappedOnCPU(psSysSpecData); if (bPowerLock) { PowerLockUnwrap(psSysSpecData); } #if defined(PDUMP) && !defined(NO_HARDWARE) && defined(CONSTRAINT_NOTIFICATIONS) { int res; PVR_TRACE(("DisableSystemClocks: Removing SGX OPP constraint")); res = constraint_remove(psSysSpecData->pVdd2Handle); if (res != 0) { PVR_DPF((PVR_DBG_WARNING, "DisableSystemClocks: constraint_remove failed (%d)", res)); } } #endif #if defined(CONSTRAINT_NOTIFICATIONS) UnRegisterConstraintNotifications(); #endif #if defined(DEBUG) || defined(TIMING) TimerRegPhysBase.uiAddr = SYS_TI81xx_GP7TIMER_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); } clk_disable(psSysSpecData->psGPT11_ICK); clk_disable(psSysSpecData->psGPT11_FCK); #endif #if defined(CONSTRAINT_NOTIFICATIONS) constraint_put(psSysSpecData->pVdd2Handle); #endif if (bPowerLock) { PowerLockWrap(psSysSpecData); } }
PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData) { SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; struct clk *psCLK; IMG_INT res; PVRSRV_ERROR eError; IMG_BOOL bPowerLock; #if defined(DEBUG) || defined(TIMING) IMG_INT rate; struct clk *sys_ck; IMG_CPU_PHYADDR TimerRegPhysBase; IMG_HANDLE hTimerEnable; IMG_UINT32 *pui32TimerEnable; #endif PVR_TRACE(("EnableSystemClocks: Enabling System Clocks")); if (!psSysSpecData->bSysClocksOneTimeInit) { bPowerLock = IMG_FALSE; spin_lock_init(&psSysSpecData->sPowerLock); atomic_set(&psSysSpecData->sPowerLockCPU, -1); spin_lock_init(&psSysSpecData->sNotifyLock); atomic_set(&psSysSpecData->sNotifyLockCPU, -1); atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); psCLK = clk_get(NULL, "sgx_ck"); if (IS_ERR(psCLK)) { PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get SGX Functional Clock")); goto ExitError; } psSysSpecData->psSGX_FCK = psCLK; psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE; } else { bPowerLock = PowerLockWrappedOnCPU(psSysSpecData); if (bPowerLock) { PowerLockUnwrap(psSysSpecData); } } #if defined(CONSTRAINT_NOTIFICATIONS) psSysSpecData->pVdd2Handle = constraint_get(PVRSRV_MODNAME, &cnstr_id_vdd2); if (IS_ERR(psSysSpecData->pVdd2Handle)) { PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get VDD2 constraint handle")); goto ExitError; } RegisterConstraintNotifications(); #endif #if defined(DEBUG) || defined(TIMING) if(cpu_is_ti816x()) { psCLK = clk_get(NULL, "gpt6_fck"); } else { psCLK = clk_get(NULL, "gpt7_fck"); } if (IS_ERR(psCLK)) { PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock")); goto ExitUnRegisterConstraintNotifications; } psSysSpecData->psGPT11_FCK = psCLK; if(cpu_is_ti816x()) { psCLK = clk_get(NULL, "gpt6_ick"); } else { psCLK = clk_get(NULL, "gpt7_ick"); } if (IS_ERR(psCLK)) { PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 interface clock")); goto ExitUnRegisterConstraintNotifications; } psSysSpecData->psGPT11_ICK = psCLK; 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; } TimerRegPhysBase.uiAddr = SYS_TI81xx_GP7TIMER_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; } rate = *pui32TimerEnable; if(!(rate & 4)) { PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)")); *pui32TimerEnable = rate | 4; } OSUnMapPhysToLin(pui32TimerEnable, 4, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, hTimerEnable); TimerRegPhysBase.uiAddr = SYS_TI81xx_GP7TIMER_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 #if defined(PDUMP) && !defined(NO_HARDWARE) && defined(CONSTRAINT_NOTIFICATIONS) PVR_TRACE(("EnableSystemClocks: Setting SGX OPP constraint")); res = constraint_set(psSysSpecData->pVdd2Handle, max_vdd2_opp); if (res != 0) { PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: constraint_set failed (%d)", res)); goto ExitConstraintSetFailed; } #endif eError = PVRSRV_OK; goto Exit; #if defined(PDUMP) && !defined(NO_HARDWARE) && defined(CONSTRAINT_NOTIFICATIONS) ExitConstraintSetFailed: #endif #if defined(DEBUG) || defined(TIMING) ExitDisableGPT11ICK: clk_disable(psSysSpecData->psGPT11_ICK); ExitDisableGPT11FCK: clk_disable(psSysSpecData->psGPT11_FCK); ExitUnRegisterConstraintNotifications: #endif #if defined(CONSTRAINT_NOTIFICATIONS) UnRegisterConstraintNotifications(); constraint_put(psSysSpecData->pVdd2Handle); #endif Exit: if (bPowerLock) { PowerLockWrap(psSysSpecData); } ExitError: eError = PVRSRV_ERROR_DISABLE_CLOCK_FAILURE; return eError; }
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 PVRSRV_ERROR eError; IMG_CPU_PHYADDR sTimerRegPhysBase; IMG_HANDLE hTimerEnable; IMG_UINT32 *pui32TimerEnable; #if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) PVR_ASSERT(psSysSpecData->sTimerRegPhysBase.uiAddr == 0); #endif #if defined(PVR_OMAP3_TIMING_PRCM) psCLK = clk_get(NULL, "gpt7_fck"); if (IS_ERR(psCLK)) { PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock")); goto ExitError; } psSysSpecData->psGPT11_FCK = psCLK; psCLK = clk_get(NULL, "gpt7_ick"); if (IS_ERR(psCLK)) { PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 interface clock")); goto ExitError; } psSysSpecData->psGPT11_ICK = psCLK; 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 ExitError; } 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 sTimerRegPhysBase.uiAddr = SYS_TI335x_GP7TIMER_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")); 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); sTimerRegPhysBase.uiAddr = SYS_TI335x_GP7TIMER_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")); goto ExitDisableGPT11ICK; } *pui32TimerEnable = 3; OSUnMapPhysToLin(pui32TimerEnable, 4, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, hTimerEnable); #if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) psSysSpecData->sTimerRegPhysBase = sTimerRegPhysBase; #endif eError = PVRSRV_OK; goto Exit; ExitDisableGPT11ICK: #if defined(PVR_OMAP3_TIMING_PRCM) clk_disable(psSysSpecData->psGPT11_ICK); ExitDisableGPT11FCK: clk_disable(psSysSpecData->psGPT11_FCK); ExitError: #endif eError = PVRSRV_ERROR_CLOCK_REQUEST_FAILED; Exit: return eError; }
/*! ****************************************************************************** @Function SysInitialise @Description Initialises kernel services at 'driver load' time @Return PVRSRV_ERROR : ******************************************************************************/ PVRSRV_ERROR SysInitialise(IMG_VOID) { IMG_UINT32 i; PVRSRV_ERROR eError; PVRSRV_DEVICE_NODE *psDeviceNode; SGX_TIMING_INFORMATION* psTimingInfo; gpsSysData = &gsSysData; OSMemSet(gpsSysData, 0, sizeof(SYS_DATA)); gpsSysData->pvSysSpecificData = &gsSysSpecificData; gsSysSpecificData.ui32SysSpecificData = 0; #if defined(LDM_PCI) || defined(SUPPORT_DRI_DRM) /* Save the pci_dev structure pointer from module.c */ PVR_ASSERT(gpsPVRLDMDev != IMG_NULL); gsSysSpecificData.psPCIDev = gpsPVRLDMDev; #endif eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure")); SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA); /* Set up timing information*/ 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 /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; #ifdef __linux__ eError = PCIInitDev(gpsSysData); if (eError != PVRSRV_OK) { SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PCINIT); #endif gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT; /* init device ID's */ 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")); SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } /* Locate the devices within the system, specifying the physical addresses of each devices components (regs, mem, ports etc.) */ eError = SysLocateDevices(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices")); SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV); /* Map the Atlas and PDP registers. */ gpsSysData->pvSOCRegsBase = OSMapPhysToLin(gsSOCRegsCpuPBase, SYS_ATLAS_REG_REGION_SIZE, PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, IMG_NULL); /* Do some initial register setup */ eError = SysInitRegisters(); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitRegisters: Failed to initialise registers")); SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITREG); #if defined(READ_TCF_HOST_MEM_SIGNATURE) SysTestTCFHostMemSig(gsSGXDeviceMap.sRegsCpuPBase, gsSGXDeviceMap.sLocalMemCpuPBase); #endif /* Register devices with the system This also sets up their memory maps/heaps */ eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice, SysGetSGXInterruptBit(), &gui32SGXDeviceID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!")); SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REGDEV); /* A given SOC may have 0 to n local device memory blocks. It is assumed device local memory blocks will be either specific to each device or shared among one or more services managed devices. Note: no provision is made for a single device having more than one local device memory blocks. If required we must add new types, e.g.PVRSRV_BACKINGSTORE_LOCALMEM_NONCONTIG0 PVRSRV_BACKINGSTORE_LOCALMEM_NONCONTIG1 */ /* Create Local Device Page Managers for each device memory block. We'll use an RA to do the management (only one for the emulator) */ gpsSysData->apsLocalDevMemArena[0] = RA_Create ("TestChipDeviceMemory", gsSGXDeviceMap.sLocalMemSysPBase.uiAddr, gsSGXDeviceMap.ui32LocalMemSize, IMG_NULL, HOST_PAGESIZE(), IMG_NULL, IMG_NULL, IMG_NULL, IMG_NULL); if (gpsSysData->apsLocalDevMemArena[0] == IMG_NULL) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to create local dev mem allocator!")); SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_RA_ARENA); /* Once all devices are registered, specify the backing store and, if required, customise the memory heap config */ psDeviceNode = gpsSysData->psDeviceNodeList; while(psDeviceNode) { /* perform any OEM SOC address space customisations here */ switch(psDeviceNode->sDevId.eDeviceType) { case PVRSRV_DEVICE_TYPE_SGX: { DEVICE_MEMORY_INFO *psDevMemoryInfo; DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; /* specify the backing store to use for the device's MMU PT/PDs */ psDeviceNode->psLocalDevMemArena = gpsSysData->apsLocalDevMemArena[0]; /* useful pointers */ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; /* specify the backing store for all SGX heaps */ for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++) { /* specify the backing store type (all local device mem noncontig) for test chip */ psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG; /* map the device memory allocator(s) onto the device memory heaps as required */ psDeviceMemoryHeap[i].psLocalDevMemArena = gpsSysData->apsLocalDevMemArena[0]; #ifdef OEM_CUSTOMISE /* if required, modify the memory config */ #endif } break; } default: break; } /* advance to next device */ psDeviceNode = psDeviceNode->psNext; } /* Initialise all devices 'managed' by services: */ eError = PVRSRVInitialiseDevice (gui32SGXDeviceID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!")); SysDeinitialise(gpsSysData); gpsSysData = IMG_NULL; return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV); return PVRSRV_OK; }
static PVRSRV_ERROR SysCreateVersionString(SYS_DATA *psSysData) { IMG_UINT32 ui32MaxStrLen; PVRSRV_ERROR eError; IMG_INT32 i32Count; IMG_CHAR *pszVersionString; IMG_UINT32 ui32SGXRevision = 0; IMG_VOID *pvSGXRegs; pvSGXRegs = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase, gsSGXDeviceMap.ui32RegsSize, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); if (pvSGXRegs != IMG_NULL) { ui32SGXRevision = OSReadHWReg(pvSGXRegs, EUR_CR_CORE_REVISION); OSUnMapPhysToLin(pvSGXRegs, gsSGXDeviceMap.ui32RegsSize, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); } else { PVR_DPF((PVR_DBG_ERROR,"SysCreateVersionString: Couldn't map SGX registers")); } ui32MaxStrLen = OSStringLength(VERSION_STR_MAX_LEN_TEMPLATE); eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, ui32MaxStrLen + 1, (IMG_PVOID *)&pszVersionString, IMG_NULL, "Version String"); if(eError != PVRSRV_OK) { return eError; } i32Count = OSSNPrintf(pszVersionString, ui32MaxStrLen + 1, "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(i32Count == -1) { ui32MaxStrLen = OSStringLength(VERSION_STR_MAX_LEN_TEMPLATE); OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32MaxStrLen + 1, pszVersionString, IMG_NULL); return PVRSRV_ERROR_INVALID_PARAMS; } psSysData->pszVersionString = pszVersionString; return PVRSRV_OK; }
PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer, IMG_SIZE_T *puiBufSize, IMG_BOOL bSave) { IMG_SIZE_T uiBytesSaved = 0; IMG_PVOID pvLocalMemCPUVAddr; RA_SEGMENT_DETAILS sSegDetails; if (hArena == IMG_NULL) { return (PVRSRV_ERROR_INVALID_PARAMS); } sSegDetails.uiSize = 0; sSegDetails.sCpuPhyAddr.uiAddr = 0; sSegDetails.hSegment = 0; while (RA_GetNextLiveSegment(hArena, &sSegDetails)) { if (pbyBuffer == IMG_NULL) { uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize; } else { if ((uiBytesSaved + sizeof(sSegDetails.uiSize) + sSegDetails.uiSize) > *puiBufSize) { return (PVRSRV_ERROR_OUT_OF_MEMORY); } PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVSaveRestoreLiveSegments: Base %08x size %08x", sSegDetails.sCpuPhyAddr.uiAddr, sSegDetails.uiSize)); pvLocalMemCPUVAddr = OSMapPhysToLin(sSegDetails.sCpuPhyAddr, sSegDetails.uiSize, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); if (pvLocalMemCPUVAddr == IMG_NULL) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Failed to map local memory to host")); return (PVRSRV_ERROR_OUT_OF_MEMORY); } if (bSave) { OSMemCopy(pbyBuffer, &sSegDetails.uiSize, sizeof(sSegDetails.uiSize)); pbyBuffer += sizeof(sSegDetails.uiSize); OSMemCopy(pbyBuffer, pvLocalMemCPUVAddr, sSegDetails.uiSize); pbyBuffer += sSegDetails.uiSize; } else { IMG_UINT32 uiSize; OSMemCopy(&uiSize, pbyBuffer, sizeof(sSegDetails.uiSize)); if (uiSize != sSegDetails.uiSize) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Segment size error")); } else { pbyBuffer += sizeof(sSegDetails.uiSize); OSMemCopy(pvLocalMemCPUVAddr, pbyBuffer, sSegDetails.uiSize); pbyBuffer += sSegDetails.uiSize; } } uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize; OSUnMapPhysToLin(pvLocalMemCPUVAddr, sSegDetails.uiSize, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); } } if (pbyBuffer == IMG_NULL) { *puiBufSize = uiBytesSaved; } return (PVRSRV_OK); }
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); gsSGXDeviceMap.ui32Flags = 0x0; #if defined(NO_HARDWARE) gsSGXDeviceMap.ui32RegsSize = SYS_TI335x_SGX_REGS_SIZE; eError = OSBaseAllocContigMemory(gsSGXDeviceMap.ui32RegsSize, &gsSGXRegsCPUVAddr, &sCpuPAddr); if(eError != PVRSRV_OK) { return eError; } gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr; gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase); #if defined(__linux__) gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; #else gsSGXDeviceMap.pvRegsCpuVBase = IMG_NULL; #endif OSMemSet(gsSGXRegsCPUVAddr, 0, gsSGXDeviceMap.ui32RegsSize); 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_TI335x_SGX_REGS_SYS_PHYS_BASE; gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); gsSGXDeviceMap.ui32RegsSize = SYS_TI335x_SGX_REGS_SIZE; gsSGXDeviceMap.ui32IRQ = SYS_TI335x_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) { static IMG_CHAR pszPDumpDevName[] = "SGXMEM"; gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName; } #endif return PVRSRV_OK; }
static IMG_BOOL ZeroBuf(struct BM_BUF *pBuf, struct BM_MAPPING *pMapping, u32 ui32Bytes, u32 ui32Flags) { void *pvCpuVAddr; if (pBuf->CpuVAddr) { OSMemSet(pBuf->CpuVAddr, 0, ui32Bytes); } else if (pMapping->eCpuMemoryOrigin == hm_contiguous || pMapping->eCpuMemoryOrigin == hm_wrapped) { pvCpuVAddr = (void __force *)OSMapPhysToLin(pBuf->CpuPAddr, ui32Bytes, PVRSRV_HAP_KERNEL_ONLY | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK), NULL); if (!pvCpuVAddr) { PVR_DPF(PVR_DBG_ERROR, "ZeroBuf: " "OSMapPhysToLin for contiguous buffer failed"); return IMG_FALSE; } OSMemSet(pvCpuVAddr, 0, ui32Bytes); OSUnMapPhysToLin((void __force __iomem *)pvCpuVAddr, ui32Bytes, PVRSRV_HAP_KERNEL_ONLY | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK), NULL); } else { u32 ui32BytesRemaining = ui32Bytes; u32 ui32CurrentOffset = 0; struct IMG_CPU_PHYADDR CpuPAddr; PVR_ASSERT(pBuf->hOSMemHandle); while (ui32BytesRemaining > 0) { u32 ui32BlockBytes = MIN(ui32BytesRemaining, HOST_PAGESIZE()); CpuPAddr = OSMemHandleToCpuPAddr(pBuf->hOSMemHandle, ui32CurrentOffset); if (CpuPAddr.uiAddr & (HOST_PAGESIZE() - 1)) ui32BlockBytes = MIN(ui32BytesRemaining, HOST_PAGEALIGN(CpuPAddr.uiAddr) - CpuPAddr.uiAddr); pvCpuVAddr = (void __force *)OSMapPhysToLin(CpuPAddr, ui32BlockBytes, PVRSRV_HAP_KERNEL_ONLY | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK), NULL); if (!pvCpuVAddr) { PVR_DPF(PVR_DBG_ERROR, "ZeroBuf: " "OSMapPhysToLin while " "zeroing non-contiguous memory FAILED"); return IMG_FALSE; } OSMemSet(pvCpuVAddr, 0, ui32BlockBytes); OSUnMapPhysToLin((void __force __iomem *)pvCpuVAddr, ui32BlockBytes, PVRSRV_HAP_KERNEL_ONLY | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK), NULL); ui32BytesRemaining -= ui32BlockBytes; ui32CurrentOffset += ui32BlockBytes; } } return IMG_TRUE; }
/***********************************************************************//** * Map the CPU physical backing for the registers to CPU virtual memory * so we can write to it from the host * * @returns PVRSRV_OK for success, or failure code **************************************************************************/ static PVRSRV_ERROR SysMapInRegisters(void) { PVRSRV_DEVICE_NODE *psDeviceNodeList; psDeviceNodeList = gpsSysData->psDeviceNodeList; while (psDeviceNodeList) { switch (psDeviceNodeList->sDevId.eDeviceType) { case PVRSRV_DEVICE_TYPE_SGX: { PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *) psDeviceNodeList->pvDevice; #if !defined(NO_HARDWARE) if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS)) { /* Remap Regs */ psDevInfo->pvRegsBaseKM = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase, gsSGXDeviceMap.ui32RegsSize, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); if (!psDevInfo->pvRegsBaseKM) { PVR_DPF((PVR_DBG_ERROR,"SysMapInRegisters : Failed to map in regs\n")); return PVRSRV_ERROR_BAD_MAPPING; } SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS); } #else /* !defined(NO_HARDWARE) */ /* * SysLocateDevices will have reallocated the dummy * registers. */ psDevInfo->pvRegsBaseKM = gsSGXDeviceMap.pvRegsCpuVBase; #endif /* !defined(NO_HARDWARE) */ psDevInfo->ui32RegSize = gsSGXDeviceMap.ui32RegsSize; psDevInfo->sRegsPhysBase = gsSGXDeviceMap.sRegsSysPBase; break; } #if defined(SUPPORT_MSVDX) case PVRSRV_DEVICE_TYPE_MSVDX: { PVRSRV_MSVDXDEV_INFO *psDevInfo = (PVRSRV_MSVDXDEV_INFO *) psDeviceNodeList->pvDevice; #if !defined(NO_HARDWARE) if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_MSVDX_REGS)) { /* Remap registers */ psDevInfo->pvRegsBaseKM = OSMapPhysToLin(gsMSVDXDeviceMap.sRegsCpuPBase, gsMSVDXDeviceMap.ui32RegsSize, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); if (!psDevInfo->pvRegsBaseKM) { PVR_DPF((PVR_DBG_ERROR,"SysMapInRegisters : Failed to map MSVDX registers\n")); return PVRSRV_ERROR_BAD_MAPPING; } SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_MSVDX_REGS); } #else /* !defined(NO_HARDWARE) */ /* * SysLocateDevices will have reallocated the dummy * registers. */ psDevInfo->pvRegsBaseKM = gsMSVDXDeviceMap.sRegsCpuVBase; #endif /* !defined(NO_HARDWARE) */ psDevInfo->ui32RegSize = gsMSVDXDeviceMap.ui32RegsSize; psDevInfo->sRegsPhysBase = gsMSVDXDeviceMap.sRegsSysPBase; break; } #endif /* SUPPORT_MSVDX */ default: /* Ignore any other (unknown) devices */ break; } psDeviceNodeList = psDeviceNodeList->psNext; } return PVRSRV_OK; }
static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData) { IMG_UINT32 ui32BaseAddr = 0; IMG_UINT32 ui32IRQ = 0; #if defined(SGX_FEATURE_HOST_PORT) IMG_UINT32 ui32HostPortAddr = 0; #endif SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; #if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) struct drm_psb_private *dev_priv = (struct drm_psb_private *) gpDrmDevice->dev_private; #endif ui32BaseAddr = OSPCIAddrRangeStart(psSysSpecData->hSGXPCI, POULSBO_ADDR_RANGE_INDEX); #if defined(SGX_FEATURE_HOST_PORT) ui32HostPortAddr = OSPCIAddrRangeStart(psSysSpecData->hSGXPCI, POULSBO_HP_ADDR_RANGE_INDEX); #endif if (OSPCIIRQ(psSysSpecData->hSGXPCI, &ui32IRQ) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysLocateDevices: Couldn't get IRQ")); return PVRSRV_ERROR_INVALID_DEVICE; } PVR_TRACE(("ui32BaseAddr: %08X", ui32BaseAddr)); #if defined(SGX_FEATURE_HOST_PORT) PVR_TRACE(("ui32HostPortAddr: %08X", ui32HostPortAddr)); #endif PVR_TRACE(("IRQ: %d", ui32IRQ)); gsSGXDeviceMap.ui32Flags = 0x0; gsSGXDeviceMap.ui32IRQ = ui32IRQ; #if defined(SUPPORT_DRI_DRM_EXT) gsSGXDeviceMap.sRegsSysPBase.uiAddr = ui32BaseAddr + SGX_REGS_OFFSET; #else gsSGXDeviceMap.sRegsSysPBase.uiAddr = ui32BaseAddr + SGX_REGS_OFFSET; #endif gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); gsSGXDeviceMap.ui32RegsSize = SGX_REG_SIZE; #if defined(SGX_FEATURE_HOST_PORT) gsSGXDeviceMap.ui32Flags = SGX_HOSTPORT_PRESENT; gsSGXDeviceMap.sHPSysPBase.uiAddr = ui32HostPortAddr; gsSGXDeviceMap.sHPCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sHPSysPBase); gsSGXDeviceMap.ui32HPSize = SYS_SGX_HP_SIZE; #endif #if defined(MRST_SLAVEPORT) gsSGXDeviceMap.sSPSysPBase.uiAddr = ui32BaseAddr + MRST_SGX_SP_OFFSET; gsSGXDeviceMap.sSPCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sSPSysPBase); gsSGXDeviceMap.ui32SPSize = SGX_SP_SIZE; #endif gsSGXDeviceMap.sLocalMemSysPBase.uiAddr = 0; gsSGXDeviceMap.sLocalMemDevPBase.uiAddr = 0; gsSGXDeviceMap.sLocalMemCpuPBase.uiAddr = 0; gsSGXDeviceMap.ui32LocalMemSize = 0; #if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) gsSGXDeviceMap.sExtSysCacheRegsDevPBase.uiAddr = SYS_EXT_SYS_CACHE_GBL_INV_REG_OFFSET; gsSGXDeviceMap.ui32ExtSysCacheRegsSize = SGX_EXT_SYSTEM_CACHE_REGS_SIZE; MDFLD_GL3_WRITE(gsSGXDeviceMap.sExtSysCacheRegsDevPBase.uiAddr, MDFLD_GL3_USE_WRT_INVAL); #endif #if !defined(NO_HARDWARE) { IMG_SYS_PHYADDR sPoulsboRegsCpuPBase; sPoulsboRegsCpuPBase.uiAddr = ui32BaseAddr + POULSBO_REGS_OFFSET; gsPoulsboRegsCPUVaddr = OSMapPhysToLin(SysSysPAddrToCpuPAddr(sPoulsboRegsCpuPBase), POULSBO_REG_SIZE, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); sPoulsboRegsCpuPBase.uiAddr = ui32BaseAddr + POULSBO_DISPLAY_REGS_OFFSET; gsPoulsboDisplayRegsCPUVaddr = OSMapPhysToLin(SysSysPAddrToCpuPAddr(sPoulsboRegsCpuPBase), POULSBO_DISPLAY_REG_SIZE, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); } #endif #if defined(PDUMP) { static IMG_CHAR pszPDumpDevName[] = "SGXMEM"; gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName; } #endif return PVRSRV_OK; }
enum PVRSRV_ERROR MMU_Initialise(struct PVRSRV_DEVICE_NODE *psDeviceNode, struct MMU_CONTEXT **ppsMMUContext, struct IMG_DEV_PHYADDR *psPDDevPAddr) { u32 *pui32Tmp; u32 i; void *pvPDCpuVAddr; struct IMG_DEV_PHYADDR sPDDevPAddr; struct IMG_CPU_PHYADDR sCpuPAddr; struct IMG_SYS_PHYADDR sSysPAddr; struct MMU_CONTEXT *psMMUContext; void *hPDOSMemHandle; struct SYS_DATA *psSysData; struct PVRSRV_SGXDEV_INFO *psDevInfo; PVR_DPF(PVR_DBG_MESSAGE, "MMU_Initialise"); if (SysAcquireData(&psSysData) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: ERROR call to SysAcquireData failed"); return PVRSRV_ERROR_GENERIC; } if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct MMU_CONTEXT), (void **) &psMMUContext, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocMem failed"); return PVRSRV_ERROR_GENERIC; } OSMemSet(psMMUContext, 0, sizeof(struct MMU_CONTEXT)); psDevInfo = (struct PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; psMMUContext->psDevInfo = psDevInfo; psMMUContext->psDeviceNode = psDeviceNode; if (psDeviceNode->psLocalDevMemArena == NULL) { if (OSAllocPages (PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, SGX_MMU_PAGE_SIZE, SGX_MMU_PAGE_SIZE, &pvPDCpuVAddr, &hPDOSMemHandle) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: " "ERROR call to OSAllocPages failed"); goto err1; } if (pvPDCpuVAddr) sCpuPAddr = OSMapLinToCPUPhys(pvPDCpuVAddr); else sCpuPAddr = OSMemHandleToCpuPAddr(hPDOSMemHandle, 0); sPDDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); } else { if (RA_Alloc(psDeviceNode->psLocalDevMemArena, SGX_MMU_PAGE_SIZE, NULL, 0, SGX_MMU_PAGE_SIZE, &(sSysPAddr.uiAddr)) != IMG_TRUE) { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: " "ERROR call to RA_Alloc failed"); goto err1; } sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); sPDDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr); pvPDCpuVAddr = (void __force *) OSMapPhysToLin(sCpuPAddr, SGX_MMU_PAGE_SIZE, PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, &hPDOSMemHandle); if (!pvPDCpuVAddr) { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: " "ERROR failed to map page tables"); goto err2; } } PDUMPCOMMENT("Alloc page directory"); PDUMPMALLOCPAGETABLE(pvPDCpuVAddr, PDUMP_PD_UNIQUETAG); if (pvPDCpuVAddr) { pui32Tmp = (u32 *) pvPDCpuVAddr; } else { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: pvPDCpuVAddr invalid"); goto err3; } for (i = 0; i < SGX_MMU_PD_SIZE; i++) pui32Tmp[i] = 0; PDUMPCOMMENT("Page directory contents"); PDUMPPAGETABLE(pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); psMMUContext->pvPDCpuVAddr = pvPDCpuVAddr; psMMUContext->sPDDevPAddr = sPDDevPAddr; psMMUContext->hPDOSMemHandle = hPDOSMemHandle; *ppsMMUContext = psMMUContext; *psPDDevPAddr = sPDDevPAddr; psMMUContext->psNext = (struct MMU_CONTEXT *) psDevInfo->pvMMUContextList; psDevInfo->pvMMUContextList = (void *) psMMUContext; return PVRSRV_OK; err3: if (psDeviceNode->psLocalDevMemArena) OSUnMapPhysToLin((void __iomem __force *)pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, hPDOSMemHandle); err2: if (!psDeviceNode->psLocalDevMemArena) OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, SGX_MMU_PAGE_SIZE, pvPDCpuVAddr, hPDOSMemHandle); else RA_Free(psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); err1: OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct MMU_CONTEXT), psMMUContext, NULL); return PVRSRV_ERROR_GENERIC; }
static PVRSRV_ERROR SysMapInRegisters(IMG_VOID) { PVRSRV_DEVICE_NODE *psDeviceNodeList; psDeviceNodeList = gpsSysData->psDeviceNodeList; while (psDeviceNodeList) { switch(psDeviceNodeList->sDevId.eDeviceType) { case PVRSRV_DEVICE_TYPE_SGX: { PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNodeList->pvDevice; if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS)) { psDevInfo->pvRegsBaseKM = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase, gsSGXDeviceMap.ui32RegsSize, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); if (!psDevInfo->pvRegsBaseKM) { PVR_DPF((PVR_DBG_ERROR,"SysMapInRegisters : Failed to map in SGX registers\n")); return PVRSRV_ERROR_BAD_MAPPING; } SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_REGS); } psDevInfo->ui32RegSize = gsSGXDeviceMap.ui32RegsSize; psDevInfo->sRegsPhysBase = gsSGXDeviceMap.sRegsSysPBase; #if defined(SGX_FEATURE_HOST_PORT) if (gsSGXDeviceMap.ui32Flags & SGX_HOSTPORT_PRESENT) { if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_HP)) { psDevInfo->pvHostPortBaseKM = OSMapPhysToLin(gsSGXDeviceMap.sHPCpuPBase, gsSGXDeviceMap.ui32HPSize, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); if (!psDevInfo->pvHostPortBaseKM) { PVR_DPF((PVR_DBG_ERROR,"SysMapInRegisters : Failed to map in host port\n")); return PVRSRV_ERROR_BAD_MAPPING; } SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNMAP_SGX_HP); } psDevInfo->ui32HPSize = gsSGXDeviceMap.ui32HPSize; psDevInfo->sHPSysPAddr = gsSGXDeviceMap.sHPSysPBase; } #endif break; } default: break; } psDeviceNodeList = psDeviceNodeList->psNext; } return PVRSRV_OK; }
/* EmuReset */ static PVRSRV_ERROR EmuReset(IMG_CPU_PHYADDR sRegsCpuPBase) { IMG_CPU_PHYADDR sWrapperRegsCpuPBase; IMG_VOID *pvWrapperRegs; IMG_UINT32 ui32MemLatency; sWrapperRegsCpuPBase.uiAddr = sRegsCpuPBase.uiAddr + EMULATOR_RGX_REG_WRAPPER_OFFSET; /* Create a temporary mapping of the wrapper registers in order to reset the emulator design. */ pvWrapperRegs = OSMapPhysToLin(sWrapperRegsCpuPBase, EMULATOR_RGX_REG_WRAPPER_SIZE, 0); if (pvWrapperRegs == IMG_NULL) { PVR_DPF((PVR_DBG_ERROR,"EmuReset: Failed to create wrapper register mapping\n")); return PVRSRV_ERROR_BAD_MAPPING; } /* Set the memory latency. This needs to be done before the soft reset to ensure it applies to all aspects of the emulator. */ ui32MemLatency = EmuMemLatencyGet(); if (ui32MemLatency != 0) { PVR_LOG(("EmuReset: Mem latency = 0x%X", ui32MemLatency)); } OSWriteHWReg32(pvWrapperRegs, EMU_CR_MEMORY_LATENCY, ui32MemLatency); (void) OSReadHWReg32(pvWrapperRegs, EMU_CR_MEMORY_LATENCY); /* Emu reset. */ OSWriteHWReg32(pvWrapperRegs, EMU_CR_SOFT_RESET, EMU_CR_SOFT_RESET_SYS_EN|EMU_CR_SOFT_RESET_MEM_EN|EMU_CR_SOFT_RESET_CORE_EN); /* Flush register write */ (void) OSReadHWReg32(pvWrapperRegs, EMU_CR_SOFT_RESET); OSWaitus(10); OSWriteHWReg32(pvWrapperRegs, EMU_CR_SOFT_RESET, 0x0); /* Flush register write */ (void) OSReadHWReg32(pvWrapperRegs, EMU_CR_SOFT_RESET); OSWaitus(10); #if !defined(LMA) /* If we're UMA then enable bus mastering */ OSWriteHWReg32(pvWrapperRegs, EMU_CR_PCI_MASTER, EMU_CR_PCI_MASTER_MODE_EN); #else /* otherwise disable it: the emu regbank is not resetable */ OSWriteHWReg32(pvWrapperRegs, EMU_CR_PCI_MASTER, 0x0); #endif /* Flush register write */ (void) OSReadHWReg32(pvWrapperRegs, EMU_CR_PCI_MASTER); /* Remove the temporary register mapping. */ OSUnMapPhysToLin(pvWrapperRegs, EMULATOR_RGX_REG_WRAPPER_SIZE, 0); return PVRSRV_OK; }
/*! ****************************************************************************** @Function SysLocateDevices @Description Specifies devices in the systems memory map @Input psSysData - sys data @Return PVRSRV_ERROR ******************************************************************************/ 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); /* SGX Device: */ gsSGXDeviceMap.ui32Flags = 0x0; #if defined(NO_HARDWARE) /* * For no hardware, allocate some contiguous memory for the * register block. */ /* Registers */ gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3630_SGX_REGS_SIZE; eError = OSBaseAllocContigMemory(gsSGXDeviceMap.ui32RegsSize, &gsSGXRegsCPUVAddr, &sCpuPAddr); if(eError != PVRSRV_OK) { return eError; } gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr; gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase); #if defined(__linux__) /* Indicate the registers are already mapped */ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; #else /* * FIXME: Could we just use the virtual address returned by * OSBaseAllocContigMemory? */ gsSGXDeviceMap.pvRegsCpuVBase = IMG_NULL; #endif OSMemSet(gsSGXRegsCPUVAddr, 0, gsSGXDeviceMap.ui32RegsSize); /* device interrupt IRQ Note: no interrupts available on no hardware system */ gsSGXDeviceMap.ui32IRQ = 0; #else /* defined(NO_HARDWARE) */ #if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) /* get the resource and IRQ through platform resource API */ 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)); #if defined(SGX544) && defined(SGX_FEATURE_MP) /* FIXME: Workaround due to HWMOD change. Otherwise this region is too small. */ gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3630_SGX_REGS_SIZE; #else gsSGXDeviceMap.ui32RegsSize = (unsigned int)(dev_res->end - dev_res->start); #endif PVR_TRACE(("SGX register size: %d",gsSGXDeviceMap.ui32RegsSize)); gsSGXDeviceMap.ui32IRQ = dev_irq; PVR_TRACE(("SGX IRQ: %d", gsSGXDeviceMap.ui32IRQ)); #else /* defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) */ gsSGXDeviceMap.sRegsSysPBase.uiAddr = SYS_OMAP3630_SGX_REGS_SYS_PHYS_BASE; gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3630_SGX_REGS_SIZE; gsSGXDeviceMap.ui32IRQ = SYS_OMAP3630_SGX_IRQ; #endif /* defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) */ #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; } /* Indicate the registers are already mapped */ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; gpvOCPRegsLinAddr = gsSGXRegsCPUVAddr; #endif #endif /* defined(NO_HARDWARE) */ #if defined(PDUMP) { /* initialise memory region name for pdumping */ static IMG_CHAR pszPDumpDevName[] = "SGXMEM"; gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName; } #endif /* add other devices here: */ return PVRSRV_OK; }
/***********************************************************************//** * Locate and describe our devices on the PCI bus * * Fills out the device map for all devices we know aout and control * * @returns PVRSRV_OK for success, or failure code **************************************************************************/ static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData) { IMG_UINT32 ui32IRQ = 0; #if !defined(NO_HARDWARE) SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; #else PVRSRV_ERROR eError; #endif /************************ * SOC Setup * ************************/ #if !defined(NO_HARDWARE) /* Get the regions from the base address register */ gsSOCDeviceMap.sRegsSysPBase.uiAddr = OSPCIAddrRangeStart(psSysSpecData->hSGXPCI, CEDARVIEW_ADDR_RANGE_INDEX); PVR_TRACE(("uiBaseAddr: " SYSPADDR_FMT, gsSOCDeviceMap.sRegsSysPBase.uiAddr)); /* Convert it to a CPU physical address */ gsSOCDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSOCDeviceMap.sRegsSysPBase); /* * And map in the system registers. */ gsSOCDeviceMap.sRegsCpuVBase = OSMapPhysToLin(gsSOCDeviceMap.sRegsCpuPBase, SYS_SOC_REG_SIZE, PVRSRV_HAP_KERNEL_ONLY | PVRSRV_HAP_UNCACHED, IMG_NULL); SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_SOC_REGS_MAPPED); #endif /************************ * SGX Setup * ************************/ #if !defined(NO_HARDWARE) gsSGXDeviceMap.sRegsSysPBase.uiAddr = gsSOCDeviceMap.sRegsSysPBase.uiAddr + SYS_SGX_REG_OFFSET; gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); /* device interrupt IRQ */ if (OSPCIIRQ(psSysSpecData->hSGXPCI, &ui32IRQ) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysLocateDevices: Couldn't get IRQ")); return PVRSRV_ERROR_INVALID_DEVICE; } PVR_TRACE(("IRQ: %d", ui32IRQ)); #else /* !defined(NO_HARDWARE) */ /* * With no hardware, allocate contiguous memory to emulate the registers */ eError = OSBaseAllocContigMemory(SYS_SGX_REG_SIZE, &(gsSGXDeviceMap.pvRegsCpuVBase), &(gsSGXDeviceMap.sRegsCpuPBase)); if(eError != PVRSRV_OK) { return eError; } SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_DUMMY_SGX_REGS); OSMemSet(gsSGXDeviceMap.pvRegsCpuVBase, 0, SYS_SGX_REG_SIZE); gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase); #endif /* !defined(NO_HARDWARE) */ /* * Other setup */ gsSGXDeviceMap.ui32Flags = 0x0; gsSGXDeviceMap.ui32RegsSize = SYS_SGX_REG_SIZE; gsSGXDeviceMap.ui32IRQ = ui32IRQ; /* * Local Device Memory Region is never present */ gsSGXDeviceMap.sLocalMemSysPBase.uiAddr = 0; gsSGXDeviceMap.sLocalMemDevPBase.uiAddr = 0; gsSGXDeviceMap.sLocalMemCpuPBase.uiAddr = 0; gsSGXDeviceMap.ui32LocalMemSize = 0; #if defined(PDUMP) { /* initialise memory region name for pdumping */ static IMG_CHAR pszPDumpDevName[] = SYSTEM_PDUMP_NAME; gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName; } #endif /************************ * VXD Setup * ************************/ #if defined(SUPPORT_MSVDX) #if !defined(NO_HARDWARE) gsMSVDXDeviceMap.sRegsSysPBase.uiAddr = gsSOCDeviceMap.sRegsSysPBase.uiAddr + SYS_MSVDX_REG_OFFSET; gsMSVDXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsMSVDXDeviceMap.sRegsSysPBase); #else /* No hardware registers */ eError = OSBaseAllocContigMemory(MSVDX_REG_SIZE, &(gsMSVDXDeviceMap.sRegsCpuVBase), &(gsMSVDXDeviceMap.sRegsCpuPBase)); if(eError != PVRSRV_OK) { return eError; } SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_DUMMY_MSVDX_REGS); OSMemSet(gsMSVDXDeviceMap.sRegsCpuVBase, 0, MSVDX_REG_SIZE); gsMSVDXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsMSVDXDeviceMap.sRegsCpuPBase); #endif /* NO_HARDWARE */ /* Common setup */ gsMSVDXDeviceMap.ui32RegsSize = MSVDX_REG_SIZE; /* * No local device memory region */ gsMSVDXDeviceMap.sLocalMemSysPBase.uiAddr = 0; gsMSVDXDeviceMap.sLocalMemDevPBase.uiAddr = 0; gsMSVDXDeviceMap.sLocalMemCpuPBase.uiAddr = 0; gsMSVDXDeviceMap.ui32LocalMemSize = 0; /* * device interrupt IRQ */ gsMSVDXDeviceMap.ui32IRQ = ui32IRQ; #if defined(PDUMP) { /* initialise memory region name for pdumping */ static IMG_CHAR pszPDumpDevName[] = SYSTEM_PDUMP_NAME; gsMSVDXDeviceMap.pszPDumpDevName = pszPDumpDevName; } #endif /* defined(PDUMP) */ #endif /* defined(SUPPORT_MSVDX) */ PVR_DPF((PVR_DBG_MESSAGE, "SGX registers base physical address: 0x" SYSPADDR_FMT, gsSGXDeviceMap.sRegsSysPBase.uiAddr)); #if defined(SUPPORT_MSVDX) PVR_DPF((PVR_DBG_MESSAGE, "VXD registers base physical address: 0x" SYSPADDR_FMT, gsMSVDXDeviceMap.sRegsSysPBase.uiAddr)); #endif return PVRSRV_OK; }