aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r300.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/r300.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/r300.c')
-rw-r--r--drivers/gpu/drm/radeon/r300.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 0e9eb761a90..9825fb19331 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -26,8 +26,9 @@
26 * Jerome Glisse 26 * Jerome Glisse
27 */ 27 */
28#include <linux/seq_file.h> 28#include <linux/seq_file.h>
29#include "drmP.h" 29#include <drm/drmP.h>
30#include "drm.h" 30#include <drm/drm.h>
31#include <drm/drm_crtc_helper.h>
31#include "radeon_reg.h" 32#include "radeon_reg.h"
32#include "radeon.h" 33#include "radeon.h"
33#include "radeon_asic.h" 34#include "radeon_asic.h"
@@ -426,12 +427,35 @@ int r300_ga_reset(struct radeon_device *rdev)
426 return -1; 427 return -1;
427} 428}
428 429
430bool r300_gpu_is_lockup(struct radeon_device *rdev)
431{
432 u32 rbbm_status;
433 int r;
434
435 rbbm_status = RREG32(R_000E40_RBBM_STATUS);
436 if (!G_000E40_GUI_ACTIVE(rbbm_status)) {
437 r100_gpu_lockup_update(&rdev->config.r300.lockup, &rdev->cp);
438 return false;
439 }
440 /* force CP activities */
441 r = radeon_ring_lock(rdev, 2);
442 if (!r) {
443 /* PACKET2 NOP */
444 radeon_ring_write(rdev, 0x80000000);
445 radeon_ring_write(rdev, 0x80000000);
446 radeon_ring_unlock_commit(rdev);
447 }
448 rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR);
449 return r100_gpu_cp_is_lockup(rdev, &rdev->config.r300.lockup, &rdev->cp);
450}
451
429int r300_gpu_reset(struct radeon_device *rdev) 452int r300_gpu_reset(struct radeon_device *rdev)
430{ 453{
431 uint32_t status; 454 uint32_t status;
432 455
433 /* reset order likely matter */ 456 /* reset order likely matter */
434 status = RREG32(RADEON_RBBM_STATUS); 457 status = RREG32(RADEON_RBBM_STATUS);
458 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
435 /* reset HDP */ 459 /* reset HDP */
436 r100_hdp_reset(rdev); 460 r100_hdp_reset(rdev);
437 /* reset rb2d */ 461 /* reset rb2d */