1 // SPDX-License-Identifier: GPL-2.0-only OR MIT
2 /* Copyright (c) 2023 Imagination Technologies Ltd. */
3
4 #include "pvr_device.h"
5 #include "pvr_fw.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"
10 #include "pvr_vm.h"
11
12 #include <linux/compiler.h>
13 #include <linux/delay.h>
14 #include <linux/ktime.h>
15 #include <linux/types.h>
16
17 #define POLL_TIMEOUT_USEC 1000000
18
19 static void
rogue_axi_ace_list_init(struct pvr_device * pvr_dev)20 rogue_axi_ace_list_init(struct pvr_device *pvr_dev)
21 {
22 /* Setup AXI-ACE config. Set everything to outer cache. */
23 u64 reg_val =
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);
32
33 pvr_cr_write64(pvr_dev, ROGUE_CR_AXI_ACE_LITE_CONFIGURATION, reg_val);
34 }
35
36 static void
rogue_bif_init(struct pvr_device * pvr_dev)37 rogue_bif_init(struct pvr_device *pvr_dev)
38 {
39 dma_addr_t pc_dma_addr;
40 u64 pc_addr;
41
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);
44
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);
49
50 pvr_cr_write64(pvr_dev, BIF_CAT_BASEX(MMU_CONTEXT_MAPPING_FWPRIV),
51 pc_addr);
52
53 if (pvr_dev->fw_dev.processor_type == PVR_FW_PROCESSOR_TYPE_RISCV) {
54 pc_addr = (((u64)pc_dma_addr >> ROGUE_CR_FWCORE_MEM_CAT_BASE0_ADDR_ALIGNSHIFT)
55 << ROGUE_CR_FWCORE_MEM_CAT_BASE0_ADDR_SHIFT) &
56 ~ROGUE_CR_FWCORE_MEM_CAT_BASE0_ADDR_CLRMSK;
57
58 pvr_cr_write64(pvr_dev, FWCORE_MEM_CAT_BASEX(MMU_CONTEXT_MAPPING_FWPRIV), pc_addr);
59 }
60 }
61
62 static int
rogue_slc_init(struct pvr_device * pvr_dev)63 rogue_slc_init(struct pvr_device *pvr_dev)
64 {
65 u16 slc_cache_line_size_bits;
66 u32 reg_val;
67 int err;
68
69 /*
70 * SLC Misc control.
71 *
72 * Note: This is a 64bit register and we set only the lower 32bits
73 * leaving the top 32bits (ROGUE_CR_SLC_CTRL_MISC_SCRAMBLE_BITS)
74 * unchanged from the HW default.
75 */
76 reg_val = (pvr_cr_read32(pvr_dev, ROGUE_CR_SLC_CTRL_MISC) &
77 ROGUE_CR_SLC_CTRL_MISC_ENABLE_PSG_HAZARD_CHECK_EN) |
78 ROGUE_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_PVR_HASH1;
79
80 err = PVR_FEATURE_VALUE(pvr_dev, slc_cache_line_size_bits, &slc_cache_line_size_bits);
81 if (err)
82 return err;
83
84 /* Bypass burst combiner if SLC line size is smaller than 1024 bits. */
85 if (slc_cache_line_size_bits < 1024)
86 reg_val |= ROGUE_CR_SLC_CTRL_MISC_BYPASS_BURST_COMBINER_EN;
87
88 if (PVR_HAS_QUIRK(pvr_dev, 71242) && !PVR_HAS_FEATURE(pvr_dev, gpu_multicore_support))
89 reg_val |= ROGUE_CR_SLC_CTRL_MISC_LAZYWB_OVERRIDE_EN;
90
91 pvr_cr_write32(pvr_dev, ROGUE_CR_SLC_CTRL_MISC, reg_val);
92
93 return 0;
94 }
95
96 /**
97 * pvr_fw_start() - Start FW processor and boot firmware
98 * @pvr_dev: Target PowerVR device.
99 *
100 * Returns:
101 * * 0 on success, or
102 * * Any error returned by rogue_slc_init().
103 */
104 int
pvr_fw_start(struct pvr_device * pvr_dev)105 pvr_fw_start(struct pvr_device *pvr_dev)
106 {
107 bool has_reset2 = PVR_HAS_FEATURE(pvr_dev, xe_tpu2);
108 u64 soft_reset_mask;
109 int err;
110
111 if (PVR_HAS_FEATURE(pvr_dev, pbe2_in_xe))
112 soft_reset_mask = ROGUE_CR_SOFT_RESET__PBE2_XE__MASKFULL;
113 else
114 soft_reset_mask = ROGUE_CR_SOFT_RESET_MASKFULL;
115
116 if (PVR_HAS_FEATURE(pvr_dev, sys_bus_secure_reset)) {
117 /*
118 * Disable the default sys_bus_secure protection to perform
119 * minimal setup.
120 */
121 pvr_cr_write32(pvr_dev, ROGUE_CR_SYS_BUS_SECURE, 0);
122 (void)pvr_cr_read32(pvr_dev, ROGUE_CR_SYS_BUS_SECURE); /* Fence write */
123 }
124
125 if (pvr_dev->fw_dev.processor_type == PVR_FW_PROCESSOR_TYPE_RISCV)
126 pvr_cr_write32(pvr_dev, ROGUE_CR_FWCORE_BOOT, 0);
127
128 /* Set Rogue in soft-reset. */
129 pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, soft_reset_mask);
130 if (has_reset2)
131 pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET2, ROGUE_CR_SOFT_RESET2_MASKFULL);
132
133 /* Read soft-reset to fence previous write in order to clear the SOCIF pipeline. */
134 (void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET);
135 if (has_reset2)
136 (void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET2);
137
138 /* Take Rascal and Dust out of reset. */
139 pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET,
140 soft_reset_mask ^ ROGUE_CR_SOFT_RESET_RASCALDUSTS_EN);
141 if (has_reset2)
142 pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET2, 0);
143
144 (void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET);
145 if (has_reset2)
146 (void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET2);
147
148 /* Take everything out of reset but the FW processor. */
149 pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, ROGUE_CR_SOFT_RESET_GARTEN_EN);
150 if (has_reset2)
151 pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET2, 0);
152
153 (void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET);
154 if (has_reset2)
155 (void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET2);
156
157 err = rogue_slc_init(pvr_dev);
158 if (err)
159 goto err_reset;
160
161 /* Initialise Firmware wrapper. */
162 pvr_dev->fw_dev.defs->wrapper_init(pvr_dev);
163
164 /* We must init the AXI-ACE interface before first BIF transaction. */
165 rogue_axi_ace_list_init(pvr_dev);
166
167 if (pvr_dev->fw_dev.processor_type != PVR_FW_PROCESSOR_TYPE_MIPS) {
168 /* Initialise BIF. */
169 rogue_bif_init(pvr_dev);
170 }
171
172 /* Need to wait for at least 16 cycles before taking the FW processor out of reset ... */
173 udelay(3);
174
175 pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, 0x0);
176 (void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET);
177
178 /* ... and afterwards. */
179 udelay(3);
180
181 if (pvr_dev->fw_dev.processor_type == PVR_FW_PROCESSOR_TYPE_RISCV) {
182 /* Boot the FW. */
183 pvr_cr_write32(pvr_dev, ROGUE_CR_FWCORE_BOOT, 1);
184 udelay(3);
185 }
186
187 return 0;
188
189 err_reset:
190 /* Put everything back into soft-reset. */
191 pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, soft_reset_mask);
192
193 return err;
194 }
195
196 /**
197 * pvr_fw_stop() - Stop FW processor
198 * @pvr_dev: Target PowerVR device.
199 *
200 * Returns:
201 * * 0 on success, or
202 * * Any error returned by pvr_cr_poll_reg32().
203 */
204 int
pvr_fw_stop(struct pvr_device * pvr_dev)205 pvr_fw_stop(struct pvr_device *pvr_dev)
206 {
207 const u32 sidekick_idle_mask = ROGUE_CR_SIDEKICK_IDLE_MASKFULL &
208 ~(ROGUE_CR_SIDEKICK_IDLE_GARTEN_EN |
209 ROGUE_CR_SIDEKICK_IDLE_SOCIF_EN |
210 ROGUE_CR_SIDEKICK_IDLE_HOSTIF_EN);
211 bool skip_garten_idle = false;
212 u32 reg_value;
213 int err;
214
215 /*
216 * Wait for Sidekick/Jones to signal IDLE except for the Garten Wrapper.
217 * For cores with the LAYOUT_MARS feature, SIDEKICK would have been
218 * powered down by the FW.
219 */
220 err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_SIDEKICK_IDLE, sidekick_idle_mask,
221 sidekick_idle_mask, POLL_TIMEOUT_USEC);
222 if (err)
223 return err;
224
225 /* Unset MTS DM association with threads. */
226 pvr_cr_write32(pvr_dev, ROGUE_CR_MTS_INTCTX_THREAD0_DM_ASSOC,
227 ROGUE_CR_MTS_INTCTX_THREAD0_DM_ASSOC_MASKFULL &
228 ROGUE_CR_MTS_INTCTX_THREAD0_DM_ASSOC_DM_ASSOC_CLRMSK);
229 pvr_cr_write32(pvr_dev, ROGUE_CR_MTS_BGCTX_THREAD0_DM_ASSOC,
230 ROGUE_CR_MTS_BGCTX_THREAD0_DM_ASSOC_MASKFULL &
231 ROGUE_CR_MTS_BGCTX_THREAD0_DM_ASSOC_DM_ASSOC_CLRMSK);
232 pvr_cr_write32(pvr_dev, ROGUE_CR_MTS_INTCTX_THREAD1_DM_ASSOC,
233 ROGUE_CR_MTS_INTCTX_THREAD1_DM_ASSOC_MASKFULL &
234 ROGUE_CR_MTS_INTCTX_THREAD1_DM_ASSOC_DM_ASSOC_CLRMSK);
235 pvr_cr_write32(pvr_dev, ROGUE_CR_MTS_BGCTX_THREAD1_DM_ASSOC,
236 ROGUE_CR_MTS_BGCTX_THREAD1_DM_ASSOC_MASKFULL &
237 ROGUE_CR_MTS_BGCTX_THREAD1_DM_ASSOC_DM_ASSOC_CLRMSK);
238
239 /* Extra Idle checks. */
240 err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_BIF_STATUS_MMU, 0,
241 ROGUE_CR_BIF_STATUS_MMU_MASKFULL,
242 POLL_TIMEOUT_USEC);
243 if (err)
244 return err;
245
246 err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_BIFPM_STATUS_MMU, 0,
247 ROGUE_CR_BIFPM_STATUS_MMU_MASKFULL,
248 POLL_TIMEOUT_USEC);
249 if (err)
250 return err;
251
252 if (!PVR_HAS_FEATURE(pvr_dev, xt_top_infrastructure)) {
253 err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_BIF_READS_EXT_STATUS, 0,
254 ROGUE_CR_BIF_READS_EXT_STATUS_MASKFULL,
255 POLL_TIMEOUT_USEC);
256 if (err)
257 return err;
258 }
259
260 err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_BIFPM_READS_EXT_STATUS, 0,
261 ROGUE_CR_BIFPM_READS_EXT_STATUS_MASKFULL,
262 POLL_TIMEOUT_USEC);
263 if (err)
264 return err;
265
266 err = pvr_cr_poll_reg64(pvr_dev, ROGUE_CR_SLC_STATUS1, 0,
267 ROGUE_CR_SLC_STATUS1_MASKFULL,
268 POLL_TIMEOUT_USEC);
269 if (err)
270 return err;
271
272 /*
273 * Wait for SLC to signal IDLE.
274 * For cores with the LAYOUT_MARS feature, SLC would have been powered
275 * down by the FW.
276 */
277 err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_SLC_IDLE,
278 ROGUE_CR_SLC_IDLE_MASKFULL,
279 ROGUE_CR_SLC_IDLE_MASKFULL, POLL_TIMEOUT_USEC);
280 if (err)
281 return err;
282
283 /*
284 * Wait for Sidekick/Jones to signal IDLE except for the Garten Wrapper.
285 * For cores with the LAYOUT_MARS feature, SIDEKICK would have been powered
286 * down by the FW.
287 */
288 err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_SIDEKICK_IDLE, sidekick_idle_mask,
289 sidekick_idle_mask, POLL_TIMEOUT_USEC);
290 if (err)
291 return err;
292
293 if (pvr_dev->fw_dev.processor_type == PVR_FW_PROCESSOR_TYPE_META) {
294 err = pvr_meta_cr_read32(pvr_dev, META_CR_TxVECINT_BHALT, ®_value);
295 if (err)
296 return err;
297
298 /*
299 * Wait for Sidekick/Jones to signal IDLE including the Garten
300 * Wrapper if there is no debugger attached (TxVECINT_BHALT =
301 * 0x0).
302 */
303 if (reg_value)
304 skip_garten_idle = true;
305 }
306
307 if (!skip_garten_idle) {
308 err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_SIDEKICK_IDLE,
309 ROGUE_CR_SIDEKICK_IDLE_GARTEN_EN,
310 ROGUE_CR_SIDEKICK_IDLE_GARTEN_EN,
311 POLL_TIMEOUT_USEC);
312 if (err)
313 return err;
314 }
315
316 if (PVR_HAS_FEATURE(pvr_dev, pbe2_in_xe))
317 pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET,
318 ROGUE_CR_SOFT_RESET__PBE2_XE__MASKFULL);
319 else
320 pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, ROGUE_CR_SOFT_RESET_MASKFULL);
321
322 return 0;
323 }
324