
/*
 *  ATI Mach64 Hardware Acceleration
 */

#include <linux/delay.h>
#include <linux/fb.h>
#include <video/mach64.h>
#include "atyfb.h"

    /*
     *  Generic Mach64 routines
     */

/* this is for DMA GUI engine! work in progress */
typedef struct {
	u32 frame_buf_offset;
	u32 system_mem_addr;
	u32 command;
	u32 reserved;
} BM_DESCRIPTOR_ENTRY;

#define LAST_DESCRIPTOR (1 << 31)
#define SYSTEM_TO_FRAME_BUFFER 0

static u32 rotation24bpp(u32 dx, u32 direction)
{
	u32 rotation;
	if (direction & DST_X_LEFT_TO_RIGHT) {
		rotation = (dx / 4) % 6;
	} else {
		rotation = ((dx + 2) / 4) % 6;
	}

	return ((rotation << 8) | DST_24_ROTATION_ENABLE);
}

void aty_reset_engine(const struct atyfb_par *par)
{
	/* reset engine */
	aty_st_le32(GEN_TEST_CNTL,
		aty_ld_le32(GEN_TEST_CNTL, par) & ~GUI_ENGINE_ENABLE, par);
	/* enable engine */
	aty_st_le32(GEN_TEST_CNTL,
		aty_ld_le32(GEN_TEST_CNTL, par) | GUI_ENGINE_ENABLE, par);
	/* ensure engine is not locked up by clearing any FIFO or */
	/* HOST errors */
	aty_st_le32(BUS_CNTL,
		aty_ld_le32(BUS_CNTL, par) | BUS_HOST_ERR_ACK | BUS_FIFO_ERR_ACK, par);
}

static void reset_GTC_3D_engine(const struct atyfb_par *par)
{
	aty_st_le32(SCALE_3D_CNTL, 0xc0, par);
	mdelay(GTC_3D_RESET_DELAY);
	aty_st_le32(SETUP_CNTL, 0x00, par);
	mdelay(GTC_3D_RESET_DELAY);
	aty_st_le32(SCALE_3D_CNTL, 0x00, par);
	mdelay(GTC_3D_RESET_DELAY);
}

