mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 02:44:41 +01:00
drm/amdgpu: Clear overflow for SRIOV
For VF, it doesn't have the permission to clear overflow, clear the bit by reset. Signed-off-by: Emily Deng <Emily.Deng@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
fb20954c97
commit
5ae4591f4e
4 changed files with 24 additions and 4 deletions
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_ih.h"
|
||||
#include "amdgpu_reset.h"
|
||||
|
||||
/**
|
||||
* amdgpu_ih_ring_init - initialize the IH state
|
||||
|
|
@ -227,13 +228,23 @@ restart_ih:
|
|||
ih->rptr &= ih->ptr_mask;
|
||||
}
|
||||
|
||||
amdgpu_ih_set_rptr(adev, ih);
|
||||
if (!ih->overflow)
|
||||
amdgpu_ih_set_rptr(adev, ih);
|
||||
|
||||
wake_up_all(&ih->wait_process);
|
||||
|
||||
/* make sure wptr hasn't changed while processing */
|
||||
wptr = amdgpu_ih_get_wptr(adev, ih);
|
||||
if (wptr != ih->rptr)
|
||||
goto restart_ih;
|
||||
if (!ih->overflow)
|
||||
goto restart_ih;
|
||||
|
||||
if (ih->overflow)
|
||||
if (amdgpu_sriov_runtime(adev))
|
||||
WARN_ONCE(!amdgpu_reset_domain_schedule(adev->reset_domain,
|
||||
&adev->virt.flr_work),
|
||||
"Failed to queue work! at %s",
|
||||
__func__);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ struct amdgpu_ih_ring {
|
|||
/* For waiting on IH processing at checkpoint. */
|
||||
wait_queue_head_t wait_process;
|
||||
uint64_t processed_timestamp;
|
||||
bool overflow;
|
||||
};
|
||||
|
||||
/* return true if time stamp t2 is after t1 with 48bit wrap around */
|
||||
|
|
|
|||
|
|
@ -349,6 +349,7 @@ static int ih_v6_0_irq_init(struct amdgpu_device *adev)
|
|||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
ih[i]->overflow = false;
|
||||
}
|
||||
|
||||
/* update doorbell range for ih ring 0 */
|
||||
|
|
@ -446,7 +447,10 @@ static u32 ih_v6_0_get_wptr(struct amdgpu_device *adev,
|
|||
wptr = RREG32_NO_KIQ(ih_regs->ih_rb_wptr);
|
||||
if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
|
||||
goto out;
|
||||
wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
|
||||
else
|
||||
ih->overflow = true;
|
||||
|
||||
/* When a ring buffer overflow happen start parsing interrupt
|
||||
* from the last not overwritten vector (wptr + 32). Hopefully
|
||||
|
|
|
|||
|
|
@ -350,6 +350,7 @@ static int vega20_ih_irq_init(struct amdgpu_device *adev)
|
|||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
ih[i]->overflow = false;
|
||||
}
|
||||
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
|
|
@ -437,7 +438,10 @@ static u32 vega20_ih_get_wptr(struct amdgpu_device *adev,
|
|||
if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
|
||||
goto out;
|
||||
|
||||
wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
|
||||
else
|
||||
ih->overflow = true;
|
||||
|
||||
/* When a ring buffer overflow happen start parsing interrupt
|
||||
* from the last not overwritten vector (wptr + 32). Hopefully
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue