Merge branch 'drm-radeon-lockup' into drm-core-next
[sfrench/cifs-2.6.git] / drivers / gpu / drm / radeon / rs600.c
index a81bc7a21e14b967c23a218c3095031371f7d327..5e3f21861f45e34a46f1bc8be4b9e384a2545380 100644 (file)
@@ -147,6 +147,78 @@ void rs600_hpd_fini(struct radeon_device *rdev)
        }
 }
 
+void rs600_bm_disable(struct radeon_device *rdev)
+{
+       u32 tmp;
+
+       /* disable bus mastering */
+       pci_read_config_word(rdev->pdev, 0x4, (u16*)&tmp);
+       pci_write_config_word(rdev->pdev, 0x4, tmp & 0xFFFB);
+       mdelay(1);
+}
+
+int rs600_asic_reset(struct radeon_device *rdev)
+{
+       u32 status, tmp;
+
+       struct rv515_mc_save save;
+
+       /* Stops all mc clients */
+       rv515_mc_stop(rdev, &save);
+       status = RREG32(R_000E40_RBBM_STATUS);
+       if (!G_000E40_GUI_ACTIVE(status)) {
+               return 0;
+       }
+       status = RREG32(R_000E40_RBBM_STATUS);
+       dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
+       /* stop CP */
+       WREG32(RADEON_CP_CSQ_CNTL, 0);
+       tmp = RREG32(RADEON_CP_RB_CNTL);
+       WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA);
+       WREG32(RADEON_CP_RB_RPTR_WR, 0);
+       WREG32(RADEON_CP_RB_WPTR, 0);
+       WREG32(RADEON_CP_RB_CNTL, tmp);
+       pci_save_state(rdev->pdev);
+       /* disable bus mastering */
+       rs600_bm_disable(rdev);
+       /* reset GA+VAP */
+       WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_VAP(1) |
+                                       S_0000F0_SOFT_RESET_GA(1));
+       RREG32(R_0000F0_RBBM_SOFT_RESET);
+       mdelay(500);
+       WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
+       mdelay(1);
+       status = RREG32(R_000E40_RBBM_STATUS);
+       dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
+       /* reset CP */
+       WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_CP(1));
+       RREG32(R_0000F0_RBBM_SOFT_RESET);
+       mdelay(500);
+       WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
+       mdelay(1);
+       status = RREG32(R_000E40_RBBM_STATUS);
+       dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
+       /* reset MC */
+       WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_MC(1));
+       RREG32(R_0000F0_RBBM_SOFT_RESET);
+       mdelay(500);
+       WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
+       mdelay(1);
+       status = RREG32(R_000E40_RBBM_STATUS);
+       dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
+       /* restore PCI & busmastering */
+       pci_restore_state(rdev->pdev);
+       /* Check if GPU is idle */
+       if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) {
+               dev_err(rdev->dev, "failed to reset GPU\n");
+               rdev->gpu_lockup = true;
+               return -1;
+       }
+       rv515_mc_resume(rdev, &save);
+       dev_info(rdev->dev, "GPU reset succeed\n");
+       return 0;
+}
+
 /*
  * GART.
  */
@@ -454,7 +526,6 @@ int rs600_mc_wait_for_idle(struct radeon_device *rdev)
 
 void rs600_gpu_init(struct radeon_device *rdev)
 {
-       r100_hdp_reset(rdev);
        r420_pipes_init(rdev);
        /* Wait for mc idle */
        if (rs600_mc_wait_for_idle(rdev))
@@ -601,7 +672,7 @@ int rs600_resume(struct radeon_device *rdev)
        /* Resume clock before doing reset */
        rv515_clock_startup(rdev);
        /* Reset gpu before posting otherwise ATOM will enter infinite loop */
-       if (radeon_gpu_reset(rdev)) {
+       if (radeon_asic_reset(rdev)) {
                dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
                        RREG32(R_000E40_RBBM_STATUS),
                        RREG32(R_0007C0_CP_STAT));
@@ -664,7 +735,7 @@ int rs600_init(struct radeon_device *rdev)
                return -EINVAL;
        }
        /* Reset gpu before posting otherwise ATOM will enter infinite loop */
-       if (radeon_gpu_reset(rdev)) {
+       if (radeon_asic_reset(rdev)) {
                dev_warn(rdev->dev,
                        "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
                        RREG32(R_000E40_RBBM_STATUS),