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
lock_srbm(struct amdgpu_device * adev,uint32_t mec,uint32_t pipe,uint32_t queue,uint32_t vmid)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
unlock_srbm(struct amdgpu_device * adev)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
acquire_queue(struct amdgpu_device * adev,uint32_t pipe_id,uint32_t queue_id)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
release_queue(struct amdgpu_device * adev)52 static void release_queue(struct amdgpu_device *adev)
53 {
54 unlock_srbm(adev);
55 }
56
init_interrupts_v12(struct amdgpu_device * adev,uint32_t pipe_id,uint32_t inst)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
get_sdma_rlc_reg_offset(struct amdgpu_device * adev,unsigned int engine_id,unsigned int queue_id)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
hqd_dump_v12(struct amdgpu_device * adev,uint32_t pipe_id,uint32_t queue_id,uint32_t (** dump)[2],uint32_t * n_regs,uint32_t inst)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
hqd_sdma_dump_v12(struct amdgpu_device * adev,uint32_t engine_id,uint32_t queue_id,uint32_t (** dump)[2],uint32_t * n_regs)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
wave_control_execute_v12(struct amdgpu_device * adev,uint32_t gfx_index_val,uint32_t sq_cmd,uint32_t inst)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. */
kgd_gfx_v12_enable_debug_trap(struct amdgpu_device * adev,bool restore_dbg_registers,uint32_t vmid)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. */
kgd_gfx_v12_disable_debug_trap(struct amdgpu_device * adev,bool keep_trap_enabled,uint32_t vmid)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
kgd_gfx_v12_validate_trap_override_request(struct amdgpu_device * adev,uint32_t trap_override,uint32_t * trap_mask_supported)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
trap_mask_map_sw_to_hw(uint32_t mask)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
trap_mask_map_hw_to_sw(uint32_t mask)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. */
kgd_gfx_v12_set_wave_launch_trap_override(struct amdgpu_device * adev,uint32_t vmid,uint32_t trap_override,uint32_t trap_mask_bits,uint32_t trap_mask_request,uint32_t * trap_mask_prev,uint32_t kfd_dbg_trap_cntl_prev)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. */
kgd_gfx_v12_set_wave_launch_mode(struct amdgpu_device * adev,uint8_t wave_launch_mode,uint32_t vmid)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)
kgd_gfx_v12_set_address_watch(struct amdgpu_device * adev,uint64_t watch_address,uint32_t watch_address_mask,uint32_t watch_id,uint32_t watch_mode,uint32_t debug_vmid,uint32_t inst)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
kgd_gfx_v12_clear_address_watch(struct amdgpu_device * adev,uint32_t watch_id)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
kgd_gfx_v12_hqd_sdma_get_doorbell(struct amdgpu_device * adev,int engine,int queue)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
lock_spi_csq_mutexes(struct amdgpu_device * adev)371 static void lock_spi_csq_mutexes(struct amdgpu_device *adev)
372 {
373 mutex_lock(&adev->srbm_mutex);
374 mutex_lock(&adev->grbm_idx_mutex);
375
376 }
377
unlock_spi_csq_mutexes(struct amdgpu_device * adev)378 static void unlock_spi_csq_mutexes(struct amdgpu_device *adev)
379 {
380 mutex_unlock(&adev->grbm_idx_mutex);
381 mutex_unlock(&adev->srbm_mutex);
382 }
383
384 /**
385 * get_wave_count: Read device registers to get number of waves in flight for
386 * a particular queue. The method also returns the doorbell offset associated
387 * with the queue.
388 *
389 * @adev: Handle of device whose registers are to be read
390 * @queue_idx: Index of queue in the queue-map bit-field
391 * @queue_cnt: Stores the wave count and doorbell offset for an active queue
392 * @inst: xcc's instance number on a multi-XCC setup
393 */
get_wave_count(struct amdgpu_device * adev,int queue_idx,struct kfd_cu_occupancy * queue_cnt,uint32_t inst)394 static void get_wave_count(struct amdgpu_device *adev, int queue_idx,
395 struct kfd_cu_occupancy *queue_cnt, uint32_t inst)
396 {
397 int pipe_idx;
398 int queue_slot;
399 unsigned int reg_val;
400 unsigned int wave_cnt;
401 /*
402 * Program GRBM with appropriate MEID, PIPEID, QUEUEID and VMID
403 * parameters to read out waves in flight. Get doorbell offset if there are
404 * non-zero waves in flight.
405 */
406 pipe_idx = queue_idx / adev->gfx.mec.num_queue_per_pipe;
407 queue_slot = queue_idx % adev->gfx.mec.num_queue_per_pipe;
408 soc24_grbm_select(adev, 1, pipe_idx, queue_slot, 0);
409 reg_val = RREG32_SOC15_IP(GC, SOC15_REG_OFFSET(GC, 0,
410 regSPI_CSQ_WF_ACTIVE_COUNT_0) + queue_slot);
411 wave_cnt = reg_val & SPI_CSQ_WF_ACTIVE_COUNT_0__COUNT_MASK;
412 if (wave_cnt != 0) {
413 queue_cnt->wave_cnt += wave_cnt;
414 queue_cnt->doorbell_off =
415 (RREG32_SOC15(GC, 0, regCP_HQD_PQ_DOORBELL_CONTROL) &
416 CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET_MASK) >>
417 CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT;
418 }
419 }
420
421 /**
422 * kgd_gfx_v12_get_cu_occupancy: Reads relevant registers associated with each
423 * shader engine and aggregates the number of waves that are in flight for the
424 * process whose pasid is provided as a parameter. The process could have ZERO
425 * or more queues running and submitting waves to compute units.
426 *
427 * @adev: Handle of device from which to get number of waves in flight
428 * @cu_occupancy: Array that gets filled with wave_cnt and doorbell offset
429 * for comparison later.
430 * @max_waves_per_cu: Output parameter updated with maximum number of waves
431 * possible per Compute Unit
432 * @inst: xcc's instance number on a multi-XCC setup
433 *
434 * Note: It's possible that the device has too many queues (oversubscription)
435 * in which case a VMID could be remapped to a different PASID. This could lead
436 * to an inaccurate wave count. Following is a high-level sequence:
437 * Time T1: vmid = getVmid(); vmid is associated with Pasid P1
438 * Time T2: passId = getPasId(vmid); vmid is associated with Pasid P2
439 * In the sequence above wave count obtained from time T1 will be incorrectly
440 * lost or added to total wave count.
441 *
442 * The registers that provide the waves in flight are:
443 *
444 * SPI_CSQ_WF_ACTIVE_STATUS - bit-map of queues per pipe. The bit is ON if a
445 * queue is slotted, OFF if there is no queue. A process could have ZERO or
446 * more queues slotted and submitting waves to be run on compute units. Even
447 * when there is a queue it is possible there could be zero wave fronts, this
448 * can happen when queue is waiting on top-of-pipe events - e.g. waitRegMem
449 * command
450 *
451 * For each bit that is ON from above:
452 *
453 * Read (SPI_CSQ_WF_ACTIVE_COUNT_0 + queue_idx) register. It provides the
454 * number of waves that are in flight for the queue at specified index. The
455 * index ranges from 0 to 7.
456 *
457 * If non-zero waves are in flight, store the corresponding doorbell offset
458 * of the queue, along with the wave count.
459 *
460 * Determine if the queue belongs to the process by comparing the doorbell
461 * offset against the process's queues. If it matches, aggregate the wave
462 * count for the process.
463 *
464 * Reading registers referenced above involves programming GRBM appropriately
465 */
kgd_gfx_v12_get_cu_occupancy(struct amdgpu_device * adev,struct kfd_cu_occupancy * cu_occupancy,int * max_waves_per_cu,uint32_t inst)466 static void kgd_gfx_v12_get_cu_occupancy(struct amdgpu_device *adev,
467 struct kfd_cu_occupancy *cu_occupancy,
468 int *max_waves_per_cu, uint32_t inst)
469 {
470 int qidx;
471 int se_idx;
472 int se_cnt;
473 int queue_map;
474 int max_queue_cnt;
475 DECLARE_BITMAP(cp_queue_bitmap, AMDGPU_MAX_QUEUES);
476
477 lock_spi_csq_mutexes(adev);
478 soc24_grbm_select(adev, 1, 0, 0, 0);
479
480 /*
481 * Iterate through the shader engines and arrays of the device
482 * to get number of waves in flight
483 */
484 bitmap_complement(cp_queue_bitmap, adev->gfx.mec_bitmap[0].queue_bitmap,
485 AMDGPU_MAX_QUEUES);
486 max_queue_cnt = adev->gfx.mec.num_pipe_per_mec *
487 adev->gfx.mec.num_queue_per_pipe;
488 se_cnt = adev->gfx.config.max_shader_engines;
489 for (se_idx = 0; se_idx < se_cnt; se_idx++) {
490 amdgpu_gfx_select_se_sh(adev, se_idx, 0, 0xffffffff, inst);
491 queue_map = RREG32_SOC15(GC, 0,
492 regSPI_CSQ_WF_ACTIVE_STATUS);
493
494 for (qidx = 0; qidx < max_queue_cnt; qidx++) {
495 /* Skip queues that are not associated with
496 * compute functions
497 */
498 if (!test_bit(qidx, cp_queue_bitmap))
499 continue;
500
501 if (!(queue_map & (1 << qidx)))
502 continue;
503
504 /* Get number of waves in flight and aggregate them */
505 get_wave_count(adev, qidx, &cu_occupancy[qidx], inst);
506 }
507 }
508
509 amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff, inst);
510 soc24_grbm_select(adev, 0, 0, 0, 0);
511 unlock_spi_csq_mutexes(adev);
512
513 /* Update the output parameters and return */
514 *max_waves_per_cu = adev->gfx.cu_info.simd_per_cu *
515 adev->gfx.cu_info.max_waves_per_simd;
516 }
517
518 const struct kfd2kgd_calls gfx_v12_kfd2kgd = {
519 .init_interrupts = init_interrupts_v12,
520 .hqd_dump = hqd_dump_v12,
521 .hqd_sdma_dump = hqd_sdma_dump_v12,
522 .wave_control_execute = wave_control_execute_v12,
523 .get_atc_vmid_pasid_mapping_info = NULL,
524 .enable_debug_trap = kgd_gfx_v12_enable_debug_trap,
525 .disable_debug_trap = kgd_gfx_v12_disable_debug_trap,
526 .validate_trap_override_request = kgd_gfx_v12_validate_trap_override_request,
527 .set_wave_launch_trap_override = kgd_gfx_v12_set_wave_launch_trap_override,
528 .set_wave_launch_mode = kgd_gfx_v12_set_wave_launch_mode,
529 .set_address_watch = kgd_gfx_v12_set_address_watch,
530 .clear_address_watch = kgd_gfx_v12_clear_address_watch,
531 .hqd_sdma_get_doorbell = kgd_gfx_v12_hqd_sdma_get_doorbell,
532 .get_cu_occupancy = kgd_gfx_v12_get_cu_occupancy,
533 };
534