void aty_init_engine(struct atyfb_par *par, struct fb_info *info)
{
	u32 pitch_value;

	/* determine modal information from global mode structure */
	pitch_value = info->var.xres_virtual;

	if (info->var.bits_per_pixel == 24) {
		/* In 24 bpp, the engine is in 8 bpp - this requires that all */
		/* horizontal coordinates and widths must be adjusted */
		pitch_value *= 3;
	}

	/* On GTC (RagePro), we need to reset the 3D engine before */
	if (M64_HAS(RESET_3D))
		reset_GTC_3D_engine(par);

	/* Reset engine, enable, and clear any engine errors */
	aty_reset_engine(par);
	/* Ensure that vga page pointers are set to zero - the upper */
	/* page pointers are set to 1 to handle overflows in the */
	/* lower page */
	aty_st_le32(MEM_VGA_WP_SEL, 0x00010000, par);
	aty_st_le32(MEM_VGA_RP_SEL, 0x00010000, par);

	/* ---- Setup standard engine context ---- */

	/* All GUI registers here are FIFOed - therefore, wait for */
	/* the appropriate number of empty FIFO entries */
	wait_for_fifo(14, par);

	/* enable all registers to be loaded for context loads */
	aty_st_le32(CONTEXT_MASK, 0xFFFFFFFF, par);

	/* set destination pitch to modal pitch, set offset to zero */
	aty_st_le32(DST_OFF_PITCH, (pitch_value / 8) << 22, par);

	/* zero these registers (set them to a known state) */
	aty_st_le32(DST_Y_X, 0, par);
	aty_st_le32(DST_HEIGHT, 0, par);
	aty_st_le32(DST_BRES_ERR, 0, par);
	aty_st_le32(DST_BRES_INC, 0, par);
	aty_st_le32(DST_BRES_DEC, 0, par);

	/* set destination drawing attributes */
	aty_st_le32(DST_CNTL, DST_LAST_PEL | DST_Y_TOP_TO_BOTTOM |
		    DST_X_LEFT_TO_RIGHT, par);

	/* set source pitch to modal pitch, set offset to zero */
	aty_st_le32(SRC_OFF_PITCH, (pitch_value / 8) << 22, par);

	/* set these registers to a known state */
	aty_st_le32(SRC_Y_X, 0, par);
	aty_st_le32(SRC_HEIGHT1_WIDTH1, 1, par);
	aty_st_le32(SRC_Y_X_START, 0, par);
	aty_st_le32(SRC_HEIGHT2_WIDTH2, 1, par);

	/* set source pixel retrieving attributes */
	aty_st_le32(SRC_CNTL, SRC_LINE_X_LEFT_TO_RIGHT, par);

	/* set host attributes */
	wait_for_fifo(13, par);
	aty_st_le32(HOST_CNTL, 0, par);

	/* set pattern attributes */
	aty_st_le32(PAT_REG0, 0, par);
	aty_st_le32(PAT_REG1, 0, par);
	aty_st_le32(PAT_CNTL, 0, par);

	/* set scissors to modal size */
	aty_st_le32(SC_LEFT, 0, par);
	aty_st_le32(SC_TOP, 0, par);
	aty_st_le32(SC_BOTTOM, par->crtc.vyres - 1, par);
	aty_st_le32(SC_RIGHT, pitch_value - 1, par);

	/* set background color to minimum value (usually BLACK) */
	aty_st_le32(DP_BKGD_CLR, 0, par);

	/* set foreground color to maximum value (usually WHITE) */
	aty_st_le32(DP_FRGD_CLR, 0xFFFFFFFF, par);

	/* set write mask to effect all pixel bits */
	aty_st_le32(DP_WRITE_MASK, 0xFFFFFFFF, par);

	/* set foreground mix to overpaint and background mix to */
	/* no-effect */
	aty_st_le32(DP_MIX, FRGD_MIX_S | BKGD_MIX_D, par);

	/* set primary source pixel channel to foreground color */
	/* register */
	aty_st_le32(DP_SRC, FRGD_SRC_FRGD_CLR, par);

	/* set compare functionality to false (no-effect on */
	/* destination) */
	wait_for_fifo(3, par);
	aty_st_le32(CLR_CMP_CLR, 0, par);
	aty_st_le32(CLR_CMP_MASK, 0xFFFFFFFF, par);
	aty_st_le32(CLR_CMP_CNTL, 0, par);

	/* set pixel depth */
	wait_for_fifo(2, par);
	aty_st_le32(DP_PIX_WIDTH, par->crtc.dp_pix_width, par);
	aty_st_le32(DP_CHAIN_MASK, par->crtc.dp_chain_mask, par);

	wait_for_fifo(5, par);
 	aty_st_le32(SCALE_3D_CNTL, 0, par);
	aty_st_le32(Z_CNTL, 0, par);
	aty_st_le32(CRTC_INT_CNTL, aty_ld_le32(CRTC_INT_CNTL, par) & ~0x20,
		    par);
	aty_st_le32(GUI_TRAJ_CNTL, 0x100023, par);

	/* insure engine is idle before leaving */
	wait_for_idle(par);
}

    /*
     *  Accelerated functions
     */

static inline void draw_rect(s16 x, s16 y, u16 width, u16 height,
			     struct atyfb_par *par)
{
	/* perform rectangle fill */
	wait_for_fifo(2, par);
	aty_st_le32(DST_Y_X, (x << 16) | y, par);
	aty_st_le32(DST_HEIGHT_WIDTH, (width << 16) | height, par);
	par->blitter_may_be_busy = 1;
}

