Skip to content

Commit

Permalink
[ARM] pxafb: allow pxafb_set_par() to start from arbitrary yoffset
Browse files Browse the repository at this point in the history
Note the var->yres_virtual is only re-calculated from the fix.smem_len
when text mode acceleration is enabled (which is default), this is due
to the issue as Russell suggested below:

Previous experience of doing this with the X server and acornfb is that
it causes all sorts of problems - it seems to force the X server into
assuming that the framebuffer should be panned no matter what settings
you ask it for.

The recommended workaround (implemented in acornfb) is to only do these
kinds of adjustments if text mode acceleration is enabled.  IIRC, the X
server should be disabling text mode acceleration when it maps the
framebuffer.  I seem to remember that there are X servers which forget
to do that though.

Signed-off-by: Eric Miao <eric.miao@marvell.com>
Signed-off-by: Eric Miao <ycmiao@ycmiao-hp520.(none)>
  • Loading branch information
Eric Miao authored and Eric Miao committed Dec 29, 2008
1 parent 77e1967 commit 7e4b19c
Showing 1 changed file with 16 additions and 13 deletions.
29 changes: 16 additions & 13 deletions drivers/video/pxafb.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,6 @@ static void pxafb_setmode(struct fb_var_screeninfo *var,
var->lower_margin = mode->lower_margin;
var->sync = mode->sync;
var->grayscale = mode->cmap_greyscale;
var->xres_virtual = var->xres;
var->yres_virtual = var->yres;
}

/*
Expand Down Expand Up @@ -345,10 +343,14 @@ static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
return -EINVAL;
}

var->xres_virtual =
max(var->xres_virtual, var->xres);
var->yres_virtual =
max(var->yres_virtual, var->yres);
/* we don't support xpan, force xres_virtual to be equal to xres */
var->xres_virtual = var->xres;

if (var->accel_flags & FB_ACCELF_TEXT)
var->yres_virtual = fbi->fb.fix.smem_len /
(var->xres_virtual * var->bits_per_pixel / 8);
else
var->yres_virtual = max(var->yres_virtual, var->yres);

/*
* Setup the RGB parameters for this display.
Expand Down Expand Up @@ -878,7 +880,7 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var,
struct pxafb_info *fbi)
{
u_long flags;
size_t nbytes;
size_t nbytes, offset;

#if DEBUG_VAR
if (!(fbi->lccr0 & LCCR0_LCDT)) {
Expand Down Expand Up @@ -939,17 +941,18 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var,

fbi->reg_lccr3 |= pxafb_bpp_to_lccr3(var);

nbytes = var->yres * fbi->fb.fix.line_length;
nbytes = fbi->fb.fix.line_length * var->yres;
offset = fbi->fb.fix.line_length * var->yoffset;

if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual) {
nbytes = nbytes / 2;
setup_frame_dma(fbi, DMA_LOWER, PAL_NONE, nbytes, nbytes);
setup_frame_dma(fbi, DMA_LOWER, PAL_NONE, offset + nbytes, nbytes);
}

if ((var->bits_per_pixel >= 16) || (fbi->lccr0 & LCCR0_LCDT))
setup_frame_dma(fbi, DMA_BASE, PAL_NONE, 0, nbytes);
setup_frame_dma(fbi, DMA_BASE, PAL_NONE, offset, nbytes);
else
setup_frame_dma(fbi, DMA_BASE, PAL_BASE, 0, nbytes);
setup_frame_dma(fbi, DMA_BASE, PAL_BASE, offset, nbytes);

fbi->reg_lccr4 = lcd_readl(fbi, LCCR4) & ~LCCR4_PAL_FOR_MASK;
fbi->reg_lccr4 |= (fbi->lccr4 & LCCR4_PAL_FOR_MASK);
Expand Down Expand Up @@ -1362,15 +1365,15 @@ static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev)
fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS;
fbi->fb.fix.type_aux = 0;
fbi->fb.fix.xpanstep = 0;
fbi->fb.fix.ypanstep = 0;
fbi->fb.fix.ypanstep = 1;
fbi->fb.fix.ywrapstep = 0;
fbi->fb.fix.accel = FB_ACCEL_NONE;

fbi->fb.var.nonstd = 0;
fbi->fb.var.activate = FB_ACTIVATE_NOW;
fbi->fb.var.height = -1;
fbi->fb.var.width = -1;
fbi->fb.var.accel_flags = 0;
fbi->fb.var.accel_flags = FB_ACCELF_TEXT;
fbi->fb.var.vmode = FB_VMODE_NONINTERLACED;

fbi->fb.fbops = &pxafb_ops;
Expand Down

0 comments on commit 7e4b19c

Please sign in to comment.