aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c41
1 files changed, 35 insertions, 6 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
index b927e8798534..52c17f6219a7 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
@@ -123,7 +124,7 @@ void amdgpu_irq_disable_all(struct amdgpu_device *adev)
123 int r; 124 int r;
124 125
125 spin_lock_irqsave(&adev->irq.lock, irqflags); 126 spin_lock_irqsave(&adev->irq.lock, irqflags);
126 for (i = 0; i < AMDGPU_IH_CLIENTID_MAX; ++i) { 127 for (i = 0; i < AMDGPU_IRQ_CLIENTID_MAX; ++i) {
127 if (!adev->irq.client[i].sources) 128 if (!adev->irq.client[i].sources)
128 continue; 129 continue;
129 130
@@ -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); 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;
@@ -273,7 +302,7 @@ void amdgpu_irq_fini(struct amdgpu_device *adev)
273 cancel_work_sync(&adev->reset_work); 302 cancel_work_sync(&adev->reset_work);
274 } 303 }
275 304
276 for (i = 0; i < AMDGPU_IH_CLIENTID_MAX; ++i) { 305 for (i = 0; i < AMDGPU_IRQ_CLIENTID_MAX; ++i) {
277 if (!adev->irq.client[i].sources) 306 if (!adev->irq.client[i].sources)
278 continue; 307 continue;
279 308
@@ -313,7 +342,7 @@ int amdgpu_irq_add_id(struct amdgpu_device *adev,
313 unsigned client_id, unsigned src_id, 342 unsigned client_id, unsigned src_id,
314 struct amdgpu_irq_src *source) 343 struct amdgpu_irq_src *source)
315{ 344{
316 if (client_id >= AMDGPU_IH_CLIENTID_MAX) 345 if (client_id >= AMDGPU_IRQ_CLIENTID_MAX)
317 return -EINVAL; 346 return -EINVAL;
318 347
319 if (src_id >= AMDGPU_MAX_IRQ_SRC_ID) 348 if (src_id >= AMDGPU_MAX_IRQ_SRC_ID)
@@ -367,7 +396,7 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev,
367 396
368 trace_amdgpu_iv(entry); 397 trace_amdgpu_iv(entry);
369 398
370 if (client_id >= AMDGPU_IH_CLIENTID_MAX) { 399 if (client_id >= AMDGPU_IRQ_CLIENTID_MAX) {
371 DRM_DEBUG("Invalid client_id in IV: %d\n", client_id); 400 DRM_DEBUG("Invalid client_id in IV: %d\n", client_id);
372 return; 401 return;
373 } 402 }
@@ -440,7 +469,7 @@ void amdgpu_irq_gpu_reset_resume_helper(struct amdgpu_device *adev)
440{ 469{
441 int i, j, k; 470 int i, j, k;
442 471
443 for (i = 0; i < AMDGPU_IH_CLIENTID_MAX; ++i) { 472 for (i = 0; i < AMDGPU_IRQ_CLIENTID_MAX; ++i) {
444 if (!adev->irq.client[i].sources) 473 if (!adev->irq.client[i].sources)
445 continue; 474 continue;
446 475