drm/radeon/kms: Use surfaces for scanout / cursor byte swapping on big endian.
Signed-off-by: Michel Dänzer <daenzer@vmware.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
committed by
Dave Airlie
parent
733289c265
commit
c88f9f0c91
@@ -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 {
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
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 {
|
|||||||
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;
|
||||||
|
Reference in New Issue
Block a user