aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c179
1 files changed, 106 insertions, 73 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
index d3ca73090e39..33ee6ae28f37 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
@@ -48,6 +48,7 @@
48#endif 48#endif
49#define FIRMWARE_TONGA "amdgpu/tonga_vce.bin" 49#define FIRMWARE_TONGA "amdgpu/tonga_vce.bin"
50#define FIRMWARE_CARRIZO "amdgpu/carrizo_vce.bin" 50#define FIRMWARE_CARRIZO "amdgpu/carrizo_vce.bin"
51#define FIRMWARE_FIJI "amdgpu/fiji_vce.bin"
51 52
52#ifdef CONFIG_DRM_AMDGPU_CIK 53#ifdef CONFIG_DRM_AMDGPU_CIK
53MODULE_FIRMWARE(FIRMWARE_BONAIRE); 54MODULE_FIRMWARE(FIRMWARE_BONAIRE);
@@ -58,6 +59,7 @@ MODULE_FIRMWARE(FIRMWARE_MULLINS);
58#endif 59#endif
59MODULE_FIRMWARE(FIRMWARE_TONGA); 60MODULE_FIRMWARE(FIRMWARE_TONGA);
60MODULE_FIRMWARE(FIRMWARE_CARRIZO); 61MODULE_FIRMWARE(FIRMWARE_CARRIZO);
62MODULE_FIRMWARE(FIRMWARE_FIJI);
61 63
62static void amdgpu_vce_idle_work_handler(struct work_struct *work); 64static void amdgpu_vce_idle_work_handler(struct work_struct *work);
63 65
@@ -101,6 +103,9 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size)
101 case CHIP_CARRIZO: 103 case CHIP_CARRIZO:
102 fw_name = FIRMWARE_CARRIZO; 104 fw_name = FIRMWARE_CARRIZO;
103 break; 105 break;
106 case CHIP_FIJI:
107 fw_name = FIRMWARE_FIJI;
108 break;
104 109
105 default: 110 default:
106 return -EINVAL; 111 return -EINVAL;
@@ -334,6 +339,14 @@ void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp)
334 } 339 }
335} 340}
336 341
342static int amdgpu_vce_free_job(
343 struct amdgpu_cs_parser *sched_job)
344{
345 amdgpu_ib_free(sched_job->adev, sched_job->ibs);
346 kfree(sched_job->ibs);
347 return 0;
348}
349
337/** 350/**
338 * amdgpu_vce_get_create_msg - generate a VCE create msg 351 * amdgpu_vce_get_create_msg - generate a VCE create msg
339 * 352 *
@@ -345,59 +358,69 @@ void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp)
345 * Open up a stream for HW test 358 * Open up a stream for HW test
346 */ 359 */
347int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, 360int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
348 struct amdgpu_fence **fence) 361 struct fence **fence)
349{ 362{
350 const unsigned ib_size_dw = 1024; 363 const unsigned ib_size_dw = 1024;
351 struct amdgpu_ib ib; 364 struct amdgpu_ib *ib = NULL;
365 struct fence *f = NULL;
366 struct amdgpu_device *adev = ring->adev;
352 uint64_t dummy; 367 uint64_t dummy;
353 int i, r; 368 int i, r;
354 369
355 r = amdgpu_ib_get(ring, NULL, ib_size_dw * 4, &ib); 370 ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL);
371 if (!ib)
372 return -ENOMEM;
373 r = amdgpu_ib_get(ring, NULL, ib_size_dw * 4, ib);
356 if (r) { 374 if (r) {
357 DRM_ERROR("amdgpu: failed to get ib (%d).\n", r); 375 DRM_ERROR("amdgpu: failed to get ib (%d).\n", r);
376 kfree(ib);
358 return r; 377 return r;
359 } 378 }
360 379
361 dummy = ib.gpu_addr + 1024; 380 dummy = ib->gpu_addr + 1024;
362 381
363 /* stitch together an VCE create msg */ 382 /* stitch together an VCE create msg */
364 ib.length_dw = 0; 383 ib->length_dw = 0;
365 ib.ptr[ib.length_dw++] = 0x0000000c; /* len */ 384 ib->ptr[ib->length_dw++] = 0x0000000c; /* len */
366 ib.ptr[ib.length_dw++] = 0x00000001; /* session cmd */ 385 ib->ptr[ib->length_dw++] = 0x00000001; /* session cmd */
367 ib.ptr[ib.length_dw++] = handle; 386 ib->ptr[ib->length_dw++] = handle;
368 387
369 ib.ptr[ib.length_dw++] = 0x00000030; /* len */ 388 ib->ptr[ib->length_dw++] = 0x00000030; /* len */
370 ib.ptr[ib.length_dw++] = 0x01000001; /* create cmd */ 389 ib->ptr[ib->length_dw++] = 0x01000001; /* create cmd */
371 ib.ptr[ib.length_dw++] = 0x00000000; 390 ib->ptr[ib->length_dw++] = 0x00000000;
372 ib.ptr[ib.length_dw++] = 0x00000042; 391 ib->ptr[ib->length_dw++] = 0x00000042;
373 ib.ptr[ib.length_dw++] = 0x0000000a; 392 ib->ptr[ib->length_dw++] = 0x0000000a;
374 ib.ptr[ib.length_dw++] = 0x00000001; 393 ib->ptr[ib->length_dw++] = 0x00000001;
375 ib.ptr[ib.length_dw++] = 0x00000080; 394 ib->ptr[ib->length_dw++] = 0x00000080;
376 ib.ptr[ib.length_dw++] = 0x00000060; 395 ib->ptr[ib->length_dw++] = 0x00000060;
377 ib.ptr[ib.length_dw++] = 0x00000100; 396 ib->ptr[ib->length_dw++] = 0x00000100;
378 ib.ptr[ib.length_dw++] = 0x00000100; 397 ib->ptr[ib->length_dw++] = 0x00000100;
379 ib.ptr[ib.length_dw++] = 0x0000000c; 398 ib->ptr[ib->length_dw++] = 0x0000000c;
380 ib.ptr[ib.length_dw++] = 0x00000000; 399 ib->ptr[ib->length_dw++] = 0x00000000;
381 400
382 ib.ptr[ib.length_dw++] = 0x00000014; /* len */ 401 ib->ptr[ib->length_dw++] = 0x00000014; /* len */
383 ib.ptr[ib.length_dw++] = 0x05000005; /* feedback buffer */ 402 ib->ptr[ib->length_dw++] = 0x05000005; /* feedback buffer */
384 ib.ptr[ib.length_dw++] = upper_32_bits(dummy); 403 ib->ptr[ib->length_dw++] = upper_32_bits(dummy);
385 ib.ptr[ib.length_dw++] = dummy; 404 ib->ptr[ib->length_dw++] = dummy;
386 ib.ptr[ib.length_dw++] = 0x00000001; 405 ib->ptr[ib->length_dw++] = 0x00000001;
387 406
388 for (i = ib.length_dw; i < ib_size_dw; ++i) 407 for (i = ib->length_dw; i < ib_size_dw; ++i)
389 ib.ptr[i] = 0x0; 408 ib->ptr[i] = 0x0;
390 409
391 r = amdgpu_ib_schedule(ring->adev, 1, &ib, AMDGPU_FENCE_OWNER_UNDEFINED); 410 r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1,
392 if (r) { 411 &amdgpu_vce_free_job,
393 DRM_ERROR("amdgpu: failed to schedule ib (%d).\n", r); 412 AMDGPU_FENCE_OWNER_UNDEFINED,
394 } 413 &f);
395 414 if (r)
415 goto err;
396 if (fence) 416 if (fence)
397 *fence = amdgpu_fence_ref(ib.fence); 417 *fence = fence_get(f);
398 418 fence_put(f);
399 amdgpu_ib_free(ring->adev, &ib); 419 if (amdgpu_enable_scheduler)
400 420 return 0;
421err:
422 amdgpu_ib_free(adev, ib);
423 kfree(ib);
401 return r; 424 return r;
402} 425}
403 426
@@ -412,49 +435,59 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
412 * Close up a stream for HW test or if userspace failed to do so 435 * Close up a stream for HW test or if userspace failed to do so
413 */ 436 */
414int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, 437int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
415 struct amdgpu_fence **fence) 438 struct fence **fence)
416{ 439{
417 const unsigned ib_size_dw = 1024; 440 const unsigned ib_size_dw = 1024;
418 struct amdgpu_ib ib; 441 struct amdgpu_ib *ib = NULL;
442 struct fence *f = NULL;
443 struct amdgpu_device *adev = ring->adev;
419 uint64_t dummy; 444 uint64_t dummy;
420 int i, r; 445 int i, r;
421 446
422 r = amdgpu_ib_get(ring, NULL, ib_size_dw * 4, &ib); 447 ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL);
448 if (!ib)
449 return -ENOMEM;
450
451 r = amdgpu_ib_get(ring, NULL, ib_size_dw * 4, ib);
423 if (r) { 452 if (r) {
453 kfree(ib);
424 DRM_ERROR("amdgpu: failed to get ib (%d).\n", r); 454 DRM_ERROR("amdgpu: failed to get ib (%d).\n", r);
425 return r; 455 return r;
426 } 456 }
427 457
428 dummy = ib.gpu_addr + 1024; 458 dummy = ib->gpu_addr + 1024;
429 459
430 /* stitch together an VCE destroy msg */ 460 /* stitch together an VCE destroy msg */
431 ib.length_dw = 0; 461 ib->length_dw = 0;
432 ib.ptr[ib.length_dw++] = 0x0000000c; /* len */ 462 ib->ptr[ib->length_dw++] = 0x0000000c; /* len */
433 ib.ptr[ib.length_dw++] = 0x00000001; /* session cmd */ 463 ib->ptr[ib->length_dw++] = 0x00000001; /* session cmd */
434 ib.ptr[ib.length_dw++] = handle; 464 ib->ptr[ib->length_dw++] = handle;
435 465
436 ib.ptr[ib.length_dw++] = 0x00000014; /* len */ 466 ib->ptr[ib->length_dw++] = 0x00000014; /* len */
437 ib.ptr[ib.length_dw++] = 0x05000005; /* feedback buffer */ 467 ib->ptr[ib->length_dw++] = 0x05000005; /* feedback buffer */
438 ib.ptr[ib.length_dw++] = upper_32_bits(dummy); 468 ib->ptr[ib->length_dw++] = upper_32_bits(dummy);
439 ib.ptr[ib.length_dw++] = dummy; 469 ib->ptr[ib->length_dw++] = dummy;
440 ib.ptr[ib.length_dw++] = 0x00000001; 470 ib->ptr[ib->length_dw++] = 0x00000001;
441 471
442 ib.ptr[ib.length_dw++] = 0x00000008; /* len */ 472 ib->ptr[ib->length_dw++] = 0x00000008; /* len */
443 ib.ptr[ib.length_dw++] = 0x02000001; /* destroy cmd */ 473 ib->ptr[ib->length_dw++] = 0x02000001; /* destroy cmd */
444 474
445 for (i = ib.length_dw; i < ib_size_dw; ++i) 475 for (i = ib->length_dw; i < ib_size_dw; ++i)
446 ib.ptr[i] = 0x0; 476 ib->ptr[i] = 0x0;
447 477 r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1,
448 r = amdgpu_ib_schedule(ring->adev, 1, &ib, AMDGPU_FENCE_OWNER_UNDEFINED); 478 &amdgpu_vce_free_job,
449 if (r) { 479 AMDGPU_FENCE_OWNER_UNDEFINED,
450 DRM_ERROR("amdgpu: failed to schedule ib (%d).\n", r); 480 &f);
451 } 481 if (r)
452 482 goto err;
453 if (fence) 483 if (fence)
454 *fence = amdgpu_fence_ref(ib.fence); 484 *fence = fence_get(f);
455 485 fence_put(f);
456 amdgpu_ib_free(ring->adev, &ib); 486 if (amdgpu_enable_scheduler)
457 487 return 0;
488err:
489 amdgpu_ib_free(adev, ib);
490 kfree(ib);
458 return r; 491 return r;
459} 492}
460 493
@@ -800,7 +833,7 @@ int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring)
800 */ 833 */
801int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring) 834int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring)
802{ 835{
803 struct amdgpu_fence *fence = NULL; 836 struct fence *fence = NULL;
804 int r; 837 int r;
805 838
806 r = amdgpu_vce_get_create_msg(ring, 1, NULL); 839 r = amdgpu_vce_get_create_msg(ring, 1, NULL);
@@ -815,13 +848,13 @@ int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring)
815 goto error; 848 goto error;
816 } 849 }
817 850
818 r = amdgpu_fence_wait(fence, false); 851 r = fence_wait(fence, false);
819 if (r) { 852 if (r) {
820 DRM_ERROR("amdgpu: fence wait failed (%d).\n", r); 853 DRM_ERROR("amdgpu: fence wait failed (%d).\n", r);
821 } else { 854 } else {
822 DRM_INFO("ib test on ring %d succeeded\n", ring->idx); 855 DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
823 } 856 }
824error: 857error:
825 amdgpu_fence_unref(&fence); 858 fence_put(fence);
826 return r; 859 return r;
827} 860}