summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/radeon/cik.c136
1 files changed, 91 insertions, 45 deletions
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 2307e218914b..dd1a7b206a48 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -8209,6 +8209,92 @@ static void cik_uvd_resume(struct radeon_device *rdev)
}
}
+static void cik_vce_init(struct radeon_device *rdev)
+{
+ int r;
+
+ 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 cik_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 cik_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_v2_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 cik_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, VCE_CMD_NO_OP);
+ 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, VCE_CMD_NO_OP);
+ 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;
+ }
+}
+
/**
* cik_startup - program the asic to a functional state
*
@@ -8312,22 +8398,7 @@ static int cik_startup(struct radeon_device *rdev)
}
cik_uvd_start(rdev);
-
- 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_vce_start(rdev);
/* Enable IRQ */
if (!rdev->irq.installed) {
@@ -8404,23 +8475,7 @@ static int cik_startup(struct radeon_device *rdev)
return r;
cik_uvd_resume(rdev);
-
- 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_vce_resume(rdev);
r = radeon_ib_pool_init(rdev);
if (r) {
@@ -8500,7 +8555,8 @@ int cik_suspend(struct radeon_device *rdev)
uvd_v1_0_fini(rdev);
radeon_uvd_suspend(rdev);
}
- radeon_vce_suspend(rdev);
+ if (rdev->has_vce)
+ radeon_vce_suspend(rdev);
cik_fini_pg(rdev);
cik_fini_cg(rdev);
cik_irq_suspend(rdev);
@@ -8627,17 +8683,7 @@ int cik_init(struct radeon_device *rdev)
r600_ring_init(rdev, ring, 256 * 1024);
cik_uvd_init(rdev);
-
- 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_vce_init(rdev);
rdev->ih.ring_obj = NULL;
r600_ih_ring_init(rdev, 64 * 1024);