summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/gma500/framebuffer.c
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2011-11-29 22:27:34 (GMT)
committerDave Airlie <airlied@redhat.com>2011-12-06 09:55:40 (GMT)
commit1b223c9ebf11e9597820fac57b211709f8ffce26 (patch)
treed249394aeb95edb1b7c60cf53959d1183cae860f /drivers/gpu/drm/gma500/framebuffer.c
parenta6ba582d264f67074f669f76172e8a2afadff2a4 (diff)
downloadlinux-fsl-qoriq-1b223c9ebf11e9597820fac57b211709f8ffce26.tar.xz
gma500: Be smarter about layout
If we can't fit a page aligned display stride then it's not the end of the world for a normal font, so try half a page and work down sizes. Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/gma500/framebuffer.c')
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.c46
1 files changed, 30 insertions, 16 deletions
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index 652f1ec..9ec1676 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -385,7 +385,8 @@ static int psbfb_create(struct psb_fbdev *fbdev,
int ret;
struct gtt_range *backing;
u32 bpp, depth;
- int gtt_roll = 1;
+ int gtt_roll = 0;
+ int pitch_lines = 0;
mode_cmd.width = sizes->surface_width;
mode_cmd.height = sizes->surface_height;
@@ -395,27 +396,40 @@ static int psbfb_create(struct psb_fbdev *fbdev,
if (bpp == 24)
bpp = 32;
- /* Acceleration via the GTT requires pitch to be 4096 byte aligned
- (ie 1024 or 2048 pixels in normal use) */
- mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((bpp + 7) / 8), 4096);
- depth = sizes->surface_depth;
+ do {
+ /*
+ * Acceleration via the GTT requires pitch to be
+ * power of two aligned. Preferably page but less
+ * is ok with some fonts
+ */
+ mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((bpp + 7) / 8), 4096 >> pitch_lines);
+ depth = sizes->surface_depth;
+
+ size = mode_cmd.pitches[0] * mode_cmd.height;
+ size = ALIGN(size, PAGE_SIZE);
+
+ /* Allocate the fb in the GTT with stolen page backing */
+ backing = psbfb_alloc(dev, size);
+
+ if (pitch_lines)
+ pitch_lines *= 2;
+ else
+ pitch_lines = 1;
+ gtt_roll++;
+ } while (backing == NULL && pitch_lines <= 16);
- size = mode_cmd.pitches[0] * mode_cmd.height;
- size = ALIGN(size, PAGE_SIZE);
+ /* The final pitch we accepted if we succeeded */
+ pitch_lines /= 2;
- /* Try and allocate with the alignment we need */
- backing = psbfb_alloc(dev, size);
if (backing == NULL) {
/*
* We couldn't get the space we wanted, fall back to the
* display engine requirement instead. The HW requires
* the pitch to be 64 byte aligned
- *
- * FIXME: We could try alignments in a loop so that we can still
- * accelerate power of two font sizes.
*/
gtt_roll = 0; /* Don't use GTT accelerated scrolling */
+ pitch_lines = 64;
mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((bpp + 7) / 8), 64);
@@ -452,12 +466,12 @@ static int psbfb_create(struct psb_fbdev *fbdev,
strcpy(info->fix.id, "psbfb");
info->flags = FBINFO_DEFAULT;
- if (gtt_roll) { /* GTT rolling seems best */
+ if (dev_priv->ops->accel_2d && pitch_lines > 8) /* 2D engine */
+ info->fbops = &psbfb_ops;
+ else if (gtt_roll) { /* GTT rolling seems best */
info->fbops = &psbfb_roll_ops;
info->flags |= FBINFO_HWACCEL_YPAN;
- } else if (dev_priv->ops->accel_2d) /* 2D engine */
- info->fbops = &psbfb_ops;
- else /* Software */
+ } else /* Software */
info->fbops = &psbfb_unaccel_ops;
ret = fb_alloc_cmap(&info->cmap, 256, 0);