aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2017-11-17 05:09:43 -0500
committerAlex Deucher <alexander.deucher@amd.com>2017-12-06 12:47:58 -0500
commit235943189db8ce05b888f48a04ded4448eebc408 (patch)
tree72ed48bf642a3da0b029c91f8f79a8a60c667245 /drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
parentb98f1b9e5e71b636036cc6c0e1a3b428acd216cb (diff)
drm/amdgpu: fix VCE buffer placement restrictions v2
Turned out that VCE still has a placement restriction that BOs can't cross a 4GB boundary. Fix this by adding a command submission parser prepass to correctly place the buffers. v2: add function description Signed-off-by: Christian König <christian.koenig@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c101
1 files changed, 99 insertions, 2 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
index 92477e67087c..a91abfb32746 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
@@ -544,6 +544,54 @@ err:
544} 544}
545 545
546/** 546/**
547 * amdgpu_vce_cs_validate_bo - make sure not to cross 4GB boundary
548 *
549 * @p: parser context
550 * @lo: address of lower dword
551 * @hi: address of higher dword
552 * @size: minimum size
553 * @index: bs/fb index
554 *
555 * Make sure that no BO cross a 4GB boundary.
556 */
557static int amdgpu_vce_validate_bo(struct amdgpu_cs_parser *p, uint32_t ib_idx,
558 int lo, int hi, unsigned size, int32_t index)
559{
560 int64_t offset = ((uint64_t)size) * ((int64_t)index);
561 struct amdgpu_bo_va_mapping *mapping;
562 unsigned i, fpfn, lpfn;
563 struct amdgpu_bo *bo;
564 uint64_t addr;
565 int r;
566
567 addr = ((uint64_t)amdgpu_get_ib_value(p, ib_idx, lo)) |
568 ((uint64_t)amdgpu_get_ib_value(p, ib_idx, hi)) << 32;
569 if (index >= 0) {
570 addr += offset;
571 fpfn = PAGE_ALIGN(offset) >> PAGE_SHIFT;
572 lpfn = 0x100000000ULL >> PAGE_SHIFT;
573 } else {
574 fpfn = 0;
575 lpfn = (0x100000000ULL - PAGE_ALIGN(offset)) >> PAGE_SHIFT;
576 }
577
578 r = amdgpu_cs_find_mapping(p, addr, &bo, &mapping);
579 if (r) {
580 DRM_ERROR("Can't find BO for addr 0x%010Lx %d %d %d %d\n",
581 addr, lo, hi, size, index);
582 return r;
583 }
584
585 for (i = 0; i < bo->placement.num_placement; ++i) {
586 bo->placements[i].fpfn = max(bo->placements[i].fpfn, fpfn);
587 bo->placements[i].lpfn = bo->placements[i].fpfn ?
588 min(bo->placements[i].fpfn, lpfn) : lpfn;
589 }
590 return ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
591}
592
593
594/**
547 * amdgpu_vce_cs_reloc - command submission relocation 595 * amdgpu_vce_cs_reloc - command submission relocation
548 * 596 *
549 * @p: parser context 597 * @p: parser context
@@ -648,12 +696,13 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
648 uint32_t allocated = 0; 696 uint32_t allocated = 0;
649 uint32_t tmp, handle = 0; 697 uint32_t tmp, handle = 0;
650 uint32_t *size = &tmp; 698 uint32_t *size = &tmp;
651 int i, r = 0, idx = 0; 699 unsigned idx;
700 int i, r = 0;
652 701
653 p->job->vm = NULL; 702 p->job->vm = NULL;
654 ib->gpu_addr = amdgpu_sa_bo_gpu_addr(ib->sa_bo); 703 ib->gpu_addr = amdgpu_sa_bo_gpu_addr(ib->sa_bo);
655 704
656 while (idx < ib->length_dw) { 705 for (idx = 0; idx < ib->length_dw;) {
657 uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx); 706 uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx);
658 uint32_t cmd = amdgpu_get_ib_value(p, ib_idx, idx + 1); 707 uint32_t cmd = amdgpu_get_ib_value(p, ib_idx, idx + 1);
659 708
@@ -664,6 +713,54 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
664 } 713 }
665 714
666 switch (cmd) { 715 switch (cmd) {
716 case 0x00000002: /* task info */
717 fb_idx = amdgpu_get_ib_value(p, ib_idx, idx + 6);
718 bs_idx = amdgpu_get_ib_value(p, ib_idx, idx + 7);
719 break;
720
721 case 0x03000001: /* encode */
722 r = amdgpu_vce_validate_bo(p, ib_idx, idx + 10,
723 idx + 9, 0, 0);
724 if (r)
725 goto out;
726
727 r = amdgpu_vce_validate_bo(p, ib_idx, idx + 12,
728 idx + 11, 0, 0);
729 if (r)
730 goto out;
731 break;
732
733 case 0x05000001: /* context buffer */
734 r = amdgpu_vce_validate_bo(p, ib_idx, idx + 3,
735 idx + 2, 0, 0);
736 if (r)
737 goto out;
738 break;
739
740 case 0x05000004: /* video bitstream buffer */
741 tmp = amdgpu_get_ib_value(p, ib_idx, idx + 4);
742 r = amdgpu_vce_validate_bo(p, ib_idx, idx + 3, idx + 2,
743 tmp, bs_idx);
744 if (r)
745 goto out;
746 break;
747
748 case 0x05000005: /* feedback buffer */
749 r = amdgpu_vce_validate_bo(p, ib_idx, idx + 3, idx + 2,
750 4096, fb_idx);
751 if (r)
752 goto out;
753 break;
754 }
755
756 idx += len / 4;
757 }
758
759 for (idx = 0; idx < ib->length_dw;) {
760 uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx);
761 uint32_t cmd = amdgpu_get_ib_value(p, ib_idx, idx + 1);
762
763 switch (cmd) {
667 case 0x00000001: /* session */ 764 case 0x00000001: /* session */
668 handle = amdgpu_get_ib_value(p, ib_idx, idx + 2); 765 handle = amdgpu_get_ib_value(p, ib_idx, idx + 2);
669 session_idx = amdgpu_vce_validate_handle(p, handle, 766 session_idx = amdgpu_vce_validate_handle(p, handle,