[xorg-x11-drv-openchrome] 0.2.904 + svn916 : VX900 support

Xavier Bachelot xavierb at fedoraproject.org
Thu Mar 3 21:12:11 UTC 2011


commit 7f50867308665dcb137ffc7cf5d36e1f4e9a2711
Author: Xavier Bachelot <xavier at bachelot.org>
Date:   Thu Mar 3 22:11:54 2011 +0100

    0.2.904 + svn916 : VX900 support

 openchrome-0.2.904-latest_trunk.patch | 2710 --------------------
 openchrome-0.2.904-svn916.patch       | 4365 +++++++++++++++++++++++++++++++++
 2 files changed, 4365 insertions(+), 2710 deletions(-)
---
diff --git a/openchrome-0.2.904-svn916.patch b/openchrome-0.2.904-svn916.patch
new file mode 100644
index 0000000..83c6bb8
--- /dev/null
+++ b/openchrome-0.2.904-svn916.patch
@@ -0,0 +1,4365 @@
+Index: ChangeLog
+===================================================================
+--- ChangeLog	(.../tags/release_0_2_904)	(revision 916)
++++ ChangeLog	(.../trunk)	(revision 916)
+@@ -1,3 +1,219 @@
++2011-01-23  Bartosz Kosiorek  <gang65 at poczta.onet.pl>
++
++	Enable hardware cursor for VX900
++
++	* src/via_cursor.c: (viaHWCursorInit):
++	* src/via_mode.c: (ViaModeSet):
++
++2010-12-16  Bartosz Kosiorek  <gang65 at poczta.onet.pl>
++
++	Merge vx900_branch - initial VX900 support
++
++	* src/via_accel.c: (viaFlushPCI), (viaDisableVQ),
++	(viaInitialize2DEngine), (viaAccelSync), (viaPitchHelper),
++	(viaInitXAA):
++	* src/via_bandwidth.c: (ViaSetPrimaryFIFO), (ViaSetSecondaryFIFO):
++	* src/via_bios.h:
++	* src/via_crtc.c: (ViaFirstCRTCSetMode), (ViaSecondCRTCSetMode):
++	* src/via_cursor.c: (viaHWCursorInit), (viaCursorStore),
++	(viaCursorRestore), (viaShowCursor), (viaHideCursor),
++	(viaSetCursorPosition), (viaLoadCursorImage), (viaSetCursorColors):
++	* src/via_driver.c: (VIASetupDefaultOptions), (VIAPreInit),
++	(VIALeaveVT), (VIASave), (VIARestore), (ViaMMIOEnable),
++	(ViaMMIODisable), (VIAMapFB), (VIAWriteMode), (VIACloseScreen):
++	* src/via_driver.h:
++	* src/via_id.c:
++	* src/via_id.h:
++	* src/via_mode.c: (ViaDFPDetect), (ViaOutputsDetect),
++	(ViaOutputsSelect), (ViaGetMemoryBandwidth), (ViaSetDotclock),
++	(ViaModeSet):
++	* src/via_mode.h:
++	* src/via_panel.c: (ViaPanelScaleDisable), (ViaPanelPreInit),
++	(ViaPanelGetSizeFromDDC):
++	* src/via_video.c: (DecideOverlaySupport):
++	* src/via_xvmc.c: (ViaInitXVMC):
++
++2010-12-15  Bartosz Kosiorek  <gang65 at poczta.onet.pl>
++
++	Enable the new mode switch and panel support on K8M800 and VM800 chipsets
++
++	* src/via_driver.c: (VIASetupDefaultOptions), (VIAPreInit):
++	* src/via_mode.c: (ViaModeSet):
++
++2010-11-10  Bartosz Kosiorek  <gang65 at poczta.onet.pl>
++
++    Replace the deprecated functions 
++    xalloc/xrealloc/xfree/xcalloc with 
++    malloc/realloc/free/calloc.
++    Refer to "/xserver/include/os.h"
++
++	* src/via_accel.c: (viaSetupCBuffer), (viaTearDownCBuffer),
++	(viaInitExa), (viaExitAccel), (viaFinishInitAccel):
++	* src/via_dga.c: (VIASetupDGAMode):
++	* src/via_dri.c: (VIAInitVisualConfigs), (VIADRIScreenInit),
++	(VIADRICloseScreen):
++	* src/via_driver.c: (VIAFreeRec), (VIAProbe), (VIAPreInit),
++	(VIACloseScreen):
++	* src/via_memcpy.c: (viaVidCopyInit):
++	* src/via_swov.c: (Upd_Video):
++	* src/via_vbe.c: (ViaVbeSetMode):
++	* src/via_video.c: (viaExitVideo), (viaStopVideo),
++	(viaDmaBlitImage):
++	* src/via_xvmc.c: (cleanupViaXvMC), (ViaCleanupXVMC),
++	(ViaXvMCCreateContext), (ViaXvMCCreateSurface),
++	(ViaXvMCCreateSubpicture), (ViaXvMCDestroyContext),
++	(ViaXvMCDestroySurface), (ViaXvMCDestroySubpicture),
++	(viaXvMCInitXv):
++
++2010-10-24  Bartosz Kosiorek  <gang65 at poczta.onet.pl>
++
++	Siragon ML-6200 laptop support
++
++	* src/via_id.c:
++
++2010-06-24  Jon Nettleton  <jon.nettleton at gmail.com>
++
++	PM800 also uses the CME Engine.  Setup the hqv_cme_regs
++	for it.
++
++	* src/via_swov.c: (VIAVidHWDiffInit):
++
++2010-06-09  Bartosz Kosiorek  <gang65 at poczta.onet.pl>
++
++	Fix freeze on 64bit system for K8M800 chipset
++
++	* src/via_dri.c: (VIADRIAgpInit):
++
++2010-05-04  Jon Nettleton <jon.nettleton at gmail.com>
++
++	Re-enable the Virtual Queue for the VX800/VX855 chipsets.
++
++	* src/via_accel.c: (viaDisableVQ), (viaInitialize2DEngine):
++
++2010-05-04  Jon Nettleton  <jon.nettleton at gmail.com>
++
++	Disable certain hardware clipping options for the VX855.
++	These cause the 2d engine to become unstable when in
++	16-bit mode.
++
++	* src/via_accel.c: (viaInitXAA):
++
++2010-05-04  Jon Nettleton <jon.nettleton at gmail.com>
++
++	Add an undocumented option which allows certain I2C buses
++	to be probed at startup.  This allows workarounds for custom
++	chipset makers that have used the VX855 I2C buses for other
++	purposes.
++
++	* src/via_bios.h:
++	* src/via_driver.c: (VIASetupDefaultOptions), (VIAPreInit):
++	* src/via_driver.h:
++	* src/via_i2c.c:
++
++2010-05-04  Jon Nettleton  <jon.nettleton at gmail.com>
++
++	Improve 2d performance on chipsets that don't have
++	AGP/PCIe support yet.
++
++	* src/via_accel.c: (viaSetupForScreenToScreenCopy),
++	(viaSetupForSolidFill), (viaSetupForMono8x8PatternFill),
++	(viaSetupForColor8x8PatternFill),
++	(viaSetupForCPUToScreenColorExpandFill),
++	(viaSubsequentScanlineCPUToScreenColorExpandFill),
++	(viaSetupForImageWrite), (viaSubsequentImageWriteRect),
++	(viaSetupForSolidLine), (viaSetupForDashedLine), (viaInitXAA):
++
++2010-05-04  Jon Nettleton <jon.nettleton at gmail.com>
++
++	Put timeouts on our while statements.  These codepaths
++	should be interrupted by a hardware state change, but
++	if something goes wrong they loop forevere.  Let's try
++	and behave a little by putting a timeout on these loops.
++
++	* src/via_swov.c: (viaWaitHQVFlip), (viaWaitHQVFlipClear),
++	(viaWaitHQVDone):
++	* src/via_video.c: (Flip):
++
++2010-05-04  Jon Nettleton <jon.nettleton at gmail.com>
++
++	Add XVideo support for the VX855 Chipset.
++	To support this chipset I have added HWDiff->HQVCmeRegs
++	that allows handling differing register values, and
++	HWDiff->dwNewScaleCtl which allows selection of a
++	new Video scaling engine needed for the VX800/VX855
++	chipsets.
++
++	* src/via.h:
++	* src/via_bandwidth.c: (ViaSetSecondaryFIFO):
++	* src/via_driver.h:
++	* src/via_swov.c: (SaveVideoRegister), (VIAVidHWDiffInit),
++	(viaOverlayHQVCalcZoomWidth), (viaOverlayHQVCalcZoomHeight),
++	(ViaSwovSurfaceCreate), (SetHQVFetch), (Upd_Video):
++	* src/via_swov.h:
++
++2010-04-21  Bartosz Kosiorek  <gang65 at poczta.onet.pl>
++
++	Replace RegionsEqual with REGION_EQUAL and use 
++        the xf86XVFillKeyHelperDrawable instead of xf86XVFillKeyHelper
++
++	* src/via_video.c: (viaReputImage), (viaPutImage):
++
++2010-03-07  Bartosz Kosiorek  <gang65 at poczta.onet.pl>
++
++	Fix segfaults with EXA and XV (Ticket #359)
++        Tested on K8M890 and VN800
++
++	* src/via_video.c: (viaReputImage), (viaPutImage):
++
++2010-02-10  Bartosz Kosiorek  <gang65 at poczta.onet.pl>
++
++	Fix bug with suspend and VT switch on VX800 and 64bit systems
++
++	* src/via_driver.h:
++	* src/via_video.c: (viaResetVideo), (viaSaveVideo),
++	(viaRestoreVideo), (viaExitVideo):
++	* src/via_video.h:
++
++2010-01-24  Bartosz Kosiorek  <gang65 at poczta.onet.pl>
++
++	Fix starting address restore and save (initial 64-bit support)
++
++	* src/via_crtc.c: (ViaFirstCRTCSetMode),
++	(ViaFirstCRTCSetStartingAddress):
++	* src/via_dri.c: (VIADRIAgpInit):
++	* src/via_driver.c: (VIASave), (VIARestore):
++	* src/via_driver.h:
++
++2009-12-04  Bartosz Kosiorek  <gang65 at poczta.onet.pl>
++
++	Enable new mode switch for VM800 chipsets
++
++	* src/via_driver.c: (VIASetupDefaultOptions):
++
++2009-11-21  Bartosz Kosiorek  <gang65 at poczta.onet.pl>
++
++	Add option to enable unaccelerated RandR rotation ("SWRandR").
++        The accelerated option "HWRandR" is currently not implemented.
++
++	* man/openchrome.man:
++	* src/via_driver.c: (VIAPreInit):
++
++2009-11-20  Bartosz Kosiorek  <gang65 at poczta.onet.pl>
++
++	Enabled new mode switch for PM800 chipset, 
++        to resolve many bugs with resolution detecting and changing
++        (eg. switching to console)
++
++	* src/via_driver.c: (VIASetupDefaultOptions), (VIAPreInit):
++
++2009-11-07  Bartosz Kosiorek  <gang65 at poczta.onet.pl>
++
++	Add more comments to ViaSetSecondaryFIFO, add panel scale support for 
++ 	CLE266 and KM400, fix bug with malloc.
++
++	* src/via_bandwidth.c: (ViaSetSecondaryFIFO):
++	* src/via_panel.c: (ViaPanelScale), (ViaPanelGetNativeDisplayMode):
++
+ 2009-09-26  Bartosz Kosiorek  <gang65 at poczta.onet.pl>
+ 
+ 	Save/restore ECK Clock Synthesizer
+Index: src/via_panel.c
+===================================================================
+--- src/via_panel.c	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_panel.c	(.../trunk)	(revision 916)
+@@ -45,17 +45,17 @@ static ViaPanelModeRec ViaPanelNativeModes[] = {
+     {1280, 768},
+     {1280, 1024},
+     {1400, 1050},
+-    {1600, 1200},   /* 0x6 Resolution 1440x900 */
++    {1440, 900},    /* 0x6 Resolution 1440x900 */
+     {1280, 800},    /* 0x7 Resolution 1280x800 (Samsung NC20) */
+     {800, 480},     /* 0x8 For Quanta 800x480 */
+     {1024, 600},    /* 0x9 Resolution 1024x600 (for HP 2133) */
+     {1366, 768},    /* 0xA Resolution 1366x768 */
+-    {1920, 1080},
+-    {1920, 1200},
+-    {1280, 1024},   /* 0xD Need to be fixed to 1920x1200 */
+-    {1440, 900},    /* 0xE Need to be fixed to 640x240 */
+-    {1280, 720},    /* 0xF 480x640 */
+-    {1200, 900},   /* 0x10 For Panasonic 1280x768 18bit Dual-Channel Panel */
++    {1600, 1200},   /* 0xB Resolution 1600x1200 */
++    {1680, 1050},
++    {1920, 1200},   /* 0xD Resolution 1920x1200 */
++    {640, 240},     /* 0xE Resolution 640x240 */
++    {480, 640},     /* 0xF Resolution 480x640 */
++    {1280, 768},   /* 0x10 For Panasonic 1280x768 18bit Dual-Channel Panel */
+     {1360, 768},   /* 0x11 Resolution 1360X768 */
+     {1024, 768},   /* 0x12 Resolution 1024x768 */
+     {800, 480}     /* 0x13 General 8x4 panel use this setting */
+@@ -147,6 +147,9 @@ ViaPanelScaleDisable(ScrnInfoPtr pScrn)
+     vgaHWPtr hwp = VGAHWPTR(pScrn);
+ 
+     ViaCrtcMask(hwp, 0x79, 0x00, 0x01);
++    /* Disable VX900 down scaling */
++    if (pVia->Chipset == VIA_VX900)
++        ViaCrtcMask(hwp, 0x89, 0x00, 0x01);
+     if (pVia->Chipset != VIA_CLE266 && pVia->Chipset != VIA_KM400)
+         ViaCrtcMask(hwp, 0xA2, 0x00, 0xC8);
+ }
+@@ -171,12 +174,18 @@ ViaPanelScale(ScrnInfoPtr pScrn, int resWidth, int
+                      resWidth, resHeight, panelWidth, panelHeight));
+ 
+     if (resWidth < panelWidth) {
+-        /* FIXME: It is different for chipset < K8M800 */
+-        horScalingFactor = ((resWidth - 1) * 4096) / (panelWidth - 1);
++        /* Load Horizontal Scaling Factor */
++        if (pVia->Chipset != VIA_CLE266 && pVia->Chipset != VIA_KM400) {
++            horScalingFactor = ((resWidth - 1) * 4096) / (panelWidth - 1);
++            
++            /* Horizontal scaling enabled */
++            cra2 = 0xC0;
++            cr9f = horScalingFactor & 0x0003;          /* HSCaleFactor[1:0] at CR9F[1:0] */
++	} else {
++            /* TODO: Need testing */
++            horScalingFactor = ((resWidth - 1) * 1024) / (panelWidth - 1);
++        }
+ 
+-        /* Horizontal scaling enabled */
+-        cra2 = 0xC0;
+-        cr9f = horScalingFactor & 0x0003;          /* HSCaleFactor[1:0] at CR9F[1:0] */
+         cr77 = (horScalingFactor & 0x03FC) >> 2;   /* HSCaleFactor[9:2] at CR77[7:0] */
+         cr79 = (horScalingFactor & 0x0C00) >> 10;  /* HSCaleFactor[11:10] at CR79[5:4] */
+         cr79 <<= 4;
+@@ -184,11 +193,18 @@ ViaPanelScale(ScrnInfoPtr pScrn, int resWidth, int
+     }
+ 
+     if (resHeight < panelHeight) {
+-        verScalingFactor = ((resHeight - 1) * 2048) / (panelHeight - 1);
++        /* Load Vertical Scaling Factor */
++        if (pVia->Chipset != VIA_CLE266 && pVia->Chipset != VIA_KM400) {
++            verScalingFactor = ((resHeight - 1) * 2048) / (panelHeight - 1);
+ 
+-        /* Vertical scaling enabled */
+-        cra2 |= 0x08;
+-        cr79 |= ((verScalingFactor & 0x0001) << 3);       /* VSCaleFactor[0] at CR79[3] */
++            /* Vertical scaling enabled */
++            cra2 |= 0x08;
++            cr79 |= ((verScalingFactor & 0x0001) << 3);       /* VSCaleFactor[0] at CR79[3] */
++        } else {
++            /* TODO: Need testing */
++            verScalingFactor = ((resHeight - 1) * 1024) / (panelHeight - 1);
++        }
++
+         cr78 |= (verScalingFactor & 0x01FE) >> 1;         /* VSCaleFactor[8:1] at CR78[7:0] */
+         cr79 |= ((verScalingFactor & 0x0600) >> 9) << 6;  /* VSCaleFactor[10:9] at CR79[7:6] */
+         scaling = TRUE;
+@@ -203,13 +219,19 @@ ViaPanelScale(ScrnInfoPtr pScrn, int resWidth, int
+         ViaCrtcMask(hwp, 0x77, cr77, 0xFF);
+         ViaCrtcMask(hwp, 0x78, cr78, 0xFF);
+         ViaCrtcMask(hwp, 0x79, cr79, 0xF8);
+-        ViaCrtcMask(hwp, 0x9F, cr9f, 0x03);
++        if (pVia->Chipset != VIA_CLE266 && pVia->Chipset != VIA_KM400) {
++            ViaCrtcMask(hwp, 0x9F, cr9f, 0x03);
++        }
+         ViaCrtcMask(hwp, 0x79, 0x03, 0x03);
+-    } else
++    } else {
++        /*  Disable panel scale */
+         ViaCrtcMask(hwp, 0x79, 0x00, 0x01);
++    }
++    
++    if (pVia->Chipset != VIA_CLE266 && pVia->Chipset != VIA_KM400) {
++        ViaCrtcMask(hwp, 0xA2, cra2, 0xC8);
++    }
+ 
+-    ViaCrtcMask(hwp, 0xA2, cra2, 0xC8);
+-
+     /* Horizontal scaling selection: interpolation */
+     // ViaCrtcMask(hwp, 0x79, 0x02, 0x02);
+     // else
+@@ -233,14 +255,14 @@ ViaPanelGetNativeDisplayMode(ScrnInfoPtr pScrn)
+ 
+     if (panelMode->Width && panelMode->Height) {
+ 
+-        /* TODO: fix refresh rate and check malloc */
++        /* TODO: fix refresh rate */
+         DisplayModePtr p = malloc( sizeof(DisplayModeRec) ) ;
+-        memset(p, 0, sizeof(DisplayModeRec));
++        if (p) {
++            memset(p, 0, sizeof(DisplayModeRec));
+ 
+-        float refresh = 60.0f ;
++            float refresh = 60.0f ;
+ 
+-        /* The following code is borrowed from xf86SetModeCrtc. */
+-        if (p) {
++            /* The following code is borrowed from xf86SetModeCrtc. */
+             viaTimingCvt(p, panelMode->Width, panelMode->Height, refresh, FALSE, TRUE);
+             p->CrtcHDisplay = p->HDisplay;
+             p->CrtcHSyncStart = p->HSyncStart;
+@@ -256,9 +278,13 @@ ViaPanelGetNativeDisplayMode(ScrnInfoPtr pScrn)
+             p->CrtcVBlankEnd = max(p->CrtcVSyncEnd, p->CrtcVTotal);
+             p->CrtcHBlankStart = min(p->CrtcHSyncStart, p->CrtcHDisplay);
+             p->CrtcHBlankEnd = max(p->CrtcHSyncEnd, p->CrtcHTotal);
+-
++            
++            pVia->pBIOSInfo->Panel->NativeDisplayMode = p;
++        } else {
++            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
++                     "Out of memory. Size: %d bytes\n", sizeof(DisplayModeRec));
+         }
+-        pVia->pBIOSInfo->Panel->NativeDisplayMode = p;
++        
+     } else {
+         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                    "Invalid panel dimension (%dx%d)\n", panelMode->Width,
+@@ -282,10 +308,7 @@ ViaPanelPreInit(ScrnInfoPtr pScrn)
+         Bool ret;
+ 
+         ret = ViaPanelGetSizeFromDDCv1(pScrn, &width, &height);
+-/*
+-        if (!ret)
+-            ret = ViaPanelGetSizeFromDDCv2(pScrn, &width);
+-*/
++
+         if (ret) {
+             panel->NativeModeIndex = ViaPanelLookUpModeIndex(width, height);
+             DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaPanelLookUpModeIndex, Width %d, Height %d, NativeModeIndex%d\n", width, height, panel->NativeModeIndex));
+@@ -333,28 +356,28 @@ ViaPanelCenterMode(DisplayModePtr centerMode, Disp
+ 
+ 
+ /*
+- * Try to interprete EDID ourselves.
++ * Try to interpret EDID ourselves.
+  */
+ Bool
+ ViaPanelGetSizeFromEDID(ScrnInfoPtr pScrn, xf86MonPtr pMon,
+                         int *width, int *height)
+ {
+-    int i, max = 0, vsize;
++    int i, max_hsize = 0, vsize = 0;
+ 
+     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAGetPanelSizeFromEDID\n"));
+ 
+     /* !!! Why are we not checking VESA modes? */
+ 
+     /* checking standard timings */
+-    for (i = 0; i < 8; i++)
++    for (i = 0; i < STD_TIMINGS; i++)
+         if ((pMon->timings2[i].hsize > 256)
+-            && (pMon->timings2[i].hsize > max)) {
+-            max = pMon->timings2[i].hsize;
++            && (pMon->timings2[i].hsize > max_hsize)) {
++            max_hsize = pMon->timings2[i].hsize;
+             vsize = pMon->timings2[i].vsize;
+         }
+ 
+-    if (max != 0) {
+-        *width = max;
++    if (max_hsize != 0) {
++        *width = max_hsize;
+         *height = vsize;
+         return TRUE;
+     }
+@@ -369,14 +392,14 @@ ViaPanelGetSizeFromEDID(ScrnInfoPtr pScrn, xf86Mon
+             struct detailed_timings timing = pMon->det_mon[i].section.d_timings;
+ 
+             /* ignore v_active for now */
+-            if ((timing.clock > 15000000) && (timing.h_active > max)) {
+-                max = timing.h_active;
++            if ((timing.clock > 15000000) && (timing.h_active > max_hsize)) {
++                max_hsize = timing.h_active;
+                 vsize = timing.v_active;
+             }
+         }
+ 
+-    if (max != 0) {
+-        *width = max;
++    if (max_hsize != 0) {
++        *width = max_hsize;
+         *height = vsize;
+         return TRUE;
+     }
+@@ -386,7 +409,6 @@ ViaPanelGetSizeFromEDID(ScrnInfoPtr pScrn, xf86Mon
+ 
+ Bool
+ ViaPanelGetSizeFromDDCv1(ScrnInfoPtr pScrn, int *width, int *height)
+-
+ {
+     VIAPtr pVia = VIAPTR(pScrn);
+     xf86MonPtr pMon;
+@@ -396,7 +418,7 @@ ViaPanelGetSizeFromDDCv1(ScrnInfoPtr pScrn, int *w
+     if (!xf86I2CProbeAddress(pVia->pI2CBus2, 0xA0))
+         return FALSE;
+ 
+-    pMon = xf86DoEDID_DDC2(pScrn->scrnIndex, pVia->pI2CBus2);
++    pMon = xf86DoEEDID(pScrn->scrnIndex, pVia->pI2CBus2, TRUE);
+     if (!pMon)
+         return FALSE;
+ 
+Index: src/via_id.h
+===================================================================
+--- src/via_id.h	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_id.h	(.../trunk)	(revision 916)
+@@ -39,6 +39,7 @@ enum VIACHIPTAGS {
+     VIA_P4M890,
+     VIA_VX800,
+     VIA_VX855,
++    VIA_VX900,
+     VIA_LAST
+ };
+ 
+@@ -56,6 +57,7 @@ enum VIACHIPTAGS {
+ #define PCI_CHIP_VT3327         0x3343 /* P4M890 */
+ #define PCI_CHIP_VT3353         0x1122 /* VX800 */
+ #define PCI_CHIP_VT3409         0x5122 /* VX855/VX875 */
++#define PCI_CHIP_VT3410         0x7122 /* VX900 */
+ 
+ /* There is some conflicting information about the two major revisions of
+  * the CLE266, often labelled Ax and Cx.  The dividing line seems to be
+Index: src/via_video.c
+===================================================================
+--- src/via_video.c	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_video.c	(.../trunk)	(revision 916)
+@@ -354,6 +354,14 @@ DecideOverlaySupport(ScrnInfoPtr pScrn)
+                 mClock = 333;
+                 memEfficiency = (float)SINGLE_3205_133;
+                 break;
++            case VIA_MEM_DDR800:
++                mClock = 400;
++                memEfficiency = (float)SINGLE_3205_133;
++                break;
++            case VIA_MEM_DDR1066:
++                mClock = 533;
++                memEfficiency = (float)SINGLE_3205_133;
++                break;
+             default:
+                 /*Unknow DRAM Type */
+                 DBG_DD(ErrorF("Unknow DRAM Type!\n"));
+@@ -426,7 +434,7 @@ DecideOverlaySupport(ScrnInfoPtr pScrn)
+             DBG_DD(ErrorF(" via_video.c : totalBandwidth= %f : \n",
+                 totalBandWidth));
+             if (needBandWidth < totalBandWidth)
+-            return TRUE;
++                return TRUE;
+         }
+         return FALSE;
+     }
+@@ -466,8 +474,8 @@ viaResetVideo(ScrnInfoPtr pScrn)
+ 
+     viaVidEng->video1_ctl = 0;
+     viaVidEng->video3_ctl = 0;
+-    viaVidEng->compose = 0x80000000;
+-    viaVidEng->compose = 0x40000000;
++    viaVidEng->compose = V1_COMMAND_FIRE;
++    viaVidEng->compose = V3_COMMAND_FIRE;
+     viaVidEng->color_key = 0x821;
+     viaVidEng->snd_color_key = 0x821;
+ 
+@@ -479,16 +487,16 @@ viaSaveVideo(ScrnInfoPtr pScrn)
+     VIAPtr pVia = VIAPTR(pScrn);
+     vmmtr viaVidEng = (vmmtr) pVia->VidMapBase;
+     
++    DBG_DD(ErrorF(" via_video.c : viaSaveVideo : \n"));
+     /* Save video registers */
+-    /* TODO: Identify which registers should be saved and restored */
+     memcpy(pVia->VideoRegs, (void*)viaVidEng, sizeof(video_via_regs));
+ 
+     pVia->dwV1 = ((vmmtr) viaVidEng)->video1_ctl;
+     pVia->dwV3 = ((vmmtr) viaVidEng)->video3_ctl;
+     viaVidEng->video1_ctl = 0;
+     viaVidEng->video3_ctl = 0;
+-    viaVidEng->compose = 0x80000000;
+-    viaVidEng->compose = 0x40000000;
++    viaVidEng->compose = V1_COMMAND_FIRE;
++    viaVidEng->compose = V3_COMMAND_FIRE;
+ }
+ 
+ void
+@@ -496,16 +504,66 @@ viaRestoreVideo(ScrnInfoPtr pScrn)
+ {
+     VIAPtr pVia = VIAPTR(pScrn);
+     vmmtr viaVidEng = (vmmtr) pVia->VidMapBase;
++    video_via_regs  *localVidEng = pVia->VideoRegs;
++
+     
++    DBG_DD(ErrorF(" via_video.c : viaRestoreVideo : \n"));
+     /* Restore video registers */
+-    /* TODO: Identify which registers should be saved and restored */
+-    memcpy((void*)viaVidEng, pVia->VideoRegs, sizeof(video_via_regs));
++    /* flush restored video engines' setting to VidMapBase */
++    
++    viaVidEng->alphawin_hvstart = localVidEng->alphawin_hvstart;
++    viaVidEng->alphawin_size   = localVidEng->alphawin_size;
++    viaVidEng->alphawin_ctl    = localVidEng->alphawin_ctl;
++    viaVidEng->alphafb_stride  = localVidEng->alphafb_stride;
++    viaVidEng->color_key       = localVidEng->color_key;
++    viaVidEng->alphafb_addr    = localVidEng->alphafb_addr;
++    viaVidEng->chroma_low      = localVidEng->chroma_low;
++    viaVidEng->chroma_up       = localVidEng->chroma_up;
++    viaVidEng->interruptflag   = localVidEng->interruptflag;
+ 
++    if (pVia->ChipId != PCI_CHIP_VT3314)
++    {
++        /*VT3314 only has V3*/
++        viaVidEng->video1_ctl      = localVidEng->video1_ctl;
++        viaVidEng->video1_fetch    = localVidEng->video1_fetch;
++        viaVidEng->video1y_addr1   = localVidEng->video1y_addr1;
++        viaVidEng->video1_stride   = localVidEng->video1_stride;
++        viaVidEng->video1_hvstart  = localVidEng->video1_hvstart;
++        viaVidEng->video1_size     = localVidEng->video1_size;
++        viaVidEng->video1y_addr2   = localVidEng->video1y_addr2;
++        viaVidEng->video1_zoom     = localVidEng->video1_zoom;
++        viaVidEng->video1_mictl    = localVidEng->video1_mictl;
++        viaVidEng->video1y_addr0   = localVidEng->video1y_addr0;
++        viaVidEng->video1_fifo     = localVidEng->video1_fifo;
++        viaVidEng->video1y_addr3   = localVidEng->video1y_addr3;
++        viaVidEng->v1_source_w_h   = localVidEng->v1_source_w_h ;
++        viaVidEng->video1_CSC1     = localVidEng->video1_CSC1;
++        viaVidEng->video1_CSC2     = localVidEng->video1_CSC2;
++    }
++    viaVidEng->snd_color_key   = localVidEng->snd_color_key;
++    viaVidEng->v3alpha_prefifo = localVidEng->v3alpha_prefifo;
++    viaVidEng->v3alpha_fifo    = localVidEng->v3alpha_fifo;
++    viaVidEng->video3_CSC2     = localVidEng->video3_CSC2;
++    viaVidEng->video3_CSC2     = localVidEng->video3_CSC2;
++    viaVidEng->v3_source_width = localVidEng->v3_source_width;
++    viaVidEng->video3_ctl      = localVidEng->video3_ctl;
++    viaVidEng->video3_addr0    = localVidEng->video3_addr0;
++    viaVidEng->video3_addr1    = localVidEng->video3_addr1;
++    viaVidEng->video3_stride   = localVidEng->video3_stride;
++    viaVidEng->video3_hvstart  = localVidEng->video3_hvstart;
++    viaVidEng->video3_size     = localVidEng->video3_size;
++    viaVidEng->v3alpha_fetch   = localVidEng->v3alpha_fetch;
++    viaVidEng->video3_zoom     = localVidEng->video3_zoom;
++    viaVidEng->video3_mictl    = localVidEng->video3_mictl;
++    viaVidEng->video3_CSC1     = localVidEng->video3_CSC1;
++    viaVidEng->video3_CSC2     = localVidEng->video3_CSC2;    
++    viaVidEng->compose         = localVidEng->compose;
++    
+     viaVidEng->video1_ctl = pVia->dwV1;
+     viaVidEng->video3_ctl = pVia->dwV3;
+-    viaVidEng->compose = 0x80000000;
+-    viaVidEng->compose = 0x40000000;
+-
++    if (pVia->ChipId != PCI_CHIP_VT3314)
++        viaVidEng->compose = V1_COMMAND_FIRE;
++    viaVidEng->compose = V3_COMMAND_FIRE;
+ }
+ 
+ void
+@@ -524,8 +582,8 @@ viaExitVideo(ScrnInfoPtr pScrn)
+ 
+     viaVidEng->video1_ctl = 0;
+     viaVidEng->video3_ctl = 0;
+-    viaVidEng->compose = 0x80000000;
+-    viaVidEng->compose = 0x40000000;
++    viaVidEng->compose = V1_COMMAND_FIRE;
++    viaVidEng->compose = V3_COMMAND_FIRE;
+ 
+     /*
+      * Free all adaptor info allocated in viaInitVideo.
+@@ -542,15 +600,15 @@ viaExitVideo(ScrnInfoPtr pScrn)
+                             (viaPortPrivPtr) curAdapt->pPortPrivates->ptr + j,
+                             TRUE);
+                     }
+-                    xfree(curAdapt->pPortPrivates->ptr);
++                    free(curAdapt->pPortPrivates->ptr);
+                 }
+-                xfree(curAdapt->pPortPrivates);
++                free(curAdapt->pPortPrivates);
+             }
+-            xfree(curAdapt);
++            free(curAdapt);
+         }
+     }
+     if (allAdaptors)
+-        xfree(allAdaptors);
++        free(allAdaptors);
+ }
+ 
+ void
+@@ -561,7 +619,7 @@ viaInitVideo(ScreenPtr pScreen)
+     XF86VideoAdaptorPtr *adaptors, *newAdaptors;
+     int num_adaptors, num_new;
+ 
+-    DBG_DD(ErrorF(" via_video.c : viaInitVideo : \n"));
++    DBG_DD(ErrorF(" via_video.c : viaInitVideo, Screen[%d]\n", pScrn->scrnIndex));
+ 
+     allAdaptors = NULL;
+     newAdaptors = NULL;
+@@ -611,7 +669,7 @@ viaInitVideo(ScreenPtr pScreen)
+ 
+     DBG_DD(ErrorF(" via_video.c : num_adaptors : %d\n", num_adaptors));
+     if (newAdaptors) {
+-        allAdaptors = xalloc((num_adaptors + num_new) *
++        allAdaptors = malloc((num_adaptors + num_new) *
+                 sizeof(XF86VideoAdaptorPtr *));
+         if (allAdaptors) {
+             if (num_adaptors)
+@@ -636,134 +694,7 @@ viaInitVideo(ScreenPtr pScreen)
+     }
+ }
+ 
+-static Bool
+-RegionsEqual(RegionPtr A, RegionPtr B)
+-{
+-    int *dataA, *dataB;
+-    int num;
+ 
+-    num = REGION_NUM_RECTS(A);
+-    if (num != REGION_NUM_RECTS(B))
+-        return FALSE;
+-
+-    if ((A->extents.x1 != B->extents.x1) ||
+-        (A->extents.x2 != B->extents.x2) ||
+-        (A->extents.y1 != B->extents.y1) || (A->extents.y2 != B->extents.y2))
+-    return FALSE;
+-
+-    dataA = (int *)REGION_RECTS(A);
+-    dataB = (int *)REGION_RECTS(B);
+-
+-    while (num--) {
+-        if ((dataA[0] != dataB[0]) || (dataA[1] != dataB[1]))
+-            return FALSE;
+-        dataA += 2;
+-        dataB += 2;
+-    }
+-
+-    return TRUE;
+-}
+-
+-static void
+-viaVideoFillPixmap(ScrnInfoPtr pScrn,
+-        char *base,
+-        unsigned long pitch,
+-        int depth,
+-        int x, int y, int w, int h,
+-        unsigned long color)
+-{
+-    int i;
+-
+-    ErrorF("pitch %lu, depth %d, x %d, y %d, w %d, h %d, color 0x%08lx\n",
+-            pitch, depth, x, y, w, h, color);
+-
+-    depth = (depth + 7) >> 3;
+-
+-    base += y*pitch + x*depth;
+-
+-    switch(depth) {
+-        case 4:
+-        while(h--) {
+-            register CARD32 *p = (CARD32 *)base;
+-            for (i=0; i<w; ++i) {
+-                *p++ = color;
+-            }
+-            base += pitch;
+-        }
+-        break;
+-        case 2: {
+-            register CARD16 col = color & 0x0000FFFF;
+-            while(h--) {
+-                register CARD16 *p = (CARD16 *)base;
+-                for (i=0; i<w; ++i) {
+-                    *p++ = col;
+-                }
+-                base += pitch;
+-            }
+-            break;
+-        }
+-        case 1: {
+-            register CARD8 col = color & 0xFF;
+-            while(h--) {
+-                register CARD8 *p = (CARD8 *)base;
+-                for (i=0; i<w; ++i) {
+-                    *p++ = col;
+-                }
+-                base += pitch;
+-            }
+-            break;
+-        }
+-        default:
+-        break;
+-    }
+-}
+-    
+-
+-
+-static int
+-viaPaintColorkey(ScrnInfoPtr pScrn, viaPortPrivPtr pPriv, RegionPtr clipBoxes,
+-    DrawablePtr pDraw)
+-{
+-
+-    if (pDraw->type == DRAWABLE_WINDOW) {
+-
+-        VIAPtr pVia = VIAPTR(pScrn);
+-        PixmapPtr pPix = (pScrn->pScreen->GetWindowPixmap)((WindowPtr) pDraw);
+-        unsigned long pitch = pPix->devKind;
+-        long offset = (long) pPix->devPrivate.ptr - (long) pVia->FBBase;
+-        int x,y;
+-        BoxPtr pBox;
+-        int nBox;
+-
+-        REGION_TRANSLATE(pScrn->pScreen, clipBoxes, - pPix->screen_x,
+-            - pPix->screen_y);
+-
+-        nBox = REGION_NUM_RECTS(clipBoxes);
+-        pBox = REGION_RECTS(clipBoxes);
+-
+-        while(nBox--) {
+-            if (pVia->NoAccel || offset < 0 ||
+-                offset > pScrn->videoRam*1024) {
+-                viaVideoFillPixmap(pScrn, pPix->devPrivate.ptr, pitch,
+-                    pDraw->bitsPerPixel, pBox->x1, pBox->y1,
+-                    pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
+-                    pPriv->colorKey);
+-            } else {
+-                viaAccelFillPixmap(pScrn, offset, pitch,
+-                    pDraw->bitsPerPixel, pBox->x1, pBox->y1,
+-                    pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
+-                    pPriv->colorKey);
+-            }
+-            pBox++;
+-        }
+-
+-        DamageDamageRegion(pPix, clipBoxes);
+-    }
+-
+-    return 0;
+-}
+-
+-
+ /*
+  * This one gets called, for example, on panning.
+  */
+@@ -779,14 +710,19 @@ viaReputImage(ScrnInfoPtr pScrn,
+     viaPortPrivPtr pPriv = (viaPortPrivPtr) data;
+     VIAPtr pVia = VIAPTR(pScrn);
+ 
+-    if (!RegionsEqual(&pPriv->clip, clipBoxes)) {
++    if (!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) {
+         REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
+         if (pPriv->autoPaint) {
+             if (pDraw->type == DRAWABLE_WINDOW) {
+-                viaPaintColorkey(pScrn, pPriv, clipBoxes, pDraw);
++                /* TODO Replace xf86XVFillKeyHelper with xf86XVFillKeyHelperDrawable
++                   Currently resizing problem exist in VLC Media Player
++                   Example of implementation:
++                xf86XVFillKeyHelperDrawable(pDraw, pPriv->colorKey, clipBoxes);
++                DamageDamageRegion(pDraw, clipBoxes); */
++                
++                xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
+             } else {
+-                xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey,
+-                    clipBoxes);
++                xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
+             }
+         }
+     }
+@@ -832,7 +768,7 @@ viaSetupAdaptors(ScreenPtr pScreen, XF86VideoAdapt
+     DevUnion *pdevUnion;
+     int i, j, usedPorts, numPorts;
+ 
+-    DBG_DD(ErrorF(" via_video.c : viaSetupImageVideo: \n"));
++    DBG_DD(ErrorF(" via_video.c : viaSetupAdaptors (viaSetupImageVideo): \n"));
+ 
+     xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
+     xvContrast = MAKE_ATOM("XV_CONTRAST");
+@@ -931,7 +867,7 @@ viaStopVideo(ScrnInfoPtr pScrn, pointer data, Bool
+     if (exit) {
+         ViaSwovSurfaceDestroy(pScrn, pPriv);
+         if (pPriv->dmaBounceBuffer)
+-            xfree(pPriv->dmaBounceBuffer);
++            free(pPriv->dmaBounceBuffer);
+         pPriv->dmaBounceBuffer = 0;
+         pPriv->dmaBounceStride = 0;
+         pPriv->dmaBounceLines = 0;
+@@ -1042,6 +978,8 @@ viaGetPortAttribute(ScrnInfoPtr pScrn,
+         }
+ 
+     } else {
++        DBG_DD(ErrorF(" via_video.c : viaGetPortAttribute : is not supported the attribute\n"));
++        
+         /*return BadMatch */;
+     }
+     return Success;
+@@ -1070,6 +1008,7 @@ Flip(VIAPtr pVia, viaPortPrivPtr pPriv, int fourcc
+         unsigned long DisplayBufferIndex)
+ {
+     unsigned long proReg = 0;
++    unsigned count = 50000;
+ 
+     if (pVia->ChipId == PCI_CHIP_VT3259
+         && !(pVia->swov.gdwVideoFlagSW & VIDEO_1_INUSE))
+@@ -1081,7 +1020,8 @@ Flip(VIAPtr pVia, viaPortPrivPtr pPriv, int fourcc
+         case FOURCC_RV15:
+         case FOURCC_RV16:
+         case FOURCC_RV32:
+-            while ((VIDInD(HQV_CONTROL + proReg) & HQV_SW_FLIP));
++            while ((VIDInD(HQV_CONTROL + proReg) & HQV_SW_FLIP)
++                    && --count);
+             VIDOutD(HQV_SRC_STARTADDR_Y + proReg,
+                 pVia->swov.SWDevice.dwSWPhysicalAddr[DisplayBufferIndex]);
+             VIDOutD(HQV_CONTROL + proReg,
+@@ -1090,7 +1030,8 @@ Flip(VIAPtr pVia, viaPortPrivPtr pPriv, int fourcc
+             break;
+         case FOURCC_YV12:
+         default:
+-            while ((VIDInD(HQV_CONTROL + proReg) & HQV_SW_FLIP));
++            while ((VIDInD(HQV_CONTROL + proReg) & HQV_SW_FLIP)
++                    && --count);
+             VIDOutD(HQV_SRC_STARTADDR_Y + proReg,
+                 pVia->swov.SWDevice.dwSWPhysicalAddr[DisplayBufferIndex]);
+             if (pVia->VideoEngine == VIDEO_ENGINE_CME) {
+@@ -1174,7 +1115,7 @@ viaDmaBlitImage(VIAPtr pVia,
+             pPort->dmaBounceStride != bounceStride ||
+             pPort->dmaBounceLines != bounceLines) {
+             if (pPort->dmaBounceBuffer) {
+-                xfree(pPort->dmaBounceBuffer);
++                free(pPort->dmaBounceBuffer);
+                 pPort->dmaBounceBuffer = 0;
+             }
+             size = bounceStride * bounceLines + 16;
+@@ -1296,7 +1237,7 @@ viaPutImage(ScrnInfoPtr pScrn,
+     unsigned long retCode;
+ 
+ # ifdef XV_DEBUG
+-    ErrorF(" via_video.c : viaPutImage : called\n");
++    ErrorF(" via_video.c : viaPutImage : called,  Screen[%d]\n", pScrn->scrnIndex);
+     ErrorF(" via_video.c : FourCC=0x%x width=%d height=%d sync=%d\n", id,
+             width, height, sync);
+     ErrorF
+@@ -1405,12 +1346,11 @@ viaPutImage(ScrnInfoPtr pScrn,
+ 
+             lpUpdateOverlay->dwFlags = DDOVER_KEYDEST;
+ 
+-            if (pScrn->bitsPerPixel == 8)
+-            lpUpdateOverlay->dwColorSpaceLowValue =
+-            pPriv->colorKey & 0xff;
+-            else
+-            lpUpdateOverlay->dwColorSpaceLowValue = pPriv->colorKey;
+-
++            if (pScrn->bitsPerPixel == 8) {
++                lpUpdateOverlay->dwColorSpaceLowValue = pPriv->colorKey & 0xff;
++            } else {
++                lpUpdateOverlay->dwColorSpaceLowValue = pPriv->colorKey;
++            }
+             /* If use extend FIFO mode */
+             if (pScrn->currentMode->HDisplay > 1024) {
+                 dwUseExtendedFIFO = 1;
+@@ -1436,7 +1376,8 @@ viaPutImage(ScrnInfoPtr pScrn,
+                     && (pPriv->old_src_w == src_w) && (pPriv->old_src_h == src_h)
+                     && (pVia->old_dwUseExtendedFIFO == dwUseExtendedFIFO)
+                     && (pVia->VideoStatus & VIDEO_SWOV_ON) &&
+-                    RegionsEqual(&pPriv->clip, clipBoxes)) {
++                    REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) {
++                DBG_DD(ErrorF(" via_video.c : don't do UpdateOverlay! \n"));
+                 viaXvError(pScrn, pPriv, xve_none);
+                 return Success;
+             }
+@@ -1454,16 +1395,18 @@ viaPutImage(ScrnInfoPtr pScrn,
+             pVia->VideoStatus |= VIDEO_SWOV_ON;
+ 
+             /*  BitBlt: Draw the colorkey rectangle */
+-            if (!RegionsEqual(&pPriv->clip, clipBoxes)) {
++            if (!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) {
+                 REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
+                 if (pPriv->autoPaint) {
+                     if (pDraw->type == DRAWABLE_WINDOW) {
+-                        viaPaintColorkey(pScrn, pPriv, clipBoxes, pDraw);
++                        xf86XVFillKeyHelperDrawable(pDraw, pPriv->colorKey, clipBoxes);
++                        DamageDamageRegion(pDraw, clipBoxes);
+                     } else {
+-                        xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey,
+-                            clipBoxes);
++                        xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
+                     }
+                 }
++            } else {
++                DBG_DD(ErrorF(" via_video.c : // No need to draw Colorkey!! \n"));
+             }
+             /*
+              *  Update video overlay
+@@ -1498,6 +1441,7 @@ viaQueryImageAttributes(ScrnInfoPtr pScrn,
+ 
+     DBG_DD(ErrorF(" via_video.c : viaQueryImageAttributes : FourCC=0x%x, ",
+             id));
++    DBG_DD(ErrorF(" via_video.c : Screen[%d],  w=%d, h=%d\n", pScrn->scrnIndex, *w, *h));
+ 
+     if ((!w) || (!h))
+         return 0;
+Index: src/via_lvds.c
+===================================================================
+--- src/via_lvds.c	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_lvds.c	(.../trunk)	(revision 916)
+@@ -42,7 +42,7 @@
+             2^13 X 0.0698uSec [1/14.318MHz] = 8192 X 0.0698uSec =572.1uSec
+             Timer = Counter x 572 uSec
+         2. Note:
+-            0.0698 uSec is too small to compute for hardware. So we multify a 
++            0.0698 uSec is too small to compute for hardware. So we multiply a 
+             reference value(2^13) to make it big enough to compute for hardware.
+         3. Note:
+             The meaning of the TD0~TD3 are count of the clock. 
+Index: src/via_video.h
+===================================================================
+--- src/via_video.h	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_video.h	(.../trunk)	(revision 916)
+@@ -44,6 +44,10 @@
+ 
+ #define VIDEO_BPP 2
+ 
++
++#define V1_COMMAND_FIRE               0x80000000  /* V1 commands fire */
++#define V3_COMMAND_FIRE               0x40000000  /* V3 commands fire */
++
+ typedef struct
+ {
+     CARD32 interruptflag;	       /* 200 */
+@@ -89,7 +93,7 @@ typedef struct
+     CARD32 video3_ctl;		       /* 2a0 */
+     CARD32 video3_addr0;	       /* 2a4 */
+     CARD32 video3_addr1;	       /* 2a8 */
+-    CARD32 video3_stribe;	       /* 2ac */
++    CARD32 video3_stride;	       /* 2ac */
+     CARD32 video3_hvstart;	       /* 2b0 */
+     CARD32 video3_size;		       /* 2b4 */
+     CARD32 v3alpha_fetch;	       /* 2b8 */
+Index: src/via_mode.c
+===================================================================
+--- src/via_mode.c	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_mode.c	(.../trunk)	(revision 916)
+@@ -308,11 +308,14 @@ ViaDFPDetect(ScrnInfoPtr pScrn)
+     xf86MonPtr          monPtr = NULL;
+ 
+     if (pVia->pI2CBus2)
+-        monPtr = xf86DoEDID_DDC2(pScrn->scrnIndex, pVia->pI2CBus2);
++        monPtr = xf86DoEEDID(pScrn->scrnIndex, pVia->pI2CBus2, TRUE);
+     
+     if (monPtr) {
+         xf86PrintEDID(monPtr);
+         xf86SetDDCproperties(pScrn, monPtr);
++        DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
++                   "DDC pI2CBus2 detected a %s\n", DIGITAL(monPtr->features.input_type) ?
++                   "DFP" : "CRT"));
+         return TRUE;
+     } else {
+         return FALSE;
+@@ -380,6 +383,7 @@ ViaOutputsDetect(ScrnInfoPtr pScrn)
+         case VIA_CX700:
+         case VIA_VX800:
+         case VIA_VX855:
++        case VIA_VX900:
+             if (ViaDFPDetect(pScrn)) {
+                 pBIOSInfo->DfpPresent = TRUE;
+                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+@@ -514,6 +518,7 @@ ViaOutputsSelect(ScrnInfoPtr pScrn)
+                 case VIA_CX700:
+                 case VIA_VX800:
+                 case VIA_VX855:
++                case VIA_VX900:
+                     pVia->pBIOSInfo->Lvds->IsActive = TRUE ;
+                     break;
+             }
+@@ -859,6 +864,9 @@ ViaGetMemoryBandwidth(ScrnInfoPtr pScrn)
+         case VIA_MEM_DDR533:
+         case VIA_MEM_DDR667:
+             return VIA_BW_DDR667;
++        case VIA_MEM_DDR800:
++        case VIA_MEM_DDR1066:
++            return VIA_BW_DDR1066;
+         default:
+             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                        "ViaBandwidthAllowed: Unknown memory type: %d\n", pVia->MemClk);
+@@ -999,8 +1007,8 @@ ViaSetDotclock(ScrnInfoPtr pScrn, CARD32 clock, in
+         dn  = pll.params.dn;
+         dm  = pll.params.dm;
+ 
+-        /* The VX855 does not modify dm/dn, but earlier chipsets do. */
+-        if (pVia->Chipset != VIA_VX855) {
++        /* The VX855 and VX900 do not modify dm/dn, but earlier chipsets do. */
++        if ((pVia->Chipset != VIA_VX855) && (pVia->Chipset != VIA_VX900)) {
+             dm -= 2;
+             dn -= 2;
+         }
+@@ -1078,7 +1086,7 @@ VIASetLCDMode(ScrnInfoPtr pScrn, DisplayModePtr mo
+             pBIOSInfo->Clock = Table.InitTb.LCDClk_12Bit;
+         else {
+             pBIOSInfo->Clock = Table.InitTb.VClk_12Bit;
+-            /* for some reason still to be defined this is neccessary */
++            /* for some reason still to be defined this is necessary */
+             ViaSetSecondaryDotclock(pScrn, Table.InitTb.LCDClk_12Bit);
+         }
+     } else {
+@@ -1708,7 +1716,7 @@ ViaModeSet(ScrnInfoPtr pScrn, DisplayModePtr mode)
+         ViaModeSecondCRTC(pScrn, mode);
+         ViaSecondDisplayChannelEnable(pScrn);
+     }
+-
++    
+     if (pBIOSInfo->FirstCRTC->IsActive) {
+         if (pBIOSInfo->CrtActive) {
+             /* CRT on FirstCRTC */
+@@ -1734,6 +1742,15 @@ ViaModeSet(ScrnInfoPtr pScrn, DisplayModePtr mode)
+         ViaDisplayDisableCRT(pScrn);
+     }
+ 
++    // Enable panel support on VM800, K8M800 and VX900 chipset
++    // See: https://bugs.launchpad.net/openchrome/+bug/186103
++    if (pBIOSInfo->Panel->IsActive &&
++       ((pVia->Chipset == VIA_VM800) ||
++        (pVia->Chipset == VIA_K8M800) || 
++        (pVia->Chipset == VIA_VX900) )) {
++        pBIOSInfo->FirstCRTC->IsActive=TRUE;
++        ViaModeFirstCRTC(pScrn, mode);
++    }
+     if (pBIOSInfo->Simultaneous->IsActive) {
+         ViaDisplayEnableSimultaneous(pScrn);
+     } else {
+Index: src/via_mode.h
+===================================================================
+--- src/via_mode.h	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_mode.h	(.../trunk)	(revision 916)
+@@ -32,8 +32,9 @@
+  */
+ #define VIA_BW_MIN       74000000 /* > 640x480 at 60Hz@32bpp */
+ #define VIA_BW_DDR200   394000000
+-#define VIA_BW_DDR400   498000000 /* > 1920x1080 at 60Hz@32bpp */
++#define VIA_BW_DDR400   553000000 /* > 1920x1200 at 60Hz@32bpp */
+ #define VIA_BW_DDR667   922000000
++#define VIA_BW_DDR1066  922000000
+ 
+ union pllparams {
+     struct {
+@@ -54,50 +55,50 @@ static struct ViaDotClock {
+     CARD16 UniChrome;
+     union pllparams UniChromePro;
+ } ViaDotClocks[] = {
+-    {  25200, 0x513C, /* 0xa79004 */ { 1, 4, 6, 169 } },
+-    {  25312, 0xC763, /* 0xc49005 */ { 1, 4, 7, 198 } },
+-    {  26591, 0x471A, /* 0xce9005 */ { 1, 4, 7, 208 } },
+-    {  31500, 0xC558, /* 0xae9003 */ { 1, 4, 5, 176 } },
+-    {  31704, 0x471F, /* 0xaf9002 */ { 1, 4, 4, 177 } },
+-    {  32663, 0xC449, /* 0x479000 */ { 1, 4, 2,  73 } },
+-    {  33750, 0x4721, /* 0x959002 */ { 1, 4, 4, 151 } },
+-    {  35500, 0x5877, /* 0x759001 */ { 1, 4, 3, 119 } },
+-    {  36000, 0x5879, /* 0x9f9002 */ { 1, 4, 4, 161 } },
+-    {  39822, 0xC459, /* 0x578c02 */ { 1, 3, 4,  89 } },
+-    {  40000, 0x515F, /* 0x848c04 */ { 1, 3, 6, 134 } },
+-    {  41164, 0x4417, /* 0x2c8c00 */ { 1, 3, 2,  46 } },
+-    {  46981, 0x5069, /* 0x678c02 */ { 1, 3, 4, 105 } },
+-    {  49500, 0xC353, /* 0xa48c04 */ { 3, 3, 5, 138 } },
+-    {  50000, 0xC354, /* 0x368c00 */ { 1, 3, 2,  56 } },
+-    {  56300, 0x4F76, /* 0x3d8c00 */ { 1, 3, 2,  63 } },
+-    {  57275,      0, /* 0x3e8c00 */ { 1, 3, 5, 157 } }, /* For XO 1.5 no need for a unichrome clock */
+-    {  57284, 0x4E70, /* 0x3e8c00 */ { 1, 3, 2,  64 } },
+-    {  64995, 0x0D3B, /* 0x6b8c01 */ { 1, 3, 3, 109 } },
+-    {  65000, 0x0D3B, /* 0x6b8c01 */ { 1, 3, 3, 109 } }, /* Slightly unstable on PM800 */
+-    {  65028, 0x866D, /* 0x6b8c01 */ { 1, 3, 3, 109 } },
+-    {  74480, 0x156E, /* 0x288800 */ { 1, 2, 2,  42 } },
+-    {  75000, 0x156E, /* 0x288800 */ { 1, 2, 2,  42 } },
+-    {  78800, 0x442C, /* 0x2a8800 */ { 1, 2, 2,  44 } },
+-    {  81135, 0x0622, /* 0x428801 */ { 1, 2, 3,  68 } },
+-    {  81613, 0x4539, /* 0x708803 */ { 1, 2, 5, 114 } },
+-    {  94500, 0x4542, /* 0x4d8801 */ { 1, 2, 3,  79 } },
+-    { 108000, 0x0B53, /* 0x778802 */ { 1, 2, 4, 121 } },
+-    { 108280, 0x4879, /* 0x778802 */ { 1, 2, 4, 121 } },
+-    { 122000, 0x0D6F, /* 0x428800 */ { 1, 2, 2,  68 } },
+-    { 122726, 0x073C, /* 0x878802 */ { 1, 2, 4, 137 } },
+-    { 135000, 0x0742, /* 0x6f8801 */ { 1, 2, 3, 113 } },
+-    { 148500, 0x0853, /* 0x518800 */ { 1, 2, 2,  83 } },
+-    { 155800, 0x0857, /* 0x558402 */ { 1, 1, 4,  87 } }, 
+-    { 157500, 0x422C, /* 0x2a8400 */ { 1, 1, 2,  44 } },
+-    { 161793, 0x4571, /* 0x6f8403 */ { 1, 1, 5, 113 } }, 
+-    { 162000, 0x0A71, /* 0x6f8403 */ { 1, 1, 5, 113 } },
+-    { 175500, 0x4231, /* 0x2f8400 */ { 1, 1, 2,  49 } },
+-    { 189000, 0x0542, /* 0x4d8401 */ { 1, 1, 3,  79 } },
+-    { 202500, 0x0763, /* 0x6F8402 */ { 1, 1, 4, 113 } },
+-    { 204800, 0x0764, /* 0x548401 */ { 1, 1, 3,  86 } },
+-    { 218300, 0x043D, /* 0x3b8400 */ { 1, 1, 2,  61 } },
+-    { 229500, 0x0660, /* 0x3e8400 */ { 1, 1, 2,  64 } }, /* Not tested on Pro } */
+-    {      0,      0,                { 0, 0, 0,   0 } }
++    {  25200, 0x513C, /* 0xa79004 */ { { 1, 4, 6, 169 } } },
++    {  25312, 0xC763, /* 0xc49005 */ { { 1, 4, 7, 198 } } },
++    {  26591, 0x471A, /* 0xce9005 */ { { 1, 4, 7, 208 } } },
++    {  31500, 0xC558, /* 0xae9003 */ { { 1, 4, 5, 176 } } },
++    {  31704, 0x471F, /* 0xaf9002 */ { { 1, 4, 4, 177 } } },
++    {  32663, 0xC449, /* 0x479000 */ { { 1, 4, 2,  73 } } },
++    {  33750, 0x4721, /* 0x959002 */ { { 1, 4, 4, 151 } } },
++    {  35500, 0x5877, /* 0x759001 */ { { 1, 4, 3, 119 } } },
++    {  36000, 0x5879, /* 0x9f9002 */ { { 1, 4, 4, 161 } } },
++    {  39822, 0xC459, /* 0x578c02 */ { { 1, 3, 4,  89 } } },
++    {  40000, 0x515F, /* 0x848c04 */ { { 1, 3, 6, 134 } } },
++    {  41164, 0x4417, /* 0x2c8c00 */ { { 1, 3, 2,  46 } } },
++    {  46981, 0x5069, /* 0x678c02 */ { { 1, 3, 4, 105 } } },
++    {  49500, 0xC353, /* 0xa48c04 */ { { 3, 3, 5, 138 } } },
++    {  50000, 0xC354, /* 0x368c00 */ { { 1, 3, 2,  56 } } },
++    {  56300, 0x4F76, /* 0x3d8c00 */ { { 1, 3, 2,  63 } } },
++    {  57275,      0, /* 0x3e8c00 */ { { 1, 3, 5, 157 } } }, /* For XO 1.5 no need for a unichrome clock */
++    {  57284, 0x4E70, /* 0x3e8c00 */ { { 1, 3, 2,  64 } } },
++    {  64995, 0x0D3B, /* 0x6b8c01 */ { { 1, 3, 3, 109 } } },
++    {  65000, 0x0D3B, /* 0x6b8c01 */ { { 1, 3, 3, 109 } } }, /* Slightly unstable on PM800 */
++    {  65028, 0x866D, /* 0x6b8c01 */ { { 1, 3, 3, 109 } } },
++    {  74480, 0x156E, /* 0x288800 */ { { 1, 2, 2,  42 } } },
++    {  75000, 0x156E, /* 0x288800 */ { { 1, 2, 2,  42 } } },
++    {  78800, 0x442C, /* 0x2a8800 */ { { 1, 2, 2,  44 } } },
++    {  81135, 0x0622, /* 0x428801 */ { { 1, 2, 3,  68 } } },
++    {  81613, 0x4539, /* 0x708803 */ { { 1, 2, 5, 114 } } },
++    {  94500, 0x4542, /* 0x4d8801 */ { { 1, 2, 3,  79 } } },
++    { 108000, 0x0B53, /* 0x778802 */ { { 1, 2, 4, 121 } } },
++    { 108280, 0x4879, /* 0x778802 */ { { 1, 2, 4, 121 } } },
++    { 122000, 0x0D6F, /* 0x428800 */ { { 1, 2, 2,  68 } } },
++    { 122726, 0x073C, /* 0x878802 */ { { 1, 2, 4, 137 } } },
++    { 135000, 0x0742, /* 0x6f8801 */ { { 1, 2, 3, 113 } } },
++    { 148500, 0x0853, /* 0x518800 */ { { 1, 2, 2,  83 } } },
++    { 155800, 0x0857, /* 0x558402 */ { { 1, 1, 4,  87 } } }, 
++    { 157500, 0x422C, /* 0x2a8400 */ { { 1, 1, 2,  44 } } },
++    { 161793, 0x4571, /* 0x6f8403 */ { { 1, 1, 5, 113 } } }, 
++    { 162000, 0x0A71, /* 0x6f8403 */ { { 1, 1, 5, 113 } } },
++    { 175500, 0x4231, /* 0x2f8400 */ { { 1, 1, 2,  49 } } },
++    { 189000, 0x0542, /* 0x4d8401 */ { { 1, 1, 3,  79 } } },
++    { 202500, 0x0763, /* 0x6F8402 */ { { 1, 1, 4, 113 } } },
++    { 204800, 0x0764, /* 0x548401 */ { { 1, 1, 3,  86 } } },
++    { 218300, 0x043D, /* 0x3b8400 */ { { 1, 1, 2,  61 } } },
++    { 229500, 0x0660, /* 0x3e8400 */ { { 1, 1, 2,  64 } } }, /* Not tested on Pro } */
++    {      0,      0,                { { 0, 0, 0,   0 } } }
+ };
+ 
+ /*
+@@ -131,7 +132,7 @@ static DisplayModeRec ViaPanelModes[] = {
+     { MODEPREFIX("856x480"),    31704,  856,  872,  960, 1064, 0,  480,  480,  483,  497, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX },
+     { MODEPREFIX("1024x512"),   41164, 1024, 1056, 1160, 1296, 0,  512,  512,  515,  531, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX },
+     { MODEPREFIX("1024x576"),   46981, 1024, 1064, 1168, 1312, 0,  576,  576,  579,  597, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX },
+-    { MODEPREFIX("1024x600"),   48960, 1024, 1064, 1168, 1312, 0,  600,  601,  604,  622, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX },
++    { MODEPREFIX("1024x600"),   48960, 1024, 1048, 1152, 1312, 0,  600,  601,  604,  630, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX },
+     { MODEPREFIX("1024x768"),   65028, 1024, 1048, 1184, 1344, 0,  768,  770,  776,  806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX },
+     { MODEPREFIX("1152x864"),   81613, 1152, 1216, 1336, 1520, 0,  864,  864,  867,  895, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX },
+     { MODEPREFIX("1280x768"),   81135, 1280, 1328, 1440, 1688, 0,  768,  770,  776,  802, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX },
+Index: src/via_memcpy.c
+===================================================================
+--- src/via_memcpy.c	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_memcpy.c	(.../trunk)	(revision 916)
+@@ -581,12 +581,12 @@ viaVidCopyInit(char *copyType, ScreenPtr pScreen)
+ 
+     if (VIAAllocLinear(&tmpFbBuffer, pScrn, alignSize + 31))
+         return libc_YUV42X;
+-    if (NULL == (buf2 = (unsigned char *)xalloc(testSize))) {
++    if (NULL == (buf2 = (unsigned char *)malloc(testSize))) {
+         VIAFreeLinear(&tmpFbBuffer);
+         return libc_YUV42X;
+     }
+-    if (NULL == (buf3 = (unsigned char *)xalloc(testSize))) {
+-        xfree(buf2);
++    if (NULL == (buf3 = (unsigned char *)malloc(testSize))) {
++        free(buf2);
+         VIAFreeLinear(&tmpFbBuffer);
+         return libc_YUV42X;
+     }
+@@ -642,8 +642,8 @@ viaVidCopyInit(char *copyType, ScreenPtr pScreen)
+                        curData->mName);
+         }
+     }
+-    xfree(buf3);
+-    xfree(buf2);
++    free(buf3);
++    free(buf2);
+     VIAFreeLinear(&tmpFbBuffer);
+     xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+                "Using %s YUV42X copy for %s.\n",
+Index: src/via_driver.c
+===================================================================
+--- src/via_driver.c	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_driver.c	(.../trunk)	(revision 916)
+@@ -143,6 +143,7 @@ static const struct pci_id_match via_device_match[
+    VIA_DEVICE_MATCH (PCI_CHIP_VT3327, 0 ),
+    VIA_DEVICE_MATCH (PCI_CHIP_VT3353, 0 ),
+    VIA_DEVICE_MATCH (PCI_CHIP_VT3409, 0 ),
++   VIA_DEVICE_MATCH (PCI_CHIP_VT3410, 0 ),
+     { 0, 0, 0 },
+ };
+ 
+@@ -174,12 +175,13 @@ static SymTabRec VIAChipsets[] = {
+     {VIA_K8M800,   "K8M800/K8N800"},
+     {VIA_PM800,    "PM800/PM880/CN400"},
+     {VIA_VM800,    "VM800/P4M800Pro/VN800/CN700"},
++    {VIA_CX700,    "CX700/VX700"},
+     {VIA_K8M890,   "K8M890/K8N890"},
++    {VIA_P4M890,   "P4M890"},
+     {VIA_P4M900,   "P4M900/VN896/CN896"},
+-    {VIA_CX700,    "CX700/VX700"},
+-    {VIA_P4M890,   "P4M890"},
+-    {VIA_VX800,    "VX800"},
+-    {VIA_VX855,    "VX855"},
++    {VIA_VX800,    "VX800/VX820"},
++    {VIA_VX855,    "VX855/VX875"},
++    {VIA_VX900,    "VX900"},
+     {-1,            NULL }
+ };
+ 
+@@ -190,12 +192,13 @@ static PciChipsets VIAPciChipsets[] = {
+     {VIA_K8M800,   PCI_CHIP_VT3204,    VIA_RES_SHARED},
+     {VIA_PM800,    PCI_CHIP_VT3259,    VIA_RES_SHARED},
+     {VIA_VM800,    PCI_CHIP_VT3314,    VIA_RES_SHARED},
++    {VIA_CX700,    PCI_CHIP_VT3324,    VIA_RES_SHARED},
+     {VIA_K8M890,   PCI_CHIP_VT3336,    VIA_RES_SHARED},
++    {VIA_P4M890,   PCI_CHIP_VT3327,    VIA_RES_SHARED},
+     {VIA_P4M900,   PCI_CHIP_VT3364,    VIA_RES_SHARED},
+-    {VIA_CX700,    PCI_CHIP_VT3324,    VIA_RES_SHARED},
+-    {VIA_P4M890,   PCI_CHIP_VT3327,    VIA_RES_SHARED},
+     {VIA_VX800,    PCI_CHIP_VT3353,    VIA_RES_SHARED},
+     {VIA_VX855,    PCI_CHIP_VT3409,    VIA_RES_SHARED},
++    {VIA_VX900,    PCI_CHIP_VT3410,    VIA_RES_SHARED},
+     {-1,           -1,                 VIA_RES_UNDEF}
+ };
+ 
+@@ -215,9 +218,11 @@ typedef enum
+     OPTION_EXA_SCRATCH_SIZE,
+     OPTION_SWCURSOR,
+     OPTION_SHADOW_FB,
++    OPTION_ROTATION_TYPE,
+     OPTION_ROTATE,
+     OPTION_VIDEORAM,
+     OPTION_ACTIVEDEVICE,
++    OPTION_I2CDEVICES,
+     OPTION_BUSWIDTH,
+     OPTION_CENTER,
+     OPTION_PANELSIZE,
+@@ -253,6 +258,7 @@ static OptionInfoRec VIAOptions[] = {
+     {OPTION_EXA_SCRATCH_SIZE,    "ExaScratchSize",   OPTV_INTEGER, {0}, FALSE},
+     {OPTION_SWCURSOR,            "SWCursor",         OPTV_BOOLEAN, {0}, FALSE},
+     {OPTION_SHADOW_FB,           "ShadowFB",         OPTV_BOOLEAN, {0}, FALSE},
++    {OPTION_ROTATION_TYPE,       "RotationType",     OPTV_ANYSTR,  {0}, FALSE},
+     {OPTION_ROTATE,              "Rotate",           OPTV_ANYSTR,  {0}, FALSE},
+     {OPTION_VIDEORAM,            "VideoRAM",         OPTV_INTEGER, {0}, FALSE},
+     {OPTION_ACTIVEDEVICE,        "ActiveDevice",     OPTV_ANYSTR,  {0}, FALSE},
+@@ -276,6 +282,7 @@ static OptionInfoRec VIAOptions[] = {
+     {OPTION_MODE_SWITCH_METHOD,  "ModeSwitchMethod", OPTV_ANYSTR,  {0}, FALSE},
+     {OPTION_MAX_DRIMEM,          "MaxDRIMem",        OPTV_INTEGER, {0}, FALSE},
+     {OPTION_AGPMEM,              "AGPMem",           OPTV_INTEGER, {0}, FALSE},
++    {OPTION_I2CDEVICES,          "I2CDevices",       OPTV_ANYSTR,  {0}, FALSE},
+     {-1,                         NULL,               OPTV_NONE,    {0}, FALSE}
+ };
+ 
+@@ -307,6 +314,7 @@ VIASetup(pointer module, pointer opts, int *errmaj
+ {
+     static Bool setupDone = FALSE;
+ 
++    /* Only be loaded once */
+     if (!setupDone) {
+         setupDone = TRUE;
+         xf86AddDriver(&VIA, module,
+@@ -339,6 +347,7 @@ VIAGetRec(ScrnInfoPtr pScrn)
+     if (pScrn->driverPrivate)
+         return TRUE;
+ 
++    /* allocate VIARec */
+     pScrn->driverPrivate = xnfcalloc(sizeof(VIARec), 1);
+     VIAPtr pVia = ((VIARec *) (pScrn->driverPrivate));
+ 
+@@ -400,36 +409,36 @@ VIAFreeRec(ScrnInfoPtr pScrn)
+ 
+         if (pBIOSInfo->Panel) {
+             if (pBIOSInfo->Panel->NativeMode)
+-                xfree(pBIOSInfo->Panel->NativeMode);
++                free(pBIOSInfo->Panel->NativeMode);
+             if (pBIOSInfo->Panel->CenteredMode)
+-                xfree(pBIOSInfo->Panel->CenteredMode);
+-            xfree(pBIOSInfo->Panel);
++                free(pBIOSInfo->Panel->CenteredMode);
++            free(pBIOSInfo->Panel);
+         }
+ 
+         if (pBIOSInfo->FirstCRTC)
+-            xfree(pBIOSInfo->FirstCRTC);
++            free(pBIOSInfo->FirstCRTC);
+         if (pBIOSInfo->SecondCRTC)
+-            xfree(pBIOSInfo->SecondCRTC);
++            free(pBIOSInfo->SecondCRTC);
+         if (pBIOSInfo->Simultaneous)
+-            xfree(pBIOSInfo->Simultaneous);
++            free(pBIOSInfo->Simultaneous);
+         if (pBIOSInfo->Lvds)
+-            xfree(pBIOSInfo->Lvds);
++            free(pBIOSInfo->Lvds);
+     }
+ 
+     if (VIAPTR(pScrn)->pVbe)
+         vbeFree(VIAPTR(pScrn)->pVbe);
+ 
+     if (pVia->VideoRegs)
+-        xfree(pVia->VideoRegs);
++        free(pVia->VideoRegs);
+ 
+     if (((VIARec *) (pScrn->driverPrivate))->pBIOSInfo->TVI2CDev)
+         xf86DestroyI2CDevRec((((VIARec *) (pScrn->driverPrivate))->pBIOSInfo->
+                               TVI2CDev), TRUE);
+-    xfree(((VIARec *) (pScrn->driverPrivate))->pBIOSInfo);
++    free(((VIARec *) (pScrn->driverPrivate))->pBIOSInfo);
+ 
+     VIAUnmapMem(pScrn);
+ 
+-    xfree(pScrn->driverPrivate);
++    free(pScrn->driverPrivate);
+     pScrn->driverPrivate = NULL;
+ } /* VIAFreeRec */
+ 
+@@ -455,7 +464,6 @@ via_pci_probe(DriverPtr driver, int entity_num,
+ {
+     ScrnInfoPtr scrn = NULL;
+     EntityInfoPtr entity;
+-    DevUnion *private;
+ 
+     scrn = xf86ConfigPciEntity(scrn, 0, entity_num, VIAPciChipsets,
+                                NULL, NULL, NULL, NULL, NULL);
+@@ -513,7 +521,7 @@ VIAProbe(DriverPtr drv, int flags)
+                                     numDevSections,
+                                     drv,
+                                     &usedChips);
+-    xfree(devSections);
++    free(devSections);
+ 
+     if (numUsed <= 0)
+         return FALSE;
+@@ -588,11 +596,11 @@ VIAProbe(DriverPtr drv, int flags)
+                 }
+                 instance++;
+             }
+-            xfree(pEnt);
++            free(pEnt);
+         }
+     }
+ 
+-    xfree(usedChips);
++    free(usedChips);
+ 
+     return foundScreen;
+ 
+@@ -652,6 +660,12 @@ VIAProbeDDC(ScrnInfoPtr pScrn, int index)
+     vbeInfoPtr pVbe;
+ 
+     if (xf86LoadSubModule(pScrn, "vbe")) {
++        /* FIXME This line should be replaced with:
++
++           pVbe = VBEExtendedInit(NULL, index, 0);
++
++           for XF86 version > 4.2.99
++        */
+         pVbe = VBEInit(NULL, index);
+         ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
+         vbeFree(pVbe);
+@@ -664,7 +678,7 @@ VIASetupDefaultOptions(ScrnInfoPtr pScrn)
+     VIAPtr pVia = VIAPTR(pScrn);
+     VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+ 
+-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIASetupDefaultOptions\n"));
++    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIASetupDefaultOptions - Setting up default chipset options.\n"));
+ 
+     pVia->shadowFB = FALSE;
+     pVia->NoAccel = FALSE;
+@@ -684,10 +698,14 @@ VIASetupDefaultOptions(ScrnInfoPtr pScrn)
+     pVia->maxDriSize = 0;
+     pVia->agpMem = AGP_SIZE / 1024;
+     pVia->ActiveDevice = 0x00;
++    pVia->I2CDevices = 0x00;
+     pVia->VideoEngine = VIDEO_ENGINE_CLE;
+ #ifdef HAVE_DEBUG
+     pVia->PrintVGARegs = FALSE;
+ #endif
++
++    /* Disable vertical interpolation because the size of */
++    /* line buffer (limited to 800) is too small to do interpolation. */
+     pVia->swov.maxWInterp = 800;
+     pVia->swov.maxHInterp = 600;
+     pVia->useLegacyVBE = TRUE;
+@@ -710,20 +728,30 @@ VIASetupDefaultOptions(ScrnInfoPtr pScrn)
+             break;
+         case VIA_K8M800:
+             pVia->DRIIrqEnable = FALSE;
+-            pVia->UseLegacyModeSwitch = TRUE;
+             break;
+         case VIA_PM800:
++            /* Use new mode switch to resolve many resolution and display bugs (switch to console) */
++            /* FIXME The video playing (XV) is not working correctly after turn on new mode switch */
+             pVia->VideoEngine = VIDEO_ENGINE_CME;
+-            pVia->UseLegacyModeSwitch = TRUE;
+             break;
+         case VIA_VM800:
+-            pVia->UseLegacyModeSwitch = TRUE;
++            /* New mode switch resolve bug with gamma set #282 */
++            /* and with Xv after hibernate #240                */
+             break;
++        case VIA_CX700:
++            pVia->VideoEngine = VIDEO_ENGINE_CME;
++            pVia->swov.maxWInterp = 1920;
++            pVia->swov.maxHInterp = 1080;
++            break;
+         case VIA_K8M890:
+             pVia->VideoEngine = VIDEO_ENGINE_CME;
+             pVia->agpEnable = FALSE;
+             pVia->dmaXV = FALSE;
+             break;
++        case VIA_P4M890:
++            pVia->VideoEngine = VIDEO_ENGINE_CME;
++            pVia->dmaXV = FALSE;
++            break;
+         case VIA_P4M900:
+             pVia->VideoEngine = VIDEO_ENGINE_CME;
+             pVia->agpEnable = FALSE;
+@@ -732,20 +760,13 @@ VIASetupDefaultOptions(ScrnInfoPtr pScrn)
+             pVia->dmaXV = FALSE;
+             pBIOSInfo->TVDIPort = VIA_DI_PORT_DVP0; 
+             break;
+-        case VIA_CX700:
+-            pVia->VideoEngine = VIDEO_ENGINE_CME;
+-            pVia->swov.maxWInterp = 1920;
+-            pVia->swov.maxHInterp = 1080;
+-            break;
+-        case VIA_P4M890:
+-            pVia->VideoEngine = VIDEO_ENGINE_CME;
+-            pVia->dmaXV = FALSE;
+-            break;
++
+         case VIA_VX800:
+         case VIA_VX855:
++        case VIA_VX900:
+             pVia->VideoEngine = VIDEO_ENGINE_CME;
+-            /* pVia->agpEnable = FALSE;
+-            pVia->dmaXV = FALSE;*/
++            pVia->agpEnable = FALSE;
++            pVia->dmaXV = FALSE;
+             break;
+     }
+ 
+@@ -807,7 +828,7 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+     pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ #ifndef XSERVER_LIBPCIACCESS
+     if (pEnt->resources) {
+-        xfree(pEnt);
++        free(pEnt);
+         VIAFreeRec(pScrn);
+         return FALSE;
+     }
+@@ -825,7 +846,7 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+             pPriv = xf86GetEntityPrivate(pScrn->entityList[0], gVIAEntityIndex);
+             pVIAEnt = pPriv->ptr;
+             if (pVIAEnt->BypassSecondary) {
+-                xfree(pEnt);
++                free(pEnt);
+                 VIAFreeRec(pScrn);
+                 return FALSE;
+             }
+@@ -848,6 +869,7 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+             pVIAEnt->HasSecondary = FALSE;
+             pVIAEnt->RestorePrimary = FALSE;
+             pVIAEnt->IsSecondaryRestored = FALSE;
++           
+         }
+     } else {
+         pVia->sharedData = xnfcalloc(sizeof(ViaSharedRec), 1);
+@@ -866,7 +888,7 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+      */
+ 
+     if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) {
+-        xfree(pEnt);
++        free(pEnt);
+         VIAFreeRec(pScrn);
+         return FALSE;
+     } else {
+@@ -881,7 +903,7 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                            "Given depth (%d) is not supported by this driver\n",
+                            pScrn->depth);
+-                xfree(pEnt);
++                free(pEnt);
+                 VIAFreeRec(pScrn);
+                 return FALSE;
+         }
+@@ -897,7 +919,7 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+         rgb zeros = { 0, 0, 0 };
+ 
+         if (!xf86SetWeight(pScrn, zeros, zeros)) {
+-            xfree(pEnt);
++            free(pEnt);
+             VIAFreeRec(pScrn);
+             return FALSE;
+         } else {
+@@ -914,7 +936,7 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+             xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+                        " (%s) is not supported at depth %d.\n",
+                        xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+-            xfree(pEnt);
++            free(pEnt);
+             VIAFreeRec(pScrn);
+             return FALSE;
+         }
+@@ -979,7 +1001,7 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+ 
+     xf86DrvMsg(pScrn->scrnIndex, from, "Chipset revision: %d\n", pVia->ChipRev);
+ 
+-    xfree(pEnt);
++    free(pEnt);
+ 
+     /* Detect the amount of installed RAM */
+     from = X_PROBED;
+@@ -993,6 +1015,12 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+ 
+     switch (pVia->Chipset) {
+         case VIA_CLE266:
++#ifdef XSERVER_LIBPCIACCESS
++            pci_device_cfg_read_u8(bridge, &videoRam, 0xE1);
++#else
++            videoRam = pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70;
++#endif
++            pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10;
+         case VIA_KM400:
+ #ifdef XSERVER_LIBPCIACCESS
+             pci_device_cfg_read_u8(bridge, &videoRam, 0xE1);
+@@ -1000,6 +1028,12 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+             videoRam = pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70;
+ #endif
+             pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10;
++            /* Workaround for #177 (VRAM probing fail on P4M800) */
++            if (pScrn->videoRam < 16384) {
++                xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++                           "Memory size detection failed: using 16 MB.\n");
++                pScrn->videoRam = 16 << 10;
++            }
+             break;
+         case VIA_PM800:
+         case VIA_VM800:
+@@ -1017,6 +1051,7 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+         case VIA_CX700:
+         case VIA_VX800:
+         case VIA_VX855:
++        case VIA_VX900:
+ #ifdef XSERVER_LIBPCIACCESS
+             pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1);
+ #else
+@@ -1046,23 +1081,18 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+             }
+     }
+ 
+-    if (from == X_PROBED)
++    if (from == X_PROBED) {
+         xf86DrvMsg(pScrn->scrnIndex, from,
+                    "Probed amount of VideoRAM = %d kB\n", pScrn->videoRam);
++    }
+ 
+-    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+-               "Setting up default chipset options.\n");
+     if (!VIASetupDefaultOptions(pScrn)) {
+         VIAFreeRec(pScrn);
+         return FALSE;
+     }
+ 
+-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Reading config file...\n");
+     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, VIAOptions);
+ 
+-    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+-               "Starting to parse config file options...\n");
+-
+     if (xf86GetOptValInteger(VIAOptions, OPTION_VIDEORAM, &pScrn->videoRam))
+         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+                    "Setting amount of VideoRAM to %d kB\n", pScrn->videoRam);
+@@ -1100,6 +1130,31 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+     }
+ 
+     /* When rotating, switch shadow framebuffer on and acceleration off. */
++    if ((s = xf86GetOptValString(VIAOptions, OPTION_ROTATION_TYPE))) {
++        if (!xf86NameCmp(s, "SWRandR")) {
++            pVia->shadowFB = TRUE;
++            pVia->NoAccel = TRUE;
++            pVia->RandRRotation = TRUE;
++            pVia->rotate = RR_Rotate_0;
++            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen "
++                       "RandR enabled, acceleration disabled\n");
++        } else if (!xf86NameCmp(s, "HWRandR")) {
++            pVia->shadowFB = TRUE;
++            pVia->NoAccel = TRUE;
++            pVia->RandRRotation = TRUE;
++            pVia->rotate = RR_Rotate_0;
++            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Hardware accelerated "
++                       "rotating screen is not implemented. Using SW RandR.\n");
++        } else {
++            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid"
++                       "value for Option \"RotationType\".\n", s);
++            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++                       "Valid options are \"SWRandR\" and \"HWRandR\".\n");
++        }
++    }
++
++
++    /* When rotating, switch shadow framebuffer on and acceleration off. */
+     if ((s = xf86GetOptValString(VIAOptions, OPTION_ROTATE))) {
+         if (!xf86NameCmp(s, "CW")) {
+             pVia->shadowFB = TRUE;
+@@ -1498,6 +1553,7 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+         }
+     }
+ 
++    /* Initialize the colormap */
+     Gamma zeros = { 0.0, 0.0, 0.0 };
+     if (!xf86SetGamma(pScrn, zeros)) {
+         VIAFreeRec(pScrn);
+@@ -1523,6 +1579,17 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+ 
+     pVia->videoRambytes = pScrn->videoRam << 10;
+ 
++    /* I2CDevices Option for I2C Initialization */
++    //pVia->I2CDevices = 0x00;
++    if ((s = xf86GetOptValString(VIAOptions, OPTION_I2CDEVICES))) {
++        if (strstr(s, "Bus1"))
++            pVia->I2CDevices |= VIA_I2C_BUS1;
++        if (strstr(s, "Bus2"))
++            pVia->I2CDevices |= VIA_I2C_BUS2;
++        if (strstr(s, "Bus3"))  
++            pVia->I2CDevices |= VIA_I2C_BUS3;
++    }
++
+     if (!xf86LoadSubModule(pScrn, "i2c")) {
+         VIAFreeRec(pScrn);
+         return FALSE;
+@@ -1536,10 +1603,13 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+     } else {
+ 
+         if (pVia->pI2CBus1) {
+-            pVia->DDC1 = xf86DoEDID_DDC2(pScrn->scrnIndex, pVia->pI2CBus1);
++            pVia->DDC1 = xf86DoEEDID(pScrn->scrnIndex, pVia->pI2CBus1, TRUE);
+             if (pVia->DDC1) {
+                 xf86PrintEDID(pVia->DDC1);
+                 xf86SetDDCproperties(pScrn, pVia->DDC1);
++                DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
++                    "DDC pI2CBus1 detected a %s\n", DIGITAL(pVia->DDC1->features.input_type) ?
++                    "DFP" : "CRT"));
+             }
+         }
+     }
+@@ -1559,17 +1629,6 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+             ViaPanelPreInit(pScrn);
+     }
+ 
+-    if (pBIOSInfo->Panel->IsActive &&
+-        ((pVia->Chipset == VIA_K8M800) ||
+-         (pVia->Chipset == VIA_PM800) ||
+-         (pVia->Chipset == VIA_VM800))) {
+-        xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Panel on K8M800, PM800 and "
+-                   "VM800 is currently not supported.\n");
+-        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+-                   "Using VBE to set modes to work around this.\n");
+-        pVia->useVBEModes = TRUE;
+-    }
+-
+     pVia->pVbe = NULL;
+     if (pVia->useVBEModes) {
+         /* VBE doesn't properly initialise int10 itself. */
+@@ -1593,6 +1652,7 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+         }
+ 
+     } else {
++        int max_pitch, max_height;
+         /* Add own modes. */
+         ViaModesAttach(pScrn, pScrn->monitor);
+ 
+@@ -1609,6 +1669,26 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+         clockRanges->interlaceAllowed = TRUE;
+         clockRanges->doubleScanAllowed = FALSE;
+ 
++        switch (pVia->Chipset) {
++            case VIA_CLE266:
++            case VIA_KM400:
++            case VIA_K8M800:
++            case VIA_PM800:
++            case VIA_VM800:
++                max_pitch = 3344;
++                max_height = 2508;
++            case VIA_CX700:
++            case VIA_K8M890:
++            case VIA_P4M890:
++            case VIA_P4M900:
++                max_pitch = 8192/(pScrn->bitsPerPixel >> 3)-1;
++                max_height = max_pitch;
++                break;
++            default:
++                max_pitch = 16384/(pScrn->bitsPerPixel >> 3)-1;
++                max_height = max_pitch;        
++        }
++
+         /*
+          * xf86ValidateModes will check that the mode HTotal and VTotal values
+          * don't exceed the chipset's limit if pScrn->maxHValue and
+@@ -1621,7 +1701,7 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+          *
+          * CLE266A: primary AdjustFrame can use only 24 bits, so we are limited
+          * to 12x11 bits; 4080x2048 (~2:1), 3344x2508 (4:3), or 2896x2896 (1:1).
+-         * Test CLE266Cx, KM400, KM400A, K8M800, PM800, CN400 please.
++         * TODO Test CLE266Cx, KM400, KM400A, K8M800, CN400 please.
+          *
+          * We should be able to limit the memory available for a mode to 32 MB,
+          * but xf86ValidateModes (or miScanLineWidth) fails to catch this
+@@ -1629,15 +1709,16 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+          */
+ 
+         /* Select valid modes from those available. */
+-        i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,     /* availModes */
+-                              pScrn->display->modes,    /* modeNames */
+-                              clockRanges,      /* list of clock ranges */
++        i = xf86ValidateModes(pScrn, 
++			      pScrn->monitor->Modes,     /* List of modes available for the monitor */
++                              pScrn->display->modes,     /* List of mode names that the screen is requesting */
++                              clockRanges,               /* list of clock ranges */
+                               NULL,     /* list of line pitches */
+                               256,      /* minimum line pitch */
+-                              3344,     /* maximum line pitch */
+-                              32 * 8,   /* pitch inc (bits) */
+-                              128,      /* min height */
+-                              2508,     /* max height */
++                              max_pitch,     /* maximum line pitch */
++                              16 * 8,   /* pitch increment (in bits), we just want 16 bytes alignment */
++                              128,      /* min virtual height */
++                              max_height,     /* maximum virtual height */
+                               pScrn->display->virtualX, /* virtual width */
+                               pScrn->display->virtualY, /* virtual height */
+                               pVia->videoRambytes,      /* apertureSize */
+@@ -1650,6 +1731,7 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+             return FALSE;
+         }
+ 
++        /* This function deletes modes in the modes field of the ScrnInfoRec that have been marked as invalid. */
+         xf86PruneDriverModes(pScrn);
+ 
+         if (i == 0 || pScrn->modes == NULL) {
+@@ -1662,9 +1744,17 @@ VIAPreInit(ScrnInfoPtr pScrn, int flags)
+     /* Set up screen parameters. */
+     pVia->Bpp = pScrn->bitsPerPixel >> 3;
+     pVia->Bpl = pScrn->displayWidth * pVia->Bpp;
++
++    /* This function fills in the Crtc fields for all the modes in the modes field of the ScrnInfoRec. */
+     xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
++
++    /* Set the current mode to the first in the list */
+     pScrn->currentMode = pScrn->modes;
++
++    /* Print the list of modes being used */    
+     xf86PrintModes(pScrn);
++
++    /* Set display resolution */
+     xf86SetDpi(pScrn, 0, 0);
+ 
+ #ifdef USE_FB
+@@ -1822,6 +1912,7 @@ VIALeaveVT(int scrnIndex, int flags)
+         case VIA_P4M900:
+         case VIA_VX800:
+         case VIA_VX855:
++        case VIA_VX900:
+             break;
+         default:
+             hwp->writeSeq(hwp, 0x1A, pVia->SavedReg.SR1A | 0x40);
+@@ -1935,7 +2026,9 @@ VIASave(ScrnInfoPtr pScrn)
+         Regs->SR17 = hwp->readSeq(hwp, 0x17);
+         Regs->SR18 = hwp->readSeq(hwp, 0x18);
+         Regs->SR19 = hwp->readSeq(hwp, 0x19);
++        /* PCI Bus Control */
+         Regs->SR1A = hwp->readSeq(hwp, 0x1A);
++
+         Regs->SR1B = hwp->readSeq(hwp, 0x1B);
+         Regs->SR1C = hwp->readSeq(hwp, 0x1C);
+         Regs->SR1D = hwp->readSeq(hwp, 0x1D);
+@@ -1977,40 +2070,59 @@ VIASave(ScrnInfoPtr pScrn)
+                 Regs->SR4C = hwp->readSeq(hwp, 0x4C);
+                 break;
+         }
+-        DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+-              "Non-Primary Adapter! saving VGA_SR_MODE only !!\n"));
++
++        /* Save Preemptive Arbiter Control Register */
++        Regs->SR4D = hwp->readSeq(hwp, 0x4D);
+         DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Crtc...\n"));
+ 
+         Regs->CR13 = hwp->readCrtc(hwp, 0x13);
+ 
+         Regs->CR32 = hwp->readCrtc(hwp, 0x32);
+         Regs->CR33 = hwp->readCrtc(hwp, 0x33);
+-        Regs->CR34 = hwp->readCrtc(hwp, 0x34);
++
+         Regs->CR35 = hwp->readCrtc(hwp, 0x35);
+         Regs->CR36 = hwp->readCrtc(hwp, 0x36);
+ 
++
++
++        /* Starting Address */
++        /* Start Address High */
++        Regs->CR0C = hwp->readCrtc(hwp, 0x0C);
++        /* Start Address Low */
++        Regs->CR0D = hwp->readCrtc(hwp, 0x0D);
++        /* Starting Address Overflow Bits[28:24] */
+         Regs->CR48 = hwp->readCrtc(hwp, 0x48);
++        /* CR34 are fire bits. Must be written after CR0C CR0D CR48.  */
++        /* Starting Address Overflow Bits[23:16] */
++        Regs->CR34 = hwp->readCrtc(hwp, 0x34);
++
++
+         Regs->CR49 = hwp->readCrtc(hwp, 0x49);
+ 
+         DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TVSave...\n"));
+         if (pBIOSInfo->TVI2CDev)
+             ViaTVSave(pScrn);
+ 
+-        /* Save LCD control registers. */
++        /* Save LCD control registers (from CR 0x50 to 0x93). */
+         for (i = 0; i < 68; i++)
+             Regs->CRTCRegs[i] = hwp->readCrtc(hwp, i + 0x50);
+ 
+         if (pVia->Chipset != VIA_CLE266 && pVia->Chipset != VIA_KM400) {
+-
+-            Regs->CRA0 = hwp->readCrtc(hwp, 0xA0);
+-            Regs->CRA1 = hwp->readCrtc(hwp, 0xA1);
+-            Regs->CRA2 = hwp->readCrtc(hwp, 0xA2);
+-
++            /* LVDS Channel 2 Function Select 0 / DVI Function Select */ 
+             Regs->CR97 = hwp->readCrtc(hwp, 0x97);
++            /* LVDS Channel 1 Function Select 0 */
+             Regs->CR99 = hwp->readCrtc(hwp, 0x99);
++            /* Digital Video Port 1 Function Select 0 */
+             Regs->CR9B = hwp->readCrtc(hwp, 0x9B);
++            /* Power Now Control 4 */
+             Regs->CR9F = hwp->readCrtc(hwp, 0x9F);
+ 
++            /* Horizontal Scaling Initial Value */
++            Regs->CRA0 = hwp->readCrtc(hwp, 0xA0);
++            /* Vertical Scaling Initial Value */
++            Regs->CRA1 = hwp->readCrtc(hwp, 0xA1);
++            /* Scaling Enable Bit */
++            Regs->CRA2 = hwp->readCrtc(hwp, 0xA2);
+         }
+ 
+         /* Save TMDS status */
+@@ -2018,6 +2130,7 @@ VIASave(ScrnInfoPtr pScrn)
+             case VIA_CX700:
+             case VIA_VX800:
+             case VIA_VX855:
++            case VIA_VX900:
+                 Regs->CRD2 = hwp->readCrtc(hwp, 0xD2);
+                 break;
+         }
+@@ -2045,15 +2158,15 @@ VIARestore(ScrnInfoPtr pScrn)
+     /* Unlock extended registers. */
+     hwp->writeSeq(hwp, 0x10, 0x01);
+ 
+-    /*=* CR6A, CR6B, CR6C must be reset before restore
+-         standard vga regs, or system will be hang. *=*/
++    /*=* CR6A, CR6B, CR6C must be reset before restoring
++         standard vga regs, or system will hang. *=*/
+     /*=* TODO Check is reset IGA2 channel before disable IGA2 channel
+-         is neccesery or it may cause some line garbage. *=*/
++         is necessary or it may cause some line garbage. *=*/
+     hwp->writeCrtc(hwp, 0x6A, 0x00);
+     hwp->writeCrtc(hwp, 0x6B, 0x00);
+     hwp->writeCrtc(hwp, 0x6C, 0x00);
+     
+-    /* Gamma must disable before restore pallette */
++    /* Gamma must be disabled before restoring palette */
+     ViaGammaDisable(pScrn);
+ 
+     if (pBIOSInfo->TVI2CDev)
+@@ -2098,11 +2211,19 @@ VIARestore(ScrnInfoPtr pScrn)
+     hwp->writeSeq(hwp, 0x45, Regs->SR45);
+     hwp->writeSeq(hwp, 0x46, Regs->SR46);
+ 
++    /* Reset VCK PLL */
++    hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) | 0x02); /* Set SR40[1] to 1 */
++    hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) & 0xFD); /* Set SR40[1] to 0 */
++
+     /* ECK Clock Synthesizer: */
+     hwp->writeSeq(hwp, 0x47, Regs->SR47);
+     hwp->writeSeq(hwp, 0x48, Regs->SR48);
+     hwp->writeSeq(hwp, 0x49, Regs->SR49);
+ 
++    /* Reset ECK PLL */
++    hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) | 0x01); /* Set SR40[0] to 1 */
++    hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) & 0xFE); /* Set SR40[0] to 0 */
++
+     switch (pVia->Chipset) {
+         case VIA_CLE266:
+         case VIA_KM400:
+@@ -2112,9 +2233,22 @@ VIARestore(ScrnInfoPtr pScrn)
+             hwp->writeSeq(hwp, 0x4A, Regs->SR4A);
+             hwp->writeSeq(hwp, 0x4B, Regs->SR4B);
+             hwp->writeSeq(hwp, 0x4C, Regs->SR4C);
++
++            /* Reset LCK PLL */
++            hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) | 0x04); /* Set SR40[2] to 1 */
++            hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) & 0xFB); /* Set SR40[2] to 0 */
+             break;
+     }
+ 
++    /* Restore Preemptive Arbiter Control Register
++     * VX800 and VX855 should restore this register too,
++     * but I don't do that for I don't want to affect any
++     * chips now.
++     */
++    if (pVia->Chipset == VIA_VX900) {
++        hwp->writeSeq(hwp, 0x4D, Regs->SR4D);
++    }
++
+     /* Reset dotclocks. */
+     ViaSeqMask(hwp, 0x40, 0x06, 0x06);
+     ViaSeqMask(hwp, 0x40, 0x00, 0x06);
+@@ -2127,14 +2261,23 @@ VIARestore(ScrnInfoPtr pScrn)
+     hwp->writeCrtc(hwp, 0x32, Regs->CR32);
+     /* HSYNCH Adjuster */
+     hwp->writeCrtc(hwp, 0x33, Regs->CR33);
+-    /* Starting Address Overflow */
+-    hwp->writeCrtc(hwp, 0x34, Regs->CR34);
+     /* Extended Overflow */
+     hwp->writeCrtc(hwp, 0x35, Regs->CR35);
+     /*Power Management 3 (Monitor Control) */
+     hwp->writeCrtc(hwp, 0x36, Regs->CR36);
+ 
++    /* Starting Address */
++    /* Start Address High */
++    hwp->writeCrtc(hwp, 0x0C, Regs->CR0C);
++    /* Start Address Low */
++    hwp->writeCrtc(hwp, 0x0D, Regs->CR0D);
++    /* Starting Address Overflow Bits[28:24] */
+     hwp->writeCrtc(hwp, 0x48, Regs->CR48);
++    /* CR34 are fire bits. Must be written after CR0C CR0D CR48.  */
++    /* Starting Address Overflow Bits[23:16] */
++    hwp->writeCrtc(hwp, 0x34, Regs->CR34);
++    
++
+     hwp->writeCrtc(hwp, 0x49, Regs->CR49);
+ 
+     /* Restore LCD control registers. */
+@@ -2160,6 +2303,7 @@ VIARestore(ScrnInfoPtr pScrn)
+         case VIA_CX700:
+         case VIA_VX800:
+         case VIA_VX855:
++        case VIA_VX900:
+             /* LVDS Control Register */
+             hwp->writeCrtc(hwp, 0xD2, Regs->CRD2);
+             break;
+@@ -2189,6 +2333,7 @@ ViaMMIOEnable(ScrnInfoPtr pScrn)
+         case VIA_P4M900:
+         case VIA_VX800:
+         case VIA_VX855:
++        case VIA_VX900:
+             ViaSeqMask(hwp, 0x1A, 0x08, 0x08);
+             break;
+         default:
+@@ -2212,6 +2357,7 @@ ViaMMIODisable(ScrnInfoPtr pScrn)
+         case VIA_P4M900:
+         case VIA_VX800:
+         case VIA_VX855:
++        case VIA_VX900:
+             ViaSeqMask(hwp, 0x1A, 0x00, 0x08);
+             break;
+         default:
+@@ -2328,10 +2474,18 @@ VIAMapFB(ScrnInfoPtr pScrn)
+     VIAPtr pVia = VIAPTR(pScrn);
+ 
+ #ifdef XSERVER_LIBPCIACCESS
+-    pVia->FrameBufferBase = pVia->PciInfo->regions[0].base_addr;
++    if (pVia->Chipset == VIA_VX900) {
++        pVia->FrameBufferBase = pVia->PciInfo->regions[2].base_addr;
++    } else {
++        pVia->FrameBufferBase = pVia->PciInfo->regions[0].base_addr;
++    }
+     int err;
+ #else
+-    pVia->FrameBufferBase = pVia->PciInfo->memBase[0];
++    if (pVia->Chipset == VIA_VX900) {
++        pVia->FrameBufferBase = pVia->PciInfo->memBase[2];
++    } else {
++        pVia->FrameBufferBase = pVia->PciInfo->memBase[0];
++    }
+ #endif
+ 
+     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAMapFB\n"));
+@@ -2453,7 +2607,6 @@ static void
+ VIALoadRgbLut(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
+               VisualPtr pVisual)
+ {
+-    VIAPtr pVia = VIAPTR(pScrn);
+     vgaHWPtr hwp = VGAHWPTR(pScrn);
+ 
+     int i, j, index;
+@@ -2844,7 +2997,7 @@ VIAInternalScreenInit(int scrnIndex, ScreenPtr pSc
+ 
+     if (pVia->shadowFB) {
+         pVia->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
+-        pVia->ShadowPtr = xalloc(pVia->ShadowPitch * shadowHeight);
++        pVia->ShadowPtr = malloc(pVia->ShadowPitch * shadowHeight);
+         displayWidth = pVia->ShadowPitch / (pScrn->bitsPerPixel >> 3);
+         FBStart = pVia->ShadowPtr;
+     } else {
+@@ -2880,7 +3033,6 @@ static Bool
+ VIAWriteMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
+ {
+     VIAPtr pVia = VIAPTR(pScrn);
+-    VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+ 
+     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAWriteMode\n"));
+ 
+@@ -2917,6 +3069,7 @@ VIAWriteMode(ScrnInfoPtr pScrn, DisplayModePtr mod
+                 case VIA_P4M900:
+                 case VIA_VX800:
+                 case VIA_VX855:
++                case VIA_VX900:
+                     /*
+                      * Since we are using virtual, we need to adjust
+                      * the offset to match the framebuffer alignment.
+@@ -2963,6 +3116,7 @@ VIACloseScreen(int scrnIndex, ScreenPtr pScreen)
+             case VIA_P4M900:
+             case VIA_VX800:
+             case VIA_VX855:
++            case VIA_VX900:
+                 break;
+             default :
+                 hwp->writeSeq(hwp, 0x1A, pVia->SavedReg.SR1A | 0x40);
+@@ -2986,11 +3140,11 @@ VIACloseScreen(int scrnIndex, ScreenPtr pScreen)
+ 
+     viaExitAccel(pScreen);
+     if (pVia->ShadowPtr) {
+-        xfree(pVia->ShadowPtr);
++        free(pVia->ShadowPtr);
+         pVia->ShadowPtr = NULL;
+     }
+     if (pVia->DGAModes) {
+-        xfree(pVia->DGAModes);
++        free(pVia->DGAModes);
+         pVia->DGAModes = NULL;
+     }
+ 
+@@ -3033,9 +3187,7 @@ static void
+ VIAAdjustFrame(int scrnIndex, int x, int y, int flags)
+ {
+     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+-    vgaHWPtr hwp = VGAHWPTR(pScrn);
+     VIAPtr pVia = VIAPTR(pScrn);
+-    CARD32 Base;
+ 
+     DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "VIAAdjustFrame %dx%d\n", x, y));
+ 
+@@ -3173,7 +3325,6 @@ VIASwitchMode(int scrnIndex, DisplayModePtr mode,
+ static void
+ VIADPMS(ScrnInfoPtr pScrn, int mode, int flags)
+ {
+-    vgaHWPtr hwp = VGAHWPTR(pScrn);
+     VIAPtr pVia = VIAPTR(pScrn);
+     VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+ 
+Index: src/via_crtc.c
+===================================================================
+--- src/via_crtc.c	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_crtc.c	(.../trunk)	(revision 916)
+@@ -174,6 +174,7 @@ ViaFirstCRTCSetMode(ScrnInfoPtr pScrn, DisplayMode
+         case VIA_P4M900:
+ 	case VIA_VX800:
+ 	case VIA_VX855:
++	case VIA_VX900:
+             break;
+         default:
+             ViaSeqMask(hwp, 0x16, 0x08, 0xBF);
+@@ -234,8 +235,8 @@ ViaFirstCRTCSetMode(ScrnInfoPtr pScrn, DisplayMode
+     /* Primary starting address -> 0x00, adjustframe does the rest */
+     hwp->writeCrtc(hwp, 0x0C, 0x00);
+     hwp->writeCrtc(hwp, 0x0D, 0x00);
++    ViaCrtcMask(hwp, 0x48, 0x00, 0x03); /* is this even possible on CLE266A ? */
+     hwp->writeCrtc(hwp, 0x34, 0x00);
+-    ViaCrtcMask(hwp, 0x48, 0x00, 0x03); /* is this even possible on CLE266A ? */
+ 
+     /* vertical sync start : 2047 */
+     temp = mode->CrtcVSyncStart;
+@@ -278,6 +279,7 @@ ViaFirstCRTCSetMode(ScrnInfoPtr pScrn, DisplayMode
+         case VIA_P4M900:
+ 	case VIA_VX800:
+ 	case VIA_VX855:
++	case VIA_VX900:
+             break;
+         default:
+             /* some leftovers */
+@@ -314,6 +316,7 @@ ViaFirstCRTCSetMode(ScrnInfoPtr pScrn, DisplayMode
+         case VIA_P4M900:
+ 	case VIA_VX800:
+ 	case VIA_VX855:
++	case VIA_VX900:
+             break;
+         default:
+             /* some leftovers */
+@@ -331,15 +334,20 @@ ViaFirstCRTCSetStartingAddress(ScrnInfoPtr pScrn,
+     CARD32 Base;
+     CARD32 tmp;
+ 
++    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaFirstCRTCSetStartingAddress\n"));
++
+     Base = (y * pScrn->displayWidth + x) * (pScrn->bitsPerPixel / 8);
+     Base = Base >> 1;
+ 
+     hwp->writeCrtc(hwp, 0x0C, (Base & 0xFF00) >> 8);
+     hwp->writeCrtc(hwp, 0x0D, Base & 0xFF);
++    /* FIXME The proper starting address for CR48 is 0x1F - Bits[28:24] */
++    if (!(pVia->Chipset == VIA_CLE266 && CLE266_REV_IS_AX(pVia->ChipRev)))
++        ViaCrtcMask(hwp, 0x48, Base >> 24, 0x0F);
++    /* CR34 are fire bits. Must be written after CR0C CR0D CR48.  */
+     hwp->writeCrtc(hwp, 0x34, (Base & 0xFF0000) >> 16);
+ 
+-    if (!(pVia->Chipset == VIA_CLE266 && CLE266_REV_IS_AX(pVia->ChipRev)))
+-        ViaCrtcMask(hwp, 0x48, Base >> 24, 0x0F);
++
+ }
+ 
+ void
+@@ -434,6 +442,7 @@ ViaSecondCRTCSetMode(ScrnInfoPtr pScrn, DisplayMod
+         case VIA_P4M900:
+ 	case VIA_VX800:
+ 	case VIA_VX855:
++	case VIA_VX900:  
+             break;
+         default:
+             ViaSeqMask(hwp, 0x16, 0x08, 0xBF);
+@@ -518,6 +527,7 @@ ViaSecondCRTCSetMode(ScrnInfoPtr pScrn, DisplayMod
+         case VIA_P4M900:
+ 	case VIA_VX800:
+ 	case VIA_VX855:
++	case VIA_VX900:
+             break;
+         default:
+             /* some leftovers */
+Index: src/via_swov.c
+===================================================================
+--- src/via_swov.c	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_swov.c	(.../trunk)	(revision 916)
+@@ -65,6 +65,31 @@
+ #define IN_VIDEO_DISPLAY     (*((unsigned long volatile *)(pVia->VidMapBase+V_FLAGS))&VBI_STATUS)
+ #define VIA_FIRETIMEOUT 40000
+ 
++enum HQV_CME_Regs {
++        HQV_SDO_CTRL1,
++        HQV_SDO_CTRL2,
++        HQV_SDO_CTRL3,
++        HQV_SDO_CTRL4
++};
++
++/* register offsets for VT3553/VX800 */
++static const unsigned hqv_cme_regs[] = {
++    [HQV_SDO_CTRL1]  = HQV_SRC_DATA_OFFSET_CONTROL1,
++    [HQV_SDO_CTRL2]  = HQV_SRC_DATA_OFFSET_CONTROL2,
++    [HQV_SDO_CTRL3]  = HQV_SRC_DATA_OFFSET_CONTROL3,
++    [HQV_SDO_CTRL4]  = HQV_SRC_DATA_OFFSET_CONTROL4
++};
++
++/* register hqv offsets for new VT3409/VX855 */
++static const unsigned hqv_cme_regs_409[] = {
++    [HQV_SDO_CTRL1]  = HQV_SRC_DATA_OFFSET_CTRL1_409,
++    [HQV_SDO_CTRL2]  = HQV_SRC_DATA_OFFSET_CTRL2_409,
++    [HQV_SDO_CTRL3]  = HQV_SRC_DATA_OFFSET_CTRL3_409,
++    [HQV_SDO_CTRL4]  = HQV_SRC_DATA_OFFSET_CTRL4_409
++};
++
++#define HQV_CME_REG(HWDiff, name) (HWDiff)->HQVCmeRegs[name]
++
+ static void
+ viaWaitVideoCommandFire(VIAPtr pVia)
+ {
+@@ -88,6 +113,7 @@ viaWaitHQVFlip(VIAPtr pVia)
+ {
+     unsigned long proReg = 0;
+     CARD32 volatile *pdwState;
++    unsigned count = 50000;
+ 
+     if (pVia->ChipId == PCI_CHIP_VT3259
+         && !(pVia->swov.gdwVideoFlagSW & VIDEO_1_INUSE))
+@@ -96,10 +122,9 @@ viaWaitHQVFlip(VIAPtr pVia)
+     pdwState = (CARD32 volatile *)(pVia->VidMapBase + (HQV_CONTROL + proReg));
+ 
+     if (pVia->VideoEngine == VIDEO_ENGINE_CME) {
+-        // while (*pdwState & (HQV_SUBPIC_FLIP | HQV_SW_FLIP)) ;
+-	while (*pdwState & HQV_SUBPIC_FLIP);
++		while (--count && (*pdwState & HQV_SUBPIC_FLIP));
+     } else {
+-        while (!(*pdwState & HQV_FLIP_STATUS)) ;
++        while (--count && !(*pdwState & HQV_FLIP_STATUS)) ;
+     }
+ }
+ 
+@@ -109,8 +134,9 @@ viaWaitHQVFlipClear(VIAPtr pVia, unsigned long dwD
+     CARD32 volatile *pdwState =
+             (CARD32 volatile *)(pVia->VidMapBase + HQV_CONTROL);
+     *pdwState = dwData;
++    unsigned count = 50000;
+ 
+-    while ((*pdwState & HQV_FLIP_STATUS)) {
++    while (--count && (*pdwState & HQV_FLIP_STATUS)) {
+         VIDOutD(HQV_CONTROL, *pdwState | HQV_FLIP_STATUS);
+     }
+ }
+@@ -126,6 +152,7 @@ viaWaitHQVDone(VIAPtr pVia)
+ {
+     CARD32 volatile *pdwState;
+     unsigned long proReg = 0;
++    unsigned count = 50000;
+ 
+     if (pVia->ChipId == PCI_CHIP_VT3259
+         && !(pVia->swov.gdwVideoFlagSW & VIDEO_1_INUSE))
+@@ -133,7 +160,7 @@ viaWaitHQVDone(VIAPtr pVia)
+ 
+     pdwState = (CARD32 volatile *)(pVia->VidMapBase + (HQV_CONTROL + proReg));
+     if (pVia->swov.MPEG_ON) {
+-        while ((*pdwState & HQV_SW_FLIP)) ;
++        while (--count && (*pdwState & HQV_SW_FLIP)) ;
+     }
+ }
+ 
+@@ -179,12 +206,14 @@ ResetVidRegBuffer(VIAPtr pVia)
+ static void
+ SaveVideoRegister(VIAPtr pVia, CARD32 index, CARD32 data)
+ {
++    if (pVia->VidRegCursor >= VIDREG_BUFFER_SIZE) {
++        DBG_DD(ErrorF("SaveVideoRegister: Out of video register space flushing"));
++        FlushVidRegBuffer(pVia);
++        ResetVidRegBuffer(pVia);
++    }
++
+     pVia->VidRegBuffer[pVia->VidRegCursor++] = index;
+     pVia->VidRegBuffer[pVia->VidRegCursor++] = data;
+-
+-    if (pVia->VidRegCursor > VIDREG_BUFFER_SIZE) {
+-        DBG_DD(ErrorF("SaveVideoRegister: Out of video register space"));
+-    }
+ }
+ 
+ /*
+@@ -224,6 +253,7 @@ VIAVidHWDiffInit(ScrnInfoPtr pScrn)
+                 HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE;
+                 HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE;
+             }
++            HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE;
+             break;
+         case VIA_KM400:
+             HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE;
+@@ -232,6 +262,7 @@ VIAVidHWDiffInit(ScrnInfoPtr pScrn)
+             HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE;
+             HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE;
+             HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE;
++            HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE;
+             break;
+         case VIA_K8M800:
+             HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE;
+@@ -240,6 +271,7 @@ VIAVidHWDiffInit(ScrnInfoPtr pScrn)
+             HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE;
+             HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE;
+             HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE;
++            HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE;
+             break;
+         case VIA_PM800:
+             HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE;
+@@ -248,6 +280,8 @@ VIAVidHWDiffInit(ScrnInfoPtr pScrn)
+             HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE;
+             HWDiff->dwHQVDisablePatch = VID_HWDIFF_FALSE;
+             HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE;
++            HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE;
++            HWDiff->HQVCmeRegs = hqv_cme_regs;
+             break;
+         case VIA_VM800:
+         case VIA_P4M900:
+@@ -257,6 +291,8 @@ VIAVidHWDiffInit(ScrnInfoPtr pScrn)
+             HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE;
+             HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE;
+             HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE;
++            HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE;
++            HWDiff->HQVCmeRegs = hqv_cme_regs;
+             break;
+         case VIA_K8M890:
+             HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE;
+@@ -265,6 +301,8 @@ VIAVidHWDiffInit(ScrnInfoPtr pScrn)
+             HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE;
+             HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE;
+             HWDiff->dwNeedV1Prefetch = VID_HWDIFF_TRUE;
++            HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE;
++            HWDiff->HQVCmeRegs = hqv_cme_regs;
+             break;
+         case VIA_P4M890:
+             HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE;
+@@ -273,6 +311,8 @@ VIAVidHWDiffInit(ScrnInfoPtr pScrn)
+             HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE;
+             HWDiff->dwHQVDisablePatch = VID_HWDIFF_TRUE;
+             HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE;
++            HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE;
++            HWDiff->HQVCmeRegs = hqv_cme_regs;
+             break;
+         case VIA_CX700:
+             HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE;
+@@ -281,8 +321,19 @@ VIAVidHWDiffInit(ScrnInfoPtr pScrn)
+             HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE;
+             HWDiff->dwHQVDisablePatch = VID_HWDIFF_FALSE;
+             HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE;
++            HWDiff->dwNewScaleCtl = VID_HWDIFF_FALSE;
++            HWDiff->HQVCmeRegs = hqv_cme_regs;
+             break;
+         case VIA_VX800:
++            HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE;
++            HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_TRUE;
++            HWDiff->dwSupportTwoColorKey = VID_HWDIFF_TRUE;
++            HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE;
++            HWDiff->dwHQVDisablePatch = VID_HWDIFF_FALSE;
++            HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE;
++            HWDiff->dwNewScaleCtl = VID_HWDIFF_TRUE;
++            HWDiff->HQVCmeRegs = hqv_cme_regs;
++            break;
+         case VIA_VX855:
+             HWDiff->dwThreeHQVBuffer = VID_HWDIFF_TRUE;
+             HWDiff->dwHQVFetchByteUnit = VID_HWDIFF_TRUE;
+@@ -290,6 +341,8 @@ VIAVidHWDiffInit(ScrnInfoPtr pScrn)
+             HWDiff->dwHQVInitPatch = VID_HWDIFF_FALSE;
+             HWDiff->dwHQVDisablePatch = VID_HWDIFF_FALSE;
+             HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE;
++            HWDiff->dwNewScaleCtl = VID_HWDIFF_TRUE;
++            HWDiff->HQVCmeRegs = hqv_cme_regs_409;
+             break;
+         default:
+             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+@@ -509,10 +562,12 @@ viaOverlayHQVCalcZoomWidth(VIAPtr pVia,
+                            unsigned long *pMiniCtl,
+                            unsigned long *pHQVfilterCtl,
+                            unsigned long *pHQVminiCtl,
++                           unsigned long *pHQVscaleCtlH,
+                            unsigned long *pHQVzoomflag)
+ {
+     unsigned long tmp, sw1, d, falign, mdiv;
+     Bool zoom_ok = TRUE;
++    VIAHWDiff *hwDiff = &pVia->HWDiff;
+ 
+     CARD32 HQVfilter[5] = { HQV_H_FILTER_DEFAULT, HQV_H_TAP4_121,
+         HQV_H_TAP4_121, HQV_H_TAP8_12221, HQV_H_TAP8_12221
+@@ -525,24 +580,57 @@ viaOverlayHQVCalcZoomWidth(VIAPtr pVia,
+     if (srcWidth == dstWidth) { /* No zoom */
+         *pHQVfilterCtl |= HQV_H_FILTER_DEFAULT;
+     } else if (srcWidth < dstWidth) { /* Zoom in */
++			*pZoomCtl &= 0x0000FFFF;
++	        tmp = srcWidth * 0x800 / dstWidth;
++	        *pZoomCtl |= ((tmp & 0x7ff) << 16) | V1_X_ZOOM_ENABLE;
++	        *pMiniCtl |= V1_X_INTERPOLY;
++	        zoom_ok = !(tmp > 0x7ff);
+ 
+-        tmp = srcWidth * 0x800 / dstWidth;
+-        *pZoomCtl = ((tmp & 0x7ff) << 16) | V1_X_ZOOM_ENABLE;
+-        *pMiniCtl |= V1_X_INTERPOLY;
+-        zoom_ok = !(tmp > 0x7ff);
++	        *pHQVzoomflag = 1;
++	        *pHQVfilterCtl |= HQV_H_FILTER_DEFAULT;
++    } else { /* srcWidth > dstWidth - Zoom out */
++		if (hwDiff->dwNewScaleCtl) {
++            if (srcWidth > (dstWidth << 3)) {
++                /*<1/8*/
++                /*FIXME!*/
++                if (dstWidth <= 32) {
++                    dstWidth = 33;
++                }
++                if (srcWidth > (dstWidth << 5)) {
++                    tmp = 1 * 0x1000 / 31;
++                } else {
++                    tmp = (dstWidth * 0x1000) / srcWidth;
++                }
+ 
+-        *pHQVzoomflag = 1;
+-        *pHQVfilterCtl |= HQV_H_FILTER_DEFAULT;
++                *pHQVscaleCtlH = HQV_H_SCALE_DOWN_UNDER_EIGHTH;
++            } else if (srcWidth == (dstWidth << 3)) {
++                /*1/8*/
++                tmp = ((dstWidth - 1) * 0x1000) / srcWidth;
++                *pHQVscaleCtlH = HQV_H_SCALE_DOWN_UNDER_EIGHTH;
++            } else if (srcWidth > (dstWidth << 2)) {
++                /*1/4 -1/8 zoom-out*/
++                tmp = (srcWidth * 0x1000) / dstWidth;
++                *pHQVscaleCtlH = HQV_H_SCALE_DOWN_FOURTH_TO_EIGHTH;
++            } else {
++                /*1-1/4 zoom-out*/
++                /*setting :src/(destination+0.5)*/
++                tmp = (srcWidth * 0x2000) / ((dstWidth << 1) + 1);
++                *pHQVscaleCtlH = HQV_H_SCALE_DOWN_FOURTH_TO_1;
++            }
+ 
+-    } else { /* srcWidth > dstWidth - Zoom out */
++            /*rounding to nearest interger*/
++            tmp += (((tmp * 0x1000) & 0xfff) > 1) ? 1 : 0;
++            *pHQVscaleCtlH |= (tmp & 0x7fff) | HQV_H_SCALE_ENABLE;
++		} else {
++	        /* HQV rounding patch, instead of:
++	         * //tmp = dstWidth*0x0800 / srcWidth; */
++	        tmp = dstWidth * 0x800 * 0x400 / srcWidth;
++	        tmp = tmp / 0x400 + ((tmp & 0x3ff) ? 1 : 0);
+ 
+-        /* HQV rounding patch, instead of:
+-         * //tmp = dstWidth*0x0800 / srcWidth; */
+-        tmp = dstWidth * 0x800 * 0x400 / srcWidth;
+-        tmp = tmp / 0x400 + ((tmp & 0x3ff) ? 1 : 0);
++	        *pHQVminiCtl = (tmp & 0x7ff) | HQV_H_MINIFY_ENABLE | HQV_H_MINIFY_DOWN;
+ 
+-        *pHQVminiCtl = (tmp & 0x7ff) | HQV_H_MINIFY_ENABLE | HQV_H_MINIFY_DOWN;
+-
++	        *pHQVminiCtl |= HQV_HDEBLOCK_FILTER;
++		}
+         /* Scale down the picture by a factor mdiv = (1 << d) = {2, 4, 8 or 16} */
+ 
+         sw1 = srcWidth;
+@@ -561,27 +649,25 @@ viaOverlayHQVCalcZoomWidth(VIAPtr pVia,
+         *pMiniCtl |= ((d << 1) - 1) << 24; /* <= {1,3,5,7} << 24 */
+ 
+         *pHQVfilterCtl |= HQVfilter[d];
+-        /* *pHQVminiCtl = HQVmini[d]; */
+-        *pHQVminiCtl |= HQV_HDEBLOCK_FILTER;
+ 
+-        /* Scale to arbitrary size, on top of previous scaling by (1 << d). */
++       	/* Scale to arbitrary size, on top of previous scaling by (1 << d). */
+ 
+-        if (sw1 < dstWidth) {
+-            /* CLE bug
+-             *pZoomCtl = sw1 * 0x0800 / dstWidth;*/
+-            *pZoomCtl = (sw1 - 2) * 0x0800 / dstWidth;
+-            *pZoomCtl = ((*pZoomCtl & 0x7ff) << 16) | V1_X_ZOOM_ENABLE;
+-        }
+-    }
++       	if (sw1 < dstWidth) {
++            	/* CLE bug
++           	*pZoomCtl = sw1 * 0x0800 / dstWidth;*/
++           	*pZoomCtl = (sw1 - 2) * 0x0800 / dstWidth;
++           	*pZoomCtl = ((*pZoomCtl & 0x7ff) << 16) | V1_X_ZOOM_ENABLE;
++   		}
+ 
+-    if (videoFlag & VIDEO_1_INUSE) {
+-        pVia->swov.overlayRecordV1.dwFetchAlignment = falign;
+-        pVia->swov.overlayRecordV1.dwminifyH = mdiv;
+-    } else {
+-        pVia->swov.overlayRecordV3.dwFetchAlignment = falign;
+-        pVia->swov.overlayRecordV3.dwminifyH = mdiv;
+-    }
++    	if (videoFlag & VIDEO_1_INUSE) {
++        	pVia->swov.overlayRecordV1.dwFetchAlignment = falign;
++        	pVia->swov.overlayRecordV1.dwminifyH = mdiv;
++    	} else {
++        	pVia->swov.overlayRecordV3.dwFetchAlignment = falign;
++        	pVia->swov.overlayRecordV3.dwminifyH = mdiv;
++    	}
+ 
++	}
+     return zoom_ok;
+ }
+ 
+@@ -591,10 +677,12 @@ viaOverlayHQVCalcZoomHeight(VIAPtr pVia,
+                             unsigned long *pZoomCtl, unsigned long *pMiniCtl,
+                             unsigned long *pHQVfilterCtl,
+                             unsigned long *pHQVminiCtl,
++                            unsigned long *pHQVscaleCtlV,
+                             unsigned long *pHQVzoomflag)
+ {
+     unsigned long tmp, sh1, d;
+     Bool zoom_ok = TRUE;
++    VIAHWDiff *hwDiff = &pVia->HWDiff;
+ 
+     CARD32 HQVfilter[5] = { HQV_V_TAP4_121, HQV_V_TAP4_121, HQV_V_TAP4_121,
+                             HQV_V_TAP8_12221, HQV_V_TAP8_12221 };
+@@ -608,48 +696,58 @@ viaOverlayHQVCalcZoomHeight(VIAPtr pVia,
+     if (srcHeight == dstHeight) { /* No zoom */
+         *pHQVfilterCtl |= HQV_V_TAP4_121;
+     } else if (srcHeight < dstHeight) { /* Zoom in */
++		*pZoomCtl &= 0xFFFF0000;
++	    tmp = srcHeight * 0x400 / dstHeight - 1;
++	    *pZoomCtl |= ((tmp & 0x3ff) | V1_Y_ZOOM_ENABLE);
++	    *pMiniCtl |= (V1_Y_INTERPOLY | V1_YCBCR_INTERPOLY);
+ 
+-        tmp = srcHeight * 0x0400 / dstHeight;
+-        *pZoomCtl |= ((tmp & 0x3ff) | V1_Y_ZOOM_ENABLE);
+-        *pMiniCtl |= (V1_Y_INTERPOLY | V1_YCBCR_INTERPOLY);
+-
+-        *pHQVzoomflag = 1;
+-        *pHQVfilterCtl |= HQV_V_TAP4_121;
++	    *pHQVzoomflag = 1;
++	    *pHQVfilterCtl |= HQV_V_TAP4_121;
+     } else { /* srcHeight > dstHeight - Zoom out */
++		if (hwDiff->dwNewScaleCtl) {
++            /*setting :src/(destination+0.5)*/
++            tmp = srcHeight * 0x2000 / ((dstHeight << 1) + 1);
++            tmp += (((tmp * 0x1000) & 0xfff) > 1) ? 1 : 0;
++            if ((tmp & 0x1ffff) == 0) {
++                tmp = 0x1ffff;
++            }
+ 
+-        /* HQV rounding patch, instead of:
+-         * //tmp = dstHeight*0x0800 / srcHeight; */
+-        tmp = dstHeight * 0x0800 * 0x400 / srcHeight;
+-        tmp = tmp / 0x400 + ((tmp & 0x3ff) ? 1 : 0);
+-        *pHQVminiCtl |= (((tmp & 0x7ff) << 16) | HQV_V_MINIFY_ENABLE
+-                         | HQV_V_MINIFY_DOWN);
++            *pHQVscaleCtlV = (tmp & 0x1ffff) | HQV_V_SCALE_ENABLE| HQV_V_SCALE_DOWN;
++		} else {
++	        /* HQV rounding patch, instead of:
++	         * //tmp = dstHeight*0x0800 / srcHeight; */
++	        tmp = dstHeight * 0x0800 * 0x400 / srcHeight;
++	        tmp = tmp / 0x400 + ((tmp & 0x3ff) ? 1 : 0);
++	        *pHQVminiCtl |= (((tmp & 0x7ff) << 16) | HQV_V_MINIFY_ENABLE
++	                         | HQV_V_MINIFY_DOWN);
+ 
+-        /* Scale down the picture by a factor (1 << d) = {2, 4, 8 or 16} */
++	        /* Scale down the picture by a factor (1 << d) = {2, 4, 8 or 16} */
++	
++	        sh1 = srcHeight;
++	        for (d = 1; d < 5; d++) {
++	            sh1 >>= 1;
++	            if (sh1 <= dstHeight)
++	                break;
++	        }
++	        if (d == 5) { /* Too small. */
++	            d = 4;
++	            zoom_ok = FALSE;
++	        }
+ 
+-        sh1 = srcHeight;
+-        for (d = 1; d < 5; d++) {
+-            sh1 >>= 1;
+-            if (sh1 <= dstHeight)
+-                break;
+-        }
+-        if (d == 5) { /* Too small. */
+-            d = 4;
+-            zoom_ok = FALSE;
+-        }
++	        *pMiniCtl |= ((d << 1) - 1) << 16; /* <= {1,3,5,7} << 16 */
+ 
+-        *pMiniCtl |= ((d << 1) - 1) << 16; /* <= {1,3,5,7} << 16 */
++	        *pHQVfilterCtl |= HQVfilter[d];
++	        /* *pHQVminiCtl |= HQVmini[d]; */
++	        *pHQVminiCtl |= HQV_VDEBLOCK_FILTER;
+ 
+-        *pHQVfilterCtl |= HQVfilter[d];
+-        /* *pHQVminiCtl |= HQVmini[d]; */
+-        *pHQVminiCtl |= HQV_VDEBLOCK_FILTER;
++	        /* Scale to arbitrary size, on top of previous scaling by (1 << d). */
+ 
+-        /* Scale to arbitrary size, on top of previous scaling by (1 << d). */
+-
+-        if (sh1 < dstHeight) {
+-            tmp = sh1 * 0x0400 / dstHeight;
+-            *pZoomCtl |= ((tmp & 0x3ff) | V1_Y_ZOOM_ENABLE);
+-            *pMiniCtl |= V1_Y_INTERPOLY | V1_YCBCR_INTERPOLY;
+-        }
++	        if (sh1 < dstHeight) {
++	            tmp = sh1 * 0x0400 / dstHeight;
++	            *pZoomCtl |= ((tmp & 0x3ff) | V1_Y_ZOOM_ENABLE);
++	            *pMiniCtl |= V1_Y_INTERPOLY | V1_YCBCR_INTERPOLY;
++	        }
++		}
+     }
+ 
+     return zoom_ok;
+@@ -1488,6 +1586,7 @@ SetColorKey(VIAPtr pVia, unsigned long videoFlag,
+ 
+     if (videoFlag & VIDEO_1_INUSE) {
+         SaveVideoRegister(pVia, V_COLOR_KEY, keyLow);
++        SaveVideoRegister(pVia, SND_COLOR_KEY, keyLow);
+     } else {
+         if (pVia->HWDiff.dwSupportTwoColorKey)    /*CLE_C0 */
+             SaveVideoRegister(pVia, V3_COLOR_KEY, keyLow);
+@@ -1561,8 +1660,9 @@ SetHQVFetch(VIAPtr pVia, CARD32 srcFetch, unsigned
+         srcFetch >>= 3;  /* fetch unit is 8 bytes */
+     }
+ 
+-    SaveVideoRegister(pVia, HQV_SRC_FETCH_LINE + proReg,
+-                      ((srcFetch - 1) << 16) | (srcHeight - 1));
++    if (pVia->ChipId != PCI_CHIP_VT3409)
++        SaveVideoRegister(pVia, HQV_SRC_FETCH_LINE + proReg,
++                          ((srcFetch - 1) << 16) | (srcHeight - 1));
+ }
+ 
+ static void
+@@ -1713,13 +1813,14 @@ Upd_Video(ScrnInfoPtr pScrn, unsigned long videoFl
+     unsigned long zoomCtl = 0, miniCtl = 0;
+     unsigned long hqvCtl = 0;
+     unsigned long hqvFilterCtl = 0, hqvMiniCtl = 0;
++    unsigned long hqvScaleCtlH = 0, hqvScaleCtlV = 0;
+     unsigned long haveHQVzoomH = 0, haveHQVzoomV = 0;
+     unsigned long hqvSrcWidth = 0, hqvDstWidth = 0;
+     unsigned long hqvSrcFetch = 0, hqvOffset = 0;
+     unsigned long dwOffset = 0, fetch = 0, tmp = 0;
+     unsigned long proReg = 0;
+ 
+-    DBG_DD(ErrorF("videoflag=%p\n", videoFlag));
++    DBG_DD(ErrorF("videoflag=%ld\n", videoFlag));
+ 
+     if (pVia->ChipId == PCI_CHIP_VT3259 && !(videoFlag & VIDEO_1_INUSE))
+         proReg = PRO_HQV1_OFFSET;
+@@ -1762,16 +1863,16 @@ Upd_Video(ScrnInfoPtr pScrn, unsigned long videoFl
+ 
+     /* 
+      * FIXME:
+-     * Enable video on secondary 
++     * Enable video on secondary (change Panel to SecondCRTC?)
+      */
+     if ((pVia->VideoEngine == VIDEO_ENGINE_CME
+          || pVia->Chipset == VIA_VM800)
+         && pVia->pBIOSInfo->Panel->IsActive) {
+ 
+         /* V1_ON_SND_DISPLAY */
+-        vidCtl |= 0x80000000;
++        vidCtl |= V1_ON_SND_DISPLAY;
+         /* SECOND_DISPLAY_COLOR_KEY_ENABLE */
+-        compose |= 0x00010000 | 0x1;
++        compose |= SECOND_DISPLAY_COLOR_KEY_ENABLE | 0x1;
+     }
+ 
+     viaOverlayGetV1V3Format(pVia, (videoFlag & VIDEO_1_INUSE) ? 1 : 3,
+@@ -1925,7 +2026,7 @@ Upd_Video(ScrnInfoPtr pScrn, unsigned long videoFl
+ 
+     if (!viaOverlayHQVCalcZoomWidth(pVia, videoFlag, srcWidth, dstWidth,
+                                     &zoomCtl, &miniCtl, &hqvFilterCtl,
+-                                    &hqvMiniCtl, &haveHQVzoomH)) {
++                                    &hqvMiniCtl, &hqvScaleCtlH, &haveHQVzoomH)) {
+         /* Need to scale (minify) too much - can't handle it. */
+         SetFetch(pVia, videoFlag, fetch);
+         FireVideoCommand(pVia, videoFlag, compose);
+@@ -1964,7 +2065,7 @@ Upd_Video(ScrnInfoPtr pScrn, unsigned long videoFl
+ 
+     if (!viaOverlayHQVCalcZoomHeight(pVia, srcHeight, dstHeight, &zoomCtl,
+                                      &miniCtl, &hqvFilterCtl, &hqvMiniCtl,
+-                                     &haveHQVzoomV)) {
++                                     &hqvScaleCtlV, &haveHQVzoomV)) {
+         /* Need to scale (minify) too much - can't handle it. */
+         FireVideoCommand(pVia, videoFlag, compose);
+         FlushVidRegBuffer(pVia);
+@@ -2008,8 +2109,13 @@ Upd_Video(ScrnInfoPtr pScrn, unsigned long videoFl
+                 hqvFilterCtl &= 0xfffdffff;
+             SetMiniAndZoom(pVia, videoFlag, 0, 0);
+         }
+-        SaveVideoRegister(pVia, HQV_MINIFY_CONTROL + proReg, hqvMiniCtl);
+-        SaveVideoRegister(pVia, HQV_FILTER_CONTROL + proReg, hqvFilterCtl);
++		if (hwDiff->dwNewScaleCtl) {
++        	SaveVideoRegister(pVia, HQV_H_SCALE_CONTROL + proReg, hqvScaleCtlH);
++        	SaveVideoRegister(pVia, HQV_V_SCALE_CONTROL + proReg, hqvScaleCtlV);
++		} else {
++        	SaveVideoRegister(pVia, HQV_MINIFY_CONTROL + proReg, hqvMiniCtl);
++		}
++       	SaveVideoRegister(pVia, HQV_FILTER_CONTROL + proReg, hqvFilterCtl);
+     } else
+         SetMiniAndZoom(pVia, videoFlag, miniCtl, zoomCtl);
+ 
+@@ -2022,11 +2128,24 @@ Upd_Video(ScrnInfoPtr pScrn, unsigned long videoFl
+                                miniCtl, compose);
+ 
+     if (pVia->VideoEngine == VIDEO_ENGINE_CME) {
+-        VIDOutD(HQV_SRC_DATA_OFFSET_CONTROL1,0);
+-        VIDOutD(HQV_SRC_DATA_OFFSET_CONTROL3,((pUpdate->SrcRight - 1 ) << 16) | (pUpdate->SrcBottom - 1));
++        SaveVideoRegister(pVia, HQV_CME_REG(hwDiff, HQV_SDO_CTRL1),0);
++        SaveVideoRegister(pVia, HQV_CME_REG(hwDiff, HQV_SDO_CTRL3),((pUpdate->SrcRight - 1 ) << 16) | (pUpdate->SrcBottom - 1));
+         if (pVia->Chipset == VIA_VX800 || pVia->Chipset == VIA_VX855) {
+-            VIDOutD(HQV_SRC_DATA_OFFSET_CONTROL2,0);
+-            VIDOutD(HQV_SRC_DATA_OFFSET_CONTROL4,((pUpdate->SrcRight - 1 ) << 16) | (pUpdate->SrcBottom - 1));
++            SaveVideoRegister(pVia, HQV_CME_REG(hwDiff, HQV_SDO_CTRL2),0);
++            SaveVideoRegister(pVia, HQV_CME_REG(hwDiff, HQV_SDO_CTRL4),((pUpdate->SrcRight - 1 ) << 16) | (pUpdate->SrcBottom - 1));
++            if (pVia->Chipset == VIA_VX855) {
++                SaveVideoRegister(pVia, HQV_DST_DATA_OFFSET_CTRL1,0);
++                SaveVideoRegister(pVia, HQV_DST_DATA_OFFSET_CTRL3,((pUpdate->SrcRight - 1 ) << 16) | (pUpdate->SrcBottom - 1));
++                SaveVideoRegister(pVia, HQV_DST_DATA_OFFSET_CTRL2,0);
++                SaveVideoRegister(pVia, HQV_DST_DATA_OFFSET_CTRL4,((pUpdate->SrcRight - 1 ) << 16) | (pUpdate->SrcBottom - 1));
++                SaveVideoRegister(pVia, HQV_BACKGROUND_DATA_OFFSET,((pUpdate->SrcRight - 1 ) << 16) | (pUpdate->SrcBottom - 1));
++                SaveVideoRegister(pVia, HQV_EXTENDED_CONTROL,0);
++                /*0x3e0*/
++                SaveVideoRegister(pVia, HQV_SUBP_HSCALE_CTRL,0);
++                /*0x3e8*/
++                SaveVideoRegister(pVia, HQV_SUBP_VSCALE_CTRL,0);
++                SaveVideoRegister(pVia, HQV_DEFAULT_VIDEO_COLOR, HQV_FIX_COLOR);
++            }
+         }
+     }
+ 
+@@ -2062,9 +2181,6 @@ Upd_Video(ScrnInfoPtr pScrn, unsigned long videoFl
+                     usleep(1);
+                 }
+ 
+-                if (pVia->VideoEngine == VIDEO_ENGINE_CME)
+-                    hqvCtl |= HQV_GEN_IRQ;
+-
+                 VIDOutD(HQV_CONTROL + proReg, hqvCtl & ~HQV_SW_FLIP);
+                 VIDOutD(HQV_CONTROL + proReg, hqvCtl | HQV_SW_FLIP);
+ 
+Index: src/via_driver.h
+===================================================================
+--- src/via_driver.h	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_driver.h	(.../trunk)	(revision 916)
+@@ -127,9 +127,10 @@ typedef struct {
+     CARD8   SR27, SR28, SR29, SR2A,SR2B,SR2C,SR2D,SR2E;
+     CARD8   SR2F, SR30, SR31, SR32,SR33,SR34,SR40,SR41;
+     CARD8   SR42, SR43, SR44, SR45,SR46,SR47,SR48,SR49;
+-    CARD8   SR4A, SR4B, SR4C;
++    CARD8   SR4A, SR4B, SR4C, SR4D;
+ 
+     /*   extended CRTC registers */
++    CARD8   CR0C, CR0D;
+     CARD8   CR13, CR30, CR31, CR32, CR33, CR34, CR35, CR36;
+     CARD8   CR37, CR38, CR39, CR3A, CR40, CR41, CR42, CR43;
+     CARD8   CR44, CR45, CR46, CR47, CR48, CR49, CR4A;
+@@ -142,7 +143,7 @@ typedef struct {
+ } VIARegRec, *VIARegPtr;
+ 
+ /*
+- * varables that need to be shared among different screens.
++ * variables that need to be shared among different screens.
+  */
+ typedef struct {
+     Bool b3DRegsInitialized;
+@@ -285,6 +286,7 @@ typedef struct _VIA {
+     Bool                agpDMA;
+     Bool                nPOT[VIA_NUM_TEXUNITS];
+     const unsigned     *TwodRegs;
++    const unsigned     *HqvCmeRegs;
+     ExaDriverPtr        exaDriverPtr;
+     ExaOffscreenArea   *exa_scratch;
+     unsigned int        exa_scratch_next;
+@@ -412,16 +414,18 @@ typedef struct _VIA {
+     void                *cursorMap;
+     CARD32              cursorOffset;
+ 
++    CARD8               I2CDevices;	/* Option */
++
+ #ifdef HAVE_DEBUG
+     Bool                disableXvBWCheck;
+     Bool                DumpVGAROM;
+     Bool                PrintVGARegs;
+     Bool                PrintTVRegs;
+     Bool                I2CScan;
++#endif /* HAVE_DEBUG */
+     
+     Bool                UseLegacyModeSwitch ;
+     video_via_regs*     VideoRegs ;
+-#endif /* HAVE_DEBUG */
+ } VIARec, *VIAPtr;
+ 
+ #define VIAPTR(p) ((VIAPtr)((p)->driverPrivate))
+@@ -433,7 +437,7 @@ typedef struct
+     Bool HasSecondary;
+     Bool BypassSecondary;
+     /*These two registers are used to make sure the CRTC2 is
+-      retored before CRTC_EXT, otherwise it could lead to blank screen.*/
++      restored before CRTC_EXT, otherwise it could lead to blank screen.*/
+     Bool IsSecondaryRestored;
+     Bool RestorePrimary;
+ 
+Index: src/via_bios.h
+===================================================================
+--- src/via_bios.h	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_bios.h	(.../trunk)	(revision 916)
+@@ -82,6 +82,11 @@
+ #define	    VIA_DEVICE_TV		    0x04
+ #define	    VIA_DEVICE_DFP		    0x08
+ 
++#define     VIA_I2C_NONE                    0x00
++#define     VIA_I2C_BUS1                    0x01
++#define     VIA_I2C_BUS2                    0x02
++#define     VIA_I2C_BUS3                    0x04
++
+ /* System Memory CLK */
+ #define VIA_MEM_SDR66   0x00
+ #define VIA_MEM_SDR100  0x01
+@@ -92,7 +97,9 @@
+ #define VIA_MEM_DDR400  0x06
+ #define VIA_MEM_DDR533  0x07
+ #define VIA_MEM_DDR667  0x08
+-#define VIA_MEM_END     0x09
++#define VIA_MEM_DDR800  0x09
++#define VIA_MEM_DDR1066 0x0A
++#define VIA_MEM_END     0x0B
+ #define VIA_MEM_NONE    0xFF
+ 
+ /* Digital Output Bus Width */
+Index: src/via_swov.h
+===================================================================
+--- src/via_swov.h	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_swov.h	(.../trunk)	(revision 916)
+@@ -53,7 +53,7 @@ typedef struct __VIAHWDiff
+ {
+     unsigned long dwThreeHQVBuffer;    /* Use Three HQV Buffers */
+     /* unsigned long dwV3SrcHeightSetting; *//* Set Video Source Width and Height */
+-    /* unsigned long dwSupportExtendFIFO; *//* Support Extand FIFO */
++    /* unsigned long dwSupportExtendFIFO; *//* Support Extend FIFO */
+     unsigned long dwHQVFetchByteUnit;  /* HQV Fetch Count unit is byte */
+     unsigned long dwHQVInitPatch;      /* Initialize HQV Engine 2 times */
+     /*unsigned long dwSupportV3Gamma; *//* Support V3 Gamma */
+@@ -73,6 +73,8 @@ typedef struct __VIAHWDiff
+     /*unsigned long dwV3FIFOPatch; *//* For CLE V3 FIFO Bug (srcWidth <= 8) */
+     unsigned long dwSupportTwoColorKey;	/* Support two color key */
+     /* unsigned long dwCxColorSpace; *//* CLE_Cx ColorSpace */
++    unsigned dwNewScaleCtl; /* Use new HQV scale engine code */
++    const unsigned *HQVCmeRegs; /* Which set of CME regs to use for newer chipsets */
+ } VIAHWDiff;
+ 
+ void VIAVidHWDiffInit(ScrnInfoPtr pScrn);
+Index: src/via_bandwidth.c
+===================================================================
+--- src/via_bandwidth.c	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_bandwidth.c	(.../trunk)	(revision 916)
+@@ -194,6 +194,7 @@ ViaSetPrimaryFIFO(ScrnInfoPtr pScrn, DisplayModePt
+             else
+                 ViaSeqMask(hwp, 0x22, 0x00, 0x1F);  /* 128/4 = overflow = 0 */
+             break;
++        /* PM800/PM880/CN400 */
+         case VIA_PM800:
+             hwp->writeSeq(hwp, 0x17, 0x5F);     /* 95 */
+             ViaSeqMask(hwp, 0x16, 0x20, 0xBF);  /* 32 */
+@@ -204,9 +205,10 @@ ViaSetPrimaryFIFO(ScrnInfoPtr pScrn, DisplayModePt
+             else
+                 ViaSeqMask(hwp, 0x22, 0x1F, 0x1F);  /* 31 */
+             break;
++        /* P4M800Pro/VN800/CN700 */ 
+         case VIA_VM800:
+             hwp->writeSeq(hwp, 0x17, 0x2F);
+-            ViaSeqMask(hwp, 0x16, 0x14, 0xBF);
++            ViaSeqMask(hwp, 0x16, 0x14, 0xBF);  /* 80/4    = 20  = 0x14 */
+             ViaSeqMask(hwp, 0x18, 0x08, 0xBF);
+ 
+             if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32))
+@@ -215,40 +217,60 @@ ViaSetPrimaryFIFO(ScrnInfoPtr pScrn, DisplayModePt
+                 ViaSeqMask(hwp, 0x22, 0x00, 0x1F);
+             break;
+         case VIA_K8M890:
+-            hwp->writeSeq(hwp, 0x16, 0x92);
+-            hwp->writeSeq(hwp, 0x17, 0xB3);
+-            hwp->writeSeq(hwp, 0x18, 0x8A);
++            /* depth location: {SR17,0,7} */
++            hwp->writeSeq(hwp, 0x17, 0xB3);    /* 360/2-1 = 179 = 0xB3 */
++            /* Formula (x & 0x3F) | ((x & 0x40) << 1) */
++            /* threshold location: {SR16,0,5},{SR16,7,7} */
++            ViaSeqMask(hwp, 0x16, 0x92, 0xBF); /* 328/4   = 82  = 0x52 */
++            /* high threshold location: {SR18,0,5},{SR18,7,7} */
++            ViaSeqMask(hwp, 0x18, 0x8A, 0xBF); /* 296/4   = 74  = 0x4A */
++            /* display queue expire num location: {SR22,0,4}. */
++            ViaSeqMask(hwp, 0x22, 0x1F, 0x1F); /* 124/4   = 31  = 0x1F */
+             break;
+         case VIA_P4M900:
+-            ViaSeqMask(hwp, 0x17, 0x2F, 0xFF);
+-            ViaSeqMask(hwp, 0x16, 0x13, 0x3F);
+-            ViaSeqMask(hwp, 0x16, 0x00, 0x80);
+-            ViaSeqMask(hwp, 0x18, 0x13, 0x3F);
+-            ViaSeqMask(hwp, 0x18, 0x00, 0x80);
++            /* location: {SR17,0,7} */
++            hwp->writeSeq(hwp, 0x17, 0x2F);    /* 96/2-1  = 47  = 0x2F */
++            /* location: {SR16,0,5},{SR16,7,7} */
++            ViaSeqMask(hwp, 0x16, 0x13, 0xBF); /* 76/4    = 19  = 0x13 */
++            /* location: {SR18,0,5},{SR18,7,7} */
++            ViaSeqMask(hwp, 0x18, 0x13, 0xBF); /* 76/4    = 19  = 0x13 */
++            /* location: {SR22,0,4}. */
++            ViaSeqMask(hwp, 0x22, 0x08, 0x1F); /* 32/4    = 8   = 0x08 */
+             break;
+         case VIA_P4M890:
+-            hwp->writeSeq(hwp, 0x16, 0x13);
+-            hwp->writeSeq(hwp, 0x17, 0x2F);
+-            hwp->writeSeq(hwp, 0x18, 0x53);
+-            hwp->writeSeq(hwp, 0x22, 0x10);
++            hwp->writeSeq(hwp, 0x17, 0x2F);      /* 96/2-1  = 47  = 0x2F */
++            ViaSeqMask(hwp, 0x16, 0x13, 0xBF);   /* 76/4    = 19  = 0x13 */
++            ViaSeqMask(hwp, 0x18, 0x10, 0xBF);   /* 64/4    = 16  = 0x10 */
++            ViaSeqMask(hwp, 0x22, 0x08, 0x1F);   /* 32/4    = 8   = 0x08 */
+             break;
+         case VIA_CX700:
+-            hwp->writeSeq(hwp, 0x16, 0x26);
+             hwp->writeSeq(hwp, 0x17, 0x5F);
+-            hwp->writeSeq(hwp, 0x18, 0x66);
+-            hwp->writeSeq(hwp, 0x22, 0x1F);
++            ViaSeqMask(hwp, 0x16, 0x20, 0xBF);   /* 128/4  = 32  = 0x20 */
++            ViaSeqMask(hwp, 0x18, 0x20, 0xBF);   /* 128/4  = 32  = 0x20 */
++            ViaSeqMask(hwp, 0x22, 0x1F, 0x1F);   /* 124/4  = 31  = 0x1F */
+             break;
+         case VIA_VX800:
+-            hwp->writeSeq(hwp, 0x16, 0x26); /* 152/4   = 38 */
+-            hwp->writeSeq(hwp, 0x17, 0x5F); /* 192/2-1 = 95 */
++            hwp->writeSeq(hwp, 0x17, 0x5F); /* 192/2-1 = 95   = 0x5F */
++            hwp->writeSeq(hwp, 0x16, 0x26); /* 152/4   = 38   = 0x26 */
+             hwp->writeSeq(hwp, 0x18, 0x26); /* 152/4   = 38 */ 
+             hwp->writeSeq(hwp, 0x22, 0x10); /*  64/4   = 16 */
+             break;
+         case VIA_VX855:
+-              hwp->writeSeq(hwp, 0x16, 0x50); /* 320/4   = 80 */
+-              hwp->writeSeq(hwp, 0x17, 0xC7); /* 400/2-1 = 199 */
+-              hwp->writeSeq(hwp, 0x18, 0x50); /* 320/4   = 80 */
+-              hwp->writeSeq(hwp, 0x22, 0x28); /* 160/4   = 40 */
++            hwp->writeSeq(hwp, 0x17, 0xC7); /* 400/2-1 = 199  = 0xC7 */
++            /* Formula for {SR16,0,5},{SR16,7,7} is: (0x50 & 0x3F) | ((0x50 & 0x40) << 1) = 0x90 */
++            hwp->writeSeq(hwp, 0x16, 0x90); /* 320/4   = 80   = 0x50 */
++            /* Formula for {SR18,0,5},{SR18,7,7} is: (0x50 & 0x3F) | ((0x50 & 0x40) << 1) = 0x90 */
++            hwp->writeSeq(hwp, 0x18, 0x90); /* 320/4   = 80   = 0x50 */
++            hwp->writeSeq(hwp, 0x22, 0x28); /* 160/4   = 40   = 0x28 */
++            break;
++        case VIA_VX900:
++            hwp->writeSeq(hwp, 0x17, 0xC7); /* 400/2-1 = 199  = 0xC7 */
++            /* Formula for {SR16,0,5},{SR16,7,7} is: (0x50 & 0x3F) | ((0x50 & 0x40) << 1) = 0x90 */
++            hwp->writeSeq(hwp, 0x16, 0x90); /* 320/4   = 80   = 0x50 */
++            /* Formula for {SR18,0,5},{SR18,7,7} is: (0x50 & 0x3F) | ((0x50 & 0x40) << 1) = 0x90 */
++            hwp->writeSeq(hwp, 0x18, 0x90); /* 320/4   = 80   = 0x50 */
++            hwp->writeSeq(hwp, 0x22, 0x28); /* 160/4   = 40   = 0x28 */
++            break;
+         default:
+             xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaSetPrimaryFIFO: "
+                        "Chipset %d not implemented\n", pVia->Chipset);
+@@ -371,7 +393,38 @@ ViaSetSecondaryFIFO(ScrnInfoPtr pScrn, DisplayMode
+                 ViaCrtcMask(hwp, 0x94, 0x20, 0x7F);
+             break;
+         case VIA_P4M890:
++            /* depth location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
++            ViaCrtcMask(hwp, 0x68, 0xB0, 0xF0); /* 96/8-1 = 11  = 0x0B */
++            ViaCrtcMask(hwp, 0x94, 0x00, 0x80);
++            ViaCrtcMask(hwp, 0x95, 0x00, 0x80);
++
++            /* location: {CR68,0,3},{CR95,4,6} */
++            ViaCrtcMask(hwp, 0x68, 0x03, 0x0F); /* 76/4   = 19  = 0x13 */
++            ViaCrtcMask(hwp, 0x95, 0x10, 0x70);
++
++            /* location: {CR92,0,3},{CR95,0,2} */
++            ViaCrtcMask(hwp, 0x92, 0x00, 0x0F); /* 64/4   = 16  = 0x10 */
++            ViaCrtcMask(hwp, 0x95, 0x01, 0x07);
++
++            /* location: {CR94,0,6} */
++            ViaCrtcMask(hwp, 0x94, 0x08, 0x7F); /* 32/4   = 8   = 0x08 */
++            break;
+         case VIA_K8M890:
++            /* Display Queue Depth, location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
++            ViaCrtcMask(hwp, 0x68, 0xC0, 0xF0); /* 360/8-1 = 44  = 0x2C; 0x2C << 4 = 0xC0 */
++            ViaCrtcMask(hwp, 0x94, 0x00, 0x80); /* 0x2C << 3 = 0x00 */
++            ViaCrtcMask(hwp, 0x95, 0x80, 0x80); /* 0x2C << 2 = 0x80 */
++
++            /* Display Queue Read Threshold 1, location: {CR68,0,3},{CR95,4,6} */
++            ViaCrtcMask(hwp, 0x68, 0x02, 0x0F); /* 328/4   = 82  = 0x52 */
++            ViaCrtcMask(hwp, 0x95, 0x50, 0x70);
++
++            /* location: {CR92,0,3},{CR95,0,2} */
++            ViaCrtcMask(hwp, 0x92, 0x0A, 0x0F); /* 296/4   = 74  = 0x4A */
++            ViaCrtcMask(hwp, 0x95, 0x04, 0x07); /* 0x4A >> 4 = 0x04 */
++
++            /* Display Expire Number Bits, location: {CR94,0,6} */
++            ViaCrtcMask(hwp, 0x94, 0x1F, 0x7F); /* 124/4   = 31  = 0x1F */
+             break;
+         case VIA_P4M900:
+             ViaCrtcMask(hwp, 0x68, 0xB0, 0xF0);
+@@ -402,8 +455,8 @@ ViaSetSecondaryFIFO(ScrnInfoPtr pScrn, DisplayMode
+             break;
+         case VIA_VX800:
+             /* {CR68,4,7},{CR94,7,7},{CR95,7,7} : 96/8-1 = 0x0B */
+-            ViaCrtcMask(hwp, 0x68, 0xA0, 0xF0); 
+-            ViaCrtcMask(hwp, 0x94, 0x00, 0x80);
++            ViaCrtcMask(hwp, 0x68, 0xB0, 0xF0); /* ((0x0B & 0x0F) << 4)) = 0xB0 */
++            ViaCrtcMask(hwp, 0x94, 0x00, 0x80); /* ((0x0B & 0x10) << 3)) = 0x00 */
+             ViaCrtcMask(hwp, 0x95, 0x00, 0x80);
+             /* {CR68,0,3},{CR95,4,6} : 64/4 = 0x10 */
+             ViaCrtcMask(hwp, 0x68, 0x04, 0x0F);
+@@ -418,7 +471,39 @@ ViaSetSecondaryFIFO(ScrnInfoPtr pScrn, DisplayMode
+                 ViaCrtcMask(hwp, 0x94, 0x20, 0x7F);
+             break;
+         case VIA_VX855:
++            /* {CR68,4,7},{CR94,7,7},{CR95,7,7} : 200/8-1 = 24 = 0x18 */
++            ViaCrtcMask(hwp, 0x68, 0x80, 0xF0); /* ((0x18 & 0x0F) << 4)) = 0x80 */
++            ViaCrtcMask(hwp, 0x94, 0x80, 0x80); /* ((0x18 & 0x10) << 3)) = 0x80 */
++            ViaCrtcMask(hwp, 0x95, 0x00, 0x80); /* ((0x18 & 0x20) << 2)) = 0x00 */
++            /* {CR68,0,3},{CR95,4,6} : 160/4 = 0x28 */
++            ViaCrtcMask(hwp, 0x68, 0x08, 0x0F); /* (0x28 & 0x0F) = 0x08 */
++            ViaCrtcMask(hwp, 0x95, 0x20, 0x70); /* (0x28 & 0x70) = 0x20 */
++            /* {CR92,0,3},{CR95,0,2} : 160/4 = 0x28 */
++            ViaCrtcMask(hwp, 0x92, 0x08, 0x08); /* (0x28 & 0x0F) = 0x08 */
++            ViaCrtcMask(hwp, 0x95, 0x02, 0x07); /* ((0x28 & 0x70) >> 4)) = 0x02 */
++            /* {CR94,0,6} : 320/4 = 0x50 */
++            if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32))
++                ViaCrtcMask(hwp, 0x94, 0x08, 0x7F);
++            else
++                ViaCrtcMask(hwp, 0x94, 0x08, 0x7F);
+             break;
++        case VIA_VX900:
++            /* {CR68,4,7},{CR94,7,7},{CR95,7,7} : 192/8-1 = 23 = 0x17 */
++            ViaCrtcMask(hwp, 0x68, 0x70, 0xF0); /* ((0x17 & 0x0F) << 4)) = 0x70 */
++            ViaCrtcMask(hwp, 0x94, 0x80, 0x80); /* ((0x17 & 0x10) << 3)) = 0x80 */
++            ViaCrtcMask(hwp, 0x95, 0x00, 0x80); /* ((0x17 & 0x20) << 2)) = 0x00 */
++            /* {CR68,0,3},{CR95,4,6} : 160/4 = 0x28 */
++            ViaCrtcMask(hwp, 0x68, 0x08, 0x0F); /* (0x28 & 0x0F) = 0x08 */
++            ViaCrtcMask(hwp, 0x95, 0x20, 0x70); /* (0x28 & 0x70) = 0x20 */
++            /* {CR92,0,3},{CR95,0,2} : 160/4 = 0x28 */
++            ViaCrtcMask(hwp, 0x92, 0x08, 0x08); /* (0x28 & 0x0F) = 0x08 */
++            ViaCrtcMask(hwp, 0x95, 0x02, 0x07); /* ((0x28 & 0x70) >> 4)) = 0x2 */
++            /* {CR94,0,6} : 320/4 = 0x50 */
++            if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32))
++                ViaCrtcMask(hwp, 0x94, 0x08, 0x7F);
++            else
++                ViaCrtcMask(hwp, 0x94, 0x08, 0x7F);
++            break;
+         default:
+             xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaSetSecondaryFIFO: "
+                        "Chipset %d not implemented\n", pVia->Chipset);
+Index: src/via_accel.c
+===================================================================
+--- src/via_accel.c	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_accel.c	(.../trunk)	(revision 916)
+@@ -196,6 +196,7 @@ viaFlushPCI(ViaCommandBuffer * buf)
+ 					switch (pVia->Chipset) {
+ 					    case VIA_VX800:
+ 					    case VIA_VX855:
++					    case VIA_VX900:
+ 							while ((VIAGETREG(VIA_REG_STATUS) &
+ 							       (VIA_CMD_RGTR_BUSY_H5 | VIA_2D_ENG_BUSY_H5))
+ 									&& (loop++ < MAXLOOP)) ;
+@@ -287,7 +288,7 @@ viaSetupCBuffer(ScrnInfoPtr pScrn, ViaCommandBuffe
+ 
+     buf->pScrn = pScrn;
+     buf->bufSize = ((size == 0) ? VIA_DMASIZE : size) >> 2;
+-    buf->buf = (CARD32 *) xcalloc(buf->bufSize, sizeof(CARD32));
++    buf->buf = (CARD32 *) calloc(buf->bufSize, sizeof(CARD32));
+     if (!buf->buf)
+         return BadAlloc;
+     buf->waitFlags = 0;
+@@ -312,7 +313,7 @@ void
+ viaTearDownCBuffer(ViaCommandBuffer * buf)
+ {
+     if (buf && buf->buf)
+-        xfree(buf->buf);
++        free(buf->buf);
+     buf->buf = NULL;
+ }
+ 
+@@ -417,6 +418,9 @@ viaDisableVQ(ScrnInfoPtr pScrn)
+     switch (pVia->Chipset) {
+         case VIA_K8M890:
+         case VIA_P4M900:
++        case VIA_VX800:
++        case VIA_VX855:
++        case VIA_VX900:
+             VIASETREG(0x41c, 0x00100000);
+             VIASETREG(0x420, 0x74301000);
+             break;
+@@ -472,16 +476,25 @@ viaInitialize2DEngine(ScrnInfoPtr pScrn)
+         VIASETREG(i, 0x0);
+     }
+ 
+-    if (pVia->Chipset == VIA_VX800 || pVia->Chipset == VIA_VX855) {
+-        for (i = 0x44; i < 0x5c; i += 4) {
++    if (pVia->Chipset == VIA_VX800 || 
++        pVia->Chipset == VIA_VX855 ||
++        pVia->Chipset == VIA_VX900) {
++        for (i = 0x44; i <= 0x5c; i += 4) {
+             VIASETREG(i, 0x0);
+         }
+     }
+ 
++    if (pVia->Chipset == VIA_VX900)
++    {
++        /*410 redefine 0x30 34 38*/
++        VIASETREG(0x60, 0x0); /*already useable here*/
++    }
++
+     /* Make the VIA_REG() macro magic work */
+     switch (pVia->Chipset) {
+     case VIA_VX800:
+     case VIA_VX855:
++    case VIA_VX900:
+         pVia->TwodRegs = via_2d_regs_m1;
+         break;
+     default:
+@@ -492,6 +505,9 @@ viaInitialize2DEngine(ScrnInfoPtr pScrn)
+     switch (pVia->Chipset) {
+         case VIA_K8M890:
+         case VIA_P4M900:
++        case VIA_VX800:
++        case VIA_VX855:
++        case VIA_VX900:
+             viaInitPCIe(pVia);
+             break;
+         default:
+@@ -503,6 +519,9 @@ viaInitialize2DEngine(ScrnInfoPtr pScrn)
+         switch (pVia->Chipset) {
+             case VIA_K8M890:
+             case VIA_P4M900:
++            case VIA_VX800:
++            case VIA_VX855:
++            case VIA_VX900:
+                 viaEnablePCIeVQ(pVia);
+                 break;
+             default:
+@@ -530,6 +549,7 @@ viaAccelSync(ScrnInfoPtr pScrn)
+     switch (pVia->Chipset) {
+         case VIA_VX800:
+         case VIA_VX855:
++        case VIA_VX900:
+             while ((VIAGETREG(VIA_REG_STATUS) &
+                     (VIA_CMD_RGTR_BUSY_H5 | VIA_2D_ENG_BUSY_H5 | VIA_3D_ENG_BUSY_H5))
+                    && (loop++ < MAXLOOP)) ;
+@@ -590,7 +610,9 @@ viaPitchHelper(VIAPtr pVia, unsigned dstPitch, uns
+     unsigned val = (dstPitch >> 3) << 16 | (srcPitch >> 3);
+     RING_VARS;
+ 
+-    if (pVia->Chipset != VIA_VX800 && pVia->Chipset != VIA_VX855) {
++    if (pVia->Chipset != VIA_VX800 &&
++        pVia->Chipset != VIA_VX855 && 
++        pVia->Chipset != VIA_VX900) {
+         val |= VIA_PITCH_ENABLE;
+     }
+     OUT_RING_H1(VIA_REG(pVia, PITCH), val);
+@@ -759,6 +781,7 @@ viaSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, i
+     tdc->cmd = cmd;
+     viaAccelTransparentHelper(pVia, (trans_color != -1) ? 0x4000 : 0x0000,
+                               trans_color, FALSE);
++    ADVANCE_RING;
+ }
+ 
+ static void
+@@ -796,6 +819,7 @@ viaSetupForSolidFill(ScrnInfoPtr pScrn, int color,
+     tdc->cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(rop);
+     tdc->fgColor = color;
+     viaAccelTransparentHelper(pVia, 0x00, 0x00, FALSE);
++    ADVANCE_RING;
+ }
+ 
+ static void
+@@ -852,6 +876,7 @@ viaSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, i
+     tdc->pattern0 = pattern0;
+     tdc->pattern1 = pattern1;
+     viaAccelTransparentHelper(pVia, 0x00, 0x00, FALSE);
++    ADVANCE_RING;
+ }
+ 
+ static void
+@@ -901,6 +926,7 @@ viaSetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
+     tdc->patternAddr = (patternx * pVia->Bpp + patterny * pVia->Bpl);
+     viaAccelTransparentHelper(pVia, (trans_color != -1) ? 0x4000 : 0x0000,
+                               trans_color, FALSE);
++    ADVANCE_RING;
+ }
+ 
+ static void
+@@ -962,9 +988,9 @@ viaSetupForCPUToScreenColorExpandFill(ScrnInfoPtr
+     tdc->fgColor = fg;
+     tdc->bgColor = bg;
+ 
++    viaAccelTransparentHelper(pVia, 0x0, 0x0, FALSE);
++
+     ADVANCE_RING;
+-
+-    viaAccelTransparentHelper(pVia, 0x0, 0x0, FALSE);
+ }
+ 
+ static void
+@@ -991,7 +1017,7 @@ viaSubsequentScanlineCPUToScreenColorExpandFill(Sc
+                        pScrn->fbOffset + sub * pVia->Bpl, tdc->mode,
+                        pVia->Bpl, pVia->Bpl, tdc->cmd);
+ 
+-    viaFlushPCI(cb);
++    ADVANCE_RING;
+     viaDisableClipping(pScrn);
+ }
+ 
+@@ -1005,9 +1031,9 @@ viaSetupForImageWrite(ScrnInfoPtr pScrn, int rop,
+     RING_VARS;
+ 
+     tdc->cmd = VIA_GEC_BLT | VIA_GEC_SRC_SYS | VIAACCELCOPYROP(rop);
+-    ADVANCE_RING;
+     viaAccelTransparentHelper(pVia, (trans_color != -1) ? 0x4000 : 0x0000,
+                               trans_color, FALSE);
++    ADVANCE_RING;
+ }
+ 
+ static void
+@@ -1030,7 +1056,7 @@ viaSubsequentImageWriteRect(ScrnInfoPtr pScrn, int
+                        pScrn->fbOffset + pVia->Bpl * sub, tdc->mode,
+                        pVia->Bpl, pVia->Bpl, tdc->cmd);
+ 
+-    viaFlushPCI(cb);
++    ADVANCE_RING;
+     viaDisableClipping(pScrn);
+ }
+ 
+@@ -1052,6 +1078,7 @@ viaSetupForSolidLine(ScrnInfoPtr pScrn, int color,
+     OUT_RING_H1(VIA_REG(pVia, GEMODE), tdc->mode);
+     OUT_RING_H1(VIA_REG(pVia, MONOPAT0), 0xFF);
+     OUT_RING_H1(VIA_REG(pVia, MONOPATFGC), tdc->fgColor);
++    ADVANCE_RING;
+ }
+ 
+ static void
+@@ -1189,6 +1216,7 @@ viaSetupForDashedLine(ScrnInfoPtr pScrn, int fg, i
+     OUT_RING_H1(VIA_REG(pVia, MONOPATFGC), tdc->fgColor);
+     OUT_RING_H1(VIA_REG(pVia, MONOPATBGC), tdc->bgColor);
+     OUT_RING_H1(VIA_REG(pVia, MONOPAT0), tdc->pattern0);
++    ADVANCE_RING;
+ }
+ 
+ static void
+@@ -1210,7 +1238,8 @@ viaInitXAA(ScreenPtr pScreen)
+ 
+     /* General acceleration flags. */
+     xaaptr->Flags = (PIXMAP_CACHE |
+-                     OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER |
++                     OFFSCREEN_PIXMAPS | 
++                     LINEAR_FRAMEBUFFER |
+                      MICROSOFT_ZERO_LINE_BIAS | 0);
+ 
+     if (pScrn->bitsPerPixel == 8)
+@@ -1218,24 +1247,29 @@ viaInitXAA(ScreenPtr pScreen)
+ 
+     xaaptr->SetClippingRectangle = viaSetClippingRectangle;
+     xaaptr->DisableClipping = viaDisableClipping;
+-    xaaptr->ClippingFlags = (HARDWARE_CLIP_SOLID_FILL |
+-                             HARDWARE_CLIP_SOLID_LINE |
+-                             HARDWARE_CLIP_DASHED_LINE |
+-                             HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
++    xaaptr->ClippingFlags = (HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
+                              HARDWARE_CLIP_MONO_8x8_FILL |
+                              HARDWARE_CLIP_COLOR_8x8_FILL |
+                              HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND | 0);
+ 
++    if (pVia->Chipset != VIA_VX855 && pVia->Chipset != VIA_VX900)
++    	xaaptr->ClippingFlags |= (HARDWARE_CLIP_SOLID_FILL |
++                                  HARDWARE_CLIP_SOLID_LINE |
++                                  HARDWARE_CLIP_DASHED_LINE);
++
+     xaaptr->Sync = viaAccelSync;
+ 
++    /* ScreenToScreen copies */
+     xaaptr->SetupForScreenToScreenCopy = viaSetupForScreenToScreenCopy;
+     xaaptr->SubsequentScreenToScreenCopy = viaSubsequentScreenToScreenCopy;
+     xaaptr->ScreenToScreenCopyFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE;
+ 
++    /* Solid filled rectangles */
+     xaaptr->SetupForSolidFill = viaSetupForSolidFill;
+     xaaptr->SubsequentSolidFillRect = viaSubsequentSolidFillRect;
+     xaaptr->SolidFillFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE;
+ 
++    /* Mono 8x8 pattern fills */
+     xaaptr->SetupForMono8x8PatternFill = viaSetupForMono8x8PatternFill;
+     xaaptr->SubsequentMono8x8PatternFillRect =
+             viaSubsequentMono8x8PatternFillRect;
+@@ -1244,6 +1278,7 @@ viaInitXAA(ScreenPtr pScreen)
+                                        HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
+                                        BIT_ORDER_IN_BYTE_MSBFIRST | 0);
+ 
++    /* Color 8x8 pattern fills */
+     xaaptr->SetupForColor8x8PatternFill = viaSetupForColor8x8PatternFill;
+     xaaptr->SubsequentColor8x8PatternFillRect =
+             viaSubsequentColor8x8PatternFillRect;
+@@ -1252,12 +1287,14 @@ viaInitXAA(ScreenPtr pScreen)
+                                         HARDWARE_PATTERN_PROGRAMMED_BITS |
+                                         HARDWARE_PATTERN_PROGRAMMED_ORIGIN | 0);
+ 
++    /* Solid lines */
+     xaaptr->SetupForSolidLine = viaSetupForSolidLine;
+     xaaptr->SubsequentSolidTwoPointLine = viaSubsequentSolidTwoPointLine;
+     xaaptr->SubsequentSolidHorVertLine = viaSubsequentSolidHorVertLine;
+     xaaptr->SolidBresenhamLineErrorTermBits = 14;
+     xaaptr->SolidLineFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE;
+ 
++    /* Dashed line */
+     xaaptr->SetupForDashedLine = viaSetupForDashedLine;
+     xaaptr->SubsequentDashedTwoPointLine = viaSubsequentDashedTwoPointLine;
+     xaaptr->DashPatternMaxLength = 8;
+@@ -1266,49 +1303,50 @@ viaInitXAA(ScreenPtr pScreen)
+                                LINE_PATTERN_POWER_OF_2_ONLY |
+                                LINE_PATTERN_MSBFIRST_LSBJUSTIFIED | 0);
+ 
++    /* CPU to Screen color expansion */
+     xaaptr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK |
+-            CPU_TRANSFER_PAD_DWORD |
+-            SCANLINE_PAD_DWORD |
+-            BIT_ORDER_IN_BYTE_MSBFIRST |
+-            LEFT_EDGE_CLIPPING | ROP_NEEDS_SOURCE | 0;
++           				 	CPU_TRANSFER_PAD_DWORD |
++						SCANLINE_PAD_DWORD |
++            					BIT_ORDER_IN_BYTE_MSBFIRST |
++            					LEFT_EDGE_CLIPPING | 
++            					ROP_NEEDS_SOURCE | 0;
+ 
+     xaaptr->SetupForScanlineCPUToScreenColorExpandFill =
+             viaSetupForCPUToScreenColorExpandFill;
+     xaaptr->SubsequentScanlineCPUToScreenColorExpandFill =
+             viaSubsequentScanlineCPUToScreenColorExpandFill;
+     xaaptr->ColorExpandBase = pVia->BltBase;
+-    xaaptr->ColorExpandRange = VIA_MMIO_BLTSIZE;
++    if (pVia->Chipset == VIA_VX800 ||
++        pVia->Chipset == VIA_VX855 ||
++        pVia->Chipset == VIA_VX900)
++        xaaptr->ColorExpandRange = VIA_MMIO_BLTSIZE;
++    else
++        xaaptr->ColorExpandRange = (64 * 1024);
+ 
++    /* ImageWrite */
+     xaaptr->ImageWriteFlags = (NO_PLANEMASK |
+                                CPU_TRANSFER_PAD_DWORD |
+                                SCANLINE_PAD_DWORD |
+                                BIT_ORDER_IN_BYTE_MSBFIRST |
+-                               LEFT_EDGE_CLIPPING | ROP_NEEDS_SOURCE | 0);
+-                               // SYNC_AFTER_IMAGE_WRITE | 0);
++                               LEFT_EDGE_CLIPPING | 
++			       ROP_NEEDS_SOURCE |
++                               NO_GXCOPY | 0);
+ 
+     /*
+      * Most Unichromes are much faster using processor-to-framebuffer writes
+      * than when using the 2D engine for this.
+-     * test with x11perf -shmput500!
++     * test with "x11perf -shmput500"
++     * Example: K8M890 chipset; with GPU=86.3/sec; without GPU=132.0/sec
++     * TODO Check speed for other chipsets
+      */
+ 
+-    switch (pVia->Chipset) {
+-        case VIA_K8M800:
+-        case VIA_K8M890:
+-        case VIA_P4M900:
+-        case VIA_VX800:
+-        case VIA_VX855:
+-            break;
+-        default:
+-            xaaptr->ImageWriteFlags |= NO_GXCOPY;
+-            break;
+-    }
+-
+     xaaptr->SetupForImageWrite = viaSetupForImageWrite;
+     xaaptr->SubsequentImageWriteRect = viaSubsequentImageWriteRect;
+     xaaptr->ImageWriteBase = pVia->BltBase;
+ 
+-    if (pVia->Chipset == VIA_VX800 || pVia->Chipset == VIA_VX855)
++    if (pVia->Chipset == VIA_VX800 ||
++        pVia->Chipset == VIA_VX855 ||
++        pVia->Chipset == VIA_VX900)
+         xaaptr->ImageWriteRange = VIA_MMIO_BLTSIZE;
+     else
+         xaaptr->ImageWriteRange = (64 * 1024);
+@@ -2344,7 +2382,7 @@ viaInitExa(ScreenPtr pScreen)
+     }
+ 
+     if (!exaDriverInit(pScreen, pExa)) {
+-        xfree(pExa);
++        free(pExa);
+         return NULL;
+     }
+ 
+@@ -2354,7 +2392,7 @@ viaInitExa(ScreenPtr pScreen)
+ 
+ 
+ /*
+- * Acceleration initializatuon function. Sets up offscreen memory disposition,
++ * Acceleration initialization function. Sets up offscreen memory disposition,
+  * and initializes engines and acceleration method.
+  */
+ Bool
+@@ -2542,7 +2580,7 @@ viaExitAccel(ScreenPtr pScreen)
+             }
+         }
+         if (pVia->dBounce)
+-            xfree(pVia->dBounce);
++            free(pVia->dBounce);
+ #endif /* XF86DRI */
+         if (pVia->scratchAddr) {
+             exaOffscreenFree(pScreen, pVia->scratchFBBuffer);
+@@ -2551,7 +2589,7 @@ viaExitAccel(ScreenPtr pScreen)
+         if (pVia->exaDriverPtr) {
+             exaDriverFini(pScreen);
+         }
+-        xfree(pVia->exaDriverPtr);
++        free(pVia->exaDriverPtr);
+         pVia->exaDriverPtr = NULL;
+         return;
+     }
+@@ -2577,7 +2615,7 @@ viaFinishInitAccel(ScreenPtr pScreen)
+ 
+     if (pVia->directRenderingEnabled && pVia->useEXA) {
+ 
+-        pVia->dBounce = xcalloc(VIA_DMA_DL_SIZE * 2, 1);
++        pVia->dBounce = calloc(VIA_DMA_DL_SIZE * 2, 1);
+ 
+         if (!pVia->IsPCI) {
+ 
+Index: src/via_vt162x.c
+===================================================================
+--- src/via_vt162x.c	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_vt162x.c	(.../trunk)	(revision 916)
+@@ -41,30 +41,42 @@ ViaSetTVClockSource(ScrnInfoPtr pScrn)
+     VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+     vgaHWPtr hwp = VGAHWPTR(pScrn);
+ 
+-    /* External TV: */
+-    switch(pVia->Chipset) {
+-        case VIA_CX700:
+-        case VIA_VX800:
+-            if (pBIOSInfo->FirstCRTC->IsActive) {
+-                if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP1)
+-                    ViaCrtcMask(hwp, 0x6C, 0xB0, 0xF0);
+-                else if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP0)
+-                    ViaCrtcMask(hwp, 0x6C, 0x90, 0xF0);
+-            } else {
+-                /* IGA2 */
+-                if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP1)
+-                    ViaCrtcMask(hwp, 0x6C, 0x0B, 0x0F);
+-                else if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP0)
+-                    ViaCrtcMask(hwp, 0x6C, 0x09, 0x0F);
++    switch(pBIOSInfo->TVEncoder) {
++        case VIA_VT1625:
++            /* External TV: */
++            switch(pVia->Chipset) {
++                case VIA_CX700:
++                case VIA_VX800:
++                case VIA_VX855:
++                    if (pBIOSInfo->FirstCRTC->IsActive) {
++                        if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP1)
++                            ViaCrtcMask(hwp, 0x6C, 0xB0, 0xF0);
++                        else if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP0)
++                            ViaCrtcMask(hwp, 0x6C, 0x90, 0xF0);
++                    } else {
++                        /* IGA2 */
++                        if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP1)
++                            ViaCrtcMask(hwp, 0x6C, 0x0B, 0x0F);
++                        else if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP0)
++                            ViaCrtcMask(hwp, 0x6C, 0x09, 0x0F);
++                    }
++                    break;
++                default:
++                    if (pBIOSInfo->FirstCRTC->IsActive)
++                        ViaCrtcMask(hwp, 0x6C, 0x21, 0x21);
++                    else
++                        ViaCrtcMask(hwp, 0x6C, 0xA1, 0xA1);
++                    break;
+             }
+             break;
+         default:
+             if (pBIOSInfo->FirstCRTC->IsActive)
+-                ViaCrtcMask(hwp, 0x6C, 0x21, 0x21);
++                ViaCrtcMask(hwp, 0x6C, 0x50, 0xF0);
+             else
+-                ViaCrtcMask(hwp, 0x6C, 0xA1, 0xA1);
++                ViaCrtcMask(hwp, 0x6C, 0x05, 0x0F);
+             break;
+     }
++
+ }
+ 
+ static void
+Index: src/via_vbe.c
+===================================================================
+--- src/via_vbe.c	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_vbe.c	(.../trunk)	(revision 916)
+@@ -230,7 +230,7 @@ ViaVbeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pM
+                 /* Some cards do not like setting the clock. */
+                 xf86ErrorF("...but worked OK without customized "
+                            "refresh and dotclock.\n");
+-                xfree(data->block);
++                free(data->block);
+                 data->block = NULL;
+                 data->mode &= ~(1 << 11);
+             } else {
+@@ -322,7 +322,7 @@ ViaVbeSaveRestore(ScrnInfoPtr pScrn, vbeSaveRestor
+                 && (function == MODE_SAVE)) {
+                 /* Do not rely on the memory not being touched. */
+                 if (pVia->vbeMode.pstate == NULL)
+-                    pVia->vbeMode.pstate = xalloc(pVia->vbeMode.stateSize);
++                    pVia->vbeMode.pstate = malloc(pVia->vbeMode.stateSize);
+                 memcpy(pVia->vbeMode.pstate, pVia->vbeMode.state,
+                        pVia->vbeMode.stateSize);
+             }
+Index: src/via_xvmc.c
+===================================================================
+--- src/via_xvmc.c	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_xvmc.c	(.../trunk)	(revision 916)
+@@ -151,7 +151,7 @@ cleanupViaXvMC(ViaXvMCPtr vXvMC, XF86VideoAdaptorP
+     for (i = 0; i < VIA_XVMC_MAX_CONTEXTS; ++i) {
+         vXvMC->contexts[i] = 0;
+         if (vXvMC->cPrivs[i]) {
+-            xfree(vXvMC->cPrivs[i]);
++            free(vXvMC->cPrivs[i]);
+             vXvMC->cPrivs[i] = 0;
+         }
+     }
+@@ -159,7 +159,7 @@ cleanupViaXvMC(ViaXvMCPtr vXvMC, XF86VideoAdaptorP
+     for (i = 0; i < VIA_XVMC_MAX_SURFACES; ++i) {
+         vXvMC->surfaces[i] = 0;
+         if (vXvMC->sPrivs[i]) {
+-            xfree(vXvMC->sPrivs[i]);
++            free(vXvMC->sPrivs[i]);
+             vXvMC->sPrivs[i] = 0;
+         }
+     }
+@@ -270,7 +270,7 @@ static XF86ImagePtr Via_subpicture_list[2] = {
+ /* 
+  * Filling in the device dependent adaptor record. 
+  * This is named "VIA Video Overlay" because this code falls under the
+- * XV extenstion, the name must match or it won't be used.
++ * XV extension, the name must match or it won't be used.
+  *
+  * For surface and subpicture, see above.
+  * The function pointers point to functions below.
+@@ -325,10 +325,11 @@ ViaInitXVMC(ScreenPtr pScreen)
+ 
+     if ((pVia->Chipset == VIA_KM400) ||
+         (pVia->Chipset == VIA_CX700) ||
++        (pVia->Chipset == VIA_K8M890) ||
++        (pVia->Chipset == VIA_P4M900) ||
+         (pVia->Chipset == VIA_VX800) ||
+         (pVia->Chipset == VIA_VX855) ||
+-        (pVia->Chipset == VIA_K8M890) ||
+-        (pVia->Chipset == VIA_P4M900)) {
++        (pVia->Chipset == VIA_VX900)) {
+         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                    "[XvMC] XvMC is not supported on this chipset.\n");
+         return;
+@@ -424,7 +425,7 @@ ViaCleanupXVMC(ScrnInfoPtr pScrn, XF86VideoAdaptor
+             viaPortPrivPtr pPriv = XvAdaptors[i]->pPortPrivates[j].ptr;
+ 
+             if (pPriv->xvmc_priv)
+-                xfree(pPriv->xvmc_priv);
++                free(pPriv->xvmc_priv);
+         }
+     }
+     pVia->XvMCEnabled = 0;
+@@ -460,7 +461,7 @@ ViaXvMCCreateContext(ScrnInfoPtr pScrn, XvMCContex
+         return BadAlloc;
+     }
+ 
+-    *priv = xcalloc(1, sizeof(ViaXvMCCreateContextRec));
++    *priv = calloc(1, sizeof(ViaXvMCCreateContextRec));
+     contextRec = (ViaXvMCCreateContextRec *) * priv;
+ 
+     if (!*priv) {
+@@ -475,12 +476,12 @@ ViaXvMCCreateContext(ScrnInfoPtr pScrn, XvMCContex
+             break;
+     }
+ 
+-    cPriv = (ViaXvMCContextPriv *) xcalloc(1, sizeof(ViaXvMCContextPriv));
++    cPriv = (ViaXvMCContextPriv *) calloc(1, sizeof(ViaXvMCContextPriv));
+ 
+     if (!cPriv) {
+         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                    "[XvMC] ViaXvMCCreateContext: Unable to allocate memory!\n");
+-        xfree(*priv);
++        free(*priv);
+         *num_priv = 0;
+         return BadAlloc;
+     }
+@@ -532,7 +533,7 @@ ViaXvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfac
+         return BadAlloc;
+     }
+ 
+-    sPriv = (ViaXvMCSurfacePriv *) xcalloc(1, sizeof(ViaXvMCSurfacePriv));
++    sPriv = (ViaXvMCSurfacePriv *) calloc(1, sizeof(ViaXvMCSurfacePriv));
+ 
+     if (!sPriv) {
+         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+@@ -566,13 +567,13 @@ ViaXvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfac
+ #endif
+     *num_priv = numBuffers + 2;
+ 
+-    *priv = (INT32 *) xcalloc(*num_priv, sizeof(INT32));
++    *priv = (INT32 *) calloc(*num_priv, sizeof(INT32));
+ 
+     if (!*priv) {
+         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                    "[XvMC] ViaXvMCCreateSurface: Unable to allocate memory!\n");
+         *num_priv = 0;
+-        xfree(sPriv);
++        free(sPriv);
+         return BadAlloc;
+     }
+ 
+@@ -588,8 +589,8 @@ ViaXvMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfac
+     sPriv->memory_ref.pool = 0;
+     if (VIAAllocLinear(&(sPriv->memory_ref), pScrn,
+                        numBuffers * bufSize + 32)) {
+-        xfree(*priv);
+-        xfree(sPriv);
++        free(*priv);
++        free(sPriv);
+         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[XvMC] ViaXvMCCreateSurface: "
+                    "Unable to allocate frambuffer memory!\n");
+         return BadAlloc;
+@@ -631,7 +632,7 @@ ViaXvMCCreateSubpicture(ScrnInfoPtr pScrn, XvMCSub
+         return BadAlloc;
+     }
+ 
+-    sPriv = (ViaXvMCSurfacePriv *) xcalloc(1, sizeof(ViaXvMCSurfacePriv));
++    sPriv = (ViaXvMCSurfacePriv *) calloc(1, sizeof(ViaXvMCSurfacePriv));
+ 
+     if (!sPriv) {
+         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[XvMC] ViaXvMCCreateSubpicture:"
+@@ -640,13 +641,13 @@ ViaXvMCCreateSubpicture(ScrnInfoPtr pScrn, XvMCSub
+         return BadAlloc;
+     }
+ 
+-    *priv = (INT32 *) xcalloc(3, sizeof(INT32));
++    *priv = (INT32 *) calloc(3, sizeof(INT32));
+ 
+     if (!*priv) {
+         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[XvMC] ViaXvMCCreateSubpicture:"
+                    " Unable to allocate memory!\n");
+         *num_priv = 0;
+-        xfree(sPriv);
++        free(sPriv);
+         return BadAlloc;
+     }
+ 
+@@ -663,8 +664,8 @@ ViaXvMCCreateSubpicture(ScrnInfoPtr pScrn, XvMCSub
+     bufSize = size_xx44(ctx->width, ctx->height);
+     sPriv->memory_ref.pool = 0;
+     if (VIAAllocLinear(&(sPriv->memory_ref), pScrn, 1 * bufSize + 32)) {
+-        xfree(*priv);
+-        xfree(sPriv);
++        free(*priv);
++        free(sPriv);
+         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[XvMC] ViaXvMCCreateSubpicture:"
+                    " Unable to allocate framebuffer memory!\n");
+         return BadAlloc;
+@@ -701,7 +702,7 @@ ViaXvMCDestroyContext(ScrnInfoPtr pScrn, XvMCConte
+                 vx->ctxDisplaying = 0;
+             }
+ 
+-            xfree(vXvMC->cPrivs[i]);
++            free(vXvMC->cPrivs[i]);
+             vXvMC->cPrivs[i] = 0;
+             vXvMC->nContexts--;
+             vXvMC->contexts[i] = 0;
+@@ -736,7 +737,7 @@ ViaXvMCDestroySurface(ScrnInfoPtr pScrn, XvMCSurfa
+             }
+ 
+             VIAFreeLinear(&(vXvMC->sPrivs[i]->memory_ref));
+-            xfree(vXvMC->sPrivs[i]);
++            free(vXvMC->sPrivs[i]);
+             vXvMC->nSurfaces--;
+             vXvMC->sPrivs[i] = 0;
+             vXvMC->surfaces[i] = 0;
+@@ -778,7 +779,7 @@ ViaXvMCDestroySubpicture(ScrnInfoPtr pScrn, XvMCSu
+             }
+ 
+             VIAFreeLinear(&(vXvMC->sPrivs[i]->memory_ref));
+-            xfree(vXvMC->sPrivs[i]);
++            free(vXvMC->sPrivs[i]);
+             vXvMC->nSurfaces--;
+             vXvMC->sPrivs[i] = 0;
+             vXvMC->surfaces[i] = 0;
+@@ -828,7 +829,7 @@ viaXvMCInitXv(ScrnInfoPtr pScrn, XF86VideoAdaptorP
+     for (j = 0; j < XvAdapt->nPorts; ++j) {
+         pPriv = (viaPortPrivPtr) XvAdapt->pPortPrivates[j].ptr;
+ 
+-        if (NULL == (pPriv->xvmc_priv = xcalloc(1, sizeof(ViaXvMCXVPriv))))
++        if (NULL == (pPriv->xvmc_priv = calloc(1, sizeof(ViaXvMCXVPriv))))
+             return BadAlloc;
+ 
+         for (i = 0; i < VIA_NUM_XVMC_ATTRIBUTES; ++i) {
+Index: src/via_cursor.c
+===================================================================
+--- src/via_cursor.c	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_cursor.c	(.../trunk)	(revision 916)
+@@ -98,6 +98,7 @@ viaHWCursorInit(ScreenPtr pScreen)
+         case VIA_P4M900:
+         case VIA_VX800:
+         case VIA_VX855:
++        case VIA_VX900:
+ 			if (pVia->pBIOSInfo->FirstCRTC->IsActive) {
+ 				pVia->CursorRegControl  = VIA_REG_HI_CONTROL0;
+ 				pVia->CursorRegBase     = VIA_REG_HI_BASE0;
+@@ -145,9 +146,12 @@ viaHWCursorInit(ScreenPtr pScreen)
+     infoPtr->ShowCursor = viaShowCursor;
+     infoPtr->UseHWCursor = viaUseHWCursor;
+ 
++    /* ARGB Cursor init */
+     infoPtr->UseHWCursorARGB = viaUseHWCursorARGB;
+-	if (pVia->CursorARGBSupported)
++    if (pVia->CursorARGBSupported) {
++        DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "HWCursor ARGB enabled\n"));
+     	infoPtr->LoadCursorARGB = viaLoadCursorARGB;
++    }
+ 
+     /* Set cursor location in frame buffer. */
+     VIASETREG(VIA_REG_CURSOR_MODE, pVia->cursorOffset);
+@@ -166,6 +170,7 @@ viaHWCursorInit(ScreenPtr pScreen)
+         case VIA_P4M900:
+         case VIA_VX800:
+         case VIA_VX855:
++        case VIA_VX900:
+ 			if (pVia->pBIOSInfo->FirstCRTC->IsActive) {
+ 				VIASETREG(VIA_REG_PRIM_HI_INVTCOLOR, 0x00FFFFFF);
+ 				VIASETREG(VIA_REG_V327_HI_INVTCOLOR, 0x00FFFFFF);
+@@ -225,6 +230,7 @@ viaCursorStore(ScrnInfoPtr pScrn)
+         case VIA_P4M900:
+         case VIA_VX800:
+         case VIA_VX855:
++        case VIA_VX900:
+ 		if (pVia->pBIOSInfo->FirstCRTC->IsActive) {
+ 	    		pVia->CursorPrimHiInvtColor = VIAGETREG(VIA_REG_PRIM_HI_INVTCOLOR);
+ 	    		pVia->CursorV327HiInvtColor = VIAGETREG(VIA_REG_V327_HI_INVTCOLOR);
+@@ -265,6 +271,7 @@ viaCursorRestore(ScrnInfoPtr pScrn)
+         case VIA_P4M900:
+         case VIA_VX800:
+         case VIA_VX855:
++        case VIA_VX900:
+ 		if (pVia->pBIOSInfo->FirstCRTC->IsActive) {
+ 	    		VIASETREG(VIA_REG_PRIM_HI_INVTCOLOR, pVia->CursorPrimHiInvtColor);
+ 	    		VIASETREG(VIA_REG_V327_HI_INVTCOLOR, pVia->CursorV327HiInvtColor);
+@@ -284,7 +291,7 @@ viaCursorRestore(ScrnInfoPtr pScrn)
+ }
+ 
+ /*
+- * ARGB Cursor
++ * display the current cursor
+  */
+ 
+ void
+@@ -298,6 +305,7 @@ viaShowCursor(ScrnInfoPtr pScrn)
+         case VIA_P4M900:
+         case VIA_VX800:
+         case VIA_VX855:
++        case VIA_VX900:
+              if (pVia->pBIOSInfo->FirstCRTC->IsActive) {
+                  VIASETREG(VIA_REG_HI_CONTROL0, 0x36000005);
+              }
+@@ -319,13 +327,19 @@ viaShowCursor(ScrnInfoPtr pScrn)
+             */
+ 
+             /* Duoview */
+-	    if (pVia->CursorPipe)
++	    if (pVia->CursorPipe) {
++                /* Mono Cursor Display Path [bit31]: Secondary */
++                /* FIXME For CLE266 and KM400 try to enable 32x32 cursor size [bit1] */
+                 VIASETREG(VIA_REG_ALPHA_CONTROL, 0xF6000005);
+-            else
++            } else {
++                /* Mono Cursor Display Path [bit31]: Primary */
+                 VIASETREG(VIA_REG_ALPHA_CONTROL, 0x76000005);
++            }
+     }
+ }
+ 
++
++/* hide the current cursor */
+ void
+ viaHideCursor(ScrnInfoPtr pScrn)
+ {
+@@ -338,6 +352,7 @@ viaHideCursor(ScrnInfoPtr pScrn)
+         case VIA_P4M900:
+         case VIA_VX800:
+         case VIA_VX855:
++        case VIA_VX900:
+              if (pVia->pBIOSInfo->FirstCRTC->IsActive) {
+                  temp = VIAGETREG(VIA_REG_HI_CONTROL0);
+                  VIASETREG(VIA_REG_HI_CONTROL0, temp & 0xFFFFFFFA);
+@@ -350,10 +365,16 @@ viaHideCursor(ScrnInfoPtr pScrn)
+         
+         default:
+              temp = VIAGETREG(VIA_REG_ALPHA_CONTROL);
++             /* Hardware cursor disable [bit0] */
+              VIASETREG(VIA_REG_ALPHA_CONTROL, temp & 0xFFFFFFFA);
+     }
+ }
+ 
++/*
++    Set the cursor position to (x,y).  X and/or y may be negative
++    indicating that the cursor image is partially offscreen on
++    the left and/or top edges of the screen.
++*/
+ static void
+ viaSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+ {
+@@ -380,6 +401,7 @@ viaSetCursorPosition(ScrnInfoPtr pScrn, int x, int
+         case VIA_P4M900:
+         case VIA_VX800:
+         case VIA_VX855:
++        case VIA_VX900:
+              if (pVia->pBIOSInfo->FirstCRTC->IsActive) {                
+                  VIASETREG(VIA_REG_HI_POS0,    ((x    << 16) | (y    & 0x07ff)));
+                  VIASETREG(VIA_REG_HI_OFFSET0, ((xoff << 16) | (yoff & 0x07ff)));
+@@ -409,6 +431,15 @@ viaUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pC
+             && pCurs->bits->height <= pVia->CursorMaxHeight);
+ }
+ 
++/*
++    If the driver is unable to use a hardware cursor for reasons
++    other than the cursor being larger than the maximum specified
++    in the MaxWidth or MaxHeight field below, it can supply the
++    UseHWCursor function.  If UseHWCursor is provided by the driver,
++    it will be called whenever the cursor shape changes or the video
++    mode changes.  This is useful for when the hardware cursor cannot
++    be used in interlaced or doublescan modes.
++*/
+ static Bool
+ viaUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+ {
+@@ -423,8 +454,11 @@ viaUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+             && pCurs->bits->height <= pVia->CursorMaxHeight);
+ }
+ 
++/*
++    Load Mono Cursor Image 
++*/
+ static void
+-viaLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *s)
++viaLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
+ {
+     VIAPtr pVia = VIAPTR(pScrn);
+     CARD32 temp;
+@@ -439,7 +473,7 @@ static void
+     if (pVia->CursorARGBSupported) {
+ #define ARGB_PER_CHUNK	(8 * sizeof (chunk) / 2)
+ 		for (i = 0; i < (pVia->CursorMaxWidth * pVia->CursorMaxHeight / ARGB_PER_CHUNK); i++) {
+-		    chunk = *s++;
++		    chunk = *src++;
+ 		    for (j = 0; j < ARGB_PER_CHUNK; j++, chunk >>= 2)
+ 			*dst++ = mono_cursor_color[chunk & 3];
+ 		}
+@@ -447,7 +481,7 @@ static void
+ 		pVia->CursorFG = mono_cursor_color[3];
+ 		pVia->CursorBG = mono_cursor_color[2];
+     } else {
+-	memcpy(dst, (CARD8*)s, pVia->CursorSize);
++	memcpy(dst, (CARD8*)src, pVia->CursorSize);
+     }
+     switch(pVia->Chipset) {
+         case VIA_CX700:
+@@ -455,6 +489,7 @@ static void
+         case VIA_P4M900:
+         case VIA_VX800:
+         case VIA_VX855:
++        case VIA_VX900:
+              if (pVia->pBIOSInfo->FirstCRTC->IsActive) {
+                  temp = VIAGETREG(VIA_REG_HI_CONTROL0);
+                  VIASETREG(VIA_REG_HI_CONTROL0, temp & 0xFFFFFFFE);
+@@ -471,11 +506,17 @@ static void
+     }
+ }
+ 
++/*
++    Set the cursor foreground and background colors.  In 8bpp, fg and
++    bg are indices into the current colormap unless the 
++    HARDWARE_CURSOR_TRUECOLOR_AT_8BPP flag is set.  In that case
++    and in all other bpps the fg and bg are in 8-8-8 RGB format.
++*/
++
+ static void
+ viaSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+ {
+     VIAPtr pVia = VIAPTR(pScrn);
+-    CARD32 control = pVia->CursorRegControl;
+     CARD32 pixel;
+     CARD32 temp;
+     CARD32 *dst;
+@@ -487,12 +528,10 @@ viaSetCursorColors(ScrnInfoPtr pScrn, int bg, int
+     fg |= 0xff000000;
+     bg |= 0xff000000;
+ 
++    /* Don't recolour the image if we don't have to. */
+     if (fg == pVia->CursorFG && bg == pVia->CursorBG)
+ 	return;
+ 
+-    temp = VIAGETREG(control);
+-    VIASETREG(control, temp & 0xFFFFFFFE);
+-
+     dst = (CARD32*)pVia->cursorMap;
+     for (i = 0; i < pVia->CursorMaxWidth * pVia->CursorMaxHeight; i++, dst++)
+ 	if ((pixel = *dst))
+@@ -507,6 +546,7 @@ viaSetCursorColors(ScrnInfoPtr pScrn, int bg, int
+         case VIA_P4M900:
+         case VIA_VX800:
+         case VIA_VX855:
++        case VIA_VX900:
+              if (pVia->pBIOSInfo->FirstCRTC->IsActive) {
+                  temp = VIAGETREG(VIA_REG_HI_CONTROL0);
+                  VIASETREG(VIA_REG_HI_CONTROL0, temp & 0xFFFFFFFE);
+@@ -517,7 +557,8 @@ viaSetCursorColors(ScrnInfoPtr pScrn, int bg, int
+              }
+              break;        
+         default:
+-             VIASETREG(control, temp);
++             temp = VIAGETREG(VIA_REG_ALPHA_CONTROL);
++             VIASETREG(VIA_REG_ALPHA_CONTROL, temp & 0xFFFFFFFE);
+     }
+ }
+ 
+Index: src/via_i2c.c
+===================================================================
+--- src/via_i2c.c	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_i2c.c	(.../trunk)	(revision 916)
+@@ -365,9 +365,18 @@ ViaI2CInit(ScrnInfoPtr pScrn)
+ 
+     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaI2CInit\n"));
+ 
+-    pVia->pI2CBus1 = ViaI2CBus1Init(pScrn->scrnIndex);
+-    pVia->pI2CBus2 = ViaI2CBus2Init(pScrn->scrnIndex);
+-    pVia->pI2CBus3 = ViaI2CBus3Init(pScrn->scrnIndex);
++    if (!pVia->I2CDevices) {
++        pVia->pI2CBus1 = ViaI2CBus1Init(pScrn->scrnIndex);
++        pVia->pI2CBus2 = ViaI2CBus2Init(pScrn->scrnIndex);
++        pVia->pI2CBus3 = ViaI2CBus3Init(pScrn->scrnIndex);
++    } else {
++        if (pVia->I2CDevices & VIA_I2C_BUS1)
++            pVia->pI2CBus1 = ViaI2CBus1Init(pScrn->scrnIndex);
++        if (pVia->I2CDevices & VIA_I2C_BUS2)
++            pVia->pI2CBus2 = ViaI2CBus2Init(pScrn->scrnIndex);
++        if (pVia->I2CDevices & VIA_I2C_BUS3)
++            pVia->pI2CBus3 = ViaI2CBus3Init(pScrn->scrnIndex);
++    }
+ 
+ #ifdef HAVE_DEBUG
+     if (pVia->I2CScan) {
+Index: src/via_dri.c
+===================================================================
+--- src/via_dri.c	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_dri.c	(.../trunk)	(revision 916)
+@@ -187,7 +187,7 @@ VIADRIRingBufferInit(ScrnInfoPtr pScrn)
+             return FALSE;
+ 
+         /*
+-         * Info frome code-snippet on DRI-DEVEL list; Erdi Chen.
++         * Info from code-snippet on DRI-DEVEL list; Erdi Chen.
+          */
+ 
+         switch (pVia->ChipId) {
+@@ -267,6 +267,7 @@ VIADRIAgpInit(ScreenPtr pScreen, VIAPtr pVia)
+     pVIADRI = pDRIInfo->devPrivate;
+     pVia->agpSize = 0;
+ 
++
+     if (drmAgpAcquire(pVia->drmFD) < 0) {
+         xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpAcquire failed %d\n",
+                    errno);
+@@ -431,17 +432,17 @@ VIAInitVisualConfigs(ScreenPtr pScreen)
+     if (pScrn->bitsPerPixel == 16 || pScrn->bitsPerPixel == 32) {
+         numConfigs = 12;
+         if (!(pConfigs = (__GLXvisualConfig *)
+-                         xcalloc(sizeof(__GLXvisualConfig), numConfigs)))
++                         calloc(sizeof(__GLXvisualConfig), numConfigs)))
+             return FALSE;
+         if (!(pVIAConfigs = (VIAConfigPrivPtr)
+-                            xcalloc(sizeof(VIAConfigPrivRec), numConfigs))) {
+-            xfree(pConfigs);
++                            calloc(sizeof(VIAConfigPrivRec), numConfigs))) {
++            free(pConfigs);
+             return FALSE;
+         }
+         if (!(pVIAConfigPtrs = (VIAConfigPrivPtr *)
+-                               xcalloc(sizeof(VIAConfigPrivPtr), numConfigs))) {
+-            xfree(pConfigs);
+-            xfree(pVIAConfigs);
++                               calloc(sizeof(VIAConfigPrivPtr), numConfigs))) {
++            free(pConfigs);
++            free(pVIAConfigs);
+             return FALSE;
+         }
+         for (i = 0; i < numConfigs; i++)
+@@ -593,23 +594,28 @@ VIADRIScreenInit(ScreenPtr pScreen)
+         case VIA_P4M900:
+         case VIA_VX800:
+         case VIA_VX855:
++        case VIA_VX900:
+             pDRIInfo->clientDriverName = "swrast";
+             break;
+         default:
+             pDRIInfo->clientDriverName = VIAClientDriverName;
+             break;
+     }
+-    pDRIInfo->busIdString = xalloc(64);
+-    sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d",
++    if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
++        pDRIInfo->busIdString = DRICreatePCIBusID(pVia->PciInfo);
++    } else {
++        pDRIInfo->busIdString = malloc(64);
++        sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d",
+ #ifdef XSERVER_LIBPCIACCESS
+-            ((pVia->PciInfo->domain << 8) | pVia->PciInfo->bus),
+-            pVia->PciInfo->dev, pVia->PciInfo->func
++                ((pVia->PciInfo->domain << 8) | pVia->PciInfo->bus),
++                pVia->PciInfo->dev, pVia->PciInfo->func
+ #else
+-            ((pciConfigPtr)pVia->PciInfo->thisCard)->busnum,
+-            ((pciConfigPtr)pVia->PciInfo->thisCard)->devnum,
+-            ((pciConfigPtr)pVia->PciInfo->thisCard)->funcnum
++                ((pciConfigPtr)pVia->PciInfo->thisCard)->busnum,
++                ((pciConfigPtr)pVia->PciInfo->thisCard)->devnum,
++                ((pciConfigPtr)pVia->PciInfo->thisCard)->funcnum
+ #endif
+-           );
++               );
++    }
+     pDRIInfo->ddxDriverMajorVersion = VIA_DRIDDX_VERSION_MAJOR;
+     pDRIInfo->ddxDriverMinorVersion = VIA_DRIDDX_VERSION_MINOR;
+     pDRIInfo->ddxDriverPatchVersion = VIA_DRIDDX_VERSION_PATCH;
+@@ -646,7 +652,7 @@ VIADRIScreenInit(ScreenPtr pScreen)
+     pDRIInfo->SAREASize = SAREA_MAX;
+ #endif
+ 
+-    if (!(pVIADRI = (VIADRIPtr) xcalloc(sizeof(VIADRIRec), 1))) {
++    if (!(pVIADRI = (VIADRIPtr) calloc(sizeof(VIADRIRec), 1))) {
+         DRIDestroyInfoRec(pVia->pDRIInfo);
+         pVia->pDRIInfo = NULL;
+         return FALSE;
+@@ -665,7 +671,7 @@ VIADRIScreenInit(ScreenPtr pScreen)
+     if (!DRIScreenInit(pScreen, pDRIInfo, &pVia->drmFD)) {
+         xf86DrvMsg(pScreen->myNum, X_ERROR,
+                    "[dri] DRIScreenInit failed.  Disabling DRI.\n");
+-        xfree(pDRIInfo->devPrivate);
++        free(pDRIInfo->devPrivate);
+         pDRIInfo->devPrivate = NULL;
+         DRIDestroyInfoRec(pVia->pDRIInfo);
+         pVia->pDRIInfo = NULL;
+@@ -748,7 +754,7 @@ VIADRICloseScreen(ScreenPtr pScreen)
+     if (pVia->pDRIInfo) {
+         if ((pVIADRI = (VIADRIPtr) pVia->pDRIInfo->devPrivate)) {
+             VIADRIIrqExit(pScrn, pVIADRI);
+-            xfree(pVIADRI);
++            free(pVIADRI);
+             pVia->pDRIInfo->devPrivate = NULL;
+         }
+         DRIDestroyInfoRec(pVia->pDRIInfo);
+@@ -756,11 +762,11 @@ VIADRICloseScreen(ScreenPtr pScreen)
+     }
+ 
+     if (pVia->pVisualConfigs) {
+-        xfree(pVia->pVisualConfigs);
++        free(pVia->pVisualConfigs);
+         pVia->pVisualConfigs = NULL;
+     }
+     if (pVia->pVisualConfigsPriv) {
+-        xfree(pVia->pVisualConfigsPriv);
++        free(pVia->pVisualConfigsPriv);
+         pVia->pVisualConfigsPriv = NULL;
+     }
+ }
+Index: src/via.h
+===================================================================
+--- src/via.h	(.../tags/release_0_2_904)	(revision 916)
++++ src/via.h	(.../trunk)	(revision 916)
+@@ -34,7 +34,7 @@
+ 
+ /* Video Engines */
+ #define VIDEO_ENGINE_UNK	0 /* Unknown video engine */
+-#define VIDEO_ENGINE_CLE	1 /* CLE First generaion video engine */
++#define VIDEO_ENGINE_CLE	1 /* CLE First generation video engine */
+ #define VIDEO_ENGINE_CME	2 /* CME Second generation video engine */
+ 
+ /* Video status flag */
+@@ -215,6 +215,9 @@
+ #define HQV_DST_STRIDE          0x1F4
+ #define HQV_SRC_STRIDE          0x1F8
+ 
++#define HQV_H_SCALE_CONTROL     0x1B0
++#define HQV_V_SCALE_CONTROL     0x1B4
++
+ #define PRO_HQV1_OFFSET         0x1000
+ /*
+  *  Video command definition
+@@ -515,7 +518,23 @@
+ #define HQV_FIFO_STATUS     0x00001000  
+ #define HQV_GEN_IRQ         0x00000080
+ #define HQV_FIFO_DEPTH_1    0x00010000
++/* for CME engine */
++#define HQV_SW_FLIP_QUEUE_ENABLE    0x00100000
+ 
++/* for hwDiff->dwNewScaleCtl */
++#define HQV_H_SCALE_ENABLE                 0x80000000
++#define HQV_H_SCALE_UP                     0x00000000  
++#define HQV_H_SCALE_DOWN_FOURTH_TO_1       0x10000000 
++#define HQV_H_SCALE_DOWN_FOURTH_TO_EIGHTH  0x20000000 
++#define HQV_H_SCALE_DOWN_UNDER_EIGHTH      0x30000000 
++
++#define HQV_V_SCALE_ENABLE 0x80000000
++#define HQV_V_SCALE_UP     0x00000000
++#define HQV_V_SCALE_DOWN   0x10000000
++
++/* HQV Default Vodeo Color 0x3B8 */
++#define HQV_FIX_COLOR           0x0643212c
++
+ /* HQV_FILTER_CONTROL      0x3E4 */
+ #define HQV_H_LOWPASS_2TAP  0x00000001
+ #define HQV_H_LOWPASS_4TAP  0x00000002
+@@ -575,6 +594,25 @@
+ #define HQV_VDEBLOCK_FILTER 0x80000000
+ #define HQV_HDEBLOCK_FILTER 0x00008000
+ 
++/* new added registers for VT3409.For some registers have different meanings 
++ * but the same address,we add postfix _409 to distinguish */
++#define HQV_COLOR_ADJUSTMENT_PRE_CTRL1      0x160
++#define HQV_COLOR_ADJUSTMENT_PRE_CTRL2      0x164
++#define HQV_COLOR_ADJUSTMENT_PRE_CTRL3      0x168
++#define HQV_COLOR_ADJUSTMENT_PRE_CTRL4      0x16C
++#define HQV_SRC_DATA_OFFSET_CTRL1_409       0x170 
++#define HQV_SRC_DATA_OFFSET_CTRL2_409       0x174  
++#define HQV_SRC_DATA_OFFSET_CTRL3_409       0x178  
++#define HQV_SRC_DATA_OFFSET_CTRL4_409       0x17C  
++#define HQV_DST_DATA_OFFSET_CTRL1           0x180
++#define HQV_DST_DATA_OFFSET_CTRL2           0x184  
++#define HQV_DST_DATA_OFFSET_CTRL3           0x188  
++#define HQV_DST_DATA_OFFSET_CTRL4           0x18C 
++#define HQV_RESIDUE_PIXEL_FRAME_STARTADDR   0x1BC
++#define HQV_BACKGROUND_DATA_OFFSET          0x1CC
++#define HQV_SUBP_HSCALE_CTRL                0x1E0
++#define HQV_SUBP_VSCALE_CTRL                0x1E8
++
+ /* Add new HQV Registers for VT3353: */
+ #define HQV_SRC_DATA_OFFSET_CONTROL1        0x180
+ #define HQV_SRC_DATA_OFFSET_CONTROL2        0x184
+@@ -588,6 +626,7 @@
+ #define HQV_COLOR_ADJUSTMENT_CONTROL2       0x1A4
+ #define HQV_COLOR_ADJUSTMENT_CONTROL3       0x1A8
+ #define HQV_COLOR_ADJUSTMENT_CONTROL5       0x1AC
++#define HQV_DEFAULT_VIDEO_COLOR             0x1B8
+ 
+ #define CHROMA_KEY_LOW          0x00FFFFFF
+ #define CHROMA_KEY_HIGH         0x00FFFFFF
+Index: man/openchrome.man
+===================================================================
+--- man/openchrome.man	(.../tags/release_0_2_904)	(revision 916)
++++ man/openchrome.man	(.../trunk)	(revision 916)
+@@ -22,7 +22,7 @@ The
+ .B openchrome
+ driver supports the following chipsets: CLE266, KM400/KN400/KM400A/P4M800,
+ CN400/PM800/PN800/PM880, K8M800, CN700/VM800/P4M800Pro, CX700, P4M890, K8M890,
+-P4M900/VN896/CN896, VX800 and VX855.
++P4M900/VN896/CN896, VX800, VX855 and VX900.
+ The driver includes 2D acceleration and Xv video overlay extensions.
+ Flat panel, TV, and VGA outputs are supported, depending on the hardware
+ configuration.
+@@ -59,16 +59,18 @@ are supported:
+ .BI "Option \*qAccelMethod\*q  \*q" string \*q
+ The driver supports "XAA" and "EXA" acceleration methods.  The default
+ method is XAA, since EXA is still experimental.  Contrary to XAA, EXA
+-implements acceleration for screen uploads and downlads (if DRI is
++implements acceleration for screen uploads and downloads (if DRI is
+ enabled) and for the Render/Composite extension.
+ .TP
+ .BI "Option \*qActiveDevice\*q  \*q" string \*q
+ Specifies the active device combination.  Any string containing "CRT",
+ "LCD", "DFP", "TV" should be possible. "CRT" represents anything that
+-is connected to the VGA port, "LCD" and "DFP" are for laptop panels
+-(not TFT screens attached to the VGA port), "TV" is self-explanatory.
++is connected to the VGA port, "LCD" is for laptop panels (not TFT screens
++attached to the VGA port), "DFP" is for screens connected to the DVI port,
++"TV" is self-explanatory.
+ The default is to use what is detected.  The driver is currently unable
+-to use LCD and TV simultaneously, and will favour the LCD.
++to use LCD and TV simultaneously, and will favour the LCD.  The DVI port is
++not properly probed and needs to be enabled with this option.
+ .TP
+ .BI "Option \*qAGPMem\*q  \*q" integer \*q
+ Sets the amount of AGP memory that is allocated at X server startup.
+@@ -81,7 +83,7 @@ EXA scratch area in AGP space, it will be allocate
+ no room for DRI textures, they will be allocated from the DRI part of
+ VRAM (see the option "MaxDRIMem").  The default amount of AGP is
+ 32768 kB.  Note that the AGP aperture set in the BIOS must be able
+-to accomodate the amount of AGP memory specified here.  Otherwise no
++to accommodate the amount of AGP memory specified here.  Otherwise no
+ AGP memory will be available.  It is safe to set a very large AGP
+ aperture in the BIOS.
+ .TP
+@@ -131,10 +133,10 @@ as possible to the EXA pixmap storage area.
+ .TP
+ .BI "Option \*qMigrationHeuristic\*q  \*q" string \*q
+ Sets the heuristic for EXA pixmap migration.  This is an EXA core
+-option, and on Xorg server versions after 1.1.0 this defaults to
+-"smart".  The openchrome driver performs best with "greedy", so you
++option, and starting from __xservername__ server version 1.3.0 this defaults to
++"always".  The openchrome driver performs best with "greedy", so you
+ should really add this option to your configuration file.  The third
+-possibility is "always", which might become more useful in the future.
++possibility is "smart".
+ .TP
+ .BI "Option \*qNoAccel\*q  \*q" boolean \*q
+ Disables the use of hardware acceleration.  Acceleration is enabled
+@@ -159,9 +161,16 @@ Specifies the size (width x height) of the LCD pan
+ system.  The sizes 640x480, 800x600, 1024x768, 1280x1024, and 1400x1050
+ are supported.
+ .TP
++.BI "Option \*qRotationType\*q  \*q" string \*q
++Enabled rotation by using RandR. The driver only support unaccelerated
++RandR rotations "SWRandR". Hardware rotations "HWRandR" is currently 
++unimplemented.
++.TP
+ .BI "Option \*qRotate\*q  \*q" string \*q
+ Rotates the display either clockwise ("CW"), counterclockwise ("CCW") and
+-upside-down ("UD"). Rotation is only supported unaccelerated.
++upside-down ("UD"). Rotation is only supported unaccelerated.  Adding 
++option "Rotate", enables RandR rotation feature.  The RandR allows 
++clients to dynamically change X screens.
+ .TP
+ .BI "Option \*qShadowFB\*q  \*q" boolean \*q
+ Enables the use of a shadow frame buffer.  This is required when
+@@ -234,6 +243,6 @@ overscan).  These modes are made available by the
+ provided in __xconfigfile__ will be ignored.
+ 
+ .SH "SEE ALSO"
+-__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
++__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__), EXA(__filemansuffix__), Xv(__filemansuffix__)
+ .SH AUTHORS
+ Authors include: ...
+Index: src/via_dga.c
+===================================================================
+--- src/via_dga.c	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_dga.c	(.../trunk)	(revision 916)
+@@ -89,16 +89,16 @@ VIASetupDGAMode(
+         otherPitch = secondPitch ? secondPitch : pMode->HDisplay;
+ 
+         if (pMode->HDisplay != otherPitch) {
+-            newmodes = xrealloc(modes, (*num + 2) * sizeof(DGAModeRec));
++            newmodes = realloc(modes, (*num + 2) * sizeof(DGAModeRec));
+             oneMore = TRUE;
+         }
+         else {
+-            newmodes = xrealloc(modes, (*num + 1) * sizeof(DGAModeRec));
++            newmodes = realloc(modes, (*num + 1) * sizeof(DGAModeRec));
+             oneMore = FALSE;
+         }
+ 
+         if (!newmodes) {
+-            xfree(modes);
++            free(modes);
+             return NULL;
+         }
+ 
+Index: src/via_id.c
+===================================================================
+--- src/via_id.c	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_id.c	(.../trunk)	(revision 916)
+@@ -63,6 +63,7 @@ static struct ViaCardIdStruct ViaCardId[] = {
+     {"Giga-byte 7VM400(A)M",                  VIA_KM400,   0x1458, 0xD000, VIA_DEVICE_CRT},
+     {"MSI KM4(A)M-V",                         VIA_KM400,   0x1462, 0x7061, VIA_DEVICE_CRT}, /* aka "DFI KM400-MLV" */
+     {"MSI PM8M2-V",                           VIA_KM400,   0x1462, 0x7071, VIA_DEVICE_CRT},
++    {"MSI PM8M-V",                            VIA_KM400,   0x1462, 0x7104, VIA_DEVICE_CRT},
+     {"MSI KM4(A)M-L",                         VIA_KM400,   0x1462, 0x7348, VIA_DEVICE_CRT},
+     {"Abit VA-10 (1)",                        VIA_KM400,   0x147B, 0x140B, VIA_DEVICE_CRT},
+     {"Abit VA-10 (2)",                        VIA_KM400,   0x147B, 0x140C, VIA_DEVICE_CRT},
+@@ -114,6 +115,7 @@ static struct ViaCardIdStruct ViaCardId[] = {
+     {"Packard Bell Easynote B3 800/B3340",    VIA_K8M800,  0x1631, 0xC009, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+     {"Packard Bell Imedia 2097",              VIA_K8M800,  0x1631, 0xD007, VIA_DEVICE_CRT},
+     {"Fujitsu-Siemens Amilo K7610",           VIA_K8M800,  0x1734, 0x10B3, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
++    {"Lenovo ThinkCenter E51 8714",           VIA_K8M800,  0x17AA, 0x1008, VIA_DEVICE_CRT},
+     {"ASRock K8Upgrade-VM800",                VIA_K8M800,  0x1849, 0x3108, VIA_DEVICE_CRT},
+     {"Axper XP-M8VM800",                      VIA_K8M800,  0x1940, 0xD000, VIA_DEVICE_CRT},
+ 
+@@ -138,6 +140,7 @@ static struct ViaCardIdStruct ViaCardId[] = {
+     {"Haier A60-440256080BD",                 VIA_VM800,   0x1019, 0x0F79, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+     {"PCChips P23G",                          VIA_VM800,   0x1019, 0x1623, VIA_DEVICE_CRT},
+     {"ECS P4M800PRO-M",                       VIA_VM800,   0x1019, 0x2122, VIA_DEVICE_CRT},
++    {"ECS P4M800PRO-M2 (V2.0)",               VIA_VM800,   0x1019, 0x2123, VIA_DEVICE_CRT},
+     {"ECS C7VCM",                             VIA_VM800,   0x1019, 0xAA2D, VIA_DEVICE_CRT},
+     {"PCChips V21G",                          VIA_VM800,   0x1019, 0xAA51, VIA_DEVICE_CRT},
+     {"Asustek P5VDC-MX",                      VIA_VM800,   0x1043, 0x3344, VIA_DEVICE_CRT},
+@@ -152,6 +155,7 @@ static struct ViaCardIdStruct ViaCardId[] = {
+     {"MSI PM8PM",                             VIA_VM800,   0x1462, 0x7222, VIA_DEVICE_CRT},
+     {"Twinhead M6",                           VIA_VM800,   0x14FF, 0xA007, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+     {"RoverBook Partner W500",                VIA_VM800,   0x1509, 0x4330, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
++    {"FIC PTM800Pro LF",                      VIA_VM800,   0x1509, 0x601A, VIA_DEVICE_CRT},
+     {"Clevo/RoverBook Voyager V511L",         VIA_VM800,   0x1558, 0x0662, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+     {"Clevo M5xxS",                           VIA_VM800,   0x1558, 0x5406, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+     {"Biostar P4M80-M4 / P4VMA-M",            VIA_VM800,   0x1565, 0x1202, VIA_DEVICE_CRT},
+@@ -170,6 +174,7 @@ static struct ViaCardIdStruct ViaCardId[] = {
+     {"Asustek M2V-MX SE",                     VIA_K8M890,  0x1043, 0x8297, VIA_DEVICE_CRT},
+     {"Foxconn K8M890M2MA-RS2H",               VIA_K8M890,  0x105B, 0x0C84, VIA_DEVICE_CRT},
+     {"Shuttle FX22V1",                        VIA_K8M890,  0x1297, 0x3080, VIA_DEVICE_CRT},
++    {"MSI K8M890M2-V",                        VIA_K8M890,  0x1462, 0x7139, VIA_DEVICE_CRT},
+     {"MSI K9VGM-V",                           VIA_K8M890,  0x1462, 0x7253, VIA_DEVICE_CRT},
+     {"Averatec 226x",                         VIA_K8M890,  0x14FF, 0xA002, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+     {"Fujitsu/Siemens Amilo La 1703",         VIA_K8M890,  0x1734, 0x10D9, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+@@ -183,12 +188,13 @@ static struct ViaCardIdStruct ViaCardId[] = {
+     {"Mitac 8515",                            VIA_P4M900,  0x1071, 0x8515, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+     {"Medion Notebook MD96483",               VIA_P4M900,  0x1071, 0x8615, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+     {"Mitac 8624",                            VIA_P4M900,  0x1071, 0x8624, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+-    {"VIA VT3364 (P4M900)",                   VIA_P4M900,  0x1106, 0x3371, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
++    {"VIA VB8001 Mini-ITX Board (P4M900)",    VIA_P4M900,  0x1106, 0x3371, VIA_DEVICE_CRT},
+     {"Gigabyte GA-VM900M",                    VIA_P4M900,  0x1458, 0xD000, VIA_DEVICE_CRT},
+     {"MSI VR321",                             VIA_P4M900,  0x1462, 0x3355, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+     {"MSI P4M900M / P4M900M2-F/L",            VIA_P4M900,  0x1462, 0x7255, VIA_DEVICE_CRT},
+     {"MSI P4M900M3-L",                        VIA_P4M900,  0x1462, 0x7387, VIA_DEVICE_CRT},
+     {"Twinhead H12V",                         VIA_P4M900,  0x14FF, 0xA00F, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
++    {"Twinhead K15V",                         VIA_P4M900,  0x14FF, 0xA012, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+     {"Everex NC1501/NC1503",                  VIA_P4M900,  0x1509, 0x1E30, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+     {"Clevo M660SE",                          VIA_P4M900,  0x1558, 0x0664, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+     {"Clevo M660SR",                          VIA_P4M900,  0x1558, 0x0669, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+@@ -198,6 +204,7 @@ static struct ViaCardIdStruct ViaCardId[] = {
+     {"Fujitsu/Siemens Amilo Pro V3515",       VIA_P4M900,  0x1734, 0x10CB, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+     {"Fujitsu/Siemens Amilo Li1705",          VIA_P4M900,  0x1734, 0x10F7, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+     {"ASRock P4VM900-SATA2",                  VIA_P4M900,  0x1849, 0x3371, VIA_DEVICE_CRT},
++    {"Semp Informática Notebook IS 1462",     VIA_P4M900,  0x1509, 0x1D41, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ 
+     /*** CX700 ***/
+     {"VIA VT8454B",                           VIA_CX700,   0x0908, 0x1975, VIA_DEVICE_CRT}, /* Evaluation board, reference possibly wrong */
+@@ -224,14 +231,21 @@ static struct ViaCardIdStruct ViaCardId[] = {
+ 
+     /*** VX800 ***/
+     {"VIA Epia M700",                         VIA_VX800,   0x1106, 0x1122, VIA_DEVICE_CRT},
++    {"Guillemot-Hercules ECafe EC900B",       VIA_VX800,   0x1106, 0x3349, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+     {"VIA OpenBook",                          VIA_VX800,   0x1170, 0x0311, VIA_DEVICE_CRT | VIA_DEVICE_LCD}, /* VIA OpenBook eNote VBE8910 */
+     {"Samsung NC20",                          VIA_VX800,   0x144d, 0xc04e, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
++    {"FIC CE2A1",                             VIA_VX800,   0x1509, 0x3002, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+     {"Quanta DreamBook Light IL1",            VIA_VX800,   0x152d, 0x0771, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+     {"Lenovo S12",                            VIA_VX800,   0x17aa, 0x388c, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
++    {"Siragon ML-6200",                       VIA_VX800,   0x1106, 0x2211, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ 
+     /*** VX855 ***/
+     {"VIA VT8562C",                           VIA_VX855,   0x1106, 0x5122, VIA_DEVICE_CRT},
++    {"OLPC XO 1.5",                           VIA_VX855,   0x152D, 0x0833, VIA_DEVICE_LCD},
+ 
++    /*** VX900 ***/
++    {"Foxconn L740",                          VIA_VX900,   0x105B, 0x0CFD, VIA_DEVICE_LCD | VIA_DEVICE_CRT},
++
+     /* keep this */
+     {NULL,                                    VIA_UNKNOWN, 0x0000, 0x0000, VIA_DEVICE_NONE}
+ };
+Index: src/via_timing.h
+===================================================================
+--- src/via_timing.h	(.../tags/release_0_2_904)	(revision 916)
++++ src/via_timing.h	(.../trunk)	(revision 916)
+@@ -40,7 +40,7 @@
+ #define TIMING_CVT_WARN_REFRESH_RATE_NOT_RB 1 << 3
+ 
+ /**
+- * Geneartes a CVT modeline
++ * Generates a CVT modeline
+  * mode must not be null, if mode->name is null a new char* will be allocated. 
+  * 
+  */


More information about the scm-commits mailing list