[PATCH 4/9] drm/amdgpu: move more interrupt processing into amdgpu_irq.c
Huang Rui
ray.huang at amd.com
Wed Sep 26 06:13:16 UTC 2018
On Mon, Sep 24, 2018 at 02:38:15PM +0200, Christian König wrote:
> Add a callback to amdgpu_ih_process to remove most of the IV logic.
>
> Signed-off-by: Christian König <christian.koenig at amd.com>
Acked-by: Huang Rui <ray.huang at amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 24 +++++-------------------
> drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 4 +++-
> drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 31 ++++++++++++++++++++++++++++++-
> 3 files changed, 38 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
> index 15fb0f9738ab..8af67f649660 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
> @@ -24,7 +24,6 @@
> #include <drm/drmP.h>
> #include "amdgpu.h"
> #include "amdgpu_ih.h"
> -#include "amdgpu_amdkfd.h"
>
> /**
> * amdgpu_ih_ring_init - initialize the IH state
> @@ -129,9 +128,10 @@ void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih)
> * Interrupt hander (VI), walk the IH ring.
> * Returns irq process return code.
> */
> -int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih)
> +int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
> + void (*callback)(struct amdgpu_device *adev,
> + struct amdgpu_ih_ring *ih))
> {
> - struct amdgpu_iv_entry entry;
> u32 wptr;
>
> if (!ih->enabled || adev->shutdown)
> @@ -150,24 +150,10 @@ int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih)
> rmb();
>
> while (ih->rptr != wptr) {
> - u32 ring_index = ih->rptr >> 2;
> -
> - /* Prescreening of high-frequency interrupts */
> - if (!amdgpu_ih_prescreen_iv(adev)) {
> - ih->rptr &= ih->ptr_mask;
> - continue;
> - }
> -
> - /* Before dispatching irq to IP blocks, send it to amdkfd */
> - amdgpu_amdkfd_interrupt(adev,
> - (const void *) &ih->ring[ring_index]);
> -
> - entry.iv_entry = (const uint32_t *)&ih->ring[ring_index];
> - amdgpu_ih_decode_iv(adev, &entry);
> + callback(adev, ih);
> ih->rptr &= ih->ptr_mask;
> -
> - amdgpu_irq_dispatch(adev, &entry);
> }
> +
> amdgpu_ih_set_rptr(adev);
> atomic_set(&ih->lock, 0);
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
> index 3e55f985005c..fd2bbaa20ab4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
> @@ -85,6 +85,8 @@ struct amdgpu_ih_funcs {
> int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
> unsigned ring_size, bool use_bus_addr);
> void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih);
> -int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih);
> +int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
> + void (*callback)(struct amdgpu_device *adev,
> + struct amdgpu_ih_ring *ih));
>
> #endif
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> index aaa8545e458a..2fca08e130b6 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> @@ -51,6 +51,7 @@
> #include "atom.h"
> #include "amdgpu_connectors.h"
> #include "amdgpu_trace.h"
> +#include "amdgpu_amdkfd.h"
>
> #include <linux/pm_runtime.h>
>
> @@ -146,6 +147,34 @@ void amdgpu_irq_disable_all(struct amdgpu_device *adev)
> spin_unlock_irqrestore(&adev->irq.lock, irqflags);
> }
>
> +/**
> + * amdgpu_irq_callback - callback from the IH ring
> + *
> + * @adev: amdgpu device pointer
> + * @ih: amdgpu ih ring
> + *
> + * Callback from IH ring processing to handle the entry at the current position
> + * and advance the read pointer.
> + */
> +static void amdgpu_irq_callback(struct amdgpu_device *adev,
> + struct amdgpu_ih_ring *ih)
> +{
> + u32 ring_index = ih->rptr >> 2;
> + struct amdgpu_iv_entry entry;
> +
> + /* Prescreening of high-frequency interrupts */
> + if (!amdgpu_ih_prescreen_iv(adev))
> + return;
> +
> + /* Before dispatching irq to IP blocks, send it to amdkfd */
> + amdgpu_amdkfd_interrupt(adev, (const void *) &ih->ring[ring_index]);
> +
> + entry.iv_entry = (const uint32_t *)&ih->ring[ring_index];
> + amdgpu_ih_decode_iv(adev, &entry);
> +
> + amdgpu_irq_dispatch(adev, &entry);
> +}
> +
> /**
> * amdgpu_irq_handler - IRQ handler
> *
> @@ -163,7 +192,7 @@ irqreturn_t amdgpu_irq_handler(int irq, void *arg)
> struct amdgpu_device *adev = dev->dev_private;
> irqreturn_t ret;
>
> - ret = amdgpu_ih_process(adev, &adev->irq.ih);
> + ret = amdgpu_ih_process(adev, &adev->irq.ih, amdgpu_irq_callback);
> if (ret == IRQ_HANDLED)
> pm_runtime_mark_last_busy(dev->dev);
> return ret;
> --
> 2.14.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
More information about the amd-gfx
mailing list