aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2018-09-17 09:18:37 -0400
committerAlex Deucher <alexander.deucher@amd.com>2018-09-26 22:09:22 -0400
commit1f8969463bca23327eedadab0fef0d28c9b6f29f (patch)
tree0b2d16d6ed8a7da61b1e8594f104fb6f9d2271d9 /drivers/gpu/drm/amd/amdgpu
parent95d7fc4a412aabd3f5b2e1123c3b8faf1a3d8da7 (diff)
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: Christian König <christian.koenig@amd.com> Acked-by: Huang Rui <ray.huang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c24
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c31
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 @@
24#include <drm/drmP.h> 24#include <drm/drmP.h>
25#include "amdgpu.h" 25#include "amdgpu.h"
26#include "amdgpu_ih.h" 26#include "amdgpu_ih.h"
27#include "amdgpu_amdkfd.h"
28 27
29/** 28/**
30 * amdgpu_ih_ring_init - initialize the IH state 29 * 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 * Interrupt hander (VI), walk the IH ring. 128 * Interrupt hander (VI), walk the IH ring.
130 * Returns irq process return code. 129 * Returns irq process return code.
131 */ 130 */
132int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih) 131int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
132 void (*callback)(struct amdgpu_device *adev,
133 struct amdgpu_ih_ring *ih))
133{ 134{
134 struct amdgpu_iv_entry entry;
135 u32 wptr; 135 u32 wptr;
136 136
137 if (!ih->enabled || adev->shutdown) 137 if (!ih->enabled || adev->shutdown)
@@ -150,24 +150,10 @@ restart_ih:
150 rmb(); 150 rmb();
151 151
152 while (ih->rptr != wptr) { 152 while (ih->rptr != wptr) {
153 u32 ring_index = ih->rptr >> 2; 153 callback(adev, ih);
154
155 /* Prescreening of high-frequency interrupts */
156 if (!amdgpu_ih_prescreen_iv(adev)) {
157 ih->rptr &= ih->ptr_mask;
158 continue;
159 }
160
161 /* Before dispatching irq to IP blocks, send it to amdkfd */
162 amdgpu_amdkfd_interrupt(adev,
163 (const void *) &ih->ring[ring_index]);
164
165 entry.iv_entry = (const uint32_t *)&ih->ring[ring_index];
166 amdgpu_ih_decode_iv(adev, &entry);
167 ih->rptr &= ih->ptr_mask; 154 ih->rptr &= ih->ptr_mask;
168
169 amdgpu_irq_dispatch(adev, &entry);
170 } 155 }
156
171 amdgpu_ih_set_rptr(adev); 157 amdgpu_ih_set_rptr(adev);
172 atomic_set(&ih->lock, 0); 158 atomic_set(&ih->lock, 0);
173 159
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 {
85int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, 85int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
86 unsigned ring_size, bool use_bus_addr); 86 unsigned ring_size, bool use_bus_addr);
87void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); 87void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih);
88int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); 88int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
89 void (*callback)(struct amdgpu_device *adev,
90 struct amdgpu_ih_ring *ih));
89 91
90#endif 92#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 @@
51#include "atom.h" 51#include "atom.h"
52#include "amdgpu_connectors.h" 52#include "amdgpu_connectors.h"
53#include "amdgpu_trace.h" 53#include "amdgpu_trace.h"
54#include "amdgpu_amdkfd.h"
54 55
55#include <linux/pm_runtime.h> 56#include <linux/pm_runtime.h>
56 57
@@ -147,6 +148,34 @@ void amdgpu_irq_disable_all(struct amdgpu_device *adev)
147} 148}
148 149
149/** 150/**
151 * amdgpu_irq_callback - callback from the IH ring
152 *
153 * @adev: amdgpu device pointer
154 * @ih: amdgpu ih ring
155 *
156 * Callback from IH ring processing to handle the entry at the current position
157 * and advance the read pointer.
158 */
159static void amdgpu_irq_callback(struct amdgpu_device *adev,
160 struct amdgpu_ih_ring *ih)
161{
162 u32 ring_index = ih->rptr >> 2;
163 struct amdgpu_iv_entry entry;
164
165 /* Prescreening of high-frequency interrupts */
166 if (!amdgpu_ih_prescreen_iv(adev))
167 return;
168
169 /* Before dispatching irq to IP blocks, send it to amdkfd */
170 amdgpu_amdkfd_interrupt(adev, (const void *) &ih->ring[ring_index]);
171
172 entry.iv_entry = (const uint32_t *)&ih->ring[ring_index];
173 amdgpu_ih_decode_iv(adev, &entry);
174
175 amdgpu_irq_dispatch(adev, &entry);
176}
177
178/**
150 * amdgpu_irq_handler - IRQ handler 179 * amdgpu_irq_handler - IRQ handler
151 * 180 *
152 * @irq: IRQ number (unused) 181 * @irq: IRQ number (unused)
@@ -163,7 +192,7 @@ irqreturn_t amdgpu_irq_handler(int irq, void *arg)
163 struct amdgpu_device *adev = dev->dev_private; 192 struct amdgpu_device *adev = dev->dev_private;
164 irqreturn_t ret; 193 irqreturn_t ret;
165 194
166 ret = amdgpu_ih_process(adev, &adev->irq.ih); 195 ret = amdgpu_ih_process(adev, &adev->irq.ih, amdgpu_irq_callback);
167 if (ret == IRQ_HANDLED) 196 if (ret == IRQ_HANDLED)
168 pm_runtime_mark_last_busy(dev->dev); 197 pm_runtime_mark_last_busy(dev->dev);
169 return ret; 198 return ret;