drm/radeon/kms: Use surfaces for scanout / cursor byte swapping on big endian.
authorMichel Dänzer <daenzer@vmware.com>
Tue, 15 Sep 2009 15:09:30 +0000 (17:09 +0200)
committerDave Airlie <airlied@redhat.com>
Fri, 18 Sep 2009 06:01:59 +0000 (16:01 +1000)
Signed-off-by: Michel Dänzer <daenzer@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/radeon_fb.c
drivers/gpu/drm/radeon/radeon_object.c
include/drm/radeon_drm.h

index fa0fdc1..737970b 100644 (file)
@@ -2235,6 +2235,11 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg,
                        flags |= R300_SURF_TILE_MICRO;
        }
 
+       if (tiling_flags & RADEON_TILING_SWAP_16BIT)
+               flags |= RADEON_SURF_AP0_SWP_16BPP | RADEON_SURF_AP1_SWP_16BPP;
+       if (tiling_flags & RADEON_TILING_SWAP_32BIT)
+               flags |= RADEON_SURF_AP0_SWP_32BPP | RADEON_SURF_AP1_SWP_32BPP;
+
        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);
index 19e244a..944e4fa 100644 (file)
@@ -45,71 +45,9 @@ struct radeon_fb_device {
        struct radeon_device            *rdev;
 };
 
