Commit c88f9f0c authored by Michel Dänzer's avatar Michel Dänzer Committed by Dave Airlie

drm/radeon/kms: Use surfaces for scanout / cursor byte swapping on big endian.

Signed-off-by: default avatarMichel Dänzer <daenzer@vmware.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 733289c2
...@@ -2235,6 +2235,11 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg, ...@@ -2235,6 +2235,11 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg,
flags |= R300_SURF_TILE_MICRO; 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); 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_INFO + surf_index, flags);
WREG32(RADEON_SURFACE0_LOWER_BOUND + surf_index, offset); WREG32(RADEON_SURFACE0_LOWER_BOUND + surf_index, offset);
......
...@@ -45,71 +45,9 @@ struct radeon_fb_device { ...@@ -45,71 +45,9 @@ struct radeon_fb_device {
struct radeon_device *rdev; 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 = { static struct fb_ops radeonfb_ops = {
.owner = THIS_MODULE, .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_set_par = drm_fb_helper_set_par,
.fb_setcolreg = drm_fb_helper_setcolreg, .fb_setcolreg = drm_fb_helper_setcolreg,
.fb_fillrect = cfb_fillrect, .fb_fillrect = cfb_fillrect,
...@@ -206,6 +144,7 @@ int radeonfb_create(struct drm_device *dev, ...@@ -206,6 +144,7 @@ int radeonfb_create(struct drm_device *dev,
void *fbptr = NULL; void *fbptr = NULL;
unsigned long tmp; unsigned long tmp;
bool fb_tiled = false; /* useful for testing */ bool fb_tiled = false; /* useful for testing */
u32 tiling_flags = 0;
mode_cmd.width = surface_width; mode_cmd.width = surface_width;
mode_cmd.height = surface_height; mode_cmd.height = surface_height;
...@@ -230,7 +169,22 @@ int radeonfb_create(struct drm_device *dev, ...@@ -230,7 +169,22 @@ int radeonfb_create(struct drm_device *dev,
robj = gobj->driver_private; robj = gobj->driver_private;
if (fb_tiled) 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); mutex_lock(&rdev->ddev->struct_mutex);
fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj); fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj);
if (fb == NULL) { if (fb == NULL) {
...@@ -313,45 +267,6 @@ int radeonfb_create(struct drm_device *dev, ...@@ -313,45 +267,6 @@ int radeonfb_create(struct drm_device *dev,
DRM_INFO("fb depth is %d\n", fb->depth); DRM_INFO("fb depth is %d\n", fb->depth);
DRM_INFO(" pitch is %d\n", fb->pitch); 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; fb->fbdev = info;
rfbdev->rfb = rfb; rfbdev->rfb = rfb;
rfbdev->rdev = rdev; rfbdev->rdev = rdev;
......
...@@ -188,6 +188,7 @@ int radeon_object_kmap(struct radeon_object *robj, void **ptr) ...@@ -188,6 +188,7 @@ int radeon_object_kmap(struct radeon_object *robj, void **ptr)
if (ptr) { if (ptr) {
*ptr = robj->kptr; *ptr = robj->kptr;
} }
radeon_object_check_tiling(robj, 0, 0);
return 0; return 0;
} }
...@@ -200,6 +201,7 @@ void radeon_object_kunmap(struct radeon_object *robj) ...@@ -200,6 +201,7 @@ void radeon_object_kunmap(struct radeon_object *robj)
} }
robj->kptr = NULL; robj->kptr = NULL;
spin_unlock(&robj->tobj.lock); spin_unlock(&robj->tobj.lock);
radeon_object_check_tiling(robj, 0, 0);
ttm_bo_kunmap(&robj->kmap); ttm_bo_kunmap(&robj->kmap);
} }
......
...@@ -802,11 +802,12 @@ struct drm_radeon_gem_create { ...@@ -802,11 +802,12 @@ struct drm_radeon_gem_create {
uint32_t flags; uint32_t flags;
}; };
#define RADEON_TILING_MACRO 0x1 #define RADEON_TILING_MACRO 0x1
#define RADEON_TILING_MICRO 0x2 #define RADEON_TILING_MICRO 0x2
#define RADEON_TILING_SWAP 0x4 #define RADEON_TILING_SWAP_16BIT 0x4
#define RADEON_TILING_SURFACE 0x8 /* this object requires a surface #define RADEON_TILING_SWAP_32BIT 0x8
* when mapped - i.e. front buffer */ #define RADEON_TILING_SURFACE 0x10 /* this object requires a surface
* when mapped - i.e. front buffer */
struct drm_radeon_gem_set_tiling { struct drm_radeon_gem_set_tiling {
uint32_t handle; uint32_t handle;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment