1 /*************************************************************************/ /*!
3 @Title Device specific power routines
4 @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
5 @Description Device specific functions
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 "rgx_fwif_km.h"
50 #include "rgxfwutils.h"
52 #include "rgxdefs_km.h"
54 #include "pvr_debug.h"
58 #include "devicemem_pdump.h"
59 #include "rgxapi_km.h"
60 #include "rgxtimecorr.h"
62 #include "process_stats.h"
64 extern IMG_UINT32 g_ui32HostSampleIRQCount;
66 #if ! defined(FIX_HW_BRN_37453)
68 *******************************************************************************
70 @Function RGXEnableClocks
72 @Description Enable RGX Clocks
74 @Input psDevInfo - device info structure
78 ******************************************************************************/
79 static IMG_VOID RGXEnableClocks(PVRSRV_RGXDEV_INFO *psDevInfo)
81 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGX clock: use default (automatic clock gating)");
85 #include "pvr_dvfs_device.h"
90 *******************************************************************************
94 @Description Initialise RGX SLC
96 @Input psDevInfo - device info structure
100 ******************************************************************************/
101 #if !defined(RGX_FEATURE_S7_CACHE_HIERARCHY)
103 #define RGX_INIT_SLC _RGXInitSLC
105 static IMG_VOID _RGXInitSLC(PVRSRV_RGXDEV_INFO *psDevInfo)
108 IMG_UINT32 ui32RegVal;
110 #if defined(FIX_HW_BRN_36492)
111 /* Because the WA for this BRN forbids using SLC reset, need to inval it instead */
112 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "Invalidate the SLC");
113 OSWriteHWReg32(psDevInfo->pvRegsBaseKM,
114 RGX_CR_SLC_CTRL_FLUSH_INVAL, RGX_CR_SLC_CTRL_FLUSH_INVAL_ALL_EN);
115 PDUMPREG32(RGX_PDUMPREG_NAME,
116 RGX_CR_SLC_CTRL_FLUSH_INVAL, RGX_CR_SLC_CTRL_FLUSH_INVAL_ALL_EN,
117 PDUMP_FLAGS_CONTINUOUS);
119 /* poll for completion */
120 PVRSRVPollForValueKM((IMG_UINT32 *)((IMG_UINT8*)psDevInfo->pvRegsBaseKM + RGX_CR_SLC_STATUS0),
122 RGX_CR_SLC_STATUS0_INVAL_PENDING_EN);
124 PDUMPREGPOL(RGX_PDUMPREG_NAME,
127 RGX_CR_SLC_STATUS0_INVAL_PENDING_EN,
128 PDUMP_FLAGS_CONTINUOUS,
129 PDUMP_POLL_OPERATOR_EQUAL);
132 if (!PVRSRVSystemSnoopingOfCPUCache() && !PVRSRVSystemSnoopingOfDeviceCache())
134 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "System has NO cache snooping");
138 if (PVRSRVSystemSnoopingOfCPUCache())
140 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "System has CPU cache snooping");
142 if (PVRSRVSystemSnoopingOfDeviceCache())
144 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "System has DEVICE cache snooping");
148 #if (RGX_FEATURE_SLC_SIZE_IN_BYTES < (128*1024))
152 ui32Reg = RGX_CR_SLC_CTRL_BYPASS;
154 /* Bypass SLC for textures if the SLC size is less than 128kB */
155 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "Bypass SLC for TPU");
156 ui32RegVal = RGX_CR_SLC_CTRL_BYPASS_REQ_TPU_EN;
158 OSWriteHWReg32(psDevInfo->pvRegsBaseKM, ui32Reg, ui32RegVal);
159 PDUMPREG32(RGX_PDUMPREG_NAME, ui32Reg, ui32RegVal, PDUMP_FLAGS_CONTINUOUS);
165 ui32Reg = RGX_CR_SLC_CTRL_MISC;
166 ui32RegVal = RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_PVR_HASH1;
168 /* Bypass burst combiner if SLC line size is smaller than 1024 bits */
169 #if (RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS < 1024)
170 ui32RegVal |= RGX_CR_SLC_CTRL_MISC_BYPASS_BURST_COMBINER_EN;
172 OSWriteHWReg32(psDevInfo->pvRegsBaseKM, ui32Reg, ui32RegVal);
173 PDUMPREG32(RGX_PDUMPREG_NAME, ui32Reg, ui32RegVal, PDUMP_FLAGS_CONTINUOUS);
176 #endif /* RGX_FEATURE_S7_CACHE_HIERARCHY */
180 *******************************************************************************
182 @Function RGXInitSLC3
184 @Description Initialise RGX SLC3
186 @Input psDevInfo - device info structure
190 ******************************************************************************/
191 #if defined(RGX_FEATURE_S7_CACHE_HIERARCHY)
193 #define RGX_INIT_SLC _RGXInitSLC3
195 static IMG_VOID _RGXInitSLC3(PVRSRV_RGXDEV_INFO *psDevInfo)
198 IMG_UINT32 ui32RegVal;
201 #if defined(HW_ERN_51468)
205 ui32Reg = RGX_CR_SLC3_CTRL_MISC;
206 ui32RegVal = RGX_CR_SLC3_CTRL_MISC_ADDR_DECODE_MODE_WEAVED_HASH;
207 OSWriteHWReg32(psDevInfo->pvRegsBaseKM, ui32Reg, ui32RegVal);
208 PDUMPREG32(RGX_PDUMPREG_NAME, ui32Reg, ui32RegVal, PDUMP_FLAGS_CONTINUOUS);
215 ui32Reg = RGX_CR_SLC3_CTRL_MISC;
216 ui32RegVal = RGX_CR_SLC3_CTRL_MISC_ADDR_DECODE_MODE_SCRAMBLE_PVR_HASH;
217 OSWriteHWReg32(psDevInfo->pvRegsBaseKM, ui32Reg, ui32RegVal);
218 PDUMPREG32(RGX_PDUMPREG_NAME, ui32Reg, ui32RegVal, PDUMP_FLAGS_CONTINUOUS);
225 IMG_UINT32 aui32ScrambleRegs[] = {
226 RGX_CR_SLC3_SCRAMBLE,
227 RGX_CR_SLC3_SCRAMBLE2,
228 RGX_CR_SLC3_SCRAMBLE3,
229 RGX_CR_SLC3_SCRAMBLE4};
231 IMG_UINT64 aui64ScrambleValues[] = {
232 #if (RGX_FEATURE_SLC_BANKS == 2)
233 IMG_UINT64_C(0x6965a99a55696a6a),
234 IMG_UINT64_C(0x6aa9aa66959aaa9a),
235 IMG_UINT64_C(0x9a5665965a99a566),
236 IMG_UINT64_C(0x5aa69596aa66669a)
237 #elif (RGX_FEATURE_SLC_BANKS == 4)
238 IMG_UINT64_C(0xc6788d722dd29ce4),
239 IMG_UINT64_C(0x7272e4e11b279372),
240 IMG_UINT64_C(0x87d872d26c6c4be1),
241 IMG_UINT64_C(0xe1b4878d4b36e478)
242 #elif (RGX_FEATURE_SLC_BANKS == 8)
243 IMG_UINT64_C(0x859d6569e8fac688),
244 IMG_UINT64_C(0xf285e1eae4299d33),
245 IMG_UINT64_C(0x1e1af2be3c0aa447)
250 i < sizeof(aui64ScrambleValues)/sizeof(IMG_UINT64);
253 IMG_UINT32 ui32Reg = aui32ScrambleRegs[i];
254 IMG_UINT64 ui64Value = aui64ScrambleValues[i];
256 OSWriteHWReg64(psDevInfo->pvRegsBaseKM, ui32Reg, ui64Value);
257 PDUMPREG64(RGX_PDUMPREG_NAME, ui32Reg, ui64Value, PDUMP_FLAGS_CONTINUOUS);
262 #if defined(HW_ERN_45914)
263 /* Disable the forced SLC coherency which the hardware enables for compatibility with older pdumps */
264 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: disable forced SLC coherency");
265 OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_GARTEN_SLC, 0);
266 PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_GARTEN_SLC, 0, PDUMP_FLAGS_CONTINUOUS);
274 *******************************************************************************
278 @Description Initialise RGX BIF
280 @Input psDevInfo - device info structure
284 ******************************************************************************/
285 static IMG_VOID RGXInitBIF(PVRSRV_RGXDEV_INFO *psDevInfo)
288 IMG_DEV_PHYADDR sPCAddr;
291 Acquire the address of the Kernel Page Catalogue.
293 eError = MMU_AcquireBaseAddr(psDevInfo->psKernelMMUCtx, &sPCAddr);
294 PVR_ASSERT(eError == PVRSRV_OK);
296 /* Sanity check Cat-Base address */
297 PVR_ASSERT((((sPCAddr.uiAddr
298 >> psDevInfo->ui32KernelCatBaseAlignShift)
299 << psDevInfo->ui32KernelCatBaseShift)
300 & ~psDevInfo->ui64KernelCatBaseMask) == 0x0UL);
303 Write the kernel catalogue base.
305 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGX firmware MMU Page Catalogue");
307 if (psDevInfo->ui32KernelCatBaseIdReg != -1)
309 /* Set the mapping index */
310 OSWriteHWReg32(psDevInfo->pvRegsBaseKM,
311 psDevInfo->ui32KernelCatBaseIdReg,
312 psDevInfo->ui32KernelCatBaseId);
314 /* pdump mapping context */
315 PDUMPREG32(RGX_PDUMPREG_NAME,
316 psDevInfo->ui32KernelCatBaseIdReg,
317 psDevInfo->ui32KernelCatBaseId,
318 PDUMP_FLAGS_CONTINUOUS);
321 if (psDevInfo->ui32KernelCatBaseWordSize == 8)
323 /* Write the cat-base address */
324 OSWriteHWReg64(psDevInfo->pvRegsBaseKM,
325 psDevInfo->ui32KernelCatBaseReg,
327 >> psDevInfo->ui32KernelCatBaseAlignShift)
328 << psDevInfo->ui32KernelCatBaseShift)
329 & psDevInfo->ui64KernelCatBaseMask);
333 /* Write the cat-base address */
334 OSWriteHWReg32(psDevInfo->pvRegsBaseKM,
335 psDevInfo->ui32KernelCatBaseReg,
336 (IMG_UINT32)(((sPCAddr.uiAddr
337 >> psDevInfo->ui32KernelCatBaseAlignShift)
338 << psDevInfo->ui32KernelCatBaseShift)
339 & psDevInfo->ui64KernelCatBaseMask));
342 /* pdump catbase address */
343 MMU_PDumpWritePageCatBase(psDevInfo->psKernelMMUCtx,
345 psDevInfo->ui32KernelCatBaseReg,
346 psDevInfo->ui32KernelCatBaseWordSize,
347 psDevInfo->ui32KernelCatBaseAlignShift,
348 psDevInfo->ui32KernelCatBaseShift,
349 PDUMP_FLAGS_CONTINUOUS);
354 #if defined(SUPPORT_TRUSTED_DEVICE)
355 #if defined(TRUSTED_DEVICE_DEFAULT_ENABLED)
356 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXInitBIF: Trusted Device enabled");
357 OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_TRUST, RGX_CR_BIF_TRUST_ENABLE_EN);
358 PDUMPREG32(RGX_PDUMPREG_NAME, RGX_CR_BIF_TRUST, RGX_CR_BIF_TRUST_ENABLE_EN, PDUMP_FLAGS_CONTINUOUS);
359 OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_SYS_BUS_SECURE, RGX_CR_SYS_BUS_SECURE_ENABLE_EN);
360 PDUMPREG32(RGX_PDUMPREG_NAME, RGX_CR_SYS_BUS_SECURE, RGX_CR_SYS_BUS_SECURE_ENABLE_EN, PDUMP_FLAGS_CONTINUOUS);
361 #else /* ! defined(TRUSTED_DEVICE_DEFAULT_ENABLED) */
362 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXInitBIF: Trusted Device disabled");
363 OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_TRUST, 0);
364 PDUMPREG32(RGX_PDUMPREG_NAME, RGX_CR_BIF_TRUST, 0, PDUMP_FLAGS_CONTINUOUS);
365 OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_SYS_BUS_SECURE, 0);
366 PDUMPREG32(RGX_PDUMPREG_NAME, RGX_CR_SYS_BUS_SECURE, 0, PDUMP_FLAGS_CONTINUOUS);
367 #endif /* TRUSTED_DEVICE_DEFAULT_ENABLED */
372 #if defined(RGX_FEATURE_AXI_ACELITE)
374 *******************************************************************************
376 @Function RGXAXIACELiteInit
378 @Description Initialise AXI-ACE Lite interface
380 @Input psDevInfo - device info structure
384 ******************************************************************************/
385 static IMG_VOID RGXAXIACELiteInit(PVRSRV_RGXDEV_INFO *psDevInfo)
387 IMG_UINT32 ui32RegAddr;
388 IMG_UINT64 ui64RegVal;
390 ui32RegAddr = RGX_CR_AXI_ACE_LITE_CONFIGURATION;
392 /* Setup AXI-ACE config. Set everything to outer cache */
393 ui64RegVal = (3U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWDOMAIN_NON_SNOOPING_SHIFT) |
394 (3U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_NON_SNOOPING_SHIFT) |
395 (2U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_CACHE_MAINTENANCE_SHIFT) |
396 (2U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWDOMAIN_COHERENT_SHIFT) |
397 (2U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_COHERENT_SHIFT) |
398 (((IMG_UINT64) 1) << RGX_CR_AXI_ACE_LITE_CONFIGURATION_DISABLE_COHERENT_WRITELINEUNIQUE_SHIFT) |
399 (2U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_AWCACHE_COHERENT_SHIFT) |
400 (2U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARCACHE_COHERENT_SHIFT) |
401 (2U << RGX_CR_AXI_ACE_LITE_CONFIGURATION_ARCACHE_CACHE_MAINTENANCE_SHIFT);
403 OSWriteHWReg64(psDevInfo->pvRegsBaseKM,
406 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "Init AXI-ACE interface");
407 PDUMPREG64(RGX_PDUMPREG_NAME, ui32RegAddr, ui64RegVal, PDUMP_FLAGS_CONTINUOUS);
413 *******************************************************************************
419 (client invoked) chip-reset and initialisation
421 @Input psDevInfo - device info structure
425 ******************************************************************************/
426 static PVRSRV_ERROR RGXStart(PVRSRV_RGXDEV_INFO *psDevInfo, PVRSRV_DEVICE_CONFIG *psDevConfig)
428 PVRSRV_ERROR eError = PVRSRV_OK;
429 RGXFWIF_INIT *psRGXFWInit;
431 #if defined(FIX_HW_BRN_37453)
432 /* Force all clocks on*/
433 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: force all clocks on");
434 OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_CLK_CTRL, RGX_CR_CLK_CTRL_ALL_ON);
435 PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_CLK_CTRL, RGX_CR_CLK_CTRL_ALL_ON, PDUMP_FLAGS_CONTINUOUS);
438 #if defined(SUPPORT_SHARED_SLC) && !defined(FIX_HW_BRN_36492)
439 /* When the SLC is shared, the SLC reset is performed by the System layer when calling
440 * RGXInitSLC (before any device uses it), therefore mask out the SLC bit to avoid
441 * soft_resetting it here. If HW_BRN_36492, the bit is already masked out.
443 #define RGX_CR_SOFT_RESET_ALL (RGX_CR_SOFT_RESET_MASKFULL ^ RGX_CR_SOFT_RESET_SLC_EN)
444 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: Shared SLC (don't reset SLC as part of RGX reset)");
446 #define RGX_CR_SOFT_RESET_ALL (RGX_CR_SOFT_RESET_MASKFULL)
449 #if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
450 /* Set RGX in soft-reset */
451 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: soft reset assert step 1");
452 OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, RGX_S7_SOFT_RESET_DUSTS);
453 PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, RGX_S7_SOFT_RESET_DUSTS, PDUMP_FLAGS_CONTINUOUS);
455 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: soft reset assert step 2");
456 OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, RGX_S7_SOFT_RESET_JONES_ALL | RGX_S7_SOFT_RESET_DUSTS);
457 PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, RGX_S7_SOFT_RESET_JONES_ALL | RGX_S7_SOFT_RESET_DUSTS, PDUMP_FLAGS_CONTINUOUS);
459 OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET2, RGX_S7_SOFT_RESET2);
460 PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET2, RGX_S7_SOFT_RESET2, PDUMP_FLAGS_CONTINUOUS);
462 /* Read soft-reset to fence previous write in order to clear the SOCIF pipeline */
463 (IMG_VOID) OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET);
464 PDUMPREGREAD64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, PDUMP_FLAGS_CONTINUOUS);
466 /* Take everything out of reset but META */
467 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: soft reset de-assert step 1 excluding META");
468 OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, RGX_S7_SOFT_RESET_DUSTS | RGX_CR_SOFT_RESET_GARTEN_EN);
469 PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, RGX_S7_SOFT_RESET_DUSTS | RGX_CR_SOFT_RESET_GARTEN_EN, PDUMP_FLAGS_CONTINUOUS);
471 OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET2, 0x0);
472 PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET2, 0x0, PDUMP_FLAGS_CONTINUOUS);
473 (IMG_VOID) OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET);
474 PDUMPREGREAD64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, PDUMP_FLAGS_CONTINUOUS);
476 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: soft reset de-assert step 2 excluding META");
477 OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_GARTEN_EN);
478 PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_GARTEN_EN, PDUMP_FLAGS_CONTINUOUS);
479 (IMG_VOID) OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET);
480 PDUMPREGREAD64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, PDUMP_FLAGS_CONTINUOUS);
482 /* Set RGX in soft-reset */
483 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: soft reset everything");
484 OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_ALL);
485 PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_ALL, PDUMP_FLAGS_CONTINUOUS);
487 /* Take Rascal and Dust out of reset */
488 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: Rascal and Dust out of reset");
489 OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_ALL ^ RGX_CR_SOFT_RESET_RASCALDUSTS_EN);
490 PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_ALL ^ RGX_CR_SOFT_RESET_RASCALDUSTS_EN, PDUMP_FLAGS_CONTINUOUS);
492 /* Read soft-reset to fence previous write in order to clear the SOCIF pipeline */
493 (IMG_VOID) OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET);
494 PDUMPREGREAD64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, PDUMP_FLAGS_CONTINUOUS);
496 /* Take everything out of reset but META */
497 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: Take everything out of reset but META");
498 OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_GARTEN_EN);
499 PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_GARTEN_EN, PDUMP_FLAGS_CONTINUOUS);
502 #if ! defined(FIX_HW_BRN_37453)
506 RGXEnableClocks(psDevInfo);
512 #if !defined(SUPPORT_SHARED_SLC)
513 RGX_INIT_SLC(psDevInfo);
516 #if !defined(SUPPORT_META_SLAVE_BOOT)
517 /* Configure META to Master boot */
518 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: META Master boot");
519 OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_META_BOOT, RGX_CR_META_BOOT_MODE_EN);
520 PDUMPREG32(RGX_PDUMPREG_NAME, RGX_CR_META_BOOT, RGX_CR_META_BOOT_MODE_EN, PDUMP_FLAGS_CONTINUOUS);
523 /* Set Garten IDLE to META idle and Set the Garten Wrapper BIF Fence address */
525 IMG_UINT64 ui64GartenConfig;
527 /* Garten IDLE bit controlled by META */
528 ui64GartenConfig = RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_META;
530 /* Set fence addr to the bootloader */
531 ui64GartenConfig |= (RGXFW_BOOTLDR_DEVV_ADDR & ~RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_ADDR_CLRMSK);
533 /* Set PC = 0 for fences */
534 ui64GartenConfig &= RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PC_BASE_CLRMSK;
536 #if defined(RGX_FEATURE_SLC_VIVT)
537 #if !defined(FIX_HW_BRN_51281)
538 /* Ensure the META fences go all the way to external memory */
539 ui64GartenConfig |= RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_SLC_COHERENT_EN; /* SLC Coherent 1 */
540 ui64GartenConfig &= RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PERSISTENCE_CLRMSK; /* SLC Persistence 0 */
544 /* Set SLC DM=META */
545 ui64GartenConfig |= ((IMG_UINT64) RGXFW_SEGMMU_META_DM_ID) << RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_DM_SHIFT;
549 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: Configure META wrapper");
550 OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_MTS_GARTEN_WRAPPER_CONFIG, ui64GartenConfig);
551 PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_MTS_GARTEN_WRAPPER_CONFIG, ui64GartenConfig, PDUMP_FLAGS_CONTINUOUS);
554 #if defined(RGX_FEATURE_AXI_ACELITE)
556 We must init the AXI-ACE interface before 1st BIF transaction
558 RGXAXIACELiteInit(psDevInfo);
564 RGXInitBIF(psDevInfo);
566 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: Take META out of reset");
567 /* need to wait for at least 16 cycles before taking meta out of reset ... */
568 PVRSRVSystemWaitCycles(psDevConfig, 32);
569 PDUMPIDLWITHFLAGS(32, PDUMP_FLAGS_CONTINUOUS);
571 OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, 0x0);
572 PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, 0x0, PDUMP_FLAGS_CONTINUOUS);
574 (IMG_VOID) OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET);
575 PDUMPREGREAD64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, PDUMP_FLAGS_CONTINUOUS);
577 /* ... and afterwards */
578 PVRSRVSystemWaitCycles(psDevConfig, 32);
579 PDUMPIDLWITHFLAGS(32, PDUMP_FLAGS_CONTINUOUS);
580 #if defined(FIX_HW_BRN_37453)
581 /* we rely on the 32 clk sleep from above */
583 /* switch clocks back to auto */
584 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: set clocks back to auto");
585 OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_CLK_CTRL, RGX_CR_CLK_CTRL_ALL_AUTO);
586 PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_CLK_CTRL, RGX_CR_CLK_CTRL_ALL_AUTO, PDUMP_FLAGS_CONTINUOUS);
590 * Start the firmware.
592 #if defined(SUPPORT_META_SLAVE_BOOT)
593 RGXStartFirmware(psDevInfo);
595 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXStart: RGX Firmware Master boot Start");
600 /* Check whether the FW has started by polling on bFirmwareStarted flag */
601 eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWIfInitMemDesc,
602 (IMG_VOID **)&psRGXFWInit);
603 if (eError != PVRSRV_OK)
605 PVR_DPF((PVR_DBG_ERROR,"RGXStart: Failed to acquire kernel fw if ctl (%u)", eError));
609 if (PVRSRVPollForValueKM((IMG_UINT32 *)&psRGXFWInit->bFirmwareStarted,
611 0xFFFFFFFF) != PVRSRV_OK)
613 PVR_DPF((PVR_DBG_ERROR, "RGXStart: Polling for 'FW started' flag failed."));
614 eError = PVRSRV_ERROR_TIMEOUT;
615 DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfInitMemDesc);
620 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "Wait for the Firmware to start.");
621 eError = DevmemPDumpDevmemPol32(psDevInfo->psRGXFWIfInitMemDesc,
622 offsetof(RGXFWIF_INIT, bFirmwareStarted),
625 PDUMP_POLL_OPERATOR_EQUAL,
626 PDUMP_FLAGS_CONTINUOUS);
628 if (eError != PVRSRV_OK)
630 PVR_DPF((PVR_DBG_ERROR, "RGXStart: problem pdumping POL for psRGXFWIfInitMemDesc (%d)", eError));
631 DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfInitMemDesc);
636 SetFirmwareStartTime(psRGXFWInit->ui32FirmwareStartedTimeStamp);
638 DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfInitMemDesc);
645 *******************************************************************************
649 @Description Stop RGX in preparation for power down
651 @Input psDevInfo - RGX device info
655 ******************************************************************************/
656 static PVRSRV_ERROR RGXStop(PVRSRV_RGXDEV_INFO *psDevInfo)
662 eError = RGXRunScript(psDevInfo, psDevInfo->psScripts->asDeinitCommands, RGX_MAX_DEINIT_COMMANDS, PDUMP_FLAGS_CONTINUOUS, IMG_NULL);
663 if (eError != PVRSRV_OK)
665 PVR_DPF((PVR_DBG_ERROR,"RGXStop: RGXRunScript failed (%d)", eError));
676 #if defined(SUPPORT_SHARED_SLC)
677 PVRSRV_ERROR RGXInitSLC(IMG_HANDLE hDevHandle)
680 PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
681 PVRSRV_RGXDEV_INFO *psDevInfo;
683 if (psDeviceNode == IMG_NULL)
685 return PVRSRV_ERROR_INVALID_PARAMS;
688 psDevInfo = psDeviceNode->pvDevice;
690 #if !defined(FIX_HW_BRN_36492)
693 PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "RGXInitSLC: soft reset SLC");
694 OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_SLC_EN);
695 PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, RGX_CR_SOFT_RESET_SLC_EN, PDUMP_FLAGS_CONTINUOUS);
697 /* Read soft-reset to fence previous write in order to clear the SOCIF pipeline */
698 OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET);
699 PDUMPREGREAD64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, PDUMP_FLAGS_CONTINUOUS);
701 /* Take everything out of reset */
702 OSWriteHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_SOFT_RESET, 0);
703 PDUMPREG64(RGX_PDUMPREG_NAME, RGX_CR_SOFT_RESET, 0, PDUMP_FLAGS_CONTINUOUS);
706 RGX_INIT_SLC(psDevInfo);
713 static IMG_VOID _RGXUpdateGPUUtilStats(PVRSRV_RGXDEV_INFO *psDevInfo)
715 RGXFWIF_GPU_UTIL_FWCB *psUtilFWCb;
716 IMG_UINT64 *paui64StatsCounters;
717 IMG_UINT64 ui64LastPeriod;
718 IMG_UINT64 ui64LastState;
719 IMG_UINT64 ui64LastTime;
720 IMG_UINT64 ui64TimeNow;
722 psUtilFWCb = psDevInfo->psRGXFWIfGpuUtilFWCb;
723 paui64StatsCounters = &psUtilFWCb->aui64StatsCounters[0];
725 OSLockAcquire(psDevInfo->hGPUUtilLock);
727 ui64TimeNow = RGXFWIF_GPU_UTIL_GET_TIME(OSClockns64());
729 /* Update counters to account for the time since the last update */
730 ui64LastState = RGXFWIF_GPU_UTIL_GET_STATE(psUtilFWCb->ui64LastWord);
731 ui64LastTime = RGXFWIF_GPU_UTIL_GET_TIME(psUtilFWCb->ui64LastWord);
732 ui64LastPeriod = RGXFWIF_GPU_UTIL_GET_PERIOD(ui64TimeNow, ui64LastTime);
733 paui64StatsCounters[ui64LastState] += ui64LastPeriod;
735 /* Update state and time of the latest update */
736 psUtilFWCb->ui64LastWord = RGXFWIF_GPU_UTIL_MAKE_WORD(ui64TimeNow, ui64LastState);
738 OSLockRelease(psDevInfo->hGPUUtilLock);
745 PVRSRV_ERROR RGXPrePowerState (IMG_HANDLE hDevHandle,
746 PVRSRV_DEV_POWER_STATE eNewPowerState,
747 PVRSRV_DEV_POWER_STATE eCurrentPowerState,
750 PVRSRV_ERROR eError = PVRSRV_OK;
752 if ((eNewPowerState != eCurrentPowerState) &&
753 (eNewPowerState != PVRSRV_DEV_POWER_STATE_ON))
755 PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
756 PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
757 RGXFWIF_KCCB_CMD sPowCmd;
758 RGXFWIF_TRACEBUF *psFWTraceBuf = psDevInfo->psRGXFWIfTraceBuf;
761 /* Send the Power off request to the FW */
762 sPowCmd.eCmdType = RGXFWIF_KCCB_CMD_POW;
763 sPowCmd.uCmdData.sPowData.ePowType = RGXFWIF_POW_OFF_REQ;
764 sPowCmd.uCmdData.sPowData.uPoweReqData.bForced = bForced;
766 SyncPrimSet(psDevInfo->psPowSyncPrim, 0);
768 /* Send one pow command to each DM to make sure we flush all the DMs pipelines */
769 for (ui32DM = 0; ui32DM < RGXFWIF_DM_MAX; ui32DM++)
771 eError = RGXSendCommandRaw(psDevInfo,
776 if (eError != PVRSRV_OK)
778 PVR_DPF((PVR_DBG_ERROR,"RGXPrePowerState: Failed to send Power off request for DM%d", ui32DM));
783 /* Wait for the firmware to complete processing. It cannot use PVRSRVWaitForValueKM as it relies
784 on the EventObject which is signalled in this MISR */
785 eError = PVRSRVPollForValueKM(psDevInfo->psPowSyncPrim->pui32LinAddr, 0x1, 0xFFFFFFFF);
787 /* Check the Power state after the answer */
788 if (eError == PVRSRV_OK)
790 /* Finally, de-initialise some registers. */
791 if (psFWTraceBuf->ePowState == RGXFWIF_POW_OFF)
793 #if !defined(NO_HARDWARE)
794 /* Wait for the pending META to host interrupts to come back. */
795 eError = PVRSRVPollForValueKM(&g_ui32HostSampleIRQCount,
796 psDevInfo->psRGXFWIfTraceBuf->ui32InterruptCount,
799 if (eError != PVRSRV_OK)
801 PVR_DPF((PVR_DBG_ERROR,"RGXPrePowerState: Wait for pending interrupts failed. Host:%d, FW: %d",
802 g_ui32HostSampleIRQCount,
803 psDevInfo->psRGXFWIfTraceBuf->ui32InterruptCount));
805 RGX_WaitForInterruptsTimeout(psDevInfo);
807 #endif /* NO_HARDWARE */
809 /* Update GPU frequency and timer correlation related data */
810 RGXGPUFreqCalibratePrePowerState(psDeviceNode);
812 /* Update GPU state counters */
813 _RGXUpdateGPUUtilStats(psDevInfo);
815 #if defined(PVR_DVFS)
816 eError = SuspendDVFS();
817 if (eError != PVRSRV_OK)
819 PVR_DPF((PVR_DBG_ERROR,"RGXPostPowerState: Failed to suspend DVFS"));
823 eError = RGXStop(psDevInfo);
824 if (eError != PVRSRV_OK)
826 PVR_DPF((PVR_DBG_ERROR,"RGXPrePowerState: RGXStop failed (%s)", PVRSRVGetErrorStringKM(eError)));
827 eError = PVRSRV_ERROR_DEVICE_POWER_CHANGE_FAILURE;
829 psDevInfo->bIgnoreFurtherIRQs = IMG_TRUE;
833 /* the sync was updated bu the pow state isn't off -> the FW denied the transition */
834 eError = PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED;
837 { /* It is an error for a forced request to be denied */
838 PVR_DPF((PVR_DBG_ERROR,"RGXPrePowerState: Failure to power off during a forced power off. FW: %d", psFWTraceBuf->ePowState));
842 else if (eError == PVRSRV_ERROR_TIMEOUT)
844 /* timeout waiting for the FW to ack the request: return timeout */
845 PVR_DPF((PVR_DBG_WARNING,"RGXPrePowerState: Timeout waiting for powoff ack from the FW"));
849 PVR_DPF((PVR_DBG_ERROR,"RGXPrePowerState: Error waiting for powoff ack from the FW (%s)", PVRSRVGetErrorStringKM(eError)));
850 eError = PVRSRV_ERROR_DEVICE_POWER_CHANGE_FAILURE;
862 PVRSRV_ERROR RGXPostPowerState (IMG_HANDLE hDevHandle,
863 PVRSRV_DEV_POWER_STATE eNewPowerState,
864 PVRSRV_DEV_POWER_STATE eCurrentPowerState,
867 if ((eNewPowerState != eCurrentPowerState) &&
868 (eCurrentPowerState != PVRSRV_DEV_POWER_STATE_ON))
871 PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
872 PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
873 PVRSRV_DEVICE_CONFIG *psDevConfig = psDeviceNode->psDevConfig;
875 if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF)
877 /* Update GPU frequency and timer correlation related data */
878 RGXGPUFreqCalibratePostPowerState(psDeviceNode);
880 /* Update GPU state counters */
881 _RGXUpdateGPUUtilStats(psDevInfo);
884 Run the RGX init script.
886 eError = RGXStart(psDevInfo, psDevConfig);
887 if (eError != PVRSRV_OK)
889 PVR_DPF((PVR_DBG_ERROR,"RGXPostPowerState: RGXStart failed"));
893 /* Coming up from off, re-allow RGX interrupts. */
894 psDevInfo->bIgnoreFurtherIRQs = IMG_FALSE;
896 #if defined(PVR_DVFS)
897 eError = ResumeDVFS();
898 if (eError != PVRSRV_OK)
900 PVR_DPF((PVR_DBG_ERROR,"RGXPostPowerState: Failed to resume DVFS"));
907 PDUMPCOMMENT("RGXPostPowerState: Current state: %d, New state: %d", eCurrentPowerState, eNewPowerState);
914 RGXPreClockSpeedChange
916 PVRSRV_ERROR RGXPreClockSpeedChange (IMG_HANDLE hDevHandle,
917 PVRSRV_DEV_POWER_STATE eCurrentPowerState)
919 PVRSRV_ERROR eError = PVRSRV_OK;
920 PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
921 PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
922 RGX_DATA *psRGXData = (RGX_DATA*)psDeviceNode->psDevConfig->hDevData;
923 RGXFWIF_TRACEBUF *psFWTraceBuf = psDevInfo->psRGXFWIfTraceBuf;
925 PVR_UNREFERENCED_PARAMETER(psRGXData);
927 PVR_DPF((PVR_DBG_MESSAGE,"RGXPreClockSpeedChange: RGX clock speed was %uHz",
928 psRGXData->psRGXTimingInfo->ui32CoreClockSpeed));
930 if ((eCurrentPowerState != PVRSRV_DEV_POWER_STATE_OFF)
931 && (psFWTraceBuf->ePowState != RGXFWIF_POW_OFF))
933 /* Update GPU frequency and timer correlation related data */
934 RGXGPUFreqCalibratePreClockSpeedChange(psDeviceNode);
942 RGXPostClockSpeedChange
944 PVRSRV_ERROR RGXPostClockSpeedChange (IMG_HANDLE hDevHandle,
945 PVRSRV_DEV_POWER_STATE eCurrentPowerState)
947 PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
948 PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
949 RGX_DATA *psRGXData = (RGX_DATA*)psDeviceNode->psDevConfig->hDevData;
950 PVRSRV_ERROR eError = PVRSRV_OK;
951 RGXFWIF_TRACEBUF *psFWTraceBuf = psDevInfo->psRGXFWIfTraceBuf;
952 IMG_UINT32 ui32NewClockSpeed = psRGXData->psRGXTimingInfo->ui32CoreClockSpeed;
954 /* Update runtime configuration with the new value */
955 psDevInfo->psRGXFWIfRuntimeCfg->ui32CoreClockSpeed = ui32NewClockSpeed;
957 if ((eCurrentPowerState != PVRSRV_DEV_POWER_STATE_OFF)
958 && (psFWTraceBuf->ePowState != RGXFWIF_POW_OFF))
960 RGXFWIF_KCCB_CMD sCOREClkSpeedChangeCmd;
962 RGXGPUFreqCalibratePostClockSpeedChange(psDeviceNode, ui32NewClockSpeed);
964 sCOREClkSpeedChangeCmd.eCmdType = RGXFWIF_KCCB_CMD_CORECLKSPEEDCHANGE;
965 sCOREClkSpeedChangeCmd.uCmdData.sCORECLKSPEEDCHANGEData.ui32NewClockSpeed = ui32NewClockSpeed;
967 /* Ensure the new clock speed is written to memory before requesting the FW to read it */
970 PDUMPCOMMENT("Scheduling CORE clock speed change command");
973 eError = RGXSendCommandRaw(psDeviceNode->pvDevice,
975 &sCOREClkSpeedChangeCmd,
976 sizeof(sCOREClkSpeedChangeCmd),
980 if (eError != PVRSRV_OK)
982 PDUMPCOMMENT("Scheduling CORE clock speed change command failed");
983 PVR_DPF((PVR_DBG_ERROR, "RGXPostClockSpeedChange: Scheduling KCCB command failed. Error:%u", eError));
987 PVR_DPF((PVR_DBG_MESSAGE,"RGXPostClockSpeedChange: RGX clock speed changed to %uHz",
988 psRGXData->psRGXTimingInfo->ui32CoreClockSpeed));
996 ******************************************************************************
998 @Function RGXDustCountChange
1002 Does change of number of DUSTs
1004 @Input hDevHandle : RGX Device Node
1005 @Input ui32NumberOfDusts : Number of DUSTs to make transition to
1007 @Return PVRSRV_ERROR :
1009 ******************************************************************************/
1010 PVRSRV_ERROR RGXDustCountChange(IMG_HANDLE hDevHandle,
1011 IMG_UINT32 ui32NumberOfDusts)
1014 PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
1015 PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
1016 PVRSRV_ERROR eError;
1017 RGXFWIF_KCCB_CMD sDustCountChange;
1018 IMG_UINT32 ui32MaxAvailableDusts = RGX_FEATURE_NUM_CLUSTERS / 2;
1020 #if !defined(NO_HARDWARE)
1021 RGXFWIF_TRACEBUF *psFWTraceBuf = psDevInfo->psRGXFWIfTraceBuf;
1023 if (psFWTraceBuf->ePowState != RGXFWIF_POW_FORCED_IDLE)
1025 eError = PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED;
1026 PVR_DPF((PVR_DBG_ERROR,"RGXDustCountChange: Attempt to change dust count when not IDLE"));
1031 PVR_ASSERT(ui32MaxAvailableDusts > 1);
1033 if (ui32NumberOfDusts > ui32MaxAvailableDusts)
1035 eError = PVRSRV_ERROR_INVALID_PARAMS;
1036 PVR_DPF((PVR_DBG_ERROR,
1037 "RGXDustCountChange: Invalid number of DUSTs (%u) while expecting value within <0,%u>. Error:%u",
1039 ui32MaxAvailableDusts,
1044 SyncPrimSet(psDevInfo->psPowSyncPrim, 0);
1046 sDustCountChange.eCmdType = RGXFWIF_KCCB_CMD_POW;
1047 sDustCountChange.uCmdData.sPowData.ePowType = RGXFWIF_POW_NUMDUST_CHANGE;
1048 sDustCountChange.uCmdData.sPowData.uPoweReqData.ui32NumOfDusts = ui32NumberOfDusts;
1050 PDUMPCOMMENT("Scheduling command to change Dust Count to %u", ui32NumberOfDusts);
1051 eError = RGXSendCommandRaw(psDeviceNode->pvDevice,
1054 sizeof(sDustCountChange),
1057 if (eError != PVRSRV_OK)
1059 PDUMPCOMMENT("Scheduling command to change Dust Count failed. Error:%u", eError);
1060 PVR_DPF((PVR_DBG_ERROR, "RGXDustCountChange: Scheduling KCCB to change Dust Count failed. Error:%u", eError));
1064 /* Wait for the firmware to answer. */
1065 eError = PVRSRVPollForValueKM(psDevInfo->psPowSyncPrim->pui32LinAddr, 0x1, 0xFFFFFFFF);
1067 if (eError != PVRSRV_OK)
1069 PVR_DPF((PVR_DBG_ERROR,"RGXDustCountChange: Timeout waiting for idle request"));
1074 PDUMPCOMMENT("RGXDustCountChange: Poll for Kernel SyncPrim [0x%p] on DM %d ", psDevInfo->psPowSyncPrim->pui32LinAddr, RGXFWIF_DM_GP);
1076 SyncPrimPDumpPol(psDevInfo->psPowSyncPrim,
1079 PDUMP_POLL_OPERATOR_EQUAL,
1086 @Function RGXAPMLatencyChange
1088 PVRSRV_ERROR RGXAPMLatencyChange(IMG_HANDLE hDevHandle,
1089 IMG_UINT32 ui32ActivePMLatencyms,
1090 IMG_BOOL bActivePMLatencyPersistant)
1093 PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
1094 PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
1095 PVRSRV_ERROR eError;
1096 RGXFWIF_RUNTIME_CFG *psRuntimeCfg = psDevInfo->psRGXFWIfRuntimeCfg;
1097 PVRSRV_DEV_POWER_STATE ePowerState;
1099 eError = PVRSRVPowerLock();
1100 if (eError != PVRSRV_OK)
1102 PVR_DPF((PVR_DBG_ERROR,"RGXAPMLatencyChange: Failed to acquire power lock"));
1106 /* Update runtime configuration with the new values */
1107 psRuntimeCfg->ui32ActivePMLatencyms = ui32ActivePMLatencyms;
1108 psRuntimeCfg->bActivePMLatencyPersistant = bActivePMLatencyPersistant;
1110 eError = PVRSRVGetDevicePowerState(psDeviceNode->sDevId.ui32DeviceIndex, &ePowerState);
1112 if ((eError == PVRSRV_OK) && (ePowerState != PVRSRV_DEV_POWER_STATE_OFF))
1114 RGXFWIF_KCCB_CMD sActivePMLatencyChange;
1115 sActivePMLatencyChange.eCmdType = RGXFWIF_KCCB_CMD_POW;
1116 sActivePMLatencyChange.uCmdData.sPowData.ePowType = RGXFWIF_POW_APM_LATENCY_CHANGE;
1117 sActivePMLatencyChange.uCmdData.sPowData.uPoweReqData.ui32ActivePMLatencyms = ui32ActivePMLatencyms;
1119 /* Ensure the new APM latency is written to memory before requesting the FW to read it */
1122 PDUMPCOMMENT("Scheduling command to change APM latency to %u", ui32ActivePMLatencyms);
1123 eError = RGXSendCommandRaw(psDeviceNode->pvDevice,
1125 &sActivePMLatencyChange,
1126 sizeof(sActivePMLatencyChange),
1129 if (eError != PVRSRV_OK)
1131 PDUMPCOMMENT("Scheduling command to change APM latency failed. Error:%u", eError);
1132 PVR_DPF((PVR_DBG_ERROR, "RGXAPMLatencyChange: Scheduling KCCB to change APM latency failed. Error:%u", eError));
1137 PVRSRVPowerUnlock();
1143 RGXActivePowerRequest
1145 PVRSRV_ERROR RGXActivePowerRequest(IMG_HANDLE hDevHandle)
1147 PVRSRV_ERROR eError = PVRSRV_OK;
1148 PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
1150 PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
1151 RGXFWIF_TRACEBUF *psFWTraceBuf = psDevInfo->psRGXFWIfTraceBuf;
1153 OSAcquireBridgeLock();
1154 /* NOTE: If this function were to wait for event object attempt should be
1155 made to prevent releasing bridge lock during sleep. Bridge lock should
1156 be held during sleep. */
1158 /* Powerlock to avoid further requests from racing with the FW hand-shake from now on
1159 (previous kicks to this point are detected by the FW) */
1160 eError = PVRSRVPowerLock();
1161 if(eError != PVRSRV_OK)
1163 PVR_DPF((PVR_DBG_ERROR,"RGXActivePowerRequest: Failed to acquire PowerLock (device index: %d, error: %s)",
1164 psDeviceNode->sDevId.ui32DeviceIndex,
1165 PVRSRVGetErrorStringKM(eError)));
1166 goto _RGXActivePowerRequest_PowerLock_failed;
1169 /* Check again for IDLE once we have the power lock */
1170 if (psFWTraceBuf->ePowState == RGXFWIF_POW_IDLE)
1173 psDevInfo->ui32ActivePMReqTotal++;
1175 SetFirmwareHandshakeIdleTime(RGXReadHWTimerReg(psDevInfo)-psFWTraceBuf->ui64StartIdleTime);
1179 PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
1180 PVRSRV_DEV_POWER_STATE_OFF,
1181 IMG_FALSE); /* forced */
1184 if (eError == PVRSRV_OK)
1186 psDevInfo->ui32ActivePMReqOk++;
1188 else if (eError == PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED)
1190 psDevInfo->ui32ActivePMReqDenied++;
1195 PVRSRVPowerUnlock();
1197 _RGXActivePowerRequest_PowerLock_failed:
1198 OSReleaseBridgeLock();
1204 RGXForcedIdleRequest
1207 #define RGX_FORCED_IDLE_RETRY_COUNT 10
1209 PVRSRV_ERROR RGXForcedIdleRequest(IMG_HANDLE hDevHandle, IMG_BOOL bDeviceOffPermitted)
1211 PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
1212 PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
1213 RGXFWIF_KCCB_CMD sPowCmd;
1214 PVRSRV_ERROR eError;
1215 IMG_UINT32 ui32RetryCount = 0;
1217 #if !defined(NO_HARDWARE)
1218 RGXFWIF_TRACEBUF *psFWTraceBuf = psDevInfo->psRGXFWIfTraceBuf;
1220 /* Firmware already forced idle */
1221 if (psFWTraceBuf->ePowState == RGXFWIF_POW_FORCED_IDLE)
1226 /* Firmware is not powered. Sometimes this is permitted, for instance we were forcing idle to power down. */
1227 if (psFWTraceBuf->ePowState == RGXFWIF_POW_OFF)
1229 return (bDeviceOffPermitted) ? PVRSRV_OK : PVRSRV_ERROR_DEVICE_IDLE_REQUEST_DENIED;
1233 SyncPrimSet(psDevInfo->psPowSyncPrim, 0);
1234 sPowCmd.eCmdType = RGXFWIF_KCCB_CMD_POW;
1235 sPowCmd.uCmdData.sPowData.ePowType = RGXFWIF_POW_FORCED_IDLE_REQ;
1236 sPowCmd.uCmdData.sPowData.uPoweReqData.bCancelForcedIdle = IMG_FALSE;
1238 PDUMPCOMMENT("RGXForcedIdleRequest: Sending forced idle command");
1240 /* Send one forced IDLE command to GP */
1241 eError = RGXSendCommandRaw(psDevInfo,
1247 if (eError != PVRSRV_OK)
1249 PVR_DPF((PVR_DBG_ERROR,"RGXForcedIdleRequest: Failed to send idle request"));
1253 /* Wait for GPU to finish current workload */
1255 eError = PVRSRVPollForValueKM(psDevInfo->psPowSyncPrim->pui32LinAddr, 0x1, 0xFFFFFFFF);
1256 if ((eError == PVRSRV_OK) || (ui32RetryCount == RGX_FORCED_IDLE_RETRY_COUNT))
1261 PVR_DPF((PVR_DBG_WARNING,"RGXForcedIdleRequest: Request timeout. Retry %d of %d", ui32RetryCount, RGX_FORCED_IDLE_RETRY_COUNT));
1264 if (eError != PVRSRV_OK)
1266 PVR_DPF((PVR_DBG_ERROR,"RGXForcedIdleRequest: Idle request failed. Firmware potentially left in forced idle state"));
1271 PDUMPCOMMENT("RGXForcedIdleRequest: Poll for Kernel SyncPrim [0x%p] on DM %d ", psDevInfo->psPowSyncPrim->pui32LinAddr, RGXFWIF_DM_GP);
1273 SyncPrimPDumpPol(psDevInfo->psPowSyncPrim,
1276 PDUMP_POLL_OPERATOR_EQUAL,
1280 #if !defined(NO_HARDWARE)
1281 /* Check the firmware state for idleness */
1282 if (psFWTraceBuf->ePowState != RGXFWIF_POW_FORCED_IDLE)
1284 PVR_DPF((PVR_DBG_ERROR,"RGXForcedIdleRequest: Failed to force IDLE"));
1286 return PVRSRV_ERROR_DEVICE_IDLE_REQUEST_DENIED;
1294 RGXCancelForcedIdleRequest
1296 PVRSRV_ERROR RGXCancelForcedIdleRequest(IMG_HANDLE hDevHandle)
1298 PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle;
1299 PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
1300 RGXFWIF_KCCB_CMD sPowCmd;
1301 PVRSRV_ERROR eError = PVRSRV_OK;
1303 SyncPrimSet(psDevInfo->psPowSyncPrim, 0);
1305 /* Send the IDLE request to the FW */
1306 sPowCmd.eCmdType = RGXFWIF_KCCB_CMD_POW;
1307 sPowCmd.uCmdData.sPowData.ePowType = RGXFWIF_POW_FORCED_IDLE_REQ;
1308 sPowCmd.uCmdData.sPowData.uPoweReqData.bCancelForcedIdle = IMG_TRUE;
1310 PDUMPCOMMENT("RGXForcedIdleRequest: Sending cancel forced idle command");
1312 /* Send cancel forced IDLE command to GP */
1313 eError = RGXSendCommandRaw(psDevInfo,
1319 if (eError != PVRSRV_OK)
1321 PDUMPCOMMENT("RGXCancelForcedIdleRequest: Failed to send cancel IDLE request for DM%d", RGXFWIF_DM_GP);
1325 /* Wait for the firmware to answer. */
1326 eError = PVRSRVPollForValueKM(psDevInfo->psPowSyncPrim->pui32LinAddr, 1, 0xFFFFFFFF);
1328 if (eError != PVRSRV_OK)
1330 PVR_DPF((PVR_DBG_ERROR,"RGXCancelForcedIdleRequest: Timeout waiting for cancel idle request"));
1335 PDUMPCOMMENT("RGXCancelForcedIdleRequest: Poll for Kernel SyncPrim [0x%p] on DM %d ", psDevInfo->psPowSyncPrim->pui32LinAddr, RGXFWIF_DM_GP);
1337 SyncPrimPDumpPol(psDevInfo->psPowSyncPrim,
1340 PDUMP_POLL_OPERATOR_EQUAL,
1347 PVR_DPF((PVR_DBG_ERROR,"RGXCancelForcedIdleRequest: Firmware potentially left in forced idle state"));
1351 /******************************************************************************
1352 End of file (rgxpower.c)
1353 ******************************************************************************/