void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
{
	struct atyfb_par *par = (struct atyfb_par *) info->par;
	u32 dy = area->dy, sy = area->sy, direction = DST_LAST_PEL;
	u32 sx = area->sx, dx = area->dx, width = area->width, rotation = 0;

	if (par->asleep)
		return;
	if (!area->width || !area->height)
		return;
	if (!par->accel_flags) {
		cfb_copyarea(info, area);
		return;
	}

	if (info->var.bits_per_pixel == 24) {
		/* In 24 bpp, the engine is in 8 bpp - this requires that all */
		/* horizontal coordinates and widths must be adjusted */
		sx *= 3;
		dx *= 3;
		width *= 3;
	}

	if (area->sy < area->dy) {
		dy += area->height - 1;
		sy += area->height - 1;
	} else
		direction |= DST_Y_TOP_TO_BOTTOM;

	if (sx < dx) {
		dx += width - 1;
		sx += width - 1;
	} else
		direction |= DST_X_LEFT_TO_RIGHT;

	if (info->var.bits_per_pixel == 24) {
		rotation = rotation24bpp(dx, direction);
	}

	wait_for_fifo(4, par);
	aty_st_le32(DP_SRC, FRGD_SRC_BLIT, par);
	aty_st_le32(SRC_Y_X, (sx << 16) | sy, par);
	aty_st_le32(SRC_HEIGHT1_WIDTH1, (width << 16) | area->height, par);
	aty_st_le32(DST_CNTL, direction | rotation, par);
	draw_rect(dx, dy, width, area->height, par);
}

void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{
	struct atyfb_par *par = (struct atyfb_par *) info->par;
	u32 color = rect->color, dx = rect->dx, width = rect->width, rotation = 0;

	if (par->asleep)
		return;
	if (!rect->width || !rect->height)
		return;
	if (!par->accel_flags) {
		cfb_fillrect(info, rect);
		return;
	}

	color |= (rect->color << 8);
	color |= (rect->color << 16);

	if (info->var.bits_per_pixel == 24) {
		/* In 24 bpp, the engine is in 8 bpp - this requires that all */
		/* horizontal coordinates and widths must be adjusted */
		dx *= 3;
		width *= 3;
		rotation = rotation24bpp(dx, DST_X_LEFT_TO_RIGHT);
	}

	wait_for_fifo(3, par);
	aty_st_le32(DP_FRGD_CLR, color, par);
	aty_st_le32(DP_SRC,
		    BKGD_SRC_BKGD_CLR | FRGD_SRC_FRGD_CLR | MONO_SRC_ONE,
		    par);
	aty_st_le32(DST_CNTL,
		    DST_LAST_PEL | DST_Y_TOP_TO_BOTTOM |
		    DST_X_LEFT_TO_RIGHT | rotation, par);
	draw_rect(dx, rect->dy, width, rect->height, par);
}

