/*
 *
 * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
 *
 * (c) 1998-2002 Petr Vandrovec <vandrove@vc.cvut.cz>
 *
 * Version: 1.65 2002/08/14
 *
 * MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
 *
 * Contributors: "menion?" <menion@mindless.com>
 *                     Betatesting, fixes, ideas
 *
 *               "Kurt Garloff" <garloff@suse.de>
 *                     Betatesting, fixes, ideas, videomodes, videomodes timmings
 *
 *               "Tom Rini" <trini@kernel.crashing.org>
 *                     MTRR stuff, PPC cleanups, betatesting, fixes, ideas
 *
 *               "Bibek Sahu" <scorpio@dodds.net>
 *                     Access device through readb|w|l and write b|w|l
 *                     Extensive debugging stuff
 *
 *               "Daniel Haun" <haund@usa.net>
 *                     Testing, hardware cursor fixes
 *
 *               "Scott Wood" <sawst46+@pitt.edu>
 *                     Fixes
 *
 *               "Gerd Knorr" <kraxel@goldbach.isdn.cs.tu-berlin.de>
 *                     Betatesting
 *
 *               "Kelly French" <targon@hazmat.com>
 *               "Fernando Herrera" <fherrera@eurielec.etsit.upm.es>
 *                     Betatesting, bug reporting
 *
 *               "Pablo Bianucci" <pbian@pccp.com.ar>
 *                     Fixes, ideas, betatesting
 *
 *               "Inaky Perez Gonzalez" <inaky@peloncho.fis.ucm.es>
 *                     Fixes, enhandcements, ideas, betatesting
 *
 *               "Ryuichi Oikawa" <roikawa@rr.iiij4u.or.jp>
 *                     PPC betatesting, PPC support, backward compatibility
 *
 *               "Paul Womar" <Paul@pwomar.demon.co.uk>
 *               "Owen Waller" <O.Waller@ee.qub.ac.uk>
 *                     PPC betatesting
 *
 *               "Thomas Pornin" <pornin@bolet.ens.fr>
 *                     Alpha betatesting
 *
 *               "Pieter van Leuven" <pvl@iae.nl>
 *               "Ulf Jaenicke-Roessler" <ujr@physik.phy.tu-dresden.de>
 *                     G100 testing
 *
 *               "H. Peter Arvin" <hpa@transmeta.com>
 *                     Ideas
 *
 *               "Cort Dougan" <cort@cs.nmt.edu>
 *                     CHRP fixes and PReP cleanup
 *
 *               "Mark Vojkovich" <mvojkovi@ucsd.edu>
 *                     G400 support
 *
 * (following author is not in any relation with this code, but his code
 *  is included in this driver)
 *
 * Based on framebuffer driver for VBE 2.0 compliant graphic boards
 *     (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
 *
 * (following author is not in any relation with this code, but his ideas
 *  were used when writing this driver)
 *
 *		 FreeVBE/AF (Matrox), "Shawn Hargreaves" <shawn@talula.demon.co.uk>
 *
 */

#include "matroxfb_accel.h"
#include "matroxfb_DAC1064.h"
#include "matroxfb_Ti3026.h"
#include "matroxfb_misc.h"

#define curr_ydstorg(x)	((x)->curr.ydstorg.pixels)

#define mga_ydstlen(y,l) mga_outl(M_YDSTLEN | M_EXEC, ((y) << 16) | (l))

static inline void matrox_cfb4_pal(u_int32_t* pal) {
	unsigned int i;
	
	for (i = 0; i < 16; i++) {
		pal[i] = i * 0x11111111U;
	}
}

static inline void matrox_cfb8_pal(u_int32_t* pal) {
	unsigned int i;
	
	for (i = 0; i < 16; i++) {
		pal[i] = i * 0x01010101U;
	}
}

