Re: FAILED: patch "[PATCH] drm/radeon: fix halting UVD" failed to apply to 3.10-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Greg,

as requested the rebased patch is attached.

Regards,
Christian.

Am 12.08.2013 06:36, schrieb gregkh@xxxxxxxxxxxxxxxxxxx:
The patch below does not apply to the 3.10-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@xxxxxxxxxxxxxxx>.

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

 From 2858c00d2823c83acce2a1175dbabb2cebee8678 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@xxxxxxx>
Date: Thu, 1 Aug 2013 17:34:07 +0200
Subject: [PATCH] drm/radeon: fix halting UVD
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

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@xxxxxxx>
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Alex Deucher <alexander.deucher@xxxxxxx>

diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 6dacec4..524db70 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)
  	radeon_vm_manager_fini(rdev);
  	cik_cp_enable(rdev, false);
  	cik_sdma_enable(rdev, false);
-	r600_uvd_rbc_stop(rdev);
+	r600_uvd_stop(rdev);
  	radeon_uvd_suspend(rdev);
  	cik_irq_suspend(rdev);
  	radeon_wb_disable(rdev);
@@ -6358,6 +6358,7 @@ void cik_fini(struct radeon_device *rdev)
  	radeon_vm_manager_fini(rdev);
  	radeon_ib_pool_fini(rdev);
  	radeon_irq_kms_fini(rdev);
+	r600_uvd_stop(rdev);
  	radeon_uvd_fini(rdev);
  	cik_pcie_gart_fini(rdev);
  	r600_vram_scratch_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 038dcac..5b98e57 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)
  int evergreen_suspend(struct radeon_device *rdev)
  {
  	r600_audio_fini(rdev);
+	r600_uvd_stop(rdev);
  	radeon_uvd_suspend(rdev);
  	r700_cp_stop(rdev);
  	r600_dma_stop(rdev);
-	r600_uvd_rbc_stop(rdev);
  	evergreen_irq_suspend(rdev);
  	radeon_wb_disable(rdev);
  	evergreen_pcie_gart_disable(rdev);
@@ -5429,6 +5429,7 @@ void evergreen_fini(struct radeon_device *rdev)
  	radeon_ib_pool_fini(rdev);
  	radeon_irq_kms_fini(rdev);
  	evergreen_pcie_gart_fini(rdev);
+	r600_uvd_stop(rdev);
  	radeon_uvd_fini(rdev);
  	r600_vram_scratch_fini(rdev);
  	radeon_gem_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 56bd4f3..16e91b0 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)
  	radeon_vm_manager_fini(rdev);
  	cayman_cp_enable(rdev, false);
  	cayman_dma_stop(rdev);
-	r600_uvd_rbc_stop(rdev);
+	r600_uvd_stop(rdev);
  	radeon_uvd_suspend(rdev);
  	evergreen_irq_suspend(rdev);
  	radeon_wb_disable(rdev);
@@ -2418,6 +2418,7 @@ void cayman_fini(struct radeon_device *rdev)
  	radeon_vm_manager_fini(rdev);
  	radeon_ib_pool_fini(rdev);
  	radeon_irq_kms_fini(rdev);
+	r600_uvd_stop(rdev);
  	radeon_uvd_fini(rdev);
  	cayman_pcie_gart_fini(rdev);
  	r600_vram_scratch_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 10f712e..0a9553a 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)
  	return 0;
  }
-void r600_uvd_rbc_stop(struct radeon_device *rdev)
+void r600_uvd_stop(struct radeon_device *rdev)
  {
  	struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
/* force RBC into idle state */
  	WREG32(UVD_RBC_RB_CNTL, 0x11010101);
+
+	/* Stall UMC and register bus before resetting VCPU */
+	WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
+	WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
+	mdelay(1);
+
+	/* put VCPU into reset */
+	WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
+	mdelay(5);
+
+	/* disable VCPU clock */
+	WREG32(UVD_VCPU_CNTL, 0x0);
+
+	/* Unstall UMC and register bus */
+	WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
+	WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
+
  	ring->ready = false;
  }
@@ -2722,6 +2739,11 @@ int r600_uvd_init(struct radeon_device *rdev)
  	/* disable interupt */
  	WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1));
+ /* Stall UMC and register bus before resetting VCPU */
+	WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
+	WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
+	mdelay(1);
+
  	/* put LMI, VCPU, RBC etc... into reset */
  	WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET |
  	       LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET |
@@ -2751,10 +2773,6 @@ int r600_uvd_init(struct radeon_device *rdev)
  	WREG32(UVD_MPC_SET_ALU, 0);
  	WREG32(UVD_MPC_SET_MUX, 0x88);
- /* Stall UMC */
-	WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
-	WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
-
  	/* take all subblocks out of reset, except VCPU */
  	WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
  	mdelay(5);
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 902479f..3d61d5a 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
  /* uvd */
  int r600_uvd_init(struct radeon_device *rdev);
  int r600_uvd_rbc_start(struct radeon_device *rdev);
-void r600_uvd_rbc_stop(struct radeon_device *rdev);
+void r600_uvd_stop(struct radeon_device *rdev);
  int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
  void r600_uvd_fence_emit(struct radeon_device *rdev,
  			 struct radeon_fence *fence);
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 30ea14e..f101013 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)
  int rv770_suspend(struct radeon_device *rdev)
  {
  	r600_audio_fini(rdev);
+	r600_uvd_stop(rdev);
  	radeon_uvd_suspend(rdev);
  	r700_cp_stop(rdev);
  	r600_dma_stop(rdev);
@@ -2098,6 +2099,7 @@ void rv770_fini(struct radeon_device *rdev)
  	radeon_ib_pool_fini(rdev);
  	radeon_irq_kms_fini(rdev);
  	rv770_pcie_gart_fini(rdev);
+	r600_uvd_stop(rdev);
  	radeon_uvd_fini(rdev);
  	r600_vram_scratch_fini(rdev);
  	radeon_gem_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index 6ca9046..242c1ac 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)
  	si_cp_enable(rdev, false);
  	cayman_dma_stop(rdev);
  	if (rdev->has_uvd) {
-		r600_uvd_rbc_stop(rdev);
+		r600_uvd_stop(rdev);
  		radeon_uvd_suspend(rdev);
  	}
  	si_irq_suspend(rdev);
@@ -6763,8 +6763,10 @@ void si_fini(struct radeon_device *rdev)
  	radeon_vm_manager_fini(rdev);
  	radeon_ib_pool_fini(rdev);
  	radeon_irq_kms_fini(rdev);
-	if (rdev->has_uvd)
+	if (rdev->has_uvd) {
+		r600_uvd_stop(rdev);
  		radeon_uvd_fini(rdev);
+	}
  	si_pcie_gart_fini(rdev);
  	r600_vram_scratch_fini(rdev);
  	radeon_gem_fini(rdev);



>From f71e8bef8f6e42b13d61e038fa735dcfd44f6148 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@xxxxxxx>
Date: Thu, 1 Aug 2013 17:34:07 +0200
Subject: [PATCH] drm/radeon: fix halting UVD v2
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

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.

v2: rebased on 3.10-stable tree

Signed-off-by: Christian König <christian.koenig@xxxxxxx>
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Alex Deucher <alexander.deucher@xxxxxxx>
---
 drivers/gpu/drm/radeon/evergreen.c   |    3 ++-
 drivers/gpu/drm/radeon/ni.c          |    3 ++-
 drivers/gpu/drm/radeon/r600.c        |   28 +++++++++++++++++++++++-----
 drivers/gpu/drm/radeon/radeon_asic.h |    2 +-
 drivers/gpu/drm/radeon/rv770.c       |    2 ++
 drivers/gpu/drm/radeon/si.c          |    6 ++++--
 6 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 0f89ce3..fdac919 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -4854,10 +4854,10 @@ int evergreen_resume(struct radeon_device *rdev)
 int evergreen_suspend(struct radeon_device *rdev)
 {
 	r600_audio_fini(rdev);
+	r600_uvd_stop(rdev);
 	radeon_uvd_suspend(rdev);
 	r700_cp_stop(rdev);
 	r600_dma_stop(rdev);
-	r600_uvd_rbc_stop(rdev);
 	evergreen_irq_suspend(rdev);
 	radeon_wb_disable(rdev);
 	evergreen_pcie_gart_disable(rdev);
@@ -4988,6 +4988,7 @@ void evergreen_fini(struct radeon_device *rdev)
 	radeon_ib_pool_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	evergreen_pcie_gart_fini(rdev);
+	r600_uvd_stop(rdev);
 	radeon_uvd_fini(rdev);
 	r600_vram_scratch_fini(rdev);
 	radeon_gem_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 8458330..b6956f6 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -2133,7 +2133,7 @@ int cayman_suspend(struct radeon_device *rdev)
 	radeon_vm_manager_fini(rdev);
 	cayman_cp_enable(rdev, false);
 	cayman_dma_stop(rdev);
-	r600_uvd_rbc_stop(rdev);
+	r600_uvd_stop(rdev);
 	radeon_uvd_suspend(rdev);
 	evergreen_irq_suspend(rdev);
 	radeon_wb_disable(rdev);
@@ -2265,6 +2265,7 @@ void cayman_fini(struct radeon_device *rdev)
 	radeon_vm_manager_fini(rdev);
 	radeon_ib_pool_fini(rdev);
 	radeon_irq_kms_fini(rdev);
+	r600_uvd_stop(rdev);
 	radeon_uvd_fini(rdev);
 	cayman_pcie_gart_fini(rdev);
 	r600_vram_scratch_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index b60004e..5a6c7fa 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2675,12 +2675,29 @@ int r600_uvd_rbc_start(struct radeon_device *rdev)
 	return 0;
 }
 
