/*
 *  linux/drivers/video/kyro/STG4000OverlayDevice.c
 *
 *  Copyright (C) 2000 Imagination Technologies Ltd
 *  Copyright (C) 2002 STMicroelectronics
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file COPYING in the main directory of this archive
 * for more details.
 */

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/types.h>

#include "STG4000Reg.h"
#include "STG4000Interface.h"

/* HW Defines */

#define STG4000_NO_SCALING    0x800
#define STG4000_NO_DECIMATION 0xFFFFFFFF

/* Primary surface */
#define STG4000_PRIM_NUM_PIX   5
#define STG4000_PRIM_ALIGN     4
#define STG4000_PRIM_ADDR_BITS 20

#define STG4000_PRIM_MIN_WIDTH  640
#define STG4000_PRIM_MAX_WIDTH  1600
#define STG4000_PRIM_MIN_HEIGHT 480
#define STG4000_PRIM_MAX_HEIGHT 1200

/* Overlay surface */
#define STG4000_OVRL_NUM_PIX   4
#define STG4000_OVRL_ALIGN     2
#define STG4000_OVRL_ADDR_BITS 20
#define STG4000_OVRL_NUM_MODES 5

#define STG4000_OVRL_MIN_WIDTH  0
#define STG4000_OVRL_MAX_WIDTH  720
#define STG4000_OVRL_MIN_HEIGHT 0
#define STG4000_OVRL_MAX_HEIGHT 576

/* Decimation and Scaling */
static u32 adwDecim8[33] = {
	    0xffffffff, 0xfffeffff, 0xffdffbff, 0xfefefeff, 0xfdf7efbf,
	    0xfbdf7bdf, 0xf7bbddef, 0xeeeeeeef, 0xeeddbb77, 0xedb76db7,
	    0xdb6db6db, 0xdb5b5b5b, 0xdab5ad6b, 0xd5ab55ab, 0xd555aaab,
	    0xaaaaaaab, 0xaaaa5555, 0xaa952a55, 0xa94a5295, 0xa5252525,
	    0xa4924925, 0x92491249, 0x91224489, 0x91111111, 0x90884211,
	    0x88410821, 0x88102041, 0x81010101, 0x80800801, 0x80010001,
	    0x80000001, 0x00000001, 0x00000000
};

typedef struct _OVRL_SRC_DEST {
	/*clipped on-screen pixel position of overlay */
	u32 ulDstX1;
	u32 ulDstY1;
	u32 ulDstX2;
	u32 ulDstY2;

	/*clipped pixel pos of source data within buffer thses need to be 128 bit word aligned */
	u32 ulSrcX1;
	u32 ulSrcY1;
	u32 ulSrcX2;
	u32 ulSrcY2;

	/* on-screen pixel position of overlay */
	s32 lDstX1;
	s32 lDstY1;
	s32 lDstX2;
	s32 lDstY2;
} OVRL_SRC_DEST;

static u32 ovlWidth, ovlHeight, ovlStride;
static int ovlLinear;

void ResetOverlayRegisters(volatile STG4000REG __iomem *pSTGReg)
{
	u32 tmp;

	/* Set Overlay address to default */
	tmp = STG_READ_REG(DACOverlayAddr);
	CLEAR_BITS_FRM_TO(0, 20);
	CLEAR_BIT(31);
	STG_WRITE_REG(DACOverlayAddr, tmp);

	/* Set Overlay U address */
	tmp = STG_READ_REG(DACOverlayUAddr);
	CLEAR_BITS_FRM_TO(0, 20);
	STG_WRITE_REG(DACOverlayUAddr, tmp);

	/* Set Overlay V address */
	tmp = STG_READ_REG(DACOverlayVAddr);
	CLEAR_BITS_FRM_TO(0, 20);
	STG_WRITE_REG(DACOverlayVAddr, tmp);

	/* Set Overlay Size */
	tmp = STG_READ_REG(DACOverlaySize);
	CLEAR_BITS_FRM_TO(0, 10);
	CLEAR_BITS_FRM_TO(12, 31);
	STG_WRITE_REG(DACOverlaySize, tmp);

	/* Set Overlay Vt Decimation */
	tmp = STG4000_NO_DECIMATION;
	STG_WRITE_REG(DACOverlayVtDec, tmp);

	/* Set Overlay format to default value */
	tmp = STG_READ_REG(DACPixelFormat);
	CLEAR_BITS_FRM_TO(4, 7);
	CLEAR_BITS_FRM_TO(16, 22);
	STG_WRITE_REG(DACPixelFormat, tmp);

	/* Set Vertical scaling to default */
	tmp = STG_READ_REG(DACVerticalScal);
	CLEAR_BITS_FRM_TO(0, 11);
	CLEAR_BITS_FRM_TO(16, 22);
	tmp |= STG4000_NO_SCALING;	/* Set to no scaling */
	STG_WRITE_REG(DACVerticalScal, tmp);

	/* Set Horizontal Scaling to default */
	tmp = STG_READ_REG(DACHorizontalScal);
	CLEAR_BITS_FRM_TO(0, 11);
	CLEAR_BITS_FRM_TO(16, 17);
	tmp |= STG4000_NO_SCALING;	/* Set to no scaling */
	STG_WRITE_REG(DACHorizontalScal, tmp);

	/* Set Blend mode to Alpha Blend */
	/* ????? SG 08/11/2001 Surely this isn't the alpha blend mode,
	   hopefully its overwrite
	 */
	tmp = STG_READ_REG(DACBlendCtrl);
	CLEAR_BITS_FRM_TO(0, 30);
	tmp = (GRAPHICS_MODE << 28);
	STG_WRITE_REG(DACBlendCtrl, tmp);

}