static void matroxfb_copyarea(struct fb_info* info, const struct fb_copyarea* area);
static void matroxfb_fillrect(struct fb_info* info, const struct fb_fillrect* rect);
static void matroxfb_imageblit(struct fb_info* info, const struct fb_image* image);
static void matroxfb_cfb4_fillrect(struct fb_info* info, const struct fb_fillrect* rect);
static void matroxfb_cfb4_copyarea(struct fb_info* info, const struct fb_copyarea* area);

void matrox_cfbX_init(struct matrox_fb_info *minfo)
{
	u_int32_t maccess;
	u_int32_t mpitch;
	u_int32_t mopmode;
	int accel;

	DBG(__func__)

	mpitch = minfo->fbcon.var.xres_virtual;

	minfo->fbops.fb_copyarea = cfb_copyarea;
	minfo->fbops.fb_fillrect = cfb_fillrect;
	minfo->fbops.fb_imageblit = cfb_imageblit;
	minfo->fbops.fb_cursor = NULL;

	accel = (minfo->fbcon.var.accel_flags & FB_ACCELF_TEXT) == FB_ACCELF_TEXT;

	switch (minfo->fbcon.var.bits_per_pixel) {
		case 4:		maccess = 0x00000000;	/* accelerate as 8bpp video */
				mpitch = (mpitch >> 1) | 0x8000; /* disable linearization */
				mopmode = M_OPMODE_4BPP;
				matrox_cfb4_pal(minfo->cmap);
				if (accel && !(mpitch & 1)) {
					minfo->fbops.fb_copyarea = matroxfb_cfb4_copyarea;
					minfo->fbops.fb_fillrect = matroxfb_cfb4_fillrect;
				}
				break;
		case 8:		maccess = 0x00000000;
				mopmode = M_OPMODE_8BPP;
				matrox_cfb8_pal(minfo->cmap);
				if (accel) {
					minfo->fbops.fb_copyarea = matroxfb_copyarea;
					minfo->fbops.fb_fillrect = matroxfb_fillrect;
					minfo->fbops.fb_imageblit = matroxfb_imageblit;
				}
				break;
		case 16:	if (minfo->fbcon.var.green.length == 5)
					maccess = 0xC0000001;
				else
					maccess = 0x40000001;
				mopmode = M_OPMODE_16BPP;
				if (accel) {
					minfo->fbops.fb_copyarea = matroxfb_copyarea;
					minfo->fbops.fb_fillrect = matroxfb_fillrect;
					minfo->fbops.fb_imageblit = matroxfb_imageblit;
				}
				break;
		case 24:	maccess = 0x00000003;
				mopmode = M_OPMODE_24BPP;
				if (accel) {
					minfo->fbops.fb_copyarea = matroxfb_copyarea;
					minfo->fbops.fb_fillrect = matroxfb_fillrect;
					minfo->fbops.fb_imageblit = matroxfb_imageblit;
				}
				break;
		case 32:	maccess = 0x00000002;
				mopmode = M_OPMODE_32BPP;
				if (accel) {
					minfo->fbops.fb_copyarea = matroxfb_copyarea;
					minfo->fbops.fb_fillrect = matroxfb_fillrect;
					minfo->fbops.fb_imageblit = matroxfb_imageblit;
				}
				break;
		default:	maccess = 0x00000000;
				mopmode = 0x00000000;
				break;	/* turn off acceleration!!! */
	}
	mga_fifo(8);
	mga_outl(M_PITCH, mpitch);
	mga_outl(M_YDSTORG, curr_ydstorg(minfo));
	if (minfo->capable.plnwt)
		mga_outl(M_PLNWT, -1);
	if (minfo->capable.srcorg) {
		mga_outl(M_SRCORG, 0);
		mga_outl(M_DSTORG, 0);
	}
	mga_outl(M_OPMODE, mopmode);
	mga_outl(M_CXBNDRY, 0xFFFF0000);
	mga_outl(M_YTOP, 0);
	mga_outl(M_YBOT, 0x01FFFFFF);
	mga_outl(M_MACCESS, maccess);
	minfo->accel.m_dwg_rect = M_DWG_TRAP | M_DWG_SOLID | M_DWG_ARZERO | M_DWG_SGNZERO | M_DWG_SHIFTZERO;
	if (isMilleniumII(minfo)) minfo->accel.m_dwg_rect |= M_DWG_TRANSC;
	minfo->accel.m_opmode = mopmode;
	minfo->accel.m_access = maccess;
	minfo->accel.m_pitch = mpitch;
}

