aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2013-08-01 11:34:07 -0400
committerAlex Deucher <alexander.deucher@amd.com>2013-08-07 17:37:11 -0400
commit2858c00d2823c83acce2a1175dbabb2cebee8678 (patch)
tree1751bd3ac36c6749a0fded1775def26b19be2dcb
parent797f203f622164a322b9a0f962ce431e3f6ca48e (diff)
drm/radeon: fix halting UVD
Removing the clock/power or resetting the VCPU can cause hangs if that happens in the middle of a register write. Stall the memory and register bus before putting the VCPU into reset. Keep it in reset when unloading the module or suspending. Signed-off-by: Christian König <christian.koenig@amd.com> Cc: stable@vger.kernel.org Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/radeon/cik.c3
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c3
-rw-r--r--drivers/gpu/drm/radeon/ni.c3
-rw-r--r--drivers/gpu/drm/radeon/r600.c28
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h2
-rw-r--r--drivers/gpu/drm/radeon/rv770.c2
-rw-r--r--drivers/gpu/drm/radeon/si.c6
7 files changed, 36 insertions, 11 deletions
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 6dacec4e2090..524db70aaf6e 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -6194,7 +6194,7 @@ int cik_suspend(struct radeon_device *rdev)
6194 radeon_vm_manager_fini(rdev); 6194 radeon_vm_manager_fini(rdev);
6195 cik_cp_enable(rdev, false); 6195 cik_cp_enable(rdev, false);
6196 cik_sdma_enable(rdev, false); 6196 cik_sdma_enable(rdev, false);
6197 r600_uvd_rbc_stop(rdev); 6197 r600_uvd_stop(rdev);
6198 radeon_uvd_suspend(rdev); 6198 radeon_uvd_suspend(rdev);
6199 cik_irq_suspend(rdev); 6199 cik_irq_suspend(rdev);
6200 radeon_wb_disable(rdev); 6200 radeon_wb_disable(rdev);
@@ -6358,6 +6358,7 @@ void cik_fini(struct radeon_device *rdev)
6358 radeon_vm_manager_fini(rdev); 6358 radeon_vm_manager_fini(rdev);
6359 radeon_ib_pool_fini(rdev); 6359 radeon_ib_pool_fini(rdev);
6360 radeon_irq_kms_fini(rdev); 6360 radeon_irq_kms_fini(rdev);
6361 r600_uvd_stop(rdev);
6361 radeon_uvd_fini(rdev); 6362 radeon_uvd_fini(rdev);
6362 cik_pcie_gart_fini(rdev); 6363 cik_pcie_gart_fini(rdev);
6363 r600_vram_scratch_fini(rdev); 6364 r600_vram_scratch_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 038dcac7670c..5b98e573d60a 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -5291,10 +5291,10 @@ int evergreen_resume(struct radeon_device *rdev)
5291int evergreen_suspend(struct radeon_device *rdev) 5291int evergreen_suspend(struct radeon_device *rdev)
5292{ 5292{
5293 r600_audio_fini(rdev); 5293 r600_audio_fini(rdev);
5294 r600_uvd_stop(rdev);
5294 radeon_uvd_suspend(rdev); 5295 radeon_uvd_suspend(rdev);
5295 r700_cp_stop(rdev); 5296 r700_cp_stop(rdev);
5296 r600_dma_stop(rdev); 5297 r600_dma_stop(rdev);
5297 r600_uvd_rbc_stop(rdev);
5298 evergreen_irq_suspend(rdev); 5298 evergreen_irq_suspend(rdev);
5299 radeon_wb_disable(rdev); 5299 radeon_wb_disable(rdev);
5300 evergreen_pcie_gart_disable(rdev); 5300 evergreen_pcie_gart_disable(rdev);
@@ -5429,6 +5429,7 @@ void evergreen_fini(struct radeon_device *rdev)
5429 radeon_ib_pool_fini(rdev); 5429 radeon_ib_pool_fini(rdev);
5430 radeon_irq_kms_fini(rdev); 5430 radeon_irq_kms_fini(rdev);
5431 evergreen_pcie_gart_fini(rdev); 5431 evergreen_pcie_gart_fini(rdev);
5432 r600_uvd_stop(rdev);
5432 radeon_uvd_fini(rdev); 5433 radeon_uvd_fini(rdev);
5433 r600_vram_scratch_fini(rdev); 5434 r600_vram_scratch_fini(rdev);
5434 radeon_gem_fini(rdev); 5435 radeon_gem_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 56bd4f3be4fe..16e91b08bf57 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -2286,7 +2286,7 @@ int cayman_suspend(struct radeon_device *rdev)
2286 radeon_vm_manager_fini(rdev); 2286 radeon_vm_manager_fini(rdev);
2287 cayman_cp_enable(rdev, false); 2287 cayman_cp_enable(rdev, false);
2288 cayman_dma_stop(rdev); 2288 cayman_dma_stop(rdev);
2289 r600_uvd_rbc_stop(rdev); 2289 r600_uvd_stop(rdev);
2290 radeon_uvd_suspend(rdev); 2290 radeon_uvd_suspend(rdev);
2291 evergreen_irq_suspend(rdev); 2291 evergreen_irq_suspend(rdev);
2292 radeon_wb_disable(rdev); 2292 radeon_wb_disable(rdev);
@@ -2418,6 +2418,7 @@ void cayman_fini(struct radeon_device *rdev)
2418 radeon_vm_manager_fini(rdev); 2418 radeon_vm_manager_fini(rdev);
2419 radeon_ib_pool_fini(rdev); 2419 radeon_ib_pool_fini(rdev);
2420 radeon_irq_kms_fini(rdev); 2420 radeon_irq_kms_fini(rdev);
2421 r600_uvd_stop(rdev);
2421 radeon_uvd_fini(rdev); 2422 radeon_uvd_fini(rdev);
2422 cayman_pcie_gart_fini(rdev); 2423 cayman_pcie_gart_fini(rdev);
2423 r600_vram_scratch_fini(rdev); 2424 r600_vram_scratch_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 10f712e37003..0a9553abec54 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2697,12 +2697,29 @@ int r600_uvd_rbc_start(struct radeon_device *rdev)
2697 return 0; 2697 return 0;
2698} 2698}
2699 2699
2700void r600_uvd_rbc_stop(struct radeon_device *rdev) 2700void r600_uvd_stop(struct radeon_device *rdev)
2701{ 2701{
2702 struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; 2702 struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
2703 2703
2704 /* force RBC into idle state */ 2704 /* force RBC into idle state */
2705 WREG32(UVD_RBC_RB_CNTL, 0x11010101); 2705 WREG32(UVD_RBC_RB_CNTL, 0x11010101);
2706
2707 /* Stall UMC and register bus before resetting VCPU */
2708 WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
2709 WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
2710 mdelay(1);
2711
2712 /* put VCPU into reset */
2713 WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
2714 mdelay(5);
2715
2716 /* disable VCPU clock */
2717 WREG32(UVD_VCPU_CNTL, 0x0);
2718
2719 /* Unstall UMC and register bus */
2720 WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
2721 WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
2722
2706 ring->ready = false; 2723 ring->ready = false;
2707} 2724}
2708 2725
@@ -2722,6 +2739,11 @@ int r600_uvd_init(struct radeon_device *rdev)
2722 /* disable interupt */ 2739 /* disable interupt */
2723 WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1)); 2740 WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1));
2724 2741
2742 /* Stall UMC and register bus before resetting VCPU */
2743 WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
2744 WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
2745 mdelay(1);
2746
2725 /* put LMI, VCPU, RBC etc... into reset */ 2747 /* put LMI, VCPU, RBC etc... into reset */
2726 WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET | 2748 WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET |
2727 LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET | 2749 LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET |
@@ -2751,10 +2773,6 @@ int r600_uvd_init(struct radeon_device *rdev)
2751 WREG32(UVD_MPC_SET_ALU, 0); 2773 WREG32(UVD_MPC_SET_ALU, 0);
2752 WREG32(UVD_MPC_SET_MUX, 0x88); 2774 WREG32(UVD_MPC_SET_MUX, 0x88);
2753 2775
2754 /* Stall UMC */
2755 WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
2756 WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
2757
2758 /* take all subblocks out of reset, except VCPU */ 2776 /* take all subblocks out of reset, except VCPU */
2759 WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET); 2777 WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
2760 mdelay(5); 2778 mdelay(5);
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 902479fa737f..3d61d5aac18f 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -441,7 +441,7 @@ void rs780_dpm_debugfs_print_current_performance_level(struct radeon_device *rde
441/* uvd */ 441/* uvd */
442int r600_uvd_init(struct radeon_device *rdev); 442int r600_uvd_init(struct radeon_device *rdev);
443int r600_uvd_rbc_start(struct radeon_device *rdev); 443int r600_uvd_rbc_start(struct radeon_device *rdev);
444void r600_uvd_rbc_stop(struct radeon_device *rdev); 444void r600_uvd_stop(struct radeon_device *rdev);
445int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); 445int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
446void r600_uvd_fence_emit(struct radeon_device *rdev, 446void r600_uvd_fence_emit(struct radeon_device *rdev,
447 struct radeon_fence *fence); 447 struct radeon_fence *fence);
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 30ea14e8854c..f1010131bac0 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -1983,6 +1983,7 @@ int rv770_resume(struct radeon_device *rdev)
1983int rv770_suspend(struct radeon_device *rdev) 1983int rv770_suspend(struct radeon_device *rdev)
1984{ 1984{
1985 r600_audio_fini(rdev); 1985 r600_audio_fini(rdev);
1986 r600_uvd_stop(rdev);
1986 radeon_uvd_suspend(rdev); 1987 radeon_uvd_suspend(rdev);
1987 r700_cp_stop(rdev); 1988 r700_cp_stop(rdev);
1988 r600_dma_stop(rdev); 1989 r600_dma_stop(rdev);
@@ -2098,6 +2099,7 @@ void rv770_fini(struct radeon_device *rdev)
2098 radeon_ib_pool_fini(rdev); 2099 radeon_ib_pool_fini(rdev);
2099 radeon_irq_kms_fini(rdev); 2100 radeon_irq_kms_fini(rdev);
2100 rv770_pcie_gart_fini(rdev); 2101 rv770_pcie_gart_fini(rdev);
2102 r600_uvd_stop(rdev);
2101 radeon_uvd_fini(rdev); 2103 radeon_uvd_fini(rdev);
2102 r600_vram_scratch_fini(rdev); 2104 r600_vram_scratch_fini(rdev);
2103 radeon_gem_fini(rdev); 2105 radeon_gem_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index 6ca904673a4f..242c1ac83e23 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -6621,7 +6621,7 @@ int si_suspend(struct radeon_device *rdev)
6621 si_cp_enable(rdev, false); 6621 si_cp_enable(rdev, false);
6622 cayman_dma_stop(rdev); 6622 cayman_dma_stop(rdev);
6623 if (rdev->has_uvd) { 6623 if (rdev->has_uvd) {
6624 r600_uvd_rbc_stop(rdev); 6624 r600_uvd_stop(rdev);
6625 radeon_uvd_suspend(rdev); 6625 radeon_uvd_suspend(rdev);
6626 } 6626 }
6627 si_irq_suspend(rdev); 6627 si_irq_suspend(rdev);
@@ -6763,8 +6763,10 @@ void si_fini(struct radeon_device *rdev)
6763 radeon_vm_manager_fini(rdev); 6763 radeon_vm_manager_fini(rdev);
6764 radeon_ib_pool_fini(rdev); 6764 radeon_ib_pool_fini(rdev);
6765 radeon_irq_kms_fini(rdev); 6765 radeon_irq_kms_fini(rdev);
6766 if (rdev->has_uvd) 6766 if (rdev->has_uvd) {
6767 r600_uvd_stop(rdev);
6767 radeon_uvd_fini(rdev); 6768 radeon_uvd_fini(rdev);
6769 }
6768 si_pcie_gart_fini(rdev); 6770 si_pcie_gart_fini(rdev);
6769 r600_vram_scratch_fini(rdev); 6771 r600_vram_scratch_fini(rdev);
6770 radeon_gem_fini(rdev); 6772 radeon_gem_fini(rdev);