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