int CreateOverlaySurface(volatile STG4000REG __iomem *pSTGReg,
			 u32 inWidth,
			 u32 inHeight,
			 int bLinear,
			 u32 ulOverlayOffset,
			 u32 * retStride, u32 * retUVStride)
{
	u32 tmp;
	u32 ulStride;

	if (inWidth > STG4000_OVRL_MAX_WIDTH ||
	    inHeight > STG4000_OVRL_MAX_HEIGHT) {
		return -EINVAL;
	}

	/* Stride in 16 byte words - 16Bpp */
	if (bLinear) {
		/* Format is 16bits so num 16 byte words is width/8 */
		if ((inWidth & 0x7) == 0) {	/* inWidth % 8 */
			ulStride = (inWidth / 8);
		} else {
			/* Round up to next 16byte boundary */
			ulStride = ((inWidth + 8) / 8);
		}
	} else {
		/* Y component is 8bits so num 16 byte words is width/16 */
		if ((inWidth & 0xf) == 0) {	/* inWidth % 16 */
			ulStride = (inWidth / 16);
		} else {
			/* Round up to next 16byte boundary */
			ulStride = ((inWidth + 16) / 16);
		}
	}


	/* Set Overlay address and Format mode */
	tmp = STG_READ_REG(DACOverlayAddr);
	CLEAR_BITS_FRM_TO(0, 20);
	if (bLinear) {
		CLEAR_BIT(31);	/* Overlay format to Linear */
	} else {
		tmp |= SET_BIT(31);	/* Overlay format to Planer */
	}

	/* Only bits 24:4 of the Overlay address */
	tmp |= (ulOverlayOffset >> 4);
	STG_WRITE_REG(DACOverlayAddr, tmp);

	if (!bLinear) {
		u32 uvSize =
		    (inWidth & 0x1) ? (inWidth + 1 / 2) : (inWidth / 2);
		u32 uvStride;
		u32 ulOffset;
		/* Y component is 8bits so num 32 byte words is width/32 */
		if ((uvSize & 0xf) == 0) {	/* inWidth % 16 */
			uvStride = (uvSize / 16);
		} else {
			/* Round up to next 32byte boundary */
			uvStride = ((uvSize + 16) / 16);
		}

		ulOffset = ulOverlayOffset + (inHeight * (ulStride * 16));
		/* Align U,V data to 32byte boundary */
		if ((ulOffset & 0x1f) != 0)
			ulOffset = (ulOffset + 32L) & 0xffffffE0L;

		tmp = STG_READ_REG(DACOverlayUAddr);
		CLEAR_BITS_FRM_TO(0, 20);
		tmp |= (ulOffset >> 4);
		STG_WRITE_REG(DACOverlayUAddr, tmp);

		ulOffset += (inHeight / 2) * (uvStride * 16);
		/* Align U,V data to 32byte boundary */
		if ((ulOffset & 0x1f) != 0)
			ulOffset = (ulOffset + 32L) & 0xffffffE0L;

		tmp = STG_READ_REG(DACOverlayVAddr);
		CLEAR_BITS_FRM_TO(0, 20);
		tmp |= (ulOffset >> 4);
		STG_WRITE_REG(DACOverlayVAddr, tmp);

		*retUVStride = uvStride * 16;
	}


	/* Set Overlay YUV pixel format
	 * Make sure that LUT not used - ??????
	 */
	tmp = STG_READ_REG(DACPixelFormat);
	/* Only support Planer or UYVY linear formats */
	CLEAR_BITS_FRM_TO(4, 9);
	STG_WRITE_REG(DACPixelFormat, tmp);

	ovlWidth = inWidth;
	ovlHeight = inHeight;
	ovlStride = ulStride;
	ovlLinear = bLinear;
	*retStride = ulStride << 4;	/* In bytes */

	return 0;
}

