diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/vega10_ih.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c index 1b2f69a9a24e..8d89ab7f0ae8 100644 --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include "soc15_common.h" | 31 | #include "soc15_common.h" |
32 | #include "vega10_ih.h" | 32 | #include "vega10_ih.h" |
33 | 33 | ||
34 | 34 | #define MAX_REARM_RETRY 10 | |
35 | 35 | ||
36 | static void vega10_ih_set_interrupt_funcs(struct amdgpu_device *adev); | 36 | static void vega10_ih_set_interrupt_funcs(struct amdgpu_device *adev); |
37 | 37 | ||
@@ -382,6 +382,38 @@ static void vega10_ih_decode_iv(struct amdgpu_device *adev, | |||
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 | * vega10_ih_set_rptr - set the IH ring buffer rptr | 417 | * vega10_ih_set_rptr - set the IH ring buffer rptr |
386 | * | 418 | * |
387 | * @adev: amdgpu_device pointer | 419 | * @adev: amdgpu_device pointer |
@@ -395,6 +427,9 @@ static void vega10_ih_set_rptr(struct amdgpu_device *adev, | |||
395 | /* XXX check if swapping is necessary on BE */ | 427 | /* XXX check if swapping is necessary on BE */ |
396 | *ih->rptr_cpu = ih->rptr; | 428 | *ih->rptr_cpu = ih->rptr; |
397 | WDOORBELL32(ih->doorbell_index, ih->rptr); | 429 | WDOORBELL32(ih->doorbell_index, ih->rptr); |
430 | |||
431 | if (amdgpu_sriov_vf(adev)) | ||
432 | vega10_ih_irq_rearm(adev, ih); | ||
398 | } else if (ih == &adev->irq.ih) { | 433 | } else if (ih == &adev->irq.ih) { |
399 | WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr); | 434 | WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr); |
400 | } else if (ih == &adev->irq.ih1) { | 435 | } else if (ih == &adev->irq.ih1) { |