aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
diff options
context:
space:
mode:
authorLeo Liu <leo.liu@amd.com>2016-12-21 13:56:44 -0500
committerAlex Deucher <alexander.deucher@amd.com>2017-05-24 17:41:23 -0400
commit2d531d81d0fb906ee74a5d5f8c04857849efa785 (patch)
treee0fae57a4a4730fb0759782721c5cd088534ade1 /drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
parent95d0906f8506550a7c4a59c770732e7de912cffc (diff)
drm/amdgpu: add encode tests for vcn
Add encode ring and ib tests. Signed-off-by: Leo Liu <leo.liu@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c203
1 files changed, 203 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
index 97b09b63753c..9bb59cc33ace 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
@@ -112,6 +112,15 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
112 return r; 112 return r;
113 } 113 }
114 114
115 ring = &adev->vcn.ring_enc[0];
116 rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_NORMAL];
117 r = amd_sched_entity_init(&ring->sched, &adev->vcn.entity_enc,
118 rq, amdgpu_sched_jobs);
119 if (r != 0) {
120 DRM_ERROR("Failed setting up VCN enc run queue.\n");
121 return r;
122 }
123
115 return 0; 124 return 0;
116} 125}
117 126
@@ -121,6 +130,8 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev)
121 130
122 amd_sched_entity_fini(&adev->vcn.ring_dec.sched, &adev->vcn.entity_dec); 131 amd_sched_entity_fini(&adev->vcn.ring_dec.sched, &adev->vcn.entity_dec);
123 132
133 amd_sched_entity_fini(&adev->vcn.ring_enc[0].sched, &adev->vcn.entity_enc);
134
124 amdgpu_bo_free_kernel(&adev->vcn.vcpu_bo, 135 amdgpu_bo_free_kernel(&adev->vcn.vcpu_bo,
125 &adev->vcn.gpu_addr, 136 &adev->vcn.gpu_addr,
126 (void **)&adev->vcn.cpu_addr); 137 (void **)&adev->vcn.cpu_addr);
@@ -423,3 +434,195 @@ int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout)
423error: 434error:
424 return r; 435 return r;
425} 436}
437
438static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
439 struct dma_fence **fence)
440{
441 const unsigned ib_size_dw = 1024;
442 struct amdgpu_job *job;
443 struct amdgpu_ib *ib;
444 struct dma_fence *f = NULL;
445 uint64_t dummy;
446 int i, r;
447
448 r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
449 if (r)
450 return r;
451
452 ib = &job->ibs[0];
453
454 dummy = ib->gpu_addr + 1024;
455
456 /* stitch together an VCN enc create msg */
457 ib->length_dw = 0;
458 ib->ptr[ib->length_dw++] = 0x0000000c; /* len */
459 ib->ptr[ib->length_dw++] = 0x00000001; /* session cmd */
460 ib->ptr[ib->length_dw++] = handle;
461
462 ib->ptr[ib->length_dw++] = 0x00000040; /* len */
463 ib->ptr[ib->length_dw++] = 0x01000001; /* create cmd */
464 ib->ptr[ib->length_dw++] = 0x00000000;
465 ib->ptr[ib->length_dw++] = 0x00000042;
466 ib->ptr[ib->length_dw++] = 0x0000000a;
467 ib->ptr[ib->length_dw++] = 0x00000001;
468 ib->ptr[ib->length_dw++] = 0x00000080;
469 ib->ptr[ib->length_dw++] = 0x00000060;
470 ib->ptr[ib->length_dw++] = 0x00000100;
471 ib->ptr[ib->length_dw++] = 0x00000100;
472 ib->ptr[ib->length_dw++] = 0x0000000c;
473 ib->ptr[ib->length_dw++] = 0x00000000;
474 ib->ptr[ib->length_dw++] = 0x00000000;
475 ib->ptr[ib->length_dw++] = 0x00000000;
476 ib->ptr[ib->length_dw++] = 0x00000000;
477 ib->ptr[ib->length_dw++] = 0x00000000;
478
479 ib->ptr[ib->length_dw++] = 0x00000014; /* len */
480 ib->ptr[ib->length_dw++] = 0x05000005; /* feedback buffer */
481 ib->ptr[ib->length_dw++] = upper_32_bits(dummy);
482 ib->ptr[ib->length_dw++] = dummy;
483 ib->ptr[ib->length_dw++] = 0x00000001;
484
485 for (i = ib->length_dw; i < ib_size_dw; ++i)
486 ib->ptr[i] = 0x0;
487
488 r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f);
489 job->fence = dma_fence_get(f);
490 if (r)
491 goto err;
492
493 amdgpu_job_free(job);
494 if (fence)
495 *fence = dma_fence_get(f);
496 dma_fence_put(f);
497 return 0;
498
499err:
500 amdgpu_job_free(job);
501 return r;
502}
503
504static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
505 bool direct, struct dma_fence **fence)
506{
507 const unsigned ib_size_dw = 1024;
508 struct amdgpu_job *job;
509 struct amdgpu_ib *ib;
510 struct dma_fence *f = NULL;
511 int i, r;
512
513 r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
514 if (r)
515 return r;
516
517 ib = &job->ibs[0];
518
519 /* stitch together an VCN enc destroy msg */
520 ib->length_dw = 0;
521 ib->ptr[ib->length_dw++] = 0x0000000c; /* len */
522 ib->ptr[ib->length_dw++] = 0x00000001; /* session cmd */
523 ib->ptr[ib->length_dw++] = handle;
524
525 ib->ptr[ib->length_dw++] = 0x00000020; /* len */
526 ib->ptr[ib->length_dw++] = 0x00000002; /* task info */
527 ib->ptr[ib->length_dw++] = 0xffffffff; /* next task info, set to 0xffffffff if no */
528 ib->ptr[ib->length_dw++] = 0x00000001; /* destroy session */
529 ib->ptr[ib->length_dw++] = 0x00000000;
530 ib->ptr[ib->length_dw++] = 0x00000000;
531 ib->ptr[ib->length_dw++] = 0xffffffff; /* feedback is not needed, set to 0xffffffff and firmware will not output feedback */
532 ib->ptr[ib->length_dw++] = 0x00000000;
533
534 ib->ptr[ib->length_dw++] = 0x00000008; /* len */
535 ib->ptr[ib->length_dw++] = 0x02000001; /* destroy cmd */
536
537 for (i = ib->length_dw; i < ib_size_dw; ++i)
538 ib->ptr[i] = 0x0;
539
540 if (direct) {
541 r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f);
542 job->fence = dma_fence_get(f);
543 if (r)
544 goto err;
545
546 amdgpu_job_free(job);
547 } else {
548 r = amdgpu_job_submit(job, ring, &ring->adev->vcn.entity_enc,
549 AMDGPU_FENCE_OWNER_UNDEFINED, &f);
550 if (r)
551 goto err;
552 }
553
554 if (fence)
555 *fence = dma_fence_get(f);
556 dma_fence_put(f);
557 return 0;
558
559err:
560 amdgpu_job_free(job);
561 return r;
562}
563
564int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring)
565{
566 struct amdgpu_device *adev = ring->adev;
567 uint32_t rptr = amdgpu_ring_get_rptr(ring);
568 unsigned i;
569 int r;
570
571 r = amdgpu_ring_alloc(ring, 16);
572 if (r) {
573 DRM_ERROR("amdgpu: vcn enc failed to lock ring %d (%d).\n",
574 ring->idx, r);
575 return r;
576 }
577 amdgpu_ring_write(ring, VCE_CMD_END);
578 amdgpu_ring_commit(ring);
579
580 for (i = 0; i < adev->usec_timeout; i++) {
581 if (amdgpu_ring_get_rptr(ring) != rptr)
582 break;
583 DRM_UDELAY(1);
584 }
585
586 if (i < adev->usec_timeout) {
587 DRM_INFO("ring test on %d succeeded in %d usecs\n",
588 ring->idx, i);
589 } else {
590 DRM_ERROR("amdgpu: ring %d test failed\n",
591 ring->idx);
592 r = -ETIMEDOUT;
593 }
594
595 return r;
596}
597
598int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)
599{
600 struct dma_fence *fence = NULL;
601 long r;
602
603 r = amdgpu_vcn_enc_get_create_msg(ring, 1, NULL);
604 if (r) {
605 DRM_ERROR("amdgpu: failed to get create msg (%ld).\n", r);
606 goto error;
607 }
608
609 r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, true, &fence);
610 if (r) {
611 DRM_ERROR("amdgpu: failed to get destroy ib (%ld).\n", r);
612 goto error;
613 }
614
615 r = dma_fence_wait_timeout(fence, false, timeout);
616 if (r == 0) {
617 DRM_ERROR("amdgpu: IB test timed out.\n");
618 r = -ETIMEDOUT;
619 } else if (r < 0) {
620 DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r);
621 } else {
622 DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
623 r = 0;
624 }
625error:
626 dma_fence_put(fence);
627 return r;
628}