xref: /linux/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v12.c (revision 570f7e331f5febb30f1384817463c7e42b65ca7d)
1 /*
2  * Copyright 2023 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  */
22 
23 #include "amdgpu.h"
24 #include "amdgpu_amdkfd.h"
25 #include "gc/gc_12_0_0_offset.h"
26 #include "gc/gc_12_0_0_sh_mask.h"
27 #include "soc24.h"
28 #include <uapi/linux/kfd_ioctl.h>
29 
30 static void lock_srbm(struct amdgpu_device *adev, uint32_t mec, uint32_t pipe,
31 			uint32_t queue, uint32_t vmid)
32 {
33 	mutex_lock(&adev->srbm_mutex);
34 	soc24_grbm_select(adev, mec, pipe, queue, vmid);
35 }
36 
37 static void unlock_srbm(struct amdgpu_device *adev)
38 {
39 	soc24_grbm_select(adev, 0, 0, 0, 0);
40 	mutex_unlock(&adev->srbm_mutex);
41 }
42 
43 static void acquire_queue(struct amdgpu_device *adev, uint32_t pipe_id,
44 				uint32_t queue_id)
45 {
46 	uint32_t mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
47 	uint32_t pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
48 
49 	lock_srbm(adev, mec, pipe, queue_id, 0);
50 }
51 
52 static void release_queue(struct amdgpu_device *adev)
53 {
54 	unlock_srbm(adev);
55 }
56 
57 static int init_interrupts_v12(struct amdgpu_device *adev, uint32_t pipe_id, uint32_t inst)
58 {
59 	uint32_t mec;
60 	uint32_t pipe;
61 
62 	mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
63 	pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
64 
65 	lock_srbm(adev, mec, pipe, 0, 0);
66 
67 	WREG32_SOC15(GC, 0, regCPC_INT_CNTL,
68 		CP_INT_CNTL_RING0__TIME_STAMP_INT_ENABLE_MASK |
69 		CP_INT_CNTL_RING0__OPCODE_ERROR_INT_ENABLE_MASK);
70 
71 	unlock_srbm(adev);
72 
73 	return 0;
74 }
75 
76 static uint32_t get_sdma_rlc_reg_offset(struct amdgpu_device *adev,
77 				unsigned int engine_id,
78 				unsigned int queue_id)
79 {
80 	uint32_t sdma_engine_reg_base = 0;
81 	uint32_t sdma_rlc_reg_offset;
82 
83 	switch (engine_id) {
84 	case 0:
85 		sdma_engine_reg_base = SOC15_REG_OFFSET(SDMA0, 0,
86 				regSDMA0_QUEUE0_RB_CNTL) - regSDMA0_QUEUE0_RB_CNTL;
87 		break;
88 	case 1:
89 		sdma_engine_reg_base = SOC15_REG_OFFSET(SDMA1, 0,
90 				regSDMA1_QUEUE0_RB_CNTL) - regSDMA0_QUEUE0_RB_CNTL;
91 		break;
92 	default:
93 		WARN(1, "Invalid SDMA engine id %d\n", engine_id);
94 		break;
95 	}
96 
97 	sdma_rlc_reg_offset = sdma_engine_reg_base
98 		+ queue_id * (regSDMA0_QUEUE1_RB_CNTL - regSDMA0_QUEUE0_RB_CNTL);
99 
100 	pr_debug("RLC register offset for SDMA%d RLC%d: 0x%x\n", engine_id,
101 			queue_id, sdma_rlc_reg_offset);
102 
103 	return sdma_rlc_reg_offset;
104 }
105 
106 static int hqd_dump_v12(struct amdgpu_device *adev,
107 			uint32_t pipe_id, uint32_t queue_id,
108 			uint32_t (**dump)[2], uint32_t *n_regs, uint32_t inst)
109 {
110 	uint32_t i = 0, reg;
111 #define HQD_N_REGS 56
112 #define DUMP_REG(addr) do {				\
113 		if (WARN_ON_ONCE(i >= HQD_N_REGS))	\
114 			break;				\
115 		(*dump)[i][0] = (addr) << 2;		\
116 		(*dump)[i++][1] = RREG32(addr);		\
117 	} while (0)
118 
119 	*dump = kmalloc_objs(**dump, HQD_N_REGS);
120 	if (*dump == NULL)
121 		return -ENOMEM;
122 
123 	acquire_queue(adev, pipe_id, queue_id);
124 
125 	for (reg = SOC15_REG_OFFSET(GC, 0, regCP_MQD_BASE_ADDR);
126 	     reg <= SOC15_REG_OFFSET(GC, 0, regCP_HQD_PQ_WPTR_HI); reg++)
127 		DUMP_REG(reg);
128 
129 	release_queue(adev);
130 
131 	WARN_ON_ONCE(i != HQD_N_REGS);
132 	*n_regs = i;
133 
134 	return 0;
135 }
136 
137 static int hqd_sdma_dump_v12(struct amdgpu_device *adev,
138 			     uint32_t engine_id, uint32_t queue_id,
139 			     uint32_t (**dump)[2], uint32_t *n_regs)
140 {
141 	uint32_t sdma_rlc_reg_offset = get_sdma_rlc_reg_offset(adev,
142 			engine_id, queue_id);
143 	uint32_t i = 0, reg;
144 
145 	const uint32_t first_reg = regSDMA0_QUEUE0_RB_CNTL;
146 	const uint32_t last_reg = regSDMA0_QUEUE0_CONTEXT_STATUS;
147 #undef HQD_N_REGS
148 #define HQD_N_REGS (last_reg - first_reg + 1)
149 
150 	*dump = kmalloc_objs(**dump, HQD_N_REGS);
151 	if (*dump == NULL)
152 		return -ENOMEM;
153 
154 	for (reg = first_reg;
155 	     reg <= last_reg; reg++)
156 		DUMP_REG(sdma_rlc_reg_offset + reg);
157 
158 	WARN_ON_ONCE(i != HQD_N_REGS);
159 	*n_regs = i;
160 
161 	return 0;
162 }
163 
164 static int wave_control_execute_v12(struct amdgpu_device *adev,
165 					uint32_t gfx_index_val,
166 					uint32_t sq_cmd, uint32_t inst)
167 {
168 	uint32_t data = 0;
169 
170 	mutex_lock(&adev->grbm_idx_mutex);
171 
172 	WREG32(SOC15_REG_OFFSET(GC, 0, regGRBM_GFX_INDEX), gfx_index_val);
173 	WREG32(SOC15_REG_OFFSET(GC, 0, regSQ_CMD), sq_cmd);
174 
175 	data = REG_SET_FIELD(data, GRBM_GFX_INDEX,
176 		INSTANCE_BROADCAST_WRITES, 1);
177 	data = REG_SET_FIELD(data, GRBM_GFX_INDEX,
178 		SA_BROADCAST_WRITES, 1);
179 	data = REG_SET_FIELD(data, GRBM_GFX_INDEX,
180 		SE_BROADCAST_WRITES, 1);
181 
182 	WREG32(SOC15_REG_OFFSET(GC, 0, regGRBM_GFX_INDEX), data);
183 	mutex_unlock(&adev->grbm_idx_mutex);
184 
185 	return 0;
186 }
187 
188 /* returns TRAP_EN, EXCP_EN and EXCP_REPLACE. */
189 static uint32_t kgd_gfx_v12_enable_debug_trap(struct amdgpu_device *adev,
190 					    bool restore_dbg_registers,
191 					    uint32_t vmid)
192 {
193 	uint32_t data = 0;
194 
195 	data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, TRAP_EN, 1);
196 	data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, EXCP_EN, 0);
197 	data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, EXCP_REPLACE, 0);
198 
199 	return data;
200 }
201 
202 /* returns TRAP_EN, EXCP_EN and EXCP_REPLACE. */
203 static uint32_t kgd_gfx_v12_disable_debug_trap(struct amdgpu_device *adev,
204 						bool keep_trap_enabled,
205 						uint32_t vmid)
206 {
207 	uint32_t data = 0;
208 
209 	data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, TRAP_EN, 1);
210 	data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, EXCP_EN, 0);
211 	data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, EXCP_REPLACE, 0);
212 
213 	return data;
214 }
215 
216 static int kgd_gfx_v12_validate_trap_override_request(struct amdgpu_device *adev,
217 							uint32_t trap_override,
218 							uint32_t *trap_mask_supported)
219 {
220 	*trap_mask_supported &= KFD_DBG_TRAP_MASK_FP_INVALID |
221 				KFD_DBG_TRAP_MASK_FP_INPUT_DENORMAL |
222 				KFD_DBG_TRAP_MASK_FP_DIVIDE_BY_ZERO |
223 				KFD_DBG_TRAP_MASK_FP_OVERFLOW |
224 				KFD_DBG_TRAP_MASK_FP_UNDERFLOW |
225 				KFD_DBG_TRAP_MASK_FP_INEXACT |
226 				KFD_DBG_TRAP_MASK_INT_DIVIDE_BY_ZERO |
227 				KFD_DBG_TRAP_MASK_DBG_ADDRESS_WATCH |
228 				KFD_DBG_TRAP_MASK_DBG_MEMORY_VIOLATION |
229 				KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_START |
230 				KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_END;
231 
232 
233 	if (trap_override != KFD_DBG_TRAP_OVERRIDE_OR &&
234 			trap_override != KFD_DBG_TRAP_OVERRIDE_REPLACE)
235 		return -EPERM;
236 
237 	return 0;
238 }
239 
240 static uint32_t trap_mask_map_sw_to_hw(uint32_t mask)
241 {
242 	uint32_t trap_on_start = (mask & KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_START) ? 1 : 0;
243 	uint32_t trap_on_end = (mask & KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_END) ? 1 : 0;
244 	uint32_t excp_en = mask & (KFD_DBG_TRAP_MASK_FP_INVALID |
245 			KFD_DBG_TRAP_MASK_FP_INPUT_DENORMAL |
246 			KFD_DBG_TRAP_MASK_FP_DIVIDE_BY_ZERO |
247 			KFD_DBG_TRAP_MASK_FP_OVERFLOW |
248 			KFD_DBG_TRAP_MASK_FP_UNDERFLOW |
249 			KFD_DBG_TRAP_MASK_FP_INEXACT |
250 			KFD_DBG_TRAP_MASK_INT_DIVIDE_BY_ZERO |
251 			KFD_DBG_TRAP_MASK_DBG_ADDRESS_WATCH |
252 			KFD_DBG_TRAP_MASK_DBG_MEMORY_VIOLATION);
253 	uint32_t ret;
254 
255 	ret = REG_SET_FIELD(0, SPI_GDBG_PER_VMID_CNTL, EXCP_EN, excp_en);
256 	ret = REG_SET_FIELD(ret, SPI_GDBG_PER_VMID_CNTL, TRAP_ON_START, trap_on_start);
257 	ret = REG_SET_FIELD(ret, SPI_GDBG_PER_VMID_CNTL, TRAP_ON_END, trap_on_end);
258 
259 	return ret;
260 }
261 
262 static uint32_t trap_mask_map_hw_to_sw(uint32_t mask)
263 {
264 	uint32_t ret = REG_GET_FIELD(mask, SPI_GDBG_PER_VMID_CNTL, EXCP_EN);
265 
266 	if (REG_GET_FIELD(mask, SPI_GDBG_PER_VMID_CNTL, TRAP_ON_START))
267 		ret |= KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_START;
268 
269 	if (REG_GET_FIELD(mask, SPI_GDBG_PER_VMID_CNTL, TRAP_ON_END))
270 		ret |= KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_END;
271 
272 	return ret;
273 }
274 
275 /* returns TRAP_EN, EXCP_EN and EXCP_REPLACE. */
276 static uint32_t kgd_gfx_v12_set_wave_launch_trap_override(struct amdgpu_device *adev,
277 					uint32_t vmid,
278 					uint32_t trap_override,
279 					uint32_t trap_mask_bits,
280 					uint32_t trap_mask_request,
281 					uint32_t *trap_mask_prev,
282 					uint32_t kfd_dbg_trap_cntl_prev)
283 
284 {
285 	uint32_t data = 0;
286 
287 	*trap_mask_prev = trap_mask_map_hw_to_sw(kfd_dbg_trap_cntl_prev);
288 
289 	data = (trap_mask_bits & trap_mask_request) | (*trap_mask_prev & ~trap_mask_request);
290 	data = trap_mask_map_sw_to_hw(data);
291 
292 	data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, TRAP_EN, 1);
293 	data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, EXCP_REPLACE, trap_override);
294 
295 	return data;
296 }
297 
298 /* returns STALL_VMID or LAUNCH_MODE. */
299 static uint32_t kgd_gfx_v12_set_wave_launch_mode(struct amdgpu_device *adev,
300 					uint8_t wave_launch_mode,
301 					uint32_t vmid)
302 {
303 	uint32_t data = 0;
304 	bool is_stall_mode = wave_launch_mode == 4;
305 
306 	if (is_stall_mode)
307 		data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, STALL_VMID,
308 									1);
309 	else
310 		data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, LAUNCH_MODE,
311 							wave_launch_mode);
312 
313 	return data;
314 }
315 
316 #define TCP_WATCH_STRIDE (regTCP_WATCH1_ADDR_H - regTCP_WATCH0_ADDR_H)
317 static uint32_t kgd_gfx_v12_set_address_watch(struct amdgpu_device *adev,
318 					uint64_t watch_address,
319 					uint32_t watch_address_mask,
320 					uint32_t watch_id,
321 					uint32_t watch_mode,
322 					uint32_t debug_vmid,
323 					uint32_t inst)
324 {
325 	uint32_t watch_address_high;
326 	uint32_t watch_address_low;
327 	uint32_t watch_address_cntl;
328 
329 	watch_address_cntl = 0;
330 	watch_address_low = lower_32_bits(watch_address);
331 	watch_address_high = upper_32_bits(watch_address) & 0xffff;
332 
333 	watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
334 			TCP_WATCH0_CNTL,
335 			MODE,
336 			watch_mode);
337 
338 	watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
339 			TCP_WATCH0_CNTL,
340 			MASK,
341 			watch_address_mask >> 7);
342 
343 	watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
344 			TCP_WATCH0_CNTL,
345 			VALID,
346 			1);
347 
348 	WREG32_RLC((SOC15_REG_OFFSET(GC, 0, regTCP_WATCH0_ADDR_H) +
349 			(watch_id * TCP_WATCH_STRIDE)),
350 			watch_address_high);
351 
352 	WREG32_RLC((SOC15_REG_OFFSET(GC, 0, regTCP_WATCH0_ADDR_L) +
353 			(watch_id * TCP_WATCH_STRIDE)),
354 			watch_address_low);
355 
356 	return watch_address_cntl;
357 }
358 
359 static uint32_t kgd_gfx_v12_clear_address_watch(struct amdgpu_device *adev,
360 					uint32_t watch_id)
361 {
362 	return 0;
363 }
364 
365 static uint32_t kgd_gfx_v12_hqd_sdma_get_doorbell(struct amdgpu_device *adev,
366 						 int engine, int queue)
367 {
368 	return 0;
369 }
370 
371 const struct kfd2kgd_calls gfx_v12_kfd2kgd = {
372 	.init_interrupts = init_interrupts_v12,
373 	.hqd_dump = hqd_dump_v12,
374 	.hqd_sdma_dump = hqd_sdma_dump_v12,
375 	.wave_control_execute = wave_control_execute_v12,
376 	.get_atc_vmid_pasid_mapping_info = NULL,
377 	.enable_debug_trap = kgd_gfx_v12_enable_debug_trap,
378 	.disable_debug_trap = kgd_gfx_v12_disable_debug_trap,
379 	.validate_trap_override_request = kgd_gfx_v12_validate_trap_override_request,
380 	.set_wave_launch_trap_override = kgd_gfx_v12_set_wave_launch_trap_override,
381 	.set_wave_launch_mode = kgd_gfx_v12_set_wave_launch_mode,
382 	.set_address_watch = kgd_gfx_v12_set_address_watch,
383 	.clear_address_watch = kgd_gfx_v12_clear_address_watch,
384 	.hqd_sdma_get_doorbell = kgd_gfx_v12_hqd_sdma_get_doorbell
385 };
386