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