aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-12-07 06:28:22 +1000
committerDave Airlie <airlied@redhat.com>2017-12-07 06:28:22 +1000
commit9c606cd4117a3c45e04a6616b1a0dbeb18eeee62 (patch)
treeaa6c1db29e1a3f687c81fa03aecd24992a76e993 /drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
parentc5dd52f653fa74f8f4771425c6db33609ad21258 (diff)
parent3997eea57caf542e9327df9b6bb2882a57c4c421 (diff)
Merge branch 'drm-next-4.16' of git://people.freedesktop.org/~agd5f/linux into drm-next
First feature request for 4.16. Highlights: - RV and Vega header cleanups - TTM operation context support - 48 bit GPUVM fixes for Vega/RV - More smatch fixes - ECC support for vega10 - Resizeable BAR support - Multi-display sync support in DC - SR-IOV fixes - Various scheduler improvements - GPU reset fixes and vram lost tracking - Clean up DC/powerplay interfaces - DCN display fixes - Various DC fixes * 'drm-next-4.16' of git://people.freedesktop.org/~agd5f/linux: (291 commits) drm/radeon: Use drm_fb_helper_lastclose() and _poll_changed() drm/amdgpu: Use drm_fb_helper_lastclose() and _poll_changed() drm/amd/display: Use drm_fb_helper_poll_changed() drm/ttm: swap consecutive allocated pooled pages v4 drm/amdgpu: fix amdgpu_sync_resv v2 drm/ttm: swap consecutive allocated cached pages v3 drm/amd/amdgpu: set gtt size according to system memory size only drm/amdgpu: Get rid of dep_sync as a seperate object. drm/amdgpu: allow specifying vm_block_size for multi level PDs v2 drm/amdgpu: move validation of the VM size into the VM code drm/amdgpu: allow non pot VM size values drm/amdgpu: choose number of VM levels based on VM size drm/amdgpu: unify VM size handling of Vega10 with older generation drm/amdgpu: fix amdgpu_vm_num_entries drm/amdgpu: fix VM PD addr shift drm/amdgpu: correct vce4.0 fw config for SRIOV (V2) drm/amd/display: Don't call dm_log_to_buffer directly in dc_conn_log drm/amd/display: Add dm_logger_append_va API drm/ttm: Use a static string instead of an array of char * drm/amd/display: remove usage of legacy_cursor_update ...
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c108
1 files changed, 103 insertions, 5 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
index 2918de2f39ec..ba6d846b08ff 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
@@ -176,7 +176,7 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size)
ring = &adev->vce.ring[0];
rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_NORMAL];
r = amd_sched_entity_init(&ring->sched, &adev->vce.entity,
- rq, amdgpu_sched_jobs);
+ rq, amdgpu_sched_jobs, NULL);
if (r != 0) {
DRM_ERROR("Failed setting up VCE run queue.\n");
return r;
@@ -544,6 +544,55 @@ err:
}
/**
+ * amdgpu_vce_cs_validate_bo - make sure not to cross 4GB boundary
+ *
+ * @p: parser context
+ * @lo: address of lower dword
+ * @hi: address of higher dword
+ * @size: minimum size
+ * @index: bs/fb index
+ *
+ * Make sure that no BO cross a 4GB boundary.
+ */
+static int amdgpu_vce_validate_bo(struct amdgpu_cs_parser *p, uint32_t ib_idx,
+ int lo, int hi, unsigned size, int32_t index)
+{
+ int64_t offset = ((uint64_t)size) * ((int64_t)index);
+ struct ttm_operation_ctx ctx = { false, false };
+ struct amdgpu_bo_va_mapping *mapping;
+ unsigned i, fpfn, lpfn;
+ struct amdgpu_bo *bo;
+ uint64_t addr;
+ int r;
+
+ addr = ((uint64_t)amdgpu_get_ib_value(p, ib_idx, lo)) |
+ ((uint64_t)amdgpu_get_ib_value(p, ib_idx, hi)) << 32;
+ if (index >= 0) {
+ addr += offset;
+ fpfn = PAGE_ALIGN(offset) >> PAGE_SHIFT;
+ lpfn = 0x100000000ULL >> PAGE_SHIFT;
+ } else {
+ fpfn = 0;
+ lpfn = (0x100000000ULL - PAGE_ALIGN(offset)) >> PAGE_SHIFT;
+ }
+
+ r = amdgpu_cs_find_mapping(p, addr, &bo, &mapping);
+ if (r) {
+ DRM_ERROR("Can't find BO for addr 0x%010Lx %d %d %d %d\n",
+ addr, lo, hi, size, index);
+ return r;
+ }
+
+ for (i = 0; i < bo->placement.num_placement; ++i) {
+ bo->placements[i].fpfn = max(bo->placements[i].fpfn, fpfn);
+ bo->placements[i].lpfn = bo->placements[i].fpfn ?
+ min(bo->placements[i].fpfn, lpfn) : lpfn;
+ }
+ return ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
+}
+
+
+/**
* amdgpu_vce_cs_reloc - command submission relocation
*
* @p: parser context
@@ -648,12 +697,13 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
uint32_t allocated = 0;
uint32_t tmp, handle = 0;
uint32_t *size = &tmp;
- int i, r = 0, idx = 0;
+ unsigned idx;
+ int i, r = 0;
p->job->vm = NULL;
ib->gpu_addr = amdgpu_sa_bo_gpu_addr(ib->sa_bo);
- while (idx < ib->length_dw) {
+ for (idx = 0; idx < ib->length_dw;) {
uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx);
uint32_t cmd = amdgpu_get_ib_value(p, ib_idx, idx + 1);
@@ -664,6 +714,54 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
}
switch (cmd) {
+ case 0x00000002: /* task info */
+ fb_idx = amdgpu_get_ib_value(p, ib_idx, idx + 6);
+ bs_idx = amdgpu_get_ib_value(p, ib_idx, idx + 7);
+ break;
+
+ case 0x03000001: /* encode */
+ r = amdgpu_vce_validate_bo(p, ib_idx, idx + 10,
+ idx + 9, 0, 0);
+ if (r)
+ goto out;
+
+ r = amdgpu_vce_validate_bo(p, ib_idx, idx + 12,
+ idx + 11, 0, 0);
+ if (r)
+ goto out;
+ break;
+
+ case 0x05000001: /* context buffer */
+ r = amdgpu_vce_validate_bo(p, ib_idx, idx + 3,
+ idx + 2, 0, 0);
+ if (r)
+ goto out;
+ break;
+
+ case 0x05000004: /* video bitstream buffer */
+ tmp = amdgpu_get_ib_value(p, ib_idx, idx + 4);
+ r = amdgpu_vce_validate_bo(p, ib_idx, idx + 3, idx + 2,
+ tmp, bs_idx);
+ if (r)
+ goto out;
+ break;
+
+ case 0x05000005: /* feedback buffer */
+ r = amdgpu_vce_validate_bo(p, ib_idx, idx + 3, idx + 2,
+ 4096, fb_idx);
+ if (r)
+ goto out;
+ break;
+ }
+
+ idx += len / 4;
+ }
+
+ for (idx = 0; idx < ib->length_dw;) {
+ uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx);
+ uint32_t cmd = amdgpu_get_ib_value(p, ib_idx, idx + 1);
+
+ switch (cmd) {
case 0x00000001: /* session */
handle = amdgpu_get_ib_value(p, ib_idx, idx + 2);
session_idx = amdgpu_vce_validate_handle(p, handle,
@@ -954,7 +1052,7 @@ int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring)
}
if (i < timeout) {
- DRM_INFO("ring test on %d succeeded in %d usecs\n",
+ DRM_DEBUG("ring test on %d succeeded in %d usecs\n",
ring->idx, i);
} else {
DRM_ERROR("amdgpu: ring %d test failed\n",
@@ -999,7 +1097,7 @@ int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring, long timeout)
} else if (r < 0) {
DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r);
} else {
- DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
+ DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx);
r = 0;
}
error: