aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2013-08-13 05:56:53 -0400
committerAlex Deucher <alexander.deucher@amd.com>2013-08-30 16:30:42 -0400
commite409b128625732926c112cc9b709fb7bb1aa387f (patch)
tree41a6cea66751573bf5a2e984942106860019f773 /drivers/gpu
parent2e1e6dad6a6d437e4c40611fdcc4e6cd9e2f969e (diff)
drm/radeon: separate UVD code v3
Our different hardware blocks are actually completely separated, so it doesn't make much sense any more to structure the code by pure chipset generations. Start restructuring the code by separating our the UVD block. v2: updated commit message v3: rebased and restructurized start/stop functions for kv dpm. Signed-off-by: Christian König <christian.koenig@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/Makefile8
-rw-r--r--drivers/gpu/drm/radeon/cik.c41
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c8
-rw-r--r--drivers/gpu/drm/radeon/kv_dpm.c11
-rw-r--r--drivers/gpu/drm/radeon/ni.c25
-rw-r--r--drivers/gpu/drm/radeon/r600.c345
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.c32
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h55
-rw-r--r--drivers/gpu/drm/radeon/rv770.c105
-rw-r--r--drivers/gpu/drm/radeon/rv770d.h16
-rw-r--r--drivers/gpu/drm/radeon/si.c8
-rw-r--r--drivers/gpu/drm/radeon/uvd_v1_0.c434
-rw-r--r--drivers/gpu/drm/radeon/uvd_v2_2.c165
-rw-r--r--drivers/gpu/drm/radeon/uvd_v3_1.c55
-rw-r--r--drivers/gpu/drm/radeon/uvd_v4_2.c73
15 files changed, 826 insertions, 555 deletions
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index ea913cc681b4..1e23b18d549a 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -82,6 +82,14 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
82 trinity_smc.o ni_dpm.o si_smc.o si_dpm.o kv_smc.o kv_dpm.o ci_smc.o \ 82 trinity_smc.o ni_dpm.o si_smc.o si_dpm.o kv_smc.o kv_dpm.o ci_smc.o \
83 ci_dpm.o 83 ci_dpm.o
84 84
85# add UVD block
86radeon-y += \
87 radeon_uvd.o \
88 uvd_v1_0.o \
89 uvd_v2_2.o \
90 uvd_v3_1.o \
91 uvd_v4_2.o
92
85radeon-$(CONFIG_COMPAT) += radeon_ioc32.o 93radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
86radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o 94radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
87radeon-$(CONFIG_ACPI) += radeon_acpi.o 95radeon-$(CONFIG_ACPI) += radeon_acpi.o
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 34be795de173..1400b5203db1 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -69,7 +69,6 @@ static void cik_pcie_gen3_enable(struct radeon_device *rdev);
69static void cik_program_aspm(struct radeon_device *rdev); 69static void cik_program_aspm(struct radeon_device *rdev);
70static void cik_init_pg(struct radeon_device *rdev); 70static void cik_init_pg(struct radeon_device *rdev);
71static void cik_init_cg(struct radeon_device *rdev); 71static void cik_init_cg(struct radeon_device *rdev);
72void cik_uvd_resume(struct radeon_device *rdev);
73 72
74/* get temperature in millidegrees */ 73/* get temperature in millidegrees */
75int ci_get_temp(struct radeon_device *rdev) 74int ci_get_temp(struct radeon_device *rdev)
@@ -7616,9 +7615,8 @@ static int cik_startup(struct radeon_device *rdev)
7616 return r; 7615 return r;
7617 } 7616 }
7618 7617
7619 r = radeon_uvd_resume(rdev); 7618 r = uvd_v4_2_resume(rdev);
7620 if (!r) { 7619 if (!r) {
7621 cik_uvd_resume(rdev);
7622 r = radeon_fence_driver_start_ring(rdev, 7620 r = radeon_fence_driver_start_ring(rdev,
7623 R600_RING_TYPE_UVD_INDEX); 7621 R600_RING_TYPE_UVD_INDEX);
7624 if (r) 7622 if (r)
@@ -7705,7 +7703,7 @@ static int cik_startup(struct radeon_device *rdev)
7705 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, 7703 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
7706 RADEON_CP_PACKET2); 7704 RADEON_CP_PACKET2);
7707 if (!r) 7705 if (!r)
7708 r = r600_uvd_init(rdev, true); 7706 r = uvd_v1_0_init(rdev);
7709 if (r) 7707 if (r)
7710 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); 7708 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
7711 } 7709 }
@@ -7770,7 +7768,7 @@ int cik_suspend(struct radeon_device *rdev)
7770 radeon_vm_manager_fini(rdev); 7768 radeon_vm_manager_fini(rdev);
7771 cik_cp_enable(rdev, false); 7769 cik_cp_enable(rdev, false);
7772 cik_sdma_enable(rdev, false); 7770 cik_sdma_enable(rdev, false);
7773 r600_uvd_stop(rdev); 7771 uvd_v1_0_fini(rdev);
7774 radeon_uvd_suspend(rdev); 7772 radeon_uvd_suspend(rdev);
7775 cik_irq_suspend(rdev); 7773 cik_irq_suspend(rdev);
7776 radeon_wb_disable(rdev); 7774 radeon_wb_disable(rdev);
@@ -7934,7 +7932,7 @@ void cik_fini(struct radeon_device *rdev)
7934 radeon_vm_manager_fini(rdev); 7932 radeon_vm_manager_fini(rdev);
7935 radeon_ib_pool_fini(rdev); 7933 radeon_ib_pool_fini(rdev);
7936 radeon_irq_kms_fini(rdev); 7934 radeon_irq_kms_fini(rdev);
7937 r600_uvd_stop(rdev); 7935 uvd_v1_0_fini(rdev);
7938 radeon_uvd_fini(rdev); 7936 radeon_uvd_fini(rdev);
7939 cik_pcie_gart_fini(rdev); 7937 cik_pcie_gart_fini(rdev);
7940 r600_vram_scratch_fini(rdev); 7938 r600_vram_scratch_fini(rdev);
@@ -8595,37 +8593,6 @@ int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
8595 return r; 8593 return r;
8596} 8594}
8597 8595
8598void cik_uvd_resume(struct radeon_device *rdev)
8599{
8600 uint64_t addr;
8601 uint32_t size;
8602
8603 /* programm the VCPU memory controller bits 0-27 */
8604 addr = rdev->uvd.gpu_addr >> 3;
8605 size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3;
8606 WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
8607 WREG32(UVD_VCPU_CACHE_SIZE0, size);
8608
8609 addr += size;
8610 size = RADEON_UVD_STACK_SIZE >> 3;
8611 WREG32(UVD_VCPU_CACHE_OFFSET1, addr);
8612 WREG32(UVD_VCPU_CACHE_SIZE1, size);
8613
8614 addr += size;
8615 size = RADEON_UVD_HEAP_SIZE >> 3;
8616 WREG32(UVD_VCPU_CACHE_OFFSET2, addr);
8617 WREG32(UVD_VCPU_CACHE_SIZE2, size);
8618
8619 /* bits 28-31 */
8620 addr = (rdev->uvd.gpu_addr >> 28) & 0xF;
8621 WREG32(UVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0));
8622
8623 /* bits 32-39 */
8624 addr = (rdev->uvd.gpu_addr >> 32) & 0xFF;
8625 WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31));
8626
8627}
8628
8629static void cik_pcie_gen3_enable(struct radeon_device *rdev) 8596static void cik_pcie_gen3_enable(struct radeon_device *rdev)
8630{ 8597{
8631 struct pci_dev *root = rdev->pdev->bus->self; 8598 struct pci_dev *root = rdev->pdev->bus->self;
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 389f5a981358..52ed22333f0d 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -5239,7 +5239,7 @@ static int evergreen_startup(struct radeon_device *rdev)
5239 return r; 5239 return r;
5240 } 5240 }
5241 5241
5242 r = rv770_uvd_resume(rdev); 5242 r = uvd_v2_2_resume(rdev);
5243 if (!r) { 5243 if (!r) {
5244 r = radeon_fence_driver_start_ring(rdev, 5244 r = radeon_fence_driver_start_ring(rdev,
5245 R600_RING_TYPE_UVD_INDEX); 5245 R600_RING_TYPE_UVD_INDEX);
@@ -5295,7 +5295,7 @@ static int evergreen_startup(struct radeon_device *rdev)
5295 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, 5295 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
5296 RADEON_CP_PACKET2); 5296 RADEON_CP_PACKET2);
5297 if (!r) 5297 if (!r)
5298 r = r600_uvd_init(rdev, true); 5298 r = uvd_v1_0_init(rdev);
5299 5299
5300 if (r) 5300 if (r)
5301 DRM_ERROR("radeon: error initializing UVD (%d).\n", r); 5301 DRM_ERROR("radeon: error initializing UVD (%d).\n", r);
@@ -5350,7 +5350,7 @@ int evergreen_resume(struct radeon_device *rdev)
5350int evergreen_suspend(struct radeon_device *rdev) 5350int evergreen_suspend(struct radeon_device *rdev)
5351{ 5351{
5352 r600_audio_fini(rdev); 5352 r600_audio_fini(rdev);
5353 r600_uvd_stop(rdev); 5353 uvd_v1_0_fini(rdev);
5354 radeon_uvd_suspend(rdev); 5354 radeon_uvd_suspend(rdev);
5355 r700_cp_stop(rdev); 5355 r700_cp_stop(rdev);
5356 r600_dma_stop(rdev); 5356 r600_dma_stop(rdev);
@@ -5487,7 +5487,7 @@ void evergreen_fini(struct radeon_device *rdev)
5487 radeon_ib_pool_fini(rdev); 5487 radeon_ib_pool_fini(rdev);
5488 radeon_irq_kms_fini(rdev); 5488 radeon_irq_kms_fini(rdev);
5489 evergreen_pcie_gart_fini(rdev); 5489 evergreen_pcie_gart_fini(rdev);
5490 r600_uvd_stop(rdev); 5490 uvd_v1_0_fini(rdev);
5491 radeon_uvd_fini(rdev); 5491 radeon_uvd_fini(rdev);
5492 r600_vram_scratch_fini(rdev); 5492 r600_vram_scratch_fini(rdev);
5493 radeon_gem_fini(rdev); 5493 radeon_gem_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c
index 3e232a4d3f4c..ef6c901690da 100644
--- a/drivers/gpu/drm/radeon/kv_dpm.c
+++ b/drivers/gpu/drm/radeon/kv_dpm.c
@@ -26,6 +26,7 @@
26#include "cikd.h" 26#include "cikd.h"
27#include "r600_dpm.h" 27#include "r600_dpm.h"
28#include "kv_dpm.h" 28#include "kv_dpm.h"
29#include "radeon_asic.h"
29#include <linux/seq_file.h> 30#include <linux/seq_file.h>
30 31
31#define KV_MAX_DEEPSLEEP_DIVIDER_ID 5 32#define KV_MAX_DEEPSLEEP_DIVIDER_ID 5
@@ -59,10 +60,6 @@ extern void cik_exit_rlc_safe_mode(struct radeon_device *rdev);
59extern void cik_update_cg(struct radeon_device *rdev, 60extern void cik_update_cg(struct radeon_device *rdev,
60 u32 block, bool enable); 61 u32 block, bool enable);
61 62
62extern void cik_uvd_resume(struct radeon_device *rdev);
63extern int r600_uvd_init(struct radeon_device *rdev, bool ring_test);
64extern void r600_do_uvd_stop(struct radeon_device *rdev);
65
66static const struct kv_lcac_config_values sx_local_cac_cfg_kv[] = 63static const struct kv_lcac_config_values sx_local_cac_cfg_kv[] =
67{ 64{
68 { 0, 4, 1 }, 65 { 0, 4, 1 },
@@ -1473,7 +1470,7 @@ void kv_dpm_powergate_uvd(struct radeon_device *rdev, bool gate)
1473 pi->uvd_power_gated = gate; 1470 pi->uvd_power_gated = gate;
1474 1471
1475 if (gate) { 1472 if (gate) {
1476 r600_do_uvd_stop(rdev); 1473 uvd_v1_0_stop(rdev);
1477 cik_update_cg(rdev, RADEON_CG_BLOCK_UVD, false); 1474 cik_update_cg(rdev, RADEON_CG_BLOCK_UVD, false);
1478 kv_update_uvd_dpm(rdev, gate); 1475 kv_update_uvd_dpm(rdev, gate);
1479 if (pi->caps_uvd_pg) 1476 if (pi->caps_uvd_pg)
@@ -1481,8 +1478,8 @@ void kv_dpm_powergate_uvd(struct radeon_device *rdev, bool gate)
1481 } else { 1478 } else {
1482 if (pi->caps_uvd_pg) 1479 if (pi->caps_uvd_pg)
1483 kv_notify_message_to_smu(rdev, PPSMC_MSG_UVDPowerON); 1480 kv_notify_message_to_smu(rdev, PPSMC_MSG_UVDPowerON);
1484 cik_uvd_resume(rdev); 1481 uvd_v4_2_resume(rdev);
1485 r600_uvd_init(rdev, false); 1482 uvd_v1_0_start(rdev);
1486 cik_update_cg(rdev, RADEON_CG_BLOCK_UVD, true); 1483 cik_update_cg(rdev, RADEON_CG_BLOCK_UVD, true);
1487 kv_update_uvd_dpm(rdev, gate); 1484 kv_update_uvd_dpm(rdev, gate);
1488 } 1485 }
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index e04b17338336..0205fa1594fa 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1373,23 +1373,6 @@ void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
1373 radeon_ring_write(ring, 10); /* poll interval */ 1373 radeon_ring_write(ring, 10); /* poll interval */
1374} 1374}
1375 1375
1376void cayman_uvd_semaphore_emit(struct radeon_device *rdev,
1377 struct radeon_ring *ring,
1378 struct radeon_semaphore *semaphore,
1379 bool emit_wait)
1380{
1381 uint64_t addr = semaphore->gpu_addr;
1382
1383 radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0));
1384 radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF);
1385
1386 radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0));
1387 radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF);
1388
1389 radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0));
1390 radeon_ring_write(ring, 0x80 | (emit_wait ? 1 : 0));
1391}
1392
1393static void cayman_cp_enable(struct radeon_device *rdev, bool enable) 1376static void cayman_cp_enable(struct radeon_device *rdev, bool enable)
1394{ 1377{
1395 if (enable) 1378 if (enable)
@@ -2141,7 +2124,7 @@ static int cayman_startup(struct radeon_device *rdev)
2141 return r; 2124 return r;
2142 } 2125 }
2143 2126
2144 r = rv770_uvd_resume(rdev); 2127 r = uvd_v2_2_resume(rdev);
2145 if (!r) { 2128 if (!r) {
2146 r = radeon_fence_driver_start_ring(rdev, 2129 r = radeon_fence_driver_start_ring(rdev,
2147 R600_RING_TYPE_UVD_INDEX); 2130 R600_RING_TYPE_UVD_INDEX);
@@ -2229,7 +2212,7 @@ static int cayman_startup(struct radeon_device *rdev)
2229 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, 2212 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
2230 RADEON_CP_PACKET2); 2213 RADEON_CP_PACKET2);
2231 if (!r) 2214 if (!r)
2232 r = r600_uvd_init(rdev, true); 2215 r = uvd_v1_0_init(rdev);
2233 if (r) 2216 if (r)
2234 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); 2217 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
2235 } 2218 }
@@ -2283,7 +2266,7 @@ int cayman_suspend(struct radeon_device *rdev)
2283 radeon_vm_manager_fini(rdev); 2266 radeon_vm_manager_fini(rdev);
2284 cayman_cp_enable(rdev, false); 2267 cayman_cp_enable(rdev, false);
2285 cayman_dma_stop(rdev); 2268 cayman_dma_stop(rdev);
2286 r600_uvd_stop(rdev); 2269 uvd_v1_0_fini(rdev);
2287 radeon_uvd_suspend(rdev); 2270 radeon_uvd_suspend(rdev);
2288 evergreen_irq_suspend(rdev); 2271 evergreen_irq_suspend(rdev);
2289 radeon_wb_disable(rdev); 2272 radeon_wb_disable(rdev);
@@ -2414,7 +2397,7 @@ void cayman_fini(struct radeon_device *rdev)
2414 radeon_vm_manager_fini(rdev); 2397 radeon_vm_manager_fini(rdev);
2415 radeon_ib_pool_fini(rdev); 2398 radeon_ib_pool_fini(rdev);
2416 radeon_irq_kms_fini(rdev); 2399 radeon_irq_kms_fini(rdev);
2417 r600_uvd_stop(rdev); 2400 uvd_v1_0_fini(rdev);
2418 radeon_uvd_fini(rdev); 2401 radeon_uvd_fini(rdev);
2419 cayman_pcie_gart_fini(rdev); 2402 cayman_pcie_gart_fini(rdev);
2420 r600_vram_scratch_fini(rdev); 2403 r600_vram_scratch_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 30849eca6e07..3a08ef92d33f 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2664,231 +2664,6 @@ void r600_dma_fini(struct radeon_device *rdev)
2664} 2664}
2665 2665
2666/* 2666/*
2667 * UVD
2668 */
2669uint32_t r600_uvd_get_rptr(struct radeon_device *rdev,
2670 struct radeon_ring *ring)
2671{
2672 return RREG32(UVD_RBC_RB_RPTR);
2673}
2674
2675uint32_t r600_uvd_get_wptr(struct radeon_device *rdev,
2676 struct radeon_ring *ring)
2677{
2678 return RREG32(UVD_RBC_RB_WPTR);
2679}
2680
2681void r600_uvd_set_wptr(struct radeon_device *rdev,
2682 struct radeon_ring *ring)
2683{
2684 WREG32(UVD_RBC_RB_WPTR, ring->wptr);
2685}
2686
2687static int r600_uvd_rbc_start(struct radeon_device *rdev, bool ring_test)
2688{
2689 struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
2690 uint32_t rb_bufsz, tmp;
2691 int r;
2692
2693 /* force RBC into idle state */
2694 WREG32(UVD_RBC_RB_CNTL, 0x11010101);
2695
2696 /* Set the write pointer delay */
2697 WREG32(UVD_RBC_RB_WPTR_CNTL, 0);
2698
2699 /* programm the 4GB memory segment for rptr and ring buffer */
2700 WREG32(UVD_LMI_EXT40_ADDR, upper_32_bits(ring->gpu_addr) |
2701 (0x7 << 16) | (0x1 << 31));
2702
2703 /* Initialize the ring buffer's read and write pointers */
2704 WREG32(UVD_RBC_RB_RPTR, 0x0);
2705
2706 ring->wptr = ring->rptr = RREG32(UVD_RBC_RB_RPTR);
2707 WREG32(UVD_RBC_RB_WPTR, ring->wptr);
2708
2709 /* set the ring address */
2710 WREG32(UVD_RBC_RB_BASE, ring->gpu_addr);
2711
2712 /* Set ring buffer size */
2713 rb_bufsz = drm_order(ring->ring_size);
2714 rb_bufsz = (0x1 << 8) | rb_bufsz;
2715 WREG32_P(UVD_RBC_RB_CNTL, rb_bufsz, ~0x11f1f);
2716
2717 if (ring_test) {
2718 ring->ready = true;
2719 r = radeon_ring_test(rdev, R600_RING_TYPE_UVD_INDEX, ring);
2720 if (r) {
2721 ring->ready = false;
2722 return r;
2723 }
2724
2725 r = radeon_ring_lock(rdev, ring, 10);
2726 if (r) {
2727 DRM_ERROR("radeon: ring failed to lock UVD ring (%d).\n", r);
2728 return r;
2729 }
2730
2731 tmp = PACKET0(UVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL, 0);
2732 radeon_ring_write(ring, tmp);
2733 radeon_ring_write(ring, 0xFFFFF);
2734
2735 tmp = PACKET0(UVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL, 0);
2736 radeon_ring_write(ring, tmp);
2737 radeon_ring_write(ring, 0xFFFFF);
2738
2739 tmp = PACKET0(UVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL, 0);
2740 radeon_ring_write(ring, tmp);
2741 radeon_ring_write(ring, 0xFFFFF);
2742
2743 /* Clear timeout status bits */
2744 radeon_ring_write(ring, PACKET0(UVD_SEMA_TIMEOUT_STATUS, 0));
2745 radeon_ring_write(ring, 0x8);
2746
2747 radeon_ring_write(ring, PACKET0(UVD_SEMA_CNTL, 0));
2748 radeon_ring_write(ring, 3);
2749
2750 radeon_ring_unlock_commit(rdev, ring);
2751 }
2752
2753 return 0;
2754}
2755
2756void r600_do_uvd_stop(struct radeon_device *rdev)
2757{
2758 /* force RBC into idle state */
2759 WREG32(UVD_RBC_RB_CNTL, 0x11010101);
2760
2761 /* Stall UMC and register bus before resetting VCPU */
2762 WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
2763 WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
2764 mdelay(1);
2765
2766 /* put VCPU into reset */
2767 WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
2768 mdelay(5);
2769
2770 /* disable VCPU clock */
2771 WREG32(UVD_VCPU_CNTL, 0x0);
2772
2773 /* Unstall UMC and register bus */
2774 WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
2775 WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
2776}
2777
2778void r600_uvd_stop(struct radeon_device *rdev)
2779{
2780 struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
2781
2782 r600_do_uvd_stop(rdev);
2783 ring->ready = false;
2784}
2785
2786int r600_uvd_init(struct radeon_device *rdev, bool ring_test)
2787{
2788 int i, j, r;
2789 /* disable byte swapping */
2790 u32 lmi_swap_cntl = 0;
2791 u32 mp_swap_cntl = 0;
2792
2793 /* raise clocks while booting up the VCPU */
2794 radeon_set_uvd_clocks(rdev, 53300, 40000);
2795
2796 /* disable clock gating */
2797 WREG32(UVD_CGC_GATE, 0);
2798
2799 /* disable interupt */
2800 WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1));
2801
2802 /* Stall UMC and register bus before resetting VCPU */
2803 WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
2804 WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
2805 mdelay(1);
2806
2807 /* put LMI, VCPU, RBC etc... into reset */
2808 WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET |
2809 LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET |
2810 CXW_SOFT_RESET | TAP_SOFT_RESET | LMI_UMC_SOFT_RESET);
2811 mdelay(5);
2812
2813 /* take UVD block out of reset */
2814 WREG32_P(SRBM_SOFT_RESET, 0, ~SOFT_RESET_UVD);
2815 mdelay(5);
2816
2817 /* initialize UVD memory controller */
2818 WREG32(UVD_LMI_CTRL, 0x40 | (1 << 8) | (1 << 13) |
2819 (1 << 21) | (1 << 9) | (1 << 20));
2820
2821#ifdef __BIG_ENDIAN
2822 /* swap (8 in 32) RB and IB */
2823 lmi_swap_cntl = 0xa;
2824 mp_swap_cntl = 0;
2825#endif
2826 WREG32(UVD_LMI_SWAP_CNTL, lmi_swap_cntl);
2827 WREG32(UVD_MP_SWAP_CNTL, mp_swap_cntl);
2828
2829 WREG32(UVD_MPC_SET_MUXA0, 0x40c2040);
2830 WREG32(UVD_MPC_SET_MUXA1, 0x0);
2831 WREG32(UVD_MPC_SET_MUXB0, 0x40c2040);
2832 WREG32(UVD_MPC_SET_MUXB1, 0x0);
2833 WREG32(UVD_MPC_SET_ALU, 0);
2834 WREG32(UVD_MPC_SET_MUX, 0x88);
2835
2836 /* take all subblocks out of reset, except VCPU */
2837 WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
2838 mdelay(5);
2839
2840 /* enable VCPU clock */
2841 WREG32(UVD_VCPU_CNTL, 1 << 9);
2842
2843 /* enable UMC */
2844 WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
2845
2846 /* boot up the VCPU */
2847 WREG32(UVD_SOFT_RESET, 0);
2848 mdelay(10);
2849
2850 WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
2851
2852 for (i = 0; i < 10; ++i) {
2853 uint32_t status;
2854 for (j = 0; j < 100; ++j) {
2855 status = RREG32(UVD_STATUS);
2856 if (status & 2)
2857 break;
2858 mdelay(10);
2859 }
2860 r = 0;
2861 if (status & 2)
2862 break;
2863
2864 DRM_ERROR("UVD not responding, trying to reset the VCPU!!!\n");
2865 WREG32_P(UVD_SOFT_RESET, VCPU_SOFT_RESET, ~VCPU_SOFT_RESET);
2866 mdelay(10);
2867 WREG32_P(UVD_SOFT_RESET, 0, ~VCPU_SOFT_RESET);
2868 mdelay(10);
2869 r = -1;
2870 }
2871
2872 if (r) {
2873 DRM_ERROR("UVD not responding, giving up!!!\n");
2874 goto done;
2875 }
2876
2877 /* enable interupt */
2878 WREG32_P(UVD_MASTINT_EN, 3<<1, ~(3 << 1));
2879
2880 r = r600_uvd_rbc_start(rdev, ring_test);
2881 if (!r)
2882 DRM_INFO("UVD initialized successfully.\n");
2883
2884done:
2885 /* lower clocks again */
2886 radeon_set_uvd_clocks(rdev, 0, 0);
2887
2888 return r;
2889}
2890
2891/*
2892 * GPU scratch registers helpers function. 2667 * GPU scratch registers helpers function.
2893 */ 2668 */
2894void r600_scratch_init(struct radeon_device *rdev) 2669void r600_scratch_init(struct radeon_device *rdev)
@@ -2997,40 +2772,6 @@ int r600_dma_ring_test(struct radeon_device *rdev,
2997 return r; 2772 return r;
2998} 2773}
2999 2774
3000int r600_uvd_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
3001{
3002 uint32_t tmp = 0;
3003 unsigned i;
3004 int r;
3005
3006 WREG32(UVD_CONTEXT_ID, 0xCAFEDEAD);
3007 r = radeon_ring_lock(rdev, ring, 3);
3008 if (r) {
3009 DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n",
3010 ring->idx, r);
3011 return r;
3012 }
3013 radeon_ring_write(ring, PACKET0(UVD_CONTEXT_ID, 0));
3014 radeon_ring_write(ring, 0xDEADBEEF);
3015 radeon_ring_unlock_commit(rdev, ring);
3016 for (i = 0; i < rdev->usec_timeout; i++) {
3017 tmp = RREG32(UVD_CONTEXT_ID);
3018 if (tmp == 0xDEADBEEF)
3019 break;
3020 DRM_UDELAY(1);
3021 }
3022
3023 if (i < rdev->usec_timeout) {
3024 DRM_INFO("ring test on %d succeeded in %d usecs\n",
3025 ring->idx, i);
3026 } else {
3027 DRM_ERROR("radeon: ring %d test failed (0x%08X)\n",
3028 ring->idx, tmp);
3029 r = -EINVAL;
3030 }
3031 return r;
3032}
3033
3034/* 2775/*
3035 * CP fences/semaphores 2776 * CP fences/semaphores
3036 */ 2777 */
@@ -3082,30 +2823,6 @@ void r600_fence_ring_emit(struct radeon_device *rdev,
3082 } 2823 }
3083} 2824}
3084 2825
3085void r600_uvd_fence_emit(struct radeon_device *rdev,
3086 struct radeon_fence *fence)
3087{
3088 struct radeon_ring *ring = &rdev->ring[fence->ring];
3089 uint64_t addr = rdev->fence_drv[fence->ring].gpu_addr;
3090
3091 radeon_ring_write(ring, PACKET0(UVD_CONTEXT_ID, 0));
3092 radeon_ring_write(ring, fence->seq);
3093 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0));
3094 radeon_ring_write(ring, addr & 0xffffffff);
3095 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0));
3096 radeon_ring_write(ring, upper_32_bits(addr) & 0xff);
3097 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0));
3098 radeon_ring_write(ring, 0);
3099
3100 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0));
3101 radeon_ring_write(ring, 0);
3102 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0));
3103 radeon_ring_write(ring, 0);
3104 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0));
3105 radeon_ring_write(ring, 2);
3106 return;
3107}
3108
3109void r600_semaphore_ring_emit(struct radeon_device *rdev, 2826void r600_semaphore_ring_emit(struct radeon_device *rdev,
3110 struct radeon_ring *ring, 2827 struct radeon_ring *ring,
3111 struct radeon_semaphore *semaphore, 2828 struct radeon_semaphore *semaphore,
@@ -3175,23 +2892,6 @@ void r600_dma_semaphore_ring_emit(struct radeon_device *rdev,
3175 radeon_ring_write(ring, upper_32_bits(addr) & 0xff); 2892 radeon_ring_write(ring, upper_32_bits(addr) & 0xff);
3176} 2893}
3177 2894
3178void r600_uvd_semaphore_emit(struct radeon_device *rdev,
3179 struct radeon_ring *ring,
3180 struct radeon_semaphore *semaphore,
3181 bool emit_wait)
3182{
3183 uint64_t addr = semaphore->gpu_addr;
3184
3185 radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0));
3186 radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF);
3187
3188 radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0));
3189 radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF);
3190
3191 radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0));
3192 radeon_ring_write(ring, emit_wait ? 1 : 0);
3193}
3194
3195/** 2895/**
3196 * r600_copy_cpdma - copy pages using the CP DMA engine 2896 * r600_copy_cpdma - copy pages using the CP DMA engine
3197 * 2897 *
@@ -3656,16 +3356,6 @@ void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
3656 radeon_ring_write(ring, ib->length_dw); 3356 radeon_ring_write(ring, ib->length_dw);
3657} 3357}
3658 3358
3659void r600_uvd_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
3660{
3661 struct radeon_ring *ring = &rdev->ring[ib->ring];
3662
3663 radeon_ring_write(ring, PACKET0(UVD_RBC_IB_BASE, 0));
3664 radeon_ring_write(ring, ib->gpu_addr);
3665 radeon_ring_write(ring, PACKET0(UVD_RBC_IB_SIZE, 0));
3666 radeon_ring_write(ring, ib->length_dw);
3667}
3668
3669int r600_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) 3359int r600_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
3670{ 3360{
3671 struct radeon_ib ib; 3361 struct radeon_ib ib;
@@ -3783,41 +3473,6 @@ int r600_dma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
3783 return r; 3473 return r;
3784} 3474}
3785 3475
3786int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
3787{
3788 struct radeon_fence *fence = NULL;
3789 int r;
3790
3791 r = radeon_set_uvd_clocks(rdev, 53300, 40000);
3792 if (r) {
3793 DRM_ERROR("radeon: failed to raise UVD clocks (%d).\n", r);
3794 return r;
3795 }
3796
3797 r = radeon_uvd_get_create_msg(rdev, ring->idx, 1, NULL);
3798 if (r) {
3799 DRM_ERROR("radeon: failed to get create msg (%d).\n", r);
3800 goto error;
3801 }
3802
3803 r = radeon_uvd_get_destroy_msg(rdev, ring->idx, 1, &fence);
3804 if (r) {
3805 DRM_ERROR("radeon: failed to get destroy ib (%d).\n", r);
3806 goto error;
3807 }
3808
3809 r = radeon_fence_wait(fence, false);
3810 if (r) {
3811 DRM_ERROR("radeon: fence wait failed (%d).\n", r);
3812 goto error;
3813 }
3814 DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
3815error:
3816 radeon_fence_unref(&fence);
3817 radeon_set_uvd_clocks(rdev, 0, 0);
3818 return r;
3819}
3820
3821/** 3476/**
3822 * r600_dma_ring_ib_execute - Schedule an IB on the DMA engine 3477 * r600_dma_ring_ib_execute - Schedule an IB on the DMA engine
3823 * 3478 *
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
index 785b7a7add77..da755bf37421 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -1150,16 +1150,16 @@ static struct radeon_asic rs780_asic = {
1150}; 1150};
1151 1151
1152static struct radeon_asic_ring rv770_uvd_ring = { 1152static struct radeon_asic_ring rv770_uvd_ring = {
1153 .ib_execute = &r600_uvd_ib_execute, 1153 .ib_execute = &uvd_v1_0_ib_execute,
1154 .emit_fence = &r600_uvd_fence_emit, 1154 .emit_fence = &uvd_v2_2_fence_emit,
1155 .emit_semaphore = &r600_uvd_semaphore_emit, 1155 .emit_semaphore = &uvd_v1_0_semaphore_emit,
1156 .cs_parse = &radeon_uvd_cs_parse, 1156 .cs_parse = &radeon_uvd_cs_parse,
1157 .ring_test = &r600_uvd_ring_test, 1157 .ring_test = &uvd_v1_0_ring_test,
1158 .ib_test = &r600_uvd_ib_test, 1158 .ib_test = &uvd_v1_0_ib_test,
1159 .is_lockup = &radeon_ring_test_lockup, 1159 .is_lockup = &radeon_ring_test_lockup,
1160 .get_rptr = &r600_uvd_get_rptr, 1160 .get_rptr = &uvd_v1_0_get_rptr,
1161 .get_wptr = &r600_uvd_get_wptr, 1161 .get_wptr = &uvd_v1_0_get_wptr,
1162 .set_wptr = &r600_uvd_set_wptr, 1162 .set_wptr = &uvd_v1_0_set_wptr,
1163}; 1163};
1164 1164
1165static struct radeon_asic rv770_asic = { 1165static struct radeon_asic rv770_asic = {
@@ -1586,16 +1586,16 @@ static struct radeon_asic_ring cayman_dma_ring = {
1586}; 1586};
1587 1587
1588static struct radeon_asic_ring cayman_uvd_ring = { 1588static struct radeon_asic_ring cayman_uvd_ring = {
1589 .ib_execute = &r600_uvd_ib_execute, 1589 .ib_execute = &uvd_v1_0_ib_execute,
1590 .emit_fence = &r600_uvd_fence_emit, 1590 .emit_fence = &uvd_v2_2_fence_emit,
1591 .emit_semaphore = &cayman_uvd_semaphore_emit, 1591 .emit_semaphore = &uvd_v3_1_semaphore_emit,
1592 .cs_parse = &radeon_uvd_cs_parse, 1592 .cs_parse = &radeon_uvd_cs_parse,
1593 .ring_test = &r600_uvd_ring_test, 1593 .ring_test = &uvd_v1_0_ring_test,
1594 .ib_test = &r600_uvd_ib_test, 1594 .ib_test = &uvd_v1_0_ib_test,
1595 .is_lockup = &radeon_ring_test_lockup, 1595 .is_lockup = &radeon_ring_test_lockup,
1596 .get_rptr = &r600_uvd_get_rptr, 1596 .get_rptr = &uvd_v1_0_get_rptr,
1597 .get_wptr = &r600_uvd_get_wptr, 1597 .get_wptr = &uvd_v1_0_get_wptr,
1598 .set_wptr = &r600_uvd_set_wptr, 1598 .set_wptr = &uvd_v1_0_set_wptr,
1599}; 1599};
1600 1600
1601static struct radeon_asic cayman_asic = { 1601static struct radeon_asic cayman_asic = {
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 5c53eb78b22d..e69f00a7f153 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -336,7 +336,6 @@ int r600_dma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
336void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); 336void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
337int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); 337int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *cp);
338int r600_dma_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); 338int r600_dma_ring_test(struct radeon_device *rdev, struct radeon_ring *cp);
339int r600_uvd_ring_test(struct radeon_device *rdev, struct radeon_ring *ring);
340int r600_copy_cpdma(struct radeon_device *rdev, 339int r600_copy_cpdma(struct radeon_device *rdev,
341 uint64_t src_offset, uint64_t dst_offset, 340 uint64_t src_offset, uint64_t dst_offset,
342 unsigned num_gpu_pages, struct radeon_fence **fence); 341 unsigned num_gpu_pages, struct radeon_fence **fence);
@@ -430,24 +429,6 @@ void rs780_dpm_print_power_state(struct radeon_device *rdev,
430void rs780_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, 429void rs780_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
431 struct seq_file *m); 430 struct seq_file *m);
432 431
433/* uvd */
434uint32_t r600_uvd_get_rptr(struct radeon_device *rdev,
435 struct radeon_ring *ring);
436uint32_t r600_uvd_get_wptr(struct radeon_device *rdev,
437 struct radeon_ring *ring);
438void r600_uvd_set_wptr(struct radeon_device *rdev,
439 struct radeon_ring *ring);
440int r600_uvd_init(struct radeon_device *rdev, bool ring_test);
441void r600_uvd_stop(struct radeon_device *rdev);
442int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
443void r600_uvd_fence_emit(struct radeon_device *rdev,
444 struct radeon_fence *fence);
445void r600_uvd_semaphore_emit(struct radeon_device *rdev,
446 struct radeon_ring *ring,
447 struct radeon_semaphore *semaphore,
448 bool emit_wait);
449void r600_uvd_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
450
451/* 432/*
452 * rv770,rv730,rv710,rv740 433 * rv770,rv730,rv710,rv740
453 */ 434 */
@@ -465,7 +446,6 @@ int rv770_copy_dma(struct radeon_device *rdev,
465 unsigned num_gpu_pages, 446 unsigned num_gpu_pages,
466 struct radeon_fence **fence); 447 struct radeon_fence **fence);
467u32 rv770_get_xclk(struct radeon_device *rdev); 448u32 rv770_get_xclk(struct radeon_device *rdev);
468int rv770_uvd_resume(struct radeon_device *rdev);
469int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); 449int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
470int rv770_get_temp(struct radeon_device *rdev); 450int rv770_get_temp(struct radeon_device *rdev);
471/* rv7xx pm */ 451/* rv7xx pm */
@@ -800,4 +780,39 @@ int kv_dpm_force_performance_level(struct radeon_device *rdev,
800 enum radeon_dpm_forced_level level); 780 enum radeon_dpm_forced_level level);
801void kv_dpm_powergate_uvd(struct radeon_device *rdev, bool gate); 781void kv_dpm_powergate_uvd(struct radeon_device *rdev, bool gate);
802 782
783/* uvd v1.0 */
784uint32_t uvd_v1_0_get_rptr(struct radeon_device *rdev,
785 struct radeon_ring *ring);
786uint32_t uvd_v1_0_get_wptr(struct radeon_device *rdev,
787 struct radeon_ring *ring);
788void uvd_v1_0_set_wptr(struct radeon_device *rdev,
789 struct radeon_ring *ring);
790
791int uvd_v1_0_init(struct radeon_device *rdev);
792void uvd_v1_0_fini(struct radeon_device *rdev);
793int uvd_v1_0_start(struct radeon_device *rdev);
794void uvd_v1_0_stop(struct radeon_device *rdev);
795
796int uvd_v1_0_ring_test(struct radeon_device *rdev, struct radeon_ring *ring);
797int uvd_v1_0_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
798void uvd_v1_0_semaphore_emit(struct radeon_device *rdev,
799 struct radeon_ring *ring,
800 struct radeon_semaphore *semaphore,
801 bool emit_wait);
802void uvd_v1_0_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
803
804/* uvd v2.2 */
805int uvd_v2_2_resume(struct radeon_device *rdev);
806void uvd_v2_2_fence_emit(struct radeon_device *rdev,
807 struct radeon_fence *fence);
808
809/* uvd v3.1 */
810void uvd_v3_1_semaphore_emit(struct radeon_device *rdev,
811 struct radeon_ring *ring,
812 struct radeon_semaphore *semaphore,
813 bool emit_wait);
814
815/* uvd v4.2 */
816int uvd_v4_2_resume(struct radeon_device *rdev);
817
803#endif 818#endif
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index fd9dcb2d182b..aaab7b1bba27 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -801,103 +801,6 @@ u32 rv770_get_xclk(struct radeon_device *rdev)
801 return reference_clock; 801 return reference_clock;
802} 802}
803 803
804int rv770_uvd_resume(struct radeon_device *rdev)
805{
806 uint64_t addr;
807 uint32_t chip_id, size;
808 int r;
809
810 r = radeon_uvd_resume(rdev);
811 if (r)
812 return r;
813
814 /* programm the VCPU memory controller bits 0-27 */
815 addr = rdev->uvd.gpu_addr >> 3;
816 size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3;
817 WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
818 WREG32(UVD_VCPU_CACHE_SIZE0, size);
819
820 addr += size;
821 size = RADEON_UVD_STACK_SIZE >> 3;
822 WREG32(UVD_VCPU_CACHE_OFFSET1, addr);
823 WREG32(UVD_VCPU_CACHE_SIZE1, size);
824
825 addr += size;
826 size = RADEON_UVD_HEAP_SIZE >> 3;
827 WREG32(UVD_VCPU_CACHE_OFFSET2, addr);
828 WREG32(UVD_VCPU_CACHE_SIZE2, size);
829
830 /* bits 28-31 */
831 addr = (rdev->uvd.gpu_addr >> 28) & 0xF;
832 WREG32(UVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0));
833
834 /* bits 32-39 */
835 addr = (rdev->uvd.gpu_addr >> 32) & 0xFF;
836 WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31));
837
838 /* tell firmware which hardware it is running on */
839 switch (rdev->family) {
840 default:
841 return -EINVAL;
842 case CHIP_RV710:
843 chip_id = 0x01000005;
844 break;
845 case CHIP_RV730:
846 chip_id = 0x01000006;
847 break;
848 case CHIP_RV740:
849 chip_id = 0x01000007;
850 break;
851 case CHIP_CYPRESS:
852 case CHIP_HEMLOCK:
853 chip_id = 0x01000008;
854 break;
855 case CHIP_JUNIPER:
856 chip_id = 0x01000009;
857 break;
858 case CHIP_REDWOOD:
859 chip_id = 0x0100000a;
860 break;
861 case CHIP_CEDAR:
862 chip_id = 0x0100000b;
863 break;
864 case CHIP_SUMO:
865 case CHIP_SUMO2:
866 chip_id = 0x0100000c;
867 break;
868 case CHIP_PALM:
869 chip_id = 0x0100000e;
870 break;
871 case CHIP_CAYMAN:
872 chip_id = 0x0100000f;
873 break;
874 case CHIP_BARTS:
875 chip_id = 0x01000010;
876 break;
877 case CHIP_TURKS:
878 chip_id = 0x01000011;
879 break;
880 case CHIP_CAICOS:
881 chip_id = 0x01000012;
882 break;
883 case CHIP_TAHITI:
884 chip_id = 0x01000014;
885 break;
886 case CHIP_VERDE:
887 chip_id = 0x01000015;
888 break;
889 case CHIP_PITCAIRN:
890 chip_id = 0x01000016;
891 break;
892 case CHIP_ARUBA:
893 chip_id = 0x01000017;
894 break;
895 }
896 WREG32(UVD_VCPU_CHIP_ID, chip_id);
897
898 return 0;
899}
900
901u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) 804u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
902{ 805{
903 struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; 806 struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
@@ -1870,7 +1773,7 @@ static int rv770_startup(struct radeon_device *rdev)
1870 return r; 1773 return r;
1871 } 1774 }
1872 1775
1873 r = rv770_uvd_resume(rdev); 1776 r = uvd_v2_2_resume(rdev);
1874 if (!r) { 1777 if (!r) {
1875 r = radeon_fence_driver_start_ring(rdev, 1778 r = radeon_fence_driver_start_ring(rdev,
1876 R600_RING_TYPE_UVD_INDEX); 1779 R600_RING_TYPE_UVD_INDEX);
@@ -1927,7 +1830,7 @@ static int rv770_startup(struct radeon_device *rdev)
1927 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, 1830 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
1928 RADEON_CP_PACKET2); 1831 RADEON_CP_PACKET2);
1929 if (!r) 1832 if (!r)
1930 r = r600_uvd_init(rdev, true); 1833 r = uvd_v1_0_init(rdev);
1931 1834
1932 if (r) 1835 if (r)
1933 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); 1836 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
@@ -1977,7 +1880,7 @@ int rv770_resume(struct radeon_device *rdev)
1977int rv770_suspend(struct radeon_device *rdev) 1880int rv770_suspend(struct radeon_device *rdev)
1978{ 1881{
1979 r600_audio_fini(rdev); 1882 r600_audio_fini(rdev);
1980 r600_uvd_stop(rdev); 1883 uvd_v1_0_fini(rdev);
1981 radeon_uvd_suspend(rdev); 1884 radeon_uvd_suspend(rdev);
1982 r700_cp_stop(rdev); 1885 r700_cp_stop(rdev);
1983 r600_dma_stop(rdev); 1886 r600_dma_stop(rdev);
@@ -2092,7 +1995,7 @@ void rv770_fini(struct radeon_device *rdev)
2092 radeon_ib_pool_fini(rdev); 1995 radeon_ib_pool_fini(rdev);
2093 radeon_irq_kms_fini(rdev); 1996 radeon_irq_kms_fini(rdev);
2094 rv770_pcie_gart_fini(rdev); 1997 rv770_pcie_gart_fini(rdev);
2095 r600_uvd_stop(rdev); 1998 uvd_v1_0_fini(rdev);
2096 radeon_uvd_fini(rdev); 1999 radeon_uvd_fini(rdev);
2097 r600_vram_scratch_fini(rdev); 2000 r600_vram_scratch_fini(rdev);
2098 radeon_gem_fini(rdev); 2001 radeon_gem_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h
index 6bef2b7d601b..9fe60e542922 100644
--- a/drivers/gpu/drm/radeon/rv770d.h
+++ b/drivers/gpu/drm/radeon/rv770d.h
@@ -971,7 +971,21 @@
971# define TARGET_LINK_SPEED_MASK (0xf << 0) 971# define TARGET_LINK_SPEED_MASK (0xf << 0)
972# define SELECTABLE_DEEMPHASIS (1 << 6) 972# define SELECTABLE_DEEMPHASIS (1 << 6)
973 973
974/*
975 * PM4
976 */
977#define PACKET0(reg, n) ((RADEON_PACKET_TYPE0 << 30) | \
978 (((reg) >> 2) & 0xFFFF) | \
979 ((n) & 0x3FFF) << 16)
980#define PACKET3(op, n) ((RADEON_PACKET_TYPE3 << 30) | \
981 (((op) & 0xFF) << 8) | \
982 ((n) & 0x3FFF) << 16)
983
974/* UVD */ 984/* UVD */
985#define UVD_GPCOM_VCPU_CMD 0xef0c
986#define UVD_GPCOM_VCPU_DATA0 0xef10
987#define UVD_GPCOM_VCPU_DATA1 0xef14
988
975#define UVD_LMI_EXT40_ADDR 0xf498 989#define UVD_LMI_EXT40_ADDR 0xf498
976#define UVD_VCPU_CHIP_ID 0xf4d4 990#define UVD_VCPU_CHIP_ID 0xf4d4
977#define UVD_VCPU_CACHE_OFFSET0 0xf4d8 991#define UVD_VCPU_CACHE_OFFSET0 0xf4d8
@@ -985,4 +999,6 @@
985#define UVD_RBC_RB_RPTR 0xf690 999#define UVD_RBC_RB_RPTR 0xf690
986#define UVD_RBC_RB_WPTR 0xf694 1000#define UVD_RBC_RB_WPTR 0xf694
987 1001
1002#define UVD_CONTEXT_ID 0xf6f4
1003
988#endif 1004#endif
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index ae232be62921..f3f79089405e 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -6339,7 +6339,7 @@ static int si_startup(struct radeon_device *rdev)
6339 } 6339 }
6340 6340
6341 if (rdev->has_uvd) { 6341 if (rdev->has_uvd) {
6342 r = rv770_uvd_resume(rdev); 6342 r = uvd_v2_2_resume(rdev);
6343 if (!r) { 6343 if (!r) {
6344 r = radeon_fence_driver_start_ring(rdev, 6344 r = radeon_fence_driver_start_ring(rdev,
6345 R600_RING_TYPE_UVD_INDEX); 6345 R600_RING_TYPE_UVD_INDEX);
@@ -6420,7 +6420,7 @@ static int si_startup(struct radeon_device *rdev)
6420 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, 6420 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
6421 RADEON_CP_PACKET2); 6421 RADEON_CP_PACKET2);
6422 if (!r) 6422 if (!r)
6423 r = r600_uvd_init(rdev, true); 6423 r = uvd_v1_0_init(rdev);
6424 if (r) 6424 if (r)
6425 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); 6425 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
6426 } 6426 }
@@ -6473,7 +6473,7 @@ int si_suspend(struct radeon_device *rdev)
6473 si_cp_enable(rdev, false); 6473 si_cp_enable(rdev, false);
6474 cayman_dma_stop(rdev); 6474 cayman_dma_stop(rdev);
6475 if (rdev->has_uvd) { 6475 if (rdev->has_uvd) {
6476 r600_uvd_stop(rdev); 6476 uvd_v1_0_fini(rdev);
6477 radeon_uvd_suspend(rdev); 6477 radeon_uvd_suspend(rdev);
6478 } 6478 }
6479 si_irq_suspend(rdev); 6479 si_irq_suspend(rdev);
@@ -6616,7 +6616,7 @@ void si_fini(struct radeon_device *rdev)
6616 radeon_ib_pool_fini(rdev); 6616 radeon_ib_pool_fini(rdev);
6617 radeon_irq_kms_fini(rdev); 6617 radeon_irq_kms_fini(rdev);
6618 if (rdev->has_uvd) { 6618 if (rdev->has_uvd) {
6619 r600_uvd_stop(rdev); 6619 uvd_v1_0_fini(rdev);
6620 radeon_uvd_fini(rdev); 6620 radeon_uvd_fini(rdev);
6621 } 6621 }
6622 si_pcie_gart_fini(rdev); 6622 si_pcie_gart_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/uvd_v1_0.c b/drivers/gpu/drm/radeon/uvd_v1_0.c
new file mode 100644
index 000000000000..76ca669f0c8e
--- /dev/null
+++ b/drivers/gpu/drm/radeon/uvd_v1_0.c
@@ -0,0 +1,434 @@
1/*
2 * Copyright 2013 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Christian König <christian.koenig@amd.com>
23 */
24
25#include <drm/drmP.h>
26#include "radeon.h"
27#include "radeon_asic.h"
28#include "r600d.h"
29
30/**
31 * uvd_v1_0_get_rptr - get read pointer
32 *
33 * @rdev: radeon_device pointer
34 * @ring: radeon_ring pointer
35 *
36 * Returns the current hardware read pointer
37 */
38uint32_t uvd_v1_0_get_rptr(struct radeon_device *rdev,
39 struct radeon_ring *ring)
40{
41 return RREG32(UVD_RBC_RB_RPTR);
42}
43
44/**
45 * uvd_v1_0_get_wptr - get write pointer
46 *
47 * @rdev: radeon_device pointer
48 * @ring: radeon_ring pointer
49 *
50 * Returns the current hardware write pointer
51 */
52uint32_t uvd_v1_0_get_wptr(struct radeon_device *rdev,
53 struct radeon_ring *ring)
54{
55 return RREG32(UVD_RBC_RB_WPTR);
56}
57
58/**
59 * uvd_v1_0_set_wptr - set write pointer
60 *
61 * @rdev: radeon_device pointer
62 * @ring: radeon_ring pointer
63 *
64 * Commits the write pointer to the hardware
65 */
66void uvd_v1_0_set_wptr(struct radeon_device *rdev,
67 struct radeon_ring *ring)
68{
69 WREG32(UVD_RBC_RB_WPTR, ring->wptr);
70}
71
72/**
73 * uvd_v1_0_init - start and test UVD block
74 *
75 * @rdev: radeon_device pointer
76 *
77 * Initialize the hardware, boot up the VCPU and do some testing
78 */
79int uvd_v1_0_init(struct radeon_device *rdev)
80{
81 struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
82 uint32_t tmp;
83 int r;
84
85 /* raise clocks while booting up the VCPU */
86 radeon_set_uvd_clocks(rdev, 53300, 40000);
87
88 uvd_v1_0_start(rdev);
89
90 ring->ready = true;
91 r = radeon_ring_test(rdev, R600_RING_TYPE_UVD_INDEX, ring);
92 if (r) {
93 ring->ready = false;
94 goto done;
95 }
96
97 r = radeon_ring_lock(rdev, ring, 10);
98 if (r) {
99 DRM_ERROR("radeon: ring failed to lock UVD ring (%d).\n", r);
100 goto done;
101 }
102
103 tmp = PACKET0(UVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL, 0);
104 radeon_ring_write(ring, tmp);
105 radeon_ring_write(ring, 0xFFFFF);
106
107 tmp = PACKET0(UVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL, 0);
108 radeon_ring_write(ring, tmp);
109 radeon_ring_write(ring, 0xFFFFF);
110
111 tmp = PACKET0(UVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL, 0);
112 radeon_ring_write(ring, tmp);
113 radeon_ring_write(ring, 0xFFFFF);
114
115 /* Clear timeout status bits */
116 radeon_ring_write(ring, PACKET0(UVD_SEMA_TIMEOUT_STATUS, 0));
117 radeon_ring_write(ring, 0x8);
118
119 radeon_ring_write(ring, PACKET0(UVD_SEMA_CNTL, 0));
120 radeon_ring_write(ring, 3);
121
122 radeon_ring_unlock_commit(rdev, ring);
123
124done:
125 /* lower clocks again */
126 radeon_set_uvd_clocks(rdev, 0, 0);
127
128 if (!r)
129 DRM_INFO("UVD initialized successfully.\n");
130
131 return r;
132}
133
134/**
135 * uvd_v1_0_fini - stop the hardware block
136 *
137 * @rdev: radeon_device pointer
138 *
139 * Stop the UVD block, mark ring as not ready any more
140 */
141void uvd_v1_0_fini(struct radeon_device *rdev)
142{
143 struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
144
145 uvd_v1_0_stop(rdev);
146 ring->ready = false;
147}
148
149/**
150 * uvd_v1_0_start - start UVD block
151 *
152 * @rdev: radeon_device pointer
153 *
154 * Setup and start the UVD block
155 */
156int uvd_v1_0_start(struct radeon_device *rdev)
157{
158 struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
159 uint32_t rb_bufsz;
160 int i, j, r;
161
162 /* disable byte swapping */
163 u32 lmi_swap_cntl = 0;
164 u32 mp_swap_cntl = 0;
165
166 /* disable clock gating */
167 WREG32(UVD_CGC_GATE, 0);
168
169 /* disable interupt */
170 WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1));
171
172 /* Stall UMC and register bus before resetting VCPU */
173 WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
174 WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
175 mdelay(1);
176
177 /* put LMI, VCPU, RBC etc... into reset */
178 WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET |
179 LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET |
180 CXW_SOFT_RESET | TAP_SOFT_RESET | LMI_UMC_SOFT_RESET);
181 mdelay(5);
182
183 /* take UVD block out of reset */
184 WREG32_P(SRBM_SOFT_RESET, 0, ~SOFT_RESET_UVD);
185 mdelay(5);
186
187 /* initialize UVD memory controller */
188 WREG32(UVD_LMI_CTRL, 0x40 | (1 << 8) | (1 << 13) |
189 (1 << 21) | (1 << 9) | (1 << 20));
190
191#ifdef __BIG_ENDIAN
192 /* swap (8 in 32) RB and IB */
193 lmi_swap_cntl = 0xa;
194 mp_swap_cntl = 0;
195#endif
196 WREG32(UVD_LMI_SWAP_CNTL, lmi_swap_cntl);
197 WREG32(UVD_MP_SWAP_CNTL, mp_swap_cntl);
198
199 WREG32(UVD_MPC_SET_MUXA0, 0x40c2040);
200 WREG32(UVD_MPC_SET_MUXA1, 0x0);
201 WREG32(UVD_MPC_SET_MUXB0, 0x40c2040);
202 WREG32(UVD_MPC_SET_MUXB1, 0x0);
203 WREG32(UVD_MPC_SET_ALU, 0);
204 WREG32(UVD_MPC_SET_MUX, 0x88);
205
206 /* take all subblocks out of reset, except VCPU */
207 WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
208 mdelay(5);
209
210 /* enable VCPU clock */
211 WREG32(UVD_VCPU_CNTL, 1 << 9);
212
213 /* enable UMC */
214 WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
215
216 /* boot up the VCPU */
217 WREG32(UVD_SOFT_RESET, 0);
218 mdelay(10);
219
220 WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
221
222 for (i = 0; i < 10; ++i) {
223 uint32_t status;
224 for (j = 0; j < 100; ++j) {
225 status = RREG32(UVD_STATUS);
226 if (status & 2)
227 break;
228 mdelay(10);
229 }
230 r = 0;
231 if (status & 2)
232 break;
233
234 DRM_ERROR("UVD not responding, trying to reset the VCPU!!!\n");
235 WREG32_P(UVD_SOFT_RESET, VCPU_SOFT_RESET, ~VCPU_SOFT_RESET);
236 mdelay(10);
237 WREG32_P(UVD_SOFT_RESET, 0, ~VCPU_SOFT_RESET);
238 mdelay(10);
239 r = -1;
240 }
241
242 if (r) {
243 DRM_ERROR("UVD not responding, giving up!!!\n");
244 return r;
245 }
246
247 /* enable interupt */
248 WREG32_P(UVD_MASTINT_EN, 3<<1, ~(3 << 1));
249
250 /* force RBC into idle state */
251 WREG32(UVD_RBC_RB_CNTL, 0x11010101);
252
253 /* Set the write pointer delay */
254 WREG32(UVD_RBC_RB_WPTR_CNTL, 0);
255
256 /* programm the 4GB memory segment for rptr and ring buffer */
257 WREG32(UVD_LMI_EXT40_ADDR, upper_32_bits(ring->gpu_addr) |
258 (0x7 << 16) | (0x1 << 31));
259
260 /* Initialize the ring buffer's read and write pointers */
261 WREG32(UVD_RBC_RB_RPTR, 0x0);
262
263 ring->wptr = ring->rptr = RREG32(UVD_RBC_RB_RPTR);
264 WREG32(UVD_RBC_RB_WPTR, ring->wptr);
265
266 /* set the ring address */
267 WREG32(UVD_RBC_RB_BASE, ring->gpu_addr);
268
269 /* Set ring buffer size */
270 rb_bufsz = drm_order(ring->ring_size);
271 rb_bufsz = (0x1 << 8) | rb_bufsz;
272 WREG32_P(UVD_RBC_RB_CNTL, rb_bufsz, ~0x11f1f);
273
274 return 0;
275}
276
277/**
278 * uvd_v1_0_stop - stop UVD block
279 *
280 * @rdev: radeon_device pointer
281 *
282 * stop the UVD block
283 */
284void uvd_v1_0_stop(struct radeon_device *rdev)
285{
286 /* force RBC into idle state */
287 WREG32(UVD_RBC_RB_CNTL, 0x11010101);
288
289 /* Stall UMC and register bus before resetting VCPU */
290 WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
291 WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
292 mdelay(1);
293
294 /* put VCPU into reset */
295 WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
296 mdelay(5);
297
298 /* disable VCPU clock */
299 WREG32(UVD_VCPU_CNTL, 0x0);
300
301 /* Unstall UMC and register bus */
302 WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
303 WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
304}
305
306/**
307 * uvd_v1_0_ring_test - register write test
308 *
309 * @rdev: radeon_device pointer
310 * @ring: radeon_ring pointer
311 *
312 * Test if we can successfully write to the context register
313 */
314int uvd_v1_0_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
315{
316 uint32_t tmp = 0;
317 unsigned i;
318 int r;
319
320 WREG32(UVD_CONTEXT_ID, 0xCAFEDEAD);
321 r = radeon_ring_lock(rdev, ring, 3);
322 if (r) {
323 DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n",
324 ring->idx, r);
325 return r;
326 }
327 radeon_ring_write(ring, PACKET0(UVD_CONTEXT_ID, 0));
328 radeon_ring_write(ring, 0xDEADBEEF);
329 radeon_ring_unlock_commit(rdev, ring);
330 for (i = 0; i < rdev->usec_timeout; i++) {
331 tmp = RREG32(UVD_CONTEXT_ID);
332 if (tmp == 0xDEADBEEF)
333 break;
334 DRM_UDELAY(1);
335 }
336
337 if (i < rdev->usec_timeout) {
338 DRM_INFO("ring test on %d succeeded in %d usecs\n",
339 ring->idx, i);
340 } else {
341 DRM_ERROR("radeon: ring %d test failed (0x%08X)\n",
342 ring->idx, tmp);
343 r = -EINVAL;
344 }
345 return r;
346}
347
348/**
349 * uvd_v1_0_semaphore_emit - emit semaphore command
350 *
351 * @rdev: radeon_device pointer
352 * @ring: radeon_ring pointer
353 * @semaphore: semaphore to emit commands for
354 * @emit_wait: true if we should emit a wait command
355 *
356 * Emit a semaphore command (either wait or signal) to the UVD ring.
357 */
358void uvd_v1_0_semaphore_emit(struct radeon_device *rdev,
359 struct radeon_ring *ring,
360 struct radeon_semaphore *semaphore,
361 bool emit_wait)
362{
363 uint64_t addr = semaphore->gpu_addr;
364
365 radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0));
366 radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF);
367
368 radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0));
369 radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF);
370
371 radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0));
372 radeon_ring_write(ring, emit_wait ? 1 : 0);
373}
374
375/**
376 * uvd_v1_0_ib_execute - execute indirect buffer
377 *
378 * @rdev: radeon_device pointer
379 * @ib: indirect buffer to execute
380 *
381 * Write ring commands to execute the indirect buffer
382 */
383void uvd_v1_0_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
384{
385 struct radeon_ring *ring = &rdev->ring[ib->ring];
386
387 radeon_ring_write(ring, PACKET0(UVD_RBC_IB_BASE, 0));
388 radeon_ring_write(ring, ib->gpu_addr);
389 radeon_ring_write(ring, PACKET0(UVD_RBC_IB_SIZE, 0));
390 radeon_ring_write(ring, ib->length_dw);
391}
392
393/**
394 * uvd_v1_0_ib_test - test ib execution
395 *
396 * @rdev: radeon_device pointer
397 * @ring: radeon_ring pointer
398 *
399 * Test if we can successfully execute an IB
400 */
401int uvd_v1_0_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
402{
403 struct radeon_fence *fence = NULL;
404 int r;
405
406 r = radeon_set_uvd_clocks(rdev, 53300, 40000);
407 if (r) {
408 DRM_ERROR("radeon: failed to raise UVD clocks (%d).\n", r);
409 return r;
410 }
411
412 r = radeon_uvd_get_create_msg(rdev, ring->idx, 1, NULL);
413 if (r) {
414 DRM_ERROR("radeon: failed to get create msg (%d).\n", r);
415 goto error;
416 }
417
418 r = radeon_uvd_get_destroy_msg(rdev, ring->idx, 1, &fence);
419 if (r) {
420 DRM_ERROR("radeon: failed to get destroy ib (%d).\n", r);
421 goto error;
422 }
423
424 r = radeon_fence_wait(fence, false);
425 if (r) {
426 DRM_ERROR("radeon: fence wait failed (%d).\n", r);
427 goto error;
428 }
429 DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
430error:
431 radeon_fence_unref(&fence);
432 radeon_set_uvd_clocks(rdev, 0, 0);
433 return r;
434}
diff --git a/drivers/gpu/drm/radeon/uvd_v2_2.c b/drivers/gpu/drm/radeon/uvd_v2_2.c
new file mode 100644
index 000000000000..b19ef4951085
--- /dev/null
+++ b/drivers/gpu/drm/radeon/uvd_v2_2.c
@@ -0,0 +1,165 @@
1/*
2 * Copyright 2013 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Christian König <christian.koenig@amd.com>
23 */
24
25#include <linux/firmware.h>
26#include <drm/drmP.h>
27#include "radeon.h"
28#include "radeon_asic.h"
29#include "rv770d.h"
30
31/**
32 * uvd_v2_2_fence_emit - emit an fence & trap command
33 *
34 * @rdev: radeon_device pointer
35 * @fence: fence to emit
36 *
37 * Write a fence and a trap command to the ring.
38 */
39void uvd_v2_2_fence_emit(struct radeon_device *rdev,
40 struct radeon_fence *fence)
41{
42 struct radeon_ring *ring = &rdev->ring[fence->ring];
43 uint64_t addr = rdev->fence_drv[fence->ring].gpu_addr;
44
45 radeon_ring_write(ring, PACKET0(UVD_CONTEXT_ID, 0));
46 radeon_ring_write(ring, fence->seq);
47 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0));
48 radeon_ring_write(ring, addr & 0xffffffff);
49 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0));
50 radeon_ring_write(ring, upper_32_bits(addr) & 0xff);
51 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0));
52 radeon_ring_write(ring, 0);
53
54 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0));
55 radeon_ring_write(ring, 0);
56 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0));
57 radeon_ring_write(ring, 0);
58 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0));
59 radeon_ring_write(ring, 2);
60 return;
61}
62
63/**
64 * uvd_v2_2_resume - memory controller programming
65 *
66 * @rdev: radeon_device pointer
67 *
68 * Let the UVD memory controller know it's offsets
69 */
70int uvd_v2_2_resume(struct radeon_device *rdev)
71{
72 uint64_t addr;
73 uint32_t chip_id, size;
74 int r;
75
76 r = radeon_uvd_resume(rdev);
77 if (r)
78 return r;
79
80 /* programm the VCPU memory controller bits 0-27 */
81 addr = rdev->uvd.gpu_addr >> 3;
82 size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3;
83 WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
84 WREG32(UVD_VCPU_CACHE_SIZE0, size);
85
86 addr += size;
87 size = RADEON_UVD_STACK_SIZE >> 3;
88 WREG32(UVD_VCPU_CACHE_OFFSET1, addr);
89 WREG32(UVD_VCPU_CACHE_SIZE1, size);
90
91 addr += size;
92 size = RADEON_UVD_HEAP_SIZE >> 3;
93 WREG32(UVD_VCPU_CACHE_OFFSET2, addr);
94 WREG32(UVD_VCPU_CACHE_SIZE2, size);
95
96 /* bits 28-31 */
97 addr = (rdev->uvd.gpu_addr >> 28) & 0xF;
98 WREG32(UVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0));
99
100 /* bits 32-39 */
101 addr = (rdev->uvd.gpu_addr >> 32) & 0xFF;
102 WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31));
103
104 /* tell firmware which hardware it is running on */
105 switch (rdev->family) {
106 default:
107 return -EINVAL;
108 case CHIP_RV710:
109 chip_id = 0x01000005;
110 break;
111 case CHIP_RV730:
112 chip_id = 0x01000006;
113 break;
114 case CHIP_RV740:
115 chip_id = 0x01000007;
116 break;
117 case CHIP_CYPRESS:
118 case CHIP_HEMLOCK:
119 chip_id = 0x01000008;
120 break;
121 case CHIP_JUNIPER:
122 chip_id = 0x01000009;
123 break;
124 case CHIP_REDWOOD:
125 chip_id = 0x0100000a;
126 break;
127 case CHIP_CEDAR:
128 chip_id = 0x0100000b;
129 break;
130 case CHIP_SUMO:
131 case CHIP_SUMO2:
132 chip_id = 0x0100000c;
133 break;
134 case CHIP_PALM:
135 chip_id = 0x0100000e;
136 break;
137 case CHIP_CAYMAN:
138 chip_id = 0x0100000f;
139 break;
140 case CHIP_BARTS:
141 chip_id = 0x01000010;
142 break;
143 case CHIP_TURKS:
144 chip_id = 0x01000011;
145 break;
146 case CHIP_CAICOS:
147 chip_id = 0x01000012;
148 break;
149 case CHIP_TAHITI:
150 chip_id = 0x01000014;
151 break;
152 case CHIP_VERDE:
153 chip_id = 0x01000015;
154 break;
155 case CHIP_PITCAIRN:
156 chip_id = 0x01000016;
157 break;
158 case CHIP_ARUBA:
159 chip_id = 0x01000017;
160 break;
161 }
162 WREG32(UVD_VCPU_CHIP_ID, chip_id);
163
164 return 0;
165}
diff --git a/drivers/gpu/drm/radeon/uvd_v3_1.c b/drivers/gpu/drm/radeon/uvd_v3_1.c
new file mode 100644
index 000000000000..5b6fa1f62d4e
--- /dev/null
+++ b/drivers/gpu/drm/radeon/uvd_v3_1.c
@@ -0,0 +1,55 @@
1/*
2 * Copyright 2013 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Christian König <christian.koenig@amd.com>
23 */
24
25#include <drm/drmP.h>
26#include "radeon.h"
27#include "radeon_asic.h"
28#include "nid.h"
29
30/**
31 * uvd_v3_1_semaphore_emit - emit semaphore command
32 *
33 * @rdev: radeon_device pointer
34 * @ring: radeon_ring pointer
35 * @semaphore: semaphore to emit commands for
36 * @emit_wait: true if we should emit a wait command
37 *
38 * Emit a semaphore command (either wait or signal) to the UVD ring.
39 */
40void uvd_v3_1_semaphore_emit(struct radeon_device *rdev,
41 struct radeon_ring *ring,
42 struct radeon_semaphore *semaphore,
43 bool emit_wait)
44{
45 uint64_t addr = semaphore->gpu_addr;
46
47 radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0));
48 radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF);
49
50 radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0));
51 radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF);
52
53 radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0));
54 radeon_ring_write(ring, 0x80 | (emit_wait ? 1 : 0));
55}
diff --git a/drivers/gpu/drm/radeon/uvd_v4_2.c b/drivers/gpu/drm/radeon/uvd_v4_2.c
new file mode 100644
index 000000000000..d7e480786098
--- /dev/null
+++ b/drivers/gpu/drm/radeon/uvd_v4_2.c
@@ -0,0 +1,73 @@
1/*
2 * Copyright 2013 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Christian König <christian.koenig@amd.com>
23 */
24
25#include <linux/firmware.h>
26#include <drm/drmP.h>
27#include "radeon.h"
28#include "radeon_asic.h"
29#include "cikd.h"
30
31/**
32 * uvd_v4_2_resume - memory controller programming
33 *
34 * @rdev: radeon_device pointer
35 *
36 * Let the UVD memory controller know it's offsets
37 */
38int uvd_v4_2_resume(struct radeon_device *rdev)
39{
40 uint64_t addr;
41 uint32_t size;
42 int r;
43
44 r = radeon_uvd_resume(rdev);
45 if (r)
46 return r;
47
48 /* programm the VCPU memory controller bits 0-27 */
49 addr = rdev->uvd.gpu_addr >> 3;
50 size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3;
51 WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
52 WREG32(UVD_VCPU_CACHE_SIZE0, size);
53
54 addr += size;
55 size = RADEON_UVD_STACK_SIZE >> 3;
56 WREG32(UVD_VCPU_CACHE_OFFSET1, addr);
57 WREG32(UVD_VCPU_CACHE_SIZE1, size);
58
59 addr += size;
60 size = RADEON_UVD_HEAP_SIZE >> 3;
61 WREG32(UVD_VCPU_CACHE_OFFSET2, addr);
62 WREG32(UVD_VCPU_CACHE_SIZE2, size);
63
64 /* bits 28-31 */
65 addr = (rdev->uvd.gpu_addr >> 28) & 0xF;
66 WREG32(UVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0));
67
68 /* bits 32-39 */
69 addr = (rdev->uvd.gpu_addr >> 32) & 0xFF;
70 WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31));
71
72 return 0;
73}