diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/radeon/ni.c | 139 |
1 files changed, 91 insertions, 48 deletions
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 38c39473ebd3..ec0aac8d455f 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -2069,6 +2069,93 @@ static void cayman_uvd_resume(struct radeon_device *rdev) } } +static void cayman_vce_init(struct radeon_device *rdev) +{ + int r; + + /* Only set for CHIP_ARUBA */ + if (!rdev->has_vce) + return; + + r = radeon_vce_init(rdev); + if (r) { + dev_err(rdev->dev, "failed VCE (%d) init.\n", r); + /* + * At this point rdev->vce.vcpu_bo is NULL which trickles down + * to early fails cayman_vce_start() and thus nothing happens + * there. So it is pointless to try to go through that code + * hence why we disable vce here. + */ + rdev->has_vce = 0; + return; + } + rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_obj = NULL; + r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE1_INDEX], 4096); + rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_obj = NULL; + r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE2_INDEX], 4096); +} + +static void cayman_vce_start(struct radeon_device *rdev) +{ + int r; + + if (!rdev->has_vce) + return; + + r = radeon_vce_resume(rdev); + if (r) { + dev_err(rdev->dev, "failed VCE resume (%d).\n", r); + goto error; + } + r = vce_v1_0_resume(rdev); + if (r) { + dev_err(rdev->dev, "failed VCE resume (%d).\n", r); + goto error; + } + r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE1_INDEX); + if (r) { + dev_err(rdev->dev, "failed initializing VCE1 fences (%d).\n", r); + goto error; + } + r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE2_INDEX); + if (r) { + dev_err(rdev->dev, "failed initializing VCE2 fences (%d).\n", r); + goto error; + } + return; + +error: + rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0; + rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0; +} + +static void cayman_vce_resume(struct radeon_device *rdev) +{ + struct radeon_ring *ring; + int r; + + if (!rdev->has_vce || !rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size) + return; + + ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0); + if (r) { + dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r); + return; + } + ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0); + if (r) { + dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r); + return; + } + r = vce_v1_0_init(rdev); + if (r) { + dev_err(rdev->dev, "failed initializing VCE (%d).\n", r); + return; + } +} + static int cayman_startup(struct radeon_device *rdev) { struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; @@ -2124,25 +2211,7 @@ static int cayman_startup(struct radeon_device *rdev) } cayman_uvd_start(rdev); - - if (rdev->family == CHIP_ARUBA) { - r = radeon_vce_resume(rdev); - if (!r) - r = vce_v1_0_resume(rdev); - - if (!r) - r = radeon_fence_driver_start_ring(rdev, - TN_RING_TYPE_VCE1_INDEX); - if (!r) - r = radeon_fence_driver_start_ring(rdev, - TN_RING_TYPE_VCE2_INDEX); - - if (r) { - dev_err(rdev->dev, "VCE init error (%d).\n", r); - rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0; - rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0; - } - } + cayman_vce_start(rdev); r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX); if (r) { @@ -2212,21 +2281,7 @@ static int cayman_startup(struct radeon_device *rdev) return r; cayman_uvd_resume(rdev); - - if (rdev->family == CHIP_ARUBA) { - ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; - if (ring->ring_size) - r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0); - - ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; - if (ring->ring_size) - r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0); - - if (!r) - r = vce_v1_0_init(rdev); - if (r) - DRM_ERROR("radeon: failed initializing VCE (%d).\n", r); - } + cayman_vce_resume(rdev); r = radeon_ib_pool_init(rdev); if (r) { @@ -2379,19 +2434,7 @@ int cayman_init(struct radeon_device *rdev) r600_ring_init(rdev, ring, 64 * 1024); cayman_uvd_init(rdev); - - if (rdev->family == CHIP_ARUBA) { - r = radeon_vce_init(rdev); - if (!r) { - ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; - ring->ring_obj = NULL; - r600_ring_init(rdev, ring, 4096); - - ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; - ring->ring_obj = NULL; - r600_ring_init(rdev, ring, 4096); - } - } + cayman_vce_init(rdev); rdev->ih.ring_obj = NULL; r600_ih_ring_init(rdev, 64 * 1024); @@ -2446,7 +2489,7 @@ void cayman_fini(struct radeon_device *rdev) radeon_irq_kms_fini(rdev); uvd_v1_0_fini(rdev); radeon_uvd_fini(rdev); - if (rdev->family == CHIP_ARUBA) + if (rdev->has_vce) radeon_vce_fini(rdev); cayman_pcie_gart_fini(rdev); r600_vram_scratch_fini(rdev); |