static IMG_VOID SGXResetSetupBIFContexts(PVRSRV_SGXDEV_INFO *psDevInfo, IMG_UINT32 ui32PDUMPFlags) { IMG_UINT32 ui32RegVal; #if !defined(PDUMP) PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags); #endif #if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) ui32RegVal = (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT); #if defined(SGX_FEATURE_2D_HARDWARE) && !defined(SGX_FEATURE_PTLA) ui32RegVal |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_2D_SHIFT); #endif #if defined(FIX_HW_BRN_23410) ui32RegVal |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_TA_SHIFT); #endif OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32RegVal); PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Set up EDM requestor page table in BIF\r\n"); PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_BANK0, ui32RegVal, ui32PDUMPFlags); #endif { IMG_UINT32 ui32EDMDirListReg; #if (SGX_BIF_DIR_LIST_INDEX_EDM == 0) ui32EDMDirListReg = EUR_CR_BIF_DIR_LIST_BASE0; #else ui32EDMDirListReg = EUR_CR_BIF_DIR_LIST_BASE1 + 4 * (SGX_BIF_DIR_LIST_INDEX_EDM - 1); #endif ui32RegVal = psDevInfo->sKernelPDDevPAddr.uiAddr >> SGX_MMU_PDE_ADDR_ALIGNSHIFT; #if defined(FIX_HW_BRN_28011) OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal); PDUMPPDREGWITHFLAGS(&psDevInfo->sMMUAttrib, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG); #endif OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32EDMDirListReg, ui32RegVal); PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the EDM's directory list base\r\n"); PDUMPPDREGWITHFLAGS(&psDevInfo->sMMUAttrib, ui32EDMDirListReg, ui32RegVal, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG); } }
/*! ******************************************************************************* @Function SGXResetSetupBIFContexts @Description Configure the BIF for the EDM context @Input psDevInfo - SGX Device Info @Return IMG_VOID ******************************************************************************/ static IMG_VOID SGXResetSetupBIFContexts(PVRSRV_SGXDEV_INFO *psDevInfo, IMG_UINT32 ui32PDUMPFlags) { IMG_UINT32 ui32RegVal; #if !defined(PDUMP) PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags); #endif /* PDUMP */ #if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) /* Set up EDM for bank 0 to point at kernel context */ ui32RegVal = (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT); #if defined(SGX_FEATURE_2D_HARDWARE) && !defined(SGX_FEATURE_PTLA) /* Set up 2D core for bank 0 to point at kernel context */ ui32RegVal |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_2D_SHIFT); #endif /* SGX_FEATURE_2D_HARDWARE */ #if defined(FIX_HW_BRN_23410) /* Set up TA core for bank 0 to point at kernel context to guarantee it is a valid context */ ui32RegVal |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_TA_SHIFT); #endif /* FIX_HW_BRN_23410 */ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32RegVal); PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Set up EDM requestor page table in BIF\r\n"); PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_BANK0, ui32RegVal, ui32PDUMPFlags); #endif /* defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) */ { IMG_UINT32 ui32EDMDirListReg; /* Set up EDM context with kernel page directory */ #if (SGX_BIF_DIR_LIST_INDEX_EDM == 0) ui32EDMDirListReg = EUR_CR_BIF_DIR_LIST_BASE0; #else /* Bases 0 and 1 are not necessarily contiguous */ ui32EDMDirListReg = EUR_CR_BIF_DIR_LIST_BASE1 + 4 * (SGX_BIF_DIR_LIST_INDEX_EDM - 1); #endif /* SGX_BIF_DIR_LIST_INDEX_EDM */ ui32RegVal = psDevInfo->sKernelPDDevPAddr.uiAddr >> SGX_MMU_PDE_ADDR_ALIGNSHIFT; #if defined(FIX_HW_BRN_28011) OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal); PDUMPPDREGWITHFLAGS(&psDevInfo->sMMUAttrib, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG); #endif OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32EDMDirListReg, ui32RegVal); PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the EDM's directory list base\r\n"); PDUMPPDREGWITHFLAGS(&psDevInfo->sMMUAttrib, ui32EDMDirListReg, ui32RegVal, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG); } }
void SGXReset(struct PVRSRV_SGXDEV_INFO *psDevInfo, u32 ui32PDUMPFlags) { u32 ui32RegVal; const u32 ui32BifFaultMask = EUR_CR_BIF_INT_STAT_FAULT_MASK; #ifndef PDUMP PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags); #endif psDevInfo->ui32NumResets++; PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Start of SGX reset sequence\r\n"); #if defined(FIX_HW_BRN_23944) ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK; OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT); if (ui32RegVal & ui32BifFaultMask) { ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK | EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK; OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK; OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); } #endif SGXResetSoftReset(psDevInfo, IMG_TRUE, ui32PDUMPFlags, IMG_TRUE); SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); ui32RegVal = psDevInfo->sBIFResetPDDevPAddr.uiAddr; OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal); SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags, IMG_TRUE); SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_FALSE); for (;;) { u32 ui32BifIntStat = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT); struct IMG_DEV_VIRTADDR sBifFault; u32 ui32PDIndex, ui32PTIndex; if ((ui32BifIntStat & ui32BifFaultMask) == 0) break; sBifFault.uiAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_FAULT); PVR_DPF(PVR_DBG_WARNING, "SGXReset: Page fault 0x%x/0x%x", ui32BifIntStat, sBifFault.uiAddr); ui32PDIndex = sBifFault.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); ui32PTIndex = (sBifFault.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT; SGXResetSoftReset(psDevInfo, IMG_TRUE, ui32PDUMPFlags, IMG_FALSE); psDevInfo->pui32BIFResetPD[ui32PDIndex] = psDevInfo->sBIFResetPTDevPAddr.uiAddr | SGX_MMU_PDE_VALID; psDevInfo->pui32BIFResetPT[ui32PTIndex] = psDevInfo->sBIFResetPageDevPAddr.uiAddr | SGX_MMU_PTE_VALID; ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS); OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR, ui32RegVal); ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS2); OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR2, ui32RegVal); SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags, IMG_FALSE); SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_FALSE); psDevInfo->pui32BIFResetPD[ui32PDIndex] = 0; psDevInfo->pui32BIFResetPT[ui32PTIndex] = 0; } OSWriteHWReg(psDevInfo->pvRegsBaseKM, SGX_BIF_DIR_LIST_REG_EDM, psDevInfo->sKernelPDDevPAddr.uiAddr); PDUMPPDREGWITHFLAGS(SGX_BIF_DIR_LIST_REG_EDM, psDevInfo->sKernelPDDevPAddr.uiAddr, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG); SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_TRUE); PVR_DPF(PVR_DBG_WARNING, "Soft Reset of SGX"); SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); ui32RegVal = 0; OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32RegVal); PDUMPREGWITHFLAGS(EUR_CR_SOFT_RESET, ui32RegVal, ui32PDUMPFlags); SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "End of SGX reset sequence\r\n"); }