EXPORT_SYMBOL(matrox_cfbX_init);

static void matrox_accel_restore_maccess(struct matrox_fb_info *minfo)
{
	mga_outl(M_MACCESS, minfo->accel.m_access);
	mga_outl(M_PITCH, minfo->accel.m_pitch);
}

static void matrox_accel_bmove(struct matrox_fb_info *minfo, int vxres, int sy,
			       int sx, int dy, int dx, int height, int width)
{
	int start, end;
	CRITFLAGS

	DBG(__func__)

	CRITBEGIN

	if ((dy < sy) || ((dy == sy) && (dx <= sx))) {
		mga_fifo(4);
		matrox_accel_restore_maccess(minfo);
		mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_SGNZERO |
			 M_DWG_BFCOL | M_DWG_REPLACE);
		mga_outl(M_AR5, vxres);
		width--;
		start = sy*vxres+sx+curr_ydstorg(minfo);
		end = start+width;
	} else {
		mga_fifo(5);
		matrox_accel_restore_maccess(minfo);
		mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_BFCOL | M_DWG_REPLACE);
		mga_outl(M_SGN, 5);
		mga_outl(M_AR5, -vxres);
		width--;
		end = (sy+height-1)*vxres+sx+curr_ydstorg(minfo);
		start = end+width;
		dy += height-1;
	}
	mga_fifo(6);
	matrox_accel_restore_maccess(minfo);
	mga_outl(M_AR0, end);
	mga_outl(M_AR3, start);
	mga_outl(M_FXBNDRY, ((dx+width)<<16) | dx);
	mga_ydstlen(dy, height);
	WaitTillIdle();

	CRITEND
}

static void matrox_accel_bmove_lin(struct matrox_fb_info *minfo, int vxres,
				   int sy, int sx, int dy, int dx, int height,
				   int width)
{
	int start, end;
	CRITFLAGS

	DBG(__func__)

	CRITBEGIN

	if ((dy < sy) || ((dy == sy) && (dx <= sx))) {
		mga_fifo(4);
		matrox_accel_restore_maccess(minfo);
		mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_SGNZERO |
			M_DWG_BFCOL | M_DWG_REPLACE);
		mga_outl(M_AR5, vxres);
		width--;
		start = sy*vxres+sx+curr_ydstorg(minfo);
		end = start+width;
	} else {
		mga_fifo(5);
		matrox_accel_restore_maccess(minfo);
		mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_BFCOL | M_DWG_REPLACE);
		mga_outl(M_SGN, 5);
		mga_outl(M_AR5, -vxres);
		width--;
		end = (sy+height-1)*vxres+sx+curr_ydstorg(minfo);
		start = end+width;
		dy += height-1;
	}
	mga_fifo(7);
	matrox_accel_restore_maccess(minfo);
	mga_outl(M_AR0, end);
	mga_outl(M_AR3, start);
	mga_outl(M_FXBNDRY, ((dx+width)<<16) | dx);
	mga_outl(M_YDST, dy*vxres >> 5);
	mga_outl(M_LEN | M_EXEC, height);
	WaitTillIdle();

	CRITEND
}

static void matroxfb_cfb4_copyarea(struct fb_info* info, const struct fb_copyarea* area) {
	struct matrox_fb_info *minfo = info2minfo(info);

	if ((area->sx | area->dx | area->width) & 1)
		cfb_copyarea(info, area);
	else
		matrox_accel_bmove_lin(minfo, minfo->fbcon.var.xres_virtual >> 1, area->sy, area->sx >> 1, area->dy, area->dx >> 1, area->height, area->width >> 1);
}

