1 /**********************************************************************
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
25 ******************************************************************************/
29 #include "services_headers.h"
30 #include "sgxinfokm.h"
31 #include "sgxconfig.h"
33 #include "pvr_pdump.h"
35 static void SGXResetSoftReset(struct PVRSRV_SGXDEV_INFO *psDevInfo,
36 IMG_BOOL bResetBIF, u32 ui32PDUMPFlags,
39 u32 ui32SoftResetRegVal =
40 EUR_CR_SOFT_RESET_DPM_RESET_MASK |
41 EUR_CR_SOFT_RESET_TA_RESET_MASK |
42 EUR_CR_SOFT_RESET_USE_RESET_MASK |
43 EUR_CR_SOFT_RESET_ISP_RESET_MASK | EUR_CR_SOFT_RESET_TSP_RESET_MASK;
45 #ifdef EUR_CR_SOFT_RESET_TWOD_RESET_MASK
46 ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TWOD_RESET_MASK;
50 PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
54 ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_BIF_RESET_MASK;
56 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET,
59 PDUMPREGWITHFLAGS(EUR_CR_SOFT_RESET, ui32SoftResetRegVal,
63 static void SGXResetSleep(struct PVRSRV_SGXDEV_INFO *psDevInfo,
64 u32 ui32PDUMPFlags, IMG_BOOL bPDump)
67 PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
70 OSWaitus(1000 * 1000000 / psDevInfo->ui32CoreClockSpeed);
72 PDUMPIDLWITHFLAGS(30, ui32PDUMPFlags);
74 PDumpRegRead(EUR_CR_SOFT_RESET, ui32PDUMPFlags);
80 static void SGXResetInvalDC(struct PVRSRV_SGXDEV_INFO *psDevInfo,
81 u32 ui32PDUMPFlags, IMG_BOOL bPDump)
85 ui32RegVal = EUR_CR_BIF_CTRL_INVALDC_MASK;
86 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
88 PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
89 SGXResetSleep(psDevInfo, ui32PDUMPFlags, bPDump);
92 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal);
94 PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags);
95 SGXResetSleep(psDevInfo, ui32PDUMPFlags, bPDump);
98 (u32 __iomem *)((u8 __iomem *)psDevInfo->pvRegsBaseKM +
99 EUR_CR_BIF_MEM_REQ_STAT),
100 0, EUR_CR_BIF_MEM_REQ_STAT_READS_MASK,
101 MAX_HW_TIME_US / WAIT_TRY_COUNT, WAIT_TRY_COUNT) != PVRSRV_OK) {
102 PVR_DPF(PVR_DBG_ERROR, "Wait for DC invalidate failed.");
107 PDUMPREGPOLWITHFLAGS(EUR_CR_BIF_MEM_REQ_STAT, 0,
108 EUR_CR_BIF_MEM_REQ_STAT_READS_MASK,
112 void SGXReset(struct PVRSRV_SGXDEV_INFO *psDevInfo, u32 ui32PDUMPFlags)
116 const u32 ui32BifFaultMask = EUR_CR_BIF_INT_STAT_FAULT_MASK;
120 PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags);
123 psDevInfo->ui32NumResets++;
125 PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags,
126 "Start of SGX reset sequence\r\n");
128 SGXResetSoftReset(psDevInfo, IMG_TRUE, ui32PDUMPFlags, IMG_TRUE);
130 SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
133 ui32RegVal = psDevInfo->sBIFResetPDDevPAddr.uiAddr;
134 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0,
137 SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
139 SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags, IMG_TRUE);
140 SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
142 SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
146 OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT);
147 struct IMG_DEV_VIRTADDR sBifFault;
148 u32 ui32PDIndex, ui32PTIndex;
150 if ((ui32BifIntStat & ui32BifFaultMask) == 0)
154 OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_FAULT);
155 PVR_DPF(PVR_DBG_WARNING, "SGXReset: Page fault 0x%x/0x%x",
156 ui32BifIntStat, sBifFault.uiAddr);
158 sBifFault.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);
160 (sBifFault.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT;
162 SGXResetSoftReset(psDevInfo, IMG_TRUE, ui32PDUMPFlags,
165 psDevInfo->pui32BIFResetPD[ui32PDIndex] =
166 psDevInfo->sBIFResetPTDevPAddr.uiAddr |
167 SGX_MMU_PDE_PAGE_SIZE_4K | SGX_MMU_PDE_VALID;
168 psDevInfo->pui32BIFResetPT[ui32PTIndex] =
169 psDevInfo->sBIFResetPageDevPAddr.uiAddr | SGX_MMU_PTE_VALID;
172 OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS);
173 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR,
176 OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS2);
177 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR2,
180 SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
182 SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags,
184 SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
186 SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_FALSE);
188 psDevInfo->pui32BIFResetPD[ui32PDIndex] = 0;
189 psDevInfo->pui32BIFResetPT[ui32PTIndex] = 0;
193 u32 ui32EDMDirListReg;
195 #if (SGX_BIF_DIR_LIST_INDEX_EDM == 0)
196 ui32EDMDirListReg = EUR_CR_BIF_DIR_LIST_BASE0;
200 EUR_CR_BIF_DIR_LIST_BASE1 +
201 4 * (SGX_BIF_DIR_LIST_INDEX_EDM - 1);
204 OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32EDMDirListReg,
205 psDevInfo->sKernelPDDevPAddr.uiAddr);
206 PDUMPPDREGWITHFLAGS(ui32EDMDirListReg,
207 psDevInfo->sKernelPDDevPAddr.uiAddr,
211 SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
213 PVR_DPF(PVR_DBG_MESSAGE, "Soft Reset of SGX");
214 SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
217 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32RegVal);
218 PDUMPREGWITHFLAGS(EUR_CR_SOFT_RESET, ui32RegVal, ui32PDUMPFlags);
220 SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE);
222 PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "End of SGX reset sequence\r\n");