xref: /linux/drivers/gpu/drm/imagination/pvr_fw_startstop.c (revision aec2f682d47c54ef434b2d440992626d80b1ebdc)
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
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
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
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
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
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 	u64 layout_mars_value = 0;
213 	bool layout_mars = false;
214 	bool meta_fw = pvr_dev->fw_dev.processor_type == PVR_FW_PROCESSOR_TYPE_META;
215 	u32 reg_value;
216 	int err;
217 
218 	if (PVR_FEATURE_VALUE(pvr_dev, layout_mars, &layout_mars_value) == 0)
219 		layout_mars = layout_mars_value > 0;
220 
221 	/*
222 	 * For cores with the LAYOUT_MARS feature, SIDEKICK and SLC would have been
223 	 * powered down by the FW.
224 	 */
225 	if (!layout_mars) {
226 		/* Wait for Sidekick/Jones to signal IDLE except for the Garten Wrapper. */
227 		err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_SIDEKICK_IDLE, sidekick_idle_mask,
228 					sidekick_idle_mask, POLL_TIMEOUT_USEC);
229 		if (err)
230 			return err;
231 
232 		/* Wait for SLC to signal IDLE. */
233 		err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_SLC_IDLE, ROGUE_CR_SLC_IDLE_MASKFULL,
234 					ROGUE_CR_SLC_IDLE_MASKFULL, POLL_TIMEOUT_USEC);
235 		if (err)
236 			return err;
237 	}
238 
239 	/* Unset MTS DM association with threads. */
240 	pvr_cr_write32(pvr_dev, ROGUE_CR_MTS_INTCTX_THREAD0_DM_ASSOC,
241 		       ROGUE_CR_MTS_INTCTX_THREAD0_DM_ASSOC_MASKFULL &
242 		       ROGUE_CR_MTS_INTCTX_THREAD0_DM_ASSOC_DM_ASSOC_CLRMSK);
243 	pvr_cr_write32(pvr_dev, ROGUE_CR_MTS_BGCTX_THREAD0_DM_ASSOC,
244 		       ROGUE_CR_MTS_BGCTX_THREAD0_DM_ASSOC_MASKFULL &
245 		       ROGUE_CR_MTS_BGCTX_THREAD0_DM_ASSOC_DM_ASSOC_CLRMSK);
246 
247 	if (meta_fw) {
248 		pvr_cr_write32(pvr_dev, ROGUE_CR_MTS_INTCTX_THREAD1_DM_ASSOC,
249 			       ROGUE_CR_MTS_INTCTX_THREAD1_DM_ASSOC_MASKFULL &
250 			       ROGUE_CR_MTS_INTCTX_THREAD1_DM_ASSOC_DM_ASSOC_CLRMSK);
251 		pvr_cr_write32(pvr_dev, ROGUE_CR_MTS_BGCTX_THREAD1_DM_ASSOC,
252 			       ROGUE_CR_MTS_BGCTX_THREAD1_DM_ASSOC_MASKFULL &
253 			       ROGUE_CR_MTS_BGCTX_THREAD1_DM_ASSOC_DM_ASSOC_CLRMSK);
254 	}
255 
256 	/* Extra Idle checks. */
257 	err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_BIF_STATUS_MMU, 0,
258 				ROGUE_CR_BIF_STATUS_MMU_MASKFULL,
259 				POLL_TIMEOUT_USEC);
260 	if (err)
261 		return err;
262 
263 	err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_BIFPM_STATUS_MMU, 0,
264 				ROGUE_CR_BIFPM_STATUS_MMU_MASKFULL,
265 				POLL_TIMEOUT_USEC);
266 	if (err)
267 		return err;
268 
269 	if (!PVR_HAS_FEATURE(pvr_dev, xt_top_infrastructure)) {
270 		err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_BIF_READS_EXT_STATUS, 0,
271 					ROGUE_CR_BIF_READS_EXT_STATUS_MASKFULL,
272 					POLL_TIMEOUT_USEC);
273 		if (err)
274 			return err;
275 	}
276 
277 	err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_BIFPM_READS_EXT_STATUS, 0,
278 				ROGUE_CR_BIFPM_READS_EXT_STATUS_MASKFULL,
279 				POLL_TIMEOUT_USEC);
280 	if (err)
281 		return err;
282 
283 	err = pvr_cr_poll_reg64(pvr_dev, ROGUE_CR_SLC_STATUS1, 0,
284 				ROGUE_CR_SLC_STATUS1_MASKFULL,
285 				POLL_TIMEOUT_USEC);
286 	if (err)
287 		return err;
288 
289 	/*
290 	 * For cores with the LAYOUT_MARS feature, SIDEKICK and SLC would have been
291 	 * powered down by the FW.
292 	 */
293 	if (!layout_mars) {
294 		/* Wait for SLC to signal IDLE. */
295 		err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_SLC_IDLE,
296 					ROGUE_CR_SLC_IDLE_MASKFULL,
297 					ROGUE_CR_SLC_IDLE_MASKFULL, POLL_TIMEOUT_USEC);
298 		if (err)
299 			return err;
300 
301 		/* Wait for Sidekick/Jones to signal IDLE except for the Garten Wrapper. */
302 		err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_SIDEKICK_IDLE, sidekick_idle_mask,
303 					sidekick_idle_mask, POLL_TIMEOUT_USEC);
304 		if (err)
305 			return err;
306 	}
307 
308 	if (meta_fw) {
309 		err = pvr_meta_cr_read32(pvr_dev, META_CR_TxVECINT_BHALT, &reg_value);
310 		if (err)
311 			return err;
312 
313 		/*
314 		 * Wait for Sidekick/Jones to signal IDLE including the Garten
315 		 * Wrapper if there is no debugger attached (TxVECINT_BHALT =
316 		 * 0x0).
317 		 */
318 		if (reg_value)
319 			skip_garten_idle = true;
320 	}
321 
322 	if (meta_fw || !layout_mars) {
323 		if (!skip_garten_idle) {
324 			err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_SIDEKICK_IDLE,
325 						ROGUE_CR_SIDEKICK_IDLE_GARTEN_EN,
326 						ROGUE_CR_SIDEKICK_IDLE_GARTEN_EN,
327 						POLL_TIMEOUT_USEC);
328 			if (err)
329 				return err;
330 		}
331 	} else {
332 		/*
333 		 * As FW core has been moved from SIDEKICK to the new MARS domain, checking
334 		 * idle bits for CPU & System Arbiter excluding SOCIF which will never be
335 		 * idle if Host polling on this register
336 		 */
337 		err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_MARS_IDLE,
338 					ROGUE_CR_MARS_IDLE_CPU_EN |
339 					ROGUE_CR_MARS_IDLE_MH_SYSARB0_EN,
340 					ROGUE_CR_MARS_IDLE_CPU_EN |
341 					ROGUE_CR_MARS_IDLE_MH_SYSARB0_EN,
342 					POLL_TIMEOUT_USEC);
343 
344 		if (err)
345 			return err;
346 	}
347 
348 	if (PVR_HAS_FEATURE(pvr_dev, pbe2_in_xe))
349 		pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET,
350 			       ROGUE_CR_SOFT_RESET__PBE2_XE__MASKFULL);
351 	else
352 		pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, ROGUE_CR_SOFT_RESET_MASKFULL);
353 
354 	return 0;
355 }
356