Merge remote-tracking branches 'regulator/topic/pv88090', 'regulator/topic/qcom-smd...
[cascardo/linux.git] / drivers / gpu / drm / amd / amdgpu / vce_v3_0.c
1 /*
2  * Copyright 2014 Advanced Micro Devices, Inc.
3  * All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sub license, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
17  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19  * USE OR OTHER DEALINGS IN THE SOFTWARE.
20  *
21  * The above copyright notice and this permission notice (including the
22  * next paragraph) shall be included in all copies or substantial portions
23  * of the Software.
24  *
25  * Authors: Christian König <christian.koenig@amd.com>
26  */
27
28 #include <linux/firmware.h>
29 #include <drm/drmP.h>
30 #include "amdgpu.h"
31 #include "amdgpu_vce.h"
32 #include "vid.h"
33 #include "vce/vce_3_0_d.h"
34 #include "vce/vce_3_0_sh_mask.h"
35 #include "oss/oss_3_0_d.h"
36 #include "oss/oss_3_0_sh_mask.h"
37 #include "gca/gfx_8_0_d.h"
38 #include "smu/smu_7_1_2_d.h"
39 #include "smu/smu_7_1_2_sh_mask.h"
40
41 #define GRBM_GFX_INDEX__VCE_INSTANCE__SHIFT     0x04
42 #define GRBM_GFX_INDEX__VCE_INSTANCE_MASK       0x10
43 #define mmVCE_LMI_VCPU_CACHE_40BIT_BAR0         0x8616
44 #define mmVCE_LMI_VCPU_CACHE_40BIT_BAR1         0x8617
45 #define mmVCE_LMI_VCPU_CACHE_40BIT_BAR2         0x8618
46
47 #define VCE_V3_0_FW_SIZE        (384 * 1024)
48 #define VCE_V3_0_STACK_SIZE     (64 * 1024)
49 #define VCE_V3_0_DATA_SIZE      ((16 * 1024 * AMDGPU_MAX_VCE_HANDLES) + (52 * 1024))
50
51 static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx);
52 static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev);
53 static void vce_v3_0_set_irq_funcs(struct amdgpu_device *adev);
54
55 /**
56  * vce_v3_0_ring_get_rptr - get read pointer
57  *
58  * @ring: amdgpu_ring pointer
59  *
60  * Returns the current hardware read pointer
61  */
62 static uint32_t vce_v3_0_ring_get_rptr(struct amdgpu_ring *ring)
63 {
64         struct amdgpu_device *adev = ring->adev;
65
66         if (ring == &adev->vce.ring[0])
67                 return RREG32(mmVCE_RB_RPTR);
68         else
69                 return RREG32(mmVCE_RB_RPTR2);
70 }
71
72 /**
73  * vce_v3_0_ring_get_wptr - get write pointer
74  *
75  * @ring: amdgpu_ring pointer
76  *
77  * Returns the current hardware write pointer
78  */
79 static uint32_t vce_v3_0_ring_get_wptr(struct amdgpu_ring *ring)
80 {
81         struct amdgpu_device *adev = ring->adev;
82
83         if (ring == &adev->vce.ring[0])
84                 return RREG32(mmVCE_RB_WPTR);
85         else
86                 return RREG32(mmVCE_RB_WPTR2);
87 }
88
89 /**
90  * vce_v3_0_ring_set_wptr - set write pointer
91  *
92  * @ring: amdgpu_ring pointer
93  *
94  * Commits the write pointer to the hardware
95  */
96 static void vce_v3_0_ring_set_wptr(struct amdgpu_ring *ring)
97 {
98         struct amdgpu_device *adev = ring->adev;
99
100         if (ring == &adev->vce.ring[0])
101                 WREG32(mmVCE_RB_WPTR, ring->wptr);
102         else
103                 WREG32(mmVCE_RB_WPTR2, ring->wptr);
104 }
105
106 /**
107  * vce_v3_0_start - start VCE block
108  *
109  * @adev: amdgpu_device pointer
110  *
111  * Setup and start the VCE block
112  */
113 static int vce_v3_0_start(struct amdgpu_device *adev)
114 {
115         struct amdgpu_ring *ring;
116         int idx, i, j, r;
117
118         mutex_lock(&adev->grbm_idx_mutex);
119         for (idx = 0; idx < 2; ++idx) {
120
121                 if (adev->vce.harvest_config & (1 << idx))
122                         continue;
123
124                 if(idx == 0)
125                         WREG32_P(mmGRBM_GFX_INDEX, 0,
126                                 ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
127                 else
128                         WREG32_P(mmGRBM_GFX_INDEX,
129                                 GRBM_GFX_INDEX__VCE_INSTANCE_MASK,
130                                 ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
131
132                 vce_v3_0_mc_resume(adev, idx);
133
134                 /* set BUSY flag */
135                 WREG32_P(mmVCE_STATUS, 1, ~1);
136                 if (adev->asic_type >= CHIP_STONEY)
137                         WREG32_P(mmVCE_VCPU_CNTL, 1, ~0x200001);
138                 else
139                         WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK,
140                                 ~VCE_VCPU_CNTL__CLK_EN_MASK);
141
142                 WREG32_P(mmVCE_SOFT_RESET,
143                          VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK,
144                          ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
145
146                 mdelay(100);
147
148                 WREG32_P(mmVCE_SOFT_RESET, 0,
149                         ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
150
151                 for (i = 0; i < 10; ++i) {
152                         uint32_t status;
153                         for (j = 0; j < 100; ++j) {
154                                 status = RREG32(mmVCE_STATUS);
155                                 if (status & 2)
156                                         break;
157                                 mdelay(10);
158                         }
159                         r = 0;
160                         if (status & 2)
161                                 break;
162
163                         DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n");
164                         WREG32_P(mmVCE_SOFT_RESET,
165                                 VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK,
166                                 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
167                         mdelay(10);
168                         WREG32_P(mmVCE_SOFT_RESET, 0,
169                                 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
170                         mdelay(10);
171                         r = -1;
172                 }
173
174                 /* clear BUSY flag */
175                 WREG32_P(mmVCE_STATUS, 0, ~1);
176
177                 if (r) {
178                         DRM_ERROR("VCE not responding, giving up!!!\n");
179                         mutex_unlock(&adev->grbm_idx_mutex);
180                         return r;
181                 }
182         }
183
184         WREG32_P(mmGRBM_GFX_INDEX, 0, ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
185         mutex_unlock(&adev->grbm_idx_mutex);
186
187         ring = &adev->vce.ring[0];
188         WREG32(mmVCE_RB_RPTR, ring->wptr);
189         WREG32(mmVCE_RB_WPTR, ring->wptr);
190         WREG32(mmVCE_RB_BASE_LO, ring->gpu_addr);
191         WREG32(mmVCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
192         WREG32(mmVCE_RB_SIZE, ring->ring_size / 4);
193
194         ring = &adev->vce.ring[1];
195         WREG32(mmVCE_RB_RPTR2, ring->wptr);
196         WREG32(mmVCE_RB_WPTR2, ring->wptr);
197         WREG32(mmVCE_RB_BASE_LO2, ring->gpu_addr);
198         WREG32(mmVCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
199         WREG32(mmVCE_RB_SIZE2, ring->ring_size / 4);
200
201         return 0;
202 }
203
204 #define ixVCE_HARVEST_FUSE_MACRO__ADDRESS     0xC0014074
205 #define VCE_HARVEST_FUSE_MACRO__SHIFT       27
206 #define VCE_HARVEST_FUSE_MACRO__MASK        0x18000000
207
208 static unsigned vce_v3_0_get_harvest_config(struct amdgpu_device *adev)
209 {
210         u32 tmp;
211         unsigned ret;
212
213         /* Fiji, Stoney are single pipe */
214         if ((adev->asic_type == CHIP_FIJI) ||
215             (adev->asic_type == CHIP_STONEY)){
216                 ret = AMDGPU_VCE_HARVEST_VCE1;
217                 return ret;
218         }
219
220         /* Tonga and CZ are dual or single pipe */
221         if (adev->flags & AMD_IS_APU)
222                 tmp = (RREG32_SMC(ixVCE_HARVEST_FUSE_MACRO__ADDRESS) &
223                        VCE_HARVEST_FUSE_MACRO__MASK) >>
224                         VCE_HARVEST_FUSE_MACRO__SHIFT;
225         else
226                 tmp = (RREG32_SMC(ixCC_HARVEST_FUSES) &
227                        CC_HARVEST_FUSES__VCE_DISABLE_MASK) >>
228                         CC_HARVEST_FUSES__VCE_DISABLE__SHIFT;
229
230         switch (tmp) {
231         case 1:
232                 ret = AMDGPU_VCE_HARVEST_VCE0;
233                 break;
234         case 2:
235                 ret = AMDGPU_VCE_HARVEST_VCE1;
236                 break;
237         case 3:
238                 ret = AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1;
239                 break;
240         default:
241                 ret = 0;
242         }
243
244         return ret;
245 }
246
247 static int vce_v3_0_early_init(void *handle)
248 {
249         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
250
251         adev->vce.harvest_config = vce_v3_0_get_harvest_config(adev);
252
253         if ((adev->vce.harvest_config &
254              (AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1)) ==
255             (AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1))
256                 return -ENOENT;
257
258         vce_v3_0_set_ring_funcs(adev);
259         vce_v3_0_set_irq_funcs(adev);
260
261         return 0;
262 }
263
264 static int vce_v3_0_sw_init(void *handle)
265 {
266         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
267         struct amdgpu_ring *ring;
268         int r;
269
270         /* VCE */
271         r = amdgpu_irq_add_id(adev, 167, &adev->vce.irq);
272         if (r)
273                 return r;
274
275         r = amdgpu_vce_sw_init(adev, VCE_V3_0_FW_SIZE +
276                 (VCE_V3_0_STACK_SIZE + VCE_V3_0_DATA_SIZE) * 2);
277         if (r)
278                 return r;
279
280         r = amdgpu_vce_resume(adev);
281         if (r)
282                 return r;
283
284         ring = &adev->vce.ring[0];
285         sprintf(ring->name, "vce0");
286         r = amdgpu_ring_init(adev, ring, 4096, VCE_CMD_NO_OP, 0xf,
287                              &adev->vce.irq, 0, AMDGPU_RING_TYPE_VCE);
288         if (r)
289                 return r;
290
291         ring = &adev->vce.ring[1];
292         sprintf(ring->name, "vce1");
293         r = amdgpu_ring_init(adev, ring, 4096, VCE_CMD_NO_OP, 0xf,
294                              &adev->vce.irq, 0, AMDGPU_RING_TYPE_VCE);
295         if (r)
296                 return r;
297
298         return r;
299 }
300
301 static int vce_v3_0_sw_fini(void *handle)
302 {
303         int r;
304         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
305
306         r = amdgpu_vce_suspend(adev);
307         if (r)
308                 return r;
309
310         r = amdgpu_vce_sw_fini(adev);
311         if (r)
312                 return r;
313
314         return r;
315 }
316
317 static int vce_v3_0_hw_init(void *handle)
318 {
319         struct amdgpu_ring *ring;
320         int r;
321         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
322
323         r = vce_v3_0_start(adev);
324         if (r)
325                 return r;
326
327         ring = &adev->vce.ring[0];
328         ring->ready = true;
329         r = amdgpu_ring_test_ring(ring);
330         if (r) {
331                 ring->ready = false;
332                 return r;
333         }
334
335         ring = &adev->vce.ring[1];
336         ring->ready = true;
337         r = amdgpu_ring_test_ring(ring);
338         if (r) {
339                 ring->ready = false;
340                 return r;
341         }
342
343         DRM_INFO("VCE initialized successfully.\n");
344
345         return 0;
346 }
347
348 static int vce_v3_0_hw_fini(void *handle)
349 {
350         return 0;
351 }
352
353 static int vce_v3_0_suspend(void *handle)
354 {
355         int r;
356         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
357
358         r = vce_v3_0_hw_fini(adev);
359         if (r)
360                 return r;
361
362         r = amdgpu_vce_suspend(adev);
363         if (r)
364                 return r;
365
366         return r;
367 }
368
369 static int vce_v3_0_resume(void *handle)
370 {
371         int r;
372         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
373
374         r = amdgpu_vce_resume(adev);
375         if (r)
376                 return r;
377
378         r = vce_v3_0_hw_init(adev);
379         if (r)
380                 return r;
381
382         return r;
383 }
384
385 static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx)
386 {
387         uint32_t offset, size;
388
389         WREG32_P(mmVCE_CLOCK_GATING_A, 0, ~(1 << 16));
390         WREG32_P(mmVCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000);
391         WREG32_P(mmVCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F);
392         WREG32(mmVCE_CLOCK_GATING_B, 0xf7);
393
394         WREG32(mmVCE_LMI_CTRL, 0x00398000);
395         WREG32_P(mmVCE_LMI_CACHE_CTRL, 0x0, ~0x1);
396         WREG32(mmVCE_LMI_SWAP_CNTL, 0);
397         WREG32(mmVCE_LMI_SWAP_CNTL1, 0);
398         WREG32(mmVCE_LMI_VM_CTRL, 0);
399         if (adev->asic_type >= CHIP_STONEY) {
400                 WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR0, (adev->vce.gpu_addr >> 8));
401                 WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR1, (adev->vce.gpu_addr >> 8));
402                 WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR2, (adev->vce.gpu_addr >> 8));
403         } else
404                 WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR, (adev->vce.gpu_addr >> 8));
405         offset = AMDGPU_VCE_FIRMWARE_OFFSET;
406         size = VCE_V3_0_FW_SIZE;
407         WREG32(mmVCE_VCPU_CACHE_OFFSET0, offset & 0x7fffffff);
408         WREG32(mmVCE_VCPU_CACHE_SIZE0, size);
409
410         if (idx == 0) {
411                 offset += size;
412                 size = VCE_V3_0_STACK_SIZE;
413                 WREG32(mmVCE_VCPU_CACHE_OFFSET1, offset & 0x7fffffff);
414                 WREG32(mmVCE_VCPU_CACHE_SIZE1, size);
415                 offset += size;
416                 size = VCE_V3_0_DATA_SIZE;
417                 WREG32(mmVCE_VCPU_CACHE_OFFSET2, offset & 0x7fffffff);
418                 WREG32(mmVCE_VCPU_CACHE_SIZE2, size);
419         } else {
420                 offset += size + VCE_V3_0_STACK_SIZE + VCE_V3_0_DATA_SIZE;
421                 size = VCE_V3_0_STACK_SIZE;
422                 WREG32(mmVCE_VCPU_CACHE_OFFSET1, offset & 0xfffffff);
423                 WREG32(mmVCE_VCPU_CACHE_SIZE1, size);
424                 offset += size;
425                 size = VCE_V3_0_DATA_SIZE;
426                 WREG32(mmVCE_VCPU_CACHE_OFFSET2, offset & 0xfffffff);
427                 WREG32(mmVCE_VCPU_CACHE_SIZE2, size);
428         }
429
430         WREG32_P(mmVCE_LMI_CTRL2, 0x0, ~0x100);
431
432         WREG32_P(mmVCE_SYS_INT_EN, VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK,
433                  ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK);
434 }
435
436 static bool vce_v3_0_is_idle(void *handle)
437 {
438         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
439         u32 mask = 0;
440         int idx;
441
442         for (idx = 0; idx < 2; ++idx) {
443                 if (adev->vce.harvest_config & (1 << idx))
444                         continue;
445
446                 if (idx == 0)
447                         mask |= SRBM_STATUS2__VCE0_BUSY_MASK;
448                 else
449                         mask |= SRBM_STATUS2__VCE1_BUSY_MASK;
450         }
451
452         return !(RREG32(mmSRBM_STATUS2) & mask);
453 }
454
455 static int vce_v3_0_wait_for_idle(void *handle)
456 {
457         unsigned i;
458         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
459         u32 mask = 0;
460         int idx;
461
462         for (idx = 0; idx < 2; ++idx) {
463                 if (adev->vce.harvest_config & (1 << idx))
464                         continue;
465
466                 if (idx == 0)
467                         mask |= SRBM_STATUS2__VCE0_BUSY_MASK;
468                 else
469                         mask |= SRBM_STATUS2__VCE1_BUSY_MASK;
470         }
471
472         for (i = 0; i < adev->usec_timeout; i++) {
473                 if (!(RREG32(mmSRBM_STATUS2) & mask))
474                         return 0;
475         }
476         return -ETIMEDOUT;
477 }
478
479 static int vce_v3_0_soft_reset(void *handle)
480 {
481         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
482         u32 mask = 0;
483         int idx;
484
485         for (idx = 0; idx < 2; ++idx) {
486                 if (adev->vce.harvest_config & (1 << idx))
487                         continue;
488
489                 if (idx == 0)
490                         mask |= SRBM_SOFT_RESET__SOFT_RESET_VCE0_MASK;
491                 else
492                         mask |= SRBM_SOFT_RESET__SOFT_RESET_VCE1_MASK;
493         }
494         WREG32_P(mmSRBM_SOFT_RESET, mask,
495                  ~(SRBM_SOFT_RESET__SOFT_RESET_VCE0_MASK |
496                    SRBM_SOFT_RESET__SOFT_RESET_VCE1_MASK));
497         mdelay(5);
498
499         return vce_v3_0_start(adev);
500 }
501
502 static void vce_v3_0_print_status(void *handle)
503 {
504         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
505
506         dev_info(adev->dev, "VCE 3.0 registers\n");
507         dev_info(adev->dev, "  VCE_STATUS=0x%08X\n",
508                  RREG32(mmVCE_STATUS));
509         dev_info(adev->dev, "  VCE_VCPU_CNTL=0x%08X\n",
510                  RREG32(mmVCE_VCPU_CNTL));
511         dev_info(adev->dev, "  VCE_VCPU_CACHE_OFFSET0=0x%08X\n",
512                  RREG32(mmVCE_VCPU_CACHE_OFFSET0));
513         dev_info(adev->dev, "  VCE_VCPU_CACHE_SIZE0=0x%08X\n",
514                  RREG32(mmVCE_VCPU_CACHE_SIZE0));
515         dev_info(adev->dev, "  VCE_VCPU_CACHE_OFFSET1=0x%08X\n",
516                  RREG32(mmVCE_VCPU_CACHE_OFFSET1));
517         dev_info(adev->dev, "  VCE_VCPU_CACHE_SIZE1=0x%08X\n",
518                  RREG32(mmVCE_VCPU_CACHE_SIZE1));
519         dev_info(adev->dev, "  VCE_VCPU_CACHE_OFFSET2=0x%08X\n",
520                  RREG32(mmVCE_VCPU_CACHE_OFFSET2));
521         dev_info(adev->dev, "  VCE_VCPU_CACHE_SIZE2=0x%08X\n",
522                  RREG32(mmVCE_VCPU_CACHE_SIZE2));
523         dev_info(adev->dev, "  VCE_SOFT_RESET=0x%08X\n",
524                  RREG32(mmVCE_SOFT_RESET));
525         dev_info(adev->dev, "  VCE_RB_BASE_LO2=0x%08X\n",
526                  RREG32(mmVCE_RB_BASE_LO2));
527         dev_info(adev->dev, "  VCE_RB_BASE_HI2=0x%08X\n",
528                  RREG32(mmVCE_RB_BASE_HI2));
529         dev_info(adev->dev, "  VCE_RB_SIZE2=0x%08X\n",
530                  RREG32(mmVCE_RB_SIZE2));
531         dev_info(adev->dev, "  VCE_RB_RPTR2=0x%08X\n",
532                  RREG32(mmVCE_RB_RPTR2));
533         dev_info(adev->dev, "  VCE_RB_WPTR2=0x%08X\n",
534                  RREG32(mmVCE_RB_WPTR2));
535         dev_info(adev->dev, "  VCE_RB_BASE_LO=0x%08X\n",
536                  RREG32(mmVCE_RB_BASE_LO));
537         dev_info(adev->dev, "  VCE_RB_BASE_HI=0x%08X\n",
538                  RREG32(mmVCE_RB_BASE_HI));
539         dev_info(adev->dev, "  VCE_RB_SIZE=0x%08X\n",
540                  RREG32(mmVCE_RB_SIZE));
541         dev_info(adev->dev, "  VCE_RB_RPTR=0x%08X\n",
542                  RREG32(mmVCE_RB_RPTR));
543         dev_info(adev->dev, "  VCE_RB_WPTR=0x%08X\n",
544                  RREG32(mmVCE_RB_WPTR));
545         dev_info(adev->dev, "  VCE_CLOCK_GATING_A=0x%08X\n",
546                  RREG32(mmVCE_CLOCK_GATING_A));
547         dev_info(adev->dev, "  VCE_CLOCK_GATING_B=0x%08X\n",
548                  RREG32(mmVCE_CLOCK_GATING_B));
549         dev_info(adev->dev, "  VCE_UENC_CLOCK_GATING=0x%08X\n",
550                  RREG32(mmVCE_UENC_CLOCK_GATING));
551         dev_info(adev->dev, "  VCE_UENC_REG_CLOCK_GATING=0x%08X\n",
552                  RREG32(mmVCE_UENC_REG_CLOCK_GATING));
553         dev_info(adev->dev, "  VCE_SYS_INT_EN=0x%08X\n",
554                  RREG32(mmVCE_SYS_INT_EN));
555         dev_info(adev->dev, "  VCE_LMI_CTRL2=0x%08X\n",
556                  RREG32(mmVCE_LMI_CTRL2));
557         dev_info(adev->dev, "  VCE_LMI_CTRL=0x%08X\n",
558                  RREG32(mmVCE_LMI_CTRL));
559         dev_info(adev->dev, "  VCE_LMI_VM_CTRL=0x%08X\n",
560                  RREG32(mmVCE_LMI_VM_CTRL));
561         dev_info(adev->dev, "  VCE_LMI_SWAP_CNTL=0x%08X\n",
562                  RREG32(mmVCE_LMI_SWAP_CNTL));
563         dev_info(adev->dev, "  VCE_LMI_SWAP_CNTL1=0x%08X\n",
564                  RREG32(mmVCE_LMI_SWAP_CNTL1));
565         dev_info(adev->dev, "  VCE_LMI_CACHE_CTRL=0x%08X\n",
566                  RREG32(mmVCE_LMI_CACHE_CTRL));
567 }
568
569 static int vce_v3_0_set_interrupt_state(struct amdgpu_device *adev,
570                                         struct amdgpu_irq_src *source,
571                                         unsigned type,
572                                         enum amdgpu_interrupt_state state)
573 {
574         uint32_t val = 0;
575
576         if (state == AMDGPU_IRQ_STATE_ENABLE)
577                 val |= VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK;
578
579         WREG32_P(mmVCE_SYS_INT_EN, val, ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK);
580         return 0;
581 }
582
583 static int vce_v3_0_process_interrupt(struct amdgpu_device *adev,
584                                       struct amdgpu_irq_src *source,
585                                       struct amdgpu_iv_entry *entry)
586 {
587         DRM_DEBUG("IH: VCE\n");
588
589         WREG32_P(mmVCE_SYS_INT_STATUS,
590                 VCE_SYS_INT_STATUS__VCE_SYS_INT_TRAP_INTERRUPT_INT_MASK,
591                 ~VCE_SYS_INT_STATUS__VCE_SYS_INT_TRAP_INTERRUPT_INT_MASK);
592
593         switch (entry->src_data) {
594         case 0:
595                 amdgpu_fence_process(&adev->vce.ring[0]);
596                 break;
597         case 1:
598                 amdgpu_fence_process(&adev->vce.ring[1]);
599                 break;
600         default:
601                 DRM_ERROR("Unhandled interrupt: %d %d\n",
602                           entry->src_id, entry->src_data);
603                 break;
604         }
605
606         return 0;
607 }
608
609 static int vce_v3_0_set_clockgating_state(void *handle,
610                                           enum amd_clockgating_state state)
611 {
612         return 0;
613 }
614
615 static int vce_v3_0_set_powergating_state(void *handle,
616                                           enum amd_powergating_state state)
617 {
618         /* This doesn't actually powergate the VCE block.
619          * That's done in the dpm code via the SMC.  This
620          * just re-inits the block as necessary.  The actual
621          * gating still happens in the dpm code.  We should
622          * revisit this when there is a cleaner line between
623          * the smc and the hw blocks
624          */
625         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
626
627         if (state == AMD_PG_STATE_GATE)
628                 /* XXX do we need a vce_v3_0_stop()? */
629                 return 0;
630         else
631                 return vce_v3_0_start(adev);
632 }
633
634 const struct amd_ip_funcs vce_v3_0_ip_funcs = {
635         .early_init = vce_v3_0_early_init,
636         .late_init = NULL,
637         .sw_init = vce_v3_0_sw_init,
638         .sw_fini = vce_v3_0_sw_fini,
639         .hw_init = vce_v3_0_hw_init,
640         .hw_fini = vce_v3_0_hw_fini,
641         .suspend = vce_v3_0_suspend,
642         .resume = vce_v3_0_resume,
643         .is_idle = vce_v3_0_is_idle,
644         .wait_for_idle = vce_v3_0_wait_for_idle,
645         .soft_reset = vce_v3_0_soft_reset,
646         .print_status = vce_v3_0_print_status,
647         .set_clockgating_state = vce_v3_0_set_clockgating_state,
648         .set_powergating_state = vce_v3_0_set_powergating_state,
649 };
650
651 static const struct amdgpu_ring_funcs vce_v3_0_ring_funcs = {
652         .get_rptr = vce_v3_0_ring_get_rptr,
653         .get_wptr = vce_v3_0_ring_get_wptr,
654         .set_wptr = vce_v3_0_ring_set_wptr,
655         .parse_cs = amdgpu_vce_ring_parse_cs,
656         .emit_ib = amdgpu_vce_ring_emit_ib,
657         .emit_fence = amdgpu_vce_ring_emit_fence,
658         .emit_semaphore = amdgpu_vce_ring_emit_semaphore,
659         .test_ring = amdgpu_vce_ring_test_ring,
660         .test_ib = amdgpu_vce_ring_test_ib,
661         .insert_nop = amdgpu_ring_insert_nop,
662 };
663
664 static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev)
665 {
666         adev->vce.ring[0].funcs = &vce_v3_0_ring_funcs;
667         adev->vce.ring[1].funcs = &vce_v3_0_ring_funcs;
668 }
669
670 static const struct amdgpu_irq_src_funcs vce_v3_0_irq_funcs = {
671         .set = vce_v3_0_set_interrupt_state,
672         .process = vce_v3_0_process_interrupt,
673 };
674
675 static void vce_v3_0_set_irq_funcs(struct amdgpu_device *adev)
676 {
677         adev->vce.irq.num_types = 1;
678         adev->vce.irq.funcs = &vce_v3_0_irq_funcs;
679 };