summaryrefslogtreecommitdiff
path: root/src/via_video.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/via_video.c')
-rw-r--r--src/via_video.c314
1 files changed, 133 insertions, 181 deletions
diff --git a/src/via_video.c b/src/via_video.c
index badc20f..040c85d 100644
--- a/src/via_video.c
+++ b/src/via_video.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/via/via_video.c,v 1.12 2003/11/10 18:22:35 tsi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/via/via_video.c,v 1.17 2004/02/04 04:15:09 dawes Exp $ */
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
@@ -223,28 +223,10 @@ static char * XVPORTNAME[5] =
"XV_SWOV",
"XV_TV0" ,
"XV_TV1" ,
- /*"XV_TV2" ,*/
"XV_UTCTRL",
"XV_DUMMY"
};
-
-#define DDR100SUPPORTMODECOUNT 24
-#define DDR133UNSUPPORTMODECOUNT 19
-static const MODEINFO SupportDDR100[DDR100SUPPORTMODECOUNT]=
- {{640,480,8,60}, {640,480,8,75}, {640,480,8,85}, {640,480,8,100}, {640,480,8,120},
- {640,480,16,60}, {640,480,16,75}, {640,480,16,85}, {640,480,16,100}, {640,480,16,120},
- {640,480,32,60}, {640,480,32,75}, {640,480,32,85}, {640,480,16,100}, {640,480,32,120},
- {800,600,8,60}, {800,600,8,75}, {800,600,8,85}, {800,600,8,100}, {800,600,16,60},
- {800,600,16,75}, {800,600,16,85}, {800,600,32,60}, {1024,768,8,60}};
-
-static const MODEINFO UnSupportDDR133[DDR133UNSUPPORTMODECOUNT]=
- {{1152,864,32,75}, {1280,768,32,75}, {1280,768,32,85}, {1280,960,32,60}, {1280,960,32,75},
- {1280,960,32,85}, {1280,1024,16,85}, {1280,1024,32,60}, {1280,1024,32,75}, {1280,1024,32,85},
- {1400,1050,16,85}, {1400,1050,32,60}, {1400,1050,32,75}, {1400,1050,32,85}, {1600,1200,8,75},
- {1600,1200,8,85}, {1600,1200,16,75}, {1600,1200,16,85}, {1600,1200,32,60}};
-
-
/*
* F U N C T I O N
*/
@@ -264,54 +246,46 @@ static __inline void waitDISPLAYBEGIN(vmmtr viaVidEng)
while (IN_VBLANK);
}
-/* Decide if the mode support video overlay */
+/*
+ * Decide if the mode support video overlay. This depends on the bandwidth
+ * of the mode and the type of RAM available.
+ */
+
static Bool DecideOverlaySupport(VIAPtr pVia)
{
- unsigned long iCount;
+ /* Small trick here. We keep the height in 16's of lines and width in 32's
+ to avoid numeric overflow */
+ unsigned long bandwidth = (pVia->graphicInfo.dwHeight >> 4) * (pVia->graphicInfo.dwWidth >> 5) *
+ pVia->graphicInfo.dwBPP * pVia->graphicInfo.dwRefreshRate;
VGAOUT8(0x3D4, 0x3D);
switch ((VGAIN8(0x3D5) & 0x70) >> 4)
{
- case 0:
+ case 0: /* No overlay without DDR */
case SDR100:
- break;
-
case SDR133:
- break;
-
+ return FALSE;
case DDR100:
- for (iCount=0; iCount < DDR100SUPPORTMODECOUNT; iCount++)
+ /* Basic limit for DDR100 is about this */
+ if(bandwidth > 1800000)
+ return FALSE;
+ /* But we have constraints at higher than 800x600 */
+ if (pVia->graphicInfo.dwWidth > 800)
{
- if ( (pVia->graphicInfo.dwWidth == SupportDDR100[iCount].dwWidth) &&
- (pVia->graphicInfo.dwHeight == SupportDDR100[iCount].dwHeight) &&
- (pVia->graphicInfo.dwBPP == SupportDDR100[iCount].dwBPP) &&
- (pVia->graphicInfo.dwRefreshRate == SupportDDR100[iCount].dwRefreshRate) )
- {
- return TRUE;
- break;
- }
+ if(pVia->graphicInfo.dwBPP != 8)
+ return FALSE;
+ if(pVia->graphicInfo.dwHeight > 768)
+ return FALSE;
+ if(pVia->graphicInfo.dwRefreshRate > 60)
+ return FALSE;
}
-
- return FALSE;
- break;
+ return TRUE;
case DDR133:
- for (iCount=0; iCount < DDR133UNSUPPORTMODECOUNT; iCount++)
- {
- if ( (pVia->graphicInfo.dwWidth == UnSupportDDR133[iCount].dwWidth) &&
- (pVia->graphicInfo.dwHeight == UnSupportDDR133[iCount].dwHeight) &&
- (pVia->graphicInfo.dwBPP == UnSupportDDR133[iCount].dwBPP) &&
- (pVia->graphicInfo.dwRefreshRate == UnSupportDDR133[iCount].dwRefreshRate) )
- {
- return FALSE;
- break;
- }
- }
-
+ if(bandwidth > 7901250)
+ return FALSE;
return TRUE;
- break;
}
-
return FALSE;
}
@@ -377,7 +351,10 @@ void viaInitVideo(ScreenPtr pScreen)
DBG_DD(ErrorF(" via_video.c : viaInitVideo : \n"));
- if((pVia->Chipset == VIA_CLE266))
+ /*
+ * We have no KM400 information..
+ */
+ if(pVia->Chipset == VIA_CLE266)
{
newAdaptor = viaSetupImageVideoG(pScreen);
}
@@ -408,17 +385,6 @@ void viaInitVideo(ScreenPtr pScreen)
if(newAdaptors)
xfree(newAdaptors);
-
-
- /* Driver init */
- /* DriverProc(CREATEDRIVER,NULL); */
-
- /* 3rd party Device Init */
- /*
- InitializeVDEC();
- InitializeTUNER();
- InitializeAudio();
- */
}
@@ -433,6 +399,8 @@ viaSetupImageVideoG(ScreenPtr pScreen)
DBG_DD(ErrorF(" via_video.c : viaSetupImageVideoG: \n"));
+ /* Look for available devices */
+ ViaTunerProbe(pScrn);
xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
xvContrast = MAKE_ATOM("XV_CONTRAST");
@@ -455,25 +423,19 @@ viaSetupImageVideoG(ScreenPtr pScreen)
if(!(adaptPtr[i] = xf86XVAllocateVideoAdaptorRec(pScrn)))
return NULL;
- gviaPortPriv[i] = (viaPortPrivPtr)xcalloc(1, sizeof(viaPortPrivRec) );
- if ( ! gviaPortPriv[i] ){
- DBG_DD(ErrorF(" via_xvpriv.c : Fail to allocate gviaPortPriv: \n"));
- }
- else{
- DBG_DD(ErrorF(" via_xvpriv.c : gviaPortPriv[%d] = 0x%08x \n", i,gviaPortPriv[i]));
- }
- /*
- if(!(pPriv[i] = xcalloc(1, sizeof(viaPortPrivPtr))))
+ gviaPortPriv[i] = (viaPortPrivPtr)xnfcalloc(1, sizeof(viaPortPrivRec) );
+ pdevUnion[i] = (DevUnion *)xnfcalloc(1, sizeof(DevUnion));
+
+ if(i == 0) /* Overlay engine */
{
- xfree(adaptPtr[i]);
- return NULL;
+ adaptPtr[i]->type = XvInputMask | XvWindowMask | XvImageMask | XvVideoMask | XvStillMask;
+ adaptPtr[i]->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ }
+ else
+ {
+ adaptPtr[i]->type = XvInputMask | XvWindowMask | XvVideoMask;
+ adaptPtr[i]->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
}
- */
-
- pdevUnion[i] = (DevUnion *)xcalloc(1, sizeof(DevUnion) );
-
- adaptPtr[i]->type = XvInputMask | XvWindowMask | XvImageMask | XvVideoMask | XvStillMask;
- adaptPtr[i]->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
adaptPtr[i]->name = XVPORTNAME[i];
adaptPtr[i]->nEncodings = 8;
adaptPtr[i]->pEncodings = DummyEncoding;
@@ -484,10 +446,6 @@ viaSetupImageVideoG(ScreenPtr pScreen)
adaptPtr[i]->nPorts = 1;
adaptPtr[i]->pPortPrivates = pdevUnion[i];
adaptPtr[i]->pPortPrivates->ptr = (pointer) gviaPortPriv[i];
-/*
- adaptPtr[i]->pPortPrivates = (DevUnion*)(&pPriv[1]);
- adaptPtr[i]->pPortPrivates[0].ptr = (pointer)pPriv;
-*/
if (i == 3) /* Utility port doesn't need attribute */
{
adaptPtr[i]->nAttributes = 0;
@@ -506,7 +464,6 @@ viaSetupImageVideoG(ScreenPtr pScreen)
adaptPtr[i]->GetPortAttribute = viaGetPortAttributeG;
adaptPtr[i]->QueryBestSize = viaQueryBestSizeG;
adaptPtr[i]->PutImage = viaPutImageG;
-/* adaptPtr[i]->ReputImage= viaReputImageG; */
adaptPtr[i]->QueryImageAttributes = viaQueryImageAttributesG;
#ifdef COLOR_KEY
@@ -519,14 +476,14 @@ viaSetupImageVideoG(ScreenPtr pScreen)
gviaPortPriv[i]->xv_portnum = i;
/* gotta uninit this someplace */
+#ifdef XFREE86_44
REGION_NULL(pScreen, &gviaPortPriv[i]->clip);
+#else
+ REGION_INIT(pScreen, &gviaPortPriv[i]->clip, NullBox, 1);
+#endif
} /* End of for */
-
-
viaResetVideo(pScrn);
-
return adaptPtr[0];
-
}
@@ -560,13 +517,14 @@ RegionsEqual(RegionPtr A, RegionPtr B)
}
-static unsigned long CreateSWOVSurface(ScrnInfoPtr pScrn, viaPortPrivPtr pPriv, int fourcc, short width, short height)
+static int CreateSWOVSurface(ScrnInfoPtr pScrn, viaPortPrivPtr pPriv, int fourcc, short width, short height)
{
VIAPtr pVia = VIAPTR(pScrn);
LPDDSURFACEDESC lpSurfaceDesc = &pPriv->SurfaceDesc;
+ unsigned long retCode;
if (pVia->Video.VideoStatus & SWOV_SURFACE_CREATED)
- return TRUE;
+ return Success;
lpSurfaceDesc->dwWidth = (unsigned long)width;
lpSurfaceDesc->dwHeight = (unsigned long)height;
@@ -574,7 +532,8 @@ static unsigned long CreateSWOVSurface(ScrnInfoPtr pScrn, viaPortPrivPtr pPriv,
lpSurfaceDesc->dwFourCC = (unsigned long)fourcc;
- VIAVidCreateSurface(pScrn, lpSurfaceDesc);
+ if (Success != (retCode = VIAVidCreateSurface(pScrn, lpSurfaceDesc)))
+ return retCode;
pPriv->ddLock.dwFourCC = (unsigned long)fourcc;
@@ -588,7 +547,7 @@ static unsigned long CreateSWOVSurface(ScrnInfoPtr pScrn, viaPortPrivPtr pPriv,
pVia->Video.VideoStatus |= SWOV_SURFACE_CREATED|SW_VIDEO_ON;
pVia->Video.dwAction = ACTION_SET_VIDEOSTATUS;
- return TRUE;
+ return Success;
}
@@ -665,7 +624,7 @@ viaStopVideoG(ScrnInfoPtr pScrn, pointer data, Bool exit)
* Inputs: CARD16 channel - the tuner channel to be set. *
* Outputs: NONE *
****************************************************************************/
-static void SetTunerChannel (viaPortPrivPtr pChanPriv, INT32 frequency)
+static void SetTunerChannel (ViaTunerPtr pTuner, viaPortPrivPtr pChanPriv, INT32 frequency)
{
int control;
short divider = 0;
@@ -675,36 +634,30 @@ static void SetTunerChannel (viaPortPrivPtr pChanPriv, INT32 frequency)
case PAL_60_COMPOSITE :
case PAL_60_TUNER :
case PAL_60_SVIDEO :
- divider=633+(short)frequency;
+ divider = 633 + (short)frequency;
break;
case NTSC_COMPOSITE :
case NTSC_TUNER :
case NTSC_SVIDEO :
- divider=733+(short)frequency;
+ divider = 733 + (short)frequency;
break;
default:
- divider=frequency;
+ divider = frequency;
}
control = 0x8E00;
if ( divider <= LOW_BAND )
- {
- control |= 0xA0;
- }
- else{
- if ( divider <= MID_BAND )
- control |= 0x90;
- else
- control |= 0x30;
- }
-
-
+ control |= 0xA0;
+ else if ( divider <= MID_BAND )
+ control |= 0x90;
+ else
+ control |= 0x30;
- DBG_DD(ErrorF(" via_video.c : SetTunerChannel : Divider = 0x%08x, Control= 0x%08x, \n",
- divider,control));
+ DBG_DD(ErrorF(" via_video.c : SetTunerChannel : Divider = 0x%08x, Control= 0x%08x, \n", divider,control));
- /* Tuner chip interfacing goes here */
+ if(pTuner)
+ ViaTunerChannel(pTuner, divider, control);
} /* SetTunerChannel ()... */
@@ -736,7 +689,13 @@ viaSetPortAttributeG(
vmmtr viaVidEng = (vmmtr) pVia->VidMapBase;
viaPortPrivPtr pPriv = (viaPortPrivPtr)data;
int attr, avalue;
-
+ ViaTunerPtr pTuner = NULL;
+
+ if(pPriv->xv_portnum == COMMAND_FOR_TV0)
+ pTuner = pVia->Tuner[0];
+ else if(pPriv->xv_portnum == COMMAND_FOR_TV1)
+ pTuner = pVia->Tuner[1];
+ ;
DBG_DD(ErrorF(" via_video.c : viaSetPortAttributeG : \n"));
pVia->OverlaySupported = DecideOverlaySupport(pVia);
@@ -763,53 +722,53 @@ viaSetPortAttributeG(
{
DBG_DD(ErrorF(" xvBrightness = %08d\n",value));
pPriv->pict.brightness = xv_to_v4l(value);
+ if(pTuner)
+ ViaTunerBrightness(pTuner, value);
}
if (attribute == xvContrast)
{
DBG_DD(ErrorF(" xvContrast = %08d\n",value));
pPriv->pict.contrast = xv_to_v4l(value);
+ if(pTuner)
+ ViaTunerContrast(pTuner, value);
}
if (attribute == xvSaturation)
{
DBG_DD(ErrorF(" xvSaturation = %08d\n",value));
pPriv->pict.colour = xv_to_v4l(value);
+ if(pTuner)
+ ViaTunerSaturation(pTuner, value);
}
if (attribute == xvHue)
{
DBG_DD(ErrorF(" xvHue = %08d\n",value));
pPriv->pict.hue = xv_to_v4l(value);
+ if(pTuner)
+ ViaTunerHue(pTuner, value);
}
/* Audio control */
} else if (attribute == xvMute){
DBG_DD(ErrorF(" via_video.c : viaSetPortAttributeG : xvMute = %08d\n",value));
- if ( value )
- {
- pPriv->AudioMode = ATTR_MUTE_ON;
- attr = ATTR_MUTE_ON;
- }
- else{
- pPriv->AudioMode = ATTR_MUTE_OFF;
- attr = ATTR_STEREO;
- }
-
+ if(value)
+ value = 1;
+ ViaAudioMute(pVia, value);
} else if (attribute == xvVolume){
DBG_DD(ErrorF(" via_video.c : viaSetPortAttributeG : xvVolume = %08d\n",value));
pPriv->Volume = value;
attr = ATTR_VOLUME;
avalue = value;
-
+ /* FIXME */
/* Tuner control. Channel switch */
} else if (attribute == xvFreq){
DBG_DD(ErrorF(" via_video.c : viaSetPortAttributeG : xvFreq = %08x\n",value));
- SetTunerChannel(pPriv, value );
-
+ SetTunerChannel(pTuner, pPriv, value );
/* Video decoder control. NTSC/PAL, SVIDEO/COMPOSITIVE/TV */
} else if (attribute == xvEncoding){
DBG_DD(ErrorF(" xvEncoding = %d. \n",value));
-
pPriv->dwEncoding = value;
-
+ if(pTuner)
+ ViaTunerStandard(pTuner, value);
/* VIA Proprietary Attribute for Video control */
} else if (attribute == xvPort ){
DBG_DD(ErrorF(" via_video.c : viaSetPortAttributeG : xvPort=%d\n", value));
@@ -829,9 +788,14 @@ viaSetPortAttributeG(
/* VIA Proprietary Attribute for AUDIO control */
} else if (attribute == xvAudioCtrl ){
DBG_DD(ErrorF(" via_video.c : viaSetPortAttributeG : xvAudioSwitch=%d\n", value));
-
- attr = ATTR_AUDIO_CONTROLByAP;
- avalue = value;
+ if(pTuner)
+ {
+ ViaAudioMode(pVia, value);
+ if(pPriv->xv_portnum == COMMAND_FOR_TV0)
+ ViaAudioSelect(pVia,0);
+ else
+ ViaAudioSelect(pVia, 1);
+ }
}else{
DBG_DD(ErrorF(" via_video.c : viaSetPortAttributeG : is not supported the attribute"));
return BadMatch;
@@ -946,17 +910,21 @@ static void CopyDataYUV422(
int h,
int w )
{
- int count;
+ int count;
/* copy YUY2 data to video memory,
* do 32 bits alignment.
*/
- count = h;
- while(count--) {
- memcpy(dst, src, w);
- src += srcPitch;
- dst += dstPitch;
- }
+
+ w <<= 1; /* Each pixel is YU or YV - 16 bits */
+ srcPitch <<= 1;
+
+ count = h;
+ while(count--) {
+ memcpy(dst, src, w);
+ src += srcPitch;
+ dst += dstPitch;
+ }
}
@@ -975,38 +943,37 @@ CopyDataYUV420(
int h,
int w
){
- int count;
+ int count;
/* copy Y component to video memory */
- count = h;
- while(count--) {
- memcpy(dst1, src1, w);
- src1 += srcPitch;
- dst1 += dstPitch;
- }
+ count = h;
+ while(count--) {
+ memcpy(dst1, src1, w);
+ src1 += srcPitch;
+ dst1 += dstPitch;
+ }
/* UV component is 1/4 of Y */
- w >>= 1;
- h >>= 1;
- srcPitch >>= 1;
- dstPitch >>= 1;
+ w >>= 1;
+ h >>= 1;
+ srcPitch >>= 1;
+ dstPitch >>= 1;
/* copy V(Cr) component to video memory */
- count = h;
- while(count--) {
- memcpy(dst2, src2, w);
- src2 += srcPitch;
- dst2 += dstPitch;
- }
+ count = h;
+ while(count--) {
+ memcpy(dst2, src2, w);
+ src2 += srcPitch;
+ dst2 += dstPitch;
+ }
/* copy U(Cb) component to video memory */
- count = h;
- while(count--) {
- memcpy(dst3, src3, w);
- src3 += srcPitch;
- dst3 += dstPitch;
- }
-
+ count = h;
+ while(count--) {
+ memcpy(dst3, src3, w);
+ src3 += srcPitch;
+ dst3 += dstPitch;
+ }
}
@@ -1025,6 +992,7 @@ viaPutImageG(
VIAPtr pVia = VIAPTR(pScrn);
viaPortPrivPtr pPriv = (viaPortPrivPtr)data;
vmmtr viaVidEng = (vmmtr) pVia->VidMapBase;
+ unsigned long retCode;
/* int i;
BoxPtr pbox; */
@@ -1061,9 +1029,10 @@ viaPutImageG(
if ( (pPriv->old_src_w != src_w) || (pPriv->old_src_h != src_h) )
DestroySWOVSurface(pScrn, pPriv);
- if ( !CreateSWOVSurface(pScrn, pPriv, id, width, height) )
+ if (Success != ( retCode = CreateSWOVSurface(pScrn, pPriv, id, width, height) ))
{
DBG_DD(ErrorF(" : Fail to Create SW Video Surface\n"));
+ return retCode;
}
@@ -1108,12 +1077,7 @@ viaPutImageG(
lpUpdateOverlay->rSrc.right = src_x + width;
lpUpdateOverlay->rSrc.bottom = src_y + height;
- /* temp solve LinDVD AP bug */
- /* When y<0, lindvd will send wrong x */
- if (drw_y<0)
- lpUpdateOverlay->rDest.left = drw_x/2;
- else
- lpUpdateOverlay->rDest.left = drw_x;
+ lpUpdateOverlay->rDest.left = drw_x;
lpUpdateOverlay->rDest.top = drw_y;
lpUpdateOverlay->rDest.right = lpUpdateOverlay->rDest.left + drw_w;
lpUpdateOverlay->rDest.bottom = drw_y + drw_h;
@@ -1169,18 +1133,6 @@ viaPutImageG(
REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
-#if 0
- /* draw these */
- /* FillSolidRects function cause segment fail in SAMM mode
- * So I change to use SetupForSolidFill
- * Changed to XAAFillSolidRects by Alan
- */
-
- XAAFillSolidRects(pScrn, pPriv->colorKey, GXcopy,
- (CARD32)~0,
- REGION_NUM_RECTS(clipBoxes),
- REGION_RECTS(clipBoxes));
-#endif
}
/*