diff options
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 24 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 4 | ||||
| -rw-r--r-- | 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 @@ | |||
| 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 | */ |
| 132 | int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih) | 131 | int 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 { | |||
| 85 | int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, | 85 | int 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); |
| 87 | void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); | 87 | void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); |
| 88 | int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); | 88 | int 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 | */ | ||
| 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, &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; |
