hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/gpu/drm/amd/amdgpu/iceland_ih.c
....@@ -20,7 +20,9 @@
2020 * OTHER DEALINGS IN THE SOFTWARE.
2121 *
2222 */
23
-#include <drm/drmP.h>
23
+
24
+#include <linux/pci.h>
25
+
2426 #include "amdgpu.h"
2527 #include "amdgpu_ih.h"
2628 #include "vid.h"
....@@ -103,9 +105,9 @@
103105 */
104106 static int iceland_ih_irq_init(struct amdgpu_device *adev)
105107 {
108
+ struct amdgpu_ih_ring *ih = &adev->irq.ih;
106109 int rb_bufsz;
107110 u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
108
- u64 wptr_off;
109111
110112 /* disable irqs */
111113 iceland_ih_disable_interrupts(adev);
....@@ -133,9 +135,8 @@
133135 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_WRITEBACK_ENABLE, 1);
134136
135137 /* set the writeback address whether it's enabled or not */
136
- wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
137
- WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
138
- WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF);
138
+ WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(ih->wptr_addr));
139
+ WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(ih->wptr_addr) & 0xFF);
139140
140141 WREG32(mmIH_RB_CNTL, ih_rb_cntl);
141142
....@@ -185,54 +186,37 @@
185186 * Used by cz_irq_process(VI).
186187 * Returns the value of the wptr.
187188 */
188
-static u32 iceland_ih_get_wptr(struct amdgpu_device *adev)
189
+static u32 iceland_ih_get_wptr(struct amdgpu_device *adev,
190
+ struct amdgpu_ih_ring *ih)
189191 {
190192 u32 wptr, tmp;
191193
192
- wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]);
194
+ wptr = le32_to_cpu(*ih->wptr_cpu);
193195
194
- if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
195
- wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
196
- /* When a ring buffer overflow happen start parsing interrupt
197
- * from the last not overwritten vector (wptr + 16). Hopefully
198
- * this should allow us to catchup.
199
- */
200
- dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
201
- wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask);
202
- adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask;
203
- tmp = RREG32(mmIH_RB_CNTL);
204
- tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
205
- WREG32(mmIH_RB_CNTL, tmp);
206
- }
207
- return (wptr & adev->irq.ih.ptr_mask);
208
-}
196
+ if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
197
+ goto out;
209198
210
-/**
211
- * iceland_ih_prescreen_iv - prescreen an interrupt vector
212
- *
213
- * @adev: amdgpu_device pointer
214
- *
215
- * Returns true if the interrupt vector should be further processed.
216
- */
217
-static bool iceland_ih_prescreen_iv(struct amdgpu_device *adev)
218
-{
219
- u32 ring_index = adev->irq.ih.rptr >> 2;
220
- u16 pasid;
199
+ /* Double check that the overflow wasn't already cleared. */
200
+ wptr = RREG32(mmIH_RB_WPTR);
221201
222
- switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) {
223
- case 146:
224
- case 147:
225
- pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16;
226
- if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid))
227
- return true;
228
- break;
229
- default:
230
- /* Not a VM fault */
231
- return true;
232
- }
202
+ if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
203
+ goto out;
233204
234
- adev->irq.ih.rptr += 16;
235
- return false;
205
+ wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
206
+ /* When a ring buffer overflow happen start parsing interrupt
207
+ * from the last not overwritten vector (wptr + 16). Hopefully
208
+ * this should allow us to catchup.
209
+ */
210
+ dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
211
+ wptr, ih->rptr, (wptr + 16) & ih->ptr_mask);
212
+ ih->rptr = (wptr + 16) & ih->ptr_mask;
213
+ tmp = RREG32(mmIH_RB_CNTL);
214
+ tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
215
+ WREG32(mmIH_RB_CNTL, tmp);
216
+
217
+
218
+out:
219
+ return (wptr & ih->ptr_mask);
236220 }
237221
238222 /**
....@@ -244,18 +228,19 @@
244228 * position and also advance the position.
245229 */
246230 static void iceland_ih_decode_iv(struct amdgpu_device *adev,
231
+ struct amdgpu_ih_ring *ih,
247232 struct amdgpu_iv_entry *entry)
248233 {
249234 /* wptr/rptr are in bytes! */
250
- u32 ring_index = adev->irq.ih.rptr >> 2;
235
+ u32 ring_index = ih->rptr >> 2;
251236 uint32_t dw[4];
252237
253
- dw[0] = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]);
254
- dw[1] = le32_to_cpu(adev->irq.ih.ring[ring_index + 1]);
255
- dw[2] = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]);
256
- dw[3] = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]);
238
+ dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
239
+ dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
240
+ dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
241
+ dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
257242
258
- entry->client_id = AMDGPU_IH_CLIENTID_LEGACY;
243
+ entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
259244 entry->src_id = dw[0] & 0xff;
260245 entry->src_data[0] = dw[1] & 0xfffffff;
261246 entry->ring_id = dw[2] & 0xff;
....@@ -263,7 +248,7 @@
263248 entry->pasid = (dw[2] >> 16) & 0xffff;
264249
265250 /* wptr/rptr are in bytes! */
266
- adev->irq.ih.rptr += 16;
251
+ ih->rptr += 16;
267252 }
268253
269254 /**
....@@ -273,9 +258,10 @@
273258 *
274259 * Set the IH ring buffer rptr.
275260 */
276
-static void iceland_ih_set_rptr(struct amdgpu_device *adev)
261
+static void iceland_ih_set_rptr(struct amdgpu_device *adev,
262
+ struct amdgpu_ih_ring *ih)
277263 {
278
- WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr);
264
+ WREG32(mmIH_RB_RPTR, ih->rptr);
279265 }
280266
281267 static int iceland_ih_early_init(void *handle)
....@@ -297,7 +283,7 @@
297283 int r;
298284 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
299285
300
- r = amdgpu_ih_ring_init(adev, 64 * 1024, false);
286
+ r = amdgpu_ih_ring_init(adev, &adev->irq.ih, 64 * 1024, false);
301287 if (r)
302288 return r;
303289
....@@ -311,7 +297,7 @@
311297 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
312298
313299 amdgpu_irq_fini(adev);
314
- amdgpu_ih_ring_fini(adev);
300
+ amdgpu_ih_ring_fini(adev, &adev->irq.ih);
315301 amdgpu_irq_remove_domain(adev);
316302
317303 return 0;
....@@ -440,15 +426,13 @@
440426
441427 static const struct amdgpu_ih_funcs iceland_ih_funcs = {
442428 .get_wptr = iceland_ih_get_wptr,
443
- .prescreen_iv = iceland_ih_prescreen_iv,
444429 .decode_iv = iceland_ih_decode_iv,
445430 .set_rptr = iceland_ih_set_rptr
446431 };
447432
448433 static void iceland_ih_set_interrupt_funcs(struct amdgpu_device *adev)
449434 {
450
- if (adev->irq.ih_funcs == NULL)
451
- adev->irq.ih_funcs = &iceland_ih_funcs;
435
+ adev->irq.ih_funcs = &iceland_ih_funcs;
452436 }
453437
454438 const struct amdgpu_ip_block_version iceland_ih_ip_block =