Merge tag 'kvmarm-fixes-5.11-2' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / amdgpu / navi10_ih.c
1 /*
2  * Copyright 2019 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
24 #include <linux/pci.h>
25
26 #include "amdgpu.h"
27 #include "amdgpu_ih.h"
28
29 #include "oss/osssys_5_0_0_offset.h"
30 #include "oss/osssys_5_0_0_sh_mask.h"
31
32 #include "soc15_common.h"
33 #include "navi10_ih.h"
34
35 #define MAX_REARM_RETRY 10
36
37 #define mmIH_CHICKEN_Sienna_Cichlid                 0x018d
38 #define mmIH_CHICKEN_Sienna_Cichlid_BASE_IDX        0
39
40 static void navi10_ih_set_interrupt_funcs(struct amdgpu_device *adev);
41
42 /**
43  * force_update_wptr_for_self_int - Force update the wptr for self interrupt
44  *
45  * @adev: amdgpu_device pointer
46  * @threshold: threshold to trigger the wptr reporting
47  * @timeout: timeout to trigger the wptr reporting
48  * @enabled: Enable/disable timeout flush mechanism
49  *
50  * threshold input range: 0 ~ 15, default 0,
51  * real_threshold = 2^threshold
52  * timeout input range: 0 ~ 20, default 8,
53  * real_timeout = (2^timeout) * 1024 / (socclk_freq)
54  *
55  * Force update wptr for self interrupt ( >= SIENNA_CICHLID).
56  */
57 static void
58 force_update_wptr_for_self_int(struct amdgpu_device *adev,
59                                u32 threshold, u32 timeout, bool enabled)
60 {
61         u32 ih_cntl, ih_rb_cntl;
62
63         if (adev->asic_type < CHIP_SIENNA_CICHLID)
64                 return;
65
66         ih_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_CNTL2);
67         ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
68
69         ih_cntl = REG_SET_FIELD(ih_cntl, IH_CNTL2,
70                                 SELF_IV_FORCE_WPTR_UPDATE_TIMEOUT, timeout);
71         ih_cntl = REG_SET_FIELD(ih_cntl, IH_CNTL2,
72                                 SELF_IV_FORCE_WPTR_UPDATE_ENABLE, enabled);
73         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1,
74                                    RB_USED_INT_THRESHOLD, threshold);
75
76         WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
77         ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
78         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2,
79                                    RB_USED_INT_THRESHOLD, threshold);
80         WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
81         WREG32_SOC15(OSSSYS, 0, mmIH_CNTL2, ih_cntl);
82 }
83
84 /**
85  * navi10_ih_enable_interrupts - Enable the interrupt ring buffer
86  *
87  * @adev: amdgpu_device pointer
88  *
89  * Enable the interrupt ring buffer (NAVI10).
90  */
91 static void navi10_ih_enable_interrupts(struct amdgpu_device *adev)
92 {
93         u32 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
94
95         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_ENABLE, 1);
96         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, ENABLE_INTR, 1);
97         if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
98                 if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL, ih_rb_cntl)) {
99                         DRM_ERROR("PSP program IH_RB_CNTL failed!\n");
100                         return;
101                 }
102         } else {
103                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
104         }
105
106         adev->irq.ih.enabled = true;
107
108         if (adev->irq.ih1.ring_size) {
109                 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
110                 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1,
111                                            RB_ENABLE, 1);
112                 if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
113                         if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING1,
114                                                 ih_rb_cntl)) {
115                                 DRM_ERROR("program IH_RB_CNTL_RING1 failed!\n");
116                                 return;
117                         }
118                 } else {
119                         WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
120                 }
121                 adev->irq.ih1.enabled = true;
122         }
123
124         if (adev->irq.ih2.ring_size) {
125                 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
126                 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2,
127                                            RB_ENABLE, 1);
128                 if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
129                         if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING2,
130                                                 ih_rb_cntl)) {
131                                 DRM_ERROR("program IH_RB_CNTL_RING2 failed!\n");
132                                 return;
133                         }
134                 } else {
135                         WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
136                 }
137                 adev->irq.ih2.enabled = true;
138         }
139
140         if (adev->irq.ih_soft.ring_size)
141                 adev->irq.ih_soft.enabled = true;
142 }
143
144 /**
145  * navi10_ih_disable_interrupts - Disable the interrupt ring buffer
146  *
147  * @adev: amdgpu_device pointer
148  *
149  * Disable the interrupt ring buffer (NAVI10).
150  */
151 static void navi10_ih_disable_interrupts(struct amdgpu_device *adev)
152 {
153         u32 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
154
155         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_ENABLE, 0);
156         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, ENABLE_INTR, 0);
157         if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
158                 if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL, ih_rb_cntl)) {
159                         DRM_ERROR("PSP program IH_RB_CNTL failed!\n");
160                         return;
161                 }
162         } else {
163                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
164         }
165
166         /* set rptr, wptr to 0 */
167         WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0);
168         WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR, 0);
169         adev->irq.ih.enabled = false;
170         adev->irq.ih.rptr = 0;
171
172         if (adev->irq.ih1.ring_size) {
173                 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
174                 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1,
175                                            RB_ENABLE, 0);
176                 if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
177                         if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING1,
178                                                 ih_rb_cntl)) {
179                                 DRM_ERROR("program IH_RB_CNTL_RING1 failed!\n");
180                                 return;
181                         }
182                 } else {
183                         WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
184                 }
185                 /* set rptr, wptr to 0 */
186                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, 0);
187                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING1, 0);
188                 adev->irq.ih1.enabled = false;
189                 adev->irq.ih1.rptr = 0;
190         }
191
192         if (adev->irq.ih2.ring_size) {
193                 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
194                 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2,
195                                            RB_ENABLE, 0);
196                 if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
197                         if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING2,
198                                                 ih_rb_cntl)) {
199                                 DRM_ERROR("program IH_RB_CNTL_RING2 failed!\n");
200                                 return;
201                         }
202                 } else {
203                         WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
204                 }
205                 /* set rptr, wptr to 0 */
206                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, 0);
207                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING2, 0);
208                 adev->irq.ih2.enabled = false;
209                 adev->irq.ih2.rptr = 0;
210         }
211
212 }
213
214 static uint32_t navi10_ih_rb_cntl(struct amdgpu_ih_ring *ih, uint32_t ih_rb_cntl)
215 {
216         int rb_bufsz = order_base_2(ih->ring_size / 4);
217
218         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
219                                    MC_SPACE, ih->use_bus_addr ? 1 : 4);
220         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
221                                    WPTR_OVERFLOW_CLEAR, 1);
222         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
223                                    WPTR_OVERFLOW_ENABLE, 1);
224         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_SIZE, rb_bufsz);
225         /* Ring Buffer write pointer writeback. If enabled, IH_RB_WPTR register
226          * value is written to memory
227          */
228         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
229                                    WPTR_WRITEBACK_ENABLE, 1);
230         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SNOOP, 1);
231         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_RO, 0);
232         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_VMID, 0);
233
234         return ih_rb_cntl;
235 }
236
237 static uint32_t navi10_ih_doorbell_rptr(struct amdgpu_ih_ring *ih)
238 {
239         u32 ih_doorbell_rtpr = 0;
240
241         if (ih->use_doorbell) {
242                 ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
243                                                  IH_DOORBELL_RPTR, OFFSET,
244                                                  ih->doorbell_index);
245                 ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
246                                                  IH_DOORBELL_RPTR,
247                                                  ENABLE, 1);
248         } else {
249                 ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
250                                                  IH_DOORBELL_RPTR,
251                                                  ENABLE, 0);
252         }
253         return ih_doorbell_rtpr;
254 }
255
256 static void navi10_ih_reroute_ih(struct amdgpu_device *adev)
257 {
258         uint32_t tmp;
259
260         /* Reroute to IH ring 1 for VMC */
261         WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_INDEX, 0x12);
262         tmp = RREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA);
263         tmp = REG_SET_FIELD(tmp, IH_CLIENT_CFG_DATA, CLIENT_TYPE, 1);
264         tmp = REG_SET_FIELD(tmp, IH_CLIENT_CFG_DATA, RING_ID, 1);
265         WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA, tmp);
266
267         /* Reroute IH ring 1 for UMC */
268         WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_INDEX, 0x1B);
269         tmp = RREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA);
270         tmp = REG_SET_FIELD(tmp, IH_CLIENT_CFG_DATA, RING_ID, 1);
271         WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA, tmp);
272 }
273
274 /**
275  * navi10_ih_irq_init - init and enable the interrupt ring
276  *
277  * @adev: amdgpu_device pointer
278  *
279  * Allocate a ring buffer for the interrupt controller,
280  * enable the RLC, disable interrupts, enable the IH
281  * ring buffer and enable it (NAVI).
282  * Called at device load and reume.
283  * Returns 0 for success, errors for failure.
284  */
285 static int navi10_ih_irq_init(struct amdgpu_device *adev)
286 {
287         struct amdgpu_ih_ring *ih = &adev->irq.ih;
288         u32 ih_rb_cntl, ih_chicken;
289         u32 tmp;
290
291         /* disable irqs */
292         navi10_ih_disable_interrupts(adev);
293
294         adev->nbio.funcs->ih_control(adev);
295
296         /* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/
297         WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, ih->gpu_addr >> 8);
298         WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI, (ih->gpu_addr >> 40) & 0xff);
299
300         ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
301         ih_rb_cntl = navi10_ih_rb_cntl(ih, ih_rb_cntl);
302         ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RPTR_REARM,
303                                    !!adev->irq.msi_enabled);
304         if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
305                 if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL, ih_rb_cntl)) {
306                         DRM_ERROR("PSP program IH_RB_CNTL failed!\n");
307                         return -ETIMEDOUT;
308                 }
309         } else {
310                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
311         }
312         if (adev->irq.ih1.ring_size)
313                 navi10_ih_reroute_ih(adev);
314
315         if (unlikely(adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT)) {
316                 if (ih->use_bus_addr) {
317                         switch (adev->asic_type) {
318                         case CHIP_SIENNA_CICHLID:
319                         case CHIP_NAVY_FLOUNDER:
320                         case CHIP_VANGOGH:
321                         case CHIP_DIMGREY_CAVEFISH:
322                                 ih_chicken = RREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN_Sienna_Cichlid);
323                                 ih_chicken = REG_SET_FIELD(ih_chicken,
324                                                 IH_CHICKEN, MC_SPACE_GPA_ENABLE, 1);
325                                 WREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN_Sienna_Cichlid, ih_chicken);
326                                 break;
327                         default:
328                                 ih_chicken = RREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN);
329                                 ih_chicken = REG_SET_FIELD(ih_chicken,
330                                                 IH_CHICKEN, MC_SPACE_GPA_ENABLE, 1);
331                                 WREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN, ih_chicken);
332                                 break;
333                         }
334                 }
335         }
336
337         /* set the writeback address whether it's enabled or not */
338         WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_LO,
339                      lower_32_bits(ih->wptr_addr));
340         WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_HI,
341                      upper_32_bits(ih->wptr_addr) & 0xFFFF);
342
343         /* set rptr, wptr to 0 */
344         WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0);
345         WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR, 0);
346
347         WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR,
348                         navi10_ih_doorbell_rptr(ih));
349
350         adev->nbio.funcs->ih_doorbell_range(adev, ih->use_doorbell,
351                                             ih->doorbell_index);
352
353         ih = &adev->irq.ih1;
354         if (ih->ring_size) {
355                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_RING1, ih->gpu_addr >> 8);
356                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI_RING1,
357                              (ih->gpu_addr >> 40) & 0xff);
358
359                 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
360                 ih_rb_cntl = navi10_ih_rb_cntl(ih, ih_rb_cntl);
361                 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
362                                            WPTR_OVERFLOW_ENABLE, 0);
363                 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
364                                            RB_FULL_DRAIN_ENABLE, 1);
365                 if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
366                         if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING1,
367                                                 ih_rb_cntl)) {
368                                 DRM_ERROR("program IH_RB_CNTL_RING1 failed!\n");
369                                 return -ETIMEDOUT;
370                         }
371                 } else {
372                         WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
373                 }
374                 /* set rptr, wptr to 0 */
375                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING1, 0);
376                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, 0);
377
378                 WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR_RING1,
379                                 navi10_ih_doorbell_rptr(ih));
380         }
381
382         ih = &adev->irq.ih2;
383         if (ih->ring_size) {
384                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_RING2, ih->gpu_addr >> 8);
385                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI_RING2,
386                              (ih->gpu_addr >> 40) & 0xff);
387
388                 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
389                 ih_rb_cntl = navi10_ih_rb_cntl(ih, ih_rb_cntl);
390
391                 if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
392                         if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING2,
393                                                 ih_rb_cntl)) {
394                                 DRM_ERROR("program IH_RB_CNTL_RING2 failed!\n");
395                                 return -ETIMEDOUT;
396                         }
397                 } else {
398                         WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
399                 }
400                 /* set rptr, wptr to 0 */
401                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING2, 0);
402                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, 0);
403
404                 WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR_RING2,
405                              navi10_ih_doorbell_rptr(ih));
406         }
407
408
409         tmp = RREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL);
410         tmp = REG_SET_FIELD(tmp, IH_STORM_CLIENT_LIST_CNTL,
411                             CLIENT18_IS_STORM_CLIENT, 1);
412         WREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL, tmp);
413
414         tmp = RREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL);
415         tmp = REG_SET_FIELD(tmp, IH_INT_FLOOD_CNTL, FLOOD_CNTL_ENABLE, 1);
416         WREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL, tmp);
417
418         pci_set_master(adev->pdev);
419
420         /* enable interrupts */
421         navi10_ih_enable_interrupts(adev);
422         /* enable wptr force update for self int */
423         force_update_wptr_for_self_int(adev, 0, 8, true);
424
425         return 0;
426 }
427
428 /**
429  * navi10_ih_irq_disable - disable interrupts
430  *
431  * @adev: amdgpu_device pointer
432  *
433  * Disable interrupts on the hw (NAVI10).
434  */
435 static void navi10_ih_irq_disable(struct amdgpu_device *adev)
436 {
437         force_update_wptr_for_self_int(adev, 0, 8, false);
438         navi10_ih_disable_interrupts(adev);
439
440         /* Wait and acknowledge irq */
441         mdelay(1);
442 }
443
444 /**
445  * navi10_ih_get_wptr - get the IH ring buffer wptr
446  *
447  * @adev: amdgpu_device pointer
448  * @ih: IH ring buffer to fetch wptr
449  *
450  * Get the IH ring buffer wptr from either the register
451  * or the writeback memory buffer (NAVI10).  Also check for
452  * ring buffer overflow and deal with it.
453  * Returns the value of the wptr.
454  */
455 static u32 navi10_ih_get_wptr(struct amdgpu_device *adev,
456                               struct amdgpu_ih_ring *ih)
457 {
458         u32 wptr, reg, tmp;
459
460         wptr = le32_to_cpu(*ih->wptr_cpu);
461
462         if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
463                 goto out;
464
465         if (ih == &adev->irq.ih)
466                 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR);
467         else if (ih == &adev->irq.ih1)
468                 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR_RING1);
469         else if (ih == &adev->irq.ih2)
470                 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR_RING2);
471         else
472                 BUG();
473
474         wptr = RREG32_NO_KIQ(reg);
475         if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
476                 goto out;
477         wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
478
479         /* When a ring buffer overflow happen start parsing interrupt
480          * from the last not overwritten vector (wptr + 32). Hopefully
481          * this should allow us to catch up.
482          */
483         tmp = (wptr + 32) & ih->ptr_mask;
484         dev_warn(adev->dev, "IH ring buffer overflow "
485                  "(0x%08X, 0x%08X, 0x%08X)\n",
486                  wptr, ih->rptr, tmp);
487         ih->rptr = tmp;
488
489         if (ih == &adev->irq.ih)
490                 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL);
491         else if (ih == &adev->irq.ih1)
492                 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL_RING1);
493         else if (ih == &adev->irq.ih2)
494                 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL_RING2);
495         else
496                 BUG();
497
498         tmp = RREG32_NO_KIQ(reg);
499         tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
500         WREG32_NO_KIQ(reg, tmp);
501 out:
502         return (wptr & ih->ptr_mask);
503 }
504
505 /**
506  * navi10_ih_decode_iv - decode an interrupt vector
507  *
508  * @adev: amdgpu_device pointer
509  * @ih: IH ring buffer to decode
510  * @entry: IV entry to place decoded information into
511  *
512  * Decodes the interrupt vector at the current rptr
513  * position and also advance the position.
514  */
515 static void navi10_ih_decode_iv(struct amdgpu_device *adev,
516                                 struct amdgpu_ih_ring *ih,
517                                 struct amdgpu_iv_entry *entry)
518 {
519         /* wptr/rptr are in bytes! */
520         u32 ring_index = ih->rptr >> 2;
521         uint32_t dw[8];
522
523         dw[0] = le32_to_cpu(ih->ring[ring_index + 0]);
524         dw[1] = le32_to_cpu(ih->ring[ring_index + 1]);
525         dw[2] = le32_to_cpu(ih->ring[ring_index + 2]);
526         dw[3] = le32_to_cpu(ih->ring[ring_index + 3]);
527         dw[4] = le32_to_cpu(ih->ring[ring_index + 4]);
528         dw[5] = le32_to_cpu(ih->ring[ring_index + 5]);
529         dw[6] = le32_to_cpu(ih->ring[ring_index + 6]);
530         dw[7] = le32_to_cpu(ih->ring[ring_index + 7]);
531
532         entry->client_id = dw[0] & 0xff;
533         entry->src_id = (dw[0] >> 8) & 0xff;
534         entry->ring_id = (dw[0] >> 16) & 0xff;
535         entry->vmid = (dw[0] >> 24) & 0xf;
536         entry->vmid_src = (dw[0] >> 31);
537         entry->timestamp = dw[1] | ((u64)(dw[2] & 0xffff) << 32);
538         entry->timestamp_src = dw[2] >> 31;
539         entry->pasid = dw[3] & 0xffff;
540         entry->pasid_src = dw[3] >> 31;
541         entry->src_data[0] = dw[4];
542         entry->src_data[1] = dw[5];
543         entry->src_data[2] = dw[6];
544         entry->src_data[3] = dw[7];
545
546         /* wptr/rptr are in bytes! */
547         ih->rptr += 32;
548 }
549
550 /**
551  * navi10_ih_irq_rearm - rearm IRQ if lost
552  *
553  * @adev: amdgpu_device pointer
554  * @ih: IH ring to match
555  *
556  */
557 static void navi10_ih_irq_rearm(struct amdgpu_device *adev,
558                                struct amdgpu_ih_ring *ih)
559 {
560         uint32_t reg_rptr = 0;
561         uint32_t v = 0;
562         uint32_t i = 0;
563
564         if (ih == &adev->irq.ih)
565                 reg_rptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_RPTR);
566         else if (ih == &adev->irq.ih1)
567                 reg_rptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_RPTR_RING1);
568         else if (ih == &adev->irq.ih2)
569                 reg_rptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_RPTR_RING2);
570         else
571                 return;
572
573         /* Rearm IRQ / re-write doorbell if doorbell write is lost */
574         for (i = 0; i < MAX_REARM_RETRY; i++) {
575                 v = RREG32_NO_KIQ(reg_rptr);
576                 if ((v < ih->ring_size) && (v != ih->rptr))
577                         WDOORBELL32(ih->doorbell_index, ih->rptr);
578                 else
579                         break;
580         }
581 }
582
583 /**
584  * navi10_ih_set_rptr - set the IH ring buffer rptr
585  *
586  * @adev: amdgpu_device pointer
587  *
588  * @ih: IH ring buffer to set rptr
589  * Set the IH ring buffer rptr.
590  */
591 static void navi10_ih_set_rptr(struct amdgpu_device *adev,
592                                struct amdgpu_ih_ring *ih)
593 {
594         if (ih->use_doorbell) {
595                 /* XXX check if swapping is necessary on BE */
596                 *ih->rptr_cpu = ih->rptr;
597                 WDOORBELL32(ih->doorbell_index, ih->rptr);
598
599                 if (amdgpu_sriov_vf(adev))
600                         navi10_ih_irq_rearm(adev, ih);
601         } else if (ih == &adev->irq.ih) {
602                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr);
603         } else if (ih == &adev->irq.ih1) {
604                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, ih->rptr);
605         } else if (ih == &adev->irq.ih2) {
606                 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, ih->rptr);
607         }
608 }
609
610 /**
611  * navi10_ih_self_irq - dispatch work for ring 1 and 2
612  *
613  * @adev: amdgpu_device pointer
614  * @source: irq source
615  * @entry: IV with WPTR update
616  *
617  * Update the WPTR from the IV and schedule work to handle the entries.
618  */
619 static int navi10_ih_self_irq(struct amdgpu_device *adev,
620                               struct amdgpu_irq_src *source,
621                               struct amdgpu_iv_entry *entry)
622 {
623         uint32_t wptr = cpu_to_le32(entry->src_data[0]);
624
625         switch (entry->ring_id) {
626         case 1:
627                 *adev->irq.ih1.wptr_cpu = wptr;
628                 schedule_work(&adev->irq.ih1_work);
629                 break;
630         case 2:
631                 *adev->irq.ih2.wptr_cpu = wptr;
632                 schedule_work(&adev->irq.ih2_work);
633                 break;
634         default: break;
635         }
636         return 0;
637 }
638
639 static const struct amdgpu_irq_src_funcs navi10_ih_self_irq_funcs = {
640         .process = navi10_ih_self_irq,
641 };
642
643 static void navi10_ih_set_self_irq_funcs(struct amdgpu_device *adev)
644 {
645         adev->irq.self_irq.num_types = 0;
646         adev->irq.self_irq.funcs = &navi10_ih_self_irq_funcs;
647 }
648
649 static int navi10_ih_early_init(void *handle)
650 {
651         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
652
653         navi10_ih_set_interrupt_funcs(adev);
654         navi10_ih_set_self_irq_funcs(adev);
655         return 0;
656 }
657
658 static int navi10_ih_sw_init(void *handle)
659 {
660         int r;
661         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
662         bool use_bus_addr;
663
664         r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_IH, 0,
665                                 &adev->irq.self_irq);
666
667         if (r)
668                 return r;
669
670         /* use gpu virtual address for ih ring
671          * until ih_checken is programmed to allow
672          * use bus address for ih ring by psp bl */
673         if ((adev->flags & AMD_IS_APU) ||
674             (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP))
675                 use_bus_addr = false;
676         else
677                 use_bus_addr = true;
678         r = amdgpu_ih_ring_init(adev, &adev->irq.ih, 256 * 1024, use_bus_addr);
679         if (r)
680                 return r;
681
682         adev->irq.ih.use_doorbell = true;
683         adev->irq.ih.doorbell_index = adev->doorbell_index.ih << 1;
684
685         adev->irq.ih1.ring_size = 0;
686         adev->irq.ih2.ring_size = 0;
687
688         if (adev->asic_type < CHIP_NAVI10) {
689                 r = amdgpu_ih_ring_init(adev, &adev->irq.ih1, PAGE_SIZE, true);
690                 if (r)
691                         return r;
692
693                 adev->irq.ih1.use_doorbell = true;
694                 adev->irq.ih1.doorbell_index =
695                                         (adev->doorbell_index.ih + 1) << 1;
696
697                 r = amdgpu_ih_ring_init(adev, &adev->irq.ih2, PAGE_SIZE, true);
698                 if (r)
699                         return r;
700
701                 adev->irq.ih2.use_doorbell = true;
702                 adev->irq.ih2.doorbell_index =
703                                         (adev->doorbell_index.ih + 2) << 1;
704         }
705
706         r = amdgpu_ih_ring_init(adev, &adev->irq.ih_soft, PAGE_SIZE, true);
707         if (r)
708                 return r;
709
710         r = amdgpu_irq_init(adev);
711
712         return r;
713 }
714
715 static int navi10_ih_sw_fini(void *handle)
716 {
717         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
718
719         amdgpu_irq_fini(adev);
720         amdgpu_ih_ring_fini(adev, &adev->irq.ih2);
721         amdgpu_ih_ring_fini(adev, &adev->irq.ih1);
722         amdgpu_ih_ring_fini(adev, &adev->irq.ih);
723
724         return 0;
725 }
726
727 static int navi10_ih_hw_init(void *handle)
728 {
729         int r;
730         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
731
732         r = navi10_ih_irq_init(adev);
733         if (r)
734                 return r;
735
736         return 0;
737 }
738
739 static int navi10_ih_hw_fini(void *handle)
740 {
741         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
742
743         navi10_ih_irq_disable(adev);
744
745         return 0;
746 }
747
748 static int navi10_ih_suspend(void *handle)
749 {
750         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
751
752         return navi10_ih_hw_fini(adev);
753 }
754
755 static int navi10_ih_resume(void *handle)
756 {
757         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
758
759         return navi10_ih_hw_init(adev);
760 }
761
762 static bool navi10_ih_is_idle(void *handle)
763 {
764         /* todo */
765         return true;
766 }
767
768 static int navi10_ih_wait_for_idle(void *handle)
769 {
770         /* todo */
771         return -ETIMEDOUT;
772 }
773
774 static int navi10_ih_soft_reset(void *handle)
775 {
776         /* todo */
777         return 0;
778 }
779
780 static void navi10_ih_update_clockgating_state(struct amdgpu_device *adev,
781                                                bool enable)
782 {
783         uint32_t data, def, field_val;
784
785         if (adev->cg_flags & AMD_CG_SUPPORT_IH_CG) {
786                 def = data = RREG32_SOC15(OSSSYS, 0, mmIH_CLK_CTRL);
787                 field_val = enable ? 0 : 1;
788                 data = REG_SET_FIELD(data, IH_CLK_CTRL,
789                                      DBUS_MUX_CLK_SOFT_OVERRIDE, field_val);
790                 data = REG_SET_FIELD(data, IH_CLK_CTRL,
791                                      OSSSYS_SHARE_CLK_SOFT_OVERRIDE, field_val);
792                 data = REG_SET_FIELD(data, IH_CLK_CTRL,
793                                      LIMIT_SMN_CLK_SOFT_OVERRIDE, field_val);
794                 data = REG_SET_FIELD(data, IH_CLK_CTRL,
795                                      DYN_CLK_SOFT_OVERRIDE, field_val);
796                 data = REG_SET_FIELD(data, IH_CLK_CTRL,
797                                      REG_CLK_SOFT_OVERRIDE, field_val);
798                 if (def != data)
799                         WREG32_SOC15(OSSSYS, 0, mmIH_CLK_CTRL, data);
800         }
801
802         return;
803 }
804
805 static int navi10_ih_set_clockgating_state(void *handle,
806                                            enum amd_clockgating_state state)
807 {
808         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
809
810         navi10_ih_update_clockgating_state(adev,
811                                 state == AMD_CG_STATE_GATE);
812         return 0;
813 }
814
815 static int navi10_ih_set_powergating_state(void *handle,
816                                            enum amd_powergating_state state)
817 {
818         return 0;
819 }
820
821 static void navi10_ih_get_clockgating_state(void *handle, u32 *flags)
822 {
823         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
824
825         if (!RREG32_SOC15(OSSSYS, 0, mmIH_CLK_CTRL))
826                 *flags |= AMD_CG_SUPPORT_IH_CG;
827
828         return;
829 }
830
831 static const struct amd_ip_funcs navi10_ih_ip_funcs = {
832         .name = "navi10_ih",
833         .early_init = navi10_ih_early_init,
834         .late_init = NULL,
835         .sw_init = navi10_ih_sw_init,
836         .sw_fini = navi10_ih_sw_fini,
837         .hw_init = navi10_ih_hw_init,
838         .hw_fini = navi10_ih_hw_fini,
839         .suspend = navi10_ih_suspend,
840         .resume = navi10_ih_resume,
841         .is_idle = navi10_ih_is_idle,
842         .wait_for_idle = navi10_ih_wait_for_idle,
843         .soft_reset = navi10_ih_soft_reset,
844         .set_clockgating_state = navi10_ih_set_clockgating_state,
845         .set_powergating_state = navi10_ih_set_powergating_state,
846         .get_clockgating_state = navi10_ih_get_clockgating_state,
847 };
848
849 static const struct amdgpu_ih_funcs navi10_ih_funcs = {
850         .get_wptr = navi10_ih_get_wptr,
851         .decode_iv = navi10_ih_decode_iv,
852         .set_rptr = navi10_ih_set_rptr
853 };
854
855 static void navi10_ih_set_interrupt_funcs(struct amdgpu_device *adev)
856 {
857         if (adev->irq.ih_funcs == NULL)
858                 adev->irq.ih_funcs = &navi10_ih_funcs;
859 }
860
861 const struct amdgpu_ip_block_version navi10_ih_ip_block =
862 {
863         .type = AMD_IP_BLOCK_TYPE_IH,
864         .major = 5,
865         .minor = 0,
866         .rev = 0,
867         .funcs = &navi10_ih_ip_funcs,
868 };