-----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;	

Reply via email to