Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdkfd: fix support for trap on wave start and end for gfx12

Similar to GFX11, GFX12 supports trapping on wave start and end.

Signed-off-by: Jonathan Kim <jonathan.kim@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Jonathan Kim and committed by
Alex Deucher
984b265f fda3f378

+43 -5
+43 -5
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v12.c
··· 224 224 KFD_DBG_TRAP_MASK_FP_INEXACT | 225 225 KFD_DBG_TRAP_MASK_INT_DIVIDE_BY_ZERO | 226 226 KFD_DBG_TRAP_MASK_DBG_ADDRESS_WATCH | 227 - KFD_DBG_TRAP_MASK_DBG_MEMORY_VIOLATION; 227 + KFD_DBG_TRAP_MASK_DBG_MEMORY_VIOLATION | 228 + KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_START | 229 + KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_END; 230 + 228 231 229 232 if (trap_override != KFD_DBG_TRAP_OVERRIDE_OR && 230 233 trap_override != KFD_DBG_TRAP_OVERRIDE_REPLACE) 231 234 return -EPERM; 232 235 233 236 return 0; 237 + } 238 + 239 + static uint32_t trap_mask_map_sw_to_hw(uint32_t mask) 240 + { 241 + uint32_t trap_on_start = (mask & KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_START) ? 1 : 0; 242 + uint32_t trap_on_end = (mask & KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_END) ? 1 : 0; 243 + uint32_t excp_en = mask & (KFD_DBG_TRAP_MASK_FP_INVALID | 244 + KFD_DBG_TRAP_MASK_FP_INPUT_DENORMAL | 245 + KFD_DBG_TRAP_MASK_FP_DIVIDE_BY_ZERO | 246 + KFD_DBG_TRAP_MASK_FP_OVERFLOW | 247 + KFD_DBG_TRAP_MASK_FP_UNDERFLOW | 248 + KFD_DBG_TRAP_MASK_FP_INEXACT | 249 + KFD_DBG_TRAP_MASK_INT_DIVIDE_BY_ZERO | 250 + KFD_DBG_TRAP_MASK_DBG_ADDRESS_WATCH | 251 + KFD_DBG_TRAP_MASK_DBG_MEMORY_VIOLATION); 252 + uint32_t ret; 253 + 254 + ret = REG_SET_FIELD(0, SPI_GDBG_PER_VMID_CNTL, EXCP_EN, excp_en); 255 + ret = REG_SET_FIELD(ret, SPI_GDBG_PER_VMID_CNTL, TRAP_ON_START, trap_on_start); 256 + ret = REG_SET_FIELD(ret, SPI_GDBG_PER_VMID_CNTL, TRAP_ON_END, trap_on_end); 257 + 258 + return ret; 259 + } 260 + 261 + static uint32_t trap_mask_map_hw_to_sw(uint32_t mask) 262 + { 263 + uint32_t ret = REG_GET_FIELD(mask, SPI_GDBG_PER_VMID_CNTL, EXCP_EN); 264 + 265 + if (REG_GET_FIELD(mask, SPI_GDBG_PER_VMID_CNTL, TRAP_ON_START)) 266 + ret |= KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_START; 267 + 268 + if (REG_GET_FIELD(mask, SPI_GDBG_PER_VMID_CNTL, TRAP_ON_END)) 269 + ret |= KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_END; 270 + 271 + return ret; 234 272 } 235 273 236 274 /* returns TRAP_EN, EXCP_EN and EXCP_REPLACE. */ ··· 283 245 { 284 246 uint32_t data = 0; 285 247 286 - *trap_mask_prev = REG_GET_FIELD(kfd_dbg_trap_cntl_prev, SPI_GDBG_PER_VMID_CNTL, EXCP_EN); 287 - trap_mask_bits = (trap_mask_bits & trap_mask_request) | 288 - (*trap_mask_prev & ~trap_mask_request); 248 + *trap_mask_prev = trap_mask_map_hw_to_sw(kfd_dbg_trap_cntl_prev); 249 + 250 + data = (trap_mask_bits & trap_mask_request) | (*trap_mask_prev & ~trap_mask_request); 251 + data = trap_mask_map_sw_to_hw(data); 289 252 290 253 data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, TRAP_EN, 1); 291 - data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, EXCP_EN, trap_mask_bits); 292 254 data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, EXCP_REPLACE, trap_override); 293 255 294 256 return data;