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

Commit 34dec243 authored by Krzysztof Helt's avatar Krzysztof Helt Committed by Linus Torvalds
Browse files

tridentfb: various pixclock and timing improvements



This patch fixes few issues related to timings and pixclock generation:

 - disallow the pixclocks with numerator lower than
   double denominator. This fixes display instability
   for some modes.
 - choose the pixelclock with the highest
   numerator and denominator values. This improve
   image quality and fixes display instability
   for some modes.
 - make interlaced modes work.
 - set synchronization pulses polarization
   correctly.
 - horizontal synchronization timing are now
   the same as generated by X.

Signed-off-by: default avatarKrzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 2c86a0c2
Loading
Loading
Loading
Loading
+28 −7
Original line number Original line Diff line number Diff line
@@ -680,10 +680,12 @@ static void set_vclk(struct tridentfb_par *par, unsigned long freq)


	d = 20000;
	d = 20000;
	for (k = 1; k >= 0; k--)
	for (k = 1; k >= 0; k--)
		for (m = 0; m < 32; m++)
		for (m = 0; m < 32; m++) {
			for (n = 0; n < 122; n++) {
			n = 2 * (m + 2) - 8;
			for (n = (n < 0 ? 0 : n); n < 122; n++) {
				fi = ((14318l * (n + 8)) / (m + 2)) >> k;
				fi = ((14318l * (n + 8)) / (m + 2)) >> k;
				if ((di = abs(fi - freq)) < d) {
				di = abs(fi - freq);
				if (di <= d) {
					d = di;
					d = di;
					best_n = n;
					best_n = n;
					best_m = m;
					best_m = m;
@@ -692,6 +694,7 @@ static void set_vclk(struct tridentfb_par *par, unsigned long freq)
				if (fi > freq)
				if (fi > freq)
					break;
					break;
			}
			}
		}


	if (is_oldclock(par->chip_id)) {
	if (is_oldclock(par->chip_id)) {
		lo = best_n | (best_m << 7);
		lo = best_n | (best_m << 7);
@@ -977,8 +980,8 @@ static int tridentfb_set_par(struct fb_info *info)


	debug("enter\n");
	debug("enter\n");
	hdispend = var->xres / 8 - 1;
	hdispend = var->xres / 8 - 1;
	hsyncstart = (var->xres + var->right_margin) / 8 - 1;
	hsyncstart = (var->xres + var->right_margin) / 8;
	hsyncend = (var->xres + var->right_margin + var->hsync_len) / 8 - 1;
	hsyncend = (var->xres + var->right_margin + var->hsync_len) / 8;
	htotal = (var->xres + var->left_margin + var->right_margin +
	htotal = (var->xres + var->left_margin + var->right_margin +
		  var->hsync_len) / 8 - 5;
		  var->hsync_len) / 8 - 5;
	hblankstart = hdispend + 1;
	hblankstart = hdispend + 1;
@@ -991,8 +994,22 @@ static int tridentfb_set_par(struct fb_info *info)
	vblankstart = vdispend + 1;
	vblankstart = vdispend + 1;
	vblankend = vtotal;
	vblankend = vtotal;


	if (info->var.vmode & FB_VMODE_INTERLACED) {
		vtotal /= 2;
		vdispend /= 2;
		vsyncstart /= 2;
		vsyncend /= 2;
		vblankstart /= 2;
		vblankend /= 2;
	}

	crtc_unlock(par);
	crtc_unlock(par);
	write3CE(par, CyberControl, 8);
	write3CE(par, CyberControl, 8);
	tmp = 0xEB;
	if (var->sync & FB_SYNC_HOR_HIGH_ACT)
		tmp &= ~0x40;
	if (var->sync & FB_SYNC_VERT_HIGH_ACT)
		tmp &= ~0x80;


	if (par->flatpanel && var->xres < nativex) {
	if (par->flatpanel && var->xres < nativex) {
		/*
		/*
@@ -1000,7 +1017,7 @@ static int tridentfb_set_par(struct fb_info *info)
		 * than requested resolution decide whether
		 * than requested resolution decide whether
		 * we stretch or center
		 * we stretch or center
		 */
		 */
		t_outb(par, 0xEB, VGA_MIS_W);
		t_outb(par, tmp | 0xC0, VGA_MIS_W);


		shadowmode_on(par);
		shadowmode_on(par);


@@ -1010,7 +1027,7 @@ static int tridentfb_set_par(struct fb_info *info)
			screen_stretch(par);
			screen_stretch(par);


	} else {
	} else {
		t_outb(par, 0x2B, VGA_MIS_W);
		t_outb(par, tmp, VGA_MIS_W);
		write3CE(par, CyberControl, 8);
		write3CE(par, CyberControl, 8);
	}
	}


@@ -1071,6 +1088,10 @@ static int tridentfb_set_par(struct fb_info *info)
	tmp = (info->var.vmode & FB_VMODE_INTERLACED) ? 0x84 : 0x80;
	tmp = (info->var.vmode & FB_VMODE_INTERLACED) ? 0x84 : 0x80;
	/* enable access extended memory */
	/* enable access extended memory */
	write3X4(par, CRTCModuleTest, tmp);
	write3X4(par, CRTCModuleTest, tmp);
	tmp = read3CE(par, MiscIntContReg) & ~0x4;
	if (info->var.vmode & FB_VMODE_INTERLACED)
		tmp |= 0x4;
	write3CE(par, MiscIntContReg, tmp);


	/* enable GE for text acceleration */
	/* enable GE for text acceleration */
	write3X4(par, GraphEngReg, 0x80);
	write3X4(par, GraphEngReg, 0x80);