All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Jérôme Glisse" <jglisse@redhat.com>
To: dri-devel@lists.freedesktop.org
Cc: "Alex Deucher" <alexander.deucher@amd.com>,
	"Jérome Glisse" <jglisse@redhat.com>,
	"Christian König" <christian.koenig@amd.com>
Subject: [PATCH 3/4] drm/radeon: consolidate uvd/vce initialization, resume and suspend.
Date: Wed, 16 Mar 2016 13:48:50 +0100	[thread overview]
Message-ID: <1458132531-5524-1-git-send-email-jglisse@redhat.com> (raw)

From: Jérome Glisse <jglisse@redhat.com>

This consolidate uvd/vce into a common shape for all generation. It
also leverage the rdev->has_uvd flags to know what it is useless to
try to resume/suspend uvd/vce block.

There is no functional changes when there is no error. On error the
device driver will behave differently than before after this patch.
It should now safely ignore uvd/vce errors and keeps normal operation
of others engine. This is an improvement over current situation where
we have different behavior depending on GPU generation and on what
fails.

Finaly this is a preparatory step for a patch which allow to disable
uvd/vce as a driver option.

This have only been tested on southern island so please test it on
other generations (i do not have hardware handy for now).

Signed-off-by: Jérôme Glisse <jglisse@redhat.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/radeon/cik.c       | 226 ++++++++++++++++++++++------------
 drivers/gpu/drm/radeon/evergreen.c | 122 ++++++++++++++-----
 drivers/gpu/drm/radeon/ni.c        | 240 +++++++++++++++++++++++++------------
 drivers/gpu/drm/radeon/r600.c      | 113 ++++++++++++-----
 drivers/gpu/drm/radeon/rv770.c     | 122 ++++++++++++++-----
 drivers/gpu/drm/radeon/si.c        | 213 ++++++++++++++++++++------------
 drivers/gpu/drm/radeon/uvd_v4_2.c  |   5 +
 7 files changed, 724 insertions(+), 317 deletions(-)

diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index f2a4c0f..489e202 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -8496,6 +8496,142 @@ restart_ih:
 /*
  * startup/shutdown callbacks
  */
