hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/gpu/drm/amd/amdgpu/cz_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 cz_ih_irq_init(struct amdgpu_device *adev)
105107 {
106
- int rb_bufsz;
108
+ struct amdgpu_ih_ring *ih = &adev->irq.ih;
107109 u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
108
- u64 wptr_off;
110
+ int rb_bufsz;
109111
110112 /* disable irqs */
111113 cz_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,38 @@
185186 * Used by cz_irq_process(VI).
186187 * Returns the value of the wptr.
187188 */
188
-static u32 cz_ih_get_wptr(struct amdgpu_device *adev)
189
+static u32 cz_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
- * cz_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 cz_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
+
207
+ /* When a ring buffer overflow happen start parsing interrupt
208
+ * from the last not overwritten vector (wptr + 16). Hopefully
209
+ * this should allow us to catchup.
210
+ */
211
+ dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
212
+ wptr, ih->rptr, (wptr + 16) & ih->ptr_mask);
213
+ ih->rptr = (wptr + 16) & ih->ptr_mask;
214
+ tmp = RREG32(mmIH_RB_CNTL);
215
+ tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
216
+ WREG32(mmIH_RB_CNTL, tmp);
217
+
218
+
219
+out:
220
+ return (wptr & ih->ptr_mask);
236221 }
237222
238223 /**
....@@ -244,18 +229,19 @@
244229 * position and also advance the position.
245230 */
246231 static void cz_ih_decode_iv(struct amdgpu_device *adev,
247
- struct amdgpu_iv_entry *entry)
232
+ struct amdgpu_ih_ring *ih,
233
+ struct amdgpu_iv_entry *entry)
248234 {
249235 /* wptr/rptr are in bytes! */
250
- u32 ring_index = adev->irq.ih.rptr >> 2;
236
+ u32 ring_index = ih->rptr >> 2;
251237 uint32_t dw[4];
252238
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]);
239
+ dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
240
+ dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
241
+ dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
242
+ dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
257243
258
- entry->client_id = AMDGPU_IH_CLIENTID_LEGACY;
244
+ entry->client_id = AMDGPU_IRQ_CLIENTID_LEGACY;
259245 entry->src_id = dw[0] & 0xff;
260246 entry->src_data[0] = dw[1] & 0xfffffff;
261247 entry->ring_id = dw[2] & 0xff;
....@@ -263,7 +249,7 @@
263249 entry->pasid = (dw[2] >> 16) & 0xffff;
264250
265251 /* wptr/rptr are in bytes! */
266
- adev->irq.ih.rptr += 16;
252
+ ih->rptr += 16;
267253 }
268254
269255 /**
....@@ -273,9 +259,10 @@
273259 *
274260 * Set the IH ring buffer rptr.
275261 */
276
-static void cz_ih_set_rptr(struct amdgpu_device *adev)
262
+static void cz_ih_set_rptr(struct amdgpu_device *adev,
263
+ struct amdgpu_ih_ring *ih)
277264 {
278
- WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr);
265
+ WREG32(mmIH_RB_RPTR, ih->rptr);
279266 }
280267
281268 static int cz_ih_early_init(void *handle)
....@@ -297,7 +284,7 @@
297284 int r;
298285 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
299286
300
- r = amdgpu_ih_ring_init(adev, 64 * 1024, false);
287
+ r = amdgpu_ih_ring_init(adev, &adev->irq.ih, 64 * 1024, false);
301288 if (r)
302289 return r;
303290
....@@ -311,7 +298,7 @@
311298 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
312299
313300 amdgpu_irq_fini(adev);
314
- amdgpu_ih_ring_fini(adev);
301
+ amdgpu_ih_ring_fini(adev, &adev->irq.ih);
315302 amdgpu_irq_remove_domain(adev);
316303
317304 return 0;
....@@ -442,15 +429,13 @@
442429
443430 static const struct amdgpu_ih_funcs cz_ih_funcs = {
444431 .get_wptr = cz_ih_get_wptr,
445
- .prescreen_iv = cz_ih_prescreen_iv,
446432 .decode_iv = cz_ih_decode_iv,
447433 .set_rptr = cz_ih_set_rptr
448434 };
449435
450436 static void cz_ih_set_interrupt_funcs(struct amdgpu_device *adev)
451437 {
452
- if (adev->irq.ih_funcs == NULL)
453
- adev->irq.ih_funcs = &cz_ih_funcs;
438
+ adev->irq.ih_funcs = &cz_ih_funcs;
454439 }
455440
456441 const struct amdgpu_ip_block_version cz_ih_ip_block =