cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

STG4000OverlayDevice.c (15608B)


      1/*
      2 *  linux/drivers/video/kyro/STG4000OverlayDevice.c
      3 *
      4 *  Copyright (C) 2000 Imagination Technologies Ltd
      5 *  Copyright (C) 2002 STMicroelectronics
      6 *
      7 * This file is subject to the terms and conditions of the GNU General Public
      8 * License.  See the file COPYING in the main directory of this archive
      9 * for more details.
     10 */
     11
     12#include <linux/kernel.h>
     13#include <linux/errno.h>
     14#include <linux/types.h>
     15
     16#include "STG4000Reg.h"
     17#include "STG4000Interface.h"
     18
     19/* HW Defines */
     20
     21#define STG4000_NO_SCALING    0x800
     22#define STG4000_NO_DECIMATION 0xFFFFFFFF
     23
     24/* Primary surface */
     25#define STG4000_PRIM_NUM_PIX   5
     26#define STG4000_PRIM_ALIGN     4
     27#define STG4000_PRIM_ADDR_BITS 20
     28
     29#define STG4000_PRIM_MIN_WIDTH  640
     30#define STG4000_PRIM_MAX_WIDTH  1600
     31#define STG4000_PRIM_MIN_HEIGHT 480
     32#define STG4000_PRIM_MAX_HEIGHT 1200
     33
     34/* Overlay surface */
     35#define STG4000_OVRL_NUM_PIX   4
     36#define STG4000_OVRL_ALIGN     2
     37#define STG4000_OVRL_ADDR_BITS 20
     38#define STG4000_OVRL_NUM_MODES 5
     39
     40#define STG4000_OVRL_MIN_WIDTH  0
     41#define STG4000_OVRL_MAX_WIDTH  720
     42#define STG4000_OVRL_MIN_HEIGHT 0
     43#define STG4000_OVRL_MAX_HEIGHT 576
     44
     45/* Decimation and Scaling */
     46static u32 adwDecim8[33] = {
     47	    0xffffffff, 0xfffeffff, 0xffdffbff, 0xfefefeff, 0xfdf7efbf,
     48	    0xfbdf7bdf, 0xf7bbddef, 0xeeeeeeef, 0xeeddbb77, 0xedb76db7,
     49	    0xdb6db6db, 0xdb5b5b5b, 0xdab5ad6b, 0xd5ab55ab, 0xd555aaab,
     50	    0xaaaaaaab, 0xaaaa5555, 0xaa952a55, 0xa94a5295, 0xa5252525,
     51	    0xa4924925, 0x92491249, 0x91224489, 0x91111111, 0x90884211,
     52	    0x88410821, 0x88102041, 0x81010101, 0x80800801, 0x80010001,
     53	    0x80000001, 0x00000001, 0x00000000
     54};
     55
     56typedef struct _OVRL_SRC_DEST {
     57	/*clipped on-screen pixel position of overlay */
     58	u32 ulDstX1;
     59	u32 ulDstY1;
     60	u32 ulDstX2;
     61	u32 ulDstY2;
     62
     63	/*clipped pixel pos of source data within buffer thses need to be 128 bit word aligned */
     64	u32 ulSrcX1;
     65	u32 ulSrcY1;
     66	u32 ulSrcX2;
     67	u32 ulSrcY2;
     68
     69	/* on-screen pixel position of overlay */
     70	s32 lDstX1;
     71	s32 lDstY1;
     72	s32 lDstX2;
     73	s32 lDstY2;
     74} OVRL_SRC_DEST;
     75
     76static u32 ovlWidth, ovlHeight, ovlStride;
     77static int ovlLinear;
     78
     79void ResetOverlayRegisters(volatile STG4000REG __iomem *pSTGReg)
     80{
     81	u32 tmp;
     82
     83	/* Set Overlay address to default */
     84	tmp = STG_READ_REG(DACOverlayAddr);
     85	CLEAR_BITS_FRM_TO(0, 20);
     86	CLEAR_BIT(31);
     87	STG_WRITE_REG(DACOverlayAddr, tmp);
     88
     89	/* Set Overlay U address */
     90	tmp = STG_READ_REG(DACOverlayUAddr);
     91	CLEAR_BITS_FRM_TO(0, 20);
     92	STG_WRITE_REG(DACOverlayUAddr, tmp);
     93
     94	/* Set Overlay V address */
     95	tmp = STG_READ_REG(DACOverlayVAddr);
     96	CLEAR_BITS_FRM_TO(0, 20);
     97	STG_WRITE_REG(DACOverlayVAddr, tmp);
     98
     99	/* Set Overlay Size */
    100	tmp = STG_READ_REG(DACOverlaySize);
    101	CLEAR_BITS_FRM_TO(0, 10);
    102	CLEAR_BITS_FRM_TO(12, 31);
    103	STG_WRITE_REG(DACOverlaySize, tmp);
    104
    105	/* Set Overlay Vt Decimation */
    106	tmp = STG4000_NO_DECIMATION;
    107	STG_WRITE_REG(DACOverlayVtDec, tmp);
    108
    109	/* Set Overlay format to default value */
    110	tmp = STG_READ_REG(DACPixelFormat);
    111	CLEAR_BITS_FRM_TO(4, 7);
    112	CLEAR_BITS_FRM_TO(16, 22);
    113	STG_WRITE_REG(DACPixelFormat, tmp);
    114
    115	/* Set Vertical scaling to default */
    116	tmp = STG_READ_REG(DACVerticalScal);
    117	CLEAR_BITS_FRM_TO(0, 11);
    118	CLEAR_BITS_FRM_TO(16, 22);
    119	tmp |= STG4000_NO_SCALING;	/* Set to no scaling */
    120	STG_WRITE_REG(DACVerticalScal, tmp);
    121
    122	/* Set Horizontal Scaling to default */
    123	tmp = STG_READ_REG(DACHorizontalScal);
    124	CLEAR_BITS_FRM_TO(0, 11);
    125	CLEAR_BITS_FRM_TO(16, 17);
    126	tmp |= STG4000_NO_SCALING;	/* Set to no scaling */
    127	STG_WRITE_REG(DACHorizontalScal, tmp);
    128
    129	/* Set Blend mode to Alpha Blend */
    130	/* ????? SG 08/11/2001 Surely this isn't the alpha blend mode,
    131	   hopefully its overwrite
    132	 */
    133	tmp = STG_READ_REG(DACBlendCtrl);
    134	CLEAR_BITS_FRM_TO(0, 30);
    135	tmp = (GRAPHICS_MODE << 28);
    136	STG_WRITE_REG(DACBlendCtrl, tmp);
    137
    138}
    139
    140int CreateOverlaySurface(volatile STG4000REG __iomem *pSTGReg,
    141			 u32 inWidth,
    142			 u32 inHeight,
    143			 int bLinear,
    144			 u32 ulOverlayOffset,
    145			 u32 * retStride, u32 * retUVStride)
    146{
    147	u32 tmp;
    148	u32 ulStride;
    149
    150	if (inWidth > STG4000_OVRL_MAX_WIDTH ||
    151	    inHeight > STG4000_OVRL_MAX_HEIGHT) {
    152		return -EINVAL;
    153	}
    154
    155	/* Stride in 16 byte words - 16Bpp */
    156	if (bLinear) {
    157		/* Format is 16bits so num 16 byte words is width/8 */
    158		if ((inWidth & 0x7) == 0) {	/* inWidth % 8 */
    159			ulStride = (inWidth / 8);
    160		} else {
    161			/* Round up to next 16byte boundary */
    162			ulStride = ((inWidth + 8) / 8);
    163		}
    164	} else {
    165		/* Y component is 8bits so num 16 byte words is width/16 */
    166		if ((inWidth & 0xf) == 0) {	/* inWidth % 16 */
    167			ulStride = (inWidth / 16);
    168		} else {
    169			/* Round up to next 16byte boundary */
    170			ulStride = ((inWidth + 16) / 16);
    171		}
    172	}
    173
    174
    175	/* Set Overlay address and Format mode */
    176	tmp = STG_READ_REG(DACOverlayAddr);
    177	CLEAR_BITS_FRM_TO(0, 20);
    178	if (bLinear) {
    179		CLEAR_BIT(31);	/* Overlay format to Linear */
    180	} else {
    181		tmp |= SET_BIT(31);	/* Overlay format to Planer */
    182	}
    183
    184	/* Only bits 24:4 of the Overlay address */
    185	tmp |= (ulOverlayOffset >> 4);
    186	STG_WRITE_REG(DACOverlayAddr, tmp);
    187
    188	if (!bLinear) {
    189		u32 uvSize =
    190		    (inWidth & 0x1) ? (inWidth + 1 / 2) : (inWidth / 2);
    191		u32 uvStride;
    192		u32 ulOffset;
    193		/* Y component is 8bits so num 32 byte words is width/32 */
    194		if ((uvSize & 0xf) == 0) {	/* inWidth % 16 */
    195			uvStride = (uvSize / 16);
    196		} else {
    197			/* Round up to next 32byte boundary */
    198			uvStride = ((uvSize + 16) / 16);
    199		}
    200
    201		ulOffset = ulOverlayOffset + (inHeight * (ulStride * 16));
    202		/* Align U,V data to 32byte boundary */
    203		if ((ulOffset & 0x1f) != 0)
    204			ulOffset = (ulOffset + 32L) & 0xffffffE0L;
    205
    206		tmp = STG_READ_REG(DACOverlayUAddr);
    207		CLEAR_BITS_FRM_TO(0, 20);
    208		tmp |= (ulOffset >> 4);
    209		STG_WRITE_REG(DACOverlayUAddr, tmp);
    210
    211		ulOffset += (inHeight / 2) * (uvStride * 16);
    212		/* Align U,V data to 32byte boundary */
    213		if ((ulOffset & 0x1f) != 0)
    214			ulOffset = (ulOffset + 32L) & 0xffffffE0L;
    215
    216		tmp = STG_READ_REG(DACOverlayVAddr);
    217		CLEAR_BITS_FRM_TO(0, 20);
    218		tmp |= (ulOffset >> 4);
    219		STG_WRITE_REG(DACOverlayVAddr, tmp);
    220
    221		*retUVStride = uvStride * 16;
    222	}
    223
    224
    225	/* Set Overlay YUV pixel format
    226	 * Make sure that LUT not used - ??????
    227	 */
    228	tmp = STG_READ_REG(DACPixelFormat);
    229	/* Only support Planer or UYVY linear formats */
    230	CLEAR_BITS_FRM_TO(4, 9);
    231	STG_WRITE_REG(DACPixelFormat, tmp);
    232
    233	ovlWidth = inWidth;
    234	ovlHeight = inHeight;
    235	ovlStride = ulStride;
    236	ovlLinear = bLinear;
    237	*retStride = ulStride << 4;	/* In bytes */
    238
    239	return 0;
    240}
    241
    242int SetOverlayBlendMode(volatile STG4000REG __iomem *pSTGReg,
    243			OVRL_BLEND_MODE mode,
    244			u32 ulAlpha, u32 ulColorKey)
    245{
    246	u32 tmp;
    247
    248	tmp = STG_READ_REG(DACBlendCtrl);
    249	CLEAR_BITS_FRM_TO(28, 30);
    250	tmp |= (mode << 28);
    251
    252	switch (mode) {
    253	case COLOR_KEY:
    254		CLEAR_BITS_FRM_TO(0, 23);
    255		tmp |= (ulColorKey & 0x00FFFFFF);
    256		break;
    257
    258	case GLOBAL_ALPHA:
    259		CLEAR_BITS_FRM_TO(24, 27);
    260		tmp |= ((ulAlpha & 0xF) << 24);
    261		break;
    262
    263	case CK_PIXEL_ALPHA:
    264		CLEAR_BITS_FRM_TO(0, 23);
    265		tmp |= (ulColorKey & 0x00FFFFFF);
    266		break;
    267
    268	case CK_GLOBAL_ALPHA:
    269		CLEAR_BITS_FRM_TO(0, 23);
    270		tmp |= (ulColorKey & 0x00FFFFFF);
    271		CLEAR_BITS_FRM_TO(24, 27);
    272		tmp |= ((ulAlpha & 0xF) << 24);
    273		break;
    274
    275	case GRAPHICS_MODE:
    276	case PER_PIXEL_ALPHA:
    277		break;
    278
    279	default:
    280		return -EINVAL;
    281	}
    282
    283	STG_WRITE_REG(DACBlendCtrl, tmp);
    284
    285	return 0;
    286}
    287
    288void EnableOverlayPlane(volatile STG4000REG __iomem *pSTGReg)
    289{
    290	u32 tmp;
    291	/* Enable Overlay */
    292	tmp = STG_READ_REG(DACPixelFormat);
    293	tmp |= SET_BIT(7);
    294	STG_WRITE_REG(DACPixelFormat, tmp);
    295
    296	/* Set video stream control */
    297	tmp = STG_READ_REG(DACStreamCtrl);
    298	tmp |= SET_BIT(1);	/* video stream */
    299	STG_WRITE_REG(DACStreamCtrl, tmp);
    300}
    301
    302static u32 Overlap(u32 ulBits, u32 ulPattern)
    303{
    304	u32 ulCount = 0;
    305
    306	while (ulBits) {
    307		if (!(ulPattern & 1))
    308			ulCount++;
    309		ulBits--;
    310		ulPattern = ulPattern >> 1;
    311	}
    312
    313	return ulCount;
    314
    315}
    316
    317int SetOverlayViewPort(volatile STG4000REG __iomem *pSTGReg,
    318		       u32 left, u32 top,
    319		       u32 right, u32 bottom)
    320{
    321	OVRL_SRC_DEST srcDest;
    322
    323	u32 ulSrcTop, ulSrcBottom;
    324	u32 ulSrc, ulDest;
    325	u32 ulFxScale, ulFxOffset;
    326	u32 ulHeight, ulWidth;
    327	u32 ulPattern;
    328	u32 ulDecimate, ulDecimated;
    329	u32 ulApplied;
    330	u32 ulDacXScale, ulDacYScale;
    331	u32 ulScale;
    332	u32 ulLeft, ulRight;
    333	u32 ulSrcLeft, ulSrcRight;
    334	u32 ulScaleLeft;
    335	u32 ulhDecim;
    336	u32 ulsVal;
    337	u32 ulVertDecFactor;
    338	int bResult;
    339	u32 ulClipOff = 0;
    340	u32 ulBits = 0;
    341	u32 ulsAdd = 0;
    342	u32 tmp, ulStride;
    343	u32 ulExcessPixels, ulClip, ulExtraLines;
    344
    345
    346	srcDest.ulSrcX1 = 0;
    347	srcDest.ulSrcY1 = 0;
    348	srcDest.ulSrcX2 = ovlWidth - 1;
    349	srcDest.ulSrcY2 = ovlHeight - 1;
    350
    351	srcDest.ulDstX1 = left;
    352	srcDest.ulDstY1 = top;
    353	srcDest.ulDstX2 = right;
    354	srcDest.ulDstY2 = bottom;
    355
    356	srcDest.lDstX1 = srcDest.ulDstX1;
    357	srcDest.lDstY1 = srcDest.ulDstY1;
    358	srcDest.lDstX2 = srcDest.ulDstX2;
    359	srcDest.lDstY2 = srcDest.ulDstY2;
    360
    361    /************* Vertical decimation/scaling ******************/
    362
    363	/* Get Src Top and Bottom */
    364	ulSrcTop = srcDest.ulSrcY1;
    365	ulSrcBottom = srcDest.ulSrcY2;
    366
    367	ulSrc = ulSrcBottom - ulSrcTop;
    368	ulDest = srcDest.lDstY2 - srcDest.lDstY1;	/* on-screen overlay */
    369
    370	if (ulSrc <= 1)
    371		return -EINVAL;
    372
    373	/* First work out the position we are to display as offset from the
    374	 * source of the buffer
    375	 */
    376	ulFxScale = (ulDest << 11) / ulSrc;	/* fixed point scale factor */
    377	ulFxOffset = (srcDest.lDstY2 - srcDest.ulDstY2) << 11;
    378
    379	ulSrcBottom = ulSrcBottom - (ulFxOffset / ulFxScale);
    380	ulSrc = ulSrcBottom - ulSrcTop;
    381	ulHeight = ulSrc;
    382
    383	ulDest = srcDest.ulDstY2 - (srcDest.ulDstY1 - 1);
    384	ulPattern = adwDecim8[ulBits];
    385
    386	/* At this point ulSrc represents the input decimator */
    387	if (ulSrc > ulDest) {
    388		ulDecimate = ulSrc - ulDest;
    389		ulBits = 0;
    390		ulApplied = ulSrc / 32;
    391
    392		while (((ulBits * ulApplied) +
    393			Overlap((ulSrc % 32),
    394				adwDecim8[ulBits])) < ulDecimate)
    395			ulBits++;
    396
    397		ulPattern = adwDecim8[ulBits];
    398		ulDecimated =
    399		    (ulBits * ulApplied) + Overlap((ulSrc % 32),
    400						   ulPattern);
    401		ulSrc = ulSrc - ulDecimated;	/* the number number of lines that will go into the scaler */
    402	}
    403
    404	if (ulBits && (ulBits != 32)) {
    405		ulVertDecFactor = (63 - ulBits) / (32 - ulBits);	/* vertical decimation factor scaled up to nearest integer */
    406	} else {
    407		ulVertDecFactor = 1;
    408	}
    409
    410	ulDacYScale = ((ulSrc - 1) * 2048) / (ulDest + 1);
    411
    412	tmp = STG_READ_REG(DACOverlayVtDec);	/* Decimation */
    413	CLEAR_BITS_FRM_TO(0, 31);
    414	tmp = ulPattern;
    415	STG_WRITE_REG(DACOverlayVtDec, tmp);
    416
    417	/***************** Horizontal decimation/scaling ***************************/
    418
    419	/*
    420	 * Now we handle the horizontal case, this is a simplified version of
    421	 * the vertical case in that we decimate by factors of 2.  as we are
    422	 * working in words we should always be able to decimate by these
    423	 * factors.  as we always have to have a buffer which is aligned to a
    424	 * whole number of 128 bit words, we must align the left side to the
    425	 * lowest to the next lowest 128 bit boundary, and the right hand edge
    426	 * to the next largets boundary, (in a similar way to how we didi it in
    427	 * PMX1) as the left and right hand edges are aligned to these
    428	 * boundaries normally this only becomes an issue when we are chopping
    429	 * of one of the sides We shall work out vertical stuff first
    430	 */
    431	ulSrc = srcDest.ulSrcX2 - srcDest.ulSrcX1;
    432	ulDest = srcDest.lDstX2 - srcDest.lDstX1;
    433#ifdef _OLDCODE
    434	ulLeft = srcDest.ulDstX1;
    435	ulRight = srcDest.ulDstX2;
    436#else
    437	if (srcDest.ulDstX1 > 2) {
    438		ulLeft = srcDest.ulDstX1 + 2;
    439		ulRight = srcDest.ulDstX2 + 1;
    440	} else {
    441		ulLeft = srcDest.ulDstX1;
    442		ulRight = srcDest.ulDstX2 + 1;
    443	}
    444#endif
    445	/* first work out the position we are to display as offset from the source of the buffer */
    446	bResult = 1;
    447
    448	do {
    449		if (ulDest == 0)
    450			return -EINVAL;
    451
    452		/* source pixels per dest pixel <<11 */
    453		ulFxScale = ((ulSrc - 1) << 11) / (ulDest);
    454
    455		/* then number of destination pixels out we are */
    456		ulFxOffset = ulFxScale * ((srcDest.ulDstX1 - srcDest.lDstX1) + ulClipOff);
    457		ulFxOffset >>= 11;
    458
    459		/* this replaces the code which was making a decision as to use either ulFxOffset or ulSrcX1 */
    460		ulSrcLeft = srcDest.ulSrcX1 + ulFxOffset;
    461
    462		/* then number of destination pixels out we are */
    463		ulFxOffset = ulFxScale * (srcDest.lDstX2 - srcDest.ulDstX2);
    464		ulFxOffset >>= 11;
    465
    466		ulSrcRight = srcDest.ulSrcX2 - ulFxOffset;
    467
    468		/*
    469		 * we must align these to our 128 bit boundaries. we shall
    470		 * round down the pixel pos to the nearest 8 pixels.
    471		 */
    472		ulScaleLeft = ulSrcLeft;
    473
    474		/* shift fxscale until it is in the range of the scaler */
    475		ulhDecim = 0;
    476		ulScale = (((ulSrcRight - ulSrcLeft) - 1) << (11 - ulhDecim)) / (ulRight - ulLeft + 2);
    477
    478		while (ulScale > 0x800) {
    479			ulhDecim++;
    480			ulScale = (((ulSrcRight - ulSrcLeft) - 1) << (11 - ulhDecim)) / (ulRight - ulLeft + 2);
    481		}
    482
    483		/*
    484		 * to try and get the best values We first try and use
    485		 * src/dwdest for the scale factor, then we move onto src-1
    486		 *
    487		 * we want to check to see if we will need to clip data, if so
    488		 * then we should clip our source so that we don't need to
    489		 */
    490		if (!ovlLinear) {
    491			ulSrcLeft &= ~0x1f;
    492
    493			/*
    494			 * we must align the right hand edge to the next 32
    495			 * pixel` boundary, must be on a 256 boundary so u, and
    496			 * v are 128 bit aligned
    497			 */
    498			ulSrcRight = (ulSrcRight + 0x1f) & ~0x1f;
    499		} else {
    500			ulSrcLeft &= ~0x7;
    501
    502			/*
    503			 * we must align the right hand edge to the next
    504			 * 8pixel` boundary
    505			 */
    506			ulSrcRight = (ulSrcRight + 0x7) & ~0x7;
    507		}
    508
    509		/* this is the input size line store needs to cope with */
    510		ulWidth = ulSrcRight - ulSrcLeft;
    511
    512		/*
    513		 * use unclipped value to work out scale factror this is the
    514		 * scale factor we want we shall now work out the horizonal
    515		 * decimation and scaling
    516		 */
    517		ulsVal = ((ulWidth / 8) >> ulhDecim);
    518
    519		if ((ulWidth != (ulsVal << ulhDecim) * 8))
    520			ulsAdd = 1;
    521
    522		/* input pixels to scaler; */
    523		ulSrc = ulWidth >> ulhDecim;
    524
    525		if (ulSrc <= 2)
    526			return -EINVAL;
    527
    528		ulExcessPixels = ((((ulScaleLeft - ulSrcLeft)) << (11 - ulhDecim)) / ulScale);
    529
    530		ulClip = (ulSrc << 11) / ulScale;
    531		ulClip -= (ulRight - ulLeft);
    532		ulClip += ulExcessPixels;
    533
    534		if (ulClip)
    535			ulClip--;
    536
    537		/* We may need to do more here if we really have a HW rev < 5 */
    538	} while (!bResult);
    539
    540	ulExtraLines = (1 << ulhDecim) * ulVertDecFactor;
    541	ulExtraLines += 64;
    542	ulHeight += ulExtraLines;
    543
    544	ulDacXScale = ulScale;
    545
    546
    547	tmp = STG_READ_REG(DACVerticalScal);
    548	CLEAR_BITS_FRM_TO(0, 11);
    549	CLEAR_BITS_FRM_TO(16, 22);	/* Vertical Scaling */
    550
    551	/* Calculate new output line stride, this is always the number of 422
    552	   words in the line buffer, so it doesn't matter if the
    553	   mode is 420. Then set the vertical scale register.
    554	 */
    555	ulStride = (ulWidth >> (ulhDecim + 3)) + ulsAdd;
    556	tmp |= ((ulStride << 16) | (ulDacYScale));	/* DAC_LS_CTRL = stride */
    557	STG_WRITE_REG(DACVerticalScal, tmp);
    558
    559	/* Now set up the overlay size using the modified width and height
    560	   from decimate and scaling calculations
    561	 */
    562	tmp = STG_READ_REG(DACOverlaySize);
    563	CLEAR_BITS_FRM_TO(0, 10);
    564	CLEAR_BITS_FRM_TO(12, 31);
    565
    566	if (ovlLinear) {
    567		tmp |=
    568		    (ovlStride | ((ulHeight + 1) << 12) |
    569		     (((ulWidth / 8) - 1) << 23));
    570	} else {
    571		tmp |=
    572		    (ovlStride | ((ulHeight + 1) << 12) |
    573		     (((ulWidth / 32) - 1) << 23));
    574	}
    575
    576	STG_WRITE_REG(DACOverlaySize, tmp);
    577
    578	/* Set Video Window Start */
    579	tmp = ((ulLeft << 16)) | (srcDest.ulDstY1);
    580	STG_WRITE_REG(DACVidWinStart, tmp);
    581
    582	/* Set Video Window End */
    583	tmp = ((ulRight) << 16) | (srcDest.ulDstY2);
    584	STG_WRITE_REG(DACVidWinEnd, tmp);
    585
    586	/* Finally set up the rest of the overlay regs in the order
    587	   done in the IMG driver
    588	 */
    589	tmp = STG_READ_REG(DACPixelFormat);
    590	tmp = ((ulExcessPixels << 16) | tmp) & 0x7fffffff;
    591	STG_WRITE_REG(DACPixelFormat, tmp);
    592
    593	tmp = STG_READ_REG(DACHorizontalScal);
    594	CLEAR_BITS_FRM_TO(0, 11);
    595	CLEAR_BITS_FRM_TO(16, 17);
    596	tmp |= ((ulhDecim << 16) | (ulDacXScale));
    597	STG_WRITE_REG(DACHorizontalScal, tmp);
    598
    599	return 0;
    600}