+
+static void cik_uvd_vce_init(struct radeon_device *rdev)
+{
+	struct radeon_ring *ring;
+	int r;
+
+	if (!rdev->has_uvd)
+		return;
+
+	r = radeon_uvd_init(rdev);
+	if (r)
+		goto error_uvd;
+	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
+	ring->ring_obj = NULL;
+	r600_ring_init(rdev, ring, 4096);
+
+	r = radeon_vce_init(rdev);
+	if (r)
+		goto error_vce;
+	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);
+
+	return;
+
+error_vce:
+	radeon_uvd_fini(rdev);
+error_uvd:
+	dev_err(rdev->dev, "UVD/VCE init error (%d).\n", r);
+	/* On error just disable everything. */
+	rdev->has_uvd = 0;
+}
+
+static void cik_uvd_vce_startup(struct radeon_device *rdev)
+{
+	int r;
+
+	if (!rdev->has_uvd)
+		return;
+
+	r = uvd_v4_2_resume(rdev);
+	if (r)
+		goto error;
+	r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX);
+	if (r)
+		goto error_uvd;
+
+	r = radeon_vce_resume(rdev);
+	if (r)
+		goto error_uvd;
+	r = vce_v2_0_resume(rdev);
+	if (r)
+		goto error_vce;
+	r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE1_INDEX);
+	if (r)
+		goto error_vce;
+	r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE2_INDEX);
+	if (r)
+		goto error_vce;
+
+	return;
+
+error_vce:
+	radeon_vce_suspend(rdev);
+error_uvd:
+	radeon_uvd_suspend(rdev);
+error:
+	dev_err(rdev->dev, "UVD/VCE startup error (%d).\n", r);
+	/* On error just disable everything. */
+	radeon_vce_fini(rdev);
+	radeon_uvd_fini(rdev);
+	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
+	rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0;
+	rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0;
+	rdev->has_uvd = 0;
+}
+
+static void cik_uvd_vce_resume(struct radeon_device *rdev)
+{
+	struct radeon_ring *ring;
+	int r;
+
+	if (!rdev->has_uvd)
+		return;
+
+	/* On uvd/vce error we disable uvd/vce so we should have bail above. */
+	BUG_ON(!rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size);
+	BUG_ON(!rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size);
+	BUG_ON(!rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size);
+
+	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
+	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, RADEON_CP_PACKET2);
+	if (r)
+		goto error;
+	r = uvd_v1_0_init(rdev);
+	if (r)
+		goto error_uvd;
+
+	ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
+	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, VCE_CMD_NO_OP);
+	if (r)
+		goto error_vce1;
+	ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
+	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, VCE_CMD_NO_OP);
+	if (r)
+		goto error_vce2;
+	r = vce_v1_0_init(rdev);
+	if (r)
+		goto error_vce;
+
+	return;
+
+error_vce:
+	radeon_ring_fini(rdev, &rdev->ring[TN_RING_TYPE_VCE2_INDEX]);
+error_vce2:
+	radeon_ring_fini(rdev, &rdev->ring[TN_RING_TYPE_VCE1_INDEX]);
+error_vce1:
+	uvd_v1_0_fini(rdev);
+error_uvd:
+	radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX]);
+error:
+	dev_err(rdev->dev, "UVD/VCE resume error (%d).\n", r);
+	/* On error just disable everything. */
+	radeon_uvd_suspend(rdev);
+	radeon_vce_suspend(rdev);
+	radeon_uvd_fini(rdev);
+	radeon_vce_fini(rdev);
+	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
+	rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0;
+	rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0;
+	rdev->has_uvd = 0;
+}
+
 /**
  * cik_startup - program the asic to a functional state
  *
@@ -8598,34 +8734,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;
-
-	r = radeon_vce_resume(rdev);
-	if (!r) {
-		r = vce_v2_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;
-	}
+	cik_uvd_vce_startup(rdev);
 
 	/* Enable IRQ */
 	if (!rdev->irq.installed) {
@@ -8701,32 +8810,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);
-	}
-
-	r = -ENOENT;
-
-	ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
-	if (ring->ring_size)
-		r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
-				     VCE_CMD_NO_OP);
-
-	ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
-	if (ring->ring_size)
-		r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
-				     VCE_CMD_NO_OP);
-
-	if (!r)
-		r = vce_v1_0_init(rdev);
-	else if (r != -ENOENT)
-		DRM_ERROR("radeon: failed initializing VCE (%d).\n", r);
+	cik_uvd_vce_resume(rdev);
 
 	r = radeon_ib_pool_init(rdev);
 	if (r) {
@@ -8802,9 +8886,11 @@ 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);
-	radeon_vce_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);
 	cik_irq_suspend(rdev);
@@ -8930,23 +9016,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);
-	}
-
-	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);
-	}
+	cik_uvd_vce_init(rdev);
 
 	rdev->ih.ring_obj = NULL;
 	r600_ih_ring_init(rdev, 64 * 1024);
@@ -9007,9 +9077,11 @@ void cik_fini(struct radeon_device *rdev)
 	radeon_vm_manager_fini(rdev);
 	radeon_ib_pool_fini(rdev);
 	radeon_irq_kms_fini(rdev);
-	uvd_v1_0_fini(rdev);
-	radeon_uvd_fini(rdev);
-	radeon_vce_fini(rdev);
+	if (rdev->has_uvd) {
+		uvd_v1_0_fini(rdev);
+		radeon_uvd_fini(rdev);
+		radeon_vce_fini(rdev);
+	}
 	cik_pcie_gart_fini(rdev);
 	r600_vram_scratch_fini(rdev);
 	radeon_gem_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 76c4bdf..22854de 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -5363,6 +5363,87 @@ restart_ih:
 	return IRQ_HANDLED;
 }
 
+static void evergreen_uvd_init(struct radeon_device *rdev)
+{
+	struct radeon_ring *ring;
+	int r;
+
+	if (!rdev->has_uvd)
+		return;
+
+	r = radeon_uvd_init(rdev);
+	if (r)
+		goto error_uvd;
+	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
+	ring->ring_obj = NULL;
+	r600_ring_init(rdev, ring, 4096);
+
+	return;
+
+error_uvd:
+	dev_err(rdev->dev, "UVD init error (%d).\n", r);
+	/* On error just disable everything. */
+	rdev->has_uvd = 0;
+}
+
+static void evergreen_uvd_startup(struct radeon_device *rdev)
+{
+	int r;
+
+	if (!rdev->has_uvd)
+		return;
+
+	r = uvd_v2_2_resume(rdev);
+	if (r)
+		goto error;
+	r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX);
+	if (r)
+		goto error_uvd;
+
+	return;
+
+error_uvd:
+	radeon_uvd_suspend(rdev);
+error:
+	dev_err(rdev->dev, "UVD startup error (%d).\n", r);
+	/* On error just disable everything. */
+	radeon_uvd_fini(rdev);
+	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
+	rdev->has_uvd = 0;
+}
+
+static void evergreen_uvd_resume(struct radeon_device *rdev)
+{
+	struct radeon_ring *ring;
+	int r;
+
+	if (!rdev->has_uvd)
+		return;
+
+	/* On uvd error we disable uvd so we should have bail above. */
+	BUG_ON(!rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size);
+
+	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
+	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, RADEON_CP_PACKET2);
+	if (r)
+		goto error;
+	r = uvd_v1_0_init(rdev);
+	if (r)
+		goto error_uvd;
+
+	return;
+
+error_uvd:
+	radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX]);
+error:
+	dev_err(rdev->dev, "UVD resume error (%d).\n", r);
+	/* On error just disable everything. */
+	radeon_uvd_suspend(rdev);
+	radeon_uvd_fini(rdev);
+	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
+	rdev->has_uvd = 0;
+}
+
 static int evergreen_startup(struct radeon_device *rdev)
 {
 	struct radeon_ring *ring;
@@ -5427,16 +5508,7 @@ static int evergreen_startup(struct radeon_device *rdev)
 		return r;
 	}
 
-	r = uvd_v2_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;
+	evergreen_uvd_startup(rdev);
 
 	/* Enable IRQ */
 	if (!rdev->irq.installed) {
@@ -5475,16 +5547,7 @@ static int evergreen_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: error initializing UVD (%d).\n", r);
-	}
+	evergreen_uvd_resume(rdev);
 
 	r = radeon_ib_pool_init(rdev);
 	if (r) {
@@ -5539,8 +5602,10 @@ int evergreen_suspend(struct radeon_device *rdev)
 {
 	radeon_pm_suspend(rdev);
 	radeon_audio_fini(rdev);
-	uvd_v1_0_fini(rdev);
-	radeon_uvd_suspend(rdev);
+	if (rdev->has_uvd) {
+		uvd_v1_0_fini(rdev);
+		radeon_uvd_suspend(rdev);
+	}
 	r700_cp_stop(rdev);
 	r600_dma_stop(rdev);
 	evergreen_irq_suspend(rdev);
@@ -5641,12 +5706,7 @@ int evergreen_init(struct radeon_device *rdev)
 	rdev->ring[R600_RING_TYPE_DMA_INDEX].ring_obj = NULL;
 	r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX], 64 * 1024);
 
-	r = radeon_uvd_init(rdev);
-	if (!r) {
-		rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL;
-		r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX],
-			       4096);
-	}
+	evergreen_uvd_init(rdev);
 
 	rdev->ih.ring_obj = NULL;
 	r600_ih_ring_init(rdev, 64 * 1024);
@@ -5697,8 +5757,10 @@ void evergreen_fini(struct radeon_device *rdev)
 	radeon_wb_fini(rdev);
 	radeon_ib_pool_fini(rdev);
 	radeon_irq_kms_fini(rdev);
-	uvd_v1_0_fini(rdev);
-	radeon_uvd_fini(rdev);
+	if (rdev->has_uvd) {
+		uvd_v1_0_fini(rdev);
+		radeon_uvd_fini(rdev);
+	}
 	evergreen_pcie_gart_fini(rdev);
 	r600_vram_scratch_fini(rdev);
 	radeon_gem_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index b88d63c9..74f7316 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -2002,6 +2002,154 @@ bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
 	return radeon_ring_test_lockup(rdev, ring);
 }
 
