diff options
author | Christian König <christian.koenig@amd.com> | 2016-07-01 16:19:25 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-07-14 16:46:04 -0400 |
commit | e5223214b22a4f81c12400e10b24e15d549e2bb6 (patch) | |
tree | 09e0c7b7e27ebd3fbed258c1cbfb93b926f114f8 /drivers/gpu/drm/amd/amdgpu | |
parent | 182830a1783ad35f93b9f1a6003a7a48074ed53d (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.c | 53 |
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 | */ |
577 | static int amdgpu_vce_validate_handle(struct amdgpu_cs_parser *p, | 577 | static 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 | ||
740 | out: | 738 | out: |
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 | ||