1 /* $NetBSD: amdgpu_vcn.c,v 1.2 2021/12/18 23:44:58 riastradh Exp $ */ 2 3 /* 4 * Copyright 2016 Advanced Micro Devices, Inc. 5 * All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the 9 * "Software"), to deal in the Software without restriction, including 10 * without limitation the rights to use, copy, modify, merge, publish, 11 * distribute, sub license, and/or sell copies of the Software, and to 12 * permit persons to whom the Software is furnished to do so, subject to 13 * the following conditions: 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. 22 * 23 * The above copyright notice and this permission notice (including the 24 * next paragraph) shall be included in all copies or substantial portions 25 * of the Software. 26 * 27 */ 28 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: amdgpu_vcn.c,v 1.2 2021/12/18 23:44:58 riastradh Exp $"); 31 32 #include <linux/firmware.h> 33 #include <linux/module.h> 34 #include <linux/pci.h> 35 36 #include "amdgpu.h" 37 #include "amdgpu_pm.h" 38 #include "amdgpu_vcn.h" 39 #include "soc15d.h" 40 41 /* Firmware Names */ 42 #define FIRMWARE_RAVEN "amdgpu/raven_vcn.bin" 43 #define FIRMWARE_PICASSO "amdgpu/picasso_vcn.bin" 44 #define FIRMWARE_RAVEN2 "amdgpu/raven2_vcn.bin" 45 #define FIRMWARE_ARCTURUS "amdgpu/arcturus_vcn.bin" 46 #define FIRMWARE_RENOIR "amdgpu/renoir_vcn.bin" 47 #define FIRMWARE_NAVI10 "amdgpu/navi10_vcn.bin" 48 #define FIRMWARE_NAVI14 "amdgpu/navi14_vcn.bin" 49 #define FIRMWARE_NAVI12 "amdgpu/navi12_vcn.bin" 50 51 MODULE_FIRMWARE(FIRMWARE_RAVEN); 52 MODULE_FIRMWARE(FIRMWARE_PICASSO); 53 MODULE_FIRMWARE(FIRMWARE_RAVEN2); 54 MODULE_FIRMWARE(FIRMWARE_ARCTURUS); 55 MODULE_FIRMWARE(FIRMWARE_RENOIR); 56 MODULE_FIRMWARE(FIRMWARE_NAVI10); 57 MODULE_FIRMWARE(FIRMWARE_NAVI14); 58 MODULE_FIRMWARE(FIRMWARE_NAVI12); 59 60 static void amdgpu_vcn_idle_work_handler(struct work_struct *work); 61 62 int amdgpu_vcn_sw_init(struct amdgpu_device *adev) 63 { 64 unsigned long bo_size; 65 const char *fw_name; 66 const struct common_firmware_header *hdr; 67 unsigned char fw_check; 68 int i, r; 69 70 INIT_DELAYED_WORK(&adev->vcn.idle_work, amdgpu_vcn_idle_work_handler); 71 72 switch (adev->asic_type) { 73 case CHIP_RAVEN: 74 if (adev->rev_id >= 8) 75 fw_name = FIRMWARE_RAVEN2; 76 else if (adev->pdev->device == 0x15d8) 77 fw_name = FIRMWARE_PICASSO; 78 else 79 fw_name = FIRMWARE_RAVEN; 80 break; 81 case CHIP_ARCTURUS: 82 fw_name = FIRMWARE_ARCTURUS; 83 if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && 84 (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) 85 adev->vcn.indirect_sram = true; 86 break; 87 case CHIP_RENOIR: 88 fw_name = FIRMWARE_RENOIR; 89 if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && 90 (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) 91 adev->vcn.indirect_sram = true; 92 break; 93 case CHIP_NAVI10: 94 fw_name = FIRMWARE_NAVI10; 95 if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && 96 (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) 97 adev->vcn.indirect_sram = true; 98 break; 99 case CHIP_NAVI14: 100 fw_name = FIRMWARE_NAVI14; 101 if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && 102 (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) 103 adev->vcn.indirect_sram = true; 104 break; 105 case CHIP_NAVI12: 106 fw_name = FIRMWARE_NAVI12; 107 if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && 108 (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) 109 adev->vcn.indirect_sram = true; 110 break; 111 default: 112 return -EINVAL; 113 } 114 115 r = request_firmware(&adev->vcn.fw, fw_name, adev->dev); 116 if (r) { 117 dev_err(adev->dev, "amdgpu_vcn: Can't load firmware \"%s\"\n", 118 fw_name); 119 return r; 120 } 121 122 r = amdgpu_ucode_validate(adev->vcn.fw); 123 if (r) { 124 dev_err(adev->dev, "amdgpu_vcn: Can't validate firmware \"%s\"\n", 125 fw_name); 126 release_firmware(adev->vcn.fw); 127 adev->vcn.fw = NULL; 128 return r; 129 } 130 131 hdr = (const struct common_firmware_header *)adev->vcn.fw->data; 132 adev->vcn.fw_version = le32_to_cpu(hdr->ucode_version); 133 134 /* Bit 20-23, it is encode major and non-zero for new naming convention. 135 * This field is part of version minor and DRM_DISABLED_FLAG in old naming 136 * convention. Since the l:wq!atest version minor is 0x5B and DRM_DISABLED_FLAG 137 * is zero in old naming convention, this field is always zero so far. 138 * These four bits are used to tell which naming convention is present. 139 */ 140 fw_check = (le32_to_cpu(hdr->ucode_version) >> 20) & 0xf; 141 if (fw_check) { 142 unsigned int dec_ver, enc_major, enc_minor, vep, fw_rev; 143 144 fw_rev = le32_to_cpu(hdr->ucode_version) & 0xfff; 145 enc_minor = (le32_to_cpu(hdr->ucode_version) >> 12) & 0xff; 146 enc_major = fw_check; 147 dec_ver = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xf; 148 vep = (le32_to_cpu(hdr->ucode_version) >> 28) & 0xf; 149 DRM_INFO("Found VCN firmware Version ENC: %hu.%hu DEC: %hu VEP: %hu Revision: %hu\n", 150 enc_major, enc_minor, dec_ver, vep, fw_rev); 151 } else { 152 unsigned int version_major, version_minor, family_id; 153 154 family_id = le32_to_cpu(hdr->ucode_version) & 0xff; 155 version_major = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xff; 156 version_minor = (le32_to_cpu(hdr->ucode_version) >> 8) & 0xff; 157 DRM_INFO("Found VCN firmware Version: %hu.%hu Family ID: %hu\n", 158 version_major, version_minor, family_id); 159 } 160 161 bo_size = AMDGPU_VCN_STACK_SIZE + AMDGPU_VCN_CONTEXT_SIZE; 162 if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) 163 bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8); 164 165 for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 166 if (adev->vcn.harvest_config & (1 << i)) 167 continue; 168 169 r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE, 170 AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.inst[i].vcpu_bo, 171 &adev->vcn.inst[i].gpu_addr, &adev->vcn.inst[i].cpu_addr); 172 if (r) { 173 dev_err(adev->dev, "(%d) failed to allocate vcn bo\n", r); 174 return r; 175 } 176 177 if (adev->vcn.indirect_sram) { 178 r = amdgpu_bo_create_kernel(adev, 64 * 2 * 4, PAGE_SIZE, 179 AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.inst[i].dpg_sram_bo, 180 &adev->vcn.inst[i].dpg_sram_gpu_addr, &adev->vcn.inst[i].dpg_sram_cpu_addr); 181 if (r) { 182 dev_err(adev->dev, "VCN %d (%d) failed to allocate DPG bo\n", i, r); 183 return r; 184 } 185 } 186 } 187 188 return 0; 189 } 190 191 int amdgpu_vcn_sw_fini(struct amdgpu_device *adev) 192 { 193 int i, j; 194 195 cancel_delayed_work_sync(&adev->vcn.idle_work); 196 197 for (j = 0; j < adev->vcn.num_vcn_inst; ++j) { 198 if (adev->vcn.harvest_config & (1 << j)) 199 continue; 200 if (adev->vcn.indirect_sram) { 201 amdgpu_bo_free_kernel(&adev->vcn.inst[j].dpg_sram_bo, 202 &adev->vcn.inst[j].dpg_sram_gpu_addr, 203 (void **)&adev->vcn.inst[j].dpg_sram_cpu_addr); 204 } 205 kvfree(adev->vcn.inst[j].saved_bo); 206 207 amdgpu_bo_free_kernel(&adev->vcn.inst[j].vcpu_bo, 208 &adev->vcn.inst[j].gpu_addr, 209 (void **)&adev->vcn.inst[j].cpu_addr); 210 211 amdgpu_ring_fini(&adev->vcn.inst[j].ring_dec); 212 213 for (i = 0; i < adev->vcn.num_enc_rings; ++i) 214 amdgpu_ring_fini(&adev->vcn.inst[j].ring_enc[i]); 215 } 216 217 release_firmware(adev->vcn.fw); 218 219 return 0; 220 } 221 222 int amdgpu_vcn_suspend(struct amdgpu_device *adev) 223 { 224 unsigned size; 225 void *ptr; 226 int i; 227 228 cancel_delayed_work_sync(&adev->vcn.idle_work); 229 230 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 231 if (adev->vcn.harvest_config & (1 << i)) 232 continue; 233 if (adev->vcn.inst[i].vcpu_bo == NULL) 234 return 0; 235 236 size = amdgpu_bo_size(adev->vcn.inst[i].vcpu_bo); 237 ptr = adev->vcn.inst[i].cpu_addr; 238 239 adev->vcn.inst[i].saved_bo = kvmalloc(size, GFP_KERNEL); 240 if (!adev->vcn.inst[i].saved_bo) 241 return -ENOMEM; 242 243 memcpy_fromio(adev->vcn.inst[i].saved_bo, ptr, size); 244 } 245 return 0; 246 } 247 248 int amdgpu_vcn_resume(struct amdgpu_device *adev) 249 { 250 unsigned size; 251 void *ptr; 252 int i; 253 254 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 255 if (adev->vcn.harvest_config & (1 << i)) 256 continue; 257 if (adev->vcn.inst[i].vcpu_bo == NULL) 258 return -EINVAL; 259 260 size = amdgpu_bo_size(adev->vcn.inst[i].vcpu_bo); 261 ptr = adev->vcn.inst[i].cpu_addr; 262 263 if (adev->vcn.inst[i].saved_bo != NULL) { 264 memcpy_toio(ptr, adev->vcn.inst[i].saved_bo, size); 265 kvfree(adev->vcn.inst[i].saved_bo); 266 adev->vcn.inst[i].saved_bo = NULL; 267 } else { 268 const struct common_firmware_header *hdr; 269 unsigned offset; 270 271 hdr = (const struct common_firmware_header *)adev->vcn.fw->data; 272 if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { 273 offset = le32_to_cpu(hdr->ucode_array_offset_bytes); 274 memcpy_toio(adev->vcn.inst[i].cpu_addr, adev->vcn.fw->data + offset, 275 le32_to_cpu(hdr->ucode_size_bytes)); 276 size -= le32_to_cpu(hdr->ucode_size_bytes); 277 ptr += le32_to_cpu(hdr->ucode_size_bytes); 278 } 279 memset_io(ptr, 0, size); 280 } 281 } 282 return 0; 283 } 284 285 static void amdgpu_vcn_idle_work_handler(struct work_struct *work) 286 { 287 struct amdgpu_device *adev = 288 container_of(work, struct amdgpu_device, vcn.idle_work.work); 289 unsigned int fences = 0, fence[AMDGPU_MAX_VCN_INSTANCES] = {0}; 290 unsigned int i, j; 291 292 for (j = 0; j < adev->vcn.num_vcn_inst; ++j) { 293 if (adev->vcn.harvest_config & (1 << j)) 294 continue; 295 296 for (i = 0; i < adev->vcn.num_enc_rings; ++i) { 297 fence[j] += amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_enc[i]); 298 } 299 300 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { 301 struct dpg_pause_state new_state; 302 303 if (fence[j]) 304 new_state.fw_based = VCN_DPG_STATE__PAUSE; 305 else 306 new_state.fw_based = VCN_DPG_STATE__UNPAUSE; 307 308 adev->vcn.pause_dpg_mode(adev, j, &new_state); 309 } 310 311 fence[j] += amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_dec); 312 fences += fence[j]; 313 } 314 315 if (fences == 0) { 316 amdgpu_gfx_off_ctrl(adev, true); 317 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, 318 AMD_PG_STATE_GATE); 319 } else { 320 schedule_delayed_work(&adev->vcn.idle_work, VCN_IDLE_TIMEOUT); 321 } 322 } 323 324 void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring) 325 { 326 struct amdgpu_device *adev = ring->adev; 327 bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work); 328 329 if (set_clocks) { 330 amdgpu_gfx_off_ctrl(adev, false); 331 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, 332 AMD_PG_STATE_UNGATE); 333 } 334 335 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { 336 struct dpg_pause_state new_state; 337 unsigned int fences = 0; 338 unsigned int i; 339 340 for (i = 0; i < adev->vcn.num_enc_rings; ++i) { 341 fences += amdgpu_fence_count_emitted(&adev->vcn.inst[ring->me].ring_enc[i]); 342 } 343 if (fences) 344 new_state.fw_based = VCN_DPG_STATE__PAUSE; 345 else 346 new_state.fw_based = VCN_DPG_STATE__UNPAUSE; 347 348 if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC) 349 new_state.fw_based = VCN_DPG_STATE__PAUSE; 350 351 adev->vcn.pause_dpg_mode(adev, ring->me, &new_state); 352 } 353 } 354 355 void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring) 356 { 357 schedule_delayed_work(&ring->adev->vcn.idle_work, VCN_IDLE_TIMEOUT); 358 } 359 360 int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring) 361 { 362 struct amdgpu_device *adev = ring->adev; 363 uint32_t tmp = 0; 364 unsigned i; 365 int r; 366 367 WREG32(adev->vcn.inst[ring->me].external.scratch9, 0xCAFEDEAD); 368 r = amdgpu_ring_alloc(ring, 3); 369 if (r) 370 return r; 371 amdgpu_ring_write(ring, PACKET0(adev->vcn.internal.scratch9, 0)); 372 amdgpu_ring_write(ring, 0xDEADBEEF); 373 amdgpu_ring_commit(ring); 374 for (i = 0; i < adev->usec_timeout; i++) { 375 tmp = RREG32(adev->vcn.inst[ring->me].external.scratch9); 376 if (tmp == 0xDEADBEEF) 377 break; 378 udelay(1); 379 } 380 381 if (i >= adev->usec_timeout) 382 r = -ETIMEDOUT; 383 384 return r; 385 } 386 387 static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring, 388 struct amdgpu_bo *bo, 389 struct dma_fence **fence) 390 { 391 struct amdgpu_device *adev = ring->adev; 392 struct dma_fence *f = NULL; 393 struct amdgpu_job *job; 394 struct amdgpu_ib *ib; 395 uint64_t addr; 396 int i, r; 397 398 r = amdgpu_job_alloc_with_ib(adev, 64, &job); 399 if (r) 400 goto err; 401 402 ib = &job->ibs[0]; 403 addr = amdgpu_bo_gpu_offset(bo); 404 ib->ptr[0] = PACKET0(adev->vcn.internal.data0, 0); 405 ib->ptr[1] = addr; 406 ib->ptr[2] = PACKET0(adev->vcn.internal.data1, 0); 407 ib->ptr[3] = addr >> 32; 408 ib->ptr[4] = PACKET0(adev->vcn.internal.cmd, 0); 409 ib->ptr[5] = 0; 410 for (i = 6; i < 16; i += 2) { 411 ib->ptr[i] = PACKET0(adev->vcn.internal.nop, 0); 412 ib->ptr[i+1] = 0; 413 } 414 ib->length_dw = 16; 415 416 r = amdgpu_job_submit_direct(job, ring, &f); 417 if (r) 418 goto err_free; 419 420 amdgpu_bo_fence(bo, f, false); 421 amdgpu_bo_unreserve(bo); 422 amdgpu_bo_unref(&bo); 423 424 if (fence) 425 *fence = dma_fence_get(f); 426 dma_fence_put(f); 427 428 return 0; 429 430 err_free: 431 amdgpu_job_free(job); 432 433 err: 434 amdgpu_bo_unreserve(bo); 435 amdgpu_bo_unref(&bo); 436 return r; 437 } 438 439 static int amdgpu_vcn_dec_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, 440 struct dma_fence **fence) 441 { 442 struct amdgpu_device *adev = ring->adev; 443 struct amdgpu_bo *bo = NULL; 444 uint32_t *msg; 445 int r, i; 446 447 r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE, 448 AMDGPU_GEM_DOMAIN_VRAM, 449 &bo, NULL, (void **)&msg); 450 if (r) 451 return r; 452 453 msg[0] = cpu_to_le32(0x00000028); 454 msg[1] = cpu_to_le32(0x00000038); 455 msg[2] = cpu_to_le32(0x00000001); 456 msg[3] = cpu_to_le32(0x00000000); 457 msg[4] = cpu_to_le32(handle); 458 msg[5] = cpu_to_le32(0x00000000); 459 msg[6] = cpu_to_le32(0x00000001); 460 msg[7] = cpu_to_le32(0x00000028); 461 msg[8] = cpu_to_le32(0x00000010); 462 msg[9] = cpu_to_le32(0x00000000); 463 msg[10] = cpu_to_le32(0x00000007); 464 msg[11] = cpu_to_le32(0x00000000); 465 msg[12] = cpu_to_le32(0x00000780); 466 msg[13] = cpu_to_le32(0x00000440); 467 for (i = 14; i < 1024; ++i) 468 msg[i] = cpu_to_le32(0x0); 469 470 return amdgpu_vcn_dec_send_msg(ring, bo, fence); 471 } 472 473 static int amdgpu_vcn_dec_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, 474 struct dma_fence **fence) 475 { 476 struct amdgpu_device *adev = ring->adev; 477 struct amdgpu_bo *bo = NULL; 478 uint32_t *msg; 479 int r, i; 480 481 r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE, 482 AMDGPU_GEM_DOMAIN_VRAM, 483 &bo, NULL, (void **)&msg); 484 if (r) 485 return r; 486 487 msg[0] = cpu_to_le32(0x00000028); 488 msg[1] = cpu_to_le32(0x00000018); 489 msg[2] = cpu_to_le32(0x00000000); 490 msg[3] = cpu_to_le32(0x00000002); 491 msg[4] = cpu_to_le32(handle); 492 msg[5] = cpu_to_le32(0x00000000); 493 for (i = 6; i < 1024; ++i) 494 msg[i] = cpu_to_le32(0x0); 495 496 return amdgpu_vcn_dec_send_msg(ring, bo, fence); 497 } 498 499 int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout) 500 { 501 struct amdgpu_device *adev = ring->adev; 502 struct dma_fence *fence; 503 long r; 504 505 /* temporarily disable ib test for sriov */ 506 if (amdgpu_sriov_vf(adev)) 507 return 0; 508 509 r = amdgpu_vcn_dec_get_create_msg(ring, 1, NULL); 510 if (r) 511 goto error; 512 513 r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &fence); 514 if (r) 515 goto error; 516 517 r = dma_fence_wait_timeout(fence, false, timeout); 518 if (r == 0) 519 r = -ETIMEDOUT; 520 else if (r > 0) 521 r = 0; 522 523 dma_fence_put(fence); 524 error: 525 return r; 526 } 527 528 int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring) 529 { 530 struct amdgpu_device *adev = ring->adev; 531 uint32_t rptr; 532 unsigned i; 533 int r; 534 535 r = amdgpu_ring_alloc(ring, 16); 536 if (r) 537 return r; 538 539 rptr = amdgpu_ring_get_rptr(ring); 540 541 amdgpu_ring_write(ring, VCN_ENC_CMD_END); 542 amdgpu_ring_commit(ring); 543 544 for (i = 0; i < adev->usec_timeout; i++) { 545 if (amdgpu_ring_get_rptr(ring) != rptr) 546 break; 547 udelay(1); 548 } 549 550 if (i >= adev->usec_timeout) 551 r = -ETIMEDOUT; 552 553 return r; 554 } 555 556 static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, 557 struct amdgpu_bo *bo, 558 struct dma_fence **fence) 559 { 560 const unsigned ib_size_dw = 16; 561 struct amdgpu_job *job; 562 struct amdgpu_ib *ib; 563 struct dma_fence *f = NULL; 564 uint64_t addr; 565 int i, r; 566 567 r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); 568 if (r) 569 return r; 570 571 ib = &job->ibs[0]; 572 addr = amdgpu_bo_gpu_offset(bo); 573 574 ib->length_dw = 0; 575 ib->ptr[ib->length_dw++] = 0x00000018; 576 ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ 577 ib->ptr[ib->length_dw++] = handle; 578 ib->ptr[ib->length_dw++] = upper_32_bits(addr); 579 ib->ptr[ib->length_dw++] = addr; 580 ib->ptr[ib->length_dw++] = 0x0000000b; 581 582 ib->ptr[ib->length_dw++] = 0x00000014; 583 ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ 584 ib->ptr[ib->length_dw++] = 0x0000001c; 585 ib->ptr[ib->length_dw++] = 0x00000000; 586 ib->ptr[ib->length_dw++] = 0x00000000; 587 588 ib->ptr[ib->length_dw++] = 0x00000008; 589 ib->ptr[ib->length_dw++] = 0x08000001; /* op initialize */ 590 591 for (i = ib->length_dw; i < ib_size_dw; ++i) 592 ib->ptr[i] = 0x0; 593 594 r = amdgpu_job_submit_direct(job, ring, &f); 595 if (r) 596 goto err; 597 598 if (fence) 599 *fence = dma_fence_get(f); 600 dma_fence_put(f); 601 602 return 0; 603 604 err: 605 amdgpu_job_free(job); 606 return r; 607 } 608 609 static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, 610 struct amdgpu_bo *bo, 611 struct dma_fence **fence) 612 { 613 const unsigned ib_size_dw = 16; 614 struct amdgpu_job *job; 615 struct amdgpu_ib *ib; 616 struct dma_fence *f = NULL; 617 uint64_t addr; 618 int i, r; 619 620 r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); 621 if (r) 622 return r; 623 624 ib = &job->ibs[0]; 625 addr = amdgpu_bo_gpu_offset(bo); 626 627 ib->length_dw = 0; 628 ib->ptr[ib->length_dw++] = 0x00000018; 629 ib->ptr[ib->length_dw++] = 0x00000001; 630 ib->ptr[ib->length_dw++] = handle; 631 ib->ptr[ib->length_dw++] = upper_32_bits(addr); 632 ib->ptr[ib->length_dw++] = addr; 633 ib->ptr[ib->length_dw++] = 0x0000000b; 634 635 ib->ptr[ib->length_dw++] = 0x00000014; 636 ib->ptr[ib->length_dw++] = 0x00000002; 637 ib->ptr[ib->length_dw++] = 0x0000001c; 638 ib->ptr[ib->length_dw++] = 0x00000000; 639 ib->ptr[ib->length_dw++] = 0x00000000; 640 641 ib->ptr[ib->length_dw++] = 0x00000008; 642 ib->ptr[ib->length_dw++] = 0x08000002; /* op close session */ 643 644 for (i = ib->length_dw; i < ib_size_dw; ++i) 645 ib->ptr[i] = 0x0; 646 647 r = amdgpu_job_submit_direct(job, ring, &f); 648 if (r) 649 goto err; 650 651 if (fence) 652 *fence = dma_fence_get(f); 653 dma_fence_put(f); 654 655 return 0; 656 657 err: 658 amdgpu_job_free(job); 659 return r; 660 } 661 662 int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) 663 { 664 struct amdgpu_device *adev = ring->adev; 665 struct dma_fence *fence = NULL; 666 struct amdgpu_bo *bo = NULL; 667 long r; 668 669 /* temporarily disable ib test for sriov */ 670 if (amdgpu_sriov_vf(adev)) 671 return 0; 672 673 r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE, 674 AMDGPU_GEM_DOMAIN_VRAM, 675 &bo, NULL, NULL); 676 if (r) 677 return r; 678 679 r = amdgpu_vcn_enc_get_create_msg(ring, 1, bo, NULL); 680 if (r) 681 goto error; 682 683 r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, bo, &fence); 684 if (r) 685 goto error; 686 687 r = dma_fence_wait_timeout(fence, false, timeout); 688 if (r == 0) 689 r = -ETIMEDOUT; 690 else if (r > 0) 691 r = 0; 692 693 error: 694 dma_fence_put(fence); 695 amdgpu_bo_unreserve(bo); 696 amdgpu_bo_unref(&bo); 697 return r; 698 } 699