+static void cayman_uvd_vce_init(struct radeon_device *rdev)
+{
+	struct radeon_ring *ring;
+	int r;
+
+	if (!rdev->has_uvd)
+		return;
+
+	r = radeon_uvd_init(rdev);
+	if (r)
+		goto error_uvd;
+	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
+	ring->ring_obj = NULL;
+	r600_ring_init(rdev, ring, 4096);
+
+	if (rdev->family != CHIP_ARUBA)
+		return;
+
+	r = radeon_vce_init(rdev);
+	if (r)
+		goto error_vce;
+	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);
+
+	return;
+
+error_vce:
+	radeon_uvd_fini(rdev);
+error_uvd:
+	dev_err(rdev->dev, "UVD/VCE init error (%d).\n", r);
+	/* On error just disable everything. */
+	rdev->has_uvd = 0;
+}
+
+static void cayman_uvd_vce_startup(struct radeon_device *rdev)
+{
+	int r;
+
+	if (!rdev->has_uvd)
+		return;
+
+	r = uvd_v2_2_resume(rdev);
+	if (r)
+		goto error;
+	r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX);
+	if (r)
+		goto error_uvd;
+
+	/* VCE only CHIP_ARUBA */
+	if (rdev->family != CHIP_ARUBA)
+		return;
+	r = radeon_vce_resume(rdev);
+	if (r)
+		goto error_uvd;
+	r = vce_v1_0_resume(rdev);
+	if (r)
+		goto error_vce;
+	r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE1_INDEX);
+	if (r)
+		goto error_vce;
+	r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE2_INDEX);
+	if (r)
+		goto error_vce;
+
+	return;
+
+error_vce:
+	radeon_vce_suspend(rdev);
+error_uvd:
+	radeon_uvd_suspend(rdev);
+error:
+	dev_err(rdev->dev, "UVD/VCE startup error (%d).\n", r);
+	/* On error just disable everything. */
+	radeon_uvd_fini(rdev);
+	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
+	if (rdev->family == CHIP_ARUBA) {
+		radeon_vce_fini(rdev);
+		rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0;
+		rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0;
+	}
+	rdev->has_uvd = 0;
+}
+
+static void cayman_uvd_vce_resume(struct radeon_device *rdev)
+{
+	struct radeon_ring *ring;
+	int r;
+
+	if (!rdev->has_uvd)
+		return;
+
+	/* On uvd/vce error we disable uvd/vce so we should have bail above. */
+	BUG_ON(!rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size);
+
+	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
+	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, RADEON_CP_PACKET2);
+	if (r)
+		goto error;
+	r = uvd_v1_0_init(rdev);
+	if (r)
+		goto error_uvd;
+
+	/* VCE only CHIP_ARUBA */
+	if (rdev->family != CHIP_ARUBA)
+		return;
+	BUG_ON(!rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size);
+	BUG_ON(!rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size);
+	ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
+	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0);
+	if (r)
+		goto error_vce1;
+	ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
+	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0);
+	if (r)
+		goto error_vce2;
+	r = vce_v1_0_init(rdev);
+	if (r)
+		goto error_vce;
+
+	return;
+
+error_vce:
+	radeon_ring_fini(rdev, &rdev->ring[TN_RING_TYPE_VCE2_INDEX]);
+error_vce2:
+	radeon_ring_fini(rdev, &rdev->ring[TN_RING_TYPE_VCE1_INDEX]);
+error_vce1:
+	uvd_v1_0_fini(rdev);
+	radeon_vce_suspend(rdev);
+error_uvd:
+	radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX]);
+error:
+	dev_err(rdev->dev, "UVD/VCE resume error (%d).\n", r);
+	/* On error just disable everything. */
+	radeon_uvd_suspend(rdev);
+	radeon_uvd_fini(rdev);
+	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
+	if (rdev->family == CHIP_ARUBA) {
+		radeon_vce_fini(rdev);
+		rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0;
+		rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0;
+	}
+	rdev->has_uvd = 0;
+}
+
 static int cayman_startup(struct radeon_device *rdev)
 {
 	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
@@ -2056,34 +2204,7 @@ static int cayman_startup(struct radeon_device *rdev)
 		return r;
 	}
 
