Commit 9939a481 authored by Krzysztof Helt's avatar Krzysztof Helt Committed by Linus Torvalds

s3c2410fb: use new margin fields

This patch makes use of margins fields in the s3c2410fb_display
structure.
Signed-off-by: default avatarKrzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: default avatarAntonino Daplas <adaplas@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 1f411537
...@@ -197,6 +197,14 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var, ...@@ -197,6 +197,14 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var,
return -EINVAL; return -EINVAL;
} }
/* it is always the size as the display */
var->xres_virtual = display->xres;
var->yres_virtual = display->yres;
/* copy lcd settings */
var->left_margin = display->left_margin;
var->right_margin = display->right_margin;
var->transp.offset = 0; var->transp.offset = 0;
var->transp.length = 0; var->transp.length = 0;
/* set r/g/b positions */ /* set r/g/b positions */
...@@ -270,45 +278,45 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var, ...@@ -270,45 +278,45 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var,
return 0; return 0;
} }
/* s3c2410fb_activate_var /* s3c2410fb_calculate_stn_lcd_regs
* *
* activate (set) the controller from the given framebuffer * calculate register values from var settings
* information
*/ */
static void s3c2410fb_activate_var(struct fb_info *info, static void s3c2410fb_calculate_stn_lcd_regs(const struct fb_info *info,
struct fb_var_screeninfo *var) struct s3c2410fb_hw *regs)
{ {
struct s3c2410fb_info *fbi = info->par; const struct s3c2410fb_info *fbi = info->par;
struct s3c2410fb_mach_info *mach_info = fbi->mach_info; const struct fb_var_screeninfo *var = &info->var;
struct s3c2410fb_display *display = mach_info->displays + int type = regs->lcdcon1 & ~S3C2410_LCDCON1_TFT;
fbi->current_display; int hs = var->xres >> 2;
int hs; unsigned wdly = (var->left_margin >> 4) - 1;
fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_MODEMASK;
fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_TFT;
dprintk("%s: var->xres = %d\n", __FUNCTION__, var->xres); dprintk("%s: var->xres = %d\n", __FUNCTION__, var->xres);
dprintk("%s: var->yres = %d\n", __FUNCTION__, var->yres); dprintk("%s: var->yres = %d\n", __FUNCTION__, var->yres);
dprintk("%s: var->bpp = %d\n", __FUNCTION__, var->bits_per_pixel); dprintk("%s: var->bpp = %d\n", __FUNCTION__, var->bits_per_pixel);
fbi->regs.lcdcon1 |= display->type; if (type != S3C2410_LCDCON1_STN4)
hs >>= 1;
regs->lcdcon1 &= ~S3C2410_LCDCON1_MODEMASK;
if (display->type == S3C2410_LCDCON1_TFT)
switch (var->bits_per_pixel) { switch (var->bits_per_pixel) {
case 1: case 1:
fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT1BPP; regs->lcdcon1 |= S3C2410_LCDCON1_STN1BPP;
break; break;
case 2: case 2:
fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT2BPP; regs->lcdcon1 |= S3C2410_LCDCON1_STN2GREY;
break; break;
case 4: case 4:
fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT4BPP; regs->lcdcon1 |= S3C2410_LCDCON1_STN4GREY;
break; break;
case 8: case 8:
fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT8BPP; regs->lcdcon1 |= S3C2410_LCDCON1_STN8BPP;
hs *= 3;
break; break;
case 16: case 12:
fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT16BPP; regs->lcdcon1 |= S3C2410_LCDCON1_STN12BPP;
hs *= 3;
break; break;
default: default:
...@@ -316,22 +324,55 @@ static void s3c2410fb_activate_var(struct fb_info *info, ...@@ -316,22 +324,55 @@ static void s3c2410fb_activate_var(struct fb_info *info,
dev_err(fbi->dev, "invalid bpp %d\n", dev_err(fbi->dev, "invalid bpp %d\n",
var->bits_per_pixel); var->bits_per_pixel);
} }
else /* update X/Y info */
dprintk("setting vert: up=%d, low=%d, sync=%d\n",
var->upper_margin, var->lower_margin, var->vsync_len);
dprintk("setting horz: lft=%d, rt=%d, sync=%d\n",
var->left_margin, var->right_margin, var->hsync_len);
regs->lcdcon2 &= ~S3C2410_LCDCON2_LINEVAL(0x3ff);
regs->lcdcon2 |= S3C2410_LCDCON2_LINEVAL(var->yres - 1);
if (wdly > 3)
wdly = 3;
regs->lcdcon3 = S3C2410_LCDCON3_WDLY(wdly) |
S3C2410_LCDCON3_LINEBLANK(var->right_margin / 8) |
S3C2410_LCDCON3_HOZVAL(hs - 1);
}
/* s3c2410fb_calculate_tft_lcd_regs
*
* calculate register values from var settings
*/
static void s3c2410fb_calculate_tft_lcd_regs(const struct fb_info *info,
struct s3c2410fb_hw *regs)
{
const struct s3c2410fb_info *fbi = info->par;
const struct fb_var_screeninfo *var = &info->var;
dprintk("%s: var->xres = %d\n", __FUNCTION__, var->xres);
dprintk("%s: var->yres = %d\n", __FUNCTION__, var->yres);
dprintk("%s: var->bpp = %d\n", __FUNCTION__, var->bits_per_pixel);
regs->lcdcon1 &= ~S3C2410_LCDCON1_MODEMASK;
switch (var->bits_per_pixel) { switch (var->bits_per_pixel) {
case 1: case 1:
fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN1BPP; regs->lcdcon1 |= S3C2410_LCDCON1_TFT1BPP;
break; break;
case 2: case 2:
fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN2GREY; regs->lcdcon1 |= S3C2410_LCDCON1_TFT2BPP;
break; break;
case 4: case 4:
fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN4GREY; regs->lcdcon1 |= S3C2410_LCDCON1_TFT4BPP;
break; break;
case 8: case 8:
fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN8BPP; regs->lcdcon1 |= S3C2410_LCDCON1_TFT8BPP;
break; break;
case 12: case 16:
fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN12BPP; regs->lcdcon1 |= S3C2410_LCDCON1_TFT16BPP;
break; break;
default: default:
...@@ -339,56 +380,50 @@ static void s3c2410fb_activate_var(struct fb_info *info, ...@@ -339,56 +380,50 @@ static void s3c2410fb_activate_var(struct fb_info *info,
dev_err(fbi->dev, "invalid bpp %d\n", dev_err(fbi->dev, "invalid bpp %d\n",
var->bits_per_pixel); var->bits_per_pixel);
} }
/* update X/Y info */
/* check to see if we need to update sync/borders */
if (!mach_info->fixed_syncs) {
dprintk("setting vert: up=%d, low=%d, sync=%d\n", dprintk("setting vert: up=%d, low=%d, sync=%d\n",
var->upper_margin, var->lower_margin, var->vsync_len); var->upper_margin, var->lower_margin, var->vsync_len);
dprintk("setting horz: lft=%d, rt=%d, sync=%d\n", dprintk("setting horz: lft=%d, rt=%d, sync=%d\n",
var->left_margin, var->right_margin, var->hsync_len); var->left_margin, var->right_margin, var->hsync_len);
regs->lcdcon2 &= ~S3C2410_LCDCON2_LINEVAL(0x3ff);
regs->lcdcon2 |= S3C2410_LCDCON2_LINEVAL(var->yres - 1);
regs->lcdcon3 = S3C2410_LCDCON3_HBPD(var->right_margin - 1) |
S3C2410_LCDCON3_HFPD(var->left_margin - 1) |
S3C2410_LCDCON3_HOZVAL(var->xres - 1);
}
/* s3c2410fb_activate_var
*
* activate (set) the controller from the given framebuffer
* information
*/
static void s3c2410fb_activate_var(struct fb_info *info)
{
struct s3c2410fb_info *fbi = info->par;
struct fb_var_screeninfo *var = &info->var;
struct s3c2410fb_mach_info *mach_info = fbi->mach_info;
struct s3c2410fb_display *display = mach_info->displays +
fbi->current_display;
/* set display type */
fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_TFT;
fbi->regs.lcdcon1 |= display->type;
/* check to see if we need to update sync/borders */
if (!mach_info->fixed_syncs) {
fbi->regs.lcdcon2 = fbi->regs.lcdcon2 =
S3C2410_LCDCON2_VBPD(var->upper_margin - 1) | S3C2410_LCDCON2_VBPD(var->upper_margin - 1) |
S3C2410_LCDCON2_VFPD(var->lower_margin - 1) | S3C2410_LCDCON2_VFPD(var->lower_margin - 1) |
S3C2410_LCDCON2_VSPW(var->vsync_len - 1); S3C2410_LCDCON2_VSPW(var->vsync_len - 1);
fbi->regs.lcdcon3 =
S3C2410_LCDCON3_HBPD(var->right_margin - 1) |
S3C2410_LCDCON3_HFPD(var->left_margin - 1);
fbi->regs.lcdcon4 &= ~S3C2410_LCDCON4_HSPW(0xff); fbi->regs.lcdcon4 &= ~S3C2410_LCDCON4_HSPW(0xff);
fbi->regs.lcdcon4 |= S3C2410_LCDCON4_HSPW(var->hsync_len - 1); fbi->regs.lcdcon4 |= S3C2410_LCDCON4_HSPW(var->hsync_len - 1);
} }
/* update X/Y info */
fbi->regs.lcdcon2 &= ~S3C2410_LCDCON2_LINEVAL(0x3ff);
fbi->regs.lcdcon2 |= S3C2410_LCDCON2_LINEVAL(var->yres - 1);
switch (display->type) {
case S3C2410_LCDCON1_DSCAN4:
case S3C2410_LCDCON1_STN8:
hs = var->xres / 8;
break;
case S3C2410_LCDCON1_STN4:
hs = var->xres / 4;
break;
default:
case S3C2410_LCDCON1_TFT:
hs = var->xres;
break;
}
/* Special cases : STN color displays */
if (((fbi->regs.lcdcon1 & S3C2410_LCDCON1_MODEMASK) == S3C2410_LCDCON1_STN8BPP) ||
((fbi->regs.lcdcon1 & S3C2410_LCDCON1_MODEMASK) == S3C2410_LCDCON1_STN12BPP))
hs = hs * 3;
fbi->regs.lcdcon3 &= ~S3C2410_LCDCON3_HOZVAL(0x7ff);
fbi->regs.lcdcon3 |= S3C2410_LCDCON3_HOZVAL(hs - 1);
if (var->pixclock > 0) { if (var->pixclock > 0) {
int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock); int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock);
...@@ -406,6 +441,11 @@ static void s3c2410fb_activate_var(struct fb_info *info, ...@@ -406,6 +441,11 @@ static void s3c2410fb_activate_var(struct fb_info *info,
fbi->regs.lcdcon1 |= S3C2410_LCDCON1_CLKVAL(clkdiv); fbi->regs.lcdcon1 |= S3C2410_LCDCON1_CLKVAL(clkdiv);
} }
if (display->type == S3C2410_LCDCON1_TFT)
s3c2410fb_calculate_tft_lcd_regs(info, &fbi->regs);
else
s3c2410fb_calculate_stn_lcd_regs(info, &fbi->regs);
/* write new registers */ /* write new registers */
dprintk("new register set:\n"); dprintk("new register set:\n");
...@@ -452,7 +492,7 @@ static int s3c2410fb_set_par(struct fb_info *info) ...@@ -452,7 +492,7 @@ static int s3c2410fb_set_par(struct fb_info *info)
/* activate this new configuration */ /* activate this new configuration */
s3c2410fb_activate_var(info, var); s3c2410fb_activate_var(info);
return 0; return 0;
} }
...@@ -848,6 +888,8 @@ static int __init s3c2410fb_probe(struct platform_device *pdev) ...@@ -848,6 +888,8 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
fbinfo->var.yres = display->yres; fbinfo->var.yres = display->yres;
fbinfo->var.yres_virtual = display->yres; fbinfo->var.yres_virtual = display->yres;
fbinfo->var.bits_per_pixel = display->bpp; fbinfo->var.bits_per_pixel = display->bpp;
fbinfo->var.left_margin = display->left_margin;
fbinfo->var.right_margin = display->right_margin;
fbinfo->var.upper_margin = fbinfo->var.upper_margin =
S3C2410_LCDCON2_GET_VBPD(mregs->lcdcon2) + 1; S3C2410_LCDCON2_GET_VBPD(mregs->lcdcon2) + 1;
...@@ -856,10 +898,6 @@ static int __init s3c2410fb_probe(struct platform_device *pdev) ...@@ -856,10 +898,6 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
fbinfo->var.vsync_len = fbinfo->var.vsync_len =
S3C2410_LCDCON2_GET_VSPW(mregs->lcdcon2) + 1; S3C2410_LCDCON2_GET_VSPW(mregs->lcdcon2) + 1;
fbinfo->var.left_margin =
S3C2410_LCDCON3_GET_HFPD(mregs->lcdcon3) + 1;
fbinfo->var.right_margin =
S3C2410_LCDCON3_GET_HBPD(mregs->lcdcon3) + 1;
fbinfo->var.hsync_len = fbinfo->var.hsync_len =
S3C2410_LCDCON4_GET_HSPW(mregs->lcdcon4) + 1; S3C2410_LCDCON4_GET_HSPW(mregs->lcdcon4) + 1;
......
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