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_2_0_d.h" 36 #include "oss/oss_2_0_sh_mask.h" 37 #include "gca/gfx_8_0_d.h" 38 39 #define GRBM_GFX_INDEX__VCE_INSTANCE__SHIFT 0x04 40 #define GRBM_GFX_INDEX__VCE_INSTANCE_MASK 0x10 41 42 #define VCE_V3_0_FW_SIZE (384 * 1024) 43 #define VCE_V3_0_STACK_SIZE (64 * 1024) 44 #define VCE_V3_0_DATA_SIZE ((16 * 1024 * AMDGPU_MAX_VCE_HANDLES) + (52 * 1024)) 45 46 static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx); 47 static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev); 48 static void vce_v3_0_set_irq_funcs(struct amdgpu_device *adev); 49 50 /** 51 * vce_v3_0_ring_get_rptr - get read pointer 52 * 53 * @ring: amdgpu_ring pointer 54 * 55 * Returns the current hardware read pointer 56 */ 57 static uint32_t vce_v3_0_ring_get_rptr(struct amdgpu_ring *ring) 58 { 59 struct amdgpu_device *adev = ring->adev; 60 61 if (ring == &adev->vce.ring[0]) 62 return RREG32(mmVCE_RB_RPTR); 63 else 64 return RREG32(mmVCE_RB_RPTR2); 65 } 66 67 /** 68 * vce_v3_0_ring_get_wptr - get write pointer 69 * 70 * @ring: amdgpu_ring pointer 71 * 72 * Returns the current hardware write pointer 73 */ 74 static uint32_t vce_v3_0_ring_get_wptr(struct amdgpu_ring *ring) 75 { 76 struct amdgpu_device *adev = ring->adev; 77 78 if (ring == &adev->vce.ring[0]) 79 return RREG32(mmVCE_RB_WPTR); 80 else 81 return RREG32(mmVCE_RB_WPTR2); 82 } 83 84 /** 85 * vce_v3_0_ring_set_wptr - set write pointer 86 * 87 * @ring: amdgpu_ring pointer 88 * 89 * Commits the write pointer to the hardware 90 */ 91 static void vce_v3_0_ring_set_wptr(struct amdgpu_ring *ring) 92 { 93 struct amdgpu_device *adev = ring->adev; 94 95 if (ring == &adev->vce.ring[0]) 96 WREG32(mmVCE_RB_WPTR, ring->wptr); 97 else 98 WREG32(mmVCE_RB_WPTR2, ring->wptr); 99 } 100 101 /** 102 * vce_v3_0_start - start VCE block 103 * 104 * @adev: amdgpu_device pointer 105 * 106 * Setup and start the VCE block 107 */ 108 static int vce_v3_0_start(struct amdgpu_device *adev) 109 { 110 struct amdgpu_ring *ring; 111 int idx, i, j, r; 112 113 mutex_lock(&adev->grbm_idx_mutex); 114 for (idx = 0; idx < 2; ++idx) { 115 if(idx == 0) 116 WREG32_P(mmGRBM_GFX_INDEX, 0, 117 ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); 118 else 119 WREG32_P(mmGRBM_GFX_INDEX, 120 GRBM_GFX_INDEX__VCE_INSTANCE_MASK, 121 ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); 122 123 vce_v3_0_mc_resume(adev, idx); 124 125 /* set BUSY flag */ 126 WREG32_P(mmVCE_STATUS, 1, ~1); 127 128 WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK, 129 ~VCE_VCPU_CNTL__CLK_EN_MASK); 130 131 WREG32_P(mmVCE_SOFT_RESET, 132 VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK, 133 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); 134 135 mdelay(100); 136 137 WREG32_P(mmVCE_SOFT_RESET, 0, 138 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); 139 140 for (i = 0; i < 10; ++i) { 141 uint32_t status; 142 for (j = 0; j < 100; ++j) { 143 status = RREG32(mmVCE_STATUS); 144 if (status & 2) 145 break; 146 mdelay(10); 147 } 148 r = 0; 149 if (status & 2) 150 break; 151 152 DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n"); 153 WREG32_P(mmVCE_SOFT_RESET, 154 VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK, 155 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); 156 mdelay(10); 157 WREG32_P(mmVCE_SOFT_RESET, 0, 158 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); 159 mdelay(10); 160 r = -1; 161 } 162 163 /* clear BUSY flag */ 164 WREG32_P(mmVCE_STATUS, 0, ~1); 165 166 if (r) { 167 DRM_ERROR("VCE not responding, giving up!!!\n"); 168 mutex_unlock(&adev->grbm_idx_mutex); 169 return r; 170 } 171 } 172 173 WREG32_P(mmGRBM_GFX_INDEX, 0, ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK); 174 mutex_unlock(&adev->grbm_idx_mutex); 175 176 ring = &adev->vce.ring[0]; 177 WREG32(mmVCE_RB_RPTR, ring->wptr); 178 WREG32(mmVCE_RB_WPTR, ring->wptr); 179 WREG32(mmVCE_RB_BASE_LO, ring->gpu_addr); 180 WREG32(mmVCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); 181 WREG32(mmVCE_RB_SIZE, ring->ring_size / 4); 182 183 ring = &adev->vce.ring[1]; 184 WREG32(mmVCE_RB_RPTR2, ring->wptr); 185 WREG32(mmVCE_RB_WPTR2, ring->wptr); 186 WREG32(mmVCE_RB_BASE_LO2, ring->gpu_addr); 187 WREG32(mmVCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); 188 WREG32(mmVCE_RB_SIZE2, ring->ring_size / 4); 189 190 return 0; 191 } 192 193 static int vce_v3_0_early_init(struct amdgpu_device *adev) 194 { 195 vce_v3_0_set_ring_funcs(adev); 196 vce_v3_0_set_irq_funcs(adev); 197 198 return 0; 199 } 200 201 static int vce_v3_0_sw_init(struct amdgpu_device *adev) 202 { 203 struct amdgpu_ring *ring; 204 int r; 205 206 /* VCE */ 207 r = amdgpu_irq_add_id(adev, 167, &adev->vce.irq); 208 if (r) 209 return r; 210 211 r = amdgpu_vce_sw_init(adev, VCE_V3_0_FW_SIZE + 212 (VCE_V3_0_STACK_SIZE + VCE_V3_0_DATA_SIZE) * 2); 213 if (r) 214 return r; 215 216 r = amdgpu_vce_resume(adev); 217 if (r) 218 return r; 219 220 ring = &adev->vce.ring[0]; 221 sprintf(ring->name, "vce0"); 222 r = amdgpu_ring_init(adev, ring, 4096, VCE_CMD_NO_OP, 0xf, 223 &adev->vce.irq, 0, AMDGPU_RING_TYPE_VCE); 224 if (r) 225 return r; 226 227 ring = &adev->vce.ring[1]; 228 sprintf(ring->name, "vce1"); 229 r = amdgpu_ring_init(adev, ring, 4096, VCE_CMD_NO_OP, 0xf, 230 &adev->vce.irq, 0, AMDGPU_RING_TYPE_VCE); 231 if (r) 232 return r; 233 234 return r; 235 } 236 237 static int vce_v3_0_sw_fini(struct amdgpu_device *adev) 238 { 239 int r; 240 241 r = amdgpu_vce_suspend(adev); 242 if (r) 243 return r; 244 245 r = amdgpu_vce_sw_fini(adev); 246 if (r) 247 return r; 248 249 return r; 250 } 251 252 static int vce_v3_0_hw_init(struct amdgpu_device *adev) 253 { 254 struct amdgpu_ring *ring; 255 int r; 256 257 r = vce_v3_0_start(adev); 258 if (r) 259 return r; 260 261 ring = &adev->vce.ring[0]; 262 ring->ready = true; 263 r = amdgpu_ring_test_ring(ring); 264 if (r) { 265 ring->ready = false; 266 return r; 267 } 268 269 ring = &adev->vce.ring[1]; 270 ring->ready = true; 271 r = amdgpu_ring_test_ring(ring); 272 if (r) { 273 ring->ready = false; 274 return r; 275 } 276 277 DRM_INFO("VCE initialized successfully.\n"); 278 279 return 0; 280 } 281 282 static int vce_v3_0_hw_fini(struct amdgpu_device *adev) 283 { 284 // TODO 285 return 0; 286 } 287 288 static int vce_v3_0_suspend(struct amdgpu_device *adev) 289 { 290 int r; 291 292 r = vce_v3_0_hw_fini(adev); 293 if (r) 294 return r; 295 296 r = amdgpu_vce_suspend(adev); 297 if (r) 298 return r; 299 300 return r; 301 } 302 303 static int vce_v3_0_resume(struct amdgpu_device *adev) 304 { 305 int r; 306 307 r = amdgpu_vce_resume(adev); 308 if (r) 309 return r; 310 311 r = vce_v3_0_hw_init(adev); 312 if (r) 313 return r; 314 315 return r; 316 } 317 318 static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx) 319 { 320 uint32_t offset, size; 321 322 WREG32_P(mmVCE_CLOCK_GATING_A, 0, ~(1 << 16)); 323 WREG32_P(mmVCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000); 324 WREG32_P(mmVCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F); 325 WREG32(mmVCE_CLOCK_GATING_B, 0xf7); 326 327 WREG32(mmVCE_LMI_CTRL, 0x00398000); 328 WREG32_P(mmVCE_LMI_CACHE_CTRL, 0x0, ~0x1); 329 WREG32(mmVCE_LMI_SWAP_CNTL, 0); 330 WREG32(mmVCE_LMI_SWAP_CNTL1, 0); 331 WREG32(mmVCE_LMI_VM_CTRL, 0); 332 333 WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR, (adev->vce.gpu_addr >> 8)); 334 offset = AMDGPU_VCE_FIRMWARE_OFFSET; 335 size = VCE_V3_0_FW_SIZE; 336 WREG32(mmVCE_VCPU_CACHE_OFFSET0, offset & 0x7fffffff); 337 WREG32(mmVCE_VCPU_CACHE_SIZE0, size); 338 339 if (idx == 0) { 340 offset += size; 341 size = VCE_V3_0_STACK_SIZE; 342 WREG32(mmVCE_VCPU_CACHE_OFFSET1, offset & 0x7fffffff); 343 WREG32(mmVCE_VCPU_CACHE_SIZE1, size); 344 offset += size; 345 size = VCE_V3_0_DATA_SIZE; 346 WREG32(mmVCE_VCPU_CACHE_OFFSET2, offset & 0x7fffffff); 347 WREG32(mmVCE_VCPU_CACHE_SIZE2, size); 348 } else { 349 offset += size + VCE_V3_0_STACK_SIZE + VCE_V3_0_DATA_SIZE; 350 size = VCE_V3_0_STACK_SIZE; 351 WREG32(mmVCE_VCPU_CACHE_OFFSET1, offset & 0xfffffff); 352 WREG32(mmVCE_VCPU_CACHE_SIZE1, size); 353 offset += size; 354 size = VCE_V3_0_DATA_SIZE; 355 WREG32(mmVCE_VCPU_CACHE_OFFSET2, offset & 0xfffffff); 356 WREG32(mmVCE_VCPU_CACHE_SIZE2, size); 357 } 358 359 WREG32_P(mmVCE_LMI_CTRL2, 0x0, ~0x100); 360 361 WREG32_P(mmVCE_SYS_INT_EN, VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK, 362 ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK); 363 } 364 365 static bool vce_v3_0_is_idle(struct amdgpu_device *adev) 366 { 367 return !(RREG32(mmSRBM_STATUS2) & SRBM_STATUS2__VCE_BUSY_MASK); 368 } 369 370 static int vce_v3_0_wait_for_idle(struct amdgpu_device *adev) 371 { 372 unsigned i; 373 374 for (i = 0; i < adev->usec_timeout; i++) { 375 if (!(RREG32(mmSRBM_STATUS2) & SRBM_STATUS2__VCE_BUSY_MASK)) 376 return 0; 377 } 378 return -ETIMEDOUT; 379 } 380 381 static int vce_v3_0_soft_reset(struct amdgpu_device *adev) 382 { 383 WREG32_P(mmSRBM_SOFT_RESET, SRBM_SOFT_RESET__SOFT_RESET_VCE_MASK, 384 ~SRBM_SOFT_RESET__SOFT_RESET_VCE_MASK); 385 mdelay(5); 386 387 return vce_v3_0_start(adev); 388 } 389 390 static void vce_v3_0_print_status(struct amdgpu_device *adev) 391 { 392 dev_info(adev->dev, "VCE 3.0 registers\n"); 393 dev_info(adev->dev, " VCE_STATUS=0x%08X\n", 394 RREG32(mmVCE_STATUS)); 395 dev_info(adev->dev, " VCE_VCPU_CNTL=0x%08X\n", 396 RREG32(mmVCE_VCPU_CNTL)); 397 dev_info(adev->dev, " VCE_VCPU_CACHE_OFFSET0=0x%08X\n", 398 RREG32(mmVCE_VCPU_CACHE_OFFSET0)); 399 dev_info(adev->dev, " VCE_VCPU_CACHE_SIZE0=0x%08X\n", 400 RREG32(mmVCE_VCPU_CACHE_SIZE0)); 401 dev_info(adev->dev, " VCE_VCPU_CACHE_OFFSET1=0x%08X\n", 402 RREG32(mmVCE_VCPU_CACHE_OFFSET1)); 403 dev_info(adev->dev, " VCE_VCPU_CACHE_SIZE1=0x%08X\n", 404 RREG32(mmVCE_VCPU_CACHE_SIZE1)); 405 dev_info(adev->dev, " VCE_VCPU_CACHE_OFFSET2=0x%08X\n", 406 RREG32(mmVCE_VCPU_CACHE_OFFSET2)); 407 dev_info(adev->dev, " VCE_VCPU_CACHE_SIZE2=0x%08X\n", 408 RREG32(mmVCE_VCPU_CACHE_SIZE2)); 409 dev_info(adev->dev, " VCE_SOFT_RESET=0x%08X\n", 410 RREG32(mmVCE_SOFT_RESET)); 411 dev_info(adev->dev, " VCE_RB_BASE_LO2=0x%08X\n", 412 RREG32(mmVCE_RB_BASE_LO2)); 413 dev_info(adev->dev, " VCE_RB_BASE_HI2=0x%08X\n", 414 RREG32(mmVCE_RB_BASE_HI2)); 415 dev_info(adev->dev, " VCE_RB_SIZE2=0x%08X\n", 416 RREG32(mmVCE_RB_SIZE2)); 417 dev_info(adev->dev, " VCE_RB_RPTR2=0x%08X\n", 418 RREG32(mmVCE_RB_RPTR2)); 419 dev_info(adev->dev, " VCE_RB_WPTR2=0x%08X\n", 420 RREG32(mmVCE_RB_WPTR2)); 421 dev_info(adev->dev, " VCE_RB_BASE_LO=0x%08X\n", 422 RREG32(mmVCE_RB_BASE_LO)); 423 dev_info(adev->dev, " VCE_RB_BASE_HI=0x%08X\n", 424 RREG32(mmVCE_RB_BASE_HI)); 425 dev_info(adev->dev, " VCE_RB_SIZE=0x%08X\n", 426 RREG32(mmVCE_RB_SIZE)); 427 dev_info(adev->dev, " VCE_RB_RPTR=0x%08X\n", 428 RREG32(mmVCE_RB_RPTR)); 429 dev_info(adev->dev, " VCE_RB_WPTR=0x%08X\n", 430 RREG32(mmVCE_RB_WPTR)); 431 dev_info(adev->dev, " VCE_CLOCK_GATING_A=0x%08X\n", 432 RREG32(mmVCE_CLOCK_GATING_A)); 433 dev_info(adev->dev, " VCE_CLOCK_GATING_B=0x%08X\n", 434 RREG32(mmVCE_CLOCK_GATING_B)); 435 dev_info(adev->dev, " VCE_UENC_CLOCK_GATING=0x%08X\n", 436 RREG32(mmVCE_UENC_CLOCK_GATING)); 437 dev_info(adev->dev, " VCE_UENC_REG_CLOCK_GATING=0x%08X\n", 438 RREG32(mmVCE_UENC_REG_CLOCK_GATING)); 439 dev_info(adev->dev, " VCE_SYS_INT_EN=0x%08X\n", 440 RREG32(mmVCE_SYS_INT_EN)); 441 dev_info(adev->dev, " VCE_LMI_CTRL2=0x%08X\n", 442 RREG32(mmVCE_LMI_CTRL2)); 443 dev_info(adev->dev, " VCE_LMI_CTRL=0x%08X\n", 444 RREG32(mmVCE_LMI_CTRL)); 445 dev_info(adev->dev, " VCE_LMI_VM_CTRL=0x%08X\n", 446 RREG32(mmVCE_LMI_VM_CTRL)); 447 dev_info(adev->dev, " VCE_LMI_SWAP_CNTL=0x%08X\n", 448 RREG32(mmVCE_LMI_SWAP_CNTL)); 449 dev_info(adev->dev, " VCE_LMI_SWAP_CNTL1=0x%08X\n", 450 RREG32(mmVCE_LMI_SWAP_CNTL1)); 451 dev_info(adev->dev, " VCE_LMI_CACHE_CTRL=0x%08X\n", 452 RREG32(mmVCE_LMI_CACHE_CTRL)); 453 } 454 455 static int vce_v3_0_set_interrupt_state(struct amdgpu_device *adev, 456 struct amdgpu_irq_src *source, 457 unsigned type, 458 enum amdgpu_interrupt_state state) 459 { 460 uint32_t val = 0; 461 462 if (state == AMDGPU_IRQ_STATE_ENABLE) 463 val |= VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK; 464 465 WREG32_P(mmVCE_SYS_INT_EN, val, ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK); 466 return 0; 467 } 468 469 static int vce_v3_0_process_interrupt(struct amdgpu_device *adev, 470 struct amdgpu_irq_src *source, 471 struct amdgpu_iv_entry *entry) 472 { 473 DRM_DEBUG("IH: VCE\n"); 474 switch (entry->src_data) { 475 case 0: 476 amdgpu_fence_process(&adev->vce.ring[0]); 477 break; 478 case 1: 479 amdgpu_fence_process(&adev->vce.ring[1]); 480 break; 481 default: 482 DRM_ERROR("Unhandled interrupt: %d %d\n", 483 entry->src_id, entry->src_data); 484 break; 485 } 486 487 return 0; 488 } 489 490 static int vce_v3_0_set_clockgating_state(struct amdgpu_device *adev, 491 enum amdgpu_clockgating_state state) 492 { 493 //TODO 494 return 0; 495 } 496 497 static int vce_v3_0_set_powergating_state(struct amdgpu_device *adev, 498 enum amdgpu_powergating_state state) 499 { 500 /* This doesn't actually powergate the VCE block. 501 * That's done in the dpm code via the SMC. This 502 * just re-inits the block as necessary. The actual 503 * gating still happens in the dpm code. We should 504 * revisit this when there is a cleaner line between 505 * the smc and the hw blocks 506 */ 507 if (state == AMDGPU_PG_STATE_GATE) 508 /* XXX do we need a vce_v3_0_stop()? */ 509 return 0; 510 else 511 return vce_v3_0_start(adev); 512 } 513 514 const struct amdgpu_ip_funcs vce_v3_0_ip_funcs = { 515 .early_init = vce_v3_0_early_init, 516 .late_init = NULL, 517 .sw_init = vce_v3_0_sw_init, 518 .sw_fini = vce_v3_0_sw_fini, 519 .hw_init = vce_v3_0_hw_init, 520 .hw_fini = vce_v3_0_hw_fini, 521 .suspend = vce_v3_0_suspend, 522 .resume = vce_v3_0_resume, 523 .is_idle = vce_v3_0_is_idle, 524 .wait_for_idle = vce_v3_0_wait_for_idle, 525 .soft_reset = vce_v3_0_soft_reset, 526 .print_status = vce_v3_0_print_status, 527 .set_clockgating_state = vce_v3_0_set_clockgating_state, 528 .set_powergating_state = vce_v3_0_set_powergating_state, 529 }; 530 531 static const struct amdgpu_ring_funcs vce_v3_0_ring_funcs = { 532 .get_rptr = vce_v3_0_ring_get_rptr, 533 .get_wptr = vce_v3_0_ring_get_wptr, 534 .set_wptr = vce_v3_0_ring_set_wptr, 535 .parse_cs = amdgpu_vce_ring_parse_cs, 536 .emit_ib = amdgpu_vce_ring_emit_ib, 537 .emit_fence = amdgpu_vce_ring_emit_fence, 538 .emit_semaphore = amdgpu_vce_ring_emit_semaphore, 539 .test_ring = amdgpu_vce_ring_test_ring, 540 .test_ib = amdgpu_vce_ring_test_ib, 541 .is_lockup = amdgpu_ring_test_lockup, 542 }; 543 544 static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev) 545 { 546 adev->vce.ring[0].funcs = &vce_v3_0_ring_funcs; 547 adev->vce.ring[1].funcs = &vce_v3_0_ring_funcs; 548 } 549 550 static const struct amdgpu_irq_src_funcs vce_v3_0_irq_funcs = { 551 .set = vce_v3_0_set_interrupt_state, 552 .process = vce_v3_0_process_interrupt, 553 }; 554 555 static void vce_v3_0_set_irq_funcs(struct amdgpu_device *adev) 556 { 557 adev->vce.irq.num_types = 1; 558 adev->vce.irq.funcs = &vce_v3_0_irq_funcs; 559 }; 560