static void matroxfb_copyarea(struct fb_info* info, const struct fb_copyarea* area) {
	struct matrox_fb_info *minfo = info2minfo(info);

	matrox_accel_bmove(minfo, minfo->fbcon.var.xres_virtual, area->sy, area->sx, area->dy, area->dx, area->height, area->width);
}

static void matroxfb_accel_clear(struct matrox_fb_info *minfo, u_int32_t color,
				 int sy, int sx, int height, int width)
{
	CRITFLAGS

	DBG(__func__)

	CRITBEGIN

	mga_fifo(7);
	matrox_accel_restore_maccess(minfo);
	mga_outl(M_DWGCTL, minfo->accel.m_dwg_rect | M_DWG_REPLACE);
	mga_outl(M_FCOL, color);
	mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx);
	mga_ydstlen(sy, height);
	WaitTillIdle();

	CRITEND
}

static void matroxfb_fillrect(struct fb_info* info, const struct fb_fillrect* rect) {
	struct matrox_fb_info *minfo = info2minfo(info);

	switch (rect->rop) {
		case ROP_COPY:
			matroxfb_accel_clear(minfo, ((u_int32_t *)info->pseudo_palette)[rect->color], rect->dy, rect->dx, rect->height, rect->width);
			break;
	}
}

static void matroxfb_cfb4_clear(struct matrox_fb_info *minfo, u_int32_t bgx,
				int sy, int sx, int height, int width)
{
	int whattodo;
	CRITFLAGS

	DBG(__func__)

	CRITBEGIN

	whattodo = 0;
	if (sx & 1) {
		sx ++;
		if (!width) return;
		width --;
		whattodo = 1;
	}
	if (width & 1) {
		whattodo |= 2;
	}
	width >>= 1;
	sx >>= 1;
	if (width) {
		mga_fifo(7);
		matrox_accel_restore_maccess(minfo);
		mga_outl(M_DWGCTL, minfo->accel.m_dwg_rect | M_DWG_REPLACE2);
		mga_outl(M_FCOL, bgx);
		mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx);
		mga_outl(M_YDST, sy * minfo->fbcon.var.xres_virtual >> 6);
		mga_outl(M_LEN | M_EXEC, height);
		WaitTillIdle();
	}
	if (whattodo) {
		u_int32_t step = minfo->fbcon.var.xres_virtual >> 1;
		vaddr_t vbase = minfo->video.vbase;
		if (whattodo & 1) {
			unsigned int uaddr = sy * step + sx - 1;
			u_int32_t loop;
			u_int8_t bgx2 = bgx & 0xF0;
			for (loop = height; loop > 0; loop --) {
				mga_writeb(vbase, uaddr, (mga_readb(vbase, uaddr) & 0x0F) | bgx2);
				uaddr += step;
			}
		}
		if (whattodo & 2) {
			unsigned int uaddr = sy * step + sx + width;
			u_int32_t loop;
			u_int8_t bgx2 = bgx & 0x0F;
			for (loop = height; loop > 0; loop --) {
				mga_writeb(vbase, uaddr, (mga_readb(vbase, uaddr) & 0xF0) | bgx2);
				uaddr += step;
			}
		}
	}

	CRITEND
}

static void matroxfb_cfb4_fillrect(struct fb_info* info, const struct fb_fillrect* rect) {
	struct matrox_fb_info *minfo = info2minfo(info);

	switch (rect->rop) {
		case ROP_COPY:
			matroxfb_cfb4_clear(minfo, ((u_int32_t *)info->pseudo_palette)[rect->color], rect->dy, rect->dx, rect->height, rect->width);
			break;
	}
}

static void matroxfb_1bpp_imageblit(struct matrox_fb_info *minfo, u_int32_t fgx,
				    u_int32_t bgx, const u_int8_t *chardata,
				    int width, int height, int yy, int xx)
{
	u_int32_t step;
	u_int32_t ydstlen;
	u_int32_t xlen;
	u_int32_t ar0;
	u_int32_t charcell;
	u_int32_t fxbndry;
	vaddr_t mmio;
	int easy;
	CRITFLAGS

	DBG_HEAVY(__func__);

	step = (width + 7) >> 3;
	charcell = height * step;
	xlen = (charcell + 3) & ~3;
	ydstlen = (yy << 16) | height;
	if (width == step << 3) {
		ar0 = height * width - 1;
		easy = 1;
	} else {
		ar0 = width - 1;
		easy = 0;
	}

	CRITBEGIN

	mga_fifo(5);
	matrox_accel_restore_maccess(minfo);
	if (easy)
		mga_outl(M_DWGCTL, M_DWG_ILOAD | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_LINEAR | M_DWG_REPLACE);
	else
		mga_outl(M_DWGCTL, M_DWG_ILOAD | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_REPLACE);
	mga_outl(M_FCOL, fgx);
	mga_outl(M_BCOL, bgx);
	fxbndry = ((xx + width - 1) << 16) | xx;
	mmio = minfo->mmio.vbase;

	mga_fifo(8);
	matrox_accel_restore_maccess(minfo);
	mga_writel(mmio, M_FXBNDRY, fxbndry);
	mga_writel(mmio, M_AR0, ar0);
	mga_writel(mmio, M_AR3, 0);
	if (easy) {
		mga_writel(mmio, M_YDSTLEN | M_EXEC, ydstlen);
		mga_memcpy_toio(mmio, chardata, xlen);
	} else {
		mga_writel(mmio, M_AR5, 0);
		mga_writel(mmio, M_YDSTLEN | M_EXEC, ydstlen);
		if ((step & 3) == 0) {
			/* Great. Source has 32bit aligned lines, so we can feed them
			   directly to the accelerator. */
			mga_memcpy_toio(mmio, chardata, charcell);
		} else if (step == 1) {
			/* Special case for 1..8bit widths */
			while (height--) {
#if defined(__BIG_ENDIAN)
				fb_writel((*chardata) << 24, mmio.vaddr);
#else
				fb_writel(*chardata, mmio.vaddr);
#endif
				chardata++;
			}
		} else if (step == 2) {
			/* Special case for 9..15bit widths */
			while (height--) {
#if defined(__BIG_ENDIAN)
				fb_writel((*(u_int16_t*)chardata) << 16, mmio.vaddr);
#else
				fb_writel(*(u_int16_t*)chardata, mmio.vaddr);
#endif
				chardata += 2;
			}
		} else {
			/* Tell... well, why bother... */
			while (height--) {
				size_t i;
				
				for (i = 0; i < step; i += 4) {
					/* Hope that there are at least three readable bytes beyond the end of bitmap */
					fb_writel(get_unaligned((u_int32_t*)(chardata + i)),mmio.vaddr);
				}
				chardata += step;
			}
		}
	}
	WaitTillIdle();
	CRITEND
}


static void matroxfb_imageblit(struct fb_info* info, const struct fb_image* image) {
	struct matrox_fb_info *minfo = info2minfo(info);

	DBG_HEAVY(__func__);

	if (image->depth == 1) {
		u_int32_t fgx, bgx;

		fgx = ((u_int32_t*)info->pseudo_palette)[image->fg_color];
		bgx = ((u_int32_t*)info->pseudo_palette)[image->bg_color];
		matroxfb_1bpp_imageblit(minfo, fgx, bgx, image->data, image->width, image->height, image->dy, image->dx);
	} else {
		/* Danger! image->depth is useless: logo painting code always
		   passes framebuffer color depth here, although logo data are
		   always 8bpp and info->pseudo_palette is changed to contain
		   logo palette to be used (but only for true/direct-color... sic...).
		   So do it completely in software... */
		cfb_imageblit(info, image);
	}
}

MODULE_LICENSE("GPL");