int SetOverlayBlendMode(volatile STG4000REG __iomem *pSTGReg,
			OVRL_BLEND_MODE mode,
			u32 ulAlpha, u32 ulColorKey)
{
	u32 tmp;

	tmp = STG_READ_REG(DACBlendCtrl);
	CLEAR_BITS_FRM_TO(28, 30);
	tmp |= (mode << 28);

	switch (mode) {
	case COLOR_KEY:
		CLEAR_BITS_FRM_TO(0, 23);
		tmp |= (ulColorKey & 0x00FFFFFF);
		break;

	case GLOBAL_ALPHA:
		CLEAR_BITS_FRM_TO(24, 27);
		tmp |= ((ulAlpha & 0xF) << 24);
		break;

	case CK_PIXEL_ALPHA:
		CLEAR_BITS_FRM_TO(0, 23);
		tmp |= (ulColorKey & 0x00FFFFFF);
		break;

	case CK_GLOBAL_ALPHA:
		CLEAR_BITS_FRM_TO(0, 23);
		tmp |= (ulColorKey & 0x00FFFFFF);
		CLEAR_BITS_FRM_TO(24, 27);
		tmp |= ((ulAlpha & 0xF) << 24);
		break;

	case GRAPHICS_MODE:
	case PER_PIXEL_ALPHA:
		break;

	default:
		return -EINVAL;
	}

	STG_WRITE_REG(DACBlendCtrl, tmp);

	return 0;
}

void EnableOverlayPlane(volatile STG4000REG __iomem *pSTGReg)
{
	u32 tmp;
	/* Enable Overlay */
	tmp = STG_READ_REG(DACPixelFormat);
	tmp |= SET_BIT(7);
	STG_WRITE_REG(DACPixelFormat, tmp);

	/* Set video stream control */
	tmp = STG_READ_REG(DACStreamCtrl);
	tmp |= SET_BIT(1);	/* video stream */
	STG_WRITE_REG(DACStreamCtrl, tmp);
}

static u32 Overlap(u32 ulBits, u32 ulPattern)
{
	u32 ulCount = 0;

	while (ulBits) {
		if (!(ulPattern & 1))
			ulCount++;
		ulBits--;
		ulPattern = ulPattern >> 1;
	}

	return ulCount;

}