-	r = uvd_v2_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;
-
-	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_uvd_vce_startup(rdev);
 
 	r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
 	if (r) {
@@ -2152,30 +2273,7 @@ static int cayman_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);
-	}
-
-	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_uvd_vce_resume(rdev);
 
 	r = radeon_ib_pool_init(rdev);
 	if (r) {
@@ -2230,8 +2328,12 @@ int cayman_suspend(struct radeon_device *rdev)
 	radeon_vm_manager_fini(rdev);
 	cayman_cp_enable(rdev, false);
 	cayman_dma_stop(rdev);
-	uvd_v1_0_fini(rdev);
-	radeon_uvd_suspend(rdev);
+	if (rdev->has_uvd) {
+		uvd_v1_0_fini(rdev);
+		radeon_uvd_suspend(rdev);
+		if (rdev->family == CHIP_ARUBA)
+			radeon_vce_suspend(rdev);
+	}
 	evergreen_irq_suspend(rdev);
 	radeon_wb_disable(rdev);
 	cayman_pcie_gart_disable(rdev);
@@ -2325,25 +2427,7 @@ int cayman_init(struct radeon_device *rdev)
 	ring->ring_obj = NULL;
 	r600_ring_init(rdev, ring, 64 * 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);
-	}
-
-	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_uvd_vce_init(rdev);
 
 	rdev->ih.ring_obj = NULL;
 	r600_ih_ring_init(rdev, 64 * 1024);
@@ -2396,10 +2480,12 @@ void cayman_fini(struct radeon_device *rdev)
 	radeon_vm_manager_fini(rdev);
 	radeon_ib_pool_fini(rdev);
 	radeon_irq_kms_fini(rdev);
-	uvd_v1_0_fini(rdev);
-	radeon_uvd_fini(rdev);
-	if (rdev->family == CHIP_ARUBA)
-		radeon_vce_fini(rdev);
+	if (rdev->has_uvd) {
+		uvd_v1_0_fini(rdev);
+		radeon_uvd_fini(rdev);
+		if (rdev->family == CHIP_ARUBA)
+			radeon_vce_fini(rdev);
+	}
 	cayman_pcie_gart_fini(rdev);
 	r600_vram_scratch_fini(rdev);
 	radeon_gem_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index f86ab69..9d95bee 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -3035,6 +3035,87 @@ void r600_clear_surface_reg(struct radeon_device *rdev, int reg)
 	/* FIXME: implement */
 }
 
+static void r600_uvd_init(struct radeon_device *rdev)
+{
+	struct radeon_ring *ring;
+	int r;
+
+	if (!rdev->has_uvd)
+		return;
+
+	r = radeon_uvd_init(rdev);
+	if (r)
+		goto error_uvd;
+	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
+	ring->ring_obj = NULL;
+	r600_ring_init(rdev, ring, 4096);
+
+	return;
+
+error_uvd:
+	dev_err(rdev->dev, "UVD init error (%d).\n", r);
+	/* On error just disable everything. */
+	rdev->has_uvd = 0;
+}
+
+static void r600_uvd_startup(struct radeon_device *rdev)
+{
+	int r;
+
+	if (!rdev->has_uvd)
+		return;
+
+	r = uvd_v1_0_resume(rdev);
+	if (r)
+		goto error;
+	r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX);
+	if (r)
+		goto error_uvd;
+
+	return;
+
+error_uvd:
+	radeon_uvd_suspend(rdev);
+error:
+	dev_err(rdev->dev, "UVD startup error (%d).\n", r);
+	/* On error just disable everything. */
+	radeon_uvd_fini(rdev);
+	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
+	rdev->has_uvd = 0;
+}
+
+static void r600_uvd_resume(struct radeon_device *rdev)
+{
+	struct radeon_ring *ring;
+	int r;
+
+	if (!rdev->has_uvd)
+		return;
+
+	/* On uvd error we disable uvd so we should have bail above. */
+	BUG_ON(!rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size);
+
+	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
+	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, RADEON_CP_PACKET2);
+	if (r)
+		goto error;
+	r = uvd_v1_0_init(rdev);
+	if (r)
+		goto error_uvd;
+
+	return;
+
+error_uvd:
+	radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX]);
+error:
+	dev_err(rdev->dev, "UVD resume error (%d).\n", r);
+	/* On error just disable everything. */
+	radeon_uvd_suspend(rdev);
+	radeon_uvd_fini(rdev);
+	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
+	rdev->has_uvd = 0;
+}
+
 static int r600_startup(struct radeon_device *rdev)
 {
 	struct radeon_ring *ring;
@@ -3070,17 +3151,7 @@ static int r600_startup(struct radeon_device *rdev)
 		return r;
 	}
 
-	if (rdev->has_uvd) {
-		r = uvd_v1_0_resume(rdev);
-		if (!r) {
-			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);
-			}
-		}
-		if (r)
-			rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
-	}
+	r600_uvd_startup(rdev);
 
 	/* Enable IRQ */
 	if (!rdev->irq.installed) {
@@ -3110,17 +3181,7 @@ static int r600_startup(struct radeon_device *rdev)
 	if (r)
 		return r;
 
-	if (rdev->has_uvd) {
-		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);
-		}
-	}
+	r600_uvd_resume(rdev);
 
 	r = radeon_ib_pool_init(rdev);
 	if (r) {
@@ -3264,13 +3325,7 @@ int r600_init(struct radeon_device *rdev)
 	rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
 	r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
 
-	if (rdev->has_uvd) {
-		r = radeon_uvd_init(rdev);
-		if (!r) {
-			rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL;
-			r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096);
-		}
-	}
+	r600_uvd_init(rdev);
 
 	rdev->ih.ring_obj = NULL;
 	r600_ih_ring_init(rdev, 64 * 1024);
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 01ee96a..cf6e2ee 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -1681,6 +1681,87 @@ static int rv770_mc_init(struct radeon_device *rdev)
 	return 0;
 }
 
+static void rv770_uvd_init(struct radeon_device *rdev)
+{
+	struct radeon_ring *ring;
+	int r;
+
+	if (!rdev->has_uvd)
+		return;
+
+	r = radeon_uvd_init(rdev);
+	if (r)
+		goto error_uvd;
+	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
+	ring->ring_obj = NULL;
+	r600_ring_init(rdev, ring, 4096);
+
+	return;
+
+error_uvd:
+	dev_err(rdev->dev, "UVD init error (%d).\n", r);
+	/* On error just disable everything. */
+	rdev->has_uvd = 0;
+}
+
+static void rv770_uvd_startup(struct radeon_device *rdev)
+{
+	int r;
+
+	if (!rdev->has_uvd)
+		return;
+
+	r = uvd_v2_2_resume(rdev);
+	if (r)
+		goto error;
+	r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX);
+	if (r)
+		goto error_uvd;
+
+	return;
+
+error_uvd:
+	radeon_uvd_suspend(rdev);
+error:
+	dev_err(rdev->dev, "UVD startup error (%d).\n", r);
+	/* On error just disable everything. */
+	radeon_uvd_fini(rdev);
+	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
+	rdev->has_uvd = 0;
+}
+
+static void rv770_uvd_resume(struct radeon_device *rdev)
+{
+	struct radeon_ring *ring;
+	int r;
+
+	if (!rdev->has_uvd)
+		return;
+
+	/* On uvd error we disable uvd so we should have bail above. */
+	BUG_ON(!rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size);
+
+	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
+	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, RADEON_CP_PACKET2);
+	if (r)
+		goto error;
+	r = uvd_v1_0_init(rdev);
+	if (r)
+		goto error_uvd;
+
+	return;
+
+error_uvd:
+	radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX]);
+error:
+	dev_err(rdev->dev, "UVD resume error (%d).\n", r);
+	/* On error just disable everything. */
+	radeon_uvd_suspend(rdev);
+	radeon_uvd_fini(rdev);
+	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
+	rdev->has_uvd = 0;
+}
+
 static int rv770_startup(struct radeon_device *rdev)
 {
 	struct radeon_ring *ring;
@@ -1723,16 +1804,7 @@ static int rv770_startup(struct radeon_device *rdev)
 		return r;
 	}
 
-	r = uvd_v2_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;
+	rv770_uvd_startup(rdev);
 
 	/* Enable IRQ */
 	if (!rdev->irq.installed) {
@@ -1772,16 +1844,7 @@ static int rv770_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);
-	}
+	rv770_uvd_resume(rdev);
 
 	r = radeon_ib_pool_init(rdev);
 	if (r) {
@@ -1831,8 +1894,10 @@ int rv770_suspend(struct radeon_device *rdev)
 {
 	radeon_pm_suspend(rdev);
 	radeon_audio_fini(rdev);
-	uvd_v1_0_fini(rdev);
-	radeon_uvd_suspend(rdev);
+	if (rdev->has_uvd) {
+		uvd_v1_0_fini(rdev);
+		radeon_uvd_suspend(rdev);
+	}
 	r700_cp_stop(rdev);
 	r600_dma_stop(rdev);
 	r600_irq_suspend(rdev);
@@ -1917,12 +1982,7 @@ int rv770_init(struct radeon_device *rdev)
 	rdev->ring[R600_RING_TYPE_DMA_INDEX].ring_obj = NULL;
 	r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX], 64 * 1024);
 
-	r = radeon_uvd_init(rdev);
-	if (!r) {
-		rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL;
-		r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX],
-			       4096);
-	}
+	rv770_uvd_init(rdev);
 
 	rdev->ih.ring_obj = NULL;
 	r600_ih_ring_init(rdev, 64 * 1024);
@@ -1957,8 +2017,10 @@ void rv770_fini(struct radeon_device *rdev)
 	radeon_wb_fini(rdev);
 	radeon_ib_pool_fini(rdev);
 	radeon_irq_kms_fini(rdev);
-	uvd_v1_0_fini(rdev);
-	radeon_uvd_fini(rdev);
+	if (rdev->has_uvd) {
+		uvd_v1_0_fini(rdev);
+		radeon_uvd_fini(rdev);
+	}
 	rv770_pcie_gart_fini(rdev);
 	r600_vram_scratch_fini(rdev);
 	radeon_gem_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index e894be2..7d8d5f5 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -6868,6 +6868,142 @@ restart_ih:
 /*
  * startup/shutdown callbacks
  */
+
+static void si_uvd_vce_init(struct radeon_device *rdev)
+{
+	struct radeon_ring *ring;
+	int r;
+
+	if (!rdev->has_uvd)
+		return;
+
+	r = radeon_uvd_init(rdev);
+	if (r)
+		goto error_uvd;
+	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
+	ring->ring_obj = NULL;
+	r600_ring_init(rdev, ring, 4096);
+
+	r = radeon_vce_init(rdev);
+	if (r)
+		goto error_vce;
+	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);
+
+	return;
+
+error_vce:
+	radeon_uvd_fini(rdev);
+error_uvd:
+	dev_err(rdev->dev, "UVD/VCE init error (%d).\n", r);
+	/* On error just disable everything. */
+	rdev->has_uvd = 0;
+}
+
+static void si_uvd_vce_startup(struct radeon_device *rdev)
+{
+	int r;
+
+	if (!rdev->has_uvd)
+		return;
+
+	r = uvd_v2_2_resume(rdev);
+	if (r)
+		goto error;
+	r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX);
+	if (r)
+		goto error_uvd;
+
+	r = radeon_vce_resume(rdev);
+	if (r)
+		goto error_uvd;
+	r = vce_v1_0_resume(rdev);
+	if (r)
+		goto error_vce;
+	r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE1_INDEX);
+	if (r)
+		goto error_vce;
+	r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE2_INDEX);
+	if (r)
+		goto error_vce;
+
+	return;
+
+error_vce:
+	radeon_vce_suspend(rdev);
+error_uvd:
+	radeon_uvd_suspend(rdev);
+error:
+	dev_err(rdev->dev, "UVD/VCE startup error (%d).\n", r);
+	/* On error just disable everything. */
+	radeon_vce_fini(rdev);
+	radeon_uvd_fini(rdev);
+	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
+	rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0;
+	rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0;
+	rdev->has_uvd = 0;
+}
+
+static void si_uvd_vce_resume(struct radeon_device *rdev)
+{
+	struct radeon_ring *ring;
+	int r;
+
+	if (!rdev->has_uvd)
+		return;
+
+	/* On uvd/vce error we disable uvd/vce so we should have bail above. */
+	BUG_ON(!rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size);
+	BUG_ON(!rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size);
+	BUG_ON(!rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size);
+
+	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
+	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, RADEON_CP_PACKET2);
+	if (r)
+		goto error;
+	r = uvd_v1_0_init(rdev);
+	if (r)
+		goto error_uvd;
+
+	ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
+	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, VCE_CMD_NO_OP);
+	if (r)
+		goto error_vce1;
+	ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
+	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, VCE_CMD_NO_OP);
+	if (r)
+		goto error_vce2;
+	r = vce_v1_0_init(rdev);
+	if (r)
+		goto error_vce;
+
+	return;
+
+error_vce:
+	radeon_ring_fini(rdev, &rdev->ring[TN_RING_TYPE_VCE2_INDEX]);
+error_vce2:
+	radeon_ring_fini(rdev, &rdev->ring[TN_RING_TYPE_VCE1_INDEX]);
+error_vce1:
+	uvd_v1_0_fini(rdev);
+error_uvd:
+	radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX]);
+error:
+	dev_err(rdev->dev, "UVD/VCE resume error (%d).\n", r);
+	/* On error just disable everything. */
+	radeon_uvd_suspend(rdev);
+	radeon_vce_suspend(rdev);
+	radeon_uvd_fini(rdev);
+	radeon_vce_fini(rdev);
+	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
+	rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0;
+	rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0;
+	rdev->has_uvd = 0;
+}
+
 static int si_startup(struct radeon_device *rdev)
 {
 	struct radeon_ring *ring;
@@ -6946,33 +7082,7 @@ static int si_startup(struct radeon_device *rdev)
 		return r;
 	}
 
