diff options
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/radeon/cik.c | 108 |
1 files changed, 79 insertions, 29 deletions
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 8ac82df2efde..2307e218914b 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -8137,6 +8137,78 @@ restart_ih: /* * startup/shutdown callbacks */ +static void cik_uvd_init(struct radeon_device *rdev) +{ + int r; + + if (!rdev->has_uvd) + return; + + r = radeon_uvd_init(rdev); + if (r) { + dev_err(rdev->dev, "failed UVD (%d) init.\n", r); + /* + * At this point rdev->uvd.vcpu_bo is NULL which trickles down + * to early fails cik_uvd_start() and thus nothing happens + * there. So it is pointless to try to go through that code + * hence why we disable uvd here. + */ + rdev->has_uvd = 0; + return; + } + rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL; + r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096); +} + +static void cik_uvd_start(struct radeon_device *rdev) +{ + int r; + + if (!rdev->has_uvd) + return; + + r = radeon_uvd_resume(rdev); + if (r) { + dev_err(rdev->dev, "failed UVD resume (%d).\n", r); + goto error; + } + r = uvd_v4_2_resume(rdev); + if (r) { + dev_err(rdev->dev, "failed UVD 4.2 resume (%d).\n", r); + goto error; + } + r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX); + if (r) { + dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r); + goto error; + } + return; + +error: + rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; +} + +static void cik_uvd_resume(struct radeon_device *rdev) +{ + struct radeon_ring *ring; + int r; + + if (!rdev->has_uvd || !rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size) + return; + + ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, 0, RADEON_CP_PACKET2); + if (r) { + dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r); + return; + } + r = uvd_v1_0_init(rdev); + if (r) { + dev_err(rdev->dev, "failed initializing UVD (%d).\n", r); + return; + } +} + /** * cik_startup - program the asic to a functional state * @@ -8239,18 +8311,7 @@ static int cik_startup(struct radeon_device *rdev) return r; } - r = radeon_uvd_resume(rdev); - if (!r) { - r = uvd_v4_2_resume(rdev); - if (!r) { - r = radeon_fence_driver_start_ring(rdev, - R600_RING_TYPE_UVD_INDEX); - if (r) - dev_err(rdev->dev, "UVD fences init error (%d).\n", r); - } - } - if (r) - rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; + cik_uvd_start(rdev); r = radeon_vce_resume(rdev); if (!r) { @@ -8342,15 +8403,7 @@ static int cik_startup(struct radeon_device *rdev) if (r) return r; - ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; - if (ring->ring_size) { - r = radeon_ring_init(rdev, ring, ring->ring_size, 0, - RADEON_CP_PACKET2); - if (!r) - r = uvd_v1_0_init(rdev); - if (r) - DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); - } + cik_uvd_resume(rdev); r = -ENOENT; @@ -8443,8 +8496,10 @@ int cik_suspend(struct radeon_device *rdev) radeon_vm_manager_fini(rdev); cik_cp_enable(rdev, false); cik_sdma_enable(rdev, false); - uvd_v1_0_fini(rdev); - radeon_uvd_suspend(rdev); + if (rdev->has_uvd) { + uvd_v1_0_fini(rdev); + radeon_uvd_suspend(rdev); + } radeon_vce_suspend(rdev); cik_fini_pg(rdev); cik_fini_cg(rdev); @@ -8571,12 +8626,7 @@ int cik_init(struct radeon_device *rdev) ring->ring_obj = NULL; r600_ring_init(rdev, ring, 256 * 1024); - r = radeon_uvd_init(rdev); - if (!r) { - ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; - ring->ring_obj = NULL; - r600_ring_init(rdev, ring, 4096); - } + cik_uvd_init(rdev); r = radeon_vce_init(rdev); if (!r) { |