Blob Blame History Raw
Index: configure.ac
===================================================================
--- configure.ac	(.../tags/release_0_2_903)	(revision 751)
+++ configure.ac	(.../trunk)	(revision 751)
@@ -70,7 +70,7 @@
 XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto)
 
 # Checks for pkg-config packages
-PKG_CHECK_MODULES(XORG, [xorg-server xproto xvmc fontsproto libdrm $REQUIRED_MODULES])
+PKG_CHECK_MODULES(XORG, [xorg-server xproto fontsproto libdrm $REQUIRED_MODULES])
 sdkdir=$(pkg-config --variable=sdkdir xorg-server)
 
 # Checks for libraries.
@@ -126,6 +126,7 @@
 
 if test "x$XVMC" = xyes; then
 	AC_CHECK_HEADERS(pthread.h sys/ioctl.h sys/time.h time.h,,[XVMC="no"; break],)
+	PKG_CHECK_MODULES(XVMC, [x11 xext xvmc])
 fi
 
 AC_MSG_CHECKING([whether to build XvMC driver support])
@@ -133,33 +134,10 @@
 
 AM_CONDITIONAL(XVMC, test x$XVMC = xyes)
 
-AC_CHECK_FILE([${sdkdir}/xf86Module.h],
-              [have_xf86Module_h="yes"], [have_xf86Module_h="no"])
-
 # Check the ABI_VIDEODRV_VERSION
 SAVE_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS $XORG_CFLAGS"
 		
-if test "x$have_xf86Module_h" = xyes; then
-AC_MSG_CHECKING([whether to use old Xv ABI])
-        AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[
-                           ]])],
-                           [OLD_XVABI=no],
-			   [OLD_XVABI=yes])
-else
-        OLD_XVABI=yes
-        echo -n "xf86Module.h not found, "
-fi
-
-CFLAGS="$SAVE_CFLAGS"
-
-if test "x$OLD_XVABI" = xyes; then
-                echo "yes."
-else
-                echo "no."
-                AC_DEFINE(USE_NEW_XVABI, 1, [Use new Xv ABI (7.1RC1+)])
-fi
-
 AM_CONDITIONAL(XSERVER_LIBPCIACCESS, test x$XSERVER_LIBPCIACCESS = xyes)
 if test "$XSERVER_LIBPCIACCESS" = yes; then
         AC_DEFINE(XSERVER_LIBPCIACCESS,1,[Enable libpciaccess])
@@ -186,7 +164,6 @@
 AC_DEFINE(X_USE_REGION_NULL,1,[Compatibility define for older Xen])
 AC_DEFINE(X_HAVE_XAAGETROP,1,[Compatibility define for older Xen])
 AC_DEFINE(X_NEED_I2CSTART,1,[Compatibility define for older Xen])
-AC_DEFINE(VIA_HAVE_EXA,1,[Build support for Exa])
 
 DRIVER_MAN_SUFFIX="4"
 AC_SUBST([DRIVER_MAN_SUFFIX])
Index: libxvmc/Makefile.am
===================================================================
--- libxvmc/Makefile.am	(.../tags/release_0_2_903)	(revision 751)
+++ libxvmc/Makefile.am	(.../trunk)	(revision 751)
@@ -24,13 +24,13 @@
 	xf86dristr.h \
 	vldXvMC.h
 
-libchromeXvMC_la_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(top_srcdir)/src -I$(top_srcdir)/libxvmc -DTRUE=1 -DFALSE=0
+libchromeXvMC_la_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ @XVMC_CFLAGS@ -I$(top_srcdir)/src -I$(top_srcdir)/libxvmc -DTRUE=1 -DFALSE=0
 libchromeXvMC_la_LDFLAGS = -version-number 1:0:0
-libchromeXvMC_la_LIBADD = @DRI_LIBS@
+libchromeXvMC_la_LIBADD = @DRI_LIBS@ @XVMC_LIBS@
 
-libchromeXvMCPro_la_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(top_srcdir)/src -I$(top_srcdir)/libxvmc -DTRUE=1 -DFALSE=0
+libchromeXvMCPro_la_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ @XVMC_CFLAGS@ -I$(top_srcdir)/src -I$(top_srcdir)/libxvmc -DTRUE=1 -DFALSE=0
 libchromeXvMCPro_la_LDFLAGS = -version-number 1:0:0
-libchromeXvMCPro_la_LIBADD = @DRI_LIBS@
+libchromeXvMCPro_la_LIBADD = @DRI_LIBS@ @XVMC_LIBS@
 else
 EXTRA_DIST = \
 	driDrawable.c \
Index: libxvmc/viaLowLevel.c
===================================================================
--- libxvmc/viaLowLevel.c	(.../tags/release_0_2_903)	(revision 751)
+++ libxvmc/viaLowLevel.c	(.../trunk)	(revision 751)
@@ -276,8 +276,8 @@
 	xl->tsMem.context = *(xl->drmcontext);
 	xl->tsMem.size = 64;
 	xl->tsMem.type = VIA_MEM_VIDEO;
-	if (drmCommandWriteRead(xl->fd, DRM_VIA_ALLOCMEM, &xl->tsMem,
-		sizeof(xl->tsMem)) < 0)
+	if ((ret = drmCommandWriteRead(xl->fd, DRM_VIA_ALLOCMEM, &xl->tsMem,
+		sizeof(xl->tsMem))) < 0)
 	    return ret;
 	if (xl->tsMem.size != 64)
 	    return -1;
Index: libxvmc/viaLowLevelPro.c
===================================================================
--- libxvmc/viaLowLevelPro.c	(.../tags/release_0_2_903)	(revision 751)
+++ libxvmc/viaLowLevelPro.c	(.../trunk)	(revision 751)
@@ -1460,13 +1460,13 @@
 
     if (size != mem->size) {
 	if (mem->size)
-	    drmCommandWrite(xl->fd, DRM_VIA_FREEMEM, mem, sizeof(mem));
+	    drmCommandWrite(xl->fd, DRM_VIA_FREEMEM, mem, sizeof(*mem));
 	mem->context = *(xl->drmcontext);
 	mem->size = size;
 	mem->type = VIA_MEM_VIDEO;
 
 	if (((ret = drmCommandWriteRead(xl->fd, DRM_VIA_ALLOCMEM, mem,
-			sizeof(mem))) < 0) || mem->size != size) {
+			sizeof(*mem))) < 0) || mem->size != size) {
 	    mem->size = 0;
 	    return -1;
 	}
@@ -1484,7 +1484,7 @@
     drm_via_mem_t *mem = &buf->mem;
 
     if (mem->size)
-	drmCommandWrite(xl->fd, DRM_VIA_FREEMEM, mem, sizeof(mem));
+	drmCommandWrite(xl->fd, DRM_VIA_FREEMEM, mem, sizeof(*mem));
     mem->size = 0;
 }
 
Index: libxvmc/viaXvMC.c
===================================================================
--- libxvmc/viaXvMC.c	(.../tags/release_0_2_903)	(revision 751)
+++ libxvmc/viaXvMC.c	(.../trunk)	(revision 751)
@@ -248,7 +248,7 @@
     return errType;
 }
 
-Status
+_X_EXPORT Status
 XvMCCreateContext(Display * display, XvPortID port,
     int surface_type_id, int width, int height, int flags,
     XvMCContext * context)
@@ -572,7 +572,7 @@
     return Success;
 }
 
-Status
+_X_EXPORT Status
 XvMCDestroyContext(Display * display, XvMCContext * context)
 {
     ViaXvMCContext *pViaXvMC;
@@ -594,7 +594,7 @@
     return releaseContextResources(display, context, 1, Success);
 }
 
-Status
+_X_EXPORT Status
 XvMCCreateSurface(Display * display, XvMCContext * context,
     XvMCSurface * surface)
 {
@@ -661,7 +661,7 @@
     return Success;
 }
 
-Status
+_X_EXPORT Status
 XvMCDestroySurface(Display * display, XvMCSurface * surface)
 {
     ViaXvMCSurface *pViaSurface;
@@ -684,7 +684,7 @@
     return Success;
 }
 
-Status
+_X_EXPORT Status
 XvMCPutSlice2(Display * display, XvMCContext * context, char *slice,
     int nBytes, int sliceCode)
 {
@@ -711,7 +711,7 @@
     return Success;
 }
 
-Status
+_X_EXPORT Status
 XvMCPutSlice(Display * display, XvMCContext * context, char *slice,
     int nBytes)
 {
@@ -781,7 +781,7 @@
     return Success;
 }
 
-Status
+_X_EXPORT Status
 XvMCPutSurface(Display * display, XvMCSurface * surface, Drawable draw,
     short srcx, short srcy, unsigned short srcw,
     unsigned short srch, short destx, short desty,
@@ -964,7 +964,7 @@
     printf("flags: 0x%x\n", control->flags);
 }
 
-Status
+_X_EXPORT Status
 XvMCBeginSurface(Display * display,
     XvMCContext * context,
     XvMCSurface * target_surface,
@@ -1062,7 +1062,7 @@
     return Success;
 }
 
-Status
+_X_EXPORT Status
 XvMCSyncSurface(Display * display, XvMCSurface * surface)
 {
     ViaXvMCSurface *pViaSurface;
@@ -1124,7 +1124,7 @@
     return Success;
 }
 
-Status
+_X_EXPORT Status
 XvMCLoadQMatrix(Display * display, XvMCContext * context,
     const XvMCQMatrix * qmx)
 {
@@ -1174,7 +1174,7 @@
  * standard completeness.
  */
 
-Status XvMCRenderSurface
+_X_EXPORT Status XvMCRenderSurface
     (Display * display,
     XvMCContext * context,
     unsigned int picture_structure,
@@ -1189,20 +1189,20 @@
     return (error_base + XvMCBadContext);
 }
 
-Status XvMCCreateBlocks
+_X_EXPORT Status XvMCCreateBlocks
     (Display * display,
     XvMCContext * context, unsigned int num_blocks, XvMCBlockArray * block)
 {
     return (error_base + XvMCBadContext);
 }
 
-Status
+_X_EXPORT Status
 XvMCDestroyBlocks(Display * display, XvMCBlockArray * block)
 {
     return Success;
 }
 
-Status XvMCCreateMacroBlocks
+_X_EXPORT Status XvMCCreateMacroBlocks
     (Display * display,
     XvMCContext * context,
     unsigned int num_blocks, XvMCMacroBlockArray * blocks)
@@ -1210,13 +1210,13 @@
     return (error_base + XvMCBadContext);
 }
 
-Status
+_X_EXPORT Status
 XvMCDestroyMacroBlocks(Display * display, XvMCMacroBlockArray * block)
 {
     return (error_base + XvMCBadContext);
 }
 
-Status
+_X_EXPORT Status
 XvMCCreateSubpicture(Display * display,
     XvMCContext * context,
     XvMCSubpicture * subpicture,
@@ -1277,7 +1277,7 @@
     return Success;
 }
 
-Status
+_X_EXPORT Status
 XvMCSetSubpicturePalette(Display * display, XvMCSubpicture * subpicture,
     unsigned char *palette)
 {
@@ -1356,7 +1356,7 @@
     return 0;
 }
 
-Status
+_X_EXPORT Status
 XvMCClearSubpicture(Display * display,
     XvMCSubpicture * subpicture,
     short x,
@@ -1399,7 +1399,7 @@
     return Success;
 }
 
-Status
+_X_EXPORT Status
 XvMCCompositeSubpicture(Display * display,
     XvMCSubpicture * subpicture,
     XvImage * image,
@@ -1463,7 +1463,7 @@
     return Success;
 }
 
-Status
+_X_EXPORT Status
 XvMCBlendSubpicture(Display * display,
     XvMCSurface * target_surface,
     XvMCSubpicture * subpicture,
@@ -1503,7 +1503,7 @@
     return Success;
 }
 
-Status
+_X_EXPORT Status
 XvMCBlendSubpicture2(Display * display,
     XvMCSurface * source_surface,
     XvMCSurface * target_surface,
@@ -1600,7 +1600,7 @@
     return Success;
 }
 
-Status
+_X_EXPORT Status
 XvMCSyncSubpicture(Display * display, XvMCSubpicture * subpicture)
 {
     ViaXvMCSubPicture *pViaSubPic;
@@ -1627,7 +1627,7 @@
     return retVal;
 }
 
-Status
+_X_EXPORT Status
 XvMCFlushSubpicture(Display * display, XvMCSubpicture * subpicture)
 {
     ViaXvMCSubPicture *pViaSubPic;
@@ -1642,7 +1642,7 @@
     return Success;
 }
 
-Status
+_X_EXPORT Status
 XvMCDestroySubpicture(Display * display, XvMCSubpicture * subpicture)
 {
     ViaXvMCSubPicture *pViaSubPic;
@@ -1681,7 +1681,7 @@
     return Success;
 }
 
-Status
+_X_EXPORT Status
 XvMCGetSubpictureStatus(Display * display, XvMCSubpicture * subpic, int *stat)
 {
     ViaXvMCSubPicture *pViaSubPic;
@@ -1705,7 +1705,7 @@
     return Success;
 }
 
-Status
+_X_EXPORT Status
 XvMCFlushSurface(Display * display, XvMCSurface * surface)
 {
     ViaXvMCSurface *pViaSurface;
@@ -1735,7 +1735,7 @@
     return ret;
 }
 
-Status
+_X_EXPORT Status
 XvMCGetSurfaceStatus(Display * display, XvMCSurface * surface, int *stat)
 {
     ViaXvMCSurface *pViaSurface;
@@ -1770,7 +1770,7 @@
     return ret;
 }
 
-XvAttribute *
+_X_EXPORT XvAttribute *
 XvMCQueryAttributes(Display * display, XvMCContext * context, int *number)
 {
     ViaXvMCContext *pViaXvMC;
@@ -1797,7 +1797,7 @@
     return ret;
 }
 
-Status
+_X_EXPORT Status
 XvMCSetAttribute(Display * display,
     XvMCContext * context, Atom attribute, int value)
 {
@@ -1850,7 +1850,7 @@
     return Success;
 }
 
-Status
+_X_EXPORT Status
 XvMCGetAttribute(Display * display,
     XvMCContext * context, Atom attribute, int *value)
 {
@@ -1884,7 +1884,7 @@
     return Success;
 }
 
-Status
+_X_EXPORT Status
 XvMCHideSurface(Display * display, XvMCSurface * surface)
 {
 
Index: ChangeLog
===================================================================
--- ChangeLog	(.../tags/release_0_2_903)	(revision 751)
+++ ChangeLog	(.../trunk)	(revision 751)
@@ -1,3 +1,323 @@
+2009-03-21  Xavier Bachelot  <xavier@bachelot.org>
+
+	* src/via_bios.h:
+	* src/via_display.c: (ViaDisplaySetStreamOnDFP):
+	* src/via_driver.c: (VIAPreInit), (VIASave), (VIARestore),
+	(VIADPMS):
+	* src/via_driver.h:
+	* src/via_mode.c: (ViaDFPDetect), (ViaOutputsDetect),
+	(ViaOutputsSelect), (ViaDFPPower), (ViaModeSet):
+
+	CX700 integrated TMDS (Patch courtesy Tim Chen from VIA).
+
+2009-02-19  Gabriel Mansi  <gabriel-dot-mansi-at-gmail-dot-com>
+
+	* src/via_driver.c: (VIAScreenInit), (VIAWriteMode):
+
+	Initialize CRTC before a mode switch. Fix bug #260.
+
+2009-01-26  Jon Nettleton <jon.nettleton@gmail.com>
+
+	* src/via_accel.c: (viaInitXAA), (viaExaCheckComposite):
+
+	a couple of small compatibility fixes for XAA and EXA.
+
+2009-01-17  Jon Nettleton  <jon.nettleton@gmail.com>
+
+	* libxvmc/viaLowLevel.c: (viaDMAInitTimeStamp):
+	* src/via_accel.c: (viaDisableVQ):
+	* src/via_video.c: (viaVideoFillPixmap):
+
+	viaLowLevel.c and via_accel.c are fixes by 
+	Bartosz Kosiorek.  The via_video.c is a syntax
+	fix by Robert Bridge.  Thanks for the bug fixes.
+
+2009-01-17  Jon Nettleton  <jon.nettleton@gmail.com>
+
+	* configure.ac:
+	* src/via_accel.c: (viaInitAccel), (viaExitAccel),
+	(viaFinishInitAccel):
+	* src/via_driver.c: (VIASetup), (VIASetupDefaultOptions),
+	(VIAPreInit), (VIAWriteMode), (VIAInitialize3DEngine):
+	* src/via_driver.h:
+	* src/via_memory.c: (viaExaFBSave), (VIAFreeLinear),
+	(viaOffScreenLinear), (VIAInitLinear):
+	* src/via_priv.h:
+
+	Patch submitted by Robert Bridge, originally started by
+	Xavier Bachelot, to remove old EXA support.  We are moving
+	forward with the driver and are no longer supporting the
+	old EXA initializations.	
+
+2009-01-14  Jon Nettleton  <jon.nettleton@gmail.com>
+
+	* src/via_accel.c: (viaDisableVQ), (viaInitialize2DEngine),
+	(viaAccelSync):
+
+	According to VIA's code the P4M900 should have the same
+	acceleration initialization registers as the K8M890.  This
+	patch fixes this and gives about a 10x increase in the 
+	video benchmark numbers.
+
+2009-01-14  Jon Nettleton  <jon.nettletno@gmail.com>
+
+	* src/via_accel.c: (viaFlushPCI):
+
+	remove the check for VIA_3D_ENG_BUSY in the idle loop.
+	This causes xorg to chew a bit more cpu with XAA enabled,
+	and it causes the entire X server to dump if EXA is enabled.
+	I should investigate further, but for now I will just remove
+	it.
+
+2009-01-14  Jon Nettleton  <jon.nettleton@gmail.com>
+
+	* src/via_accel.c: (viaFlushPCI):
+
+	Oops forgot to change registers for the vx800 chipset
+	when waiting for Idle in the engines.  I also added
+	back in waiting for the 3d engine to be idle.  I am
+	not sure if this was removed for a reason.
+
+2009-01-07  Jon Nettleton <jon.nettleton@gmail.com>
+
+	* src/via_bios.h:
+	* src/via_crtc.c: (via_xf86crtc_resize), (ViaPreInitCRTCConfig):
+	* src/via_driver.c: (VIAPreInit):
+
+	Temporary hack to fix a bug with newer Xorg and DRI
+	that crashes if CRTC is not setup.  I am adding this
+	because I am working on this part of the code anyways
+	so it won't get lost in bit rot.
+
+2009-01-06  Jon Nettleton  <jon.nettleton@gmail.com>
+
+	* src/via_mode.c: (ViaModesMonitorFixup), (ViaModesAttachHelper):
+
+	Make sure that the monitor settings will handle our
+	internal Modes set for TV out and LCD Panels.
+
+2009-01-05  Jon Nettleton  <jon.nettleton@gmail.com>
+
+	* src/via_cursor.c: (viaHWCursorInit), (viaLoadCursorImage):
+
+	A couple more tweaks to fix mono hardware cursor on older
+	chipsets.
+
+2009-01-05  Jon Nettleton  <jon.nettleton@gmail.com>
+
+	* src/via_cursor.c: (viaHWCursorInit), (viaUseHWCursorARGB),
+	(viaUseHWCursor):
+	* src/via_driver.c: (VIAScreenInit):
+
+	Missed a couple of changes for the chipset specific
+	cursors.  Moved chipset detection to HWInit.  Removed
+	some extraneous debugging.
+
+2009-01-04  Gabriel Mansi  <gabriel-dot-mansi-at-gmail-dot-com>
+
+	* src/via.h:
+	* src/via_accel.c: (viaInitialize2DEngine):
+	* src/via_crtc.c: (ViaFirstCRTCSetMode), (ViaSecondCRTCSetMode):
+	* src/via_driver.c: (ViaMMIOEnable), (ViaMMIODisable),
+	(VIAWriteMode):
+	* src/via_swov.c: (SetFIFO_V3), (Upd_Video):
+	* src/via_video.c: (DecideOverlaySupport):
+
+	Initial XVideo support for VX800.
+
+2009-01-04  Jon Nettleton  <jon.nettleton@gmail.com>
+
+	* src/via_cursor.c: (viaHWCursorInit), (viaCursorSetFB),
+	(viaUseHWCursorARGB), (viaUseHWCursor), (viaLoadCursorImage),
+	(viaSetCursorColors), (viaLoadCursorARGB):
+	* src/via_driver.h:
+
+	Okay I tried to cheat.  We need to have some chipset
+	specific intelligence.  I have added this back into
+	the initial test to check for HWCursor support.
+
+2009-01-04  Jon Nettleton <jon.nettleton@gmail.com>
+
+	* src/via_accel.c: (viaInitXAA), (viaInitAccel):
+	* src/via_crtc.c: (ViaSecondCRTCSetStartingAddress):
+	* src/via_cursor.c: (viaHWCursorInit), (viaCursorSetFB),
+	(viaCursorStore), (viaCursorRestore), (viaShowCursor),
+	(viaHideCursor), (viaSetCursorPosition), (viaUseHWCursorARGB),
+	(viaUseHWCursor), (viaLoadCursorImage), (viaSetCursorColors),
+	(viaLoadCursorARGB):
+	* src/via_dga.c: (VIADGASetMode):
+	* src/via_driver.c: (VIAFreeRec), (VIASetupDefaultOptions),
+	(VIAPreInit), (VIAEnterVT), (VIALeaveVT), (VIAScreenInit),
+	(VIACloseScreen):
+	* src/via_driver.h:
+	* src/via_regs.h:
+
+	This is a take at reworking HWCursor.  It works off the
+	ttm_branch and the work done in the randr_branch.  It only needs
+	marginal testing as HWCursor was already very broken.
+
+2009-01-04  Jon Nettleton  <jon.nettleton@gmail.com>
+
+	* src/via_driver.c: (VIAMapMMIO), (VIAMapFB):
+
+	Moved pVia->FrameBufferBase setting to within
+	VIAMapFB where it was before being called without
+	being set.
+
+2009-01-04  Jon Nettleton  <jon.nettleton@gmail.com>
+
+	* src/via_driver.c: (VIAPreInit):
+
+	Patch submitted by Robert Bridge to clean up compiler
+        warnings.  Should close trac ticket #243.  Thanks
+	RobbieAB.
+
+2008-12-29  Jon Nettleton  <jon.nettleton@gmail.com>
+
+	* src/via_accel.c: (viaInitXAA):
+	* src/via_driver.c: (VIAMapMMIO), (VIAMapFB):
+
+	Finally tracked down the XAA libpciaccess bug.  Also
+	Realized I had not enabled write-combining on the main
+	framebuffer.  This should give a small speed boost.
+
+2008-12-26  Jon Nettleton <jon.nettleton@gmail.com>
+
+	* src/via_mode.h:
+
+	Added support for all Modes in ViaPanelNativeModes to
+	ViaPanelModes.  Modes used are from Via's released driver
+	in ViaSupportModes.
+
+2008-11-04  Jon Nettleton  <jon.nettleton@gmail.com>
+
+	* src/via_crtc.c: (ViaFirstCRTCSetMode), (ViaSecondCRTCSetMode):
+
+	Found needed register writes that are needed so VX800 doesn't
+	crash when CRT is not enabled.  I also removed NEEDS FIXING
+        comments from them as they are obviously needed.
+
+2008-11-03  Jon Nettleton  <jon.nettleton@gmail.com>
+
+	* src/via_accel.c: (viaSubsequentMono8x8PatternFillRect),
+	(viaSetupForSolidLine), (viaSubsequentSolidHorVertLine),
+	(viaSetupForDashedLine), (viaAccelMarkSync):
+
+	A few more acceleration tweaks for the VX800.  
+	This should fix all the XAA rendering issues.
+	This should also allow 800x480 Panels to work without
+	custom modelines.
+
+2008-11-02  Jon Nettleton  <jon.nettleton@gmail.com>
+
+	* src/via_accel.c: (viaFlushPCI), (viaDisableVQ),
+	(viaInitialize2DEngine), (viaAccelSync), (viaPitchHelper),
+	(viaAccelClippingHelper), (viaAccelSolidHelper),
+	(viaAccelTransparentHelper), (viaAccelCopyHelper),
+	(viaSetupForScreenToScreenCopy), (viaSubsequentScreenToScreenCopy),
+	(viaSetupForSolidFill), (viaSubsequentSolidFillRect),
+	(viaSetupForMono8x8PatternFill),
+	(viaSubsequentMono8x8PatternFillRect),
+	(viaSetupForColor8x8PatternFill),
+	(viaSubsequentColor8x8PatternFillRect),
+	(viaSetupForCPUToScreenColorExpandFill),
+	(viaSubsequentScanlineCPUToScreenColorExpandFill),
+	(viaSetupForImageWrite), (viaSubsequentImageWriteRect),
+	(viaSetupForSolidLine), (viaSubsequentSolidTwoPointLine),
+	(viaSubsequentSolidHorVertLine), (viaSetupForDashedLine),
+	(viaInitXAA), (viaAccelMarkSync), (viaExaPrepareSolid),
+	(viaExaSolid), (viaExaPrepareCopy), (viaExaCopy):
+	* src/via_bandwidth.c: (ViaSetPrimaryFIFO), (ViaSetSecondaryFIFO):
+	* src/via_cursor.c: (viaCursorARGBInit), (viaCursorARGBShow),
+	(viaCursorARGBHide), (viaCursorARGBSetPosition),
+	(viaCursorRecInit):
+	* src/via_driver.c: (VIASetupDefaultOptions), (VIAPreInit),
+	(VIALeaveVT), (VIACloseScreen):
+	* src/via_driver.h:
+	* src/via_id.c:
+	* src/via_id.h:
+	* src/via_mode.c: (ViaOutputsSelect), (VIAGetPanelSize),
+	(ViaPanelGetIndex):
+	* src/via_mode.h:
+	* src/via_panel.c: (ViaPanelPreInit):
+	* src/via_regs.h:
+	* src/via_swov.c: (VIAVidHWDiffInit), (viaCalculateVideoColor),
+	(viaSetColorSpace), (ViaInitVideoStatusFlag), (ViaSetVidCtl),
+	(SetFIFO_V3_64or32or32), (SetFIFO_V3_64or32or16):
+	* src/via_video.c: (viaInitVideo):
+
+        Initial support for the VX800 chipset.  This is based off the
+        Basic chipset support work of Xavier Bachelot and the inital
+        Acceleration work done by Harald Welte.  I verified the changes
+        based off the most recent VIA codebaase and fixed a couple of
+        rendering issues.
+
+        Still needs more work on EXA ( font rendering glitches ) and
+        XVideo.
+
+2008-05-26  Gabriel Mansi <gabriel.mansi@gmail.com>
+
+	* src/Makefile.am:
+	* src/via_accel.c: (viaInitAccel):
+	* src/via_bios.h:
+	* src/via_crtc.c: (ViaCRTCSetGraphicsRegisters),
+	(ViaCRTCSetAttributeRegisters), (ViaCRTCInit),
+	(ViaFirstCRTCSetMode), (ViaFirstCRTCSetStartingAddress),
+	(ViaSecondCRTCSetStartingAddress),
+	(ViaSecondCRTCHorizontalQWCount), (ViaSecondCRTCHorizontalOffset),
+	(ViaSecondCRTCSetMode), (ViaFirstCRTCModeValid),
+	(ViaSecondCRTCModeValid), (ViaShadowCRTCSetMode):
+	* src/via_cursor.c: (viaCursorARGBInit), (viaCursorSetFB),
+	(viaCursorHWInit), (viaCursorHWShow), (viaCursorHWHide),
+	(viaCursorShow), (viaCursorHide), (viaCursorLoadImage),
+	(viaCursorHWSetPosition), (viaCursorSetPosition),
+	(viaCursorSetColors), (viaCursorStore), (viaCursorRestore),
+	(viaCursorARGBShow), (viaCursorARGBHide),
+	(viaCursorARGBSetPosition), (viaCursorARGBUse),
+	(viaCursorARGBLoad), (viaCursorRecInit), (viaCursorRecDestroy),
+	(viaCursorHWUse):
+	* src/via_dga.c: (VIADGASetMode):
+	* src/via_display.c: (ViaSecondDisplayChannelEnable),
+	(ViaSecondDisplayChannelDisable), (ViaDisplayInit),
+	(ViaDisplayEnableSimultaneous), (ViaDisplayDisableSimultaneous),
+	(ViaDisplayEnableCRT), (ViaDisplayDisableCRT),
+	(ViaDisplaySetStreamOnCRT):
+	* src/via_driver.c: (VIAGetRec), (VIAFreeRec),
+	(VIASetupDefaultOptions), (VIAPreInit), (VIAEnterVT), (VIALeaveVT),
+	(ViaGammaDisable), (VIASave), (VIARestore), (ViaMMIOEnable),
+	(ViaMMIODisable), (VIAMapMMIO), (VIAUnmapMem), (VIALoadPalette),
+	(VIAScreenInit), (VIAWriteMode), (VIACloseScreen),
+	(VIAAdjustFrame), (VIADPMS):
+	* src/via_driver.h:
+	* src/via_lvds.c: (ViaLVDSPowerFirstSequence),
+	(ViaLVDSPowerSecondSequence), (ViaLVDSDFPPower),
+	(ViaLVDSPowerChannel), (ViaLVDSPower):
+	* src/via_mode.c: (ViaPrintMode), (ViaOutputsSelect),
+	(VIAGetPanelSize), (ViaPanelGetIndex), (ViaModesAttach),
+	(ViaValidMode), (VIASetLCDMode), (ViaModePrimaryLegacy),
+	(ViaModeSecondaryLegacy), (ViaLCDPower), (ViaModeFirstCRTC),
+	(ViaModeSecondCRTC), (ViaModeSet):
+	* src/via_panel.c: (ViaPanelLookUpModeIndex),
+	(ViaPanelGetNativeModeFromOption),
+	(ViaPanelGetNativeModeFromScratchPad), (ViaPanelScaleDisable),
+	(ViaPanelScale), (ViaPanelGetNativeDisplayMode), (ViaPanelPreInit),
+	(ViaPanelCenterMode), (ViaPanelGetSizeFromEDID),
+	(ViaPanelGetSizeFromDDCv1), (ViaPanelGetSizeFromDDCv2):
+	* src/via_regs.h:
+	* src/via_swov.c: (Upd_Video):
+	* src/via_timing.c: (froundf), (timingGenerateMode),
+	(viaTimingCvt), (viaTimingGtf):
+	* src/via_timing.h:
+	* src/via_vbe.c: (ViaVbeGetActiveDevices), (ViaVbeSetMode),
+	(ViaVbeDoDPMS):
+	* src/via_video.c: (DecideOverlaySupport), (viaSaveVideo),
+	(viaRestoreVideo):
+
+	Merge panel code from randr branch (rev. 427 to 553)
+	Add native mode setting for P4M890, P4M900, K8M890 and CX700
+	Add LVDS power functions for P4M900 and CX700
+	Add ARGB hardware cursor support
+
 2008-03-11  Xavier Bachelot  <xavier-at-bachelot-dot-org>
 
 	* configure.ac:
Index: src/via_panel.c
===================================================================
--- src/via_panel.c	(.../tags/release_0_2_903)	(revision 0)
+++ src/via_panel.c	(.../trunk)	(revision 751)
@@ -0,0 +1,461 @@
+/*
+ * Copyright 2007 The Openchrome Project [openchrome.org]
+ * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ * Copyright 1998-2007 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2007 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Core panel functions.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "via.h"
+#include "via_driver.h"
+#include "via_vgahw.h"
+#include "via_id.h"
+#include "via_timing.h"
+
+static ViaPanelModeRec ViaPanelNativeModes[] = {
+    {640, 480},
+    {800, 600},
+    {1024, 768},
+    {1280, 768},
+    {1280, 1024},
+    {1400, 1050},
+    {1600, 1200},
+    {1280, 800},
+    {800, 480},
+    {1366, 768},
+    {1360, 768},
+    {1920, 1080},
+    {1920, 1200},
+    {1024, 600},
+    {1440, 900},
+    {1280, 720}
+};
+
+static int
+ViaPanelLookUpModeIndex(int width, int height)
+{
+    int i, index = VIA_PANEL_INVALID;
+    int length = sizeof(ViaPanelNativeModes) / sizeof(ViaPanelModeRec);
+
+    for (i = 0; i < length; i++) {
+        if (ViaPanelNativeModes[i].Width == width
+            && ViaPanelNativeModes[i].Height == height) {
+            index = i;
+            break;
+        }
+    }
+    return index;
+}
+
+/*
+ * Sets the panel dimensions from the configuration
+ * using name with format "9999x9999".
+ */
+void
+ViaPanelGetNativeModeFromOption(ScrnInfoPtr pScrn, char *name)
+{
+    VIAPtr pVia = VIAPTR(pScrn);
+    VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+    ViaPanelInfoPtr panel = pBIOSInfo->Panel;
+    CARD8 index;
+    CARD8 length;
+    char aux[10];
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                     "ViaPanelGetNativeModeFromOption\n"));
+
+    panel->NativeModeIndex = VIA_PANEL_INVALID;
+    if (strlen(name) < 10) {
+        length = sizeof(ViaPanelNativeModes) / sizeof(ViaPanelModeRec);
+
+        for (index = 0; index < length; index++) {
+            sprintf(aux, "%dx%d", ViaPanelNativeModes[index].Width,
+                    ViaPanelNativeModes[index].Height);
+            if (!xf86NameCmp(name, aux)) {
+                panel->NativeModeIndex = index;
+                panel->NativeMode->Width = ViaPanelNativeModes[index].Width;
+                panel->NativeMode->Height = ViaPanelNativeModes[index].Height;
+                break;
+            }
+        }
+    } else {
+        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                   "%s is not a valid panel size.\n", name);
+    }
+}
+
+/*
+ * Gets the native panel resolution from scratch pad registers.
+ */
+void
+ViaPanelGetNativeModeFromScratchPad(ScrnInfoPtr pScrn)
+{
+    VIAPtr pVia = VIAPTR(pScrn);
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+    CARD8 index;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                     "ViaPanelGetNativeModeFromScratchPad\n"));
+
+    index = hwp->readCrtc(hwp, 0x3F) & 0x0F;
+
+    ViaPanelInfoPtr panel = pVia->pBIOSInfo->Panel;
+
+    panel->NativeModeIndex = index;
+    panel->NativeMode->Width = ViaPanelNativeModes[index].Width;
+    panel->NativeMode->Height = ViaPanelNativeModes[index].Height;
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+               "Native Panel Resolution is %dx%d\n",
+               panel->NativeMode->Width, panel->NativeMode->Height);
+}
+
+void
+ViaPanelScaleDisable(ScrnInfoPtr pScrn)
+{
+    VIAPtr pVia = VIAPTR(pScrn);
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+    ViaCrtcMask(hwp, 0x79, 0x00, 0x01);
+    if (pVia->Chipset != VIA_CLE266 && pVia->Chipset != VIA_KM400)
+        ViaCrtcMask(hwp, 0xA2, 0x00, 0xC8);
+}
+
+void
+ViaPanelScale(ScrnInfoPtr pScrn, int resWidth, int resHeight,
+              int panelWidth, int panelHeight)
+{
+    VIAPtr pVia = VIAPTR(pScrn);
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+    int horScalingFactor = 0;
+    int verScalingFactor = 0;
+    CARD8 cra2 = 0;
+    CARD8 cr77 = 0;
+    CARD8 cr78 = 0;
+    CARD8 cr79 = 0;
+    CARD8 cr9f = 0;
+    Bool scaling = FALSE;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                     "ViaPanelScale: %d,%d -> %d,%d\n",
+                     resWidth, resHeight, panelWidth, panelHeight));
+
+    if (resWidth < panelWidth) {
+        /* FIXME: It is different for chipset < K8M800 */
+        horScalingFactor = ((resWidth - 1) * 4096) / (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;
+        scaling = TRUE;
+    }
+
+    if (resHeight < panelHeight) {
+        verScalingFactor = ((resHeight - 1) * 2048) / (panelHeight - 1);
+
+        /* Vertical scaling enabled */
+        cra2 |= 0x08;
+        cr79 |= ((verScalingFactor & 0x0001) << 3);       /* VSCaleFactor[0] at CR79[3] */
+        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;
+    }
+
+    if (scaling) {
+        DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                         "Scaling factor: horizontal %d (0x%x), vertical %d (0x%x)\n",
+                         horScalingFactor, horScalingFactor,
+                         verScalingFactor, verScalingFactor));
+
+        ViaCrtcMask(hwp, 0x77, cr77, 0xFF);
+        ViaCrtcMask(hwp, 0x78, cr78, 0xFF);
+        ViaCrtcMask(hwp, 0x79, cr79, 0xF8);
+        ViaCrtcMask(hwp, 0x9F, cr9f, 0x03);
+        ViaCrtcMask(hwp, 0x79, 0x03, 0x03);
+    } else
+        ViaCrtcMask(hwp, 0x79, 0x00, 0x01);
+
+    ViaCrtcMask(hwp, 0xA2, cra2, 0xC8);
+
+    /* Horizontal scaling selection: interpolation */
+    // ViaCrtcMask(hwp, 0x79, 0x02, 0x02);
+    // else
+    // ViaCrtcMask(hwp, 0x79, 0x00, 0x02);
+    /* Horizontal scaling factor selection original / linear */
+    //ViaCrtcMask(hwp, 0xA2, 0x40, 0x40);
+}
+
+
+/*
+ * Generates a display mode for the native panel resolution,  using CVT.
+ */
+static void
+ViaPanelGetNativeDisplayMode(ScrnInfoPtr pScrn)
+{
+    VIAPtr pVia = VIAPTR(pScrn);
+    ViaPanelModePtr panelMode = pVia->pBIOSInfo->Panel->NativeMode;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                     "ViaPanelGetNativeDisplayMode\n"));
+
+    if (panelMode->Width && panelMode->Height) {
+
+        /* TODO: fix refresh rate and check malloc */
+        DisplayModePtr p = malloc( sizeof(DisplayModeRec) ) ;
+        memset(p, 0, sizeof(DisplayModeRec));
+
+        float refresh = 60.0f ;
+
+        /* The following code is borrowed from xf86SetModeCrtc. */
+        if (p) {
+            viaTimingCvt(p, panelMode->Width, panelMode->Height, refresh, FALSE, TRUE);
+            p->CrtcHDisplay = p->HDisplay;
+            p->CrtcHSyncStart = p->HSyncStart;
+            p->CrtcHSyncEnd = p->HSyncEnd;
+            p->CrtcHTotal = p->HTotal;
+            p->CrtcHSkew = p->HSkew;
+            p->CrtcVDisplay = p->VDisplay;
+            p->CrtcVSyncStart = p->VSyncStart;
+            p->CrtcVSyncEnd = p->VSyncEnd;
+            p->CrtcVTotal = p->VTotal;
+
+            p->CrtcVBlankStart = min(p->CrtcVSyncStart, p->CrtcVDisplay);
+            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_WARNING,
+                   "Invalid panel dimension (%dx%d)\n", panelMode->Width,
+                   panelMode->Height);
+    }
+}
+
+void
+ViaPanelPreInit(ScrnInfoPtr pScrn)
+{
+    VIAPtr pVia = VIAPTR(pScrn);
+    VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaPanelPreInit\n"));
+
+    ViaPanelInfoPtr panel = pBIOSInfo->Panel;
+
+    /* First try to get the mode from EDID. */
+    if (panel->NativeModeIndex == VIA_PANEL_INVALID) {
+        int width, height;
+        Bool ret;
+
+        ret = ViaPanelGetSizeFromDDCv1(pScrn, &width, &height);
+/*
+        if (!ret)
+            ret = ViaPanelGetSizeFromDDCv2(pScrn, &width);
+*/
+        if (ret) {
+            panel->NativeModeIndex = ViaPanelLookUpModeIndex(width, height);
+            if (panel->NativeModeIndex != VIA_PANEL_INVALID) {
+                panel->NativeMode->Width = width;
+                panel->NativeMode->Height = height;
+            }
+        }
+    }
+
+    if (panel->NativeModeIndex == VIA_PANEL_INVALID)
+        ViaPanelGetNativeModeFromScratchPad(pScrn);
+
+    if (panel->NativeModeIndex != VIA_PANEL_INVALID)
+        ViaPanelGetNativeDisplayMode(pScrn);
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NativeModeIndex: %d\n", panel->NativeModeIndex )) ;
+
+}
+
+void
+ViaPanelCenterMode(DisplayModePtr centerMode, DisplayModePtr panelMode,
+                   DisplayModePtr mode)
+{
+    memcpy(centerMode, mode, sizeof(DisplayModeRec));
+
+    CARD32 HDiff = (panelMode->CrtcHDisplay - mode->CrtcHDisplay) / 2;
+    CARD32 VDiff = (panelMode->CrtcVDisplay - mode->CrtcVDisplay) / 2;
+
+    centerMode->CrtcHTotal += HDiff * 2;
+    centerMode->CrtcVTotal += VDiff * 2;
+
+    centerMode->CrtcHSyncStart += HDiff;
+    centerMode->CrtcHSyncEnd += HDiff;
+    centerMode->CrtcHBlankStart += HDiff;
+    centerMode->CrtcHBlankEnd += HDiff;
+
+    centerMode->CrtcVSyncStart += VDiff;
+    centerMode->CrtcVSyncEnd += VDiff;
+    centerMode->CrtcVBlankStart += VDiff;
+    centerMode->CrtcVBlankEnd += VDiff;
+}
+
+
+/*
+ * Try to interprete EDID ourselves.
+ */
+Bool
+ViaPanelGetSizeFromEDID(ScrnInfoPtr pScrn, xf86MonPtr pMon,
+                        int *width, int *height)
+{
+    int i, max = 0, vsize;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAGetPanelSizeFromEDID\n"));
+
+    /* !!! Why are we not checking VESA modes? */
+
+    /* checking standard timings */
+    for (i = 0; i < 8; i++)
+        if ((pMon->timings2[i].hsize > 256)
+            && (pMon->timings2[i].hsize > max)) {
+            max = pMon->timings2[i].hsize;
+            vsize = pMon->timings2[i].vsize;
+        }
+
+    if (max != 0) {
+        *width = max;
+        *height = vsize;
+        return TRUE;
+    }
+
+    /* checking detailed monitor section */
+
+    /* !!! skip Ranges and standard timings */
+
+    /* check detailed timings */
+    for (i = 0; i < DET_TIMINGS; i++)
+        if (pMon->det_mon[i].type == DT) {
+            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;
+                vsize = timing.v_active;
+            }
+        }
+
+    if (max != 0) {
+        *width = max;
+        *height = vsize;
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+Bool
+ViaPanelGetSizeFromDDCv1(ScrnInfoPtr pScrn, int *width, int *height)
+{
+    VIAPtr pVia = VIAPTR(pScrn);
+    xf86MonPtr pMon;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAGetPanelSizeFromDDCv1\n"));
+
+    if (!xf86I2CProbeAddress(pVia->pI2CBus2, 0xA0))
+        return FALSE;
+
+    pMon = xf86DoEDID_DDC2(pScrn->scrnIndex, pVia->pI2CBus2);
+    if (!pMon)
+        return FALSE;
+
+    pVia->DDC2 = pMon;
+
+    if (!pVia->DDC1) {
+        xf86PrintEDID(pMon);
+        xf86SetDDCproperties(pScrn, pMon);
+    }
+
+    if (!ViaPanelGetSizeFromEDID(pScrn, pMon, width, height)) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "Unable to read PanelSize from EDID information\n");
+        return FALSE;
+    }
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                     "VIAGetPanelSizeFromDDCv1: (%dx%d)\n", *width, *height));
+    return TRUE;
+}
+
+Bool
+ViaPanelGetSizeFromDDCv2(ScrnInfoPtr pScrn, int *width)
+{
+    VIAPtr pVia = VIAPTR(pScrn);
+    CARD8 W_Buffer[1];
+    CARD8 R_Buffer[4];
+    I2CDevPtr dev;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAGetPanelSizeFromDDCv2\n"));
+
+    if (!xf86I2CProbeAddress(pVia->pI2CBus2, 0xA2))
+        return FALSE;
+
+    dev = xf86CreateI2CDevRec();
+    if (!dev)
+        return FALSE;
+
+    dev->DevName = "EDID2";
+    dev->SlaveAddr = 0xA2;
+    dev->ByteTimeout = 2200;  /* VESA DDC spec 3 p. 43 (+10 %) */
+    dev->StartTimeout = 550;
+    dev->BitTimeout = 40;
+    dev->ByteTimeout = 40;
+    dev->AcknTimeout = 40;
+    dev->pI2CBus = pVia->pI2CBus2;
+
+    if (!xf86I2CDevInit(dev)) {
+        xf86DestroyI2CDevRec(dev, TRUE);
+        return FALSE;
+    }
+
+    xf86I2CReadByte(dev, 0x00, R_Buffer);
+    if (R_Buffer[0] != 0x20) {
+        xf86DestroyI2CDevRec(dev, TRUE);
+        return FALSE;
+    }
+
+    /* Found EDID2 Table */
+
+    W_Buffer[0] = 0x76;
+    xf86I2CWriteRead(dev, W_Buffer, 1, R_Buffer, 2);
+    xf86DestroyI2CDevRec(dev, TRUE);
+
+    *width = R_Buffer[0] | (R_Buffer[1] << 8);
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                     "VIAGetPanelSizeFromDDCv2: %d\n", *width));
+
+    return TRUE;
+}
Index: src/via_id.h
===================================================================
--- src/via_id.h	(.../tags/release_0_2_903)	(revision 751)
+++ src/via_id.h	(.../trunk)	(revision 751)
@@ -37,6 +37,7 @@
     VIA_P4M900,
     VIA_CX700,
     VIA_P4M890,
+    VIA_VX800,
     VIA_LAST
 };
 
@@ -52,6 +53,7 @@
 #define PCI_CHIP_VT3364         0x3371 /* P4M900 */
 #define PCI_CHIP_VT3324         0x3157 /* CX700 */
 #define PCI_CHIP_VT3327         0x3343 /* P4M890 */
+#define PCI_CHIP_VT3353         0x1122 /* VX800 */
 
 /* 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_903)	(revision 751)
+++ src/via_video.c	(.../trunk)	(revision 751)
@@ -112,11 +112,7 @@
 static int viaSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer);
 static int viaPutImage(ScrnInfoPtr, short, short, short, short, short, short,
     short, short, int, unsigned char *, short, short, Bool,
-    RegionPtr, pointer
-#ifdef USE_NEW_XVABI
-    , DrawablePtr
-#endif
-);
+    RegionPtr, pointer, DrawablePtr);
 static void nv12Blit(unsigned char *nv12Chroma,
     const unsigned char *uBuffer,
     const unsigned char *vBuffer,
@@ -282,7 +278,8 @@
         pVia->ChipId != PCI_CHIP_VT3327 && 
         pVia->ChipId != PCI_CHIP_VT3336 && 
         pVia->ChipId != PCI_CHIP_VT3364 && 
-        pVia->ChipId != PCI_CHIP_VT3324) {
+        pVia->ChipId != PCI_CHIP_VT3324 &&
+	pVia->ChipId != PCI_CHIP_VT3353) {
         CARD32 bandwidth = (mode->HDisplay >> 4) * (mode->VDisplay >> 5) *
             pScrn->bitsPerPixel * mode->VRefresh;
 
@@ -370,14 +367,14 @@
     
         if (pVia->pVbe) {
             refresh = 100;
-	    if (pBIOSInfo->PanelActive)
+            if (pBIOSInfo->Panel->IsActive)
                 refresh = 70;
             if (pBIOSInfo->TVActive)
                 refresh = 60;
         } else {
-	    if (pBIOSInfo->PanelActive) {
-                width = pBIOSInfo->panelX;
-                height = pBIOSInfo->panelY;
+            if (pBIOSInfo->Panel->IsActive) {
+                width = pBIOSInfo->Panel->NativeMode->Width;
+                height = pBIOSInfo->Panel->NativeMode->Height;
                 if ((width == 1400) && (height == 1050)) {
                     width = 1280;
                     height = 1024;
@@ -476,6 +473,10 @@
 {
     VIAPtr pVia = VIAPTR(pScrn);
     vmmtr viaVidEng = (vmmtr) pVia->VidMapBase;
+    
+    /* 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;
@@ -490,6 +491,10 @@
 {
     VIAPtr pVia = VIAPTR(pScrn);
     vmmtr viaVidEng = (vmmtr) pVia->VidMapBase;
+    
+    /* Restore video registers */
+    /* TODO: Identify which registers should be saved and restored */
+    memcpy((void*)viaVidEng, pVia->VideoRegs, sizeof(video_via_regs));
 
     viaVidEng->video1_ctl = pVia->dwV1;
     viaVidEng->video3_ctl = pVia->dwV3;
@@ -568,6 +573,7 @@
         (pVia->Chipset == VIA_K8M890) ||
         (pVia->Chipset == VIA_P4M900) ||
         (pVia->Chipset == VIA_CX700) ||
+        (pVia->Chipset == VIA_VX800) ||
         (pVia->Chipset == VIA_P4M890));
     if ((pVia->drmVerMajor < 2) ||
         ((pVia->drmVerMajor == 2) && (pVia->drmVerMinor < 9)))
@@ -586,7 +592,7 @@
         (pVia->Chipset == VIA_K8M800) || (pVia->Chipset == VIA_PM800) ||
         (pVia->Chipset == VIA_VM800) || (pVia->Chipset == VIA_K8M890) ||
         (pVia->Chipset == VIA_P4M900) || (pVia->Chipset == VIA_CX700) ||
-        (pVia->Chipset == VIA_P4M890)) {
+        (pVia->Chipset == VIA_P4M890) || (pVia->Chipset == VIA_VX800)) {
         num_new = viaSetupAdaptors(pScreen, &newAdaptors);
         num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
     } else {
@@ -650,8 +656,6 @@
     return TRUE;
 }
 
-#ifdef USE_NEW_XVABI
-
 static void
 viaVideoFillPixmap(ScrnInfoPtr pScrn,
         char *base,
@@ -662,7 +666,7 @@
 {
     int i;
 
-    ErrorF("pitch %lu, depth %d, x %d, y %d, w %d h %d, color 0x%08x\n",
+    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;
@@ -750,7 +754,6 @@
 
     return 0;
 }
-#endif
 
 
 /*
@@ -759,11 +762,8 @@
 
 static int
 viaReputImage(ScrnInfoPtr pScrn,
-        short drw_x, short drw_y, RegionPtr clipBoxes, pointer data
-#ifdef USE_NEW_XVABI
-        , DrawablePtr pDraw
-#endif
-)
+        short drw_x, short drw_y, RegionPtr clipBoxes, pointer data,
+        DrawablePtr pDraw)
 {
 
     DDUPDATEOVERLAY UpdateOverlay_Video;
@@ -774,17 +774,12 @@
     if (!RegionsEqual(&pPriv->clip, clipBoxes)) {
         REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
         if (pPriv->autoPaint) {
-#ifdef USE_NEW_XVABI
             if (pDraw->type == DRAWABLE_WINDOW) {
                 viaPaintColorkey(pScrn, pPriv, clipBoxes, pDraw);
             } else {
                 xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey,
                     clipBoxes);
             }
-#else
-            xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey,
-                clipBoxes);
-#endif
         }
     }
 
@@ -924,8 +919,8 @@
     DBG_DD(ErrorF(" via_video.c : viaStopVideo: exit=%d\n", exit));
 
     REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
+    ViaOverlayHide(pScrn);
     if (exit) {
-        ViaOverlayHide(pScrn);
         ViaSwovSurfaceDestroy(pScrn, pPriv);
         if (pPriv->dmaBounceBuffer)
             xfree(pPriv->dmaBounceBuffer);
@@ -1271,11 +1266,8 @@
         short src_w, short src_h,
         short drw_w, short drw_h,
         int id, unsigned char *buf,
-        short width, short height, Bool sync, RegionPtr clipBoxes, pointer data
-#ifdef USE_NEW_XVABI
-        , DrawablePtr pDraw
-#endif
-)
+        short width, short height, Bool sync, RegionPtr clipBoxes,
+        pointer data, DrawablePtr pDraw)
 {
     VIAPtr pVia = VIAPTR(pScrn);
     viaPortPrivPtr pPriv = (viaPortPrivPtr) data;
@@ -1443,17 +1435,12 @@
             if (!RegionsEqual(&pPriv->clip, clipBoxes)) {
                 REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
                 if (pPriv->autoPaint) {
-#ifdef USE_NEW_XVABI
                     if (pDraw->type == DRAWABLE_WINDOW) {
                         viaPaintColorkey(pScrn, pPriv, clipBoxes, pDraw);
                     } else {
                         xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey,
                             clipBoxes);
                     }
-#else
-                    xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey,
-                        clipBoxes);
-#endif
                 }
             }
             /*
Index: src/via_lvds.c
===================================================================
--- src/via_lvds.c	(.../tags/release_0_2_903)	(revision 0)
+++ src/via_lvds.c	(.../trunk)	(revision 751)
@@ -0,0 +1,122 @@
+/* 
+ * Copyright 2007 The Openchrome Project [openchrome.org]
+ * Copyright 1998-2007 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2007 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Integrated LVDS power management functions.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "via.h"
+#include "via_driver.h"
+#include "via_vgahw.h"
+#include "via_id.h"
+
+
+static void
+ViaLVDSPowerFirstSequence(ScrnInfoPtr pScrn, Bool on)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+    if (on) {
+        /* Use hardware control power sequence. */
+        hwp->writeCrtc(hwp, 0x91, hwp->readCrtc(hwp, 0x91) & 0xFE);
+        /* Turn on back light. */
+        hwp->writeCrtc(hwp, 0x91, hwp->readCrtc(hwp, 0x91) & 0x3F);
+        /* Turn on hardware power sequence. */
+        hwp->writeCrtc(hwp, 0x6A, hwp->readCrtc(hwp, 0x6A) | 0x08);
+    } else {
+        /* Turn off power sequence. */
+        hwp->writeCrtc(hwp, 0x6A, hwp->readCrtc(hwp, 0x6A) & 0xF7);
+        usleep(1);
+        /* Turn off back light. */
+        hwp->writeCrtc(hwp, 0x91, 0xC0);
+    }
+}
+
+static void
+ViaLVDSPowerSecondSequence(ScrnInfoPtr pScrn, Bool on)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+    if (on) {
+        /* Use hardware control power sequence. */
+        hwp->writeCrtc(hwp, 0xD3, hwp->readCrtc(hwp, 0xD3) & 0xFE);
+        /* Turn on back light. */
+        hwp->writeCrtc(hwp, 0xD3, hwp->readCrtc(hwp, 0xD3) & 0x3F);
+        /* Turn on hardware power sequence. */
+        hwp->writeCrtc(hwp, 0xD4, hwp->readCrtc(hwp, 0xD4) | 0x02);
+    } else {
+        /* Turn off power sequence. */
+        hwp->writeCrtc(hwp, 0xD4, hwp->readCrtc(hwp, 0xD4) & 0xFD);
+        usleep(1);
+        /* Turn off back light. */
+        hwp->writeCrtc(hwp, 0xD3, 0xC0);
+    }
+}
+
+static void
+ViaLVDSDFPPower(ScrnInfoPtr pScrn, Bool on)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+    if (on) {
+        /* Turn DFP High/Low pad on. */
+        hwp->writeSeq(hwp, 0x2A, hwp->readSeq(hwp, 0x2A) | 0x0F);
+    } else {
+        /* Turn DFP High/Low pad off. */
+        hwp->writeSeq(hwp, 0x2A, hwp->readSeq(hwp, 0x2A) & 0xF0);
+
+    }
+}
+
+static void
+ViaLVDSPowerChannel(ScrnInfoPtr pScrn, Bool on)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+    CARD8 lvdsMask;
+
+    if (on) {
+        /* LVDS0: 0x7F, LVDS1: 0xBF */
+        lvdsMask = 0x7F & 0xBF;
+        hwp->writeCrtc(hwp, 0xD2, hwp->readCrtc(hwp, 0xD2) & lvdsMask);
+    } else {
+        /* LVDS0: 0x80, LVDS1: 0x40 */
+        lvdsMask = 0x80 | 0x40;
+        hwp->writeCrtc(hwp, 0xD2, hwp->readCrtc(hwp, 0xD2) | lvdsMask);
+    }
+}
+
+void
+ViaLVDSPower(ScrnInfoPtr pScrn, Bool on)
+{
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaLVDSPower\n"));
+    ViaLVDSPowerFirstSequence(pScrn, on);
+    ViaLVDSPowerSecondSequence(pScrn, on);
+    ViaLVDSDFPPower(pScrn, on);
+    ViaLVDSPowerChannel(pScrn, on);
+}
Index: src/via_mode.c
===================================================================
--- src/via_mode.c	(.../tags/release_0_2_903)	(revision 751)
+++ src/via_mode.c	(.../trunk)	(revision 751)
@@ -1,4 +1,5 @@
 /*
+ * Copyright 2005-2007 The Openchrome Project [openchrome.org]
  * Copyright 2004-2005 The Unichrome Project  [unichrome.sf.net]
  * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
  * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
@@ -45,6 +46,54 @@
  */
 #include "via_mode.h"
 
+static void
+ViaPrintMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Name: %s\n", mode->name);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock: %d\n", mode->Clock);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VRefresh: %f\n", mode->VRefresh);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "HSync: %f\n", mode->HSync);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "HDisplay: %d\n", mode->HDisplay);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "HSyncStart: %d\n", mode->HSyncStart);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "HSyncEnd: %d\n", mode->HSyncEnd);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "HTotal: %d\n", mode->HTotal);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "HSkew: %d\n", mode->HSkew);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VDisplay: %d\n", mode->VDisplay);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VSyncStart: %d\n", mode->VSyncStart);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VSyncEnd: %d\n", mode->VSyncEnd);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VTotal: %d\n", mode->VTotal);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VScan: %d\n", mode->VScan);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Flags: %d\n", mode->Flags);
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHDisplay: 0x%x\n",
+               mode->CrtcHDisplay);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHBlankStart: 0x%x\n",
+               mode->CrtcHBlankStart);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSyncStart: 0x%x\n",
+               mode->CrtcHSyncStart);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSyncEnd: 0x%x\n",
+               mode->CrtcHSyncEnd);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHBlankEnd: 0x%x\n",
+               mode->CrtcHBlankEnd);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHTotal: 0x%x\n",
+               mode->CrtcHTotal);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSkew: 0x%x\n",
+               mode->CrtcHSkew);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVDisplay: 0x%x\n",
+               mode->CrtcVDisplay);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVBlankStart: 0x%x\n",
+               mode->CrtcVBlankStart);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVSyncStart: 0x%x\n",
+               mode->CrtcVSyncStart);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVSyncEnd: 0x%x\n",
+               mode->CrtcVSyncEnd);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVBlankEnd: 0x%x\n",
+               mode->CrtcVBlankEnd);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVTotal: 0x%x\n",
+               mode->CrtcVTotal);
+
+}
+
 /*
  *
  * TV specific code.
@@ -243,6 +292,29 @@
     return MODE_OK;
 }
 
+
+static Bool
+ViaDFPDetect(ScrnInfoPtr pScrn)
+{
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDFPDetect\n"));
+
+    VIAPtr pVia = VIAPTR(pScrn);
+    VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+    xf86MonPtr          monPtr = NULL;
+
+    if (pVia->pI2CBus2)
+        monPtr = xf86DoEDID_DDC2(pScrn->scrnIndex, pVia->pI2CBus2);
+    
+    if (monPtr) {
+        xf86PrintEDID(monPtr);
+        xf86SetDDCproperties(pScrn, monPtr);
+        return TRUE;
+    } else {
+        return FALSE;
+    }
+}
+
+
 /*
  *
  */
@@ -256,7 +328,8 @@
 
     pBIOSInfo->CrtPresent = FALSE;
     pBIOSInfo->PanelPresent = FALSE;
-
+    pBIOSInfo->DfpPresent = FALSE;
+    
     /* Panel */
     if (pBIOSInfo->ForcePanel) {
         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling panel from config.\n");
@@ -277,7 +350,7 @@
             pBIOSInfo->CrtPresent = TRUE;
     }
 
-    /* 
+    /*
      * FIXME: xf86I2CProbeAddress(pVia->pI2CBus3, 0x40)
      * disables the panel on P4M900
      * See ViaTVDetect.
@@ -297,6 +370,19 @@
             pBIOSInfo->TVOutput = 0;
         }
     }
+    
+    if ((pVia->Chipset == VIA_CX700) || (pVia->Chipset == VIA_VX800)) {
+        
+        if (ViaDFPDetect(pScrn)) {
+            pBIOSInfo->DfpPresent = TRUE;
+            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                       "DFP is connected.\n");
+        } else {
+            pBIOSInfo->DfpPresent = FALSE;
+            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                       "DFP is disconnected.\n");
+        }
+    }
 }
 
 #ifdef HAVE_DEBUG
@@ -347,24 +433,30 @@
                      " Initialised register: 0x%02x\n",
                      VIAGetActiveDisplay(pScrn)));
 
-    pBIOSInfo->PanelActive = FALSE;
+    pBIOSInfo->Panel->IsActive = FALSE;
     pBIOSInfo->CrtActive = FALSE;
     pBIOSInfo->TVActive = FALSE;
-
+    pBIOSInfo->DfpActive = FALSE;
+    
     if (!pVia->ActiveDevice) {
         /* always enable the panel when present */
         if (pBIOSInfo->PanelPresent)
-            pBIOSInfo->PanelActive = TRUE;
+            pBIOSInfo->Panel->IsActive = TRUE;
         else if (pBIOSInfo->TVOutput != TVOUTPUT_NONE)  /* cable is attached! */
             pBIOSInfo->TVActive = TRUE;
 
         /* CRT can be used with everything when present */
         if (pBIOSInfo->CrtPresent)
             pBIOSInfo->CrtActive = TRUE;
+
+        /* DFP */
+        if (pBIOSInfo->DfpPresent)
+            pBIOSInfo->DfpActive = TRUE;
+        
     } else {
         if (pVia->ActiveDevice & VIA_DEVICE_LCD) {
             if (pBIOSInfo->PanelPresent)
-                pBIOSInfo->PanelActive = TRUE;
+                pBIOSInfo->Panel->IsActive = TRUE;
             else
                 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unable to activate"
                            " panel: no panel is present.\n");
@@ -377,7 +469,7 @@
             else if (pBIOSInfo->TVOutput == TVOUTPUT_NONE)
                 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unable to activate"
                            " TV encoder: no cable attached.\n");
-            else if (pBIOSInfo->PanelActive)
+            else if (pBIOSInfo->Panel->IsActive)
                 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unable to activate"
                            " TV encoder and panel simultaneously. Not using"
                            " TV encoder.\n");
@@ -385,221 +477,112 @@
                 pBIOSInfo->TVActive = TRUE;
         }
 
+        if (pVia->ActiveDevice & VIA_DEVICE_DFP) {
+            pBIOSInfo->DfpPresent = TRUE;
+            pBIOSInfo->DfpActive = TRUE;
+        }
+
         if ((pVia->ActiveDevice & VIA_DEVICE_CRT)
-            || (!pBIOSInfo->PanelActive && !pBIOSInfo->TVActive)) {
+            || (!pBIOSInfo->Panel->IsActive && !pBIOSInfo->TVActive
+                && !pBIOSInfo->DfpActive)) {
             pBIOSInfo->CrtPresent = TRUE;
             pBIOSInfo->CrtActive = TRUE;
         }
     }
+    if (!pVia->UseLegacyModeSwitch) {
+        if (pBIOSInfo->CrtActive)
+            pBIOSInfo->FirstCRTC->IsActive = TRUE ;
+        if (pBIOSInfo->DfpActive)
+            pBIOSInfo->FirstCRTC->IsActive = TRUE ;
+        if (pBIOSInfo->Panel->IsActive) {
+            pVia->pBIOSInfo->SecondCRTC->IsActive = TRUE ;
+            if (pVia->Chipset == VIA_P4M900 || pVia->Chipset == VIA_CX700 || pVia->Chipset == VIA_VX800 )
+                pVia->pBIOSInfo->Lvds->IsActive = TRUE ;
+        }
+    }
 
 #ifdef HAVE_DEBUG
     if (pBIOSInfo->CrtActive)
         DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
                          "ViaOutputsSelect: CRT.\n"));
-    if (pBIOSInfo->PanelActive)
+    if (pBIOSInfo->Panel->IsActive)
         DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
                          "ViaOutputsSelect: Panel.\n"));
     if (pBIOSInfo->TVActive)
         DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
                          "ViaOutputsSelect: TV.\n"));
+    if (pBIOSInfo->DfpActive)
+        DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                         "ViaOutputsSelect: DFP.\n"));
 #endif
     return TRUE; /* !Secondary always has at least CRT */
 }
 
 /*
- * Try to interprete EDID ourselves.
- */
-static Bool
-ViaGetPanelSizeFromEDID(ScrnInfoPtr pScrn, xf86MonPtr pMon, int *size)
-{
-    int i, max = 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++)
-        if ((pMon->timings2[i].hsize > 256) && (pMon->timings2[i].hsize > max))
-            max = pMon->timings2[i].hsize;
-
-    if (max != 0) {
-        *size = max;
-        return TRUE;
-    }
-
-    /* checking detailed monitor section */
-
-    /* !!! skip Ranges and standard timings */
-
-    /* check detailed timings */
-    for (i = 0; i < DET_TIMINGS; i++)
-        if (pMon->det_mon[i].type == DT) {
-            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 (max != 0) {
-        *size = max;
-        return TRUE;
-    }
-
-    return FALSE;
-}
-
-/*
  *
  */
-static Bool
-VIAGetPanelSizeFromDDCv1(ScrnInfoPtr pScrn, int *size)
-{
-    VIAPtr pVia = VIAPTR(pScrn);
-    xf86MonPtr pMon;
-
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAGetPanelSizeFromDDCv1\n"));
-
-    if (!xf86I2CProbeAddress(pVia->pI2CBus2, 0xA0))
-        return FALSE;
-
-    pMon = xf86DoEDID_DDC2(pScrn->scrnIndex, pVia->pI2CBus2);
-    if (!pMon)
-        return FALSE;
-
-    pVia->DDC2 = pMon;
-
-    if (!pVia->DDC1) {
-        xf86PrintEDID(pMon);
-        xf86SetDDCproperties(pScrn, pMon);
-    }
-
-    if (!ViaGetPanelSizeFromEDID(pScrn, pMon, size)) {
-        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "Unable to read PanelSize from EDID information\n");
-        return FALSE;
-    }
-
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                     "VIAGetPanelSizeFromDDCv1: %d\n", *size));
-    return TRUE;
-}
-
-/*
- *
- */
-static Bool
-VIAGetPanelSizeFromDDCv2(ScrnInfoPtr pScrn, int *size)
-{
-    VIAPtr pVia = VIAPTR(pScrn);
-    CARD8 W_Buffer[1];
-    CARD8 R_Buffer[2];
-    I2CDevPtr dev;
-
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAGetPanelSizeFromDDCv2\n"));
-
-    if (!xf86I2CProbeAddress(pVia->pI2CBus2, 0xA2))
-        return FALSE;
-
-    dev = xf86CreateI2CDevRec();
-    if (!dev)
-        return FALSE;
-
-    dev->DevName = "EDID2";
-    dev->SlaveAddr = 0xA2;
-    dev->ByteTimeout = 2200;  /* VESA DDC spec 3 p. 43 (+10 %) */
-    dev->StartTimeout = 550;
-    dev->BitTimeout = 40;
-    dev->ByteTimeout = 40;
-    dev->AcknTimeout = 40;
-    dev->pI2CBus = pVia->pI2CBus2;
-
-    if (!xf86I2CDevInit(dev)) {
-        xf86DestroyI2CDevRec(dev, TRUE);
-        return FALSE;
-    }
-
-    xf86I2CReadByte(dev, 0x00, R_Buffer);
-    if (R_Buffer[0] != 0x20) {
-        xf86DestroyI2CDevRec(dev, TRUE);
-        return FALSE;
-    }
-
-    /* Found EDID2 Table */
-
-    W_Buffer[0] = 0x76;
-    xf86I2CWriteRead(dev, W_Buffer, 1, R_Buffer, 2);
-    xf86DestroyI2CDevRec(dev, TRUE);
-
-    *size = R_Buffer[0] | (R_Buffer[1] << 8);
-
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                     "VIAGetPanelSizeFromDDCv2: %d\n", *size));
-    return TRUE;
-}
-
-/*
- *
- */
 static void
 VIAGetPanelSize(ScrnInfoPtr pScrn)
 {
     vgaHWPtr hwp = VGAHWPTR(pScrn);
     VIAPtr pVia = VIAPTR(pScrn);
     VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
-    char *PanelSizeString[7] = { "640x480", "800x600", "1024x768", "1280x768"
+    char *PanelSizeString[7] = { "640x480", "800x480", "800x600", "1024x768", "1280x768"
                                  "1280x1024", "1400x1050", "1600x1200" };
-    int size = 0;
+    int width = 0;
+    int height = 0;
     Bool ret;
 
     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAGetPanelSize\n"));
 
-    ret = VIAGetPanelSizeFromDDCv1(pScrn, &size);
+    ret = ViaPanelGetSizeFromDDCv1(pScrn, &width, &height);
     if (!ret)
-        ret = VIAGetPanelSizeFromDDCv2(pScrn, &size);
+        ret = ViaPanelGetSizeFromDDCv2(pScrn, &width);
 
     if (ret) {
-        switch (size) {
+        switch (width) {
             case 640:
-                pBIOSInfo->PanelSize = VIA_PANEL6X4;
+                pBIOSInfo->Panel->NativeModeIndex = VIA_PANEL6X4;
                 break;
             case 800:
-                pBIOSInfo->PanelSize = VIA_PANEL8X6;
+		if (height == 480)
+               	    pBIOSInfo->Panel->NativeModeIndex = VIA_PANEL8X4;
+		else
+               	    pBIOSInfo->Panel->NativeModeIndex = VIA_PANEL8X6;
                 break;
             case 1024:
-                pBIOSInfo->PanelSize = VIA_PANEL10X7;
+                pBIOSInfo->Panel->NativeModeIndex = VIA_PANEL10X7;
                 break;
             case 1280:
-                pBIOSInfo->PanelSize = VIA_PANEL12X10;
+                pBIOSInfo->Panel->NativeModeIndex = VIA_PANEL12X10;
                 break;
             case 1400:
-                pBIOSInfo->PanelSize = VIA_PANEL14X10;
+                pBIOSInfo->Panel->NativeModeIndex = VIA_PANEL14X10;
                 break;
             case 1600:
-                pBIOSInfo->PanelSize = VIA_PANEL16X12;
+                pBIOSInfo->Panel->NativeModeIndex = VIA_PANEL16X12;
                 break;
             default:
-                pBIOSInfo->PanelSize = VIA_PANEL_INVALID;
+                pBIOSInfo->Panel->NativeModeIndex = VIA_PANEL_INVALID;
                 break;
         }
     } else {
-        pBIOSInfo->PanelSize = hwp->readCrtc(hwp, 0x3F) >> 4;
-        if (pBIOSInfo->PanelSize == 0) {
+        pBIOSInfo->Panel->NativeModeIndex = hwp->readCrtc(hwp, 0x3F) >> 4;
+        if (pBIOSInfo->Panel->NativeModeIndex == 0) {
             /* VIA_PANEL6X4 == 0, but that value equals unset */
             xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unable to "
                        "retrieve PanelSize: using default (1024x768)\n");
-            pBIOSInfo->PanelSize = VIA_PANEL10X7;
+            pBIOSInfo->Panel->NativeModeIndex = VIA_PANEL10X7;
             return;
         }
     }
 
-    if (pBIOSInfo->PanelSize < 7)
+    if (pBIOSInfo->Panel->NativeModeIndex < 7)
         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using panel at %s.\n",
-                   PanelSizeString[pBIOSInfo->PanelSize]);
+                   PanelSizeString[pBIOSInfo->Panel->NativeModeIndex]);
     else
         xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unknown panel size "
-                   "detected: %d.\n", pBIOSInfo->PanelSize);
+                   "detected: %d.\n", pBIOSInfo->Panel->NativeModeIndex);
 }
 
 /*
@@ -656,7 +639,7 @@
 
 /*
  *
- * ViaResolutionTable[i].PanelIndex is pBIOSInfo->PanelSize 
+ * ViaResolutionTable[i].PanelIndex is pBIOSInfo->PanelSize
  * pBIOSInfo->PanelIndex is the index to lcdTable.
  *
  */
@@ -670,9 +653,9 @@
 
     pBIOSInfo->PanelIndex = VIA_BIOS_NUM_PANEL;
 
-    if (pBIOSInfo->PanelSize == VIA_PANEL_INVALID) {
+    if (pBIOSInfo->Panel->NativeModeIndex == VIA_PANEL_INVALID) {
         VIAGetPanelSize(pScrn);
-        if (pBIOSInfo->PanelSize == VIA_PANEL_INVALID) {
+        if (pBIOSInfo->Panel->NativeModeIndex == VIA_PANEL_INVALID) {
             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                        "ViaPanelGetIndex: PanelSize not set.\n");
             return FALSE;
@@ -692,12 +675,14 @@
         return FALSE;
     }
 
-    for (i = 0; ViaResolutionTable[i].Index != VIA_RES_INVALID; i++)
-        if (ViaResolutionTable[i].PanelIndex == pBIOSInfo->PanelSize) {
+    for (i = 0; ViaResolutionTable[i].Index != VIA_RES_INVALID; i++) {
+        if (ViaResolutionTable[i].PanelIndex
+            == pBIOSInfo->Panel->NativeModeIndex) {
             pBIOSInfo->panelX = ViaResolutionTable[i].X;
             pBIOSInfo->panelY = ViaResolutionTable[i].Y;
             break;
         }
+    }
 
     if (ViaResolutionTable[i].Index == VIA_RES_INVALID) {
         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaPanelGetIndex: Unable"
@@ -712,8 +697,11 @@
         return FALSE;
     }
 
-    for (i = 0; i < VIA_BIOS_NUM_PANEL; i++)
-        if (lcdTable[i].fpSize == pBIOSInfo->PanelSize) {
+    for (i = 0; i < VIA_BIOS_NUM_PANEL; i++) {
+        DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaPanelGetIndex:"
+                         "Match Debug: %d == %d)\n", pBIOSInfo->Panel->NativeModeIndex,
+                         lcdTable[i].fpSize));
+        if (lcdTable[i].fpSize == pBIOSInfo->Panel->NativeModeIndex) {
             int modeNum, tmp;
 
             modeNum = ViaGetVesaMode(pScrn, mode);
@@ -736,6 +724,7 @@
                        " to match given mode with this PanelSize.\n");
             return FALSE;
         }
+    }
 
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaPanelGetIndex: Unable"
                " to match PanelSize with an lcdTable entry.\n");
@@ -743,6 +732,53 @@
 }
 
 /*
+ * adapted from nv and savage 
+ */
+static void
+ViaModesMonitorFixup(ScrnInfoPtr pScrn, MonPtr monitorp, DisplayModePtr mode)
+{
+	/* These are all modes that the driver sets up
+	 * so we can comfortably update the monitor
+	 * configuration to work with them.
+	 */
+
+	if (monitorp->hsync[0].lo == 0)
+		monitorp->hsync[0].lo = 31.50;
+	if (monitorp->hsync[0].hi == 0)
+		monitorp->hsync[0].hi = 37.90;
+	if (monitorp->vrefresh[0].lo == 0)
+		monitorp->vrefresh[0].lo = 50.00;
+	if (monitorp->vrefresh[0].hi == 0)
+		monitorp->vrefresh[0].hi = 70.00;
+
+	if (!mode->HSync)
+		mode->HSync = ((float) mode->Clock ) / ((float) mode->HTotal);
+	if (!mode->VRefresh)
+		mode->VRefresh = (1000.0 * ((float) mode->Clock)) /
+		   ((float) (mode->HTotal * mode->VTotal));
+
+	if (mode->HSync < monitorp->hsync[0].lo) {
+		monitorp->hsync[0].lo = mode->HSync;
+		DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModesMonitorFixup - Adjusted HSync.lo to %f\n", monitorp->hsync[0].lo));
+	}
+	if (mode->HSync > monitorp->hsync[0].hi) {
+		monitorp->hsync[0].hi = mode->HSync;
+		DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModesMonitorFixup - Adjusted HSync.hi to %f\n", monitorp->hsync[0].hi));
+	}
+	if (mode->VRefresh < monitorp->vrefresh[0].lo) {
+		monitorp->vrefresh[0].lo = mode->VRefresh;
+		DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModesMonitorFixup - Adjusted VRefresh.lo to %f\n", monitorp->vrefresh[0].lo));
+	}
+	if (mode->VRefresh > monitorp->vrefresh[0].hi) {
+		monitorp->vrefresh[0].hi = mode->VRefresh;
+		DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModesMonitorFixup - Adjusted VRefresh.hi to %f\n", monitorp->vrefresh[0].hi));
+	}
+
+	monitorp->nHsync = 1;
+	monitorp->nVrefresh = 1;
+}
+
+/*
  * Stolen from xf86Config.c's addDefaultModes
  */
 static void
@@ -764,6 +800,7 @@
             mode->prev = NULL;
         }
         last = mode;
+        ViaModesMonitorFixup(pScrn, monitorp, mode);
     }
     monitorp->Last = last;
 }
@@ -778,7 +815,7 @@
 
     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModesAttach\n"));
 
-    if (pBIOSInfo->PanelActive)
+    if (pBIOSInfo->Panel->IsActive)
         ViaModesAttachHelper(pScrn, monitorp, ViaPanelModes);
     if (pBIOSInfo->TVActive && pBIOSInfo->TVModes)
         ViaModesAttachHelper(pScrn, monitorp, pBIOSInfo->TVModes);
@@ -815,155 +852,12 @@
     }
 }
 
-/*
- * Checks for limitations imposed by the available VGA timing registers.
- *
- */
-static ModeStatus
-ViaModePrimaryVGAValid(ScrnInfoPtr pScrn, DisplayModePtr mode)
-{
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModePrimaryVGAValid\n"));
+static CARD32
+ViaModeDotClockTranslate(ScrnInfoPtr pScrn, DisplayModePtr mode);
 
-    if (mode->CrtcHTotal > 4100) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHTotal out of range.\n");
-        return MODE_BAD_HVALUE;
-    }
-
-    if (mode->CrtcHDisplay > 2048) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHDisplay out of range.\n");
-        return MODE_BAD_HVALUE;
-    }
-
-    if (mode->CrtcHBlankStart > 2048) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHBlankStart out of range.\n");
-        return MODE_BAD_HVALUE;
-    }
-
-    if ((mode->CrtcHBlankEnd - mode->CrtcHBlankStart) > 1025) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHBlankEnd out of range.\n");
-        return MODE_HBLANK_WIDE;
-    }
-
-    if (mode->CrtcHSyncStart > 4095) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSyncStart out of range.\n");
-        return MODE_BAD_HVALUE;
-    }
-
-    if ((mode->CrtcHSyncEnd - mode->CrtcHSyncStart) > 256) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSyncEnd out of range.\n");
-        return MODE_HSYNC_WIDE;
-    }
-
-    if (mode->CrtcVTotal > 2049) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVTotal out of range.\n");
-        return MODE_BAD_VVALUE;
-    }
-
-    if (mode->CrtcVDisplay > 2048) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVDisplay out of range.\n");
-        return MODE_BAD_VVALUE;
-    }
-
-    if (mode->CrtcVSyncStart > 2047) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVSyncStart out of range.\n");
-        return MODE_BAD_VVALUE;
-    }
-
-    if ((mode->CrtcVSyncEnd - mode->CrtcVSyncStart) > 16) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVSyncEnd out of range.\n");
-        return MODE_VSYNC_WIDE;
-    }
-
-    if (mode->CrtcVBlankStart > 2048) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVBlankStart out of range.\n");
-        return MODE_BAD_VVALUE;
-    }
-
-    if ((mode->CrtcVBlankEnd - mode->CrtcVBlankStart) > 257) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVBlankEnd out of range.\n");
-        return MODE_VBLANK_WIDE;
-    }
-
-    return MODE_OK;
-}
-
 /*
  *
  */
-static ModeStatus
-ViaModeSecondaryVGAValid(ScrnInfoPtr pScrn, DisplayModePtr mode)
-{
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModeSecondaryVGAValid\n"));
-
-    if (mode->CrtcHTotal > 4096) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHTotal out of range.\n");
-        return MODE_BAD_HVALUE;
-    }
-
-    if (mode->CrtcHDisplay > 2048) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHDisplay out of range.\n");
-        return MODE_BAD_HVALUE;
-    }
-
-    if (mode->CrtcHBlankStart > 2048) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHBlankStart out of range.\n");
-        return MODE_BAD_HVALUE;
-    }
-
-    if (mode->CrtcHBlankEnd > 4096) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHBlankEnd out of range.\n");
-        return MODE_HBLANK_WIDE;
-    }
-
-    if (mode->CrtcHSyncStart > 2047) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSyncStart out of range.\n");
-        return MODE_BAD_HVALUE;
-    }
-
-    if ((mode->CrtcHSyncEnd - mode->CrtcHSyncStart) > 512) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSyncEnd out of range.\n");
-        return MODE_HSYNC_WIDE;
-    }
-
-    if (mode->CrtcVTotal > 2048) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVTotal out of range.\n");
-        return MODE_BAD_VVALUE;
-    }
-
-    if (mode->CrtcVDisplay > 2048) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVDisplay out of range.\n");
-        return MODE_BAD_VVALUE;
-    }
-
-    if (mode->CrtcVBlankStart > 2048) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVBlankStart out of range.\n");
-        return MODE_BAD_VVALUE;
-    }
-
-    if (mode->CrtcVBlankEnd > 2048) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVBlankEnd out of range.\n");
-        return MODE_VBLANK_WIDE;
-    }
-
-    if (mode->CrtcVSyncStart > 2047) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVSyncStart out of range.\n");
-        return MODE_BAD_VVALUE;
-    }
-
-    if ((mode->CrtcVSyncEnd - mode->CrtcVSyncStart) > 32) {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVSyncEnd out of range.\n");
-        return MODE_VSYNC_WIDE;
-    }
-
-    return MODE_OK;
-}
-
-
-static CARD32 ViaModeDotClockTranslate(ScrnInfoPtr pScrn, DisplayModePtr mode);
-
-/*
- *
- */
 ModeStatus
 ViaValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
 {
@@ -982,27 +876,57 @@
     if (mode->Flags & V_INTERLACE)
         return MODE_NO_INTERLACE;
 
-    if (pVia->IsSecondary)
-        ret = ViaModeSecondaryVGAValid(pScrn, mode);
-    else
-        ret = ViaModePrimaryVGAValid(pScrn, mode);
+    if (pVia->UseLegacyModeSwitch) {
 
-    if (ret != MODE_OK)
-        return ret;
+        if (pVia->IsSecondary)
+            ret = ViaSecondCRTCModeValid(pScrn, mode);
+        else
+            ret = ViaFirstCRTCModeValid(pScrn, mode);
 
-    if (pBIOSInfo->TVActive) {
-        ret = ViaTVModeValid(pScrn, mode);
-        if (ret != MODE_OK) {
-            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                       "Mode \"%s\" is not supported by TV encoder.\n",
-                       mode->name);
+        if (ret != MODE_OK)
             return ret;
+
+        if (pBIOSInfo->TVActive) {
+            ret = ViaTVModeValid(pScrn, mode);
+            if (ret != MODE_OK) {
+                xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                           "Mode \"%s\" is not supported by TV encoder.\n",
+                           mode->name);
+                return ret;
+            }
+        } else {
+            if (pBIOSInfo->Panel->IsActive && !ViaPanelGetIndex(pScrn, mode))
+                return MODE_BAD;
+            else if (!ViaModeDotClockTranslate(pScrn, mode))
+                return MODE_NOCLOCK;
         }
-    } else if (pBIOSInfo->PanelActive && !ViaPanelGetIndex(pScrn, mode))
-        return MODE_BAD;
-    else if (!ViaModeDotClockTranslate(pScrn, mode))
-        return MODE_NOCLOCK;
 
+    } else {
+
+        if (pBIOSInfo->FirstCRTC->IsActive) {
+            ret = ViaFirstCRTCModeValid(pScrn, mode);
+            if (ret != MODE_OK)
+                return ret;
+        }
+
+        if (pBIOSInfo->SecondCRTC->IsActive) {
+            ret = ViaSecondCRTCModeValid(pScrn, mode);
+            if (ret != MODE_OK)
+                return ret;
+        }
+
+        if (pBIOSInfo->Panel->IsActive) {
+            ViaPanelModePtr nativeMode = pBIOSInfo->Panel->NativeMode;
+
+            if (nativeMode->Width < mode->HDisplay
+                || nativeMode->Height < mode->VDisplay)
+                return MODE_PANEL;
+        }
+
+        if (!ViaModeDotClockTranslate(pScrn, mode))
+            return MODE_NOCLOCK;
+    }
+
     temp = mode->CrtcHDisplay * mode->CrtcVDisplay * mode->VRefresh
             * (pScrn->bitsPerPixel >> 3);
     if (pBIOSInfo->Bandwidth < temp) {
@@ -1037,7 +961,7 @@
     hwp->writeMiscOut(hwp, data | 0x0C);
 }
 
-/* 
+/*
  *
  */
 static void
@@ -1062,7 +986,7 @@
     ViaSeqMask(hwp, 0x40, 0x00, 0x02);
 }
 
-/* 
+/*
  *
  */
 static void
@@ -1104,7 +1028,7 @@
 
     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIASetLCDMode\n"));
 
-    if (pBIOSInfo->PanelSize == VIA_PANEL12X10)
+    if (pBIOSInfo->Panel->NativeModeIndex == VIA_PANEL12X10)
         hwp->writeCrtc(hwp, 0x89, 0x07);
 
     /* LCD Expand Mode Y Scale Flag */
@@ -1165,7 +1089,7 @@
             case VIA_RES_1280X768:
             case VIA_RES_1280X960:
             case VIA_RES_1280X1024:
-                if (pBIOSInfo->PanelSize == VIA_PANEL12X10)
+                if (pBIOSInfo->Panel->NativeModeIndex == VIA_PANEL12X10)
                     resIdx = VIA_RES_INVALID;
                 else
                     resIdx = 4;
@@ -1317,261 +1241,6 @@
     }
 }
 
-/*
- *
- */
-static void
-ViaModePrimaryVGA(ScrnInfoPtr pScrn, DisplayModePtr mode)
-{
-    vgaHWPtr hwp = VGAHWPTR(pScrn);
-    CARD16 temp;
-
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModePrimaryVGA\n"));
-
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModePrimaryVGA: "
-                     "Setting up %s\n", mode->name));
-
-    ViaCrtcMask(hwp, 0x11, 0x00, 0x80); /* modify starting address */
-    ViaCrtcMask(hwp, 0x03, 0x80, 0x80); /* enable vertical retrace access */
-    hwp->writeSeq(hwp, 0x10, 0x01);     /* unlock extended registers */
-    ViaCrtcMask(hwp, 0x47, 0x00, 0x01); /* unlock CRT registers */
-
-    /* Set Misc Register */
-    temp = 0x23;
-    if (mode->Flags & V_NHSYNC)
-        temp |= 0x40;
-    if (mode->Flags & V_NVSYNC)
-        temp |= 0x80;
-    temp |= 0x0C;  /* undefined/external clock */
-    hwp->writeMiscOut(hwp, temp);
-
-    /* Sequence registers */
-    hwp->writeSeq(hwp, 0x00, 0x00);
-
-    /* if (mode->Flags & V_CLKDIV2)
-     * hwp->writeSeq(hwp, 0x01, 0x09);
-     * else */
-    hwp->writeSeq(hwp, 0x01, 0x01);
-
-    hwp->writeSeq(hwp, 0x02, 0x0F);
-    hwp->writeSeq(hwp, 0x03, 0x00);
-    hwp->writeSeq(hwp, 0x04, 0x0E);
-
-    ViaSeqMask(hwp, 0x15, 0x02, 0x02);
-
-    /* bpp */
-    switch (pScrn->bitsPerPixel) {
-        case 8:
-            ViaSeqMask(hwp, 0x15, 0x20, 0xFC);
-            break;
-        case 16:
-            ViaSeqMask(hwp, 0x15, 0xB4, 0xFC);
-            break;
-        case 24:
-        case 32:
-            ViaSeqMask(hwp, 0x15, 0xAC, 0xFC);
-            break;
-        default:
-            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unhandled bitdepth: %d\n",
-                       pScrn->bitsPerPixel);
-            break;
-    }
-
-    ViaSeqMask(hwp, 0x16, 0x08, 0xBF);
-    ViaSeqMask(hwp, 0x17, 0x1F, 0xFF);
-    ViaSeqMask(hwp, 0x18, 0x4E, 0xFF);
-    ViaSeqMask(hwp, 0x1A, 0x08, 0xFD);
-
-    /* graphics registers */
-    hwp->writeGr(hwp, 0x00, 0x00);
-    hwp->writeGr(hwp, 0x01, 0x00);
-    hwp->writeGr(hwp, 0x02, 0x00);
-    hwp->writeGr(hwp, 0x03, 0x00);
-    hwp->writeGr(hwp, 0x04, 0x00);
-    hwp->writeGr(hwp, 0x05, 0x40);
-    hwp->writeGr(hwp, 0x06, 0x05);
-    hwp->writeGr(hwp, 0x07, 0x0F);
-    hwp->writeGr(hwp, 0x08, 0xFF);
-
-    ViaGrMask(hwp, 0x20, 0, 0xFF);
-    ViaGrMask(hwp, 0x21, 0, 0xFF);
-    ViaGrMask(hwp, 0x22, 0, 0xFF);
-
-    /* attribute registers */
-    hwp->writeAttr(hwp, 0x00, 0x00);
-    hwp->writeAttr(hwp, 0x01, 0x01);
-    hwp->writeAttr(hwp, 0x02, 0x02);
-    hwp->writeAttr(hwp, 0x03, 0x03);
-    hwp->writeAttr(hwp, 0x04, 0x04);
-    hwp->writeAttr(hwp, 0x05, 0x05);
-    hwp->writeAttr(hwp, 0x06, 0x06);
-    hwp->writeAttr(hwp, 0x07, 0x07);
-    hwp->writeAttr(hwp, 0x08, 0x08);
-    hwp->writeAttr(hwp, 0x09, 0x09);
-    hwp->writeAttr(hwp, 0x0A, 0x0A);
-    hwp->writeAttr(hwp, 0x0B, 0x0B);
-    hwp->writeAttr(hwp, 0x0C, 0x0C);
-    hwp->writeAttr(hwp, 0x0D, 0x0D);
-    hwp->writeAttr(hwp, 0x0E, 0x0E);
-    hwp->writeAttr(hwp, 0x0F, 0x0F);
-    hwp->writeAttr(hwp, 0x10, 0x41);
-    hwp->writeAttr(hwp, 0x11, 0xFF);
-    hwp->writeAttr(hwp, 0x12, 0x0F);
-    hwp->writeAttr(hwp, 0x13, 0x00);
-    hwp->writeAttr(hwp, 0x14, 0x00);
-
-    /* Crtc registers */
-    /* horizontal total : 4100 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHTotal: 0x%03X\n",
-                     mode->CrtcHTotal));
-    temp = (mode->CrtcHTotal >> 3) - 5;
-    hwp->writeCrtc(hwp, 0x00, temp & 0xFF);
-    ViaCrtcMask(hwp, 0x36, temp >> 5, 0x08);
-
-    /* horizontal address : 2048 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHDisplay: 0x%03X\n",
-                     mode->CrtcHDisplay));
-    temp = (mode->CrtcHDisplay >> 3) - 1;
-    hwp->writeCrtc(hwp, 0x01, temp & 0xFF);
-
-    /* horizontal blanking start : 2048 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHBlankStart: 0x%03X\n",
-                     mode->CrtcHBlankStart));
-    if (mode->CrtcHBlankStart != mode->CrtcHDisplay)  /* FIXME */
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Caught X working around "
-                   "an old VGA limitation (HBlankStart).\n");
-    temp = (mode->CrtcHDisplay >> 3) - 1;
-    hwp->writeCrtc(hwp, 0x02, temp & 0xFF);
-    /* If HblankStart has more bits anywhere, add them here */
-
-    /* horizontal blanking end : start + 1025 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHBlankEnd: 0x%03X\n",
-                     mode->CrtcHBlankEnd));
-    if (mode->CrtcHBlankEnd != mode->CrtcHTotal)  /* FIXME */
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Caught X working around "
-                   "an old VGA limitation (HBlankEnd).\n");
-    temp = (mode->CrtcHTotal >> 3) - 1;
-    ViaCrtcMask(hwp, 0x03, temp, 0x1F);
-    ViaCrtcMask(hwp, 0x05, temp << 2, 0x80);
-    ViaCrtcMask(hwp, 0x33, temp >> 1, 0x20);
-
-    /* CrtcHSkew ??? */
-
-    /* horizontal sync start : 4095 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSyncStart: 0x%03X\n",
-                     mode->CrtcHSyncStart));
-    temp = mode->CrtcHSyncStart >> 3;
-    hwp->writeCrtc(hwp, 0x04, temp & 0xFF);
-    ViaCrtcMask(hwp, 0x33, temp >> 4, 0x10);
-
-    /* horizontal sync end : start + 256 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSyncEnd: 0x%03X\n",
-                     mode->CrtcHSyncEnd));
-    temp = mode->CrtcHSyncEnd >> 3;
-    ViaCrtcMask(hwp, 0x05, temp, 0x1F);
-
-    /* vertical total : 2049 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVTotal: 0x%03X\n",
-                     mode->CrtcVTotal));
-    temp = mode->CrtcVTotal - 2;
-    hwp->writeCrtc(hwp, 0x06, temp & 0xFF);
-    ViaCrtcMask(hwp, 0x07, temp >> 8, 0x01);
-    ViaCrtcMask(hwp, 0x07, temp >> 4, 0x20);
-    ViaCrtcMask(hwp, 0x35, temp >> 10, 0x01);
-
-    /* vertical address : 2048 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVDisplay: 0x%03X\n",
-                     mode->CrtcVDisplay));
-    temp = mode->CrtcVDisplay - 1;
-    hwp->writeCrtc(hwp, 0x12, temp & 0xFF);
-    ViaCrtcMask(hwp, 0x07, temp >> 7, 0x02);
-    ViaCrtcMask(hwp, 0x07, temp >> 3, 0x40);
-    ViaCrtcMask(hwp, 0x35, temp >> 8, 0x04);
-
-    /* Primary starting address -> 0x00, adjustframe does the rest */
-    hwp->writeCrtc(hwp, 0x0C, 0x00);
-    hwp->writeCrtc(hwp, 0x0D, 0x00);
-    hwp->writeCrtc(hwp, 0x34, 0x00);
-    ViaCrtcMask(hwp, 0x48, 0x00, 0x03); /* is this even possible on CLE266A ? */
-
-    /* vertical sync start : 2047 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVSyncStart: 0x%03X\n",
-                     mode->CrtcVSyncStart));
-    temp = mode->CrtcVSyncStart;
-    hwp->writeCrtc(hwp, 0x10, temp & 0xFF);
-    ViaCrtcMask(hwp, 0x07, temp >> 6, 0x04);
-    ViaCrtcMask(hwp, 0x07, temp >> 2, 0x80);
-    ViaCrtcMask(hwp, 0x35, temp >> 9, 0x02);
-
-    /* vertical sync end : start + 16 -- other bits someplace? */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVSyncEnd: 0x%03X\n",
-                     mode->CrtcVSyncEnd));
-    ViaCrtcMask(hwp, 0x11, mode->CrtcVSyncEnd, 0x0F);
-
-    /* line compare: We are not doing splitscreen so 0x3FFF */
-    hwp->writeCrtc(hwp, 0x18, 0xFF);
-    ViaCrtcMask(hwp, 0x07, 0x10, 0x10);
-    ViaCrtcMask(hwp, 0x09, 0x40, 0x40);
-    ViaCrtcMask(hwp, 0x33, 0x07, 0x06);
-    ViaCrtcMask(hwp, 0x35, 0x10, 0x10);
-
-    /* zero Maximum scan line */
-    ViaCrtcMask(hwp, 0x09, 0x00, 0x1F);
-    hwp->writeCrtc(hwp, 0x14, 0x00);
-
-    /* vertical blanking start : 2048 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVBlankStart: 0x%03X\n",
-                     mode->CrtcVBlankStart));
-    if (mode->CrtcVBlankStart != mode->CrtcVDisplay)  /* FIXME */
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Caught X working around "
-                   "an old VGA limitation (VBlankStart).\n");
-    temp = mode->CrtcVDisplay - 1;
-    hwp->writeCrtc(hwp, 0x15, temp & 0xFF);
-    ViaCrtcMask(hwp, 0x07, temp >> 5, 0x08);
-    ViaCrtcMask(hwp, 0x09, temp >> 4, 0x20);
-    ViaCrtcMask(hwp, 0x35, temp >> 7, 0x08);
-
-    /* vertical blanking end : start + 257 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVBlankEnd: 0x%03X\n",
-                     mode->CrtcVBlankEnd));
-    if (mode->CrtcVBlankEnd != mode->CrtcVTotal)  /* FIXME */
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Caught X working around "
-                   "an old VGA limitation (VBlankEnd).\n");
-    temp = mode->CrtcVTotal - 1;
-    hwp->writeCrtc(hwp, 0x16, temp);
-
-    /* some leftovers */
-    hwp->writeCrtc(hwp, 0x08, 0x00);
-    ViaCrtcMask(hwp, 0x32, 0, 0xFF);  /* ? */
-    ViaCrtcMask(hwp, 0x33, 0, 0xC8);
-
-    /* offset */
-    temp = (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)) >> 3;
-    /* Make sure that this is 32byte aligned */
-    if (temp & 0x03) {
-        temp += 0x03;
-        temp &= ~0x03;
-    }
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Offset: 0x%03X\n", temp));
-    hwp->writeCrtc(hwp, 0x13, temp & 0xFF);
-    ViaCrtcMask(hwp, 0x35, temp >> 3, 0xE0);
-
-    /* fetch count */
-    temp = (mode->CrtcHDisplay * (pScrn->bitsPerPixel >> 3)) >> 3;
-    /* Make sure that this is 32byte aligned */
-    if (temp & 0x03) {
-        temp += 0x03;
-        temp &= ~0x03;
-    }
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Fetch Count: 0x%03X\n", temp));
-    hwp->writeSeq(hwp, 0x1C, (temp >> 1) & 0xFF);
-    ViaSeqMask(hwp, 0x1D, temp >> 9, 0x03);
-
-    /* some leftovers */
-    ViaCrtcMask(hwp, 0x32, 0, 0xFF);
-    ViaCrtcMask(hwp, 0x33, 0, 0xC8);
-}
-
 static CARD32
 ViaComputeDotClock(unsigned clock)
 {
@@ -1692,13 +1361,14 @@
  *
  */
 void
-ViaModePrimary(ScrnInfoPtr pScrn, DisplayModePtr mode)
+ViaModePrimaryLegacy(ScrnInfoPtr pScrn, DisplayModePtr mode)
 {
     vgaHWPtr hwp = VGAHWPTR(pScrn);
     VIAPtr pVia = VIAPTR(pScrn);
     VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
 
     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModePrimary\n"));
+    DEBUG(ViaPrintMode(pScrn, mode));
 
     /* Turn off Screen */
     ViaCrtcMask(hwp, 0x17, 0x00, 0x80);
@@ -1709,7 +1379,8 @@
     hwp->writeCrtc(hwp, 0x6C, 0x00);
     hwp->writeCrtc(hwp, 0x93, 0x00);
 
-    ViaModePrimaryVGA(pScrn, mode);
+    ViaCRTCInit(pScrn);
+    ViaFirstCRTCSetMode(pScrn, mode);
     pBIOSInfo->Clock = ViaModeDotClockTranslate(pScrn, mode);
     pBIOSInfo->ClockExternal = FALSE;
 
@@ -1721,7 +1392,7 @@
     else
         ViaSeqMask(hwp, 0x16, 0x00, 0x40);
 
-    if (pBIOSInfo->PanelActive && ViaPanelGetIndex(pScrn, mode)) {
+    if (pBIOSInfo->Panel->IsActive && ViaPanelGetIndex(pScrn, mode)) {
         VIASetLCDMode(pScrn, mode);
         ViaLCDPower(pScrn, TRUE);
     } else if (pBIOSInfo->PanelPresent)
@@ -1765,192 +1436,23 @@
     hwp->disablePalette(hwp);
 }
 
-void
-ViaModeSecondaryVGAFetchCount(ScrnInfoPtr pScrn, int width)
-{
-
-    vgaHWPtr hwp = VGAHWPTR(pScrn);
-    CARD16 temp;
-
-    /* fetch count */
-    temp = (width * (pScrn->bitsPerPixel >> 3)) >> 3;
-    /* Make sure that this is 32byte aligned */
-    if (temp & 0x03) {
-        temp += 0x03;
-        temp &= ~0x03;
-    }
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Fetch Count: 0x%03X\n", temp));
-    hwp->writeCrtc(hwp, 0x65, (temp >> 1) & 0xFF);
-    ViaCrtcMask(hwp, 0x67, temp >> 7, 0x0C);
-}
-
-void
-ViaModeSecondaryVGAOffset(ScrnInfoPtr pScrn)
-{
-
-    vgaHWPtr hwp = VGAHWPTR(pScrn);
-    CARD16 temp;
-
-    /* offset */
-    temp = (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)) >> 3;
-    if (temp & 0x03) {  /* Make sure that this is 32byte aligned */
-        temp += 0x03;
-        temp &= ~0x03;
-    }
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Offset: 0x%03X\n", temp));
-    hwp->writeCrtc(hwp, 0x66, temp & 0xFF);
-    ViaCrtcMask(hwp, 0x67, temp >> 8, 0x03);
-
-}
-
 /*
  *
  */
-static void
-ViaModeSecondaryVGA(ScrnInfoPtr pScrn, DisplayModePtr mode)
-{
-    vgaHWPtr hwp = VGAHWPTR(pScrn);
-    CARD16 temp;
-
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModeSecondaryVGA\n"));
-
-    /* bpp */
-    switch (pScrn->bitsPerPixel) {
-        case 8:
-            ViaCrtcMask(hwp, 0x67, 0x00, 0xC0);
-            break;
-        case 16:
-            ViaCrtcMask(hwp, 0x67, 0x40, 0xC0);
-            break;
-        case 24:
-        case 32:
-            ViaCrtcMask(hwp, 0x67, 0x80, 0xC0);
-            break;
-        default:
-            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unhandled bitdepth: %d\n",
-                       pScrn->bitsPerPixel);
-            break;
-    }
-
-    /* Crtc registers */
-    /* horizontal total : 4096 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHTotal: 0x%03X\n",
-                     mode->CrtcHTotal));
-    temp = mode->CrtcHTotal - 1;
-    hwp->writeCrtc(hwp, 0x50, temp & 0xFF);
-    ViaCrtcMask(hwp, 0x55, temp >> 8, 0x0F);
-
-    /* horizontal address : 2048 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHDisplay: 0x%03X\n",
-                     mode->CrtcHDisplay));
-    temp = mode->CrtcHDisplay - 1;
-    hwp->writeCrtc(hwp, 0x51, temp & 0xFF);
-    ViaCrtcMask(hwp, 0x55, temp >> 4, 0x70);
-
-    /* horizontal blanking start : 2048 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHBlankStart: 0x%03X\n",
-                     mode->CrtcHBlankStart));
-    if (mode->CrtcHBlankStart != mode->CrtcHDisplay)  /* FIXME */
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Caught X working around "
-                   "an old VGA limitation (HBlankStart).\n");
-    temp = mode->CrtcHDisplay - 1;
-    hwp->writeCrtc(hwp, 0x52, temp & 0xFF);
-    ViaCrtcMask(hwp, 0x54, temp >> 8, 0x07);
-
-    /* horizontal blanking end : 4096 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHBlankEnd: 0x%03X\n",
-                     mode->CrtcHBlankEnd));
-    if (mode->CrtcHBlankEnd != mode->CrtcHTotal)  /* FIXME */
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Caught X working around "
-                   "an old VGA limitation (HBlankEnd).\n");
-    temp = mode->CrtcHTotal - 1;
-    hwp->writeCrtc(hwp, 0x53, temp & 0xFF);
-    ViaCrtcMask(hwp, 0x54, temp >> 5, 0x38);
-    ViaCrtcMask(hwp, 0x5D, temp >> 5, 0x40);
-
-    /* horizontal sync start : 2047 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSyncStart: 0x%03X\n",
-                     mode->CrtcHSyncStart));
-    temp = mode->CrtcHSyncStart;
-    hwp->writeCrtc(hwp, 0x56, temp & 0xFF);
-    ViaCrtcMask(hwp, 0x54, temp >> 2, 0xC0);
-    ViaCrtcMask(hwp, 0x5C, temp >> 3, 0x80);
-
-    /* horizontal sync end : sync start + 512 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSyncEnd: 0x%03X\n",
-                     mode->CrtcHSyncEnd));
-    temp = mode->CrtcHSyncEnd;
-    hwp->writeCrtc(hwp, 0x57, temp & 0xFF);
-    ViaCrtcMask(hwp, 0x5C, temp >> 2, 0x40);
-
-    /* vertical total : 2048 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVTotal: 0x%03X\n",
-                     mode->CrtcVTotal));
-    temp = mode->CrtcVTotal - 1;
-    hwp->writeCrtc(hwp, 0x58, temp & 0xFF);
-    ViaCrtcMask(hwp, 0x5D, temp >> 8, 0x07);
-
-    /* vertical address : 2048 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVDisplay: 0x%03X\n",
-                     mode->CrtcVDisplay));
-    temp = mode->CrtcVDisplay - 1;
-    hwp->writeCrtc(hwp, 0x59, temp & 0xFF);
-    ViaCrtcMask(hwp, 0x5D, temp >> 5, 0x38);
-
-    /* vertical blanking start : 2048 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVBlankStart: 0x%03X\n",
-                     mode->CrtcVBlankStart));
-    if (mode->CrtcVBlankStart != mode->CrtcVDisplay)  /* FIXME */
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Caught X working around "
-                   "an old VGA limitation (VBlankStart).\n");
-    temp = mode->CrtcVDisplay - 1;
-    hwp->writeCrtc(hwp, 0x5A, temp & 0xFF);
-    ViaCrtcMask(hwp, 0x5C, temp >> 8, 0x07);
-
-    /* vertical blanking end : 2048 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVBlankEnd: 0x%03X\n",
-                     mode->CrtcVBlankEnd));
-    if (mode->CrtcVBlankEnd != mode->CrtcVTotal)  /* FIXME */
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Caught X working around "
-                   "an old VGA limitation (VBlankEnd).\n");
-    temp = mode->CrtcVTotal - 1;
-    hwp->writeCrtc(hwp, 0x5B, temp & 0xFF);
-    ViaCrtcMask(hwp, 0x5C, temp >> 5, 0x38);
-
-    /* vertical sync start : 2047 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVSyncStart: 0x%03X\n",
-                     mode->CrtcVSyncStart));
-    temp = mode->CrtcVSyncStart;
-    hwp->writeCrtc(hwp, 0x5E, temp & 0xFF);
-    ViaCrtcMask(hwp, 0x5F, temp >> 3, 0xE0);
-
-    /* vertical sync end : start + 32 */
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVSyncEnd: 0x%03X\n",
-                     mode->CrtcVSyncEnd));
-    temp = mode->CrtcVSyncEnd;
-    ViaCrtcMask(hwp, 0x5F, temp, 0x1F);
-
-    ViaModeSecondaryVGAOffset(pScrn);
-    ViaModeSecondaryVGAFetchCount(pScrn, mode->CrtcHDisplay);
-
-}
-
-/*
- *
- */
 void
-ViaModeSecondary(ScrnInfoPtr pScrn, DisplayModePtr mode)
+ViaModeSecondaryLegacy(ScrnInfoPtr pScrn, DisplayModePtr mode)
 {
     vgaHWPtr hwp = VGAHWPTR(pScrn);
     VIAPtr pVia = VIAPTR(pScrn);
     VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
 
     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModeSecondary\n"));
+    DEBUG(ViaPrintMode(pScrn, mode));
 
     /* Turn off Screen */
     ViaCrtcMask(hwp, 0x17, 0x00, 0x80);
 
-    ViaModeSecondaryVGA(pScrn, mode);
+    ViaSecondCRTCSetMode(pScrn, mode);
 
     if (pBIOSInfo->TVActive)
         ViaTVSetMode(pScrn, mode);
@@ -1959,7 +1461,7 @@
     if (!(pVia->Chipset == VIA_CLE266 && pVia->ChipRev == 0x02))
         ViaCrtcMask(hwp, 0x6C, 0x00, 0x1E);
 
-    if (pBIOSInfo->PanelActive
+    if (pBIOSInfo->Panel->IsActive
         && (pBIOSInfo->PanelIndex != VIA_BIOS_NUM_PANEL)) {
         pBIOSInfo->SetDVI = TRUE;
         VIASetLCDMode(pScrn, mode);
@@ -2017,9 +1519,12 @@
     else
         ViaCrtcMask(hwp, 0x6A, 0x00, 0x08);
 
+    if (pBIOSInfo->LCDPower) 
+        pBIOSInfo->LCDPower(pScrn, On);
+
     /* Find Panel Size Index for PowerSeq Table */
     if (pVia->Chipset == VIA_CLE266) {
-        if (pBIOSInfo->PanelSize != VIA_PANEL_INVALID) {
+        if (pBIOSInfo->Panel->NativeModeIndex != VIA_PANEL_INVALID) {
             for (i = 0; i < NumPowerOn; i++) {
                 if (lcdTable[pBIOSInfo->PanelIndex].powerSeq
                     == powerOn[i].powerSeq)
@@ -2038,3 +1543,137 @@
         ViaLCDPowerSequence(hwp, powerOff[i]);
     usleep(1);
 }
+
+void
+ViaDFPPower(ScrnInfoPtr pScrn, Bool On)
+{
+#ifdef HAVE_DEBUG
+    if (On)
+        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDFPPower: On.\n");
+    else
+        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDFPPower: Off.\n");
+#endif
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+    VIAPtr pVia = VIAPTR(pScrn);
+    VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+
+    /* Display Channel Select */
+    ViaCrtcMask(hwp, 0xD2, 0x30, 0x30);
+
+    /* Power on TMDS */
+    ViaCrtcMask(hwp, 0xD2, 0x00, 0x08);
+    
+}
+
+
+void
+ViaModeFirstCRTC(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModeFirstCRTC\n");
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+    VIAPtr pVia = VIAPTR(pScrn);
+    VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+
+    /* Turn off Screen */
+    ViaCrtcMask(hwp, 0x17, 0x00, 0x80);
+
+    ViaFirstCRTCSetMode(pScrn, mode);
+    pBIOSInfo->Clock = ViaModeDotClockTranslate(pScrn, mode);
+    pBIOSInfo->ClockExternal = FALSE;
+
+    ViaSetPrimaryFIFO(pScrn, mode);
+
+    ViaSetPrimaryDotclock(pScrn, pBIOSInfo->Clock);
+    ViaSetUseExternalClock(hwp);
+    ViaCrtcMask(hwp, 0x6B, 0x00, 0x01);
+
+    hwp->disablePalette(hwp);
+
+    /* Turn on Screen */
+    ViaCrtcMask(hwp, 0x17, 0x80, 0x80);
+}
+
+void
+ViaModeSecondCRTC(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+    VIAPtr pVia = VIAPTR(pScrn);
+    VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+    DisplayModePtr nativeDisplayMode = pBIOSInfo->Panel->NativeDisplayMode;
+    DisplayModePtr centeredMode = pBIOSInfo->Panel->CenteredMode;
+    DisplayModePtr realMode = mode;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModeSecondCRTC\n"));
+
+    if (pBIOSInfo->Panel->IsActive) {
+        if (nativeDisplayMode) {
+            ViaPanelScale(pScrn, mode->HDisplay, mode->VDisplay,
+                          nativeDisplayMode->HDisplay,
+                          nativeDisplayMode->VDisplay);
+            if (!pBIOSInfo->Center
+                && (mode->HDisplay < nativeDisplayMode->HDisplay
+                    || mode->VDisplay < nativeDisplayMode->VDisplay)) {
+                pBIOSInfo->Panel->Scale = TRUE;
+                realMode = nativeDisplayMode;
+            } else {
+                pBIOSInfo->Panel->Scale = FALSE;
+                ViaPanelCenterMode(centeredMode, nativeDisplayMode, mode);
+                realMode = centeredMode;
+                ViaPanelScaleDisable(pScrn);
+            }
+        }
+    }
+
+    ViaSecondCRTCSetMode(pScrn, realMode);
+    ViaSetSecondaryFIFO(pScrn, realMode);
+    pBIOSInfo->Clock = ViaModeDotClockTranslate(pScrn, realMode);
+
+    /* Fix LCD scaling */
+    ViaSecondCRTCHorizontalQWCount(pScrn, mode->CrtcHDisplay);
+
+    pBIOSInfo->ClockExternal = FALSE;
+    ViaSetSecondaryDotclock(pScrn, pBIOSInfo->Clock);
+    ViaSetUseExternalClock(hwp);
+
+    hwp->disablePalette(hwp);
+}
+
+void
+ViaModeSet(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+    VIAPtr pVia = VIAPTR(pScrn);
+    VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModeSet\n"));
+
+    ViaPrintMode(pScrn, mode);
+
+    if (pBIOSInfo->SecondCRTC->IsActive) {
+        ViaModeSecondCRTC(pScrn, mode);
+        ViaSecondDisplayChannelEnable(pScrn);
+    }
+
+    if (pBIOSInfo->FirstCRTC->IsActive) {
+        if (pBIOSInfo->CrtActive) {
+            /* CRT on FirstCRTC */
+            ViaDisplaySetStreamOnCRT(pScrn, TRUE);
+            ViaDisplayEnableCRT(pScrn);
+        }
+
+        if (pBIOSInfo->DfpActive) {
+            /* DFP on FirstCrtc */
+            ViaDisplaySetStreamOnDFP(pScrn, TRUE);
+            ViaDFPPower(pScrn, TRUE);
+        }
+        
+        ViaModeFirstCRTC(pScrn, mode);
+    } else {
+        ViaDisplayDisableCRT(pScrn);
+    }
+
+    if (pBIOSInfo->Simultaneous->IsActive) {
+        ViaDisplayEnableSimultaneous(pScrn);
+    } else {
+        ViaDisplayDisableSimultaneous(pScrn);
+    }
+}
Index: src/via_mode.h
===================================================================
--- src/via_mode.h	(.../tags/release_0_2_903)	(revision 751)
+++ src/via_mode.h	(.../trunk)	(revision 751)
@@ -32,7 +32,7 @@
  */
 #define VIA_BW_MIN       74000000 /* > 640x480@60Hz@32bpp */
 #define VIA_BW_DDR200   394000000
-#define VIA_BW_DDR400   461000000
+#define VIA_BW_DDR400   498000000 /* > 1920x1080@60Hz@32bpp */
 #define VIA_BW_DDR667   922000000
 
     
@@ -113,20 +113,27 @@
 
 static DisplayModeRec ViaPanelModes[] = {
     { MODEPREFIX("640x480"),    25312,  640,  656,  752,  800, 0,  480,  489,  491,  525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX },
+    { MODEPREFIX("720x480"),    26591,  720,  736,  808,  896, 0,  480,  480,  483,  497, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX },
+    { MODEPREFIX("720x576"),    32663,  720,  744,  816,  912, 0,  576,  576,  579,  597, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX },
+    { MODEPREFIX("800x480"),    40000,   800,  832,  960, 1056, 0,   480,  541,  545,  628, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX },
     { MODEPREFIX("800x600"),    39822,  800,  840,  968, 1056, 0,  600,  600,  604,  628, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX },
+    { MODEPREFIX("848x480"),    33750,  848,  864,  976, 1088, 0,  480,  485,  493,  517, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX },
+    { 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("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("1280x1024"), 108280, 1280, 1328, 1440, 1688, 0, 1024, 1024, 1027, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX },
-    { MODEPREFIX("1600x1200"), 161793, 1600, 1664, 1856, 2160, 0, 1200, 1200, 1203, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX },
     { MODEPREFIX("1280x768"),   81135, 1280, 1328, 1440, 1688, 0,  768,  770,  776,  802, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX },
+    { MODEPREFIX("1280x720"),   74600, 1280, 1341, 1474, 1688, 0,  720,  721,  724,  746, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX },
     { MODEPREFIX("1280x960"),  108280, 1280, 1376, 1488, 1800, 0,  960,  960,  963, 1000, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX },
-    { MODEPREFIX("848x480"),    33750,  848,  864,  976, 1088, 0,  480,  485,  493,  517, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX },
+    { MODEPREFIX("1280x1024"), 108280, 1280, 1328, 1440, 1688, 0, 1024, 1024, 1027, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX },
+    { MODEPREFIX("1360x768"),   85500, 1360, 1392, 1712, 1744, 0,  768,  783,  791,  807, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX },
+    { MODEPREFIX("1366x768"),  85860,  1366, 1440, 1584, 1800, 0, 768,  769,  772,   795, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX },
     { MODEPREFIX("1400x1050"), 122726, 1400, 1488, 1640, 1880, 0, 1050, 1050, 1053, 1087, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX },
-    { MODEPREFIX("720x480"),    26591,  720,  736,  808,  896, 0,  480,  480,  483,  497, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX },
-    { MODEPREFIX("720x576"),    32663,  720,  744,  816,  912, 0,  576,  576,  579,  597, 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("856x480"),    31704,  856,  872,  960, 1064, 0,  480,  480,  483,  497, 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("1440x900"),  106470, 1440, 1520, 1672, 1904, 0,  900,  901,  904,  932, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX },
+    { MODEPREFIX("1600x1200"), 161793, 1600, 1664, 1856, 2160, 0, 1200, 1200, 1203, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX },
+    { MODEPREFIX("1920x1080"), 172900, 1920, 2043, 2249, 2578, 0, 1080, 1081, 1084, 1118, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX },
     { MODEPREFIX(NULL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIX },
 };
 
@@ -182,6 +189,7 @@
     {VIA_RES_1024X512,  VIA_PANEL_INVALID, 1024,  512},
     {VIA_RES_856X480,   VIA_PANEL_INVALID,  856,  480},
     {VIA_RES_1024X576,  VIA_PANEL_INVALID, 1024,  576},
+    {VIA_RES_800X480,   VIA_PANEL8X4,  	    800,  480},
     {VIA_RES_INVALID,   VIA_PANEL_INVALID,    0,    0}
 };
 
Index: src/via_driver.c
===================================================================
--- src/via_driver.c	(.../tags/release_0_2_903)	(revision 751)
+++ src/via_driver.c	(.../trunk)	(revision 751)
@@ -73,6 +73,7 @@
     return via_pci_device(&bridge_match);
 }
 
+struct pci_device *
 viaPciDeviceVga(void)
 {
     static const struct pci_slot_match bridge_match = {
@@ -126,6 +127,7 @@
    VIA_DEVICE_MATCH (PCI_CHIP_VT3364, 0 ),
    VIA_DEVICE_MATCH (PCI_CHIP_VT3324, 0 ),
    VIA_DEVICE_MATCH (PCI_CHIP_VT3327, 0 ),
+   VIA_DEVICE_MATCH (PCI_CHIP_VT3353, 0 ),
     { 0, 0, 0 },
 };
 
@@ -161,6 +163,7 @@
     {VIA_P4M900,   "P4M900/VN896/CN896"},
     {VIA_CX700,    "CX700/VX700"},
     {VIA_P4M890,   "P4M890"},
+    {VIA_VX800,    "VX800"},
     {-1,            NULL }
 };
 
@@ -175,6 +178,7 @@
     {VIA_P4M900,   PCI_CHIP_VT3364,    RES_SHARED_VGA},
     {VIA_CX700,    PCI_CHIP_VT3324,    RES_SHARED_VGA},
     {VIA_P4M890,   PCI_CHIP_VT3327,    RES_SHARED_VGA},
+    {VIA_VX800,    PCI_CHIP_VT3353,    RES_SHARED_VGA},
     {-1,           -1,                 RES_UNDEFINED}
 };
 
@@ -189,11 +193,9 @@
 #endif
     OPTION_VBEMODES,
     OPTION_NOACCEL,
-#ifdef VIA_HAVE_EXA
     OPTION_ACCELMETHOD,
     OPTION_EXA_NOCOMPOSITE,
     OPTION_EXA_SCRATCH_SIZE,
-#endif
     OPTION_SWCURSOR,
     OPTION_SHADOW_FB,
     OPTION_ROTATE,
@@ -227,11 +229,9 @@
 #endif
     {OPTION_VBEMODES,            "VBEModes",         OPTV_BOOLEAN, {0}, FALSE},
     {OPTION_NOACCEL,             "NoAccel",          OPTV_BOOLEAN, {0}, FALSE},
-#ifdef VIA_HAVE_EXA
     {OPTION_ACCELMETHOD,         "AccelMethod",      OPTV_STRING,  {0}, FALSE},
     {OPTION_EXA_NOCOMPOSITE,     "ExaNoComposite",   OPTV_BOOLEAN, {0}, FALSE},
     {OPTION_EXA_SCRATCH_SIZE,    "ExaScratchSize",   OPTV_INTEGER, {0}, FALSE},
-#endif
     {OPTION_SWCURSOR,            "SWCursor",         OPTV_BOOLEAN, {0}, FALSE},
     {OPTION_SHADOW_FB,           "ShadowFB",         OPTV_BOOLEAN, {0}, FALSE},
     {OPTION_ROTATE,              "Rotate",           OPTV_ANYSTR,  {0}, FALSE},
@@ -346,7 +346,6 @@
     NULL
 };
 
-#ifdef VIA_HAVE_EXA
 static const char *exaSymbols[] = {
     "exaGetVersion",
     "exaDriverInit",
@@ -356,14 +355,9 @@
     "exaGetPixmapPitch",
     "exaGetPixmapOffset",
     "exaWaitSync",
-#if (EXA_VERSION_MAJOR >= 2)
     "exaDriverAlloc",
-#else
-    "exaGetVersion",
-#endif
     NULL
 };
-#endif
 
 static const char *shadowSymbols[] = {
     "ShadowFBInit",
@@ -486,9 +480,7 @@
 #endif
                           ramdacSymbols,
                           xaaSymbols,
-#ifdef VIA_HAVE_EXA
                           exaSymbols,
-#endif
                           shadowSymbols,
                           vbeSymbols,
                           i2cSymbols,
@@ -513,34 +505,97 @@
 static Bool
 VIAGetRec(ScrnInfoPtr pScrn)
 {
+    Bool ret;
+
     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAGetRec\n"));
+
+    ret = FALSE;
     if (pScrn->driverPrivate)
         return TRUE;
 
     pScrn->driverPrivate = xnfcalloc(sizeof(VIARec), 1);
-    ((VIARec *) (pScrn->driverPrivate))->pBIOSInfo =
-            xnfcalloc(sizeof(VIABIOSInfoRec), 1);
-    ((VIARec *) (pScrn->driverPrivate))->pBIOSInfo->scrnIndex =
-            pScrn->scrnIndex;
-    ((VIARec *) (pScrn->driverPrivate))->pBIOSInfo->TVI2CDev = NULL;
+    VIAPtr pVia = ((VIARec *) (pScrn->driverPrivate));
 
-    ((VIARec *) (pScrn->driverPrivate))->CursorImage = NULL;
+    if (pVia) {
 
-    return TRUE;
+        pVia->pBIOSInfo = xnfcalloc(sizeof(VIABIOSInfoRec), 1);
+        VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
 
+        if (pBIOSInfo) {
+            pBIOSInfo->scrnIndex = pScrn->scrnIndex;
+            pBIOSInfo->TVI2CDev = NULL;
+
+            pBIOSInfo->Panel =
+                    (ViaPanelInfoPtr) xnfcalloc(sizeof(ViaPanelInfoRec), 1);
+            if (pBIOSInfo->Panel) {
+                pBIOSInfo->Panel->NativeModeIndex = VIA_PANEL_INVALID;
+                pBIOSInfo->Panel->NativeMode =
+                        (ViaPanelModePtr) xnfcalloc(sizeof(ViaPanelModeRec), 1);
+                pBIOSInfo->Panel->CenteredMode =
+                        (DisplayModePtr) xnfcalloc(sizeof(DisplayModeRec), 1);
+                pBIOSInfo->Lvds =
+                        (ViaLVDSInfoPtr) xnfcalloc(sizeof(ViaLVDSInfoRec), 1);
+                pBIOSInfo->FirstCRTC =
+                        (ViaCRTCInfoPtr) xnfcalloc(sizeof(ViaCRTCInfoRec), 1);
+                pBIOSInfo->SecondCRTC =
+                        (ViaCRTCInfoPtr) xnfcalloc(sizeof(ViaCRTCInfoRec), 1);
+                pBIOSInfo->Simultaneous =
+                        (ViaSimultaneousInfoPtr)
+                        xnfcalloc(sizeof(ViaSimultaneousInfoRec), 1);
+                ret = pBIOSInfo->Panel->NativeMode
+                        && pBIOSInfo->Panel->CenteredMode && pBIOSInfo->Lvds
+                        && pBIOSInfo->FirstCRTC && pBIOSInfo->SecondCRTC
+                        && pBIOSInfo->Simultaneous;
+            }
+            pVia->VideoRegs =
+                    (video_via_regs *) xnfcalloc(sizeof(video_via_regs), 1);
+            if (!pVia->VideoRegs)
+                ret = FALSE;
+        }
+    }
+
+    return ret;
+
 } /* VIAGetRec */
 
 
 static void
 VIAFreeRec(ScrnInfoPtr pScrn)
 {
+    VIAPtr pVia = VIAPTR(pScrn);
+
     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAFreeRec\n"));
     if (!pScrn->driverPrivate)
         return;
 
+    VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+
+    if (pBIOSInfo) {
+
+        if (pBIOSInfo->Panel) {
+            if (pBIOSInfo->Panel->NativeMode)
+                xfree(pBIOSInfo->Panel->NativeMode);
+            if (pBIOSInfo->Panel->CenteredMode)
+                xfree(pBIOSInfo->Panel->CenteredMode);
+            xfree(pBIOSInfo->Panel);
+        }
+
+        if (pBIOSInfo->FirstCRTC)
+            xfree(pBIOSInfo->FirstCRTC);
+        if (pBIOSInfo->SecondCRTC)
+            xfree(pBIOSInfo->SecondCRTC);
+        if (pBIOSInfo->Simultaneous)
+            xfree(pBIOSInfo->Simultaneous);
+        if (pBIOSInfo->Lvds)
+            xfree(pBIOSInfo->Lvds);
+    }
+
     if (VIAPTR(pScrn)->pVbe)
         vbeFree(VIAPTR(pScrn)->pVbe);
 
+    if (pVia->VideoRegs)
+        xfree(pVia->VideoRegs);
+
     if (((VIARec *) (pScrn->driverPrivate))->pBIOSInfo->TVI2CDev)
         xf86DestroyI2CDevRec((((VIARec *) (pScrn->driverPrivate))->pBIOSInfo->
                               TVI2CDev), TRUE);
@@ -787,10 +842,8 @@
 
     pVia->shadowFB = FALSE;
     pVia->NoAccel = FALSE;
-#ifdef VIA_HAVE_EXA
     pVia->noComposite = FALSE;
     pVia->exaScratchSize = VIA_SCRATCH_SIZE / 1024;
-#endif
     pVia->hwcursor = TRUE;
     pVia->VQEnable = TRUE;
     pVia->DRIIrqEnable = TRUE;
@@ -813,6 +866,8 @@
     pVia->swov.maxHInterp = 600;
     pVia->useLegacyVBE = TRUE;
 
+    pVia->UseLegacyModeSwitch = TRUE;
+    
     switch (pVia->Chipset) {
         case VIA_KM400:
             /* IRQ is not broken on KM400A, but testing (pVia->ChipRev < 0x80)
@@ -820,19 +875,18 @@
             pVia->DRIIrqEnable = FALSE;
             break;
         case VIA_K8M800:
-            pVia->agpEnable = FALSE;
             pVia->DRIIrqEnable = FALSE;
             break;
         case VIA_PM800:
             pVia->VideoEngine = VIDEO_ENGINE_CME;
             break;
         case VIA_VM800:
-            pVia->agpEnable = FALSE;
             break;
         case VIA_K8M890:
             pVia->VideoEngine = VIDEO_ENGINE_CME;
             pVia->agpEnable = FALSE;
             pVia->dmaXV = FALSE;
+            pVia->UseLegacyModeSwitch = FALSE;
             break;
         case VIA_P4M900:
             pVia->VideoEngine = VIDEO_ENGINE_CME;
@@ -840,16 +894,25 @@
             pVia->useLegacyVBE = FALSE;
             /* FIXME: this needs to be tested */
             pVia->dmaXV = FALSE;
+            pVia->UseLegacyModeSwitch = FALSE;
             break;
         case VIA_CX700:
             pVia->VideoEngine = VIDEO_ENGINE_CME;
             pVia->swov.maxWInterp = 1920;
             pVia->swov.maxHInterp = 1080;
+            pVia->UseLegacyModeSwitch = FALSE;
             break;
         case VIA_P4M890:
             pVia->VideoEngine = VIDEO_ENGINE_CME;
             pVia->dmaXV = FALSE;
+            pVia->UseLegacyModeSwitch = FALSE;
             break;
+        case VIA_VX800:
+            pVia->VideoEngine = VIDEO_ENGINE_CME;
+            /* pVia->agpEnable = FALSE;
+            pVia->dmaXV = FALSE;*/
+            pVia->UseLegacyModeSwitch = FALSE;
+            break;
     }
 
     return TRUE;
@@ -875,6 +938,7 @@
 
 #ifdef XSERVER_LIBPCIACCESS
     struct pci_device *bridge = via_host_bridge();
+    uint8_t rev = 0 ;
 #endif
 
     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAPreInit\n"));
@@ -1067,9 +1131,8 @@
     } else {
         /* Read PCI bus 0, dev 0, function 0, index 0xF6 to get chip revision */
 #ifdef XSERVER_LIBPCIACCESS
-        struct pci_device *bridge = via_host_bridge();
-
-        pci_device_cfg_read_u8(bridge, &pVia->ChipRev, 0xF6);
+	pci_device_cfg_read_u8(bridge, &rev, 0xF6);
+	pVia->ChipRev = rev ;
 #else
         pVia->ChipRev = pciReadByte(pciTag(0, 0, 0), 0xF6);
 #endif
@@ -1090,6 +1153,8 @@
     struct pci_device *vgaDevice = viaPciDeviceVga();
 #endif
 
+    hwp = VGAHWPTR(pScrn);
+
     switch (pVia->Chipset) {
         case VIA_CLE266:
         case VIA_KM400:
@@ -1114,6 +1179,7 @@
         case VIA_P4M890:
         case VIA_P4M900:
         case VIA_CX700:
+        case VIA_VX800:
 #ifdef XSERVER_LIBPCIACCESS
             pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1);
 #else
@@ -1139,7 +1205,7 @@
             } else {
                 from = X_DEFAULT;
                 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-                           "No memory-detection done.  Use VideoRAM option.\n");
+                           "No memory-detection done. Use VideoRAM option.\n");
             }
     }
 
@@ -1202,7 +1268,6 @@
                        "Valid options are \"CW\" or \"CCW\".\n");
         }
     }
-#ifdef VIA_HAVE_EXA
     if (!pVia->NoAccel) {
         from = X_DEFAULT;
         if ((s = (char *)xf86GetOptValString(VIAOptions, OPTION_ACCELMETHOD))) {
@@ -1235,13 +1300,13 @@
                        pVia->exaScratchSize);
         }
     }
-#endif /* VIA_HAVE_EXA */
 
     /* Use a hardware cursor, unless on secondary or on shadow framebuffer. */
     from = X_DEFAULT;
     if (pVia->IsSecondary || pVia->shadowFB)
         pVia->hwcursor = FALSE;
-    else if (xf86GetOptValBool(VIAOptions, OPTION_SWCURSOR, &pVia->hwcursor)) {
+    else if (xf86GetOptValBool(VIAOptions, OPTION_SWCURSOR,
+                               &pVia->hwcursor)) {
         pVia->hwcursor = !pVia->hwcursor;
         from = X_CONFIG;
     }
@@ -1346,8 +1411,8 @@
             pVia->ActiveDevice |= VIA_DEVICE_CRT;
         if (strstr(s, "LCD"))
             pVia->ActiveDevice |= VIA_DEVICE_LCD;
-        if (strstr(s, "DFP"))  /* just treat this the same as LCD */
-            pVia->ActiveDevice |= VIA_DEVICE_LCD;
+        if (strstr(s, "DFP"))  
+            pVia->ActiveDevice |= VIA_DEVICE_DFP;
         if (strstr(s, "TV"))
             pVia->ActiveDevice |= VIA_DEVICE_TV;
     }
@@ -1375,45 +1440,24 @@
     xf86DrvMsg(pScrn->scrnIndex, from, "DVI Center is %s.\n",
                pBIOSInfo->Center ? "enabled" : "disabled");
 
-
     /* Panel Size Option */
-    pBIOSInfo->PanelSize = VIA_PANEL_INVALID;
     if ((s = xf86GetOptValString(VIAOptions, OPTION_PANELSIZE))) {
-        if (!xf86NameCmp(s, "640x480")) {
-            pBIOSInfo->PanelSize = VIA_PANEL6X4;
+        ViaPanelGetNativeModeFromOption(pScrn, s);
+        if (pBIOSInfo->Panel->NativeModeIndex != VIA_PANEL_INVALID) {
+            ViaPanelModePtr mode = pBIOSInfo->Panel->NativeMode;
+
+            DEBUG(xf86DrvMsg
+                  (pScrn->scrnIndex, X_CONFIG, "Panel mode index is %d\n",
+                   pBIOSInfo->Panel->NativeModeIndex));
             xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
-                       "Selected Panel Size is 640x480\n");
-        } else if (!xf86NameCmp(s, "800x600")) {
-            pBIOSInfo->PanelSize = VIA_PANEL8X6;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
-                       "Selected Panel Size is 800x600\n");
-        } else if (!xf86NameCmp(s, "1024x768")) {
-            pBIOSInfo->PanelSize = VIA_PANEL10X7;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
-                       "Selected Panel Size is 1024x768\n");
-        } else if (!xf86NameCmp(s, "1280x768")) {
-            pBIOSInfo->PanelSize = VIA_PANEL12X7;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
-                       "Selected Panel Size is 1280x768\n");
-        } else if (!xf86NameCmp(s, "1280x800")) {
-            pBIOSInfo->PanelSize = VIA_PANEL12X8;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
-                       "Selected Panel Size is 1280x800\n");
-        } else if (!xf86NameCmp(s, "1280x1024")) {
-            pBIOSInfo->PanelSize = VIA_PANEL12X10;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
-                       "Selected Panel Size is 1280x1024\n");
-        } else if (!xf86NameCmp(s, "1400x1050")) {
-            pBIOSInfo->PanelSize = VIA_PANEL14X10;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
-                       "Selected Panel Size is 1400x1050\n");
+                       "Selected Panel Size is %dx%d\n", mode->Width,
+                       mode->Height);
         }
     } else {
         xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
                    "Panel size is not selected from config file.\n");
     }
 
-
     /* Force the use of the Panel? */
     pBIOSInfo->ForcePanel = FALSE;
     from = xf86GetOptValBool(VIAOptions, OPTION_FORCEPANEL,
@@ -1504,7 +1548,6 @@
         VIAFreeRec(pScrn);
         return FALSE;
     }
-    hwp = VGAHWPTR(pScrn);
 
 #ifdef HAVE_DEBUG
     //pVia->PrintVGARegs = FALSE;
@@ -1607,18 +1650,21 @@
         return FALSE;
     }
 
-    if (pBIOSInfo->PanelActive &&
+	/* Might not belong here temporary fix for bug fix */
+    ViaPreInitCRTCConfig(pScrn);
+
+    if (!pVia->UseLegacyModeSwitch) {
+        if (pBIOSInfo->Panel->IsActive)
+            ViaPanelPreInit(pScrn);
+    }
+
+    if (pBIOSInfo->Panel->IsActive &&
         ((pVia->Chipset == VIA_K8M800) ||
          (pVia->Chipset == VIA_PM800) ||
-         (pVia->Chipset == VIA_VM800) ||
-         (pVia->Chipset == VIA_P4M890) ||
-         (pVia->Chipset == VIA_K8M890) ||
-         (pVia->Chipset == VIA_CX700) ||
-         (pVia->Chipset == VIA_P4M900))) {
+         (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,
-                   "Panel on K8M800, PM800, VM800, P4M890, K8M890, CX700 or "
-                   "P4M900 is currently not supported.\n");
-        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
                    "Using VBE to set modes to work around this.\n");
         pVia->useVBEModes = TRUE;
     }
@@ -1755,9 +1801,7 @@
 #endif
 
     if (!pVia->NoAccel) {
-#ifdef VIA_HAVE_EXA
         if (pVia->useEXA) {
-#if (EXA_VERSION_MAJOR >= 2)
             XF86ModReqInfo req;
             int errmaj, errmin;
 
@@ -1770,16 +1814,8 @@
                 VIAFreeRec(pScrn);
                 return FALSE;
             }
-#else
-
-            if (!xf86LoadSubModule(pScrn, "exa")) {
-                VIAFreeRec(pScrn);
-                return FALSE;
-            }
-#endif /* EXA_VERSION */
             xf86LoaderReqSymLists(exaSymbols, NULL);
         }
-#endif /* VIA_HAVE_EXA */
         if (!xf86LoadSubModule(pScrn, "xaa")) {
             VIAFreeRec(pScrn);
             return FALSE;
@@ -1836,7 +1872,7 @@
 
     /* A patch for APM suspend/resume, when HWCursor has garbage. */
     if (pVia->hwcursor)
-        ViaCursorRestore(pScrn);
+        viaCursorRestore(pScrn);
 
     /* Restore video status. */
     if (!pVia->IsSecondary)
@@ -1890,7 +1926,7 @@
     viaAccelSync(pScrn);
 
     /* A soft reset helps to avoid a 3D hang on VT switch. */
-    if (pVia->Chipset != VIA_K8M890 && pVia->Chipset != VIA_P4M900)
+    if (pVia->Chipset != VIA_K8M890 && pVia->Chipset != VIA_P4M900 && pVia->Chipset != VIA_VX800)
         hwp->writeSeq(hwp, 0x1A, pVia->SavedReg.SR1A | 0x40);
 
 #ifdef XF86DRI
@@ -1908,7 +1944,7 @@
         viaSaveVideo(pScrn);
 
     if (pVia->hwcursor)
-        ViaCursorStore(pScrn);
+        viaCursorStore(pScrn);
 
     if (pVia->pVbe && pVia->vbeSR)
         ViaVbeSaveRestore(pScrn, MODE_RESTORE);
@@ -1918,7 +1954,40 @@
     vgaHWLock(hwp);
 }
 
+static void
+ViaGammaDisable(ScrnInfoPtr pScrn)
+{
 
+    VIAPtr pVia = VIAPTR(pScrn);
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+    switch (pVia->Chipset) {
+        case VIA_CLE266:
+        case VIA_KM400:
+            ViaSeqMask(hwp, 0x16, 0x00, 0x80);
+            break;
+        default:
+            ViaCrtcMask(hwp, 0x33, 0x00, 0x80);
+            break;
+    }
+
+    /* Disable gamma on secondary */
+    /* This is needed or the hardware will lockup */
+    ViaSeqMask(hwp, 0x1A, 0x00, 0x01);
+    ViaCrtcMask(hwp, 0x6A, 0x00, 0x02);
+    switch (pVia->Chipset) {
+        case VIA_CLE266:
+        case VIA_KM400:
+        case VIA_K8M800:
+        case VIA_PM800:
+            break;
+        default:
+            ViaCrtcMask(hwp, 0x6A, 0x00, 0x20);
+            break;
+    }
+
+}
+
 static void
 VIASave(ScrnInfoPtr pScrn)
 {
@@ -2009,6 +2078,7 @@
         Regs->CR35 = hwp->readCrtc(hwp, 0x35);
         Regs->CR36 = hwp->readCrtc(hwp, 0x36);
 
+        Regs->CR48 = hwp->readCrtc(hwp, 0x48);
         Regs->CR49 = hwp->readCrtc(hwp, 0x49);
 
         DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TVSave...\n"));
@@ -2019,15 +2089,23 @@
         for (i = 0; i < 68; i++)
             Regs->CRTCRegs[i] = hwp->readCrtc(hwp, i + 0x50);
 
-        Regs->CRA0 = hwp->readCrtc(hwp, 0xA0);
-        Regs->CRA1 = hwp->readCrtc(hwp, 0xA1);
-        Regs->CRA2 = hwp->readCrtc(hwp, 0xA2);
+        if (pVia->Chipset != VIA_CLE266 && pVia->Chipset != VIA_KM400) {
 
-        Regs->CR97 = hwp->readCrtc(hwp, 0x97);
-        Regs->CR99 = hwp->readCrtc(hwp, 0x99);
-        Regs->CR9B = hwp->readCrtc(hwp, 0x9B);
-        Regs->CR9F = hwp->readCrtc(hwp, 0x9F);
+            Regs->CRA0 = hwp->readCrtc(hwp, 0xA0);
+            Regs->CRA1 = hwp->readCrtc(hwp, 0xA1);
+            Regs->CRA2 = hwp->readCrtc(hwp, 0xA2);
 
+            Regs->CR97 = hwp->readCrtc(hwp, 0x97);
+            Regs->CR99 = hwp->readCrtc(hwp, 0x99);
+            Regs->CR9B = hwp->readCrtc(hwp, 0x9B);
+            Regs->CR9F = hwp->readCrtc(hwp, 0x9F);
+
+        }
+
+        /* Save TMDS status */
+        if ((pVia->Chipset == VIA_CX700) || (pVia->Chipset == VIA_VX800))
+            Regs->CRD2 = hwp->readCrtc(hwp, 0xD2);
+        
         vgaHWProtect(pScrn, FALSE);
     }
 }
@@ -2055,6 +2133,8 @@
     hwp->writeCrtc(hwp, 0x6B, 0x00);
     hwp->writeCrtc(hwp, 0x6C, 0x00);
 
+    ViaGammaDisable(pScrn);
+
     if (pBIOSInfo->TVI2CDev)
         ViaTVRestore(pScrn);
 
@@ -2118,22 +2198,31 @@
     hwp->writeCrtc(hwp, 0x35, Regs->CR35);
     hwp->writeCrtc(hwp, 0x36, Regs->CR36);
 
+    hwp->writeCrtc(hwp, 0x48, Regs->CR48);
     hwp->writeCrtc(hwp, 0x49, Regs->CR49);
 
     /* Restore LCD control registers. */
     for (i = 0; i < 68; i++)
         hwp->writeCrtc(hwp, i + 0x50, Regs->CRTCRegs[i]);
 
-    hwp->writeCrtc(hwp, 0xA0, Regs->CRA0);
-    hwp->writeCrtc(hwp, 0xA1, Regs->CRA1);
-    hwp->writeCrtc(hwp, 0xA2, Regs->CRA2);
-#if 0
-    hwp->writeCrtc(hwp, 0x97, Regs->CR97);
-    hwp->writeCrtc(hwp, 0x99, Regs->CR99);
-    hwp->writeCrtc(hwp, 0x9B, Regs->CR9B);
-    hwp->writeCrtc(hwp, 0x9F, Regs->CR9F);
-#endif
-    if (pBIOSInfo->PanelActive)
+    if (pVia->Chipset != VIA_CLE266 && pVia->Chipset != VIA_KM400) {
+
+        hwp->writeCrtc(hwp, 0xA0, Regs->CRA0);
+        hwp->writeCrtc(hwp, 0xA1, Regs->CRA1);
+        hwp->writeCrtc(hwp, 0xA2, Regs->CRA2);
+
+        hwp->writeCrtc(hwp, 0x97, Regs->CR97);
+        hwp->writeCrtc(hwp, 0x99, Regs->CR99);
+        hwp->writeCrtc(hwp, 0x9B, Regs->CR9B);
+        hwp->writeCrtc(hwp, 0x9F, Regs->CR9F);
+
+    }
+
+    /* Restore TMDS status */
+    if ((pVia->Chipset == VIA_CX700) || (pVia->Chipset == VIA_VX800))
+        hwp->writeCrtc(hwp, 0xD2, Regs->CRD2);
+    
+    if (pBIOSInfo->Panel->IsActive)
         ViaLCDPower(pScrn, TRUE);
 
     ViaDisablePrimaryFIFO(pScrn);
@@ -2145,26 +2234,61 @@
     vgaHWProtect(pScrn, FALSE);
 }
 
+static void
+ViaMMIOEnable(ScrnInfoPtr pScrn)
+{
+    VIAPtr pVia = VIAPTR(pScrn);
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
 
+    switch (pVia->Chipset) {
+        case VIA_K8M890:
+        case VIA_CX700:
+        case VIA_P4M900:
+        case VIA_VX800:
+            ViaSeqMask(hwp, 0x1A, 0x08, 0x08);
+            break;
+        default:
+            if (pVia->IsSecondary)
+                ViaSeqMask(hwp, 0x1A, 0x38, 0x38);
+            else
+                ViaSeqMask(hwp, 0x1A, 0x68, 0x68);
+            break;
+    }
+}
+
+static void
+ViaMMIODisable(ScrnInfoPtr pScrn)
+{
+    VIAPtr pVia = VIAPTR(pScrn);
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+    switch (pVia->Chipset) {
+        case VIA_K8M890:
+        case VIA_CX700:
+        case VIA_P4M900:
+        case VIA_VX800:
+            ViaSeqMask(hwp, 0x1A, 0x00, 0x08);
+            break;
+        default:
+            ViaSeqMask(hwp, 0x1A, 0x00, 0x60);
+            break;
+    }
+}
+
 static Bool
 VIAMapMMIO(ScrnInfoPtr pScrn)
 {
     VIAPtr pVia = VIAPTR(pScrn);
 
 #ifdef XSERVER_LIBPCIACCESS
+    pVia->MmioBase = pVia->PciInfo->regions[1].base_addr;
     int err;
+#else
+    pVia->MmioBase = pVia->PciInfo->memBase[1];
 #endif
 
     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAMapMMIO\n"));
 
-#ifdef XSERVER_LIBPCIACCESS
-    pVia->FrameBufferBase = pVia->PciInfo->regions[0].base_addr;
-    pVia->MmioBase = pVia->PciInfo->regions[1].base_addr;
-#else
-    pVia->FrameBufferBase = pVia->PciInfo->memBase[0];
-    pVia->MmioBase = pVia->PciInfo->memBase[1];
-#endif
-
     xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
                "mapping MMIO @ 0x%lx with size 0x%x\n",
                pVia->MmioBase, VIA_MMIO_REGSIZE);
@@ -2196,8 +2320,7 @@
     err = pci_device_map_range(pVia->PciInfo,
                                pVia->MmioBase + VIA_MMIO_BLTBASE,
                                VIA_MMIO_BLTSIZE,
-                               (PCI_DEV_MAP_FLAG_WRITABLE
-                                | PCI_DEV_MAP_FLAG_WRITE_COMBINE),
+                               PCI_DEV_MAP_FLAG_WRITABLE,
                                (void **)&pVia->BltBase);
 
     if (err) {
@@ -2215,7 +2338,7 @@
 
     if (!pVia->MapBase || !pVia->BltBase) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "Internal error: cound not map registers\n");
+                   "BitBlit could not be mapped.\n");
         return FALSE;
     }
 
@@ -2238,14 +2361,15 @@
         hwp->writeMiscOut(hwp, val | 0x01);
 
         /* Unlock extended IO space. */
-        hwp->writeSeq(hwp, 0x10, 0x01);
+        ViaSeqMask(hwp, 0x10, 0x01, 0x01);
 
-        /* Enable MMIO. */
-        if (pVia->IsSecondary)
-            ViaSeqMask(hwp, 0x1A, 0x38, 0x38);
-        else
-            ViaSeqMask(hwp, 0x1A, 0x68, 0x68);
+        ViaMMIOEnable(pScrn);
 
+        vgaHWSetMmioFuncs(hwp, pVia->MapBase, 0x8000);
+
+        /* Unlock CRTC. */
+        ViaCrtcMask(hwp, 0x47, 0x00, 0x01);
+
         vgaHWGetIOBase(hwp);
     }
 
@@ -2257,8 +2381,12 @@
 VIAMapFB(ScrnInfoPtr pScrn)
 {
     VIAPtr pVia = VIAPTR(pScrn);
+
 #ifdef XSERVER_LIBPCIACCESS
+    pVia->FrameBufferBase = pVia->PciInfo->regions[0].base_addr;
     int err;
+#else
+    pVia->FrameBufferBase = pVia->PciInfo->memBase[0];
 #endif
 
     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAMapFB\n"));
@@ -2298,7 +2426,8 @@
 #ifdef XSERVER_LIBPCIACCESS
         err = pci_device_map_range(pVia->PciInfo, pVia->FrameBufferBase,
                                    pVia->videoRambytes,
-                                   PCI_DEV_MAP_FLAG_WRITABLE,
+                                   (PCI_DEV_MAP_FLAG_WRITABLE |
+                                    PCI_DEV_MAP_FLAG_WRITE_COMBINE),
                                    (void **)&pVia->FBBase);
         if (err) {
             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -2346,8 +2475,7 @@
 
     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAUnmapMem\n"));
 
-    /* Disable MMIO. */
-    ViaSeqMask(VGAHWPTR(pScrn), 0x1A, 0x00, 0x60);
+    ViaMMIODisable(pScrn);
 
 #ifdef XSERVER_LIBPCIACCESS
     if (pVia->MapBase)
@@ -2431,75 +2559,65 @@
 {
     vgaHWPtr hwp = VGAHWPTR(pScrn);
     VIAPtr pVia = VIAPTR(pScrn);
+    VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+
     int i, index;
     int SR1A, SR1B, CR67, CR6A;
 
     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIALoadPalette\n"));
 
     if (pScrn->bitsPerPixel != 8) {
-        switch (pVia->Chipset) {
-            case VIA_CLE266:
-            case VIA_KM400:
-                ViaSeqMask(hwp, 0x16, 0x80, 0x80);
-                break;
-            case VIA_P4M900:
-                xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VIALoadPalette: "
-                           "Function not implemented for this chipset.\n");
-                return;
-            default:
-                ViaCrtcMask(hwp, 0x33, 0x80, 0x80);
-                break;
-        }
 
-        ViaSeqMask(hwp, 0x1A, 0x00, 0x01);
-        VIALoadRgbLut(pScrn, numColors, indices, colors, pVisual);
+        if (pBIOSInfo->FirstCRTC->IsActive) {
 
-        /* If secondary is enabled, adjust its palette too. */
-        if (hwp->readCrtc(hwp, 0x6A) & 0x80) {
-            ViaSeqMask(hwp, 0x1A, 0x01, 0x01);
-            ViaCrtcMask(hwp, 0x6A, 0x02, 0x02);
             switch (pVia->Chipset) {
-                case VIA_K8M800:
-                case VIA_PM800:
+                case VIA_CLE266:
+                case VIA_KM400:
+                    ViaSeqMask(hwp, 0x16, 0x80, 0x80);
                     break;
                 default:
-                    ViaSeqMask(hwp, 0x6A, 0x20, 0x20);
+                    ViaCrtcMask(hwp, 0x33, 0x80, 0x80);
                     break;
             }
+
+            ViaSeqMask(hwp, 0x1A, 0x00, 0x01);
             VIALoadRgbLut(pScrn, numColors, indices, colors, pVisual);
         }
 
-        return;
-    }
+        /* If secondary is enabled, adjust its palette too. */
+        if (pBIOSInfo->SecondCRTC->IsActive) {
+            if (!(pVia->Chipset == VIA_CLE266
+                  && CLE266_REV_IS_AX(pVia->ChipRev))) {
+                ViaSeqMask(hwp, 0x1A, 0x01, 0x01);
+                ViaCrtcMask(hwp, 0x6A, 0x02, 0x02);
+                switch (pVia->Chipset) {
+                    case VIA_CLE266:
+                    case VIA_KM400:
+                    case VIA_K8M800:
+                    case VIA_PM800:
+                        break;
+                    default:
+                        ViaCrtcMask(hwp, 0x6A, 0x20, 0x20);
+                        break;
+                }
+                VIALoadRgbLut(pScrn, numColors, indices, colors, pVisual);
+            }
+        }
 
-    SR1A = hwp->readSeq(hwp, 0x1A);
-    SR1B = hwp->readSeq(hwp, 0x1B);
-    CR67 = hwp->readCrtc(hwp, 0x67);
-    CR6A = hwp->readCrtc(hwp, 0x6A);
+    } else {
 
-    if (pVia->IsSecondary) {
-        ViaSeqMask(hwp, 0x1A, 0x01, 0x01);
-        ViaSeqMask(hwp, 0x1B, 0x80, 0x80);
-        ViaCrtcMask(hwp, 0x67, 0x00, 0xC0);
-        ViaCrtcMask(hwp, 0x6A, 0xC0, 0xC0);
-    }
+        SR1A = hwp->readSeq(hwp, 0x1A);
+        SR1B = hwp->readSeq(hwp, 0x1B);
+        CR67 = hwp->readCrtc(hwp, 0x67);
+        CR6A = hwp->readCrtc(hwp, 0x6A);
 
-    for (i = 0; i < numColors; i++) {
-        index = indices[i];
-        hwp->writeDacWriteAddr(hwp, index);
-        hwp->writeDacData(hwp, colors[index].red);
-        hwp->writeDacData(hwp, colors[index].green);
-        hwp->writeDacData(hwp, colors[index].blue);
-    }
+        if (pBIOSInfo->SecondCRTC->IsActive) {
+            ViaSeqMask(hwp, 0x1A, 0x01, 0x01);
+            ViaSeqMask(hwp, 0x1B, 0x80, 0x80);
+            ViaCrtcMask(hwp, 0x67, 0x00, 0xC0);
+            ViaCrtcMask(hwp, 0x6A, 0xC0, 0xC0);
+        }
 
-    if (pVia->IsSecondary) {
-        hwp->writeSeq(hwp, 0x1A, SR1A);
-        hwp->writeSeq(hwp, 0x1B, SR1B);
-        hwp->writeCrtc(hwp, 0x67, CR67);
-        hwp->writeCrtc(hwp, 0x6A, CR6A);
-
-        /* Screen 0 palette was changed by mode setting of Screen 1,
-         * so load it again. */
         for (i = 0; i < numColors; i++) {
             index = indices[i];
             hwp->writeDacWriteAddr(hwp, index);
@@ -2507,6 +2625,23 @@
             hwp->writeDacData(hwp, colors[index].green);
             hwp->writeDacData(hwp, colors[index].blue);
         }
+
+        if (pBIOSInfo->SecondCRTC->IsActive) {
+            hwp->writeSeq(hwp, 0x1A, SR1A);
+            hwp->writeSeq(hwp, 0x1B, SR1B);
+            hwp->writeCrtc(hwp, 0x67, CR67);
+            hwp->writeCrtc(hwp, 0x6A, CR6A);
+
+            /* Screen 0 palette was changed by mode setting of Screen 1,
+             * so load it again. */
+            for (i = 0; i < numColors; i++) {
+                index = indices[i];
+                hwp->writeDacWriteAddr(hwp, index);
+                hwp->writeDacData(hwp, colors[index].red);
+                hwp->writeDacData(hwp, colors[index].green);
+                hwp->writeDacData(hwp, colors[index].blue);
+            }
+        }
     }
 }
 
@@ -2543,6 +2678,7 @@
         }
     } else {
         vgaHWBlankScreen(pScrn, FALSE);
+
         if (!VIAWriteMode(pScrn, pScrn->currentMode)) {
             vgaHWBlankScreen(pScrn, TRUE);
             return FALSE;
@@ -2623,7 +2759,8 @@
     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- SW cursor set up\n"));
 
     if (pVia->hwcursor) {
-        if (!VIAHWCursorInit(pScreen)) {
+        if (!viaHWCursorInit(pScreen)) {
+			pVia->hwcursor = FALSE;
             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                        "Hardware cursor initialization failed\n");
         }
@@ -2787,6 +2924,7 @@
 VIAWriteMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
 {
     VIAPtr pVia = VIAPTR(pScrn);
+    VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
 
     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAWriteMode\n"));
 
@@ -2799,10 +2937,15 @@
         if (!vgaHWInit(pScrn, mode))
             return FALSE;
 
-        if (!pVia->IsSecondary)
-            ViaModePrimary(pScrn, mode);
-        else
-            ViaModeSecondary(pScrn, mode);
+        if (pVia->UseLegacyModeSwitch) {
+            if (!pVia->IsSecondary)
+                ViaModePrimaryLegacy(pScrn, mode);
+            else
+                ViaModeSecondaryLegacy(pScrn, mode);
+        } else {
+            ViaCRTCInit(pScrn);
+            ViaModeSet(pScrn, mode);
+        }
 
     } else {
 
@@ -2813,22 +2956,19 @@
          * to detect when the display is using the secondary head.
          * TODO: This should be enabled for other chipsets as well.
          */
-        if (pVia->Chipset == VIA_P4M900 && pVia->pBIOSInfo->PanelActive) {
+        if ((pVia->Chipset == VIA_P4M900 || pVia->Chipset == VIA_VX800) && pVia->pBIOSInfo->Panel->IsActive) {
             /*
              * Since we are using virtual, we need to adjust
              * the offset to match the framebuffer alignment.
              */
-            if (pScrn->displayWidth != mode->HDisplay)
-                ViaModeSecondaryVGAOffset(pScrn);
-            // ViaModeSecondaryVGAFixAlignment(pScrn, mode);
+            if (pScrn->displayWidth != mode->CrtcHDisplay)
+                ViaSecondCRTCHorizontalOffset(pScrn);
         }
     }
 
     /* Enable the graphics engine. */
     if (!pVia->NoAccel) {
-#if defined(XF86DRI) || defined(VIA_HAVE_EXA)
         VIAInitialize3DEngine(pScrn);
-#endif
         viaInitialize2DEngine(pScrn);
     }
 
@@ -2856,14 +2996,15 @@
         viaAccelSync(pScrn);
 
         /* A soft reset avoids a 3D hang after X restart. */
-        if (pVia->Chipset != VIA_K8M890 && pVia->Chipset != VIA_P4M900)
+        if (pVia->Chipset != VIA_K8M890 && pVia->Chipset != VIA_P4M900 &&
+            pVia->Chipset != VIA_VX800)
             hwp->writeSeq(hwp, 0x1A, pVia->SavedReg.SR1A | 0x40);
 
         if (!pVia->IsSecondary) {
             /* Turn off all video activities. */
             viaExitVideo(pScrn);
-
-            VIAHideCursor(pScrn);
+            if (pVia->hwcursor)
+                viaHideCursor(pScrn);
         }
 
         if (pVia->VQEnable)
@@ -2875,10 +3016,6 @@
 #endif
 
     viaExitAccel(pScreen);
-    if (pVia->CursorInfoRec) {
-        xf86DestroyCursorInfoRec(pVia->CursorInfoRec);
-        pVia->CursorInfoRec = NULL;
-    }
     if (pVia->ShadowPtr) {
         xfree(pVia->ShadowPtr);
         pVia->ShadowPtr = NULL;
@@ -2936,24 +3073,17 @@
     if (pVia->pVbe) {
         ViaVbeAdjustFrame(scrnIndex, x, y, flags);
     } else {
+        if (pVia->UseLegacyModeSwitch) {
+            if (!pVia->IsSecondary)
+                ViaFirstCRTCSetStartingAddress(pScrn, x, y);
+            else
+                ViaSecondCRTCSetStartingAddress(pScrn, x, y);
+        } else {
+            if (pVia->pBIOSInfo->FirstCRTC->IsActive)
+                ViaFirstCRTCSetStartingAddress(pScrn, x, y);
 
-        Base = (y * pScrn->displayWidth + x) * (pScrn->bitsPerPixel / 8);
-
-        /* Now program the start address registers. */
-        if (pVia->IsSecondary) {
-            Base = (Base + pScrn->fbOffset) >> 3;
-            ViaCrtcMask(hwp, 0x62, (Base & 0x7F) << 1, 0xFE);
-            hwp->writeCrtc(hwp, 0x63, (Base & 0x7F80) >> 7);
-            hwp->writeCrtc(hwp, 0x64, (Base & 0x7F8000) >> 15);
-        } else {
-            Base = Base >> 1;
-            hwp->writeCrtc(hwp, 0x0C, (Base & 0xFF00) >> 8);
-            hwp->writeCrtc(hwp, 0x0D, Base & 0xFF);
-            hwp->writeCrtc(hwp, 0x34, (Base & 0xFF0000) >> 16);
-#if 0
-            /* The CLE266A doesn't have this implemented, it seems. -- Luc */
-            ViaCrtcMask(hwp, 0x48, Base >> 24, 0x03);
-#endif
+            if (pVia->pBIOSInfo->SecondCRTC->IsActive)
+                ViaSecondCRTCSetStartingAddress(pScrn, x, y);
         }
     }
 
@@ -3003,52 +3133,65 @@
     vgaHWPtr hwp = VGAHWPTR(pScrn);
     VIAPtr pVia = VIAPTR(pScrn);
     VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
-    CARD8 val;
 
     if (pVia->pVbe) {
         ViaVbeDPMS(pScrn, mode, flags);
-        return;
-    }
+    } else {
 
-    /* Clear DPMS setting. */
-    val = hwp->readCrtc(hwp, 0x36);
-    val &= 0xCF;
+        switch (mode) {
+            case DPMSModeOn:
 
-    /* Turn CRT off, if user doesn't want it on. */
-    if (!pVia->IsSecondary && !pBIOSInfo->CrtActive)
-        val |= 0x30;
+                if (pBIOSInfo->Lvds->IsActive)
+                    ViaLVDSPower(pScrn, TRUE);
 
-    switch (mode) {
-        case DPMSModeOn:
-            if (pBIOSInfo->PanelActive)
-                ViaLCDPower(pScrn, TRUE);
+                if (pBIOSInfo->CrtActive)
+                    ViaDisplayEnableCRT(pScrn);
 
-            if (pBIOSInfo->TVActive)
-                ViaTVPower(pScrn, TRUE);
+                if (pBIOSInfo->Panel->IsActive)
+                    ViaLCDPower(pScrn, TRUE);
 
-            hwp->writeCrtc(hwp, 0x36, val);
-            break;
-        case DPMSModeStandby:
-        case DPMSModeSuspend:
-        case DPMSModeOff:
-            if (pBIOSInfo->PanelActive)
-                ViaLCDPower(pScrn, FALSE);
+                if (pBIOSInfo->TVActive)
+                    ViaTVPower(pScrn, TRUE);
 
-            if (pBIOSInfo->TVActive)
-                ViaTVPower(pScrn, FALSE);
+                if (pBIOSInfo->DfpActive)
+                    ViaDFPPower(pScrn, TRUE);
 
-            val |= 0x30;
-            hwp->writeCrtc(hwp, 0x36, val);
-            break;
-        default:
-            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                       "Invalid DPMS mode %d\n", mode);
-            break;
+                if (pBIOSInfo->Simultaneous->IsActive)
+                    ViaDisplayEnableSimultaneous(pScrn);
+
+                break;
+            case DPMSModeStandby:
+            case DPMSModeSuspend:
+            case DPMSModeOff:
+
+                if (pBIOSInfo->Lvds->IsActive)
+                    ViaLVDSPower(pScrn, FALSE);
+
+                if (pBIOSInfo->CrtActive)
+                    ViaDisplayDisableCRT(pScrn);
+
+                if (pBIOSInfo->Panel->IsActive)
+                    ViaLCDPower(pScrn, FALSE);
+
+                if (pBIOSInfo->TVActive)
+                    ViaTVPower(pScrn, FALSE);
+
+                if (pBIOSInfo->DfpActive)
+                    ViaDFPPower(pScrn, FALSE);
+                
+                if (pBIOSInfo->Simultaneous->IsActive)
+                    ViaDisplayDisableSimultaneous(pScrn);
+
+                break;
+            default:
+                xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid DPMS mode %d\n",
+                           mode);
+                break;
+        }
     }
-    return;
+
 }
 
-#if defined(XF86DRI) || defined(VIA_HAVE_EXA)
 void
 VIAInitialize3DEngine(ScrnInfoPtr pScrn)
 {
@@ -3111,4 +3254,3 @@
     VIASETREG(VIA_REG_TRANSPACE, 0x11000000);
     VIASETREG(VIA_REG_TRANSPACE, 0x20000000);
 }
-#endif
Index: src/via_crtc.c
===================================================================
--- src/via_crtc.c	(.../tags/release_0_2_903)	(revision 0)
+++ src/via_crtc.c	(.../trunk)	(revision 751)
@@ -0,0 +1,659 @@
+/*
+ * Copyright 2005-2007 The Openchrome Project [openchrome.org]
+ * Copyright 2004-2005 The Unichrome Project  [unichrome.sf.net]
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "via.h"
+#include "via_driver.h"
+#include "via_vgahw.h"
+#include "via_id.h"
+
+#include "via_mode.h"
+
+#include <xorg/xf86Crtc.h>
+
+static void
+ViaCRTCSetGraphicsRegisters(ScrnInfoPtr pScrn)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+    /* graphics registers */
+    hwp->writeGr(hwp, 0x00, 0x00);
+    hwp->writeGr(hwp, 0x01, 0x00);
+    hwp->writeGr(hwp, 0x02, 0x00);
+    hwp->writeGr(hwp, 0x03, 0x00);
+    hwp->writeGr(hwp, 0x04, 0x00);
+    hwp->writeGr(hwp, 0x05, 0x40);
+    hwp->writeGr(hwp, 0x06, 0x05);
+    hwp->writeGr(hwp, 0x07, 0x0F);
+    hwp->writeGr(hwp, 0x08, 0xFF);
+
+    ViaGrMask(hwp, 0x20, 0, 0xFF);
+    ViaGrMask(hwp, 0x21, 0, 0xFF);
+    ViaGrMask(hwp, 0x22, 0, 0xFF);
+}
+
+static void
+ViaCRTCSetAttributeRegisters(ScrnInfoPtr pScrn)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+    CARD8 i;
+
+    /* attribute registers */
+    for (i = 0; i <= 0xF; i++) {
+        hwp->writeAttr(hwp, i, i);
+    }
+    hwp->writeAttr(hwp, 0x10, 0x41);
+    hwp->writeAttr(hwp, 0x11, 0xFF);
+    hwp->writeAttr(hwp, 0x12, 0x0F);
+    hwp->writeAttr(hwp, 0x13, 0x00);
+    hwp->writeAttr(hwp, 0x14, 0x00);
+}
+
+static Bool
+via_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
+{
+    scrn->virtualX = width;
+    scrn->virtualY = height;
+    return TRUE;
+}
+
+static const
+xf86CrtcConfigFuncsRec via_xf86crtc_config_funcs = {
+    via_xf86crtc_resize
+};
+
+void 
+ViaPreInitCRTCConfig(ScrnInfoPtr pScrn)
+{
+     xf86CrtcConfigInit (pScrn, &via_xf86crtc_config_funcs);
+}
+
+
+void
+ViaCRTCInit(ScrnInfoPtr pScrn)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+    hwp->writeSeq(hwp, 0x10, 0x01); /* unlock extended registers */
+    ViaCrtcMask(hwp, 0x47, 0x00, 0x01); /* unlock CRT registers */
+    ViaCRTCSetGraphicsRegisters(pScrn);
+    ViaCRTCSetAttributeRegisters(pScrn);
+}
+
+void
+ViaFirstCRTCSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+    VIAPtr pVia = VIAPTR(pScrn);
+    CARD16 temp;
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaFirstCRTCSetMode\n"));
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting up %s\n", mode->name));
+
+    ViaCrtcMask(hwp, 0x11, 0x00, 0x80); /* modify starting address */
+    ViaCrtcMask(hwp, 0x03, 0x80, 0x80); /* enable vertical retrace access */
+
+    /* Set Misc Register */
+    temp = 0x23;
+    if (mode->Flags & V_NHSYNC)
+        temp |= 0x40;
+    if (mode->Flags & V_NVSYNC)
+        temp |= 0x80;
+    temp |= 0x0C; /* Undefined/external clock */
+    hwp->writeMiscOut(hwp, temp);
+
+    /* Sequence registers */
+    hwp->writeSeq(hwp, 0x00, 0x00);
+
+#if 0
+    if (mode->Flags & V_CLKDIV2)
+        hwp->writeSeq(hwp, 0x01, 0x09);
+    else
+#endif
+        hwp->writeSeq(hwp, 0x01, 0x01);
+
+    hwp->writeSeq(hwp, 0x02, 0x0F);
+    hwp->writeSeq(hwp, 0x03, 0x00);
+    hwp->writeSeq(hwp, 0x04, 0x0E);
+
+    ViaSeqMask(hwp, 0x15, 0x02, 0x02);
+
+    /* bpp */
+    switch (pScrn->bitsPerPixel) {
+        case 8:
+            /* Only CLE266.AX use 6bits LUT. */
+            if (pVia->Chipset == VIA_CLE266 && pVia->ChipRev < 15)
+                ViaSeqMask(hwp, 0x15, 0x22, 0xFE);
+            else
+                ViaSeqMask(hwp, 0x15, 0xA2, 0xFE);
+
+            break;
+        case 16:
+            ViaSeqMask(hwp, 0x15, 0xB6, 0xFE);
+            break;
+        case 24:
+        case 32:
+            ViaSeqMask(hwp, 0x15, 0xAE, 0xFE);
+            break;
+        default:
+            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unhandled bitdepth: %d\n",
+                       pScrn->bitsPerPixel);
+            break;
+    }
+
+    switch (pVia->ChipId) {
+        case VIA_K8M890:
+        case VIA_CX700:
+        case VIA_P4M900:
+	case VIA_VX800:
+            break;
+        default:
+            ViaSeqMask(hwp, 0x16, 0x08, 0xBF);
+            ViaSeqMask(hwp, 0x17, 0x1F, 0xFF);
+            ViaSeqMask(hwp, 0x18, 0x4E, 0xFF);
+            ViaSeqMask(hwp, 0x1A, 0x08, 0xFD);
+            break;
+    }
+
+    /* Crtc registers */
+    /* horizontal total : 4100 */
+    temp = (mode->CrtcHTotal >> 3) - 5;
+    hwp->writeCrtc(hwp, 0x00, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x36, temp >> 5, 0x08);
+
+    /* horizontal address : 2048 */
+    temp = (mode->CrtcHDisplay >> 3) - 1;
+    hwp->writeCrtc(hwp, 0x01, temp & 0xFF);
+
+    /* horizontal blanking start : 2048 */
+    /* temp = (mode->CrtcHDisplay >> 3) - 1; */
+    temp = (mode->CrtcHBlankStart >> 3) - 1;
+    hwp->writeCrtc(hwp, 0x02, temp & 0xFF);
+    /* If HblankStart has more bits anywhere, add them here */
+
+    /* horizontal blanking end : start + 1025 */
+    /* temp = (mode->CrtcHTotal >> 3) - 1; */
+    temp = (mode->CrtcHBlankEnd >> 3) - 1;
+    ViaCrtcMask(hwp, 0x03, temp, 0x1F);
+    ViaCrtcMask(hwp, 0x05, temp << 2, 0x80);
+    ViaCrtcMask(hwp, 0x33, temp >> 1, 0x20);
+
+    /* CrtcHSkew ??? */
+
+    /* horizontal sync start : 4095 */
+    temp = mode->CrtcHSyncStart >> 3;
+    hwp->writeCrtc(hwp, 0x04, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x33, temp >> 4, 0x10);
+
+    /* horizontal sync end : start + 256 */
+    temp = mode->CrtcHSyncEnd >> 3;
+    ViaCrtcMask(hwp, 0x05, temp, 0x1F);
+
+    /* vertical total : 2049 */
+    temp = mode->CrtcVTotal - 2;
+    hwp->writeCrtc(hwp, 0x06, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x07, temp >> 8, 0x01);
+    ViaCrtcMask(hwp, 0x07, temp >> 4, 0x20);
+    ViaCrtcMask(hwp, 0x35, temp >> 10, 0x01);
+
+    /* vertical address : 2048 */
+    temp = mode->CrtcVDisplay - 1;
+    hwp->writeCrtc(hwp, 0x12, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x07, temp >> 7, 0x02);
+    ViaCrtcMask(hwp, 0x07, temp >> 3, 0x40);
+    ViaCrtcMask(hwp, 0x35, temp >> 8, 0x04);
+
+    /* Primary starting address -> 0x00, adjustframe does the rest */
+    hwp->writeCrtc(hwp, 0x0C, 0x00);
+    hwp->writeCrtc(hwp, 0x0D, 0x00);
+    hwp->writeCrtc(hwp, 0x34, 0x00);
+    ViaCrtcMask(hwp, 0x48, 0x00, 0x03); /* is this even possible on CLE266A ? */
+
+    /* vertical sync start : 2047 */
+    temp = mode->CrtcVSyncStart;
+    hwp->writeCrtc(hwp, 0x10, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x07, temp >> 6, 0x04);
+    ViaCrtcMask(hwp, 0x07, temp >> 2, 0x80);
+    ViaCrtcMask(hwp, 0x35, temp >> 9, 0x02);
+
+    /* vertical sync end : start + 16 -- other bits someplace? */
+    ViaCrtcMask(hwp, 0x11, mode->CrtcVSyncEnd, 0x0F);
+
+    /* line compare: We are not doing splitscreen so 0x3FFF */
+    hwp->writeCrtc(hwp, 0x18, 0xFF);
+    ViaCrtcMask(hwp, 0x07, 0x10, 0x10);
+    ViaCrtcMask(hwp, 0x09, 0x40, 0x40);
+    ViaCrtcMask(hwp, 0x33, 0x07, 0x06);
+    ViaCrtcMask(hwp, 0x35, 0x10, 0x10);
+
+    /* zero Maximum scan line */
+    ViaCrtcMask(hwp, 0x09, 0x00, 0x1F);
+    hwp->writeCrtc(hwp, 0x14, 0x00);
+
+    /* vertical blanking start : 2048 */
+    /* temp = mode->CrtcVDisplay - 1; */
+    temp = mode->CrtcVBlankStart - 1;
+    hwp->writeCrtc(hwp, 0x15, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x07, temp >> 5, 0x08);
+    ViaCrtcMask(hwp, 0x09, temp >> 4, 0x20);
+    ViaCrtcMask(hwp, 0x35, temp >> 7, 0x08);
+
+    /* vertical blanking end : start + 257 */
+    /* temp = mode->CrtcVTotal - 1; */
+    temp = mode->CrtcVBlankEnd - 1;
+    hwp->writeCrtc(hwp, 0x16, temp);
+
+    /* FIXME: check if this is really necessary here */
+    switch (pVia->ChipId) {
+        case VIA_K8M890:
+        case VIA_CX700:
+        case VIA_P4M900:
+	case VIA_VX800:
+            break;
+        default:
+            /* some leftovers */
+            hwp->writeCrtc(hwp, 0x08, 0x00);
+            ViaCrtcMask(hwp, 0x32, 0, 0xFF);  /* ? */
+            ViaCrtcMask(hwp, 0x33, 0, 0xC8);
+            break;
+    }
+
+    /* offset */
+    temp = (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)) >> 3;
+    /* Make sure that this is 32-byte aligned. */
+    if (temp & 0x03) {
+        temp += 0x03;
+        temp &= ~0x03;
+    }
+    hwp->writeCrtc(hwp, 0x13, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x35, temp >> 3, 0xE0);
+
+    /* fetch count */
+    temp = (mode->CrtcHDisplay * (pScrn->bitsPerPixel >> 3)) >> 3;
+    /* Make sure that this is 32-byte aligned. */
+    if (temp & 0x03) {
+        temp += 0x03;
+        temp &= ~0x03;
+    }
+    hwp->writeSeq(hwp, 0x1C, (temp >> 1) & 0xFF);
+    ViaSeqMask(hwp, 0x1D, temp >> 9, 0x03);
+
+    switch (pVia->ChipId) {
+        case VIA_K8M890:
+        case VIA_CX700:
+        case VIA_P4M900:
+	case VIA_VX800:
+            break;
+        default:
+            /* some leftovers */
+            ViaCrtcMask(hwp, 0x32, 0, 0xFF);
+            ViaCrtcMask(hwp, 0x33, 0, 0xC8);
+            break;
+    }
+}
+
+void
+ViaFirstCRTCSetStartingAddress(ScrnInfoPtr pScrn, int x, int y)
+{
+    VIAPtr pVia = VIAPTR(pScrn);
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+    CARD32 Base;
+    CARD32 tmp;
+
+    Base = (y * pScrn->displayWidth + x) * (pScrn->bitsPerPixel / 8);
+    Base = Base >> 1;
+
+    hwp->writeCrtc(hwp, 0x0C, (Base & 0xFF00) >> 8);
+    hwp->writeCrtc(hwp, 0x0D, Base & 0xFF);
+    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
+ViaSecondCRTCSetStartingAddress(ScrnInfoPtr pScrn, int x, int y)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+    CARD32 Base;
+    CARD32 tmp;
+
+    Base = (y * pScrn->displayWidth + x) * (pScrn->bitsPerPixel / 8);
+    Base = (Base + pScrn->fbOffset) >> 3;
+
+    tmp = hwp->readCrtc(hwp, 0x62) & 0x01;
+    tmp |= (Base & 0x7F) << 1;
+    hwp->writeCrtc(hwp, 0x62, tmp);
+
+    hwp->writeCrtc(hwp, 0x63, (Base & 0x7F80) >> 7);
+    hwp->writeCrtc(hwp, 0x64, (Base & 0x7F8000) >> 15);
+    hwp->writeCrtc(hwp, 0xA3, (Base & 0x03800000) >> 23);
+}
+
+void
+ViaSecondCRTCHorizontalQWCount(ScrnInfoPtr pScrn, int width)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+    CARD16 temp;
+
+    /* fetch count */
+    temp = (width * (pScrn->bitsPerPixel >> 3)) >> 3;
+    /* Make sure that this is 32-byte aligned. */
+    if (temp & 0x03) {
+        temp += 0x03;
+        temp &= ~0x03;
+    }
+    hwp->writeCrtc(hwp, 0x65, (temp >> 1) & 0xFF);
+    ViaCrtcMask(hwp, 0x67, temp >> 7, 0x0C);
+}
+
+void
+ViaSecondCRTCHorizontalOffset(ScrnInfoPtr pScrn)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+    CARD16 temp;
+
+    /* offset */
+    temp = (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)) >> 3;
+    /* Make sure that this is 32-byte aligned. */
+    if (temp & 0x03) {
+        temp += 0x03;
+        temp &= ~0x03;
+	}
+    
+    hwp->writeCrtc(hwp, 0x66, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x67, temp >> 8, 0x03);
+}
+
+void
+ViaSecondCRTCSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+    VIAPtr pVia = VIAPTR(pScrn);
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+    CARD16 temp;
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "mode: %p\n", mode);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "mode->name: %p\n", mode->name);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "mode->name: %s\n", mode->name);
+
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSecondCRTCSetMode\n"));
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting up %s\n", mode->name));
+    /* bpp */
+    switch (pScrn->bitsPerPixel) {
+        case 8:
+            ViaCrtcMask(hwp, 0x67, 0x00, 0xC0);
+            break;
+        case 16:
+            ViaCrtcMask(hwp, 0x67, 0x40, 0xC0);
+            break;
+        case 24:
+        case 32:
+            ViaCrtcMask(hwp, 0x67, 0xC0, 0xC0);
+            break;
+        default:
+            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unhandled bitdepth: %d\n",
+                       pScrn->bitsPerPixel);
+            break;
+    }
+
+    switch (pVia->ChipId) {
+        case VIA_K8M890:
+        case VIA_CX700:
+        case VIA_P4M900:
+	case VIA_VX800:
+            break;
+        default:
+            ViaSeqMask(hwp, 0x16, 0x08, 0xBF);
+            ViaSeqMask(hwp, 0x17, 0x1F, 0xFF);
+            ViaSeqMask(hwp, 0x18, 0x4E, 0xFF);
+            ViaSeqMask(hwp, 0x1A, 0x08, 0xFD);
+            break;
+    }
+
+    /* Crtc registers */
+    /* horizontal total : 4096 */
+    temp = mode->CrtcHTotal - 1;
+    hwp->writeCrtc(hwp, 0x50, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x55, temp >> 8, 0x0F);
+
+    /* horizontal address : 2048 */
+    temp = mode->CrtcHDisplay - 1;
+    hwp->writeCrtc(hwp, 0x51, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x55, temp >> 4, 0x70);
+
+    /* horizontal blanking start : 2048 */
+    /* temp = mode->CrtcHDisplay - 1; */
+    temp = mode->CrtcHBlankStart - 1;
+    hwp->writeCrtc(hwp, 0x52, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x54, temp >> 8, 0x07);
+
+    /* horizontal blanking end : 4096 */
+    /* temp = mode->CrtcHTotal - 1; */
+    temp = mode->CrtcHBlankEnd - 1;
+    hwp->writeCrtc(hwp, 0x53, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x54, temp >> 5, 0x38);
+    ViaCrtcMask(hwp, 0x5D, temp >> 5, 0x40);
+
+    /* horizontal sync start : 2047 */
+    temp = mode->CrtcHSyncStart;
+    hwp->writeCrtc(hwp, 0x56, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x54, temp >> 2, 0xC0);
+    ViaCrtcMask(hwp, 0x5C, temp >> 3, 0x80);
+
+    if (pVia->ChipId != VIA_CLE266 && pVia->ChipId != VIA_KM400)
+        ViaCrtcMask(hwp, 0x5D, temp >> 4, 0x80);
+
+    /* horizontal sync end : sync start + 512 */
+    temp = mode->CrtcHSyncEnd;
+    hwp->writeCrtc(hwp, 0x57, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x5C, temp >> 2, 0x40);
+
+    /* vertical total : 2048 */
+    temp = mode->CrtcVTotal - 1;
+    hwp->writeCrtc(hwp, 0x58, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x5D, temp >> 8, 0x07);
+
+    /* vertical address : 2048 */
+    temp = mode->CrtcVDisplay - 1;
+    hwp->writeCrtc(hwp, 0x59, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x5D, temp >> 5, 0x38);
+
+    /* vertical blanking start : 2048 */
+    /* temp = mode->CrtcVDisplay - 1; */
+    temp = mode->CrtcVBlankStart - 1;
+    hwp->writeCrtc(hwp, 0x5A, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x5C, temp >> 8, 0x07);
+
+    /* vertical blanking end : 2048 */
+    /* temp = mode->CrtcVTotal - 1; */
+    temp = mode->CrtcVBlankEnd - 1;
+    hwp->writeCrtc(hwp, 0x5B, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x5C, temp >> 5, 0x38);
+
+    /* vertical sync start : 2047 */
+    temp = mode->CrtcVSyncStart;
+    hwp->writeCrtc(hwp, 0x5E, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x5F, temp >> 3, 0xE0);
+
+    /* vertical sync end : start + 32 */
+    temp = mode->CrtcVSyncEnd;
+    ViaCrtcMask(hwp, 0x5F, temp, 0x1F);
+
+    switch (pVia->ChipId) {
+        case VIA_K8M890:
+        case VIA_CX700:
+        case VIA_P4M900:
+	case VIA_VX800:
+            break;
+        default:
+            /* some leftovers */
+            hwp->writeCrtc(hwp, 0x08, 0x00);
+            ViaCrtcMask(hwp, 0x32, 0, 0xFF);  /* ? */
+            ViaCrtcMask(hwp, 0x33, 0, 0xC8);
+            break;
+    }
+
+    ViaSecondCRTCHorizontalOffset(pScrn);
+    ViaSecondCRTCHorizontalQWCount(pScrn, mode->CrtcHDisplay);
+
+}
+
+/*
+ * Checks for limitations imposed by the available VGA timing registers.
+ */
+ModeStatus
+ViaFirstCRTCModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaFirstCRTCModeValid\n"));
+
+    if (mode->CrtcHTotal > 4100)
+        return MODE_BAD_HVALUE;
+
+    if (mode->CrtcHDisplay > 2048)
+        return MODE_BAD_HVALUE;
+
+    if (mode->CrtcHBlankStart > 2048)
+        return MODE_BAD_HVALUE;
+
+    if ((mode->CrtcHBlankEnd - mode->CrtcHBlankStart) > 1025)
+        return MODE_HBLANK_WIDE;
+
+    if (mode->CrtcHSyncStart > 4095)
+        return MODE_BAD_HVALUE;
+
+    if ((mode->CrtcHSyncEnd - mode->CrtcHSyncStart) > 256)
+        return MODE_HSYNC_WIDE;
+
+    if (mode->CrtcVTotal > 2049)
+        return MODE_BAD_VVALUE;
+
+    if (mode->CrtcVDisplay > 2048)
+        return MODE_BAD_VVALUE;
+
+    if (mode->CrtcVSyncStart > 2047)
+        return MODE_BAD_VVALUE;
+
+    if ((mode->CrtcVSyncEnd - mode->CrtcVSyncStart) > 16)
+        return MODE_VSYNC_WIDE;
+
+    if (mode->CrtcVBlankStart > 2048)
+        return MODE_BAD_VVALUE;
+
+    if ((mode->CrtcVBlankEnd - mode->CrtcVBlankStart) > 257)
+        return MODE_VBLANK_WIDE;
+
+    return MODE_OK;
+}
+
+ModeStatus
+ViaSecondCRTCModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSecondCRTCModeValid\n"));
+
+    if (mode->CrtcHTotal > 4096)
+        return MODE_BAD_HVALUE;
+
+    if (mode->CrtcHDisplay > 2048)
+        return MODE_BAD_HVALUE;
+
+    if (mode->CrtcHBlankStart > 2048)
+        return MODE_BAD_HVALUE;
+
+    if (mode->CrtcHBlankEnd > 4096)
+        return MODE_HBLANK_WIDE;
+
+    if (mode->CrtcHSyncStart > 2047)
+        return MODE_BAD_HVALUE;
+
+    if ((mode->CrtcHSyncEnd - mode->CrtcHSyncStart) > 512)
+        return MODE_HSYNC_WIDE;
+
+    if (mode->CrtcVTotal > 2048)
+        return MODE_BAD_VVALUE;
+
+    if (mode->CrtcVDisplay > 2048)
+        return MODE_BAD_VVALUE;
+
+    if (mode->CrtcVBlankStart > 2048)
+        return MODE_BAD_VVALUE;
+
+    if (mode->CrtcVBlankEnd > 2048)
+        return MODE_VBLANK_WIDE;
+
+    if (mode->CrtcVSyncStart > 2047)
+        return MODE_BAD_VVALUE;
+
+    if ((mode->CrtcVSyncEnd - mode->CrtcVSyncStart) > 32)
+        return MODE_VSYNC_WIDE;
+
+    return MODE_OK;
+}
+
+/*
+ * Not tested yet
+ */
+void
+ViaShadowCRTCSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaShadowCRTCSetMode\n"));
+
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+    CARD16 temp;
+
+    temp = (mode->CrtcHTotal >> 3) - 5;
+    hwp->writeCrtc(hwp, 0x6D, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x71, temp >> 5, 0x08);
+
+    temp = (mode->CrtcHBlankEnd >> 3) - 1;
+    hwp->writeCrtc(hwp, 0x6E, temp & 0xFF);
+
+    temp = mode->CrtcVTotal - 2;
+    hwp->writeCrtc(hwp, 0x6F, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x71, temp >> 8, 0x07);
+
+    temp = mode->CrtcVDisplay - 1;
+    hwp->writeCrtc(hwp, 0x70, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x71, temp >> 4, 0x70);
+
+    temp = mode->CrtcVBlankStart - 1;
+    hwp->writeCrtc(hwp, 0x72, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x74, temp >> 4, 0x70);
+
+    temp = mode->CrtcVTotal - 1;
+    hwp->writeCrtc(hwp, 0x73, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x74, temp >> 8, 0x07);
+
+    ViaCrtcMask(hwp, 0x76, mode->CrtcVSyncEnd, 0x0F);
+
+    temp = mode->CrtcVSyncStart;
+    hwp->writeCrtc(hwp, 0x75, temp & 0xFF);
+    ViaCrtcMask(hwp, 0x76, temp >> 4, 0x70);
+}
Index: src/via_swov.c
===================================================================
--- src/via_swov.c	(.../tags/release_0_2_903)	(revision 751)
+++ src/via_swov.c	(.../trunk)	(revision 751)
@@ -95,7 +95,8 @@
     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 | HQV_SW_FLIP)) ;
+	while (*pdwState & HQV_SUBPIC_FLIP);
     } else {
         while (!(*pdwState & HQV_FLIP_STATUS)) ;
     }
@@ -280,6 +281,14 @@
             HWDiff->dwHQVDisablePatch = VID_HWDIFF_FALSE;
             HWDiff->dwNeedV1Prefetch = VID_HWDIFF_FALSE;
             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;
+            break;
         default:
             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                        "VIAVidHWDiffInit: Unhandled ChipSet.\n");
@@ -774,6 +783,7 @@
         case PCI_CHIP_VT3364:
         case PCI_CHIP_VT3324:
         case PCI_CHIP_VT3327:
+        case PCI_CHIP_VT3353:
             model = 0;
             break;
         case PCI_CHIP_CLE3122:
@@ -911,6 +921,7 @@
         case PCI_CHIP_VT3336:
         case PCI_CHIP_VT3324:
         case PCI_CHIP_VT3364:
+        case PCI_CHIP_VT3353:
         case PCI_CHIP_CLE3122:
             VIDOutD(V1_ColorSpaceReg_2, col2);
             VIDOutD(V1_ColorSpaceReg_1, col1);
@@ -939,6 +950,7 @@
         case PCI_CHIP_VT3336:
         case PCI_CHIP_VT3324:
         case PCI_CHIP_VT3364:
+        case PCI_CHIP_VT3353:
             return (VIDEO_HQV_INUSE | SW_USE_HQV | VIDEO_1_INUSE
                     | VIDEO_ACTIVE | VIDEO_SHOW);
         case PCI_CHIP_CLE3122:
@@ -976,6 +988,7 @@
             case PCI_CHIP_VT3336:
             case PCI_CHIP_VT3324:
             case PCI_CHIP_VT3364:
+            case PCI_CHIP_VT3353:
                 return V3_ENABLE | VIDEO_EXPIRE_NUM_VT3336;
             case PCI_CHIP_CLE3122:
                 if (CLE266_REV_IS_CX(pVia->ChipRev))
@@ -1258,7 +1271,8 @@
 {
     if ((pVia->ChipId == PCI_CHIP_VT3314)
         || (pVia->ChipId == PCI_CHIP_VT3324)
-        || (pVia->ChipId == PCI_CHIP_VT3327)) {
+        || (pVia->ChipId == PCI_CHIP_VT3327
+	|| (pVia->ChipId == PCI_CHIP_VT3353))) {
         SaveVideoRegister(pVia, ALPHA_V3_FIFO_CONTROL,
                           (VIDInD(ALPHA_V3_FIFO_CONTROL) & ALPHA_FIFO_MASK)
                           | ((depth - 1) & 0xff) | ((threshold & 0xff) << 8));
@@ -1320,6 +1334,7 @@
         case PCI_CHIP_VT3336:
         case PCI_CHIP_VT3324:
         case PCI_CHIP_VT3364:
+        case PCI_CHIP_VT3353:
             SetFIFO_V3(pVia, 225, 200, 250);
             break;
         case PCI_CHIP_VT3204:
@@ -1351,6 +1366,7 @@
         case PCI_CHIP_VT3336:
         case PCI_CHIP_VT3324:
         case PCI_CHIP_VT3364:
+        case PCI_CHIP_VT3353:
             SetFIFO_V3(pVia, 225, 200, 250);
             break;
         case PCI_CHIP_VT3204:
@@ -1674,6 +1690,7 @@
           unsigned long chromaKeyLow, unsigned long chromaKeyHigh)
 {
     VIAPtr pVia = VIAPTR(pScrn);
+    VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
     vgaHWPtr hwp = VGAHWPTR(pScrn);
     VIAHWDiff *hwDiff = &pVia->HWDiff;
 
@@ -1707,8 +1724,15 @@
                   pUpdate->DstLeft, pUpdate->DstRight,
                   pUpdate->DstTop, pUpdate->DstBottom));
 
-    pVia->swov.overlayRecordV1.dwWidth = dstWidth =
-            pUpdate->DstRight - pUpdate->DstLeft;
+    dstWidth = pUpdate->DstRight - pUpdate->DstLeft;
+    if (pBIOSInfo->Panel->IsActive && pBIOSInfo->Panel->Scale) {
+        /* FIXME: We need to determine if the panel is using V1 or V3 */
+        float hfactor = (float)pBIOSInfo->Panel->NativeMode->Width
+                        / pScrn->currentMode->HDisplay;
+        dstWidth *= hfactor;
+    }
+
+    pVia->swov.overlayRecordV1.dwWidth = dstWidth;
     pVia->swov.overlayRecordV1.dwHeight = dstHeight =
             pUpdate->DstBottom - pUpdate->DstTop;
     srcWidth = (unsigned long)pUpdate->SrcRight - pUpdate->SrcLeft;
@@ -1729,7 +1753,8 @@
      */
     if ((pVia->VideoEngine == VIDEO_ENGINE_CME
          || pVia->Chipset == VIA_VM800)
-        && pVia->pBIOSInfo->PanelActive) {
+        && pVia->pBIOSInfo->Panel->IsActive) {
+
         /* V1_ON_SND_DISPLAY */
         vidCtl |= 0x80000000;
         /* SECOND_DISPLAY_COLOR_KEY_ENABLE */
@@ -1983,6 +2008,15 @@
         compose = SetChromaKey(pVia, videoFlag, chromaKeyLow, chromaKeyHigh,
                                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));
+        if (pVia->Chipset == VIA_VX800) {
+            VIDOutD(HQV_SRC_DATA_OFFSET_CONTROL2,0);
+            VIDOutD(HQV_SRC_DATA_OFFSET_CONTROL4,((pUpdate->SrcRight - 1 ) << 16) | (pUpdate->SrcBottom - 1));
+        }
+    }
+
     /* Set up video control */
     if (videoFlag & VIDEO_HQV_INUSE) {
 
Index: src/via_driver.h
===================================================================
--- src/via_driver.h	(.../tags/release_0_2_903)	(revision 751)
+++ src/via_driver.h	(.../trunk)	(revision 751)
@@ -65,6 +65,7 @@
 #include "via_swov.h"
 #include "via_dmabuffer.h"
 #include "via_3d.h"
+#include "via_video.h"
 
 #ifdef XSERVER_LIBPCIACCESS
 #include <pciaccess.h>
@@ -78,7 +79,6 @@
 #include "via_dri.h"
 #endif
 
-#ifdef VIA_HAVE_EXA
 #include "exa.h"
 #define VIA_AGP_UPL_SIZE    (1024*128)
 #define VIA_DMA_DL_SIZE     (1024*128)
@@ -92,7 +92,6 @@
 #define VIA_MIN_UPLOAD 4000
 #define VIA_MIN_TEX_UPLOAD 200
 #define VIA_MIN_DOWNLOAD 200
-#endif
 
 #define AGP_PAGE_SIZE 4096
 #define AGP_PAGES 8192
@@ -101,14 +100,9 @@
 #define DRIVER_NAME     "openchrome"
 #define VERSION_MAJOR   0
 #define VERSION_MINOR   2
-#ifdef USE_NEW_XVABI
 #define PATCHLEVEL      903
-#else
-#define PATCHLEVEL      0
-#endif
 #define VIA_VERSION     ((VERSION_MAJOR<<24) | (VERSION_MINOR<<16) | PATCHLEVEL)
 
-#define VIA_CURSOR_SIZE         (4 * 1024)
 #define VIA_VQ_SIZE             (256 * 1024)
 
 typedef struct {
@@ -130,6 +124,9 @@
     CARD8   CR97, CR99, CR9B, CR9F, CRA0, CRA1, CRA2;
     CARD8   CRTCRegs[68];
 /*    CARD8   LCDRegs[0x40];*/
+
+    /* TMDS/LVDS Control */
+    CARD8   CRD2;
 } VIARegRec, *VIARegPtr;
 
 /*
@@ -211,7 +208,6 @@
     int                 FBFreeEnd;
     int                 driSize;
     int                 maxDriSize;
-    int                 CursorStart;
     int                 VQStart;
     int                 VQEnd;
 
@@ -230,7 +226,7 @@
 
     /* Here are all the Options */
     Bool                VQEnable;
-    Bool                hwcursor;
+    Bool		hwcursor;
     Bool                NoAccel;
     Bool                shadowFB;
     int                 rotate;
@@ -276,7 +272,7 @@
     CARD32              lastMarkerRead;
     Bool                agpDMA;
     Bool                nPOT[VIA_NUM_TEXUNITS];
-#ifdef VIA_HAVE_EXA
+    const unsigned     *TwodRegs;
     ExaDriverPtr        exaDriverPtr;
     ExaOffscreenArea   *exa_scratch;
     unsigned int        exa_scratch_next;
@@ -298,7 +294,6 @@
     char *              texAddr;
     char *              dBounce;
 #endif
-#endif
 
     /* BIOS Info Ptr */
     VIABIOSInfoPtr      pBIOSInfo;
@@ -354,11 +349,32 @@
     Bool                dmaXV;
 
     CARD8               ActiveDevice;	/* Option */
+
     unsigned char       *CursorImage;
-    CARD32		CursorFG;
-    CARD32		CursorBG;
-    CARD32		CursorMC;
+    CARD32              CursorFG;
+    CARD32              CursorBG;
+    Bool                CursorARGB;
+    Bool                CursorARGBSupported;
+    CARD8               CursorPipe;
+    int                 CursorStart;
+	int					CursorMaxWidth;
+	int					CursorMaxHeight;
+	int					CursorSize;
 
+    CARD32              CursorRegControl;
+    CARD32              CursorRegBase;
+    CARD32              CursorRegPos;
+    CARD32              CursorRegOffset;
+    CARD32              CursorRegFifo;
+    CARD32              CursorRegTransKey;
+
+    CARD32              CursorControl0;
+    CARD32              CursorControl1;
+    CARD32              CursorFifo;
+    CARD32              CursorTransparentKey;
+    CARD32              CursorPrimHiInvtColor;
+    CARD32              CursorV327HiInvtColor; 
+    
     /* Video */
     int                 VideoEngine;
     swovRec		swov;
@@ -375,12 +391,21 @@
     
     ViaSharedPtr	sharedData;
     Bool                useDmaBlit;
+
+    void                *displayMap;
+    CARD32              displayOffset;
+    void                *cursorMap;
+    CARD32              cursorOffset;
+
 #ifdef HAVE_DEBUG
     Bool                disableXvBWCheck;
     Bool                DumpVGAROM;
     Bool                PrintVGARegs;
     Bool                PrintTVRegs;
     Bool                I2CScan;
+    
+    Bool                UseLegacyModeSwitch ;
+    video_via_regs*     VideoRegs ;
 #endif /* HAVE_DEBUG */
 } VIARec, *VIAPtr;
 
@@ -402,16 +427,17 @@
 } VIAEntRec, *VIAEntPtr;
 
 /* Prototypes. */
-#if defined(XF86DRI) || defined(VIA_HAVE_EXA)
 void VIAInitialize3DEngine(ScrnInfoPtr pScrn);
-#endif 
 
 /* In via_cursor.c. */
-Bool VIAHWCursorInit(ScreenPtr pScreen);
-void VIAShowCursor(ScrnInfoPtr);
-void VIAHideCursor(ScrnInfoPtr);
-void ViaCursorStore(ScrnInfoPtr pScrn);
-void ViaCursorRestore(ScrnInfoPtr pScrn);
+Bool viaCursorHWInit(ScreenPtr pScreen);
+void viaCursorShow(ScrnInfoPtr);
+void viaCursorHide(ScrnInfoPtr);
+void viaCursorStore(ScrnInfoPtr pScrn);
+void viaCursorRestore(ScrnInfoPtr pScrn);
+Bool viaCursorRecInit(ScrnInfoPtr pScrn);
+void viaCursorRecDestroy(ScrnInfoPtr pScrn);
+void viaCursorSetFB(ScrnInfoPtr pScrn);
 
 /* In via_accel.c. */
 Bool viaInitAccel(ScreenPtr);
Index: src/via_bios.h
===================================================================
--- src/via_bios.h	(.../tags/release_0_2_903)	(revision 751)
+++ src/via_bios.h	(.../trunk)	(revision 751)
@@ -34,6 +34,14 @@
 #define     VIA_PANEL14X10                  5
 #define     VIA_PANEL16X12                  6
 #define     VIA_PANEL12X8                   7
+#define     VIA_PANEL8X4                    8
+#define     VIA_PANEL1366X7                 9
+#define     VIA_PANEL1360X7                 10
+#define     VIA_PANEL1920x1080              11
+#define     VIA_PANEL1920x1200              12
+#define     VIA_PANEL10X6                   13
+#define     VIA_PANEL14X9                   14
+#define     VIA_PANEL1280X720               15
 #define     VIA_PANEL_INVALID               255
 
 #define     TVTYPE_NONE                     0x00
@@ -90,6 +98,46 @@
 #define	    VIA_DI_12BIT		    0x00
 #define	    VIA_DI_24BIT		    0x01
 
+typedef struct ViaPanelMode {
+    int Width ;
+    int Height ;
+} ViaPanelModeRec, *ViaPanelModePtr ;
+
+typedef struct ViaPanelInfo {
+    Bool IsActive ;
+    /* current native resolution */
+    ViaPanelModePtr NativeMode ;
+    /* Native resolution index, see via_panel.c */
+    CARD8 NativeModeIndex;
+    /* Generated mode for native resolution */
+    DisplayModePtr  NativeDisplayMode ;
+#if 0
+    /* Panel size from configuration */
+    char*           PanelSizeFromOption;
+#endif
+    /* Current mode but centered */
+    DisplayModePtr  CenteredMode ;
+    /* Determine if we must use the hardware scaler
+     * It might be false even if the "Center" option
+     * was specified
+     */
+    Bool            Scale;
+} ViaPanelInfoRec, *ViaPanelInfoPtr ;
+
+typedef struct ViaLVDSInfo {
+    Bool IsActive ;
+} ViaLVDSInfoRec, *ViaLVDSInfoPtr ;
+
+typedef struct ViaCRTCInfo {
+    Bool IsActive ;
+    /* TODO: add CRTC constraints here */
+} ViaCRTCInfoRec, *ViaCRTCInfoPtr ;
+
+typedef struct ViaSimultaneousInfo {
+    Bool IsActive ;
+} ViaSimultaneousInfoRec, *ViaSimultaneousInfoPtr ;
+
+
 typedef struct _VIABIOSINFO {
     int         scrnIndex;
 
@@ -102,13 +150,12 @@
     CARD32      Bandwidth; /* available memory bandwidth */
 
     /* Panel/LCD entries */
+    ViaPanelInfoPtr Panel ;
     Bool        PanelPresent;
-    Bool        PanelActive;
     Bool        ForcePanel;
     int         PanelIndex;
-    int         PanelSize;
     Bool        Center;
-    CARD8	BusWidth;		/* Digital Output Bus Width */
+    CARD8       BusWidth;		/* Digital Output Bus Width */
     Bool        SetDVI;
     /* LCD Simultaneous Expand Mode HWCursor Y Scale */
     Bool        scaleY;
@@ -116,6 +163,20 @@
     int         panelY;
     int         resY;
 
+    /* DFP */
+    Bool        DfpPresent;
+    Bool        DfpActive;
+    
+    /* Integrated LVDS */
+    ViaLVDSInfoPtr Lvds;
+    
+    /* CRTCs */
+    ViaCRTCInfoPtr FirstCRTC ;
+    ViaCRTCInfoPtr SecondCRTC ;
+
+    /* Simultaneous */
+    ViaSimultaneousInfoPtr Simultaneous ;
+
     /* TV entries */
     int         TVEncoder;
     int         TVOutput;
@@ -156,18 +217,46 @@
 void ViaModesAttach(ScrnInfoPtr pScrn, MonPtr monitorp);
 CARD32 ViaGetMemoryBandwidth(ScrnInfoPtr pScrn);
 ModeStatus ViaValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags);
-void ViaModePrimary(ScrnInfoPtr pScrn, DisplayModePtr mode);
-void ViaModeSecondary(ScrnInfoPtr pScrn, DisplayModePtr mode);
-void ViaModeSecondaryVGAOffset(ScrnInfoPtr pScrn);
-void ViaModeSecondaryVGAFetchCount(ScrnInfoPtr pScrn, int width);
+void ViaModePrimaryLegacy(ScrnInfoPtr pScrn, DisplayModePtr mode);
+void ViaModeSecondaryLegacy(ScrnInfoPtr pScrn, DisplayModePtr mode);
 void ViaLCDPower(ScrnInfoPtr pScrn, Bool On);
+void ViaDFPPower(ScrnInfoPtr pScrn, Bool On);
 void ViaTVPower(ScrnInfoPtr pScrn, Bool On);
 void ViaTVSave(ScrnInfoPtr pScrn);
 void ViaTVRestore(ScrnInfoPtr pScrn);
 #ifdef HAVE_DEBUG
 void ViaTVPrintRegs(ScrnInfoPtr pScrn);
 #endif
+void ViaModeSecondCRTC(ScrnInfoPtr pScrn, DisplayModePtr mode);
+void ViaModeFirstCRTC(ScrnInfoPtr pScrn, DisplayModePtr mode);
+void ViaModeSet(ScrnInfoPtr pScrn, DisplayModePtr mode);
 
+/* via_crtc.c */
+void ViaPreInitCRTCConfig(ScrnInfoPtr pScrn);
+void ViaCRTCInit(ScrnInfoPtr pScrn);
+void ViaFirstCRTCSetStartingAddress(ScrnInfoPtr pSCrn, int x, int y);
+void ViaFirstCRTCSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode);
+void ViaSecondCRTCSetStartingAddress(ScrnInfoPtr pScrn, int x, int y);
+void ViaSecondCRTCHorizontalOffset(ScrnInfoPtr pScrn);
+void ViaSecondCRTCHorizontalQWCount(ScrnInfoPtr pScrn, int width);
+void ViaSecondCRTCSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode);
+ModeStatus ViaFirstCRTCModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode);
+ModeStatus ViaSecondCRTCModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode);
+void ViaShadowCRTCSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode);
+
+/* via_panel.c */
+void ViaPanelScale(ScrnInfoPtr pScrn, int resWidth, int resHeight, int panelWidth, int panelHeight );
+void ViaPanelScaleDisable(ScrnInfoPtr pScrn);
+void ViaPanelGetNativeModeFromScratchPad(ScrnInfoPtr pScrn);
+void ViaPanelGetNativeModeFromOption(ScrnInfoPtr pScrn, char* name);
+void ViaPanelPreInit(ScrnInfoPtr pScrn);
+void ViaPanelCenterMode(DisplayModePtr centerMode, DisplayModePtr panelMode, DisplayModePtr mode);
+Bool ViaPanelGetSizeFromDDCv1(ScrnInfoPtr pScrn, int* width, int* height);
+Bool ViaPanelGetSizeFromDDCv2(ScrnInfoPtr pScrn, int* width);
+Bool ViaPanelGetSizeFromEDID(ScrnInfoPtr pScrn, xf86MonPtr pMon, int* width, int* height);
+/* via_lvds.c */
+void ViaLVDSPower(ScrnInfoPtr pScrn, Bool on);
+
 /* in via_bandwidth.c */
 void ViaSetPrimaryFIFO(ScrnInfoPtr pScrn, DisplayModePtr mode);
 void ViaSetSecondaryFIFO(ScrnInfoPtr pScrn, DisplayModePtr mode);
@@ -181,4 +270,13 @@
 I2CDevPtr ViaCH7xxxDetect(ScrnInfoPtr pScrn, I2CBusPtr pBus, CARD8 Address);
 void ViaCH7xxxInit(ScrnInfoPtr pScrn);
 
+/* via_display.c */
+void ViaSecondDisplayChannelEnable(ScrnInfoPtr pScrn);
+void ViaSecondDisplayChannelDisable(ScrnInfoPtr pScrn);
+void ViaDisplayInit(ScrnInfoPtr pScrn);
+void ViaDisplayEnableSimultaneous(ScrnInfoPtr pScrn);
+void ViaDisplayDisableSimultaneous(ScrnInfoPtr pScrn);
+void ViaDisplayEnableCRT(ScrnInfoPtr pScrn);
+void ViaDisplayDisableCRT(ScrnInfoPtr pScrn);
+
 #endif /* _VIA_BIOS_H_ */
Index: src/via_bandwidth.c
===================================================================
--- src/via_bandwidth.c	(.../tags/release_0_2_903)	(revision 751)
+++ src/via_bandwidth.c	(.../trunk)	(revision 751)
@@ -227,6 +227,10 @@
             ViaSeqMask(hwp, 0x18, 0x00, 0x80);
             break;
         case VIA_P4M890:
+            hwp->writeSeq(hwp, 0x16, 0x13);
+            hwp->writeSeq(hwp, 0x17, 0x2F);
+            hwp->writeSeq(hwp, 0x18, 0x53);
+            hwp->writeSeq(hwp, 0x22, 0x10);
             break;
         case VIA_CX700:
             hwp->writeSeq(hwp, 0x16, 0x26);
@@ -234,6 +238,12 @@
             hwp->writeSeq(hwp, 0x18, 0x66);
             hwp->writeSeq(hwp, 0x22, 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, 0x18, 0x26); /* 152/4   = 38 */ 
+            hwp->writeSeq(hwp, 0x22, 0x10); /*  64/4   = 16 */
+            break;
         default:
             xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaSetPrimaryFIFO: "
                        "Chipset %d not implemented\n", pVia->Chipset);
@@ -385,6 +395,23 @@
             else
                 ViaCrtcMask(hwp, 0x94, 0x20, 0x7F);
             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, 0x95, 0x00, 0x80);
+            /* {CR68,0,3},{CR95,4,6} : 64/4 = 0x10 */
+            ViaCrtcMask(hwp, 0x68, 0x04, 0x0F);
+            ViaCrtcMask(hwp, 0x95, 0x10, 0x70);
+            /* {CR92,0,3},{CR95,0,2} : 32/4 = 0x08 */
+            ViaCrtcMask(hwp, 0x92, 0x08, 0x0F);
+            ViaCrtcMask(hwp, 0x95, 0x00, 0x07);
+            /* {CR94,0,6} : 128/4 = 0x20 */
+            if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32))
+                ViaCrtcMask(hwp, 0x94, 0x10, 0x7F);
+            else
+                ViaCrtcMask(hwp, 0x94, 0x20, 0x7F);
+            break;
         default:
             xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaSetSecondaryFIFO: "
                        "Chipset %d not implemented\n", pVia->Chipset);
Index: src/via_display.c
===================================================================
--- src/via_display.c	(.../tags/release_0_2_903)	(revision 0)
+++ src/via_display.c	(.../trunk)	(revision 751)
@@ -0,0 +1,145 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "via.h"
+#include "via_driver.h"
+#include "via_vgahw.h"
+#include "via_id.h"
+
+/*
+ * Enables the second display channel.
+ */
+void
+ViaSecondDisplayChannelEnable(ScrnInfoPtr pScrn)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                     "ViaSecondDisplayChannelEnable\n"));
+    ViaCrtcMask(hwp, 0x6A, 0x00, 1 << 6);
+    ViaCrtcMask(hwp, 0x6A, 1 << 7, 1 << 7);
+    ViaCrtcMask(hwp, 0x6A, 1 << 6, 1 << 6);
+}
+
+/*
+ * Disables the second display channel.
+ */
+void
+ViaSecondDisplayChannelDisable(ScrnInfoPtr pScrn)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                     "ViaSecondDisplayChannelDisable\n"));
+
+    ViaCrtcMask(hwp, 0x6A, 0x00, 1 << 6);
+    ViaCrtcMask(hwp, 0x6A, 0x00, 1 << 7);
+    ViaCrtcMask(hwp, 0x6A, 1 << 6, 1 << 6);
+}
+
+/*
+ * Initial settings for displays.
+ */
+void
+ViaDisplayInit(ScrnInfoPtr pScrn)
+{
+    VIAPtr pVia = VIAPTR(pScrn);
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDisplayPreInit\n"));
+
+    ViaSecondDisplayChannelDisable(pScrn);
+    ViaCrtcMask(hwp, 0x6A, 0x00, 0x3D);
+
+    hwp->writeCrtc(hwp, 0x6B, 0x00);
+    hwp->writeCrtc(hwp, 0x6C, 0x00);
+    hwp->writeCrtc(hwp, 0x79, 0x00);
+
+    /* (IGA1 Timing Plus 2, added in VT3259 A3 or later) */
+    if (pVia->Chipset != VIA_CLE266 && pVia->Chipset != VIA_KM400)
+        ViaCrtcMask(hwp, 0x47, 0x00, 0xC8);
+}
+
+/*
+ * Enables simultaneous mode.
+ */
+void
+ViaDisplayEnableSimultaneous(ScrnInfoPtr pScrn)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                     "ViaDisplayEnableSimultaneous\n"));
+    ViaCrtcMask(hwp, 0x6B, 0x08, 0x08);
+}
+
+/*
+ * Disables simultaneous mode.
+ */
+void
+ViaDisplayDisableSimultaneous(ScrnInfoPtr pScrn)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                     "ViaDisplayDisableSimultaneous\n"));
+    ViaCrtcMask(hwp, 0x6B, 0x00, 0x08);
+}
+
+/*
+ * Enables CRT using DPMS registers.
+ */
+void
+ViaDisplayEnableCRT(ScrnInfoPtr pScrn)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDisplayEnableCRT\n"));
+    ViaCrtcMask(hwp, 0x36, 0x00, 0x30);
+}
+
+/*
+ * Disables CRT using DPMS registers.
+ */
+void
+ViaDisplayDisableCRT(ScrnInfoPtr pScrn)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDisplayDisableCRT\n"));
+    ViaCrtcMask(hwp, 0x36, 0x30, 0x30);
+}
+
+/*
+ * Sets the primary or secondary display stream on CRT.
+ */
+void
+ViaDisplaySetStreamOnCRT(ScrnInfoPtr pScrn, Bool primary)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDisplaySetStreamOnCRT\n"));
+
+    if (primary)
+        ViaSeqMask(hwp, 0x16, 0x00, 0x40);
+    else
+        ViaSeqMask(hwp, 0x16, 0x40, 0x40);
+}
+
+/*
+ * Sets the primary or secondary display stream on internal TMDS.
+ */
+void
+ViaDisplaySetStreamOnDFP(ScrnInfoPtr pScrn, Bool primary)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDisplaySetStreamOnDFP\n"));
+
+    if (primary)
+        ViaCrtcMask(hwp, 0x99, 0x00, 0x10);
+    else
+        ViaCrtcMask(hwp, 0x99, 0x10, 0x10);
+}
+
Index: src/via_regs.h
===================================================================
--- src/via_regs.h	(.../tags/release_0_2_903)	(revision 751)
+++ src/via_regs.h	(.../trunk)	(revision 751)
@@ -42,7 +42,7 @@
 #define VIA_MMIO_REGBASE        0x0
 #define VIA_MMIO_VGABASE        0x8000
 #define VIA_MMIO_BLTBASE        0x200000
-#define VIA_MMIO_BLTSIZE        0x20000
+#define VIA_MMIO_BLTSIZE        0x200000
 
 
 /* defines for VIA 2D registers */
@@ -71,6 +71,33 @@
 #define VIA_REG_MONOPAT1        0x040
 #define VIA_REG_COLORPAT        0x100       /* from 0x100 to 0x1ff */
 
+/* defineds vor VIA 2D registers for VT3353 (M1 engine) */
+#define VIA_REG_GECMD_M1        0x000
+#define VIA_REG_GEMODE_M1       0x004
+#define VIA_REG_GESTATUS_M1     0x004       /* as same as VIA_REG_GEMODE */
+#define VIA_REG_PITCH_M1        0x008       /* pitch of src and dst */
+#define VIA_REG_DIMENSION_M1    0x00C       /* width and height */
+#define VIA_REG_DSTPOS_M1       0x010
+#define VIA_REG_LINE_XY_M1      0x010
+#define VIA_REG_DSTBASE_M1      0x014
+#define VIA_REG_SRCPOS_M1       0x018
+#define VIA_REG_LINE_K1K2_M1    0x018
+#define VIA_REG_SRCBASE_M1      0x01C
+#define VIA_REG_PATADDR_M1      0x020
+#define VIA_REG_MONOPAT0_M1     0x024
+#define VIA_REG_MONOPAT1_M1     0x028
+#define VIA_REG_OFFSET_M1       0x02C
+#define VIA_REG_LINE_ERROR_M1   0x02C
+#define VIA_REG_CLIPTL_M1       0x040       /* top and left of clipping */
+#define VIA_REG_CLIPBR_M1       0x044       /* bottom and right of clipping */
+#define VIA_REG_KEYCONTROL_M1   0x048       /* color key control */
+#define VIA_REG_FGCOLOR_M1      0x04C
+#define VIA_REG_DSTCOLORKEY_M1  0x04C       /* as same as VIA_REG_FG */
+#define VIA_REG_BGCOLOR_M1      0x050
+#define VIA_REG_SRCCOLORKEY_M1  0x050       /* as same as VIA_REG_BG */
+#define VIA_REG_MONOPATFGC_M1   0x058       /* Add foreground color of Pattern */
+#define VIA_REG_MONOPATBGC_M1   0x05C       /* Add background color of Pattern */
+#define VIA_REG_COLORPAT_M1     0x100       /* from 0x100 to 0x1ff */
 
 
 /* defines for VIA video registers */
@@ -86,6 +113,51 @@
 #define VIA_REG_CURSOR_FG       0x2E0
 
 
+/* These regs move about on diffrent hw */
+#define VIA_REG_HI_CONTROL1     VIA_REG_ALPHA_CONTROL
+#define VIA_REG_HI_BASE1        VIA_REG_ALPHA_BASE
+#define VIA_REG_HI_POS1         VIA_REG_ALPHA_POS
+#define VIA_REG_HI_OFFSET1      VIA_REG_ALPHA_OFFSET
+#define VIA_REG_HI_FIFO1        VIA_REG_ALPHA_FIFO
+#define VIA_REG_HI_TRANSKEY1    VIA_REG_ALPHA_TRANSKEY
+
+/* Note that Hardware Icon and Alpha Window overlap */
+#define VIA_REG_ALPHA_CONTROL   0x260
+#define VIA_REG_ALPHA_BASE      0x224
+#define VIA_REG_ALPHA_POS       0x208
+#define VIA_REG_ALPHA_OFFSET    0x20C
+#define VIA_REG_ALPHA_PREFIFO   0x268
+#define VIA_REG_ALPHA_FIFO      0x278
+#define VIA_REG_ALPHA_TRANSKEY  0x270
+
+/* secret regs */
+#define VIA_REG_HI_CONTROL0     0x2F0
+#define VIA_REG_HI_BASE0        0x2F4
+#define VIA_REG_HI_POS0         0x2F8
+#define VIA_REG_HI_OFFSET0      0x2FC
+#define VIA_REG_HI_FIFO0        0x2E8
+#define VIA_REG_HI_TRANSKEY0    0x2EC
+
+/*CN400 and older Hardware Icon engine register*/
+#define VIA_REG_HI_POSSTART             0x208
+#define VIA_REG_HI_CENTEROFFSET         0x20C
+#define VIA_REG_HI_FBOFFSET             0x224
+#define VIA_REG_HI_CONTROL              0x260
+#define VIA_REG_HI_TRANSPARENT_COLOR    0x270
+#define VIA_REG_HI_INVTCOLOR            0x274
+/* VT3324 primary Hardware Icon engine register */
+#define VIA_REG_PRIM_HI_POSEND          0x290
+#define VIA_REG_V327_HI_INVTCOLOR       0x2E4
+#define VIA_REG_PRIM_HI_FIFO            0x2E8
+#define VIA_REG_PRIM_HI_TRANSCOLOR      0x2EC
+#define VIA_REG_PRIM_HI_CTRL            0x2F0
+#define VIA_REG_PRIM_HI_FBOFFSET        0x2F4
+#define VIA_REG_PRIM_HI_POSSTART        0x2F8
+#define VIA_REG_PRIM_HI_CENTEROFFSET    0x2FC
+#define VIA_REG_PRIM_HI_INVTCOLOR       0x120C
+
+
+
 /* defines for VIA 3D registers */
 #define VIA_REG_STATUS          0x400
 #define VIA_REG_TRANSET         0x43C
@@ -97,6 +169,11 @@
 #define VIA_3D_ENG_BUSY         0x00000001  /* 3D Engine is busy */
 #define VIA_VR_QUEUE_BUSY       0x00020000 /* Virtual Queue is busy */
 
+/* VIA_REG_STATUS(0x400): Egine Status */
+#define VIA_CMD_RGTR_BUSY_H5    0x00000010  /* Command Regulator is busy */
+#define VIA_2D_ENG_BUSY_H5      0x00000002  /* 2D Engine is busy */
+#define VIA_3D_ENG_BUSY_H5      0x00001FE1  /* 3D Engine is busy */
+#define VIA_VR_QUEUE_BUSY_H5    0x00000004  /* Virtual Queue is busy */
 
 /* VIA_REG_GECMD(0x00): 2D Engine Command  */
 #define VIA_GEC_NOOP            0x00000000
Index: src/via_accel.c
===================================================================
--- src/via_accel.c	(.../tags/release_0_2_903)	(revision 751)
+++ src/via_accel.c	(.../trunk)	(revision 751)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
  * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
  * Copyright 2006 Thomas Hellström. All Rights Reserved.
  *
@@ -52,6 +52,95 @@
 #define VIAACCELCOPYROP(vRop) (XAACopyROP[vRop] << 24)
 #endif
 
+enum VIA_2D_Regs {
+	GECMD,
+	GEMODE,
+	GESTATUS,
+	SRCPOS,
+	DSTPOS,
+	LINE_K1K2,
+	LINE_XY,
+	LINE_ERROR,
+	DIMENSION,
+	PATADDR,
+	FGCOLOR,
+	DSTCOLORKEY,
+	BGCOLOR,
+	SRCCOLORKEY,
+	CLIPTL,
+	CLIPBR,
+	OFFSET,
+	KEYCONTROL,
+	SRCBASE,
+	DSTBASE,
+	PITCH,
+	MONOPAT0,
+	MONOPAT1,
+	COLORPAT,
+	MONOPATFGC,
+	MONOPATBGC
+};
+
+/* register offsets for old 2D core */
+static const unsigned via_2d_regs[] = {
+    [GECMD]             = VIA_REG_GECMD,
+    [GEMODE]            = VIA_REG_GEMODE,
+    [GESTATUS]          = VIA_REG_GESTATUS,
+    [SRCPOS]            = VIA_REG_SRCPOS,
+    [DSTPOS]            = VIA_REG_DSTPOS,
+    [LINE_K1K2]         = VIA_REG_LINE_K1K2,
+    [LINE_XY]           = VIA_REG_LINE_XY,
+    [LINE_ERROR]        = VIA_REG_LINE_ERROR,
+    [DIMENSION]         = VIA_REG_DIMENSION,
+    [PATADDR]           = VIA_REG_PATADDR,
+    [FGCOLOR]           = VIA_REG_FGCOLOR,
+    [DSTCOLORKEY]       = VIA_REG_DSTCOLORKEY,
+    [BGCOLOR]           = VIA_REG_BGCOLOR,
+    [SRCCOLORKEY]       = VIA_REG_SRCCOLORKEY,
+    [CLIPTL]            = VIA_REG_CLIPTL,
+    [CLIPBR]            = VIA_REG_CLIPBR,
+    [KEYCONTROL]        = VIA_REG_KEYCONTROL,
+    [SRCBASE]           = VIA_REG_SRCBASE,
+    [DSTBASE]           = VIA_REG_DSTBASE,
+    [PITCH]             = VIA_REG_PITCH,
+    [MONOPAT0]          = VIA_REG_MONOPAT0,
+    [MONOPAT1]          = VIA_REG_MONOPAT1,
+    [COLORPAT]          = VIA_REG_COLORPAT,
+    [MONOPATFGC]        = VIA_REG_FGCOLOR,
+    [MONOPATBGC]        = VIA_REG_BGCOLOR
+};
+
+/* register offsets for new 2D core (M1 in VT3353 == VX800) */
+static const unsigned via_2d_regs_m1[] = {
+    [GECMD]             = VIA_REG_GECMD_M1,
+    [GEMODE]            = VIA_REG_GEMODE_M1,
+    [GESTATUS]          = VIA_REG_GESTATUS_M1,
+    [SRCPOS]            = VIA_REG_SRCPOS_M1,
+    [DSTPOS]            = VIA_REG_DSTPOS_M1,
+    [LINE_K1K2]         = VIA_REG_LINE_K1K2_M1,
+    [LINE_XY]           = VIA_REG_LINE_XY_M1,
+    [LINE_ERROR]        = VIA_REG_LINE_ERROR_M1,
+    [DIMENSION]         = VIA_REG_DIMENSION_M1,
+    [PATADDR]           = VIA_REG_PATADDR_M1,
+    [FGCOLOR]           = VIA_REG_FGCOLOR_M1,
+    [DSTCOLORKEY]       = VIA_REG_DSTCOLORKEY_M1,
+    [BGCOLOR]           = VIA_REG_BGCOLOR_M1,
+    [SRCCOLORKEY]       = VIA_REG_SRCCOLORKEY_M1,
+    [CLIPTL]            = VIA_REG_CLIPTL_M1,
+    [CLIPBR]            = VIA_REG_CLIPBR_M1,
+    [KEYCONTROL]        = VIA_REG_KEYCONTROL_M1,
+    [SRCBASE]           = VIA_REG_SRCBASE_M1,
+    [DSTBASE]           = VIA_REG_DSTBASE_M1,
+    [PITCH]             = VIA_REG_PITCH_M1,
+    [MONOPAT0]          = VIA_REG_MONOPAT0_M1,
+    [MONOPAT1]          = VIA_REG_MONOPAT1_M1,
+    [COLORPAT]          = VIA_REG_COLORPAT_M1,
+    [MONOPATFGC]        = VIA_REG_MONOPATFGC_M1,
+    [MONOPATBGC]        = VIA_REG_MONOPATBGC_M1
+};
+
+#define VIA_REG(pVia, name)	(pVia)->TwodRegs[name]
+
 /*
  * Use PCI MMIO to flush the command buffer when AGP DMA is not available.
  */
@@ -104,15 +193,26 @@
                      * for an unacceptable amount of time in VIASETREG while
                      * other high priority interrupts may be pending.
                      */
-                    if (pVia->Chipset != VIA_P4M890 &&
-                        pVia->Chipset != VIA_K8M890 &&
-                        pVia->Chipset != VIA_P4M900) {
-                        while (!(VIAGETREG(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY)
-                               && (loop++ < MAXLOOP)) ;
+					switch (pVia->Chipset) {
+					    case VIA_VX800:
+							while ((VIAGETREG(VIA_REG_STATUS) &
+							       (VIA_CMD_RGTR_BUSY_H5 | VIA_2D_ENG_BUSY_H5))
+									&& (loop++ < MAXLOOP)) ;
+					    break;
+					    case VIA_K8M890:
+					    case VIA_P4M890:
+					    case VIA_P4M900:
+                    		while ((VIAGETREG(VIA_REG_STATUS) &
+                            	   (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY))
+                            		&& (loop++ < MAXLOOP)) ;
+					    break;
+						default:
+                        	while (!(VIAGETREG(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY)
+                                   && (loop++ < MAXLOOP)) ;
+                    		while ((VIAGETREG(VIA_REG_STATUS) &
+                            	   (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY))
+                                   && (loop++ < MAXLOOP)) ;
                     }
-                    while ((VIAGETREG(VIA_REG_STATUS) &
-                            (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY))
-                           && (loop++ < MAXLOOP)) ;
                 }
                 offset = (*bp++ & 0x0FFFFFFF) << 2;
                 value = *bp++;
@@ -314,8 +414,8 @@
     VIAPtr pVia = VIAPTR(pScrn);
 
     switch (pVia->Chipset) {
-        case VIA_P4M890:
         case VIA_K8M890:
+        case VIA_P4M900:
             VIASETREG(0x41c, 0x00100000);
             VIASETREG(0x420, 0x74301000);
             break;
@@ -367,12 +467,29 @@
     int i;
 
     /* Initialize the 2D engine registers to reset the 2D engine. */
-    for (i = 0x04; i < 0x44; i += 4) {
+    for (i = 0x04; i <= 0x40; i += 4) {
         VIASETREG(i, 0x0);
     }
 
+    if (pVia->Chipset == VIA_VX800) {
+        for (i = 0x44; i < 0x5c; i += 4) {
+            VIASETREG(i, 0x0);
+        }
+    }
+
+    /* Make the VIA_REG() macro magic work */
     switch (pVia->Chipset) {
+    case VIA_VX800:
+        pVia->TwodRegs = via_2d_regs_m1;
+        break;
+    default:
+        pVia->TwodRegs = via_2d_regs;
+        break;
+    }
+
+    switch (pVia->Chipset) {
         case VIA_K8M890:
+        case VIA_P4M900:
             viaInitPCIe(pVia);
             break;
         default:
@@ -383,6 +500,7 @@
     if (pVia->VQStart != 0) {
         switch (pVia->Chipset) {
             case VIA_K8M890:
+            case VIA_P4M900:
                 viaEnablePCIeVQ(pVia);
                 break;
             default:
@@ -408,11 +526,16 @@
     mem_barrier();
 
     switch (pVia->Chipset) {
+        case VIA_VX800:
+            while ((VIAGETREG(VIA_REG_STATUS) &
+                    (VIA_CMD_RGTR_BUSY_H5 | VIA_2D_ENG_BUSY_H5 | VIA_3D_ENG_BUSY_H5))
+                   && (loop++ < MAXLOOP)) ;
+            break;
         case VIA_P4M890:
         case VIA_K8M890:
         case VIA_P4M900:
             while ((VIAGETREG(VIA_REG_STATUS) &
-                    (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY))
+                    (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY))
                    && (loop++ < MAXLOOP)) ;
             break;
         default:
@@ -455,18 +578,40 @@
 }
 
 /*
+ * This is a small helper to wrap around a PITCH register write
+ * to deal with the sublte differences of M1 and old 2D engine
+ */
+static void
+viaPitchHelper(VIAPtr pVia, unsigned dstPitch, unsigned srcPitch)
+{
+    unsigned val = (dstPitch >> 3) << 16 | (srcPitch >> 3);
+    RING_VARS;
+
+    if (pVia->Chipset != VIA_VX800) {
+        val |= VIA_PITCH_ENABLE;
+    }
+    OUT_RING_H1(VIA_REG(pVia, PITCH), val);
+}
+
+/*
  * Emit clipping borders to the command buffer and update the 2D context
  * current command with clipping info.
  */
 static int
-viaAccelClippingHelper(ViaCommandBuffer * cb, int refY, ViaTwodContext * tdc)
+viaAccelClippingHelper(VIAPtr pVia, int refY)
 {
+    ViaTwodContext *tdc = &pVia->td;
+
+    RING_VARS;
+
     if (tdc->clipping) {
         refY = (refY < tdc->clipY1) ? refY : tdc->clipY1;
         tdc->cmd |= VIA_GEC_CLIP_ENABLE;
         BEGIN_RING(4);
-        OUT_RING_H1(VIA_REG_CLIPTL, ((tdc->clipY1 - refY) << 16) | tdc->clipX1);
-        OUT_RING_H1(VIA_REG_CLIPBR, ((tdc->clipY2 - refY) << 16) | tdc->clipX2);
+        OUT_RING_H1(VIA_REG(pVia, CLIPTL),
+                    ((tdc->clipY1 - refY) << 16) | tdc->clipX1);
+        OUT_RING_H1(VIA_REG(pVia, CLIPBR),
+		    ((tdc->clipY2 - refY) << 16) | tdc->clipX2);
     } else {
         tdc->cmd &= ~VIA_GEC_CLIP_ENABLE;
     }
@@ -477,18 +622,20 @@
  * Emit a solid blit operation to the command buffer. 
  */
 static void
-viaAccelSolidHelper(ViaCommandBuffer * cb, int x, int y, int w, int h,
+viaAccelSolidHelper(VIAPtr pVia, int x, int y, int w, int h,
                     unsigned fbBase, CARD32 mode, unsigned pitch,
                     CARD32 fg, CARD32 cmd)
 {
+    RING_VARS;
+
     BEGIN_RING(14);
-    OUT_RING_H1(VIA_REG_GEMODE, mode);
-    OUT_RING_H1(VIA_REG_DSTBASE, fbBase >> 3);
-    OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | (pitch >> 3) << 16);
-    OUT_RING_H1(VIA_REG_DSTPOS, (y << 16) | (x & 0xFFFF));
-    OUT_RING_H1(VIA_REG_DIMENSION, ((h - 1) << 16) | (w - 1));
-    OUT_RING_H1(VIA_REG_FGCOLOR, fg);
-    OUT_RING_H1(VIA_REG_GECMD, cmd);
+    OUT_RING_H1(VIA_REG(pVia, GEMODE), mode);
+    OUT_RING_H1(VIA_REG(pVia, DSTBASE), fbBase >> 3);
+    viaPitchHelper(pVia, pitch, 0);
+    OUT_RING_H1(VIA_REG(pVia, DSTPOS), (y << 16) | (x & 0xFFFF));
+    OUT_RING_H1(VIA_REG(pVia, DIMENSION), ((h - 1) << 16) | (w - 1));
+    OUT_RING_H1(VIA_REG(pVia, MONOPATFGC), fg);
+    OUT_RING_H1(VIA_REG(pVia, GECMD), cmd);
 }
 
 /*
@@ -534,16 +681,19 @@
  * Emit transparency state and color to the command buffer.
  */
 static void
-viaAccelTransparentHelper(ViaTwodContext * tdc, ViaCommandBuffer * cb,
-                          CARD32 keyControl, CARD32 transColor,
-                          Bool usePlaneMask)
+viaAccelTransparentHelper(VIAPtr pVia, CARD32 keyControl,
+                          CARD32 transColor, Bool usePlaneMask)
 {
+    ViaTwodContext *tdc = &pVia->td;
+
+    RING_VARS;
+
     tdc->keyControl &= ((usePlaneMask) ? 0xF0000000 : 0x00000000);
     tdc->keyControl |= (keyControl & 0x0FFFFFFF);
     BEGIN_RING(4);
-    OUT_RING_H1(VIA_REG_KEYCONTROL, tdc->keyControl);
+    OUT_RING_H1(VIA_REG(pVia, KEYCONTROL), tdc->keyControl);
     if (keyControl) {
-        OUT_RING_H1(VIA_REG_SRCCOLORKEY, transColor);
+        OUT_RING_H1(VIA_REG(pVia, SRCCOLORKEY), transColor);
     }
 }
 
@@ -551,11 +701,13 @@
  * Emit a copy blit operation to the command buffer.
  */
 static void
-viaAccelCopyHelper(ViaCommandBuffer * cb, int xs, int ys, int xd, int yd,
+viaAccelCopyHelper(VIAPtr pVia, int xs, int ys, int xd, int yd,
                    int w, int h, unsigned srcFbBase, unsigned dstFbBase,
                    CARD32 mode, unsigned srcPitch, unsigned dstPitch,
                    CARD32 cmd)
 {
+    RING_VARS;
+
     if (cmd & VIA_GEC_DECY) {
         ys += h - 1;
         yd += h - 1;
@@ -567,15 +719,14 @@
     }
 
     BEGIN_RING(16);
-    OUT_RING_H1(VIA_REG_GEMODE, mode);
-    OUT_RING_H1(VIA_REG_SRCBASE, srcFbBase >> 3);
-    OUT_RING_H1(VIA_REG_DSTBASE, dstFbBase >> 3);
-    OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE |
-                ((dstPitch >> 3) << 16) | (srcPitch >> 3));
-    OUT_RING_H1(VIA_REG_SRCPOS, (ys << 16) | (xs & 0xFFFF));
-    OUT_RING_H1(VIA_REG_DSTPOS, (yd << 16) | (xd & 0xFFFF));
-    OUT_RING_H1(VIA_REG_DIMENSION, ((h - 1) << 16) | (w - 1));
-    OUT_RING_H1(VIA_REG_GECMD, cmd);
+    OUT_RING_H1(VIA_REG(pVia, GEMODE), mode);
+    OUT_RING_H1(VIA_REG(pVia, SRCBASE), srcFbBase >> 3);
+    OUT_RING_H1(VIA_REG(pVia, DSTBASE), dstFbBase >> 3);
+    viaPitchHelper(pVia, dstPitch, srcPitch);
+    OUT_RING_H1(VIA_REG(pVia, SRCPOS), (ys << 16) | (xs & 0xFFFF));
+    OUT_RING_H1(VIA_REG(pVia, DSTPOS), (yd << 16) | (xd & 0xFFFF));
+    OUT_RING_H1(VIA_REG(pVia, DIMENSION), ((h - 1) << 16) | (w - 1));
+    OUT_RING_H1(VIA_REG(pVia, GECMD), cmd);
 }
 
 /*
@@ -603,7 +754,7 @@
         cmd |= VIA_GEC_DECY;
 
     tdc->cmd = cmd;
-    viaAccelTransparentHelper(tdc, cb, (trans_color != -1) ? 0x4000 : 0x0000,
+    viaAccelTransparentHelper(pVia, (trans_color != -1) ? 0x4000 : 0x0000,
                               trans_color, FALSE);
 }
 
@@ -620,8 +771,8 @@
     if (!w || !h)
         return;
 
-    sub = viaAccelClippingHelper(cb, y2, tdc);
-    viaAccelCopyHelper(cb, x1, 0, x2, y2 - sub, w, h,
+    sub = viaAccelClippingHelper(pVia, y2);
+    viaAccelCopyHelper(pVia, x1, 0, x2, y2 - sub, w, h,
                        pScrn->fbOffset + pVia->Bpl * y1,
                        pScrn->fbOffset + pVia->Bpl * sub,
                        tdc->mode, pVia->Bpl, pVia->Bpl, tdc->cmd);
@@ -641,7 +792,7 @@
 
     tdc->cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(rop);
     tdc->fgColor = color;
-    viaAccelTransparentHelper(tdc, cb, 0x00, 0x00, FALSE);
+    viaAccelTransparentHelper(pVia, 0x00, 0x00, FALSE);
 }
 
 static void
@@ -656,8 +807,8 @@
     if (!w || !h)
         return;
 
-    sub = viaAccelClippingHelper(cb, y, tdc);
-    viaAccelSolidHelper(cb, x, y - sub, w, h,
+    sub = viaAccelClippingHelper(pVia, y);
+    viaAccelSolidHelper(pVia, x, y - sub, w, h,
                         pScrn->fbOffset + pVia->Bpl * sub, tdc->mode, pVia->Bpl,
                         tdc->fgColor, tdc->cmd);
     ADVANCE_RING;
@@ -697,7 +848,7 @@
     tdc->bgColor = bg;
     tdc->pattern0 = pattern0;
     tdc->pattern1 = pattern1;
-    viaAccelTransparentHelper(tdc, cb, 0x00, 0x00, FALSE);
+    viaAccelTransparentHelper(pVia, 0x00, 0x00, FALSE);
 }
 
 static void
@@ -716,21 +867,21 @@
         return;
 
     patOffset = ((patOffy & 0x7) << 29) | ((patOffx & 0x7) << 26);
-    sub = viaAccelClippingHelper(cb, y, tdc);
+    sub = viaAccelClippingHelper(pVia, y);
     dstBase = pScrn->fbOffset + sub * pVia->Bpl;
 
     BEGIN_RING(22);
-    OUT_RING_H1(VIA_REG_GEMODE, tdc->mode);
-    OUT_RING_H1(VIA_REG_DSTBASE, dstBase >> 3);
-    OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pVia->Bpl >> 3) << 16));
-    OUT_RING_H1(VIA_REG_DSTPOS, ((y - sub) << 16) | (x & 0xFFFF));
-    OUT_RING_H1(VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1)));
-    OUT_RING_H1(VIA_REG_PATADDR, patOffset);
-    OUT_RING_H1(VIA_REG_FGCOLOR, tdc->fgColor);
-    OUT_RING_H1(VIA_REG_BGCOLOR, tdc->bgColor);
-    OUT_RING_H1(VIA_REG_MONOPAT0, tdc->pattern0);
-    OUT_RING_H1(VIA_REG_MONOPAT1, tdc->pattern1);
-    OUT_RING_H1(VIA_REG_GECMD, tdc->cmd);
+    OUT_RING_H1(VIA_REG(pVia, GEMODE), tdc->mode);
+    OUT_RING_H1(VIA_REG(pVia, DSTBASE), dstBase >> 3);
+    viaPitchHelper(pVia, pVia->Bpl, 0);
+    OUT_RING_H1(VIA_REG(pVia, DSTPOS), ((y - sub) << 16) | (x & 0xFFFF));
+    OUT_RING_H1(VIA_REG(pVia, DIMENSION), (((h - 1) << 16) | (w - 1)));
+    OUT_RING_H1(VIA_REG(pVia, PATADDR), patOffset);
+    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);
+    OUT_RING_H1(VIA_REG(pVia, MONOPAT1), tdc->pattern1);
+    OUT_RING_H1(VIA_REG(pVia, GECMD), tdc->cmd);
     ADVANCE_RING;
 }
 
@@ -745,7 +896,7 @@
 
     tdc->cmd = VIA_GEC_BLT | VIAACCELPATTERNROP(rop);
     tdc->patternAddr = (patternx * pVia->Bpp + patterny * pVia->Bpl);
-    viaAccelTransparentHelper(tdc, cb, (trans_color != -1) ? 0x4000 : 0x0000,
+    viaAccelTransparentHelper(pVia, (trans_color != -1) ? 0x4000 : 0x0000,
                               trans_color, FALSE);
 }
 
@@ -766,17 +917,17 @@
 
     patAddr = (tdc->patternAddr >> 3) |
             ((patOffy & 0x7) << 29) | ((patOffx & 0x7) << 26);
-    sub = viaAccelClippingHelper(cb, y, tdc);
+    sub = viaAccelClippingHelper(pVia, y);
     dstBase = pScrn->fbOffset + sub * pVia->Bpl;
 
     BEGIN_RING(14);
-    OUT_RING_H1(VIA_REG_GEMODE, tdc->mode);
-    OUT_RING_H1(VIA_REG_DSTBASE, dstBase >> 3);
-    OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pVia->Bpl >> 3) << 16));
-    OUT_RING_H1(VIA_REG_DSTPOS, ((y - sub) << 16) | (x & 0xFFFF));
-    OUT_RING_H1(VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1)));
-    OUT_RING_H1(VIA_REG_PATADDR, patAddr);
-    OUT_RING_H1(VIA_REG_GECMD, tdc->cmd);
+    OUT_RING_H1(VIA_REG(pVia, GEMODE), tdc->mode);
+    OUT_RING_H1(VIA_REG(pVia, DSTBASE), dstBase >> 3);
+    viaPitchHelper(pVia, pVia->Bpl, 0);
+    OUT_RING_H1(VIA_REG(pVia, DSTPOS), ((y - sub) << 16) | (x & 0xFFFF));
+    OUT_RING_H1(VIA_REG(pVia, DIMENSION), (((h - 1) << 16) | (w - 1)));
+    OUT_RING_H1(VIA_REG(pVia, PATADDR), patAddr);
+    OUT_RING_H1(VIA_REG(pVia, GECMD), tdc->cmd);
     ADVANCE_RING;
 }
 
@@ -810,7 +961,7 @@
 
     ADVANCE_RING;
 
-    viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, FALSE);
+    viaAccelTransparentHelper(pVia, 0x0, 0x0, FALSE);
 }
 
 static void
@@ -829,11 +980,11 @@
                                 (y + h - 1));
     }
 
-    sub = viaAccelClippingHelper(cb, y, tdc);
+    sub = viaAccelClippingHelper(pVia, y);
     BEGIN_RING(4);
-    OUT_RING_H1(VIA_REG_BGCOLOR, tdc->bgColor);
-    OUT_RING_H1(VIA_REG_FGCOLOR, tdc->fgColor);
-    viaAccelCopyHelper(cb, 0, 0, x, y - sub, w, h, 0,
+    OUT_RING_H1(VIA_REG(pVia, BGCOLOR), tdc->bgColor);
+    OUT_RING_H1(VIA_REG(pVia, FGCOLOR), tdc->fgColor);
+    viaAccelCopyHelper(pVia, 0, 0, x, y - sub, w, h, 0,
                        pScrn->fbOffset + sub * pVia->Bpl, tdc->mode,
                        pVia->Bpl, pVia->Bpl, tdc->cmd);
 
@@ -852,7 +1003,7 @@
 
     tdc->cmd = VIA_GEC_BLT | VIA_GEC_SRC_SYS | VIAACCELCOPYROP(rop);
     ADVANCE_RING;
-    viaAccelTransparentHelper(tdc, cb, (trans_color != -1) ? 0x4000 : 0x0000,
+    viaAccelTransparentHelper(pVia, (trans_color != -1) ? 0x4000 : 0x0000,
                               trans_color, FALSE);
 }
 
@@ -871,8 +1022,8 @@
                                 (y + h - 1));
     }
 
-    sub = viaAccelClippingHelper(cb, y, tdc);
-    viaAccelCopyHelper(cb, 0, 0, x, y - sub, w, h, 0,
+    sub = viaAccelClippingHelper(pVia, y);
+    viaAccelCopyHelper(pVia, 0, 0, x, y - sub, w, h, 0,
                        pScrn->fbOffset + pVia->Bpl * sub, tdc->mode,
                        pVia->Bpl, pVia->Bpl, tdc->cmd);
 
@@ -889,15 +1040,15 @@
 
     RING_VARS;
 
-    viaAccelTransparentHelper(tdc, cb, 0x00, 0x00, FALSE);
+    viaAccelTransparentHelper(pVia, 0x00, 0x00, FALSE);
     tdc->cmd = VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(rop);
     tdc->fgColor = color;
     tdc->dashed = FALSE;
 
     BEGIN_RING(6);
-    OUT_RING_H1(VIA_REG_GEMODE, tdc->mode);
-    OUT_RING_H1(VIA_REG_MONOPAT0, 0xFF);
-    OUT_RING_H1(VIA_REG_FGCOLOR, tdc->fgColor);
+    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);
 }
 
 static void
@@ -912,7 +1063,7 @@
 
     RING_VARS;
 
-    sub = viaAccelClippingHelper(cb, (y1 < y2) ? y1 : y2, tdc);
+    sub = viaAccelClippingHelper(pVia, (y1 < y2) ? y1 : y2);
     cmd = tdc->cmd | VIA_GEC_LINE;
 
     dx = x2 - x1;
@@ -944,8 +1095,8 @@
     y2 -= sub;
 
     BEGIN_RING(14);
-    OUT_RING_H1(VIA_REG_DSTBASE, dstBase >> 3);
-    OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pVia->Bpl >> 3) << 16));
+    OUT_RING_H1(VIA_REG(pVia, DSTBASE), dstBase >> 3);
+    viaPitchHelper(pVia, pVia->Bpl, 0);
 
     /*
      * major = 2*dmaj, minor = 2*dmin, err = -dmaj - ((bias >> octant) & 1) 
@@ -953,14 +1104,14 @@
      * Error Term = (StartX<EndX) ? (2*dmin - dmax - 1) : (2*(dmin - dmax)) 
      */
 
-    OUT_RING_H1(VIA_REG_LINE_K1K2,
+    OUT_RING_H1(VIA_REG(pVia, LINE_K1K2),
                 ((((dy << 1) & 0x3fff) << 16) | (((dy - dx) << 1) & 0x3fff)));
-    OUT_RING_H1(VIA_REG_LINE_XY, ((y1 << 16) | (x1 & 0xFFFF)));
-    OUT_RING_H1(VIA_REG_DIMENSION, dx);
-    OUT_RING_H1(VIA_REG_LINE_ERROR,
+    OUT_RING_H1(VIA_REG(pVia, LINE_XY), ((y1 << 16) | (x1 & 0xFFFF)));
+    OUT_RING_H1(VIA_REG(pVia, DIMENSION), dx);
+    OUT_RING_H1(VIA_REG(pVia, LINE_ERROR),
                 (((dy << 1) - dx - error) & 0x3fff) |
                 ((tdc->dashed) ? 0xFF0000 : 0));
-    OUT_RING_H1(VIA_REG_GECMD, cmd);
+    OUT_RING_H1(VIA_REG(pVia, GECMD), cmd);
     ADVANCE_RING;
 }
 
@@ -974,21 +1125,21 @@
 
     RING_VARS;
 
-    sub = viaAccelClippingHelper(cb, y, tdc);
+    sub = viaAccelClippingHelper(pVia, y);
     dstBase = pScrn->fbOffset + sub * pVia->Bpl;
 
     BEGIN_RING(10);
-    OUT_RING_H1(VIA_REG_DSTBASE, dstBase >> 3);
-    OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pVia->Bpl >> 3) << 16));
+    OUT_RING_H1(VIA_REG(pVia, DSTBASE), dstBase >> 3);
+    viaPitchHelper(pVia, pVia->Bpl, 0);
 
     if (dir == DEGREES_0) {
-        OUT_RING_H1(VIA_REG_DSTPOS, ((y - sub) << 16) | (x & 0xFFFF));
-        OUT_RING_H1(VIA_REG_DIMENSION, (len - 1));
-        OUT_RING_H1(VIA_REG_GECMD, tdc->cmd | VIA_GEC_BLT);
+        OUT_RING_H1(VIA_REG(pVia, DSTPOS), ((y - sub) << 16) | (x & 0xFFFF));
+        OUT_RING_H1(VIA_REG(pVia, DIMENSION), (len - 1));
+        OUT_RING_H1(VIA_REG(pVia, GECMD), tdc->cmd | VIA_GEC_BLT);
     } else {
-        OUT_RING_H1(VIA_REG_DSTPOS, ((y - sub) << 16) | (x & 0xFFFF));
-        OUT_RING_H1(VIA_REG_DIMENSION, ((len - 1) << 16));
-        OUT_RING_H1(VIA_REG_GECMD, tdc->cmd | VIA_GEC_BLT);
+        OUT_RING_H1(VIA_REG(pVia, DSTPOS), ((y - sub) << 16) | (x & 0xFFFF));
+        OUT_RING_H1(VIA_REG(pVia, DIMENSION), ((len - 1) << 16));
+        OUT_RING_H1(VIA_REG(pVia, GECMD), tdc->cmd | VIA_GEC_BLT);
     }
     ADVANCE_RING;
 }
@@ -1005,7 +1156,7 @@
 
     RING_VARS;
 
-    viaAccelTransparentHelper(tdc, cb, 0x00, 0x00, FALSE);
+    viaAccelTransparentHelper(pVia, 0x00, 0x00, FALSE);
     cmd = VIA_GEC_LINE | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(rop);
 
     if (bg == -1) {
@@ -1031,10 +1182,10 @@
     tdc->dashed = TRUE;
 
     BEGIN_RING(8);
-    OUT_RING_H1(VIA_REG_GEMODE, tdc->mode);
-    OUT_RING_H1(VIA_REG_FGCOLOR, tdc->fgColor);
-    OUT_RING_H1(VIA_REG_BGCOLOR, tdc->bgColor);
-    OUT_RING_H1(VIA_REG_MONOPAT0, tdc->pattern0);
+    OUT_RING_H1(VIA_REG(pVia, GEMODE), tdc->mode);
+    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);
 }
 
 static void
@@ -1129,8 +1280,8 @@
                                CPU_TRANSFER_PAD_DWORD |
                                SCANLINE_PAD_DWORD |
                                BIT_ORDER_IN_BYTE_MSBFIRST |
-                               LEFT_EDGE_CLIPPING | ROP_NEEDS_SOURCE |
-                               SYNC_AFTER_IMAGE_WRITE | 0);
+                               LEFT_EDGE_CLIPPING | ROP_NEEDS_SOURCE | 0);
+                               // SYNC_AFTER_IMAGE_WRITE | 0);
 
     /*
      * Most Unichromes are much faster using processor-to-framebuffer writes
@@ -1140,14 +1291,19 @@
 
     if (pVia->Chipset != VIA_K8M800 &&
         pVia->Chipset != VIA_K8M890 &&
-        pVia->Chipset != VIA_P4M900)
+        pVia->Chipset != VIA_P4M900 &&
+        pVia->Chipset != VIA_VX800)
         xaaptr->ImageWriteFlags |= NO_GXCOPY;
 
     xaaptr->SetupForImageWrite = viaSetupForImageWrite;
     xaaptr->SubsequentImageWriteRect = viaSubsequentImageWriteRect;
     xaaptr->ImageWriteBase = pVia->BltBase;
-    xaaptr->ImageWriteRange = VIA_MMIO_BLTSIZE;
 
+    if (pVia->Chipset == VIA_VX800)
+        xaaptr->ImageWriteRange = VIA_MMIO_BLTSIZE;
+    else
+        xaaptr->ImageWriteRange = (64 * 1024);
+
     return XAAInit(pScreen, xaaptr);
 
 }
@@ -1173,8 +1329,8 @@
 
     if (pVia->agpDMA) {
         BEGIN_RING(2);
-        OUT_RING_H1(VIA_REG_KEYCONTROL, 0x00);
-        viaAccelSolidHelper(cb, 0, 0, 1, 1, pVia->markerOffset,
+        OUT_RING_H1(VIA_REG(pVia, KEYCONTROL), 0x00);
+        viaAccelSolidHelper(pVia, 0, 0, 1, 1, pVia->markerOffset,
                             VIA_GEM_32bpp, 4, pVia->curMarker,
                             (0xF0 << 24) | VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT);
         ADVANCE_RING;
@@ -1238,7 +1394,6 @@
 }
 
 
-#ifdef VIA_HAVE_EXA
 /*
  * Exa functions. It is assumed that EXA does not exceed the blitter limits.
  */
@@ -1259,7 +1414,7 @@
 
     if (!viaAccelPlaneMaskHelper(tdc, planeMask))
         return FALSE;
-    viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, TRUE);
+    viaAccelTransparentHelper(pVia, 0x0, 0x0, TRUE);
 
     tdc->cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(alu);
 
@@ -1283,7 +1438,7 @@
     dstPitch = exaGetPixmapPitch(pPixmap);
     dstOffset = exaGetPixmapOffset(pPixmap);
 
-    viaAccelSolidHelper(cb, x1, y1, w, h, dstOffset,
+    viaAccelSolidHelper(pVia, x1, y1, w, h, dstOffset,
                         tdc->mode, dstPitch, tdc->fgColor, tdc->cmd);
     ADVANCE_RING;
 }
@@ -1325,7 +1480,7 @@
 
     if (!viaAccelPlaneMaskHelper(tdc, planeMask))
         return FALSE;
-    viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, TRUE);
+    viaAccelTransparentHelper(pVia, 0x0, 0x0, TRUE);
 
     return TRUE;
 }
@@ -1345,7 +1500,7 @@
     if (!width || !height)
         return;
 
-    viaAccelCopyHelper(cb, srcX, srcY, dstX, dstY, width, height,
+    viaAccelCopyHelper(pVia, srcX, srcY, dstX, dstY, width, height,
                        srcOffset, dstOffset, tdc->mode, tdc->srcPitch,
                        exaGetPixmapPitch(pDstPixmap), tdc->cmd);
     ADVANCE_RING;
@@ -1905,6 +2060,9 @@
         pMaskPicture->pDrawable->height < VIA_MIN_COMPOSITE)
         return FALSE;
 
+    if (pMaskPicture->repeat != RepeatNormal)
+        return FALSE;
+
     if (pMaskPicture && pMaskPicture->componentAlpha) {
 #ifdef VIA_DEBUG_COMPOSITE
         ErrorF("Component Alpha operation\n");
@@ -2110,7 +2268,6 @@
                   width, height);
 }
 
-#if (EXA_VERSION_MAJOR >= 2)
 
 static ExaDriverPtr
 viaInitExa(ScreenPtr pScreen)
@@ -2185,80 +2342,8 @@
     return pExa;
 }
 
-#else
 
 /*
- * Initialize EXA. Alignments are 2D engine constraints.
- */
-static ExaDriverPtr
-viaInitExa(ScreenPtr pScreen)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    VIAPtr pVia = VIAPTR(pScrn);
-    ExaDriverPtr pExa = (ExaDriverPtr) xnfcalloc(sizeof(ExaDriverRec), 1);
-
-    if (!pExa)
-        return NULL;
-
-    pExa->card.memoryBase = pVia->FBBase;
-    pExa->card.memorySize = pVia->FBFreeEnd;
-    pExa->card.offScreenBase = pScrn->virtualY * pVia->Bpl;
-    pExa->card.pixmapOffsetAlign = 32;
-    pExa->card.pixmapPitchAlign = 16;
-    pExa->card.flags = EXA_OFFSCREEN_PIXMAPS |
-            (pVia->nPOT[1] ? 0 : EXA_OFFSCREEN_ALIGN_POT);
-    pExa->card.maxX = 2047;
-    pExa->card.maxY = 2047;
-
-    pExa->accel.WaitMarker = viaAccelWaitMarker;
-    pExa->accel.MarkSync = viaAccelMarkSync;
-    pExa->accel.PrepareSolid = viaExaPrepareSolid;
-    pExa->accel.Solid = viaExaSolid;
-    pExa->accel.DoneSolid = viaExaDoneSolidCopy;
-    pExa->accel.PrepareCopy = viaExaPrepareCopy;
-    pExa->accel.Copy = viaExaCopy;
-    pExa->accel.DoneCopy = viaExaDoneSolidCopy;
-
-#ifdef XF86DRI
-    if (pVia->directRenderingEnabled) {
-#ifdef linux
-        if ((pVia->drmVerMajor > 2) ||
-            ((pVia->drmVerMajor == 2) && (pVia->drmVerMinor >= 7))) {
-            if (pVia->Chipset != VIA_K8M800)
-                pExa->accel.UploadToScreen = viaExaUploadToScreen;
-            pExa->accel.DownloadFromScreen = viaExaDownloadFromScreen;
-        }
-#endif /* linux */
-        if (pVia->Chipset == VIA_K8M800)
-            pExa->accel.UploadToScreen = viaExaTexUploadToScreen;
-    }
-#endif /* XF86DRI */
-
-    pExa->accel.UploadToScratch = viaExaUploadToScratch;
-
-    if (!pVia->noComposite) {
-        pExa->accel.CheckComposite = viaExaCheckComposite;
-        pExa->accel.PrepareComposite = viaExaPrepareComposite;
-        pExa->accel.Composite = viaExaComposite;
-        pExa->accel.DoneComposite = viaExaDoneSolidCopy;
-    } else {
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                   "[EXA] Disabling EXA accelerated composite.\n");
-    }
-
-    if (!exaDriverInit(pScreen, pExa)) {
-        xfree(pExa);
-        return NULL;
-    }
-
-    viaInit3DState(&pVia->v3d);
-    return pExa;
-}
-
-#endif /* EXA_VERSION_MAJOR */
-#endif /* VIA_HAVE_EXA */
-
-/*
  * Acceleration initializatuon function. Sets up offscreen memory disposition,
  * and initializes engines and acceleration method.
  */
@@ -2273,16 +2358,14 @@
 
     pVia->VQStart = 0;
     if (((pVia->FBFreeEnd - pVia->FBFreeStart) >= VIA_VQ_SIZE)
-        && pVia->VQEnable) {
-        pVia->VQStart = pVia->FBFreeEnd - VIA_VQ_SIZE;
-        pVia->VQEnd = pVia->VQStart + VIA_VQ_SIZE - 1;
-        pVia->FBFreeEnd -= VIA_VQ_SIZE;
+	&& pVia->VQEnable) {
+	pVia->VQStart = pVia->FBFreeEnd - VIA_VQ_SIZE;
+	pVia->VQEnd = pVia->VQStart + VIA_VQ_SIZE - 1;
+	pVia->FBFreeEnd -= VIA_VQ_SIZE;
     }
 
-    if (pVia->hwcursor) {
-        pVia->FBFreeEnd -= VIA_CURSOR_SIZE;
-        pVia->CursorStart = pVia->FBFreeEnd;
-    }
+    if (pVia->hwcursor)
+        viaCursorSetFB(pScrn);
 
     viaInitialize2DEngine(pScrn);
 
@@ -2309,7 +2392,6 @@
     pVia->nPOT[0] = nPOTSupported;
     pVia->nPOT[1] = nPOTSupported;
 
-#ifdef VIA_HAVE_EXA
 #ifdef XF86DRI
     pVia->texAddr = NULL;
     pVia->dBounce = NULL;
@@ -2342,7 +2424,6 @@
                    "[EXA] Enabled EXA acceleration.\n");
         return TRUE;
     }
-#endif /* VIA_HAVE_EXA */
 
     AvailFBArea.x1 = 0;
     AvailFBArea.y1 = 0;
@@ -2395,7 +2476,6 @@
     viaAccelSync(pScrn);
     viaTearDownCBuffer(&pVia->cb);
 
-#ifdef VIA_HAVE_EXA
     if (pVia->useEXA) {
 #ifdef XF86DRI
         if (pVia->directRenderingEnabled) {
@@ -2426,7 +2506,6 @@
         pVia->exaDriverPtr = NULL;
         return;
     }
-#endif /* VIA_HAVE_EXA */
     if (pVia->AccelInfoRec) {
         XAADestroyInfoRec(pVia->AccelInfoRec);
         pVia->AccelInfoRec = NULL;
@@ -2444,7 +2523,6 @@
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     VIAPtr pVia = VIAPTR(pScrn);
 
-#ifdef VIA_HAVE_EXA
 #ifdef XF86DRI
     int size, ret;
 
@@ -2455,12 +2533,7 @@
         if (!pVia->IsPCI) {
 
             /* Allocate upload and scratch space. */
-#if (EXA_VERSION_MAJOR >= 2)
             if (pVia->exaDriverPtr->UploadToScreen == viaExaTexUploadToScreen) {
-#else
-            if (pVia->exaDriverPtr->accel.UploadToScreen ==
-                viaExaTexUploadToScreen) {
-#endif
                 size = VIA_AGP_UPL_SIZE * 2 + 32;
                 pVia->texAGPBuffer.context = 1;
                 pVia->texAGPBuffer.size = size;
@@ -2516,7 +2589,6 @@
             pVia->scratchAddr = (char *)pVia->FBBase + pVia->scratchOffset;
         }
     }
-#endif /* VIA_HAVE_EXA */
     if (Success != viaSetupCBuffer(pScrn, &pVia->cb, 0)) {
         pVia->NoAccel = TRUE;
         viaExitAccel(pScreen);
@@ -2554,8 +2626,8 @@
             cmd |= VIA_GEC_DECY;
 
         viaAccelSetMode(pScrn->bitsPerPixel, tdc);
-        viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, FALSE);
-        viaAccelCopyHelper(cb, srcx, 0, dstx, 0, w, h, srcOffset, dstOffset,
+        viaAccelTransparentHelper(pVia, 0x0, 0x0, FALSE);
+        viaAccelCopyHelper(pVia, srcx, 0, dstx, 0, w, h, srcOffset, dstOffset,
                            tdc->mode, pVia->Bpl, pVia->Bpl, cmd);
         pVia->accelMarker = viaAccelMarkSync(pScrn->pScreen);
         ADVANCE_RING;
@@ -2578,8 +2650,8 @@
 
     if (!pVia->NoAccel) {
         viaAccelSetMode(pScrn->bitsPerPixel, tdc);
-        viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, FALSE);
-        viaAccelSolidHelper(cb, x, 0, w, h, dstBase, tdc->mode,
+        viaAccelTransparentHelper(pVia, 0x0, 0x0, FALSE);
+        viaAccelSolidHelper(pVia, x, 0, w, h, dstBase, tdc->mode,
                             pVia->Bpl, color, cmd);
         pVia->accelMarker = viaAccelMarkSync(pScrn->pScreen);
         ADVANCE_RING;
@@ -2604,8 +2676,8 @@
 
     if (!pVia->NoAccel) {
         viaAccelSetMode(depth, tdc);
-        viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, FALSE);
-        viaAccelSolidHelper(cb, x, 0, w, h, dstBase, tdc->mode,
+        viaAccelTransparentHelper(pVia, 0x0, 0x0, FALSE);
+        viaAccelSolidHelper(pVia, x, 0, w, h, dstBase, tdc->mode,
                             pitch, color, cmd);
         pVia->accelMarker = viaAccelMarkSync(pScrn->pScreen);
         ADVANCE_RING;
Index: src/via_memory.c
===================================================================
--- src/via_memory.c	(.../tags/release_0_2_903)	(revision 751)
+++ src/via_memory.c	(.../trunk)	(revision 751)
@@ -52,7 +52,6 @@
  *	2  -  DRM
  */
 
-#ifdef VIA_HAVE_EXA
 static void
 viaExaFBSave(ScreenPtr pScreen, ExaOffscreenArea * exa)
 {
@@ -61,7 +60,6 @@
                "\t\thttp://wiki.openchrome.org/tikiwiki/tiki-index"
                ".php?page=EXAAcceleration .\n");
 }
-#endif
 
 void
 VIAFreeLinear(VIAMemPtr mem)
@@ -71,7 +69,6 @@
         case 0:
             return;
         case 1:
-#ifdef VIA_HAVE_EXA
             {
                 VIAPtr pVia = VIAPTR(mem->pScrn);
 
@@ -82,7 +79,6 @@
                     return;
                 }
             }
-#endif
             xf86FreeOffscreenLinear(mem->linear);
             mem->linear = NULL;
             mem->pool = 0;
@@ -103,7 +99,6 @@
 {
     int depth = pScrn->bitsPerPixel >> 3;
 
-#ifdef VIA_HAVE_EXA
     VIAPtr pVia = VIAPTR(pScrn);
 
     if (pVia->useEXA && !pVia->NoAccel) {
@@ -118,7 +113,6 @@
         mem->pScrn = pScrn;
         return Success;
     }
-#endif
 
     mem->linear = xf86AllocateOffscreenLinear(pScrn->pScreen,
                                               (size + depth - 1) / depth,
@@ -175,11 +169,9 @@
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     VIAPtr pVia = VIAPTR(pScrn);
 
-#ifdef VIA_HAVE_EXA
     if (pVia->useEXA && !pVia->NoAccel)
         return;
     else
-#endif
     {
         unsigned long offset = (pVia->FBFreeStart + pVia->Bpp - 1) / pVia->Bpp;
         long size = pVia->FBFreeEnd / pVia->Bpp - offset;
Index: src/via_vbe.c
===================================================================
--- src/via_vbe.c	(.../tags/release_0_2_903)	(revision 751)
+++ src/via_vbe.c	(.../trunk)	(revision 751)
@@ -95,7 +95,7 @@
     /* Set Active Device and translate BIOS byte definition. */
     if (pBIOSInfo->CrtActive)
         activeDevices = 0x01;
-    if (pBIOSInfo->PanelActive)
+    if (pBIOSInfo->Panel->IsActive)
         activeDevices |= 0x02;
     if (pBIOSInfo->TVActive)
         activeDevices |= 0x04;
@@ -244,7 +244,7 @@
         }
     } else {
 
-        if (pBIOSInfo->PanelActive && !pVia->useLegacyVBE) {
+        if (pBIOSInfo->Panel->IsActive && !pVia->useLegacyVBE) {
             /* 
              * FIXME: Should we always set the panel expansion?
              * Does it depend on the resolution?
@@ -437,7 +437,7 @@
     VIAPtr pVia = VIAPTR(pScrn);
     VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
 
-    if (pBIOSInfo->PanelActive)
+    if (pBIOSInfo->Panel->IsActive)
         ViaVbePanelPower(pVia->pVbe, (mode == DPMSModeOn));
 
     VBEDPMSSet(pVia->pVbe, mode);
Index: src/via_cursor.c
===================================================================
--- src/via_cursor.c	(.../tags/release_0_2_903)	(revision 751)
+++ src/via_cursor.c	(.../trunk)	(revision 751)
@@ -1,5 +1,6 @@
 /*
- * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2007 The Openchrome Project [openchrome.org]
+ * Copyright 1998-2007 VIA Technologies, Inc. All Rights Reserved.
  * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -35,20 +36,93 @@
 
 #include "via.h"
 #include "via_driver.h"
+#include "via_id.h"
+#include "cursorstr.h"
 
-static void VIALoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
-static void VIASetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
-static void VIASetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
+void viaShowCursor(ScrnInfoPtr pScrn);
+void viaHideCursor(ScrnInfoPtr pScrn);
+static void viaSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
+static Bool viaUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs);
+static Bool viaUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs);
+static void viaLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
+static void viaSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
+static void viaLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs);
 
-#define MAX_CURS 32
+static CARD32 mono_cursor_color[] = {
+	0x00000000,
+	0x00000000,
+	0xffffffff,
+	0xff000000,
+};
 
 Bool
-VIAHWCursorInit(ScreenPtr pScreen)
+viaHWCursorInit(ScreenPtr pScreen)
 {
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     VIAPtr pVia = VIAPTR(pScrn);
     xf86CursorInfoPtr infoPtr;
 
+	switch (pVia->Chipset) {
+		case VIA_CLE266:
+		case VIA_KM400:
+			/* FIXME Mono HW Cursors not working */
+			pVia->hwcursor = FALSE;
+			pVia->CursorARGBSupported = FALSE;
+			pVia->CursorMaxWidth = 32;
+			pVia->CursorMaxHeight = 32;
+			pVia->CursorSize = ((pVia->CursorMaxWidth * pVia->CursorMaxHeight) / 8) * 2;
+			break;
+		default:
+			pVia->CursorARGBSupported = TRUE;
+			pVia->CursorMaxWidth = 64;
+			pVia->CursorMaxHeight = 64;
+			pVia->CursorSize = pVia->CursorMaxWidth * (pVia->CursorMaxHeight + 1) * 4;
+			break;
+    }
+
+    if (pVia->NoAccel) 
+    	viaCursorSetFB(pScrn);
+
+    pVia->cursorMap = pVia->FBBase + pVia->CursorStart;
+
+    if (pVia->cursorMap == NULL)
+		return FALSE;
+
+    pVia->cursorOffset = pScrn->fbOffset + pVia->CursorStart;
+    memset(pVia->cursorMap, 0x00, pVia->CursorSize);
+
+    switch (pVia->Chipset) {
+        case VIA_CX700:
+        /* case VIA_CN750: */
+        case VIA_P4M890:
+        case VIA_P4M900:
+        case VIA_VX800:
+			if (pVia->pBIOSInfo->FirstCRTC->IsActive) {
+				pVia->CursorRegControl  = VIA_REG_HI_CONTROL0;
+				pVia->CursorRegBase     = VIA_REG_HI_BASE0;
+				pVia->CursorRegPos      = VIA_REG_HI_POS0;
+				pVia->CursorRegOffset   = VIA_REG_HI_OFFSET0;
+				pVia->CursorRegFifo     = VIA_REG_HI_FIFO0;
+				pVia->CursorRegTransKey = VIA_REG_HI_TRANSKEY0;
+			}
+			if (pVia->pBIOSInfo->SecondCRTC->IsActive) {
+				pVia->CursorRegControl  = VIA_REG_HI_CONTROL1;
+				pVia->CursorRegBase     = VIA_REG_HI_BASE1;
+				pVia->CursorRegPos      = VIA_REG_HI_POS1;
+				pVia->CursorRegOffset   = VIA_REG_HI_OFFSET1;
+				pVia->CursorRegFifo     = VIA_REG_HI_FIFO1;
+				pVia->CursorRegTransKey = VIA_REG_HI_TRANSKEY1;
+			}
+			break;
+		default:
+			pVia->CursorRegControl = VIA_REG_ALPHA_CONTROL;
+			pVia->CursorRegBase = VIA_REG_ALPHA_BASE;
+			pVia->CursorRegPos = VIA_REG_ALPHA_POS;
+			pVia->CursorRegOffset = VIA_REG_ALPHA_OFFSET;
+			pVia->CursorRegFifo = VIA_REG_ALPHA_FIFO;
+			pVia->CursorRegTransKey = VIA_REG_ALPHA_TRANSKEY;
+    }
+
     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAHWCursorInit\n"));
     infoPtr = xf86CreateCursorInfoRec();
     if (!infoPtr)
@@ -56,168 +130,361 @@
 
     pVia->CursorInfoRec = infoPtr;
 
-    infoPtr->MaxWidth = MAX_CURS;
-    infoPtr->MaxHeight = MAX_CURS;
-    infoPtr->Flags = (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 |
+    infoPtr->MaxWidth = pVia->CursorMaxWidth;
+    infoPtr->MaxHeight = pVia->CursorMaxHeight;
+    infoPtr->Flags = (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 |
                       HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
-                      /*HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | */
                       HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
-                      HARDWARE_CURSOR_INVERT_MASK |
-                      HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
                       0);
 
-    infoPtr->SetCursorColors = VIASetCursorColors;
-    infoPtr->SetCursorPosition = VIASetCursorPosition;
-    infoPtr->LoadCursorImage = VIALoadCursorImage;
-    infoPtr->HideCursor = VIAHideCursor;
-    infoPtr->ShowCursor = VIAShowCursor;
-    infoPtr->UseHWCursor = NULL;
+    infoPtr->SetCursorColors = viaSetCursorColors;
+    infoPtr->SetCursorPosition = viaSetCursorPosition;
+    infoPtr->LoadCursorImage = viaLoadCursorImage;
+    infoPtr->HideCursor = viaHideCursor;
+    infoPtr->ShowCursor = viaShowCursor;
+    infoPtr->UseHWCursor = viaUseHWCursor;
 
-    if (!pVia->CursorStart) {
-        pVia->CursorStart = pVia->FBFreeEnd - VIA_CURSOR_SIZE;
-        pVia->FBFreeEnd -= VIA_CURSOR_SIZE;
-    }
+    infoPtr->UseHWCursorARGB = viaUseHWCursorARGB;
+	if (pVia->CursorARGBSupported)
+    	infoPtr->LoadCursorARGB = viaLoadCursorARGB;
 
     /* Set cursor location in frame buffer. */
-    VIASETREG(VIA_REG_CURSOR_MODE, pVia->CursorStart);
+    VIASETREG(VIA_REG_CURSOR_MODE, pVia->cursorOffset);
 
+    pVia->CursorPipe = (pVia->pBIOSInfo->Panel->IsActive) ? 1 : 0;
+
+    /* Init HI_X0 */
+    VIASETREG(pVia->CursorRegControl, 0);
+    VIASETREG(pVia->CursorRegBase, pVia->cursorOffset);
+    VIASETREG(pVia->CursorRegTransKey, 0);
+
+    switch (pVia->Chipset) {
+        case VIA_CX700:
+        /* case VIA_CN750: */
+        case VIA_P4M890:
+        case VIA_P4M900:
+        case VIA_VX800:
+			if (pVia->pBIOSInfo->FirstCRTC->IsActive) {
+				VIASETREG(VIA_REG_PRIM_HI_INVTCOLOR, 0x00FFFFFF);
+				VIASETREG(VIA_REG_V327_HI_INVTCOLOR, 0x00FFFFFF);
+				VIASETREG(pVia->CursorRegFifo, 0x0D000D0F);
+			}
+			if (pVia->pBIOSInfo->SecondCRTC->IsActive) {
+				VIASETREG(VIA_REG_HI_INVTCOLOR, 0X00FFFFFF);
+				VIASETREG(VIA_REG_ALPHA_PREFIFO, 0xE0000);
+				VIASETREG(pVia->CursorRegFifo, 0xE0F0000);
+
+				/* Just in case */
+				VIASETREG(VIA_REG_HI_BASE0, pVia->cursorOffset);
+			}
+			break;
+    	default:
+			VIASETREG(VIA_REG_HI_INVTCOLOR, 0X00FFFFFF);
+			VIASETREG(VIA_REG_ALPHA_PREFIFO, 0xE0000);
+			VIASETREG(pVia->CursorRegFifo, 0xE0F0000);
+	}
+
     return xf86InitCursor(pScreen, infoPtr);
 }
 
+void
+viaCursorSetFB(ScrnInfoPtr pScrn)
+{
+    VIAPtr pVia = VIAPTR(pScrn);
 
+    if ((pVia->FBFreeEnd - pVia->FBFreeStart) > pVia->CursorSize) {
+        pVia->CursorStart = pVia->FBFreeEnd - pVia->CursorSize;
+        pVia->FBFreeEnd = pVia->CursorStart;
+        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CursorStart: 0x%x\n", pVia->CursorStart);
+    }
+}
+
+
 void
-VIAShowCursor(ScrnInfoPtr pScrn)
+viaCursorStore(ScrnInfoPtr pScrn)
 {
     VIAPtr pVia = VIAPTR(pScrn);
-    CARD32 dwCursorMode;
 
-    dwCursorMode = VIAGETREG(VIA_REG_CURSOR_MODE);
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaCursorStore\n"));
 
-    /* Turn on hardware cursor. */
-    VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode | 0x3);
+    if (pVia->CursorPipe) {
+		pVia->CursorControl1 = VIAGETREG(pVia->CursorRegControl);
+    } else {
+		pVia->CursorControl0 = VIAGETREG(pVia->CursorRegControl);
+    }
+
+    pVia->CursorTransparentKey = VIAGETREG(pVia->CursorRegTransKey);
+
+
+    switch (pVia->Chipset) {
+        case VIA_CX700:
+        /* case VIA_CN750: */
+        case VIA_P4M890:
+        case VIA_P4M900:
+        case VIA_VX800:
+			if (pVia->pBIOSInfo->FirstCRTC->IsActive) {
+	    		pVia->CursorPrimHiInvtColor = VIAGETREG(VIA_REG_PRIM_HI_INVTCOLOR);
+	    		pVia->CursorV327HiInvtColor = VIAGETREG(VIA_REG_V327_HI_INVTCOLOR);
+			} 
+			if (pVia->pBIOSInfo->SecondCRTC->IsActive) {
+	    	/* TODO add saves here */
+			}
+			pVia->CursorFifo = VIAGETREG(pVia->CursorRegFifo);
+			break;
+		default:
+			/* TODO add saves here */
+			break;
+    }
 }
 
-
 void
-VIAHideCursor(ScrnInfoPtr pScrn)
+viaCursorRestore(ScrnInfoPtr pScrn)
 {
     VIAPtr pVia = VIAPTR(pScrn);
-    CARD32 dwCursorMode;
 
-    dwCursorMode = VIAGETREG(VIA_REG_CURSOR_MODE);
+    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaCursorRestore\n"));
 
-    /* Turn cursor off. */
-    VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode & 0xFFFFFFFE);
+    if (pVia->CursorPipe) {
+		VIASETREG(pVia->CursorRegControl, pVia->CursorControl1);
+    } else {
+		VIASETREG(pVia->CursorRegControl, pVia->CursorControl0);
+    }
+
+    VIASETREG(pVia->CursorRegBase, pVia->cursorOffset);
+
+    VIASETREG(pVia->CursorRegTransKey, pVia->CursorTransparentKey);
+
+
+    switch (pVia->Chipset) {
+        case VIA_CX700:
+        /* case VIA_CN750: */
+        case VIA_P4M890:
+        case VIA_P4M900:
+        case VIA_VX800:
+			if (pVia->pBIOSInfo->FirstCRTC->IsActive) {
+	    		VIASETREG(VIA_REG_PRIM_HI_INVTCOLOR, pVia->CursorPrimHiInvtColor);
+	    		VIASETREG(VIA_REG_V327_HI_INVTCOLOR, pVia->CursorV327HiInvtColor);
+			}
+			if (pVia->pBIOSInfo->SecondCRTC->IsActive) {
+	    		/* TODO add real restores here */
+	    		VIASETREG(VIA_REG_HI_INVTCOLOR, 0X00FFFFFF);
+	    		VIASETREG(VIA_REG_ALPHA_PREFIFO, 0xE0000);
+			}
+			VIASETREG(pVia->CursorRegFifo, pVia->CursorFifo);
+			break;
+		default:
+			/* TODO add real restores here */
+			VIASETREG(VIA_REG_ALPHA_PREFIFO, 0xE0000);
+			VIASETREG(pVia->CursorRegFifo, 0xE0F0000);
+    }
 }
 
+/*
+ * ARGB Cursor
+ */
 
-static void
-VIALoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
+void
+viaShowCursor(ScrnInfoPtr pScrn)
 {
     VIAPtr pVia = VIAPTR(pScrn);
-    CARD32 dwCursorMode;
+    CARD32 temp;
+    CARD32 control = pVia->CursorRegControl;
 
-    viaAccelSync(pScrn);
+    temp =
+	(1 << 30) |
+	(1 << 29) |
+	(1 << 28) |
+	(1 << 26) |
+	(1 << 25) |
+	(1 <<  2) |
+	(1 <<  0);
 
-    dwCursorMode = VIAGETREG(VIA_REG_CURSOR_MODE);
+    if (pVia->CursorPipe)
+	temp |= (1 << 31);
 
-    /* Turn cursor off. */
-    VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode & 0xFFFFFFFE);
+    VIASETREG(control, temp);
+}
 
-    /* Upload the cursor image to the frame buffer. */
-    memcpy(pVia->FBBase + pVia->CursorStart, src, MAX_CURS * MAX_CURS / 8 * 2);
+void
+viaHideCursor(ScrnInfoPtr pScrn)
+{
+    VIAPtr pVia = VIAPTR(pScrn);
+    CARD32 temp;
+    CARD32 control = pVia->CursorRegControl;
 
-    /* Restore cursor status */
-    VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode);
+    temp = VIAGETREG(control);
+    VIASETREG(control, temp & 0xFFFFFFFE);
 }
 
 static void
-VIASetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+viaSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
 {
     VIAPtr pVia = VIAPTR(pScrn);
-    VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
-    unsigned char xoff, yoff;
-    CARD32 dwCursorMode;
+    CARD32 temp;
+    CARD32 control = pVia->CursorRegControl;
+    CARD32 offset = pVia->CursorRegOffset;
+    CARD32 pos = pVia->CursorRegPos;
+    unsigned xoff, yoff;
 
     if (x < 0) {
-        xoff = ((-x) & 0xFE);
-        x = 0;
+	xoff = ((-x) & 0xFE);
+	x = 0;
     } else {
-        xoff = 0;
+	xoff = 0;
     }
 
     if (y < 0) {
-        yoff = ((-y) & 0xFE);
-        y = 0;
+	yoff = ((-y) & 0xFE);
+	y = 0;
     } else {
-        yoff = 0;
-        /* LCD Expand Mode Cursor Y Position Re-Calculated */
-        if (pBIOSInfo->scaleY) {
-            y = (int)(((pBIOSInfo->panelY * y) + (pBIOSInfo->resY >> 1))
-                      / pBIOSInfo->resY);
-        }
+	yoff = 0;
     }
 
-    /* Hide cursor before set cursor position in order to avoid ghost cursor
-     * image when directly set cursor position. It should be a HW bug but
-     * we can use patch by SW. */
-    dwCursorMode = VIAGETREG(VIA_REG_CURSOR_MODE);
+    temp = VIAGETREG(control);
+    VIASETREG(control, temp & 0xFFFFFFFE);
 
-    /* Turn cursor off. */
-    VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode & 0xFFFFFFFE);
+    VIASETREG(pos,    ((x    << 16) | (y    & 0x07ff)));
+    VIASETREG(offset, ((xoff << 16) | (yoff & 0x07ff)));
 
-    VIASETREG(VIA_REG_CURSOR_ORG, ((xoff << 16) | (yoff & 0x003f)));
-    VIASETREG(VIA_REG_CURSOR_POS, ((x << 16) | (y & 0x07ff)));
+    VIASETREG(control, temp);
+}
 
-    /* Restore cursor status */
-    VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode);
+static Bool
+viaUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    VIAPtr pVia = VIAPTR(pScrn);
+
+    return (pVia->hwcursor
+            && pVia->CursorARGBSupported
+            && pCurs->bits->width <= pVia->CursorMaxWidth
+            && pCurs->bits->height <= pVia->CursorMaxHeight);
 }
 
+static Bool
+viaUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    VIAPtr pVia = VIAPTR(pScrn);
 
+    return (pVia->hwcursor
+            /* Can't enable HW cursor on both CRTCs at the same time. */
+            && !(pVia->pBIOSInfo->FirstCRTC->IsActive
+                 && pVia->pBIOSInfo->SecondCRTC->IsActive)
+            && pCurs->bits->width <= pVia->CursorMaxWidth
+            && pCurs->bits->height <= pVia->CursorMaxHeight);
+}
+
 static void
-VIASetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+viaLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *s)
 {
     VIAPtr pVia = VIAPTR(pScrn);
+    CARD32 control = pVia->CursorRegControl;
+    CARD32 temp;
+    CARD32 *dst;
+    CARD8 *src;
+    CARD8 chunk;
+    int i, j;
 
-    VIASETREG(VIA_REG_CURSOR_FG, fg);
-    VIASETREG(VIA_REG_CURSOR_BG, bg);
+    temp = VIAGETREG(control);
+    VIASETREG(control, temp & 0xFFFFFFFE);
+
+    pVia->CursorARGB = FALSE;
+
+    dst = (CARD32*)(pVia->cursorMap);
+    src = (CARD8*)s;
+
+    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++;
+		for (j = 0; j < ARGB_PER_CHUNK; j++, chunk >>= 2)
+			*dst++ = mono_cursor_color[chunk & 3];
+		}
+
+		pVia->CursorFG = mono_cursor_color[3];
+		pVia->CursorBG = mono_cursor_color[2];
+	} else {
+		memcpy(dst, src, pVia->CursorSize);
+	}
+
+    VIASETREG(control, temp);
 }
 
-void
-ViaCursorStore(ScrnInfoPtr pScrn)
+static void
+viaSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
 {
     VIAPtr pVia = VIAPTR(pScrn);
+    CARD32 control = pVia->CursorRegControl;
+    CARD32 pixel;
+    CARD32 temp;
+    CARD32 *dst;
+    int i;
 
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaCursorStore\n"));
+    if (pVia->CursorFG)
+	return;
 
-    if (pVia->CursorImage) {
-        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "ViaCursorStore: stale image left.\n");
-        xfree(pVia->CursorImage);
-    }
+    fg |= 0xff000000;
+    bg |= 0xff000000;
 
-    pVia->CursorImage = xcalloc(1, 0x1000);
-    memcpy(pVia->CursorImage, pVia->FBBase + pVia->CursorStart, 0x1000);
-    pVia->CursorFG = (CARD32) VIAGETREG(VIA_REG_CURSOR_FG);
-    pVia->CursorBG = (CARD32) VIAGETREG(VIA_REG_CURSOR_BG);
-    pVia->CursorMC = (CARD32) VIAGETREG(VIA_REG_CURSOR_MODE);
+    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))
+	    *dst = (pixel == pVia->CursorFG) ? fg : bg;
+
+    pVia->CursorFG = fg;
+    pVia->CursorBG = bg;
+
+    VIASETREG(control, temp);
 }
 
-void
-ViaCursorRestore(ScrnInfoPtr pScrn)
+static void
+viaLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs)
 {
     VIAPtr pVia = VIAPTR(pScrn);
+    CARD32 control = pVia->CursorRegControl;
+    int x, y, w, h;
+    CARD32 *image;
+    CARD32 *dst;
+    CARD32 *src;
+    CARD32 temp;
 
-    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaCursorRestore\n"));
+    temp = VIAGETREG(control);
+    VIASETREG(control, temp & 0xFFFFFFFE);
 
-    if (pVia->CursorImage) {
-        memcpy(pVia->FBBase + pVia->CursorStart, pVia->CursorImage, 0x1000);
-        VIASETREG(VIA_REG_CURSOR_FG, pVia->CursorFG);
-        VIASETREG(VIA_REG_CURSOR_BG, pVia->CursorBG);
-        VIASETREG(VIA_REG_CURSOR_MODE, pVia->CursorMC);
-        xfree(pVia->CursorImage);
-        pVia->CursorImage = NULL;
-    } else
-        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "ViaCursorRestore: No cursor image stored.\n");
+    pVia->CursorARGB = TRUE;
+
+    dst = (CARD32*)pVia->cursorMap;
+    image = pCurs->bits->argb;
+
+    w = pCurs->bits->width;
+    if (w > pVia->CursorMaxWidth)
+	w = pVia->CursorMaxWidth;
+
+    h = pCurs->bits->height;
+    if (h > pVia->CursorMaxHeight)
+	h = pVia->CursorMaxHeight;
+
+    for (y = 0; y < h; y++) {
+
+	src = image;
+	image += pCurs->bits->width;
+
+	for (x = 0; x < w; x++)
+	    *dst++ = *src++;
+	for (; x < pVia->CursorMaxHeight; x++)
+	    *dst++ = 0;
+    }
+
+    for (; y < pVia->CursorMaxHeight; y++)
+	for (x = 0; x < pVia->CursorMaxWidth; x++)
+	    *dst++ = 0;
+
+    VIASETREG(control, temp);
 }
Index: src/via_xvmc.c
===================================================================
--- src/via_xvmc.c	(.../tags/release_0_2_903)	(revision 751)
+++ src/via_xvmc.c	(.../trunk)	(revision 751)
@@ -114,11 +114,7 @@
 static int viaXvMCInterceptPutImage(ScrnInfoPtr, short, short, short, short,
                                     short, short, short, short, int,
                                     unsigned char *, short, short, Bool,
-                                    RegionPtr, pointer
-#ifdef USE_NEW_XVABI
-                                    , DrawablePtr
-#endif
-        );
+                                    RegionPtr, pointer, DrawablePtr);
 static int viaXvMCInterceptXvGetAttribute(ScrnInfoPtr pScrn, Atom attribute,
                                           INT32 * value, pointer data);
 
@@ -325,6 +321,7 @@
 
     if ((pVia->Chipset == VIA_KM400) ||
         (pVia->Chipset == VIA_CX700) ||
+        (pVia->Chipset == VIA_VX800) ||
         (pVia->Chipset == VIA_K8M890) ||
         (pVia->Chipset == VIA_P4M900)) {
         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -923,11 +920,7 @@
                          short src_h, short drw_w, short drw_h,
                          int id, unsigned char *buf, short width,
                          short height, Bool sync, RegionPtr clipBoxes,
-                         pointer data
-#ifdef USE_NEW_XVABI
-                         , DrawablePtr pDraw
-#endif
-        )
+                         pointer data, DrawablePtr pDraw)
 {
     viaPortPrivPtr pPriv = (viaPortPrivPtr) data;
     ViaXvMCXVPriv *vx = (ViaXvMCXVPriv *) pPriv->xvmc_priv;
@@ -984,11 +977,7 @@
     }
     return vx->PutImage(pScrn, src_x, src_y, drw_x, drw_y, src_w, src_h,
                         drw_w, drw_h, id, buf, width, height, sync, clipBoxes,
-                        data
-#ifdef USE_NEW_XVABI
-                        , pDraw
-#endif
-            );
+                        data, pDraw);
 }
 
 unsigned long
Index: src/via_dri.c
===================================================================
--- src/via_dri.c	(.../tags/release_0_2_903)	(revision 751)
+++ src/via_dri.c	(.../trunk)	(revision 751)
@@ -588,7 +588,16 @@
 
     pDRIInfo = pVia->pDRIInfo;
     pDRIInfo->drmDriverName = VIAKernelDriverName;
-    pDRIInfo->clientDriverName = VIAClientDriverName;
+    switch (pVia->Chipset) {
+        case VIA_K8M890:
+        case VIA_P4M900:
+        case VIA_VX800:
+            pDRIInfo->clientDriverName = "swrast";
+            break;
+        default:
+            pDRIInfo->clientDriverName = VIAClientDriverName;
+            break;
+    }
     pDRIInfo->busIdString = xalloc(64);
     sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d",
 #ifdef XSERVER_LIBPCIACCESS
Index: src/via_vt162x.h
===================================================================
--- src/via_vt162x.h	(.../tags/release_0_2_903)	(revision 751)
+++ src/via_vt162x.h	(.../trunk)	(revision 751)
@@ -926,6 +926,23 @@
       0x0, 0x0,
     },
 
+    { "640x480", 640, 480, TVTYPE_PAL, 0, 0,
+      /*  00                                                                                         0F */
+      { 0x03,    0, 0x10, 0x1F, 0x03,    0,    0, 0xF2,  0x42, 0x0A, 0x88, 0x00, 0x55, 0x5E,    0, 0xB0,
+           0, 0x80, 0x0A, 0x09, 0x19, 0x28, 0xCB, 0x8A,  0x09, 0x2A,    0, 0x50, 0x41, 0x80,    0, 0x10,
+        0x17, 0x1C, 0x35, 0x7D, 0x02,    0,    0,    0,     0,    0,    0,    0,    0,    0,    0,    0 },
+      /*  4A                            4F    50                                                     59 */
+      { 0xC5, 0x0F,    0, 0x01, 0x10, 0x51, 0xE7, 0x81,  0x23, 0x57, 0x22, 0x5F, 0x6F, 0x7F, 0x23, 0x94,
+      /*  5A                            5F    60                       64 */
+        0xD0, 0x1C, 0x8F, 0x16, 0xE1, 0x38, 0x7A, 0x28,  0xFF, 0xBF, 0x03 },
+      /* RBG 65,66,67,27,2b,2c */
+      { 0x6A, 0x62, 0x65, 0x8D, 0x96, 0x20 },
+      /* Y-Cb-Cr 65,66,67 */
+      { 0x42, 0x49, 0x49 },
+      /* Subcarrier 19,18,17,16, DotCrawl Subcarrier (set bit 3 of reg 11 then subcarrier) */
+      0x2D66772D, 0,
+    },
+
     { "720x576", 720, 576, TVTYPE_PAL, 0, 0,
       /*  00                                                                                         0F */
       { 0x03, 0x00, 0x10, 0x1f, 0x03, 0x00, 0x00, 0xc9,  0x4c, 0x11, 0x7c, 0x00, 0x56, 0x57, 0x07, 0xbf,
Index: src/via.h
===================================================================
--- src/via.h	(.../tags/release_0_2_903)	(revision 751)
+++ src/via.h	(.../trunk)	(revision 751)
@@ -561,9 +561,6 @@
 #define HQV_V_FILTER_DEFAULT    0x00420000
 #define HQV_H_FILTER_DEFAULT    0x00000040
 
-
-
-
 /* HQV_MINI_CONTROL        0x3E8 */
 #define HQV_H_MINIFY_ENABLE 0x00000800
 #define HQV_H_MINIFY_DOWN   0x00001000
@@ -572,6 +569,19 @@
 #define HQV_VDEBLOCK_FILTER 0x80000000
 #define HQV_HDEBLOCK_FILTER 0x00008000
 
+/* Add new HQV Registers for VT3353: */
+#define HQV_SRC_DATA_OFFSET_CONTROL1        0x180
+#define HQV_SRC_DATA_OFFSET_CONTROL2        0x184
+#define HQV_SRC_DATA_OFFSET_CONTROL3        0x188
+#define HQV_SRC_DATA_OFFSET_CONTROL4        0x18C
+#define HQV_HW_TUNING_PERFORMANCE           0x190
+#define HQV_EXTENDED_CONTROL                0x194
+#define HQV_STATIC_RECORD_FB_STARTADDR      0x198
+#define HQV_STATIC_RECORD_FB_STRIDE         0x19C
+#define HQV_COLOR_ADJUSTMENT_CONTROL1       0x1A0
+#define HQV_COLOR_ADJUSTMENT_CONTROL2       0x1A4
+#define HQV_COLOR_ADJUSTMENT_CONTROL3       0x1A8
+#define HQV_COLOR_ADJUSTMENT_CONTROL5       0x1AC
 
 #define CHROMA_KEY_LOW          0x00FFFFFF
 #define CHROMA_KEY_HIGH         0x00FFFFFF
Index: src/via_priv.h
===================================================================
--- src/via_priv.h	(.../tags/release_0_2_903)	(revision 751)
+++ src/via_priv.h	(.../trunk)	(revision 751)
@@ -29,9 +29,7 @@
 #ifdef XF86DRI
 #include "via_drm.h"
 #endif
-#ifdef VIA_HAVE_EXA
 #include "exa.h"
-#endif
 
 /*
  * Alignment macro functions
@@ -147,9 +145,7 @@
 #endif
     void  *pVia;			/* VIA driver pointer */
     FBLinearPtr linear;			/* X linear pool info ptr */
-#ifdef VIA_HAVE_EXA
     ExaOffscreenArea *exa;
-#endif
     ScrnInfoPtr pScrn;
 } VIAMem;
 
Index: src/via_timing.c
===================================================================
--- src/via_timing.c	(.../tags/release_0_2_903)	(revision 0)
+++ src/via_timing.c	(.../trunk)	(revision 751)
@@ -0,0 +1,398 @@
+/*
+ * Copyright 2007-2008 Gabriel Mansi.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * GTF and CVT timing calculator
+ *
+ * Based on
+ * GTF spreadsheet developed by Andy Morrish
+ * http://www.vesa.org/Public/GTF/GTF_V1R1.xls
+ * and
+ * CVT spreadsheet developed by Graham Loveridge
+ * http://www.vesa.org/Public/CVT/CVTd6r1.xls
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "via_timing.h"
+
+__inline__ static float froundf(Bool gtf, float f) {
+    return gtf ? rintf(f) : floorf(f) ;
+}
+
+#define MODE_NAME_LENGTH 20
+static int timingGenerateMode(DisplayModePtr mode, Bool gtf, int width, int height, float refresh, Bool interlaced, Bool reducedBlanking) {
+
+    if (!mode) return TIMING_ERR_BAD_ALLOC ;
+
+    int ret = 0 ;
+    float H_PIXELS = width ;
+    float V_LINES = height ;
+    Bool MARGINS_RQD = FALSE ;
+    Bool INT_RQD = interlaced ;
+    float IP_FREQ_RQD = refresh ;
+    Bool RED_BLANK_RQD = reducedBlanking && !gtf ;
+
+    if (!gtf) {
+        if (refresh != 50.0f
+                && refresh != 60.0f
+                && refresh != 75.0f
+                && refresh != 85.0f )
+            ret |= TIMING_CVT_WARN_REFRESH_RATE ;
+
+        if (reducedBlanking && refresh != 60.0f)
+            ret |= TIMING_CVT_WARN_REFRESH_RATE_NOT_RB ;
+
+    }
+    /* 1) These are the default values that define the MARGIN size:  */
+    /* Top/ bottom MARGIN size as % of height  (%)  {DEFAULT = 1.8} */
+    float TOP_BOTTOM_MARGIN = 1.8f ;
+
+    /* 2) This default value defines the horizontal timing boundaries: */
+    /* Character cell horizontal granularity (pixels)  {DEFAULT = 8} */
+    float CELL_GRAN = 8.0f ;
+
+    /* 3) These default values define analog system sync pulse width limitations: */
+    /* 4:3 -> 4, 16:9 -> 5, 16: -> 6, 5:4 -> 7, 15:9 -> 7,
+     * Reserved -> 8, Reserved -> 9, Custom -> 10
+     */
+    float V_SYNC_RQD = 3.0f ;
+    float vSync ;
+    if (gtf) {
+        vSync = V_SYNC_RQD ;
+    } else {
+        float aspectRatio = (float)width / height ;
+        if ( aspectRatio == 4.0f / 3.0f ) vSync = 4 ;
+        else if ( aspectRatio == 16.0f / 9.0f ) vSync = 5 ;
+        else if ( aspectRatio == 16.0f / 10.0f ) vSync = 6 ;
+        else if ( aspectRatio == 5.0f / 4.0f || aspectRatio == 15.0f / 9.0f ) vSync = 7 ;
+        else {
+            vSync = 10 ;
+            ret |= TIMING_CVT_WARN_ASPECT_RATIO ;
+        }
+    }
+
+    /* Nominal H sync width (% of line period)  {DEFAULT = 8} */
+    float NOMINAL_H_SYNC_WIDTH = 8.0f ;
+
+    /* 4) These default values define analog scan system vertical blanking time limitations: */
+    /* Minimum time of vertical sync+back porch interval (us) */
+    float MIN_V_SYNC_BP_INTERVAL =  550.0f ;
+    /* Minimum number of vertical back porch lines {DEFAULT = 6} */
+    float MIN_V_BPORCH = 6 ;
+    /* Minimum vertical porch (no of lines) {DEFAULT = 3} */
+    float MIN_V_PORCH = gtf ? 1.0f : 3.0f ;
+    /* 5) Definition of Horizontal blanking time limitation: */
+    /* Generalized blanking limitation formula used of the form:
+     * <H BLANKING TIME (%)> =C - ( M / Fh)
+     * Where:
+     * M (gradient) (%/kHz)  {DEFAULT = 600}
+     * C (offset) (%)  {DEFAULT = 40}
+     * K (blanking time scaling factor)  {DEFAULT = 128}
+     * J (scaling factor weighting)  {DEFAULT = 20}
+     */
+    float GTF_M_VAR = 600 ;
+    float GTF_C_VAR = 40 ;
+    float GTF_K_VAR = 128 ;
+    float GTF_J_VAR = 20 ;
+
+    /* M' = K / 256 * M */
+    float mPrime = GTF_K_VAR / 256 * GTF_M_VAR ;
+    /* C' = ( ( C - J ) * K / 256 ) + J */
+    float cPrime = ( ( GTF_C_VAR - GTF_J_VAR ) * GTF_K_VAR / 256 ) + GTF_J_VAR ;
+    /* Fixed number of clocks for horizontal blanking  {DEFAULT = 160} */
+    float K130 = 160 ;
+    /* Fixed number of clocks for horizontal sync  {DEFAULT = 32} */
+    float K131 = 32 ;
+    /* Minimum vertical blanking interval time (us)  {DEFAULT = 460} */
+    float K133 = 460 ;
+    /* Fixed number of lines for vertical front porch  {DEFAULT = 3} */
+    float RB_V_FPORCH = 3 ;
+
+    /* Minimum number of vertical back porch lines  {DEFAULT = 6} */
+    /* float RB_MIN_V_BPORCH = 6 ; */
+
+    float CLOCK_STEP = 0.25f ;
+
+    /* CONSTANTS */
+
+    float cellGranRnd = floorf(CELL_GRAN) ;
+    float marginPer = TOP_BOTTOM_MARGIN;
+    float minVPorchRnd = floorf(MIN_V_PORCH) ;
+
+    /* STANDARD CRT TIMING SCRATCH PAD: */
+    float minVSyncBP = MIN_V_SYNC_BP_INTERVAL ;
+    float hSyncPer = NOMINAL_H_SYNC_WIDTH ;
+
+    /* REDUCED BLANKING SCRATCH PAD: */
+    float rbMinVBlank = K133 ;
+    float rbHSync = K131 ;
+    float rbHBlank = K130 ;
+
+    /* COMMON TIMING PARAMETERS: */
+    /* 1 REQUIRED FIELD RATE */
+    float vFieldRateRqd = INT_RQD ? IP_FREQ_RQD * 2.0f : IP_FREQ_RQD ;
+    /* 2 HORIZONTAL PIXELS */
+    float hPixelsRnd = froundf( gtf, ( H_PIXELS/cellGranRnd ) * cellGranRnd );
+    /* 3 DETERMINE LEFT & RIGHT BORDERS */
+    float leftMargin = MARGINS_RQD ? floorf( hPixelsRnd * marginPer / 100.0f / cellGranRnd ) * cellGranRnd : 0 ;
+    float rightMargin = leftMargin ;
+    /* 4 FIND TOTAL ACTIVE PIXELS */
+    float totalActivePixels = hPixelsRnd + leftMargin + rightMargin ;
+    /* 5 FIND NUMBER OF LINES PER FIELD */
+    float vLinesRnd = INT_RQD ? froundf( gtf, V_LINES / 2.0f ) : froundf( gtf, V_LINES ) ;
+    /* 6 FIND TOP & BOTTOM MARGINS */
+    float topMargin = MARGINS_RQD ? froundf( gtf, marginPer/100.0f*vLinesRnd ) : 0 ;
+    float botMargin = topMargin ;
+
+    float interlace = INT_RQD ? 0.5f : 0 ;
+
+
+    /* 8 ESTIMATE HORIZ. PERIOD (us): */
+    float U23 = ( ( 1.0f / vFieldRateRqd ) - minVSyncBP / 1000000.0f )
+                    / ( vLinesRnd + ( 2.0f * topMargin ) + minVPorchRnd + interlace ) * 1000000.0f ;
+
+    /* 8.1 Reduced blanking */
+    float Y23 = ( ( 1000000.0f / vFieldRateRqd ) - rbMinVBlank ) / ( vLinesRnd + topMargin + botMargin ) ;
+
+    /* RESULTS Estimated Horizontal Frequency (kHz): */
+    float hPeriodEst = RED_BLANK_RQD ? Y23 : U23 ;
+
+    /* 9 FIND NUMBER OF LINES IN (SYNC + BACK PORCH): */
+    /* Estimated V_SYNC_BP */
+    float U26 = froundf( gtf,  minVSyncBP / hPeriodEst ) ;
+    if ( !gtf ) U26 += 1.0f ;
+
+    /* float U27 = MIN_VSYNC_BP/H_PERIOD_EST ; */
+
+    /* 9.1 RB */
+    float vbiLines = floorf( rbMinVBlank/hPeriodEst ) + 1.0f ;
+    /* float Y27 = RB_MIN_V_BLANK/H_PERIOD_EST ; */
+
+    float vSyncBP ;
+    if (gtf)
+        vSyncBP = rintf( MIN_V_SYNC_BP_INTERVAL / hPeriodEst ) ;
+    else
+        vSyncBP = U26 < ( vSync + MIN_V_BPORCH ) ? vSync + MIN_V_BPORCH : U26 ;
+
+    /* RESULTS Ver Sync */
+    float vSyncRnd = (int) vSync ;
+
+    /* 10 FIND NUMBER OF LINES IN BACK PORCH (Lines): */
+    /* float U31 = V_SYNC_BP-V_SYNC_RND ; */
+    /* 10.1 RB */
+    float rbMinVbi = RB_V_FPORCH + vSyncRnd + MIN_V_BPORCH ;
+    float actVbiLines = vbiLines < rbMinVbi ? rbMinVbi : vbiLines ;
+
+    /*11 FIND TOTAL NUMBER OF LINES IN VERTICAL FIELD: */
+    float U34 = vLinesRnd + topMargin + botMargin + vSyncBP + interlace + minVPorchRnd ;
+    /* 11.1 RB FIND TOTAL NUMBER OF LINES IN VERTICAL FIELD: */
+    float Y34 = actVbiLines + vLinesRnd + topMargin + botMargin + interlace ;
+
+    /* RESULTS */
+    float totalVLines = RED_BLANK_RQD ? Y34 : U34 ;
+
+    /* 12 FIND IDEAL BLANKING DUTY CYCLE FROM FORMULA (%): */
+    float idealDutyCicle = cPrime - ( mPrime * hPeriodEst / 1000.0f ) ;
+
+    float hPeriod ;
+    float vFieldRateEst ;
+    if (gtf) {
+        vFieldRateEst = 1.0f / hPeriodEst / totalVLines *  1000000.0f ;
+        hPeriod = hPeriodEst / ( vFieldRateRqd / vFieldRateEst ) ;
+    } else
+        hPeriod = idealDutyCicle ;
+
+    /* 12.1 RB FIND TOTAL NUMBER OF PIXELS IN A LINE (Pixels): */
+    float Y37 = rbHBlank + totalActivePixels ;
+
+    /* 13 FIND BLANKING TIME TO NEAREST CHAR CELL (Pixels): */
+
+    float vFieldRate ;
+    if (gtf) {
+        vFieldRate = rintf( totalActivePixels * idealDutyCicle / ( 100.0f - idealDutyCicle ) / ( 2.0f * cellGranRnd ) ) * ( 2.0f * cellGranRnd ) ;
+    } else {
+        vFieldRate = hPeriod < 20.0f ?
+                floorf( totalActivePixels * 20.0f / ( 100.0f - 20.0f ) / ( 2.0f * cellGranRnd ) ) * (2.0f * cellGranRnd ) :
+                floorf( totalActivePixels * idealDutyCicle / ( 100.0f - idealDutyCicle ) / ( 2.0f * cellGranRnd ) ) * ( 2.0f * cellGranRnd ) ;
+    }
+
+    /* RESULTS Horizontal Blanking (Pixels): */
+    float hBlank = RED_BLANK_RQD ? rbHBlank : vFieldRate ;
+
+    /* 14 FIND TOTAL NUMBER OF PIXELS IN A LINE (Pixels): */
+    float vFrameRate = totalActivePixels + hBlank ;
+
+    float totalPixels  = RED_BLANK_RQD ? Y37 : vFrameRate ;
+
+    /* 15 FIND PIXEL CLOCK FREQUENCY (MHz): */
+    float pixelFreq ;
+    if (gtf)
+        pixelFreq = totalPixels / hPeriodEst ;
+    else
+        pixelFreq = CLOCK_STEP * floorf( ( totalPixels / hPeriodEst ) / CLOCK_STEP ) ;
+
+    /* float U47 = TOTAL_PIXELS/H_PERIOD_EST ; */
+
+    /* 13 RB FIND PIXEL CLOCK FREQUENCY (MHz): Y40*/
+    float Y40 = CLOCK_STEP * floorf( ( vFieldRateRqd * totalVLines * totalPixels / 1000000.0f ) / CLOCK_STEP ) ;
+    /* float Y41 = V_FIELD_RATE_RQD*TOTAL_V_LINES*TOTAL_PIXELS/1000000.0f ; */
+
+    /* RESULTS Actual Pixel Clock (MHz): */
+    float actPixelFreq = RED_BLANK_RQD ? Y40 : pixelFreq ;
+
+    /* 16 FIND ACTUAL HORIZONTAL FREQUENCY (kHz): */
+    //float U50 = 1000.0f*ACT_PIXEL_FREQ/TOTAL_PIXELS ;
+
+    /* 14 RB FIND ACTUAL HORIZONTAL FREQUENCY (kHz): */
+    //float Y44 = 1000.0f*ACT_PIXEL_FREQ/TOTAL_PIXELS ;
+
+    /* RESULTS Actual Horizontal Frequency (kHz): */
+    //float ACT_H_FREQ = RED_BLANK_RQD ? Y44 : U50 ;
+
+    float actHFreq ;
+    if (gtf)
+        actHFreq = 1000.0f / hPeriod ;
+    else
+        actHFreq = 1000.0f * actPixelFreq / totalPixels ;
+
+    /* 17 FIND ACTUAL FIELD RATE (Hz): */
+    // float U53 = 1000.0f*ACT_H_FREQ/TOTAL_V_LINES ;
+
+    /* 15 RB FIND ACTUAL FIELD RATE (Hz): */
+    // float Y47 = 1000.0f*ACT_H_FREQ/TOTAL_V_LINES ;
+
+    /* RESULTS Actual Vertical Frequency (Hz): */
+    // float ACT_FIELD_RATE = RED_BLANK_RQD ? Y47 : U53 ;
+    float actFieldRate = 1000.0f * actHFreq / totalVLines ;
+
+    /* 16 RB FIND ACTUAL VERTICAL  FRAME FREQUENCY (Hz): */
+    //float Y50 = INT_RQD ? ACT_FIELD_RATE/2.0f : ACT_FIELD_RATE ;
+
+    /* 18 FIND ACTUAL VERTICAL  FRAME FREQUENCY (Hz): */
+    //float U56 = INT_RQD ? ACT_FIELD_RATE/2.0f : ACT_FIELD_RATE ;
+
+    /* RESULTS Actual Vertical Frequency (Hz): */
+    //float ACT_FRAME_RATE = RED_BLANK_RQD ? Y50 : U56 ;
+    float actFrameRat = INT_RQD ? actFieldRate / 2.0f : actFieldRate ;
+
+    /* RESULTS Hor Back porch*/
+    float hBackPorch = hBlank / 2 ;
+
+    /* RESULTS Ver Blank */
+//    float vBlank = RED_BLANK_RQD ? actVbiLines : vSyncBP + minVPorchRnd ;
+
+    /* RESULTS Ver Front Porch*/
+    float vFrontPorch = RED_BLANK_RQD ? RB_V_FPORCH : minVPorchRnd ;
+
+    /* RESULTS Ver back porch */
+//    float vBackPorch = vBlank - vFrontPorch - vSyncRnd ;
+
+    /* RESULTS Hor Sync */
+    float hSyncRnd = RED_BLANK_RQD ? rbHSync : froundf( gtf, ( hSyncPer / 100.0f * totalPixels / cellGranRnd ) ) * cellGranRnd ;
+
+    /* RESULTS Hor Front Porch: */
+    float hFrontPorch ;
+    if (gtf)
+        hFrontPorch = ( hBlank / 2.0f ) - hSyncRnd ;
+    else
+        hFrontPorch = hBlank - hBackPorch - hSyncRnd ;
+
+#if DEBUG
+    fprintf( stderr, "hFrontPorch:\t\t%f\n", hFrontPorch ) ;
+    fprintf( stderr, "totalActivePixels:\t\t%f\n", totalActivePixels ) ;
+    fprintf( stderr, "vFieldRateRqd:\t\t\t%f\n", vFieldRateRqd ) ;
+    fprintf( stderr, "minVSyncBP:\t\t\t%f\n", minVSyncBP ) ;
+    fprintf( stderr, "vLinesRnd:\t\t\t%f\n", vLinesRnd ) ;
+    fprintf( stderr, "minVPorchRnd:\t\t\t%f\n", minVPorchRnd ) ;
+    fprintf( stderr, "interlace:\t\t\t%f\n", interlace ) ;
+    fprintf( stderr, "vSyncBP:\t\t\t%f\n", vSyncBP ) ;
+    fprintf( stderr, "hSyncPer:\t\t\t%f\n", hSyncPer ) ;
+    fprintf( stderr, "totalPixels:\t\t\t%f\n", totalPixels ) ;
+    fprintf( stderr, "cellGranRnd:\t\t\t%f\n", cellGranRnd ) ;
+    fprintf( stderr, "hPeriod:\t\t\t%f\n", hPeriod ) ;
+    fprintf( stderr, "vFieldRate:\t\t\t%f\n", vFieldRate ) ;
+    fprintf( stderr, "hPeriodEst:\t\t\t%f\n", hPeriodEst ) ;
+    fprintf( stderr, "totalVLines:\t\t\t%f\n", totalVLines ) ;
+    fprintf( stderr, "vFieldRateEst:\t\t\t%f\n", vFieldRateEst ) ;
+    fprintf( stderr, "vFieldRateRqd:\t\t\t%f\n", vFieldRateRqd ) ;
+    fprintf( stderr, "idealDutyCicle:\t\t\t%f\n", idealDutyCicle ) ;
+    fprintf( stderr, "actHFreq:\t\t\t%f\n", actHFreq ) ;
+    fprintf( stderr, "hblank:\t\t\t\t%f\n", hBlank ) ;
+    fprintf( stderr, "actPixelFreq:\t\t\t%f\n", actPixelFreq ) ;
+#endif
+
+    if (mode) {
+        if (mode->name == NULL) {
+            mode->name = malloc(MODE_NAME_LENGTH);
+            if (mode->name) {
+                memset(mode->name, 0, MODE_NAME_LENGTH) ;
+                char c = 0 ;
+                if (RED_BLANK_RQD) c = 'r' ;
+                if (INT_RQD) c = 'i' ;
+                sprintf(mode->name, "%dx%d@%d%c", width, height, (int)refresh, c ) ;
+            }
+        }
+
+        mode->Clock = actPixelFreq * 1000.0f ;
+        mode->VRefresh = actFrameRat ;
+
+        mode->HDisplay = width ;
+        mode->HSyncStart = width + hFrontPorch ;
+        mode->HSyncEnd = width + ( hFrontPorch + hSyncRnd ) ;
+        mode->HTotal = totalPixels ;
+
+        mode->VDisplay = height ;
+        mode->VSyncStart = height + vFrontPorch ;
+        mode->VSyncEnd = height + (vFrontPorch + vSyncRnd) ;
+        mode->VTotal = INT_RQD ? totalVLines * 2 : totalVLines ;
+        mode->Flags = 0 ;
+
+        if (RED_BLANK_RQD) {
+            mode->Flags |= V_PHSYNC ;
+            mode->Flags |= V_NVSYNC ;
+        } else {
+            mode->Flags |= V_NHSYNC ;
+            mode->Flags |= V_PVSYNC ;
+        }
+
+        if (!(mode->Flags & V_PHSYNC)) mode->Flags |= V_NHSYNC ;
+        if (!(mode->Flags & V_NHSYNC)) mode->Flags |= V_PHSYNC ;
+        if (!(mode->Flags & V_PVSYNC)) mode->Flags |= V_NVSYNC ;
+        if (!(mode->Flags & V_NVSYNC)) mode->Flags |= V_PVSYNC ;
+
+        if (INT_RQD) mode->Flags |= V_INTERLACE ;
+    } else {
+        ret |= TIMING_ERR_BAD_ALLOC ;
+    }
+
+    return ret ;
+}
+
+int viaTimingCvt(DisplayModePtr mode, int width, int height, float refresh, Bool interlaced, Bool reducedBlanking) {
+    return timingGenerateMode( mode, FALSE, width, height, refresh, interlaced, reducedBlanking ) ;
+}
+
+int viaTimingGtf(DisplayModePtr mode, int width, int height, float refresh, Bool interlaced) {
+    return timingGenerateMode( mode, TRUE, width, height, refresh, interlaced, FALSE ) ;
+}
Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(.../tags/release_0_2_903)	(revision 751)
+++ src/Makefile.am	(.../trunk)	(revision 751)
@@ -43,23 +43,29 @@
          via_ch7xxx.c \
          via_ch7xxx.h \
          via_cursor.c \
+         via_crtc.c \
          via_dga.c \
+         via_display.c \
          via_dmabuffer.h \
          via_driver.c \
          via_driver.h \
          via_i2c.c \
          via_id.c \
          via_id.h \
+         via_lvds.c \
          via_memcpy.c \
          via_memcpy.h \
          via_memory.c \
          via_mode.c \
          via_mode.h \
+         via_panel.c \
          via_priv.h \
          via_regs.h \
          via_shadow.c \
          via_swov.c \
          via_swov.h \
+         via_timing.c \
+         via_timing.h \
          via_vbe.c \
          via_vgahw.c \
          via_vgahw.h \
Index: src/via_dga.c
===================================================================
--- src/via_dga.c	(.../tags/release_0_2_903)	(revision 751)
+++ src/via_dga.c	(.../trunk)	(revision 751)
@@ -248,7 +248,7 @@
 
         pScrn->SwitchMode(index, pScrn->currentMode, 0);
         if (pVia->hwcursor)
-            VIAShowCursor(pScrn);
+            viaShowCursor(pScrn);
 
         pVia->DGAactive = FALSE;
     }
@@ -261,7 +261,7 @@
 #endif
 
         if (pVia->hwcursor)
-            VIAHideCursor(pScrn);
+            viaHideCursor(pScrn);
 
         if (!pVia->DGAactive) {  /* save the old parameters */
             pVia->DGAOldDisplayWidth = pScrn->displayWidth;
Index: src/via_id.c
===================================================================
--- src/via_id.c	(.../tags/release_0_2_903)	(revision 751)
+++ src/via_id.c	(.../trunk)	(revision 751)
@@ -87,6 +87,7 @@
     {"Asustek K8V-MX",                        VIA_K8M800,  0x1043, 0x8129, VIA_DEVICE_CRT},
     {"Mitac 8399",                            VIA_K8M800,  0x1071, 0x8399, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV}, /* aka "Pogolinux Konabook 3100" */
     {"Mitac 8889",                            VIA_K8M800,  0x1071, 0x8889, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV},
+    {"MSI K8M Neo-V (broken pci id)",         VIA_K8M800,  0x1106, 0x0204, VIA_DEVICE_CRT},
     {"VIA VT3108 (K8M800)",                   VIA_K8M800,  0x1106, 0x3108, VIA_DEVICE_CRT}, /* borrowed by Asustek A8V-MX */ 
     {"Shuttle FX21",                          VIA_K8M800,  0x1297, 0x3052, VIA_DEVICE_CRT},
     {"Shuttle FX83",                          VIA_K8M800,  0x1297, 0xF683, VIA_DEVICE_CRT | VIA_DEVICE_TV},
@@ -113,6 +114,7 @@
     {"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},
     {"ASRock K8Upgrade-VM800",                VIA_K8M800,  0x1849, 0x3108, VIA_DEVICE_CRT},
+    {"Axper XP-M8VM800",                      VIA_K8M800,  0x1940, 0xD000, VIA_DEVICE_CRT},
 
     /*** PM800, PM880, PN800, CN400 ***/
     {"VIA VT3118 (PM800)",                    VIA_PM800,   0x1106, 0x3118, VIA_DEVICE_CRT}, /* borrowed by ECS PM800-M2 */
@@ -138,6 +140,7 @@
     {"PCChips V21G",                          VIA_VM800,   0x1019, 0xAA51, VIA_DEVICE_CRT},
     {"Asustek P5VDC-MX",                      VIA_VM800,   0x1043, 0x3344, VIA_DEVICE_CRT},
     {"Asustek P5VDC-TVM",                     VIA_VM800,   0x1043, 0x81CE, VIA_DEVICE_CRT},
+    {"Foxconn P4M800P7MB-RS2H",               VIA_VM800,   0x105B, 0x0CF0, VIA_DEVICE_CRT},
     {"Gateway MX3210",                        VIA_VM800,   0x107B, 0x0216, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
     {"VIA VT3344 (VM800) - EPIA EN",          VIA_VM800,   0x1106, 0x3344, VIA_DEVICE_CRT | VIA_DEVICE_TV},
     {"Gigabyte GA-8VM800M-775",               VIA_VM800,   0x1458, 0xD000, VIA_DEVICE_CRT},
@@ -145,6 +148,7 @@
     {"MSI Fuzzy CN700/CN700T/CN700G",         VIA_VM800,   0x1462, 0x7199, VIA_DEVICE_CRT | VIA_DEVICE_TV},
     {"MSI PM8M3-V",                           VIA_VM800,   0x1462, 0x7211, VIA_DEVICE_CRT},
     {"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},
     {"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},
@@ -158,6 +162,7 @@
     {"Asustek P5V800-MX",                     VIA_VM800,   0x3344, 0x1122, VIA_DEVICE_CRT},
 
     /*** K8M890 ***/
+    {"IBM AnyPlace Kiosk 3xx",                VIA_K8M890,  0x1106, 0x3230, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
     {"Asustek A8V-VM",                        VIA_K8M890,  0x1043, 0x81B5, VIA_DEVICE_CRT},
     {"Asustek M2V-MX SE",                     VIA_K8M890,  0x1043, 0x8297, VIA_DEVICE_CRT},
     {"Foxconn K8M890M2MA-RS2H",               VIA_K8M890,  0x105B, 0x0C84, VIA_DEVICE_CRT},
@@ -179,6 +184,7 @@
     {"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},
     {"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},
@@ -196,6 +202,7 @@
     {"Samsung Q1B",                           VIA_CX700,   0x144D, 0xC02C, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
     {"FIC CE260",                             VIA_CX700,   0x1509, 0x2D30, VIA_DEVICE_LCD},
     {"FIC CE261",                             VIA_CX700,   0x1509, 0x2F07, VIA_DEVICE_LCD},
+    {"Gigabyte M704 / RoverPC A700GQ",        VIA_CX700,   0x161F, 0x2060, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
     {"Packard Bell EasyNote XS",              VIA_CX700,   0x1631, 0xC201, VIA_DEVICE_LCD}, /* aka Everex Cloudbook CE1200V */
 
     /*** P4M890, VN890 ***/
@@ -204,11 +211,17 @@
     {"Asustek P5V-VM ULTRA",                  VIA_P4M890,  0x1043, 0x81B5, VIA_DEVICE_CRT},
     {"Asustek P5V-VM DH",                     VIA_P4M890,  0x1043, 0x81CE, VIA_DEVICE_CRT},
     {"Mitac 8615",                            VIA_P4M890,  0x1071, 0x8615, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+    {"Mitac 8624 (Joybook R41E)",             VIA_P4M890,  0x1071, 0x8624, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
     {"VIA VT3343 (P4M890)",                   VIA_P4M890,  0x1106, 0x3343, VIA_DEVICE_CRT},
     {"MSI P4M890M-L/IL (MS-7255)",            VIA_P4M890,  0x1462, 0x7255, VIA_DEVICE_CRT},
     {"Biostar P4M890-M7 TE",                  VIA_P4M890,  0x1565, 0x1207, VIA_DEVICE_CRT},
     {"ASRock P4VM890",                        VIA_P4M890,  0x1849, 0x3343, VIA_DEVICE_CRT},
 
+    /*** VX800 ***/
+    {"VIA Epia M700",                         VIA_VX800,   0x1106, 0x1122, VIA_DEVICE_CRT},
+    {"Samsung NC20",                          VIA_VX800,   0x144d, 0xc04e, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+    {"Quanta DreamBook Light IL1",            VIA_VX800,   0x152d, 0x0771, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+
     /* keep this */
     {NULL,                                    VIA_UNKNOWN, 0x0000, 0x0000, VIA_DEVICE_NONE}
 };
Index: src/via_timing.h
===================================================================
--- src/via_timing.h	(.../tags/release_0_2_903)	(revision 0)
+++ src/via_timing.h	(.../trunk)	(revision 751)
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2007-2008 Gabriel Mansi.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _TIMING_H_
+#define _TIMING_H_
+
+#include "xf86.h"
+
+/* Aspect ratio not CVT standard */
+#define TIMING_CVT_WARN_ASPECT_RATIO 1 << 0
+
+/* Error allocating memory */
+#define TIMING_ERR_BAD_ALLOC 1 << 1
+
+/* Refresh rate not CVT standard */
+#define TIMING_CVT_WARN_REFRESH_RATE 1 << 2
+
+/* Refresh rate not valid for reducing blanking */
+#define TIMING_CVT_WARN_REFRESH_RATE_NOT_RB 1 << 3
+
+/**
+ * Geneartes a CVT modeline
+ * mode must not be null, if mode->name is null a new char* will be allocated. 
+ * 
+ */
+int viaTimingCvt(DisplayModePtr mode, int width, int height, float refresh, Bool interlaced, Bool reducedBlanking);
+
+int viaTimingGtf(DisplayModePtr mode, int width, int height, float refresh, Bool interlaced) ;
+
+#endif /*_TIMING_H_*/