-	if (rdev->has_uvd) {
-		r = uvd_v2_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;
-	}
-
-	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;
-	}
+	si_uvd_vce_startup(rdev);
 
 	/* Enable IRQ */
 	if (!rdev->irq.installed) {
@@ -7030,34 +7140,7 @@ static int si_startup(struct radeon_device *rdev)
 	if (r)
 		return r;
 
-	if (rdev->has_uvd) {
-		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);
-		}
-	}
-
-	r = -ENOENT;
-
-	ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
-	if (ring->ring_size)
-		r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
-				     VCE_CMD_NO_OP);
-
-	ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
-	if (ring->ring_size)
-		r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
-				     VCE_CMD_NO_OP);
-
-	if (!r)
-		r = vce_v1_0_init(rdev);
-	else if (r != -ENOENT)
-		DRM_ERROR("radeon: failed initializing VCE (%d).\n", r);
+	si_uvd_vce_resume(rdev);
 
 	r = radeon_ib_pool_init(rdev);
 	if (r) {
@@ -7216,25 +7299,7 @@ int si_init(struct radeon_device *rdev)
 	ring->ring_obj = NULL;
 	r600_ring_init(rdev, ring, 64 * 1024);
 
-	if (rdev->has_uvd) {
-		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);
-		}
-	}
-
-	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);
-	}
+	si_uvd_vce_init(rdev);
 
 	rdev->ih.ring_obj = NULL;
 	r600_ih_ring_init(rdev, 64 * 1024);
diff --git a/drivers/gpu/drm/radeon/uvd_v4_2.c b/drivers/gpu/drm/radeon/uvd_v4_2.c
index d04d507..d7e4807 100644
--- a/drivers/gpu/drm/radeon/uvd_v4_2.c
+++ b/drivers/gpu/drm/radeon/uvd_v4_2.c
@@ -39,6 +39,11 @@ int uvd_v4_2_resume(struct radeon_device *rdev)
 {
 	uint64_t addr;
 	uint32_t size;
+	int r;
+
+	r = radeon_uvd_resume(rdev);
+	if (r)
+		return r;
 
 	/* programm the VCPU memory controller bits 0-27 */
 	addr = rdev->uvd.gpu_addr >> 3;
-- 
1.8.3.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

             reply	other threads:[~2016-03-16 12:49 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-16 12:48 Jérôme Glisse [this message]
2016-03-16 13:03 ` [PATCH 3/4] drm/radeon: consolidate uvd/vce initialization, resume and suspend Christian König
2016-03-16 14:59   ` Jerome Glisse
2016-03-16 15:19     ` Christian König
2016-03-16 15:56       ` Jerome Glisse
2016-03-16 17:06         ` Christian König
2016-03-16 17:43           ` Jerome Glisse
2016-03-16 18:51             ` Christian König
2016-03-16 20:41               ` Dave Airlie
2016-03-16 20:58                 ` Deucher, Alexander
2016-03-17  7:36                 ` Daniel Vetter
2016-03-18  4:00                   ` Michel Dänzer
2016-03-18  8:16                     ` Daniel Vetter
2016-03-19  9:41                       ` Daniel Vetter
2016-03-19 10:46                         ` Daniel Vetter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1458132531-5524-1-git-send-email-jglisse@redhat.com \
    --to=jglisse@redhat.com \
    --cc=alexander.deucher@amd.com \
    --cc=christian.koenig@amd.com \
    --cc=dri-devel@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.