aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r600.c
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2010-03-09 09:45:10 -0500
committerDave Airlie <airlied@redhat.com>2010-04-05 20:42:45 -0400
commit225758d8ba4fdcc1e8c9cf617fd89529bd4a9596 (patch)
treea9ac2f23435d4a6db5aa33774ba94d9f0aeb5c4c /drivers/gpu/drm/radeon/r600.c
parent95beb690170e6ce918fe53c73a0fcc7cf64d704a (diff)
drm/radeon/kms: fence cleanup + more reliable GPU lockup detection V4
This patch cleanup the fence code, it drops the timeout field of fence as the time to complete each IB is unpredictable and shouldn't be bound. The fence cleanup lead to GPU lockup detection improvement, this patch introduce a callback, allowing to do asic specific test for lockup detection. In this patch the CP is use as a first indicator of GPU lockup. If CP doesn't make progress during 1second we assume we are facing a GPU lockup. To avoid overhead of testing GPU lockup frequently due to fence taking time to be signaled we query the lockup callback every 500msec. There is plenty code comment explaining the design & choise inside the code. This have been tested mostly on R3XX/R5XX hw, in normal running destkop (compiz firefox, quake3 running) the lockup callback wasn't call once (1 hour session). Also tested with forcing GPU lockup and lockup was reported after the 1s CP activity timeout. V2 switch to 500ms timeout so GPU lockup get call at least 2 times in less than 2sec. V3 store last jiffies in fence struct so on ERESTART, EBUSY we keep track of how long we already wait for a given fence V4 make sure we got up to date cp read pointer so we don't have false positive 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.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 5509354c7c89..a09c062df4db 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -784,7 +784,7 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
784 dev_info(rdev->dev, " R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp); 784 dev_info(rdev->dev, " R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp);
785 WREG32(R_008020_GRBM_SOFT_RESET, tmp); 785 WREG32(R_008020_GRBM_SOFT_RESET, tmp);
786 (void)RREG32(R_008020_GRBM_SOFT_RESET); 786 (void)RREG32(R_008020_GRBM_SOFT_RESET);
787 udelay(50); 787 mdelay(1);
788 WREG32(R_008020_GRBM_SOFT_RESET, 0); 788 WREG32(R_008020_GRBM_SOFT_RESET, 0);
789 (void)RREG32(R_008020_GRBM_SOFT_RESET); 789 (void)RREG32(R_008020_GRBM_SOFT_RESET);
790 } 790 }
@@ -824,16 +824,16 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
824 dev_info(rdev->dev, " R_000E60_SRBM_SOFT_RESET=0x%08X\n", srbm_reset); 824 dev_info(rdev->dev, " R_000E60_SRBM_SOFT_RESET=0x%08X\n", srbm_reset);
825 WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset); 825 WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset);
826 (void)RREG32(R_000E60_SRBM_SOFT_RESET); 826 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
827 udelay(50); 827 mdelay(1);
828 WREG32(R_000E60_SRBM_SOFT_RESET, 0); 828 WREG32(R_000E60_SRBM_SOFT_RESET, 0);
829 (void)RREG32(R_000E60_SRBM_SOFT_RESET); 829 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
830 WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset); 830 WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset);
831 (void)RREG32(R_000E60_SRBM_SOFT_RESET); 831 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
832 udelay(50); 832 mdelay(1);
833 WREG32(R_000E60_SRBM_SOFT_RESET, 0); 833 WREG32(R_000E60_SRBM_SOFT_RESET, 0);
834 (void)RREG32(R_000E60_SRBM_SOFT_RESET); 834 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
835 /* Wait a little for things to settle down */ 835 /* Wait a little for things to settle down */
836 udelay(50); 836 mdelay(1);
837 dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n", 837 dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n",
838 RREG32(R_008010_GRBM_STATUS)); 838 RREG32(R_008010_GRBM_STATUS));
839 dev_info(rdev->dev, " R_008014_GRBM_STATUS2=0x%08X\n", 839 dev_info(rdev->dev, " R_008014_GRBM_STATUS2=0x%08X\n",
@@ -848,6 +848,32 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
848 return 0; 848 return 0;
849} 849}
850 850
851bool r600_gpu_is_lockup(struct radeon_device *rdev)
852{
853 u32 srbm_status;
854 u32 grbm_status;
855 u32 grbm_status2;
856 int r;
857
858 srbm_status = RREG32(R_000E50_SRBM_STATUS);
859 grbm_status = RREG32(R_008010_GRBM_STATUS);
860 grbm_status2 = RREG32(R_008014_GRBM_STATUS2);
861 if (!G_008010_GUI_ACTIVE(grbm_status)) {
862 r100_gpu_lockup_update(&rdev->config.r300.lockup, &rdev->cp);
863 return false;
864 }
865 /* force CP activities */
866 r = radeon_ring_lock(rdev, 2);
867 if (!r) {
868 /* PACKET2 NOP */
869 radeon_ring_write(rdev, 0x80000000);
870 radeon_ring_write(rdev, 0x80000000);
871 radeon_ring_unlock_commit(rdev);
872 }
873 rdev->cp.rptr = RREG32(R600_CP_RB_RPTR);
874 return r100_gpu_cp_is_lockup(rdev, &rdev->config.r300.lockup, &rdev->cp);
875}
876
851int r600_gpu_reset(struct radeon_device *rdev) 877int r600_gpu_reset(struct radeon_device *rdev)
852{ 878{
853 return r600_gpu_soft_reset(rdev); 879 return r600_gpu_soft_reset(rdev);