1 // SPDX-License-Identifier: GPL-2.0-only OR MIT
2 /* Copyright (c) 2023 Imagination Technologies Ltd. */
4 #include "pvr_device.h"
6 #include "pvr_fw_meta.h"
7 #include "pvr_fw_startstop.h"
8 #include "pvr_rogue_cr_defs.h"
9 #include "pvr_rogue_meta.h"
12 #include <linux/compiler.h>
13 #include <linux/delay.h>
14 #include <linux/ktime.h>
15 #include <linux/types.h>
17 #define POLL_TIMEOUT_USEC 1000000
20 rogue_axi_ace_list_init(struct pvr_device *pvr_dev)
22 /* Setup AXI-ACE config. Set everything to outer cache. */
24 (3U << ROGUE_CR_AXI_ACE_LITE_CONFIGURATION_AWDOMAIN_NON_SNOOPING_SHIFT) |
25 (3U << ROGUE_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_NON_SNOOPING_SHIFT) |
26 (2U << ROGUE_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_CACHE_MAINTENANCE_SHIFT) |
27 (2U << ROGUE_CR_AXI_ACE_LITE_CONFIGURATION_AWDOMAIN_COHERENT_SHIFT) |
28 (2U << ROGUE_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_COHERENT_SHIFT) |
29 (2U << ROGUE_CR_AXI_ACE_LITE_CONFIGURATION_AWCACHE_COHERENT_SHIFT) |
30 (2U << ROGUE_CR_AXI_ACE_LITE_CONFIGURATION_ARCACHE_COHERENT_SHIFT) |
31 (2U << ROGUE_CR_AXI_ACE_LITE_CONFIGURATION_ARCACHE_CACHE_MAINTENANCE_SHIFT);
33 pvr_cr_write64(pvr_dev, ROGUE_CR_AXI_ACE_LITE_CONFIGURATION, reg_val);
37 rogue_bif_init(struct pvr_device *pvr_dev)
39 dma_addr_t pc_dma_addr;
42 /* Acquire the address of the Kernel Page Catalogue. */
43 pc_dma_addr = pvr_vm_get_page_table_root_addr(pvr_dev->kernel_vm_ctx);
45 /* Write the kernel catalogue base. */
46 pc_addr = ((((u64)pc_dma_addr >> ROGUE_CR_BIF_CAT_BASE0_ADDR_ALIGNSHIFT)
47 << ROGUE_CR_BIF_CAT_BASE0_ADDR_SHIFT) &
48 ~ROGUE_CR_BIF_CAT_BASE0_ADDR_CLRMSK);
50 pvr_cr_write64(pvr_dev, BIF_CAT_BASEX(MMU_CONTEXT_MAPPING_FWPRIV),
55 rogue_slc_init(struct pvr_device *pvr_dev)
57 u16 slc_cache_line_size_bits;
64 * Note: This is a 64bit register and we set only the lower 32bits
65 * leaving the top 32bits (ROGUE_CR_SLC_CTRL_MISC_SCRAMBLE_BITS)
66 * unchanged from the HW default.
68 reg_val = (pvr_cr_read32(pvr_dev, ROGUE_CR_SLC_CTRL_MISC) &
69 ROGUE_CR_SLC_CTRL_MISC_ENABLE_PSG_HAZARD_CHECK_EN) |
70 ROGUE_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_PVR_HASH1;
72 err = PVR_FEATURE_VALUE(pvr_dev, slc_cache_line_size_bits, &slc_cache_line_size_bits);
76 /* Bypass burst combiner if SLC line size is smaller than 1024 bits. */
77 if (slc_cache_line_size_bits < 1024)
78 reg_val |= ROGUE_CR_SLC_CTRL_MISC_BYPASS_BURST_COMBINER_EN;
80 if (PVR_HAS_QUIRK(pvr_dev, 71242) && !PVR_HAS_FEATURE(pvr_dev, gpu_multicore_support))
81 reg_val |= ROGUE_CR_SLC_CTRL_MISC_LAZYWB_OVERRIDE_EN;
83 pvr_cr_write32(pvr_dev, ROGUE_CR_SLC_CTRL_MISC, reg_val);
89 * pvr_fw_start() - Start FW processor and boot firmware
90 * @pvr_dev: Target PowerVR device.
94 * * Any error returned by rogue_slc_init().
97 pvr_fw_start(struct pvr_device *pvr_dev)
99 bool has_reset2 = PVR_HAS_FEATURE(pvr_dev, xe_tpu2);
103 if (PVR_HAS_FEATURE(pvr_dev, pbe2_in_xe))
104 soft_reset_mask = ROGUE_CR_SOFT_RESET__PBE2_XE__MASKFULL;
106 soft_reset_mask = ROGUE_CR_SOFT_RESET_MASKFULL;
108 if (PVR_HAS_FEATURE(pvr_dev, sys_bus_secure_reset)) {
110 * Disable the default sys_bus_secure protection to perform
113 pvr_cr_write32(pvr_dev, ROGUE_CR_SYS_BUS_SECURE, 0);
114 (void)pvr_cr_read32(pvr_dev, ROGUE_CR_SYS_BUS_SECURE); /* Fence write */
117 /* Set Rogue in soft-reset. */
118 pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, soft_reset_mask);
120 pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET2, ROGUE_CR_SOFT_RESET2_MASKFULL);
122 /* Read soft-reset to fence previous write in order to clear the SOCIF pipeline. */
123 (void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET);
125 (void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET2);
127 /* Take Rascal and Dust out of reset. */
128 pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET,
129 soft_reset_mask ^ ROGUE_CR_SOFT_RESET_RASCALDUSTS_EN);
131 pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET2, 0);
133 (void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET);
135 (void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET2);
137 /* Take everything out of reset but the FW processor. */
138 pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, ROGUE_CR_SOFT_RESET_GARTEN_EN);
140 pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET2, 0);
142 (void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET);
144 (void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET2);
146 err = rogue_slc_init(pvr_dev);
150 /* Initialise Firmware wrapper. */
151 pvr_dev->fw_dev.defs->wrapper_init(pvr_dev);
153 /* We must init the AXI-ACE interface before first BIF transaction. */
154 rogue_axi_ace_list_init(pvr_dev);
156 if (pvr_dev->fw_dev.processor_type != PVR_FW_PROCESSOR_TYPE_MIPS) {
157 /* Initialise BIF. */
158 rogue_bif_init(pvr_dev);
161 /* Need to wait for at least 16 cycles before taking the FW processor out of reset ... */
164 pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, 0x0);
165 (void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET);
167 /* ... and afterwards. */
173 /* Put everything back into soft-reset. */
174 pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, soft_reset_mask);
180 * pvr_fw_stop() - Stop FW processor
181 * @pvr_dev: Target PowerVR device.
185 * * Any error returned by pvr_cr_poll_reg32().
188 pvr_fw_stop(struct pvr_device *pvr_dev)
190 const u32 sidekick_idle_mask = ROGUE_CR_SIDEKICK_IDLE_MASKFULL &
191 ~(ROGUE_CR_SIDEKICK_IDLE_GARTEN_EN |
192 ROGUE_CR_SIDEKICK_IDLE_SOCIF_EN |
193 ROGUE_CR_SIDEKICK_IDLE_HOSTIF_EN);
194 bool skip_garten_idle = false;
199 * Wait for Sidekick/Jones to signal IDLE except for the Garten Wrapper.
200 * For cores with the LAYOUT_MARS feature, SIDEKICK would have been
201 * powered down by the FW.
203 err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_SIDEKICK_IDLE, sidekick_idle_mask,
204 sidekick_idle_mask, POLL_TIMEOUT_USEC);
208 /* Unset MTS DM association with threads. */
209 pvr_cr_write32(pvr_dev, ROGUE_CR_MTS_INTCTX_THREAD0_DM_ASSOC,
210 ROGUE_CR_MTS_INTCTX_THREAD0_DM_ASSOC_MASKFULL &
211 ROGUE_CR_MTS_INTCTX_THREAD0_DM_ASSOC_DM_ASSOC_CLRMSK);
212 pvr_cr_write32(pvr_dev, ROGUE_CR_MTS_BGCTX_THREAD0_DM_ASSOC,
213 ROGUE_CR_MTS_BGCTX_THREAD0_DM_ASSOC_MASKFULL &
214 ROGUE_CR_MTS_BGCTX_THREAD0_DM_ASSOC_DM_ASSOC_CLRMSK);
215 pvr_cr_write32(pvr_dev, ROGUE_CR_MTS_INTCTX_THREAD1_DM_ASSOC,
216 ROGUE_CR_MTS_INTCTX_THREAD1_DM_ASSOC_MASKFULL &
217 ROGUE_CR_MTS_INTCTX_THREAD1_DM_ASSOC_DM_ASSOC_CLRMSK);
218 pvr_cr_write32(pvr_dev, ROGUE_CR_MTS_BGCTX_THREAD1_DM_ASSOC,
219 ROGUE_CR_MTS_BGCTX_THREAD1_DM_ASSOC_MASKFULL &
220 ROGUE_CR_MTS_BGCTX_THREAD1_DM_ASSOC_DM_ASSOC_CLRMSK);
222 /* Extra Idle checks. */
223 err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_BIF_STATUS_MMU, 0,
224 ROGUE_CR_BIF_STATUS_MMU_MASKFULL,
229 err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_BIFPM_STATUS_MMU, 0,
230 ROGUE_CR_BIFPM_STATUS_MMU_MASKFULL,
235 if (!PVR_HAS_FEATURE(pvr_dev, xt_top_infrastructure)) {
236 err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_BIF_READS_EXT_STATUS, 0,
237 ROGUE_CR_BIF_READS_EXT_STATUS_MASKFULL,
243 err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_BIFPM_READS_EXT_STATUS, 0,
244 ROGUE_CR_BIFPM_READS_EXT_STATUS_MASKFULL,
249 err = pvr_cr_poll_reg64(pvr_dev, ROGUE_CR_SLC_STATUS1, 0,
250 ROGUE_CR_SLC_STATUS1_MASKFULL,
256 * Wait for SLC to signal IDLE.
257 * For cores with the LAYOUT_MARS feature, SLC would have been powered
260 err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_SLC_IDLE,
261 ROGUE_CR_SLC_IDLE_MASKFULL,
262 ROGUE_CR_SLC_IDLE_MASKFULL, POLL_TIMEOUT_USEC);
267 * Wait for Sidekick/Jones to signal IDLE except for the Garten Wrapper.
268 * For cores with the LAYOUT_MARS feature, SIDEKICK would have been powered
271 err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_SIDEKICK_IDLE, sidekick_idle_mask,
272 sidekick_idle_mask, POLL_TIMEOUT_USEC);
276 if (pvr_dev->fw_dev.processor_type == PVR_FW_PROCESSOR_TYPE_META) {
277 err = pvr_meta_cr_read32(pvr_dev, META_CR_TxVECINT_BHALT, ®_value);
282 * Wait for Sidekick/Jones to signal IDLE including the Garten
283 * Wrapper if there is no debugger attached (TxVECINT_BHALT =
287 skip_garten_idle = true;
290 if (!skip_garten_idle) {
291 err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_SIDEKICK_IDLE,
292 ROGUE_CR_SIDEKICK_IDLE_GARTEN_EN,
293 ROGUE_CR_SIDEKICK_IDLE_GARTEN_EN,
299 if (PVR_HAS_FEATURE(pvr_dev, pbe2_in_xe))
300 pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET,
301 ROGUE_CR_SOFT_RESET__PBE2_XE__MASKFULL);
303 pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, ROGUE_CR_SOFT_RESET_MASKFULL);