diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 179 |
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 |
53 | MODULE_FIRMWARE(FIRMWARE_BONAIRE); | 54 | MODULE_FIRMWARE(FIRMWARE_BONAIRE); |
@@ -58,6 +59,7 @@ MODULE_FIRMWARE(FIRMWARE_MULLINS); | |||
58 | #endif | 59 | #endif |
59 | MODULE_FIRMWARE(FIRMWARE_TONGA); | 60 | MODULE_FIRMWARE(FIRMWARE_TONGA); |
60 | MODULE_FIRMWARE(FIRMWARE_CARRIZO); | 61 | MODULE_FIRMWARE(FIRMWARE_CARRIZO); |
62 | MODULE_FIRMWARE(FIRMWARE_FIJI); | ||
61 | 63 | ||
62 | static void amdgpu_vce_idle_work_handler(struct work_struct *work); | 64 | static 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 | ||
342 | static 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 | */ |
347 | int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, | 360 | int 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; | |
421 | err: | ||
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 | */ |
414 | int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, | 437 | int 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; | |
488 | err: | ||
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 | */ |
801 | int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring) | 834 | int 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 | } |
824 | error: | 857 | error: |
825 | amdgpu_fence_unref(&fence); | 858 | fence_put(fence); |
826 | return r; | 859 | return r; |
827 | } | 860 | } |