[PATCH] radeon: Fix surface register on r100

Mark Kettenis mark.kettenis at xs4all.nl
Wed Jul 3 15:40:32 PDT 2013


Working on KMS support on OpenBSD/sparc64, I ended up with the initial
framebuffer on a Sun XVR-100 card (Radeon 7000/VE, RV100 with
OpenFirmware) being tiled when none of the tiling flags were set.
Tracked it down to an issue with r100_set_surface_reg().  The tiling
bits on these older chips are a bit different than the later ones.
There is no real flag for macro tiled buffer;
RADEON_SURF_TILE_COLOR_MACRO is 0.  So if we aren't actually tiling,
we can't actually indicate that by not setting that bit.  Instead we
should make sure that we set the size of tiles to 0.  The diff below
reorganizes the code handling these variants a bit to do that.  It
also seems that you can't have a buffer that's only micro tiled.  The
diff turns that into a BUG(), but perhaps that isn't such a good idea
since I believe that userland can actually request such a tiling and
the ioctl code doesn't check this.  So perhaps it should just fall
through into the no-tiling case.

With this fixed, I'm pretty sure the special RN50 handling can go.
The extra /= 16 was probably enough to make the pitch small enough to
keep the hardware from tiling.

Signed-off-by: Mark Kettenis <kettenis at openbsd.org>

diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index d0314ec..84d832a 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -3072,11 +3072,20 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg,
 	int flags = 0;
 
 	if (rdev->family <= CHIP_RS200) {
-		if ((tiling_flags & (RADEON_TILING_MACRO|RADEON_TILING_MICRO))
-				 == (RADEON_TILING_MACRO|RADEON_TILING_MICRO))
+		switch (tiling_flags & (RADEON_TILING_MACRO|RADEON_TILING_MICRO)) {
+		case RADEON_TILING_MACRO|RADEON_TILING_MICRO:
 			flags |= RADEON_SURF_TILE_COLOR_BOTH;
-		if (tiling_flags & RADEON_TILING_MACRO)
+			break;
+		case RADEON_TILING_MACRO:
 			flags |= RADEON_SURF_TILE_COLOR_MACRO;
+			break;
+		case RADEON_TILING_MICRO:
+			BUG();
+			break;
+		case 0:
+			pitch = 0;
+			break;
+		}
 	} else if (rdev->family <= CHIP_RV280) {
 		if (tiling_flags & (RADEON_TILING_MACRO))
 			flags |= R200_SURF_TILE_COLOR_MACRO;
@@ -3094,13 +3103,6 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg,
 	if (tiling_flags & RADEON_TILING_SWAP_32BIT)
 		flags |= RADEON_SURF_AP0_SWP_32BPP | RADEON_SURF_AP1_SWP_32BPP;
 
-	/* when we aren't tiling the pitch seems to needs to be furtherdivided down. - tested on power5 + rn50 server */
-	if (tiling_flags & (RADEON_TILING_SWAP_16BIT | RADEON_TILING_SWAP_32BIT)) {
-		if (!(tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO)))
-			if (ASIC_IS_RN50(rdev))
-				pitch /= 16;
-	}
-
 	/* r100/r200 divide by 16 */
 	if (rdev->family < CHIP_R300)
 		flags |= pitch / 16;


More information about the dri-devel mailing list