// SPDX-License-Identifier: GPL-2.0-only
/*
 *
 * 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");
