1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <linux/pci.h>
25
26#include "amdgpu.h"
27#include "amdgpu_ih.h"
28#include "soc15.h"
29
30#include "oss/osssys_4_0_offset.h"
31#include "oss/osssys_4_0_sh_mask.h"
32
33#include "soc15_common.h"
34#include "vega10_ih.h"
35
36#define MAX_REARM_RETRY 10
37
38static void vega10_ih_set_interrupt_funcs(struct amdgpu_device *adev);
39
40
41
42
43
44
45
46
47static void vega10_ih_enable_interrupts(struct amdgpu_device *adev)
48{
49 u32 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
50
51 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_ENABLE, 1);
52 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, ENABLE_INTR, 1);
53 if (amdgpu_sriov_vf(adev)) {
54 if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL, ih_rb_cntl)) {
55 DRM_ERROR("PSP program IH_RB_CNTL failed!\n");
56 return;
57 }
58 } else {
59 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
60 }
61 adev->irq.ih.enabled = true;
62
63 if (adev->irq.ih1.ring_size) {
64 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
65 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1,
66 RB_ENABLE, 1);
67 if (amdgpu_sriov_vf(adev)) {
68 if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING1,
69 ih_rb_cntl)) {
70 DRM_ERROR("program IH_RB_CNTL_RING1 failed!\n");
71 return;
72 }
73 } else {
74 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
75 }
76 adev->irq.ih1.enabled = true;
77 }
78
79 if (adev->irq.ih2.ring_size) {
80 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
81 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2,
82 RB_ENABLE, 1);
83 if (amdgpu_sriov_vf(adev)) {
84 if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING2,
85 ih_rb_cntl)) {
86 DRM_ERROR("program IH_RB_CNTL_RING2 failed!\n");
87 return;
88 }
89 } else {
90 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
91 }
92 adev->irq.ih2.enabled = true;
93 }
94
95 if (adev->irq.ih_soft.ring_size)
96 adev->irq.ih_soft.enabled = true;
97}
98
99
100
101
102
103
104
105
106static void vega10_ih_disable_interrupts(struct amdgpu_device *adev)
107{
108 u32 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
109
110 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_ENABLE, 0);
111 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, ENABLE_INTR, 0);
112 if (amdgpu_sriov_vf(adev)) {
113 if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL, ih_rb_cntl)) {
114 DRM_ERROR("PSP program IH_RB_CNTL failed!\n");
115 return;
116 }
117 } else {
118 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
119 }
120
121
122 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0);
123 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR, 0);
124 adev->irq.ih.enabled = false;
125 adev->irq.ih.rptr = 0;
126
127 if (adev->irq.ih1.ring_size) {
128 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
129 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1,
130 RB_ENABLE, 0);
131 if (amdgpu_sriov_vf(adev)) {
132 if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING1,
133 ih_rb_cntl)) {
134 DRM_ERROR("program IH_RB_CNTL_RING1 failed!\n");
135 return;
136 }
137 } else {
138 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
139 }
140
141 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, 0);
142 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING1, 0);
143 adev->irq.ih1.enabled = false;
144 adev->irq.ih1.rptr = 0;
145 }
146
147 if (adev->irq.ih2.ring_size) {
148 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
149 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2,
150 RB_ENABLE, 0);
151 if (amdgpu_sriov_vf(adev)) {
152 if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING2,
153 ih_rb_cntl)) {
154 DRM_ERROR("program IH_RB_CNTL_RING2 failed!\n");
155 return;
156 }
157 } else {
158 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
159 }
160
161
162 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, 0);
163 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING2, 0);
164 adev->irq.ih2.enabled = false;
165 adev->irq.ih2.rptr = 0;
166 }
167}
168
169static uint32_t vega10_ih_rb_cntl(struct amdgpu_ih_ring *ih, uint32_t ih_rb_cntl)
170{
171 int rb_bufsz = order_base_2(ih->ring_size / 4);
172
173 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
174 MC_SPACE, ih->use_bus_addr ? 1 : 4);
175 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
176 WPTR_OVERFLOW_CLEAR, 1);
177 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
178 WPTR_OVERFLOW_ENABLE, 1);
179 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_SIZE, rb_bufsz);
180
181
182
183 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
184 WPTR_WRITEBACK_ENABLE, 1);
185 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SNOOP, 1);
186 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_RO, 0);
187 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_VMID, 0);
188
189 return ih_rb_cntl;
190}
191
192static uint32_t vega10_ih_doorbell_rptr(struct amdgpu_ih_ring *ih)
193{
194 u32 ih_doorbell_rtpr = 0;
195
196 if (ih->use_doorbell) {
197 ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
198 IH_DOORBELL_RPTR, OFFSET,
199 ih->doorbell_index);
200 ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
201 IH_DOORBELL_RPTR,
202 ENABLE, 1);
203 } else {
204 ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
205 IH_DOORBELL_RPTR,
206 ENABLE, 0);
207 }
208 return ih_doorbell_rtpr;
209}
210
211
212
213
214
215
216
217
218
219
220
221
222static int vega10_ih_irq_init(struct amdgpu_device *adev)
223{
224 struct amdgpu_ih_ring *ih;
225 u32 ih_rb_cntl, ih_chicken;
226 int ret = 0;
227 u32 tmp;
228
229
230 vega10_ih_disable_interrupts(adev);
231
232 adev->nbio.funcs->ih_control(adev);
233
234 ih = &adev->irq.ih;
235
236 WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, ih->gpu_addr >> 8);
237 WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI, (ih->gpu_addr >> 40) & 0xff);
238
239 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
240 ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
241 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RPTR_REARM,
242 !!adev->irq.msi_enabled);
243 if (amdgpu_sriov_vf(adev)) {
244 if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL, ih_rb_cntl)) {
245 DRM_ERROR("PSP program IH_RB_CNTL failed!\n");
246 return -ETIMEDOUT;
247 }
248 } else {
249 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
250 }
251
252 if ((adev->asic_type == CHIP_ARCTURUS &&
253 adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) ||
254 adev->asic_type == CHIP_RENOIR) {
255 ih_chicken = RREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN);
256 if (adev->irq.ih.use_bus_addr) {
257 ih_chicken = REG_SET_FIELD(ih_chicken, IH_CHICKEN,
258 MC_SPACE_GPA_ENABLE, 1);
259 } else {
260 ih_chicken = REG_SET_FIELD(ih_chicken, IH_CHICKEN,
261 MC_SPACE_FBPA_ENABLE, 1);
262 }
263 WREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN, ih_chicken);
264 }
265
266
267 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_LO,
268 lower_32_bits(ih->wptr_addr));
269 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_HI,
270 upper_32_bits(ih->wptr_addr) & 0xFFFF);
271
272
273 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR, 0);
274 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0);
275
276 WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR,
277 vega10_ih_doorbell_rptr(ih));
278
279 ih = &adev->irq.ih1;
280 if (ih->ring_size) {
281 WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_RING1, ih->gpu_addr >> 8);
282 WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI_RING1,
283 (ih->gpu_addr >> 40) & 0xff);
284
285 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
286 ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
287 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
288 WPTR_OVERFLOW_ENABLE, 0);
289 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
290 RB_FULL_DRAIN_ENABLE, 1);
291 if (amdgpu_sriov_vf(adev)) {
292 if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING1,
293 ih_rb_cntl)) {
294 DRM_ERROR("program IH_RB_CNTL_RING1 failed!\n");
295 return -ETIMEDOUT;
296 }
297 } else {
298 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
299 }
300
301
302 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING1, 0);
303 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, 0);
304
305 WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR_RING1,
306 vega10_ih_doorbell_rptr(ih));
307 }
308
309 ih = &adev->irq.ih2;
310 if (ih->ring_size) {
311 WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_RING2, ih->gpu_addr >> 8);
312 WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI_RING2,
313 (ih->gpu_addr >> 40) & 0xff);
314
315 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
316 ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
317
318 if (amdgpu_sriov_vf(adev)) {
319 if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING2,
320 ih_rb_cntl)) {
321 DRM_ERROR("program IH_RB_CNTL_RING2 failed!\n");
322 return -ETIMEDOUT;
323 }
324 } else {
325 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
326 }
327
328
329 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING2, 0);
330 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, 0);
331
332 WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR_RING2,
333 vega10_ih_doorbell_rptr(ih));
334 }
335
336 tmp = RREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL);
337 tmp = REG_SET_FIELD(tmp, IH_STORM_CLIENT_LIST_CNTL,
338 CLIENT18_IS_STORM_CLIENT, 1);
339 WREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL, tmp);
340
341 tmp = RREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL);
342 tmp = REG_SET_FIELD(tmp, IH_INT_FLOOD_CNTL, FLOOD_CNTL_ENABLE, 1);
343 WREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL, tmp);
344
345 pci_set_master(adev->pdev);
346
347
348 vega10_ih_enable_interrupts(adev);
349
350 return ret;
351}
352
353
354
355
356
357
358
359
360static void vega10_ih_irq_disable(struct amdgpu_device *adev)
361{
362 vega10_ih_disable_interrupts(adev);
363
364
365 mdelay(1);
366}
367
368
369
370
371
372
373
374
375
376
377
378
379static u32 vega10_ih_get_wptr(struct amdgpu_device *adev,
380 struct amdgpu_ih_ring *ih)
381{
382 u32 wptr, reg, tmp;
383
384 wptr = le32_to_cpu(*ih->wptr_cpu);
385
386 if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
387 goto out;
388
389
390
391 if (ih == &adev->irq.ih)
392 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR);
393 else if (ih == &adev->irq.ih1)
394 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR_RING1);
395 else if (ih == &adev->irq.ih2)
396 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR_RING2);
397 else
398 BUG();
399
400 wptr = RREG32_NO_KIQ(reg);
401 if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
402 goto out;
403
404 wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
405
406
407
408
409
410 tmp = (wptr + 32) & ih->ptr_mask;
411 dev_warn(adev->dev, "IH ring buffer overflow "
412 "(0x%08X, 0x%08X, 0x%08X)\n",
413 wptr, ih->rptr, tmp);
414 ih->rptr = tmp;
415
416 if (ih == &adev->irq.ih)
417 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL);
418 else if (ih == &adev->irq.ih1)
419 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL_RING1);
420 else if (ih == &adev->irq.ih2)
421 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL_RING2);
422 else
423 BUG();
424
425 tmp = RREG32_NO_KIQ(reg);
426 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
427 WREG32_NO_KIQ(reg, tmp);
428
429out:
430 return (wptr & ih->ptr_mask);
431}
432
433
434
435
436
437
438
439
440
441
442
443static void vega10_ih_decode_iv(struct amdgpu_device *adev,
444 struct amdgpu_ih_ring *ih,
445 struct amdgpu_iv_entry *entry)
446{
447
448 u32 ring_index = ih->rptr >> 2;
449 uint32_t dw[8];
450
451 dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
452 dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
453 dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
454 dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
455 dw[4] = le32_to_cpu(ih->ring[ring_index + 4]);
456 dw[5] = le32_to_cpu(ih->ring[ring_index + 5]);
457 dw[6] = le32_to_cpu(ih->ring[ring_index + 6]);
458 dw[7] = le32_to_cpu(ih->ring[ring_index + 7]);
459
460 entry->client_id = dw[0] & 0xff;
461 entry->src_id = (dw[0] >> 8) & 0xff;
462 entry->ring_id = (dw[0] >> 16) & 0xff;
463 entry->vmid = (dw[0] >> 24) & 0xf;
464 entry->vmid_src = (dw[0] >> 31);
465 entry->timestamp = dw[1] | ((u64)(dw[2] & 0xffff) << 32);
466 entry->timestamp_src = dw[2] >> 31;
467 entry->pasid = dw[3] & 0xffff;
468 entry->pasid_src = dw[3] >> 31;
469 entry->src_data[0] = dw[4];
470 entry->src_data[1] = dw[5];
471 entry->src_data[2] = dw[6];
472 entry->src_data[3] = dw[7];
473
474
475 ih->rptr += 32;
476}
477
478
479
480
481
482
483
484
485static void vega10_ih_irq_rearm(struct amdgpu_device *adev,
486 struct amdgpu_ih_ring *ih)
487{
488 uint32_t reg_rptr = 0;
489 uint32_t v = 0;
490 uint32_t i = 0;
491
492 if (ih == &adev->irq.ih)
493 reg_rptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_RPTR);
494 else if (ih == &adev->irq.ih1)
495 reg_rptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_RPTR_RING1);
496 else if (ih == &adev->irq.ih2)
497 reg_rptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_RPTR_RING2);
498 else
499 return;
500
501
502 for (i = 0; i < MAX_REARM_RETRY; i++) {
503 v = RREG32_NO_KIQ(reg_rptr);
504 if ((v < ih->ring_size) && (v != ih->rptr))
505 WDOORBELL32(ih->doorbell_index, ih->rptr);
506 else
507 break;
508 }
509}
510
511
512
513
514
515
516
517
518
519static void vega10_ih_set_rptr(struct amdgpu_device *adev,
520 struct amdgpu_ih_ring *ih)
521{
522 if (ih->use_doorbell) {
523
524 *ih->rptr_cpu = ih->rptr;
525 WDOORBELL32(ih->doorbell_index, ih->rptr);
526
527 if (amdgpu_sriov_vf(adev))
528 vega10_ih_irq_rearm(adev, ih);
529 } else if (ih == &adev->irq.ih) {
530 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr);
531 } else if (ih == &adev->irq.ih1) {
532 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, ih->rptr);
533 } else if (ih == &adev->irq.ih2) {
534 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, ih->rptr);
535 }
536}
537
538
539
540
541
542
543
544
545
546
547static int vega10_ih_self_irq(struct amdgpu_device *adev,
548 struct amdgpu_irq_src *source,
549 struct amdgpu_iv_entry *entry)
550{
551 uint32_t wptr = cpu_to_le32(entry->src_data[0]);
552
553 switch (entry->ring_id) {
554 case 1:
555 *adev->irq.ih1.wptr_cpu = wptr;
556 schedule_work(&adev->irq.ih1_work);
557 break;
558 case 2:
559 *adev->irq.ih2.wptr_cpu = wptr;
560 schedule_work(&adev->irq.ih2_work);
561 break;
562 default: break;
563 }
564 return 0;
565}
566
567static const struct amdgpu_irq_src_funcs vega10_ih_self_irq_funcs = {
568 .process = vega10_ih_self_irq,
569};
570
571static void vega10_ih_set_self_irq_funcs(struct amdgpu_device *adev)
572{
573 adev->irq.self_irq.num_types = 0;
574 adev->irq.self_irq.funcs = &vega10_ih_self_irq_funcs;
575}
576
577static int vega10_ih_early_init(void *handle)
578{
579 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
580
581 vega10_ih_set_interrupt_funcs(adev);
582 vega10_ih_set_self_irq_funcs(adev);
583 return 0;
584}
585
586static int vega10_ih_sw_init(void *handle)
587{
588 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
589 int r;
590
591 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_IH, 0,
592 &adev->irq.self_irq);
593 if (r)
594 return r;
595
596 r = amdgpu_ih_ring_init(adev, &adev->irq.ih, 256 * 1024, true);
597 if (r)
598 return r;
599
600 adev->irq.ih.use_doorbell = true;
601 adev->irq.ih.doorbell_index = adev->doorbell_index.ih << 1;
602
603 r = amdgpu_ih_ring_init(adev, &adev->irq.ih1, PAGE_SIZE, true);
604 if (r)
605 return r;
606
607 adev->irq.ih1.use_doorbell = true;
608 adev->irq.ih1.doorbell_index = (adev->doorbell_index.ih + 1) << 1;
609
610 r = amdgpu_ih_ring_init(adev, &adev->irq.ih2, PAGE_SIZE, true);
611 if (r)
612 return r;
613
614 adev->irq.ih2.use_doorbell = true;
615 adev->irq.ih2.doorbell_index = (adev->doorbell_index.ih + 2) << 1;
616
617 r = amdgpu_ih_ring_init(adev, &adev->irq.ih_soft, PAGE_SIZE, true);
618 if (r)
619 return r;
620
621 r = amdgpu_irq_init(adev);
622
623 return r;
624}
625
626static int vega10_ih_sw_fini(void *handle)
627{
628 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
629
630 amdgpu_irq_fini(adev);
631 amdgpu_ih_ring_fini(adev, &adev->irq.ih2);
632 amdgpu_ih_ring_fini(adev, &adev->irq.ih1);
633 amdgpu_ih_ring_fini(adev, &adev->irq.ih);
634
635 return 0;
636}
637
638static int vega10_ih_hw_init(void *handle)
639{
640 int r;
641 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
642
643 r = vega10_ih_irq_init(adev);
644 if (r)
645 return r;
646
647 return 0;
648}
649
650static int vega10_ih_hw_fini(void *handle)
651{
652 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
653
654 vega10_ih_irq_disable(adev);
655
656 return 0;
657}
658
659static int vega10_ih_suspend(void *handle)
660{
661 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
662
663 return vega10_ih_hw_fini(adev);
664}
665
666static int vega10_ih_resume(void *handle)
667{
668 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
669
670 return vega10_ih_hw_init(adev);
671}
672
673static bool vega10_ih_is_idle(void *handle)
674{
675
676 return true;
677}
678
679static int vega10_ih_wait_for_idle(void *handle)
680{
681
682 return -ETIMEDOUT;
683}
684
685static int vega10_ih_soft_reset(void *handle)
686{
687
688
689 return 0;
690}
691
692static void vega10_ih_update_clockgating_state(struct amdgpu_device *adev,
693 bool enable)
694{
695 uint32_t data, def, field_val;
696
697 if (adev->cg_flags & AMD_CG_SUPPORT_IH_CG) {
698 def = data = RREG32_SOC15(OSSSYS, 0, mmIH_CLK_CTRL);
699 field_val = enable ? 0 : 1;
700
701
702
703
704 if (adev->asic_type > CHIP_VEGA10) {
705 data = REG_SET_FIELD(data, IH_CLK_CTRL,
706 IH_RETRY_INT_CAM_MEM_CLK_SOFT_OVERRIDE, field_val);
707 data = REG_SET_FIELD(data, IH_CLK_CTRL,
708 IH_BUFFER_MEM_CLK_SOFT_OVERRIDE, field_val);
709 }
710
711 data = REG_SET_FIELD(data, IH_CLK_CTRL,
712 DBUS_MUX_CLK_SOFT_OVERRIDE, field_val);
713 data = REG_SET_FIELD(data, IH_CLK_CTRL,
714 OSSSYS_SHARE_CLK_SOFT_OVERRIDE, field_val);
715 data = REG_SET_FIELD(data, IH_CLK_CTRL,
716 LIMIT_SMN_CLK_SOFT_OVERRIDE, field_val);
717 data = REG_SET_FIELD(data, IH_CLK_CTRL,
718 DYN_CLK_SOFT_OVERRIDE, field_val);
719 data = REG_SET_FIELD(data, IH_CLK_CTRL,
720 REG_CLK_SOFT_OVERRIDE, field_val);
721 if (def != data)
722 WREG32_SOC15(OSSSYS, 0, mmIH_CLK_CTRL, data);
723 }
724}
725
726static int vega10_ih_set_clockgating_state(void *handle,
727 enum amd_clockgating_state state)
728{
729 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
730
731 vega10_ih_update_clockgating_state(adev,
732 state == AMD_CG_STATE_GATE);
733 return 0;
734
735}
736
737static int vega10_ih_set_powergating_state(void *handle,
738 enum amd_powergating_state state)
739{
740 return 0;
741}
742
743const struct amd_ip_funcs vega10_ih_ip_funcs = {
744 .name = "vega10_ih",
745 .early_init = vega10_ih_early_init,
746 .late_init = NULL,
747 .sw_init = vega10_ih_sw_init,
748 .sw_fini = vega10_ih_sw_fini,
749 .hw_init = vega10_ih_hw_init,
750 .hw_fini = vega10_ih_hw_fini,
751 .suspend = vega10_ih_suspend,
752 .resume = vega10_ih_resume,
753 .is_idle = vega10_ih_is_idle,
754 .wait_for_idle = vega10_ih_wait_for_idle,
755 .soft_reset = vega10_ih_soft_reset,
756 .set_clockgating_state = vega10_ih_set_clockgating_state,
757 .set_powergating_state = vega10_ih_set_powergating_state,
758};
759
760static const struct amdgpu_ih_funcs vega10_ih_funcs = {
761 .get_wptr = vega10_ih_get_wptr,
762 .decode_iv = vega10_ih_decode_iv,
763 .set_rptr = vega10_ih_set_rptr
764};
765
766static void vega10_ih_set_interrupt_funcs(struct amdgpu_device *adev)
767{
768 adev->irq.ih_funcs = &vega10_ih_funcs;
769}
770
771const struct amdgpu_ip_block_version vega10_ih_ip_block =
772{
773 .type = AMD_IP_BLOCK_TYPE_IH,
774 .major = 4,
775 .minor = 0,
776 .rev = 0,
777 .funcs = &vega10_ih_ip_funcs,
778};
779