Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  *  linux/drivers/video/kyro/STG4000OverlayDevice.c
0003  *
0004  *  Copyright (C) 2000 Imagination Technologies Ltd
0005  *  Copyright (C) 2002 STMicroelectronics
0006  *
0007  * This file is subject to the terms and conditions of the GNU General Public
0008  * License.  See the file COPYING in the main directory of this archive
0009  * for more details.
0010  */
0011 
0012 #include <linux/kernel.h>
0013 #include <linux/errno.h>
0014 #include <linux/types.h>
0015 
0016 #include "STG4000Reg.h"
0017 #include "STG4000Interface.h"
0018 
0019 /* HW Defines */
0020 
0021 #define STG4000_NO_SCALING    0x800
0022 #define STG4000_NO_DECIMATION 0xFFFFFFFF
0023 
0024 /* Primary surface */
0025 #define STG4000_PRIM_NUM_PIX   5
0026 #define STG4000_PRIM_ALIGN     4
0027 #define STG4000_PRIM_ADDR_BITS 20
0028 
0029 #define STG4000_PRIM_MIN_WIDTH  640
0030 #define STG4000_PRIM_MAX_WIDTH  1600
0031 #define STG4000_PRIM_MIN_HEIGHT 480
0032 #define STG4000_PRIM_MAX_HEIGHT 1200
0033 
0034 /* Overlay surface */
0035 #define STG4000_OVRL_NUM_PIX   4
0036 #define STG4000_OVRL_ALIGN     2
0037 #define STG4000_OVRL_ADDR_BITS 20
0038 #define STG4000_OVRL_NUM_MODES 5
0039 
0040 #define STG4000_OVRL_MIN_WIDTH  0
0041 #define STG4000_OVRL_MAX_WIDTH  720
0042 #define STG4000_OVRL_MIN_HEIGHT 0
0043 #define STG4000_OVRL_MAX_HEIGHT 576
0044 
0045 /* Decimation and Scaling */
0046 static u32 adwDecim8[33] = {
0047         0xffffffff, 0xfffeffff, 0xffdffbff, 0xfefefeff, 0xfdf7efbf,
0048         0xfbdf7bdf, 0xf7bbddef, 0xeeeeeeef, 0xeeddbb77, 0xedb76db7,
0049         0xdb6db6db, 0xdb5b5b5b, 0xdab5ad6b, 0xd5ab55ab, 0xd555aaab,
0050         0xaaaaaaab, 0xaaaa5555, 0xaa952a55, 0xa94a5295, 0xa5252525,
0051         0xa4924925, 0x92491249, 0x91224489, 0x91111111, 0x90884211,
0052         0x88410821, 0x88102041, 0x81010101, 0x80800801, 0x80010001,
0053         0x80000001, 0x00000001, 0x00000000
0054 };
0055 
0056 typedef struct _OVRL_SRC_DEST {
0057     /*clipped on-screen pixel position of overlay */
0058     u32 ulDstX1;
0059     u32 ulDstY1;
0060     u32 ulDstX2;
0061     u32 ulDstY2;
0062 
0063     /*clipped pixel pos of source data within buffer thses need to be 128 bit word aligned */
0064     u32 ulSrcX1;
0065     u32 ulSrcY1;
0066     u32 ulSrcX2;
0067     u32 ulSrcY2;
0068 
0069     /* on-screen pixel position of overlay */
0070     s32 lDstX1;
0071     s32 lDstY1;
0072     s32 lDstX2;
0073     s32 lDstY2;
0074 } OVRL_SRC_DEST;
0075 
0076 static u32 ovlWidth, ovlHeight, ovlStride;
0077 static int ovlLinear;
0078 
0079 void ResetOverlayRegisters(volatile STG4000REG __iomem *pSTGReg)
0080 {
0081     u32 tmp;
0082 
0083     /* Set Overlay address to default */
0084     tmp = STG_READ_REG(DACOverlayAddr);
0085     CLEAR_BITS_FRM_TO(0, 20);
0086     CLEAR_BIT(31);
0087     STG_WRITE_REG(DACOverlayAddr, tmp);
0088 
0089     /* Set Overlay U address */
0090     tmp = STG_READ_REG(DACOverlayUAddr);
0091     CLEAR_BITS_FRM_TO(0, 20);
0092     STG_WRITE_REG(DACOverlayUAddr, tmp);
0093 
0094     /* Set Overlay V address */
0095     tmp = STG_READ_REG(DACOverlayVAddr);
0096     CLEAR_BITS_FRM_TO(0, 20);
0097     STG_WRITE_REG(DACOverlayVAddr, tmp);
0098 
0099     /* Set Overlay Size */
0100     tmp = STG_READ_REG(DACOverlaySize);
0101     CLEAR_BITS_FRM_TO(0, 10);
0102     CLEAR_BITS_FRM_TO(12, 31);
0103     STG_WRITE_REG(DACOverlaySize, tmp);
0104 
0105     /* Set Overlay Vt Decimation */
0106     tmp = STG4000_NO_DECIMATION;
0107     STG_WRITE_REG(DACOverlayVtDec, tmp);
0108 
0109     /* Set Overlay format to default value */
0110     tmp = STG_READ_REG(DACPixelFormat);
0111     CLEAR_BITS_FRM_TO(4, 7);
0112     CLEAR_BITS_FRM_TO(16, 22);
0113     STG_WRITE_REG(DACPixelFormat, tmp);
0114 
0115     /* Set Vertical scaling to default */
0116     tmp = STG_READ_REG(DACVerticalScal);
0117     CLEAR_BITS_FRM_TO(0, 11);
0118     CLEAR_BITS_FRM_TO(16, 22);
0119     tmp |= STG4000_NO_SCALING;  /* Set to no scaling */
0120     STG_WRITE_REG(DACVerticalScal, tmp);
0121 
0122     /* Set Horizontal Scaling to default */
0123     tmp = STG_READ_REG(DACHorizontalScal);
0124     CLEAR_BITS_FRM_TO(0, 11);
0125     CLEAR_BITS_FRM_TO(16, 17);
0126     tmp |= STG4000_NO_SCALING;  /* Set to no scaling */
0127     STG_WRITE_REG(DACHorizontalScal, tmp);
0128 
0129     /* Set Blend mode to Alpha Blend */
0130     /* ????? SG 08/11/2001 Surely this isn't the alpha blend mode,
0131        hopefully its overwrite
0132      */
0133     tmp = STG_READ_REG(DACBlendCtrl);
0134     CLEAR_BITS_FRM_TO(0, 30);
0135     tmp = (GRAPHICS_MODE << 28);
0136     STG_WRITE_REG(DACBlendCtrl, tmp);
0137 
0138 }
0139 
0140 int CreateOverlaySurface(volatile STG4000REG __iomem *pSTGReg,
0141              u32 inWidth,
0142              u32 inHeight,
0143              int bLinear,
0144              u32 ulOverlayOffset,
0145              u32 * retStride, u32 * retUVStride)
0146 {
0147     u32 tmp;
0148     u32 ulStride;
0149 
0150     if (inWidth > STG4000_OVRL_MAX_WIDTH ||
0151         inHeight > STG4000_OVRL_MAX_HEIGHT) {
0152         return -EINVAL;
0153     }
0154 
0155     /* Stride in 16 byte words - 16Bpp */
0156     if (bLinear) {
0157         /* Format is 16bits so num 16 byte words is width/8 */
0158         if ((inWidth & 0x7) == 0) { /* inWidth % 8 */
0159             ulStride = (inWidth / 8);
0160         } else {
0161             /* Round up to next 16byte boundary */
0162             ulStride = ((inWidth + 8) / 8);
0163         }
0164     } else {
0165         /* Y component is 8bits so num 16 byte words is width/16 */
0166         if ((inWidth & 0xf) == 0) { /* inWidth % 16 */
0167             ulStride = (inWidth / 16);
0168         } else {
0169             /* Round up to next 16byte boundary */
0170             ulStride = ((inWidth + 16) / 16);
0171         }
0172     }
0173 
0174 
0175     /* Set Overlay address and Format mode */
0176     tmp = STG_READ_REG(DACOverlayAddr);
0177     CLEAR_BITS_FRM_TO(0, 20);
0178     if (bLinear) {
0179         CLEAR_BIT(31);  /* Overlay format to Linear */
0180     } else {
0181         tmp |= SET_BIT(31); /* Overlay format to Planer */
0182     }
0183 
0184     /* Only bits 24:4 of the Overlay address */
0185     tmp |= (ulOverlayOffset >> 4);
0186     STG_WRITE_REG(DACOverlayAddr, tmp);
0187 
0188     if (!bLinear) {
0189         u32 uvSize =
0190             (inWidth & 0x1) ? (inWidth + 1 / 2) : (inWidth / 2);
0191         u32 uvStride;
0192         u32 ulOffset;
0193         /* Y component is 8bits so num 32 byte words is width/32 */
0194         if ((uvSize & 0xf) == 0) {  /* inWidth % 16 */
0195             uvStride = (uvSize / 16);
0196         } else {
0197             /* Round up to next 32byte boundary */
0198             uvStride = ((uvSize + 16) / 16);
0199         }
0200 
0201         ulOffset = ulOverlayOffset + (inHeight * (ulStride * 16));
0202         /* Align U,V data to 32byte boundary */
0203         if ((ulOffset & 0x1f) != 0)
0204             ulOffset = (ulOffset + 32L) & 0xffffffE0L;
0205 
0206         tmp = STG_READ_REG(DACOverlayUAddr);
0207         CLEAR_BITS_FRM_TO(0, 20);
0208         tmp |= (ulOffset >> 4);
0209         STG_WRITE_REG(DACOverlayUAddr, tmp);
0210 
0211         ulOffset += (inHeight / 2) * (uvStride * 16);
0212         /* Align U,V data to 32byte boundary */
0213         if ((ulOffset & 0x1f) != 0)
0214             ulOffset = (ulOffset + 32L) & 0xffffffE0L;
0215 
0216         tmp = STG_READ_REG(DACOverlayVAddr);
0217         CLEAR_BITS_FRM_TO(0, 20);
0218         tmp |= (ulOffset >> 4);
0219         STG_WRITE_REG(DACOverlayVAddr, tmp);
0220 
0221         *retUVStride = uvStride * 16;
0222     }
0223 
0224 
0225     /* Set Overlay YUV pixel format
0226      * Make sure that LUT not used - ??????
0227      */
0228     tmp = STG_READ_REG(DACPixelFormat);
0229     /* Only support Planer or UYVY linear formats */
0230     CLEAR_BITS_FRM_TO(4, 9);
0231     STG_WRITE_REG(DACPixelFormat, tmp);
0232 
0233     ovlWidth = inWidth;
0234     ovlHeight = inHeight;
0235     ovlStride = ulStride;
0236     ovlLinear = bLinear;
0237     *retStride = ulStride << 4; /* In bytes */
0238 
0239     return 0;
0240 }
0241 
0242 int SetOverlayBlendMode(volatile STG4000REG __iomem *pSTGReg,
0243             OVRL_BLEND_MODE mode,
0244             u32 ulAlpha, u32 ulColorKey)
0245 {
0246     u32 tmp;
0247 
0248     tmp = STG_READ_REG(DACBlendCtrl);
0249     CLEAR_BITS_FRM_TO(28, 30);
0250     tmp |= (mode << 28);
0251 
0252     switch (mode) {
0253     case COLOR_KEY:
0254         CLEAR_BITS_FRM_TO(0, 23);
0255         tmp |= (ulColorKey & 0x00FFFFFF);
0256         break;
0257 
0258     case GLOBAL_ALPHA:
0259         CLEAR_BITS_FRM_TO(24, 27);
0260         tmp |= ((ulAlpha & 0xF) << 24);
0261         break;
0262 
0263     case CK_PIXEL_ALPHA:
0264         CLEAR_BITS_FRM_TO(0, 23);
0265         tmp |= (ulColorKey & 0x00FFFFFF);
0266         break;
0267 
0268     case CK_GLOBAL_ALPHA:
0269         CLEAR_BITS_FRM_TO(0, 23);
0270         tmp |= (ulColorKey & 0x00FFFFFF);
0271         CLEAR_BITS_FRM_TO(24, 27);
0272         tmp |= ((ulAlpha & 0xF) << 24);
0273         break;
0274 
0275     case GRAPHICS_MODE:
0276     case PER_PIXEL_ALPHA:
0277         break;
0278 
0279     default:
0280         return -EINVAL;
0281     }
0282 
0283     STG_WRITE_REG(DACBlendCtrl, tmp);
0284 
0285     return 0;
0286 }
0287 
0288 void EnableOverlayPlane(volatile STG4000REG __iomem *pSTGReg)
0289 {
0290     u32 tmp;
0291     /* Enable Overlay */
0292     tmp = STG_READ_REG(DACPixelFormat);
0293     tmp |= SET_BIT(7);
0294     STG_WRITE_REG(DACPixelFormat, tmp);
0295 
0296     /* Set video stream control */
0297     tmp = STG_READ_REG(DACStreamCtrl);
0298     tmp |= SET_BIT(1);  /* video stream */
0299     STG_WRITE_REG(DACStreamCtrl, tmp);
0300 }
0301 
0302 static u32 Overlap(u32 ulBits, u32 ulPattern)
0303 {
0304     u32 ulCount = 0;
0305 
0306     while (ulBits) {
0307         if (!(ulPattern & 1))
0308             ulCount++;
0309         ulBits--;
0310         ulPattern = ulPattern >> 1;
0311     }
0312 
0313     return ulCount;
0314 
0315 }
0316 
0317 int SetOverlayViewPort(volatile STG4000REG __iomem *pSTGReg,
0318                u32 left, u32 top,
0319                u32 right, u32 bottom)
0320 {
0321     OVRL_SRC_DEST srcDest;
0322 
0323     u32 ulSrcTop, ulSrcBottom;
0324     u32 ulSrc, ulDest;
0325     u32 ulFxScale, ulFxOffset;
0326     u32 ulHeight, ulWidth;
0327     u32 ulPattern;
0328     u32 ulDecimate, ulDecimated;
0329     u32 ulApplied;
0330     u32 ulDacXScale, ulDacYScale;
0331     u32 ulScale;
0332     u32 ulLeft, ulRight;
0333     u32 ulSrcLeft, ulSrcRight;
0334     u32 ulScaleLeft;
0335     u32 ulhDecim;
0336     u32 ulsVal;
0337     u32 ulVertDecFactor;
0338     int bResult;
0339     u32 ulClipOff = 0;
0340     u32 ulBits = 0;
0341     u32 ulsAdd = 0;
0342     u32 tmp, ulStride;
0343     u32 ulExcessPixels, ulClip, ulExtraLines;
0344 
0345 
0346     srcDest.ulSrcX1 = 0;
0347     srcDest.ulSrcY1 = 0;
0348     srcDest.ulSrcX2 = ovlWidth - 1;
0349     srcDest.ulSrcY2 = ovlHeight - 1;
0350 
0351     srcDest.ulDstX1 = left;
0352     srcDest.ulDstY1 = top;
0353     srcDest.ulDstX2 = right;
0354     srcDest.ulDstY2 = bottom;
0355 
0356     srcDest.lDstX1 = srcDest.ulDstX1;
0357     srcDest.lDstY1 = srcDest.ulDstY1;
0358     srcDest.lDstX2 = srcDest.ulDstX2;
0359     srcDest.lDstY2 = srcDest.ulDstY2;
0360 
0361     /************* Vertical decimation/scaling ******************/
0362 
0363     /* Get Src Top and Bottom */
0364     ulSrcTop = srcDest.ulSrcY1;
0365     ulSrcBottom = srcDest.ulSrcY2;
0366 
0367     ulSrc = ulSrcBottom - ulSrcTop;
0368     ulDest = srcDest.lDstY2 - srcDest.lDstY1;   /* on-screen overlay */
0369 
0370     if (ulSrc <= 1)
0371         return -EINVAL;
0372 
0373     /* First work out the position we are to display as offset from the
0374      * source of the buffer
0375      */
0376     ulFxScale = (ulDest << 11) / ulSrc; /* fixed point scale factor */
0377     ulFxOffset = (srcDest.lDstY2 - srcDest.ulDstY2) << 11;
0378 
0379     ulSrcBottom = ulSrcBottom - (ulFxOffset / ulFxScale);
0380     ulSrc = ulSrcBottom - ulSrcTop;
0381     ulHeight = ulSrc;
0382 
0383     ulDest = srcDest.ulDstY2 - (srcDest.ulDstY1 - 1);
0384     ulPattern = adwDecim8[ulBits];
0385 
0386     /* At this point ulSrc represents the input decimator */
0387     if (ulSrc > ulDest) {
0388         ulDecimate = ulSrc - ulDest;
0389         ulBits = 0;
0390         ulApplied = ulSrc / 32;
0391 
0392         while (((ulBits * ulApplied) +
0393             Overlap((ulSrc % 32),
0394                 adwDecim8[ulBits])) < ulDecimate)
0395             ulBits++;
0396 
0397         ulPattern = adwDecim8[ulBits];
0398         ulDecimated =
0399             (ulBits * ulApplied) + Overlap((ulSrc % 32),
0400                            ulPattern);
0401         ulSrc = ulSrc - ulDecimated;    /* the number number of lines that will go into the scaler */
0402     }
0403 
0404     if (ulBits && (ulBits != 32)) {
0405         ulVertDecFactor = (63 - ulBits) / (32 - ulBits);    /* vertical decimation factor scaled up to nearest integer */
0406     } else {
0407         ulVertDecFactor = 1;
0408     }
0409 
0410     ulDacYScale = ((ulSrc - 1) * 2048) / (ulDest + 1);
0411 
0412     tmp = STG_READ_REG(DACOverlayVtDec);    /* Decimation */
0413     CLEAR_BITS_FRM_TO(0, 31);
0414     tmp = ulPattern;
0415     STG_WRITE_REG(DACOverlayVtDec, tmp);
0416 
0417     /***************** Horizontal decimation/scaling ***************************/
0418 
0419     /*
0420      * Now we handle the horizontal case, this is a simplified version of
0421      * the vertical case in that we decimate by factors of 2.  as we are
0422      * working in words we should always be able to decimate by these
0423      * factors.  as we always have to have a buffer which is aligned to a
0424      * whole number of 128 bit words, we must align the left side to the
0425      * lowest to the next lowest 128 bit boundary, and the right hand edge
0426      * to the next largets boundary, (in a similar way to how we didi it in
0427      * PMX1) as the left and right hand edges are aligned to these
0428      * boundaries normally this only becomes an issue when we are chopping
0429      * of one of the sides We shall work out vertical stuff first
0430      */
0431     ulSrc = srcDest.ulSrcX2 - srcDest.ulSrcX1;
0432     ulDest = srcDest.lDstX2 - srcDest.lDstX1;
0433 #ifdef _OLDCODE
0434     ulLeft = srcDest.ulDstX1;
0435     ulRight = srcDest.ulDstX2;
0436 #else
0437     if (srcDest.ulDstX1 > 2) {
0438         ulLeft = srcDest.ulDstX1 + 2;
0439         ulRight = srcDest.ulDstX2 + 1;
0440     } else {
0441         ulLeft = srcDest.ulDstX1;
0442         ulRight = srcDest.ulDstX2 + 1;
0443     }
0444 #endif
0445     /* first work out the position we are to display as offset from the source of the buffer */
0446     bResult = 1;
0447 
0448     do {
0449         if (ulDest == 0)
0450             return -EINVAL;
0451 
0452         /* source pixels per dest pixel <<11 */
0453         ulFxScale = ((ulSrc - 1) << 11) / (ulDest);
0454 
0455         /* then number of destination pixels out we are */
0456         ulFxOffset = ulFxScale * ((srcDest.ulDstX1 - srcDest.lDstX1) + ulClipOff);
0457         ulFxOffset >>= 11;
0458 
0459         /* this replaces the code which was making a decision as to use either ulFxOffset or ulSrcX1 */
0460         ulSrcLeft = srcDest.ulSrcX1 + ulFxOffset;
0461 
0462         /* then number of destination pixels out we are */
0463         ulFxOffset = ulFxScale * (srcDest.lDstX2 - srcDest.ulDstX2);
0464         ulFxOffset >>= 11;
0465 
0466         ulSrcRight = srcDest.ulSrcX2 - ulFxOffset;
0467 
0468         /*
0469          * we must align these to our 128 bit boundaries. we shall
0470          * round down the pixel pos to the nearest 8 pixels.
0471          */
0472         ulScaleLeft = ulSrcLeft;
0473 
0474         /* shift fxscale until it is in the range of the scaler */
0475         ulhDecim = 0;
0476         ulScale = (((ulSrcRight - ulSrcLeft) - 1) << (11 - ulhDecim)) / (ulRight - ulLeft + 2);
0477 
0478         while (ulScale > 0x800) {
0479             ulhDecim++;
0480             ulScale = (((ulSrcRight - ulSrcLeft) - 1) << (11 - ulhDecim)) / (ulRight - ulLeft + 2);
0481         }
0482 
0483         /*
0484          * to try and get the best values We first try and use
0485          * src/dwdest for the scale factor, then we move onto src-1
0486          *
0487          * we want to check to see if we will need to clip data, if so
0488          * then we should clip our source so that we don't need to
0489          */
0490         if (!ovlLinear) {
0491             ulSrcLeft &= ~0x1f;
0492 
0493             /*
0494              * we must align the right hand edge to the next 32
0495              * pixel` boundary, must be on a 256 boundary so u, and
0496              * v are 128 bit aligned
0497              */
0498             ulSrcRight = (ulSrcRight + 0x1f) & ~0x1f;
0499         } else {
0500             ulSrcLeft &= ~0x7;
0501 
0502             /*
0503              * we must align the right hand edge to the next
0504              * 8pixel` boundary
0505              */
0506             ulSrcRight = (ulSrcRight + 0x7) & ~0x7;
0507         }
0508 
0509         /* this is the input size line store needs to cope with */
0510         ulWidth = ulSrcRight - ulSrcLeft;
0511 
0512         /*
0513          * use unclipped value to work out scale factror this is the
0514          * scale factor we want we shall now work out the horizonal
0515          * decimation and scaling
0516          */
0517         ulsVal = ((ulWidth / 8) >> ulhDecim);
0518 
0519         if ((ulWidth != (ulsVal << ulhDecim) * 8))
0520             ulsAdd = 1;
0521 
0522         /* input pixels to scaler; */
0523         ulSrc = ulWidth >> ulhDecim;
0524 
0525         if (ulSrc <= 2)
0526             return -EINVAL;
0527 
0528         ulExcessPixels = ((((ulScaleLeft - ulSrcLeft)) << (11 - ulhDecim)) / ulScale);
0529 
0530         ulClip = (ulSrc << 11) / ulScale;
0531         ulClip -= (ulRight - ulLeft);
0532         ulClip += ulExcessPixels;
0533 
0534         if (ulClip)
0535             ulClip--;
0536 
0537         /* We may need to do more here if we really have a HW rev < 5 */
0538     } while (!bResult);
0539 
0540     ulExtraLines = (1 << ulhDecim) * ulVertDecFactor;
0541     ulExtraLines += 64;
0542     ulHeight += ulExtraLines;
0543 
0544     ulDacXScale = ulScale;
0545 
0546 
0547     tmp = STG_READ_REG(DACVerticalScal);
0548     CLEAR_BITS_FRM_TO(0, 11);
0549     CLEAR_BITS_FRM_TO(16, 22);  /* Vertical Scaling */
0550 
0551     /* Calculate new output line stride, this is always the number of 422
0552        words in the line buffer, so it doesn't matter if the
0553        mode is 420. Then set the vertical scale register.
0554      */
0555     ulStride = (ulWidth >> (ulhDecim + 3)) + ulsAdd;
0556     tmp |= ((ulStride << 16) | (ulDacYScale));  /* DAC_LS_CTRL = stride */
0557     STG_WRITE_REG(DACVerticalScal, tmp);
0558 
0559     /* Now set up the overlay size using the modified width and height
0560        from decimate and scaling calculations
0561      */
0562     tmp = STG_READ_REG(DACOverlaySize);
0563     CLEAR_BITS_FRM_TO(0, 10);
0564     CLEAR_BITS_FRM_TO(12, 31);
0565 
0566     if (ovlLinear) {
0567         tmp |=
0568             (ovlStride | ((ulHeight + 1) << 12) |
0569              (((ulWidth / 8) - 1) << 23));
0570     } else {
0571         tmp |=
0572             (ovlStride | ((ulHeight + 1) << 12) |
0573              (((ulWidth / 32) - 1) << 23));
0574     }
0575 
0576     STG_WRITE_REG(DACOverlaySize, tmp);
0577 
0578     /* Set Video Window Start */
0579     tmp = ((ulLeft << 16)) | (srcDest.ulDstY1);
0580     STG_WRITE_REG(DACVidWinStart, tmp);
0581 
0582     /* Set Video Window End */
0583     tmp = ((ulRight) << 16) | (srcDest.ulDstY2);
0584     STG_WRITE_REG(DACVidWinEnd, tmp);
0585 
0586     /* Finally set up the rest of the overlay regs in the order
0587        done in the IMG driver
0588      */
0589     tmp = STG_READ_REG(DACPixelFormat);
0590     tmp = ((ulExcessPixels << 16) | tmp) & 0x7fffffff;
0591     STG_WRITE_REG(DACPixelFormat, tmp);
0592 
0593     tmp = STG_READ_REG(DACHorizontalScal);
0594     CLEAR_BITS_FRM_TO(0, 11);
0595     CLEAR_BITS_FRM_TO(16, 17);
0596     tmp |= ((ulhDecim << 16) | (ulDacXScale));
0597     STG_WRITE_REG(DACHorizontalScal, tmp);
0598 
0599     return 0;
0600 }