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

drm/amdgpu: Rearm IRQ in Vega10 SR-IOV if IRQ lost

In Multi-VFs stress test, sometimes we see IRQ lost when running
benchmark, just rearm it.

Signed-off-by: Trigger Huang <Trigger.Huang@amd.com>
Acked-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Trigger Huang and committed by
Alex Deucher
74dcfe74 bdb1ccb0

+36 -1
+36 -1
drivers/gpu/drm/amd/amdgpu/vega10_ih.c
··· 31 31 #include "soc15_common.h" 32 32 #include "vega10_ih.h" 33 33 34 - 34 + #define MAX_REARM_RETRY 10 35 35 36 36 static void vega10_ih_set_interrupt_funcs(struct amdgpu_device *adev); 37 37 ··· 382 382 } 383 383 384 384 /** 385 + * vega10_ih_irq_rearm - rearm IRQ if lost 386 + * 387 + * @adev: amdgpu_device pointer 388 + * 389 + */ 390 + static void vega10_ih_irq_rearm(struct amdgpu_device *adev, 391 + struct amdgpu_ih_ring *ih) 392 + { 393 + uint32_t reg_rptr = 0; 394 + uint32_t v = 0; 395 + uint32_t i = 0; 396 + 397 + if (ih == &adev->irq.ih) 398 + reg_rptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_RPTR); 399 + else if (ih == &adev->irq.ih1) 400 + reg_rptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_RPTR_RING1); 401 + else if (ih == &adev->irq.ih2) 402 + reg_rptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_RPTR_RING2); 403 + else 404 + return; 405 + 406 + /* Rearm IRQ / re-wwrite doorbell if doorbell write is lost */ 407 + for (i = 0; i < MAX_REARM_RETRY; i++) { 408 + v = RREG32_NO_KIQ(reg_rptr); 409 + if ((v < ih->ring_size) && (v != ih->rptr)) 410 + WDOORBELL32(ih->doorbell_index, ih->rptr); 411 + else 412 + break; 413 + } 414 + } 415 + 416 + /** 385 417 * vega10_ih_set_rptr - set the IH ring buffer rptr 386 418 * 387 419 * @adev: amdgpu_device pointer ··· 427 395 /* XXX check if swapping is necessary on BE */ 428 396 *ih->rptr_cpu = ih->rptr; 429 397 WDOORBELL32(ih->doorbell_index, ih->rptr); 398 + 399 + if (amdgpu_sriov_vf(adev)) 400 + vega10_ih_irq_rearm(adev, ih); 430 401 } else if (ih == &adev->irq.ih) { 431 402 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr); 432 403 } else if (ih == &adev->irq.ih1) {