mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 11:19:37 +00:00
drm/amdgpu: Add prescreening stage in IH processing (v2)
To filter out high-frequency interrupts that can be safely ignored. v2: squash in trivial typo fix for si (Alex) Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
d2791c4563
commit
00ecd8a27c
8 changed files with 92 additions and 0 deletions
|
@ -334,6 +334,7 @@ struct amdgpu_gart_funcs {
|
|||
struct amdgpu_ih_funcs {
|
||||
/* ring read/write ptr handling, called from interrupt context */
|
||||
u32 (*get_wptr)(struct amdgpu_device *adev);
|
||||
bool (*prescreen_iv)(struct amdgpu_device *adev);
|
||||
void (*decode_iv)(struct amdgpu_device *adev,
|
||||
struct amdgpu_iv_entry *entry);
|
||||
void (*set_rptr)(struct amdgpu_device *adev);
|
||||
|
@ -1749,6 +1750,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
|
|||
#define amdgpu_ring_init_cond_exec(r) (r)->funcs->init_cond_exec((r))
|
||||
#define amdgpu_ring_patch_cond_exec(r,o) (r)->funcs->patch_cond_exec((r),(o))
|
||||
#define amdgpu_ih_get_wptr(adev) (adev)->irq.ih_funcs->get_wptr((adev))
|
||||
#define amdgpu_ih_prescreen_iv(adev) (adev)->irq.ih_funcs->prescreen_iv((adev))
|
||||
#define amdgpu_ih_decode_iv(adev, iv) (adev)->irq.ih_funcs->decode_iv((adev), (iv))
|
||||
#define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev))
|
||||
#define amdgpu_display_vblank_get_counter(adev, crtc) (adev)->mode_info.funcs->vblank_get_counter((adev), (crtc))
|
||||
|
|
|
@ -169,6 +169,12 @@ int amdgpu_ih_process(struct amdgpu_device *adev)
|
|||
while (adev->irq.ih.rptr != wptr) {
|
||||
u32 ring_index = adev->irq.ih.rptr >> 2;
|
||||
|
||||
/* Prescreening of high-frequency interrupts */
|
||||
if (!amdgpu_ih_prescreen_iv(adev)) {
|
||||
adev->irq.ih.rptr &= adev->irq.ih.ptr_mask;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Before dispatching irq to IP blocks, send it to amdkfd */
|
||||
amdgpu_amdkfd_interrupt(adev,
|
||||
(const void *) &adev->irq.ih.ring[ring_index]);
|
||||
|
|
|
@ -228,6 +228,19 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev)
|
|||
* [127:96] - reserved
|
||||
*/
|
||||
|
||||
/**
|
||||
* cik_ih_prescreen_iv - prescreen an interrupt vector
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Returns true if the interrupt vector should be further processed.
|
||||
*/
|
||||
static bool cik_ih_prescreen_iv(struct amdgpu_device *adev)
|
||||
{
|
||||
/* Process all interrupts */
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* cik_ih_decode_iv - decode an interrupt vector
|
||||
*
|
||||
|
@ -433,6 +446,7 @@ static const struct amd_ip_funcs cik_ih_ip_funcs = {
|
|||
|
||||
static const struct amdgpu_ih_funcs cik_ih_funcs = {
|
||||
.get_wptr = cik_ih_get_wptr,
|
||||
.prescreen_iv = cik_ih_prescreen_iv,
|
||||
.decode_iv = cik_ih_decode_iv,
|
||||
.set_rptr = cik_ih_set_rptr
|
||||
};
|
||||
|
|
|
@ -207,6 +207,19 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev)
|
|||
return (wptr & adev->irq.ih.ptr_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* cz_ih_prescreen_iv - prescreen an interrupt vector
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Returns true if the interrupt vector should be further processed.
|
||||
*/
|
||||
static bool cz_ih_prescreen_iv(struct amdgpu_device *adev)
|
||||
{
|
||||
/* Process all interrupts */
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* cz_ih_decode_iv - decode an interrupt vector
|
||||
*
|
||||
|
@ -414,6 +427,7 @@ static const struct amd_ip_funcs cz_ih_ip_funcs = {
|
|||
|
||||
static const struct amdgpu_ih_funcs cz_ih_funcs = {
|
||||
.get_wptr = cz_ih_get_wptr,
|
||||
.prescreen_iv = cz_ih_prescreen_iv,
|
||||
.decode_iv = cz_ih_decode_iv,
|
||||
.set_rptr = cz_ih_set_rptr
|
||||
};
|
||||
|
|
|
@ -207,6 +207,19 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev)
|
|||
return (wptr & adev->irq.ih.ptr_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* iceland_ih_prescreen_iv - prescreen an interrupt vector
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Returns true if the interrupt vector should be further processed.
|
||||
*/
|
||||
static bool iceland_ih_prescreen_iv(struct amdgpu_device *adev)
|
||||
{
|
||||
/* Process all interrupts */
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* iceland_ih_decode_iv - decode an interrupt vector
|
||||
*
|
||||
|
@ -412,6 +425,7 @@ static const struct amd_ip_funcs iceland_ih_ip_funcs = {
|
|||
|
||||
static const struct amdgpu_ih_funcs iceland_ih_funcs = {
|
||||
.get_wptr = iceland_ih_get_wptr,
|
||||
.prescreen_iv = iceland_ih_prescreen_iv,
|
||||
.decode_iv = iceland_ih_decode_iv,
|
||||
.set_rptr = iceland_ih_set_rptr
|
||||
};
|
||||
|
|
|
@ -118,6 +118,19 @@ static u32 si_ih_get_wptr(struct amdgpu_device *adev)
|
|||
return (wptr & adev->irq.ih.ptr_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* si_ih_prescreen_iv - prescreen an interrupt vector
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Returns true if the interrupt vector should be further processed.
|
||||
*/
|
||||
static bool si_ih_prescreen_iv(struct amdgpu_device *adev)
|
||||
{
|
||||
/* Process all interrupts */
|
||||
return true;
|
||||
}
|
||||
|
||||
static void si_ih_decode_iv(struct amdgpu_device *adev,
|
||||
struct amdgpu_iv_entry *entry)
|
||||
{
|
||||
|
@ -288,6 +301,7 @@ static const struct amd_ip_funcs si_ih_ip_funcs = {
|
|||
|
||||
static const struct amdgpu_ih_funcs si_ih_funcs = {
|
||||
.get_wptr = si_ih_get_wptr,
|
||||
.prescreen_iv = si_ih_prescreen_iv,
|
||||
.decode_iv = si_ih_decode_iv,
|
||||
.set_rptr = si_ih_set_rptr
|
||||
};
|
||||
|
|
|
@ -218,6 +218,19 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev)
|
|||
return (wptr & adev->irq.ih.ptr_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* tonga_ih_prescreen_iv - prescreen an interrupt vector
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Returns true if the interrupt vector should be further processed.
|
||||
*/
|
||||
static bool tonga_ih_prescreen_iv(struct amdgpu_device *adev)
|
||||
{
|
||||
/* Process all interrupts */
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* tonga_ih_decode_iv - decode an interrupt vector
|
||||
*
|
||||
|
@ -478,6 +491,7 @@ static const struct amd_ip_funcs tonga_ih_ip_funcs = {
|
|||
|
||||
static const struct amdgpu_ih_funcs tonga_ih_funcs = {
|
||||
.get_wptr = tonga_ih_get_wptr,
|
||||
.prescreen_iv = tonga_ih_prescreen_iv,
|
||||
.decode_iv = tonga_ih_decode_iv,
|
||||
.set_rptr = tonga_ih_set_rptr
|
||||
};
|
||||
|
|
|
@ -226,6 +226,19 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev)
|
|||
return (wptr & adev->irq.ih.ptr_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* vega10_ih_prescreen_iv - prescreen an interrupt vector
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Returns true if the interrupt vector should be further processed.
|
||||
*/
|
||||
static bool vega10_ih_prescreen_iv(struct amdgpu_device *adev)
|
||||
{
|
||||
/* TODO: Filter known pending page faults */
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* vega10_ih_decode_iv - decode an interrupt vector
|
||||
*
|
||||
|
@ -410,6 +423,7 @@ const struct amd_ip_funcs vega10_ih_ip_funcs = {
|
|||
|
||||
static const struct amdgpu_ih_funcs vega10_ih_funcs = {
|
||||
.get_wptr = vega10_ih_get_wptr,
|
||||
.prescreen_iv = vega10_ih_prescreen_iv,
|
||||
.decode_iv = vega10_ih_decode_iv,
|
||||
.set_rptr = vega10_ih_set_rptr
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue