diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 41 |
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 | */ | ||
159 | static 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 | ||