aboutsummaryrefslogtreecommitdiffstats
path: root/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0027-yocto-amd-drm-radeon-initial-VCE-support-v4.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-steppeeagle/recipes-kernel/linux/linux-yocto/0027-yocto-amd-drm-radeon-initial-VCE-support-v4.patch')
-rw-r--r--meta-steppeeagle/recipes-kernel/linux/linux-yocto/0027-yocto-amd-drm-radeon-initial-VCE-support-v4.patch1434
1 files changed, 0 insertions, 1434 deletions
diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0027-yocto-amd-drm-radeon-initial-VCE-support-v4.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0027-yocto-amd-drm-radeon-initial-VCE-support-v4.patch
deleted file mode 100644
index e64abef2..00000000
--- a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0027-yocto-amd-drm-radeon-initial-VCE-support-v4.patch
+++ /dev/null
@@ -1,1434 +0,0 @@
-From 5890ab59e66a268c7910a7a5ad939107fa1b8a1d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
-Date: Thu, 23 May 2013 12:10:04 +0200
-Subject: [PATCH 27/44] drm/radeon: initial VCE support v4
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Only VCE 2.0 support so far.
-
-v2: squashing multiple patches into this one
-v3: add IRQ support for CIK, major cleanups,
- basic code documentation
-v4: remove HAINAN from chipset list
-
-Signed-off-by: Christian König <christian.koenig@amd.com>
----
- drivers/gpu/drm/radeon/Makefile | 6 +
- drivers/gpu/drm/radeon/cik.c | 60 ++++
- drivers/gpu/drm/radeon/cikd.h | 33 ++
- drivers/gpu/drm/radeon/radeon.h | 56 +++-
- drivers/gpu/drm/radeon/radeon_asic.c | 17 +
- drivers/gpu/drm/radeon/radeon_asic.h | 13 +
- drivers/gpu/drm/radeon/radeon_cs.c | 4 +
- drivers/gpu/drm/radeon/radeon_kms.c | 1 +
- drivers/gpu/drm/radeon/radeon_ring.c | 4 +
- drivers/gpu/drm/radeon/radeon_test.c | 39 ++-
- drivers/gpu/drm/radeon/radeon_vce.c | 588 ++++++++++++++++++++++++++++++++++
- drivers/gpu/drm/radeon/sid.h | 47 +++
- drivers/gpu/drm/radeon/vce_v1_0.c | 187 +++++++++++
- drivers/gpu/drm/radeon/vce_v2_0.c | 70 ++++
- include/uapi/drm/radeon_drm.h | 1 +
- 15 files changed, 1117 insertions(+), 9 deletions(-)
- create mode 100644 drivers/gpu/drm/radeon/radeon_vce.c
- create mode 100644 drivers/gpu/drm/radeon/vce_v1_0.c
- create mode 100644 drivers/gpu/drm/radeon/vce_v2_0.c
-
-diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
-index 306364a..ed60caa 100644
---- a/drivers/gpu/drm/radeon/Makefile
-+++ b/drivers/gpu/drm/radeon/Makefile
-@@ -99,6 +99,12 @@ radeon-y += \
- uvd_v3_1.o \
- uvd_v4_2.o
-
-+# add VCE block
-+radeon-y += \
-+ radeon_vce.o \
-+ vce_v1_0.o \
-+ vce_v2_0.o \
-+
- radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
- radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
- radeon-$(CONFIG_ACPI) += radeon_acpi.o
-diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
-index 4a89b5c..872b146 100644
---- a/drivers/gpu/drm/radeon/cik.c
-+++ b/drivers/gpu/drm/radeon/cik.c
-@@ -6753,6 +6753,20 @@ restart_ih:
- /* reset addr and status */
- WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
- break;
-+ case 167: /* VCE */
-+ DRM_DEBUG("IH: VCE int: 0x%08x\n", src_data);
-+ switch (src_data) {
-+ case 0:
-+ radeon_fence_process(rdev, TN_RING_TYPE_VCE1_INDEX);
-+ break;
-+ case 1:
-+ radeon_fence_process(rdev, TN_RING_TYPE_VCE2_INDEX);
-+ break;
-+ default:
-+ DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
-+ break;
-+ }
-+ break;
- case 176: /* GFX RB CP_INT */
- case 177: /* GFX IB CP_INT */
- radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
-@@ -7071,6 +7085,22 @@ static int cik_startup(struct radeon_device *rdev)
- 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;
-+ }
-+
- /* Enable IRQ */
- if (!rdev->irq.installed) {
- r = radeon_irq_kms_init(rdev);
-@@ -7146,6 +7176,23 @@ static int cik_startup(struct radeon_device *rdev)
- 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);
-+
- r = radeon_ib_pool_init(rdev);
- if (r) {
- dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
-@@ -7213,6 +7260,7 @@ int cik_suspend(struct radeon_device *rdev)
- cik_sdma_enable(rdev, false);
- 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);
-@@ -7321,6 +7369,17 @@ int cik_init(struct radeon_device *rdev)
- 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);
-+ }
-+
- rdev->ih.ring_obj = NULL;
- r600_ih_ring_init(rdev, 64 * 1024);
-
-@@ -7381,6 +7440,7 @@ void cik_fini(struct radeon_device *rdev)
- radeon_irq_kms_fini(rdev);
- 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/cikd.h b/drivers/gpu/drm/radeon/cikd.h
-index 7a0a0d2..b296d50 100644
---- a/drivers/gpu/drm/radeon/cikd.h
-+++ b/drivers/gpu/drm/radeon/cikd.h
-@@ -1899,4 +1899,37 @@
- /* UVD CTX indirect */
- #define UVD_CGC_MEM_CTRL 0xC0
-
-+/* VCE */
-+
-+#define VCE_VCPU_CACHE_OFFSET0 0x20024
-+#define VCE_VCPU_CACHE_SIZE0 0x20028
-+#define VCE_VCPU_CACHE_OFFSET1 0x2002c
-+#define VCE_VCPU_CACHE_SIZE1 0x20030
-+#define VCE_VCPU_CACHE_OFFSET2 0x20034
-+#define VCE_VCPU_CACHE_SIZE2 0x20038
-+#define VCE_RB_RPTR2 0x20178
-+#define VCE_RB_WPTR2 0x2017c
-+#define VCE_RB_RPTR 0x2018c
-+#define VCE_RB_WPTR 0x20190
-+#define VCE_CLOCK_GATING_A 0x202f8
-+#define VCE_CLOCK_GATING_B 0x202fc
-+#define VCE_UENC_CLOCK_GATING 0x207bc
-+#define VCE_UENC_REG_CLOCK_GATING 0x207c0
-+#define VCE_SYS_INT_EN 0x21300
-+# define VCE_SYS_INT_TRAP_INTERRUPT_EN (1 << 3)
-+#define VCE_LMI_CTRL2 0x21474
-+#define VCE_LMI_CTRL 0x21498
-+#define VCE_LMI_VM_CTRL 0x214a0
-+#define VCE_LMI_SWAP_CNTL 0x214b4
-+#define VCE_LMI_SWAP_CNTL1 0x214b8
-+#define VCE_LMI_CACHE_CTRL 0x214f4
-+
-+#define VCE_CMD_NO_OP 0x00000000
-+#define VCE_CMD_END 0x00000001
-+#define VCE_CMD_IB 0x00000002
-+#define VCE_CMD_FENCE 0x00000003
-+#define VCE_CMD_TRAP 0x00000004
-+#define VCE_CMD_IB_AUTO 0x00000005
-+#define VCE_CMD_SEMAPHORE 0x00000006
-+
- #endif
-diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
-index fb7323d..094e5f5 100644
---- a/drivers/gpu/drm/radeon/radeon.h
-+++ b/drivers/gpu/drm/radeon/radeon.h
-@@ -111,19 +111,16 @@ extern int radeon_aspm;
- #define RADEONFB_CONN_LIMIT 4
- #define RADEON_BIOS_NUM_SCRATCH 8
-
--/* max number of rings */
--#define RADEON_NUM_RINGS 6
--
- /* fence seq are set to this number when signaled */
- #define RADEON_FENCE_SIGNALED_SEQ 0LL
-
- /* internal ring indices */
- /* r1xx+ has gfx CP ring */
--#define RADEON_RING_TYPE_GFX_INDEX 0
-+#define RADEON_RING_TYPE_GFX_INDEX 0
-
- /* cayman has 2 compute CP rings */
--#define CAYMAN_RING_TYPE_CP1_INDEX 1
--#define CAYMAN_RING_TYPE_CP2_INDEX 2
-+#define CAYMAN_RING_TYPE_CP1_INDEX 1
-+#define CAYMAN_RING_TYPE_CP2_INDEX 2
-
- /* R600+ has an async dma ring */
- #define R600_RING_TYPE_DMA_INDEX 3
-@@ -131,7 +128,14 @@ extern int radeon_aspm;
- #define CAYMAN_RING_TYPE_DMA1_INDEX 4
-
- /* R600+ */
--#define R600_RING_TYPE_UVD_INDEX 5
-+#define R600_RING_TYPE_UVD_INDEX 5
-+
-+/* TN+ */
-+#define TN_RING_TYPE_VCE1_INDEX 6
-+#define TN_RING_TYPE_VCE2_INDEX 7
-+
-+/* max number of rings */
-+#define RADEON_NUM_RINGS 8
-
- /* hardcode those limit for now */
- #define RADEON_VA_IB_OFFSET (1 << 20)
-@@ -1586,6 +1590,42 @@ int radeon_uvd_calc_upll_dividers(struct radeon_device *rdev,
- int radeon_uvd_send_upll_ctlreq(struct radeon_device *rdev,
- unsigned cg_upll_func_cntl);
-
-+/*
-+ * VCE
-+ */
-+#define RADEON_MAX_VCE_HANDLES 16
-+#define RADEON_VCE_STACK_SIZE (1024*1024)
-+#define RADEON_VCE_HEAP_SIZE (4*1024*1024)
-+
-+struct radeon_vce {
-+ struct radeon_bo *vcpu_bo;
-+ void *cpu_addr;
-+ uint64_t gpu_addr;
-+ atomic_t handles[RADEON_MAX_VCE_HANDLES];
-+ struct drm_file *filp[RADEON_MAX_VCE_HANDLES];
-+};
-+
-+int radeon_vce_init(struct radeon_device *rdev);
-+void radeon_vce_fini(struct radeon_device *rdev);
-+int radeon_vce_suspend(struct radeon_device *rdev);
-+int radeon_vce_resume(struct radeon_device *rdev);
-+int radeon_vce_get_create_msg(struct radeon_device *rdev, int ring,
-+ uint32_t handle, struct radeon_fence **fence);
-+int radeon_vce_get_destroy_msg(struct radeon_device *rdev, int ring,
-+ uint32_t handle, struct radeon_fence **fence);
-+void radeon_vce_free_handles(struct radeon_device *rdev, struct drm_file *filp);
-+int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi);
-+int radeon_vce_cs_parse(struct radeon_cs_parser *p);
-+bool radeon_vce_semaphore_emit(struct radeon_device *rdev,
-+ struct radeon_ring *ring,
-+ struct radeon_semaphore *semaphore,
-+ bool emit_wait);
-+void radeon_vce_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
-+void radeon_vce_fence_emit(struct radeon_device *rdev,
-+ struct radeon_fence *fence);
-+int radeon_vce_ring_test(struct radeon_device *rdev, struct radeon_ring *ring);
-+int radeon_vce_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
-+
- struct r600_audio_pin {
- int channels;
- int rate;
-@@ -2180,6 +2220,7 @@ struct radeon_device {
- struct radeon_gem gem;
- struct radeon_pm pm;
- struct radeon_uvd uvd;
-+ struct radeon_vce vce;
- uint32_t bios_scratch[RADEON_BIOS_NUM_SCRATCH];
- struct radeon_wb wb;
- struct radeon_dummy_page dummy_page;
-@@ -2198,6 +2239,7 @@ struct radeon_device {
- const struct firmware *sdma_fw; /* CIK SDMA firmware */
- const struct firmware *smc_fw; /* SMC firmware */
- const struct firmware *uvd_fw; /* UVD firmware */
-+ const struct firmware *vce_fw; /* VCE firmware */
- struct r600_vram_scratch vram_scratch;
- int msi_enabled; /* msi enabled */
- struct r600_ih ih; /* r6/700 interrupt ring */
-diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
-index a539869..763280b 100644
---- a/drivers/gpu/drm/radeon/radeon_asic.c
-+++ b/drivers/gpu/drm/radeon/radeon_asic.c
-@@ -1978,6 +1978,19 @@ static struct radeon_asic_ring ci_dma_ring = {
- .set_wptr = &cik_sdma_set_wptr,
- };
-
-+static struct radeon_asic_ring ci_vce_ring = {
-+ .ib_execute = &radeon_vce_ib_execute,
-+ .emit_fence = &radeon_vce_fence_emit,
-+ .emit_semaphore = &radeon_vce_semaphore_emit,
-+ .cs_parse = &radeon_vce_cs_parse,
-+ .ring_test = &radeon_vce_ring_test,
-+ .ib_test = &radeon_vce_ib_test,
-+ .is_lockup = &radeon_ring_test_lockup,
-+ .get_rptr = &vce_v1_0_get_rptr,
-+ .get_wptr = &vce_v1_0_get_wptr,
-+ .set_wptr = &vce_v1_0_set_wptr,
-+};
-+
- static struct radeon_asic ci_asic = {
- .init = &cik_init,
- .fini = &cik_fini,
-@@ -2006,6 +2019,8 @@ static struct radeon_asic ci_asic = {
- [R600_RING_TYPE_DMA_INDEX] = &ci_dma_ring,
- [CAYMAN_RING_TYPE_DMA1_INDEX] = &ci_dma_ring,
- [R600_RING_TYPE_UVD_INDEX] = &cayman_uvd_ring,
-+ [TN_RING_TYPE_VCE1_INDEX] = &ci_vce_ring,
-+ [TN_RING_TYPE_VCE2_INDEX] = &ci_vce_ring,
- },
- .irq = {
- .set = &cik_irq_set,
-@@ -2107,6 +2122,8 @@ static struct radeon_asic kv_asic = {
- [R600_RING_TYPE_DMA_INDEX] = &ci_dma_ring,
- [CAYMAN_RING_TYPE_DMA1_INDEX] = &ci_dma_ring,
- [R600_RING_TYPE_UVD_INDEX] = &cayman_uvd_ring,
-+ [TN_RING_TYPE_VCE1_INDEX] = &ci_vce_ring,
-+ [TN_RING_TYPE_VCE2_INDEX] = &ci_vce_ring,
- },
- .irq = {
- .set = &cik_irq_set,
-diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
-index 998042e..a6c3eeb 100644
---- a/drivers/gpu/drm/radeon/radeon_asic.h
-+++ b/drivers/gpu/drm/radeon/radeon_asic.h
-@@ -850,4 +850,17 @@ bool uvd_v3_1_semaphore_emit(struct radeon_device *rdev,
- /* uvd v4.2 */
- int uvd_v4_2_resume(struct radeon_device *rdev);
-
-+/* vce v1.0 */
-+uint32_t vce_v1_0_get_rptr(struct radeon_device *rdev,
-+ struct radeon_ring *ring);
-+uint32_t vce_v1_0_get_wptr(struct radeon_device *rdev,
-+ struct radeon_ring *ring);
-+void vce_v1_0_set_wptr(struct radeon_device *rdev,
-+ struct radeon_ring *ring);
-+int vce_v1_0_init(struct radeon_device *rdev);
-+int vce_v1_0_start(struct radeon_device *rdev);
-+
-+/* vce v2.0 */
-+int vce_v2_0_resume(struct radeon_device *rdev);
-+
- #endif
-diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
-index 83731ff..2f8e92b 100644
---- a/drivers/gpu/drm/radeon/radeon_cs.c
-+++ b/drivers/gpu/drm/radeon/radeon_cs.c
-@@ -147,6 +147,10 @@ static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority
- case RADEON_CS_RING_UVD:
- p->ring = R600_RING_TYPE_UVD_INDEX;
- break;
-+ case RADEON_CS_RING_VCE:
-+ /* TODO: only use the low priority ring for now */
-+ p->ring = TN_RING_TYPE_VCE1_INDEX;
-+ break;
- }
- return 0;
- }
-diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
-index 5d67422..07da88f 100644
---- a/drivers/gpu/drm/radeon/radeon_kms.c
-+++ b/drivers/gpu/drm/radeon/radeon_kms.c
-@@ -579,6 +579,7 @@ void radeon_driver_preclose_kms(struct drm_device *dev,
- if (rdev->cmask_filp == file_priv)
- rdev->cmask_filp = NULL;
- radeon_uvd_free_handles(rdev, file_priv);
-+ radeon_vce_free_handles(rdev, file_priv);
- }
-
- /*
-diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
-index 65f1cea..91457f8 100644
---- a/drivers/gpu/drm/radeon/radeon_ring.c
-+++ b/drivers/gpu/drm/radeon/radeon_ring.c
-@@ -814,6 +814,8 @@ static int cayman_cp2_index = CAYMAN_RING_TYPE_CP2_INDEX;
- static int radeon_dma1_index = R600_RING_TYPE_DMA_INDEX;
- static int radeon_dma2_index = CAYMAN_RING_TYPE_DMA1_INDEX;
- static int r600_uvd_index = R600_RING_TYPE_UVD_INDEX;
-+static int si_vce1_index = TN_RING_TYPE_VCE1_INDEX;
-+static int si_vce2_index = TN_RING_TYPE_VCE2_INDEX;
-
- static struct drm_info_list radeon_debugfs_ring_info_list[] = {
- {"radeon_ring_gfx", radeon_debugfs_ring_info, 0, &radeon_gfx_index},
-@@ -822,6 +824,8 @@ static struct drm_info_list radeon_debugfs_ring_info_list[] = {
- {"radeon_ring_dma1", radeon_debugfs_ring_info, 0, &radeon_dma1_index},
- {"radeon_ring_dma2", radeon_debugfs_ring_info, 0, &radeon_dma2_index},
- {"radeon_ring_uvd", radeon_debugfs_ring_info, 0, &r600_uvd_index},
-+ {"radeon_ring_vce1", radeon_debugfs_ring_info, 0, &si_vce1_index},
-+ {"radeon_ring_vce2", radeon_debugfs_ring_info, 0, &si_vce2_index},
- };
-
- static int radeon_debugfs_sa_info(struct seq_file *m, void *data)
-diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c
-index 12e8099..3a13e0d 100644
---- a/drivers/gpu/drm/radeon/radeon_test.c
-+++ b/drivers/gpu/drm/radeon/radeon_test.c
-@@ -257,20 +257,36 @@ static int radeon_test_create_and_emit_fence(struct radeon_device *rdev,
- struct radeon_ring *ring,
- struct radeon_fence **fence)
- {
-+ uint32_t handle = ring->idx ^ 0xdeafbeef;
- int r;
-
- if (ring->idx == R600_RING_TYPE_UVD_INDEX) {
-- r = radeon_uvd_get_create_msg(rdev, ring->idx, 1, NULL);
-+ r = radeon_uvd_get_create_msg(rdev, ring->idx, handle, NULL);
- if (r) {
- DRM_ERROR("Failed to get dummy create msg\n");
- return r;
- }
-
-- r = radeon_uvd_get_destroy_msg(rdev, ring->idx, 1, fence);
-+ r = radeon_uvd_get_destroy_msg(rdev, ring->idx, handle, fence);
- if (r) {
- DRM_ERROR("Failed to get dummy destroy msg\n");
- return r;
- }
-+
-+ } else if (ring->idx == TN_RING_TYPE_VCE1_INDEX ||
-+ ring->idx == TN_RING_TYPE_VCE2_INDEX) {
-+ r = radeon_vce_get_create_msg(rdev, ring->idx, handle, NULL);
-+ if (r) {
-+ DRM_ERROR("Failed to get dummy create msg\n");
-+ return r;
-+ }
-+
-+ r = radeon_vce_get_destroy_msg(rdev, ring->idx, handle, fence);
-+ if (r) {
-+ DRM_ERROR("Failed to get dummy destroy msg\n");
-+ return r;
-+ }
-+
- } else {
- r = radeon_ring_lock(rdev, ring, 64);
- if (r) {
-@@ -486,6 +502,16 @@ out_cleanup:
- printk(KERN_WARNING "Error while testing ring sync (%d).\n", r);
- }
-
-+static bool radeon_test_sync_possible(struct radeon_ring *ringA,
-+ struct radeon_ring *ringB)
-+{
-+ if (ringA->idx == TN_RING_TYPE_VCE2_INDEX &&
-+ ringB->idx == TN_RING_TYPE_VCE1_INDEX)
-+ return false;
-+
-+ return true;
-+}
-+
- void radeon_test_syncing(struct radeon_device *rdev)
- {
- int i, j, k;
-@@ -500,6 +526,9 @@ void radeon_test_syncing(struct radeon_device *rdev)
- if (!ringB->ready)
- continue;
-
-+ if (!radeon_test_sync_possible(ringA, ringB))
-+ continue;
-+
- DRM_INFO("Testing syncing between rings %d and %d...\n", i, j);
- radeon_test_ring_sync(rdev, ringA, ringB);
-
-@@ -511,6 +540,12 @@ void radeon_test_syncing(struct radeon_device *rdev)
- if (!ringC->ready)
- continue;
-
-+ if (!radeon_test_sync_possible(ringA, ringC))
-+ continue;
-+
-+ if (!radeon_test_sync_possible(ringB, ringC))
-+ continue;
-+
- DRM_INFO("Testing syncing between rings %d, %d and %d...\n", i, j, k);
- radeon_test_ring_sync2(rdev, ringA, ringB, ringC);
-
-diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c
-new file mode 100644
-index 0000000..2547d8e
---- /dev/null
-+++ b/drivers/gpu/drm/radeon/radeon_vce.c
-@@ -0,0 +1,588 @@
-+/*
-+ * Copyright 2013 Advanced Micro Devices, Inc.
-+ * All Rights Reserved.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the
-+ * "Software"), to deal in the Software without restriction, including
-+ * without limitation the rights to use, copy, modify, merge, publish,
-+ * distribute, sub license, and/or sell copies of the Software, and to
-+ * permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
-+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * The above copyright notice and this permission notice (including the
-+ * next paragraph) shall be included in all copies or substantial portions
-+ * of the Software.
-+ *
-+ * Authors: Christian König <christian.koenig@amd.com>
-+ */
-+
-+#include <linux/firmware.h>
-+#include <linux/module.h>
-+#include <drm/drmP.h>
-+#include <drm/drm.h>
-+
-+#include "radeon.h"
-+#include "radeon_asic.h"
-+#include "sid.h"
-+
-+/* Firmware Names */
-+#define FIRMWARE_BONAIRE "radeon/BONAIRE_vce.bin"
-+
-+MODULE_FIRMWARE(FIRMWARE_BONAIRE);
-+
-+/**
-+ * radeon_vce_init - allocate memory, load vce firmware
-+ *
-+ * @rdev: radeon_device pointer
-+ *
-+ * First step to get VCE online, allocate memory and load the firmware
-+ */
-+int radeon_vce_init(struct radeon_device *rdev)
-+{
-+ unsigned long bo_size;
-+ const char *fw_name;
-+ int i, r;
-+
-+ switch (rdev->family) {
-+ case CHIP_BONAIRE:
-+ case CHIP_KAVERI:
-+ case CHIP_KABINI:
-+ fw_name = FIRMWARE_BONAIRE;
-+ break;
-+
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ r = request_firmware(&rdev->vce_fw, fw_name, rdev->dev);
-+ if (r) {
-+ dev_err(rdev->dev, "radeon_vce: Can't load firmware \"%s\"\n",
-+ fw_name);
-+ return r;
-+ }
-+
-+ bo_size = RADEON_GPU_PAGE_ALIGN(rdev->vce_fw->size) +
-+ RADEON_VCE_STACK_SIZE + RADEON_VCE_HEAP_SIZE;
-+ r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true,
-+ RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->vce.vcpu_bo);
-+ if (r) {
-+ dev_err(rdev->dev, "(%d) failed to allocate VCE bo\n", r);
-+ return r;
-+ }
-+
-+ r = radeon_vce_resume(rdev);
-+ if (r)
-+ return r;
-+
-+ memset(rdev->vce.cpu_addr, 0, bo_size);
-+ memcpy(rdev->vce.cpu_addr, rdev->vce_fw->data, rdev->vce_fw->size);
-+
-+ r = radeon_vce_suspend(rdev);
-+ if (r)
-+ return r;
-+
-+ for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) {
-+ atomic_set(&rdev->vce.handles[i], 0);
-+ rdev->vce.filp[i] = NULL;
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * radeon_vce_fini - free memory
-+ *
-+ * @rdev: radeon_device pointer
-+ *
-+ * Last step on VCE teardown, free firmware memory
-+ */
-+void radeon_vce_fini(struct radeon_device *rdev)
-+{
-+ radeon_vce_suspend(rdev);
-+ radeon_bo_unref(&rdev->vce.vcpu_bo);
-+}
-+
-+/**
-+ * radeon_vce_suspend - unpin VCE fw memory
-+ *
-+ * @rdev: radeon_device pointer
-+ *
-+ * TODO: Test VCE suspend/resume
-+ */
-+int radeon_vce_suspend(struct radeon_device *rdev)
-+{
-+ int r;
-+
-+ if (rdev->vce.vcpu_bo == NULL)
-+ return 0;
-+
-+ r = radeon_bo_reserve(rdev->vce.vcpu_bo, false);
-+ if (!r) {
-+ radeon_bo_kunmap(rdev->vce.vcpu_bo);
-+ radeon_bo_unpin(rdev->vce.vcpu_bo);
-+ radeon_bo_unreserve(rdev->vce.vcpu_bo);
-+ }
-+ return r;
-+}
-+
-+/**
-+ * radeon_vce_resume - pin VCE fw memory
-+ *
-+ * @rdev: radeon_device pointer
-+ *
-+ * TODO: Test VCE suspend/resume
-+ */
-+int radeon_vce_resume(struct radeon_device *rdev)
-+{
-+ int r;
-+
-+ if (rdev->vce.vcpu_bo == NULL)
-+ return -EINVAL;
-+
-+ r = radeon_bo_reserve(rdev->vce.vcpu_bo, false);
-+ if (r) {
-+ radeon_bo_unref(&rdev->vce.vcpu_bo);
-+ dev_err(rdev->dev, "(%d) failed to reserve VCE bo\n", r);
-+ return r;
-+ }
-+
-+ r = radeon_bo_pin(rdev->vce.vcpu_bo, RADEON_GEM_DOMAIN_VRAM,
-+ &rdev->vce.gpu_addr);
-+ if (r) {
-+ radeon_bo_unreserve(rdev->vce.vcpu_bo);
-+ radeon_bo_unref(&rdev->vce.vcpu_bo);
-+ dev_err(rdev->dev, "(%d) VCE bo pin failed\n", r);
-+ return r;
-+ }
-+
-+ r = radeon_bo_kmap(rdev->vce.vcpu_bo, &rdev->vce.cpu_addr);
-+ if (r) {
-+ dev_err(rdev->dev, "(%d) VCE map failed\n", r);
-+ return r;
-+ }
-+
-+ radeon_bo_unreserve(rdev->vce.vcpu_bo);
-+
-+ return 0;
-+}
-+
-+/**
-+ * radeon_vce_free_handles - free still open VCE handles
-+ *
-+ * @rdev: radeon_device pointer
-+ * @filp: drm file pointer
-+ *
-+ * Close all VCE handles still open by this file pointer
-+ */
-+void radeon_vce_free_handles(struct radeon_device *rdev, struct drm_file *filp)
-+{
-+ int i, r;
-+ for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) {
-+ uint32_t handle = atomic_read(&rdev->vce.handles[i]);
-+ if (!handle || rdev->vce.filp[i] != filp)
-+ continue;
-+
-+ r = radeon_vce_get_destroy_msg(rdev, TN_RING_TYPE_VCE1_INDEX,
-+ handle, NULL);
-+ if (r)
-+ DRM_ERROR("Error destroying VCE handle (%d)!\n", r);
-+
-+ rdev->vce.filp[i] = NULL;
-+ atomic_set(&rdev->vce.handles[i], 0);
-+ }
-+}
-+
-+/**
-+ * radeon_vce_get_create_msg - generate a VCE create msg
-+ *
-+ * @rdev: radeon_device pointer
-+ * @ring: ring we should submit the msg to
-+ * @handle: VCE session handle to use
-+ * @fence: optional fence to return
-+ *
-+ * Open up a stream for HW test
-+ */
-+int radeon_vce_get_create_msg(struct radeon_device *rdev, int ring,
-+ uint32_t handle, struct radeon_fence **fence)
-+{
-+ const unsigned ib_size_dw = 1024;
-+ struct radeon_ib ib;
-+ uint64_t dummy;
-+ int i, r;
-+
-+ r = radeon_ib_get(rdev, ring, &ib, NULL, ib_size_dw * 4);
-+ if (r) {
-+ DRM_ERROR("radeon: failed to get ib (%d).\n", r);
-+ return r;
-+ }
-+
-+ dummy = ib.gpu_addr + 1024;
-+
-+ /* stitch together an VCE create msg */
-+ ib.length_dw = 0;
-+ ib.ptr[ib.length_dw++] = 0x0000000c; /* len */
-+ ib.ptr[ib.length_dw++] = 0x00000001; /* session cmd */
-+ ib.ptr[ib.length_dw++] = handle;
-+
-+ ib.ptr[ib.length_dw++] = 0x00000030; /* len */
-+ ib.ptr[ib.length_dw++] = 0x01000001; /* create cmd */
-+ ib.ptr[ib.length_dw++] = 0x00000000;
-+ ib.ptr[ib.length_dw++] = 0x00000042;
-+ ib.ptr[ib.length_dw++] = 0x0000000a;
-+ ib.ptr[ib.length_dw++] = 0x00000001;
-+ ib.ptr[ib.length_dw++] = 0x00000080;
-+ ib.ptr[ib.length_dw++] = 0x00000060;
-+ ib.ptr[ib.length_dw++] = 0x00000100;
-+ ib.ptr[ib.length_dw++] = 0x00000100;
-+ ib.ptr[ib.length_dw++] = 0x0000000c;
-+ ib.ptr[ib.length_dw++] = 0x00000000;
-+
-+ ib.ptr[ib.length_dw++] = 0x00000014; /* len */
-+ ib.ptr[ib.length_dw++] = 0x05000005; /* feedback buffer */
-+ ib.ptr[ib.length_dw++] = upper_32_bits(dummy);
-+ ib.ptr[ib.length_dw++] = dummy;
-+ ib.ptr[ib.length_dw++] = 0x00000001;
-+
-+ for (i = ib.length_dw; i < ib_size_dw; ++i)
-+ ib.ptr[i] = 0x0;
-+
-+ r = radeon_ib_schedule(rdev, &ib, NULL);
-+ if (r) {
-+ DRM_ERROR("radeon: failed to schedule ib (%d).\n", r);
-+ }
-+
-+ if (fence)
-+ *fence = radeon_fence_ref(ib.fence);
-+
-+ radeon_ib_free(rdev, &ib);
-+
-+ return r;
-+}
-+
-+/**
-+ * radeon_vce_get_destroy_msg - generate a VCE destroy msg
-+ *
-+ * @rdev: radeon_device pointer
-+ * @ring: ring we should submit the msg to
-+ * @handle: VCE session handle to use
-+ * @fence: optional fence to return
-+ *
-+ * Close up a stream for HW test or if userspace failed to do so
-+ */
-+int radeon_vce_get_destroy_msg(struct radeon_device *rdev, int ring,
-+ uint32_t handle, struct radeon_fence **fence)
-+{
-+ const unsigned ib_size_dw = 1024;
-+ struct radeon_ib ib;
-+ uint64_t dummy;
-+ int i, r;
-+
-+ r = radeon_ib_get(rdev, ring, &ib, NULL, ib_size_dw * 4);
-+ if (r) {
-+ DRM_ERROR("radeon: failed to get ib (%d).\n", r);
-+ return r;
-+ }
-+
-+ dummy = ib.gpu_addr + 1024;
-+
-+ /* stitch together an VCE destroy msg */
-+ ib.length_dw = 0;
-+ ib.ptr[ib.length_dw++] = 0x0000000c; /* len */
-+ ib.ptr[ib.length_dw++] = 0x00000001; /* session cmd */
-+ ib.ptr[ib.length_dw++] = handle;
-+
-+ ib.ptr[ib.length_dw++] = 0x00000014; /* len */
-+ ib.ptr[ib.length_dw++] = 0x05000005; /* feedback buffer */
-+ ib.ptr[ib.length_dw++] = upper_32_bits(dummy);
-+ ib.ptr[ib.length_dw++] = dummy;
-+ ib.ptr[ib.length_dw++] = 0x00000001;
-+
-+ ib.ptr[ib.length_dw++] = 0x00000008; /* len */
-+ ib.ptr[ib.length_dw++] = 0x02000001; /* destroy cmd */
-+
-+ for (i = ib.length_dw; i < ib_size_dw; ++i)
-+ ib.ptr[i] = 0x0;
-+
-+ r = radeon_ib_schedule(rdev, &ib, NULL);
-+ if (r) {
-+ DRM_ERROR("radeon: failed to schedule ib (%d).\n", r);
-+ }
-+
-+ if (fence)
-+ *fence = radeon_fence_ref(ib.fence);
-+
-+ radeon_ib_free(rdev, &ib);
-+
-+ return r;
-+}
-+
-+/**
-+ * radeon_vce_cs_reloc - command submission relocation
-+ *
-+ * @p: parser context
-+ * @lo: address of lower dword
-+ * @hi: address of higher dword
-+ *
-+ * Patch relocation inside command stream with real buffer address
-+ */
-+int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi)
-+{
-+ struct radeon_cs_chunk *relocs_chunk;
-+ uint64_t offset;
-+ unsigned idx;
-+
-+ relocs_chunk = &p->chunks[p->chunk_relocs_idx];
-+ offset = radeon_get_ib_value(p, lo);
-+ idx = radeon_get_ib_value(p, hi);
-+
-+ if (idx >= relocs_chunk->length_dw) {
-+ DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
-+ idx, relocs_chunk->length_dw);
-+ return -EINVAL;
-+ }
-+
-+ offset += p->relocs_ptr[(idx / 4)]->lobj.gpu_offset;
-+
-+ p->ib.ptr[lo] = offset & 0xFFFFFFFF;
-+ p->ib.ptr[hi] = offset >> 32;
-+
-+ return 0;
-+}
-+
-+/**
-+ * radeon_vce_cs_parse - parse and validate the command stream
-+ *
-+ * @p: parser context
-+ *
-+ */
-+int radeon_vce_cs_parse(struct radeon_cs_parser *p)
-+{
-+ uint32_t handle = 0;
-+ bool destroy = false;
-+ int i, r;
-+
-+ while (p->idx < p->chunks[p->chunk_ib_idx].length_dw) {
-+ uint32_t len = radeon_get_ib_value(p, p->idx);
-+ uint32_t cmd = radeon_get_ib_value(p, p->idx + 1);
-+
-+ if ((len < 8) || (len & 3)) {
-+ DRM_ERROR("invalid VCE command length (%d)!\n", len);
-+ return -EINVAL;
-+ }
-+
-+ switch (cmd) {
-+ case 0x00000001: // session
-+ handle = radeon_get_ib_value(p, p->idx + 2);
-+ break;
-+
-+ case 0x00000002: // task info
-+ case 0x01000001: // create
-+ case 0x04000001: // config extension
-+ case 0x04000002: // pic control
-+ case 0x04000005: // rate control
-+ case 0x04000007: // motion estimation
-+ case 0x04000008: // rdo
-+ break;
-+
-+ case 0x03000001: // encode
-+ r = radeon_vce_cs_reloc(p, p->idx + 10, p->idx + 9);
-+ if (r)
-+ return r;
-+
-+ r = radeon_vce_cs_reloc(p, p->idx + 12, p->idx + 11);
-+ if (r)
-+ return r;
-+ break;
-+
-+ case 0x02000001: // destroy
-+ destroy = true;
-+ break;
-+
-+ case 0x05000001: // context buffer
-+ case 0x05000004: // video bitstream buffer
-+ case 0x05000005: // feedback buffer
-+ r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2);
-+ if (r)
-+ return r;
-+ break;
-+
-+ default:
-+ DRM_ERROR("invalid VCE command (0x%x)!\n", cmd);
-+ return -EINVAL;
-+ }
-+
-+ p->idx += len / 4;
-+ }
-+
-+ if (destroy) {
-+ /* IB contains a destroy msg, free the handle */
-+ for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i)
-+ atomic_cmpxchg(&p->rdev->vce.handles[i], handle, 0);
-+
-+ return 0;
-+ }
-+
-+ /* create or encode, validate the handle */
-+ for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) {
-+ if (atomic_read(&p->rdev->vce.handles[i]) == handle)
-+ return 0;
-+ }
-+
-+ /* handle not found try to alloc a new one */
-+ for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) {
-+ if (!atomic_cmpxchg(&p->rdev->vce.handles[i], 0, handle)) {
-+ p->rdev->vce.filp[i] = p->filp;
-+ return 0;
-+ }
-+ }
-+
-+ DRM_ERROR("No more free VCE handles!\n");
-+ return -EINVAL;
-+}
-+
-+/**
-+ * radeon_vce_semaphore_emit - emit a semaphore command
-+ *
-+ * @rdev: radeon_device pointer
-+ * @ring: engine to use
-+ * @semaphore: address of semaphore
-+ * @emit_wait: true=emit wait, false=emit signal
-+ *
-+ */
-+bool radeon_vce_semaphore_emit(struct radeon_device *rdev,
-+ struct radeon_ring *ring,
-+ struct radeon_semaphore *semaphore,
-+ bool emit_wait)
-+{
-+ uint64_t addr = semaphore->gpu_addr;
-+
-+ radeon_ring_write(ring, VCE_CMD_SEMAPHORE);
-+ radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF);
-+ radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF);
-+ radeon_ring_write(ring, 0x01003000 | (emit_wait ? 1 : 0));
-+ if (!emit_wait)
-+ radeon_ring_write(ring, VCE_CMD_END);
-+
-+ return true;
-+}
-+
-+/**
-+ * radeon_vce_ib_execute - execute indirect buffer
-+ *
-+ * @rdev: radeon_device pointer
-+ * @ib: the IB to execute
-+ *
-+ */
-+void radeon_vce_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
-+{
-+ struct radeon_ring *ring = &rdev->ring[ib->ring];
-+ radeon_ring_write(ring, VCE_CMD_IB);
-+ radeon_ring_write(ring, ib->gpu_addr);
-+ radeon_ring_write(ring, upper_32_bits(ib->gpu_addr));
-+ radeon_ring_write(ring, ib->length_dw);
-+}
-+
-+/**
-+ * radeon_vce_fence_emit - add a fence command to the ring
-+ *
-+ * @rdev: radeon_device pointer
-+ * @fence: the fence
-+ *
-+ */
-+void radeon_vce_fence_emit(struct radeon_device *rdev,
-+ struct radeon_fence *fence)
-+{
-+ struct radeon_ring *ring = &rdev->ring[fence->ring];
-+ uint32_t addr = rdev->fence_drv[fence->ring].gpu_addr;
-+
-+ radeon_ring_write(ring, VCE_CMD_FENCE);
-+ radeon_ring_write(ring, addr);
-+ radeon_ring_write(ring, upper_32_bits(addr));
-+ radeon_ring_write(ring, fence->seq);
-+ radeon_ring_write(ring, VCE_CMD_TRAP);
-+ radeon_ring_write(ring, VCE_CMD_END);
-+}
-+
-+/**
-+ * radeon_vce_ring_test - test if VCE ring is working
-+ *
-+ * @rdev: radeon_device pointer
-+ * @ring: the engine to test on
-+ *
-+ */
-+int radeon_vce_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
-+{
-+ uint32_t rptr = vce_v1_0_get_rptr(rdev, ring);
-+ unsigned i;
-+ int r;
-+
-+ r = radeon_ring_lock(rdev, ring, 16);
-+ if (r) {
-+ DRM_ERROR("radeon: vce failed to lock ring %d (%d).\n",
-+ ring->idx, r);
-+ return r;
-+ }
-+ radeon_ring_write(ring, VCE_CMD_END);
-+ radeon_ring_unlock_commit(rdev, ring);
-+
-+ for (i = 0; i < rdev->usec_timeout; i++) {
-+ if (vce_v1_0_get_rptr(rdev, ring) != rptr)
-+ break;
-+ DRM_UDELAY(1);
-+ }
-+
-+ if (i < rdev->usec_timeout) {
-+ DRM_INFO("ring test on %d succeeded in %d usecs\n",
-+ ring->idx, i);
-+ } else {
-+ DRM_ERROR("radeon: ring %d test failed\n",
-+ ring->idx);
-+ r = -ETIMEDOUT;
-+ }
-+
-+ return r;
-+}
-+
-+/**
-+ * radeon_vce_ib_test - test if VCE IBs are working
-+ *
-+ * @rdev: radeon_device pointer
-+ * @ring: the engine to test on
-+ *
-+ */
-+int radeon_vce_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
-+{
-+ struct radeon_fence *fence = NULL;
-+ int r;
-+
-+ r = radeon_vce_get_create_msg(rdev, ring->idx, 1, NULL);
-+ if (r) {
-+ DRM_ERROR("radeon: failed to get create msg (%d).\n", r);
-+ goto error;
-+ }
-+
-+ r = radeon_vce_get_destroy_msg(rdev, ring->idx, 1, &fence);
-+ if (r) {
-+ DRM_ERROR("radeon: failed to get destroy ib (%d).\n", r);
-+ goto error;
-+ }
-+
-+ r = radeon_fence_wait(fence, false);
-+ if (r) {
-+ DRM_ERROR("radeon: fence wait failed (%d).\n", r);
-+ } else {
-+ DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
-+ }
-+error:
-+ radeon_fence_unref(&fence);
-+ return r;
-+}
-diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h
-index db3dd87..1da5a7a 100644
---- a/drivers/gpu/drm/radeon/sid.h
-+++ b/drivers/gpu/drm/radeon/sid.h
-@@ -1747,4 +1747,51 @@
- #define DMA_PACKET_CONSTANT_FILL 0xd
- #define DMA_PACKET_NOP 0xf
-
-+#define VCE_STATUS 0x20004
-+#define VCE_VCPU_CNTL 0x20014
-+#define VCE_CLK_EN (1 << 0)
-+#define VCE_VCPU_CACHE_OFFSET0 0x20024
-+#define VCE_VCPU_CACHE_SIZE0 0x20028
-+#define VCE_VCPU_CACHE_OFFSET1 0x2002c
-+#define VCE_VCPU_CACHE_SIZE1 0x20030
-+#define VCE_VCPU_CACHE_OFFSET2 0x20034
-+#define VCE_VCPU_CACHE_SIZE2 0x20038
-+#define VCE_SOFT_RESET 0x20120
-+#define VCE_ECPU_SOFT_RESET (1 << 0)
-+#define VCE_FME_SOFT_RESET (1 << 2)
-+#define VCE_RB_BASE_LO2 0x2016c
-+#define VCE_RB_BASE_HI2 0x20170
-+#define VCE_RB_SIZE2 0x20174
-+#define VCE_RB_RPTR2 0x20178
-+#define VCE_RB_WPTR2 0x2017c
-+#define VCE_RB_BASE_LO 0x20180
-+#define VCE_RB_BASE_HI 0x20184
-+#define VCE_RB_SIZE 0x20188
-+#define VCE_RB_RPTR 0x2018c
-+#define VCE_RB_WPTR 0x20190
-+#define VCE_CLOCK_GATING_A 0x202f8
-+#define VCE_CLOCK_GATING_B 0x202fc
-+#define VCE_UENC_CLOCK_GATING 0x205bc
-+#define VCE_UENC_REG_CLOCK_GATING 0x205c0
-+#define VCE_FW_REG_STATUS 0x20e10
-+# define VCE_FW_REG_STATUS_BUSY (1 << 0)
-+# define VCE_FW_REG_STATUS_PASS (1 << 3)
-+# define VCE_FW_REG_STATUS_DONE (1 << 11)
-+#define VCE_LMI_FW_START_KEYSEL 0x20e18
-+#define VCE_LMI_FW_PERIODIC_CTRL 0x20e20
-+#define VCE_LMI_CTRL2 0x20e74
-+#define VCE_LMI_CTRL 0x20e98
-+#define VCE_LMI_VM_CTRL 0x20ea0
-+#define VCE_LMI_SWAP_CNTL 0x20eb4
-+#define VCE_LMI_SWAP_CNTL1 0x20eb8
-+#define VCE_LMI_CACHE_CTRL 0x20ef4
-+
-+#define VCE_CMD_NO_OP 0x00000000
-+#define VCE_CMD_END 0x00000001
-+#define VCE_CMD_IB 0x00000002
-+#define VCE_CMD_FENCE 0x00000003
-+#define VCE_CMD_TRAP 0x00000004
-+#define VCE_CMD_IB_AUTO 0x00000005
-+#define VCE_CMD_SEMAPHORE 0x00000006
-+
- #endif
-diff --git a/drivers/gpu/drm/radeon/vce_v1_0.c b/drivers/gpu/drm/radeon/vce_v1_0.c
-new file mode 100644
-index 0000000..e0c3534
---- /dev/null
-+++ b/drivers/gpu/drm/radeon/vce_v1_0.c
-@@ -0,0 +1,187 @@
-+/*
-+ * Copyright 2013 Advanced Micro Devices, Inc.
-+ * All Rights Reserved.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the
-+ * "Software"), to deal in the Software without restriction, including
-+ * without limitation the rights to use, copy, modify, merge, publish,
-+ * distribute, sub license, and/or sell copies of the Software, and to
-+ * permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
-+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * The above copyright notice and this permission notice (including the
-+ * next paragraph) shall be included in all copies or substantial portions
-+ * of the Software.
-+ *
-+ * Authors: Christian König <christian.koenig@amd.com>
-+ */
-+
-+#include <linux/firmware.h>
-+#include <drm/drmP.h>
-+#include "radeon.h"
-+#include "radeon_asic.h"
-+#include "sid.h"
-+
-+/**
-+ * vce_v1_0_get_rptr - get read pointer
-+ *
-+ * @rdev: radeon_device pointer
-+ * @ring: radeon_ring pointer
-+ *
-+ * Returns the current hardware read pointer
-+ */
-+uint32_t vce_v1_0_get_rptr(struct radeon_device *rdev,
-+ struct radeon_ring *ring)
-+{
-+ if (ring->idx == TN_RING_TYPE_VCE1_INDEX)
-+ return RREG32(VCE_RB_RPTR);
-+ else
-+ return RREG32(VCE_RB_RPTR2);
-+}
-+
-+/**
-+ * vce_v1_0_get_wptr - get write pointer
-+ *
-+ * @rdev: radeon_device pointer
-+ * @ring: radeon_ring pointer
-+ *
-+ * Returns the current hardware write pointer
-+ */
-+uint32_t vce_v1_0_get_wptr(struct radeon_device *rdev,
-+ struct radeon_ring *ring)
-+{
-+ if (ring->idx == TN_RING_TYPE_VCE1_INDEX)
-+ return RREG32(VCE_RB_WPTR);
-+ else
-+ return RREG32(VCE_RB_WPTR2);
-+}
-+
-+/**
-+ * vce_v1_0_set_wptr - set write pointer
-+ *
-+ * @rdev: radeon_device pointer
-+ * @ring: radeon_ring pointer
-+ *
-+ * Commits the write pointer to the hardware
-+ */
-+void vce_v1_0_set_wptr(struct radeon_device *rdev,
-+ struct radeon_ring *ring)
-+{
-+ if (ring->idx == TN_RING_TYPE_VCE1_INDEX)
-+ WREG32(VCE_RB_WPTR, ring->wptr);
-+ else
-+ WREG32(VCE_RB_WPTR2, ring->wptr);
-+}
-+
-+/**
-+ * vce_v1_0_start - start VCE block
-+ *
-+ * @rdev: radeon_device pointer
-+ *
-+ * Setup and start the VCE block
-+ */
-+int vce_v1_0_start(struct radeon_device *rdev)
-+{
-+ struct radeon_ring *ring;
-+ int i, j, r;
-+
-+ /* set BUSY flag */
-+ WREG32_P(VCE_STATUS, 1, ~1);
-+
-+ ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
-+ WREG32(VCE_RB_RPTR, ring->rptr);
-+ WREG32(VCE_RB_WPTR, ring->wptr);
-+ WREG32(VCE_RB_BASE_LO, ring->gpu_addr);
-+ WREG32(VCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
-+ WREG32(VCE_RB_SIZE, ring->ring_size / 4);
-+
-+ ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
-+ WREG32(VCE_RB_RPTR2, ring->rptr);
-+ WREG32(VCE_RB_WPTR2, ring->wptr);
-+ WREG32(VCE_RB_BASE_LO2, ring->gpu_addr);
-+ WREG32(VCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
-+ WREG32(VCE_RB_SIZE2, ring->ring_size / 4);
-+
-+ WREG32_P(VCE_VCPU_CNTL, VCE_CLK_EN, ~VCE_CLK_EN);
-+
-+ WREG32_P(VCE_SOFT_RESET,
-+ VCE_ECPU_SOFT_RESET |
-+ VCE_FME_SOFT_RESET, ~(
-+ VCE_ECPU_SOFT_RESET |
-+ VCE_FME_SOFT_RESET));
-+
-+ mdelay(100);
-+
-+ WREG32_P(VCE_SOFT_RESET, 0, ~(
-+ VCE_ECPU_SOFT_RESET |
-+ VCE_FME_SOFT_RESET));
-+
-+ for (i = 0; i < 10; ++i) {
-+ uint32_t status;
-+ for (j = 0; j < 100; ++j) {
-+ status = RREG32(VCE_STATUS);
-+ if (status & 2)
-+ break;
-+ mdelay(10);
-+ }
-+ r = 0;
-+ if (status & 2)
-+ break;
-+
-+ DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n");
-+ WREG32_P(VCE_SOFT_RESET, VCE_ECPU_SOFT_RESET, ~VCE_ECPU_SOFT_RESET);
-+ mdelay(10);
-+ WREG32_P(VCE_SOFT_RESET, 0, ~VCE_ECPU_SOFT_RESET);
-+ mdelay(10);
-+ r = -1;
-+ }
-+
-+ /* clear BUSY flag */
-+ WREG32_P(VCE_STATUS, 0, ~1);
-+
-+ if (r) {
-+ DRM_ERROR("VCE not responding, giving up!!!\n");
-+ return r;
-+ }
-+
-+ return 0;
-+}
-+
-+int vce_v1_0_init(struct radeon_device *rdev)
-+{
-+ struct radeon_ring *ring;
-+ int r;
-+
-+ r = vce_v1_0_start(rdev);
-+ if (r)
-+ return r;
-+
-+ ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
-+ ring->ready = true;
-+ r = radeon_ring_test(rdev, TN_RING_TYPE_VCE1_INDEX, ring);
-+ if (r) {
-+ ring->ready = false;
-+ return r;
-+ }
-+
-+ ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
-+ ring->ready = true;
-+ r = radeon_ring_test(rdev, TN_RING_TYPE_VCE2_INDEX, ring);
-+ if (r) {
-+ ring->ready = false;
-+ return r;
-+ }
-+
-+ DRM_INFO("VCE initialized successfully.\n");
-+
-+ return 0;
-+}
-diff --git a/drivers/gpu/drm/radeon/vce_v2_0.c b/drivers/gpu/drm/radeon/vce_v2_0.c
-new file mode 100644
-index 0000000..4911d1b
---- /dev/null
-+++ b/drivers/gpu/drm/radeon/vce_v2_0.c
-@@ -0,0 +1,70 @@
-+/*
-+ * Copyright 2013 Advanced Micro Devices, Inc.
-+ * All Rights Reserved.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the
-+ * "Software"), to deal in the Software without restriction, including
-+ * without limitation the rights to use, copy, modify, merge, publish,
-+ * distribute, sub license, and/or sell copies of the Software, and to
-+ * permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
-+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * The above copyright notice and this permission notice (including the
-+ * next paragraph) shall be included in all copies or substantial portions
-+ * of the Software.
-+ *
-+ * Authors: Christian König <christian.koenig@amd.com>
-+ */
-+
-+#include <linux/firmware.h>
-+#include <drm/drmP.h>
-+#include "radeon.h"
-+#include "radeon_asic.h"
-+#include "cikd.h"
-+
-+int vce_v2_0_resume(struct radeon_device *rdev)
-+{
-+ uint64_t addr = rdev->vce.gpu_addr;
-+ uint32_t size;
-+
-+ WREG32_P(VCE_CLOCK_GATING_A, 0, ~(1 << 16));
-+ WREG32_P(VCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000);
-+ WREG32_P(VCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F);
-+ WREG32(VCE_CLOCK_GATING_B, 0xf7);
-+
-+ WREG32(VCE_LMI_CTRL, 0x00398000);
-+ WREG32_P(VCE_LMI_CACHE_CTRL, 0x0, ~0x1);
-+ WREG32(VCE_LMI_SWAP_CNTL, 0);
-+ WREG32(VCE_LMI_SWAP_CNTL1, 0);
-+ WREG32(VCE_LMI_VM_CTRL, 0);
-+
-+ size = RADEON_GPU_PAGE_ALIGN(rdev->vce_fw->size);
-+ WREG32(VCE_VCPU_CACHE_OFFSET0, addr & 0x7fffffff);
-+ WREG32(VCE_VCPU_CACHE_SIZE0, size);
-+
-+ addr += size;
-+ size = RADEON_VCE_STACK_SIZE;
-+ WREG32(VCE_VCPU_CACHE_OFFSET1, addr & 0x7fffffff);
-+ WREG32(VCE_VCPU_CACHE_SIZE1, size);
-+
-+ addr += size;
-+ size = RADEON_VCE_HEAP_SIZE;
-+ WREG32(VCE_VCPU_CACHE_OFFSET2, addr & 0x7fffffff);
-+ WREG32(VCE_VCPU_CACHE_SIZE2, size);
-+
-+ WREG32_P(VCE_LMI_CTRL2, 0x0, ~0x100);
-+
-+ WREG32_P(VCE_SYS_INT_EN, VCE_SYS_INT_TRAP_INTERRUPT_EN,
-+ ~VCE_SYS_INT_TRAP_INTERRUPT_EN);
-+
-+ return 0;
-+}
-diff --git a/include/uapi/drm/radeon_drm.h b/include/uapi/drm/radeon_drm.h
-index fe421e8..b93c92a 100644
---- a/include/uapi/drm/radeon_drm.h
-+++ b/include/uapi/drm/radeon_drm.h
-@@ -919,6 +919,7 @@ struct drm_radeon_gem_va {
- #define RADEON_CS_RING_COMPUTE 1
- #define RADEON_CS_RING_DMA 2
- #define RADEON_CS_RING_UVD 3
-+#define RADEON_CS_RING_VCE 4
- /* The third dword of RADEON_CHUNK_ID_FLAGS is a sint32 that sets the priority */
- /* 0 = normal, + = higher priority, - = lower priority */
-
---
-1.7.9.5
-