-static int radeon_fb_check_var(struct fb_var_screeninfo *var,
-                              struct fb_info *info)
-{
-       int ret;
-       ret = drm_fb_helper_check_var(var, info);
-       if (ret)
-               return ret;
-
-       /* big endian override for radeon endian workaround */
-#ifdef __BIG_ENDIAN
-       {
-               int depth;
-               switch (var->bits_per_pixel) {
-               case 16:
-                       depth = (var->green.length == 6) ? 16 : 15;
-                       break;
-               case 32:
-                       depth = (var->transp.length > 0) ? 32 : 24;
-                       break;
-               default:
-                       depth = var->bits_per_pixel;
-                       break;
-               }
-               switch (depth) {
-               case 8:
-                       var->red.offset = 0;
-                       var->green.offset = 0;
-                       var->blue.offset = 0;
-                       var->red.length = 8;
-                       var->green.length = 8;
-                       var->blue.length = 8;
-                       var->transp.length = 0;
-                       var->transp.offset = 0;
-                       break;
-               case 24:
-                       var->red.offset = 8;
-                       var->green.offset = 16;
-                       var->blue.offset = 24;
-                       var->red.length = 8;
-                       var->green.length = 8;
-                       var->blue.length = 8;
-                       var->transp.length = 0;
-                       var->transp.offset = 0;
-                       break;
-               case 32:
-                       var->red.offset = 8;
-                       var->green.offset = 16;
-                       var->blue.offset = 24;
-                       var->red.length = 8;
-                       var->green.length = 8;
-                       var->blue.length = 8;
-                       var->transp.length = 8;
-                       var->transp.offset = 0;
-                       break;
-               default:
-                       return -EINVAL;
-               }
-       }
-#endif
-       return 0;
-}
-
 static struct fb_ops radeonfb_ops = {
        .owner = THIS_MODULE,
-       .fb_check_var = radeon_fb_check_var,
+       .fb_check_var = drm_fb_helper_check_var,
        .fb_set_par = drm_fb_helper_set_par,
        .fb_setcolreg = drm_fb_helper_setcolreg,
        .fb_fillrect = cfb_fillrect,
@@ -206,6 +144,7 @@ int radeonfb_create(struct drm_device *dev,
        void *fbptr = NULL;
        unsigned long tmp;
        bool fb_tiled = false; /* useful for testing */
+       u32 tiling_flags = 0;
 
        mode_cmd.width = surface_width;
        mode_cmd.height = surface_height;
@@ -230,7 +169,22 @@ int radeonfb_create(struct drm_device *dev,
        robj = gobj->driver_private;
 
        if (fb_tiled)
-               radeon_object_set_tiling_flags(robj, RADEON_TILING_MACRO|RADEON_TILING_SURFACE, mode_cmd.pitch);
+               tiling_flags = RADEON_TILING_MACRO;
+
+#ifdef __BIG_ENDIAN
+       switch (mode_cmd.bpp) {
+       case 32:
+               tiling_flags |= RADEON_TILING_SWAP_32BIT;
+               break;
+       case 16:
+               tiling_flags |= RADEON_TILING_SWAP_16BIT;
+       default:
+               break;
+       }
+#endif
+
+       if (tiling_flags)
+               radeon_object_set_tiling_flags(robj, tiling_flags | RADEON_TILING_SURFACE, mode_cmd.pitch);
        mutex_lock(&rdev->ddev->struct_mutex);
        fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj);
        if (fb == NULL) {
@@ -313,45 +267,6 @@ int radeonfb_create(struct drm_device *dev,
        DRM_INFO("fb depth is %d\n", fb->depth);
        DRM_INFO("   pitch is %d\n", fb->pitch);
 
-#ifdef __BIG_ENDIAN
-       /* fill var sets defaults for this stuff - override
-          on big endian */
-       switch (fb->depth) {
-       case 8:
-               info->var.red.offset = 0;
-               info->var.green.offset = 0;
-               info->var.blue.offset = 0;
-               info->var.red.length = 8; /* 8bit DAC */
-               info->var.green.length = 8;
-               info->var.blue.length = 8;
-               info->var.transp.offset = 0;
-               info->var.transp.length = 0;
-               break;
-       case 24:
-               info->var.red.offset = 8;
-               info->var.green.offset = 16;
-               info->var.blue.offset = 24;
-               info->var.red.length = 8;
-               info->var.green.length = 8;
-               info->var.blue.length = 8;
-               info->var.transp.offset = 0;
-               info->var.transp.length = 0;
-               break;
-       case 32:
-               info->var.red.offset = 8;
-               info->var.green.offset = 16;
-               info->var.blue.offset = 24;
-               info->var.red.length = 8;
-               info->var.green.length = 8;
-               info->var.blue.length = 8;
-               info->var.transp.offset = 0;
-               info->var.transp.length = 8;
-               break;
-       default:
-               break;
-       }
-#endif
-
        fb->fbdev = info;
        rfbdev->rfb = rfb;
        rfbdev->rdev = rdev;
index 1500d5b..73af463 100644 (file)
@@ -188,6 +188,7 @@ int radeon_object_kmap(struct radeon_object *robj, void **ptr)
        if (ptr) {
                *ptr = robj->kptr;
        }
+       radeon_object_check_tiling(robj, 0, 0);
        return 0;
 }
 
@@ -200,6 +201,7 @@ void radeon_object_kunmap(struct radeon_object *robj)
        }
        robj->kptr = NULL;
        spin_unlock(&robj->tobj.lock);
+       radeon_object_check_tiling(robj, 0, 0);
        ttm_bo_kunmap(&robj->kmap);
 }
 
index b67bbd7..3b9932a 100644 (file)
@@ -802,11 +802,12 @@ struct drm_radeon_gem_create {
        uint32_t        flags;
 };
 
-#define RADEON_TILING_MACRO 0x1
-#define RADEON_TILING_MICRO 0x2
-#define RADEON_TILING_SWAP  0x4
-#define RADEON_TILING_SURFACE  0x8 /* this object requires a surface
-                                   * when mapped - i.e. front buffer */
+#define RADEON_TILING_MACRO       0x1
+#define RADEON_TILING_MICRO       0x2
+#define RADEON_TILING_SWAP_16BIT  0x4
+#define RADEON_TILING_SWAP_32BIT  0x8
+#define RADEON_TILING_SURFACE     0x10 /* this object requires a surface
+                                       * when mapped - i.e. front buffer */
 
 struct drm_radeon_gem_set_tiling {
        uint32_t        handle;