void atyfb_imageblit(struct fb_info *info, const struct fb_image *image)
{
	struct atyfb_par *par = (struct atyfb_par *) info->par;
	u32 src_bytes, dx = image->dx, dy = image->dy, width = image->width;
	u32 pix_width_save, pix_width, host_cntl, rotation = 0, src, mix;

	if (par->asleep)
		return;
	if (!image->width || !image->height)
		return;
	if (!par->accel_flags ||
	    (image->depth != 1 && info->var.bits_per_pixel != image->depth)) {
		cfb_imageblit(info, image);
		return;
	}

	pix_width = pix_width_save = aty_ld_le32(DP_PIX_WIDTH, par);
	host_cntl = aty_ld_le32(HOST_CNTL, par) | HOST_BYTE_ALIGN;

	switch (image->depth) {
	case 1:
	    pix_width &= ~(BYTE_ORDER_MASK | HOST_MASK);
	    pix_width |= (BYTE_ORDER_MSB_TO_LSB | HOST_1BPP);
	    break;
	case 4:
	    pix_width &= ~(BYTE_ORDER_MASK | HOST_MASK);
	    pix_width |= (BYTE_ORDER_MSB_TO_LSB | HOST_4BPP);
	    break;
	case 8:
	    pix_width &= ~HOST_MASK;
	    pix_width |= HOST_8BPP;
	    break;
	case 15:
	    pix_width &= ~HOST_MASK;
	    pix_width |= HOST_15BPP;
	    break;
	case 16:
	    pix_width &= ~HOST_MASK;
	    pix_width |= HOST_16BPP;
	    break;
	case 24:
	    pix_width &= ~HOST_MASK;
	    pix_width |= HOST_24BPP;
	    break;
	case 32:
	    pix_width &= ~HOST_MASK;
	    pix_width |= HOST_32BPP;
	    break;
	}

	if (info->var.bits_per_pixel == 24) {
		/* In 24 bpp, the engine is in 8 bpp - this requires that all */
		/* horizontal coordinates and widths must be adjusted */
		dx *= 3;
		width *= 3;

		rotation = rotation24bpp(dx, DST_X_LEFT_TO_RIGHT);

		pix_width &= ~DST_MASK;
		pix_width |= DST_8BPP;

		/*
		 * since Rage 3D IIc we have DP_HOST_TRIPLE_EN bit
		 * this hwaccelerated triple has an issue with not aligned data
		 */
		if (M64_HAS(HW_TRIPLE) && image->width % 8 == 0)
			pix_width |= DP_HOST_TRIPLE_EN;
	}

	if (image->depth == 1) {
		u32 fg, bg;
		if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
		    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
			fg = ((u32*)(info->pseudo_palette))[image->fg_color];
			bg = ((u32*)(info->pseudo_palette))[image->bg_color];
		} else {
			fg = image->fg_color;
			bg = image->bg_color;
		}

		wait_for_fifo(2, par);
		aty_st_le32(DP_BKGD_CLR, bg, par);
		aty_st_le32(DP_FRGD_CLR, fg, par);
		src = MONO_SRC_HOST | FRGD_SRC_FRGD_CLR | BKGD_SRC_BKGD_CLR;
		mix = FRGD_MIX_S | BKGD_MIX_S;
	} else {
		src = MONO_SRC_ONE | FRGD_SRC_HOST;
		mix = FRGD_MIX_D_XOR_S | BKGD_MIX_D;
	}

	wait_for_fifo(6, par);
	aty_st_le32(DP_WRITE_MASK, 0xFFFFFFFF, par);
	aty_st_le32(DP_PIX_WIDTH, pix_width, par);
	aty_st_le32(DP_MIX, mix, par);
	aty_st_le32(DP_SRC, src, par);
	aty_st_le32(HOST_CNTL, host_cntl, par);
	aty_st_le32(DST_CNTL, DST_Y_TOP_TO_BOTTOM | DST_X_LEFT_TO_RIGHT | rotation, par);

	draw_rect(dx, dy, width, image->height, par);
	src_bytes = (((image->width * image->depth) + 7) / 8) * image->height;

	/* manual triple each pixel */
	if (info->var.bits_per_pixel == 24 && !(pix_width & DP_HOST_TRIPLE_EN)) {
		int inbit, outbit, mult24, byte_id_in_dword, width;
		u8 *pbitmapin = (u8*)image->data, *pbitmapout;
		u32 hostdword;

		for (width = image->width, inbit = 7, mult24 = 0; src_bytes; ) {
			for (hostdword = 0, pbitmapout = (u8*)&hostdword, byte_id_in_dword = 0;
				byte_id_in_dword < 4 && src_bytes;
				byte_id_in_dword++, pbitmapout++) {
				for (outbit = 7; outbit >= 0; outbit--) {
					*pbitmapout |= (((*pbitmapin >> inbit) & 1) << outbit);
					mult24++;
					/* next bit */
					if (mult24 == 3) {
						mult24 = 0;
						inbit--;
						width--;
					}

					/* next byte */
					if (inbit < 0 || width == 0) {
						src_bytes--;
						pbitmapin++;
						inbit = 7;

						if (width == 0) {
						    width = image->width;
						    outbit = 0;
						}
					}
				}
			}
			wait_for_fifo(1, par);
			aty_st_le32(HOST_DATA0, hostdword, par);
		}
	} else {
		u32 *pbitmap, dwords = (src_bytes + 3) / 4;
		for (pbitmap = (u32*)(image->data); dwords; dwords--, pbitmap++) {
			wait_for_fifo(1, par);
			aty_st_le32(HOST_DATA0, le32_to_cpup(pbitmap), par);
		}
	}

	/* restore pix_width */
	wait_for_fifo(1, par);
	aty_st_le32(DP_PIX_WIDTH, pix_width_save, par);
}
