Merge tag 'for-v5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power...
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / amdgpu / vega10_ih.c
1 /*
2  * Copyright 2016 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  */
23 #include <drm/drmP.h>
24 #include "amdgpu.h"
25 #include "amdgpu_ih.h"
26 #include "soc15.h"
27
28 #include "oss/osssys_4_0_offset.h"
29 #include "oss/osssys_4_0_sh_mask.h"
30
31 #include "soc15_common.h"
32 #include "vega10_ih.h"
33
34
35
36 static void vega10_ih_set_interrupt_funcs(struct amdgpu_device *adev);
37
38 /**
39  * vega10_ih_enable_interrupts - Enable the interrupt ring buffer
40  *
41  * @adev: amdgpu_device pointer
42  *
43  * Enable the interrupt ring buffer (VEGA10).
44  */
45 static void vega10_ih_enable_interrupts(struct amdgpu_device *adev)
46 {
47         u32 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
48
49         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_ENABLE, 1);
50         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, ENABLE_INTR, 1);
51         WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
52         adev->irq.ih.enabled = true;
53
54         if (adev->irq.ih1.ring_size) {
55                 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
56                 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1,
57                                            RB_ENABLE, 1);
58                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
59                 adev->irq.ih1.enabled = true;
60         }
61
62         if (adev->irq.ih2.ring_size) {
63                 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
64                 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2,
65                                            RB_ENABLE, 1);
66                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
67                 adev->irq.ih2.enabled = true;
68         }
69 }
70
71 /**
72  * vega10_ih_disable_interrupts - Disable the interrupt ring buffer
73  *
74  * @adev: amdgpu_device pointer
75  *
76  * Disable the interrupt ring buffer (VEGA10).
77  */
78 static void vega10_ih_disable_interrupts(struct amdgpu_device *adev)
79 {
80         u32 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
81
82         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_ENABLE, 0);
83         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, ENABLE_INTR, 0);
84         WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
85         /* set rptr, wptr to 0 */
86         WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0);
87         WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR, 0);
88         adev->irq.ih.enabled = false;
89         adev->irq.ih.rptr = 0;
90
91         if (adev->irq.ih1.ring_size) {
92                 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
93                 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1,
94                                            RB_ENABLE, 0);
95                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
96                 /* set rptr, wptr to 0 */
97                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, 0);
98                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING1, 0);
99                 adev->irq.ih1.enabled = false;
100                 adev->irq.ih1.rptr = 0;
101         }
102
103         if (adev->irq.ih2.ring_size) {
104                 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
105                 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2,
106                                            RB_ENABLE, 0);
107                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
108                 /* set rptr, wptr to 0 */
109                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, 0);
110                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING2, 0);
111                 adev->irq.ih2.enabled = false;
112                 adev->irq.ih2.rptr = 0;
113         }
114 }
115
116 static uint32_t vega10_ih_rb_cntl(struct amdgpu_ih_ring *ih, uint32_t ih_rb_cntl)
117 {
118         int rb_bufsz = order_base_2(ih->ring_size / 4);
119
120         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
121                                    MC_SPACE, ih->use_bus_addr ? 1 : 4);
122         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
123                                    WPTR_OVERFLOW_CLEAR, 1);
124         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
125                                    WPTR_OVERFLOW_ENABLE, 1);
126         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_SIZE, rb_bufsz);
127         /* Ring Buffer write pointer writeback. If enabled, IH_RB_WPTR register
128          * value is written to memory
129          */
130         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
131                                    WPTR_WRITEBACK_ENABLE, 1);
132         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SNOOP, 1);
133         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_RO, 0);
134         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_VMID, 0);
135
136         return ih_rb_cntl;
137 }
138
139 /**
140  * vega10_ih_irq_init - init and enable the interrupt ring
141  *
142  * @adev: amdgpu_device pointer
143  *
144  * Allocate a ring buffer for the interrupt controller,
145  * enable the RLC, disable interrupts, enable the IH
146  * ring buffer and enable it (VI).
147  * Called at device load and reume.
148  * Returns 0 for success, errors for failure.
149  */
150 static int vega10_ih_irq_init(struct amdgpu_device *adev)
151 {
152         struct amdgpu_ih_ring *ih;
153         int ret = 0;
154         u32 ih_rb_cntl, ih_doorbell_rtpr;
155         u32 tmp;
156
157         /* disable irqs */
158         vega10_ih_disable_interrupts(adev);
159
160         adev->nbio_funcs->ih_control(adev);
161
162         ih = &adev->irq.ih;
163         /* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/
164         WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, ih->gpu_addr >> 8);
165         WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI, (ih->gpu_addr >> 40) & 0xff);
166
167         ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
168         ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
169         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RPTR_REARM,
170                                    !!adev->irq.msi_enabled);
171         WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
172
173         /* set the writeback address whether it's enabled or not */
174         WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_LO,
175                      lower_32_bits(ih->wptr_addr));
176         WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_HI,
177                      upper_32_bits(ih->wptr_addr) & 0xFFFF);
178
179         /* set rptr, wptr to 0 */
180         WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0);
181         WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR, 0);
182
183         ih_doorbell_rtpr = RREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR);
184         if (adev->irq.ih.use_doorbell) {
185                 ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
186                                                  IH_DOORBELL_RPTR, OFFSET,
187                                                  adev->irq.ih.doorbell_index);
188                 ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
189                                                  IH_DOORBELL_RPTR,
190                                                  ENABLE, 1);
191         } else {
192                 ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
193                                                  IH_DOORBELL_RPTR,
194                                                  ENABLE, 0);
195         }
196         WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR, ih_doorbell_rtpr);
197
198         ih = &adev->irq.ih1;
199         if (ih->ring_size) {
200                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_RING1, ih->gpu_addr >> 8);
201                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI_RING1,
202                              (ih->gpu_addr >> 40) & 0xff);
203
204                 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
205                 ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
206                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
207
208                 /* set rptr, wptr to 0 */
209                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, 0);
210                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING1, 0);
211         }
212
213         ih = &adev->irq.ih2;
214         if (ih->ring_size) {
215                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_RING2, ih->gpu_addr >> 8);
216                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI_RING2,
217                              (ih->gpu_addr >> 40) & 0xff);
218
219                 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
220                 ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl);
221                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
222
223                 /* set rptr, wptr to 0 */
224                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, 0);
225                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING2, 0);
226         }
227
228         tmp = RREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL);
229         tmp = REG_SET_FIELD(tmp, IH_STORM_CLIENT_LIST_CNTL,
230                             CLIENT18_IS_STORM_CLIENT, 1);
231         WREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL, tmp);
232
233         tmp = RREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL);
234         tmp = REG_SET_FIELD(tmp, IH_INT_FLOOD_CNTL, FLOOD_CNTL_ENABLE, 1);
235         WREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL, tmp);
236
237         pci_set_master(adev->pdev);
238
239         /* enable interrupts */
240         vega10_ih_enable_interrupts(adev);
241
242         return ret;
243 }
244
245 /**
246  * vega10_ih_irq_disable - disable interrupts
247  *
248  * @adev: amdgpu_device pointer
249  *
250  * Disable interrupts on the hw (VEGA10).
251  */
252 static void vega10_ih_irq_disable(struct amdgpu_device *adev)
253 {
254         vega10_ih_disable_interrupts(adev);
255
256         /* Wait and acknowledge irq */
257         mdelay(1);
258 }
259
260 /**
261  * vega10_ih_get_wptr - get the IH ring buffer wptr
262  *
263  * @adev: amdgpu_device pointer
264  *
265  * Get the IH ring buffer wptr from either the register
266  * or the writeback memory buffer (VEGA10).  Also check for
267  * ring buffer overflow and deal with it.
268  * Returns the value of the wptr.
269  */
270 static u32 vega10_ih_get_wptr(struct amdgpu_device *adev,
271                               struct amdgpu_ih_ring *ih)
272 {
273         u32 wptr, reg, tmp;
274
275         wptr = le32_to_cpu(*ih->wptr_cpu);
276
277         if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
278                 goto out;
279
280         /* Double check that the overflow wasn't already cleared. */
281
282         if (ih == &adev->irq.ih)
283                 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR);
284         else if (ih == &adev->irq.ih1)
285                 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR_RING1);
286         else if (ih == &adev->irq.ih2)
287                 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR_RING2);
288         else
289                 BUG();
290
291         wptr = RREG32_NO_KIQ(reg);
292         if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
293                 goto out;
294
295         wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
296
297         /* When a ring buffer overflow happen start parsing interrupt
298          * from the last not overwritten vector (wptr + 32). Hopefully
299          * this should allow us to catchup.
300          */
301         tmp = (wptr + 32) & ih->ptr_mask;
302         dev_warn(adev->dev, "IH ring buffer overflow "
303                  "(0x%08X, 0x%08X, 0x%08X)\n",
304                  wptr, ih->rptr, tmp);
305         ih->rptr = tmp;
306
307         if (ih == &adev->irq.ih)
308                 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL);
309         else if (ih == &adev->irq.ih1)
310                 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL_RING1);
311         else if (ih == &adev->irq.ih2)
312                 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL_RING2);
313         else
314                 BUG();
315
316         tmp = RREG32_NO_KIQ(reg);
317         tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
318         WREG32_NO_KIQ(reg, tmp);
319
320 out:
321         return (wptr & ih->ptr_mask);
322 }
323
324 /**
325  * vega10_ih_decode_iv - decode an interrupt vector
326  *
327  * @adev: amdgpu_device pointer
328  *
329  * Decodes the interrupt vector at the current rptr
330  * position and also advance the position.
331  */
332 static void vega10_ih_decode_iv(struct amdgpu_device *adev,
333                                 struct amdgpu_ih_ring *ih,
334                                 struct amdgpu_iv_entry *entry)
335 {
336         /* wptr/rptr are in bytes! */
337         u32 ring_index = ih->rptr >> 2;
338         uint32_t dw[8];
339
340         dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
341         dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
342         dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
343         dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
344         dw[4] = le32_to_cpu(ih->ring[ring_index + 4]);
345         dw[5] = le32_to_cpu(ih->ring[ring_index + 5]);
346         dw[6] = le32_to_cpu(ih->ring[ring_index + 6]);
347         dw[7] = le32_to_cpu(ih->ring[ring_index + 7]);
348
349         entry->client_id = dw[0] & 0xff;
350         entry->src_id = (dw[0] >> 8) & 0xff;
351         entry->ring_id = (dw[0] >> 16) & 0xff;
352         entry->vmid = (dw[0] >> 24) & 0xf;
353         entry->vmid_src = (dw[0] >> 31);
354         entry->timestamp = dw[1] | ((u64)(dw[2] & 0xffff) << 32);
355         entry->timestamp_src = dw[2] >> 31;
356         entry->pasid = dw[3] & 0xffff;
357         entry->pasid_src = dw[3] >> 31;
358         entry->src_data[0] = dw[4];
359         entry->src_data[1] = dw[5];
360         entry->src_data[2] = dw[6];
361         entry->src_data[3] = dw[7];
362
363         /* wptr/rptr are in bytes! */
364         ih->rptr += 32;
365 }
366
367 /**
368  * vega10_ih_set_rptr - set the IH ring buffer rptr
369  *
370  * @adev: amdgpu_device pointer
371  *
372  * Set the IH ring buffer rptr.
373  */
374 static void vega10_ih_set_rptr(struct amdgpu_device *adev,
375                                struct amdgpu_ih_ring *ih)
376 {
377         if (ih->use_doorbell) {
378                 /* XXX check if swapping is necessary on BE */
379                 *ih->rptr_cpu = ih->rptr;
380                 WDOORBELL32(ih->doorbell_index, ih->rptr);
381         } else if (ih == &adev->irq.ih) {
382                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr);
383         } else if (ih == &adev->irq.ih1) {
384                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, ih->rptr);
385         } else if (ih == &adev->irq.ih2) {
386                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, ih->rptr);
387         }
388 }
389
390 /**
391  * vega10_ih_self_irq - dispatch work for ring 1 and 2
392  *
393  * @adev: amdgpu_device pointer
394  * @source: irq source
395  * @entry: IV with WPTR update
396  *
397  * Update the WPTR from the IV and schedule work to handle the entries.
398  */
399 static int vega10_ih_self_irq(struct amdgpu_device *adev,
400                               struct amdgpu_irq_src *source,
401                               struct amdgpu_iv_entry *entry)
402 {
403         uint32_t wptr = cpu_to_le32(entry->src_data[0]);
404
405         switch (entry->ring_id) {
406         case 1:
407                 *adev->irq.ih1.wptr_cpu = wptr;
408                 schedule_work(&adev->irq.ih1_work);
409                 break;
410         case 2:
411                 *adev->irq.ih2.wptr_cpu = wptr;
412                 schedule_work(&adev->irq.ih2_work);
413                 break;
414         default: break;
415         }
416         return 0;
417 }
418
419 static const struct amdgpu_irq_src_funcs vega10_ih_self_irq_funcs = {
420         .process = vega10_ih_self_irq,
421 };
422
423 static void vega10_ih_set_self_irq_funcs(struct amdgpu_device *adev)
424 {
425         adev->irq.self_irq.num_types = 0;
426         adev->irq.self_irq.funcs = &vega10_ih_self_irq_funcs;
427 }
428
429 static int vega10_ih_early_init(void *handle)
430 {
431         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
432
433         vega10_ih_set_interrupt_funcs(adev);
434         vega10_ih_set_self_irq_funcs(adev);
435         return 0;
436 }
437
438 static int vega10_ih_sw_init(void *handle)
439 {
440         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
441         int r;
442
443         r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_IH, 0,
444                               &adev->irq.self_irq);
445         if (r)
446                 return r;
447
448         r = amdgpu_ih_ring_init(adev, &adev->irq.ih, 256 * 1024, true);
449         if (r)
450                 return r;
451
452         if (adev->asic_type == CHIP_VEGA10) {
453                 r = amdgpu_ih_ring_init(adev, &adev->irq.ih1, PAGE_SIZE, true);
454                 if (r)
455                         return r;
456
457                 r = amdgpu_ih_ring_init(adev, &adev->irq.ih2, PAGE_SIZE, true);
458                 if (r)
459                         return r;
460         }
461
462         /* TODO add doorbell for IH1 & IH2 as well */
463         adev->irq.ih.use_doorbell = true;
464         adev->irq.ih.doorbell_index = adev->doorbell_index.ih << 1;
465
466         r = amdgpu_irq_init(adev);
467
468         return r;
469 }
470
471 static int vega10_ih_sw_fini(void *handle)
472 {
473         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
474
475         amdgpu_irq_fini(adev);
476         amdgpu_ih_ring_fini(adev, &adev->irq.ih2);
477         amdgpu_ih_ring_fini(adev, &adev->irq.ih1);
478         amdgpu_ih_ring_fini(adev, &adev->irq.ih);
479
480         return 0;
481 }
482
483 static int vega10_ih_hw_init(void *handle)
484 {
485         int r;
486         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
487
488         r = vega10_ih_irq_init(adev);
489         if (r)
490                 return r;
491
492         return 0;
493 }
494
495 static int vega10_ih_hw_fini(void *handle)
496 {
497         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
498
499         vega10_ih_irq_disable(adev);
500
501         return 0;
502 }
503
504 static int vega10_ih_suspend(void *handle)
505 {
506         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
507
508         return vega10_ih_hw_fini(adev);
509 }
510
511 static int vega10_ih_resume(void *handle)
512 {
513         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
514
515         return vega10_ih_hw_init(adev);
516 }
517
518 static bool vega10_ih_is_idle(void *handle)
519 {
520         /* todo */
521         return true;
522 }
523
524 static int vega10_ih_wait_for_idle(void *handle)
525 {
526         /* todo */
527         return -ETIMEDOUT;
528 }
529
530 static int vega10_ih_soft_reset(void *handle)
531 {
532         /* todo */
533
534         return 0;
535 }
536
537 static int vega10_ih_set_clockgating_state(void *handle,
538                                           enum amd_clockgating_state state)
539 {
540         return 0;
541 }
542
543 static int vega10_ih_set_powergating_state(void *handle,
544                                           enum amd_powergating_state state)
545 {
546         return 0;
547 }
548
549 const struct amd_ip_funcs vega10_ih_ip_funcs = {
550         .name = "vega10_ih",
551         .early_init = vega10_ih_early_init,
552         .late_init = NULL,
553         .sw_init = vega10_ih_sw_init,
554         .sw_fini = vega10_ih_sw_fini,
555         .hw_init = vega10_ih_hw_init,
556         .hw_fini = vega10_ih_hw_fini,
557         .suspend = vega10_ih_suspend,
558         .resume = vega10_ih_resume,
559         .is_idle = vega10_ih_is_idle,
560         .wait_for_idle = vega10_ih_wait_for_idle,
561         .soft_reset = vega10_ih_soft_reset,
562         .set_clockgating_state = vega10_ih_set_clockgating_state,
563         .set_powergating_state = vega10_ih_set_powergating_state,
564 };
565
566 static const struct amdgpu_ih_funcs vega10_ih_funcs = {
567         .get_wptr = vega10_ih_get_wptr,
568         .decode_iv = vega10_ih_decode_iv,
569         .set_rptr = vega10_ih_set_rptr
570 };
571
572 static void vega10_ih_set_interrupt_funcs(struct amdgpu_device *adev)
573 {
574         adev->irq.ih_funcs = &vega10_ih_funcs;
575 }
576
577 const struct amdgpu_ip_block_version vega10_ih_ip_block =
578 {
579         .type = AMD_IP_BLOCK_TYPE_IH,
580         .major = 4,
581         .minor = 0,
582         .rev = 0,
583         .funcs = &vega10_ih_ip_funcs,
584 };