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 */
vce_v3_0_ring_get_rptr(struct amdgpu_ring * ring)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 */
vce_v3_0_ring_get_wptr(struct amdgpu_ring * ring)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 */
vce_v3_0_ring_set_wptr(struct amdgpu_ring * ring)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 */
vce_v3_0_start(struct amdgpu_device * adev)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
vce_v3_0_get_harvest_config(struct amdgpu_device * adev)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
vce_v3_0_early_init(void * handle)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
vce_v3_0_sw_init(void * handle)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
vce_v3_0_sw_fini(void * handle)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
vce_v3_0_hw_init(void * handle)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
vce_v3_0_hw_fini(void * handle)348 static int vce_v3_0_hw_fini(void *handle)
349 {
350 return 0;
351 }
352
vce_v3_0_suspend(void * handle)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
vce_v3_0_resume(void * handle)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
vce_v3_0_mc_resume(struct amdgpu_device * adev,int idx)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
vce_v3_0_is_idle(void * handle)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
vce_v3_0_wait_for_idle(void * handle)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
vce_v3_0_soft_reset(void * handle)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
vce_v3_0_print_status(void * handle)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
vce_v3_0_set_interrupt_state(struct amdgpu_device * adev,struct amdgpu_irq_src * source,unsigned type,enum amdgpu_interrupt_state state)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
vce_v3_0_process_interrupt(struct amdgpu_device * adev,struct amdgpu_irq_src * source,struct amdgpu_iv_entry * entry)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
vce_v3_0_set_clockgating_state(void * handle,enum amd_clockgating_state state)609 static int vce_v3_0_set_clockgating_state(void *handle,
610 enum amd_clockgating_state state)
611 {
612 return 0;
613 }
614
vce_v3_0_set_powergating_state(void * handle,enum amd_powergating_state state)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
vce_v3_0_set_ring_funcs(struct amdgpu_device * adev)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
vce_v3_0_set_irq_funcs(struct amdgpu_device * adev)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 };
680