Commit 1f896946 authored by Christian König's avatar Christian König Committed by Alex Deucher

drm/amdgpu: move more interrupt processing into amdgpu_irq.c

Add a callback to amdgpu_ih_process to remove most of the IV logic.
Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Acked-by: default avatarHuang Rui <ray.huang@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 95d7fc4a
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include "amdgpu.h" #include "amdgpu.h"
#include "amdgpu_ih.h" #include "amdgpu_ih.h"
#include "amdgpu_amdkfd.h"
/** /**
* amdgpu_ih_ring_init - initialize the IH state * 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) ...@@ -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. * Interrupt hander (VI), walk the IH ring.
* Returns irq process return code. * 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; u32 wptr;
if (!ih->enabled || adev->shutdown) if (!ih->enabled || adev->shutdown)
...@@ -150,24 +150,10 @@ int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih) ...@@ -150,24 +150,10 @@ int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih)
rmb(); rmb();
while (ih->rptr != wptr) { while (ih->rptr != wptr) {
u32 ring_index = ih->rptr >> 2; callback(adev, ih);
/* 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);
ih->rptr &= ih->ptr_mask; ih->rptr &= ih->ptr_mask;
amdgpu_irq_dispatch(adev, &entry);
} }
amdgpu_ih_set_rptr(adev); amdgpu_ih_set_rptr(adev);
atomic_set(&ih->lock, 0); atomic_set(&ih->lock, 0);
......
...@@ -85,6 +85,8 @@ struct amdgpu_ih_funcs { ...@@ -85,6 +85,8 @@ struct amdgpu_ih_funcs {
int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
unsigned ring_size, bool use_bus_addr); unsigned ring_size, bool use_bus_addr);
void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); 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 #endif
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#include "atom.h" #include "atom.h"
#include "amdgpu_connectors.h" #include "amdgpu_connectors.h"
#include "amdgpu_trace.h" #include "amdgpu_trace.h"
#include "amdgpu_amdkfd.h"
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
...@@ -146,6 +147,34 @@ void amdgpu_irq_disable_all(struct amdgpu_device *adev) ...@@ -146,6 +147,34 @@ void amdgpu_irq_disable_all(struct amdgpu_device *adev)
spin_unlock_irqrestore(&adev->irq.lock, irqflags); 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 * amdgpu_irq_handler - IRQ handler
* *
...@@ -163,7 +192,7 @@ irqreturn_t amdgpu_irq_handler(int irq, void *arg) ...@@ -163,7 +192,7 @@ irqreturn_t amdgpu_irq_handler(int irq, void *arg)
struct amdgpu_device *adev = dev->dev_private; struct amdgpu_device *adev = dev->dev_private;
irqreturn_t ret; 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) if (ret == IRQ_HANDLED)
pm_runtime_mark_last_busy(dev->dev); pm_runtime_mark_last_busy(dev->dev);
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment