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

Commit 2686ba89 authored by Krzysztof Helt's avatar Krzysztof Helt Committed by Linus Torvalds
Browse files

pm3fb: various fixes



 - fix 16-bit RGBA 4444 and 5551 modes (use fbset -rgba to set them)
 - kill wmb() after each register write by PM3_SLOW_WRITE_REG
 - kill inaccurate comments (leftovers from skeletonfb.c)
 - kill PCI class restriction, now it is more general and shorter
 - white spaces and other minor fixes and source reducing

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 11d1a62c
Loading
Loading
Loading
Loading
+152 −181
Original line number Original line Diff line number Diff line
@@ -51,11 +51,6 @@
 */
 */
static char *mode_option __devinitdata;
static char *mode_option __devinitdata;


/*
 *  If your driver supports multiple boards, you should make the
 *  below data types arrays, or allocate them dynamically (using kmalloc()).
 */

/*
/*
 * This structure defines the hardware state of the graphics card. Normally
 * This structure defines the hardware state of the graphics card. Normally
 * you place this in a header file in linux/include/video. This file usually
 * you place this in a header file in linux/include/video. This file usually
@@ -104,36 +99,28 @@ static inline void PM3_WAIT(struct pm3_par *par, u32 n)
	while (PM3_READ_REG(par, PM3InFIFOSpace) < n);
	while (PM3_READ_REG(par, PM3InFIFOSpace) < n);
}
}


static inline void PM3_SLOW_WRITE_REG(struct pm3_par *par, s32 off, u32 v)
{
	if (par->v_regs) {
		mb();
		PM3_WAIT(par, 1);
		wmb();
		PM3_WRITE_REG(par, off, v);
	}
}

static inline void PM3_SET_INDEX(struct pm3_par *par, unsigned index)
{
	PM3_SLOW_WRITE_REG(par, PM3RD_IndexHigh, (index >> 8) & 0xff);
	PM3_SLOW_WRITE_REG(par, PM3RD_IndexLow, index & 0xff);
}

static inline void PM3_WRITE_DAC_REG(struct pm3_par *par, unsigned r, u8 v)
static inline void PM3_WRITE_DAC_REG(struct pm3_par *par, unsigned r, u8 v)
{
{
	PM3_SET_INDEX(par, r);
	PM3_WAIT(par, 3);
	PM3_WRITE_REG(par, PM3RD_IndexHigh, (r >> 8) & 0xff);
	PM3_WRITE_REG(par, PM3RD_IndexLow, r & 0xff);
	wmb();
	wmb();
	PM3_WRITE_REG(par, PM3RD_IndexedData, v);
	PM3_WRITE_REG(par, PM3RD_IndexedData, v);
	wmb();
}
}


static inline void pm3fb_set_color(struct pm3_par *par, unsigned char regno,
static inline void pm3fb_set_color(struct pm3_par *par, unsigned char regno,
			unsigned char r, unsigned char g, unsigned char b)
			unsigned char r, unsigned char g, unsigned char b)
{
{
	PM3_SLOW_WRITE_REG(par, PM3RD_PaletteWriteAddress, regno);
	PM3_WAIT(par, 4);
	PM3_SLOW_WRITE_REG(par, PM3RD_PaletteData, r);
	PM3_WRITE_REG(par, PM3RD_PaletteWriteAddress, regno);
	PM3_SLOW_WRITE_REG(par, PM3RD_PaletteData, g);
	wmb();
	PM3_SLOW_WRITE_REG(par, PM3RD_PaletteData, b);
	PM3_WRITE_REG(par, PM3RD_PaletteData, r);
	wmb();
	PM3_WRITE_REG(par, PM3RD_PaletteData, g);
	wmb();
	PM3_WRITE_REG(par, PM3RD_PaletteData, b);
	wmb();
}
}


static void pm3fb_clear_colormap(struct pm3_par *par,
static void pm3fb_clear_colormap(struct pm3_par *par,
@@ -141,7 +128,7 @@ static void pm3fb_clear_colormap(struct pm3_par *par,
{
{
	int i;
	int i;


	for (i = 0; i < 256 ; i++) /* fill color map with white */
	for (i = 0; i < 256 ; i++)
		pm3fb_set_color(par, i, r, g, b);
		pm3fb_set_color(par, i, r, g, b);


}
}
@@ -175,19 +162,26 @@ static void pm3fb_calculate_clock(unsigned long reqclock,
	}
	}
}
}


static inline int pm3fb_shift_bpp(unsigned long depth, int v)
static inline int pm3fb_depth(const struct fb_var_screeninfo *var)
{
{
	switch (depth) {
	if ( var->bits_per_pixel == 16 )
		return var->red.length + var->green.length
			+ var->blue.length;

	return var->bits_per_pixel;
}

static inline int pm3fb_shift_bpp(unsigned bpp, int v)
{
	switch (bpp) {
	case 8:
	case 8:
		return (v >> 4);
		return (v >> 4);
	case 12:
	case 15:
	case 16:
	case 16:
		return (v >> 3);
		return (v >> 3);
	case 32:
	case 32:
		return (v >> 2);
		return (v >> 2);
	}
	}
	DPRINTK("Unsupported depth %ld\n", depth);
	DPRINTK("Unsupported depth %u\n", bpp);
	return 0;
	return 0;
}
}


@@ -206,56 +200,50 @@ static void pm3fb_write_mode(struct fb_info *info)
	const u32 vbend = vsend + info->var.upper_margin;
	const u32 vbend = vsend + info->var.upper_margin;
	const u32 vtotal = info->var.yres + vbend;
	const u32 vtotal = info->var.yres + vbend;
	const u32 width = (info->var.xres_virtual + 7) & ~7;
	const u32 width = (info->var.xres_virtual + 7) & ~7;

	const unsigned bpp = info->var.bits_per_pixel;
	PM3_SLOW_WRITE_REG(par, PM3MemBypassWriteMask, 0xffffffff);

	PM3_SLOW_WRITE_REG(par, PM3Aperture0, 0x00000000);
	PM3_WAIT(par, 20);
	PM3_SLOW_WRITE_REG(par, PM3Aperture1, 0x00000000);
	PM3_WRITE_REG(par, PM3MemBypassWriteMask, 0xffffffff);
	PM3_SLOW_WRITE_REG(par, PM3FIFODis, 0x00000007);
	PM3_WRITE_REG(par, PM3Aperture0, 0x00000000);

	PM3_WRITE_REG(par, PM3Aperture1, 0x00000000);
	PM3_SLOW_WRITE_REG(par, PM3HTotal,
	PM3_WRITE_REG(par, PM3FIFODis, 0x00000007);
			   pm3fb_shift_bpp(info->var.bits_per_pixel,

					  htotal - 1));
	PM3_WRITE_REG(par, PM3HTotal,
	PM3_SLOW_WRITE_REG(par, PM3HsEnd,
			   pm3fb_shift_bpp(bpp, htotal - 1));
			   pm3fb_shift_bpp(info->var.bits_per_pixel,
	PM3_WRITE_REG(par, PM3HsEnd,
					  hsend));
			   pm3fb_shift_bpp(bpp, hsend));
	PM3_SLOW_WRITE_REG(par, PM3HsStart,
	PM3_WRITE_REG(par, PM3HsStart,
			   pm3fb_shift_bpp(info->var.bits_per_pixel,
			   pm3fb_shift_bpp(bpp, hsstart));
					  hsstart));
	PM3_WRITE_REG(par, PM3HbEnd,
	PM3_SLOW_WRITE_REG(par, PM3HbEnd,
			   pm3fb_shift_bpp(bpp, hbend));
			   pm3fb_shift_bpp(info->var.bits_per_pixel,
	PM3_WRITE_REG(par, PM3HgEnd,
					  hbend));
			   pm3fb_shift_bpp(bpp, hbend));
	PM3_SLOW_WRITE_REG(par, PM3HgEnd,
	PM3_WRITE_REG(par, PM3ScreenStride,
			   pm3fb_shift_bpp(info->var.bits_per_pixel,
			   pm3fb_shift_bpp(bpp, width));
					  hbend));
	PM3_WRITE_REG(par, PM3VTotal, vtotal - 1);
	PM3_SLOW_WRITE_REG(par, PM3ScreenStride,
	PM3_WRITE_REG(par, PM3VsEnd, vsend - 1);
			   pm3fb_shift_bpp(info->var.bits_per_pixel,
	PM3_WRITE_REG(par, PM3VsStart, vsstart - 1);
					  width));
	PM3_WRITE_REG(par, PM3VbEnd, vbend);
	PM3_SLOW_WRITE_REG(par, PM3VTotal, vtotal - 1);

	PM3_SLOW_WRITE_REG(par, PM3VsEnd, vsend - 1);
	switch (bpp) {
	PM3_SLOW_WRITE_REG(par, PM3VsStart, vsstart - 1);
	PM3_SLOW_WRITE_REG(par, PM3VbEnd, vbend);

	switch (info->var.bits_per_pixel) {
	case 8:
	case 8:
		PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
		PM3_WRITE_REG(par, PM3ByAperture1Mode,
				   PM3ByApertureMode_PIXELSIZE_8BIT);
				   PM3ByApertureMode_PIXELSIZE_8BIT);
		PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
		PM3_WRITE_REG(par, PM3ByAperture2Mode,
				   PM3ByApertureMode_PIXELSIZE_8BIT);
				   PM3ByApertureMode_PIXELSIZE_8BIT);
		break;
		break;


	case 12:
	case 15:
	case 16:
	case 16:
#ifndef __BIG_ENDIAN
#ifndef __BIG_ENDIAN
		PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
		PM3_WRITE_REG(par, PM3ByAperture1Mode,
				   PM3ByApertureMode_PIXELSIZE_16BIT);
				   PM3ByApertureMode_PIXELSIZE_16BIT);
		PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
		PM3_WRITE_REG(par, PM3ByAperture2Mode,
				   PM3ByApertureMode_PIXELSIZE_16BIT);
				   PM3ByApertureMode_PIXELSIZE_16BIT);
#else
#else
		PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
		PM3_WRITE_REG(par, PM3ByAperture1Mode,
				   PM3ByApertureMode_PIXELSIZE_16BIT |
				   PM3ByApertureMode_PIXELSIZE_16BIT |
				   PM3ByApertureMode_BYTESWAP_BADC);
				   PM3ByApertureMode_BYTESWAP_BADC);
		PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
		PM3_WRITE_REG(par, PM3ByAperture2Mode,
				   PM3ByApertureMode_PIXELSIZE_16BIT |
				   PM3ByApertureMode_PIXELSIZE_16BIT |
				   PM3ByApertureMode_BYTESWAP_BADC);
				   PM3ByApertureMode_BYTESWAP_BADC);
#endif /* ! __BIG_ENDIAN */
#endif /* ! __BIG_ENDIAN */
@@ -263,23 +251,22 @@ static void pm3fb_write_mode(struct fb_info *info)


	case 32:
	case 32:
#ifndef __BIG_ENDIAN
#ifndef __BIG_ENDIAN
		PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
		PM3_WRITE_REG(par, PM3ByAperture1Mode,
				   PM3ByApertureMode_PIXELSIZE_32BIT);
				   PM3ByApertureMode_PIXELSIZE_32BIT);
		PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
		PM3_WRITE_REG(par, PM3ByAperture2Mode,
				   PM3ByApertureMode_PIXELSIZE_32BIT);
				   PM3ByApertureMode_PIXELSIZE_32BIT);
#else
#else
		PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
		PM3_WRITE_REG(par, PM3ByAperture1Mode,
				   PM3ByApertureMode_PIXELSIZE_32BIT |
				   PM3ByApertureMode_PIXELSIZE_32BIT |
				   PM3ByApertureMode_BYTESWAP_DCBA);
				   PM3ByApertureMode_BYTESWAP_DCBA);
		PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
		PM3_WRITE_REG(par, PM3ByAperture2Mode,
				   PM3ByApertureMode_PIXELSIZE_32BIT |
				   PM3ByApertureMode_PIXELSIZE_32BIT |
				   PM3ByApertureMode_BYTESWAP_DCBA);
				   PM3ByApertureMode_BYTESWAP_DCBA);
#endif /* ! __BIG_ENDIAN */
#endif /* ! __BIG_ENDIAN */
		break;
		break;


	default:
	default:
		DPRINTK("Unsupported depth %d\n",
		DPRINTK("Unsupported depth %d\n", bpp);
			info->var.bits_per_pixel);
		break;
		break;
	}
	}


@@ -296,14 +283,15 @@ static void pm3fb_write_mode(struct fb_info *info)
			   PM3VideoControl_VSYNC_MASK);
			   PM3VideoControl_VSYNC_MASK);
		video |= PM3VideoControl_HSYNC_ACTIVE_HIGH |
		video |= PM3VideoControl_HSYNC_ACTIVE_HIGH |
			 PM3VideoControl_VSYNC_ACTIVE_HIGH;
			 PM3VideoControl_VSYNC_ACTIVE_HIGH;
		PM3_SLOW_WRITE_REG(par, PM3VideoControl, video);
		PM3_WRITE_REG(par, PM3VideoControl, video);
	}
	}
	PM3_SLOW_WRITE_REG(par, PM3VClkCtl,
	PM3_WRITE_REG(par, PM3VClkCtl,
			   (PM3_READ_REG(par, PM3VClkCtl) & 0xFFFFFFFC));
			   (PM3_READ_REG(par, PM3VClkCtl) & 0xFFFFFFFC));
	PM3_SLOW_WRITE_REG(par, PM3ScreenBase, par->base);
	PM3_WRITE_REG(par, PM3ScreenBase, par->base);
	PM3_SLOW_WRITE_REG(par, PM3ChipConfig,
	PM3_WRITE_REG(par, PM3ChipConfig,
			   (PM3_READ_REG(par, PM3ChipConfig) & 0xFFFFFFFD));
			   (PM3_READ_REG(par, PM3ChipConfig) & 0xFFFFFFFD));


	wmb();
	{
	{
		unsigned char uninitialized_var(m);	/* ClkPreScale */
		unsigned char uninitialized_var(m);	/* ClkPreScale */
		unsigned char uninitialized_var(n);	/* ClkFeedBackScale */
		unsigned char uninitialized_var(n);	/* ClkFeedBackScale */
@@ -337,7 +325,7 @@ static void pm3fb_write_mode(struct fb_info *info)


	PM3_WRITE_DAC_REG(par, PM3RD_DACControl, 0x00);
	PM3_WRITE_DAC_REG(par, PM3RD_DACControl, 0x00);


	switch (info->var.bits_per_pixel) {
	switch (pm3fb_depth(&info->var)) {
	case 8:
	case 8:
		PM3_WRITE_DAC_REG(par, PM3RD_PixelSize,
		PM3_WRITE_DAC_REG(par, PM3RD_PixelSize,
				  PM3RD_PixelSize_8_BIT_PIXELS);
				  PM3RD_PixelSize_8_BIT_PIXELS);
@@ -393,58 +381,45 @@ static void pm3fb_write_mode(struct fb_info *info)
 * hardware independent functions
 * hardware independent functions
 */
 */
int pm3fb_init(void);
int pm3fb_init(void);
int pm3fb_setup(char*);


static int pm3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
static int pm3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
{
	u32 lpitch;
	u32 lpitch;
	unsigned bpp = var->red.length + var->green.length
			+ var->blue.length + var->transp.length;

	if ( bpp != var->bits_per_pixel ) {
		/* set predefined mode for bits_per_pixel settings */


	var->transp.offset = 0;
	var->transp.length = 0;
		switch(var->bits_per_pixel) {
		switch(var->bits_per_pixel) {
		case 8:
		case 8:
			var->red.length = var->green.length = var->blue.length = 8;
			var->red.length = var->green.length = var->blue.length = 8;
			var->red.offset = var->green.offset = var->blue.offset = 0;
			var->red.offset = var->green.offset = var->blue.offset = 0;
		break;
			var->transp.offset = 0;
	case 12:
			var->transp.length = 0;
		var->red.offset   = 8;
		var->red.length   = 4;
		var->green.offset = 4;
		var->green.length = 4;
		var->blue.offset  = 0;
		var->blue.length  = 4;
		var->transp.offset = 12;
		var->transp.length = 4;
	case 15:
		var->red.offset   = 10;
		var->red.length   = 5;
		var->green.offset = 5;
		var->green.length = 5;
		var->blue.offset  = 0;
		var->blue.length  = 5;
		var->transp.offset = 15;
		var->transp.length = 1;
			break;
			break;
		case 16:
		case 16:
		var->red.offset   = 11;
			var->red.length = var->blue.length = 5;
		var->red.length   = 5;
		var->green.offset = 5;
			var->green.length = 6;
			var->green.length = 6;
		var->blue.offset  = 0;
			var->transp.length = 0;
		var->blue.length  = 5;
			break;
			break;
		case 32:
		case 32:
		var->transp.offset = 24;
		var->transp.length = 8;
		var->red.offset	  = 16;
		var->green.offset = 8;
		var->blue.offset  = 0;
			var->red.length = var->green.length = var->blue.length = 8;
			var->red.length = var->green.length = var->blue.length = 8;
			var->transp.length = 8;
			break;
			break;
		default:
		default:
			DPRINTK("depth not supported: %u\n", var->bits_per_pixel);
			DPRINTK("depth not supported: %u\n", var->bits_per_pixel);
			return -EINVAL;
			return -EINVAL;
		}
		}
	}
	/* it is assumed BGRA order */
	if (var->bits_per_pixel > 8 )
	{
		var->blue.offset = 0;
		var->green.offset = var->blue.length;
		var->red.offset = var->green.offset + var->green.length;
		var->transp.offset = var->red.offset + var->red.length;
	}
	var->height = var->width = -1;
	var->height = var->width = -1;


	if (var->xres != var->xres_virtual) {
	if (var->xres != var->xres_virtual) {
@@ -502,10 +477,9 @@ static int pm3fb_set_par(struct fb_info *info)
{
{
	struct pm3_par *par = info->par;
	struct pm3_par *par = info->par;
	const u32 xres = (info->var.xres + 31) & ~31;
	const u32 xres = (info->var.xres + 31) & ~31;
	const int depth = (info->var.bits_per_pixel + 7) & ~7;
	const unsigned bpp = info->var.bits_per_pixel;


	par->base = pm3fb_shift_bpp(info->var.bits_per_pixel,
	par->base = pm3fb_shift_bpp(bpp,(info->var.yoffset * xres)
					(info->var.yoffset * xres)
					+ info->var.xoffset);
					+ info->var.xoffset);
	par->video = 0;
	par->video = 0;


@@ -530,12 +504,10 @@ static int pm3fb_set_par(struct fb_info *info)
		par->video |= PM3VideoControl_DISABLE;
		par->video |= PM3VideoControl_DISABLE;
		DPRINTK("PM3Video disabled\n");
		DPRINTK("PM3Video disabled\n");
	}
	}
	switch (depth) {
	switch (bpp) {
	case 8:
	case 8:
		par->video |= PM3VideoControl_PIXELSIZE_8BIT;
		par->video |= PM3VideoControl_PIXELSIZE_8BIT;
		break;
		break;
	case 12:
	case 15:
	case 16:
	case 16:
		par->video |= PM3VideoControl_PIXELSIZE_16BIT;
		par->video |= PM3VideoControl_PIXELSIZE_16BIT;
		break;
		break;
@@ -548,9 +520,9 @@ static int pm3fb_set_par(struct fb_info *info)
	}
	}


	info->fix.visual =
	info->fix.visual =
		(depth == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
		(bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
	info->fix.line_length = ((info->var.xres_virtual + 7)  & ~7)
	info->fix.line_length = ((info->var.xres_virtual + 7)  & ~7)
					* depth / 8;
					* bpp / 8;


/*	pm3fb_clear_memory(info, 0);*/
/*	pm3fb_clear_memory(info, 0);*/
	pm3fb_clear_colormap(par, 0, 0, 0);
	pm3fb_clear_colormap(par, 0, 0, 0);
@@ -621,7 +593,6 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
		case 8:
		case 8:
			break;
			break;
		case 16:
		case 16:
		case 24:
		case 32:
		case 32:
			((u32*)(info->pseudo_palette))[regno] = v;
			((u32*)(info->pseudo_palette))[regno] = v;
			break;
			break;
@@ -643,7 +614,8 @@ static int pm3fb_pan_display(struct fb_var_screeninfo *var,
	par->base = pm3fb_shift_bpp(var->bits_per_pixel,
	par->base = pm3fb_shift_bpp(var->bits_per_pixel,
					(var->yoffset * xres)
					(var->yoffset * xres)
					+ var->xoffset);
					+ var->xoffset);
	PM3_SLOW_WRITE_REG(par, PM3ScreenBase, par->base);
	PM3_WAIT(par, 1);
	PM3_WRITE_REG(par, PM3ScreenBase, par->base);
	return 0;
	return 0;
}
}


@@ -665,21 +637,21 @@ static int pm3fb_blank(int blank_mode, struct fb_info *info)


	switch (blank_mode) {
	switch (blank_mode) {
	case FB_BLANK_UNBLANK:
	case FB_BLANK_UNBLANK:
		video = video | PM3VideoControl_ENABLE;
		video |= PM3VideoControl_ENABLE;
		break;
		break;
	case FB_BLANK_NORMAL:	/* FIXME */
	case FB_BLANK_NORMAL:
		video = video & ~(PM3VideoControl_ENABLE);
		video &= ~(PM3VideoControl_ENABLE);
		break;
		break;
	case FB_BLANK_HSYNC_SUSPEND:
	case FB_BLANK_HSYNC_SUSPEND:
		video = video & ~(PM3VideoControl_HSYNC_MASK |
		video &= ~(PM3VideoControl_HSYNC_MASK |
			  PM3VideoControl_BLANK_ACTIVE_LOW);
			  PM3VideoControl_BLANK_ACTIVE_LOW);
		break;
		break;
	case FB_BLANK_VSYNC_SUSPEND:
	case FB_BLANK_VSYNC_SUSPEND:
		video = video & ~(PM3VideoControl_VSYNC_MASK |
		video &= ~(PM3VideoControl_VSYNC_MASK |
			  PM3VideoControl_BLANK_ACTIVE_LOW);
			  PM3VideoControl_BLANK_ACTIVE_LOW);
		break;
		break;
	case FB_BLANK_POWERDOWN:
	case FB_BLANK_POWERDOWN:
		video = video & ~(PM3VideoControl_HSYNC_MASK |
		video &= ~(PM3VideoControl_HSYNC_MASK |
			  PM3VideoControl_VSYNC_MASK |
			  PM3VideoControl_VSYNC_MASK |
			  PM3VideoControl_BLANK_ACTIVE_LOW);
			  PM3VideoControl_BLANK_ACTIVE_LOW);
		break;
		break;
@@ -688,8 +660,8 @@ static int pm3fb_blank(int blank_mode, struct fb_info *info)
		return 1;
		return 1;
	}
	}


	PM3_SLOW_WRITE_REG(par,PM3VideoControl, video);
	PM3_WAIT(par, 1);

	PM3_WRITE_REG(par,PM3VideoControl, video);
	return 0;
	return 0;
}
}


@@ -703,9 +675,9 @@ static struct fb_ops pm3fb_ops = {
	.fb_set_par	= pm3fb_set_par,
	.fb_set_par	= pm3fb_set_par,
	.fb_setcolreg	= pm3fb_setcolreg,
	.fb_setcolreg	= pm3fb_setcolreg,
	.fb_pan_display	= pm3fb_pan_display,
	.fb_pan_display	= pm3fb_pan_display,
	.fb_fillrect	= cfb_fillrect,		/* Needed !!! */
	.fb_fillrect	= cfb_fillrect,
	.fb_copyarea	= cfb_copyarea,		/* Needed !!! */
	.fb_copyarea	= cfb_copyarea,
	.fb_imageblit	= cfb_imageblit,	/* Needed !!! */
	.fb_imageblit	= cfb_imageblit,
	.fb_blank	= pm3fb_blank,
	.fb_blank	= pm3fb_blank,
};
};


@@ -722,7 +694,7 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par)
	unsigned long	memsize = 0, tempBypass, i, temp1, temp2;
	unsigned long	memsize = 0, tempBypass, i, temp1, temp2;
	unsigned char	__iomem *screen_mem;
	unsigned char	__iomem *screen_mem;


	pm3fb_fix.smem_len = 64 * 1024 * 1024; /* request full aperture size */
	pm3fb_fix.smem_len = 64 * 1024l * 1024; /* request full aperture size */
	/* Linear frame buffer - request region and map it. */
	/* Linear frame buffer - request region and map it. */
	if (!request_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len,
	if (!request_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len,
				 "pm3fb smem")) {
				 "pm3fb smem")) {
@@ -744,7 +716,8 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par)


	DPRINTK("PM3MemBypassWriteMask was: 0x%08lx\n", tempBypass);
	DPRINTK("PM3MemBypassWriteMask was: 0x%08lx\n", tempBypass);


	PM3_SLOW_WRITE_REG(par, PM3MemBypassWriteMask, 0xFFFFFFFF);
	PM3_WAIT(par, 1);
	PM3_WRITE_REG(par, PM3MemBypassWriteMask, 0xFFFFFFFF);


	/* pm3 split up memory, replicates, and do a lot of nasty stuff IMHO ;-) */
	/* pm3 split up memory, replicates, and do a lot of nasty stuff IMHO ;-) */
	for (i = 0; i < 32; i++) {
	for (i = 0; i < 32; i++) {
@@ -765,10 +738,9 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par)
	if (memsize + 1 == i) {
	if (memsize + 1 == i) {
		for (i = 0; i < 32; i++) {
		for (i = 0; i < 32; i++) {
			/* Clear first 32MB ; 0 is 0, no need to byteswap */
			/* Clear first 32MB ; 0 is 0, no need to byteswap */
			writel(0x0000000,
			writel(0x0000000, (screen_mem + (i * 1048576)));
			       (screen_mem + (i * 1048576)));
			mb();
		}
		}
		wmb();


		for (i = 32; i < 64; i++) {
		for (i = 32; i < 64; i++) {
			fb_writel(i * 0x00345678,
			fb_writel(i * 0x00345678,
@@ -787,7 +759,8 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par)
	}
	}
	DPRINTK("Second detect pass got %ld MB\n", memsize + 1);
	DPRINTK("Second detect pass got %ld MB\n", memsize + 1);


	PM3_SLOW_WRITE_REG(par, PM3MemBypassWriteMask, tempBypass);
	PM3_WAIT(par, 1);
	PM3_WRITE_REG(par, PM3MemBypassWriteMask, tempBypass);


	iounmap(screen_mem);
	iounmap(screen_mem);
	release_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len);
	release_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len);
@@ -890,7 +863,6 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
		goto err_exit_both;
		goto err_exit_both;
	}
	}


	/* This has to been done !!! */
	if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
	if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
		retval = -ENOMEM;
		retval = -ENOMEM;
		goto err_exit_both;
		goto err_exit_both;
@@ -907,7 +879,7 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
	}
	}
	printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
	printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
	   info->fix.id);
	   info->fix.id);
	pci_set_drvdata(dev, info); /* or dev_set_drvdata(device, info) */
	pci_set_drvdata(dev, info);
	return 0;
	return 0;


 err_exit_all:
 err_exit_all:
@@ -949,8 +921,7 @@ static void __devexit pm3fb_remove(struct pci_dev *dev)


static struct pci_device_id pm3fb_id_table[] = {
static struct pci_device_id pm3fb_id_table[] = {
	{ PCI_VENDOR_ID_3DLABS, 0x0a,
	{ PCI_VENDOR_ID_3DLABS, 0x0a,
	  PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
	  0xff0000, 0 },
	{ 0, }
	{ 0, }
};
};


@@ -964,6 +935,22 @@ static struct pci_driver pm3fb_driver = {


MODULE_DEVICE_TABLE(pci, pm3fb_id_table);
MODULE_DEVICE_TABLE(pci, pm3fb_id_table);


#ifndef MODULE
	/*
	 *  Setup
	 */

/*
 * Only necessary if your driver takes special options,
 * otherwise we fall back on the generic fb_setup().
 */
static int __init pm3fb_setup(char *options)
{
	/* Parse user speficied options (`video=pm3fb:') */
	return 0;
}
#endif /* MODULE */

int __init pm3fb_init(void)
int __init pm3fb_init(void)
{
{
	/*
	/*
@@ -985,22 +972,6 @@ static void __exit pm3fb_exit(void)
	pci_unregister_driver(&pm3fb_driver);
	pci_unregister_driver(&pm3fb_driver);
}
}


#ifndef MODULE
	/*
	 *  Setup
	 */

/*
 * Only necessary if your driver takes special options,
 * otherwise we fall back on the generic fb_setup().
 */
int __init pm3fb_setup(char *options)
{
	/* Parse user speficied options (`video=pm3fb:') */
	return 0;
}
#endif /* MODULE */

module_init(pm3fb_init);
module_init(pm3fb_init);
module_exit(pm3fb_exit);
module_exit(pm3fb_exit);