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