1 /*************************************************************************/ /*!
3 @Title Rogue firmware utility routines
4 @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
5 @Description Rogue firmware utility routines
6 @License Dual MIT/GPLv2
8 The contents of this file are subject to the MIT license as set out below.
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files (the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
17 The above copyright notice and this permission notice shall be included in
18 all copies or substantial portions of the Software.
20 Alternatively, the contents of this file may be used under the terms of
21 the GNU General Public License Version 2 ("GPL") in which case the provisions
22 of GPL are applicable instead of those above.
24 If you wish to allow use of your version of this file only under the terms of
25 GPL, and not to allow others to use your version of this file under the terms
26 of the MIT license, indicate your decision by deleting the provisions above
27 and replace them with the notice and other provisions required by GPL as set
28 out in the file called "GPL-COPYING" included in this distribution. If you do
29 not delete the provisions above, a recipient may use your version of this file
30 under the terms of either the MIT license or GPL.
32 This License is also included in this distribution in the file called
35 EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
36 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
37 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
38 PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
39 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
40 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
41 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42 */ /**************************************************************************/
48 #include "rgxdefs_km.h"
49 #include "rgx_fwif_km.h"
54 #include "devicemem.h"
55 #include "devicemem_pdump.h"
56 #include "devicemem_server.h"
58 #include "pvr_debug.h"
59 #include "pvr_notifier.h"
60 #include "rgxfwutils.h"
61 #include "rgx_options.h"
63 #include "rgx_fwif_alignchecks.h"
64 #include "rgx_fwif_resetframework.h"
65 #include "rgx_pdump_panics.h"
66 #include "rgxheapconfig.h"
68 #if defined(SUPPORT_PVRSRV_GPUVIRT)
69 #include "rgxfwutils_vz.h"
72 #include "rgxhwperf.h"
74 #include "rgxcompute.h"
75 #include "rgxtransfer.h"
78 #if defined(SUPPORT_DISPLAY_CLASS)
79 #include "dc_server.h"
84 #include "sync_internal.h"
87 #include "devicemem_server_utils.h"
89 #include "rgx_bvnc_defs_km.h"
91 #if defined(SUPPORT_TRUSTED_DEVICE)
92 #include "physmem_osmem.h"
96 #include <linux/kernel.h> // sprintf
97 #include <linux/string.h> // strncpy, strlen
98 #include "rogue_trace_events.h"
103 #if defined(PVRSRV_ENABLE_PROCESS_STATS)
104 #include "process_stats.h"
107 #if defined(SUPPORT_WORKLOAD_ESTIMATION)
108 #include "rgxworkest.h"
111 #if defined(SUPPORT_PDVFS)
112 #include "rgxpdvfs.h"
115 /* Kernel CCB length */
116 /* Reducing the size of the KCCB in an attempt to avoid flooding and overflowing the FW kick queue
117 * in the case of multiple OSes */
118 #define RGXFWIF_KCCB_NUMCMDS_LOG2_GPUVIRT_ONLY (6)
119 #define RGXFWIF_KCCB_NUMCMDS_LOG2_FEAT_GPU_VIRTUALISATION (7)
122 /* Firmware CCB length */
123 #if defined(SUPPORT_PDVFS)
124 #define RGXFWIF_FWCCB_NUMCMDS_LOG2 (8)
126 #define RGXFWIF_FWCCB_NUMCMDS_LOG2 (5)
129 /* Workload Estimation Firmware CCB length */
130 #define RGXFWIF_WORKEST_FWCCB_NUMCMDS_LOG2 (7)
134 RGXFWIF_KCCB_CMD sKCCBcmd;
135 DLLIST_NODE sListNode;
136 PDUMP_FLAGS_T uiPdumpFlags;
137 PVRSRV_RGXDEV_INFO *psDevInfo;
139 } RGX_DEFERRED_KCCB_CMD;
142 /* ensure PIDs are 32-bit because a 32-bit PDump load is generated for the
143 * PID filter example entries
145 static_assert(sizeof(IMG_PID) == sizeof(IMG_UINT32),
146 "FW PID filtering assumes the IMG_PID type is 32-bits wide as it "
147 "generates WRW commands for loading the PID values");
150 #if !defined(PVRSRV_GPUVIRT_GUESTDRV)
151 static PVRSRV_ERROR _AllocateSLC3Fence(PVRSRV_RGXDEV_INFO* psDevInfo, RGXFWIF_INIT* psRGXFWInit)
154 DEVMEM_MEMDESC** ppsSLC3FenceMemDesc = &psDevInfo->psSLC3FenceMemDesc;
155 IMG_UINT32 ui32CacheLineSize = GET_ROGUE_CACHE_LINE_SIZE(psDevInfo->sDevFeatureCfg.ui32CacheLineSize);
159 eError = DevmemAllocate(psDevInfo->psFirmwareHeap,
162 PVRSRV_MEMALLOCFLAG_GPU_READABLE |
163 PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
164 PVRSRV_MEMALLOCFLAG_UNCACHED |
165 PVRSRV_MEMALLOCFLAG_FW_LOCAL,
167 ppsSLC3FenceMemDesc);
168 if (eError != PVRSRV_OK)
170 PVR_DPF_RETURN_RC(eError);
174 We need to map it so the heap for this allocation
177 eError = DevmemMapToDevice(*ppsSLC3FenceMemDesc,
178 psDevInfo->psFirmwareHeap,
179 &psRGXFWInit->sSLC3FenceDevVAddr);
180 if (eError != PVRSRV_OK)
182 DevmemFwFree(psDevInfo, *ppsSLC3FenceMemDesc);
183 *ppsSLC3FenceMemDesc = NULL;
186 PVR_DPF_RETURN_RC1(eError, *ppsSLC3FenceMemDesc);
189 static void _FreeSLC3Fence(PVRSRV_RGXDEV_INFO* psDevInfo)
191 DEVMEM_MEMDESC* psSLC3FenceMemDesc = psDevInfo->psSLC3FenceMemDesc;
193 if (psSLC3FenceMemDesc)
195 DevmemReleaseDevVirtAddr(psSLC3FenceMemDesc);
196 DevmemFree(psSLC3FenceMemDesc);
201 static void __MTSScheduleWrite(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT32 ui32Value)
203 /* ensure memory is flushed before kicking MTS */
204 OSWriteMemoryBarrier();
206 OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_MTS_SCHEDULE, ui32Value);
208 /* ensure the MTS kick goes through before continuing */
214 *******************************************************************************
215 @Function RGXFWSetupSignatureChecks
220 ******************************************************************************/
221 static PVRSRV_ERROR RGXFWSetupSignatureChecks(PVRSRV_RGXDEV_INFO* psDevInfo,
222 DEVMEM_MEMDESC** ppsSigChecksMemDesc,
223 IMG_UINT32 ui32SigChecksBufSize,
224 RGXFWIF_SIGBUF_CTL* psSigBufCtl,
225 const IMG_CHAR* pszBufferName)
228 DEVMEM_FLAGS_T uiMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
229 PVRSRV_MEMALLOCFLAG_GPU_READABLE |
230 PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
231 PVRSRV_MEMALLOCFLAG_CPU_READABLE |
232 PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
233 PVRSRV_MEMALLOCFLAG_UNCACHED |
234 PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
236 /* Allocate memory for the checks */
237 PDUMPCOMMENT("Allocate memory for %s signature checks", pszBufferName);
238 eError = DevmemFwAllocate(psDevInfo,
239 ui32SigChecksBufSize,
242 ppsSigChecksMemDesc);
243 if (eError != PVRSRV_OK)
245 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate %d bytes for signature checks (%u)",
246 ui32SigChecksBufSize,
251 /* Prepare the pointer for the fw to access that memory */
252 RGXSetFirmwareAddress(&psSigBufCtl->sBuffer,
253 *ppsSigChecksMemDesc,
254 0, RFW_FWADDR_NOREF_FLAG);
256 DevmemPDumpLoadMem( *ppsSigChecksMemDesc,
258 ui32SigChecksBufSize,
259 PDUMP_FLAGS_CONTINUOUS);
261 psSigBufCtl->ui32LeftSizeInRegs = ui32SigChecksBufSize / sizeof(IMG_UINT32);
266 #if defined(RGXFW_ALIGNCHECKS)
268 *******************************************************************************
269 @Function RGXFWSetupAlignChecks
270 @Description This functions allocates and fills memory needed for the
271 aligns checks of the UM and KM structures shared with the
272 firmware. The format of the data in the memory is as follows:
273 <number of elements in the KM array>
274 <array of KM structures' sizes and members' offsets>
275 <number of elements in the UM array>
276 <array of UM structures' sizes and members' offsets>
277 The UM array is passed from the user side. If the
278 SUPPORT_KERNEL_SRVINIT macro is defined the firmware is
279 is responsible for filling this part of the memory. If that
280 happens the check of the UM structures will be performed
281 by the host driver on client's connect.
282 If the macro is not defined the client driver fills the memory
283 and the firmware checks for the alignment of all structures.
287 ******************************************************************************/
288 static PVRSRV_ERROR RGXFWSetupAlignChecks(PVRSRV_RGXDEV_INFO* psDevInfo,
289 RGXFWIF_DEV_VIRTADDR *psAlignChecksDevFW,
290 IMG_UINT32 *pui32RGXFWAlignChecks,
291 IMG_UINT32 ui32RGXFWAlignChecksArrLength)
293 IMG_UINT32 aui32RGXFWAlignChecksKM[] = { RGXFW_ALIGN_CHECKS_INIT_KM };
294 IMG_UINT32 ui32RGXFWAlingChecksTotal;
295 IMG_UINT32* paui32AlignChecks;
298 #if defined(SUPPORT_KERNEL_SRVINIT)
299 /* In this case we don't know the number of elements in UM array.
300 * We have to assume something so we assume RGXFW_ALIGN_CHECKS_UM_MAX. */
301 PVR_ASSERT(ui32RGXFWAlignChecksArrLength == 0);
302 ui32RGXFWAlingChecksTotal = sizeof(aui32RGXFWAlignChecksKM)
303 + RGXFW_ALIGN_CHECKS_UM_MAX * sizeof(IMG_UINT32)
304 + 2 * sizeof(IMG_UINT32);
306 /* '2 * sizeof(IMG_UINT32)' if for sizes of km and um arrays. */
307 PVR_ASSERT(ui32RGXFWAlignChecksArrLength != 0);
308 ui32RGXFWAlingChecksTotal = sizeof(aui32RGXFWAlignChecksKM)
309 + ui32RGXFWAlignChecksArrLength * sizeof(IMG_UINT32)
310 + 2 * sizeof(IMG_UINT32);
313 /* Allocate memory for the checks */
314 PDUMPCOMMENT("Allocate memory for alignment checks");
315 eError = DevmemFwAllocate(psDevInfo,
316 ui32RGXFWAlingChecksTotal,
317 PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
318 PVRSRV_MEMALLOCFLAG_GPU_READABLE |
319 #if defined(SUPPORT_KERNEL_SRVINIT)
320 PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
322 PVRSRV_MEMALLOCFLAG_CPU_READABLE |
323 PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
324 PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | PVRSRV_MEMALLOCFLAG_UNCACHED,
326 &psDevInfo->psRGXFWAlignChecksMemDesc);
327 if (eError != PVRSRV_OK)
329 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate %d bytes for alignment checks (%u)",
330 ui32RGXFWAlingChecksTotal,
335 eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWAlignChecksMemDesc,
336 (void **)&paui32AlignChecks);
337 if (eError != PVRSRV_OK)
339 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to acquire kernel addr for alignment checks (%u)",
344 /* Copy the values */
345 #if defined(SUPPORT_KERNEL_SRVINIT)
346 *paui32AlignChecks++ = sizeof(aui32RGXFWAlignChecksKM)/sizeof(IMG_UINT32);
347 OSDeviceMemCopy(paui32AlignChecks, &aui32RGXFWAlignChecksKM[0], sizeof(aui32RGXFWAlignChecksKM));
348 paui32AlignChecks += sizeof(aui32RGXFWAlignChecksKM)/sizeof(IMG_UINT32);
350 *paui32AlignChecks = 0;
352 *paui32AlignChecks++ = sizeof(aui32RGXFWAlignChecksKM)/sizeof(IMG_UINT32);
353 OSDeviceMemCopy(paui32AlignChecks, &aui32RGXFWAlignChecksKM[0], sizeof(aui32RGXFWAlignChecksKM));
354 paui32AlignChecks += sizeof(aui32RGXFWAlignChecksKM)/sizeof(IMG_UINT32);
356 *paui32AlignChecks++ = ui32RGXFWAlignChecksArrLength;
357 OSDeviceMemCopy(paui32AlignChecks, pui32RGXFWAlignChecks, ui32RGXFWAlignChecksArrLength * sizeof(IMG_UINT32));
360 DevmemPDumpLoadMem( psDevInfo->psRGXFWAlignChecksMemDesc,
362 ui32RGXFWAlingChecksTotal,
363 PDUMP_FLAGS_CONTINUOUS);
365 /* Prepare the pointer for the fw to access that memory */
366 RGXSetFirmwareAddress(psAlignChecksDevFW,
367 psDevInfo->psRGXFWAlignChecksMemDesc,
368 0, RFW_FWADDR_NOREF_FLAG);
376 DevmemFwFree(psDevInfo, psDevInfo->psRGXFWAlignChecksMemDesc);
377 psDevInfo->psRGXFWAlignChecksMemDesc = NULL;
380 PVR_ASSERT(eError != PVRSRV_OK);
384 static void RGXFWFreeAlignChecks(PVRSRV_RGXDEV_INFO* psDevInfo)
386 if (psDevInfo->psRGXFWAlignChecksMemDesc != NULL)
388 DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWAlignChecksMemDesc);
389 DevmemFwFree(psDevInfo, psDevInfo->psRGXFWAlignChecksMemDesc);
390 psDevInfo->psRGXFWAlignChecksMemDesc = NULL;
396 void RGXSetFirmwareAddress(RGXFWIF_DEV_VIRTADDR *ppDest,
397 DEVMEM_MEMDESC *psSrc,
398 IMG_UINT32 uiExtraOffset,
399 IMG_UINT32 ui32Flags)
402 IMG_DEV_VIRTADDR psDevVirtAddr;
403 PVRSRV_DEVICE_NODE *psDeviceNode;
404 IMG_UINT64 ui64ErnsBrns = 0;
405 PVRSRV_RGXDEV_INFO *psDevInfo;
407 psDeviceNode = (PVRSRV_DEVICE_NODE *) DevmemGetConnection(psSrc);
408 psDevInfo = (PVRSRV_RGXDEV_INFO *)psDeviceNode->pvDevice;
409 ui64ErnsBrns = psDevInfo->sDevFeatureCfg.ui64ErnsBrns;
411 if(psDevInfo->sDevFeatureCfg.ui32META)
413 IMG_UINT32 ui32Offset;
414 IMG_BOOL bCachedInMETA;
415 DEVMEM_FLAGS_T uiDevFlags;
416 IMG_UINT32 uiGPUCacheMode;
418 eError = DevmemAcquireDevVirtAddr(psSrc, &psDevVirtAddr);
419 PVR_ASSERT(eError == PVRSRV_OK);
421 /* Convert to an address in META memmap */
422 ui32Offset = psDevVirtAddr.uiAddr + uiExtraOffset - RGX_FIRMWARE_HEAP_BASE ;
424 /* Check in the devmem flags whether this memory is cached/uncached */
425 DevmemGetFlags(psSrc, &uiDevFlags);
427 /* Honour the META cache flags */
428 bCachedInMETA = (PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED) & uiDevFlags) != 0;
430 /* Honour the SLC cache flags */
431 uiGPUCacheMode = DevmemDeviceCacheMode(psDeviceNode, uiDevFlags);
433 ui32Offset += RGXFW_SEGMMU_DATA_BASE_ADDRESS;
437 ui32Offset |= RGXFW_SEGMMU_DATA_META_CACHED;
441 ui32Offset |= RGXFW_SEGMMU_DATA_META_UNCACHED;
444 if (PVRSRV_CHECK_GPU_CACHED(uiGPUCacheMode))
446 ui32Offset |= RGXFW_SEGMMU_DATA_VIVT_SLC_CACHED;
450 ui32Offset |= RGXFW_SEGMMU_DATA_VIVT_SLC_UNCACHED;
452 ppDest->ui32Addr = ui32Offset;
455 eError = DevmemAcquireDevVirtAddr(psSrc, &psDevVirtAddr);
456 PVR_ASSERT(eError == PVRSRV_OK);
457 ppDest->ui32Addr = (IMG_UINT32)((psDevVirtAddr.uiAddr + uiExtraOffset) & 0xFFFFFFFF);
460 if (ui32Flags & RFW_FWADDR_NOREF_FLAG)
462 DevmemReleaseDevVirtAddr(psSrc);
467 void RGXSetMetaDMAAddress(RGXFWIF_DMA_ADDR *psDest,
468 DEVMEM_MEMDESC *psSrcMemDesc,
469 RGXFWIF_DEV_VIRTADDR *psSrcFWDevVAddr,
473 IMG_DEV_VIRTADDR sDevVirtAddr;
475 eError = DevmemAcquireDevVirtAddr(psSrcMemDesc, &sDevVirtAddr);
476 PVR_ASSERT(eError == PVRSRV_OK);
478 psDest->psDevVirtAddr.uiAddr = sDevVirtAddr.uiAddr;
479 psDest->psDevVirtAddr.uiAddr += uiOffset;
480 psDest->pbyFWAddr.ui32Addr = psSrcFWDevVAddr->ui32Addr;
482 DevmemReleaseDevVirtAddr(psSrcMemDesc);
486 void RGXUnsetFirmwareAddress(DEVMEM_MEMDESC *psSrc)
488 DevmemReleaseDevVirtAddr(psSrc);
491 struct _RGX_SERVER_COMMON_CONTEXT_ {
492 PVRSRV_RGXDEV_INFO *psDevInfo;
493 DEVMEM_MEMDESC *psFWCommonContextMemDesc;
494 PRGXFWIF_FWCOMMONCONTEXT sFWCommonContextFWAddr;
495 DEVMEM_MEMDESC *psFWMemContextMemDesc;
496 DEVMEM_MEMDESC *psFWFrameworkMemDesc;
497 DEVMEM_MEMDESC *psContextStateMemDesc;
498 RGX_CLIENT_CCB *psClientCCB;
499 DEVMEM_MEMDESC *psClientCCBMemDesc;
500 DEVMEM_MEMDESC *psClientCCBCtrlMemDesc;
501 IMG_BOOL bCommonContextMemProvided;
502 IMG_UINT32 ui32ContextID;
503 DLLIST_NODE sListNode;
504 RGXFWIF_CONTEXT_RESET_REASON eLastResetReason;
505 IMG_UINT32 ui32LastResetJobRef;
508 PVRSRV_ERROR FWCommonContextAllocate(CONNECTION_DATA *psConnection,
509 PVRSRV_DEVICE_NODE *psDeviceNode,
510 RGX_CCB_REQUESTOR_TYPE eRGXCCBRequestor,
512 DEVMEM_MEMDESC *psAllocatedMemDesc,
513 IMG_UINT32 ui32AllocatedOffset,
514 DEVMEM_MEMDESC *psFWMemContextMemDesc,
515 DEVMEM_MEMDESC *psContextStateMemDesc,
516 IMG_UINT32 ui32CCBAllocSize,
517 IMG_UINT32 ui32Priority,
518 RGX_COMMON_CONTEXT_INFO *psInfo,
519 RGX_SERVER_COMMON_CONTEXT **ppsServerCommonContext)
521 PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
522 RGX_SERVER_COMMON_CONTEXT *psServerCommonContext;
523 RGXFWIF_FWCOMMONCONTEXT *psFWCommonContext;
524 IMG_UINT32 ui32FWCommonContextOffset;
529 Allocate all the resources that are required
531 psServerCommonContext = OSAllocMem(sizeof(*psServerCommonContext));
532 if (psServerCommonContext == NULL)
534 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
538 psServerCommonContext->psDevInfo = psDevInfo;
540 if (psAllocatedMemDesc)
542 PDUMPCOMMENT("Using existing MemDesc for Rogue firmware %s context (offset = %d)",
543 aszCCBRequestors[eRGXCCBRequestor][REQ_PDUMP_COMMENT],
544 ui32AllocatedOffset);
545 ui32FWCommonContextOffset = ui32AllocatedOffset;
546 psServerCommonContext->psFWCommonContextMemDesc = psAllocatedMemDesc;
547 psServerCommonContext->bCommonContextMemProvided = IMG_TRUE;
551 /* Allocate device memory for the firmware context */
552 PDUMPCOMMENT("Allocate Rogue firmware %s context", aszCCBRequestors[eRGXCCBRequestor][REQ_PDUMP_COMMENT]);
553 eError = DevmemFwAllocate(psDevInfo,
554 sizeof(*psFWCommonContext),
555 RGX_FWCOMCTX_ALLOCFLAGS,
557 &psServerCommonContext->psFWCommonContextMemDesc);
558 if (eError != PVRSRV_OK)
560 PVR_DPF((PVR_DBG_ERROR,"%s : Failed to allocate firmware %s context (%s)",
562 aszCCBRequestors[eRGXCCBRequestor][REQ_PDUMP_COMMENT],
563 PVRSRVGetErrorStringKM(eError)));
564 goto fail_contextalloc;
566 ui32FWCommonContextOffset = 0;
567 psServerCommonContext->bCommonContextMemProvided = IMG_FALSE;
570 /* Record this context so we can refer to it if the FW needs to tell us it was reset. */
571 psServerCommonContext->eLastResetReason = RGXFWIF_CONTEXT_RESET_REASON_NONE;
572 psServerCommonContext->ui32LastResetJobRef = 0;
573 psServerCommonContext->ui32ContextID = psDevInfo->ui32CommonCtxtCurrentID++;
575 /* Allocate the client CCB */
576 eError = RGXCreateCCB(psDevInfo,
580 psServerCommonContext,
581 &psServerCommonContext->psClientCCB,
582 &psServerCommonContext->psClientCCBMemDesc,
583 &psServerCommonContext->psClientCCBCtrlMemDesc);
584 if (eError != PVRSRV_OK)
586 PVR_DPF((PVR_DBG_ERROR, "%s: failed to create CCB for %s context(%s)",
588 aszCCBRequestors[eRGXCCBRequestor][REQ_PDUMP_COMMENT],
589 PVRSRVGetErrorStringKM(eError)));
590 goto fail_allocateccb;
594 Temporarily map the firmware context to the kernel and init it
596 eError = DevmemAcquireCpuVirtAddr(psServerCommonContext->psFWCommonContextMemDesc,
598 if (eError != PVRSRV_OK)
600 PVR_DPF((PVR_DBG_ERROR,"%s: Failed to map firmware %s context (%s)to CPU",
602 aszCCBRequestors[eRGXCCBRequestor][REQ_PDUMP_COMMENT],
603 PVRSRVGetErrorStringKM(eError)));
604 goto fail_cpuvirtacquire;
607 psFWCommonContext = (RGXFWIF_FWCOMMONCONTEXT *) (pui8Ptr + ui32FWCommonContextOffset);
608 psFWCommonContext->eDM = eDM;
610 /* Set the firmware CCB device addresses in the firmware common context */
611 RGXSetFirmwareAddress(&psFWCommonContext->psCCB,
612 psServerCommonContext->psClientCCBMemDesc,
613 0, RFW_FWADDR_FLAG_NONE);
614 RGXSetFirmwareAddress(&psFWCommonContext->psCCBCtl,
615 psServerCommonContext->psClientCCBCtrlMemDesc,
616 0, RFW_FWADDR_FLAG_NONE);
618 if (psDevInfo->sDevFeatureCfg.ui64Features & RGX_FEATURE_META_DMA_BIT_MASK)
620 RGXSetMetaDMAAddress(&psFWCommonContext->sCCBMetaDMAAddr,
621 psServerCommonContext->psClientCCBMemDesc,
622 &psFWCommonContext->psCCB,
626 /* Set the memory context device address */
627 psServerCommonContext->psFWMemContextMemDesc = psFWMemContextMemDesc;
628 RGXSetFirmwareAddress(&psFWCommonContext->psFWMemContext,
629 psFWMemContextMemDesc,
630 0, RFW_FWADDR_FLAG_NONE);
632 /* Set the framework register updates address */
633 psServerCommonContext->psFWFrameworkMemDesc = psInfo->psFWFrameworkMemDesc;
634 if (psInfo->psFWFrameworkMemDesc != NULL)
636 RGXSetFirmwareAddress(&psFWCommonContext->psRFCmd,
637 psInfo->psFWFrameworkMemDesc,
638 0, RFW_FWADDR_FLAG_NONE);
642 /* This should never be touched in this contexts without a framework
643 * memdesc, but ensure it is zero so we see crashes if it is.
645 psFWCommonContext->psRFCmd.ui32Addr = 0;
648 psFWCommonContext->ui32Priority = ui32Priority;
649 psFWCommonContext->ui32PrioritySeqNum = 0;
651 if(psInfo->psMCUFenceAddr != NULL)
653 psFWCommonContext->ui64MCUFenceAddr = psInfo->psMCUFenceAddr->uiAddr;
656 if((psDevInfo->sDevFeatureCfg.ui32CtrlStreamFormat == 2) && \
657 (psDevInfo->sDevFeatureCfg.ui64Features & RGX_FEATURE_SIGNAL_SNOOPING_BIT_MASK))
659 if (eDM == RGXFWIF_DM_CDM)
661 if(psInfo->psResumeSignalAddr != NULL)
663 psFWCommonContext->ui64ResumeSignalAddr = psInfo->psResumeSignalAddr->uiAddr;
668 /* Store a references to Server Common Context and PID for notifications back from the FW. */
669 psFWCommonContext->ui32ServerCommonContextID = psServerCommonContext->ui32ContextID;
670 psFWCommonContext->ui32PID = OSGetCurrentClientProcessIDKM();
672 /* Set the firmware GPU context state buffer */
673 psServerCommonContext->psContextStateMemDesc = psContextStateMemDesc;
674 if (psContextStateMemDesc)
676 RGXSetFirmwareAddress(&psFWCommonContext->psContextState,
677 psContextStateMemDesc,
679 RFW_FWADDR_FLAG_NONE);
683 * Dump the created context
685 PDUMPCOMMENT("Dump %s context", aszCCBRequestors[eRGXCCBRequestor][REQ_PDUMP_COMMENT]);
686 DevmemPDumpLoadMem(psServerCommonContext->psFWCommonContextMemDesc,
687 ui32FWCommonContextOffset,
688 sizeof(*psFWCommonContext),
689 PDUMP_FLAGS_CONTINUOUS);
691 /* We've finished the setup so release the CPU mapping */
692 DevmemReleaseCpuVirtAddr(psServerCommonContext->psFWCommonContextMemDesc);
694 /* Map this allocation into the FW */
695 RGXSetFirmwareAddress(&psServerCommonContext->sFWCommonContextFWAddr,
696 psServerCommonContext->psFWCommonContextMemDesc,
697 ui32FWCommonContextOffset,
698 RFW_FWADDR_FLAG_NONE);
702 IMG_UINT32 ui32FWAddr = 0;
705 ui32FWAddr = (IMG_UINT32) ((uintptr_t) IMG_CONTAINER_OF((void *) ((uintptr_t)
706 psServerCommonContext->sFWCommonContextFWAddr.ui32Addr), RGXFWIF_FWRENDERCONTEXT, sTAContext));
709 ui32FWAddr = (IMG_UINT32) ((uintptr_t) IMG_CONTAINER_OF((void *) ((uintptr_t)
710 psServerCommonContext->sFWCommonContextFWAddr.ui32Addr), RGXFWIF_FWRENDERCONTEXT, s3DContext));
713 ui32FWAddr = psServerCommonContext->sFWCommonContextFWAddr.ui32Addr;
717 trace_rogue_create_fw_context(OSGetCurrentClientProcessNameKM(),
718 aszCCBRequestors[eRGXCCBRequestor][REQ_PDUMP_COMMENT],
722 /*Add the node to the list when finalised */
723 dllist_add_to_tail(&(psDevInfo->sCommonCtxtListHead), &(psServerCommonContext->sListNode));
725 *ppsServerCommonContext = psServerCommonContext;
729 DevmemReleaseCpuVirtAddr(psServerCommonContext->psFWCommonContextMemDesc);
731 RGXUnsetFirmwareAddress(psServerCommonContext->psFWCommonContextMemDesc);
732 if (!psServerCommonContext->bCommonContextMemProvided)
734 DevmemFwFree(psDevInfo, psServerCommonContext->psFWCommonContextMemDesc);
735 psServerCommonContext->psFWCommonContextMemDesc = NULL;
738 OSFreeMem(psServerCommonContext);
743 void FWCommonContextFree(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext)
746 /* Remove the context from the list of all contexts. */
747 dllist_remove_node(&psServerCommonContext->sListNode);
750 Unmap the context itself and then all it's resources
753 /* Unmap the FW common context */
754 RGXUnsetFirmwareAddress(psServerCommonContext->psFWCommonContextMemDesc);
755 /* Umap context state buffer (if there was one) */
756 if (psServerCommonContext->psContextStateMemDesc)
758 RGXUnsetFirmwareAddress(psServerCommonContext->psContextStateMemDesc);
760 /* Unmap the framework buffer */
761 if (psServerCommonContext->psFWFrameworkMemDesc)
763 RGXUnsetFirmwareAddress(psServerCommonContext->psFWFrameworkMemDesc);
765 /* Unmap client CCB and CCB control */
766 RGXUnsetFirmwareAddress(psServerCommonContext->psClientCCBCtrlMemDesc);
767 RGXUnsetFirmwareAddress(psServerCommonContext->psClientCCBMemDesc);
768 /* Unmap the memory context */
769 RGXUnsetFirmwareAddress(psServerCommonContext->psFWMemContextMemDesc);
771 /* Destroy the client CCB */
772 RGXDestroyCCB(psServerCommonContext->psDevInfo, psServerCommonContext->psClientCCB);
775 /* Free the FW common context (if there was one) */
776 if (!psServerCommonContext->bCommonContextMemProvided)
778 DevmemFwFree(psServerCommonContext->psDevInfo,
779 psServerCommonContext->psFWCommonContextMemDesc);
780 psServerCommonContext->psFWCommonContextMemDesc = NULL;
782 /* Free the hosts representation of the common context */
783 OSFreeMem(psServerCommonContext);
786 PRGXFWIF_FWCOMMONCONTEXT FWCommonContextGetFWAddress(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext)
788 return psServerCommonContext->sFWCommonContextFWAddr;
791 RGX_CLIENT_CCB *FWCommonContextGetClientCCB(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext)
793 return psServerCommonContext->psClientCCB;
796 RGXFWIF_CONTEXT_RESET_REASON FWCommonContextGetLastResetReason(RGX_SERVER_COMMON_CONTEXT *psServerCommonContext,
797 IMG_UINT32 *pui32LastResetJobRef)
799 RGXFWIF_CONTEXT_RESET_REASON eLastResetReason;
801 PVR_ASSERT(psServerCommonContext != NULL);
802 PVR_ASSERT(pui32LastResetJobRef != NULL);
804 /* Take the most recent reason & job ref and reset for next time... */
805 eLastResetReason = psServerCommonContext->eLastResetReason;
806 *pui32LastResetJobRef = psServerCommonContext->ui32LastResetJobRef;
807 psServerCommonContext->eLastResetReason = RGXFWIF_CONTEXT_RESET_REASON_NONE;
808 psServerCommonContext->ui32LastResetJobRef = 0;
810 return eLastResetReason;
814 *******************************************************************************
815 @Function RGXFreeKernelCCB
816 @Description Free the kernel CCB
820 ******************************************************************************/
821 static void RGXFreeKernelCCB(PVRSRV_RGXDEV_INFO *psDevInfo)
823 if (psDevInfo->psKernelCCBMemDesc != NULL)
825 if (psDevInfo->psKernelCCB != NULL)
827 DevmemReleaseCpuVirtAddr(psDevInfo->psKernelCCBMemDesc);
828 psDevInfo->psKernelCCB = NULL;
830 DevmemFwFree(psDevInfo, psDevInfo->psKernelCCBMemDesc);
831 psDevInfo->psKernelCCBMemDesc = NULL;
833 if (psDevInfo->psKernelCCBCtlMemDesc != NULL)
835 if (psDevInfo->psKernelCCBCtl != NULL)
837 DevmemReleaseCpuVirtAddr(psDevInfo->psKernelCCBCtlMemDesc);
838 psDevInfo->psKernelCCBCtl = NULL;
840 DevmemFwFree(psDevInfo, psDevInfo->psKernelCCBCtlMemDesc);
841 psDevInfo->psKernelCCBCtlMemDesc = NULL;
846 *******************************************************************************
847 @Function RGXSetupKernelCCB
848 @Description Allocate and initialise the kernel CCB
851 @Input ui32NumCmdsLog2
855 ******************************************************************************/
856 static PVRSRV_ERROR RGXSetupKernelCCB(PVRSRV_RGXDEV_INFO *psDevInfo,
857 RGXFWIF_INIT *psRGXFWInit,
858 IMG_UINT32 ui32NumCmdsLog2,
859 IMG_UINT32 ui32CmdSize)
862 RGXFWIF_CCB_CTL *psKCCBCtl;
863 DEVMEM_FLAGS_T uiCCBCtlMemAllocFlags, uiCCBMemAllocFlags;
864 IMG_UINT32 ui32kCCBSize = (1U << ui32NumCmdsLog2);
868 * FIXME: the write offset need not be writeable by the firmware, indeed may
869 * not even be needed for reading. Consider moving it to its own data
872 uiCCBCtlMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
873 PVRSRV_MEMALLOCFLAG_GPU_READABLE |
874 PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
875 PVRSRV_MEMALLOCFLAG_CPU_READABLE |
876 PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
877 PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
878 PVRSRV_MEMALLOCFLAG_UNCACHED |
879 PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
881 /* Allocation flags for Kernel CCB */
882 uiCCBMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
883 PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED) |
884 PVRSRV_MEMALLOCFLAG_GPU_READABLE |
885 PVRSRV_MEMALLOCFLAG_CPU_READABLE |
886 PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
887 PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
888 PVRSRV_MEMALLOCFLAG_UNCACHED |
889 PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
892 * Allocate memory for the kernel CCB control.
894 PDUMPCOMMENT("Allocate memory for kernel CCB control");
895 eError = DevmemFwAllocate(psDevInfo,
896 sizeof(RGXFWIF_CCB_CTL),
897 uiCCBCtlMemAllocFlags,
898 "FwKernelCCBControl",
899 &psDevInfo->psKernelCCBCtlMemDesc);
901 if (eError != PVRSRV_OK)
903 PVR_DPF((PVR_DBG_ERROR,"RGXSetupKernelCCB: Failed to allocate kernel CCB ctl (%u)", eError));
908 * Allocate memory for the kernel CCB.
909 * (this will reference further command data in non-shared CCBs)
911 PDUMPCOMMENT("Allocate memory for kernel CCB");
912 eError = DevmemFwAllocate(psDevInfo,
913 ui32kCCBSize * ui32CmdSize,
916 &psDevInfo->psKernelCCBMemDesc);
918 if (eError != PVRSRV_OK)
920 PVR_DPF((PVR_DBG_ERROR,"RGXSetupKernelCCB: Failed to allocate kernel CCB (%u)", eError));
925 * Map the kernel CCB control to the kernel.
927 eError = DevmemAcquireCpuVirtAddr(psDevInfo->psKernelCCBCtlMemDesc,
928 (void **)&psDevInfo->psKernelCCBCtl);
929 if (eError != PVRSRV_OK)
931 PVR_DPF((PVR_DBG_ERROR,"RGXSetupKernelCCB: Failed to acquire cpu kernel CCB Ctl (%u)", eError));
936 * Map the kernel CCB to the kernel.
938 eError = DevmemAcquireCpuVirtAddr(psDevInfo->psKernelCCBMemDesc,
939 (void **)&psDevInfo->psKernelCCB);
940 if (eError != PVRSRV_OK)
942 PVR_DPF((PVR_DBG_ERROR,"RGXSetupKernelCCB: Failed to acquire cpu kernel CCB (%u)", eError));
947 * Initialise the kernel CCB control.
949 psKCCBCtl = psDevInfo->psKernelCCBCtl;
950 psKCCBCtl->ui32WriteOffset = 0;
951 psKCCBCtl->ui32ReadOffset = 0;
952 psKCCBCtl->ui32WrapMask = ui32kCCBSize - 1;
953 psKCCBCtl->ui32CmdSize = ui32CmdSize;
956 * Set-up RGXFWIfCtl pointers to access the kCCB
958 RGXSetFirmwareAddress(&psRGXFWInit->psKernelCCBCtl,
959 psDevInfo->psKernelCCBCtlMemDesc,
960 0, RFW_FWADDR_NOREF_FLAG);
962 RGXSetFirmwareAddress(&psRGXFWInit->psKernelCCB,
963 psDevInfo->psKernelCCBMemDesc,
964 0, RFW_FWADDR_NOREF_FLAG);
967 * Pdump the kernel CCB control.
969 PDUMPCOMMENT("Initialise kernel CCB ctl");
970 DevmemPDumpLoadMem(psDevInfo->psKernelCCBCtlMemDesc, 0, sizeof(RGXFWIF_CCB_CTL), 0);
975 RGXFreeKernelCCB(psDevInfo);
977 PVR_ASSERT(eError != PVRSRV_OK);
982 *******************************************************************************
983 @Function RGXFreeFirmwareCCB
984 @Description Free the firmware CCB
986 @Input ppsFirmwareCCBCtl
987 @Input ppsFirmwareCCBCtlMemDesc
988 @Input ppui8FirmwareCCB
989 @Input ppsFirmwareCCBMemDesc
992 ******************************************************************************/
993 static void RGXFreeFirmwareCCB(PVRSRV_RGXDEV_INFO *psDevInfo,
994 RGXFWIF_CCB_CTL **ppsFirmwareCCBCtl,
995 DEVMEM_MEMDESC **ppsFirmwareCCBCtlMemDesc,
996 IMG_UINT8 **ppui8FirmwareCCB,
997 DEVMEM_MEMDESC **ppsFirmwareCCBMemDesc)
999 if (*ppsFirmwareCCBMemDesc != NULL)
1001 if (*ppui8FirmwareCCB != NULL)
1003 DevmemReleaseCpuVirtAddr(*ppsFirmwareCCBMemDesc);
1004 *ppui8FirmwareCCB = NULL;
1006 DevmemFwFree(psDevInfo, *ppsFirmwareCCBMemDesc);
1007 *ppsFirmwareCCBMemDesc = NULL;
1009 if (*ppsFirmwareCCBCtlMemDesc != NULL)
1011 if (*ppsFirmwareCCBCtl != NULL)
1013 DevmemReleaseCpuVirtAddr(*ppsFirmwareCCBCtlMemDesc);
1014 *ppsFirmwareCCBCtl = NULL;
1016 DevmemFwFree(psDevInfo, *ppsFirmwareCCBCtlMemDesc);
1017 *ppsFirmwareCCBCtlMemDesc = NULL;
1021 #define INPUT_STR_SIZE_MAX 13
1022 #define APPEND_STR_SIZE 7
1023 #define COMBINED_STR_LEN_MAX (INPUT_STR_SIZE_MAX + APPEND_STR_SIZE + 1)
1026 *******************************************************************************
1027 @Function RGXSetupFirmwareCCB
1028 @Description Allocate and initialise a Firmware CCB
1030 @Input ppsFirmwareCCBCtl
1031 @Input ppsFirmwareCCBCtlMemDesc
1032 @Input ppui8FirmwareCCB
1033 @Input ppsFirmwareCCBMemDesc
1034 @Input psFirmwareCCBCtlFWAddr
1035 @Input psFirmwareCCBFWAddr
1036 @Input ui32NumCmdsLog2
1038 @Input pszName Must be less than or equal to
1040 @Return PVRSRV_ERROR
1041 ******************************************************************************/
1042 static PVRSRV_ERROR RGXSetupFirmwareCCB(PVRSRV_RGXDEV_INFO *psDevInfo,
1043 RGXFWIF_CCB_CTL **ppsFirmwareCCBCtl,
1044 DEVMEM_MEMDESC **ppsFirmwareCCBCtlMemDesc,
1045 IMG_UINT8 **ppui8FirmwareCCB,
1046 DEVMEM_MEMDESC **ppsFirmwareCCBMemDesc,
1047 PRGXFWIF_CCB_CTL *psFirmwareCCBCtlFWAddr,
1048 PRGXFWIF_CCB *psFirmwareCCBFWAddr,
1049 IMG_UINT32 ui32NumCmdsLog2,
1050 IMG_UINT32 ui32CmdSize,
1053 PVRSRV_ERROR eError;
1054 RGXFWIF_CCB_CTL *psFWCCBCtl;
1055 DEVMEM_FLAGS_T uiCCBCtlMemAllocFlags, uiCCBMemAllocFlags;
1056 IMG_UINT32 ui32FWCCBSize = (1U << ui32NumCmdsLog2);
1057 IMG_CHAR sCCBCtlName[COMBINED_STR_LEN_MAX] = "";
1058 IMG_CHAR sAppend[] = "Control";
1061 * FIXME: the write offset need not be writeable by the host, indeed may
1062 * not even be needed for reading. Consider moving it to its own data
1065 uiCCBCtlMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
1066 PVRSRV_MEMALLOCFLAG_GPU_READABLE |
1067 PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
1068 PVRSRV_MEMALLOCFLAG_CPU_READABLE |
1069 PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
1070 PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
1071 PVRSRV_MEMALLOCFLAG_UNCACHED |
1072 PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
1074 /* Allocation flags for Firmware CCB */
1075 uiCCBMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
1076 PVRSRV_MEMALLOCFLAG_GPU_READABLE |
1077 PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
1078 PVRSRV_MEMALLOCFLAG_CPU_READABLE |
1079 PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
1080 PVRSRV_MEMALLOCFLAG_UNCACHED |
1081 PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
1083 PVR_ASSERT(strlen(sCCBCtlName) == 0);
1084 PVR_ASSERT(strlen(sAppend) == APPEND_STR_SIZE);
1085 PVR_ASSERT(strlen(pszName) <= INPUT_STR_SIZE_MAX);
1087 /* Append "Control" to the name for the control struct. */
1088 strncat(sCCBCtlName, pszName, INPUT_STR_SIZE_MAX);
1089 strncat(sCCBCtlName, sAppend, APPEND_STR_SIZE);
1092 Allocate memory for the Firmware CCB control.
1094 PDUMPCOMMENT("Allocate memory for %s", sCCBCtlName);
1095 eError = DevmemFwAllocate(psDevInfo,
1096 sizeof(RGXFWIF_CCB_CTL),
1097 uiCCBCtlMemAllocFlags,
1099 ppsFirmwareCCBCtlMemDesc);
1101 if (eError != PVRSRV_OK)
1103 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmwareCCB: Failed to allocate %s (%u)", sCCBCtlName, eError));
1108 Allocate memory for the Firmware CCB.
1109 (this will reference further command data in non-shared CCBs)
1111 PDUMPCOMMENT("Allocate memory for %s", pszName);
1112 eError = DevmemFwAllocate(psDevInfo,
1113 ui32FWCCBSize * ui32CmdSize,
1116 ppsFirmwareCCBMemDesc);
1118 if (eError != PVRSRV_OK)
1120 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmwareCCB: Failed to allocate %s (%u)", pszName, eError));
1125 Map the Firmware CCB control to the kernel.
1127 eError = DevmemAcquireCpuVirtAddr(*ppsFirmwareCCBCtlMemDesc,
1128 (void **)ppsFirmwareCCBCtl);
1129 if (eError != PVRSRV_OK)
1131 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmwareCCB: Failed to acquire cpu %s (%u)", sCCBCtlName, eError));
1136 Map the firmware CCB to the kernel.
1138 eError = DevmemAcquireCpuVirtAddr(*ppsFirmwareCCBMemDesc,
1139 (void **)ppui8FirmwareCCB);
1140 if (eError != PVRSRV_OK)
1142 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmwareCCB: Failed to acquire cpu %s (%u)", pszName, eError));
1147 * Initialise the firmware CCB control.
1149 psFWCCBCtl = *ppsFirmwareCCBCtl;
1150 psFWCCBCtl->ui32WriteOffset = 0;
1151 psFWCCBCtl->ui32ReadOffset = 0;
1152 psFWCCBCtl->ui32WrapMask = ui32FWCCBSize - 1;
1153 psFWCCBCtl->ui32CmdSize = ui32CmdSize;
1156 * Set-up RGXFWIfCtl pointers to access the kCCBs
1158 RGXSetFirmwareAddress(psFirmwareCCBCtlFWAddr,
1159 *ppsFirmwareCCBCtlMemDesc,
1160 0, RFW_FWADDR_NOREF_FLAG);
1162 RGXSetFirmwareAddress(psFirmwareCCBFWAddr,
1163 *ppsFirmwareCCBMemDesc,
1164 0, RFW_FWADDR_NOREF_FLAG);
1167 * Pdump the kernel CCB control.
1169 PDUMPCOMMENT("Initialise %s", sCCBCtlName);
1170 DevmemPDumpLoadMem(*ppsFirmwareCCBCtlMemDesc,
1172 sizeof(RGXFWIF_CCB_CTL),
1178 RGXFreeFirmwareCCB(psDevInfo,
1180 ppsFirmwareCCBCtlMemDesc,
1182 ppsFirmwareCCBMemDesc);
1184 PVR_ASSERT(eError != PVRSRV_OK);
1188 static void RGXSetupFaultReadRegisterRollback(PVRSRV_RGXDEV_INFO *psDevInfo)
1192 if (psDevInfo->psRGXFaultAddressMemDesc)
1194 if (DevmemServerGetImportHandle(psDevInfo->psRGXFaultAddressMemDesc,(void **)&psPMR) == PVRSRV_OK)
1196 PMRUnlockSysPhysAddresses(psPMR);
1198 DevmemFwFree(psDevInfo, psDevInfo->psRGXFaultAddressMemDesc);
1199 psDevInfo->psRGXFaultAddressMemDesc = NULL;
1203 static PVRSRV_ERROR RGXSetupFaultReadRegister(PVRSRV_DEVICE_NODE *psDeviceNode, RGXFWIF_INIT *psRGXFWInit)
1205 PVRSRV_ERROR eError = PVRSRV_OK;
1206 #if !defined(PVRSRV_GPUVIRT_GUESTDRV)
1207 IMG_UINT32 *pui32MemoryVirtAddr;
1209 size_t ui32PageSize;
1210 DEVMEM_FLAGS_T uiMemAllocFlags;
1211 PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
1214 ui32PageSize = OSGetPageSize();
1216 /* Allocate page of memory to use for page faults on non-blocking memory transactions */
1217 uiMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
1218 PVRSRV_MEMALLOCFLAG_GPU_READABLE |
1219 PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
1220 PVRSRV_MEMALLOCFLAG_CPU_READABLE |
1221 PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
1222 PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
1223 PVRSRV_MEMALLOCFLAG_UNCACHED;
1225 psDevInfo->psRGXFaultAddressMemDesc = NULL;
1226 eError = DevmemFwAllocateExportable(psDeviceNode,
1231 &psDevInfo->psRGXFaultAddressMemDesc);
1233 if (eError != PVRSRV_OK)
1235 PVR_DPF((PVR_DBG_ERROR,"Failed to allocate mem for fault address (%u)",
1237 goto failFaultAddressDescAlloc;
1241 eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFaultAddressMemDesc,
1242 (void **)&pui32MemoryVirtAddr);
1243 if (eError != PVRSRV_OK)
1245 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to acquire mem for fault address (%u)",
1247 goto failFaultAddressDescAqCpuVirt;
1250 for (i = 0; i < ui32PageSize/sizeof(IMG_UINT32); i++)
1252 *(pui32MemoryVirtAddr + i) = 0xDEADBEEF;
1255 eError = DevmemServerGetImportHandle(psDevInfo->psRGXFaultAddressMemDesc,(void **)&psPMR);
1257 if (eError != PVRSRV_OK)
1259 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Error getting PMR for fault address (%u)",
1262 goto failFaultAddressDescGetPMR;
1267 IMG_UINT32 ui32Log2PageSize = OSGetPageShift();
1269 eError = PMRLockSysPhysAddresses(psPMR);
1271 if (eError != PVRSRV_OK)
1273 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Error locking physical address for fault address MemDesc (%u)",
1276 goto failFaultAddressDescLockPhys;
1279 eError = PMR_DevPhysAddr(psPMR,ui32Log2PageSize,1,0,&(psRGXFWInit->sFaultPhysAddr),&bValid);
1281 if (eError != PVRSRV_OK)
1283 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Error getting physical address for fault address MemDesc (%u)",
1286 goto failFaultAddressDescGetPhys;
1291 psRGXFWInit->sFaultPhysAddr.uiAddr = 0;
1292 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed getting physical address for fault address MemDesc - invalid page (0x%llX)",
1293 psRGXFWInit->sFaultPhysAddr.uiAddr));
1295 goto failFaultAddressDescGetPhys;
1299 DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFaultAddressMemDesc);
1303 failFaultAddressDescGetPhys:
1304 PMRUnlockSysPhysAddresses(psPMR);
1306 failFaultAddressDescLockPhys:
1308 failFaultAddressDescGetPMR:
1309 DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFaultAddressMemDesc);
1311 failFaultAddressDescAqCpuVirt:
1312 DevmemFwFree(psDevInfo, psDevInfo->psRGXFaultAddressMemDesc);
1313 psDevInfo->psRGXFaultAddressMemDesc = NULL;
1315 failFaultAddressDescAlloc:
1320 static PVRSRV_ERROR RGXHwBrn37200(PVRSRV_RGXDEV_INFO *psDevInfo)
1322 PVRSRV_ERROR eError = PVRSRV_OK;
1324 #if !defined(PVRSRV_GPUVIRT_GUESTDRV)
1325 IMG_UINT64 ui64ErnsBrns = psDevInfo->sDevFeatureCfg.ui64ErnsBrns;
1326 IMG_UINT32 ui32CacheLineSize = GET_ROGUE_CACHE_LINE_SIZE(psDevInfo->sDevFeatureCfg.ui32CacheLineSize);
1328 if(ui64ErnsBrns & FIX_HW_BRN_37200_BIT_MASK)
1330 struct _DEVMEM_HEAP_ *psBRNHeap;
1331 DEVMEM_FLAGS_T uiFlags;
1332 IMG_DEV_VIRTADDR sTmpDevVAddr;
1335 uiPageSize = OSGetPageSize();
1337 uiFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
1338 PVRSRV_MEMALLOCFLAG_GPU_READABLE |
1339 PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
1340 PVRSRV_MEMALLOCFLAG_CPU_READABLE |
1341 PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
1342 PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
1343 PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT |
1344 PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE |
1345 PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
1347 eError = DevmemFindHeapByName(psDevInfo->psKernelDevmemCtx,
1348 "HWBRN37200", /* FIXME: We need to create an IDENT macro for this string.
1349 Make sure the IDENT macro is not accessible to userland */
1352 if (eError != PVRSRV_OK)
1354 PVR_DPF((PVR_DBG_ERROR,"RGXHwBrn37200: HWBRN37200 Failed DevmemFindHeapByName (%u)", eError));
1355 goto failFWHWBRN37200FindHeapByName;
1358 psDevInfo->psRGXFWHWBRN37200MemDesc = NULL;
1359 eError = DevmemAllocate(psBRNHeap,
1364 &psDevInfo->psRGXFWHWBRN37200MemDesc);
1366 if (eError != PVRSRV_OK)
1368 PVR_DPF((PVR_DBG_ERROR,"RGXHwBrn37200: Failed to allocate %u bytes for HWBRN37200 (%u)",
1369 (IMG_UINT32)uiPageSize,
1371 goto failFWHWBRN37200MemDescAlloc;
1375 We need to map it so the heap for this allocation
1378 eError = DevmemMapToDevice(psDevInfo->psRGXFWHWBRN37200MemDesc,
1382 if (eError != PVRSRV_OK)
1384 PVR_DPF((PVR_DBG_ERROR,"RGXHwBrn37200: Failed to allocate %u bytes for HWBRN37200 (%u)",
1385 (IMG_UINT32)uiPageSize,
1387 goto failFWHWBRN37200DevmemMapToDevice;
1394 failFWHWBRN37200DevmemMapToDevice:
1396 failFWHWBRN37200MemDescAlloc:
1397 DevmemFwFree(psDevInfo, psDevInfo->psRGXFWHWBRN37200MemDesc);
1398 psDevInfo->psRGXFWHWBRN37200MemDesc = NULL;
1400 failFWHWBRN37200FindHeapByName:;
1406 #if !defined(PVRSRV_GPUVIRT_GUESTDRV)
1407 /*************************************************************************/ /*!
1408 @Function RGXTraceBufferIsInitRequired
1410 @Description Returns true if the firmware trace buffer is not allocated and
1411 might be required by the firmware soon. Trace buffer allocated
1412 on-demand to reduce RAM footprint on systems not needing
1415 @Input psDevInfo RGX device info
1417 @Return IMG_BOOL Whether on-demand allocation(s) is/are needed
1419 */ /**************************************************************************/
1420 INLINE IMG_BOOL RGXTraceBufferIsInitRequired(PVRSRV_RGXDEV_INFO *psDevInfo)
1422 RGXFWIF_TRACEBUF* psTraceBufCtl = psDevInfo->psRGXFWIfTraceBuf;
1424 /* The firmware expects a trace buffer only when:
1425 * - Logtype is "trace" AND
1426 * - at least one LogGroup is configured
1428 if((psDevInfo->psRGXFWIfTraceBufferMemDesc[0] == NULL)
1429 && (psTraceBufCtl->ui32LogType & RGXFWIF_LOG_TYPE_TRACE)
1430 && (psTraceBufCtl->ui32LogType & RGXFWIF_LOG_TYPE_GROUP_MASK))
1438 /*************************************************************************/ /*!
1439 @Function RGXTraceBufferInitOnDemandResources
1441 @Description Allocates the firmware trace buffer required for dumping trace
1442 info from the firmware.
1444 @Input psDevInfo RGX device info
1446 @Return PVRSRV_OK If all went good, PVRSRV_ERROR otherwise.
1447 */ /**************************************************************************/
1448 PVRSRV_ERROR RGXTraceBufferInitOnDemandResources(PVRSRV_RGXDEV_INFO *psDevInfo)
1450 RGXFWIF_TRACEBUF* psTraceBufCtl = psDevInfo->psRGXFWIfTraceBuf;
1451 DEVMEM_FLAGS_T uiMemAllocFlags;
1452 PVRSRV_ERROR eError = PVRSRV_OK;
1453 IMG_UINT32 ui32FwThreadNum;
1455 uiMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
1456 PVRSRV_MEMALLOCFLAG_GPU_READABLE |
1457 PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
1458 PVRSRV_MEMALLOCFLAG_CPU_READABLE |
1459 PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
1460 PVRSRV_MEMALLOCFLAG_UNCACHED |
1461 PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
1463 for (ui32FwThreadNum = 0; ui32FwThreadNum < RGXFW_THREAD_NUM; ui32FwThreadNum++)
1465 /* Ensure allocation API is only called when not already allocated */
1466 PVR_ASSERT(psDevInfo->psRGXFWIfTraceBufferMemDesc[ui32FwThreadNum] == NULL);
1468 PDUMPCOMMENT("Allocate rgxfw trace buffer(%u)", ui32FwThreadNum);
1469 eError = DevmemFwAllocate(psDevInfo,
1470 RGXFW_TRACE_BUFFER_SIZE * sizeof(*(psTraceBufCtl->sTraceBuf[ui32FwThreadNum].pui32TraceBuffer)),
1473 &psDevInfo->psRGXFWIfTraceBufferMemDesc[ui32FwThreadNum]);
1474 if (eError != PVRSRV_OK)
1476 PVR_DPF((PVR_DBG_ERROR,"%s: Failed to allocate %zu bytes for fw trace buffer %u (Error code:%u)",
1478 RGXFW_TRACE_BUFFER_SIZE * sizeof(*(psTraceBufCtl->sTraceBuf[ui32FwThreadNum].pui32TraceBuffer)),
1484 /* Firmware address should not be already set */
1485 PVR_ASSERT(psTraceBufCtl->sTraceBuf[ui32FwThreadNum].pui32RGXFWIfTraceBuffer.ui32Addr == 0x0);
1487 /* for the FW to use this address when dumping in log (trace) buffer */
1488 RGXSetFirmwareAddress(&psTraceBufCtl->sTraceBuf[ui32FwThreadNum].pui32RGXFWIfTraceBuffer,
1489 psDevInfo->psRGXFWIfTraceBufferMemDesc[ui32FwThreadNum],
1490 0, RFW_FWADDR_NOREF_FLAG);
1491 /* Set an address for the host to be able to read fw trace buffer */
1492 eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWIfTraceBufferMemDesc[ui32FwThreadNum],
1493 (void **)&psTraceBufCtl->sTraceBuf[ui32FwThreadNum].pui32TraceBuffer);
1494 if (eError != PVRSRV_OK)
1496 PVR_DPF((PVR_DBG_ERROR,"%s: Failed to acquire kernel tracebuf (%u) ctl (Error code: %u)",
1497 __FUNCTION__, ui32FwThreadNum, eError));
1502 /* Just return error in-case of failures, clean-up would be handled by DeInit function */
1507 /*************************************************************************/ /*!
1508 @Function RGXTraceBufferDeinit
1510 @Description Deinitialises all the allocations and references that are made
1511 for the FW trace buffer(s)
1513 @Input ppsDevInfo RGX device info
1515 */ /**************************************************************************/
1516 static void RGXTraceBufferDeinit(PVRSRV_RGXDEV_INFO *psDevInfo)
1518 RGXFWIF_TRACEBUF* psTraceBufCtl = psDevInfo->psRGXFWIfTraceBuf;
1521 for (i = 0; i < RGXFW_THREAD_NUM; i++)
1523 if (psDevInfo->psRGXFWIfTraceBufferMemDesc[i])
1525 if (psTraceBufCtl->sTraceBuf[i].pui32TraceBuffer != NULL)
1527 DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfTraceBufferMemDesc[i]);
1528 psTraceBufCtl->sTraceBuf[i].pui32TraceBuffer = NULL;
1531 DevmemFwFree(psDevInfo, psDevInfo->psRGXFWIfTraceBufferMemDesc[i]);
1532 psDevInfo->psRGXFWIfTraceBufferMemDesc[i] = NULL;
1539 *******************************************************************************
1541 @Function RGXSetupFirmware
1545 Setups all the firmware related data
1549 @Return PVRSRV_ERROR
1551 ******************************************************************************/
1552 PVRSRV_ERROR RGXSetupFirmware(PVRSRV_DEVICE_NODE *psDeviceNode,
1553 IMG_BOOL bEnableSignatureChecks,
1554 IMG_UINT32 ui32SignatureChecksBufSize,
1555 IMG_UINT32 ui32HWPerfFWBufSizeKB,
1556 IMG_UINT64 ui64HWPerfFilter,
1557 IMG_UINT32 ui32RGXFWAlignChecksArrLength,
1558 IMG_UINT32 *pui32RGXFWAlignChecks,
1559 IMG_UINT32 ui32ConfigFlags,
1560 IMG_UINT32 ui32LogType,
1561 RGXFWIF_BIFTILINGMODE eBifTilingMode,
1562 IMG_UINT32 ui32NumTilingCfgs,
1563 IMG_UINT32 *pui32BIFTilingXStrides,
1564 IMG_UINT32 ui32FilterFlags,
1565 IMG_UINT32 ui32JonesDisableMask,
1566 IMG_UINT32 ui32HWRDebugDumpLimit,
1567 IMG_UINT32 ui32HWPerfCountersDataSize,
1569 RGXFWIF_DEV_VIRTADDR *psRGXFWInitFWAddr,
1570 RGX_RD_POWER_ISLAND_CONF eRGXRDPowerIslandConf,
1571 FW_PERF_CONF eFirmwarePerf)
1574 PVRSRV_ERROR eError;
1575 DEVMEM_FLAGS_T uiMemAllocFlags;
1576 RGXFWIF_INIT *psRGXFWInit = NULL;
1577 PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
1578 IMG_UINT32 dm, ui32Temp = 0;
1579 IMG_UINT64 ui64ErnsBrns;
1580 #if defined (SUPPORT_PDVFS)
1581 RGXFWIF_PDVFS_OPP *psPDVFSOPPInfo;
1582 IMG_DVFS_DEVICE_CFG *psDVFSDeviceCfg;
1584 ui64ErnsBrns = psDevInfo->sDevFeatureCfg.ui64ErnsBrns;
1588 uiMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
1589 PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED) |
1590 PVRSRV_MEMALLOCFLAG_GPU_READABLE |
1591 PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
1592 PVRSRV_MEMALLOCFLAG_CPU_READABLE |
1593 PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
1594 PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
1595 PVRSRV_MEMALLOCFLAG_UNCACHED |
1596 PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
1597 /* FIXME: Change to Cached */
1600 PDUMPCOMMENT("Allocate RGXFWIF_INIT structure");
1602 eError = DevmemFwAllocate(psDevInfo,
1603 sizeof(RGXFWIF_INIT),
1606 &psDevInfo->psRGXFWIfInitMemDesc);
1608 if (eError != PVRSRV_OK)
1610 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate %u bytes for fw if ctl (%u)",
1611 (IMG_UINT32)sizeof(RGXFWIF_INIT),
1616 eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWIfInitMemDesc,
1617 (void **)&psRGXFWInit);
1618 if (eError != PVRSRV_OK)
1620 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to acquire kernel fw if ctl (%u)",
1625 RGXSetFirmwareAddress(&psDevInfo->sFWInitFWAddr,
1626 psDevInfo->psRGXFWIfInitMemDesc,
1627 0, RFW_FWADDR_NOREF_FLAG);
1628 *psRGXFWInitFWAddr = psDevInfo->sFWInitFWAddr;
1630 #if defined(PVRSRV_GPUVIRT_GUESTDRV)
1632 * Guest drivers do not support the following functionality:
1633 * - Perform actual on-chip fw loading & initialisation
1634 * - Perform actual on-chip fw management (i.e. reset)
1635 * - Perform actual on-chip fw HWPerf,Trace,Utils,ActivePM
1638 /* FW trace control structure */
1639 uiMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
1640 PVRSRV_MEMALLOCFLAG_GPU_READABLE |
1641 PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
1642 PVRSRV_MEMALLOCFLAG_CPU_READABLE |
1643 PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
1644 PVRSRV_MEMALLOCFLAG_UNCACHED |
1645 PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
1647 PDUMPCOMMENT("Allocate rgxfw trace control structure");
1648 eError = DevmemFwAllocate(psDevInfo,
1649 sizeof(RGXFWIF_TRACEBUF),
1652 &psDevInfo->psRGXFWIfTraceBufCtlMemDesc);
1654 if (eError != PVRSRV_OK)
1656 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate %u bytes for fw trace (%u)",
1657 (IMG_UINT32)sizeof(RGXFWIF_TRACEBUF),
1662 RGXSetFirmwareAddress(&psRGXFWInit->sTraceBufCtl,
1663 psDevInfo->psRGXFWIfTraceBufCtlMemDesc,
1664 0, RFW_FWADDR_NOREF_FLAG);
1666 eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWIfTraceBufCtlMemDesc,
1667 (void **)&psDevInfo->psRGXFWIfTraceBuf);
1668 if (eError != PVRSRV_OK)
1670 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to acquire kernel tracebuf ctl (%u)",
1675 /* Set initial firmware log type/group(s) */
1676 if (ui32LogType & ~RGXFWIF_LOG_TYPE_MASK)
1678 eError = PVRSRV_ERROR_INVALID_PARAMS;
1679 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Invalid initial log type (0x%X)",ui32LogType));
1682 psDevInfo->psRGXFWIfTraceBuf->ui32LogType = ui32LogType;
1685 /* When PDUMP is enabled, ALWAYS allocate on-demand trace buffer resource
1686 * (irrespective of loggroup(s) enabled), given that logtype/loggroups can
1687 * be set during PDump playback in logconfig, at any point of time */
1688 eError = RGXTraceBufferInitOnDemandResources(psDevInfo);
1690 /* Otherwise, allocate only if required */
1691 if (RGXTraceBufferIsInitRequired(psDevInfo))
1693 eError = RGXTraceBufferInitOnDemandResources(psDevInfo);
1700 PVR_LOGG_IF_ERROR(eError, "RGXTraceBufferInitOnDemandResources", fail);
1702 uiMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
1703 PVRSRV_MEMALLOCFLAG_GPU_READABLE |
1704 PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
1705 PVRSRV_MEMALLOCFLAG_CPU_READABLE |
1706 PVRSRV_MEMALLOCFLAG_UNCACHED |
1707 PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
1709 if ((0 != psDevInfo->sDevFeatureCfg.ui32MCMS) && \
1710 (0 == (ui64ErnsBrns & FIX_HW_BRN_50767_BIT_MASK)))
1712 IMG_BOOL bMetaDMA = psDevInfo->sDevFeatureCfg.ui64Features & RGX_FEATURE_META_DMA_BIT_MASK;
1714 #if defined(SUPPORT_TRUSTED_DEVICE)
1717 IMG_UINT64 ui64SecBufHandle;
1719 PDUMPCOMMENT("Import secure buffer to store FW coremem data");
1720 eError = DevmemImportTDSecureBuf(psDeviceNode,
1721 RGX_META_COREMEM_BSS_SIZE,
1724 &psDevInfo->psRGXFWIfCorememDataStoreMemDesc,
1730 PDUMPCOMMENT("Allocate buffer to store FW coremem data");
1731 eError = DevmemFwAllocate(psDevInfo,
1732 RGX_META_COREMEM_BSS_SIZE,
1734 "FwCorememDataStore",
1735 &psDevInfo->psRGXFWIfCorememDataStoreMemDesc);
1738 if (eError != PVRSRV_OK)
1740 PVR_DPF((PVR_DBG_ERROR, "RGXSetupFirmware: Failed to allocate coremem data store (%u)",
1745 RGXSetFirmwareAddress(&psRGXFWInit->sCorememDataStore.pbyFWAddr,
1746 psDevInfo->psRGXFWIfCorememDataStoreMemDesc,
1747 0, RFW_FWADDR_NOREF_FLAG);
1751 RGXSetMetaDMAAddress(&psRGXFWInit->sCorememDataStore,
1752 psDevInfo->psRGXFWIfCorememDataStoreMemDesc,
1753 &psRGXFWInit->sCorememDataStore.pbyFWAddr,
1758 /* init HW frame info */
1759 PDUMPCOMMENT("Allocate rgxfw HW info buffer");
1760 eError = DevmemFwAllocate(psDevInfo,
1761 sizeof(RGXFWIF_HWRINFOBUF),
1764 &psDevInfo->psRGXFWIfHWRInfoBufCtlMemDesc);
1766 if (eError != PVRSRV_OK)
1768 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate %d bytes for HW info (%u)",
1769 (IMG_UINT32)sizeof(RGXFWIF_HWRINFOBUF),
1774 RGXSetFirmwareAddress(&psRGXFWInit->sRGXFWIfHWRInfoBufCtl,
1775 psDevInfo->psRGXFWIfHWRInfoBufCtlMemDesc,
1776 0, RFW_FWADDR_NOREF_FLAG);
1778 eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWIfHWRInfoBufCtlMemDesc,
1779 (void **)&psDevInfo->psRGXFWIfHWRInfoBuf);
1780 if (eError != PVRSRV_OK)
1782 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to acquire kernel tracebuf ctl (%u)",
1787 /* Might be uncached. Be conservative and use a DeviceMemSet */
1788 OSDeviceMemSet(psDevInfo->psRGXFWIfHWRInfoBuf, 0, sizeof(RGXFWIF_HWRINFOBUF));
1790 /* Allocate shared buffer for GPU utilisation */
1791 uiMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
1792 PVRSRV_MEMALLOCFLAG_GPU_READABLE |
1793 PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
1794 PVRSRV_MEMALLOCFLAG_CPU_READABLE |
1795 PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
1796 PVRSRV_MEMALLOCFLAG_UNCACHED |
1797 PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
1799 PDUMPCOMMENT("Allocate shared buffer for GPU utilisation");
1800 eError = DevmemFwAllocate(psDevInfo,
1801 sizeof(RGXFWIF_GPU_UTIL_FWCB),
1803 "FwGPUUtilisationBuffer",
1804 &psDevInfo->psRGXFWIfGpuUtilFWCbCtlMemDesc);
1806 if (eError != PVRSRV_OK)
1808 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate %u bytes for GPU utilisation buffer ctl (%u)",
1809 (IMG_UINT32)sizeof(RGXFWIF_GPU_UTIL_FWCB),
1814 RGXSetFirmwareAddress(&psRGXFWInit->sGpuUtilFWCbCtl,
1815 psDevInfo->psRGXFWIfGpuUtilFWCbCtlMemDesc,
1816 0, RFW_FWADDR_NOREF_FLAG);
1818 eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWIfGpuUtilFWCbCtlMemDesc,
1819 (void **)&psDevInfo->psRGXFWIfGpuUtilFWCb);
1820 if (eError != PVRSRV_OK)
1822 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to acquire kernel GPU utilisation buffer ctl (%u)",
1827 /* Initialise GPU utilisation buffer */
1828 psDevInfo->psRGXFWIfGpuUtilFWCb->ui64LastWord =
1829 RGXFWIF_GPU_UTIL_MAKE_WORD(OSClockns64(),RGXFWIF_GPU_UTIL_STATE_IDLE);
1832 uiMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
1833 PVRSRV_MEMALLOCFLAG_GPU_READABLE |
1834 PVRSRV_MEMALLOCFLAG_CPU_READABLE |
1835 PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
1836 PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
1837 PVRSRV_MEMALLOCFLAG_UNCACHED |
1838 PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
1840 PDUMPCOMMENT("Allocate rgxfw FW runtime configuration (FW)");
1841 eError = DevmemFwAllocate(psDevInfo,
1842 sizeof(RGXFWIF_RUNTIME_CFG),
1845 &psDevInfo->psRGXFWIfRuntimeCfgMemDesc);
1847 if (eError != PVRSRV_OK)
1849 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate %u bytes for FW runtime configuration (%u)",
1850 (IMG_UINT32)sizeof(RGXFWIF_RUNTIME_CFG),
1855 RGXSetFirmwareAddress(&psRGXFWInit->sRuntimeCfg,
1856 psDevInfo->psRGXFWIfRuntimeCfgMemDesc,
1857 0, RFW_FWADDR_NOREF_FLAG);
1859 eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWIfRuntimeCfgMemDesc,
1860 (void **)&psDevInfo->psRGXFWIfRuntimeCfg);
1861 if (eError != PVRSRV_OK)
1863 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to acquire kernel FW runtime configuration (%u)",
1869 /* HWPerf: Determine the size of the FW buffer */
1870 if (ui32HWPerfFWBufSizeKB == 0 ||
1871 ui32HWPerfFWBufSizeKB == RGXFW_HWPERF_L1_SIZE_DEFAULT)
1873 /* Under pvrsrvctl 0 size implies AppHint not set or is set to zero,
1874 * use default size from driver constant. Under SUPPORT_KERNEL_SRVINIT
1875 * default is the above macro. In either case, set it to the default,
1878 psDevInfo->ui32RGXFWIfHWPerfBufSize = RGXFW_HWPERF_L1_SIZE_DEFAULT<<10;
1880 else if (ui32HWPerfFWBufSizeKB > (RGXFW_HWPERF_L1_SIZE_MAX))
1882 /* Size specified as a AppHint but it is too big */
1883 PVR_DPF((PVR_DBG_WARNING,"RGXSetupFirmware: HWPerfFWBufSizeInKB value (%u) too big, using maximum (%u)",
1884 ui32HWPerfFWBufSizeKB, RGXFW_HWPERF_L1_SIZE_MAX));
1885 psDevInfo->ui32RGXFWIfHWPerfBufSize = RGXFW_HWPERF_L1_SIZE_MAX<<10;
1887 else if (ui32HWPerfFWBufSizeKB > (RGXFW_HWPERF_L1_SIZE_MIN))
1889 /* Size specified as in AppHint HWPerfFWBufSizeInKB */
1890 PVR_DPF((PVR_DBG_WARNING,"RGXSetupFirmware: Using HWPerf FW buffer size of %u KB",
1891 ui32HWPerfFWBufSizeKB));
1892 psDevInfo->ui32RGXFWIfHWPerfBufSize = ui32HWPerfFWBufSizeKB<<10;
1896 /* Size specified as a AppHint but it is too small */
1897 PVR_DPF((PVR_DBG_WARNING,"RGXSetupFirmware: HWPerfFWBufSizeInKB value (%u) too small, using minimum (%u)",
1898 ui32HWPerfFWBufSizeKB, RGXFW_HWPERF_L1_SIZE_MIN));
1899 psDevInfo->ui32RGXFWIfHWPerfBufSize = RGXFW_HWPERF_L1_SIZE_MIN<<10;
1902 /* init HWPERF data */
1903 psDevInfo->psRGXFWIfTraceBuf->ui32HWPerfRIdx = 0;
1904 psDevInfo->psRGXFWIfTraceBuf->ui32HWPerfWIdx = 0;
1905 psDevInfo->psRGXFWIfTraceBuf->ui32HWPerfWrapCount = 0;
1906 psDevInfo->psRGXFWIfTraceBuf->ui32HWPerfSize = psDevInfo->ui32RGXFWIfHWPerfBufSize;
1907 psRGXFWInit->bDisableFilterHWPerfCustomCounter = (ui32ConfigFlags & RGXFWIF_INICFG_HWP_DISABLE_FILTER) ? IMG_TRUE : IMG_FALSE;
1908 psDevInfo->psRGXFWIfTraceBuf->ui32HWPerfUt = 0;
1909 psDevInfo->psRGXFWIfTraceBuf->ui32HWPerfDropCount = 0;
1910 psDevInfo->psRGXFWIfTraceBuf->ui32FirstDropOrdinal = 0;
1911 psDevInfo->psRGXFWIfTraceBuf->ui32LastDropOrdinal = 0;
1912 psDevInfo->psRGXFWIfTraceBuf->ui32PowMonEnergy = 0;
1914 /* Second stage initialisation or HWPerf, hHWPerfLock created in first
1915 * stage. See RGXRegisterDevice() call to RGXHWPerfInit(). */
1916 if (psDevInfo->ui64HWPerfFilter == 0)
1918 psDevInfo->ui64HWPerfFilter = ui64HWPerfFilter;
1919 psRGXFWInit->ui64HWPerfFilter = ui64HWPerfFilter;
1923 /* The filter has already been modified. This can happen if the driver
1924 * was compiled with SUPPORT_KERNEL_SRVINIT enabled and e.g.
1925 * pvr/gpu_tracing_on was enabled. */
1926 psRGXFWInit->ui64HWPerfFilter = psDevInfo->ui64HWPerfFilter;
1930 /* When PDUMP is enabled, ALWAYS allocate on-demand HWPerf resources
1931 * (irrespective of HWPerf enabled or not), given that HWPerf can be
1932 * enabled during PDump playback via RTCONF at any point of time. */
1933 eError = RGXHWPerfInitOnDemandResources();
1935 /* Otherwise, only allocate if HWPerf is enabled via apphint */
1936 if (ui32ConfigFlags & RGXFWIF_INICFG_HWPERF_EN)
1938 eError = RGXHWPerfInitOnDemandResources();
1941 PVR_LOGG_IF_ERROR(eError, "RGXHWPerfInitOnDemandResources", fail);
1943 RGXHWPerfInitAppHintCallbacks(psDeviceNode);
1945 #if defined(SUPPORT_USER_REGISTER_CONFIGURATION)
1946 PDUMPCOMMENT("Allocate rgxfw register configuration structure");
1947 eError = DevmemFwAllocate(psDevInfo,
1948 sizeof(RGXFWIF_REG_CFG),
1949 uiMemAllocFlags | PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE,
1950 "FwRegisterConfigStructure",
1951 &psDevInfo->psRGXFWIfRegCfgMemDesc);
1953 if (eError != PVRSRV_OK)
1955 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate %u bytes for fw register configurations (%u)",
1956 (IMG_UINT32)sizeof(RGXFWIF_REG_CFG),
1961 RGXSetFirmwareAddress(&psRGXFWInit->sRegCfg,
1962 psDevInfo->psRGXFWIfRegCfgMemDesc,
1963 0, RFW_FWADDR_NOREF_FLAG);
1966 uiMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
1967 PVRSRV_MEMALLOCFLAG_GPU_READABLE |
1968 PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
1969 PVRSRV_MEMALLOCFLAG_CPU_READABLE |
1970 PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
1971 PVRSRV_MEMALLOCFLAG_UNCACHED |
1972 PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
1974 PDUMPCOMMENT("Allocate rgxfw hwperfctl structure");
1975 eError = DevmemFwAllocateExportable(psDeviceNode,
1976 ui32HWPerfCountersDataSize,
1979 "FwExHWPerfControlStructure",
1980 &psDevInfo->psRGXFWIfHWPerfCountersMemDesc);
1982 if (eError != PVRSRV_OK)
1984 PVR_DPF((PVR_DBG_ERROR,"RGXInitHWPerfCounters: Failed to allocate %u bytes for fw hwperf control (%u)",
1985 ui32HWPerfCountersDataSize,
1990 eError = DevmemLocalGetImportHandle(psDevInfo->psRGXFWIfHWPerfCountersMemDesc, (void**) ppsHWPerfPMR);
1992 if (eError != PVRSRV_OK)
1994 PVR_DPF((PVR_DBG_ERROR,"DevmemLocalGetImportHandle failed (%u)", eError));
1999 RGXSetFirmwareAddress(&psRGXFWInit->sHWPerfCtl,
2000 psDevInfo->psRGXFWIfHWPerfCountersMemDesc,
2003 /* Required info by FW to calculate the ActivePM idle timer latency */
2005 RGX_DATA *psRGXData = (RGX_DATA*) psDeviceNode->psDevConfig->hDevData;
2006 RGXFWIF_RUNTIME_CFG *psRuntimeCfg = psDevInfo->psRGXFWIfRuntimeCfg;
2008 psRGXFWInit->ui32InitialCoreClockSpeed = psRGXData->psRGXTimingInfo->ui32CoreClockSpeed;
2009 psRGXFWInit->ui32ActivePMLatencyms = psRGXData->psRGXTimingInfo->ui32ActivePMLatencyms;
2011 /* Initialise variable runtime configuration to the system defaults */
2012 psRuntimeCfg->ui32CoreClockSpeed = psRGXFWInit->ui32InitialCoreClockSpeed;
2013 psRuntimeCfg->ui32ActivePMLatencyms = psRGXFWInit->ui32ActivePMLatencyms;
2014 psRuntimeCfg->bActivePMLatencyPersistant = IMG_TRUE;
2016 /* Initialize the DefaultDustsNumInit Field to Max Dusts */
2017 psRuntimeCfg->ui32DefaultDustsNumInit = MAX(1, (psDevInfo->sDevFeatureCfg.ui32NumClusters/2));
2020 PDUMPCOMMENT("Dump initial state of FW runtime configuration");
2021 DevmemPDumpLoadMem( psDevInfo->psRGXFWIfRuntimeCfgMemDesc,
2023 sizeof(RGXFWIF_RUNTIME_CFG),
2024 PDUMP_FLAGS_CONTINUOUS);
2026 #endif /* defined(PVRSRV_GPUVIRT_GUESTDRV) */
2028 /* Allocate a sync for power management */
2029 eError = SyncPrimContextCreate(psDevInfo->psDeviceNode,
2030 &psDevInfo->hSyncPrimContext);
2031 if (eError != PVRSRV_OK)
2033 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate sync primitive context with error (%u)", eError));
2037 eError = SyncPrimAlloc(psDevInfo->hSyncPrimContext, &psDevInfo->psPowSyncPrim, "fw power ack");
2038 if (eError != PVRSRV_OK)
2040 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate sync primitive with error (%u)", eError));
2044 eError = SyncPrimGetFirmwareAddr(psDevInfo->psPowSyncPrim,
2045 &psRGXFWInit->sPowerSync.ui32Addr);
2046 if (eError != PVRSRV_OK)
2048 PVR_DPF((PVR_DBG_ERROR,
2049 "%s: Failed to get Sync Prim FW address with error (%u)",
2050 __FUNCTION__, eError));
2054 /* Setup Fault read register */
2055 eError = RGXSetupFaultReadRegister(psDeviceNode, psRGXFWInit);
2056 if (eError != PVRSRV_OK)
2058 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to setup fault read register"));
2062 /* Apply FIX_HW_BRN_37200 */
2063 eError = RGXHwBrn37200(psDevInfo);
2064 if (eError != PVRSRV_OK)
2066 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to apply HWBRN37200"));
2070 #if defined(SUPPORT_PVRSRV_GPUVIRT)
2071 if(!(psDevInfo->sDevFeatureCfg.ui64Features & RGX_FEATURE_GPU_VIRTUALISATION_BIT_MASK))
2073 ui32Temp = RGXFWIF_KCCB_NUMCMDS_LOG2_GPUVIRT_ONLY;
2077 ui32Temp = RGXFWIF_KCCB_NUMCMDS_LOG2_FEAT_GPU_VIRTUALISATION;
2080 * Set up kernel CCB.
2082 eError = RGXSetupKernelCCB(psDevInfo,
2085 sizeof(RGXFWIF_KCCB_CMD));
2086 if (eError != PVRSRV_OK)
2088 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate Kernel CCB"));
2093 * Set up firmware CCB.
2095 eError = RGXSetupFirmwareCCB(psDevInfo,
2096 &psDevInfo->psFirmwareCCBCtl,
2097 &psDevInfo->psFirmwareCCBCtlMemDesc,
2098 &psDevInfo->psFirmwareCCB,
2099 &psDevInfo->psFirmwareCCBMemDesc,
2100 &psRGXFWInit->psFirmwareCCBCtl,
2101 &psRGXFWInit->psFirmwareCCB,
2102 RGXFWIF_FWCCB_NUMCMDS_LOG2,
2103 sizeof(RGXFWIF_FWCCB_CMD),
2106 if (eError != PVRSRV_OK)
2108 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate Firmware CCB"));
2111 /* RD Power Island */
2113 RGX_DATA *psRGXData = (RGX_DATA*) psDeviceNode->psDevConfig->hDevData;
2114 IMG_BOOL bSysEnableRDPowIsland = psRGXData->psRGXTimingInfo->bEnableRDPowIsland;
2115 IMG_BOOL bEnableRDPowIsland = ((eRGXRDPowerIslandConf == RGX_RD_POWER_ISLAND_DEFAULT) && bSysEnableRDPowIsland) ||
2116 (eRGXRDPowerIslandConf == RGX_RD_POWER_ISLAND_FORCE_ON);
2118 ui32ConfigFlags |= bEnableRDPowIsland? RGXFWIF_INICFG_POW_RASCALDUST : 0;
2121 #if defined(SUPPORT_WORKLOAD_ESTIMATION)
2122 ui32ConfigFlags |= RGXFWIF_INICFG_WORKEST_V2;
2124 #if defined(SUPPORT_PDVFS)
2125 /* Proactive DVFS depends on Workload Estimation */
2126 psPDVFSOPPInfo = &(psRGXFWInit->sPDVFSOPPInfo);
2127 psDVFSDeviceCfg = &psDeviceNode->psDevConfig->sDVFS.sDVFSDeviceCfg;
2129 if(psDVFSDeviceCfg->pasOPPTable != NULL)
2131 if(psDVFSDeviceCfg->ui32OPPTableSize >
2132 sizeof(psPDVFSOPPInfo->asOPPValues)/sizeof(psPDVFSOPPInfo->asOPPValues[0]))
2134 PVR_DPF((PVR_DBG_ERROR,
2135 "RGXSetupFirmware: OPP Table too large :"
2136 " Size = %u, Maximum size = %lu",
2137 psDVFSDeviceCfg->ui32OPPTableSize,
2138 (unsigned long)(sizeof(psPDVFSOPPInfo->asOPPValues)/sizeof(psPDVFSOPPInfo->asOPPValues[0]))));
2139 eError = PVRSRV_ERROR_INVALID_PARAMS;
2143 memcpy(psPDVFSOPPInfo->asOPPValues,
2144 psDVFSDeviceCfg->pasOPPTable,
2145 sizeof(psPDVFSOPPInfo->asOPPValues));
2146 psPDVFSOPPInfo->ui32MaxOPPPoint =
2147 (psDVFSDeviceCfg->ui32OPPTableSize) - 1;
2149 ui32ConfigFlags |= RGXFWIF_INICFG_PDVFS_V2;
2153 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Missing OPP Table"));
2158 psRGXFWInit->ui32ConfigFlags = ui32ConfigFlags & RGXFWIF_INICFG_ALL;
2160 #if defined(SUPPORT_WORKLOAD_ESTIMATION)
2162 * Set up Workload Estimation firmware CCB.
2164 eError = RGXSetupFirmwareCCB(psDevInfo,
2165 &psDevInfo->psWorkEstFirmwareCCBCtl,
2166 &psDevInfo->psWorkEstFirmwareCCBCtlMemDesc,
2167 &psDevInfo->psWorkEstFirmwareCCB,
2168 &psDevInfo->psWorkEstFirmwareCCBMemDesc,
2169 &psRGXFWInit->psWorkEstFirmwareCCBCtl,
2170 &psRGXFWInit->psWorkEstFirmwareCCB,
2171 RGXFWIF_WORKEST_FWCCB_NUMCMDS_LOG2,
2172 sizeof(RGXFWIF_WORKEST_FWCCB_CMD),
2175 if (eError != PVRSRV_OK)
2177 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate Workload Estimation Firmware CCB"));
2182 /* Require a minimum amount of memory for the signature buffers */
2183 if (ui32SignatureChecksBufSize < RGXFW_SIG_BUFFER_SIZE_MIN)
2185 ui32SignatureChecksBufSize = RGXFW_SIG_BUFFER_SIZE_MIN;
2188 /* Setup Signature and Checksum Buffers for TA and 3D */
2189 eError = RGXFWSetupSignatureChecks(psDevInfo,
2190 &psDevInfo->psRGXFWSigTAChecksMemDesc,
2191 ui32SignatureChecksBufSize,
2192 &psRGXFWInit->asSigBufCtl[RGXFWIF_DM_TA],
2194 if (eError != PVRSRV_OK)
2196 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to setup TA signature checks"));
2199 psDevInfo->ui32SigTAChecksSize = ui32SignatureChecksBufSize;
2201 eError = RGXFWSetupSignatureChecks(psDevInfo,
2202 &psDevInfo->psRGXFWSig3DChecksMemDesc,
2203 ui32SignatureChecksBufSize,
2204 &psRGXFWInit->asSigBufCtl[RGXFWIF_DM_3D],
2206 if (eError != PVRSRV_OK)
2208 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to setup 3D signature checks"));
2211 psDevInfo->ui32Sig3DChecksSize = ui32SignatureChecksBufSize;
2213 if(psDevInfo->sDevFeatureCfg.ui64Features & RGX_FEATURE_RAY_TRACING_BIT_MASK)
2215 eError = RGXFWSetupSignatureChecks(psDevInfo,
2216 &psDevInfo->psRGXFWSigRTChecksMemDesc,
2217 ui32SignatureChecksBufSize,
2218 &psRGXFWInit->asSigBufCtl[RGXFWIF_DM_RTU],
2220 if (eError != PVRSRV_OK)
2222 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to setup RTU signature checks"));
2225 psDevInfo->ui32SigRTChecksSize = ui32SignatureChecksBufSize;
2227 eError = RGXFWSetupSignatureChecks(psDevInfo,
2228 &psDevInfo->psRGXFWSigSHChecksMemDesc,
2229 ui32SignatureChecksBufSize,
2230 &psRGXFWInit->asSigBufCtl[RGXFWIF_DM_SHG],
2232 if (eError != PVRSRV_OK)
2234 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to setup SHG signature checks"));
2237 psDevInfo->ui32SigSHChecksSize = ui32SignatureChecksBufSize;
2240 #if defined(RGXFW_ALIGNCHECKS)
2241 eError = RGXFWSetupAlignChecks(psDevInfo,
2242 &psRGXFWInit->sAlignChecks,
2243 pui32RGXFWAlignChecks,
2244 ui32RGXFWAlignChecksArrLength);
2245 if (eError != PVRSRV_OK)
2247 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to setup alignment checks"));
2252 psRGXFWInit->ui32FilterFlags = ui32FilterFlags;
2254 #if defined(PVRSRV_GPUVIRT_GUESTDRV)
2256 * Guest drivers do not support the following functionality:
2257 * - Perform actual on-chip fw RDPowIsland(ing)
2258 * - Perform actual on-chip fw tracing
2259 * - Configure FW perf counters
2261 PVR_UNREFERENCED_PARAMETER(dm);
2262 PVR_UNREFERENCED_PARAMETER(eFirmwarePerf);
2265 if(ui64ErnsBrns & FIX_HW_BRN_52402_BIT_MASK)
2267 /* Fill the remaining bits of fw the init data */
2268 psRGXFWInit->sPDSExecBase.uiAddr = RGX_PDSCODEDATA_BRN_52402_HEAP_BASE;
2269 psRGXFWInit->sUSCExecBase.uiAddr = RGX_USCCODE_BRN_52402_HEAP_BASE;
2272 /* Fill the remaining bits of fw the init data */
2273 psRGXFWInit->sPDSExecBase.uiAddr = RGX_PDSCODEDATA_HEAP_BASE;
2274 psRGXFWInit->sUSCExecBase.uiAddr = RGX_USCCODE_HEAP_BASE;
2277 psRGXFWInit->sDPXControlStreamBase.uiAddr = RGX_DOPPLER_HEAP_BASE;
2278 psRGXFWInit->sResultDumpBase.uiAddr = RGX_DOPPLER_OVERFLOW_HEAP_BASE;
2279 psRGXFWInit->sRTUHeapBase.uiAddr = RGX_DOPPLER_HEAP_BASE;
2280 psRGXFWInit->sTDMTPUYUVCeoffsHeapBase.uiAddr = RGX_TDM_TPU_YUV_COEFFS_HEAP_BASE;
2283 if(psDevInfo->sDevFeatureCfg.ui64Features & RGX_FEATURE_S7_TOP_INFRASTRUCTURE_BIT_MASK)
2285 psRGXFWInit->ui32JonesDisableMask = ui32JonesDisableMask;
2287 psDevInfo->bPDPEnabled = (ui32ConfigFlags & RGXFWIF_SRVCFG_DISABLE_PDP_EN)
2288 ? IMG_FALSE : IMG_TRUE;
2289 psRGXFWInit->ui32HWRDebugDumpLimit = ui32HWRDebugDumpLimit;
2291 psRGXFWInit->eFirmwarePerf = eFirmwarePerf;
2293 if(psDevInfo->sDevFeatureCfg.ui64Features & RGX_FEATURE_SLC_VIVT_BIT_MASK)
2295 eError = _AllocateSLC3Fence(psDevInfo, psRGXFWInit);
2296 if (eError != PVRSRV_OK)
2298 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate memory for SLC3Fence"));
2304 if ( (psDevInfo->sDevFeatureCfg.ui32META) && \
2305 ((ui32ConfigFlags & RGXFWIF_INICFG_METAT1_ENABLED) != 0))
2307 /* Allocate a page for T1 stack */
2308 eError = DevmemFwAllocate(psDevInfo,
2309 RGX_META_STACK_SIZE,
2310 RGX_FWCOMCTX_ALLOCFLAGS,
2312 & psDevInfo->psMETAT1StackMemDesc);
2313 if (eError != PVRSRV_OK)
2315 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate T1 Stack"));
2319 RGXSetFirmwareAddress(&psRGXFWInit->sT1Stack,
2320 psDevInfo->psMETAT1StackMemDesc,
2321 0, RFW_FWADDR_NOREF_FLAG);
2323 PVR_DPF((PVR_DBG_MESSAGE, "RGXSetupFirmware: T1 Stack Frame allocated at %x",
2324 psRGXFWInit->sT1Stack.ui32Addr));
2327 #if defined(SUPPORT_PDVFS)
2328 /* Core clock rate */
2330 PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
2331 PVRSRV_MEMALLOCFLAG_GPU_READABLE |
2332 PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
2333 PVRSRV_MEMALLOCFLAG_CPU_READABLE |
2334 PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
2335 PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
2336 PVRSRV_MEMALLOCFLAG_UNCACHED |
2337 PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
2339 eError = DevmemFwAllocate(psDevInfo,
2343 &psDevInfo->psRGXFWIFCoreClkRateMemDesc);
2344 if (eError != PVRSRV_OK)
2346 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to allocate PDVFS core clock rate"));
2350 RGXSetFirmwareAddress(&psRGXFWInit->sCoreClockRate,
2351 psDevInfo->psRGXFWIFCoreClkRateMemDesc,
2352 0, RFW_FWADDR_NOREF_FLAG);
2354 PVR_DPF((PVR_DBG_MESSAGE, "RGXSetupFirmware: PDVFS core clock rate allocated at %x",
2355 psRGXFWInit->sCoreClockRate.ui32Addr));
2357 eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWIFCoreClkRateMemDesc,
2358 (void **)&psDevInfo->pui32RGXFWIFCoreClkRate);
2359 if (eError != PVRSRV_OK)
2361 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to acquire core clk rate (%u)",
2369 PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) |
2370 PVRSRV_MEMALLOCFLAG_GPU_READABLE | /* XXX ?? */
2371 PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE |
2372 PVRSRV_MEMALLOCFLAG_CPU_READABLE |
2373 PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
2374 PVRSRV_MEMALLOCFLAG_UNCACHED |
2375 PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
2378 the timer query arrays
2380 PDUMPCOMMENT("Allocate timer query arrays (FW)");
2381 eError = DevmemFwAllocate(psDevInfo,
2382 sizeof(IMG_UINT64) * RGX_MAX_TIMER_QUERIES,
2384 "FwStartTimesArray",
2385 & psDevInfo->psStartTimeMemDesc);
2386 if (eError != PVRSRV_OK)
2388 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to map start times array"));
2392 eError = DevmemAcquireCpuVirtAddr(psDevInfo->psStartTimeMemDesc,
2393 (void **)& psDevInfo->pui64StartTimeById);
2395 if (eError != PVRSRV_OK)
2397 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to map start times array"));
2401 eError = DevmemFwAllocate(psDevInfo,
2402 sizeof(IMG_UINT64) * RGX_MAX_TIMER_QUERIES,
2405 & psDevInfo->psEndTimeMemDesc);
2406 if (eError != PVRSRV_OK)
2408 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to map end times array"));
2412 eError = DevmemAcquireCpuVirtAddr(psDevInfo->psEndTimeMemDesc,
2413 (void **)& psDevInfo->pui64EndTimeById);
2415 if (eError != PVRSRV_OK)
2417 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to map end times array"));
2421 eError = DevmemFwAllocate(psDevInfo,
2422 sizeof(IMG_UINT32) * RGX_MAX_TIMER_QUERIES,
2424 "FwCompletedOpsArray",
2425 & psDevInfo->psCompletedMemDesc);
2426 if (eError != PVRSRV_OK)
2428 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to completed ops array"));
2432 eError = DevmemAcquireCpuVirtAddr(psDevInfo->psCompletedMemDesc,
2433 (void **)& psDevInfo->pui32CompletedById);
2435 if (eError != PVRSRV_OK)
2437 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed to map completed ops array"));
2441 /* Initialize FW started flag */
2442 psRGXFWInit->bFirmwareStarted = IMG_FALSE;
2443 psRGXFWInit->ui32MarkerVal = 1;
2445 /* Initialise the compatibility check data */
2446 RGXFWIF_COMPCHECKS_BVNC_INIT(psRGXFWInit->sRGXCompChecks.sFWBVNC);
2447 RGXFWIF_COMPCHECKS_BVNC_INIT(psRGXFWInit->sRGXCompChecks.sHWBVNC);
2449 PDUMPCOMMENT("Dump RGXFW Init data");
2450 if (!bEnableSignatureChecks)
2453 PDUMPCOMMENT("(to enable rgxfw signatures place the following line after the RTCONF line)");
2454 DevmemPDumpLoadMem( psDevInfo->psRGXFWIfInitMemDesc,
2455 offsetof(RGXFWIF_INIT, asSigBufCtl),
2456 sizeof(RGXFWIF_SIGBUF_CTL)*(psDevInfo->sDevFeatureCfg.ui32MAXDMCount),
2457 PDUMP_FLAGS_CONTINUOUS);
2459 psRGXFWInit->asSigBufCtl[RGXFWIF_DM_3D].sBuffer.ui32Addr = 0x0;
2460 psRGXFWInit->asSigBufCtl[RGXFWIF_DM_TA].sBuffer.ui32Addr = 0x0;
2463 for (dm = 0; dm < (psDevInfo->sDevFeatureCfg.ui32MAXDMCount); dm++)
2465 psDevInfo->psRGXFWIfTraceBuf->aui32HwrDmLockedUpCount[dm] = 0;
2466 psDevInfo->psRGXFWIfTraceBuf->aui32HwrDmOverranCount[dm] = 0;
2467 psDevInfo->psRGXFWIfTraceBuf->aui32HwrDmRecoveredCount[dm] = 0;
2468 psDevInfo->psRGXFWIfTraceBuf->aui32HwrDmFalseDetectCount[dm] = 0;
2472 * BIF Tiling configuration
2475 psRGXFWInit->eBifTilingMode = eBifTilingMode;
2477 psRGXFWInit->sBifTilingCfg[0].uiBase = RGX_BIF_TILING_HEAP_1_BASE;
2478 psRGXFWInit->sBifTilingCfg[0].uiLen = RGX_BIF_TILING_HEAP_SIZE;
2479 psRGXFWInit->sBifTilingCfg[0].uiXStride = pui32BIFTilingXStrides[0];
2480 psRGXFWInit->sBifTilingCfg[1].uiBase = RGX_BIF_TILING_HEAP_2_BASE;
2481 psRGXFWInit->sBifTilingCfg[1].uiLen = RGX_BIF_TILING_HEAP_SIZE;
2482 psRGXFWInit->sBifTilingCfg[1].uiXStride = pui32BIFTilingXStrides[1];
2483 psRGXFWInit->sBifTilingCfg[2].uiBase = RGX_BIF_TILING_HEAP_3_BASE;
2484 psRGXFWInit->sBifTilingCfg[2].uiLen = RGX_BIF_TILING_HEAP_SIZE;
2485 psRGXFWInit->sBifTilingCfg[2].uiXStride = pui32BIFTilingXStrides[2];
2486 psRGXFWInit->sBifTilingCfg[3].uiBase = RGX_BIF_TILING_HEAP_4_BASE;
2487 psRGXFWInit->sBifTilingCfg[3].uiLen = RGX_BIF_TILING_HEAP_SIZE;
2488 psRGXFWInit->sBifTilingCfg[3].uiXStride = pui32BIFTilingXStrides[3];
2491 PDUMPCOMMENT("Dump rgxfw hwperfctl structure");
2492 DevmemPDumpLoadZeroMem (psDevInfo->psRGXFWIfHWPerfCountersMemDesc,
2494 ui32HWPerfCountersDataSize,
2495 PDUMP_FLAGS_CONTINUOUS);
2497 PDUMPCOMMENT("Dump rgxfw trace control structure");
2498 DevmemPDumpLoadMem( psDevInfo->psRGXFWIfTraceBufCtlMemDesc,
2500 sizeof(RGXFWIF_TRACEBUF),
2501 PDUMP_FLAGS_CONTINUOUS);
2502 #if defined(SUPPORT_USER_REGISTER_CONFIGURATION)
2503 PDUMPCOMMENT("Dump rgxfw register configuration buffer");
2504 DevmemPDumpLoadMem( psDevInfo->psRGXFWIfRegCfgMemDesc,
2506 sizeof(RGXFWIF_REG_CFG),
2507 PDUMP_FLAGS_CONTINUOUS);
2509 PDUMPCOMMENT("Dump rgxfw init structure");
2510 DevmemPDumpLoadMem( psDevInfo->psRGXFWIfInitMemDesc,
2512 sizeof(RGXFWIF_INIT),
2513 PDUMP_FLAGS_CONTINUOUS);
2514 if ((0 != psDevInfo->sDevFeatureCfg.ui32MCMS) && \
2515 (0 == (psDevInfo->sDevFeatureCfg.ui64ErnsBrns & FIX_HW_BRN_50767_BIT_MASK)))
2517 PDUMPCOMMENT("Dump rgxfw coremem data store");
2518 DevmemPDumpLoadMem( psDevInfo->psRGXFWIfCorememDataStoreMemDesc,
2520 RGX_META_COREMEM_BSS_SIZE,
2521 PDUMP_FLAGS_CONTINUOUS);
2524 PDUMPCOMMENT("RTCONF: run-time configuration");
2527 /* Dump the config options so they can be edited.
2529 * FIXME: Need new DevmemPDumpWRW API which writes a WRW to load ui32ConfigFlags
2531 PDUMPCOMMENT("(Set the FW config options here)");
2532 PDUMPCOMMENT("( Ctx Switch TA Enable: 0x%08x)", RGXFWIF_INICFG_CTXSWITCH_TA_EN);
2533 PDUMPCOMMENT("( Ctx Switch 3D Enable: 0x%08x)", RGXFWIF_INICFG_CTXSWITCH_3D_EN);
2534 PDUMPCOMMENT("( Ctx Switch CDM Enable: 0x%08x)", RGXFWIF_INICFG_CTXSWITCH_CDM_EN);
2535 PDUMPCOMMENT("( Ctx Switch Rand mode: 0x%08x)", RGXFWIF_INICFG_CTXSWITCH_MODE_RAND);
2536 PDUMPCOMMENT("( Ctx Switch Soft Reset Enable: 0x%08x)", RGXFWIF_INICFG_CTXSWITCH_SRESET_EN);
2537 PDUMPCOMMENT("( Reserved (do not set): 0x%08x)", RGXFWIF_INICFG_RSVD);
2538 PDUMPCOMMENT("( Rascal+Dust Power Island: 0x%08x)", RGXFWIF_INICFG_POW_RASCALDUST);
2539 PDUMPCOMMENT("( Enable HWPerf: 0x%08x)", RGXFWIF_INICFG_HWPERF_EN);
2540 PDUMPCOMMENT("( Enable HWR: 0x%08x)", RGXFWIF_INICFG_HWR_EN);
2541 PDUMPCOMMENT("( Check MList: 0x%08x)", RGXFWIF_INICFG_CHECK_MLIST_EN);
2542 PDUMPCOMMENT("( Disable Auto Clock Gating: 0x%08x)", RGXFWIF_INICFG_DISABLE_CLKGATING_EN);
2543 PDUMPCOMMENT("( Enable HWPerf Polling Perf Counter: 0x%08x)", RGXFWIF_INICFG_POLL_COUNTERS_EN);
2545 if(psDevInfo->sDevFeatureCfg.ui64Features & RGX_FEATURE_VDM_OBJECT_LEVEL_LLS_BIT_MASK)
2547 PDUMPCOMMENT("( Ctx Switch Object mode Index: 0x%08x)", RGXFWIF_INICFG_VDM_CTX_STORE_MODE_INDEX);
2548 PDUMPCOMMENT("( Ctx Switch Object mode Instance: 0x%08x)", RGXFWIF_INICFG_VDM_CTX_STORE_MODE_INSTANCE);
2549 PDUMPCOMMENT("( Ctx Switch Object mode List: 0x%08x)", RGXFWIF_INICFG_VDM_CTX_STORE_MODE_LIST);
2552 PDUMPCOMMENT("( Enable SHG Bypass mode: 0x%08x)", RGXFWIF_INICFG_SHG_BYPASS_EN);
2553 PDUMPCOMMENT("( Enable RTU Bypass mode: 0x%08x)", RGXFWIF_INICFG_RTU_BYPASS_EN);
2554 PDUMPCOMMENT("( Enable register configuration: 0x%08x)", RGXFWIF_INICFG_REGCONFIG_EN);
2555 PDUMPCOMMENT("( Assert on TA Out-of-Memory: 0x%08x)", RGXFWIF_INICFG_ASSERT_ON_OUTOFMEMORY);
2556 PDUMPCOMMENT("( Disable HWPerf custom counter filter: 0x%08x)", RGXFWIF_INICFG_HWP_DISABLE_FILTER);
2557 PDUMPCOMMENT("( Enable HWPerf custom performance timer: 0x%08x)", RGXFWIF_INICFG_CUSTOM_PERF_TIMER_EN);
2558 PDUMPCOMMENT("( Enable CDM Killing Rand mode: 0x%08x)", RGXFWIF_INICFG_CDM_KILL_MODE_RAND_EN);
2559 PDUMPCOMMENT("( Enable Ctx Switch profile mode: 0x%08x (none=b'000, fast=b'001, medium=b'010, slow=b'011, nodelay=b'100))", RGXFWIF_INICFG_CTXSWITCH_PROFILE_MASK);
2560 PDUMPCOMMENT("( Disable DM overlap (except TA during SPM): 0x%08x)", RGXFWIF_INICFG_DISABLE_DM_OVERLAP);
2561 PDUMPCOMMENT("( Enable Meta T1 running main code: 0x%08x)", RGXFWIF_INICFG_METAT1_MAIN);
2562 PDUMPCOMMENT("( Enable Meta T1 running dummy code: 0x%08x)", RGXFWIF_INICFG_METAT1_DUMMY);
2563 PDUMPCOMMENT("( Assert on HWR trigger (page fault, lockup, overrun or poll failure): 0x%08x)", RGXFWIF_INICFG_ASSERT_ON_HWR_TRIGGER);
2565 DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfInitMemDesc,
2566 offsetof(RGXFWIF_INIT, ui32ConfigFlags),
2567 psRGXFWInit->ui32ConfigFlags,
2568 PDUMP_FLAGS_CONTINUOUS);
2570 /* default: no filter */
2571 psRGXFWInit->sPIDFilter.eMode = RGXFW_PID_FILTER_INCLUDE_ALL_EXCEPT;
2572 psRGXFWInit->sPIDFilter.asItems[0].uiPID = 0;
2574 PDUMPCOMMENT("( PID filter type: %X=INCLUDE_ALL_EXCEPT, %X=EXCLUDE_ALL_EXCEPT)",
2575 RGXFW_PID_FILTER_INCLUDE_ALL_EXCEPT,
2576 RGXFW_PID_FILTER_EXCLUDE_ALL_EXCEPT);
2578 DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfInitMemDesc,
2579 offsetof(RGXFWIF_INIT, sPIDFilter.eMode),
2580 psRGXFWInit->sPIDFilter.eMode,
2581 PDUMP_FLAGS_CONTINUOUS);
2583 PDUMPCOMMENT("( PID filter PID/OSID list (Up to %u entries. Terminate with a zero PID))",
2584 RGXFWIF_PID_FILTER_MAX_NUM_PIDS);
2588 /* generate a few WRWs in the pdump stream as an example */
2589 for(i = 0; i < MIN(RGXFWIF_PID_FILTER_MAX_NUM_PIDS, 8); i++)
2592 * Some compilers cannot cope with the uses of offsetof() below - the specific problem being the use of
2593 * a non-const variable in the expression, which it needs to be const. Typical compiler output is
2594 * "expression must have a constant value".
2596 const IMG_DEVMEM_OFFSET_T uiPIDOff
2597 = (IMG_DEVMEM_OFFSET_T)(uintptr_t)&(((RGXFWIF_INIT *)0)->sPIDFilter.asItems[i].uiPID);
2599 const IMG_DEVMEM_OFFSET_T uiOSIDOff
2600 = (IMG_DEVMEM_OFFSET_T)(uintptr_t)&(((RGXFWIF_INIT *)0)->sPIDFilter.asItems[i].ui32OSID);
2602 PDUMPCOMMENT("(PID and OSID pair %u)", i);
2604 PDUMPCOMMENT("(PID)");
2605 DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfInitMemDesc,
2608 PDUMP_FLAGS_CONTINUOUS);
2610 PDUMPCOMMENT("(OSID)");
2611 DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfInitMemDesc,
2614 PDUMP_FLAGS_CONTINUOUS);
2619 * Dump the log config so it can be edited.
2621 PDUMPCOMMENT("(Set the log config here)");
2622 PDUMPCOMMENT("( Log Type: set bit 0 for TRACE, reset for TBI)");
2623 PDUMPCOMMENT("( MAIN Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_MAIN);
2624 PDUMPCOMMENT("( MTS Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_MTS);
2625 PDUMPCOMMENT("( CLEANUP Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_CLEANUP);
2626 PDUMPCOMMENT("( CSW Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_CSW);
2627 PDUMPCOMMENT("( BIF Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_BIF);
2628 PDUMPCOMMENT("( PM Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_PM);
2629 PDUMPCOMMENT("( RTD Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_RTD);
2630 PDUMPCOMMENT("( SPM Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_SPM);
2631 PDUMPCOMMENT("( POW Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_POW);
2632 PDUMPCOMMENT("( HWR Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_HWR);
2633 PDUMPCOMMENT("( HWP Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_HWP);
2635 if(psDevInfo->sDevFeatureCfg.ui64Features & RGX_FEATURE_RAY_TRACING_BIT_MASK)
2637 PDUMPCOMMENT("( RPM Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_RPM);
2640 if (psDevInfo->sDevFeatureCfg.ui64Features & RGX_FEATURE_META_DMA_BIT_MASK)
2642 PDUMPCOMMENT("( DMA Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_DMA);
2644 PDUMPCOMMENT("( DEBUG Group Enable: 0x%08x)", RGXFWIF_LOG_TYPE_GROUP_DEBUG);
2645 DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfTraceBufCtlMemDesc,
2646 offsetof(RGXFWIF_TRACEBUF, ui32LogType),
2647 psDevInfo->psRGXFWIfTraceBuf->ui32LogType,
2648 PDUMP_FLAGS_CONTINUOUS);
2650 PDUMPCOMMENT("Set the HWPerf Filter config here");
2651 DevmemPDumpLoadMemValue64(psDevInfo->psRGXFWIfInitMemDesc,
2652 offsetof(RGXFWIF_INIT, ui64HWPerfFilter),
2653 psRGXFWInit->ui64HWPerfFilter,
2654 PDUMP_FLAGS_CONTINUOUS);
2656 #if defined(SUPPORT_USER_REGISTER_CONFIGURATION)
2657 PDUMPCOMMENT("(Number of registers configurations at pow on, dust change, ta, 3d, cdm and tla/tdm)");
2658 DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfRegCfgMemDesc,
2659 offsetof(RGXFWIF_REG_CFG, aui8NumRegsType[RGXFWIF_REG_CFG_TYPE_PWR_ON]),
2661 PDUMP_FLAGS_CONTINUOUS);
2662 DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfRegCfgMemDesc,
2663 offsetof(RGXFWIF_REG_CFG, aui8NumRegsType[RGXFWIF_REG_CFG_TYPE_DUST_CHANGE]),
2665 PDUMP_FLAGS_CONTINUOUS);
2666 DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfRegCfgMemDesc,
2667 offsetof(RGXFWIF_REG_CFG, aui8NumRegsType[RGXFWIF_REG_CFG_TYPE_TA]),
2669 PDUMP_FLAGS_CONTINUOUS);
2670 DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfRegCfgMemDesc,
2671 offsetof(RGXFWIF_REG_CFG, aui8NumRegsType[RGXFWIF_REG_CFG_TYPE_3D]),
2673 PDUMP_FLAGS_CONTINUOUS);
2674 DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfRegCfgMemDesc,
2675 offsetof(RGXFWIF_REG_CFG, aui8NumRegsType[RGXFWIF_REG_CFG_TYPE_CDM]),
2677 PDUMP_FLAGS_CONTINUOUS);
2679 if(psDevInfo->sDevFeatureCfg.ui64Features & RGX_FEATURE_TLA_BIT_MASK)
2681 DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfRegCfgMemDesc,
2682 offsetof(RGXFWIF_REG_CFG, aui8NumRegsType[RGXFWIF_REG_CFG_TYPE_TLA]),
2684 PDUMP_FLAGS_CONTINUOUS);
2687 if(psDevInfo->sDevFeatureCfg.ui64Features & RGX_FEATURE_FASTRENDER_DM_BIT_MASK)
2689 DevmemPDumpLoadMemValue32(psDevInfo->psRGXFWIfRegCfgMemDesc,
2690 offsetof(RGXFWIF_REG_CFG, aui8NumRegsType[RGXFWIF_REG_CFG_TYPE_TDM]),
2692 PDUMP_FLAGS_CONTINUOUS);
2695 PDUMPCOMMENT("(Set registers here: address, mask, value)");
2696 DevmemPDumpLoadMemValue64(psDevInfo->psRGXFWIfRegCfgMemDesc,
2697 offsetof(RGXFWIF_REG_CFG, asRegConfigs[0].ui64Addr),
2699 PDUMP_FLAGS_CONTINUOUS);
2700 DevmemPDumpLoadMemValue64(psDevInfo->psRGXFWIfRegCfgMemDesc,
2701 offsetof(RGXFWIF_REG_CFG, asRegConfigs[0].ui64Mask),
2703 PDUMP_FLAGS_CONTINUOUS);
2704 DevmemPDumpLoadMemValue64(psDevInfo->psRGXFWIfRegCfgMemDesc,
2705 offsetof(RGXFWIF_REG_CFG, asRegConfigs[0].ui64Value),
2707 PDUMP_FLAGS_CONTINUOUS);
2708 #endif /* SUPPORT_USER_REGISTER_CONFIGURATION */
2710 #endif /* PVRSRV_GPUVIRT_GUESTDRV */
2712 #if defined(SUPPORT_PVRSRV_GPUVIRT)
2713 /* Perform additional virtualisation initialisation */
2714 eError = RGXVzSetupFirmware(psDeviceNode);
2715 if (eError != PVRSRV_OK)
2717 PVR_DPF((PVR_DBG_ERROR,"RGXSetupFirmware: Failed RGXVzSetupFirmware"));
2722 /* We don't need access to the fw init data structure anymore */
2723 DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfInitMemDesc);
2726 psDevInfo->bFirmwareInitialised = IMG_TRUE;
2731 #if !defined(PVRSRV_GPUVIRT_GUESTDRV)
2732 if (psDevInfo->psRGXFWIfInitMemDesc != NULL && psRGXFWInit != NULL)
2734 DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfInitMemDesc);
2737 RGXFreeFirmware(psDevInfo);
2739 PVR_ASSERT(eError != PVRSRV_OK);
2744 *******************************************************************************
2746 @Function RGXFreeFirmware
2750 Frees all the firmware-related allocations
2754 @Return PVRSRV_ERROR
2756 ******************************************************************************/
2757 void RGXFreeFirmware(PVRSRV_RGXDEV_INFO *psDevInfo)
2759 IMG_UINT64 ui64ErnsBrns = psDevInfo->sDevFeatureCfg.ui64ErnsBrns;
2761 psDevInfo->bFirmwareInitialised = IMG_FALSE;
2763 RGXFreeKernelCCB(psDevInfo);
2765 RGXFreeFirmwareCCB(psDevInfo,
2766 &psDevInfo->psFirmwareCCBCtl,
2767 &psDevInfo->psFirmwareCCBCtlMemDesc,
2768 &psDevInfo->psFirmwareCCB,
2769 &psDevInfo->psFirmwareCCBMemDesc);
2771 #if defined(SUPPORT_WORKLOAD_ESTIMATION)
2772 RGXFreeFirmwareCCB(psDevInfo,
2773 &psDevInfo->psWorkEstFirmwareCCBCtl,
2774 &psDevInfo->psWorkEstFirmwareCCBCtlMemDesc,
2775 &psDevInfo->psWorkEstFirmwareCCB,
2776 &psDevInfo->psWorkEstFirmwareCCBMemDesc);
2779 #if defined(RGXFW_ALIGNCHECKS)
2780 if (psDevInfo->psRGXFWAlignChecksMemDesc)
2782 RGXFWFreeAlignChecks(psDevInfo);
2786 if (psDevInfo->psRGXFWSigTAChecksMemDesc)
2788 DevmemFwFree(psDevInfo, psDevInfo->psRGXFWSigTAChecksMemDesc);
2789 psDevInfo->psRGXFWSigTAChecksMemDesc = NULL;
2792 if (psDevInfo->psRGXFWSig3DChecksMemDesc)
2794 DevmemFwFree(psDevInfo, psDevInfo->psRGXFWSig3DChecksMemDesc);
2795 psDevInfo->psRGXFWSig3DChecksMemDesc = NULL;
2798 if(psDevInfo->sDevFeatureCfg.ui64Features & RGX_FEATURE_RAY_TRACING_BIT_MASK)
2800 if (psDevInfo->psRGXFWSigRTChecksMemDesc)
2802 DevmemFwFree(psDevInfo, psDevInfo->psRGXFWSigRTChecksMemDesc);
2803 psDevInfo->psRGXFWSigRTChecksMemDesc = NULL;
2806 if (psDevInfo->psRGXFWSigSHChecksMemDesc)
2808 DevmemFwFree(psDevInfo, psDevInfo->psRGXFWSigSHChecksMemDesc);
2809 psDevInfo->psRGXFWSigSHChecksMemDesc = NULL;
2813 if(ui64ErnsBrns & FIX_HW_BRN_37200_BIT_MASK)
2815 if (psDevInfo->psRGXFWHWBRN37200MemDesc)
2817 DevmemReleaseDevVirtAddr(psDevInfo->psRGXFWHWBRN37200MemDesc);
2818 DevmemFree(psDevInfo->psRGXFWHWBRN37200MemDesc);
2819 psDevInfo->psRGXFWHWBRN37200MemDesc = NULL;
2823 RGXSetupFaultReadRegisterRollback(psDevInfo);
2825 if (psDevInfo->psPowSyncPrim != NULL)
2827 SyncPrimFree(psDevInfo->psPowSyncPrim);
2828 psDevInfo->psPowSyncPrim = NULL;
2831 if (psDevInfo->hSyncPrimContext != 0)
2833 SyncPrimContextDestroy(psDevInfo->hSyncPrimContext);
2834 psDevInfo->hSyncPrimContext = 0;
2837 #if !defined(PVRSRV_GPUVIRT_GUESTDRV)
2838 if (psDevInfo->psRGXFWIfGpuUtilFWCbCtlMemDesc)
2840 if (psDevInfo->psRGXFWIfGpuUtilFWCb != NULL)
2842 DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfGpuUtilFWCbCtlMemDesc);
2843 psDevInfo->psRGXFWIfGpuUtilFWCb = NULL;
2845 DevmemFwFree(psDevInfo, psDevInfo->psRGXFWIfGpuUtilFWCbCtlMemDesc);
2846 psDevInfo->psRGXFWIfGpuUtilFWCbCtlMemDesc = NULL;
2851 if (psDevInfo->psRGXFWIfRuntimeCfgMemDesc)
2853 if (psDevInfo->psRGXFWIfRuntimeCfg != NULL)
2855 DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfRuntimeCfgMemDesc);
2856 psDevInfo->psRGXFWIfRuntimeCfg = NULL;
2858 DevmemFwFree(psDevInfo, psDevInfo->psRGXFWIfRuntimeCfgMemDesc);
2859 psDevInfo->psRGXFWIfRuntimeCfgMemDesc = NULL;
2862 if (psDevInfo->psRGXFWIfHWRInfoBufCtlMemDesc)
2864 if (psDevInfo->psRGXFWIfHWRInfoBuf != NULL)
2866 DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfHWRInfoBufCtlMemDesc);
2867 psDevInfo->psRGXFWIfHWRInfoBuf = NULL;
2869 DevmemFwFree(psDevInfo, psDevInfo->psRGXFWIfHWRInfoBufCtlMemDesc);
2870 psDevInfo->psRGXFWIfHWRInfoBufCtlMemDesc = NULL;
2873 if ((0 != psDevInfo->sDevFeatureCfg.ui32MCMS) && \
2874 (0 == (ui64ErnsBrns & FIX_HW_BRN_50767_BIT_MASK)))
2876 if (psDevInfo->psRGXFWIfCorememDataStoreMemDesc)
2878 DevmemFwFree(psDevInfo, psDevInfo->psRGXFWIfCorememDataStoreMemDesc);
2879 psDevInfo->psRGXFWIfCorememDataStoreMemDesc = NULL;
2883 if (psDevInfo->psRGXFWIfTraceBufCtlMemDesc)
2885 if (psDevInfo->psRGXFWIfTraceBuf != NULL)
2887 /* first deinit/free the tracebuffer allocation */
2888 RGXTraceBufferDeinit(psDevInfo);
2890 DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfTraceBufCtlMemDesc);
2891 psDevInfo->psRGXFWIfTraceBuf = NULL;
2893 DevmemFwFree(psDevInfo, psDevInfo->psRGXFWIfTraceBufCtlMemDesc);
2894 psDevInfo->psRGXFWIfTraceBufCtlMemDesc = NULL;
2896 #if defined(SUPPORT_USER_REGISTER_CONFIGURATION)
2897 if (psDevInfo->psRGXFWIfRegCfgMemDesc)
2899 DevmemFwFree(psDevInfo, psDevInfo->psRGXFWIfRegCfgMemDesc);
2900 psDevInfo->psRGXFWIfRegCfgMemDesc = NULL;
2903 if (psDevInfo->psRGXFWIfHWPerfCountersMemDesc)
2905 RGXUnsetFirmwareAddress(psDevInfo->psRGXFWIfHWPerfCountersMemDesc);
2906 DevmemFwFree(psDevInfo, psDevInfo->psRGXFWIfHWPerfCountersMemDesc);
2907 psDevInfo->psRGXFWIfHWPerfCountersMemDesc = NULL;
2909 if(psDevInfo->sDevFeatureCfg.ui64Features & RGX_FEATURE_SLC_VIVT_BIT_MASK)
2911 _FreeSLC3Fence(psDevInfo);
2914 if( (psDevInfo->sDevFeatureCfg.ui32META) && (psDevInfo->psMETAT1StackMemDesc))
2916 DevmemFwFree(psDevInfo, psDevInfo->psMETAT1StackMemDesc);
2917 psDevInfo->psMETAT1StackMemDesc = NULL;
2920 #if defined(SUPPORT_PDVFS)
2921 if (psDevInfo->psRGXFWIFCoreClkRateMemDesc)
2923 if (psDevInfo->pui32RGXFWIFCoreClkRate != NULL)
2925 DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIFCoreClkRateMemDesc);
2926 psDevInfo->pui32RGXFWIFCoreClkRate = NULL;
2929 DevmemFwFree(psDevInfo, psDevInfo->psRGXFWIFCoreClkRateMemDesc);
2930 psDevInfo->psRGXFWIFCoreClkRateMemDesc = NULL;
2934 if (psDevInfo->psRGXFWIfInitMemDesc)
2936 DevmemFwFree(psDevInfo, psDevInfo->psRGXFWIfInitMemDesc);
2937 psDevInfo->psRGXFWIfInitMemDesc = NULL;
2941 if (psDevInfo->psCompletedMemDesc)
2943 if (psDevInfo->pui32CompletedById)
2945 DevmemReleaseCpuVirtAddr(psDevInfo->psCompletedMemDesc);
2946 psDevInfo->pui32CompletedById = NULL;
2948 DevmemFwFree(psDevInfo, psDevInfo->psCompletedMemDesc);
2949 psDevInfo->psCompletedMemDesc = NULL;
2951 if (psDevInfo->psEndTimeMemDesc)
2953 if (psDevInfo->pui64EndTimeById)
2955 DevmemReleaseCpuVirtAddr(psDevInfo->psEndTimeMemDesc);
2956 psDevInfo->pui64EndTimeById = NULL;
2959 DevmemFwFree(psDevInfo, psDevInfo->psEndTimeMemDesc);
2960 psDevInfo->psEndTimeMemDesc = NULL;
2962 if (psDevInfo->psStartTimeMemDesc)
2964 if (psDevInfo->pui64StartTimeById)
2966 DevmemReleaseCpuVirtAddr(psDevInfo->psStartTimeMemDesc);
2967 psDevInfo->pui64StartTimeById = NULL;
2970 DevmemFwFree(psDevInfo, psDevInfo->psStartTimeMemDesc);
2971 psDevInfo->psStartTimeMemDesc = NULL;
2976 /******************************************************************************
2977 FUNCTION : RGXAcquireKernelCCBSlot
2979 PURPOSE : Attempts to obtain a slot in the Kernel CCB
2981 PARAMETERS : psCCB - the CCB
2982 : Address of space if available, NULL otherwise
2984 RETURNS : PVRSRV_ERROR
2985 ******************************************************************************/
2986 static PVRSRV_ERROR RGXAcquireKernelCCBSlot(DEVMEM_MEMDESC *psKCCBCtrlMemDesc,
2987 RGXFWIF_CCB_CTL *psKCCBCtl,
2988 IMG_UINT32 *pui32Offset)
2990 IMG_UINT32 ui32OldWriteOffset, ui32NextWriteOffset;
2992 ui32OldWriteOffset = psKCCBCtl->ui32WriteOffset;
2993 ui32NextWriteOffset = (ui32OldWriteOffset + 1) & psKCCBCtl->ui32WrapMask;
2995 /* Note: The MTS can queue up to 255 kicks (254 pending kicks and 1 executing kick)
2996 * Hence the kernel CCB should not queue more 254 commands
2998 PVR_ASSERT(psKCCBCtl->ui32WrapMask < 255);
3001 /* Wait for sufficient CCB space to become available */
3002 PDUMPCOMMENTWITHFLAGS(0, "Wait for kCCB woff=%u", ui32NextWriteOffset);
3003 DevmemPDumpCBP(psKCCBCtrlMemDesc,
3004 offsetof(RGXFWIF_CCB_CTL, ui32ReadOffset),
3005 ui32NextWriteOffset,
3007 (psKCCBCtl->ui32WrapMask + 1));
3010 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
3013 if (ui32NextWriteOffset != psKCCBCtl->ui32ReadOffset)
3015 *pui32Offset = ui32NextWriteOffset;
3020 * The following sanity check doesn't impact performance,
3021 * since the CPU has to wait for the GPU anyway (full kernel CCB).
3023 if (PVRSRVGetPVRSRVData()->eServicesState != PVRSRV_SERVICES_STATE_OK)
3025 return PVRSRV_ERROR_KERNEL_CCB_FULL;
3029 OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
3030 } END_LOOP_UNTIL_TIMEOUT();
3032 /* Time out on waiting for CCB space */
3033 return PVRSRV_ERROR_KERNEL_CCB_FULL;
3037 PVRSRV_ERROR RGXSendCommandWithPowLock(PVRSRV_RGXDEV_INFO *psDevInfo,
3038 RGXFWIF_DM eKCCBType,
3039 RGXFWIF_KCCB_CMD *psKCCBCmd,
3040 IMG_UINT32 ui32CmdSize,
3041 IMG_UINT32 ui32PDumpFlags)
3043 PVRSRV_ERROR eError;
3044 PVRSRV_DEVICE_NODE *psDeviceNode = psDevInfo->psDeviceNode;
3046 /* Ensure Rogue is powered up before kicking MTS */
3047 eError = PVRSRVPowerLock(psDeviceNode);
3049 if (eError != PVRSRV_OK)
3051 PVR_DPF((PVR_DBG_WARNING, "RGXSendCommandWithPowLock: failed to acquire powerlock (%s)",
3052 PVRSRVGetErrorStringKM(eError)));
3054 goto _PVRSRVPowerLock_Exit;
3058 eError = PVRSRVSetDevicePowerStateKM(psDeviceNode,
3059 PVRSRV_DEV_POWER_STATE_ON,
3063 if (eError != PVRSRV_OK)
3065 PVR_DPF((PVR_DBG_WARNING, "RGXSendCommandWithPowLock: failed to transition Rogue to ON (%s)",
3066 PVRSRVGetErrorStringKM(eError)));
3068 goto _PVRSRVSetDevicePowerStateKM_Exit;
3071 eError = RGXSendCommand(psDevInfo, eKCCBType, psKCCBCmd, ui32CmdSize, ui32PDumpFlags);
3072 if (eError != PVRSRV_OK)
3074 PVR_DPF((PVR_DBG_ERROR, "RGXSendCommandWithPowLock: failed to schedule command (%s)",
3075 PVRSRVGetErrorStringKM(eError)));
3077 /* PVRSRVDebugRequest must be called without powerlock */
3078 PVRSRVPowerUnlock(psDeviceNode);
3079 PVRSRVDebugRequest(psDeviceNode, DEBUG_REQUEST_VERBOSITY_MAX, NULL, NULL);
3080 goto _PVRSRVPowerLock_Exit;
3084 _PVRSRVSetDevicePowerStateKM_Exit:
3085 PVRSRVPowerUnlock(psDeviceNode);
3087 _PVRSRVPowerLock_Exit:
3091 static PVRSRV_ERROR RGXSendCommandRaw(PVRSRV_RGXDEV_INFO *psDevInfo,
3092 RGXFWIF_DM eKCCBType,
3093 RGXFWIF_KCCB_CMD *psKCCBCmd,
3094 IMG_UINT32 ui32CmdSize,
3095 IMG_UINT32 uiPdumpFlags)
3097 PVRSRV_ERROR eError;
3098 PVRSRV_DEVICE_NODE *psDeviceNode = psDevInfo->psDeviceNode;
3099 RGXFWIF_CCB_CTL *psKCCBCtl = psDevInfo->psKernelCCBCtl;
3100 IMG_UINT8 *pui8KCCB = psDevInfo->psKernelCCB;
3101 IMG_UINT32 ui32NewWriteOffset;
3102 IMG_UINT32 ui32OldWriteOffset = psKCCBCtl->ui32WriteOffset;
3105 PVR_UNREFERENCED_PARAMETER(uiPdumpFlags);
3107 IMG_BOOL bIsInCaptureRange;
3108 IMG_BOOL bPdumpEnabled;
3109 IMG_BOOL bPDumpPowTrans = PDUMPPOWCMDINTRANS();
3111 PDumpIsCaptureFrameKM(&bIsInCaptureRange);
3112 bPdumpEnabled = (bIsInCaptureRange || PDUMP_IS_CONTINUOUS(uiPdumpFlags)) && !bPDumpPowTrans;
3114 /* in capture range */
3117 if (!psDevInfo->bDumpedKCCBCtlAlready)
3119 /* entering capture range */
3120 psDevInfo->bDumpedKCCBCtlAlready = IMG_TRUE;
3122 /* wait for firmware to catch up */
3123 PVR_DPF((PVR_DBG_MESSAGE, "RGXSendCommandRaw: waiting on fw to catch-up, roff: %d, woff: %d",
3124 psKCCBCtl->ui32ReadOffset, ui32OldWriteOffset));
3125 PVRSRVPollForValueKM(&psKCCBCtl->ui32ReadOffset, ui32OldWriteOffset, 0xFFFFFFFF);
3127 /* Dump Init state of Kernel CCB control (read and write offset) */
3128 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "Initial state of kernel CCB Control, roff: %d, woff: %d",
3129 psKCCBCtl->ui32ReadOffset, psKCCBCtl->ui32WriteOffset);
3131 DevmemPDumpLoadMem(psDevInfo->psKernelCCBCtlMemDesc,
3133 sizeof(RGXFWIF_CCB_CTL),
3134 PDUMP_FLAGS_CONTINUOUS);
3139 psKCCBCmd->eDM = eKCCBType;
3141 PVR_ASSERT(ui32CmdSize == psKCCBCtl->ui32CmdSize);
3142 if (!OSLockIsLocked(psDeviceNode->hPowerLock))
3144 PVR_DPF((PVR_DBG_ERROR, "RGXSendCommandRaw called without power lock held!"));
3145 PVR_ASSERT(OSLockIsLocked(psDeviceNode->hPowerLock));
3149 * Acquire a slot in the CCB.
3151 eError = RGXAcquireKernelCCBSlot(psDevInfo->psKernelCCBCtlMemDesc, psKCCBCtl, &ui32NewWriteOffset);
3152 if (eError != PVRSRV_OK)
3154 PVR_DPF((PVR_DBG_ERROR, "RGXSendCommandRaw failed to acquire CCB slot. Type:%u Error:%u",
3155 eKCCBType, eError));
3156 goto _RGXSendCommandRaw_Exit;
3160 * Copy the command into the CCB.
3162 OSDeviceMemCopy(&pui8KCCB[ui32OldWriteOffset * psKCCBCtl->ui32CmdSize],
3163 psKCCBCmd, psKCCBCtl->ui32CmdSize);
3165 /* ensure kCCB data is written before the offsets */
3166 OSWriteMemoryBarrier();
3168 /* Move past the current command */
3169 psKCCBCtl->ui32WriteOffset = ui32NewWriteOffset;
3173 /* in capture range */
3176 /* Dump new Kernel CCB content */
3177 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "Dump kCCB cmd for DM %d, woff = %d",
3179 ui32OldWriteOffset);
3180 DevmemPDumpLoadMem(psDevInfo->psKernelCCBMemDesc,
3181 ui32OldWriteOffset * psKCCBCtl->ui32CmdSize,
3182 psKCCBCtl->ui32CmdSize,
3183 PDUMP_FLAGS_CONTINUOUS);
3185 /* Dump new kernel CCB write offset */
3186 PDUMPCOMMENTWITHFLAGS(uiPdumpFlags, "Dump kCCBCtl woff (added new cmd for DM %d): %d",
3188 ui32NewWriteOffset);
3189 DevmemPDumpLoadMem(psDevInfo->psKernelCCBCtlMemDesc,
3190 offsetof(RGXFWIF_CCB_CTL, ui32WriteOffset),
3195 /* out of capture range */
3198 RGXPdumpDrainKCCB(psDevInfo, ui32OldWriteOffset);
3199 if (eError != PVRSRV_OK)
3201 PVR_DPF((PVR_DBG_WARNING, "RGXSendCommandRaw: problem draining kCCB (%d)", eError));
3202 goto _RGXSendCommandRaw_Exit;
3208 PDUMPCOMMENTWITHFLAGS(uiPdumpFlags, "MTS kick for kernel CCB");
3210 * Kick the MTS to schedule the firmware.
3213 IMG_UINT32 ui32MTSRegVal;
3214 #if defined(SUPPORT_PVRSRV_GPUVIRT)
3215 if(!(psDevInfo->sDevFeatureCfg.ui64Features & RGX_FEATURE_GPU_VIRTUALISATION_BIT_MASK))
3217 ui32MTSRegVal = ((RGXFWIF_DM_GP + PVRSRV_GPUVIRT_OSID) & ~RGX_CR_MTS_SCHEDULE_DM_CLRMSK) | RGX_CR_MTS_SCHEDULE_TASK_COUNTED;
3221 ui32MTSRegVal = (RGXFWIF_DM_GP & ~RGX_CR_MTS_SCHEDULE_DM_CLRMSK) | RGX_CR_MTS_SCHEDULE_TASK_COUNTED;
3225 __MTSScheduleWrite(psDevInfo, ui32MTSRegVal);
3227 PDUMPREG32(RGX_PDUMPREG_NAME, RGX_CR_MTS_SCHEDULE, ui32MTSRegVal, uiPdumpFlags);
3230 #if defined (NO_HARDWARE)
3231 /* keep the roff updated because fw isn't there to update it */
3232 psKCCBCtl->ui32ReadOffset = psKCCBCtl->ui32WriteOffset;
3235 _RGXSendCommandRaw_Exit:
3240 PVRSRV_ERROR RGXSendCommand(PVRSRV_RGXDEV_INFO *psDevInfo,
3241 RGXFWIF_DM eKCCBType,
3242 RGXFWIF_KCCB_CMD *psKCCBCmd,
3243 IMG_UINT32 ui32CmdSize,
3244 IMG_UINT32 uiPdumpFlags)
3247 PVRSRV_ERROR eError = PVRSRV_OK;
3248 DLLIST_NODE *psNode, *psNext;
3249 RGX_DEFERRED_KCCB_CMD *psTempDeferredKCCBCmd;
3251 /* Check if there is any deferred KCCB command before sending the command passed as argument */
3252 dllist_foreach_node(&psDevInfo->sKCCBDeferredCommandsListHead, psNode, psNext)
3254 psTempDeferredKCCBCmd = IMG_CONTAINER_OF(psNode, RGX_DEFERRED_KCCB_CMD, sListNode);
3255 /* For every deferred KCCB command, try to send it*/
3256 eError = RGXSendCommandRaw(psTempDeferredKCCBCmd->psDevInfo,
3257 psTempDeferredKCCBCmd->eDM,
3258 &(psTempDeferredKCCBCmd->sKCCBcmd),
3259 sizeof(psTempDeferredKCCBCmd->sKCCBcmd),
3260 psTempDeferredKCCBCmd->uiPdumpFlags);
3261 if (eError != PVRSRV_OK)
3265 /* Remove from the deferred list the sent deferred KCCB command */
3266 dllist_remove_node(psNode);
3267 OSFreeMem(psTempDeferredKCCBCmd);
3270 eError = RGXSendCommandRaw(psDevInfo,
3279 * If we don't manage to enqueue one of the deferred commands or the command
3280 * passed as argument because the KCCB is full, insert the latter into the deferred commands list.
3281 * The deferred commands will also be flushed eventually by:
3282 * - one more KCCB command sent for any DM
3283 * - the watchdog thread
3284 * - the power off sequence
3286 if (eError == PVRSRV_ERROR_KERNEL_CCB_FULL)
3288 RGX_DEFERRED_KCCB_CMD *psDeferredCommand;
3290 psDeferredCommand = OSAllocMem(sizeof(*psDeferredCommand));
3292 if(!psDeferredCommand)
3294 PVR_DPF((PVR_DBG_WARNING,"Deferring a KCCB command failed: allocation failure: requesting retry "));
3295 eError = PVRSRV_ERROR_RETRY;
3299 psDeferredCommand->sKCCBcmd = *psKCCBCmd;
3300 psDeferredCommand->eDM = eKCCBType;
3301 psDeferredCommand->uiPdumpFlags = uiPdumpFlags;
3302 psDeferredCommand->psDevInfo = psDevInfo;
3304 PVR_DPF((PVR_DBG_WARNING,"Deferring a KCCB command for DM %d" ,eKCCBType));
3305 dllist_add_to_tail(&(psDevInfo->sKCCBDeferredCommandsListHead), &(psDeferredCommand->sListNode));
3316 void RGXScheduleProcessQueuesKM(PVRSRV_CMDCOMP_HANDLE hCmdCompHandle)
3318 PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE*) hCmdCompHandle;
3319 PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
3321 OSScheduleMISR(psDevInfo->hProcessQueuesMISR);
3325 ******************************************************************************
3327 @Function _RGXScheduleProcessQueuesMISR
3329 @Description - Sends uncounted kick to all the DMs (the FW will process all
3330 the queue for all the DMs)
3331 ******************************************************************************/
3332 static void _RGXScheduleProcessQueuesMISR(void *pvData)
3334 PVRSRV_DEVICE_NODE *psDeviceNode = pvData;
3335 PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
3336 PVRSRV_ERROR eError;
3337 PVRSRV_DEV_POWER_STATE ePowerState;
3339 /* We don't need to acquire the BridgeLock as this power transition won't
3340 send a command to the FW */
3341 eError = PVRSRVPowerLock(psDeviceNode);
3342 if (eError != PVRSRV_OK)
3344 PVR_DPF((PVR_DBG_WARNING, "RGXScheduleProcessQueuesKM: failed to acquire powerlock (%s)",
3345 PVRSRVGetErrorStringKM(eError)));
3350 /* Check whether it's worth waking up the GPU */
3351 eError = PVRSRVGetDevicePowerState(psDeviceNode, &ePowerState);
3353 if ((eError == PVRSRV_OK) && (ePowerState == PVRSRV_DEV_POWER_STATE_OFF))
3355 #if !defined(PVRSRV_GPUVIRT_GUESTDRV)
3356 /* For now, guest drivers will always wake-up the GPU */
3357 RGXFWIF_GPU_UTIL_FWCB *psUtilFWCb = psDevInfo->psRGXFWIfGpuUtilFWCb;
3358 IMG_BOOL bGPUHasWorkWaiting;
3360 bGPUHasWorkWaiting =
3361 (RGXFWIF_GPU_UTIL_GET_STATE(psUtilFWCb->ui64LastWord) == RGXFWIF_GPU_UTIL_STATE_BLOCKED);
3363 if (!bGPUHasWorkWaiting)
3365 /* all queues are empty, don't wake up the GPU */
3366 PVRSRVPowerUnlock(psDeviceNode);
3373 /* wake up the GPU */
3374 eError = PVRSRVSetDevicePowerStateKM(psDeviceNode,
3375 PVRSRV_DEV_POWER_STATE_ON,
3379 if (eError != PVRSRV_OK)
3381 PVR_DPF((PVR_DBG_WARNING, "RGXScheduleProcessQueuesKM: failed to transition Rogue to ON (%s)",
3382 PVRSRVGetErrorStringKM(eError)));
3384 PVRSRVPowerUnlock(psDeviceNode);
3388 /* uncounted kick to the FW */
3390 IMG_UINT32 ui32MTSRegVal;
3391 #if defined(SUPPORT_PVRSRV_GPUVIRT)
3392 if(!(psDevInfo->sDevFeatureCfg.ui64Features & RGX_FEATURE_GPU_VIRTUALISATION_BIT_MASK))
3394 ui32MTSRegVal = ((RGXFWIF_DM_GP + PVRSRV_GPUVIRT_OSID) & ~RGX_CR_MTS_SCHEDULE_DM_CLRMSK) | RGX_CR_MTS_SCHEDULE_TASK_NON_COUNTED;
3398 ui32MTSRegVal = (RGXFWIF_DM_GP & ~RGX_CR_MTS_SCHEDULE_DM_CLRMSK) | RGX_CR_MTS_SCHEDULE_TASK_NON_COUNTED;
3401 HTBLOGK(HTB_SF_MAIN_KICK_UNCOUNTED);
3402 __MTSScheduleWrite(psDevInfo, ui32MTSRegVal);
3405 PVRSRVPowerUnlock(psDeviceNode);
3408 PVRSRV_ERROR RGXInstallProcessQueuesMISR(IMG_HANDLE *phMISR, PVRSRV_DEVICE_NODE *psDeviceNode)
3410 return OSInstallMISR(phMISR,
3411 _RGXScheduleProcessQueuesMISR,
3416 ******************************************************************************
3418 @Function RGXScheduleCommand
3420 @Description - Submits a CCB command and kicks the firmware but first schedules
3421 any commands which have to happen before handle
3423 @Input psDevInfo - pointer to device info
3424 @Input eKCCBType - see RGXFWIF_CMD_*
3425 @Input psKCCBCmd - kernel CCB command
3426 @Input ui32CmdSize - kernel CCB SIZE
3427 @Input ui32CacheOpFence - CPU dcache operation fence
3428 @Input ui32PDumpFlags - PDUMP_FLAGS_CONTINUOUS bit set if the pdump flags should be continuous
3431 @Return PVRSRV_ERROR
3433 ******************************************************************************/
3434 PVRSRV_ERROR RGXScheduleCommand(PVRSRV_RGXDEV_INFO *psDevInfo,
3435 RGXFWIF_DM eKCCBType,
3436 RGXFWIF_KCCB_CMD *psKCCBCmd,
3437 IMG_UINT32 ui32CmdSize,
3438 IMG_UINT32 ui32CacheOpFence,
3439 IMG_UINT32 ui32PDumpFlags)
3441 PVRSRV_ERROR eError;
3442 IMG_UINT32 uiMMUSyncUpdate;
3444 eError = CacheOpFence(eKCCBType, ui32CacheOpFence);
3445 if (eError != PVRSRV_OK) goto RGXScheduleCommand_exit;
3447 #if defined (SUPPORT_VALIDATION)
3448 /* For validation, force the core to different dust count states with each kick */
3449 if ((eKCCBType == RGXFWIF_DM_TA) || (eKCCBType == RGXFWIF_DM_CDM))
3451 if (psDevInfo->ui32DeviceFlags & RGXKM_DEVICE_STATE_DUST_REQUEST_INJECT_EN)
3453 IMG_UINT32 ui32NumDusts = RGXGetNextDustCount(&psDevInfo->sDustReqState, psDevInfo->sDevFeatureCfg.ui32MAXDustCount);
3454 PVRSRVDeviceDustCountChange(psDevInfo->psDeviceNode, ui32NumDusts);
3459 eError = RGXPreKickCacheCommand(psDevInfo, eKCCBType, &uiMMUSyncUpdate, IMG_FALSE);
3460 if (eError != PVRSRV_OK) goto RGXScheduleCommand_exit;
3462 eError = RGXSendCommandWithPowLock(psDevInfo, eKCCBType, psKCCBCmd, ui32CmdSize, ui32PDumpFlags);
3463 if (eError != PVRSRV_OK) goto RGXScheduleCommand_exit;
3465 RGXScheduleCommand_exit:
3470 * RGXCheckFirmwareCCB
3472 void RGXCheckFirmwareCCB(PVRSRV_RGXDEV_INFO *psDevInfo)
3474 RGXFWIF_FWCCB_CMD *psFwCCBCmd;
3476 RGXFWIF_CCB_CTL *psFWCCBCtl = psDevInfo->psFirmwareCCBCtl;
3477 IMG_UINT8 *psFWCCB = psDevInfo->psFirmwareCCB;
3479 while (psFWCCBCtl->ui32ReadOffset != psFWCCBCtl->ui32WriteOffset)
3481 /* Point to the next command */
3482 psFwCCBCmd = ((RGXFWIF_FWCCB_CMD *)psFWCCB) + psFWCCBCtl->ui32ReadOffset;
3484 HTBLOGK(HTB_SF_MAIN_FWCCB_CMD, psFwCCBCmd->eCmdType);
3485 switch(psFwCCBCmd->eCmdType)
3487 case RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING:
3489 if (psDevInfo->bPDPEnabled)
3491 PDUMP_PANIC(ZSBUFFER_BACKING, "Request to add backing to ZSBuffer");
3493 RGXProcessRequestZSBufferBacking(psDevInfo,
3494 psFwCCBCmd->uCmdData.sCmdZSBufferBacking.ui32ZSBufferID);
3498 case RGXFWIF_FWCCB_CMD_ZSBUFFER_UNBACKING:
3500 if (psDevInfo->bPDPEnabled)
3502 PDUMP_PANIC(ZSBUFFER_UNBACKING, "Request to remove backing from ZSBuffer");
3504 RGXProcessRequestZSBufferUnbacking(psDevInfo,
3505 psFwCCBCmd->uCmdData.sCmdZSBufferBacking.ui32ZSBufferID);
3509 case RGXFWIF_FWCCB_CMD_FREELIST_GROW:
3511 if (psDevInfo->bPDPEnabled)
3513 PDUMP_PANIC(FREELIST_GROW, "Request to grow the free list");
3515 RGXProcessRequestGrow(psDevInfo,
3516 psFwCCBCmd->uCmdData.sCmdFreeListGS.ui32FreelistID);
3520 case RGXFWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION:
3522 if (psDevInfo->bPDPEnabled)
3524 PDUMP_PANIC(FREELISTS_RECONSTRUCTION, "Request to reconstruct free lists");
3526 #if defined(PVRSRV_GPUVIRT_GUESTDRV)
3527 PVR_DPF((PVR_DBG_MESSAGE, "RGXCheckFirmwareCCBs: Freelist reconstruction request (%d) for %d freelists",
3528 psFwCCBCmd->uCmdData.sCmdFreeListsReconstruction.ui32HwrCounter+1,
3529 psFwCCBCmd->uCmdData.sCmdFreeListsReconstruction.ui32FreelistsCount));
3531 PVR_DPF((PVR_DBG_MESSAGE, "RGXCheckFirmwareCCBs: Freelist reconstruction request (%d/%d) for %d freelists",
3532 psFwCCBCmd->uCmdData.sCmdFreeListsReconstruction.ui32HwrCounter+1,
3533 psDevInfo->psRGXFWIfTraceBuf->ui32HwrCounter+1,
3534 psFwCCBCmd->uCmdData.sCmdFreeListsReconstruction.ui32FreelistsCount));
3537 RGXProcessRequestFreelistsReconstruction(psDevInfo,
3538 psFwCCBCmd->uCmdData.sCmdFreeListsReconstruction.ui32FreelistsCount,
3539 psFwCCBCmd->uCmdData.sCmdFreeListsReconstruction.aui32FreelistIDs);
3543 case RGXFWIF_FWCCB_CMD_DOPPLER_MEMORY_GROW:
3545 if(psDevInfo->sDevFeatureCfg.ui64Features & RGX_FEATURE_RAY_TRACING_BIT_MASK)
3547 if (psDevInfo->bPDPEnabled)
3549 PDUMP_PANIC(FREELIST_GROW, "Request to grow the RPM free list");
3551 RGXProcessRequestRPMGrow(psDevInfo,
3552 psFwCCBCmd->uCmdData.sCmdFreeListGS.ui32FreelistID);
3556 case RGXFWIF_FWCCB_CMD_CONTEXT_RESET_NOTIFICATION:
3558 DLLIST_NODE *psNode, *psNext;
3559 RGXFWIF_FWCCB_CMD_CONTEXT_RESET_DATA *psCmdContextResetNotification =
3560 &psFwCCBCmd->uCmdData.sCmdContextResetNotification;
3561 IMG_UINT32 ui32ServerCommonContextID =
3562 psCmdContextResetNotification->ui32ServerCommonContextID;
3563 RGX_SERVER_COMMON_CONTEXT *psServerCommonContext = NULL;
3565 dllist_foreach_node(&psDevInfo->sCommonCtxtListHead, psNode, psNext)
3567 RGX_SERVER_COMMON_CONTEXT *psThisContext =
3568 IMG_CONTAINER_OF(psNode, RGX_SERVER_COMMON_CONTEXT, sListNode);
3570 if (psThisContext->ui32ContextID == ui32ServerCommonContextID)
3572 psServerCommonContext = psThisContext;
3577 PVR_DPF((PVR_DBG_MESSAGE, "RGXCheckFirmwareCCBs: Context 0x%p reset (ID=0x%08x, Reason=%d, JobRef=0x%08x)",
3578 psServerCommonContext,
3579 psCmdContextResetNotification->ui32ServerCommonContextID,
3580 (IMG_UINT32)(psCmdContextResetNotification->eResetReason),
3581 psCmdContextResetNotification->ui32ResetJobRef));
3583 if (psServerCommonContext != NULL)
3585 psServerCommonContext->eLastResetReason = psCmdContextResetNotification->eResetReason;
3586 psServerCommonContext->ui32LastResetJobRef = psCmdContextResetNotification->ui32ResetJobRef;
3589 if (psCmdContextResetNotification->bPageFault)
3591 DevmemIntPFNotify(psDevInfo->psDeviceNode,
3592 psCmdContextResetNotification->ui64PCAddress);
3597 case RGXFWIF_FWCCB_CMD_DEBUG_DUMP:
3599 RGXDumpDebugInfo(NULL,NULL,psDevInfo);
3603 case RGXFWIF_FWCCB_CMD_UPDATE_STATS:
3605 #if defined(PVRSRV_ENABLE_PROCESS_STATS)
3606 IMG_PID pidTmp = psFwCCBCmd->uCmdData.sCmdUpdateStatsData.pidOwner;
3607 IMG_INT32 i32AdjustmentValue = psFwCCBCmd->uCmdData.sCmdUpdateStatsData.i32AdjustmentValue;
3609 switch (psFwCCBCmd->uCmdData.sCmdUpdateStatsData.eElementToUpdate)
3611 case RGXFWIF_FWCCB_CMD_UPDATE_NUM_PARTIAL_RENDERS:
3613 PVRSRVStatsUpdateRenderContextStats(i32AdjustmentValue,0,0,0,0,0,pidTmp);
3616 case RGXFWIF_FWCCB_CMD_UPDATE_NUM_OUT_OF_MEMORY:
3618 PVRSRVStatsUpdateRenderContextStats(0,i32AdjustmentValue,0,0,0,0,pidTmp);
3621 case RGXFWIF_FWCCB_CMD_UPDATE_NUM_TA_STORES:
3623 PVRSRVStatsUpdateRenderContextStats(0,0,i32AdjustmentValue,0,0,0,pidTmp);
3626 case RGXFWIF_FWCCB_CMD_UPDATE_NUM_3D_STORES:
3628 PVRSRVStatsUpdateRenderContextStats(0,0,0,i32AdjustmentValue,0,0,pidTmp);
3631 case RGXFWIF_FWCCB_CMD_UPDATE_NUM_SH_STORES:
3633 PVRSRVStatsUpdateRenderContextStats(0,0,0,0,i32AdjustmentValue,0,pidTmp);
3636 case RGXFWIF_FWCCB_CMD_UPDATE_NUM_CDM_STORES:
3638 PVRSRVStatsUpdateRenderContextStats(0,0,0,0,0,i32AdjustmentValue,pidTmp);
3645 case RGXFWIF_FWCCB_CMD_CORE_CLK_RATE_CHANGE:
3647 #if defined(SUPPORT_PDVFS)
3648 PDVFSProcessCoreClkRateChange(psDevInfo,
3649 psFwCCBCmd->uCmdData.sCmdCoreClkRateChange.ui32CoreClkRate);
3655 PVR_ASSERT(IMG_FALSE);
3659 /* Update read offset */
3660 psFWCCBCtl->ui32ReadOffset = (psFWCCBCtl->ui32ReadOffset + 1) & psFWCCBCtl->ui32WrapMask;
3665 * PVRSRVRGXFrameworkCopyCommand
3667 PVRSRV_ERROR PVRSRVRGXFrameworkCopyCommand(DEVMEM_MEMDESC *psFWFrameworkMemDesc,
3668 IMG_PBYTE pbyGPUFRegisterList,
3669 IMG_UINT32 ui32FrameworkRegisterSize)
3671 PVRSRV_ERROR eError;
3672 RGXFWIF_RF_REGISTERS *psRFReg;
3674 eError = DevmemAcquireCpuVirtAddr(psFWFrameworkMemDesc,
3676 if (eError != PVRSRV_OK)
3678 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXFrameworkCopyCommand: Failed to map firmware render context state (%u)",
3683 OSDeviceMemCopy(psRFReg, pbyGPUFRegisterList, ui32FrameworkRegisterSize);
3685 /* Release the CPU mapping */
3686 DevmemReleaseCpuVirtAddr(psFWFrameworkMemDesc);
3689 * Dump the FW framework buffer
3691 PDUMPCOMMENT("Dump FWFramework buffer");
3692 DevmemPDumpLoadMem(psFWFrameworkMemDesc, 0, ui32FrameworkRegisterSize, PDUMP_FLAGS_CONTINUOUS);
3698 * PVRSRVRGXFrameworkCreateKM
3700 PVRSRV_ERROR PVRSRVRGXFrameworkCreateKM(PVRSRV_DEVICE_NODE *psDeviceNode,
3701 DEVMEM_MEMDESC **ppsFWFrameworkMemDesc,
3702 IMG_UINT32 ui32FrameworkCommandSize)
3704 PVRSRV_ERROR eError;
3705 PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
3708 Allocate device memory for the firmware GPU framework state.
3709 Sufficient info to kick one or more DMs should be contained in this buffer
3711 PDUMPCOMMENT("Allocate Rogue firmware framework state");
3713 eError = DevmemFwAllocate(psDevInfo,
3714 ui32FrameworkCommandSize,
3715 RGX_FWCOMCTX_ALLOCFLAGS,
3716 "FwGPUFrameworkState",
3717 ppsFWFrameworkMemDesc);
3719 if (eError != PVRSRV_OK)
3721 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXFrameworkContextKM: Failed to allocate firmware framework state (%u)",
3729 PVRSRV_ERROR RGXWaitForFWOp(PVRSRV_RGXDEV_INFO *psDevInfo,
3731 PVRSRV_CLIENT_SYNC_PRIM *psSyncPrim,
3732 IMG_UINT32 ui32PDumpFlags)
3734 PVRSRV_ERROR eError = PVRSRV_OK;
3735 PVRSRV_DEVICE_NODE *psDeviceNode = psDevInfo->psDeviceNode;
3736 RGXFWIF_KCCB_CMD sCmdSyncPrim;
3738 /* Ensure Rogue is powered up before kicking MTS */
3739 eError = PVRSRVPowerLock(psDeviceNode);
3741 if (eError != PVRSRV_OK)
3743 PVR_DPF((PVR_DBG_ERROR, "%s: failed to acquire powerlock (%s)",
3745 PVRSRVGetErrorStringKM(eError)));
3747 goto _PVRSRVPowerLock_Exit;
3751 eError = PVRSRVSetDevicePowerStateKM(psDeviceNode,
3752 PVRSRV_DEV_POWER_STATE_ON,
3756 if (eError != PVRSRV_OK)
3758 PVR_DPF((PVR_DBG_ERROR, "%s: failed to transition Rogue to ON (%s)",
3760 PVRSRVGetErrorStringKM(eError)));
3762 goto _PVRSRVSetDevicePowerStateKM_Exit;
3765 /* Setup sync primitive */
3766 eError = SyncPrimSet(psSyncPrim, 0);
3767 if (eError != PVRSRV_OK)
3769 PVR_DPF((PVR_DBG_ERROR,"%s: Failed to set SyncPrim (%u)",
3770 __FUNCTION__, eError));
3771 goto _SyncPrimSet_Exit;
3774 /* prepare a sync command */
3775 eError = SyncPrimGetFirmwareAddr(psSyncPrim,
3776 &sCmdSyncPrim.uCmdData.sSyncData.sSyncObjDevVAddr.ui32Addr);
3777 if (eError != PVRSRV_OK)
3779 PVR_DPF((PVR_DBG_ERROR,"%s: Failed to get SyncPrim FW address(%u)",
3780 __FUNCTION__, eError));
3781 goto _SyncPrimGetFirmwareAddr_Exit;
3783 sCmdSyncPrim.eCmdType = RGXFWIF_KCCB_CMD_SYNC;
3784 sCmdSyncPrim.uCmdData.sSyncData.uiUpdateVal = 1;
3786 PDUMPCOMMENT("RGXWaitForFWOp: Submit Kernel SyncPrim [0x%08x] to DM %d ",
3787 sCmdSyncPrim.uCmdData.sSyncData.sSyncObjDevVAddr.ui32Addr, eDM);
3789 /* submit the sync primitive to the kernel CCB */
3790 eError = RGXSendCommand(psDevInfo,
3793 sizeof(RGXFWIF_KCCB_CMD),
3795 if (eError != PVRSRV_OK)
3797 PVR_DPF((PVR_DBG_ERROR,"%s: Failed to schedule Kernel SyncPrim with error (%u)",
3800 goto _RGXSendCommandRaw_Exit;
3803 /* Wait for sync primitive to be updated */
3805 PDUMPCOMMENT("RGXScheduleCommandAndWait: Poll for Kernel SyncPrim [0x%08x] on DM %d ",
3806 sCmdSyncPrim.uCmdData.sSyncData.sSyncObjDevVAddr.ui32Addr, eDM);
3808 SyncPrimPDumpPol(psSyncPrim,
3811 PDUMP_POLL_OPERATOR_EQUAL,
3816 RGXFWIF_CCB_CTL *psKCCBCtl = psDevInfo->psKernelCCBCtl;
3817 IMG_UINT32 ui32CurrentQueueLength =
3818 (psKCCBCtl->ui32WrapMask+1 +
3819 psKCCBCtl->ui32WriteOffset -
3820 psKCCBCtl->ui32ReadOffset) & psKCCBCtl->ui32WrapMask;
3821 IMG_UINT32 ui32MaxRetries;
3823 for (ui32MaxRetries = (ui32CurrentQueueLength + 1) * 3;
3827 eError = PVRSRVWaitForValueKMAndHoldBridgeLockKM(psSyncPrim->pui32LinAddr, 1, 0xffffffff);
3829 if (eError != PVRSRV_ERROR_TIMEOUT)
3835 if (eError == PVRSRV_ERROR_TIMEOUT)
3837 PVR_DPF((PVR_DBG_ERROR,"%s: PVRSRVWaitForValueKMAndHoldBridgeLock timed out. Dump debug information.",
3839 PVRSRVPowerUnlock(psDeviceNode);
3841 PVRSRVDebugRequest(psDeviceNode, DEBUG_REQUEST_VERBOSITY_MAX, NULL, NULL);
3842 PVR_ASSERT(eError != PVRSRV_ERROR_TIMEOUT);
3843 goto _PVRSRVDebugRequest_Exit;
3847 _RGXSendCommandRaw_Exit:
3848 _SyncPrimGetFirmwareAddr_Exit:
3850 _PVRSRVSetDevicePowerStateKM_Exit:
3852 PVRSRVPowerUnlock(psDeviceNode);
3854 _PVRSRVDebugRequest_Exit:
3855 _PVRSRVPowerLock_Exit:
3859 PVRSRV_ERROR RGXStateFlagCtrl(PVRSRV_RGXDEV_INFO *psDevInfo,
3860 IMG_UINT32 ui32Config,
3861 IMG_UINT32 *pui32ConfigState,
3862 IMG_BOOL bSetNotClear)
3864 PVRSRV_ERROR eError;
3865 RGXFWIF_KCCB_CMD sStateFlagCmd;
3866 PVRSRV_CLIENT_SYNC_PRIM *psResponseSync;
3870 eError = PVRSRV_ERROR_INVALID_PARAMS;
3874 if (psDevInfo->psDeviceNode->eDevState != PVRSRV_DEVICE_STATE_ACTIVE)
3876 eError = PVRSRV_ERROR_NOT_INITIALISED;
3880 sStateFlagCmd.eCmdType = RGXFWIF_KCCB_CMD_STATEFLAGS_CTRL;
3881 sStateFlagCmd.eDM = RGXFWIF_DM_GP;
3882 sStateFlagCmd.uCmdData.sStateFlagCtrl.ui32Config = ui32Config;
3883 sStateFlagCmd.uCmdData.sStateFlagCtrl.bSetNotClear = bSetNotClear;
3885 eError = SyncPrimAlloc(psDevInfo->hSyncPrimContext, &psResponseSync, "rgx config flags");
3886 if (PVRSRV_OK != eError)
3890 eError = SyncPrimSet(psResponseSync, 0);
3891 if (eError != PVRSRV_OK)
3893 goto return_freesync_;
3896 eError = SyncPrimGetFirmwareAddr(psResponseSync, &sStateFlagCmd.uCmdData.sStateFlagCtrl.sSyncObjDevVAddr.ui32Addr);
3897 if (PVRSRV_OK != eError)
3899 goto return_freesync_;
3902 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
3904 eError = RGXScheduleCommand(psDevInfo,
3907 sizeof(sStateFlagCmd),
3909 PDUMP_FLAGS_CONTINUOUS);
3910 if (eError != PVRSRV_ERROR_RETRY)
3914 OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
3915 } END_LOOP_UNTIL_TIMEOUT();
3916 PVR_LOGG_IF_ERROR(eError, "RGXScheduleCommand", return_);
3918 /* Wait for FW to complete */
3919 eError = RGXWaitForFWOp(psDevInfo,
3921 psDevInfo->psDeviceNode->psSyncPrim,
3922 PDUMP_FLAGS_CONTINUOUS);
3923 PVR_LOGG_IF_ERROR(eError, "RGXWaitForFWOp", return_);
3925 if (pui32ConfigState)
3927 *pui32ConfigState = *psResponseSync->pui32LinAddr;
3931 SyncPrimFree(psResponseSync);
3937 PVRSRV_ERROR RGXScheduleCleanupCommand(PVRSRV_RGXDEV_INFO *psDevInfo,
3939 RGXFWIF_KCCB_CMD *psKCCBCmd,
3940 IMG_UINT32 ui32CmdSize,
3941 RGXFWIF_CLEANUP_TYPE eCleanupType,
3942 PVRSRV_CLIENT_SYNC_PRIM *psSyncPrim,
3943 IMG_UINT32 ui32PDumpFlags)
3945 PVRSRV_ERROR eError;
3947 psKCCBCmd->eCmdType = RGXFWIF_KCCB_CMD_CLEANUP;
3949 psKCCBCmd->uCmdData.sCleanupData.eCleanupType = eCleanupType;
3950 eError = SyncPrimGetFirmwareAddr(psSyncPrim, &psKCCBCmd->uCmdData.sCleanupData.sSyncObjDevVAddr.ui32Addr);
3951 if (eError != PVRSRV_OK)
3956 eError = SyncPrimSet(psSyncPrim, 0);
3957 if (eError != PVRSRV_OK)
3963 Send the cleanup request to the firmware. If the resource is still busy
3964 the firmware will tell us and we'll drop out with a retry.
3966 eError = RGXScheduleCommand(psDevInfo,
3972 if (eError != PVRSRV_OK)
3977 /* Wait for sync primitive to be updated */
3979 PDUMPCOMMENT("Wait for the firmware to reply to the cleanup command");
3980 SyncPrimPDumpPol(psSyncPrim,
3981 RGXFWIF_CLEANUP_RUN,
3982 RGXFWIF_CLEANUP_RUN,
3983 PDUMP_POLL_OPERATOR_EQUAL,
3987 * The cleanup request to the firmware will tell us if a given resource is busy or not.
3988 * If the RGXFWIF_CLEANUP_BUSY flag is set, this means that the resource is still in use.
3989 * In this case we return a PVRSRV_ERROR_RETRY error to the client drivers and they will
3990 * re-issue the cleanup request until it succeed.
3992 * Since this retry mechanism doesn't work for pdumps, client drivers should ensure
3993 * that cleanup requests are only submitted if the resource is unused.
3994 * If this is not the case, the following poll will block infinitely, making sure
3995 * the issue doesn't go unnoticed.
3997 PDUMPCOMMENT("Cleanup: If this poll fails, the following resource is still in use (DM=%u, type=%u, address=0x%08x), which is incorrect in pdumps",
3999 psKCCBCmd->uCmdData.sCleanupData.eCleanupType,
4000 psKCCBCmd->uCmdData.sCleanupData.uCleanupData.psContext.ui32Addr);
4001 SyncPrimPDumpPol(psSyncPrim,
4003 RGXFWIF_CLEANUP_BUSY,
4004 PDUMP_POLL_OPERATOR_EQUAL,
4009 RGXFWIF_CCB_CTL *psKCCBCtl = psDevInfo->psKernelCCBCtl;
4010 IMG_UINT32 ui32CurrentQueueLength = (psKCCBCtl->ui32WrapMask+1 +
4011 psKCCBCtl->ui32WriteOffset -
4012 psKCCBCtl->ui32ReadOffset) & psKCCBCtl->ui32WrapMask;
4013 IMG_UINT32 ui32MaxRetries;
4015 for (ui32MaxRetries = ui32CurrentQueueLength + 1;
4019 eError = PVRSRVWaitForValueKMAndHoldBridgeLockKM(psSyncPrim->pui32LinAddr, RGXFWIF_CLEANUP_RUN, RGXFWIF_CLEANUP_RUN);
4021 if (eError != PVRSRV_ERROR_TIMEOUT)
4028 If the firmware hasn't got back to us in a timely manner
4029 then bail and let the caller retry the command.
4031 if (eError == PVRSRV_ERROR_TIMEOUT)
4033 PVR_DPF((PVR_DBG_WARNING,"RGXScheduleCleanupCommand: PVRSRVWaitForValueKMAndHoldBridgeLock timed out. Dump debug information."));
4035 eError = PVRSRV_ERROR_RETRY;
4037 PVRSRVDebugRequest(psDevInfo->psDeviceNode,
4038 DEBUG_REQUEST_VERBOSITY_MAX, NULL, NULL);
4042 else if (eError != PVRSRV_OK)
4049 If the command has was run but a resource was busy, then the request
4050 will need to be retried.
4052 if (*psSyncPrim->pui32LinAddr & RGXFWIF_CLEANUP_BUSY)
4054 eError = PVRSRV_ERROR_RETRY;
4055 goto fail_requestbusy;
4063 PVR_ASSERT(eError != PVRSRV_OK);
4069 RGXRequestCommonContextCleanUp
4071 PVRSRV_ERROR RGXFWRequestCommonContextCleanUp(PVRSRV_DEVICE_NODE *psDeviceNode,
4072 RGX_SERVER_COMMON_CONTEXT *psServerCommonContext,
4073 PVRSRV_CLIENT_SYNC_PRIM *psSyncPrim,
4075 IMG_UINT32 ui32PDumpFlags)
4077 RGXFWIF_KCCB_CMD sRCCleanUpCmd = {0};
4078 PVRSRV_ERROR eError;
4079 PRGXFWIF_FWCOMMONCONTEXT psFWCommonContextFWAddr;
4081 psFWCommonContextFWAddr = FWCommonContextGetFWAddress(psServerCommonContext);
4083 PDUMPCOMMENT("Common ctx cleanup Request DM%d [context = 0x%08x]",
4084 eDM, psFWCommonContextFWAddr.ui32Addr);
4085 PDUMPCOMMENT("Wait for CCB to be empty before common ctx cleanup");
4087 RGXCCBPDumpDrainCCB(FWCommonContextGetClientCCB(psServerCommonContext), ui32PDumpFlags);
4089 /* Setup our command data, the cleanup call will fill in the rest */
4090 sRCCleanUpCmd.uCmdData.sCleanupData.uCleanupData.psContext = psFWCommonContextFWAddr;
4092 /* Request cleanup of the firmware resource */
4093 eError = RGXScheduleCleanupCommand(psDeviceNode->pvDevice,
4096 sizeof(RGXFWIF_KCCB_CMD),
4097 RGXFWIF_CLEANUP_FWCOMMONCONTEXT,
4101 if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
4103 PVR_DPF((PVR_DBG_ERROR,"RGXRequestCommonContextCleanUp: Failed to schedule a memory context cleanup with error (%u)", eError));
4110 * RGXRequestHWRTDataCleanUp
4113 PVRSRV_ERROR RGXFWRequestHWRTDataCleanUp(PVRSRV_DEVICE_NODE *psDeviceNode,
4114 PRGXFWIF_HWRTDATA psHWRTData,
4115 PVRSRV_CLIENT_SYNC_PRIM *psSync,
4118 RGXFWIF_KCCB_CMD sHWRTDataCleanUpCmd = {0};
4119 PVRSRV_ERROR eError;
4121 PDUMPCOMMENT("HW RTData cleanup Request DM%d [HWRTData = 0x%08x]", eDM, psHWRTData.ui32Addr);
4123 sHWRTDataCleanUpCmd.uCmdData.sCleanupData.uCleanupData.psHWRTData = psHWRTData;
4125 eError = RGXScheduleCleanupCommand(psDeviceNode->pvDevice,
4127 &sHWRTDataCleanUpCmd,
4128 sizeof(sHWRTDataCleanUpCmd),
4129 RGXFWIF_CLEANUP_HWRTDATA,
4133 if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
4135 PVR_DPF((PVR_DBG_ERROR,"RGXRequestHWRTDataCleanUp: Failed to schedule a HWRTData cleanup with error (%u)", eError));
4142 RGXFWRequestFreeListCleanUp
4144 PVRSRV_ERROR RGXFWRequestFreeListCleanUp(PVRSRV_RGXDEV_INFO *psDevInfo,
4145 PRGXFWIF_FREELIST psFWFreeList,
4146 PVRSRV_CLIENT_SYNC_PRIM *psSync)
4148 RGXFWIF_KCCB_CMD sFLCleanUpCmd = {0};
4149 PVRSRV_ERROR eError;
4151 PDUMPCOMMENT("Free list cleanup Request [FreeList = 0x%08x]", psFWFreeList.ui32Addr);
4153 /* Setup our command data, the cleanup call will fill in the rest */
4154 sFLCleanUpCmd.uCmdData.sCleanupData.uCleanupData.psFreelist = psFWFreeList;
4156 /* Request cleanup of the firmware resource */
4157 eError = RGXScheduleCleanupCommand(psDevInfo,
4160 sizeof(RGXFWIF_KCCB_CMD),
4161 RGXFWIF_CLEANUP_FREELIST,
4165 if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
4167 PVR_DPF((PVR_DBG_ERROR,"RGXFWRequestFreeListCleanUp: Failed to schedule a memory context cleanup with error (%u)", eError));
4174 RGXFWRequestZSBufferCleanUp
4176 PVRSRV_ERROR RGXFWRequestZSBufferCleanUp(PVRSRV_RGXDEV_INFO *psDevInfo,
4177 PRGXFWIF_ZSBUFFER psFWZSBuffer,
4178 PVRSRV_CLIENT_SYNC_PRIM *psSync)
4180 RGXFWIF_KCCB_CMD sZSBufferCleanUpCmd = {0};
4181 PVRSRV_ERROR eError;
4183 PDUMPCOMMENT("ZS Buffer cleanup Request [ZS Buffer = 0x%08x]", psFWZSBuffer.ui32Addr);
4185 /* Setup our command data, the cleanup call will fill in the rest */
4186 sZSBufferCleanUpCmd.uCmdData.sCleanupData.uCleanupData.psZSBuffer = psFWZSBuffer;
4188 /* Request cleanup of the firmware resource */
4189 eError = RGXScheduleCleanupCommand(psDevInfo,
4191 &sZSBufferCleanUpCmd,
4192 sizeof(RGXFWIF_KCCB_CMD),
4193 RGXFWIF_CLEANUP_ZSBUFFER,
4197 if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
4199 PVR_DPF((PVR_DBG_ERROR,"RGXFWRequestZSBufferCleanUp: Failed to schedule a memory context cleanup with error (%u)", eError));
4206 PVRSRV_ERROR RGXFWRequestRayFrameDataCleanUp(PVRSRV_DEVICE_NODE *psDeviceNode,
4207 PRGXFWIF_RAY_FRAME_DATA psHWFrameData,
4208 PVRSRV_CLIENT_SYNC_PRIM *psSync,
4211 RGXFWIF_KCCB_CMD sHWFrameDataCleanUpCmd = {0};
4212 PVRSRV_ERROR eError;
4214 PDUMPCOMMENT("HW FrameData cleanup Request DM%d [HWFrameData = 0x%08x]", eDM, psHWFrameData.ui32Addr);
4216 sHWFrameDataCleanUpCmd.uCmdData.sCleanupData.uCleanupData.psHWFrameData = psHWFrameData;
4218 eError = RGXScheduleCleanupCommand(psDeviceNode->pvDevice,
4220 &sHWFrameDataCleanUpCmd,
4221 sizeof(sHWFrameDataCleanUpCmd),
4222 RGXFWIF_CLEANUP_HWFRAMEDATA,
4226 if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
4228 PVR_DPF((PVR_DBG_ERROR,"RGXFWRequestRayFrameDataCleanUp: Failed to schedule a HWFrameData cleanup with error (%u)", eError));
4235 RGXFWRequestRPMFreeListCleanUp
4237 PVRSRV_ERROR RGXFWRequestRPMFreeListCleanUp(PVRSRV_RGXDEV_INFO *psDevInfo,
4238 PRGXFWIF_RPM_FREELIST psFWRPMFreeList,
4239 PVRSRV_CLIENT_SYNC_PRIM *psSync)
4241 RGXFWIF_KCCB_CMD sFLCleanUpCmd = {0};
4242 PVRSRV_ERROR eError;
4244 PDUMPCOMMENT("RPM Free list cleanup Request [RPM FreeList = 0x%08x]", psFWRPMFreeList.ui32Addr);
4246 /* Setup our command data, the cleanup call will fill in the rest */
4247 sFLCleanUpCmd.uCmdData.sCleanupData.uCleanupData.psRPMFreelist = psFWRPMFreeList;
4249 /* Request cleanup of the firmware resource */
4250 eError = RGXScheduleCleanupCommand(psDevInfo,
4253 sizeof(RGXFWIF_KCCB_CMD),
4254 RGXFWIF_CLEANUP_RPM_FREELIST,
4258 if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
4260 PVR_DPF((PVR_DBG_ERROR,"RGXFWRequestRPMFreeListCleanUp: Failed to schedule a memory context cleanup with error (%u)", eError));
4266 PVRSRV_ERROR RGXFWSetHCSDeadline(PVRSRV_RGXDEV_INFO *psDevInfo,
4267 IMG_UINT32 ui32HCSDeadlineMs)
4269 PVRSRV_ERROR eError;
4270 RGXFWIF_KCCB_CMD sSetHCSDeadline;
4272 sSetHCSDeadline.eCmdType = RGXFWIF_KCCB_CMD_HCS_SET_DEADLINE;
4273 sSetHCSDeadline.eDM = RGXFWIF_DM_GP;
4274 sSetHCSDeadline.uCmdData.sHCSCtrl.ui32HCSDeadlineMS = ui32HCSDeadlineMs;
4276 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
4278 eError = RGXScheduleCommand(psDevInfo,
4281 sizeof(sSetHCSDeadline),
4283 PDUMP_FLAGS_CONTINUOUS);
4285 if (eError != PVRSRV_ERROR_RETRY)
4289 OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
4290 } END_LOOP_UNTIL_TIMEOUT();
4295 PVRSRV_ERROR RGXFWOSConfig(PVRSRV_RGXDEV_INFO *psDevInfo)
4297 PVRSRV_ERROR eError;
4298 RGXFWIF_KCCB_CMD sOSConfigCmdData;
4300 sOSConfigCmdData.eCmdType = RGXFWIF_KCCB_CMD_OS_CFG_INIT;
4301 sOSConfigCmdData.eDM = RGXFWIF_DM_GP;
4302 sOSConfigCmdData.uCmdData.sCmdOSConfigData.sOSInit = psDevInfo->sFWInitFWAddr;
4304 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
4306 eError = RGXScheduleCommand(psDevInfo,
4309 sizeof(sOSConfigCmdData),
4311 PDUMP_FLAGS_CONTINUOUS);
4312 if (eError != PVRSRV_ERROR_RETRY)
4316 OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
4317 } END_LOOP_UNTIL_TIMEOUT();
4322 PVRSRV_ERROR RGXFWSetOSIsolationThreshold(PVRSRV_RGXDEV_INFO *psDevInfo,
4323 IMG_UINT32 ui32IsolationPriorityThreshold)
4325 PVRSRV_ERROR eError;
4326 RGXFWIF_KCCB_CMD sOSidIsoConfCmd;
4328 sOSidIsoConfCmd.eCmdType = RGXFWIF_KCCB_CMD_OS_ISOLATION_GROUP_CHANGE;
4329 sOSidIsoConfCmd.uCmdData.sCmdOSidIsolationData.ui32IsolationPriorityThreshold = ui32IsolationPriorityThreshold;
4331 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
4333 eError = RGXScheduleCommand(psDevInfo,
4336 sizeof(sOSidIsoConfCmd),
4338 PDUMP_FLAGS_CONTINUOUS);
4339 if (eError != PVRSRV_ERROR_RETRY)
4343 OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
4344 } END_LOOP_UNTIL_TIMEOUT();
4349 PVRSRV_ERROR RGXFWSetVMOnlineState(PVRSRV_RGXDEV_INFO *psDevInfo,
4350 IMG_UINT32 ui32OSid,
4351 RGXFWIF_OS_STATE_CHANGE eOSOnlineState)
4353 PVRSRV_ERROR eError = PVRSRV_OK;
4354 #if !defined(PVRSRV_GPUVIRT_GUESTDRV)
4355 RGXFWIF_KCCB_CMD sOSOnlineStateCmd;
4356 RGXFWIF_TRACEBUF *psRGXFWIfTraceBuf = psDevInfo->psRGXFWIfTraceBuf;
4357 volatile IMG_UINT32 *pui32OSStateFlags;
4359 sOSOnlineStateCmd.eCmdType = RGXFWIF_KCCB_CMD_OS_ONLINE_STATE_CONFIGURE;
4360 sOSOnlineStateCmd.uCmdData.sCmdOSOnlineStateData.ui32OSid = ui32OSid;
4361 sOSOnlineStateCmd.uCmdData.sCmdOSOnlineStateData.eNewOSState = eOSOnlineState;
4363 if (eOSOnlineState == RGXFWIF_OS_ONLINE)
4365 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
4367 eError = RGXScheduleCommand(psDevInfo,
4370 sizeof(sOSOnlineStateCmd),
4372 PDUMP_FLAGS_CONTINUOUS);
4373 if (eError != PVRSRV_ERROR_RETRY)
4377 OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
4378 } END_LOOP_UNTIL_TIMEOUT();
4383 if (psRGXFWIfTraceBuf == NULL)
4385 return PVRSRV_ERROR_NOT_INITIALISED;
4387 pui32OSStateFlags = (volatile IMG_UINT32*) &psRGXFWIfTraceBuf->ui32OSStateFlags[ui32OSid];
4389 /* Attempt several times until the FW manages to offload the OS */
4390 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
4392 IMG_UINT32 ui32OSStateFlags;
4395 eError = RGXScheduleCommand(psDevInfo,
4398 sizeof(sOSOnlineStateCmd),
4401 if (unlikely(eError == PVRSRV_ERROR_RETRY))
4405 PVR_LOGG_IF_ERROR(eError, "RGXScheduleCommand", return_);
4407 /* Wait for FW to process the cmd */
4408 eError = RGXWaitForFWOp(psDevInfo,
4410 psDevInfo->psDeviceNode->psSyncPrim,
4411 PDUMP_FLAGS_CONTINUOUS);
4412 PVR_LOGG_IF_ERROR(eError, "RGXWaitForFWOp", return_);
4414 /* read the OS state */
4416 ui32OSStateFlags = *pui32OSStateFlags;
4418 if ((ui32OSStateFlags & RGXFW_OS_STATE_ACTIVE_OS) == 0)
4420 /* FW finished offloading the OSID */
4426 eError = PVRSRV_ERROR_TIMEOUT;
4429 OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
4431 } END_LOOP_UNTIL_TIMEOUT();
4438 PVRSRV_ERROR RGXFWChangeOSidPriority(PVRSRV_RGXDEV_INFO *psDevInfo,
4439 IMG_UINT32 ui32OSid,
4440 IMG_UINT32 ui32Priority)
4442 PVRSRV_ERROR eError;
4443 RGXFWIF_KCCB_CMD sOSidPriorityCmd;
4445 sOSidPriorityCmd.eCmdType = RGXFWIF_KCCB_CMD_OSID_PRIORITY_CHANGE;
4446 sOSidPriorityCmd.uCmdData.sCmdOSidPriorityData.ui32OSidNum = ui32OSid;
4447 sOSidPriorityCmd.uCmdData.sCmdOSidPriorityData.ui32Priority = ui32Priority;
4449 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
4451 eError = RGXScheduleCommand(psDevInfo,
4454 sizeof(sOSidPriorityCmd),
4456 PDUMP_FLAGS_CONTINUOUS);
4457 if (eError != PVRSRV_ERROR_RETRY)
4461 OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
4462 } END_LOOP_UNTIL_TIMEOUT();
4467 PVRSRV_ERROR ContextSetPriority(RGX_SERVER_COMMON_CONTEXT *psContext,
4468 CONNECTION_DATA *psConnection,
4469 PVRSRV_RGXDEV_INFO *psDevInfo,
4470 IMG_UINT32 ui32Priority,
4473 IMG_UINT32 ui32CmdSize;
4474 IMG_UINT8 *pui8CmdPtr;
4475 RGXFWIF_KCCB_CMD sPriorityCmd;
4476 RGXFWIF_CCB_CMD_HEADER *psCmdHeader;
4477 RGXFWIF_CMD_PRIORITY *psCmd;
4478 PVRSRV_ERROR eError;
4481 Get space for command
4483 ui32CmdSize = RGX_CCB_FWALLOC_ALIGN(sizeof(RGXFWIF_CCB_CMD_HEADER) + sizeof(RGXFWIF_CMD_PRIORITY));
4485 eError = RGXAcquireCCB(FWCommonContextGetClientCCB(psContext),
4487 (void **) &pui8CmdPtr,
4488 PDUMP_FLAGS_CONTINUOUS);
4489 if (eError != PVRSRV_OK)
4491 if(eError != PVRSRV_ERROR_RETRY)
4493 PVR_DPF((PVR_DBG_ERROR, "%s: Failed to acquire space for client CCB", __FUNCTION__));
4495 goto fail_ccbacquire;
4499 Write the command header and command
4501 psCmdHeader = (RGXFWIF_CCB_CMD_HEADER *) pui8CmdPtr;
4502 psCmdHeader->eCmdType = RGXFWIF_CCB_CMD_TYPE_PRIORITY;
4503 psCmdHeader->ui32CmdSize = RGX_CCB_FWALLOC_ALIGN(sizeof(RGXFWIF_CMD_PRIORITY));
4504 pui8CmdPtr += sizeof(*psCmdHeader);
4506 psCmd = (RGXFWIF_CMD_PRIORITY *) pui8CmdPtr;
4507 psCmd->ui32Priority = ui32Priority;
4508 pui8CmdPtr += sizeof(*psCmd);
4511 We should reserved space in the kernel CCB here and fill in the command
4513 This is so if there isn't space in the kernel CCB we can return with
4514 retry back to services client before we take any operations
4520 RGXReleaseCCB(FWCommonContextGetClientCCB(psContext),
4522 PDUMP_FLAGS_CONTINUOUS);
4524 /* Construct the priority command. */
4525 sPriorityCmd.eCmdType = RGXFWIF_KCCB_CMD_KICK;
4526 sPriorityCmd.uCmdData.sCmdKickData.psContext = FWCommonContextGetFWAddress(psContext);
4527 sPriorityCmd.uCmdData.sCmdKickData.ui32CWoffUpdate = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(psContext));
4528 sPriorityCmd.uCmdData.sCmdKickData.ui32NumCleanupCtl = 0;
4529 sPriorityCmd.uCmdData.sCmdKickData.sWorkloadDataFWAddress.ui32Addr = 0;
4530 sPriorityCmd.uCmdData.sCmdKickData.ui32WorkEstCmdHeaderOffset = 0;
4532 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
4534 eError = RGXScheduleCommand(psDevInfo,
4537 sizeof(sPriorityCmd),
4539 PDUMP_FLAGS_CONTINUOUS);
4540 if (eError != PVRSRV_ERROR_RETRY)
4544 OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
4545 } END_LOOP_UNTIL_TIMEOUT();
4547 if (eError != PVRSRV_OK)
4549 PVR_DPF((PVR_DBG_ERROR,"ContextSetPriority: Failed to submit set priority command with error (%u)", eError));
4555 PVR_ASSERT(eError != PVRSRV_OK);
4562 PVRSRV_ERROR RGXReadMETAAddr(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT32 ui32METAAddr, IMG_UINT32 *pui32Value)
4564 IMG_UINT8 *pui8RegBase = (IMG_UINT8*)psDevInfo->pvRegsBaseKM;
4565 IMG_UINT32 ui32Value;
4567 /* Wait for Slave Port to be Ready */
4568 if (PVRSRVPollForValueKM(
4569 (IMG_UINT32*) (pui8RegBase + RGX_CR_META_SP_MSLVCTRL1),
4570 RGX_CR_META_SP_MSLVCTRL1_READY_EN|RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN,
4571 RGX_CR_META_SP_MSLVCTRL1_READY_EN|RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN) != PVRSRV_OK)
4573 return PVRSRV_ERROR_TIMEOUT;
4576 /* Issue the Read */
4578 psDevInfo->pvRegsBaseKM,
4579 RGX_CR_META_SP_MSLVCTRL0,
4580 ui32METAAddr | RGX_CR_META_SP_MSLVCTRL0_RD_EN);
4582 /* Wait for Slave Port to be Ready: read complete */
4583 if (PVRSRVPollForValueKM(
4584 (IMG_UINT32*) (pui8RegBase + RGX_CR_META_SP_MSLVCTRL1),
4585 RGX_CR_META_SP_MSLVCTRL1_READY_EN|RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN,
4586 RGX_CR_META_SP_MSLVCTRL1_READY_EN|RGX_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN) != PVRSRV_OK)
4588 return PVRSRV_ERROR_TIMEOUT;
4591 /* Read the value */
4592 ui32Value = OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_META_SP_MSLVDATAX);
4594 *pui32Value = ui32Value;
4601 RGXUpdateHealthStatus
4603 PVRSRV_ERROR RGXUpdateHealthStatus(PVRSRV_DEVICE_NODE* psDevNode,
4604 IMG_BOOL bCheckAfterTimePassed)
4606 #if !defined(PVRSRV_GPUVIRT_GUESTDRV)
4607 PVRSRV_DATA* psPVRSRVData = PVRSRVGetPVRSRVData();
4608 PVRSRV_DEVICE_HEALTH_STATUS eNewStatus = PVRSRV_DEVICE_HEALTH_STATUS_OK;
4609 PVRSRV_DEVICE_HEALTH_REASON eNewReason = PVRSRV_DEVICE_HEALTH_REASON_NONE;
4610 PVRSRV_RGXDEV_INFO* psDevInfo;
4611 RGXFWIF_TRACEBUF* psRGXFWIfTraceBufCtl;
4612 RGXFWIF_CCB_CTL *psKCCBCtl;
4613 IMG_UINT32 ui32ThreadCount;
4614 IMG_BOOL bKCCBCmdsWaiting;
4616 PVR_ASSERT(psDevNode != NULL);
4617 psDevInfo = psDevNode->pvDevice;
4618 psRGXFWIfTraceBufCtl = psDevInfo->psRGXFWIfTraceBuf;
4620 /* If the firmware is not initialised, there is not much point continuing! */
4621 if (!psDevInfo->bFirmwareInitialised || psDevInfo->pvRegsBaseKM == NULL ||
4622 psDevInfo->psDeviceNode == NULL)
4627 /* If Rogue is not powered on, don't continue
4628 (there is a race condition where PVRSRVIsDevicePowered returns TRUE when the GPU is actually powering down.
4629 That's not a problem as this function does not touch the HW except for the RGXScheduleCommand function,
4630 which is already powerlock safe. The worst thing that could happen is that Rogue might power back up
4631 but the chances of that are very low */
4632 if (!PVRSRVIsDevicePowered(psDevNode))
4637 /* If this is a quick update, then include the last current value... */
4638 if (!bCheckAfterTimePassed)
4640 eNewStatus = OSAtomicRead(&psDevNode->eHealthStatus);
4641 eNewReason = OSAtomicRead(&psDevNode->eHealthReason);
4645 Firmware thread checks...
4647 for (ui32ThreadCount = 0; ui32ThreadCount < RGXFW_THREAD_NUM; ui32ThreadCount++)
4649 if (psRGXFWIfTraceBufCtl != NULL)
4651 IMG_CHAR* pszTraceAssertInfo = psRGXFWIfTraceBufCtl->sTraceBuf[ui32ThreadCount].sAssertBuf.szInfo;
4654 Check if the FW has hit an assert...
4656 if (*pszTraceAssertInfo != '\0')
4658 PVR_DPF((PVR_DBG_WARNING, "RGXGetDeviceHealthStatus: Firmware thread %d has asserted: %s (%s:%d)",
4659 ui32ThreadCount, pszTraceAssertInfo,
4660 psRGXFWIfTraceBufCtl->sTraceBuf[ui32ThreadCount].sAssertBuf.szPath,
4661 psRGXFWIfTraceBufCtl->sTraceBuf[ui32ThreadCount].sAssertBuf.ui32LineNum));
4662 eNewStatus = PVRSRV_DEVICE_HEALTH_STATUS_DEAD;
4663 eNewReason = PVRSRV_DEVICE_HEALTH_REASON_ASSERTED;
4664 goto _RGXUpdateHealthStatus_Exit;
4668 Check the threads to see if they are in the same poll locations as last time...
4670 if (bCheckAfterTimePassed)
4672 if (psRGXFWIfTraceBufCtl->aui32CrPollAddr[ui32ThreadCount] != 0 &&
4673 psRGXFWIfTraceBufCtl->aui32CrPollAddr[ui32ThreadCount] == psDevInfo->aui32CrLastPollAddr[ui32ThreadCount])
4675 PVR_DPF((PVR_DBG_WARNING, "RGXGetDeviceHealthStatus: Firmware stuck on CR poll: T%u polling %s (reg:0x%08X mask:0x%08X)",
4677 ((psRGXFWIfTraceBufCtl->aui32CrPollAddr[ui32ThreadCount] & RGXFW_POLL_TYPE_SET)?("set"):("unset")),
4678 psRGXFWIfTraceBufCtl->aui32CrPollAddr[ui32ThreadCount] & ~RGXFW_POLL_TYPE_SET,
4679 psRGXFWIfTraceBufCtl->aui32CrPollMask[ui32ThreadCount]));
4680 eNewStatus = PVRSRV_DEVICE_HEALTH_STATUS_NOT_RESPONDING;
4681 eNewReason = PVRSRV_DEVICE_HEALTH_REASON_POLL_FAILING;
4682 goto _RGXUpdateHealthStatus_Exit;
4684 psDevInfo->aui32CrLastPollAddr[ui32ThreadCount] = psRGXFWIfTraceBufCtl->aui32CrPollAddr[ui32ThreadCount];
4690 Event Object Timeouts check...
4692 if (!bCheckAfterTimePassed)
4694 if (psDevInfo->ui32GEOTimeoutsLastTime > 1 && psPVRSRVData->ui32GEOConsecutiveTimeouts > psDevInfo->ui32GEOTimeoutsLastTime)
4696 PVR_DPF((PVR_DBG_WARNING, "RGXGetDeviceHealthStatus: Global Event Object Timeouts have risen (from %d to %d)",
4697 psDevInfo->ui32GEOTimeoutsLastTime, psPVRSRVData->ui32GEOConsecutiveTimeouts));
4698 eNewStatus = PVRSRV_DEVICE_HEALTH_STATUS_NOT_RESPONDING;
4699 eNewReason = PVRSRV_DEVICE_HEALTH_REASON_TIMEOUTS;
4701 psDevInfo->ui32GEOTimeoutsLastTime = psPVRSRVData->ui32GEOConsecutiveTimeouts;
4705 Check the Kernel CCB pointer is valid. If any commands were waiting last time, then check
4706 that some have executed since then.
4708 bKCCBCmdsWaiting = IMG_FALSE;
4709 psKCCBCtl = psDevInfo->psKernelCCBCtl;
4711 if (psKCCBCtl != NULL)
4713 if (psKCCBCtl->ui32ReadOffset > psKCCBCtl->ui32WrapMask ||
4714 psKCCBCtl->ui32WriteOffset > psKCCBCtl->ui32WrapMask)
4716 PVR_DPF((PVR_DBG_WARNING, "RGXGetDeviceHealthStatus: KCCB has invalid offset (ROFF=%d WOFF=%d)",
4717 psKCCBCtl->ui32ReadOffset, psKCCBCtl->ui32WriteOffset));
4718 eNewStatus = PVRSRV_DEVICE_HEALTH_STATUS_DEAD;
4719 eNewReason = PVRSRV_DEVICE_HEALTH_REASON_QUEUE_CORRUPT;
4722 if (psKCCBCtl->ui32ReadOffset != psKCCBCtl->ui32WriteOffset)
4724 bKCCBCmdsWaiting = IMG_TRUE;
4728 if (bCheckAfterTimePassed && psDevInfo->psRGXFWIfTraceBuf != NULL)
4730 IMG_UINT32 ui32KCCBCmdsExecuted = psDevInfo->psRGXFWIfTraceBuf->ui32KCCBCmdsExecuted;
4732 if (psDevInfo->ui32KCCBCmdsExecutedLastTime == ui32KCCBCmdsExecuted)
4735 If something was waiting last time then the Firmware has stopped processing commands.
4737 if (psDevInfo->bKCCBCmdsWaitingLastTime)
4739 PVR_DPF((PVR_DBG_WARNING, "RGXGetDeviceHealthStatus: No KCCB commands executed since check!"));
4740 eNewStatus = PVRSRV_DEVICE_HEALTH_STATUS_NOT_RESPONDING;
4741 eNewReason = PVRSRV_DEVICE_HEALTH_REASON_QUEUE_STALLED;
4745 If no commands are currently pending and nothing happened since the last poll, then
4746 schedule a dummy command to ping the firmware so we know it is alive and processing.
4748 if (!bKCCBCmdsWaiting)
4750 RGXFWIF_KCCB_CMD sCmpKCCBCmd;
4751 PVRSRV_ERROR eError;
4753 sCmpKCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_HEALTH_CHECK;
4755 eError = RGXScheduleCommand(psDevNode->pvDevice,
4758 sizeof(sCmpKCCBCmd),
4761 if (eError != PVRSRV_OK)
4763 PVR_DPF((PVR_DBG_WARNING, "RGXGetDeviceHealthStatus: Cannot schedule Health Check command! (0x%x)", eError));
4767 bKCCBCmdsWaiting = IMG_TRUE;
4772 psDevInfo->bKCCBCmdsWaitingLastTime = bKCCBCmdsWaiting;
4773 psDevInfo->ui32KCCBCmdsExecutedLastTime = ui32KCCBCmdsExecuted;
4776 if (bCheckAfterTimePassed && (PVRSRV_DEVICE_HEALTH_STATUS_OK==eNewStatus))
4778 /* Attempt to detect and deal with any stalled client contexts.
4779 * Currently, ui32StalledClientMask is not a reliable method of detecting a stalled
4780 * application as the app could just be busy with a long running task,
4781 * or a lots of smaller workloads. Also the definition of stalled is
4782 * effectively subject to the timer frequency calling this function
4783 * (which is a platform config value with no guarantee it is correctly tuned).
4786 IMG_UINT32 ui32StalledClientMask = 0;
4788 ui32StalledClientMask |= CheckForStalledClientTransferCtxt(psDevInfo);
4790 ui32StalledClientMask |= CheckForStalledClientRenderCtxt(psDevInfo);
4792 #if !defined(UNDER_WDDM)
4793 if(psDevInfo->sDevFeatureCfg.ui64Features & RGX_FEATURE_COMPUTE_BIT_MASK)
4795 ui32StalledClientMask |= CheckForStalledClientComputeCtxt(psDevInfo);
4799 if (psDevInfo->sDevFeatureCfg.ui64Features & RGX_FEATURE_RAY_TRACING_BIT_MASK)
4801 ui32StalledClientMask |= CheckForStalledClientRayCtxt(psDevInfo);
4804 /* If at least one DM stalled bit is different than before */
4805 if (psDevInfo->ui32StalledClientMask ^ ui32StalledClientMask)
4807 /* Print all the stalled DMs */
4808 PVR_LOG(("RGXGetDeviceHealthStatus: Possible stalled client contexts detected: %s%s%s%s%s%s%s%s%s",
4809 RGX_STRINGIFY_KICK_TYPE_DM_IF_SET(ui32StalledClientMask, RGX_KICK_TYPE_DM_GP),
4810 RGX_STRINGIFY_KICK_TYPE_DM_IF_SET(ui32StalledClientMask, RGX_KICK_TYPE_DM_TDM_2D),
4811 RGX_STRINGIFY_KICK_TYPE_DM_IF_SET(ui32StalledClientMask, RGX_KICK_TYPE_DM_TA),
4812 RGX_STRINGIFY_KICK_TYPE_DM_IF_SET(ui32StalledClientMask, RGX_KICK_TYPE_DM_3D),
4813 RGX_STRINGIFY_KICK_TYPE_DM_IF_SET(ui32StalledClientMask, RGX_KICK_TYPE_DM_CDM),
4814 RGX_STRINGIFY_KICK_TYPE_DM_IF_SET(ui32StalledClientMask, RGX_KICK_TYPE_DM_RTU),
4815 RGX_STRINGIFY_KICK_TYPE_DM_IF_SET(ui32StalledClientMask, RGX_KICK_TYPE_DM_SHG),
4816 RGX_STRINGIFY_KICK_TYPE_DM_IF_SET(ui32StalledClientMask, RGX_KICK_TYPE_DM_TQ2D),
4817 RGX_STRINGIFY_KICK_TYPE_DM_IF_SET(ui32StalledClientMask, RGX_KICK_TYPE_DM_TQ3D)));
4819 psDevInfo->ui32StalledClientMask = ui32StalledClientMask;
4823 Finished, save the new status...
4825 _RGXUpdateHealthStatus_Exit:
4826 OSAtomicWrite(&psDevNode->eHealthStatus, eNewStatus);
4827 OSAtomicWrite(&psDevNode->eHealthReason, eNewReason);
4830 * Attempt to service the HWPerf buffer to regularly transport idle/periodic
4831 * packets to host buffer.
4833 if (psDevNode->pfnServiceHWPerf != NULL)
4835 PVRSRV_ERROR eError = psDevNode->pfnServiceHWPerf(psDevNode);
4836 if (eError != PVRSRV_OK)
4838 PVR_DPF((PVR_DBG_WARNING, "DevicesWatchdogThread: "
4839 "Error occurred when servicing HWPerf buffer (%d)",
4846 } /* RGXUpdateHealthStatus */
4848 PVRSRV_ERROR CheckStalledClientCommonContext(RGX_SERVER_COMMON_CONTEXT *psCurrentServerCommonContext, RGX_KICK_TYPE_DM eKickTypeDM)
4850 RGX_CLIENT_CCB *psCurrentClientCCB = psCurrentServerCommonContext->psClientCCB;
4852 return CheckForStalledCCB(psCurrentClientCCB, eKickTypeDM);
4855 void DumpStalledFWCommonContext(RGX_SERVER_COMMON_CONTEXT *psCurrentServerCommonContext,
4856 DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
4857 void *pvDumpDebugFile)
4859 RGX_CLIENT_CCB *psCurrentClientCCB = psCurrentServerCommonContext->psClientCCB;
4860 PRGXFWIF_FWCOMMONCONTEXT sFWCommonContext = psCurrentServerCommonContext->sFWCommonContextFWAddr;
4862 #if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) || defined(PVRSRV_ENABLE_FULL_CCB_DUMP)
4863 DumpCCB(psCurrentServerCommonContext->psDevInfo, sFWCommonContext,
4864 psCurrentClientCCB, pfnDumpDebugPrintf, pvDumpDebugFile);
4866 DumpStalledCCBCommand(sFWCommonContext, psCurrentClientCCB, pfnDumpDebugPrintf, pvDumpDebugFile);
4870 void AttachKickResourcesCleanupCtls(PRGXFWIF_CLEANUP_CTL *apsCleanupCtl,
4871 IMG_UINT32 *pui32NumCleanupCtl,
4874 RGX_RTDATA_CLEANUP_DATA *psRTDataCleanup,
4875 RGX_ZSBUFFER_DATA *psZBuffer,
4876 RGX_ZSBUFFER_DATA *psSBuffer)
4878 PRGXFWIF_CLEANUP_CTL *psCleanupCtlWrite = apsCleanupCtl;
4880 PVR_ASSERT((eDM == RGXFWIF_DM_TA) || (eDM == RGXFWIF_DM_3D));
4884 if(eDM == RGXFWIF_DM_TA)
4888 PRGXFWIF_CLEANUP_CTL psCleanupCtl;
4890 RGXSetFirmwareAddress(&psCleanupCtl, psRTDataCleanup->psFWHWRTDataMemDesc,
4891 offsetof(RGXFWIF_HWRTDATA, sTACleanupState),
4892 RFW_FWADDR_NOREF_FLAG);
4894 *(psCleanupCtlWrite++) = psCleanupCtl;
4901 PRGXFWIF_CLEANUP_CTL psCleanupCtl;
4903 RGXSetFirmwareAddress(&psCleanupCtl, psRTDataCleanup->psFWHWRTDataMemDesc,
4904 offsetof(RGXFWIF_HWRTDATA, s3DCleanupState),
4905 RFW_FWADDR_NOREF_FLAG);
4907 *(psCleanupCtlWrite++) = psCleanupCtl;
4912 (psCleanupCtlWrite++)->ui32Addr = psZBuffer->sZSBufferFWDevVAddr.ui32Addr +
4913 offsetof(RGXFWIF_FWZSBUFFER, sCleanupState);
4918 (psCleanupCtlWrite++)->ui32Addr = psSBuffer->sZSBufferFWDevVAddr.ui32Addr +
4919 offsetof(RGXFWIF_FWZSBUFFER, sCleanupState);
4924 *pui32NumCleanupCtl = psCleanupCtlWrite - apsCleanupCtl;
4926 PVR_ASSERT(*pui32NumCleanupCtl <= RGXFWIF_KCCB_CMD_KICK_DATA_MAX_NUM_CLEANUP_CTLS);
4929 PVRSRV_ERROR RGXResetHWRLogs(PVRSRV_DEVICE_NODE *psDevNode)
4931 #if defined(PVRSRV_GPUVIRT_GUESTDRV)
4932 /* Guest drivers do not support HW reset */
4933 PVR_UNREFERENCED_PARAMETER(psDevNode);
4935 PVRSRV_RGXDEV_INFO *psDevInfo;
4936 RGXFWIF_HWRINFOBUF *psHWRInfoBuf;
4937 RGXFWIF_TRACEBUF *psRGXFWIfTraceBufCtl;
4940 if(psDevNode->pvDevice == NULL)
4942 return PVRSRV_ERROR_INVALID_DEVINFO;
4944 psDevInfo = psDevNode->pvDevice;
4946 psHWRInfoBuf = psDevInfo->psRGXFWIfHWRInfoBuf;
4947 psRGXFWIfTraceBufCtl = psDevInfo->psRGXFWIfTraceBuf;
4949 for(i = 0 ; i < psDevInfo->sDevFeatureCfg.ui32MAXDMCount ; i++)
4951 /* Reset the HWR numbers */
4952 psRGXFWIfTraceBufCtl->aui32HwrDmLockedUpCount[i] = 0;
4953 psRGXFWIfTraceBufCtl->aui32HwrDmFalseDetectCount[i] = 0;
4954 psRGXFWIfTraceBufCtl->aui32HwrDmRecoveredCount[i] = 0;
4955 psRGXFWIfTraceBufCtl->aui32HwrDmOverranCount[i] = 0;
4958 for(i = 0 ; i < RGXFWIF_HWINFO_MAX ; i++)
4960 psHWRInfoBuf->sHWRInfo[i].ui32HWRNumber = 0;
4963 for(i = 0 ; i < RGXFW_THREAD_NUM ; i++)
4965 psHWRInfoBuf->ui32FirstCrPollAddr[i] = 0;
4966 psHWRInfoBuf->ui32FirstCrPollMask[i] = 0;
4969 psHWRInfoBuf->ui32WriteIndex = 0;
4970 psHWRInfoBuf->ui32DDReqCount = 0;
4975 PVRSRV_ERROR RGXGetPhyAddr(PMR *psPMR,
4976 IMG_DEV_PHYADDR *psPhyAddr,
4977 IMG_UINT32 ui32LogicalOffset,
4978 IMG_UINT32 ui32Log2PageSize,
4979 IMG_UINT32 ui32NumOfPages,
4983 PVRSRV_ERROR eError;
4985 eError = PMRLockSysPhysAddresses(psPMR);
4986 if (eError != PVRSRV_OK)
4988 PVR_DPF((PVR_DBG_ERROR,"RGXGetPhyAddr: PMRLockSysPhysAddresses failed (%u)",
4993 eError = PMR_DevPhysAddr(psPMR,
5000 if (eError != PVRSRV_OK)
5002 PVR_DPF((PVR_DBG_ERROR,"RGXGetPhyAddr: PMR_DevPhysAddr failed (%u)",
5008 eError = PMRUnlockSysPhysAddresses(psPMR);
5009 if (eError != PVRSRV_OK)
5011 PVR_DPF((PVR_DBG_ERROR,"RGXGetPhyAddr: PMRUnLockSysPhysAddresses failed (%u)",
5020 PVRSRV_ERROR RGXPdumpDrainKCCB(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_UINT32 ui32WriteOffset)
5022 RGXFWIF_CCB_CTL *psKCCBCtl = psDevInfo->psKernelCCBCtl;
5023 PVRSRV_ERROR eError = PVRSRV_OK;
5025 if (psDevInfo->bDumpedKCCBCtlAlready)
5027 /* exiting capture range */
5028 psDevInfo->bDumpedKCCBCtlAlready = IMG_FALSE;
5030 /* make sure previous cmd is drained in pdump in case we will 'jump' over some future cmds */
5031 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS | PDUMP_FLAGS_POWER,
5032 "kCCB(%p): Draining rgxfw_roff (0x%x) == woff (0x%x)",
5036 eError = DevmemPDumpDevmemPol32(psDevInfo->psKernelCCBCtlMemDesc,
5037 offsetof(RGXFWIF_CCB_CTL, ui32ReadOffset),
5040 PDUMP_POLL_OPERATOR_EQUAL,
5041 PDUMP_FLAGS_CONTINUOUS | PDUMP_FLAGS_POWER);
5043 if (eError != PVRSRV_OK)
5045 PVR_DPF((PVR_DBG_ERROR, "RGXPdumpDrainKCCB: problem pdumping POL for kCCBCtl (%d)", eError));
5055 *******************************************************************************
5057 @Function RGXClientConnectCompatCheck_ClientAgainstFW
5061 Check compatibility of client and firmware (build options)
5062 at the connection time.
5064 @Input psDeviceNode - device node
5065 @Input ui32ClientBuildOptions - build options for the client
5067 @Return PVRSRV_ERROR - depending on mismatch found
5069 ******************************************************************************/
5070 PVRSRV_ERROR IMG_CALLCONV RGXClientConnectCompatCheck_ClientAgainstFW(PVRSRV_DEVICE_NODE * psDeviceNode, IMG_UINT32 ui32ClientBuildOptions)
5072 PVRSRV_ERROR eError;
5073 #if defined(PVRSRV_GPUVIRT_GUESTDRV)
5076 #if !defined(NO_HARDWARE) || defined(PDUMP)
5077 PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
5079 #if !defined(NO_HARDWARE)
5080 RGXFWIF_INIT *psRGXFWInit = NULL;
5081 IMG_UINT32 ui32BuildOptionsMismatch;
5082 IMG_UINT32 ui32BuildOptionsFW;
5084 eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWIfInitMemDesc,
5085 (void **)&psRGXFWInit);
5086 if (eError != PVRSRV_OK)
5088 PVR_DPF((PVR_DBG_ERROR,"%s: Failed to acquire kernel fw compatibility check info (%u)",
5089 __FUNCTION__, eError));
5093 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
5095 if(*((volatile IMG_BOOL *)&psRGXFWInit->sRGXCompChecks.bUpdated))
5097 /* No need to wait if the FW has already updated the values */
5100 OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
5101 } END_LOOP_UNTIL_TIMEOUT();
5105 PDUMPCOMMENT("Compatibility check: client and FW build options");
5106 eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfInitMemDesc,
5107 offsetof(RGXFWIF_INIT, sRGXCompChecks) +
5108 offsetof(RGXFWIF_COMPCHECKS, ui32BuildOptions),
5109 ui32ClientBuildOptions,
5111 PDUMP_POLL_OPERATOR_EQUAL,
5112 PDUMP_FLAGS_CONTINUOUS);
5113 if (eError != PVRSRV_OK)
5115 PVR_DPF((PVR_DBG_ERROR, "RGXDevInitCompatCheck: problem pdumping POL for psRGXFWIfInitMemDesc (%d)", eError));
5120 #if !defined(NO_HARDWARE)
5121 if (psRGXFWInit == NULL)
5123 PVR_DPF((PVR_DBG_ERROR,"%s: Failed to acquire kernel fw compatibility check info, psRGXFWInit is NULL", __FUNCTION__));
5124 eError = PVRSRV_ERROR_INVALID_PARAMS;
5128 ui32BuildOptionsFW = psRGXFWInit->sRGXCompChecks.ui32BuildOptions;
5129 ui32BuildOptionsMismatch = ui32ClientBuildOptions ^ ui32BuildOptionsFW;
5131 if (ui32BuildOptionsMismatch != 0)
5133 if ( (ui32ClientBuildOptions & ui32BuildOptionsMismatch) != 0)
5135 PVR_LOG(("(FAIL) RGXDevInitCompatCheck: Mismatch in Firmware and client build options; "
5136 "extra options present in client: (0x%x). Please check rgx_options.h",
5137 ui32ClientBuildOptions & ui32BuildOptionsMismatch ));
5140 if ( (ui32BuildOptionsFW & ui32BuildOptionsMismatch) != 0)
5142 PVR_LOG(("(FAIL) RGXDevInitCompatCheck: Mismatch in Firmware and client build options; "
5143 "extra options present in Firmware: (0x%x). Please check rgx_options.h",
5144 ui32BuildOptionsFW & ui32BuildOptionsMismatch ));
5146 eError = PVRSRV_ERROR_BUILD_OPTIONS_MISMATCH;
5151 PVR_DPF((PVR_DBG_MESSAGE, "RGXDevInitCompatCheck: Firmware and client build options match. [ OK ]"));
5156 #if !defined(NO_HARDWARE)
5158 DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfInitMemDesc);
5165 /******************************************************************************
5166 End of file (rgxfwutils.c)
5167 ******************************************************************************/