aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r600.c
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2010-03-09 09:45:12 -0500
committerDave Airlie <airlied@redhat.com>2010-04-05 21:21:11 -0400
commit90aca4d2740255bd130ea71a91530b9920c70abe (patch)
treeacf9b8a4353e6727cd6cba5b71caaf9f067e465d /drivers/gpu/drm/radeon/r600.c
parenta2d07b7438f015a0349bc9af3c96a8164549bbc5 (diff)
drm/radeon/kms: simplify & improve GPU reset V2
This simplify and improve GPU reset for R1XX-R6XX hw, it's not 100% reliable here are result: - R1XX/R2XX works bunch of time in a row, sometimes it seems it can work indifinitly - R3XX/R3XX the most unreliable one, sometimes you will be able to reset few times, sometimes not even once - R5XX more reliable than previous hw, seems to work most of the times but once in a while it fails for no obvious reasons (same status than previous reset just no same happy ending) - R6XX/R7XX are lot more reliable with this patch, still it seems that it can fail after a bunch (reset every 2sec for 3hour bring down the GPU & computer) This have been tested on various hw, for some odd reasons i wasn't able to lockup RS480/RS690 (while they use to love locking up). Note that on R1XX-R5XX the cursor will disapear after lockup haven't checked why, switch to console and back to X will restore cursor. Next step is to record the bogus command that leaded to the lockup. V2 Fix r6xx resume path to avoid reinitializing blit module, use the gpu_lockup boolean to avoid entering inifinite waiting loop on fence while reiniting the GPU Signed-off-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/r600.c')
-rw-r--r--drivers/gpu/drm/radeon/r600.c53
1 files changed, 5 insertions, 48 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 24fd5459fb42..13c9cc34231d 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -749,7 +749,6 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
749 S_008014_DB2_BUSY(1) | S_008014_DB3_BUSY(1) | 749 S_008014_DB2_BUSY(1) | S_008014_DB3_BUSY(1) |
750 S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) | 750 S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) |
751 S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1); 751 S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1);
752 u32 srbm_reset = 0;
753 u32 tmp; 752 u32 tmp;
754 753
755 dev_info(rdev->dev, "GPU softreset \n"); 754 dev_info(rdev->dev, "GPU softreset \n");
@@ -764,7 +763,7 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
764 dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); 763 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
765 } 764 }
766 /* Disable CP parsing/prefetching */ 765 /* Disable CP parsing/prefetching */
767 WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(0xff)); 766 WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1));
768 /* Check if any of the rendering block is busy and reset it */ 767 /* Check if any of the rendering block is busy and reset it */
769 if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) || 768 if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) ||
770 (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) { 769 (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) {
@@ -783,55 +782,17 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
783 S_008020_SOFT_RESET_VGT(1); 782 S_008020_SOFT_RESET_VGT(1);
784 dev_info(rdev->dev, " R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp); 783 dev_info(rdev->dev, " R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp);
785 WREG32(R_008020_GRBM_SOFT_RESET, tmp); 784 WREG32(R_008020_GRBM_SOFT_RESET, tmp);
786 (void)RREG32(R_008020_GRBM_SOFT_RESET); 785 RREG32(R_008020_GRBM_SOFT_RESET);
787 mdelay(1); 786 mdelay(15);
788 WREG32(R_008020_GRBM_SOFT_RESET, 0); 787 WREG32(R_008020_GRBM_SOFT_RESET, 0);
789 (void)RREG32(R_008020_GRBM_SOFT_RESET);
790 } 788 }
791 /* Reset CP (we always reset CP) */ 789 /* Reset CP (we always reset CP) */
792 tmp = S_008020_SOFT_RESET_CP(1); 790 tmp = S_008020_SOFT_RESET_CP(1);
793 dev_info(rdev->dev, "R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp); 791 dev_info(rdev->dev, "R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp);
794 WREG32(R_008020_GRBM_SOFT_RESET, tmp); 792 WREG32(R_008020_GRBM_SOFT_RESET, tmp);
795 (void)RREG32(R_008020_GRBM_SOFT_RESET); 793 RREG32(R_008020_GRBM_SOFT_RESET);
796 udelay(50); 794 mdelay(15);
797 WREG32(R_008020_GRBM_SOFT_RESET, 0); 795 WREG32(R_008020_GRBM_SOFT_RESET, 0);
798 (void)RREG32(R_008020_GRBM_SOFT_RESET);
799 /* Reset others GPU block if necessary */
800 if (G_000E50_RLC_BUSY(RREG32(R_000E50_SRBM_STATUS)))
801 srbm_reset |= S_000E60_SOFT_RESET_RLC(1);
802 if (G_000E50_GRBM_RQ_PENDING(RREG32(R_000E50_SRBM_STATUS)))
803 srbm_reset |= S_000E60_SOFT_RESET_GRBM(1);
804 if (G_000E50_HI_RQ_PENDING(RREG32(R_000E50_SRBM_STATUS)))
805 srbm_reset |= S_000E60_SOFT_RESET_IH(1);
806 if (G_000E50_VMC_BUSY(RREG32(R_000E50_SRBM_STATUS)))
807 srbm_reset |= S_000E60_SOFT_RESET_VMC(1);
808 if (G_000E50_MCB_BUSY(RREG32(R_000E50_SRBM_STATUS)))
809 srbm_reset |= S_000E60_SOFT_RESET_MC(1);
810 if (G_000E50_MCDZ_BUSY(RREG32(R_000E50_SRBM_STATUS)))
811 srbm_reset |= S_000E60_SOFT_RESET_MC(1);
812 if (G_000E50_MCDY_BUSY(RREG32(R_000E50_SRBM_STATUS)))
813 srbm_reset |= S_000E60_SOFT_RESET_MC(1);
814 if (G_000E50_MCDX_BUSY(RREG32(R_000E50_SRBM_STATUS)))
815 srbm_reset |= S_000E60_SOFT_RESET_MC(1);
816 if (G_000E50_MCDW_BUSY(RREG32(R_000E50_SRBM_STATUS)))
817 srbm_reset |= S_000E60_SOFT_RESET_MC(1);
818 if (G_000E50_RLC_BUSY(RREG32(R_000E50_SRBM_STATUS)))
819 srbm_reset |= S_000E60_SOFT_RESET_RLC(1);
820 if (G_000E50_SEM_BUSY(RREG32(R_000E50_SRBM_STATUS)))
821 srbm_reset |= S_000E60_SOFT_RESET_SEM(1);
822 if (G_000E50_BIF_BUSY(RREG32(R_000E50_SRBM_STATUS)))
823 srbm_reset |= S_000E60_SOFT_RESET_BIF(1);
824 dev_info(rdev->dev, " R_000E60_SRBM_SOFT_RESET=0x%08X\n", srbm_reset);
825 WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset);
826 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
827 mdelay(1);
828 WREG32(R_000E60_SRBM_SOFT_RESET, 0);
829 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
830 WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset);
831 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
832 mdelay(1);
833 WREG32(R_000E60_SRBM_SOFT_RESET, 0);
834 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
835 /* Wait a little for things to settle down */ 796 /* Wait a little for things to settle down */
836 mdelay(1); 797 mdelay(1);
837 dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n", 798 dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n",
@@ -840,10 +801,6 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
840 RREG32(R_008014_GRBM_STATUS2)); 801 RREG32(R_008014_GRBM_STATUS2));
841 dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n", 802 dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n",
842 RREG32(R_000E50_SRBM_STATUS)); 803 RREG32(R_000E50_SRBM_STATUS));
843 /* After reset we need to reinit the asic as GPU often endup in an
844 * incoherent state.
845 */
846 atom_asic_init(rdev->mode_info.atom_context);
847 rv515_mc_resume(rdev, &save); 804 rv515_mc_resume(rdev, &save);
848 return 0; 805 return 0;
849} 806}