aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2013-08-06 11:39:38 -0400
committerAlex Deucher <alexander.deucher@amd.com>2013-08-30 16:30:34 -0400
commit5e884f606cdba9c599c9c9373808f272ae794088 (patch)
tree37ff80e016bf2b79d91bd4be289dcceab9691e93
parent9e9d976205626c3bd92776181cde6a2dda648c2b (diff)
drm/radeon: restructure UVD code to handle UVD PG (v2)
When we PG (powergate) UVD, we need to re-initialize it before we can use it again. v2: rebase on UVD stop fixes Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/radeon/cik.c14
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c2
-rw-r--r--drivers/gpu/drm/radeon/ni.c2
-rw-r--r--drivers/gpu/drm/radeon/r600.c74
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h4
-rw-r--r--drivers/gpu/drm/radeon/rv770.c2
-rw-r--r--drivers/gpu/drm/radeon/si.c2
7 files changed, 50 insertions, 50 deletions
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 736a416b51a7..59b866aa08d9 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -69,6 +69,7 @@ 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);
72static void cik_uvd_resume(struct radeon_device *rdev);
72 73
73/* get temperature in millidegrees */ 74/* get temperature in millidegrees */
74int ci_get_temp(struct radeon_device *rdev) 75int ci_get_temp(struct radeon_device *rdev)
@@ -7619,8 +7620,9 @@ static int cik_startup(struct radeon_device *rdev)
7619 return r; 7620 return r;
7620 } 7621 }
7621 7622
7622 r = cik_uvd_resume(rdev); 7623 r = radeon_uvd_resume(rdev);
7623 if (!r) { 7624 if (!r) {
7625 cik_uvd_resume(rdev);
7624 r = radeon_fence_driver_start_ring(rdev, 7626 r = radeon_fence_driver_start_ring(rdev,
7625 R600_RING_TYPE_UVD_INDEX); 7627 R600_RING_TYPE_UVD_INDEX);
7626 if (r) 7628 if (r)
@@ -7708,7 +7710,7 @@ static int cik_startup(struct radeon_device *rdev)
7708 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, 7710 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
7709 0, 0xfffff, RADEON_CP_PACKET2); 7711 0, 0xfffff, RADEON_CP_PACKET2);
7710 if (!r) 7712 if (!r)
7711 r = r600_uvd_init(rdev); 7713 r = r600_uvd_init(rdev, true);
7712 if (r) 7714 if (r)
7713 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); 7715 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
7714 } 7716 }
@@ -8598,15 +8600,10 @@ int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
8598 return r; 8600 return r;
8599} 8601}
8600 8602
8601int cik_uvd_resume(struct radeon_device *rdev) 8603static void cik_uvd_resume(struct radeon_device *rdev)
8602{ 8604{
8603 uint64_t addr; 8605 uint64_t addr;
8604 uint32_t size; 8606 uint32_t size;
8605 int r;
8606
8607 r = radeon_uvd_resume(rdev);
8608 if (r)
8609 return r;
8610 8607
8611 /* programm the VCPU memory controller bits 0-27 */ 8608 /* programm the VCPU memory controller bits 0-27 */
8612 addr = rdev->uvd.gpu_addr >> 3; 8609 addr = rdev->uvd.gpu_addr >> 3;
@@ -8632,7 +8629,6 @@ int cik_uvd_resume(struct radeon_device *rdev)
8632 addr = (rdev->uvd.gpu_addr >> 32) & 0xFF; 8629 addr = (rdev->uvd.gpu_addr >> 32) & 0xFF;
8633 WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31)); 8630 WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31));
8634 8631
8635 return 0;
8636} 8632}
8637 8633
8638static void cik_pcie_gen3_enable(struct radeon_device *rdev) 8634static void cik_pcie_gen3_enable(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 2ce12ee3e67f..710c1d4ae5db 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -5296,7 +5296,7 @@ static int evergreen_startup(struct radeon_device *rdev)
5296 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, 5296 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
5297 0, 0xfffff, RADEON_CP_PACKET2); 5297 0, 0xfffff, RADEON_CP_PACKET2);
5298 if (!r) 5298 if (!r)
5299 r = r600_uvd_init(rdev); 5299 r = r600_uvd_init(rdev, true);
5300 5300
5301 if (r) 5301 if (r)
5302 DRM_ERROR("radeon: error initializing UVD (%d).\n", r); 5302 DRM_ERROR("radeon: error initializing UVD (%d).\n", r);
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 21f2eceff2c6..bc298a3500a4 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -2230,7 +2230,7 @@ static int cayman_startup(struct radeon_device *rdev)
2230 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, 2230 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
2231 0, 0xfffff, RADEON_CP_PACKET2); 2231 0, 0xfffff, RADEON_CP_PACKET2);
2232 if (!r) 2232 if (!r)
2233 r = r600_uvd_init(rdev); 2233 r = r600_uvd_init(rdev, true);
2234 if (r) 2234 if (r)
2235 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); 2235 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
2236 } 2236 }
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 3db2e4ddb2d6..8a600153ef6c 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2623,7 +2623,7 @@ void r600_dma_fini(struct radeon_device *rdev)
2623/* 2623/*
2624 * UVD 2624 * UVD
2625 */ 2625 */
2626int r600_uvd_rbc_start(struct radeon_device *rdev) 2626static int r600_uvd_rbc_start(struct radeon_device *rdev, bool ring_test)
2627{ 2627{
2628 struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; 2628 struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
2629 uint64_t rptr_addr; 2629 uint64_t rptr_addr;
@@ -2664,47 +2664,47 @@ int r600_uvd_rbc_start(struct radeon_device *rdev)
2664 rb_bufsz = (0x1 << 8) | rb_bufsz; 2664 rb_bufsz = (0x1 << 8) | rb_bufsz;
2665 WREG32(UVD_RBC_RB_CNTL, rb_bufsz); 2665 WREG32(UVD_RBC_RB_CNTL, rb_bufsz);
2666 2666
2667 ring->ready = true; 2667 if (ring_test) {
2668 r = radeon_ring_test(rdev, R600_RING_TYPE_UVD_INDEX, ring); 2668 ring->ready = true;
2669 if (r) { 2669 r = radeon_ring_test(rdev, R600_RING_TYPE_UVD_INDEX, ring);
2670 ring->ready = false; 2670 if (r) {
2671 return r; 2671 ring->ready = false;
2672 } 2672 return r;
2673 }
2673 2674
2674 r = radeon_ring_lock(rdev, ring, 10); 2675 r = radeon_ring_lock(rdev, ring, 10);
2675 if (r) { 2676 if (r) {
2676 DRM_ERROR("radeon: ring failed to lock UVD ring (%d).\n", r); 2677 DRM_ERROR("radeon: ring failed to lock UVD ring (%d).\n", r);
2677 return r; 2678 return r;
2678 } 2679 }
2679 2680
2680 tmp = PACKET0(UVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL, 0); 2681 tmp = PACKET0(UVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL, 0);
2681 radeon_ring_write(ring, tmp); 2682 radeon_ring_write(ring, tmp);
2682 radeon_ring_write(ring, 0xFFFFF); 2683 radeon_ring_write(ring, 0xFFFFF);
2683 2684
2684 tmp = PACKET0(UVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL, 0); 2685 tmp = PACKET0(UVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL, 0);
2685 radeon_ring_write(ring, tmp); 2686 radeon_ring_write(ring, tmp);
2686 radeon_ring_write(ring, 0xFFFFF); 2687 radeon_ring_write(ring, 0xFFFFF);
2687 2688
2688 tmp = PACKET0(UVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL, 0); 2689 tmp = PACKET0(UVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL, 0);
2689 radeon_ring_write(ring, tmp); 2690 radeon_ring_write(ring, tmp);
2690 radeon_ring_write(ring, 0xFFFFF); 2691 radeon_ring_write(ring, 0xFFFFF);
2691 2692
2692 /* Clear timeout status bits */ 2693 /* Clear timeout status bits */
2693 radeon_ring_write(ring, PACKET0(UVD_SEMA_TIMEOUT_STATUS, 0)); 2694 radeon_ring_write(ring, PACKET0(UVD_SEMA_TIMEOUT_STATUS, 0));
2694 radeon_ring_write(ring, 0x8); 2695 radeon_ring_write(ring, 0x8);
2695 2696
2696 radeon_ring_write(ring, PACKET0(UVD_SEMA_CNTL, 0)); 2697 radeon_ring_write(ring, PACKET0(UVD_SEMA_CNTL, 0));
2697 radeon_ring_write(ring, 3); 2698 radeon_ring_write(ring, 3);
2698 2699
2699 radeon_ring_unlock_commit(rdev, ring); 2700 radeon_ring_unlock_commit(rdev, ring);
2701 }
2700 2702
2701 return 0; 2703 return 0;
2702} 2704}
2703 2705
2704void r600_uvd_stop(struct radeon_device *rdev) 2706void r600_do_uvd_stop(struct radeon_device *rdev)
2705{ 2707{
2706 struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
2707
2708 /* force RBC into idle state */ 2708 /* force RBC into idle state */
2709 WREG32(UVD_RBC_RB_CNTL, 0x11010101); 2709 WREG32(UVD_RBC_RB_CNTL, 0x11010101);
2710 2710
@@ -2723,11 +2723,17 @@ void r600_uvd_stop(struct radeon_device *rdev)
2723 /* Unstall UMC and register bus */ 2723 /* Unstall UMC and register bus */
2724 WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8)); 2724 WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
2725 WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3)); 2725 WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
2726}
2726 2727
2728void r600_uvd_stop(struct radeon_device *rdev)
2729{
2730 struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
2731
2732 r600_do_uvd_stop(rdev);
2727 ring->ready = false; 2733 ring->ready = false;
2728} 2734}
2729 2735
2730int r600_uvd_init(struct radeon_device *rdev) 2736int r600_uvd_init(struct radeon_device *rdev, bool ring_test)
2731{ 2737{
2732 int i, j, r; 2738 int i, j, r;
2733 /* disable byte swapping */ 2739 /* disable byte swapping */
@@ -2815,17 +2821,17 @@ int r600_uvd_init(struct radeon_device *rdev)
2815 2821
2816 if (r) { 2822 if (r) {
2817 DRM_ERROR("UVD not responding, giving up!!!\n"); 2823 DRM_ERROR("UVD not responding, giving up!!!\n");
2818 radeon_set_uvd_clocks(rdev, 0, 0); 2824 goto done;
2819 return r;
2820 } 2825 }
2821 2826
2822 /* enable interupt */ 2827 /* enable interupt */
2823 WREG32_P(UVD_MASTINT_EN, 3<<1, ~(3 << 1)); 2828 WREG32_P(UVD_MASTINT_EN, 3<<1, ~(3 << 1));
2824 2829
2825 r = r600_uvd_rbc_start(rdev); 2830 r = r600_uvd_rbc_start(rdev, ring_test);
2826 if (!r) 2831 if (!r)
2827 DRM_INFO("UVD initialized successfully.\n"); 2832 DRM_INFO("UVD initialized successfully.\n");
2828 2833
2834done:
2829 /* lower clocks again */ 2835 /* lower clocks again */
2830 radeon_set_uvd_clocks(rdev, 0, 0); 2836 radeon_set_uvd_clocks(rdev, 0, 0);
2831 2837
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 1e386c48ae2d..3570817a5847 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -424,8 +424,7 @@ void rs780_dpm_debugfs_print_current_performance_level(struct radeon_device *rde
424 struct seq_file *m); 424 struct seq_file *m);
425 425
426/* uvd */ 426/* uvd */
427int r600_uvd_init(struct radeon_device *rdev); 427int r600_uvd_init(struct radeon_device *rdev, bool ring_test);
428int r600_uvd_rbc_start(struct radeon_device *rdev);
429void r600_uvd_stop(struct radeon_device *rdev); 428void r600_uvd_stop(struct radeon_device *rdev);
430int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); 429int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
431void r600_uvd_fence_emit(struct radeon_device *rdev, 430void r600_uvd_fence_emit(struct radeon_device *rdev,
@@ -696,7 +695,6 @@ u32 cik_get_xclk(struct radeon_device *rdev);
696uint32_t cik_pciep_rreg(struct radeon_device *rdev, uint32_t reg); 695uint32_t cik_pciep_rreg(struct radeon_device *rdev, uint32_t reg);
697void cik_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); 696void cik_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
698int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); 697int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
699int cik_uvd_resume(struct radeon_device *rdev);
700void cik_sdma_fence_ring_emit(struct radeon_device *rdev, 698void cik_sdma_fence_ring_emit(struct radeon_device *rdev,
701 struct radeon_fence *fence); 699 struct radeon_fence *fence);
702void cik_sdma_semaphore_ring_emit(struct radeon_device *rdev, 700void cik_sdma_semaphore_ring_emit(struct radeon_device *rdev,
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 95590bd07afb..52253b2ab0d5 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -1928,7 +1928,7 @@ static int rv770_startup(struct radeon_device *rdev)
1928 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, 1928 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
1929 0, 0xfffff, RADEON_CP_PACKET2); 1929 0, 0xfffff, RADEON_CP_PACKET2);
1930 if (!r) 1930 if (!r)
1931 r = r600_uvd_init(rdev); 1931 r = r600_uvd_init(rdev, true);
1932 1932
1933 if (r) 1933 if (r)
1934 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); 1934 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index 4f91e1f4d814..da23ce8f4388 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -6421,7 +6421,7 @@ static int si_startup(struct radeon_device *rdev)
6421 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, 6421 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
6422 0, 0xfffff, RADEON_CP_PACKET2); 6422 0, 0xfffff, RADEON_CP_PACKET2);
6423 if (!r) 6423 if (!r)
6424 r = r600_uvd_init(rdev); 6424 r = r600_uvd_init(rdev, true);
6425 if (r) 6425 if (r)
6426 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); 6426 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
6427 } 6427 }