]> rtime.felk.cvut.cz Git - linux-imx.git/blobdiff - drivers/gpu/drm/radeon/r600.c
drm/radeon: always program the MC on startup
[linux-imx.git] / drivers / gpu / drm / radeon / r600.c
index 393880a094129d5fe54a6e6431de09798101e858..af848045670c3a61b07059ee69433862f5bdcf4a 100644 (file)
@@ -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);
@@ -3166,7 +3184,7 @@ int r600_copy_cpdma(struct radeon_device *rdev,
 
        size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT);
        num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff);
-       r = radeon_ring_lock(rdev, ring, num_loops * 6 + 21);
+       r = radeon_ring_lock(rdev, ring, num_loops * 6 + 24);
        if (r) {
                DRM_ERROR("radeon: moving bo (%d).\n", r);
                radeon_semaphore_free(rdev, &sem, NULL);
@@ -3181,6 +3199,9 @@ int r600_copy_cpdma(struct radeon_device *rdev,
                radeon_semaphore_free(rdev, &sem, NULL);
        }
 
+       radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
+       radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
+       radeon_ring_write(ring, WAIT_3D_IDLE_bit);
        for (i = 0; i < num_loops; i++) {
                cur_size_in_bytes = size_in_bytes;
                if (cur_size_in_bytes > 0x1fffff)
@@ -3309,6 +3330,8 @@ static int r600_startup(struct radeon_device *rdev)
        /* enable pcie gen2 link */
        r600_pcie_gen2_enable(rdev);
 
+       r600_mc_program(rdev);
+
        if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
                r = r600_init_microcode(rdev);
                if (r) {
@@ -3321,7 +3344,6 @@ static int r600_startup(struct radeon_device *rdev)
        if (r)
                return r;
 
-       r600_mc_program(rdev);
        if (rdev->flags & RADEON_IS_AGP) {
                r600_agp_enable(rdev);
        } else {