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

drm/amdgpu: use GPU_HDP_FLUSH for sriov

Currently SRIOV runtime will use kiq to write HDP_MEM_FLUSH_CNTL for
hdp flush. This register need to be write from CPU for nbif to aware,
otherwise it will not work.

Implement amdgpu_kiq_hdp_flush and use kiq to do gpu hdp flush during
sriov runtime.

v2:
- fallback to amdgpu_asic_flush_hdp when amdgpu_kiq_hdp_flush failed
- add function amdgpu_mes_hdp_flush

v3:
- changed returned error

Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Victor Zhao <Victor.Zhao@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Victor Zhao and committed by
Alex Deucher
6169b555 e71ca1ef

+95 -3
+10 -3
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
··· 7315 7315 if (adev->gmc.xgmi.connected_to_cpu) 7316 7316 return; 7317 7317 7318 - if (ring && ring->funcs->emit_hdp_flush) 7318 + if (ring && ring->funcs->emit_hdp_flush) { 7319 7319 amdgpu_ring_emit_hdp_flush(ring); 7320 - else 7321 - amdgpu_asic_flush_hdp(adev, ring); 7320 + return; 7321 + } 7322 + 7323 + if (!ring && amdgpu_sriov_runtime(adev)) { 7324 + if (!amdgpu_kiq_hdp_flush(adev)) 7325 + return; 7326 + } 7327 + 7328 + amdgpu_asic_flush_hdp(adev, ring); 7322 7329 } 7323 7330 7324 7331 void amdgpu_device_invalidate_hdp(struct amdgpu_device *adev,
+71
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
··· 33 33 #include "amdgpu_reset.h" 34 34 #include "amdgpu_xcp.h" 35 35 #include "amdgpu_xgmi.h" 36 + #include "amdgpu_mes.h" 36 37 #include "nvd.h" 37 38 38 39 /* delay 0.1 second to enable gfx off feature */ ··· 1193 1192 spin_unlock_irqrestore(&kiq->ring_lock, flags); 1194 1193 failed_kiq_write: 1195 1194 dev_err(adev->dev, "failed to write reg:%x\n", reg); 1195 + } 1196 + 1197 + int amdgpu_kiq_hdp_flush(struct amdgpu_device *adev) 1198 + { 1199 + signed long r, cnt = 0; 1200 + unsigned long flags; 1201 + uint32_t seq; 1202 + struct amdgpu_kiq *kiq = &adev->gfx.kiq[0]; 1203 + struct amdgpu_ring *ring = &kiq->ring; 1204 + 1205 + if (amdgpu_device_skip_hw_access(adev)) 1206 + return 0; 1207 + 1208 + if (adev->enable_mes_kiq && adev->mes.ring[0].sched.ready) 1209 + return amdgpu_mes_hdp_flush(adev); 1210 + 1211 + if (!ring->funcs->emit_hdp_flush) { 1212 + return -EOPNOTSUPP; 1213 + } 1214 + 1215 + spin_lock_irqsave(&kiq->ring_lock, flags); 1216 + r = amdgpu_ring_alloc(ring, 32); 1217 + if (r) 1218 + goto failed_unlock; 1219 + 1220 + amdgpu_ring_emit_hdp_flush(ring); 1221 + r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT); 1222 + if (r) 1223 + goto failed_undo; 1224 + 1225 + amdgpu_ring_commit(ring); 1226 + spin_unlock_irqrestore(&kiq->ring_lock, flags); 1227 + 1228 + r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); 1229 + 1230 + /* don't wait anymore for gpu reset case because this way may 1231 + * block gpu_recover() routine forever, e.g. this virt_kiq_rreg 1232 + * is triggered in TTM and ttm_bo_lock_delayed_workqueue() will 1233 + * never return if we keep waiting in virt_kiq_rreg, which cause 1234 + * gpu_recover() hang there. 1235 + * 1236 + * also don't wait anymore for IRQ context 1237 + * */ 1238 + if (r < 1 && (amdgpu_in_reset(adev) || in_interrupt())) 1239 + goto failed_kiq_hdp_flush; 1240 + 1241 + might_sleep(); 1242 + while (r < 1 && cnt++ < MAX_KIQ_REG_TRY) { 1243 + if (amdgpu_in_reset(adev)) 1244 + goto failed_kiq_hdp_flush; 1245 + 1246 + msleep(MAX_KIQ_REG_BAILOUT_INTERVAL); 1247 + r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); 1248 + } 1249 + 1250 + if (cnt > MAX_KIQ_REG_TRY) { 1251 + dev_err(adev->dev, "failed to flush HDP via KIQ timeout\n"); 1252 + return -ETIMEDOUT; 1253 + } 1254 + 1255 + return 0; 1256 + 1257 + failed_undo: 1258 + amdgpu_ring_undo(ring); 1259 + failed_unlock: 1260 + spin_unlock_irqrestore(&kiq->ring_lock, flags); 1261 + failed_kiq_hdp_flush: 1262 + dev_err(adev->dev, "failed to flush HDP via KIQ\n"); 1263 + return r < 0 ? r : -EIO; 1196 1264 } 1197 1265 1198 1266 int amdgpu_gfx_get_num_kcq(struct amdgpu_device *adev) ··· 2555 2485 &amdgpu_debugfs_compute_sched_mask_fops); 2556 2486 #endif 2557 2487 } 2488 +
+1
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
··· 615 615 struct amdgpu_iv_entry *entry); 616 616 uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg, uint32_t xcc_id); 617 617 void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, uint32_t xcc_id); 618 + int amdgpu_kiq_hdp_flush(struct amdgpu_device *adev); 618 619 int amdgpu_gfx_get_num_kcq(struct amdgpu_device *adev); 619 620 void amdgpu_gfx_cp_init_microcode(struct amdgpu_device *adev, uint32_t ucode_id); 620 621
+12
drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
··· 528 528 return r; 529 529 } 530 530 531 + int amdgpu_mes_hdp_flush(struct amdgpu_device *adev) 532 + { 533 + uint32_t hdp_flush_req_offset, hdp_flush_done_offset, ref_and_mask; 534 + 535 + hdp_flush_req_offset = adev->nbio.funcs->get_hdp_flush_req_offset(adev); 536 + hdp_flush_done_offset = adev->nbio.funcs->get_hdp_flush_done_offset(adev); 537 + ref_and_mask = adev->nbio.hdp_flush_reg->ref_and_mask_cp0; 538 + 539 + return amdgpu_mes_reg_write_reg_wait(adev, hdp_flush_req_offset, hdp_flush_done_offset, 540 + ref_and_mask, ref_and_mask); 541 + } 542 + 531 543 int amdgpu_mes_set_shader_debugger(struct amdgpu_device *adev, 532 544 uint64_t process_context_addr, 533 545 uint32_t spi_gdbg_per_vmid_cntl,
+1
drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
··· 429 429 int amdgpu_mes_reg_write_reg_wait(struct amdgpu_device *adev, 430 430 uint32_t reg0, uint32_t reg1, 431 431 uint32_t ref, uint32_t mask); 432 + int amdgpu_mes_hdp_flush(struct amdgpu_device *adev); 432 433 int amdgpu_mes_set_shader_debugger(struct amdgpu_device *adev, 433 434 uint64_t process_context_addr, 434 435 uint32_t spi_gdbg_per_vmid_cntl,