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
19static void
20rogue_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
36static void
37rogue_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
54static int
55rogue_slc_init(struct pvr_device *pvr_dev)
56{
57	u16 slc_cache_line_size_bits;
58	u32 reg_val;
59	int err;
60
61	/*
62	 * SLC Misc control.
63	 *
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.
67	 */
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;
71
72	err = PVR_FEATURE_VALUE(pvr_dev, slc_cache_line_size_bits, &slc_cache_line_size_bits);
73	if (err)
74		return err;
75
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;
79
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;
82
83	pvr_cr_write32(pvr_dev, ROGUE_CR_SLC_CTRL_MISC, reg_val);
84
85	return 0;
86}
87
88/**
89 * pvr_fw_start() - Start FW processor and boot firmware
90 * @pvr_dev: Target PowerVR device.
91 *
92 * Returns:
93 *  * 0 on success, or
94 *  * Any error returned by rogue_slc_init().
95 */
96int
97pvr_fw_start(struct pvr_device *pvr_dev)
98{
99	bool has_reset2 = PVR_HAS_FEATURE(pvr_dev, xe_tpu2);
100	u64 soft_reset_mask;
101	int err;
102
103	if (PVR_HAS_FEATURE(pvr_dev, pbe2_in_xe))
104		soft_reset_mask = ROGUE_CR_SOFT_RESET__PBE2_XE__MASKFULL;
105	else
106		soft_reset_mask = ROGUE_CR_SOFT_RESET_MASKFULL;
107
108	if (PVR_HAS_FEATURE(pvr_dev, sys_bus_secure_reset)) {
109		/*
110		 * Disable the default sys_bus_secure protection to perform
111		 * minimal setup.
112		 */
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 */
115	}
116
117	/* Set Rogue in soft-reset. */
118	pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, soft_reset_mask);
119	if (has_reset2)
120		pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET2, ROGUE_CR_SOFT_RESET2_MASKFULL);
121
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);
124	if (has_reset2)
125		(void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET2);
126
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);
130	if (has_reset2)
131		pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET2, 0);
132
133	(void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET);
134	if (has_reset2)
135		(void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET2);
136
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);
139	if (has_reset2)
140		pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET2, 0);
141
142	(void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET);
143	if (has_reset2)
144		(void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET2);
145
146	err = rogue_slc_init(pvr_dev);
147	if (err)
148		goto err_reset;
149
150	/* Initialise Firmware wrapper. */
151	pvr_dev->fw_dev.defs->wrapper_init(pvr_dev);
152
153	/* We must init the AXI-ACE interface before first BIF transaction. */
154	rogue_axi_ace_list_init(pvr_dev);
155
156	if (pvr_dev->fw_dev.processor_type != PVR_FW_PROCESSOR_TYPE_MIPS) {
157		/* Initialise BIF. */
158		rogue_bif_init(pvr_dev);
159	}
160
161	/* Need to wait for at least 16 cycles before taking the FW processor out of reset ... */
162	udelay(3);
163
164	pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, 0x0);
165	(void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET);
166
167	/* ... and afterwards. */
168	udelay(3);
169
170	return 0;
171
172err_reset:
173	/* Put everything back into soft-reset. */
174	pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, soft_reset_mask);
175
176	return err;
177}
178
179/**
180 * pvr_fw_stop() - Stop FW processor
181 * @pvr_dev: Target PowerVR device.
182 *
183 * Returns:
184 *  * 0 on success, or
185 *  * Any error returned by pvr_cr_poll_reg32().
186 */
187int
188pvr_fw_stop(struct pvr_device *pvr_dev)
189{
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;
195	u32 reg_value;
196	int err;
197
198	/*
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.
202	 */
203	err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_SIDEKICK_IDLE, sidekick_idle_mask,
204				sidekick_idle_mask, POLL_TIMEOUT_USEC);
205	if (err)
206		return err;
207
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);
221
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,
225				POLL_TIMEOUT_USEC);
226	if (err)
227		return err;
228
229	err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_BIFPM_STATUS_MMU, 0,
230				ROGUE_CR_BIFPM_STATUS_MMU_MASKFULL,
231				POLL_TIMEOUT_USEC);
232	if (err)
233		return err;
234
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,
238					POLL_TIMEOUT_USEC);
239		if (err)
240			return err;
241	}
242
243	err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_BIFPM_READS_EXT_STATUS, 0,
244				ROGUE_CR_BIFPM_READS_EXT_STATUS_MASKFULL,
245				POLL_TIMEOUT_USEC);
246	if (err)
247		return err;
248
249	err = pvr_cr_poll_reg64(pvr_dev, ROGUE_CR_SLC_STATUS1, 0,
250				ROGUE_CR_SLC_STATUS1_MASKFULL,
251				POLL_TIMEOUT_USEC);
252	if (err)
253		return err;
254
255	/*
256	 * Wait for SLC to signal IDLE.
257	 * For cores with the LAYOUT_MARS feature, SLC would have been powered
258	 * down by the FW.
259	 */
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);
263	if (err)
264		return err;
265
266	/*
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
269	 * down by the FW.
270	 */
271	err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_SIDEKICK_IDLE, sidekick_idle_mask,
272				sidekick_idle_mask, POLL_TIMEOUT_USEC);
273	if (err)
274		return err;
275
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, &reg_value);
278		if (err)
279			return err;
280
281		/*
282		 * Wait for Sidekick/Jones to signal IDLE including the Garten
283		 * Wrapper if there is no debugger attached (TxVECINT_BHALT =
284		 * 0x0).
285		 */
286		if (reg_value)
287			skip_garten_idle = true;
288	}
289
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,
294					POLL_TIMEOUT_USEC);
295		if (err)
296			return err;
297	}
298
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);
302	else
303		pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, ROGUE_CR_SOFT_RESET_MASKFULL);
304
305	return 0;
306}
307