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