radeon/kms: fix powerpc/rn50 untiled behaviour.
authorDave Airlie <airlied@redhat.com>
Fri, 11 Jun 2010 04:40:16 +0000 (14:40 +1000)
committerDave Airlie <airlied@redhat.com>
Mon, 14 Jun 2010 23:56:00 +0000 (09:56 +1000)
Installing 2.6.34 on a Power5/rn50 combo machine, X showed buggy sw rendering,
enabling tiling in the DDX fixed it. Investigation showed that a further /16
was needed in the untiled case on this chipset. Need further investigations
on what other chips this could affect, possibly rv100->rv280.

Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/radeon/r100.c

index cf89aa2eb28c07cb61054f43db647c5ec4ff9f59..1930db6d1771c4c02f4a588e13335ef321a22f7d 100644 (file)
@@ -2604,12 +2604,6 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg,
        int surf_index = reg * 16;
        int flags = 0;
 
-       /* r100/r200 divide by 16 */
-       if (rdev->family < CHIP_R300)
-               flags = pitch / 16;
-       else
-               flags = pitch / 8;
-
        if (rdev->family <= CHIP_RS200) {
                if ((tiling_flags & (RADEON_TILING_MACRO|RADEON_TILING_MICRO))
                                 == (RADEON_TILING_MACRO|RADEON_TILING_MICRO))
@@ -2633,6 +2627,20 @@ 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;
+       else
+               flags |= pitch / 8;
+
+
        DRM_DEBUG("writing surface %d %d %x %x\n", reg, flags, offset, offset+obj_size-1);
        WREG32(RADEON_SURFACE0_INFO + surf_index, flags);
        WREG32(RADEON_SURFACE0_LOWER_BOUND + surf_index, offset);