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

Commit 91b3a6f4 authored by Krzysztof Helt's avatar Krzysztof Helt Committed by Linus Torvalds
Browse files

pm2fb: accelerated imageblit



This patch adds accelerated imageblit function.

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 d5383fcc
Loading
Loading
Loading
Loading
+120 −3
Original line number Diff line number Diff line
@@ -60,6 +60,8 @@
#define DPRINTK(a,b...)
#endif

#define PM2_PIXMAP_SIZE	(1600 * 4)

/*
 * Driver data
 */
@@ -1166,6 +1168,104 @@ static void pm2fb_copyarea(struct fb_info *info,
			modded.width, modded.height, 0);
}

static void pm2fb_imageblit(struct fb_info *info, const struct fb_image *image)
{
	struct pm2fb_par *par = info->par;
	u32 height = image->height;
	u32 fgx, bgx;
	const u32 *src = (const u32*)image->data;
	u32 xres = (info->var.xres + 31) & ~31;

	if (info->state != FBINFO_STATE_RUNNING)
		return;
	if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1) {
		cfb_imageblit(info, image);
		return;
	}
	switch (info->fix.visual) {
		case FB_VISUAL_PSEUDOCOLOR:
			fgx = image->fg_color;
			bgx = image->bg_color;
			break;
		case FB_VISUAL_TRUECOLOR:
		default:
			fgx = par->palette[image->fg_color];
			bgx = par->palette[image->bg_color];
			break;
	}
	if (info->var.bits_per_pixel == 8) {
		fgx |= fgx << 8;
		bgx |= bgx << 8;
	}
	if (info->var.bits_per_pixel <= 16) {
		fgx |= fgx << 16;
		bgx |= bgx << 16;
	}

	WAIT_FIFO(par, 13);
	pm2_WR(par, PM2R_FB_READ_MODE, partprod(xres));
	pm2_WR(par, PM2R_SCISSOR_MIN_XY,
			((image->dy & 0xfff) << 16) | (image->dx & 0x0fff));
	pm2_WR(par, PM2R_SCISSOR_MAX_XY,
			(((image->dy + image->height) & 0x0fff) << 16) |
			((image->dx + image->width) & 0x0fff));
	pm2_WR(par, PM2R_SCISSOR_MODE, 1);
	/* GXcopy & UNIT_ENABLE */
	pm2_WR(par, PM2R_LOGICAL_OP_MODE, (0x3 << 1) | 1 );
	pm2_WR(par, PM2R_RECTANGLE_ORIGIN,
			((image->dy & 0xfff) << 16) | (image->dx & 0x0fff));
	pm2_WR(par, PM2R_RECTANGLE_SIZE,
			((image->height & 0x0fff) << 16) |
			((image->width) & 0x0fff));
	if (info->var.bits_per_pixel == 24) {
		pm2_WR(par, PM2R_COLOR_DDA_MODE, 1);
		/* clear area */
		pm2_WR(par, PM2R_CONSTANT_COLOR, bgx);
		pm2_WR(par, PM2R_RENDER,
			PM2F_RENDER_RECTANGLE |
			PM2F_INCREASE_X | PM2F_INCREASE_Y );
		/* BitMapPackEachScanline & invert bits and byte order*/
		/* force background */
		pm2_WR(par, PM2R_RASTERIZER_MODE,  (1<<9) | 1 | (3<<7));
		pm2_WR(par, PM2R_CONSTANT_COLOR, fgx);
		pm2_WR(par, PM2R_RENDER,
			PM2F_RENDER_RECTANGLE |
			PM2F_INCREASE_X | PM2F_INCREASE_Y |
			PM2F_RENDER_SYNC_ON_BIT_MASK);
	} else {
		pm2_WR(par, PM2R_COLOR_DDA_MODE, 0);
		/* clear area */
		pm2_WR(par, PM2R_FB_BLOCK_COLOR, bgx);
		pm2_WR(par, PM2R_RENDER,
			PM2F_RENDER_RECTANGLE |
			PM2F_RENDER_FASTFILL |
			PM2F_INCREASE_X | PM2F_INCREASE_Y );
		/* invert bits and byte order*/
		pm2_WR(par, PM2R_RASTERIZER_MODE,  1 | (3<<7) );
		pm2_WR(par, PM2R_FB_BLOCK_COLOR, fgx);
		pm2_WR(par, PM2R_RENDER,
			PM2F_RENDER_RECTANGLE |
			PM2F_INCREASE_X | PM2F_INCREASE_Y |
			PM2F_RENDER_FASTFILL |
			PM2F_RENDER_SYNC_ON_BIT_MASK);
	}

	while (height--) {
		int width = ((image->width + 7) >> 3)
				+ info->pixmap.scan_align - 1;
		width >>= 2;
		WAIT_FIFO(par, width);
		while (width--) {
			pm2_WR(par, PM2R_BIT_MASK_PATTERN, *src);
			src++;
		}
	}
	WAIT_FIFO(par, 3);
	pm2_WR(par, PM2R_RASTERIZER_MODE, 0);
	pm2_WR(par, PM2R_COLOR_DDA_MODE, 0);
	pm2_WR(par, PM2R_SCISSOR_MODE, 0);
}

/* ------------ Hardware Independent Functions ------------ */

/*
@@ -1181,7 +1281,7 @@ static struct fb_ops pm2fb_ops = {
	.fb_pan_display	= pm2fb_pan_display,
	.fb_fillrect	= pm2fb_fillrect,
	.fb_copyarea	= pm2fb_copyarea,
	.fb_imageblit	= cfb_imageblit,
	.fb_imageblit	= pm2fb_imageblit,
	.fb_sync	= pm2fb_sync,
};

@@ -1340,11 +1440,24 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
	info->flags		= FBINFO_DEFAULT |
				  FBINFO_HWACCEL_YPAN |
				  FBINFO_HWACCEL_COPYAREA |
				  FBINFO_HWACCEL_IMAGEBLIT |
				  FBINFO_HWACCEL_FILLRECT;

	info->pixmap.addr = kmalloc(PM2_PIXMAP_SIZE, GFP_KERNEL);
	if (!info->pixmap.addr) {
		err_retval = -ENOMEM;
		goto err_exit_pixmap;
	}
	info->pixmap.size = PM2_PIXMAP_SIZE;
	info->pixmap.buf_align = 4;
	info->pixmap.scan_align = 4;
	info->pixmap.access_align = 32;
	info->pixmap.flags = FB_PIXMAP_SYSTEM;

	if (noaccel) {
		printk(KERN_DEBUG "disabling acceleration\n");
		info->flags |= FBINFO_HWACCEL_DISABLED;
		info->pixmap.scan_align = 1;
	}

	if (!mode)
@@ -1373,6 +1486,8 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
 err_exit_all:
	fb_dealloc_cmap(&info->cmap);
 err_exit_both:
	kfree(info->pixmap.addr);
 err_exit_pixmap:
	iounmap(info->screen_base);
	release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
 err_exit_mmio:
@@ -1409,6 +1524,8 @@ static void __devexit pm2fb_remove(struct pci_dev *pdev)
	release_mem_region(fix->mmio_start, fix->mmio_len);

	pci_set_drvdata(pdev, NULL);
	if (info->pixmap.addr)
		kfree(info->pixmap.addr);
	kfree(info);
}

+7 −0
Original line number Diff line number Diff line
@@ -68,11 +68,14 @@
#define PM2R_D_Y					0x8028
#define PM2R_COUNT					0x8030
#define PM2R_RENDER					0x8038
#define PM2R_BIT_MASK_PATTERN				0x8068
#define PM2R_RASTERIZER_MODE				0x80a0
#define PM2R_RECTANGLE_ORIGIN				0x80d0
#define PM2R_RECTANGLE_SIZE				0x80d8
#define PM2R_PACKED_DATA_LIMITS				0x8150
#define PM2R_SCISSOR_MODE				0x8180
#define PM2R_SCISSOR_MIN_XY				0x8188
#define PM2R_SCISSOR_MAX_XY				0x8190
#define PM2R_SCREEN_SIZE				0x8198
#define PM2R_AREA_STIPPLE_MODE				0x81a0
#define PM2R_WINDOW_ORIGIN				0x81c8
@@ -83,7 +86,9 @@
#define PM2R_TEXEL_LUT_MODE				0x8678
#define PM2R_TEXTURE_COLOR_MODE				0x8680
#define PM2R_FOG_MODE					0x8690
#define PM2R_TEXEL0					0x8760
#define PM2R_COLOR_DDA_MODE				0x87e0
#define PM2R_CONSTANT_COLOR				0x87e8
#define PM2R_ALPHA_BLEND_MODE				0x8810
#define PM2R_DITHER_MODE				0x8818
#define PM2R_FB_SOFT_WRITE_MASK				0x8820
@@ -169,6 +174,8 @@
#define PM2F_RENDER_TRAPEZOID				(1L<<6)
#define PM2F_RENDER_POINT				(2L<<6)
#define PM2F_RENDER_RECTANGLE				(3L<<6)
#define PM2F_RENDER_SYNC_ON_BIT_MASK			(1L<<11)
#define PM2F_RENDER_TEXTURE_ENABLE			(1L<<13)
#define PM2F_SYNCHRONIZATION				(1L<<10)
#define PM2F_PLL_LOCKED					0x10
#define PM2F_BEING_RESET				(1L<<31)