summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJon Nettleton <jon.nettleton@gmail.com>2007-06-07 13:15:10 +0000
committerJon Nettleton <jon.nettleton@gmail.com>2007-06-07 13:15:10 +0000
commit83c4eb79d5d5870a3dde9431b393cb08c175fd0d (patch)
tree68538648978ea85c7131191d7d97f7802b509b98 /src
parent0552096a2831446d7ace66bf88d14bdd2742c65d (diff)
mv unichrome to src
Diffstat (limited to 'src')
-rw-r--r--src/Imakefile231
-rw-r--r--src/Makefile.am99
-rw-r--r--src/via.h649
-rw-r--r--src/via.man232
-rw-r--r--src/via_3d.c592
-rw-r--r--src/via_3d.h121
-rw-r--r--src/via_3d_reg.h1651
-rw-r--r--src/via_accel.c2652
-rw-r--r--src/via_bandwidth.c368
-rw-r--r--src/via_bios.h181
-rw-r--r--src/via_ch7xxx.c650
-rw-r--r--src/via_ch7xxx.h737
-rw-r--r--src/via_cursor.c228
-rw-r--r--src/via_dga.c321
-rw-r--r--src/via_dmabuffer.h100
-rw-r--r--src/via_dri.c1101
-rw-r--r--src/via_dri.h78
-rw-r--r--src/via_driver.c2858
-rw-r--r--src/via_driver.h472
-rw-r--r--src/via_drm.h270
-rw-r--r--src/via_drmclient.h98
-rw-r--r--src/via_i2c.c428
-rw-r--r--src/via_id.c249
-rw-r--r--src/via_id.h91
-rw-r--r--src/via_memcpy.c695
-rw-r--r--src/via_memcpy.h31
-rw-r--r--src/via_memory.c194
-rw-r--r--src/via_mode.c1997
-rw-r--r--src/via_mode.h920
-rw-r--r--src/via_priv.h170
-rw-r--r--src/via_regs.h177
-rw-r--r--src/via_shadow.c313
-rw-r--r--src/via_swov.c2203
-rw-r--r--src/via_swov.h84
-rw-r--r--src/via_vbe.c340
-rw-r--r--src/via_vgahw.c194
-rw-r--r--src/via_vgahw.h51
-rw-r--r--src/via_video.c1626
-rw-r--r--src/via_video.h113
-rw-r--r--src/via_vt162x.c846
-rw-r--r--src/via_vt162x.h928
-rw-r--r--src/via_xvmc.c1015
-rw-r--r--src/via_xvmc.h104
-rw-r--r--src/via_xvpriv.h90
44 files changed, 26548 insertions, 0 deletions
diff --git a/src/Imakefile b/src/Imakefile
new file mode 100644
index 000000000000..e7ca37d0c2b8
--- /dev/null
+++ b/src/Imakefile
@@ -0,0 +1,231 @@
+#define IHaveModules
+#include <Server.tmpl>
+
+XCOMM Add a comment into the source if we are building svn code.
+all:: svnversion.h
+
+svnversion.h:
+ @if [ -f svnrelease.h ]; then \
+ echo '#include "svnrelease.h"' > $@.tmp; \
+ elif [ -d .svn ]; then \
+ echo '#define BUILDCOMMENT "(development build, at svn revision '\
+ "`svnversion -nc . | sed -e s/^[^:]*://`"')\n"' > $@.tmp; \
+ else date +'#define BUILDCOMMENT "(development build, compiled on %c)\n"' > $@.tmp; fi
+
+ @(chmod 666 $@.tmp 2> /dev/null || /bin/true)
+ @cmp -s $@ $@.tmp || (mv $@.tmp $@ ; echo created $@)
+
+.PHONY: svnversion.h
+
+XCOMM Check the version to see if we need anything special.
+#ifdef XF86_VERSION_CURRENT
+XCOMM We are using Xfree86
+
+XCOMM This needs a seperate check though, debian dfsg-6 needs this
+XCOMM but it's version is still 4.3.0.1 - see via_xvmc.c
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,3,99,3,0)
+DEFXVPRIV = -DX_NEED_XVPRIV_H
+#endif
+
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,3,99,16,0)
+DEFREGIONNULL = -DX_USE_REGION_NULL
+#endif
+
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,4,99,2,0)
+XCOMM for Imakefile only
+#define X_NEED_NEWMODULETARGET 1
+#endif
+
+#if XF86_VERSION_CURRENT <= XF86_VERSION_NUMERIC(4,4,99,7,0)
+XCOMM drm_hw_lock_t is hidden behind __KERNEL__ here
+XCOMM use drmLock instead
+DEFXNEEDDRMLOCK = -DX_NEED_DRMLOCK
+#else
+#undef DEFXNEEDDRMLOCK
+#endif
+
+#else
+XCOMM We are using X.org
+XCOMM The XF86_VERSION stuff just had to be renamed it seems. Why
+XCOMM they kept XORG_VERSION at all I don't know, since they are
+XCOMM apparently not bothering with altering it. Both the x.org
+XCOMM release and a cvs checkout (3m after release) here are
+XCOMM 6.7.0.0.0. Luckily, apart from the drm.h location, this is
+XCOMM not a problem... yet. -- luc
+
+DEFXVPRIV = -DX_NEED_XVPRIV_H
+DEFREGIONNULL = -DX_USE_REGION_NULL
+
+#if BuildXF86DRI
+XCOMM Since we are unable to properly version, just include the lot.
+X_DRM_H_LOCATION = -I$(DRMSRCDIR)/shared-core -I$(DRMSRCDIR)/shared -I$(XF86OSSRC)/shared/drm/kernel
+#endif
+
+XCOMM Include the Xorg changes concerning dlloader (by Adam Jackson).
+XCOMM The current changes are not necessary yet, but I've backported
+XCOMM them anyway.
+#if MakeDllModules
+DEFXAAGETROP = -DX_HAVE_XAAGETROP
+#endif
+
+XCOMM We don't need X_NEED_NEWMODULETARGET with X.org
+#undef X_NEED_NEWMODULETARGET
+
+XCOMM I2CBusses require the Start function attached from 6.8 and on
+#if XORG_VERSION_MINOR > 7
+DEFI2CSTART = -DX_NEED_I2CSTART
+#else
+#undef DEFI2CSTART
+#endif
+
+#if XORG_VERSION_MINOR < 7
+XCOMM drm_hw_lock_t is hidden behind __KERNEL__ here
+XCOMM use drmLock instead
+DEFXNEEDDRMLOCK = -DX_NEED_DRMLOCK
+#else
+#undef DEFXNEEDDRMLOCK
+#endif
+
+#endif
+
+#if BuildXF86DRI
+DRISRCS = via_dri.c via_xvmc.c
+DRIOBJS = via_dri.o via_xvmc.o
+DRIINCLUDES = -I$(SERVERSRC)/GL/dri -I$(LIBSRC)/GL/dri \
+ $(X_DRM_H_LOCATION) -I$(TOP)/include
+DRIDEFINES = $(GLX_DEFINES)
+#endif
+
+#ifdef XF86EXA
+EXAINCLUDES = -I$(XF86SRC)/exa
+EXADEFINES = -DVIA_HAVE_EXA
+#endif
+
+SRCS = via_driver.c \
+ via_3d.c \
+ via_accel.c \
+ via_bandwidth.c \
+ via_ch7xxx.c \
+ via_mode.c \
+ via_cursor.c \
+ via_shadow.c \
+ via_dga.c \
+ via_video.c \
+ via_i2c.c \
+ via_id.c \
+ via_swov.c \
+ via_memory.c \
+ via_memcpy.c \
+ via_vbe.c \
+ via_vgahw.c \
+ via_vt162x.c \
+ $(DRISRCS)
+
+OBJS = via_driver.o \
+ via_3d.o \
+ via_accel.o \
+ via_bandwidth.o \
+ via_ch7xxx.o \
+ via_mode.o \
+ via_cursor.o \
+ via_shadow.o \
+ via_dga.o \
+ via_video.o \
+ via_i2c.o \
+ via_id.o \
+ via_swov.o \
+ via_memory.o \
+ via_memcpy.o \
+ via_vbe.o \
+ via_vgahw.o \
+ via_vt162x.o \
+ $(DRIOBJS)
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa \
+ -I$(XF86SRC)/xf1bpp -I$(XF86SRC)/xf4bpp \
+ -I$(XF86SRC)/xf24_32bpp -I$(SERVERSRC)/Xext \
+ -I$(XF86SRC)/vgahw -I$(XF86SRC)/ramdac \
+ -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \
+ -I$(XF86SRC)/rac -I$(XF86SRC)/int10 -I$(XF86SRC) -I$(SERVERSRC)/render \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(FONTINCSRC) \
+ -I$(EXTINCSRC) -I$(XF86SRC)/vbe -I$(XF86SRC)/shadowfb \
+ -I$(SERVERSRC)/fb $(DRIINCLUDES) $(EXAINCLUDES)
+#endif
+
+DEFINES = $(DRIDEFINES) $(DEFXVPRIV) $(DEFREGIONNULL) \
+ $(DEFXAAGETROP) $(DEFI2CSTART) $(DEFXNEEDDRMLOCK) $(EXADEFINES)
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+NormalAsmObjectRule()
+
+ModuleObjectRule()
+#ifdef X_NEED_NEWMODULETARGET
+ObjectModuleTarget(via, $(OBJS),drivers)
+#else
+ObjectModuleTarget(via, $(OBJS))
+#endif
+
+#ifdef InstallVideoObjectModule
+InstallVideoObjectModule(via,$(MODULEDIR))
+#else
+InstallObjectModule(via,$(MODULEDIR),drivers)
+#endif
+
+#if !defined(XF86DriverSDK)
+CppManTarget(via,)
+InstallModuleManPage(via)
+#endif
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via.h,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_3d.c,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_3d.h,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_accel.c,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_bandwidth.c,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_bios.h,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_ch7xxx.c,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_ch7xxx.h,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_cursor.c,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_dga.c,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_dmabuffer.h,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_dri.c,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_dri.h,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_driver.c,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_driver.h,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_drm.h,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_drmclient.h,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_i2c.c,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_id.h,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_id.c,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_memcpy.c,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_memcpy.h,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_memory.c,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_mode.c,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_mode.h,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_priv.h,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_regs.h,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_shadow.c,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_swov.c,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_swov.h,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_vbe.c,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_vgahw.c,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_vgahw.h,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_video.c,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_video.h,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_vt162x.c,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_vt162x.h,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_xvmc.c,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_xvmc.h,$(DRIVERSDKDIR)/drivers/via)
+InstallDriverSDKNonExecFile(via_xvpriv.h,$(DRIVERSDKDIR)/drivers/via)
+
+InstallDriverSDKObjectModule(via,$(DRIVERSDKMODULEDIR),drivers)
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 000000000000..bc820941c52f
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,99 @@
+# Copyright 2005 Adam Jackson.
+#
+# 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
+# on 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
+# ADAM JACKSON 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.
+
+# this is obnoxious:
+# -module lets us name the module exactly how we want
+# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
+# _ladir passes a dummy rpath to libtool so the thing will actually link
+# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
+EXTRA_DIST = svnversion.h
+CONFIG_CLEAN_FILES= svnversion.h
+AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@
+via_drv_la_LTLIBRARIES = via_drv.la
+via_drv_la_LDFLAGS = -module -avoid-version
+via_drv_ladir = @moduledir@/drivers
+
+via_drv_la_SOURCES = \
+ via_3d_reg.h \
+ via_3d.c \
+ via_3d.h \
+ via_accel.c \
+ via_bandwidth.c \
+ via_bios.h \
+ via_ch7xxx.c \
+ via_ch7xxx.h \
+ via_cursor.c \
+ via_dga.c \
+ via_dmabuffer.h \
+ via_driver.c \
+ via_driver.h \
+ via.h \
+ via_i2c.c \
+ via_id.c \
+ via_id.h \
+ via_memcpy.c \
+ via_memcpy.h \
+ via_memory.c \
+ via_mode.c \
+ via_mode.h \
+ via_priv.h \
+ via_regs.h \
+ via_shadow.c \
+ via_swov.c \
+ via_swov.h \
+ via_vbe.c \
+ via_vgahw.c \
+ via_vgahw.h \
+ via_video.c \
+ via_video.h \
+ via_vt162x.c \
+ via_vt162x.h \
+ via_xvpriv.h
+
+if DRI
+via_drv_la_SOURCES += \
+ via_dri.c \
+ via_dri.h \
+ via_drmclient.h \
+ via_xvmc.c \
+ via_xvmc.h
+
+else
+EXTRA_DIST += \
+ via_dri.c \
+ via_dri.h \
+ via_drmclient.h \
+ via_xvmc.c \
+ via_xvmc.h
+endif
+
+via_driver.lo: svnversion.h
+svnversion.h:
+ @if [ -f svnrelease.h ]; then \
+ echo '#include "svnrelease.h"' > $@.tmp; \
+ elif [ -d .svn ]; then \
+ echo '#define BUILDCOMMENT "(development build, at svn revision '\
+ "`svnversion -nc .. | sed -e s/^[^:]*://`"')\n"' > $@.tmp; \
+ else date +'#define BUILDCOMMENT "(development build, compiled on %c)\n"' > $@.tmp; fi
+
+ @(chmod 666 $@.tmp 2> /dev/null || /bin/true)
+ @cmp -s $@ $@.tmp || (mv $@.tmp $@ ; echo created $@)
+
+.PHONY: svnversion.h
diff --git a/src/via.h b/src/via.h
new file mode 100644
index 000000000000..e741d774b924
--- /dev/null
+++ b/src/via.h
@@ -0,0 +1,649 @@
+/*
+ * 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.
+ */
+
+#ifndef _VIA_H_
+#define _VIA_H_ 1
+
+#include "xorgVersion.h"
+
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+/* Video status flag */
+
+#define VIDEO_MPEG_INUSE 0x08000000 /*Video is used with MPEG */
+#define VIDEO_HQV_INUSE 0x04000000 /*Video is used with HQV*/
+#define VIDEO_CAPTURE0_INUSE 0x02000000 /*Video is used with CAPTURE 0*/
+#define VIDEO_CAPTURE1_INUSE 0x00000000 /*Video is used with CAPTURE 1*/
+#define VIDEO_1_INUSE 0x01000000 /*Video 1 is used with software flip*/
+#define VIDEO_3_INUSE 0x00000000 /*Video 3 is used with software flip*/
+#define MPEG_USE_V1 0x00010000 /*[16] : 1:MPEG use V1, 0:MPEG use V3*/
+#define MPEG_USE_V3 0x00000000 /*[16] : 1:MPEG use V1, 0:MPEG use V3*/
+#define MPEG_USE_HQV 0x00020000 /*[17] : 1:MPEG use HQV,0:MPEG not use HQV*/
+#define MPEG_USE_HW_FLIP 0x00040000 /*[18] : 1:MPEG use H/W flip,0:MPEG use S/W flip*/
+#define MPEG_USE_SW_FLIP 0x00000000 /*[18] : 1:MPEG use H/W flip,0:MPEG use S/W flip*/
+#define CAP0_USE_V1 0x00001000 /*[12] : 1:Capture 0 use V1, 0:Capture 0 use V3*/
+#define CAP0_USE_V3 0x00000000 /*[12] : 1:Capture 0 use V1, 0:Capture 0 use V3*/
+#define CAP0_USE_HQV 0x00002000 /*[13] : 1:Capture 0 use HQV,0:Capture 0 not use HQV*/
+#define CAP0_USE_HW_FLIP 0x00004000 /*[14] : 1:Capture 0 use H/W flip,0:Capture 0 use S/W flip*/
+#define CAP0_USE_CCIR656 0x00008000 /*[15] : 1:Capture 0 use CCIR656,0:Capture 0 CCIR601*/
+#define CAP1_USE_V1 0x00000100 /*[ 8] : 1:Capture 1 use V1, 0:Capture 1 use V3*/
+#define CAP1_USE_V3 0x00000000 /*[ 8] : 1:Capture 1 use V1, 0:Capture 1 use V3*/
+#define CAP1_USE_HQV 0x00000200 /*[ 9] : 1:Capture 1 use HQV,0:Capture 1 not use HQV*/
+#define CAP1_USE_HW_FLIP 0x00000400 /*[10] : 1:Capture 1 use H/W flip,0:Capture 1 use S/W flip */
+#define SW_USE_V1 0x00000010 /*[ 4] : 1:Capture 1 use V1, 0:Capture 1 use V3 */
+#define SW_USE_V3 0x00000000 /*[ 4] : 1:Capture 1 use V1, 0:Capture 1 use V3 */
+#define SW_USE_HQV 0x00000020 /*[ 5] : 1:Capture 1 use HQV,0:Capture 1 not use HQV */
+
+/*
+#define VIDEO1_INUSE 0x00000010 //[ 4] : 1:Video 1 is used with S/W flip
+#define VIDEO1_USE_HQV 0x00000020 //[ 5] : 1:Video 1 use HQV with S/W flip
+#define VIDEO3_INUSE 0x00000001 //[ 0] : 1:Video 3 is used with S/W flip
+#define VIDEO3_USE_HQV 0x00000002 //[ 1] : 1:Video 3 use HQV with S/W flip
+*/
+
+/* H/W registers for Video Engine */
+
+/*
+ * bus master
+ */
+#define PCI_MASTER_ENABLE 0x01
+#define PCI_MASTER_SCATTER 0x00
+#define PCI_MASTER_SINGLE 0x02
+#define PCI_MASTER_GUI 0x00
+#define PCI_MASTER_VIDEO 0x04
+#define PCI_MASTER_INPUT 0x00
+#define PCI_MASTER_OUTPUT 0x08
+
+/*
+ * video registers
+ */
+#define V_FLAGS 0x00
+#define V_CAP_STATUS 0x04
+#define V_FLIP_STATUS 0x04
+#define V_ALPHA_WIN_START 0x08
+#define V_ALPHA_WIN_END 0x0C
+#define V_ALPHA_CONTROL 0x10
+#define V_CRT_STARTADDR 0x14
+#define V_CRT_STARTADDR_2 0x18
+#define V_ALPHA_STRIDE 0x1C
+#define V_COLOR_KEY 0x20
+#define V_ALPHA_STARTADDR 0x24
+#define V_CHROMAKEY_LOW 0x28
+#define V_CHROMAKEY_HIGH 0x2C
+#define V1_CONTROL 0x30
+#define V12_QWORD_PER_LINE 0x34
+#define V1_STARTADDR_1 0x38
+#define V1_STARTADDR_Y1 V1_STARTADDR_1
+#define V1_STRIDE 0x3C
+#define V1_WIN_START_Y 0x40
+#define V1_WIN_START_X 0x42
+#define V1_WIN_END_Y 0x44
+#define V1_WIN_END_X 0x46
+#define V1_STARTADDR_2 0x48
+#define V1_STARTADDR_Y2 V1_STARTADDR_2
+#define V1_ZOOM_CONTROL 0x4C
+#define V1_MINI_CONTROL 0x50
+#define V1_STARTADDR_0 0x54
+#define V1_STARTADDR_Y0 V1_STARTADDR_0
+#define V_FIFO_CONTROL 0x58
+#define V1_STARTADDR_3 0x5C
+#define V1_STARTADDR_Y3 V1_STARTADDR_3
+#define HI_CONTROL 0x60
+#define SND_COLOR_KEY 0x64
+#define ALPHA_V3_PREFIFO_CONTROL 0x68
+#define V1_SOURCE_HEIGHT 0x6C
+#define HI_TRANSPARENT_COLOR 0x70
+#define V_DISPLAY_TEMP 0x74 /* No use */
+#define ALPHA_V3_FIFO_CONTROL 0x78
+#define V3_SOURCE_WIDTH 0x7C
+#define V3_COLOR_KEY 0x80
+#define V1_ColorSpaceReg_1 0x84
+#define V1_ColorSpaceReg_2 0x88
+#define V1_STARTADDR_CB0 0x8C
+#define V1_OPAQUE_CONTROL 0x90 /* To be deleted */
+#define V3_OPAQUE_CONTROL 0x94 /* To be deleted */
+#define V_COMPOSE_MODE 0x98
+#define V3_STARTADDR_2 0x9C
+#define V3_CONTROL 0xA0
+#define V3_STARTADDR_0 0xA4
+#define V3_STARTADDR_1 0xA8
+#define V3_STRIDE 0xAC
+#define V3_WIN_START_Y 0xB0
+#define V3_WIN_START_X 0xB2
+#define V3_WIN_END_Y 0xB4
+#define V3_WIN_END_X 0xB6
+#define V3_ALPHA_QWORD_PER_LINE 0xB8
+#define V3_ZOOM_CONTROL 0xBC
+#define V3_MINI_CONTROL 0xC0
+#define V3_ColorSpaceReg_1 0xC4
+#define V3_ColorSpaceReg_2 0xC8
+#define V3_DISPLAY_TEMP 0xCC /* No use */
+#define V1_STARTADDR_CB1 0xE4
+#define V1_STARTADDR_CB2 0xE8
+#define V1_STARTADDR_CB3 0xEC
+#define V1_STARTADDR_CR0 0xF0
+#define V1_STARTADDR_CR1 0xF4
+#define V1_STARTADDR_CR2 0xF8
+#define V1_STARTADDR_CR3 0xFC
+
+/* Video Capture Engine Registers
+ * Capture Port 1
+ */
+#define CAP0_MASKS 0x100
+#define CAP1_MASKS 0x104
+#define CAP0_CONTROL 0x110
+#define CAP0_H_RANGE 0x114
+#define CAP0_V_RANGE 0x118
+#define CAP0_SCAL_CONTROL 0x11C
+#define CAP0_VBI_H_RANGE 0x120
+#define CAP0_VBI_V_RANGE 0x124
+#define CAP0_VBI_STARTADDR 0x128
+#define CAP0_VBI_STRIDE 0x12C
+#define CAP0_ANCIL_COUNT 0x130
+#define CAP0_MAXCOUNT 0x134
+#define CAP0_VBIMAX_COUNT 0x138
+#define CAP0_DATA_COUNT 0x13C
+#define CAP0_FB_STARTADDR0 0x140
+#define CAP0_FB_STARTADDR1 0x144
+#define CAP0_FB_STARTADDR2 0x148
+#define CAP0_STRIDE 0x150
+/* Capture Port 2 */
+#define CAP1_CONTROL 0x154
+#define CAP1_SCAL_CONTROL 0x160
+#define CAP1_VBI_H_RANGE 0x164 /*To be deleted*/
+#define CAP1_VBI_V_RANGE 0x168 /*To be deleted*/
+#define CAP1_VBI_STARTADDR 0x16C /*To be deleted*/
+#define CAP1_VBI_STRIDE 0x170 /*To be deleted*/
+#define CAP1_ANCIL_COUNT 0x174 /*To be deleted*/
+#define CAP1_MAXCOUNT 0x178
+#define CAP1_VBIMAX_COUNT 0x17C /*To be deleted*/
+#define CAP1_DATA_COUNT 0x180
+#define CAP1_FB_STARTADDR0 0x184
+#define CAP1_FB_STARTADDR1 0x188
+#define CAP1_STRIDE 0x18C
+
+/* SUBPICTURE Registers */
+#define SUBP_CONTROL_STRIDE 0x1C0
+#define SUBP_STARTADDR 0x1C4
+#define RAM_TABLE_CONTROL 0x1C8
+#define RAM_TABLE_READ 0x1CC
+
+/* HQV Registers */
+#define HQV_CONTROL 0x1D0
+#define HQV_SRC_STARTADDR_Y 0x1D4
+#define HQV_SRC_STARTADDR_U 0x1D8
+#define HQV_SRC_STARTADDR_V 0x1DC
+#define HQV_SRC_FETCH_LINE 0x1E0
+#define HQV_FILTER_CONTROL 0x1E4
+#define HQV_MINIFY_CONTROL 0x1E8
+#define HQV_DST_STARTADDR0 0x1EC
+#define HQV_DST_STARTADDR1 0x1F0
+#define HQV_DST_STARTADDR2 0x1FC
+#define HQV_DST_STRIDE 0x1F4
+#define HQV_SRC_STRIDE 0x1F8
+
+#define PRO_HQV1_OFFSET 0x1000
+/*
+ * Video command definition
+ */
+/* #define V_ALPHA_CONTROL 0x210 */
+#define ALPHA_WIN_EXPIRENUMBER_4 0x00040000
+#define ALPHA_WIN_CONSTANT_FACTOR_4 0x00004000
+#define ALPHA_WIN_CONSTANT_FACTOR_12 0x0000c000
+#define ALPHA_WIN_BLENDING_CONSTANT 0x00000000
+#define ALPHA_WIN_BLENDING_ALPHA 0x00000001
+#define ALPHA_WIN_BLENDING_GRAPHIC 0x00000002
+#define ALPHA_WIN_PREFIFO_THRESHOLD_12 0x000c0000
+#define ALPHA_WIN_FIFO_THRESHOLD_8 0x000c0000
+#define ALPHA_WIN_FIFO_DEPTH_16 0x00100000
+
+/* V_CHROMAKEY_LOW 0x228 */
+#define V_CHROMAKEY_V3 0x80000000
+
+/* V1_CONTROL 0x230 */
+#define V1_ENABLE 0x00000001
+#define V1_FULL_SCREEN 0x00000002
+#define V1_YUV422 0x00000000
+#define V1_RGB32 0x00000004
+#define V1_RGB15 0x00000008
+#define V1_RGB16 0x0000000C
+#define V1_YCbCr420 0x00000010
+#define V1_COLORSPACE_SIGN 0x00000080
+#define V1_SRC_IS_FIELD_PIC 0x00000200
+#define V1_SRC_IS_FRAME_PIC 0x00000000
+#define V1_BOB_ENABLE 0x00400000
+#define V1_FIELD_BASE 0x00000000
+#define V1_FRAME_BASE 0x01000000
+#define V1_SWAP_SW 0x00000000
+#define V1_SWAP_HW_HQV 0x02000000
+#define V1_SWAP_HW_CAPTURE 0x04000000
+#define V1_SWAP_HW_MC 0x06000000
+/* #define V1_DOUBLE_BUFFERS 0x00000000 */
+/* #define V1_QUADRUPLE_BUFFERS 0x18000000 */
+#define V1_EXPIRE_NUM 0x00050000
+#define V1_EXPIRE_NUM_A 0x000a0000
+#define V1_EXPIRE_NUM_F 0x000f0000 /* jason */
+#define V1_FIFO_EXTENDED 0x00200000
+#define V1_ON_CRT 0x00000000
+#define V1_ON_SND_DISPLAY 0x80000000
+#define V1_FIFO_32V1_32V2 0x00000000
+#define V1_FIFO_48V1_32V2 0x00200000
+
+/* V12_QWORD_PER_LINE 0x234 */
+#define V1_FETCH_COUNT 0x3ff00000
+#define V1_FETCHCOUNT_ALIGNMENT 0x0000000f
+#define V1_FETCHCOUNT_UNIT 0x00000004 /* Doubld QWORD */
+
+/* V1_STRIDE */
+#define V1_STRIDE_YMASK 0x00001fff
+#define V1_STRIDE_UVMASK 0x1ff00000
+
+/* V1_ZOOM_CONTROL 0x24C */
+#define V1_X_ZOOM_ENABLE 0x80000000
+#define V1_Y_ZOOM_ENABLE 0x00008000
+
+/* V1_MINI_CONTROL 0x250 */
+#define V1_X_INTERPOLY 0x00000002 /* X interpolation */
+#define V1_Y_INTERPOLY 0x00000001 /* Y interpolation */
+#define V1_YCBCR_INTERPOLY 0x00000004 /* Y, Cb, Cr all interpolation */
+#define V1_X_DIV_2 0x01000000
+#define V1_X_DIV_4 0x03000000
+#define V1_X_DIV_8 0x05000000
+#define V1_X_DIV_16 0x07000000
+#define V1_Y_DIV_2 0x00010000
+#define V1_Y_DIV_4 0x00030000
+#define V1_Y_DIV_8 0x00050000
+#define V1_Y_DIV_16 0x00070000
+
+/* V1_STARTADDR0 0x254 */
+#define SW_FLIP_ODD 0x08000000
+
+/* V_FIFO_CONTROL 0x258
+ * IA2 has 32 level FIFO for packet mode video format
+ * 32 level FIFO for planar mode video YV12. with extension reg 230 bit 21 enable
+ * 16 level FIFO for planar mode video YV12. with extension reg 230 bit 21 disable
+ * BCos of 128 bits. 1 level in IA2 = 2 level in VT3122
+ */
+#define V1_FIFO_DEPTH12 0x0000000B
+#define V1_FIFO_DEPTH16 0x0000000F
+#define V1_FIFO_DEPTH32 0x0000001F
+#define V1_FIFO_DEPTH48 0x0000002F
+#define V1_FIFO_DEPTH64 0x0000003F
+#define V1_FIFO_THRESHOLD6 0x00000600
+#define V1_FIFO_THRESHOLD8 0x00000800
+#define V1_FIFO_THRESHOLD12 0x00000C00
+#define V1_FIFO_THRESHOLD16 0x00001000
+#define V1_FIFO_THRESHOLD24 0x00001800
+#define V1_FIFO_THRESHOLD32 0x00002000
+#define V1_FIFO_THRESHOLD40 0x00002800
+#define V1_FIFO_THRESHOLD48 0x00003000
+#define V1_FIFO_THRESHOLD56 0x00003800
+#define V1_FIFO_THRESHOLD61 0x00003D00
+#define V1_FIFO_PRETHRESHOLD10 0x0A000000
+#define V1_FIFO_PRETHRESHOLD12 0x0C000000
+#define V1_FIFO_PRETHRESHOLD29 0x1d000000
+#define V1_FIFO_PRETHRESHOLD40 0x28000000
+#define V1_FIFO_PRETHRESHOLD44 0x2c000000
+#define V1_FIFO_PRETHRESHOLD56 0x38000000
+#define V1_FIFO_PRETHRESHOLD61 0x3D000000
+
+/* ALPHA_V3_FIFO_CONTROL 0x278
+ * IA2 has 32 level FIFO for packet mode video format
+ * 32 level FIFO for planar mode video YV12. with extension reg 230 bit 21 enable
+ * 16 level FIFO for planar mode video YV12. with extension reg 230 bit 21 disable
+ * 8 level FIFO for ALPHA
+ * BCos of 128 bits. 1 level in IA2 = 2 level in VT3122
+ */
+#define V3_FIFO_DEPTH16 0x0000000F
+#define V3_FIFO_DEPTH24 0x00000017
+#define V3_FIFO_DEPTH32 0x0000001F
+#define V3_FIFO_DEPTH48 0x0000002F
+#define V3_FIFO_DEPTH64 0x0000003F
+#define V3_FIFO_THRESHOLD8 0x00000800
+#define V3_FIFO_THRESHOLD12 0x00000C00
+#define V3_FIFO_THRESHOLD16 0x00001000
+#define V3_FIFO_THRESHOLD24 0x00001800
+#define V3_FIFO_THRESHOLD29 0x00001D00
+#define V3_FIFO_THRESHOLD32 0x00002000
+#define V3_FIFO_THRESHOLD40 0x00002800
+#define V3_FIFO_THRESHOLD48 0x00003000
+#define V3_FIFO_THRESHOLD56 0x00003800
+#define V3_FIFO_THRESHOLD61 0x00003D00
+#define V3_FIFO_PRETHRESHOLD10 0x0000000A
+#define V3_FIFO_PRETHRESHOLD12 0x0000000C
+#define V3_FIFO_PRETHRESHOLD29 0x0000001d
+#define V3_FIFO_PRETHRESHOLD40 0x00000028
+#define V3_FIFO_PRETHRESHOLD44 0x0000002c
+#define V3_FIFO_PRETHRESHOLD56 0x00000038
+#define V3_FIFO_PRETHRESHOLD61 0x0000003D
+#define V3_FIFO_MASK 0x0000007F
+#define V3_FIFO_MASK_3314 0x000000FF
+#define ALPHA_FIFO_DEPTH8 0x00070000
+#define ALPHA_FIFO_THRESHOLD4 0x04000000
+#define ALPHA_FIFO_MASK 0xffff0000
+#define ALPHA_FIFO_PRETHRESHOLD4 0x00040000
+
+/* IA2 */
+#define ColorSpaceValue_1 0x140020f2
+#define ColorSpaceValue_2 0x0a0a2c00
+
+#define ColorSpaceValue_1_3123C0 0x13000DED
+#define ColorSpaceValue_2_3123C0 0x13171000
+#define ColorSpaceValue_1_32045 0x13000DED
+#define ColorSpaceValue_2_32045 0x13171000
+
+/* For TV setting */
+#define ColorSpaceValue_1TV 0x140020f2
+#define ColorSpaceValue_2TV 0x0a0a2c00
+
+/* V_COMPOSE_MODE 0x298 */
+#define SELECT_VIDEO_IF_COLOR_KEY 0x00000001 /* select video if (color key),otherwise select graphics */
+#define SELECT_VIDEO3_IF_COLOR_KEY 0x00000020 /* For 3123C0, select video3 if (color key),otherwise select graphics */
+#define SELECT_VIDEO_IF_CHROMA_KEY 0x00000002 /* 0x0000000a //select video if (chroma key ),otherwise select graphics */
+#define ALWAYS_SELECT_VIDEO 0x00000000 /* always select video,Chroma key and Color key disable */
+#define COMPOSE_V1_V3 0x00000000 /* V1 on top of V3 */
+#define COMPOSE_V3_V1 0x00100000 /* V3 on top of V1 */
+#define COMPOSE_V1_TOP 0x00000000
+#define COMPOSE_V3_TOP 0x00100000
+#define V1_COMMAND_FIRE 0x80000000 /* V1 commands fire */
+#define V3_COMMAND_FIRE 0x40000000 /* V3 commands fire */
+#define V_COMMAND_LOAD 0x20000000 /* Video register always loaded */
+#define V_COMMAND_LOAD_VBI 0x10000000 /* Video register always loaded at vbi without waiting source flip */
+#define V3_COMMAND_LOAD 0x08000000 /* CLE_C0 Video3 register always loaded */
+#define V3_COMMAND_LOAD_VBI 0x00000100 /* CLE_C0 Video3 register always loaded at vbi without waiting source flip */
+#define SECOND_DISPLAY_COLOR_KEY_ENABLE 0x00010000
+
+/* V3_ZOOM_CONTROL 0x2bc */
+#define V3_X_ZOOM_ENABLE 0x80000000
+#define V3_Y_ZOOM_ENABLE 0x00008000
+
+/* V3_MINI_CONTROL 0x2c0 */
+#define V3_X_INTERPOLY 0x00000002 /* X interpolation */
+#define V3_Y_INTERPOLY 0x00000001 /* Y interpolation */
+#define V3_YCBCR_INTERPOLY 0x00000004 /* Y, Cb, Cr all interpolation */
+#define V3_X_DIV_2 0x01000000
+#define V3_X_DIV_4 0x03000000
+#define V3_X_DIV_8 0x05000000
+#define V3_X_DIV_16 0x07000000
+#define V3_Y_DIV_2 0x00010000
+#define V3_Y_DIV_4 0x00030000
+#define V3_Y_DIV_8 0x00050000
+#define V3_Y_DIV_16 0x00070000
+
+/* SUBP_CONTROL_STRIDE 0x3c0 */
+#define SUBP_HQV_ENABLE 0x00010000
+#define SUBP_IA44 0x00020000
+#define SUBP_AI44 0x00000000
+#define SUBP_STRIDE_MASK 0x00001fff
+#define SUBP_CONTROL_MASK 0x00070000
+
+/* RAM_TABLE_CONTROL 0x3c8 */
+#define RAM_TABLE_RGB_ENABLE 0x00000007
+
+/* CAPTURE0_CONTROL 0x310 */
+#define C0_ENABLE 0x00000001
+#define BUFFER_2_MODE 0x00000000
+#define BUFFER_3_MODE 0x00000004
+#define BUFFER_4_MODE 0x00000006
+#define SWAP_YUYV 0x00000000
+#define SWAP_UYVY 0x00000100
+#define SWAP_YVYU 0x00000200
+#define SWAP_VYUY 0x00000300
+#define IN_601_8 0x00000000
+#define IN_656_8 0x00000010
+#define IN_601_16 0x00000020
+#define IN_656_16 0x00000030
+#define DEINTER_ODD 0x00000000
+#define DEINTER_EVEN 0x00001000
+#define DEINTER_ODD_EVEN 0x00002000
+#define DEINTER_FRAME 0x00003000
+#define VIP_1 0x00000000
+#define VIP_2 0x00000400
+#define H_FILTER_2 0x00010000
+#define H_FILTER_4 0x00020000
+#define H_FILTER_8_1331 0x00030000
+#define H_FILTER_8_12221 0x00040000
+#define VIP_ENABLE 0x00000008
+#define EN_FIELD_SIG 0x00000800
+#define VREF_INVERT 0x00100000
+#define FIELD_INPUT_INVERSE 0x00400000
+#define FIELD_INVERSE 0x40000000
+
+#define C1_H_MINI_EN 0x00000800
+#define C0_H_MINI_EN 0x00000800
+#define C1_V_MINI_EN 0x04000000
+#define C0_V_MINI_EN 0x04000000
+#define C1_H_MINI_2 0x00000400
+
+/* CAPTURE1_CONTROL 0x354 */
+#define C1_ENABLE 0x00000001
+
+/* V3_CONTROL 0x2A0 */
+#define V3_ENABLE 0x00000001
+#define V3_FULL_SCREEN 0x00000002
+#define V3_YUV422 0x00000000
+#define V3_RGB32 0x00000004
+#define V3_RGB15 0x00000008
+#define V3_RGB16 0x0000000C
+#define V3_COLORSPACE_SIGN 0x00000080
+#define V3_EXPIRE_NUM 0x00040000
+#define V3_EXPIRE_NUM_F 0x000f0000
+#define V3_EXPIRE_NUM_3204 0x00100000
+#define V3_EXPIRE_NUM_3205 0x00080000
+#define V3_BOB_ENABLE 0x00400000
+#define V3_FIELD_BASE 0x00000000
+#define V3_FRAME_BASE 0x01000000
+#define V3_SWAP_SW 0x00000000
+#define V3_SWAP_HW_HQV 0x02000000
+#define V3_FLIP_HW_CAPTURE0 0x04000000
+#define V3_FLIP_HW_CAPTURE1 0x06000000
+
+/* V3_ALPHA_FETCH_COUNT 0x2B8 */
+#define V3_FETCH_COUNT 0x3ff00000
+#define ALPHA_FETCH_COUNT 0x000003ff
+
+/* HQV_CONTROL 0x3D0 */
+#define HQV_RGB32 0x00000000
+#define HQV_RGB16 0x20000000
+#define HQV_RGB15 0x30000000
+#define HQV_YUV422 0x80000000
+#define HQV_YUV420 0xC0000000
+#define HQV_ENABLE 0x08000000
+#define HQV_SRC_SW 0x00000000
+#define HQV_SRC_MC 0x01000000
+#define HQV_SRC_CAPTURE0 0x02000000
+#define HQV_SRC_CAPTURE1 0x03000000
+#define HQV_FLIP_EVEN 0x00000000
+#define HQV_FLIP_ODD 0x00000020
+#define HQV_SW_FLIP 0x00000010 /* Write 1 to flip HQV buffer */
+#define HQV_DEINTERLACE 0x00010000 /* First line of odd field will be repeated 3 times */
+#define HQV_FIELD_2_FRAME 0x00020000 /* Src is field. Display each line 2 times */
+#define HQV_FRAME_2_FIELD 0x00040000 /* Src is field. Display field */
+#define HQV_FRAME_UV 0x00000000 /* Src is Non-interleaved */
+#define HQV_FIELD_UV 0x00100000 /* Src is interleaved */
+#define HQV_IDLE 0x00000008
+#define HQV_FLIP_STATUS 0x00000001
+#define HQV_DOUBLE_BUFF 0x00000000
+#define HQV_TRIPLE_BUFF 0x04000000
+#define HQV_SUBPIC_FLIP 0x00008000
+#define HQV_FIFO_STATUS 0x00001000
+#define HQV_GEN_IRQ 0x00000080
+#define HQV_FIFO_DEPTH_1 0x00010000
+
+/* HQV_FILTER_CONTROL 0x3E4 */
+#define HQV_H_LOWPASS_2TAP 0x00000001
+#define HQV_H_LOWPASS_4TAP 0x00000002
+#define HQV_H_LOWPASS_8TAP1 0x00000003 /* To be deleted */
+#define HQV_H_LOWPASS_8TAP2 0x00000004 /* To be deleted */
+#define HQV_H_HIGH_PASS 0x00000008
+#define HQV_H_LOW_PASS 0x00000000
+#define HQV_V_LOWPASS_2TAP 0x00010000
+#define HQV_V_LOWPASS_4TAP 0x00020000
+#define HQV_V_LOWPASS_8TAP1 0x00030000
+#define HQV_V_LOWPASS_8TAP2 0x00040000
+#define HQV_V_HIGH_PASS 0x00080000
+#define HQV_V_LOW_PASS 0x00000000
+#define HQV_H_HIPASS_F1_DEFAULT 0x00000040
+#define HQV_H_HIPASS_F2_DEFAULT 0x00000000
+#define HQV_V_HIPASS_F1_DEFAULT 0x00400000
+#define HQV_V_HIPASS_F2_DEFAULT 0x00000000
+#define HQV_H_HIPASS_F1_2TAP 0x00000050
+#define HQV_H_HIPASS_F2_2TAP 0x00000100
+#define HQV_V_HIPASS_F1_2TAP 0x00500000
+#define HQV_V_HIPASS_F2_2TAP 0x01000000
+#define HQV_H_HIPASS_F1_4TAP 0x00000060
+#define HQV_H_HIPASS_F2_4TAP 0x00000200
+#define HQV_V_HIPASS_F1_4TAP 0x00600000
+#define HQV_V_HIPASS_F2_4TAP 0x02000000
+#define HQV_H_HIPASS_F1_8TAP 0x00000080
+#define HQV_H_HIPASS_F2_8TAP 0x00000400
+#define HQV_V_HIPASS_F1_8TAP 0x00800000
+#define HQV_V_HIPASS_F2_8TAP 0x04000000
+/* IA2 NEW */
+#define HQV_V_FILTER2 0x00080000
+#define HQV_H_FILTER2 0x00000008
+#define HQV_H_TAP2_11 0x00000041
+#define HQV_H_TAP4_121 0x00000042
+#define HQV_H_TAP4_1111 0x00000401
+#define HQV_H_TAP8_1331 0x00000221
+#define HQV_H_TAP8_12221 0x00000402
+#define HQV_H_TAP16_1991 0x00000159
+#define HQV_H_TAP16_141041 0x0000026A
+#define HQV_H_TAP32 0x0000015A
+#define HQV_V_TAP2_11 0x00410000
+#define HQV_V_TAP4_121 0x00420000
+#define HQV_V_TAP4_1111 0x04010000
+#define HQV_V_TAP8_1331 0x02210000
+#define HQV_V_TAP8_12221 0x04020000
+#define HQV_V_TAP16_1991 0x01590000
+#define HQV_V_TAP16_141041 0x026A0000
+#define HQV_V_TAP32 0x015A0000
+#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
+#define HQV_V_MINIFY_ENABLE 0x08000000
+#define HQV_V_MINIFY_DOWN 0x10000000
+#define HQV_VDEBLOCK_FILTER 0x80000000
+#define HQV_HDEBLOCK_FILTER 0x00008000
+
+
+#define CHROMA_KEY_LOW 0x00FFFFFF
+#define CHROMA_KEY_HIGH 0x00FFFFFF
+
+/* V_CAP_STATUS */
+#define V_ST_UPDATE_NOT_YET 0x00000003
+#define V1_ST_UPDATE_NOT_YET 0x00000001
+#define V3_ST_UPDATE_NOT_YET 0x00000008
+
+#define VBI_STATUS 0x00000002
+
+/*
+ * Macros for Video MMIO
+ */
+#ifndef V4L2
+#define VIDInB(port) *((volatile CARD8 *)(pVia->VidMapBase + (port)))
+#define VIDInW(port) *((volatile CARD16 *)(pVia->VidMapBase + (port)))
+#define VIDInD(port) *((volatile CARD32 *)(pVia->VidMapBase + (port)))
+#define VIDOutB(port, data) *((volatile CARD8 *)(pVia->VidMapBase + (port))) = (data)
+#define VIDOutW(port, data) *((volatile CARD16 *)(pVia->VidMapBase + (port))) = (data)
+#define VIDOutD(port, data) *((volatile CARD32 *)(pVia->VidMapBase + (port))) = (data)
+#define MPGOutD(port, data) *((volatile CARD32 *)(pVia->MpegMapBase +(port))) = (data)
+#define MPGInD(port) *((volatile CARD32 *)(pVia->MpegMapBase +(port)))
+#endif
+
+/*
+ * Macros for GE MMIO
+ */
+#define GEInW(port) *((volatile CARD16 *)(lpGEMMIO + (port)))
+#define GEInD(port) *((volatile CARD32 *)(lpGEMMIO + (port)))
+#define GEOutW(port, data) *((volatile CARD16 *)(lpGEMMIO + (port))) = (data)
+#define GEOutD(port, data) *((volatile CARD32 *)(lpGEMMIO + (port))) = (data)
+
+/*
+ * MPEG 1/2 Slice Engine (at 0xC00 relative to base)
+ */
+
+#define MPG_CONTROL 0x00
+#define MPG_CONTROL_STRUCT 0x03
+#define MPG_CONTROL_STRUCT_TOP 0x01
+#define MPG_CONTROL_STRUCT_BOTTOM 0x02
+#define MPG_CONTROL_STRUCT_FRAME 0x03
+ /* Use TOP if interlaced */
+#define MPG_CONTROL_TYPE 0x3C
+#define MPG_CONTROL_TYPE_I (0x01 << 2)
+#define MPG_CONTROL_TYPE_B (0x02 << 2)
+#define MPG_CONTROL_TYPE_P (0x03 << 3)
+#define MPG_CONTROL_ALTSCAN 0x40
+#define MPG_BLOCK 0x08 /* Unsure */
+#define MPG_COMMAND 0x0C
+#define MPG_DATA1 0x10
+#define MPG_DATA2 0x14
+#define MPG_DATA3 0x18
+#define MPG_DATA4 0x1C
+
+#define MPG_YPHYSICAL(x) (0x20 + 12*(x))
+#define MPG_CbPHYSICAL(x) (0x24 + 12*(x))
+#define MPG_CrPHYSICAL(x) (0x28 + 12*(x))
+
+#define MPG_PITCH 0x50
+#define MPG_STATUS 0x54
+
+#define MPG_MATRIX_IDX 0x5C
+#define MPG_MATRIX_IDX_INTRA 0x00
+#define MPG_MATRIX_IDX_NON 0x01
+#define MPG_MATRIX_DATA 0x60
+
+#define MPG_SLICE_CTRL_1 0x90
+#define MPG_SLICE_MBAMAX 0x2FFF
+#define MPG_SLICE_PREDICTIVE_DCT 0x4000
+#define MPG_SLICE_TOP_FIRST 0x8000
+#define MPG_SLICE_MACROBLOCK_WIDTH(x) ((x)<<18) /* in 64's */
+#define MPG_SLICE_CTRL_2 0x94
+#define MPG_SLICE_CONCEAL_MVEC 0x0000001
+#define MPG_SLICE_QSCALE_TYPE 0x0000002
+#define MPG_SLICE_DCPRECISION 0x000000C
+#define MPG_SLICE_MACROBQUOT 0x0FFFFF0
+#define MPG_SLICE_INTRAVLC 0x1000000
+#define MPG_SLICE_CTRL_3 0x98
+#define MPG_SLICE_FHMVR 0x0000003
+#define MPG_SLICE_FVMVR 0x000000C
+#define MPG_SLICE_BHMVR 0x0000030
+#define MPG_SLICE_BVMVR 0x00000C0
+#define MPG_SLICE_SECOND_FIELD 0x0100000
+#define MPG_SLICE_RESET 0x0400000
+#define MPG_SLICE_LENGTH 0x9C
+#define MPG_SLICE_DATA 0xA0
+
+
+
+#endif /* _VIA_H_ */
diff --git a/src/via.man b/src/via.man
new file mode 100644
index 000000000000..4a52fc05c3d4
--- /dev/null
+++ b/src/via.man
@@ -0,0 +1,232 @@
+.\" Shorthand for double quote that works everywhere,
+.\" also within other double quotes:
+.ds q \N'34'
+.TH VIA __drivermansuffix__ __vendorversion__
+.SH NAME
+via \- video driver for VIA Unichromes
+.SH SYNOPSIS
+.nf
+.B "Section \*qDevice\*q"
+.BI " Identifier \*q" string \*q
+.B " Driver \*qvia\*q"
+\ \ ...
+.B EndSection
+.fi
+
+.SH DESCRIPTION
+.B via
+is an __xservername__ driver for VIA chipsets that have an integrated
+Unichrome graphics engine.
+.PP
+The
+.B via
+driver supports the CLE266, KM/N400, K8M/N800, PM/N800 and CN400 chipsets
+from VIA, including 2D acceleration and the Xv video overlay extensions.
+Flat panel, TV, and VGA outputs are supported, depending on the hardware
+configuration.
+.PP
+3D direct rendering is available using experimental drivers from Mesa
+(www.mesa3d.org). There is also an XvMC client library for hardware
+acceleration of MPEG1/MPEG2 decoding (available on the CLE266,
+PM/N800, K8M/N800, and CN400 chipsets) that uses the Direct Rendering
+Infrastructure (DRI). The XvMC client library implements a non-standard
+"VLD" extension to the XvMC standard. The current Direct Rendering
+Manager (DRM) kernel module is available at dri.sourceforge.net.
+.PP
+The driver supports free modes for Unichrome Pros (K8M/N800, PM/N800, and
+CN400). For plain Unichromes (CLE266, KM/N400), it currently supports
+only a limited number of dotclocks, so if you are using X modelines you
+must make sure that the dotclock is one of those supported. Supported
+dotclocks on plain Unichromes are currently (in MHz): 25.2, 25.312,
+26.591, 31.5, 31.704, 32.663, 33.750, 35.5, 36.0, 39.822, 40.0, 41.164,
+46.981, 49.5, 50.0, 56.3, 57.284, 64.995, 65.0, 65.028, 74.480,
+75.0, 78.8, 81.613, 94.5, 108.0, 108.28, 122.0, 122.726, 135.0,
+148.5, 155.8, 157.5, 161.793, 162.0, 175.5, 189.0, 202.5, 204.8,
+218.3, 229.5. On top of this, bandwidth restrictions apply for both
+Unichromes and Unichrome Pros.
+.PP
+.SH CONFIGURATION DETAILS
+Please refer to __xconfigfile__(__filemansuffix__) for general configuration
+details. This section only covers configuration details specific to this
+driver.
+.PP
+The following driver
+.B options
+are supported:
+.TP
+.BI "Option \*qAccelMethod\*q \*q" string \*q
+The driver supports "XAA" and "EXA" acceleration methods. The default
+method is XAA, since EXA is still experimental. Contrary to XAA, EXA
+implements acceleration for screen uploads and downlads (if DRI is
+enabled) and for the Render/Composite extension.
+.TP
+.BI "Option \*qActiveDevice\*q \*q" string \*q
+Specifies the active device combination. Any string containing "CRT",
+"LCD", "DFP", "TV" should be possible. "CRT" represents anything that
+is connected to the VGA port, "LCD" and "DFP" are for laptop panels
+(not TFT screens attached to the VGA port), "TV" is self-explanatory.
+The default is to use what is detected. The driver is currently unable
+to use LCD and TV simultaneously, and will favour the LCD.
+.TP
+.BI "Option \*qAGPMem\*q \*q" integer \*q
+Sets the amount of AGP memory that is allocated at X server startup.
+The allocated memory will be "integer" kB. This AGP memory is used for
+the AGP command buffer (if option "EnableAGPDMA" is set to "true"), for
+DRI textures, and for the EXA scratch area. The driver will allocate at
+least one system page of AGP memory and, if the AGP command buffer is
+used, at least 2MB + one system page. If there is no room for the EXA
+scratch area in AGP space, it will be allocated from VRAM. If there is
+no room for DRI textures, they will be allocated from the DRI part of
+VRAM (see the option "MaxDRIMem"). The default amount of AGP is
+32768kB. Note that the AGP aperture set in the BIOS must be able
+to accomodate the amount of AGP memory specified here. Otherwise no
+AGP memory will be available. It is safe to set a very large AGP
+aperture in the BIOS.
+.TP
+.BI "Option \*qCenter\*q \*q" boolean \*q
+Enables or disables image centering on DVI displays.
+.TP
+.BI "Option \*qDisableIRQ\*q \*q" boolean \*q
+Disables the Vblank IRQ. This is a workaround for some mainboards that
+have problems with IRQs from the Unichrome engine. With IRQs disabled,
+DRI clients have no way to synchronize drawing to Vblank. ( Enabled by
+default on the KM400 and K8M800 Chipsets )
+.TP
+.BI "Option \*qDisableVQ\*q \*q" boolean \*q
+Disables the use of VQ. VQ is enabled by default.
+.TP
+.BI "Option \*qEnableAGPDMA\*q \*q" boolean \*q
+Enables the AGP DMA functionality in DRM. This requires that DRI is enabled
+and will force 2D and 3D acceleration to use AGP DMA. The XvMC DRI client
+will also make use of this on the CLE266 to consume much less CPU. ( This is
+enabled by default on all chipsets except the K8M890 and P4M900 )
+.TP
+.BI "Option \*qExaNoComposite\*q \*q" boolean \*q
+If EXA is enabled (using the option "AccelMethod"), this option enables
+or disables acceleration of compositing. Since EXA, and in particular its
+composite acceleration, is still experimental, this is a way to disable
+a misbehaving composite acceleration.
+.TP
+.BI "Option \*qExaScratchSize\*q \*q" integer \*q
+Sets the size of the EXA scratch area to "integer" kB. This area is
+used by EXA as a last place to look for available space for pixmaps.
+Too little space will slow compositing down. This option should be set
+to the size of the largest pixmap used. If you have a screen width of
+over 1024 pixels and use 24 bpp, set this to 8192. Otherwise you can
+leave this at the default 4096. The space will be allocated from AGP
+memory if available, otherwise from VRAM.
+.TP
+.BI "Option \*qHWCursor\*q \*q" boolean \*q
+Enables or disables the use of hardware cursors. The default is enabled.
+.TP
+.BI "Option \*qLCDDualEdge\*q \*q" boolean \*q
+Enables or disables the use of dual-edge mode to set the LCD.
+.TP
+.BI "Option \*qMaxDRIMem\*q \*q" integer \*q
+Sets the maximum amount of VRAM memory allocated for DRI clients to
+"integer" kB. Normally DRI clients get half the available VRAM size,
+but in some cases it may make sense to limit this amount. For example,
+if you are using a composite manager and you want to give as much memory
+as possible to the EXA pixmap storage area.
+.TP
+.BI "Option \*qMigrationHeuristic\*q \*q" string \*q
+Sets the heuristic for EXA pixmap migration. This is an EXA core
+option, and on Xorg xserver versions after 1.1.0 this defaults to
+"smart". The Openchrome driver performs best with "greedy", so you
+should really add this option to your configuration file. The third
+possibility is "always", which might become more useful in the future.
+.TP
+.BI "Option \*qNoAccel\*q \*q" boolean \*q
+Disables or enables acceleration. Default: acceleration is enabled.
+.TP
+.BI "Option \*qNoAGPFor2D\*q \*q" boolean \*q
+With this option set, 2D acceleration will not use AGP DMA even if
+it is enabled.
+.TP
+.BI "Option \*qNoXVDMA\*q \*q" boolean \*q
+If DRI is enabled, Xv normally uses PCI DMA to transfer video images
+from system to frame-buffer memory. This is somewhat slower than
+direct copies due to the limitations of the PCI bus, but on the other
+hand it decreases CPU usage significantly, particularly on computers
+with fast processors. Some video players are buggy and will display
+rendering artifacts when PCI DMA is used. If you experience this,
+or don't want your PCI bus to be stressed with Xv images, set this
+option to "true". This option has no effect when DRI is not enabled.
+.TP
+.BI "Option \*qPanelSize\*q \*q" string \*q
+Specifies the size (width x height) of the LCD panel attached to the
+system. The sizes 640x480, 800x600, 1024x768, 1280x1024, and 1400x1050
+are supported.
+.TP
+.BI "Option \*qRotate\*q \*q" string \*q
+Rotates the display either clockwise ("CW") or counterclockwise ("CCW").
+Rotation is only supported unaccelerated.
+.TP
+.BI "Option \*qShadowFB\*q \*q" boolean \*q
+Uses a shadow frame buffer. This is required when rotating the display,
+but otherwise defaults to disabled.
+.TP
+.BI "Option \*qSWCursor\*q \*q" boolean \*q
+Enables or disables the use of a software cursor. The default is disabled.
+.TP
+.BI "Option \*qTVDeflicker\*q \*q" integer \*q
+Specifies the deflicker setting for TV output. Valid values are "0", "1",
+and "2". 0) No deflicker, 1) 1:1:1 deflicker, 2) 1:2:1 deflicker.
+.TP
+.BI "Option \*qTVDotCrawl\*q \*q" boolean \*q
+Enables or disables dotcrawl.
+.TP
+.BI "Option \*qTVOutput\*q \*q" string \*q
+Specifies which TV output to use. The driver supports "S-Video",
+"Composite", "SC", "RGB" and "YCbCr" outputs. Note that on some
+EPIA boards the compositer-video port is shared with audio-out and
+is selected via a jumper.
+.TP
+.BI "Option \*qTVType\*q \*q" string \*q
+Specifies TV output format. The driver currently supports "NTSC" and
+"PAL" timings only.
+.TP
+.BI "Option \*qVBEModes\*q \*q" boolean \*q
+Uses the VBE BIOS calls to set the display mode. This mimics the
+behaviour of the vesa video driver but still provides acceleration and
+other features. This option may be used if your hardware works with
+the vesa driver but not with the Openchrome driver. It may not work
+on 64-bit systems. Using "VBEModes" may speed up driver acceleration
+significantly due to a more aggressive hardware setting, particularly
+on systems with low memory bandwidth. Your refresh rate may be limited
+to 60 Hz on some systems.
+.TP
+.BI "Option \*qVBESaveRestore\*q \*q" boolean \*q
+Uses the VBE BIOS calls to save and restore the display state when the
+X server is launched. This can be extremely slow on some hardware, and
+the system may appear to have locked for 10 seconds or so. The default
+is to use the driver builtin function. This option only works if option
+"VBEModes" is enabled.
+.TP
+.BI "Option \*qVideoRAM\*q \*q" integer \*q
+Overrides the VideoRAM autodetection. This should never be needed.
+.PP
+.SH "TV ENCODERS"
+Unichromes tend to be paired with several different TV encoders.
+.TP
+.BI "VIA Technologies VT1621"
+Still untested, as no combination with a Unichrome is known or available.
+Supports the following normal modes: "640x480" and "800x600". Use
+"640x480Over" and "800x600Over" for vertical overscan. These modes
+are made available by the driver; modelines provided in __xconfigfile__
+will be ignored.
+.TP
+.BI "VIA Technologies VT1622, VT1622A, VT1623"
+Supports the following modes: "640x480", "800x600", "1024x768",
+"848x480", "720x480" (NTSC only) and "720x576" (PAL only). Use
+"640x480Over", "800x600Over", "1024x768Over", "848x480Over",
+"720x480Over" (NTSC) and "720x576Over" (PAL) for vertical overscan.
+The modes "720x480Noscale" (NTSC) and "720x576Noscale" (PAL) (available
+on VT1622 only) provide cleaner TV output (unscaled with only minimal
+overscan). These modes are made available by the driver; modelines
+provided in __xconfigfile__ will be ignored.
+
+.SH "SEE ALSO"
+__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
+.SH AUTHORS
+Authors include: ...
diff --git a/src/via_3d.c b/src/via_3d.c
new file mode 100644
index 000000000000..9ccdaad00856
--- /dev/null
+++ b/src/via_3d.c
@@ -0,0 +1,592 @@
+/*
+ * Copyright 2006 Thomas Hellstrom. 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.
+ */
+
+#include "via_3d.h"
+#include "via_3d_reg.h"
+#include <picturestr.h>
+
+typedef struct
+{
+ Bool supported;
+ CARD32 col0;
+ CARD32 col1;
+ CARD32 al0;
+ CARD32 al1;
+} ViaCompositeOperator;
+
+typedef struct
+{
+ CARD32 pictFormat;
+ Bool dstSupported;
+ Bool texSupported;
+ CARD32 dstFormat;
+ CARD32 texFormat;
+} Via3DFormat;
+
+static ViaCompositeOperator viaOperatorModes[256];
+static Via3DFormat via3DFormats[256];
+
+#define VIA_NUM_3D_OPCODES 19
+#define VIA_NUM_3D_FORMATS 15
+#define VIA_FMT_HASH(arg) (((((arg) >> 1) + (arg)) >> 8) & 0xFF)
+
+static const CARD32 viaOpCodes[VIA_NUM_3D_OPCODES][5] = {
+ {PictOpClear, 0x05, 0x45, 0x40, 0x80},
+ {PictOpSrc, 0x15, 0x45, 0x50, 0x80},
+ {PictOpDst, 0x05, 0x55, 0x40, 0x90},
+ {PictOpOver, 0x15, 0x52, 0x50, 0x91},
+ {PictOpOverReverse, 0x13, 0x45, 0x52, 0x90},
+ {PictOpIn, 0x03, 0x45, 0x42, 0x80},
+ {PictOpInReverse, 0x05, 0x42, 0x40, 0x81},
+ {PictOpOut, 0x13, 0x45, 0x52, 0x80},
+ {PictOpOutReverse, 0x05, 0x52, 0x40, 0x91},
+ {PictOpAtop, 0x03, 0x52, 0x42, 0x91},
+ {PictOpAtopReverse, 0x13, 0x42, 0x52, 0x81},
+ {PictOpXor, 0x15, 0x52, 0x52, 0x91},
+ {PictOpAdd, 0x15, 0x55, 0x50, 0x90},
+ {PictOpDisjointClear, 0x05, 0x45, 0x40, 0x80},
+ {PictOpDisjointSrc, 0x15, 0x45, 0x50, 0x80},
+ {PictOpDisjointDst, 0x05, 0x55, 0x40, 0x90},
+ {PictOpConjointClear, 0x05, 0x45, 0x40, 0x80},
+ {PictOpConjointSrc, 0x15, 0x45, 0x50, 0x80},
+ {PictOpConjointDst, 0x05, 0x55, 0x40, 0x90}
+};
+
+static const CARD32 viaFormats[VIA_NUM_3D_FORMATS][5] = {
+ {PICT_x1r5g5b5, HC_HDBFM_RGB555, HC_HTXnFM_RGB555, 1, 1},
+ {PICT_r5g6b5, HC_HDBFM_RGB565, HC_HTXnFM_RGB565, 1, 1},
+ {PICT_a4r4g4b4, HC_HDBFM_ARGB4444, HC_HTXnFM_ARGB4444, 1, 1},
+ {PICT_a1r5g5b5, HC_HDBFM_ARGB1555, HC_HTXnFM_ARGB1555, 1, 1},
+ {PICT_x1b5g5r5, HC_HDBFM_BGR555, HC_HTXnFM_BGR555, 1, 1},
+ {PICT_b5g6r5, HC_HDBFM_BGR565, HC_HTXnFM_BGR565, 1, 1},
+ {PICT_a4b4g4r4, HC_HDBFM_ABGR4444, HC_HTXnFM_ABGR4444, 1, 1},
+ {PICT_a1b5g5r5, HC_HDBFM_ABGR1555, HC_HTXnFM_ABGR1555, 1, 1},
+ {PICT_x8r8g8b8, HC_HDBFM_ARGB0888, HC_HTXnFM_ARGB0888, 1, 1},
+ {PICT_a8r8g8b8, HC_HDBFM_ARGB8888, HC_HTXnFM_ARGB8888, 1, 1},
+ {PICT_x8b8g8r8, HC_HDBFM_ABGR0888, HC_HTXnFM_ABGR0888, 1, 1},
+ {PICT_a8b8g8r8, HC_HDBFM_ABGR8888, HC_HTXnFM_ABGR8888, 1, 1},
+ {PICT_a8, 0x00, HC_HTXnFM_A8, 0, 1},
+ {PICT_a4, 0x00, HC_HTXnFM_A4, 0, 1},
+ {PICT_a1, 0x00, HC_HTXnFM_A1, 0, 1}
+};
+
+static CARD32
+via3DDstFormat(int format)
+{
+ return via3DFormats[VIA_FMT_HASH(format)].dstFormat;
+}
+
+static CARD32
+via3DTexFormat(int format)
+{
+ return via3DFormats[VIA_FMT_HASH(format)].texFormat;
+}
+
+static Bool
+via3DDstSupported(int format)
+{
+ Via3DFormat *fm = via3DFormats + VIA_FMT_HASH(format);
+
+ if (fm->pictFormat != format)
+ return FALSE;
+ return fm->dstSupported;
+}
+
+static Bool
+via3DTexSupported(int format)
+{
+ Via3DFormat *fm = via3DFormats + VIA_FMT_HASH(format);
+
+ if (fm->pictFormat != format)
+ return FALSE;
+ return fm->texSupported;
+}
+
+static void
+viaSet3DDestination(Via3DState * v3d, CARD32 offset, CARD32 pitch, int format)
+{
+ v3d->drawingDirty = TRUE; /* Affects planemask format. */
+ v3d->destDirty = TRUE;
+ v3d->destOffset = offset;
+ v3d->destPitch = pitch;
+ v3d->destFormat = via3DDstFormat(format);
+ v3d->destDepth = (v3d->destFormat < HC_HDBFM_ARGB0888) ? 16 : 32;
+}
+
+static void
+viaSet3DDrawing(Via3DState * v3d, int rop,
+ CARD32 planeMask, CARD32 solidColor, CARD32 solidAlpha)
+{
+ v3d->drawingDirty = TRUE;
+ v3d->rop = rop;
+ v3d->planeMask = planeMask;
+ v3d->solidColor = solidColor;
+ v3d->solidAlpha = solidAlpha;
+}
+
+static void
+viaSet3DFlags(Via3DState * v3d, int numTextures,
+ Bool writeAlpha, Bool writeColor, Bool blend)
+{
+ v3d->enableDirty = TRUE;
+ v3d->blendDirty = TRUE;
+ v3d->numTextures = numTextures;
+ v3d->writeAlpha = writeAlpha;
+ v3d->writeColor = writeColor;
+ v3d->blend = blend;
+}
+
+static Bool
+viaOrder(CARD32 val, CARD32 * shift)
+{
+ *shift = 0;
+
+ while (val > (1 << *shift))
+ (*shift)++;
+ return (val == (1 << *shift));
+}
+
+static Bool
+viaSet3DTexture(Via3DState * v3d, int tex, CARD32 offset,
+ CARD32 pitch, Bool npot, CARD32 width, CARD32 height, int format,
+ ViaTextureModes sMode, ViaTextureModes tMode,
+ ViaTexBlendingModes blendingMode, Bool agpTexture)
+{
+ ViaTextureUnit *vTex = v3d->tex + tex;
+
+ vTex->textureLevel0Offset = offset;
+ vTex->npot = npot;
+ if (!viaOrder(pitch, &vTex->textureLevel0Exp) && !vTex->npot)
+ return FALSE;
+ vTex->textureLevel0Pitch = pitch;
+ if (!viaOrder(width, &vTex->textureLevel0WExp))
+ return FALSE;
+ if (!viaOrder(height, &vTex->textureLevel0HExp))
+ return FALSE;
+
+ if (pitch <= 4) {
+ ErrorF("Warning! texture pitch is leq 4\n");
+ }
+
+ vTex->textureFormat = via3DTexFormat(format);
+
+ switch (blendingMode) {
+ case via_src:
+ vTex->texCsat = (0x01 << 23) | (0x10 << 14) | (0x03 << 7) | 0x00;
+ vTex->texAsat =
+ (0x0B << 14) | ((PICT_FORMAT_A(format) ? 0x04 : 0x02) << 7) |
+ 0x03;
+ vTex->texRCa = 0x00000000;
+ vTex->texRAa = 0x00000000;
+ vTex->texBColDirty = TRUE;
+ break;
+ case via_src_onepix_mask:
+ vTex->texCsat = (0x01 << 23) | (0x09 << 14) | (0x03 << 7) | 0x00;
+ vTex->texAsat =
+ (0x03 << 14) | ((PICT_FORMAT_A(format) ? 0x04 : 0x02) << 7) |
+ 0x03;
+ break;
+ case via_src_onepix_comp_mask:
+ vTex->texCsat = (0x01 << 23) | (0x09 << 14) | (0x03 << 7) | 0x00;
+ vTex->texAsat =
+ (0x03 << 14) | ((PICT_FORMAT_A(format) ? 0x04 : 0x02) << 7) |
+ 0x03;
+ break;
+ case via_mask:
+ vTex->texCsat = (0x01 << 23) | (0x07 << 14) | (0x04 << 7) | 0x00;
+ vTex->texAsat = (0x01 << 23) | (0x04 << 14) | (0x02 << 7) | 0x03;
+ break;
+ case via_comp_mask:
+ vTex->texCsat = (0x01 << 23) | (0x03 << 14) | (0x04 << 7) | 0x00;
+ vTex->texAsat = (0x01 << 23) | (0x04 << 14) | (0x02 << 7) | 0x03;
+ break;
+ default:
+ return FALSE;
+ }
+
+ vTex->textureDirty = TRUE;
+ vTex->textureModesS = sMode - via_single;
+ vTex->textureModesT = tMode - via_single;
+
+ vTex->agpTexture = agpTexture;
+ return TRUE;
+}
+
+static void
+viaSet3DTexBlendCol(Via3DState * v3d, int tex, Bool component, CARD32 color)
+{
+ CARD32 alpha;
+ ViaTextureUnit *vTex = v3d->tex + tex;
+
+ vTex->texRAa = (color >> 8) & 0x00FF0000;
+ if (component) {
+ vTex->texRCa = (color & 0x00FFFFFF);
+ } else {
+ alpha = color >> 24;
+ vTex->texRCa = alpha | (alpha << 8) | (alpha << 16) | (alpha << 24);
+ }
+ vTex->texBColDirty = TRUE;
+}
+
+/*
+ * Check if compositing operator is supported and return corresponding register setting.
+ */
+
+static void
+viaSet3DCompositeOperator(Via3DState * v3d, CARD8 op)
+{
+ ViaCompositeOperator *vOp = viaOperatorModes + op;
+
+ v3d->blendDirty = TRUE;
+ if (v3d && vOp->supported) {
+ v3d->blendCol0 = vOp->col0 << 4;
+ v3d->blendCol1 = vOp->col1 << 2;
+ v3d->blendAl0 = vOp->al0 << 4;
+ v3d->blendAl1 = vOp->al1 << 2;
+ }
+}
+
+static Bool
+via3DOpSupported(CARD8 op)
+{
+ return viaOperatorModes[op].supported;
+}
+
+static void
+via3DEmitQuad(Via3DState * v3d, ViaCommandBuffer * cb, int dstX, int dstY,
+ int src0X, int src0Y, int src1X, int src1Y, int w, int h)
+{
+ CARD32 acmd;
+ float dx1, dx2, dy1, dy2, sx1[2], sx2[2], sy1[2], sy2[2], wf;
+ double scalex, scaley;
+ int i, numTex;
+ ViaTextureUnit *vTex;
+
+ numTex = v3d->numTextures;
+ dx1 = dstX;
+ dx2 = dstX + w;
+ dy1 = dstY;
+ dy2 = dstY + h;
+
+ if (numTex) {
+ sx1[0] = src0X;
+ sx1[1] = src1X;
+ sy1[0] = src0Y;
+ sy1[1] = src1Y;
+ for (i = 0; i < numTex; ++i) {
+ vTex = v3d->tex + i;
+ scalex = 1. / (double)((1 << vTex->textureLevel0WExp));
+ scaley = 1. / (double)((1 << vTex->textureLevel0HExp));
+ sx2[i] = sx1[i] + w;
+ sy2[i] = sy1[i] + h;
+ sx1[i] *= scalex;
+ sy1[i] *= scaley;
+ sx2[i] *= scalex;
+ sy2[i] *= scaley;
+ }
+ }
+
+ wf = 0.05;
+
+ /*
+ * Vertex buffer. Emit two 3-point triangles. The W or Z coordinate
+ * is needed for AGP DMA, and the W coordinate is for some obscure
+ * reason needed for texture mapping to be done correctly. So emit
+ * a w value after the x and y coordinates.
+ */
+
+ BEGIN_H2(HC_ParaType_CmdVdata, 22 + numTex * 6);
+ acmd = ((1 << 14) | (1 << 13) | (1 << 11));
+ if (numTex)
+ acmd |= ((1 << 7) | (1 << 8));
+ OUT_RING_SubA(0xEC, acmd);
+
+ acmd = 2 << 16;
+ OUT_RING_SubA(0xEE, acmd);
+
+ OUT_RING(*((CARD32 *) (&dx1)));
+ OUT_RING(*((CARD32 *) (&dy1)));
+ OUT_RING(*((CARD32 *) (&wf)));
+ for (i = 0; i < numTex; ++i) {
+ OUT_RING(*((CARD32 *) (sx1 + i)));
+ OUT_RING(*((CARD32 *) (sy1 + i)));
+ }
+
+ OUT_RING(*((CARD32 *) (&dx2)));
+ OUT_RING(*((CARD32 *) (&dy1)));
+ OUT_RING(*((CARD32 *) (&wf)));
+ for (i = 0; i < numTex; ++i) {
+ OUT_RING(*((CARD32 *) (sx2 + i)));
+ OUT_RING(*((CARD32 *) (sy1 + i)));
+ }
+
+ OUT_RING(*((CARD32 *) (&dx1)));
+ OUT_RING(*((CARD32 *) (&dy2)));
+ OUT_RING(*((CARD32 *) (&wf)));
+ for (i = 0; i < numTex; ++i) {
+ OUT_RING(*((CARD32 *) (sx1 + i)));
+ OUT_RING(*((CARD32 *) (sy2 + i)));
+ }
+
+ OUT_RING(*((CARD32 *) (&dx1)));
+ OUT_RING(*((CARD32 *) (&dy2)));
+ OUT_RING(*((CARD32 *) (&wf)));
+ for (i = 0; i < numTex; ++i) {
+ OUT_RING(*((CARD32 *) (sx1 + i)));
+ OUT_RING(*((CARD32 *) (sy2 + i)));
+ }
+
+ OUT_RING(*((CARD32 *) (&dx2)));
+ OUT_RING(*((CARD32 *) (&dy1)));
+ OUT_RING(*((CARD32 *) (&wf)));
+ for (i = 0; i < numTex; ++i) {
+ OUT_RING(*((CARD32 *) (sx2 + i)));
+ OUT_RING(*((CARD32 *) (sy1 + i)));
+ }
+
+ OUT_RING(*((CARD32 *) (&dx2)));
+ OUT_RING(*((CARD32 *) (&dy2)));
+ OUT_RING(*((CARD32 *) (&wf)));
+ for (i = 0; i < numTex; ++i) {
+ OUT_RING(*((CARD32 *) (sx2 + i)));
+ OUT_RING(*((CARD32 *) (sy2 + i)));
+ }
+ OUT_RING_SubA(0xEE,
+ acmd | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK);
+ OUT_RING_SubA(0xEE,
+ acmd | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK);
+
+ ADVANCE_RING;
+}
+
+static void
+via3DEmitState(Via3DState * v3d, ViaCommandBuffer * cb, Bool forceUpload)
+{
+ int i;
+ Bool saveHas3dState;
+ ViaTextureUnit *vTex;
+
+ /*
+ * Destination buffer location, format and pitch.
+ */
+
+ if (forceUpload || v3d->destDirty) {
+ v3d->destDirty = FALSE;
+ BEGIN_H2(HC_ParaType_NotTex, 3);
+
+ OUT_RING_SubA(HC_SubA_HDBBasL, v3d->destOffset & 0x00FFFFFF);
+ OUT_RING_SubA(HC_SubA_HDBBasH, v3d->destOffset >> 24);
+ OUT_RING_SubA(HC_SubA_HDBFM, v3d->destFormat |
+ (v3d->destPitch & HC_HDBPit_MASK) | HC_HDBLoc_Local);
+ }
+
+ if (forceUpload || v3d->blendDirty) {
+ v3d->blendDirty = FALSE;
+ BEGIN_H2(HC_ParaType_NotTex, 6);
+ OUT_RING_SubA(HC_SubA_HABLRFCa, 0x00);
+ OUT_RING_SubA(HC_SubA_HABLRFCb, 0x00);
+ OUT_RING_SubA(HC_SubA_HABLCsat, v3d->blendCol0);
+ OUT_RING_SubA(HC_SubA_HABLCop, v3d->blendCol1);
+ OUT_RING_SubA(HC_SubA_HABLAsat, v3d->blendAl0);
+ OUT_RING_SubA(HC_SubA_HABLAop, v3d->blendAl1);
+ }
+
+ if (forceUpload || v3d->drawingDirty) {
+
+ CARD32 planeMaskLo, planeMaskHi;
+
+ v3d->drawingDirty = FALSE;
+ BEGIN_H2(HC_ParaType_NotTex, 4);
+
+ /*
+ * Raster operation and Planemask.
+ */
+
+ if ( /* v3d->destDepth == 16 Bad Docs? */ FALSE) {
+ planeMaskLo = (v3d->planeMask & 0x000000FF) << 16;
+ planeMaskHi = (v3d->planeMask & 0x0000FF00) >> 8;
+ } else {
+ planeMaskLo = v3d->planeMask & 0x00FFFFFF;
+ planeMaskHi = v3d->planeMask >> 24;
+ }
+
+ OUT_RING_SubA(HC_SubA_HROP, ((v3d->rop & 0x0F) << 8) | planeMaskHi);
+ OUT_RING_SubA(HC_SubA_HFBBMSKL, planeMaskLo);
+
+ /*
+ * Solid shading color and alpha. Pixel center at
+ * floating coordinates (X.5,Y.5).
+ */
+
+ OUT_RING_SubA(HC_SubA_HSolidCL,
+ (v3d->solidColor & 0x00FFFFFF) | (0 << 23));
+ OUT_RING_SubA(HC_SubA_HPixGC,
+ ((v3d->solidColor & 0xFF000000) >> 16) | (0 << 23) | (v3d->
+ solidAlpha & 0xFF));
+ }
+
+ if (forceUpload || v3d->enableDirty) {
+ v3d->enableDirty = FALSE;
+ BEGIN_H2(HC_ParaType_NotTex, 1);
+
+ OUT_RING_SubA(HC_SubA_HEnable,
+ ((v3d->writeColor) ? HC_HenCW_MASK : 0) |
+ ((v3d->blend) ? HC_HenABL_MASK : 0) |
+ ((v3d->numTextures) ? HC_HenTXMP_MASK : 0) |
+ ((v3d->writeAlpha) ? HC_HenAW_MASK : 0));
+
+ if (v3d->numTextures) {
+ BEGIN_H2((HC_ParaType_Tex | (HC_SubType_TexGeneral << 8)), 2);
+ OUT_RING_SubA(HC_SubA_HTXSMD, (0 << 7) | (0 << 6) |
+ (((v3d->numTextures - 1) & 0x1) << 3) | (0 << 1) | 1);
+ OUT_RING_SubA(HC_SubA_HTXSMD, (0 << 7) | (0 << 6) |
+ (((v3d->numTextures - 1) & 0x1) << 3) | (0 << 1) | 0);
+ }
+ }
+
+ for (i = 0; i < v3d->numTextures; ++i) {
+ vTex = v3d->tex + i;
+
+ if (forceUpload || vTex->textureDirty) {
+ vTex->textureDirty = FALSE;
+
+ BEGIN_H2((HC_ParaType_Tex |
+ (((i == 0) ? HC_SubType_Tex0 : HC_SubType_Tex1) << 8)),
+ 13);
+
+ OUT_RING_SubA(HC_SubA_HTXnFM, (vTex->textureFormat |
+ (vTex->agpTexture ? HC_HTXnLoc_AGP : HC_HTXnLoc_Local)));
+ OUT_RING_SubA(HC_SubA_HTXnL0BasL,
+ vTex->textureLevel0Offset & 0x00FFFFFF);
+ OUT_RING_SubA(HC_SubA_HTXnL012BasH,
+ vTex->textureLevel0Offset >> 24);
+ if (vTex->npot) {
+ OUT_RING_SubA(HC_SubA_HTXnL0Pit,
+ (vTex->textureLevel0Pitch & HC_HTXnLnPit_MASK) |
+ HC_HTXnEnPit_MASK);
+ } else {
+ OUT_RING_SubA(HC_SubA_HTXnL0Pit,
+ vTex->textureLevel0Exp << HC_HTXnLnPitE_SHIFT);
+ }
+ OUT_RING_SubA(HC_SubA_HTXnL0_5WE, vTex->textureLevel0WExp);
+ OUT_RING_SubA(HC_SubA_HTXnL0_5HE, vTex->textureLevel0HExp);
+ OUT_RING_SubA(HC_SubA_HTXnL0OS, 0x00);
+ OUT_RING_SubA(HC_SubA_HTXnTB, 0x00);
+ OUT_RING_SubA(HC_SubA_HTXnMPMD,
+ (((unsigned)vTex->textureModesT) << 19) | (((unsigned)vTex->
+ textureModesS) << 16));
+
+ OUT_RING_SubA(HC_SubA_HTXnTBLCsat, vTex->texCsat);
+ OUT_RING_SubA(HC_SubA_HTXnTBLCop, (0x00 << 22) | (0x00 << 19) |
+ (0x00 << 14) | (0x02 << 11) |
+ (0x00 << 7) | (0x03 << 3) | 0x02);
+ OUT_RING_SubA(HC_SubA_HTXnTBLAsat, vTex->texAsat);
+ OUT_RING_SubA(HC_SubA_HTXnTBLRFog, 0x00);
+ }
+ }
+
+ for (i = 0; i < v3d->numTextures; ++i) {
+ vTex = v3d->tex + i;
+
+ if (forceUpload || vTex->texBColDirty) {
+ saveHas3dState = cb->has3dState;
+ vTex->texBColDirty = FALSE;
+ BEGIN_H2((HC_ParaType_Tex |
+ (((i == 0) ? HC_SubType_Tex0 : HC_SubType_Tex1) << 8)),
+ 2);
+ OUT_RING_SubA(HC_SubA_HTXnTBLRAa, vTex->texRAa);
+ OUT_RING_SubA(HC_SubA_HTXnTBLRCa, vTex->texRCa);
+ cb->has3dState = saveHas3dState;
+ }
+ }
+}
+
+/*
+ * Cliprect. Considered not important for the DRM 3D State, so restore the
+ * has3dState flag afterwards.
+ */
+
+static void
+via3DEmitClipRect(Via3DState * v3d, ViaCommandBuffer * cb, int x, int y,
+ int w, int h)
+{
+ Bool saveHas3dState;
+
+ saveHas3dState = cb->has3dState;
+ BEGIN_H2(HC_ParaType_NotTex, 4);
+ OUT_RING_SubA(HC_SubA_HClipTB, (y << 12) | (y + h));
+ OUT_RING_SubA(HC_SubA_HClipLR, (x << 12) | (x + w));
+ cb->has3dState = saveHas3dState;
+}
+
+void
+viaInit3DState(Via3DState * v3d)
+{
+ ViaCompositeOperator *op;
+ int i;
+ CARD32 tmp, hash;
+ Via3DFormat *format;
+
+ v3d->setDestination = viaSet3DDestination;
+ v3d->setDrawing = viaSet3DDrawing;
+ v3d->setFlags = viaSet3DFlags;
+ v3d->setTexture = viaSet3DTexture;
+ v3d->setTexBlendCol = viaSet3DTexBlendCol;
+ v3d->opSupported = via3DOpSupported;
+ v3d->setCompositeOperator = viaSet3DCompositeOperator;
+ v3d->emitQuad = via3DEmitQuad;
+ v3d->emitState = via3DEmitState;
+ v3d->emitClipRect = via3DEmitClipRect;
+ v3d->dstSupported = via3DDstSupported;
+ v3d->texSupported = via3DTexSupported;
+
+ for (i = 0; i < 256; ++i) {
+ viaOperatorModes[i].supported = FALSE;
+ }
+
+ for (i = 0; i < VIA_NUM_3D_OPCODES; ++i) {
+ op = viaOperatorModes + viaOpCodes[i][0];
+ op->supported = TRUE;
+ op->col0 = viaOpCodes[i][1];
+ op->col1 = viaOpCodes[i][2];
+ op->al0 = viaOpCodes[i][3];
+ op->al1 = viaOpCodes[i][4];
+ }
+
+ for (i = 0; i < 256; ++i) {
+ via3DFormats[i].pictFormat = 0x00;
+ }
+ for (i = 0; i < VIA_NUM_3D_FORMATS; ++i) {
+ tmp = viaFormats[i][0];
+ hash = VIA_FMT_HASH(tmp);
+ format = via3DFormats + hash;
+ if (format->pictFormat) {
+ ErrorF("BUG: Bad hash function\n");
+ }
+ format->pictFormat = tmp;
+ format->dstSupported = (viaFormats[i][3] != 0x00);
+ format->texSupported = (viaFormats[i][4] != 0x00);
+ format->dstFormat = viaFormats[i][1];
+ format->texFormat = viaFormats[i][2];
+ }
+}
diff --git a/src/via_3d.h b/src/via_3d.h
new file mode 100644
index 000000000000..c33228e321ae
--- /dev/null
+++ b/src/via_3d.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2006 Thomas Hellstrom. 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.
+ */
+
+#ifndef VIA_3D_H
+#define VIA_3D_H
+
+#include "xf86.h"
+#include "via_dmabuffer.h"
+
+#define VIA_NUM_TEXUNITS 2
+
+typedef enum
+{
+ via_single,
+ via_clamp,
+ via_repeat,
+ via_mirror,
+ via_warp
+} ViaTextureModes;
+
+typedef enum
+{
+ via_src,
+ via_src_onepix_mask,
+ via_src_onepix_comp_mask,
+ via_mask,
+ via_comp_mask
+} ViaTexBlendingModes;
+
+typedef struct _ViaTextureUnit
+{
+ CARD32 textureLevel0Offset;
+ CARD32 textureLevel0Pitch;
+ CARD32 textureLevel0Exp;
+ CARD32 textureLevel0WExp;
+ CARD32 textureLevel0HExp;
+ CARD32 textureFormat;
+ CARD32 textureModesT;
+ CARD32 textureModesS;
+ CARD32 texCsat;
+ CARD32 texRCa;
+ CARD32 texAsat;
+ CARD32 texRAa;
+ Bool agpTexture;
+ Bool textureDirty;
+ Bool texBColDirty;
+ Bool npot;
+} ViaTextureUnit;
+
+typedef struct _Via3DState
+{
+ Bool destDirty;
+ Bool blendDirty;
+ Bool enableDirty;
+ Bool drawingDirty;
+ CARD32 rop;
+ CARD32 planeMask;
+ CARD32 solidColor;
+ CARD32 solidAlpha;
+ CARD32 destOffset;
+ CARD32 destPitch;
+ CARD32 destFormat;
+ int destDepth;
+ int numTextures;
+ Bool blend;
+ CARD32 blendCol0;
+ CARD32 blendCol1;
+ CARD32 blendAl0;
+ CARD32 blendAl1;
+ Bool writeAlpha;
+ Bool writeColor;
+ Bool useDestAlpha;
+ ViaTextureUnit tex[VIA_NUM_TEXUNITS];
+ void (*setDestination) (struct _Via3DState * v3d, CARD32 offset,
+ CARD32 pitch, int format);
+ void (*setDrawing) (struct _Via3DState * v3d, int rop,
+ CARD32 planeMask, CARD32 solidColor, CARD32 solidAlpha);
+ void (*setFlags) (struct _Via3DState * v3d, int numTextures,
+ Bool writeAlpha, Bool writeColor, Bool blend);
+ Bool(*setTexture) (struct _Via3DState * v3d, int tex, CARD32 offset,
+ CARD32 pitch, Bool nPot, CARD32 width, CARD32 height, int format,
+ ViaTextureModes sMode, ViaTextureModes tMode,
+ ViaTexBlendingModes blendingMode, Bool agpTexture);
+ void (*setTexBlendCol) (struct _Via3DState * v3d, int tex, Bool component,
+ CARD32 color);
+ void (*setCompositeOperator) (struct _Via3DState * v3d, CARD8 op);
+ Bool(*opSupported) (CARD8 op);
+ void (*emitQuad) (struct _Via3DState * v3d, ViaCommandBuffer * cb,
+ int dstX, int dstY, int src0X, int src0Y, int src1X, int src1Y, int w,
+ int h);
+ void (*emitState) (struct _Via3DState * v3d, ViaCommandBuffer * cb,
+ Bool forceUpload);
+ void (*emitClipRect) (struct _Via3DState * v3d, ViaCommandBuffer * cb,
+ int x, int y, int w, int h);
+ Bool(*dstSupported) (int format);
+ Bool(*texSupported) (int format);
+} Via3DState;
+
+void viaInit3DState(Via3DState * v3d);
+
+#endif
diff --git a/src/via_3d_reg.h b/src/via_3d_reg.h
new file mode 100644
index 000000000000..cf61bb514db1
--- /dev/null
+++ b/src/via_3d_reg.h
@@ -0,0 +1,1651 @@
+/*
+ * 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
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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 VIA_3D_REG_H
+#define VIA_3D_REG_H
+#define HC_REG_BASE 0x0400
+
+#define HC_REG_TRANS_SPACE 0x0040
+
+#define HC_ParaN_MASK 0xffffffff
+#define HC_Para_MASK 0x00ffffff
+#define HC_SubA_MASK 0xff000000
+#define HC_SubA_SHIFT 24
+/* Transmission Setting
+ */
+#define HC_REG_TRANS_SET 0x003c
+#define HC_ParaSubType_MASK 0xff000000
+#define HC_ParaType_MASK 0x00ff0000
+#define HC_ParaOS_MASK 0x0000ff00
+#define HC_ParaAdr_MASK 0x000000ff
+#define HC_ParaSubType_SHIFT 24
+#define HC_ParaType_SHIFT 16
+#define HC_ParaOS_SHIFT 8
+#define HC_ParaAdr_SHIFT 0
+
+#define HC_ParaType_CmdVdata 0x0000
+#define HC_ParaType_NotTex 0x0001
+#define HC_ParaType_Tex 0x0002
+#define HC_ParaType_Palette 0x0003
+#define HC_ParaType_PreCR 0x0010
+#define HC_ParaType_Auto 0x00fe
+
+/* Transmission Space
+ */
+#define HC_REG_Hpara0 0x0040
+#define HC_REG_HpataAF 0x02fc
+
+/* Read
+ */
+#define HC_REG_HREngSt 0x0000
+#define HC_REG_HRFIFOempty 0x0004
+#define HC_REG_HRFIFOfull 0x0008
+#define HC_REG_HRErr 0x000c
+#define HC_REG_FIFOstatus 0x0010
+/* HC_REG_HREngSt 0x0000
+ */
+#define HC_HDASZC_MASK 0x00010000
+#define HC_HSGEMI_MASK 0x0000f000
+#define HC_HLGEMISt_MASK 0x00000f00
+#define HC_HCRSt_MASK 0x00000080
+#define HC_HSE0St_MASK 0x00000040
+#define HC_HSE1St_MASK 0x00000020
+#define HC_HPESt_MASK 0x00000010
+#define HC_HXESt_MASK 0x00000008
+#define HC_HBESt_MASK 0x00000004
+#define HC_HE2St_MASK 0x00000002
+#define HC_HE3St_MASK 0x00000001
+/* HC_REG_HRFIFOempty 0x0004
+ */
+#define HC_HRZDempty_MASK 0x00000010
+#define HC_HRTXAempty_MASK 0x00000008
+#define HC_HRTXDempty_MASK 0x00000004
+#define HC_HWZDempty_MASK 0x00000002
+#define HC_HWCDempty_MASK 0x00000001
+/* HC_REG_HRFIFOfull 0x0008
+ */
+#define HC_HRZDfull_MASK 0x00000010
+#define HC_HRTXAfull_MASK 0x00000008
+#define HC_HRTXDfull_MASK 0x00000004
+#define HC_HWZDfull_MASK 0x00000002
+#define HC_HWCDfull_MASK 0x00000001
+/* HC_REG_HRErr 0x000c
+ */
+#define HC_HAGPCMErr_MASK 0x80000000
+#define HC_HAGPCMErrC_MASK 0x70000000
+/* HC_REG_FIFOstatus 0x0010
+ */
+#define HC_HRFIFOATall_MASK 0x80000000
+#define HC_HRFIFOATbusy_MASK 0x40000000
+#define HC_HRATFGMDo_MASK 0x00000100
+#define HC_HRATFGMDi_MASK 0x00000080
+#define HC_HRATFRZD_MASK 0x00000040
+#define HC_HRATFRTXA_MASK 0x00000020
+#define HC_HRATFRTXD_MASK 0x00000010
+#define HC_HRATFWZD_MASK 0x00000008
+#define HC_HRATFWCD_MASK 0x00000004
+#define HC_HRATTXTAG_MASK 0x00000002
+#define HC_HRATTXCH_MASK 0x00000001
+
+/* AGP Command Setting
+ */
+#define HC_SubA_HAGPBstL 0x0060
+#define HC_SubA_HAGPBendL 0x0061
+#define HC_SubA_HAGPCMNT 0x0062
+#define HC_SubA_HAGPBpL 0x0063
+#define HC_SubA_HAGPBpH 0x0064
+/* HC_SubA_HAGPCMNT 0x0062
+ */
+#define HC_HAGPCMNT_MASK 0x00800000
+#define HC_HCmdErrClr_MASK 0x00400000
+#define HC_HAGPBendH_MASK 0x0000ff00
+#define HC_HAGPBstH_MASK 0x000000ff
+#define HC_HAGPBendH_SHIFT 8
+#define HC_HAGPBstH_SHIFT 0
+/* HC_SubA_HAGPBpL 0x0063
+ */
+#define HC_HAGPBpL_MASK 0x00fffffc
+#define HC_HAGPBpID_MASK 0x00000003
+#define HC_HAGPBpID_PAUSE 0x00000000
+#define HC_HAGPBpID_JUMP 0x00000001
+#define HC_HAGPBpID_STOP 0x00000002
+/* HC_SubA_HAGPBpH 0x0064
+ */
+#define HC_HAGPBpH_MASK 0x00ffffff
+
+/* Miscellaneous Settings
+ */
+#define HC_SubA_HClipTB 0x0070
+#define HC_SubA_HClipLR 0x0071
+#define HC_SubA_HFPClipTL 0x0072
+#define HC_SubA_HFPClipBL 0x0073
+#define HC_SubA_HFPClipLL 0x0074
+#define HC_SubA_HFPClipRL 0x0075
+#define HC_SubA_HFPClipTBH 0x0076
+#define HC_SubA_HFPClipLRH 0x0077
+#define HC_SubA_HLP 0x0078
+#define HC_SubA_HLPRF 0x0079
+#define HC_SubA_HSolidCL 0x007a
+#define HC_SubA_HPixGC 0x007b
+#define HC_SubA_HSPXYOS 0x007c
+#define HC_SubA_HVertexCNT 0x007d
+
+#define HC_HClipT_MASK 0x00fff000
+#define HC_HClipT_SHIFT 12
+#define HC_HClipB_MASK 0x00000fff
+#define HC_HClipB_SHIFT 0
+#define HC_HClipL_MASK 0x00fff000
+#define HC_HClipL_SHIFT 12
+#define HC_HClipR_MASK 0x00000fff
+#define HC_HClipR_SHIFT 0
+#define HC_HFPClipBH_MASK 0x0000ff00
+#define HC_HFPClipBH_SHIFT 8
+#define HC_HFPClipTH_MASK 0x000000ff
+#define HC_HFPClipTH_SHIFT 0
+#define HC_HFPClipRH_MASK 0x0000ff00
+#define HC_HFPClipRH_SHIFT 8
+#define HC_HFPClipLH_MASK 0x000000ff
+#define HC_HFPClipLH_SHIFT 0
+#define HC_HSolidCH_MASK 0x000000ff
+#define HC_HPixGC_MASK 0x00800000
+#define HC_HSPXOS_MASK 0x00fff000
+#define HC_HSPXOS_SHIFT 12
+#define HC_HSPYOS_MASK 0x00000fff
+
+/* Command
+ * Command A
+ */
+#define HC_HCmdHeader_MASK 0xfe000000 /*0xffe00000 */
+#define HC_HE3Fire_MASK 0x00100000
+#define HC_HPMType_MASK 0x000f0000
+#define HC_HEFlag_MASK 0x0000e000
+#define HC_HShading_MASK 0x00001c00
+#define HC_HPMValidN_MASK 0x00000200
+#define HC_HPLEND_MASK 0x00000100
+#define HC_HVCycle_MASK 0x000000ff
+#define HC_HVCycle_Style_MASK 0x000000c0
+#define HC_HVCycle_ChgA_MASK 0x00000030
+#define HC_HVCycle_ChgB_MASK 0x0000000c
+#define HC_HVCycle_ChgC_MASK 0x00000003
+#define HC_HPMType_Point 0x00000000
+#define HC_HPMType_Line 0x00010000
+#define HC_HPMType_Tri 0x00020000
+#define HC_HPMType_TriWF 0x00040000
+#define HC_HEFlag_NoAA 0x00000000
+#define HC_HEFlag_ab 0x00008000
+#define HC_HEFlag_bc 0x00004000
+#define HC_HEFlag_ca 0x00002000
+#define HC_HShading_Solid 0x00000000
+#define HC_HShading_FlatA 0x00000400
+#define HC_HShading_FlatB 0x00000800
+#define HC_HShading_FlatC 0x00000c00
+#define HC_HShading_Gouraud 0x00001000
+#define HC_HVCycle_Full 0x00000000
+#define HC_HVCycle_AFP 0x00000040
+#define HC_HVCycle_One 0x000000c0
+#define HC_HVCycle_NewA 0x00000000
+#define HC_HVCycle_AA 0x00000010
+#define HC_HVCycle_AB 0x00000020
+#define HC_HVCycle_AC 0x00000030
+#define HC_HVCycle_NewB 0x00000000
+#define HC_HVCycle_BA 0x00000004
+#define HC_HVCycle_BB 0x00000008
+#define HC_HVCycle_BC 0x0000000c
+#define HC_HVCycle_NewC 0x00000000
+#define HC_HVCycle_CA 0x00000001
+#define HC_HVCycle_CB 0x00000002
+#define HC_HVCycle_CC 0x00000003
+
+/* Command B
+ */
+#define HC_HLPrst_MASK 0x00010000
+#define HC_HLLastP_MASK 0x00008000
+#define HC_HVPMSK_MASK 0x00007f80
+#define HC_HBFace_MASK 0x00000040
+#define HC_H2nd1VT_MASK 0x0000003f
+#define HC_HVPMSK_X 0x00004000
+#define HC_HVPMSK_Y 0x00002000
+#define HC_HVPMSK_Z 0x00001000
+#define HC_HVPMSK_W 0x00000800
+#define HC_HVPMSK_Cd 0x00000400
+#define HC_HVPMSK_Cs 0x00000200
+#define HC_HVPMSK_S 0x00000100
+#define HC_HVPMSK_T 0x00000080
+
+/* Enable Setting
+ */
+#define HC_SubA_HEnable 0x0000
+#define HC_HenTXEnvMap_MASK 0x00200000
+#define HC_HenVertexCNT_MASK 0x00100000
+#define HC_HenCPUDAZ_MASK 0x00080000
+#define HC_HenDASZWC_MASK 0x00040000
+#define HC_HenFBCull_MASK 0x00020000
+#define HC_HenCW_MASK 0x00010000
+#define HC_HenAA_MASK 0x00008000
+#define HC_HenST_MASK 0x00004000
+#define HC_HenZT_MASK 0x00002000
+#define HC_HenZW_MASK 0x00001000
+#define HC_HenAT_MASK 0x00000800
+#define HC_HenAW_MASK 0x00000400
+#define HC_HenSP_MASK 0x00000200
+#define HC_HenLP_MASK 0x00000100
+#define HC_HenTXCH_MASK 0x00000080
+#define HC_HenTXMP_MASK 0x00000040
+#define HC_HenTXPP_MASK 0x00000020
+#define HC_HenTXTR_MASK 0x00000010
+#define HC_HenCS_MASK 0x00000008
+#define HC_HenFOG_MASK 0x00000004
+#define HC_HenABL_MASK 0x00000002
+#define HC_HenDT_MASK 0x00000001
+
+/* Z Setting
+ */
+#define HC_SubA_HZWBBasL 0x0010
+#define HC_SubA_HZWBBasH 0x0011
+#define HC_SubA_HZWBType 0x0012
+#define HC_SubA_HZBiasL 0x0013
+#define HC_SubA_HZWBend 0x0014
+#define HC_SubA_HZWTMD 0x0015
+#define HC_SubA_HZWCDL 0x0016
+#define HC_SubA_HZWCTAGnum 0x0017
+#define HC_SubA_HZCYNum 0x0018
+#define HC_SubA_HZWCFire 0x0019
+/* HC_SubA_HZWBType
+ */
+#define HC_HZWBType_MASK 0x00800000
+#define HC_HZBiasedWB_MASK 0x00400000
+#define HC_HZONEasFF_MASK 0x00200000
+#define HC_HZOONEasFF_MASK 0x00100000
+#define HC_HZWBFM_MASK 0x00030000
+#define HC_HZWBLoc_MASK 0x0000c000
+#define HC_HZWBPit_MASK 0x00003fff
+#define HC_HZWBFM_16 0x00000000
+#define HC_HZWBFM_32 0x00020000
+#define HC_HZWBFM_24 0x00030000
+#define HC_HZWBLoc_Local 0x00000000
+#define HC_HZWBLoc_SyS 0x00004000
+/* HC_SubA_HZWBend
+ */
+#define HC_HZWBend_MASK 0x00ffe000
+#define HC_HZBiasH_MASK 0x000000ff
+#define HC_HZWBend_SHIFT 10
+/* HC_SubA_HZWTMD
+ */
+#define HC_HZWTMD_MASK 0x00070000
+#define HC_HEBEBias_MASK 0x00007f00
+#define HC_HZNF_MASK 0x000000ff
+#define HC_HZWTMD_NeverPass 0x00000000
+#define HC_HZWTMD_LT 0x00010000
+#define HC_HZWTMD_EQ 0x00020000
+#define HC_HZWTMD_LE 0x00030000
+#define HC_HZWTMD_GT 0x00040000
+#define HC_HZWTMD_NE 0x00050000
+#define HC_HZWTMD_GE 0x00060000
+#define HC_HZWTMD_AllPass 0x00070000
+#define HC_HEBEBias_SHIFT 8
+/* HC_SubA_HZWCDL 0x0016
+ */
+#define HC_HZWCDL_MASK 0x00ffffff
+/* HC_SubA_HZWCTAGnum 0x0017
+ */
+#define HC_HZWCTAGnum_MASK 0x00ff0000
+#define HC_HZWCTAGnum_SHIFT 16
+#define HC_HZWCDH_MASK 0x000000ff
+#define HC_HZWCDH_SHIFT 0
+/* HC_SubA_HZCYNum 0x0018
+ */
+#define HC_HZCYNum_MASK 0x00030000
+#define HC_HZCYNum_SHIFT 16
+#define HC_HZWCQWnum_MASK 0x00003fff
+#define HC_HZWCQWnum_SHIFT 0
+/* HC_SubA_HZWCFire 0x0019
+ */
+#define HC_ZWCFire_MASK 0x00010000
+#define HC_HZWCQWnumLast_MASK 0x00003fff
+#define HC_HZWCQWnumLast_SHIFT 0
+
+/* Stencil Setting
+ */
+#define HC_SubA_HSTREF 0x0023
+#define HC_SubA_HSTMD 0x0024
+/* HC_SubA_HSBFM
+ */
+#define HC_HSBFM_MASK 0x00030000
+#define HC_HSBLoc_MASK 0x0000c000
+#define HC_HSBPit_MASK 0x00003fff
+/* HC_SubA_HSTREF
+ */
+#define HC_HSTREF_MASK 0x00ff0000
+#define HC_HSTOPMSK_MASK 0x0000ff00
+#define HC_HSTBMSK_MASK 0x000000ff
+#define HC_HSTREF_SHIFT 16
+#define HC_HSTOPMSK_SHIFT 8
+/* HC_SubA_HSTMD
+ */
+#define HC_HSTMD_MASK 0x00070000
+#define HC_HSTOPSF_MASK 0x000001c0
+#define HC_HSTOPSPZF_MASK 0x00000038
+#define HC_HSTOPSPZP_MASK 0x00000007
+#define HC_HSTMD_NeverPass 0x00000000
+#define HC_HSTMD_LT 0x00010000
+#define HC_HSTMD_EQ 0x00020000
+#define HC_HSTMD_LE 0x00030000
+#define HC_HSTMD_GT 0x00040000
+#define HC_HSTMD_NE 0x00050000
+#define HC_HSTMD_GE 0x00060000
+#define HC_HSTMD_AllPass 0x00070000
+#define HC_HSTOPSF_KEEP 0x00000000
+#define HC_HSTOPSF_ZERO 0x00000040
+#define HC_HSTOPSF_REPLACE 0x00000080
+#define HC_HSTOPSF_INCRSAT 0x000000c0
+#define HC_HSTOPSF_DECRSAT 0x00000100
+#define HC_HSTOPSF_INVERT 0x00000140
+#define HC_HSTOPSF_INCR 0x00000180
+#define HC_HSTOPSF_DECR 0x000001c0
+#define HC_HSTOPSPZF_KEEP 0x00000000
+#define HC_HSTOPSPZF_ZERO 0x00000008
+#define HC_HSTOPSPZF_REPLACE 0x00000010
+#define HC_HSTOPSPZF_INCRSAT 0x00000018
+#define HC_HSTOPSPZF_DECRSAT 0x00000020
+#define HC_HSTOPSPZF_INVERT 0x00000028
+#define HC_HSTOPSPZF_INCR 0x00000030
+#define HC_HSTOPSPZF_DECR 0x00000038
+#define HC_HSTOPSPZP_KEEP 0x00000000
+#define HC_HSTOPSPZP_ZERO 0x00000001
+#define HC_HSTOPSPZP_REPLACE 0x00000002
+#define HC_HSTOPSPZP_INCRSAT 0x00000003
+#define HC_HSTOPSPZP_DECRSAT 0x00000004
+#define HC_HSTOPSPZP_INVERT 0x00000005
+#define HC_HSTOPSPZP_INCR 0x00000006
+#define HC_HSTOPSPZP_DECR 0x00000007
+
+/* Alpha Setting
+ */
+#define HC_SubA_HABBasL 0x0030
+#define HC_SubA_HABBasH 0x0031
+#define HC_SubA_HABFM 0x0032
+#define HC_SubA_HATMD 0x0033
+#define HC_SubA_HABLCsat 0x0034
+#define HC_SubA_HABLCop 0x0035
+#define HC_SubA_HABLAsat 0x0036
+#define HC_SubA_HABLAop 0x0037
+#define HC_SubA_HABLRCa 0x0038
+#define HC_SubA_HABLRFCa 0x0039
+#define HC_SubA_HABLRCbias 0x003a
+#define HC_SubA_HABLRCb 0x003b
+#define HC_SubA_HABLRFCb 0x003c
+#define HC_SubA_HABLRAa 0x003d
+#define HC_SubA_HABLRAb 0x003e
+/* HC_SubA_HABFM
+ */
+#define HC_HABFM_MASK 0x00030000
+#define HC_HABLoc_MASK 0x0000c000
+#define HC_HABPit_MASK 0x000007ff
+/* HC_SubA_HATMD
+ */
+#define HC_HATMD_MASK 0x00000700
+#define HC_HATREF_MASK 0x000000ff
+#define HC_HATMD_NeverPass 0x00000000
+#define HC_HATMD_LT 0x00000100
+#define HC_HATMD_EQ 0x00000200
+#define HC_HATMD_LE 0x00000300
+#define HC_HATMD_GT 0x00000400
+#define HC_HATMD_NE 0x00000500
+#define HC_HATMD_GE 0x00000600
+#define HC_HATMD_AllPass 0x00000700
+/* HC_SubA_HABLCsat
+ */
+#define HC_HABLCsat_MASK 0x00010000
+#define HC_HABLCa_MASK 0x0000fc00
+#define HC_HABLCa_C_MASK 0x0000c000
+#define HC_HABLCa_OPC_MASK 0x00003c00
+#define HC_HABLFCa_MASK 0x000003f0
+#define HC_HABLFCa_C_MASK 0x00000300
+#define HC_HABLFCa_OPC_MASK 0x000000f0
+#define HC_HABLCbias_MASK 0x0000000f
+#define HC_HABLCbias_C_MASK 0x00000008
+#define HC_HABLCbias_OPC_MASK 0x00000007
+/*-- Define the input color.
+ */
+#define HC_XC_Csrc 0x00000000
+#define HC_XC_Cdst 0x00000001
+#define HC_XC_Asrc 0x00000002
+#define HC_XC_Adst 0x00000003
+#define HC_XC_Fog 0x00000004
+#define HC_XC_HABLRC 0x00000005
+#define HC_XC_minSrcDst 0x00000006
+#define HC_XC_maxSrcDst 0x00000007
+#define HC_XC_mimAsrcInvAdst 0x00000008
+#define HC_XC_OPC 0x00000000
+#define HC_XC_InvOPC 0x00000010
+#define HC_XC_OPCp5 0x00000020
+/*-- Define the input Alpha
+ */
+#define HC_XA_OPA 0x00000000
+#define HC_XA_InvOPA 0x00000010
+#define HC_XA_OPAp5 0x00000020
+#define HC_XA_0 0x00000000
+#define HC_XA_Asrc 0x00000001
+#define HC_XA_Adst 0x00000002
+#define HC_XA_Fog 0x00000003
+#define HC_XA_minAsrcFog 0x00000004
+#define HC_XA_minAsrcAdst 0x00000005
+#define HC_XA_maxAsrcFog 0x00000006
+#define HC_XA_maxAsrcAdst 0x00000007
+#define HC_XA_HABLRA 0x00000008
+#define HC_XA_minAsrcInvAdst 0x00000008
+#define HC_XA_HABLFRA 0x00000009
+/*--
+ */
+#define HC_HABLCa_OPC (HC_XC_OPC << 10)
+#define HC_HABLCa_InvOPC (HC_XC_InvOPC << 10)
+#define HC_HABLCa_OPCp5 (HC_XC_OPCp5 << 10)
+#define HC_HABLCa_Csrc (HC_XC_Csrc << 10)
+#define HC_HABLCa_Cdst (HC_XC_Cdst << 10)
+#define HC_HABLCa_Asrc (HC_XC_Asrc << 10)
+#define HC_HABLCa_Adst (HC_XC_Adst << 10)
+#define HC_HABLCa_Fog (HC_XC_Fog << 10)
+#define HC_HABLCa_HABLRCa (HC_XC_HABLRC << 10)
+#define HC_HABLCa_minSrcDst (HC_XC_minSrcDst << 10)
+#define HC_HABLCa_maxSrcDst (HC_XC_maxSrcDst << 10)
+#define HC_HABLFCa_OPC (HC_XC_OPC << 4)
+#define HC_HABLFCa_InvOPC (HC_XC_InvOPC << 4)
+#define HC_HABLFCa_OPCp5 (HC_XC_OPCp5 << 4)
+#define HC_HABLFCa_Csrc (HC_XC_Csrc << 4)
+#define HC_HABLFCa_Cdst (HC_XC_Cdst << 4)
+#define HC_HABLFCa_Asrc (HC_XC_Asrc << 4)
+#define HC_HABLFCa_Adst (HC_XC_Adst << 4)
+#define HC_HABLFCa_Fog (HC_XC_Fog << 4)
+#define HC_HABLFCa_HABLRCa (HC_XC_HABLRC << 4)
+#define HC_HABLFCa_minSrcDst (HC_XC_minSrcDst << 4)
+#define HC_HABLFCa_maxSrcDst (HC_XC_maxSrcDst << 4)
+#define HC_HABLFCa_mimAsrcInvAdst (HC_XC_mimAsrcInvAdst << 4)
+#define HC_HABLCbias_HABLRCbias 0x00000000
+#define HC_HABLCbias_Asrc 0x00000001
+#define HC_HABLCbias_Adst 0x00000002
+#define HC_HABLCbias_Fog 0x00000003
+#define HC_HABLCbias_Cin 0x00000004
+/* HC_SubA_HABLCop 0x0035
+ */
+#define HC_HABLdot_MASK 0x00010000
+#define HC_HABLCop_MASK 0x00004000
+#define HC_HABLCb_MASK 0x00003f00
+#define HC_HABLCb_C_MASK 0x00003000
+#define HC_HABLCb_OPC_MASK 0x00000f00
+#define HC_HABLFCb_MASK 0x000000fc
+#define HC_HABLFCb_C_MASK 0x000000c0
+#define HC_HABLFCb_OPC_MASK 0x0000003c
+#define HC_HABLCshift_MASK 0x00000003
+#define HC_HABLCb_OPC (HC_XC_OPC << 8)
+#define HC_HABLCb_InvOPC (HC_XC_InvOPC << 8)
+#define HC_HABLCb_OPCp5 (HC_XC_OPCp5 << 8)
+#define HC_HABLCb_Csrc (HC_XC_Csrc << 8)
+#define HC_HABLCb_Cdst (HC_XC_Cdst << 8)
+#define HC_HABLCb_Asrc (HC_XC_Asrc << 8)
+#define HC_HABLCb_Adst (HC_XC_Adst << 8)
+#define HC_HABLCb_Fog (HC_XC_Fog << 8)
+#define HC_HABLCb_HABLRCa (HC_XC_HABLRC << 8)
+#define HC_HABLCb_minSrcDst (HC_XC_minSrcDst << 8)
+#define HC_HABLCb_maxSrcDst (HC_XC_maxSrcDst << 8)
+#define HC_HABLFCb_OPC (HC_XC_OPC << 2)
+#define HC_HABLFCb_InvOPC (HC_XC_InvOPC << 2)
+#define HC_HABLFCb_OPCp5 (HC_XC_OPCp5 << 2)
+#define HC_HABLFCb_Csrc (HC_XC_Csrc << 2)
+#define HC_HABLFCb_Cdst (HC_XC_Cdst << 2)
+#define HC_HABLFCb_Asrc (HC_XC_Asrc << 2)
+#define HC_HABLFCb_Adst (HC_XC_Adst << 2)
+#define HC_HABLFCb_Fog (HC_XC_Fog << 2)
+#define HC_HABLFCb_HABLRCb (HC_XC_HABLRC << 2)
+#define HC_HABLFCb_minSrcDst (HC_XC_minSrcDst << 2)
+#define HC_HABLFCb_maxSrcDst (HC_XC_maxSrcDst << 2)
+#define HC_HABLFCb_mimAsrcInvAdst (HC_XC_mimAsrcInvAdst << 2)
+/* HC_SubA_HABLAsat 0x0036
+ */
+#define HC_HABLAsat_MASK 0x00010000
+#define HC_HABLAa_MASK 0x0000fc00
+#define HC_HABLAa_A_MASK 0x0000c000
+#define HC_HABLAa_OPA_MASK 0x00003c00
+#define HC_HABLFAa_MASK 0x000003f0
+#define HC_HABLFAa_A_MASK 0x00000300
+#define HC_HABLFAa_OPA_MASK 0x000000f0
+#define HC_HABLAbias_MASK 0x0000000f
+#define HC_HABLAbias_A_MASK 0x00000008
+#define HC_HABLAbias_OPA_MASK 0x00000007
+#define HC_HABLAa_OPA (HC_XA_OPA << 10)
+#define HC_HABLAa_InvOPA (HC_XA_InvOPA << 10)
+#define HC_HABLAa_OPAp5 (HC_XA_OPAp5 << 10)
+#define HC_HABLAa_0 (HC_XA_0 << 10)
+#define HC_HABLAa_Asrc (HC_XA_Asrc << 10)
+#define HC_HABLAa_Adst (HC_XA_Adst << 10)
+#define HC_HABLAa_Fog (HC_XA_Fog << 10)
+#define HC_HABLAa_minAsrcFog (HC_XA_minAsrcFog << 10)
+#define HC_HABLAa_minAsrcAdst (HC_XA_minAsrcAdst << 10)
+#define HC_HABLAa_maxAsrcFog (HC_XA_maxAsrcFog << 10)
+#define HC_HABLAa_maxAsrcAdst (HC_XA_maxAsrcAdst << 10)
+#define HC_HABLAa_HABLRA (HC_XA_HABLRA << 10)
+#define HC_HABLFAa_OPA (HC_XA_OPA << 4)
+#define HC_HABLFAa_InvOPA (HC_XA_InvOPA << 4)
+#define HC_HABLFAa_OPAp5 (HC_XA_OPAp5 << 4)
+#define HC_HABLFAa_0 (HC_XA_0 << 4)
+#define HC_HABLFAa_Asrc (HC_XA_Asrc << 4)
+#define HC_HABLFAa_Adst (HC_XA_Adst << 4)
+#define HC_HABLFAa_Fog (HC_XA_Fog << 4)
+#define HC_HABLFAa_minAsrcFog (HC_XA_minAsrcFog << 4)
+#define HC_HABLFAa_minAsrcAdst (HC_XA_minAsrcAdst << 4)
+#define HC_HABLFAa_maxAsrcFog (HC_XA_maxAsrcFog << 4)
+#define HC_HABLFAa_maxAsrcAdst (HC_XA_maxAsrcAdst << 4)
+#define HC_HABLFAa_minAsrcInvAdst (HC_XA_minAsrcInvAdst << 4)
+#define HC_HABLFAa_HABLFRA (HC_XA_HABLFRA << 4)
+#define HC_HABLAbias_HABLRAbias 0x00000000
+#define HC_HABLAbias_Asrc 0x00000001
+#define HC_HABLAbias_Adst 0x00000002
+#define HC_HABLAbias_Fog 0x00000003
+#define HC_HABLAbias_Aaa 0x00000004
+/* HC_SubA_HABLAop 0x0037
+ */
+#define HC_HABLAop_MASK 0x00004000
+#define HC_HABLAb_MASK 0x00003f00
+#define HC_HABLAb_OPA_MASK 0x00000f00
+#define HC_HABLFAb_MASK 0x000000fc
+#define HC_HABLFAb_OPA_MASK 0x0000003c
+#define HC_HABLAshift_MASK 0x00000003
+#define HC_HABLAb_OPA (HC_XA_OPA << 8)
+#define HC_HABLAb_InvOPA (HC_XA_InvOPA << 8)
+#define HC_HABLAb_OPAp5 (HC_XA_OPAp5 << 8)
+#define HC_HABLAb_0 (HC_XA_0 << 8)
+#define HC_HABLAb_Asrc (HC_XA_Asrc << 8)
+#define HC_HABLAb_Adst (HC_XA_Adst << 8)
+#define HC_HABLAb_Fog (HC_XA_Fog << 8)
+#define HC_HABLAb_minAsrcFog (HC_XA_minAsrcFog << 8)
+#define HC_HABLAb_minAsrcAdst (HC_XA_minAsrcAdst << 8)
+#define HC_HABLAb_maxAsrcFog (HC_XA_maxAsrcFog << 8)
+#define HC_HABLAb_maxAsrcAdst (HC_XA_maxAsrcAdst << 8)
+#define HC_HABLAb_HABLRA (HC_XA_HABLRA << 8)
+#define HC_HABLFAb_OPA (HC_XA_OPA << 2)
+#define HC_HABLFAb_InvOPA (HC_XA_InvOPA << 2)
+#define HC_HABLFAb_OPAp5 (HC_XA_OPAp5 << 2)
+#define HC_HABLFAb_0 (HC_XA_0 << 2)
+#define HC_HABLFAb_Asrc (HC_XA_Asrc << 2)
+#define HC_HABLFAb_Adst (HC_XA_Adst << 2)
+#define HC_HABLFAb_Fog (HC_XA_Fog << 2)
+#define HC_HABLFAb_minAsrcFog (HC_XA_minAsrcFog << 2)
+#define HC_HABLFAb_minAsrcAdst (HC_XA_minAsrcAdst << 2)
+#define HC_HABLFAb_maxAsrcFog (HC_XA_maxAsrcFog << 2)
+#define HC_HABLFAb_maxAsrcAdst (HC_XA_maxAsrcAdst << 2)
+#define HC_HABLFAb_minAsrcInvAdst (HC_XA_minAsrcInvAdst << 2)
+#define HC_HABLFAb_HABLFRA (HC_XA_HABLFRA << 2)
+/* HC_SubA_HABLRAa 0x003d
+ */
+#define HC_HABLRAa_MASK 0x00ff0000
+#define HC_HABLRFAa_MASK 0x0000ff00
+#define HC_HABLRAbias_MASK 0x000000ff
+#define HC_HABLRAa_SHIFT 16
+#define HC_HABLRFAa_SHIFT 8
+/* HC_SubA_HABLRAb 0x003e
+ */
+#define HC_HABLRAb_MASK 0x0000ff00
+#define HC_HABLRFAb_MASK 0x000000ff
+#define HC_HABLRAb_SHIFT 8
+
+/* Destination Setting
+ */
+#define HC_SubA_HDBBasL 0x0040
+#define HC_SubA_HDBBasH 0x0041
+#define HC_SubA_HDBFM 0x0042
+#define HC_SubA_HFBBMSKL 0x0043
+#define HC_SubA_HROP 0x0044
+/* HC_SubA_HDBFM 0x0042
+ */
+#define HC_HDBFM_MASK 0x001f0000
+#define HC_HDBLoc_MASK 0x0000c000
+#define HC_HDBPit_MASK 0x00003fff
+#define HC_HDBFM_RGB555 0x00000000
+#define HC_HDBFM_RGB565 0x00010000
+#define HC_HDBFM_ARGB4444 0x00020000
+#define HC_HDBFM_ARGB1555 0x00030000
+#define HC_HDBFM_BGR555 0x00040000
+#define HC_HDBFM_BGR565 0x00050000
+#define HC_HDBFM_ABGR4444 0x00060000
+#define HC_HDBFM_ABGR1555 0x00070000
+#define HC_HDBFM_ARGB0888 0x00080000
+#define HC_HDBFM_ARGB8888 0x00090000
+#define HC_HDBFM_ABGR0888 0x000a0000
+#define HC_HDBFM_ABGR8888 0x000b0000
+#define HC_HDBLoc_Local 0x00000000
+#define HC_HDBLoc_Sys 0x00004000
+/* HC_SubA_HROP 0x0044
+ */
+#define HC_HROP_MASK 0x00000f00
+#define HC_HFBBMSKH_MASK 0x000000ff
+#define HC_HROP_BLACK 0x00000000
+#define HC_HROP_DPon 0x00000100
+#define HC_HROP_DPna 0x00000200
+#define HC_HROP_Pn 0x00000300
+#define HC_HROP_PDna 0x00000400
+#define HC_HROP_Dn 0x00000500
+#define HC_HROP_DPx 0x00000600
+#define HC_HROP_DPan 0x00000700
+#define HC_HROP_DPa 0x00000800
+#define HC_HROP_DPxn 0x00000900
+#define HC_HROP_D 0x00000a00
+#define HC_HROP_DPno 0x00000b00
+#define HC_HROP_P 0x00000c00
+#define HC_HROP_PDno 0x00000d00
+#define HC_HROP_DPo 0x00000e00
+#define HC_HROP_WHITE 0x00000f00
+
+/* Fog Setting
+ */
+#define HC_SubA_HFogLF 0x0050
+#define HC_SubA_HFogCL 0x0051
+#define HC_SubA_HFogCH 0x0052
+#define HC_SubA_HFogStL 0x0053
+#define HC_SubA_HFogStH 0x0054
+#define HC_SubA_HFogOOdMF 0x0055
+#define HC_SubA_HFogOOdEF 0x0056
+#define HC_SubA_HFogEndL 0x0057
+#define HC_SubA_HFogDenst 0x0058
+/* HC_SubA_FogLF 0x0050
+ */
+#define HC_FogLF_MASK 0x00000010
+#define HC_FogEq_MASK 0x00000008
+#define HC_FogMD_MASK 0x00000007
+#define HC_FogMD_LocalFog 0x00000000
+#define HC_FogMD_LinearFog 0x00000002
+#define HC_FogMD_ExponentialFog 0x00000004
+#define HC_FogMD_Exponential2Fog 0x00000005
+/* #define HC_FogMD_FogTable 0x00000003 */
+
+/* HC_SubA_HFogDenst 0x0058
+ */
+#define HC_FogDenst_MASK 0x001fff00
+#define HC_FogEndL_MASK 0x000000ff
+
+/* Texture subtype definitions
+ */
+#define HC_SubType_Tex0 0x00000000
+#define HC_SubType_Tex1 0x00000001
+#define HC_SubType_TexGeneral 0x000000fe
+
+/* Attribute of texture n
+ */
+#define HC_SubA_HTXnL0BasL 0x0000
+#define HC_SubA_HTXnL1BasL 0x0001
+#define HC_SubA_HTXnL2BasL 0x0002
+#define HC_SubA_HTXnL3BasL 0x0003
+#define HC_SubA_HTXnL4BasL 0x0004
+#define HC_SubA_HTXnL5BasL 0x0005
+#define HC_SubA_HTXnL6BasL 0x0006
+#define HC_SubA_HTXnL7BasL 0x0007
+#define HC_SubA_HTXnL8BasL 0x0008
+#define HC_SubA_HTXnL9BasL 0x0009
+#define HC_SubA_HTXnLaBasL 0x000a
+#define HC_SubA_HTXnLbBasL 0x000b
+#define HC_SubA_HTXnLcBasL 0x000c
+#define HC_SubA_HTXnLdBasL 0x000d
+#define HC_SubA_HTXnLeBasL 0x000e
+#define HC_SubA_HTXnLfBasL 0x000f
+#define HC_SubA_HTXnL10BasL 0x0010
+#define HC_SubA_HTXnL11BasL 0x0011
+#define HC_SubA_HTXnL012BasH 0x0020
+#define HC_SubA_HTXnL345BasH 0x0021
+#define HC_SubA_HTXnL678BasH 0x0022
+#define HC_SubA_HTXnL9abBasH 0x0023
+#define HC_SubA_HTXnLcdeBasH 0x0024
+#define HC_SubA_HTXnLf1011BasH 0x0025
+#define HC_SubA_HTXnL0Pit 0x002b
+#define HC_SubA_HTXnL1Pit 0x002c
+#define HC_SubA_HTXnL2Pit 0x002d
+#define HC_SubA_HTXnL3Pit 0x002e
+#define HC_SubA_HTXnL4Pit 0x002f
+#define HC_SubA_HTXnL5Pit 0x0030
+#define HC_SubA_HTXnL6Pit 0x0031
+#define HC_SubA_HTXnL7Pit 0x0032
+#define HC_SubA_HTXnL8Pit 0x0033
+#define HC_SubA_HTXnL9Pit 0x0034
+#define HC_SubA_HTXnLaPit 0x0035
+#define HC_SubA_HTXnLbPit 0x0036
+#define HC_SubA_HTXnLcPit 0x0037
+#define HC_SubA_HTXnLdPit 0x0038
+#define HC_SubA_HTXnLePit 0x0039
+#define HC_SubA_HTXnLfPit 0x003a
+#define HC_SubA_HTXnL10Pit 0x003b
+#define HC_SubA_HTXnL11Pit 0x003c
+#define HC_SubA_HTXnL0_5WE 0x004b
+#define HC_SubA_HTXnL6_bWE 0x004c
+#define HC_SubA_HTXnLc_11WE 0x004d
+#define HC_SubA_HTXnL0_5HE 0x0051
+#define HC_SubA_HTXnL6_bHE 0x0052
+#define HC_SubA_HTXnLc_11HE 0x0053
+#define HC_SubA_HTXnL0OS 0x0077
+#define HC_SubA_HTXnTB 0x0078
+#define HC_SubA_HTXnMPMD 0x0079
+#define HC_SubA_HTXnCLODu 0x007a
+#define HC_SubA_HTXnFM 0x007b
+#define HC_SubA_HTXnTRCH 0x007c
+#define HC_SubA_HTXnTRCL 0x007d
+#define HC_SubA_HTXnTBC 0x007e
+#define HC_SubA_HTXnTRAH 0x007f
+#define HC_SubA_HTXnTBLCsat 0x0080
+#define HC_SubA_HTXnTBLCop 0x0081
+#define HC_SubA_HTXnTBLMPfog 0x0082
+#define HC_SubA_HTXnTBLAsat 0x0083
+#define HC_SubA_HTXnTBLRCa 0x0085
+#define HC_SubA_HTXnTBLRCb 0x0086
+#define HC_SubA_HTXnTBLRCc 0x0087
+#define HC_SubA_HTXnTBLRCbias 0x0088
+#define HC_SubA_HTXnTBLRAa 0x0089
+#define HC_SubA_HTXnTBLRFog 0x008a
+#define HC_SubA_HTXnBumpM00 0x0090
+#define HC_SubA_HTXnBumpM01 0x0091
+#define HC_SubA_HTXnBumpM10 0x0092
+#define HC_SubA_HTXnBumpM11 0x0093
+#define HC_SubA_HTXnLScale 0x0094
+#define HC_SubA_HTXSMD 0x0000
+/* HC_SubA_HTXnL012BasH 0x0020
+ */
+#define HC_HTXnL0BasH_MASK 0x000000ff
+#define HC_HTXnL1BasH_MASK 0x0000ff00
+#define HC_HTXnL2BasH_MASK 0x00ff0000
+#define HC_HTXnL1BasH_SHIFT 8
+#define HC_HTXnL2BasH_SHIFT 16
+/* HC_SubA_HTXnL345BasH 0x0021
+ */
+#define HC_HTXnL3BasH_MASK 0x000000ff
+#define HC_HTXnL4BasH_MASK 0x0000ff00
+#define HC_HTXnL5BasH_MASK 0x00ff0000
+#define HC_HTXnL4BasH_SHIFT 8
+#define HC_HTXnL5BasH_SHIFT 16
+/* HC_SubA_HTXnL678BasH 0x0022
+ */
+#define HC_HTXnL6BasH_MASK 0x000000ff
+#define HC_HTXnL7BasH_MASK 0x0000ff00
+#define HC_HTXnL8BasH_MASK 0x00ff0000
+#define HC_HTXnL7BasH_SHIFT 8
+#define HC_HTXnL8BasH_SHIFT 16
+/* HC_SubA_HTXnL9abBasH 0x0023
+ */
+#define HC_HTXnL9BasH_MASK 0x000000ff
+#define HC_HTXnLaBasH_MASK 0x0000ff00
+#define HC_HTXnLbBasH_MASK 0x00ff0000
+#define HC_HTXnLaBasH_SHIFT 8
+#define HC_HTXnLbBasH_SHIFT 16
+/* HC_SubA_HTXnLcdeBasH 0x0024
+ */
+#define HC_HTXnLcBasH_MASK 0x000000ff
+#define HC_HTXnLdBasH_MASK 0x0000ff00
+#define HC_HTXnLeBasH_MASK 0x00ff0000
+#define HC_HTXnLdBasH_SHIFT 8
+#define HC_HTXnLeBasH_SHIFT 16
+/* HC_SubA_HTXnLcdeBasH 0x0025
+ */
+#define HC_HTXnLfBasH_MASK 0x000000ff
+#define HC_HTXnL10BasH_MASK 0x0000ff00
+#define HC_HTXnL11BasH_MASK 0x00ff0000
+#define HC_HTXnL10BasH_SHIFT 8
+#define HC_HTXnL11BasH_SHIFT 16
+/* HC_SubA_HTXnL0Pit 0x002b
+ */
+#define HC_HTXnLnPit_MASK 0x00003fff
+#define HC_HTXnEnPit_MASK 0x00080000
+#define HC_HTXnLnPitE_MASK 0x00f00000
+#define HC_HTXnLnPitE_SHIFT 20
+/* HC_SubA_HTXnL0_5WE 0x004b
+ */
+#define HC_HTXnL0WE_MASK 0x0000000f
+#define HC_HTXnL1WE_MASK 0x000000f0
+#define HC_HTXnL2WE_MASK 0x00000f00
+#define HC_HTXnL3WE_MASK 0x0000f000
+#define HC_HTXnL4WE_MASK 0x000f0000
+#define HC_HTXnL5WE_MASK 0x00f00000
+#define HC_HTXnL1WE_SHIFT 4
+#define HC_HTXnL2WE_SHIFT 8
+#define HC_HTXnL3WE_SHIFT 12
+#define HC_HTXnL4WE_SHIFT 16
+#define HC_HTXnL5WE_SHIFT 20
+/* HC_SubA_HTXnL6_bWE 0x004c
+ */
+#define HC_HTXnL6WE_MASK 0x0000000f
+#define HC_HTXnL7WE_MASK 0x000000f0
+#define HC_HTXnL8WE_MASK 0x00000f00
+#define HC_HTXnL9WE_MASK 0x0000f000
+#define HC_HTXnLaWE_MASK 0x000f0000
+#define HC_HTXnLbWE_MASK 0x00f00000
+#define HC_HTXnL7WE_SHIFT 4
+#define HC_HTXnL8WE_SHIFT 8
+#define HC_HTXnL9WE_SHIFT 12
+#define HC_HTXnLaWE_SHIFT 16
+#define HC_HTXnLbWE_SHIFT 20
+/* HC_SubA_HTXnLc_11WE 0x004d
+ */
+#define HC_HTXnLcWE_MASK 0x0000000f
+#define HC_HTXnLdWE_MASK 0x000000f0
+#define HC_HTXnLeWE_MASK 0x00000f00
+#define HC_HTXnLfWE_MASK 0x0000f000
+#define HC_HTXnL10WE_MASK 0x000f0000
+#define HC_HTXnL11WE_MASK 0x00f00000
+#define HC_HTXnLdWE_SHIFT 4
+#define HC_HTXnLeWE_SHIFT 8
+#define HC_HTXnLfWE_SHIFT 12
+#define HC_HTXnL10WE_SHIFT 16
+#define HC_HTXnL11WE_SHIFT 20
+/* HC_SubA_HTXnL0_5HE 0x0051
+ */
+#define HC_HTXnL0HE_MASK 0x0000000f
+#define HC_HTXnL1HE_MASK 0x000000f0
+#define HC_HTXnL2HE_MASK 0x00000f00
+#define HC_HTXnL3HE_MASK 0x0000f000
+#define HC_HTXnL4HE_MASK 0x000f0000
+#define HC_HTXnL5HE_MASK 0x00f00000
+#define HC_HTXnL1HE_SHIFT 4
+#define HC_HTXnL2HE_SHIFT 8
+#define HC_HTXnL3HE_SHIFT 12
+#define HC_HTXnL4HE_SHIFT 16
+#define HC_HTXnL5HE_SHIFT 20
+/* HC_SubA_HTXnL6_bHE 0x0052
+ */
+#define HC_HTXnL6HE_MASK 0x0000000f
+#define HC_HTXnL7HE_MASK 0x000000f0
+#define HC_HTXnL8HE_MASK 0x00000f00
+#define HC_HTXnL9HE_MASK 0x0000f000
+#define HC_HTXnLaHE_MASK 0x000f0000
+#define HC_HTXnLbHE_MASK 0x00f00000
+#define HC_HTXnL7HE_SHIFT 4
+#define HC_HTXnL8HE_SHIFT 8
+#define HC_HTXnL9HE_SHIFT 12
+#define HC_HTXnLaHE_SHIFT 16
+#define HC_HTXnLbHE_SHIFT 20
+/* HC_SubA_HTXnLc_11HE 0x0053
+ */
+#define HC_HTXnLcHE_MASK 0x0000000f
+#define HC_HTXnLdHE_MASK 0x000000f0
+#define HC_HTXnLeHE_MASK 0x00000f00
+#define HC_HTXnLfHE_MASK 0x0000f000
+#define HC_HTXnL10HE_MASK 0x000f0000
+#define HC_HTXnL11HE_MASK 0x00f00000
+#define HC_HTXnLdHE_SHIFT 4
+#define HC_HTXnLeHE_SHIFT 8
+#define HC_HTXnLfHE_SHIFT 12
+#define HC_HTXnL10HE_SHIFT 16
+#define HC_HTXnL11HE_SHIFT 20
+/* HC_SubA_HTXnL0OS 0x0077
+ */
+#define HC_HTXnL0OS_MASK 0x003ff000
+#define HC_HTXnLVmax_MASK 0x00000fc0
+#define HC_HTXnLVmin_MASK 0x0000003f
+#define HC_HTXnL0OS_SHIFT 12
+#define HC_HTXnLVmax_SHIFT 6
+/* HC_SubA_HTXnTB 0x0078
+ */
+#define HC_HTXnTB_MASK 0x00f00000
+#define HC_HTXnFLSe_MASK 0x0000e000
+#define HC_HTXnFLSs_MASK 0x00001c00
+#define HC_HTXnFLTe_MASK 0x00000380
+#define HC_HTXnFLTs_MASK 0x00000070
+#define HC_HTXnFLDs_MASK 0x0000000f
+#define HC_HTXnTB_NoTB 0x00000000
+#define HC_HTXnTB_TBC_S 0x00100000
+#define HC_HTXnTB_TBC_T 0x00200000
+#define HC_HTXnTB_TB_S 0x00400000
+#define HC_HTXnTB_TB_T 0x00800000
+#define HC_HTXnFLSe_Nearest 0x00000000
+#define HC_HTXnFLSe_Linear 0x00002000
+#define HC_HTXnFLSe_NonLinear 0x00004000
+#define HC_HTXnFLSe_Sharp 0x00008000
+#define HC_HTXnFLSe_Flat_Gaussian_Cubic 0x0000c000
+#define HC_HTXnFLSs_Nearest 0x00000000
+#define HC_HTXnFLSs_Linear 0x00000400
+#define HC_HTXnFLSs_NonLinear 0x00000800
+#define HC_HTXnFLSs_Flat_Gaussian_Cubic 0x00001800
+#define HC_HTXnFLTe_Nearest 0x00000000
+#define HC_HTXnFLTe_Linear 0x00000080
+#define HC_HTXnFLTe_NonLinear 0x00000100
+#define HC_HTXnFLTe_Sharp 0x00000180
+#define HC_HTXnFLTe_Flat_Gaussian_Cubic 0x00000300
+#define HC_HTXnFLTs_Nearest 0x00000000
+#define HC_HTXnFLTs_Linear 0x00000010
+#define HC_HTXnFLTs_NonLinear 0x00000020
+#define HC_HTXnFLTs_Flat_Gaussian_Cubic 0x00000060
+#define HC_HTXnFLDs_Tex0 0x00000000
+#define HC_HTXnFLDs_Nearest 0x00000001
+#define HC_HTXnFLDs_Linear 0x00000002
+#define HC_HTXnFLDs_NonLinear 0x00000003
+#define HC_HTXnFLDs_Dither 0x00000004
+#define HC_HTXnFLDs_ConstLOD 0x00000005
+#define HC_HTXnFLDs_Ani 0x00000006
+#define HC_HTXnFLDs_AniDither 0x00000007
+/* HC_SubA_HTXnMPMD 0x0079
+ */
+#define HC_HTXnMPMD_SMASK 0x00070000
+#define HC_HTXnMPMD_TMASK 0x00380000
+#define HC_HTXnLODDTf_MASK 0x00000007
+#define HC_HTXnXY2ST_MASK 0x00000008
+#define HC_HTXnMPMD_Tsingle 0x00000000
+#define HC_HTXnMPMD_Tclamp 0x00080000
+#define HC_HTXnMPMD_Trepeat 0x00100000
+#define HC_HTXnMPMD_Tmirror 0x00180000
+#define HC_HTXnMPMD_Twrap 0x00200000
+#define HC_HTXnMPMD_Ssingle 0x00000000
+#define HC_HTXnMPMD_Sclamp 0x00010000
+#define HC_HTXnMPMD_Srepeat 0x00020000
+#define HC_HTXnMPMD_Smirror 0x00030000
+#define HC_HTXnMPMD_Swrap 0x00040000
+/* HC_SubA_HTXnCLODu 0x007a
+ */
+#define HC_HTXnCLODu_MASK 0x000ffc00
+#define HC_HTXnCLODd_MASK 0x000003ff
+#define HC_HTXnCLODu_SHIFT 10
+/* HC_SubA_HTXnFM 0x007b
+ */
+#define HC_HTXnFM_MASK 0x00ff0000
+#define HC_HTXnLoc_MASK 0x00000003
+#define HC_HTXnFM_INDEX 0x00000000
+#define HC_HTXnFM_Intensity 0x00080000
+#define HC_HTXnFM_Lum 0x00100000
+#define HC_HTXnFM_Alpha 0x00180000
+#define HC_HTXnFM_DX 0x00280000
+#define HC_HTXnFM_ARGB16 0x00880000
+#define HC_HTXnFM_ARGB32 0x00980000
+#define HC_HTXnFM_ABGR16 0x00a80000
+#define HC_HTXnFM_ABGR32 0x00b80000
+#define HC_HTXnFM_RGBA16 0x00c80000
+#define HC_HTXnFM_RGBA32 0x00d80000
+#define HC_HTXnFM_BGRA16 0x00e80000
+#define HC_HTXnFM_BGRA32 0x00f80000
+#define HC_HTXnFM_BUMPMAP 0x00380000
+#define HC_HTXnFM_Index1 (HC_HTXnFM_INDEX | 0x00000000)
+#define HC_HTXnFM_Index2 (HC_HTXnFM_INDEX | 0x00010000)
+#define HC_HTXnFM_Index4 (HC_HTXnFM_INDEX | 0x00020000)
+#define HC_HTXnFM_Index8 (HC_HTXnFM_INDEX | 0x00030000)
+#define HC_HTXnFM_T1 (HC_HTXnFM_Intensity | 0x00000000)
+#define HC_HTXnFM_T2 (HC_HTXnFM_Intensity | 0x00010000)
+#define HC_HTXnFM_T4 (HC_HTXnFM_Intensity | 0x00020000)
+#define HC_HTXnFM_T8 (HC_HTXnFM_Intensity | 0x00030000)
+#define HC_HTXnFM_L1 (HC_HTXnFM_Lum | 0x00000000)
+#define HC_HTXnFM_L2 (HC_HTXnFM_Lum | 0x00010000)
+#define HC_HTXnFM_L4 (HC_HTXnFM_Lum | 0x00020000)
+#define HC_HTXnFM_L8 (HC_HTXnFM_Lum | 0x00030000)
+#define HC_HTXnFM_AL44 (HC_HTXnFM_Lum | 0x00040000)
+#define HC_HTXnFM_AL88 (HC_HTXnFM_Lum | 0x00050000)
+#define HC_HTXnFM_A1 (HC_HTXnFM_Alpha | 0x00000000)
+#define HC_HTXnFM_A2 (HC_HTXnFM_Alpha | 0x00010000)
+#define HC_HTXnFM_A4 (HC_HTXnFM_Alpha | 0x00020000)
+#define HC_HTXnFM_A8 (HC_HTXnFM_Alpha | 0x00030000)
+#define HC_HTXnFM_DX1 (HC_HTXnFM_DX | 0x00010000)
+#define HC_HTXnFM_DX23 (HC_HTXnFM_DX | 0x00020000)
+#define HC_HTXnFM_DX45 (HC_HTXnFM_DX | 0x00030000)
+#define HC_HTXnFM_RGB555 (HC_HTXnFM_ARGB16 | 0x00000000)
+#define HC_HTXnFM_RGB565 (HC_HTXnFM_ARGB16 | 0x00010000)
+#define HC_HTXnFM_ARGB1555 (HC_HTXnFM_ARGB16 | 0x00020000)
+#define HC_HTXnFM_ARGB4444 (HC_HTXnFM_ARGB16 | 0x00030000)
+#define HC_HTXnFM_ARGB0888 (HC_HTXnFM_ARGB32 | 0x00000000)
+#define HC_HTXnFM_ARGB8888 (HC_HTXnFM_ARGB32 | 0x00010000)
+#define HC_HTXnFM_BGR555 (HC_HTXnFM_ABGR16 | 0x00000000)
+#define HC_HTXnFM_BGR565 (HC_HTXnFM_ABGR16 | 0x00010000)
+#define HC_HTXnFM_ABGR1555 (HC_HTXnFM_ABGR16 | 0x00020000)
+#define HC_HTXnFM_ABGR4444 (HC_HTXnFM_ABGR16 | 0x00030000)
+#define HC_HTXnFM_ABGR0888 (HC_HTXnFM_ABGR32 | 0x00000000)
+#define HC_HTXnFM_ABGR8888 (HC_HTXnFM_ABGR32 | 0x00010000)
+#define HC_HTXnFM_RGBA5550 (HC_HTXnFM_RGBA16 | 0x00000000)
+#define HC_HTXnFM_RGBA5551 (HC_HTXnFM_RGBA16 | 0x00020000)
+#define HC_HTXnFM_RGBA4444 (HC_HTXnFM_RGBA16 | 0x00030000)
+#define HC_HTXnFM_RGBA8880 (HC_HTXnFM_RGBA32 | 0x00000000)
+#define HC_HTXnFM_RGBA8888 (HC_HTXnFM_RGBA32 | 0x00010000)
+#define HC_HTXnFM_BGRA5550 (HC_HTXnFM_BGRA16 | 0x00000000)
+#define HC_HTXnFM_BGRA5551 (HC_HTXnFM_BGRA16 | 0x00020000)
+#define HC_HTXnFM_BGRA4444 (HC_HTXnFM_BGRA16 | 0x00030000)
+#define HC_HTXnFM_BGRA8880 (HC_HTXnFM_BGRA32 | 0x00000000)
+#define HC_HTXnFM_BGRA8888 (HC_HTXnFM_BGRA32 | 0x00010000)
+#define HC_HTXnFM_VU88 (HC_HTXnFM_BUMPMAP | 0x00000000)
+#define HC_HTXnFM_LVU655 (HC_HTXnFM_BUMPMAP | 0x00010000)
+#define HC_HTXnFM_LVU888 (HC_HTXnFM_BUMPMAP | 0x00020000)
+#define HC_HTXnLoc_Local 0x00000000
+#define HC_HTXnLoc_Sys 0x00000002
+#define HC_HTXnLoc_AGP 0x00000003
+/* HC_SubA_HTXnTRAH 0x007f
+ */
+#define HC_HTXnTRAH_MASK 0x00ff0000
+#define HC_HTXnTRAL_MASK 0x0000ff00
+#define HC_HTXnTBA_MASK 0x000000ff
+#define HC_HTXnTRAH_SHIFT 16
+#define HC_HTXnTRAL_SHIFT 8
+/* HC_SubA_HTXnTBLCsat 0x0080
+ *-- Define the input texture.
+ */
+#define HC_XTC_TOPC 0x00000000
+#define HC_XTC_InvTOPC 0x00000010
+#define HC_XTC_TOPCp5 0x00000020
+#define HC_XTC_Cbias 0x00000000
+#define HC_XTC_InvCbias 0x00000010
+#define HC_XTC_0 0x00000000
+#define HC_XTC_Dif 0x00000001
+#define HC_XTC_Spec 0x00000002
+#define HC_XTC_Tex 0x00000003
+#define HC_XTC_Cur 0x00000004
+#define HC_XTC_Adif 0x00000005
+#define HC_XTC_Fog 0x00000006
+#define HC_XTC_Atex 0x00000007
+#define HC_XTC_Acur 0x00000008
+#define HC_XTC_HTXnTBLRC 0x00000009
+#define HC_XTC_Ctexnext 0x0000000a
+/*--
+ */
+#define HC_HTXnTBLCsat_MASK 0x00800000
+#define HC_HTXnTBLCa_MASK 0x000fc000
+#define HC_HTXnTBLCb_MASK 0x00001f80
+#define HC_HTXnTBLCc_MASK 0x0000003f
+#define HC_HTXnTBLCa_TOPC (HC_XTC_TOPC << 14)
+#define HC_HTXnTBLCa_InvTOPC (HC_XTC_InvTOPC << 14)
+#define HC_HTXnTBLCa_TOPCp5 (HC_XTC_TOPCp5 << 14)
+#define HC_HTXnTBLCa_0 (HC_XTC_0 << 14)
+#define HC_HTXnTBLCa_Dif (HC_XTC_Dif << 14)
+#define HC_HTXnTBLCa_Spec (HC_XTC_Spec << 14)
+#define HC_HTXnTBLCa_Tex (HC_XTC_Tex << 14)
+#define HC_HTXnTBLCa_Cur (HC_XTC_Cur << 14)
+#define HC_HTXnTBLCa_Adif (HC_XTC_Adif << 14)
+#define HC_HTXnTBLCa_Fog (HC_XTC_Fog << 14)
+#define HC_HTXnTBLCa_Atex (HC_XTC_Atex << 14)
+#define HC_HTXnTBLCa_Acur (HC_XTC_Acur << 14)
+#define HC_HTXnTBLCa_HTXnTBLRC (HC_XTC_HTXnTBLRC << 14)
+#define HC_HTXnTBLCa_Ctexnext (HC_XTC_Ctexnext << 14)
+#define HC_HTXnTBLCb_TOPC (HC_XTC_TOPC << 7)
+#define HC_HTXnTBLCb_InvTOPC (HC_XTC_InvTOPC << 7)
+#define HC_HTXnTBLCb_TOPCp5 (HC_XTC_TOPCp5 << 7)
+#define HC_HTXnTBLCb_0 (HC_XTC_0 << 7)
+#define HC_HTXnTBLCb_Dif (HC_XTC_Dif << 7)
+#define HC_HTXnTBLCb_Spec (HC_XTC_Spec << 7)
+#define HC_HTXnTBLCb_Tex (HC_XTC_Tex << 7)
+#define HC_HTXnTBLCb_Cur (HC_XTC_Cur << 7)
+#define HC_HTXnTBLCb_Adif (HC_XTC_Adif << 7)
+#define HC_HTXnTBLCb_Fog (HC_XTC_Fog << 7)
+#define HC_HTXnTBLCb_Atex (HC_XTC_Atex << 7)
+#define HC_HTXnTBLCb_Acur (HC_XTC_Acur << 7)
+#define HC_HTXnTBLCb_HTXnTBLRC (HC_XTC_HTXnTBLRC << 7)
+#define HC_HTXnTBLCb_Ctexnext (HC_XTC_Ctexnext << 7)
+#define HC_HTXnTBLCc_TOPC (HC_XTC_TOPC << 0)
+#define HC_HTXnTBLCc_InvTOPC (HC_XTC_InvTOPC << 0)
+#define HC_HTXnTBLCc_TOPCp5 (HC_XTC_TOPCp5 << 0)
+#define HC_HTXnTBLCc_0 (HC_XTC_0 << 0)
+#define HC_HTXnTBLCc_Dif (HC_XTC_Dif << 0)
+#define HC_HTXnTBLCc_Spec (HC_XTC_Spec << 0)
+#define HC_HTXnTBLCc_Tex (HC_XTC_Tex << 0)
+#define HC_HTXnTBLCc_Cur (HC_XTC_Cur << 0)
+#define HC_HTXnTBLCc_Adif (HC_XTC_Adif << 0)
+#define HC_HTXnTBLCc_Fog (HC_XTC_Fog << 0)
+#define HC_HTXnTBLCc_Atex (HC_XTC_Atex << 0)
+#define HC_HTXnTBLCc_Acur (HC_XTC_Acur << 0)
+#define HC_HTXnTBLCc_HTXnTBLRC (HC_XTC_HTXnTBLRC << 0)
+#define HC_HTXnTBLCc_Ctexnext (HC_XTC_Ctexnext << 0)
+/* HC_SubA_HTXnTBLCop 0x0081
+ */
+#define HC_HTXnTBLdot_MASK 0x00c00000
+#define HC_HTXnTBLCop_MASK 0x00380000
+#define HC_HTXnTBLCbias_MASK 0x0007c000
+#define HC_HTXnTBLCshift_MASK 0x00001800
+#define HC_HTXnTBLAop_MASK 0x00000380
+#define HC_HTXnTBLAbias_MASK 0x00000078
+#define HC_HTXnTBLAshift_MASK 0x00000003
+#define HC_HTXnTBLCop_Add 0x00000000
+#define HC_HTXnTBLCop_Sub 0x00080000
+#define HC_HTXnTBLCop_Min 0x00100000
+#define HC_HTXnTBLCop_Max 0x00180000
+#define HC_HTXnTBLCop_Mask 0x00200000
+#define HC_HTXnTBLCbias_Cbias (HC_XTC_Cbias << 14)
+#define HC_HTXnTBLCbias_InvCbias (HC_XTC_InvCbias << 14)
+#define HC_HTXnTBLCbias_0 (HC_XTC_0 << 14)
+#define HC_HTXnTBLCbias_Dif (HC_XTC_Dif << 14)
+#define HC_HTXnTBLCbias_Spec (HC_XTC_Spec << 14)
+#define HC_HTXnTBLCbias_Tex (HC_XTC_Tex << 14)
+#define HC_HTXnTBLCbias_Cur (HC_XTC_Cur << 14)
+#define HC_HTXnTBLCbias_Adif (HC_XTC_Adif << 14)
+#define HC_HTXnTBLCbias_Fog (HC_XTC_Fog << 14)
+#define HC_HTXnTBLCbias_Atex (HC_XTC_Atex << 14)
+#define HC_HTXnTBLCbias_Acur (HC_XTC_Acur << 14)
+#define HC_HTXnTBLCbias_HTXnTBLRC (HC_XTC_HTXnTBLRC << 14)
+#define HC_HTXnTBLCshift_1 0x00000000
+#define HC_HTXnTBLCshift_2 0x00000800
+#define HC_HTXnTBLCshift_No 0x00001000
+#define HC_HTXnTBLCshift_DotP 0x00001800
+/*=* John Sheng [2003.7.18] texture combine *=*/
+#define HC_HTXnTBLDOT3 0x00080000
+#define HC_HTXnTBLDOT4 0x000C0000
+
+#define HC_HTXnTBLAop_Add 0x00000000
+#define HC_HTXnTBLAop_Sub 0x00000080
+#define HC_HTXnTBLAop_Min 0x00000100
+#define HC_HTXnTBLAop_Max 0x00000180
+#define HC_HTXnTBLAop_Mask 0x00000200
+#define HC_HTXnTBLAbias_Inv 0x00000040
+#define HC_HTXnTBLAbias_Adif 0x00000000
+#define HC_HTXnTBLAbias_Fog 0x00000008
+#define HC_HTXnTBLAbias_Acur 0x00000010
+#define HC_HTXnTBLAbias_HTXnTBLRAbias 0x00000018
+#define HC_HTXnTBLAbias_Atex 0x00000020
+#define HC_HTXnTBLAshift_1 0x00000000
+#define HC_HTXnTBLAshift_2 0x00000001
+#define HC_HTXnTBLAshift_No 0x00000002
+/* #define HC_HTXnTBLAshift_DotP 0x00000003 */
+/* HC_SubA_HTXnTBLMPFog 0x0082
+ */
+#define HC_HTXnTBLMPfog_MASK 0x00e00000
+#define HC_HTXnTBLMPfog_0 0x00000000
+#define HC_HTXnTBLMPfog_Adif 0x00200000
+#define HC_HTXnTBLMPfog_Fog 0x00400000
+#define HC_HTXnTBLMPfog_Atex 0x00600000
+#define HC_HTXnTBLMPfog_Acur 0x00800000
+#define HC_HTXnTBLMPfog_GHTXnTBLRFog 0x00a00000
+/* HC_SubA_HTXnTBLAsat 0x0083
+ *-- Define the texture alpha input.
+ */
+#define HC_XTA_TOPA 0x00000000
+#define HC_XTA_InvTOPA 0x00000008
+#define HC_XTA_TOPAp5 0x00000010
+#define HC_XTA_Adif 0x00000000
+#define HC_XTA_Fog 0x00000001
+#define HC_XTA_Acur 0x00000002
+#define HC_XTA_HTXnTBLRA 0x00000003
+#define HC_XTA_Atex 0x00000004
+#define HC_XTA_Atexnext 0x00000005
+/*--
+ */
+#define HC_HTXnTBLAsat_MASK 0x00800000
+#define HC_HTXnTBLAMB_MASK 0x00700000
+#define HC_HTXnTBLAa_MASK 0x0007c000
+#define HC_HTXnTBLAb_MASK 0x00000f80
+#define HC_HTXnTBLAc_MASK 0x0000001f
+#define HC_HTXnTBLAMB_SHIFT 20
+#define HC_HTXnTBLAa_TOPA (HC_XTA_TOPA << 14)
+#define HC_HTXnTBLAa_InvTOPA (HC_XTA_InvTOPA << 14)
+#define HC_HTXnTBLAa_TOPAp5 (HC_XTA_TOPAp5 << 14)
+#define HC_HTXnTBLAa_Adif (HC_XTA_Adif << 14)
+#define HC_HTXnTBLAa_Fog (HC_XTA_Fog << 14)
+#define HC_HTXnTBLAa_Acur (HC_XTA_Acur << 14)
+#define HC_HTXnTBLAa_HTXnTBLRA (HC_XTA_HTXnTBLRA << 14)
+#define HC_HTXnTBLAa_Atex (HC_XTA_Atex << 14)
+#define HC_HTXnTBLAa_Atexnext (HC_XTA_Atexnext << 14)
+#define HC_HTXnTBLAb_TOPA (HC_XTA_TOPA << 7)
+#define HC_HTXnTBLAb_InvTOPA (HC_XTA_InvTOPA << 7)
+#define HC_HTXnTBLAb_TOPAp5 (HC_XTA_TOPAp5 << 7)
+#define HC_HTXnTBLAb_Adif (HC_XTA_Adif << 7)
+#define HC_HTXnTBLAb_Fog (HC_XTA_Fog << 7)
+#define HC_HTXnTBLAb_Acur (HC_XTA_Acur << 7)
+#define HC_HTXnTBLAb_HTXnTBLRA (HC_XTA_HTXnTBLRA << 7)
+#define HC_HTXnTBLAb_Atex (HC_XTA_Atex << 7)
+#define HC_HTXnTBLAb_Atexnext (HC_XTA_Atexnext << 7)
+#define HC_HTXnTBLAc_TOPA (HC_XTA_TOPA << 0)
+#define HC_HTXnTBLAc_InvTOPA (HC_XTA_InvTOPA << 0)
+#define HC_HTXnTBLAc_TOPAp5 (HC_XTA_TOPAp5 << 0)
+#define HC_HTXnTBLAc_Adif (HC_XTA_Adif << 0)
+#define HC_HTXnTBLAc_Fog (HC_XTA_Fog << 0)
+#define HC_HTXnTBLAc_Acur (HC_XTA_Acur << 0)
+#define HC_HTXnTBLAc_HTXnTBLRA (HC_XTA_HTXnTBLRA << 0)
+#define HC_HTXnTBLAc_Atex (HC_XTA_Atex << 0)
+#define HC_HTXnTBLAc_Atexnext (HC_XTA_Atexnext << 0)
+/* HC_SubA_HTXnTBLRAa 0x0089
+ */
+#define HC_HTXnTBLRAa_MASK 0x00ff0000
+#define HC_HTXnTBLRAb_MASK 0x0000ff00
+#define HC_HTXnTBLRAc_MASK 0x000000ff
+#define HC_HTXnTBLRAa_SHIFT 16
+#define HC_HTXnTBLRAb_SHIFT 8
+#define HC_HTXnTBLRAc_SHIFT 0
+/* HC_SubA_HTXnTBLRFog 0x008a
+ */
+#define HC_HTXnTBLRFog_MASK 0x0000ff00
+#define HC_HTXnTBLRAbias_MASK 0x000000ff
+#define HC_HTXnTBLRFog_SHIFT 8
+#define HC_HTXnTBLRAbias_SHIFT 0
+/* HC_SubA_HTXnLScale 0x0094
+ */
+#define HC_HTXnLScale_MASK 0x0007fc00
+#define HC_HTXnLOff_MASK 0x000001ff
+#define HC_HTXnLScale_SHIFT 10
+/* HC_SubA_HTXSMD 0x0000
+ */
+#define HC_HTXSMD_MASK 0x00000080
+#define HC_HTXTMD_MASK 0x00000040
+#define HC_HTXNum_MASK 0x00000038
+#define HC_HTXTRMD_MASK 0x00000006
+#define HC_HTXCHCLR_MASK 0x00000001
+#define HC_HTXNum_SHIFT 3
+
+/* Texture Palette n
+ */
+#define HC_SubType_TexPalette0 0x00000000
+#define HC_SubType_TexPalette1 0x00000001
+#define HC_SubType_FogTable 0x00000010
+#define HC_SubType_Stipple 0x00000014
+/* HC_SubA_TexPalette0 0x0000
+ */
+#define HC_HTPnA_MASK 0xff000000
+#define HC_HTPnR_MASK 0x00ff0000
+#define HC_HTPnG_MASK 0x0000ff00
+#define HC_HTPnB_MASK 0x000000ff
+/* HC_SubA_FogTable 0x0010
+ */
+#define HC_HFPn3_MASK 0xff000000
+#define HC_HFPn2_MASK 0x00ff0000
+#define HC_HFPn1_MASK 0x0000ff00
+#define HC_HFPn_MASK 0x000000ff
+#define HC_HFPn3_SHIFT 24
+#define HC_HFPn2_SHIFT 16
+#define HC_HFPn1_SHIFT 8
+
+/* Auto Testing & Security
+ */
+#define HC_SubA_HenFIFOAT 0x0000
+#define HC_SubA_HFBDrawFirst 0x0004
+#define HC_SubA_HFBBasL 0x0005
+#define HC_SubA_HFBDst 0x0006
+/* HC_SubA_HenFIFOAT 0x0000
+ */
+#define HC_HenFIFOAT_MASK 0x00000020
+#define HC_HenGEMILock_MASK 0x00000010
+#define HC_HenFBASwap_MASK 0x00000008
+#define HC_HenOT_MASK 0x00000004
+#define HC_HenCMDQ_MASK 0x00000002
+#define HC_HenTXCTSU_MASK 0x00000001
+/* HC_SubA_HFBDrawFirst 0x0004
+ */
+#define HC_HFBDrawFirst_MASK 0x00000800
+#define HC_HFBQueue_MASK 0x00000400
+#define HC_HFBLock_MASK 0x00000200
+#define HC_HEOF_MASK 0x00000100
+#define HC_HFBBasH_MASK 0x000000ff
+
+/* GEMI Setting
+ */
+#define HC_SubA_HTArbRCM 0x0008
+#define HC_SubA_HTArbRZ 0x000a
+#define HC_SubA_HTArbWZ 0x000b
+#define HC_SubA_HTArbRTX 0x000c
+#define HC_SubA_HTArbRCW 0x000d
+#define HC_SubA_HTArbE2 0x000e
+#define HC_SubA_HArbRQCM 0x0010
+#define HC_SubA_HArbWQCM 0x0011
+#define HC_SubA_HGEMITout 0x0020
+#define HC_SubA_HFthRTXD 0x0040
+#define HC_SubA_HFthRTXA 0x0044
+#define HC_SubA_HCMDQstL 0x0050
+#define HC_SubA_HCMDQendL 0x0051
+#define HC_SubA_HCMDQLen 0x0052
+/* HC_SubA_HTArbRCM 0x0008
+ */
+#define HC_HTArbRCM_MASK 0x0000ffff
+/* HC_SubA_HTArbRZ 0x000a
+ */
+#define HC_HTArbRZ_MASK 0x0000ffff
+/* HC_SubA_HTArbWZ 0x000b
+ */
+#define HC_HTArbWZ_MASK 0x0000ffff
+/* HC_SubA_HTArbRTX 0x000c
+ */
+#define HC_HTArbRTX_MASK 0x0000ffff
+/* HC_SubA_HTArbRCW 0x000d
+ */
+#define HC_HTArbRCW_MASK 0x0000ffff
+/* HC_SubA_HTArbE2 0x000e
+ */
+#define HC_HTArbE2_MASK 0x0000ffff
+/* HC_SubA_HArbRQCM 0x0010
+ */
+#define HC_HTArbRQCM_MASK 0x0000ffff
+/* HC_SubA_HArbWQCM 0x0011
+ */
+#define HC_HArbWQCM_MASK 0x0000ffff
+/* HC_SubA_HGEMITout 0x0020
+ */
+#define HC_HGEMITout_MASK 0x000f0000
+#define HC_HNPArbZC_MASK 0x0000ffff
+#define HC_HGEMITout_SHIFT 16
+/* HC_SubA_HFthRTXD 0x0040
+ */
+#define HC_HFthRTXD_MASK 0x00ff0000
+#define HC_HFthRZD_MASK 0x0000ff00
+#define HC_HFthWZD_MASK 0x000000ff
+#define HC_HFthRTXD_SHIFT 16
+#define HC_HFthRZD_SHIFT 8
+/* HC_SubA_HFthRTXA 0x0044
+ */
+#define HC_HFthRTXA_MASK 0x000000ff
+
+/******************************************************************************
+** Define the Halcyon Internal register access constants. For simulator only.
+******************************************************************************/
+#define HC_SIMA_HAGPBstL 0x0000
+#define HC_SIMA_HAGPBendL 0x0001
+#define HC_SIMA_HAGPCMNT 0x0002
+#define HC_SIMA_HAGPBpL 0x0003
+#define HC_SIMA_HAGPBpH 0x0004
+#define HC_SIMA_HClipTB 0x0005
+#define HC_SIMA_HClipLR 0x0006
+#define HC_SIMA_HFPClipTL 0x0007
+#define HC_SIMA_HFPClipBL 0x0008
+#define HC_SIMA_HFPClipLL 0x0009
+#define HC_SIMA_HFPClipRL 0x000a
+#define HC_SIMA_HFPClipTBH 0x000b
+#define HC_SIMA_HFPClipLRH 0x000c
+#define HC_SIMA_HLP 0x000d
+#define HC_SIMA_HLPRF 0x000e
+#define HC_SIMA_HSolidCL 0x000f
+#define HC_SIMA_HPixGC 0x0010
+#define HC_SIMA_HSPXYOS 0x0011
+#define HC_SIMA_HCmdA 0x0012
+#define HC_SIMA_HCmdB 0x0013
+#define HC_SIMA_HEnable 0x0014
+#define HC_SIMA_HZWBBasL 0x0015
+#define HC_SIMA_HZWBBasH 0x0016
+#define HC_SIMA_HZWBType 0x0017
+#define HC_SIMA_HZBiasL 0x0018
+#define HC_SIMA_HZWBend 0x0019
+#define HC_SIMA_HZWTMD 0x001a
+#define HC_SIMA_HZWCDL 0x001b
+#define HC_SIMA_HZWCTAGnum 0x001c
+#define HC_SIMA_HZCYNum 0x001d
+#define HC_SIMA_HZWCFire 0x001e
+/* #define HC_SIMA_HSBBasL 0x001d */
+/* #define HC_SIMA_HSBBasH 0x001e */
+/* #define HC_SIMA_HSBFM 0x001f */
+#define HC_SIMA_HSTREF 0x0020
+#define HC_SIMA_HSTMD 0x0021
+#define HC_SIMA_HABBasL 0x0022
+#define HC_SIMA_HABBasH 0x0023
+#define HC_SIMA_HABFM 0x0024
+#define HC_SIMA_HATMD 0x0025
+#define HC_SIMA_HABLCsat 0x0026
+#define HC_SIMA_HABLCop 0x0027
+#define HC_SIMA_HABLAsat 0x0028
+#define HC_SIMA_HABLAop 0x0029
+#define HC_SIMA_HABLRCa 0x002a
+#define HC_SIMA_HABLRFCa 0x002b
+#define HC_SIMA_HABLRCbias 0x002c
+#define HC_SIMA_HABLRCb 0x002d
+#define HC_SIMA_HABLRFCb 0x002e
+#define HC_SIMA_HABLRAa 0x002f
+#define HC_SIMA_HABLRAb 0x0030
+#define HC_SIMA_HDBBasL 0x0031
+#define HC_SIMA_HDBBasH 0x0032
+#define HC_SIMA_HDBFM 0x0033
+#define HC_SIMA_HFBBMSKL 0x0034
+#define HC_SIMA_HROP 0x0035
+#define HC_SIMA_HFogLF 0x0036
+#define HC_SIMA_HFogCL 0x0037
+#define HC_SIMA_HFogCH 0x0038
+#define HC_SIMA_HFogStL 0x0039
+#define HC_SIMA_HFogStH 0x003a
+#define HC_SIMA_HFogOOdMF 0x003b
+#define HC_SIMA_HFogOOdEF 0x003c
+#define HC_SIMA_HFogEndL 0x003d
+#define HC_SIMA_HFogDenst 0x003e
+/*---- start of texture 0 setting ----
+ */
+#define HC_SIMA_HTX0L0BasL 0x0040
+#define HC_SIMA_HTX0L1BasL 0x0041
+#define HC_SIMA_HTX0L2BasL 0x0042
+#define HC_SIMA_HTX0L3BasL 0x0043
+#define HC_SIMA_HTX0L4BasL 0x0044
+#define HC_SIMA_HTX0L5BasL 0x0045
+#define HC_SIMA_HTX0L6BasL 0x0046
+#define HC_SIMA_HTX0L7BasL 0x0047
+#define HC_SIMA_HTX0L8BasL 0x0048
+#define HC_SIMA_HTX0L9BasL 0x0049
+#define HC_SIMA_HTX0LaBasL 0x004a
+#define HC_SIMA_HTX0LbBasL 0x004b
+#define HC_SIMA_HTX0LcBasL 0x004c
+#define HC_SIMA_HTX0LdBasL 0x004d
+#define HC_SIMA_HTX0LeBasL 0x004e
+#define HC_SIMA_HTX0LfBasL 0x004f
+#define HC_SIMA_HTX0L10BasL 0x0050
+#define HC_SIMA_HTX0L11BasL 0x0051
+#define HC_SIMA_HTX0L012BasH 0x0052
+#define HC_SIMA_HTX0L345BasH 0x0053
+#define HC_SIMA_HTX0L678BasH 0x0054
+#define HC_SIMA_HTX0L9abBasH 0x0055
+#define HC_SIMA_HTX0LcdeBasH 0x0056
+#define HC_SIMA_HTX0Lf1011BasH 0x0057
+#define HC_SIMA_HTX0L0Pit 0x0058
+#define HC_SIMA_HTX0L1Pit 0x0059
+#define HC_SIMA_HTX0L2Pit 0x005a
+#define HC_SIMA_HTX0L3Pit 0x005b
+#define HC_SIMA_HTX0L4Pit 0x005c
+#define HC_SIMA_HTX0L5Pit 0x005d
+#define HC_SIMA_HTX0L6Pit 0x005e
+#define HC_SIMA_HTX0L7Pit 0x005f
+#define HC_SIMA_HTX0L8Pit 0x0060
+#define HC_SIMA_HTX0L9Pit 0x0061
+#define HC_SIMA_HTX0LaPit 0x0062
+#define HC_SIMA_HTX0LbPit 0x0063
+#define HC_SIMA_HTX0LcPit 0x0064
+#define HC_SIMA_HTX0LdPit 0x0065
+#define HC_SIMA_HTX0LePit 0x0066
+#define HC_SIMA_HTX0LfPit 0x0067
+#define HC_SIMA_HTX0L10Pit 0x0068
+#define HC_SIMA_HTX0L11Pit 0x0069
+#define HC_SIMA_HTX0L0_5WE 0x006a
+#define HC_SIMA_HTX0L6_bWE 0x006b
+#define HC_SIMA_HTX0Lc_11WE 0x006c
+#define HC_SIMA_HTX0L0_5HE 0x006d
+#define HC_SIMA_HTX0L6_bHE 0x006e
+#define HC_SIMA_HTX0Lc_11HE 0x006f
+#define HC_SIMA_HTX0L0OS 0x0070
+#define HC_SIMA_HTX0TB 0x0071
+#define HC_SIMA_HTX0MPMD 0x0072
+#define HC_SIMA_HTX0CLODu 0x0073
+#define HC_SIMA_HTX0FM 0x0074
+#define HC_SIMA_HTX0TRCH 0x0075
+#define HC_SIMA_HTX0TRCL 0x0076
+#define HC_SIMA_HTX0TBC 0x0077
+#define HC_SIMA_HTX0TRAH 0x0078
+#define HC_SIMA_HTX0TBLCsat 0x0079
+#define HC_SIMA_HTX0TBLCop 0x007a
+#define HC_SIMA_HTX0TBLMPfog 0x007b
+#define HC_SIMA_HTX0TBLAsat 0x007c
+#define HC_SIMA_HTX0TBLRCa 0x007d
+#define HC_SIMA_HTX0TBLRCb 0x007e
+#define HC_SIMA_HTX0TBLRCc 0x007f
+#define HC_SIMA_HTX0TBLRCbias 0x0080
+#define HC_SIMA_HTX0TBLRAa 0x0081
+#define HC_SIMA_HTX0TBLRFog 0x0082
+#define HC_SIMA_HTX0BumpM00 0x0083
+#define HC_SIMA_HTX0BumpM01 0x0084
+#define HC_SIMA_HTX0BumpM10 0x0085
+#define HC_SIMA_HTX0BumpM11 0x0086
+#define HC_SIMA_HTX0LScale 0x0087
+/*---- end of texture 0 setting ---- 0x008f
+ */
+#define HC_SIMA_TX0TX1_OFF 0x0050
+/*---- start of texture 1 setting ----
+ */
+#define HC_SIMA_HTX1L0BasL (HC_SIMA_HTX0L0BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L1BasL (HC_SIMA_HTX0L1BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L2BasL (HC_SIMA_HTX0L2BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L3BasL (HC_SIMA_HTX0L3BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L4BasL (HC_SIMA_HTX0L4BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L5BasL (HC_SIMA_HTX0L5BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L6BasL (HC_SIMA_HTX0L6BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L7BasL (HC_SIMA_HTX0L7BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L8BasL (HC_SIMA_HTX0L8BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L9BasL (HC_SIMA_HTX0L9BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LaBasL (HC_SIMA_HTX0LaBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LbBasL (HC_SIMA_HTX0LbBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LcBasL (HC_SIMA_HTX0LcBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LdBasL (HC_SIMA_HTX0LdBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LeBasL (HC_SIMA_HTX0LeBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LfBasL (HC_SIMA_HTX0LfBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L10BasL (HC_SIMA_HTX0L10BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L11BasL (HC_SIMA_HTX0L11BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L012BasH (HC_SIMA_HTX0L012BasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L345BasH (HC_SIMA_HTX0L345BasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L678BasH (HC_SIMA_HTX0L678BasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L9abBasH (HC_SIMA_HTX0L9abBasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LcdeBasH (HC_SIMA_HTX0LcdeBasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1Lf1011BasH (HC_SIMA_HTX0Lf1011BasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L0Pit (HC_SIMA_HTX0L0Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L1Pit (HC_SIMA_HTX0L1Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L2Pit (HC_SIMA_HTX0L2Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L3Pit (HC_SIMA_HTX0L3Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L4Pit (HC_SIMA_HTX0L4Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L5Pit (HC_SIMA_HTX0L5Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L6Pit (HC_SIMA_HTX0L6Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L7Pit (HC_SIMA_HTX0L7Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L8Pit (HC_SIMA_HTX0L8Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L9Pit (HC_SIMA_HTX0L9Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LaPit (HC_SIMA_HTX0LaPit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LbPit (HC_SIMA_HTX0LbPit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LcPit (HC_SIMA_HTX0LcPit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LdPit (HC_SIMA_HTX0LdPit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LePit (HC_SIMA_HTX0LePit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LfPit (HC_SIMA_HTX0LfPit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L10Pit (HC_SIMA_HTX0L10Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L11Pit (HC_SIMA_HTX0L11Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L0_5WE (HC_SIMA_HTX0L0_5WE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L6_bWE (HC_SIMA_HTX0L6_bWE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1Lc_11WE (HC_SIMA_HTX0Lc_11WE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L0_5HE (HC_SIMA_HTX0L0_5HE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L6_bHE (HC_SIMA_HTX0L6_bHE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1Lc_11HE (HC_SIMA_HTX0Lc_11HE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L0OS (HC_SIMA_HTX0L0OS + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TB (HC_SIMA_HTX0TB + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1MPMD (HC_SIMA_HTX0MPMD + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1CLODu (HC_SIMA_HTX0CLODu + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1FM (HC_SIMA_HTX0FM + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TRCH (HC_SIMA_HTX0TRCH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TRCL (HC_SIMA_HTX0TRCL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBC (HC_SIMA_HTX0TBC + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TRAH (HC_SIMA_HTX0TRAH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LTC (HC_SIMA_HTX0LTC + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LTA (HC_SIMA_HTX0LTA + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLCsat (HC_SIMA_HTX0TBLCsat + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLCop (HC_SIMA_HTX0TBLCop + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLMPfog (HC_SIMA_HTX0TBLMPfog + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLAsat (HC_SIMA_HTX0TBLAsat + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRCa (HC_SIMA_HTX0TBLRCa + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRCb (HC_SIMA_HTX0TBLRCb + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRCc (HC_SIMA_HTX0TBLRCc + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRCbias (HC_SIMA_HTX0TBLRCbias + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRAa (HC_SIMA_HTX0TBLRAa + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRFog (HC_SIMA_HTX0TBLRFog + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1BumpM00 (HC_SIMA_HTX0BumpM00 + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1BumpM01 (HC_SIMA_HTX0BumpM01 + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1BumpM10 (HC_SIMA_HTX0BumpM10 + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1BumpM11 (HC_SIMA_HTX0BumpM11 + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LScale (HC_SIMA_HTX0LScale + HC_SIMA_TX0TX1_OFF)
+/*---- end of texture 1 setting ---- 0xaf
+ */
+#define HC_SIMA_HTXSMD 0x00b0
+#define HC_SIMA_HenFIFOAT 0x00b1
+#define HC_SIMA_HFBDrawFirst 0x00b2
+#define HC_SIMA_HFBBasL 0x00b3
+#define HC_SIMA_HTArbRCM 0x00b4
+#define HC_SIMA_HTArbRZ 0x00b5
+#define HC_SIMA_HTArbWZ 0x00b6
+#define HC_SIMA_HTArbRTX 0x00b7
+#define HC_SIMA_HTArbRCW 0x00b8
+#define HC_SIMA_HTArbE2 0x00b9
+#define HC_SIMA_HGEMITout 0x00ba
+#define HC_SIMA_HFthRTXD 0x00bb
+#define HC_SIMA_HFthRTXA 0x00bc
+/* Define the texture palette 0
+ */
+#define HC_SIMA_HTP0 0x0100
+#define HC_SIMA_HTP1 0x0200
+#define HC_SIMA_FOGTABLE 0x0300
+#define HC_SIMA_STIPPLE 0x0400
+#define HC_SIMA_HE3Fire 0x0440
+#define HC_SIMA_TRANS_SET 0x0441
+#define HC_SIMA_HREngSt 0x0442
+#define HC_SIMA_HRFIFOempty 0x0443
+#define HC_SIMA_HRFIFOfull 0x0444
+#define HC_SIMA_HRErr 0x0445
+#define HC_SIMA_FIFOstatus 0x0446
+
+/******************************************************************************
+** Define the AGP command header.
+******************************************************************************/
+#define HC_ACMD_MASK 0xfe000000
+#define HC_ACMD_SUB_MASK 0x0c000000
+#define HC_ACMD_HCmdA 0xee000000
+#define HC_ACMD_HCmdB 0xec000000
+#define HC_ACMD_HCmdC 0xea000000
+#define HC_ACMD_H1 0xf0000000
+#define HC_ACMD_H2 0xf2000000
+#define HC_ACMD_H3 0xf4000000
+#define HC_ACMD_H4 0xf6000000
+
+#define HC_ACMD_H1IO_MASK 0x000001ff
+#define HC_ACMD_H2IO1_MASK 0x001ff000
+#define HC_ACMD_H2IO2_MASK 0x000001ff
+#define HC_ACMD_H2IO1_SHIFT 12
+#define HC_ACMD_H2IO2_SHIFT 0
+#define HC_ACMD_H3IO_MASK 0x000001ff
+#define HC_ACMD_H3COUNT_MASK 0x01fff000
+#define HC_ACMD_H3COUNT_SHIFT 12
+#define HC_ACMD_H4ID_MASK 0x000001ff
+#define HC_ACMD_H4COUNT_MASK 0x01fffe00
+#define HC_ACMD_H4COUNT_SHIFT 9
+
+/********************************************************************************
+** Define Header
+********************************************************************************/
+#define HC_HEADER2 0xF210F110
+
+/********************************************************************************
+** Define Dummy Value
+********************************************************************************/
+#define HC_DUMMY 0xCCCCCCCC
+/********************************************************************************
+** Define for DMA use
+********************************************************************************/
+#define HALCYON_HEADER2 0XF210F110
+#define HALCYON_FIRECMD 0XEE100000
+#define HALCYON_FIREMASK 0XFFF00000
+#define HALCYON_CMDB 0XEC000000
+#define HALCYON_CMDBMASK 0XFFFE0000
+#define HALCYON_SUB_ADDR0 0X00000000
+#define HALCYON_HEADER1MASK 0XFFFFFC00
+#define HALCYON_HEADER1 0XF0000000
+#define HC_SubA_HAGPBstL 0x0060
+#define HC_SubA_HAGPBendL 0x0061
+#define HC_SubA_HAGPCMNT 0x0062
+#define HC_SubA_HAGPBpL 0x0063
+#define HC_SubA_HAGPBpH 0x0064
+#define HC_HAGPCMNT_MASK 0x00800000
+#define HC_HCmdErrClr_MASK 0x00400000
+#define HC_HAGPBendH_MASK 0x0000ff00
+#define HC_HAGPBstH_MASK 0x000000ff
+#define HC_HAGPBendH_SHIFT 8
+#define HC_HAGPBstH_SHIFT 0
+#define HC_HAGPBpL_MASK 0x00fffffc
+#define HC_HAGPBpID_MASK 0x00000003
+#define HC_HAGPBpID_PAUSE 0x00000000
+#define HC_HAGPBpID_JUMP 0x00000001
+#define HC_HAGPBpID_STOP 0x00000002
+#define HC_HAGPBpH_MASK 0x00ffffff
+
+
+#define VIA_VIDEO_HEADER5 0xFE040000
+#define VIA_VIDEO_HEADER6 0xFE050000
+#define VIA_VIDEO_HEADER7 0xFE060000
+#define VIA_VIDEOMASK 0xFFFF0000
+#endif
diff --git a/src/via_accel.c b/src/via_accel.c
new file mode 100644
index 000000000000..e4cf82e52021
--- /dev/null
+++ b/src/via_accel.c
@@ -0,0 +1,2652 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ * Copyright 2006 Thomas Hellstrom. 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.
+ *
+ * Mostly rewritten and modified for EXA support by Thomas Hellstrom 2005.
+ */
+
+/*************************************************************************
+ *
+ * File: via_accel.c
+ * Content: 2D acceleration function for VIA/S3G UniChrome
+ *
+ ************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <X11/Xarch.h>
+#include "xaalocal.h"
+#include "xaarop.h"
+#include "miline.h"
+
+#include "via.h"
+#include "via_driver.h"
+#include "via_regs.h"
+#include "via_id.h"
+#include "via_dmabuffer.h"
+
+#ifdef X_HAVE_XAAGETROP
+#define VIAACCELPATTERNROP(vRop) (XAAGetPatternROP(vRop) << 24)
+#define VIAACCELCOPYROP(vRop) (XAAGetCopyROP(vRop) << 24)
+#else
+#define VIAACCELPATTERNROP(vRop) (XAAPatternROP[vRop] << 24)
+#define VIAACCELCOPYROP(vRop) (XAACopyROP[vRop] << 24)
+#endif
+
+/*
+ * Use PCI MMIO to flush the command buffer when AGP DMA is not available.
+ */
+
+static void
+viaDumpDMA(ViaCommandBuffer * buf)
+{
+ register CARD32 *bp = buf->buf;
+ CARD32 *endp = bp + buf->pos;
+
+ while (bp != endp) {
+ if (((bp - buf->buf) & 3) == 0) {
+ ErrorF("\n %04lx: ", (unsigned long)(bp - buf->buf));
+ }
+ ErrorF("0x%08x ", (unsigned)*bp++);
+ }
+ ErrorF("\n");
+}
+
+void
+viaFlushPCI(ViaCommandBuffer * buf)
+{
+ register CARD32 *bp = buf->buf;
+ CARD32 transSetting;
+ CARD32 *endp = bp + buf->pos;
+ unsigned loop = 0;
+ register CARD32 offset = 0;
+ register CARD32 value;
+ VIAPtr pVia = VIAPTR(buf->pScrn);
+
+ while (bp < endp) {
+ if (*bp == HALCYON_HEADER2) {
+ if (++bp == endp)
+ return;
+ VIASETREG(VIA_REG_TRANSET, transSetting = *bp++);
+ while (bp < endp) {
+ if ((transSetting != HC_ParaType_CmdVdata) &&
+ ((*bp == HALCYON_HEADER2)
+ || (*bp & HALCYON_HEADER1MASK) == HALCYON_HEADER1))
+ break;
+ VIASETREG(VIA_REG_TRANSPACE, *bp++);
+ }
+ } else if ((*bp & HALCYON_HEADER1MASK) == HALCYON_HEADER1) {
+
+ while (bp < endp) {
+ if (*bp == HALCYON_HEADER2)
+ break;
+ if (offset == 0) {
+ /*
+ * Not doing this wait will probably stall the processor
+ * for an unacceptable amount of time in VIASETREG while
+ * other high priority interrupts may be pending.
+ */
+ 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)) ;
+ }
+ offset = (*bp++ & 0x0FFFFFFF) << 2;
+ value = *bp++;
+ VIASETREG(offset, value);
+ }
+ } else {
+ ErrorF("Command stream parser error.\n");
+ }
+ }
+ buf->pos = 0;
+ buf->mode = 0;
+ buf->has3dState = FALSE;
+}
+
+/*
+ * Flush the command buffer using DRM. If in PCI mode, we can bypass DRM,
+ * but not for command buffers that contains 3D engine state, since then
+ * the DRM command verifier will lose track of the 3D engine state.
+ */
+
+#ifdef XF86DRI
+static void
+viaFlushDRIEnabled(ViaCommandBuffer * cb)
+{
+ ScrnInfoPtr pScrn = cb->pScrn;
+ VIAPtr pVia = VIAPTR(pScrn);
+ char *tmp = (char *)cb->buf;
+ int tmpSize;
+ drm_via_cmdbuffer_t b;
+
+ /*
+ * Align command buffer end for AGP DMA.
+ */
+
+ OUT_RING_H1(0x2f8, 0x67676767);
+ if (pVia->agpDMA && cb->mode == 2 && cb->rindex != HC_ParaType_CmdVdata
+ && (cb->pos & 1)) {
+ OUT_RING(HC_DUMMY);
+ }
+
+ tmpSize = cb->pos * sizeof(CARD32);
+ if (pVia->agpDMA || (pVia->directRenderingEnabled && cb->has3dState)) {
+ cb->mode = 0;
+ cb->has3dState = FALSE;
+ while (tmpSize > 0) {
+ b.size = (tmpSize > VIA_DMASIZE) ? VIA_DMASIZE : tmpSize;
+ tmpSize -= b.size;
+ b.buf = tmp;
+ tmp += b.size;
+ if (drmCommandWrite(pVia->drmFD,
+ ((pVia->agpDMA) ? DRM_VIA_CMDBUFFER : DRM_VIA_PCICMD), &b,
+ sizeof(b))) {
+ ErrorF("DRM command buffer submission failed.\n");
+ viaDumpDMA(cb);
+ return;
+ }
+ }
+ cb->pos = 0;
+ } else {
+ viaFlushPCI(cb);
+ }
+}
+#endif
+
+/*
+ * Initialize a command buffer. Some fields are currently not used since they
+ * are intended for Unichrome Pro group A video commands.
+ */
+
+int
+viaSetupCBuffer(ScrnInfoPtr pScrn, ViaCommandBuffer * buf, unsigned size)
+{
+#ifdef XF86DRI
+ VIAPtr pVia = VIAPTR(pScrn);
+#endif
+
+ buf->pScrn = pScrn;
+ buf->bufSize = ((size == 0) ? VIA_DMASIZE : size) >> 2;
+ buf->buf = (CARD32 *) xcalloc(buf->bufSize, sizeof(CARD32));
+ if (!buf->buf)
+ return BadAlloc;
+ buf->waitFlags = 0;
+ buf->pos = 0;
+ buf->mode = 0;
+ buf->header_start = 0;
+ buf->rindex = 0;
+ buf->has3dState = FALSE;
+ buf->flushFunc = viaFlushPCI;
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled) {
+ buf->flushFunc = viaFlushDRIEnabled;
+ }
+#endif
+ return Success;
+}
+
+/*
+ * Free resources associated with a command buffer.
+ */
+
+void
+viaTearDownCBuffer(ViaCommandBuffer * buf)
+{
+ if (buf && buf->buf)
+ xfree(buf->buf);
+ buf->buf = NULL;
+}
+
+/*
+ * Leftover from VIA's code.
+ */
+
+static void
+viaInitAgp(VIAPtr pVia)
+{
+ VIASETREG(VIA_REG_TRANSET, 0x00100000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x00000000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x00333004);
+ VIASETREG(VIA_REG_TRANSPACE, 0x60000000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x61000000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x62000000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x63000000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x64000000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x7D000000);
+
+ VIASETREG(VIA_REG_TRANSET, 0xfe020000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x00000000);
+}
+
+/*
+ * Initialize the virtual command queue. Header 2 commands can be put
+ * in this queue for buffering. AFAIK it doesn't handle Header 1
+ * commands, which is really a pity, since it has to be idled before
+ * issuing a H1 command.
+ */
+
+static void
+viaEnableVQ(VIAPtr pVia)
+{
+ CARD32
+ vqStartAddr = pVia->VQStart,
+ vqEndAddr = pVia->VQEnd,
+ vqStartL = 0x50000000 | (vqStartAddr & 0xFFFFFF),
+ vqEndL = 0x51000000 | (vqEndAddr & 0xFFFFFF),
+ vqStartEndH = 0x52000000 | ((vqStartAddr & 0xFF000000) >> 24) |
+ ((vqEndAddr & 0xFF000000) >> 16),
+ vqLen = 0x53000000 | (VIA_VQ_SIZE >> 3);
+
+ VIASETREG(VIA_REG_TRANSET, 0x00fe0000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x080003fe);
+ VIASETREG(VIA_REG_TRANSPACE, 0x0a00027c);
+ VIASETREG(VIA_REG_TRANSPACE, 0x0b000260);
+ VIASETREG(VIA_REG_TRANSPACE, 0x0c000274);
+ VIASETREG(VIA_REG_TRANSPACE, 0x0d000264);
+ VIASETREG(VIA_REG_TRANSPACE, 0x0e000000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x0f000020);
+ VIASETREG(VIA_REG_TRANSPACE, 0x1000027e);
+ VIASETREG(VIA_REG_TRANSPACE, 0x110002fe);
+ VIASETREG(VIA_REG_TRANSPACE, 0x200f0060);
+
+ VIASETREG(VIA_REG_TRANSPACE, 0x00000006);
+ VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f);
+ VIASETREG(VIA_REG_TRANSPACE, 0x44000000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x45080c04);
+ VIASETREG(VIA_REG_TRANSPACE, 0x46800408);
+ VIASETREG(VIA_REG_TRANSPACE, vqStartEndH);
+ VIASETREG(VIA_REG_TRANSPACE, vqStartL);
+ VIASETREG(VIA_REG_TRANSPACE, vqEndL);
+ VIASETREG(VIA_REG_TRANSPACE, vqLen);
+}
+
+/*
+ * Disable the virtual command queue.
+ */
+
+void
+viaDisableVQ(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ VIASETREG(VIA_REG_TRANSET, 0x00fe0000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x00000004);
+ VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f);
+ VIASETREG(VIA_REG_TRANSPACE, 0x44000000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x45080c04);
+ VIASETREG(VIA_REG_TRANSPACE, 0x46800408);
+}
+
+/*
+ * Update our 2D state (TwoDContext) with a new mode.
+ */
+
+static Bool
+viaAccelSetMode(int bpp, ViaTwodContext * tdc)
+{
+ switch (bpp) {
+ case 16:
+ tdc->mode = VIA_GEM_16bpp;
+ tdc->bytesPPShift = 1;
+ return TRUE;
+ case 32:
+ tdc->mode = VIA_GEM_32bpp;
+ tdc->bytesPPShift = 2;
+ return TRUE;
+ case 8:
+ tdc->mode = VIA_GEM_8bpp;
+ tdc->bytesPPShift = 0;
+ return TRUE;
+ default:
+ tdc->bytesPPShift = 0;
+ return FALSE;
+ }
+}
+
+/*
+ * Initialize the 2D engine and set the 2D context mode to the
+ * current screen depth. Also enable the virtual queue.
+ */
+
+void
+viaInitialize2DEngine(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+ int i;
+
+ /*
+ * init 2D engine regs to reset 2D engine
+ */
+
+ for (i = 0x04; i < 0x44; i += 4) {
+ VIASETREG(i, 0x0);
+ }
+
+ viaInitAgp(pVia);
+
+ if (pVia->VQStart != 0) {
+ viaEnableVQ(pVia);
+ } else {
+ viaDisableVQ(pScrn);
+ }
+
+ viaAccelSetMode(pScrn->bitsPerPixel, tdc);
+}
+
+/*
+ * Wait for acceleration engines idle. An expensive way to sync.
+ */
+
+void
+viaAccelSync(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ int loop = 0;
+
+ mem_barrier();
+
+ while (!(VIAGETREG(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY)
+ && (loop++ < MAXLOOP)) ;
+
+ while ((VIAGETREG(VIA_REG_STATUS) &
+ (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) &&
+ (loop++ < MAXLOOP)) ;
+}
+
+/*
+ * Set 2D state clipping on.
+ */
+
+static void
+viaSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+
+ tdc->clipping = TRUE;
+ tdc->clipX1 = (x1 & 0xFFFF);
+ tdc->clipY1 = y1;
+ tdc->clipX2 = (x2 & 0xFFFF);
+ tdc->clipY2 = y2;
+}
+
+/*
+ * Set 2D state clipping off.
+ */
+
+static void
+viaDisableClipping(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+
+ tdc->clipping = FALSE;
+}
+
+/*
+ * 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)
+{
+ 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);
+ } else {
+ tdc->cmd &= ~VIA_GEC_CLIP_ENABLE;
+ }
+ return refY;
+
+}
+
+/*
+ * Emit a solid blit operation to the command buffer.
+ */
+
+static void
+viaAccelSolidHelper(ViaCommandBuffer * cb, int x, int y, int w, int h,
+ unsigned fbBase, CARD32 mode, unsigned pitch, CARD32 fg, CARD32 cmd)
+{
+ 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);
+}
+
+/*
+ * Check if we can use a planeMask and update the 2D context accordingly.
+ */
+
+static Bool
+viaAccelPlaneMaskHelper(ViaTwodContext * tdc, CARD32 planeMask)
+{
+ CARD32 modeMask = (1 << ((1 << tdc->bytesPPShift) << 3)) - 1;
+ CARD32 curMask = 0x00000000;
+ CARD32 curByteMask;
+ int i;
+
+ if ((planeMask & modeMask) != modeMask) {
+
+ /*
+ * Masking doesn't work in 8bpp.
+ */
+
+ if (modeMask == 0xFF) {
+ tdc->keyControl &= 0x0FFFFFFF;
+ return FALSE;
+ }
+
+ /*
+ * Translate the bit planemask to a byte planemask.
+ */
+
+ for (i = 0; i < (1 << tdc->bytesPPShift); ++i) {
+ curByteMask = (0xFF << (i << 3));
+
+ if ((planeMask & curByteMask) == 0) {
+ curMask |= (1 << i);
+ } else if ((planeMask & curByteMask) != curByteMask) {
+ tdc->keyControl &= 0x0FFFFFFF;
+ return FALSE;
+ }
+ }
+ ErrorF("DEBUG: planeMask 0x%08x, curMask 0%02x\n",
+ (unsigned)planeMask, (unsigned)curMask);
+
+ tdc->keyControl = (tdc->keyControl & 0x0FFFFFFF) | (curMask << 28);
+ }
+
+ return TRUE;
+}
+
+/*
+ * Emit transparency state and color to the command buffer.
+ */
+
+static void
+viaAccelTransparentHelper(ViaTwodContext * tdc, ViaCommandBuffer * cb,
+ CARD32 keyControl, CARD32 transColor, Bool usePlaneMask)
+{
+ tdc->keyControl &= ((usePlaneMask) ? 0xF0000000 : 0x00000000);
+ tdc->keyControl |= (keyControl & 0x0FFFFFFF);
+ BEGIN_RING(4);
+ OUT_RING_H1(VIA_REG_KEYCONTROL, tdc->keyControl);
+ if (keyControl) {
+ OUT_RING_H1(VIA_REG_SRCCOLORKEY, transColor);
+ }
+}
+
+/*
+ * Emit a copy blit operation to the command buffer.
+ */
+
+static void
+viaAccelCopyHelper(ViaCommandBuffer * cb, int xs, int ys, int xd, int yd,
+ int w, int h, unsigned srcFbBase, unsigned dstFbBase, CARD32 mode,
+ unsigned srcPitch, unsigned dstPitch, CARD32 cmd)
+{
+ if (cmd & VIA_GEC_DECY) {
+ ys += h - 1;
+ yd += h - 1;
+ }
+
+ if (cmd & VIA_GEC_DECX) {
+ xs += w - 1;
+ xd += w - 1;
+ }
+
+ 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);
+}
+
+/*
+ * XAA functions. Note that the 2047 line blitter limit has been worked around by adding
+ * min(y1, y2, clipping y) * stride to the offset (which is recommended by VIA docs).
+ * The y values (including clipping) must be subtracted accordingly.
+ */
+
+static void
+viaSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
+ unsigned planemask, int trans_color)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ CARD32 cmd;
+ ViaTwodContext *tdc = &pVia->td;
+
+ RING_VARS;
+
+ cmd = VIA_GEC_BLT | VIAACCELCOPYROP(rop);
+
+ if (xdir < 0)
+ cmd |= VIA_GEC_DECX;
+
+ if (ydir < 0)
+ cmd |= VIA_GEC_DECY;
+
+ tdc->cmd = cmd;
+ viaAccelTransparentHelper(tdc, cb, (trans_color != -1) ? 0x4000 : 0x0000,
+ trans_color, FALSE);
+}
+
+static void
+viaSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+ int sub;
+
+ RING_VARS;
+
+ if (!w || !h)
+ return;
+
+ sub = viaAccelClippingHelper(cb, y2, tdc);
+ viaAccelCopyHelper(cb, 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);
+ ADVANCE_RING;
+}
+
+/*
+ * SetupForSolidFill is also called to set up for lines.
+ */
+
+static void
+viaSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned planemask)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+
+ RING_VARS;
+
+ tdc->cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(rop);
+ tdc->fgColor = color;
+ viaAccelTransparentHelper(tdc, cb, 0x00, 0x00, FALSE);
+}
+
+static void
+viaSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+ int sub;
+
+ RING_VARS;
+
+ if (!w || !h)
+ return;
+
+ sub = viaAccelClippingHelper(cb, y, tdc);
+ viaAccelSolidHelper(cb, x, y - sub, w, h,
+ pScrn->fbOffset + pVia->Bpl * sub, tdc->mode, pVia->Bpl, tdc->fgColor,
+ tdc->cmd);
+ ADVANCE_RING;
+}
+
+/*
+ * Original VIA comment:
+ * The meaning of the two pattern paremeters to Setup & Subsequent for
+ * Mono8x8Patterns varies depending on the flag bits. We specify
+ * HW_PROGRAMMED_BITS, which means our hardware can handle 8x8 patterns
+ * without caching in the frame buffer. Thus, Setup gets the pattern bits.
+ * There is no way with BCI to rotate an 8x8 pattern, so we do NOT specify
+ * HW_PROGRAMMED_ORIGIN. XAA wil rotate it for us and pass the rotated
+ * pattern to both Setup and Subsequent. If we DID specify PROGRAMMED_ORIGIN,
+ * then Setup would get the unrotated pattern, and Subsequent gets the
+ * origin values.
+ */
+
+static void
+viaSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattern0, int pattern1,
+ int fg, int bg, int rop, unsigned planemask)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ int cmd;
+ ViaTwodContext *tdc = &pVia->td;
+
+ RING_VARS;
+
+ cmd = VIA_GEC_BLT | VIA_GEC_PAT_REG | VIA_GEC_PAT_MONO |
+ VIAACCELPATTERNROP(rop);
+
+ if (bg == -1) {
+ cmd |= VIA_GEC_MPAT_TRANS;
+ }
+
+ tdc->cmd = cmd;
+ tdc->fgColor = fg;
+ tdc->bgColor = bg;
+ tdc->pattern0 = pattern0;
+ tdc->pattern1 = pattern1;
+ viaAccelTransparentHelper(tdc, cb, 0x00, 0x00, FALSE);
+
+}
+
+static void
+viaSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patOffx,
+ int patOffy, int x, int y, int w, int h)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ CARD32 patOffset;
+ ViaTwodContext *tdc = &pVia->td;
+ CARD32 dstBase;
+ int sub;
+
+ RING_VARS;
+
+ if (!w || !h)
+ return;
+
+ patOffset = ((patOffy & 0x7) << 29) | ((patOffx & 0x7) << 26);
+ sub = viaAccelClippingHelper(cb, y, tdc);
+ 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);
+ ADVANCE_RING;
+}
+
+static void
+viaSetupForColor8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny,
+ int rop, unsigned planemask, int trans_color)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+
+ RING_VARS;
+
+ tdc->cmd = VIA_GEC_BLT | VIAACCELPATTERNROP(rop);
+ tdc->patternAddr = (patternx * pVia->Bpp + patterny * pVia->Bpl);
+ viaAccelTransparentHelper(tdc, cb, (trans_color != -1) ? 0x4000 : 0x0000,
+ trans_color, FALSE);
+}
+
+static void
+viaSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, int patOffx,
+ int patOffy, int x, int y, int w, int h)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ CARD32 patAddr;
+ ViaTwodContext *tdc = &pVia->td;
+ CARD32 dstBase;
+ int sub;
+
+ RING_VARS;
+
+ if (!w || !h)
+ return;
+
+ patAddr = (tdc->patternAddr >> 3) |
+ ((patOffy & 0x7) << 29) | ((patOffx & 0x7) << 26);
+ sub = viaAccelClippingHelper(cb, y, tdc);
+ 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);
+ ADVANCE_RING;
+}
+
+/*
+ * CPU to screen functions cannot use AGP due to complicated syncing. Therefore the
+ * command buffer is flushed before new command emissions and viaFluchPCI is called
+ * explicitly instead of cb->flushFunc() at the end of each CPU to screen function.
+ * Should the buffer get completely filled again by a CPU to screen command emission,
+ * a horrible error will occur.
+ */
+
+static void
+viaSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg,
+ int rop, unsigned planemask)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ int cmd;
+ ViaTwodContext *tdc = &pVia->td;
+
+ RING_VARS;
+
+ cmd = VIA_GEC_BLT | VIA_GEC_SRC_SYS | VIA_GEC_SRC_MONO |
+ VIAACCELCOPYROP(rop);
+
+ if (bg == -1) {
+ cmd |= VIA_GEC_MSRC_TRANS;
+ }
+
+ tdc->cmd = cmd;
+ tdc->fgColor = fg;
+ tdc->bgColor = bg;
+
+ ADVANCE_RING;
+
+ viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, FALSE);
+}
+
+static void
+viaSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h, int skipleft)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+ int sub;
+
+ RING_VARS;
+
+ if (skipleft) {
+ viaSetClippingRectangle(pScrn, (x + skipleft), y, (x + w - 1),
+ (y + h - 1));
+ }
+
+ sub = viaAccelClippingHelper(cb, y, tdc);
+ 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,
+ pScrn->fbOffset + sub * pVia->Bpl, tdc->mode, pVia->Bpl, pVia->Bpl,
+ tdc->cmd);
+
+ viaFlushPCI(cb);
+ viaDisableClipping(pScrn);
+}
+
+static void
+viaSetupForImageWrite(ScrnInfoPtr pScrn, int rop, unsigned planemask,
+ int trans_color, int bpp, int depth)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+
+ RING_VARS;
+
+ tdc->cmd = VIA_GEC_BLT | VIA_GEC_SRC_SYS | VIAACCELCOPYROP(rop);
+ ADVANCE_RING;
+ viaAccelTransparentHelper(tdc, cb, (trans_color != -1) ? 0x4000 : 0x0000,
+ trans_color, FALSE);
+}
+
+static void
+viaSubsequentImageWriteRect(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ int skipleft)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+ int sub;
+
+ RING_VARS;
+
+ if (skipleft) {
+ viaSetClippingRectangle(pScrn, (x + skipleft), y, (x + w - 1),
+ (y + h - 1));
+ }
+
+ sub = viaAccelClippingHelper(cb, y, tdc);
+ viaAccelCopyHelper(cb, 0, 0, x, y - sub, w, h, 0,
+ pScrn->fbOffset + pVia->Bpl * sub, tdc->mode, pVia->Bpl, pVia->Bpl,
+ tdc->cmd);
+
+ viaFlushPCI(cb);
+ viaDisableClipping(pScrn);
+}
+
+static void
+viaSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+
+ RING_VARS;
+
+ viaAccelTransparentHelper(tdc, cb, 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);
+}
+
+static void
+viaSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int flags)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ int dx, dy, cmd, tmp, error = 1;
+ ViaTwodContext *tdc = &pVia->td;
+ CARD32 dstBase;
+ int sub;
+
+ RING_VARS;
+
+ sub = viaAccelClippingHelper(cb, (y1 < y2) ? y1 : y2, tdc);
+ cmd = tdc->cmd | VIA_GEC_LINE;
+
+ dx = x2 - x1;
+ if (dx < 0) {
+ dx = -dx;
+ cmd |= VIA_GEC_DECX; /* line will be drawn from right */
+ error = 0;
+ }
+
+ dy = y2 - y1;
+ if (dy < 0) {
+ dy = -dy;
+ cmd |= VIA_GEC_DECY; /* line will be drawn from bottom */
+ }
+
+ if (dy > dx) {
+ tmp = dy;
+ dy = dx;
+ dx = tmp; /* Swap 'dx' and 'dy' */
+ cmd |= VIA_GEC_Y_MAJOR; /* Y major line */
+ }
+
+ if (flags & OMIT_LAST) {
+ cmd |= VIA_GEC_LASTPIXEL_OFF;
+ }
+
+ dstBase = pScrn->fbOffset + sub * pVia->Bpl;
+ y1 -= sub;
+ 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));
+
+ /*
+ * major = 2*dmaj, minor = 2*dmin, err = -dmaj - ((bias >> octant) & 1)
+ * K1 = 2*dmin K2 = 2*(dmin - dmax)
+ * Error Term = (StartX<EndX) ? (2*dmin - dmax - 1) : (2*(dmin - dmax))
+ */
+
+ OUT_RING_H1(VIA_REG_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,
+ (((dy << 1) - dx - error) & 0x3fff) | ((tdc->dashed) ? 0xFF0000 : 0));
+ OUT_RING_H1(VIA_REG_GECMD, cmd);
+ ADVANCE_RING;
+
+}
+
+static void
+viaSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len,
+ int dir)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+ CARD32 dstBase;
+ int sub;
+
+ RING_VARS;
+
+ sub = viaAccelClippingHelper(cb, y, tdc);
+ 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));
+
+ 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);
+ } 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);
+ }
+ ADVANCE_RING;
+}
+
+static void
+viaSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int length, unsigned char *pattern)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ int cmd;
+ CARD32 pat = *(CARD32 *) pattern;
+ ViaTwodContext *tdc = &pVia->td;
+
+ RING_VARS;
+
+ viaAccelTransparentHelper(tdc, cb, 0x00, 0x00, FALSE);
+ cmd = VIA_GEC_LINE | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(rop);
+
+ if (bg == -1) {
+ cmd |= VIA_GEC_MPAT_TRANS;
+ }
+
+ tdc->cmd = cmd;
+ tdc->fgColor = fg;
+ tdc->bgColor = bg;
+
+ switch (length) {
+ case 2:
+ pat |= pat << 2; /* fall through */
+ case 4:
+ pat |= pat << 4; /* fall through */
+ case 8:
+ pat |= pat << 8; /* fall through */
+ case 16:
+ pat |= pat << 16;
+ }
+
+ tdc->pattern0 = pat;
+ 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);
+}
+
+static void
+viaSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, int x2,
+ int y2, int flags, int phase)
+{
+ viaSubsequentSolidTwoPointLine(pScrn, x1, y1, x2, y2, flags);
+}
+
+static int
+viaInitXAA(ScreenPtr pScreen)
+{
+
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ XAAInfoRecPtr xaaptr;
+
+ /*
+ * General acceleration flags
+ */
+
+ if (!(xaaptr = pVia->AccelInfoRec = XAACreateInfoRec()))
+ return FALSE;
+
+ xaaptr->Flags = PIXMAP_CACHE |
+ OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER | MICROSOFT_ZERO_LINE_BIAS | 0;
+
+ if (pScrn->bitsPerPixel == 8)
+ xaaptr->CachePixelGranularity = 128;
+
+ xaaptr->SetClippingRectangle = viaSetClippingRectangle;
+ xaaptr->DisableClipping = viaDisableClipping;
+ xaaptr->ClippingFlags = HARDWARE_CLIP_SOLID_FILL |
+ HARDWARE_CLIP_SOLID_LINE |
+ HARDWARE_CLIP_DASHED_LINE |
+ HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
+ HARDWARE_CLIP_MONO_8x8_FILL |
+ HARDWARE_CLIP_COLOR_8x8_FILL |
+ HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND | 0;
+
+ xaaptr->Sync = viaAccelSync;
+
+ xaaptr->SetupForScreenToScreenCopy = viaSetupForScreenToScreenCopy;
+ xaaptr->SubsequentScreenToScreenCopy = viaSubsequentScreenToScreenCopy;
+ xaaptr->ScreenToScreenCopyFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE;
+
+ xaaptr->SetupForSolidFill = viaSetupForSolidFill;
+ xaaptr->SubsequentSolidFillRect = viaSubsequentSolidFillRect;
+ xaaptr->SolidFillFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE;
+
+ xaaptr->SetupForMono8x8PatternFill = viaSetupForMono8x8PatternFill;
+ xaaptr->SubsequentMono8x8PatternFillRect =
+ viaSubsequentMono8x8PatternFillRect;
+ xaaptr->Mono8x8PatternFillFlags = NO_PLANEMASK |
+ HARDWARE_PATTERN_PROGRAMMED_BITS |
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN | BIT_ORDER_IN_BYTE_MSBFIRST | 0;
+
+ xaaptr->SetupForColor8x8PatternFill = viaSetupForColor8x8PatternFill;
+ xaaptr->SubsequentColor8x8PatternFillRect =
+ viaSubsequentColor8x8PatternFillRect;
+ xaaptr->Color8x8PatternFillFlags = NO_PLANEMASK |
+ NO_TRANSPARENCY |
+ HARDWARE_PATTERN_PROGRAMMED_BITS |
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN | 0;
+
+ xaaptr->SetupForSolidLine = viaSetupForSolidLine;
+ xaaptr->SubsequentSolidTwoPointLine = viaSubsequentSolidTwoPointLine;
+ xaaptr->SubsequentSolidHorVertLine = viaSubsequentSolidHorVertLine;
+ xaaptr->SolidBresenhamLineErrorTermBits = 14;
+ xaaptr->SolidLineFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE;
+
+ xaaptr->SetupForDashedLine = viaSetupForDashedLine;
+ xaaptr->SubsequentDashedTwoPointLine = viaSubsequentDashedTwoPointLine;
+ xaaptr->DashPatternMaxLength = 8;
+ xaaptr->DashedLineFlags = NO_PLANEMASK |
+ ROP_NEEDS_SOURCE |
+ LINE_PATTERN_POWER_OF_2_ONLY | LINE_PATTERN_MSBFIRST_LSBJUSTIFIED | 0;
+
+ xaaptr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK |
+ CPU_TRANSFER_PAD_DWORD |
+ SCANLINE_PAD_DWORD |
+ BIT_ORDER_IN_BYTE_MSBFIRST |
+ LEFT_EDGE_CLIPPING | ROP_NEEDS_SOURCE | 0;
+
+ xaaptr->SetupForScanlineCPUToScreenColorExpandFill =
+ viaSetupForCPUToScreenColorExpandFill;
+ xaaptr->SubsequentScanlineCPUToScreenColorExpandFill =
+ viaSubsequentScanlineCPUToScreenColorExpandFill;
+ xaaptr->ColorExpandBase = pVia->BltBase;
+ xaaptr->ColorExpandRange = VIA_MMIO_BLTSIZE;
+
+ xaaptr->ImageWriteFlags = NO_PLANEMASK |
+ CPU_TRANSFER_PAD_DWORD |
+ SCANLINE_PAD_DWORD |
+ BIT_ORDER_IN_BYTE_MSBFIRST |
+ LEFT_EDGE_CLIPPING | ROP_NEEDS_SOURCE | SYNC_AFTER_IMAGE_WRITE | 0;
+
+ /*
+ * Most Unichromes are much faster using processor to
+ * framebuffer writes than using the 2D engine for this.
+ * test with x11perf -shmput500!
+ */
+
+ if (pVia->Chipset != VIA_K8M800)
+ xaaptr->ImageWriteFlags |= NO_GXCOPY;
+
+ xaaptr->SetupForImageWrite = viaSetupForImageWrite;
+ xaaptr->SubsequentImageWriteRect = viaSubsequentImageWriteRect;
+ xaaptr->ImageWriteBase = pVia->BltBase;
+ xaaptr->ImageWriteRange = VIA_MMIO_BLTSIZE;
+
+ return XAAInit(pScreen, xaaptr);
+
+}
+
+/*
+ * Mark Sync using the 2D blitter for AGP. NoOp for PCI.
+ * In the future one could even launch a NULL PCI DMA command
+ * to have an interrupt generated, provided it is possible to
+ * write to the PCI DMA engines from the AGP command stream.
+ */
+
+int
+viaAccelMarkSync(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ RING_VARS;
+
+ ++pVia->curMarker;
+
+ /*
+ * Wrap around without possibly affecting the int sign bit.
+ */
+
+ pVia->curMarker &= 0x7FFFFFFF;
+
+ if (pVia->agpDMA) {
+ BEGIN_RING(2);
+ OUT_RING_H1(VIA_REG_KEYCONTROL, 0x00);
+ viaAccelSolidHelper(cb, 0, 0, 1, 1, pVia->markerOffset,
+ VIA_GEM_32bpp, 4, pVia->curMarker,
+ (0xF0 << 24) | VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT);
+ ADVANCE_RING;
+ }
+ return pVia->curMarker;
+}
+
+/*
+ * Wait for the value to get blitted, or in the PCI case for engine idle.
+ */
+
+void
+viaAccelWaitMarker(ScreenPtr pScreen, int marker)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ CARD32 uMarker = marker;
+
+ if (pVia->agpDMA) {
+ while ((pVia->lastMarkerRead - uMarker) > (1 << 24))
+ pVia->lastMarkerRead = *pVia->markerBuf;
+ } else {
+ viaAccelSync(pScrn);
+ }
+}
+
+#ifdef VIA_HAVE_EXA
+
+/*
+ * Exa functions. It is assumed that EXA does not exceed the blitter limits.
+ */
+
+static Bool
+viaExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+
+ RING_VARS;
+
+ if (exaGetPixmapPitch(pPixmap) & 7)
+ return FALSE;
+
+ if (!viaAccelSetMode(pPixmap->drawable.depth, tdc))
+ return FALSE;
+
+ if (!viaAccelPlaneMaskHelper(tdc, planeMask))
+ return FALSE;
+ viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, TRUE);
+
+ tdc->cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(alu);
+
+ tdc->fgColor = fg;
+
+ return TRUE;
+}
+
+static void
+viaExaSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+ CARD32 dstPitch, dstOffset;
+
+ RING_VARS;
+
+ int w = x2 - x1, h = y2 - y1;
+
+ dstPitch = exaGetPixmapPitch(pPixmap);
+ dstOffset = exaGetPixmapOffset(pPixmap);
+
+ viaAccelSolidHelper(cb, x1, y1, w, h, dstOffset,
+ tdc->mode, dstPitch, tdc->fgColor, tdc->cmd);
+ ADVANCE_RING;
+}
+
+static void
+viaExaDoneSolidCopy(PixmapPtr pPixmap)
+{
+}
+
+static Bool
+viaExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
+ int ydir, int alu, Pixel planeMask)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+
+ RING_VARS;
+
+ if (pSrcPixmap->drawable.bitsPerPixel !=
+ pDstPixmap->drawable.bitsPerPixel)
+ return FALSE;
+
+ if ((tdc->srcPitch = exaGetPixmapPitch(pSrcPixmap)) & 3)
+ return FALSE;
+
+ if (exaGetPixmapPitch(pDstPixmap) & 7)
+ return FALSE;
+
+ tdc->srcOffset = exaGetPixmapOffset(pSrcPixmap);
+
+ tdc->cmd = VIA_GEC_BLT | VIAACCELCOPYROP(alu);
+ if (xdir < 0)
+ tdc->cmd |= VIA_GEC_DECX;
+ if (ydir < 0)
+ tdc->cmd |= VIA_GEC_DECY;
+
+ if (!viaAccelSetMode(pDstPixmap->drawable.bitsPerPixel, tdc))
+ return FALSE;
+
+ if (!viaAccelPlaneMaskHelper(tdc, planeMask))
+ return FALSE;
+ viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, TRUE);
+
+ return TRUE;
+}
+
+static void
+viaExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
+ int width, int height)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+ CARD32 srcOffset = tdc->srcOffset;
+ CARD32 dstOffset = exaGetPixmapOffset(pDstPixmap);
+
+ RING_VARS;
+
+ if (!width || !height)
+ return;
+
+ viaAccelCopyHelper(cb, srcX, srcY, dstX, dstY, width, height,
+ srcOffset, dstOffset, tdc->mode, tdc->srcPitch,
+ exaGetPixmapPitch(pDstPixmap), tdc->cmd);
+ ADVANCE_RING;
+}
+
+#ifdef VIA_DEBUG_COMPOSITE
+static void
+viaExaCompositePictDesc(PicturePtr pict, char *string, int n)
+{
+ char format[20];
+ char size[20];
+
+ if (!pict) {
+ snprintf(string, n, "None");
+ return;
+ }
+
+ switch (pict->format) {
+ case PICT_x8r8g8b8:
+ snprintf(format, 20, "RGB8888");
+ break;
+ case PICT_a8r8g8b8:
+ snprintf(format, 20, "ARGB8888");
+ break;
+ case PICT_r5g6b5:
+ snprintf(format, 20, "RGB565 ");
+ break;
+ case PICT_x1r5g5b5:
+ snprintf(format, 20, "RGB555 ");
+ break;
+ case PICT_a8:
+ snprintf(format, 20, "A8 ");
+ break;
+ case PICT_a1:
+ snprintf(format, 20, "A1 ");
+ break;
+ default:
+ snprintf(format, 20, "0x%x", (int)pict->format);
+ break;
+ }
+
+ snprintf(size, 20, "%dx%d%s", pict->pDrawable->width,
+ pict->pDrawable->height, pict->repeat ? " R" : "");
+
+ snprintf(string, n, "0x%lx: fmt %s (%s)", (long)pict->pDrawable, format,
+ size);
+}
+
+static void
+viaExaPrintComposite(CARD8 op,
+ PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst)
+{
+ char sop[20];
+ char srcdesc[40], maskdesc[40], dstdesc[40];
+
+ switch (op) {
+ case PictOpSrc:
+ sprintf(sop, "Src");
+ break;
+ case PictOpOver:
+ sprintf(sop, "Over");
+ break;
+ default:
+ sprintf(sop, "0x%x", (int)op);
+ break;
+ }
+
+ viaExaCompositePictDesc(pSrc, srcdesc, 40);
+ viaExaCompositePictDesc(pMask, maskdesc, 40);
+ viaExaCompositePictDesc(pDst, dstdesc, 40);
+
+ ErrorF("Composite fallback: op %s, \n"
+ " src %s, \n"
+ " mask %s, \n"
+ " dst %s, \n", sop, srcdesc, maskdesc, dstdesc);
+}
+#endif /* VIA_DEBUG_COMPOSITE */
+
+/*
+ * Helper for bitdepth expansion.
+ */
+
+static CARD32
+viaBitExpandHelper(CARD32 component, CARD32 bits)
+{
+ CARD32 tmp, mask;
+
+ mask = (1 << (8 - bits)) - 1;
+ tmp = component << (8 - bits);
+ return ((component & 1) ? tmp | mask : tmp);
+}
+
+/*
+ * Extract the components from a pixel of format "format" to an
+ * argb8888 pixel. This is used to extract data from one-pixel repeat pixmaps.
+ * Assumes little endian.
+ */
+
+static void
+viaPixelARGB8888(unsigned format, void *pixelP, CARD32 * argb8888)
+{
+ CARD32 bits, shift, pixel, bpp;
+
+ bpp = PICT_FORMAT_BPP(format);
+
+ if (bpp <= 8) {
+ pixel = *((CARD8 *) pixelP);
+ } else if (bpp <= 16) {
+ pixel = *((CARD16 *) pixelP);
+ } else {
+ pixel = *((CARD32 *) pixelP);
+ }
+
+ switch (PICT_FORMAT_TYPE(format)) {
+ case PICT_TYPE_A:
+ bits = PICT_FORMAT_A(format);
+ *argb8888 = viaBitExpandHelper(pixel & ((1 << bits) - 1), bits) << 24;
+ return;
+ case PICT_TYPE_ARGB:
+ shift = 0;
+ bits = PICT_FORMAT_B(format);
+ *argb8888 = viaBitExpandHelper(pixel & ((1 << bits) - 1), bits);
+ shift += bits;
+ bits = PICT_FORMAT_G(format);
+ *argb8888 |=
+ viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1),
+ bits) << 8;
+ shift += bits;
+ bits = PICT_FORMAT_R(format);
+ *argb8888 |=
+ viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1),
+ bits) << 16;
+ shift += bits;
+ bits = PICT_FORMAT_A(format);
+ *argb8888 |= ((bits) ?
+ viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1),
+ bits) : 0xFF) << 24;
+ return;
+ case PICT_TYPE_ABGR:
+ shift = 0;
+ bits = PICT_FORMAT_B(format);
+ *argb8888 = viaBitExpandHelper(pixel & ((1 << bits) - 1), bits) << 16;
+ shift += bits;
+ bits = PICT_FORMAT_G(format);
+ *argb8888 |=
+ viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1),
+ bits) << 8;
+ shift += bits;
+ bits = PICT_FORMAT_R(format);
+ *argb8888 |=
+ viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1), bits);
+ shift += bits;
+ bits = PICT_FORMAT_A(format);
+ *argb8888 |= ((bits) ?
+ viaBitExpandHelper((pixel >> shift) & ((1 << bits) - 1),
+ bits) : 0xFF) << 24;
+ return;
+ default:
+ break;
+ }
+ return;
+}
+
+/*
+ * Check if the above function will work.
+ */
+
+static Bool
+viaExpandablePixel(int format)
+{
+ int formatType = PICT_FORMAT_TYPE(format);
+
+ return (formatType == PICT_TYPE_A ||
+ formatType == PICT_TYPE_ABGR || formatType == PICT_TYPE_ARGB);
+}
+
+/*
+ * Check if we need to force upload of the whole 3D state (when other
+ * clients or subsystems have touched the 3D engine). Also tell DRI
+ * clients and subsystems that we have touched the 3D engine.
+ */
+
+static Bool
+viaCheckUpload(ScrnInfoPtr pScrn, Via3DState * v3d)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ Bool forceUpload;
+
+ forceUpload = (pVia->lastToUpload != v3d);
+ pVia->lastToUpload = v3d;
+
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled) {
+ volatile drm_via_sarea_t *saPriv = (drm_via_sarea_t *)
+ DRIGetSAREAPrivate(pScrn->pScreen);
+ int myContext = DRIGetContext(pScrn->pScreen);
+
+ forceUpload = forceUpload || (saPriv->ctxOwner != myContext);
+ saPriv->ctxOwner = myContext;
+ }
+#endif
+ return forceUpload;
+}
+
+static Bool
+viaOrder(CARD32 val, CARD32 * shift)
+{
+ *shift = 0;
+
+ while (val > (1 << *shift))
+ (*shift)++;
+ return (val == (1 << *shift));
+}
+
+#ifdef XF86DRI
+
+static int
+viaAccelDMADownload(ScrnInfoPtr pScrn, unsigned long fbOffset,
+ unsigned srcPitch, unsigned char *dst,
+ unsigned dstPitch, unsigned w, unsigned h)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ drm_via_dmablit_t blit[2], *curBlit;
+ unsigned char *sysAligned = NULL;
+ Bool doSync[2], useBounceBuffer;
+ unsigned pitch, numLines[2];
+ int curBuf, err, i, ret, blitHeight;
+
+ ret = 0;
+
+ useBounceBuffer = (((unsigned long)dst & 15) || (dstPitch & 15));
+ doSync[0] = FALSE;
+ doSync[1] = FALSE;
+ curBuf = 1;
+ blitHeight = h;
+ pitch = dstPitch;
+ if (useBounceBuffer) {
+ pitch = ALIGN_TO(dstPitch, 16);
+ blitHeight = VIA_DMA_DL_SIZE / pitch;
+ }
+
+ while (doSync[0] || doSync[1] || h != 0) {
+ curBuf = 1 - curBuf;
+ curBlit = &blit[curBuf];
+ if (doSync[curBuf]) {
+
+ do {
+ err = drmCommandWrite(pVia->drmFD, DRM_VIA_BLIT_SYNC,
+ &curBlit->sync, sizeof(curBlit->sync));
+ } while (err == -EAGAIN);
+
+ if (err)
+ return err;
+
+ doSync[curBuf] = FALSE;
+ if (useBounceBuffer) {
+ for (i = 0; i < numLines[curBuf]; ++i) {
+ memcpy(dst, curBlit->mem_addr, w);
+ dst += dstPitch;
+ curBlit->mem_addr += pitch;
+ }
+ }
+ }
+
+ if (h == 0)
+ continue;
+
+ curBlit->num_lines = (h > blitHeight) ? blitHeight : h;
+ h -= curBlit->num_lines;
+ numLines[curBuf] = curBlit->num_lines;
+
+ sysAligned =
+ (unsigned char *)pVia->dBounce + (curBuf * VIA_DMA_DL_SIZE);
+ sysAligned = (unsigned char *)
+ ALIGN_TO((unsigned long)sysAligned, 16);
+
+ curBlit->mem_addr = (useBounceBuffer) ? sysAligned : dst;
+ curBlit->line_length = w;
+ curBlit->mem_stride = pitch;
+ curBlit->fb_addr = fbOffset;
+ curBlit->fb_stride = srcPitch;
+ curBlit->to_fb = 0;
+ fbOffset += curBlit->num_lines * srcPitch;
+
+ do {
+ err = drmCommandWriteRead(pVia->drmFD, DRM_VIA_DMA_BLIT, curBlit,
+ sizeof(*curBlit));
+ } while (err == -EAGAIN);
+
+ if (err) {
+ ret = err;
+ h = 0;
+ continue;
+ }
+
+ doSync[curBuf] = TRUE;
+ }
+
+ return ret;
+}
+
+/*
+ * Use PCI DMA if we can. If the system alignments don't match, we're using
+ * an aligned bounce buffer for pipelined PCI DMA and memcpy.
+ * Throughput for large transfers is around 65 MB/s.
+ */
+
+static Bool
+viaExaDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h,
+ char *dst, int dst_pitch)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ unsigned srcPitch = exaGetPixmapPitch(pSrc);
+ unsigned wBytes = (pSrc->drawable.bitsPerPixel * w + 7) >> 3;
+ unsigned srcOffset;
+ char *bounceAligned = NULL;
+ unsigned totSize;
+
+ if (!w || !h)
+ return TRUE;
+
+ srcOffset = x * pSrc->drawable.bitsPerPixel;
+ if (srcOffset & 3)
+ return FALSE;
+ srcOffset = exaGetPixmapOffset(pSrc) + y * srcPitch + (srcOffset >> 3);
+
+ totSize = wBytes * h;
+
+ exaWaitSync(pScrn->pScreen);
+ if (totSize < VIA_MIN_DOWNLOAD) {
+ bounceAligned = (char *)pVia->FBBase + srcOffset;
+ while (h--) {
+ memcpy(dst, bounceAligned, wBytes);
+ dst += dst_pitch;
+ bounceAligned += srcPitch;
+ }
+ return TRUE;
+ }
+
+ if (!pVia->directRenderingEnabled)
+ return FALSE;
+
+ if ((srcPitch & 3) || (srcOffset & 3)) {
+ ErrorF("VIA EXA download src_pitch misaligned\n");
+ return FALSE;
+ }
+
+ if (viaAccelDMADownload(pScrn, srcOffset, srcPitch, (unsigned char *)dst,
+ dst_pitch, wBytes, h))
+ return FALSE;
+
+ return TRUE;
+}
+
+/*
+ * Upload to framebuffer memory using memcpy to AGP pipelined with a
+ * 3D engine texture operation from AGP to framebuffer. The AGP buffers (2)
+ * should be kept rather small for optimal pipelining.
+ */
+
+static Bool
+viaExaTexUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src,
+ int src_pitch)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ unsigned dstPitch = exaGetPixmapPitch(pDst);
+ unsigned wBytes = (w * pDst->drawable.bitsPerPixel + 7) >> 3;
+ unsigned dstOffset;
+ CARD32 texWidth, texHeight, texPitch;
+ int format;
+ char *dst;
+ int i, sync[2], yOffs, bufH, bufOffs, height;
+ Bool buf;
+ Via3DState *v3d = &pVia->v3d;
+
+ if (!w || !h)
+ return TRUE;
+
+ if (wBytes * h < VIA_MIN_TEX_UPLOAD) {
+ dstOffset = x * pDst->drawable.bitsPerPixel;
+ if (dstOffset & 3)
+ return FALSE;
+ dst =
+ (char *)pVia->FBBase + (exaGetPixmapOffset(pDst) + y * dstPitch +
+ (dstOffset >> 3));
+ exaWaitSync(pScrn->pScreen);
+
+ while (h--) {
+ memcpy(dst, src, wBytes);
+ dst += dstPitch;
+ src += src_pitch;
+ }
+ return TRUE;
+ }
+
+ if (!pVia->texAddr)
+ return FALSE;
+
+ switch (pDst->drawable.bitsPerPixel) {
+ case 32:
+ format = PICT_a8r8g8b8;
+ break;
+ case 16:
+ format = PICT_r5g6b5;
+ break;
+ default:
+ return FALSE;
+ }
+
+ dstOffset = exaGetPixmapOffset(pDst);
+
+ if (pVia->nPOT[0]) {
+ texPitch = ALIGN_TO(wBytes, 32);
+ height = VIA_AGP_UPL_SIZE / texPitch;
+ } else {
+ viaOrder(wBytes, &texPitch);
+ if (texPitch < 3)
+ texPitch = 3;
+ height = VIA_AGP_UPL_SIZE >> texPitch;
+ texPitch = 1 << texPitch;
+ }
+
+ if (height > 1024)
+ height = 1024;
+ viaOrder(w, &texWidth);
+ texWidth = 1 << texWidth;
+
+ texHeight = height << 1;
+ bufOffs = texPitch * height;
+
+ v3d->setDestination(v3d, dstOffset, dstPitch, format);
+ v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, 0x000000FF, 0x00);
+ v3d->setFlags(v3d, 1, TRUE, TRUE, FALSE);
+ if (!v3d->setTexture(v3d, 0, pVia->texOffset + pVia->agpAddr, texPitch,
+ pVia->nPOT[0], texWidth, texHeight, format, via_single,
+ via_single, via_src, TRUE))
+ return FALSE;
+
+ v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d));
+ v3d->emitClipRect(v3d, &pVia->cb, 0, 0, pDst->drawable.width,
+ pDst->drawable.height);
+
+ buf = 1;
+ yOffs = 0;
+ sync[0] = -1;
+ sync[1] = -1;
+
+ while (h) {
+ buf = (buf) ? 0 : 1;
+ bufH = (h > height) ? height : h;
+ dst = pVia->texAddr + ((buf) ? bufOffs : 0);
+
+ if (sync[buf] >= 0)
+ viaAccelWaitMarker(pScrn->pScreen, sync[buf]);
+
+ for (i = 0; i < bufH; ++i) {
+ memcpy(dst, src, wBytes);
+ dst += texPitch;
+ src += src_pitch;
+ }
+
+ v3d->emitQuad(v3d, &pVia->cb, x, y + yOffs, 0, (buf) ? height : 0, 0,
+ 0, w, bufH);
+
+ sync[buf] = viaAccelMarkSync(pScrn->pScreen);
+
+ h -= bufH;
+ yOffs += bufH;
+ }
+
+ if (sync[buf] >= 0)
+ viaAccelWaitMarker(pScrn->pScreen, sync[buf]);
+
+ return TRUE;
+}
+
+/*
+ * I'm not sure PCI DMA upload is necessary. Seems buggy for widths below 65,
+ * and I'd guess that in most situations CPU direct writes are faster.
+ * Use DMA only when alignments match. At least it saves some CPU cycles.
+ */
+
+static Bool
+viaExaUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src,
+ int src_pitch)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ drm_via_dmablit_t blit;
+ unsigned dstPitch = exaGetPixmapPitch(pDst);
+ unsigned wBytes = (w * pDst->drawable.bitsPerPixel + 7) >> 3;
+ unsigned dstOffset;
+ char *dst;
+ int err;
+
+ dstOffset = x * pDst->drawable.bitsPerPixel;
+ if (dstOffset & 3)
+ return FALSE;
+ dstOffset = exaGetPixmapOffset(pDst) + y * dstPitch + (dstOffset >> 3);
+
+ if (wBytes * h < VIA_MIN_UPLOAD || wBytes < 65) {
+ dst = (char *)pVia->FBBase + dstOffset;
+
+ exaWaitSync(pScrn->pScreen);
+ while (h--) {
+ memcpy(dst, src, wBytes);
+ dst += dstPitch;
+ src += src_pitch;
+ }
+ return TRUE;
+ }
+
+ if (!pVia->directRenderingEnabled)
+ return FALSE;
+
+ if (((unsigned long)src & 15) || (src_pitch & 15))
+ return FALSE;
+
+ if ((dstPitch & 3) || (dstOffset & 3))
+ return FALSE;
+
+ blit.line_length = wBytes;
+ blit.num_lines = h;
+ blit.fb_addr = dstOffset;
+ blit.fb_stride = dstPitch;
+ blit.mem_addr = (unsigned char *)src;
+ blit.mem_stride = src_pitch;
+ blit.to_fb = 1;
+
+ exaWaitSync(pScrn->pScreen);
+ while (-EAGAIN == (err =
+ drmCommandWriteRead(pVia->drmFD, DRM_VIA_DMA_BLIT, &blit,
+ sizeof(blit)))) ;
+ if (err < 0)
+ return FALSE;
+
+ while (-EAGAIN == (err = drmCommandWrite(pVia->drmFD, DRM_VIA_BLIT_SYNC,
+ &blit.sync, sizeof(blit.sync)))) ;
+ return (err == 0);
+}
+
+#endif /* XF86DRI */
+
+static Bool
+viaExaUploadToScratch(PixmapPtr pSrc, PixmapPtr pDst)
+{
+
+ ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ char *src, *dst;
+ unsigned w, wBytes, srcPitch, h;
+ CARD32 dstPitch;
+
+ if (!pVia->scratchAddr)
+ return FALSE;
+
+ *pDst = *pSrc;
+ w = pSrc->drawable.width;
+ h = pSrc->drawable.height;
+ wBytes = (w * pSrc->drawable.bitsPerPixel + 7) >> 3;
+
+ viaOrder(wBytes, &dstPitch);
+ dstPitch = 1 << dstPitch;
+ if (dstPitch < 8)
+ dstPitch = 8;
+ if (dstPitch * h > pVia->exaScratchSize * 1024) {
+ ErrorF("EXA UploadToScratch Failed %u %u %u %u\n",
+ dstPitch, h, dstPitch * h, pVia->exaScratchSize * 1024);
+ return FALSE;
+ }
+
+ pDst->devKind = dstPitch;
+ pDst->devPrivate.ptr = dst = pVia->scratchAddr;
+ src = pSrc->devPrivate.ptr;
+ srcPitch = exaGetPixmapPitch(pSrc);
+
+ /*
+ * Copying to AGP needs not be HW accelerated.
+ * If scratch is in FB, we are without DRI and HW accel.
+ */
+
+ viaAccelSync(pScrn);
+
+ while (h--) {
+ memcpy(dst, src, wBytes);
+ dst += dstPitch;
+ src += srcPitch;
+ }
+
+ return TRUE;
+}
+
+static Bool
+viaExaCheckComposite(int op, PicturePtr pSrcPicture,
+ PicturePtr pMaskPicture, PicturePtr pDstPicture)
+{
+
+ ScrnInfoPtr pScrn = xf86Screens[pDstPicture->pDrawable->pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ Via3DState *v3d = &pVia->v3d;
+
+ /*
+ * Reject small composites early. They are done much faster in software.
+ */
+
+ if (!pSrcPicture->repeat &&
+ pSrcPicture->pDrawable->width *
+ pSrcPicture->pDrawable->height < VIA_MIN_COMPOSITE)
+ return FALSE;
+
+ if (pMaskPicture &&
+ !pMaskPicture->repeat &&
+ pMaskPicture->pDrawable->width *
+ pMaskPicture->pDrawable->height < VIA_MIN_COMPOSITE)
+ return FALSE;
+
+ if (pMaskPicture && pMaskPicture->componentAlpha) {
+#ifdef VIA_DEBUG_COMPOSITE
+ ErrorF("Component Alpha operation\n");
+#endif
+ return FALSE;
+ }
+
+ if (!v3d->opSupported(op)) {
+#ifdef VIA_DEBUG_COMPOSITE
+#warning Composite verbose debug turned on.
+ ErrorF("Operator not supported\n");
+ viaExaPrintComposite(op, pSrcPicture, pMaskPicture, pDstPicture);
+#endif
+ return FALSE;
+ }
+
+ /*
+ * FIXME: A8 destination formats are currently not supported and do not
+ * seem supported by the hardware, although there are some leftover
+ * register settings apparent in the via_3d_reg.h file. We need to fix this
+ * (if important), by using component ARGB8888 operations with bitmask.
+ */
+
+ if (!v3d->dstSupported(pDstPicture->format)) {
+#ifdef VIA_DEBUG_COMPOSITE
+ ErrorF("Destination format not supported:\n");
+ viaExaPrintComposite(op, pSrcPicture, pMaskPicture, pDstPicture);
+#endif
+ return FALSE;
+ }
+
+ if (v3d->texSupported(pSrcPicture->format)) {
+ if (pMaskPicture && (PICT_FORMAT_A(pMaskPicture->format) == 0 ||
+ !v3d->texSupported(pMaskPicture->format))) {
+#ifdef VIA_DEBUG_COMPOSITE
+ ErrorF("Mask format not supported:\n");
+ viaExaPrintComposite(op, pSrcPicture, pMaskPicture, pDstPicture);
+#endif
+ return FALSE;
+ }
+ return TRUE;
+ }
+#ifdef VIA_DEBUG_COMPOSITE
+ ErrorF("Src format not supported:\n");
+ viaExaPrintComposite(op, pSrcPicture, pMaskPicture, pDstPicture);
+#endif
+ return FALSE;
+}
+
+static Bool
+viaIsAGP(VIAPtr pVia, PixmapPtr pPix, unsigned long *offset)
+{
+#ifdef XF86DRI
+ unsigned long offs;
+
+ if (pVia->directRenderingEnabled && !pVia->IsPCI) {
+ offs = (unsigned long)pPix->devPrivate.ptr -
+ (unsigned long)pVia->agpMappedAddr;
+
+ if ((offs - pVia->scratchOffset) < pVia->agpSize) {
+ *offset = offs + pVia->agpAddr;
+ return TRUE;
+ }
+ }
+#endif
+ return FALSE;
+}
+
+static Bool
+viaIsOffscreen(VIAPtr pVia, PixmapPtr pPix)
+{
+ return ((unsigned long)pPix->devPrivate.ptr -
+ (unsigned long)pVia->FBBase) < pVia->videoRambytes;
+}
+
+static Bool
+viaExaPrepareComposite(int op, PicturePtr pSrcPicture,
+ PicturePtr pMaskPicture, PicturePtr pDstPicture,
+ PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
+{
+ CARD32 height, width;
+ ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ Via3DState *v3d = &pVia->v3d;
+ int curTex = 0;
+ ViaTexBlendingModes srcMode;
+ Bool isAGP;
+ unsigned long offset;
+
+ v3d->setDestination(v3d, exaGetPixmapOffset(pDst),
+ exaGetPixmapPitch(pDst), pDstPicture->format);
+ v3d->setCompositeOperator(v3d, op);
+ v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, 0x000000FF, 0xFF);
+
+ viaOrder(pSrc->drawable.width, &width);
+ viaOrder(pSrc->drawable.height, &height);
+
+ /*
+ * For one-pixel repeat mask pictures we avoid using multitexturing by
+ * modifying the src's texture blending equation and feed the pixel
+ * value as a constant alpha for the src's texture. Multitexturing on the
+ * unichromes seems somewhat slow, so this speeds up translucent windows.
+ */
+
+ srcMode = via_src;
+ pVia->maskP = NULL;
+ if (pMaskPicture &&
+ (pMaskPicture->pDrawable->height == 1) &&
+ (pMaskPicture->pDrawable->width == 1) &&
+ pMaskPicture->repeat && viaExpandablePixel(pMaskPicture->format)) {
+ pVia->maskP = pMask->devPrivate.ptr;
+ pVia->maskFormat = pMaskPicture->format;
+ pVia->componentAlpha = pMaskPicture->componentAlpha;
+ srcMode =
+ (pMaskPicture->
+ componentAlpha) ? via_src_onepix_comp_mask : via_src_onepix_mask;
+ }
+
+ /*
+ * One-Pixel repeat src pictures go as solid color instead of textures.
+ * Speeds up window shadows.
+ */
+
+ pVia->srcP = NULL;
+ if (pSrcPicture &&
+ (pSrcPicture->pDrawable->height == 1) &&
+ (pSrcPicture->pDrawable->width == 1) &&
+ pSrcPicture->repeat && viaExpandablePixel(pSrcPicture->format)) {
+ pVia->srcP = pSrc->devPrivate.ptr;
+ pVia->srcFormat = pSrcPicture->format;
+ }
+
+ /*
+ * Exa should be smart enough to eliminate this IN operation.
+ */
+
+ if (pVia->srcP && pVia->maskP) {
+ ErrorF
+ ("Bad one-pixel IN composite operation. EXA needs to be smarter.\n");
+ return FALSE;
+ }
+
+ if (!pVia->srcP) {
+ offset = exaGetPixmapOffset(pSrc);
+ isAGP = viaIsAGP(pVia, pSrc, &offset);
+ if (!isAGP && !viaIsOffscreen(pVia, pSrc))
+ return FALSE;
+ if (!v3d->setTexture(v3d, curTex, offset,
+ exaGetPixmapPitch(pSrc), pVia->nPOT[curTex], 1 << width,
+ 1 << height, pSrcPicture->format, via_repeat, via_repeat,
+ srcMode, isAGP)) {
+ return FALSE;
+ }
+ curTex++;
+ }
+
+ if (pMaskPicture && !pVia->maskP) {
+ offset = exaGetPixmapOffset(pMask);
+ isAGP = viaIsAGP(pVia, pMask, &offset);
+ if (!isAGP && !viaIsOffscreen(pVia, pMask))
+ return FALSE;
+ viaOrder(pMask->drawable.width, &width);
+ viaOrder(pMask->drawable.height, &height);
+ if (!v3d->setTexture(v3d, curTex, offset,
+ exaGetPixmapPitch(pMask), pVia->nPOT[curTex], 1 << width,
+ 1 << height, pMaskPicture->format, via_repeat, via_repeat,
+ (pMaskPicture->componentAlpha) ? via_comp_mask : via_mask,
+ isAGP)) {
+ return FALSE;
+ }
+ curTex++;
+ }
+
+ v3d->setFlags(v3d, curTex, FALSE, TRUE, TRUE);
+ v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d));
+ v3d->emitClipRect(v3d, &pVia->cb, 0, 0, pDst->drawable.width,
+ pDst->drawable.height);
+
+ return TRUE;
+}
+
+static void
+viaExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
+ int dstX, int dstY, int width, int height)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ Via3DState *v3d = &pVia->v3d;
+ CARD32 col;
+
+ if (pVia->maskP) {
+ viaPixelARGB8888(pVia->maskFormat, pVia->maskP, &col);
+ v3d->setTexBlendCol(v3d, 0, pVia->componentAlpha, col);
+ }
+ if (pVia->srcP) {
+ viaPixelARGB8888(pVia->srcFormat, pVia->srcP, &col);
+ v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, col & 0x00FFFFFF, col >> 24);
+ srcX = maskX;
+ srcY = maskY;
+ }
+
+ if (pVia->maskP || pVia->srcP)
+ v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d));
+
+ v3d->emitQuad(v3d, &pVia->cb, dstX, dstY, srcX, srcY, maskX, maskY, width,
+ height);
+}
+
+#if (EXA_VERSION_MAJOR >= 2)
+
+static ExaDriverPtr
+viaInitExa(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ ExaDriverPtr pExa = exaDriverAlloc();
+
+ memset(pExa, 0, sizeof(*pExa));
+
+ if (!pExa)
+ return NULL;
+
+ pExa->exa_major = EXA_VERSION_MAJOR;
+ pExa->exa_minor = EXA_VERSION_MINOR;
+ pExa->memoryBase = pVia->FBBase;
+ pExa->memorySize = pVia->FBFreeEnd;
+ pExa->offScreenBase = pScrn->virtualY * pVia->Bpl;
+ pExa->pixmapOffsetAlign = 32;
+ pExa->pixmapPitchAlign = 16;
+ pExa->flags = EXA_OFFSCREEN_PIXMAPS |
+ (pVia->nPOT[1] ? 0 : EXA_OFFSCREEN_ALIGN_POT);
+ pExa->maxX = 2047;
+ pExa->maxY = 2047;
+ pExa->WaitMarker = viaAccelWaitMarker;
+ pExa->MarkSync = viaAccelMarkSync;
+ pExa->PrepareSolid = viaExaPrepareSolid;
+ pExa->Solid = viaExaSolid;
+ pExa->DoneSolid = viaExaDoneSolidCopy;
+ pExa->PrepareCopy = viaExaPrepareCopy;
+ pExa->Copy = viaExaCopy;
+ pExa->DoneCopy = viaExaDoneSolidCopy;
+
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled) {
+#ifdef linux
+ if ((pVia->drmVerMajor > 2) ||
+ ((pVia->drmVerMajor == 2) && (pVia->drmVerMinor >= 7))) {
+ pExa->DownloadFromScreen = viaExaDownloadFromScreen;
+ }
+#endif /* linux */
+ switch (pVia->Chipset) {
+ case VIA_K8M800:
+ case VIA_KM400:
+ pExa->UploadToScreen = viaExaTexUploadToScreen;
+ break;
+ default:
+ pExa->UploadToScreen = NULL;
+ break;
+ }
+ }
+#endif /* XF86DRI */
+
+ pExa->UploadToScratch = viaExaUploadToScratch;
+
+ if (!pVia->noComposite) {
+ pExa->CheckComposite = viaExaCheckComposite;
+ pExa->PrepareComposite = viaExaPrepareComposite;
+ pExa->Composite = viaExaComposite;
+ pExa->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;
+}
+
+#else
+
+/*
+ * Init 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 init function. Sets up offscreen memory disposition, initializes engines
+ * and acceleration method.
+ */
+
+Bool
+viaInitAccel(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ BoxRec AvailFBArea;
+ int maxY;
+ Bool nPOTSupported;
+
+ 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;
+ }
+
+ viaInitialize2DEngine(pScrn);
+
+ if (pVia->hwcursor) {
+ pVia->FBFreeEnd -= VIA_CURSOR_SIZE;
+ pVia->CursorStart = pVia->FBFreeEnd;
+ }
+
+ /*
+ * Sync marker space.
+ */
+
+ pVia->FBFreeEnd -= 32;
+ pVia->markerOffset = (pVia->FBFreeEnd + 31) & ~31;
+ pVia->markerBuf = (CARD32 *) ((char *)pVia->FBBase + pVia->markerOffset);
+ *pVia->markerBuf = 0;
+ pVia->curMarker = 0;
+ pVia->lastMarkerRead = 0;
+
+ /*
+ * nPOT textures. DRM versions below 2.11.0 don't allow them.
+ * Also some CLE266 hardware may not allow nPOT textures for
+ * texture engine 1. We need to figure that out.
+ */
+
+ nPOTSupported = TRUE;
+#ifdef XF86DRI
+ nPOTSupported = (!pVia->directRenderingEnabled) ||
+ (pVia->drmVerMajor > 2) ||
+ ((pVia->drmVerMajor == 2) && (pVia->drmVerMinor >= 11));
+#endif
+ pVia->nPOT[0] = nPOTSupported;
+ pVia->nPOT[1] = nPOTSupported;
+
+#ifdef VIA_HAVE_EXA
+#ifdef XF86DRI
+ pVia->texAddr = NULL;
+ pVia->dBounce = NULL;
+ pVia->scratchAddr = NULL;
+#endif /* XF86DRI */
+ if (pVia->useEXA) {
+ pVia->exaDriverPtr = viaInitExa(pScreen);
+ if (!pVia->exaDriverPtr) {
+
+ /*
+ * Docs recommend turning off also Xv here, but we handle this
+ * case with the old linear offscreen FB manager through
+ * VIAInitLinear.
+ */
+
+ pVia->NoAccel = TRUE;
+ return FALSE;
+ }
+
+ pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart) / 2;
+
+ if ((pVia->driSize > (pVia->maxDriSize * 1024))
+ && pVia->maxDriSize > 0)
+ pVia->driSize = pVia->maxDriSize * 1024;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[EXA] Enabled EXA acceleration.\n");
+ return TRUE;
+ }
+#endif /* VIA_HAVE_EXA */
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+
+ /*
+ * Memory distribution for XAA is tricky. We'd like to make the
+ * pixmap cache no larger than 3 x visible screen size, otherwise
+ * XAA may get slow for some undetermined reason.
+ */
+
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled) {
+ pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart) / 2;
+ maxY = pScrn->virtualY + (pVia->driSize / pVia->Bpl);
+ } else
+#endif
+ {
+ maxY = pVia->FBFreeEnd / pVia->Bpl;
+ }
+ if (maxY > 4 * pScrn->virtualY)
+ maxY = 4 * pScrn->virtualY;
+
+ pVia->FBFreeStart = (maxY + 1) * pVia->Bpl;
+
+ AvailFBArea.y2 = maxY;
+ xf86InitFBManager(pScreen, &AvailFBArea);
+ VIAInitLinear(pScreen);
+
+ pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart - pVia->Bpl);
+ if ((pVia->driSize > (pVia->maxDriSize * 1024)) && pVia->maxDriSize > 0)
+ pVia->driSize = pVia->maxDriSize * 1024;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %d lines for offscreen memory.\n",
+ AvailFBArea.y2 - pScrn->virtualY));
+
+ return viaInitXAA(pScreen);
+}
+
+/*
+ * Free the used acceleration resources.
+ */
+
+void
+viaExitAccel(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ viaAccelSync(pScrn);
+ viaTearDownCBuffer(&pVia->cb);
+
+#ifdef VIA_HAVE_EXA
+ if (pVia->useEXA) {
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled) {
+ if (pVia->texAddr) {
+ drmCommandWrite(pVia->drmFD, DRM_VIA_FREEMEM,
+ &pVia->texAGPBuffer, sizeof(drm_via_mem_t));
+ pVia->texAddr = NULL;
+ }
+ if (pVia->scratchAddr && !pVia->IsPCI &&
+ ((unsigned long)pVia->scratchAddr -
+ (unsigned long)pVia->agpMappedAddr ==
+ pVia->scratchOffset)) {
+ drmCommandWrite(pVia->drmFD, DRM_VIA_FREEMEM,
+ &pVia->scratchAGPBuffer, sizeof(drm_via_mem_t));
+ pVia->scratchAddr = NULL;
+ }
+ }
+ if (pVia->dBounce)
+ xfree(pVia->dBounce);
+#endif /* XF86DRI */
+ if (pVia->scratchAddr) {
+ exaOffscreenFree(pScreen, pVia->scratchFBBuffer);
+ pVia->scratchAddr = NULL;
+ }
+ if (pVia->exaDriverPtr) {
+ exaDriverFini(pScreen);
+ }
+ xfree(pVia->exaDriverPtr);
+ pVia->exaDriverPtr = NULL;
+ return;
+ }
+#endif /* VIA_HAVE_EXA */
+ if (pVia->AccelInfoRec) {
+ XAADestroyInfoRec(pVia->AccelInfoRec);
+ pVia->AccelInfoRec = NULL;
+ }
+}
+
+/*
+ * Allocate a command buffer and buffers for accelerated upload, download,
+ * and EXA scratch area. The scratch area resides primarily in AGP memory,
+ * but reverts to FB if AGP is not available.
+ */
+
+void
+viaFinishInitAccel(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+
+#ifdef VIA_HAVE_EXA
+#ifdef XF86DRI
+ int size, ret;
+
+ if (pVia->directRenderingEnabled && pVia->useEXA) {
+
+ pVia->dBounce = xcalloc(VIA_DMA_DL_SIZE * 2, 1);
+
+ 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;
+ pVia->texAGPBuffer.type = VIA_MEM_AGP;
+ ret =
+ drmCommandWriteRead(pVia->drmFD, DRM_VIA_ALLOCMEM,
+ &pVia->texAGPBuffer, sizeof(drm_via_mem_t));
+
+ if (ret || size != pVia->texAGPBuffer.size) {
+ pVia->texAGPBuffer.size = 0;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Allocated %u kiB of AGP memory for system to frame-buffer transfer.\n",
+ size / 1024);
+ pVia->texOffset = (pVia->texAGPBuffer.offset + 31) & ~31;
+ pVia->texAddr =
+ (char *)pVia->agpMappedAddr + pVia->texOffset;
+ }
+
+ }
+
+ size = pVia->exaScratchSize * 1024 + 32;
+ pVia->scratchAGPBuffer.context = 1;
+ pVia->scratchAGPBuffer.size = size;
+ pVia->scratchAGPBuffer.type = VIA_MEM_AGP;
+ ret =
+ drmCommandWriteRead(pVia->drmFD, DRM_VIA_ALLOCMEM,
+ &pVia->scratchAGPBuffer, sizeof(drm_via_mem_t));
+ if (ret || size != pVia->scratchAGPBuffer.size) {
+ pVia->scratchAGPBuffer.size = 0;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Allocated %u kiB of AGP memory for EXA scratch area.\n",
+ size / 1024);
+ pVia->scratchOffset =
+ (pVia->scratchAGPBuffer.offset + 31) & ~31;
+ pVia->scratchAddr =
+ (char *)pVia->agpMappedAddr + pVia->scratchOffset;
+ }
+
+ }
+ }
+#endif /* XF86DRI */
+ if (!pVia->scratchAddr && pVia->useEXA) {
+
+ pVia->scratchFBBuffer =
+ exaOffscreenAlloc(pScreen, pVia->exaScratchSize * 1024,
+ 32, TRUE, NULL, NULL);
+ if (pVia->scratchFBBuffer) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Allocated %u kiB of framebuffer memory for EXA scratch area.\n",
+ pVia->exaScratchSize);
+ pVia->scratchOffset = pVia->scratchFBBuffer->offset;
+ pVia->scratchAddr = (char *)pVia->FBBase + pVia->scratchOffset;
+ }
+
+ }
+#endif /* VIA_HAVE_EXA */
+ if (Success != viaSetupCBuffer(pScrn, &pVia->cb, 0)) {
+ pVia->NoAccel = TRUE;
+ viaExitAccel(pScreen);
+ return;
+ }
+}
+
+/*
+ * DGA accelerated functions go here and let them be independent of acceleration
+ * method.
+ */
+
+void
+viaAccelBlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, int w, int h,
+ int dstx, int dsty)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ ViaTwodContext *tdc = &pVia->td;
+ unsigned dstOffset = pScrn->fbOffset + dsty * pVia->Bpl;
+ unsigned srcOffset = pScrn->fbOffset + srcy * pVia->Bpl;
+
+ RING_VARS;
+
+ if (!w || !h)
+ return;
+
+ if (!pVia->NoAccel) {
+
+ int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
+ int ydir = (srcy < dsty) ? -1 : 1;
+ CARD32 cmd = VIA_GEC_BLT | VIAACCELCOPYROP(GXcopy);
+
+ if (xdir < 0)
+ cmd |= VIA_GEC_DECX;
+ if (ydir < 0)
+ cmd |= VIA_GEC_DECY;
+
+ viaAccelSetMode(pScrn->bitsPerPixel, tdc);
+ viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, FALSE);
+ viaAccelCopyHelper(cb, srcx, 0, dstx, 0, w, h, srcOffset, dstOffset,
+ tdc->mode, pVia->Bpl, pVia->Bpl, cmd);
+ pVia->accelMarker = viaAccelMarkSync(pScrn->pScreen);
+ ADVANCE_RING;
+ }
+}
+
+void
+viaAccelFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned long color)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ unsigned dstBase = pScrn->fbOffset + y * pVia->Bpl;
+ ViaTwodContext *tdc = &pVia->td;
+ CARD32 cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT |
+ VIAACCELPATTERNROP(GXcopy);
+ RING_VARS;
+
+ if (!w || !h)
+ return;
+
+ if (!pVia->NoAccel) {
+ viaAccelSetMode(pScrn->bitsPerPixel, tdc);
+ viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, FALSE);
+ viaAccelSolidHelper(cb, x, 0, w, h, dstBase, tdc->mode,
+ pVia->Bpl, color, cmd);
+ pVia->accelMarker = viaAccelMarkSync(pScrn->pScreen);
+ ADVANCE_RING;
+ }
+}
+
+void
+viaAccelFillPixmap(ScrnInfoPtr pScrn,
+ unsigned long offset,
+ unsigned long pitch,
+ int depth, int x, int y, int w, int h, unsigned long color)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ unsigned dstBase = offset + y * pitch;
+ ViaTwodContext *tdc = &pVia->td;
+ CARD32 cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT |
+ VIAACCELPATTERNROP(GXcopy);
+ RING_VARS;
+
+ if (!w || !h)
+ return;
+
+ if (!pVia->NoAccel) {
+ viaAccelSetMode(depth, tdc);
+ viaAccelTransparentHelper(tdc, cb, 0x0, 0x0, FALSE);
+ viaAccelSolidHelper(cb, x, 0, w, h, dstBase, tdc->mode,
+ pitch, color, cmd);
+ pVia->accelMarker = viaAccelMarkSync(pScrn->pScreen);
+ ADVANCE_RING;
+ }
+}
+
+void
+viaAccelSyncMarker(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ viaAccelWaitMarker(pScrn->pScreen, pVia->accelMarker);
+}
+
+void
+viaAccelTextureBlit(ScrnInfoPtr pScrn, unsigned long srcOffset,
+ unsigned srcPitch, unsigned w, unsigned h, unsigned srcX, unsigned srcY,
+ unsigned srcFormat, unsigned long dstOffset, unsigned dstPitch,
+ unsigned dstX, unsigned dstY, unsigned dstFormat, int rotate)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ unsigned wOrder, hOrder;
+ Via3DState *v3d = &pVia->v3d;
+
+ viaOrder(w, &wOrder);
+ viaOrder(h, &hOrder);
+
+ v3d->setDestination(v3d, dstOffset, dstPitch, dstFormat);
+ v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, 0x000000FF, 0x00);
+ v3d->setFlags(v3d, 1, TRUE, TRUE, FALSE);
+ v3d->setTexture(v3d, 0, srcOffset, srcPitch, TRUE, 1 << wOrder,
+ 1 << hOrder, srcFormat, via_single, via_single, via_src, FALSE);
+ v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d));
+ v3d->emitClipRect(v3d, &pVia->cb, dstX, dstY, w, h);
+ v3d->emitQuad(v3d, &pVia->cb, dstX, dstY, srcX, srcY, 0, 0, w, h);
+}
diff --git a/src/via_bandwidth.c b/src/via_bandwidth.c
new file mode 100644
index 000000000000..569d4f522c18
--- /dev/null
+++ b/src/via_bandwidth.c
@@ -0,0 +1,368 @@
+/*
+ * 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_driver.h"
+#include "via_vgahw.h"
+#include "via_id.h"
+
+/*
+ * Now that via_bios is no longer such a behemoth and the relevant
+ * code is moved via_mode.c, this code should be moved to via_mode.c too
+ * especially as output abstraction will trim via_mode.c down further
+ */
+
+/*
+ *
+ */
+static void
+ViaSetCLE266APrimaryFIFO(ScrnInfoPtr pScrn, Bool Enable)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ CARD32 dwGE230, dwGE298;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSetCLE266APrimaryFIFO: %d\n", Enable));
+
+ dwGE298 = VIAGETREG(0x298);
+ VIASETREG(0x298, dwGE298 | 0x20000000);
+
+ dwGE230 = VIAGETREG(0x230);
+ if (Enable)
+ dwGE230 |= 0x00200000;
+ else
+ dwGE230 &= ~0x00200000;
+ VIASETREG(0x230, dwGE230);
+
+ dwGE298 = VIAGETREG(0x298);
+ VIASETREG(0x298, dwGE298 & ~0x20000000);
+}
+
+/*
+ *
+ */
+typedef struct {
+ CARD16 X;
+ CARD16 Y;
+ CARD16 Bpp;
+ CARD8 bRamClock;
+ CARD8 bTuningValue;
+} ViaExpireNumberTable;
+
+static ViaExpireNumberTable CLE266AExpireNumber[] = {
+ {1280, 768,32,0x03,0x3}, {1280,1024,32,0x03,0x4}, {1280,1024,32,0x04,0x3},
+ {1600,1200,16,0x03,0x4}, {1600,1200,32,0x04,0x4}, {1024, 768,32,0x03,0xA},
+ {1400,1050,16,0x03,0x3}, {1400,1050,32,0x03,0x4}, {1400,1050,32,0x04,0x4},
+ { 800, 600,32,0x03,0xA}, { 0, 0, 0, 0, 0}
+};
+
+static ViaExpireNumberTable CLE266CExpireNumber[] = {
+ {1280, 768,32,0x03,0x3}, {1280,1024,32,0x03,0x4}, {1280,1024,32,0x04,0x4},
+ {1600,1200,32,0x03,0x3}, {1600,1200,32,0x04,0x4}, {1024, 768,32,0x03,0xA},
+ {1400,1050,32,0x03,0x4}, {1400,1050,32,0x04,0x4},
+ { 800, 600,32,0x03,0xA}, { 0, 0, 0, 0, 0}
+};
+
+static ViaExpireNumberTable KM400ExpireNumber[]={
+ {1280,1024,32,0x03,0x3}, {1280,1024,32,0x04,0x9}, {1280, 768,32,0x03,0x3},
+ {1280, 768,32,0x04,0x9}, {1400,1050,32,0x03,0x3}, {1400,1050,32,0x04,0x9},
+ {1600,1200,32,0x03,0x4}, {1600,1200,32,0x04,0xA}, { 0, 0, 0, 0, 0}
+};
+
+/*
+ *
+ */
+static void
+ViaSetPrimaryExpireNumber(ScrnInfoPtr pScrn, DisplayModePtr mode, ViaExpireNumberTable *Expire)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSetPrimaryExpireNumber\n"));
+
+ for (; Expire->X; Expire++)
+ if ((Expire->X == mode->CrtcHDisplay) &&
+ (Expire->Y == mode->CrtcVDisplay) &&
+ (Expire->Bpp == pScrn->bitsPerPixel) &&
+ (Expire->bRamClock == pVia->MemClk)) {
+ ViaSeqMask(hwp, 0x22, Expire->bTuningValue, 0x1F);
+ return;
+ }
+}
+
+/*
+ *
+ */
+void
+ViaSetPrimaryFIFO(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSetPrimaryFIFO\n"));
+
+ /* standard values */
+ ViaSeqMask(hwp, 0x17, 0x1F, 0xFF);
+
+ if (mode->CrtcHDisplay >= 1600) {
+ ViaSeqMask(hwp, 0x16, 0x0F, 0xBF);
+ ViaSeqMask(hwp, 0x18, 0x4F, 0xFF);
+ } else if (mode->CrtcHDisplay >= 1024) {
+ ViaSeqMask(hwp, 0x16, 0x0C, 0xBF);
+ ViaSeqMask(hwp, 0x18, 0x4C, 0xFF);
+ } else {
+ ViaSeqMask(hwp, 0x16, 0x08, 0xBF);
+ ViaSeqMask(hwp, 0x18, 0x4E, 0xFF);
+ }
+
+ switch(pVia->Chipset) {
+ case VIA_CLE266:
+ if (CLE266_REV_IS_CX(pVia->ChipRev)) {
+ if (pVia->HasSecondary) { /* SAMM or DuoView case */
+ if (mode->HDisplay >= 1024) {
+ ViaSeqMask(hwp, 0x16, 0x1C, 0x3F); /* 28 */
+ hwp->writeSeq(hwp, 0x17, 0x3F); /* 63 */
+ hwp->writeSeq(hwp, 0x18, 0x57); /* 23 */
+ }
+ } else { /* Single view or Simultaneous case */
+#if 0
+ if (mode->HDisplay > 1024) {
+ ViaSeqMask(hwp, 0x16, 0x17, 0x3F); /* 23 */
+ hwp->writeSeq(hwp, 0x17, 0x2F); /* 47 */
+ hwp->writeSeq(hwp, 0x18, 0x57); /* 23 */
+ }
+#endif
+ }
+ /* originally when setting secondary */
+ ViaSetPrimaryExpireNumber(pScrn, mode, CLE266CExpireNumber);
+ } else {
+ if ((mode->HDisplay > 1024) && pVia->HasSecondary) {
+ ViaSetCLE266APrimaryFIFO(pScrn, TRUE);
+
+ ViaSeqMask(hwp, 0x16, 0x17, 0x3F); /* 23 */
+ hwp->writeSeq(hwp, 0x17, 0x2F); /* 47 */
+ hwp->writeSeq(hwp, 0x18, 0x57); /* 23 */
+ }
+
+ /* originally when setting secondary */
+ ViaSetPrimaryExpireNumber(pScrn, mode, CLE266AExpireNumber);
+ }
+ break;
+ case VIA_KM400:
+ if (pVia->HasSecondary) { /* SAMM or DuoView case */
+ if ((mode->HDisplay >= 1600) &&
+ (pVia->MemClk <= VIA_MEM_DDR200)) {
+ ViaSeqMask(hwp, 0x16, 0x09, 0x3F); /* 9 */
+ hwp->writeSeq(hwp, 0x17, 0x1C); /* 28 */
+ } else {
+ ViaSeqMask(hwp, 0x16, 0x1C, 0x3F); /* 28 */
+ hwp->writeSeq(hwp, 0x17, 0x3F); /* 63 */
+ }
+ } else {
+ if ((mode->HDisplay > 1280))
+ ViaSeqMask(hwp, 0x16, 0x1C, 0x3F); /* 28 */
+ else if (mode->HDisplay > 1024)
+ ViaSeqMask(hwp, 0x16, 0x17, 0x3F); /* 23 */
+ else
+ ViaSeqMask(hwp, 0x16, 0x10, 0x3F); /* 16 */
+ hwp->writeSeq(hwp, 0x17, 0x3F); /* 63 */
+ }
+ hwp->writeSeq(hwp, 0x18, 0x57); /* 23 */
+
+ /* originally when setting secondary */
+ ViaSetPrimaryExpireNumber(pScrn, mode, KM400ExpireNumber);
+ break;
+ case VIA_K8M800:
+ hwp->writeSeq(hwp, 0x17, 0xBF); /* 384/2 - 1 = 191 (orig via comment: 384/8) */
+ ViaSeqMask(hwp, 0x16, 0x92, 0xBF); /* 328/4 = 82 = 0x52*/
+ ViaSeqMask(hwp, 0x18, 0x8a, 0xBF); /* 74 */
+
+ if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32))
+ ViaSeqMask(hwp, 0x22, 0x10, 0x1F); /* 64/4 = 16 */
+ else
+ ViaSeqMask(hwp, 0x22, 0x00, 0x1F); /* 128/4 = overflow = 0 */
+ break;
+ case VIA_PM800:
+ hwp->writeSeq(hwp, 0x17, 0x5F); /* 95 */
+ ViaSeqMask(hwp, 0x16, 0x20, 0xBF); /* 32 */
+ ViaSeqMask(hwp, 0x18, 0x10, 0xBF); /* 16 */
+
+ if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32))
+ ViaSeqMask(hwp, 0x22, 0x10, 0x1F); /* 64/4 = 16 */
+ else
+ ViaSeqMask(hwp, 0x22, 0x1F, 0x1F); /* 31 */
+ break;
+ case VIA_VM800:
+ hwp->writeSeq(hwp, 0x17, 0x2F);
+ ViaSeqMask(hwp, 0x16, 0x14, 0xBF);
+ ViaSeqMask(hwp, 0x18, 0x08, 0xBF);
+
+ if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32))
+ ViaSeqMask(hwp, 0x22, 0x10, 0x1F);
+ else
+ ViaSeqMask(hwp, 0x22, 0x00, 0x1F);
+ break;
+
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaSetPrimaryFIFO:"
+ " Chipset %d not implemented\n", pVia->Chipset);
+ break;
+
+ }
+}
+
+/*
+ * I've thrown out the LCD requirement. Size > 1024 is not supported
+ * by any currently known TV encoder anyway. -- Luc.
+ *
+ */
+void
+ViaSetSecondaryFIFO(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSetSecondaryFIFO\n"));
+
+ switch (pVia->Chipset) {
+ case VIA_CLE266:
+ if (CLE266_REV_IS_CX(pVia->ChipRev)) {
+ if (mode->HDisplay >= 1024) {
+ ViaCrtcMask(hwp, 0x6A, 0x20, 0x20);
+ hwp->writeCrtc(hwp, 0x68, 0xAB); /* depth: 10, threshold: 11 */
+ } else {
+ ViaCrtcMask(hwp, 0x6A, 0x00, 0x20);
+ hwp->writeCrtc(hwp, 0x68, 0x67); /* depth: 6, threshold: 7 */
+ }
+ } else {
+ if ((pScrn->bitsPerPixel >= 24) &&
+ (((mode->VDisplay > 768) && (pVia->MemClk <= VIA_MEM_DDR200)) ||
+ ((mode->HDisplay > 1280) && (pVia->MemClk <= VIA_MEM_DDR266)))) {
+ ViaCrtcMask(hwp, 0x6A, 0x20, 0x20);
+ hwp->writeCrtc(hwp, 0x68, 0xAB); /* depth: 10, threshold: 11 */
+ } else {
+ ViaCrtcMask(hwp, 0x6A, 0x00, 0x20);
+ hwp->writeCrtc(hwp, 0x68, 0x67); /* depth: 6, threshold: 7 */
+ }
+ }
+ break;
+ case VIA_KM400:
+ if ((mode->HDisplay >= 1600) && (pVia->MemClk <= VIA_MEM_DDR200)) {
+ ViaCrtcMask(hwp, 0x6A, 0x20, 0x20);
+ hwp->writeCrtc(hwp, 0x68, 0xEB); /* depth: 14, threshold: 11 */
+ } else if ((pScrn->bitsPerPixel == 32) &&
+ (((mode->HDisplay > 1024) && (pVia->MemClk <= VIA_MEM_DDR333)) ||
+ ((mode->HDisplay >= 1024) && (pVia->MemClk <= VIA_MEM_DDR200)))) {
+ ViaCrtcMask(hwp, 0x6A, 0x20, 0x20);
+ hwp->writeCrtc(hwp, 0x68, 0xCA); /* depth: 12, threshold: 10 */
+ } else if ((pScrn->bitsPerPixel == 16) &&
+ (((mode->HDisplay > 1280) && (pVia->MemClk <= VIA_MEM_DDR333)) ||
+ ((mode->HDisplay >= 1280) && (pVia->MemClk <= VIA_MEM_DDR200)))) {
+ ViaCrtcMask(hwp, 0x6A, 0x20, 0x20);
+ hwp->writeCrtc(hwp, 0x68, 0xAB); /* depth: 10, threshold: 11 */
+ } else {
+ ViaCrtcMask(hwp, 0x6A, 0x00, 0x20);
+ hwp->writeCrtc(hwp, 0x68, 0x67); /* depth: 6, threshold: 7 */
+ }
+ break;
+ case VIA_K8M800:
+ /* depth: (384 /8 -1 -1) = 46 = 0x2E */
+ ViaCrtcMask(hwp, 0x68, 0xE0, 0xF0);
+ ViaCrtcMask(hwp, 0x94, 0x00, 0x80);
+ ViaCrtcMask(hwp, 0x95, 0x80, 0x80);
+
+ /* threshold: (328/4) = 82 = 0x52 */
+ ViaCrtcMask(hwp, 0x68, 0x02, 0x0F);
+ ViaCrtcMask(hwp, 0x95, 0x50, 0x70);
+
+ /* preq: 74 = 0x4A */
+ ViaCrtcMask(hwp, 0x92, 0x0A, 0x0F);
+ ViaCrtcMask(hwp, 0x95, 0x04, 0x07);
+
+ if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32))
+ ViaCrtcMask(hwp, 0x94, 0x10, 0x7F); /* 64/4 */
+ else
+ ViaCrtcMask(hwp, 0x94, 0x20, 0x7F); /* 128/4 */
+ break;
+ case VIA_PM800:
+ /* depth: 12 - 1 = 0x0B */
+ ViaCrtcMask(hwp, 0x68, 0xB0, 0xF0);
+ ViaCrtcMask(hwp, 0x94, 0x00, 0x80);
+ ViaCrtcMask(hwp, 0x95, 0x00, 0x80);
+
+ /* threshold: 16 = 0x10 */
+ ViaCrtcMask(hwp, 0x68, 0x00, 0x0F);
+ ViaCrtcMask(hwp, 0x95, 0x10, 0x70);
+
+ /* preq: 8 = 0x08 */
+ ViaCrtcMask(hwp, 0x92, 0x08, 0x0F);
+ ViaCrtcMask(hwp, 0x95, 0x00, 0x07);
+
+ if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32))
+ ViaCrtcMask(hwp, 0x94, 0x10, 0x7F); /* 64/4 */
+ else
+ ViaCrtcMask(hwp, 0x94, 0x20, 0x7F); /* 128/4 */
+ break;
+ case VIA_VM800:
+ ViaCrtcMask(hwp, 0x68, 0xA0, 0xF0);
+ ViaCrtcMask(hwp, 0x94, 0x00, 0x80);
+ ViaCrtcMask(hwp, 0x95, 0x00, 0x80);
+
+ ViaCrtcMask(hwp, 0x68, 0x04, 0x0F);
+ ViaCrtcMask(hwp, 0x95, 0x10, 0x70);
+
+ ViaCrtcMask(hwp, 0x92, 0x08, 0x0F);
+ ViaCrtcMask(hwp, 0x95, 0x00, 0x07);
+
+ 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);
+ break;
+ }
+}
+
+/*
+ * Wrap around ViaSetCLE266APrimaryFIFO
+ */
+void
+ViaDisablePrimaryFIFO(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDisablePrimaryFIFO\n"));
+
+ /* Cause of exit XWindow will dump back register value, others chipset no
+ * need to set extended fifo value */
+ if ((pVia->Chipset == VIA_CLE266) && CLE266_REV_IS_AX(pVia->ChipRev) &&
+ ((pScrn->currentMode->HDisplay > 1024) || pVia->HasSecondary))
+ ViaSetCLE266APrimaryFIFO(pScrn, FALSE);
+}
diff --git a/src/via_bios.h b/src/via_bios.h
new file mode 100644
index 000000000000..a6f814066359
--- /dev/null
+++ b/src/via_bios.h
@@ -0,0 +1,181 @@
+/*
+ * 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.
+ */
+
+#ifndef _VIA_BIOS_H_
+#define _VIA_BIOS_H_ 1
+
+#define VIA_PANEL6X4 0
+#define VIA_PANEL8X6 1
+#define VIA_PANEL10X7 2
+#define VIA_PANEL12X7 3
+#define VIA_PANEL12X10 4
+#define VIA_PANEL14X10 5
+#define VIA_PANEL16X12 6
+#define VIA_PANEL12X8 7
+#define VIA_PANEL_INVALID 255
+
+#define TVTYPE_NONE 0x00
+#define TVTYPE_NTSC 0x01
+#define TVTYPE_PAL 0x02
+#define TVTYPE_480P 0X03
+#define TVTYPE_576P 0X04
+#define TVTYPE_720P 0X05
+#define TVTYPE_1080I 0X06
+
+#define TVOUTPUT_NONE 0x00
+#define TVOUTPUT_COMPOSITE 0x01
+#define TVOUTPUT_SVIDEO 0x02
+#define TVOUTPUT_RGB 0x04
+#define TVOUTPUT_YCBCR 0x08
+#define TVOUTPUT_SC 0x16
+
+#define VIA_NONETV 0
+#define VIA_VT1621 1 /* TV2PLUS */
+#define VIA_VT1622 2 /* TV3 */
+#define VIA_VT1623 3 /* also VT1622A */
+#define VIA_VT1625 4
+#define VIA_CH7011 5
+#define VIA_CH7019A 6
+#define VIA_CH7019B 7
+#define VIA_CH7017 8
+#define VIA_CH7304 9
+#define VIA_CH7305 10
+
+
+#define VIA_TVNORMAL 0
+#define VIA_TVOVER 1
+
+#define VIA_DEVICE_NONE 0x00
+#define VIA_DEVICE_CRT 0x01
+#define VIA_DEVICE_LCD 0x02
+#define VIA_DEVICE_TV 0x04
+#define VIA_DEVICE_DFP 0x08
+
+/* System Memory CLK */
+#define VIA_MEM_SDR66 0x00
+#define VIA_MEM_SDR100 0x01
+#define VIA_MEM_SDR133 0x02
+#define VIA_MEM_DDR200 0x03
+#define VIA_MEM_DDR266 0x04
+#define VIA_MEM_DDR333 0x05
+#define VIA_MEM_DDR400 0x06
+#define VIA_MEM_DDR533 0x07
+#define VIA_MEM_END 0x08
+#define VIA_MEM_NONE 0xFF
+
+/* Digital Output Bus Width */
+#define VIA_DI_12BIT 0x00
+#define VIA_DI_24BIT 0x01
+
+typedef struct _VIABIOSINFO {
+ int scrnIndex;
+
+ Bool CrtPresent;
+ Bool CrtActive;
+
+ CARD16 ResolutionIndex;
+ CARD32 Clock; /* register value for the dotclock */
+ Bool ClockExternal;
+ CARD32 Bandwidth; /* available memory bandwidth */
+
+ /* Panel/LCD entries */
+ Bool PanelPresent;
+ Bool PanelActive;
+ Bool ForcePanel;
+ int PanelIndex;
+ int PanelSize;
+ Bool Center;
+ CARD8 BusWidth; /* Digital Output Bus Width */
+ Bool SetDVI;
+ /* LCD Simultaneous Expand Mode HWCursor Y Scale */
+ Bool scaleY;
+ int panelX;
+ int panelY;
+ int resY;
+
+ /* TV entries */
+ int TVEncoder;
+ int TVOutput;
+ Bool TVActive;
+ I2CDevPtr TVI2CDev;
+ int TVType;
+ Bool TVDotCrawl;
+ int TVDeflicker;
+ CARD8 TVRegs[0xFF];
+ int TVNumRegs;
+
+ /* TV Callbacks */
+ void (*TVSave) (ScrnInfoPtr pScrn);
+ void (*TVRestore) (ScrnInfoPtr pScrn);
+ Bool (*TVDACSense) (ScrnInfoPtr pScrn);
+ ModeStatus (*TVModeValid) (ScrnInfoPtr pScrn, DisplayModePtr mode);
+ void (*TVModeI2C) (ScrnInfoPtr pScrn, DisplayModePtr mode);
+ void (*TVModeCrtc) (ScrnInfoPtr pScrn, DisplayModePtr mode);
+ void (*TVPower) (ScrnInfoPtr pScrn, Bool On);
+ void (*LCDPower) (ScrnInfoPtr pScrn, Bool On);
+ DisplayModePtr TVModes;
+ void (*TVPrintRegs) (ScrnInfoPtr pScrn);
+
+} VIABIOSInfoRec, *VIABIOSInfoPtr;
+
+/* Function prototypes */
+/* via_vbe.c */
+void ViaVbeAdjustFrame(int scrnIndex, int x, int y, int flags);
+Bool ViaVbeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode);
+Bool ViaVbeSaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function);
+Bool ViaVbeModePreInit(ScrnInfoPtr pScrn);
+void ViaVbeDPMS(ScrnInfoPtr pScrn, int mode, int flags);
+void ViaVbeDoDPMS(ScrnInfoPtr pScrn, int mode);
+
+/* via_mode.c */
+void ViaOutputsDetect(ScrnInfoPtr pScrn);
+Bool ViaOutputsSelect(ScrnInfoPtr pScrn);
+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 ViaLCDPower(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
+
+/* in via_bandwidth.c */
+void ViaSetPrimaryFIFO(ScrnInfoPtr pScrn, DisplayModePtr mode);
+void ViaSetSecondaryFIFO(ScrnInfoPtr pScrn, DisplayModePtr mode);
+void ViaDisablePrimaryFIFO(ScrnInfoPtr pScrn);
+
+/* via_vt162x.c */
+I2CDevPtr ViaVT162xDetect(ScrnInfoPtr pScrn, I2CBusPtr pBus, CARD8 Address);
+void ViaVT162xInit(ScrnInfoPtr pScrn);
+
+/* via_ch7xxx.c */
+I2CDevPtr ViaCH7xxxDetect(ScrnInfoPtr pScrn, I2CBusPtr pBus, CARD8 Address);
+void ViaCH7xxxInit(ScrnInfoPtr pScrn);
+
+#endif /* _VIA_BIOS_H_ */
diff --git a/src/via_ch7xxx.c b/src/via_ch7xxx.c
new file mode 100644
index 000000000000..64e3e1f31463
--- /dev/null
+++ b/src/via_ch7xxx.c
@@ -0,0 +1,650 @@
+/*
+ * Copyright 2005 Terry Lewis. All Rights Reserved.
+ * Copyright 2005 Philip Langdale. All Rights Reserved. (CH7011 additions)
+ * Copyright 2004 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
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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_driver.h"
+#include "via_vgahw.h"
+#include "via_ch7xxx.h"
+#include "via_id.h"
+
+#ifdef HAVE_DEBUG
+/*
+ *
+ */
+static void
+CH7xxxPrintRegs(ScrnInfoPtr pScrn)
+{
+ VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo;
+ CARD8 i, buf;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Printing registers for %s\n",
+ pBIOSInfo->TVI2CDev->DevName);
+
+ for (i = 0; i < pBIOSInfo->TVNumRegs; i++) {
+ xf86I2CReadByte(pBIOSInfo->TVI2CDev, i, &buf);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV%02X: 0x%02X\n", i, buf);
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "End of TV registers.\n");
+}
+#endif /* HAVE_DEBUG */
+
+/*
+ *
+ */
+I2CDevPtr
+ViaCH7xxxDetect(ScrnInfoPtr pScrn, I2CBusPtr pBus, CARD8 Address)
+{
+ VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo;
+ I2CDevPtr pDev = xf86CreateI2CDevRec();
+ CARD8 buf;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaCH7xxxDetect\n"));
+
+ pDev->DevName = "CH7xxx";
+ pDev->SlaveAddr = Address;
+ pDev->pI2CBus = pBus;
+
+ if (!xf86I2CDevInit(pDev)) {
+ xf86DestroyI2CDevRec(pDev, TRUE);
+ return NULL;
+ }
+
+
+ if (!xf86I2CReadByte(pDev, 0x4B, &buf)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to read from %s Slave %d.\n",
+ pBus->BusName, Address);
+ xf86DestroyI2CDevRec(pDev, TRUE);
+ return NULL;
+ }
+
+ switch (buf) {
+ case 0x17:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected Chrontel CH7011 TV Encoder\n");
+ pBIOSInfo->TVEncoder = VIA_CH7011;
+ pDev->DevName="CH7011";
+ break;
+ case 0x19:
+ xf86I2CReadByte(pDev, 0x4A, &buf);
+ if (buf == 0x81) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected Chrontel CH7019A LVDS Transmitter/TV Encoder\n");
+ pBIOSInfo->TVEncoder = VIA_CH7019A;
+ pDev->DevName="CH7019A";
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected Chrontel CH7019B LVDS Transmitter/TV Encoder\n");
+ pBIOSInfo->TVEncoder = VIA_CH7019B;
+ pDev->DevName="CH7019B";
+ }
+ break;
+ case 0x1B:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected Chrontel CH7017 LVDS Transmitter\n");
+ pBIOSInfo->TVEncoder = VIA_CH7017;
+ pDev->DevName="CH7017";
+ break;
+ case 0x3A:
+ /* single init table --> single channel LVDS transmitter ? */
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected Chrontel CH7304 LVDS Transmitter\n");
+ pBIOSInfo->TVEncoder = VIA_CH7304;
+ pDev->DevName="CH7304";
+ break;
+ case 0x3B:
+ /* dual init table --> dual channel LVDS transmitter ? */
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected Chrontel CH7305 LVDS Transmitter\n");
+ pBIOSInfo->TVEncoder = VIA_CH7305;
+ pDev->DevName="CH7305";
+ break;
+ default:
+ pBIOSInfo->TVEncoder = VIA_NONETV;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unknown CH7xxx"
+ " device found. [%x:0x1B contains %x]\n",
+ Address, buf);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Unknown CH7xxx encoder found\n");
+
+ xf86DestroyI2CDevRec(pDev,TRUE);
+ pDev = NULL;
+ break;
+ }
+
+ return pDev;
+}
+
+/*
+ *
+ */
+
+static void
+CH7xxxSave(ScrnInfoPtr pScrn)
+{
+ int i;
+ VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxSave\n"));
+
+ for (i = 0; i < pBIOSInfo->TVNumRegs; i++)
+ xf86I2CReadByte(pBIOSInfo->TVI2CDev, i, &(pBIOSInfo->TVRegs[i]));
+}
+
+
+static void
+CH7xxxRestore(ScrnInfoPtr pScrn)
+{
+ int i;
+ VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxRestore\n"));
+
+ for (i = 0; i < pBIOSInfo->TVNumRegs; i++)
+ xf86I2CWriteByte(pBIOSInfo->TVI2CDev, i, pBIOSInfo->TVRegs[i]);
+}
+
+static CARD8
+CH7xxxDACSenseI2C(I2CDevPtr pDev)
+{
+ CARD8 save, sense;
+
+ /* Turn all DACP on*/
+ xf86I2CWriteByte(pDev, 0x49, 0x20);
+
+ /* Make sure Bypass mode is disabled (DACBP) bit0 is set to '0' */
+ xf86I2CReadByte(pDev, 0x21, &save);
+ xf86I2CWriteByte(pDev, 0x21, save & ~0x01);
+
+ /* Set Sense bit0 to '1' */
+ xf86I2CReadByte(pDev, 0x20, &save);
+ xf86I2CWriteByte(pDev, 0x20, save | 0x01);
+
+ /* Set Sense bit0 back to '0' */
+ xf86I2CReadByte(pDev, 0x20, &save);
+ xf86I2CWriteByte(pDev, 0x20, save & ~0x01);
+
+ /* Read DACT status bits */
+ xf86I2CReadByte(pDev, 0x20, &sense);
+
+ return (sense & 0x1F);
+}
+
+/*
+ * A CH7xxx hack. (T. Lewis. S-Video fixed by P. Langdale)
+ *
+ * CH7xxx Cable types (C+S and YcBcR untested and almost certainly wrong)
+ * 0x10 = Composite
+ * 0x0C = S-Video
+ * 0x02 = Composite+S-Video
+ * 0x04 = YcBcR
+ * 0x00 = Nothing Connected
+ */
+
+static Bool
+CH7xxxDACSense(ScrnInfoPtr pScrn)
+{
+ VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo;
+ CARD8 sense;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxDACDetect\n"));
+
+/* is this needed? IH */
+ if (!pBIOSInfo->TVI2CDev ||
+ !pBIOSInfo->TVEncoder)
+ return FALSE;
+
+ sense = CH7xxxDACSenseI2C(pBIOSInfo->TVI2CDev);
+
+ /* I'm sure these case values are correct,
+ * but we should get something in any case.
+ * 0x10 (Composite), 0x0C (S-Video) and 0x00 (Nothing connected)
+ * seem to be correct however.
+ */
+ switch (sense) {
+ case 0x10:
+ pBIOSInfo->TVOutput = TVOUTPUT_COMPOSITE;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CH7xxx: Composite connected.\n");
+ return TRUE;
+ case 0x0C:
+ pBIOSInfo->TVOutput = TVOUTPUT_SVIDEO;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CH7xxx: S-Video connected.\n");
+ return TRUE;
+ case 0x02:
+ pBIOSInfo->TVOutput = TVOUTPUT_SC;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CHxxx: Composite+S-Video connected.\n");
+ return TRUE;
+ case 0x04:
+ pBIOSInfo->TVOutput = TVOUTPUT_YCBCR;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CHxxx: YcBcR Connected.\n");
+ return TRUE;
+ case 0x00:
+ pBIOSInfo->TVOutput = TVOUTPUT_NONE;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CH7xxx: Nothing connected.\n");
+ return FALSE;
+ default:
+ pBIOSInfo->TVOutput = TVOUTPUT_NONE;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "CH7xxx: Unknown cable combination: 0x0%2X.\n",sense);
+ return FALSE;
+ }
+}
+
+static CARD8
+CH7011ModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo;
+ int i;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7011ModeIndex\n"));
+ for (i = 0; CH7011Table[i].Width; i++) {
+ if ((CH7011Table[i].Width == mode->CrtcHDisplay) &&
+ (CH7011Table[i].Height == mode->CrtcVDisplay) &&
+ (CH7011Table[i].Standard == pBIOSInfo->TVType) &&
+ !(strcmp(CH7011Table[i].name, mode->name)))
+ return i;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "CH7011ModeIndex:"
+ " Mode \"%s\" not found in Table\n", mode->name);
+ return 0xFF;
+}
+
+static CARD8
+CH7019ModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo;
+ int i;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7019ModeIndex\n"));
+ for (i = 0; CH7019Table[i].Width; i++) {
+ if ((CH7019Table[i].Width == mode->CrtcHDisplay) &&
+ (CH7019Table[i].Height == mode->CrtcVDisplay) &&
+ (CH7019Table[i].Standard == pBIOSInfo->TVType) &&
+ !(strcmp(CH7019Table[i].name, mode->name)))
+ return i;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "CH7019ModeIndex:"
+ " Mode \"%s\" not found in Table\n", mode->name);
+ return 0xFF;
+}
+
+/*
+ *
+ */
+static ModeStatus
+CH7xxxModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxModeValid\n"));
+
+ if ((mode->PrivSize != sizeof(struct CH7xxxModePrivate)) ||
+ ((mode->Private != (void *) &CH7xxxModePrivateNTSC) &&
+ (mode->Private != (void *) &CH7xxxModePrivatePAL))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Not a mode defined by the TV Encoder.\n");
+ return MODE_BAD;
+ }
+
+ if ((pBIOSInfo->TVType == TVTYPE_NTSC) &&
+ (mode->Private != (void *) &CH7xxxModePrivateNTSC)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standard is NTSC. This is a PAL mode.\n");
+ return MODE_BAD;
+ } else if ((pBIOSInfo->TVType == TVTYPE_PAL) &&
+ (mode->Private != (void *) &CH7xxxModePrivatePAL)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standard is PAL. This is a NTSC mode.\n");
+ return MODE_BAD;
+ }
+
+ if (pBIOSInfo->TVEncoder == VIA_CH7011)
+ {
+ if (CH7011ModeIndex(pScrn, mode) != 0xFF)
+ return MODE_OK;
+ }
+ else
+ {
+ if (CH7019ModeIndex(pScrn, mode) != 0xFF)
+ return MODE_OK;
+ }
+ return MODE_BAD;
+}
+
+static void
+CH7xxxModeI2C(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+
+ CARD8 i, j;
+
+ VIABIOSTVMASKTableRec Mask;
+ struct CH7xxxTableRec Table;
+
+ if (pBIOSInfo->TVEncoder == VIA_CH7011)
+ {
+ Table = CH7011Table[CH7011ModeIndex(pScrn, mode)];
+ Mask = ch7011MaskTable;
+ }
+ else
+ {
+ Table = CH7019Table[CH7019ModeIndex(pScrn, mode)];
+ Mask = ch7019MaskTable;
+ }
+
+ DEBUG(xf86DrvMsg(pBIOSInfo->scrnIndex, X_INFO, "CH7011ModeI2C\n"));
+
+ xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x3E);
+ xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1E, 0xD0);
+
+ for (i = 0,j = 0; (j < Mask.numTV) && (i < VIA_BIOS_TABLE_NUM_TV_REG); i++) {
+ if (Mask.TV[i] == 0xFF) {
+ xf86I2CWriteByte(pBIOSInfo->TVI2CDev, i, Table.TV[i]);
+ j++;
+ } else {
+ xf86I2CWriteByte(pBIOSInfo->TVI2CDev, i, pBIOSInfo->TVRegs[i]);
+ }
+ }
+
+ if ((pBIOSInfo->TVType == TVTYPE_NTSC) && pBIOSInfo->TVDotCrawl) {
+ CARD16 *DotCrawl = Table.DotCrawlNTSC;
+ CARD8 address, save;
+
+ for (i = 1; i < (DotCrawl[0] + 1); i++) {
+ address = (CARD8)(DotCrawl[i] & 0xFF);
+
+ save = (CARD8)(DotCrawl[i] >> 8);
+ xf86I2CWriteByte(pBIOSInfo->TVI2CDev, address, save);
+ }
+ }
+
+ /*
+ * Only Composite and SVideo have been tested.
+ */
+ switch(pBIOSInfo->TVOutput){
+ case TVOUTPUT_COMPOSITE:
+ xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x2E);
+ break;
+ case TVOUTPUT_SVIDEO:
+ xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x32);
+ break;
+ case TVOUTPUT_SC:
+ xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x3C);
+ break;
+ case TVOUTPUT_YCBCR:
+ xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x3A);
+ break;
+ default:
+ break;
+ }
+
+ if (pVia->IsSecondary) { /* Patch as setting 2nd path */
+ j = (CARD8)(Mask.misc2 >> 5);
+ for (i = 0; i < j; i++)
+ xf86I2CWriteByte(pBIOSInfo->TVI2CDev, Table.Patch2[i] & 0xFF, Table.Patch2[i] >> 8);
+ }
+}
+
+static void
+CH7xxxModeCrtc(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ VIAPtr pVia = VIAPTR(pScrn);
+ VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+ CARD8 *CRTC, *Misc;
+ int i, j;
+
+ VIABIOSTVMASKTableRec Mask;
+ struct CH7xxxTableRec Table;
+
+ if (pBIOSInfo->TVEncoder == VIA_CH7011)
+ {
+ Table = CH7011Table[CH7011ModeIndex(pScrn, mode)];
+ Mask = ch7011MaskTable;
+ }
+ else
+ {
+ Table = CH7019Table[CH7019ModeIndex(pScrn, mode)];
+ Mask = ch7019MaskTable;
+ }
+
+ DEBUG(xf86DrvMsg(pBIOSInfo->scrnIndex, X_INFO, "CH7xxxModeCrtc\n"));
+
+ if (pVia->IsSecondary) {
+ switch (pScrn->bitsPerPixel) {
+ case 16:
+ CRTC = Table.CRTC2_16BPP;
+ break;
+ case 24:
+ case 32:
+ CRTC = Table.CRTC2_32BPP;
+ break;
+ case 8:
+ default:
+ CRTC = Table.CRTC2_8BPP;
+ break;
+ }
+ Misc = Table.Misc2;
+
+
+ for (i = 0, j = 0; i < Mask.numCRTC2; j++) {
+ if (Mask.CRTC2[j] == 0xFF) {
+ hwp->writeCrtc(hwp, j + 0x50, CRTC[j]);
+ i++;
+ }
+ }
+
+ if (Mask.misc2 & 0x18) {
+ pBIOSInfo->Clock = (Misc[3] << 8) & Misc[4];
+ /* VIASetUseExternalClock(hwp); */
+ }
+
+ ViaCrtcMask(hwp, 0x6A, 0xC0, 0xC0);
+ ViaCrtcMask(hwp, 0x6B, 0x01, 0x01);
+ ViaCrtcMask(hwp, 0x6C, 0x01, 0x01);
+
+ /* Disable LCD Scaling */
+ if (!pVia->SAMM || pVia->FirstInit)
+ hwp->writeCrtc(hwp, 0x79, 0x00);}
+ else {
+
+ CRTC = Table.CRTC1;
+ Misc = Table.Misc1;
+
+ for (i = 0, j = 0; i < Mask.numCRTC1; j++) {
+ if (Mask.CRTC1[j] == 0xFF) {
+ hwp->writeCrtc(hwp, j, CRTC[j]);
+ i++;
+ }
+ }
+
+ ViaCrtcMask(hwp, 0x33, Misc[0], 0x20);
+ hwp->writeCrtc(hwp, 0x6A, Misc[1]);
+
+ if ((pVia->Chipset == VIA_CLE266) &&
+ CLE266_REV_IS_AX(pVia->ChipRev)) {
+ hwp->writeCrtc(hwp, 0x6B, Misc[2] | 0x81);
+ /* Fix TV clock Polarity for CLE266A2 */
+ if (pVia->ChipRev == 0x02)
+ hwp->writeCrtc(hwp, 0x6C, Misc[3] | 0x01);
+ } else
+ hwp->writeCrtc(hwp, 0x6B, Misc[2] | 0x01);
+
+ if (Mask.misc1 & 0x30) {
+ /* CLE266Ax use 2x XCLK */
+ if ((pVia->Chipset == VIA_CLE266) &&
+ CLE266_REV_IS_AX(pVia->ChipRev))
+ pBIOSInfo->Clock = 0x471C;
+ else
+ pBIOSInfo->Clock = (Misc[4] << 8) | Misc[5];
+ }
+
+ ViaCrtcMask(hwp, 0x6A, 0x40, 0x40);
+ ViaCrtcMask(hwp, 0x6B, 0x01, 0x01);
+ ViaCrtcMask(hwp, 0x6C, 0x01, 0x01);
+ }
+
+ ViaSeqMask(hwp, 0x1E, 0xC0, 0xC0); /* Enable DI0/DVP0 */
+}
+
+
+/*
+ *
+ */
+static void
+CH7xxxTVPower(ScrnInfoPtr pScrn, Bool On)
+{
+ VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo;
+
+ if (On){
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxTVPower: On\n"));
+ xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x20);
+ }else{
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxTVPower: Off\n"));
+ xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x3E);
+ xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1E, 0xD0);
+ }
+}
+
+static void
+CH7019LCDPower(ScrnInfoPtr pScrn, Bool On)
+{
+ VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo;
+ CARD8 W_Buffer[2], R_Buffer[1];
+ int i;
+
+ if (On){
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxLCDPower: On\n"));
+ W_Buffer[0] = 0x63;
+ W_Buffer[1] = 0x4B;
+ xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0);
+ W_Buffer[0] = 0x66;
+ W_Buffer[1] = 0x20;
+ xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0);
+
+ for (i = 0; i < 10; i++) {
+ W_Buffer[0] = 0x63;
+ xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,1, R_Buffer,1);
+ usleep(100);
+ W_Buffer[0] = 0x63;
+ W_Buffer[1] = (R_Buffer[0] | 0x40);
+ xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "CH7xxxLCDPower: [%d]write 0x63 = %X!\n", i+1, W_Buffer[1]));
+ usleep(1);
+ W_Buffer[0] = 0x63;
+ W_Buffer[1] &= ~0x40;
+ xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "CH7xxxLCDPower: [%d]write 0x63 = %X!\n", i+1, W_Buffer[1]));
+ usleep(100);
+ W_Buffer[0] = 0x66;
+ xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,1, R_Buffer,1);
+
+ if (((R_Buffer[0] & 0x44) == 0x44) || (i >= 9)) {
+ /* PLL lock OK, Turn on VDD */
+ usleep(500);
+ W_Buffer[1] = R_Buffer[0] | 0x01;
+ xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "CH7xxxLCDPower: CH7019 PLL lock ok!\n"));
+ /* reset data path */
+ W_Buffer[0] = 0x48;
+ xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,1, R_Buffer,1);
+ W_Buffer[1] = R_Buffer[0] & ~0x08;
+ xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0);
+ usleep(1);
+ W_Buffer[1] = R_Buffer[0];
+ xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0);
+ break;
+ }
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "CH7xxxLCDPower: [%d]CH7019 PLL lock fail!\n", i+1));
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "CH7xxxLCDPower: [%d]0x66 = %X!\n", i+1, R_Buffer[0]));
+ }
+ }else{
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CH7xxxLCDPower: Off\n"));
+ /* Turn off VDD (Turn off backlignt only) */
+ W_Buffer[0] = 0x66;
+ xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,1, R_Buffer,1);
+ W_Buffer[1] &= ~0x01;
+ xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0);
+ usleep(100);
+ /* Turn off LVDS path */
+ W_Buffer[0] = 0x63;
+ xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,1, R_Buffer,1);
+ W_Buffer[1] = (R_Buffer[0] | 0x40);
+ xf86I2CWriteRead(pBIOSInfo->TVI2CDev, W_Buffer,2, NULL,0);
+ }
+}
+
+/*
+ *
+ */
+void
+ViaCH7xxxInit(ScrnInfoPtr pScrn)
+{
+ VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaCH7xxxInit\n"));
+
+ switch (pBIOSInfo->TVEncoder) {
+ case VIA_CH7011:
+ pBIOSInfo->TVSave = CH7xxxSave;
+ pBIOSInfo->TVRestore = CH7xxxRestore;
+ pBIOSInfo->TVDACSense = CH7xxxDACSense;
+ pBIOSInfo->TVModeValid = CH7xxxModeValid;
+ pBIOSInfo->TVModeI2C = CH7xxxModeI2C;
+ pBIOSInfo->TVModeCrtc = CH7xxxModeCrtc;
+ pBIOSInfo->TVPower = CH7xxxTVPower;
+ pBIOSInfo->TVModes = CH7011Modes;
+ pBIOSInfo->LCDPower = NULL;
+ pBIOSInfo->TVNumRegs = CH_7011_MAX_NUM_REG;
+#ifdef HAVE_DEBUG
+ pBIOSInfo->TVPrintRegs = CH7xxxPrintRegs;
+#endif
+ break;
+ case VIA_CH7019A:
+ case VIA_CH7019B:
+ pBIOSInfo->TVDACSense = CH7xxxDACSense;
+ pBIOSInfo->TVSave = CH7xxxSave;
+ pBIOSInfo->TVRestore = CH7xxxRestore;
+ pBIOSInfo->TVModeValid = CH7xxxModeValid;
+ pBIOSInfo->TVModeI2C = CH7xxxModeI2C;
+ pBIOSInfo->TVModeCrtc = CH7xxxModeCrtc;
+ pBIOSInfo->TVPower = CH7xxxTVPower;
+ pBIOSInfo->TVModes = CH7019Modes;
+ pBIOSInfo->LCDPower = CH7019LCDPower;
+ pBIOSInfo->TVNumRegs = CH_7019_MAX_NUM_REG;
+#ifdef HAVE_DEBUG
+ pBIOSInfo->TVPrintRegs = CH7xxxPrintRegs;
+#endif
+ break;
+ default:
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaCH7xxxInit missing\n"));
+ break;
+ }
+
+ /* Save before continuing */
+ if (pBIOSInfo->TVSave)
+ pBIOSInfo->TVSave(pScrn);
+}
diff --git a/src/via_ch7xxx.h b/src/via_ch7xxx.h
new file mode 100644
index 000000000000..f74264202b35
--- /dev/null
+++ b/src/via_ch7xxx.h
@@ -0,0 +1,737 @@
+/*
+ * Copyright 2005 Terry Lewis. All Rights Reserved.
+ * Copyright 2005 Philip Langdale. All Rights Reserved. (CH7011 additions)
+ * 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
+ * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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 _VIA_CH7xxx_H_
+#define _VIA_CH7xxx_H_ 1
+
+/*+#define VIA_BIOS_MAX_NUM_TV_REG 0x80
++#define VIA_BIOS_MAX_NUM_TV_CRTC 32
++#define VIA_BIOS_NUM_TV_SPECIAL_REG 8
++#define VIA_BIOS_MAX_NUM_TV_PATCH 8
++#define VIA_BIOS_NUM_TV_OTHER 16
+*/
+
+#define VIA_BIOS_TABLE_NUM_TV_REG 0x23 /* 0x00 - 0x22 */
+
+#define CH_7011_MAX_NUM_REG 0x4C /* 0x00 - 0x4B */
+#define CH_7019_MAX_NUM_REG 0x80 /* 0x00 - 0x7F */
+
+#define VIA_BIOS_MAX_NUM_TV_CRTC 32
+#define VIA_BIOS_NUM_TV_SPECIAL_REG 8
+#define VIA_BIOS_MAX_NUM_TV_PATCH 8
+#define VIA_BIOS_NUM_TV_OTHER 16
+
+struct CH7xxxModePrivate {
+ char id[12]; /* "CH7xxx" */
+ CARD8 Standard;
+};
+
+static struct CH7xxxModePrivate CH7xxxModePrivateNTSC = {
+ { 'C', 'H', '7', 'x', 'x', 'x', 0, 0, 0, 0, 0, 0 },
+ TVTYPE_NTSC,
+};
+
+static struct CH7xxxModePrivate CH7xxxModePrivatePAL = {
+ { 'C', 'H', '7', 'x', 'x', 'x', 0, 0, 0, 0, 0, 0 },
+ TVTYPE_PAL,
+};
+
+
+#define MODEPREFIX(name) NULL, NULL, name, 0,M_T_DEFAULT
+#define MODESUFFIXNTSC 0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,FALSE,FALSE,\
+ sizeof(struct CH7xxxModePrivate),(void *)&CH7xxxModePrivateNTSC,0,0.0,0.0
+#define MODESUFFIXPAL 0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,FALSE,FALSE,\
+ sizeof(struct CH7xxxModePrivate),(void *)&CH7xxxModePrivatePAL,0,0.0,0.0
+
+/* dotclock is just for modeline validation */
+static DisplayModeRec CH7011Modes[]={
+ { MODEPREFIX("640x480"), 23520, 640, 656, 744, 784, 0, 480, 487, 491, 600, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC },
+ { MODEPREFIX("640x480"), 30000, 640, 680, 808, 1000, 0, 480, 520, 523, 600, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL },
+ { MODEPREFIX("800x600"), 39900, 800, 840, 976, 1064, 0, 600, 604, 620, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXNTSC },
+ { MODEPREFIX("800x600"), 34500, 800, 816, 880, 920, 0, 600, 604, 620, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXPAL },
+ { MODEPREFIX("1024x768"), 54810, 1024, 1032, 1088, 1160, 0, 768, 780, 792, 945, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC },
+ { MODEPREFIX("1024x768"), 57000, 1024, 1040, 1112, 1200, 0, 768, 829, 840, 950, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL },
+
+ { MODEPREFIX("640x480Over"), 20160, 640, 648, 704, 720, 0, 480, 487, 491, 560, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC },
+ { MODEPREFIX("640x480Over"), 21000, 640, 664, 792, 840, 0, 480, 485, 491, 500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL },
+ { MODEPREFIX("800x600Over"), 35910, 800, 840, 984, 1080, 0, 600, 601, 604, 665, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXNTSC },
+ { MODEPREFIX("800x600Over"), 32500, 800, 832, 928, 1000, 0, 600, 600, 604, 650, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXPAL },
+ { MODEPREFIX("1024x768Over"), 50400, 1024, 1040, 1112, 1200, 0, 768, 772, 776, 840, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC },
+ { MODEPREFIX("1024x768Over"), 49500, 1024, 1032, 1112, 1200, 0, 768, 771, 776, 825, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL },
+
+ { MODEPREFIX("720x480"), 25200, 720, 728, 776, 840, 0, 480, 511, 515, 600, 0, V_NHSYNC | V_PVSYNC, MODESUFFIXNTSC },
+ { MODEPREFIX("720x576"), 28500, 720, 728, 744, 760, 0, 576, 635, 643, 750, 0, V_NHSYNC | V_PVSYNC, MODESUFFIXPAL },
+ { MODEPREFIX("720x480Noscale"), 27972, 720, 736, 768, 888, 0, 480, 480, 483, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC },
+ { MODEPREFIX("720x576Noscale"), 28000, 720, 728, 864, 896, 0, 576, 576, 579, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL },
+
+ { MODEPREFIX(NULL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIXNTSC },
+};
+
+static DisplayModeRec CH7019Modes[]={
+ { MODEPREFIX("640x480"), 23520, 640, 656, 744, 784, 0, 480, 487, 491, 600, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC },
+ { MODEPREFIX("640x480"), 30000, 640, 680, 808, 1000, 0, 480, 520, 523, 600, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL },
+ { MODEPREFIX("800x600"), 39900, 800, 840, 976, 1064, 0, 600, 604, 620, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXNTSC },
+ { MODEPREFIX("800x600"), 34500, 800, 816, 880, 920, 0, 600, 604, 620, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXPAL },
+ { MODEPREFIX("1024x768"), 54810, 1024, 1032, 1088, 1160, 0, 768, 780, 792, 945, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC },
+ { MODEPREFIX("1024x768"), 57000, 1024, 1040, 1112, 1200, 0, 768, 829, 840, 950, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL },
+ { MODEPREFIX("640x480Over"), 20160, 640, 648, 704, 720, 0, 480, 487, 491, 560, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC },
+ { MODEPREFIX("640x480Over"), 21000, 640, 664, 792, 840, 0, 480, 485, 491, 500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL },
+ { MODEPREFIX("800x600Over"), 35910, 800, 840, 984, 1080, 0, 600, 601, 604, 665, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXNTSC },
+ { MODEPREFIX("800x600Over"), 32500, 800, 832, 928, 1000, 0, 600, 600, 604, 650, 0, V_PHSYNC | V_PVSYNC, MODESUFFIXPAL },
+ { MODEPREFIX("1024x768Over"), 50400, 1024, 1040, 1112, 1200, 0, 768, 772, 776, 840, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXNTSC },
+ { MODEPREFIX("1024x768Over"), 49500, 1024, 1032, 1112, 1200, 0, 768, 771, 776, 825, 0, V_NHSYNC | V_NVSYNC, MODESUFFIXPAL },
+
+ { MODEPREFIX(NULL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIXNTSC },
+};
+
+
+typedef struct _VIATVMASKTABLE {
+ CARD8 TV[VIA_BIOS_TABLE_NUM_TV_REG];
+ CARD8 CRTC1[VIA_BIOS_MAX_NUM_TV_CRTC];
+ CARD8 CRTC2[VIA_BIOS_MAX_NUM_TV_CRTC];
+ CARD8 misc1;
+ CARD8 misc2;
+ int numTV;
+ int numCRTC1;
+ int numCRTC2;
+} VIABIOSTVMASKTableRec, *VIABIOSTVMASKTablePtr;
+
+struct CH7xxxTableRec {
+ char* name;
+ CARD16 Width;
+ CARD16 Height;
+ int Standard;
+
+ CARD8 TV[VIA_BIOS_TABLE_NUM_TV_REG]; /*35*/
+ CARD8 CRTC1[VIA_BIOS_MAX_NUM_TV_CRTC];
+ CARD8 Misc1[VIA_BIOS_NUM_TV_SPECIAL_REG];
+ CARD8 Misc2[VIA_BIOS_NUM_TV_SPECIAL_REG];
+/*merge these three*/
+ CARD8 CRTC2_8BPP[VIA_BIOS_MAX_NUM_TV_CRTC];
+ CARD8 CRTC2_16BPP[VIA_BIOS_MAX_NUM_TV_CRTC];
+ CARD8 CRTC2_32BPP[VIA_BIOS_MAX_NUM_TV_CRTC];
+ CARD16 Patch2[VIA_BIOS_MAX_NUM_TV_PATCH];
+ CARD16 DotCrawlNTSC[VIA_BIOS_NUM_TV_OTHER];
+};
+
+
+static struct CH7xxxTableRec
+CH7011Table[] = {
+ { "640x480", 640, 480, TVTYPE_NTSC,
+ { 0X6A, /* 0x00 Mode 17 */
+ 0X3F, /* 0x01 FF Default 0x27 (was 7F) */
+ 0X7E, /* 0x02 VBW Default 0xBE (was 0x7E) */
+ 0X8B, /* 0x03 TE Decent Text 0x8B (was 8D) */
+ 0X28, /* 0x04 SAV Default 0x50 (was 0x21) */
+ 0X2C, /* 0x05 HP Default 0x50 (was 0x2E) */
+ 0X05, /* 0x06 VP Default 0x00 (was 0x04) */
+ 0X83, /* 0x07 BL Default 0x83 */
+ 0X03, /* 0x08 CE Default 0x03 */
+ 0X80, /* 0x09 TPC Default 0x80 */
+ 0X3F, /* 0x0A PLLM Default 0x3F */
+ 0X7E, /* 0x0B PLLN Default 0x7E */
+ 0X20, /* 0x0C FSCI Default 0x20 */
+ 0X80, /* 0x0D FSCI Default 0x80 */
+ 0X00, /* 0x0E FSCI Default 0x08 (was 00) */
+ 0X00, /* 0x0F FSCI Default 0xEB (was 00) */
+ 0, /* 0x10 CIVC */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* We don't touch these */
+ 0X48, /* 0x1C */
+ 0X40, /* 0x1D */
+ 0XD2, /* 0x1E */
+ 0X80, /* 0x1F */
+ 0X40, /* 0x20 */
+ 0, /* 0x21 */
+ 0, /* 0x22 */ },
+ { 0X5D, 0X4F, 0X4F, 0X81, 0X52, 0X9E, 0X56, 0XBA, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X8, 0, 0XDF, 0, 0, 0XDF, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XEF, 0X57, 0XDF, 0XDF, 0X57, 0X11, 0XA, 0X8, 0X50, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XEF, 0X57, 0XDF, 0XDF, 0X57, 0X11, 0XA, 0X8, 0X50, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XEF, 0X57, 0XDF, 0XDF, 0X57, 0X11, 0XA, 0X8, 0X50, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X2284, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X2, 0X811, 0X9217, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ },
+
+ { "640x480", 640, 480, TVTYPE_PAL,
+ { 0X61, /* 0x00 PAL Mode 14 non-OS 640x480 1:1 */
+ 0X27, /* 0x01 FF Default 0x27 (was 7F) */
+ 0XBE, /* 0x02 VBW Default 0xBE (was 0x7E) */
+ 0X8B, /* 0x03 TE Decent Text 0x8B (was 8D) */
+ 0X28, /* 0x04 SAV Default 0x50 (was 0x21) */
+ 0X2C, /* 0x05 HP Default 0x50 (was 0x2E) */
+ 0X05, /* 0x06 VP Default 0x00 (was 0x04) */
+ 0X83, /* 0x07 BL Default 0x83 */
+ 0X01, /* 0x08 CE Default 0x03 */
+ 0X81, /* 0x09 TPC Default 0x80 */
+ 0X04, /* 0x0A PLLM Default 0x3F */
+ 0X09, /* 0x0B PLLN Default 0x7E */
+ 0X26, /* 0x0C FSCI Default 0x20 */
+ 0X6F, /* 0x0D FSCI Default 0x80 */
+ 0X1F, /* 0x0E FSCI Default 0x08 */
+ 0XD0, /* 0x0F FSCI Default 0xEB */
+ 0, /* 0x10 CIVC */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* We don't touch these */
+ 0X48, /* 0x1C */
+ 0X40, /* 0x1D */
+ 0XD2, /* 0x1E */
+ 0X80, /* 0x1F */
+ 0X40, /* 0x20 */
+ 0, /* 0x21 */
+ 0, /* 0x22 */ },
+ { 0X64, 0X4F, 0X4F, 0X88, 0X53, 0X83, 0X6F, 0XBA, 0, 0X40, 0, 0, 0, 0, 0, 0, 0X11, 0, 0XDF, 0, 0, 0XDF, 0X70, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0X1E, 0X70, 0XDF, 0XDF, 0X70, 0X51, 0XA, 0X11, 0X5D, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0X1E, 0X70, 0XDF, 0XDF, 0X70, 0X51, 0XA, 0X11, 0X5D, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0X1E, 0X70, 0XDF, 0XDF, 0X70, 0X51, 0XA, 0X11, 0X5D, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X3284, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ },
+
+ { "800x600", 800, 600, TVTYPE_NTSC,
+ { 0XCF, /* 0x00 Mode 29 */
+ 0X27, /* 0x01 FF Default 0x27 (was 7F) */
+ 0XBE, /* 0x02 VBW Default 0xBE (was 0x76) */
+ 0X8B, /* 0x03 TE Decent Text 0x8B (was 8F) */
+ 0X59, /* 0x04 SAV*/
+ 0X3C, /* 0x05 HP */
+ 0X15, /* 0x06 VP */
+ 0X66, /* 0x07 BL Default 0x83 */
+ 0X3, /* 0x08 CE Default 0x03 */
+ 0X88,
+ 0X59,
+ 0X2E,
+ 0X19,
+ 0X8B,
+ 0X3A,
+ 0X63,
+ 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0X48,
+ 0X40,
+ 0XD2,
+ 0X80,
+ 0X40,
+ 0,
+ 0, },
+ { 0X80, 0X63, 0X63, 0X84, 0X69, 0X1A, 0XEC, 0XF0, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X5C, 0, 0X57, 0, 0, 0X57, 0XED, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0X27, 0X1F, 0X1F, 0X27, 0XE3, 0X34, 0X48, 0XD6, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X5C, 0X5D, 0, 0, 0, 0, 0, 0X32, 0X64, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X27, 0X1F, 0X1F, 0X27, 0XE3, 0X34, 0X48, 0XD6, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X5C, 0X5D, 0, 0, 0, 0, 0, 0X64, 0XC8, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X27, 0X1F, 0X1F, 0X27, 0XE3, 0X34, 0X48, 0XD6, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X5C, 0X5D, 0, 0, 0, 0, 0, 0XC8, 0X90, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X5A84, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X2, 0X811, 0X5117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ },
+
+ { "800x600", 800, 600, TVTYPE_PAL,
+ { 0XC3, 0X7F, 0XE0, 0X8F, 0X39, 0X3F, 0X38, 0X70, 0X3, 0X81, 0X21, 0X56, 0X1F, 0X87, 0X28, 0X18,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80,
+ 0X40, 0, 0, },
+ { 0X73, 0X63, 0X63, 0X97, 0X67, 0X91, 0XEC, 0XF0, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X7E, 0, 0X57, 0, 0, 0X57, 0XED, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0XBF, 0X1F, 0X1F, 0XBF, 0XDB, 0X33, 0X38, 0X8E, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X74, 0X4D, 0, 0, 0, 0, 0, 0X32, 0X64, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XBF, 0X1F, 0X1F, 0XBF, 0XDB, 0X33, 0X38, 0X8E, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X74, 0X4D, 0, 0, 0, 0, 0, 0X64, 0XC8, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XBF, 0X1F, 0X1F, 0XBF, 0XDB, 0X33, 0X38, 0X8E, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X74, 0X4D, 0, 0, 0, 0, 0, 0XC8, 0X90, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X3A84, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ },
+
+/*check these two modes*/
+ { "1024x768", 1024, 768, TVTYPE_NTSC,
+ { 0XEE,
+ 0X3F, /* 0x01 FF Default 0x27 (was 7F) */
+ 0X7E,
+ 0X87,
+ 0X49,
+ 0X32,
+ 0X9,
+ 0X83,
+ 0X3,
+ 0X88,
+ 0X47,
+ 0X4D,
+ 0X1B,
+ 0XE4,
+ 0X89,
+ 0X51,
+ 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0X48,
+ 0X40,
+ 0XD2,
+ 0X80,
+ 0X40,
+ 0,
+ 0, },
+ { 0X8C, 0X7F, 0X7F, 0X90, 0X81, 0X8, 0XAF, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0XC, 0, 0XFF, 0, 0, 0XFF, 0XB0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0X40, 0X80, 0XE, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X3F, 0XB0, 0XFF, 0XFF, 0XB0, 0X9A, 0X13, 0XC, 0X7A, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X3F, 0XB0, 0XFF, 0XFF, 0XB0, 0X9A, 0X13, 0XC, 0X7A, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X3F, 0XB0, 0XFF, 0XFF, 0XB0, 0X9A, 0X13, 0XC, 0X7A, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X4A84, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X2, 0X811, 0X6717, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ },
+
+ { "1024x768", 1024, 768, TVTYPE_PAL,
+ { 0XE5, 0X7F, 0XE0, 0X8F, 0XC1, 0X3E, 0X4A, 0X70, 0, 0X81, 0X7, 0X2A, 0X20, 0X6D, 0XC2, 0XD7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80,
+ 0X40, 0, 0, },
+ { 0XAA, 0X7F, 0X7F, 0X8E, 0X83, 0X97, 0XE6, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X11, 0, 0XFF, 0, 0, 0XFF, 0XE7, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0X40, 0X80, 0XE, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XBE, 0XE7, 0XFF, 0XFF, 0XE7, 0X9A, 0X13, 0X7, 0X7B, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X8E, 0, 0, 0 },
+ { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XBE, 0XE7, 0XFF, 0XFF, 0XE7, 0X9A, 0X13, 0X7, 0X7B, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X8E, 0, 0, 0 },
+ { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XBE, 0XE7, 0XFF, 0XFF, 0XE7, 0X9A, 0X13, 0X7, 0X7B, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X8E, 0, 0, 0 },
+ { 0XC284, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ },
+
+ { "640x480Over", 640, 480, TVTYPE_NTSC,
+ { 0X69, /* 0x00 DM Mode 16 640x480 1/1 */
+ 0X3F, /* 0x01 FF Default 0x27 (was 7F) */
+ 0X7E, /* 0x02 VBW Default 0xBE (was 7E) */
+ 0X03, /* 0x03 TE Decent text 0x83 (was 8D) */
+ 0X18, /* 0x04 SAV Default 0x50 (was 10) */
+ 0X19, /* 0x05 HP Default 0x50 */
+ 0XFB, /* 0x06 VP Default 0x00 */
+ 0X83, /* 0x07 BL Default 0x83 (NTSC-J 66) */
+ 0X03, /* 0x08 CE Default 0x03 */
+ 0X80, /* 0x09 TPC Default 0x80 */
+ 0X3F, /* 0x0A PLLM Default 0x3F */
+ 0X6E, /* 0x0B PLLN Default 0x7E */
+ 0X25, /* 0x0C FSCI Default 0x25 */
+ 0X24, /* 0x0D FSCI Default 0x24 */
+ 0X92, /* 0x0E FSCI Default 0x9C (was 92) */
+ 0X49, /* 0x0F FSCI Default 0x7A (was 49) */
+ 0X00, /* 0x10 CIVC Default 0x01 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* We don't touch these */
+ 0X48, /* 0x1C CM Default 0x00 */
+ 0X40, /* 0x1D IC Default 0x88 */
+ 0XD2, /* 0x1E GPIO Default 0xC0 */
+ 0X80, /* 0x1F IDF Default 0x00 */
+ 0X40, /* 0x20 CD */
+ 0X00, /* 0x21 DC */
+ 0X00, /* 0x22 BCO Default 0x00 */ },
+/* why is this #ifed, what's the difference? */
+#if 0
+ { 0X55, 0X4F, 0X4F, 0X99, 0X51, 0X18, 0X2E, 0X3E, 0, 0X40, 0, 0, 0, 0, 0, 0, 0XE7, 0, 0XDF, 0, 0, 0XDF, 0X2F, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X20, 0X40, 0, 0, 0X87, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X87, 0X1C, 0, 0, 0 },
+ { 0XCF, 0X7F, 0X7F, 0XCF, 0X92, 0X22, 0X87, 0XBC, 0X2F, 0XDF, 0XDF, 0X2F, 0X11, 0XA, 0XFF, 0X24, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0, 0X80, 0, 0, 0 },
+ { 0XCF, 0X7F, 0X7F, 0XCF, 0X92, 0X22, 0X87, 0XBC, 0X2F, 0XDF, 0XDF, 0X2F, 0X11, 0XA, 0XFF, 0X24, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0, 0X80, 0, 0, 0 },
+ { 0XCF, 0X7F, 0X7F, 0XCF, 0X92, 0X22, 0X87, 0XBC, 0X2F, 0XDF, 0XDF, 0X2F, 0X11, 0XA, 0XFF, 0X24, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0, 0X80, 0, 0, 0 },
+ { 0X7107, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X3, 0X811, 0XF416, 0X9F17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+#else
+ { 0X5D, 0X4F, 0X4F, 0X81, 0X52, 0X9E, 0XB, 0X3E, 0, 0X60, 0, 0, 0, 0, 0, 0, 0XEE, 0, 0XDF, 0, 0, 0XDF, 0XC, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XFF, 0XC, 0XDF, 0XDF, 0XC, 0X11, 0XA, 0XEE, 0X31, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XFF, 0XC, 0XDF, 0XDF, 0XC, 0X11, 0XA, 0XEE, 0X31, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XFF, 0XC, 0XDF, 0XDF, 0XC, 0X11, 0XA, 0XEE, 0X31, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X1184, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X2, 0X811, 0XAD17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+#endif
+ },
+
+ { "640x480Over", 640, 480, TVTYPE_PAL,
+ { 0X60, /* 0x00 DM Mode 13 PAL 640x480 OS 5/4 */
+ 0X27, /* 0x01 FF Default 0x27 (was 7F) */
+ 0XBE, /* 0x02 VBW Default 0xBE (was 7E) */
+ 0X83, /* 0x03 TE Decent text 0x8B (was 8D) */
+ 0X10, /* 0x04 SAV Default 0x50 */
+ 0X19, /* 0x05 HP Default 0x50 */
+ 0XFB, /* 0x06 VP Default 0x00 */
+ 0X83, /* 0x07 BL Default 0x83 */
+ 0X01, /* 0x08 CE Default 0x03 */
+ 0X81, /* 0x09 TPC Default 0x80 */
+ 0X0D, /* 0x0A PLLM Default 0x3F */
+ 0X0B, /* 0x0B PLLN Default 0x7E */
+ 0X30, /* 0x0C FSCI Default 0x25 */
+ 0X0A, /* 0x0D FSCI Default 0x24 */
+ 0XE7, /* 0x0E FSCI Default 0x9C */
+ 0XC4, /* 0x0F FSCI Default 0x7A */
+ 0X00, /* 0x10 CIVC Default 0x01 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* We don't touch these */
+ 0X48, /* 0x1C CM Default 0x00 */
+ 0X40, /* 0x1D IC Default 0x88 */
+ 0XD2, /* 0x1E GPIO Default 0xC0 */
+ 0X80, /* 0x1F IDF Default 0x00 */
+ 0X40, /* 0x20 CD */
+ 0X00, /* 0x21 DC */
+ 0X00, /* 0x22 BCO Default 0x00 */ },
+ { 0X64, 0X4F, 0X4F, 0X88, 0X53, 0X83, 0XF2, 0X1F, 0, 0X40, 0, 0, 0, 0, 0, 0, 0XE5, 0, 0XDF, 0, 0, 0XDF, 0XF3, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0XFF, 0XF3, 0XDF, 0XDF, 0XF3, 0X9, 0X9, 0XE5, 0X40, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0XFF, 0XF3, 0XDF, 0XDF, 0XF3, 0X9, 0X9, 0XE5, 0X40, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0XFF, 0XF3, 0XDF, 0XDF, 0XF3, 0X9, 0X9, 0XE5, 0X40, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X3184, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ },
+
+ { "800x600Over", 800, 600, TVTYPE_NTSC,
+ { 0XCE, /* 0x00 Mode 28 */
+ 0X27, /* 0x01 Default 0x27 (was 7F) */
+ 0XBE, /* 0x02 Default 0xBE (was 76) */
+ 0X8F, /* 0x03 */
+ 0X51, /* 0x04 */
+ 0X2E, /* 0x05 */
+ 0X10, /* 0x06 */
+ 0X83, /* 0x07 */
+ 0X3, /* 0x08 */
+ 0X81, /* 0x09 */
+ 0X13, /* 0x0A */
+ 0X3E, /* 0x0B */
+ 0X1C, /* 0x0C */
+ 0, /* 0x0D */
+ 0, /* 0x0E */
+ 0, /* 0x0F */
+ 0, /* 0x10 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0X48,
+ 0X40,
+ 0XD2,
+ 0X80,
+ 0X40, 0, 0, },
+ { 0X7D, 0X63, 0X63, 0X81, 0X69, 0X18, 0XBA, 0XF0, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X5A, 0, 0X57, 0, 0, 0X57, 0XBB, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0XF, 0X1F, 0X1F, 0XF, 0XE3, 0X34, 0X44, 0XC6, 0XBB, 0X57, 0X57, 0XBB, 0X52, 0X12, 0X3F, 0X59, 0, 0, 0, 0, 0, 0X32, 0X64, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XF, 0X1F, 0X1F, 0XF, 0XE3, 0X34, 0X44, 0XC6, 0XBB, 0X57, 0X57, 0XBB, 0X52, 0X12, 0X3F, 0X59, 0, 0, 0, 0, 0, 0X64, 0XC8, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XF, 0X1F, 0X1F, 0XF, 0XE3, 0X34, 0X44, 0XC6, 0XBB, 0X57, 0X57, 0XBB, 0X52, 0X12, 0X3F, 0X59, 0, 0, 0, 0, 0, 0XC8, 0X90, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X5284, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X2, 0X811, 0XD017, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ },
+
+ { "800x600Over", 800, 600, TVTYPE_PAL,
+ { 0XC1, 0X7F, 0XE0, 0X8F, 0X20, 0X1D, 0X36, 0X70, 0X3, 0X94, 0X39, 0X87, 0X26, 0X79, 0X8C, 0XC,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80,
+ 0X40, 0, 0, },
+ { 0X71, 0X63, 0X63, 0X95, 0X67, 0X90, 0X6F, 0XF0, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X57, 0, 0X57, 0, 0, 0X57, 0X70, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0XAF, 0X1F, 0X1F, 0XAF, 0XDB, 0X33, 0X35, 0X8E, 0X70, 0X57, 0X57, 0X70, 0X52, 0X12, 0X57, 0X5A, 0, 0, 0, 0, 0, 0X32, 0X64, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XAF, 0X1F, 0X1F, 0XAF, 0XDB, 0X33, 0X35, 0X8E, 0X70, 0X57, 0X57, 0X70, 0X52, 0X12, 0X57, 0X5A, 0, 0, 0, 0, 0, 0X64, 0XC8, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XAF, 0X1F, 0X1F, 0XAF, 0XDB, 0X33, 0X35, 0X8E, 0X70, 0X57, 0X57, 0X70, 0X52, 0X12, 0X57, 0X5A, 0, 0, 0, 0, 0, 0XC8, 0X90, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X2184, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ },
+
+ { "1024x768Over", 1024, 768, TVTYPE_NTSC,
+ { 0XED,
+ 0X3F, /* 0x01 FF Default 0x27 (was 7F) */
+ 0X7E,
+ 0X87,
+ 0X49,
+ 0X20,
+ 0,
+ 0X83,
+ 0X3,
+ 0X90,
+ 0X89,
+ 0X35,
+ 0X1F,
+ 0X61,
+ 0X1A,
+ 0X7C,
+ 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0X48,
+ 0X40,
+ 0XD2,
+ 0X80,
+ 0X40,
+ 0,
+ 0, },
+ { 0X8C, 0X7F, 0X7F, 0X90, 0X81, 0X8, 0X46, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X4, 0, 0XFF, 0, 0, 0XFF, 0X47, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X38, 0X47, 0XFF, 0XFF, 0X47, 0X9A, 0X13, 0X4, 0X6F, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X38, 0X47, 0XFF, 0XFF, 0X47, 0X9A, 0X13, 0X4, 0X6F, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X38, 0X47, 0XFF, 0XFF, 0X47, 0X9A, 0X13, 0X4, 0X6F, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X5084, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X2, 0X811, 0X4517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ },
+
+ { "1024x768Over", 1024, 768, TVTYPE_PAL,
+ { 0XE4, 0X7F, 0XA0, 0X8F, 0XB1, 0X28, 0X37, 0X70, 0, 0X81, 0X10, 0X4C, 0X25, 0XF, 0XBA, 0X1B,
+ 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80,
+ 0X40, 0, 0, },
+ { 0XAA, 0X7F, 0X7F, 0X8E, 0X84, 0X97, 0X69, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X7, 0, 0XFF, 0, 0, 0XFF, 0X6A, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XB184, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ },
+
+ { "720x480", 720, 480, TVTYPE_NTSC,
+ { 0X89, /* 0x00 DM Mode 19 720x480 1/1 */
+ 0X3F, /* 0x01 FF Default 0x27 (was 7F) */
+ 0X7E, /* 0x02 VBW Default 0xBE (was 7E) */
+ 0X03, /* 0x03 TE Decent text 0x83 (was 8D) */
+ 0X18, /* 0x04 SAV Default 0x50 (was 10) */
+ 0X19, /* 0x05 HP Default 0x50 */
+ 0XFB, /* 0x06 VP Default 0x00 */
+ 0X83, /* 0x07 BL Default 0x83 (NTSC-J 66) */
+ 0X03, /* 0x08 CE Default 0x03 */
+ 0X80, /* 0x09 TPC Default 0x80 */
+ 0X3F, /* 0x0A PLLM Default 0x3F */
+ 0X7C, /* 0x0B PLLN Default 0x7C */
+ 0X21, /* 0x0C FSCI Default 0x25 */
+ 0X04, /* 0x0D FSCI Default 0x04 */
+ 0X10, /* 0x0E FSCI Default 0x10 */
+ 0X41, /* 0x0F FSCI Default 0x41 */
+ 0X00, /* 0x10 CIVC Default 0x01 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* We don't touch these */
+ 0X48, /* 0x1C CM Default 0x00 */
+ 0X40, /* 0x1D IC Default 0x88 */
+ 0XD2, /* 0x1E GPIO Default 0xC0 */
+ 0X80, /* 0x1F IDF Default 0x00 */
+ 0X40, /* 0x20 CD */
+ 0X00, /* 0x21 DC */
+ 0X00, /* 0x22 BCO Default 0x00 */ },
+ { 0X64, 0X59, 0X59, 0X88, 0X5B, 0X81, 0X56, 0X3E, 0, 0X40, 0, 0, 0, 0, 0, 0, 0XFF, 0, 0XDF, 0, 0, 0XDF, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X20, 0X40, 0, 0X4, 0X87, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X87, 0X1C, 0, 0, 0 },
+ { 0X47, 0XCF, 0XCF, 0X47, 0X9A, 0X23, 0XD9, 0XA, 0X57, 0XDF, 0XDF, 0X57, 0X51, 0XA, 0XFF, 0X3B, 0, 0, 0, 0, 0, 0X2D, 0X5A, 0, 0, 0, 0X80, 0, 0X80, 0, 0, 0 },
+ { 0X47, 0XCF, 0XCF, 0X47, 0X9A, 0X23, 0XD9, 0XA, 0X57, 0XDF, 0XDF, 0X57, 0X51, 0XA, 0XFF, 0X3B, 0, 0, 0, 0, 0, 0X5A, 0XB4, 0X40, 0, 0, 0X80, 0, 0X80, 0, 0, 0 },
+ { 0X47, 0XCF, 0XCF, 0X47, 0X9A, 0X23, 0XD9, 0XA, 0X57, 0XDF, 0XDF, 0X57, 0X51, 0XA, 0XFF, 0X3B, 0, 0, 0, 0, 0, 0XB4, 0X68, 0X81, 0, 0, 0X80, 0, 0X80, 0, 0, 0 },
+ { 0X6E07, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X3, 0X811, 0XC316, 0X4C17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ },
+
+/* don't we want 720x576 for pal? */
+ { "720x480", 720, 480, TVTYPE_PAL,
+ { 0XE4, 0X7F, 0XA0, 0X8F, 0XB1, 0X28, 0X37, 0X70, 0, 0X81, 0X10, 0X4C, 0X25, 0XF, 0XBA, 0X1B,
+ 0X1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80,
+ 0X40, 0, 0, },
+ { 0XAA, 0X7F, 0X7F, 0X8E, 0X84, 0X97, 0X69, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X7, 0, 0XFF, 0, 0, 0XFF, 0X6A, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XB184, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ },
+};
+
+static struct CH7xxxTableRec
+CH7019Table[] = {
+ { "640x480", 640, 480, TVTYPE_NTSC,
+ { 0X6A, 0X7F, 0X7E, 0X8D, 0X21, 0X2E, 0X4, 0X83, 0X3, 0X80, 0X3F, 0X7E, 0X20, 0X80, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80,
+ 0X40, 0, 0 },
+ { 0X5D, 0X4F, 0X4F, 0X81, 0X52, 0X9E, 0X56, 0XBA, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X8, 0, 0XDF, 0, 0, 0XDF, 0X57, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XEF, 0X57, 0XDF, 0XDF, 0X57, 0X11, 0XA, 0X8, 0X50, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XEF, 0X57, 0XDF, 0XDF, 0X57, 0X11, 0XA, 0X8, 0X50, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XEF, 0X57, 0XDF, 0XDF, 0X57, 0X11, 0XA, 0X8, 0X50, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X2284, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X2, 0X811, 0X9217, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ },
+
+ { "640x480", 640, 480, TVTYPE_PAL,
+ { 0X61, 0X7F, 0XE0, 0X8F, 0X31, 0X35, 0X33, 0X6E, 0X3, 0X81, 0X4, 0X9, 0X26, 0X6F, 0X1F, 0XD0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0X48, 0X40, 0XD2, 0X80,
+ 0X40, 0, 0 },
+ { 0X64, 0X4F, 0X4F, 0X88, 0X53, 0X83, 0X6F, 0XBA, 0, 0X40, 0, 0, 0, 0, 0, 0, 0X11, 0, 0XDF, 0, 0, 0XDF, 0X70, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0X1E, 0X70, 0XDF, 0XDF, 0X70, 0X51, 0XA, 0X11, 0X5D, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0X1E, 0X70, 0XDF, 0XDF, 0X70, 0X51, 0XA, 0X11, 0X5D, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0X1E, 0X70, 0XDF, 0XDF, 0X70, 0X51, 0XA, 0X11, 0X5D, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X3284, 0, 0, 0, 0, 0, 0, 0 },
+ },
+
+ { "800x600", 800, 600, TVTYPE_NTSC,
+ { 0XCF, 0X7F, 0X76, 0X8F, 0X59, 0X3C, 0X15, 0X83, 0X3, 0X88, 0X59, 0X2E, 0X19, 0X8B, 0X3A, 0X63,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80,
+ 0X40, 0, 0},
+ { 0X80, 0X63, 0X63, 0X84, 0X69, 0X1A, 0XEC, 0XF0, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X5C, 0, 0X57, 0, 0, 0X57, 0XED, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0X27, 0X1F, 0X1F, 0X27, 0XE3, 0X34, 0X48, 0XD6, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X5C, 0X5D, 0, 0, 0, 0, 0, 0X32, 0X64, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X27, 0X1F, 0X1F, 0X27, 0XE3, 0X34, 0X48, 0XD6, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X5C, 0X5D, 0, 0, 0, 0, 0, 0X64, 0XC8, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X27, 0X1F, 0X1F, 0X27, 0XE3, 0X34, 0X48, 0XD6, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X5C, 0X5D, 0, 0, 0, 0, 0, 0XC8, 0X90, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X5A84, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X2, 0X811, 0X5117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ },
+
+ { "800x600", 800, 600, TVTYPE_PAL,
+ { 0XC3, 0X7F, 0XE0, 0X8F, 0X39, 0X3F, 0X38, 0X70, 0X3, 0X81, 0X21, 0X56, 0X1F, 0X87, 0X28, 0X18,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80,
+ 0X40, 0, 0},
+ { 0X73, 0X63, 0X63, 0X97, 0X67, 0X91, 0XEC, 0XF0, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X7E, 0, 0X57, 0, 0, 0X57, 0XED, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0XBF, 0X1F, 0X1F, 0XBF, 0XDB, 0X33, 0X38, 0X8E, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X74, 0X4D, 0, 0, 0, 0, 0, 0X32, 0X64, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XBF, 0X1F, 0X1F, 0XBF, 0XDB, 0X33, 0X38, 0X8E, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X74, 0X4D, 0, 0, 0, 0, 0, 0X64, 0XC8, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XBF, 0X1F, 0X1F, 0XBF, 0XDB, 0X33, 0X38, 0X8E, 0XED, 0X57, 0X57, 0XED, 0X52, 0X12, 0X74, 0X4D, 0, 0, 0, 0, 0, 0XC8, 0X90, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X3A84, 0, 0, 0, 0, 0, 0, 0 },
+ },
+
+ { "1024x768", 1024, 768, TVTYPE_NTSC,
+ { 0XEE, 0X7F, 0X7E, 0X87, 0X49, 0X32, 0X9, 0X83, 0X3, 0X88, 0X47, 0X4D, 0X1B, 0XE4, 0X89, 0X51,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80,
+ 0X40, 0, 0},
+ { 0X8C, 0X7F, 0X7F, 0X90, 0X81, 0X8, 0XAF, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0XC, 0, 0XFF, 0, 0, 0XFF, 0XB0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0X40, 0X80, 0XE, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X3F, 0XB0, 0XFF, 0XFF, 0XB0, 0X9A, 0X13, 0XC, 0X7A, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X3F, 0XB0, 0XFF, 0XFF, 0XB0, 0X9A, 0X13, 0XC, 0X7A, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X3F, 0XB0, 0XFF, 0XFF, 0XB0, 0X9A, 0X13, 0XC, 0X7A, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X4A84, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X2, 0X811, 0X6717, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+
+ { "1024x768", 1024, 768, TVTYPE_PAL,
+ { 0XE5, 0X7F, 0XE0, 0X8F, 0XC1, 0X3E, 0X4A, 0X70, 0, 0X81, 0X7, 0X2A, 0X20, 0X6D, 0XC2, 0XD7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80,
+ 0X40, 0, 0},
+ { 0XAA, 0X7F, 0X7F, 0X8E, 0X83, 0X97, 0XE6, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X11, 0, 0XFF, 0, 0, 0XFF, 0XE7, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0X40, 0X80, 0XE, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XBE, 0XE7, 0XFF, 0XFF, 0XE7, 0X9A, 0X13, 0X7, 0X7B, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X8E, 0, 0, 0 },
+ { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XBE, 0XE7, 0XFF, 0XFF, 0XE7, 0X9A, 0X13, 0X7, 0X7B, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X8E, 0, 0, 0 },
+ { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XBE, 0XE7, 0XFF, 0XFF, 0XE7, 0X9A, 0X13, 0X7, 0X7B, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X8E, 0, 0, 0 },
+ { 0XC284, 0, 0, 0, 0, 0, 0, 0 },
+ },
+
+ { "640x480Over", 640, 480, TVTYPE_NTSC,
+ { 0X69, 0X7F, 0X7E, 0X8D, 0X10, 0X19, 0, 0X83, 0X3, 0X80, 0X3F, 0X6E, 0X25, 0X24, 0X92, 0X49,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80,
+ 0X40, 0, 0},
+ { 0X5D, 0X4F, 0X4F, 0X81, 0X52, 0X9E, 0XB, 0X3E, 0, 0X60, 0, 0, 0, 0, 0, 0, 0XEE, 0, 0XDF, 0, 0, 0XDF, 0XC, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XFF, 0XC, 0XDF, 0XDF, 0XC, 0X11, 0XA, 0XEE, 0X31, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XFF, 0XC, 0XDF, 0XDF, 0XC, 0X11, 0XA, 0XEE, 0X31, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XF, 0X7F, 0X7F, 0XF, 0X9A, 0X23, 0X8F, 0XFF, 0XC, 0XDF, 0XDF, 0XC, 0X11, 0XA, 0XEE, 0X31, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X1184, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X2, 0X811, 0XAD17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+
+ { "640x480Over", 640, 480, TVTYPE_PAL,
+ { 0X60, 0X7F, 0XE0, 0X8F, 0X31, 0X1B, 0X2D, 0X6E, 0X3, 0X81, 0XD, 0X14, 0X30, 0XA, 0XE7, 0XC4,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80,
+ 0X40, 0, 0},
+ { 0X64, 0X4F, 0X4F, 0X88, 0X53, 0X83, 0XF2, 0X1F, 0, 0X40, 0, 0, 0, 0, 0, 0, 0XE5, 0, 0XDF, 0, 0, 0XDF, 0XF3, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0XFF, 0XF3, 0XDF, 0XDF, 0XF3, 0X9, 0X9, 0XE5, 0X40, 0, 0, 0, 0, 0, 0X28, 0X50, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0XFF, 0XF3, 0XDF, 0XDF, 0XF3, 0X9, 0X9, 0XE5, 0X40, 0, 0, 0, 0, 0, 0X50, 0XA0, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X47, 0X7F, 0X7F, 0X47, 0X9A, 0X23, 0X95, 0XFF, 0XF3, 0XDF, 0XDF, 0XF3, 0X9, 0X9, 0XE5, 0X40, 0, 0, 0, 0, 0, 0XA0, 0X40, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X3184, 0, 0, 0, 0, 0, 0, 0 },
+ },
+
+ { "800x600Over", 800, 600, TVTYPE_NTSC,
+ { 0XCE, 0X7F, 0X76, 0X8F, 0X51, 0X2E, 0X10, 0X83, 0X3, 0X81, 0X13, 0X3E, 0X1C,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80,
+ 0X40, 0, 0},
+ { 0X7D, 0X63, 0X63, 0X81, 0X69, 0X18, 0XBA, 0XF0, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X5A, 0, 0X57, 0, 0, 0X57, 0XBB, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0XF, 0X1F, 0X1F, 0XF, 0XE3, 0X34, 0X44, 0XC6, 0XBB, 0X57, 0X57, 0XBB, 0X52, 0X12, 0X3F, 0X59, 0, 0, 0, 0, 0, 0X32, 0X64, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XF, 0X1F, 0X1F, 0XF, 0XE3, 0X34, 0X44, 0XC6, 0XBB, 0X57, 0X57, 0XBB, 0X52, 0X12, 0X3F, 0X59, 0, 0, 0, 0, 0, 0X64, 0XC8, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XF, 0X1F, 0X1F, 0XF, 0XE3, 0X34, 0X44, 0XC6, 0XBB, 0X57, 0X57, 0XBB, 0X52, 0X12, 0X3F, 0X59, 0, 0, 0, 0, 0, 0XC8, 0X90, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X5284, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X2, 0X811, 0XD017, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+
+ { "800x600Over", 800, 600, TVTYPE_PAL,
+ { 0XC1, 0X7F, 0XE0, 0X8F, 0X20, 0X1D, 0X36, 0X70, 0X3, 0X94, 0X39, 0X87, 0X26, 0X79, 0X8C, 0XC,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80,
+ 0X40, 0, 0},
+ { 0X71, 0X63, 0X63, 0X95, 0X67, 0X90, 0X6F, 0XF0, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X57, 0, 0X57, 0, 0, 0X57, 0X70, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X20, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0XAF, 0X1F, 0X1F, 0XAF, 0XDB, 0X33, 0X35, 0X8E, 0X70, 0X57, 0X57, 0X70, 0X52, 0X12, 0X57, 0X5A, 0, 0, 0, 0, 0, 0X32, 0X64, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XAF, 0X1F, 0X1F, 0XAF, 0XDB, 0X33, 0X35, 0X8E, 0X70, 0X57, 0X57, 0X70, 0X52, 0X12, 0X57, 0X5A, 0, 0, 0, 0, 0, 0X64, 0XC8, 0X40, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XAF, 0X1F, 0X1F, 0XAF, 0XDB, 0X33, 0X35, 0X8E, 0X70, 0X57, 0X57, 0X70, 0X52, 0X12, 0X57, 0X5A, 0, 0, 0, 0, 0, 0XC8, 0X90, 0X81, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X2184, 0, 0, 0, 0, 0, 0, 0 },
+ },
+
+ { "1024x768Over", 1024, 768, TVTYPE_NTSC,
+ { 0XED, 0X7F, 0X7E, 0X87, 0X49, 0X20, 0, 0X83, 0X3, 0X90, 0X89, 0X35, 0X1F, 0X61, 0X1A, 0X7C,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80,
+ 0X40, 0, 0},
+ { 0X8C, 0X7F, 0X7F, 0X90, 0X81, 0X8, 0X46, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X4, 0, 0XFF, 0, 0, 0XFF, 0X47, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X38, 0X47, 0XFF, 0XFF, 0X47, 0X9A, 0X13, 0X4, 0X6F, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X38, 0X47, 0XFF, 0XFF, 0X47, 0X9A, 0X13, 0X4, 0X6F, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X87, 0XFF, 0XFF, 0X87, 0X23, 0X34, 0X9, 0X38, 0X47, 0XFF, 0XFF, 0X47, 0X9A, 0X13, 0X4, 0X6F, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X5084, 0, 0, 0, 0, 0, 0, 0 },
+ { 0X2, 0X811, 0X4517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+
+ { "1024x768Over", 1024, 768, TVTYPE_PAL,
+ { 0XE4, 0X7F, 0XA0, 0X8F, 0XB1, 0X28, 0X37, 0X70, 0, 0X81, 0X10, 0X4C, 0X25, 0XF, 0XBA, 0X1B, 0X1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0X48, 0X40, 0XD2, 0X80,
+ 0X40, 0, 0},
+ { 0XAA, 0X7F, 0X7F, 0X8E, 0X84, 0X97, 0X69, 0XF5, 0, 0X60, 0, 0, 0, 0, 0, 0, 0X7, 0, 0XFF, 0, 0, 0XFF, 0X6A, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0X40, 0X80, 0, 0X47, 0X1C, 0, 0 },
+ { 0, 0, 0, 0X47, 0X1C, 0, 0, 0 },
+ { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0X40, 0X80, 0, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0X80, 0, 0X41, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0X77, 0XFF, 0XFF, 0X77, 0X2B, 0X35, 0X1B, 0XB7, 0X6A, 0XFF, 0XFF, 0X6A, 0X9A, 0X13, 0X7, 0X77, 0, 0, 0, 0, 0, 0, 0, 0X86, 0, 0, 0X80, 0X20, 0X90, 0, 0, 0 },
+ { 0XB184, 0, 0, 0, 0, 0, 0, 0 },
+ }
+};
+
+static const VIABIOSTVMASKTableRec ch7011MaskTable = {
+ { 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
+ 0XFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0XFF, 0XFF, 0XFF, 0XFF,
+ 0XFF, 0XFF, 0XFF },
+ { 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0, 0XFF, 0, 0, 0, 0, 0, 0,
+ 0XFF, 0, 0XFF, 0, 0, 0XFF, 0XFF, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
+ 0, 0, 0, 0, 0, 0XFF, 0XFF, 0XFF, 0, 0, 0XFF, 0XFF, 0XFF, 0, 0, 0 },
+ 0X3F, 0X38,24,13,22
+};
+
+static const VIABIOSTVMASKTableRec ch7019MaskTable = {
+ { 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
+ 0XFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0XFF, 0XFF, 0XFF, 0XFF,
+ 0XFF, 0XFF, 0XFF },
+ { 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0, 0XFF, 0, 0, 0, 0, 0, 0,
+ 0XFF, 0, 0XFF, 0, 0, 0XFF, 0XFF, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
+ 0, 0, 0, 0, 0, 0XFF, 0XFF, 0XFF, 0, 0, 0XFF, 0XFF, 0XFF, 0, 0, 0 },
+ 0X3F, 0X38,24,13,22
+};
+
+#endif
diff --git a/src/via_cursor.c b/src/via_cursor.c
new file mode 100644
index 000000000000..35acb6661299
--- /dev/null
+++ b/src/via_cursor.c
@@ -0,0 +1,228 @@
+/*
+ * 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.
+ */
+
+/*************************************************************************
+ *
+ * File: via_cursor.c
+ * Content: Hardware cursor support for VIA/S3G UniChrome
+ *
+ ************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "via.h"
+#include "via_driver.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);
+
+#define MAX_CURS 32
+
+Bool
+VIAHWCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAHWCursorInit\n"));
+ infoPtr = xf86CreateCursorInfoRec();
+ if (!infoPtr)
+ return FALSE;
+
+ pVia->CursorInfoRec = infoPtr;
+
+ infoPtr->MaxWidth = MAX_CURS;
+ infoPtr->MaxHeight = MAX_CURS;
+ infoPtr->Flags = HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 |
+ 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;
+
+ if (!pVia->CursorStart) {
+ pVia->CursorStart = pVia->FBFreeEnd - VIA_CURSOR_SIZE;
+ pVia->FBFreeEnd -= VIA_CURSOR_SIZE;
+ }
+
+ /* Set cursor location in frame buffer. */
+ VIASETREG(VIA_REG_CURSOR_MODE, pVia->CursorStart);
+
+ return xf86InitCursor(pScreen, infoPtr);
+}
+
+
+
+void
+VIAShowCursor(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ CARD32 dwCursorMode;
+
+ dwCursorMode = VIAGETREG(VIA_REG_CURSOR_MODE);
+
+ /* Turn on Hardware Cursor */
+ VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode | 0x3);
+}
+
+
+void
+VIAHideCursor(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ CARD32 dwCursorMode;
+
+ dwCursorMode = VIAGETREG(VIA_REG_CURSOR_MODE);
+
+ /* Turn cursor off. */
+ VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode & 0xFFFFFFFE);
+}
+
+
+static void
+VIALoadCursorImage(ScrnInfoPtr pScrn, unsigned char* src)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ CARD32 dwCursorMode;
+
+ viaAccelSync(pScrn);
+
+ dwCursorMode = VIAGETREG(VIA_REG_CURSOR_MODE);
+
+ /* Turn cursor off. */
+ VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode & 0xFFFFFFFE);
+
+ /* Upload the cursor image to the frame buffer. */
+ memcpy(pVia->FBBase + pVia->CursorStart, src, MAX_CURS * MAX_CURS / 8 * 2);
+
+ /* Restore cursor status */
+ VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode);
+}
+
+static void
+VIASetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+ unsigned char xoff, yoff;
+ CARD32 dwCursorMode;
+
+ if (x < 0) {
+ xoff = ((-x) & 0xFE);
+ x = 0;
+ } else {
+ xoff = 0;
+ }
+
+ if (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);
+ }
+ }
+
+ /* 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);
+
+ /* Turn cursor off. */
+ VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode & 0xFFFFFFFE);
+
+ VIASETREG(VIA_REG_CURSOR_ORG, ((xoff << 16) | (yoff & 0x003f)));
+ VIASETREG(VIA_REG_CURSOR_POS, ((x << 16) | (y & 0x07ff)));
+
+ /* Restore cursor status */
+ VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode);
+}
+
+
+static void
+VIASetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ VIASETREG(VIA_REG_CURSOR_FG, fg);
+ VIASETREG(VIA_REG_CURSOR_BG, bg);
+
+}
+
+/*
+ *
+ */
+void
+ViaCursorStore(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaCursorStore\n"));
+
+ if (pVia->CursorImage) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaCursorStore: stale image left.\n");
+ xfree(pVia->CursorImage);
+ }
+
+ 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);
+}
+
+/*
+ *
+ */
+void
+ViaCursorRestore(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaCursorRestore\n"));
+
+ 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");
+}
diff --git a/src/via_dga.c b/src/via_dga.c
new file mode 100644
index 000000000000..3c1367438ac3
--- /dev/null
+++ b/src/via_dga.c
@@ -0,0 +1,321 @@
+/*
+ * 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 "xaalocal.h"
+#include "via_driver.h"
+#include "dgaproc.h"
+
+
+static Bool VIADGAOpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
+ int *, int *, int *);
+static Bool VIADGASetMode(ScrnInfoPtr, DGAModePtr);
+static int VIADGAGetViewport(ScrnInfoPtr);
+static void VIADGASetViewport(ScrnInfoPtr, int, int, int);
+
+static
+DGAFunctionRec VIADGAFuncs = {
+ VIADGAOpenFramebuffer,
+ NULL, /* CloseFrameBuffer */
+ VIADGASetMode,
+ VIADGASetViewport,
+ VIADGAGetViewport,
+ viaAccelSyncMarker,
+ viaAccelFillRect,
+ viaAccelBlitRect,
+ NULL /* BlitTransRect */
+};
+
+#define DGATRACE 4
+
+
+static DGAModePtr
+VIASetupDGAMode(
+ ScrnInfoPtr pScrn,
+ DGAModePtr modes,
+ int *num,
+ int bitsPerPixel,
+ int depth,
+ Bool pixmap,
+ int secondPitch,
+ unsigned long red,
+ unsigned long green,
+ unsigned long blue,
+ short visualClass
+)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ DGAModePtr mode, newmodes = NULL;
+ DisplayModePtr pMode, firstMode;
+ int otherPitch, Bpp = bitsPerPixel >> 3;
+ Bool oneMore;
+
+ xf86ErrorFVerb(DGATRACE, " VIASetupDGAMode\n");
+
+ pMode = firstMode = pScrn->modes;
+
+ /*
+ * DGA 1.0 would only provide modes where the depth and stride
+ * matched the current desktop. Some DGA apps might still expect
+ * this, so we provide them, too.
+ */
+
+ while (pMode) {
+
+ otherPitch = secondPitch ? secondPitch : pMode->HDisplay;
+
+ if (pMode->HDisplay != otherPitch) {
+ newmodes = xrealloc(modes, (*num + 2) * sizeof(DGAModeRec));
+ oneMore = TRUE;
+ }
+ else {
+ newmodes = xrealloc(modes, (*num + 1) * sizeof(DGAModeRec));
+ oneMore = FALSE;
+ }
+
+ if (!newmodes) {
+ xfree(modes);
+ return NULL;
+ }
+
+ modes = newmodes;
+
+SECOND_PASS:
+
+ mode = modes + *num;
+ (*num)++;
+
+ mode->mode = pMode;
+ mode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;
+
+ if(!pVia->NoAccel)
+ mode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
+
+ if (pMode->Flags & V_DBLSCAN)
+ mode->flags |= DGA_DOUBLESCAN;
+
+ if (pMode->Flags & V_INTERLACE)
+ mode->flags |= DGA_INTERLACED;
+
+ mode->byteOrder = pScrn->imageByteOrder;
+ mode->depth = depth;
+ mode->bitsPerPixel = bitsPerPixel;
+ mode->red_mask = red;
+ mode->green_mask = green;
+ mode->blue_mask = blue;
+ mode->visualClass = visualClass;
+ mode->viewportWidth = pMode->HDisplay;
+ mode->viewportHeight = pMode->VDisplay;
+ mode->xViewportStep = 2;
+ mode->yViewportStep = 1;
+ mode->viewportFlags = DGA_FLIP_RETRACE;
+ mode->offset = 0;
+ mode->address = pVia->FBBase;
+
+ xf86ErrorFVerb(DGATRACE,
+ "VIADGAInit vpWid=%d, vpHgt=%d, Bpp=%d, mdbitsPP=%d\n",
+ mode->viewportWidth,
+ mode->viewportHeight,
+ Bpp,
+ mode->bitsPerPixel);
+
+ if (oneMore) { /* first one is narrow width */
+ mode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L;
+ mode->imageWidth = pMode->HDisplay;
+ mode->imageHeight = pMode->VDisplay;
+ mode->pixmapWidth = mode->imageWidth;
+ mode->pixmapHeight = mode->imageHeight;
+ mode->maxViewportX = mode->imageWidth - mode->viewportWidth;
+
+ /* this might need to get clamped to some maximum */
+ mode->maxViewportY = mode->imageHeight - mode->viewportHeight;
+ oneMore = FALSE;
+
+ xf86ErrorFVerb(DGATRACE,
+ "VIADGAInit 1 imgHgt=%d, stride=%d\n",
+ mode->imageHeight,
+ mode->bytesPerScanline );
+
+ goto SECOND_PASS;
+ }
+ else {
+ mode->bytesPerScanline = ((pScrn->displayWidth * Bpp) + 3) & ~3L;
+ mode->imageWidth = pScrn->displayWidth;
+ mode->imageHeight = pVia->videoRambytes / mode->bytesPerScanline;
+ mode->pixmapWidth = mode->imageWidth;
+ mode->pixmapHeight = mode->imageHeight;
+ mode->maxViewportX = mode->imageWidth - mode->viewportWidth;
+ /* this might need to get clamped to some maximum */
+ mode->maxViewportY = mode->imageHeight - mode->viewportHeight;
+
+ xf86ErrorFVerb(DGATRACE,
+ "VIADGAInit 2 imgHgt=%d, stride=%d\n",
+ mode->imageHeight,
+ mode->bytesPerScanline);
+ }
+
+ pMode = pMode->next;
+
+ if (pMode == firstMode)
+ break;
+ }
+
+ return modes;
+}
+
+
+Bool
+VIADGAInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ DGAModePtr modes = NULL;
+ int num = 0;
+
+ xf86ErrorFVerb(DGATRACE, " VIADGAInit\n");
+
+ /* 8 */
+ modes = VIASetupDGAMode(pScrn, modes, &num, 8, 8,
+ (pScrn->bitsPerPixel == 8),
+ (pScrn->bitsPerPixel != 8) ? 0 : pScrn->displayWidth,
+ 0, 0, 0, PseudoColor);
+
+ /* 16 */
+ modes = VIASetupDGAMode(pScrn, modes, &num, 16, 16,
+ (pScrn->bitsPerPixel == 16),
+ (pScrn->depth != 16) ? 0 : pScrn->displayWidth,
+ 0xf800, 0x07e0, 0x001f, TrueColor);
+
+ modes = VIASetupDGAMode(pScrn, modes, &num, 16, 16,
+ (pScrn->bitsPerPixel == 16),
+ (pScrn->depth != 16) ? 0 : pScrn->displayWidth,
+ 0xf800, 0x07e0, 0x001f, DirectColor);
+
+ /* 24-in-32 */
+ modes = VIASetupDGAMode(pScrn, modes, &num, 32, 24,
+ (pScrn->bitsPerPixel == 32),
+ (pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth,
+ 0xff0000, 0x00ff00, 0x0000ff, TrueColor);
+
+ modes = VIASetupDGAMode(pScrn, modes, &num, 32, 24,
+ (pScrn->bitsPerPixel == 32),
+ (pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth,
+ 0xff0000, 0x00ff00, 0x0000ff, DirectColor);
+
+ pVia->numDGAModes = num;
+ pVia->DGAModes = modes;
+
+ return DGAInit(pScreen, &VIADGAFuncs, modes, num);
+}
+
+
+static Bool
+VIADGASetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
+{
+ int index = pScrn->pScreen->myNum;
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ if (!pMode) { /* restore the original mode */
+ /* put the ScreenParameters back */
+
+ pScrn->displayWidth = pVia->DGAOldDisplayWidth;
+ pScrn->bitsPerPixel = pVia->DGAOldBitsPerPixel;
+ pScrn->depth = pVia->DGAOldDepth;
+
+ pScrn->SwitchMode(index, pScrn->currentMode, 0);
+ if (pVia->hwcursor)
+ VIAShowCursor(pScrn);
+
+ pVia->DGAactive = FALSE;
+ }
+ else {
+#if 0
+ ErrorF("pScrn->bitsPerPixel %d, pScrn->depth %d\n",
+ pScrn->bitsPerPixel, pScrn->depth);
+ ErrorF(" want bitsPerPixel %d, want depth %d\n",
+ pMode->bitsPerPixel, pMode->depth);
+#endif
+
+ if (pVia->hwcursor)
+ VIAHideCursor(pScrn);
+
+ if (!pVia->DGAactive) { /* save the old parameters */
+ pVia->DGAOldDisplayWidth = pScrn->displayWidth;
+ pVia->DGAOldBitsPerPixel = pScrn->bitsPerPixel;
+ pVia->DGAOldDepth = pScrn->depth;
+
+ pVia->DGAactive = TRUE;
+ }
+
+ pScrn->bitsPerPixel = pMode->bitsPerPixel;
+ pScrn->depth = pMode->depth;
+ pScrn->displayWidth = pMode->bytesPerScanline /
+ (pMode->bitsPerPixel >> 3);
+
+ pScrn->SwitchMode(index, pMode->mode, 0);
+ }
+
+ return TRUE;
+}
+
+
+static int
+VIADGAGetViewport(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ return pVia->DGAViewportStatus;
+}
+
+
+static void
+VIADGASetViewport(ScrnInfoPtr pScrn, int x, int y, int flags)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ pScrn->AdjustFrame(pScrn->pScreen->myNum, x, y, flags);
+ pVia->DGAViewportStatus = 0; /* MGAAdjustFrame loops until finished */
+}
+
+static Bool
+VIADGAOpenFramebuffer(
+ ScrnInfoPtr pScrn,
+ char **name,
+ unsigned char **mem,
+ int *size,
+ int *offset,
+ int *flags)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ *name = NULL; /* no special device */
+ *mem = (unsigned char*)pVia->FrameBufferBase;
+ *size = pVia->videoRambytes;
+ *offset = 0;
+ *flags = DGA_NEED_ROOT;
+
+ return TRUE;
+}
diff --git a/src/via_dmabuffer.h b/src/via_dmabuffer.h
new file mode 100644
index 000000000000..39eeb7e95baa
--- /dev/null
+++ b/src/via_dmabuffer.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) Thomas Hellstrom (2005)
+ *
+ * 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.
+ */
+
+#ifndef VIA_DMABUFFER_H
+#define VIA_DMABUFFER_H
+
+#include "via_3d_reg.h"
+
+typedef struct _ViaCommandBuffer
+{
+ ScrnInfoPtr pScrn;
+ CARD32 *buf;
+ CARD32 waitFlags;
+ unsigned pos;
+ unsigned bufSize;
+ int mode;
+ int header_start;
+ int rindex;
+ Bool has3dState;
+ void (*flushFunc) (struct _ViaCommandBuffer * cb);
+} ViaCommandBuffer;
+
+#define VIA_DMASIZE 16384
+
+#define H1_ADDR(val) (((val) >> 2) | 0xF0000000)
+#define WAITFLAGS(flags) \
+ (cb)->waitFlags |= (flags)
+
+#define BEGIN_RING(size) \
+ do { \
+ if (cb->flushFunc && (cb->pos > (cb->bufSize-(size)))) { \
+ cb->flushFunc(cb); \
+ } \
+ } while(0)
+
+#define BEGIN_H2(paraType, h2size) \
+ do{ \
+ BEGIN_RING((h2size)+6); \
+ if (cb->mode == 2 && (paraType) == cb->rindex) \
+ break; \
+ if (cb->pos & 1) \
+ OUT_RING(HC_DUMMY); \
+ cb->header_start = cb->pos; \
+ cb->rindex = paraType; \
+ cb->mode = 2; \
+ OUT_RING(HALCYON_HEADER2); \
+ OUT_RING((paraType) << 16); \
+ if (!cb->has3dState && ((paraType) != HC_ParaType_CmdVdata)) { \
+ cb->has3dState = TRUE; \
+ } \
+ } while(0);
+
+#define OUT_RING(val) do{ \
+ (cb)->buf[(cb)->pos++] = (val); \
+ } while(0);
+
+#define OUT_RING_QW(val1, val2) \
+ do { \
+ (cb)->buf[(cb)->pos++] = (val1); \
+ (cb)->buf[(cb)->pos++] = (val2); \
+ } while (0)
+
+#define ADVANCE_RING \
+ cb->flushFunc(cb)
+
+#define RING_VARS \
+ ViaCommandBuffer *cb = &pVia->cb
+
+#define OUT_RING_H1(val1, val2) \
+ OUT_RING_QW(H1_ADDR(val1), val2)
+
+#define OUT_RING_SubA(val1, val2) \
+ OUT_RING(((val1) << HC_SubA_SHIFT) | ((val2) & HC_Para_MASK))
+
+extern int viaSetupCBuffer(ScrnInfoPtr pScrn, ViaCommandBuffer * buf,
+ unsigned size);
+extern void viaTearDownCBuffer(ViaCommandBuffer * buf);
+extern void viaFlushPCI(ViaCommandBuffer * buf);
+
+#endif
diff --git a/src/via_dri.c b/src/via_dri.c
new file mode 100644
index 000000000000..c109d770c377
--- /dev/null
+++ b/src/via_dri.c
@@ -0,0 +1,1101 @@
+/*
+ * 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 "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Priv.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#define _XF86DRI_SERVER_
+#include "GL/glxtokens.h"
+#include "sarea.h"
+
+#include "via.h"
+#include "via_driver.h"
+#include "via_drm.h"
+#include "via_dri.h"
+#include "via_id.h"
+#include "xf86drm.h"
+
+#ifndef DRIINFO_MAJOR_VERSION
+#define DRIINFO_MAJOR_VERSION 4
+#endif
+#ifndef DRIINFO_MINOR_VERSION
+#define DRIINFO_MINOR_VERSION 0
+#endif
+
+#define VIDEO 0
+#define AGP 1
+#define AGP_CMDBUF_PAGES 512
+#define AGP_CMDBUF_SIZE (AGP_PAGE_SIZE * AGP_CMDBUF_PAGES)
+#define VIA_AGP_MODE_MASK 0x17
+#define VIA_AGPv3_MODE 0x08
+#define VIA_AGPv3_8X_MODE 0x02
+#define VIA_AGPv3_4X_MODE 0x01
+#define VIA_AGP_4X_MODE 0x04
+#define VIA_AGP_2X_MODE 0x02
+#define VIA_AGP_1X_MODE 0x01
+#define VIA_AGP_FW_MODE 0x10
+
+extern void GlxSetVisualConfigs(
+ int nconfigs,
+ __GLXvisualConfig *configs,
+ void **configprivs
+);
+
+typedef struct {
+ int major;
+ int minor;
+ int patchlevel;
+} ViaDRMVersion;
+
+static char VIAKernelDriverName[] = "via";
+static char VIAClientDriverName[] = "unichrome";
+static const ViaDRMVersion drmExpected = {1, 3, 0};
+static const ViaDRMVersion drmCompat = {2, 0, 0};
+
+int test_alloc_FB(ScreenPtr pScreen, VIAPtr pVia, int Size);
+int test_alloc_AGP(ScreenPtr pScreen, VIAPtr pVia, int Size);
+static Bool VIAInitVisualConfigs(ScreenPtr pScreen);
+static Bool VIADRIAgpInit(ScreenPtr pScreen, VIAPtr pVia);
+static Bool VIADRIPciInit(ScreenPtr pScreen, VIAPtr pVia);
+static Bool VIADRIFBInit(ScreenPtr pScreen, VIAPtr pVia);
+static Bool VIADRIKernelInit(ScreenPtr pScreen, VIAPtr pVia);
+static Bool VIADRIMapInit(ScreenPtr pScreen, VIAPtr pVia);
+
+static Bool VIACreateContext(ScreenPtr pScreen, VisualPtr visual,
+ drm_context_t hwContext, void *pVisualConfigPriv,
+ DRIContextType contextStore);
+static void VIADestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
+ DRIContextType contextStore);
+static void VIADRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
+ DRIContextType readContextType,
+ void *readContextStore,
+ DRIContextType writeContextType,
+ void *writeContextStore);
+static void VIADRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index);
+static void VIADRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc, CARD32 index);
+
+
+static void VIADRIIrqInit( ScrnInfoPtr pScrn , VIADRIPtr pVIADRI)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ pVIADRI->irqEnabled = drmGetInterruptFromBusID
+ (pVia->drmFD,
+ ((pciConfigPtr)pVia->PciInfo->thisCard)->busnum,
+ ((pciConfigPtr)pVia->PciInfo->thisCard)->devnum,
+ ((pciConfigPtr)pVia->PciInfo->thisCard)->funcnum);
+ if ((drmCtlInstHandler(pVia->drmFD, pVIADRI->irqEnabled))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "[drm] Failure adding irq handler. "
+ "Falling back to irq-free operation.\n");
+ pVIADRI->irqEnabled = 0;
+ }
+
+ if (pVIADRI->irqEnabled)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[drm] Irq handler installed, using IRQ %d.\n",
+ pVIADRI->irqEnabled);
+}
+
+static void VIADRIIrqExit( ScrnInfoPtr pScrn , VIADRIPtr pVIADRI) {
+
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ if (pVIADRI->irqEnabled) {
+ if (drmCtlUninstHandler(pVia->drmFD)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,"[drm] Irq handler uninstalled.\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] Could not uninstall irq handler.\n");
+ }
+ }
+}
+
+void
+VIADRIRingBufferCleanup(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate;
+
+ if (pVIADRI->ringBufActive) {
+ drm_via_dma_init_t ringBufInit;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[drm] Cleaning up DMA ring-buffer.\n");
+ ringBufInit.func = VIA_CLEANUP_DMA;
+ if (drmCommandWrite(pVia->drmFD, DRM_VIA_DMA_INIT, &ringBufInit,
+ sizeof(ringBufInit))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "[drm] Failed to clean up DMA ring-buffer: %d\n", errno);
+ }
+ pVIADRI->ringBufActive = 0;
+ }
+}
+
+Bool
+VIADRIRingBufferInit(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate;
+
+ if (pVIADRI->ringBufActive)
+ return TRUE;
+
+ if (pVia->agpEnable) {
+ drm_via_dma_init_t ringBufInit;
+
+ if (((pVia->drmVerMajor == 1) && (pVia->drmVerMinor <= 3))) {
+ return FALSE;
+ }
+
+ /*
+ * Info frome code-snippet on DRI-DEVEL list; Erdi Chen.
+ */
+
+ switch (pVia->ChipId) {
+ case PCI_CHIP_VT3314:
+ case PCI_CHIP_VT3259:
+ pVIADRI->reg_pause_addr = 0x40c;
+ break;
+ default:
+ pVIADRI->reg_pause_addr = 0x418;
+ break;
+ }
+
+ ringBufInit.offset = pVia->agpSize;
+ ringBufInit.size = AGP_CMDBUF_SIZE;
+ ringBufInit.reg_pause_addr = pVIADRI->reg_pause_addr;
+ ringBufInit.func = VIA_INIT_DMA;
+ if (drmCommandWrite(pVia->drmFD, DRM_VIA_DMA_INIT, &ringBufInit,
+ sizeof(ringBufInit))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] Failed to initialize DMA ring-buffer: %d\n", errno);
+ return FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[drm] Initialized AGP ring-buffer, size 0x%lx at AGP offset 0x%lx.\n",
+ ringBufInit.size, ringBufInit.offset);
+
+ pVIADRI->ringBufActive = 1;
+ }
+ return TRUE;
+}
+
+static Bool VIASetAgpMode(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ CARD32 mode = drmAgpGetMode(pVia->drmFD);
+ unsigned int vendor = drmAgpVendorId(pVia->drmFD);
+ unsigned int device = drmAgpDeviceId(pVia->drmFD);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Detected AGP vendor 0x%04x, device 0x04%x\n",
+ vendor, device);
+
+ mode &= ~VIA_AGP_MODE_MASK;
+ if ((mode & VIA_AGPv3_MODE)) {
+ mode |= VIA_AGPv3_8X_MODE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Found AGP v3 compatible device. "
+ "Trying AGP 8X mode.\n");
+ } else {
+ mode |= VIA_AGP_4X_MODE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Didn't find any AGP v3 compatible device. "
+ "Trying AGP 4X mode.\n");
+ }
+
+ mode |= VIA_AGP_FW_MODE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Trying to enable AGP fast writes.\n");
+
+ if (drmAgpEnable(pVia->drmFD, mode) < 0) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static Bool
+VIADRIAgpInit(ScreenPtr pScreen, VIAPtr pVia)
+{
+ int agpPages;
+ unsigned long agpCmdSize;
+ unsigned long agp_phys;
+ drmAddress agpaddr;
+ VIADRIPtr pVIADRI;
+ DRIInfoPtr pDRIInfo;
+ pDRIInfo = pVia->pDRIInfo;
+ pVIADRI = pDRIInfo->devPrivate;
+ pVia->agpSize = 0;
+
+ if (drmAgpAcquire(pVia->drmFD) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpAcquire failed %d\n", errno);
+ return FALSE;
+ }
+
+ if (!VIASetAgpMode(xf86Screens[pScreen->myNum])) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] VIASetAgpMode failed\n");
+ drmAgpRelease(pVia->drmFD);
+ return FALSE;
+ }
+
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] drmAgpEnabled succeeded\n");
+
+ agpCmdSize = (pVia->agpEnable) ? AGP_CMDBUF_SIZE : 0;
+
+ if (pVia->agpMem*1024 < agpCmdSize + AGP_PAGE_SIZE) {
+ pVia->agpMem = (agpCmdSize + AGP_PAGE_SIZE) / 1024;
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] Forcing AGP size to %d kB\n", pVia->agpMem);
+ }
+
+ agpPages = (pVia->agpMem*1024 + AGP_PAGE_SIZE - 1) / AGP_PAGE_SIZE;
+
+ if (drmAgpAlloc(pVia->drmFD, agpPages*AGP_PAGE_SIZE,
+ 0, &agp_phys, &pVia->agpHandle) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] drmAgpAlloc failed\n");
+ drmAgpRelease(pVia->drmFD);
+ return FALSE;
+ }
+
+ if (drmAgpBind(pVia->drmFD, pVia->agpHandle, 0) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] drmAgpBind failed\n");
+ drmAgpFree(pVia->drmFD, pVia->agpHandle);
+ drmAgpRelease(pVia->drmFD);
+
+ return FALSE;
+ }
+
+ /*
+ * Place the ring-buffer last in the AGP region, and restrict the
+ * public map not to include the buffer for security reasons.
+ */
+
+ pVia->agpSize = agpPages*AGP_PAGE_SIZE - agpCmdSize;
+ pVia->agpAddr = drmAgpBase(pVia->drmFD);
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] agpAddr = 0x%08lx\n",pVia->agpAddr);
+
+ pVIADRI->agp.size = pVia->agpSize;
+ if (drmAddMap(pVia->drmFD, (drm_handle_t)0,
+ pVIADRI->agp.size, DRM_AGP, 0,
+ &pVIADRI->agp.handle) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] Failed to map public agp area\n");
+ pVIADRI->agp.size = 0;
+ drmAgpUnbind(pVia->drmFD, pVia->agpHandle);
+ drmAgpFree(pVia->drmFD, pVia->agpHandle);
+ drmAgpRelease(pVia->drmFD);
+ return FALSE;
+ }
+
+ drmMap(pVia->drmFD, pVIADRI->agp.handle, pVIADRI->agp.size, &agpaddr);
+ pVia->agpMappedAddr = agpaddr;
+
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] agpBase = %p\n", pVia->agpBase);
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] agpAddr = 0x%08lx\n", pVia->agpAddr);
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] agpSize = 0x%08x\n", pVia->agpSize);
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] agp physical addr = 0x%08lx\n", agp_phys);
+
+ {
+ drm_via_agp_t agp;
+ agp.offset = 0;
+ agp.size = pVia->agpSize;
+ if (drmCommandWrite(pVia->drmFD, DRM_VIA_AGP_INIT, &agp,
+ sizeof(drm_via_agp_t)) < 0) {
+ drmUnmap(agpaddr,pVia->agpSize);
+ drmRmMap(pVia->drmFD,pVIADRI->agp.handle);
+ drmAgpUnbind(pVia->drmFD, pVia->agpHandle);
+ drmAgpFree(pVia->drmFD, pVia->agpHandle);
+ drmAgpRelease(pVia->drmFD);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static Bool VIADRIFBInit(ScreenPtr pScreen, VIAPtr pVia)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ int FBSize = pVia->driSize;
+ int FBOffset;
+ VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate;
+
+ if (FBSize < pVia->Bpl) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] No DRM framebuffer heap available.\n");
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] Please increase the frame buffer\n");
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] memory area in BIOS. Disabling DRI.\n");
+ return FALSE;
+ }
+ if (FBSize < 3*(pScrn->virtualY * pVia->Bpl)) {
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "[drm] The DRM Heap and Pixmap cache memory could be too small\n");
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "[drm] for optimal performance. Please increase the frame buffer\n");
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "[drm] memory area in BIOS.\n");
+ }
+
+ pVia->driOffScreenMem.pool = 0;
+ if (Success != viaOffScreenLinear(&pVia->driOffScreenMem, pScrn, FBSize)) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] failed to allocate offscreen frame buffer area\n");
+ return FALSE;
+ }
+
+ FBOffset = pVia->driOffScreenMem.base;
+
+ pVIADRI->fbOffset = FBOffset;
+ pVIADRI->fbSize = FBSize;
+
+ {
+ drm_via_fb_t fb;
+ fb.offset = FBOffset;
+ fb.size = FBSize;
+
+ if (drmCommandWrite(pVia->drmFD, DRM_VIA_FB_INIT, &fb,
+ sizeof(drm_via_fb_t)) < 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] failed to init frame buffer area\n");
+ return FALSE;
+ } else {
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] Using %d bytes for DRM memory heap.\n", FBSize);
+ return TRUE;
+ }
+ }
+}
+
+static Bool VIADRIPciInit(ScreenPtr pScreen, VIAPtr pVia)
+{
+ return TRUE;
+}
+
+static Bool
+VIAInitVisualConfigs(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ int numConfigs = 0;
+ __GLXvisualConfig *pConfigs = 0;
+ VIAConfigPrivPtr pVIAConfigs = 0;
+ VIAConfigPrivPtr *pVIAConfigPtrs = 0;
+ int i, db, stencil, accum;
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ case 24:
+ break;
+ case 16:
+ numConfigs = 12;
+ if (!(pConfigs = (__GLXvisualConfig*)xcalloc(sizeof(__GLXvisualConfig),
+ numConfigs)))
+ return FALSE;
+ if (!(pVIAConfigs = (VIAConfigPrivPtr)xcalloc(sizeof(VIAConfigPrivRec),
+ numConfigs))) {
+ xfree(pConfigs);
+ return FALSE;
+ }
+ if (!(pVIAConfigPtrs = (VIAConfigPrivPtr*)xcalloc(sizeof(VIAConfigPrivPtr),
+ numConfigs))) {
+ xfree(pConfigs);
+ xfree(pVIAConfigs);
+ return FALSE;
+ }
+ for (i=0; i<numConfigs; i++)
+ pVIAConfigPtrs[i] = &pVIAConfigs[i];
+
+ i = 0;
+ for (accum = 0; accum <= 1; accum++) {
+ /* 32bpp depth buffer disabled, as Mesa has limitations */
+ for (stencil=0; stencil<=2; stencil++) {
+ for (db = 0; db <= 1; db++) {
+ pConfigs[i].vid = -1;
+ pConfigs[i].class = -1;
+ pConfigs[i].rgba = TRUE;
+ pConfigs[i].redSize = -1;
+ pConfigs[i].greenSize = -1;
+ pConfigs[i].blueSize = -1;
+ pConfigs[i].redMask = -1;
+ pConfigs[i].greenMask = -1;
+ pConfigs[i].blueMask = -1;
+ pConfigs[i].alphaSize = 0;
+ pConfigs[i].alphaMask = 0;
+
+ if (accum) {
+ pConfigs[i].accumRedSize = 16;
+ pConfigs[i].accumGreenSize = 16;
+ pConfigs[i].accumBlueSize = 16;
+ pConfigs[i].accumAlphaSize = 0;
+ }
+ else {
+ pConfigs[i].accumRedSize = 0;
+ pConfigs[i].accumGreenSize = 0;
+ pConfigs[i].accumBlueSize = 0;
+ pConfigs[i].accumAlphaSize = 0;
+ }
+ if (!db)
+ pConfigs[i].doubleBuffer = TRUE;
+ else
+ pConfigs[i].doubleBuffer = FALSE;
+
+ pConfigs[i].stereo = FALSE;
+ pConfigs[i].bufferSize = -1;
+
+ switch (stencil) {
+ case 0:
+ pConfigs[i].depthSize = 24;
+ pConfigs[i].stencilSize = 8;
+ break;
+ case 1:
+ pConfigs[i].depthSize = 16;
+ pConfigs[i].stencilSize = 0;
+ break;
+ case 2:
+ pConfigs[i].depthSize = 0;
+ pConfigs[i].stencilSize = 0;
+ break;
+ case 3:
+ pConfigs[i].depthSize = 32;
+ pConfigs[i].stencilSize = 0;
+ break;
+ }
+
+ pConfigs[i].auxBuffers = 0;
+ pConfigs[i].level = 0;
+ if (accum) {
+ pConfigs[i].visualRating = GLX_SLOW_VISUAL_EXT;
+ } else {
+ pConfigs[i].visualRating = GLX_NONE_EXT;
+ }
+ pConfigs[i].transparentPixel = GLX_NONE_EXT;
+ pConfigs[i].transparentRed = 0;
+ pConfigs[i].transparentGreen = 0;
+ pConfigs[i].transparentBlue = 0;
+ pConfigs[i].transparentAlpha = 0;
+ pConfigs[i].transparentIndex = 0;
+ i++;
+ }
+ }
+ }
+
+ if (i != numConfigs) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[dri] Incorrect initialization of visuals. Disabling DRI.\n");
+ return FALSE;
+ }
+ break;
+
+ case 32:
+ numConfigs = 12;
+ if (!(pConfigs = (__GLXvisualConfig*)xcalloc(sizeof(__GLXvisualConfig),
+ numConfigs)))
+ return FALSE;
+ if (!(pVIAConfigs = (VIAConfigPrivPtr)xcalloc(sizeof(VIAConfigPrivRec),
+ numConfigs))) {
+ xfree(pConfigs);
+ return FALSE;
+ }
+ if (!(pVIAConfigPtrs = (VIAConfigPrivPtr*)xcalloc(sizeof(VIAConfigPrivPtr),
+ numConfigs))) {
+ xfree(pConfigs);
+ xfree(pVIAConfigs);
+ return FALSE;
+ }
+ for (i=0; i<numConfigs; i++)
+ pVIAConfigPtrs[i] = &pVIAConfigs[i];
+
+ i = 0;
+ for (accum = 0; accum <= 1; accum++) {
+ /* 32bpp depth buffer disabled, as Mesa has limitations */
+ for (stencil=0; stencil<=2; stencil++) {
+ for (db = 0; db <= 1; db++) {
+ pConfigs[i].vid = -1;
+ pConfigs[i].class = -1;
+ pConfigs[i].rgba = TRUE;
+ pConfigs[i].redSize = -1;
+ pConfigs[i].greenSize = -1;
+ pConfigs[i].blueSize = -1;
+ pConfigs[i].redMask = -1;
+ pConfigs[i].greenMask = -1;
+ pConfigs[i].blueMask = -1;
+ pConfigs[i].alphaSize = 8;
+ pConfigs[i].alphaMask = 0xFF000000;
+
+ if (accum) {
+ pConfigs[i].accumRedSize = 16;
+ pConfigs[i].accumGreenSize = 16;
+ pConfigs[i].accumBlueSize = 16;
+ pConfigs[i].accumAlphaSize = 16;
+ }
+ else {
+ pConfigs[i].accumRedSize = 0;
+ pConfigs[i].accumGreenSize = 0;
+ pConfigs[i].accumBlueSize = 0;
+ pConfigs[i].accumAlphaSize = 0;
+ }
+ if (!db)
+ pConfigs[i].doubleBuffer = TRUE;
+ else
+ pConfigs[i].doubleBuffer = FALSE;
+
+ pConfigs[i].stereo = FALSE;
+ pConfigs[i].bufferSize = -1;
+
+ switch (stencil) {
+ case 0:
+ pConfigs[i].depthSize = 24;
+ pConfigs[i].stencilSize = 8;
+ break;
+ case 1:
+ pConfigs[i].depthSize = 16;
+ pConfigs[i].stencilSize = 0;
+ break;
+ case 2:
+ pConfigs[i].depthSize = 0;
+ pConfigs[i].stencilSize = 0;
+ break;
+ case 3:
+ pConfigs[i].depthSize = 32;
+ pConfigs[i].stencilSize = 0;
+ break;
+ }
+
+ pConfigs[i].auxBuffers = 0;
+ pConfigs[i].level = 0;
+ if (accum)
+ pConfigs[i].visualRating = GLX_SLOW_VISUAL_EXT;
+ else
+ pConfigs[i].visualRating = GLX_NONE_EXT;
+ pConfigs[i].transparentPixel = GLX_NONE_EXT;
+ pConfigs[i].transparentRed = 0;
+ pConfigs[i].transparentGreen = 0;
+ pConfigs[i].transparentBlue = 0;
+ pConfigs[i].transparentAlpha = 0;
+ pConfigs[i].transparentIndex = 0;
+ i++;
+ }
+ }
+ }
+
+ if (i != numConfigs) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[dri] Incorrect initialization of visuals. Disabling DRI.\n");
+ return FALSE;
+ }
+
+ break;
+ }
+
+ pVia->numVisualConfigs = numConfigs;
+ pVia->pVisualConfigs = pConfigs;
+ pVia->pVisualConfigsPriv = pVIAConfigs;
+ GlxSetVisualConfigs(numConfigs, pConfigs, (void**)pVIAConfigPtrs);
+
+ return TRUE;
+}
+
+Bool VIADRIScreenInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ DRIInfoPtr pDRIInfo;
+ VIADRIPtr pVIADRI;
+ drmVersionPtr drmVer;
+
+ /* if symbols or version check fails, we still want this to be NULL */
+ pVia->pDRIInfo = NULL;
+
+ /* Check that the GLX, DRI, and DRM modules have been loaded by testing
+ * for canonical symbols in each module. */
+ if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) return FALSE;
+ if (!xf86LoaderCheckSymbol("drmAvailable")) return FALSE;
+ if (!xf86LoaderCheckSymbol("DRIQueryVersion")) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[dri] VIADRIScreenInit failed (libdri.a too old)\n");
+ return FALSE;
+ }
+
+ /* Check the DRI version */
+ {
+ int major, minor, patch;
+ DRIQueryVersion(&major, &minor, &patch);
+ if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[dri] VIADRIScreenInit failed because of a version mismatch.\n"
+ "[dri] libdri version is %d.%d.%d but version %d.%d.x is needed.\n"
+ "[dri] Disabling DRI.\n",
+ major, minor, patch,
+ DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION);
+ return FALSE;
+ }
+ }
+
+ pVia->pDRIInfo = DRICreateInfoRec();
+ if (!pVia->pDRIInfo)
+ return FALSE;
+
+ pDRIInfo = pVia->pDRIInfo;
+ pDRIInfo->drmDriverName = VIAKernelDriverName;
+ pDRIInfo->clientDriverName = VIAClientDriverName;
+ pDRIInfo->busIdString = xalloc(64);
+ sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d",
+ ((pciConfigPtr)pVia->PciInfo->thisCard)->busnum,
+ ((pciConfigPtr)pVia->PciInfo->thisCard)->devnum,
+ ((pciConfigPtr)pVia->PciInfo->thisCard)->funcnum);
+ pDRIInfo->ddxDriverMajorVersion = VIA_DRIDDX_VERSION_MAJOR;
+ pDRIInfo->ddxDriverMinorVersion = VIA_DRIDDX_VERSION_MINOR;
+ pDRIInfo->ddxDriverPatchVersion = VIA_DRIDDX_VERSION_PATCH;
+#if (DRIINFO_MAJOR_VERSION == 5)
+ pDRIInfo->frameBufferPhysicalAddress = (pointer) pVia->FrameBufferBase;
+#else
+ pDRIInfo->frameBufferPhysicalAddress = pVia->FrameBufferBase;
+#endif
+ pDRIInfo->frameBufferSize = pVia->videoRambytes;
+
+ pDRIInfo->frameBufferStride = (pScrn->displayWidth *
+ pScrn->bitsPerPixel / 8);
+ pDRIInfo->ddxDrawableTableEntry = VIA_MAX_DRAWABLES;
+
+ if (SAREA_MAX_DRAWABLES < VIA_MAX_DRAWABLES)
+ pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES;
+ else
+ pDRIInfo->maxDrawableTableEntry = VIA_MAX_DRAWABLES;
+
+#ifdef NOT_DONE
+ /* FIXME need to extend DRI protocol to pass this size back to client
+ * for SAREA mapping that includes a device private record
+ */
+ pDRIInfo->SAREASize =
+ ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); /* round to page */
+ /* + shared memory device private rec */
+#else
+ /* For now the mapping works by using a fixed size defined
+ * in the SAREA header
+ */
+ if (sizeof(XF86DRISAREARec)+sizeof(drm_via_sarea_t) > SAREA_MAX) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Data does not fit in SAREA\n");
+ DRIDestroyInfoRec(pVia->pDRIInfo);
+ pVia->pDRIInfo = NULL;
+ return FALSE;
+ }
+ pDRIInfo->SAREASize = SAREA_MAX;
+#endif
+
+ if (!(pVIADRI = (VIADRIPtr)xcalloc(sizeof(VIADRIRec),1))) {
+ DRIDestroyInfoRec(pVia->pDRIInfo);
+ pVia->pDRIInfo = NULL;
+ return FALSE;
+ }
+ pDRIInfo->devPrivate = pVIADRI;
+ pDRIInfo->devPrivateSize = sizeof(VIADRIRec);
+ pDRIInfo->contextSize = sizeof(VIADRIContextRec);
+
+ pDRIInfo->CreateContext = VIACreateContext;
+ pDRIInfo->DestroyContext = VIADestroyContext;
+ pDRIInfo->SwapContext = VIADRISwapContext;
+ pDRIInfo->InitBuffers = VIADRIInitBuffers;
+ pDRIInfo->MoveBuffers = VIADRIMoveBuffers;
+ pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
+
+ if (!DRIScreenInit(pScreen, pDRIInfo, &pVia->drmFD)) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[dri] DRIScreenInit failed. Disabling DRI.\n");
+ xfree(pDRIInfo->devPrivate);
+ pDRIInfo->devPrivate = NULL;
+ DRIDestroyInfoRec(pVia->pDRIInfo);
+ pVia->pDRIInfo = NULL;
+ pVia->drmFD = -1;
+ return FALSE;
+ }
+
+ if (NULL == (drmVer = drmGetVersion(pVia->drmFD))) {
+ VIADRICloseScreen(pScreen);
+ return FALSE;
+ }
+ pVia->drmVerMajor = drmVer->version_major;
+ pVia->drmVerMinor = drmVer->version_minor;
+ pVia->drmVerPL = drmVer->version_patchlevel;
+
+ if ((drmVer->version_major < drmExpected.major) ||
+ (drmVer->version_major > drmCompat.major) ||
+ ((drmVer->version_major == drmExpected.major ) &&
+ (drmVer->version_minor < drmExpected.minor))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "[dri] Kernel drm is not compatible with this driver.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "[dri] Kernel drm version: %d.%d.%d "
+ "and I can work with versions %d.%d.x - %d.x.x\n",
+ drmVer->version_major,drmVer->version_minor,
+ drmVer->version_patchlevel, drmExpected.major,
+ drmExpected.minor, drmCompat.major);
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "[dri] Please update either this 2D driver or your kernel DRM. "
+ "Disabling DRI.\n");
+ drmFreeVersion(drmVer);
+ VIADRICloseScreen(pScreen);
+ return FALSE;
+ }
+ drmFreeVersion(drmVer);
+
+
+ if (!(VIAInitVisualConfigs(pScreen))) {
+ VIADRICloseScreen(pScreen);
+ return FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] visual configs initialized.\n" );
+
+ /* DRIScreenInit doesn't add all the common mappings. Add additional mappings here. */
+ if (!VIADRIMapInit(pScreen, pVia)) {
+ VIADRICloseScreen(pScreen);
+ return FALSE;
+ }
+ pVIADRI->regs.size = VIA_MMIO_REGSIZE;
+ pVIADRI->regs.handle = pVia->registerHandle;
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] mmio Registers = 0x%08lx\n",
+ (unsigned long) pVIADRI->regs.handle);
+
+ pVIADRI->drixinerama = FALSE;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] mmio mapped.\n" );
+
+ return TRUE;
+}
+
+void
+VIADRICloseScreen(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ VIADRIPtr pVIADRI;
+
+ VIADRIRingBufferCleanup(pScrn);
+ if (pVia->agpSize) {
+ drmUnmap(pVia->agpMappedAddr,pVia->agpSize);
+ drmRmMap(pVia->drmFD,pVia->agpHandle);
+ drmAgpUnbind(pVia->drmFD, pVia->agpHandle);
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Freeing agp memory\n");
+ drmAgpFree(pVia->drmFD, pVia->agpHandle);
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Releasing agp module\n");
+ drmAgpRelease(pVia->drmFD);
+ }
+
+ DRICloseScreen(pScreen);
+ VIAFreeLinear(&pVia->driOffScreenMem);
+
+ if (pVia->pDRIInfo) {
+ if ((pVIADRI = (VIADRIPtr) pVia->pDRIInfo->devPrivate)) {
+ VIADRIIrqExit(pScrn, pVIADRI);
+ xfree(pVIADRI);
+ pVia->pDRIInfo->devPrivate = NULL;
+ }
+ DRIDestroyInfoRec(pVia->pDRIInfo);
+ pVia->pDRIInfo = NULL;
+ }
+
+ if (pVia->pVisualConfigs) {
+ xfree(pVia->pVisualConfigs);
+ pVia->pVisualConfigs = NULL;
+ }
+ if (pVia->pVisualConfigsPriv) {
+ xfree(pVia->pVisualConfigsPriv);
+ pVia->pVisualConfigsPriv = NULL;
+ }
+}
+
+/* TODO: xserver receives driver's swapping event and does something
+ * according the data initialized in this function.
+ */
+static Bool
+VIACreateContext(ScreenPtr pScreen, VisualPtr visual,
+ drm_context_t hwContext, void *pVisualConfigPriv,
+ DRIContextType contextStore)
+{
+ return TRUE;
+}
+
+static void
+VIADestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
+ DRIContextType contextStore)
+{
+}
+
+Bool
+VIADRIFinishScreenInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ VIADRIPtr pVIADRI;
+
+ pVia->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT;
+
+ pVia->IsPCI = !VIADRIAgpInit(pScreen, pVia);
+
+ if (pVia->IsPCI) {
+ VIADRIPciInit(pScreen, pVia);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] use pci.\n" );
+ }
+ else
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] use agp.\n" );
+
+ if (!(VIADRIFBInit(pScreen, pVia))) {
+ VIADRICloseScreen(pScreen);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[dri] frame buffer initialization failed.\n" );
+ return FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] frame buffer initialized.\n" );
+
+ DRIFinishScreenInit(pScreen);
+
+ if (!VIADRIKernelInit(pScreen, pVia)) {
+ VIADRICloseScreen(pScreen);
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[dri] kernel data initialized.\n");
+
+ /* set SAREA value */
+ {
+ drm_via_sarea_t *saPriv;
+
+ saPriv=(drm_via_sarea_t *)DRIGetSAREAPrivate(pScreen);
+ assert(saPriv);
+ memset(saPriv, 0, sizeof(*saPriv));
+ saPriv->ctxOwner = -1;
+ }
+ pVIADRI=(VIADRIPtr)pVia->pDRIInfo->devPrivate;
+ pVIADRI->deviceID=pVia->Chipset;
+ pVIADRI->width=pScrn->virtualX;
+ pVIADRI->height=pScrn->virtualY;
+ pVIADRI->mem=pScrn->videoRam*1024;
+ pVIADRI->bytesPerPixel= (pScrn->bitsPerPixel+7) / 8;
+ pVIADRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
+ /* TODO */
+ pVIADRI->scrnX=pVIADRI->width;
+ pVIADRI->scrnY=pVIADRI->height;
+
+
+ /* Initialize IRQ */
+ if (pVia->DRIIrqEnable)
+ VIADRIIrqInit(pScrn, pVIADRI);
+
+ pVIADRI->ringBufActive = 0;
+ VIADRIRingBufferInit(pScrn);
+ return TRUE;
+}
+
+static void
+VIADRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
+ DRIContextType oldContextType, void *oldContext,
+ DRIContextType newContextType, void *newContext)
+{
+ /*ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ */
+ return;
+}
+
+static void
+VIADRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
+{
+ /*ScreenPtr pScreen = pWin->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ */
+ return;
+}
+
+static void
+VIADRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc, CARD32 index)
+{
+ /*ScreenPtr pScreen = pParent->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ */
+ return;
+}
+
+/* Initialize the kernel data structures. */
+static Bool VIADRIKernelInit(ScreenPtr pScreen, VIAPtr pVia)
+{
+ drm_via_init_t drmInfo;
+ memset(&drmInfo, 0, sizeof(drm_via_init_t));
+ drmInfo.func = VIA_INIT_MAP;
+ drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec);
+ drmInfo.fb_offset = pVia->frameBufferHandle;
+ drmInfo.mmio_offset = pVia->registerHandle;
+ if (pVia->IsPCI)
+ drmInfo.agpAddr = (CARD32)NULL;
+ else
+ drmInfo.agpAddr = (CARD32)pVia->agpAddr;
+
+ if ((drmCommandWrite(pVia->drmFD, DRM_VIA_MAP_INIT,&drmInfo,
+ sizeof(drm_via_init_t))) < 0)
+ return FALSE;
+
+
+ return TRUE;
+}
+/* Add a map for the MMIO registers */
+static Bool VIADRIMapInit(ScreenPtr pScreen, VIAPtr pVia)
+{
+ int flags = DRM_READ_ONLY;
+
+ if (drmAddMap(pVia->drmFD, pVia->MmioBase, VIA_MMIO_REGSIZE,
+ DRM_REGISTERS, flags, &pVia->registerHandle) < 0) {
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] register handle = 0x%08lx\n",
+ (unsigned long) pVia->registerHandle);
+ if (drmAddMap(pVia->drmFD, pVia->FrameBufferBase, pVia->videoRambytes,
+ DRM_FRAME_BUFFER, 0, &pVia->frameBufferHandle) < 0) {
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] framebuffer handle = 0x%08lx\n",
+ (unsigned long) pVia->frameBufferHandle);
+
+ return TRUE;
+}
+
+#define DRM_VIA_BLIT_MAX_SIZE (2048*2048*4)
+
+static int
+viaDRIFBMemcpy(int fd, unsigned long fbOffset, unsigned char *addr,
+ unsigned long size, Bool toFB)
+{
+ int err;
+ drm_via_dmablit_t blit;
+ unsigned long curSize;
+
+ do {
+ curSize = (size > DRM_VIA_BLIT_MAX_SIZE) ? DRM_VIA_BLIT_MAX_SIZE :
+ size;
+
+ blit.num_lines = 1;
+ blit.line_length = curSize;
+ blit.fb_addr = fbOffset;
+ blit.fb_stride = ALIGN_TO(curSize, 16);
+ blit.mem_addr = addr;
+ blit.mem_stride = blit.fb_stride;
+ blit.to_fb = (toFB) ? 1 : 0;
+
+ do {
+ err = drmCommandWriteRead(fd, DRM_VIA_DMA_BLIT,
+ &blit, sizeof(blit));
+ } while (-EAGAIN == err);
+
+ if (err)
+ return err;
+
+ do {
+ err = drmCommandWriteRead(fd, DRM_VIA_BLIT_SYNC,
+ &blit.sync, sizeof(blit.sync));
+ } while (-EAGAIN == err);
+ if (err)
+ return err;
+
+ fbOffset += curSize;
+ addr += curSize;
+ size -= curSize;
+
+ } while (size > 0);
+ return 0;
+}
+
+
+
+void
+viaDRIOffscreenSave(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate;
+ unsigned char *saveAddr = pVia->FBBase + pVIADRI->fbOffset;
+ unsigned long saveSize = pVIADRI->fbSize;
+ unsigned long curSize;
+ int err;
+
+
+ if (pVia->driOffScreenSave)
+ free(pVia->driOffScreenSave);
+
+ pVia->driOffScreenSave = malloc(saveSize + 16);
+ if (pVia->driOffScreenSave) {
+ if ((pVia->drmVerMajor == 2) && (pVia->drmVerMinor >= 8)) {
+ err = viaDRIFBMemcpy(pVia->drmFD, pVIADRI->fbOffset,
+ (unsigned char *)
+ ALIGN_TO((unsigned long)
+ pVia->driOffScreenSave, 16),
+ saveSize, FALSE);
+ if (!err)
+ return;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Hardware backup of DRI offscreen memory failed: %s.\n"
+ "\tUsing slow software backup instead.\n",
+ strerror(-err));
+ }
+ memcpy((void *)ALIGN_TO((unsigned long) pVia->driOffScreenSave, 16),
+ saveAddr, saveSize);
+
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Out of memory trying to backup DRI offscreen memory.\n");
+ }
+ return;
+}
+
+
+void
+viaDRIOffscreenRestore(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate;
+
+ unsigned char *saveAddr = pVia->FBBase + pVIADRI->fbOffset;
+ unsigned long saveSize = pVIADRI->fbSize;
+
+ if (pVia->driOffScreenSave) {
+ memcpy(saveAddr,
+ (void *)ALIGN_TO((unsigned long)pVia->driOffScreenSave, 16),
+ saveSize);
+ free(pVia->driOffScreenSave);
+ pVia->driOffScreenSave = NULL;
+ }
+}
diff --git a/src/via_dri.h b/src/via_dri.h
new file mode 100644
index 000000000000..cce2e6a5f778
--- /dev/null
+++ b/src/via_dri.h
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+/*
+ * Keep this file in perfect sync between the ddx and dri drivers.
+ * At least bump the VIA_DRIDDX_VERSION defines appropriately.
+ *
+ */
+#ifndef _VIA_DRI_H_
+#define _VIA_DRI_H_ 1
+
+#define VIA_MAX_DRAWABLES 256
+
+#define VIA_DRIDDX_VERSION_MAJOR 5
+#define VIA_DRIDDX_VERSION_MINOR 0
+#define VIA_DRIDDX_VERSION_PATCH 0
+
+#if !defined(XFree86Server) && !defined(_XDEFS_H)
+typedef int Bool;
+#endif
+
+typedef struct {
+ drm_handle_t handle;
+ drmSize size;
+} viaRegion, *viaRegionPtr;
+
+typedef struct {
+ viaRegion regs, agp;
+ int deviceID;
+ int width;
+ int height;
+ int mem;
+ int bytesPerPixel;
+ int priv1;
+ int priv2;
+ int fbOffset;
+ int fbSize;
+ Bool drixinerama;
+ int backOffset;
+ int depthOffset;
+ int textureOffset;
+ int textureSize;
+ int irqEnabled;
+ unsigned int scrnX, scrnY;
+ int sarea_priv_offset;
+ int ringBufActive;
+ unsigned int reg_pause_addr;
+} VIADRIRec, *VIADRIPtr;
+
+typedef struct {
+ int dummy;
+} VIAConfigPrivRec, *VIAConfigPrivPtr;
+
+typedef struct {
+ int dummy;
+} VIADRIContextRec, *VIADRIContextPtr;
+
+#endif /* _VIA_DRI_H_ */
diff --git a/src/via_driver.c b/src/via_driver.c
new file mode 100644
index 000000000000..8c9cb23d287e
--- /dev/null
+++ b/src/via_driver.c
@@ -0,0 +1,2858 @@
+/*
+ * Copyright 2005-2007 The Openchrome Project [openchrome.org]
+ * Copyright 2004-2006 Luc Verhaegen.
+ * 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.
+ */
+
+/*************************************************************************
+ *
+ * File: via_driver.c
+ * Content: XFree86 4.0 for VIA/S3G UniChrome
+ *
+ ************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86RAC.h"
+#include "shadowfb.h"
+
+#include "globals.h"
+#define DPMS_SERVER
+#include <X11/extensions/dpms.h>
+
+#include "svnversion.h"
+
+#include "via_driver.h"
+#include "via_video.h"
+
+#include "via.h"
+
+#ifdef XF86DRI
+#include "dri.h"
+#endif
+#include "via_vgahw.h"
+#include "via_id.h"
+
+/*
+ * prototypes
+ */
+
+static void VIAIdentify(int flags);
+static Bool VIAProbe(DriverPtr drv, int flags);
+static Bool VIASetupDefaultOptions(ScrnInfoPtr pScrn);
+static Bool VIAPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool VIAEnterVT(int scrnIndex, int flags);
+static void VIALeaveVT(int scrnIndex, int flags);
+static void VIASave(ScrnInfoPtr pScrn);
+static void VIARestore(ScrnInfoPtr pScrn);
+static Bool VIAWriteMode(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static Bool VIACloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool VIASaveScreen(ScreenPtr pScreen, int mode);
+static Bool VIAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
+ char **argv);
+static int VIAInternalScreenInit(int scrnIndex, ScreenPtr pScreen);
+static void VIAFreeScreen(int scrnIndex, int flags);
+static Bool VIASwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+static void VIAAdjustFrame(int scrnIndex, int y, int x, int flags);
+static void VIADPMS(ScrnInfoPtr pScrn, int mode, int flags);
+static const OptionInfoRec * VIAAvailableOptions(int chipid, int busid);
+
+static Bool VIAMapMMIO(ScrnInfoPtr pScrn);
+static Bool VIAMapFB(ScrnInfoPtr pScrn);
+static void VIAUnmapMem(ScrnInfoPtr pScrn);
+
+static void VIALoadRgbLut(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, VisualPtr pVisual);
+
+DriverRec VIA =
+{
+ VIA_VERSION,
+ DRIVER_NAME,
+ VIAIdentify,
+ VIAProbe,
+ VIAAvailableOptions,
+ NULL,
+ 0
+};
+
+
+/* Supported chipsets */
+
+static SymTabRec VIAChipsets[] = {
+ {VIA_CLE266, "CLE266"},
+ {VIA_KM400, "KM400/KN400"},
+ {VIA_K8M800, "K8M800"},
+ {VIA_PM800, "PM800/PM880/CN400"},
+ {VIA_VM800, "VM800/CN700/P4M800Pro"},
+ {-1, NULL }
+};
+
+/* This table maps a PCI device ID to a chipset family identifier. */
+static PciChipsets VIAPciChipsets[] = {
+ /* {VIA_CLE266, PCI_CHIP_CLE3022, RES_SHARED_VGA}, */
+ {VIA_CLE266, PCI_CHIP_CLE3122, RES_SHARED_VGA},
+ {VIA_KM400, PCI_CHIP_VT3205, RES_SHARED_VGA},
+ {VIA_K8M800, PCI_CHIP_VT3204, RES_SHARED_VGA},
+ {VIA_PM800, PCI_CHIP_VT3259, RES_SHARED_VGA},
+ {VIA_VM800, PCI_CHIP_VT3314, RES_SHARED_VGA},
+ {-1, -1, RES_UNDEFINED}
+};
+
+int gVIAEntityIndex = -1;
+
+typedef enum {
+#ifdef HAVE_DEBUG
+ OPTION_PRINTVGAREGS,
+ OPTION_PRINTTVREGS,
+ OPTION_I2CSCAN,
+#endif /* HAVE_DEBUG */
+ OPTION_VBEMODES,
+ OPTION_NOACCEL,
+#ifdef VIA_HAVE_EXA
+ OPTION_ACCELMETHOD,
+ OPTION_EXA_NOCOMPOSITE,
+ OPTION_EXA_SCRATCH_SIZE,
+#endif
+ OPTION_SWCURSOR,
+ OPTION_HWCURSOR,
+ OPTION_SHADOW_FB,
+ OPTION_ROTATE,
+ OPTION_VIDEORAM,
+ OPTION_ACTIVEDEVICE,
+ OPTION_BUSWIDTH,
+ OPTION_CENTER,
+ OPTION_PANELSIZE,
+ OPTION_FORCEPANEL,
+ OPTION_TVDOTCRAWL,
+ OPTION_TVPROGRESSIVE,
+ OPTION_TVTYPE,
+ OPTION_TVOUTPUT,
+ OPTION_DISABLEVQ,
+ OPTION_DRIXINERAMA,
+ OPTION_DISABLEIRQ,
+ OPTION_TVDEFLICKER,
+ OPTION_AGP_DMA,
+ OPTION_2D_DMA,
+ OPTION_XV_DMA,
+ OPTION_VBE_SAVERESTORE,
+ OPTION_MAX_DRIMEM,
+ OPTION_AGPMEM,
+ OPTION_DISABLE_XV_BW_CHECK
+} VIAOpts;
+
+
+static OptionInfoRec VIAOptions[] =
+{
+#ifdef HAVE_DEBUG /* Don't document these */
+ {OPTION_PRINTVGAREGS, "PrintVGARegs", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_PRINTTVREGS, "PrintTVRegs", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_I2CSCAN, "I2CScan", OPTV_BOOLEAN, {0}, FALSE},
+#endif /* HAVE_DEBUG */
+ {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 /* VIA_HAVE_EXA */
+ {OPTION_HWCURSOR, "HWCursor", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_SWCURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE},
+ {OPTION_VIDEORAM, "VideoRAM", OPTV_INTEGER, {0}, FALSE},
+ {OPTION_ACTIVEDEVICE, "ActiveDevice", OPTV_ANYSTR, {0}, FALSE},
+ {OPTION_BUSWIDTH, "BusWidth", OPTV_ANYSTR, {0}, FALSE},
+ {OPTION_CENTER, "Center", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_PANELSIZE, "PanelSize", OPTV_ANYSTR, {0}, FALSE},
+ {OPTION_FORCEPANEL, "ForcePanel", OPTV_BOOLEAN, {0}, FALSE}, /* last resort - don't doc */
+ {OPTION_TVDOTCRAWL, "TVDotCrawl", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_TVDEFLICKER,"TVDeflicker", OPTV_INTEGER, {0}, FALSE},
+ {OPTION_TVPROGRESSIVE, "TVProgressive", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_TVTYPE, "TVType", OPTV_ANYSTR, {0}, FALSE},
+ {OPTION_TVOUTPUT, "TVOutput", OPTV_ANYSTR, {0}, FALSE},
+ {OPTION_DISABLEVQ, "DisableVQ", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_DISABLEIRQ, "DisableIRQ", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_AGP_DMA, "EnableAGPDMA", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_2D_DMA, "NoAGPFor2D", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_XV_DMA, "NoXVDMA", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_VBE_SAVERESTORE, "VbeSaveRestore", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_DISABLE_XV_BW_CHECK, "DisableXvBWCheck", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_MAX_DRIMEM, "MaxDRIMem", OPTV_INTEGER, {0}, FALSE},
+ {OPTION_AGPMEM, "AGPMem", OPTV_INTEGER, {0}, FALSE},
+ {-1, NULL, OPTV_NONE, {0}, FALSE}
+};
+
+
+static const char *vgaHWSymbols[] = {
+ "vgaHWGetHWRec",
+ "vgaHWSetMmioFuncs",
+ "vgaHWSetStdFuncs",
+ "vgaHWGetIOBase",
+ "vgaHWSave",
+ "vgaHWProtect",
+ "vgaHWRestore",
+ "vgaHWMapMem",
+ "vgaHWUnmapMem",
+ "vgaHWInit",
+ "vgaHWSaveScreen",
+ "vgaHWLock",
+ "vgaHWUnlock",
+ "vgaHWFreeHWRec",
+ "vgaHWGetIndex", /* Through VGAHWPTR() */
+ NULL
+};
+
+
+static const char *ramdacSymbols[] = {
+ "xf86InitCursor",
+ "xf86CreateCursorInfoRec",
+ "xf86DestroyCursorInfoRec",
+ NULL
+};
+
+static const char *vbeSymbols[] = {
+ "vbeDoEDID",
+ "VBEDPMSSet",
+ "VBEExtendedInit",
+ "vbeFree",
+ "VBEGetVBEInfo",
+ "VBEGetVBEMode",
+ "VBEGetModePool",
+ "VBEInit",
+ "VBEPrintModes",
+ "VBESaveRestore",
+ "VBESetDisplayStart",
+ "VBESetGetLogicalScanlineLength",
+ "VBESetLogicalScanline",
+ "VBESetModeNames",
+ "VBESetModeParameters",
+ "VBESetVBEMode",
+ "VBEValidateModes",
+ "xf86ExecX86int10",
+ "xf86Int10AllocPages",
+ "xf86Int10FreePages",
+ NULL
+};
+
+static const char *ddcSymbols[] = {
+ "xf86PrintEDID",
+ "xf86DoEDID_DDC2",
+ "xf86SetDDCproperties",
+ NULL
+};
+
+
+static const char *i2cSymbols[] = {
+ "xf86CreateI2CBusRec",
+ "xf86I2CBusInit",
+ "xf86CreateI2CDevRec",
+ "xf86I2CDevInit",
+ "xf86I2CWriteRead",
+ "xf86I2CProbeAddress",
+ "xf86DestroyI2CDevRec",
+ "xf86I2CReadByte",
+ "xf86I2CWriteByte",
+ NULL
+};
+
+static const char *xaaSymbols[] = {
+#ifdef X_HAVE_XAAGETROP
+ "XAAGetCopyROP",
+ "XAAGetCopyROP_PM",
+ "XAAGetPatternROP",
+#else
+ "XAACopyROP",
+ "XAACopyROP_PM",
+ "XAAPatternROP",
+#endif
+ "XAACreateInfoRec",
+ "XAADestroyInfoRec",
+ "XAAInit",
+ "XAAFillSolidRects",
+ NULL
+};
+
+#ifdef VIA_HAVE_EXA
+static const char *exaSymbols[] = {
+ "exaGetVersion",
+ "exaDriverInit",
+ "exaDriverFini",
+ "exaOffscreenAlloc",
+ "exaOffscreenFree",
+ "exaGetPixmapPitch",
+ "exaGetPixmapOffset",
+ "exaWaitSync",
+#if (EXA_VERSION_MAJOR >= 2)
+ "exaDriverAlloc",
+#else
+ "exaGetVersion",
+#endif
+ NULL
+};
+#endif
+
+static const char *shadowSymbols[] = {
+ "ShadowFBInit",
+ NULL
+};
+
+#ifdef USE_FB
+static const char *fbSymbols[] = {
+ "fbScreenInit",
+ "fbPictureInit",
+ NULL
+};
+#else
+static const char *cfbSymbols[] = {
+ "cfbScreenInit",
+ "cfb16ScreenInit",
+ "cfb24ScreenInit",
+ "cfb24_32ScreenInit",
+ "cfb32ScreenInit",
+ "cfb16BresS",
+ "cfb24BresS",
+ NULL
+};
+#endif
+
+#ifdef XFree86LOADER
+#ifdef XF86DRI
+static const char *drmSymbols[] = {
+ "drmAddBufs",
+ "drmAddMap",
+ "drmAgpAcquire",
+ "drmAgpAlloc",
+ "drmAgpBase",
+ "drmAgpBind",
+ "drmAgpDeviceId",
+ "drmAgpEnable",
+ "drmAgpFree",
+ "drmAgpGetMode",
+ "drmAgpRelease",
+ "drmAgpVendorId",
+ "drmCtlInstHandler",
+ "drmCtlUninstHandler",
+ "drmCommandNone",
+ "drmCommandWrite"
+ "drmCommandWriteRead",
+ "drmFreeVersion",
+ "drmGetInterruptFromBusID",
+ "drmGetLibVersion",
+ "drmGetVersion",
+ "drmMap",
+ "drmMapBufs",
+ "drmUnmap",
+ "drmUnmapBufs",
+ "drmAgpUnbind",
+ "drmRmMap",
+ "drmCreateContext",
+ "drmAuthMagic",
+ "drmDestroyContext",
+ "drmSetContextFlags",
+ NULL
+};
+
+static const char *driSymbols[] = {
+ "DRICloseScreen",
+ "DRICreateInfoRec",
+ "DRIDestroyInfoRec",
+ "DRIFinishScreenInit",
+ "DRIGetSAREAPrivate",
+ "DRILock",
+ "DRIQueryVersion",
+ "DRIScreenInit",
+ "DRIUnlock",
+ "DRIOpenConnection",
+ "DRICloseConnection",
+ "GlxSetVisualConfigs",
+ NULL
+};
+#endif
+
+static MODULESETUPPROTO(VIASetup);
+
+static XF86ModuleVersionInfo VIAVersRec = {
+ "via",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+#ifdef XORG_VERSION_CURRENT
+ XORG_VERSION_CURRENT,
+#else
+ XF86_VERSION_CURRENT,
+#endif
+ VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0, 0, 0, 0}
+};
+
+XF86ModuleData viaModuleData = {&VIAVersRec, VIASetup, NULL};
+
+static pointer VIASetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&VIA, module, 0);
+ LoaderRefSymLists(vgaHWSymbols,
+#ifdef USE_FB
+ fbSymbols,
+#else
+ cfbSymbols,
+#endif
+ ramdacSymbols,
+ xaaSymbols,
+#ifdef VIA_HAVE_EXA
+ exaSymbols,
+#endif
+ shadowSymbols,
+ vbeSymbols,
+ i2cSymbols,
+ ddcSymbols,
+#ifdef XF86DRI
+ drmSymbols,
+ driSymbols,
+#endif
+ NULL);
+
+ return (pointer) 1;
+ }
+ else {
+ if (errmaj)
+ *errmaj = LDR_ONCEONLY;
+
+ return NULL;
+ }
+} /* VIASetup */
+
+#endif /* XFree86LOADER */
+
+static Bool VIAGetRec(ScrnInfoPtr pScrn)
+{
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAGetRec\n"));
+ 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;
+
+ ((VIARec *)(pScrn->driverPrivate))->CursorImage = NULL;
+
+ return TRUE;
+
+} /* VIAGetRec */
+
+
+static void VIAFreeRec(ScrnInfoPtr pScrn)
+{
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAFreeRec\n"));
+ if (!pScrn->driverPrivate)
+ return;
+
+ if (VIAPTR(pScrn)->pVbe)
+ vbeFree(VIAPTR(pScrn)->pVbe);
+
+ if (((VIARec *)(pScrn->driverPrivate))->pBIOSInfo->TVI2CDev)
+ xf86DestroyI2CDevRec((((VIARec *)(pScrn->driverPrivate))->pBIOSInfo->TVI2CDev), TRUE);
+ xfree(((VIARec *)(pScrn->driverPrivate))->pBIOSInfo);
+
+ VIAUnmapMem(pScrn);
+
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+} /* VIAFreeRec */
+
+
+
+static const OptionInfoRec * VIAAvailableOptions(int chipid, int busid)
+{
+
+ return VIAOptions;
+
+} /* VIAAvailableOptions */
+
+
+static void VIAIdentify(int flags)
+{
+ xf86PrintChipsets("VIA", "driver for VIA chipsets", VIAChipsets);
+} /* VIAIdentify */
+
+static Bool VIAProbe(DriverPtr drv, int flags)
+{
+ GDevPtr *devSections;
+ int *usedChips;
+ int numDevSections;
+ int numUsed;
+ Bool foundScreen = FALSE;
+ int i;
+
+ /* sanity checks */
+ if ((numDevSections = xf86MatchDevice(DRIVER_NAME, &devSections)) <= 0)
+ return FALSE;
+
+ if (xf86GetPciVideoInfo() == NULL)
+ return FALSE;
+
+ numUsed = xf86MatchPciInstances(DRIVER_NAME,
+ PCI_VIA_VENDOR_ID,
+ VIAChipsets,
+ VIAPciChipsets,
+ devSections,
+ numDevSections,
+ drv,
+ &usedChips);
+ xfree(devSections);
+
+ if (numUsed <= 0)
+ return FALSE;
+
+ xf86Msg(X_NOTICE, "VIA Technologies does not support or endorse this driver in any way.\n");
+ xf86Msg(X_NOTICE, "For support, please refer to http://www.openchrome.org/ or\n");
+ xf86Msg(X_NOTICE, "your X vendor.\n");
+
+#ifdef BUILDCOMMENT
+ xf86Msg(X_NOTICE, BUILDCOMMENT);
+#endif
+
+ if (flags & PROBE_DETECT) {
+ foundScreen = TRUE;
+ }
+ else {
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn = xf86AllocateScreen(drv, 0);
+ EntityInfoPtr pEnt;
+ if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
+ VIAPciChipsets, 0, 0, 0, 0, 0)))
+ {
+ pScrn->driverVersion = VIA_VERSION;
+ pScrn->driverName = DRIVER_NAME;
+ pScrn->name = "VIA";
+ pScrn->Probe = VIAProbe;
+ pScrn->PreInit = VIAPreInit;
+ pScrn->ScreenInit = VIAScreenInit;
+ pScrn->SwitchMode = VIASwitchMode;
+ pScrn->AdjustFrame = VIAAdjustFrame;
+ pScrn->EnterVT = VIAEnterVT;
+ pScrn->LeaveVT = VIALeaveVT;
+ pScrn->FreeScreen = VIAFreeScreen;
+ pScrn->ValidMode = ViaValidMode;
+ foundScreen = TRUE;
+ }
+ /*
+ xf86ConfigActivePciEntity(pScrn,
+ usedChips[i],
+ VIAPciChipsets,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ */
+ pEnt = xf86GetEntityInfo(usedChips[i]);
+
+ /* CLE266 card support Dual-Head, mark the entity as sharable*/
+ if(pEnt->chipset == VIA_CLE266 || pEnt->chipset == VIA_KM400)
+ {
+ static int instance = 0;
+ DevUnion* pPriv;
+
+ xf86SetEntitySharable(usedChips[i]);
+ xf86SetEntityInstanceForScreen(pScrn,
+ pScrn->entityList[0], instance);
+
+ if(gVIAEntityIndex < 0)
+ {
+ gVIAEntityIndex = xf86AllocateEntityPrivateIndex();
+ pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+ gVIAEntityIndex);
+
+ if (!pPriv->ptr)
+ {
+ VIAEntPtr pVIAEnt;
+ pPriv->ptr = xnfcalloc(sizeof(VIAEntRec), 1);
+ pVIAEnt = pPriv->ptr;
+ pVIAEnt->IsDRIEnabled = FALSE;
+ pVIAEnt->BypassSecondary = FALSE;
+ pVIAEnt->HasSecondary = FALSE;
+ pVIAEnt->IsSecondaryRestored = FALSE;
+ }
+ }
+ instance++;
+ }
+ xfree(pEnt);
+ }
+ }
+
+ xfree(usedChips);
+
+ return foundScreen;
+
+} /* VIAProbe */
+
+#ifdef XF86DRI
+static void kickVblank(ScrnInfoPtr pScrn)
+{
+ /*
+ * Switching mode will clear registers that make vblank
+ * interrupts happen. If the driver thinks interrupts
+ * are enabled, make sure vblank interrupts go through.
+ * registers are not documented in VIA docs.
+ */
+
+ VIAPtr pVia = VIAPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate;
+
+ if (pVIADRI->irqEnabled) {
+ hwp->writeCrtc(hwp, 0x11, hwp->readCrtc(hwp, 0x11) | 0x30);
+ }
+}
+#endif
+
+static int LookupChipSet(PciChipsets *pset, int chipSet)
+{
+ while (pset->numChipset >= 0) {
+ if (pset->numChipset == chipSet) return pset->PCIid;
+ pset++;
+ }
+ return -1;
+}
+
+
+static int LookupChipID(PciChipsets* pset, int ChipID)
+{
+ /* Is there a function to do this for me? */
+ while (pset->numChipset >= 0)
+ {
+ if (pset->PCIid == ChipID)
+ return pset->numChipset;
+
+ pset++;
+ }
+
+ return -1;
+
+} /* LookupChipID */
+
+static void
+VIAProbeDDC(ScrnInfoPtr pScrn, int index)
+{
+ vbeInfoPtr pVbe;
+
+ if (xf86LoadSubModule(pScrn, "vbe")) {
+ xf86LoaderReqSymLists(vbeSymbols, NULL);
+ pVbe = VBEInit(NULL,index);
+ ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
+ vbeFree(pVbe);
+ }
+}
+
+static Bool VIASetupDefaultOptions(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIASetupDefaultOptions\n"));
+
+ pVia->shadowFB = FALSE;
+ pVia->NoAccel = FALSE;
+#ifdef VIA_HAVE_EXA
+ pVia->noComposite = FALSE;
+ pVia->exaScratchSize = VIA_SCRATCH_SIZE / 1024;
+#endif /* VIA_HAVE_EXA */
+ pVia->hwcursor = pVia->shadowFB ? FALSE : TRUE;
+ pVia->VQEnable = TRUE;
+ pVia->DRIIrqEnable = TRUE;
+ pVia->agpEnable = TRUE;
+ pVia->dma2d = TRUE;
+ pVia->dmaXV = TRUE;
+ pVia->useVBEModes = FALSE;
+ pVia->vbeSR = FALSE;
+#ifdef HAVE_DEBUG
+ pVia->disableXvBWCheck = FALSE;
+#endif
+ pVia->maxDriSize = 0;
+ pVia->agpMem = AGP_SIZE / 1024;
+ pVia->ActiveDevice = 0x00;
+#ifdef HAVE_DEBUG
+ pVia->PrintVGARegs = FALSE;
+#endif
+
+ switch (pVia->Chipset)
+ {
+ case VIA_KM400:
+ pVia->DRIIrqEnable = FALSE;
+ break;
+ case VIA_K8M800:
+ pVia->DRIIrqEnable = FALSE;
+ break;
+ }
+
+ return TRUE;
+}
+
+
+static Bool VIAPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ EntityInfoPtr pEnt;
+ VIAPtr pVia;
+ VIABIOSInfoPtr pBIOSInfo;
+ MessageType from = X_DEFAULT;
+ ClockRangePtr clockRanges;
+ char *s = NULL;
+#ifndef USE_FB
+ char *mod = NULL;
+ const char *reqSym = NULL;
+#endif
+ vgaHWPtr hwp;
+ int i, bMemSize = 0;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAPreInit\n"));
+
+ if (pScrn->numEntities > 1)
+ return FALSE;
+
+ if (flags & PROBE_DETECT)
+ return FALSE;
+
+ if (!xf86LoadSubModule(pScrn, "vgahw"))
+ return FALSE;
+
+ xf86LoaderReqSymLists(vgaHWSymbols, NULL);
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+
+#if 0
+ /* Here we can alter the number of registers saved and restored by the
+ * standard vgaHWSave and Restore routines.
+ */
+ vgaHWSetRegCounts(pScrn, VGA_NUM_CRTC, VGA_NUM_SEQ, VGA_NUM_GFX, VGA_NUM_ATTR);
+#endif
+
+ if (!VIAGetRec(pScrn)) {
+ return FALSE;
+ }
+
+ pVia = VIAPTR(pScrn);
+ pBIOSInfo = pVia->pBIOSInfo;
+
+ pVia->IsSecondary = FALSE;
+ pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (pEnt->resources) {
+ xfree(pEnt);
+ VIAFreeRec(pScrn);
+ return FALSE;
+ }
+
+ pVia->EntityIndex = pEnt->index;
+
+ if(xf86IsEntityShared(pScrn->entityList[0]))
+ {
+ if(xf86IsPrimInitDone(pScrn->entityList[0]))
+ {
+ DevUnion* pPriv;
+ VIAEntPtr pVIAEnt;
+ VIAPtr pVia1;
+
+ pVia->IsSecondary = TRUE;
+ pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+ gVIAEntityIndex);
+ pVIAEnt = pPriv->ptr;
+ if (pVIAEnt->BypassSecondary) {
+ xfree(pEnt);
+ VIAFreeRec(pScrn);
+ return FALSE;
+ }
+ pVIAEnt->pSecondaryScrn = pScrn;
+ pVIAEnt->HasSecondary = TRUE;
+ pVia1 = VIAPTR(pVIAEnt->pPrimaryScrn);
+ pVia1->HasSecondary = TRUE;
+ pVia->sharedData = pVia1->sharedData;
+ }
+ else
+ {
+ DevUnion* pPriv;
+ VIAEntPtr pVIAEnt;
+
+ xf86SetPrimInitDone(pScrn->entityList[0]);
+ pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+ gVIAEntityIndex);
+ pVia->sharedData = xnfcalloc(sizeof(ViaSharedRec),1);
+ pVIAEnt = pPriv->ptr;
+ pVIAEnt->pPrimaryScrn = pScrn;
+ pVIAEnt->IsDRIEnabled = FALSE;
+ pVIAEnt->BypassSecondary = FALSE;
+ pVIAEnt->HasSecondary = FALSE;
+ pVIAEnt->RestorePrimary = FALSE;
+ pVIAEnt->IsSecondaryRestored = FALSE;
+ }
+ } else {
+ pVia->sharedData = xnfcalloc(sizeof(ViaSharedRec),1);
+ }
+
+ if (flags & PROBE_DETECT) {
+ VIAProbeDDC(pScrn, pVia->EntityIndex);
+ return TRUE;
+ }
+
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /*
+ * We support depths of 8, 16 and 24.
+ * We support bpp of 8, 16, and 32.
+ */
+
+ if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) {
+ xfree(pEnt);
+ VIAFreeRec(pScrn);
+ return FALSE;
+ }
+ else {
+ switch (pScrn->depth) {
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ /* OK */
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ xfree(pEnt);
+ VIAFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+
+ xf86PrintDepthBpp(pScrn);
+
+ if (pScrn->depth == 32) {
+ pScrn->depth = 24;
+ }
+
+ if (pScrn->depth > 8) {
+ rgb zeros = {0, 0, 0};
+
+ if (!xf86SetWeight(pScrn, zeros, zeros)) {
+ xfree(pEnt);
+ VIAFreeRec(pScrn);
+ return FALSE;
+ } else {
+ /* TODO check weight returned is supported */
+ ;
+ }
+ }
+
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ }
+ else {
+ /* We don't currently support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d.\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ xfree(pEnt);
+ VIAFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+
+ /* We use a programmable clock */
+ pScrn->progClock = TRUE;
+
+ xf86CollectOptions(pScrn, NULL);
+
+ /* Set the bits per RGB for 8bpp mode */
+ if (pScrn->depth == 8)
+ pScrn->rgbBits = 6;
+
+ pVia->PciInfo = xf86GetPciInfoForEntity(pEnt->index);
+ xf86RegisterResources(pEnt->index, NULL, ResNone);
+
+ /*
+ xf86SetOperatingState(RES_SHARED_VGA, pEnt->index, ResUnusedOpr);
+ xf86SetOperatingState(resVgaMemShared, pEnt->index, ResDisableOpr);
+ */
+
+ if (pEnt->device->chipset && *pEnt->device->chipset) {
+ pScrn->chipset = pEnt->device->chipset;
+ pVia->Chipset = xf86StringToToken(VIAChipsets, pScrn->chipset);
+ pVia->ChipId = pEnt->device->chipID = LookupChipSet(VIAPciChipsets, pVia->Chipset);
+ from = X_CONFIG;
+ } else if (pEnt->device->chipID >= 0) {
+ pVia->ChipId = pEnt->device->chipID;
+ pVia->Chipset = LookupChipID(VIAPciChipsets, pVia->ChipId);
+ pScrn->chipset = (char *)xf86TokenToString(VIAChipsets,
+ pVia->Chipset);
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
+ pEnt->device->chipID);
+ } else {
+ from = X_PROBED;
+ pVia->ChipId = pVia->PciInfo->chipType;
+ pVia->Chipset = LookupChipID(VIAPciChipsets, pVia->ChipId);
+ pScrn->chipset = (char *)xf86TokenToString(VIAChipsets,
+ pVia->Chipset);
+ }
+
+ if (pEnt->device->chipRev >= 0) {
+ pVia->ChipRev = pEnt->device->chipRev;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
+ pVia->ChipRev);
+ }
+ else {
+ /*pVia->ChipRev = pVia->PciInfo->chipRev;*/
+ /* Read PCI bus 0, dev 0, function 0, index 0xF6 to get chip rev. */
+ pVia->ChipRev = pciReadByte(pciTag(0, 0, 0), 0xF6);
+ }
+
+ from = X_DEFAULT;
+
+ pScrn->videoRam = pEnt->device->videoRam;
+ from = xf86GetOptValInteger(VIAOptions, OPTION_VIDEORAM,
+ &pScrn->videoRam) ?
+ X_CONFIG : X_PROBED;
+ xf86DrvMsg( pScrn->scrnIndex, X_CONFIG,
+ "VideoRAM %dkB\n", pScrn->videoRam );
+
+ if (pEnt->device->videoRam != 0) {
+ if (!pScrn->videoRam)
+ pScrn->videoRam = pEnt->device->videoRam;
+ else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Video Memory Size in Option is %d KB, Detect is %d KB!",
+ pScrn->videoRam, pEnt->device->videoRam);
+ }
+ }
+
+ xfree(pEnt);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Setting up default chipset options...\n");
+
+ if (!VIASetupDefaultOptions(pScrn)) {
+ VIAFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, VIAOptions);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Starting to parse config file options...\n");
+ //pVia->shadowFB = FALSE;
+ from = xf86GetOptValBool(VIAOptions, OPTION_SHADOW_FB, &pVia->shadowFB) ?
+ X_CONFIG : X_DEFAULT;
+ xf86DrvMsg(pScrn->scrnIndex, from, "ShadowFB is %s.\n",
+ pVia->shadowFB ? "enabled" : "disabled");
+
+ if ((s = xf86GetOptValString(VIAOptions, OPTION_ROTATE))) {
+ if (!xf86NameCmp(s, "CW")) {
+ /* accel is disabled below for shadowFB */
+ pVia->shadowFB = TRUE;
+ pVia->rotate = 1;
+ pVia->hwcursor = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Rotating screen clockwise - acceleration disabled.\n");
+ }
+ else if(!xf86NameCmp(s, "CCW")) {
+ pVia->shadowFB = TRUE;
+ pVia->rotate = -1;
+ pVia->hwcursor = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen"
+ "counter clockwise - acceleration disabled.\n");
+ }
+ else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid"
+ "value for Option \"Rotate\".\n", s);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Valid options are \"CW\" or \"CCW\".\n");
+ }
+ }
+
+ //pVia->NoAccel = FALSE;
+ from = xf86GetOptValBool(VIAOptions, OPTION_NOACCEL, &pVia->NoAccel) ?
+ X_CONFIG : X_DEFAULT;
+ xf86DrvMsg(pScrn->scrnIndex, from, "Acceleration is %s.\n",
+ !pVia->NoAccel ? "enabled" : "disabled");
+
+ if (pVia->shadowFB && !pVia->NoAccel) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "HW acceleration not supported with \"shadowFB\".\n");
+ pVia->NoAccel = TRUE;
+ }
+
+#ifdef VIA_HAVE_EXA
+ if(!pVia->NoAccel) {
+ from = X_DEFAULT;
+ if((s = (char *)xf86GetOptValString(VIAOptions, OPTION_ACCELMETHOD))) {
+ if(!xf86NameCmp(s,"XAA")) {
+ from = X_CONFIG;
+ pVia->useEXA = FALSE;
+ }
+ else if(!xf86NameCmp(s,"EXA")) {
+ from = X_CONFIG;
+ pVia->useEXA = TRUE;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration architecture.\n",
+ pVia->useEXA ? "EXA" : "XAA");
+
+ //pVia->noComposite = FALSE;
+ if (pVia->useEXA) {
+ from = xf86GetOptValBool(VIAOptions, OPTION_EXA_NOCOMPOSITE,
+ &pVia->noComposite) ?
+ X_CONFIG : X_DEFAULT;
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "EXA composite acceleration %s.\n",
+ !pVia->noComposite ? "enabled" : "disabled");
+
+ //pVia->exaScratchSize = VIA_SCRATCH_SIZE / 1024;
+ from = xf86GetOptValInteger(VIAOptions, OPTION_EXA_SCRATCH_SIZE,
+ &pVia->exaScratchSize) ?
+ X_CONFIG : X_DEFAULT;
+ xf86DrvMsg( pScrn->scrnIndex, from,
+ "EXA scratch area size is %dkB.\n",
+ pVia->exaScratchSize );
+ }
+ }
+#endif /* VIA_HAVE_EXA */
+
+ /*
+ * The SWCursor setting takes priority over HWCursor. The default
+ * if neither is specified is HW.
+ */
+
+ from = X_DEFAULT;
+ //pVia->hwcursor = pVia->shadowFB ? FALSE : TRUE;
+ if (xf86GetOptValBool(VIAOptions, OPTION_HWCURSOR, &pVia->hwcursor))
+ from = X_CONFIG;
+
+ if (xf86GetOptValBool(VIAOptions, OPTION_SWCURSOR, &pVia->hwcursor)) {
+ pVia->hwcursor = !pVia->hwcursor;
+ from = X_CONFIG;
+ }
+
+ if (pVia->IsSecondary)
+ pVia->hwcursor = FALSE;
+
+ if (pVia->hwcursor) {
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Hardware two-color cursors.\n"
+ "\tSoftware full color cursors.\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using software cursors.\n");
+ }
+
+ //pVia->VQEnable = TRUE;
+ from = xf86GetOptValBool(VIAOptions, OPTION_DISABLEVQ, &pVia->VQEnable)
+ ? X_CONFIG : X_DEFAULT;
+ if (from == X_CONFIG)
+ pVia->VQEnable = !pVia->VQEnable;
+ xf86DrvMsg(pScrn->scrnIndex, from, "GPU virtual command queue will be %s.\n",
+ (pVia->VQEnable) ? "enabled" : "disabled");
+
+ //pVia->DRIIrqEnable = TRUE;
+ from = xf86GetOptValBool(VIAOptions, OPTION_DISABLEIRQ,
+ &pVia->DRIIrqEnable)
+ ? X_CONFIG : X_DEFAULT;
+ if (from == X_CONFIG)
+ pVia->DRIIrqEnable = !pVia->DRIIrqEnable;
+ xf86DrvMsg(pScrn->scrnIndex, from, "DRI IRQ will be %s if DRI is enabled.\n",
+ (pVia->DRIIrqEnable) ? "enabled" : "disabled");
+
+ //pVia->agpEnable = FALSE;
+ from = xf86GetOptValBool(VIAOptions, OPTION_AGP_DMA, &pVia->agpEnable)
+ ? X_CONFIG : X_DEFAULT;
+ xf86DrvMsg(pScrn->scrnIndex, from, "AGP DMA will be %s if DRI is enabled.\n",
+ (pVia->agpEnable) ? "enabled" : "disabled");
+
+ //pVia->dma2d = TRUE;
+ if (pVia->agpEnable) {
+ from = xf86GetOptValBool(VIAOptions, OPTION_2D_DMA, &pVia->dma2d)
+ ? X_CONFIG : X_DEFAULT;
+ if (from == X_CONFIG)
+ pVia->dma2d = !pVia->dma2d;
+ xf86DrvMsg(pScrn->scrnIndex, from, "AGP DMA will %sbe used for 2D "
+ "acceleration.\n",
+ (pVia->dma2d) ? "" : "not ");
+ }
+
+ //pVia->dmaXV = TRUE;
+ from = xf86GetOptValBool(VIAOptions, OPTION_XV_DMA, &pVia->dmaXV)
+ ? X_CONFIG : X_DEFAULT;
+ if (from == X_CONFIG)
+ pVia->dmaXV = !pVia->dmaXV;
+ xf86DrvMsg(pScrn->scrnIndex, from, "PCI DMA will %sbe used for XV "
+ "image transfer if DRI is enabled.\n",
+ (pVia->dmaXV) ? "" : "not ");
+
+ //pVia->useVBEModes = FALSE;
+ from = xf86GetOptValBool(VIAOptions, OPTION_VBEMODES, &pVia->useVBEModes)
+ ? X_CONFIG : X_DEFAULT;
+ xf86DrvMsg(pScrn->scrnIndex, from, "Will %senable VBE modes.\n",
+ (pVia->useVBEModes) ? "" : "not ");
+
+ //pVia->vbeSR = FALSE;
+ from = xf86GetOptValBool(VIAOptions, OPTION_VBE_SAVERESTORE, &pVia->vbeSR)
+ ? X_CONFIG : X_DEFAULT;
+ xf86DrvMsg(pScrn->scrnIndex, from, "VBE VGA register save & restore "
+ "will %sbe used\n\tif VBE modes are enabled.\n",
+ (pVia->vbeSR) ? "" : "not ");
+
+#ifdef HAVE_DEBUG
+ //pVia->disableXvBWCheck = FALSE;
+ from = xf86GetOptValBool(VIAOptions, OPTION_DISABLE_XV_BW_CHECK,
+ &pVia->disableXvBWCheck)
+ ? X_CONFIG : X_DEFAULT;
+ xf86DrvMsg(pScrn->scrnIndex, from, "Xv Bandwidth check is %s.\n",
+ pVia->disableXvBWCheck ? "disabled" : "enabled");
+ if (pVia->disableXvBWCheck) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "You may get a \"snowy\" screen"
+ " when using the Xv overlay.\n");
+ }
+#endif
+
+ //pVia->maxDriSize = 0;
+ from = xf86GetOptValInteger(VIAOptions, OPTION_MAX_DRIMEM,
+ &pVia->maxDriSize)
+ ? X_CONFIG : X_DEFAULT;
+ if (pVia->maxDriSize > 0)
+ xf86DrvMsg( pScrn->scrnIndex, from,
+ "Will impose a %dkB limit on video-ram set aside for DRI.\n",
+ pVia->maxDriSize );
+ else
+ xf86DrvMsg( pScrn->scrnIndex, from,
+ "Will not impose a limit on video-ram set aside for DRI.\n");
+
+ //pVia->agpMem = AGP_SIZE / 1024;
+ from = xf86GetOptValInteger(VIAOptions, OPTION_AGPMEM,
+ &pVia->agpMem)
+ ? X_CONFIG : X_DEFAULT;
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Will try to allocate %dkB of AGP memory.\n",
+ pVia->agpMem );
+
+ /* ActiveDevice Option for device selection */
+ //pVia->ActiveDevice = 0x00;
+ if ((s = xf86GetOptValString(VIAOptions, OPTION_ACTIVEDEVICE))) {
+ if (xf86strstr(s, "CRT"))
+ pVia->ActiveDevice |= VIA_DEVICE_CRT;
+ if (xf86strstr(s, "LCD"))
+ pVia->ActiveDevice |= VIA_DEVICE_LCD;
+ if (xf86strstr(s, "DFP")) /* just treat this the same as LCD */
+ pVia->ActiveDevice |= VIA_DEVICE_LCD;
+ if (xf86strstr(s, "TV"))
+ pVia->ActiveDevice |= VIA_DEVICE_TV;
+ }
+
+ /* Digital Output Bus Width Option */
+ pBIOSInfo->BusWidth = VIA_DI_12BIT;
+ from = X_DEFAULT;
+ if ((s = xf86GetOptValString(VIAOptions, OPTION_BUSWIDTH))) {
+ from = X_CONFIG;
+ if (!xf86NameCmp(s, "12BIT")) {
+ pBIOSInfo->BusWidth = VIA_DI_12BIT;
+ } else if (!xf86NameCmp(s, "24BIT")) {
+ pBIOSInfo->BusWidth = VIA_DI_24BIT;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Digital output bus width is %d bits.\n",
+ (pBIOSInfo->BusWidth == VIA_DI_12BIT) ? 12:24);
+
+
+ /* LCD Center/Expend Option */
+ pBIOSInfo->Center = FALSE;
+ from = xf86GetOptValBool(VIAOptions, OPTION_CENTER, &pBIOSInfo->Center)
+ ? X_CONFIG : X_DEFAULT;
+ 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;
+ 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");
+ }
+ } 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,
+ &pBIOSInfo->ForcePanel)
+ ? X_CONFIG:X_DEFAULT;
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Panel will %sbe forced.\n",
+ pBIOSInfo->ForcePanel ? "" : "not ");
+
+ pBIOSInfo->TVDotCrawl = FALSE;
+ from = xf86GetOptValBool(VIAOptions, OPTION_TVDOTCRAWL,
+ &pBIOSInfo->TVDotCrawl)
+ ? X_CONFIG:X_DEFAULT;
+ xf86DrvMsg(pScrn->scrnIndex, from, "TV dotCrawl is %s.\n",
+ pBIOSInfo->TVDotCrawl ? "enabled" : "disabled");
+
+ /* TV Deflicker */
+ pBIOSInfo->TVDeflicker = 0;
+ from = xf86GetOptValInteger(VIAOptions, OPTION_TVDEFLICKER,
+ &pBIOSInfo->TVDeflicker)
+ ? X_CONFIG:X_DEFAULT;
+ xf86DrvMsg( pScrn->scrnIndex, from, "TV deflicker is set to %d.\n",
+ pBIOSInfo->TVDeflicker );
+
+ pBIOSInfo->TVType = TVTYPE_NONE;
+ if ((s = xf86GetOptValString(VIAOptions, OPTION_TVTYPE))) {
+ if (!xf86NameCmp(s, "NTSC")) {
+ pBIOSInfo->TVType = TVTYPE_NTSC;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Type is NTSC.\n");
+ }
+ else if(!xf86NameCmp(s, "PAL")) {
+ pBIOSInfo->TVType = TVTYPE_PAL;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Type is PAL.\n");
+ }
+ else if(!xf86NameCmp(s, "480P")) {
+ pBIOSInfo->TVType = TVTYPE_480P;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Type is SDTV 480P.\n");
+ }
+ else if(!xf86NameCmp(s, "576P")) {
+ pBIOSInfo->TVType = TVTYPE_576P;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Type is SDTV 576P.\n");
+ }
+ else if(!xf86NameCmp(s, "720P")) {
+ pBIOSInfo->TVType = TVTYPE_720P;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Type is HDTV 720P.\n");
+ }
+ else if(!xf86NameCmp(s, "1080I")) {
+ pBIOSInfo->TVType = TVTYPE_1080I;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Type is HDTV 1080i.\n");
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
+ "No default TV type is set.\n");
+ }
+
+ /* TV out put signal Option */
+ pBIOSInfo->TVOutput = TVOUTPUT_NONE;
+ if ((s = xf86GetOptValString(VIAOptions, OPTION_TVOUTPUT))) {
+ if (!xf86NameCmp(s, "S-Video")) {
+ pBIOSInfo->TVOutput = TVOUTPUT_SVIDEO;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Output Signal is S-Video.\n");
+ }
+ else if(!xf86NameCmp(s, "Composite")) {
+ pBIOSInfo->TVOutput = TVOUTPUT_COMPOSITE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Output Signal is Composite.\n");
+ }
+ else if(!xf86NameCmp(s, "SC")) {
+ pBIOSInfo->TVOutput = TVOUTPUT_SC;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Output Signal is SC.\n");
+ }
+ else if(!xf86NameCmp(s, "RGB")) {
+ pBIOSInfo->TVOutput = TVOUTPUT_RGB;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Output Signal is RGB.\n");
+ }
+ else if(!xf86NameCmp(s, "YCbCr")) {
+ pBIOSInfo->TVOutput = TVOUTPUT_YCBCR;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Output Signal is YCbCr.\n");
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
+ "No default TV output signal type is set.\n");
+ }
+
+ VIAVidHWDiffInit(pScrn);
+
+ /* maybe throw in some more sanity checks here */
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
+
+ pVia->PciTag = pciTag(pVia->PciInfo->bus, pVia->PciInfo->device,
+ pVia->PciInfo->func);
+
+ if (!VIAMapMMIO(pScrn)) {
+ VIAFreeRec(pScrn);
+ return FALSE;
+ }
+ hwp = VGAHWPTR(pScrn);
+
+
+#ifdef HAVE_DEBUG
+ //pVia->PrintVGARegs = FALSE;
+ from = xf86GetOptValBool(VIAOptions, OPTION_PRINTVGAREGS,
+ &pVia->PrintVGARegs)
+ ? X_CONFIG : X_DEFAULT;
+ xf86DrvMsg(pScrn->scrnIndex, from, "Will %sprint VGA Registers.\n",
+ pVia->PrintVGARegs ? "" : "not ");
+ if (pVia->PrintVGARegs)
+ ViaVgahwPrint(VGAHWPTR(pScrn)); /* Do this as early as possible */
+
+ pVia->I2CScan = FALSE;
+ from = xf86GetOptValBool(VIAOptions, OPTION_I2CSCAN, &pVia->I2CScan)
+ ? X_CONFIG : X_DEFAULT;
+ xf86DrvMsg(pScrn->scrnIndex, from, "Will %sscan I2C buses.\n",
+ pVia->I2CScan ? "" : "not ");
+#endif /* HAVE_DEBUG */
+
+ if (pVia->Chipset == VIA_CLE266)
+ ViaDoubleCheckCLE266Revision(pScrn);
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Chipset Rev.: %d\n", pVia->ChipRev);
+
+ ViaCheckCardId(pScrn);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "...Finished parsing config file options.\n");
+
+
+ /* read memory bandwidth from registers */
+ pVia->MemClk = hwp->readCrtc(hwp, 0x3D) >> 4;
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Detected MemClk %d\n", pVia->MemClk));
+ if (pVia->MemClk >= VIA_MEM_END) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unknown Memory clock: %d\n", pVia->MemClk);
+ pVia->MemClk = VIA_MEM_END - 1;
+ }
+ pBIOSInfo->Bandwidth = ViaGetMemoryBandwidth(pScrn);
+
+ if (pBIOSInfo->TVType == TVTYPE_NONE) {
+ /* use jumper to determine TV Type */
+
+ if (hwp->readCrtc(hwp, 0x3B) & 0x02) {
+ pBIOSInfo->TVType = TVTYPE_PAL;
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Detected TV Standard: PAL.\n"));
+ }
+ else {
+ pBIOSInfo->TVType = TVTYPE_NTSC;
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Detected TV Standard: NTSC.\n"));
+ }
+ }
+
+ {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros)) {
+ VIAFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+
+ /* Detect amount of installed RAM */
+ if (pScrn->videoRam < 16384 || pScrn->videoRam > 65536) {
+ if(pVia->Chipset == VIA_CLE266) {
+ bMemSize = hwp->readSeq(hwp, 0x34);
+ if (!bMemSize) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "CR34 says nothing; trying CR39.\n");
+ bMemSize = hwp->readSeq(hwp, 0x39);
+ }
+ } else
+ bMemSize = hwp->readSeq(hwp, 0x39);
+
+ if (bMemSize > 16 && bMemSize <= 128)
+ pScrn->videoRam = (bMemSize + 1) << 9;
+ else if (bMemSize > 0 && bMemSize < 31)
+ pScrn->videoRam = bMemSize << 12;
+ else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Memory size detection failed: using 16MB.\n");
+ pScrn->videoRam = 16 << 10; /* Assume the basic 16MB */
+ }
+ }
+
+ /* Split FB for SAMM */
+ /* FIXME: For now, split FB into two equal sections. This should
+ * be able to be adjusted by user with a config option. */
+ if (pVia->IsSecondary) {
+ DevUnion* pPriv;
+ VIAEntPtr pVIAEnt;
+ VIAPtr pVia1;
+
+ pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+ gVIAEntityIndex);
+ pVIAEnt = pPriv->ptr;
+ pScrn->videoRam = pScrn->videoRam >> 1;
+ pVIAEnt->pPrimaryScrn->videoRam = pScrn->videoRam;
+ pVia1 = VIAPTR(pVIAEnt->pPrimaryScrn);
+ pVia1->videoRambytes = pScrn->videoRam << 10;
+ pVia->FrameBufferBase += (pScrn->videoRam << 10);
+ }
+
+ pVia->videoRambytes = pScrn->videoRam << 10;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,"videoram = %dk\n",
+ pScrn->videoRam);
+
+ if (!xf86LoadSubModule(pScrn, "i2c")) {
+ VIAFreeRec(pScrn);
+ return FALSE;
+ }
+ else {
+ xf86LoaderReqSymLists(i2cSymbols,NULL);
+ ViaI2CInit(pScrn);
+ }
+
+ if (!xf86LoadSubModule(pScrn, "ddc")) {
+ VIAFreeRec(pScrn);
+ return FALSE;
+ } else {
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+
+ if (pVia->pI2CBus1) {
+ pVia->DDC1 = xf86DoEDID_DDC2(pScrn->scrnIndex, pVia->pI2CBus1);
+ if (pVia->DDC1) {
+ xf86PrintEDID(pVia->DDC1);
+ xf86SetDDCproperties(pScrn, pVia->DDC1);
+ }
+ }
+ }
+
+ ViaOutputsDetect(pScrn);
+ if (!ViaOutputsSelect(pScrn)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No outputs possible.\n");
+ VIAFreeRec(pScrn);
+ return FALSE;
+ }
+
+ if (pBIOSInfo->PanelActive && ((pVia->Chipset == VIA_K8M800) ||
+ (pVia->Chipset == VIA_PM800) ||
+ (pVia->Chipset == VIA_VM800))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Panel on K8M800, PM800 or VM800 is"
+ " currently not supported.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Using VBE to set modes to"
+ " work around this.\n");
+ pVia->useVBEModes = TRUE;
+ }
+
+ pVia->pVbe = NULL;
+ if (pVia->useVBEModes) {
+ /* VBE doesn't properly initialise int10 itself */
+ if (xf86LoadSubModule(pScrn, "int10") && xf86LoadSubModule(pScrn, "vbe")) {
+ xf86LoaderReqSymLists(vbeSymbols, NULL);
+ pVia->pVbe = VBEExtendedInit(NULL, pVia->EntityIndex,
+ SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
+ }
+
+ if (!pVia->pVbe)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VBE initialisation failed."
+ " Using builtin code to set modes.\n");
+ }
+
+ if (pVia->pVbe) {
+
+ if (!ViaVbeModePreInit( pScrn )) {
+ VIAFreeRec(pScrn);
+ return FALSE;
+ }
+
+ } else {
+ /* Add own Modes */
+ ViaModesAttach(pScrn, pScrn->monitor);
+
+ /*
+ * Setup the ClockRanges, which describe what clock ranges are available,
+ * and what sort of modes they can be used for.
+ */
+
+ clockRanges = xnfalloc(sizeof(ClockRange));
+ clockRanges->next = NULL;
+ clockRanges->minClock = 20000;
+ clockRanges->maxClock = 230000;
+
+ clockRanges->clockIndex = -1;
+ clockRanges->interlaceAllowed = TRUE;
+ clockRanges->doubleScanAllowed = FALSE;
+
+ /*
+ * xf86ValidateModes will check that the mode HTotal and VTotal values
+ * don't exceed the chipset's limit if pScrn->maxHValue and
+ * pScrn->maxVValue are set. Since our VIAValidMode() already takes
+ * care of this, we don't worry about setting them here.
+ *
+ * CLE266A:
+ * Max Line Pitch: 4080, (FB corruption when higher, driver problem?)
+ * Max Height: 4096 (and beyond)
+ *
+ * CLE266A: primary AdjustFrame only is able to use 24bits, so we are
+ * limited to 12x11bits; 4080x2048 (~2:1), 3344x2508 (4:3) or 2896x2896
+ * (1:1).
+ * Test CLE266Cx, KM400, KM400A, K8M800, PM800, CN400 please.
+ *
+ * We should be able to limit the memory available for a mode to 32MB,
+ * yet xf86ValidateModes (or miScanLineWidth) fails to catch this properly
+ * (apertureSize).
+ */
+
+ /* Select valid modes from those available */
+ i = xf86ValidateModes(pScrn,
+ pScrn->monitor->Modes, /* availModes */
+ pScrn->display->modes, /* modeNames */
+ clockRanges, /* list of clock ranges */
+ NULL, /* list of line pitches */
+ 256, /* mini line pitch */
+ 3344, /* max line pitch */
+ 32*8, /* pitch inc (bits) */
+ 128, /* min height */
+ 2508, /* max height */
+ pScrn->display->virtualX, /* virtual width */
+ pScrn->display->virtualY, /* virtual height */
+ pVia->videoRambytes, /* apertureSize */
+ LOOKUP_BEST_REFRESH); /* lookup mode flags */
+
+
+ if (i == -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86ValidateModes failure\n");
+ VIAFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86PruneDriverModes(pScrn);
+
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ VIAFreeRec(pScrn);
+ return FALSE;
+ }
+
+ }
+
+ /* Set up screen parameters. */
+ pVia->Bpp = pScrn->bitsPerPixel >> 3;
+ pVia->Bpl = pScrn->displayWidth * pVia->Bpp;
+
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+ pScrn->currentMode = pScrn->modes;
+ xf86PrintModes(pScrn);
+ xf86SetDpi(pScrn, 0, 0);
+
+#ifdef USE_FB
+ if (xf86LoadSubModule(pScrn, "fb") == NULL) {
+ VIAFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(fbSymbols, NULL);
+
+#else
+ /* load bpp-specific modules */
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ mod = "cfb";
+ reqSym = "cfbScreenInit";
+ break;
+ case 16:
+ mod = "cfb16";
+ reqSym = "cfb16ScreenInit";
+ break;
+ case 32:
+ mod = "cfb32";
+ reqSym = "cfb32ScreenInit";
+ break;
+ }
+
+ if (mod && xf86LoadSubModule(pScrn, mod) == NULL) {
+ VIAFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymbols(reqSym, NULL);
+#endif
+
+ if (!pVia->NoAccel) {
+#ifdef VIA_HAVE_EXA
+ if(pVia->useEXA) {
+#if (EXA_VERSION_MAJOR >= 2)
+ XF86ModReqInfo req;
+ int errmaj, errmin;
+
+ memset(&req, 0, sizeof(req));
+ req.majorversion = 2;
+ req.minorversion = 0;
+ if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req,
+ &errmaj, &errmin)) {
+ LoaderErrorMsg(NULL, "exa", errmaj, errmin);
+ 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;
+ }
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+ }
+
+ if (pVia->hwcursor) {
+ if (!xf86LoadSubModule(pScrn, "ramdac")) {
+ VIAFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+ }
+
+ if (pVia->shadowFB) {
+ if (!xf86LoadSubModule(pScrn, "shadowfb")) {
+ VIAFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(shadowSymbols, NULL);
+ }
+
+ VIAUnmapMem(pScrn);
+
+ return TRUE;
+}
+
+
+static Bool VIAEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ VIAPtr pVia = VIAPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ Bool ret;
+
+ /* FIXME: Rebind AGP memory here */
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "VIAEnterVT\n"));
+
+ if (pVia->pVbe) {
+ if (pVia->vbeSR)
+ ViaVbeSaveRestore(pScrn, MODE_SAVE);
+ else
+ VIASave(pScrn);
+ ret = ViaVbeSetMode(pScrn, pScrn->currentMode);
+ } else {
+ VIASave(pScrn);
+ ret = VIAWriteMode(pScrn, pScrn->currentMode);
+ }
+ vgaHWUnlock(hwp);
+
+ VIASaveScreen(pScrn->pScreen, SCREEN_SAVER_ON);
+
+
+ /* Patch for APM suspend resume, HWCursor has garbage */
+ if (pVia->hwcursor)
+ ViaCursorRestore(pScrn);
+
+ /* restore video status */
+ if (!pVia->IsSecondary)
+ viaRestoreVideo(pScrn);
+
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled) {
+ kickVblank(pScrn);
+ VIADRIRingBufferInit(pScrn);
+ viaDRIOffscreenRestore(pScrn);
+ }
+#endif
+
+ if (pVia->NoAccel) {
+ memset(pVia->FBBase, 0x00, pVia->Bpl * pScrn->virtualY);
+ } else {
+ viaAccelFillRect(pScrn, 0, 0, pScrn->displayWidth, pScrn->virtualY,
+ 0x00000000);
+ viaAccelSyncMarker(pScrn);
+ }
+
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled) {
+ DRIUnlock(screenInfo.screens[scrnIndex]);
+ }
+#endif
+
+ return ret;
+}
+
+
+static void VIALeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "VIALeaveVT\n"));
+
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled) {
+ volatile drm_via_sarea_t *saPriv = (drm_via_sarea_t *)
+ DRIGetSAREAPrivate(pScrn->pScreen);
+
+ DRILock(screenInfo.screens[scrnIndex], 0);
+ saPriv->ctxOwner = ~0;
+ }
+#endif
+
+ viaAccelSync(pScrn);
+
+ /*
+ * A soft reset helps fix 3D hang on VT switch.
+ */
+
+ hwp->writeSeq(hwp, 0x1A, pVia->SavedReg.SR1A | 0x40);
+
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled) {
+ VIADRIRingBufferCleanup(pScrn);
+ viaDRIOffscreenSave(pScrn);
+ }
+#endif
+
+ if (pVia->VQEnable)
+ viaDisableVQ(pScrn);
+
+ /* Save video status and turn off all video activities */
+
+ if (!pVia->IsSecondary)
+ viaSaveVideo(pScrn);
+
+ if (pVia->hwcursor)
+ ViaCursorStore(pScrn);
+
+ if (pVia->pVbe && pVia->vbeSR)
+ ViaVbeSaveRestore(pScrn, MODE_RESTORE);
+ else
+ VIARestore(pScrn);
+
+ vgaHWLock(hwp);
+
+}
+
+
+static void
+VIASave(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ VIAPtr pVia = VIAPTR(pScrn);
+ VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+ VIARegPtr Regs = &pVia->SavedReg;
+ int i;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIASave\n"));
+
+ if(pVia->IsSecondary)
+ {
+ DevUnion* pPriv;
+ VIAEntPtr pVIAEnt;
+ VIAPtr pVia1;
+ vgaHWPtr hwp1;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Secondary\n"));
+
+ pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+ gVIAEntityIndex);
+ pVIAEnt = pPriv->ptr;
+ hwp1 = VGAHWPTR(pVIAEnt->pPrimaryScrn);
+ pVia1 = VIAPTR(pVIAEnt->pPrimaryScrn);
+ hwp->SavedReg = hwp1->SavedReg;
+ pVia->SavedReg = pVia1->SavedReg;
+ }
+ else {
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Primary\n"));
+
+ vgaHWProtect(pScrn, TRUE);
+
+ if (xf86IsPrimaryPci(pVia->PciInfo))
+ vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_ALL);
+ else
+ vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE);
+
+ /* Unlock extended regs */
+ hwp->writeSeq(hwp, 0x10, 0x01);
+
+ Regs->SR14 = hwp->readSeq(hwp, 0x14);
+ Regs->SR15 = hwp->readSeq(hwp, 0x15);
+ Regs->SR16 = hwp->readSeq(hwp, 0x16);
+ Regs->SR17 = hwp->readSeq(hwp, 0x17);
+ Regs->SR18 = hwp->readSeq(hwp, 0x18);
+ Regs->SR19 = hwp->readSeq(hwp, 0x19);
+ Regs->SR1A = hwp->readSeq(hwp, 0x1A);
+ Regs->SR1B = hwp->readSeq(hwp, 0x1B);
+ Regs->SR1C = hwp->readSeq(hwp, 0x1C);
+ Regs->SR1D = hwp->readSeq(hwp, 0x1D);
+ Regs->SR1E = hwp->readSeq(hwp, 0x1E);
+ Regs->SR1F = hwp->readSeq(hwp, 0x1F);
+
+ Regs->SR22 = hwp->readSeq(hwp, 0x22);
+ Regs->SR23 = hwp->readSeq(hwp, 0x23);
+ Regs->SR24 = hwp->readSeq(hwp, 0x24);
+ Regs->SR25 = hwp->readSeq(hwp, 0x25);
+ Regs->SR26 = hwp->readSeq(hwp, 0x26);
+ Regs->SR27 = hwp->readSeq(hwp, 0x27);
+ Regs->SR28 = hwp->readSeq(hwp, 0x28);
+ Regs->SR29 = hwp->readSeq(hwp, 0x29);
+ Regs->SR2A = hwp->readSeq(hwp, 0x2A);
+ Regs->SR2B = hwp->readSeq(hwp, 0x2B);
+
+ Regs->SR2E = hwp->readSeq(hwp, 0x2E);
+
+ Regs->SR44 = hwp->readSeq(hwp, 0x44);
+ Regs->SR45 = hwp->readSeq(hwp, 0x45);
+ Regs->SR46 = hwp->readSeq(hwp, 0x46);
+ Regs->SR47 = hwp->readSeq(hwp, 0x47);
+
+ Regs->CR13 = hwp->readCrtc(hwp, 0x13);
+
+ Regs->CR32 = hwp->readCrtc(hwp, 0x32);
+ Regs->CR33 = hwp->readCrtc(hwp, 0x33);
+ Regs->CR34 = hwp->readCrtc(hwp, 0x34);
+ Regs->CR35 = hwp->readCrtc(hwp, 0x35);
+ Regs->CR36 = hwp->readCrtc(hwp, 0x36);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TVSave...\n"));
+ if (pBIOSInfo->TVI2CDev)
+ ViaTVSave(pScrn);
+
+ /* Save LCD control regs */
+ for (i = 0; i < 68; i++)
+ Regs->CRTCRegs[i] = hwp->readCrtc(hwp, i + 0x50);
+
+ vgaHWProtect(pScrn, FALSE);
+ }
+}
+
+static void
+VIARestore(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ VIAPtr pVia = VIAPTR(pScrn);
+ VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+ VIARegPtr Regs = &pVia->SavedReg;
+ int i;
+ CARD8 tmp;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIARestore\n"));
+
+ /* Secondary? */
+
+ vgaHWProtect(pScrn, TRUE);
+
+ /* Unlock extended regs */
+ hwp->writeSeq(hwp, 0x10, 0x01);
+
+ hwp->writeCrtc(hwp, 0x6A, 0x00);
+ hwp->writeCrtc(hwp, 0x6B, 0x00);
+ hwp->writeCrtc(hwp, 0x6C, 0x00);
+
+ if (pBIOSInfo->TVI2CDev)
+ ViaTVRestore(pScrn);
+
+ /* Restore the standard vga regs */
+ if (xf86IsPrimaryPci(pVia->PciInfo))
+ vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_ALL);
+ else
+ vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE);
+
+ /* Restore extended regs */
+ hwp->writeSeq(hwp, 0x14, Regs->SR14);
+ hwp->writeSeq(hwp, 0x15, Regs->SR15);
+ hwp->writeSeq(hwp, 0x16, Regs->SR16);
+ hwp->writeSeq(hwp, 0x17, Regs->SR17);
+ hwp->writeSeq(hwp, 0x18, Regs->SR18);
+ hwp->writeSeq(hwp, 0x19, Regs->SR19);
+ hwp->writeSeq(hwp, 0x1A, Regs->SR1A);
+ hwp->writeSeq(hwp, 0x1B, Regs->SR1B);
+ hwp->writeSeq(hwp, 0x1C, Regs->SR1C);
+ hwp->writeSeq(hwp, 0x1D, Regs->SR1D);
+ hwp->writeSeq(hwp, 0x1E, Regs->SR1E);
+ hwp->writeSeq(hwp, 0x1F, Regs->SR1F);
+
+ hwp->writeSeq(hwp, 0x22, Regs->SR22);
+ hwp->writeSeq(hwp, 0x23, Regs->SR23);
+ hwp->writeSeq(hwp, 0x24, Regs->SR24);
+ hwp->writeSeq(hwp, 0x25, Regs->SR25);
+ hwp->writeSeq(hwp, 0x26, Regs->SR26);
+ hwp->writeSeq(hwp, 0x27, Regs->SR27);
+ hwp->writeSeq(hwp, 0x28, Regs->SR28);
+ hwp->writeSeq(hwp, 0x29, Regs->SR29);
+ hwp->writeSeq(hwp, 0x2A, Regs->SR2A);
+ hwp->writeSeq(hwp, 0x2B, Regs->SR2B);
+
+ hwp->writeSeq(hwp, 0x2E, Regs->SR2E);
+
+ hwp->writeSeq(hwp, 0x44, Regs->SR44);
+ hwp->writeSeq(hwp, 0x45, Regs->SR45);
+ hwp->writeSeq(hwp, 0x46, Regs->SR46);
+ hwp->writeSeq(hwp, 0x47, Regs->SR47);
+
+ /* Reset dotclocks */
+ ViaSeqMask(hwp, 0x40, 0x06, 0x06);
+ ViaSeqMask(hwp, 0x40, 0x00, 0x06);
+
+ hwp->writeCrtc(hwp, 0x13, Regs->CR13);
+ hwp->writeCrtc(hwp, 0x32, Regs->CR32);
+ hwp->writeCrtc(hwp, 0x33, Regs->CR33);
+ hwp->writeCrtc(hwp, 0x34, Regs->CR34);
+ hwp->writeCrtc(hwp, 0x35, Regs->CR35);
+ hwp->writeCrtc(hwp, 0x36, Regs->CR36);
+
+ /* Restore LCD control regs */
+ for (i = 0; i < 68; i++)
+ hwp->writeCrtc(hwp, i + 0x50, Regs->CRTCRegs[i]);
+
+ if (pBIOSInfo->PanelActive)
+ ViaLCDPower(pScrn, TRUE);
+
+ ViaDisablePrimaryFIFO(pScrn);
+
+ /* Reset clock */
+ tmp = hwp->readMiscOut(hwp);
+ hwp->writeMiscOut(hwp, tmp);
+
+ vgaHWProtect(pScrn, FALSE);
+}
+
+static Bool
+VIAMapMMIO(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAMapMMIO\n"));
+
+ pVia->FrameBufferBase = pVia->PciInfo->memBase[0];
+ pVia->MmioBase = pVia->PciInfo->memBase[1];
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "mapping MMIO @ 0x%lx with size 0x%x\n",
+ pVia->MmioBase, VIA_MMIO_REGSIZE);
+
+ pVia->MapBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag,
+ pVia->MmioBase, VIA_MMIO_REGSIZE);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "mapping BitBlt MMIO @ 0x%lx with size 0x%x\n",
+ pVia->MmioBase + VIA_MMIO_BLTBASE, VIA_MMIO_BLTSIZE);
+
+ pVia->BltBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag,
+ pVia->MmioBase + VIA_MMIO_BLTBASE,
+ VIA_MMIO_BLTSIZE);
+
+ if (!pVia->MapBase || !pVia->BltBase) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Internal error: cound not map registers\n");
+ return FALSE;
+ }
+
+ /* Memory mapped IO for Video Engine */
+ pVia->VidMapBase = pVia->MapBase + 0x200;
+ /* Memory mapped IO for Mpeg Engine */
+ pVia->MpegMapBase = pVia->MapBase + 0xc00;
+
+ /* Set up MMIO vgaHW */
+ {
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CARD8 val;
+
+ vgaHWSetMmioFuncs(hwp, pVia->MapBase, 0x8000);
+
+ val = hwp->readEnable(hwp);
+ hwp->writeEnable(hwp, val | 0x01);
+
+ val = hwp->readMiscOut(hwp);
+ hwp->writeMiscOut(hwp, val | 0x01);
+
+ /* Unlock Extended IO Space */
+ hwp->writeSeq(hwp, 0x10, 0x01);
+
+ /* Enable MMIO */
+ if (pVia->IsSecondary)
+ ViaSeqMask(hwp, 0x1A, 0x38, 0x38);
+ else
+ ViaSeqMask(hwp, 0x1A, 0x68, 0x68);
+
+ vgaHWGetIOBase(hwp);
+ }
+
+ return TRUE;
+}
+
+
+static Bool VIAMapFB(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAMapFB\n"));
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "mapping framebuffer @ 0x%lx with size 0x%lx\n",
+ pVia->FrameBufferBase, pVia->videoRambytes);
+
+ if (pVia->videoRambytes) {
+
+ /*
+ * FIXME: This is a hack to get rid of offending wrongly sized
+ * MTRR regions set up by the VIA BIOS. Should be taken care of
+ * in the OS support layer.
+ */
+
+ unsigned char *tmp;
+ tmp = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ pVia->PciTag, pVia->FrameBufferBase,
+ pVia->videoRambytes);
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)tmp,
+ pVia->videoRambytes);
+
+ /*
+ * And, as if this wasn't enough, 2.6 series kernels doesn't
+ * remove MTRR regions on the first attempt. Try again.
+ */
+
+ tmp = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ pVia->PciTag, pVia->FrameBufferBase,
+ pVia->videoRambytes);
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)tmp,
+ pVia->videoRambytes);
+
+ /*
+ * End of hack.
+ */
+
+ pVia->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pVia->PciTag, pVia->FrameBufferBase,
+ pVia->videoRambytes);
+
+ if (!pVia->FBBase) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Internal error: could not map framebuffer\n");
+ return FALSE;
+ }
+
+ pVia->FBFreeStart = (pScrn->displayWidth * pScrn->bitsPerPixel >> 3) *
+ pScrn->virtualY;
+ pVia->FBFreeEnd = pVia->videoRambytes;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Frame buffer start: %p, free start: 0x%x end: 0x%x\n",
+ pVia->FBBase, pVia->FBFreeStart, pVia->FBFreeEnd);
+ }
+
+ pScrn->memPhysBase = pVia->PciInfo->memBase[0];
+ pScrn->fbOffset = 0;
+ if(pVia->IsSecondary) pScrn->fbOffset = pScrn->videoRam << 10;
+
+ return TRUE;
+}
+
+
+static void
+VIAUnmapMem(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAUnmapMem\n"));
+
+ /* Disable MMIO */
+ ViaSeqMask(VGAHWPTR(pScrn), 0x1A, 0x00, 0x60);
+
+ if (pVia->MapBase)
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pVia->MapBase, VIA_MMIO_REGSIZE);
+
+ if (pVia->BltBase)
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pVia->BltBase, VIA_MMIO_BLTSIZE);
+
+ if (pVia->FBBase)
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pVia->FBBase, pVia->videoRambytes);
+}
+
+static void
+VIALoadRgbLut(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, VisualPtr pVisual)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ int i, j, index;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIALoadRgbLut\n"));
+
+ hwp->enablePalette(hwp);
+ hwp->writeDacMask(hwp, 0xFF);
+
+ /* We need the same palette contents for both 16 and 24 bits, but X doesn't
+ * play: X's colormap handling is hopelessly intertwined with almost every
+ * X subsystem. So we just space out RGB values over the 256*3. */
+
+ switch (pScrn->bitsPerPixel) {
+ case 16:
+ for (i = 0; i < numColors; i++) {
+ index = indices[i];
+ hwp->writeDacWriteAddr(hwp, index * 4);
+ for (j = 0; j < 4; j++) {
+ hwp->writeDacData(hwp, colors[index/2].red);
+ hwp->writeDacData(hwp, colors[index].green);
+ hwp->writeDacData(hwp, colors[index/2].blue);
+ }
+ }
+ break;
+ case 8:
+ case 24:
+ case 32:
+ 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);
+ }
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unsupported bitdepth: %d\n", pScrn->bitsPerPixel);
+ break;
+ }
+ hwp->disablePalette(hwp);
+}
+
+static void
+VIALoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
+ LOCO *colors, VisualPtr pVisual)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ VIAPtr pVia = VIAPTR(pScrn);
+ 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;
+ default:
+ ViaCrtcMask(hwp, 0x33, 0x80, 0x80);
+ break;
+ }
+
+ ViaSeqMask(hwp, 0x1A, 0x00, 0x01);
+ VIALoadRgbLut(pScrn, numColors, indices, colors, pVisual);
+
+ /* 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:
+ break;
+ default:
+ ViaSeqMask(hwp, 0x6A, 0x20, 0x20);
+ break;
+ }
+ VIALoadRgbLut(pScrn, numColors, indices, colors, pVisual);
+ }
+
+ return;
+ }
+
+ SR1A = hwp->readSeq(hwp, 0x1A);
+ SR1B = hwp->readSeq(hwp, 0x1B);
+ CR67 = hwp->readCrtc(hwp, 0x67);
+ CR6A = hwp->readCrtc(hwp, 0x6A);
+
+ if (pVia->IsSecondary) {
+ ViaSeqMask(hwp, 0x1A, 0x01, 0x01);
+ ViaSeqMask(hwp, 0x1B, 0x80, 0x80);
+ ViaCrtcMask(hwp, 0x67, 0x00, 0xC0);
+ ViaCrtcMask(hwp, 0x6A, 0xC0, 0xC0);
+ }
+
+ 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 (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 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);
+ }
+ }
+}
+
+/*
+ *
+ */
+static Bool
+VIAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ pScrn->pScreen = pScreen;
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAScreenInit\n"));
+
+ if (!VIAMapFB(pScrn))
+ return FALSE;
+
+ if (!VIAMapMMIO(pScrn))
+ return FALSE;
+
+ if (pVia->pVbe && pVia->vbeSR)
+ ViaVbeSaveRestore(pScrn, MODE_SAVE);
+ else
+ VIASave(pScrn);
+
+ vgaHWUnlock(hwp);
+
+ pVia->FirstInit = TRUE;
+ if (pVia->pVbe) {
+ vgaHWBlankScreen(pScrn, FALSE);
+ if (!ViaVbeSetMode(pScrn, pScrn->currentMode)) {
+ vgaHWBlankScreen(pScrn, TRUE);
+ return FALSE;
+ }
+ } else {
+ vgaHWBlankScreen(pScrn, FALSE);
+ if (!VIAWriteMode(pScrn, pScrn->currentMode)) {
+ vgaHWBlankScreen(pScrn, TRUE);
+ return FALSE;
+ }
+ }
+ pVia->FirstInit = FALSE;
+
+ /* Darken the screen for aesthetic reasons and set the viewport */
+ VIASaveScreen(pScreen, SCREEN_SAVER_ON);
+ pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Blanked\n"));
+
+ miClearVisualTypes();
+
+ if (pScrn->bitsPerPixel > 8 && !pVia->IsSecondary) {
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ if (!miSetPixmapDepths())
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ if (!miSetPixmapDepths())
+ return FALSE;
+ }
+
+#ifdef XF86DRI
+ pVia->directRenderingEnabled = VIADRIScreenInit(pScreen);
+#endif
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Visuals set up\n"));
+
+ if (!VIAInternalScreenInit(scrnIndex, pScreen))
+ return FALSE;
+
+ xf86SetBlackWhitePixels(pScreen);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- B & W\n"));
+
+ if (pScrn->bitsPerPixel > 8) {
+ VisualPtr visual;
+
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+#ifdef USE_FB
+ /* must be after RGB ordering fixed */
+ fbPictureInit(pScreen, 0, 0);
+#endif
+
+ if (!pVia->NoAccel) {
+ viaInitAccel(pScreen);
+ }
+
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+ /*xf86SetSilkenMouse(pScreen);*/
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Backing store set up\n"));
+
+ if(!pVia->shadowFB) /* hardware cursor needs to wrap this layer */
+ VIADGAInit(pScreen);
+
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- SW cursor set up\n"));
+
+ if (pVia->hwcursor) {
+ if (!VIAHWCursorInit(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Hardware cursor initialization failed\n");
+ }
+ }
+
+ if (pVia->shadowFB)
+ ViaShadowFBInit(pScrn, pScreen);
+
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Def Color map set up\n"));
+
+ if (!xf86HandleColormaps(pScreen, 256, 8, VIALoadPalette, NULL,
+ CMAP_RELOAD_ON_MODE_SWITCH
+ | CMAP_PALETTED_TRUECOLOR))
+ return FALSE;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Palette loaded\n"));
+
+ pVia->CloseScreen = pScreen->CloseScreen;
+ pScreen->SaveScreen = VIASaveScreen;
+ pScreen->CloseScreen = VIACloseScreen;
+
+ xf86DPMSInit(pScreen, VIADPMS, 0);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- DPMS set up\n"));
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Color maps etc. set up\n"));
+ pVia->agpDMA = FALSE;
+
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled)
+ pVia->directRenderingEnabled = VIADRIFinishScreenInit(pScreen);
+
+ if (pVia->directRenderingEnabled) {
+ VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering enabled\n");
+ pVia->agpDMA = pVia->dma2d && pVIADRI->ringBufActive;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering disabled\n");
+ }
+#endif
+ if (!pVia->NoAccel)
+ viaFinishInitAccel(pScreen);
+
+ if (pVia->NoAccel) {
+ memset(pVia->FBBase, 0x00, pVia->videoRambytes);
+ } else {
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled)
+ DRILock(screenInfo.screens[scrnIndex], 0);
+#endif
+ viaAccelFillRect(pScrn, pScrn->frameX0, pScrn->frameY0,
+ pScrn->displayWidth, pScrn->virtualY,
+ 0x00000000);
+ viaAccelSyncMarker(pScrn);
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled)
+ DRIUnlock(screenInfo.screens[scrnIndex]);
+#endif
+ }
+ vgaHWBlankScreen(pScrn, TRUE);
+
+ if (pVia->NoAccel) {
+
+ /*
+ * This is only for Xv in Noaccel path, and since Xv is in some
+ * sense accelerated, it might be a better idea to disable it
+ * altogether.
+ */
+
+ BoxRec AvailFBArea;
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = pScrn->virtualY + 1;
+ pVia->FBFreeStart=(AvailFBArea.y2 + 1)*pVia->Bpl;
+ xf86InitFBManager(pScreen, &AvailFBArea);
+ VIAInitLinear(pScreen);
+ pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart - pVia->Bpl);
+ }
+
+ viaInitVideo(pScreen);
+
+ if (serverGeneration == 1)
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+
+#ifdef HAVE_DEBUG
+ if (pVia->PrintVGARegs) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAScreenInit: Printing VGA registers.\n");
+ ViaVgahwPrint(VGAHWPTR(pScrn));
+ }
+
+ if (pVia->PrintTVRegs) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAScreenInit: Printing TV registers.\n");
+ ViaTVPrintRegs(pScrn);
+ }
+#endif
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Done\n"));
+ return TRUE;
+}
+
+
+static int VIAInternalScreenInit(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ int width, height, displayWidth;
+ unsigned char *FBStart;
+
+ xf86DrvMsg(scrnIndex, X_INFO, "VIAInternalScreenInit\n");
+
+ displayWidth = pScrn->displayWidth;
+
+ if (pVia->rotate) {
+ height = pScrn->virtualX;
+ width = pScrn->virtualY;
+ } else {
+ width = pScrn->virtualX;
+ height = pScrn->virtualY;
+ }
+
+ if (pVia->shadowFB) {
+ pVia->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
+ pVia->ShadowPtr = xalloc(pVia->ShadowPitch * height);
+ displayWidth = pVia->ShadowPitch / (pScrn->bitsPerPixel >> 3);
+ FBStart = pVia->ShadowPtr;
+ }
+ else {
+ pVia->ShadowPtr = NULL;
+ FBStart = pVia->FBBase;
+ }
+
+#ifdef USE_FB
+ return fbScreenInit(pScreen, FBStart, width, height,
+ pScrn->xDpi, pScrn->yDpi, displayWidth,
+ pScrn->bitsPerPixel);
+#else
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ return cfbScreenInit(pScreen, FBStart, width, height, pScrn->xDpi,
+ pScrn->yDpi, displayWidth);
+ case 16:
+ return cfb16ScreenInit(pScreen, FBStart, width, height, pScrn->xDpi,
+ pScrn->yDpi, displayWidth);
+ case 32:
+ return cfb32ScreenInit(pScreen, FBStart, width, height, pScrn->xDpi,
+ pScrn->yDpi, displayWidth);
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR, "Internal error: invalid bpp (%d) in "
+ "VIAInternalScreenInit\n", pScrn->bitsPerPixel);
+ return FALSE;
+ }
+#endif
+}
+
+static Bool
+VIAWriteMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAWriteMode\n"));
+
+ pVia->OverlaySupported = FALSE;
+
+ if (!vgaHWInit(pScrn, mode))
+ return FALSE;
+
+ pScrn->vtSema = TRUE;
+
+ if (!pVia->IsSecondary)
+ ViaModePrimary(pScrn, mode);
+ else
+ ViaModeSecondary(pScrn, mode);
+
+ /* Enable the graphics engine. */
+ if (!pVia->NoAccel) {
+#if defined(XF86DRI) || defined(VIA_HAVE_EXA)
+ VIAInitialize3DEngine(pScrn);
+#endif
+ viaInitialize2DEngine(pScrn);
+ }
+
+ VIAAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ return TRUE;
+}
+
+
+static Bool VIACloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "VIACloseScreen\n"));
+ /* Is the display currently visible ? */
+ if(pScrn->vtSema)
+ {
+
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled)
+ DRILock(screenInfo.screens[scrnIndex], 0);
+#endif
+ /* Wait Hardware Engine idle to exit graphical mode */
+ viaAccelSync(pScrn);
+
+
+ /* A soft reset Fixes 3D Hang after X restart */
+
+ hwp->writeSeq(hwp, 0x1A, pVia->SavedReg.SR1A | 0x40);
+
+ if (!pVia->IsSecondary) {
+ /* Turn off all video activities */
+ viaExitVideo(pScrn);
+
+ VIAHideCursor(pScrn);
+ }
+
+ if (pVia->VQEnable)
+ viaDisableVQ(pScrn);
+ }
+
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled)
+ VIADRICloseScreen(pScreen);
+#endif
+
+ viaExitAccel(pScreen);
+ if (pVia->CursorInfoRec) {
+ xf86DestroyCursorInfoRec(pVia->CursorInfoRec);
+ pVia->CursorInfoRec = NULL;
+ }
+ if (pVia->ShadowPtr) {
+ xfree(pVia->ShadowPtr);
+ pVia->ShadowPtr = NULL;
+ }
+ if (pVia->DGAModes) {
+ xfree(pVia->DGAModes);
+ pVia->DGAModes = NULL;
+ }
+
+ if (pScrn->vtSema) {
+ if (pVia->pVbe && pVia->vbeSR)
+ ViaVbeSaveRestore(pScrn, MODE_RESTORE);
+ else
+ VIARestore(pScrn);
+
+ vgaHWLock(hwp);
+ VIAUnmapMem(pScrn);
+ }
+ pScrn->vtSema = FALSE;
+ pScreen->CloseScreen = pVia->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+/*
+ * This only gets called when a screen is being deleted. It does not
+ * get called routinely at the end of a server generation.
+ */
+static void VIAFreeScreen(int scrnIndex, int flags)
+{
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "VIAFreeScreen\n"));
+
+ VIAFreeRec(xf86Screens[scrnIndex]);
+
+ if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+}
+
+static Bool VIASaveScreen(ScreenPtr pScreen, int mode)
+{
+ return vgaHWSaveScreen(pScreen, mode);
+}
+
+static void
+VIAAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ VIAPtr pVia = VIAPTR(pScrn);
+ CARD32 Base;
+
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "VIAAdjustFrame\n"));
+
+ if (pVia->pVbe) {
+ ViaVbeAdjustFrame(scrnIndex, x, y, flags);
+ VIAVidAdjustFrame(pScrn, x, y);
+ return;
+ }
+
+ 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
+ }
+
+ VIAVidAdjustFrame(pScrn, x, y);
+}
+
+
+static Bool
+VIASwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ VIAPtr pVia = VIAPTR(pScrn);
+ Bool ret;
+
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "VIASwitchMode\n"));
+
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled)
+ DRILock(screenInfo.screens[scrnIndex], 0);
+#endif
+
+ viaAccelSync(pScrn);
+
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled)
+ VIADRIRingBufferCleanup(pScrn);
+#endif
+
+ if (pVia->VQEnable)
+ viaDisableVQ(pScrn);
+
+ if (pVia->pVbe)
+ ret = ViaVbeSetMode(pScrn, mode);
+ else
+ ret = VIAWriteMode(pScrn, mode);
+
+#ifdef XF86DRI
+ if (pVia->directRenderingEnabled) {
+ kickVblank(pScrn);
+ VIADRIRingBufferInit(pScrn);
+ DRIUnlock(screenInfo.screens[scrnIndex]);
+ }
+#endif
+ return ret;
+
+}
+
+
+static void VIADPMS(ScrnInfoPtr pScrn, int mode, int flags)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ VIAPtr pVia = VIAPTR(pScrn);
+ VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+ CARD8 val;
+
+ if (pVia->pVbe) {
+ ViaVbeDPMS(pScrn, mode, flags);
+ return;
+ }
+
+ /* Clear DPMS setting */
+ val = hwp->readCrtc(hwp, 0x36);
+ val &= 0xCF;
+
+ /* Turn Off CRT, if user doesn't want crt on */
+ if (!pVia->IsSecondary && !pBIOSInfo->CrtActive)
+ val |= 0x30;
+
+ switch (mode) {
+ case DPMSModeOn:
+ if (pBIOSInfo->PanelActive)
+ ViaLCDPower(pScrn, TRUE);
+
+ if (pBIOSInfo->TVActive)
+ ViaTVPower(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, FALSE);
+
+ val |= 0x30;
+ hwp->writeCrtc(hwp, 0x36, val);
+ 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)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ int i;
+
+ VIASETREG(VIA_REG_TRANSET, 0x00010000);
+
+ for (i = 0; i <= 0x7D; i++)
+ {
+ VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24);
+ }
+
+ VIASETREG(VIA_REG_TRANSET, 0x00020000);
+
+ for (i = 0; i <= 0x94; i++)
+ {
+ VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24);
+ }
+
+ VIASETREG(VIA_REG_TRANSPACE, 0x82400000);
+
+ VIASETREG(VIA_REG_TRANSET, 0x01020000);
+
+
+ for (i = 0; i <= 0x94; i++)
+ {
+ VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24);
+ }
+
+ VIASETREG(VIA_REG_TRANSPACE, 0x82400000);
+ VIASETREG(VIA_REG_TRANSET, 0xfe020000);
+
+ for (i = 0; i <= 0x03; i++)
+ {
+ VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24);
+ }
+
+ VIASETREG(VIA_REG_TRANSET, 0x00030000);
+
+ for (i = 0; i <= 0xff; i++)
+ {
+ VIASETREG(VIA_REG_TRANSPACE, 0);
+ }
+ VIASETREG(VIA_REG_TRANSET, 0x00100000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x00333004);
+ VIASETREG(VIA_REG_TRANSPACE, 0x10000002);
+ VIASETREG(VIA_REG_TRANSPACE, 0x60000000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x61000000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x62000000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x63000000);
+ VIASETREG(VIA_REG_TRANSPACE, 0x64000000);
+
+ VIASETREG(VIA_REG_TRANSET, 0x00fe0000);
+
+ if (pVia->ChipRev >= 3 )
+ VIASETREG(VIA_REG_TRANSPACE,0x40008c0f);
+ else
+ VIASETREG(VIA_REG_TRANSPACE,0x4000800f);
+
+ VIASETREG(VIA_REG_TRANSPACE,0x44000000);
+ VIASETREG(VIA_REG_TRANSPACE,0x45080C04);
+ VIASETREG(VIA_REG_TRANSPACE,0x46800408);
+ VIASETREG(VIA_REG_TRANSPACE,0x50000000);
+ VIASETREG(VIA_REG_TRANSPACE,0x51000000);
+ VIASETREG(VIA_REG_TRANSPACE,0x52000000);
+ VIASETREG(VIA_REG_TRANSPACE,0x53000000);
+
+
+ VIASETREG(VIA_REG_TRANSET,0x00fe0000);
+ VIASETREG(VIA_REG_TRANSPACE,0x08000001);
+ VIASETREG(VIA_REG_TRANSPACE,0x0A000183);
+ VIASETREG(VIA_REG_TRANSPACE,0x0B00019F);
+ VIASETREG(VIA_REG_TRANSPACE,0x0C00018B);
+ VIASETREG(VIA_REG_TRANSPACE,0x0D00019B);
+ VIASETREG(VIA_REG_TRANSPACE,0x0E000000);
+ VIASETREG(VIA_REG_TRANSPACE,0x0F000000);
+ VIASETREG(VIA_REG_TRANSPACE,0x10000000);
+ VIASETREG(VIA_REG_TRANSPACE,0x11000000);
+ VIASETREG(VIA_REG_TRANSPACE,0x20000000);
+}
+#endif
diff --git a/src/via_driver.h b/src/via_driver.h
new file mode 100644
index 000000000000..81c098c89d14
--- /dev/null
+++ b/src/via_driver.h
@@ -0,0 +1,472 @@
+/*
+ * 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.
+ */
+
+#ifndef _VIA_DRIVER_H_
+#define _VIA_DRIVER_H_ 1
+
+#define HAVE_DEBUG
+
+#ifdef HAVE_DEBUG
+#define DEBUG(x) x
+#else
+#define DEBUG(x)
+#endif
+
+#include "vgaHW.h"
+#include "xf86.h"
+#include "xf86Resources.h"
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+#include "xf86_OSproc.h"
+#include "compiler.h"
+#include "xf86Cursor.h"
+#include "mipointer.h"
+#include "micmap.h"
+#include "fourcc.h"
+
+#define USE_FB
+#ifdef USE_FB
+#include "fb.h"
+#else
+#include "cfb.h"
+#include "cfb16.h"
+#include "cfb32.h"
+#endif
+
+#include "xf86cmap.h"
+#include "vbe.h"
+#include "xaa.h"
+
+#include "via_regs.h"
+#include "via_bios.h"
+#include "via_priv.h"
+#include "via_swov.h"
+#include "via_dmabuffer.h"
+#include "via_3d.h"
+
+#ifdef XF86DRI
+#define _XF86DRI_SERVER_
+#include "sarea.h"
+#include "dri.h"
+#include "GL/glxint.h"
+#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)
+#define VIA_SCRATCH_SIZE (4*1024*1024)
+
+/*
+ * Pixmap sizes below which we don't try to do hw accel.
+ */
+
+#define VIA_MIN_COMPOSITE 400
+#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
+#define AGP_SIZE (AGP_PAGE_SIZE * AGP_PAGES)
+
+#define DRIVER_NAME "via"
+#define VERSION_MAJOR 0
+#define VERSION_MINOR 2
+#ifdef USE_NEW_XVABI
+#define PATCHLEVEL 1
+#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 {
+ CARD8 SR08, SR0A, SR0F;
+
+ /* extended Sequencer registers */
+ CARD8 SR10, SR11, SR12, SR13,SR14,SR15,SR16;
+ CARD8 SR17, SR18, SR19, SR1A,SR1B,SR1C,SR1D,SR1E;
+ CARD8 SR1F, SR20, SR21, SR22,SR23,SR24,SR25,SR26;
+ CARD8 SR27, SR28, SR29, SR2A,SR2B,SR2C,SR2D,SR2E;
+ CARD8 SR2F, SR30, SR31, SR32,SR33,SR34,SR40,SR41;
+ CARD8 SR42, SR43, SR44, SR45,SR46,SR47;
+
+ /* extended CRTC registers */
+ CARD8 CR13, CR30, CR31, CR32, CR33, CR34, CR35, CR36;
+ CARD8 CR37, CR38, CR39, CR3A, CR40, CR41, CR42, CR43;
+ CARD8 CR44, CR45, CR46, CR47, CR48, CR49, CR4A;
+ CARD8 CRTCRegs[68];
+/* CARD8 LCDRegs[0x40];*/
+} VIARegRec, *VIARegPtr;
+
+/*
+ * varables that need to be shared among different screens.
+ */
+typedef struct {
+ Bool b3DRegsInitialized;
+} ViaSharedRec, *ViaSharedPtr;
+
+#ifdef XF86DRI
+
+#define VIA_XVMC_MAX_BUFFERS 2
+#define VIA_XVMC_MAX_CONTEXTS 4
+#define VIA_XVMC_MAX_SURFACES 20
+
+
+typedef struct {
+ VIAMem memory_ref;
+ unsigned long offsets[VIA_XVMC_MAX_BUFFERS];
+} ViaXvMCSurfacePriv;
+
+typedef struct {
+ drm_context_t drmCtx;
+} ViaXvMCContextPriv;
+
+typedef struct {
+ XID contexts[VIA_XVMC_MAX_CONTEXTS];
+ XID surfaces[VIA_XVMC_MAX_SURFACES];
+ ViaXvMCSurfacePriv *sPrivs[VIA_XVMC_MAX_SURFACES];
+ ViaXvMCContextPriv *cPrivs[VIA_XVMC_MAX_CONTEXTS];
+ int nContexts,nSurfaces;
+ drm_handle_t mmioBase,fbBase,sAreaBase;
+ unsigned sAreaSize;
+ drmAddress sAreaAddr;
+ unsigned activePorts;
+}ViaXvMC, *ViaXvMCPtr;
+
+#endif
+
+typedef struct _twodContext {
+ CARD32 mode;
+ CARD32 cmd;
+ CARD32 fgColor;
+ CARD32 bgColor;
+ CARD32 pattern0;
+ CARD32 pattern1;
+ CARD32 patternAddr;
+ CARD32 keyControl;
+ unsigned srcOffset;
+ unsigned srcPitch;
+ unsigned Bpp;
+ unsigned bytesPPShift;
+ Bool clipping;
+ Bool dashed;
+ int clipX1;
+ int clipX2;
+ int clipY1;
+ int clipY2;
+} ViaTwodContext;
+
+typedef struct{
+ /* textMode */
+ CARD8 *state, *pstate; /* SVGA state */
+ int statePage, stateSize, stateMode;
+
+ /* vbe version */
+ int major, minor;
+} ViaVbeModeInfo;
+
+typedef struct _VIA {
+ VIARegRec SavedReg;
+ xf86CursorInfoPtr CursorInfoRec;
+ int Bpp, Bpl;
+
+ Bool FirstInit;
+ unsigned long videoRambytes;
+ int videoRamKbytes;
+ int FBFreeStart;
+ int FBFreeEnd;
+ int driSize;
+ int maxDriSize;
+ int CursorStart;
+ int VQStart;
+ int VQEnd;
+
+ /* These are physical addresses. */
+ unsigned long FrameBufferBase;
+ unsigned long MmioBase;
+
+ /* These are linear addresses. */
+ unsigned char* MapBase;
+ unsigned char* VidMapBase;
+ unsigned char* MpegMapBase;
+ unsigned char* BltBase;
+ unsigned char* MapBaseDense;
+ unsigned char* FBBase;
+ CARD8 MemClk;
+
+ /* Here are all the Options */
+ Bool VQEnable;
+ Bool hwcursor;
+ Bool NoAccel;
+ Bool shadowFB;
+ int rotate;
+ Bool vbeSR;
+ int agpMem;
+
+ CloseScreenProcPtr CloseScreen;
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+ int Chipset;
+ int ChipId;
+ int ChipRev;
+ int EntityIndex;
+
+ /* vbe */
+ vbeInfoPtr pVbe;
+ ViaVbeModeInfo vbeMode;
+ Bool useVBEModes;
+
+ /* Support for shadowFB and rotation */
+ unsigned char* ShadowPtr;
+ int ShadowPitch;
+ void (*PointerMoved)(int index, int x, int y);
+
+ /* Support for XAA acceleration */
+ XAAInfoRecPtr AccelInfoRec;
+ ViaTwodContext td;
+ Via3DState v3d;
+ Via3DState *lastToUpload;
+ ViaCommandBuffer cb;
+ int accelMarker;
+ CARD32 markerOffset;
+ CARD32 *markerBuf;
+ CARD32 curMarker;
+ CARD32 lastMarkerRead;
+ Bool agpDMA;
+ Bool nPOT[VIA_NUM_TEXUNITS];
+#ifdef VIA_HAVE_EXA
+ ExaDriverPtr exaDriverPtr;
+ ExaOffscreenArea *exa_scratch;
+ unsigned int exa_scratch_next;
+ Bool useEXA;
+ void *maskP;
+ CARD32 maskFormat;
+ Bool componentAlpha;
+ void *srcP;
+ CARD32 srcFormat;
+ ExaOffscreenArea *scratchFBBuffer;
+ unsigned scratchOffset;
+ int exaScratchSize;
+ char * scratchAddr;
+ Bool noComposite;
+#ifdef XF86DRI
+ drm_via_mem_t scratchAGPBuffer;
+ drm_via_mem_t texAGPBuffer;
+ unsigned texOffset;
+ char * texAddr;
+ char * dBounce;
+#endif
+#endif
+
+ /* BIOS Info Ptr */
+ VIABIOSInfoPtr pBIOSInfo;
+ struct ViaCardIdStruct* Id;
+
+ /* Support for DGA */
+ int numDGAModes;
+ DGAModePtr DGAModes;
+ Bool DGAactive;
+ int DGAViewportStatus;
+ int DGAOldDisplayWidth;
+ int DGAOldBitsPerPixel;
+ int DGAOldDepth;
+
+ /* I2C & DDC */
+ I2CBusPtr pI2CBus1;
+ I2CBusPtr pI2CBus2;
+ I2CBusPtr pI2CBus3;
+ xf86MonPtr DDC1;
+ xf86MonPtr DDC2;
+
+ /* MHS */
+ Bool IsSecondary;
+ Bool HasSecondary;
+ Bool SAMM;
+
+#ifdef XF86DRI
+ Bool directRenderingEnabled;
+ Bool XvMCEnabled;
+ DRIInfoPtr pDRIInfo;
+ int drmFD;
+ int numVisualConfigs;
+ __GLXvisualConfig* pVisualConfigs;
+ VIAConfigPrivPtr pVisualConfigsPriv;
+ drm_handle_t agpHandle;
+ drm_handle_t registerHandle;
+ drm_handle_t frameBufferHandle;
+ unsigned long agpAddr;
+ drmAddress agpMappedAddr;
+ unsigned char *agpBase;
+ unsigned int agpSize;
+ Bool IsPCI;
+ ViaXvMC xvmc;
+ int drmVerMajor;
+ int drmVerMinor;
+ int drmVerPL;
+ VIAMem driOffScreenMem;
+ void * driOffScreenSave;
+#endif
+ Bool DRIIrqEnable;
+ Bool agpEnable;
+ Bool dma2d;
+ Bool dmaXV;
+
+ CARD8 ActiveDevice; /* Option */
+ unsigned char *CursorImage;
+ CARD32 CursorFG;
+ CARD32 CursorBG;
+ CARD32 CursorMC;
+
+ /* Video */
+ swovRec swov;
+ CARD32 VideoStatus;
+ VIAHWDiff HWDiff;
+ unsigned long dwV1, dwV3;
+ unsigned long OverlaySupported;
+ unsigned long dwFrameNum;
+
+ CARD32* VidRegBuffer; /* Temporary buffer for video overlay registers. */
+ unsigned long VidRegCursor; /* Write cursor for VidRegBuffer. */
+
+ unsigned long old_dwUseExtendedFIFO;
+
+ ViaSharedPtr sharedData;
+ Bool useDmaBlit;
+#ifdef HAVE_DEBUG
+ Bool disableXvBWCheck;
+ Bool DumpVGAROM;
+ Bool PrintVGARegs;
+ Bool PrintTVRegs;
+ Bool I2CScan;
+#endif /* HAVE_DEBUG */
+} VIARec, *VIAPtr;
+
+#define VIAPTR(p) ((VIAPtr)((p)->driverPrivate))
+
+typedef struct
+{
+ Bool IsDRIEnabled;
+
+ Bool HasSecondary;
+ Bool BypassSecondary;
+ /*These two registers are used to make sure the CRTC2 is
+ retored before CRTC_EXT, otherwise it could lead to blank screen.*/
+ Bool IsSecondaryRestored;
+ Bool RestorePrimary;
+
+ ScrnInfoPtr pSecondaryScrn;
+ ScrnInfoPtr pPrimaryScrn;
+} 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);
+
+/* In via_accel.c. */
+Bool viaInitAccel(ScreenPtr);
+void viaInitialize2DEngine(ScrnInfoPtr);
+void viaAccelSync(ScrnInfoPtr);
+void viaDisableVQ(ScrnInfoPtr);
+void viaExitAccel(ScreenPtr);
+void viaAccelBlitRect(ScrnInfoPtr, int, int, int, int, int, int);
+void viaAccelFillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
+void viaAccelSyncMarker(ScrnInfoPtr);
+void viaFinishInitAccel(ScreenPtr);
+void viaAccelWaitMarker(ScreenPtr, int);
+int viaAccelMarkSync(ScreenPtr);
+void viaAccelFillPixmap(ScrnInfoPtr, unsigned long, unsigned long,
+ int, int, int, int, int, unsigned long);
+void viaAccelTextureBlit(ScrnInfoPtr, unsigned long, unsigned, unsigned,
+ unsigned, unsigned, unsigned, unsigned,
+ unsigned long, unsigned, unsigned,
+ unsigned, unsigned, int);
+
+
+
+/* In via_shadow.c */
+void ViaShadowFBInit(ScrnInfoPtr pScrn, ScreenPtr pScreen);
+
+/* In via_dga.c */
+Bool VIADGAInit(ScreenPtr);
+
+/*In via_video.c*/
+void viaInitVideo(ScreenPtr pScreen);
+void viaExitVideo(ScrnInfoPtr pScrn);
+void viaSaveVideo(ScrnInfoPtr pScrn);
+void viaRestoreVideo(ScrnInfoPtr pScrn);
+void viaSetColorSpace(VIAPtr pVia, int hue, int saturation, int brightness, int contrast,
+ Bool reset);
+void VIAVidAdjustFrame(ScrnInfoPtr pScrn, int x, int y);
+
+/* In via_memory.c */
+void VIAFreeLinear(VIAMemPtr);
+int VIAAllocLinear(VIAMemPtr, ScrnInfoPtr, unsigned long);
+int viaOffscreenLinear(VIAMemPtr, ScrnInfoPtr, unsigned long);
+void VIAInitLinear(ScreenPtr pScreen);
+
+/* In via_xwmc.c */
+
+#ifdef XF86DRI
+/* Basic init and exit functions */
+void ViaInitXVMC(ScreenPtr pScreen);
+void ViaCleanupXVMC(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr *XvAdaptors, int XvAdaptorCount);
+int viaXvMCInitXv(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr XvAdapt);
+
+/* Returns the size of the fake Xv Image used as XvMC command buffer to the X server*/
+unsigned long viaXvMCPutImageSize(ScrnInfoPtr pScrn);
+
+
+
+#endif
+
+/* via_i2c.c */
+void ViaI2CInit(ScrnInfoPtr pScrn);
+
+#ifdef XF86DRI
+Bool VIADRIScreenInit(ScreenPtr pScreen);
+void VIADRICloseScreen(ScreenPtr pScreen);
+Bool VIADRIFinishScreenInit(ScreenPtr pScreen);
+void VIADRIRingBufferCleanup(ScrnInfoPtr pScrn);
+Bool VIADRIRingBufferInit(ScrnInfoPtr pScrn);
+void viaDRIOffscreenRestore(ScrnInfoPtr pScrn);
+void viaDRIOffscreenSave(ScrnInfoPtr pScrn);
+
+#endif /* XF86DRI */
+
+#endif /* _VIA_DRIVER_H_ */
diff --git a/src/via_drm.h b/src/via_drm.h
new file mode 100644
index 000000000000..9d85a1e84c0b
--- /dev/null
+++ b/src/via_drm.h
@@ -0,0 +1,270 @@
+/*
+ * 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 AUTHOR(S) OR COPYRIGHT HOLDER(S) 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 _VIA_DRM_H_
+#define _VIA_DRM_H_
+
+/* WARNING: These defines must be the same as what the Xserver uses.
+ * if you change them, you must change the defines in the Xserver.
+ */
+
+#ifndef _VIA_DEFINES_
+#define _VIA_DEFINES_
+
+#if !defined(__KERNEL__) && !defined(_KERNEL)
+#include "via_drmclient.h"
+#endif
+
+#define VIA_NR_SAREA_CLIPRECTS 8
+#define VIA_NR_XVMC_PORTS 10
+#define VIA_NR_XVMC_LOCKS 5
+#define VIA_MAX_CACHELINE_SIZE 64
+#define XVMCLOCKPTR(saPriv,lockNo) \
+ ((volatile drm_hw_lock_t *)(((((unsigned long) (saPriv)->XvMCLockArea) + \
+ (VIA_MAX_CACHELINE_SIZE - 1)) & \
+ ~(VIA_MAX_CACHELINE_SIZE - 1)) + \
+ VIA_MAX_CACHELINE_SIZE*(lockNo)))
+
+/* Each region is a minimum of 64k, and there are at most 64 of them.
+ */
+#define VIA_NR_TEX_REGIONS 64
+#define VIA_LOG_MIN_TEX_REGION_SIZE 16
+#endif
+
+#define VIA_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */
+#define VIA_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */
+#define VIA_UPLOAD_CTX 0x4
+#define VIA_UPLOAD_BUFFERS 0x8
+#define VIA_UPLOAD_TEX0 0x10
+#define VIA_UPLOAD_TEX1 0x20
+#define VIA_UPLOAD_CLIPRECTS 0x40
+#define VIA_UPLOAD_ALL 0xff
+
+/* VIA specific ioctls */
+#define DRM_VIA_ALLOCMEM 0x00
+#define DRM_VIA_FREEMEM 0x01
+#define DRM_VIA_AGP_INIT 0x02
+#define DRM_VIA_FB_INIT 0x03
+#define DRM_VIA_MAP_INIT 0x04
+#define DRM_VIA_DEC_FUTEX 0x05
+#define NOT_USED
+#define DRM_VIA_DMA_INIT 0x07
+#define DRM_VIA_CMDBUFFER 0x08
+#define DRM_VIA_FLUSH 0x09
+#define DRM_VIA_PCICMD 0x0a
+#define DRM_VIA_CMDBUF_SIZE 0x0b
+#define NOT_USED
+#define DRM_VIA_WAIT_IRQ 0x0d
+#define DRM_VIA_DMA_BLIT 0x0e
+#define DRM_VIA_BLIT_SYNC 0x0f
+
+#define DRM_IOCTL_VIA_ALLOCMEM DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_ALLOCMEM, drm_via_mem_t)
+#define DRM_IOCTL_VIA_FREEMEM DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_FREEMEM, drm_via_mem_t)
+#define DRM_IOCTL_VIA_AGP_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_AGP_INIT, drm_via_agp_t)
+#define DRM_IOCTL_VIA_FB_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_FB_INIT, drm_via_fb_t)
+#define DRM_IOCTL_VIA_MAP_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_MAP_INIT, drm_via_init_t)
+#define DRM_IOCTL_VIA_DEC_FUTEX DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_DEC_FUTEX, drm_via_futex_t)
+#define DRM_IOCTL_VIA_DMA_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_DMA_INIT, drm_via_dma_init_t)
+#define DRM_IOCTL_VIA_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_CMDBUFFER, drm_via_cmdbuffer_t)
+#define DRM_IOCTL_VIA_FLUSH DRM_IO( DRM_COMMAND_BASE + DRM_VIA_FLUSH)
+#define DRM_IOCTL_VIA_PCICMD DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_PCICMD, drm_via_cmdbuffer_t)
+#define DRM_IOCTL_VIA_CMDBUF_SIZE DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_CMDBUF_SIZE, \
+ drm_via_cmdbuf_size_t)
+#define DRM_IOCTL_VIA_WAIT_IRQ DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_WAIT_IRQ, drm_via_irqwait_t)
+#define DRM_IOCTL_VIA_DMA_BLIT DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_DMA_BLIT, drm_via_dmablit_t)
+#define DRM_IOCTL_VIA_BLIT_SYNC DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_BLIT_SYNC, drm_via_blitsync_t)
+
+/* Indices into buf.Setup where various bits of state are mirrored per
+ * context and per buffer. These can be fired at the card as a unit,
+ * or in a piecewise fashion as required.
+ */
+
+#define VIA_TEX_SETUP_SIZE 8
+
+/* Flags for clear ioctl
+ */
+#define VIA_FRONT 0x1
+#define VIA_BACK 0x2
+#define VIA_DEPTH 0x4
+#define VIA_STENCIL 0x8
+
+#define VIA_MEM_VIDEO 0 /* matches drm constant */
+#define VIA_MEM_AGP 1 /* matches drm constant */
+#define VIA_MEM_SYSTEM 2
+#define VIA_MEM_MIXED 3
+#define VIA_MEM_UNKNOWN 4
+
+typedef struct {
+ uint32_t offset;
+ uint32_t size;
+} drm_via_agp_t;
+
+typedef struct {
+ uint32_t offset;
+ uint32_t size;
+} drm_via_fb_t;
+
+typedef struct {
+ uint32_t context;
+ uint32_t type;
+ uint32_t size;
+ unsigned long index;
+ unsigned long offset;
+} drm_via_mem_t;
+
+typedef struct _drm_via_init {
+ enum {
+ VIA_INIT_MAP = 0x01,
+ VIA_CLEANUP_MAP = 0x02
+ } func;
+
+ unsigned long sarea_priv_offset;
+ unsigned long fb_offset;
+ unsigned long mmio_offset;
+ unsigned long agpAddr;
+} drm_via_init_t;
+
+typedef struct _drm_via_futex {
+ enum {
+ VIA_FUTEX_WAIT = 0x00,
+ VIA_FUTEX_WAKE = 0X01
+ } func;
+ uint32_t ms;
+ uint32_t lock;
+ uint32_t val;
+} drm_via_futex_t;
+
+typedef struct _drm_via_dma_init {
+ enum {
+ VIA_INIT_DMA = 0x01,
+ VIA_CLEANUP_DMA = 0x02,
+ VIA_DMA_INITIALIZED = 0x03
+ } func;
+
+ unsigned long offset;
+ unsigned long size;
+ unsigned long reg_pause_addr;
+} drm_via_dma_init_t;
+
+typedef struct _drm_via_cmdbuffer {
+ char __user *buf;
+ unsigned long size;
+} drm_via_cmdbuffer_t;
+
+/* Warning: If you change the SAREA structure you must change the Xserver
+ * structure as well */
+
+typedef struct _drm_via_tex_region {
+ unsigned char next, prev; /* indices to form a circular LRU */
+ unsigned char inUse; /* owned by a client, or free? */
+ int age; /* tracked by clients to update local LRU's */
+} drm_via_tex_region_t;
+
+typedef struct _drm_via_sarea {
+ unsigned int dirty;
+ unsigned int nbox;
+ drm_clip_rect_t boxes[VIA_NR_SAREA_CLIPRECTS];
+ drm_via_tex_region_t texList[VIA_NR_TEX_REGIONS + 1];
+ int texAge; /* last time texture was uploaded */
+ int ctxOwner; /* last context to upload state */
+ int vertexPrim;
+
+ /*
+ * Below is for XvMC.
+ * We want the lock integers alone on, and aligned to, a cache line.
+ * Therefore this somewhat strange construct.
+ */
+
+ char XvMCLockArea[VIA_MAX_CACHELINE_SIZE * (VIA_NR_XVMC_LOCKS + 1)];
+
+ unsigned int XvMCDisplaying[VIA_NR_XVMC_PORTS];
+ unsigned int XvMCSubPicOn[VIA_NR_XVMC_PORTS];
+ unsigned int XvMCCtxNoGrabbed; /* Last context to hold decoder */
+
+ /* Used by the 3d driver only at this point, for pageflipping:
+ */
+
+ unsigned int pfCurrentOffset;
+} drm_via_sarea_t;
+
+typedef struct _drm_via_cmdbuf_size {
+ enum {
+ VIA_CMDBUF_SPACE = 0x01,
+ VIA_CMDBUF_LAG = 0x02
+ } func;
+ int wait;
+ uint32_t size;
+} drm_via_cmdbuf_size_t;
+
+typedef enum {
+ VIA_IRQ_ABSOLUTE = 0x0,
+ VIA_IRQ_RELATIVE = 0x1,
+ VIA_IRQ_SIGNAL = 0x10000000,
+ VIA_IRQ_FORCE_SEQUENCE = 0x20000000
+} via_irq_seq_type_t;
+
+#define VIA_IRQ_FLAGS_MASK 0xF0000000
+
+enum drm_via_irqs{drm_via_irq_hqv0 = 0,
+ drm_via_irq_hqv1,
+ drm_via_irq_dma0_dd,
+ drm_via_irq_dma0_td,
+ drm_via_irq_dma1_dd,
+ drm_via_irq_dma1_td,
+ drm_via_irq_num};
+
+struct drm_via_wait_irq_request{
+ unsigned irq;
+ via_irq_seq_type_t type;
+ uint32_t sequence;
+ uint32_t signal;
+};
+
+typedef union drm_via_irqwait {
+ struct drm_via_wait_irq_request request;
+ struct drm_wait_vblank_reply reply;
+} drm_via_irqwait_t;
+
+typedef struct drm_via_blitsync {
+ uint32_t sync_handle;
+ unsigned engine;
+} drm_via_blitsync_t;
+
+typedef struct drm_via_dmablit {
+ uint32_t num_lines;
+ uint32_t line_length;
+
+ uint32_t fb_addr;
+ uint32_t fb_stride;
+
+ unsigned char *mem_addr;
+ uint32_t mem_stride;
+
+ int bounce_buffer;
+ int to_fb;
+
+ drm_via_blitsync_t sync;
+} drm_via_dmablit_t;
+
+
+#endif /* _VIA_DRM_H_ */
diff --git a/src/via_drmclient.h b/src/via_drmclient.h
new file mode 100644
index 000000000000..8d54693ecd4a
--- /dev/null
+++ b/src/via_drmclient.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2005 The Unichrome Project, 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 AUTHOR(S) OR COPYRIGHT HOLDER(S) 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 _VIA_DRMCLIENT_H
+#define _VIA_DRMCLIENT_H
+
+#include "drm.h"
+#include "xf86drm.h"
+#include "stdint.h"
+
+#ifdef X_NEED_DRMLOCK
+#define drm_hw_lock_t drmLock
+#endif
+
+#define UNICHROME_LOCK(fd, lockNo, saPriv, context, lastcontext, ret) \
+ do { \
+ volatile drm_hw_lock_t *lockPtr = XVMCLOCKPTR((saPriv), (lockNo)); \
+ unsigned lockVal; \
+ DRM_CAS_RESULT(__ret); \
+ \
+ ret = 0; \
+ lockVal = lockPtr->lock & ~(DRM_LOCK_HELD | DRM_LOCK_CONT); \
+ DRM_CAS(lockPtr, lockVal, (context) | DRM_LOCK_HELD, __ret); \
+ if (__ret) { \
+ drm_via_futex_t fx; \
+ \
+ lockVal = lockPtr->lock; \
+ if (! (lockVal & DRM_LOCK_HELD)) continue; \
+ if ((lockVal & ~(DRM_LOCK_HELD | DRM_LOCK_CONT) ) \
+ == (context)) { \
+ lastcontext = lockVal & ~(DRM_LOCK_HELD | DRM_LOCK_CONT); \
+ break; \
+ } \
+ fx.val = lockVal | DRM_LOCK_CONT; \
+ DRM_CAS( lockPtr, lockVal, fx.val, __ret); \
+ lockVal = lockPtr->lock; \
+ if (__ret) continue; \
+ fx.func = VIA_FUTEX_WAIT; \
+ fx.lock = (lockNo); \
+ fx.ms = 10; \
+ ret = drmCommandWrite((fd), DRM_VIA_DEC_FUTEX, \
+ &fx,sizeof(fx)); \
+ lastcontext = lockVal; \
+ if (ret) break; \
+ continue; \
+ } else { \
+ lastcontext = lockVal; \
+ break; \
+ } \
+ } while (1) \
+
+#define UNICHROME_UNLOCK(fd, lockNo, saPriv, context) \
+ do { \
+ volatile drm_hw_lock_t *lockPtr = XVMCLOCKPTR((saPriv), (lockNo)); \
+ \
+ if ((lockPtr->lock & ~DRM_LOCK_CONT) == \
+ ((context) | DRM_LOCK_HELD)) { \
+ DRM_CAS_RESULT(__ret); \
+ DRM_CAS(lockPtr,(context) | DRM_LOCK_HELD, context, __ret); \
+ if (__ret) { \
+ drm_via_futex_t fx; \
+ fx.func = VIA_FUTEX_WAKE; \
+ fx.lock = lockNo; \
+ DRM_CAS(lockPtr, (context) | DRM_LOCK_HELD | \
+ DRM_LOCK_CONT, \
+ context, __ret); \
+ drmCommandWrite((fd), DRM_VIA_DEC_FUTEX, &fx, \
+ sizeof(fx)); \
+ } \
+ } \
+ } while (0) \
+
+#define UNICHROME_LOCK_DECODER1 0
+#define UNICHROME_LOCK_DECODER2 1
+#define UNICHROME_LOCK_HQV 4
+#define __user
+
+#endif
diff --git a/src/via_i2c.c b/src/via_i2c.c
new file mode 100644
index 000000000000..8a52729520e9
--- /dev/null
+++ b/src/via_i2c.c
@@ -0,0 +1,428 @@
+/*
+ * Copyright 2004 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.
+ */
+/*
+ * Implements three i2c busses through registers SR26, SR2c and SR31
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "via_driver.h"
+#include "via_vgahw.h"
+
+#define SDA_READ 0x04
+#define SCL_READ 0x08
+#define SDA_WRITE 0x10
+#define SCL_WRITE 0x20
+
+/*
+ *
+ * CRT I2C
+ *
+ */
+/*
+ *
+ */
+static void
+ViaI2C1PutBits(I2CBusPtr Bus, int clock, int data)
+{
+ vgaHWPtr hwp = VGAHWPTR(xf86Screens[Bus->scrnIndex]);
+ CARD8 value = 0x01; /* Enable */
+
+ if (clock)
+ value |= SCL_WRITE;
+
+ if (data)
+ value |= SDA_WRITE;
+
+ ViaSeqMask(hwp, 0x26, value, 0x01 | SCL_WRITE | SDA_WRITE);
+}
+
+/*
+ *
+ */
+static void
+ViaI2C1GetBits(I2CBusPtr Bus, int *clock, int *data)
+{
+ vgaHWPtr hwp = VGAHWPTR(xf86Screens[Bus->scrnIndex]);
+ CARD8 value = hwp->readSeq(hwp, 0x26);
+
+ *clock = (value & SCL_READ) != 0;
+ *data = (value & SDA_READ) != 0;
+}
+
+/*
+ *
+ */
+static I2CBusPtr
+ViaI2CBus1Init(int scrnIndex)
+{
+ I2CBusPtr pI2CBus = xf86CreateI2CBusRec();
+
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "ViaI2CBus1Init\n"));
+
+ if (!pI2CBus)
+ return NULL;
+
+ pI2CBus->BusName = "I2C bus 1";
+ pI2CBus->scrnIndex = scrnIndex;
+ pI2CBus->I2CPutBits = ViaI2C1PutBits;
+ pI2CBus->I2CGetBits = ViaI2C1GetBits;
+
+ if (!xf86I2CBusInit(pI2CBus)) {
+ xf86DestroyI2CBusRec(pI2CBus, TRUE, FALSE);
+ return NULL;
+ }
+
+ return pI2CBus;
+}
+
+/*
+ *
+ * First data bus I2C: tends to have TV-encoders
+ *
+ */
+/*
+ *
+ */
+static void
+ViaI2C2PutBits(I2CBusPtr Bus, int clock, int data)
+{
+ vgaHWPtr hwp = VGAHWPTR(xf86Screens[Bus->scrnIndex]);
+ CARD8 value = 0x01; /* Enable */
+
+ if (clock)
+ value |= SCL_WRITE;
+
+ if (data)
+ value |= SDA_WRITE;
+
+ ViaSeqMask(hwp, 0x31, value, 0x01 | SCL_WRITE | SDA_WRITE);
+}
+
+/*
+ *
+ */
+static void
+ViaI2C2GetBits(I2CBusPtr Bus, int *clock, int *data)
+{
+ vgaHWPtr hwp = VGAHWPTR(xf86Screens[Bus->scrnIndex]);
+ CARD8 value = hwp->readSeq(hwp, 0x31);
+
+ *clock = (value & SCL_READ) != 0;
+ *data = (value & SDA_READ) != 0;
+}
+
+/*
+ *
+ */
+static I2CBusPtr
+ViaI2CBus2Init(int scrnIndex)
+{
+ I2CBusPtr pI2CBus = xf86CreateI2CBusRec();
+
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "ViaI2cBus2Init\n"));
+
+ if (!pI2CBus)
+ return NULL;
+
+ pI2CBus->BusName = "I2C bus 2";
+ pI2CBus->scrnIndex = scrnIndex;
+ pI2CBus->I2CPutBits = ViaI2C2PutBits;
+ pI2CBus->I2CGetBits = ViaI2C2GetBits;
+
+ if (!xf86I2CBusInit(pI2CBus)) {
+ xf86DestroyI2CBusRec(pI2CBus, TRUE, FALSE);
+ return NULL;
+ }
+
+ return pI2CBus;
+}
+
+/*
+ * A third I2C bus implemented by a few IO pins.
+ * Requires higher level functions to be used properly.
+ * Former via_gpioi2c.
+ *
+ */
+/*
+ *
+ */
+static Bool
+ViaI2C3Start(I2CBusPtr b, int timeout)
+{
+ vgaHWPtr hwp = VGAHWPTR(xf86Screens[b->scrnIndex]);
+
+ ViaSeqMask(hwp, 0x2C, 0xF0, 0xF0);
+ b->I2CUDelay(b, b->RiseFallTime);
+
+ ViaSeqMask(hwp, 0x2C, 0x00, 0x10);
+ b->I2CUDelay(b, b->HoldTime);
+ ViaSeqMask(hwp, 0x2C, 0x00, 0x20);
+ b->I2CUDelay(b, b->HoldTime);
+
+ return TRUE;
+}
+
+/*
+ *
+ */
+static Bool
+ViaI2C3Address(I2CDevPtr d, I2CSlaveAddr addr)
+{
+ I2CBusPtr b = d->pI2CBus;
+
+#ifdef X_NEED_I2CSTART
+ if (b->I2CStart(d->pI2CBus, d->StartTimeout)) {
+#else
+ if (ViaI2C3Start(d->pI2CBus, d->StartTimeout)) {
+#endif
+ if (b->I2CPutByte(d, addr & 0xFF)) {
+ if ((addr & 0xF8) != 0xF0 &&
+ (addr & 0xFE) != 0x00)
+ return TRUE;
+
+ if (b->I2CPutByte(d, (addr >> 8) & 0xFF))
+ return TRUE;
+ }
+
+ b->I2CStop(d);
+ }
+
+ return FALSE;
+}
+
+/*
+ *
+ */
+static void
+ViaI2C3Stop(I2CDevPtr d)
+{
+ I2CBusPtr b = d->pI2CBus;
+ vgaHWPtr hwp = VGAHWPTR(xf86Screens[b->scrnIndex]);
+
+ ViaSeqMask(hwp, 0x2C, 0xC0, 0xF0);
+ b->I2CUDelay(b, b->RiseFallTime);
+
+ ViaSeqMask(hwp, 0x2C, 0x20, 0x20);
+ b->I2CUDelay(b, b->HoldTime);
+
+ ViaSeqMask(hwp, 0x2C, 0x10, 0x10);
+ b->I2CUDelay(b, b->HoldTime);
+
+ ViaSeqMask(hwp, 0x2C, 0x00, 0x20);
+ b->I2CUDelay(b, b->HoldTime);
+}
+
+/*
+ *
+ */
+static void
+ViaI2C3PutBit(I2CBusPtr b, Bool sda, int timeout)
+{
+ vgaHWPtr hwp = VGAHWPTR(xf86Screens[b->scrnIndex]);
+
+ if (sda)
+ ViaSeqMask(hwp, 0x2C, 0x50, 0x50);
+ else
+ ViaSeqMask(hwp, 0x2C, 0x40, 0x50);
+ b->I2CUDelay(b, b->RiseFallTime/5);
+
+ ViaSeqMask(hwp, 0x2C, 0xA0, 0xA0);
+ b->I2CUDelay(b, b->HoldTime);
+ b->I2CUDelay(b, timeout);
+
+ ViaSeqMask(hwp, 0x2C, 0x80, 0xA0);
+ b->I2CUDelay(b, b->RiseFallTime/5);
+}
+
+/*
+ *
+ */
+static Bool
+ViaI2C3PutByte(I2CDevPtr d, I2CByte data)
+{
+ I2CBusPtr b = d->pI2CBus;
+ vgaHWPtr hwp = VGAHWPTR(xf86Screens[b->scrnIndex]);
+ Bool ret;
+ int i;
+
+ for (i = 7; i >= 0; i--)
+ ViaI2C3PutBit(b, (data >> i) & 0x01, b->BitTimeout);
+
+ /* raise first to avoid false positives */
+ ViaSeqMask(hwp, 0x2C, 0x50, 0x50);
+ ViaSeqMask(hwp, 0x2C, 0x00, 0x40);
+ b->I2CUDelay(b, b->RiseFallTime);
+ ViaSeqMask(hwp, 0x2C, 0xA0, 0xA0);
+
+ if (hwp->readSeq(hwp, 0x2C) & 0x04)
+ ret = FALSE;
+ else
+ ret = TRUE;
+
+ ViaSeqMask(hwp, 0x2C, 0x80, 0xA0);
+ b->I2CUDelay(b, b->RiseFallTime);
+
+ return ret;
+}
+
+/*
+ *
+ */
+static Bool
+ViaI2C3GetBit(I2CBusPtr b, int timeout)
+{
+ vgaHWPtr hwp = VGAHWPTR(xf86Screens[b->scrnIndex]);
+ Bool ret;
+
+ ViaSeqMask(hwp, 0x2c, 0x80, 0xC0);
+ b->I2CUDelay(b, b->RiseFallTime/5);
+ ViaSeqMask(hwp, 0x2c, 0xA0, 0xA0);
+ b->I2CUDelay(b, 3*b->HoldTime);
+ b->I2CUDelay(b, timeout);
+
+ if (hwp->readSeq(hwp, 0x2C) & 0x04)
+ ret = TRUE;
+ else
+ ret = FALSE;
+
+ ViaSeqMask(hwp, 0x2C, 0x80, 0xA0);
+ b->I2CUDelay(b, b->HoldTime);
+ b->I2CUDelay(b, b->RiseFallTime/5);
+
+ return ret;
+}
+
+/*
+ *
+ */
+static Bool
+ViaI2C3GetByte(I2CDevPtr d, I2CByte *data, Bool last)
+{
+ I2CBusPtr b = d->pI2CBus;
+ vgaHWPtr hwp = VGAHWPTR(xf86Screens[b->scrnIndex]);
+ int i;
+
+ *data = 0x00;
+
+ for (i = 7; i >= 0; i--)
+ if (ViaI2C3GetBit(b, b->BitTimeout))
+ *data |= 0x01 << i;
+
+ if (last) /* send NACK */
+ ViaSeqMask(hwp, 0x2C, 0x50, 0x50);
+ else /* send ACK */
+ ViaSeqMask(hwp, 0x2C, 0x40, 0x50);
+
+ ViaSeqMask(hwp, 0x2C, 0xA0, 0xA0);
+ b->I2CUDelay(b, b->HoldTime);
+
+ ViaSeqMask(hwp, 0x2C, 0x80, 0xA0);
+
+ return TRUE;
+}
+
+/*
+ *
+ */
+static I2CBusPtr
+ViaI2CBus3Init(int scrnIndex)
+{
+ I2CBusPtr pI2CBus = xf86CreateI2CBusRec();
+
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "ViaI2CBus3Init\n"));
+
+ if (!pI2CBus)
+ return NULL;
+
+ pI2CBus->BusName = "I2C bus 3";
+ pI2CBus->scrnIndex = scrnIndex;
+ pI2CBus->I2CAddress = ViaI2C3Address;
+#ifdef X_NEED_I2CSTART
+ pI2CBus->I2CStart = ViaI2C3Start;
+#endif
+ pI2CBus->I2CStop = ViaI2C3Stop;
+ pI2CBus->I2CPutByte = ViaI2C3PutByte;
+ pI2CBus->I2CGetByte = ViaI2C3GetByte;
+
+ pI2CBus->HoldTime = 10;
+ pI2CBus->BitTimeout = 10;
+ pI2CBus->ByteTimeout = 10;
+ pI2CBus->StartTimeout = 10;
+
+ if (!xf86I2CBusInit(pI2CBus)) {
+ xf86DestroyI2CBusRec(pI2CBus, TRUE, FALSE);
+ return NULL;
+ }
+
+ return pI2CBus;
+}
+
+#ifdef HAVE_DEBUG
+/*
+ *
+ */
+static void
+ViaI2CScan(I2CBusPtr Bus)
+{
+ CARD8 i;
+
+ xf86DrvMsg(Bus->scrnIndex, X_INFO, "ViaI2CScan: Scanning %s\n",
+ Bus->BusName);
+
+ for (i = 0x10; i < 0xF0; i += 2)
+ if (xf86I2CProbeAddress(Bus, i))
+ xf86DrvMsg(Bus->scrnIndex, X_PROBED, "Found slave on %s "
+ "- 0x%02X\n", Bus->BusName, i);
+}
+#endif
+
+/*
+ *
+ *
+ *
+ */
+void
+ViaI2CInit(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaI2CInit\n"));
+
+ pVia->pI2CBus1 = ViaI2CBus1Init(pScrn->scrnIndex);
+ pVia->pI2CBus2 = ViaI2CBus2Init(pScrn->scrnIndex);
+ pVia->pI2CBus3 = ViaI2CBus3Init(pScrn->scrnIndex);
+
+#ifdef HAVE_DEBUG
+ if (pVia->I2CScan) {
+ if (pVia->pI2CBus2)
+ ViaI2CScan(pVia->pI2CBus2);
+ if (pVia->pI2CBus3)
+ ViaI2CScan(pVia->pI2CBus3);
+ }
+#endif
+}
diff --git a/src/via_id.c b/src/via_id.c
new file mode 100644
index 000000000000..8f7801c518b3
--- /dev/null
+++ b/src/via_id.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2004-2005 The Unichrome Project [unichrome.sf.net]
+ *
+ * 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 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.
+ */
+
+/*
+ * Contents: a rather big structure with card-id information,
+ * and checking functions.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "via_driver.h"
+#include "via_id.h"
+
+/*
+ * Known missing devices:
+ *
+ * CLE266:
+ * Biostar M6VLQ Grand
+ * Biostar M6VLQ Pro
+ * PcChips M789CLU (with C3 onboard)
+ * PcChips M791G
+ * Soltek SL-B6A-F800 (C3 800Mhz onboard)
+ * Soltek SL-B6A-F1000 (Qbic IQ3601 | C3 1Ghz onboard)
+ * plus loads of semi-embedded devices
+ *
+ * KM400:
+ * ECS KM400-M
+ * ECS KM400A-M2
+ * PcChips M851G
+ * PcChips M851AG
+ * Soltek SL-B7C-FGR (Qbic EQ3704 | km400a)
+ * Soyo SY-K7VMP
+ * Soyo SY-K7VMP2
+ *
+ * K8M800:
+ * Abit KV8-MAX3
+ * Abit KV8
+ * Biostar Ideq 210V (km400a)
+ * Biostar M7VIZ
+ * Chaintech MK8M800
+ * Epox EP-8KMM5I (km400a)
+ * MSI K8M Neo-V
+ * MSI K8MM-V
+ * MSI K8MM-ILSR
+ * PcChips M861G
+ * Soltek SL-B9C-FGR (Qbic EQ3802-300P)
+ * Soltek SL-K8M800I-R
+ *
+ * PM800:
+ * Biostar Ideq 210M
+ * Biostar P4VMA-M
+ * Biostar P4M80-M7 (is this even a unichrome?)
+ * PcChips M955G
+ * PcChips M957G
+ * Soltek SL-PM800I
+ * Soltek SL-PM800I-R
+ * Soltek SL-PM800
+ * Soyo SY-P4VM800
+ */
+
+/*
+ * There's no reason for this to be known outside of via_id.o;
+ * only a pointer to a single entry will ever be used outside.
+ */
+static struct ViaCardIdStruct ViaCardId[] = {
+ /* CLE266 */
+ {"LT21 VA28", VIA_CLE266, 0x1019, 0x1B44, VIA_DEVICE_CRT},
+ {"ECS G320", VIA_CLE266, 0x1019, 0xB320, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ {"Asustek Terminator C3V", VIA_CLE266, 0x1043, 0x8155, VIA_DEVICE_CRT},
+ {"VIA VT3122 (CLE266)-EPIA M/MII/...", VIA_CLE266, 0x1106, 0x3122, VIA_DEVICE_CRT | VIA_DEVICE_TV},
+ {"Clevo T200V", VIA_CLE266, 0x1558, 0x200A, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ /* KM400 */
+ {"ECS KM400-M2", VIA_KM400, 0x1019, 0x1842, VIA_DEVICE_CRT},
+ {"Acer Aspire 135x", VIA_KM400, 0x1025, 0x0033, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV},
+ {"Asustek A7V8X-MX", VIA_KM400, 0x1043, 0x80ED, VIA_DEVICE_CRT},
+ {"Asustek A7V8X-LA", VIA_KM400, 0x1043, 0x80F9, VIA_DEVICE_CRT},
+ {"Asustek A7V8X-MX SE / A7V400-MX", VIA_KM400, 0x1043, 0x8118, VIA_DEVICE_CRT},
+ {"Asustek Terminator A7VT", VIA_KM400, 0x1043, 0x813E, VIA_DEVICE_CRT | VIA_DEVICE_TV},
+ {"Mitac 8375X", VIA_KM400, 0x1071, 0x8375, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV}, /* aka "UMAX 585T" */
+ {"Soltek SL-75MIV2", VIA_KM400, 0x1106, 0x0000, VIA_DEVICE_CRT}, /* VIA/0x0000 */
+ {"VIA VT3205 (KM400)", VIA_KM400, 0x1106, 0x3205, VIA_DEVICE_CRT | VIA_DEVICE_TV}, /* borrowed by Soltek SL-B7C-FGR */
+ {"VIA VT7205 (KM400A)", VIA_KM400, 0x1106, 0x7205, VIA_DEVICE_CRT}, /* borrowed by Biostar iDEQ 200V/Chaintech 7VIF4 */
+ {"Shuttle FX43", VIA_KM400, 0x1297, 0xF643, VIA_DEVICE_CRT | VIA_DEVICE_TV},
+ {"Giga-byte 7VM400(A)M", VIA_KM400, 0x1458, 0xD000, VIA_DEVICE_CRT}, /* 7VM400M, GA-7VM400AM */
+ {"MSI KM4(A)M-V", VIA_KM400, 0x1462, 0x7061, VIA_DEVICE_CRT}, /* aka "DFI KM400-MLV" */
+ {"MSI PM8M2-V", VIA_KM400, 0x1462, 0x7071, VIA_DEVICE_CRT},
+ {"MSI KM4(A)M-L", VIA_KM400, 0x1462, 0x7348, VIA_DEVICE_CRT},
+ {"Abit VA-10 (1)", VIA_KM400, 0x147B, 0x140B, VIA_DEVICE_CRT},
+ {"Abit VA-10 (2)", VIA_KM400, 0x147B, 0x140C, VIA_DEVICE_CRT},
+ {"Abit VA-20", VIA_KM400, 0x147B, 0x1411, VIA_DEVICE_CRT},
+ {"Averatec 322x", VIA_KM400, 0x14FF, 0x030D, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ {"FIC K7M-400A", VIA_KM400, 0x1509, 0x9233, VIA_DEVICE_CRT},
+ {"Biostar M7VIZ", VIA_KM400, 0x1565, 0x1200, VIA_DEVICE_CRT},
+ {"Biostar P4M800-M7", VIA_KM400, 0x1565, 0x1202, VIA_DEVICE_CRT},
+ {"Uniwill 755CI", VIA_KM400, 0x1584, 0x800A, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV}, /* aka "Gericom Hummer Advance", "Maxdata M-Book 1200X" */
+ {"Packard Bell Quasar2 (MSI MS6786)", VIA_KM400, 0x1631, 0xD002, VIA_DEVICE_CRT},
+ {"Epox EP-8KMM3I", VIA_KM400, 0x1695, 0x9023, VIA_DEVICE_CRT},
+ {"ASRock Inc. K7VM2/3/4", VIA_KM400, 0x1849, 0x7205, VIA_DEVICE_CRT},
+ {"ACorp KM400QP", VIA_KM400, 0x1915, 0x1100, VIA_DEVICE_CRT| VIA_DEVICE_TV},
+ {"Soyo K7VME", VIA_KM400, 0xA723, 0x10FD, VIA_DEVICE_CRT},
+ /* K8M800 */
+ {"ZX-5360", VIA_K8M800, 0x1019, 0x0F60, VIA_DEVICE_CRT | VIA_DEVICE_LCD },
+ {"ECS K8M800-M2 (1.0)", VIA_K8M800, 0x1019, 0x1828, VIA_DEVICE_CRT},
+ {"ECS K8M800-M2 (2.0)", VIA_K8M800, 0x1019, 0x1B45, VIA_DEVICE_CRT},
+ {"Acer Aspire 136x", VIA_K8M800, 0x1025, 0x006E, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV},
+ {"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},
+ {"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},
+ {"Sharp Actius AL27", VIA_K8M800, 0x13BD, 0x1044, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ {"Giga-byte GA-K8VM800M", VIA_K8M800, 0x1458, 0xD000, VIA_DEVICE_CRT},
+ {"MSI K8M Neo-V", VIA_K8M800, 0x1462, 0x0320, VIA_DEVICE_CRT},
+ {"MSI K8MM-V", VIA_K8M800, 0x1462, 0x7142, VIA_DEVICE_CRT},
+ {"MSI K8MM3-V", VIA_K8M800, 0x1462, 0x7181, VIA_DEVICE_CRT},
+ {"MSI K8MM-ILSR", VIA_K8M800, 0x1462, 0x7410, VIA_DEVICE_CRT},
+ {"Abit KV-80", VIA_K8M800, 0x147B, 0x1419, VIA_DEVICE_CRT},
+ {"Abit KV-81", VIA_K8M800, 0x147B, 0x141A, VIA_DEVICE_CRT},
+ {"Averatec 327x", VIA_K8M800, 0x14FF, 0x0315, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ {"Twinhead N14RA", VIA_K8M800, 0x14FF, 0x0321, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ {"Averatec 3715", VIA_K8M800, 0x14FF, 0x0322, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ {"Averatec 54xx", VIA_K8M800, 0x1509, 0x3930, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ {"FIC K8M-800M", VIA_K8M800, 0x1509, 0x6001, VIA_DEVICE_CRT},
+ {"Clevo L570W", VIA_K8M800, 0x1558, 0x0570, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ {"Mesh Pegasus", VIA_K8M800, 0x1558, 0x4702, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ {"Biostar K8VGA-M", VIA_K8M800, 0x1565, 0x1203, VIA_DEVICE_CRT},
+ {"DFI K8M800-MLVF", VIA_K8M800, 0x15BD, 0x1002, VIA_DEVICE_CRT},
+ {"Packard Bell Easynote E6116/E63xx", VIA_K8M800, 0x1631, 0xC008, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV},
+ {"Packard Bell Easynote B3 800/B3340", VIA_K8M800, 0x1631, 0xC009, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ {"Packard Bell Imedia 2097", VIA_K8M800, 0x1631, 0xD007, VIA_DEVICE_CRT},
+ {"Fujitsu-Siemens Amilo K7610", VIA_K8M800, 0x1734, 0x10B3, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ {"ASRock K8Upgrade-VM800", VIA_K8M800, 0x1849, 0x3108, VIA_DEVICE_CRT},
+ /* PM800 */
+ {"VIA VT3118 (PM800)", VIA_PM800, 0x1106, 0x3118, VIA_DEVICE_CRT}, /* borrowed by ECS PM800-M2 */
+ {"Mitac 8666", VIA_PM800, 0x1071, 0x8666, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV},
+ {"Medion MIM2080", VIA_PM800, 0x1071, 0x8965, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV},
+ {"TwinHead E12BL", VIA_PM800, 0x14FF, 0x0314, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ {"Biostar P4VMA-M", VIA_PM800, 0x1565, 0x1202, VIA_DEVICE_CRT},
+ {"Sotec WA2330S5", VIA_PM800, 0x161F, 0x2037, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV},
+ {"Packard Bell Easynote R1100", VIA_PM800, 0x1631, 0xC015, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ {"Fujitsu/Siemens Amilo Pro V2010", VIA_PM800, 0x1734, 0x1078, VIA_DEVICE_CRT | VIA_DEVICE_LCD | VIA_DEVICE_TV},
+ {"Fujitsu/Siemens Amilo L7310", VIA_PM800, 0x1734, 0x10AB, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ {"ASRock P4VM8", VIA_PM800, 0x1849, 0x3118, VIA_DEVICE_CRT},
+ {"Chaintech MPM800-3", VIA_PM800, 0x270F, 0x7671, VIA_DEVICE_CRT},
+ {"MaxSelect Optima C4", VIA_PM800, 0x1558, 0x5402, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ /* VM800 */
+ {"Clevo/RoverBook Partner E419L", VIA_VM800, 0x1019, 0x0F75, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ {"ECS P4M800PRO-M", VIA_VM800, 0x1019, 0x2122, VIA_DEVICE_CRT},
+ {"ECS C7VCM", VIA_VM800, 0x1019, 0xAA2D, VIA_DEVICE_CRT},
+ {"Asustek P5VDC-MX", VIA_VM800, 0x1043, 0x3344, VIA_DEVICE_CRT},
+ {"Asustek P5VDC-TVM", VIA_VM800, 0x1043, 0x81CE, 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},
+ {"MSI PM8M-V", VIA_VM800, 0x1462, 0x7104, VIA_DEVICE_CRT},
+ {"MSI PM8M3-V", VIA_VM800, 0x1462, 0x7211, VIA_DEVICE_CRT},
+ {"MSI PM8PM", VIA_VM800, 0x1462, 0x7222, VIA_DEVICE_CRT},
+ {"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},
+ {"Biostar P4M80-M4", VIA_VM800, 0x1565, 0x1202, VIA_DEVICE_CRT}, /* shares numbers with Biostar P4VMA-M */
+ {"Fujitsu/Siemens Amilo Pro V2030", VIA_VM800, 0x1734, 0x109B, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ {"Fujitsu/Siemens Amilo Pro V2035", VIA_VM800, 0x1734, 0x10AE, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ {"Fujitsu/Siemens Amilo Pro V2055", VIA_VM800, 0x1734, 0x10CA, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ {"Fujitsu/Siemens Amilo L7320", VIA_VM800, 0x1734, 0x10CD, VIA_DEVICE_CRT | VIA_DEVICE_LCD},
+ {"ASRock P4VM800", VIA_VM800, 0x1849, 0x3344, VIA_DEVICE_CRT},
+ {"Asustek P5V800-MX", VIA_VM800, 0x3344, 0x1122, VIA_DEVICE_CRT},
+ /* keep this */
+ {NULL, VIA_UNKNOWN, 0x0000, 0x0000, VIA_DEVICE_NONE}
+};
+
+/*
+ * Fancy little routine stolen from fb.
+ * We don't do anything but warn really.
+ */
+void
+ViaDoubleCheckCLE266Revision(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ VIAPtr pVia = VIAPTR(pScrn);
+ /* Crtc 0x4F is only defined in CLE266Cx */
+ CARD8 tmp = hwp->readCrtc(hwp, 0x4F);
+
+ hwp->writeCrtc(hwp, 0x4F, 0x55);
+
+ if (hwp->readCrtc(hwp, 0x4F) == 0x55) {
+ if (CLE266_REV_IS_AX(pVia->ChipRev))
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "CLE266 Revision seems"
+ " to be Cx, yet %d was detected previously.\n", pVia->ChipRev);
+ } else {
+ if (CLE266_REV_IS_CX(pVia->ChipRev))
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "CLE266 Revision seems"
+ " to be Ax, yet %d was detected previously.\n", pVia->ChipRev);
+ }
+ hwp->writeCrtc(hwp, 0x4F, tmp);
+}
+
+/*
+ *
+ */
+void
+ViaCheckCardId(ScrnInfoPtr pScrn)
+{
+ struct ViaCardIdStruct *Id;
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ if ((pVia->PciInfo->subsysVendor == pVia->PciInfo->vendor) &&
+ (pVia->PciInfo->subsysCard == pVia->PciInfo->chipType))
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Manufacturer plainly copied main PCI IDs to subsystem/card IDs.\n");
+
+ for (Id = ViaCardId; Id->String; Id++) {
+ if ((Id->Chip == pVia->Chipset) &&
+ (Id->Vendor == pVia->PciInfo->subsysVendor) &&
+ (Id->Device == pVia->PciInfo->subsysCard)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected %s.\n", Id->String);
+ pVia->Id = Id;
+ return;
+ }
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unknown Card-IDs (%4X|%4X); please report to <openchrome-users@openchrome.org>\n",
+ pVia->PciInfo->subsysVendor, pVia->PciInfo->subsysCard);
+ pVia->Id = NULL;
+}
diff --git a/src/via_id.h b/src/via_id.h
new file mode 100644
index 000000000000..bccaa714514a
--- /dev/null
+++ b/src/via_id.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2004-2005 The Unichrome Project [unichrome.sf.net]
+ *
+ *
+ * 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 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 _VIA_ID_H_
+#define _VIA_ID_H_ 1
+
+/* Chip tags. These are used to group the adapters into
+ * related families.
+ */
+enum VIACHIPTAGS {
+ VIA_UNKNOWN = 0,
+ VIA_CLE266,
+ VIA_KM400,
+ VIA_K8M800,
+ VIA_PM800,
+ VIA_VM800,
+ VIA_LAST
+};
+
+
+#define PCI_VIA_VENDOR_ID 0x1106
+
+/*
+ * I have disabled CLE3022. This way anyone using this device
+ * will have to read this comment or at least complain
+ * someplace. There is also the possibility that it just does
+ * not exist in the wild.
+ *
+ * Contact unichrome-devel@lists.sf.net asap if you can
+ * provide any further information.
+ *
+ */
+/* #define PCI_CHIP_CLE3022 0x3022 */ /* CLE266??? */
+#define PCI_CHIP_VT3204 0x3108 /* K8M800 */
+#define PCI_CHIP_VT3259 0x3118 /* PM800/PM880/CN400 */
+#define PCI_CHIP_CLE3122 0x3122 /* CLE266 */
+#define PCI_CHIP_VT3205 0x7205 /* KM400 */
+#define PCI_CHIP_VT3314 0x3344 /* VM800 */
+
+/*
+ * There is also quite some conflicting information on the
+ * 2 major revisions of the CLE266, oft labelled as Ax and Cx
+ * It seems to center around
+ * ChipRev > 15 == Cx
+ * and
+ * ChipRev < 15 == Ax
+ * There is only one case in original xfree86 code where 15 is
+ * handled; in via_bandwidth.c:
+ * if (pBIOSInfo->ChipRev > 14) { // For 3123Cx
+ * While setting the primary fifo, the secondary is > 15 again.
+ *
+ * So does this rule out the existence of CLE266B?
+ *
+ * It seems to be 0x10, anything from that and up is Cx, anything
+ * below is Ax
+ */
+#define CLE266_REV_IS_CX(x) ((x) >= 0x10)
+#define CLE266_REV_IS_AX(x) ((x) < 0x10)
+
+struct ViaCardIdStruct {
+ char* String; /* Full identification string. */
+ CARD8 Chip; /* Which unichrome device? */
+ CARD16 Vendor; /* PCI Card/Subsystem vendor id */
+ CARD16 Device; /* PCI Card/Subsystem device id */
+ CARD8 Outputs; /* ORed list of VIA_DEVICE_CRT, VIA_DEVICE_LCD, VIA_DEVICE_TV */
+};
+
+void ViaDoubleCheckCLE266Revision(ScrnInfoPtr pScrn);
+void ViaCheckCardId(ScrnInfoPtr pScrn);
+
+#endif /* _VIA_ID_H_ */
diff --git a/src/via_memcpy.c b/src/via_memcpy.c
new file mode 100644
index 000000000000..1a6d1b701e2b
--- /dev/null
+++ b/src/via_memcpy.c
@@ -0,0 +1,695 @@
+/*
+ * Copyright (C) 2004 Thomas Hellstrom, 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_memcpy.h"
+#include "compiler.h"
+
+
+#define BSIZ 2048 /* Size of /proc/cpuinfo buffer */
+#define BSIZW 720 /* Typical Copy Width (YUV420) Copy. */
+#define BSIZA 736 /* Multiple of 32 bytes */
+#define BSIZH 576 /* Typical Copy Hight */
+
+#define SSE_PREFETCH " prefetchnta "
+#define FENCE __asm__ __volatile__ ("sfence":::"memory");
+#define FENCEMMS __asm__ __volatile__ ("\t" \
+ "sfence\n\t" \
+ "emms\n\t" \
+ :::"memory");
+#define FEMMS __asm__ __volatile__("femms":::"memory");
+#define EMMS __asm__ __volatile__("emms":::"memory");
+
+#define NOW_PREFETCH " prefetch "
+
+
+#define PREFETCH1(arch_prefetch,from) \
+ __asm__ __volatile__ ( \
+ "1: " arch_prefetch "(%0)\n" \
+ arch_prefetch "32(%0)\n" \
+ arch_prefetch "64(%0)\n" \
+ arch_prefetch "96(%0)\n" \
+ arch_prefetch "128(%0)\n" \
+ arch_prefetch "160(%0)\n" \
+ arch_prefetch "192(%0)\n" \
+ arch_prefetch "256(%0)\n" \
+ arch_prefetch "288(%0)\n" \
+ "2:\n" \
+ : : "r" (from) );
+
+#define PREFETCH2(arch_prefetch,from) \
+ __asm__ __volatile__ ( \
+ arch_prefetch "320(%0)\n" \
+ : : "r" (from) );
+#define PREFETCH3(arch_prefetch,from) \
+ __asm__ __volatile__ ( \
+ arch_prefetch "288(%0)\n" \
+ : : "r" (from) );
+
+
+
+#define small_memcpy(to,from,n) \
+ { \
+ __asm__ __volatile__( \
+ "movl %2,%%ecx\n\t" \
+ "sarl $2,%%ecx\n\t" \
+ "rep ; movsl\n\t" \
+ "testb $2,%b2\n\t" \
+ "je 1f\n\t" \
+ "movsw\n" \
+ "1:\ttestb $1,%b2\n\t" \
+ "je 2f\n\t" \
+ "movsb\n" \
+ "2:" \
+ :"=&D" (to), "=&S" (from) \
+ :"q" (n),"0" ((long) to),"1" ((long) from) \
+ : "%ecx","memory"); \
+ }
+
+
+#define SSE_CPY(prefetch,from,to,dummy,lcnt) \
+ if ((unsigned long) from & 15) { \
+ __asm__ __volatile__ ( \
+ "1:\n" \
+ prefetch "320(%1)\n" \
+ " movups (%1), %%xmm0\n" \
+ " movups 16(%1), %%xmm1\n" \
+ " movntps %%xmm0, (%0)\n" \
+ " movntps %%xmm1, 16(%0)\n" \
+ prefetch "352(%1)\n" \
+ " movups 32(%1), %%xmm2\n" \
+ " movups 48(%1), %%xmm3\n" \
+ " movntps %%xmm2, 32(%0)\n" \
+ " movntps %%xmm3, 48(%0)\n" \
+ " addl $64,%0\n" \
+ " addl $64,%1\n" \
+ " decl %2\n" \
+ " jne 1b\n" \
+ :"=&D"(to), "=&S"(from), "=&r"(dummy) \
+ :"0" (to), "1" (from), "2" (lcnt): "memory"); \
+ } else { \
+ __asm__ __volatile__ ( \
+ "2:\n" \
+ prefetch "320(%1)\n" \
+ " movaps (%1), %%xmm0\n" \
+ " movaps 16(%1), %%xmm1\n" \
+ " movntps %%xmm0, (%0)\n" \
+ " movntps %%xmm1, 16(%0)\n" \
+ prefetch "352(%1)\n" \
+ " movaps 32(%1), %%xmm2\n" \
+ " movaps 48(%1), %%xmm3\n" \
+ " movntps %%xmm2, 32(%0)\n" \
+ " movntps %%xmm3, 48(%0)\n" \
+ " addl $64,%0\n" \
+ " addl $64,%1\n" \
+ " decl %2\n" \
+ " jne 2b\n" \
+ :"=&D"(to), "=&S"(from), "=&r"(dummy) \
+ :"0" (to), "1" (from), "2" (lcnt): "memory"); \
+ }
+
+#define MMX_CPY(prefetch,from,to,dummy,lcnt) \
+ __asm__ __volatile__ ( \
+ "1:\n" \
+ prefetch "320(%1)\n" \
+ "2: movq (%1), %%mm0\n" \
+ " movq 8(%1), %%mm1\n" \
+ " movq 16(%1), %%mm2\n" \
+ " movq 24(%1), %%mm3\n" \
+ " movq %%mm0, (%0)\n" \
+ " movq %%mm1, 8(%0)\n" \
+ " movq %%mm2, 16(%0)\n" \
+ " movq %%mm3, 24(%0)\n" \
+ prefetch "352(%1)\n" \
+ " movq 32(%1), %%mm0\n" \
+ " movq 40(%1), %%mm1\n" \
+ " movq 48(%1), %%mm2\n" \
+ " movq 56(%1), %%mm3\n" \
+ " movq %%mm0, 32(%0)\n" \
+ " movq %%mm1, 40(%0)\n" \
+ " movq %%mm2, 48(%0)\n" \
+ " movq %%mm3, 56(%0)\n" \
+ " addl $64,%0\n" \
+ " addl $64,%1\n" \
+ " decl %2\n" \
+ " jne 1b\n" \
+ :"=&D"(to), "=&S"(from), "=&r"(dummy) \
+ :"0" (to), "1" (from), "2" (lcnt) : "memory");
+
+#define MMXEXT_CPY(prefetch,from,to,dummy,lcnt) \
+ __asm__ __volatile__ ( \
+ ".p2align 4,,7\n" \
+ "1:\n" \
+ prefetch "320(%1)\n" \
+ " movq (%1), %%mm0\n" \
+ " movq 8(%1), %%mm1\n" \
+ " movq 16(%1), %%mm2\n" \
+ " movq 24(%1), %%mm3\n" \
+ " movntq %%mm0, (%0)\n" \
+ " movntq %%mm1, 8(%0)\n" \
+ " movntq %%mm2, 16(%0)\n" \
+ " movntq %%mm3, 24(%0)\n" \
+ prefetch "352(%1)\n" \
+ " movq 32(%1), %%mm0\n" \
+ " movq 40(%1), %%mm1\n" \
+ " movq 48(%1), %%mm2\n" \
+ " movq 56(%1), %%mm3\n" \
+ " movntq %%mm0, 32(%0)\n" \
+ " movntq %%mm1, 40(%0)\n" \
+ " movntq %%mm2, 48(%0)\n" \
+ " movntq %%mm3, 56(%0)\n" \
+ " addl $64,%0\n" \
+ " addl $64,%1\n" \
+ " decl %2\n" \
+ " jne 1b\n" \
+ :"=&D"(to), "=&S"(from), "=&r"(dummy) \
+ :"0" (to), "1" (from), "2" (lcnt) : "memory");
+
+
+#define PREFETCH_FUNC(prefix,itype,ptype,begin,fence) \
+ \
+ static void prefix##_YUV42X(unsigned char *to, \
+ const unsigned char *from, \
+ int dstPitch, \
+ int w, \
+ int h, \
+ int yuv422) \
+ \
+ { \
+ int \
+ dadd,rest,count,hc,lcnt; \
+ register int dummy; \
+ PREFETCH1(ptype##_PREFETCH,from); \
+ begin; \
+ count = 2; \
+ \
+ /* \
+ * If destination pitch and width ar equal, do it all in one go. \
+ */ \
+ \
+ if ( yuv422 ) { \
+ w <<= 1; \
+ if (w == dstPitch) { \
+ w *= h; \
+ h = 1; \
+ dstPitch = w; \
+ count = 0; \
+ } else { \
+ h -= 1; \
+ count = 1; \
+ } \
+ } else if (w == dstPitch) { \
+ w = h*(w + (w >> 1)); \
+ count = 0; \
+ h = 1; \
+ dstPitch = w; \
+ } \
+ \
+ lcnt = w >> 6; \
+ rest = w & 63; \
+ while(count--) { \
+ hc = h; \
+ lcnt = w >> 6; \
+ rest = w & 63; \
+ dadd = dstPitch - w; \
+ while(hc--) { \
+ if (lcnt) { \
+ itype##_CPY(ptype##_PREFETCH,from,to,dummy, \
+ lcnt); \
+ } \
+ if (rest) { \
+ PREFETCH2(ptype##_PREFETCH,from); \
+ small_memcpy(to, from, rest); \
+ PREFETCH3(ptype##_PREFETCH,from); \
+ } \
+ to += dadd; \
+ } \
+ w >>= 1; \
+ dstPitch >>= 1; \
+ h -= 1; \
+ } \
+ if (lcnt > 5) { \
+ lcnt -= 5; \
+ itype##_CPY(ptype##_PREFETCH,from,to,dummy,lcnt); \
+ lcnt = 5; \
+ } \
+ if (lcnt) { \
+ itype##_CPY("#",from,to,dummy,lcnt); \
+ } \
+ if (rest) small_memcpy(to, from, rest); \
+ fence; \
+ }
+
+#define NOPREFETCH_FUNC(prefix,itype,begin,fence) \
+ static void prefix##_YUV42X(unsigned char *to, \
+ const unsigned char *from, \
+ int dstPitch, \
+ int w, \
+ int h, \
+ int yuv422) \
+ \
+ { \
+ int \
+ dadd,rest,count,hc,lcnt; \
+ register int dummy; \
+ begin; \
+ count = 2; \
+ \
+ /* \
+ * If destination pitch and width ar equal, do it all in one go. \
+ */ \
+ \
+ if ( yuv422 ) { \
+ w <<= 1; \
+ count = 1; \
+ if (w == dstPitch) { \
+ w *= h; \
+ h = 1; \
+ dstPitch = w; \
+ } \
+ } else if (w == dstPitch) { \
+ w = h*(w + (w >> 1)); \
+ count = 1; \
+ h = 1; \
+ dstPitch = w; \
+ } \
+ \
+ lcnt = w >> 6; \
+ rest = w & 63; \
+ while(count--) { \
+ hc = h; \
+ dadd = dstPitch - w; \
+ lcnt = w >> 6; \
+ rest = w & 63; \
+ while(hc--) { \
+ if (lcnt) { \
+ itype##_CPY("#",from,to,dummy,lcnt); \
+ } \
+ if (rest) small_memcpy(to, from, rest); \
+ to += dadd; \
+ } \
+ w >>= 1; \
+ dstPitch >>= 1; \
+ } \
+ fence; \
+ } \
+
+#if !defined(__i386__) || (defined(linux) && defined(__i386__))
+
+static void libc_YUV42X(unsigned char *dst,
+ const unsigned char *src,
+ int dstPitch,
+ int w,
+ int h, int yuv422) {
+ if ( yuv422 ) w <<= 1;
+ if (dstPitch == w) {
+ int size = h*((yuv422) ? w : (w + (w >> 1)));
+ xf86memcpy(dst, src, size);
+ return;
+ } else {
+ int count;
+
+ /* copy Y component to video memory */
+
+ count = h;
+ while(count--) {
+ xf86memcpy(dst, src, w);
+ src += w;
+ dst += dstPitch;
+ }
+
+ /* UV component is 1/2 of Y */
+
+ if (! yuv422 ) {
+
+ w >>= 1;
+ dstPitch >>= 1;
+
+ /* copy V(Cr),U(Cb) components to video memory */
+
+ count = h;
+ while(count--) {
+ xf86memcpy(dst, src, w);
+ src += w;
+ dst += dstPitch;
+ }
+ }
+ }
+}
+#endif
+
+#ifdef __i386__
+
+
+
+/* linux kernel __memcpy */
+static __inline void * __memcpy(void * to, const void * from, size_t n)
+{
+ int d1,d2,d3;
+
+ __asm__ __volatile__(
+ "rep ; movsl\n\t"
+ "testb $2,%b4\n\t"
+ "je 1f\n\t"
+ "movsw\n"
+ "1:\ttestb $1,%b4\n\t"
+ "je 2f\n\t"
+ "movsb\n"
+ "2:"
+ : "=&c" (d1), "=&D" (d2), "=&S" (d3)
+ :"0" (n >> 2), "q" (n),"1" ((long) to),"2" ((long) from)
+ : "memory");
+
+ return (to);
+}
+
+
+static void kernel_YUV42X(unsigned char *dst,
+ const unsigned char *src,
+ int dstPitch,
+ int w,
+ int h, int yuv422) {
+
+ if ( yuv422 ) w <<= 1;
+ if (dstPitch == w) {
+ int size = h*((yuv422) ? w : (w + (w >> 1)));
+ __memcpy(dst, src, size);
+ return;
+ } else {
+ int count;
+
+ /* copy Y component to video memory */
+
+ count = h;
+ while(count--) {
+ __memcpy(dst, src, w);
+ src += w;
+ dst += dstPitch;
+ }
+
+ /* UV component is 1/2 of Y */
+
+ if (! yuv422 ) {
+
+ w >>= 1;
+ dstPitch >>= 1;
+
+ /* copy V(Cr),U(Cb) components to video memory */
+
+ count = h;
+ while(count--) {
+ __memcpy(dst, src, w);
+ src += w;
+ dst += dstPitch;
+ }
+ }
+ }
+}
+
+#ifdef linux
+
+PREFETCH_FUNC(sse,SSE,SSE,,FENCE)
+PREFETCH_FUNC(mmxext,MMXEXT,SSE,EMMS,FENCEMMS)
+PREFETCH_FUNC(now,MMX,NOW,FEMMS,FEMMS)
+NOPREFETCH_FUNC(mmx,MMX,EMMS,EMMS)
+
+
+static void * kernel_memcpy(void * to, const void * from, size_t len) {
+ return __memcpy(to, from, len);
+}
+
+static unsigned fastrdtsc(void)
+{
+ unsigned eax;
+ __asm__ volatile ("\t"
+ "pushl %%ebx\n\t"
+ "cpuid\n\t"
+ ".byte 0x0f, 0x31\n\t"
+ "popl %%ebx\n"
+ : "=a" (eax)
+ : "0"(0)
+ : "ecx","edx","cc");
+ return eax;
+}
+
+
+
+static unsigned time_function(vidCopyFunc mf,unsigned char *buf1,
+ unsigned char *buf2) {
+ unsigned t,t2;
+
+ t = fastrdtsc();
+
+ (*mf)(buf1,buf2,BSIZA,BSIZW,BSIZH,0);
+
+ t2 = fastrdtsc();
+ return ((t < t2) ? t2 - t : 0xFFFFFFFFU - (t - t2 -1));
+}
+
+enum {libc=0,kernel,sse,mmx,now,mmxext,totNum};
+
+
+typedef struct {
+ vidCopyFunc mFunc;
+ char *mName,**cpuFlag;
+} McFuncData;
+
+static char *libc_cpuflags[] = {" ",0};
+static char *kernel_cpuflags[] = {" ",0};
+static char *sse_cpuflags[] = {" sse ",0};
+static char *mmx_cpuflags[] = {" mmx ",0};
+static char *now_cpuflags[] = {" 3dnow ",0};
+static char *mmx2_cpuflags[] = {" mmxext ", " sse ",0};
+
+static McFuncData mcFunctions[totNum] =
+ {{libc_YUV42X,"libc",libc_cpuflags},
+ {kernel_YUV42X,"kernel",kernel_cpuflags},
+ {sse_YUV42X,"SSE",sse_cpuflags},
+ {mmx_YUV42X,"MMX",mmx_cpuflags},
+ {now_YUV42X,"3DNow!",now_cpuflags},
+ {mmxext_YUV42X,"MMX2",mmx2_cpuflags}};
+
+
+static int flagValid(const char *cpuinfo, char *flag) {
+
+ const char *flagLoc,*nextProc;
+ int located = 0;
+
+ while ((cpuinfo = strstr(cpuinfo, "processor\t:"))) {
+ located = 1;
+ cpuinfo += 11;
+ if ((flagLoc = strstr(cpuinfo,flag))) {
+ if ((nextProc = strstr(cpuinfo,"processor\t:"))) {
+ if (nextProc < flagLoc) return 0;
+ }
+ } else {
+ return 0;
+ }
+ }
+ return located;
+}
+
+
+static int cpuValid(const char *cpuinfo, char **flags) {
+
+
+ for(; *flags != 0; flags++) {
+ if (flagValid(cpuinfo, *flags)) return 1;
+ }
+ return 0;
+}
+#endif
+
+
+vidCopyFunc viaVidCopyInit( char *copyType,
+ ScreenPtr pScreen ) {
+
+ /*
+ * Benchmark the video copy routines using a relevant benchmark
+ * and choose the fastest.
+ */
+
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+#ifdef linux
+ char buf[BSIZ];
+ unsigned char *buf1,*buf2,*buf3;
+ char *tmpBuf,*endBuf;
+ int count,j,bestSoFar;
+ unsigned best,tmp,testSize,alignSize,tmp2;
+ VIAMem tmpFbBuffer;
+ McFuncData *curData;
+ FILE *cpuInfoFile;
+ double cpuFreq;
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ if (NULL == (cpuInfoFile = fopen("/proc/cpuinfo","r"))) {
+ return libc_YUV42X;
+ }
+ count = fread(buf,1,BSIZ,cpuInfoFile);
+ if (ferror(cpuInfoFile)) {
+ fclose(cpuInfoFile);
+ return libc_YUV42X;
+ }
+ fclose(cpuInfoFile);
+ if (BSIZ == count) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "\"/proc/cpuinfo\" file too long. "
+ "Using Linux kernel memcpy.\n");
+ return libc_YUV42X;
+ }
+ buf[count] = 0;
+
+ while(count--)
+ if ('\n' == buf[count]) buf[count] = ' ';
+
+ /*
+ * Extract the cpu frequency.
+ */
+
+ cpuFreq = 0.;
+
+ if (NULL != (tmpBuf = strstr(buf,"cpu MHz"))) {
+ if (NULL != (tmpBuf = strstr(tmpBuf,":") + 1)) {
+ cpuFreq = strtod(tmpBuf,&endBuf);
+ if (endBuf == tmpBuf) tmpBuf = NULL;
+ }
+ }
+
+ alignSize = BSIZH*(BSIZA + (BSIZA >> 1));
+ testSize = BSIZH*(BSIZW + (BSIZW >> 1));
+ tmpFbBuffer.pool = 0;
+
+ /*
+ * Allocate an area of offscreen FB memory, (buf1), a simulated video
+ * player buffer (buf2) and a pool of uninitialized "video" data (buf3).
+ */
+
+ if (VIAAllocLinear(&tmpFbBuffer, pScrn, alignSize + 31))
+ return libc_YUV42X;
+ if (NULL == (buf2 = (unsigned char *)xalloc(testSize))) {
+ VIAFreeLinear(&tmpFbBuffer);
+ return libc_YUV42X;
+ }
+ if (NULL == (buf3 = (unsigned char *)xalloc(testSize))) {
+ xfree(buf2);
+ VIAFreeLinear(&tmpFbBuffer);
+ return libc_YUV42X;
+ }
+ buf1 = (unsigned char *)pVia->FBBase + tmpFbBuffer.base;
+
+ /*
+ * Align the frame buffer destination memory to a 32 byte boundary.
+ */
+
+ if ((unsigned long)buf1 & 31)
+ buf1 += (32 - ((unsigned long)buf1 & 31));
+
+ bestSoFar = 0;
+ best = 0xFFFFFFFFU;
+
+ /*
+ * Make probable buf1 and buf2 are not paged out by
+ * referencing them.
+ */
+
+ libc_YUV42X(buf1,buf2,BSIZA,BSIZW,BSIZH,0);
+
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Benchmarking %s copy. Less is better.\n",copyType);
+ for (j=0; j<totNum; ++j) {
+ curData = mcFunctions + j;
+
+ if (cpuValid(buf,curData->cpuFlag)) {
+
+ /*
+ * Simulate setup of the video buffer.
+ */
+
+ kernel_memcpy(buf2,buf3,testSize);
+
+ /*
+ * Copy the video buffer to frame-buffer memory.
+ */
+
+ tmp = time_function(curData->mFunc,buf1,buf2);
+
+ /*
+ * Do it again to avoid context switch effects.
+ */
+
+ kernel_memcpy(buf2,buf3,testSize);
+ tmp2 = time_function(curData->mFunc,buf1,buf2);
+ tmp = (tmp2 < tmp) ? tmp2 : tmp;
+
+ if (NULL == tmpBuf) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Timed %6s YUV420 copy... %u.\n",curData->mName,tmp);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Timed %6s YUV420 copy... %u. "
+ "Throughput: %.1f MiB/s.\n",curData->mName,tmp,
+ cpuFreq * 1.e6 * (double)testSize /
+ ((double)(tmp) * (double)(0x100000)));
+ }
+ if (tmp < best) {
+ best = tmp;
+ bestSoFar = j;
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Ditch %6s YUV420 copy... Not supported by CPU.\n",
+ curData->mName);
+
+ }
+ }
+ xfree(buf3);
+ xfree(buf2);
+ VIAFreeLinear(&tmpFbBuffer);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Using %s YUV42X copy for %s.\n",mcFunctions[bestSoFar].mName,
+ copyType);
+ return mcFunctions[bestSoFar].mFunc;
+#endif
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using copy of Linux kernel memcpy for video.\n");
+ return kernel_YUV42X;
+}
+
+#else
+
+vidCopyFunc viaVidCopyInit( char *copyType,
+ ScreenPtr pScreen ) {
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using default xfree86 memcpy for video.\n");
+ return libc_YUV42X;
+}
+
+#endif
+
diff --git a/src/via_memcpy.h b/src/via_memcpy.h
new file mode 100644
index 000000000000..bc908e44c57b
--- /dev/null
+++ b/src/via_memcpy.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2004 Thomas Hellstrom, 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.
+ */
+#ifndef _VIA_MEMCPY_H_
+#define _VIA_MEMCPY_H_
+#include "xf86.h"
+
+typedef void (*vidCopyFunc)(unsigned char *, const unsigned char *,
+ int, int, int, int);
+extern vidCopyFunc viaVidCopyInit( char *copyType, ScreenPtr pScreen );
+
+#endif
diff --git a/src/via_memory.c b/src/via_memory.c
new file mode 100644
index 000000000000..63206d3569f4
--- /dev/null
+++ b/src/via_memory.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2003 Red Hat, 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 "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86fbman.h"
+
+#include "via.h"
+
+#ifdef XF86DRI
+#include "xf86drm.h"
+#endif
+
+#include "via_driver.h"
+#include "via_priv.h"
+#include "via_swov.h"
+#ifdef XF86DRI
+#include "via_drm.h"
+#endif
+
+/*
+ * Isolate the wonders of X memory allocation and DRI memory allocation
+ * and 4.3 or 4.4 differences in once abstraction
+ *
+ * The pool code indicates who provided the memory
+ * 0 - nobody
+ * 1 - xf86 linear
+ * 2 - DRM
+ */
+
+static void
+viaExaFBSave(ScreenPtr pScreen, ExaOffscreenArea *exa)
+{
+ FatalError("Xserver is not properly patched and incompatible with OpenChrome exa.\n"
+ "\tPlease look at Xorg bugzilla bug #7639, and\n"
+ "\thttp://wiki.openchrome.org/tikiwiki/tiki-index.php?page=EXAAcceleration .\n");
+}
+
+
+void VIAFreeLinear(VIAMemPtr mem)
+{
+ DEBUG(ErrorF("Freed %lu (pool %d)\n", mem->base, mem->pool));
+ switch(mem->pool) {
+ case 0:
+ return;
+ case 1:
+#ifdef VIA_HAVE_EXA
+ {
+ VIAPtr pVia = VIAPTR(mem->pScrn);
+ if (pVia->useEXA && !pVia->NoAccel) {
+ exaOffscreenFree(mem->pScrn->pScreen, mem->exa);
+ mem->linear = NULL;
+ mem->pool = 0;
+ return;
+ }
+ }
+#endif
+ xf86FreeOffscreenLinear(mem->linear);
+ mem->linear = NULL;
+ mem->pool = 0;
+ return;
+ case 2:
+#ifdef XF86DRI
+ if(drmCommandWrite(mem->drm_fd, DRM_VIA_FREEMEM,
+ &mem->drm, sizeof(drm_via_mem_t)) < 0)
+ ErrorF("DRM module failed free.\n");
+#endif
+ mem->pool = 0;
+ return;
+ }
+}
+
+int
+viaOffScreenLinear(VIAMemPtr mem, ScrnInfoPtr pScrn,
+ unsigned long size) {
+
+ int depth = pScrn->bitsPerPixel >> 3;
+
+#ifdef VIA_HAVE_EXA
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ if (pVia->useEXA && !pVia->NoAccel) {
+
+ mem->exa = exaOffscreenAlloc(pScrn->pScreen, size,
+ 32, TRUE, NULL,NULL);
+ if (mem->exa == NULL)
+ return BadAlloc;
+ mem->exa->save = viaExaFBSave;
+ mem->base = mem->exa->offset;
+ mem->pool = 1;
+ mem->pScrn = pScrn;
+ return Success;
+ }
+#endif
+
+ mem->linear = xf86AllocateOffscreenLinear(pScrn->pScreen,
+ ( size + depth - 1 ) / depth,
+ 32, NULL, NULL, NULL);
+ if(mem->linear == NULL)
+ return BadAlloc;
+ mem->base = mem->linear->offset * depth;
+ mem->pool = 1;
+ mem->pScrn = pScrn;
+ return Success;
+
+}
+
+int
+VIAAllocLinear(VIAMemPtr mem, ScrnInfoPtr pScrn, unsigned long size)
+{
+
+#ifdef XF86DRI
+ VIAPtr pVia = VIAPTR(pScrn);
+ int ret;
+
+ if(mem->pool)
+ ErrorF("VIA Double Alloc.\n");
+
+ if(pVia->directRenderingEnabled) {
+ mem->pScrn = pScrn;
+ mem->drm_fd = pVia->drmFD;
+ mem->drm.context = DRIGetContext(pScrn->pScreen);
+ mem->drm.size = size;
+ mem->drm.type = VIA_MEM_VIDEO;
+ ret = drmCommandWriteRead(mem->drm_fd, DRM_VIA_ALLOCMEM, &mem->drm,
+ sizeof(drm_via_mem_t));
+ if (ret || (size != mem->drm.size)) {
+
+ /*
+ * Try X Offsceen fallback before failing.
+ */
+
+ if (Success == viaOffScreenLinear(mem, pScrn, size))
+ return Success;
+ ErrorF("DRM memory allocation failed\n");
+ return BadAlloc;
+ }
+
+ mem->base = mem->drm.offset;
+ mem->pool = 2;
+ DEBUG(ErrorF("Fulfilled via DRI at %lu\n", mem->base));
+ return Success;
+ }
+#endif
+ {
+ if (Success == viaOffScreenLinear(mem, pScrn, size))
+ return Success;
+ ErrorF("Linear memory allocation failed\n");
+ return BadAlloc;
+ }
+ return Success;
+}
+
+void VIAInitLinear(ScreenPtr pScreen)
+{
+ 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;
+ if (size > 0) xf86InitFBManagerLinear(pScreen, offset, size);
+ }
+}
+
diff --git a/src/via_mode.c b/src/via_mode.c
new file mode 100644
index 000000000000..94f0dca97de3
--- /dev/null
+++ b/src/via_mode.c
@@ -0,0 +1,1997 @@
+/*
+ * 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.
+ */
+
+/*
+ * via_mode.c
+ *
+ * Everything to do with setting and changing modes.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "via.h"
+#include "via_driver.h"
+#include "via_vgahw.h"
+#include "via_id.h"
+
+/*
+ * Modetable nonsense.
+ *
+ */
+#include "via_mode.h"
+
+/*
+ *
+ * TV specific code.
+ *
+ */
+
+/*
+ *
+ */
+static Bool
+ViaTVDetect(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIATVDetect\n"));
+
+ /* preset some pBIOSInfo TV related values -- move up */
+ pBIOSInfo->TVEncoder = VIA_NONETV;
+ pBIOSInfo->TVI2CDev = NULL;
+ pBIOSInfo->TVSave = NULL;
+ pBIOSInfo->TVRestore = NULL;
+ pBIOSInfo->TVDACSense = NULL;
+ pBIOSInfo->TVModeValid = NULL;
+ pBIOSInfo->TVModeI2C = NULL;
+ pBIOSInfo->TVModeCrtc = NULL;
+ pBIOSInfo->TVPower = NULL;
+ pBIOSInfo->TVModes = NULL;
+ pBIOSInfo->TVPrintRegs = NULL;
+ pBIOSInfo->LCDPower = NULL;
+ pBIOSInfo->TVNumRegs = 0;
+
+ /*
+ * On an SK43G (KM400/Ch7011), false positive detections at a VT162x
+ * chip were observed, so try to detect the Ch7011 first.
+ */
+ if (pVia->pI2CBus2 && xf86I2CProbeAddress(pVia->pI2CBus2, 0xEC))
+ pBIOSInfo->TVI2CDev = ViaCH7xxxDetect(pScrn, pVia->pI2CBus2, 0xEC);
+ else if (pVia->pI2CBus2 && xf86I2CProbeAddress(pVia->pI2CBus2, 0x40))
+ pBIOSInfo->TVI2CDev = ViaVT162xDetect(pScrn, pVia->pI2CBus2, 0x40);
+ else if (pVia->pI2CBus3 && xf86I2CProbeAddress(pVia->pI2CBus3, 0x40))
+ pBIOSInfo->TVI2CDev = ViaVT162xDetect(pScrn, pVia->pI2CBus3, 0x40);
+ else if (pVia->pI2CBus2 && xf86I2CProbeAddress(pVia->pI2CBus2, 0xEA))
+ pBIOSInfo->TVI2CDev = ViaCH7xxxDetect(pScrn, pVia->pI2CBus2, 0xEA);
+ else if (pVia->pI2CBus3 && xf86I2CProbeAddress(pVia->pI2CBus3, 0xEA))
+ pBIOSInfo->TVI2CDev = ViaCH7xxxDetect(pScrn, pVia->pI2CBus3, 0xEA);
+
+ if (pBIOSInfo->TVI2CDev)
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ *
+ */
+static Bool
+ViaTVInit(ScrnInfoPtr pScrn)
+{
+ VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaTVInit\n"));
+
+ switch (pBIOSInfo->TVEncoder){
+ case VIA_VT1621:
+ case VIA_VT1622:
+ case VIA_VT1623:
+ case VIA_VT1625:
+ ViaVT162xInit(pScrn);
+ break;
+ case VIA_CH7011:
+ case VIA_CH7019A:
+ case VIA_CH7019B:
+ ViaCH7xxxInit(pScrn);
+ break;
+ default:
+ return FALSE;
+ break;
+ }
+
+ if (!pBIOSInfo->TVSave || !pBIOSInfo->TVRestore ||
+ !pBIOSInfo->TVDACSense || !pBIOSInfo->TVModeValid ||
+ !pBIOSInfo->TVModeI2C || !pBIOSInfo->TVModeCrtc ||
+ !pBIOSInfo->TVPower || !pBIOSInfo->TVModes ||
+ !pBIOSInfo->TVPrintRegs) {
+
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaTVInit: TVEncoder was not "
+ "properly initialised.");
+
+ xf86DestroyI2CDevRec(pBIOSInfo->TVI2CDev, TRUE);
+ pBIOSInfo->TVI2CDev = NULL;
+ pBIOSInfo->TVOutput = TVOUTPUT_NONE;
+ pBIOSInfo->TVEncoder = VIA_NONETV;
+ pBIOSInfo->TVI2CDev = NULL;
+ pBIOSInfo->TVSave = NULL;
+ pBIOSInfo->TVRestore = NULL;
+ pBIOSInfo->TVDACSense = NULL;
+ pBIOSInfo->TVModeValid = NULL;
+ pBIOSInfo->TVModeI2C = NULL;
+ pBIOSInfo->TVModeCrtc = NULL;
+ pBIOSInfo->TVPower = NULL;
+ pBIOSInfo->TVModes = NULL;
+ pBIOSInfo->TVPrintRegs = NULL;
+ pBIOSInfo->TVNumRegs = 0;
+
+ return FALSE;
+ }
+
+ /* Save now */
+ pBIOSInfo->TVSave(pScrn);
+
+#ifdef HAVE_DEBUG
+ if (VIAPTR(pScrn)->PrintTVRegs)
+ pBIOSInfo->TVPrintRegs(pScrn);
+#endif
+
+ return TRUE;
+}
+
+void
+ViaTVSave(ScrnInfoPtr pScrn)
+{
+ VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo;
+
+ if (pBIOSInfo->TVSave)
+ pBIOSInfo->TVSave(pScrn);
+}
+
+void
+ViaTVRestore(ScrnInfoPtr pScrn)
+{
+ VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo;
+ if (pBIOSInfo->TVRestore)
+ pBIOSInfo->TVRestore(pScrn);
+}
+
+static Bool
+ViaTVDACSense(ScrnInfoPtr pScrn)
+{
+ VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo;
+
+ if (pBIOSInfo->TVDACSense)
+ return pBIOSInfo->TVDACSense(pScrn);
+ return FALSE;
+}
+
+static void
+ViaTVSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo;
+
+ if (pBIOSInfo->TVModeI2C)
+ pBIOSInfo->TVModeI2C(pScrn, mode);
+
+ if (pBIOSInfo->TVModeCrtc)
+ pBIOSInfo->TVModeCrtc(pScrn, mode);
+}
+
+void
+ViaTVPower(ScrnInfoPtr pScrn, Bool On)
+{
+ VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo;
+
+#ifdef HAVE_DEBUG
+ if (On)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaTVPower: On.\n");
+ else
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaTVPower: Off.\n");
+#endif
+
+ if (pBIOSInfo->TVPower)
+ pBIOSInfo->TVPower(pScrn, On);
+}
+
+#ifdef HAVE_DEBUG
+void
+ViaTVPrintRegs(ScrnInfoPtr pScrn)
+{
+ VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo;
+
+ if (pBIOSInfo->TVPrintRegs)
+ pBIOSInfo->TVPrintRegs(pScrn);
+}
+#endif /* HAVE_DEBUG */
+
+/*
+ *
+ */
+static ModeStatus
+ViaTVModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo;
+
+ if (pBIOSInfo->TVModeValid)
+ return pBIOSInfo->TVModeValid(pScrn, mode);
+ return MODE_OK;
+}
+
+/*
+ *
+ */
+void
+ViaOutputsDetect(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaOutputsDetect\n"));
+
+ pBIOSInfo->CrtPresent = FALSE;
+ pBIOSInfo->PanelPresent = FALSE;
+
+ /* Panel */
+ if (pBIOSInfo->ForcePanel) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling panel from config.\n");
+ pBIOSInfo->PanelPresent = TRUE;
+ } else if (pVia->Id && (pVia->Id->Outputs & VIA_DEVICE_LCD)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling panel from"
+ " PCI-Subsystem Id information.\n");
+ pBIOSInfo->PanelPresent = TRUE;
+ }
+
+ /* Crt */
+ if (pVia->DDC1)
+ pBIOSInfo->CrtPresent = TRUE;
+ /* If any of the unichromes support this, add CRT detection here */
+ else if (!pBIOSInfo->PanelPresent) {
+ /* Make sure that at least CRT is enabled. */
+ if (!pVia->Id || (pVia->Id->Outputs & VIA_DEVICE_CRT))
+ pBIOSInfo->CrtPresent = TRUE;
+ }
+
+ /* TV encoder */
+ if (ViaTVDetect(pScrn) && ViaTVInit(pScrn)) {
+ if (!pBIOSInfo->TVOutput) /* Config might've set this already */
+ ViaTVDACSense(pScrn);
+ } else if (pVia->Id && (pVia->Id->Outputs & VIA_DEVICE_TV)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "This device is supposed to have a"
+ " TV encoder but we are unable to detect it (support missing?).\n");
+ pBIOSInfo->TVOutput = 0;
+ }
+}
+
+#ifdef HAVE_DEBUG
+/*
+ * Returns:
+ * Bit[7] 2nd Path
+ * Bit[6] 1/0 MHS Enable/Disable
+ * Bit[5] 0 = Bypass Callback, 1 = Enable Callback
+ * Bit[4] 0 = Hot-Key Sequence Control (OEM Specific)
+ * Bit[3] LCD
+ * Bit[2] TV
+ * Bit[1] CRT
+ * Bit[0] DVI
+ */
+static CARD8
+VIAGetActiveDisplay(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CARD8 tmp;
+
+ tmp = (hwp->readCrtc(hwp, 0x3E) >> 4);
+ tmp |= ((hwp->readCrtc(hwp, 0x3B) & 0x18) << 3);
+
+ return tmp;
+}
+#endif /* HAVE_DEBUG */
+
+/*
+ *
+ */
+Bool
+ViaOutputsSelect(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+
+ if (pVia->IsSecondary) { /* we just abort for now */
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaOutputsSelect:"
+ " Not handling secondary.\n");
+ return FALSE;
+ }
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaOutputsSelect\n"));
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaOutputsSelect: X"
+ " Configuration: 0x%02x\n", pVia->ActiveDevice));
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaOutputsSelect: BIOS"
+ " Initialised register: 0x%02x\n",
+ VIAGetActiveDisplay(pScrn)));
+
+ pBIOSInfo->PanelActive = FALSE;
+ pBIOSInfo->CrtActive = FALSE;
+ pBIOSInfo->TVActive = FALSE;
+
+ if (!pVia->ActiveDevice) {
+ /* always enable the panel when present */
+ if (pBIOSInfo->PanelPresent)
+ pBIOSInfo->PanelActive = 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;
+ } else {
+ if (pVia->ActiveDevice & VIA_DEVICE_LCD) {
+ if (pBIOSInfo->PanelPresent)
+ pBIOSInfo->PanelActive = TRUE;
+ else
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unable to activate"
+ " panel: no panel is present.\n");
+ }
+
+ if (pVia->ActiveDevice & VIA_DEVICE_TV) {
+ if (!pBIOSInfo->TVI2CDev)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unable to activate"
+ " TV encoder: no TV encoder present.\n");
+ else if (pBIOSInfo->TVOutput == TVOUTPUT_NONE)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unable to activate"
+ " TV encoder: no cable attached.\n");
+ else if (pBIOSInfo->PanelActive)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unable to activate"
+ " TV encoder and panel simultaneously. Not using"
+ " TV encoder.\n");
+ else
+ pBIOSInfo->TVActive = TRUE;
+ }
+
+ if ((pVia->ActiveDevice & VIA_DEVICE_CRT) ||
+ (!pBIOSInfo->PanelActive && !pBIOSInfo->TVActive)) {
+ pBIOSInfo->CrtPresent = TRUE;
+ pBIOSInfo->CrtActive = TRUE;
+ }
+ }
+
+#ifdef HAVE_DEBUG
+ if (pBIOSInfo->CrtActive)
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaOutputsSelect: CRT.\n"));
+ if (pBIOSInfo->PanelActive)
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaOutputsSelect: Panel.\n"));
+ if (pBIOSInfo->TVActive)
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaOutputsSelect: TV.\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"
+ "1280x1024", "1400x1050", "1600x1200"};
+ int size = 0;
+ Bool ret;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAGetPanelSize\n"));
+
+ ret = VIAGetPanelSizeFromDDCv1(pScrn, &size);
+ if (!ret)
+ ret = VIAGetPanelSizeFromDDCv2(pScrn, &size);
+
+ if (ret) {
+ switch (size) {
+ case 640:
+ pBIOSInfo->PanelSize = VIA_PANEL6X4;
+ break;
+ case 800:
+ pBIOSInfo->PanelSize = VIA_PANEL8X6;
+ break;
+ case 1024:
+ pBIOSInfo->PanelSize = VIA_PANEL10X7;
+ break;
+ case 1280:
+ pBIOSInfo->PanelSize = VIA_PANEL12X10;
+ break;
+ case 1400:
+ pBIOSInfo->PanelSize = VIA_PANEL14X10;
+ break;
+ case 1600:
+ pBIOSInfo->PanelSize = VIA_PANEL16X12;
+ break;
+ default:
+ pBIOSInfo->PanelSize = VIA_PANEL_INVALID;
+ break;
+ }
+ } else {
+ pBIOSInfo->PanelSize = hwp->readCrtc(hwp, 0x3F) >> 4;
+ if (pBIOSInfo->PanelSize == 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;
+ return;
+ }
+ }
+
+ if (pBIOSInfo->PanelSize < 7)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using panel at %s.\n",
+ PanelSizeString[pBIOSInfo->PanelSize]);
+ else
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unknown panel size "
+ "detected: %d.\n", pBIOSInfo->PanelSize);
+}
+
+/*
+ *
+ */
+static Bool
+ViaGetResolutionIndex(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo;
+ int i;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaGetResolutionIndex\n"));
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaGetResolutionIndex: Looking"
+ " for %dx%d\n", mode->CrtcHDisplay, mode->CrtcVDisplay));
+ for (i = 0; ViaResolutionTable[i].Index != VIA_RES_INVALID; i++) {
+ if ((ViaResolutionTable[i].X == mode->CrtcHDisplay) &&
+ (ViaResolutionTable[i].Y == mode->CrtcVDisplay)){
+ pBIOSInfo->ResolutionIndex = ViaResolutionTable[i].Index;
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaGetResolutionIndex:"
+ " %d\n", pBIOSInfo->ResolutionIndex));
+ return TRUE;
+ }
+ }
+
+ pBIOSInfo->ResolutionIndex = VIA_RES_INVALID;
+ return FALSE;
+}
+
+/*
+ *
+ */
+static int
+ViaGetVesaMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ int i;
+
+ for (i = 0; ViaVesaModes[i].Width; i++)
+ if ((ViaVesaModes[i].Width == mode->CrtcHDisplay) &&
+ (ViaVesaModes[i].Height == mode->CrtcVDisplay)) {
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ return ViaVesaModes[i].mode_8b;
+ case 16:
+ return ViaVesaModes[i].mode_16b;
+ case 24:
+ case 32:
+ return ViaVesaModes[i].mode_32b;
+ default:
+ return 0xFFFF;
+ }
+ }
+ return 0xFFFF;
+}
+
+/*
+ *
+ * ViaResolutionTable[i].PanelIndex is pBIOSInfo->PanelSize
+ * pBIOSInfo->PanelIndex is the index to lcdTable.
+ *
+ */
+static Bool
+ViaPanelGetIndex(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo;
+ int i;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaPanelGetIndex\n"));
+
+ pBIOSInfo->PanelIndex = VIA_BIOS_NUM_PANEL;
+
+ if (pBIOSInfo->PanelSize == VIA_PANEL_INVALID) {
+ VIAGetPanelSize(pScrn);
+ if (pBIOSInfo->PanelSize == VIA_PANEL_INVALID) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaPanelGetIndex:"
+ " PanelSize not set.\n");
+ return FALSE;
+ }
+ }
+
+ if ((mode->PrivSize != sizeof(struct ViaModePriv)) ||
+ (mode->Private != (void *)&ViaPanelPrivate)){
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaPanelGetIndex:"
+ " Mode not supported by Panel.\n");
+ return FALSE;
+ }
+
+ if (!ViaGetResolutionIndex(pScrn, mode)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel does not support this"
+ " resolution: %s\n", mode->name);
+ return FALSE;
+ }
+
+ for (i = 0; ViaResolutionTable[i].Index != VIA_RES_INVALID; i++)
+ if (ViaResolutionTable[i].PanelIndex == pBIOSInfo->PanelSize) {
+ 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"
+ " to find matching PanelSize in ViaResolutionTable.\n");
+ return FALSE;
+ }
+
+ if ((pBIOSInfo->panelX != mode->CrtcHDisplay) ||
+ (pBIOSInfo->panelY != mode->CrtcVDisplay)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaPanelGetIndex: Non-native"
+ "resolutions are broken.\n");
+ return FALSE;
+ }
+
+ for (i = 0; i < VIA_BIOS_NUM_PANEL; i++)
+ if (lcdTable[i].fpSize == pBIOSInfo->PanelSize) {
+ int modeNum, tmp;
+
+ modeNum = ViaGetVesaMode(pScrn, mode);
+ if (modeNum == 0xFFFF) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaPanelGetIndex: "
+ "Unable to determine matching VESA modenumber.\n");
+ return FALSE;
+ }
+
+ tmp = 0x01 << (modeNum & 0xF);
+ if ((CARD16)(tmp) & lcdTable[i].SuptMode[(modeNum >> 4)]) {
+ pBIOSInfo->PanelIndex = i;
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaPanelGetIndex:"
+ "index: %d (%dx%d)\n", pBIOSInfo->PanelIndex,
+ pBIOSInfo->panelX, pBIOSInfo->panelY));
+ return TRUE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaPanelGetIndex: Unable"
+ " 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");
+ return FALSE;
+}
+
+/*
+ * Stolen from xf86Config.c's addDefaultModes
+ */
+static void
+ViaModesAttachHelper(ScrnInfoPtr pScrn, MonPtr monitorp, DisplayModePtr Modes)
+{
+ DisplayModePtr mode;
+ DisplayModePtr last = monitorp->Last;
+ int i;
+
+ for (i = 0; Modes[i].name; i++) {
+ mode = xnfalloc(sizeof(DisplayModeRec));
+ memcpy(mode, &Modes[i], sizeof(DisplayModeRec));
+ mode->name = xnfstrdup(Modes[i].name);
+ if (last) {
+ mode->prev = last;
+ last->next = mode;
+ } else { /* this is the first mode */
+ monitorp->Modes = mode;
+ mode->prev = NULL;
+ }
+ last = mode;
+ }
+ monitorp->Last = last;
+}
+
+/*
+ *
+ */
+void
+ViaModesAttach(ScrnInfoPtr pScrn, MonPtr monitorp)
+{
+ VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModesAttach\n"));
+
+ if (pBIOSInfo->PanelActive)
+ ViaModesAttachHelper(pScrn, monitorp, ViaPanelModes);
+ if (pBIOSInfo->TVActive && pBIOSInfo->TVModes)
+ ViaModesAttachHelper(pScrn, monitorp, pBIOSInfo->TVModes);
+}
+
+/*
+ *
+ */
+CARD32
+ViaGetMemoryBandwidth(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaGetMemoryBandwidth\n"));
+
+ switch (pVia->Chipset) {
+ case VIA_CLE266:
+ if (CLE266_REV_IS_AX(pVia->ChipRev))
+ return ViaBandwidthTable[VIA_BW_CLE266A].Bandwidth[pVia->MemClk];
+ else
+ return ViaBandwidthTable[VIA_BW_CLE266C].Bandwidth[pVia->MemClk];
+ case VIA_KM400:
+ /* 0x84 is earliest public device, 0x80 is more likely though */
+ if (pVia->ChipRev < 0x84)
+ return ViaBandwidthTable[VIA_BW_KM400].Bandwidth[pVia->MemClk];
+ else
+ return ViaBandwidthTable[VIA_BW_KM400A].Bandwidth[pVia->MemClk];
+ case VIA_K8M800:
+ return ViaBandwidthTable[VIA_BW_K8M800].Bandwidth[pVia->MemClk];
+ case VIA_PM800:
+ return ViaBandwidthTable[VIA_BW_PM800].Bandwidth[pVia->MemClk];
+ case VIA_VM800:
+ return ViaBandwidthTable[VIA_BW_VM800].Bandwidth[pVia->MemClk];
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaBandwidthAllowed: Unknown Chipset.\n");
+ return VIA_BW_MIN;
+ }
+}
+
+/*
+ * 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"));
+
+ 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)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ VIAPtr pVia = VIAPTR(pScrn);
+ VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+ ModeStatus ret;
+ CARD32 temp;
+
+ if (pVia->pVbe)
+ return MODE_OK;
+
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "ViaValidMode: Validating %s (%d)\n",
+ mode->name, mode->Clock));
+
+ if (mode->Flags & V_INTERLACE)
+ return MODE_NO_INTERLACE;
+
+ if (pVia->IsSecondary)
+ ret = ViaModeSecondaryVGAValid(pScrn, mode);
+ else
+ ret = ViaModePrimaryVGAValid(pScrn, mode);
+
+ if (ret != MODE_OK)
+ return ret;
+
+ if (pBIOSInfo->TVActive) {
+ ret = ViaTVModeValid(pScrn, mode);
+ if (ret != MODE_OK) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Mode \"%s\" not supported by"
+ " TV encoder.\n", mode->name);
+ return ret;
+ }
+ } else if (pBIOSInfo->PanelActive && !ViaPanelGetIndex(pScrn, mode))
+ return MODE_BAD;
+ else if (!ViaModeDotClockTranslate(pScrn, mode))
+ return MODE_NOCLOCK;
+
+ temp = mode->CrtcHDisplay * mode->CrtcVDisplay * mode->VRefresh *
+ (pScrn->bitsPerPixel >> 3);
+ if (pBIOSInfo->Bandwidth < temp) {
+ xf86DrvMsg(scrnIndex, X_INFO, "Required bandwidth is not available. (%u > %u)\n",
+ (unsigned) temp, (unsigned) pBIOSInfo->Bandwidth);
+ return MODE_CLOCK_HIGH; /* since there is no MODE_BANDWIDTH */
+ }
+
+ return MODE_OK;
+}
+
+/*
+ *
+ * Some very common abstractions.
+ *
+ */
+
+/*
+ * Standard vga call really.
+ * Needs to be called to reset the dotclock (after SR40:2/1 reset)
+ */
+static void
+ViaSetUseExternalClock(vgaHWPtr hwp)
+{
+ CARD8 data;
+
+ DEBUG(xf86DrvMsg(hwp->pScrn->scrnIndex, X_INFO, "ViaSetUseExternalClock\n"));
+
+ data = hwp->readMiscOut(hwp);
+ hwp->writeMiscOut(hwp, data | 0x0C);
+}
+
+/*
+ *
+ */
+static void
+ViaSetPrimaryDotclock(ScrnInfoPtr pScrn, CARD32 clock)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(hwp->pScrn->scrnIndex, X_INFO, "ViaSetPrimaryDotclock to 0x%06x\n",
+ (unsigned) clock));
+
+ if ((pVia->Chipset == VIA_CLE266) || (pVia->Chipset == VIA_KM400)) {
+ hwp->writeSeq(hwp, 0x46, clock >> 8);
+ hwp->writeSeq(hwp, 0x47, clock & 0xFF);
+ } else { /* unichrome pro */
+ hwp->writeSeq(hwp, 0x44, clock >> 16);
+ hwp->writeSeq(hwp, 0x45, (clock >> 8) & 0xFF);
+ hwp->writeSeq(hwp, 0x46, clock & 0xFF);
+ }
+
+ ViaSeqMask(hwp, 0x40, 0x02, 0x02);
+ ViaSeqMask(hwp, 0x40, 0x00, 0x02);
+}
+
+/*
+ *
+ */
+static void
+ViaSetSecondaryDotclock(ScrnInfoPtr pScrn, CARD32 clock)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(hwp->pScrn->scrnIndex, X_INFO, "ViaSetSecondaryDotclock to 0x%06x\n",
+ (unsigned) clock));
+
+ if ((pVia->Chipset == VIA_CLE266) || (pVia->Chipset == VIA_KM400)) {
+ hwp->writeSeq(hwp, 0x44, clock >> 8);
+ hwp->writeSeq(hwp, 0x45, clock & 0xFF);
+ } else { /* unichrome pro */
+ hwp->writeSeq(hwp, 0x4A, clock >> 16);
+ hwp->writeSeq(hwp, 0x4B, (clock >> 8) & 0xFF);
+ hwp->writeSeq(hwp, 0x4C, clock & 0xFF);
+ }
+
+ ViaSeqMask(hwp, 0x40, 0x04, 0x04);
+ ViaSeqMask(hwp, 0x40, 0x00, 0x04);
+}
+
+/*
+ * Broken, only does native mode decently. I (Luc) personally broke this.
+ */
+static void
+VIASetLCDMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ VIAPtr pVia = VIAPTR(pScrn);
+ VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+ VIALCDModeTableRec Table = lcdTable[pBIOSInfo->PanelIndex];
+ CARD8 modeNum = 0;
+ int resIdx;
+ int port, offset, data;
+ int i, j, misc;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIASetLCDMode\n"));
+
+ if (pBIOSInfo->PanelSize == VIA_PANEL12X10)
+ hwp->writeCrtc(hwp, 0x89, 0x07);
+
+ /* LCD Expand Mode Y Scale Flag */
+ pBIOSInfo->scaleY = FALSE;
+
+ /* Set LCD InitTb Regs */
+ if (pBIOSInfo->BusWidth == VIA_DI_12BIT) {
+ if (pVia->IsSecondary)
+ pBIOSInfo->Clock = Table.InitTb.LCDClk_12Bit;
+ else {
+ pBIOSInfo->Clock = Table.InitTb.VClk_12Bit;
+ /* for some reason still to be defined this is neccessary */
+ ViaSetSecondaryDotclock(pScrn, Table.InitTb.LCDClk_12Bit);
+ }
+ } else {
+ if (pVia->IsSecondary)
+ pBIOSInfo->Clock = Table.InitTb.LCDClk;
+ else {
+ pBIOSInfo->Clock = Table.InitTb.VClk;
+ ViaSetSecondaryDotclock(pScrn, Table.InitTb.LCDClk);
+ }
+
+ }
+
+ ViaSetUseExternalClock(hwp);
+
+ for (i = 0; i < Table.InitTb.numEntry; i++) {
+ port = Table.InitTb.port[i];
+ offset = Table.InitTb.offset[i];
+ data = Table.InitTb.data[i];
+ ViaVgahwWrite(hwp, 0x300+port, offset, 0x301+port, data);
+ }
+
+ if ((mode->CrtcHDisplay != pBIOSInfo->panelX) ||
+ (mode->CrtcVDisplay != pBIOSInfo->panelY)) {
+ VIALCDModeEntryPtr Main;
+ VIALCDMPatchEntryPtr Patch1, Patch2;
+ int numPatch1, numPatch2;
+
+ resIdx = VIA_RES_INVALID;
+
+ /* Find MxxxCtr & MxxxExp Index and
+ * HWCursor Y Scale (PanelSize Y / Res. Y) */
+ pBIOSInfo->resY = mode->CrtcVDisplay;
+ switch (pBIOSInfo->ResolutionIndex) {
+ case VIA_RES_640X480:
+ resIdx = 0;
+ break;
+ case VIA_RES_800X600:
+ resIdx = 1;
+ break;
+ case VIA_RES_1024X768:
+ resIdx = 2;
+ break;
+ case VIA_RES_1152X864:
+ resIdx = 3;
+ break;
+ case VIA_RES_1280X768:
+ case VIA_RES_1280X960:
+ case VIA_RES_1280X1024:
+ if (pBIOSInfo->PanelSize == VIA_PANEL12X10)
+ resIdx = VIA_RES_INVALID;
+ else
+ resIdx = 4;
+ break;
+ default:
+ resIdx = VIA_RES_INVALID;
+ break;
+ }
+
+ if ((mode->CrtcHDisplay == 640) &&
+ (mode->CrtcVDisplay == 400))
+ resIdx = 0;
+
+ if (resIdx == VIA_RES_INVALID) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "VIASetLCDMode: Failed "
+ "to find a suitable Panel Size index.\n");
+ return;
+ }
+
+ if (pBIOSInfo->Center) {
+ Main = &(Table.MCtr[resIdx]);
+ Patch1 = Table.MPatchDP1Ctr;
+ numPatch1 = Table.numMPatchDP1Ctr;
+ Patch2 = Table.MPatchDP2Ctr;
+ numPatch2 = Table.numMPatchDP2Ctr;
+ } else { /* expand! */
+ /* LCD Expand Mode Y Scale Flag */
+ pBIOSInfo->scaleY = TRUE;
+ Main = &(Table.MExp[resIdx]);
+ Patch1 = Table.MPatchDP1Exp;
+ numPatch1 = Table.numMPatchDP1Exp;
+ Patch2 = Table.MPatchDP2Exp;
+ numPatch2 = Table.numMPatchDP2Exp;
+ }
+
+ /* Set Main LCD Registers */
+ for (i = 0; i < Main->numEntry; i++){
+ ViaVgahwWrite(hwp, 0x300 + Main->port[i], Main->offset[i],
+ 0x301 + Main->port[i], Main->data[i]);
+ }
+
+ if (pBIOSInfo->BusWidth == VIA_DI_12BIT) {
+ if (pVia->IsSecondary)
+ pBIOSInfo->Clock = Main->LCDClk_12Bit;
+ else
+ pBIOSInfo->Clock = Main->VClk_12Bit;
+ } else {
+ if (pVia->IsSecondary)
+ pBIOSInfo->Clock = Main->LCDClk;
+ else
+ pBIOSInfo->Clock = Main->VClk;
+ }
+
+ j = ViaGetVesaMode(pScrn, mode);
+ if (j == 0xFFFF) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "VIASetLCDMode: "
+ "Unable to determine matching VESA modenumber.\n");
+ return;
+ }
+ for (i = 0; i < modeFix.numEntry; i++) {
+ if (modeFix.reqMode[i] == j) {
+ modeNum = modeFix.fixMode[i];
+ break;
+ }
+ }
+
+ /* Set LCD Mode patch registers. */
+ for (i = 0; i < numPatch2; i++, Patch2++) {
+ if (Patch2->Mode == modeNum) {
+ if (!pBIOSInfo->Center && (mode->CrtcHDisplay == pBIOSInfo->panelX))
+ pBIOSInfo->scaleY = FALSE;
+
+ for (j = 0; j < Patch2->numEntry; j++){
+ ViaVgahwWrite(hwp, 0x300 + Patch2->port[j], Patch2->offset[j],
+ 0x301 + Patch2->port[j], Patch2->data[j]);
+ }
+
+ if (pBIOSInfo->BusWidth == VIA_DI_12BIT) {
+ if (pVia->IsSecondary)
+ pBIOSInfo->Clock = Patch2->LCDClk_12Bit;
+ else
+ pBIOSInfo->Clock = Patch2->VClk_12Bit;
+ } else {
+ if (pVia->IsSecondary)
+ pBIOSInfo->Clock = Patch2->LCDClk;
+ else
+ pBIOSInfo->Clock = Patch2->VClk;
+ }
+ break;
+ }
+ }
+
+
+ /* Set LCD Secondary Mode Patch registers. */
+ if (pVia->IsSecondary) {
+ for (i = 0; i < numPatch1; i++, Patch1++) {
+ if (Patch1->Mode == modeNum) {
+ for (j = 0; j < Patch1->numEntry; j++) {
+ ViaVgahwWrite(hwp, 0x300 + Patch1->port[j], Patch1->offset[j],
+ 0x301 + Patch1->port[j], Patch1->data[j]);
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ /* LCD patch 3D5.02 */
+ misc = hwp->readCrtc(hwp, 0x01);
+ hwp->writeCrtc(hwp, 0x02, misc);
+
+ /* Enable LCD */
+ if (!pVia->IsSecondary) {
+ /* CRT Display Source Bit 6 - 0: CRT, 1: LCD */
+ ViaSeqMask(hwp, 0x16, 0x40, 0x40);
+
+ /* Enable Simultaneous */
+ if (pBIOSInfo->BusWidth == VIA_DI_12BIT) {
+ hwp->writeCrtc(hwp, 0x6B, 0xA8);
+
+ if ((pVia->Chipset == VIA_CLE266) &&
+ CLE266_REV_IS_AX(pVia->ChipRev))
+ hwp->writeCrtc(hwp, 0x93, 0xB1);
+ else
+ hwp->writeCrtc(hwp, 0x93, 0xAF);
+ } else {
+ ViaCrtcMask(hwp, 0x6B, 0x08, 0x08);
+ hwp->writeCrtc(hwp, 0x93, 0x00);
+ }
+ hwp->writeCrtc(hwp, 0x6A, 0x48);
+ } else {
+ /* CRT Display Source Bit 6 - 0: CRT, 1: LCD */
+ ViaSeqMask(hwp, 0x16, 0x00, 0x40);
+
+ /* Enable SAMM */
+ if (pBIOSInfo->BusWidth == VIA_DI_12BIT) {
+ ViaCrtcMask(hwp, 0x6B, 0x20, 0x20);
+ if ((pVia->Chipset == VIA_CLE266) &&
+ CLE266_REV_IS_AX(pVia->ChipRev))
+ hwp->writeCrtc(hwp, 0x93, 0xB1);
+ else
+ hwp->writeCrtc(hwp, 0x93, 0xAF);
+ } else {
+ hwp->writeCrtc(hwp, 0x6B, 0x00);
+ hwp->writeCrtc(hwp, 0x93, 0x00);
+ }
+ hwp->writeCrtc(hwp, 0x6A, 0xC8);
+ }
+}
+
+/*
+ *
+ */
+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) /* FIX ME */
+ 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) /* FIX ME */
+ 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) /* FIX ME */
+ 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) /* FIX ME */
+ 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)
+{
+ double fvco, fout, fref, err, minErr;
+ CARD32 dr,dn,dm,maxdm,maxdn;
+ CARD32 factual,best;
+
+ fref = 14.31818e6;
+ fout = (double) clock * 1.e3;
+ factual = ~0;
+ maxdm=127;
+ maxdn = 7;
+ minErr = 1e10;
+ best = 0;
+
+ for (dr = 0; dr<4; ++dr )
+ {
+ for (dn = (dr==0)?2:1; dn<=maxdn; ++dn)
+ {
+ for (dm = 1; dm<=maxdm; ++dm)
+ {
+ factual = fref * dm;
+ factual /= (dn << dr);
+ err = fabs((double)factual/fout-1.);
+ if (err<minErr)
+ {
+ minErr = err;
+ best = (dm & 127) | ((dn & 31)<<8) | (dr << 14);
+ }
+ }
+ }
+ }
+ return best;
+}
+
+static CARD32
+ViaComputeProDotClock(unsigned clock)
+{
+ double fvco, fout, fref, err, minErr;
+ CARD32 dr = 0, dn, dm, maxdm, maxdn;
+ CARD32 factual, bestClock;
+
+ fref = 14.318e6;
+ fout = (double) clock * 1.e3;
+ factual = ~0;
+ maxdm = factual / 14318000U - 2;
+ minErr = 1.e10;
+ bestClock = 0U;
+
+ do {
+ fvco = fout * (1 << dr);
+ } while( fvco < 300.e6 && dr++ < 8);
+
+ if (dr == 8) {
+ return 0;
+ }
+
+ if (clock < 30000)
+ maxdn = 6;
+ else if (clock < 45000)
+ maxdn = 5;
+ else if (clock < 170000)
+ maxdn = 4;
+ else
+ maxdn = 3;
+
+
+ for (dn = 0; dn < maxdn; ++dn) {
+ for (dm = 0; dm < maxdm; ++dm) {
+ factual = 14318000U * (dm + 2);
+ factual /= (dn + 2) << dr;
+ if ((err = fabs((double) factual / fout - 1.)) < 0.005) {
+ if (err < minErr) {
+ minErr = err;
+ bestClock = ((dm & 0xff) << 16) |
+ ( ((1 << 7) | (dr << 2) | ((dm & 0x300) >> 8)) << 8) |
+ ( dn & 0x7f);
+ }
+ }
+ }
+ }
+
+ return bestClock;
+}
+
+/*
+ *
+ */
+static CARD32
+ViaModeDotClockTranslate(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ int i;
+
+ if ((pVia->Chipset == VIA_CLE266) || (pVia->Chipset == VIA_KM400)) {
+ CARD32 best1=0, best2;
+ for (i = 0; ViaDotClocks[i].DotClock; i++)
+ if (ViaDotClocks[i].DotClock == mode->Clock) {
+ best1 = ViaDotClocks[i].UniChrome;
+ break;
+ }
+
+ best2 = ViaComputeDotClock(mode->Clock);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaComputeDotClock %d : %04x : %04x\n",mode->Clock, best1,best2));
+ return best2;
+ } else {
+ for (i = 0; ViaDotClocks[i].DotClock; i++)
+ if (ViaDotClocks[i].DotClock == mode->Clock)
+ return ViaDotClocks[i].UniChromePro;
+ return ViaComputeProDotClock(mode->Clock);
+ }
+
+ return 0;
+}
+
+/*
+ *
+ */
+void
+ViaModePrimary(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ VIAPtr pVia = VIAPTR(pScrn);
+ VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModePrimary\n"));
+
+ /* Turn off Screen */
+ ViaCrtcMask(hwp, 0x17, 0x00, 0x80);
+
+ /* Clean Second Path Status */
+ hwp->writeCrtc(hwp, 0x6A, 0x00);
+ hwp->writeCrtc(hwp, 0x6B, 0x00);
+ hwp->writeCrtc(hwp, 0x6C, 0x00);
+ hwp->writeCrtc(hwp, 0x93, 0x00);
+
+ ViaModePrimaryVGA(pScrn, mode);
+ pBIOSInfo->Clock = ViaModeDotClockTranslate(pScrn, mode);
+ pBIOSInfo->ClockExternal = FALSE;
+
+ /* Enable MMIO & PCI burst (1 wait state) */
+ ViaSeqMask(hwp, 0x1A, 0x06, 0x06);
+
+ if (!pBIOSInfo->CrtActive)
+ ViaCrtcMask(hwp, 0x36, 0x30, 0x30);
+ else
+ ViaSeqMask(hwp, 0x16, 0x00, 0x40);
+
+ if (pBIOSInfo->PanelActive && ViaPanelGetIndex(pScrn, mode)) {
+ VIASetLCDMode(pScrn, mode);
+ ViaLCDPower(pScrn, TRUE);
+ } else if (pBIOSInfo->PanelPresent)
+ ViaLCDPower(pScrn, FALSE);
+
+ if (pBIOSInfo->TVActive) {
+ /* Quick 'n dirty workaround for non-primary case until TVCrtcMode
+ is removed -- copy from clock handling code below */
+ if ((pVia->Chipset == VIA_CLE266) && CLE266_REV_IS_AX(pVia->ChipRev))
+ ViaSetPrimaryDotclock(pScrn, 0x471C); /* CLE266Ax use 2x XCLK */
+ else if ((pVia->Chipset == VIA_K8M800) || (pVia->Chipset == VIA_PM800) || (pVia->Chipset == VIA_VM800))
+ ViaSetPrimaryDotclock(pScrn, 0x529001);
+ else
+ ViaSetPrimaryDotclock(pScrn, 0x871C);
+ ViaSetUseExternalClock(hwp);
+
+ ViaTVSetMode(pScrn, mode);
+ } else
+ ViaTVPower(pScrn, FALSE);
+
+ ViaSetPrimaryFIFO(pScrn, mode);
+
+ if (pBIOSInfo->ClockExternal) {
+ if ((pVia->Chipset == VIA_CLE266) && CLE266_REV_IS_AX(pVia->ChipRev))
+ ViaSetPrimaryDotclock(pScrn, 0x471C); /* CLE266Ax use 2x XCLK */
+ else if ((pVia->Chipset == VIA_K8M800) || (pVia->Chipset == VIA_PM800) ||(pVia->Chipset == VIA_VM800))
+ ViaSetPrimaryDotclock(pScrn, 0x529001);
+ else
+ ViaSetPrimaryDotclock(pScrn, 0x871C);
+ if ((pVia->Chipset != VIA_K8M800) && (pVia->Chipset != VIA_PM800) && (pVia->Chipset != VIA_VM800))
+ ViaCrtcMask(hwp, 0x6B, 0x01, 0x01);
+ } else {
+ ViaSetPrimaryDotclock(pScrn, pBIOSInfo->Clock);
+ ViaSetUseExternalClock(hwp);
+ ViaCrtcMask(hwp, 0x6B, 0x00, 0x01);
+ }
+
+ /* Enable CRT Controller (3D5.17 Hardware Reset) */
+ ViaCrtcMask(hwp, 0x17, 0x80, 0x80);
+
+ hwp->disablePalette(hwp);
+}
+
+/*
+ *
+ */
+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) /* FIX ME */
+ 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) /* FIX ME */
+ 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) /* FIX ME */
+ 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) /* FIX ME */
+ 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);
+
+ /* 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);
+
+ /* 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->writeCrtc(hwp, 0x65, (temp >> 1) & 0xFF);
+ ViaCrtcMask(hwp, 0x67, temp >> 7, 0x0C);
+}
+
+/*
+ *
+ */
+void
+ViaModeSecondary(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ VIAPtr pVia = VIAPTR(pScrn);
+ VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModeSecondary\n"));
+
+ /* Turn off Screen */
+ ViaCrtcMask(hwp, 0x17, 0x00, 0x80);
+
+ ViaModeSecondaryVGA(pScrn, mode);
+
+ if (pBIOSInfo->TVActive)
+ ViaTVSetMode(pScrn, mode);
+
+ /* CLE266A2 apparently doesn't like this */
+ if ((pVia->Chipset != VIA_CLE266) || (pVia->ChipRev != 0x02))
+ ViaCrtcMask(hwp, 0x6C, 0x00, 0x1E);
+
+ if (pBIOSInfo->PanelActive && (pBIOSInfo->PanelIndex != VIA_BIOS_NUM_PANEL)) {
+ pBIOSInfo->SetDVI = TRUE;
+ VIASetLCDMode(pScrn, mode);
+ ViaLCDPower(pScrn, TRUE);
+ } else if (pBIOSInfo->PanelPresent)
+ ViaLCDPower(pScrn, FALSE);
+
+ ViaSetSecondaryFIFO(pScrn, mode);
+
+ ViaSetSecondaryDotclock(pScrn, pBIOSInfo->Clock);
+ ViaSetUseExternalClock(hwp);
+
+ ViaCrtcMask(hwp, 0x17, 0x80, 0x80);
+
+ hwp->disablePalette(hwp);
+}
+
+/*
+ *
+ */
+static void
+ViaLCDPowerSequence(vgaHWPtr hwp, VIALCDPowerSeqRec Sequence)
+{
+ int i;
+
+ for (i = 0; i < Sequence.numEntry; i++) {
+ ViaVgahwMask(hwp, 0x300 + Sequence.port[i], Sequence.offset[i],
+ 0x301 + Sequence.port[i], Sequence.data[i],
+ Sequence.mask[i]);
+ usleep(Sequence.delay[i]);
+ }
+}
+
+/*
+ *
+ */
+void
+ViaLCDPower(ScrnInfoPtr pScrn, Bool On)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ VIAPtr pVia = VIAPTR(pScrn);
+ VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+ int i;
+
+#ifdef HAVE_DEBUG
+ if (On)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaLCDPower: On.\n");
+ else
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaLCDPower: Off.\n");
+#endif
+
+ /* Enable LCD */
+ if (On)
+ ViaCrtcMask(hwp, 0x6A, 0x08, 0x08);
+ else
+ ViaCrtcMask(hwp, 0x6A, 0x00, 0x08);
+
+ /* Find Panel Size Index for PowerSeq Table */
+ if (pVia->Chipset == VIA_CLE266) {
+ if (pBIOSInfo->PanelSize != VIA_PANEL_INVALID) {
+ for (i = 0; i < NumPowerOn; i++) {
+ if (lcdTable[pBIOSInfo->PanelIndex].powerSeq == powerOn[i].powerSeq)
+ break;
+ }
+ } else
+ i = 0;
+ } else /* KM and K8M use PowerSeq Table index 2. */
+ i = 2;
+
+ usleep(1);
+ if (On)
+ ViaLCDPowerSequence(hwp, powerOn[i]);
+ else
+ ViaLCDPowerSequence(hwp, powerOff[i]);
+ usleep(1);
+}
diff --git a/src/via_mode.h b/src/via_mode.h
new file mode 100644
index 000000000000..ea7bb871cc28
--- /dev/null
+++ b/src/via_mode.h
@@ -0,0 +1,920 @@
+/*
+ * 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.
+ */
+
+#ifndef _VIA_MODE_H_
+#define _VIA_MODE_H_ 1
+
+/*
+ * Bandwidth
+ *
+ */
+/* used for impossible entries: allow a minimum bandwidth in case this does happen */
+#define VIA_BW_MIN 74000000 /* > 640x480@60Hz@32bpp */
+
+/* index to table */
+#define VIA_BW_CLE266A 0
+#define VIA_BW_CLE266C 1
+#define VIA_BW_KM400 2
+#define VIA_BW_KM400A 3
+#define VIA_BW_K8M800 4
+#define VIA_BW_PM800 5
+#define VIA_BW_VM800 6
+#define VIA_BW_ALL 7
+
+/*
+ * 393216000 is for SDR133 in via_refresh.h
+ * 460800000 is for DDR266
+ */
+static struct {
+ CARD8 Device; /* equal to index */
+ CARD32 Bandwidth[VIA_MEM_END];
+} ViaBandwidthTable[VIA_BW_ALL] = {
+ { VIA_BW_CLE266A, { VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN, 394000000, 461000000, VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN } },
+ { VIA_BW_CLE266C, { VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN, 394000000, 461000000, VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN } },
+ { VIA_BW_KM400, { VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN, 394000000, 461000000, 461000000, VIA_BW_MIN, VIA_BW_MIN } },
+ { VIA_BW_KM400A, { VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN, 394000000, 461000000, 461000000, 461000000, VIA_BW_MIN } },
+ { VIA_BW_K8M800, { VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN, 394000000, 461000000, 461000000, 461000000, VIA_BW_MIN } },
+ { VIA_BW_PM800, { VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN, 394000000, 461000000, 461000000, 461000000, 922000000 } },
+ { VIA_BW_VM800, { VIA_BW_MIN, VIA_BW_MIN, VIA_BW_MIN, 394000000, 461000000, 461000000, 461000000, 922000000 } }
+};
+
+/*
+ * simple lookup table for dotclocks
+ *
+ */
+static struct ViaDotClock {
+ int DotClock;
+ CARD16 UniChrome;
+ CARD32 UniChromePro;
+} ViaDotClocks[] = {
+ { 25200, 0x513C, 0xa79004 },
+ { 25312, 0xC763, 0xc49005 },
+ { 26591, 0x471A, 0xce9005 },
+ { 31500, 0xC558, 0xae9003 },
+ { 31704, 0x471F, 0xaf9002 },
+ { 32663, 0xC449, 0x479000 },
+ { 33750, 0x4721, 0x959002 },
+ { 35500, 0x5877, 0x759001 },
+ { 36000, 0x5879, 0x9f9002 },
+ { 39822, 0xC459, 0x578c02 },
+ { 40000, 0x515F, 0x848c04 },
+ { 41164, 0x4417, 0x2c8c00 },
+ { 46981, 0x5069, 0x678c02 },
+ { 49500, 0xC353, 0xa48c04 },
+ { 50000, 0xC354, 0x368c00 },
+ { 56300, 0x4F76, 0x3d8c00 },
+ { 57284, 0x4E70, 0x3e8c00 },
+ { 64995, 0x0D3B, 0x6b8c01 },
+ { 65000, 0x0D3B, 0x6b8c01 }, /* Slightly unstable on PM800 */
+ { 65028, 0x866D, 0x6b8c01 },
+ { 74480, 0x156E, 0x288800 },
+ { 75000, 0x156E, 0x288800 },
+ { 78800, 0x442C, 0x2a8800 },
+ { 81135, 0x0622, 0x428801 },
+ { 81613, 0x4539, 0x708803 },
+ { 94500, 0x4542, 0x4d8801 },
+ { 108000, 0x0B53, 0x778802 },
+ { 108280, 0x4879, 0x778802 },
+ { 122000, 0x0D6F, 0x428800 },
+ { 122726, 0x073C, 0x878802 },
+ { 135000, 0x0742, 0x6f8801 },
+ { 148500, 0x0853, 0x518800 },
+ { 155800, 0x0857, 0x558402 },
+ { 157500, 0x422C, 0x2a8400 },
+ { 161793, 0x4571, 0x6f8403 },
+ { 162000, 0x0A71, 0x6f8403 },
+ { 175500, 0x4231, 0x2f8400 },
+ { 189000, 0x0542, 0x4d8401 },
+ { 202500, 0x0763, 0x6F8402 },
+ { 204800, 0x0764, 0x548401 },
+ { 218300, 0x043D, 0x3b8400 },
+ { 229500, 0x0660, 0x3e8400 }, /* Not tested on Pro */
+ { 0, 0, 0 }
+};
+
+/*
+ *
+ * Panel
+ *
+ */
+/*
+ * Since mode->PrivFlags is overwritten to support the antique Tseng
+ * this is the only way to flag a selfdefined mode as such.
+ */
+struct ViaModePriv {
+ char id[12]; /* "Unichrome" */
+};
+
+static struct ViaModePriv ViaPanelPrivate = {
+ { 'U', 'n', 'i', 'c', 'h', 'r', 'o', 'm', 'e', 0, 0, 0 },
+};
+
+#define MODEPREFIX(name) NULL, NULL, name, 0,M_T_DEFAULT
+#define MODESUFFIX 0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,FALSE,FALSE,\
+ sizeof(struct ViaModePriv),(void *)&ViaPanelPrivate,0,0.0,0.0
+
+static DisplayModeRec ViaPanelModes[] = {
+ { MODEPREFIX("640x480"), 25312, 640, 656, 752, 800, 0, 480, 489, 491, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX },
+ { MODEPREFIX("800x600"), 39822, 800, 840, 968, 1056, 0, 600, 600, 604, 628, 0, V_PHSYNC | 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("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("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(NULL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIX },
+};
+
+#define VIA_RES_640X480 0
+#define VIA_RES_800X600 1
+#define VIA_RES_1024X768 2
+#define VIA_RES_1152X864 3
+#define VIA_RES_1280X1024 4
+#define VIA_RES_1600X1200 5
+#define VIA_RES_1440X1050 6
+#define VIA_RES_1280X768 7
+#define VIA_RES_1280X960 8
+#define VIA_RES_1920X1440 9
+#define VIA_RES_848X480 10
+#define VIA_RES_1400X1050 11
+#define VIA_RES_720X480 12
+#define VIA_RES_720X576 13
+#define VIA_RES_1024X512 14
+#define VIA_RES_856X480 15
+#define VIA_RES_1024X576 16
+#define VIA_RES_800X480 17
+#define VIA_RES_1280X800 18
+#define VIA_RES_1280X720 19
+#define VIA_RES_1920X1080 20
+#define VIA_RES_1366X768 22
+#define VIA_RES_INVALID 0xFF
+
+/*
+ * simple lookuptable for PanelIndex selection
+ */
+
+static struct {
+ int Index;
+ int PanelIndex;
+ int X;
+ int Y;
+} ViaResolutionTable[] = {
+ {VIA_RES_640X480, VIA_PANEL6X4, 640, 480},
+ {VIA_RES_800X600, VIA_PANEL8X6, 800, 600},
+ {VIA_RES_1024X768, VIA_PANEL10X7, 1024, 768},
+ {VIA_RES_1152X864, VIA_PANEL_INVALID, 1152, 864},
+ {VIA_RES_1280X1024, VIA_PANEL12X10, 1280, 1024},
+ {VIA_RES_1600X1200, VIA_PANEL16X12, 1600, 1200},
+ {VIA_RES_1440X1050, VIA_PANEL_INVALID, 1440, 1050},
+ {VIA_RES_1280X768, VIA_PANEL12X7, 1280, 768},
+ {VIA_RES_1280X800, VIA_PANEL12X8, 1280, 800},
+ {VIA_RES_1280X960, VIA_PANEL_INVALID, 1280, 960},
+ /* {VIA_RES_1920X1440, VIA_PANEL_INVALID, 1920, 1140}, */
+ {VIA_RES_848X480, VIA_PANEL_INVALID, 848, 480},
+ {VIA_RES_1400X1050, VIA_PANEL14X10, 1400, 1050},
+ {VIA_RES_720X480, VIA_PANEL_INVALID, 720, 480},
+ {VIA_RES_720X576, VIA_PANEL_INVALID, 720, 576},
+ {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_INVALID, VIA_PANEL_INVALID, 0, 0}
+};
+
+static struct {
+ CARD16 Width;
+ CARD16 Height;
+ CARD8 mode_8b;
+ CARD8 mode_16b;
+ CARD8 mode_32b;
+} ViaVesaModes[] = {
+ { 400, 300, 0x22, 0x23, 0x24 },
+ { 512, 384, 0x25, 0x26, 0x27 },
+ { 640, 400, 0x30, 0x2E, 0x2F },
+ { 640, 480, 0x31, 0x33, 0x34 },
+ { 800, 600, 0x36, 0x38, 0x39 },
+ { 1024, 768, 0x3B, 0x3D, 0x3E },
+ { 1152, 864, 0x40, 0x42, 0x43 },
+ { 1280, 1024, 0x45, 0x47, 0x48 },
+ { 1600, 1200, 0x4A, 0x4C, 0x4D },
+ { 1440, 1050, 0x50, 0x52, 0x53 },
+ { 1280, 768, 0x54, 0x56, 0x57 },
+ { 1280, 960, 0x58, 0x5A, 0x5B },
+ { 320, 200, 0x5C, 0x5D, 0x5E },
+ { 1920, 1440, 0x60, 0x61, 0x62 },
+ { 848, 480, 0x63, 0x64, 0x65 },
+ { 1400, 1050, 0x66, 0x67, 0x68 },
+ { 720, 480, 0x70, 0x71, 0x72 },
+ { 720, 576, 0x73, 0x74, 0x75 },
+ { 1024, 512, 0x76, 0x77, 0x78 },
+ { 856, 480, 0x79, 0x7A, 0x7B },
+ { 320, 240, 0x7C, 0x7D, 0x7E },
+ { 0, 0, 0, 0, 0 },
+};
+
+#define VIA_BIOS_REG_LCD_MAX_NUM 48
+#define VIA_BIOS_NUM_LCD_SUPPORT_MASK 8
+#define VIA_BIOS_NUM_PANEL 7
+#define VIA_BIOS_MAX_NUM_MPATCH2 18
+#define VIA_BIOS_MAX_NUM_MPATCH1 9
+#define VIA_BIOS_MAX_NUM_CTREXP 5
+
+typedef struct _VIALCDMODEENTRY {
+ CARD16 LCDClk;
+ CARD16 VClk;
+ CARD16 LCDClk_12Bit;
+ CARD16 VClk_12Bit;
+ CARD8 port[VIA_BIOS_REG_LCD_MAX_NUM];
+ CARD8 offset[VIA_BIOS_REG_LCD_MAX_NUM];
+ CARD8 data[VIA_BIOS_REG_LCD_MAX_NUM];
+ int numEntry;
+} VIALCDModeEntry, *VIALCDModeEntryPtr;
+
+
+typedef struct _VIALCDMPATCHENTRY {
+ CARD8 Mode;
+ CARD16 LCDClk;
+ CARD16 VClk;
+ CARD16 LCDClk_12Bit;
+ CARD16 VClk_12Bit;
+ CARD8 port[VIA_BIOS_REG_LCD_MAX_NUM];
+ CARD8 offset[VIA_BIOS_REG_LCD_MAX_NUM];
+ CARD8 data[VIA_BIOS_REG_LCD_MAX_NUM];
+ int numEntry;
+} VIALCDMPatchEntry, *VIALCDMPatchEntryPtr;
+
+
+typedef struct _VIALCDMODETABLE {
+ CARD8 fpIndex;
+ CARD8 fpSize;
+ CARD8 powerSeq;
+ int numMPatchDP2Ctr;
+ int numMPatchDP2Exp;
+ int numMPatchDP1Ctr;
+ int numMPatchDP1Exp;
+ CARD16 SuptMode[VIA_BIOS_NUM_LCD_SUPPORT_MASK];
+ VIALCDModeEntry FPconfigTb;
+ VIALCDModeEntry InitTb;
+ VIALCDMPatchEntry MPatchDP2Ctr[VIA_BIOS_MAX_NUM_MPATCH2];
+ VIALCDMPatchEntry MPatchDP2Exp[VIA_BIOS_MAX_NUM_MPATCH2];
+ VIALCDMPatchEntry MPatchDP1Ctr[VIA_BIOS_MAX_NUM_MPATCH1];
+ VIALCDMPatchEntry MPatchDP1Exp[VIA_BIOS_MAX_NUM_MPATCH1];
+ VIALCDModeEntry LowResCtr;
+ VIALCDModeEntry LowResExp;
+ VIALCDModeEntry MCtr[VIA_BIOS_MAX_NUM_CTREXP];
+ VIALCDModeEntry MExp[VIA_BIOS_MAX_NUM_CTREXP];
+} VIALCDModeTableRec, *VIALCDModePtr;
+
+static const VIALCDModeTableRec lcdTable[] = {
+ { 0, 0, 0X1, 13, 13, 5, 5,
+ { 0XE0FF, 0XF, 0XC0FC, 0X1B, 0, 0X7000, 0, 0X7000 },
+ { 0, 0, 0, 0, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X7A, 0X7B, 0X7C, 0X7D, 0X7E, 0X7F, 0X80, 0X81, 0X82, 0X83, 0X84, 0X85, 0X86, 0X87, 0X88, 0X89, 0X8A, 0X8B, 0X8C, 0X8D, 0X8E, 0X8F, 0X90, 0X68, 0X69, 0X92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1, 0X2, 0X3, 0X4, 0X7, 0XA, 0XD, 0X13, 0X16, 0X19, 0X1C, 0X1D, 0X1E, 0X1F, 0, 0, 0X88, 0XD, 0X5D, 0X79, 0XFF, 0X10, 0XB, 0X67, 0, 0X7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 26 },
+ { 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X50, 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X58, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X66, 0X67, 0X6D, 0X6E, 0X6F, 0X70, 0X71, 0X72, 0X73, 0X74, 0X75, 0X76, 0X77, 0X78, 0X79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X1F, 0X7F, 0X7F, 0X1F, 0X9A, 0X23, 0X87, 0XE7, 0XC, 0XDF, 0XDF, 0XC, 0X11, 0XA, 0XE1, 0X23, 0XA0, 0X50, 0, 0X5F, 0X63, 0XB, 0XDF, 0X12, 0XDF, 0XC, 0X12, 0XE2, 0X14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 32 },
+ {
+ { 0, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X6D, 0X6E, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X2D, 0X31, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 12 },
+ { 0X2, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 },
+ { 0X6, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 },
+ { 0XD, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X6D, 0X6E, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X2D, 0X31, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 12 },
+ { 0XE, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 },
+ { 0XF, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5D, 0X9E, 0XCB, 0X9, 0XA0, 0X22, 0X5D, 0X5D, 0XA1, 0X13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 },
+ { 0X10, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X5D, 0X9E, 0XCB, 0X9, 0XA0, 0X22, 0X5D, 0X5D, 0XA1, 0X13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 },
+ { 0X13, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 },
+ { 0X30, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 10 },
+ { 0X5C, 0XC763, 0XC763, 0X8763, 0X8763, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0XDF, 0X7F, 0X51, 0X13, 0XE7, 0X47, 0XC7, 0X53, 0X80, 0X9, 0X2, 0X55, 0X37, 0X50, 0XC7, 0X2, 0XC7, 0X2, 0X56, 0X18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 21 },
+ { 0X7C, 0XC763, 0XC763, 0X8763, 0X8763, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X71, 0X72, 0X74, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X3F, 0XDF, 0X7F, 0X51, 0X13, 0XE7, 0X47, 0XEF, 0X67, 0X94, 0X9, 0X2, 0X69, 0X2B, 0X50, 0XEF, 0X2, 0XEF, 0X2, 0X6A, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 21 },
+ { 0X22, 0XC763, 0XC763, 0X8763, 0X8763, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0X7, 0XA7, 0X92, 0X13, 0XF, 0X6F, 0X2B, 0X85, 0XB2, 0X9, 0XA, 0X87, 0X29, 0X64, 0X2B, 0X2B, 0X88, 0X1A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 19 },
+ { 0X25, 0XC763, 0XC763, 0X8763, 0X8763, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X65, 0X70, 0X72, 0X75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0XFF, 0X3F, 0XDF, 0X92, 0X13, 0X47, 0XA7, 0X7F, 0XAF, 0XDC, 0X9, 0XA, 0XB1, 0X34, 0X80, 0X7F, 0X7F, 0XB2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 18 },
+ { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+ { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+ { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+ { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+ { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }
+ },
+ {
+ { 0, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X6D, 0X6E, 0X70, 0X72, 0X75, 0X76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X8F, 0XB7, 0XE4, 0X9, 0XB9, 0X3B, 0X2D, 0X31, 0X8F, 0X8F, 0XBA, 0X1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 12 },
+ { 0X2, 0X407, 0X407, 0X4523, 0X4523, { 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0XD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0X59, 0X5A, 0X5B, 0X5C, 0X5E, 0X5F, 0X70, 0X