-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
As you may be aware, I was trying to get R300 support into a state where it
is possible to start OpenGL applications, let them hang the CP and *not*
bring down the entire machine.
Looks like I was successful :)
The attached patch ati.unlock.1.patch against the DDX makes sure the RBBM
(whatever that means; I'm guessing Ring Buffer something or other) is reset
in RADEONEngineReset(), before any other register is accessed that could
potentially cause a final crash (DSTCACHE_* is the major offender in this
category).
Now since I don't have any Radeon-related documentation at all, I have no
idea whether this patch will work on any other chip. For all that I know,
it might totally break the driver on R100/R200. I'm especially confused by
the fact that the bottom half of EngineReset() treats RBBM_SOFT_RESET
differently for the R300. Can anybody explain why?
Maybe it would even be safest/cleanest to move the entire RBBM_SOFT_RESET
block to the top of the function?
I can now launch glxgears several times in a row. It will be killed a few
seconds later (during this time the GUI will hang), and as far as I can
tell, everything continues to work normally.
Of course, for all I know the 3D part of the chip might still be wedged
internally, which would make this patch (partially) useless for working on
the driver. I guess I'll find out soon enough.
Important: You'll need my watchdog patch for the DRM from that other thread.
Otherwise, the reset code in the X server will never be called, and this
patch will have no effect.
I would also like to point out that the modified xf86 driver that was posted
on this list (see http://volodya-project.sourceforge.net/R300.php) does
not check the version of the DRM. I know, this is really a silly, minor
point to make at this time, but I've attached a small patch to fix this
anyway.
cu,
Nicolai
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
iD8DBQFAs6SssxPozBga0lwRAsKwAJ0eyDj01OjMybqe18du3Qs06peOSACaAkVL
B9hN0+nizrYWhM6/nXcf6uE=
=4tp0
-----END PGP SIGNATURE-----
diff -ur -x '*.o' ati-vladimir/radeon_accel.c ati/radeon_accel.c
--- ati-vladimir/radeon_accel.c 2004-05-20 16:02:24.000000000 +0200
+++ ati/radeon_accel.c 2004-05-25 21:14:24.000000000 +0200
@@ -170,6 +170,31 @@
CARD32 rbbm_soft_reset;
CARD32 host_path_cntl;
+ /* The following RBBM_SOFT_RESET sequence can help un-wedge
+ * an R300 after the command processor got stuck.
+ */
+ rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET);
+ OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
+ RADEON_SOFT_RESET_CP |
+ RADEON_SOFT_RESET_HI |
+ RADEON_SOFT_RESET_SE |
+ RADEON_SOFT_RESET_RE |
+ RADEON_SOFT_RESET_PP |
+ RADEON_SOFT_RESET_E2 |
+ RADEON_SOFT_RESET_RB));
+ INREG(RADEON_RBBM_SOFT_RESET);
+ OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset & (CARD32)
+ ~(RADEON_SOFT_RESET_CP |
+ RADEON_SOFT_RESET_HI |
+ RADEON_SOFT_RESET_SE |
+ RADEON_SOFT_RESET_RE |
+ RADEON_SOFT_RESET_PP |
+ RADEON_SOFT_RESET_E2 |
+ RADEON_SOFT_RESET_RB)));
+ INREG(RADEON_RBBM_SOFT_RESET);
+ OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
+ INREG(RADEON_RBBM_SOFT_RESET);
+
RADEONEngineFlush(pScrn);
clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX);
diff -ur -x '*.o' ati-vladimir/radeon_accelfuncs.c ati/radeon_accelfuncs.c
--- ati-vladimir/radeon_accelfuncs.c 2004-05-20 16:02:24.000000000 +0200
+++ ati/radeon_accelfuncs.c 2004-05-25 21:13:37.000000000 +0200
@@ -122,7 +122,7 @@
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"%s: CP idle %d\n", __FUNCTION__, ret);
}
- } while ((ret == -EBUSY) && (i++ < RADEON_TIMEOUT));
+ } while ((ret == -EBUSY) && (i++ < RADEON_TIMEOUT/10000)); /* the ioctl has an internal delay */
if (ret == 0) return;
--- ati-vladimir/radeon_dri.c 2004-05-20 16:02:24.000000000 +0200
+++ ati/radeon_dri.c 2004-05-20 16:13:47.000000000 +0200
@@ -1369,6 +1369,9 @@
if (info->IsIGP) {
req_minor = 10;
req_patch = 0;
+ } else if (info->ChipFamily >= CHIP_FAMILY_R300) {
+ req_minor = 11;
+ req_patch = 1;
} else if (info->ChipFamily >= CHIP_FAMILY_R200) {
req_minor = 5;
req_patch = 0;