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,
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);
......
......@@ -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;
......
......@@ -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);
}
......
......@@ -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;
......
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