All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Antonino A. Daplas" <adaplas@gmail.com>
To: Andrew Morton <akpm@osdl.org>
Cc: Linux Fbdev development list <linux-fbdev-devel@lists.sourceforge.net>
Subject: [PATCH 32/33] tdfxfb: 3 fixes
Date: Thu, 26 Jul 2007 20:52:05 +0800	[thread overview]
Message-ID: <46A898F5.7030201@gmail.com> (raw)

From: Krzysztof Helt <krzysztof.h1@wp.pl>

This patch fixes 3 issues:
- transparency handling in tdfxfb
- panning with more than 4096 virtual height and acceleration (acceleration
with x & y > 4096)
- exit paths on errors in tdfxfb_probe()

Additionally it sets a FBINFO_READS_FAST flag to use smart blitter scrolling
(speed up on tdfxfb).

Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: Antonino Daplas <adaplas@gmail.com>
---

 drivers/video/tdfxfb.c |  172 ++++++++++++++++++++++++++++++------------------
 1 files changed, 108 insertions(+), 64 deletions(-)

diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index e6aced9..2566683 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -502,6 +502,8 @@ static int tdfxfb_check_var(struct fb_va
 		return -EINVAL;
 	}
 
+	var->transp.offset = 0;
+	var->transp.length = 0;
 	switch (var->bits_per_pixel) {
 	case 8:
 		var->red.length = var->green.length = var->blue.length = 8;
@@ -515,10 +517,12 @@ static int tdfxfb_check_var(struct fb_va
 		var->blue.length  = 5;
 		break;
 	case 32:
+		var->transp.offset = 24;
+		var->transp.length = 8;
 	case 24:
-		var->red.offset=16;
-		var->green.offset=8;
-		var->blue.offset=0;
+		var->red.offset = 16;
+		var->green.offset = 8;
+		var->blue.offset = 0;
 		var->red.length = var->green.length = var->blue.length = 8;
 		break;
 	}
@@ -874,13 +878,26 @@ static void tdfxfb_fillrect(struct fb_in
 	u32 stride = info->fix.line_length;
 	u32 fmt= stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13);
 	int tdfx_rop;
+	u32 dx = rect->dx;
+	u32 dy = rect->dy;
+	u32 dstbase = 0;
 
 	if (rect->rop == ROP_COPY)
 		tdfx_rop = TDFX_ROP_COPY;
 	else
 		tdfx_rop = TDFX_ROP_XOR;
 
-	banshee_make_room(par, 5);
+	/* asume always rect->height < 4096 */
+	if (dy + rect->height > 4095) {
+		dstbase = stride * dy;
+		dy = 0;
+	}
+	/* asume always rect->width < 4096 */
+	if (dx + rect->width > 4095) {
+		dstbase += dx * bpp >> 3;
+		dx = 0;
+	}
+	banshee_make_room(par, 6);
 	tdfx_outl(par, DSTFORMAT, fmt);
 	if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR) {
 		tdfx_outl(par, COLORFORE, rect->color);
@@ -888,8 +905,9 @@ static void tdfxfb_fillrect(struct fb_in
 		tdfx_outl(par, COLORFORE, par->palette[rect->color]);
 	}
 	tdfx_outl(par, COMMAND_2D, COMMAND_2D_FILLRECT | (tdfx_rop << 24));
+	tdfx_outl(par, DSTBASE, dstbase);
 	tdfx_outl(par, DSTSIZE, rect->width | (rect->height << 16));
-	tdfx_outl(par, LAUNCH_2D, rect->dx | (rect->dy << 16));
+	tdfx_outl(par, LAUNCH_2D, dx | (dy << 16));
 }
 
 /*
@@ -904,6 +922,30 @@ static void tdfxfb_copyarea(struct fb_in
 	u32 stride = info->fix.line_length;
 	u32 blitcmd = COMMAND_2D_S2S_BITBLT | (TDFX_ROP_COPY << 24);
 	u32 fmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13);
+	u32 dstbase = 0;
+	u32 srcbase = 0;
+
+	/* asume always area->height < 4096 */
+	if (sy + area->height > 4095) {
+		srcbase = stride * sy;
+		sy = 0;
+	}
+	/* asume always area->width < 4096 */
+	if (sx + area->width > 4095) {
+		srcbase += sx * bpp >> 3;
+		sx = 0;
+	}
+	/* asume always area->height < 4096 */
+	if (dy + area->height > 4095) {
+		dstbase = stride * dy;
+		dy = 0;
+	}
+	/* asume always area->width < 4096 */
+	if (dx + area->width > 4095) {
+		dstbase += dx * bpp >> 3;
+		dx = 0;
+	}
+
 
 	if (area->sx <= area->dx) {
 		//-X
@@ -918,13 +960,15 @@ static void tdfxfb_copyarea(struct fb_in
 		dy += area->height - 1;
 	}
 
-	banshee_make_room(par, 6);
+	banshee_make_room(par, 8);
 
 	tdfx_outl(par, SRCFORMAT, fmt);
 	tdfx_outl(par, DSTFORMAT, fmt);
 	tdfx_outl(par, COMMAND_2D, blitcmd);
 	tdfx_outl(par, DSTSIZE, area->width | (area->height << 16));
 	tdfx_outl(par, DSTXY, dx | (dy << 16));
+	tdfx_outl(par, SRCBASE, srcbase);
+	tdfx_outl(par, DSTBASE, dstbase);
 	tdfx_outl(par, LAUNCH_2D, sx | (sy << 16));
 }
 
@@ -938,35 +982,48 @@ static void tdfxfb_imageblit(struct fb_i
 	u32 dstfmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13);
 	u8 *chardata = (u8 *) image->data;
 	u32 srcfmt;
+	u32 dx = image->dx;
+	u32 dy = image->dy;
+	u32 dstbase = 0;
 
 	if (image->depth != 1) {
 		//banshee_make_room(par, 6 + ((size + 3) >> 2));
 		//srcfmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13) | 0x400000;
 		cfb_imageblit(info, image);
 		return;
-	} else {
-		banshee_make_room(par, 8);
-		switch (info->fix.visual) {
-		case FB_VISUAL_PSEUDOCOLOR:
-			tdfx_outl(par, COLORFORE, image->fg_color);
-			tdfx_outl(par, COLORBACK, image->bg_color);
-			break;
-		case FB_VISUAL_TRUECOLOR:
-		default:
-			tdfx_outl(par, COLORFORE,
-				  par->palette[image->fg_color]);
-			tdfx_outl(par, COLORBACK,
-				  par->palette[image->bg_color]);
-		}
+	}
+	banshee_make_room(par, 9);
+	switch (info->fix.visual) {
+	case FB_VISUAL_PSEUDOCOLOR:
+		tdfx_outl(par, COLORFORE, image->fg_color);
+		tdfx_outl(par, COLORBACK, image->bg_color);
+		break;
+	case FB_VISUAL_TRUECOLOR:
+	default:
+		tdfx_outl(par, COLORFORE,
+			  par->palette[image->fg_color]);
+		tdfx_outl(par, COLORBACK,
+			  par->palette[image->bg_color]);
+	}
 #ifdef __BIG_ENDIAN
-		srcfmt = 0x400000 | BIT(20);
+	srcfmt = 0x400000 | BIT(20);
 #else
-		srcfmt = 0x400000;
+	srcfmt = 0x400000;
 #endif
+	/* asume always image->height < 4096 */
+	if (dy + image->height > 4095) {
+		dstbase = stride * dy;
+		dy = 0;
+	}
+	/* asume always image->width < 4096 */
+	if (dx + image->width > 4095) {
+		dstbase += dx * bpp >> 3;
+		dx = 0;
 	}
 
+	tdfx_outl(par, DSTBASE, dstbase);
 	tdfx_outl(par, SRCXY, 0);
-	tdfx_outl(par, DSTXY, image->dx | (image->dy << 16));
+	tdfx_outl(par, DSTXY, dx | (dy << 16));
 	tdfx_outl(par, COMMAND_2D, COMMAND_2D_H2S_BITBLT | (TDFX_ROP_COPY << 24));
 	tdfx_outl(par, SRCFORMAT, srcfmt);
 	tdfx_outl(par, DSTFORMAT, dstfmt);
@@ -1211,44 +1268,36 @@ static int __devinit tdfxfb_probe(struct
 
 	tdfx_fix.mmio_start = pci_resource_start(pdev, 0);
 	tdfx_fix.mmio_len = pci_resource_len(pdev, 0);
+	if (!request_mem_region(tdfx_fix.mmio_start, tdfx_fix.mmio_len,
+				"tdfx regbase")) {
+		printk(KERN_WARNING "tdfxfb: Can't reserve regbase\n");
+		goto out_err;
+	}
+
 	default_par->regbase_virt =
 		ioremap_nocache(tdfx_fix.mmio_start, tdfx_fix.mmio_len);
 	if (!default_par->regbase_virt) {
 		printk("fb: Can't remap %s register area.\n", tdfx_fix.id);
-		goto out_err;
-	}
-
-	if (!request_mem_region(pci_resource_start(pdev, 0),
-				pci_resource_len(pdev, 0), "tdfx regbase")) {
-		printk(KERN_WARNING "tdfxfb: Can't reserve regbase\n");
-		goto out_err;
+		goto out_err_regbase;
 	}
 
 	tdfx_fix.smem_start = pci_resource_start(pdev, 1);
 	if (!(tdfx_fix.smem_len = do_lfb_size(default_par, pdev->device))) {
 		printk("fb: Can't count %s memory.\n", tdfx_fix.id);
-		release_mem_region(pci_resource_start(pdev, 0),
-				   pci_resource_len(pdev, 0));
-		goto out_err;
+		goto out_err_regbase;
 	}
 
-	if (!request_mem_region(pci_resource_start(pdev, 1),
+	if (!request_mem_region(tdfx_fix.smem_start,
 				pci_resource_len(pdev, 1), "tdfx smem")) {
 		printk(KERN_WARNING "tdfxfb: Can't reserve smem\n");
-		release_mem_region(pci_resource_start(pdev, 0),
-				   pci_resource_len(pdev, 0));
-		goto out_err;
+		goto out_err_regbase;
 	}
 
 	info->screen_base = ioremap_nocache(tdfx_fix.smem_start,
 					    tdfx_fix.smem_len);
 	if (!info->screen_base) {
 		printk("fb: Can't remap %s framebuffer.\n", tdfx_fix.id);
-		release_mem_region(pci_resource_start(pdev, 1),
-				   pci_resource_len(pdev, 1));
-		release_mem_region(pci_resource_start(pdev, 0),
-				   pci_resource_len(pdev, 0));
-		goto out_err;
+		goto out_err_screenbase;
 	}
 
 	default_par->iobase = pci_resource_start(pdev, 2);
@@ -1256,11 +1305,7 @@ static int __devinit tdfxfb_probe(struct
 	if (!request_region(pci_resource_start(pdev, 2),
 			    pci_resource_len(pdev, 2), "tdfx iobase")) {
 		printk(KERN_WARNING "tdfxfb: Can't reserve iobase\n");
-		release_mem_region(pci_resource_start(pdev, 1),
-				   pci_resource_len(pdev, 1));
-		release_mem_region(pci_resource_start(pdev, 0),
-				   pci_resource_len(pdev, 0));
-		goto out_err;
+		goto out_err_screenbase;
 	}
 
 	printk("fb: %s memory = %dK\n", tdfx_fix.id, tdfx_fix.smem_len >> 10);
@@ -1274,7 +1319,9 @@ static int __devinit tdfxfb_probe(struct
 	info->flags		= FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
 #ifdef CONFIG_FB_3DFX_ACCEL
 	info->flags             |= FBINFO_HWACCEL_FILLRECT |
-		FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_IMAGEBLIT;
+				   FBINFO_HWACCEL_COPYAREA |
+				   FBINFO_HWACCEL_IMAGEBLIT |
+				   FBINFO_READS_FAST;
 #endif
 
 	if (!mode_option)
@@ -1288,27 +1335,17 @@ #endif
 	lpitch = info->var.xres_virtual * ((info->var.bits_per_pixel + 7) >> 3);
 	info->var.yres_virtual = info->fix.smem_len / lpitch;
 	if (info->var.yres_virtual < info->var.yres)
-		goto out_err;
-
-#ifdef CONFIG_FB_3DFX_ACCEL
-	/*
-	 * FIXME: Limit var->yres_virtual to 4096 because of screen artifacts
-	 * during scrolling. This is only present if 2D acceleration is
-	 * enabled.
-	 */
-	if (info->var.yres_virtual > 4096)
-		info->var.yres_virtual = 4096;
-#endif /* CONFIG_FB_3DFX_ACCEL */
+		goto out_err_iobase;
 
 	if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
 		printk(KERN_WARNING "tdfxfb: Can't allocate color map\n");
-		goto out_err;
+		goto out_err_iobase;
 	}
 
 	if (register_framebuffer(info) < 0) {
 		printk("tdfxfb: can't register framebuffer\n");
 		fb_dealloc_cmap(&info->cmap);
-		goto out_err;
+		goto out_err_iobase;
 	}
 	/*
 	 * Our driver data
@@ -1316,14 +1353,21 @@ #endif /* CONFIG_FB_3DFX_ACCEL */
 	pci_set_drvdata(pdev, info);
 	return 0;
 
-out_err:
+out_err_iobase:
+	release_mem_region(pci_resource_start(pdev, 2),
+			   pci_resource_len(pdev, 2));
+out_err_screenbase:
+	if (info->screen_base)
+		iounmap(info->screen_base);
+	release_mem_region(tdfx_fix.smem_start, pci_resource_len(pdev, 1));
+out_err_regbase:
 	/*
 	 * Cleanup after anything that was remapped/allocated.
 	 */
 	if (default_par->regbase_virt)
 		iounmap(default_par->regbase_virt);
-	if (info->screen_base)
-		iounmap(info->screen_base);
+	release_mem_region(tdfx_fix.mmio_start, tdfx_fix.mmio_len);
+out_err:
 	framebuffer_release(info);
 	return -ENXIO;
 }


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

                 reply	other threads:[~2007-07-26 13:00 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=46A898F5.7030201@gmail.com \
    --to=adaplas@gmail.com \
    --cc=akpm@osdl.org \
    --cc=linux-fbdev-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.