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:
Родитель
733289c265
Коммит
c88f9f0c91
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче