aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2016-07-01 16:19:25 -0400
committerAlex Deucher <alexander.deucher@amd.com>2016-07-14 16:46:04 -0400
commite5223214b22a4f81c12400e10b24e15d549e2bb6 (patch)
tree09e0c7b7e27ebd3fbed258c1cbfb93b926f114f8 /drivers/gpu/drm/amd/amdgpu
parent182830a1783ad35f93b9f1a6003a7a48074ed53d (diff)
drm/amdgpu: allow multiple sessions in the same VCE IB
We always used updated firmware for amdgpu, so this actually should work fine. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c53
1 files changed, 27 insertions, 26 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
index 473eb092149a..718f22712335 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
@@ -575,12 +575,10 @@ static int amdgpu_vce_cs_reloc(struct amdgpu_cs_parser *p, uint32_t ib_idx,
575 * we we don't have another free session index. 575 * we we don't have another free session index.
576 */ 576 */
577static int amdgpu_vce_validate_handle(struct amdgpu_cs_parser *p, 577static int amdgpu_vce_validate_handle(struct amdgpu_cs_parser *p,
578 uint32_t handle, bool *allocated) 578 uint32_t handle, uint32_t *allocated)
579{ 579{
580 unsigned i; 580 unsigned i;
581 581
582 *allocated = false;
583
584 /* validate the handle */ 582 /* validate the handle */
585 for (i = 0; i < AMDGPU_MAX_VCE_HANDLES; ++i) { 583 for (i = 0; i < AMDGPU_MAX_VCE_HANDLES; ++i) {
586 if (atomic_read(&p->adev->vce.handles[i]) == handle) { 584 if (atomic_read(&p->adev->vce.handles[i]) == handle) {
@@ -597,7 +595,7 @@ static int amdgpu_vce_validate_handle(struct amdgpu_cs_parser *p,
597 if (!atomic_cmpxchg(&p->adev->vce.handles[i], 0, handle)) { 595 if (!atomic_cmpxchg(&p->adev->vce.handles[i], 0, handle)) {
598 p->adev->vce.filp[i] = p->filp; 596 p->adev->vce.filp[i] = p->filp;
599 p->adev->vce.img_size[i] = 0; 597 p->adev->vce.img_size[i] = 0;
600 *allocated = true; 598 *allocated |= 1 << i;
601 return i; 599 return i;
602 } 600 }
603 } 601 }
@@ -617,9 +615,9 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
617 struct amdgpu_ib *ib = &p->job->ibs[ib_idx]; 615 struct amdgpu_ib *ib = &p->job->ibs[ib_idx];
618 unsigned fb_idx = 0, bs_idx = 0; 616 unsigned fb_idx = 0, bs_idx = 0;
619 int session_idx = -1; 617 int session_idx = -1;
620 bool destroyed = false; 618 uint32_t destroyed = 0;
621 bool created = false; 619 uint32_t created = 0;
622 bool allocated = false; 620 uint32_t allocated = 0;
623 uint32_t tmp, handle = 0; 621 uint32_t tmp, handle = 0;
624 uint32_t *size = &tmp; 622 uint32_t *size = &tmp;
625 int i, r = 0, idx = 0; 623 int i, r = 0, idx = 0;
@@ -636,19 +634,15 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
636 goto out; 634 goto out;
637 } 635 }
638 636
639 if (destroyed) {
640 DRM_ERROR("No other command allowed after destroy!\n");
641 r = -EINVAL;
642 goto out;
643 }
644
645 switch (cmd) { 637 switch (cmd) {
646 case 0x00000001: /* session */ 638 case 0x00000001: /* session */
647 handle = amdgpu_get_ib_value(p, ib_idx, idx + 2); 639 handle = amdgpu_get_ib_value(p, ib_idx, idx + 2);
648 session_idx = amdgpu_vce_validate_handle(p, handle, 640 session_idx = amdgpu_vce_validate_handle(p, handle,
649 &allocated); 641 &allocated);
650 if (session_idx < 0) 642 if (session_idx < 0) {
651 return session_idx; 643 r = session_idx;
644 goto out;
645 }
652 size = &p->adev->vce.img_size[session_idx]; 646 size = &p->adev->vce.img_size[session_idx];
653 break; 647 break;
654 648
@@ -658,8 +652,12 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
658 break; 652 break;
659 653
660 case 0x01000001: /* create */ 654 case 0x01000001: /* create */
661 created = true; 655 created |= 1 << session_idx;
662 if (!allocated) { 656 if (destroyed & (1 << session_idx)) {
657 destroyed &= ~(1 << session_idx);
658 allocated |= 1 << session_idx;
659
660 } else if (!(allocated & (1 << session_idx))) {
663 DRM_ERROR("Handle already in use!\n"); 661 DRM_ERROR("Handle already in use!\n");
664 r = -EINVAL; 662 r = -EINVAL;
665 goto out; 663 goto out;
@@ -692,7 +690,7 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
692 break; 690 break;
693 691
694 case 0x02000001: /* destroy */ 692 case 0x02000001: /* destroy */
695 destroyed = true; 693 destroyed |= 1 << session_idx;
696 break; 694 break;
697 695
698 case 0x05000001: /* context buffer */ 696 case 0x05000001: /* context buffer */
@@ -732,21 +730,24 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
732 idx += len / 4; 730 idx += len / 4;
733 } 731 }
734 732
735 if (allocated && !created) { 733 if (allocated & ~created) {
736 DRM_ERROR("New session without create command!\n"); 734 DRM_ERROR("New session without create command!\n");
737 r = -ENOENT; 735 r = -ENOENT;
738 } 736 }
739 737
740out: 738out:
741 if ((!r && destroyed) || (r && allocated)) { 739 if (!r) {
742 /* 740 /* No error, free all destroyed handle slots */
743 * IB contains a destroy msg or we have allocated an 741 tmp = destroyed;
744 * handle and got an error, anyway free the handle 742 } else {
745 */ 743 /* Error during parsing, free all allocated handle slots */
746 for (i = 0; i < AMDGPU_MAX_VCE_HANDLES; ++i) 744 tmp = allocated;
747 atomic_cmpxchg(&p->adev->vce.handles[i], handle, 0);
748 } 745 }
749 746
747 for (i = 0; i < AMDGPU_MAX_VCE_HANDLES; ++i)
748 if (tmp & (1 << i))
749 atomic_set(&p->adev->vce.handles[i], 0);
750
750 return r; 751 return r;
751} 752}
752 753