-void r600_uvd_rbc_stop(struct radeon_device *rdev)
+void r600_uvd_stop(struct radeon_device *rdev)
 {
 	struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
 
 	/* force RBC into idle state */
 	WREG32(UVD_RBC_RB_CNTL, 0x11010101);
+
+	/* Stall UMC and register bus before resetting VCPU */
+	WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
+	WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
+	mdelay(1);
+
+	/* put VCPU into reset */
+	WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
+	mdelay(5);
+
+	/* disable VCPU clock */
+	WREG32(UVD_VCPU_CNTL, 0x0);
+
+	/* Unstall UMC and register bus */
+	WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
+	WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
+
 	ring->ready = false;
 }
 
@@ -2700,6 +2717,11 @@ int r600_uvd_init(struct radeon_device *rdev)
 	/* disable interupt */
 	WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1));
 
+	/* Stall UMC and register bus before resetting VCPU */
+	WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
+	WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
+	mdelay(1);
+
 	/* put LMI, VCPU, RBC etc... into reset */
 	WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET |
 	       LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET |
@@ -2729,10 +2751,6 @@ int r600_uvd_init(struct radeon_device *rdev)
 	WREG32(UVD_MPC_SET_ALU, 0);
 	WREG32(UVD_MPC_SET_MUX, 0x88);
 
-	/* Stall UMC */
-	WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
-	WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
-
 	/* take all subblocks out of reset, except VCPU */
 	WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
 	mdelay(5);
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index a72759e..34223fc 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -399,7 +399,7 @@ uint64_t r600_get_gpu_clock_counter(struct radeon_device *rdev);
 /* uvd */
 int r600_uvd_init(struct radeon_device *rdev);
 int r600_uvd_rbc_start(struct radeon_device *rdev);
-void r600_uvd_rbc_stop(struct radeon_device *rdev);
+void r600_uvd_stop(struct radeon_device *rdev);
 int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
 void r600_uvd_fence_emit(struct radeon_device *rdev,
 			 struct radeon_fence *fence);
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 30ea14e..f101013 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)
 int rv770_suspend(struct radeon_device *rdev)
 {
 	r600_audio_fini(rdev);
+	r600_uvd_stop(rdev);
 	radeon_uvd_suspend(rdev);
 	r700_cp_stop(rdev);
 	r600_dma_stop(rdev);
@@ -2098,6 +2099,7 @@ void rv770_fini(struct radeon_device *rdev)
 	radeon_ib_pool_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	rv770_pcie_gart_fini(rdev);
+	r600_uvd_stop(rdev);
 	radeon_uvd_fini(rdev);
 	r600_vram_scratch_fini(rdev);
 	radeon_gem_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index a1b0da6..f56ef18 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -5473,7 +5473,7 @@ int si_suspend(struct radeon_device *rdev)
 	si_cp_enable(rdev, false);
 	cayman_dma_stop(rdev);
 	if (rdev->has_uvd) {
-		r600_uvd_rbc_stop(rdev);
+		r600_uvd_stop(rdev);
 		radeon_uvd_suspend(rdev);
 	}
 	si_irq_suspend(rdev);
@@ -5613,8 +5613,10 @@ void si_fini(struct radeon_device *rdev)
 	radeon_vm_manager_fini(rdev);
 	radeon_ib_pool_fini(rdev);
 	radeon_irq_kms_fini(rdev);
-	if (rdev->has_uvd)
+	if (rdev->has_uvd) {
+		r600_uvd_stop(rdev);
 		radeon_uvd_fini(rdev);
+	}
 	si_pcie_gart_fini(rdev);
 	r600_vram_scratch_fini(rdev);
 	radeon_gem_fini(rdev);
-- 
1.7.9.5


[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]