int SetOverlayViewPort(volatile STG4000REG __iomem *pSTGReg,
		       u32 left, u32 top,
		       u32 right, u32 bottom)
{
	OVRL_SRC_DEST srcDest;

	u32 ulSrcTop, ulSrcBottom;
	u32 ulSrc, ulDest;
	u32 ulFxScale, ulFxOffset;
	u32 ulHeight, ulWidth;
	u32 ulPattern;
	u32 ulDecimate, ulDecimated;
	u32 ulApplied;
	u32 ulDacXScale, ulDacYScale;
	u32 ulScale;
	u32 ulLeft, ulRight;
	u32 ulSrcLeft, ulSrcRight;
	u32 ulScaleLeft;
	u32 ulhDecim;
	u32 ulsVal;
	u32 ulVertDecFactor;
	int bResult;
	u32 ulClipOff = 0;
	u32 ulBits = 0;
	u32 ulsAdd = 0;
	u32 tmp, ulStride;
	u32 ulExcessPixels, ulClip, ulExtraLines;


	srcDest.ulSrcX1 = 0;
	srcDest.ulSrcY1 = 0;
	srcDest.ulSrcX2 = ovlWidth - 1;
	srcDest.ulSrcY2 = ovlHeight - 1;

	srcDest.ulDstX1 = left;
	srcDest.ulDstY1 = top;
	srcDest.ulDstX2 = right;
	srcDest.ulDstY2 = bottom;

	srcDest.lDstX1 = srcDest.ulDstX1;
	srcDest.lDstY1 = srcDest.ulDstY1;
	srcDest.lDstX2 = srcDest.ulDstX2;
	srcDest.lDstY2 = srcDest.ulDstY2;

    /************* Vertical decimation/scaling ******************/

	/* Get Src Top and Bottom */
	ulSrcTop = srcDest.ulSrcY1;
	ulSrcBottom = srcDest.ulSrcY2;

	ulSrc = ulSrcBottom - ulSrcTop;
	ulDest = srcDest.lDstY2 - srcDest.lDstY1;	/* on-screen overlay */

	if (ulSrc <= 1)
		return -EINVAL;

	/* First work out the position we are to display as offset from the
	 * source of the buffer
	 */
	ulFxScale = (ulDest << 11) / ulSrc;	/* fixed point scale factor */
	ulFxOffset = (srcDest.lDstY2 - srcDest.ulDstY2) << 11;

	ulSrcBottom = ulSrcBottom - (ulFxOffset / ulFxScale);
	ulSrc = ulSrcBottom - ulSrcTop;
	ulHeight = ulSrc;

	ulDest = srcDest.ulDstY2 - (srcDest.ulDstY1 - 1);
	ulPattern = adwDecim8[ulBits];

	/* At this point ulSrc represents the input decimator */
	if (ulSrc > ulDest) {
		ulDecimate = ulSrc - ulDest;
		ulBits = 0;
		ulApplied = ulSrc / 32;

		while (((ulBits * ulApplied) +
			Overlap((ulSrc % 32),
				adwDecim8[ulBits])) < ulDecimate)
			ulBits++;

		ulPattern = adwDecim8[ulBits];
		ulDecimated =
		    (ulBits * ulApplied) + Overlap((ulSrc % 32),
						   ulPattern);
		ulSrc = ulSrc - ulDecimated;	/* the number number of lines that will go into the scaler */
	}

	if (ulBits && (ulBits != 32)) {
		ulVertDecFactor = (63 - ulBits) / (32 - ulBits);	/* vertical decimation factor scaled up to nearest integer */
	} else {
		ulVertDecFactor = 1;
	}

	ulDacYScale = ((ulSrc - 1) * 2048) / (ulDest + 1);

	tmp = STG_READ_REG(DACOverlayVtDec);	/* Decimation */
	CLEAR_BITS_FRM_TO(0, 31);
	tmp = ulPattern;
	STG_WRITE_REG(DACOverlayVtDec, tmp);

	/***************** Horizontal decimation/scaling ***************************/

	/*
	 * Now we handle the horizontal case, this is a simplified version of
	 * the vertical case in that we decimate by factors of 2.  as we are
	 * working in words we should always be able to decimate by these
	 * factors.  as we always have to have a buffer which is aligned to a
	 * whole number of 128 bit words, we must align the left side to the
	 * lowest to the next lowest 128 bit boundary, and the right hand edge
	 * to the next largets boundary, (in a similar way to how we didi it in
	 * PMX1) as the left and right hand edges are aligned to these
	 * boundaries normally this only becomes an issue when we are chopping
	 * of one of the sides We shall work out vertical stuff first
	 */
	ulSrc = srcDest.ulSrcX2 - srcDest.ulSrcX1;
	ulDest = srcDest.lDstX2 - srcDest.lDstX1;
#ifdef _OLDCODE
	ulLeft = srcDest.ulDstX1;
	ulRight = srcDest.ulDstX2;
#else
	if (srcDest.ulDstX1 > 2) {
		ulLeft = srcDest.ulDstX1 + 2;
		ulRight = srcDest.ulDstX2 + 1;
	} else {
		ulLeft = srcDest.ulDstX1;
		ulRight = srcDest.ulDstX2 + 1;
	}
#endif
	/* first work out the position we are to display as offset from the source of the buffer */
	bResult = 1;

	do {
		if (ulDest == 0)
			return -EINVAL;

		/* source pixels per dest pixel <<11 */
		ulFxScale = ((ulSrc - 1) << 11) / (ulDest);

		/* then number of destination pixels out we are */
		ulFxOffset = ulFxScale * ((srcDest.ulDstX1 - srcDest.lDstX1) + ulClipOff);
		ulFxOffset >>= 11;

		/* this replaces the code which was making a decision as to use either ulFxOffset or ulSrcX1 */
		ulSrcLeft = srcDest.ulSrcX1 + ulFxOffset;

		/* then number of destination pixels out we are */
		ulFxOffset = ulFxScale * (srcDest.lDstX2 - srcDest.ulDstX2);
		ulFxOffset >>= 11;

		ulSrcRight = srcDest.ulSrcX2 - ulFxOffset;

		/*
		 * we must align these to our 128 bit boundaries. we shall
		 * round down the pixel pos to the nearest 8 pixels.
		 */
		ulScaleLeft = ulSrcLeft;

		/* shift fxscale until it is in the range of the scaler */
		ulhDecim = 0;
		ulScale = (((ulSrcRight - ulSrcLeft) - 1) << (11 - ulhDecim)) / (ulRight - ulLeft + 2);

		while (ulScale > 0x800) {
			ulhDecim++;
			ulScale = (((ulSrcRight - ulSrcLeft) - 1) << (11 - ulhDecim)) / (ulRight - ulLeft + 2);
		}

		/*
		 * to try and get the best values We first try and use
		 * src/dwdest for the scale factor, then we move onto src-1
		 *
		 * we want to check to see if we will need to clip data, if so
		 * then we should clip our source so that we don't need to
		 */
		if (!ovlLinear) {
			ulSrcLeft &= ~0x1f;

			/*
			 * we must align the right hand edge to the next 32
			 * pixel` boundary, must be on a 256 boundary so u, and
			 * v are 128 bit aligned
			 */
			ulSrcRight = (ulSrcRight + 0x1f) & ~0x1f;
		} else {
			ulSrcLeft &= ~0x7;

			/*
			 * we must align the right hand edge to the next
			 * 8pixel` boundary
			 */
			ulSrcRight = (ulSrcRight + 0x7) & ~0x7;
		}

		/* this is the input size line store needs to cope with */
		ulWidth = ulSrcRight - ulSrcLeft;

		/*
		 * use unclipped value to work out scale factror this is the
		 * scale factor we want we shall now work out the horizonal
		 * decimation and scaling
		 */
		ulsVal = ((ulWidth / 8) >> ulhDecim);

		if ((ulWidth != (ulsVal << ulhDecim) * 8))
			ulsAdd = 1;

		/* input pixels to scaler; */
		ulSrc = ulWidth >> ulhDecim;

		if (ulSrc <= 2)
			return -EINVAL;

		ulExcessPixels = ((((ulScaleLeft - ulSrcLeft)) << (11 - ulhDecim)) / ulScale);

		ulClip = (ulSrc << 11) / ulScale;
		ulClip -= (ulRight - ulLeft);
		ulClip += ulExcessPixels;

		if (ulClip)
			ulClip--;

		/* We may need to do more here if we really have a HW rev < 5 */
	} while (!bResult);

	ulExtraLines = (1 << ulhDecim) * ulVertDecFactor;
	ulExtraLines += 64;
	ulHeight += ulExtraLines;

	ulDacXScale = ulScale;


	tmp = STG_READ_REG(DACVerticalScal);
	CLEAR_BITS_FRM_TO(0, 11);
	CLEAR_BITS_FRM_TO(16, 22);	/* Vertical Scaling */

	/* Calculate new output line stride, this is always the number of 422
	   words in the line buffer, so it doesn't matter if the
	   mode is 420. Then set the vertical scale register.
	 */
	ulStride = (ulWidth >> (ulhDecim + 3)) + ulsAdd;
	tmp |= ((ulStride << 16) | (ulDacYScale));	/* DAC_LS_CTRL = stride */
	STG_WRITE_REG(DACVerticalScal, tmp);

	/* Now set up the overlay size using the modified width and height
	   from decimate and scaling calculations
	 */
	tmp = STG_READ_REG(DACOverlaySize);
	CLEAR_BITS_FRM_TO(0, 10);
	CLEAR_BITS_FRM_TO(12, 31);

	if (ovlLinear) {
		tmp |=
		    (ovlStride | ((ulHeight + 1) << 12) |
		     (((ulWidth / 8) - 1) << 23));
	} else {
		tmp |=
		    (ovlStride | ((ulHeight + 1) << 12) |
		     (((ulWidth / 32) - 1) << 23));
	}

	STG_WRITE_REG(DACOverlaySize, tmp);

	/* Set Video Window Start */
	tmp = ((ulLeft << 16)) | (srcDest.ulDstY1);
	STG_WRITE_REG(DACVidWinStart, tmp);

	/* Set Video Window End */
	tmp = ((ulRight) << 16) | (srcDest.ulDstY2);
	STG_WRITE_REG(DACVidWinEnd, tmp);

	/* Finally set up the rest of the overlay regs in the order
	   done in the IMG driver
	 */
	tmp = STG_READ_REG(DACPixelFormat);
	tmp = ((ulExcessPixels << 16) | tmp) & 0x7fffffff;
	STG_WRITE_REG(DACPixelFormat, tmp);

	tmp = STG_READ_REG(DACHorizontalScal);
	CLEAR_BITS_FRM_TO(0, 11);
	CLEAR_BITS_FRM_TO(16, 17);
	tmp |= ((ulhDecim << 16) | (ulDacXScale));
	STG_WRITE_REG(DACHorizontalScal, tmp);

	return 0;
}
