|
@@ -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);
|