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