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) { |
