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