Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+136 −98
Original line number Diff line number Diff line
@@ -197,6 +197,14 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var,
		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.length = 0;
	/* set r/g/b positions */
@@ -270,45 +278,45 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var,
	return 0;
}

/* s3c2410fb_activate_var
/* s3c2410fb_calculate_stn_lcd_regs
 *
 * activate (set) the controller from the given framebuffer
 * information
 * calculate register values from var settings
 */
static void s3c2410fb_activate_var(struct fb_info *info,
				   struct fb_var_screeninfo *var)
static void s3c2410fb_calculate_stn_lcd_regs(const struct fb_info *info,
					     struct s3c2410fb_hw *regs)
{
	struct s3c2410fb_info *fbi = info->par;
	struct s3c2410fb_mach_info *mach_info = fbi->mach_info;
	struct s3c2410fb_display *display = mach_info->displays +
					    fbi->current_display;
	int hs;

	fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_MODEMASK;
	fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_TFT;
	const struct s3c2410fb_info *fbi = info->par;
	const struct fb_var_screeninfo *var = &info->var;
	int type = regs->lcdcon1 & ~S3C2410_LCDCON1_TFT;
	int hs = var->xres >> 2;
	unsigned wdly = (var->left_margin >> 4) - 1;

	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);

	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) {
	case 1:
			fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT1BPP;
		regs->lcdcon1 |= S3C2410_LCDCON1_STN1BPP;
		break;
	case 2:
			fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT2BPP;
		regs->lcdcon1 |= S3C2410_LCDCON1_STN2GREY;
		break;
	case 4:
			fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT4BPP;
		regs->lcdcon1 |= S3C2410_LCDCON1_STN4GREY;
		break;
	case 8:
			fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT8BPP;
		regs->lcdcon1 |= S3C2410_LCDCON1_STN8BPP;
		hs *= 3;
		break;
		case 16:
			fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT16BPP;
	case 12:
		regs->lcdcon1 |= S3C2410_LCDCON1_STN12BPP;
		hs *= 3;
		break;

	default:
@@ -316,22 +324,55 @@ static void s3c2410fb_activate_var(struct fb_info *info,
		dev_err(fbi->dev, "invalid bpp %d\n",
			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) {
	case 1:
			fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN1BPP;
		regs->lcdcon1 |= S3C2410_LCDCON1_TFT1BPP;
		break;
	case 2:
			fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN2GREY;
		regs->lcdcon1 |= S3C2410_LCDCON1_TFT2BPP;
		break;
	case 4:
			fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN4GREY;
		regs->lcdcon1 |= S3C2410_LCDCON1_TFT4BPP;
		break;
	case 8:
			fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN8BPP;
		regs->lcdcon1 |= S3C2410_LCDCON1_TFT8BPP;
		break;
		case 12:
			fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN12BPP;
	case 16:
		regs->lcdcon1 |= S3C2410_LCDCON1_TFT16BPP;
		break;

	default:
@@ -339,56 +380,50 @@ static void s3c2410fb_activate_var(struct fb_info *info,
		dev_err(fbi->dev, "invalid bpp %d\n",
			var->bits_per_pixel);
	}

	/* check to see if we need to update sync/borders */

	if (!mach_info->fixed_syncs) {
	/* 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);

	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 =
			S3C2410_LCDCON2_VBPD(var->upper_margin - 1) |
			S3C2410_LCDCON2_VFPD(var->lower_margin - 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(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) {
		int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock);

@@ -406,6 +441,11 @@ static void s3c2410fb_activate_var(struct fb_info *info,
		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 */

	dprintk("new register set:\n");
@@ -452,7 +492,7 @@ static int s3c2410fb_set_par(struct fb_info *info)

	/* activate this new configuration */

	s3c2410fb_activate_var(info, var);
	s3c2410fb_activate_var(info);
	return 0;
}

@@ -848,6 +888,8 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
	fbinfo->var.yres	    = display->yres;
	fbinfo->var.yres_virtual    = display->yres;
	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    =
				S3C2410_LCDCON2_GET_VBPD(mregs->lcdcon2) + 1;
@@ -856,10 +898,6 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
	fbinfo->var.vsync_len	    =
				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	    =
				S3C2410_LCDCON4_GET_HSPW(mregs->lcdcon4) + 1;