diff -urN xf86-video-nsc-2.8.1-orig/man/nsc.man xf86-video-nsc-2.8.1/man/nsc.man
--- xf86-video-nsc-2.8.1-orig/man/nsc.man 2006-02-27 19:16:13.000000000 +0100
+++ xf86-video-nsc-2.8.1/man/nsc.man 2006-07-11 17:00:28.000000000 +0200
@@ -14,15 +14,18 @@
.fi
.SH DESCRIPTION
.B nsc
-is an __xservername__ driver for National Semiconductors GEODE processor family.
-It uses the DURANGO kit provided by National Semiconductor.
+is an __xservername__ driver for the AMD Geode (formerly National Semiconductors
+Geode) processor family.
+It uses the DURANGO kit provided by National Semiconductor up to the GX
+series and the CIMARRON kit provided by AMD for the LX series.
The driver is accelerated, and provides support for the following
-framebuffer depths: 8, 16 and 24.
+framebuffer depths: 8, 16 and 24 including XVideo acceleration. On the
+LX series hardware RGBA cursors are supported.
.SH SUPPORTED HARDWARE
The
.B nsc
-driver supports GXLV (5530 companion chip), SC1200, SC1400 and
-GX2 (5535 companion chip).
+driver supports the GXLV (5530 companion chip), SC1200, SC1400,
+GX2 (5535 companion chip) and AMD LX.
.SH CONFIGURATION DETAILS
Please refer to __xconfigfile__(__filemansuffix__) for general configuration
details. This section only covers configuration details specific to this
@@ -131,4 +134,4 @@
.SH "SEE ALSO"
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
.SH AUTHOR
-Author: Sarma V. Kolluru
+Author: Sarma V. Kolluru and Rene Rebe
diff -urN xf86-video-nsc-2.8.1-orig/src/Makefile.am xf86-video-nsc-2.8.1/src/Makefile.am
--- xf86-video-nsc-2.8.1-orig/src/Makefile.am 2005-10-05 00:59:15.000000000 +0200
+++ xf86-video-nsc-2.8.1/src/Makefile.am 2006-07-11 17:00:28.000000000 +0200
@@ -23,7 +23,7 @@
# -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.
-AM_CFLAGS = @XORG_CFLAGS@ -I$(top_srcdir)/src/gfx -I$(top_srcdir)/src/panel
+AM_CFLAGS = @XORG_CFLAGS@ -I$(top_srcdir)/src/gfx -I$(top_srcdir)/src/panel -I$(top_srcdir)/src/cim
AM_CCASFLAGS = @XORG_CFLAGS@
nsc_drv_la_LTLIBRARIES = nsc_drv.la
nsc_drv_la_LDFLAGS = -module -avoid-version
@@ -31,6 +31,7 @@
nsc_drv_la_SOURCES = \
durango.c \
+ cimarron.c \
nsc_driver.c \
nsc_fourcc.h \
nsc_galstub.c \
@@ -46,6 +47,12 @@
nsc_gx2_driver.c \
nsc_gx2_shadow.c \
nsc_gx2_video.c \
+ amd_lx_accel.c \
+ amd_lx_cursor.c \
+ amd_lx_dga.c \
+ amd_lx_driver.c \
+ amd_lx_shadow.c \
+ amd_lx_video.c \
nsc.h \
panel.c
@@ -117,6 +124,18 @@
gfx/tv_fs451.c \
gfx/tv_geode.c \
gfx/vid_1400.c \
- gfx/vip_1400.c
+ gfx/vip_1400.c \
+ \
+ cim/cim_df.c \
+ cim/cim_gp.c \
+ cim/cim_modes.c \
+ cim/cim_vg.ci \
+ cim/cim_vop.c \
+ cim/cim_filter.c \
+ cim/cim_init.c \
+ cim/cim_msr.c \
+ cim/cim_vip.c \
+ cim/cimarron.c
+
diff -urN xf86-video-nsc-2.8.1-orig/src/Makefile.in xf86-video-nsc-2.8.1/src/Makefile.in
--- xf86-video-nsc-2.8.1-orig/src/Makefile.in 2006-04-08 03:37:03.000000000 +0200
+++ xf86-video-nsc-2.8.1/src/Makefile.in 2006-07-11 17:55:20.000000000 +0200
@@ -78,19 +78,22 @@
nsc_drv_laLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(nsc_drv_la_LTLIBRARIES)
nsc_drv_la_LIBADD =
-am__nsc_drv_la_SOURCES_DIST = durango.c nsc_driver.c nsc_fourcc.h \
- nsc_galstub.c nsc_gx1_accel.c nsc_gx1_cursor.c nsc_gx1_dga.c \
- nsc_gx1_driver.c nsc_gx1_shadow.c nsc_gx1_video.c \
- nsc_gx2_accel.c nsc_gx2_cursor.c nsc_gx2_dga.c \
- nsc_gx2_driver.c nsc_gx2_shadow.c nsc_gx2_video.c nsc.h \
- panel.c nsc_msr_asm.S
+am__nsc_drv_la_SOURCES_DIST = durango.c cimarron.c nsc_driver.c \
+ nsc_fourcc.h nsc_galstub.c nsc_gx1_accel.c nsc_gx1_cursor.c \
+ nsc_gx1_dga.c nsc_gx1_driver.c nsc_gx1_shadow.c \
+ nsc_gx1_video.c nsc_gx2_accel.c nsc_gx2_cursor.c nsc_gx2_dga.c \
+ nsc_gx2_driver.c nsc_gx2_shadow.c nsc_gx2_video.c \
+ amd_lx_accel.c amd_lx_cursor.c amd_lx_dga.c amd_lx_driver.c \
+ amd_lx_shadow.c amd_lx_video.c nsc.h panel.c nsc_msr_asm.S
@I386ARCH_TRUE@am__objects_1 = nsc_msr_asm.lo
-am_nsc_drv_la_OBJECTS = durango.lo nsc_driver.lo nsc_galstub.lo \
- nsc_gx1_accel.lo nsc_gx1_cursor.lo nsc_gx1_dga.lo \
- nsc_gx1_driver.lo nsc_gx1_shadow.lo nsc_gx1_video.lo \
- nsc_gx2_accel.lo nsc_gx2_cursor.lo nsc_gx2_dga.lo \
- nsc_gx2_driver.lo nsc_gx2_shadow.lo nsc_gx2_video.lo panel.lo \
- $(am__objects_1)
+am_nsc_drv_la_OBJECTS = durango.lo cimarron.lo nsc_driver.lo \
+ nsc_galstub.lo nsc_gx1_accel.lo nsc_gx1_cursor.lo \
+ nsc_gx1_dga.lo nsc_gx1_driver.lo nsc_gx1_shadow.lo \
+ nsc_gx1_video.lo nsc_gx2_accel.lo nsc_gx2_cursor.lo \
+ nsc_gx2_dga.lo nsc_gx2_driver.lo nsc_gx2_shadow.lo \
+ nsc_gx2_video.lo amd_lx_accel.lo amd_lx_cursor.lo \
+ amd_lx_dga.lo amd_lx_driver.lo amd_lx_shadow.lo \
+ amd_lx_video.lo panel.lo $(am__objects_1)
nsc_drv_la_OBJECTS = $(am_nsc_drv_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
@@ -238,17 +241,18 @@
# -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.
-AM_CFLAGS = @XORG_CFLAGS@ -I$(top_srcdir)/src/gfx -I$(top_srcdir)/src/panel
+AM_CFLAGS = @XORG_CFLAGS@ -I$(top_srcdir)/src/gfx -I$(top_srcdir)/src/panel -I$(top_srcdir)/src/cim
AM_CCASFLAGS = @XORG_CFLAGS@
nsc_drv_la_LTLIBRARIES = nsc_drv.la
nsc_drv_la_LDFLAGS = -module -avoid-version
nsc_drv_ladir = @moduledir@/drivers
-nsc_drv_la_SOURCES = durango.c nsc_driver.c nsc_fourcc.h nsc_galstub.c \
- nsc_gx1_accel.c nsc_gx1_cursor.c nsc_gx1_dga.c \
+nsc_drv_la_SOURCES = durango.c cimarron.c nsc_driver.c nsc_fourcc.h \
+ nsc_galstub.c nsc_gx1_accel.c nsc_gx1_cursor.c nsc_gx1_dga.c \
nsc_gx1_driver.c nsc_gx1_shadow.c nsc_gx1_video.c \
nsc_gx2_accel.c nsc_gx2_cursor.c nsc_gx2_dga.c \
- nsc_gx2_driver.c nsc_gx2_shadow.c nsc_gx2_video.c nsc.h \
- panel.c $(am__append_1)
+ nsc_gx2_driver.c nsc_gx2_shadow.c nsc_gx2_video.c \
+ amd_lx_accel.c amd_lx_cursor.c amd_lx_dga.c amd_lx_driver.c \
+ amd_lx_shadow.c amd_lx_video.c nsc.h panel.c $(am__append_1)
EXTRA_DIST = \
nsc_galfns.c \
nsc_gx2_vga.c \
@@ -312,7 +316,18 @@
gfx/tv_fs451.c \
gfx/tv_geode.c \
gfx/vid_1400.c \
- gfx/vip_1400.c
+ gfx/vip_1400.c \
+ \
+ cim/cim_df.c \
+ cim/cim_gp.c \
+ cim/cim_modes.c \
+ cim/cim_vg.ci \
+ cim/cim_vop.c \
+ cim/cim_filter.c \
+ cim/cim_init.c \
+ cim/cim_msr.c \
+ cim/cim_vip.c \
+ cim/cimarron.c
all: all-am
@@ -383,6 +398,13 @@
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amd_lx_accel.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amd_lx_cursor.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amd_lx_dga.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amd_lx_driver.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amd_lx_shadow.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amd_lx_video.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cimarron.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/durango.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nsc_driver.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nsc_galstub.Plo@am__quote@
@@ -489,7 +511,7 @@
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
- $(mkdir_p) $(distdir)/gfx $(distdir)/panel
+ $(mkdir_p) $(distdir)/cim $(distdir)/gfx $(distdir)/panel
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
diff -urN xf86-video-nsc-2.8.1-orig/src/amd_lx_accel.c xf86-video-nsc-2.8.1/src/amd_lx_accel.c
--- xf86-video-nsc-2.8.1-orig/src/amd_lx_accel.c 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/amd_lx_accel.c 2006-07-11 18:08:36.000000000 +0200
@@ -0,0 +1,1476 @@
+/*
+ * $Workfile: amd_lx_accel.c $
+ * $Revision: #4 $
+ * $Author: billm $
+ *
+ * File Contents: This file is consists of main Xfree
+ * acceleration supported routines like solid fill used
+ * here.
+ * Project: Geode Xfree Frame buffer device driver.
+ *
+ *
+ */
+
+/*
+ * Copyright (c) 2003-2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice 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.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+/*
+ * */
+/*
+ * */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Xfree86 header files */
+
+#include "vgaHW.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xaalocal.h"
+#include "xf86fbman.h"
+#include "miline.h"
+#include "xf86_libc.h"
+#include "xaarop.h"
+#include "nsc.h"
+
+#define LX_FILL_RECT_SUPPORT 1
+#define LX_BRES_LINE_SUPPORT 1
+#define LX_DASH_LINE_SUPPORT 1
+#define LX_MONO_8X8_PAT_SUPPORT 1
+#define LX_CLREXP_8X8_PAT_SUPPORT 1
+#define LX_SCR2SCREXP_SUPPORT 1
+#define LX_SCR2SCRCPY_SUPPORT 1
+#define LX_CPU2SCREXP_SUPPORT 1
+#define LX_SCANLINE_SUPPORT 1
+#define LX_USE_OFFSCRN_MEM 1
+#define LX_WRITE_PIXMAP_SUPPORT 1
+
+#undef ulong
+typedef unsigned long ulong;
+#undef uint
+typedef unsigned int uint;
+#undef ushort
+typedef unsigned short ushort;
+#undef uchar
+typedef unsigned char uchar;
+
+#if DEBUGLVL>0
+extern FILE *zdfp;
+#if DEBUGTIM>0
+#ifndef USE_RDTSC
+#define DBLOG(n,s...) do { if((DEBUGLVL)>=(n)) { long secs,usecs; \
+ getsecs(&secs,&usecs); fprintf(zdfp,"%d,%d ",secs,usecs); \
+ fprintf(zdfp,s); } } while(0)
+#else
+#define tsc(n) __asm__ __volatile__ ( \
+ " rdtsc" \
+ : "=a" (((int*)(&(n)))[0]), "=d" (((int*)(&(n)))[1]) \
+ : )
+#define DBLOG(n,s...) do { if((DEBUGLVL)>=(n)) { long long t; \
+ tsc(t); fprintf(zdfp,"%lld ",t); \
+ fprintf(zdfp,s); } } while(0)
+#endif
+#else
+#define DBLOG(n,s...) do { if((DEBUGLVL)>=(n)) fprintf(zdfp,s); } while(0)
+#endif
+#else
+#define DBLOG(n,s...) do {} while(0)
+#endif
+
+#define CALC_FBOFFSET(x, y) \
+ (((ulong)(y) << gu3_yshift) | \
+ ((ulong)(x) << gu3_xshift))
+
+#define OS_UDELAY 0
+#if OS_UDELAY > 0
+#define OS_USLEEP(usec) usleep(usec);
+#else
+#define OS_USLEEP(usec)
+#endif
+
+#define HOOK(fn) localRecPtr->fn = LX##fn
+
+static int lx0 = -1, ly0 = -1;
+static int lx1 = -1, ly1 = -1;
+static int ROP;
+
+/* #define ENABLE_PREFETCH CIMGP_ENABLE_PREFETCH */
+#define ENABLE_PREFETCH 0
+#define BLTFLAGS_HAZARD CIMGP_BLTFLAGS_HAZARD
+
+/* specify dst bounding box, upper left/lower right */
+static int
+lx_flags0(int x0,int y0, int x1,int y1)
+{
+ int n = ((ROP^(ROP>>1))&0x55) == 0 || /* no dst */
+ x0 >= lx1 || y0 >= ly1 || /* rght/below */
+ x1 <= lx0 || y1 <= ly0 ? /* left/above */
+ ENABLE_PREFETCH : BLTFLAGS_HAZARD ;
+ lx0 = x0; ly0 = y0; lx1 = x1; ly1 = y1;
+ return n;
+}
+
+/* specify dst bounding box, upper left/WxH */
+static int
+lx_flags1(int x0,int y0, int w,int h)
+{
+ return lx_flags0(x0,y0, x0+w,y0+h);
+}
+
+/* specify dst bounding box, two points */
+static int
+lx_flags2(int x0,int y0, int x1,int y1)
+{
+ int n;
+ if( x0 >= x1 ) { n = x0; x0 = x1-1; x1 = n+1; }
+ if( y0 >= y1 ) { n = y0; y0 = y1-1; y1 = n+1; }
+ return lx_flags0(x0,y0, x1,y1);
+}
+
+/* specify src/dst bounding box, upper left/WxH */
+static int
+lx_flags3(int x0,int y0, int x1,int y1, int w,int h)
+{
+ int x2 = x1+w, y2 = y1+h;
+ /* dst not hazzard and src not hazzard */
+ int n = ( ((ROP^(ROP>>1))&0x55) == 0 ||
+ x1 >= lx1 || y1 >= ly1 ||
+ x2 <= lx0 || y2 <= ly0 ) &&
+ ( ((ROP^(ROP>>2))&0x33) == 0 ||
+ x0 >= lx1 || y0 >= ly1 ||
+ x0+w <= lx0 || y0+h <= ly0 ) ?
+ ENABLE_PREFETCH : BLTFLAGS_HAZARD;
+ lx0 = x1; ly0 = y1; lx1 = x2; ly1 = y2;
+ return n;
+}
+
+static void
+lx_endpt(int x,int y,int len, int mag,int min,int err,int oct, int *px, int *py)
+{
+ int u = len-1;
+ int v = (u*min-err)/mag;
+
+ switch( oct ) {
+ default:
+ case 0: x += u; y += v; break;
+ case 1: x += v; y += u; break;
+ case 2: x += u; y -= v; break;
+ case 3: x += v; y -= u; break;
+ case 4: x -= u; y += v; break;
+ case 5: x -= v; y += u; break;
+ case 6: x -= u; y -= v; break;
+ case 7: x -= v; y -= u; break;
+ }
+ *px = x; *py = y;
+}
+
+/* static storage declarations */
+
+typedef struct sGBltBox {
+ ulong x, y;
+ ulong w, h;
+ ulong color;
+ int bpp, transparent;
+} GBltBox;
+
+static GBltBox giwr;
+static GBltBox gc2s;
+
+typedef struct sGDashLine {
+ ulong pat;
+ int len;
+ int fg;
+ int bg;
+} GDashLine;
+
+static GDashLine gdln;
+
+static uint gu3_xshift = 1;
+static uint gu3_yshift = 1;
+static uint gu3_img_fmt = 0;
+#if !LX_USE_OFFSCRN_MEM
+static uint ImgBufOffset;
+#else
+static uchar *ImgLnsBuffers;
+#endif
+static uchar *ClrLnsBuffers;
+static XAAInfoRecPtr localRecPtr;
+
+static int lx_src_fmt[4] = {
+ CIMGP_SOURCE_FMT_8BPP_INDEXED,
+ CIMGP_SOURCE_FMT_0_5_6_5,
+ CIMGP_SOURCE_FMT_24BPP,
+ CIMGP_SOURCE_FMT_8_8_8_8
+};
+
+
+/* pat 0xF0 */
+/* src 0xCC */
+/* dst 0xAA */
+
+/* (src FUNC dst) */
+
+static const int SDfn[16] = {
+ 0x00, 0x88, 0x44, 0xCC, 0x22, 0xAA, 0x66, 0xEE,
+ 0x11, 0x99, 0x55, 0xDD, 0x33, 0xBB, 0x77, 0xFF
+};
+
+/* ((src FUNC dst) AND pat-mask) OR (dst AND (NOT pat-mask)) */
+
+static const int SDfn_PM[16] = {
+ 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
+ 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA
+};
+
+/* (pat FUNC dst) */
+
+static int PDfn[16] = {
+ 0x00, 0xA0, 0x50, 0xF0, 0x0A, 0xAA, 0x5A, 0xFA,
+ 0x05, 0xA5, 0x55, 0xF5, 0x0F, 0xAF, 0x5F, 0xFF
+};
+
+/* ((pat FUNC dst) AND src-mask) OR (dst AND (NOT src-mask)) */
+
+static int PDfn_SM[16] = {
+ 0x22, 0xA2, 0x62, 0xE2, 0x2A, 0xAA, 0x6A, 0xEA,
+ 0x26, 0xA6, 0x66, 0xE6, 0x2E, 0xAE, 0x6E, 0xEE
+};
+
+
+
+/*----------------------------------------------------------------------------
+ * LXAccelSync.
+ *
+ * Description :This function is called to synchronize with the graphics
+ * engine and it waits the graphic engine is idle. This is
+ * required before allowing direct access to the framebuffer.
+ *
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ *
+ * Returns :none
+ *---------------------------------------------------------------------------*/
+void
+LXAccelSync(ScrnInfoPtr pScrni)
+{
+ DBLOG(3,"LXAccelSync()\n");
+ while( gp_test_blt_busy() != 0 ) { OS_USLEEP(OS_UDELAY) }
+}
+
+#if LX_FILL_RECT_SUPPORT
+/*----------------------------------------------------------------------------
+ * LXSetupForSolidFill.
+ *
+ * Description :The SetupFor and Subsequent SolidFill(Rect) provide
+ * filling rectangular areas of the screen with a
+ * foreground color.
+ *
+ * Parameters.
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ * color int foreground fill color
+ * rop int unmapped raster op
+ * planemask uint -1 (fill) or pattern data
+ *
+ * Returns :none
+ *--------------------------------------------------------------------------*/
+static void
+LXSetupForSolidFill(ScrnInfoPtr pScrni, int color, int rop, uint planemask)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ DBLOG(2,"LXSetupForSolidFill(%#x,%#x,%#x)\n",color,rop,planemask);
+ rop &= 0x0F;
+ gp_declare_blt(0);
+ if( planemask == ~0U ) { /* fill with color */
+ gp_set_raster_operation(ROP=SDfn[rop]);
+ }
+ else { /* select rop that uses source data for planemask */
+ gp_set_raster_operation(ROP=SDfn_PM[rop]);
+ gp_set_solid_pattern(planemask);
+ }
+ gp_set_solid_source(color);
+ gp_set_strides(pGeode->AccelPitch,pGeode->AccelPitch);
+ gp_write_parameters();
+}
+
+ /*----------------------------------------------------------------------------
+ * LXSubsequentSolidFillRect.
+ *
+ * Description :see LXSetupForSolidFill.
+ *
+ * Parameters.
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ * x int destination x offset
+ * y int destination y offset
+ * w int fill area width (pixels)
+ * h int fill area height (pixels)
+ *
+ * Returns :none
+ *
+ * Sample application uses:
+ * - Window backgrounds.
+ * - pull down highlighting.
+ * - x11perf: rectangle tests (-rect500).
+ * - x11perf: fill trapezoid tests (-trap100).
+ * - x11perf: horizontal line segments (-hseg500).
+ *---------------------------------------------------------------------------*/
+static void
+LXSubsequentSolidFillRect(ScrnInfoPtr pScrni, int x, int y, int w, int h)
+{
+ int flags;
+ DBLOG(2,"LXSubsequentSolidFillRect() at %d,%d %dx%d\n",x,y,w,h);
+ flags = lx_flags1(x,y,w,h);
+ gp_declare_blt(flags);
+ gp_pattern_fill(CALC_FBOFFSET(x,y), w, h);
+}
+
+/* LX_FILL_RECT_SUPPORT */
+#endif
+
+#if LX_CLREXP_8X8_PAT_SUPPORT
+/*----------------------------------------------------------------------------
+ * LXSetupForColor8x8PatternFill
+ *
+ * Description :8x8 color pattern data is 64 pixels of full color data
+ * stored linearly in offscreen video memory. These patterns
+ * are useful as a substitute for 8x8 mono patterns when tiling,
+ * doing opaque stipples, or regular stipples.
+ *
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ * patx int x offset to pattern data
+ * paty int y offset to pattern data
+ * rop int unmapped raster operation
+ * planemask uint -1 (copy) or pattern data
+ * trans_color int -1 (copy) or transparent color (not enabled)
+ * trans color only supported on source channel
+ * or in monochrome pattern channel
+ *
+ * Returns :none.
+ *
+ *---------------------------------------------------------------------------*/
+
+static void
+LXSetupForColor8x8PatternFill(ScrnInfoPtr pScrni, int patx, int paty, int rop,
+ uint planemask, int trans_color)
+{
+ unsigned long *pat_8x8;
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ DBLOG(2,"LXSetupForColor8x8PatternFill() pat %#x,%#x rop %#x %#x %#x\n"
+ ,patx,paty,rop,planemask,trans_color);
+ pat_8x8 = (unsigned long *)(pGeode->FBBase+CALC_FBOFFSET(patx,paty));
+ /* since the cache may be loaded by blt, we must wait here */
+ LXAccelSync(pScrni);
+ gp_set_color_pattern(pat_8x8,gu3_img_fmt,0,0);
+ rop &= 0x0F;
+ gp_declare_blt(0);
+ if( planemask == ~0U ) { /* fill with pattern */
+ gp_set_raster_operation(ROP=PDfn[rop]);
+ }
+ else { /* select rop that uses source data for planemask */
+ gp_set_raster_operation(ROP=PDfn_SM[rop]);
+ gp_set_solid_source((ulong)planemask);
+ }
+ gp_set_strides(pGeode->AccelPitch,pGeode->AccelPitch);
+ gp_write_parameters();
+}
+
+/*----------------------------------------------------------------------------
+ * LXSubsequentColor8x8PatternFillRect
+ *
+ * Description :see LXSetupForColor8x8PatternFill.
+ *
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ * patx int pattern phase x offset
+ * paty int pattern phase y offset
+ * x int destination x offset
+ * y int destination y offset
+ * w int fill area width (pixels)
+ * h int fill area height (pixels)
+ *
+ * Returns :none
+ *
+ * Sample application uses:
+ * - Patterned desktops
+ * - x11perf: stippled rectangle tests (-srect500).
+ * - x11perf: opaque stippled rectangle tests (-osrect500).
+ *--------------------------------------------------------------------------*/
+static void
+LXSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrni, int patx, int paty,
+ int x, int y, int w, int h)
+{
+ int flags;
+ DBLOG(2,"LXSubsequentColor8x8PatternFillRect() patxy %d,%d at %d,%d %dsx%d\n",
+ patx,paty,x,y,w,h);
+ flags = lx_flags1(x,y,w,h);
+ gp_declare_blt(flags);
+ gp_set_pattern_origin(patx,paty);
+ gp_pattern_fill(CALC_FBOFFSET(x,y), w, h);
+}
+
+/* LX_CLREXP_8X8_PAT_SUPPORT */
+#endif
+
+#if LX_MONO_8X8_PAT_SUPPORT
+/*----------------------------------------------------------------------------
+ * LXSetupForMono8x8PatternFill
+ *
+ * Description :8x8 mono pattern data is 64 bits of color expansion data
+ * with ones indicating the foreground color and zeros
+ * indicating the background color. These patterns are
+ * useful when tiling, doing opaque stipples, or regular
+ * stipples.
+ *
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ * patx int x offset to pattern data
+ * paty int y offset to pattern data
+ * fg int foreground color
+ * bg int -1 (transparent) or background color
+ * rop int unmapped raster operation
+ * planemask uint -1 (copy) or pattern data
+ *
+ * Returns :none.
+ *
+ * Comments :none.
+ *
+ *--------------------------------------------------------------------------*/
+static void
+LXSetupForMono8x8PatternFill(ScrnInfoPtr pScrni, int patx, int paty,
+ int fg, int bg, int rop, uint planemask)
+{
+ int trans;
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ DBLOG(2,"LXSetupForMono8x8PatternFill() pat %#x,%#x fg %#x bg %#x %#x %#x\n",
+ patx,paty,fg,bg,rop,planemask);
+ rop &= 0x0F;
+ gp_declare_blt(0);
+ if( planemask == ~0U ) { /* fill with pattern */
+ gp_set_raster_operation(ROP=PDfn[rop]);
+ }
+ else { /* select rop that uses source data for planemask */
+ gp_set_raster_operation(ROP=PDfn_SM[rop]);
+ gp_set_solid_source((ulong)planemask);
+ }
+ trans = bg==-1 ? 1 : 0;
+ gp_set_mono_pattern(bg,fg, patx,paty, trans, 0, 0);
+ gp_set_strides(pGeode->AccelPitch,pGeode->AccelPitch);
+ gp_write_parameters();
+}
+
+/*----------------------------------------------------------------------------
+ * LXSubsequentMono8x8PatternFillRect
+ *
+ * Description :see LXSetupForMono8x8PatternFill
+ *
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ * patx int pattern phase x offset
+ * paty int pattern phase y offset
+ * x int destination x offset
+ * y int destination y offset
+ * w int fill area width (pixels)
+ * h int fill area height (pixels)
+
+ * Returns :none
+ *
+ * Sample application uses:
+ * - Patterned desktops
+ * - x11perf: stippled rectangle tests (-srect500).
+ * - x11perf: opaque stippled rectangle tests (-osrect500).
+ *--------------------------------------------------------------------------*/
+static void
+LXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrni, int patx, int paty,
+ int x, int y, int w, int h)
+{
+ int flags;
+ DBLOG(2,"LXSubsequentMono8x8PatternFillRect() pat %#x,%#x at %d,%d %dx%d\n",patx,paty,x,y,w,h);
+ flags = lx_flags1(x,y,w,h);
+ gp_declare_blt(flags);
+ gp_set_pattern_origin(patx,paty);
+ gp_pattern_fill(CALC_FBOFFSET(x,y), w,h);
+}
+
+/* LX_MONO_8X8_PAT_SUPPORT */
+#endif
+
+#if LX_SCR2SCRCPY_SUPPORT
+/*----------------------------------------------------------------------------
+ * LXSetupForScreenToScreenCopy
+ *
+ * Description :SetupFor and Subsequent ScreenToScreenCopy functions
+ * provide an interface for copying rectangular areas from
+ * video memory to video memory.
+ *
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ * xdir int x copy direction (up/dn)
+ * ydir int y copy direction (up/dn)
+ * rop int unmapped raster operation
+ * planemask uint -1 (copy) or pattern data
+ * trans_color int -1 (copy) or transparent color
+ *
+ * Returns :none
+ *---------------------------------------------------------------------------*/
+static void
+LXSetupForScreenToScreenCopy(ScrnInfoPtr pScrni, int xdir, int ydir, int rop,
+ uint planemask, int trans_color)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ DBLOG(2,"LXSetupForScreenToScreenCopy() xd%d yd%d rop %#x %#x %#x\n",
+ xdir,ydir,rop,planemask,trans_color);
+ rop &= 0x0F;
+ gp_declare_blt(0);
+ if( planemask == ~0U ) {
+ gp_set_raster_operation(ROP=SDfn[rop]);
+ }
+ else {
+ gp_set_raster_operation(ROP=SDfn_PM[rop]);
+ gp_set_solid_pattern((ulong)planemask);
+ }
+ gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch);
+ gp_write_parameters();
+ gc2s.transparent = (trans_color == -1) ? 0 : 1;
+ gc2s.color = trans_color;
+}
+
+/*----------------------------------------------------------------------------
+ * LXSubsquentScreenToScreenCopy
+ *
+ * Description :see LXSetupForScreenToScreenCopy.
+ *
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ * x1 int source x offset
+ * y1 int source y offset
+ * x2 int destination x offset
+ * y2 int destination y offset
+ * w int copy area width (pixels)
+ * h int copy area height (pixels)
+ *
+ * Returns :none
+ *
+ * Sample application uses (non-transparent):
+ * - Moving windows.
+ * - x11perf: scroll tests (-scroll500).
+ * - x11perf: copy from window to window (-copywinwin500).
+ *---------------------------------------------------------------------------*/
+static void
+LXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrni,
+ int x1, int y1, int x2, int y2, int w, int h)
+{
+ int flags;
+ DBLOG(2,"LXSubsequentScreenToScreenCopy() from %d,%d to %d,%d %dx%d\n",x1,y1,x2,y2,w,h);
+ flags = lx_flags3(x1,y1,x2,y2,w,h);
+ gp_declare_blt(flags);
+ if( gc2s.transparent ) {
+ gp_set_source_transparency(gc2s.color,~0);
+ }
+ flags = 0;
+ if( x2 > x1 ) flags |= 1;
+ if( y2 > y1 ) flags |= 2;
+ gp_screen_to_screen_blt(CALC_FBOFFSET(x2,y2), CALC_FBOFFSET(x1,y1), w,h, flags);
+}
+
+/* LX_SCR2SCRCPY_SUPPORT */
+#endif
+
+#if LX_SCANLINE_SUPPORT
+/*----------------------------------------------------------------------------
+ * LXSetupForScanlineImageWrite
+ *
+ * Description :SetupFor/Subsequent ScanlineImageWrite and ImageWriteScanline
+ * transfer full color pixel data from system memory to video
+ * memory. This is useful for dealing with alignment issues and
+ * performing raster ops on the data.
+ *
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ * rop int unmapped raster operation
+ * planemask uint -1 (copy) or pattern data
+ * bpp int bits per pixel (unused)
+ * depth int color depth (unused)
+ *
+ * Returns :none
+ *
+ * x11perf -putimage10
+ * x11perf -putimage100
+ * x11perf -putimage500
+*----------------------------------------------------------------------------
+*/
+static void
+LXSetupForScanlineImageWrite(ScrnInfoPtr pScrni, int rop, uint planemask,
+ int trans_color, int bpp, int depth)
+{
+ int Bpp = (bpp+7) >> 3;
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ DBLOG(2,"LXSetupForScanlineImageWrite() rop %#x %#x %#x %d %d\n",
+ rop,planemask,trans_color,bpp,depth);
+ rop &= 0x0F;
+ gp_set_source_format(lx_src_fmt[Bpp-1]);
+ gp_declare_blt(0);
+ if( planemask == ~0U ) {
+ gp_set_raster_operation(ROP=SDfn[rop]);
+ }
+ else {
+ gp_set_raster_operation(ROP=SDfn_PM[rop]);
+ gp_set_solid_pattern(planemask);
+ }
+ gp_set_strides(pGeode->AccelPitch,pGeode->AccelPitch);
+ gp_write_parameters();
+ giwr.transparent = (trans_color == -1) ? 0 : 1;
+ giwr.color = trans_color;
+}
+
+/*----------------------------------------------------------------------------
+ * LXSubsequentScanlineImageWriteRect
+ *
+ * Description : see LXSetupForScanlineImageWrite.
+ *
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ * x int destination x offset
+ * y int destination y offset
+ * w int copy area width (pixels)
+ * h int copy area height (pixels)
+ * skipleft int x margin (pixels) to skip (not enabled)
+ *
+ * Returns :none
+ *---------------------------------------------------------------------------*/
+static void
+LXSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrni,
+ int x, int y, int w, int h, int skipleft)
+{
+ DBLOG(2,"LXSubsequentScanlineImageWriteRect() rop %d,%d %dx%d %d\n",x,y,w,h,skipleft);
+ giwr.x = x; giwr.y = y;
+ giwr.w = w; giwr.h = h;
+ /* since the image buffer must be not busy (it may be busy from
+ * a previous ScanlineWriteImage), we must add a Sync here */
+#if !LX_USE_OFFSCRN_MEM
+ LXAccelSync(pScrni);
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * LXSubsquentImageWriteScanline
+ *
+ * Description : see LXSetupForScanlineImageWrite.
+ *
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ * bufno int scanline number in write group
+ *
+ * Returns :none
+ *
+ * Sample application uses (non-transparent):
+ * - Moving windows.
+ * - x11perf: scroll tests (-scroll500).
+ * - x11perf: copy from window to window (-copywinwin500).
+ *
+ *---------------------------------------------------------------------------*/
+static void
+LXSubsequentImageWriteScanline(ScrnInfoPtr pScrni, int bufno)
+{
+ GeodePtr pGeode;
+ int blt_height = 0;
+ DBLOG(3,"LXSubsequentImageWriteScanline() %d\n",bufno);
+ pGeode = GEODEPTR(pScrni);
+
+ if( (blt_height=pGeode->NoOfImgBuffers) > giwr.h )
+ blt_height = giwr.h;
+ if( ++bufno < blt_height ) return;
+
+ gp_declare_blt(ENABLE_PREFETCH);
+ if( giwr.transparent ) {
+ gp_set_source_transparency(giwr.color,~0);
+ }
+#if !LX_USE_OFFSCRN_MEM
+ gp_screen_to_screen_blt(CALC_FBOFFSET(giwr.x,giwr.y), ImgBufOffset,
+ giwr.w, blt_height, 0);
+ LXAccelSync(pScrni);
+#else
+ gp_color_bitmap_to_screen_blt(CALC_FBOFFSET(giwr.x,giwr.y), 0,
+ giwr.w, blt_height, ImgLnsBuffers, pGeode->AccelPitch);
+#endif
+ giwr.h -= blt_height;
+ giwr.y += blt_height;
+}
+
+/* LX_SCANLINE_SUPPORT */
+#endif
+
+#if LX_CPU2SCREXP_SUPPORT
+/*----------------------------------------------------------------------------
+ * LXSetupForScanlineCPUToScreenColorExpandFill
+ *
+ * Description :SetupFor/Subsequent CPUToScreenColorExpandFill and
+ * ColorExpandScanline routines provide an interface for
+ * doing expansion blits from source patterns stored in
+ * system memory.
+ *
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ * fg int foreground color
+ * bg int -1 (transparent) or background color
+ * rop int unmapped raster operation
+ * planemask uint -1 (copy) or pattern data
+ *
+ * Returns :none.
+ *---------------------------------------------------------------------------*/
+
+static void
+LXSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrni,
+ int fg, int bg, int rop,
+ uint planemask)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ DBLOG(2,"LXSetupForScanlineCPUToScreenColorExpandFill() fg %#x bg %#x rop %#x %#x\n",
+ fg,bg,rop,planemask);
+ rop &= 0x0F;
+ gp_declare_blt(0);
+ if( planemask == ~0U ) {
+ gp_set_raster_operation(ROP=SDfn[rop]);
+ }
+ else {
+ gp_set_raster_operation(ROP=SDfn_PM[rop]);
+ gp_set_solid_pattern(planemask);
+ }
+ gp_set_mono_source(bg, fg, (bg == -1));
+ gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch);
+ gp_write_parameters();
+ gc2s.bpp = 1;
+ gc2s.transparent = 0;
+ gc2s.color = 0;
+}
+
+/*----------------------------------------------------------------------------
+ * LXSubsequentScanlineCPUToScreenColorExpandFill
+ *
+ * Description :see LXSetupForScanlineCPUToScreenColorExpandFill
+ *
+ * Parameters:
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ * x int destination x offset
+ * y int destination y offset
+ * w int fill area width (pixels)
+ * h int fill area height (pixels)
+ *
+ * Returns :none
+ *
+ *---------------------------------------------------------------------------*/
+static void
+LXSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrni,
+ int x, int y, int w, int h, int skipleft)
+{
+ DBLOG(2,"LXSubsequentScanlineCPUToScreenColorExpandFill() %d,%d %dx%d %d\n",
+ x,y,w,h,skipleft);
+ gc2s.x = x; gc2s.y = y;
+ gc2s.w = w; gc2s.h = h;
+}
+
+/*----------------------------------------------------------------------------
+ * LXSubsequentColorExpandScanline
+ *
+ * Description :see LXSetupForScanlineCPUToScreenColorExpandFill
+ *
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ * bufno int scanline number in write group
+ *
+ * Returns :none
+*----------------------------------------------------------------------------
+*/
+static void
+LXSubsequentColorExpandScanline(ScrnInfoPtr pScrni, int bufno)
+{
+ GeodePtr pGeode;
+ ulong srcpitch;
+ int blt_height = 0;
+ DBLOG(3,"LXSubsequentColorExpandScanline() %d\n",bufno);
+ pGeode = GEODEPTR(pScrni);
+
+ if( (blt_height=pGeode->NoOfImgBuffers) > gc2s.h )
+ blt_height = gc2s.h;
+ if( ++bufno < blt_height ) return;
+
+ gp_declare_blt(ENABLE_PREFETCH);
+ /* convert from bits to dwords */
+ srcpitch = ((pGeode->AccelPitch+31) >> 5) << 2;
+ gp_mono_bitmap_to_screen_blt(CALC_FBOFFSET(gc2s.x,gc2s.y), 0, gc2s.w,blt_height,
+ ClrLnsBuffers,srcpitch);
+ gc2s.h -= blt_height;
+ gc2s.y += blt_height;
+}
+
+/* LX_CPU2SCREXP_SUPPORT */
+#endif
+
+#if LX_SCR2SCREXP_SUPPORT
+
+/*----------------------------------------------------------------------------
+ * LXSetupForScreenToScreenColorExpandFill
+ *
+ * Description :SetupFor/Subsequent ScreenToScreenColorExpandFill and
+ * ColorExpandScanline routines provide an interface for
+ * doing expansion blits from source patterns stored in
+ * video memory.
+ *
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ * fg int foreground color
+ * bg int -1 (transparent) or background color
+ * rop int unmapped raster operation
+ * planemask uint -1 (copy) or pattern data
+ *
+ * Returns :none.
+ *---------------------------------------------------------------------------*/
+
+static void
+LXSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrni, int fg, int bg,
+ int rop, uint planemask)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ DBLOG(2,"LXSetupForScreenToScreenColorExpandFill() fg %#x bg %#x rop %#x %#x\n",
+ fg,bg,rop,planemask);
+ rop &= 0x0F;
+ gp_declare_blt(0);
+ if( planemask == ~0U ) {
+ gp_set_raster_operation(ROP=SDfn[rop]);
+ }
+ else {
+ gp_set_raster_operation(ROP=SDfn_PM[rop]);
+ gp_set_solid_pattern(planemask);
+ }
+ gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch);
+ gp_set_mono_source(bg, fg, (bg == -1));
+ gp_write_parameters();
+}
+
+/*----------------------------------------------------------------------------
+ * LXSubsequentScreenToScreenColorExpandFill
+ *
+ * Description :see LXSetupForScreenToScreenColorExpandFill
+ *
+ * Parameters:
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ * x int destination x offset
+ * y int destination y offset
+ * w int fill area width (pixels)
+ * h int fill area height (pixels)
+ * offset int initial x offset
+ *
+ * Returns :none
+ *
+ *---------------------------------------------------------------------------*/
+static void
+LXSubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrni,
+ int x, int y, int w, int h,
+ int srcx, int srcy, int offset)
+{
+ int flags;
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ DBLOG(2,"LXSubsequentScreenToScreenColorExpandFill() %d,%d %dx%d %d,%d %d\n",
+ x,y,w,h,srcx,srcy,offset);
+ flags = lx_flags3(srcx,srcy,x,y,w,h);
+ gp_declare_blt(flags);
+ gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch);
+ gp_mono_expand_blt(CALC_FBOFFSET(x,y), CALC_FBOFFSET(srcx,srcy), offset, w,h, 0);
+}
+
+/* LX_SCR2SCREXP_SUPPORT */
+#endif
+
+#define VM_X_MAJOR 0
+#define VM_Y_MAJOR 1
+#define VM_MAJOR_INC 2
+#define VM_MAJOR_DEC 0
+#define VM_MINOR_INC 4
+#define VM_MINOR_DEC 0
+
+static ushort vmode[] = {
+ VM_X_MAJOR | VM_MAJOR_INC | VM_MINOR_INC, /* !XDECREASING !YDECREASING !YMAJOR */
+ VM_Y_MAJOR | VM_MAJOR_INC | VM_MINOR_INC, /* !XDECREASING !YDECREASING YMAJOR */
+ VM_X_MAJOR | VM_MAJOR_INC | VM_MINOR_DEC, /* !XDECREASING YDECREASING !YMAJOR */
+ VM_Y_MAJOR | VM_MAJOR_DEC | VM_MINOR_INC, /* !XDECREASING YDECREASING YMAJOR */
+ VM_X_MAJOR | VM_MAJOR_DEC | VM_MINOR_INC, /* XDECREASING !YDECREASING !YMAJOR */
+ VM_Y_MAJOR | VM_MAJOR_INC | VM_MINOR_DEC, /* XDECREASING !YDECREASING YMAJOR */
+ VM_X_MAJOR | VM_MAJOR_DEC | VM_MINOR_DEC, /* XDECREASING YDECREASING !YMAJOR */
+ VM_Y_MAJOR | VM_MAJOR_DEC | VM_MINOR_DEC, /* XDECREASING YDECREASING YMAJOR */
+};
+
+#define ABS(_val1, _val2) (((_val1) > (_val2)) ? ((_val1)-(_val2)) : ((_val2) - (_val1)))
+
+#if LX_BRES_LINE_SUPPORT
+/*----------------------------------------------------------------------------
+ * LXSetupForSolidLine
+ *
+ * Description :SetupForSolidLine and Subsequent HorVertLine TwoPointLine
+ * BresenhamLine provides an interface for drawing thin
+ * solid lines.
+ *
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ * color int foreground fill color
+ * rop int unmapped raster op
+ * planemask uint -1 (fill) or pattern data (not enabled)
+ *
+ * Returns :none
+*---------------------------------------------------------------------------*/
+static void
+LXSetupForSolidLine(ScrnInfoPtr pScrni,
+ int color, int rop, uint planemask)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ DBLOG(2,"LXSetupForSolidLine() %#x %#x %#x\n",color,rop,planemask);
+ rop &= 0x0F;
+ gp_declare_vector(CIMGP_BLTFLAGS_HAZARD);
+ if( planemask == ~0U ) {
+ gp_set_raster_operation(ROP=PDfn[rop]);
+ }
+ else {
+ gp_set_raster_operation(ROP=PDfn_SM[rop]);
+ gp_set_solid_source(planemask);
+ }
+ gp_set_solid_pattern((ulong)color);
+ gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch);
+ gp_write_parameters();
+}
+
+/*---------------------------------------------------------------------------
+ * LXSubsequentSolidBresenhamLine
+ *
+ * Description :see LXSetupForSolidLine
+ *
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ * x1 int destination x offset
+ * y1 int destination y offset
+ * absmaj int Bresenman absolute major
+ * absmin int Bresenman absolute minor
+ * err int Bresenman initial error term
+ * len int length of the vector (pixels)
+ * octant int specifies sign and magnitude relationships
+ * used to determine axis of magor rendering
+ * and direction of vector progress.
+ *
+ * Returns :none
+ *
+ * - Window outlines on window move.
+ * - x11perf: line segments (-line500).
+ * - x11perf: line segments (-seg500).
+ *---------------------------------------------------------------------------*/
+static void
+LXSubsequentSolidBresenhamLine(ScrnInfoPtr pScrni, int x1, int y1,
+ int absmaj, int absmin, int err,
+ int len, int octant)
+{
+ int x2, y2, flags;
+ long axial, diagn;
+ DBLOG(2,"LXSubsequentSolidBresenhamLine() %d,%d %d %d, %d %d, %d\n",
+ x1,y1,absmaj,absmin,err,len,octant);
+ if( len <= 0 ) return;
+ lx_endpt(x1,y1,len,absmaj,absmin,err,octant,&x2,&y2);
+ flags = lx_flags2(x1,y1,x2+1,y2+1);
+ gp_declare_vector(flags);
+ axial = absmin;
+ err += axial;
+ diagn = absmin-absmaj;
+ gp_bresenham_line(CALC_FBOFFSET(x1,y1), len, err, axial, diagn, vmode[octant]);
+}
+
+/*---------------------------------------------------------------------------
+ * LXSubsequentSolidTwoPointLine
+ *
+ * Description :see LXSetupForSolidLine
+ *
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ * x0 int destination x start offset
+ * y0 int destination y start offset
+ * x1 int destination x end offset
+ * y1 int destination y end offset
+ * flags int OMIT_LAST, dont draw last pixel (not used)
+ *
+ * Returns :none
+ *---------------------------------------------------------------------------*/
+static void
+LXSubsequentSolidTwoPointLine(ScrnInfoPtr pScrni, int x0, int y0,
+ int x1, int y1, int flags)
+{
+ long dx, dy, dmaj, dmin, octant, bias;
+ long axial, diagn, err, len;
+ DBLOG(2,"LXSubsequentSolidTwoPointLine() %d,%d %d,%d, %#x\n",
+ x0,y0,x1,y1,flags);
+
+ if( (dx=x1-x0) < 0 ) dx = -dx;
+ if( (dy=y1-y0) < 0 ) dy = -dy;
+ if( dy >= dx ) {
+ dmaj = dy; dmin = dx;
+ octant = YMAJOR;
+ }
+ else {
+ dmaj = dx; dmin = dy;
+ octant = 0;
+ }
+ len = dmaj;
+ if( (flags&OMIT_LAST) == 0 ) ++len;
+ if( len <= 0 ) return;
+ if (x1 < x0) octant |= XDECREASING;
+ if (y1 < y0) octant |= YDECREASING;
+
+ flags = lx_flags2(x0,y0,x1+1,y1+1);
+ gp_declare_vector(flags);
+ axial = dmin << 1;
+ bias = miGetZeroLineBias(pScrni->pScreen);
+ err = axial - dmaj - ((bias>>octant) & 1);
+ diagn = (dmin-dmaj) << 1;
+ gp_bresenham_line(CALC_FBOFFSET(x0,y0), len, err, axial, diagn, vmode[octant]);
+}
+
+/*---------------------------------------------------------------------------
+ * LXSubsequentSolidHorVertLine
+ *
+ * Description :see LXSetupForSolidLine
+ *
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ * x int destination x offset
+ * y int destination y offset
+ * len int length of the vector (pixels)
+ * dir int DEGREES_270 or DEGREES_0 line direction
+ *
+ * Sample application uses:
+ * - Window outlines on window move.
+ * - x11perf: line segments (-hseg500).
+ * - x11perf: line segments (-vseg500).
+ *---------------------------------------------------------------------------
+ */
+static void
+LXSubsequentSolidHorVertLine(ScrnInfoPtr pScrni,
+ int x, int y, int len, int dir)
+{
+ int flags, w, h;
+ DBLOG(2,"LXSubsequentHorVertLine() %d,%d %d %d\n",x,y,len,dir);
+ gp_declare_blt(0);
+ if( dir == DEGREES_0 ) {
+ w = len; h = 1;
+ }
+ else {
+ w = 1; h = len;
+ }
+ flags = lx_flags1(x,y,w,h);
+ gp_declare_blt(flags);
+ gp_pattern_fill(CALC_FBOFFSET(x,y),
+ ((dir == DEGREES_0) ? len : 1),
+ ((dir == DEGREES_0) ? 1 : len));
+}
+
+/* LX_BRES_LINE_SUPPORT */
+#endif
+
+#if LX_DASH_LINE_SUPPORT
+/*----------------------------------------------------------------------------
+ * LXSetupForDashedLine
+ *
+ * Description :SetupForDashedLine and Subsequent TwoPointLine
+ * BresenhamLine provides an interface for drawing thin
+ * dashed lines.
+ *
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ * fg int foreground fill color
+ * bg int -1 (transp) or background fill color
+ * rop int unmapped raster op
+ * planemask uint -1 (fill) or pattern data (not enabled)
+ * length int pattern length (bits)
+ * pattern uchar* dash pattern mask
+ *
+ * Returns :none
+*---------------------------------------------------------------------------*/
+static void
+LXSetupForDashedLine(ScrnInfoPtr pScrni,
+ int fg, int bg, int rop, uint planemask,
+ int length, uchar *pattern)
+{
+ int n;
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ DBLOG(2,"LXSetupForDashedLine() fg %#x bg %#x rop %#x pm %#x len %d, pat %#x\n",
+ fg,bg,rop,planemask,length,*(ulong*)pattern);
+ gdln.fg = fg;
+ gdln.bg = bg;
+ gdln.len = length;
+ n = (length+7)/8;
+ if( n > sizeof(gdln.pat) )
+ n = sizeof(gdln.pat);
+ memcpy(&gdln.pat,pattern,n);
+ rop &= 0x0F;
+ gp_declare_vector(CIMGP_BLTFLAGS_HAZARD);
+ if( planemask == ~0U ) {
+ gp_set_raster_operation(ROP=PDfn[rop]);
+ }
+ else {
+ gp_set_raster_operation(ROP=PDfn_SM[rop]);
+ gp_set_solid_source(planemask);
+ }
+ gp_set_strides(pGeode->AccelPitch, pGeode->AccelPitch);
+ gp_write_parameters();
+}
+
+/*---------------------------------------------------------------------------
+ * LXSubsequentDashedBresenhamLine
+ *
+ * Description :see LXSetupForDashedLine
+ *
+ * Arg Type Comment
+ * pScrni ScrnInfoPtr pointer to Screeen info
+ * x1 int destination x offset
+ * y1 int destination y offset
+ * absmaj int Bresenman absolute major
+ * absmin int Bresenman absolute minor
+ * err int Bresenman initial error term
+ * len int length of the vector (pixels)
+ * octant int specifies sign and magnitude relationships
+ * used to determine axis of magor rendering
+ * and direction of vector progress.
+ * phase int initial pattern offset at x1,y1
+ *
+ * Returns :none
+ *---------------------------------------------------------------------------*/
+static void
+LXSubsequentDashedBresenhamLine(ScrnInfoPtr pScrni, int x1, int y1,
+ int absmaj, int absmin, int err,
+ int len, int octant, int phase)
+{
+ int x2, y2, flags;
+ long axial, diagn;
+ ulong pattern;
+ DBLOG(2,"LXSubsequentDashedBresenhamLine() %d,%d %d %d, %d %d, %d %d\n",
+ x1,y1,absmaj,absmin,err,len,octant,phase);
+ if( len <= 0 ) return;
+ pattern = gdln.pat;
+ if( phase > 0 ) {
+ int n = gdln.len-phase;
+ pattern = ((pattern>>phase)&((1UL<= dx ) {
+ dmaj = dy; dmin = dx;
+ octant = YMAJOR;
+ }
+ else {
+ dmaj = dx; dmin = dy;
+ octant = 0;
+ }
+ len = dmaj;
+ if( (flags&OMIT_LAST) == 0 ) ++len;
+ if( len <= 0 ) return;
+ if (x1 < x0) octant |= XDECREASING;
+ if (y1 < y0) octant |= YDECREASING;
+
+ pattern = gdln.pat;
+ if( phase > 0 ) {
+ int n = gdln.len-phase;
+ pattern = ((pattern>>phase)&((1UL<pScreen);
+ err = axial-dmaj - ((bias>>octant) & 1);
+ diagn = (dmin-dmaj) << 1;
+ gp_bresenham_line(CALC_FBOFFSET(x0,y0), len, err, axial, diagn, vmode[octant]);
+}
+
+/* LX_DASH_LINE_SUPPORT */
+#endif
+
+#if LX_WRITE_PIXMAP_SUPPORT
+void
+LXWritePixmap(ScrnInfoPtr pScrni, int x, int y, int w, int h, unsigned char *src, int srcwidth,
+ int rop, unsigned int planemask, int trans, int bpp, int depth)
+{
+ int flags, dx, dy;
+ int Bpp = (bpp+7) >> 3;
+ unsigned long offset;
+ GeodePtr pGeode = GEODEPTR(pScrni);
+
+ DBLOG(2,"LXWritePixmap() %d,%d %dx%d, s%#x sp%d %#x %#x %#x %d %d\n",
+ x,y, w,h, src, srcwidth, rop, planemask, trans,bpp,depth);
+
+ rop &= 0x0F;
+ gp_set_source_format(lx_src_fmt[Bpp-1]);
+ /* must assign before lx_flags */
+ ROP = planemask == ~0U ? SDfn[rop] : SDfn_PM[rop];
+
+ if( src >= pGeode->FBBase && src < pGeode->FBBase+pGeode->FBSize ) {
+ offset = src-pGeode->FBBase;
+ dx = (offset & ((1<> Bpp;
+ dy = offset >> gu3_yshift;
+ flags = lx_flags3(x,y,dx,dy,w,h);
+ }
+ else
+ flags = ENABLE_PREFETCH;
+
+ gp_declare_blt(flags);
+ gp_set_raster_operation(ROP);
+ if( planemask != ~0U )
+ gp_set_solid_pattern(planemask);
+ gp_set_strides(pGeode->AccelPitch,pGeode->AccelPitch);
+ if( trans != -1 ) {
+ gp_set_source_transparency(trans,~0);
+ }
+
+ gp_color_bitmap_to_screen_blt(CALC_FBOFFSET(x,y), 0, w,h, src, srcwidth);
+ SET_SYNC_FLAG(pGeode->AccelInfoRec);
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * LXAccelInit.
+ *
+ * Description :Create and initialize XAAInfoRec structure.
+ * The XAAInfoRec structure contains many fields, most of
+ * which are primitive function pointers and flags. Each
+ * primitive will have two or more functions and a set of
+ * associated associated flags. These functions can be
+ * classified into two principle classes, the "SetupFor"
+ * and "Subsequent" functions. The "SetupFor" function tells
+ * the driver that the hardware should be initialized for
+ * a particular type of graphics operation. After the
+ * "SetupFor" function, one or more calls to the "Subsequent"
+ * function will be made to indicate that an instance of the
+ * particular primitive should be rendered by the hardware.
+ *
+ * Arg Type Comment
+ * pScrn ScreenPtr pointer to active Screen data
+ *
+ * Returns :TRUE on success and FALSE on Failure
+ *
+ * Comments :This function is called in LXScreenInit in
+ * amd_lx_driver.c to initialize acceleration.
+ *---------------------------------------------------------------------------*/
+Bool
+LXAccelInit(ScreenPtr pScrn)
+{
+ GeodePtr pGeode;
+ ScrnInfoPtr pScrni;
+#if DEBUGLVL>0
+ if( zdfp == NULL ) { zdfp = fopen("/tmp/xwin.log","w"); setbuf(zdfp,NULL); }
+#endif
+ DBLOG(2,"LXAccelInit()\n");
+
+ pScrni = xf86Screens[pScrn->myNum];
+ pGeode = GEODEPTR(pScrni);
+
+ switch (pScrni->bitsPerPixel) {
+ case 8:
+ gu3_img_fmt = CIMGP_SOURCE_FMT_3_3_2;
+ break;
+ case 16:
+ gu3_img_fmt = CIMGP_SOURCE_FMT_0_5_6_5;
+ break;
+ case 32:
+ gu3_img_fmt = CIMGP_SOURCE_FMT_8_8_8_8;
+ break;
+ }
+
+ gu3_xshift = pScrni->bitsPerPixel >> 4;
+
+ switch (pGeode->AccelPitch) {
+ case 1024:
+ gu3_yshift = 10;
+ break;
+ case 2048:
+ gu3_yshift = 11;
+ break;
+ case 4096:
+ gu3_yshift = 12;
+ break;
+ case 8192:
+ gu3_yshift = 13;
+ break;
+ }
+
+ /* Getting the pointer for acceleration Inforecord */
+ pGeode->AccelInfoRec = localRecPtr = XAACreateInfoRec();
+
+ /* SET ACCELERATION FLAGS */
+ localRecPtr->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER;
+
+ /* HOOK SYNCRONIZARION ROUTINE */
+ localRecPtr->Sync = LXAccelSync;
+
+#if LX_FILL_RECT_SUPPORT
+ /* HOOK FILLED RECTANGLES */
+ HOOK(SetupForSolidFill);
+ HOOK(SubsequentSolidFillRect);
+ localRecPtr->SolidFillFlags = 0;
+#endif
+
+#if LX_MONO_8X8_PAT_SUPPORT
+ /* HOOK 8x8 Mono EXPAND PATTERNS */
+ HOOK(SetupForMono8x8PatternFill);
+ HOOK(SubsequentMono8x8PatternFillRect);
+ localRecPtr->Mono8x8PatternFillFlags =
+ BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD |
+ HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_PROGRAMMED_ORIGIN;
+#endif
+
+#if LX_CLREXP_8X8_PAT_SUPPORT
+ /* Color expansion */
+ HOOK(SetupForColor8x8PatternFill);
+ HOOK(SubsequentColor8x8PatternFillRect);
+ localRecPtr->Color8x8PatternFillFlags =
+ BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY |
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN;
+#endif
+
+#if LX_SCR2SCRCPY_SUPPORT
+ /* HOOK SCREEN TO SCREEN COPIES
+ * Set flag to only allow copy if transparency is enabled.
+ */
+ HOOK(SetupForScreenToScreenCopy);
+ HOOK(SubsequentScreenToScreenCopy);
+ localRecPtr->ScreenToScreenCopyFlags =
+ BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
+#endif
+
+#if LX_BRES_LINE_SUPPORT
+ /* HOOK BRESENHAM SOLID LINES */
+ localRecPtr->SolidLineFlags = NO_PLANEMASK;
+ HOOK(SetupForSolidLine);
+ HOOK(SubsequentSolidBresenhamLine);
+ HOOK(SubsequentSolidHorVertLine);
+ HOOK(SubsequentSolidTwoPointLine);
+ localRecPtr->SolidBresenhamLineErrorTermBits = 15;
+#endif
+
+#if LX_DASH_LINE_SUPPORT
+ /* HOOK BRESENHAM DASHED LINES */
+ localRecPtr->DashedLineFlags = NO_PLANEMASK | TRANSPARENCY_ONLY |
+ LINE_PATTERN_LSBFIRST_LSBJUSTIFIED | SCANLINE_PAD_DWORD;
+ HOOK(SetupForDashedLine);
+ HOOK(SubsequentDashedBresenhamLine);
+ HOOK(SubsequentDashedTwoPointLine);
+ localRecPtr->DashedBresenhamLineErrorTermBits = 15;
+ localRecPtr->DashPatternMaxLength = 32;
+#endif
+
+#if LX_SCR2SCREXP_SUPPORT
+ /* Color expansion */
+ HOOK(SetupForScreenToScreenColorExpandFill);
+ HOOK(SubsequentScreenToScreenColorExpandFill);
+ localRecPtr->ScreenToScreenColorExpandFillFlags =
+ BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
+#endif
+
+ if (pGeode->AccelImageWriteBuffers) {
+#if LX_SCANLINE_SUPPORT
+ localRecPtr->ScanlineImageWriteBuffers = pGeode->AccelImageWriteBuffers;
+ localRecPtr->NumScanlineImageWriteBuffers = pGeode->NoOfImgBuffers;
+ HOOK(SetupForScanlineImageWrite);
+ HOOK(SubsequentScanlineImageWriteRect);
+ HOOK(SubsequentImageWriteScanline);
+ localRecPtr->ScanlineImageWriteFlags =
+ BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
+#endif
+#if !LX_USE_OFFSCRN_MEM
+ ImgBufOffset = pGeode->AccelImageWriteBuffers[0] - pGeode->FBBase;
+#else
+ ImgLnsBuffers = (uchar *)pGeode->AccelImageWriteBuffers[0];
+#endif
+
+ } else {
+ localRecPtr->PixmapCacheFlags = DO_NOT_BLIT_STIPPLES;
+ }
+
+ if (pGeode->AccelColorExpandBuffers) {
+#if LX_CPU2SCREXP_SUPPORT
+ /* Color expansion */
+ localRecPtr->ScanlineColorExpandBuffers = pGeode->AccelColorExpandBuffers;
+ localRecPtr->NumScanlineColorExpandBuffers = pGeode->NoOfColorExpandLines;
+ HOOK(SetupForScanlineCPUToScreenColorExpandFill);
+ HOOK(SubsequentScanlineCPUToScreenColorExpandFill);
+ HOOK(SubsequentColorExpandScanline);
+ localRecPtr->ScanlineCPUToScreenColorExpandFillFlags =
+ BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD;
+#endif
+ ClrLnsBuffers = (uchar *)pGeode->AccelColorExpandBuffers[0];
+ }
+
+#if LX_WRITE_PIXMAP_SUPPORT
+ HOOK(WritePixmap);
+#endif
+
+
+ return (XAAInit(pScrn, localRecPtr));
+}
+
+/* END OF FILE */
diff -urN xf86-video-nsc-2.8.1-orig/src/amd_lx_cursor.c xf86-video-nsc-2.8.1/src/amd_lx_cursor.c
--- xf86-video-nsc-2.8.1-orig/src/amd_lx_cursor.c 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/amd_lx_cursor.c 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,392 @@
+/*
+ * $Workfile: amd_lx_cursor.c $
+ * $Revision: #4 $
+ * $Author: raymondd $
+ *
+ * File Contents: Xfree cursor implementation routines
+ * for geode HWcursor init.setting cursor color,image etc
+ * are done here.
+ * Project: Geode Xfree Frame buffer device driver.
+ *
+ */
+
+/*
+ * Copyright (c) 2003-2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice 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.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+/*
+ * */
+/*
+ * */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "nsc.h"
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+
+/* Forward declarations of the functions */
+Bool LXHWCursorInit(ScreenPtr pScrn);
+static void LXSetCursorColors(ScrnInfoPtr pScrni, int bg, int fg);
+static void LXSetCursorPosition(ScrnInfoPtr pScrni, int x, int y);
+void LXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src);
+void LXHideCursor(ScrnInfoPtr pScrni);
+void LXShowCursor(ScrnInfoPtr pScrni);
+static Bool LXUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs);
+extern void LXSetVideoPosition(int x, int y, int width, int height,
+ short src_w, short src_h, short drw_w,
+ short drw_h, int id, int offset,
+ ScrnInfoPtr pScrni);
+#ifdef ARGB_CURSOR
+static Bool LXUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs);
+static void LXLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs);
+#endif
+
+/*----------------------------------------------------------------------------
+ * LXHWCursorInit.
+ *
+ * Description :This function sets the cursor information by probing the
+ * hardware.
+ *
+ * Parameters.
+ * pScrn :Screeen pointer structure.
+ *
+ * Returns :TRUE on success and FALSE on Failure
+ *
+ * Comments :Geode supports the hardware_cursor,no need to enable SW
+ * cursor.
+*----------------------------------------------------------------------------
+*/
+Bool
+LXHWCursorInit(ScreenPtr pScrn)
+{
+ ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum];
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ xf86CursorInfoPtr infoPtr;
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if (!infoPtr)
+ return FALSE;
+ /* the geode structure is intiallized with the cursor infoRec */
+ pGeode->CursorInfo = infoPtr;
+ infoPtr->MaxWidth = 32;
+ infoPtr->MaxHeight = 32;
+ /* seeting up the cursor flags */
+ infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED;
+ /* cursor info ptr is intiallized with the values obtained from
+ * * durnago calls
+ */
+ infoPtr->SetCursorColors = LXSetCursorColors;
+ infoPtr->SetCursorPosition = LXSetCursorPosition;
+ infoPtr->LoadCursorImage = LXLoadCursorImage;
+ infoPtr->HideCursor = LXHideCursor;
+ infoPtr->ShowCursor = LXShowCursor;
+ infoPtr->UseHWCursor = LXUseHWCursor;
+#ifdef ARGB_CURSOR
+ infoPtr->UseHWCursorARGB = LXUseHWCursorARGB;
+ infoPtr->LoadCursorARGB = LXLoadCursorARGB;
+#endif
+
+ return (xf86InitCursor(pScrn, infoPtr));
+}
+
+/*----------------------------------------------------------------------------
+ * LXSetCursorColors.
+ *
+ * Description :This function sets the cursor foreground and background
+ * colors
+ * Parameters:
+ * pScrni: Screeen information pointer structure.
+ * bg: Specifies the color value of cursor background color.
+ * fg: Specifies the color value of cursor foreground color.
+ * Returns: none.
+ *
+ * Comments: The integer color value passed by this function is
+ * converted into * RGB value by the gfx_set_color routines.
+ *----------------------------------------------------------------------------
+ */
+static void
+LXSetCursorColors(ScrnInfoPtr pScrni, int bg, int fg)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+
+#ifdef ARGB_CURSOR
+ /* Don't recolour cursors set with SetCursorARGB. */
+ if (pGeode->cursor_argb)
+ return;
+#endif
+
+ vg_set_mono_cursor_colors(bg, fg);
+}
+
+/*----------------------------------------------------------------------------
+ * LXSetCursorPosition.
+ *
+ * Description :This function sets the cursor co -ordinates and enable the
+ * cursor.
+ *
+ * Parameters:
+ * pScrni: Screeen information pointer structure.
+ * x: Specifies the x-cordinates of the cursor.
+ * y: Specifies the y co-ordinate of the cursor.
+ * Returns: none.
+ *
+ *----------------------------------------------------------------------------
+ */
+static void
+LXSetCursorPosition(ScrnInfoPtr pScrni, int x, int y)
+{
+ static unsigned long panOffset = 0;
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ int newX, newY;
+
+ (*pGeode->Rotation)(x,y,pGeode->HDisplay,pGeode->VDisplay,&newX,&newY);
+ (*pGeode->RBltXlat)(newX,newY,32,32,&newX,&newY);
+ if (newX < -31) newX = -31;
+ if (newY < -31) newY = -31;
+
+ { VG_PANNING_COORDINATES panning;
+ vg_set_cursor_position(newX+31, newY+31, &panning); }
+ vg_set_cursor_enable(1);
+
+#ifndef AMD_V4L2_VIDEO
+ if ((pGeode->OverlayON) && (pGeode->EnabledOutput & LX_OT_FP)) {
+ pGeode->PrevDisplayOffset = vg_get_display_offset();
+ if (pGeode->PrevDisplayOffset != panOffset) {
+ LXSetVideoPosition(pGeode->video_x, pGeode->video_y,
+ pGeode->video_w, pGeode->video_h,
+ pGeode->video_srcw, pGeode->video_srch,
+ pGeode->video_dstw, pGeode->video_dsth,
+ pGeode->video_id, pGeode->video_offset,
+ pGeode->video_scrnptr);
+ panOffset = pGeode->PrevDisplayOffset;
+ }
+ }
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * LXLoadCursorImage
+ *
+ * Description :This function loads the 32x32 cursor pattern.The shape
+ * and color is set by AND and XOR masking of arrays of 32
+ * DWORD.
+ * Parameters:
+ * pScrni: Screeen information pointer structure.
+ * src : Specifies cursor data.
+ * Returns : none
+ *
+ *----------------------------------------------------------------------------
+*/
+void
+LXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src)
+{
+ int i, n, x, y, newX, newY;
+ unsigned long andMask[32], xorMask[32];
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ unsigned long mskb, rowb;
+ unsigned char *rowp = &src[0];
+ unsigned char *mskp = &src[128];
+
+ if( src != NULL ) {
+ mskb = rowb = 0;
+ for( y=32; --y>=0; )
+ andMask[y] = xorMask[y] = 0;
+ for( y=0; y<32; ++y ) {
+ for( x=0; x<32; ++x ) {
+ if( (i=x&7) == 0 ) {
+ rowb = (*rowp & *mskp);
+ mskb = ~(*mskp);
+ ++rowp; ++mskp;
+ }
+ (*pGeode->Rotation)(x,y,32,32,&newX,&newY);
+ i = 7-i; n = 31-newX;
+ andMask[newY] |= (((mskb>>i)&1)<>i)&1)<=0; ) {
+ andMask[y] = ~0;
+ xorMask[y] = 0;
+ }
+ }
+
+#ifdef ARGB_CURSOR
+ pGeode->cursor_argb = FALSE;
+#endif
+
+
+#if 0
+ andMask[31] = 0;
+ xorMask[31] = 0;
+ for( y=31; --y>0; ) {
+ andMask[y] &= ~0x80000001;
+ xorMask[y] &= ~0x80000001;
+ }
+ andMask[0] = 0;
+ xorMask[0] = 0;
+#endif
+
+ vg_set_mono_cursor_shape32(pGeode->CursorStartOffset,&andMask[0],&xorMask[0],31,31);
+}
+
+/*----------------------------------------------------------------------------
+ * LXHideCursor
+ *
+ * Description :This function will disable the cursor.
+ *
+ * Parameters:
+ * pScrni: Handles to the Screeen information pointer structure.
+ *
+ * Returns: none.
+ *
+ * Comments: gfx_set_cursor enable function is hardcoded to disable
+ * the cursor.
+ *----------------------------------------------------------------------------
+ */
+void
+LXHideCursor(ScrnInfoPtr pScrni)
+{
+ vg_set_cursor_enable(0);
+}
+
+/*----------------------------------------------------------------------------
+ * LXShowCursor
+ *
+ * Description :This function will enable the cursor.
+ *
+ * Parameters:
+ * pScrni :Handles to the Screeen information pointer structure.
+ *
+ * Returns :none
+ *
+ * Comments :gfx_set_cursor enable function is hardcoded to enable the
+ * cursor
+ *----------------------------------------------------------------------------
+*/
+void
+LXShowCursor(ScrnInfoPtr pScrni)
+{
+ vg_set_cursor_enable(1);
+}
+
+/*----------------------------------------------------------------------------
+ * LXUseHwCursor.
+ *
+ * Description :This function will sets the hardware cursor flag in
+ * pscreen structure.
+ *
+ * Parameters.
+ * pScreen :Handles to the Screeen pointer structure.
+ *
+ * Returns :none
+ *
+ * Comments :none
+ *
+ *----------------------------------------------------------------------------
+*/
+static Bool
+LXUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs)
+{
+ ScrnInfoPtr pScrni = XF86SCRNINFO(pScrn);
+
+ if (pScrni->currentMode->Flags & V_DBLSCAN)
+ return FALSE;
+ return TRUE;
+}
+
+#ifdef ARGB_CURSOR
+#include "cursorstr.h"
+
+/* Determine if hardware cursor is in use. */
+static Bool LXUseHWCursorARGB (ScreenPtr pScrn, CursorPtr pCurs)
+{
+ ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum];
+ GeodePtr pGeode = GEODEPTR(pScrni);
+
+ if (LXUseHWCursor(pScrn, pCurs) &&
+ pCurs->bits->height <= HW_ARGB_CURSOR_H &&
+ pCurs->bits->width <= HW_ARGB_CURSOR_W)
+ return TRUE;
+ return FALSE;
+}
+
+static void LXLoadCursorARGB (ScrnInfoPtr pScrni, CursorPtr pCurs)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+
+ int x, y, w, h, newX,newY, newW, newH;
+ CARD32 *image = pCurs->bits->argb;
+ CARD32 rotated_image[HW_ARGB_CURSOR_W * HW_ARGB_CURSOR_H];
+
+ if (!image)
+ return; /* XXX can't happen */
+
+ w = pCurs->bits->width;
+ h = pCurs->bits->height;
+
+ switch( pGeode->Rotate )
+ {
+ case 1:
+ case 3:
+ newW=h;
+ newH=w;
+ break;
+ case 2:
+ default:
+ newW=w;
+ newH=h;
+ }
+
+ if (newW > HW_ARGB_CURSOR_W)
+ newW = HW_ARGB_CURSOR_W;
+ if (newH > HW_ARGB_CURSOR_H)
+ newH = HW_ARGB_CURSOR_H;
+
+ for (y=0;yRotation)(x,y,w,h,&newX,&newY);
+ rotated_image [newY*newW+newX] = image[y*w+x];
+ }
+
+ vg_set_color_cursor_shape (pGeode->CursorStartOffset,
+ (unsigned char*)rotated_image,
+ newW, newH, newW * 4 /*pitch*/, 31/*x_hot*/, 31/*y_hotspot*/);
+
+ pGeode->cursor_argb = TRUE;
+}
+
+#endif
+
+/* End of File */
diff -urN xf86-video-nsc-2.8.1-orig/src/amd_lx_dga.c xf86-video-nsc-2.8.1/src/amd_lx_dga.c
--- xf86-video-nsc-2.8.1-orig/src/amd_lx_dga.c 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/amd_lx_dga.c 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,416 @@
+/*
+ * $Workfile: amd_lx_dga.c $
+ * $Revision: #3 $
+ * $Author: raymondd $
+ *
+ * File contents: DGA(Direct Acess Graphics mode) is feature of
+ * XFree86 that allows the program to access directly to video
+ * memory on the graphics card.DGA supports the double
+ * flickering.This file has the functions to support the DGA
+ * modes.
+ *
+ * Project: Geode Xfree Frame buffer device driver.
+ *
+ */
+
+/*
+ * Copyright (c) 2003-2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice 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.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+/*
+ * */
+/*
+ * */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "nsc.h"
+#include "dgaproc.h"
+
+/* forward declarations */
+Bool LXDGAInit(ScreenPtr pScrn);
+static Bool LX_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
+ int *, int *, int *);
+static void LX_CloseFramebuffer(ScrnInfoPtr pScrni);
+static Bool LX_SetMode(ScrnInfoPtr, DGAModePtr);
+static int LX_GetViewport(ScrnInfoPtr);
+static void LX_SetViewport(ScrnInfoPtr, int, int, int);
+static void LX_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
+static void LX_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
+
+extern void LXAdjustFrame(int, int, int, int);
+extern Bool LXSwitchMode(int, DisplayModePtr, int);
+extern void LXAccelSync(ScrnInfoPtr pScrni);
+
+static DGAFunctionRec LXDGAFuncs = {
+ LX_OpenFramebuffer,
+ LX_CloseFramebuffer,
+ LX_SetMode,
+ LX_SetViewport,
+ LX_GetViewport,
+ LXAccelSync,
+ LX_FillRect,
+ LX_BlitRect,
+ NULL
+};
+
+/*----------------------------------------------------------------------------
+ * LXDGAInit.
+ *
+ * Description :This function is used to intiallize the DGA modes and sets the
+ viewport based on the screen mode.
+ * Parameters.
+ * pScreeen :Pointer to screen info structure.
+ *
+ * Returns :TRUE on success and FALSE on failure.
+ *
+ * Comments :This function prepares the DGA mode settings for
+ * other func reference.
+ *
+*----------------------------------------------------------------------------
+*/
+Bool
+LXDGAInit(ScreenPtr pScrn)
+{
+ ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum];
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ DGAModePtr modes = NULL, newmodes = NULL, currentMode;
+ DisplayModePtr pMode, firstMode;
+ int Bpp = pScrni->bitsPerPixel >> 3;
+ int num = 0;
+ Bool oneMore;
+
+ pMode = firstMode = pScrni->modes;
+ DEBUGMSG(0, (0, X_NONE, "LXDGAInit %d\n", Bpp));
+ while (pMode) {
+
+ /* redundant but it can be used in future:if(0). */
+ if (0) { /*pScrni->displayWidth != pMode->HDisplay */
+ /* memory is allocated for dga to
+ *setup the viewport and mode parameters
+ */
+ newmodes = xrealloc(modes, (num + 2) * sizeof(DGAModeRec));
+ oneMore = TRUE;
+ } else {
+ /* one record is allocated here */
+ newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec));
+ oneMore = FALSE;
+ }
+ if (!newmodes) {
+ xfree(modes);
+ return FALSE;
+ }
+ modes = newmodes;
+
+ SECOND_PASS: /* DGA mode flgas and viewport parametrs are set here. */
+
+ currentMode = modes + num;
+ num++;
+ currentMode->mode = pMode;
+ currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;
+ currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
+ if (pMode->Flags & V_DBLSCAN)
+ currentMode->flags |= DGA_DOUBLESCAN;
+ if (pMode->Flags & V_INTERLACE)
+ currentMode->flags |= DGA_INTERLACED;
+ currentMode->byteOrder = pScrni->imageByteOrder;
+ currentMode->depth = pScrni->depth;
+ currentMode->bitsPerPixel = pScrni->bitsPerPixel;
+ currentMode->red_mask = pScrni->mask.red;
+ currentMode->green_mask = pScrni->mask.green;
+ currentMode->blue_mask = pScrni->mask.blue;
+ currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor;
+ currentMode->viewportWidth = pMode->HDisplay;
+ currentMode->viewportHeight = pMode->VDisplay;
+ currentMode->xViewportStep = 1;
+ currentMode->yViewportStep = 1;
+ currentMode->viewportFlags = DGA_FLIP_RETRACE;
+ currentMode->offset = 0;
+ currentMode->address = pGeode->FBBase;
+ if (oneMore) { /* first one is narrow width */
+ currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L;
+ currentMode->imageWidth = pMode->HDisplay;
+ currentMode->imageHeight = pMode->VDisplay;
+ currentMode->pixmapWidth = currentMode->imageWidth;
+ currentMode->pixmapHeight = currentMode->imageHeight;
+ currentMode->maxViewportX = currentMode->imageWidth -
+ currentMode->viewportWidth;
+ /* this might need to get clamped to some maximum */
+ currentMode->maxViewportY = currentMode->imageHeight -
+ currentMode->viewportHeight;
+ oneMore = FALSE;
+ goto SECOND_PASS;
+ } else {
+ currentMode->bytesPerScanline =
+ ((pScrni->displayWidth * Bpp) + 3) & ~3L;
+ currentMode->imageWidth = pScrni->displayWidth;
+ currentMode->imageHeight = pMode->VDisplay;
+ currentMode->pixmapWidth = currentMode->imageWidth;
+ currentMode->pixmapHeight = currentMode->imageHeight;
+ currentMode->maxViewportX = currentMode->imageWidth -
+ currentMode->viewportWidth;
+ /* this might need to get clamped to some maximum */
+ currentMode->maxViewportY = currentMode->imageHeight -
+ currentMode->viewportHeight;
+ }
+ pMode = pMode->next;
+ if (pMode == firstMode)
+ break;
+ }
+ pGeode->numDGAModes = num;
+ pGeode->DGAModes = modes;
+ return DGAInit(pScrn, &LXDGAFuncs, modes, num);
+}
+
+/*----------------------------------------------------------------------------
+ * LX_SetMode.
+ *
+ * Description :This function is sets into the DGA mode.
+ *.
+ * Parameters.
+ * pScreeen :Pointer to screen info structure.
+ * pMode :Points to the DGAmode ptr data
+ * Returns :TRUE on success and FALSE on failure.
+ *
+ * Comments :none.
+ *
+ *
+*----------------------------------------------------------------------------
+*/
+static Bool
+LX_SetMode(ScrnInfoPtr pScrni, DGAModePtr pMode)
+{
+ static int OldDisplayWidth[MAXSCREENS];
+ int index = pScrni->pScreen->myNum;
+ GeodePtr pGeode = GEODEPTR(pScrni);
+
+ DEBUGMSG(0, (0, X_NONE, "LX_SetMode\n"));
+
+ if (!pMode) {
+ /* restore the original mode
+ * * put the ScreenParameters back
+ */
+ pScrni->displayWidth = OldDisplayWidth[index];
+ DEBUGMSG(0,
+ (0, X_NONE, "LX_SetMode !pMode %d\n", pScrni->displayWidth));
+ LXSwitchMode(index, pScrni->currentMode, 0);
+ pGeode->DGAactive = FALSE;
+ } else {
+ if (!pGeode->DGAactive) { /* save the old parameters */
+ OldDisplayWidth[index] = pScrni->displayWidth;
+ pGeode->DGAactive = TRUE;
+ DEBUGMSG(0,
+ (0, X_NONE, "LX_SetMode pMode+ NA %d\n",
+ pScrni->displayWidth));
+ }
+ pGeode->PrevDisplayOffset = vg_get_display_offset();
+
+ pScrni->displayWidth = pMode->bytesPerScanline /
+ (pMode->bitsPerPixel >> 3);
+ DEBUGMSG(0,
+ (0, X_NONE, "LX_SetMode pMode+ %d\n", pScrni->displayWidth));
+ LXSwitchMode(index, pMode->mode, 0);
+ }
+ /* enable/disable Compression */
+ if (pGeode->Compression) {
+ vg_set_compression_enable(!pGeode->DGAactive);
+ }
+
+ /* enable/disable cursor */
+ if (pGeode->HWCursor) {
+ vg_set_cursor_enable(!pGeode->DGAactive);
+ }
+
+ return TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * LX_GetViewPort.
+ *
+ * Description :This function is Gets the viewport window memory.
+ *.
+ * Parameters.
+ * pScrni :Pointer to screen info structure.
+ *
+ * Returns :returns the viewport status.
+ *
+ * Comments :none.
+ *
+ *
+*----------------------------------------------------------------------------
+*/
+static int
+LX_GetViewport(ScrnInfoPtr pScrni)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+
+ return pGeode->DGAViewportStatus;
+}
+
+/*----------------------------------------------------------------------------
+ * LX_SetViewPort.
+ *
+ * Description :This function is Gets the viewport window memory.
+ *
+ * Parameters.
+ * pScrni :Pointer to screen info structure.
+ x :x-cordinate of viewport window
+ * y :y-codinate of the viewport window.
+ * flags :indicates the viewport to be flipped or not.
+ * Returns :returns the viewport status as zero.
+ *
+ * Comments :none.
+ *
+*----------------------------------------------------------------------------
+*/
+static void
+LX_SetViewport(ScrnInfoPtr pScrni, int x, int y, int flags)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+
+ LXAdjustFrame(pScrni->pScreen->myNum, x, y, flags);
+ pGeode->DGAViewportStatus = 0; /*LXAdjustFrame loops until finished */
+}
+
+/*----------------------------------------------------------------------------
+ * LX_FillRect.
+ *
+ * Description :This function is Gets the viewport window memory.
+ *.
+ * Parameters.
+ * pScrni :Pointer to screen info structure.
+ * x :x-cordinate of viewport window
+ * y :y-codinate of the viewport window.
+ * w :width of the rectangle
+ * h :height of the rectangle.
+ * color :color to be filled in rectangle.
+ *
+ * Returns :returns the viewport status as zero.
+ *
+ * Comments :This function is implemented by solidfill routines..
+ *
+*----------------------------------------------------------------------------
+*/
+static void
+LX_FillRect(ScrnInfoPtr pScrni, int x, int y,
+ int w, int h, unsigned long color)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+
+ if (pGeode->AccelInfoRec) {
+ (*pGeode->AccelInfoRec->SetupForSolidFill) (pScrni, color, GXcopy, ~0);
+ (*pGeode->AccelInfoRec->SubsequentSolidFillRect) (pScrni, x, y, w, h);
+ SET_SYNC_FLAG(pGeode->AccelInfoRec);
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * LX_BlitRect.
+ *
+ * Description :This function implementing Blit and it moves a
+ * Rectangular block of data from one location to other
+ * Location.
+ *
+ * Parameters.
+ * pScrni :Pointer to screen info structure.
+ * srcx :x-cordinate of the src rectangle
+ * srcy :y-codinate of src rectangle.
+ * w :width of the rectangle
+ * h :height of the rectangle.
+ * dstx :x-cordinate of the dst rectangle.
+ * dsty :y -coordinates of the dst rectangle.
+ * Returns :none.
+ *
+ * Comments :none
+ *
+*----------------------------------------------------------------------------
+*/
+static void
+LX_BlitRect(ScrnInfoPtr pScrni,
+ int srcx, int srcy, int w, int h, int dstx, int dsty)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+
+ if (pGeode->AccelInfoRec) {
+ int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
+ int ydir = (srcy < dsty) ? -1 : 1;
+
+ (*pGeode->AccelInfoRec->SetupForScreenToScreenCopy)
+ (pScrni, xdir, ydir, GXcopy, ~0, -1);
+ (*pGeode->AccelInfoRec->SubsequentScreenToScreenCopy) (pScrni, srcx,
+ srcy, dstx, dsty,
+ w, h);
+ SET_SYNC_FLAG(pGeode->AccelInfoRec);
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * LX_OpenFramebuffer.
+ *
+ * Description :This function open the framebuffer driver for DGA.
+ *
+ * Parameters.
+ * pScrni :Pointer to screen info structure.
+ * srcx :x-cordinate of the src rectangle
+ * srcy :y-codinate of src rectangle.
+ * w :width of the rectangle
+ * h :height of the rectangle.
+ * dstx :x-cordinate of the dst rectangle.
+ * dsty :y -coordinates of the dst rectangle.
+ * Returns :none.
+ *
+ * Comments :none
+ *
+*----------------------------------------------------------------------------
+*/
+static Bool
+LX_OpenFramebuffer(ScrnInfoPtr pScrni,
+ char **name, unsigned char **mem,
+ int *size, int *offset, int *flags)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+
+ *name = NULL; /* no special device */
+ *mem = (unsigned char *)pGeode->FBLinearAddr;
+ *size = pGeode->FBAvail;
+ *offset = 0;
+ *flags = DGA_NEED_ROOT;
+ return TRUE;
+}
+
+static void
+LX_CloseFramebuffer(ScrnInfoPtr pScrni)
+{
+}
+
+/* end of file */
diff -urN xf86-video-nsc-2.8.1-orig/src/amd_lx_driver.c xf86-video-nsc-2.8.1/src/amd_lx_driver.c
--- xf86-video-nsc-2.8.1-orig/src/amd_lx_driver.c 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/amd_lx_driver.c 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,2836 @@
+/*
+ * $Workfile: amd_lx_driver.c $
+ * $Revision: #6 $
+ * $Author: raymondd $
+ *
+ * File Contents: This is the main module configures the interfacing
+ * with the X server. The individual modules will be
+ * loaded based upon the options selected from the
+ * XF86Config. This file also has modules for finding
+ * supported modes, turning on the modes based on options.
+ *
+ * Project: Geode Xfree Frame buffer device driver.
+ *
+ */
+
+/*
+ * Copyright (c) 2003-2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice 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.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+/*
+ * */
+/*
+ * */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Includes that are used by all drivers */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86_libc.h"
+#include "xf86Resources.h"
+
+/* We may want inb() and outb() */
+#include "compiler.h"
+
+/* We may want to access the PCI config space */
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+/* Colormap handling stuff */
+#include "xf86cmap.h"
+
+#define RC_MAX_DEPTH 24
+
+#include "nsc.h"
+#include "cim_defs.h"
+#include "cim_regs.h"
+#include "cim_dev.h"
+
+/* Frame buffer stuff */
+#include "fb.h"
+
+#include "shadowfb.h"
+
+/* Machine independent stuff */
+#include "mipointer.h"
+#include "mibank.h"
+#include "micmap.h"
+/* All drivers implementing backing store need this */
+#include "mibstore.h"
+#include "vgaHW.h"
+#include "vbe.h"
+
+/* Check for some extensions */
+#ifdef XFreeXDGA
+#define _XF86_DGA_SERVER_
+#include
+#endif /* XFreeXDGA */
+
+#ifdef DPMSExtension
+#include "globals.h"
+#include "opaque.h"
+#define DPMS_SERVER
+#include
+#endif /* DPMSExtension */
+
+#include "amd_lx_vga.c"
+
+extern SymTabRec GeodeChipsets[];
+extern OptionInfoRec GeodeOptions[];
+
+/* Forward definitions */
+static Bool LXPreInit(ScrnInfoPtr, int);
+static Bool LXScreenInit(int, ScreenPtr, int, char **);
+static Bool LXEnterVT(int, int);
+static void LXLeaveVT(int, int);
+static void LXFreeScreen(int, int);
+void LXAdjustFrame(int, int, int, int);
+Bool LXSwitchMode(int, DisplayModePtr, int);
+static int LXValidMode(int, DisplayModePtr, Bool, int);
+static void LXLoadPalette(ScrnInfoPtr pScrni,
+ int numColors, int *indizes,
+ LOCO * colors, VisualPtr pVisual);
+static Bool LXMapMem(ScrnInfoPtr);
+static Bool LXUnmapMem(ScrnInfoPtr);
+
+extern Bool LXAccelInit(ScreenPtr pScrn);
+extern Bool LXHWCursorInit(ScreenPtr pScrn);
+extern void LXHideCursor(ScrnInfoPtr pScrni);
+extern void LXShowCursor(ScrnInfoPtr pScrni);
+extern void LXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src);
+extern void LXPointerMoved(int index, int x, int y);
+extern void LXRotationInit(ScrnInfoPtr pScrni);
+extern void LXShadowFBInit(ScreenPtr pScrn,GeodePtr pGeode,int bytpp);
+extern void LXInitVideo(ScreenPtr pScrn);
+extern Bool LXDGAInit(ScreenPtr pScrn);
+
+unsigned char *XpressROMPtr;
+unsigned long fb;
+
+/* List of symbols from other modules that this module references.The purpose
+* is that to avoid unresolved symbol warnings
+*/
+extern const char *nscVgahwSymbols[];
+extern const char *nscVbeSymbols[];
+extern const char *nscInt10Symbols[];
+
+extern const char *nscFbSymbols[];
+extern const char *nscXaaSymbols[];
+extern const char *nscRamdacSymbols[];
+extern const char *nscShadowSymbols[];
+
+void LXSetupChipsetFPtr(ScrnInfoPtr pScrni);
+GeodePtr LXGetRec(ScrnInfoPtr pScrni);
+void lx_clear_screen(ScrnInfoPtr pScrni, int width, int height, int bpp);
+void lx_clear_fb(ScrnInfoPtr pScrni);
+void lx_disable_dac_power(ScrnInfoPtr pScrni,int option);
+void lx_enable_dac_power(ScrnInfoPtr pScrni,int option);
+
+#if DEBUGLVL>0
+FILE *zdfp = NULL;
+#endif
+
+/* Reference: Video Graphics Suite Specification:
+ * VG Config Register (0x00) page 16
+ * VG FP Register (0x02) page 18 */
+
+#define LX_READ_VG(reg) ( outw(0xAC1C,0xFC53), outw(0xAC1C,0x0200|(reg)), inw(0xAC1E) )
+
+/* panel resolutiosn decode of FP config reg */
+
+static struct sLXFpResolution {
+ int xres, yres;
+} lx_fp_resolution[] = {
+ { 320, 240 }, { 640, 480 }, { 800, 600 }, { 1024, 768 },
+ { 1152, 864 }, { 1280, 1024 }, { 1600, 1200 }, { 0, 0 }
+};
+
+/* Get the information from the BIOS regarding the panel */
+
+static int
+lx_get_panel_info(int *xres, int *yres)
+{
+ unsigned short reg = LX_READ_VG(0x02);
+ *xres = lx_fp_resolution[(reg>>3) & 0x07].xres;
+ *yres = lx_fp_resolution[(reg>>3) & 0x07].yres;
+ return 0;
+}
+
+static int
+lx_panel_configured(void)
+{
+ unsigned short reg = LX_READ_VG(0x00);
+ unsigned char ret = (reg >> 8) & 0x7;
+ return (ret == 1) || (ret == 5) ? 1 : 0;
+}
+
+void
+LXSetupChipsetFPtr(ScrnInfoPtr pScrni)
+{
+#if DEBUGLVL>0
+ if( zdfp == NULL ) { zdfp = fopen("/tmp/xwin.log","w"); setbuf(zdfp,NULL); }
+#endif
+ DEBUGMSG(1,(0, X_INFO, "LXSetupChipsetFPtr!\n"));
+ pScrni->PreInit = LXPreInit;
+ pScrni->ScreenInit = LXScreenInit;
+ pScrni->SwitchMode = LXSwitchMode;
+ pScrni->AdjustFrame = LXAdjustFrame;
+ pScrni->EnterVT = LXEnterVT;
+ pScrni->LeaveVT = LXLeaveVT;
+ pScrni->FreeScreen = LXFreeScreen;
+ pScrni->ValidMode = LXValidMode;
+}
+
+#ifdef AMD_V4L2_VIDEO
+void
+LXInitVideo(ScreenPtr pScrn)
+{
+ GeodePtr pGeode;
+ int num_adaptors;
+ XF86VideoAdaptorPtr *adaptors;
+ ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum];
+ pGeode = GEODEPTR(pScrni);
+ if (!pGeode->NoAccel) {
+ num_adaptors = xf86XVListGenericAdaptors(pScrni, &adaptors);
+ if( num_adaptors > 0 )
+ xf86XVScreenInit(pScrn,adaptors,num_adaptors);
+ }
+}
+#else
+extern void LXInitVideo(ScreenPtr pScrn);
+#endif
+
+/*----------------------------------------------------------------------------
+ * LXGetRec.
+ *
+ * Description :This function allocate an GeodeRec and hooked into
+ * pScrni str driverPrivate member of ScreeenInfo
+ * structure.
+ * Parameters.
+ * pScrni :Pointer handle to the screenonfo structure.
+ *
+ * Returns :allocated driver structure.
+ *
+ * Comments :none
+ *
+*----------------------------------------------------------------------------
+*/
+GeodePtr
+LXGetRec(ScrnInfoPtr pScrni)
+{
+ if (!pScrni->driverPrivate) {
+ GeodePtr pGeode;
+
+ pGeode = pScrni->driverPrivate = xnfcalloc(sizeof(GeodeRec), 1);
+#if INT10_SUPPORT
+ pGeode->vesa = xcalloc(sizeof(VESARec), 1);
+#endif
+ }
+ return GEODEPTR(pScrni);
+}
+
+/*----------------------------------------------------------------------------
+ * LXFreeRec.
+ *
+ * Description :This function deallocate an GeodeRec and freed from
+ * pScrni str driverPrivate member of ScreeenInfo
+ * structure.
+ * Parameters.
+ * pScrni :Pointer handle to the screenonfo structure.
+ *
+ * Returns :none
+ *
+ * Comments :none
+ *
+*----------------------------------------------------------------------------
+*/
+static void
+LXFreeRec(ScrnInfoPtr pScrni)
+{
+ if (pScrni->driverPrivate == NULL) {
+ return;
+ }
+ xfree(pScrni->driverPrivate);
+ pScrni->driverPrivate = NULL;
+}
+
+/*----------------------------------------------------------------------------
+ * LXSaveScreen.
+ *
+ * Description :This is todo the screen blanking
+ *
+ * Parameters.
+ * pScrn :Handle to ScreenPtr structure.
+ * mode :mode is used by vgaHWSaveScren to check blnak os on.
+ *
+ * Returns :TRUE on success and FALSE on failure.
+ *
+ * Comments :none
+*----------------------------------------------------------------------------
+*/
+static Bool
+LXSaveScreen(ScreenPtr pScrn, int mode)
+{
+ ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum];
+ DEBUGMSG(0,(0, X_INFO, "LXSaveScreen!\n"));
+
+ if (!pScrni->vtSema)
+ return vgaHWSaveScreen(pScrn, mode);
+
+ return TRUE;
+}
+
+static xf86MonPtr
+LXProbeDDC(ScrnInfoPtr pScrni, int index)
+{
+ vbeInfoPtr pVbe;
+ xf86MonPtr ddc = NULL;
+
+ if (xf86LoadSubModule(pScrni, "vbe")) {
+ pVbe = VBEInit(NULL, index);
+ ddc = vbeDoEDID(pVbe, NULL);
+ vbeFree(pVbe);
+ }
+ return ddc;
+}
+
+static void
+LXDecodeDDC(ScrnInfoPtr pScrni,xf86MonPtr ddc)
+{
+ int i;
+ DEBUGMSG(1,(0, X_INFO,
+ "Detected monitor DDC (%4s) id %d serno %d week %d year %d nsects %d\n",
+ &ddc->vendor.name[0],ddc->vendor.prod_id,ddc->vendor.serial,
+ ddc->vendor.week,ddc->vendor.year,ddc->no_sections));
+ for( i=0; idet_mon[i];
+ switch( dp->type ) {
+ case DT: {
+ struct detailed_timings *r = &dp->section.d_timings;
+ DEBUGMSG(1,(0, X_INFO, " mon det timing %0.3f %dx%d\n",
+ r->clock/1000000.0, r->h_active, r->v_active));
+ DEBUGMSG(1,(0, X_INFO, " mon border %d,%d laced %d stereo %d sync %d, misc %d\n",
+ r->h_border, r->v_border, r->interlaced, r->stereo, r->sync, r->misc));
+ } break;
+ case DS_SERIAL: {
+ char *serial_no = (char*)&dp->section.serial[0];
+ DEBUGMSG(1,(0, X_INFO, " mon serial %13s\n",serial_no));
+ } break;
+ case DS_ASCII_STR: {
+ char *ascii = (char*)&dp->section.ascii_data[0];
+ DEBUGMSG(1,(0, X_INFO, " mon ascii_str %13s\n",ascii));
+ } break;
+ case DS_NAME: {
+ char *name = (char*)&dp->section.name[0];
+ DEBUGMSG(1,(0, X_INFO, " mon name %13s\n",name));
+ } break;
+ case DS_RANGES: {
+ struct monitor_ranges *r = &dp->section.ranges;
+ DEBUGMSG(1,(0, X_INFO, " mon ranges v %d-%d h %d-%d clk %d\n",
+ r->min_v, r->max_v, r->min_h, r->max_h, r->max_clock));
+ } break;
+ case DS_WHITE_P: {
+ struct whitePoints *wp = &dp->section.wp[0];
+ DEBUGMSG(1,(0, X_INFO, " mon whitept %f,%f %f,%f idx %d,%d gamma %f,%f\n",
+ wp[1].white_x, wp[1].white_y, wp[2].white_x, wp[2].white_y,
+ wp[1].index, wp[2].index, wp[1].white_gamma, wp[2].white_gamma));
+ } break;
+ case DS_STD_TIMINGS: {
+ struct std_timings *t = &dp->section.std_t[0];
+ DEBUGMSG(1,(0, X_INFO, " mon std_timing no size @rate, id\n"));
+ for( i=0; i<5; ++i )
+ DEBUGMSG(1,(0, X_INFO, " %d %5dx%-5d @%-4d %d\n",
+ i, t[i].hsize, t[i].vsize, t[i].refresh, t[i].id));
+ } break;
+ }
+ }
+}
+
+static void
+LXFBAlloc(int fd,unsigned int offset, unsigned int size)
+{
+ cim_mem_req_t req;
+ memset(&req,0,sizeof(req));
+ strcpy(&req.owner[0],"XFree86");
+ sprintf(&req.name[0],"%08lx",offset);
+ req.flags = CIM_F_PUBLIC;
+ req.size = size;
+ ioctl(fd,CIM_RESERVE_MEM,&req);
+}
+
+/* check for "tv-" or "pnl-" in mode name, decode suffix */
+/* return -1 if mode name is not a known tv/pnl mode */
+static int
+lx_tv_mode(DisplayModePtr pMode)
+{
+ int tv_mode = -1;
+ char *bp, *cp;
+ cp = pMode->name;
+ if( (*(bp=cp) == 't' && *++bp == 'v') ||
+ (*(bp=cp) == 'p' && *++bp == 'n' && *++bp == 'l') ) {
+ if( *++bp == '-' ) {
+ if( xf86NameCmp("ntsc",++bp) == 0 ) tv_mode = VG_TVMODE_NTSC;
+ else if( xf86NameCmp("pal",bp) == 0 ) tv_mode = VG_TVMODE_PAL;
+ else if( xf86NameCmp("6x4_ntsc",bp) == 0 ) tv_mode = VG_TVMODE_6X4_NTSC;
+ else if( xf86NameCmp("8x6_ntsc",bp) == 0 ) tv_mode = VG_TVMODE_8X6_NTSC;
+ else if( xf86NameCmp("10x7_ntsc",bp) == 0 ) tv_mode = VG_TVMODE_10X7_NTSC;
+ else if( xf86NameCmp("6x4_pal",bp) == 0 ) tv_mode = VG_TVMODE_6X4_PAL;
+ else if( xf86NameCmp("8x6_pal",bp) == 0 ) tv_mode = VG_TVMODE_8X6_PAL;
+ else if( xf86NameCmp("10x7_pal",bp) == 0 ) tv_mode = VG_TVMODE_10X7_PAL;
+ else if( xf86NameCmp("480p",bp) == 0 ) tv_mode = VG_TVMODE_480P;
+ else if( xf86NameCmp("720p",bp) == 0 ) tv_mode = VG_TVMODE_720P;
+ else if( xf86NameCmp("1080i",bp) == 0 ) tv_mode = VG_TVMODE_1080I;
+ }
+ }
+ return tv_mode;
+}
+
+static int
+lx_tv_mode_interlaced(int tv_mode)
+{
+ switch( tv_mode ) {
+ case VG_TVMODE_NTSC:
+ case VG_TVMODE_PAL:
+ case VG_TVMODE_1080I:
+ return 1;
+ }
+ return 0;
+}
+
+/*----------------------------------------------------------------------------
+ * LXPreInit.
+ *
+ * Description :This function is called only once ate teh server startup
+ *
+ * Parameters.
+ * pScrni :Handle to ScreenPtr structure.
+ * options :may be used to check the probeed one with config.
+ *
+ * Returns :TRUE on success and FALSE on failure.
+ *
+ * Comments :none.
+ *----------------------------------------------------------------------------
+ */
+static Bool
+LXPreInit(ScrnInfoPtr pScrni, int options)
+{
+ ClockRangePtr GeodeClockRange;
+ MessageType from;
+ int i = 0;
+ GeodePtr pGeode;
+ char *mod = NULL;
+ xf86MonPtr ddc = NULL;
+ Q_WORD msrValue;
+ unsigned long offset, length, fb_top;
+ char dev_name[64], dev_owner[64];
+ FILE *fp; int fd;
+#if INT10_SUPPORT
+ VESAPtr pVesa;
+#endif
+ unsigned int PitchInc, minPitch, maxPitch;
+ unsigned int minHeight, maxHeight;
+ unsigned int flags, fmt, high, low;
+ int tv_encoder, tv_bus_fmt, tv_601_fmt;
+ int tv_conversion, tvox, tvoy, tv_flags;
+ int tv_601_flags, tv_vsync_shift, tv_vsync_select;
+ int tv_vsync_shift_count;
+ const char *s;
+ char **modes;
+
+ /*
+ * Setup the ClockRanges, which describe what clock ranges are
+ * available, and what sort of modes they can be used for.
+ */
+ GeodeClockRange = (ClockRangePtr)xnfcalloc(sizeof(ClockRange), 1);
+ GeodeClockRange->next = NULL;
+ GeodeClockRange->minClock = 25175;
+ GeodeClockRange->maxClock = 341350;
+ GeodeClockRange->clockIndex = -1; /* programmable */
+ GeodeClockRange->interlaceAllowed = TRUE;
+ GeodeClockRange->doubleScanAllowed = FALSE; /* XXX check this */
+
+ /* Select valid modes from those available */
+ minPitch = 1024; maxPitch = 8192; /* Can support upto 1920x1440 32Bpp */
+ minHeight = 400; maxHeight = 2048; /* Can support upto 1920x1440 32Bpp */
+ /* need height >= maxWidth for rotate */
+
+ DEBUGMSG(1,(0, X_INFO, "LXPreInit!\n"));
+ /* Allocate driver private structure */
+ if (!(pGeode = LXGetRec(pScrni)))
+ return FALSE;
+
+ DEBUGMSG(1, (0, X_NONE, "pGeode = %p\n", (void*)pGeode));
+
+ /* This is the general case */
+ for (i = 0; i < pScrni->numEntities; i++) {
+ pGeode->pEnt = xf86GetEntityInfo(pScrni->entityList[i]);
+ if (pGeode->pEnt->resources)
+ return FALSE;
+ pGeode->Chipset = pGeode->pEnt->chipset;
+ pScrni->chipset = (char *)xf86TokenToString(GeodeChipsets,
+ pGeode->pEnt->chipset);
+ }
+
+ if( (options & PROBE_DETECT) != 0 ) {
+ ConfiguredMonitor = LXProbeDDC(pScrni, pGeode->pEnt->index);
+ return TRUE;
+ }
+
+#if INT10_SUPPORT
+ if (!xf86LoadSubModule(pScrni, "int10"))
+ return FALSE;
+ xf86LoaderReqSymLists(nscInt10Symbols, NULL);
+#endif
+
+ /* If the vgahw module would be needed it would be loaded here */
+ if (!xf86LoadSubModule(pScrni, "vgahw")) {
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(nscVgahwSymbols, NULL);
+ DEBUGMSG(1,(0, X_INFO, "LXPreInit(1)!\n"));
+ /* Do the cimarron hardware detection */
+ init_detect_cpu(&pGeode->cpu_version,&pGeode->cpu_revision);
+
+ /* find the base chipset core. Currently there can be only one
+ * chip active at any time.
+ */
+ if ((pGeode->cpu_version & 0xFF) != CIM_CPU_GEODELX) {
+ ErrorF("Chipset not GEODELX !!!\n");
+ return FALSE;
+ }
+ pGeode->DetectedChipSet = LX;
+ DEBUGMSG(1,(0, X_INFO, "Detected BaseChip (%d)\n", pGeode->DetectedChipSet));
+
+ /* LX : Can have CRT or PANEL/TVO only */
+ msr_read64(MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msrValue);
+ fmt = (msrValue.low>>3) & 0x07;
+ switch( fmt ) {
+ case 4:
+ case 2:
+ case 0:
+ flags = LX_OT_CRT;
+ break;
+ case 1:
+ case 3:
+ case 5:
+ flags = LX_OT_FP;
+ if( (msrValue.low & 0x8000) != 0 ) flags |= LX_OT_CRT;
+ break;
+ case 6:
+ flags = LX_OT_VOP;
+ break;
+ case 7:
+ flags = LX_OT_DRGB;
+ break;
+ }
+
+ /* currently supported formats */
+ flags &= (LX_OT_FP | LX_OT_CRT | LX_OT_VOP);
+ /* can switch from crt/pnl vop, but not the other way */
+ flags |= LX_OT_VOP;
+ pGeode->EnabledOutput = flags;
+
+ xf86DrvMsg(0, X_INFO, "AMD LX Output Formats -%sCRT,%sVOP,%sFP,%sDRGB\n",
+ ((flags & LX_OT_CRT) ? " " : " No "), ((flags & LX_OT_VOP) ? " " : " No "),
+ ((flags & LX_OT_FP) ? " " : " No "), ((flags & LX_OT_DRGB)? " " : " No "));
+
+ pGeode->vid_version = CIM_CPU_GEODELX;
+ DEBUGMSG(1,(0, X_INFO, "LXPreInit(1.2)!\n"));
+ init_read_base_addresses (&(pGeode->InitBaseAddress));
+ DEBUGMSG(1,(0, X_INFO, "LXPreInit(1.4)!\n"));
+
+ pGeode->FBLinearAddr = pGeode->InitBaseAddress.framebuffer_base;
+ fb_top = pGeode->InitBaseAddress.framebuffer_size;
+
+ if (pGeode->pEnt->device->videoRam == 0) {
+ from = X_PROBED;
+ pScrni->videoRam = fb_top / 1024;
+ } else {
+ pScrni->videoRam = pGeode->pEnt->device->videoRam;
+ from = X_CONFIG;
+ fb_top = pScrni->videoRam << 10;
+ }
+
+ DEBUGMSG(1, (pScrni->scrnIndex, from, "VideoRam: %lu kByte\n",
+ (unsigned long)pScrni->videoRam));
+
+ pGeode->CmdBfrOffset = 0;
+ pGeode->CmdBfrSize = 0;
+
+ /* try to cause modules to load now, to reserve fb mem for other drivers */
+ pGeode->cimFd = open("/dev/cimarron",O_RDONLY);
+ if( pGeode->cimFd < 0 )
+ pGeode->cimFd = open("/dev/cim",O_RDONLY);
+ DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "/dev/cimarron: fd=%d\n",pGeode->cimFd));
+ if( (fd=open("/dev/video",O_RDONLY)) >= 0 ) close(fd);
+ if( (fd=open("/dev/video0",O_RDONLY)) >= 0 ) close(fd);
+ if( (fd=open("/dev/video1",O_RDONLY)) >= 0 ) close(fd);
+ if( (fd=open("/dev/video2",O_RDONLY)) >= 0 ) close(fd);
+ if( (fd=open("/dev/video3",O_RDONLY)) >= 0 ) close(fd);
+ if( (fd=open("/dev/video/video0",O_RDONLY)) >= 0 ) close(fd);
+ if( (fd=open("/dev/video/video1",O_RDONLY)) >= 0 ) close(fd);
+ if( (fd=open("/dev/video/video2",O_RDONLY)) >= 0 ) close(fd);
+ if( (fd=open("/dev/video/video3",O_RDONLY)) >= 0 ) close(fd);
+
+ DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "open cim map\n"));
+ if( (fp=fopen("/proc/driver/cimarron/map","r")) != NULL ) {
+ low = 0;
+ high = fb_top;
+
+ DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "scan cim map\n"));
+ while( fscanf(fp,"%63s %63s %x %lx %lx\n",
+ &dev_owner[0],&dev_name[0],&flags,&offset,&length) == 5 ) {
+ if( offset < pGeode->FBLinearAddr ) continue;
+ offset -= pGeode->FBLinearAddr;
+ if( (flags & CIM_F_CMDBUF) != 0 ) {
+ pGeode->CmdBfrOffset = offset;
+ pGeode->CmdBfrSize = length;
+ }
+ if( offset >= fb_top ) continue;
+ if( (flags & CIM_F_PRIVATE) != 0 )
+ if( offset < high ) high = offset;
+ if( offset+length >= fb_top )
+ length = fb_top - offset;
+ if( (flags & CIM_F_PUBLIC) != 0 || (flags & CIM_F_FREE) != 0 )
+ if( offset+length > low ) low = offset+length;
+ }
+ fclose(fp);
+ fb_top = high < low ? high : low;
+ }
+
+ DEBUGMSG(1,(0, X_INFO, "fb_top = %08lx\n", fb_top));
+ DEBUGMSG(1, (pScrni->scrnIndex, X_INFO,
+ "cmd bfr (map) %08lx/%08lx\n",pGeode->CmdBfrOffset,pGeode->CmdBfrSize));
+
+ /* if cimarron module not reporting, use default buffer parameters */
+ if( pGeode->CmdBfrSize == 0 ) {
+ if( fb_top < CIM_CMD_BFR_SZ ) {
+ ErrorF("No memory for CMD_BFR !!!\n");
+ return FALSE;
+ }
+ pGeode->CmdBfrSize = CIM_CMD_BFR_SZ;
+ fb_top -= pGeode->CmdBfrSize;
+ pGeode->CmdBfrOffset = fb_top;
+ }
+
+ if( pGeode->CmdBfrSize < CIM_CMD_BFR_MIN ) {
+ ErrorF("Not enough memory for CMD_BFR !!!\n");
+ return FALSE;
+ }
+ DEBUGMSG(1, (pScrni->scrnIndex, X_INFO,
+ "cmd bfr (actual) %08lx/%08lx\n",pGeode->CmdBfrOffset,pGeode->CmdBfrSize));
+
+ /* now soak up all of the usable framebuffer memory */
+ if( pGeode->cimFd >= 0 ) {
+ DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "alloc cim map\n"));
+ for(;;) {
+ if( (fp=fopen("/proc/driver/cimarron/map","r")) == NULL ) break;
+ low = fb_top;
+ high = 0;
+ while( fscanf(fp,"%63s %63s %x %lx %lx\n",
+ &dev_owner[0],&dev_name[0],&flags,&offset,&length) == 5 ) {
+ if( offset < pGeode->FBLinearAddr ) continue;
+ offset -= pGeode->FBLinearAddr;
+ if( offset >= fb_top ) continue;
+ if( (flags & CIM_F_FREE) == 0 ) continue;
+ if( low < offset ) continue;
+ low = offset;
+ if( offset+length > fb_top )
+ length = fb_top - offset;
+ high = length;
+ }
+ fclose(fp);
+ if( high == 0 ) break;
+ LXFBAlloc(pGeode->cimFd,low,high);
+ }
+ DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "check cim map\n"));
+ /* only shared memory allowed below fb_top */
+ if( (fp=fopen("/proc/driver/cimarron/map","r")) != NULL ) {
+ low = 0;
+ while( fscanf(fp,"%63s %63s %x %lx %lx\n",
+ &dev_owner[0],&dev_name[0],&flags,&offset,&length) == 5 ) {
+ if( offset < pGeode->FBLinearAddr ) continue;
+ offset -= pGeode->FBLinearAddr;
+ if( offset >= fb_top ) continue;
+ if( (flags&CIM_F_PUBLIC) == 0 ) {
+ low = 1; break;
+ }
+ }
+ fclose(fp);
+ if( low != 0 ) {
+ ErrorF("Not able to claim free FB memory !!!\n");
+ return FALSE;
+ }
+ }
+ }
+
+ pGeode->FBTop = fb_top;
+ if( fb_top < GP3_SCRATCH_BUFFER_SIZE ) {
+ ErrorF("No available FB memory !!!\n");
+ return FALSE;
+ }
+
+ /* must remove cimarron scratch buffer from FB */
+ pGeode->FBAvail = fb_top - GP3_SCRATCH_BUFFER_SIZE;
+
+ DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "FBAvail = %08lx\n",pGeode->FBAvail));
+ if (pGeode->DetectedChipSet & LX) {
+ pGeode->cpu_reg_size = 0x4000;
+ pGeode->gp_reg_size = 0x4000;
+ pGeode->vg_reg_size = 0x4000;
+ pGeode->vid_reg_size = 0x4000;
+ pGeode->vip_reg_size = 0x4000;
+ } else {
+ pGeode->cpu_reg_size = 0x9000;
+ pGeode->vid_reg_size = 0x1000;
+ }
+
+ if (!LXMapMem(pScrni))
+ return FALSE;
+
+ /* KFB will Knock of VGA */
+ /* check if VGA is active */
+ pGeode->FBVGAActive = gu3_get_vga_active();
+
+ DEBUGMSG(1, (0, X_PROBED, "VGA = %d\n", pGeode->FBVGAActive));
+
+ /* Fill in the monitor field */
+ pScrni->monitor = pScrni->confScreen->monitor;
+ DEBUGMSG(1,(0, X_INFO, "LXPreInit(2)!\n"));
+ /* Determine depth, bpp, etc. */
+ if (!xf86SetDepthBpp(pScrni, 8, 8, 8, Support24bppFb|Support32bppFb))
+ return FALSE;
+
+ if( !((pScrni->depth == 8) || (pScrni->depth == 16) ||
+ (pScrni->depth == 24) || (pScrni->depth == 32))) {
+ DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR,
+ "Given depth (%d bpp) is not supported by this driver\n",
+ pScrni->depth));
+ return FALSE;
+ }
+
+ /*This must happen after pScrni->display has been set
+ * * because xf86SetWeight references it.
+ */
+ if (pScrni->depth > 8) {
+ /* The defaults are OK for us */
+ rgb BitsPerComponent = { 0, 0, 0 };
+ rgb BitMask = { 0, 0, 0 };
+
+ if (pScrni->depth > 16) {
+ /* we are operating in 24 bpp, Redcloud */
+ BitsPerComponent.red = 8;
+ BitsPerComponent.green = 8;
+ BitsPerComponent.blue = 8;
+
+ BitMask.red = 0xFF0000;
+ BitMask.green = 0x00FF00;
+ BitMask.blue = 0x0000FF;
+ }
+ if( xf86SetWeight(pScrni, BitsPerComponent, BitMask) == 0 )
+ return FALSE;
+ }
+
+
+ xf86PrintDepthBpp(pScrni);
+
+ DEBUGMSG(1,(0, X_INFO, "LXPreInit(3)!\n"));
+
+ if (!xf86SetDefaultVisual(pScrni, -1))
+ return FALSE;
+
+ DEBUGMSG(1,(0, X_INFO, "LXPreInit(4)!\n"));
+
+ /* The new cmap layer needs this to be initialized */
+ if (pScrni->depth > 1) {
+ Gamma zeros = { 0.0, 0.0, 0.0 };
+
+ if (!xf86SetGamma(pScrni, zeros)) {
+ return FALSE;
+ }
+ }
+ DEBUGMSG(1,(0, X_INFO, "LXPreInit(5)!\n"));
+
+ /* We use a programmable clock */
+ pScrni->progClock = TRUE;
+
+ /*Collect all of the relevant option flags
+ * *(fill in pScrni->options)
+ */
+ xf86CollectOptions(pScrni, NULL);
+
+ /*Process the options */
+ xf86ProcessOptions(pScrni->scrnIndex, pScrni->options,
+ GeodeOptions);
+
+#if INT10_SUPPORT
+ pVesa = pGeode->vesa;
+ /* Initialize Vesa record */
+
+ if ((pVesa->pInt = xf86InitInt10(pGeode->pEnt->index)) == NULL) {
+ xf86DrvMsg(0, X_ERROR, "Int10 initialization failed.\n");
+ return (FALSE);
+ }
+#endif
+
+ /*Set the bits per RGB for 8bpp mode */
+ if (pScrni->depth == 8) {
+ /* Default to 8 */
+ pScrni->rgbBits = 8;
+ }
+ from = X_DEFAULT;
+
+ pGeode->FPGeomDstSet = 0;
+ if( (s=xf86GetOptValString(GeodeOptions, OPTION_FP_DEST_GEOM)) != NULL ) {
+ char *sp;
+ int xres = strtoul(s,&sp,0);
+ if( sp != NULL && *sp == 'x' ) {
+ int yres = strtoul(sp+1,&sp,0);
+ if( sp != NULL && *sp == 0 ) {
+ if( xres > 0 && xres <= maxPitch &&
+ yres >= minHeight && yres <= maxHeight ) {
+ pGeode->FPGeomDstSet = 1;
+ pGeode->FPGeomDstX = xres;
+ pGeode->FPGeomDstY = yres;
+ }
+ else
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+ "FP_DEST_GEOM \"%dx%d\" out of range\n",xres,yres));
+ }
+ }
+ if( pGeode->FPGeomDstSet == 0 ) {
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+ "FP_DEST_GEOM \"%s\" not recognized\n",s));
+ return FALSE;
+ }
+ pGeode->EnabledOutput |= LX_OT_FP;
+ }
+
+ pGeode->FPGeomActSet = 0;
+ if( (s=xf86GetOptValString(GeodeOptions, OPTION_FP_ACTIVE_GEOM)) != NULL ) {
+ char *sp;
+ int xres = strtoul(s,&sp,0);
+ if( sp != NULL && *sp == 'x' ) {
+ int yres = strtoul(sp+1,&sp,0);
+ if( sp != NULL && *sp == 0 ) {
+ if( xres > 0 && xres <= maxPitch &&
+ yres >= minHeight && yres <= maxHeight ) {
+ pGeode->FPGeomActSet = 1;
+ pGeode->FPGeomActX = xres;
+ pGeode->FPGeomActY = yres;
+ }
+ else
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+ "FP_ACTIVE_GEOM \"%s\" out of range\n",s));
+ }
+ }
+ if( pGeode->FPGeomActSet == 0 ) {
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+ "FP_ACTIVE_GEOM \"%s\" not recognized\n",s));
+ return FALSE;
+ }
+ pGeode->EnabledOutput |= LX_OT_FP;
+ }
+
+ if( (pGeode->EnabledOutput & LX_OT_FP) !=0 ) {
+ if( pGeode->FPGeomDstSet == 0 ) {
+ if( lx_panel_configured() == 0 ) {
+ ErrorF("Panel configured and enabled but not configured in BIOS !!!\n");
+ return FALSE;
+ }
+ lx_get_panel_info(&pGeode->FPBiosResX, &pGeode->FPBiosResY);
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "FP Bios panel configuation used\n"));
+ pGeode->FPGeomDstX = pGeode->FPBiosResX;
+ pGeode->FPGeomDstY = pGeode->FPBiosResY;
+ }
+ if( pGeode->FPGeomActSet == 0 ) {
+ pGeode->FPGeomActX = pGeode->FPGeomDstX;
+ pGeode->FPGeomActY = pGeode->FPGeomDstY;
+ }
+ if( pGeode->FPGeomActX > pGeode->FPGeomDstX ||
+ pGeode->FPGeomActY > pGeode->FPGeomDstY ) {
+ ErrorF("FP Geom params Active %dx%d bigger than Dest %dx%d\n",
+ pGeode->FPGeomActX,pGeode->FPGeomActY,pGeode->FPGeomDstX, pGeode->FPGeomDstY);
+ return FALSE;
+ }
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "FP Geom params Dest %dx%d, Active %dx%d\n",
+ pGeode->FPGeomDstX, pGeode->FPGeomDstY,pGeode->FPGeomActX,pGeode->FPGeomActY));
+ }
+
+ if (xf86IsOptionSet(GeodeOptions,OPTION_FLATPANEL)) {
+ if (xf86ReturnOptValBool(GeodeOptions, OPTION_FLATPANEL, TRUE)) {
+ if( (pGeode->EnabledOutput & LX_OT_FP) != 0 ) {
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "FlatPanel Selected\n"));
+ }
+ else
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+ "FlatPanel Selected, but not available - ignored\n"));
+ }
+ else {
+ if( (pGeode->EnabledOutput & LX_OT_FP) != 0 ) {
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "FlatPanel configured, but not enabled\n"));
+ pGeode->EnabledOutput &= ~LX_OT_FP;
+ }
+ }
+ }
+
+ /*
+ * *The preferred method is to use the "hw cursor" option as a tri-state
+ * *option, with the default set above.
+ */
+ pGeode->HWCursor = TRUE;
+ if (xf86GetOptValBool(GeodeOptions, OPTION_HW_CURSOR, &pGeode->HWCursor)) {
+ from = X_CONFIG;
+ }
+ /* For compatibility, accept this too (as an override) */
+ if (xf86ReturnOptValBool(GeodeOptions, OPTION_SW_CURSOR, FALSE)) {
+ from = X_CONFIG;
+ pGeode->HWCursor = FALSE;
+ }
+ DEBUGMSG(1, (pScrni->scrnIndex, from, "Using %s cursor\n",
+ pGeode->HWCursor ? "HW" : "SW"));
+
+ pGeode->Compression = TRUE;
+ if (xf86ReturnOptValBool(GeodeOptions, OPTION_NOCOMPRESSION, FALSE)) {
+ pGeode->Compression = FALSE;
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "NoCompression\n"));
+ }
+
+ pGeode->NoAccel = FALSE;
+ if (xf86ReturnOptValBool(GeodeOptions, OPTION_NOACCEL, FALSE)) {
+ pGeode->NoAccel = TRUE;
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "Acceleration disabled\n"));
+ }
+
+ if (!xf86GetOptValInteger(GeodeOptions, OPTION_OSM_IMG_BUFS,
+ &(pGeode->NoOfImgBuffers)))
+ pGeode->NoOfImgBuffers = DEFAULT_IMG_LINE_BUFS;
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+ "NoOfImgBuffers = %d\n", pGeode->NoOfImgBuffers));
+ if (!xf86GetOptValInteger(GeodeOptions, OPTION_OSM_CLR_BUFS,
+ &(pGeode->NoOfColorExpandLines)))
+ pGeode->NoOfColorExpandLines = DEFAULT_CLR_LINE_BUFS;
+ if( pGeode->NoOfColorExpandLines <= 0 )
+ pGeode->NoOfColorExpandLines = 0;
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+ "NoOfColorExpandLines = %d\n", pGeode->NoOfColorExpandLines));
+
+ pGeode->CustomMode = FALSE;
+ if (xf86ReturnOptValBool(GeodeOptions, OPTION_CUSTOM_MODE, FALSE)) {
+ pGeode->CustomMode = TRUE;
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "Custom mode enabled\n"));
+ }
+
+ if (xf86IsOptionSet(GeodeOptions,OPTION_CRTENABLE)) {
+ if (xf86ReturnOptValBool(GeodeOptions, OPTION_CRTENABLE, TRUE)) {
+ if( (pGeode->EnabledOutput & LX_OT_FP) != 0 ) {
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "CRT Output Selected\n"));
+ }
+ else
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+ "CRT Output Selected, but not available - ignored\n"));
+ }
+ else {
+ if( (pGeode->EnabledOutput & LX_OT_CRT) != 0 ) {
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "CRT output configured, but not enabled\n"));
+ pGeode->EnabledOutput &= ~LX_OT_CRT;
+ }
+ }
+ }
+
+ pGeode->TVSupport = FALSE;
+ if( (s=xf86GetOptValString(GeodeOptions, OPTION_TV_ENCODER)) != NULL ) {
+ tv_encoder = -1;
+ if( xf86NameCmp(s,"ADV7171") == 0 )
+ tv_encoder = VG_ENCODER_ADV7171;
+ else if( xf86NameCmp(s,"SAA7127") == 0 )
+ tv_encoder = VG_ENCODER_SAA7127;
+ else if( xf86NameCmp(s,"FS454") == 0 )
+ tv_encoder = VG_ENCODER_FS454;
+ else if( xf86NameCmp(s,"ADV7300") == 0 )
+ tv_encoder = VG_ENCODER_ADV7300;
+ if( tv_encoder < 0 ) {
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+ "VOP output configured, but no encoder specified, VOP diabled\n"));
+ pGeode->EnabledOutput &= ~LX_OT_VOP;
+ }
+ else
+ pGeode->TVSupport = TRUE;
+ pGeode->tv_encoder = tv_encoder;
+ }
+
+ /* If TV Supported then check for TVO support */
+ if( pGeode->TVSupport != FALSE ) {
+ tv_bus_fmt = -1;
+ tv_601_fmt = -1;
+ if( (s=xf86GetOptValString(GeodeOptions, OPTION_TV_BUS_FMT)) != NULL ) {
+ if( xf86NameCmp(s,"disabled") == 0 )
+ tv_bus_fmt = VOP_MODE_DISABLED;
+ else if( xf86NameCmp(s,"vip11") == 0 )
+ tv_bus_fmt = VOP_MODE_VIP11;
+ else if( xf86NameCmp(s,"ccir656") == 0 )
+ tv_bus_fmt = VOP_MODE_CCIR656;
+ else if( xf86NameCmp(s,"vip20_8bit") == 0 )
+ tv_bus_fmt = VOP_MODE_VIP20_8BIT;
+ else if( xf86NameCmp(s,"vip20_16bit") == 0 )
+ tv_bus_fmt = VOP_MODE_VIP20_16BIT;
+ else if( xf86NameCmp(s,"601_yuv_8bit") == 0 ) {
+ tv_601_fmt = VOP_601_YUV_8BIT;
+ tv_bus_fmt = VOP_MODE_601;
+ } else if( xf86NameCmp(s,"601_yuv_16bit") == 0 ) {
+ tv_601_fmt = VOP_601_YUV_16BIT;
+ tv_bus_fmt = VOP_MODE_601;
+ } else if( xf86NameCmp(s,"601_rgb_8_8_8") == 0 ) {
+ tv_601_fmt = VOP_601_RGB_8_8_8;
+ tv_bus_fmt = VOP_MODE_601;
+ } else if( xf86NameCmp(s,"601_yuv_4_4_4") == 0 ) {
+ tv_601_fmt = VOP_601_YUV_4_4_4;
+ tv_bus_fmt = VOP_MODE_601;
+ }
+ }
+ if( tv_bus_fmt < 0 ) {
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+ "VOP output configured, but no bus format specified,\n"
+ "VOP bus format will depend on SD/HD mode\n"));
+ }
+ pGeode->tv_bus_fmt = tv_bus_fmt;
+ pGeode->tv_601_fmt = tv_601_fmt;
+ tv_flags = 0;
+ if( (s=xf86GetOptValString(GeodeOptions, OPTION_TV_FLAGS)) != NULL ) {
+ char *opt, *sp = strdup(s);
+ if( sp != NULL ) {
+ for( opt=strtok(sp,":"); opt!=NULL; opt=strtok(NULL,":") ) {
+ if( xf86NameCmp(opt,"singlechipcompat") == 0 )
+ tv_flags |= VOP_FLAG_SINGLECHIPCOMPAT;
+ else if( xf86NameCmp(opt,"extendedsav") == 0 )
+ tv_flags |= VOP_FLAG_EXTENDEDSAV;
+ else if( xf86NameCmp(opt,"vbi") == 0 )
+ tv_flags |= VOP_FLAG_VBI;
+ else if( xf86NameCmp(opt,"task") == 0 )
+ tv_flags |= VOP_FLAG_TASK;
+ else if( xf86NameCmp(opt,"swap_uv") == 0 )
+ tv_flags |= VOP_FLAG_SWAP_UV;
+ else if( xf86NameCmp(opt,"swap_vbi") == 0 )
+ tv_flags |= VOP_FLAG_SWAP_VBI;
+ else
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+ "VOP flag \"%s\" not recognized\n",opt));
+ }
+ free(sp);
+ }
+ }
+ tv_vsync_shift_count = 0;
+ tv_601_flags = 0;
+ tv_vsync_shift = VOP_VSYNC_NOSHIFT;
+ if( (s=xf86GetOptValString(GeodeOptions, OPTION_TV_601_FLAGS)) != NULL ) {
+ char *opt, *sp = strdup(s);
+ if( sp != NULL ) {
+ for( opt=strtok(sp,":"); opt!=NULL; opt=strtok(NULL,":") ) {
+ if( xf86NameCmp(opt,"inv_de_pol") == 0 )
+ tv_601_flags |= VOP_601_INVERT_DISPE;
+ else if( xf86NameCmp(opt,"inv_hs_pol") == 0 )
+ tv_601_flags |= VOP_601_INVERT_HSYNC;
+ else if( xf86NameCmp(opt,"inv_vs_pol") == 0 )
+ tv_601_flags |= VOP_601_INVERT_VSYNC;
+ else if( xf86NameCmp(opt,"vsync-4") == 0 )
+ tv_vsync_shift = VOP_VSYNC_EARLIER_BY4;
+ else if( xf86NameCmp(opt,"vsync-2") == 0 )
+ tv_vsync_shift = VOP_VSYNC_EARLIER_BY2;
+ else if( xf86NameCmp(opt,"vsync+0") == 0 )
+ tv_vsync_shift = VOP_VSYNC_NOSHIFT;
+ else if( xf86NameCmp(opt,"vsync+2") == 0 ) {
+ tv_vsync_shift = VOP_VSYNC_LATER_BY_X;
+ tv_vsync_shift_count = 2;
+ }
+ else if( xf86NameCmp(opt,"vsync+4") == 0 ) {
+ tv_vsync_shift = VOP_VSYNC_LATER_BY_X;
+ tv_vsync_shift_count = 4;
+ }
+ else
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+ "VOP 601_flag \"%s\" not recognized\n",opt));
+ }
+ free(sp);
+ }
+ }
+ tv_vsync_select = VOP_MB_SYNCSEL_DISABLED;
+ if( (s=xf86GetOptValString(GeodeOptions, OPTION_TV_VSYNC_SELECT)) != NULL ) {
+ char *opt, *sp = strdup(s);
+ if( sp != NULL ) {
+ for( opt=strtok(sp,":"); opt!=NULL; opt=strtok(NULL,":") ) {
+ if( xf86NameCmp(opt,"disabled") == 0 )
+ tv_vsync_select = VOP_MB_SYNCSEL_DISABLED;
+ else if( xf86NameCmp(opt,"vg") == 0 )
+ tv_vsync_select = VOP_MB_SYNCSEL_VG;
+ else if( xf86NameCmp(opt,"vg_inv") == 0 )
+ tv_vsync_select = VOP_MB_SYNCSEL_VG_INV;
+ else if( xf86NameCmp(opt,"statreg17") == 0 )
+ tv_vsync_select = VOP_MB_SYNCSEL_STATREG17;
+ else if( xf86NameCmp(opt,"statreg17_inv") == 0 )
+ tv_vsync_select = VOP_MB_SYNCSEL_STATREG17_INV;
+ else
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+ "VOP vsync_select \"%s\" not recognized\n",opt));
+ }
+ free(sp);
+ }
+ }
+ pGeode->tv_flags = tv_flags;
+ pGeode->tv_601_flags = tv_601_flags;
+ pGeode->tv_vsync_shift = tv_vsync_shift;
+ pGeode->tv_vsync_shift_count = tv_vsync_shift_count;
+ pGeode->tv_vsync_select = tv_vsync_select;
+ tv_conversion = -1;
+ if( (s=xf86GetOptValString(GeodeOptions, OPTION_TV_CONVERSION)) != NULL ) {
+ if( xf86NameCmp(s,"cosited") == 0 )
+ tv_conversion = VOP_422MODE_COSITED;
+ else if( xf86NameCmp(s,"interspersed") == 0 )
+ tv_conversion = VOP_422MODE_INTERSPERSED;
+ else if( xf86NameCmp(s,"alternating") == 0 )
+ tv_conversion = VOP_422MODE_ALTERNATING;
+ else {
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+ "VOP conversion \"%s\" not recognized\n",s));
+ }
+ }
+ if( tv_conversion < 0 ) {
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+ "VOP output configured, but no conversion specified,\n"
+ "VOP conversion will defaults to \"cosited\"\n"));
+ tv_conversion = VOP_422MODE_COSITED;
+ }
+ pGeode->tv_conversion = tv_conversion;
+ tvox = tvoy = 0;
+ if( (s=xf86GetOptValString(GeodeOptions,OPTION_TV_OVERSCAN)) != NULL ) {
+ char *opt, *sp = strdup(s);
+ if( sp != NULL ) {
+ if( (opt=strtok(sp,":")) != NULL ) tvox = strtol(opt,NULL,0);
+ if( (opt=strtok(NULL, ":")) != NULL) tvoy = strtol(opt,NULL,0);
+ free(sp);
+ }
+ DEBUGMSG(1, (0, X_CONFIG, "TVO %d %d\n", tvox,tvoy));
+ }
+ pGeode->tvox = tvox; pGeode->tvoy = tvoy;
+ }
+ else if( (pGeode->EnabledOutput & LX_OT_VOP) != 0 ) {
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+ "VOP output enabled, but not configured, VOP diabled\n"));
+ pGeode->EnabledOutput &= ~LX_OT_VOP;
+ }
+
+ if( (pGeode->EnabledOutput & LX_OT_CRT) != 0 ) {
+ ddc = LXProbeDDC(pScrni, pGeode->pEnt->index);
+ }
+
+ flags = pGeode->EnabledOutput;
+ xf86DrvMsg(0, X_INFO, "AMD LX Active Formats -%sCRT,%sVOP,%sFP,%sDRGB\n",
+ ((flags & LX_OT_CRT) ? " " : " No "), ((flags & LX_OT_VOP) ? " " : " No "),
+ ((flags & LX_OT_FP) ? " " : " No "), ((flags & LX_OT_DRGB)? " " : " No "));
+
+ if( (pGeode->EnabledOutput & (LX_OT_CRT|LX_OT_FP|LX_OT_VOP)) == 0 ) {
+ ErrorF("No output enabled !!!\n");
+ return FALSE;
+ }
+
+ pGeode->ShadowFB = FALSE;
+ if (xf86ReturnOptValBool(GeodeOptions, OPTION_SHADOW_FB, FALSE)) {
+ pGeode->ShadowFB = TRUE;
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+ "Using \"Shadow Framebuffer\"\n"));
+ }
+
+ pGeode->Rotate = 0;
+ if ((s = xf86GetOptValString(GeodeOptions, OPTION_ROTATE))) {
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "Rotating - %s\n", s));
+ if (!xf86NameCmp(s, "CW")) {
+ pGeode->Rotate = 1;
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+ "Rotating screen clockwise\n"));
+ }
+ else if (!xf86NameCmp(s, "INVERT")) {
+ pGeode->Rotate = 2;
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+ "Rotating screen inverted\n"));
+ }
+ else if (!xf86NameCmp(s, "CCW")) {
+ pGeode->Rotate = 3;
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+ "Rotating screen counter clockwise\n"));
+ }
+ if( pGeode->Rotate != 0 ) {
+ pGeode->ShadowFB = TRUE;
+ }
+ else {
+ DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG,
+ "\"%s\" is not a valid value for Option \"Rotate\"\n", s));
+ DEBUGMSG(1, (pScrni->scrnIndex, X_INFO,
+ "Valid options are \"CW\", \"INVERT\", or \"CCW\"\n"));
+ }
+ }
+
+ /* XXX Init further private data here */
+
+ /*
+ * * This shouldn't happen because such problems should be caught in
+ * * GeodeProbe(), but check it just in case.
+ */
+ if (pScrni->chipset == NULL) {
+ DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR,
+ "ChipID 0x%04X is not recognised\n", pGeode->Chipset));
+ return FALSE;
+ }
+ if (pGeode->Chipset < 0) {
+ DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR,
+ "Chipset \"%s\" is not recognised\n",
+ pScrni->chipset));
+ return FALSE;
+ }
+ DEBUGMSG(1,(0, X_INFO, "LXPreInit(6)!\n"));
+
+ /*
+ * * Init the screen with some values
+ */
+ DEBUGMSG(1, (pScrni->scrnIndex, from,
+ "Video I/O registers at 0x%08lX\n",
+ (unsigned long)VGAHW_GET_IOBASE()));
+
+ if (pScrni->memPhysBase == 0) {
+ from = X_PROBED;
+ pScrni->memPhysBase = pGeode->FBLinearAddr;
+ }
+ pScrni->fbOffset = 0;
+
+ DEBUGMSG(1, (pScrni->scrnIndex, from,
+ "Linear framebuffer at 0x%08lX\n",
+ (unsigned long)pScrni->memPhysBase));
+
+ DEBUGMSG(1,(0, X_INFO, "LXPreInit(7)!\n"));
+
+ /*
+ * * xf86ValidateModes will check that the mode HTotal and VTotal values
+ * * don't exceed the chipset's limit if pScrni->maxHValue adn
+ * * pScrni->maxVValue are set. Since our LXValidMode()
+ * * already takes care of this, we don't worry about setting them here.
+ */
+ if (pScrni->depth > 16) {
+ PitchInc = 4096;
+ } else if (pScrni->depth == 16) {
+ PitchInc = 2048;
+ } else {
+ PitchInc = 1024;
+ }
+ PitchInc <<= 3; /* in bits */
+
+ /* by default use what user sets in the XF86Config file */
+ modes = pScrni->display->modes;
+
+ if( ddc != NULL && pScrni->monitor != NULL && pScrni->monitor->DDC == NULL ) {
+ pScrni->monitor->DDC = ddc;
+ LXDecodeDDC(pScrni,ddc);
+ }
+
+ i = xf86ValidateModes(pScrni, pScrni->monitor->Modes, modes, GeodeClockRange,
+ NULL, minPitch, maxPitch, PitchInc, minHeight, maxHeight,
+ pScrni->display->virtualX, pScrni->display->virtualY,
+ pGeode->FBAvail, LOOKUP_BEST_REFRESH);
+
+ DEBUGMSG(1, (pScrni->scrnIndex, from, "xf86ValidateModes:%d %d %d %d\n",
+ i, pScrni->virtualX, pScrni->virtualY, pScrni->displayWidth));
+ if( i == -1 ) {
+ LXFreeRec(pScrni);
+ return FALSE;
+ }
+ DEBUGMSG(1,(0, X_INFO, "LXPreInit(8)!\n"));
+
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrni);
+
+ DEBUGMSG(1,(0, X_INFO, "LXPreInit(9)!\n"));
+ if( i == 0 || pScrni->modes == NULL ) {
+ DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR, "No valid modes found\n"));
+ LXFreeRec(pScrni);
+ return FALSE;
+ }
+ DEBUGMSG(1,(0, X_INFO, "LXPreInit(10)!\n"));
+
+ xf86SetCrtcForModes(pScrni, 0);
+ DEBUGMSG(1,(0, X_INFO, "LXPreInit(11)!\n"));
+
+ /* Set the current mode to the first in the list */
+ pScrni->currentMode = pScrni->modes;
+ DEBUGMSG(1,(0, X_INFO, "LXPreInit(12)!\n"));
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrni);
+ DEBUGMSG(1,(0, X_INFO, "LXPreInit(13)!\n"));
+
+ /* Set the display resolution */
+ xf86SetDpi(pScrni, 0, 0);
+ DEBUGMSG(1,(0, X_INFO, "LXPreInit(14)!\n"));
+
+ /* Load bpp-specific modules */
+ mod = NULL;
+
+ if (xf86LoadSubModule(pScrni, "fb") == NULL) {
+ LXFreeRec(pScrni);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(nscFbSymbols, NULL);
+
+ DEBUGMSG(1,(0, X_INFO, "LXPreInit(15)!\n"));
+ if (pGeode->NoAccel == FALSE) {
+ if (!xf86LoadSubModule(pScrni, "xaa")) {
+ LXFreeRec(pScrni);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(nscXaaSymbols, NULL);
+ }
+ DEBUGMSG(1,(0, X_INFO, "LXPreInit(16)!\n"));
+ if (pGeode->HWCursor == TRUE) {
+ if (!xf86LoadSubModule(pScrni, "ramdac")) {
+ LXFreeRec(pScrni);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(nscRamdacSymbols, NULL);
+ }
+ DEBUGMSG(1,(0, X_INFO, "LXPreInit(17)!\n"));
+ /* Load shadowfb if needed */
+ if (pGeode->ShadowFB) {
+ if (!xf86LoadSubModule(pScrni, "shadowfb")) {
+ LXFreeRec(pScrni);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(nscShadowSymbols, NULL);
+ }
+ DEBUGMSG(1,(0, X_INFO, "LXPreInit(18)!\n"));
+ if (xf86RegisterResources(pGeode->pEnt->index, NULL, ResExclusive)) {
+ DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR,
+ "xf86RegisterResources() found resource conflicts\n"));
+ LXFreeRec(pScrni);
+ return FALSE;
+ }
+ LXUnmapMem(pScrni);
+ DEBUGMSG(1,(0, X_INFO, "LXPreInit ... done successfully!\n"));
+ return TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * LXRestore.
+ *
+ * Description :This function restores the mode that was saved on server
+ entry
+ * Parameters.
+ * pScrni :Handle to ScreenPtr structure.
+ * Pmode :poits to screen mode
+ *
+ * Returns :none.
+ *
+ * Comments :none.
+*----------------------------------------------------------------------------
+*/
+static void
+LXRestore(ScrnInfoPtr pScrni)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+
+ DEBUGMSG(0,(0, X_INFO, "LXRestore!\n"));
+ if (pGeode->FBVGAActive) {
+ vgaHWPtr pvgaHW = VGAHWPTR(pScrni);
+
+ vgaHWProtect(pScrni, TRUE);
+ vgaHWRestore(pScrni, &pvgaHW->SavedReg, VGA_SR_ALL);
+ vgaHWProtect(pScrni, FALSE);
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * LXCalculatePitchBytes.
+ *
+ * Description :This function restores the mode that was saved on server
+ *
+ * Parameters.
+ * pScrni :Handle to ScreenPtr structure.
+ * Pmode :Points to screenmode
+ *
+ * Returns :none.
+ *
+ * Comments :none.
+*----------------------------------------------------------------------------
+*/
+static int
+LXCalculatePitchBytes(unsigned int width, unsigned int bpp)
+{
+ int lineDelta = width * (bpp >> 3);
+
+ if (width < 640) {
+ /* low resolutions have both pixel and line doubling */
+ DEBUGMSG(1, (0, X_PROBED, "lower resolution %d %d\n",
+ width, lineDelta));
+ lineDelta <<= 1;
+ }
+ /* needed in Rotate mode when in accel is turned off */
+ if (1) { /*!pGeode->NoAccel */
+ if (lineDelta > 4096)
+ lineDelta = 8192;
+ else if (lineDelta > 2048)
+ lineDelta = 4096;
+ else if (lineDelta > 1024)
+ lineDelta = 2048;
+ else
+ lineDelta = 1024;
+ }
+
+ DEBUGMSG(0, (0, X_INFO, "pitch %d %d\n", width, lineDelta));
+
+ return lineDelta;
+}
+
+/*----------------------------------------------------------------------------
+ * LXGetRefreshRate.
+ *
+ * Description :This function restores the mode that saved on server
+ *
+ * Parameters.
+ * Pmode :Pointer to the screen modes
+ *
+ * Returns :It returns the selected refresh rate.
+ *
+ * Comments :none.
+*----------------------------------------------------------------------------
+*/
+static int
+LXGetRefreshRate(DisplayModePtr pMode)
+{
+#define THRESHOLD 2
+ unsigned int i;
+ static int validRates[] = { 56, 60, 70, 72, 75, 85, 90, 100 }; /* Hz */
+ unsigned long dotClock;
+ int refreshRate;
+ int selectedRate;
+
+ dotClock = pMode->SynthClock * 1000;
+ refreshRate = dotClock / (pMode->CrtcHTotal * pMode->CrtcVTotal);
+
+ if ((pMode->CrtcHTotal < 640) && (pMode->CrtcVTotal < 480))
+ refreshRate >>= 2; /* double pixel and double scan */
+
+ DEBUGMSG(0, (0, X_INFO, "dotclock %lu %d\n", dotClock, refreshRate));
+
+ selectedRate = validRates[0];
+
+ for (i = 0; i < (sizeof(validRates) / sizeof(validRates[0])); i++) {
+ if (validRates[i] < (refreshRate + THRESHOLD)) {
+ selectedRate = validRates[i];
+ }
+ }
+ return selectedRate;
+}
+
+void
+lx_clear_screen(ScrnInfoPtr pScrni, int width, int height, int bpp)
+{
+ /* no accels, mode is not yet set */
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ unsigned long offset = vg_get_display_offset();
+ unsigned long pitch = vg_get_display_pitch();
+ unsigned long n = width * ((bpp+7)>>3);
+ DEBUGMSG(0, (0, X_INFO, "clear screen %lx %d %d %d %lu %lu\n", offset,width,height,bpp,pitch,n));
+ while( height > 0 ) {
+ memset(pGeode->FBBase+offset,0,n);
+ offset += pitch;
+ --height;
+ }
+}
+
+void
+lx_clear_fb(ScrnInfoPtr pScrni)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ unsigned char *fb = pGeode->FBBase+pGeode->FBOffset;
+ memset(fb,0,pGeode->FBSize);
+ if( pGeode->ShadowPtr != NULL && pGeode->ShadowPtr != fb )
+ memset(pGeode->ShadowPtr,0,pGeode->ShadowSize);
+}
+
+static int
+lx_set_tv_mode(ScrnInfoPtr pScrni,int tv_mode)
+{
+ int ret, bpp, flags;
+ int tv_conversion, tv_bus_fmt, tv_flags;
+ int tv_601_fmt, tv_601_flags;
+ int tv_vsync_shift, tv_vsync_shift_count, tv_vsync_select;
+ unsigned long src_width, src_height;
+ char *bp, *cp, *dp;
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ VOPCONFIGURATIONBUFFER vopc;
+ bpp = pScrni->bitsPerPixel;
+ if( bpp == 32 ) bpp = 24;
+ flags = lx_tv_mode_interlaced(tv_mode) != 0 ? VG_MODEFLAG_INTERLACED : 0;
+ src_width = src_height = 0;
+ ret = vg_set_tv_mode(&src_width,&src_height,
+ pGeode->tv_encoder,tv_mode,bpp,flags,0,0);
+ DEBUGMSG(1, (0, X_INFO,
+ "Setting TV mode %lux%lu encoder=%d,bpp=%d,flags=%d,overscan %d,%d\n",
+ src_width,src_height,pGeode->tv_encoder,bpp,flags,
+ pGeode->tvox,pGeode->tvoy));
+ ret = vg_set_tv_mode(&src_width,&src_height,
+ pGeode->tv_encoder,tv_mode,bpp,flags,pGeode->tvox,pGeode->tvoy);
+
+ DEBUGMSG(1, (0, X_INFO, "Set TV mode ret=%d\n", ret));
+ if( ret == 0 ) {
+ memset(&vopc,0,sizeof(vopc));
+ tv_flags = pGeode->tv_flags;
+ tv_bus_fmt = pGeode->tv_bus_fmt;
+ tv_601_fmt = pGeode->tv_601_fmt;
+ tv_601_flags = pGeode->tv_601_flags;
+ tv_vsync_shift = pGeode->tv_vsync_shift;
+ tv_vsync_shift_count = pGeode->tv_vsync_shift_count;
+ tv_vsync_select = pGeode->tv_vsync_select;
+ tv_conversion = pGeode->tv_conversion;
+ if( tv_bus_fmt < 0 ) {
+ dp = "defaults";
+ switch( tv_mode ) {
+ case VG_TVMODE_NTSC: case VG_TVMODE_6X4_NTSC:
+ case VG_TVMODE_8X6_NTSC: case VG_TVMODE_10X7_NTSC:
+ case VG_TVMODE_PAL: case VG_TVMODE_6X4_PAL:
+ case VG_TVMODE_8X6_PAL: case VG_TVMODE_10X7_PAL:
+ tv_bus_fmt = VOP_MODE_VIP11;
+ break;
+ default:
+ tv_bus_fmt = VOP_MODE_VIP20_16BIT;
+ break;
+ }
+ }
+ else
+ dp = "set";
+ switch( tv_bus_fmt ) {
+ case VOP_MODE_VIP11: bp = "vop11"; break;
+ case VOP_MODE_CCIR656: bp = "ccir656"; break;
+ case VOP_MODE_VIP20_8BIT: bp = "vip20_8bit"; break;
+ case VOP_MODE_VIP20_16BIT: bp = "vip20_16bit"; break;
+ case VOP_MODE_601:
+ switch( tv_601_fmt ) {
+ default: tv_601_fmt = VOP_601_YUV_8BIT;
+ case VOP_601_YUV_8BIT: bp = "601_yuv_8bit"; break;
+ case VOP_601_YUV_16BIT: bp = "601_yuv_16bit"; break;
+ case VOP_601_RGB_8_8_8: bp = "601_rgb_8_8_8"; break;
+ case VOP_601_YUV_4_4_4: bp = "601_yuv_4_4_4"; break;
+ }
+ break;
+ default: tv_bus_fmt = VOP_MODE_DISABLED;
+ case VOP_MODE_DISABLED: bp = "disabled"; break;
+ }
+ switch( tv_conversion ) {
+ default: tv_conversion = VOP_422MODE_COSITED;
+ case VOP_422MODE_COSITED: cp = "cosited"; break;
+ case VOP_422MODE_INTERSPERSED: cp = "interspersed"; break;
+ case VOP_422MODE_ALTERNATING: cp = "alternating"; break;
+ }
+ vopc.flags = tv_flags;
+ vopc.mode = tv_bus_fmt;
+ vopc.conversion_mode = tv_conversion;
+ vopc.vsync_out = tv_vsync_select;
+ vopc.vop601.flags = tv_601_flags;
+ vopc.vop601.vsync_shift = tv_vsync_shift;
+ vopc.vop601.vsync_shift_count = tv_vsync_shift_count;
+ vopc.vop601.output_mode = tv_601_fmt;
+ DEBUGMSG(1, (0, X_INFO,
+ "Set TV mode %s to %s, conv %s, flags %x\n",
+ dp,bp,cp,tv_flags));
+ DEBUGMSG(1, (0, X_INFO,
+ "Set TV 601 mode %x flags %x vsync shift %x/%x\n",
+ tv_601_fmt,tv_601_flags,tv_vsync_shift,tv_vsync_shift_count));
+ vop_set_configuration(&vopc);
+ }
+ return ret;
+}
+
+static int
+lx_set_custom_mode(unsigned long bpp, unsigned long flags,
+ unsigned long hactive, unsigned long hblankstart,
+ unsigned long hsyncstart, unsigned long hsyncend,
+ unsigned long hblankend, unsigned long htotal,
+ unsigned long vactive, unsigned long vblankstart,
+ unsigned long vsyncstart, unsigned long vsyncend,
+ unsigned long vblankend, unsigned long vtotal,
+ unsigned long frequency)
+
+{
+ VG_DISPLAY_MODE mode;
+ memset(&mode,0,sizeof(mode));
+ mode.flags = flags;
+ mode.src_width = hactive;
+ mode.src_height = vactive;
+ mode.mode_width = hactive;
+ mode.mode_height = vactive;
+ mode.hactive = hactive;
+ mode.hblankstart = hblankstart;
+ mode.hsyncstart = hsyncstart;
+ mode.hsyncend = hsyncend;
+ mode.hblankend = hblankend;
+ mode.htotal = htotal;
+ mode.vactive = vactive;
+ mode.vblankstart = vblankstart;
+ mode.vsyncstart = vsyncstart;
+ mode.vsyncend = vsyncend;
+ mode.vblankend = vblankend;
+ mode.vtotal = vtotal;
+ mode.vactive_even = vactive;
+ mode.vblankstart_even = vblankstart;
+ mode.vsyncstart_even = vsyncstart;
+ mode.vsyncend_even = vsyncend;
+ mode.vblankend_even = vblankend;
+ mode.vtotal_even = vtotal;
+ mode.frequency = frequency;
+ return vg_set_custom_mode(&mode,bpp);
+}
+
+/*----------------------------------------------------------------------------
+ * LXSetMode.
+ *
+ * Description :This function sets parametrs for screen mode
+ *
+ * Parameters.
+ * pScrni :Pointer to the screenInfo structure.
+ * Pmode :Pointer to the screen modes
+ *
+ * Returns :TRUE on success and FALSE on Failure.
+ *
+ * Comments :none.
+*----------------------------------------------------------------------------
+*/
+
+static Bool
+LXSetMode(ScrnInfoPtr pScrni, DisplayModePtr pMode)
+{
+ int bpp, bppx, rate, video_enable, tv_mode, opath;
+ unsigned long flags, srcw,srch, actw,acth, dstw,dsth, video_flags;
+
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ DF_VIDEO_SOURCE_PARAMS vs_odd, vs_even;
+ gp_wait_until_idle();
+ /* disable video */
+ df_get_video_enable(&video_enable,&video_flags);
+ if( video_enable != 0 ) df_set_video_enable(0,0);
+ df_get_video_source_configuration(&vs_odd, &vs_even);
+ lx_disable_dac_power(pScrni,DF_CRT_DISABLE);
+
+ DEBUGMSG(1, (0, X_NONE, "LXSetMode! %p %p %p\n",
+ cim_gp_ptr, cim_vid_ptr, cim_fb_ptr));
+
+ /* Set the VT semaphore */
+ pScrni->vtSema = TRUE;
+
+ srcw = pMode->CrtcHDisplay;
+ srch = pMode->CrtcVDisplay;
+ bpp = pScrni->bitsPerPixel;
+ rate = LXGetRefreshRate(pMode);
+ /* otherwise color/chroma keying doesnt work */
+ bppx = bpp == 32 ? 24 : bpp;
+
+ /* The timing will be adjusted later */
+ DEBUGMSG(1, (0, X_PROBED,
+ "Setting mode %dx%d %0.3f %d %d %d %d %d %d %d %d\n",
+ pMode->CrtcHDisplay, pMode->CrtcVDisplay, pMode->SynthClock/1000.0,
+ pMode->CrtcHDisplay, pMode->CrtcHSyncStart, pMode->CrtcHSyncEnd, pMode->CrtcHTotal,
+ pMode->CrtcVDisplay, pMode->CrtcVSyncStart, pMode->CrtcVSyncEnd, pMode->CrtcVTotal));
+ DEBUGMSG(1,(0, X_INFO, "Set display mode: %lux%lu-%d (%dHz) Pitch %d/%d\n",
+ srcw,srch, bpp, rate, pGeode->Pitch,pGeode->AccelPitch));
+
+ opath = DF_DISPLAY_CRT;
+ if( (pGeode->EnabledOutput&LX_OT_FP) != 0 ) {
+ if( (pGeode->EnabledOutput&LX_OT_CRT) != 0 )
+ opath = DF_DISPLAY_CRT_FP;
+ else
+ opath = DF_DISPLAY_FP;
+ }
+
+ if( pGeode->TVSupport && (tv_mode=lx_tv_mode(pMode)) >= 0 ) {
+ DEBUGMSG(1, (0, X_INFO, "Set TV mode %d\n",tv_mode));
+ lx_set_tv_mode(pScrni,tv_mode);
+ opath = DF_DISPLAY_VOP;
+ }
+ else if( pGeode->CustomMode != 0 ) {
+ DEBUGMSG(1, (0, X_PROBED, "Setting Custom mode\n"));
+ flags = 0;
+ if( (pMode->Flags & V_NHSYNC) != 0 ) flags |= VG_MODEFLAG_NEG_HSYNC;
+ if( (pMode->Flags & V_NVSYNC) != 0 ) flags |= VG_MODEFLAG_NEG_VSYNC;
+ lx_set_custom_mode(bppx, flags,
+ pMode->CrtcHDisplay, pMode->CrtcHBlankStart, pMode->CrtcHSyncStart,
+ pMode->CrtcHSyncEnd, pMode->CrtcHBlankEnd, pMode->CrtcHTotal,
+ pMode->CrtcVDisplay, pMode->CrtcVBlankStart, pMode->CrtcVSyncStart,
+ pMode->CrtcVSyncEnd, pMode->CrtcVBlankEnd, pMode->CrtcVTotal,
+ (int)((pMode->SynthClock/1000.0)*0x10000));
+ }
+ else if( (pGeode->EnabledOutput&LX_OT_FP) != 0 ) {
+ /* display is fp */
+ actw = pGeode->FPGeomActX; dstw = pGeode->FPGeomDstX;
+ acth = pGeode->FPGeomActY; dsth = pGeode->FPGeomDstY;
+ flags = (pGeode->EnabledOutput&LX_OT_CRT) != 0 ? VG_MODEFLAG_CRT_AND_FP : 0;
+ /* cant do scaling if width > 1024 (hw bfr size limitation) */
+ if( srcw > 1024 ) {
+ if( srcw != actw )
+ DEBUGMSG(1, (0, X_PROBED, "FPGeomSrcX > 1024, scaling disabled\n"));
+ actw = srcw; acth = srch;
+ vg_set_border_color(0);
+ }
+ DEBUGMSG(1, (0, X_PROBED, "Setting Display for TFT %lux%lu %lux%lu %lux%lu %d\n",
+ srcw,srch, actw,acth, dstw,dsth, pScrni->bitsPerPixel));
+ vg_set_panel_mode(srcw,srch, actw,acth, dstw,dsth, bppx, flags);
+ }
+ else {
+ /* display is crt */
+ DEBUGMSG(1, (0, X_PROBED, "Setting Display for CRT %lux%lu-%d@%d\n",
+ srcw, srch, bppx, LXGetRefreshRate(pMode)));
+ vg_set_display_mode(srcw,srch, srcw,srch, bppx, LXGetRefreshRate(pMode),0);
+ }
+
+ df_set_output_path(opath);
+ vg_set_display_pitch(pGeode->Pitch);
+ gp_set_bpp(pScrni->bitsPerPixel);
+
+ vg_set_display_offset(0L);
+ vg_wait_vertical_blank();
+
+ DEBUGMSG(1, (0, X_PROBED, "Display mode set\n"));
+ /* enable compression if option selected */
+ if( pGeode->Compression != 0 ) {
+ DEBUGMSG(1, (0, X_PROBED, "Compression mode set %d\n", pGeode->Compression));
+ /* set the compression parameters,and it will be turned on later. */
+ vg_configure_compression(&(pGeode->CBData));
+
+ /* set the compression buffer, all parameters already set */
+ vg_set_compression_enable(1);
+ }
+
+ if( pGeode->HWCursor != 0 ) {
+ VG_PANNING_COORDINATES panning;
+ /* Load blank cursor */
+ LXLoadCursorImage(pScrni, NULL);
+ vg_set_cursor_position(0, 0, &panning);
+ LXShowCursor(pScrni);
+ }
+
+ DEBUGMSG(1,(0, X_INFO, "setting mode done.\n"));
+
+ vg_set_display_offset(pGeode->PrevDisplayOffset);
+
+ /* Restore the contents in the screen info */
+ DEBUGMSG(1,(0, X_INFO, "After setting the mode\n"));
+ switch( pGeode->Rotate ) {
+ case 1:
+ case 3:
+ pGeode->HDisplay = pMode->VDisplay;
+ pGeode->VDisplay = pMode->HDisplay;
+ break;
+ default:
+ pGeode->HDisplay = pMode->HDisplay;
+ pGeode->VDisplay = pMode->VDisplay;
+ break;
+ }
+
+ df_configure_video_source(&vs_odd,&vs_even);
+ if( video_enable != 0 )
+ df_set_video_enable(video_enable,video_flags);
+ lx_enable_dac_power(pScrni,1);
+ return TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * LXEnterGraphics.
+ *
+ * Description :This function will intiallize the displaytiming
+ structure for nextmode and switch to VGA mode.
+ *
+ * Parameters.
+ * pScrn :Screen information will be stored in this structure.
+ * pScrni :Pointer to the screenInfo structure.
+ *
+ * Returns :TRUE on success and FALSE on Failure.
+ *
+ * Comments :gfx_vga_mode_switch() will start and end the
+ * switching based on the arguments 0 or 1.soft_vga
+ * is disabled in this function.
+*----------------------------------------------------------------------------
+*/
+static Bool
+LXEnterGraphics(ScreenPtr pScrn, ScrnInfoPtr pScrni)
+{
+ int bpp;
+ unsigned long cmd_bfr_phys;
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ vgaHWPtr pvgaHW = VGAHWPTR(pScrni);
+
+ DEBUGMSG(1,(0, X_INFO, "LXEnterGraphics.\n"));
+
+ gp_wait_until_idle();
+ cmd_bfr_phys = pGeode->InitBaseAddress.framebuffer_base + pGeode->CmdBfrOffset;
+ cim_cmd_base_ptr = cim_fb_ptr + pGeode->CmdBfrOffset;
+ gp_set_frame_buffer_base(pGeode->InitBaseAddress.framebuffer_base,pGeode->FBTop);
+ gp_set_command_buffer_base(cmd_bfr_phys,0,pGeode->CmdBfrSize);
+
+ lx_disable_dac_power(pScrni,DF_CRT_DISABLE);
+ /* Save CRT State */
+ vg_get_current_display_mode(&pGeode->FBcimdisplaytiming.vgDisplayMode, &bpp);
+ pGeode->FBcimdisplaytiming.wBpp = bpp;
+
+ pGeode->FBcimdisplaytiming.wPitch = vg_get_display_pitch();
+
+ /* Save Display offset */
+ pGeode->FBDisplayOffset = vg_get_display_offset();
+ pGeode->FBBIOSMode = pvgaHW->readCrtc(pvgaHW, 0x040);
+ DEBUGMSG(1,(0, X_INFO, "FBBIOSMode %d\n", pGeode->FBBIOSMode));
+
+ /* Save the current Compression state */
+ pGeode->FBCompressionEnable = vg_get_compression_enable();
+
+ vg_get_compression_info (&(pGeode->FBCBData));
+
+ /* Save Cursor offset */
+ vg_get_cursor_info(&pGeode->FBCursor);
+
+ /* only if comming from VGA */
+ if (pGeode->FBVGAActive) {
+ unsigned short sequencer;
+ vgaHWPtr pvgaHW = VGAHWPTR(pScrni);
+
+ /* Map VGA aperture */
+ if (!vgaHWMapMem(pScrni))
+ return FALSE;
+
+ /* Unlock VGA registers */
+ vgaHWUnlock(pvgaHW);
+
+ /* Save the current state and setup the current mode */
+ vgaHWSave(pScrni, &VGAHWPTR(pScrni)->SavedReg, VGA_SR_ALL);
+
+ /* DISABLE VGA SEQUENCER */
+ /* This allows the VGA state machine to terminate. We must delay */
+ /* such that there are no pending MBUS requests. */
+
+ cim_outb(DC3_SEQUENCER_INDEX, DC3_SEQUENCER_CLK_MODE);
+ sequencer = cim_inb(DC3_SEQUENCER_DATA);
+ sequencer |= DC3_CLK_MODE_SCREEN_OFF;
+ cim_outb(DC3_SEQUENCER_DATA, sequencer);
+
+ vg_delay_milliseconds(1);
+
+ /* BLANK THE VGA DISPLAY */
+ cim_outw(DC3_SEQUENCER_INDEX, DC3_SEQUENCER_RESET);
+ sequencer = cim_inb(DC3_SEQUENCER_DATA);
+ sequencer &= ~DC3_RESET_VGA_DISP_ENABLE;
+ cim_outb(DC3_SEQUENCER_DATA, sequencer);
+
+ vg_delay_milliseconds(1);
+ }
+
+ lx_clear_fb(pScrni);
+
+ if (!LXSetMode(pScrni, pScrni->currentMode)) {
+ return FALSE;
+ }
+
+ lx_enable_dac_power(pScrni,1);
+ return TRUE;
+}
+
+void
+lx_disable_dac_power(ScrnInfoPtr pScrni,int option)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ if( (pGeode->EnabledOutput&LX_OT_FP) != 0 )
+ df_set_panel_enable(0);
+ if( (pGeode->EnabledOutput&LX_OT_CRT) != 0 ) {
+ if( (pGeode->EnabledOutput&LX_OT_FP) != 0 )
+ /* wait for the panel to be fully powered off */
+ while( (READ_VID32(DF_POWER_MANAGEMENT) & 2) == 0 );
+ df_set_crt_enable(option);
+ }
+}
+
+void
+lx_enable_dac_power(ScrnInfoPtr pScrni, int option)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ df_set_crt_enable(DF_CRT_ENABLE);
+ if( option != 0 && (pGeode->EnabledOutput&LX_OT_CRT) == 0 ) {
+ unsigned int misc = READ_VID32(DF_VID_MISC);
+ misc |= DF_DAC_POWER_DOWN;
+ WRITE_VID32(DF_VID_MISC, misc);
+ }
+ if( (pGeode->EnabledOutput&LX_OT_FP) != 0 )
+ df_set_panel_enable(1);
+}
+
+/*----------------------------------------------------------------------------
+ * LXLeaveGraphics:
+ *
+ * Description :This function will restore the displaymode parameters
+ * and switches the VGA mode
+ *
+ * Parameters.
+ * pScrni :Pointer to the screenInfo structure.
+ *
+ * Returns :none.
+*----------------------------------------------------------------------------
+*/
+static void
+LXLeaveGraphics(ScrnInfoPtr pScrni)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ gp_wait_until_idle();
+
+ /* Restore VG registers */
+ lx_disable_dac_power(pScrni,DF_CRT_DISABLE);
+ vg_set_custom_mode(&(pGeode->FBcimdisplaytiming.vgDisplayMode),
+ pGeode->FBcimdisplaytiming.wBpp);
+
+ vg_set_compression_enable(0);
+
+ /* Restore the previous Compression state */
+ if (pGeode->FBCompressionEnable) {
+ vg_configure_compression(&(pGeode->FBCBData));
+ vg_set_compression_enable(1);
+ }
+
+ vg_set_display_pitch(pGeode->FBcimdisplaytiming.wPitch);
+
+ vg_set_display_offset(pGeode->FBDisplayOffset);
+
+ /* Restore Cursor */
+ { VG_PANNING_COORDINATES panning;
+ vg_set_cursor_position(pGeode->FBCursor.cursor_x,pGeode->FBCursor.cursor_y,&panning); }
+
+ /* For the moment, always do an int 10 */
+
+#if INT10_SUPPORT
+ pGeode->vesa->pInt->num = 0x10;
+ pGeode->vesa->pInt->ax = 0x0 | pGeode->FBBIOSMode;
+ pGeode->vesa->pInt->bx = 0;
+ xf86ExecX86int10(pGeode->vesa->pInt);
+#endif
+ vg_delay_milliseconds(3);
+ LXRestore(pScrni);
+
+ lx_enable_dac_power(pScrni,0);
+}
+
+/*----------------------------------------------------------------------------
+ * LXCloseScreen.
+ *
+ * Description :This function will restore the original mode
+ * and also it unmap video memory
+ *
+ * Parameters.
+ * ScrnIndex :Screen index value of the screen will be closed.
+ * pScrn :Pointer to the screen structure.
+ *
+ *
+ * Returns :TRUE on success and FALSE on Failure.
+ *
+ * Comments :none.
+*----------------------------------------------------------------------------
+*/
+static Bool
+LXCloseScreen(int scrnIndex, ScreenPtr pScrn)
+{
+ ScrnInfoPtr pScrni = xf86Screens[scrnIndex];
+ GeodePtr pGeode = GEODEPTR(pScrni);
+
+ if( pGeode->ShadowPtr && !pGeode->ShadowInFBMem )
+ xfree(pGeode->ShadowPtr);
+
+ DEBUGMSG(1, (scrnIndex, X_PROBED, "LXCloseScreen %d\n",
+ pScrni->vtSema));
+ if (pScrni->vtSema)
+ LXLeaveGraphics(pScrni);
+
+ if (pGeode->AccelInfoRec)
+ XAADestroyInfoRec(pGeode->AccelInfoRec);
+
+ if (pGeode->AccelImageWriteBuffers) {
+#if LX_USE_OFFSCRN_MEM
+ xfree(pGeode->AccelImageWriteBuffers[0]);
+#endif
+ xfree(pGeode->AccelImageWriteBuffers);
+ pGeode->AccelImageWriteBuffers = NULL;
+ }
+ if (pGeode->AccelColorExpandBuffers) {
+ xfree(pGeode->AccelColorExpandBuffers[0]);
+ xfree(pGeode->AccelColorExpandBuffers);
+ pGeode->AccelColorExpandBuffers = NULL;
+ }
+ pScrni->vtSema = FALSE;
+
+ LXUnmapMem(pScrni);
+
+ if (pGeode && (pScrn->CloseScreen = pGeode->CloseScreen)) {
+ pGeode->CloseScreen = NULL;
+ return ((*pScrn->CloseScreen)(scrnIndex,pScrn));
+ }
+ return TRUE;
+}
+
+#ifdef DPMSExtension
+/*----------------------------------------------------------------------------
+ * LXDPMSSet.
+ *
+ * Description :This function sets geode into Power Management
+ * Signalling mode.
+ *
+ * Parameters.
+ * pScrni :Pointer to screen info strucrure.
+ * mode :Specifies the power management mode.
+ *
+ * Returns :none.
+ *
+ * Comments :none.
+*----------------------------------------------------------------------------
+*/
+static void
+LXDPMSSet(ScrnInfoPtr pScrni, int mode, int flags)
+{
+ GeodePtr pGeode;
+
+ pGeode = GEODEPTR(pScrni);
+
+ DEBUGMSG(1,(0, X_INFO, "LXDPMSSet!\n"));
+
+ /* Check if we are actively controlling the display */
+ if (!pScrni->vtSema) {
+ ErrorF("LXDPMSSet called when we not controlling the VT!\n");
+ return;
+ }
+ switch (mode) {
+ case DPMSModeOn: /* Screen: On; HSync: On; VSync: On */
+ lx_enable_dac_power(pScrni,1);
+ break;
+
+ case DPMSModeStandby: /* Screen: Off; HSync: Off; VSync: On */
+ lx_disable_dac_power(pScrni,DF_CRT_STANDBY);
+ break;
+
+ case DPMSModeSuspend: /* Screen: Off; HSync: On; VSync: Off */
+ lx_disable_dac_power(pScrni,DF_CRT_SUSPEND);
+ break;
+ case DPMSModeOff: /* Screen: Off; HSync: Off; VSync: Off */
+ lx_disable_dac_power(pScrni,DF_CRT_DISABLE);
+ break;
+ }
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * LXScreenInit.
+ *
+ * Description :This function will be called at the each ofserver
+ * generation.
+ *
+ * Parameters.
+ * scrnIndex :Specfies the screenindex value during generation.
+ * pScrn :Pointer to screen strucrure.
+ * argc :parameters for command line arguments count
+ * argv :command line arguments if any it is not used.
+ *
+ * Returns :none.
+ *
+ * Comments :none.
+*----------------------------------------------------------------------------
+*/
+static Bool
+LXScreenInit(int scrnIndex, ScreenPtr pScrn, int argc, char **argv)
+{
+ int i, bytpp, size, fbsize, fboffset, fbavail;
+ int pitch, displayWidth, virtualX, virtualY;
+ int HDisplay, VDisplay, maxHDisplay, maxVDisplay, maxX, maxY;
+ unsigned char *FBStart, **ap, *bp;
+ DisplayModePtr p;
+ GeodePtr pGeode;
+ VisualPtr visual;
+ BoxRec AvailBox;
+ RegionRec OffscreenRegion;
+ ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum];
+ Bool Inited = FALSE;
+
+ DEBUGMSG(1,(0, X_INFO, "LXScreenInit!\n"));
+ /* Get driver private */
+ pGeode = LXGetRec(pScrni);
+ DEBUGMSG(1,(0, X_INFO, "LXScreenInit(0)!\n"));
+ /*
+ * * Allocate a vgaHWRec
+ */
+
+ if (!vgaHWGetHWRec(pScrni))
+ return FALSE;
+ if (!vgaHWMapMem(pScrni))
+ return FALSE;
+
+ vgaHWGetIOBase(VGAHWPTR(pScrni));
+
+ if (!LXMapMem(pScrni))
+ return FALSE;
+
+ pGeode->Pitch = LXCalculatePitchBytes(pScrni->virtualX,
+ pScrni->bitsPerPixel);
+ pGeode->AccelPitch = pGeode->Pitch;
+ bytpp = (pScrni->bitsPerPixel+7)/8;
+
+ /* start of framebuffer for accels */
+ fboffset = 0;
+ fbavail = pGeode->FBAvail;
+
+ /* allocate display frame buffer at zero offset */
+ fbsize = pScrni->virtualY * pGeode->Pitch;
+ pGeode->FBSize = fbsize;
+
+ pGeode->CursorSize = (HW_CURSOR_W*HW_CURSOR_H)/8*2; /* can be RGBA */
+ pGeode->CursorStartOffset = 0;
+
+ DEBUGMSG(1, (scrnIndex, X_PROBED,"%d %d %d\n",
+ pScrni->virtualX, pScrni->bitsPerPixel, pGeode->Pitch));
+
+ HDisplay = pScrni->currentMode->HDisplay;
+ VDisplay = pScrni->currentMode->VDisplay;
+ pGeode->orig_virtX = pScrni->virtualX;
+ pGeode->orig_virtY = pScrni->virtualY;
+
+ p = pScrni->modes;
+ maxHDisplay = p->HDisplay;
+ maxVDisplay = p->VDisplay;
+ while( (p=p->next)!=pScrni->modes ) {
+ if( maxHDisplay < p->HDisplay ) maxHDisplay = p->HDisplay;
+ if( maxVDisplay < p->VDisplay ) maxVDisplay = p->VDisplay;
+ }
+ DEBUGMSG(1, (scrnIndex, X_PROBED,"maxHDisplay %d maxVDisplay %d\n",maxHDisplay,maxVDisplay));
+
+ switch( pGeode->Rotate ) {
+ case 1:
+ case 3:
+ pGeode->HDisplay = VDisplay;
+ pGeode->VDisplay = HDisplay;
+ virtualX = pScrni->virtualY;
+ virtualY = pScrni->virtualX;
+ maxX = maxVDisplay;
+ maxY = maxHDisplay;
+ break;
+ default:
+ pGeode->HDisplay = HDisplay;
+ pGeode->VDisplay = VDisplay;
+ virtualX = pScrni->virtualX;
+ virtualY = pScrni->virtualY;
+ maxX = maxHDisplay;
+ maxY = maxVDisplay;
+ break;
+ }
+
+ /* shadow may be first in FB, since accels render there */
+
+ pGeode->ShadowPtr = NULL;
+ if( pGeode->ShadowFB ) {
+ if( !pGeode->PointerMoved ) {
+ pGeode->PointerMoved = pScrni->PointerMoved;
+ pScrni->PointerMoved = LXPointerMoved;
+ }
+ if( !pGeode->NoAccel ) {
+ pGeode->ShadowPitch = LXCalculatePitchBytes(virtualX,pScrni->bitsPerPixel);
+ size = pGeode->ShadowPitch * virtualY;
+ if( size <= fbavail-fbsize ) {
+ pGeode->ShadowPtr = (unsigned char *)pGeode->FBBase + fboffset;
+ pGeode->AccelPitch = pGeode->ShadowPitch;
+ pGeode->ShadowSize = size;
+ pGeode->ShadowInFBMem = TRUE;
+ fboffset += size;
+ fbavail -= size;
+ }
+ else {
+ xf86DrvMsg(scrnIndex, X_ERROR, "Shadow FB, No FB Memory, trying offscreen\n");
+ }
+ }
+ if( pGeode->ShadowPtr == NULL ) {
+ pGeode->ShadowPitch = BitmapBytePad(pScrni->bitsPerPixel*virtualX);
+ size = pGeode->ShadowPitch * virtualY;
+ pGeode->ShadowPtr = xalloc(size);
+ if( pGeode->ShadowPtr != NULL ) {
+ pGeode->ShadowSize = size;
+ pGeode->ShadowInFBMem = FALSE;
+ if( !pGeode->NoAccel ) {
+ pGeode->NoAccel = TRUE;
+ pGeode->HWCursor = FALSE;
+ xf86DrvMsg(scrnIndex, X_ERROR, "Shadow FB offscreen, All Accels disabled\n");
+ }
+ }
+ else {
+ xf86DrvMsg(scrnIndex, X_ERROR, "Shadow FB, No offscreen Memory, disabled\n");
+ pGeode->ShadowFB = FALSE;
+ pGeode->Rotate = 0;
+ pGeode->HDisplay = HDisplay;
+ pGeode->VDisplay = VDisplay;
+ virtualX = pScrni->virtualX;
+ virtualY = pScrni->virtualY;
+ }
+ }
+ }
+
+ if( pGeode->ShadowPtr != NULL ) {
+ displayWidth = pGeode->ShadowPitch / bytpp;
+ FBStart = pGeode->ShadowPtr;
+ DEBUGMSG(1, (0, X_PROBED, "Shadow %p \n", FBStart));
+ }
+ else {
+ displayWidth = pGeode->Pitch / bytpp;
+ FBStart = pGeode->FBBase;
+ DEBUGMSG(1, (0, X_PROBED, "FBStart %p \n", FBStart));
+ }
+
+ DEBUGMSG(1, (0, X_PROBED, "FB display %X size %X \n",fboffset,fbsize));
+ pGeode->FBOffset = fboffset; /* offset of display framebuffer */
+ pScrni->fbOffset = fboffset;
+ fboffset += fbsize;
+ fbavail -= fbsize;
+
+ if( pGeode->Compression ) { /* Compression enabled */
+ pGeode->CBData.size = 512+32;
+ pGeode->CBData.pitch = 512+32;
+ size = maxY*pGeode->CBData.pitch;
+ DEBUGMSG(1, (0, X_PROBED, "CB %#x size %#x (%d*%lu)\n",fboffset,size,maxY,pGeode->CBData.pitch));
+ if( size <= fbavail ) {
+ pGeode->CBData.compression_offset = fboffset;
+ fboffset += size;
+ fbavail -= size;
+ }
+ else {
+ xf86DrvMsg(scrnIndex, X_ERROR, "Compression, No FB Memory, disabled\n");
+ pGeode->Compression = FALSE;
+ }
+ }
+
+ if( pGeode->HWCursor ) { /* HWCursor enabled */
+ size = pGeode->CursorSize;
+ if( size <= fbavail ) {
+ pGeode->CursorStartOffset = fboffset;
+ fboffset += size;
+ fbavail -= size;
+ }
+ else {
+ xf86DrvMsg(scrnIndex, X_ERROR, "HWCursor, No FB Memory, disabled\n");
+ pGeode->HWCursor = FALSE;
+ }
+ }
+
+ if( !pGeode->NoAccel ) { /* Acceleration enabled */
+ if( pGeode->NoOfImgBuffers > 0 ) {
+ pGeode->AccelImageWriteBuffers = NULL;
+ pitch = pGeode->AccelPitch;
+ size = pitch * pGeode->NoOfImgBuffers;
+#if !LX_USE_OFFSCRN_MEM
+ if( size <= fbavail ) {
+ bp = (unsigned char *)pGeode->FBBase + fboffset;
+ ap = xalloc(sizeof(pGeode->AccelImageWriteBuffers[0]) * pGeode->NoOfImgBuffers);
+ if( ap != NULL ) {
+ for( i=0; iNoOfImgBuffers; ++i ) {
+ ap[i] = bp;
+ bp += pitch;
+ }
+ pGeode->AccelImageWriteBuffers = ap;
+ fboffset += size;
+ fbavail -= size;
+ }
+ else {
+ xf86DrvMsg(scrnIndex, X_ERROR, "Image Write, No Memory\n");
+ }
+ }
+ else {
+ xf86DrvMsg(scrnIndex, X_ERROR, "Image Write, No FB Memory\n");
+ }
+#else
+ if( (bp=(unsigned char *)xalloc(size)) != NULL ) {
+ ap = xalloc(sizeof(pGeode->AccelImageWriteBuffers[0]) * pGeode->NoOfImgBuffers);
+ if( ap != NULL ) {
+ for( i=0; iNoOfImgBuffers; ++i ) {
+ ap[i] = bp;
+ bp += pitch;
+ }
+ pGeode->AccelImageWriteBuffers = ap;
+ }
+ else {
+ xf86DrvMsg(scrnIndex, X_ERROR, "Image Write, No Memory\n");
+ }
+ }
+ else {
+ xf86DrvMsg(scrnIndex, X_ERROR, "Image Write, No offscreen Memory\n");
+ }
+#endif
+ if( pGeode->AccelImageWriteBuffers == NULL ) {
+ xf86DrvMsg(scrnIndex, X_ERROR, "Accel Image Write disabled\n");
+ pGeode->NoOfImgBuffers = 0;
+ }
+ }
+
+ if (pGeode->NoOfColorExpandLines > 0) {
+ pGeode->AccelColorExpandBuffers = NULL;
+ pitch = ((pGeode->AccelPitch+31) >> 5) << 2;
+ size = pitch * pGeode->NoOfColorExpandLines;
+ if( (bp=(unsigned char *)xalloc(size)) != NULL ) {
+ ap = xalloc(sizeof(pGeode->AccelColorExpandBuffers[0]) * pGeode->NoOfColorExpandLines);
+ if( ap != NULL ) {
+ for( i=0; iNoOfColorExpandLines; ++i ) {
+ ap[i] = bp;
+ bp += pitch;
+ }
+ pGeode->AccelColorExpandBuffers = ap;
+ }
+ else {
+ xf86DrvMsg(scrnIndex, X_ERROR, "Color Expansion, No Memory\n");
+ }
+ }
+ else {
+ xf86DrvMsg(scrnIndex, X_ERROR, "Color Expansion, No offscreen Memory\n");
+ }
+ if( pGeode->AccelColorExpandBuffers == NULL ) {
+ xf86DrvMsg(scrnIndex, X_ERROR, "Accel Color Expansion disabled\n");
+ pGeode->NoOfColorExpandLines = 0;
+ }
+ }
+ }
+ else {
+ pGeode->NoOfImgBuffers = 0;
+ pGeode->AccelImageWriteBuffers = NULL;
+ pGeode->NoOfColorExpandLines = 0;
+ pGeode->AccelColorExpandBuffers = NULL;
+ }
+
+ /* Initialise graphics mode */
+ if (!LXEnterGraphics(pScrn, pScrni))
+ return FALSE;
+
+ pScrni->virtualX = virtualX;
+ pScrni->virtualY = virtualY;
+
+ DEBUGMSG(1,(0, X_INFO, "LXScreenInit(1)!\n"));
+
+ /* Reset visual list */
+ miClearVisualTypes();
+ DEBUGMSG(1,(0, X_INFO, "LXScreenInit(2)!\n"));
+
+ /* Setup the visual we support */
+ if (pScrni->bitsPerPixel > 8) {
+ DEBUGMSG(1, (scrnIndex, X_PROBED,
+ "miSetVisualTypes %d %X %X %X\n",
+ pScrni->depth,
+ TrueColorMask,
+ pScrni->rgbBits, pScrni->defaultVisual));
+
+ if (!miSetVisualTypes(pScrni->depth,
+ TrueColorMask,
+ pScrni->rgbBits,
+ pScrni->defaultVisual)) {
+ return FALSE;
+ }
+ } else {
+ if (!miSetVisualTypes(pScrni->depth,
+ miGetDefaultVisualMask(pScrni->depth),
+ pScrni->rgbBits,
+ pScrni->defaultVisual)) {
+ return FALSE;
+ }
+ }
+ DEBUGMSG(1,(0, X_INFO, "LXScreenInit(3)!\n"));
+
+ /* Set for RENDER extensions */
+ miSetPixmapDepths();
+
+ /* Call the framebuffer layer's ScreenInit function, and fill in other
+ * * pScrn fields.
+ */
+ switch (pScrni->bitsPerPixel) {
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ Inited = fbScreenInit(pScrn, FBStart, virtualX, virtualY,
+ pScrni->xDpi, pScrni->yDpi,
+ displayWidth, pScrni->bitsPerPixel);
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid bpp (%d) in ScreenInit\n",
+ pScrni->bitsPerPixel);
+ Inited = FALSE;
+ break;
+ }
+ if (!Inited)
+ return FALSE;
+
+ LXRotationInit(pScrni);
+ LXAdjustFrame(scrnIndex, pScrni->frameX0, pScrni->frameY0, 0);
+
+ /* SET UP GRAPHICS MEMORY AVAILABLE FOR PIXMAP CACHE */
+ AvailBox.x1 = 0;
+ AvailBox.y1 = (fboffset + pGeode->AccelPitch-1) / pGeode->AccelPitch;
+ AvailBox.x2 = displayWidth;
+ AvailBox.y2 = (pGeode->FBAvail - pGeode->AccelPitch+1) / pGeode->AccelPitch;
+
+ if( AvailBox.y1 < AvailBox.y2 ) {
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Initializing Memory manager to (%d,%d) (%d,%d)\n",
+ AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2);
+ REGION_INIT(pScrn, &OffscreenRegion, &AvailBox, 2);
+ if( !xf86InitFBManagerRegion(pScrn, &OffscreenRegion) ) {
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Memory manager initialization failed, Cache Diabled\n");
+ }
+ REGION_UNINIT(pScrn, &OffscreenRegion);
+ }
+ else {
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "No Off Screen Memory, Cache Disabled (%d,%d) (%d,%d)\n",
+ AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2);
+ }
+
+ DEBUGMSG(1,(0, X_INFO, "LXScreenInit(4)!\n"));
+ xf86SetBlackWhitePixels(pScrn);
+
+ if( !pGeode->ShadowFB ) {
+ LXDGAInit(pScrn);
+ }
+
+ DEBUGMSG(1,(0, X_INFO, "LXScreenInit(5)!\n"));
+ if (pScrni->bitsPerPixel > 8) {
+ /* Fixup RGB ordering */
+ visual = pScrn->visuals + pScrn->numVisuals;
+ while (--visual >= pScrn->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrni->offset.red;
+ visual->offsetGreen = pScrni->offset.green;
+ visual->offsetBlue = pScrni->offset.blue;
+ visual->redMask = pScrni->mask.red;
+ visual->greenMask = pScrni->mask.green;
+ visual->blueMask = pScrni->mask.blue;
+ }
+ }
+ }
+ /* must be after RGB ordering fixed */
+ fbPictureInit(pScrn, 0, 0);
+
+ DEBUGMSG(1,(0, X_INFO, "LXScreenInit(6)!\n"));
+ if (!pGeode->NoAccel) {
+ LXAccelInit(pScrn);
+ }
+ DEBUGMSG(1,(0, X_INFO, "LXScreenInit(7)!\n"));
+ miInitializeBackingStore(pScrn);
+ xf86SetBackingStore(pScrn);
+ DEBUGMSG(1,(0, X_INFO, "LXScreenInit(8)!\n"));
+ /* Initialise software cursor */
+ miDCInitialize(pScrn, xf86GetPointerScreenFuncs());
+ /* Initialize HW cursor layer.
+ * * Must follow software cursor initialization
+ */
+ if (pGeode->HWCursor) {
+ if (!LXHWCursorInit(pScrn))
+ xf86DrvMsg(pScrni->scrnIndex, X_ERROR,
+ "Hardware cursor initialization failed\n");
+ }
+ DEBUGMSG(1,(0, X_INFO, "LXScreenInit(9)!\n"));
+ /* Setup default colourmap */
+ if (!miCreateDefColormap(pScrn)) {
+ return FALSE;
+ }
+ DEBUGMSG(1,(0, X_INFO, "LXScreenInit(10)!\n"));
+ if( pScrni->bitsPerPixel == 8 ) {
+ /* Initialize colormap layer.
+ * * Must follow initialization of the default colormap
+ */
+ if (!xf86HandleColormaps(pScrn, 256, 8,
+ LXLoadPalette, NULL,
+ CMAP_PALETTED_TRUECOLOR |
+ CMAP_RELOAD_ON_MODE_SWITCH)) {
+ return FALSE;
+ }
+ }
+ DEBUGMSG(1,(0, X_INFO, "LXScreenInit(11)!\n"));
+
+ if (pGeode->ShadowFB) {
+ DEBUGMSG(1,(0, X_INFO, "Shadowed, Rotate=%d, NoAccel=%d\n",pGeode->Rotate,pGeode->NoAccel));
+ LXShadowFBInit(pScrn,pGeode,bytpp);
+ }
+#ifdef DPMSExtension
+ xf86DPMSInit(pScrn, LXDPMSSet, 0);
+#endif
+ DEBUGMSG(1,(0, X_INFO, "LXScreenInit(12)!\n"));
+
+ DEBUGMSG(1,(0, X_INFO, "LXScreenInit(13)!\n"));
+ LXInitVideo(pScrn); /* needed for video */
+ /* Wrap the screen's CloseScreen vector and set its
+ * SaveScreen vector
+ */
+ pGeode->CloseScreen = pScrn->CloseScreen;
+ pScrn->CloseScreen = LXCloseScreen;
+
+ pScrn->SaveScreen = LXSaveScreen;
+ DEBUGMSG(1,(0, X_INFO, "LXScreenInit(14)!\n"));
+
+ /* Report any unused options */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrni->scrnIndex, pScrni->options);
+ }
+ DEBUGMSG(1,(0, X_INFO, "LXScreenInit(15)!\n"));
+ return TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * LXSwitchMode.
+ *
+ * Description :This function will switches the screen mode
+ *
+ * Parameters:
+ * scrnIndex :Specfies the screen index value.
+ * pMode :pointer to the mode structure.
+ * flags :may be used for status check?.
+ *
+ * Returns :Returns TRUE on success and FALSE on failure.
+ *
+ * Comments :none.
+*----------------------------------------------------------------------------
+*/
+Bool
+LXSwitchMode(int scrnIndex, DisplayModePtr pMode, int flags)
+{
+ DEBUGMSG(1,(0, X_INFO, "LXSwitchMode!\n"));
+ return LXSetMode(xf86Screens[scrnIndex], pMode);
+}
+
+/*----------------------------------------------------------------------------
+ * LXAdjustFrame.
+ *
+ * Description :This function is used to intiallize the start
+ * address of the memory.
+ * Parameters.
+ * scrnIndex :Specfies the screen index value.
+ * x :x co-ordinate value interms of pixels.
+ * y :y co-ordinate value interms of pixels.
+ *
+ * Returns :none.
+ *
+ * Comments :none.
+*----------------------------------------------------------------------------
+*/
+void
+LXAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrni = xf86Screens[scrnIndex];
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ int newX, newY;
+ unsigned long offset;
+ if( x+pGeode->HDisplay >= pScrni->virtualX )
+ x = pScrni->virtualX-pGeode->HDisplay;
+ if( x < 0 ) x = 0;
+ if( y+pGeode->VDisplay >= pScrni->virtualY )
+ y = pScrni->virtualY-pGeode->VDisplay;
+ if( y < 0 ) y = 0;
+ pScrni->frameX0 = x;
+ pScrni->frameY0 = y;
+ pScrni->frameX1 = x + pGeode->HDisplay-1;
+ pScrni->frameY1 = y + pGeode->VDisplay-1;
+ (*pGeode->Rotation)(x,y,pScrni->virtualX,pScrni->virtualY,&newX,&newY);
+ (*pGeode->RBltXlat)(newX,newY,pGeode->HDisplay,pGeode->VDisplay,&newX,&newY);
+ offset = pGeode->FBOffset + newY*pGeode->Pitch + newX*(pScrni->bitsPerPixel>>3);
+ vg_set_display_offset(offset);
+}
+
+/*----------------------------------------------------------------------------
+ * LXEnterVT.
+ *
+ * Description :This is called when VT switching back to the X server
+ *
+ * Parameters.
+ * scrnIndex :Specfies the screen index value.
+ * flags :Not used inside the function.
+ *
+ * Returns :none.
+ *
+ * Comments :none.
+*----------------------------------------------------------------------------
+*/
+static Bool
+LXEnterVT(int scrnIndex, int flags)
+{
+ DEBUGMSG(1,(0, X_INFO, "LXEnterVT!\n"));
+ return LXEnterGraphics(NULL, xf86Screens[scrnIndex]);
+}
+
+/*----------------------------------------------------------------------------
+ * LXLeaveVT.
+ *
+ * Description :This is called when VT switching X server text mode.
+ *
+ * Parameters.
+ * scrnIndex :Specfies the screen index value.
+ * flags :Not used inside the function.
+ *
+ * Returns :none.
+ *
+ * Comments :none.
+*----------------------------------------------------------------------------
+*/
+static void
+LXLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrni = xf86Screens[scrnIndex];
+ GeodePtr pGeode = GEODEPTR(pScrni);
+
+ pGeode->PrevDisplayOffset = vg_get_display_offset();
+ DEBUGMSG(1,(0, X_INFO, "LXLeaveVT!\n"));
+ LXLeaveGraphics(xf86Screens[scrnIndex]);
+}
+
+/*----------------------------------------------------------------------------
+ * LXFreeScreen.
+ *
+ * Description :This is called to free any persistent data structures.
+ *
+ * Parameters.
+ * scrnIndex :Specfies the screen index value.
+ * flags :Not used inside the function.
+ *
+ * Returns :none.
+ *
+ * Comments :This will be called only when screen being deleted..
+*----------------------------------------------------------------------------
+*/
+static void
+LXFreeScreen(int scrnIndex, int flags)
+{
+ DEBUGMSG(1,(0, X_INFO, "LXFreeScreen!\n"));
+ if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+ LXFreeRec(xf86Screens[scrnIndex]);
+}
+
+/*----------------------------------------------------------------------------
+ * LXValidMode.
+ *
+ * Description :This function checks if a mode is suitable for selected
+ * chipset.
+ * Parameters.
+ * scrnIndex :Specfies the screen index value.
+ * pMode :Pointer to the screen mode structure..
+ * verbose :not used for implementation.
+ * flags :not used for implementation
+ *
+ * Returns :MODE_OK if the specified mode is supported or
+ * MODE_NO_INTERLACE.
+ * Comments :none.
+*----------------------------------------------------------------------------
+*/
+static int
+LXValidMode(int scrnIndex, DisplayModePtr pMode, Bool Verbose, int flags)
+{
+ unsigned int total_memory_required;
+ ScrnInfoPtr pScrni = xf86Screens[scrnIndex];
+ int ret = -1;
+ GeodePtr pGeode = GEODEPTR(pScrni);
+
+ DEBUGMSG(0, (0, X_NONE, "GeodeValidateMode: %dx%d %d %d\n",
+ pMode->CrtcHDisplay, pMode->CrtcVDisplay,
+ pScrni->bitsPerPixel, LXGetRefreshRate(pMode)));
+ if( pGeode->CustomMode == 0 ) {
+ int tv_mode;
+ VG_QUERY_MODE vgQueryMode;
+ unsigned long flags;
+
+ if (pMode->Flags & V_INTERLACE)
+ return MODE_NO_INTERLACE;
+
+ flags = VG_QUERYFLAG_REFRESH | VG_QUERYFLAG_BPP |
+ VG_QUERYFLAG_ACTIVEWIDTH | VG_QUERYFLAG_ACTIVEHEIGHT;
+
+ if( (pGeode->EnabledOutput&LX_OT_FP) != 0 ) {
+ /* scaling required, but too big to scale */
+ if( pGeode->FPGeomDstX != pMode->CrtcHDisplay && pMode->CrtcHDisplay > 1024 )
+ return MODE_NOMODE;
+ flags = VG_QUERYFLAG_PANELWIDTH | VG_QUERYFLAG_PANELHEIGHT |
+ VG_QUERYFLAG_PANEL;
+ vgQueryMode.panel_width = pGeode->FPGeomDstX;
+ vgQueryMode.panel_height = pGeode->FPGeomDstY;
+ }
+
+ vgQueryMode.active_width = pMode->CrtcHDisplay;
+ vgQueryMode.active_height = pMode->CrtcVDisplay;
+ vgQueryMode.bpp = pScrni->bitsPerPixel;
+ vgQueryMode.hz = LXGetRefreshRate(pMode);
+ vgQueryMode.query_flags = VG_QUERYFLAG_REFRESH | VG_QUERYFLAG_BPP |
+ VG_QUERYFLAG_ACTIVEWIDTH | VG_QUERYFLAG_ACTIVEHEIGHT;
+ if( (tv_mode=lx_tv_mode(pMode)) >= 0 ) {
+ vgQueryMode.encoder = pGeode->tv_encoder;
+ vgQueryMode.tvmode = tv_mode;
+ vgQueryMode.query_flags |= VG_QUERYFLAG_TVMODE | VG_QUERYFLAG_ENCODER;
+ vgQueryMode.query_flags &= ~VG_QUERYFLAG_REFRESH;
+ if( lx_tv_mode_interlaced(tv_mode) != 0 ) {
+ vgQueryMode.query_flags |= VG_QUERYFLAG_INTERLACED;
+ vgQueryMode.active_height /= 2;
+ }
+ }
+ ret = vg_get_display_mode_index(&vgQueryMode);
+ if (ret < 0)
+ return MODE_NOMODE;
+ }
+
+ total_memory_required = LXCalculatePitchBytes(pMode->CrtcHDisplay,
+ pScrni->bitsPerPixel) * pMode->CrtcVDisplay;
+
+ DEBUGMSG(0, (0, X_NONE, "Total Mem %x %lx\n",
+ total_memory_required, pGeode->FBAvail));
+
+ if (total_memory_required > pGeode->FBAvail)
+ return MODE_MEM;
+
+ return MODE_OK;
+}
+
+/*----------------------------------------------------------------------------
+ * LXLoadPalette.
+ *
+ * Description :This function sets the palette entry used for graphics data
+ *
+ * Parameters.
+ * pScrni:Points the screeninfo structure.
+ * numColors:Specifies the no of colors it supported.
+ * indizes :This is used get index value .
+ * LOCO :to be added.
+ * pVisual :to be added.
+ *
+ * Returns :MODE_OK if the specified mode is supported or
+ * MODE_NO_INTERLACE.
+ * Comments :none.
+*----------------------------------------------------------------------------
+*/
+
+static void
+LXLoadPalette(ScrnInfoPtr pScrni,
+ int numColors, int *indizes, LOCO * colors, VisualPtr pVisual)
+{
+ int i, index, color;
+
+ for (i = 0; i < numColors; i++) {
+ index = indizes[i] & 0xFF;
+ color = (((unsigned long)(colors[index].red & 0xFF)) << 16) |
+ (((unsigned long)(colors[index].green & 0xFF)) << 8) |
+ ((unsigned long)(colors[index].blue & 0xFF));
+ vg_set_display_palette_entry(index, color);
+ }
+}
+
+static Bool
+LXMapMem(ScrnInfoPtr pScrni)
+{
+ unsigned long cmd_bfr_phys;
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ DEBUGMSG(1, (0, X_NONE, "LXMapMem\n"));
+
+ cim_gp_ptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex,
+ VIDMEM_MMIO,
+ pGeode->InitBaseAddress.gp_register_base,
+ pGeode->gp_reg_size);
+ cim_vg_ptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex,
+ VIDMEM_MMIO,
+ pGeode->InitBaseAddress.vg_register_base,
+ pGeode->vg_reg_size);
+ cim_vid_ptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex,
+ VIDMEM_MMIO,
+ pGeode->InitBaseAddress.df_register_base,
+ pGeode->vid_reg_size);
+
+ cim_vip_ptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex,
+ VIDMEM_MMIO,
+ pGeode->InitBaseAddress.vip_register_base,
+ pGeode->vip_reg_size);
+
+ cim_fb_ptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex,
+ VIDMEM_FRAMEBUFFER,
+ pGeode->InitBaseAddress.framebuffer_base,
+ pGeode->InitBaseAddress.framebuffer_size);
+ pGeode->FBBase = cim_fb_ptr;
+
+ DEBUGMSG(1, (0, X_NONE, "cim ptrs %p %p %p %p %p\n",
+ cim_gp_ptr, cim_vg_ptr, cim_vid_ptr,
+ cim_vip_ptr, cim_fb_ptr));
+
+ /* CHECK IF REGISTERS WERE MAPPED SUCCESSFULLY */
+ if ((!cim_gp_ptr) || (!cim_vid_ptr) || (!cim_fb_ptr)) {
+ DEBUGMSG(1, (0, X_NONE, "Could not map hardware registers.\n"));
+ return (FALSE);
+ }
+
+ cmd_bfr_phys = pGeode->InitBaseAddress.framebuffer_base + pGeode->CmdBfrOffset;
+ cim_cmd_base_ptr = cim_fb_ptr + pGeode->CmdBfrOffset;
+
+ /* map the top of the frame buffer as the scratch buffer (GP3_SCRATCH_BUFFER_SIZE) */
+ gp_set_frame_buffer_base(pGeode->InitBaseAddress.framebuffer_base,pGeode->FBTop);
+ gp_set_command_buffer_base(cmd_bfr_phys,0,pGeode->CmdBfrSize);
+ DEBUGMSG(1, (0, X_NONE, "cim cmd %p %lx %lx %lx\n",
+ cim_cmd_base_ptr, pGeode->CmdBfrSize, cmd_bfr_phys, pGeode->FBTop));
+
+ /* Map the XpressROM ptr to read what platform are we on */
+ XpressROMPtr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex,
+ VIDMEM_FRAMEBUFFER, 0xF0000,
+ 0x10000);
+
+ DEBUGMSG(1, (0, X_NONE, "adapter info %lx %lx %lx %lx %p, %p\n",
+ pGeode->cpu_version,
+ pGeode->vid_version, pGeode->FBLinearAddr,
+ pGeode->FBAvail, pGeode->FBBase, XpressROMPtr));
+
+ return TRUE;
+}
+
+/*
+ * Unmap the framebuffer and MMIO memory.
+ */
+
+static Bool
+LXUnmapMem(ScrnInfoPtr pScrni)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ DEBUGMSG(1, (0, X_NONE, "LXUnMapMem\n"));
+
+ /* unmap all the memory map's */
+ xf86UnMapVidMem(pScrni->scrnIndex,
+ cim_gp_ptr, pGeode->gp_reg_size);
+ xf86UnMapVidMem(pScrni->scrnIndex,
+ cim_vg_ptr, pGeode->vg_reg_size);
+ xf86UnMapVidMem(pScrni->scrnIndex,
+ cim_vid_ptr, pGeode->vid_reg_size);
+ xf86UnMapVidMem(pScrni->scrnIndex,
+ cim_vip_ptr, pGeode->vip_reg_size);
+ xf86UnMapVidMem(pScrni->scrnIndex,
+ cim_fb_ptr, pGeode->InitBaseAddress.framebuffer_size);
+ xf86UnMapVidMem(pScrni->scrnIndex, XpressROMPtr, 0x10000);
+ return TRUE;
+}
+
+/* End of file */
diff -urN xf86-video-nsc-2.8.1-orig/src/amd_lx_regacc.c xf86-video-nsc-2.8.1/src/amd_lx_regacc.c
--- xf86-video-nsc-2.8.1-orig/src/amd_lx_regacc.c 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/amd_lx_regacc.c 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,70 @@
+/*
+ * $Workfile: amd_regacc.c $
+ * $Revision: #2 $
+ * $Author: raymondd $
+ *
+ * This is the main file used to add Cimarron graphics support to a software
+ * project. The main reason to have a single file include the other files
+ * is that it centralizes the location of the compiler options. This file
+ * should be tuned for a specific implementation, and then modified as needed
+ * for new Cimarron releases. The releases.txt file indicates any updates to
+ * this main file, such as a new definition for a new hardware platform.
+ *
+ * In other words, this file should be copied from the Cimarron source files
+ * once when a software project starts, and then maintained as necessary.
+ * It should not be recopied with new versions of Cimarron unless the
+ * developer is willing to tune the file again for the specific project.
+ */
+
+/*
+ * Copyright (c) 2003-2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice 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.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+/*
+ * */
+/*
+ * */
+
+#include "cim_defs.h"
+
+extern unsigned char *cim_vid_ptr;
+
+void cim_write_vid32(unsigned long offset, unsigned long value);
+unsigned long cim_read_vid32(unsigned long offset);
+
+ void
+cim_write_vid32(unsigned long offset, unsigned long value)
+{
+ WRITE_VID32(offset, value);
+}
+unsigned long
+cim_read_vid32(unsigned long offset)
+{
+ unsigned long value;
+
+ value = READ_VID32(offset);
+ return value;
+}
+
+/* END OF FILE */
diff -urN xf86-video-nsc-2.8.1-orig/src/amd_lx_shadow.c xf86-video-nsc-2.8.1/src/amd_lx_shadow.c
--- xf86-video-nsc-2.8.1-orig/src/amd_lx_shadow.c 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/amd_lx_shadow.c 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,436 @@
+/*
+ * $Workfile: amd_lx_shadow.c $
+ * $Revision: #3 $
+ * $Author: raymondd $
+ *
+ * File Contents: Direct graphics display routines are implemented and
+ * graphics rendering are all done in memory.
+ *
+ * Project: Geode Xfree Frame buffer device driver.
+ *
+ *
+ */
+
+/*
+ * Copyright (c) 2003-2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice 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.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+/*
+ * */
+/*
+ * */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86_ansic.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "nsc.h"
+#include "shadowfb.h"
+#include "servermd.h"
+
+#define CLIP(sip,bp,u1,v1,u2,v2) \
+ u1 = bp->x1; v1 = bp->y1; \
+ u2 = bp->x2; v2 = bp->y2; \
+ if( u1 < 0 ) u1 = 0; \
+ if( v1 < 0 ) v1 = 0; \
+ if( u1 > sip->virtualX ) u1 = sip->virtualX; \
+ if( v1 > sip->virtualY ) v1 = sip->virtualY; \
+ if( u2 < 0 ) u2 = 0; \
+ if( v2 < 0 ) v2 = 0; \
+ if( u2 > sip->virtualX ) u2 = sip->virtualX; \
+ if( v2 > sip->virtualY ) v2 = sip->virtualY;
+
+void LXAccelSync(ScrnInfoPtr pScrni);
+
+void
+LXRotation0(int x,int y,int w,int h,int *newX,int *newY)
+{
+ *newX = x;
+ *newY = y;
+}
+
+void
+LXRotation1(int x,int y,int w,int h,int *newX,int *newY)
+{
+ *newX = (h-1) - y;
+ *newY = x;
+}
+
+void
+LXRotation2(int x,int y,int w,int h,int *newX,int *newY)
+{
+ *newX = (w-1) - x;
+ *newY = (h-1) - y;
+}
+
+void
+LXRotation3(int x,int y,int w,int h,int *newX,int *newY)
+{
+ *newY = (w-1) - x;
+ *newX = y;
+}
+
+void
+LXRBltXlat0(int x,int y,int w,int h,int *newX,int *newY)
+{
+ *newX = x;
+ *newY = y;
+}
+
+void
+LXRBltXlat1(int x,int y,int w,int h,int *newX,int *newY)
+{
+ *newX = x - (h-1);
+ *newY = y;
+}
+
+void
+LXRBltXlat2(int x,int y,int w,int h,int *newX,int *newY)
+{
+ *newX = x - (w-1);
+ *newY = y - (h-1);
+}
+
+void
+LXRBltXlat3(int x,int y,int w,int h,int *newX,int *newY)
+{
+ *newX = x;
+ *newY = y - (w-1);
+}
+
+/*----------------------------------------------------------------------------
+ * LXPointerMoved.
+ *
+ * Description :This function moves one screen memory from one area to other.
+ *
+ * Parameters.
+ * index :Pointer to screen index.
+ * x :Specifies the new x co-ordinates of new area.
+ * y :Specifies the new y co-ordinates of new area.
+ * Returns :none
+ *
+ * Comments :none
+ *
+*----------------------------------------------------------------------------
+*/
+void
+LXPointerMoved(int index, int x, int y)
+{
+ ScrnInfoPtr pScrni = xf86Screens[index];
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ Bool frameChanged = FALSE;
+
+ if( x < 0 )
+ x = 0;
+ else if( x >= pScrni->virtualX )
+ x = pScrni->virtualX-1;
+ if( y < 0 )
+ y = 0;
+ else if( y >= pScrni->virtualY )
+ y = pScrni->virtualY-1;
+
+ if( pScrni->frameX0 > x ) {
+ pScrni->frameX0 = x;
+ pScrni->frameX1 = x + pGeode->HDisplay - 1;
+ frameChanged = TRUE ;
+ }
+
+ if( pScrni->frameX1 < x ) {
+ pScrni->frameX1 = x + 1;
+ pScrni->frameX0 = x - pGeode->HDisplay + 1;
+ frameChanged = TRUE ;
+ }
+
+ if( pScrni->frameY0 > y ) {
+ pScrni->frameY0 = y;
+ pScrni->frameY1 = y + pGeode->VDisplay - 1;
+ frameChanged = TRUE;
+ }
+
+ if( pScrni->frameY1 < y ) {
+ pScrni->frameY1 = y;
+ pScrni->frameY0 = y - pGeode->VDisplay + 1;
+ frameChanged = TRUE;
+ }
+
+ if(frameChanged && pScrni->AdjustFrame != NULL)
+ pScrni->AdjustFrame(pScrni->scrnIndex, pScrni->frameX0, pScrni->frameY0, 0);
+}
+
+void
+LXRefreshArea_Cpy(ScrnInfoPtr pScrni, int num, BoxPtr pbox)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ int x1, y1, x2, y2, width, height;
+ unsigned long src, dst;
+ int Bpp = pScrni->bitsPerPixel >> 3;
+ gp_declare_blt(0);
+ gp_set_raster_operation(0xcc); /* copy dst=src */
+ gp_write_parameters();
+ for( ; --num>=0; ++pbox ) {
+ CLIP(pScrni,pbox,x1,y1,x2,y2);
+ if( (width=x2-x1) <=0 || (height=y2-y1) <= 0 ) continue;
+ src = y1*pGeode->ShadowPitch + x1*Bpp;
+ dst = pGeode->FBOffset + y1*pGeode->Pitch + x1*Bpp;
+ gp_declare_blt(0);
+ gp_set_strides(pGeode->Pitch, pGeode->ShadowPitch);
+ gp_screen_to_screen_blt(dst,src, width,height, 0);
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * LXRefreshArea8.
+ *
+ * Description :This function copies the memory to be displayed from the
+ * shadow pointer by 8bpp.
+ * Parameters.
+ * pScrni :Pointer to ScrnInfo structure.
+ * num :Specifies the num of squarebox area to be displayed.
+ * pbox :Points to square of memory to be displayed.
+ * Returns :none
+ *
+ * Comments :none
+ *
+*----------------------------------------------------------------------------
+*/
+
+static int lx_shdw_fmt[4] = {
+ CIMGP_SOURCE_FMT_3_3_2,
+ CIMGP_SOURCE_FMT_0_5_6_5,
+ CIMGP_SOURCE_FMT_24BPP,
+ CIMGP_SOURCE_FMT_8_8_8_8
+};
+
+
+void
+LXRefreshArea_Blt(ScrnInfoPtr pScrni, int num, BoxPtr pbox)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ int width, height, x1, y1, x2, y2, newX, newY;
+ unsigned long src, dst;
+ int Bpp = pScrni->bitsPerPixel >> 3;
+ gp_set_source_format(lx_shdw_fmt[Bpp-1]);
+ gp_declare_blt(0);
+ gp_set_raster_operation(0xcc); /* copy dst=src */
+ gp_write_parameters();
+ for( ; --num>=0; ++pbox ) {
+ CLIP(pScrni,pbox,x1,y1,x2,y2);
+ if( (width=x2-x1) <=0 || (height=y2-y1) <= 0 ) continue;
+ (*pGeode->Rotation)(x1,y1,pScrni->virtualX,pScrni->virtualY,&newX,&newY);
+ (*pGeode->RBltXlat)(newX,newY,width,height,&newX,&newY);
+ src = y1*pGeode->ShadowPitch + x1*Bpp;
+ dst = pGeode->FBOffset + newY*pGeode->Pitch + newX*Bpp;
+ gp_declare_blt(0);
+ gp_set_strides(pGeode->Pitch, pGeode->ShadowPitch);
+ gp_rotate_blt(dst,src, width,height, pGeode->Rotate*90);
+ }
+}
+
+void
+LXRefreshArea0_Cpu(ScrnInfoPtr pScrni, int num, BoxPtr pbox)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ int width, height, x1, y1, x2, y2;
+ unsigned char *src, *dst;
+ int Bpp = pScrni->bitsPerPixel >> 3;
+ LXAccelSync(pScrni);
+ for( ; --num>=0; ++pbox ) {
+ CLIP(pScrni,pbox,x1,y1,x2,y2);
+ if( (width=x2-x1) <=0 || (height=y2-y1) <= 0 ) continue;
+ src = pGeode->ShadowPtr + y1*pGeode->ShadowPitch + x1*Bpp;
+ dst = pGeode->FBBase+pGeode->FBOffset + y1*pGeode->Pitch + x1*Bpp;
+ width *= Bpp;
+ while( --height >= 0 ) {
+ memcpy(dst,src,width);
+ dst += pGeode->Pitch;
+ src += pGeode->ShadowPitch;
+ }
+ }
+}
+
+#define RefreshArea1_Cpu(nm,typ) \
+void LXRefreshArea1_Cpu##nm(ScrnInfoPtr pScrni, int num, BoxPtr pbox)\
+{ \
+ GeodePtr pGeode = GEODEPTR(pScrni); \
+ int l, width, height, x1, y1, x2, y2, newX, newY; \
+ unsigned long src, dst, dp; \
+ typ *sp; \
+ LXAccelSync(pScrni); \
+ for( ; --num>=0; ++pbox ) { \
+ CLIP(pScrni,pbox,x1,y1,x2,y2); \
+ if( (width=x2-x1) <=0 || (height=y2-y1) <= 0 ) continue; \
+ src = y1*pGeode->ShadowPitch + x1*sizeof(typ); \
+ newX = pScrni->virtualY-1 - y1; \
+ newY = x1; \
+ dst = pGeode->FBOffset + newY*pGeode->Pitch + newX*sizeof(typ); \
+ while( --height >= 0 ) { \
+ sp = (typ *)(pGeode->ShadowPtr + src); \
+ dp = (unsigned long)(pGeode->FBBase + dst); \
+ for( l=width; --l>=0; ) { \
+ *(typ *)dp = *sp++; \
+ dp += pGeode->Pitch; \
+ } \
+ dst -= sizeof(typ); \
+ src += pGeode->ShadowPitch; \
+ } \
+ } \
+}
+
+RefreshArea1_Cpu( 8,unsigned char)
+RefreshArea1_Cpu(16,unsigned short)
+RefreshArea1_Cpu(32,unsigned int)
+
+#define RefreshArea2_Cpu(nm,typ) \
+void LXRefreshArea2_Cpu##nm(ScrnInfoPtr pScrni, int num, BoxPtr pbox)\
+{ \
+ GeodePtr pGeode = GEODEPTR(pScrni); \
+ int l, width, height, x1, y1, x2, y2, newX, newY; \
+ unsigned long src, dst, dp; \
+ typ *sp; \
+ LXAccelSync(pScrni); \
+ for( ; --num>=0; ++pbox ) { \
+ CLIP(pScrni,pbox,x1,y1,x2,y2); \
+ if( (width=x2-x1) <=0 || (height=y2-y1) <= 0 ) continue; \
+ src = y1*pGeode->ShadowPitch + x1*sizeof(typ); \
+ newX = pScrni->virtualX-1 - x1; \
+ newY = pScrni->virtualY-1 - y1; \
+ dst = pGeode->FBOffset + newY*pGeode->Pitch + newX*sizeof(typ); \
+ while( --height >= 0 ) { \
+ sp = (typ *)(pGeode->ShadowPtr + src); \
+ dp = (unsigned long)(pGeode->FBBase + dst); \
+ for( l=width; --l>=0; ) { \
+ *(typ *)dp = *sp++; \
+ dp -= sizeof(typ); \
+ } \
+ src += pGeode->ShadowPitch; \
+ dst -= pGeode->Pitch; \
+ } \
+ } \
+}
+
+RefreshArea2_Cpu( 8,unsigned char)
+RefreshArea2_Cpu(16,unsigned short)
+RefreshArea2_Cpu(32,unsigned int)
+
+#define RefreshArea3_Cpu(nm,typ) \
+void LXRefreshArea3_Cpu##nm(ScrnInfoPtr pScrni, int num, BoxPtr pbox)\
+{ \
+ GeodePtr pGeode = GEODEPTR(pScrni); \
+ int l, width, height, x1, y1, x2, y2, newX, newY; \
+ unsigned long src, dst, dp; \
+ typ *sp; \
+ LXAccelSync(pScrni); \
+ for( ; --num>=0; ++pbox ) { \
+ CLIP(pScrni,pbox,x1,y1,x2,y2); \
+ if( (width=x2-x1) <=0 || (height=y2-y1) <= 0 ) continue; \
+ src = y1*pGeode->ShadowPitch + x1*sizeof(typ); \
+ newX = y1; \
+ newY = pScrni->virtualX-1 - x1; \
+ dst = pGeode->FBOffset + newY*pGeode->Pitch + newX*sizeof(typ); \
+ while( --height >= 0 ) { \
+ sp = (typ *)(pGeode->ShadowPtr + src); \
+ dp = (unsigned long)(pGeode->FBBase + dst); \
+ for( l=width; --l>=0; ) { \
+ *(typ *)dp = *sp++; \
+ dp -= pGeode->Pitch; \
+ } \
+ dst += sizeof(typ); \
+ src += pGeode->ShadowPitch; \
+ } \
+ } \
+}
+
+RefreshArea3_Cpu( 8,unsigned char)
+RefreshArea3_Cpu(16,unsigned short)
+RefreshArea3_Cpu(32,unsigned int)
+
+void
+LXRotationInit(ScrnInfoPtr pScrni)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ switch( pGeode->Rotate ) {
+ case 1:
+ pGeode->Rotation = LXRotation1;
+ pGeode->RBltXlat = LXRBltXlat1;
+ break;
+ case 2:
+ pGeode->Rotation = LXRotation2;
+ pGeode->RBltXlat = LXRBltXlat2;
+ break;
+ case 3:
+ pGeode->Rotation = LXRotation3;
+ pGeode->RBltXlat = LXRBltXlat3;
+ break;
+ default:
+ pGeode->Rotation = LXRotation0;
+ pGeode->RBltXlat = LXRBltXlat0;
+ break;
+ }
+}
+
+void
+LXShadowFBInit(ScreenPtr pScrn,GeodePtr pGeode,int bytpp)
+{
+ RefreshAreaFuncPtr refreshArea;
+ if( pGeode->NoAccel || !pGeode->ShadowInFBMem || 0 ) {
+ switch( bytpp ) {
+ case 2:
+ switch( pGeode->Rotate ) {
+ case 1: refreshArea = LXRefreshArea1_Cpu16; break;
+ case 2: refreshArea = LXRefreshArea2_Cpu16; break;
+ case 3: refreshArea = LXRefreshArea3_Cpu16; break;
+ default: refreshArea = LXRefreshArea0_Cpu; break;
+ }
+ break;
+ case 4:
+ switch( pGeode->Rotate ) {
+ case 1: refreshArea = LXRefreshArea1_Cpu32; break;
+ case 2: refreshArea = LXRefreshArea2_Cpu32; break;
+ case 3: refreshArea = LXRefreshArea3_Cpu32; break;
+ default: refreshArea = LXRefreshArea0_Cpu; break;
+ }
+ break;
+ default:
+ switch( pGeode->Rotate ) {
+ case 1: refreshArea = LXRefreshArea1_Cpu8; break;
+ case 2: refreshArea = LXRefreshArea2_Cpu8; break;
+ case 3: refreshArea = LXRefreshArea3_Cpu8; break;
+ default: refreshArea = LXRefreshArea0_Cpu; break;
+ }
+ break;
+ }
+ }
+ else {
+ refreshArea = pGeode->Rotate? LXRefreshArea_Blt : LXRefreshArea_Cpy;
+ }
+ ShadowFBInit(pScrn, refreshArea);
+}
+
+/* End of file */
diff -urN xf86-video-nsc-2.8.1-orig/src/amd_lx_vga.c xf86-video-nsc-2.8.1/src/amd_lx_vga.c
--- xf86-video-nsc-2.8.1-orig/src/amd_lx_vga.c 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/amd_lx_vga.c 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,56 @@
+/*
+ * $Workfile: amd_lx_vga.c $
+ * $Revision: #3 $
+ * $Author: raymondd $
+ *
+ * This file contains routines to set modes using the VGA registers.
+ * Since this file is for the first generation graphics unit, it interfaces
+ * to SoftVGA registers. It works for both VSA1 and VSA2.
+ */
+
+/*
+ * Copyright (c) 2003-2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice 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.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+/*
+ * */
+/*
+ * */
+
+
+/* VGA STRUCTURE */
+
+int gu3_get_vga_active(void);
+
+int
+gu3_get_vga_active(void)
+{
+ int data = READ_REG32(DC3_GENERAL_CFG);
+
+ if (data & DC3_GCFG_VGAE)
+ return 1;
+ return 0;
+}
+
+/* END OF FILE */
diff -urN xf86-video-nsc-2.8.1-orig/src/amd_lx_video.c xf86-video-nsc-2.8.1/src/amd_lx_video.c
--- xf86-video-nsc-2.8.1-orig/src/amd_lx_video.c 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/amd_lx_video.c 2006-07-11 18:15:59.000000000 +0200
@@ -0,0 +1,1436 @@
+/*
+ * $Workfile: amd_lx_video.c $
+ * $Revision: #3 $
+ * $Author: raymondd $
+ *
+ * File Contents: This file consists of main Xfree video supported routines.
+ *
+ * Project: Geode Xfree Frame buffer device driver.
+ *
+ */
+
+/*
+ * Copyright (c) 2003-2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice 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.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+/*
+ * */
+/*
+ * */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/*
+ * Fixes & Extensions to support Y800 greyscale modes
+ * Alan Hourihane
+ */
+#ifndef AMD_V4L2_VIDEO
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86fbman.h"
+#include "regionstr.h"
+
+#include "nsc.h"
+#include
+#include "xaa.h"
+#include "xaalocal.h"
+#include "dixstruct.h"
+#include "fourcc.h"
+#include "nsc_fourcc.h"
+
+#if DEBUGLVL>0
+#define DBLOG(n,s...) do { if((DEBUGLVL)>=(n)) fprintf(zdfp,s); } while(0)
+#include "xf86_ansic.h"
+extern FILE *zdfp;
+#else
+#define DBLOG(n,s...) do {} while(0)
+#endif
+
+#define OFF_DELAY 200 /* milliseconds */
+#define FREE_DELAY 60000
+
+#define OFF_TIMER 0x01
+#define FREE_TIMER 0x02
+#define CLIENT_VIDEO_ON 0x04
+
+#define TIMER_MASK (OFF_TIMER | FREE_TIMER)
+#define XV_PROFILE 0
+#define REINIT 1
+
+#define DBUF 1
+void LXInitVideo(ScreenPtr pScrn);
+void LXResetVideo(ScrnInfoPtr pScrni);
+static XF86VideoAdaptorPtr LXSetupImageVideo(ScreenPtr);
+static void LXInitOffscreenImages(ScreenPtr);
+static void LXStopVideo(ScrnInfoPtr, pointer, Bool);
+static int LXSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer);
+static int LXGetPortAttribute(ScrnInfoPtr, Atom, INT32 *, pointer);
+static void LXQueryBestSize(ScrnInfoPtr, Bool,
+ short, short, short, short, unsigned int *,
+ unsigned int *, pointer);
+static int LXPutImage(ScrnInfoPtr, short, short, short, short, short, short,
+ short, short, int, unsigned char *, short, short, Bool,
+ RegionPtr, pointer);
+static int LXQueryImageAttributes(ScrnInfoPtr, int, unsigned short *,
+ unsigned short *, int *, int *);
+
+static void LXBlockHandler(int, pointer, pointer, pointer);
+void LXSetVideoPosition(int x, int y, int width, int height,
+ short src_w, short src_h, short drw_w,
+ short drw_h, int id, int offset, ScrnInfoPtr pScrni);
+
+extern void LXAccelSync(ScrnInfoPtr pScrni);
+
+#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
+
+static Atom xvColorKey, xvColorKeyMode, xvFilter
+#if DBUF
+ , xvDoubleBuffer
+#endif
+ ;
+
+/*----------------------------------------------------------------------------
+ * LXInitVideo
+ *
+ * Description :This is the initialization routine.It creates a new video adapter
+ * and calls LXSetupImageVideo to initialize the adaptor by filling
+ * XF86VideoAdaptorREc.Then it lists the existing adaptors and adds the
+ * new one to it. Finally the list of XF86VideoAdaptorPtr pointers are
+ * passed to the xf86XVScreenInit().
+ *
+ * Parameters.
+ * ScreenPtr
+ * pScrn :Screen handler pointer having screen information.
+ *
+ * Returns :none
+ *
+ * Comments :none
+ *
+*----------------------------------------------------------------------------
+*/
+void
+LXInitVideo(ScreenPtr pScrn)
+{
+ GeodePtr pGeode;
+ ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum];
+ DBLOG(1,"LXInitVideo()\n");
+
+ pGeode = GEODEPTR(pScrni);
+
+ if (!pGeode->NoAccel) {
+ XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
+ XF86VideoAdaptorPtr newAdaptor = NULL;
+
+ int num_adaptors;
+
+ newAdaptor = LXSetupImageVideo(pScrn);
+ LXInitOffscreenImages(pScrn);
+
+ num_adaptors = xf86XVListGenericAdaptors(pScrni, &adaptors);
+
+ if (newAdaptor) {
+ if (!num_adaptors) {
+ num_adaptors = 1;
+ adaptors = &newAdaptor;
+ } else {
+ newAdaptors = /* need to free this someplace */
+ xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr *));
+ if (newAdaptors) {
+ memcpy(newAdaptors, adaptors, num_adaptors *
+ sizeof(XF86VideoAdaptorPtr));
+ newAdaptors[num_adaptors] = newAdaptor;
+ adaptors = newAdaptors;
+ num_adaptors++;
+ }
+ }
+ }
+
+ if (num_adaptors)
+ xf86XVScreenInit(pScrn, adaptors, num_adaptors);
+
+ if (newAdaptors)
+ xfree(newAdaptors);
+ }
+}
+
+/* client libraries expect an encoding */
+static XF86VideoEncodingRec DummyEncoding[1] = {
+ {
+ 0,
+ "XV_IMAGE",
+ 1024, 1024,
+ {1, 1}
+ }
+};
+
+#define NUM_FORMATS 4
+
+static XF86VideoFormatRec Formats[NUM_FORMATS] = {
+ {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
+};
+
+#if DBUF
+#define NUM_ATTRIBUTES 4
+#else
+#define NUM_ATTRIBUTES 3
+#endif
+
+static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = {
+#if DBUF
+ {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"},
+#endif
+ {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
+ {XvSettable | XvGettable, 0, 1, "XV_FILTER"},
+ {XvSettable | XvGettable, 0, 1, "XV_COLORKEYMODE"}
+};
+
+static XF86ImageRec Images[] = {
+ XVIMAGE_UYVY,
+ XVIMAGE_YUY2,
+ XVIMAGE_Y2YU,
+ XVIMAGE_YVYU,
+ XVIMAGE_Y800,
+ XVIMAGE_I420,
+ XVIMAGE_YV12
+};
+
+#define NUM_IMAGES (sizeof(Images)/sizeof(Images[0]));
+
+typedef struct
+{
+ FBAreaPtr area;
+ FBLinearPtr linear;
+ RegionRec clip;
+ CARD32 filter;
+ CARD32 colorKey;
+ CARD32 colorKeyMode;
+ CARD32 videoStatus;
+ Time offTime;
+ Time freeTime;
+#if DBUF
+ Bool doubleBuffer;
+ int currentBuffer;
+#endif
+}
+GeodePortPrivRec, *GeodePortPrivPtr;
+
+#define GET_PORT_PRIVATE(pScrni) \
+ (GeodePortPrivPtr)((GEODEPTR(pScrni))->adaptor->pPortPrivates[0].ptr)
+
+/*----------------------------------------------------------------------------
+ * LXSetColorKey
+ *
+ * Description :This function reads the color key for the pallete and
+ * sets the video color key register.
+ *
+ * Parameters.
+ * ScreenInfoPtr
+ * pScrni :Screen pointer having screen information.
+ * pPriv :Video port private data
+ *
+ * Returns :none
+ *
+ * Comments :none
+ *
+*----------------------------------------------------------------------------
+*/
+static INT32
+LXSetColorkey(ScrnInfoPtr pScrni, GeodePortPrivPtr pPriv)
+{
+ int red, green, blue;
+ unsigned long key;
+
+ switch (pScrni->depth) {
+ case 8:
+ vg_get_display_palette_entry(pPriv->colorKey & 0xFF, &key);
+ red = ((key >> 16) & 0xFF);
+ green = ((key >> 8) & 0xFF);
+ blue = (key & 0xFF);
+ break;
+ case 16:
+ red = (pPriv->colorKey & pScrni->mask.red) >>
+ pScrni->offset.red << (8 - pScrni->weight.red);
+ green = (pPriv->colorKey & pScrni->mask.green) >>
+ pScrni->offset.green << (8 - pScrni->weight.green);
+ blue = (pPriv->colorKey & pScrni->mask.blue) >>
+ pScrni->offset.blue << (8 - pScrni->weight.blue);
+ break;
+ default:
+ /* for > 16 bpp we send in the mask in xf86SetWeight. This
+ * function is providing the offset by 1 more. So we take
+ * this as a special case and subtract 1 for > 16
+ */
+ red = (pPriv->colorKey & pScrni->mask.red) >>
+ (pScrni->offset.red - 1) << (8 - pScrni->weight.red);
+ green = (pPriv->colorKey & pScrni->mask.green) >>
+ (pScrni->offset.green - 1) << (8 - pScrni->weight.green);
+ blue = (pPriv->colorKey & pScrni->mask.blue) >>
+ (pScrni->offset.blue - 1) << (8 - pScrni->weight.blue);
+ break;
+ }
+
+ DBLOG(1,"LXSetColorkey() %08x %d\n",blue|(green<<8)|(red<<16),pPriv->colorKeyMode);
+ if( pPriv->colorKeyMode != 0 )
+ df_set_video_color_key((blue | (green << 8) | (red << 16)), 0xFFFFFF, 1);
+ else
+ df_set_video_color_key(0,0,1);
+ REGION_EMPTY(pScrni->pScreen, &pPriv->clip);
+ return 0;
+}
+
+/*----------------------------------------------------------------------------
+ * LXResetVideo
+ *
+ * Description : This function resets the video
+ *
+ * Parameters.
+ * ScreenInfoPtr
+ * pScrni :Screen pointer having screen information.
+ *
+ * Returns :None
+ *
+ * Comments :none
+ *
+*----------------------------------------------------------------------------
+*/
+
+void
+LXResetVideo(ScrnInfoPtr pScrni)
+{
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ DBLOG(1,"LXResetVideo()\n");
+
+ if (!pGeode->NoAccel) {
+ GeodePortPrivPtr pPriv = pGeode->adaptor->pPortPrivates[0].ptr;
+
+ LXAccelSync(pScrni);
+ df_set_video_palette(NULL);
+ LXSetColorkey(pScrni, pPriv);
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * LXSetupImageVideo
+ *
+ * Description : This function allocates space for a Videoadaptor and initializes
+ * the XF86VideoAdaptorPtr record.
+ *
+ * Parameters.
+ * ScreenPtr
+ * pScrn :Screen handler pointer having screen information.
+ *
+ * Returns :XF86VideoAdaptorPtr :- pointer to the initialized video adaptor record.
+ *
+ * Comments :none
+ *
+*----------------------------------------------------------------------------
+*/
+
+static XF86VideoAdaptorPtr
+LXSetupImageVideo(ScreenPtr pScrn)
+{
+ ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum];
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ XF86VideoAdaptorPtr adapt;
+ GeodePortPrivPtr pPriv;
+ DBLOG(1,"LXSetupImageVideo()\n");
+
+ if (!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) +
+ sizeof(GeodePortPrivRec) + sizeof(DevUnion))))
+ return NULL;
+
+ adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+ adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ adapt->name = "Advanced Micro Devices";
+ adapt->nEncodings = 1;
+ adapt->pEncodings = DummyEncoding;
+ adapt->nFormats = NUM_FORMATS;
+ adapt->pFormats = Formats;
+ adapt->nPorts = 1;
+ adapt->pPortPrivates = (DevUnion *) (&adapt[1]);
+ pPriv = (GeodePortPrivPtr) (&adapt->pPortPrivates[1]);
+ adapt->pPortPrivates[0].ptr = (pointer) (pPriv);
+ adapt->pAttributes = Attributes;
+ adapt->nImages = NUM_IMAGES;
+ adapt->nAttributes = NUM_ATTRIBUTES;
+ adapt->pImages = Images;
+ adapt->PutVideo = NULL;
+ adapt->PutStill = NULL;
+ adapt->GetVideo = NULL;
+ adapt->GetStill = NULL;
+ adapt->StopVideo = LXStopVideo;
+ adapt->SetPortAttribute = LXSetPortAttribute;
+ adapt->GetPortAttribute = LXGetPortAttribute;
+ adapt->QueryBestSize = LXQueryBestSize;
+ adapt->PutImage = LXPutImage;
+ adapt->QueryImageAttributes = LXQueryImageAttributes;
+
+ pPriv->filter = 0;
+ pPriv->colorKey = pGeode->videoKey;
+ pPriv->colorKeyMode = 0;
+ pPriv->videoStatus = 0;
+#if DBUF
+ pPriv->doubleBuffer = TRUE;
+ pPriv->currentBuffer = 0; /* init to first buffer */
+#endif
+
+ /* gotta uninit this someplace */
+#if defined(REGION_NULL)
+ REGION_NULL(pScrn, &pPriv->clip);
+#else
+ REGION_INIT(pScrn, &pPriv->clip, NullBox, 0);
+#endif
+
+ pGeode->adaptor = adapt;
+
+ pGeode->BlockHandler = pScrn->BlockHandler;
+ pScrn->BlockHandler = LXBlockHandler;
+
+ xvColorKey = MAKE_ATOM("XV_COLORKEY");
+ xvColorKeyMode = MAKE_ATOM("XV_COLORKEYMODE");
+ xvFilter = MAKE_ATOM("XV_FILTER");
+#if DBUF
+ xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER");
+#endif
+
+ LXResetVideo(pScrni);
+
+ return adapt;
+}
+
+/*----------------------------------------------------------------------------
+ * LXStopVideo
+ *
+ * Description :This function is used to stop input and output video
+ *
+ * Parameters.
+ * pScrni :Screen handler pointer having screen information.
+ * data :Pointer to the video port's private data
+ * exit :Flag indicating whether the offscreen areas used for video
+ * to be deallocated or not.
+ * Returns :none
+ *
+ * Comments :none
+ *
+*----------------------------------------------------------------------------
+*/
+static void
+LXStopVideo(ScrnInfoPtr pScrni, pointer data, Bool exit)
+{
+ GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data;
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ DBLOG(1,"LXStopVideo()\n");
+
+ REGION_EMPTY(pScrni->pScreen, &pPriv->clip);
+
+ LXAccelSync(pScrni);
+ if (exit) {
+ if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
+ df_set_video_enable(0,0);
+ }
+ if (pPriv->area) {
+ xf86FreeOffscreenArea(pPriv->area);
+ pPriv->area = NULL;
+ }
+ pPriv->videoStatus = 0;
+ pGeode->OverlayON = FALSE;
+ } else {
+ if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
+ pPriv->videoStatus |= OFF_TIMER;
+ pPriv->offTime = currentTime.milliseconds + OFF_DELAY;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * LXSetPortAttribute
+ *
+ * Description :This function is used to set the attributes of a port like colorkeymode,
+ * double buffer support and filter.
+ *
+ * Parameters.
+ * pScrni :Screen handler pointer having screen information.
+ * data :Pointer to the video port's private data
+ * attribute :The port attribute to be set
+ * value :Value of the attribute to be set.
+ *
+ * Returns :Sucess if the attribute is supported, else BadMatch
+ *
+ * Comments :none
+ *
+*----------------------------------------------------------------------------
+*/
+static int
+LXSetPortAttribute(ScrnInfoPtr pScrni,
+ Atom attribute, INT32 value, pointer data)
+{
+ GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data;
+ DBLOG(1,"LXSetPortAttribute(%d,%#x)\n",attribute,value);
+
+ LXAccelSync(pScrni);
+ if (attribute == xvColorKey) {
+ pPriv->colorKey = value;
+ LXSetColorkey(pScrni, pPriv);
+ }
+#if DBUF
+ else if (attribute == xvDoubleBuffer) {
+ if ((value < 0) || (value > 1))
+ return BadValue;
+ pPriv->doubleBuffer = value;
+ }
+#endif
+ else if (attribute == xvColorKeyMode) {
+ pPriv->colorKeyMode = value;
+ LXSetColorkey(pScrni, pPriv);
+ }
+ else if (attribute == xvFilter) {
+ if ((value < 0) || (value > 1))
+ return BadValue;
+ pPriv->filter = value;
+ }
+ else
+ return BadMatch;
+
+ return Success;
+}
+
+/*----------------------------------------------------------------------------
+ * LXGetPortAttribute
+ *
+ * Description :This function is used to get the attributes of a port like hue,
+ * saturation,brightness or contrast.
+ *
+ * Parameters.
+ * pScrni :Screen handler pointer having screen information.
+ * data :Pointer to the video port's private data
+ * attribute :The port attribute to be read
+ * value :Pointer to the value of the attribute to be read.
+ *
+ * Returns :Sucess if the attribute is supported, else BadMatch
+ *
+ * Comments :none
+ *
+*----------------------------------------------------------------------------
+*/
+static int
+LXGetPortAttribute(ScrnInfoPtr pScrni,
+ Atom attribute, INT32 * value, pointer data)
+{
+ GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data;
+ DBLOG(1,"LXGetPortAttribute(%d)\n",attribute);
+
+ if (attribute == xvColorKey) {
+ *value = pPriv->colorKey;
+ }
+#if DBUF
+ else if (attribute == xvDoubleBuffer) {
+ *value = (pPriv->doubleBuffer) ? 1 : 0;
+ }
+#endif
+ else if (attribute == xvColorKeyMode) {
+ *value = pPriv->colorKeyMode;
+ }
+ else if (attribute == xvFilter) {
+ *value = pPriv->filter;
+ } else
+ return BadMatch;
+
+ return Success;
+}
+
+/*----------------------------------------------------------------------------
+ * LXQueryBestSize
+ *
+ * Description :This function provides a way to query what the destination dimensions
+ * would end up being if they were to request that an area vid_w by vid_h
+ * from the video stream be scaled to rectangle of drw_w by drw_h on
+ * the screen.
+ *
+ * Parameters.
+ * ScreenInfoPtr
+ * pScrni :Screen handler pointer having screen information.
+ * data :Pointer to the video port's private data
+ * vid_w,vid_h :Width and height of the video data.
+ * drw_w,drw_h :Width and height of the scaled rectangle.
+ * p_w,p_h :Width and height of the destination rectangle.
+ *
+ * Returns :None
+ *
+ * Comments :None
+ *
+*----------------------------------------------------------------------------
+*/
+static void
+LXQueryBestSize(ScrnInfoPtr pScrni,
+ Bool motion,
+ short vid_w, short vid_h,
+ short drw_w, short drw_h,
+ unsigned int *p_w, unsigned int *p_h, pointer data)
+{
+ *p_w = drw_w;
+ *p_h = drw_h;
+
+ if (*p_w > 16384)
+ *p_w = 16384;
+ DBLOG(1,"LXQueryBestSize(%d, src %dx%d scl %dx%d dst %dx%d)\n",motion,vid_w,vid_h,drw_w,drw_h,*p_w,*p_h);
+}
+
+static void
+LXCopyGreyscale(unsigned char *src, unsigned char *dst, int srcp, int dstp, int h, int w)
+{
+ int i;
+ unsigned char *src2 = src;
+ unsigned char *dst2 = dst;
+ unsigned char *dst3;
+ unsigned char *src3;
+
+ dstp <<= 1;
+
+ while (h--) {
+ dst3 = dst2;
+ src3 = src2;
+ for (i = 0; i < w; i++) {
+ *dst3++ = *src3++; /* Copy Y data */
+ *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */
+ }
+ src3 = src2;
+ for (i = 0; i < w; i++) {
+ *dst3++ = *src3++; /* Copy Y data */
+ *dst3++ = 0x80; /* Fill UV with 0x80 - greyscale */
+ }
+ dst2 += dstp;
+ src2 += srcp;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * LXCopyData420
+ *
+ * Description : Copies data from src to destination
+ *
+ * Parameters.
+ * src : pointer to the source data
+ * dst : pointer to destination data
+ * srcp : pitch of the srcdata
+ * dstp : pitch of the destination data
+ * h & w : height and width of source data
+ *
+ * Returns :None
+ *
+ * Comments :None
+ *
+*----------------------------------------------------------------------------
+*/
+
+static void
+LXCopyData420(unsigned char *src, unsigned char *dst, int srcp, int dstp, int h, int w)
+{
+ while (h--) {
+ memcpy(dst, src, w);
+ src += srcp; dst += dstp;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * LXCopyData422
+ *
+ * Description : Copies data from src to destination
+ *
+ * Parameters.
+ * src : pointer to the source data
+ * dst : pointer to destination data
+ * srcp : pitch of the srcdata
+ * dstp : pitch of the destination data
+ * h & w : height and width of source data
+ *
+ * Returns :None
+ *
+ * Comments :None
+ *
+*----------------------------------------------------------------------------
+*/
+
+static void
+LXCopyData422(unsigned char *src, unsigned char *dst,
+ int srcp, int dstp, int h, int w)
+{
+ w <<= 1;
+ while (h--) {
+ memcpy(dst, src, w);
+ src += srcp; dst += dstp;
+ }
+}
+
+static FBAreaPtr
+LXAllocateMemory(ScrnInfoPtr pScrni, FBAreaPtr area, int numlines)
+{
+ ScreenPtr pScrn = screenInfo.screens[pScrni->scrnIndex];
+ FBAreaPtr new_area;
+
+ if (area) {
+ if ((area->box.y2 - area->box.y1) >= numlines)
+ return area;
+
+ if (xf86ResizeOffscreenArea(area, pScrni->displayWidth, numlines))
+ return area;
+
+ xf86FreeOffscreenArea(area);
+ }
+
+ new_area = xf86AllocateOffscreenArea(pScrn, pScrni->displayWidth,
+ numlines, 0, NULL, NULL, NULL);
+
+ if (!new_area) {
+ int max_w, max_h;
+
+ xf86QueryLargestOffscreenArea(pScrn, &max_w, &max_h, 0,
+ FAVOR_WIDTH_THEN_AREA, PRIORITY_EXTREME);
+
+ if ((max_w < pScrni->displayWidth) || (max_h < numlines))
+ return NULL;
+
+ xf86PurgeUnlockedOffscreenAreas(pScrn);
+ new_area = xf86AllocateOffscreenArea(pScrn, pScrni->displayWidth,
+ numlines, 0, NULL, NULL, NULL);
+ }
+
+ return new_area;
+}
+
+static BoxRec dstBox;
+static int srcPitch = 0, srcPitch2 = 0, dstPitch = 0, dstPitch2 = 0;
+static INT32 Bx1, Bx2, By1, By2;
+static int top, left, npixels, nlines;
+static int offset, s1offset = 0, s2offset = 0, s3offset = 0;
+static unsigned char *dst_start;
+static int d2offset = 0, d3offset = 0;
+
+static DF_VIDEO_SOURCE_PARAMS vSrcParams;
+
+void
+LXSetVideoPosition(int x, int y, int width, int height,
+ short src_w, short src_h, short drw_w, short drw_h,
+ int id, int offset, ScrnInfoPtr pScrni)
+{
+ long ystart, xend, yend;
+ unsigned long lines = 0;
+ unsigned long y_extra, uv_extra = 0;
+ DF_VIDEO_POSITION vidPos;
+
+ DBLOG(1,"LXSetVideoPosition(%d,%d %dx%d, src %dx%d, dst %dx%d, id %d, ofs %d)\n",
+ x,y,width,height,src_w,src_h,drw_w,drw_h,id,offset);
+
+ xend = x + drw_w;
+ yend = y + drw_h;
+
+ /* TOP CLIPPING */
+
+ if (y < 0) {
+ if (src_h < drw_h)
+ lines = (-y) * src_h / drw_h;
+ else
+ lines = (-y);
+ ystart = 0;
+ drw_h += y;
+ y_extra = lines * dstPitch;
+ uv_extra = (lines >> 1) * (dstPitch2);
+ } else {
+ ystart = y;
+ lines = 0;
+ y_extra = 0;
+ }
+
+ memset(&vidPos,0,sizeof(vidPos));
+ vidPos.x= x;
+ vidPos.y = ystart;
+ vidPos.width = xend - x;
+ vidPos.height = yend - ystart;
+
+ DBLOG(1,"video_pos %d,%d %dx%d\n",vidPos.x,vidPos.y,vidPos.width,vidPos.height);
+ df_set_video_position(&vidPos);
+
+ vSrcParams.y_offset = offset + y_extra;
+ if ((id == FOURCC_Y800) || (id == FOURCC_I420) || (id == FOURCC_YV12)) {
+ vSrcParams.u_offset = offset + d3offset + uv_extra;
+ vSrcParams.v_offset = offset + d2offset + uv_extra;
+ }
+ else {
+ vSrcParams.u_offset = vSrcParams.v_offset = 0;
+ }
+ vSrcParams.flags = DF_SOURCEFLAG_IMPLICITSCALING;
+
+ DBLOG(1,"video_format %#x yofs %#x uofs %#x vofs %#x yp %d uvp %d wh %dx%d flg %#x\n",
+ vSrcParams.video_format, vSrcParams.y_offset, vSrcParams.u_offset,
+ vSrcParams.v_offset, vSrcParams.y_pitch, vSrcParams.uv_pitch,
+ vSrcParams.width, vSrcParams.height, vSrcParams.flags);
+
+ df_configure_video_source(&vSrcParams, &vSrcParams);
+}
+
+/*----------------------------------------------------------------------------
+ * LXDisplayVideo
+ *
+ * Description : This function sets up the video registers for playing video
+ * It sets up the video format,width, height & position of the
+ * video window ,video offsets( y,u,v) and video pitches(y,u,v)
+ * Parameters.
+ *
+ * Returns :None
+ *
+ * Comments :None
+ *
+*----------------------------------------------------------------------------
+*/
+
+static void
+LXDisplayVideo(ScrnInfoPtr pScrni,
+ int id,
+ int offset,
+ short width, short height,
+ int pitch,
+ int x1, int y1, int x2, int y2,
+ BoxPtr dstBox,
+ short src_w, short src_h, short drw_w, short drw_h)
+{
+ DBLOG(1,"LXDisplayVideo(id %d, ofs %d, %dx%d, p %d, %d,%d, %d,%d, src %dx%d dst %dx%d)\n",
+ id,offset,width,height,pitch,x1,y1,x2,y2,src_w,src_h,drw_w,drw_h);
+
+ LXAccelSync(pScrni);
+
+ switch (id) {
+ case FOURCC_UYVY: vSrcParams.video_format = DF_VIDFMT_UYVY; break;
+ case FOURCC_Y800:
+ case FOURCC_YV12:
+ case FOURCC_I420: vSrcParams.video_format = DF_VIDFMT_Y0Y1Y2Y3; break;
+ case FOURCC_YUY2: vSrcParams.video_format = DF_VIDFMT_YUYV; break;
+ case FOURCC_Y2YU: vSrcParams.video_format = DF_VIDFMT_Y2YU; break;
+ case FOURCC_YVYU: vSrcParams.video_format = DF_VIDFMT_YVYU; break;
+ }
+
+ vSrcParams.width = width;
+ vSrcParams.height = height;
+ vSrcParams.y_pitch = dstPitch;
+ vSrcParams.uv_pitch = dstPitch2;
+
+ df_set_video_filter_coefficients(NULL,1);
+ if ((drw_w >= src_w) && (drw_h >= src_h))
+ df_set_video_scale(width, height, drw_w, drw_h,
+ DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY);
+ else if (drw_w < src_w)
+ df_set_video_scale(drw_w, height, drw_w, drw_h,
+ DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY);
+ else if (drw_h < src_h)
+ df_set_video_scale(width, drw_h, drw_w, drw_h,
+ DF_SCALEFLAG_CHANGEX | DF_SCALEFLAG_CHANGEY);
+
+ LXSetVideoPosition(dstBox->x1, dstBox->y1, width, height, src_w,
+ src_h, drw_w, drw_h, id, offset, pScrni);
+
+ df_set_video_enable(1,0);
+}
+
+#if REINIT
+static Bool
+RegionsEqual(RegionPtr A, RegionPtr B)
+{
+ int *dataA, *dataB;
+ int num;
+
+ num = REGION_NUM_RECTS(A);
+ if (num != REGION_NUM_RECTS(B)) {
+ return FALSE;
+ }
+
+ if ((A->extents.x1 != B->extents.x1) ||
+ (A->extents.x2 != B->extents.x2) ||
+ (A->extents.y1 != B->extents.y1) || (A->extents.y2 != B->extents.y2))
+ return FALSE;
+
+ dataA = (int *)REGION_RECTS(A);
+ dataB = (int *)REGION_RECTS(B);
+
+ while (num--) {
+ if ((dataA[0] != dataB[0]) || (dataA[1] != dataB[1]))
+ return FALSE;
+ dataA += 2;
+ dataB += 2;
+ }
+
+ return TRUE;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * LXPutImage : This function writes a single frame of video into a drawable.
+ * The position and size of the source rectangle is specified by src_x,src_y,
+ * src_w and src_h. This data is stored in a system memory buffer at buf.
+ * The position and size of the destination rectangle is specified by drw_x,
+ * drw_y,drw_w,drw_h.The data is in the format indicated by the image descriptor
+ * and represents a source of size width by height. If sync is TRUE the driver
+ * should not return from this function until it is through reading the data from
+ * buf. Returning when sync is TRUE indicates that it is safe for the data at buf
+ * to be replaced,freed, or modified.
+ *
+ *
+ * Description :
+ * Parameters.
+ *
+ * Returns :None
+ *
+ * Comments :None
+ *
+*----------------------------------------------------------------------------
+*/
+
+static int
+LXPutImage(ScrnInfoPtr pScrni,
+ short src_x, short src_y,
+ short drw_x, short drw_y,
+ short src_w, short src_h,
+ short drw_w, short drw_h,
+ int id, unsigned char *buf,
+ short width, short height,
+ Bool sync, RegionPtr clipBoxes, pointer data)
+{
+ GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data;
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ int new_h;
+
+#if REINIT
+ BOOL ReInitVideo = FALSE;
+ static BOOL DoReinitAgain = 0;
+#endif
+
+#if XV_PROFILE
+ long oldtime, newtime;
+
+ UpdateCurrentTime();
+ oldtime = currentTime.milliseconds;
+#endif
+ DBLOG(1,"LXPutImage(src %d,%d %dx%d dst %d,%d %dx%d, id %d %dx%d sync %d)\n",
+ src_x,src_y,src_w,src_h,drw_x,drw_y,drw_w,drw_h,id,width,height,sync);
+
+#if REINIT
+/* update cliplist */
+ if (!RegionsEqual(&pPriv->clip, clipBoxes)) {
+ ReInitVideo = TRUE;
+ }
+ if (DoReinitAgain)
+ ReInitVideo = TRUE;
+
+ if (ReInitVideo) {
+ DBLOG(1, "Regional Not Equal - Init\n");
+#endif
+ DoReinitAgain = ~DoReinitAgain;
+ if (drw_w > 16384)
+ drw_w = 16384;
+
+ /* Clip */
+ Bx1 = src_x;
+ Bx2 = src_x + src_w;
+ By1 = src_y;
+ By2 = src_y + src_h;
+
+ if ((Bx1 >= Bx2) || (By1 >= By2))
+ return Success;
+
+ dstBox.x1 = drw_x;
+ dstBox.x2 = drw_x + drw_w;
+ dstBox.y1 = drw_y;
+ dstBox.y2 = drw_y + drw_h;
+
+ dstBox.x1 -= pScrni->frameX0;
+ dstBox.x2 -= pScrni->frameX0;
+ dstBox.y1 -= pScrni->frameY0;
+ dstBox.y2 -= pScrni->frameY0;
+
+ switch (id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+
+ srcPitch = (width + 3) & ~3; /* of luma */
+ dstPitch = (width + 31) & ~31;
+
+ s2offset = srcPitch * height;
+ d2offset = dstPitch * height;
+
+ srcPitch2 = ((width >> 1) + 3) & ~3;
+ dstPitch2 = ((width >> 1) + 15) & ~15;
+
+ s3offset = (srcPitch2 * (height >> 1)) + s2offset;
+ d3offset = (dstPitch2 * (height >> 1)) + d2offset;
+
+ new_h = dstPitch * height; /* Y */
+ new_h += (dstPitch2 * height); /* U+V */
+ new_h += pGeode->Pitch - 1;
+ new_h /= pGeode->Pitch;
+ break;
+
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ case FOURCC_Y800:
+ default:
+ dstPitch = ((width << 1) + 3) & ~3;
+ srcPitch = (width << 1);
+ new_h = ((dstPitch * height) + pGeode->Pitch - 1) / pGeode->Pitch;
+ break;
+ }
+
+#if DBUF
+ if (pPriv->doubleBuffer)
+ new_h <<= 1;
+#endif
+
+ if (!(pPriv->area = LXAllocateMemory(pScrni, pPriv->area, new_h)))
+ return BadAlloc;
+
+ /* copy data */
+ top = By1;
+ left = Bx1 & ~1;
+ npixels = ((Bx2 + 1) & ~1) - left;
+
+ switch (id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ {
+ int tmp;
+
+ top &= ~1;
+ offset = (pPriv->area->box.y1 * pGeode->Pitch) + (top * dstPitch);
+
+#if DBUF
+ if (pPriv->doubleBuffer && pPriv->currentBuffer)
+ offset += (new_h >> 1) * pGeode->Pitch;
+#endif
+
+ dst_start = pGeode->FBBase + offset + left;
+ tmp = ((top >> 1) * srcPitch2) + (left >> 1);
+ s2offset += tmp;
+ s3offset += tmp;
+ if (id == FOURCC_I420) {
+ tmp = s2offset;
+ s2offset = s3offset;
+ s3offset = tmp;
+ }
+ nlines = ((By2 + 1) & ~1) - top;
+ }
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ case FOURCC_Y800:
+ default:
+ left <<= 1;
+ buf += (top * srcPitch) + left;
+ nlines = By2 - top;
+ offset = (pPriv->area->box.y1 * pGeode->Pitch) + (top * dstPitch);
+#if DBUF
+ if (pPriv->doubleBuffer && pPriv->currentBuffer)
+ offset += (new_h >> 1) * pGeode->Pitch;
+#endif
+
+ dst_start = pGeode->FBBase + offset + left;
+ break;
+ }
+ s1offset = (top * srcPitch) + left;
+
+#if REINIT
+ /* update cliplist */
+ REGION_COPY(pScrni->pScreen, &pPriv->clip, clipBoxes);
+ if (pPriv->colorKeyMode == 0) {
+ /* draw these */
+ xf86XVFillKeyHelper(pScrni, pPriv->colorKey, clipBoxes);
+ }
+ LXDisplayVideo(pScrni, id, offset, width, height, dstPitch,
+ Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w,
+ drw_h);
+ }
+#endif
+
+ switch (id) {
+
+ case FOURCC_Y800:
+ LXCopyGreyscale(buf, dst_start, srcPitch, dstPitch, nlines, npixels);
+ break;
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ LXCopyData420(buf + s1offset, dst_start, srcPitch, dstPitch, nlines,
+ npixels);
+ LXCopyData420(buf + s2offset, dst_start + d2offset, srcPitch2,
+ dstPitch2, nlines >> 1, npixels >> 1);
+ LXCopyData420(buf + s3offset, dst_start + d3offset, srcPitch2,
+ dstPitch2, nlines >> 1, npixels >> 1);
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ LXCopyData422(buf, dst_start, srcPitch, dstPitch, nlines, npixels);
+ break;
+ }
+#if !REINIT
+ /* update cliplist */
+ REGION_COPY(pScrni->pScreen, &pPriv->clip, clipBoxes);
+ if (pPriv->colorKeyMode == 0) {
+ /* draw these */
+ XAAFillSolidRects(pScrni, pPriv->colorKey, GXcopy, ~0,
+ REGION_NUM_RECTS(clipBoxes), REGION_RECTS(clipBoxes));
+ }
+ LXDisplayVideo(pScrni, id, offset, width, height, dstPitch,
+ Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, drw_h);
+#endif
+
+#if XV_PROFILE
+ UpdateCurrentTime();
+ newtime = currentTime.milliseconds;
+ DBLOG(1, "PI %d\n", newtime - oldtime);
+#endif
+
+#if DBUF
+ pPriv->currentBuffer ^= 1;
+#endif
+
+ pPriv->videoStatus = CLIENT_VIDEO_ON;
+ pGeode->OverlayON = TRUE;
+ return Success;
+}
+
+/*----------------------------------------------------------------------------
+ * LXQueryImageAttributes
+ *
+ * Description :This function is called to let the driver specify how data
+ * for a particular image of size width by height should be
+ * stored.
+ *
+ * Parameters.
+ * pScrni :Screen handler pointer having screen information.
+ * id :Id for the video format
+ * width :width of the image (can be modified by the driver)
+ * height :height of the image (can be modified by the driver)
+ * Returns : Size of the memory required for storing this image
+ *
+ * Comments :None
+ *
+*----------------------------------------------------------------------------
+*/
+static int
+LXQueryImageAttributes(ScrnInfoPtr pScrni,
+ int id,
+ unsigned short *w, unsigned short *h,
+ int *pitches, int *offsets)
+{
+ int size;
+ int tmp;
+
+ if (*w > 1024)
+ *w = 1024;
+ if (*h > 1024)
+ *h = 1024;
+
+ *w = (*w + 1) & ~1;
+ if (offsets)
+ offsets[0] = 0;
+
+ switch (id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ *h = (*h + 1) & ~1;
+ size = (*w + 3) & ~3;
+ if (pitches)
+ pitches[0] = size;
+ size *= *h;
+ if (offsets)
+ offsets[1] = size;
+ tmp = ((*w >> 1) + 3) & ~3;
+ if (pitches)
+ pitches[1] = pitches[2] = tmp;
+ tmp *= (*h >> 1);
+ size += tmp;
+ if (offsets)
+ offsets[2] = size;
+ size += tmp;
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ case FOURCC_Y800:
+ default:
+ size = *w << 1;
+ if (pitches)
+ pitches[0] = size;
+ size *= *h;
+ break;
+ }
+ DBLOG(1,"LXQueryImageAttributes(%d)= %d, %dx%d %d/%d/%d %d/%d/%d\n",
+ id,size,*w,*h,pitches[0],pitches[1],pitches[2],offsets[0],offsets[1],offsets[2]);
+ return size;
+}
+
+static void
+LXBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask)
+{
+ ScreenPtr pScrn = screenInfo.screens[i];
+ ScrnInfoPtr pScrni = xf86Screens[i];
+ GeodePtr pGeode = GEODEPTR(pScrni);
+ GeodePortPrivPtr pPriv = GET_PORT_PRIVATE(pScrni);
+
+ pScrn->BlockHandler = pGeode->BlockHandler;
+ (*pScrn->BlockHandler) (i, blockData, pTimeout, pReadmask);
+ pScrn->BlockHandler = LXBlockHandler;
+
+ if (pPriv->videoStatus & TIMER_MASK) {
+ DBLOG(1,"LXBlockHandler(%d)\n",i);
+ LXAccelSync(pScrni);
+ UpdateCurrentTime();
+ if (pPriv->videoStatus & OFF_TIMER) {
+ if (pPriv->offTime < currentTime.milliseconds) {
+ df_set_video_enable(0,0);
+ pPriv->videoStatus = FREE_TIMER;
+ pPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
+ }
+ } else { /* FREE_TIMER */
+ if (pPriv->freeTime < currentTime.milliseconds) {
+ if (pPriv->area) {
+ xf86FreeOffscreenArea(pPriv->area);
+ pPriv->area = NULL;
+ }
+ pPriv->videoStatus = 0;
+ }
+ }
+ }
+}
+
+/****************** Offscreen stuff ***************/
+
+typedef struct
+{
+ FBAreaPtr area;
+ FBLinearPtr linear;
+ Bool isOn;
+}
+OffscreenPrivRec, *OffscreenPrivPtr;
+
+/*----------------------------------------------------------------------------
+ * LXAllocateSurface
+ *
+ * Description :This function allocates an area of w by h in the offscreen
+ * Parameters.
+ * pScrni :Screen handler pointer having screen information.
+ *
+ * Returns :None
+ *
+ * Comments :None
+ *
+*----------------------------------------------------------------------------
+*/
+
+static int
+LXAllocateSurface(ScrnInfoPtr pScrni,
+ int id,
+ unsigned short w, unsigned short h, XF86SurfacePtr surface)
+{
+ FBAreaPtr area;
+ int pitch, fbpitch, numlines;
+ OffscreenPrivPtr pPriv;
+ DBLOG(1,"LXAllocateSurface(id %d, %dx%d)\n",id,w,h);
+
+ if ((w > 1024) || (h > 1024))
+ return BadAlloc;
+
+ w = (w + 1) & ~1;
+ pitch = ((w << 1) + 15) & ~15;
+ fbpitch = pScrni->bitsPerPixel * pScrni->displayWidth >> 3;
+ numlines = ((pitch * h) + fbpitch - 1) / fbpitch;
+
+ if (!(area = LXAllocateMemory(pScrni, NULL, numlines)))
+ return BadAlloc;
+
+ surface->width = w;
+ surface->height = h;
+
+ if (!(surface->pitches = xalloc(sizeof(int))))
+ return BadAlloc;
+ if (!(surface->offsets = xalloc(sizeof(int)))) {
+ xfree(surface->pitches);
+ return BadAlloc;
+ }
+ if (!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) {
+ xfree(surface->pitches);
+ xfree(surface->offsets);
+ return BadAlloc;
+ }
+
+ pPriv->area = area;
+ pPriv->isOn = FALSE;
+
+ surface->pScrn = pScrni;
+ surface->id = id;
+ surface->pitches[0] = pitch;
+ surface->offsets[0] = area->box.y1 * fbpitch;
+ surface->devPrivate.ptr = (pointer) pPriv;
+
+ return Success;
+}
+
+static int
+LXStopSurface(XF86SurfacePtr surface)
+{
+ OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr;
+ DBLOG(1,"LXStopSurface()\n");
+
+ if (pPriv->isOn) {
+ pPriv->isOn = FALSE;
+ }
+
+ return Success;
+}
+
+static int
+LXFreeSurface(XF86SurfacePtr surface)
+{
+ OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr;
+ DBLOG(1,"LXFreeSurface()\n");
+
+ if (pPriv->isOn)
+ LXStopSurface(surface);
+ xf86FreeOffscreenArea(pPriv->area);
+ xfree(surface->pitches);
+ xfree(surface->offsets);
+ xfree(surface->devPrivate.ptr);
+
+ return Success;
+}
+
+static int
+LXGetSurfaceAttribute(ScrnInfoPtr pScrni, Atom attribute, INT32 * value)
+{
+ return LXGetPortAttribute(pScrni, attribute, value,
+ (pointer) (GET_PORT_PRIVATE(pScrni)));
+}
+
+static int
+LXSetSurfaceAttribute(ScrnInfoPtr pScrni, Atom attribute, INT32 value)
+{
+ return LXSetPortAttribute(pScrni, attribute, value,
+ (pointer) (GET_PORT_PRIVATE(pScrni)));
+}
+
+static int
+LXDisplaySurface(XF86SurfacePtr surface,
+ short src_x, short src_y,
+ short drw_x, short drw_y,
+ short src_w, short src_h,
+ short drw_w, short drw_h, RegionPtr clipBoxes)
+{
+ OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr;
+ ScrnInfoPtr pScrni = surface->pScrn;
+ GeodePortPrivPtr portPriv = GET_PORT_PRIVATE(pScrni);
+ INT32 x1, y1, x2, y2;
+ BoxRec dstBox;
+ DBLOG(1,"LXDisplaySurface(src %d,%d %dx%d, dst %d,%d %dx%d)\n",
+ src_x,src_y,src_w,src_h,drw_x,drw_y,drw_w,drw_h);
+
+ DEBUGMSG(0, (0, X_NONE, "DisplaySuface\n"));
+ x1 = src_x;
+ x2 = src_x + src_w;
+ y1 = src_y;
+ y2 = src_y + src_h;
+
+ dstBox.x1 = drw_x;
+ dstBox.x2 = drw_x + drw_w;
+ dstBox.y1 = drw_y;
+ dstBox.y2 = drw_y + drw_h;
+
+ if ((x1 >= x2) || (y1 >= y2))
+ return Success;
+
+ dstBox.x1 -= pScrni->frameX0;
+ dstBox.x2 -= pScrni->frameX0;
+ dstBox.y1 -= pScrni->frameY0;
+ dstBox.y2 -= pScrni->frameY0;
+
+ xf86XVFillKeyHelper(pScrni->pScreen, portPriv->colorKey, clipBoxes);
+
+ LXDisplayVideo(pScrni, surface->id, surface->offsets[0],
+ surface->width, surface->height, surface->pitches[0],
+ x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
+
+ pPriv->isOn = TRUE;
+ if (portPriv->videoStatus & CLIENT_VIDEO_ON) {
+ REGION_EMPTY(pScrni->pScreen, &portPriv->clip);
+ UpdateCurrentTime();
+ portPriv->videoStatus = FREE_TIMER;
+ portPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
+ }
+
+ return Success;
+}
+
+/*----------------------------------------------------------------------------
+ * LXInitOffscreenImages
+ *
+ * Description :This function sets up the offscreen memory management.It fills
+ * in the XF86OffscreenImagePtr structure with functions to handle
+ * offscreen memory operations.
+ *
+ * Parameters.
+ * pScrn :Screen handler pointer having screen information.
+ *
+ * Returns : None
+ *
+ * Comments :None
+ *
+*----------------------------------------------------------------------------
+*/
+static void
+LXInitOffscreenImages(ScreenPtr pScrn)
+{
+ XF86OffscreenImagePtr offscreenImages;
+ DBLOG(1,"LXInitOffscreenImages()\n");
+
+ /* need to free this someplace */
+ if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec))))
+ return;
+
+ offscreenImages[0].image = &Images[0];
+ offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ offscreenImages[0].alloc_surface = LXAllocateSurface;
+ offscreenImages[0].free_surface = LXFreeSurface;
+ offscreenImages[0].display = LXDisplaySurface;
+ offscreenImages[0].stop = LXStopSurface;
+ offscreenImages[0].setAttribute = LXSetSurfaceAttribute;
+ offscreenImages[0].getAttribute = LXGetSurfaceAttribute;
+ offscreenImages[0].max_width = 1024;
+ offscreenImages[0].max_height = 1024;
+ offscreenImages[0].num_attributes = NUM_ATTRIBUTES;
+ offscreenImages[0].attributes = Attributes;
+
+ xf86XVRegisterOffscreenImages(pScrn, offscreenImages, 1);
+}
+
+#endif /* !AMD_V4L2_VIDEO */
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_defs.h xf86-video-nsc-2.8.1/src/cim/cim_defs.h
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_defs.h 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_defs.h 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,732 @@
+ /*
+ *
+ * Copyright (C) 2005 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *
+ *
+ *
+ *
+ *
+ * Cimarron hardware access macros.
+ *
+ *
+ */
+
+#ifndef _cim_defs_h
+#define _cim_defs_h
+
+/*-----------------------------------------*/
+/* MEMORY ACCESS MACROS */
+/*-----------------------------------------*/
+
+#ifndef CIMARRON_EXCLUDE_REGISTER_ACCESS_MACROS
+
+#define READ_GP32(offset) \
+ (*(volatile unsigned long *)(cim_gp_ptr + (offset)))
+
+#define READ_REG32(offset) \
+ (*(volatile unsigned long *)(cim_vg_ptr + (offset)))
+
+#define READ_FB32(offset) \
+ (*(volatile unsigned long *)(cim_fb_ptr + (offset)))
+
+#define WRITE_GP32(offset, value) \
+ (*(volatile unsigned long *)(cim_gp_ptr + (offset))) = (value)
+
+#define WRITE_REG32(offset, value) \
+ (*(volatile unsigned long *)(cim_vg_ptr + (offset))) = (value)
+
+#define WRITE_COMMAND32(offset, value) \
+ (*(unsigned long *)(cim_cmd_ptr + (offset))) = (value)
+
+#define WRITE_COMMAND8(offset, value) \
+ (*(unsigned char *)(cim_cmd_ptr + (offset))) = (value)
+
+#define WRITE_FB32(offset, value) \
+ (*(unsigned long *)(cim_fb_ptr + (offset))) = (value)
+
+#define READ_VID32(offset) \
+ (*(volatile unsigned long *)(cim_vid_ptr + (offset)))
+
+#define WRITE_VID32(offset, value) \
+ (*(volatile unsigned long *)(cim_vid_ptr + (offset))) = (value)
+
+#define READ_VIP32(offset) \
+ (*(volatile unsigned long *)(cim_vip_ptr + (offset)))
+
+#define WRITE_VIP32(offset, value) \
+ (*(volatile unsigned long *)(cim_vip_ptr + (offset))) = (value)
+
+#define READ_VOP32(offset) \
+ (*(volatile unsigned long *)(cim_vid_ptr + (offset)))
+
+#define WRITE_VOP32(offset, value) \
+ (*(volatile unsigned long *)(cim_vid_ptr + (offset))) = (value)
+
+#endif
+
+/*-----------------------------------------*/
+/* GP POLLING MACROS */
+/*-----------------------------------------*/
+
+#define GP3_WAIT_WRAP(variable) \
+ while(((variable = READ_GP32 (GP3_CMD_READ)) > gp3_cmd_current) || \
+ (variable <= (gp3_cmd_top + GP3_BLT_COMMAND_SIZE + GP3_BLT_COMMAND_SIZE + 96)))
+
+#define GP3_WAIT_PRIMITIVE(variable) \
+ while (((variable = READ_GP32 (GP3_CMD_READ)) > gp3_cmd_current) && \
+ (variable <= (gp3_cmd_next + 96)))
+
+#define GP3_WAIT_BUSY \
+ while(READ_GP32 (GP3_BLT_STATUS) & GP3_BS_BLT_BUSY)
+
+#define GP3_WAIT_PENDING \
+ while(READ_GP32 (GP3_BLT_STATUS) & GP3_BS_BLT_PENDING)
+
+/*-----------------------------------------------------------------*/
+/* MSR MACROS */
+/* These macros facilitate interaction with the model specific */
+/* registers in GeodeLX. There are two included methods, direct */
+/* access using the rdmsr and wrmsr opcodes and an indirect method */
+/* using VSAII. */
+/*-----------------------------------------------------------------*/
+
+#ifdef CIMARRON_INCLUDE_MSR_MACROS
+
+#if CIMARRON_MSR_DIRECT_ASM
+
+/*-----------------------------------------------------------------
+ * MSR_READ
+ * Read the contents of a 64 bit MSR into a data structure
+ *-----------------------------------------------------------------*/
+
+#define MSR_READ(msr_reg, device_add, data64_ptr) \
+{ \
+ unsigned long msr_add = (unsigned long)(msr_reg) | (unsigned long)(device_add); \
+ unsigned long data_high, data_low; \
+ _asm { mov ecx, msr_add } \
+ _asm { rdmsr } \
+ _asm { mov data_high, edx } \
+ _asm { mov data_low, eax } \
+ \
+ ((Q_WORD *)(data64_ptr))->high = data_high; \
+ ((Q_WORD *)(data64_ptr))->low = data_low; \
+}
+
+/*-----------------------------------------------------------------
+ * MSR_WRITE
+ * Write the contents of a 64 bit data structure to a MSR.
+ *-----------------------------------------------------------------*/
+
+#define MSR_WRITE(msr_reg, device_add, data64_ptr) \
+{ \
+ unsigned long msr_add = (unsigned long)(msr_reg) | (unsigned long)(device_add); \
+ unsigned long data_high, data_low; \
+ \
+ data_high = ((Q_WORD *)(data64_ptr))->high; \
+ data_low = ((Q_WORD *)(data64_ptr))->low; \
+ \
+ _asm { mov ecx, msr_add } \
+ _asm { mov edx, data_high } \
+ _asm { mov eax, data_low } \
+ _asm { wrmsr } \
+}
+
+#elif CIMARRON_MSR_VSA_IO
+
+/*-----------------------------------------------------------------
+ * MSR_READ
+ * Read the contents of a 64 bit MSR into a data structure
+ *-----------------------------------------------------------------*/
+
+#define MSR_READ(msr_reg, device_add, data64_ptr) \
+{ \
+ unsigned long msr_add = (unsigned long)(msr_reg) | (unsigned long)(device_add); \
+ unsigned long data_high, data_low; \
+ \
+ _asm { mov dx, 0x0AC1C } \
+ _asm { mov eax, 0x0FC530007 } \
+ _asm { out dx, eax } \
+ \
+ _asm { add dl, 2 } \
+ _asm { mov ecx, msr_add } \
+ _asm { in ax, dx } \
+ _asm { mov data_high, edx } \
+ _asm { mov data_low, eax } \
+ \
+ ((Q_WORD *)(data64_ptr))->high = data_high; \
+ ((Q_WORD *)(data64_ptr))->low = data_low; \
+}
+
+/*-----------------------------------------------------------------
+ * MSR_WRITE
+ * Write the contents of a 64 bit data structure to a MSR.
+ *-----------------------------------------------------------------*/
+
+#define MSR_WRITE(msr_reg, device_add, data64_ptr) \
+{ \
+ unsigned long msr_add = (unsigned long)(msr_reg) | (unsigned long)(device_add); \
+ unsigned long data_high, data_low; \
+ \
+ data_high = ((Q_WORD *)(data64_ptr))->high; \
+ data_low = ((Q_WORD *)(data64_ptr))->low; \
+ \
+ _asm { mov dx, 0x0AC1C } \
+ _asm { mov eax, 0x0FC530007 } \
+ _asm { out dx, eax } \
+ \
+ _asm { add dl, 2 } \
+ _asm { mov ecx, msr_add } \
+ _asm { mov ebx, data_high } \
+ _asm { mov eax, data_low } \
+ \
+ _asm { mov esi, 0 } \
+ _asm { mov edi, 0 } \
+ _asm { out dx, ax } \
+}
+
+#elif CIMARRON_MSR_ABSTRACTED_ASM
+
+/*-----------------------------------------------------------------
+ * MSR_READ
+ * Read the contents of a 64 bit MSR into a data structure
+ *-----------------------------------------------------------------*/
+
+#define MSR_READ(msr,adr,val) \
+ __asm__ __volatile__( \
+ " mov $0x0AC1C, %%edx\n" \
+ " mov $0xFC530007, %%eax\n" \
+ " out %%eax,%%dx\n" \
+ " add $2,%%dl\n" \
+ " in %%dx, %%ax" \
+ : "=a" ((val)->low), "=d" ((val)->high) \
+ : "c" (msr | adr))
+
+void gfx_msr_asm_read(unsigned short msrReg, unsigned long msrAddr,
+ unsigned long *ptrHigh, unsigned long *ptrLow);
+
+#define MSR_READ( MBD_MSR_CAP, address, val ) \
+ gfx_msr_asm_read( ((unsigned short)(MBD_MSR_CAP)), address, &((val)->high), &((val)->low) )
+
+
+/*-----------------------------------------------------------------
+ * MSR_WRITE
+ * Write the contents of a 64 bit data structure to a MSR.
+ *-----------------------------------------------------------------*/
+
+#define MSR_WRITE(msr,adr,val) \
+ { int d0, d1, d2, d3, d4; \
+ __asm__ __volatile__( \
+ " mov $d0, %%eax\n" \
+ " mov $d1, %%ebx\n" \
+ " mov $0x0AC1C, %%edx\n" \
+ " mov $0xFC530007, %%eax\n" \
+ " out %%eax,%%dx\n" \
+ " add $2,%%dl\n" \
+ " mov %5, %4\n" \
+ " mov 0(%6), %1\n" \
+ " mov 4(%6), %0\n" \
+ " xor %3, %3\n" \
+ " xor %2, %2\n" \
+ " out %%ax, %%dx\n" \
+ " pop %%ebx" \
+ : "=&D" (d2), "=&S" (d3), "=c" (d4) : "2" (msr | adr), "3" (val) ); \
+ }
+
+void gfx_msr_asm_write(unsigned short msrReg, unsigned long msrAddr,
+ unsigned long *ptrHigh, unsigned long *ptrLow);
+
+#define MSR_WRITE( MBD_MSR_CAP, address, val ) \
+ gfx_msr_asm_write( ((unsigned short)(MBD_MSR_CAP)), address, &((val)->high), &((val)->low) )
+
+#elif CIMARRON_MSR_KERNEL_ROUTINE
+
+#include "asm/msr.h"
+
+/*-----------------------------------------------------------------
+ * MSR_READ
+ * Read the contents of a 64 bit MSR into a data structure
+ *-----------------------------------------------------------------*/
+
+#define MSR_READ(msr_reg, device_add, data64_ptr) \
+{ \
+ unsigned long addr, val1, val2; \
+ \
+ addr = device_add | msr_reg; \
+ rdmsr (addr, val1, val2); \
+ \
+ ((Q_WORD *)(data64_ptr))->high = val2; \
+ ((Q_WORD *)(data64_ptr))->low = val1; \
+}
+
+/*-----------------------------------------------------------------
+ * MSR_WRITE
+ * Read the contents of a 64 bit data structure to a MSR.
+ *-----------------------------------------------------------------*/
+
+#define MSR_WRITE(msr_reg, device_add, data64_ptr) \
+{ \
+ unsigned long addr, val1, val2; \
+ \
+ val2 = ((Q_WORD *)(data64_ptr))->high; \
+ val1 = ((Q_WORD *)(data64_ptr))->low; \
+ \
+ addr = (device_add & 0xFFFF0000) | (unsigned long)msr_reg; \
+ wrmsr(addr, val1, val2); \
+}
+
+#endif
+
+#endif /* #ifdef CIMARRON_INCLUDE_MSR_MACROS */
+
+/*-----------------------------------------------------------------*/
+/* STRING MACROS */
+/* These macros are included to facilitate the optimization of */
+/* routines that write or copy large amounts of data. Two vesions */
+/* of these macros are included. One is intended for operating */
+/* systems that allow the use of inline assembly, while the other */
+/* is a pure C implementation for stricter operating systems. */
+/*-----------------------------------------------------------------*/
+
+#ifdef CIMARRON_INCLUDE_STRING_MACROS
+
+#if CIMARRON_OPTIMIZE_ASSEMBLY
+
+/*-----------------------------------------------------------------
+ * WRITE_COMMAND_STRING32
+ * Write a series of DWORDs to the current command buffer offset
+ *-----------------------------------------------------------------*/
+
+#define WRITE_COMMAND_STRING32(offset, dataptr, dataoffset, dword_count) \
+{ \
+ _asm { cld } \
+ _asm { mov edi, cim_cmd_ptr } \
+ _asm { add edi, offset } \
+ _asm { mov esi, dataptr } \
+ _asm { add esi, dataoffset } \
+ _asm { mov ecx, dword_count } \
+ _asm { rep movsd } \
+}
+
+/*-----------------------------------------------------------------
+ * WRITE_FB_STRING32
+ * Write a series of DWORDS to video memory.
+ *-----------------------------------------------------------------*/
+
+#define WRITE_FB_STRING32(offset, dataptr, dword_count) \
+{ \
+ unsigned long temp = (unsigned long)(dataptr); \
+ _asm { cld } \
+ _asm { mov edi, cim_fb_ptr } \
+ _asm { add edi, offset } \
+ _asm { mov esi, temp } \
+ _asm { mov ecx, dword_count } \
+ _asm { rep movsd } \
+}
+
+/*-----------------------------------------------------------------
+ * WRITE_FB_CONSTANT
+ * Write a constant DWORD to multiple video memory addresses
+ *-----------------------------------------------------------------*/
+
+#define WRITE_FB_CONSTANT(offset, value, dword_count) \
+{ \
+ unsigned long outptr = (unsigned long)cim_fb_ptr + offset; \
+ unsigned long dwords = dword_count; \
+ _asm { cld } \
+ _asm { mov edi, outptr } \
+ _asm { mov eax, value } \
+ _asm { mov ecx, dwords } \
+ _asm { rep stosd } \
+}
+
+/*-----------------------------------------------------------------
+ * WRITE_HOST_SOURCE_STRING32
+ * Write a series of DWORDs to the GP host source register
+ *-----------------------------------------------------------------*/
+
+#define WRITE_HOST_SOURCE_STRING32(dataptr, dataoffset, dword_count) \
+{ \
+ _asm { cld } \
+ _asm { mov edi, cim_gp_ptr } \
+ _asm { add edi, GP3_HST_SRC_RANGE } \
+ _asm { mov esi, dataptr } \
+ _asm { add esi, dataoffset } \
+ _asm { mov ecx, dword_count } \
+ _asm { rep movsd } \
+}
+
+#elif CIMARRON_OPTIMIZE_FORLOOP
+
+/*-----------------------------------------------------------------
+ * WRITE_COMMAND_STRING32
+ * Write a series of DWORDs to the current command buffer offset
+ *-----------------------------------------------------------------*/
+
+#define WRITE_COMMAND_STRING32(offset, dataptr, dataoffset, dword_count) \
+{ \
+ unsigned long i; \
+ unsigned long tempdata = (unsigned long)dataptr + (dataoffset); \
+ unsigned long byte_off = 0; \
+ for (i = 0; i < dword_count; i++, byte_off += 4) \
+ WRITE_COMMAND32 ((offset) + byte_off, *((unsigned long *)(tempdata + byte_off))); \
+}
+
+/*-----------------------------------------------------------------
+ * WRITE_FB_STRING32
+ * Write a series of DWORDS to video memory.
+ *-----------------------------------------------------------------*/
+
+#define WRITE_FB_STRING32(offset, dataptr, dword_count) \
+{ \
+ unsigned long i; \
+ unsigned long tempdata = (unsigned long)dataptr; \
+ unsigned long byte_off = 0; \
+ for (i = 0; i < dword_count; i++, byte_off += 4) \
+ WRITE_FB32 ((offset) + byte_off, *((unsigned long *)(tempdata + byte_off))); \
+}
+
+/*-----------------------------------------------------------------
+ * WRITE_FB_CONSTANT
+ * Write a constant DWORD to multiple video memory addresses
+ *-----------------------------------------------------------------*/
+
+#define WRITE_FB_CONSTANT(offset, value, dword_count) \
+{ \
+ unsigned long i; \
+ unsigned long tempoffset = offset; \
+ for (i = 0; i < dword_count; i++, tempoffset += 4) \
+ WRITE_FB32 (tempoffset, value); \
+}
+
+/*-----------------------------------------------------------------
+ * WRITE_HOST_SOURCE_STRING32
+ * Write a series of DWORDs to the GP host source register
+ *-----------------------------------------------------------------*/
+
+#define WRITE_HOST_SOURCE_STRING32(dataptr, dataoffset, dword_count) \
+{ \
+ unsigned long i; \
+ unsigned long tempdata = (unsigned long)dataptr + (dataoffset); \
+ unsigned long byte_off = 0; \
+ for (i = 0; i < dword_count; i++, byte_off += 4) \
+ WRITE_GP32 (byte_off + GP3_HST_SRC_RANGE, *((unsigned long *)(tempdata + byte_off))); \
+}
+
+#elif CIMARRON_OPTIMIZE_ABSTRACTED_ASM
+
+#define move_dw(d,s,n) \
+ __asm__ __volatile__( \
+ " rep\n" \
+ " movsl\n" \
+ : "=&c" (d0), "=&S" (d1), "=&D" (d2) \
+ : "0" (n), "1" ((const char *)s), "2" ((char *)d) \
+ : "memory")
+
+/*-----------------------------------------------------------------
+ * WRITE_COMMAND_STRING32
+ * Write a series of DWORDs to the current command buffer offset
+ *-----------------------------------------------------------------*/
+
+#define WRITE_COMMAND_STRING32(offset, dataptr, dataoffset, dword_count) \
+{ \
+ int d0, d1, d2; \
+ move_dw (cim_cmd_ptr+ ((unsigned long)(offset)), \
+ ((unsigned long)(dataptr)+(dataoffset)), \
+ dword_count); \
+}
+
+/*-----------------------------------------------------------------
+ * WRITE_FB_STRING32
+ * Write a series of DWORDS to video memory.
+ *-----------------------------------------------------------------*/
+
+#define WRITE_FB_STRING32(offset, dataptr, dword_count) \
+{ \
+ unsigned long i; \
+ unsigned long tempdata = (unsigned long)dataptr; \
+ unsigned long byte_off = 0; \
+ for (i = 0; i < dword_count; i++, byte_off += 4) \
+ WRITE_FB32 ((offset) + byte_off, *((unsigned long *)(tempdata + byte_off))); \
+}
+
+/*-----------------------------------------------------------------
+ * WRITE_FB_CONSTANT
+ * Write a constant DWORD to multiple video memory addresses
+ *-----------------------------------------------------------------*/
+
+#define WRITE_FB_CONSTANT(offset, value, dword_count) \
+{ \
+ unsigned long i; \
+ unsigned long tempoffset = offset; \
+ for (i = 0; i < dword_count; i++, tempoffset += 4) \
+ WRITE_FB32 (tempoffset, value); \
+}
+
+/*-----------------------------------------------------------------
+ * WRITE_HOST_SOURCE_STRING32
+ * Write a series of DWORDs to the GP host source register
+ *-----------------------------------------------------------------*/
+
+#define WRITE_HOST_SOURCE_STRING32(dataptr, dataoffset, dword_count) \
+{ \
+ unsigned long i; \
+ unsigned long tempdata = (unsigned long)dataptr + (dataoffset); \
+ unsigned long byte_off = 0; \
+ for (i = 0; i < dword_count; i++, byte_off += 4) \
+ WRITE_GP32 (byte_off + GP3_HST_SRC_RANGE, *((unsigned long *)(tempdata + byte_off))); \
+}
+
+#endif
+
+#endif /* #ifdef CIMARRON_INCLUDE_STRING_MACROS */
+
+/*-----------------------------------------------------------------
+ * WRITE_COMMAND_STRING8
+ * Write a series of bytes to the current command buffer offset
+ *-----------------------------------------------------------------*/
+
+#define WRITE_COMMAND_STRING8(offset, dataptr, dataoffset, byte_count) \
+{ \
+ unsigned long i; \
+ unsigned long array = (unsigned long)dataptr + (dataoffset); \
+ for (i = 0; i < byte_count; i++) \
+ WRITE_COMMAND8 ((offset) + i, *((unsigned char *)(array + i))); \
+}
+
+/*-----------------------------------------------------------------
+ * WRITE_HOST_SOURCE_STRING8
+ * Write a series of bytes to the host source register
+ *-----------------------------------------------------------------*/
+
+#define WRITE_HOST_SOURCE_STRING8(dataptr, dataoffset, byte_count) \
+{ \
+ unsigned long temp1 = (unsigned long)dataptr + (dataoffset); \
+ unsigned long temp2 = 0; \
+ unsigned long shift = 0; \
+ unsigned long counter; \
+ if (byte_count) \
+ { \
+ for (counter = 0; counter < byte_count; counter++) \
+ { \
+ temp2 |= ((unsigned long)(*((unsigned char *)(temp1 + counter)))) << shift; \
+ shift += 8; \
+ } \
+ WRITE_GP32 (GP3_HST_SRC, temp2); \
+ } \
+}
+
+/*-----------------------------------------*/
+/* CUSTOM STRING MACROS */
+/*-----------------------------------------*/
+
+#ifndef CIMARRON_EXCLUDE_CUSTOM_MACROS
+
+#define WRITE_CUSTOM_COMMAND_STRING32 WRITE_COMMAND_STRING32
+#define WRITE_CUSTOM_COMMAND_STRING8 WRITE_COMMAND_STRING8
+
+#endif
+
+/*-----------------------------------------*/
+/* IO ACCESS MACROS */
+/*-----------------------------------------*/
+
+#ifdef CIMARRON_INCLUDE_IO_MACROS
+
+#if CIMARRON_IO_DIRECT_ACCESS
+
+/*-------------------------------------------
+ * OUTD
+ * Writes one DWORD to a single I/O address.
+ *-------------------------------------------*/
+
+#define OUTD(port, data) cim_outd(port, data)
+void cim_outd (unsigned short port, unsigned long data)
+{
+ _asm {
+ pushf
+ mov eax, data
+ mov dx, port
+ out dx, eax
+ popf
+ }
+}
+
+/*-------------------------------------------
+ * IND
+ * Reads one DWORD from a single I/O address.
+ *-------------------------------------------*/
+
+#define IND(port) cim_ind(port)
+unsigned long cim_ind (unsigned short port)
+{
+ unsigned long data;
+ _asm {
+ pushf
+ mov dx, port
+ in eax, dx
+ mov data, eax
+ popf
+ }
+ return data;
+}
+
+/*-------------------------------------------
+ * OUTW
+ * Writes one WORD to a single I/O address.
+ *-------------------------------------------*/
+
+#define OUTW(port, data) cim_outw(port, data)
+void cim_outw (unsigned short port, unsigned short data)
+{
+ _asm {
+ pushf
+ mov ax, data
+ mov dx, port
+ out dx, ax
+ popf
+ }
+}
+
+/*-------------------------------------------
+ * INW
+ * Reads one WORD from a single I/O address.
+ *-------------------------------------------*/
+
+#define INW(port) cim_inw(port)
+unsigned short cim_inw (unsigned short port)
+{
+ unsigned short data;
+ _asm {
+ pushf
+ mov dx, port
+ in ax, dx
+ mov data, ax
+ popf
+ }
+ return data;
+}
+
+/*-------------------------------------------
+ * OUTB
+ * Writes one BYTE to a single I/O address.
+ *-------------------------------------------*/
+
+#define OUTB(port, data) cim_outb(port, data)
+void cim_outb (unsigned short port, unsigned char data)
+{
+ _asm {
+ pushf
+ mov al, data
+ mov dx, port
+ out dx, al
+ popf
+ }
+}
+
+/*-------------------------------------------
+ * INB
+ * Reads one BYTE from a single I/O address.
+ *-------------------------------------------*/
+
+#define INB(port) cim_inb(port)
+unsigned char cim_inb (unsigned short port)
+{
+ unsigned char data;
+ _asm {
+ pushf
+ mov dx, port
+ in al, dx
+ mov data, al
+ popf
+ }
+ return data;
+}
+
+#elif CIMARRON_IO_ABSTRACTED_ASM
+
+/*-------------------------------------------
+ * OUTD
+ * Writes one DWORD to a single I/O address.
+ *-------------------------------------------*/
+
+#define OUTD(port, data) cim_outd(port, data)
+void cim_outd (unsigned short port, unsigned long data);
+void cim_outd (unsigned short port, unsigned long data)
+{
+ __asm__ __volatile__ ("outl %0,%w1" : : "a" (data), "Nd" (port));
+}
+
+/*-------------------------------------------
+ * IND
+ * Reads one DWORD from a single I/O address.
+ *-------------------------------------------*/
+
+#define IND(port) cim_ind(port)
+unsigned long cim_ind (unsigned short port);
+unsigned long cim_ind (unsigned short port)
+{
+ unsigned long value;
+ __asm__ __volatile__ ("inl %w1,%0" : "=a" (value) : "Nd" (port) );
+
+ return value;
+}
+
+/*-------------------------------------------
+ * OUTW
+ * Writes one WORD to a single I/O address.
+ *-------------------------------------------*/
+
+#define OUTW(port, data) cim_outw(port, data)
+void cim_outw (unsigned short port, unsigned short data);
+void cim_outw (unsigned short port, unsigned short data)
+{
+ __asm__ volatile ("out %0,%1" : : "a" (data),"d" (port));
+}
+
+/*-------------------------------------------
+ * INW
+ * Reads one WORD from a single I/O address.
+ *-------------------------------------------*/
+
+#define INW(port) cim_inw(port)
+unsigned short cim_inw (unsigned short port);
+unsigned short cim_inw (unsigned short port)
+{
+ unsigned short value;
+ __asm__ volatile ("in %1,%0" : "=a" (value) : "d" (port));
+ return value;
+}
+
+/*-------------------------------------------
+ * INB
+ * Reads one BYTE from a single I/O address.
+ *-------------------------------------------*/
+
+#define INB(port) cim_inb(port)
+unsigned char cim_inb(unsigned short port);
+unsigned char cim_inb(unsigned short port)
+{
+ unsigned char value;
+ __asm__ volatile ("inb %1,%0":"=a" (value):"d"(port));
+
+ return value;
+}
+
+/*-------------------------------------------
+ * OUTB
+ * Writes one BYTE to a single I/O address.
+ *-------------------------------------------*/
+
+#define OUTB(port) cim_outb(port)
+void cim_outb(unsigned short port, unsigned char data);
+void cim_outb(unsigned short port, unsigned char data)
+{
+ __asm__ volatile ("outb %0,%1"::"a" (data), "d"(port));
+}
+
+#endif
+
+#endif /* CIMARRON_INCLUDE_IO_MACROS */
+
+#endif
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_df.c xf86-video-nsc-2.8.1/src/cim/cim_df.c
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_df.c 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_df.c 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,2544 @@
+ /*
+ *
+ * Copyright (C) 2005 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *
+ *
+ *
+ *
+ *
+ * Cimarron display filter routines. These routines program the video hardware.
+ *
+ *
+ */
+
+/*---------------------------------------------------------------------------
+ * df_set_crt_enable
+ *
+ * This routine enables or disables CRT output.
+ *---------------------------------------------------------------------------*/
+
+int df_set_crt_enable (int crt_output)
+{
+ unsigned long config, misc;
+
+ config = READ_VID32 (DF_DISPLAY_CONFIG);
+ misc = READ_VID32 (DF_VID_MISC);
+
+ switch (crt_output)
+ {
+ /* DISABLE DISPLAY */
+
+ case DF_CRT_DISABLE:
+
+ config &= ~(DF_DCFG_DIS_EN | DF_DCFG_HSYNC_EN |
+ DF_DCFG_VSYNC_EN | DF_DCFG_DAC_BL_EN);
+ misc |= DF_DAC_POWER_DOWN;
+ break;
+
+ /* ENABLE THE DISPLAY */
+
+ case DF_CRT_ENABLE:
+
+ config |= (DF_DCFG_DIS_EN | DF_DCFG_HSYNC_EN |
+ DF_DCFG_VSYNC_EN | DF_DCFG_DAC_BL_EN);
+ misc &= ~(DF_DAC_POWER_DOWN | DF_ANALOG_POWER_DOWN);
+ break;
+
+ /* HSYNC:OFF VSYNC:ON */
+
+ case DF_CRT_STANDBY:
+
+ config = (config & ~(DF_DCFG_DIS_EN | DF_DCFG_HSYNC_EN | DF_DCFG_DAC_BL_EN)) |
+ DF_DCFG_VSYNC_EN;
+ misc |= DF_DAC_POWER_DOWN;
+ break;
+
+ /* HSYNC:ON VSYNC:OFF */
+
+ case DF_CRT_SUSPEND:
+
+ config = (config & ~(DF_DCFG_DIS_EN | DF_DCFG_VSYNC_EN | DF_DCFG_DAC_BL_EN)) |
+ DF_DCFG_HSYNC_EN;
+ misc |= DF_DAC_POWER_DOWN;
+ break;
+
+ default:
+ return CIM_STATUS_INVALIDPARAMS;
+ }
+
+ WRITE_VID32 (DF_DISPLAY_CONFIG, config);
+ WRITE_VID32 (DF_VID_MISC, misc);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_panel_enable
+ *
+ * This routine enables or disables panel output.
+ *---------------------------------------------------------------------------*/
+
+int df_set_panel_enable (int enable)
+{
+ unsigned long pm;
+
+ pm = READ_VID32 (DF_POWER_MANAGEMENT);
+
+ if (enable) pm |= DF_PM_PANEL_ON;
+ else pm &= ~DF_PM_PANEL_ON;
+
+ WRITE_VID32 (DF_POWER_MANAGEMENT, pm);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_configure_video_source
+ *
+ * This routine initializes all aspects of the source buffer for a video overlay.
+ *---------------------------------------------------------------------------*/
+
+int df_configure_video_source (DF_VIDEO_SOURCE_PARAMS *video_source_odd,
+ DF_VIDEO_SOURCE_PARAMS *video_source_even)
+{
+ unsigned long pitch, ctrl, vcfg;
+ unsigned long lock, vg_line, gcfg;
+ unsigned long width, size, scale;
+ unsigned long misc;
+
+ lock = READ_REG32 (DC3_UNLOCK);
+ vg_line = READ_REG32 (DC3_LINE_SIZE);
+ gcfg = READ_REG32 (DC3_GENERAL_CFG);
+ vcfg = READ_VID32 (DF_VIDEO_CONFIG);
+ ctrl = READ_VID32 (DF_VID_ALPHA_CONTROL);
+ scale = READ_VID32 (DF_VIDEO_SCALER);
+
+ /* STORE THE DESIRED SCALING PROCEDURE */
+ /* Cimarron supports two modes when programming the scale and position */
+ /* of the video window. The first mode is designed to implicitly apply */
+ /* the graphics scale to any video operations. The second applys the */
+ /* video unchanged, allowing complete control by the user. To allow */
+ /* visibility between modules, the current mode is stored in a spare */
+ /* bit in the DF miscellaneous register. */
+
+ misc = READ_VID32 (DF_VID_MISC);
+ if (video_source_odd->flags & DF_SOURCEFLAG_IMPLICITSCALING)
+ misc |= DF_USER_IMPLICIT_SCALING;
+ else
+ misc &= DF_USER_IMPLICIT_SCALING;
+ WRITE_VID32 (DF_VID_MISC, misc);
+
+ /* PARAMETER - VIDEO PITCH */
+
+ pitch = (video_source_odd->y_pitch >> 3) | ((video_source_odd->uv_pitch >> 3) << 16);
+
+ /* PARAMETER - VIDEO FORMAT */
+
+ gcfg &= ~DC3_GCFG_YUV_420;
+ vcfg &= ~(DF_VCFG_VID_INP_FORMAT | DF_VCFG_4_2_0_MODE);
+ ctrl &= ~(DF_VIDEO_INPUT_IS_RGB | DF_CSC_VIDEO_YUV_TO_RGB | DF_HD_VIDEO |
+ DF_YUV_CSC_EN);
+
+ /* SELECT PIXEL ORDERING */
+
+ switch (video_source_odd->video_format & 3)
+ {
+ case 0: vcfg |= DF_VCFG_UYVY_FORMAT; break;
+ case 1: vcfg |= DF_VCFG_Y2YU_FORMAT; break;
+ case 2: vcfg |= DF_VCFG_YUYV_FORMAT; break;
+ case 3: vcfg |= DF_VCFG_YVYU_FORMAT; break;
+ }
+
+ /* SELECT SOURCE FORMAT (4:2:2, 4:2:0, RGB) */
+
+ switch (video_source_odd->video_format >> 2)
+ {
+ case 0: ctrl |= DF_CSC_VIDEO_YUV_TO_RGB; break;
+
+ case 1: ctrl |= DF_CSC_VIDEO_YUV_TO_RGB;
+ vcfg |= DF_VCFG_4_2_0_MODE;
+ gcfg |= DC3_GCFG_YUV_420;
+ break;
+
+ case 2: ctrl |= DF_VIDEO_INPUT_IS_RGB; break;
+
+ default: return CIM_STATUS_INVALIDPARAMS;
+ }
+
+ /* ALIGN TO APPROPRIATE OUTPUT COLOR SPACE */
+ /* We have assumed until this point that the output color space is RGB */
+ /* and the input (if YUV) is always SDTV video. */
+
+ if (video_source_odd->flags & DF_SOURCEFLAG_HDTVSOURCE)
+ ctrl |= DF_HD_VIDEO;
+
+ if (ctrl & DF_CSC_GRAPHICS_RGB_TO_YUV)
+ {
+ /* YUV OUTPUT - DISABLE YUV->RGB AND ENABLE YUV->YUV */
+
+ ctrl &= ~DF_CSC_VIDEO_YUV_TO_RGB;
+
+ if ((!(ctrl & DF_HD_VIDEO) && (ctrl & DF_HD_GRAPHICS)) ||
+ ((ctrl & DF_HD_VIDEO) && !(ctrl & DF_HD_GRAPHICS)))
+ {
+ ctrl |= DF_YUV_CSC_EN;
+ }
+ }
+
+ /* PARAMETER - DISPLAY FILTER BUFFER SIZE */
+ /* The line size in the video generator must be 32-byte aligned. */
+ /* However, smaller alignments are managed by setting the */
+ /* appropriate pitch and clipping the video window. */
+
+ vcfg &= ~(DF_VCFG_LINE_SIZE_LOWER_MASK | DF_VCFG_LINE_SIZE_BIT8 |
+ DF_VCFG_LINE_SIZE_BIT9);
+
+ size = ((video_source_odd->width >> 1) + 7) & 0xFFF8;
+
+ vcfg |= (size & 0x00FF) << 8;
+ if (size & 0x0100) vcfg |= DF_VCFG_LINE_SIZE_BIT8;
+ if (size & 0x0200) vcfg |= DF_VCFG_LINE_SIZE_BIT9;
+
+ scale = (scale & ~0x7FF) | video_source_odd->height;
+
+ /* PARAMETER - VIDEO GENERATOR BUFFER SIZE */
+
+ vg_line &= ~DC3_LINE_SIZE_VLS_MASK;
+
+ if (gcfg & DC3_GCFG_YUV_420)
+ width = ((video_source_odd->width >> 1) + 7) & 0xFFF8;
+ else
+ width = ((video_source_odd->width << 1) + 31) & 0xFFE0;
+
+ vg_line |= (width >> 3) << DC3_LINE_SIZE_VB_SHIFT;
+
+ /* WRITE ALL PARAMETERS AT ONCE */
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_VID32 (DF_VIDEO_CONFIG, vcfg);
+ WRITE_VID32 (DF_VID_ALPHA_CONTROL, ctrl);
+ WRITE_VID32 (DF_VIDEO_SCALER, scale);
+ WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+ WRITE_REG32 (DC3_LINE_SIZE, vg_line);
+ WRITE_REG32 (DC3_VID_YUV_PITCH, pitch);
+
+ /* WRITE EVEN OR ODD BUFFER OFFSETS */
+ /* The even buffer is only valid inside an interlaced display. */
+
+ if (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)
+ {
+ WRITE_REG32 (DC3_VID_EVEN_Y_ST_OFFSET, video_source_even->y_offset);
+ WRITE_REG32 (DC3_VID_EVEN_U_ST_OFFSET, video_source_even->u_offset);
+ WRITE_REG32 (DC3_VID_EVEN_V_ST_OFFSET, video_source_even->v_offset);
+ }
+
+ WRITE_REG32 (DC3_VID_Y_ST_OFFSET, video_source_odd->y_offset);
+ WRITE_REG32 (DC3_VID_U_ST_OFFSET, video_source_odd->u_offset);
+ WRITE_REG32 (DC3_VID_V_ST_OFFSET, video_source_odd->v_offset);
+
+ WRITE_REG32 (DC3_UNLOCK, lock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_video_offsets
+ *
+ * This routine sets the starting offset for the video buffer(s). The buffers
+ * can also be configured inside df_configure_video_source, but a separate
+ * routine is provided here to allow quick buffer flipping.
+ *---------------------------------------------------------------------------*/
+
+int df_set_video_offsets (int even, unsigned long y_offset,
+ unsigned long u_offset, unsigned long v_offset)
+{
+ unsigned long lock = READ_REG32 (DC3_UNLOCK);
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+ if (even)
+ {
+ WRITE_REG32 (DC3_VID_EVEN_Y_ST_OFFSET, y_offset);
+ WRITE_REG32 (DC3_VID_EVEN_U_ST_OFFSET, u_offset);
+ WRITE_REG32 (DC3_VID_EVEN_V_ST_OFFSET, v_offset);
+ }
+ else
+ {
+ WRITE_REG32 (DC3_VID_Y_ST_OFFSET, y_offset);
+ WRITE_REG32 (DC3_VID_U_ST_OFFSET, u_offset);
+ WRITE_REG32 (DC3_VID_V_ST_OFFSET, v_offset);
+ }
+
+ WRITE_REG32 (DC3_UNLOCK, lock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_video_scale
+ *
+ * This routine programs the horizontal/vertical scale factors for video. To
+ * disable scaling/filtering, this routine should be called with identical source
+ * and destination dimensions.
+ *---------------------------------------------------------------------------*/
+
+int df_set_video_scale (unsigned long src_width, unsigned long src_height,
+ unsigned long dst_width, unsigned long dst_height, unsigned long flags)
+{
+ unsigned long temp, misc;
+ unsigned long scale, gfxscale;
+ unsigned long fbactive, src;
+ unsigned long size, downscale;
+ unsigned long vcfg, gcfg, unlock;
+
+ /* APPLY THE GRAPHICS SCALE */
+ /* When requested by the user, we will adjust the video scale by the */
+ /* current graphics scale factor. This allows video to be programmed */
+ /* in terms of the graphics source resolution. */
+
+ misc = READ_VID32 (DF_VID_MISC);
+ if (misc & DF_USER_IMPLICIT_SCALING)
+ {
+ gfxscale = READ_REG32 (DC3_GFX_SCALE);
+ fbactive = READ_REG32 (DC3_FB_ACTIVE);
+
+ /* REVERSE ENGINEER THE SCALE FACTOR */
+ /* The graphics scale factor is (source / (dst - 1)), so a little */
+ /* math is performed to reverse engineer the correct scale for */
+ /* video. */
+ /* */
+ /* F = (0x4000*S)/(D-1) -> (D/S) = (((0x4000*S)/F)+1)/S */
+
+ scale = gfxscale & 0xFFFF;
+ src = (fbactive >> 16) + 1;
+ if (scale != 0x4000)
+ {
+ dst_width = dst_width * (((0x4000 * src) / scale) + 1);
+ dst_width /= src;
+ }
+
+ scale = gfxscale >> 16;
+ src = (fbactive & 0xFFFF) + 1;
+ if (scale != 0x4000)
+ {
+ dst_height = dst_height * (((0x4000 * src) / scale) + 1);
+ dst_height /= src;
+ }
+ }
+
+ /* CHECK FOR VALID SCALING FACTOR */
+ /* The display filter/video generator can support up to 8:1 */
+ /* horizontal downscale and up to 4:1 vertical downscale. */
+ /* Scale factors above 4:1 horizontal and 2:1 horizontal */
+ /* will have a quality impact. However, at such large scale */
+ /* factors, it might not matter, */
+
+ if (((flags & DF_SCALEFLAG_CHANGEX) && dst_width < (src_width >> 3)) ||
+ ((flags & DF_SCALEFLAG_CHANGEY) && dst_height < (src_height >> 2)))
+ {
+ return CIM_STATUS_INVALIDSCALE;
+ }
+
+ /* ENABLE OR DISABLE ADVANCED SCALING FEATURES */
+ /* Scaling above 2:1 vertical and 4:1 horizontal relies */
+ /* on mechanisms beside the line filter. */
+
+ if (flags & DF_SCALEFLAG_CHANGEX)
+ {
+ scale = READ_VID32 (DF_VIDEO_SCALER);
+ vcfg = READ_VID32 (DF_VIDEO_CONFIG);
+ vcfg &= ~(DF_VCFG_LINE_SIZE_LOWER_MASK | DF_VCFG_LINE_SIZE_BIT8 |
+ DF_VCFG_LINE_SIZE_BIT9);
+
+ if (dst_width < (src_width >> 2))
+ {
+ src_width >>= 1;
+ WRITE_VID32 (DF_VIDEO_SCALER, scale | DF_SCALE_DOUBLE_H_DOWNSCALE);
+ }
+ else
+ {
+ WRITE_VID32 (DF_VIDEO_SCALER, scale & ~DF_SCALE_DOUBLE_H_DOWNSCALE);
+ }
+
+ /* PROGRAM A NEW LINE SIZE */
+ /* The line size must be updated when using the Double Horizontal */
+ /* Downscale (DHD) bit. This is because the amount of VFIFO space */
+ /* consumed is effectively half in this mode. */
+
+ size = ((src_width >> 1) + 7) & 0xFFF8;
+ vcfg |= (size & 0x00FF) << 8;
+ if (size & 0x0100) vcfg |= DF_VCFG_LINE_SIZE_BIT8;
+ if (size & 0x0200) vcfg |= DF_VCFG_LINE_SIZE_BIT9;
+ WRITE_VID32 (DF_VIDEO_CONFIG, vcfg);
+ WRITE_VID32 (DF_VIDEO_XSCALE, ((0x10000 * src_width) / dst_width));
+ }
+ if (flags & DF_SCALEFLAG_CHANGEY)
+ {
+ unlock = READ_REG32 (DC3_UNLOCK);
+ gcfg = READ_REG32 (DC3_GENERAL_CFG) & ~DC3_GCFG_VDSE;
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ if (dst_height < (src_height >> 1))
+ {
+ gcfg |= DC3_GCFG_VDSE;
+ downscale = READ_REG32 (DC3_VID_DS_DELTA) & ~DC3_DS_DELTA_MASK;
+ if (dst_height == (src_height >> 2))
+ downscale |= (0x3FFF << 18);
+ else
+ downscale |= (((src_height >> 1) << 14) / dst_height) << 18;
+
+ WRITE_REG32 (DC3_VID_DS_DELTA, downscale);
+ WRITE_VID32 (DF_VIDEO_YSCALE, 0x20000);
+ }
+ else
+ {
+ WRITE_VID32 (DF_VIDEO_YSCALE, ((0x10000 * src_height) / dst_height));
+ }
+ WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+ WRITE_REG32 (DC3_UNLOCK, unlock);
+ }
+
+ /* CHECK IF SCALING IS DISABLED */
+ /* If no scaling occurs, we disable the hardware filter. */
+
+ temp = READ_VID32 (DF_VIDEO_CONFIG);
+ if ((READ_VID32 (DF_VIDEO_XSCALE) == 0x10000) &&
+ (READ_VID32 (DF_VIDEO_YSCALE) == 0x10000))
+ {
+ WRITE_VID32 (DF_VIDEO_CONFIG, (temp | DF_VCFG_SC_BYP));
+ }
+ else
+ WRITE_VID32 (DF_VIDEO_CONFIG, (temp & ~DF_VCFG_SC_BYP));
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_video_position
+ *
+ * This routine programs the position of the video window on the display.
+ * An indent parameter is also passed to this program to prevent artifacts
+ * when the video window is moved beyond the left edge of the screen.
+ *---------------------------------------------------------------------------*/
+
+int df_set_video_position (DF_VIDEO_POSITION *video_window)
+{
+ unsigned long vblankstart_even, vblankend_even, vsyncend_even, vtotal_even, vactive_even;
+ unsigned long hblankstart, hblankend, hsyncend, htotal, hactive;
+ unsigned long vblankstart, vblankend, vsyncend, vtotal, vactive;
+ unsigned long width, height, height_even;
+ unsigned long adjust, border_x, border_y, border_y_even;
+ unsigned long xstart, xend;
+ unsigned long ystart, yend;
+ unsigned long ckey_x, ckey_y;
+ unsigned long x_copy, y_copy;
+ unsigned long width_copy, height_copy;
+ unsigned long vcfg, initread;
+ unsigned long xscale, dst_clip;
+ unsigned long ypos, ypos_even;
+ unsigned long y, gfxscale;
+ unsigned long misc, fbactive;
+ unsigned long scale, src;
+ unsigned long irq_ctl;
+ unsigned long unlock;
+
+ hsyncend = ((READ_REG32 (DC3_H_SYNC_TIMING) >> 16) & 0xFFF) + 1;
+ vsyncend = ((READ_REG32 (DC3_V_SYNC_TIMING) >> 16) & 0xFFF) + 1;
+ vblankend = ((READ_REG32 (DC3_V_BLANK_TIMING) >> 16) & 0xFFF) + 1;
+ hblankend = ((READ_REG32 (DC3_H_BLANK_TIMING) >> 16) & 0xFFF) + 1;
+ htotal = ((READ_REG32 (DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+ vtotal = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+ vblankstart = (READ_REG32 (DC3_V_BLANK_TIMING) & 0xFFF) + 1;
+ hblankstart = (READ_REG32 (DC3_H_BLANK_TIMING) & 0xFFF) + 1;
+ hactive = (READ_REG32 (DC3_H_ACTIVE_TIMING) & 0xFFF) + 1;
+ vactive = (READ_REG32 (DC3_V_ACTIVE_TIMING) & 0xFFF) + 1;
+ unlock = READ_REG32 (DC3_UNLOCK);
+
+ /* INCLUDE BORDER IF REQUESTED */
+
+ if (video_window->flags & DF_POSFLAG_INCLUDEBORDER)
+ {
+ border_x = htotal - hblankend;
+ border_y = vtotal - vblankend;
+ hactive = hblankstart + htotal - hblankend;
+ vactive = vblankstart + vtotal - vblankend;
+ }
+ else
+ {
+ border_x = border_y = 0;
+ }
+
+ /* APPLY THE GRAPHICS SCALE */
+ /* Do not alter the input data. */
+
+ width_copy = video_window->width;
+ height_copy = video_window->height;
+ x_copy = video_window->x;
+ y_copy = video_window->y;
+
+ misc = READ_VID32 (DF_VID_MISC);
+ if (misc & DF_USER_IMPLICIT_SCALING)
+ {
+ gfxscale = READ_REG32 (DC3_GFX_SCALE);
+ fbactive = READ_REG32 (DC3_FB_ACTIVE);
+
+ /* REVERSE ENGINEER THE SCALE FACTOR */
+
+ scale = gfxscale & 0xFFFF;
+ src = (fbactive >> 16) + 1;
+ if (scale != 0x4000)
+ {
+ width_copy = width_copy * (((0x4000 * src) / scale) + 1);
+ width_copy /= src;
+ x_copy = x_copy * (((0x4000 * src) / scale) + 1);
+ x_copy /= src;
+ }
+
+ scale = gfxscale >> 16;
+ src = (fbactive & 0xFFFF) + 1;
+ if (scale != 0x4000)
+ {
+ height_copy = height_copy * (((0x4000 * src) / scale) + 1);
+ height_copy /= src;
+ y_copy = y_copy * (((0x4000 * src) / scale) + 1);
+ y_copy /= src;
+ }
+ }
+
+ /* HANDLE INTERLACING */
+ /* When the output is interlaced, we must set the position and height */
+ /* on the fields and not on the composite image. */
+
+ if ((irq_ctl = READ_REG32 (DC3_IRQ_FILT_CTL)) & DC3_IRQFILT_INTL_EN)
+ {
+ vsyncend_even = ((READ_REG32 (DC3_V_SYNC_EVEN) >> 16) & 0xFFF) + 1;
+ vtotal_even = ((READ_REG32 (DC3_V_ACTIVE_EVEN) >> 16) & 0xFFF) + 1;
+ vblankend_even = ((READ_REG32 (DC3_V_BLANK_EVEN) >> 16) & 0xFFF) + 1;
+ vactive_even = (READ_REG32 (DC3_V_ACTIVE_EVEN) & 0xFFF) + 1;
+ vblankstart_even = (READ_REG32 (DC3_V_BLANK_EVEN) & 0xFFF) + 1;
+
+ if (video_window->flags & DF_POSFLAG_INCLUDEBORDER)
+ {
+ border_y_even = vtotal_even- vblankend_even;
+ vactive_even = vblankstart_even + vtotal_even - vblankend_even;
+ }
+ else
+ border_y_even = 0;
+
+ /* THE ODD FIELD MUST ALWAYS PRECEDE THE EVEN FIELD */
+ /* This implies that we can never start video on an odd y position */
+ /* in the composite image. This is required because the only way to */
+ /* accomplish an odd y start would be to switch the buffer offsets, */
+ /* which could have serious repercussions for genlocked VIP. */
+
+ y = y_copy >> 1;
+
+ /* CALCULATE Y POSITION FOR ODD FIELD */
+ /* Clip the video window to the odd field timings. Note that the */
+ /* height in the odd field may be greater if the video height is */
+ /* odd. */
+
+ height = (height_copy + 1) >> 1;
+ if ((y + height) > vactive)
+ height = vactive - y;
+
+ ystart = y + vtotal_even - vsyncend_even + 1;
+ if (video_window->flags & DF_POSFLAG_INCLUDEBORDER)
+ ystart -= border_y_even;
+
+ yend = ystart + height;
+ ypos = (yend << 16) | ystart;
+
+ /* CALCULATE Y POSITION FOR EVEN FIELD */
+
+ height_even = height_copy >> 1;
+ if ((y + height_even) > vactive_even)
+ height_even = vactive_even - y;
+
+ ystart = y + vtotal - vsyncend + 1;
+ if (video_window->flags & DF_POSFLAG_INCLUDEBORDER)
+ ystart -= border_y;
+
+ yend = ystart + height_even;
+ ypos_even = (yend << 16) | ystart;
+
+ /* CALCULATE ACTUAL FRAME BUFFER HEIGHT */
+ /* The y position and height are used to determine the actual */
+ /* placement of the color key region. The region will either be */
+ /* the sum of the even and odd fields (for interlaced addressing */
+ /* or flicker filtering) or it will be the union of the two (for */
+ /* line doubling). We must also adjust the region such that the */
+ /* origin (0, 0) is centered on the beginning of graphics data. */
+ /* This is only a problem if video is being displayed over the */
+ /* overscan area. */
+
+ if ((READ_REG32 (DC3_GENLK_CTL) & DC3_GC_FLICKER_FILTER_ENABLE) ||
+ (irq_ctl & DC3_IRQFILT_INTL_ADDR))
+ {
+ y <<= 1;
+ height += height_even;
+ adjust = border_y + border_y_even;
+ }
+ else
+ {
+ adjust = border_y;
+ if (height_even > height)
+ height = height_even;
+ }
+ if (video_window->flags & DF_POSFLAG_INCLUDEBORDER)
+ {
+ if (y > adjust)
+ {
+ y -= adjust;
+ adjust = 0;
+ }
+ else
+ {
+ adjust -= y;
+ if (height > adjust)
+ height -= adjust;
+ else
+ height = 0;
+ }
+ }
+
+ }
+ else
+ {
+ y = y_copy;
+
+ height = height_copy;
+ if ((y + height) > vactive)
+ height = vactive - y;
+
+ ystart = y + vtotal - vsyncend + 1;
+ if (video_window->flags & DF_POSFLAG_INCLUDEBORDER)
+ ystart -= border_y;
+
+ yend = ystart + height;
+ ypos = (yend << 16) | ystart;
+ ypos_even = 0;
+ }
+
+ /* HORIZONTAL POSITION */
+ /* The horizontal values are identical for the even and odd field. */
+
+ width = width_copy;
+ xstart = x_copy + htotal - hsyncend - 14;
+ if (video_window->flags & DF_POSFLAG_INCLUDEBORDER)
+ xstart -= border_x;
+
+ /* RIGHT CLIPPING */
+
+ if ((x_copy + width) > hactive)
+ width = hactive - x_copy;
+
+ xend = xstart + width;
+
+ /* CALCULATE LEFT CLIPPING PARAMETER */
+ /* The value passed in can be interpreted as destination pixels, in which */
+ /* case the video scale is factored in, or as source pixels, in which case */
+ /* the value is written directly. Also, the display filter's initial read */
+ /* address value is only programmable on 4-pixel increments. However, we */
+ /* can achieve an arbitrary left clip by adjusting the xstart value, as */
+ /* there is a 14-clock delay in which to play. Also, according to the */
+ /* designers, 4:2:0 and 4:2:2 behave identically when setting the initial */
+ /* read address. The addition of scaling further complicates the */
+ /* algorithm. When setting the initial read address, it is in terms of */
+ /* source pixels, while adjusting the xstart value is in destination pixels */
+ /* We may thus not be able to achieve a perfect clipping fit for scaled */
+ /* video. We compensate by including two clipping parameters in our */
+ /* structure. This allows us the user additional control and it allows us */
+ /* to accurately convey to the user the state of clipping on the machine. */
+
+ initread = video_window->left_clip;
+ dst_clip = 0;
+ if (!(video_window->flags & DF_POSFLAG_DIRECTCLIP))
+ {
+ xscale = READ_VID32 (DF_VIDEO_XSCALE) & 0xFFFFF;
+ initread = (initread * xscale) / 0x10000;
+ if (xscale)
+ dst_clip = ((initread & 3) * 0x10000) / xscale;
+ }
+ else
+ dst_clip = video_window->dst_clip;
+
+ /* LIMIT THE CLIP */
+ /* We technically have a 14 pixel window in which to play. However, taking */
+ /* the entire 14 pixels makes the video timing a little hairy... Also note */
+ /* that we cannot do this when performing panel centering, as the video */
+ /* would then exceed the mode size. */
+
+ if (dst_clip > 4)
+ dst_clip = 4;
+ if (READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_DCEN)
+ dst_clip = 0;
+
+ xstart -= dst_clip;
+
+ vcfg = READ_VID32 (DF_VIDEO_CONFIG);
+ vcfg &= ~DF_VCFG_INIT_READ_MASK;
+ vcfg |= (initread >> 2) << 16;
+
+ /* SET COLOR KEY REGION */
+ /* We are assuming that color keying will never be desired outside */
+ /* of the video region. We adjust the color key region for graphics */
+ /* scaling. */
+
+ gfxscale = READ_REG32 (DC3_GFX_SCALE);
+
+ ckey_x = ((x_copy * (gfxscale & 0xFFFF)) / 0x4000) |
+ ((((x_copy + width) * (gfxscale & 0xFFFF)) / 0x4000) << 16);
+ ckey_y = ((y * (gfxscale >> 16)) / 0x4000) |
+ ((((y + height) * (gfxscale >> 16)) / 0x4000) << 16);
+
+ /* WRITE ALL PARAMETERS AT ONCE */
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_CLR_KEY_X, ckey_x);
+ WRITE_REG32 (DC3_CLR_KEY_Y, ckey_y);
+ WRITE_VID32 (DF_VIDEO_X_POS, (xend << 16) | xstart);
+ WRITE_VID32 (DF_VIDEO_Y_POS, ypos);
+ WRITE_VID32 (DF_VID_YPOS_EVEN, ypos_even);
+ WRITE_VID32 (DF_VIDEO_CONFIG, vcfg);
+ WRITE_REG32 (DC3_UNLOCK, unlock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_video_filter_coefficients
+ *
+ * This routine sets the horizontal and vertical filter coefficients for video
+ * scaling. These coefficients are used for upscaling and downscaling video.
+ * If the phase256 parameter is 1, the coefficient arrays are used as single
+ * arrays of 256 phases for both vertical and horizontal scaling. If the
+ * phase256 parameter is clear, the coefficient arrays are used as two 128-phase
+ * arrays. The first 128 entries represent the phases for vertical scaling.
+ * The last 128 entries represent the phases for horizontal scaling.
+ *---------------------------------------------------------------------------*/
+
+int df_set_video_filter_coefficients (long taps[][4], int phase256)
+{
+ unsigned long scale, coeff0, coeff1;
+ unsigned long i;
+ long (*defaults)[2];
+
+ /* SET PHASE COUNT AND CHOOSE COEFFICIENT ARRAY */
+
+ scale = READ_VID32 (DF_VIDEO_SCALER);
+ if (phase256)
+ {
+ WRITE_VID32 (DF_VIDEO_SCALER, (scale & ~DF_SCALE_128_PHASES));
+ defaults = CimarronVideoFilter256;
+ }
+ else
+ {
+ WRITE_VID32 (DF_VIDEO_SCALER, (scale | DF_SCALE_128_PHASES));
+ defaults = CimarronVideoFilter128;
+ }
+
+ /* PROGRAM COEFFICIENTS */
+
+ for (i = 0; i < 256; i++)
+ {
+ if (!taps)
+ {
+ coeff0 = defaults[i][0];
+ coeff1 = defaults[i][1];
+ }
+ else
+ {
+ if (taps[i][1] < 0) coeff0 = -taps[i][1] | 0x8000;
+ else coeff0 = taps[i][1];
+
+ coeff0 <<= 16;
+
+ if (taps[i][0] < 0) coeff0 |= -taps[i][0] | 0x8000;
+ else coeff0 |= taps[i][0];
+
+
+
+ if (taps[i][3] < 0) coeff1 = -taps[i][3] | 0x8000;
+ else coeff1 = taps[i][3];
+
+ coeff1 <<= 16;
+
+ if (taps[i][2] < 0) coeff1 |= -taps[i][2] | 0x8000;
+ else coeff1 |= taps[i][2];
+ }
+
+ WRITE_VID32 ((DF_COEFFICIENT_BASE + (i << 3)), coeff0);
+ WRITE_VID32 ((DF_COEFFICIENT_BASE + (i << 3) + 4), coeff1);
+ }
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_video_enable
+ *
+ * This routine enables or disables the video overlay.
+ *---------------------------------------------------------------------------*/
+
+int df_set_video_enable (int enable, unsigned long flags)
+{
+ unsigned long vcfg, lock, gcfg;
+ unsigned long dcfg, vg_ckey, fifo = 0;
+
+ vcfg = READ_VID32 (DF_VIDEO_CONFIG);
+ lock = READ_REG32 (DC3_UNLOCK);
+ gcfg = READ_REG32 (DC3_GENERAL_CFG);
+
+ /* SET VIDEO FIFO END WATERMARK */
+ /* The video FIFO end watermark is set to 0 when video is disabled */
+ /* to allow low priority transactions in the VG. Otherwise, the */
+ /* priority will be forced high until the VG fills the video FIFO */
+ /* by not fetching video. That could take a while... Note that */
+ /* we set the end priority to be 4 greater than the start. We */
+ /* assume that the start priority has been configured by a modeset. */
+
+ dcfg = READ_REG32 (DC3_DISPLAY_CFG) & ~DC3_DCFG_VFHPEL_MASK;
+ if (enable)
+ {
+ fifo = ((dcfg >> 12) & 0x0000000F) + 4;
+ if (fifo > 0xF)
+ fifo = 0xF;
+ }
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_DISPLAY_CFG, dcfg | (fifo << 16));
+
+ /* ENABLE OR DISABLE VIDEO */
+ /* The mechanism to fetch video data is enabled first and */
+ /* disabled last. */
+
+ if (enable)
+ {
+ WRITE_REG32 (DC3_GENERAL_CFG, (gcfg | DC3_GCFG_VIDE));
+ WRITE_VID32 (DF_VIDEO_CONFIG, (vcfg | DF_VCFG_VID_EN));
+
+ /* DISABLE COLOR KEYING IF REQUESTED BY THE USER */
+
+ if (flags & DF_ENABLEFLAG_NOCOLORKEY)
+ {
+ /* OVERRIDE THE MODE TO COLOR KEYING */
+
+ dcfg = READ_VID32 (DF_DISPLAY_CONFIG);
+ WRITE_VID32 (DF_DISPLAY_CONFIG, (dcfg & ~DF_DCFG_VG_CK));
+
+ /* DISABLE COLOR KEYING IN THE VG */
+
+ vg_ckey = READ_REG32 (DC3_COLOR_KEY);
+ WRITE_REG32 (DC3_COLOR_KEY, (vg_ckey & ~DC3_CLR_KEY_ENABLE));
+ }
+ else if (!(READ_VID32 (DF_DISPLAY_CONFIG) & DF_DCFG_VG_CK))
+ {
+ /* OTHERWISE RE-ENABLE COLOR KEYING */
+
+ vg_ckey = READ_REG32 (DC3_COLOR_KEY);
+ WRITE_REG32 (DC3_COLOR_KEY, (vg_ckey | DC3_CLR_KEY_ENABLE));
+ }
+ }
+ else
+ {
+ WRITE_VID32 (DF_VIDEO_CONFIG, (vcfg & ~DF_VCFG_VID_EN));
+ WRITE_REG32 (DC3_GENERAL_CFG, (gcfg & ~DC3_GCFG_VIDE));
+
+ /* DISABLE COLOR KEY WINDOW WHEN VIDEO IS INACTIVE */
+ /* To mimic legacy functionality, we disble color keying */
+ /* when the video window is not active. We will restore */
+ /* the enable when video is re-enabled if the appropriate */
+ /* bit is set in display config. */
+
+ vg_ckey = READ_REG32 (DC3_COLOR_KEY);
+ WRITE_REG32 (DC3_COLOR_KEY, (vg_ckey & ~DC3_CLR_KEY_ENABLE));
+ }
+ WRITE_REG32 (DC3_UNLOCK, lock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_video_color_key
+ *
+ * This routine configures the video color/chroma key mechanism.
+ *---------------------------------------------------------------------------*/
+
+int df_set_video_color_key (unsigned long key, unsigned long mask, int graphics)
+{
+ unsigned long lock, vg_ckey, df_dcfg;
+
+ vg_ckey = READ_REG32 (DC3_COLOR_KEY);
+ lock = READ_REG32 (DC3_UNLOCK);
+ df_dcfg = READ_VID32 (DF_DISPLAY_CONFIG);
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+ if (graphics)
+ {
+ /* COLOR KEY - USE VG HARDWARE */
+ /* Note that color key is never enabled unless a video window */
+ /* is active. This is to match legacy behavior. */
+
+ df_dcfg &= ~DF_DCFG_VG_CK;
+ vg_ckey = (vg_ckey & 0xFF000000) | (key & 0xFFFFFF);
+ if (READ_VID32 (DF_VIDEO_CONFIG) & DF_VCFG_VID_EN)
+ vg_ckey |= DC3_CLR_KEY_ENABLE;
+ else
+ vg_ckey &= ~DC3_CLR_KEY_ENABLE;
+
+ WRITE_VID32 (DF_DISPLAY_CONFIG, df_dcfg);
+ WRITE_REG32 (DC3_COLOR_KEY, vg_ckey);
+ WRITE_REG32 (DC3_COLOR_MASK, (mask & 0xFFFFFF));
+ }
+ else
+ {
+ /* CHROMA KEY - USE DF HARDWARE */
+
+ df_dcfg |= DF_DCFG_VG_CK;
+ vg_ckey &= ~DC3_CLR_KEY_ENABLE;
+
+ WRITE_REG32 (DC3_COLOR_KEY, vg_ckey);
+ WRITE_VID32 (DF_DISPLAY_CONFIG, df_dcfg);
+ WRITE_VID32 (DF_VIDEO_COLOR_KEY, (key & 0xFFFFFF));
+ WRITE_VID32 (DF_VIDEO_COLOR_MASK, (mask & 0xFFFFFF));
+ }
+
+ WRITE_REG32 (DC3_UNLOCK, lock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_video_palette
+ *
+ * This routine loads the video hardware palette. If a NULL pointer is
+ * specified, the palette is bypassed.
+ *--------------------------------------------------------------------------*/
+
+int df_set_video_palette (unsigned long *palette)
+{
+ unsigned long i, entry;
+ unsigned long misc, dcfg;
+
+ /* LOAD GEODE LX VIDEO PALETTE */
+
+ WRITE_VID32 (DF_PALETTE_ADDRESS, 0);
+ for (i = 0; i < 256; i++)
+ {
+ if (palette) entry = palette[i];
+ else entry = i | (i << 8) | (i << 16);
+ WRITE_VID32 (DF_PALETTE_DATA, entry);
+ }
+
+ /* ENABLE THE VIDEO PALETTE */
+ /* Ensure that the video palette has an effect by routing video data */
+ /* through the palette RAM and clearing the 'Bypass Both' bit. */
+
+ dcfg = READ_VID32 (DF_DISPLAY_CONFIG);
+ misc = READ_VID32 (DF_VID_MISC);
+
+ dcfg |= DF_DCFG_GV_PAL_BYP;
+ misc &= ~DF_GAMMA_BYPASS_BOTH;
+
+ WRITE_VID32 (DF_DISPLAY_CONFIG, dcfg);
+ WRITE_VID32 (DF_VID_MISC, misc);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_video_palette_entry
+ *
+ * This routine loads a single entry of the video hardware palette.
+ *--------------------------------------------------------------------------*/
+
+int df_set_video_palette_entry (unsigned long index, unsigned long palette)
+{
+ unsigned long misc, dcfg;
+
+ if (index > 0xFF)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ /* SET A SINGLE ENTRY */
+
+ WRITE_VID32 (DF_PALETTE_ADDRESS, index);
+ WRITE_VID32 (DF_PALETTE_DATA, palette);
+
+ /* ENABLE THE VIDEO PALETTE */
+ /* Ensure that the video palette has an effect by routing video data */
+ /* through the palette RAM and clearing the 'Bypass Both' bit. */
+
+ dcfg = READ_VID32 (DF_DISPLAY_CONFIG);
+ misc = READ_VID32 (DF_VID_MISC);
+
+ dcfg |= DF_DCFG_GV_PAL_BYP;
+ misc &= ~DF_GAMMA_BYPASS_BOTH;
+
+ WRITE_VID32 (DF_DISPLAY_CONFIG, dcfg);
+ WRITE_VID32 (DF_VID_MISC, misc);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_configure_video_cursor_color_key
+ *
+ * This routine configures the hardware video cursor color key mechanism.
+ *--------------------------------------------------------------------------*/
+
+int df_configure_video_cursor_color_key (DF_VIDEO_CURSOR_PARAMS *cursor_color_key)
+{
+ unsigned long key;
+
+ if (cursor_color_key->select_color2 >= 24)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ key = READ_VID32 (DF_CURSOR_COLOR_KEY) & DF_CURSOR_COLOR_KEY_ENABLE;
+ key = key | (cursor_color_key->key & 0xFFFFFF) | (cursor_color_key->select_color2 << 24);
+
+ WRITE_VID32 (DF_CURSOR_COLOR_KEY, key);
+ WRITE_VID32 (DF_CURSOR_COLOR_MASK, (cursor_color_key->mask & 0xFFFFFF));
+ WRITE_VID32 (DF_CURSOR_COLOR_1, (cursor_color_key->color1 & 0xFFFFFF));
+ WRITE_VID32 (DF_CURSOR_COLOR_2, (cursor_color_key->color2 & 0xFFFFFF));
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_video_cursor_color_key_enable
+ *
+ * This routine enables or disables the video cursor color key.
+ *--------------------------------------------------------------------------*/
+
+int df_set_video_cursor_color_key_enable (int enable)
+{
+ unsigned long temp = READ_VID32 (DF_CURSOR_COLOR_KEY);
+
+ if (enable) temp |= DF_CURSOR_COLOR_KEY_ENABLE;
+ else temp &= ~DF_CURSOR_COLOR_KEY_ENABLE;
+
+ WRITE_VID32 (DF_CURSOR_COLOR_KEY, temp);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_configure_alpha_window
+ *
+ * This routine configures one of the three hardware alpha regions.
+ *--------------------------------------------------------------------------*/
+
+int df_configure_alpha_window (int window, DF_ALPHA_REGION_PARAMS *alpha_data)
+{
+ unsigned long vsyncend_even, vtotal_even, vactive_even;
+ unsigned long hsyncend, htotal, hactive;
+ unsigned long vsyncend, vtotal, vactive;
+ unsigned long alpha_ctl, pos;
+ unsigned long hadjust, vadjust;
+ unsigned long y, height;
+ unsigned long xstart, xend;
+ unsigned long ystart, yend;
+ unsigned long x_copy, width_copy;
+ unsigned long y_copy, height_copy;
+ unsigned long scale, src, misc;
+ unsigned long gfxscale, fbactive;
+ unsigned long color;
+
+ if (window > 2)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ hsyncend = ((READ_REG32 (DC3_H_SYNC_TIMING) >> 16) & 0xFFF) + 1;
+ vsyncend = ((READ_REG32 (DC3_V_SYNC_TIMING) >> 16) & 0xFFF) + 1;
+ htotal = ((READ_REG32 (DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+ vtotal = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+ hactive = (READ_REG32 (DC3_H_ACTIVE_TIMING) & 0xFFF) + 1;
+ vactive = (READ_REG32 (DC3_V_ACTIVE_TIMING) & 0xFFF) + 1;
+
+ /* APPLY THE GRAPHICS SCALE */
+
+ width_copy = alpha_data->width;
+ height_copy = alpha_data->height;
+ x_copy = alpha_data->x;
+ y_copy = alpha_data->y;
+
+ misc = READ_VID32 (DF_VID_MISC);
+ if (misc & DF_USER_IMPLICIT_SCALING)
+ {
+ gfxscale = READ_REG32 (DC3_GFX_SCALE);
+ fbactive = READ_REG32 (DC3_FB_ACTIVE);
+
+ /* REVERSE ENGINEER THE SCALE FACTOR */
+
+ scale = gfxscale & 0xFFFF;
+ src = (fbactive >> 16) + 1;
+ if (scale != 0x4000)
+ {
+ width_copy = width_copy * (((0x4000 * src) / scale) + 1);
+ width_copy /= src;
+ x_copy = x_copy * (((0x4000 * src) / scale) + 1);
+ x_copy /= src;
+ }
+
+ scale = gfxscale >> 16;
+ src = (fbactive & 0xFFFF) + 1;
+ if (scale != 0x4000)
+ {
+ height_copy = height_copy * (((0x4000 * src) / scale) + 1);
+ height_copy /= src;
+ y_copy = y_copy * (((0x4000 * src) / scale) + 1);
+ y_copy /= src;
+ }
+ }
+
+ /* SET PRIORITY */
+ /* Priority is the only alpha parameter that is not in a register that */
+ /* can be indexed based on the alpha window number. */
+
+ pos = 16 + (window << 1);
+ alpha_ctl = READ_VID32 (DF_VID_ALPHA_CONTROL) & ~(3L << pos);
+ alpha_ctl |= (alpha_data->priority & 3) << pos;
+ WRITE_VID32 (DF_VID_ALPHA_CONTROL, alpha_ctl);
+
+ /* HANDLE INTERLACED MODES */
+
+ if (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)
+ {
+ vsyncend_even = ((READ_REG32 (DC3_V_SYNC_EVEN) >> 16) & 0xFFF) + 1;
+ vtotal_even = ((READ_REG32 (DC3_V_ACTIVE_EVEN) >> 16) & 0xFFF) + 1;
+ vactive_even = (READ_REG32 (DC3_V_ACTIVE_EVEN) & 0xFFF) + 1;
+
+ y = y_copy >> 1;
+
+ /* SET Y POSITION FOR ODD FIELD */
+
+ height = (height_copy + 1) >> 1;
+ vadjust = vtotal_even - vsyncend_even + 1;
+
+ ystart = y + vadjust;
+ yend = y + vadjust + height;
+
+ if (yend > (vactive + vadjust))
+ yend = vactive + vadjust;
+
+ WRITE_VID32 ((DF_ALPHA_YPOS_1 + (window << 5)), (ystart | (yend << 16)));
+
+ /* SET Y POSITION FOR EVEN FIELD */
+
+ height = height_copy >> 1;
+ vadjust = vtotal - vsyncend + 1;
+
+ ystart = y + vadjust;
+ yend = y + vadjust + height;
+
+ if (yend > (vactive_even + vadjust))
+ yend = vactive_even + vadjust;
+
+ WRITE_VID32 ((DF_VID_ALPHA_Y_EVEN_1 + (window << 3)), (ystart | (yend << 16)));
+ }
+ else
+ {
+ y = y_copy;
+ height = height_copy;
+ vadjust = vtotal - vsyncend + 1;
+
+ ystart = y + vadjust;
+ yend = y + vadjust + height;
+
+ if (yend > (vactive + vadjust))
+ yend = vactive + vadjust;
+
+ WRITE_VID32 ((DF_ALPHA_YPOS_1 + (window << 5)), (ystart | (yend << 16)));
+ }
+
+ /* SET ALPHA X POSITION */
+ /* The x position is the same for both the odd and even fields. */
+
+ hadjust = htotal - hsyncend - 2;
+
+ xstart = x_copy + hadjust;
+ xend = x_copy + hadjust + width_copy;
+
+ if (xend > (hactive + hadjust))
+ xend = hactive + hadjust;
+
+ WRITE_VID32 ((DF_ALPHA_XPOS_1 + (window << 5)), (xstart | (xend << 16)));
+
+ /* SET COLOR REGISTER */
+
+ color = alpha_data->color & 0xFFFFFF;
+ if (alpha_data->flags & DF_ALPHAFLAG_COLORENABLED)
+ color |= DF_ALPHA_COLOR_ENABLE;
+
+ WRITE_VID32 ((DF_ALPHA_COLOR_1 + (window << 5)), color);
+
+ /* SET ALPHA VALUE, DELTA AND PER PIXEL */
+
+ alpha_ctl = READ_VID32 (DF_ALPHA_CONTROL_1 + (window << 5)) & DF_ACTRL_WIN_ENABLE;
+ alpha_ctl |= (alpha_data->alpha_value & 0xFF) | DF_ACTRL_LOAD_ALPHA |
+ (((unsigned long)alpha_data->delta & 0xFF) << 8);
+ if (alpha_data->flags & DF_ALPHAFLAG_PERPIXELENABLED)
+ alpha_ctl |= DF_ACTRL_PERPIXEL_EN;
+
+ WRITE_VID32 ((DF_ALPHA_CONTROL_1 + (window << 5)), alpha_ctl);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_alpha_window_enable
+ *
+ * This routine enables or disables one of the three hardware alpha regions.
+ *--------------------------------------------------------------------------*/
+
+int df_set_alpha_window_enable (int window, int enable)
+{
+ unsigned long alpha_ctl;
+
+ if (window > 2)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ alpha_ctl = READ_VID32 (DF_ALPHA_CONTROL_1 + (window << 5));
+ if (enable) alpha_ctl |= DF_ACTRL_WIN_ENABLE;
+ else alpha_ctl &= ~DF_ACTRL_WIN_ENABLE;
+ WRITE_VID32 ((DF_ALPHA_CONTROL_1 + (window << 5)), alpha_ctl);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_no_ck_outside_alpha
+ *
+ * This function affects how color/chroma keying is performed inside the video
+ * window.
+ *
+ * If enable is 1, color/chroma key comparison is performed only inside
+ * the enabled alpha windows. Outside the enabled alpha windows, video
+ * is displayed if color keying is enabled, or graphics is displayed if
+ * chroma keying is enabled.
+ * If enable is 0, color/chroma key comparison is performed inside the
+ * entire video window.
+ *--------------------------------------------------------------------------*/
+
+int df_set_no_ck_outside_alpha (int enable)
+{
+ unsigned long value;
+
+ value = READ_VID32 (DF_VID_ALPHA_CONTROL);
+ if (enable) value |= DF_NO_CK_OUTSIDE_ALPHA;
+ else value &= ~DF_NO_CK_OUTSIDE_ALPHA;
+ WRITE_VID32 (DF_VID_ALPHA_CONTROL, value);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_video_request
+ *
+ * This routine sets the horizontal (pixel) and vertical (line) video request
+ * values.
+ *--------------------------------------------------------------------------*/
+
+int df_set_video_request (unsigned long x, unsigned long y)
+{
+ unsigned long htotal, hsyncend;
+ unsigned long vtotal, vsyncend;
+
+ hsyncend = ((READ_REG32 (DC3_H_SYNC_TIMING) >> 16) & 0xFFF) + 1;
+ vsyncend = ((READ_REG32 (DC3_V_SYNC_TIMING) >> 16) & 0xFFF) + 1;
+ htotal = ((READ_REG32 (DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+ vtotal = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+
+ /* SET DISPLAY FILTER VIDEO REQUEST */
+
+ x += htotal - hsyncend - 2;
+ y += vtotal - vsyncend + 1;
+
+ if (x >= 0x1000 || y >= 0x800)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ WRITE_VID32(DF_VIDEO_REQUEST, (y | (x << 16)));
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_output_color_space
+ *
+ * This routine sets the color space used when combining graphics and video.
+ *--------------------------------------------------------------------------*/
+
+int df_set_output_color_space (int color_space)
+{
+ unsigned long alpha_ctl;
+
+ alpha_ctl = READ_VID32 (DF_VID_ALPHA_CONTROL);
+
+ alpha_ctl &= ~(DF_CSC_GRAPHICS_RGB_TO_YUV | DF_CSC_VIDEO_YUV_TO_RGB |
+ DF_HD_GRAPHICS | DF_YUV_CSC_EN | DF_ALPHA_DRGB);
+
+ /* OUTPUT IS RGB */
+ /* Enable YUV->RGB CSC if necessary and enable alpha output if */
+ /* requested. */
+
+ if (color_space == DF_OUTPUT_RGB || color_space == DF_OUTPUT_ARGB)
+ {
+ if (!(alpha_ctl & DF_VIDEO_INPUT_IS_RGB))
+ alpha_ctl |= DF_CSC_VIDEO_YUV_TO_RGB;
+
+ if (color_space == DF_OUTPUT_ARGB)
+ alpha_ctl |= DF_ALPHA_DRGB;
+ }
+
+ /* OUTPUT IS YUV */
+ /* Enable YUV->YUV CSC if necessary and enable RGB->YUV CSC. */
+
+ else if (color_space == DF_OUTPUT_SDTV || color_space == DF_OUTPUT_HDTV)
+ {
+ alpha_ctl |= DF_CSC_GRAPHICS_RGB_TO_YUV;
+
+ if ( ((alpha_ctl & DF_HD_VIDEO) && color_space == DF_OUTPUT_SDTV) ||
+ (!(alpha_ctl & DF_HD_VIDEO) && color_space == DF_OUTPUT_HDTV))
+ {
+ alpha_ctl |= DF_YUV_CSC_EN;
+ }
+
+ if (color_space == DF_OUTPUT_HDTV)
+ alpha_ctl |= DF_HD_GRAPHICS;
+ }
+ else
+ return CIM_STATUS_INVALIDPARAMS;
+
+ WRITE_VID32 (DF_VID_ALPHA_CONTROL, alpha_ctl);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_set_output_path
+ *
+ * This routine changes the current output path in the display filter.
+ *--------------------------------------------------------------------------*/
+
+int df_set_output_path (int format)
+{
+ unsigned long panel_tim2, panel_pm;
+ unsigned long output = 0;
+ Q_WORD msr_value;
+
+ msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
+ msr_value.low &= ~(DF_SIMULTANEOUS_CRT_FP | DF_CONFIG_OUTPUT_MASK);
+ panel_tim2 = READ_VID32 (DF_VIDEO_PANEL_TIM2);
+ panel_pm = READ_VID32 (DF_POWER_MANAGEMENT);
+
+ if (format == DF_DISPLAY_CRT)
+ {
+ /* SiBZ #4188 */
+ /* When CRT output is selected, the DF drives the DISP_EN signal */
+ /* with the CRT display enable. As a consequence, systems that */
+ /* wire the DISP_EN signal to the TFT backlight control will not */
+ /* be able to set CRT-only output without leaving the backlight */
+ /* enabled. To workaround this issue, we are setting simultaneous */
+ /* TFT/CRT and disabling the TFT logic. The only caveat to this */
+ /* is that some TFT pins are shared with VIP 601 pins. VIP 601 */
+ /* will thus not work when in this pseudo-CRT mode. To address */
+ /* THAT issue, normal CRT mode sets (in cim_vg.c) will set CRT */
+ /* as the DF output format. This will allow VIP 601 on CRT-only */
+ /* systems without a TFT attached. */
+
+ panel_pm &= ~DF_PM_PANEL_ON;
+ panel_tim2 |= DF_PMTIM2_TFT_PASSHTHROUGH;
+ output = DF_OUTPUT_PANEL | DF_SIMULTANEOUS_CRT_FP;
+ }
+ else if (format == DF_DISPLAY_FP || format == DF_DISPLAY_CRT_FP)
+ {
+ panel_pm |= DF_PM_PANEL_ON;
+ panel_tim2 &= ~DF_PMTIM2_TFT_PASSHTHROUGH;
+
+ if (format == DF_DISPLAY_FP)
+ output = DF_OUTPUT_PANEL;
+ else if (format == DF_DISPLAY_CRT_FP)
+ output = DF_OUTPUT_PANEL | DF_SIMULTANEOUS_CRT_FP;
+ }
+ else
+ {
+ switch (format)
+ {
+ case DF_DISPLAY_VOP: output = DF_OUTPUT_VOP; break;
+ case DF_DISPLAY_DRGB: output = DF_OUTPUT_DRGB; break;
+ case DF_DISPLAY_CRT_DRGB: output = DF_OUTPUT_DRGB | DF_SIMULTANEOUS_CRT_FP; break;
+ default:
+ return CIM_STATUS_INVALIDPARAMS;
+ }
+ }
+ msr_value.low |= output;
+ msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
+ WRITE_VID32 (DF_VIDEO_PANEL_TIM2, panel_tim2);
+ WRITE_VID32 (DF_POWER_MANAGEMENT, panel_pm);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_test_video_flip_status
+ *
+ * This routine tests if a new video offset has been latched.
+ *--------------------------------------------------------------------------*/
+
+unsigned long df_test_video_flip_status (void)
+{
+ return (READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VFLIP);
+}
+
+/*---------------------------------------------------------------------------
+ * df_save_state
+ *
+ * This routine saves all persistent DF state information.
+ *---------------------------------------------------------------------------*/
+
+int df_save_state (DF_SAVE_RESTORE *df_state)
+{
+ unsigned long i;
+
+ /* READ ALL DF REGISTERS */
+
+ df_state->vcfg = READ_VID32 (DF_VIDEO_CONFIG);
+ df_state->dcfg = READ_VID32 (DF_DISPLAY_CONFIG);
+ df_state->video_x = READ_VID32 (DF_VIDEO_X_POS);
+ df_state->video_y = READ_VID32 (DF_VIDEO_Y_POS);
+ df_state->video_scaler = READ_VID32 (DF_VIDEO_SCALER);
+ df_state->video_color_key = READ_VID32 (DF_VIDEO_COLOR_KEY);
+ df_state->video_color_mask = READ_VID32 (DF_VIDEO_COLOR_MASK);
+ df_state->sat_limit = READ_VID32 (DF_SATURATION_LIMIT);
+ df_state->vid_misc = READ_VID32 (DF_VID_MISC);
+ df_state->video_yscale = READ_VID32 (DF_VIDEO_YSCALE);
+ df_state->video_xscale = READ_VID32 (DF_VIDEO_XSCALE);
+ df_state->vid_alpha_control = READ_VID32 (DF_VID_ALPHA_CONTROL);
+ df_state->cursor_key = READ_VID32 (DF_CURSOR_COLOR_KEY);
+ df_state->cursor_mask = READ_VID32 (DF_CURSOR_COLOR_MASK);
+ df_state->cursor_color1 = READ_VID32 (DF_CURSOR_COLOR_1);
+ df_state->cursor_color2 = READ_VID32 (DF_CURSOR_COLOR_2);
+ df_state->alpha_xpos1 = READ_VID32 (DF_ALPHA_XPOS_1);
+ df_state->alpha_ypos1 = READ_VID32 (DF_ALPHA_YPOS_1);
+ df_state->alpha_color1 = READ_VID32 (DF_ALPHA_COLOR_1);
+ df_state->alpha_control1 = READ_VID32 (DF_ALPHA_CONTROL_1);
+ df_state->alpha_xpos2 = READ_VID32 (DF_ALPHA_XPOS_2);
+ df_state->alpha_ypos2 = READ_VID32 (DF_ALPHA_YPOS_2);
+ df_state->alpha_color2 = READ_VID32 (DF_ALPHA_COLOR_2);
+ df_state->alpha_control2 = READ_VID32 (DF_ALPHA_CONTROL_2);
+ df_state->alpha_xpos3 = READ_VID32 (DF_ALPHA_XPOS_3);
+ df_state->alpha_ypos3 = READ_VID32 (DF_ALPHA_YPOS_3);
+ df_state->alpha_color3 = READ_VID32 (DF_ALPHA_COLOR_3);
+ df_state->alpha_control3 = READ_VID32 (DF_ALPHA_CONTROL_3);
+ df_state->vid_request = READ_VID32 (DF_VIDEO_REQUEST);
+ df_state->vid_ypos_even = READ_VID32 (DF_VID_YPOS_EVEN);
+ df_state->alpha_ypos_even1 = READ_VID32 (DF_VID_ALPHA_Y_EVEN_1);
+ df_state->alpha_ypos_even2 = READ_VID32 (DF_VID_ALPHA_Y_EVEN_2);
+ df_state->alpha_ypos_even3 = READ_VID32 (DF_VID_ALPHA_Y_EVEN_3);
+ df_state->panel_tim1 = READ_VID32 (DF_VIDEO_PANEL_TIM1);
+ df_state->panel_tim2 = READ_VID32 (DF_VIDEO_PANEL_TIM2);
+ df_state->panel_pm = READ_VID32 (DF_POWER_MANAGEMENT);
+ df_state->panel_dither = READ_VID32 (DF_DITHER_CONTROL);
+
+ /* READ DF PALETTE */
+
+ WRITE_VID32 (DF_PALETTE_ADDRESS, 0);
+ for (i = 0; i < 256; i++)
+ df_state->palette[i] = READ_VID32 (DF_PALETTE_DATA);
+
+ /* READ FILTER COEFFICIENTS */
+
+ for (i = 0; i < 512; i++)
+ df_state->coefficients[i] = READ_VID32 (DF_COEFFICIENT_BASE + (i << 2));
+
+ /* READ ALL DF MSRS */
+
+ msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CAP, &(df_state->msr_cap));
+ msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &(df_state->msr_config));
+ msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_SMI, &(df_state->msr_smi));
+ msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_ERROR, &(df_state->msr_error));
+ msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_PM, &(df_state->msr_pm));
+ msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_DIAG, &(df_state->msr_diag));
+ msr_read64 (MSR_DEVICE_GEODELX_DF, DF_MBD_MSR_DIAG_DF, &(df_state->msr_df_diag));
+ msr_read64 (MSR_DEVICE_GEODELX_DF, DF_MSR_PAD_SEL, &(df_state->msr_pad_sel));
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_restore_state
+ *
+ * This routine restores all persistent DF state information.
+ *---------------------------------------------------------------------------*/
+
+int df_restore_state (DF_SAVE_RESTORE *df_state)
+{
+ unsigned long i;
+
+ /* CLEAR VCFG AND DCFG */
+
+ WRITE_VID32 (DF_VIDEO_CONFIG, 0);
+ WRITE_VID32 (DF_DISPLAY_CONFIG, 0);
+
+ /* RESTORE DF MSRS */
+
+ msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CAP, &(df_state->msr_cap));
+ msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &(df_state->msr_config));
+ msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_SMI, &(df_state->msr_smi));
+ msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_ERROR, &(df_state->msr_error));
+ msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_PM, &(df_state->msr_pm));
+ msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_DIAG, &(df_state->msr_diag));
+ msr_write64 (MSR_DEVICE_GEODELX_DF, DF_MBD_MSR_DIAG_DF, &(df_state->msr_df_diag));
+ msr_write64 (MSR_DEVICE_GEODELX_DF, DF_MSR_PAD_SEL, &(df_state->msr_pad_sel));
+
+ /* RESTORE ALL DF REGISTERS */
+
+ WRITE_VID32 (DF_VIDEO_X_POS, df_state->video_x);
+ WRITE_VID32 (DF_VIDEO_Y_POS, df_state->video_y);
+ WRITE_VID32 (DF_VIDEO_SCALER, df_state->video_scaler);
+ WRITE_VID32 (DF_VIDEO_COLOR_KEY, df_state->video_color_key);
+ WRITE_VID32 (DF_VIDEO_COLOR_MASK, df_state->video_color_mask);
+ WRITE_VID32 (DF_SATURATION_LIMIT, df_state->sat_limit);
+ WRITE_VID32 (DF_VID_MISC, df_state->vid_misc);
+ WRITE_VID32 (DF_VIDEO_YSCALE, df_state->video_yscale);
+ WRITE_VID32 (DF_VIDEO_XSCALE, df_state->video_xscale);
+ WRITE_VID32 (DF_VID_ALPHA_CONTROL, df_state->vid_alpha_control);
+ WRITE_VID32 (DF_CURSOR_COLOR_KEY, df_state->cursor_key);
+ WRITE_VID32 (DF_CURSOR_COLOR_MASK, df_state->cursor_mask);
+ WRITE_VID32 (DF_CURSOR_COLOR_1, df_state->cursor_color1);
+ WRITE_VID32 (DF_CURSOR_COLOR_2, df_state->cursor_color2);
+ WRITE_VID32 (DF_ALPHA_XPOS_1, df_state->alpha_xpos1);
+ WRITE_VID32 (DF_ALPHA_YPOS_1, df_state->alpha_ypos1);
+ WRITE_VID32 (DF_ALPHA_COLOR_1, df_state->alpha_color1);
+ WRITE_VID32 (DF_ALPHA_CONTROL_1, df_state->alpha_control1);
+ WRITE_VID32 (DF_ALPHA_XPOS_2, df_state->alpha_xpos2);
+ WRITE_VID32 (DF_ALPHA_YPOS_2, df_state->alpha_ypos2);
+ WRITE_VID32 (DF_ALPHA_COLOR_2, df_state->alpha_color2);
+ WRITE_VID32 (DF_ALPHA_CONTROL_2, df_state->alpha_control1);
+ WRITE_VID32 (DF_ALPHA_XPOS_3, df_state->alpha_xpos3);
+ WRITE_VID32 (DF_ALPHA_YPOS_3, df_state->alpha_ypos3);
+ WRITE_VID32 (DF_ALPHA_COLOR_3, df_state->alpha_color3);
+ WRITE_VID32 (DF_ALPHA_CONTROL_3, df_state->alpha_control3);
+ WRITE_VID32 (DF_VIDEO_REQUEST, df_state->vid_request);
+ WRITE_VID32 (DF_VID_YPOS_EVEN, df_state->vid_ypos_even);
+ WRITE_VID32 (DF_VID_ALPHA_Y_EVEN_1, df_state->alpha_ypos_even1);
+ WRITE_VID32 (DF_VID_ALPHA_Y_EVEN_2, df_state->alpha_ypos_even2);
+ WRITE_VID32 (DF_VID_ALPHA_Y_EVEN_3, df_state->alpha_ypos_even3);
+ WRITE_VID32 (DF_VIDEO_PANEL_TIM1, df_state->panel_tim1);
+ WRITE_VID32 (DF_VIDEO_PANEL_TIM2, df_state->panel_tim2);
+ WRITE_VID32 (DF_POWER_MANAGEMENT, df_state->panel_pm);
+ WRITE_VID32 (DF_DITHER_CONTROL, df_state->panel_dither);
+
+ /* RESTORE DF PALETTE */
+
+ WRITE_VID32 (DF_PALETTE_ADDRESS, 0);
+ for (i = 0; i < 256; i++)
+ WRITE_VID32 (DF_PALETTE_DATA, df_state->palette[i]);
+
+ /* RESTORE FILTER COEFFICIENTS */
+
+ for (i = 0; i < 512; i++)
+ WRITE_VID32 (DF_COEFFICIENT_BASE + (i << 2), df_state->coefficients[i]);
+
+ /* RESTORE DCFG AND VCFG */
+
+ WRITE_VID32 (DF_DISPLAY_CONFIG, df_state->dcfg);
+ WRITE_VID32 (DF_VIDEO_CONFIG, df_state->vcfg);
+
+ return CIM_STATUS_OK;
+}
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * CIMARRON DF READ ROUTINES
+ * These routines are included for use in diagnostics or when debugging. They
+ * can be optionally excluded from a project.
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+#if CIMARRON_INCLUDE_DF_READ_ROUTINES
+
+/*---------------------------------------------------------------------------
+ * df_read_composite_crc
+ *
+ * This routine reads the CRC of the combination of graphics/video data. This
+ * CRC checks data immediately before the CRT DACs.
+ *---------------------------------------------------------------------------*/
+
+unsigned long df_read_composite_crc (int crc_source)
+{
+ Q_WORD msr_value;
+ unsigned long crc;
+ unsigned long interlaced;
+ unsigned long line, field;
+ unsigned long timeout = 1000;
+
+ if (!(READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_TGEN))
+ return 0xFFFFFFFF;
+
+ /* ENABLE 32-BIT CRCS */
+
+ msr_read64 (MSR_DEVICE_GEODELX_DF, DF_MBD_MSR_DIAG_DF, &msr_value);
+ msr_value.low |= DF_DIAG_32BIT_CRC;
+ msr_write64 (MSR_DEVICE_GEODELX_DF, DF_MBD_MSR_DIAG_DF, &msr_value);
+
+ /* RESET THE CRC */
+
+ WRITE_VID32 (DF_VID_CRC, 0);
+
+ /* WAIT FOR THE RESET TO BE LATCHED */
+
+ while ((READ_VID32 (DF_VID_CRC32) != 0x00000001) && timeout)
+ timeout--;
+
+ /* WAIT FOR THE CORRECT FIELD */
+ /* We use the VG line count and field indicator to determine when */
+ /* to kick off a CRC. */
+
+ if (crc_source & DF_CRC_SOURCE_EVEN) field = 0;
+ else field = DC3_LNCNT_EVEN_FIELD;
+
+ if ((interlaced = (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)))
+ {
+ /* WAIT FOR THE BEGINNING OF THE FIELD (LINE 1-5) */
+ /* Note that we wait for the field to be odd when CRCing the even */
+ /* field and vice versa. This is because the CRC will not begin */
+ /* until the following field. */
+
+ do
+ {
+ line = READ_REG32 (DC3_LINE_CNT_STATUS);
+ } while ((line & DC3_LNCNT_EVEN_FIELD) != field ||
+ ((line & DC3_LNCNT_V_LINE_CNT) >> 16) < 10 ||
+ ((line & DC3_LNCNT_V_LINE_CNT) >> 16) > 15);
+ }
+ else
+ {
+ /* NON-INTERLACED - EVEN FIELD CRCS ARE INVALID */
+
+ if (crc_source & DF_CRC_SOURCE_EVEN)
+ return 0xFFFFFFFF;
+ }
+
+ /* ENABLE THE CRC */
+
+ WRITE_VID32 (DF_VID_CRC, 1);
+
+ /* WAIT FOR THE CRC TO BE COMPLETED */
+
+ while (!(READ_VID32 (DF_VID_CRC) & 4))
+ ;
+
+ crc = READ_VID32 (DF_VID_CRC32);
+
+ return crc;
+}
+
+/*---------------------------------------------------------------------------
+ * df_read_composite_window_crc
+ *
+ * This routine reads the CRC of a rectangular subsection of the combination
+ * of graphics/video data.
+ *---------------------------------------------------------------------------*/
+
+unsigned long df_read_composite_window_crc (unsigned long x, unsigned long y,
+ unsigned long width, unsigned long height, int source)
+{
+ Q_WORD msr_value;
+ unsigned long interlaced;
+ unsigned long line, field;
+ unsigned long crc = 0;
+ unsigned long hsyncend, htotal, hsyncstart;
+ unsigned long vsyncend, vtotal, vsyncstart;
+ unsigned long hblankstart, hactive;
+ unsigned long vblankstart, vactive;
+
+ hsyncend = ((READ_REG32 (DC3_H_SYNC_TIMING) >> 16) & 0xFFF) + 1;
+ htotal = ((READ_REG32 (DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+ hsyncstart = (READ_REG32 (DC3_H_SYNC_TIMING) & 0xFFF) + 1;
+ hactive = (READ_REG32 (DC3_H_ACTIVE_TIMING) & 0xFFF) + 1;
+ hblankstart = (READ_REG32 (DC3_H_BLANK_TIMING) & 0xFFF) + 1;
+ if ((interlaced = (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)) &&
+ !(source & DF_CRC_SOURCE_EVEN))
+ {
+ vsyncend = ((READ_REG32 (DC3_V_SYNC_EVEN) >> 16) & 0xFFF) + 1;
+ vtotal = ((READ_REG32 (DC3_V_ACTIVE_EVEN) >> 16) & 0xFFF) + 1;
+ vsyncstart = (READ_REG32 (DC3_V_SYNC_EVEN) & 0xFFF) + 1;
+ vactive = (READ_REG32 (DC3_V_ACTIVE_EVEN) & 0xFFF) + 1;
+ vblankstart = (READ_REG32 (DC3_V_BLANK_EVEN) & 0xFFF) + 1;
+ }
+ else
+ {
+ vsyncend = ((READ_REG32 (DC3_V_SYNC_TIMING) >> 16) & 0xFFF) + 1;
+ vtotal = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+ vsyncstart = (READ_REG32 (DC3_V_SYNC_TIMING) & 0xFFF) + 1;
+ vactive = (READ_REG32 (DC3_V_ACTIVE_TIMING) & 0xFFF) + 1;
+ vblankstart = (READ_REG32 (DC3_V_BLANK_TIMING) & 0xFFF) + 1;
+ }
+
+ /* TIMINGS MUST BE ACTIVE */
+
+ if (!(READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_TGEN))
+ return 0xFFFFFFFF;
+
+ /* DISABLE GLCP ACTIONS */
+
+ msr_value.low = 0;
+ msr_value.high = 0;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DIAGCTL, &msr_value);
+
+ /* ENABLE HW CLOCK GATING AND SET GLCP CLOCK TO DOT CLOCK */
+
+ msr_value.low = 5;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, MSR_GEODELINK_PM, &msr_value);
+ msr_value.low = 0;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DBGCLKCTL, &msr_value);
+ msr_value.low = 3;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DBGCLKCTL, &msr_value);
+
+ /* USE H4 FUNCTION A FOR HSYNC AND H4 FUNCTION B FOR NOT HSYNC */
+ /* HSYNC is bit 30 for the DF */
+
+ msr_value.high = 0x00000001;
+ msr_value.low = 0xE0000FF0;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_H0CTL + 4, &msr_value);
+
+ /* USE H3 FUNCTION A FOR VSYNC AND H3 FUNCTION B FOR NOT VSYNC */
+ /* VSYNC is bit 54 for VG and bit 29 for DF */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0x001D55AA;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_H0CTL + 3, &msr_value);
+
+ /* M4 (XSTATE = 00 AND VSYNC HIGH) */
+ /* Goto state 01 */
+ /* Note: VSync = H3A */
+
+ msr_value.high = 0x00000001;
+ msr_value.low = 0x000000A0;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETM0CTL + 4, &msr_value);
+
+ /* N0 (XSTATE = 01 AND VSYNC LOW) */
+ /* Goto state 02 */
+ /* Note: VSync low = H3B */
+
+ msr_value.high = 0x00040000;
+ msr_value.low = 0x000000C0;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL, &msr_value);
+
+ /* M5 (XSTATE = 10 AND VSYNC HIGH) */
+ /* Goto state 11 */
+
+ msr_value.high = 0x00000001;
+ msr_value.low = 0x00000120;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETM0CTL + 5, &msr_value);
+
+ /* N1 (XSTATE = 10 and HSYNC LOW) */
+ /* Increment H. Counter */
+ /* Note: HSync = H4 */
+
+ msr_value.high = 0x00080000;
+ msr_value.low = 0x00000120;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL + 1, &msr_value);
+
+ /* M0 (XSTATE = 10 and H. COUNTER == LIMIT) */
+ /* Clear H. Counter and increment V. Counter */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0x00000122;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETM0CTL, &msr_value);
+
+ /* N4 (XSTATE = 10 && CMP0 <= H. COUNTER <= CMP1 && CMP2 <= V. COUNTER <= CMP3) */
+ /* CRC into REGB */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0x10C20120;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL + 4, &msr_value);
+
+ /* COMPARATOR 0 VALUE */
+ /* Value = xstart + (htotal - hsync_end) - 1 */
+ /* The value will be adjusted for a border if necessary */
+
+ msr_value.low = x + htotal - hsyncend - 1;
+ if (READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_DCEN)
+ msr_value.low -= hblankstart - hactive;
+ msr_value.low--;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPVAL0, &msr_value);
+
+ /* COMPARATOR 1 VALUE */
+ /* Value = xstart + (htotal - hsync_end - 1) - 1 + width */
+
+ msr_value.low += width - 1;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPVAL0 + 2, &msr_value);
+
+ /* COMPARATOR 2 VALUE */
+ /* Value = ystart + vtotal - vsyncend */
+
+ msr_value.low = (y + vtotal - vsyncend) << 16;
+ if (READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_DCEN)
+ msr_value.low -= (vblankstart - vactive) << 16;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPVAL0 + 4, &msr_value);
+
+ /* COMPARATOR 3 VALUE */
+ /* Value = ystart + vtotal - vsyncend + height - 1 */
+
+ msr_value.low += (height - 1) << 16;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPVAL0 + 6, &msr_value);
+
+ /* COMPARATOR MASKS */
+ /* Comparators 0 and 1 refer to lower 16 bits of RegB */
+
+ msr_value.low = 0x0000FFFF;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPMASK0, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPMASK0 + 2, &msr_value);
+
+ /* Comparators 2 and 3 refer to upper 16 bits of RegB */
+
+ msr_value.low = 0xFFFF0000;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPMASK0 + 4, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPMASK0 + 6, &msr_value);
+
+ /* SET REGB MASK */
+ /* We set the mask such that all only 24 bits of data are CRCed */
+
+ msr_value.low = 0x00FFFFFF;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REGBMASK, &msr_value);
+
+ /* SET REGA LIMITS */
+ /* Lower counter uses htotal - sync_time - 1. */
+ /* Upper counter is 0xFFFF to prevent rollover. */
+
+ msr_value.low = 0xFFFF0000 | (htotal - (hsyncend - hsyncstart) - 1);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REGAVAL, &msr_value);
+
+ /* ACTIONS */
+
+ /* STATE 00->01 (SET 4M) */
+
+ msr_value.low = 0x000C0000;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 14, &msr_value);
+
+ /* STATE 01->10 (SET 0N) */
+
+ msr_value.low = 0x0000000A;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 15, &msr_value);
+
+ /* STATE 10->11 (SET 5M) */
+
+ msr_value.low = 0x00C00000;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 16, &msr_value);
+
+ /* CLEAR REGA WHEN TRANSITIONING TO STATE 10 */
+ /* Do not clear RegB as the initial value must be 0x00000001 */
+
+ msr_value.low = 0x0000000A;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0, &msr_value);
+
+ /* REGISTER ACTION 1 */
+ /* CRC into RegB if cmp0 <= h.counter <= cmp1 && cmp2 <= v. counter < cmp3 && 7 xstate = 10 8 */
+ /* Increment h.counter if xstate = 10 and HSync is low. */
+
+ msr_value.low = 0x000A00A0;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 1, &msr_value);
+
+ /* REGISTER ACTION 2 */
+ /* Increment V. Counter in REGA */
+
+ msr_value.low = 0x0000000C;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 2, &msr_value);
+
+ /* SET REGB TO 0x00000001 */
+
+ msr_value.low = 0x00000001;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REGB, &msr_value);
+
+ /* SET XSTATE TO 0 */
+
+ msr_value.low = 0x00000000;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_XSTATE, &msr_value);
+
+ /* CLEAR ALL OTHER ACTIONS */
+ /* This prevents side-effects from previous accesses to the GLCP */
+ /* debug logic. */
+
+ msr_value.low = 0x00000000;
+ msr_value.high = 0x00000000;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 3, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 4, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 5, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 6, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 7, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 8, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 9, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 10, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 11, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 12, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 13, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 17, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 18, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 19, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 20, &msr_value);
+
+ /* WAIT FOR THE CORRECT FIELD */
+ /* We use the VG line count and field indicator to determine when */
+ /* to kick off a CRC. */
+
+ if (source & DF_CRC_SOURCE_EVEN) field = 0;
+ else field = DC3_LNCNT_EVEN_FIELD;
+
+ if (interlaced)
+ {
+ /* WAIT FOR THE BEGINNING OF THE FIELD (LINE 1-5) */
+ /* Note that we wait for the field to be odd when CRCing the even */
+ /* field and vice versa. This is because the CRC will not begin */
+ /* until the following field. */
+
+ do
+ {
+ line = READ_REG32 (DC3_LINE_CNT_STATUS);
+ } while ((line & DC3_LNCNT_EVEN_FIELD) != field ||
+ ((line & DC3_LNCNT_V_LINE_CNT) >> 16) < 1 ||
+ ((line & DC3_LNCNT_V_LINE_CNT) >> 16) > 5);
+ }
+ else
+ {
+ /* NON-INTERLACED - EVEN FIELD CRCS ARE INVALID */
+
+ if (source & DF_CRC_SOURCE_EVEN)
+ return 0xFFFFFFFF;
+ }
+
+ /* CONFIGURE DISPLAY FILTER TO LOAD DATA ONTO LOWER 32-BITS */
+
+ msr_value.high = 0;
+ msr_value.low = 0x0000800B;
+ msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_DIAG, &msr_value);
+
+ /* CONFIGURE DIAG CONTROL */
+ /* Set RegA action1 to increment lower 16 bits and clear at limit. (5) */
+ /* Set RegA action2 to increment upper 16 bits. (6) */
+ /* Set RegB action1 to CRC32 (1) */
+ /* Set all comparators to REGA override (0,1 lower mbus, 2,3 upper mbus) */
+ /* Enable all actions */
+
+ msr_value.low = 0x80EA20A0;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DIAGCTL, &msr_value);
+
+ /* DELAY TWO FRAMES */
+
+ while (READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA);
+ while (!(READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA));
+ while (READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA);
+ while (!(READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA));
+ while (READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA);
+
+ /* VERIFY THAT XSTATE = 11 */
+
+ msr_read64 (MSR_DEVICE_GEODELX_GLCP, GLCP_XSTATE, &msr_value);
+ if ((msr_value.low & 3) == 3)
+ {
+ msr_read64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REGB, &msr_value);
+
+ crc = msr_value.low;
+ }
+
+ /* DISABLE DF DIAG BUS OUTPUTS */
+
+ msr_value.low = 0x00000000;
+ msr_value.high = 0x00000000;
+ msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_DIAG, &msr_value);
+
+ /* DISABLE GLCP ACTIONS */
+
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DIAGCTL, &msr_value);
+
+ return crc;
+}
+
+/*---------------------------------------------------------------------------
+ * df_read_panel_crc
+ *
+ * This routine reads the CRC for a frame of data after the panel dithering
+ * logic.
+ *---------------------------------------------------------------------------*/
+
+unsigned long df_read_panel_crc (void)
+{
+ Q_WORD msr_value;
+ unsigned long timeout = 1000;
+
+ if (!(READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_TGEN))
+ return 0xFFFFFFFF;
+
+ /* ENABLE 32-BIT CRCS */
+
+ msr_read64 (MSR_DEVICE_GEODELX_DF, DF_MBD_MSR_DIAG_DF, &msr_value);
+ msr_value.low |= DF_DIAG_32BIT_CRC;
+ msr_write64 (MSR_DEVICE_GEODELX_DF, DF_MBD_MSR_DIAG_DF, &msr_value);
+
+ /* RESET CRC */
+
+ WRITE_VID32 (DF_PANEL_CRC, 0);
+
+ /* WAIT FOR THE RESET TO BE LATCHED */
+
+ while ((READ_VID32 (DF_PANEL_CRC32) != 0x00000001) && timeout)
+ timeout--;
+
+ WRITE_VID32 (DF_PANEL_CRC, 1);
+
+ /* WAIT FOR THE CRC TO BE COMPLETED */
+
+ while (!(READ_VID32 (DF_PANEL_CRC) & 4))
+ ;
+
+ return READ_VID32 (DF_PANEL_CRC32);
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_video_enable
+ *
+ * This routine reads the enable status of the video overlay.
+ *---------------------------------------------------------------------------*/
+
+int df_get_video_enable (int *enable, unsigned long *flags)
+{
+ *enable = 0;
+ *flags = 0;
+ if (READ_VID32 (DF_VIDEO_CONFIG) & DF_VCFG_VID_EN)
+ {
+ *enable = 1;
+
+ /* CHECK FOR COLOR KEY DISABLED */
+ /* Color keying can be completely disabled when video is enabled to */
+ /* allow unhindered per-pixel alpha blending. As color keying is */
+ /* always disabled when video is disabled, it is only possible to */
+ /* test for this condition when video is enabled. */
+
+ if (!(READ_VID32 (DF_DISPLAY_CONFIG) & DF_DCFG_VG_CK) &&
+ !(READ_REG32 (DC3_COLOR_KEY) & DC3_CLR_KEY_ENABLE))
+ {
+ *flags = DF_ENABLEFLAG_NOCOLORKEY;
+ }
+ }
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_video_source_configuration
+ *
+ * This routine reads the current configuration of the source buffers for the
+ * video overlay.
+ *---------------------------------------------------------------------------*/
+
+int df_get_video_source_configuration (DF_VIDEO_SOURCE_PARAMS *video_source_odd,
+ DF_VIDEO_SOURCE_PARAMS *video_source_even)
+{
+ unsigned long format, temp;
+ unsigned long size;
+
+ /* READ VIDEO FORMAT */
+
+ temp = READ_VID32 (DF_VIDEO_CONFIG);
+
+ format = (temp >> 2) & 3;
+ if (temp & DF_VCFG_4_2_0_MODE)
+ format |= 4;
+ else if (READ_VID32 (DF_VID_ALPHA_CONTROL) & DF_VIDEO_INPUT_IS_RGB)
+ format |= 8;
+ video_source_odd->video_format = format;
+
+ /* CHECK IF SOURCE IS HD VIDEO */
+
+ if (READ_VID32 (DF_VID_ALPHA_CONTROL) & DF_HD_VIDEO)
+ video_source_odd->flags = DF_SOURCEFLAG_HDTVSOURCE;
+ else
+ video_source_odd->flags = 0;
+
+ /* READ SCALING ALGORITHM */
+
+ if (READ_VID32 (DF_VID_MISC) & DF_USER_IMPLICIT_SCALING)
+ video_source_odd->flags |= DF_SOURCEFLAG_IMPLICITSCALING;
+
+ /* READ VIDEO PITCH */
+
+ temp = READ_REG32 (DC3_VID_YUV_PITCH);
+ video_source_odd->y_pitch = (temp & 0xFFFF) << 3;
+ video_source_odd->uv_pitch = (temp >> 16) << 3;
+
+ /* READ VIDEO SIZE */
+
+ temp = READ_VID32 (DF_VIDEO_CONFIG);
+ size = (temp >> 8) & 0xFF;
+ if (temp & DF_VCFG_LINE_SIZE_BIT8) size |= 0x100;
+ if (temp & DF_VCFG_LINE_SIZE_BIT9) size |= 0x200;
+
+ video_source_odd->width = size << 1;
+ video_source_odd->height = READ_VID32 (DF_VIDEO_SCALER) & 0x7FF;
+
+ /* READ VIDEO OFFSETS */
+
+ video_source_odd->y_offset = READ_REG32 (DC3_VID_Y_ST_OFFSET) & 0xFFFFFFF;
+ video_source_odd->u_offset = READ_REG32 (DC3_VID_U_ST_OFFSET) & 0xFFFFFFF;
+ video_source_odd->v_offset = READ_REG32 (DC3_VID_V_ST_OFFSET) & 0xFFFFFFF;
+
+ if (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)
+ {
+ video_source_even->y_offset = READ_REG32 (DC3_VID_EVEN_Y_ST_OFFSET) & 0xFFFFFFF;
+ video_source_even->u_offset = READ_REG32 (DC3_VID_EVEN_U_ST_OFFSET) & 0xFFFFFFF;
+ video_source_even->v_offset = READ_REG32 (DC3_VID_EVEN_V_ST_OFFSET) & 0xFFFFFFF;
+ }
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_video_position
+ *
+ * This routine reads the current position of the video overlay.
+ *---------------------------------------------------------------------------*/
+
+int df_get_video_position (DF_VIDEO_POSITION *video_window)
+{
+ unsigned long xreg, yreg, dst_clip, clip;
+ unsigned long height;
+ unsigned long xend, yend;
+ unsigned long hsyncend, htotal;
+ unsigned long vsyncend, vtotal;
+ unsigned long hadjust, vadjust;
+ unsigned long misc, gfxscale;
+ unsigned long temp;
+ long xstart, ystart;
+
+ video_window->flags = DF_POSFLAG_DIRECTCLIP;
+
+ hsyncend = ((READ_REG32 (DC3_H_SYNC_TIMING) >> 16) & 0xFFF) + 1;
+ htotal = ((READ_REG32 (DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+
+ /* ODD FIELD START COUNTS FROM THE EVEN FIELD TIMINGS */
+ /* We assume that the even field y position is always programmed */
+ /* to be just after the odd field. */
+
+ if (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)
+ {
+ vsyncend = ((READ_REG32 (DC3_V_SYNC_EVEN) >> 16) & 0xFFF) + 1;
+ vtotal = ((READ_REG32 (DC3_V_ACTIVE_EVEN) >> 16) & 0xFFF) + 1;
+ }
+ else
+ {
+ vsyncend = ((READ_REG32 (DC3_V_SYNC_TIMING) >> 16) & 0xFFF) + 1;
+ vtotal = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+ }
+
+ hadjust = htotal - hsyncend - 14;
+ vadjust = vtotal - vsyncend + 1;
+
+ xreg = READ_VID32 (DF_VIDEO_X_POS);
+ yreg = READ_VID32 (DF_VIDEO_Y_POS);
+
+ xstart = (xreg & 0xFFF) - hadjust;
+ ystart = (yreg & 0x7FF) - vadjust;
+ xend = ((xreg >> 16) & 0xFFF) - hadjust;
+ yend = ((yreg >> 16) & 0x7FF) - vadjust;
+
+ height = yend - ystart;
+
+ if (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)
+ {
+ /* Y COORDINATE IS ACTUALLY 2X THE ODD FIELD START */
+
+ ystart <<= 1;
+
+ /* CALCULATE THE EXACT VIDEO HEIGHT */
+ /* The height of the video window is the sum of the */
+ /* odd and even field heights. */
+
+ yreg = READ_VID32 (DF_VID_YPOS_EVEN);
+ height += ((yreg >> 16) & 0x7FF) - (yreg & 0x7FF);
+ }
+
+ clip = ((READ_VID32 (DF_VIDEO_CONFIG) >> 16) & 0x1FF) << 2;
+
+ /* ADJUST FOR CLIPPING VALUES THAT ARE NOT FOUR-PIXEL ALIGNED */
+
+ dst_clip = 0;
+ if (xstart < 0)
+ {
+ dst_clip += -xstart;
+ xstart = 0;
+ }
+
+ /* REVERSE THE GRAPHICS SCALE */
+
+ misc = READ_VID32 (DF_VID_MISC);
+ if (misc & DF_USER_IMPLICIT_SCALING)
+ {
+ gfxscale = READ_REG32 (DC3_GFX_SCALE);
+
+ if (gfxscale != 0x40004000)
+ {
+ temp = ystart + height;
+ temp = (temp * (gfxscale >> 16)) / 0x4000;
+
+ xstart = (xstart * (gfxscale & 0xFFFF)) / 0x4000;
+ xend = (xend * (gfxscale & 0xFFFF)) / 0x4000;
+ ystart = (ystart * (gfxscale >> 16)) / 0x4000;
+ height = temp - ystart;
+ }
+ }
+
+ video_window->left_clip = clip;
+ video_window->dst_clip = dst_clip;
+ video_window->x = xstart;
+ video_window->y = ystart;
+ video_window->width = xend - xstart;
+ video_window->height = height;
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_video_scale
+ *
+ * This routine reads the current scale values for video scaling.
+ *---------------------------------------------------------------------------*/
+
+int df_get_video_scale (unsigned long *x_scale, unsigned long *y_scale)
+{
+ *x_scale = READ_VID32 (DF_VIDEO_XSCALE) & 0x000FFFFF;
+ *y_scale = READ_VID32 (DF_VIDEO_YSCALE) & 0x000FFFFF;
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_video_filter_coefficients
+ *
+ * This routine reads the coefficients for the video scaler/filter.
+ *---------------------------------------------------------------------------*/
+
+int df_get_video_filter_coefficients (long taps[][4], int *phase256)
+{
+ unsigned long i, temp;
+ long coeff;
+
+ if (READ_VID32 (DF_VIDEO_SCALER) & DF_SCALE_128_PHASES)
+ *phase256 = 0;
+ else
+ *phase256 = 1;
+
+ for (i = 0; i < 256; i++)
+ {
+ temp = READ_VID32 (DF_COEFFICIENT_BASE + (i << 3));
+
+ /* TAP 0 */
+
+ coeff = temp & 0x7FFF;
+ if (temp & 0x8000) coeff = -coeff;
+ taps[i][0] = coeff;
+
+ /* TAP 1 */
+
+ temp >>= 16;
+ coeff = temp & 0x7FFF;
+ if (temp & 0x8000) coeff = -coeff;
+ taps[i][1] = coeff;
+
+ temp = READ_VID32 (DF_COEFFICIENT_BASE + (i << 3) + 4);
+
+ /* TAP 2 */
+
+ coeff = temp & 0x7FFF;
+ if (temp & 0x8000) coeff = -coeff;
+ taps[i][2] = coeff;
+
+ /* TAP 3 */
+
+ temp >>= 16;
+ coeff = temp & 0x7FFF;
+ if (temp & 0x8000) coeff = -coeff;
+ taps[i][3] = coeff;
+ }
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_video_color_key
+ *
+ * This routine reads the current settings for hardware color/chroma keying.
+ *---------------------------------------------------------------------------*/
+
+int df_get_video_color_key (unsigned long *key, unsigned long *mask, int *graphics)
+{
+ unsigned long chroma = READ_VID32 (DF_DISPLAY_CONFIG) & DF_DCFG_VG_CK;
+
+ if (chroma)
+ {
+ /* CHROMA KEY - READ KEY AND MASK FROM DF */
+
+ *graphics = 0;
+ *key = READ_VID32 (DF_VIDEO_COLOR_KEY) & 0xFFFFFF;
+ *mask = READ_VID32 (DF_VIDEO_COLOR_MASK) & 0xFFFFFF;
+ }
+ else
+ {
+ *graphics = 1;
+
+ *key = READ_REG32 (DC3_COLOR_KEY) & 0xFFFFFF;
+ *mask = READ_REG32 (DC3_COLOR_MASK) & 0xFFFFFF;
+ }
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_video_palette_entry
+ *
+ * This routine returns a single palette entry.
+ *---------------------------------------------------------------------------*/
+
+int df_get_video_palette_entry(unsigned long index, unsigned long *palette)
+{
+ if (index > 0xFF)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ /* READ A SINGLE ENTRY */
+
+ WRITE_VID32 (DF_PALETTE_ADDRESS, index);
+ *palette = READ_VID32 (DF_PALETTE_DATA);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_video_palette
+ *
+ * This routine returns the entire video palette.
+ *---------------------------------------------------------------------------*/
+
+int df_get_video_palette (unsigned long *palette)
+{
+ unsigned long i;
+
+ WRITE_VID32 (DF_PALETTE_ADDRESS, 0);
+ for (i = 0; i < 256; i++)
+ palette[i] = READ_VID32 (DF_PALETTE_DATA);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_video_cursor_color_key
+ *
+ * This routine returns the current configuration for the hardware video cursor
+ * color key.
+ *---------------------------------------------------------------------------*/
+
+int df_get_video_cursor_color_key (DF_VIDEO_CURSOR_PARAMS *cursor_color_key)
+{
+ unsigned long key;
+
+ cursor_color_key->flags = 0;
+ cursor_color_key->color1 = READ_VID32 (DF_CURSOR_COLOR_1) & 0xFFFFFF;
+ cursor_color_key->color2 = READ_VID32 (DF_CURSOR_COLOR_2) & 0xFFFFFF;
+ cursor_color_key->mask = READ_VID32 (DF_CURSOR_COLOR_MASK) & 0xFFFFFF;
+
+ key = READ_VID32 (DF_CURSOR_COLOR_KEY);
+ cursor_color_key->key = key & 0xFFFFFF;
+ cursor_color_key->select_color2 = (key >> 24) & 0x1F;
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_video_cursor_color_key_enable
+ *
+ * This routine returns the current enable status of the hardware video cursor
+ * color key.
+ *---------------------------------------------------------------------------*/
+
+int df_get_video_cursor_color_key_enable (void)
+{
+ if (READ_VID32 (DF_CURSOR_COLOR_KEY) & DF_CURSOR_COLOR_KEY_ENABLE)
+ return 1;
+
+ return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_alpha_window_configuration
+ *
+ * This routine reads the current configuration for one of the three hardware
+ * alpha regions.
+ *---------------------------------------------------------------------------*/
+
+int df_get_alpha_window_configuration (int window, DF_ALPHA_REGION_PARAMS *alpha_data)
+{
+ unsigned long pos, color, alpha_ctl;
+ unsigned long hsyncend, htotal;
+ unsigned long vsyncend, vtotal;
+ unsigned long hadjust, vadjust;
+ unsigned long xreg, yreg;
+ unsigned long misc, gfxscale;
+ unsigned long temp;
+ char delta;
+
+ if (window > 2)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ hsyncend = ((READ_REG32 (DC3_H_SYNC_TIMING) >> 16) & 0xFFF) + 1;
+ htotal = ((READ_REG32 (DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+ if (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)
+ {
+ vtotal = ((READ_REG32 (DC3_V_ACTIVE_EVEN) >> 16) & 0xFFF) + 1;
+ vsyncend = ((READ_REG32 (DC3_V_SYNC_EVEN) >> 16) & 0xFFF) + 1;
+ }
+ else
+ {
+ vtotal = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+ vsyncend = ((READ_REG32 (DC3_V_SYNC_TIMING) >> 16) & 0xFFF) + 1;
+ }
+
+ /* GET PRIORITY */
+
+ pos = 16 + (window << 1);
+ alpha_data->priority = (READ_VID32 (DF_VID_ALPHA_CONTROL) >> pos) & 3L;
+
+ /* GET ALPHA WINDOW */
+
+ hadjust = htotal - hsyncend - 2;
+ vadjust = vtotal - vsyncend + 1;
+
+ xreg = READ_VID32 (DF_ALPHA_XPOS_1 + (window << 5));
+ yreg = READ_VID32 (DF_ALPHA_YPOS_1 + (window << 5));
+ alpha_data->width = ((xreg >> 16) & 0xFFF) - (xreg & 0xFFF);
+ alpha_data->height = ((yreg >> 16) & 0x7FF) - (yreg & 0x7FF);
+ alpha_data->x = (xreg & 0xFFF) - hadjust;
+ alpha_data->y = (yreg & 0x7FF) - vadjust;
+
+ /* REVERSE THE GRAPHICS SCALE */
+
+ misc = READ_VID32 (DF_VID_MISC);
+ if (misc & DF_USER_IMPLICIT_SCALING)
+ {
+ gfxscale = READ_REG32 (DC3_GFX_SCALE);
+ if (gfxscale != 0x40004000)
+ {
+ temp = alpha_data->y + alpha_data->height;
+ temp = (temp * (gfxscale >> 16)) / 0x4000;
+
+ alpha_data->x = (alpha_data->x * (gfxscale & 0xFFFF)) / 0x4000;
+ alpha_data->width = (alpha_data->width * (gfxscale & 0xFFFF)) / 0x4000;
+ alpha_data->y = (alpha_data->y * (gfxscale >> 16)) / 0x4000;
+ alpha_data->height = temp - alpha_data->y;
+ }
+ }
+
+ if (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)
+ {
+ /* Y COORDINATE IS ACTUALLY 2X THE ODD FIELD START */
+
+ alpha_data->y <<= 1;
+
+ /* CALCULATE THE EXACT VIDEO HEIGHT */
+ /* The height of the video window is the sum of the */
+ /* odd and even field heights. */
+
+ yreg = READ_VID32 (DF_VID_ALPHA_Y_EVEN_1 + (window << 3));
+ alpha_data->height += ((yreg >> 16) & 0x7FF) - (yreg & 0x7FF);
+ }
+
+ /* GET COLOR REGISTER */
+
+ color = READ_VID32 (DF_ALPHA_COLOR_1 + (window << 5));
+ alpha_data->color = color & 0xFFFFFF;
+ if (color & DF_ALPHA_COLOR_ENABLE)
+ alpha_data->flags = DF_ALPHAFLAG_COLORENABLED;
+ else
+ alpha_data->flags = 0;
+
+ /* GET ALPHA VALUE, DELTA AND PER PIXEL */
+
+ alpha_ctl = READ_VID32 (DF_ALPHA_CONTROL_1 + (window << 5));
+ alpha_data->alpha_value = alpha_ctl & 0xFF;
+ if (alpha_ctl & DF_ACTRL_PERPIXEL_EN)
+ alpha_data->flags |= DF_ALPHAFLAG_PERPIXELENABLED;
+
+ delta = (char)((alpha_ctl >> 8) & 0xFF);
+ alpha_data->delta = (long)delta;
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_alpha_window_enable
+ *
+ * This routine reads the current enable status of one of the three hardware
+ * alpha regions.
+ *---------------------------------------------------------------------------*/
+
+int df_get_alpha_window_enable (int window)
+{
+ if (window > 2)
+ return 0;
+
+ if (READ_VID32 (DF_ALPHA_CONTROL_1 + (window << 5)) & DF_ACTRL_WIN_ENABLE)
+ return 1;
+
+ return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_video_request
+ *
+ * This routine reads the horizontal (pixel) and vertical (line) video request
+ * values.
+ *--------------------------------------------------------------------------*/
+
+int df_get_video_request (unsigned long *x, unsigned long *y)
+{
+ unsigned long request;
+ unsigned long hsyncend, htotal;
+ unsigned long vsyncend, vtotal;
+
+ hsyncend = ((READ_REG32 (DC3_H_SYNC_TIMING) >> 16) & 0xFFF) + 1;
+ vsyncend = ((READ_REG32 (DC3_V_SYNC_TIMING) >> 16) & 0xFFF) + 1;
+ htotal = ((READ_REG32 (DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+ vtotal = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+
+ request = READ_VID32 (DF_VIDEO_REQUEST);
+ *x = ((request >> 16) & 0xFFF) - (htotal - hsyncend - 2);
+ *y = (request & 0x7FF) - (vtotal - vsyncend + 1);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * df_get_output_color_space
+ *
+ * This routine sets the color space used when combining graphics and video.
+ *--------------------------------------------------------------------------*/
+
+int df_get_output_color_space (int *color_space)
+{
+ unsigned long alpha_ctl;
+
+ alpha_ctl = READ_VID32 (DF_VID_ALPHA_CONTROL);
+
+ if ((alpha_ctl & DF_CSC_VIDEO_YUV_TO_RGB) ||
+ !(alpha_ctl & DF_CSC_GRAPHICS_RGB_TO_YUV))
+ {
+ if (alpha_ctl & DF_ALPHA_DRGB)
+ *color_space = DF_OUTPUT_ARGB;
+ else
+ *color_space = DF_OUTPUT_RGB;
+ }
+ else
+ {
+ *color_space = DF_OUTPUT_SDTV;
+
+ if (alpha_ctl & DF_HD_GRAPHICS)
+ *color_space = DF_OUTPUT_HDTV;
+ }
+
+ return CIM_STATUS_OK;
+}
+
+#endif
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_filter.c xf86-video-nsc-2.8.1/src/cim/cim_filter.c
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_filter.c 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_filter.c 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,533 @@
+ /*
+ *
+ * Copyright (C) 2005 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *
+ *
+ *
+ *
+ *
+ * Cimarron default video coefficients.
+ *
+ *
+ */
+
+long CimarronVideoFilter256[][2] =
+{
+ { 0x10000000, 0x00000000 }, /* 0, 4096, 0, 0 */
+ { 0x10008008, 0x00000008 }, /* -8, 4096, 8, 0 */
+ { 0x10008010, 0x80010011 }, /* -16, 4096, 17, -1 */
+ { 0x10008019, 0x8001001A }, /* -25, 4096, 26, -1 */
+ { 0x10008021, 0x80020023 }, /* -33, 4096, 35, -2 */
+ { 0x0FFF8029, 0x8003002D }, /* -41, 4095, 45, -3 */
+ { 0x0FFE8031, 0x80030036 }, /* -49, 4094, 54, -3 */
+ { 0x0FFC8038, 0x80040040 }, /* -56, 4092, 64, -4 */
+ { 0x0FFB8040, 0x8005004A }, /* -64, 4091, 74, -5 */
+ { 0x0FF88047, 0x80050054 }, /* -71, 4088, 84, -5 */
+ { 0x0FF6804E, 0x8006005E }, /* -78, 4086, 94, -6 */
+ { 0x0FF48055, 0x80070068 }, /* -85, 4084, 104, -7 */
+ { 0x0FF0805C, 0x80070073 }, /* -92, 4080, 115, -7 */
+ { 0x0FEE8063, 0x8008007D }, /* -99, 4078, 125, -8 */
+ { 0x0FEA8069, 0x80090088 }, /* -105, 4074, 136, -9 */
+ { 0x0FE78070, 0x800A0093 }, /* -112, 4071, 147, -10 */
+ { 0x0FE28076, 0x800A009E }, /* -118, 4066, 158, -10 */
+ { 0x0FDD807C, 0x800B00AA }, /* -124, 4061, 170, -11 */
+ { 0x0FD98082, 0x800C00B5 }, /* -130, 4057, 181, -12 */
+ { 0x0FD48088, 0x800D00C1 }, /* -136, 4052, 193, -13 */
+ { 0x0FCE808E, 0x800D00CD }, /* -142, 4046, 205, -13 */
+ { 0x0FC88093, 0x800E00D9 }, /* -147, 4040, 217, -14 */
+ { 0x0FC38099, 0x800F00E5 }, /* -153, 4035, 229, -15 */
+ { 0x0FBD809E, 0x801000F1 }, /* -158, 4029, 241, -16 */
+ { 0x0FB680A3, 0x801000FD }, /* -163, 4022, 253, -16 */
+ { 0x0FAF80A8, 0x8011010A }, /* -168, 4015, 266, -17 */
+ { 0x0FA880AD, 0x80120117 }, /* -173, 4008, 279, -18 */
+ { 0x0FA180B2, 0x80130124 }, /* -178, 4001, 292, -19 */
+ { 0x0F9980B6, 0x80140131 }, /* -182, 3993, 305, -20 */
+ { 0x0F9280BB, 0x8015013E }, /* -187, 3986, 318, -21 */
+ { 0x0F8880BF, 0x8015014C }, /* -191, 3976, 332, -21 */
+ { 0x0F8080C3, 0x80160159 }, /* -195, 3968, 345, -22 */
+ { 0x0F7880C8, 0x80170167 }, /* -200, 3960, 359, -23 */
+ { 0x0F6E80CB, 0x80180175 }, /* -203, 3950, 373, -24 */
+ { 0x0F6580CF, 0x80190183 }, /* -207, 3941, 387, -25 */
+ { 0x0F5C80D3, 0x801A0191 }, /* -211, 3932, 401, -26 */
+ { 0x0F5280D7, 0x801B01A0 }, /* -215, 3922, 416, -27 */
+ { 0x0F4880DA, 0x801C01AE }, /* -218, 3912, 430, -28 */
+ { 0x0F3D80DD, 0x801D01BD }, /* -221, 3901, 445, -29 */
+ { 0x0F3280E0, 0x801E01CC }, /* -224, 3890, 460, -30 */
+ { 0x0F2880E4, 0x801F01DB }, /* -228, 3880, 475, -31 */
+ { 0x0F1C80E6, 0x802001EA }, /* -230, 3868, 490, -32 */
+ { 0x0F1180E9, 0x802101F9 }, /* -233, 3857, 505, -33 */
+ { 0x0F0480EB, 0x80210208 }, /* -235, 3844, 520, -33 */
+ { 0x0EFA80EF, 0x80230218 }, /* -239, 3834, 536, -35 */
+ { 0x0EEC80F0, 0x80230227 }, /* -240, 3820, 551, -35 */
+ { 0x0EE080F3, 0x80240237 }, /* -243, 3808, 567, -36 */
+ { 0x0ED380F5, 0x80250247 }, /* -245, 3795, 583, -37 */
+ { 0x0EC780F7, 0x80270257 }, /* -247, 3783, 599, -39 */
+ { 0x0EB980F9, 0x80280268 }, /* -249, 3769, 616, -40 */
+ { 0x0EAC80FB, 0x80290278 }, /* -251, 3756, 632, -41 */
+ { 0x0E9E80FD, 0x802A0289 }, /* -253, 3742, 649, -42 */
+ { 0x0E9080FE, 0x802B0299 }, /* -254, 3728, 665, -43 */
+ { 0x0E838100, 0x802D02AA }, /* -256, 3715, 682, -45 */
+ { 0x0E758102, 0x802E02BB }, /* -258, 3701, 699, -46 */
+ { 0x0E668103, 0x802F02CC }, /* -259, 3686, 716, -47 */
+ { 0x0E568104, 0x803002DE }, /* -260, 3670, 734, -48 */
+ { 0x0E498106, 0x803202EF }, /* -262, 3657, 751, -50 */
+ { 0x0E398107, 0x80330301 }, /* -263, 3641, 769, -51 */
+ { 0x0E298108, 0x80340313 }, /* -264, 3625, 787, -52 */
+ { 0x0E1A8109, 0x80360325 }, /* -265, 3610, 805, -54 */
+ { 0x0E0B810A, 0x80370336 }, /* -266, 3595, 822, -55 */
+ { 0x0DFA810A, 0x80380348 }, /* -266, 3578, 840, -56 */
+ { 0x0DEA810B, 0x803A035B }, /* -267, 3562, 859, -58 */
+ { 0x0DDA810C, 0x803B036D }, /* -268, 3546, 877, -59 */
+ { 0x0DCA810C, 0x803D037F }, /* -268, 3530, 895, -61 */
+ { 0x0DB7810B, 0x803E0392 }, /* -267, 3511, 914, -62 */
+ { 0x0DA7810C, 0x804003A5 }, /* -268, 3495, 933, -64 */
+ { 0x0D95810C, 0x804103B8 }, /* -268, 3477, 952, -65 */
+ { 0x0D85810C, 0x804303CA }, /* -268, 3461, 970, -67 */
+ { 0x0D73810C, 0x804403DD }, /* -268, 3443, 989, -68 */
+ { 0x0D61810C, 0x804603F1 }, /* -268, 3425, 1009, -70 */
+ { 0x0D50810C, 0x80480404 }, /* -268, 3408, 1028, -72 */
+ { 0x0D3E810C, 0x80490417 }, /* -268, 3390, 1047, -73 */
+ { 0x0D2C810C, 0x804B042B }, /* -268, 3372, 1067, -75 */
+ { 0x0D1B810C, 0x804D043E }, /* -268, 3355, 1086, -77 */
+ { 0x0D07810B, 0x804E0452 }, /* -267, 3335, 1106, -78 */
+ { 0x0CF5810B, 0x80500466 }, /* -267, 3317, 1126, -80 */
+ { 0x0CE2810A, 0x8052047A }, /* -266, 3298, 1146, -82 */
+ { 0x0CCF810A, 0x8053048E }, /* -266, 3279, 1166, -83 */
+ { 0x0CBC8109, 0x805504A2 }, /* -265, 3260, 1186, -85 */
+ { 0x0CA98108, 0x805704B6 }, /* -264, 3241, 1206, -87 */
+ { 0x0C968108, 0x805904CB }, /* -264, 3222, 1227, -89 */
+ { 0x0C838107, 0x805B04DF }, /* -263, 3203, 1247, -91 */
+ { 0x0C6F8106, 0x805C04F3 }, /* -262, 3183, 1267, -92 */
+ { 0x0C5B8105, 0x805E0508 }, /* -261, 3163, 1288, -94 */
+ { 0x0C478104, 0x8060051D }, /* -260, 3143, 1309, -96 */
+ { 0x0C348103, 0x80620531 }, /* -259, 3124, 1329, -98 */
+ { 0x0C1F8102, 0x80640547 }, /* -258, 3103, 1351, -100 */
+ { 0x0C0C8101, 0x8066055B }, /* -257, 3084, 1371, -102 */
+ { 0x0BF88100, 0x80680570 }, /* -256, 3064, 1392, -104 */
+ { 0x0BE380FE, 0x806A0585 }, /* -254, 3043, 1413, -106 */
+ { 0x0BCF80FD, 0x806C059A }, /* -253, 3023, 1434, -108 */
+ { 0x0BBA80FC, 0x806E05B0 }, /* -252, 3002, 1456, -110 */
+ { 0x0BA480F9, 0x807005C5 }, /* -249, 2980, 1477, -112 */
+ { 0x0B8F80F8, 0x807205DB }, /* -248, 2959, 1499, -114 */
+ { 0x0B7A80F6, 0x807405F0 }, /* -246, 2938, 1520, -116 */
+ { 0x0B6580F5, 0x80760606 }, /* -245, 2917, 1542, -118 */
+ { 0x0B4F80F3, 0x8077061B }, /* -243, 2895, 1563, -119 */
+ { 0x0B3A80F2, 0x80790631 }, /* -242, 2874, 1585, -121 */
+ { 0x0B2480F0, 0x807B0647 }, /* -240, 2852, 1607, -123 */
+ { 0x0B0F80EE, 0x807D065C }, /* -238, 2831, 1628, -125 */
+ { 0x0AF980ED, 0x807F0673 }, /* -237, 2809, 1651, -127 */
+ { 0x0AE480EB, 0x80810688 }, /* -235, 2788, 1672, -129 */
+ { 0x0ACE80E9, 0x8084069F }, /* -233, 2766, 1695, -132 */
+ { 0x0AB980E7, 0x808606B4 }, /* -231, 2745, 1716, -134 */
+ { 0x0AA380E6, 0x808806CB }, /* -230, 2723, 1739, -136 */
+ { 0x0A8D80E4, 0x808A06E1 }, /* -228, 2701, 1761, -138 */
+ { 0x0A7780E2, 0x808C06F7 }, /* -226, 2679, 1783, -140 */
+ { 0x0A6180E0, 0x808E070D }, /* -224, 2657, 1805, -142 */
+ { 0x0A4B80DE, 0x80910724 }, /* -222, 2635, 1828, -145 */
+ { 0x0A3580DC, 0x8093073A }, /* -220, 2613, 1850, -147 */
+ { 0x0A1F80DA, 0x80950750 }, /* -218, 2591, 1872, -149 */
+ { 0x0A0880D8, 0x80970767 }, /* -216, 2568, 1895, -151 */
+ { 0x09F280D6, 0x8099077D }, /* -214, 2546, 1917, -153 */
+ { 0x09DD80D4, 0x809C0793 }, /* -212, 2525, 1939, -156 */
+ { 0x09C680D2, 0x809E07AA }, /* -210, 2502, 1962, -158 */
+ { 0x09B080D0, 0x80A007C0 }, /* -208, 2480, 1984, -160 */
+ { 0x099980CE, 0x80A207D7 }, /* -206, 2457, 2007, -162 */
+ { 0x098380CB, 0x80A507ED }, /* -203, 2435, 2029, -165 */
+ { 0x096C80C9, 0x80A70804 }, /* -201, 2412, 2052, -167 */
+ { 0x095680C7, 0x80A9081A }, /* -199, 2390, 2074, -169 */
+ { 0x094080C5, 0x80AB0830 }, /* -197, 2368, 2096, -171 */
+ { 0x092980C3, 0x80AE0848 }, /* -195, 2345, 2120, -174 */
+ { 0x091380C1, 0x80B0085E }, /* -193, 2323, 2142, -176 */
+ { 0x08FC80BE, 0x80B20874 }, /* -190, 2300, 2164, -178 */
+ { 0x08E580BC, 0x80B4088B }, /* -188, 2277, 2187, -180 */
+ { 0x08D080BB, 0x80B708A2 }, /* -187, 2256, 2210, -183 */
+ { 0x08B980B9, 0x80B908B9 }, /* -185, 2233, 2233, -185 */
+ { 0x08A380B7, 0x80BB08CF }, /* -183, 2211, 2255, -187 */
+ { 0x088B80B4, 0x80BC08E5 }, /* -180, 2187, 2277, -188 */
+ { 0x087480B2, 0x80BE08FC }, /* -178, 2164, 2300, -190 */
+ { 0x085E80B0, 0x80C10913 }, /* -176, 2142, 2323, -193 */
+ { 0x084880AE, 0x80C30929 }, /* -174, 2120, 2345, -195 */
+ { 0x083080AB, 0x80C50940 }, /* -171, 2096, 2368, -197 */
+ { 0x081A80A9, 0x80C70956 }, /* -169, 2074, 2390, -199 */
+ { 0x080480A7, 0x80C9096C }, /* -167, 2052, 2412, -201 */
+ { 0x07ED80A5, 0x80CB0983 }, /* -165, 2029, 2435, -203 */
+ { 0x07D780A2, 0x80CE0999 }, /* -162, 2007, 2457, -206 */
+ { 0x07C080A0, 0x80D009B0 }, /* -160, 1984, 2480, -208 */
+ { 0x07AA809E, 0x80D209C6 }, /* -158, 1962, 2502, -210 */
+ { 0x0793809C, 0x80D409DD }, /* -156, 1939, 2525, -212 */
+ { 0x077D8099, 0x80D609F2 }, /* -153, 1917, 2546, -214 */
+ { 0x07668097, 0x80D80A09 }, /* -151, 1894, 2569, -216 */
+ { 0x074F8095, 0x80DA0A20 }, /* -149, 1871, 2592, -218 */
+ { 0x073A8093, 0x80DC0A35 }, /* -147, 1850, 2613, -220 */
+ { 0x07238091, 0x80DE0A4C }, /* -145, 1827, 2636, -222 */
+ { 0x070C808E, 0x80E00A62 }, /* -142, 1804, 2658, -224 */
+ { 0x06F7808C, 0x80E20A77 }, /* -140, 1783, 2679, -226 */
+ { 0x06E0808A, 0x80E40A8E }, /* -138, 1760, 2702, -228 */
+ { 0x06CA8088, 0x80E60AA4 }, /* -136, 1738, 2724, -230 */
+ { 0x06B48086, 0x80E70AB9 }, /* -134, 1716, 2745, -231 */
+ { 0x069E8084, 0x80E90ACF }, /* -132, 1694, 2767, -233 */
+ { 0x06878081, 0x80EB0AE5 }, /* -129, 1671, 2789, -235 */
+ { 0x0672807F, 0x80ED0AFA }, /* -127, 1650, 2810, -237 */
+ { 0x065C807D, 0x80EE0B0F }, /* -125, 1628, 2831, -238 */
+ { 0x0646807B, 0x80F00B25 }, /* -123, 1606, 2853, -240 */
+ { 0x06308079, 0x80F20B3B }, /* -121, 1584, 2875, -242 */
+ { 0x061A8077, 0x80F30B50 }, /* -119, 1562, 2896, -243 */
+ { 0x06068076, 0x80F50B65 }, /* -118, 1542, 2917, -245 */
+ { 0x05F08074, 0x80F60B7A }, /* -116, 1520, 2938, -246 */
+ { 0x05DB8072, 0x80F80B8F }, /* -114, 1499, 2959, -248 */
+ { 0x05C58070, 0x80F90BA4 }, /* -112, 1477, 2980, -249 */
+ { 0x05B1806E, 0x80FC0BB9 }, /* -110, 1457, 3001, -252 */
+ { 0x059B806C, 0x80FD0BCE }, /* -108, 1435, 3022, -253 */
+ { 0x0586806A, 0x80FE0BE2 }, /* -106, 1414, 3042, -254 */
+ { 0x05718068, 0x81000BF7 }, /* -104, 1393, 3063, -256 */
+ { 0x055C8066, 0x81010C0B }, /* -102, 1372, 3083, -257 */
+ { 0x05478064, 0x81020C1F }, /* -100, 1351, 3103, -258 */
+ { 0x05328062, 0x81030C33 }, /* -98, 1330, 3123, -259 */
+ { 0x051D8060, 0x81040C47 }, /* -96, 1309, 3143, -260 */
+ { 0x0508805E, 0x81050C5B }, /* -94, 1288, 3163, -261 */
+ { 0x04F3805C, 0x81060C6F }, /* -92, 1267, 3183, -262 */
+ { 0x04E0805B, 0x81070C82 }, /* -91, 1248, 3202, -263 */
+ { 0x04CB8059, 0x81080C96 }, /* -89, 1227, 3222, -264 */
+ { 0x04B68057, 0x81080CA9 }, /* -87, 1206, 3241, -264 */
+ { 0x04A28055, 0x81090CBC }, /* -85, 1186, 3260, -265 */
+ { 0x048E8053, 0x810A0CCF }, /* -83, 1166, 3279, -266 */
+ { 0x047A8052, 0x810A0CE2 }, /* -82, 1146, 3298, -266 */
+ { 0x04668050, 0x810B0CF5 }, /* -80, 1126, 3317, -267 */
+ { 0x0451804E, 0x810B0D08 }, /* -78, 1105, 3336, -267 */
+ { 0x043E804D, 0x810C0D1B }, /* -77, 1086, 3355, -268 */
+ { 0x042B804B, 0x810C0D2C }, /* -75, 1067, 3372, -268 */
+ { 0x04178049, 0x810C0D3E }, /* -73, 1047, 3390, -268 */
+ { 0x04038048, 0x810C0D51 }, /* -72, 1027, 3409, -268 */
+ { 0x03F08046, 0x810C0D62 }, /* -70, 1008, 3426, -268 */
+ { 0x03DD8044, 0x810C0D73 }, /* -68, 989, 3443, -268 */
+ { 0x03CA8043, 0x810C0D85 }, /* -67, 970, 3461, -268 */
+ { 0x03B78041, 0x810C0D96 }, /* -65, 951, 3478, -268 */
+ { 0x03A48040, 0x810C0DA8 }, /* -64, 932, 3496, -268 */
+ { 0x0391803E, 0x810B0DB8 }, /* -62, 913, 3512, -267 */
+ { 0x0380803D, 0x810C0DC9 }, /* -61, 896, 3529, -268 */
+ { 0x036D803B, 0x810C0DDA }, /* -59, 877, 3546, -268 */
+ { 0x035B803A, 0x810B0DEA }, /* -58, 859, 3562, -267 */
+ { 0x03488038, 0x810A0DFA }, /* -56, 840, 3578, -266 */
+ { 0x03368037, 0x810A0E0B }, /* -55, 822, 3595, -266 */
+ { 0x03248036, 0x81090E1B }, /* -54, 804, 3611, -265 */
+ { 0x03128034, 0x81080E2A }, /* -52, 786, 3626, -264 */
+ { 0x03018033, 0x81070E39 }, /* -51, 769, 3641, -263 */
+ { 0x02EF8032, 0x81060E49 }, /* -50, 751, 3657, -262 */
+ { 0x02DE8030, 0x81040E56 }, /* -48, 734, 3670, -260 */
+ { 0x02CC802F, 0x81030E66 }, /* -47, 716, 3686, -259 */
+ { 0x02BB802E, 0x81020E75 }, /* -46, 699, 3701, -258 */
+ { 0x02AA802D, 0x81000E83 }, /* -45, 682, 3715, -256 */
+ { 0x0299802B, 0x80FE0E90 }, /* -43, 665, 3728, -254 */
+ { 0x0288802A, 0x80FD0E9F }, /* -42, 648, 3743, -253 */
+ { 0x02778029, 0x80FB0EAD }, /* -41, 631, 3757, -251 */
+ { 0x02678028, 0x80F90EBA }, /* -40, 615, 3770, -249 */
+ { 0x02568027, 0x80F70EC8 }, /* -39, 598, 3784, -247 */
+ { 0x02468025, 0x80F50ED4 }, /* -37, 582, 3796, -245 */
+ { 0x02368024, 0x80F30EE1 }, /* -36, 566, 3809, -243 */
+ { 0x02268023, 0x80F00EED }, /* -35, 550, 3821, -240 */
+ { 0x02188023, 0x80EF0EFA }, /* -35, 536, 3834, -239 */
+ { 0x02078021, 0x80EB0F05 }, /* -33, 519, 3845, -235 */
+ { 0x01F98021, 0x80E90F11 }, /* -33, 505, 3857, -233 */
+ { 0x01EA8020, 0x80E60F1C }, /* -32, 490, 3868, -230 */
+ { 0x01DC801F, 0x80E40F27 }, /* -31, 476, 3879, -228 */
+ { 0x01CD801E, 0x80E00F31 }, /* -30, 461, 3889, -224 */
+ { 0x01BE801D, 0x80DD0F3C }, /* -29, 446, 3900, -221 */
+ { 0x01AF801C, 0x80DA0F47 }, /* -28, 431, 3911, -218 */
+ { 0x01A1801B, 0x80D70F51 }, /* -27, 417, 3921, -215 */
+ { 0x0192801A, 0x80D30F5B }, /* -26, 402, 3931, -211 */
+ { 0x01848019, 0x80CF0F64 }, /* -25, 388, 3940, -207 */
+ { 0x01768018, 0x80CB0F6D }, /* -24, 374, 3949, -203 */
+ { 0x01688017, 0x80C80F77 }, /* -23, 360, 3959, -200 */
+ { 0x015A8016, 0x80C30F7F }, /* -22, 346, 3967, -195 */
+ { 0x014D8015, 0x80BF0F87 }, /* -21, 333, 3975, -191 */
+ { 0x013F8015, 0x80BB0F91 }, /* -21, 319, 3985, -187 */
+ { 0x01328014, 0x80B60F98 }, /* -20, 306, 3992, -182 */
+ { 0x01258013, 0x80B20FA0 }, /* -19, 293, 4000, -178 */
+ { 0x01188012, 0x80AD0FA7 }, /* -18, 280, 4007, -173 */
+ { 0x010B8011, 0x80A80FAE }, /* -17, 267, 4014, -168 */
+ { 0x00FE8010, 0x80A30FB5 }, /* -16, 254, 4021, -163 */
+ { 0x00F28010, 0x809E0FBC }, /* -16, 242, 4028, -158 */
+ { 0x00E6800F, 0x80990FC2 }, /* -15, 230, 4034, -153 */
+ { 0x00DA800E, 0x80930FC7 }, /* -14, 218, 4039, -147 */
+ { 0x00CE800D, 0x808E0FCD }, /* -13, 206, 4045, -142 */
+ { 0x00C2800D, 0x80880FD3 }, /* -13, 194, 4051, -136 */
+ { 0x00B6800C, 0x80820FD8 }, /* -12, 182, 4056, -130 */
+ { 0x00AB800B, 0x807C0FDC }, /* -11, 171, 4060, -124 */
+ { 0x009F800A, 0x80760FE1 }, /* -10, 159, 4065, -118 */
+ { 0x0094800A, 0x80700FE6 }, /* -10, 148, 4070, -112 */
+ { 0x00898009, 0x80690FE9 }, /* -9, 137, 4073, -105 */
+ { 0x007E8008, 0x80630FED }, /* -8, 126, 4077, -99 */
+ { 0x00748007, 0x805C0FEF }, /* -7, 116, 4079, -92 */
+ { 0x00698007, 0x80550FF3 }, /* -7, 105, 4083, -85 */
+ { 0x005F8006, 0x804E0FF5 }, /* -6, 95, 4085, -78 */
+ { 0x00558005, 0x80470FF7 }, /* -5, 85, 4087, -71 */
+ { 0x004B8005, 0x80400FFA }, /* -5, 75, 4090, -64 */
+ { 0x00418004, 0x80380FFB }, /* -4, 65, 4091, -56 */
+ { 0x00378003, 0x80310FFD }, /* -3, 55, 4093, -49 */
+ { 0x002E8003, 0x80290FFE }, /* -3, 46, 4094, -41 */
+ { 0x00238002, 0x80211000 }, /* -2, 35, 4096, -33 */
+ { 0x001A8001, 0x80191000 }, /* -1, 26, 4096, -25 */
+ { 0x00118001, 0x80101000 }, /* -1, 17, 4096, -16 */
+ { 0x00080000, 0x80081000 }, /* 0, 8, 4096, -8 */
+};
+
+long CimarronVideoFilter128[][2] =
+{
+ { 0x10000000, 0x00000000 }, /* 0, 4096, 0, 0 */
+ { 0x10018011, 0x80010011 }, /* -17, 4097, 17, -1 */
+ { 0x10008021, 0x80020023 }, /* -33, 4096, 35, -2 */
+ { 0x0FFE8031, 0x80030036 }, /* -49, 4094, 54, -3 */
+ { 0x0FFB8040, 0x8005004A }, /* -64, 4091, 74, -5 */
+ { 0x0FF6804E, 0x8006005E }, /* -78, 4086, 94, -6 */
+ { 0x0FF0805C, 0x80070073 }, /* -92, 4080, 115, -7 */
+ { 0x0FEB806A, 0x80090088 }, /* -106, 4075, 136, -9 */
+ { 0x0FE18076, 0x800A009F }, /* -118, 4065, 159, -10 */
+ { 0x0FD98082, 0x800C00B5 }, /* -130, 4057, 181, -12 */
+ { 0x0FCE808E, 0x800D00CD }, /* -142, 4046, 205, -13 */
+ { 0x0FC38099, 0x800F00E5 }, /* -153, 4035, 229, -15 */
+ { 0x0FB680A4, 0x801000FE }, /* -164, 4022, 254, -16 */
+ { 0x0FA880AD, 0x80120117 }, /* -173, 4008, 279, -18 */
+ { 0x0F9A80B7, 0x80140131 }, /* -183, 3994, 305, -20 */
+ { 0x0F8980C0, 0x8015014C }, /* -192, 3977, 332, -21 */
+ { 0x0F7880C8, 0x80170167 }, /* -200, 3960, 359, -23 */
+ { 0x0F6680D0, 0x80190183 }, /* -208, 3942, 387, -25 */
+ { 0x0F5280D7, 0x801B01A0 }, /* -215, 3922, 416, -27 */
+ { 0x0F3E80DE, 0x801D01BD }, /* -222, 3902, 445, -29 */
+ { 0x0F2880E4, 0x801F01DB }, /* -228, 3880, 475, -31 */
+ { 0x0F1180EA, 0x802101FA }, /* -234, 3857, 506, -33 */
+ { 0x0EF880EE, 0x80220218 }, /* -238, 3832, 536, -34 */
+ { 0x0EDF80F3, 0x80240238 }, /* -243, 3807, 568, -36 */
+ { 0x0EC680F7, 0x80270258 }, /* -247, 3782, 600, -39 */
+ { 0x0EAB80FB, 0x80290279 }, /* -251, 3755, 633, -41 */
+ { 0x0E9080FF, 0x802B029A }, /* -255, 3728, 666, -43 */
+ { 0x0E748102, 0x802E02BC }, /* -258, 3700, 700, -46 */
+ { 0x0E588105, 0x803102DE }, /* -261, 3672, 734, -49 */
+ { 0x0E388107, 0x80330302 }, /* -263, 3640, 770, -51 */
+ { 0x0E1A8109, 0x80360325 }, /* -265, 3610, 805, -54 */
+ { 0x0DFB810B, 0x80390349 }, /* -267, 3579, 841, -57 */
+ { 0x0DDB810C, 0x803C036D }, /* -268, 3547, 877, -60 */
+ { 0x0DBA810D, 0x803F0392 }, /* -269, 3514, 914, -63 */
+ { 0x0D98810E, 0x804203B8 }, /* -270, 3480, 952, -66 */
+ { 0x0D74810D, 0x804503DE }, /* -269, 3444, 990, -69 */
+ { 0x0D50810D, 0x80480405 }, /* -269, 3408, 1029, -72 */
+ { 0x0D2C810C, 0x804B042B }, /* -268, 3372, 1067, -75 */
+ { 0x0D08810C, 0x804F0453 }, /* -268, 3336, 1107, -79 */
+ { 0x0CE3810B, 0x8052047A }, /* -267, 3299, 1146, -82 */
+ { 0x0CBD810A, 0x805604A3 }, /* -266, 3261, 1187, -86 */
+ { 0x0C968108, 0x805904CB }, /* -264, 3222, 1227, -89 */
+ { 0x0C708107, 0x805D04F4 }, /* -263, 3184, 1268, -93 */
+ { 0x0C488105, 0x8061051E }, /* -261, 3144, 1310, -97 */
+ { 0x0C208103, 0x80640547 }, /* -259, 3104, 1351, -100 */
+ { 0x0BF78100, 0x80680571 }, /* -256, 3063, 1393, -104 */
+ { 0x0BCF80FE, 0x806C059B }, /* -254, 3023, 1435, -108 */
+ { 0x0BA480FA, 0x807005C6 }, /* -250, 2980, 1478, -112 */
+ { 0x0B7A80F7, 0x807405F1 }, /* -247, 2938, 1521, -116 */
+ { 0x0B4F80F4, 0x8077061C }, /* -244, 2895, 1564, -119 */
+ { 0x0B2580F1, 0x807C0648 }, /* -241, 2853, 1608, -124 */
+ { 0x0AFA80ED, 0x80800673 }, /* -237, 2810, 1651, -128 */
+ { 0x0ACF80EA, 0x8084069F }, /* -234, 2767, 1695, -132 */
+ { 0x0AA380E6, 0x808806CB }, /* -230, 2723, 1739, -136 */
+ { 0x0A7880E2, 0x808D06F7 }, /* -226, 2680, 1783, -141 */
+ { 0x0A4C80DF, 0x80910724 }, /* -223, 2636, 1828, -145 */
+ { 0x0A2080DB, 0x80960751 }, /* -219, 2592, 1873, -150 */
+ { 0x09F480D7, 0x809A077D }, /* -215, 2548, 1917, -154 */
+ { 0x09C780D2, 0x809F07AA }, /* -210, 2503, 1962, -159 */
+ { 0x099A80CE, 0x80A307D7 }, /* -206, 2458, 2007, -163 */
+ { 0x096D80CA, 0x80A70804 }, /* -202, 2413, 2052, -167 */
+ { 0x094180C6, 0x80AC0831 }, /* -198, 2369, 2097, -172 */
+ { 0x091380C1, 0x80B0085E }, /* -193, 2323, 2142, -176 */
+ { 0x08E780BE, 0x80B5088C }, /* -190, 2279, 2188, -181 */
+ { 0x08B980B9, 0x80B908B9 }, /* -185, 2233, 2233, -185 */
+ { 0x088C80B5, 0x80BE08E7 }, /* -181, 2188, 2279, -190 */
+ { 0x085E80B0, 0x80C10913 }, /* -176, 2142, 2323, -193 */
+ { 0x083180AC, 0x80C60941 }, /* -172, 2097, 2369, -198 */
+ { 0x080480A7, 0x80CA096D }, /* -167, 2052, 2413, -202 */
+ { 0x07D780A3, 0x80CE099A }, /* -163, 2007, 2458, -206 */
+ { 0x07AA809F, 0x80D209C7 }, /* -159, 1962, 2503, -210 */
+ { 0x077D809A, 0x80D709F4 }, /* -154, 1917, 2548, -215 */
+ { 0x07518096, 0x80DB0A20 }, /* -150, 1873, 2592, -219 */
+ { 0x07248091, 0x80DF0A4C }, /* -145, 1828, 2636, -223 */
+ { 0x06F7808D, 0x80E20A78 }, /* -141, 1783, 2680, -226 */
+ { 0x06CA8088, 0x80E60AA4 }, /* -136, 1738, 2724, -230 */
+ { 0x069E8084, 0x80EA0AD0 }, /* -132, 1694, 2768, -234 */
+ { 0x06738080, 0x80ED0AFA }, /* -128, 1651, 2810, -237 */
+ { 0x0647807C, 0x80F10B26 }, /* -124, 1607, 2854, -241 */
+ { 0x061B8077, 0x80F40B50 }, /* -119, 1563, 2896, -244 */
+ { 0x05F18074, 0x80F70B7A }, /* -116, 1521, 2938, -247 */
+ { 0x05C68070, 0x80FA0BA4 }, /* -112, 1478, 2980, -250 */
+ { 0x059C806C, 0x80FE0BCE }, /* -108, 1436, 3022, -254 */
+ { 0x05728068, 0x81000BF6 }, /* -104, 1394, 3062, -256 */
+ { 0x05478064, 0x81030C20 }, /* -100, 1351, 3104, -259 */
+ { 0x051E8061, 0x81050C48 }, /* -97, 1310, 3144, -261 */
+ { 0x04F4805D, 0x81070C70 }, /* -93, 1268, 3184, -263 */
+ { 0x04CB8059, 0x81080C96 }, /* -89, 1227, 3222, -264 */
+ { 0x04A38056, 0x810A0CBD }, /* -86, 1187, 3261, -266 */
+ { 0x047A8052, 0x810B0CE3 }, /* -82, 1146, 3299, -267 */
+ { 0x0453804F, 0x810C0D08 }, /* -79, 1107, 3336, -268 */
+ { 0x042B804B, 0x810C0D2C }, /* -75, 1067, 3372, -268 */
+ { 0x04048048, 0x810D0D51 }, /* -72, 1028, 3409, -269 */
+ { 0x03DE8045, 0x810D0D74 }, /* -69, 990, 3444, -269 */
+ { 0x03B88042, 0x810E0D98 }, /* -66, 952, 3480, -270 */
+ { 0x0393803F, 0x810D0DB9 }, /* -63, 915, 3513, -269 */
+ { 0x036E803C, 0x810C0DDA }, /* -60, 878, 3546, -268 */
+ { 0x03498039, 0x810B0DFB }, /* -57, 841, 3579, -267 */
+ { 0x03258036, 0x81090E1A }, /* -54, 805, 3610, -265 */
+ { 0x03018033, 0x81070E39 }, /* -51, 769, 3641, -263 */
+ { 0x02DE8031, 0x81050E58 }, /* -49, 734, 3672, -261 */
+ { 0x02BC802E, 0x81020E74 }, /* -46, 700, 3700, -258 */
+ { 0x0299802B, 0x80FF0E91 }, /* -43, 665, 3729, -255 */
+ { 0x02788029, 0x80FB0EAC }, /* -41, 632, 3756, -251 */
+ { 0x02578027, 0x80F70EC7 }, /* -39, 599, 3783, -247 */
+ { 0x02378024, 0x80F30EE0 }, /* -36, 567, 3808, -243 */
+ { 0x02178022, 0x80EE0EF9 }, /* -34, 535, 3833, -238 */
+ { 0x01FA8021, 0x80EA0F11 }, /* -33, 506, 3857, -234 */
+ { 0x01DC801F, 0x80E40F27 }, /* -31, 476, 3879, -228 */
+ { 0x01BE801D, 0x80DE0F3D }, /* -29, 446, 3901, -222 */
+ { 0x01A1801B, 0x80D70F51 }, /* -27, 417, 3921, -215 */
+ { 0x01848019, 0x80D00F65 }, /* -25, 388, 3941, -208 */
+ { 0x01688017, 0x80C80F77 }, /* -23, 360, 3959, -200 */
+ { 0x014D8015, 0x80C00F88 }, /* -21, 333, 3976, -192 */
+ { 0x01328014, 0x80B70F99 }, /* -20, 306, 3993, -183 */
+ { 0x01188012, 0x80AD0FA7 }, /* -18, 280, 4007, -173 */
+ { 0x00FF8010, 0x80A40FB5 }, /* -16, 255, 4021, -164 */
+ { 0x00E6800F, 0x80990FC2 }, /* -15, 230, 4034, -153 */
+ { 0x00CE800D, 0x808E0FCD }, /* -13, 206, 4045, -142 */
+ { 0x00B6800C, 0x80820FD8 }, /* -12, 182, 4056, -130 */
+ { 0x00A0800A, 0x80760FE0 }, /* -10, 160, 4064, -118 */
+ { 0x00898009, 0x806A0FEA }, /* -9, 137, 4074, -106 */
+ { 0x00748007, 0x805C0FEF }, /* -7, 116, 4079, -92 */
+ { 0x005F8006, 0x804E0FF5 }, /* -6, 95, 4085, -78 */
+ { 0x004B8005, 0x80400FFA }, /* -5, 75, 4090, -64 */
+ { 0x00378003, 0x80310FFD }, /* -3, 55, 4093, -49 */
+ { 0x00238002, 0x80211000 }, /* -2, 35, 4096, -33 */
+ { 0x00118001, 0x80111001 }, /* -1, 17, 4097, -17 */
+ { 0x10000000, 0x00000000 }, /* 0, 4096, 0, 0 */
+ { 0x10018011, 0x80010011 }, /* -17, 4097, 17, -1 */
+ { 0x10008021, 0x80020023 }, /* -33, 4096, 35, -2 */
+ { 0x0FFE8031, 0x80030036 }, /* -49, 4094, 54, -3 */
+ { 0x0FFB8040, 0x8005004A }, /* -64, 4091, 74, -5 */
+ { 0x0FF6804E, 0x8006005E }, /* -78, 4086, 94, -6 */
+ { 0x0FF0805C, 0x80070073 }, /* -92, 4080, 115, -7 */
+ { 0x0FEB806A, 0x80090088 }, /* -106, 4075, 136, -9 */
+ { 0x0FE18076, 0x800A009F }, /* -118, 4065, 159, -10 */
+ { 0x0FD98082, 0x800C00B5 }, /* -130, 4057, 181, -12 */
+ { 0x0FCE808E, 0x800D00CD }, /* -142, 4046, 205, -13 */
+ { 0x0FC38099, 0x800F00E5 }, /* -153, 4035, 229, -15 */
+ { 0x0FB680A4, 0x801000FE }, /* -164, 4022, 254, -16 */
+ { 0x0FA880AD, 0x80120117 }, /* -173, 4008, 279, -18 */
+ { 0x0F9A80B7, 0x80140131 }, /* -183, 3994, 305, -20 */
+ { 0x0F8980C0, 0x8015014C }, /* -192, 3977, 332, -21 */
+ { 0x0F7880C8, 0x80170167 }, /* -200, 3960, 359, -23 */
+ { 0x0F6680D0, 0x80190183 }, /* -208, 3942, 387, -25 */
+ { 0x0F5280D7, 0x801B01A0 }, /* -215, 3922, 416, -27 */
+ { 0x0F3E80DE, 0x801D01BD }, /* -222, 3902, 445, -29 */
+ { 0x0F2880E4, 0x801F01DB }, /* -228, 3880, 475, -31 */
+ { 0x0F1180EA, 0x802101FA }, /* -234, 3857, 506, -33 */
+ { 0x0EF880EE, 0x80220218 }, /* -238, 3832, 536, -34 */
+ { 0x0EDF80F3, 0x80240238 }, /* -243, 3807, 568, -36 */
+ { 0x0EC680F7, 0x80270258 }, /* -247, 3782, 600, -39 */
+ { 0x0EAB80FB, 0x80290279 }, /* -251, 3755, 633, -41 */
+ { 0x0E9080FF, 0x802B029A }, /* -255, 3728, 666, -43 */
+ { 0x0E748102, 0x802E02BC }, /* -258, 3700, 700, -46 */
+ { 0x0E588105, 0x803102DE }, /* -261, 3672, 734, -49 */
+ { 0x0E388107, 0x80330302 }, /* -263, 3640, 770, -51 */
+ { 0x0E1A8109, 0x80360325 }, /* -265, 3610, 805, -54 */
+ { 0x0DFB810B, 0x80390349 }, /* -267, 3579, 841, -57 */
+ { 0x0DDB810C, 0x803C036D }, /* -268, 3547, 877, -60 */
+ { 0x0DBA810D, 0x803F0392 }, /* -269, 3514, 914, -63 */
+ { 0x0D98810E, 0x804203B8 }, /* -270, 3480, 952, -66 */
+ { 0x0D74810D, 0x804503DE }, /* -269, 3444, 990, -69 */
+ { 0x0D50810D, 0x80480405 }, /* -269, 3408, 1029, -72 */
+ { 0x0D2C810C, 0x804B042B }, /* -268, 3372, 1067, -75 */
+ { 0x0D08810C, 0x804F0453 }, /* -268, 3336, 1107, -79 */
+ { 0x0CE3810B, 0x8052047A }, /* -267, 3299, 1146, -82 */
+ { 0x0CBD810A, 0x805604A3 }, /* -266, 3261, 1187, -86 */
+ { 0x0C968108, 0x805904CB }, /* -264, 3222, 1227, -89 */
+ { 0x0C708107, 0x805D04F4 }, /* -263, 3184, 1268, -93 */
+ { 0x0C488105, 0x8061051E }, /* -261, 3144, 1310, -97 */
+ { 0x0C208103, 0x80640547 }, /* -259, 3104, 1351, -100 */
+ { 0x0BF78100, 0x80680571 }, /* -256, 3063, 1393, -104 */
+ { 0x0BCF80FE, 0x806C059B }, /* -254, 3023, 1435, -108 */
+ { 0x0BA480FA, 0x807005C6 }, /* -250, 2980, 1478, -112 */
+ { 0x0B7A80F7, 0x807405F1 }, /* -247, 2938, 1521, -116 */
+ { 0x0B4F80F4, 0x8077061C }, /* -244, 2895, 1564, -119 */
+ { 0x0B2580F1, 0x807C0648 }, /* -241, 2853, 1608, -124 */
+ { 0x0AFA80ED, 0x80800673 }, /* -237, 2810, 1651, -128 */
+ { 0x0ACF80EA, 0x8084069F }, /* -234, 2767, 1695, -132 */
+ { 0x0AA380E6, 0x808806CB }, /* -230, 2723, 1739, -136 */
+ { 0x0A7880E2, 0x808D06F7 }, /* -226, 2680, 1783, -141 */
+ { 0x0A4C80DF, 0x80910724 }, /* -223, 2636, 1828, -145 */
+ { 0x0A2080DB, 0x80960751 }, /* -219, 2592, 1873, -150 */
+ { 0x09F480D7, 0x809A077D }, /* -215, 2548, 1917, -154 */
+ { 0x09C780D2, 0x809F07AA }, /* -210, 2503, 1962, -159 */
+ { 0x099A80CE, 0x80A307D7 }, /* -206, 2458, 2007, -163 */
+ { 0x096D80CA, 0x80A70804 }, /* -202, 2413, 2052, -167 */
+ { 0x094180C6, 0x80AC0831 }, /* -198, 2369, 2097, -172 */
+ { 0x091380C1, 0x80B0085E }, /* -193, 2323, 2142, -176 */
+ { 0x08E780BE, 0x80B5088C }, /* -190, 2279, 2188, -181 */
+ { 0x08B980B9, 0x80B908B9 }, /* -185, 2233, 2233, -185 */
+ { 0x088C80B5, 0x80BE08E7 }, /* -181, 2188, 2279, -190 */
+ { 0x085E80B0, 0x80C10913 }, /* -176, 2142, 2323, -193 */
+ { 0x083180AC, 0x80C60941 }, /* -172, 2097, 2369, -198 */
+ { 0x080480A7, 0x80CA096D }, /* -167, 2052, 2413, -202 */
+ { 0x07D780A3, 0x80CE099A }, /* -163, 2007, 2458, -206 */
+ { 0x07AA809F, 0x80D209C7 }, /* -159, 1962, 2503, -210 */
+ { 0x077D809A, 0x80D709F4 }, /* -154, 1917, 2548, -215 */
+ { 0x07518096, 0x80DB0A20 }, /* -150, 1873, 2592, -219 */
+ { 0x07248091, 0x80DF0A4C }, /* -145, 1828, 2636, -223 */
+ { 0x06F7808D, 0x80E20A78 }, /* -141, 1783, 2680, -226 */
+ { 0x06CA8088, 0x80E60AA4 }, /* -136, 1738, 2724, -230 */
+ { 0x069E8084, 0x80EA0AD0 }, /* -132, 1694, 2768, -234 */
+ { 0x06738080, 0x80ED0AFA }, /* -128, 1651, 2810, -237 */
+ { 0x0647807C, 0x80F10B26 }, /* -124, 1607, 2854, -241 */
+ { 0x061B8077, 0x80F40B50 }, /* -119, 1563, 2896, -244 */
+ { 0x05F18074, 0x80F70B7A }, /* -116, 1521, 2938, -247 */
+ { 0x05C68070, 0x80FA0BA4 }, /* -112, 1478, 2980, -250 */
+ { 0x059C806C, 0x80FE0BCE }, /* -108, 1436, 3022, -254 */
+ { 0x05728068, 0x81000BF6 }, /* -104, 1394, 3062, -256 */
+ { 0x05478064, 0x81030C20 }, /* -100, 1351, 3104, -259 */
+ { 0x051E8061, 0x81050C48 }, /* -97, 1310, 3144, -261 */
+ { 0x04F4805D, 0x81070C70 }, /* -93, 1268, 3184, -263 */
+ { 0x04CB8059, 0x81080C96 }, /* -89, 1227, 3222, -264 */
+ { 0x04A38056, 0x810A0CBD }, /* -86, 1187, 3261, -266 */
+ { 0x047A8052, 0x810B0CE3 }, /* -82, 1146, 3299, -267 */
+ { 0x0453804F, 0x810C0D08 }, /* -79, 1107, 3336, -268 */
+ { 0x042B804B, 0x810C0D2C }, /* -75, 1067, 3372, -268 */
+ { 0x04048048, 0x810D0D51 }, /* -72, 1028, 3409, -269 */
+ { 0x03DE8045, 0x810D0D74 }, /* -69, 990, 3444, -269 */
+ { 0x03B88042, 0x810E0D98 }, /* -66, 952, 3480, -270 */
+ { 0x0393803F, 0x810D0DB9 }, /* -63, 915, 3513, -269 */
+ { 0x036E803C, 0x810C0DDA }, /* -60, 878, 3546, -268 */
+ { 0x03498039, 0x810B0DFB }, /* -57, 841, 3579, -267 */
+ { 0x03258036, 0x81090E1A }, /* -54, 805, 3610, -265 */
+ { 0x03018033, 0x81070E39 }, /* -51, 769, 3641, -263 */
+ { 0x02DE8031, 0x81050E58 }, /* -49, 734, 3672, -261 */
+ { 0x02BC802E, 0x81020E74 }, /* -46, 700, 3700, -258 */
+ { 0x0299802B, 0x80FF0E91 }, /* -43, 665, 3729, -255 */
+ { 0x02788029, 0x80FB0EAC }, /* -41, 632, 3756, -251 */
+ { 0x02578027, 0x80F70EC7 }, /* -39, 599, 3783, -247 */
+ { 0x02378024, 0x80F30EE0 }, /* -36, 567, 3808, -243 */
+ { 0x02178022, 0x80EE0EF9 }, /* -34, 535, 3833, -238 */
+ { 0x01FA8021, 0x80EA0F11 }, /* -33, 506, 3857, -234 */
+ { 0x01DC801F, 0x80E40F27 }, /* -31, 476, 3879, -228 */
+ { 0x01BE801D, 0x80DE0F3D }, /* -29, 446, 3901, -222 */
+ { 0x01A1801B, 0x80D70F51 }, /* -27, 417, 3921, -215 */
+ { 0x01848019, 0x80D00F65 }, /* -25, 388, 3941, -208 */
+ { 0x01688017, 0x80C80F77 }, /* -23, 360, 3959, -200 */
+ { 0x014D8015, 0x80C00F88 }, /* -21, 333, 3976, -192 */
+ { 0x01328014, 0x80B70F99 }, /* -20, 306, 3993, -183 */
+ { 0x01188012, 0x80AD0FA7 }, /* -18, 280, 4007, -173 */
+ { 0x00FF8010, 0x80A40FB5 }, /* -16, 255, 4021, -164 */
+ { 0x00E6800F, 0x80990FC2 }, /* -15, 230, 4034, -153 */
+ { 0x00CE800D, 0x808E0FCD }, /* -13, 206, 4045, -142 */
+ { 0x00B6800C, 0x80820FD8 }, /* -12, 182, 4056, -130 */
+ { 0x00A0800A, 0x80760FE0 }, /* -10, 160, 4064, -118 */
+ { 0x00898009, 0x806A0FEA }, /* -9, 137, 4074, -106 */
+ { 0x00748007, 0x805C0FEF }, /* -7, 116, 4079, -92 */
+ { 0x005F8006, 0x804E0FF5 }, /* -6, 95, 4085, -78 */
+ { 0x004B8005, 0x80400FFA }, /* -5, 75, 4090, -64 */
+ { 0x00378003, 0x80310FFD }, /* -3, 55, 4093, -49 */
+ { 0x00238002, 0x80211000 }, /* -2, 35, 4096, -33 */
+ { 0x00118001, 0x80111001 }, /* -1, 17, 4097, -17 */
+};
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_gp.c xf86-video-nsc-2.8.1/src/cim/cim_gp.c
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_gp.c 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_gp.c 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,3442 @@
+ /*
+ *
+ * Copyright (C) 2005 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *
+ *
+ *
+ *
+ *
+ * Cimarron graphics processor routines. These routines program the graphics
+ * hardware using the graphics command buffer.
+ *
+ *
+ */
+
+/*---------------------*/
+/* CIMARRON GP GLOBALS */
+/*---------------------*/
+
+CIMARRON_STATIC unsigned long gp3_bpp = 0;
+CIMARRON_STATIC unsigned long gp3_ch3_bpp = 0;
+CIMARRON_STATIC unsigned long gp3_pat_origin = 0;
+CIMARRON_STATIC unsigned long gp3_buffer_lead = 0;
+CIMARRON_STATIC unsigned long gp3_cmd_header;
+CIMARRON_STATIC unsigned long gp3_cmd_top;
+CIMARRON_STATIC unsigned long gp3_cmd_bottom;
+CIMARRON_STATIC unsigned long gp3_cmd_current;
+CIMARRON_STATIC unsigned long gp3_cmd_next;
+CIMARRON_STATIC unsigned long gp3_blt_mode;
+CIMARRON_STATIC unsigned long gp3_vec_mode;
+CIMARRON_STATIC unsigned long gp3_raster_mode;
+CIMARRON_STATIC unsigned long gp3_pix_shift;
+CIMARRON_STATIC unsigned long gp3_ch3_pat;
+CIMARRON_STATIC unsigned long gp3_blt;
+CIMARRON_STATIC unsigned long gp3_blt_flags;
+CIMARRON_STATIC unsigned long gp3_src_stride;
+CIMARRON_STATIC unsigned long gp3_dst_stride;
+CIMARRON_STATIC unsigned long gp3_src_format;
+CIMARRON_STATIC unsigned long gp3_src_pix_shift;
+CIMARRON_STATIC unsigned long gp3_pat_format;
+CIMARRON_STATIC unsigned long gp3_pat_pix_shift;
+CIMARRON_STATIC unsigned long gp3_fb_base;
+CIMARRON_STATIC unsigned long gp3_vector_pattern_color;
+CIMARRON_STATIC unsigned long gp3_scratch_base;
+CIMARRON_STATIC unsigned long gp3_base_register;
+CIMARRON_STATIC unsigned long gp3_vec_pat;
+
+/*---------------------------------------------------------------------------
+ * gp_set_limit_on_buffer_lead
+ *
+ * This routine is used to specify the maximum number of bytes in the command
+ * buffer by which software can lead the graphics processor. When declaring
+ * a BLT with the CIMGP_BLTFLAGS_LIMITBUFFER flag set, Cimarron will wait until
+ * the command buffer read and write pointers differ by no more than 'lead'
+ * bytes. This can be useful to limit the time lag possible when creating a
+ * command buffer full of simple BLT commands.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_limit_on_buffer_lead (unsigned long lead)
+{
+ gp3_buffer_lead = lead;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_command_buffer_base
+ *
+ * This routine is used to program the command buffer region in physical
+ * memory. The command buffer start address must be 1MB aligned. start and
+ * stop refer to endpoints within the associated 16MB region. Command buffers
+ * larger than 16MB are not supported.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_command_buffer_base (unsigned long address, unsigned long start,
+ unsigned long stop)
+{
+ Q_WORD msr_value;
+
+ /* WAIT FOR IDLE */
+ /* Obviously, we cannot change the command buffer pointer while the GP */
+ /* is currently fetching commands. */
+
+ gp_wait_until_idle();
+
+ /* WRITE THE COMMAND BUFFER BASE */
+
+ msr_read64 (MSR_DEVICE_GEODELX_GP, MSR_GEODELINK_CONFIG, &msr_value);
+ msr_value.low &= 0xF000FFFF;
+ msr_value.low |= (address >> 4) & 0x0FFF0000;
+ msr_write64 (MSR_DEVICE_GEODELX_GP, MSR_GEODELINK_CONFIG, &msr_value);
+
+ /* WRITE THE BASE OFFSETS */
+ /* We also reset the write and read pointers. The hardware will */
+ /* automatically update the write pointer when the read pointer */
+ /* is updated to prevent the hardware from getting confused when */
+ /* initializing a new command buffer. */
+
+ WRITE_GP32 (GP3_CMD_TOP, start);
+ WRITE_GP32 (GP3_CMD_BOT, stop);
+ WRITE_GP32 (GP3_CMD_READ, start);
+
+ /* SAVE THE BASE ADDRESSES */
+ /* These are used to determine the appropriate wrap point. */
+
+ gp3_cmd_current = gp3_cmd_top = start;
+ gp3_cmd_bottom = stop;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_frame_buffer_base
+ *
+ * This routine is used to program the base address of the frame buffer in
+ * physical memory. The frame buffer address must be 16MB aligned. Cimarron
+ * tracks the base address because the maximum frame buffer size may exceed
+ * 16MB. Any primitive will thus program the corresponding 16MB region into all
+ * base offset registers as well as program the offset into the 16MB region.
+ * The size parameter is provided to allow Cimarron to claim the last 1MB of
+ * space to be used as a scratch area for workarounds or expanded functionality.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_frame_buffer_base (unsigned long address, unsigned long size)
+{
+ gp3_scratch_base = size - GP3_SCRATCH_BUFFER_SIZE;
+ gp3_fb_base = address >> 24;
+ gp3_base_register = (gp3_fb_base << 24) | (gp3_fb_base << 14) | (gp3_fb_base << 4);
+ WRITE_GP32 (GP3_BASE_OFFSET, gp3_base_register);
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_bpp
+ *
+ * This routine sets the output BPP of the GP. The BPP used by the GP does
+ * not have to match the display BPP, but that is usually the case. The
+ * supported BPP values are as follows:
+ *
+ * 8 - palettized 8BPP
+ * 12 - 4:4:4:4
+ * 15 - 1:5:5:5
+ * 16 - 0:5:6:5
+ * 32 - 8:8:8:8
+ *-------------------------------------------------------------------------*/
+
+void gp_set_bpp (int bpp)
+{
+ /* STORE BPP */
+ /* The bpp is not updated until the next call to gp_set_raster_mode. */
+ /* This allows the gp_set_bpp call to happen outside of a BLT. It */
+ /* also implies that no registers need be written in this routine. */
+
+ switch(bpp)
+ {
+ case 8:
+ gp3_bpp = GP3_RM_BPPFMT_332;
+ gp3_ch3_bpp = GP3_CH3_SRC_3_3_2;
+ gp3_pix_shift = 0;
+ break;
+ case 12:
+ gp3_bpp = GP3_RM_BPPFMT_4444;
+ gp3_ch3_bpp = GP3_CH3_SRC_4_4_4_4;
+ gp3_pix_shift = 1;
+ break;
+ case 15:
+ gp3_bpp = GP3_RM_BPPFMT_1555;
+ gp3_ch3_bpp = GP3_CH3_SRC_1_5_5_5;
+ gp3_pix_shift = 1;
+ break;
+ case 16:
+ gp3_bpp = GP3_RM_BPPFMT_565;
+ gp3_ch3_bpp = GP3_CH3_SRC_0_5_6_5;
+ gp3_pix_shift = 1;
+ break;
+ case 24:
+ case 32:
+ gp3_bpp = GP3_RM_BPPFMT_8888;
+ gp3_ch3_bpp = GP3_CH3_SRC_8_8_8_8;
+ gp3_pix_shift = 2;
+ break;
+ default:
+ gp3_bpp = GP3_RM_BPPFMT_332;
+ gp3_ch3_bpp = GP3_CH3_SRC_3_3_2;
+ gp3_pix_shift = 0;
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * gp_declare_blt
+ *
+ * This routine is used to prepare for a 2D BLT. Its primary function
+ * is to verify that enough room is available in the command buffer
+ * to hold a BLT command. This command can be called multiple times if
+ * necessary. For example, if a function calls this routine on entry, but
+ * later realizes that a LUT load command must be executed before the BLT,
+ * the application could call gp_set_color_pattern and then call
+ * gp_declare_blt to declare the BLT. This is possible because the hardware
+ * buffer pointer is not updated until a new BLT is actually executed. An
+ * application must take care not to call any routines that perform a buffer
+ * command, (such as gp_set_color_pattern) between gp_declare_blt and the
+ * routines used to program the BLT parameters. In addition to checking for
+ * available space, this routine also performs the following actions:
+ * - Sets the wrap bit if this BLT will pass close to the end of the buffer.
+ * - Writes the command header.
+ *
+ * The available flags are defined as follows:
+ * 0x01 - Preserve the LUT
+ * 0x02 - Preserve the color pattern.
+ * 0x04 - Enable prefetch.
+ *-------------------------------------------------------------------------*/
+
+void gp_declare_blt (unsigned long flags)
+{
+ unsigned long temp;
+
+ gp3_blt = 1;
+ gp3_blt_flags = flags;
+
+ /* SET ADDRESS OF NEXT COMMAND */
+ /* A summary of the command buffer logic is as follows: */
+ /* - If after a basic BLT we will not have room for the largest */
+ /* command (a full line of host source data), we set the wrap */
+ /* bit. This will waste up to a whopping 8K of command buffer */
+ /* space, but it simplifies the logic for all commands. */
+ /* - If we are wrapping, we have extra logic to ensure that we */
+ /* don't skip over the current GP read pointer. */
+
+ gp3_cmd_next = gp3_cmd_current + GP3_BLT_COMMAND_SIZE;
+
+ /* CHECK WRAP CONDITION */
+
+ if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+ {
+ gp3_cmd_next = gp3_cmd_top;
+ gp3_cmd_header = GP3_BLT_HDR_TYPE | GP3_BLT_HDR_WRAP;
+
+ /* WAIT FOR HARDWARE */
+ /* When wrapping, we must take steps to ensure that we do not */
+ /* wrap over the current hardware read pointer. We do this by */
+ /* verifying that the hardware is not between us and the end of */
+ /* the command buffer. We also have a special case to make sure */
+ /* that the hardware is not currently reading the top of the */
+ /* command buffer. */
+
+ GP3_WAIT_WRAP(temp);
+ }
+ else
+ {
+ gp3_cmd_header = GP3_BLT_HDR_TYPE;
+
+ /* WAIT FOR AVAILABLE SPACE */
+
+ GP3_WAIT_PRIMITIVE(temp);
+ }
+
+ if (flags & CIMGP_BLTFLAGS_LIMITBUFFER)
+ {
+ while (1)
+ {
+ temp = READ_GP32 (GP3_CMD_READ);
+ if (((gp3_cmd_current >= temp) && ((gp3_cmd_current - temp) <= gp3_buffer_lead)) ||
+ ((gp3_cmd_current < temp) && ((gp3_cmd_current + (gp3_cmd_bottom - temp)) <= gp3_buffer_lead)))
+ {
+ break;
+ }
+ }
+ }
+
+ /* SET THE CURRENT BUFFER POINTER */
+ /* We initialize a pointer to the current buffer base to avoid an */
+ /* extra addition for every buffer write. */
+
+ cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+ /* SET THE HAZARD BIT */
+
+ if (flags & CIMGP_BLTFLAGS_HAZARD)
+ gp3_cmd_header |= GP3_BLT_HDR_HAZARD_ENABLE;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_declare_vector
+ *
+ * This routine is used to prepare for a 2D vector. It has no other function
+ * except to verify that enough room is available in the command buffer
+ * to hold a vector command. The same rules that apply to BLTs apply to
+ * vectors. (See the documentation for gp_declare_blt).
+ *-------------------------------------------------------------------------*/
+
+void gp_declare_vector (unsigned long flags)
+{
+ unsigned long temp;
+
+ gp3_blt = 0;
+ gp3_blt_flags = flags;
+
+ /* SET ADDRESS OF NEXT COMMAND */
+ /* The logic to force a wrap during a vector is identical */
+ /* to the BLT logic. */
+
+ /* ALLOCATE SPACE FOR AN ADDITIONAL VECTOR TO CLEAR THE BYTE ENABLES */
+
+ gp3_cmd_next = gp3_cmd_current + GP3_VECTOR_COMMAND_SIZE + GP3_VECTOR_COMMAND_SIZE + 32;
+
+ /* CHECK WRAP CONDITION */
+
+ if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+ {
+ gp3_cmd_next = gp3_cmd_top;
+ gp3_cmd_header = GP3_VEC_HDR_TYPE | GP3_VEC_HDR_WRAP;
+
+ /* CHECK WRAP CONDITION */
+
+ GP3_WAIT_WRAP(temp);
+ }
+ else
+ {
+ gp3_cmd_header = GP3_VEC_HDR_TYPE;
+
+ /* WAIT FOR AVAILABLE SPACE */
+
+ GP3_WAIT_PRIMITIVE(temp);
+
+ gp3_cmd_next -= GP3_VECTOR_COMMAND_SIZE + 32;
+ }
+
+ if (flags & CIMGP_BLTFLAGS_LIMITBUFFER)
+ {
+ while (1)
+ {
+ temp = READ_GP32 (GP3_CMD_READ);
+ if (((gp3_cmd_current >= temp) && ((gp3_cmd_current - temp) <= gp3_buffer_lead)) ||
+ ((gp3_cmd_current < temp) && ((gp3_cmd_current + (gp3_cmd_bottom - temp)) <= gp3_buffer_lead)))
+ {
+ break;
+ }
+ }
+ }
+
+ cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+ /* SET THE HAZARD BIT */
+
+ if (flags & CIMGP_BLTFLAGS_HAZARD)
+ gp3_cmd_header |= GP3_VEC_HDR_HAZARD_ENABLE;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_write_parameters
+ *
+ * This routine is called to write all recent parameters to the hardware.
+ * This routine is necessary for any implementation that performs the setup
+ * for a BLT separate from the actual BLT. An example would be a driver
+ * that prepares for multiple pattern fills by programming the ROP,
+ * pattern color and destination stride. The driver might then perform
+ * repeated pattern fills with minimal effort.
+ *-------------------------------------------------------------------------*/
+
+void gp_write_parameters (void)
+{
+ /* WRITE THE COMMAND HEADER */
+ /* Command header is at offset 0 for BLTs and vectors */
+
+ WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+
+ /* INCREMENT THE CURRENT WRITE POINTER */
+
+ gp3_cmd_current = gp3_cmd_next;
+
+ /* UPDATE THE GP WRITE POINTER */
+
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_current);
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_raster_operation
+ *
+ * This is generally the first routine called when programming a BLT. This
+ * routine performs the following functions:
+ * - Sets the initial value of the GP3_RASTER_MODE register in the buffer.
+ * - Clears any 8x8 pattern if the ROP does not involve pattern data.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_raster_operation (unsigned char ROP)
+{
+ gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE;
+
+ /* WRITE THE RASTER MODE REGISTER */
+ /* This register is in the same location in BLT and vector commands */
+
+ gp3_raster_mode = gp3_bpp | (unsigned long)ROP;
+ WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_raster_mode);
+
+ /* CHECK IF DESTINATION IS REQUIRED */
+
+ if ((ROP & 0x55) ^ ((ROP >> 1) & 0x55))
+ {
+ gp3_blt_mode = GP3_BM_DST_REQ;
+ gp3_vec_mode = GP3_VM_DST_REQ;
+ }
+ else
+ {
+ gp3_blt_mode = gp3_vec_mode = 0;
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * gp_set_alpha_operation
+ *
+ * BLTs are generally one of two types, a ROPed BLT or a BLT composited using
+ * alpha blending. For the latter, this routine is used to configure the
+ * mathematical function used to create the blended output. This routine
+ * should generally be called first when programming a BLT. The available
+ * parameters mirror the hardware and are described as follows:
+ *
+ * alpha_operation =
+ * 0 - alpha * A
+ * 1 - (1 - alpha) * B
+ * 2 - A + (1 - alpha)*B
+ * 3 - alpha*A + (1 - alpha)*B
+ *
+ * alpha_type =
+ * 0 - alpha component of channel A
+ * 1 - alpha component of channel B
+ * 2 - Constant alpha
+ * 3 - Constant 1
+ * 4 - The color components of channel A
+ * 5 - The color components of channel B
+ * 6 - Alpha comes from the alpha channel of the source before the source undergoes
+ * color conversion.
+ *
+ * channel =
+ * 0 - Channel A = source, channel B = destination
+ * 1 - Channel B = source, channel A = destination
+ *
+ * apply_alpha =
+ * 1 - Apply alpha blend to only the RGB portion of the pixel. This must be
+ * set when the source or destination format do not include an alpha channel.
+ * 2 - Apply alpha blend only to the alpha portion of the pixel. This implies
+ * that both destination and source include an alpha channel.
+ * 3 - Apply alpha blend to both the RGB and alpha portions of the pixel.
+ *
+ * Alpha-blended vectors are not currently supported.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_alpha_operation (int alpha_operation, int alpha_type, int channel,
+ int apply_alpha, unsigned char alpha)
+{
+ gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE;
+
+ /* THE AVAILABLE ALPHA DEFINITIONS FOLLOW THE HARDWARE */
+ /* This allows us to avoid giant switch structures, but it */
+ /* also implies that there is no mechanism to detect invalid */
+ /* parameters. */
+
+ gp3_raster_mode = gp3_bpp | (unsigned long)alpha |
+ ((unsigned long)apply_alpha << 22) |
+ ((unsigned long)alpha_operation << 20) |
+ ((unsigned long)alpha_type << 17) |
+ ((unsigned long)channel << 16);
+
+ WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_raster_mode);
+
+ /* CHECK IF DESTINATION IS REQUIRED */
+
+ if ( (alpha_operation == CIMGP_ALPHA_TIMES_A &&
+ channel == CIMGP_CHANNEL_A_SOURCE &&
+ alpha_type != CIMGP_CHANNEL_B_ALPHA &&
+ alpha_type != CIMGP_ALPHA_FROM_RGB_B) ||
+ (alpha_operation == CIMGP_BETA_TIMES_B &&
+ channel == CIMGP_CHANNEL_A_DEST &&
+ alpha_type != CIMGP_CHANNEL_A_ALPHA &&
+ alpha_type != CIMGP_ALPHA_FROM_RGB_A))
+ {
+ gp3_blt_mode = 0;
+ }
+ else
+ gp3_blt_mode = GP3_BM_DST_REQ;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_solid_pattern
+ *
+ * This routine is called to program the hardware for a solid pattern. It need
+ * not be called for any other reason. As a side effect, this routine will
+ * clear any 8x8 pattern data.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_solid_pattern (unsigned long color)
+{
+ /* CHANNEL 3 IS NOT NEEDED FOR SOLID PATTERNS */
+
+ gp3_ch3_pat = 0;
+
+ /* SET SOLID PATTERN IN COMMAND BUFFER */
+ /* We are assuming that only one pattern type is ever set for a */
+ /* BLT. We are also assuming that gp_set_raster_operation will */
+ /* be called before this routine. With these assumptions, we */
+ /* will thus never have to change the raster mode register for */
+ /* solid patterns. */
+
+ if (gp3_blt)
+ {
+ gp3_cmd_header |= GP3_BLT_HDR_PAT_CLR0_ENABLE;
+
+ WRITE_COMMAND32 (GP3_BLT_PAT_COLOR_0, color);
+ }
+ else
+ {
+ gp3_cmd_header |= GP3_VEC_HDR_PAT_CLR0_ENABLE;
+
+ WRITE_COMMAND32 (GP3_VECTOR_PAT_COLOR_0, color);
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_mono_pattern
+ *
+ * This routine is called to program the hardware for a monochrome pattern.
+ * As a side effect, this routine will clear any 8x8 pattern data.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_mono_pattern (unsigned long bgcolor, unsigned long fgcolor,
+ unsigned long data0, unsigned long data1, int transparent, int x, int y)
+{
+ /* CHANNEL 3 IS NOT NEEDED FOR MONOCHROME PATTERNS */
+
+ gp3_ch3_pat = 0;
+
+ /* UPDATE RASTER MODE REGISTER */
+
+ if (transparent) gp3_raster_mode |= GP3_RM_PAT_MONO | GP3_RM_PAT_TRANS;
+ else gp3_raster_mode |= GP3_RM_PAT_MONO;
+
+ gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE;
+
+ WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_raster_mode);
+
+ /* SET MONOCHROME PATTERN DATA AND COLORS */
+
+ if (gp3_blt)
+ {
+ gp3_cmd_header |= (GP3_BLT_HDR_PAT_CLR0_ENABLE | GP3_BLT_HDR_PAT_CLR1_ENABLE |
+ GP3_BLT_HDR_PAT_DATA0_ENABLE | GP3_BLT_HDR_PAT_DATA1_ENABLE);
+
+ WRITE_COMMAND32 (GP3_BLT_PAT_COLOR_0, bgcolor);
+ WRITE_COMMAND32 (GP3_BLT_PAT_COLOR_1, fgcolor);
+ WRITE_COMMAND32 (GP3_BLT_PAT_DATA_0, data0);
+ WRITE_COMMAND32 (GP3_BLT_PAT_DATA_1, data1);
+ }
+ else
+ {
+ gp3_cmd_header |= (GP3_VEC_HDR_PAT_CLR0_ENABLE | GP3_VEC_HDR_PAT_CLR1_ENABLE |
+ GP3_VEC_HDR_PAT_DATA0_ENABLE | GP3_VEC_HDR_PAT_DATA1_ENABLE);
+
+ WRITE_COMMAND32 (GP3_VECTOR_PAT_COLOR_0, bgcolor);
+ WRITE_COMMAND32 (GP3_VECTOR_PAT_COLOR_1, fgcolor);
+ WRITE_COMMAND32 (GP3_VECTOR_PAT_DATA_0, data0);
+ WRITE_COMMAND32 (GP3_VECTOR_PAT_DATA_1, data1);
+ }
+
+ /* SAVE PATTERN ORIGIN */
+
+ gp3_pat_origin = ((unsigned long)y << 29) | (((unsigned long)x & 7) << 26);
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_pattern_origin
+ *
+ * This routine overrides the pattern origins set in gp_set_mono_pattern or
+ * gp_set_color_pattern. It is generally used to override the original
+ * pattern origin due to a change in clipping.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_pattern_origin (int x, int y)
+{
+ /* SAVE PATTERN ORIGIN */
+
+ gp3_pat_origin = ((unsigned long)y << 29) | (((unsigned long)x & 7) << 26);
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_color_pattern
+ *
+ * This routine is called to program a 8x8 color pattern into the LUT hardware.
+ * Unlike the other pattern routines, this routine must be called before
+ * any gp_declare_xxxx routines. The pattern that is programmed into the
+ * hardware will stay persistent for all subsequent primitives until one of
+ * the following conditions happens.
+ * - Another pattern type is programmed.
+ * - A color-conversion BLT rotation BLT.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_color_pattern (unsigned long *pattern, int format, int x, int y)
+{
+ unsigned long size_dwords, temp;
+
+ gp3_ch3_pat = 1;
+
+ /* SAVE COLOR PATTERN SOURCE INFO */
+ /* Color patterns can be in a format different than the primary display. */
+ /* 4BPP patterns are not supported. */
+
+ gp3_pat_pix_shift = (unsigned long)((format >> 2) & 3);
+ gp3_pat_format = (((unsigned long)format & 0xF) << 24) |
+ (((unsigned long)format & 0x10) << 17) |
+ GP3_CH3_COLOR_PAT_ENABLE |
+ GP3_CH3_C3EN;
+
+ size_dwords = (64 << gp3_pat_pix_shift) >> 2;
+
+ /* CHECK FOR WRAP AFTER LUT LOAD */
+ /* Primitive size is 12 plus the amount of data. */
+
+ gp3_cmd_next = gp3_cmd_current + (size_dwords << 2) + 12;
+
+ if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+ {
+ gp3_cmd_next = gp3_cmd_top;
+ gp3_cmd_header = GP3_LUT_HDR_TYPE | GP3_LUT_HDR_WRAP | GP3_LUT_HDR_DATA_ENABLE;
+
+ /* WAIT FOR HARDWARE */
+ /* Same logic as BLT wrapping. */
+
+ GP3_WAIT_WRAP(temp);
+ }
+ else
+ {
+ gp3_cmd_header = GP3_LUT_HDR_TYPE | GP3_LUT_HDR_DATA_ENABLE;
+
+ /* WAIT FOR AVAILABLE SPACE */
+
+ GP3_WAIT_PRIMITIVE(temp);
+ }
+
+ /* SAVE CURRENT BUFFER POINTER */
+
+ cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+ /* PREPARE FOR COMMAND BUFFER DATA WRITES */
+ /* Pattern data is contiguous DWORDs at LUT address 0x100 */
+
+ WRITE_COMMAND32 (0, gp3_cmd_header);
+ WRITE_COMMAND32 (4, 0x100);
+ WRITE_COMMAND32 (8, size_dwords | GP3_LUT_DATA_TYPE);
+
+ /* WRITE ALL DATA */
+
+ WRITE_COMMAND_STRING32 (12, pattern, 0, size_dwords);
+
+ /* START OPERATION */
+
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+
+ /* SAVE PATTERN ORIGIN */
+
+ gp3_pat_origin = ((unsigned long)y << 29) | (((unsigned long)x & 7) << 26);
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_mono_source
+ *
+ * This routine is called to program the colors for monochrome source data.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_mono_source (unsigned long bgcolor, unsigned long fgcolor,
+ int transparent)
+{
+ /* UPDATE RASTER MODE REGISTER IF TRANSPARENT */
+
+ if (transparent)
+ {
+ gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE;
+ gp3_raster_mode |= GP3_RM_SRC_TRANS;
+
+ WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_raster_mode);
+ }
+
+ /* SET MONOCHROME SOURCE COLORS */
+ /* Note that this routine only sets the colors. The actual */
+ /* source type is determined by the final output routine */
+ /* (gp_mono_bitmap_xxx, gp_color_bitmap_xxx, etc.) */
+
+ gp3_cmd_header |= GP3_BLT_HDR_SRC_FG_ENABLE | GP3_BLT_HDR_SRC_BG_ENABLE;
+
+ WRITE_COMMAND32 (GP3_BLT_SRC_COLOR_FG, fgcolor);
+ WRITE_COMMAND32 (GP3_BLT_SRC_COLOR_BG, bgcolor);
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_solid_source
+ *
+ * This routine is called to program a solid source color. A solid source
+ * color is used primarily for vectors or antialiased text.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_solid_source (unsigned long color)
+{
+ /* SET SOLID SOURCE COLOR */
+ /* The solid source register is in the same place for both BLTs and */
+ /* vectors. */
+
+ gp3_cmd_header |= GP3_BLT_HDR_SRC_FG_ENABLE;
+
+ WRITE_COMMAND32 (GP3_BLT_SRC_COLOR_FG, color);
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_source_transparency
+ *
+ * This routine sets the source transparency and mask to be used in future
+ * rendering operations. Transparency is cleared by gp_set_raster_operation,
+ * so this routine should never be called first.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_source_transparency (unsigned long color, unsigned long mask)
+{
+ gp3_raster_mode |= GP3_RM_SRC_TRANS;
+ gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE | GP3_BLT_HDR_SRC_FG_ENABLE |
+ GP3_BLT_HDR_SRC_BG_ENABLE;
+
+ WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_raster_mode);
+ WRITE_COMMAND32 (GP3_BLT_SRC_COLOR_FG, color);
+ WRITE_COMMAND32 (GP3_BLT_SRC_COLOR_BG, mask);
+}
+
+/*---------------------------------------------------------------------------
+ * gp_program_lut
+ *
+ * This routine is called to program the hardware LUT with color-conversion
+ * information. This routine should be called before any gp_declare_xxxx
+ * routines.
+ *
+ * colors - Pointer to an array of DWORDs for color expansion.
+ *
+ * full_lut - Selector between 4BPP and 8BPP expansion. The hardware is
+ * initialized with 16 dwords for 4BPP expansion and 256 dwords
+ * for 8BPP expansion.
+ *-------------------------------------------------------------------------*/
+
+void gp_program_lut (unsigned long *colors, int full_lut)
+{
+ unsigned long size_dwords, temp;
+
+ /* SIZE IS EITHER 16 DWORDS (4BPP) or 256 DWORDS (8BPP) */
+
+ if (full_lut) size_dwords = 256;
+ else size_dwords = 16;
+
+ /* CHECK FOR WRAP AFTER LUT LOAD */
+ /* Primitive size is 12 plus the amount of data. */
+
+ gp3_cmd_next = gp3_cmd_current + (size_dwords << 2) + 12;
+
+ if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+ {
+ gp3_cmd_next = gp3_cmd_top;
+ gp3_cmd_header = GP3_LUT_HDR_TYPE | GP3_LUT_HDR_WRAP | GP3_LUT_HDR_DATA_ENABLE;
+
+ /* WAIT FOR HARDWARE */
+ /* Same logic as BLT wrapping. */
+
+ GP3_WAIT_WRAP(temp);
+ }
+ else
+ {
+ gp3_cmd_header = GP3_LUT_HDR_TYPE | GP3_LUT_HDR_DATA_ENABLE;
+
+ /* WAIT FOR AVAILABLE SPACE */
+
+ GP3_WAIT_PRIMITIVE(temp);
+ }
+
+ /* SAVE CURRENT BUFFER POINTER */
+
+ cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+ /* PREPARE FOR COMMAND BUFFER DATA WRITES */
+ /* Pattern data is contiguous DWORDs at LUT address 0 */
+
+ WRITE_COMMAND32 (0, gp3_cmd_header);
+ WRITE_COMMAND32 (4, 0);
+ WRITE_COMMAND32 (8, (size_dwords | GP3_LUT_DATA_TYPE));
+
+ /* WRITE ALL DATA */
+
+ WRITE_COMMAND_STRING32 (12, colors, 0, size_dwords);
+
+ /* START OPERATION */
+
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_vector_pattern
+ *
+ * This routine is called to program the hardware LUT with a vector pattern.
+ * A vector pattern is programmed as a 32-bit mask that specifies a
+ * transparency pattern. A length parameter is used to specify patterns
+ * smaller than 32. Note that vectors in Geode LX do not continue across corners.
+ * The beginning of each vector will always begin with bit 0 of the vector
+ * pattern. It is the responsibility of the caller to update the pattern
+ * if an alternate behavior is desired.
+ *
+ * This routine faces the same restrictions of all routines that program
+ * the LUT, in that it must be called before any gp_declare_xxxx routines,
+ * it cannot be combined with an 8x8 color pattern, color conversion or
+ * rotation.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_vector_pattern (unsigned long pattern, unsigned long color, int length)
+{
+ unsigned long temp, mask;
+
+ gp3_ch3_pat = 1;
+ gp3_vector_pattern_color = color;
+
+ /* CREATE SUITABLE PATTERN MASK */
+ /* The GP requires a minimum of four pixels in a vector pattern. We */
+ /* can get around this restriction by doubling any patterns smaller */
+ /* than 4 pixels. */
+
+ while (length < 4)
+ {
+ mask = 0xFFFFFFFF >> (32 - length);
+ pattern = (pattern << length) | (pattern & mask);
+ length <<= 1;
+ }
+ mask = 0xFFFFFFFF >> (32 - length);
+
+ gp3_vec_pat = pattern;
+
+ /* CHECK FOR WRAP AFTER LUT LOAD */
+
+ gp3_cmd_next = gp3_cmd_current + GP3_VECTOR_PATTERN_COMMAND_SIZE;
+
+ if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+ {
+ gp3_cmd_next = gp3_cmd_top;
+ gp3_cmd_header = GP3_LUT_HDR_TYPE | GP3_LUT_HDR_WRAP | GP3_LUT_HDR_DATA_ENABLE;
+
+ /* WAIT FOR HARDWARE */
+ /* Same logic as BLT wrapping. */
+
+ GP3_WAIT_WRAP(temp);
+ }
+ else
+ {
+ gp3_cmd_header = GP3_LUT_HDR_TYPE | GP3_LUT_HDR_DATA_ENABLE;
+
+ /* WAIT FOR AVAILABLE SPACE */
+
+ GP3_WAIT_PRIMITIVE(temp);
+ }
+
+ /* SAVE CURRENT BUFFER POINTER */
+
+ cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+ /* PREPARE FOR COMMAND BUFFER DATA WRITES */
+ /* Pattern data is 2 DWORDs at 0x100 and 0x101 */
+
+ WRITE_COMMAND32 (0, gp3_cmd_header);
+ WRITE_COMMAND32 (4, 0x100);
+ WRITE_COMMAND32 (8, (2 | GP3_LUT_DATA_TYPE));
+ WRITE_COMMAND32 (12, pattern);
+ WRITE_COMMAND32 (16, mask);
+
+ /* START OPERATION */
+
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_strides
+ *
+ * This routine is called to program the pitch between successive lines of
+ * data in the frame buffer. The strides should be DWORD aligned and less
+ * than 64K. These restrictions are not checked by the API.
+ *-------------------------------------------------------------------------*/
+
+void gp_set_strides (unsigned long dst_stride, unsigned long src_stride)
+{
+ /* SAVE STRIDES */
+ /* The source stride may be needed later for channel 3 source data and */
+ /* we may need to use these strides in calculations. */
+
+ gp3_src_stride = src_stride;
+ gp3_dst_stride = dst_stride;
+
+ /* ENABLE STRIDES */
+ /* The stride register is in the same place for BLTs and vectors */
+
+ gp3_cmd_header |= GP3_BLT_HDR_STRIDE_ENABLE;
+
+ WRITE_COMMAND32 (GP3_BLT_STRIDE, ((src_stride << 16) | dst_stride));
+}
+
+/*---------------------------------------------------------------------------
+ * gp_set_source_format
+ *
+ * This routine is used to program the format of source data used in subsequent
+ * color-conversion or rotation operations. Note that 4BPP indexed and 8BPP
+ * indexed source formats cannot be used when rotating, as the LUT will be
+ * destroyed. These formats also cannot be combined with an 8x8 color pattern.
+ * The supported formats mirror the hardware and are described as follows:
+ *
+ * 0 - 8BPP 3:3:2
+ * 1 - 8BPP indexed
+ * 4 - 16BPP 4:4:4:4
+ * 5 - 16BPP 1:5:5:5
+ * 6 - 16BPP 5:6:5
+ * 7 - 16BPP YUV
+ * 8 - 32BPP 8:8:8:8
+ * 13 - 4BPP indexed
+ * 20 - 16BPP 4:4:4:4 BGR
+ * 21 - 16BPP 1:5:5:5 BGR
+ * 22 - 16BPP 0:5:6:5 BGR
+ * 24 - 32BPP 8:8:8:8 BGR
+ *-------------------------------------------------------------------------*/
+
+void gp_set_source_format (int format)
+{
+ /* SAVE FORMAT */
+ /* We will combine the source format later when doing color conversion. */
+ /* We also save the pixel size for host source calculations. */
+ /* Conveniently, the source formats are organized such that the upper */
+ /* two bits of the nibble represent the pixel shift, with a pixel shift */
+ /* of 3 being a special case for 4BPP data. Clever, yes? Even more */
+ /* clever, bit 4 indicates BGR ordering. */
+
+ gp3_src_pix_shift = (unsigned long)((format >> 2) & 3);
+ gp3_src_format = (((unsigned long)format & 0xF) << 24) |
+ (((unsigned long)format & 0x10) << 18);
+}
+
+/*---------------------------------------------------------------------------
+ * gp_pattern_fill
+ *
+ * This routine is called to perform a simple pattern fill. The pattern
+ * can be solid, monochrome or a preprogrammed 8x8 color pattern. If
+ * the ROP involves source data, that source data will be constant.
+ *-------------------------------------------------------------------------*/
+
+void gp_pattern_fill (unsigned long dstoffset, unsigned long width, unsigned long height)
+{
+ unsigned long base_register;
+
+ base_register = (gp3_base_register & ~GP3_BASE_OFFSET_DSTMASK) |
+ ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000));
+
+ /* ENABLE RELEVANT REGISTERS */
+ /* Note that we always enable and write the channel 3 mode, if only */
+ /* to turn it off. Cimarron also always writes the base offset */
+ /* register to allow operation with frame buffers larger than 16MB. */
+
+ gp3_cmd_header |= GP3_BLT_HDR_DST_OFF_ENABLE |
+ GP3_BLT_HDR_WIDHI_ENABLE |
+ GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+ GP3_BLT_HDR_CH3_STR_ENABLE |
+ GP3_BLT_HDR_CH3_WIDHI_ENABLE |
+ GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+ /* WRITE THE REGISTERS COMMON TO ALL PATTERN TYPES */
+ /* The destination base is the frame buffer base plus whatever */
+ /* 4MB segment we happen to be BLTing to. */
+
+ WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, ((width << 16) | height));
+ WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base_register);
+
+ /* CHECK 8X8 COLOR PATTERN CASE */
+
+ if (gp3_ch3_pat)
+ {
+ /* SET CHANNEL 3 PATTERN ORIGINS */
+
+ gp3_cmd_header |= GP3_BLT_HDR_CH3_OFF_ENABLE;
+
+ /* INITIALIZE CHANNEL 3 PARAMETERS */
+
+ WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, ((width << 16) | height));
+ WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, gp3_pat_origin);
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, dstoffset & 0x3FFFFF);
+ WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, gp3_pat_format);
+ }
+ else
+ {
+ /* DISABLE CHANNEL 3 AND USE NORMAL PATTERN ORIGINS */
+
+ WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, 0);
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, ((dstoffset & 0x3FFFFF) | gp3_pat_origin));
+ }
+
+ /* START THE BLT */
+
+ WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+ WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode);
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_screen_to_screen_blt
+ *
+ * This routine is called to perform a BLT from one location inside video
+ * memory to another location inside video memory. The source and destination
+ * formats are assumed to be the current BPP. Whenever possible, this routine
+ * tries to use channel 3 to fetch source data. The BLT flags can affect this
+ * behavior in the following ways:
+ * CIMGP_BLTFLAGS_PRES_COLOR_PAT
+ * A color pattern is being stored in the channel 3 buffer. It is either
+ * being stored for a later BLT or being combined with the current source
+ * data. Channel 3 cannot be used to fetch source data or the pattern
+ * will be overwritten.
+ * CIMGP_BLTFLAGS_PRES_LUT
+ * If the first flag is not set, this flag will limit the use of the
+ * channel 3 buffer to 1K.
+ *-------------------------------------------------------------------------*/
+
+void gp_screen_to_screen_blt (unsigned long dstoffset, unsigned long srcoffset,
+ unsigned long width, unsigned long height, int flags)
+{
+ unsigned long base;
+ unsigned long ch3_flags = 0;
+ unsigned long blt_mode = gp3_blt_mode;
+ unsigned long size = ((width << 16) | height);
+ unsigned long dstbase, srcbase;
+
+ /* CALCULATE BASE OFFSETS */
+ /* We need to set the 4MB aligned base offsets before we add offsets */
+ /* for negative BLTs. */
+
+ srcbase = srcoffset & 0xFFC00000;
+ dstbase = dstoffset & 0xFFC00000;
+ srcoffset &= 0x3FFFFF;
+ dstoffset &= 0x3FFFFF;
+
+ /* ADJUST OFFSETS BASED ON FLAGS */
+ /* We adjust the source and destination offsets to point to the first */
+ /* byte of the first pixel of the BLT. This routine assumes that the */
+ /* source and destination regions do not wrap past the end of a 16MB */
+ /* region. */
+
+ if (flags & CIMGP_NEGXDIR)
+ {
+ srcoffset += (width << gp3_pix_shift) - 1;
+ dstoffset += (width << gp3_pix_shift) - 1;
+ blt_mode |= GP3_BM_NEG_XDIR;
+ ch3_flags |= GP3_CH3_NEG_XDIR;
+ }
+ if (flags & CIMGP_NEGYDIR)
+ {
+ srcoffset += (height - 1) * gp3_src_stride;
+ dstoffset += (height - 1) * gp3_dst_stride;
+ blt_mode |= GP3_BM_NEG_YDIR;
+ ch3_flags |= GP3_CH3_NEG_YDIR;
+ }
+
+ /* BRANCH BASED ON CHANNEL 3 */
+ /* If a color pattern is not being saved or used, channel 3 will */
+ /* be used to fetch source for maximum throughput. Channel 3 */
+ /* is not used if transparency or alpha blending is enabled. */
+
+ if (!(gp3_blt_flags & CIMGP_BLTFLAGS_PRES_COLOR_PAT) &&
+ !(gp3_raster_mode & GP3_RM_SRC_TRANS) &&
+ !(flags & CIMGP_NEGYDIR))
+ {
+ base = ((gp3_fb_base << 24) + dstbase) |
+ ((gp3_fb_base << 4) + (srcbase >> 20)) |
+ (gp3_base_register & GP3_BASE_OFFSET_SRCMASK);
+
+ gp3_cmd_header |= GP3_BLT_HDR_DST_OFF_ENABLE |
+ GP3_BLT_HDR_WIDHI_ENABLE |
+ GP3_BLT_HDR_CH3_STR_ENABLE |
+ GP3_BLT_HDR_CH3_WIDHI_ENABLE |
+ GP3_BLT_HDR_CH3_OFF_ENABLE |
+ GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+ GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, (dstoffset | gp3_pat_origin));
+ WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, srcoffset);
+ WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
+ WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, size);
+ WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+ WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
+ GP3_CH3_C3EN |
+ GP3_CH3_REPLACE_SOURCE |
+ gp3_ch3_bpp |
+ gp3_src_stride |
+ ch3_flags |
+ ((gp3_blt_flags & CIMGP_ENABLE_PREFETCH) << 17) |
+ ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20));
+ }
+ else
+ {
+ /* CALCULATE BASE OFFSET REGISTER */
+
+ base = ((gp3_fb_base << 24) + dstbase) |
+ ((gp3_fb_base << 14) + (srcbase >> 10)) |
+ (gp3_base_register & GP3_BASE_OFFSET_CH3MASK);
+
+ /* PROGRAM THE NORMAL SOURCE CHANNEL REGISTERS */
+ /* We assume that a color pattern is being ROPed with source */
+ /* data if the pattern type is color and the preserve pattern */
+ /* was set. */
+
+ blt_mode |= GP3_BM_SRC_FB;
+
+ gp3_cmd_header |= GP3_BLT_HDR_SRC_OFF_ENABLE |
+ GP3_BLT_HDR_DST_OFF_ENABLE |
+ GP3_BLT_HDR_WIDHI_ENABLE |
+ GP3_BLT_HDR_CH3_WIDHI_ENABLE |
+ GP3_BLT_HDR_CH3_STR_ENABLE |
+ GP3_BLT_HDR_CH3_OFF_ENABLE |
+ GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+ GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+ if (gp3_ch3_pat)
+ {
+ WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, gp3_pat_origin);
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, dstoffset);
+ WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, gp3_pat_format | ch3_flags);
+ WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, size);
+ }
+ else
+ {
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, dstoffset | gp3_pat_origin);
+ WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, 0);
+ }
+
+ WRITE_COMMAND32 (GP3_BLT_SRC_OFFSET, srcoffset);
+ WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
+ WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+ }
+
+ /* START THE BLT */
+
+ WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+ WRITE_COMMAND32 (GP3_BLT_MODE, blt_mode);
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_screen_to_screen_convert
+ *
+ * This routine is called to color-convert a rectangular region of the frame
+ * buffer into the current BPP. The format of the source region is programmed
+ * by gp_set_source_format.
+ *-------------------------------------------------------------------------*/
+
+void gp_screen_to_screen_convert (unsigned long dstoffset, unsigned long srcoffset,
+ unsigned long width, unsigned long height, int nibble)
+{
+ unsigned long size = ((width << 16) | height);
+ unsigned long ch3_offset = srcoffset & 0x3FFFFF;
+ unsigned long ch3_size, base;
+
+ base = ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)) |
+ ((gp3_fb_base << 4) + ((srcoffset & 0xFFC00000) >> 20)) |
+ (gp3_base_register & GP3_BASE_OFFSET_SRCMASK);
+
+ /* SET NIBBLE FOR 4BPP */
+ /* 4BPP is a special case in that it requires subpixel addressing. The */
+ /* user must supply this information via the nibble parameter. This */
+ /* parameter is ignored for every other source format. */
+
+ ch3_size = size;
+ if (gp3_src_pix_shift == 3)
+ ch3_offset |= ((nibble & 1) << 25);
+ else if ((gp3_src_format & GP3_CH3_SRC_MASK) == GP3_CH3_SRC_24BPP_PACKED)
+ ch3_size = ((((width * 3) + 3) >> 2) << 16) | height;
+
+ /* SET APPROPRIATE ENABLES */
+
+ gp3_cmd_header |= GP3_BLT_HDR_DST_OFF_ENABLE |
+ GP3_BLT_HDR_WIDHI_ENABLE |
+ GP3_BLT_HDR_CH3_OFF_ENABLE |
+ GP3_BLT_HDR_CH3_STR_ENABLE |
+ GP3_BLT_HDR_CH3_WIDHI_ENABLE |
+ GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+ GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+ /* WRITE ALL BLT REGISTERS */
+
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF) | gp3_pat_origin);
+ WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
+ WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, ch3_size);
+ WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, ch3_offset);
+ WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
+ GP3_CH3_C3EN |
+ GP3_CH3_REPLACE_SOURCE |
+ gp3_src_format |
+ ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20) |
+ ((gp3_blt_flags & CIMGP_ENABLE_PREFETCH) << 17) |
+ gp3_src_stride);
+ WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+
+ /* START THE BLT */
+
+ WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+ WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode);
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_color_bitmap_to_screen_blt
+ *
+ * This routine is called to BLT data from system memory into the frame buffer.
+ * 'srcy' is deliberately omitted to prevent extra calculations for simple
+ * applications that have no source indexes.
+ *-------------------------------------------------------------------------*/
+
+void gp_color_bitmap_to_screen_blt (unsigned long dstoffset, unsigned long srcx,
+ unsigned long width, unsigned long height, unsigned char *data, long pitch)
+{
+ unsigned long indent, temp;
+ unsigned long total_dwords, size_dwords;
+ unsigned long dword_count, byte_count;
+ unsigned long size = ((width << 16) | height);
+ unsigned long srcoffset;
+
+ /* ASSUME BITMAPS ARE DWORD ALIGNED */
+ /* We will offset into the source data in DWORD increments. We */
+ /* set the source index to the remaining byte offset and */
+ /* increment the size of each line to account for the dont-care */
+ /* pixel(s). */
+
+ indent = srcx << gp3_pix_shift;
+ srcoffset = (indent & ~3L);
+ indent &= 3;
+
+ /* PROGRAM THE NORMAL SOURCE CHANNEL REGISTERS */
+ /* We assume that a color pattern is being ROPed with source */
+ /* data if the pattern type is color and the preserve pattern */
+ /* was set. */
+
+ gp3_cmd_header |= GP3_BLT_HDR_SRC_OFF_ENABLE |
+ GP3_BLT_HDR_DST_OFF_ENABLE |
+ GP3_BLT_HDR_WIDHI_ENABLE |
+ GP3_BLT_HDR_CH3_STR_ENABLE |
+ GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+ GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+ if (gp3_ch3_pat)
+ {
+ gp3_cmd_header |= GP3_BLT_HDR_CH3_OFF_ENABLE | GP3_BLT_HDR_CH3_WIDHI_ENABLE;
+
+ WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, gp3_pat_origin);
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF));
+ WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, gp3_pat_format);
+ WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, size);
+ }
+ else
+ {
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, ((dstoffset & 0x3FFFFF) | gp3_pat_origin));
+ WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, 0);
+ }
+
+ WRITE_COMMAND32 (GP3_BLT_SRC_OFFSET, indent);
+ WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
+ WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET,
+ ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)));
+ WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode | GP3_BM_SRC_HOST);
+
+ /* START THE BLT */
+
+ WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+
+ /* CALCULATE THE SIZE OF ONE LINE */
+
+ size = (width << gp3_pix_shift) + indent;
+ total_dwords = (size + 3) >> 2;
+ size_dwords = (total_dwords << 2) + 8;
+ dword_count = (size >> 2);
+ byte_count = (size & 3);
+
+ /* CHECK FOR SMALL BLT CASE */
+
+ if (((total_dwords << 2) * height) <= GP3_BLT_1PASS_SIZE &&
+ (gp3_cmd_bottom - gp3_cmd_current) > (GP3_BLT_1PASS_SIZE + 72))
+ {
+ /* UPDATE THE COMMAND POINTER */
+
+ cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+ /* CHECK IF A WRAP WILL BE NEEDED */
+
+ gp3_cmd_next = gp3_cmd_current + ((total_dwords << 2) * height) + 8;
+
+ if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+ {
+ gp3_cmd_next = gp3_cmd_top;
+
+ GP3_WAIT_WRAP(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+ GP3_DATA_LOAD_HDR_ENABLE);
+ }
+ else
+ {
+ GP3_WAIT_PRIMITIVE(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+ }
+
+ /* WRITE DWORD COUNT */
+
+ WRITE_COMMAND32 (4, GP3_HOST_SOURCE_TYPE | (total_dwords * height));
+
+ while (height--)
+ {
+ /* WRITE DATA */
+
+ WRITE_COMMAND_STRING32 (8, data, srcoffset, dword_count);
+ WRITE_COMMAND_STRING8 (8 + (dword_count << 2), data,
+ srcoffset + (dword_count << 2), byte_count);
+
+ srcoffset += pitch;
+ cim_cmd_ptr += total_dwords << 2;
+ }
+
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+ }
+ else
+ {
+ /* WRITE DATA LINE BY LINE */
+ /* Each line will be created as a separate command buffer entry to allow */
+ /* line-by-line wrapping and to allow simultaneous rendering by the HW. */
+
+ while (height--)
+ {
+ /* UPDATE THE COMMAND POINTER */
+ /* The WRITE_COMMANDXX macros use a pointer to the current buffer space. */
+ /* This is created by adding gp3_cmd_current to the base pointer. */
+
+ cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+ /* CHECK IF A WRAP WILL BE NEEDED */
+
+ gp3_cmd_next = gp3_cmd_current + size_dwords;
+ if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+ {
+ gp3_cmd_next = gp3_cmd_top;
+
+ /* WAIT FOR HARDWARE */
+
+ GP3_WAIT_WRAP(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+ GP3_DATA_LOAD_HDR_ENABLE);
+ }
+ else
+ {
+ /* WAIT FOR AVAILABLE SPACE */
+
+ GP3_WAIT_PRIMITIVE(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+ }
+
+ /* WRITE DWORD COUNT */
+
+ WRITE_COMMAND32 (4, GP3_HOST_SOURCE_TYPE | total_dwords);
+
+ /* WRITE DATA */
+
+ WRITE_COMMAND_STRING32 (8, data, srcoffset, dword_count);
+ WRITE_COMMAND_STRING8 (8 + (dword_count << 2), data,
+ srcoffset + (dword_count << 2), byte_count);
+
+ /* UPDATE POINTERS */
+
+ srcoffset += pitch;
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * gp_color_convert_blt
+ *
+ * This routine is called to convert data that is stored in system memory
+ * into the current graphics BPP. The source format is programmed in
+ * gp_set_source_format.
+ *-------------------------------------------------------------------------*/
+
+void gp_color_convert_blt (unsigned long dstoffset, unsigned long srcx,
+ unsigned long width, unsigned long height, unsigned char *data, long pitch)
+{
+ unsigned long indent, temp;
+ unsigned long total_dwords, size_dwords;
+ unsigned long dword_count, byte_count;
+ unsigned long size = ((width << 16) | height);
+ unsigned long ch3_size;
+ unsigned long ch3_offset, srcoffset;
+ unsigned long base;
+
+ /* ASSUME BITMAPS ARE DWORD ALIGNED */
+ /* We will offset into the source data in DWORD increments. We */
+ /* set the source index to the remaining byte offset and */
+ /* increment the size of each line to account for the dont-care */
+ /* pixel(s). For 4BPP source data, we also set the appropriate */
+ /* nibble index. */
+
+ /* CALCULATE THE SIZE OF ONE LINE */
+
+ if ((gp3_src_format & GP3_CH3_SRC_MASK) == GP3_CH3_SRC_24BPP_PACKED)
+ {
+ /* HANDLE 24BPP */
+ /* Note that we do not do anything to guarantee that the source data */
+ /* is DWORD aligned. The logic here is that the source data will be */
+ /* cacheable, in which case Geode LX will not lose any clocks for unaligned */
+ /* moves. Also note that the channel 3 width is programmed as the */
+ /* number of dwords, while the normal width is programmed as the number */
+ /* of pixels. */
+
+ srcoffset = srcx * 3;
+ ch3_offset = 0;
+ temp = width * 3;
+ ch3_size = (((temp + 3) >> 2) << 16) | height;
+ }
+ else
+ {
+ ch3_size = size;
+
+ if (gp3_src_pix_shift == 3)
+ {
+ /* CALCULATE INDENT AND SOURCE OFFSET */
+
+ indent = (srcx >> 1);
+ srcoffset = (indent & ~3L);
+ indent &= 3;
+ ch3_offset = indent | ((srcx & 1) << 25);
+
+ temp = ((width + (srcx & 1) + 1) >> 1) + indent;
+ }
+ else
+ {
+ indent = (srcx << gp3_src_pix_shift);
+ srcoffset = (indent & ~3L);
+ indent &= 3;
+ ch3_offset = indent;
+
+ temp = (width << gp3_src_pix_shift) + indent;
+ }
+ }
+
+ total_dwords = (temp + 3) >> 2;
+ size_dwords = (total_dwords << 2) + 8;
+ dword_count = (temp >> 2);
+ byte_count = (temp & 3);
+
+ base = ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)) |
+ (gp3_base_register & ~GP3_BASE_OFFSET_DSTMASK);
+
+ /* SET APPROPRIATE ENABLES */
+
+ gp3_cmd_header |= GP3_BLT_HDR_DST_OFF_ENABLE |
+ GP3_BLT_HDR_WIDHI_ENABLE |
+ GP3_BLT_HDR_CH3_STR_ENABLE |
+ GP3_BLT_HDR_CH3_OFF_ENABLE |
+ GP3_BLT_HDR_CH3_WIDHI_ENABLE |
+ GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+ GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF) | gp3_pat_origin);
+ WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, ch3_offset);
+ WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
+ WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, ch3_size);
+ WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+ WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
+ GP3_CH3_C3EN |
+ GP3_CH3_REPLACE_SOURCE |
+ GP3_CH3_HST_SRC_ENABLE |
+ gp3_src_format |
+ ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20));
+ WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode);
+
+ /* START THE BLT */
+
+ WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+
+ if (((total_dwords << 2) * height) <= GP3_BLT_1PASS_SIZE &&
+ (gp3_cmd_bottom - gp3_cmd_current) > (GP3_BLT_1PASS_SIZE + 72))
+ {
+ /* UPDATE THE COMMAND POINTER */
+
+ cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+ /* CHECK IF A WRAP WILL BE NEEDED */
+
+ gp3_cmd_next = gp3_cmd_current + ((total_dwords << 2) * height) + 8;
+
+ if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+ {
+ gp3_cmd_next = gp3_cmd_top;
+
+ GP3_WAIT_WRAP(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+ GP3_DATA_LOAD_HDR_ENABLE);
+ }
+ else
+ {
+ GP3_WAIT_PRIMITIVE(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+ }
+
+ /* WRITE DWORD COUNT */
+
+ WRITE_COMMAND32 (4, GP3_CH3_HOST_SOURCE_TYPE | (total_dwords * height));
+
+ while (height--)
+ {
+ /* WRITE DATA */
+
+ WRITE_COMMAND_STRING32 (8, data, srcoffset, dword_count);
+ WRITE_COMMAND_STRING8 (8 + (dword_count << 2), data,
+ srcoffset + (dword_count << 2), byte_count);
+
+ srcoffset += pitch;
+ cim_cmd_ptr += total_dwords << 2;
+ }
+
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+ }
+ else
+ {
+ /* WRITE DATA LINE BY LINE */
+ /* Each line will be created as a separate command buffer entry to allow */
+ /* line-by-line wrapping and to allow simultaneous rendering by the HW. */
+
+ while (height--)
+ {
+ /* UPDATE THE COMMAND POINTER */
+ /* The WRITE_COMMANDXX macros use a pointer to the current buffer space. */
+ /* This is created by adding gp3_cmd_current to the base pointer. */
+
+ cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+ /* CHECK IF A WRAP WILL BE NEEDED */
+
+ gp3_cmd_next = gp3_cmd_current + size_dwords;
+ if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+ {
+ gp3_cmd_next = gp3_cmd_top;
+
+ /* WAIT FOR HARDWARE */
+
+ GP3_WAIT_WRAP(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+ GP3_DATA_LOAD_HDR_ENABLE);
+ }
+ else
+ {
+ /* WAIT FOR AVAILABLE SPACE */
+
+ GP3_WAIT_PRIMITIVE(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+ }
+
+ /* WRITE DWORD COUNT */
+
+ WRITE_COMMAND32 (4, GP3_CH3_HOST_SOURCE_TYPE | total_dwords);
+
+ /* WRITE DATA */
+
+ WRITE_COMMAND_STRING32 (8, data, srcoffset, dword_count);
+ WRITE_COMMAND_STRING8 (8 + (dword_count << 2), data,
+ srcoffset + (dword_count << 2), byte_count);
+
+ /* UPDATE POINTERS */
+
+ srcoffset += pitch;
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * gp_custom_convert_blt
+ *
+ * This routine is identical to gp_color_convert_blt, except that the macro
+ * to write data to the frame buffer has been replaced with a new macro. This
+ * allows a user to implement custom behavior when sending data, such as manually
+ * converting 24BPP to 32BPP, converting 2BPP to 4BPP or premultiplying alpha data.
+ *-------------------------------------------------------------------------*/
+
+void gp_custom_convert_blt (unsigned long dstoffset, unsigned long srcx,
+ unsigned long width, unsigned long height, unsigned char *data, long pitch)
+{
+ unsigned long indent, temp;
+ unsigned long total_dwords, size_dwords;
+ unsigned long dword_count, byte_count;
+ unsigned long size = ((width << 16) | height);
+ unsigned long ch3_offset, srcoffset;
+ unsigned long ch3_size, base;
+
+ /* ASSUME BITMAPS ARE DWORD ALIGNED */
+ /* We will offset into the source data in DWORD increments. We */
+ /* set the source index to the remaining byte offset and */
+ /* increment the size of each line to account for the dont-care */
+ /* pixel(s). For 4BPP source data, we also set the appropriate */
+ /* nibble index. */
+
+ /* CALCULATE THE SIZE OF ONE LINE */
+
+ if ((gp3_src_format & GP3_CH3_SRC_MASK) == GP3_CH3_SRC_24BPP_PACKED)
+ {
+ /* HANDLE 24BPP */
+ /* Note that we do not do anything to guarantee that the source data */
+ /* is DWORD aligned. The logic here is that the source data will be */
+ /* cacheable, in which case Geode LX will not lose any clocks for unaligned */
+ /* moves. Also note that the channel 3 width is programmed as the */
+ /* number of dwords, while the normal width is programmed as the number */
+ /* of pixels. */
+
+ srcoffset = srcx * 3;
+ ch3_offset = 0;
+ temp = width * 3;
+ ch3_size = (((temp + 3) >> 2) << 16) | height;
+ }
+ else
+ {
+ ch3_size = size;
+
+ if (gp3_src_pix_shift == 3)
+ {
+ /* CALCULATE INDENT AND SOURCE OFFSET */
+
+ indent = (srcx >> 1);
+ srcoffset = (indent & ~3L);
+ indent &= 3;
+ ch3_offset = indent | ((srcx & 1) << 25);
+
+ temp = ((width + (srcx & 1) + 1) >> 1) + indent;
+ }
+ else
+ {
+ indent = (srcx << gp3_src_pix_shift);
+ srcoffset = (indent & ~3L);
+ indent &= 3;
+ ch3_offset = indent;
+
+ temp = (width << gp3_src_pix_shift) + indent;
+ }
+ }
+
+ total_dwords = (temp + 3) >> 2;
+ size_dwords = (total_dwords << 2) + 8;
+ dword_count = (temp >> 2);
+ byte_count = (temp & 3);
+
+ base = ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)) |
+ (gp3_base_register & ~GP3_BASE_OFFSET_DSTMASK);
+
+ /* SET APPROPRIATE ENABLES */
+
+ gp3_cmd_header |= GP3_BLT_HDR_DST_OFF_ENABLE |
+ GP3_BLT_HDR_WIDHI_ENABLE |
+ GP3_BLT_HDR_CH3_STR_ENABLE |
+ GP3_BLT_HDR_CH3_OFF_ENABLE |
+ GP3_BLT_HDR_CH3_WIDHI_ENABLE |
+ GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+ GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF) | gp3_pat_origin);
+ WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, ch3_offset);
+ WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
+ WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, ch3_size);
+ WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+ WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
+ GP3_CH3_C3EN |
+ GP3_CH3_REPLACE_SOURCE |
+ GP3_CH3_HST_SRC_ENABLE |
+ gp3_src_format |
+ ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20));
+ WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode);
+
+ /* START THE BLT */
+
+ WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+
+ if (((total_dwords << 2) * height) <= GP3_BLT_1PASS_SIZE &&
+ (gp3_cmd_bottom - gp3_cmd_current) > (GP3_BLT_1PASS_SIZE + 72))
+ {
+ /* UPDATE THE COMMAND POINTER */
+
+ cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+ /* CHECK IF A WRAP WILL BE NEEDED */
+
+ gp3_cmd_next = gp3_cmd_current + ((total_dwords << 2) * height) + 8;
+
+ if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+ {
+ gp3_cmd_next = gp3_cmd_top;
+
+ GP3_WAIT_WRAP(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+ GP3_DATA_LOAD_HDR_ENABLE);
+ }
+ else
+ {
+ GP3_WAIT_PRIMITIVE(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+ }
+
+ /* WRITE DWORD COUNT */
+
+ WRITE_COMMAND32 (4, GP3_CH3_HOST_SOURCE_TYPE | (total_dwords * height));
+
+ while (height--)
+ {
+ /* WRITE DATA */
+
+ WRITE_CUSTOM_COMMAND_STRING32 (8, data, srcoffset, dword_count);
+ WRITE_CUSTOM_COMMAND_STRING8 (8 + (dword_count << 2), data,
+ srcoffset + (dword_count << 2), byte_count);
+
+ srcoffset += pitch;
+ cim_cmd_ptr += total_dwords << 2;
+ }
+
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+ }
+ else
+ {
+ /* WRITE DATA LINE BY LINE */
+ /* Each line will be created as a separate command buffer entry to allow */
+ /* line-by-line wrapping and to allow simultaneous rendering by the HW. */
+
+ while (height--)
+ {
+ /* UPDATE THE COMMAND POINTER */
+ /* The WRITE_COMMANDXX macros use a pointer to the current buffer space. */
+ /* This is created by adding gp3_cmd_current to the base pointer. */
+
+ cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+ /* CHECK IF A WRAP WILL BE NEEDED */
+
+ gp3_cmd_next = gp3_cmd_current + size_dwords;
+ if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+ {
+ gp3_cmd_next = gp3_cmd_top;
+
+ /* WAIT FOR HARDWARE */
+
+ GP3_WAIT_WRAP(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+ GP3_DATA_LOAD_HDR_ENABLE);
+ }
+ else
+ {
+ /* WAIT FOR AVAILABLE SPACE */
+
+ GP3_WAIT_PRIMITIVE(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+ }
+
+ /* WRITE DWORD COUNT */
+
+ WRITE_COMMAND32 (4, GP3_CH3_HOST_SOURCE_TYPE | total_dwords);
+
+ /* WRITE DATA */
+
+ WRITE_CUSTOM_COMMAND_STRING32 (8, data, srcoffset, dword_count);
+ WRITE_CUSTOM_COMMAND_STRING8 (8 + (dword_count << 2), data,
+ srcoffset + (dword_count << 2), byte_count);
+
+ /* UPDATE POINTERS */
+
+ srcoffset += pitch;
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * gp_rotate_blt
+ *
+ * This routine is called to rotate a rectangular area of video memory. The
+ * data may be color converted during the rotation. 'Degrees' must be a
+ * multiple of 90 and indicates a clockwise rotation. Width and height
+ * refer to the width and the height of the source. The output
+ * destinations will be equal to the rotated dimensions.
+ *-------------------------------------------------------------------------*/
+
+void gp_rotate_blt (unsigned long dstoffset, unsigned long srcoffset,
+ unsigned long width, unsigned long height, int degrees)
+{
+ unsigned long sizein, sizeout;
+ unsigned long ch3_flags;
+ unsigned long base;
+
+ base = ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)) |
+ ((gp3_fb_base << 4) + ((srcoffset & 0xFFC00000) >> 20)) |
+ (gp3_base_register & GP3_BASE_OFFSET_SRCMASK);
+
+ srcoffset &= 0x3FFFFF;
+ dstoffset &= 0x3FFFFF;
+
+ /* SET ROTATION PARAMETERS */
+
+ switch (degrees)
+ {
+ case 90:
+ srcoffset += (height - 1) * gp3_src_stride;
+ sizein = ((width << 16) | height);
+ sizeout = ((height << 16) | width);
+ ch3_flags = GP3_CH3_C3EN |
+ GP3_CH3_REPLACE_SOURCE |
+ GP3_CH3_ROTATE_ENABLE |
+ GP3_CH3_NEG_YDIR;
+ break;
+
+ case 180:
+ srcoffset += (height - 1) * gp3_src_stride;
+ srcoffset += (width << gp3_src_pix_shift) - 1;
+ sizein = sizeout = ((width << 16) | height);
+ ch3_flags = GP3_CH3_C3EN |
+ GP3_CH3_REPLACE_SOURCE |
+ GP3_CH3_NEG_YDIR |
+ GP3_CH3_NEG_XDIR;
+ break;
+
+ case 270:
+ srcoffset += (width << gp3_src_pix_shift) - 1;
+ sizein = ((width << 16) | height);
+ sizeout = ((height << 16) | width);
+ ch3_flags = GP3_CH3_C3EN |
+ GP3_CH3_REPLACE_SOURCE |
+ GP3_CH3_ROTATE_ENABLE |
+ GP3_CH3_NEG_XDIR;
+ break;
+
+ default:
+ sizein = sizeout = ((width << 16) | height);
+ ch3_flags = GP3_CH3_C3EN |
+ GP3_CH3_REPLACE_SOURCE;
+ break;
+ }
+
+ /* SET APPROPRIATE ENABLES */
+ /* We override the raster mode setting with a source */
+ /* copy ROP. */
+
+ gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE |
+ GP3_BLT_HDR_DST_OFF_ENABLE |
+ GP3_BLT_HDR_WIDHI_ENABLE |
+ GP3_BLT_HDR_CH3_OFF_ENABLE |
+ GP3_BLT_HDR_CH3_STR_ENABLE |
+ GP3_BLT_HDR_CH3_WIDHI_ENABLE |
+ GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+ GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+ /* WRITE ALL BLT REGISTERS */
+
+ WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_bpp | 0xCC);
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, dstoffset);
+ WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, sizeout);
+ WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, sizein);
+ WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, srcoffset);
+ WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
+ ch3_flags |
+ gp3_src_format |
+ ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20) |
+ ((gp3_blt_flags & CIMGP_ENABLE_PREFETCH) << 17) |
+ gp3_src_stride);
+ WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+
+ /* START THE BLT */
+
+ WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+ WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode);
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_mono_bitmap_to_screen_blt
+ *
+ * This routine expands and BLTs a monchrome bitmap that is stored in system
+ * memory into the framebuffer. 'data' points to an array of monochrome data.
+ * 'stride' indicates the pitch between successive lines of monochrome data.
+ * 'srcx' indicates the x coordinate within each line of blend data
+ * corresponding to the first pixel. A y coordinate for the source is
+ * deliberately omitted to avoid extra calculation for simple cases that have
+ * no y index. The calling program must adjust the data pointer accordingly.
+ *-------------------------------------------------------------------------*/
+
+void gp_mono_bitmap_to_screen_blt (unsigned long dstoffset, unsigned long srcx,
+ unsigned long width, unsigned long height, unsigned char *data, long stride)
+{
+ unsigned long indent, temp;
+ unsigned long total_dwords, size_dwords;
+ unsigned long dword_count, byte_count;
+ unsigned long size = ((width << 16) | height);
+ unsigned long srcoffset, src_value;
+
+ /* ASSUME BITMAPS ARE DWORD ALIGNED */
+ /* We will offset into the source data in DWORD increments. We */
+ /* set the source index to the remaining byte offset and */
+ /* increment the size of each line to account for the dont-care */
+ /* pixel(s). */
+
+ indent = (srcx >> 3);
+ srcoffset = (indent & ~3L);
+ indent &= 3;
+ src_value = (indent | ((srcx & 7) << 26));
+
+ /* PROGRAM THE NORMAL SOURCE CHANNEL REGISTERS */
+ /* We assume that a color pattern is being ROPed with source */
+ /* data if the pattern type is color and the preserve pattern */
+ /* was set. */
+
+ gp3_cmd_header |= GP3_BLT_HDR_SRC_OFF_ENABLE |
+ GP3_BLT_HDR_DST_OFF_ENABLE |
+ GP3_BLT_HDR_WIDHI_ENABLE |
+ GP3_BLT_HDR_CH3_STR_ENABLE |
+ GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+ GP3_BLT_HDR_RASTER_ENABLE |
+ GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+ if (gp3_ch3_pat)
+ {
+ gp3_cmd_header |= GP3_BLT_HDR_CH3_OFF_ENABLE | GP3_BLT_HDR_CH3_WIDHI_ENABLE;
+
+ WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, gp3_pat_origin);
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF));
+ WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, gp3_pat_format);
+ WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, size);
+ }
+ else
+ {
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, ((dstoffset & 0x3FFFFF) | gp3_pat_origin));
+ WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, 0);
+ }
+ if (gp3_blt_flags & CIMGP_BLTFLAGS_INVERTMONO)
+ {
+ WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_raster_mode | GP3_RM_SOURCE_INVERT);
+ }
+ else
+ {
+ WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_raster_mode & ~GP3_RM_SOURCE_INVERT);
+ }
+ WRITE_COMMAND32 (GP3_BLT_SRC_OFFSET, src_value);
+ WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
+ WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET,
+ ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)));
+ WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode | GP3_BM_SRC_HOST | GP3_BM_SRC_MONO);
+
+ /* START THE BLT */
+
+ WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+
+ /* CALCULATE THE SIZE OF ONE LINE */
+
+ size = ((width + (srcx & 7) + 7) >> 3) + indent;
+ total_dwords = (size + 3) >> 2;
+ size_dwords = (total_dwords << 2) + 8;
+ dword_count = (size >> 2);
+ byte_count = (size & 3);
+
+ /* CHECK FOR SMALL BLT CASE */
+ /* If the total amount of monochrome data is less than 50K and we have */
+ /* room in the command buffer, we will do all data writes in a single */
+ /* data packet. */
+
+ if (((total_dwords << 2) * height) <= GP3_BLT_1PASS_SIZE &&
+ (gp3_cmd_bottom - gp3_cmd_current) > (GP3_BLT_1PASS_SIZE + 72))
+ {
+ /* UPDATE THE COMMAND POINTER */
+
+ cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+ /* CHECK IF A WRAP WILL BE NEEDED */
+
+ gp3_cmd_next = gp3_cmd_current + ((total_dwords << 2) * height) + 8;
+
+ if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+ {
+ gp3_cmd_next = gp3_cmd_top;
+
+ GP3_WAIT_WRAP(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+ GP3_DATA_LOAD_HDR_ENABLE);
+ }
+ else
+ {
+ GP3_WAIT_PRIMITIVE(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+ }
+
+ /* WRITE DWORD COUNT */
+
+ WRITE_COMMAND32 (4, GP3_HOST_SOURCE_TYPE | (total_dwords * height));
+
+ while (height--)
+ {
+ /* WRITE DATA */
+
+ WRITE_COMMAND_STRING32 (8, data, srcoffset, dword_count);
+ WRITE_COMMAND_STRING8 (8 + (dword_count << 2), data,
+ srcoffset + (dword_count << 2), byte_count);
+
+ srcoffset += stride;
+ cim_cmd_ptr += total_dwords << 2;
+ }
+
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+ }
+ else
+ {
+ /* WRITE DATA LINE BY LINE */
+ /* Each line will be created as a separate command buffer entry to allow */
+ /* line-by-line wrapping and to allow simultaneous rendering by the HW. */
+
+ while (height--)
+ {
+ /* UPDATE THE COMMAND POINTER */
+ /* The WRITE_COMMANDXX macros use a pointer to the current buffer space. */
+ /* This is created by adding gp3_cmd_current to the base pointer. */
+
+ cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+ /* CHECK IF A WRAP WILL BE NEEDED */
+
+ gp3_cmd_next = gp3_cmd_current + size_dwords;
+ if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+ {
+ gp3_cmd_next = gp3_cmd_top;
+
+ /* WAIT FOR HARDWARE */
+
+ GP3_WAIT_WRAP(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+ GP3_DATA_LOAD_HDR_ENABLE);
+ }
+ else
+ {
+ /* WAIT FOR AVAILABLE SPACE */
+
+ GP3_WAIT_PRIMITIVE(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+ }
+
+ /* WRITE DWORD COUNT */
+
+ WRITE_COMMAND32 (4, GP3_HOST_SOURCE_TYPE | total_dwords);
+
+ /* WRITE DATA */
+
+ WRITE_COMMAND_STRING32 (8, data, srcoffset, dword_count);
+ WRITE_COMMAND_STRING8 (8 + (dword_count << 2), data,
+ srcoffset + (dword_count << 2), byte_count);
+
+ /* UPDATE POINTERS */
+
+ srcoffset += stride;
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * gp_text_blt
+ *
+ * This routine expands and BLTs byte-packed monochrome data to the screen.
+ * There is assumed to be no x clipping involved in the BLT.
+ *-------------------------------------------------------------------------*/
+
+void gp_text_blt (unsigned long dstoffset, unsigned long width,
+ unsigned long height, unsigned char *data)
+{
+ unsigned long temp, dwords_total;
+ unsigned long dword_count, byte_count;
+ unsigned long size = ((width << 16) | height);
+ unsigned long srcoffset = 0;
+
+ /* PROGRAM THE NORMAL SOURCE CHANNEL REGISTERS */
+ /* We assume that a color pattern is being ROPed with source */
+ /* data if the pattern type is color and the preserve pattern */
+ /* was set. */
+
+ gp3_cmd_header |= GP3_BLT_HDR_SRC_OFF_ENABLE |
+ GP3_BLT_HDR_DST_OFF_ENABLE |
+ GP3_BLT_HDR_WIDHI_ENABLE |
+ GP3_BLT_HDR_CH3_STR_ENABLE |
+ GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+ GP3_BLT_HDR_RASTER_ENABLE |
+ GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+ if (gp3_ch3_pat)
+ {
+ gp3_cmd_header |= GP3_BLT_HDR_CH3_OFF_ENABLE | GP3_BLT_HDR_CH3_WIDHI_ENABLE;
+
+ WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, gp3_pat_origin);
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF));
+ WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, gp3_pat_format);
+ WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, size);
+ }
+ else
+ {
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, ((dstoffset & 0x3FFFFF) | gp3_pat_origin));
+ WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, 0);
+ }
+ if (gp3_blt_flags & CIMGP_BLTFLAGS_INVERTMONO)
+ {
+ WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_raster_mode | GP3_RM_SOURCE_INVERT);
+ }
+ else
+ {
+ WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_raster_mode & ~GP3_RM_SOURCE_INVERT);
+ }
+
+ WRITE_COMMAND32 (GP3_BLT_SRC_OFFSET, 0);
+ WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
+ WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET,
+ ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)));
+ WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode | GP3_BM_SRC_HOST | GP3_BM_SRC_BP_MONO);
+
+ /* START THE BLT */
+
+ WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+
+ /* CALCULATE THE TOTAL NUMBER OF BYTES */
+
+ size = ((width + 7) >> 3) * height;
+
+ /* WRITE ALL DATA IN CHUNKS */
+
+ do
+ {
+ /* UPDATE THE COMMAND POINTER */
+
+ cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+ if (size > 8192)
+ {
+ dword_count = 2048;
+ byte_count = 0;
+ dwords_total = 2048;
+ size -= 8192;
+ }
+ else
+ {
+ dword_count = (size >> 2);
+ byte_count = (size & 3);
+ dwords_total = (size + 3) >> 2;
+ size = 0;
+ }
+ gp3_cmd_next = gp3_cmd_current + (dwords_total << 2) + 8;
+
+ /* CHECK IF A WRAP WILL BE NEEDED */
+
+ if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+ {
+ gp3_cmd_next = gp3_cmd_top;
+
+ /* WAIT FOR HARDWARE */
+
+ GP3_WAIT_WRAP(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+ GP3_DATA_LOAD_HDR_ENABLE);
+ }
+ else
+ {
+ /* WAIT FOR AVAILABLE SPACE */
+
+ GP3_WAIT_PRIMITIVE(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+ }
+
+ /* WRITE DWORD COUNT */
+
+ WRITE_COMMAND32 (4, GP3_HOST_SOURCE_TYPE | dwords_total);
+
+ /* WRITE DATA */
+
+ WRITE_COMMAND_STRING32 (8, data, srcoffset, dword_count);
+ WRITE_COMMAND_STRING8 (8 + (dword_count << 2), data,
+ srcoffset + (dword_count << 2), byte_count);
+
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+
+ /* UPDATE THE SOURCE OFFSET */
+ /* We add a constant value because the code will loop only if the */
+ /* data exceeds 8192 bytes. */
+
+ srcoffset += 8192;
+
+ } while (size);
+}
+
+/*---------------------------------------------------------------------------
+ * gp_mono_expand_blt
+ *
+ * This routine expands monochrome data that is stored in video memory into
+ * the current BPP. The source and destination regions are assumed not to
+ * overlap. The pitch of the source data is specified in gp_set_strides.
+ * 'srcy' is deliberately omitted to prevent extra calculations for simple
+ * applications that have no source indexes.
+ *-------------------------------------------------------------------------*/
+
+void gp_mono_expand_blt (unsigned long dstoffset, unsigned long srcoffset,
+ unsigned long srcx, unsigned long width, unsigned long height, int byte_packed)
+{
+ unsigned long base;
+ unsigned long blt_mode;
+ unsigned long size = ((width << 16) | height);
+
+ /* ADJUST SOURCE OFFSET */
+
+ srcoffset += (srcx >> 3);
+ srcx &= 7;
+
+ /* CALCULATE BASE OFFSET REGISTER */
+
+ base = ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)) |
+ ((gp3_fb_base << 14) + ((srcoffset & 0xFFC00000) >> 10)) |
+ (gp3_base_register & GP3_BASE_OFFSET_CH3MASK);
+
+ /* SET THE SOURCE TYPE */
+
+ if (byte_packed)
+ blt_mode = gp3_blt_mode | GP3_BM_SRC_FB | GP3_BM_SRC_BP_MONO;
+ else
+ blt_mode = gp3_blt_mode | GP3_BM_SRC_FB | GP3_BM_SRC_MONO;
+
+ /* SET HEADER ENABLES */
+
+ gp3_cmd_header |= GP3_BLT_HDR_SRC_OFF_ENABLE |
+ GP3_BLT_HDR_DST_OFF_ENABLE |
+ GP3_BLT_HDR_WIDHI_ENABLE |
+ GP3_BLT_HDR_CH3_STR_ENABLE |
+ GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+ GP3_BLT_HDR_RASTER_ENABLE |
+ GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+ /* ENABLE COLOR PATTERN IF APPLICABLE */
+
+ if (gp3_ch3_pat)
+ {
+ gp3_cmd_header |= GP3_BLT_HDR_CH3_OFF_ENABLE | GP3_BLT_HDR_CH3_WIDHI_ENABLE;
+
+ WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, gp3_pat_origin);
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF));
+ WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, gp3_pat_format);
+ WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, size);
+ }
+ else
+ {
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, ((dstoffset & 0x3FFFFF) | gp3_pat_origin));
+ WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR, 0);
+ }
+ if (gp3_blt_flags & CIMGP_BLTFLAGS_INVERTMONO)
+ {
+ WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_raster_mode | GP3_RM_SOURCE_INVERT);
+ }
+ else
+ {
+ WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_raster_mode & ~GP3_RM_SOURCE_INVERT);
+ }
+
+ WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+ WRITE_COMMAND32 (GP3_BLT_SRC_OFFSET,
+ (srcoffset & 0x3FFFFF) | (srcx << 26));
+ WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
+
+ /* WORKAROUND FOR SIBZ #3744 */
+ /* Under extremely rare conditions, very narrow byte-packed mono BLTs can hang */
+ /* the GP. Even under the rare case, the bad condition will only happen */
+ /* once every 16 lines. The workaround is to break the offending BLT into a */
+ /* a series of safer BLTs. This method is preferred over a two-pass approach */
+ /* because it does not require saving and restoring any GP state, such as the */
+ /* ROP or mono colors. */
+
+ if ((gp3_blt_mode & GP3_BM_DST_REQ) && byte_packed && (gp3_pix_shift < 2) &&
+ (width < 5) && ((srcoffset & 0x1F) == 0x1F) && ((srcx + width) > 8))
+ {
+ unsigned long dstoff1, size1, org1;
+ unsigned long dstoff2, size2, org2;
+ unsigned long tempheight;
+
+ size1 = ((8 - srcx) << 16) | 1;
+ size2 = ((width + srcx - 8) << 16) | 1;
+ org1 = gp3_pat_origin;
+ org2 = (org1 & 0xE0000000) | ((org1 + ((8 - srcx) << 26)) & 0x1C000000);
+ dstoff1 = dstoffset & 0x3FFFFF;
+ dstoff2 = (dstoff1 + 8 - srcx) << gp3_pix_shift;
+
+ while (height)
+ {
+ /* DIVIDE THE FIRST LINE INTO TWO SINGLE LINE BLTS */
+
+ WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size1);
+ WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, size1);
+ WRITE_COMMAND32 (GP3_BLT_SRC_OFFSET, (srcoffset & 0x3FFFFF) | (srcx << 26));
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, dstoff1 | org1);
+ WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, org1);
+ WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+ WRITE_COMMAND32 (GP3_BLT_MODE, blt_mode);
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+ gp_wait_until_idle();
+
+ gp_declare_blt (gp3_blt_flags);
+ gp3_cmd_header |= GP3_BLT_HDR_SRC_OFF_ENABLE |
+ GP3_BLT_HDR_DST_OFF_ENABLE |
+ GP3_BLT_HDR_WIDHI_ENABLE |
+ GP3_BLT_HDR_BLT_MODE_ENABLE |
+ GP3_BLT_HDR_CH3_OFF_ENABLE |
+ GP3_BLT_HDR_CH3_WIDHI_ENABLE;
+ WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size2);
+ WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, size2);
+ WRITE_COMMAND32 (GP3_BLT_SRC_OFFSET, ((srcoffset + 1) & 0x3FFFFF));
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, dstoff2 | org2);
+ WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, org2);
+ WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+ WRITE_COMMAND32 (GP3_BLT_MODE, blt_mode);
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+ gp_wait_until_idle();
+
+ if (--height)
+ {
+ org1 += 0x20000000;
+ org2 += 0x20000000;
+ dstoff1 += gp3_dst_stride;
+ dstoff2 += gp3_dst_stride;
+ srcoffset += 2;
+
+ /* THE NEXT 15 LINES ARE NOW 'SAFE' - THEY DO NOT SHOW THE PROBLEM */
+
+ tempheight = 15;
+ if (tempheight > height)
+ tempheight = height;
+
+ gp_declare_blt (gp3_blt_flags);
+ gp3_cmd_header |= GP3_BLT_HDR_SRC_OFF_ENABLE |
+ GP3_BLT_HDR_DST_OFF_ENABLE |
+ GP3_BLT_HDR_WIDHI_ENABLE |
+ GP3_BLT_HDR_BLT_MODE_ENABLE |
+ GP3_BLT_HDR_CH3_OFF_ENABLE |
+ GP3_BLT_HDR_CH3_WIDHI_ENABLE;
+ WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, (width << 16) | tempheight);
+ WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, (width << 16) | tempheight);
+ WRITE_COMMAND32 (GP3_BLT_SRC_OFFSET, (srcoffset & 0x3FFFFF) | (srcx << 26));
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, dstoff1 | org1);
+ WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, org1);
+ WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+ WRITE_COMMAND32 (GP3_BLT_MODE, blt_mode);
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+ gp_wait_until_idle();
+
+ height -= tempheight;
+
+ if (height)
+ {
+ gp_declare_blt (gp3_blt_flags);
+ gp3_cmd_header |= GP3_BLT_HDR_SRC_OFF_ENABLE |
+ GP3_BLT_HDR_DST_OFF_ENABLE |
+ GP3_BLT_HDR_WIDHI_ENABLE |
+ GP3_BLT_HDR_BLT_MODE_ENABLE |
+ GP3_BLT_HDR_CH3_OFF_ENABLE |
+ GP3_BLT_HDR_CH3_WIDHI_ENABLE;
+
+ /* ADJUST ORIGIN */
+ /* If we get here, we added a full 15 lines which is equivalent */
+ /* to subtracting one from the pattern y origin (adding 15). */
+
+ org1 -= 0x20000000;
+ org2 -= 0x20000000;
+ dstoff1 += (gp3_dst_stride * 15);
+ dstoff2 += (gp3_dst_stride * 15);
+ srcoffset += 30;
+ }
+ }
+ }
+ return;
+ }
+
+ /* START THE BLT */
+
+ WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+ WRITE_COMMAND32 (GP3_BLT_MODE, blt_mode);
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_antialiased_text
+ *
+ * This routine implements alpha blending between a constant source color and
+ * a destination region. The degree of the blend is controlled by an array
+ * of 4BPP/8BPP values specified in 'data'. 'stride' indicates the pitch between
+ * successive lines of blend data. 'srcx' indicates the x coordinate within
+ * each line of blend data corresponding to the first pixel. A y coordinate
+ * for the source is deliberately omitted to avoid extra calculation for simple
+ * cases that have no y index. The calling program must adjust the data
+ * pointer accordingly. 'fourbpp' selects between 4BPP and 8BPP alpha.
+ *-------------------------------------------------------------------------*/
+
+void gp_antialiased_text (unsigned long dstoffset, unsigned long srcx,
+ unsigned long width, unsigned long height, unsigned char *data, long stride,
+ int fourbpp)
+{
+ unsigned long indent, temp;
+ unsigned long total_dwords, size_dwords;
+ unsigned long dword_count, byte_count;
+ unsigned long size = ((width << 16) | height);
+ unsigned long ch3_offset, srcoffset;
+ unsigned long base, depth_flag;
+
+ base = ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)) |
+ (gp3_base_register & ~GP3_BASE_OFFSET_DSTMASK);
+
+ /* ENABLE ALL RELEVANT REGISTERS */
+ /* We override the raster mode register to force the */
+ /* correct alpha blend */
+
+ gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE |
+ GP3_BLT_HDR_DST_OFF_ENABLE |
+ GP3_BLT_HDR_WIDHI_ENABLE |
+ GP3_BLT_HDR_CH3_OFF_ENABLE |
+ GP3_BLT_HDR_CH3_STR_ENABLE |
+ GP3_BLT_HDR_CH3_WIDHI_ENABLE |
+ GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+ GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+ /* CALCULATIONS BASED ON ALPHA DEPTH */
+ /* Although most antialiased text is 4BPP, the hardware supports */
+ /* a full 8BPP. Either case is supported by this routine. */
+
+ if (fourbpp)
+ {
+ depth_flag = GP3_CH3_SRC_4BPP_ALPHA;
+ indent = (srcx >> 1);
+ srcoffset = (indent & ~3L);
+ indent &= 3;
+ ch3_offset = indent | ((srcx & 1) << 25);
+
+ temp = ((width + (srcx & 1) + 1) >> 1) + indent;
+ }
+ else
+ {
+ depth_flag = GP3_CH3_SRC_8BPP_ALPHA;
+ indent = srcx;
+ srcoffset = (indent & ~3L);
+ indent &= 3;
+ ch3_offset = indent;
+
+ temp = width + indent;
+ }
+
+ total_dwords = (temp + 3) >> 2;
+ size_dwords = (total_dwords << 2) + 8;
+ dword_count = (temp >> 2);
+ byte_count = (temp & 3);
+
+ /* SET RASTER MODE REGISTER */
+ /* Alpha blending will only apply to RGB when no alpha component is present. */
+ /* As 8BPP is not supported for this routine, the only alpha-less mode is */
+ /* 5:6:5. */
+
+ if (gp3_bpp == GP3_RM_BPPFMT_565)
+ {
+ WRITE_COMMAND32 (GP3_BLT_RASTER_MODE,
+ gp3_bpp |
+ GP3_RM_ALPHA_TO_RGB |
+ GP3_RM_ALPHA_A_PLUS_BETA_B |
+ GP3_RM_SELECT_ALPHA_CHAN_3);
+ }
+ else
+ {
+ WRITE_COMMAND32 (GP3_BLT_RASTER_MODE,
+ gp3_bpp |
+ GP3_RM_ALPHA_ALL |
+ GP3_RM_ALPHA_A_PLUS_BETA_B |
+ GP3_RM_SELECT_ALPHA_CHAN_3);
+ }
+
+ /* WRITE ALL REMAINING REGISTERS */
+
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF));
+ WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, ch3_offset);
+ WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
+ WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, size);
+ WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+ WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
+ GP3_CH3_C3EN |
+ GP3_CH3_HST_SRC_ENABLE |
+ depth_flag |
+ ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20));
+ WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode | GP3_BM_DST_REQ);
+
+ /* START THE BLT */
+
+ WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+
+ /* WRITE DATA LINE BY LINE */
+ /* Each line will be created as a separate command buffer entry to allow */
+ /* line-by-line wrapping and to allow simultaneous rendering by the HW. */
+
+ if (((total_dwords << 2) * height) <= GP3_BLT_1PASS_SIZE &&
+ (gp3_cmd_bottom - gp3_cmd_current) > (GP3_BLT_1PASS_SIZE + 72))
+ {
+ /* UPDATE THE COMMAND POINTER */
+
+ cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+ /* CHECK IF A WRAP WILL BE NEEDED */
+
+ gp3_cmd_next = gp3_cmd_current + ((total_dwords << 2) * height) + 8;
+
+ if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+ {
+ gp3_cmd_next = gp3_cmd_top;
+
+ GP3_WAIT_WRAP(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+ GP3_DATA_LOAD_HDR_ENABLE);
+ }
+ else
+ {
+ GP3_WAIT_PRIMITIVE(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+ }
+
+ /* WRITE DWORD COUNT */
+
+ WRITE_COMMAND32 (4, GP3_CH3_HOST_SOURCE_TYPE | (total_dwords * height));
+
+ while (height--)
+ {
+ /* WRITE DATA */
+
+ WRITE_COMMAND_STRING32 (8, data, srcoffset, dword_count);
+ WRITE_COMMAND_STRING8 (8 + (dword_count << 2), data,
+ srcoffset + (dword_count << 2), byte_count);
+
+ srcoffset += stride;
+ cim_cmd_ptr += total_dwords << 2;
+ }
+
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+ }
+ else
+ {
+ while (height--)
+ {
+ /* UPDATE THE COMMAND POINTER */
+ /* The WRITE_COMMANDXX macros use a pointer to the current buffer space. */
+ /* This is created by adding gp3_cmd_current to the base pointer. */
+
+ cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+ /* CHECK IF A WRAP WILL BE NEEDED */
+
+ gp3_cmd_next = gp3_cmd_current + size_dwords;
+ if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+ {
+ gp3_cmd_next = gp3_cmd_top;
+
+ /* WAIT FOR HARDWARE */
+
+ GP3_WAIT_WRAP(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+ GP3_DATA_LOAD_HDR_ENABLE);
+ }
+ else
+ {
+ /* WAIT FOR AVAILABLE SPACE */
+
+ GP3_WAIT_PRIMITIVE(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+ }
+
+ /* WRITE DWORD COUNT */
+
+ WRITE_COMMAND32 (4, GP3_CH3_HOST_SOURCE_TYPE | total_dwords);
+
+ /* WRITE DATA */
+
+ WRITE_COMMAND_STRING32 (8, data, srcoffset, dword_count);
+ WRITE_COMMAND_STRING8 (8 + (dword_count << 2), data,
+ srcoffset + (dword_count << 2), byte_count);
+
+ /* UPDATE POINTERS */
+
+ srcoffset += stride;
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * gp_masked_blt
+ *
+ * This routine copies source data to the screen. A monochrome mask is used
+ * to specify source transparency.
+ *-------------------------------------------------------------------------*/
+
+void gp_masked_blt (unsigned long dstoffset, unsigned long width,
+ unsigned long height, unsigned long mono_srcx, unsigned long color_srcx,
+ unsigned char *mono_mask, unsigned char *color_data, long mono_pitch,
+ long color_pitch)
+{
+ unsigned long indent, temp;
+ unsigned long total_dwords, size_dwords;
+ unsigned long dword_count, byte_count;
+ unsigned long srcoffset, size;
+ unsigned long i, ch3_offset, base;
+ unsigned long flags = 0;
+
+ if (gp3_blt_flags & CIMGP_BLTFLAGS_INVERTMONO)
+ flags = GP3_RM_SOURCE_INVERT;
+
+ /* MONO CALCULATIONS */
+
+ indent = (mono_srcx >> 3);
+ srcoffset = (indent & ~3L);
+ indent &= 3;
+
+ size = ((width + (mono_srcx & 7) + 7) >> 3) + indent;
+ total_dwords = (size + 3) >> 2;
+ size_dwords = (total_dwords << 2) + 8;
+ dword_count = (size >> 2);
+ byte_count = (size & 3);
+
+ base = ((gp3_fb_base << 24) + (gp3_scratch_base & 0xFFC00000)) |
+ (gp3_base_register & ~GP3_BASE_OFFSET_DSTMASK);
+
+ gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE |
+ GP3_BLT_HDR_STRIDE_ENABLE |
+ GP3_BLT_HDR_DST_OFF_ENABLE |
+ GP3_BLT_HDR_WIDHI_ENABLE |
+ GP3_BLT_HDR_CH3_STR_ENABLE |
+ GP3_BLT_HDR_CH3_OFF_ENABLE |
+ GP3_BLT_HDR_CH3_WIDHI_ENABLE |
+ GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+ GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+ WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, GP3_RM_BPPFMT_8888 | 0xCC);
+ WRITE_COMMAND32 (GP3_BLT_STRIDE, (total_dwords << 2));
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, gp3_scratch_base & 0x3FFFFF);
+ WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, (total_dwords << 16) | height);
+ WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, (total_dwords << 16) | height);
+ WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, 0);
+ WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+ WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
+ GP3_CH3_C3EN |
+ GP3_CH3_REPLACE_SOURCE |
+ GP3_CH3_HST_SRC_ENABLE |
+ GP3_CH3_SRC_8_8_8_8 |
+ ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20));
+ WRITE_COMMAND32 (GP3_BLT_MODE, 0);
+ WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+
+ /* START THE BLT */
+
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+
+ for (i = 0; i < height; i++)
+ {
+ /* UPDATE THE COMMAND POINTER */
+ /* The WRITE_COMMANDXX macros use a pointer to the current buffer space. */
+ /* This is created by adding gp3_cmd_current to the base pointer. */
+
+ cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+ /* CHECK IF A WRAP WILL BE NEEDED */
+
+ gp3_cmd_next = gp3_cmd_current + size_dwords;
+ if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+ {
+ gp3_cmd_next = gp3_cmd_top;
+
+ /* WAIT FOR HARDWARE */
+
+ GP3_WAIT_WRAP(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+ GP3_DATA_LOAD_HDR_ENABLE);
+ }
+ else
+ {
+ /* WAIT FOR AVAILABLE SPACE */
+
+ GP3_WAIT_PRIMITIVE(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+ }
+
+ /* WRITE DWORD COUNT */
+
+ WRITE_COMMAND32 (4, GP3_CH3_HOST_SOURCE_TYPE | total_dwords);
+
+ /* WRITE DATA */
+
+ WRITE_COMMAND_STRING32 (8, mono_mask, srcoffset, dword_count);
+ WRITE_COMMAND_STRING8 (8 + (dword_count << 2), mono_mask,
+ srcoffset + (dword_count << 2), byte_count);
+
+ /* UPDATE POINTERS */
+
+ srcoffset += mono_pitch;
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+ }
+
+ /* SECOND BLT */
+
+ gp_declare_blt (gp3_blt_flags | CIMGP_BLTFLAGS_HAZARD);
+
+ base = ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)) |
+ ((gp3_fb_base << 14) + (((gp3_scratch_base + indent) & 0xFFC00000) >> 10)) |
+ (gp3_base_register & GP3_BASE_OFFSET_CH3MASK);
+
+ gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE |
+ GP3_BLT_HDR_STRIDE_ENABLE |
+ GP3_BLT_HDR_DST_OFF_ENABLE |
+ GP3_BLT_HDR_SRC_OFF_ENABLE |
+ GP3_BLT_HDR_WIDHI_ENABLE |
+ GP3_BLT_HDR_CH3_STR_ENABLE |
+ GP3_BLT_HDR_CH3_WIDHI_ENABLE |
+ GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+ GP3_BLT_HDR_CH3_OFF_ENABLE |
+ GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+ /* ENABLE TRANSPARENCY AND PATTERN COPY ROP */
+ /* The monochrome data is used as a mask but is otherwise not involved in */
+ /* the BLT. The color data is routed through the pattern channel. */
+
+ WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_bpp | 0xF0 | GP3_RM_SRC_TRANS | flags);
+ WRITE_COMMAND32 (GP3_BLT_STRIDE, (total_dwords << 18) | gp3_dst_stride);
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, dstoffset & 0x3FFFFF);
+ WRITE_COMMAND32 (GP3_BLT_SRC_OFFSET,
+ ((gp3_scratch_base + indent) & 0x3FFFFF ) | ((mono_srcx & 7) << 26));
+ WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, (width << 16) | height);
+ WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, (width << 16) | height);
+ WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+
+ /* PROGRAM PARAMETERS FOR COLOR SOURCE DATA */
+ /* Data may be color converted along the way. */
+
+ if ((gp3_src_format & GP3_CH3_SRC_MASK) == GP3_CH3_SRC_24BPP_PACKED)
+ {
+ srcoffset = color_srcx * 3;
+ ch3_offset = 0;
+ size = width * 3;
+
+ WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, (((size + 3) >> 2) << 16) | height);
+ }
+ else if (gp3_src_pix_shift == 3)
+ {
+ /* CALCULATE INDENT AND SOURCE OFFSET */
+
+ indent = (color_srcx >> 1);
+ srcoffset = (indent & ~3L);
+ indent &= 3;
+ ch3_offset = indent | ((color_srcx & 1) << 25);
+
+ size = ((width + (color_srcx & 1) + 1) >> 1) + indent;
+ }
+ else
+ {
+ indent = (color_srcx << gp3_src_pix_shift);
+ srcoffset = (indent & ~3L);
+ indent &= 3;
+ ch3_offset = indent;
+
+ size = (width << gp3_src_pix_shift) + indent;
+ }
+
+ total_dwords = (size + 3) >> 2;
+ size_dwords = (total_dwords << 2) + 8;
+ dword_count = (size >> 2);
+ byte_count = (size & 3);
+
+ WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, ch3_offset);
+ WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
+ GP3_CH3_C3EN |
+ GP3_CH3_HST_SRC_ENABLE |
+ gp3_src_format |
+ ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20));
+ WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode | GP3_BM_SRC_MONO | GP3_BM_SRC_FB);
+
+ /* START THE BLT */
+
+ WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+
+ /* WRITE DATA LINE BY LINE */
+
+ while (height--)
+ {
+ /* UPDATE THE COMMAND POINTER */
+
+ cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+ /* CHECK IF A WRAP WILL BE NEEDED */
+
+ gp3_cmd_next = gp3_cmd_current + size_dwords;
+ if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+ {
+ gp3_cmd_next = gp3_cmd_top;
+
+ GP3_WAIT_WRAP(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+ GP3_DATA_LOAD_HDR_ENABLE);
+ }
+ else
+ {
+ GP3_WAIT_PRIMITIVE(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+ }
+
+ /* WRITE DWORD COUNT */
+
+ WRITE_COMMAND32 (4, GP3_CH3_HOST_SOURCE_TYPE | total_dwords);
+
+ /* WRITE COLOR DATA TO THE COMMAND BUFFER */
+
+ WRITE_COMMAND_STRING32 (8, color_data, srcoffset, dword_count);
+ WRITE_COMMAND_STRING8 (8 + (dword_count << 2), color_data,
+ srcoffset + (dword_count << 2), byte_count);
+
+ /* UPDATE COMMAND BUFFER POINTERS */
+ /* We do this before writing the monochrome data because otherwise */
+ /* the GP could throttle the writes to the host source register */
+ /* waiting for color data. If the command buffer has not been */
+ /* updated to load the color data... */
+
+ srcoffset += color_pitch;
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * gp_screen_to_screen_masked
+ *
+ * This routine performs a screen to screen BLT, using a monochrome mask to
+ * specify source transparency. The source data is assumed to be in the
+ * current destination format and to not overlap the destination.
+ *-------------------------------------------------------------------------*/
+
+void gp_screen_to_screen_masked (unsigned long dstoffset, unsigned long srcoffset,
+ unsigned long width, unsigned long height, unsigned long mono_srcx,
+ unsigned char *mono_mask, long mono_pitch)
+{
+ unsigned long indent, temp;
+ unsigned long total_dwords, size_dwords;
+ unsigned long dword_count, byte_count;
+ unsigned long srcoff, size;
+ unsigned long i, base;
+ unsigned long flags = 0;
+
+ if (gp3_blt_flags & CIMGP_BLTFLAGS_INVERTMONO)
+ flags = GP3_RM_SOURCE_INVERT;
+
+ /* MONO CALCULATIONS */
+
+ indent = (mono_srcx >> 3);
+ srcoff = (indent & ~3L);
+ indent &= 3;
+
+ size = ((width + (mono_srcx & 7) + 7) >> 3) + indent;
+ total_dwords = (size + 3) >> 2;
+ size_dwords = (total_dwords << 2) + 8;
+ dword_count = (size >> 2);
+ byte_count = (size & 3);
+
+ base = ((gp3_fb_base << 24) + (gp3_scratch_base & 0xFFC00000)) |
+ (gp3_base_register & ~GP3_BASE_OFFSET_DSTMASK);
+
+ gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE |
+ GP3_BLT_HDR_STRIDE_ENABLE |
+ GP3_BLT_HDR_DST_OFF_ENABLE |
+ GP3_BLT_HDR_WIDHI_ENABLE |
+ GP3_BLT_HDR_CH3_STR_ENABLE |
+ GP3_BLT_HDR_CH3_OFF_ENABLE |
+ GP3_BLT_HDR_CH3_WIDHI_ENABLE |
+ GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+ GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+ WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, GP3_RM_BPPFMT_8888 | 0xCC);
+ WRITE_COMMAND32 (GP3_BLT_STRIDE, (total_dwords << 2));
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, gp3_scratch_base & 0x3FFFFF);
+ WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, (total_dwords << 16) | height);
+ WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, (total_dwords << 16) | height);
+ WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, 0);
+ WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+ WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
+ GP3_CH3_C3EN |
+ GP3_CH3_REPLACE_SOURCE |
+ GP3_CH3_HST_SRC_ENABLE |
+ GP3_CH3_SRC_8_8_8_8 |
+ ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20));
+ WRITE_COMMAND32 (GP3_BLT_MODE, 0);
+ WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+
+ /* START THE BLT */
+
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+
+ for (i = 0; i < height; i++)
+ {
+ /* UPDATE THE COMMAND POINTER */
+ /* The WRITE_COMMANDXX macros use a pointer to the current buffer space. */
+ /* This is created by adding gp3_cmd_current to the base pointer. */
+
+ cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+ /* CHECK IF A WRAP WILL BE NEEDED */
+
+ gp3_cmd_next = gp3_cmd_current + size_dwords;
+ if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
+ {
+ gp3_cmd_next = gp3_cmd_top;
+
+ /* WAIT FOR HARDWARE */
+
+ GP3_WAIT_WRAP(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
+ GP3_DATA_LOAD_HDR_ENABLE);
+ }
+ else
+ {
+ /* WAIT FOR AVAILABLE SPACE */
+
+ GP3_WAIT_PRIMITIVE(temp);
+ WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
+ }
+
+ /* WRITE DWORD COUNT */
+
+ WRITE_COMMAND32 (4, GP3_CH3_HOST_SOURCE_TYPE | total_dwords);
+
+ /* WRITE DATA */
+
+ WRITE_COMMAND_STRING32 (8, mono_mask, srcoff, dword_count);
+ WRITE_COMMAND_STRING8 (8 + (dword_count << 2), mono_mask,
+ srcoff + (dword_count << 2), byte_count);
+
+ /* UPDATE POINTERS */
+
+ srcoff += mono_pitch;
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+ }
+
+ /* SECOND BLT */
+
+ gp_declare_blt (gp3_blt_flags | CIMGP_BLTFLAGS_HAZARD);
+
+ base = ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)) |
+ ((gp3_fb_base << 14) + (((gp3_scratch_base + indent) & 0xFFC00000) >> 10)) |
+ ((gp3_fb_base << 4) + ((srcoffset & 0xFFC00000) >> 20));
+
+ gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE |
+ GP3_BLT_HDR_STRIDE_ENABLE |
+ GP3_BLT_HDR_DST_OFF_ENABLE |
+ GP3_BLT_HDR_SRC_OFF_ENABLE |
+ GP3_BLT_HDR_WIDHI_ENABLE |
+ GP3_BLT_HDR_CH3_STR_ENABLE |
+ GP3_BLT_HDR_CH3_WIDHI_ENABLE |
+ GP3_BLT_HDR_BASE_OFFSET_ENABLE |
+ GP3_BLT_HDR_CH3_OFF_ENABLE |
+ GP3_BLT_HDR_BLT_MODE_ENABLE;
+
+ /* ENABLE TRANSPARENCY AND PATTERN COPY ROP */
+ /* The monochrome data is used as a mask but is otherwise not involved in */
+ /* the BLT. The color data is routed through the pattern channel. */
+
+ WRITE_COMMAND32 (GP3_BLT_RASTER_MODE, gp3_bpp | 0xF0 | GP3_RM_SRC_TRANS | flags);
+ WRITE_COMMAND32 (GP3_BLT_STRIDE, (total_dwords << 18) | gp3_dst_stride);
+ WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, dstoffset & 0x3FFFFF);
+ WRITE_COMMAND32 (GP3_BLT_SRC_OFFSET,
+ ((gp3_scratch_base + indent) & 0x3FFFFF ) | ((mono_srcx & 7) << 26));
+ WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, (width << 16) | height);
+ WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, (width << 16) | height);
+ WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
+
+ /* PROGRAM PARAMETERS FOR COLOR SOURCE DATA */
+
+ WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, srcoffset & 0x3FFFFF);
+ WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
+ GP3_CH3_C3EN |
+ gp3_ch3_bpp |
+ gp3_src_stride |
+ ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20));
+ WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode | GP3_BM_SRC_MONO | GP3_BM_SRC_FB);
+
+ /* START THE BLT */
+
+ WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_bresenham_line
+ *
+ * This routine draws a vector using the specified Bresenham parameters.
+ * Currently this file does not support a routine that accepts the two
+ * endpoints of a vector and calculates the Bresenham parameters. If it
+ * ever does, this routine is still required for vectors that have been
+ * clipped.
+ *-------------------------------------------------------------------------*/
+
+void gp_bresenham_line (unsigned long dstoffset, unsigned short length,
+ unsigned short initerr, unsigned short axialerr, unsigned short diagerr,
+ unsigned long flags)
+{
+ unsigned long base;
+ long offset;
+
+ /* HANDLE NEGATIVE VECTORS */
+ /* We have to be very careful with vectors that increment negatively */
+ /* Our framebuffer scheme tries to align the destination of every */
+ /* BLT or vector to the nearest 4MB-aligned boundary. This is */
+ /* necessary because the GP only supports offsets up to 16MB, but the */
+ /* framebuffer can be over 128MB. To solve this problem, the GP */
+ /* base address registers are alignable to 4MB regions. However, we */
+ /* cannot simply align the dest offset when the vector goes negative. */
+ /* The vector offset could underflow, causing the offset to jump from */
+ /* near 0 to 16MB. As we cannot accurately determine the last address */
+ /* that will be written in a vector short of walking the algorithm in */
+ /* software, we do a worst case approximation. */
+
+ offset = dstoffset;
+ if (!(flags & CIMGP_POSMAJOR))
+ {
+ if (flags & CIMGP_YMAJOR)
+ offset -= length * gp3_dst_stride;
+ else
+ offset -= (length << gp3_pix_shift);
+
+ if (offset < 0)
+ offset = 0;
+ }
+ if (!(flags & CIMGP_POSMINOR))
+ {
+ if (flags & CIMGP_YMAJOR)
+ offset -= (length << gp3_pix_shift);
+ else
+ offset -= length * gp3_dst_stride;
+
+ if (offset < 0)
+ offset = 0;
+ }
+
+ offset &= 0xFFC00000;
+ dstoffset -= offset;
+
+ base = ((gp3_fb_base << 24) + offset) |
+ (gp3_base_register & ~GP3_BASE_OFFSET_DSTMASK);
+
+ /* ENABLE RELEVANT REGISTERS */
+ /* Note that we always enable and write the channel 3 mode, if only */
+ /* to turn it off. Cimarron also always writes the base offset */
+ /* register to allow operation with frame buffers larger than 16MB. */
+
+ gp3_cmd_header |= GP3_VEC_HDR_DST_OFF_ENABLE |
+ GP3_VEC_HDR_VEC_ERR_ENABLE |
+ GP3_VEC_HDR_VEC_LEN_ENABLE |
+ GP3_VEC_HDR_BASE_OFFSET_ENABLE |
+ GP3_VEC_HDR_CH3_STR_ENABLE |
+ GP3_VEC_HDR_VEC_MODE_ENABLE;
+
+ /* WRITE THE REGISTERS COMMON TO ALL PATTERN TYPES */
+ /* The destination base is the frame buffer base plus whatever */
+ /* 4MB segment we happen to be drawing to. */
+
+ WRITE_COMMAND32 (GP3_VECTOR_VEC_ERR,
+ (((unsigned long)axialerr << 16) | (unsigned long)diagerr));
+ WRITE_COMMAND32 (GP3_VECTOR_VEC_LEN,
+ (((unsigned long)length << 16) | (unsigned long)initerr));
+ WRITE_COMMAND32 (GP3_VECTOR_BASE_OFFSET, base);
+
+ /* CHECK VECTOR PATTERN CASE */
+
+ if (gp3_ch3_pat)
+ {
+ /* SET THE SOLID COLOR */
+ /* The color for vector patterns from channel 3 comes from */
+ /* the regular pattern registers. */
+
+ gp3_cmd_header |= GP3_VEC_HDR_PAT_CLR0_ENABLE;
+
+ WRITE_COMMAND32 (GP3_VECTOR_PAT_COLOR_0, gp3_vector_pattern_color);
+
+ /* INITIALIZE CHANNEL 3 PARAMETERS */
+ /* We route the channel 3 output to the old source channel. If the user */
+ /* sets a ROP that involves source, they will get unexpected results. */
+
+ WRITE_COMMAND32 (GP3_VECTOR_DST_OFFSET, dstoffset);
+ WRITE_COMMAND32 (GP3_VECTOR_CH3_MODE_STR,
+ GP3_CH3_C3EN | GP3_CH3_REPLACE_SOURCE | GP3_CH3_COLOR_PAT_ENABLE | GP3_CH3_SRC_8_8_8_8);
+ }
+ else
+ {
+ /* DISABLE CHANNEL 3 AND USE NORMAL PATTERN ORIGINS */
+
+ WRITE_COMMAND32 (GP3_VECTOR_CH3_MODE_STR, 0);
+ WRITE_COMMAND32 (GP3_VECTOR_DST_OFFSET, (dstoffset | gp3_pat_origin));
+ }
+
+ /* START THE VECTOR */
+
+ WRITE_COMMAND32 (GP3_VEC_CMD_HEADER, gp3_cmd_header);
+ WRITE_COMMAND32 (GP3_VECTOR_MODE, (gp3_vec_mode | flags));
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+
+ gp3_cmd_current = gp3_cmd_next;
+
+ /* ADD A SECOND VECTOR TO CLEAR THE BYTE ENABLES */
+ /* We set a transparent pattern to clear the byte enables. */
+ /* We then restore the previous pattern. (SiBZ #4001) */
+
+ if (gp3_ch3_pat)
+ {
+ cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+ WRITE_COMMAND32 (0, GP3_LUT_HDR_TYPE | GP3_LUT_HDR_DATA_ENABLE);
+ WRITE_COMMAND32 (4, 0x100);
+ WRITE_COMMAND32 (8, (1 | GP3_LUT_DATA_TYPE));
+ WRITE_COMMAND32 (12, 0);
+
+ /* DUMMY VECTOR */
+ /* We shouldn't need to write anything but vector mode and the length. */
+
+ WRITE_COMMAND32 (16, GP3_VEC_HDR_TYPE | GP3_VEC_HDR_VEC_MODE_ENABLE |
+ GP3_VEC_HDR_VEC_LEN_ENABLE);
+ WRITE_COMMAND32 (16 + GP3_VECTOR_MODE, (gp3_vec_mode | flags));
+ WRITE_COMMAND32 (16 + GP3_VECTOR_VEC_LEN, (1 << 16) | (unsigned long)initerr);
+
+ WRITE_COMMAND32 (16 + GP3_VECTOR_COMMAND_SIZE, GP3_LUT_HDR_TYPE | GP3_LUT_HDR_DATA_ENABLE);
+ WRITE_COMMAND32 (20 + GP3_VECTOR_COMMAND_SIZE, 0x100);
+ WRITE_COMMAND32 (24 + GP3_VECTOR_COMMAND_SIZE, (1 | GP3_LUT_DATA_TYPE));
+ WRITE_COMMAND32 (28 + GP3_VECTOR_COMMAND_SIZE, gp3_vec_pat);
+
+ gp3_cmd_current += 32 + GP3_VECTOR_COMMAND_SIZE;
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * gp_line_from_endpoints
+ *
+ * This routine draws a vector from a set of rectangular coordinates. The
+ * rectangle is assumed to use the currently specified destination stride.
+ *-------------------------------------------------------------------------*/
+
+void gp_line_from_endpoints (unsigned long dstoffset, unsigned long x0,
+ unsigned long y0, unsigned long x1, unsigned long y1, int inclusive)
+{
+ unsigned long base;
+ unsigned long length;
+ unsigned long flags;
+ unsigned short initerr, axialerr, diagerr;
+ long dx, dy, dmaj, dmin;
+ long offset;
+
+ /* ADJUST DESTINATION OFFSET BASED ON STARTING COORDINATE */
+
+ dstoffset += (x0 << gp3_pix_shift) + (y0 * gp3_dst_stride);
+
+ /* CALCULATE BRESENHAM TERMS */
+
+ dx = (long)x1 - (long)x0;
+ dy = (long)y1 - (long)y0;
+ if (dx < 0) dx = -dx;
+ if (dy < 0) dy = -dy;
+
+ if (dx >= dy)
+ {
+ dmaj = dx;
+ dmin = dy;
+ flags = 0;
+ if (x1 > x0) flags |= CIMGP_POSMAJOR;
+ if (y1 > y0) flags |= CIMGP_POSMINOR;
+ }
+ else
+ {
+ dmaj = dy;
+ dmin = dx;
+ flags = CIMGP_YMAJOR;
+ if (x1 > x0) flags |= CIMGP_POSMINOR;
+ if (y1 > y0) flags |= CIMGP_POSMAJOR;
+ }
+
+ axialerr = (unsigned short)(dmin << 1);
+ diagerr = (unsigned short)((dmin-dmaj) << 1);
+ initerr = (unsigned short)((dmin << 1) - dmaj);
+ if (!(flags & CIMGP_POSMINOR)) initerr--;
+
+ /* CHECK FOR NO WORK */
+
+ if (!dmaj)
+ return;
+
+ /* CHECK INCLUSIVE OR EXCLUSIVE */
+ /* An inclusive line can be accomplished by simply adding 1 to the */
+ /* line length. */
+
+ length = dmaj;
+ if (inclusive)
+ length++;
+
+ /* HANDLE NEGATIVE VECTORS */
+
+ offset = dstoffset;
+ if (!(flags & CIMGP_POSMAJOR))
+ {
+ if (flags & CIMGP_YMAJOR)
+ offset -= length * gp3_dst_stride;
+ else
+ offset -= (length << gp3_pix_shift);
+
+ if (offset < 0)
+ offset = 0;
+ }
+ if (!(flags & CIMGP_POSMINOR))
+ {
+ if (flags & CIMGP_YMAJOR)
+ offset -= (length << gp3_pix_shift);
+ else
+ offset -= length * gp3_dst_stride;
+
+ if (offset < 0)
+ offset = 0;
+ }
+
+ offset &= 0xFFC00000;
+ dstoffset -= offset;
+
+ base = ((gp3_fb_base << 24) + offset) |
+ (gp3_base_register & ~GP3_BASE_OFFSET_DSTMASK);
+
+ /* ENABLE RELEVANT REGISTERS */
+ /* Note that we always enable and write the channel 3 mode, if only */
+ /* to turn it off. Cimarron also always writes the base offset */
+ /* register to allow operation with frame buffers larger than 16MB. */
+
+ gp3_cmd_header |= GP3_VEC_HDR_DST_OFF_ENABLE |
+ GP3_VEC_HDR_VEC_ERR_ENABLE |
+ GP3_VEC_HDR_VEC_LEN_ENABLE |
+ GP3_VEC_HDR_BASE_OFFSET_ENABLE |
+ GP3_VEC_HDR_CH3_STR_ENABLE |
+ GP3_VEC_HDR_VEC_MODE_ENABLE;
+
+ /* WRITE THE REGISTERS COMMON TO ALL PATTERN TYPES */
+ /* The destination base is the frame buffer base plus whatever */
+ /* 4MB segment we happen to be drawing to. */
+
+ WRITE_COMMAND32 (GP3_VECTOR_VEC_ERR,
+ (((unsigned long)axialerr << 16) | (unsigned long)diagerr));
+ WRITE_COMMAND32 (GP3_VECTOR_VEC_LEN,
+ (((unsigned long)length << 16) | (unsigned long)initerr));
+ WRITE_COMMAND32 (GP3_VECTOR_BASE_OFFSET, base);
+
+ /* CHECK VECTOR PATTERN CASE */
+
+ if (gp3_ch3_pat)
+ {
+ /* SET THE SOLID COLOR */
+ /* The color for vector patterns from channel 3 comes from */
+ /* the regular pattern registers. */
+
+ gp3_cmd_header |= GP3_VEC_HDR_PAT_CLR0_ENABLE;
+
+ WRITE_COMMAND32 (GP3_VECTOR_PAT_COLOR_0, gp3_vector_pattern_color);
+
+ /* INITIALIZE CHANNEL 3 PARAMETERS */
+ /* We route the channel 3 output to the old source channel. If the user */
+ /* sets a ROP that involves source, they will get unexpected results. */
+
+ WRITE_COMMAND32 (GP3_VECTOR_DST_OFFSET, dstoffset);
+ WRITE_COMMAND32 (GP3_VECTOR_CH3_MODE_STR,
+ GP3_CH3_C3EN | GP3_CH3_REPLACE_SOURCE | GP3_CH3_COLOR_PAT_ENABLE | GP3_CH3_SRC_8_8_8_8);
+ }
+ else
+ {
+ /* DISABLE CHANNEL 3 AND USE NORMAL PATTERN ORIGINS */
+
+ WRITE_COMMAND32 (GP3_VECTOR_CH3_MODE_STR, 0);
+ WRITE_COMMAND32 (GP3_VECTOR_DST_OFFSET, (dstoffset | gp3_pat_origin));
+ }
+
+ /* START THE VECTOR */
+
+ WRITE_COMMAND32 (GP3_VEC_CMD_HEADER, gp3_cmd_header);
+ WRITE_COMMAND32 (GP3_VECTOR_MODE, (gp3_vec_mode | flags));
+ WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
+ gp3_cmd_current = gp3_cmd_next;
+
+ /* ADD A SECOND VECTOR TO CLEAR THE BYTE ENABLES */
+ /* We set a transparent pattern to clear the byte enables. */
+ /* We then restore the previous pattern. (SiBZ #4001) */
+
+ if (gp3_ch3_pat)
+ {
+ cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;
+
+ WRITE_COMMAND32 (0, GP3_LUT_HDR_TYPE | GP3_LUT_HDR_DATA_ENABLE);
+ WRITE_COMMAND32 (4, 0x100);
+ WRITE_COMMAND32 (8, (1 | GP3_LUT_DATA_TYPE));
+ WRITE_COMMAND32 (12, 0);
+
+ /* DUMMY VECTOR */
+ /* We shouldn't need to write anything but vector mode and the length. */
+
+ WRITE_COMMAND32 (16, GP3_VEC_HDR_TYPE | GP3_VEC_HDR_VEC_MODE_ENABLE |
+ GP3_VEC_HDR_VEC_LEN_ENABLE);
+ WRITE_COMMAND32 (16 + GP3_VECTOR_MODE, (gp3_vec_mode | flags));
+ WRITE_COMMAND32 (16 + GP3_VECTOR_VEC_LEN, (1 << 16) | (unsigned long)initerr);
+
+ WRITE_COMMAND32 (16 + GP3_VECTOR_COMMAND_SIZE, GP3_LUT_HDR_TYPE | GP3_LUT_HDR_DATA_ENABLE);
+ WRITE_COMMAND32 (20 + GP3_VECTOR_COMMAND_SIZE, 0x100);
+ WRITE_COMMAND32 (24 + GP3_VECTOR_COMMAND_SIZE, (1 | GP3_LUT_DATA_TYPE));
+ WRITE_COMMAND32 (28 + GP3_VECTOR_COMMAND_SIZE, gp3_vec_pat);
+
+ gp3_cmd_current += 32 + GP3_VECTOR_COMMAND_SIZE;
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * gp_wait_until_idle
+ *
+ * This routine stalls execution until the GP is no longer actively rendering.
+ *-------------------------------------------------------------------------*/
+
+void gp_wait_until_idle (void)
+{
+ unsigned long temp;
+ while (((temp = READ_GP32 (GP3_BLT_STATUS)) & GP3_BS_BLT_BUSY) ||
+ !(temp & GP3_BS_CB_EMPTY))
+ {
+ ;
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * gp_test_blt_busy
+ *-------------------------------------------------------------------------*/
+
+int gp_test_blt_busy (void)
+{
+ unsigned long temp;
+
+ if (((temp = READ_GP32 (GP3_BLT_STATUS)) & GP3_BS_BLT_BUSY) ||
+ !(temp & GP3_BS_CB_EMPTY))
+ return 1;
+
+ return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_test_blt_pending
+ *-------------------------------------------------------------------------*/
+
+int gp_test_blt_pending (void)
+{
+ if ((READ_GP32 (GP3_BLT_STATUS)) & GP3_BS_BLT_PENDING)
+ return 1;
+
+ return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_wait_blt_pending
+ *-------------------------------------------------------------------------*/
+
+void gp_wait_blt_pending (void)
+{
+ while ((READ_GP32 (GP3_BLT_STATUS)) & GP3_BS_BLT_PENDING)
+ ;
+}
+
+/*---------------------------------------------------------------------------
+ * gp_save_state
+ *
+ * This routine saves all persistent GP information.
+ *-------------------------------------------------------------------------*/
+
+void gp_save_state (GP_SAVE_RESTORE *gp_state)
+{
+ Q_WORD msr_value;
+
+ gp_wait_until_idle();
+
+ msr_read64 (MSR_DEVICE_GEODELX_GP, MSR_GEODELINK_CONFIG, &msr_value);
+ gp_state->cmd_bottom = READ_GP32 (GP3_CMD_BOT) & 0xFFFFFF;
+ gp_state->cmd_top = READ_GP32 (GP3_CMD_TOP) & 0xFFFFFF;
+ gp_state->cmd_base = (msr_value.low << 4) & 0xFFF00000;
+ gp_state->base_offset = READ_GP32 (GP3_BASE_OFFSET);
+
+ /* RESET THE READ POINTER */
+
+ gp_set_command_buffer_base (gp_state->cmd_base, gp_state->cmd_top, gp_state->cmd_bottom);
+}
+
+/*---------------------------------------------------------------------------
+ * gp_restore_state
+ *
+ * This routine restores all persistent GP information.
+ *-------------------------------------------------------------------------*/
+
+void gp_restore_state (GP_SAVE_RESTORE *gp_state)
+{
+ gp_wait_until_idle();
+
+ WRITE_GP32 (GP3_BASE_OFFSET, gp_state->base_offset);
+
+ gp_set_command_buffer_base (gp_state->cmd_base, gp_state->cmd_top, gp_state->cmd_bottom);
+}
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_init.c xf86-video-nsc-2.8.1/src/cim/cim_init.c
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_init.c 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_init.c 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,209 @@
+ /*
+ *
+ * Copyright (C) 2005 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *
+ *
+ *
+ *
+ *
+ * Cimarron initialization routines. These routines detect a Geode LX and read
+ * all hardware base addresses.
+ *
+ *
+ */
+
+CIMARRON_STATIC unsigned long init_video_base = 0x80000900;
+
+/*---------------------------------------------------------------------------
+ * init_detect_cpu
+ *
+ * This routine verifies that a Geode LX is present and returns the processor revision
+ * ID. For compatibility, this routine can also detect a Redcloud processor.
+ * bits[24:16] = minor version
+ * bits[15:8] = major version
+ * bits[7:0] = type (1 = Geode GX, 2 = Geode LX)
+ *---------------------------------------------------------------------------*/
+
+int init_detect_cpu (unsigned long *cpu_revision, unsigned long *companion_revision)
+{
+ unsigned long bus, device, i;
+ unsigned long cpu_bus = 0, cpu_device = 0;
+ unsigned long address, data;
+ unsigned long num_bars, function;
+ int cpu_found, sb_found;
+ Q_WORD msr_value;
+
+ /* SEARCH THROUGH PCI BUS */
+ /* We search the PCI bus for the Geode LX or Geode GX northbridge. */
+ /* We then verify that one of its functions is the graphics */
+ /* controller and that all bars are filled in. */
+
+ cpu_found = sb_found = 0;
+ for (bus = 0; bus < 256; bus++)
+ {
+ for (device = 0; device < 21; device++)
+ {
+ address = 0x80000000 | (bus << 16) | (device << 11);
+
+ data = init_read_pci (address);
+
+ if (data == PCI_VENDOR_DEVICE_GEODEGX || data == PCI_VENDOR_DEVICE_GEODELX)
+ {
+ cpu_found = 1;
+ cpu_device = device;
+ cpu_bus = bus;
+ if (data == PCI_VENDOR_DEVICE_GEODEGX)
+ *cpu_revision = CIM_CPU_GEODEGX;
+ else
+ *cpu_revision = CIM_CPU_GEODELX;
+ }
+ else if (data == PCI_VENDOR_5535 || data == PCI_VENDOR_5536)
+ {
+ sb_found = 1;
+ if (data == PCI_VENDOR_5535)
+ *companion_revision = CIM_SB_5535;
+ else
+ *companion_revision = CIM_SB_5536;
+ }
+
+ if (cpu_found && sb_found)
+ break;
+ }
+ if (device != 21)
+ break;
+ }
+
+ if (bus == 256)
+ {
+ *cpu_revision = 0;
+ return CIM_STATUS_CPUNOTFOUND;
+ }
+
+ msr_init_table();
+
+ if (msr_read64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REVID, &msr_value) != CIM_STATUS_OK)
+ {
+ *cpu_revision = 0;
+ return CIM_STATUS_CPUNOTFOUND;
+ }
+
+ *cpu_revision |= ((msr_value.low & 0xF0) << 4) |
+ ((msr_value.low & 0x0F) << 16);
+
+ if (msr_read64 (MSR_DEVICE_5535_GLCP, GLCP_REVID, &msr_value) != CIM_STATUS_OK)
+ {
+ *cpu_revision = 0;
+ return CIM_STATUS_CPUNOTFOUND;
+ }
+
+ *companion_revision |= ((msr_value.low & 0xF0) << 4) |
+ ((msr_value.low & 0x0F) << 16);
+
+ /* SEARCH ALL FUNCTIONS FOR INTEGRATED GRAPHICS */
+
+ num_bars = 0;
+ for (function = 0; function < 7; function++)
+ {
+ address = 0x80000000 | (cpu_bus << 16) | (cpu_device << 11) | (function << 8);
+ data = init_read_pci (address);
+
+ if (data == PCI_VENDOR_DEVICE_GEODEGX_VIDEO)
+ {
+ num_bars = 4;
+ break;
+ }
+ else if (data == PCI_VENDOR_DEVICE_GEODELX_VIDEO)
+ {
+ num_bars = 5;
+ break;
+ }
+ }
+
+ /* VERIFY THAT ALL BARS ARE PRESENT */
+
+ if (function == 7)
+ return CIM_STATUS_DISPLAYUNAVAILABLE;
+
+ for (i = 0; i < num_bars; i++)
+ {
+ data = init_read_pci (address + 0x10 + (i << 2));
+
+ if (data == 0 || data == 0xFFFFFFFF)
+ break;
+ }
+
+ if (i != num_bars)
+ return CIM_STATUS_DISPLAYUNAVAILABLE;
+
+ /* SAVE VIDEO BASE ADDRESS FOR FUTURE CALLS */
+
+ init_video_base = address;
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * init_read_pci
+ *
+ * This routine reads an unsigned long value from a PCI address.
+ *---------------------------------------------------------------------------*/
+
+unsigned long init_read_pci (unsigned long address)
+{
+ OUTD (0xCF8, address);
+ return IND (0xCFC);
+}
+
+/*---------------------------------------------------------------------------
+ * init_read_base_addresses
+ *
+ * This routine reads all base addresses for the peripherals from the PCI BARs.
+ *---------------------------------------------------------------------------*/
+
+int init_read_base_addresses (INIT_BASE_ADDRESSES *base_addresses)
+{
+ unsigned long value;
+
+ /* READ ALL BASE ADDRESSES */
+
+ base_addresses->framebuffer_base = init_read_pci (init_video_base + 0x10);
+ base_addresses->gp_register_base = init_read_pci (init_video_base + 0x14);
+ base_addresses->vg_register_base = init_read_pci (init_video_base + 0x18);
+ base_addresses->df_register_base = init_read_pci (init_video_base + 0x1C);
+ base_addresses->vip_register_base = init_read_pci (init_video_base + 0x20);
+
+ /* READ FRAME BUFFER SIZE */
+ /* The frame buffer size is reported by a VSM in VSA II */
+ /* Virtual Register Class = 0x02 */
+ /* VG_MEM_SIZE (1MB units) = 0x00 */
+
+ OUTW (0xAC1C, 0xFC53);
+ OUTW (0xAC1C, 0x0200);
+
+ value = (unsigned long)(INW (0xAC1E)) & 0xFE;
+
+ base_addresses->framebuffer_size = value << 20;
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * init_read_cpu_frequency
+ *
+ * This routine returns the current CPU core frequency, in MHz.
+ *---------------------------------------------------------------------------*/
+
+int init_read_cpu_frequency (unsigned long *cpu_frequency)
+{
+ /* CPU SPEED IS REPORTED BY A VSM IN VSA II */
+ /* Virtual Register Class = 0x12 (Sysinfo) */
+ /* CPU Speed Register = 0x01 */
+
+ OUTW (0xAC1C, 0xFC53);
+ OUTW (0xAC1C, 0x1201);
+
+ *cpu_frequency = (unsigned long)(INW (0xAC1E));
+
+ return CIM_STATUS_OK;
+}
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_modes.c xf86-video-nsc-2.8.1/src/cim/cim_modes.c
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_modes.c 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_modes.c 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,1822 @@
+ /*
+ *
+ * Copyright (C) 2005 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *
+ *
+ *
+ *
+ *
+ * Cimarron mode tables.
+ *
+ *
+ */
+
+/*-------------------------------*/
+/* PREDEFINED DISPLAY TIMINGS */
+/*-------------------------------*/
+
+VG_DISPLAY_MODE CimarronDisplayModes[] =
+{
+ /* 320 x 240 PANEL */
+
+ { VG_SUPPORTFLAG_75HZ | /* refresh rate = 75 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP | /* All BPP supported. */
+ VG_SUPPORTFLAG_PANEL, /* Panel Mode. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ VG_MODEFLAG_PANELOUT | /* Panel output. */
+ VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC | /* negative syncs */
+ VG_MODEFLAG_QVGA, /* QVGA Panel size. */
+ 320, 240, /* No scaling. */
+ 320, 240, /* 320x240 active */
+ 320, 240, /* 320x240 panel */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0140, 0x0148, 0x0162, 0x0180, 0x0188, 0x0190, /* horizontal timings */
+ 0x00F0, 0x00F4, 0x00F9, 0x00FD, 0x00FF, 0x0104, /* vertical timings */
+ (31L << 16) | ((2000L * 65536L) / 10000L), /* freq = 31.2000 MHz */
+ },
+
+ /* 640 x 400 */
+
+ { VG_SUPPORTFLAG_70HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ VG_MODEFLAG_NEG_HSYNC, /* negative HSYNC */
+ 640, 400, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x280, 0x288, 0x290, 0x2F0, 0x318, 0x320, /* horizontal timings */
+ 0x190, 0x197, 0x19C, 0x19E, 0x1BA, 0x1C1, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (25L << 16) | ((1750L * 65536L) / 10000L), /* freq = 25.175 MHz */
+ },
+
+ /* 640x480 */
+
+ { VG_SUPPORTFLAG_60HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC, /* negative syncs */
+ 640, 480, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0280, 0x0288, 0x0290, 0x02E8, 0x0318, 0x0320, /* horizontal timings */
+ 0x01E0, 0x01E8, 0x01EA, 0x01EC, 0x0205, 0x020D, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (25L << 16) | ((1750L * 65536L) / 10000L), /* freq = 25.175 MHz */
+ },
+
+ { VG_SUPPORTFLAG_70HZ | /* refresh rate = 70 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ 0,
+ 640, 480, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0280, 0x0280, 0x0298, 0x02D8, 0x0330, 0x0330, /* horizontal timings */
+ 0x01E0, 0x01E0, 0x01E2, 0x01E5, 0x01F4, 0x01F4, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (28L << 16) | ((5600L * 65536L) / 10000L), /* freq = 28.560 MHz */
+ },
+
+ { VG_SUPPORTFLAG_72HZ | /* refresh rate = 72 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC, /* negative syncs */
+ 640, 480, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0280, 0x0288, 0x0298, 0x02c0, 0x0338, 0x0340, /* horizontal timings */
+ 0x01e0, 0x01e8, 0x01e9, 0x01ec, 0x0200, 0x0208, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (31L << 16) | ((5000L * 65536L) / 10000L), /* freq = 31.5 MHz */
+ },
+
+ { VG_SUPPORTFLAG_75HZ | /* refresh rate = 75 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC, /* negative syncs */
+ 640, 480, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0280, 0x0280, 0x0290, 0x02D0, 0x0348, 0x0348, /* horizontal timings */
+ 0x01E0, 0x01E0, 0x01E1, 0x01E4, 0x01F4, 0x01F4, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (31L << 16) | ((5000L * 65536L) / 10000L), /* freq = 31.5 MHz */
+ },
+
+ { VG_SUPPORTFLAG_85HZ | /* refresh rate = 85 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC, /* negative syncs */
+ 640, 480, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0280, 0x0280, 0x02B8, 0x02F0, 0x0340, 0x0340, /* horizontal timings */
+ 0x01E0, 0x01E0, 0x01E1, 0x01E4, 0x01FD, 0x01FD, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (36L << 16) | ((0000L * 65536L) / 10000L), /* freq = 36.0 MHz */
+ },
+
+ { VG_SUPPORTFLAG_90HZ | /* refresh rate = 90 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ 0,
+ 640, 480, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0280, 0x0280, 0x02A0, 0x02E0, 0x0340, 0x0340, /* horizontal timings */
+ 0x01E0, 0x01E0, 0x01E1, 0x01E4, 0x01FA, 0x01FA, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (37L << 16) | ((8890L * 65536L) / 10000L), /* freq = 37.889 MHz */
+ },
+
+ { VG_SUPPORTFLAG_100HZ | /* refresh rate = 100 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ 0,
+ 640, 480, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0280, 0x0280, 0x02A8, 0x02E8, 0x0350, 0x0350, /* horizontal timings */
+ 0x01E0, 0x01E0, 0x01E1, 0x01E4, 0x01FD, 0x01FD, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (43L << 16) | ((1630L * 65536L) / 10000L), /* freq = 43.163 MHz */
+ },
+
+ /* 640 x 480 PANEL */
+
+ { VG_SUPPORTFLAG_60HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP | /* All BPP supported. */
+ VG_SUPPORTFLAG_PANEL, /* Panel Mode. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ VG_MODEFLAG_PANELOUT | /* Panel output. */
+ VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC, /* negative syncs */
+ 640, 480, /* No scaling. */
+ 640, 480, /* 640x480 active */
+ 640, 480, /* 640x480 panel */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0280, 0x0280, 0x0290, 0x02E8, 0x0318, 0x0320, /* horizontal timings */
+ 0x01E0, 0x01E0, 0x01EA, 0x01EC, 0x0205, 0x020D, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (25L << 16) | ((1750L * 65536L) / 10000L), /* freq = 25.175 MHz */
+ },
+
+ /* 800x600 */
+
+ { VG_SUPPORTFLAG_56HZ | /* refresh rate = 56 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ 0,
+ 800, 600, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0320, 0x0320, 0x0338, 0x0380, 0x0400, 0x0400, /* horizontal timings */
+ 0x0258, 0x0258, 0x0259, 0x025B, 0x0271, 0x0271, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (36L << 16) | ((0000L * 65536L) / 10000L), /* freq = 36.0 MHz */
+ },
+
+ { VG_SUPPORTFLAG_60HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ 0,
+ 800, 600, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0320, 0x0328, 0x0348, 0x03D0, 0x0418, 0x0420, /* horizontal timings */
+ 0x0258, 0x0258, 0x0259, 0x025D, 0x0274, 0x0274, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (40L << 16) | ((0000L * 65536L) / 10000L), /* freq = 40.00 MHz */
+ },
+
+ { VG_SUPPORTFLAG_70HZ | /* refresh rate = 70 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ 0,
+ 800, 600, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0320, 0x0320, 0x0348, 0x0398, 0x0410, 0x0410, /* horizontal timings */
+ 0x0258, 0x0258, 0x025c, 0x025F, 0x0274, 0x0274, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (45L << 16) | ((7200L * 65536L) / 10000L), /* freq = 45.72 MHz */
+ },
+
+ { VG_SUPPORTFLAG_72HZ | /* refresh rate = 72 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ 0,
+ 800, 600, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0320, 0x0320, 0x0358, 0x03D0, 0x0410, 0x0410, /* horizontal timings */
+ 0x0258, 0x0258, 0x027D, 0x0283, 0x029A, 0x029A, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (49L << 16) | ((5000L * 65536L) / 10000L), /* freq = 49.5 MHz */
+ },
+
+ { VG_SUPPORTFLAG_75HZ | /* refresh rate = 75 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ 0,
+ 800, 600, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0320, 0x0320, 0x0330, 0x0380, 0x0420, 0x0420, /* horizontal timings */
+ 0x0258, 0x0258, 0x0259, 0x025C, 0x0271, 0x0271, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (49L << 16) | ((5000L * 65536L) / 10000L), /* freq = 49.5 MHz */
+ },
+
+ { VG_SUPPORTFLAG_85HZ | /* refresh rate = 85 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ 0,
+ 800, 600, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0320, 0x0320, 0x0340, 0x0380, 0x0418, 0x0418, /* horizontal timings */
+ 0x0258, 0x0258, 0x0259, 0x025C, 0x0277, 0x0277, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (56L << 16) | ((2500L * 65536L) / 10000L), /* freq = 56.25 MHz */
+ },
+
+ { VG_SUPPORTFLAG_90HZ | /* refresh rate = 90 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ 0,
+ 800, 600, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0320, 0x0320, 0x0348, 0x03A0, 0x0420, 0x0420, /* horizontal timings */
+ 0x0258, 0x0258, 0x0259, 0x025C, 0x0278, 0x0278, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (60L << 16) | ((650L * 65536L) / 10000L), /* freq = 60.065 MHz */
+ },
+
+ { VG_SUPPORTFLAG_100HZ | /* refresh rate = 100 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ 0,
+ 800, 600, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0320, 0x0320, 0x0350, 0x03A8, 0x0430, 0x0430, /* horizontal timings */
+ 0x0258, 0x0258, 0x0259, 0x025C, 0x0277, 0x027C, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (68L << 16) | ((1790L * 65536L) / 10000L), /* freq = 68.179 MHz */
+ },
+
+ /* 800x600 PANEL */
+
+ { VG_SUPPORTFLAG_60HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP | /* All BPP supported. */
+ VG_SUPPORTFLAG_PANEL, /* Panel Mode. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ VG_MODEFLAG_PANELOUT | /* Panel output. */
+ VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC, /* negative syncs */
+ 800, 600, /* No scaling. */
+ 800, 600, /* 800x600 active. */
+ 800, 600, /* 800x600 panel */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0320, 0x0320, 0x0348, 0x03C8, 0x0420, 0x0420, /* horizontal timings */
+ 0x0258, 0x0258, 0x0259, 0x025D, 0x0274, 0x0274, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (40L << 16) | ((0000L * 65536L) / 10000L), /* freq = 40.00 MHz */
+ },
+
+ /* 1024x768 */
+
+ { VG_SUPPORTFLAG_60HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC, /* negative syncs */
+ 1024, 768, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0400, 0x0400, 0x0418, 0x04A0, 0x0540, 0x0540, /* horizontal timings */
+ 0x0300, 0x0300, 0x0303, 0x0309, 0x0326, 0x0326, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (65L << 16) | ((0000L * 65536L) / 10000L), /* freq = 65.00 MHz */
+ },
+
+ { VG_SUPPORTFLAG_70HZ | /* refresh rate = 70 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC, /* negative syncs */
+ 1024, 768, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0400, 0x0400, 0x0418, 0x04A0, 0x0530, 0x0530, /* horizontal timings */
+ 0x0300, 0x0300, 0x0303, 0x0309, 0x0326, 0x0326, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (75L << 16) | ((0000L * 65536L) / 10000L), /* freq = 75.0 MHz */
+ },
+
+ { VG_SUPPORTFLAG_72HZ | /* refresh rate = 72 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ 0,
+ 1024, 768, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0400, 0x0400, 0x0438, 0x04A8, 0x0550, 0x0550, /* horizontal timings */
+ 0x0300, 0x0300, 0x0304, 0x0307, 0x0324, 0x0324, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (78L << 16) | ((7500L * 65536L) / 10000L), /* freq = 78.75 MHz */
+ },
+
+ { VG_SUPPORTFLAG_75HZ | /* refresh rate = 75 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ 0,
+ 1024, 768, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0400, 0x0400, 0x0410, 0x0470, 0x0520, 0x0520, /* horizontal timings */
+ 0x0300, 0x0300, 0x0301, 0x0304, 0x0320, 0x0320, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (78L << 16) | ((7500L * 65536L) / 10000L), /* freq = 78.75 MHz */
+ },
+
+ { VG_SUPPORTFLAG_85HZ | /* refresh rate = 85 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ 0,
+ 1024, 768, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0400, 0x0400, 0x0430, 0x0490, 0x0560, 0x0560, /* horizontal timings */
+ 0x0300, 0x0300, 0x0301, 0x0304, 0x0328, 0x0328, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (94L << 16) | ((5000L * 65536L) / 10000L), /* freq = 94.50 MHz */
+ },
+
+ { VG_SUPPORTFLAG_90HZ | /* refresh rate = 90 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ 0,
+ 1024, 768, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0400, 0x0400, 0x0440, 0x04B0, 0x0560, 0x0560, /* horizontal timings */
+ 0x0300, 0x0300, 0x0301, 0x0304, 0x0329, 0x0329, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (100L << 16) | ((1870L * 65536L) / 10000L), /* freq = 100.187 MHz */
+ },
+
+ { VG_SUPPORTFLAG_100HZ | /* refresh rate = 100 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ 0,
+ 1024, 768, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0400, 0x0400, 0x0448, 0x04B8, 0x0570, 0x0570, /* horizontal timings */
+ 0x0300, 0x0300, 0x0301, 0x0304, 0x032E, 0x032E, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (113L << 16) | ((3100L * 65536L) / 10000L), /* freq = 113.31 MHz */
+ },
+
+ /* 1024x768 PANEL */
+
+ { VG_SUPPORTFLAG_60HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP | /* All BPP supported. */
+ VG_SUPPORTFLAG_PANEL, /* Panel Mode. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ VG_MODEFLAG_PANELOUT | /* Panel output. */
+ VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC, /* negative syncs */
+ 1024, 768, /* No scaling. */
+ 1024, 768, /* 1024x768 active. */
+ 1024, 768, /* 1024x768 panel */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0400, 0x0400, 0x0418, 0x04A0, 0x0540, 0x0540, /* horizontal timings */
+ 0x0300, 0x0300, 0x0303, 0x0309, 0x0326, 0x0326, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (65L << 16) | ((0000L * 65536L) / 10000L), /* freq = 65.00 MHz */
+ },
+
+ /* 1152x864 */
+
+ { VG_SUPPORTFLAG_60HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ 0,
+ 1152, 864, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0480, 0x0480, 0x04C0, 0x0538, 0x05F0, 0x05F0, /* horizontal timings */
+ 0x0360, 0x0360, 0x0361, 0x0364, 0x037F, 0x037F, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (81L << 16) | ((6000L * 65536L) / 10000L), /* freq = 81.60 MHz */
+ },
+
+ { VG_SUPPORTFLAG_70HZ | /* refresh rate = 70 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ 0,
+ 1152, 864, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0480, 0x0480, 0x04C8, 0x0540, 0x0600, 0x0600, /* horizontal timings */
+ 0x0360, 0x0360, 0x0368, 0x036B, 0x038B, 0x038B, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (97L << 16) | ((5200L * 65536L) / 10000L), /* freq = 97.52 MHz */
+ },
+
+ { VG_SUPPORTFLAG_72HZ | /* refresh rate = 72 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ 0,
+ 1152, 864, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0480, 0x0480, 0x04C8, 0x0548, 0x0610, 0x0610, /* horizontal timings */
+ 0x0360, 0x0360, 0x0367, 0x036A, 0x038B, 0x038B, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (101L << 16) | ((4200L * 65536L) / 10000L), /* freq = 101.42 MHz */
+ },
+
+ { VG_SUPPORTFLAG_75HZ | /* refresh rate = 75 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ 0,
+ 1152, 864, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0480, 0x0480, 0x04C0, 0x0540, 0x0640, 0x0640, /* horizontal timings */
+ 0x0360, 0x0360, 0x0361, 0x0364, 0x0384, 0x0384, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (108L << 16) | ((0000L * 65536L) / 10000L), /* freq = 108.00 MHz */
+ },
+
+ { VG_SUPPORTFLAG_85HZ | /* refresh rate = 85 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ 0,
+ 1152, 864, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0480, 0x0480, 0x04C8, 0x0548, 0x0610, 0x0610, /* horizontal timings */
+ 0x0360, 0x0360, 0x0363, 0x0366, 0x038B, 0x038B, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (119L << 16) | ((6500L * 65536L) / 10000L), /* freq = 119.65 MHz */
+ },
+
+ { VG_SUPPORTFLAG_90HZ | /* refresh rate = 90 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ 0,
+ 1152, 864, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0480, 0x0480, 0x04D0, 0x0550, 0x0620, 0x0620, /* horizontal timings */
+ 0x0360, 0x0360, 0x0369, 0x036C, 0x0396, 0x0396, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (129L << 16) | ((6000L * 65536L) / 10000L), /* freq = 129.60 MHz */
+ },
+
+ { VG_SUPPORTFLAG_100HZ | /* refresh rate = 100 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ 0,
+ 1152, 864, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0480, 0x0480, 0x04D0, 0x0550, 0x0620, 0x0620, /* horizontal timings */
+ 0x0360, 0x0360, 0x0363, 0x0366, 0x0396, 0x0396, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (144L << 16) | ((0000L * 65536L) / 10000L), /* freq = 144.00 MHz */
+ },
+
+ /* 1152x864 PANEL */
+
+ { VG_SUPPORTFLAG_60HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP | /* All BPP supported. */
+ VG_SUPPORTFLAG_PANEL, /* Panel Mode. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ VG_MODEFLAG_PANELOUT | /* Panel output. */
+ VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC, /* negative syncs */
+ 1152, 864, /* No scaling. */
+ 1152, 864, /* 1152x864 active. */
+ 1152, 864, /* 1152x864 panel. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0480, 0x0480, 0x04C0, 0x0538, 0x05F0, 0x05F0, /* horizontal timings */
+ 0x0360, 0x0360, 0x0361, 0x0364, 0x037F, 0x037F, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (81L << 16) | ((6000L * 65536L) / 10000L), /* freq = 81.60 MHz */
+ },
+
+ /* 1280x1024 */
+
+ { VG_SUPPORTFLAG_60HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ 0,
+ 1280, 1024, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0500, 0x0500, 0x0530, 0x05A0, 0x0698, 0x0698, /* horizontal timings */
+ 0x0400, 0x0400, 0x0401, 0x0404, 0x042A, 0x042A, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (108L << 16) | ((0000L * 65536L) / 10000L), /* freq = 108.00 MHz */
+ },
+
+ { VG_SUPPORTFLAG_70HZ | /* refresh rate = 70 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ 0,
+ 1280, 1024, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0500, 0x0500, 0x0558, 0x05E0, 0x06C0, 0x06C0, /* horizontal timings */
+ 0x0400, 0x0400, 0x0406, 0x0409, 0x042F, 0x042F, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (129L << 16) | ((6000L * 65536L) / 10000L), /* freq = 129.60 MHz */
+ },
+
+ { VG_SUPPORTFLAG_72HZ | /* refresh rate = 72 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ 0,
+ 1280, 1024, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0500, 0x0500, 0x0558, 0x05E0, 0x06C0, 0x06C0, /* horizontal timings */
+ 0x0400, 0x0400, 0x0407, 0x040A, 0x0431, 0x0431, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (133L << 16) | ((5000L * 65536L) / 10000L), /* freq = 133.50 MHz */
+ },
+
+ { VG_SUPPORTFLAG_75HZ | /* refresh rate = 75 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ 0,
+ 1280, 1024, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0500, 0x0500, 0x0510, 0x05A0, 0x0698, 0x0698, /* horizontal timings */
+ 0x0400, 0x0400, 0x0401, 0x0404, 0x042A, 0x042A, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (135L << 16) | ((0000L * 65536L) / 10000L), /* freq = 135.0 MHz */
+ },
+
+ { VG_SUPPORTFLAG_85HZ | /* refresh rate = 85 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ 0,
+ 1280, 1024, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0500, 0x0500, 0x0540, 0x05E0, 0x06C0, 0x06C0, /* horizontal timings */
+ 0x0400, 0x0400, 0x0401, 0x0404, 0x0430, 0x0430, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (157L << 16) | ((5000L * 65536L) / 10000L), /* freq = 157.5 MHz */
+ },
+
+ { VG_SUPPORTFLAG_90HZ | /* refresh rate = 90 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ 0,
+ 1280, 1024, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0500, 0x0500, 0x0560, 0x05F0, 0x06E0, 0x06E0, /* horizontal timings */
+ 0x0400, 0x0400, 0x040C, 0x040F, 0x0442, 0x0442, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (172L << 16) | ((8000L * 65536L) / 10000L), /* freq = 172.80 MHz */
+ },
+
+ { VG_SUPPORTFLAG_100HZ | /* refresh rate = 100 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ 0,
+ 1280, 1024, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0500, 0x0500, 0x0560, 0x05F0, 0x06E0, 0x06E0, /* horizontal timings */
+ 0x0400, 0x0400, 0x0406, 0x0409, 0x0442, 0x0442, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (192L << 16) | ((0000L * 65536L) / 10000L), /* freq = 192.00 MHz */
+ },
+
+ /* 1280x1024 PANEL */
+
+ { VG_SUPPORTFLAG_60HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP | /* All BPP supported. */
+ VG_SUPPORTFLAG_PANEL, /* Panel Mode. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ VG_MODEFLAG_PANELOUT | /* Panel output. */
+ VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC, /* negative syncs */
+ 1280, 1024, /* No scaling. */
+ 1280, 1024, /* 1280x1024 active. */
+ 1280, 1024, /* 1280x1024 panel */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0500, 0x0500, 0x0530, 0x05A0, 0x0698, 0x0698, /* horizontal timings */
+ 0x0400, 0x0400, 0x0401, 0x0404, 0x042A, 0x042A, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (108L << 16) | ((0000L * 65536L) / 10000L), /* freq = 108.00 MHz */
+ },
+
+ /* 1600 x 1200 */
+
+ { VG_SUPPORTFLAG_60HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_HIGH_BAND | /* High bandwidth mode. */
+ 0,
+ 1600, 1200, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0640, 0x0640, 0x0680, 0x0740, 0x0870, 0x0870, /* horizontal timings */
+ 0x04B0, 0x04B0, 0x04B1, 0x04B4, 0x04E2, 0x04E2, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (162L << 16) | ((0000L * 65536L) / 10000L), /* freq = 162.0 MHz */
+ },
+
+ { VG_SUPPORTFLAG_70HZ | /* refresh rate = 70 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_HIGH_BAND | /* High bandwidth mode. */
+ 0,
+ 1600, 1200, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0640, 0x0640, 0x0680, 0x0740, 0x0870, 0x0870, /* horizontal timings */
+ 0x04B0, 0x04B0, 0x04B1, 0x04B4, 0x04E2, 0x04E2, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (189L << 16) | ((0000L * 65536L) / 10000L), /* freq = 189.0 MHz */
+ },
+
+ { VG_SUPPORTFLAG_72HZ | /* refresh rate = 72 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_HIGH_BAND | /* High bandwidth mode. */
+ 0,
+ 1600, 1200, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0640, 0x0640, 0x06B0, 0x0760, 0x0880, 0x0880, /* horizontal timings */
+ 0x04B0, 0x04B0, 0x04BD, 0x04C0, 0x04EF, 0x04EF, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (198L << 16) | ((0000L * 65536L) / 10000L), /* freq = 198.0 MHz */
+ },
+
+ { VG_SUPPORTFLAG_75HZ | /* refresh rate = 75 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_HIGH_BAND | /* High bandwidth mode. */
+ 0,
+ 1600, 1200, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0640, 0x0640, 0x0680, 0x0740, 0x0870, 0x0870, /* horizontal timings */
+ 0x04B0, 0x04B0, 0x04B1, 0x04B4, 0x04E2, 0x04E2, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (202L << 16) | ((5000L * 65536L) / 10000L), /* freq = 202.5 MHz */
+ },
+
+ { VG_SUPPORTFLAG_85HZ | /* refresh rate = 85 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_HIGH_BAND | /* High bandwidth mode. */
+ 0,
+ 1600, 1200, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0640, 0x0640, 0x0680, 0x0740, 0x0870, 0x0870, /* horizontal timings */
+ 0x04B0, 0x04B0, 0x04B1, 0x04B4, 0x04E2, 0x04E2, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (229L << 16) | ((5000L * 65536L) / 10000L), /* freq = 229.5 MHz */
+ },
+
+ { VG_SUPPORTFLAG_90HZ | /* refresh rate = 90 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_HIGH_BAND | /* High bandwidth mode. */
+ 0,
+ 1600, 1200, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0640, 0x0640, 0x06C0, 0x0770, 0x08A0, 0x08A0, /* horizontal timings */
+ 0x04B0, 0x04B0, 0x04B1, 0x04B4, 0x04F0, 0x04F0, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (251L << 16) | ((1820L * 65536L) / 10000L), /* freq = 251.182 MHz */
+ },
+
+ { VG_SUPPORTFLAG_100HZ | /* refresh rate = 100 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_HIGH_BAND | /* High bandwidth mode. */
+ 0,
+ 1600, 1200, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0640, 0x0640, 0x06C0, 0x0770, 0x08A0, 0x08A0, /* horizontal timings */
+ 0x04B0, 0x04B0, 0x04B1, 0x04B4, 0x04F7, 0x04F7, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (280L << 16) | ((6400L * 65536L) / 10000L), /* freq = 280.64 MHz */
+ },
+
+ /* 1600 x 1200 PANEL */
+
+ { VG_SUPPORTFLAG_60HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP | /* All BPP supported. */
+ VG_SUPPORTFLAG_PANEL, /* Panel Mode. */
+ VG_MODEFLAG_HIGH_BAND | /* High bandwidth mode. */
+ VG_MODEFLAG_PANELOUT | /* Panel output. */
+ VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC, /* negative syncs */
+ 1600, 1200, /* No scaling. */
+ 1600, 1200, /* 1600x1200 Active. */
+ 1600, 1200, /* 1600x1200 Panel. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0640, 0x0640, 0x0680, 0x0740, 0x0870, 0x0870, /* horizontal timings */
+ 0x04B0, 0x04B0, 0x04B1, 0x04B4, 0x04E2, 0x04E2, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (162L << 16) | ((0000L * 65536L) / 10000L), /* freq = 162.0 MHz */
+ },
+
+ /* 1920x1440 */
+
+ { VG_SUPPORTFLAG_60HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_HIGH_BAND | /* High bandwidth mode. */
+ 0,
+ 1920, 1440, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0780, 0x0780, 0x0800, 0x08D0, 0x0A28, 0x0A28, /* horizontal timings */
+ 0x05A0, 0x05A0, 0x05A1, 0x05A4, 0x05DC, 0x05DC, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (234L << 16) | ((0000L * 65536L) / 10000L), /* freq = 234.0 MHz */
+ },
+
+ { VG_SUPPORTFLAG_70HZ | /* refresh rate = 70 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_HIGH_BAND | /* High bandwidth mode. */
+ 0,
+ 1920, 1440, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0780, 0x0780, 0x0818, 0x08E8, 0x0A50, 0x0A50, /* horizontal timings */
+ 0x05A0, 0x05A0, 0x05A8, 0x05AB, 0x05E2, 0x05E2, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (278L << 16) | ((4000L * 65536L) / 10000L), /* freq = 278.4 MHz */
+ },
+
+ { VG_SUPPORTFLAG_72HZ | /* refresh rate = 70 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_HIGH_BAND | /* High bandwidth mode. */
+ 0,
+ 1920, 1440, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0780, 0x0780, 0x0818, 0x08E8, 0x0A50, 0x0A50, /* horizontal timings */
+ 0x05A0, 0x05A0, 0x05A4, 0x05A7, 0x05EB, 0x05EB, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (288L << 16) | ((0000L * 65536L) / 10000L), /* freq = 288.0 MHz */
+ },
+
+ { VG_SUPPORTFLAG_75HZ | /* refresh rate = 75 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_HIGH_BAND | /* High bandwidth mode. */
+ 0,
+ 1920, 1440, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0780, 0x0780, 0x0810, 0x08F0, 0x0A50, 0x0A50, /* horizontal timings */
+ 0x05A0, 0x05A0, 0x05A1, 0x05A4, 0x05DC, 0x05DC, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (297L << 16) | ((0000L * 65536L) / 10000L), /* freq = 297.0 MHz */
+ },
+
+ { VG_SUPPORTFLAG_85HZ | /* refresh rate = 85 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP, /* All BPP supported. */
+ VG_MODEFLAG_HIGH_BAND | /* High bandwidth mode. */
+ 0,
+ 1920, 1440, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0780, 0x0780, 0x0818, 0x08F0, 0x0A60, 0x0A60, /* horizontal timings */
+ 0x05A0, 0x05A0, 0x05A1, 0x05A4, 0x05E8, 0x05E8, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings */
+ (341L << 16) | ((3490L * 65536L) / 10000L), /* freq = 341.35 MHz */
+ },
+
+/*-------------------------------*/
+/* PREDEFINED TV TIMINGS */
+/*-------------------------------*/
+
+ /* 720 x 480i NTSC */
+
+ { VG_SUPPORTFLAG_60HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP | /* All BPP supported. */
+ VG_SUPPORTFLAG_NTSC | /* NTSC Mode. */
+ VG_SUPPORTFLAG_ADV7171 | VG_SUPPORTFLAG_SAA7127 |
+ VG_SUPPORTFLAG_ADV7300 | VG_SUPPORTFLAG_TVOUT, /* TV Mode. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ VG_MODEFLAG_INTERLACED | VG_MODEFLAG_TVOUT | /* Interlaced TV output */
+ VG_MODEFLAG_HALFCLOCK | /* DotPLL = 1/2 VOP */
+ VG_MODEFLAG_INT_FLICKER, /* Flicker Filter Out */
+ 720, 480, /* No downscaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x02D0, 0x02D0, 0x02E1, 0x0320, 0x035A, 0x035A, /* horizontal timings */
+ 0x00F0, 0x00F0, 0x00F4, 0x00F8, 0x0107, 0x0107, /* vertical timings */
+ 0x00F0, 0x00F0, 0x00F4, 0x00F8, 0x0106, 0x0106, /* Even field timings */
+ (27L << 16) | ((0000L * 65536L) / 10000L), /* freq = 27.0 MHz */
+ },
+
+ { VG_SUPPORTFLAG_60HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP | /* All BPP supported. */
+ VG_SUPPORTFLAG_NTSC | /* NTSC Mode. */
+ VG_SUPPORTFLAG_FS454 | VG_SUPPORTFLAG_TVOUT, /* TV Mode. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC | /* negative syncs */
+ VG_MODEFLAG_PANELOUT | VG_MODEFLAG_INVERT_SHFCLK, /* TFT Output. */
+ 640, 480, /* No downscaling. */
+ 640, 480, /* 640x480 active. */
+ 640, 480, /* 640x480 panel. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0280, 0x0280, 0x0333, 0x0373, 0x03A8, 0x03A8, /* horizontal timings */
+ 0x01E0, 0x01E0, 0x01F5, 0x01F7, 0x020D, 0x020D, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings. */
+ (25L << 16) | ((1750L * 65536L) / 10000L), /* freq = 25.175 MHz */
+ },
+
+ /* 800 x 600 NTSC */
+
+ { VG_SUPPORTFLAG_60HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP | /* All BPP supported. */
+ VG_SUPPORTFLAG_8X6_NTSC | /* 800x600 NTSC. */
+ VG_SUPPORTFLAG_FS454 | VG_SUPPORTFLAG_TVOUT, /* TV Mode. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC | /* negative syncs */
+ VG_MODEFLAG_PANELOUT | VG_MODEFLAG_INVERT_SHFCLK, /* Panel output */
+ 800, 600, /* No downscaling. */
+ 800, 600, /* 800x600 active. */
+ 800, 600, /* 800x600 active. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0320, 0x0320, 0x03A7, 0x03E7, 0x03F0, 0x03F0, /* horizontal timings */
+ 0x0258, 0x0258, 0x026A, 0x0272, 0x028A, 0x028A, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings. */
+ (40L << 16) | ((0000L * 65536L) / 10000L), /* freq = 40.000 MHz */
+ },
+
+ /* 1024 x 768 NTSC */
+
+ { VG_SUPPORTFLAG_60HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP | /* All BPP supported. */
+ VG_SUPPORTFLAG_10X7_NTSC | /* 1024x768 NTSC. */
+ VG_SUPPORTFLAG_FS454 | VG_SUPPORTFLAG_TVOUT, /* TV Mode. */
+ VG_MODEFLAG_AVG_BAND | /* Low bandwidth mode. */
+ VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC | /* negative syncs */
+ VG_MODEFLAG_PANELOUT | VG_MODEFLAG_INVERT_SHFCLK, /* Panel output */
+ 1024, 768, /* No downscaling. */
+ 1024, 768, /* 1024x768 active. */
+ 1024, 768, /* 1024x768 active. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0400, 0x0400, 0x0490, 0x04D0, 0x04E0, 0x04E0, /* horizontal timings */
+ 0x0300, 0x0300, 0x031B, 0x031D, 0x0339, 0x0339, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings. */
+ (65L << 16) | ((0000L * 65536L) / 10000L), /* freq = 65.00 MHz */
+ },
+
+ /* 720 x 576i PAL */
+
+ { VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP | /* All BPP supported. */
+ VG_SUPPORTFLAG_PAL | /* PAL Mode. */
+ VG_SUPPORTFLAG_ADV7171 | VG_SUPPORTFLAG_SAA7127 |
+ VG_SUPPORTFLAG_ADV7300 | VG_SUPPORTFLAG_TVOUT, /* TV Mode. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ VG_MODEFLAG_TVOUT | VG_MODEFLAG_INTERLACED | /* Interlaced TV out. */
+ VG_MODEFLAG_HALFCLOCK | /* DotPLL = 1/2 VOP */
+ VG_MODEFLAG_INT_FLICKER, /* Flicker Filter Out */
+ 720, 576, /* No downscaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x02D0, 0x02D0, 0x02E4, 0x0324, 0x0360, 0x0360, /* horizontal timings */
+ 0x0120, 0x0120, 0x0123, 0x0127, 0x0139, 0x0139, /* vertical timings */
+ 0x0120, 0x0120, 0x0123, 0x0127, 0x0138, 0x0138, /* Even timings */
+ (27L << 16) | ((0000L * 65536L) / 10000L), /* freq = 27.0 MHz */
+ },
+
+ { VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP | /* All BPP supported. */
+ VG_SUPPORTFLAG_PAL | /* PAL Mode. */
+ VG_SUPPORTFLAG_FS454 | VG_SUPPORTFLAG_TVOUT, /* TV Mode. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC | /* negative syncs */
+ VG_MODEFLAG_PANELOUT | VG_MODEFLAG_INVERT_SHFCLK, /* Panel output. */
+ 640, 480, /* No downscaling. */
+ 640, 480, /* No mode dimensions. */
+ 640, 480, /* 640x480 active. */
+ 0, 0, 0, 0, 0, /* 640x480 panel. */
+ 0x0280, 0x0280, 0x030F, 0x034F, 0x0360, 0x0360, /* horizontal timings */
+ 0x01E0, 0x01E0, 0x01F5, 0x01F7, 0x020D, 0x020D, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings. */
+ (25L << 16) | ((1750L * 65536L) / 10000L), /* freq = 25.175 MHz */
+ },
+
+ /* 800 x 600 PAL */
+
+ { VG_SUPPORTFLAG_60HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP | /* All BPP supported. */
+ VG_SUPPORTFLAG_8X6_PAL | /* 800x600 PAL. */
+ VG_SUPPORTFLAG_FS454 | VG_SUPPORTFLAG_TVOUT, /* TV Mode. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC | /* negative syncs */
+ VG_MODEFLAG_PANELOUT | VG_MODEFLAG_INVERT_SHFCLK, /* Panel output */
+ 800, 600, /* No downscaling. */
+ 800, 600, /* 800x600 active. */
+ 800, 600, /* 800x600 active. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0320, 0x0320, 0x03A7, 0x03E7, 0x03F0, 0x03F0, /* horizontal timings */
+ 0x0258, 0x0258, 0x0270, 0x0272, 0x028A, 0x028A, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings. */
+ (40L << 16) | ((0000L * 65536L) / 10000L), /* freq = 40.000 MHz */
+ },
+
+ /* 1024 x 768 PAL */
+
+ { VG_SUPPORTFLAG_60HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP | /* All BPP supported. */
+ VG_SUPPORTFLAG_10X7_PAL | /* 1024x768 NTSC. */
+ VG_SUPPORTFLAG_FS454 | VG_SUPPORTFLAG_TVOUT, /* TV Mode. */
+ VG_MODEFLAG_AVG_BAND | /* Low bandwidth mode. */
+ VG_MODEFLAG_NEG_HSYNC | VG_MODEFLAG_NEG_VSYNC | /* negative syncs */
+ VG_MODEFLAG_PANELOUT | VG_MODEFLAG_INVERT_SHFCLK, /* Panel output */
+ 1024, 768, /* No downscaling. */
+ 1024, 768, /* 1024x768 active. */
+ 1024, 768, /* 1024x768 active. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0400, 0x0400, 0x0490, 0x04d0, 0x04e0, 0x04e0, /* horizontal timings */
+ 0x0300, 0x0300, 0x031b, 0x031d, 0x0339, 0x0339, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings. */
+ (65L << 16) | ((0000L * 65536L) / 10000L), /* freq = 65.00 MHz */
+ },
+
+ /* 720 x 480p HDTV */
+
+ { VG_SUPPORTFLAG_60HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP | /* All BPP supported. */
+ VG_SUPPORTFLAG_480P | /* 720x480P. */
+ VG_SUPPORTFLAG_ADV7300 | VG_SUPPORTFLAG_TVOUT, /* TV Mode. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ VG_MODEFLAG_TVOUT, /* Progressive TV out. */
+ 720, 480, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x02D0, 0x02D0, 0x02E0, 0x0328, 0x035A, 0x035A, /* horizontal timings */
+ 0x01E0, 0x01E0, 0x01E1, 0x01E3, 0x020D, 0x020D, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings. */
+ (27L << 16) | ((0000L * 65536L) / 10000L), /* freq = 27.0 MHz */
+ },
+
+ { VG_SUPPORTFLAG_60HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP | /* All BPP supported. */
+ VG_SUPPORTFLAG_480P | /* 720x480P. */
+ VG_SUPPORTFLAG_FS454 | VG_SUPPORTFLAG_TVOUT, /* TV Mode. */
+ VG_MODEFLAG_LOW_BAND | /* Low bandwidth mode. */
+ VG_MODEFLAG_PANELOUT | VG_MODEFLAG_INVERT_SHFCLK, /* Panel output. */
+ 720, 480, /* No scaling. */
+ 720, 480, /* 720x480 active. */
+ 720, 480, /* 720x480 panel. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x02D0, 0x02D0, 0x02E3, 0x0323, 0x035A, 0x035A, /* horizontal timings */
+ 0x01E0, 0x01E0, 0x01E4, 0x01EA, 0x020D, 0x020D, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings. */
+ (27L << 16) | ((0000L * 65536L) / 10000L), /* freq = 27.0 MHz */
+ },
+
+ /* 1280x720p HDTV */
+
+ { VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP | /* All BPP supported. */
+ VG_SUPPORTFLAG_720P | /* 1280x720P */
+ VG_SUPPORTFLAG_ADV7300 | VG_SUPPORTFLAG_TVOUT, /* TV Mode. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ VG_MODEFLAG_TVOUT, /* Progressive TV out */
+ 1280, 720, /* No scaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0500, 0x0500, 0x0546, 0x0596, 0x0672, 0x0672, /* horizontal timings */
+ 0x02D0, 0x02D0, 0x02D3, 0x02D8, 0x02EE, 0x02EE, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* even timings */
+ (74L << 16) | ((2500L * 65536L) / 10000L), /* freq = 74.25 MHz */
+ },
+
+ { VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP | /* All BPP supported. */
+ VG_SUPPORTFLAG_720P | /* 1280x720P */
+ VG_SUPPORTFLAG_FS454 | VG_SUPPORTFLAG_TVOUT, /* TV Mode. */
+ VG_MODEFLAG_AVG_BAND | /* Avg bandwidth mode. */
+ VG_MODEFLAG_PANELOUT | VG_MODEFLAG_INVERT_SHFCLK, /* Panel output. */
+ 1280, 720, /* No scaling. */
+ 1280, 720, /* 1280x720 active. */
+ 1280, 720, /* 1280x720 panel. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0500, 0x0500, 0x0547, 0x0597, 0x0672, 0x0672, /* horizontal timings */
+ 0x02D0, 0x02D0, 0x02D4, 0x02D9, 0x02EE, 0x02EE, /* vertical timings */
+ 0, 0, 0, 0, 0, 0, /* No even timings. */
+ (74L << 16) | ((2500L * 65536L) / 10000L), /* freq = 74.25 MHz */
+ },
+
+ /* 1920x1080i HDTV */
+
+ { VG_SUPPORTFLAG_60HZ | /* refresh rate = 60 */
+ VG_SUPPORTFLAG_8BPP | VG_SUPPORTFLAG_12BPP |
+ VG_SUPPORTFLAG_15BPP | VG_SUPPORTFLAG_16BPP |
+ VG_SUPPORTFLAG_24BPP | VG_SUPPORTFLAG_32BPP | /* All BPP supported. */
+ VG_SUPPORTFLAG_1080I | /* 1920x1080i Mode. */
+ VG_SUPPORTFLAG_ADV7300 | VG_SUPPORTFLAG_FS454 |
+ VG_SUPPORTFLAG_TVOUT, /* TV Mode. */
+ VG_MODEFLAG_HIGH_BAND | /* High bandwidth mode. */
+ VG_MODEFLAG_INTERLACED | VG_MODEFLAG_TVOUT | /* Interlaced TV output */
+ VG_MODEFLAG_INT_ADDRESS | VG_MODEFLAG_INVERT_SHFCLK, /* Interlaced addressing*/
+ 1920, 1080, /* 2:1 downscaling. */
+ 0, 0, /* No mode dimensions. */
+ 0, 0, /* No panel dimensions. */
+ 0, 0, 0, 0, 0, /* No panel registers */
+ 0x0780, 0x0780, 0x07AD, 0x0805, 0x0898, 0x0898, /* horizontal timings */
+ 0x021C, 0x021C, 0x021E, 0x0226, 0x0233, 0x0233, /* vertical timings */
+ 0x021C, 0x021C, 0x021E, 0x0226, 0x0232, 0x0232, /* even field timings */
+ (74L << 16) | ((2500L * 65536L) / 10000L), /* freq = 74.25 MHz */
+ },
+};
+
+#define NUM_CIMARRON_DISPLAY_MODES sizeof(CimarronDisplayModes) / sizeof(VG_DISPLAY_MODE)
+
+/*-----------------------------------*/
+/* PREDEFINED PLL FREQUENCIES */
+/*-----------------------------------*/
+
+PLL_FREQUENCY CimarronPLLFrequencies[] =
+{
+ { 0x000031AC, (24L << 16) | ((9230L * 65536L) / 10000L) }, /* 24.9230, - 4,27,13 */
+ { 0x0000215D, (25L << 16) | ((1750L * 65536L) / 10000L) }, /* 25.1750, - 3,22,14 */
+ { 0x00001087, (27L << 16) | ((0000L * 65536L) / 10000L) }, /* 27.0000, - 2, 9, 8 */
+ { 0x0000216C, (28L << 16) | ((3220L * 65536L) / 10000L) }, /* 28.3220, - 3,23,13 */
+ { 0x0000218D, (28L << 16) | ((5600L * 65536L) / 10000L) }, /* 28.5600, - 3,25,14 */
+ { 0x000010C9, (31L << 16) | ((2000L * 65536L) / 10000L) }, /* 31.2000, - 2,13,10 */
+ { 0x00003147, (31L << 16) | ((5000L * 65536L) / 10000L) }, /* 31.5000, - 4,21, 8 */
+ { 0x000010A7, (33L << 16) | ((320L * 65536L) / 10000L) }, /* 33.0320, - 2,11, 8 */
+ { 0x00002159, (35L << 16) | ((1120L * 65536L) / 10000L) }, /* 35.1120, - 3,22,10 */
+ { 0x00004249, (35L << 16) | ((5000L * 65536L) / 10000L) }, /* 35.5000, - 5,37,10 */
+ { 0x00000057, (36L << 16) | ((0000L * 65536L) / 10000L) }, /* 36.0000, - 1, 6, 8 */
+ { 0x0000219A, (37L << 16) | ((8890L * 65536L) / 10000L) }, /* 37.8890, - 3,26,11 */
+ { 0x00002158, (39L << 16) | ((1680L * 65536L) / 10000L) }, /* 39.1680, - 3,22, 9 */
+ { 0x00000045, (40L << 16) | ((0000L * 65536L) / 10000L) }, /* 40.0000, - 1, 5, 6 */
+ { 0x00000089, (43L << 16) | ((1630L * 65536L) / 10000L) }, /* 43.1630, - 1, 9,10 */
+ { 0x000010E7, (44L << 16) | ((9000L * 65536L) / 10000L) }, /* 44.9000, - 2,15, 8 */
+ { 0x00002136, (45L << 16) | ((7200L * 65536L) / 10000L) }, /* 45.7200, - 3,20, 7 */
+ { 0x00003207, (49L << 16) | ((5000L * 65536L) / 10000L) }, /* 49.5000, - 4,33, 8 */
+ { 0x00002187, (50L << 16) | ((0000L * 65536L) / 10000L) }, /* 50.0000, - 3,25, 8 */
+ { 0x00004286, (56L << 16) | ((2500L * 65536L) / 10000L) }, /* 56.2500, - 5,41, 7 */
+ { 0x000010E5, (60L << 16) | ((650L * 65536L) / 10000L) }, /* 60.0650, - 2,15, 6 */
+ { 0x00004214, (65L << 16) | ((0000L * 65536L) / 10000L) }, /* 65.0000, - 5,34, 5 */
+ { 0x00001105, (68L << 16) | ((1790L * 65536L) / 10000L) }, /* 68.1790, - 2,17, 6 */
+ { 0x000031E4, (74L << 16) | ((2500L * 65536L) / 10000L) }, /* 74.2500, - 4,31, 5 */
+ { 0x00003183, (75L << 16) | ((0000L * 65536L) / 10000L) }, /* 75.0000, - 4,25, 4 */
+ { 0x00004284, (78L << 16) | ((7500L * 65536L) / 10000L) }, /* 78.7500, - 5,41, 5 */
+ { 0x00001104, (81L << 16) | ((6000L * 65536L) / 10000L) }, /* 81.6000, - 2,17, 5 */
+ { 0x00006363, (94L << 16) | ((5000L * 65536L) / 10000L) }, /* 94.5000, - 7,55, 4 */
+ { 0x00005303, (97L << 16) | ((5200L * 65536L) / 10000L) }, /* 97.5200, - 6,49, 4 */
+ { 0x00002183, (100L << 16) | ((1870L * 65536L) / 10000L) }, /* 100.187, - 3,25, 4 */
+ { 0x00002122, (101L << 16) | ((4200L * 65536L) / 10000L) }, /* 101.420, - 3,19, 3 */
+ { 0x00001081, (108L << 16) | ((0000L * 65536L) / 10000L) }, /* 108.00, - 2, 9, 2 */
+ { 0x00006201, (113L << 16) | ((3100L * 65536L) / 10000L) }, /* 113.31, - 7,33, 2 */
+ { 0x00000041, (119L << 16) | ((6500L * 65536L) / 10000L) }, /* 119.65, - 1, 5, 2 */
+ { 0x000041A1, (129L << 16) | ((6000L * 65536L) / 10000L) }, /* 129.60, - 5,27, 2 */
+ { 0x00002182, (133L << 16) | ((5000L * 65536L) / 10000L) }, /* 133.50, - 3,25, 3 */
+ { 0x000041B1, (135L << 16) | ((0000L * 65536L) / 10000L) }, /* 135.00, - 5,28, 2 */
+ { 0x00000051, (144L << 16) | ((0000L * 65536L) / 10000L) }, /* 144.00, - 1, 6, 2 */
+ { 0x000041E1, (148L << 16) | ((5000L * 65536L) / 10000L) }, /* 148.50, - 5,31, 2 */
+ { 0x000062D1, (157L << 16) | ((5000L * 65536L) / 10000L) }, /* 157.50, - 7,46, 2 */
+ { 0x000031A1, (162L << 16) | ((0000L * 65536L) / 10000L) }, /* 162.00, - 4,27, 2 */
+ { 0x00000061, (169L << 16) | ((2030L * 65536L) / 10000L) }, /* 169.203, - 1, 7, 2 */
+ { 0x00004231, (172L << 16) | ((8000L * 65536L) / 10000L) }, /* 172.800, - 5,36, 2 */
+ { 0x00002151, (175L << 16) | ((5000L * 65536L) / 10000L) }, /* 175.50, - 3,22, 2 */
+ { 0x000052E1, (189L << 16) | ((0000L * 65536L) / 10000L) }, /* 189.00, - 6,47, 2 */
+ { 0x00000071, (192L << 16) | ((0000L * 65536L) / 10000L) }, /* 192.00, - 1, 8, 2 */
+ { 0x00003201, (198L << 16) | ((0000L * 65536L) / 10000L) }, /* 198.00, - 4,33, 2 */
+ { 0x00004291, (202L << 16) | ((5000L * 65536L) / 10000L) }, /* 202.50, - 5,42, 2 */
+ { 0x00001101, (204L << 16) | ((7500L * 65536L) / 10000L) }, /* 204.75, - 2,17, 2 */
+ { 0x00007481, (218L << 16) | ((2500L * 65536L) / 10000L) }, /* 218.25, - 8,73, 2 */
+ { 0x00004170, (229L << 16) | ((5000L * 65536L) / 10000L) }, /* 229.50, - 5,24, 1 */
+ { 0x00006210, (234L << 16) | ((0000L * 65536L) / 10000L) }, /* 234.00, - 7,34, 1 */
+ { 0x00003140, (251L << 16) | ((1820L * 65536L) / 10000L) }, /* 251.182, - 4,21, 1 */
+ { 0x00006250, (261L << 16) | ((0000L * 65536L) / 10000L) }, /* 261.00, - 7,38, 1 */
+ { 0x000041C0, (278L << 16) | ((4000L * 65536L) / 10000L) }, /* 278.40, - 5,29, 1 */
+ { 0x00005220, (280L << 16) | ((6400L * 65536L) / 10000L) }, /* 280.64, - 6,35, 1 */
+ { 0x00000050, (288L << 16) | ((0000L * 65536L) / 10000L) }, /* 288.00, - 1, 6, 1 */
+ { 0x000041E0, (297L << 16) | ((0000L * 65536L) / 10000L) }, /* 297.00, - 5,31, 1 */
+ { 0x00002130, (320L << 16) | ((2070L * 65536L) / 10000L) }, /* 320.207, - 3,20, 1 */
+ { 0x00006310, (341L << 16) | ((3490L * 65536L) / 10000L) } /* 341.349, - 7,50, 1 */
+};
+
+#define NUM_CIMARRON_PLL_FREQUENCIES sizeof(CimarronPLLFrequencies) / sizeof(PLL_FREQUENCY)
+
+/*-----------------------------------*/
+/* PREDEFINED FILTER COEFFICIENTS */
+/*-----------------------------------*/
+
+unsigned long CimarronHorizontalGraphicsFilter[][2] =
+{
+ {0x1284A7D5, 0x000017D5 }, /* -43, 297, 296, -43, 5 */
+ {0x12A497D7, 0x000013D6 }, /* -41, 293, 298, -42, 4 */
+ {0x12D48BD7, 0x000013D6 }, /* -41, 290, 301, -42, 4 */
+ {0x13147FD7, 0x000013D5 }, /* -41, 287, 305, -43, 4 */
+ {0x133473D8, 0x000013D5 }, /* -40, 284, 307, -43, 4 */
+ {0x136467D8, 0x000013D5 }, /* -40, 281, 310, -43, 4 */
+ {0x13945FD8, 0x000013D4 }, /* -40, 279, 313, -44, 4 */
+ {0x13B453D9, 0x000013D4 }, /* -39, 276, 315, -44, 4 */
+ {0x13E447D9, 0x000013D4 }, /* -39, 273, 318, -44, 4 */
+ {0x14143BDA, 0x000013D3 }, /* -38, 270, 321, -45, 4 */
+ {0x143433DA, 0x000013D3 }, /* -38, 268, 323, -45, 4 */
+ {0x146427DA, 0x000013D3 }, /* -38, 265, 326, -45, 4 */
+ {0x14941BDB, 0x000013D2 }, /* -37, 262, 329, -46, 4 */
+ {0x14C40FDB, 0x000013D2 }, /* -37, 259, 332, -46, 4 */
+ {0x14F407DA, 0x000017D1 }, /* -38, 257, 335, -47, 5 */
+ {0x1503FBDC, 0x000013D2 }, /* -36, 254, 336, -46, 4 */
+ {0x1543F3DB, 0x000017D0 }, /* -37, 252, 340, -48, 5 */
+ {0x1563E3DD, 0x000013D1 }, /* -35, 248, 342, -47, 4 */
+ {0x1593D7DD, 0x000013D1 }, /* -35, 245, 345, -47, 4 */
+ {0x15B3CFDD, 0x000013D1 }, /* -35, 243, 347, -47, 4 */
+ {0x15E3C3DE, 0x000013D0 }, /* -34, 240, 350, -48, 4 */
+ {0x1613B7DE, 0x000013D0 }, /* -34, 237, 353, -48, 4 */
+ {0x1633ABDF, 0x000013D0 }, /* -33, 234, 355, -48, 4 */
+ {0x16639FDF, 0x000013D0 }, /* -33, 231, 358, -48, 4 */
+ {0x167397E0, 0x000013D0 }, /* -32, 229, 359, -48, 4 */
+ {0x16B38BE0, 0x000013CF }, /* -32, 226, 363, -49, 4 */
+ {0x16E383DF, 0x000017CE }, /* -33, 224, 366, -50, 5 */
+ {0x170373E1, 0x000013CF }, /* -31, 220, 368, -49, 4 */
+ {0x17236BE1, 0x000013CF }, /* -31, 218, 370, -49, 4 */
+ {0x17435FE2, 0x000013CF }, /* -30, 215, 372, -49, 4 */
+ {0x177353E2, 0x000013CF }, /* -30, 212, 375, -49, 4 */
+ {0x17B34BE1, 0x000017CD }, /* -31, 210, 379, -51, 5 */
+ {0x17C33FE3, 0x000013CE }, /* -29, 207, 380, -50, 4 */
+ {0x17F333E3, 0x000013CE }, /* -29, 204, 383, -50, 4 */
+ {0x181327E4, 0x000013CE }, /* -28, 201, 385, -50, 4 */
+ {0x18431FE3, 0x000017CD }, /* -29, 199, 388, -51, 5 */
+ {0x186313E4, 0x000013CE }, /* -28, 196, 390, -50, 4 */
+ {0x188307E5, 0x000013CE }, /* -27, 193, 392, -50, 4 */
+ {0x18B2FBE5, 0x000013CE }, /* -27, 190, 395, -50, 4 */
+ {0x18C2F3E6, 0x000013CE }, /* -26, 188, 396, -50, 4 */
+ {0x18F2E7E6, 0x000013CE }, /* -26, 185, 399, -50, 4 */
+ {0x1912DBE7, 0x000013CE }, /* -25, 182, 401, -50, 4 */
+ {0x1952D3E6, 0x000017CC }, /* -26, 180, 405, -52, 5 */
+ {0x1972CBE6, 0x000017CC }, /* -26, 178, 407, -52, 5 */
+ {0x1992BFE7, 0x000017CC }, /* -25, 175, 409, -52, 5 */
+ {0x19C2B3E7, 0x000017CC }, /* -25, 172, 412, -52, 5 */
+ {0x19D2A7E9, 0x000013CD }, /* -23, 169, 413, -51, 4 */
+ {0x1A029FE8, 0x000017CC }, /* -24, 167, 416, -52, 5 */
+ {0x1A1293E9, 0x000013CE }, /* -23, 164, 417, -50, 4 */
+ {0x1A3287EA, 0x000013CE }, /* -22, 161, 419, -50, 4 */
+ {0x1A627FE9, 0x000017CD }, /* -23, 159, 422, -51, 5 */
+ {0x1A7273EB, 0x000013CE }, /* -21, 156, 423, -50, 4 */
+ {0x1AA267EB, 0x000013CE }, /* -21, 153, 426, -50, 4 */
+ {0x1AC25FEB, 0x000013CE }, /* -21, 151, 428, -50, 4 */
+ {0x1AE253EC, 0x000013CE }, /* -20, 148, 430, -50, 4 */
+ {0x1B124BEB, 0x000017CD }, /* -21, 146, 433, -51, 5 */
+ {0x1B223FED, 0x000013CE }, /* -19, 143, 434, -50, 4 */
+ {0x1B5237EC, 0x000017CD }, /* -20, 141, 437, -51, 5 */
+ {0x1B622BED, 0x000013CF }, /* -19, 138, 438, -49, 4 */
+ {0x1B821FEE, 0x000013CF }, /* -18, 135, 440, -49, 4 */
+ {0x1BA217EE, 0x000013CF }, /* -18, 133, 442, -49, 4 */
+ {0x1BC20BEF, 0x000013CF }, /* -17, 130, 444, -49, 4 */
+ {0x1BE203EF, 0x000013CF }, /* -17, 128, 446, -49, 4 */
+ {0x1C01FBEE, 0x000017CF }, /* -18, 126, 448, -49, 5 */
+ {0x1C11EFF0, 0x000013D0 }, /* -16, 123, 449, -48, 4 */
+ {0x1C41E7EF, 0x000017CF }, /* -17, 121, 452, -49, 5 */
+ {0x1C61DFEF, 0x000017CF }, /* -17, 119, 454, -49, 5 */
+ {0x1C61D3F1, 0x000013D1 }, /* -15, 116, 454, -47, 4 */
+ {0x1C91CBF0, 0x000017D0 }, /* -16, 114, 457, -48, 5 */
+ {0x1CA1BFF2, 0x000013D1 }, /* -14, 111, 458, -47, 4 */
+ {0x1CC1B3F2, 0x000013D2 }, /* -14, 108, 460, -46, 4 */
+ {0x1CE1AFF1, 0x000017D1 }, /* -15, 107, 462, -47, 5 */
+ {0x1CF1A3F3, 0x000013D2 }, /* -13, 104, 463, -46, 4 */
+ {0x1D1197F3, 0x000013D3 }, /* -13, 101, 465, -45, 4 */
+ {0x1D3197F2, 0x000013D2 }, /* -14, 101, 467, -46, 4 */
+ {0x1D518BF3, 0x000013D2 }, /* -13, 98, 469, -46, 4 */
+ {0x1D6183F3, 0x000013D3 }, /* -13, 96, 470, -45, 4 */
+ {0x1D817BF3, 0x000013D3 }, /* -13, 94, 472, -45, 4 */
+ {0x1D916FF4, 0x000013D4 }, /* -12, 91, 473, -44, 4 */
+ {0x1DB167F4, 0x000013D4 }, /* -12, 89, 475, -44, 4 */
+ {0x1DC15FF4, 0x000013D5 }, /* -12, 87, 476, -43, 4 */
+ {0x1DE153F5, 0x000013D5 }, /* -11, 84, 478, -43, 4 */
+ {0x1DF14BF5, 0x000013D6 }, /* -11, 82, 479, -42, 4 */
+ {0x1E1143F5, 0x000013D6 }, /* -11, 80, 481, -42, 4 */
+ {0x1E1137F7, 0x00000FD8 }, /* -9, 77, 481, -40, 3 */
+ {0x1E3133F6, 0x000013D7 }, /* -10, 76, 483, -41, 4 */
+ {0x1E412BF6, 0x000013D8 }, /* -10, 74, 484, -40, 4 */
+ {0x1E611FF7, 0x000013D8 }, /* -9, 71, 486, -40, 4 */
+ {0x1E7117F7, 0x000013D9 }, /* -9, 69, 487, -39, 4 */
+ {0x1E810FF7, 0x000013DA }, /* -9, 67, 488, -38, 4 */
+ {0x1E9107F8, 0x000013DA }, /* -8, 65, 489, -38, 4 */
+ {0x1EA0FFF8, 0x000013DB }, /* -8, 63, 490, -37, 4 */
+ {0x1EB0F3F9, 0x00000FDD }, /* -7, 60, 491, -35, 3 */
+ {0x1ED0EFF8, 0x000013DC }, /* -8, 59, 493, -36, 4 */
+ {0x1EE0E7F9, 0x00000FDD }, /* -7, 57, 494, -35, 3 */
+ {0x1EF0DFF9, 0x00000FDE }, /* -7, 55, 495, -34, 3 */
+ {0x1F00D7F9, 0x00000FDF }, /* -7, 53, 496, -33, 3 */
+ {0x1F10CFFA, 0x00000FDF }, /* -6, 51, 497, -33, 3 */
+ {0x1F20C7FA, 0x00000FE0 }, /* -6, 49, 498, -32, 3 */
+ {0x1F20C3FA, 0x00000FE1 }, /* -6, 48, 498, -31, 3 */
+ {0x1F30BBFA, 0x00000FE2 }, /* -6, 46, 499, -30, 3 */
+ {0x1F40AFFB, 0x00000FE3 }, /* -5, 43, 500, -29, 3 */
+ {0x1F50A7FB, 0x00000FE4 }, /* -5, 41, 501, -28, 3 */
+ {0x1F60A3FB, 0x00000FE4 }, /* -5, 40, 502, -28, 3 */
+ {0x1F709BFB, 0x00000FE5 }, /* -5, 38, 503, -27, 3 */
+ {0x1F7093FC, 0x00000FE6 }, /* -4, 36, 503, -26, 3 */
+ {0x1F808FFC, 0x00000BE7 }, /* -4, 35, 504, -25, 2 */
+ {0x1F9087FC, 0x00000BE8 }, /* -4, 33, 505, -24, 2 */
+ {0x1F9083FC, 0x00000BE9 }, /* -4, 32, 505, -23, 2 */
+ {0x1FA077FD, 0x00000BEA }, /* -3, 29, 506, -22, 2 */
+ {0x1FA073FD, 0x00000BEB }, /* -3, 28, 506, -21, 2 */
+ {0x1FB06BFD, 0x00000BEC }, /* -3, 26, 507, -20, 2 */
+ {0x1FC063FD, 0x00000BED }, /* -3, 24, 508, -19, 2 */
+ {0x1FC05BFE, 0x00000BEE }, /* -2, 22, 508, -18, 2 */
+ {0x1FC057FE, 0x00000BEF }, /* -2, 21, 508, -17, 2 */
+ {0x1FD053FE, 0x000007F0 }, /* -2, 20, 509, -16, 1 */
+ {0x1FD04BFE, 0x000007F2 }, /* -2, 18, 509, -14, 1 */
+ {0x1FE043FE, 0x000007F3 }, /* -2, 16, 510, -13, 1 */
+ {0x1FE03BFF, 0x000007F4 }, /* -1, 14, 510, -12, 1 */
+ {0x1FE037FF, 0x000007F5 }, /* -1, 13, 510, -11, 1 */
+ {0x1FE033FF, 0x000007F6 }, /* -1, 12, 510, -10, 1 */
+ {0x1FF02BFF, 0x000007F7 }, /* -1, 10, 511, -9, 1 */
+ {0x1FF027FF, 0x000003F9 }, /* -1, 9, 511, -7, 0 */
+ {0x1FF01C00, 0x000003FA }, /* 0, 7, 511, -6, 0 */
+ {0x1FF01800, 0x000003FB }, /* 0, 6, 511, -5, 0 */
+ {0x1FF01400, 0x000003FC }, /* 0, 5, 511, -4, 0 */
+ {0x1FF00C00, 0x000003FE }, /* 0, 3, 511, -2, 0 */
+ {0x1FF00800, 0x000003FF }, /* 0, 2, 511, -1, 0 */
+ {0x1FF00400, 0x00000000 }, /* 0, 1, 511, 0, 0 */
+ {0x1FFFFC00, 0x00000002 }, /* 0, -1, 511, 2, 0 */
+ {0x1FFFF800, 0x00000003 }, /* 0, -2, 511, 3, 0 */
+ {0x1FFFF000, 0x00000005 }, /* 0, -4, 511, 5, 0 */
+ {0x1FFFEC00, 0x00000006 }, /* 0, -5, 511, 6, 0 */
+ {0x1FFFE800, 0x00000007 }, /* 0, -6, 511, 7, 0 */
+ {0x1FFFE400, 0x000FFC09 }, /* 0, -7, 511, 9, -1 */
+ {0x1FFFDC01, 0x000FFC0A }, /* 1, -9, 511, 10, -1 */
+ {0x1FEFDC01, 0x000FFC0B }, /* 1, -9, 510, 11, -1 */
+ {0x1FEFD401, 0x000FFC0D }, /* 1, -11, 510, 13, -1 */
+ {0x1FEFD001, 0x000FFC0E }, /* 1, -12, 510, 14, -1 */
+ {0x1FEFCC01, 0x000FF810 }, /* 1, -13, 510, 16, -2 */
+ {0x1FDFCC01, 0x000FF811 }, /* 1, -13, 509, 17, -2 */
+ {0x1FDFC401, 0x000FF813 }, /* 1, -15, 509, 19, -2 */
+ {0x1FCFC002, 0x000FF814 }, /* 2, -16, 508, 20, -2 */
+ {0x1FCFB802, 0x000FF816 }, /* 2, -18, 508, 22, -2 */
+ {0x1FCFB402, 0x000FF418 }, /* 2, -19, 508, 24, -3 */
+ {0x1FBFB402, 0x000FF419 }, /* 2, -19, 507, 25, -3 */
+ {0x1FAFB002, 0x000FF41B }, /* 2, -20, 506, 27, -3 */
+ {0x1FAFA802, 0x000FF41D }, /* 2, -22, 506, 29, -3 */
+ {0x1F9FA802, 0x000FF01F }, /* 2, -22, 505, 31, -4 */
+ {0x1F9FA402, 0x000FF020 }, /* 2, -23, 505, 32, -4 */
+ {0x1F8FA002, 0x000FF022 }, /* 2, -24, 504, 34, -4 */
+ {0x1F7F9803, 0x000FF024 }, /* 3, -26, 503, 36, -4 */
+ {0x1F7F9403, 0x000FEC26 }, /* 3, -27, 503, 38, -5 */
+ {0x1F6F9003, 0x000FEC28 }, /* 3, -28, 502, 40, -5 */
+ {0x1F5F9003, 0x000FEC29 }, /* 3, -28, 501, 41, -5 */
+ {0x1F4F8C03, 0x000FEC2B }, /* 3, -29, 500, 43, -5 */
+ {0x1F3F8C03, 0x000FE82D }, /* 3, -29, 499, 45, -6 */
+ {0x1F2F8803, 0x000FE82F }, /* 3, -30, 498, 47, -6 */
+ {0x1F2F8003, 0x000FE831 }, /* 3, -32, 498, 49, -6 */
+ {0x1F1F7C03, 0x000FE833 }, /* 3, -33, 497, 51, -6 */
+ {0x1F0F7C03, 0x000FE435 }, /* 3, -33, 496, 53, -7 */
+ {0x1EFF7803, 0x000FE437 }, /* 3, -34, 495, 55, -7 */
+ {0x1EEF7403, 0x000FE439 }, /* 3, -35, 494, 57, -7 */
+ {0x1EDF7004, 0x000FE03B }, /* 4, -36, 493, 59, -8 */
+ {0x1EBF7403, 0x000FE43C }, /* 3, -35, 491, 60, -7 */
+ {0x1EAF6C04, 0x000FE03F }, /* 4, -37, 490, 63, -8 */
+ {0x1E9F6804, 0x000FE041 }, /* 4, -38, 489, 65, -8 */
+ {0x1E8F6804, 0x000FDC43 }, /* 4, -38, 488, 67, -9 */
+ {0x1E7F6404, 0x000FDC45 }, /* 4, -39, 487, 69, -9 */
+ {0x1E6F6004, 0x000FDC47 }, /* 4, -40, 486, 71, -9 */
+ {0x1E4F6404, 0x000FD849 }, /* 4, -39, 484, 73, -10 */
+ {0x1E3F6004, 0x000FD84B }, /* 4, -40, 483, 75, -10 */
+ {0x1E1F6003, 0x000FDC4D }, /* 3, -40, 481, 77, -9 */
+ {0x1E1F5804, 0x000FD450 }, /* 4, -42, 481, 80, -11 */
+ {0x1DFF5804, 0x000FD452 }, /* 4, -42, 479, 82, -11 */
+ {0x1DEF5404, 0x000FD454 }, /* 4, -43, 478, 84, -11 */
+ {0x1DCF5804, 0x000FD056 }, /* 4, -42, 476, 86, -12 */
+ {0x1DBF5004, 0x000FD059 }, /* 4, -44, 475, 89, -12 */
+ {0x1D9F5004, 0x000FD05B }, /* 4, -44, 473, 91, -12 */
+ {0x1D8F5004, 0x000FCC5D }, /* 4, -44, 472, 93, -13 */
+ {0x1D6F5004, 0x000FCC5F }, /* 4, -44, 470, 95, -13 */
+ {0x1D5F4804, 0x000FCC62 }, /* 4, -46, 469, 98, -13 */
+ {0x1D3F4C04, 0x000FC864 }, /* 4, -45, 467, 100, -14 */
+ {0x1D1F4C04, 0x000FCC65 }, /* 4, -45, 465, 101, -13 */
+ {0x1CFF4804, 0x000FCC68 }, /* 4, -46, 463, 104, -13 */
+ {0x1CEF4405, 0x000FC46B }, /* 5, -47, 462, 107, -15 */
+ {0x1CCF4804, 0x000FC86C }, /* 4, -46, 460, 108, -14 */
+ {0x1CAF4404, 0x000FC86F }, /* 4, -47, 458, 111, -14 */
+ {0x1C9F4005, 0x000FC072 }, /* 5, -48, 457, 114, -16 */
+ {0x1C6F4404, 0x000FC474 }, /* 4, -47, 454, 116, -15 */
+ {0x1C6F3C05, 0x000FBC77 }, /* 5, -49, 454, 119, -17 */
+ {0x1C4F3C05, 0x000FBC79 }, /* 5, -49, 452, 121, -17 */
+ {0x1C1F4004, 0x000FC07B }, /* 4, -48, 449, 123, -16 */
+ {0x1C0F3C05, 0x000FB87E }, /* 5, -49, 448, 126, -18 */
+ {0x1BEF3C04, 0x000FBC80 }, /* 4, -49, 446, 128, -17 */
+ {0x1BCF3C04, 0x000FBC82 }, /* 4, -49, 444, 130, -17 */
+ {0x1BAF3C04, 0x000FB885 }, /* 4, -49, 442, 133, -18 */
+ {0x1B8F3C04, 0x000FB887 }, /* 4, -49, 440, 135, -18 */
+ {0x1B6F3C04, 0x000FB48A }, /* 4, -49, 438, 138, -19 */
+ {0x1B5F3405, 0x000FB08D }, /* 5, -51, 437, 141, -20 */
+ {0x1B2F3804, 0x000FB48F }, /* 4, -50, 434, 143, -19 */
+ {0x1B1F3405, 0x000FAC92 }, /* 5, -51, 433, 146, -21 */
+ {0x1AEF3804, 0x000FB094 }, /* 4, -50, 430, 148, -20 */
+ {0x1ACF3804, 0x000FAC97 }, /* 4, -50, 428, 151, -21 */
+ {0x1AAF3804, 0x000FAC99 }, /* 4, -50, 426, 153, -21 */
+ {0x1A7F3804, 0x000FAC9C }, /* 4, -50, 423, 156, -21 */
+ {0x1A6F3405, 0x000FA49F }, /* 5, -51, 422, 159, -23 */
+ {0x1A3F3804, 0x000FA8A1 }, /* 4, -50, 419, 161, -22 */
+ {0x1A1F3804, 0x000FA4A4 }, /* 4, -50, 417, 164, -23 */
+ {0x1A0F3005, 0x000FA0A7 }, /* 5, -52, 416, 167, -24 */
+ {0x19DF3404, 0x000FA4A9 }, /* 4, -51, 413, 169, -23 */
+ {0x19CF3005, 0x000F9CAC }, /* 5, -52, 412, 172, -25 */
+ {0x199F3005, 0x000F9CAF }, /* 5, -52, 409, 175, -25 */
+ {0x197F3005, 0x000F98B2 }, /* 5, -52, 407, 178, -26 */
+ {0x195F3005, 0x000F98B4 }, /* 5, -52, 405, 180, -26 */
+ {0x191F3804, 0x000F9CB6 }, /* 4, -50, 401, 182, -25 */
+ {0x18FF3804, 0x000F98B9 }, /* 4, -50, 399, 185, -26 */
+ {0x18CF3804, 0x000F98BC }, /* 4, -50, 396, 188, -26 */
+ {0x18BF3804, 0x000F94BE }, /* 4, -50, 395, 190, -27 */
+ {0x188F3804, 0x000F94C1 }, /* 4, -50, 392, 193, -27 */
+ {0x186F3804, 0x000F90C4 }, /* 4, -50, 390, 196, -28 */
+ {0x184F3405, 0x000F8CC7 }, /* 5, -51, 388, 199, -29 */
+ {0x181F3804, 0x000F90C9 }, /* 4, -50, 385, 201, -28 */
+ {0x17FF3804, 0x000F8CCC }, /* 4, -50, 383, 204, -29 */
+ {0x17CF3804, 0x000F8CCF }, /* 4, -50, 380, 207, -29 */
+ {0x17BF3405, 0x000F84D2 }, /* 5, -51, 379, 210, -31 */
+ {0x177F3C04, 0x000F88D4 }, /* 4, -49, 375, 212, -30 */
+ {0x174F3C04, 0x000F88D7 }, /* 4, -49, 372, 215, -30 */
+ {0x172F3C04, 0x000F84DA }, /* 4, -49, 370, 218, -31 */
+ {0x170F3C04, 0x000F84DC }, /* 4, -49, 368, 220, -31 */
+ {0x16EF3805, 0x000F7CE0 }, /* 5, -50, 366, 224, -33 */
+ {0x16BF3C04, 0x000F80E2 }, /* 4, -49, 363, 226, -32 */
+ {0x167F4004, 0x000F80E5 }, /* 4, -48, 359, 229, -32 */
+ {0x166F4004, 0x000F7CE7 }, /* 4, -48, 358, 231, -33 */
+ {0x163F4004, 0x000F7CEA }, /* 4, -48, 355, 234, -33 */
+ {0x161F4004, 0x000F78ED }, /* 4, -48, 353, 237, -34 */
+ {0x15EF4004, 0x000F78F0 }, /* 4, -48, 350, 240, -34 */
+ {0x15BF4404, 0x000F74F3 }, /* 4, -47, 347, 243, -35 */
+ {0x159F4404, 0x000F74F5 }, /* 4, -47, 345, 245, -35 */
+ {0x156F4404, 0x000F74F8 }, /* 4, -47, 342, 248, -35 */
+ {0x154F4005, 0x000F6CFC }, /* 5, -48, 340, 252, -37 */
+ {0x150F4804, 0x000F70FE }, /* 4, -46, 336, 254, -36 */
+ {0x14FF4405, 0x000F6901 }, /* 5, -47, 335, 257, -38 */
+ {0x14CF4804, 0x000F6D03 }, /* 4, -46, 332, 259, -37 */
+ {0x149F4804, 0x000F6D06 }, /* 4, -46, 329, 262, -37 */
+ {0x146F4C04, 0x000F6909 }, /* 4, -45, 326, 265, -38 */
+ {0x143F4C04, 0x000F690C }, /* 4, -45, 323, 268, -38 */
+ {0x141F4C04, 0x000F690E }, /* 4, -45, 321, 270, -38 */
+ {0x13EF5004, 0x000F6511 }, /* 4, -44, 318, 273, -39 */
+ {0x13BF5004, 0x000F6514 }, /* 4, -44, 315, 276, -39 */
+ {0x139F5004, 0x000F6117 }, /* 4, -44, 313, 279, -40 */
+ {0x136F5404, 0x000F6119 }, /* 4, -43, 310, 281, -40 */
+ {0x133F5404, 0x000F611C }, /* 4, -43, 307, 284, -40 */
+ {0x131F5404, 0x000F5D1F }, /* 4, -43, 305, 287, -41 */
+ {0x12DF5C04, 0x000F5D21 }, /* 4, -41, 301, 289, -41 */
+ {0x12AF5C04, 0x000F5D24 }, /* 4, -41, 298, 292, -41 */
+};
+
+unsigned long CimarronVerticalGraphicsFilter[] =
+{
+ 0x3F840D05, /* 261, 259, -8 */
+ 0x3F841D01, /* 257, 263, -8 */
+ 0x3F8428FE, /* 254, 266, -8 */
+ 0x3F8438FA, /* 250, 270, -8 */
+ 0x3F8444F7, /* 247, 273, -8 */
+ 0x3F8450F4, /* 244, 276, -8 */
+ 0x3F845CF1, /* 241, 279, -8 */
+ 0x3F8468EE, /* 238, 282, -8 */
+ 0x3F8474EB, /* 235, 285, -8 */
+ 0x3F8480E8, /* 232, 288, -8 */
+ 0x3F7490E5, /* 229, 292, -9 */
+ 0x3F749CE2, /* 226, 295, -9 */
+ 0x3F74ACDE, /* 222, 299, -9 */
+ 0x3F74B8DB, /* 219, 302, -9 */
+ 0x3F74C0D9, /* 217, 304, -9 */
+ 0x3F74CCD6, /* 214, 307, -9 */
+ 0x3F74D8D3, /* 211, 310, -9 */
+ 0x3F74E8CF, /* 207, 314, -9 */
+ 0x3F74F4CC, /* 204, 317, -9 */
+ 0x3F7500C9, /* 201, 320, -9 */
+ 0x3F750CC6, /* 198, 323, -9 */
+ 0x3F7518C3, /* 195, 326, -9 */
+ 0x3F7520C1, /* 193, 328, -9 */
+ 0x3F7530BD, /* 189, 332, -9 */
+ 0x3F753CBA, /* 186, 335, -9 */
+ 0x3F7548B7, /* 183, 338, -9 */
+ 0x3F6558B4, /* 180, 342, -10 */
+ 0x3F6560B2, /* 178, 344, -10 */
+ 0x3F656CAF, /* 175, 347, -10 */
+ 0x3F6578AC, /* 172, 350, -10 */
+ 0x3F6584A9, /* 169, 353, -10 */
+ 0x3F658CA7, /* 167, 355, -10 */
+ 0x3F6598A4, /* 164, 358, -10 */
+ 0x3F65A8A0, /* 160, 362, -10 */
+ 0x3F65B09E, /* 158, 364, -10 */
+ 0x3F65BC9B, /* 155, 367, -10 */
+ 0x3F65C499, /* 153, 369, -10 */
+ 0x3F65D096, /* 150, 372, -10 */
+ 0x3F55E093, /* 147, 376, -11 */
+ 0x3F55E891, /* 145, 378, -11 */
+ 0x3F55F48E, /* 142, 381, -11 */
+ 0x3F56008B, /* 139, 384, -11 */
+ 0x3F560C88, /* 136, 387, -11 */
+ 0x3F561486, /* 134, 389, -11 */
+ 0x3F562083, /* 131, 392, -11 */
+ 0x3F562881, /* 129, 394, -11 */
+ 0x3F56347E, /* 126, 397, -11 */
+ 0x3F56407B, /* 123, 400, -11 */
+ 0x3F564879, /* 121, 402, -11 */
+ 0x3F465876, /* 118, 406, -12 */
+ 0x3F466074, /* 116, 408, -12 */
+ 0x3F466872, /* 114, 410, -12 */
+ 0x3F46746F, /* 111, 413, -12 */
+ 0x3F467C6D, /* 109, 415, -12 */
+ 0x3F46846B, /* 107, 417, -12 */
+ 0x3F468C69, /* 105, 419, -12 */
+ 0x3F469866, /* 102, 422, -12 */
+ 0x3F46A064, /* 100, 424, -12 */
+ 0x3F46AC61, /* 97, 427, -12 */
+ 0x3F46B45F, /* 95, 429, -12 */
+ 0x3F46BC5D, /* 93, 431, -12 */
+ 0x3F46C45B, /* 91, 433, -12 */
+ 0x3F46CC59, /* 89, 435, -12 */
+ 0x3F36DC56, /* 86, 439, -13 */
+ 0x3F36E454, /* 84, 441, -13 */
+ 0x3F36EC52, /* 82, 443, -13 */
+ 0x3F36F450, /* 80, 445, -13 */
+ 0x3F36FC4E, /* 78, 447, -13 */
+ 0x3F37004D, /* 77, 448, -13 */
+ 0x3F370C4A, /* 74, 451, -13 */
+ 0x3F371448, /* 72, 453, -13 */
+ 0x3F371C46, /* 70, 455, -13 */
+ 0x3F372444, /* 68, 457, -13 */
+ 0x3F372C42, /* 66, 459, -13 */
+ 0x3F373440, /* 64, 461, -13 */
+ 0x3F37383F, /* 63, 462, -13 */
+ 0x3F37403D, /* 61, 464, -13 */
+ 0x3F37483B, /* 59, 466, -13 */
+ 0x3F375039, /* 57, 468, -13 */
+ 0x3F375438, /* 56, 469, -13 */
+ 0x3F375C36, /* 54, 471, -13 */
+ 0x3F376434, /* 52, 473, -13 */
+ 0x3F376833, /* 51, 474, -13 */
+ 0x3F377031, /* 49, 476, -13 */
+ 0x3F377430, /* 48, 477, -13 */
+ 0x3F377C2E, /* 46, 479, -13 */
+ 0x3F37842C, /* 44, 481, -13 */
+ 0x3F37882B, /* 43, 482, -13 */
+ 0x3F47882A, /* 42, 482, -12 */
+ 0x3F479028, /* 40, 484, -12 */
+ 0x3F479427, /* 39, 485, -12 */
+ 0x3F479C25, /* 37, 487, -12 */
+ 0x3F47A024, /* 36, 488, -12 */
+ 0x3F47A822, /* 34, 490, -12 */
+ 0x3F47AC21, /* 33, 491, -12 */
+ 0x3F47B020, /* 32, 492, -12 */
+ 0x3F57B01F, /* 31, 492, -11 */
+ 0x3F57B81D, /* 29, 494, -11 */
+ 0x3F57BC1C, /* 28, 495, -11 */
+ 0x3F57C01B, /* 27, 496, -11 */
+ 0x3F57C41A, /* 26, 497, -11 */
+ 0x3F67C818, /* 24, 498, -10 */
+ 0x3F67CC17, /* 23, 499, -10 */
+ 0x3F67D016, /* 22, 500, -10 */
+ 0x3F67D415, /* 21, 501, -10 */
+ 0x3F67D814, /* 20, 502, -10 */
+ 0x3F77D813, /* 19, 502, -9 */
+ 0x3F77DC12, /* 18, 503, -9 */
+ 0x3F77E011, /* 17, 504, -9 */
+ 0x3F87E010, /* 16, 504, -8 */
+ 0x3F87E40F, /* 15, 505, -8 */
+ 0x3F87E80E, /* 14, 506, -8 */
+ 0x3F97E80D, /* 13, 506, -7 */
+ 0x3F97EC0C, /* 12, 507, -7 */
+ 0x3F97F00B, /* 11, 508, -7 */
+ 0x3FA7F00A, /* 10, 508, -6 */
+ 0x3FA7F409, /* 9, 509, -6 */
+ 0x3FB7F408, /* 8, 509, -5 */
+ 0x3FB7F408, /* 8, 509, -5 */
+ 0x3FC7F806, /* 6, 510, -4 */
+ 0x3FC7F806, /* 6, 510, -4 */
+ 0x3FD7F805, /* 5, 510, -3 */
+ 0x3FD7FC04, /* 4, 511, -3 */
+ 0x3FE7FC03, /* 3, 511, -2 */
+ 0x3FE7FC03, /* 3, 511, -2 */
+ 0x3FF7FC02, /* 2, 511, -1 */
+ 0x3FF7FC02, /* 2, 511, -1 */
+ 0x0007FC01, /* 1, 511, 0 */
+ 0x0007FC01, /* 1, 511, 0 */
+ 0x0007FC01, /* 1, 511, 0 */
+ 0x0027FFFF, /* -1, 511, 2 */
+ 0x0027FFFF, /* -1, 511, 2 */
+ 0x0037FFFE, /* -2, 511, 3 */
+ 0x0037FFFE, /* -2, 511, 3 */
+ 0x0047FFFD, /* -3, 511, 4 */
+ 0x0047FBFE, /* -2, 510, 4 */
+ 0x0057FBFD, /* -3, 510, 5 */
+ 0x0067FBFC, /* -4, 510, 6 */
+ 0x0077F7FC, /* -4, 509, 7 */
+ 0x0077F7FC, /* -4, 509, 7 */
+ 0x0087F7FB, /* -5, 509, 8 */
+ 0x0097F3FB, /* -5, 508, 9 */
+ 0x00A7F3FA, /* -6, 508, 10 */
+ 0x00B7EFFA, /* -6, 507, 11 */
+ 0x00C7EBFA, /* -6, 506, 12 */
+ 0x00D7EBF9, /* -7, 506, 13 */
+ 0x00E7E7F9, /* -7, 505, 14 */
+ 0x00F7E3F9, /* -7, 504, 15 */
+ 0x0107E3F8, /* -8, 504, 16 */
+ 0x0117DFF8, /* -8, 503, 17 */
+ 0x0127DBF8, /* -8, 502, 18 */
+ 0x0137DBF7, /* -9, 502, 19 */
+ 0x0147D7F7, /* -9, 501, 20 */
+ 0x0157D3F7, /* -9, 500, 21 */
+ 0x0167CFF7, /* -9, 499, 22 */
+ 0x0177CBF7, /* -9, 498, 23 */
+ 0x0197C7F6, /* -10, 497, 25 */
+ 0x01A7C3F6, /* -10, 496, 26 */
+ 0x01B7BFF6, /* -10, 495, 27 */
+ 0x01C7BBF6, /* -10, 494, 28 */
+ 0x01E7B3F6, /* -10, 492, 30 */
+ 0x01F7B3F5, /* -11, 492, 31 */
+ 0x0207AFF5, /* -11, 491, 32 */
+ 0x0217ABF5, /* -11, 490, 33 */
+ 0x0237A3F5, /* -11, 488, 35 */
+ 0x02479FF5, /* -11, 487, 36 */
+ 0x026797F5, /* -11, 485, 38 */
+ 0x027793F5, /* -11, 484, 39 */
+ 0x02978BF5, /* -11, 482, 41 */
+ 0x02A78BF4, /* -12, 482, 42 */
+ 0x02B787F4, /* -12, 481, 43 */
+ 0x02D77FF4, /* -12, 479, 45 */
+ 0x02F777F4, /* -12, 477, 47 */
+ 0x030773F4, /* -12, 476, 48 */
+ 0x03276BF4, /* -12, 474, 50 */
+ 0x033767F4, /* -12, 473, 51 */
+ 0x03575FF4, /* -12, 471, 53 */
+ 0x037757F4, /* -12, 469, 55 */
+ 0x038753F4, /* -12, 468, 56 */
+ 0x03A74BF4, /* -12, 466, 58 */
+ 0x03C743F4, /* -12, 464, 60 */
+ 0x03E73BF4, /* -12, 462, 62 */
+ 0x040737F3, /* -13, 461, 64 */
+ 0x04272FF3, /* -13, 459, 66 */
+ 0x044727F3, /* -13, 457, 68 */
+ 0x04671FF3, /* -13, 455, 70 */
+ 0x048717F3, /* -13, 453, 72 */
+ 0x04A70FF3, /* -13, 451, 74 */
+ 0x04C703F4, /* -12, 448, 76 */
+ 0x04D6FFF4, /* -12, 447, 77 */
+ 0x04F6F7F4, /* -12, 445, 79 */
+ 0x0516EFF4, /* -12, 443, 81 */
+ 0x0536E7F4, /* -12, 441, 83 */
+ 0x0556DFF4, /* -12, 439, 85 */
+ 0x0586CFF5, /* -11, 435, 88 */
+ 0x05A6C7F5, /* -11, 433, 90 */
+ 0x05C6BFF5, /* -11, 431, 92 */
+ 0x05F6B7F4, /* -12, 429, 95 */
+ 0x0616AFF4, /* -12, 427, 97 */
+ 0x0636A3F5, /* -11, 424, 99 */
+ 0x06569BF5, /* -11, 422, 101 */
+ 0x06868FF5, /* -11, 419, 104 */
+ 0x06A687F5, /* -11, 417, 106 */
+ 0x06C67FF5, /* -11, 415, 108 */
+ 0x06E677F5, /* -11, 413, 110 */
+ 0x07166BF5, /* -11, 410, 113 */
+ 0x073663F5, /* -11, 408, 115 */
+ 0x07665BF4, /* -12, 406, 118 */
+ 0x07964BF5, /* -11, 402, 121 */
+ 0x07B643F5, /* -11, 400, 123 */
+ 0x07D637F6, /* -10, 397, 125 */
+ 0x08062BF6, /* -10, 394, 128 */
+ 0x082623F6, /* -10, 392, 130 */
+ 0x085617F6, /* -10, 389, 133 */
+ 0x08760FF6, /* -10, 387, 135 */
+ 0x08B603F5, /* -11, 384, 139 */
+ 0x08D5F7F6, /* -10, 381, 141 */
+ 0x0905EBF6, /* -10, 378, 144 */
+ 0x0925E3F6, /* -10, 376, 146 */
+ 0x0955D3F7, /* -9, 372, 149 */
+ 0x0985C7F7, /* -9, 369, 152 */
+ 0x09A5BFF7, /* -9, 367, 154 */
+ 0x09D5B3F7, /* -9, 364, 157 */
+ 0x0A05ABF6, /* -10, 362, 160 */
+ 0x0A359BF7, /* -9, 358, 163 */
+ 0x0A658FF7, /* -9, 355, 166 */
+ 0x0A9587F6, /* -10, 353, 169 */
+ 0x0AB57BF7, /* -9, 350, 171 */
+ 0x0AE56FF7, /* -9, 347, 174 */
+ 0x0B1563F7, /* -9, 344, 177 */
+ 0x0B455BF6, /* -10, 342, 180 */
+ 0x0B754BF7, /* -9, 338, 183 */
+ 0x0BA53FF7, /* -9, 335, 186 */
+ 0x0BD533F7, /* -9, 332, 189 */
+ 0x0C0523F8, /* -8, 328, 192 */
+ 0x0C251BF8, /* -8, 326, 194 */
+ 0x0C550FF8, /* -8, 323, 197 */
+ 0x0C9503F7, /* -9, 320, 201 */
+ 0x0CC4F7F7, /* -9, 317, 204 */
+ 0x0CF4EBF7, /* -9, 314, 207 */
+ 0x0D24DBF8, /* -8, 310, 210 */
+ 0x0D54CFF8, /* -8, 307, 213 */
+ 0x0D84C3F8, /* -8, 304, 216 */
+ 0x0DB4BBF7, /* -9, 302, 219 */
+ 0x0DE4AFF7, /* -9, 299, 222 */
+ 0x0E149FF8, /* -8, 295, 225 */
+ 0x0E4493F8, /* -8, 292, 228 */
+ 0x0E7483F9, /* -7, 288, 231 */
+ 0x0EA477F9, /* -7, 285, 234 */
+ 0x0ED46BF9, /* -7, 282, 237 */
+ 0x0F045FF9, /* -7, 279, 240 */
+ 0x0F4453F8, /* -8, 276, 244 */
+ 0x0F7447F8, /* -8, 273, 247 */
+ 0x0FA43BF8, /* -8, 270, 250 */
+ 0x0FD42BF9, /* -7, 266, 253 */
+ 0x10041FF9, /* -7, 263, 256 */
+};
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_msr.c xf86-video-nsc-2.8.1/src/cim/cim_msr.c
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_msr.c 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_msr.c 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,379 @@
+ /*
+ *
+ * Copyright (C) 2005 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *
+ *
+ *
+ *
+ *
+ * Cimarron MSR access routines. These routines allow the user to query the
+ * state of the GeodeLink Bus and read and write model-specfic registers.
+ *
+ *
+ */
+
+/*--------------------------------------------------------------*/
+/* MSR GLOBALS */
+/* These variables hold a local copy of the GeodeLink mapping */
+/* as well as a lookup table for easy device addressing. */
+/*--------------------------------------------------------------*/
+
+GEODELINK_NODE gliu_nodes[24];
+GEODELINK_NODE msr_dev_lookup[MSR_DEVICE_EMPTY];
+
+#define GET_DEVICE_ID(macrohigh, macrolow) ((macrolow >> 12) & 0xFF)
+
+/*---------------------------------------------------------------------------
+ * msr_init_table
+ *
+ * This routine intializes the internal MSR table in Cimarron. This table is
+ * used for any MSR device accesses.
+ *---------------------------------------------------------------------------*/
+
+int msr_init_table (void)
+{
+ Q_WORD msr_value;
+ unsigned int i, j;
+ int return_value = CIM_STATUS_OK;
+
+ /* CHECK FOR VALID GEODELINK CONFIGURATION */
+ /* The CPU and the three GLIUs are assumed to be at known static addresses, so */
+ /* we will check the device IDs at these addresses as proof of a valid */
+ /* GeodeLink configuration */
+
+ MSR_READ (MSR_GEODELINK_CAP, MSR_ADDRESS_VAIL, &msr_value);
+ if (GET_DEVICE_ID (msr_value.high, msr_value.low) != MSR_CLASS_CODE_VAIL)
+ return_value = CIM_STATUS_ERROR;
+
+ MSR_READ (MSR_GEODELINK_CAP, MSR_ADDRESS_GLIU0, &msr_value);
+ if (GET_DEVICE_ID (msr_value.high, msr_value.low) != MSR_CLASS_CODE_GLIU)
+ return_value = CIM_STATUS_ERROR;
+
+ MSR_READ (MSR_GEODELINK_CAP, MSR_ADDRESS_GLIU1, &msr_value);
+ if (GET_DEVICE_ID (msr_value.high, msr_value.low) != MSR_CLASS_CODE_GLIU)
+ return_value = CIM_STATUS_ERROR;
+
+ MSR_READ (MSR_GEODELINK_CAP, MSR_ADDRESS_GLIU2, &msr_value);
+ if (GET_DEVICE_ID (msr_value.high, msr_value.low) != MSR_CLASS_CODE_GLIU)
+ return_value = CIM_STATUS_ERROR;
+
+ if (return_value == CIM_STATUS_OK)
+ {
+ /* BUILD LOCAL COPY OF THE GEODELINK BUS */
+
+ msr_create_geodelink_table (gliu_nodes);
+
+ /* CLEAR TABLE STATUS */
+
+ for (i = 0; i < MSR_DEVICE_EMPTY; i++)
+ msr_dev_lookup[i].device_id = MSR_DEVICE_NOTFOUND;
+
+ /* CREATE EASY LOOKUP TABLE FOR FUTURE HARDWARE ACCESS */
+ /* Note that MSR_DEVICE_EMPTY is the index after the last */
+ /* available device. Also note that we fill in known */
+ /* devices before filling in the rest of the table. */
+
+ msr_dev_lookup[MSR_DEVICE_GEODELX_GLIU0].address_from_cpu = MSR_ADDRESS_GLIU0;
+ msr_dev_lookup[MSR_DEVICE_GEODELX_GLIU0].device_id = MSR_DEVICE_PRESENT;
+ msr_dev_lookup[MSR_DEVICE_GEODELX_GLIU1].address_from_cpu = MSR_ADDRESS_GLIU1;
+ msr_dev_lookup[MSR_DEVICE_GEODELX_GLIU1].device_id = MSR_DEVICE_PRESENT;
+ msr_dev_lookup[MSR_DEVICE_5535_GLIU].address_from_cpu = MSR_ADDRESS_GLIU2;
+ msr_dev_lookup[MSR_DEVICE_5535_GLIU].device_id = MSR_DEVICE_PRESENT;
+ msr_dev_lookup[MSR_DEVICE_GEODELX_VAIL].address_from_cpu = MSR_ADDRESS_VAIL;
+ msr_dev_lookup[MSR_DEVICE_GEODELX_VAIL].device_id = MSR_DEVICE_PRESENT;
+
+ for (i = 0; i < MSR_DEVICE_EMPTY; i++)
+ {
+ if (msr_dev_lookup[i].device_id == MSR_DEVICE_NOTFOUND)
+ {
+ for (j = 0; j < 24; j++)
+ {
+ if (gliu_nodes[j].device_id == i)
+ break;
+ }
+
+ if (j == 24)
+ msr_dev_lookup[i].device_id = MSR_DEVICE_NOTFOUND;
+ else
+ {
+ msr_dev_lookup[i].device_id = MSR_DEVICE_PRESENT;
+ msr_dev_lookup[i].address_from_cpu = gliu_nodes[j].address_from_cpu;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* ERROR OUT THE GEODELINK TABLES */
+
+ for (i = 0; i < 24; i++)
+ {
+ gliu_nodes[i].address_from_cpu = 0xFFFFFFFF;
+ gliu_nodes[i].device_id = MSR_DEVICE_EMPTY;
+ }
+
+ for (i = 0; i < MSR_DEVICE_EMPTY; i++)
+ {
+ msr_dev_lookup[i].address_from_cpu = 0xFFFFFFFF;
+ msr_dev_lookup[i].device_id = MSR_DEVICE_NOTFOUND;
+ }
+ }
+ return return_value;
+}
+
+/*---------------------------------------------------------------------------
+ * msr_create_geodelink_table
+ *
+ * This routine dumps the contents of the GeodeLink bus into an array of
+ * 24 GEODELINK_NODE structures. Indexes 0-7 represent ports 0-7 of GLIU0,
+ * indexes 8-15 represent ports 0-7 of GLIU1 and indexes 16-23 represent
+ * ports 0-7 of GLIU2 (5535).
+ *---------------------------------------------------------------------------*/
+
+int msr_create_geodelink_table (GEODELINK_NODE *gliu_nodes)
+{
+ unsigned long mbiu_port_count, reflective;
+ unsigned long port, index;
+ unsigned long gliu_count = 0;
+ int glcp_count = 0;
+ int usb_count = 0;
+ int mpci_count = 0;
+ Q_WORD msr_value;
+
+ /* ALL THREE GLIUS ARE IN ONE ARRAY */
+ /* Entries 0-7 contain the port information for GLIU0, entries */
+ /* 8-15 contain GLIU1 and 15-23 contain GLIU2. We perform the */
+ /* enumeration in two passes. The first simply fills in the */
+ /* addresses and class codes at each node. The second pass */
+ /* translates the class codes into indexes into Cimarron's device */
+ /* lookup table. */
+
+ /* COUNT GLIU0 PORTS */
+
+ MSR_READ (MSR_GLIU_CAP, MSR_ADDRESS_GLIU0, &msr_value);
+ mbiu_port_count = (msr_value.high >> NUM_PORTS_SHIFT) & 7;
+
+ /* FIND REFLECTIVE PORT */
+ /* Query the GLIU for the port through which we are communicating. */
+ /* We will avoid accesses to this port to avoid a self-reference. */
+
+ MSR_READ (MSR_GLIU_WHOAMI, MSR_ADDRESS_GLIU0, &msr_value);
+ reflective = msr_value.low & WHOAMI_MASK;
+
+ /* SPECIAL CASE FOR PORT 0 */
+ /* GLIU0 port 0 is a special case, as it points back to GLIU0. GLIU0 */
+ /* responds at address 0x10000xxx, which does not equal 0 << 29. */
+
+ gliu_nodes[0].address_from_cpu = MSR_ADDRESS_GLIU0;
+ gliu_nodes[0].device_id = MSR_CLASS_CODE_GLIU;
+
+ /* ENUMERATE ALL PORTS */
+
+ for (port = 1; port < 8; port++)
+ {
+ /* FILL IN ADDRESS */
+
+ gliu_nodes[port].address_from_cpu = port << 29;
+
+ if (port == reflective)
+ gliu_nodes[port].device_id = MSR_CLASS_CODE_REFLECTIVE;
+ else if (port > mbiu_port_count)
+ gliu_nodes[port].device_id = MSR_CLASS_CODE_UNPOPULATED;
+ else
+ {
+ MSR_READ (MSR_GEODELINK_CAP, gliu_nodes[port].address_from_cpu, &msr_value);
+ gliu_nodes[port].device_id = GET_DEVICE_ID (msr_value.high, msr_value.low);
+ }
+ }
+
+ /* COUNT GLIU1 PORTS */
+
+ MSR_READ (MSR_GLIU_CAP, MSR_ADDRESS_GLIU1, &msr_value);
+ mbiu_port_count = (msr_value.high >> NUM_PORTS_SHIFT) & 7;
+
+ /* FIND REFLECTIVE PORT */
+
+ MSR_READ (MSR_GLIU_WHOAMI, MSR_ADDRESS_GLIU1, &msr_value);
+ reflective = msr_value.low & WHOAMI_MASK;
+
+ /* ENUMERATE ALL PORTS */
+
+ for (port = 0; port < 8; port++)
+ {
+ index = port + 8;
+
+ /* FILL IN ADDRESS */
+
+ gliu_nodes[index].address_from_cpu = (0x02l << 29) + (port << 26);
+
+ if (port == reflective)
+ gliu_nodes[index].device_id = MSR_CLASS_CODE_REFLECTIVE;
+ else if (port > mbiu_port_count)
+ gliu_nodes[index].device_id = MSR_CLASS_CODE_UNPOPULATED;
+ else
+ {
+ MSR_READ (MSR_GEODELINK_CAP, gliu_nodes[index].address_from_cpu, &msr_value);
+ gliu_nodes[index].device_id = GET_DEVICE_ID (msr_value.high, msr_value.low);
+ }
+ }
+
+ /* COUNT GLIU2 PORTS */
+
+ MSR_READ (MSR_GLIU_CAP, MSR_ADDRESS_GLIU2, &msr_value);
+ mbiu_port_count = (msr_value.high >> NUM_PORTS_SHIFT) & 7;
+
+ /* FIND REFLECTIVE PORT */
+
+ MSR_READ (MSR_GLIU_WHOAMI, MSR_ADDRESS_GLIU2, &msr_value);
+ reflective = msr_value.low & WHOAMI_MASK;
+
+ /* FILL IN PORT 0 AND 1 */
+ /* Port 0 on 5535 is MBIU2. Port 1 is MPCI, but it is referenced at */
+ /* a special address. */
+
+ gliu_nodes[16].address_from_cpu = MSR_ADDRESS_GLIU2;
+ gliu_nodes[16].device_id = MSR_CLASS_CODE_GLIU;
+
+ gliu_nodes[17].address_from_cpu = MSR_ADDRESS_5535MPCI;
+ gliu_nodes[17].device_id = MSR_CLASS_CODE_MPCI;
+
+ /* ENUMERATE ALL PORTS */
+
+ for (port = 2; port < 8; port++)
+ {
+ index = port + 16;
+
+ /* FILL IN ADDRESS */
+
+ gliu_nodes[index].address_from_cpu =
+ (0x02l << 29) + (0x04l << 26) + (0x02l << 23) + (port << 20);
+
+ if (port == reflective)
+ gliu_nodes[index].device_id = MSR_CLASS_CODE_REFLECTIVE;
+ else if (port > mbiu_port_count)
+ gliu_nodes[index].device_id = MSR_CLASS_CODE_UNPOPULATED;
+ else
+ {
+ MSR_READ (MSR_GEODELINK_CAP, gliu_nodes[index].address_from_cpu, &msr_value);
+ gliu_nodes[index].device_id = GET_DEVICE_ID (msr_value.high, msr_value.low);
+ }
+ }
+
+ /* SECOND PASS - TRANSLATION */
+ /* Now that the class codes for each device are stored in the */
+ /* array, we walk through the array and translate the class */
+ /* codes to table indexes. For class codes that have multiple */
+ /* instances, the table indexes are sequential. */
+
+ for (port = 0; port < 24; port++)
+ {
+ /* SPECIAL CASE FOR GLIU UNITS */
+ /* A GLIU can be both on another port and on its own port. These */
+ /* end up as the same address, but are shown as duplicate nodes in */
+ /* the GeodeLink table. */
+
+ if ((port & 7) == 0)
+ gliu_count = port >> 3;
+
+ switch (gliu_nodes[port].device_id)
+ {
+ /* UNPOPULATED OR REFLECTIVE NODES */
+
+ case MSR_CLASS_CODE_UNPOPULATED: index = MSR_DEVICE_EMPTY; break;
+ case MSR_CLASS_CODE_REFLECTIVE: index = MSR_DEVICE_REFLECTIVE; break;
+
+ /* KNOWN CLASS CODES */
+
+ case MSR_CLASS_CODE_GLIU: index = MSR_DEVICE_GEODELX_GLIU0 + gliu_count++; break;
+ case MSR_CLASS_CODE_GLCP: index = MSR_DEVICE_GEODELX_GLCP + glcp_count++; break;
+ case MSR_CLASS_CODE_MPCI: index = MSR_DEVICE_GEODELX_MPCI + mpci_count++; break;
+ case MSR_CLASS_CODE_USB: index = MSR_DEVICE_5535_USB2 + usb_count++; break;
+ case MSR_CLASS_CODE_USB2: index = MSR_DEVICE_5536_USB_2_0; break;
+ case MSR_CLASS_CODE_ATAC: index = MSR_DEVICE_5535_ATAC; break;
+ case MSR_CLASS_CODE_MDD: index = MSR_DEVICE_5535_MDD; break;
+ case MSR_CLASS_CODE_ACC: index = MSR_DEVICE_5535_ACC; break;
+ case MSR_CLASS_CODE_MC: index = MSR_DEVICE_GEODELX_MC; break;
+ case MSR_CLASS_CODE_GP: index = MSR_DEVICE_GEODELX_GP; break;
+ case MSR_CLASS_CODE_VG: index = MSR_DEVICE_GEODELX_VG; break;
+ case MSR_CLASS_CODE_DF: index = MSR_DEVICE_GEODELX_DF; break;
+ case MSR_CLASS_CODE_FG: index = MSR_DEVICE_GEODELX_FG; break;
+ case MSR_CLASS_CODE_VIP: index = MSR_DEVICE_GEODELX_VIP; break;
+ case MSR_CLASS_CODE_AES: index = MSR_DEVICE_GEODELX_AES; break;
+ case MSR_CLASS_CODE_VAIL: index = MSR_DEVICE_GEODELX_VAIL; break;
+ default: index = MSR_DEVICE_EMPTY; break;
+ }
+
+ gliu_nodes[port].device_id = index;
+ }
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * msr_create_device_list
+ *
+ * This routine dumps a list of all known GeodeLX/5535 devices as well as their
+ * respective status and address.
+ *---------------------------------------------------------------------------*/
+
+int msr_create_device_list (GEODELINK_NODE *gliu_nodes, int max_devices)
+{
+ int i, count;
+
+ if (max_devices < MSR_DEVICE_EMPTY) count = max_devices;
+ else count = MSR_DEVICE_EMPTY;
+
+ for (i = 0; i < count; i++)
+ {
+ gliu_nodes[i].address_from_cpu = msr_dev_lookup[i].address_from_cpu;
+ gliu_nodes[i].device_id = msr_dev_lookup[i].device_id;
+ }
+
+ return CIM_STATUS_OK;
+}
+
+/*--------------------------------------------------------------------
+ * msr_read64
+ *
+ * Performs a 64-bit read from 'msr_register' in device 'device'. 'device' is
+ * an index into Cimarron's table of known GeodeLink devices.
+ *-------------------------------------------------------------------*/
+
+int msr_read64 (unsigned long device, unsigned long msr_register,
+ Q_WORD *msr_value)
+{
+ if (device < MSR_DEVICE_EMPTY)
+ {
+ if (msr_dev_lookup[device].device_id == MSR_DEVICE_PRESENT)
+ {
+ MSR_READ (msr_register, msr_dev_lookup[device].address_from_cpu, msr_value);
+ return CIM_STATUS_OK;
+ }
+ }
+
+ msr_value->low = msr_value->high = 0;
+ return CIM_STATUS_DEVNOTFOUND;
+}
+
+/*--------------------------------------------------------------------
+ * msr_write64
+ *
+ * Performs a 64-bit write to 'msr_register' in device 'device'. 'device' is
+ * an index into Cimarron's table of known GeodeLink devices.
+ *-------------------------------------------------------------------*/
+
+int msr_write64 (unsigned long device, unsigned long msr_register,
+ Q_WORD *msr_value)
+{
+ if (device < MSR_DEVICE_EMPTY)
+ {
+ if (msr_dev_lookup[device].device_id == MSR_DEVICE_PRESENT)
+ {
+ MSR_WRITE (msr_register, msr_dev_lookup[device].address_from_cpu, msr_value);
+ return CIM_STATUS_OK;
+ }
+ }
+ return CIM_STATUS_DEVNOTFOUND;
+}
+
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_parm.h xf86-video-nsc-2.8.1/src/cim/cim_parm.h
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_parm.h 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_parm.h 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,1268 @@
+ /*
+ *
+ * Copyright (C) 2005 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *
+ *
+ *
+ *
+ *
+ * Cimarron user definitions.
+ *
+ *
+ */
+
+#ifndef _cim_parm_h
+#define _cim_parm_h
+
+/*===================================================*/
+/* CIMARRON RETURN VALUE DEFINITIONS */
+/*===================================================*/
+
+#define CIM_STATUS_OK 0x00000000
+#define CIM_STATUS_ERROR 0x00000001
+#define CIM_STATUS_INVALIDPARAMS 0x00000002
+#define CIM_STATUS_DEVNOTFOUND 0x00000004
+#define CIM_STATUS_INVALIDSCALE 0x00000008
+#define CIM_STATUS_INEXACTMATCH 0x00000010
+#define CIM_STATUS_NOLOCK 0x00000020
+#define CIM_STATUS_CPUNOTFOUND 0x00000040
+#define CIM_STATUS_DISPLAYUNAVAILABLE 0x00000080
+#define CIM_STATUS_NOTFOUND 0x00000100
+
+/*===================================================*/
+/* CIMARRON CPU DEFINITIONS */
+/*===================================================*/
+
+#define CIM_CPU_GEODEGX 0x00000001
+#define CIM_CPU_GEODELX 0x00000002
+
+#define CIM_SB_5535 0x00000001
+#define CIM_SB_5536 0x00000002
+
+/*===================================================*/
+/* MSR PARAMETERS */
+/*===================================================*/
+
+/*-------------------------------------------------------------*/
+/* GEODELINK DEVICE IDS */
+/* These values uniquely identify all known GeodeLink devices */
+/* in GeodeLX and its companion, 5535/6. For multiple devices */
+/* of the same class (GLIU, USB, etc.) the table order is used */
+/* to to identify the expected device order, in terms of on */
+/* which GLIU the device is found, and on which port. */
+/*-------------------------------------------------------------*/
+
+#define MSR_DEVICE_GEODELX_GLIU0 0x00
+#define MSR_DEVICE_GEODELX_GLIU1 0x01
+#define MSR_DEVICE_5535_GLIU 0x02
+#define MSR_DEVICE_GEODELX_GLCP 0x03
+#define MSR_DEVICE_5535_GLCP 0x04
+#define MSR_DEVICE_GEODELX_MPCI 0x05
+#define MSR_DEVICE_5535_MPCI 0x06
+#define MSR_DEVICE_GEODELX_MC 0x07
+#define MSR_DEVICE_GEODELX_GP 0x08
+#define MSR_DEVICE_GEODELX_VG 0x09
+#define MSR_DEVICE_GEODELX_VIP 0x0A
+#define MSR_DEVICE_GEODELX_AES 0x0B
+#define MSR_DEVICE_GEODELX_DF 0x0C
+#define MSR_DEVICE_GEODELX_FG 0x0D
+#define MSR_DEVICE_GEODELX_VAIL 0x0E
+#define MSR_DEVICE_5536_USB_2_0 0x0F
+#define MSR_DEVICE_5535_USB2 0x10
+#define MSR_DEVICE_5535_USB1 0x11
+#define MSR_DEVICE_5535_ATAC 0x12
+#define MSR_DEVICE_5535_MDD 0x13
+#define MSR_DEVICE_5535_ACC 0x14
+#define MSR_DEVICE_EMPTY 0x15
+#define MSR_DEVICE_REFLECTIVE 0x16
+#define MSR_DEVICE_PRESENT 0x17
+#define MSR_DEVICE_NOTFOUND 0x18
+
+/*---------------------------------------------*/
+/* GEODELINK TABLE ENTRY */
+/* The following structure represents one port */
+/* on a GeodeLink Interface Unit (GLIU) */
+/*---------------------------------------------*/
+
+typedef struct tagGeodeLinkNode
+{
+ unsigned long address_from_cpu;
+ unsigned long device_id;
+
+} GEODELINK_NODE;
+
+/*---------------------------------------------*/
+/* QWORD DATA STRUCTURE */
+/* 64-bit data structure for MSR acess. */
+/*---------------------------------------------*/
+
+typedef struct tagQ_WORD
+{
+ unsigned long high;
+ unsigned long low;
+
+} Q_WORD;
+
+/*===================================================*/
+/* INITIALIZATION USER PARAMETERS */
+/*===================================================*/
+
+typedef struct tagInitBaseAddresses
+{
+ unsigned long framebuffer_base;
+ unsigned long gp_register_base;
+ unsigned long vg_register_base;
+ unsigned long df_register_base;
+ unsigned long vip_register_base;
+ unsigned long framebuffer_size;
+
+} INIT_BASE_ADDRESSES;
+
+/*===================================================*/
+/* GP USER PARAMETER DEFINITIONS */
+/*===================================================*/
+
+/*---------------------------*/
+/* GP_DECLARE_BLT PARAMETERS */
+/*---------------------------*/
+
+#define CIMGP_BLTFLAGS_PRES_LUT 0x0001
+#define CIMGP_BLTFLAGS_PRES_COLOR_PAT 0x0002
+#define CIMGP_ENABLE_PREFETCH 0x0004
+#define CIMGP_BLTFLAGS_HAZARD 0x0008
+#define CIMGP_BLTFLAGS_INVERTMONO 0x0010
+#define CIMGP_BLTFLAGS_LIMITBUFFER 0x0020
+
+/*-----------------------------------*/
+/* GP_SET_ALPHA_OPERATION PARAMETERS */
+/*-----------------------------------*/
+
+#define CIMGP_APPLY_BLEND_TO_RGB 1
+#define CIMGP_APPLY_BLEND_TO_ALPHA 2
+#define CIMGP_APPLY_BLEND_TO_ALL 3
+
+#define CIMGP_ALPHA_TIMES_A 0
+#define CIMGP_BETA_TIMES_B 1
+#define CIMGP_A_PLUS_BETA_B 2
+#define CIMGP_ALPHA_A_PLUS_BETA_B 3
+
+#define CIMGP_CHANNEL_A_ALPHA 0
+#define CIMGP_CHANNEL_B_ALPHA 1
+#define CIMGP_CONSTANT_ALPHA 2
+#define CIMGP_ALPHA_EQUALS_ONE 3
+#define CIMGP_ALPHA_FROM_RGB_A 4
+#define CIMGP_ALPHA_FROM_RGB_B 5
+#define CIMGP_CONVERTED_ALPHA 6
+
+#define CIMGP_CHANNEL_A_SOURCE 0
+#define CIMGP_CHANNEL_A_DEST 1
+
+/*---------------------------------*/
+/* GP_SET_SOURCE_FORMAT PARAMETERS */
+/*---------------------------------*/
+
+#define CIMGP_SOURCE_FMT_3_3_2 0x00
+#define CIMGP_SOURCE_FMT_8BPP_INDEXED 0x01
+#define CIMGP_SOURCE_FMT_4_4_4_4 0x04
+#define CIMGP_SOURCE_FMT_12BPP_BGR 0x14
+#define CIMGP_SOURCE_FMT_1_5_5_5 0x05
+#define CIMGP_SOURCE_FMT_15BPP_BGR 0x15
+#define CIMGP_SOURCE_FMT_0_5_6_5 0x06
+#define CIMGP_SOURCE_FMT_16BPP_BGR 0x16
+#define CIMGP_SOURCE_FMT_YUYV 0x07
+#define CIMGP_SOURCE_FMT_UYVY 0x17
+#define CIMGP_SOURCE_FMT_8_8_8_8 0x08
+#define CIMGP_SOURCE_FMT_32BPP_BGR 0x18
+#define CIMGP_SOURCE_FMT_24BPP 0x0B
+#define CIMGP_SOURCE_FMT_4BPP_INDEXED 0x0D
+
+/*------------------------------------*/
+/* GP_SCREEN_TO_SCREEN_BLT PARAMETERS */
+/*------------------------------------*/
+
+#define CIMGP_NEGXDIR 1
+#define CIMGP_NEGYDIR 2
+
+/*------------------------------------*/
+/* GP_BRESENHAM_LINE PARAMETERS */
+/*------------------------------------*/
+
+#define CIMGP_YMAJOR 1
+#define CIMGP_POSMAJOR 2
+#define CIMGP_POSMINOR 4
+
+/*----------------------------------------------*/
+/* USER STRUCTURE FOR SAVING/RESTORING GP STATE */
+/*----------------------------------------------*/
+
+typedef struct tagGPSaveRestore
+{
+ unsigned long base_offset;
+ unsigned long cmd_top;
+ unsigned long cmd_bottom;
+ unsigned long cmd_base;
+ unsigned long cmd_read;
+
+} GP_SAVE_RESTORE;
+
+/*===================================================*/
+/* VG USER PARAMETER DEFINITIONS */
+/*===================================================*/
+
+/*-------------------------------------------*/
+/* SUPPORTED TV ENCODERS */
+/*-------------------------------------------*/
+
+#define VG_ENCODER_ADV7171 0x0001
+#define VG_ENCODER_SAA7127 0x0002
+#define VG_ENCODER_FS454 0x0003
+#define VG_ENCODER_ADV7300 0x0004
+
+/*-------------------------------------------*/
+/* SUPPORTED TV RESOLUTIONS */
+/*-------------------------------------------*/
+
+#define VG_TVMODE_NTSC 0x00000000
+#define VG_TVMODE_PAL 0x00000001
+#define VG_TVMODE_480P 0x00000002
+#define VG_TVMODE_720P 0x00000003
+#define VG_TVMODE_1080I 0x00000004
+#define VG_TVMODE_6X4_NTSC 0x00000005
+#define VG_TVMODE_8X6_NTSC 0x00000006
+#define VG_TVMODE_10X7_NTSC 0x00000007
+#define VG_TVMODE_6X4_PAL 0x00000008
+#define VG_TVMODE_8X6_PAL 0x00000009
+#define VG_TVMODE_10X7_PAL 0x0000000A
+
+/*-------------------------------------------*/
+/* USER STRUCTURE FOR SETTING A DISPLAY MODE */
+/*-------------------------------------------*/
+
+#define VG_SUPPORTFLAG_8BPP 0x00000001
+#define VG_SUPPORTFLAG_12BPP 0x00000002
+#define VG_SUPPORTFLAG_15BPP 0x00000004
+#define VG_SUPPORTFLAG_16BPP 0x00000008
+#define VG_SUPPORTFLAG_24BPP 0x00000010
+#define VG_SUPPORTFLAG_32BPP 0x00000020
+#define VG_SUPPORTFLAG_56HZ 0x00000040
+#define VG_SUPPORTFLAG_60HZ 0x00000080
+#define VG_SUPPORTFLAG_70HZ 0x00000100
+#define VG_SUPPORTFLAG_72HZ 0x00000200
+#define VG_SUPPORTFLAG_75HZ 0x00000400
+#define VG_SUPPORTFLAG_85HZ 0x00000800
+#define VG_SUPPORTFLAG_90HZ 0x00001000
+#define VG_SUPPORTFLAG_100HZ 0x00002000
+#define VG_SUPPORTFLAG_HZMASK 0x00003FC0
+#define VG_SUPPORTFLAG_ADV7171 0x00004000
+#define VG_SUPPORTFLAG_SAA7127 0x00008000
+#define VG_SUPPORTFLAG_FS454 0x00010000
+#define VG_SUPPORTFLAG_ADV7300 0x00020000
+#define VG_SUPPORTFLAG_ENCODERMASK 0x0003C000
+#define VG_SUPPORTFLAG_PANEL 0x00040000
+#define VG_SUPPORTFLAG_TVOUT 0x00080000
+#define VG_SUPPORTFLAG_NTSC 0x00000000
+#define VG_SUPPORTFLAG_PAL 0x00100000
+#define VG_SUPPORTFLAG_480P 0x00200000
+#define VG_SUPPORTFLAG_720P 0x00300000
+#define VG_SUPPORTFLAG_1080I 0x00400000
+#define VG_SUPPORTFLAG_6X4_NTSC 0x00500000
+#define VG_SUPPORTFLAG_8X6_NTSC 0x00600000
+#define VG_SUPPORTFLAG_10X7_NTSC 0x00700000
+#define VG_SUPPORTFLAG_6X4_PAL 0x00800000
+#define VG_SUPPORTFLAG_8X6_PAL 0x00900000
+#define VG_SUPPORTFLAG_10X7_PAL 0x00A00000
+#define VG_SUPPORTFLAG_TVMODEMASK 0x00F00000
+
+#define VG_MODEFLAG_NEG_HSYNC 0x00000001
+#define VG_MODEFLAG_NEG_VSYNC 0x00000002
+#define VG_MODEFLAG_INTERLACED 0x00000004
+#define VG_MODEFLAG_PANELOUT 0x00000008
+#define VG_MODEFLAG_CENTERED 0x00000010
+#define VG_MODEFLAG_LINEARPITCH 0x00000020
+#define VG_MODEFLAG_TVOUT 0x00000040
+#define VG_MODEFLAG_HALFCLOCK 0x00000080
+#define VG_MODEFLAG_QVGA 0x00000100
+#define VG_MODEFLAG_EXCLUDEPLL 0x00000200
+#define VG_MODEFLAG_NOPANELTIMINGS 0x00000400
+#define VG_MODEFLAG_XVGA_TFT 0x00000800
+#define VG_MODEFLAG_CUSTOM_PANEL 0x00001000
+#define VG_MODEFLAG_CRT_AND_FP 0x00002000
+#define VG_MODEFLAG_LOW_BAND 0x00000000
+#define VG_MODEFLAG_AVG_BAND 0x00004000
+#define VG_MODEFLAG_HIGH_BAND 0x00008000
+#define VG_MODEFLAG_LEGACY_BAND 0x0000C000
+#define VG_MODEFLAG_BANDWIDTHMASK 0x0000C000
+#define VG_MODEFLAG_OVERRIDE_BAND 0x00010000
+#define VG_MODEFLAG_INT_ADDRESS 0x00000000
+#define VG_MODEFLAG_INT_LINEDOUBLE 0x00020000
+#define VG_MODEFLAG_INT_FLICKER 0x00040000
+#define VG_MODEFLAG_INT_MASK 0x00060000
+#define VG_MODEFLAG_INT_OVERRIDE 0x00080000
+#define VG_MODEFLAG_INVERT_SHFCLK 0x00100000
+#define VG_MODEFLAG_MANUAL_FREQUENCY 0x00200000
+#define VG_MODEFLAG_PLL_BYPASS 0x00400000
+#define VG_MODEFLAG_VIP_TO_DOT_CLOCK 0x00800000
+
+#define VG_MODEFLAG_VALIDUSERFLAGS (VG_MODEFLAG_CRT_AND_FP | \
+ VG_MODEFLAG_XVGA_TFT | \
+ VG_MODEFLAG_NOPANELTIMINGS | \
+ VG_MODEFLAG_EXCLUDEPLL | \
+ VG_MODEFLAG_LINEARPITCH)
+
+typedef struct tagVGDisplayMode
+{
+ /* DISPLAY MODE FLAGS */
+ /* Includes BPP, refresh rate information, interlacing, etc. */
+
+ unsigned long internal_flags;
+ unsigned long flags;
+
+ /* SOURCE RESOLUTION */
+ /* The following values reflect the resolution of the data in the frame */
+ /* buffer. These values are used to enable scaling and filtering. */
+
+ unsigned long src_width;
+ unsigned long src_height;
+
+ /* PANEL SETTINGS */
+ /* These allow a user to set a panel mode through the vg_set_custom_mode */
+ /* routine. These values are only relevant if the VG_MODEFLAG_PANEL is */
+ /* also set. */
+
+ unsigned long mode_width;
+ unsigned long mode_height;
+ unsigned long panel_width;
+ unsigned long panel_height;
+ unsigned long panel_tim1;
+ unsigned long panel_tim2;
+ unsigned long panel_dither_ctl;
+ unsigned long panel_pad_sel_low;
+ unsigned long panel_pad_sel_high;
+
+ /* OUTPUT TIMINGS */
+ /* If the active width and height do not match the source */
+ /* dimensions the graphics data will be scaled. */
+
+ unsigned long hactive;
+ unsigned long hblankstart;
+ unsigned long hsyncstart;
+ unsigned long hsyncend;
+ unsigned long hblankend;
+ unsigned long htotal;
+
+ unsigned long vactive;
+ unsigned long vblankstart;
+ unsigned long vsyncstart;
+ unsigned long vsyncend;
+ unsigned long vblankend;
+ unsigned long vtotal;
+
+ unsigned long vactive_even;
+ unsigned long vblankstart_even;
+ unsigned long vsyncstart_even;
+ unsigned long vsyncend_even;
+ unsigned long vblankend_even;
+ unsigned long vtotal_even;
+
+ /* CLOCK FREQUENCY */
+
+ unsigned long frequency;
+
+} VG_DISPLAY_MODE;
+
+/*-------------------------------------------*/
+/* PLL FLAGS */
+/*-------------------------------------------*/
+
+#define VG_PLL_DIVIDE_BY_2 0x00000001
+#define VG_PLL_DIVIDE_BY_4 0x00000002
+#define VG_PLL_BYPASS 0x00000004
+#define VG_PLL_MANUAL 0x00000008
+#define VG_PLL_VIP_CLOCK 0x00000010
+
+/*-------------------------------------------*/
+/* USER STRUCTURE FOR QUERYING DISPLAY MODES */
+/*-------------------------------------------*/
+
+typedef struct tagQueryDisplayMode
+{
+ int interlaced;
+ int halfclock;
+ unsigned long active_width;
+ unsigned long active_height;
+ unsigned long panel_width;
+ unsigned long panel_height;
+ unsigned long total_width;
+ unsigned long total_height;
+ unsigned long bpp;
+ unsigned long hz;
+ unsigned long frequency;
+ unsigned long query_flags;
+ unsigned long encoder;
+ unsigned long tvmode;
+
+} VG_QUERY_MODE;
+
+/*-------------------------------------------*/
+/* USER STRUCTURE FOR QUERYING CURSOR DATA */
+/*-------------------------------------------*/
+
+typedef struct tagCursorData
+{
+ int enable;
+ int color_cursor;
+ unsigned long cursor_offset;
+ unsigned long cursor_x;
+ unsigned long cursor_y;
+ unsigned long clipx;
+ unsigned long clipy;
+ unsigned long mono_color0;
+ unsigned long mono_color1;
+ unsigned long flags;
+
+} VG_CURSOR_DATA;
+
+/*------------------------------------------------*/
+/* VG INTERRUPT STATUS SOURCES */
+/*------------------------------------------------*/
+
+#define VG_INT_LINE_MATCH 0x00010000
+#define VG_INT_VSYNC_LOSS 0x00020000
+
+/*------------------------------------------------*/
+/* USER STRUCTURE FOR SETTING COMPRESSION DATA */
+/*------------------------------------------------*/
+
+typedef struct tagCompressionData
+{
+ unsigned long compression_offset;
+ unsigned long pitch;
+ unsigned long size;
+ unsigned long flags;
+
+} VG_COMPRESSION_DATA;
+
+/*-------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING LINE INTERRUPTS */
+/*-------------------------------------------------*/
+
+typedef struct tagInterruptInfo
+{
+ unsigned long line;
+ unsigned long flags;
+ int enable;
+
+} VG_INTERRUPT_PARAMS;
+
+/*-------------------------------------------------*/
+/* USER STRUCTURE FOR PANNING THE DESKTOP */
+/*-------------------------------------------------*/
+
+typedef struct tagPanningInfo
+{
+ unsigned long start_x;
+ unsigned long start_y;
+ int start_updated;
+
+} VG_PANNING_COORDINATES;
+
+/*--------------------------------------------------*/
+/* USER STRUCTURE FOR SAVING/RESTORING THE VG STATE */
+/*--------------------------------------------------*/
+
+typedef struct tagVGSaveRestore
+{
+ /* VG REGISTERS */
+
+ unsigned long unlock;
+ unsigned long gcfg;
+ unsigned long dcfg;
+ unsigned long arb_cfg;
+ unsigned long fb_offset;
+ unsigned long cb_offset;
+ unsigned long cursor_offset;
+ unsigned long video_y_offset;
+ unsigned long video_u_offset;
+ unsigned long video_v_offset;
+ unsigned long dv_top;
+ unsigned long line_size;
+ unsigned long gfx_pitch;
+ unsigned long video_yuv_pitch;
+ unsigned long h_active;
+ unsigned long h_blank;
+ unsigned long h_sync;
+ unsigned long v_active;
+ unsigned long v_blank;
+ unsigned long v_sync;
+ unsigned long fb_active;
+ unsigned long cursor_x;
+ unsigned long cursor_y;
+ unsigned long vid_ds_delta;
+ unsigned long fb_base;
+ unsigned long dv_ctl;
+ unsigned long gfx_scale;
+ unsigned long irq_ctl;
+ unsigned long vbi_even_ctl;
+ unsigned long vbi_odd_ctl;
+ unsigned long vbi_hor_ctl;
+ unsigned long vbi_odd_line_enable;
+ unsigned long vbi_even_line_enable;
+ unsigned long vbi_pitch;
+ unsigned long color_key;
+ unsigned long color_key_mask;
+ unsigned long color_key_x;
+ unsigned long color_key_y;
+ unsigned long irq;
+ unsigned long genlk_ctl;
+ unsigned long vid_y_even_offset;
+ unsigned long vid_u_even_offset;
+ unsigned long vid_v_even_offset;
+ unsigned long vactive_even;
+ unsigned long vblank_even;
+ unsigned long vsync_even;
+ unsigned long h_coeff[512];
+ unsigned long v_coeff[256];
+ unsigned long palette[261];
+ unsigned long cursor_data[3072];
+ unsigned long dot_pll;
+ unsigned long pll_flags;
+
+ /* VG MSRS */
+
+ Q_WORD msr_cap;
+ Q_WORD msr_config;
+ Q_WORD msr_smi;
+ Q_WORD msr_error;
+ Q_WORD msr_pm;
+ Q_WORD msr_diag;
+ Q_WORD msr_spare;
+ Q_WORD msr_ram_ctl;
+
+} VG_SAVE_RESTORE;
+
+/*-------------------------------------------*/
+/* VG_GET_DISPLAY_MODE_INDEX PARAMETERS */
+/*-------------------------------------------*/
+
+#define VG_QUERYFLAG_ACTIVEWIDTH 0x00000001
+#define VG_QUERYFLAG_ACTIVEHEIGHT 0x00000002
+#define VG_QUERYFLAG_TOTALWIDTH 0x00000004
+#define VG_QUERYFLAG_TOTALHEIGHT 0x00000008
+#define VG_QUERYFLAG_BPP 0x00000010
+#define VG_QUERYFLAG_REFRESH 0x00000020
+#define VG_QUERYFLAG_PIXELCLOCK 0x00000040
+#define VG_QUERYFLAG_PIXELCLOCK_APPROX 0x00000080
+#define VG_QUERYFLAG_PANEL 0x00000100
+#define VG_QUERYFLAG_PANELWIDTH 0x00000200
+#define VG_QUERYFLAG_PANELHEIGHT 0x00000400
+#define VG_QUERYFLAG_TVOUT 0x00000800
+#define VG_QUERYFLAG_INTERLACED 0x00001000
+#define VG_QUERYFLAG_HALFCLOCK 0x00002000
+#define VG_QUERYFLAG_ENCODER 0x00004000
+#define VG_QUERYFLAG_TVMODE 0x00008000
+
+/*-----------------------------------------------*/
+/* VG FLICKER FILTER SETTINGS */
+/*-----------------------------------------------*/
+
+#define VG_FLICKER_FILTER_NONE 0x00000000
+#define VG_FLICKER_FILTER_1_16 0x10000000
+#define VG_FLICKER_FILTER_1_8 0x20000000
+#define VG_FLICKER_FILTER_1_4 0x40000000
+#define VG_FLICKER_FILTER_5_16 0x50000000
+#define VG_FLICKER_FILTER_MASK 0xF0000000
+
+/*-----------------------------------------------*/
+/* VG CRC SOURCES */
+/*-----------------------------------------------*/
+
+#define VG_CRC_SOURCE_PREFILTER 0x00000000
+#define VG_CRC_SOURCE_PREFLICKER 0x00000001
+#define VG_CRC_SOURCE_POSTFLICKER 0x00000002
+#define VG_CRC_SOURCE_PREFILTER_EVEN 0x00000010
+#define VG_CRC_SOURCE_PREFLICKER_EVEN 0x00000011
+#define VG_CRC_SOURCE_POSTFLICKER_EVEN 0x00000012
+#define VG_CRC_SOURCE_EVEN 0x00000010
+
+/*===================================================*/
+/* DISPLAY FILTER PARAMETERS */
+/*===================================================*/
+
+/*-----------------------------------------------*/
+/* VIDEO FORMAT DEFINITIONS */
+/*-----------------------------------------------*/
+
+#define DF_VIDFMT_UYVY 0x0000
+#define DF_VIDFMT_Y2YU 0x0001
+#define DF_VIDFMT_YUYV 0x0002
+#define DF_VIDFMT_YVYU 0x0003
+#define DF_VIDFMT_Y0Y1Y2Y3 0x0004
+#define DF_VIDFMT_Y3Y2Y1Y0 0x0005
+#define DF_VIDFMT_Y1Y0Y3Y2 0x0006
+#define DF_VIDFMT_Y1Y2Y3Y0 0x0007
+#define DF_VIDFMT_RGB 0x0008
+#define DF_VIDFMT_P2M_P2L_P1M_P1L 0x0009
+#define DF_VIDFMT_P1M_P1L_P2M_P2L 0x000A
+#define DF_VIDFMT_P1M_P2L_P2M_P1L 0x000B
+
+/*-----------------------------------------------*/
+/* CRT ENABLE STATES */
+/*-----------------------------------------------*/
+
+#define DF_CRT_DISABLE 0x0000
+#define DF_CRT_ENABLE 0x0001
+#define DF_CRT_STANDBY 0x0002
+#define DF_CRT_SUSPEND 0x0003
+
+/*-----------------------------------------------*/
+/* VIDEO SCALING FLAGS */
+/*-----------------------------------------------*/
+
+#define DF_SCALEFLAG_CHANGEX 0x0001
+#define DF_SCALEFLAG_CHANGEY 0x0002
+
+/*-----------------------------------------------*/
+/* DISPLAY FILTER COLOR SPACES */
+/*-----------------------------------------------*/
+
+#define DF_OUTPUT_RGB 0x0001
+#define DF_OUTPUT_ARGB 0x0002
+#define DF_OUTPUT_SDTV 0x0003
+#define DF_OUTPUT_HDTV 0x0004
+
+/*-----------------------------------------------*/
+/* DISPLAY FILTER OUTPUT PATHS */
+/*-----------------------------------------------*/
+
+#define DF_DISPLAY_CRT 0x0001
+#define DF_DISPLAY_FP 0x0002
+#define DF_DISPLAY_CRT_FP 0x0003
+#define DF_DISPLAY_VOP 0x0004
+#define DF_DISPLAY_DRGB 0x0005
+#define DF_DISPLAY_CRT_DRGB 0x0006
+
+/*-----------------------------------------------*/
+/* WINDOWED CRC DATA SOURCES */
+/*-----------------------------------------------*/
+
+#define DF_CRC_SOURCE_GFX_DATA 0x0000
+#define DF_CRC_SOURCE_CRT_RGB 0x0001
+#define DF_CRC_SOURCE_FP_DATA 0x0002
+
+/*-----------------------------------------------*/
+/* VIDEO ENABLE FLAGS */
+/*-----------------------------------------------*/
+
+#define DF_ENABLEFLAG_NOCOLORKEY 0x0001
+
+/*-----------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING A VIDEO SOURCE */
+/*-----------------------------------------------*/
+
+#define DF_SOURCEFLAG_HDTVSOURCE 0x0001
+#define DF_SOURCEFLAG_IMPLICITSCALING 0x0002
+
+typedef struct tagVideoSourceInfo
+{
+ unsigned long video_format;
+ unsigned long y_offset;
+ unsigned long u_offset;
+ unsigned long v_offset;
+ unsigned long y_pitch;
+ unsigned long uv_pitch;
+ unsigned long width;
+ unsigned long height;
+ unsigned long flags;
+
+} DF_VIDEO_SOURCE_PARAMS;
+
+/*---------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING THE VIDEO POSITION */
+/*---------------------------------------------------*/
+
+#define DF_POSFLAG_DIRECTCLIP 0x0001
+#define DF_POSFLAG_INCLUDEBORDER 0x0002
+
+typedef struct tagVideoPosition
+{
+ long x;
+ long y;
+ unsigned long width;
+ unsigned long height;
+ unsigned long left_clip;
+ unsigned long dst_clip;
+ unsigned long flags;
+
+} DF_VIDEO_POSITION;
+
+/*-------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING THE VIDEO CURSOR */
+/*-------------------------------------------------*/
+
+typedef struct tagVideoCursorInfo
+{
+ unsigned long key;
+ unsigned long mask;
+ unsigned long color1;
+ unsigned long color2;
+ unsigned long select_color2;
+ unsigned long flags;
+
+} DF_VIDEO_CURSOR_PARAMS;
+
+/*-------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING AN ALPHA REGION */
+/*-------------------------------------------------*/
+
+#define DF_ALPHAFLAG_COLORENABLED 0x0001
+#define DF_ALPHAFLAG_PERPIXELENABLED 0x0002
+
+typedef struct tagAlphaRegionInfo
+{
+ unsigned long x;
+ unsigned long y;
+ unsigned long width;
+ unsigned long height;
+ unsigned long alpha_value;
+ unsigned long priority;
+ unsigned long color;
+ unsigned long flags;
+ long delta;
+
+} DF_ALPHA_REGION_PARAMS;
+
+/*-------------------------------------------------*/
+/* USER STRUCTURE FOR SAVING/RESTORING DF DATA */
+/*-------------------------------------------------*/
+
+typedef struct tagDFSaveRestore
+{
+ unsigned long vcfg;
+ unsigned long dcfg;
+ unsigned long video_x;
+ unsigned long video_y;
+ unsigned long video_scaler;
+ unsigned long video_color_key;
+ unsigned long video_color_mask;
+ unsigned long sat_limit;
+ unsigned long vid_misc;
+ unsigned long video_yscale;
+ unsigned long video_xscale;
+ unsigned long vid_alpha_control;
+ unsigned long cursor_key;
+ unsigned long cursor_mask;
+ unsigned long cursor_color1;
+ unsigned long cursor_color2;
+ unsigned long alpha_xpos1;
+ unsigned long alpha_ypos1;
+ unsigned long alpha_color1;
+ unsigned long alpha_control1;
+ unsigned long alpha_xpos2;
+ unsigned long alpha_ypos2;
+ unsigned long alpha_color2;
+ unsigned long alpha_control2;
+ unsigned long alpha_xpos3;
+ unsigned long alpha_ypos3;
+ unsigned long alpha_color3;
+ unsigned long alpha_control3;
+ unsigned long vid_request;
+ unsigned long vid_ypos_even;
+ unsigned long alpha_ypos_even1;
+ unsigned long alpha_ypos_even2;
+ unsigned long alpha_ypos_even3;
+ unsigned long panel_tim1;
+ unsigned long panel_tim2;
+ unsigned long panel_pm;
+ unsigned long panel_dither;
+
+ unsigned long palette[256];
+ unsigned long coefficients[512];
+
+ /* DF MSRS */
+
+ Q_WORD msr_cap;
+ Q_WORD msr_config;
+ Q_WORD msr_smi;
+ Q_WORD msr_error;
+ Q_WORD msr_pm;
+ Q_WORD msr_diag;
+ Q_WORD msr_df_diag;
+ Q_WORD msr_pad_sel;
+
+} DF_SAVE_RESTORE;
+
+/*-----------------------------------------------*/
+/* DF CRC SOURCES */
+/*-----------------------------------------------*/
+
+#define DF_CRC_SOURCE_ODD_FIELD 0x00000100
+#define DF_CRC_SOURCE_EVEN_FIELD 0x00001000
+#define DF_CRC_SOURCE_EVEN 0x00001000
+
+/*===================================================*/
+/* VIP USER PARAMETER DEFINITIONS */
+/*===================================================*/
+
+#define VIP_MODEFLAG_VSYNCACTIVEHIGH 0x00000001
+#define VIP_MODEFLAG_HSYNCACTIVEHIGH 0x00000002
+
+/*---------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING 601 SETTINGS */
+/*---------------------------------------------*/
+
+typedef struct _TAG_VIP601PARAMS
+{
+ unsigned long flags;
+ unsigned long horz_start;
+ unsigned long width;
+ unsigned long vert_start_even;
+ unsigned long even_height;
+ unsigned long vert_start_odd;
+ unsigned long odd_height;
+ unsigned long vbi_start;
+ unsigned long vbi_height;
+ unsigned long odd_detect_start;
+ unsigned long odd_detect_end;
+
+} VIP_601PARAMS;
+
+/*-------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING A VIP MODE */
+/*-------------------------------------------*/
+
+/* VIP MODE FLAGS */
+
+#define VIP_MODEFLAG_PLANARCAPTURE 0x00000001
+#define VIP_MODEFLAG_INVERTPOLARITY 0x00000002
+#define VIP_MODEFLAG_PROGRESSIVE 0x00000004
+#define VIP_MODEFLAG_DISABLEZERODETECT 0x00000008
+#define VIP_MODEFLAG_ENABLEREPEATFLAG 0x00000010
+#define VIP_MODEFLAG_10BITANCILLARY 0x00000020
+#define VIP_MODEFLAG_TOGGLEEACHFIELD 0x00000040
+#define VIP_MODEFLAG_INVERTTASKPOLARITY 0x00000080
+#define VIP_MODEFLAG_FLIPMESSAGEWHENFULL 0x00000100
+
+/* VIP CAPTURE ENABLE FLAGS */
+
+#define VIP_ENABLE_TASKA 0x00000100
+#define VIP_ENABLE_TASKA_VBI 0x00000200
+#define VIP_ENABLE_TASKB 0x00000400
+#define VIP_ENABLE_TASKB_VBI 0x00000800
+#define VIP_ENABLE_ANCILLARY 0x00001000
+#define VIP_ENABLE_ALL 0x00001F00
+
+/* VIP CAPTURE MODE FLAGS */
+
+#define VIP_MODE_IDLE 0x00000000
+#define VIP_MODE_VIP2_8BIT 0x00000002
+#define VIP_MODE_VIP2_16BIT 0x00000004
+#define VIP_MODE_VIP1_8BIT 0x00000006
+#define VIP_MODE_MSG 0x00000008
+#define VIP_MODE_DATA 0x0000000A
+#define VIP_MODE_8BIT601 0x0000000C
+#define VIP_MODE_16BIT601 0x0000000E
+
+/* 4:2:0 PLANAR CAPTURE METHODS */
+
+#define VIP_420CAPTURE_EVERYLINE 0x00000001
+#define VIP_420CAPTURE_ALTERNATINGLINES 0x00000002
+#define VIP_420CAPTURE_ALTERNATINGFIELDS 0x00000003
+
+typedef struct _TAG_SETMODEBUFFER
+{
+ unsigned long flags;
+ unsigned long stream_enables;
+ unsigned long operating_mode;
+ unsigned long planar_capture;
+ VIP_601PARAMS vip601_settings;
+
+} VIPSETMODEBUFFER;
+
+/*-----------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING VG/VIP GENLOCK */
+/*-----------------------------------------------*/
+
+/* LOSS OF VIDEO DETECTION FLAGS */
+
+#define VIP_VDE_RUNAWAY_LINE 0x00800000
+#define VIP_VDE_VERTICAL_TIMING 0x00400000
+#define VIP_VDE_CLOCKS_PER_LINE 0x00200000
+#define VIP_VDE_LOST_CLOCK 0x00100000
+
+/* VIP VSYNC SELECT FOR THE VG */
+
+#define VIP_VGSYNC_NONE 0x00000000
+#define VIP_VGSYNC_START_FRAME 0x00000001
+#define VIP_VGSYNC_FALLING_EDGE_VBLANK 0x00000002
+#define VIP_VGSYNC_RISING_EDGE_VBLANK 0x00000003
+#define VIP_VGSYNC_FALLING_EDGE_FIELD 0x00000004
+#define VIP_VGSYNC_RISING_EDGE_FIELD 0x00000005
+#define VIP_VGSYNC_VIP_CURRENT_LINE 0x00000006
+#define VIP_VGSYNC_MSG_INT 0x00000007
+
+/* VIP FIELD SELECT FOR THE VG */
+
+#define VIP_VGFIELD_INPUT 0x00000000
+#define VIP_VGFIELD_INPUT_INV 0x00000008
+#define VIP_VGFIELD_ACTIVE_PAGE 0x00000010
+#define VIP_VGFIELD_ACTIVE_PAGE_IN 0x00000018
+
+/*--------------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING THE VG VSYNC GENLOCK */
+/*--------------------------------------------------------*/
+
+typedef struct _TAG_GENLOCKBUFFER
+{
+ unsigned long vip_signal_loss;
+ unsigned long vsync_to_vg;
+ unsigned long field_to_vg;
+ unsigned long genlock_skew;
+ int enable_timeout;
+
+} VIPGENLOCKBUFFER;
+
+/*------------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING VIP ANCILLARY CAPTURE */
+/*------------------------------------------------------*/
+
+typedef struct _TAG_ANCILLARYBUFFER
+{
+ unsigned long msg1_base;
+ unsigned long msg2_base;
+ unsigned long msg_size;
+
+} VIPANCILLARYBUFFER;
+
+/*----------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING VIP CAPTURE BUFFERS */
+/*----------------------------------------------------*/
+
+#define VIP_INPUTFLAG_VBI 0x00000001
+#define VIP_INPUTFLAG_INVERTPOLARITY 0x00000002
+#define VIP_INPUTFLAG_PLANAR 0x00000004
+
+#define VIP_MAX_BUFFERS 10
+
+#define VIP_BUFFER_TASK_A 0x0000
+#define VIP_BUFFER_TASK_B 0x0001
+#define VIP_BUFFER_MAX_TASKS 0x0002
+
+#define VIP_BUFFER_A 0x0000
+#define VIP_BUFFER_B 0x0001
+#define VIP_BUFFER_ANC 0x0002
+#define VIP_BUFFER_MSG 0x0003
+#define VIP_BUFFER_601 0x0004
+#define VIP_BUFFER_A_ODD 0x0005
+#define VIP_BUFFER_A_EVEN 0x0006
+#define VIP_BUFFER_B_ODD 0x0007
+#define VIP_BUFFER_B_EVEN 0x0008
+
+typedef struct _TAG_INPUTBUFFER_ADDR
+{
+ unsigned long even_base[VIP_MAX_BUFFERS];
+ unsigned long odd_base[VIP_MAX_BUFFERS];
+ unsigned long y_pitch;
+ unsigned long uv_pitch;
+ unsigned long odd_uoffset;
+ unsigned long odd_voffset;
+ unsigned long even_uoffset;
+ unsigned long even_voffset;
+ unsigned long vbi_even_base;
+ unsigned long vbi_odd_base;
+
+} VIPINPUTBUFFER_ADDR;
+
+typedef struct _TAG_SETINPUTBUFFER
+{
+ unsigned long flags;
+ VIPINPUTBUFFER_ADDR offsets[VIP_BUFFER_MAX_TASKS];
+ unsigned long current_buffer;
+
+ VIPANCILLARYBUFFER ancillaryData;
+
+} VIPINPUTBUFFER;
+
+/*------------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING VIP SUBWINDOW CAPTURE */
+/*------------------------------------------------------*/
+
+typedef struct _TAG_SUBWINDOWBUFFER
+{
+ int enable;
+ unsigned long start;
+ unsigned long stop;
+
+} VIPSUBWINDOWBUFFER;
+
+/*--------------------------------------------------------*/
+/* USER STRUCTURE FOR SAVING/RESTORING VIP REGISTERS */
+/*--------------------------------------------------------*/
+
+typedef struct _TAG_VIPSTATEBUFFER
+{
+ unsigned long control1;
+ unsigned long control2;
+ unsigned long vip_int;
+ unsigned long current_target;
+ unsigned long max_address;
+ unsigned long taska_evenbase;
+ unsigned long taska_oddbase;
+ unsigned long taska_vbi_evenbase;
+ unsigned long taska_vbi_oddbase;
+ unsigned long taska_data_pitch;
+ unsigned long control3;
+ unsigned long taska_v_oddoffset;
+ unsigned long taska_u_oddoffset;
+ unsigned long taskb_evenbase;
+ unsigned long taskb_oddbase;
+ unsigned long taskb_vbi_evenbase;
+ unsigned long taskb_vbi_oddbase;
+ unsigned long taskb_pitch;
+ unsigned long taskb_voffset;
+ unsigned long taskb_uoffset;
+ unsigned long msg1_base;
+ unsigned long msg2_base;
+ unsigned long msg_size;
+ unsigned long page_offset;
+ unsigned long vert_start_stop;
+ unsigned long vsync_err_count;
+ unsigned long taska_u_evenoffset;
+ unsigned long taska_v_evenoffset;
+
+ Q_WORD msr_config;
+ Q_WORD msr_smi;
+ Q_WORD msr_pm;
+ Q_WORD msr_diag;
+
+} VIPSTATEBUFFER;
+
+/*--------------------------------------------------------*/
+/* VIP_SET_CAPTURE_STATE USER PARAMETERS */
+/*--------------------------------------------------------*/
+
+#define VIP_STOPCAPTURE 0x0000
+#define VIP_STOPCAPTUREATLINEEND 0x0001
+#define VIP_STOPCAPTUREATFIELDEND 0x0002
+#define VIP_STOPCAPTUREATFRAMEEND 0x0003
+#define VIP_STARTCAPTUREATNEXTLINE 0x0004
+#define VIP_STARTCAPTUREATNEXTFIELD 0x0005
+#define VIP_STARTCAPTUREATNEXTFRAME 0x0006
+#define VIP_STARTCAPTURE 0x0007
+
+/*--------------------------------------------------------*/
+/* VIP_CONFIGURE_FIFO USER PARAMETERS */
+/*--------------------------------------------------------*/
+
+#define VIP_VIDEOTHRESHOLD 0x3000
+#define VIP_ANCILLARYTHRESHOLD 0x3001
+#define VIP_VIDEOFLUSH 0x3002
+#define VIP_ANCILLARYFLUSH 0x3003
+
+/*--------------------------------------------------------*/
+/* VIP_SET_INTERRUPT_ENABLE USER DEFINITIONS */
+/*--------------------------------------------------------*/
+
+#define VIP_INT_FIFO_ERROR 0x80000000
+#define VIP_INT_FIFO_WRAP 0x40000000
+#define VIP_INT_FIFO_OVERFLOW 0x20000000
+#define VIP_INT_FIFO_THRESHOLD 0x10000000
+#define VIP_INT_LONGLINE 0x08000000
+#define VIP_INT_VERTICAL_TIMING 0x04000000
+#define VIP_INT_ACTIVE_PIXELS 0x02000000
+#define VIP_INT_CLOCK_INPUT 0x01000000
+#define VIP_INT_ANC_CHECKSUM_PARITY 0x00800000
+#define VIP_INT_MSG_BUFFER_FULL 0x00400000
+#define VIP_INT_END_VBLANK 0x00200000
+#define VIP_INT_START_VBLANK 0x00100000
+#define VIP_INT_START_EVEN 0x00080000
+#define VIP_INT_START_ODD 0x00040000
+#define VIP_INT_LINE_MATCH_TARGET 0x00020000
+#define VIP_ALL_INTERRUPTS 0xFFFE0000
+
+/*--------------------------------------------------------*/
+/* VIP_GET_CURRENT_FIELD RETURN VALUES */
+/*--------------------------------------------------------*/
+
+#define VIP_ODD_FIELD 1
+#define VIP_EVEN_FIELD 0
+
+/*-------------------------------------------------*/
+/* USER STRUCTURE FOR QUERYING VIP CAPABILITIES */
+/*-------------------------------------------------*/
+
+typedef struct _TAG_CAPABILITIESBUFFER
+{
+ unsigned long revision_id;
+ unsigned long device_id;
+ unsigned long n_clock_domains;
+ unsigned long n_smi_registers;
+
+} VIPCAPABILITIESBUFFER;
+
+/*-------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING VIP POWER */
+/*-------------------------------------------------*/
+
+typedef struct _TAG_POWERBUFFER
+{
+ int glink_clock_mode;
+ int vip_clock_mode;
+
+} VIPPOWERBUFFER;
+
+/*-------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING VIP PRIORITIES */
+/*-------------------------------------------------*/
+
+typedef struct _TAG_PRIORITYBUFFER
+{
+ unsigned long secondary;
+ unsigned long primary;
+ unsigned long pid;
+
+} VIPPRIORITYBUFFER;
+
+/*--------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING VIP DEBUG OUTPUTS */
+/*--------------------------------------------------*/
+
+#define VIP_DIAG_UPPER_GLINK_MASTER 0x00010000
+#define VIP_DIAG_UPPER_GLINK_SLAVE 0x00020000
+#define VIP_DIAG_UPPER_GLINK_SLAVE_MMREG 0x00040000
+#define VIP_DIAG_UPPER_Y_BUFFER 0x00080000
+#define VIP_DIAG_UPPER_A_BUFFER 0x00100000
+#define VIP_DIAG_UPPER_FIFO_OUTPUT 0x00200000
+#define VIP_DIAG_UPPER_FIFO_INPUT 0x01000000
+#define VIP_DIAG_UPPER_FORMATTER 0x02000000
+#define VIP_DIAG_UPPER_INPUT_CONTROL 0x04000000
+
+#define VIP_DIAG_LOWER_GLINK_MASTER 0x00000001
+#define VIP_DIAG_LOWER_GLINK_SLAVE 0x00000002
+#define VIP_DIAG_LOWER_GLINK_SLAVE_MMREG 0x00000004
+#define VIP_DIAG_LOWER_Y_BUFFER 0x00000008
+#define VIP_DIAG_LOWER_A_BUFFER 0x00000010
+#define VIP_DIAG_LOWER_FIFO_OUTPUT 0x00000020
+#define VIP_DIAG_LOWER_FIFO_INPUT 0x00000100
+#define VIP_DIAG_LOWER_FORMATTER 0x00000200
+#define VIP_DIAG_LOWER_INPUT_CONTROL 0x00000400
+
+typedef struct _TAG_DEBUGBUFFER
+{
+ unsigned long bist;
+ unsigned long enable_upper;
+ unsigned long select_upper;
+ unsigned long enable_lower;
+ unsigned long select_lower;
+
+} VIPDEBUGBUFFER;
+
+
+/*===================================================*/
+/* VOP USER PARAMETER DEFINITIONS */
+/*===================================================*/
+
+/*------------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING VBI CAPTURE */
+/*------------------------------------------------------*/
+
+typedef struct _TAG_VBIWINDOWBUFFER
+{
+ long horz_start;
+ unsigned long vbi_width;
+ unsigned long odd_line_capture_mask;
+ unsigned long even_line_capture_mask;
+ unsigned long odd_line_offset;
+ unsigned long even_line_offset;
+ unsigned long even_address_offset;
+ unsigned long odd_address_offset;
+ unsigned long data_size;
+ unsigned long data_pitch;
+ int enable_upscale;
+ int horz_from_hsync;
+
+} VOPVBIWINDOWBUFFER;
+
+/*------------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING 601 FOR VOP */
+/*------------------------------------------------------*/
+
+#define VOP_601_INVERT_DISPE 0x00080000
+#define VOP_601_INVERT_VSYNC 0x00040000
+#define VOP_601_INVERT_HSYNC 0x00020000
+
+#define VOP_VSYNC_EARLIER_BY4 0x00000000
+#define VOP_VSYNC_EARLIER_BY2 0x00004000
+#define VOP_VSYNC_NOSHIFT 0x00008000
+#define VOP_VSYNC_LATER_BY_X 0x0000C000
+
+#define VOP_601_YUV_8BIT 0x00000000
+#define VOP_601_YUV_16BIT 0x00000001
+#define VOP_601_RGB_8_8_8 0x00000002
+#define VOP_601_YUV_4_4_4 0x00000003
+
+typedef struct _TAG_VOP601
+{
+ unsigned long flags;
+ unsigned long vsync_shift;
+ unsigned long vsync_shift_count;
+ unsigned long output_mode;
+
+} VOP_601DATA;
+
+/*------------------------------------------------------*/
+/* USER STRUCTURE FOR CONFIGURING VOP OUTPUT */
+/*------------------------------------------------------*/
+
+/* VOP FLAGS */
+
+#define VOP_FLAG_SINGLECHIPCOMPAT 0x00000001
+#define VOP_FLAG_EXTENDEDSAV 0x00000002
+#define VOP_FLAG_VBI 0x00000008
+#define VOP_FLAG_TASK 0x00000010
+#define VOP_FLAG_SWAP_UV 0x00000020
+#define VOP_FLAG_SWAP_VBI 0x00000040
+
+/* 4:4:2 TO 4:2:2 DECIMATION */
+
+#define VOP_422MODE_COSITED 0x00000000
+#define VOP_422MODE_INTERSPERSED 0x00000010
+#define VOP_422MODE_ALTERNATING 0x00000020
+
+/* VOP OPERATING MODES */
+
+#define VOP_MODE_DISABLED 0x00000000
+#define VOP_MODE_VIP11 0x00000001
+#define VOP_MODE_CCIR656 0x00000002
+#define VOP_MODE_VIP20_8BIT 0x00000003
+#define VOP_MODE_VIP20_16BIT 0x00000004
+#define VOP_MODE_601 0x00000005
+
+/* VSYNC OUT SELECT FLAGS */
+
+#define VOP_MB_SYNCSEL_DISABLED 0x00000000
+#define VOP_MB_SYNCSEL_VG 0x00000020
+#define VOP_MB_SYNCSEL_VG_INV 0x00000040
+#define VOP_MB_SYNCSEL_STATREG17 0x00000060
+#define VOP_MB_SYNCSEL_STATREG17_INV 0x00000080
+
+typedef struct _TAG_VOPMODECONFIGURATIONBUFFER
+{
+ unsigned long flags;
+ unsigned long mode;
+ unsigned long conversion_mode;
+ unsigned long vsync_out;
+ VOP_601DATA vop601;
+
+} VOPCONFIGURATIONBUFFER;
+
+/*--------------------------------------------------------*/
+/* USER STRUCTURE FOR SAVING/RESTORING VOP REGISTERS */
+/*--------------------------------------------------------*/
+
+typedef struct _TAG_VOPSTATEBUFFER
+{
+ unsigned long config;
+} VOPSTATEBUFFER;
+
+#endif
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_regs.h xf86-video-nsc-2.8.1/src/cim/cim_regs.h
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_regs.h 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_regs.h 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,1233 @@
+ /*
+ *
+ * Copyright (C) 2005 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *
+ *
+ *
+ *
+ *
+ * Cimarron register definitions
+ *
+ *
+ */
+
+#ifndef _cim_regs_h
+#define _cim_regs_h
+
+/*----------------------------------------------------------------*/
+/* GRAPHICS PROCESSOR DEFINITIONS */
+/*----------------------------------------------------------------*/
+
+/*----------------------------*/
+/* COMMAND BUFFER DEFINITIONS */
+/*----------------------------*/
+
+#define GP3_BLT_COMMAND_SIZE 68 /* 18 DWORDS */
+#define GP3_VECTOR_COMMAND_SIZE 56 /* 14 DWORDS */
+#define GP3_4BPP_LUT_COMMAND_SIZE 76 /* 16 DWORDS + 3 CMD DWORDS */
+#define GP3_8BPP_LUT_COMMAND_SIZE 1036 /* 256 DWORDS + 3 CMD DWORDS */
+#define GP3_VECTOR_PATTERN_COMMAND_SIZE 20 /* 2 DWORDS + 3 CMD DWORDS */
+#define GP3_MAX_COMMAND_SIZE 9000 /* 8K + WORKAROUND SPACE */
+#define GP3_SCRATCH_BUFFER_SIZE 0x100000 /* 1MB SCRATCH BUFFER */
+#define GP3_BLT_1PASS_SIZE 0xC7F8 /* (50K - 8) is largest 1-Pass load size */
+
+/*-------------------------------------*/
+/* BLT COMMAND BUFFER REGISTER OFFSETS */
+/*-------------------------------------*/
+
+#define GP3_BLT_CMD_HEADER 0x00000000
+#define GP3_BLT_RASTER_MODE 0x00000004
+#define GP3_BLT_DST_OFFSET 0x00000008
+#define GP3_BLT_SRC_OFFSET 0x0000000C
+#define GP3_BLT_STRIDE 0x00000010
+#define GP3_BLT_WID_HEIGHT 0x00000014
+#define GP3_BLT_SRC_COLOR_FG 0x00000018
+#define GP3_BLT_SRC_COLOR_BG 0x0000001C
+#define GP3_BLT_PAT_COLOR_0 0x00000020
+#define GP3_BLT_PAT_COLOR_1 0x00000024
+#define GP3_BLT_PAT_DATA_0 0x00000028
+#define GP3_BLT_PAT_DATA_1 0x0000002C
+#define GP3_BLT_CH3_OFFSET 0x00000030
+#define GP3_BLT_CH3_MODE_STR 0x00000034
+#define GP3_BLT_CH3_WIDHI 0x00000038
+#define GP3_BLT_BASE_OFFSET 0x0000003C
+#define GP3_BLT_MODE 0x00000040
+
+/*-----------------------------------------------------------------*/
+/* VECTOR COMMAND BUFFER REGISTER OFFSETS */
+/* Some of these are identical to the BLT registers (and we will */
+/* be assumed to be such in the Cimarron code, but they are listed */
+/* here for clarity and for future changes. */
+/*-----------------------------------------------------------------*/
+
+#define GP3_VEC_CMD_HEADER 0x00000000
+#define GP3_VECTOR_RASTER_MODE 0x00000004
+#define GP3_VECTOR_DST_OFFSET 0x00000008
+#define GP3_VECTOR_VEC_ERR 0x0000000C
+#define GP3_VECTOR_STRIDE 0x00000010
+#define GP3_VECTOR_VEC_LEN 0x00000014
+#define GP3_VECTOR_SRC_COLOR_FG 0x00000018
+#define GP3_VECTOR_PAT_COLOR_0 0x0000001C
+#define GP3_VECTOR_PAT_COLOR_1 0x00000020
+#define GP3_VECTOR_PAT_DATA_0 0x00000024
+#define GP3_VECTOR_PAT_DATA_1 0x00000028
+#define GP3_VECTOR_CH3_MODE_STR 0x0000002C
+#define GP3_VECTOR_BASE_OFFSET 0x00000030
+#define GP3_VECTOR_MODE 0x00000034
+
+/*---------------------------------------------------*/
+/* GP REGISTER DEFINITIONS */
+/* Addresses for writing or reading directly to/from */
+/* the graphics processor. */
+/*---------------------------------------------------*/
+
+#define GP3_DST_OFFSET 0x00000000
+#define GP3_SRC_OFFSET 0x00000004
+#define GP3_VEC_ERR 0x00000004
+#define GP3_STRIDE 0x00000008
+#define GP3_WID_HEIGHT 0x0000000C
+#define GP3_VEC_LEN 0x0000000C
+#define GP3_SRC_COLOR_FG 0x00000010
+#define GP3_SRC_COLOR_BG 0x00000014
+#define GP3_PAT_COLOR_0 0x00000018
+#define GP3_PAT_COLOR_1 0x0000001C
+#define GP3_PAT_COLOR_2 0x00000020
+#define GP3_PAT_COLOR_3 0x00000024
+#define GP3_PAT_COLOR_4 0x00000028
+#define GP3_PAT_COLOR_5 0x0000002C
+#define GP3_PAT_DATA_0 0x00000030
+#define GP3_PAT_DATA_1 0x00000034
+#define GP3_RASTER_MODE 0x00000038
+#define GP3_VEC_MODE 0x0000003C
+#define GP3_BLT_MODE 0x00000040
+#define GP3_BLT_STATUS 0x00000044
+#define GP3_HST_SRC 0x00000048
+#define GP3_BASE_OFFSET 0x0000004C
+#define GP3_CMD_TOP 0x00000050
+#define GP3_CMD_BOT 0x00000054
+#define GP3_CMD_READ 0x00000058
+#define GP3_CMD_WRITE 0x0000005C
+#define GP3_CH3_OFFSET 0x00000060
+#define GP3_CH3_MODE_STR 0x00000064
+#define GP3_CH3_WIDHI 0x00000068
+#define GP3_CH3_HST_SRC 0x0000006C
+#define GP3_LUT_ADDRESS 0x00000070
+#define GP3_LUT_DATA 0x00000074
+#define GP3_INT_CTL 0x00000078
+#define GP3_HST_SRC_RANGE 0x00000100
+
+/*------------------------*/
+/* REGISTER BIT FIELDS */
+/*------------------------*/
+
+/* GP3_BLT_CMD_HEADER BIT DEFINITIONS */
+
+#define GP3_BLT_HDR_WRAP 0x80000000
+#define GP3_BLT_HDR_TYPE 0x00000000
+#define GP3_BLT_HDR_HAZARD_ENABLE 0x10000000
+#define GP3_BLT_HDR_RASTER_ENABLE 0x00000001
+#define GP3_BLT_HDR_DST_OFF_ENABLE 0x00000002
+#define GP3_BLT_HDR_SRC_OFF_ENABLE 0x00000004
+#define GP3_BLT_HDR_STRIDE_ENABLE 0x00000008
+#define GP3_BLT_HDR_WIDHI_ENABLE 0x00000010
+#define GP3_BLT_HDR_SRC_FG_ENABLE 0x00000020
+#define GP3_BLT_HDR_SRC_BG_ENABLE 0x00000040
+#define GP3_BLT_HDR_PAT_CLR0_ENABLE 0x00000080
+#define GP3_BLT_HDR_PAT_CLR1_ENABLE 0x00000100
+#define GP3_BLT_HDR_PAT_DATA0_ENABLE 0x00000200
+#define GP3_BLT_HDR_PAT_DATA1_ENABLE 0x00000400
+#define GP3_BLT_HDR_CH3_OFF_ENABLE 0x00000800
+#define GP3_BLT_HDR_CH3_STR_ENABLE 0x00001000
+#define GP3_BLT_HDR_CH3_WIDHI_ENABLE 0x00002000
+#define GP3_BLT_HDR_BASE_OFFSET_ENABLE 0x00004000
+#define GP3_BLT_HDR_BLT_MODE_ENABLE 0x00008000
+
+/* GP3_VEC_CMD_HEADER BIT DEFINITIONS */
+
+#define GP3_VEC_HDR_WRAP 0x80000000
+#define GP3_VEC_HDR_TYPE 0x20000000
+#define GP3_VEC_HDR_HAZARD_ENABLE 0x10000000
+#define GP3_VEC_HDR_RASTER_ENABLE 0x00000001
+#define GP3_VEC_HDR_DST_OFF_ENABLE 0x00000002
+#define GP3_VEC_HDR_VEC_ERR_ENABLE 0x00000004
+#define GP3_VEC_HDR_STRIDE_ENABLE 0x00000008
+#define GP3_VEC_HDR_VEC_LEN_ENABLE 0x00000010
+#define GP3_VEC_HDR_SRC_FG_ENABLE 0x00000020
+#define GP3_VEC_HDR_PAT_CLR0_ENABLE 0x00000040
+#define GP3_VEC_HDR_PAT_CLR1_ENABLE 0x00000080
+#define GP3_VEC_HDR_PAT_DATA0_ENABLE 0x00000100
+#define GP3_VEC_HDR_PAT_DATA1_ENABLE 0x00000200
+#define GP3_VEC_HDR_CH3_STR_ENABLE 0x00000400
+#define GP3_VEC_HDR_BASE_OFFSET_ENABLE 0x00000800
+#define GP3_VEC_HDR_VEC_MODE_ENABLE 0x00001000
+
+/* GP3_RASTER_MODE BIT DEFINITIONS */
+
+#define GP3_RM_BPPFMT_332 0x00000000 /* 8 BPP, palettized */
+#define GP3_RM_BPPFMT_4444 0x40000000 /* 16 BPP, 4:4:4:4 */
+#define GP3_RM_BPPFMT_1555 0x50000000 /* 16 BPP, 1:5:5:5 */
+#define GP3_RM_BPPFMT_565 0x60000000 /* 16 BPP, 5:6:5 */
+#define GP3_RM_BPPFMT_8888 0x80000000 /* 32 BPP, 8:8:8:8 */
+#define GP3_RM_ALPHA_ALL 0x00C00000 /* Alpha enable */
+#define GP3_RM_ALPHA_TO_RGB 0x00400000 /* Alpha applies to RGB */
+#define GP3_RM_ALPHA_TO_ALPHA 0x00800000 /* Alpha applies to alpha */
+#define GP3_RM_ALPHA_OP_MASK 0x00300000 /* Alpha operation */
+#define GP3_RM_ALPHA_TIMES_A 0x00000000 /* Alpha * A */
+#define GP3_RM_BETA_TIMES_B 0x00100000 /* (1-alpha) * B */
+#define GP3_RM_A_PLUS_BETA_B 0x00200000 /* A + (1-alpha) * B */
+#define GP3_RM_ALPHA_A_PLUS_BETA_B 0x00300000 /* alpha * A + (1 - alpha)B */
+#define GP3_RM_ALPHA_SELECT 0x000E0000 /* Alpha Select */
+#define GP3_RM_SELECT_ALPHA_A 0x00000000 /* Alpha from channel A */
+#define GP3_RM_SELECT_ALPHA_B 0x00020000 /* Alpha from channel B */
+#define GP3_RM_SELECT_ALPHA_R 0x00040000 /* Registered alpha */
+#define GP3_RM_SELECT_ALPHA_1 0x00060000 /* Constant 1 */
+#define GP3_RM_SELECT_ALPHA_CHAN_A 0x00080000 /* RGB Values from A */
+#define GP3_RM_SELECT_ALPHA_CHAN_B 0x000A0000 /* RGB Values from B */
+#define GP3_RM_SELECT_ALPHA_CHAN_3 0x000C0000 /* Alpha from channel 3 */
+#define GP3_RM_DEST_FROM_CHAN_A 0x00010000 /* Alpha channel select */
+#define GP3_RM_PATTERN_INVERT 0x00001000 /* Invert monochrome pat */
+#define GP3_RM_SOURCE_INVERT 0x00002000 /* Invert monochrome src */
+#define GP3_RM_PAT_FLAGS 0x00000700 /* pattern related bits */
+#define GP3_RM_PAT_MONO 0x00000100 /* monochrome pattern */
+#define GP3_RM_PAT_COLOR 0x00000200 /* color pattern */
+#define GP3_RM_PAT_TRANS 0x00000400 /* pattern transparency */
+#define GP3_RM_SRC_TRANS 0x00000800 /* source transparency */
+
+/* GP3_VECTOR_MODE REGISTER DESCRIPTIONS */
+
+#define GP3_VM_DST_REQ 0x00000008 /* dst data required */
+#define GP3_VM_THROTTLE 0x00000010 /* sync to VBLANK */
+
+/* GP3_BLT_MODE REGISTER DEFINITIONS */
+
+#define GP3_BM_SRC_FB 0x00000001 /* src = frame buffer */
+#define GP3_BM_SRC_HOST 0x00000002 /* src = host register */
+#define GP3_BM_DST_REQ 0x00000004 /* dst data required */
+#define GP3_BM_SRC_MONO 0x00000040 /* monochrome source data */
+#define GP3_BM_SRC_BP_MONO 0x00000080 /* Byte-packed monochrome */
+#define GP3_BM_NEG_YDIR 0x00000100 /* negative Y direction */
+#define GP3_BM_NEG_XDIR 0x00000200 /* negative X direction */
+#define GP3_BM_THROTTLE 0x00000400 /* sync to VBLANK */
+
+/* GP3_BLT_STATUS REGISTER DEFINITIONS */
+
+#define GP3_BS_BLT_BUSY 0x00000001 /* GP is not idle */
+#define GP3_BS_BLT_PENDING 0x00000004 /* second BLT is pending */
+#define GP3_BS_HALF_EMPTY 0x00000008 /* src FIFO half empty */
+#define GP3_BS_CB_EMPTY 0x00000010 /* Command buffer empty. */
+
+/* GP3_CH3_MODE_STR REGISTER DEFINITIONS */
+
+#define GP3_CH3_C3EN 0x80000000
+#define GP3_CH3_REPLACE_SOURCE 0x40000000
+#define GP3_CH3_NEG_XDIR 0x20000000
+#define GP3_CH3_NEG_YDIR 0x10000000
+#define GP3_CH3_SRC_FMT_MASK 0x0f000000
+#define GP3_CH3_SRC_3_3_2 0x00000000
+#define GP3_CH3_SRC_8BPP_INDEXED 0x01000000
+#define GP3_CH3_SRC_8BPP_ALPHA 0x02000000
+#define GP3_CH3_SRC_4_4_4_4 0x04000000
+#define GP3_CH3_SRC_1_5_5_5 0x05000000
+#define GP3_CH3_SRC_0_5_6_5 0x06000000
+#define GP3_CH3_SRC_Y_U_V 0x07000000
+#define GP3_CH3_SRC_8_8_8_8 0x08000000
+#define GP3_CH3_SRC_24BPP_PACKED 0x0B000000
+#define GP3_CH3_SRC_4BPP_INDEXED 0x0D000000
+#define GP3_CH3_SRC_4BPP_ALPHA 0x0E000000
+#define GP3_CH3_SRC_MASK 0x0F000000
+#define GP3_CH3_ROTATE_ENABLE 0x00800000
+#define GP3_CH3_BGR_ORDER 0x00400000
+#define GP3_CH3_COLOR_PAT_ENABLE 0x00200000
+#define GP3_CH3_PRESERVE_LUT 0x00100000
+#define GP3_CH3_PREFETCH_ENABLE 0x00080000
+#define GP3_CH3_HST_SRC_ENABLE 0x00040000
+#define GP3_CH3_STRIDE_MASK 0x0000FFFF
+
+/* DATA AND LUT LOAD BIT DEFINITIONS */
+
+#define GP3_LUT_HDR_WRAP 0x80000000
+#define GP3_LUT_HDR_TYPE 0x40000000
+#define GP3_LUT_HDR_DATA_ENABLE 0x00000003
+#define GP3_DATA_LOAD_HDR_WRAP 0x80000000
+#define GP3_DATA_LOAD_HDR_TYPE 0x60000000
+#define GP3_DATA_LOAD_HDR_ENABLE 0x00000001
+
+#define GP3_HOST_SOURCE_TYPE 0x00000000
+#define GP3_CH3_HOST_SOURCE_TYPE 0x20000000
+#define GP3_OLD_PATTERN_COLORS 0x40000000
+#define GP3_LUT_DATA_TYPE 0x60000000
+
+#define GP3_BASE_OFFSET_DSTMASK 0xFFC00000
+#define GP3_BASE_OFFSET_SRCMASK 0x003FF000
+#define GP3_BASE_OFFSET_CH3MASK 0x00000FFC
+
+/*----------------------------------------------------------------*/
+/* VIDEO GENERATOR DEFINITIONS */
+/*----------------------------------------------------------------*/
+
+#define DC3_UNLOCK 0x00000000 /* Unlock register */
+#define DC3_GENERAL_CFG 0x00000004 /* Config registers */
+#define DC3_DISPLAY_CFG 0x00000008
+#define DC3_ARB_CFG 0x0000000C
+
+#define DC3_FB_ST_OFFSET 0x00000010 /* Frame buffer start offset */
+#define DC3_CB_ST_OFFSET 0x00000014 /* Compression start offset */
+#define DC3_CURS_ST_OFFSET 0x00000018 /* Cursor buffer start offset */
+#define DC3_VID_Y_ST_OFFSET 0x00000020 /* Video Y Buffer start offset */
+#define DC3_VID_U_ST_OFFSET 0x00000024 /* Video U Buffer start offset */
+#define DC3_VID_V_ST_OFFSET 0x00000028 /* Video V Buffer start offset */
+#define DC3_DV_TOP 0x0000002C /* DV Ram Limit Register */
+#define DC3_LINE_SIZE 0x00000030 /* Video, CB, and FB line sizes */
+#define DC3_GFX_PITCH 0x00000034 /* FB and DB skip counts */
+#define DC3_VID_YUV_PITCH 0x00000038 /* Y, U and V buffer skip counts */
+
+#define DC3_H_ACTIVE_TIMING 0x00000040 /* Horizontal timings */
+#define DC3_H_BLANK_TIMING 0x00000044
+#define DC3_H_SYNC_TIMING 0x00000048
+#define DC3_V_ACTIVE_TIMING 0x00000050 /* Vertical Timings */
+#define DC3_V_BLANK_TIMING 0x00000054
+#define DC3_V_SYNC_TIMING 0x00000058
+#define DC3_FB_ACTIVE 0x0000005C
+
+#define DC3_CURSOR_X 0x00000060 /* Cursor X position */
+#define DC3_CURSOR_Y 0x00000064 /* Cursor Y Position */
+#define DC3_LINE_CNT_STATUS 0x0000006C
+
+#define DC3_PAL_ADDRESS 0x00000070 /* Palette Address */
+#define DC3_PAL_DATA 0x00000074 /* Palette Data */
+#define DC3_DFIFO_DIAG 0x00000078 /* Display FIFO diagnostic */
+#define DC3_CFIFO_DIAG 0x0000007C /* Compression FIFO diagnostic */
+
+#define DC3_VID_DS_DELTA 0x00000080 /* Vertical Downscaling fraction */
+
+#define DC3_PHY_MEM_OFFSET 0x00000084 /* VG Base Address Register */
+#define DC3_DV_CTL 0x00000088 /* Dirty-Valid Control Register */
+#define DC3_DV_ACC 0x0000008C /* Dirty-Valid RAM Access */
+
+#define DC3_GFX_SCALE 0x00000090 /* Graphics Scaling */
+#define DC3_IRQ_FILT_CTL 0x00000094 /* VBlank interrupt and filters */
+#define DC3_FILT_COEFF1 0x00000098
+#define DC3_FILT_COEFF2 0x0000009C
+
+#define DC3_VBI_EVEN_CTL 0x000000A0 /* VBI Data Buffer Controls */
+#define DC3_VBI_ODD_CTL 0x000000A4
+#define DC3_VBI_HOR 0x000000A8
+#define DC3_VBI_LN_ODD 0x000000AC
+#define DC3_VBI_LN_EVEN 0x000000B0
+#define DC3_VBI_PITCH 0x000000B4
+
+#define DC3_COLOR_KEY 0x000000B8 /* Graphics color key */
+#define DC3_COLOR_MASK 0x000000BC /* Graphics color key mask */
+#define DC3_CLR_KEY_X 0x000000C0
+#define DC3_CLR_KEY_Y 0x000000C4
+
+#define DC3_IRQ 0x000000C8
+#define DC3_GENLK_CTL 0x000000D4
+
+#define DC3_VID_EVEN_Y_ST_OFFSET 0x000000D8 /* Even field video buffers */
+#define DC3_VID_EVEN_U_ST_OFFSET 0x000000DC
+#define DC3_VID_EVEN_V_ST_OFFSET 0x000000E0
+
+#define DC3_V_ACTIVE_EVEN 0x000000E4 /* Even field timing registers */
+#define DC3_V_BLANK_EVEN 0x000000E8
+#define DC3_V_SYNC_EVEN 0x000000EC
+
+/* UNLOCK VALUE */
+
+#define DC3_UNLOCK_VALUE 0x00004758 /* used to unlock DC regs */
+
+/* VG GEODELINK DEVICE SMI MSR FIELDS */
+
+#define DC3_VG_BL_MASK 0x00000001
+#define DC3_MISC_MASK 0x00000002
+#define DC3_ISR0_MASK 0x00000004
+#define DC3_VGA_BL_MASK 0x00000008
+#define DC3_CRTCIO_MSK 0x00000010
+#define DC3_VG_BLANK_SMI 0x00000001
+#define DC3_MISC_SMI 0x00000002
+#define DC3_ISR0_SMI 0x00000004
+#define DC3_VGA_BLANK_SMI 0x00000008
+#define DC3_CRTCIO_SMI 0x00000010
+
+/* DC3_GENERAL_CFG BIT FIELDS */
+
+#define DC3_GCFG_DBUG 0x80000000
+#define DC3_GCFG_DBSL 0x40000000
+#define DC3_GCFG_CFRW 0x20000000
+#define DC3_GCFG_DIAG 0x10000000
+#define DC3_GCFG_CRC_MODE 0x08000000
+#define DC3_GCFG_SGFR 0x04000000
+#define DC3_GCFG_SGRE 0x02000000
+#define DC3_GCFG_SIGE 0x01000000
+#define DC3_GCFG_SIG_SEL 0x00800000
+#define DC3_GCFG_YUV_420 0x00100000
+#define DC3_GCFG_VDSE 0x00080000
+#define DC3_GCFG_VGAFT 0x00040000
+#define DC3_GCFG_FDTY 0x00020000
+#define DC3_GCFG_STFM 0x00010000
+#define DC3_GCFG_DFHPEL_MASK 0x0000F000
+#define DC3_GCFG_DFHPSL_MASK 0x00000F00
+#define DC3_GCFG_VGAE 0x00000080
+#define DC3_GCFG_DECE 0x00000040
+#define DC3_GCFG_CMPE 0x00000020
+#define DC3_GCFG_FILT_SIG_SEL 0x00000010
+#define DC3_GCFG_VIDE 0x00000008
+#define DC3_GCFG_CLR_CUR 0x00000004
+#define DC3_GCFG_CURE 0x00000002
+#define DC3_GCFG_DFLE 0x00000001
+
+/* DC3_DISPLAY_CFG BIT FIELDS */
+
+#define DC3_DCFG_VISL 0x08000000
+#define DC3_DCFG_FRLK 0x04000000
+#define DC3_DCFG_PALB 0x02000000
+#define DC3_DCFG_DCEN 0x01000000
+#define DC3_DCFG_VFHPEL_MASK 0x000F0000
+#define DC3_DCFG_VFHPSL_MASK 0x0000F000
+#define DC3_DCFG_16BPP_MODE_MASK 0x00000C00
+#define DC3_DCFG_16BPP 0x00000000
+#define DC3_DCFG_15BPP 0x00000400
+#define DC3_DCFG_12BPP 0x00000800
+#define DC3_DCFG_DISP_MODE_MASK 0x00000300
+#define DC3_DCFG_DISP_MODE_8BPP 0x00000000
+#define DC3_DCFG_DISP_MODE_16BPP 0x00000100
+#define DC3_DCFG_DISP_MODE_24BPP 0x00000200
+#define DC3_DCFG_DISP_MODE_32BPP 0x00000300
+#define DC3_DCFG_TRUP 0x00000040
+#define DC3_DCFG_VDEN 0x00000010
+#define DC3_DCFG_GDEN 0x00000008
+#define DC3_DCFG_TGEN 0x00000001
+
+/* DC3_ARB_CFG BIT FIELDS */
+
+#define DC3_ACFG_LB_LOAD_WM_EN 0x00100000
+#define DC3_ACFG_LB_LOAD_WM_MASK 0x000F0000
+#define DC3_ACFG_LPEN_END_COUNT_MASK 0x0000FE00
+#define DC3_ACFG_HPEN_SBINV 0x00000100
+#define DC3_ACFG_HPEN_FB_INV_HALFSB 0x00000080
+#define DC3_ACFG_HPEN_FB_INV_SBRD 0x00000040
+#define DC3_ACFG_HPEN_FB_INV 0x00000020
+#define DC3_ACFG_HPEN_1LB_INV 0x00000010
+#define DC3_ACFG_HPEN_2LB_INV 0x00000008
+#define DC3_ACFG_HPEN_3LB_INV 0x00000004
+#define DC3_ACFG_HPEN_LB_FILL 0x00000002
+#define DC3_ACFG_LPEN_VSYNC 0x00000001
+
+/* DC3_FB_ST_OFFSET BIT FIELDS */
+
+#define DC3_FB_ST_OFFSET_MASK 0x0FFFFFFF
+
+/* DC3_CB_ST_OFFSET BIT FIELDS */
+
+#define DC3_CB_ST_OFFSET_MASK 0x0FFFFFFF
+
+/* DC3_CURS_ST_OFFSET BIT FIELDS */
+
+#define DC3_CURS_ST_OFFSET_MASK 0x0FFFFFFF
+
+/* DC3_ICON_ST_OFFSET BIT FIELDS */
+
+#define DC3_ICON_ST_OFFSET_MASK 0x0FFFFFFF
+
+/* DC3_VID_Y_ST_OFFSET BIT FIELDS */
+
+#define DC3_VID_Y_ST_OFFSET_MASK 0x0FFFFFFF
+
+/* DC3_VID_U_ST_OFFSET BIT FIELDS */
+
+#define DC3_VID_U_ST_OFFSET_MASK 0x0FFFFFFF
+
+/* DC3_VID_V_ST_OFFSET BIT FIELDS */
+
+#define DC3_VID_V_ST_OFFSET_MASK 0x0FFFFFFF
+
+/* DC3_DV_TOP BIT FIELDS */
+
+#define DC3_DVTOP_ENABLE 0x00000001
+#define DC3_DVTOP_MAX_MASK 0x00FFFC00
+#define DC3_DVTOP_MAX_SHIFT 10
+
+/* DC3_LINE_SIZE BIT FIELDS */
+
+#define DC3_LINE_SIZE_VLS_MASK 0x3FF00000
+#define DC3_LINE_SIZE_CBLS_MASK 0x0007F000
+#define DC3_LINE_SIZE_FBLS_MASK 0x000003FF
+#define DC3_LINE_SIZE_CB_SHIFT 12
+#define DC3_LINE_SIZE_VB_SHIFT 20
+
+/* DC3_GFX_PITCH BIT FIELDS */
+
+#define DC3_GFX_PITCH_CBP_MASK 0xFFFF0000
+#define DC3_GFX_PITCH_FBP_MASK 0x0000FFFF
+
+/* DC3_VID_YUV_PITCH BIT FIELDS */
+
+#define DC3_YUV_PITCH_UVP_MASK 0xFFFF0000
+#define DC3_YUV_PITCH_YBP_MASK 0x0000FFFF
+
+/* DC3_H_ACTIVE_TIMING BIT FIELDS */
+
+#define DC3_HAT_HT_MASK 0x0FF80000
+#define DC3_HAT_HA_MASK 0x00000FF8
+
+/* DC3_H_BLANK_TIMING BIT FIELDS */
+
+#define DC3_HBT_HBE_MASK 0x0FF80000
+#define DC3_HBT_HBS_MASK 0x00000FF8
+
+/* DC3_H_SYNC_TIMING BIT FIELDS */
+
+#define DC3_HST_HSE_MASK 0x0FF80000
+#define DC3_HST_HSS_MASK 0x00000FF8
+
+/* DC3_V_ACTIVE_TIMING BIT FIELDS */
+
+#define DC3_VAT_VT_MASK 0x07FF0000
+#define DC3_VAT_VA_MASK 0x000007FF
+
+/* DC3_V_BLANK_TIMING BIT FIELDS */
+
+#define DC3_VBT_VBE_MASK 0x07FF0000
+#define DC3_VBT_VBS_MASK 0x000007FF
+
+/* DC3_V_SYNC_TIMING BIT FIELDS */
+
+#define DC3_VST_VSE_MASK 0x07FF0000
+#define DC3_VST_VSS_MASK 0x000007FF
+
+/* DC3_LINE_CNT_STATUS BIT FIELDS */
+
+#define DC3_LNCNT_DNA 0x80000000
+#define DC3_LNCNT_VNA 0x40000000
+#define DC3_LNCNT_VSA 0x20000000
+#define DC3_LNCNT_VINT 0x10000000
+#define DC3_LNCNT_FLIP 0x08000000
+#define DC3_LNCNT_V_LINE_CNT 0x07FF0000
+#define DC3_LNCNT_VFLIP 0x00008000
+#define DC3_LNCNT_SIGC 0x00004000
+#define DC3_LNCNT_EVEN_FIELD 0x00002000
+#define DC3_LNCNT_SS_LINE_CMP 0x000007FF
+
+/* DC3_VID_DS_DELTA BIT FIELDS */
+
+#define DC3_DS_DELTA_MASK 0xFFFC0000
+#define DC3_601_VSYNC_SHIFT_MASK 0x00000FFF
+#define DC3_601_VSYNC_SHIFT_ENABLE 0x00008000
+
+/* DC3_DV_CTL BIT DEFINITIONS */
+
+#define DC3_DV_LINE_SIZE_MASK 0x00000C00
+#define DC3_DV_LINE_SIZE_1024 0x00000000
+#define DC3_DV_LINE_SIZE_2048 0x00000400
+#define DC3_DV_LINE_SIZE_4096 0x00000800
+#define DC3_DV_LINE_SIZE_8192 0x00000C00
+
+/* DC3_IRQ_FILT_CTL DEFINITIONS */
+
+#define DC3_IRQFILT_LB_MASK 0x80000200
+#define DC3_IRQFILT_LB_COEFF 0x00000000
+#define DC3_IRQFILT_SCALER_FILTER 0x00000200
+#define DC3_IRQFILT_SYNCHRONIZER 0x80000000
+#define DC3_IRQFILT_FLICKER_FILTER 0x80000200
+#define DC3_IRQFILT_LB_SEL_MASK 0x60000000
+#define DC3_IRQFILT_INTL_ADDR 0x10000000
+#define DC3_IRQFILT_LINE_MASK 0x07FF0000
+#define DC3_IRQFILT_ALPHA_FILT_EN 0x00004000
+#define DC3_IRQFILT_GFX_FILT_EN 0x00001000
+#define DC3_IRQFILT_INTL_EN 0x00000800
+#define DC3_IRQFILT_H_FILT_SEL 0x00000400
+#define DC3_IRQFILT_LB_ADDR 0x00000100
+
+/* DC3_VBI_EVEN_CTL DEFINITIONS */
+
+#define DC3_VBI_EVEN_ENABLE_CRC (1L << 31)
+#define DC3_VBI_EVEN_CTL_ENABLE_16 (1L << 30)
+#define DC3_VBI_EVEN_CTL_UPSCALE (1L << 29)
+#define DC3_VBI_ENABLE (1L << 28)
+#define DC3_VBI_EVEN_CTL_OFFSET_MASK 0x0FFFFFFF
+
+/* DC3_VBI_ODD_CTL DEFINITIONS */
+
+#define DC3_VBI_ODD_CTL_OFFSET_MASK 0x0FFFFFFF
+
+/* DC3_VBI_HOR BIT DEFINITIONS */
+
+#define DC3_VBI_HOR_END_SHIFT 16
+#define DC3_VBI_HOR_END_MASK 0x0FFF0000
+#define DC3_VBI_HOR_START_MASK 0x00000FFF
+
+/* DC3_VBI_LN_ODD BIT DEFINITIONS */
+
+#define DC3_VBI_ODD_ENABLE_SHIFT 2
+#define DC3_VBI_ODD_ENABLE_MASK 0x01FFFFFC
+#define DC3_VBI_ODD_LINE_SHIFT 25
+#define DC3_VBI_ODD_LINE_MASK 0xFE000000
+
+/* DC3_VBI_LN_EVEN BIT DEFINITIONS */
+
+#define DC3_VBI_EVEN_ENABLE_SHIFT 2
+#define DC3_VBI_EVEN_ENABLE_MASK 0x01FFFFFC
+#define DC3_VBI_EVEN_LINE_SHIFT 25
+#define DC3_VBI_EVEN_LINE_MASK 0xFE000000
+
+/* DC3_COLOR_KEY DEFINITIONS */
+
+#define DC3_CLR_KEY_DATA_MASK 0x00FFFFFF
+#define DC3_CLR_KEY_ENABLE 0x01000000
+
+/* DC3_IRQ DEFINITIONS */
+
+#define DC3_IRQ_MASK 0x00000001
+#define DC3_VSYNC_IRQ_MASK 0x00000002
+#define DC3_IRQ_STATUS 0x00010000
+#define DC3_VSYNC_IRQ_STATUS 0x00020000
+
+/* DC3_GENLK_CTL DEFINITIONS */
+
+#define DC3_GC_FLICKER_FILTER_NONE 0x00000000
+#define DC3_GC_FLICKER_FILTER_1_16 0x10000000
+#define DC3_GC_FLICKER_FILTER_1_8 0x20000000
+#define DC3_GC_FLICKER_FILTER_1_4 0x40000000
+#define DC3_GC_FLICKER_FILTER_5_16 0x50000000
+#define DC3_GC_FLICKER_FILTER_MASK 0xF0000000
+#define DC3_GC_ALPHA_FLICK_ENABLE 0x02000000
+#define DC3_GC_FLICKER_FILTER_ENABLE 0x01000000
+#define DC3_GC_VIP_VID_OK 0x00800000
+#define DC3_GC_GENLK_ACTIVE 0x00400000
+#define DC3_GC_SKEW_WAIT 0x00200000
+#define DC3_GC_VSYNC_WAIT 0x00100000
+#define DC3_GC_GENLOCK_TO_ENABLE 0x00080000
+#define DC3_GC_GENLOCK_ENABLE 0x00040000
+#define DC3_GC_GENLOCK_SKEW_MASK 0x0003FFFF
+
+/* VGA DEFINITIONS */
+
+#define DC3_SEQUENCER_INDEX 0x03C4
+#define DC3_SEQUENCER_DATA 0x03C5
+#define DC3_SEQUENCER_RESET 0x00
+#define DC3_SEQUENCER_CLK_MODE 0x01
+
+#define DC3_RESET_VGA_DISP_ENABLE 0x03
+#define DC3_CLK_MODE_SCREEN_OFF 0x20
+
+/* DOT CLOCK FREQUENCY STRUCTURE */
+/* Note that m, n and p refer to the register m, n and p */
+/* and not the m, n and p from the PLL equation. The PLL */
+/* equation adds 1 to each value. */
+
+typedef struct tagPLLFrequency
+{
+ unsigned long pll_value;
+ unsigned long frequency;
+
+} PLL_FREQUENCY;
+
+/* VG MSRS */
+
+#define DC3_SPARE_MSR 0x2011
+#define DC3_RAM_CTL 0x2012
+
+/* DC3_SPARE_MSR DEFINITIONS */
+
+#define DC3_SPARE_DISABLE_CFIFO_HGO 0x00000800
+#define DC3_SPARE_VFIFO_ARB_SELECT 0x00000400
+#define DC3_SPARE_WM_LPEN_OVRD 0x00000200
+#define DC3_SPARE_LOAD_WM_LPEN_MASK 0x00000100
+#define DC3_SPARE_DISABLE_INIT_VID_PRI 0x00000080
+#define DC3_SPARE_DISABLE_VFIFO_WM 0x00000040
+#define DC3_SPARE_DISABLE_CWD_CHECK 0x00000020
+#define DC3_SPARE_PIX8_PAN_FIX 0x00000010
+#define DC3_SPARE_FIRST_REQ_MASK 0x00000002
+
+/* VG DIAG DEFINITIONS */
+
+#define DC3_MBD_DIAG_EN0 0x00008000
+#define DC3_MBD_DIAG_EN1 0x80000000
+#define DC3_DIAG_DOT_CRTC_DP 0x00000082
+#define DC3_DIAG_DOT_CRTC_DP_HIGH 0x00820000
+#define DC3_DIAG_EVEN_FIELD 0x00002000
+
+/*----------------------------------------------------------------*/
+/* DISPLAY FILTER DEFINITIONS */
+/*----------------------------------------------------------------*/
+
+#define DF_VIDEO_CONFIG 0x00000000
+#define DF_DISPLAY_CONFIG 0x00000008
+#define DF_VIDEO_X_POS 0x00000010
+#define DF_VIDEO_Y_POS 0x00000018
+#define DF_VIDEO_SCALER 0x00000020
+#define DF_VIDEO_COLOR_KEY 0x00000028
+#define DF_VIDEO_COLOR_MASK 0x00000030
+#define DF_PALETTE_ADDRESS 0x00000038
+#define DF_PALETTE_DATA 0x00000040
+#define DF_SATURATION_LIMIT 0x00000048
+#define DF_VID_MISC 0x00000050
+#define DF_VIDEO_YSCALE 0x00000060
+#define DF_VIDEO_XSCALE 0x00000068
+#define DF_VID_CRC 0x00000088
+#define DF_VID_CRC32 0x00000090
+#define DF_VID_ALPHA_CONTROL 0x00000098
+#define DF_CURSOR_COLOR_KEY 0x000000A0
+#define DF_CURSOR_COLOR_MASK 0x000000A8
+#define DF_CURSOR_COLOR_1 0x000000B0
+#define DF_CURSOR_COLOR_2 0x000000B8
+#define DF_ALPHA_XPOS_1 0x000000C0
+#define DF_ALPHA_YPOS_1 0x000000C8
+#define DF_ALPHA_COLOR_1 0x000000D0
+#define DF_ALPHA_CONTROL_1 0x000000D8
+#define DF_ALPHA_XPOS_2 0x000000E0
+#define DF_ALPHA_YPOS_2 0x000000E8
+#define DF_ALPHA_COLOR_2 0x000000F0
+#define DF_ALPHA_CONTROL_2 0x000000F8
+#define DF_ALPHA_XPOS_3 0x00000100
+#define DF_ALPHA_YPOS_3 0x00000108
+#define DF_ALPHA_COLOR_3 0x00000110
+#define DF_ALPHA_CONTROL_3 0x00000118
+#define DF_VIDEO_REQUEST 0x00000120
+#define DF_ALPHA_WATCH 0x00000128
+#define DF_VIDEO_TEST_MODE 0x00000130
+#define DF_VID_YPOS_EVEN 0x00000138
+#define DF_VID_ALPHA_Y_EVEN_1 0x00000140
+#define DF_VID_ALPHA_Y_EVEN_2 0x00000148
+#define DF_VID_ALPHA_Y_EVEN_3 0x00000150
+#define DF_VIDEO_PANEL_TIM1 0x00000400
+#define DF_VIDEO_PANEL_TIM2 0x00000408
+#define DF_POWER_MANAGEMENT 0x00000410
+#define DF_DITHER_CONTROL 0x00000418
+#define DF_DITHER_ACCESS 0x00000448
+#define DF_DITHER_DATA 0x00000450
+#define DF_PANEL_CRC 0x00000458
+#define DF_PANEL_CRC32 0x00000468
+#define DF_COEFFICIENT_BASE 0x00001000
+
+/* DF_VIDEO_CONFIG BIT DEFINITIONS */
+
+#define DF_VCFG_VID_EN 0x00000001
+#define DF_VCFG_VID_INP_FORMAT 0x0000000C
+#define DF_VCFG_SC_BYP 0x00000020
+#define DF_VCFG_LINE_SIZE_LOWER_MASK 0x0000FF00
+#define DF_VCFG_INIT_READ_MASK 0x01FF0000
+#define DF_VCFG_LINE_SIZE_BIT8 0x08000000
+#define DF_VCFG_LINE_SIZE_BIT9 0x04000000
+#define DF_VCFG_4_2_0_MODE 0x10000000
+#define DF_VCFG_UYVY_FORMAT 0x00000000
+#define DF_VCFG_Y2YU_FORMAT 0x00000004
+#define DF_VCFG_YUYV_FORMAT 0x00000008
+#define DF_VCFG_YVYU_FORMAT 0x0000000C
+
+/* DF_DISPLAY_CONFIG BIT DEFINITIONS */
+
+#define DF_DCFG_DIS_EN 0x00000001
+#define DF_DCFG_HSYNC_EN 0x00000002
+#define DF_DCFG_VSYNC_EN 0x00000004
+#define DF_DCFG_DAC_BL_EN 0x00000008
+#define DF_DCFG_CRT_HSYNC_POL 0x00000100
+#define DF_DCFG_CRT_VSYNC_POL 0x00000200
+#define DF_DCFG_CRT_SYNC_SKW_MASK 0x0001C000
+#define DF_DCFG_CRT_SYNC_SKW_INIT 0x00010000
+#define DF_DCFG_PWR_SEQ_DLY_MASK 0x000E0000
+#define DF_DCFG_PWR_SEQ_DLY_INIT 0x00080000
+#define DF_DCFG_VG_CK 0x00100000
+#define DF_DCFG_GV_PAL_BYP 0x00200000
+#define DF_DAC_VREF 0x04000000
+
+/* DF_VID_MISC BIT DEFINITIONS */
+
+#define DF_GAMMA_BYPASS_BOTH 0x00000001
+#define DF_DAC_POWER_DOWN 0x00000400
+#define DF_ANALOG_POWER_DOWN 0x00000800
+#define DF_USER_IMPLICIT_SCALING 0x00001000
+
+/* DF_VID_ALPHA_CONTROL DEFINITIONS */
+
+#define DF_HD_VIDEO 0x00000040
+#define DF_YUV_CSC_EN 0x00000080
+#define DF_NO_CK_OUTSIDE_ALPHA 0x00000100
+#define DF_HD_GRAPHICS 0x00000200
+#define DF_CSC_VIDEO_YUV_TO_RGB 0x00000400
+#define DF_CSC_GRAPHICS_RGB_TO_YUV 0x00000800
+#define DF_CSC_VOP_RGB_TO_YUV 0x00001000
+#define DF_VIDEO_INPUT_IS_RGB 0x00002000
+#define DF_VID_ALPHA_EN 0x00004000
+#define DF_ALPHA_DRGB 0x00008000
+
+/* VIDEO CURSOR COLOR KEY DEFINITIONS */
+
+#define DF_CURSOR_COLOR_KEY_ENABLE 0x20000000
+
+/* ALPHA COLOR BIT DEFINITION */
+
+#define DF_ALPHA_COLOR_ENABLE 0x01000000
+
+/* ALPHA CONTROL BIT DEFINITIONS */
+
+#define DF_ACTRL_WIN_ENABLE 0x00010000
+#define DF_ACTRL_LOAD_ALPHA 0x00020000
+#define DF_ACTRL_PERPIXEL_EN 0x00040000
+
+/* DF_VIDEO_SCALER DEFINITIONS */
+
+#define DF_SCALE_128_PHASES 0x00002000
+#define DF_SCALE_DOUBLE_H_DOWNSCALE 0x00004000
+
+/* DEFAULT PANEL TIMINGS DEFINITIONS */
+
+#define DF_DEFAULT_TFT_PMTIM1 0x00000000
+#define DF_DEFAULT_XVGA_PMTIM1 0x00000000
+#define DF_DEFAULT_TFT_PMTIM2 0x08C00000
+#define DF_DEFAULT_XVGA_PMTIM2 0x08C10000
+#define DF_DEFAULT_TFT_PAD_SEL_LOW 0xDFFFFFFF
+#define DF_DEFAULT_TFT_PAD_SEL_HIGH 0x0000003F
+#define DF_DEFAULT_XVGA_PAD_SEL_LOW 0x00000000
+#define DF_DEFAULT_XVGA_PAD_SEL_HIGH 0x00000000
+#define DF_DEFAULT_DITHCTL 0x00000070
+#define DF_DEFAULT_TV_PAD_SEL_HIGH 0x000000BF
+#define DF_DEFAULT_TV_PAD_SEL_LOW 0xDFFFFFFF
+#define DF_INVERT_VOP_CLOCK 0x00000080
+
+/* DF_VIDEO_PANEL_TIM2 DEFINITIONS */
+
+#define DF_PMTIM2_TFT_PASSHTHROUGH 0x40000000
+
+/* DF_POWER_MANAGEMENT DEFINITIONS */
+
+#define DF_PM_PANEL_ON 0x01000000
+#define DF_PM_INVERT_SHFCLK 0x00002000
+
+/* DISPLAY FILTER MSRS */
+
+#define DF_MBD_MSR_DIAG_DF 0x2010
+#define DF_MSR_PAD_SEL 0x2011
+#define DF_DIAG_32BIT_CRC 0x80000000
+
+#define DF_OUTPUT_CRT 0x00000000
+#define DF_OUTPUT_PANEL 0x00000008
+#define DF_OUTPUT_VOP 0x00000030
+#define DF_OUTPUT_DRGB 0x00000038
+#define DF_SIMULTANEOUS_CRT_FP 0x00008000
+#define DF_CONFIG_OUTPUT_MASK 0x00000038
+
+/*----------------------------------------------------------------*/
+/* MSR DEFINITIONS */
+/*----------------------------------------------------------------*/
+
+/*----------------------------*/
+/* STATIC GEODELINK ADRESSES */
+/*----------------------------*/
+
+#define MSR_ADDRESS_GLIU0 0x10000000
+#define MSR_ADDRESS_GLIU1 0x40000000
+#define MSR_ADDRESS_GLIU2 0x51010000
+#define MSR_ADDRESS_5535MPCI 0x51000000
+#define MSR_ADDRESS_VAIL 0x00000000
+
+/*----------------------------*/
+/* UNIVERSAL DEVICE MSRS */
+/*----------------------------*/
+
+#define MSR_GEODELINK_CAP 0x2000
+#define MSR_GEODELINK_CONFIG 0x2001
+#define MSR_GEODELINK_SMI 0x2002
+#define MSR_GEODELINK_ERROR 0x2003
+#define MSR_GEODELINK_PM 0x2004
+#define MSR_GEODELINK_DIAG 0x2005
+
+/*----------------------------*/
+/* DEVICE CLASS CODES */
+/*----------------------------*/
+
+#define MSR_CLASS_CODE_GLIU 0x01
+#define MSR_CLASS_CODE_GLCP 0x02
+#define MSR_CLASS_CODE_MPCI 0x05
+#define MSR_CLASS_CODE_MC 0x20
+#define MSR_CLASS_CODE_GP 0x3D
+#define MSR_CLASS_CODE_VG 0x3E
+#define MSR_CLASS_CODE_DF 0x3F
+#define MSR_CLASS_CODE_FG 0xF0
+#define MSR_CLASS_CODE_VAIL 0x86
+#define MSR_CLASS_CODE_USB 0x42
+#define MSR_CLASS_CODE_USB2 0x43
+#define MSR_CLASS_CODE_ATAC 0x47
+#define MSR_CLASS_CODE_MDD 0xDF
+#define MSR_CLASS_CODE_ACC 0x33
+#define MSR_CLASS_CODE_AES 0x30
+#define MSR_CLASS_CODE_VIP 0x3C
+#define MSR_CLASS_CODE_REFLECTIVE 0xFFF
+#define MSR_CLASS_CODE_UNPOPULATED 0x7FF
+
+/*----------------------------*/
+/* GLIU MSR DEFINITIONS */
+/*----------------------------*/
+
+#define MSR_GLIU_CAP 0x0086
+#define MSR_GLIU_WHOAMI 0x008B
+
+#define NUM_PORTS_MASK 0x00380000
+#define NUM_PORTS_SHIFT 19
+#define WHOAMI_MASK 0x07
+
+/*----------------------------*/
+/* GLCP MSR DEFINITIONS */
+/*----------------------------*/
+
+#define GLCP_CLKOFF 0x0010
+#define GLCP_CLKACTIVE 0x0011
+#define GLCP_CLKDISABLE 0x0012
+#define GLCP_CLK4ACK 0x0013
+#define GLCP_SYS_RSTPLL 0x0014
+#define GLCP_DOTPLL 0x0015
+#define GLCP_DBGCLKCTL 0x0016
+#define GLCP_REVID 0x0017
+#define GLCP_RAW_DIAG 0x0028
+#define GLCP_SETM0CTL 0x0040
+#define GLCP_SETN0CTL 0x0048
+#define GLCP_CMPVAL0 0x0050
+#define GLCP_CMPMASK0 0x0051
+#define GLCP_REGA 0x0058
+#define GLCP_REGB 0x0059
+#define GLCP_REGAMASK 0x005A
+#define GLCP_REGAVAL 0x005B
+#define GLCP_REGBMASK 0x005C
+#define GLCP_REGBVAL 0x005D
+#define GLCP_FIFOCTL 0x005E
+#define GLCP_DIAGCTL 0x005F
+#define GLCP_H0CTL 0x0060
+#define GLCP_XSTATE 0x0066
+#define GLCP_YSTATE 0x0067
+#define GLCP_ACTION0 0x0068
+
+/* GLCP_DOTPLL DEFINITIONS */
+
+#define GLCP_DOTPLL_RESET 0x00000001
+#define GLCP_DOTPLL_BYPASS 0x00008000
+#define GLCP_DOTPLL_HALFPIX 0x01000000
+#define GLCP_DOTPLL_LOCK 0x02000000
+#define GLCP_DOTPLL_VIPCLK 0x00008000
+#define GLCP_DOTPLL_DIV4 0x00010000
+
+/* GLCP DIAG DEFINITIONS */
+
+#define GLCP_MBD_DIAG_SEL0 0x00000007
+#define GLCP_MBD_DIAG_EN0 0x00008000
+#define GLCP_MBD_DIAG_SEL1 0x00070000
+#define GLCP_MBD_DIAG_EN1 0x80000000
+
+/*--------------------------------*/
+/* DISPLAY FILTER MSR DEFINITIONS */
+/*--------------------------------*/
+
+/* DISPLAY FILTER MBD_MSR_DIAG DEFINITIONS */
+
+#define DF_MBD_DIAG_SEL0 0x00007FFF
+#define DF_MBD_DIAG_EN0 0x00008000
+#define DF_MBD_DIAG_SEL1 0x7FFF0000
+#define DF_MBD_DIAG_EN1 0x80000000
+
+/* DISPLAY FILTER MBD_MSR_CONFIG DEFINITIONS */
+
+#define DF_CONFIG_FMT_MASK 0x00000038
+#define DF_CONFIG_FMT_CRT 0x00000000
+#define DF_CONFIG_FMT_FP 0x00000008
+
+/*----------------------------------------------------------------*/
+/* PCI DEFINITIONS */
+/*----------------------------------------------------------------*/
+
+#define PCI_VENDOR_DEVICE_GEODEGX 0x0028100B
+#define PCI_VENDOR_DEVICE_GEODEGX_VIDEO 0x0030100B
+#define PCI_VENDOR_DEVICE_GEODELX 0x20801022
+#define PCI_VENDOR_DEVICE_GEODELX_VIDEO 0x20811022
+#define PCI_VENDOR_5535 0x002B100B
+#define PCI_VENDOR_5536 0x20901022
+
+/*----------------------------------------------------------------*/
+/* VIP DEFINITIONS */
+/*----------------------------------------------------------------*/
+
+#define VIP_CONTROL1 0x00000000
+#define VIP_CONTROL2 0x00000004
+#define VIP_STATUS 0x00000008
+#define VIP_INTERRUPT 0x0000000C
+#define VIP_CURRENT_TARGET 0x00000010
+#define VIP_MAX_ADDRESS 0x00000014
+#define VIP_TASKA_VID_EVEN_BASE 0x00000018
+#define VIP_TASKA_VID_ODD_BASE 0x0000001C
+#define VIP_TASKA_VBI_EVEN_BASE 0x00000020
+#define VIP_TASKA_VBI_ODD_BASE 0x00000024
+#define VIP_TASKA_VID_PITCH 0x00000028
+#define VIP_CONTROL3 0x0000002C
+#define VIP_TASKA_V_OFFSET 0x00000030
+#define VIP_TASKA_U_OFFSET 0x00000034
+#define VIP_TASKB_VID_EVEN_BASE 0x00000038
+#define VIP_601_HORZ_END 0x00000038
+#define VIP_TASKB_VID_ODD_BASE 0x0000003C
+#define VIP_601_HORZ_START 0x0000003C
+#define VIP_TASKB_VBI_EVEN_BASE 0x00000040
+#define VIP_601_VBI_END 0x00000040
+#define VIP_TASKB_VBI_ODD_BASE 0x00000044
+#define VIP_601_VBI_START 0x00000044
+#define VIP_TASKB_VID_PITCH 0x00000048
+#define VIP_601_EVEN_START_STOP 0x00000048
+#define VIP_TASKB_V_OFFSET 0x00000050
+#define VIP_ODD_FIELD_DETECT 0x00000050
+#define VIP_TASKB_U_OFFSET 0x00000054
+#define VIP_ANC_MSG1_BASE 0x00000058
+#define VIP_ANC_MSG2_BASE 0x0000005C
+#define VIP_ANC_MSG_SIZE 0x00000060
+#define VIP_PAGE_OFFSET 0x00000068
+#define VIP_VERTICAL_START_STOP 0x0000006C
+#define VIP_601_ODD_START_STOP 0x0000006C
+#define VIP_FIFO_ADDRESS 0x00000070
+#define VIP_FIFO_DATA 0x00000074
+#define VIP_VSYNC_ERR_COUNT 0x00000078
+#define VIP_TASKA_U_EVEN_OFFSET 0x0000007C
+#define VIP_TASKA_V_EVEN_OFFSET 0x00000080
+
+/* INDIVIDUAL REGISTER BIT DEFINITIONS */
+/* Multibit register subsets are expressed as a mask and shift. */
+/* Single bit values are represented as a mask. */
+
+/* VIP_CONTROL1 REGISTER DEFINITIONS */
+
+#define VIP_CONTROL1_DEFAULT_ANC_FF 2
+#define VIP_CONTROL1_ANC_FF_MASK 0xE0000000
+#define VIP_CONTROL1_ANC_FF_SHIFT 29
+
+#define VIP_CONTROL1_DEFAULT_VID_FF 2
+#define VIP_CONTROL1_VID_FF_MASK 0x1F000000
+#define VIP_CONTROL1_VID_FF_SHIFT 24
+
+#define VIP_CONTROL1_VDE_FF_MASK 0x00F00000
+#define VIP_CONTROL1_VDE_FF_SHIFT 20
+
+#define VIP_CONTROL1_NON_INTERLACED (1L << 19)
+#define VIP_CONTROL1_MSG_STRM_CTRL (1L << 18)
+#define VIP_CONTROL1_DISABLE_ZERO_DETECT (1L << 17)
+#define VIP_CONTROL1_DISABLE_DECIMATION (1L << 16)
+
+#define VIP_CONTROL1_CAPTURE_ENABLE_MASK 0x0000FF00
+#define VIP_CONTROL1_CAPTURE_ENABLE_SHIFT 8
+
+#define VIP_CONTROL1_RUNMODE_MASK 0x000000E0
+#define VIP_CONTROL1_RUNMODE_SHIFT 5
+
+#define VIP_CONTROL1_PLANAR (1L << 4)
+
+#define VIP_CONTROL1_MODE_MASK 0x0000000E
+#define VIP_CONTROL1_MODE_SHIFT 1
+
+#define VIP_CONTROL1_RESET 0x00000001
+
+/* VIP_CONTROL2 REGISTER DEFINITIONS */
+
+#define VIP_CONTROL2_INVERT_POLARITY (1L << 31)
+#define VIP_CONTROL2_ADD_ERROR_ENABLE (1L << 30)
+#define VIP_CONTROL2_REPEAT_ENABLE (1L << 29)
+#define VIP_CONTROL2_SWC_ENABLE (1L << 28)
+#define VIP_CONTROL2_ANC10 (1L << 27)
+#define VIP_CONTROL2_ANCPEN (1L << 26)
+#define VIP_CONTROL2_LOOPBACK_ENABLE (1L << 25)
+#define VIP_CONTROL2_FIFO_ACCESS (1L << 24)
+#define VIP_CONTROL2_VERTERROR_ENABLE (1L << 15)
+
+#define VIP_CONTROL2_PAGECNT_MASK 0x00E00000
+#define VIP_CONTROL2_PAGECNT_SHIFT 21
+
+#define VIP_CONTROL2_DEFAULT_ANCTH 5
+#define VIP_CONTROL2_ANCTH_MASK 0x001F0000
+#define VIP_CONTROL2_ANCTH_SHIFT 16
+
+#define VIP_CONTROL2_DEFAULT_VIDTH_420 19
+#define VIP_CONTROL2_DEFAULT_VIDTH_422 19
+#define VIP_CONTROL2_VIDTH_MASK 0x00007F00
+#define VIP_CONTROL2_VIDTH_SHIFT 8
+
+#define VIP_CONTROL2_SYNC2PIN_MASK 0x000000E0
+#define VIP_CONTROL2_SYNC2PIN_SHIFT 5
+
+#define VIP_CONTROL2_FIELD2VG_MASK 0x00000018
+#define VIP_CONTROL2_FIELD2VG_SHIFT 3
+
+#define VIP_CONTROL2_SYNC2VG_MASK 0x00000007
+#define VIP_CONTROL2_SYNC2VG_SHIFT 0
+
+/* VIP_CONTROL3 REGISTER DEFINITIONS */
+
+#define VIP_CONTROL3_PLANAR_DEINT 0x00000400
+#define VIP_CONTROL3_BASE_UPDATE 0x00000200
+#define VIP_CONTROL3_DISABLE_OVERFLOW 0x00000100
+#define VIP_CONTROL3_DECIMATE_EVEN 0x00000080
+#define VIP_CONTROL3_TASK_POLARITY 0x00000040
+#define VIP_CONTROL3_VSYNC_POLARITY 0x00000020
+#define VIP_CONTROL3_HSYNC_POLARITY 0x00000010
+#define VIP_CONTROL3_FIFO_RESET 0x00000001
+
+/* VIP_STATUS REGISTER DEFINITIONS */
+
+#define VIP_STATUS_ANC_COUNT_MASK 0xFF000000
+#define VIP_STATUS_ANC_COUNT_SHIFT 24
+
+#define VIP_STATUS_FIFO_ERROR 0x00700000
+#define VIP_STATUS_ERROR_SHIFT 20
+#define VIP_STATUS_DEC_COUNT (1L << 18)
+#define VIP_STATUS_SYNCOUT (1L << 17)
+#define VIP_STATUS_BASEREG_NOTUPDT (1L << 16)
+#define VIP_STATUS_MSGBUFF_ERR (1L << 14)
+#define VIP_STATUS_MSGBUFF2_FULL (1L << 13)
+#define VIP_STATUS_MSGBUFF1_FULL (1L << 12)
+#define VIP_STATUS_WRITES_COMPLETE (1L << 9)
+#define VIP_STATUS_FIFO_EMPTY (1L << 8)
+#define VIP_STATUS_FIELD (1L << 4)
+#define VIP_STATUS_VBLANK (1L << 3)
+
+#define VIP_STATUS_RUN_MASK 0x00000007
+#define VIP_STATUS_RUN_SHIFT 0
+
+/* VIP_CURRENT_TARGET REGISTER DEFINITIONS */
+
+#define VIP_CTARGET_TLINE_MASK 0xFFFF0000
+#define VIP_CTARGET_TLINE_SHIFT 16
+
+#define VIP_CTARGET_CLINE_MASK 0x0000FFFF
+#define VIP_CTARGET_CLINE_SHIFT 0
+
+/* VIP_MAX_ADDRESS REGISTER DEFINITIONS */
+
+#define VIP_MAXADDR_MASK 0xFFFFFFFF
+#define VIP_MAXADDR_SHIFT 0
+
+/* VIP BUFFER PITCH DEFINITIONS */
+
+#define VIP_TASK_PITCH_MASK 0x0000FFFF
+#define VIP_TASK_PITCH_SHIFT 0
+
+/* VERTICAL START/STOP */
+
+#define VIP_VSTART_VERTEND_MASK 0x0FFF0000
+#define VIP_VSTART_VERTEND_SHIFT 16
+
+#define VIP_VSTART_VERTSTART_MASK 0x00000FFF
+#define VIP_VSTART_VERTSTART_SHIFT 0
+
+/* VIP FIFO ADDRESS DEFINITIONS */
+
+#define VIP_FIFO_ADDRESS_MASK 0x000000FF
+#define VIP_FIFO_ADDRESS_SHIFT 0
+
+/* VIP VSYNC ERROR DEFINITIONS */
+
+#define VIP_VSYNC_ERR_WINDOW_MASK 0xFF000000
+#define VIP_VSYNC_ERR_WINDOW_SHIFT 24
+
+#define VIP_VSYNC_ERR_COUNT_MASK 0x00FFFFFF
+#define VIP_VSYNC_ERR_COUNT_SHIFT 0
+
+/*---------------------*/
+/* VIP MSR DEFINITIONS */
+/*---------------------*/
+
+/* CAPABILITIES */
+
+#define VIP_MSR_CAP_NSMI_MASK 0xF8000000
+#define VIP_MSR_CAP_NSMI_SHIFT 27
+#define VIP_MSR_CAP_NCLK_MASK 0x07000000
+#define VIP_MSR_CAP_NCLK_SHIFT 24
+#define VIP_MSR_CAP_DEVID_MASK 0x00FFFF00
+#define VIP_MSR_CAP_DEVID_SHIFT 8
+#define VIP_MSR_CAP_REVID_MASK 0x000000FF
+#define VIP_MSR_CAP_REVID_SHIFT 0
+
+/* MASTER CONFIG */
+
+#define VIP_MSR_MCR_SECOND_PRIORITY_MASK 0x00000700
+#define VIP_MSR_MCR_SECOND_PRIORITY_SHIFT 8
+#define VIP_MSR_MCR_PRIMARY_PRIORITY_MASK 0x00000070
+#define VIP_MSR_MCR_PRIMARY_PRIORITY_SHIFT 4
+#define VIP_MSR_MCR_PID_MASK 0x00000007
+#define VIP_MSR_MCR_PID_SHIFT 0
+
+/* VIP SMI */
+
+#define VIP_MSR_SMI_FIFO_OVERFLOW (1L << 29)
+#define VIP_MSR_SMI_FIFO_THRESHOLD (1L << 28)
+#define VIP_MSR_SMI_LONGLINE (1L << 27)
+#define VIP_MSR_SMI_VERTICAL_TIMING (1L << 26)
+#define VIP_MSR_SMI_ACTIVE_PIXELS (1L << 25)
+#define VIP_MSR_SMI_CLOCK_INPUT (1L << 24)
+#define VIP_MSR_SMI_ANC_CHECKSUM_PARITY (1L << 23)
+#define VIP_MSR_SMI_MSG_BUFFER_FULL (1L << 22)
+#define VIP_MSR_SMI_END_VBLANK (1L << 21)
+#define VIP_MSR_SMI_START_VBLANK (1L << 20)
+#define VIP_MSR_SMI_START_EVEN (1L << 19)
+#define VIP_MSR_SMI_START_ODD (1L << 18)
+#define VIP_MSR_SMI_LINE_MATCH_TARGET (1L << 17)
+#define VIP_MSR_SMI_GLINK (1L << 16)
+
+/* VIP ERROR */
+
+#define VIP_MSR_ERROR_ADDRESS_MASK (1L << 17)
+#define VIP_MSR_ERROR_ADDRESS_SHIFT 17
+#define VIP_MSR_ERROR_ADDRESS_ENABLE (1L << 1)
+#define VIP_MSR_ERROR_ADDRESS_EN_SHIFT 1
+#define VIP_MSR_ERROR_TYPE_MASK (1L << 16)
+#define VIP_MSR_ERROR_TYPE_SHIFT 16
+#define VIP_MSR_ERROR_TYPE_ENABLE 1
+#define VIP_MSR_ERROR_TYPE_EN_SHIFT 0
+
+/* VIP POWER */
+
+#define VIP_MSR_POWER_GLINK (1L << 0)
+#define VIP_MSR_POWER_CLOCK (1L << 2)
+
+/* VIP DIAG */
+
+#define VIP_MSR_DIAG_BIST_WMASK 0x00000003
+#define VIP_MSR_DIAG_BIST_RMASK 0x00000007
+#define VIP_MSR_DIAG_BIST_SHIFT 0
+
+#define VIP_MSR_DIAG_MSB_ENABLE (1L << 31)
+#define VIP_MSR_DIAG_SEL_UPPER_MASK 0x7FFF0000
+#define VIP_MSR_DIAG_SEL_UPPER_SHIFT 16
+#define VIP_MSR_DIAG_LSB_ENABLE (1L << 15)
+#define VIP_MSR_DIAG_SEL_LOWER_MASK 0x00007FFF
+#define VIP_MSR_DIAG_SEL_LOWER_SHIFT 0
+
+/*----------------------------------------------------------------*/
+/* VOP DEFINITIONS */
+/*----------------------------------------------------------------*/
+
+#define VOP_CONFIGURATION 0x00000800
+#define VOP_SIGNATURE 0x00000808
+
+/* VOP_CONFIGURATION BIT DEFINITIONS */
+
+#define VOP_CONFIG_SWAPVBI 0x01000000
+#define VOP_CONFIG_RGBMODE 0x00200000
+#define VOP_CONFIG_SIGVAL 0x00100000
+#define VOP_CONFIG_INVERT_DISPE 0x00080000
+#define VOP_CONFIG_INVERT_VSYNC 0x00040000
+#define VOP_CONFIG_INVERT_HSYNC 0x00020000
+#define VOP_CONFIG_SWAPUV 0x00010000
+#define VOP_CONFIG_VSYNC_MASK 0x0000C000
+#define VOP_CONFIG_DISABLE_DECIMATE 0x00002000
+#define VOP_CONFIG_ENABLE_601 0x00001000
+#define VOP_CONFIG_VBI 0x00000800
+#define VOP_CONFIG_TASK 0x00000200
+#define VOP_CONFIG_SIG_FREE_RUN 0x00000100
+#define VOP_CONFIG_ENABLE_SIGNATURE 0x00000080
+#define VOP_CONFIG_SC_COMPATIBLE 0x00000040
+#define VOP_CONFIG_422_COSITED 0x00000000
+#define VOP_CONFIG_422_INTERSPERSED 0x00000010
+#define VOP_CONFIG_422_ALTERNATING 0x00000020
+#define VOP_CONFIG_422_MASK 0x00000030
+#define VOP_CONFIG_EXTENDED_SAV 0x00000008
+#define VOP_CONFIG_VIP2_16BIT 0x00000004
+#define VOP_CONFIG_DISABLED 0x00000000
+#define VOP_CONFIG_VIP1_1 0x00000001
+#define VOP_CONFIG_VIP2_0 0x00000002
+#define VOP_CONFIG_CCIR656 0x00000003
+#define VOP_CONFIG_MODE_MASK 0x00000003
+
+
+#endif
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_rtns.h xf86-video-nsc-2.8.1/src/cim/cim_rtns.h
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_rtns.h 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_rtns.h 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,338 @@
+ /*
+ *
+ * Copyright (C) 2005 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *
+ *
+ *
+ *
+ *
+ * Cimarron function prototypes.
+ *
+ *
+ */
+
+#ifndef _cim_rtns_h
+#define _cim_rtns_h
+
+/* INCLUDE USER PARAMETER DEFINITIONS */
+
+#include "cim_parm.h"
+
+/* COMPILER OPTION FOR C++ PROGRAMS */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*--------------------------*/
+/* CIMARRON MEMORY POINTERS */
+/*--------------------------*/
+
+extern unsigned char *cim_gp_ptr;
+extern unsigned char *cim_fb_ptr;
+extern unsigned char *cim_cmd_base_ptr;
+extern unsigned char *cim_cmd_ptr;
+extern unsigned char *cim_vid_ptr;
+extern unsigned char *cim_vip_ptr;
+extern unsigned char *cim_vg_ptr;
+
+/*----------------------------------------*/
+/* INITIALIZATION ROUTINE DEFINITIONS */
+/*----------------------------------------*/
+
+int init_detect_cpu (unsigned long *cpu_revision, unsigned long *companion_revision);
+unsigned long init_read_pci (unsigned long address);
+int init_read_base_addresses (INIT_BASE_ADDRESSES *base_addresses);
+int init_read_cpu_frequency (unsigned long *cpu_frequency);
+
+/*----------------------------------------*/
+/* GRAPHICS PROCESSOR ROUTINE DEFINITIONS */
+/*----------------------------------------*/
+
+void gp_set_limit_on_buffer_lead (unsigned long lead);
+void gp_set_command_buffer_base (unsigned long address, unsigned long start,
+ unsigned long stop);
+void gp_set_frame_buffer_base (unsigned long address, unsigned long size);
+void gp_set_bpp (int bpp);
+void gp_declare_blt (unsigned long flags);
+void gp_declare_vector (unsigned long flags);
+void gp_write_parameters (void);
+void gp_set_raster_operation (unsigned char ROP);
+void gp_set_alpha_operation (int alpha_operation, int alpha_type, int channel,
+ int apply_alpha, unsigned char alpha);
+void gp_set_solid_pattern (unsigned long color);
+void gp_set_mono_pattern (unsigned long bgcolor, unsigned long fgcolor,
+ unsigned long data0, unsigned long data1, int transparent, int x, int y);
+void gp_set_pattern_origin (int x, int y);
+void gp_set_color_pattern (unsigned long *pattern, int format, int x, int y);
+void gp_set_mono_source (unsigned long bgcolor, unsigned long fgcolor,
+ int transparent);
+void gp_set_solid_source (unsigned long color);
+void gp_set_source_transparency (unsigned long color, unsigned long mask);
+void gp_program_lut (unsigned long *colors, int full_lut);
+void gp_set_vector_pattern (unsigned long pattern, unsigned long color, int length);
+void gp_set_strides (unsigned long dst_stride, unsigned long src_stride);
+void gp_set_source_format (int format);
+void gp_pattern_fill (unsigned long dstoffset, unsigned long width, unsigned long height);
+void gp_screen_to_screen_blt (unsigned long dstoffset, unsigned long srcoffset,
+ unsigned long width, unsigned long height, int flags);
+void gp_screen_to_screen_convert (unsigned long dstoffset, unsigned long srcoffset,
+ unsigned long width, unsigned long height, int nibble);
+void gp_color_bitmap_to_screen_blt (unsigned long dstoffset, unsigned long srcx,
+ unsigned long width, unsigned long height, unsigned char *data, long pitch);
+void gp_color_convert_blt (unsigned long dstoffset, unsigned long srcx,
+ unsigned long width, unsigned long height, unsigned char *data, long pitch);
+void gp_custom_convert_blt (unsigned long dstoffset, unsigned long srcx,
+ unsigned long width, unsigned long height, unsigned char *data, long pitch);
+void gp_rotate_blt (unsigned long dstoffset, unsigned long srcoffset,
+ unsigned long width, unsigned long height, int degrees);
+void gp_mono_bitmap_to_screen_blt (unsigned long dstoffset, unsigned long srcx,
+ unsigned long width, unsigned long height, unsigned char *data, long stride);
+void gp_text_blt (unsigned long dstoffset, unsigned long width,
+ unsigned long height, unsigned char *data);
+void gp_mono_expand_blt (unsigned long dstoffset, unsigned long srcoffset,
+ unsigned long srcx, unsigned long width, unsigned long height, int byte_packed);
+void gp_antialiased_text (unsigned long dstoffset, unsigned long srcx,
+ unsigned long width, unsigned long height, unsigned char *data, long stride,
+ int fourbpp);
+void gp_masked_blt (unsigned long dstoffset, unsigned long width,
+ unsigned long height, unsigned long mono_srcx, unsigned long color_srcx,
+ unsigned char *mono_mask, unsigned char *color_data, long mono_pitch,
+ long color_pitch);
+void gp_screen_to_screen_masked (unsigned long dstoffset, unsigned long srcoffset,
+ unsigned long width, unsigned long height, unsigned long mono_srcx,
+ unsigned char *mono_mask, long mono_pitch);
+void gp_bresenham_line (unsigned long dstoffset, unsigned short length,
+ unsigned short initerr, unsigned short axialerr, unsigned short diagerr,
+ unsigned long flags);
+void gp_line_from_endpoints (unsigned long dstoffset, unsigned long x0,
+ unsigned long y0, unsigned long x1, unsigned long y1, int inclusive);
+
+int gp_test_blt_pending (void);
+void gp_wait_blt_pending (void);
+void gp_wait_until_idle (void);
+int gp_test_blt_busy (void);
+void gp_save_state (GP_SAVE_RESTORE *gp_state);
+void gp_restore_state (GP_SAVE_RESTORE *gp_state);
+
+/*----------------------------------------*/
+/* VIDEO GENERATOR ROUTINE DEFINITIONS */
+/*----------------------------------------*/
+
+int vg_delay_milliseconds (unsigned long ms);
+int vg_set_display_mode (unsigned long src_width, unsigned long src_height,
+ unsigned long dst_width, unsigned long dst_height, int bpp, int hz,
+ unsigned long flags);
+int vg_set_panel_mode (unsigned long src_width, unsigned long src_height,
+ unsigned long dst_width, unsigned long dst_height,
+ unsigned long panel_width, unsigned long panel_height,
+ int bpp, unsigned long flags);
+int vg_set_tv_mode (unsigned long *src_width, unsigned long *src_height,
+ unsigned long encoder, unsigned long tvres, int bpp, unsigned long flags,
+ unsigned long h_overscan, unsigned long v_overscan);
+int vg_set_custom_mode (VG_DISPLAY_MODE *mode_params, int bpp);
+int vg_set_display_bpp (int bpp);
+int vg_get_display_mode_index (VG_QUERY_MODE *query);
+int vg_get_display_mode_information (unsigned int index, VG_DISPLAY_MODE *vg_mode);
+int vg_get_display_mode_count (void);
+int vg_get_current_display_mode (VG_DISPLAY_MODE *current_display, int *bpp);
+int vg_set_scaler_filter_coefficients (long h_taps[][5], long v_taps[][3]);
+int vg_configure_flicker_filter (unsigned long flicker_strength, int flicker_alpha);
+int vg_set_clock_frequency (unsigned long frequency, unsigned long pll_flags);
+int vg_set_border_color (unsigned long border_color);
+int vg_set_cursor_enable(int enable);
+int vg_set_mono_cursor_colors (unsigned long bkcolor, unsigned long fgcolor);
+int vg_set_cursor_position(long xpos, long ypos, VG_PANNING_COORDINATES *panning);
+int vg_set_mono_cursor_shape32(unsigned long memoffset, unsigned long *andmask,
+ unsigned long *xormask, unsigned long x_hotspot, unsigned long y_hotspot);
+int vg_set_mono_cursor_shape64(unsigned long memoffset, unsigned long *andmask,
+ unsigned long *xormask, unsigned long x_hotspot, unsigned long y_hotspot);
+int vg_set_color_cursor_shape (unsigned long memoffset, unsigned char *data,
+ unsigned long width, unsigned long height, long pitch,
+ unsigned long x_hotspot, unsigned long y_hotspot);
+int vg_pan_desktop (unsigned long x, unsigned long y, VG_PANNING_COORDINATES *panning);
+int vg_set_display_offset (unsigned long address);
+int vg_set_display_pitch (unsigned long pitch);
+int vg_set_display_palette_entry (unsigned long index, unsigned long palette);
+int vg_set_display_palette (unsigned long *palette);
+int vg_set_compression_enable (int enable);
+int vg_configure_compression (VG_COMPRESSION_DATA *comp_data);
+int vg_test_timing_active (void);
+int vg_test_vertical_active (void);
+int vg_wait_vertical_blank(void);
+int vg_test_even_field(void);
+int vg_configure_line_interrupt (VG_INTERRUPT_PARAMS *interrupt_info);
+unsigned long vg_test_and_clear_interrupt (void);
+unsigned long vg_test_flip_status (void);
+int vg_save_state (VG_SAVE_RESTORE *vg_state);
+int vg_restore_state (VG_SAVE_RESTORE *vg_state);
+
+/*----------------------------------------*/
+/* VIDEO GENERATOR READ ROUTINES */
+/*----------------------------------------*/
+
+unsigned long vg_read_graphics_crc (int crc_source);
+unsigned long vg_read_window_crc (int crc_source, unsigned long x, unsigned long y,
+ unsigned long width, unsigned long height);
+int vg_get_scaler_filter_coefficients (long h_taps[][5], long v_taps[][3]);
+int vg_get_flicker_filter_configuration (unsigned long *strength, int *flicker_alpha);
+unsigned long vg_get_display_pitch (void);
+unsigned long vg_get_frame_buffer_line_size (void);
+unsigned long vg_get_current_vline (void);
+unsigned long vg_get_display_offset (void);
+int vg_get_cursor_info (VG_CURSOR_DATA *cursor_data);
+int vg_get_display_palette_entry (unsigned long index, unsigned long *entry);
+unsigned long vg_get_border_color (void);
+int vg_get_display_palette (unsigned long *palette);
+int vg_get_compression_info (VG_COMPRESSION_DATA *comp_data);
+int vg_get_compression_enable (void);
+int vg_get_valid_bit (int line);
+
+/*----------------------------------------*/
+/* DISPLAY FILTER ROUTINE DEFINITIONS */
+/*----------------------------------------*/
+
+int df_set_crt_enable (int crt_output);
+int df_set_panel_enable (int panel_output);
+int df_configure_video_source (DF_VIDEO_SOURCE_PARAMS *video_source_odd,
+ DF_VIDEO_SOURCE_PARAMS *video_source_even);
+int df_set_video_offsets (int even, unsigned long y_offset,
+ unsigned long u_offset, unsigned long v_offset);
+int df_set_video_scale (unsigned long src_width, unsigned long src_height,
+ unsigned long dst_width, unsigned long dst_height, unsigned long flags);
+int df_set_video_position (DF_VIDEO_POSITION *video_window);
+int df_set_video_filter_coefficients (long taps[][4], int phase256);
+int df_set_video_enable (int enable, unsigned long flags);
+int df_set_video_color_key (unsigned long key, unsigned long mask, int graphics);
+int df_set_video_palette (unsigned long *palette);
+int df_set_video_palette_entry (unsigned long index, unsigned long palette);
+int df_configure_video_cursor_color_key (DF_VIDEO_CURSOR_PARAMS *cursor_color_key);
+int df_set_video_cursor_color_key_enable (int enable);
+int df_configure_alpha_window (int window, DF_ALPHA_REGION_PARAMS *alpha_data);
+int df_set_alpha_window_enable (int window, int enable);
+int df_set_no_ck_outside_alpha (int enable);
+int df_set_video_request (unsigned long x, unsigned long y);
+int df_set_output_color_space (int color_space);
+int df_set_output_path (int format);
+unsigned long df_test_video_flip_status (void);
+int df_save_state (DF_SAVE_RESTORE *gp_state);
+int df_restore_state (DF_SAVE_RESTORE *gp_state);
+
+/*----------------------------------------*/
+/* DISPLAY FILTER READ ROUTINES */
+/*----------------------------------------*/
+
+unsigned long df_read_composite_crc (int crc_source);
+unsigned long df_read_composite_window_crc (unsigned long x, unsigned long y,
+ unsigned long width, unsigned long height, int source);
+unsigned long df_read_panel_crc (void);
+int df_get_video_enable (int *enable, unsigned long *flags);
+int df_get_video_source_configuration (DF_VIDEO_SOURCE_PARAMS *video_source_odd,
+ DF_VIDEO_SOURCE_PARAMS *video_source_even);
+int df_get_video_position (DF_VIDEO_POSITION *video_window);
+int df_get_video_scale (unsigned long *x_scale, unsigned long *y_scale);
+int df_get_video_filter_coefficients (long taps[][4], int *phase256);
+int df_get_video_color_key (unsigned long *key, unsigned long *mask, int *graphics);
+int df_get_video_palette_entry(unsigned long index, unsigned long *palette);
+int df_get_video_palette (unsigned long *palette);
+int df_get_video_cursor_color_key (DF_VIDEO_CURSOR_PARAMS *cursor_color_key);
+int df_get_video_cursor_color_key_enable (void);
+int df_get_alpha_window_configuration (int window, DF_ALPHA_REGION_PARAMS *alpha_data);
+int df_get_alpha_window_enable (int window);
+int df_get_video_request (unsigned long *x, unsigned long *y);
+int df_get_output_color_space (int *color_space);
+
+/*----------------------------------------*/
+/* MSR ROUTINE DEFINITIONS */
+/*----------------------------------------*/
+
+int msr_init_table (void);
+int msr_create_geodelink_table (GEODELINK_NODE *gliu_nodes);
+int msr_create_device_list (GEODELINK_NODE *gliu_nodes, int max_devices);
+int msr_read64 (unsigned long device, unsigned long msr_register,
+ Q_WORD *msr_value);
+int msr_write64 (unsigned long device, unsigned long msr_register,
+ Q_WORD *msr_value);
+
+/*----------------------------------------*/
+/* VIP ROUTINE DEFINITIONS */
+/*----------------------------------------*/
+
+int vip_initialize (VIPSETMODEBUFFER *buffer);
+int vip_update_601_params (VIP_601PARAMS *buffer);
+int vip_terminate (void);
+int vip_configure_capture_buffers (int buffer_type, VIPINPUTBUFFER *buffer);
+int vip_toggle_video_offsets (int buffer_type, VIPINPUTBUFFER *buffer);
+int vip_max_address_enable (unsigned long max_address, int enable);
+int vip_set_interrupt_enable (unsigned long mask, int enable);
+unsigned long vip_get_interrupt_state (void);
+int vip_set_capture_state (unsigned long state);
+int vip_set_vsync_error (unsigned long vertical_count, unsigned long window_before,
+ unsigned long window_after, int enable);
+int vip_configure_fifo (unsigned long fifo_type, unsigned long fifo_size);
+int vip_set_loopback_enable (int bEnable);
+int vip_configure_genlock (VIPGENLOCKBUFFER *buffer);
+int vip_set_genlock_enable (int bEnable);
+int vip_configure_pages (int page_count, unsigned long page_offset);
+int vip_set_interrupt_line (int line);
+int vip_reset (void);
+int vip_set_subwindow_enable (VIPSUBWINDOWBUFFER *buffer);
+int vip_reset_interrupt_state (unsigned long interrupt_mask);
+
+int vip_save_state(VIPSTATEBUFFER *save_buffer);
+int vip_restore_state(VIPSTATEBUFFER *restore_buffer);
+int vip_set_power_characteristics (VIPPOWERBUFFER *buffer);
+int vip_set_priority_characteristics (VIPPRIORITYBUFFER *buffer);
+int vip_set_debug_characteristics (VIPDEBUGBUFFER *buffer);
+int vip_test_genlock_active (void);
+int vip_test_signal_status (void);
+unsigned long vip_get_current_field (void);
+
+/*----------------------------------------*/
+/* VIP READ ROUTINES */
+/*----------------------------------------*/
+
+int vip_get_current_mode (VIPSETMODEBUFFER *buffer);
+int vip_get_601_configuration (VIP_601PARAMS *buffer);
+int vip_get_buffer_configuration (int buffer_type, VIPINPUTBUFFER *buffer);
+int vip_get_genlock_configuration (VIPGENLOCKBUFFER *buffer);
+int vip_get_genlock_enable (void);
+int vip_is_buffer_update_latched (void);
+unsigned long vip_get_capture_state (void);
+unsigned long vip_get_current_line (void);
+unsigned long vip_read_fifo (unsigned long fifo_address);
+int vip_write_fifo (unsigned long fifo_address, unsigned long fifo_data);
+int vip_enable_fifo_access (int enable);
+int vip_get_capability_characteristics (VIPCAPABILITIESBUFFER *buffer);
+int vip_get_power_characteristics (VIPPOWERBUFFER *buffer);
+int vip_get_priority_characteristics (VIPPRIORITYBUFFER *buffer);
+
+/*----------------------------------------*/
+/* VOP ROUTINE DEFINITIONS */
+/*----------------------------------------*/
+
+int vop_set_vbi_window (VOPVBIWINDOWBUFFER *buffer);
+int vop_enable_vbi_output (int enable);
+int vop_set_configuration (VOPCONFIGURATIONBUFFER *config);
+int vop_save_state(VOPSTATEBUFFER *save_buffer);
+int vop_restore_state(VOPSTATEBUFFER *save_buffer);
+
+/*----------------------------------------*/
+/* VOP READ ROUTINES */
+/*----------------------------------------*/
+
+int vop_get_current_mode (VOPCONFIGURATIONBUFFER *config);
+int vop_get_vbi_configuration (VOPVBIWINDOWBUFFER *buffer);
+int vop_get_vbi_enable (void);
+unsigned long vop_get_crc (void);
+unsigned long vop_read_vbi_crc(void);
+
+/* CLOSE BRACKET FOR C++ COMPLILATION */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_version.h xf86-video-nsc-2.8.1/src/cim/cim_version.h
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_version.h 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_version.h 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,15 @@
+ /*
+ *
+ * Copyright (C) 2005 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *
+ *
+ *
+ *
+ *
+ * Cimarron Version information
+ *
+ *
+ */
+
+#define CIMARRON_REVISION 30103
\ No newline at end of file
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_vg.c xf86-video-nsc-2.8.1/src/cim/cim_vg.c
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_vg.c 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_vg.c 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,3599 @@
+ /*
+ *
+ * Copyright (C) 2005 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *
+ *
+ *
+ *
+ *
+ * Cimarron display controller routines. These routines program the display
+ * mode and configure the hardware cursor and video buffers.
+ *
+ *
+ */
+
+/*---------------------*/
+/* CIMARRON VG GLOBALS */
+/*---------------------*/
+
+CIMARRON_STATIC unsigned long vg3_x_hotspot = 0;
+CIMARRON_STATIC unsigned long vg3_y_hotspot = 0;
+CIMARRON_STATIC unsigned long vg3_cursor_offset = 0;
+CIMARRON_STATIC unsigned long vg3_mode_width = 0;
+CIMARRON_STATIC unsigned long vg3_mode_height = 0;
+CIMARRON_STATIC unsigned long vg3_panel_width = 0;
+CIMARRON_STATIC unsigned long vg3_panel_height = 0;
+CIMARRON_STATIC unsigned long vg3_delta_x = 0;
+CIMARRON_STATIC unsigned long vg3_delta_y = 0;
+CIMARRON_STATIC unsigned long vg3_bpp = 0;
+
+CIMARRON_STATIC unsigned long vg3_color_cursor = 0;
+CIMARRON_STATIC unsigned long vg3_panel_enable = 0;
+
+/*---------------------------------------------------------------------------
+ * vg_delay_milliseconds
+ *
+ * This routine delays for a number of milliseconds based on a crude
+ * delay loop.
+ *---------------------------------------------------------------------------*/
+
+int vg_delay_milliseconds (unsigned long ms)
+{
+ /* ASSUME 500 MHZ 20 CLOCKS PER READ */
+
+ unsigned long loop = ms * 25000;
+ while (loop-- > 0)
+ {
+ READ_REG32 (DC3_UNLOCK);
+ }
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_display_mode
+ *
+ * This routine sets a CRT display mode using predefined Cimarron timings. The
+ * source width and height are specified to allow scaling.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_display_mode (unsigned long src_width, unsigned long src_height,
+ unsigned long dst_width, unsigned long dst_height, int bpp, int hz,
+ unsigned long flags)
+{
+ VG_QUERY_MODE crt_query;
+ VG_DISPLAY_MODE crt_mode;
+ int mode;
+
+ crt_query.active_width = dst_width;
+ crt_query.active_height = dst_height;
+ crt_query.bpp = bpp;
+ crt_query.hz = hz;
+ crt_query.query_flags = VG_QUERYFLAG_ACTIVEWIDTH |
+ VG_QUERYFLAG_ACTIVEHEIGHT |
+ VG_QUERYFLAG_BPP |
+ VG_QUERYFLAG_REFRESH;
+
+ mode = vg_get_display_mode_index (&crt_query);
+ if (mode >= 0)
+ {
+ crt_mode = CimarronDisplayModes[mode];
+ crt_mode.src_width = src_width;
+ crt_mode.src_height = src_height;
+
+ /* ADD USER-REQUESTED FLAGS */
+
+ crt_mode.flags |= (flags & VG_MODEFLAG_VALIDUSERFLAGS);
+
+ if (flags & VG_MODEFLAG_OVERRIDE_BAND)
+ {
+ crt_mode.flags &= ~VG_MODEFLAG_BANDWIDTHMASK;
+ crt_mode.flags |= (flags & VG_MODEFLAG_BANDWIDTHMASK);
+ }
+ if (flags & VG_MODEFLAG_INT_OVERRIDE)
+ {
+ crt_mode.flags &= ~VG_MODEFLAG_INT_MASK;
+ crt_mode.flags |= (flags & VG_MODEFLAG_INT_MASK);
+ }
+
+ return vg_set_custom_mode (&crt_mode, bpp);
+ }
+ return CIM_STATUS_ERROR;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_panel_mode
+ *
+ * This routine sets a panel mode using predefined Cimarron fixed timings. The
+ * source width and height specify the width and height of the data in the frame
+ * buffer. The destination width and height specify the width and height of
+ * the active data to be displayed. The panel width and height specify the
+ * dimensions of the panel. This interface allows the user to scale or center
+ * graphics data or both. To perform scaling, the src width or height should
+ * be different than the destination width or height. To perform centering or
+ * panning, the destination width and height should be different than the panel
+ * resolution.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_panel_mode (unsigned long src_width, unsigned long src_height,
+ unsigned long dst_width, unsigned long dst_height,
+ unsigned long panel_width, unsigned long panel_height,
+ int bpp, unsigned long flags)
+{
+ unsigned long sync_width;
+ unsigned long sync_offset;
+ VG_QUERY_MODE panel_query;
+ VG_DISPLAY_MODE panel_mode;
+ int mode;
+
+ /* SEARCH CIMARRON'S TABLE OF PREDEFINED PANEL MODES */
+ /* If the destination resolution is larger than the panel resolution, */
+ /* panning will be performed. However, the timings for a panned mode */
+ /* are identical to the timings without panning. To save space in the */
+ /* mode tables, there are no additional table entries for modes with */
+ /* panning. Instead, we read the timings for a mode without panning */
+ /* and override the structure entries that specify the width and */
+ /* height of the mode. We perform a similar procedure for centered */
+ /* modes, except that certain timing parameters are dynamically */
+ /* calculated. */
+
+ panel_query.active_width = panel_width;
+ panel_query.active_height = panel_height;
+ panel_query.panel_width = panel_width;
+ panel_query.panel_height = panel_height;
+ panel_query.bpp = bpp;
+ panel_query.query_flags = VG_QUERYFLAG_ACTIVEWIDTH |
+ VG_QUERYFLAG_ACTIVEHEIGHT |
+ VG_QUERYFLAG_PANELWIDTH |
+ VG_QUERYFLAG_PANELHEIGHT |
+ VG_QUERYFLAG_PANEL |
+ VG_QUERYFLAG_BPP;
+
+ mode = vg_get_display_mode_index (&panel_query);
+
+ /* COPY THE DATA FROM THE MODE TABLE TO A TEMPORARY STRUCTURE */
+
+ if (mode >= 0)
+ {
+ panel_mode = CimarronDisplayModes[mode];
+ panel_mode.mode_width = dst_width;
+ panel_mode.mode_height = dst_height;
+ panel_mode.src_width = src_width;
+ panel_mode.src_height = src_height;
+
+ /* ADD USER-REQUESTED FLAGS */
+
+ panel_mode.flags |= (flags & VG_MODEFLAG_VALIDUSERFLAGS);
+
+ if (flags & VG_MODEFLAG_OVERRIDE_BAND)
+ {
+ panel_mode.flags &= ~VG_MODEFLAG_BANDWIDTHMASK;
+ panel_mode.flags |= (flags & VG_MODEFLAG_BANDWIDTHMASK);
+ }
+ if (flags & VG_MODEFLAG_INT_OVERRIDE)
+ {
+ panel_mode.flags &= ~VG_MODEFLAG_INT_MASK;
+ panel_mode.flags |= (flags & VG_MODEFLAG_INT_MASK);
+ }
+
+ /* DYNAMICALLY CALCULATE CENTERED TIMINGS */
+ /* For centered timings the blank start and blank end are set to */
+ /* half the difference between the mode dimension and the panel */
+ /* dimension. The sync pulse preserves the width and offset from */
+ /* blanking whenever possible. */
+
+ if (dst_width < panel_width)
+ {
+ sync_width = panel_mode.hsyncend - panel_mode.hsyncstart;
+ sync_offset = panel_mode.hsyncstart - panel_mode.hblankstart;
+
+ panel_mode.hactive = dst_width;
+ panel_mode.hblankstart = panel_mode.hactive + ((panel_width - dst_width) >> 1);
+ panel_mode.hblankend = panel_mode.htotal - ((panel_width - dst_width) >> 1);
+ panel_mode.hsyncstart = panel_mode.hblankstart + sync_offset;
+ panel_mode.hsyncend = panel_mode.hsyncstart + sync_width;
+
+ panel_mode.flags |= VG_MODEFLAG_CENTERED;
+ }
+ if (dst_height < panel_height)
+ {
+ sync_width = panel_mode.vsyncend - panel_mode.vsyncstart;
+ sync_offset = panel_mode.vsyncstart - panel_mode.vblankstart;
+
+ panel_mode.vactive = dst_height;
+ panel_mode.vblankstart = panel_mode.vactive + ((panel_height - dst_height) >> 1);
+ panel_mode.vblankend = panel_mode.vtotal - ((panel_height - dst_height) >> 1);
+ panel_mode.vsyncstart = panel_mode.vblankstart + sync_offset;
+ panel_mode.vsyncend = panel_mode.vsyncstart + sync_width;
+
+ panel_mode.flags |= VG_MODEFLAG_CENTERED;
+ }
+ return vg_set_custom_mode (&panel_mode, bpp);
+ }
+ return CIM_STATUS_ERROR;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_tv_mode
+ *
+ * This routine sets a TV display mode using predefined Cimarron timings. The
+ * source width and height are specified to allow scaling.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_tv_mode (unsigned long *src_width, unsigned long *src_height,
+ unsigned long encoder, unsigned long tvres, int bpp, unsigned long flags,
+ unsigned long h_overscan, unsigned long v_overscan)
+{
+ unsigned long sync_width;
+ unsigned long sync_offset;
+ VG_QUERY_MODE tv_query;
+ VG_DISPLAY_MODE tv_mode;
+ int mode;
+
+ if (!src_width || !src_height)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ tv_query.bpp = bpp;
+ tv_query.encoder = encoder;
+ tv_query.tvmode = tvres;
+ tv_query.query_flags = VG_QUERYFLAG_BPP |
+ VG_QUERYFLAG_TVOUT |
+ VG_QUERYFLAG_ENCODER |
+ VG_QUERYFLAG_TVMODE;
+
+ mode = vg_get_display_mode_index (&tv_query);
+ if (mode >= 0)
+ {
+ /* RETRIEVE THE UNSCALED RESOLUTION */
+ /* As we are indexing here simply by a mode and encoder, the actual */
+ /* timings may vary. A 0 value for source or height will thus query the */
+ /* unscaled resolution. */
+
+ if (!(*src_width) || !(*src_height))
+ {
+ *src_width = CimarronDisplayModes[mode].hactive - (h_overscan << 1);
+ *src_height = CimarronDisplayModes[mode].vactive;
+
+ if (CimarronDisplayModes[mode].flags & VG_MODEFLAG_INTERLACED)
+ {
+ if (((flags & VG_MODEFLAG_INT_OVERRIDE) &&
+ (flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_LINEDOUBLE) ||
+ (!(flags & VG_MODEFLAG_INT_OVERRIDE) &&
+ (CimarronDisplayModes[mode].flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_LINEDOUBLE))
+ {
+ if (CimarronDisplayModes[mode].vactive_even > CimarronDisplayModes[mode].vactive)
+ *src_height = CimarronDisplayModes[mode].vactive_even;
+
+ /* ONLY 1/2 THE OVERSCAN FOR LINE DOUBLED MODES */
+
+ *src_height -= v_overscan;
+ }
+ else
+ {
+ *src_height += CimarronDisplayModes[mode].vactive_even;
+ *src_height -= v_overscan << 1;
+ }
+ }
+ else
+ {
+ *src_height -= v_overscan << 1;
+ }
+
+ return CIM_STATUS_OK;
+ }
+
+ tv_mode = CimarronDisplayModes[mode];
+ tv_mode.src_width = *src_width;
+ tv_mode.src_height = *src_height;
+
+ /* ADD USER-REQUESTED FLAGS */
+
+ tv_mode.flags |= (flags & VG_MODEFLAG_VALIDUSERFLAGS);
+
+ if (flags & VG_MODEFLAG_OVERRIDE_BAND)
+ {
+ tv_mode.flags &= ~VG_MODEFLAG_BANDWIDTHMASK;
+ tv_mode.flags |= (flags & VG_MODEFLAG_BANDWIDTHMASK);
+ }
+ if (flags & VG_MODEFLAG_INT_OVERRIDE)
+ {
+ tv_mode.flags &= ~VG_MODEFLAG_INT_MASK;
+ tv_mode.flags |= (flags & VG_MODEFLAG_INT_MASK);
+ }
+
+ /* ADJUST FOR OVERSCAN */
+
+ if (h_overscan)
+ {
+ sync_width = tv_mode.hsyncend - tv_mode.hsyncstart;
+ sync_offset = tv_mode.hsyncstart - tv_mode.hblankstart;
+
+ tv_mode.hactive -= h_overscan << 1;
+ tv_mode.hblankstart = tv_mode.hactive + h_overscan;
+ tv_mode.hblankend = tv_mode.htotal - h_overscan;
+ tv_mode.hsyncstart = tv_mode.hblankstart + sync_offset;
+ tv_mode.hsyncend = tv_mode.hsyncstart + sync_width;
+
+ tv_mode.flags |= VG_MODEFLAG_CENTERED;
+ }
+ if (v_overscan)
+ {
+ sync_width = tv_mode.vsyncend - tv_mode.vsyncstart;
+ sync_offset = tv_mode.vsyncstart - tv_mode.vblankstart;
+
+ if (tv_mode.flags & VG_MODEFLAG_INTERLACED)
+ {
+ tv_mode.vactive -= v_overscan;
+ tv_mode.vblankstart = tv_mode.vactive + (v_overscan >> 1);
+ tv_mode.vblankend = tv_mode.vtotal - (v_overscan >> 1);
+ tv_mode.vsyncstart = tv_mode.vblankstart + sync_offset;
+ tv_mode.vsyncend = tv_mode.vsyncstart + sync_width;
+
+ sync_width = tv_mode.vsyncend_even - tv_mode.vsyncstart_even;
+ sync_offset = tv_mode.vsyncstart_even - tv_mode.vblankstart_even;
+
+ tv_mode.vactive_even -= v_overscan;
+ tv_mode.vblankstart_even = tv_mode.vactive_even + (v_overscan >> 1);
+ tv_mode.vblankend_even = tv_mode.vtotal_even - (v_overscan >> 1);
+ tv_mode.vsyncstart_even = tv_mode.vblankstart_even + sync_offset;
+ tv_mode.vsyncend_even = tv_mode.vsyncstart_even + sync_width;
+ }
+ else
+ {
+ tv_mode.vactive -= v_overscan << 1;
+ tv_mode.vblankstart = tv_mode.vactive + v_overscan;
+ tv_mode.vblankend = tv_mode.vtotal - v_overscan;
+ tv_mode.vsyncstart = tv_mode.vblankstart + sync_offset;
+ tv_mode.vsyncend = tv_mode.vsyncstart + sync_width;
+ }
+
+ tv_mode.flags |= VG_MODEFLAG_CENTERED;
+ }
+
+ /* TV MODES WILL NEVER ALLOW PANNING */
+
+ tv_mode.panel_width = tv_mode.hactive;
+ tv_mode.panel_height = tv_mode.vactive;
+ tv_mode.mode_width = tv_mode.hactive;
+ tv_mode.mode_height = tv_mode.vactive;
+
+ return vg_set_custom_mode (&tv_mode, bpp);
+ }
+ return CIM_STATUS_ERROR;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_custom_mode
+ *
+ * This routine sets a display mode. The API is structured such that this routine
+ * can be called from four sources:
+ * - vg_set_display_mode
+ * - vg_set_panel_mode
+ * - vg_set_tv_mode
+ * - directly by the user for a custom mode.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_custom_mode (VG_DISPLAY_MODE *mode_params, int bpp)
+{
+ unsigned long config, misc, temp;
+ unsigned long irq_ctl, genlk_ctl;
+ unsigned long unlock, flags;
+ unsigned long acfg, gcfg, dcfg;
+ unsigned long size, line_size, pitch;
+ unsigned long bpp_mask, dv_size;
+ unsigned long hscale, vscale, starting_width;
+ unsigned long starting_height, output_height;
+ Q_WORD msr_value;
+
+ /* DETERMINE DIMENSIONS FOR SCALING */
+ /* Scaling is performed before flicker filtering and interlacing */
+
+ output_height = mode_params->vactive;
+
+ if (mode_params->flags & VG_MODEFLAG_INTERLACED)
+ {
+ /* EVEN AND ODD FIELDS ARE SEPARATE */
+ /* The composite image height is the sum of the height of both fields */
+
+ if ((mode_params->flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_FLICKER ||
+ (mode_params->flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_ADDRESS)
+ {
+ output_height += mode_params->vactive_even;
+ }
+
+ /* LINE DOUBLING */
+ /* The composite image height is the greater of the two field heights. */
+
+ else if (mode_params->vactive_even > output_height)
+ output_height = mode_params->vactive_even;
+ }
+
+ /* CHECK FOR VALID SCALING FACTOR */
+ /* GeodeLX supports only 2:1 vertical downscale (before interlacing) and */
+ /* 2:1 horizontal downscale. The source width when scaling must be */
+ /* less than or equal to 1024 pixels. The destination can be any size, */
+ /* except when flicker filtering is enabled. */
+
+ irq_ctl = 0;
+ if (mode_params->flags & VG_MODEFLAG_PANELOUT)
+ {
+ if (mode_params->src_width != mode_params->mode_width)
+ {
+ starting_width = (mode_params->hactive * mode_params->src_width) / mode_params->mode_width;
+ hscale = (mode_params->src_width << 14) / (mode_params->mode_width - 1);
+ irq_ctl |= (DC3_IRQFILT_ALPHA_FILT_EN | DC3_IRQFILT_GFX_FILT_EN);
+ }
+ else
+ {
+ starting_width = mode_params->hactive;
+ hscale = 0x4000;
+ }
+ if (mode_params->src_height != mode_params->mode_height)
+ {
+ starting_height = (output_height * mode_params->src_height) / mode_params->mode_height;
+ vscale = (mode_params->src_height << 14) / (mode_params->mode_height - 1);
+ irq_ctl |= (DC3_IRQFILT_ALPHA_FILT_EN | DC3_IRQFILT_GFX_FILT_EN);
+ }
+ else
+ {
+ starting_height = output_height;
+ vscale = 0x4000;
+ }
+ }
+ else
+ {
+ starting_width = mode_params->src_width;
+ starting_height = mode_params->src_height;
+ if (mode_params->src_width != mode_params->hactive)
+ {
+ hscale = (mode_params->src_width << 14) / (mode_params->hactive - 1);
+ irq_ctl |= (DC3_IRQFILT_ALPHA_FILT_EN | DC3_IRQFILT_GFX_FILT_EN);
+ }
+ else
+ {
+ hscale = 0x4000;
+ }
+ if (mode_params->src_height != output_height)
+ {
+ vscale = (mode_params->src_height << 14) / (output_height - 1);
+ irq_ctl |= (DC3_IRQFILT_ALPHA_FILT_EN | DC3_IRQFILT_GFX_FILT_EN);
+ }
+ else
+ {
+ vscale = 0x4000;
+ }
+ }
+
+ starting_width = (starting_width + 7) & 0xFFFF8;
+
+ if (mode_params->hactive < (starting_width >> 1) ||
+ output_height < (starting_height >> 1) ||
+ (irq_ctl && (starting_width > 1024)))
+ {
+ return CIM_STATUS_INVALIDSCALE;
+ }
+
+ /* VERIFY INTERLACED SCALING */
+ /* The output width must be less than or equal to 1024 pixels when the */
+ /* flicker filter is enabled. Also, scaling should be disabled when */
+ /* the interlacing mode is set to interlaced addressing. */
+
+ if (mode_params->flags & VG_MODEFLAG_INTERLACED)
+ {
+ if ((((mode_params->flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_FLICKER) &&
+ (mode_params->hactive > 1024)) ||
+ (((mode_params->flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_ADDRESS) && irq_ctl))
+ {
+ return CIM_STATUS_INVALIDSCALE;
+ }
+ }
+
+ /* CHECK FOR VALID BPP */
+
+ switch (bpp)
+ {
+ case 8: bpp_mask = DC3_DCFG_DISP_MODE_8BPP; break;
+ case 24: bpp_mask = DC3_DCFG_DISP_MODE_24BPP; break;
+ case 32: bpp_mask = DC3_DCFG_DISP_MODE_32BPP; break;
+ case 12: bpp_mask = DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_12BPP; break;
+ case 15: bpp_mask = DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_15BPP; break;
+ case 16: bpp_mask = DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_16BPP; break;
+ default: return CIM_STATUS_INVALIDPARAMS;
+ }
+
+ vg3_bpp = bpp;
+
+ /* CLEAR PANNING OFFSETS */
+
+ vg3_delta_x = 0;
+ vg3_delta_y = 0;
+
+ /* SAVE PANEL PARAMETERS */
+
+ if (mode_params->flags & VG_MODEFLAG_PANELOUT)
+ {
+ vg3_panel_enable = 1;
+ vg3_panel_width = mode_params->panel_width;
+ vg3_panel_height = mode_params->panel_height;
+ vg3_mode_width = mode_params->mode_width;
+ vg3_mode_height = mode_params->mode_height;
+
+ /* INVERT THE SHIFT CLOCK IF REQUESTED */
+ /* Note that we avoid writing the power management register if */
+ /* we can help it. */
+
+ temp = READ_VID32 (DF_POWER_MANAGEMENT);
+ if ((mode_params->flags & VG_MODEFLAG_INVERT_SHFCLK) &&
+ !(temp & DF_PM_INVERT_SHFCLK))
+ {
+ WRITE_VID32 (DF_POWER_MANAGEMENT, (temp | DF_PM_INVERT_SHFCLK));
+ }
+ else if (!(mode_params->flags & VG_MODEFLAG_INVERT_SHFCLK) &&
+ (temp & DF_PM_INVERT_SHFCLK))
+ {
+ WRITE_VID32 (DF_POWER_MANAGEMENT, (temp & ~DF_PM_INVERT_SHFCLK));
+ }
+
+ /* SET PANEL TIMING VALUES */
+
+ if (!(mode_params->flags & VG_MODEFLAG_NOPANELTIMINGS))
+ {
+ unsigned long pmtim1, pmtim2, dith_ctl;
+
+ if (mode_params->flags & VG_MODEFLAG_XVGA_TFT)
+ {
+ pmtim1 = DF_DEFAULT_XVGA_PMTIM1;
+ pmtim2 = DF_DEFAULT_XVGA_PMTIM2;
+ dith_ctl = DF_DEFAULT_DITHCTL;
+ msr_value.low = DF_DEFAULT_XVGA_PAD_SEL_LOW;
+ msr_value.high = DF_DEFAULT_XVGA_PAD_SEL_HIGH;
+ }
+ else if (mode_params->flags & VG_MODEFLAG_CUSTOM_PANEL)
+ {
+ pmtim1 = mode_params->panel_tim1;
+ pmtim2 = mode_params->panel_tim2;
+ dith_ctl = mode_params->panel_dither_ctl;
+ msr_value.low = mode_params->panel_pad_sel_low;
+ msr_value.high = mode_params->panel_pad_sel_high;
+ }
+ else
+ {
+ pmtim1 = DF_DEFAULT_TFT_PMTIM1;
+ pmtim2 = DF_DEFAULT_TFT_PMTIM2;
+ dith_ctl = DF_DEFAULT_DITHCTL;
+ msr_value.low = DF_DEFAULT_TFT_PAD_SEL_LOW;
+ msr_value.high = DF_DEFAULT_TFT_PAD_SEL_HIGH;
+
+ }
+ WRITE_VID32 (DF_VIDEO_PANEL_TIM1, pmtim1);
+ WRITE_VID32 (DF_VIDEO_PANEL_TIM2, pmtim2);
+ WRITE_VID32 (DF_DITHER_CONTROL, dith_ctl);
+ msr_write64 (MSR_DEVICE_GEODELX_DF, DF_MSR_PAD_SEL, &msr_value);
+ }
+
+ /* SET APPROPRIATE PANEL OUTPUT MODE */
+
+ msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
+
+ msr_value.low &= ~DF_CONFIG_OUTPUT_MASK;
+ msr_value.low |= DF_OUTPUT_PANEL;
+ if (mode_params->flags & VG_MODEFLAG_CRT_AND_FP)
+ msr_value.low |= DF_SIMULTANEOUS_CRT_FP;
+ else
+ msr_value.low &= ~DF_SIMULTANEOUS_CRT_FP;
+
+ msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
+
+ }
+ else if (mode_params->flags & VG_MODEFLAG_TVOUT)
+ {
+ vg3_panel_enable = 0;
+
+ /* SET APPROPRIATE TV OUTPUT MODE */
+
+ msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
+
+ msr_value.low &= ~DF_CONFIG_OUTPUT_MASK;
+ msr_value.low |= DF_OUTPUT_PANEL;
+ if (mode_params->flags & VG_MODEFLAG_CRT_AND_FP)
+ msr_value.low |= DF_SIMULTANEOUS_CRT_FP;
+ else
+ msr_value.low &= ~DF_SIMULTANEOUS_CRT_FP;
+
+ msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
+
+ /* CONFIGURE PADS FOR VOP OUTPUT */
+ /* Note that the VOP clock is currently always inverted. */
+
+ msr_value.low = DF_DEFAULT_TV_PAD_SEL_LOW;
+ msr_value.high = DF_DEFAULT_TV_PAD_SEL_HIGH;
+ msr_write64 (MSR_DEVICE_GEODELX_DF, DF_MSR_PAD_SEL, &msr_value);
+ }
+ else
+ {
+ vg3_panel_enable = 0;
+
+ /* SET OUTPUT TO CRT ONLY */
+
+ msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
+ msr_value.low &= ~DF_CONFIG_OUTPUT_MASK;
+ msr_value.low |= DF_OUTPUT_CRT;
+ msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
+ }
+
+ /* SET UNLOCK VALUE */
+
+ unlock = READ_REG32 (DC3_UNLOCK);
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+ /*-------------------------------------------------------------------*/
+ /* MAKE THE SYSTEM "SAFE" */
+ /* Before setting a mode, we first ensure that the system is in a */
+ /* benign quiescent state. This involves disabling compression and */
+ /* all interrupt sources. It also involves terminating all accesses */
+ /* to memory, including video, FIFO load, VIP and the GP. */
+ /*-------------------------------------------------------------------*/
+
+ /* DISABLE VGA */
+ /* VGA *MUST* be turned off before TGEN is enabled. If not, a condition */
+ /* will result where VGA Enable is waiting for a VSync to be latched but */
+ /* a VSync will not be generated until VGA is disabled. */
+
+ temp = READ_REG32 (DC3_GENERAL_CFG) & ~DC3_GCFG_VGAE;
+
+ /* DISABLE VIDEO (INCLUDING ALPHA WINDOWS) */
+
+ WRITE_VID32 (DF_ALPHA_CONTROL_1, 0);
+ WRITE_VID32 (DF_ALPHA_CONTROL_1 + 32, 0);
+ WRITE_VID32 (DF_ALPHA_CONTROL_1 + 64, 0);
+
+ WRITE_REG32 (DC3_GENERAL_CFG, (temp & ~DC3_GCFG_VIDE));
+ temp = READ_VID32 (DF_VIDEO_CONFIG);
+ WRITE_VID32 (DF_VIDEO_CONFIG, (temp & ~DF_VCFG_VID_EN));
+
+ /* DISABLE VG INTERRUPTS */
+
+ WRITE_REG32 (DC3_IRQ, DC3_IRQ_MASK | DC3_VSYNC_IRQ_MASK |
+ DC3_IRQ_STATUS | DC3_VSYNC_IRQ_STATUS);
+
+ /* DISABLE GENLOCK */
+
+ genlk_ctl = READ_REG32 (DC3_GENLK_CTL);
+ WRITE_REG32 (DC3_GENLK_CTL, (genlk_ctl & ~DC3_GC_GENLOCK_ENABLE));
+
+ /* DISABLE VIP CAPTURE AND VIP INTERRUPTS */
+
+ WRITE_VIP32 (VIP_CONTROL1, 0);
+ WRITE_VIP32 (VIP_CONTROL2, 0);
+ WRITE_VIP32 (VIP_INTERRUPT, VIP_ALL_INTERRUPTS | (VIP_ALL_INTERRUPTS >> 16));
+
+ /* DISABLE COLOR KEYING */
+ /* The color key mechanism should be disabled whenever a mode switch occurs. */
+
+ temp = READ_REG32 (DC3_COLOR_KEY);
+ WRITE_REG32 (DC3_COLOR_KEY, (temp & ~DC3_CLR_KEY_ENABLE));
+
+ /* BLANK THE DISPLAY */
+ /* Note that we never blank the panel. Most flat panels have very long */
+ /* latency requirements when setting their power low. Some panels require */
+ /* upwards of 500ms before VDD goes high again. Needless to say, we are not */
+ /* planning to take over one half a second inside this routine. */
+
+ misc = READ_VID32 (DF_VID_MISC);
+ config = READ_VID32 (DF_DISPLAY_CONFIG);
+
+ WRITE_VID32 (DF_VID_MISC, (misc | DF_DAC_POWER_DOWN));
+ WRITE_VID32 (DF_DISPLAY_CONFIG, (config & ~(DF_DCFG_DIS_EN | DF_DCFG_HSYNC_EN |
+ DF_DCFG_VSYNC_EN | DF_DCFG_DAC_BL_EN)));
+
+ /* DISABLE COMPRESSION */
+
+ gcfg = READ_REG32 (DC3_GENERAL_CFG);
+ gcfg &= ~(DC3_GCFG_CMPE | DC3_GCFG_DECE);
+ WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+
+ /* DISABLE THE TIMING GENERATOR */
+
+ dcfg = READ_REG32 (DC3_DISPLAY_CFG);
+ dcfg &= ~DC3_DCFG_TGEN;
+ WRITE_REG32 (DC3_DISPLAY_CFG, dcfg);
+
+ /* WAIT FOR PENDING MEMORY REQUESTS */
+
+ vg_delay_milliseconds(1);
+
+ /* DISABLE DISPLAY FIFO LOAD */
+
+ gcfg &= ~DC3_GCFG_DFLE;
+ WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+ gcfg = 0;
+ dcfg = 0;
+
+ /* WAIT FOR THE GP TO BE IDLE (JUST IN CASE) */
+
+ while (((temp = READ_GP32 (GP3_BLT_STATUS)) & GP3_BS_BLT_BUSY) ||
+ !(temp & GP3_BS_CB_EMPTY))
+ {
+ ;
+ }
+
+ /* SET THE DOT CLOCK FREQUENCY */
+
+ if (!(mode_params->flags & VG_MODEFLAG_EXCLUDEPLL))
+ {
+ if (mode_params->flags & VG_MODEFLAG_HALFCLOCK)
+ flags = VG_PLL_DIVIDE_BY_2;
+ else if (mode_params->flags & VG_MODEFLAG_QVGA)
+ flags = VG_PLL_DIVIDE_BY_4;
+ else
+ flags = 0;
+
+ /* ALLOW DOTREF TO BE USED AS THE PLL */
+ /* This is useful for some external TV encoders. */
+
+ if (mode_params->flags & VG_MODEFLAG_PLL_BYPASS)
+ flags |= VG_PLL_BYPASS;
+
+ /* ALLOW THE USER TO MANUALLY ENTER THE MSR VALUE */
+
+ if (mode_params->flags & VG_MODEFLAG_MANUAL_FREQUENCY)
+ flags |= VG_PLL_MANUAL;
+ if (mode_params->flags & VG_MODEFLAG_VIP_TO_DOT_CLOCK)
+ flags |= VG_PLL_VIP_CLOCK;
+
+ vg_set_clock_frequency (mode_params->frequency, flags);
+ }
+
+ /* CLEAR ALL BUFFER OFFSETS */
+
+ WRITE_REG32 (DC3_FB_ST_OFFSET, 0);
+ WRITE_REG32 (DC3_CB_ST_OFFSET, 0);
+ WRITE_REG32 (DC3_CURS_ST_OFFSET, 0);
+
+ genlk_ctl = READ_REG32 (DC3_GENLK_CTL) & ~(DC3_GC_ALPHA_FLICK_ENABLE |
+ DC3_GC_FLICKER_FILTER_ENABLE | DC3_GC_FLICKER_FILTER_MASK);
+
+ /* ENABLE INTERLACING */
+
+ if (mode_params->flags & VG_MODEFLAG_INTERLACED)
+ {
+ irq_ctl |= DC3_IRQFILT_INTL_EN;
+
+ if ((mode_params->flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_ADDRESS)
+ irq_ctl |= DC3_IRQFILT_INTL_ADDR;
+ else if ((mode_params->flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_FLICKER)
+ {
+ genlk_ctl |= DC3_GC_FLICKER_FILTER_1_8 | DC3_GC_FLICKER_FILTER_ENABLE |
+ DC3_GC_ALPHA_FLICK_ENABLE;
+ }
+ }
+
+ WRITE_REG32 (DC3_GFX_SCALE, (vscale << 16) | (hscale & 0xFFFF));
+ WRITE_REG32 (DC3_IRQ_FILT_CTL, irq_ctl);
+ WRITE_REG32 (DC3_GENLK_CTL, genlk_ctl);
+
+ /* SET LINE SIZE AND PITCH */
+ /* The line size and pitch are calculated from the src_width parameter */
+ /* passed in to this routine. All other parameters are ignored. */
+ /* The pitch is set either to a power of 2 to allow efficient */
+ /* compression or to a linear value to allow efficient memory management. */
+
+ switch (bpp)
+ {
+ case 8:
+ size = mode_params->src_width;
+ line_size = starting_width;
+ break;
+
+ case 12:
+ case 15:
+ case 16:
+
+ size = mode_params->src_width << 1;
+ line_size = starting_width << 1;
+ break;
+
+ case 24:
+ case 32:
+ default:
+
+ size = mode_params->src_width << 2;
+ line_size = starting_width << 2; break;
+ }
+
+ /* CALCULATE DV RAM SETTINGS AND POWER OF 2 PITCH */
+
+ pitch = 1024;
+ dv_size = DC3_DV_LINE_SIZE_1024;
+
+ if (size > 1024) { pitch = 2048; dv_size = DC3_DV_LINE_SIZE_2048; }
+ if (size > 2048) { pitch = 4096; dv_size = DC3_DV_LINE_SIZE_4096; }
+ if (size > 4096) { pitch = 8192; dv_size = DC3_DV_LINE_SIZE_8192; }
+
+ /* OVERRIDE SETTINGS FOR LINEAR PITCH */
+
+ if (mode_params->flags & VG_MODEFLAG_LINEARPITCH)
+ {
+ unsigned long max;
+ if (pitch != size)
+ {
+ /* CALCULATE MAXIMUM ADDRESS (1K ALIGNED) */
+
+ max = size * output_height;
+ max = (max + 0x3FF) & 0xFFFFFC00;
+ WRITE_REG32 (DC3_DV_TOP, max | DC3_DVTOP_ENABLE);
+
+ gcfg |= DC3_GCFG_FDTY;
+ pitch = size;
+ }
+ else
+ {
+ WRITE_REG32 (DC3_DV_TOP, 0);
+ }
+ }
+
+ /* WRITE PITCH AND DV RAM SETTINGS */
+ /* The DV RAM line length is programmed at a power of 2 boundary */
+ /* in case the user wants to toggle back to a power of 2 pitch */
+ /* later. It could happen... */
+
+ temp = READ_REG32 (DC3_DV_CTL);
+ WRITE_REG32 (DC3_GFX_PITCH, pitch >> 3);
+ WRITE_REG32 (DC3_DV_CTL, (temp & ~DC3_DV_LINE_SIZE_MASK) | dv_size);
+
+ /* SET THE LINE SIZE */
+
+ WRITE_REG32 (DC3_LINE_SIZE, (line_size + 7) >> 3);
+
+ /* ALWAYS ENABLE VIDEO AND GRAPHICS DATA */
+ /* These bits are relics from a previous design and */
+ /* should always be enabled. */
+
+ dcfg |= (DC3_DCFG_VDEN | DC3_DCFG_GDEN);
+
+ /* SET PIXEL FORMAT */
+
+ dcfg |= bpp_mask;
+
+ /* ENABLE TIMING GENERATOR, TIM. REG. UPDATES, PALETTE BYPASS */
+ /* AND VERT. INT. SELECT */
+
+ dcfg |= (unsigned long)(DC3_DCFG_TGEN | DC3_DCFG_TRUP | DC3_DCFG_PALB | DC3_DCFG_VISL);
+
+ /* SET FIFO PRIORITIES AND DISPLAY FIFO LOAD ENABLE */
+ /* Note that the bandwidth setting gets upgraded when scaling or flicker */
+ /* filtering are enabled, as they require more data throughput. */
+
+ msr_read64 (MSR_DEVICE_GEODELX_VG, DC3_SPARE_MSR, &msr_value);
+ msr_value.low &= ~(DC3_SPARE_DISABLE_CFIFO_HGO | DC3_SPARE_VFIFO_ARB_SELECT |
+ DC3_SPARE_LOAD_WM_LPEN_MASK | DC3_SPARE_WM_LPEN_OVRD |
+ DC3_SPARE_DISABLE_INIT_VID_PRI | DC3_SPARE_DISABLE_VFIFO_WM);
+
+ if ((mode_params->flags & VG_MODEFLAG_BANDWIDTHMASK) == VG_MODEFLAG_HIGH_BAND ||
+ ((mode_params->flags & VG_MODEFLAG_INTERLACED) &&
+ (mode_params->flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_FLICKER) ||
+ (irq_ctl & DC3_IRQFILT_GFX_FILT_EN))
+ {
+ /* HIGH BANDWIDTH */
+ /* Set agressive watermarks and disallow forced low priority */
+
+ gcfg |= 0x0000BA01;
+ dcfg |= 0x000EA000;
+ acfg = 0x001A0201;
+
+ msr_value.low |= DC3_SPARE_DISABLE_CFIFO_HGO | DC3_SPARE_VFIFO_ARB_SELECT |
+ DC3_SPARE_WM_LPEN_OVRD;
+ }
+ else if ((mode_params->flags & VG_MODEFLAG_BANDWIDTHMASK) == VG_MODEFLAG_AVG_BAND)
+ {
+ /* AVERAGE BANDWIDTH */
+ /* Set average watermarks and allow small regions of forced low priority. */
+
+ gcfg |= 0x0000B601;
+ dcfg |= 0x00009000;
+ acfg = 0x00160001;
+
+ msr_value.low |= DC3_SPARE_DISABLE_CFIFO_HGO | DC3_SPARE_VFIFO_ARB_SELECT |
+ DC3_SPARE_WM_LPEN_OVRD;
+
+ /* SET THE NUMBER OF LOW PRIORITY LINES TO 1/2 THE TOTAL AVAILABLE */
+
+ temp = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0x7FF) + 1;
+ temp -= (READ_REG32 (DC3_V_SYNC_TIMING) & 0x7FF) + 1;
+ temp >>= 1;
+ if (temp > 127)
+ temp = 127;
+
+ acfg |= temp << 9;
+ }
+ else if ((mode_params->flags & VG_MODEFLAG_BANDWIDTHMASK) == VG_MODEFLAG_LOW_BAND)
+ {
+ /* LOW BANDWIDTH */
+ /* Set low watermarks and allow larger regions of forced low priority. */
+
+ gcfg |= 0x00009501;
+ dcfg |= 0x00008000;
+ acfg = 0x00150001;
+
+ msr_value.low |= DC3_SPARE_DISABLE_CFIFO_HGO | DC3_SPARE_VFIFO_ARB_SELECT |
+ DC3_SPARE_WM_LPEN_OVRD;
+
+ /* SET THE NUMBER OF LOW PRIORITY LINES TO 3/4 THE TOTAL AVAILABLE */
+
+ temp = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0x7FF) + 1;
+ temp -= (READ_REG32 (DC3_V_SYNC_TIMING) & 0x7FF) + 1;
+ temp = (temp * 3) >> 2;
+ if (temp > 127)
+ temp = 127;
+
+ acfg |= temp << 9;
+ }
+ else
+ {
+ /* LEGACY CHARACTERISTICS */
+ /* Arbitration from a single set of watermarks. */
+
+ gcfg |= 0x0000B601;
+ msr_value.low |= DC3_SPARE_DISABLE_VFIFO_WM | DC3_SPARE_DISABLE_INIT_VID_PRI;
+ acfg = 0;
+ }
+
+ msr_write64 (MSR_DEVICE_GEODELX_VG, DC3_SPARE_MSR, &msr_value);
+
+ /* ENABLE FLAT PANEL CENTERING */
+ /* For panel modes having a resolution smaller than the */
+ /* panel resolution, turn on data centering. */
+
+ if (mode_params->flags & VG_MODEFLAG_CENTERED)
+ dcfg |= DC3_DCFG_DCEN;
+
+ /* COMBINE AND SET TIMING VALUES */
+
+ temp = (mode_params->hactive - 1) | ((mode_params->htotal - 1) << 16);
+ WRITE_REG32(DC3_H_ACTIVE_TIMING, temp);
+ temp = (mode_params->hblankstart - 1) | ((mode_params->hblankend - 1) << 16);
+ WRITE_REG32(DC3_H_BLANK_TIMING, temp);
+ temp = (mode_params->hsyncstart - 1) | ((mode_params->hsyncend - 1) << 16);
+ WRITE_REG32(DC3_H_SYNC_TIMING, temp);
+ temp = (mode_params->vactive - 1) | ((mode_params->vtotal - 1) << 16);
+ WRITE_REG32(DC3_V_ACTIVE_TIMING, temp);
+ temp = (mode_params->vblankstart - 1) | ((mode_params->vblankend - 1) << 16);
+ WRITE_REG32(DC3_V_BLANK_TIMING, temp);
+ temp = (mode_params->vsyncstart - 1) | ((mode_params->vsyncend - 1) << 16);
+ WRITE_REG32(DC3_V_SYNC_TIMING, temp);
+ temp = (mode_params->vactive_even - 1) | ((mode_params->vtotal_even - 1) << 16);
+ WRITE_REG32(DC3_V_ACTIVE_EVEN, temp);
+ temp = (mode_params->vblankstart_even - 1) | ((mode_params->vblankend_even - 1) << 16);
+ WRITE_REG32(DC3_V_BLANK_EVEN, temp);
+ temp = (mode_params->vsyncstart_even - 1) | ((mode_params->vsyncend_even - 1) << 16);
+ WRITE_REG32(DC3_V_SYNC_EVEN, temp);
+
+ /* SET THE VIDEO REQUEST REGISTER */
+
+ WRITE_VID32 (DF_VIDEO_REQUEST, 0);
+
+ /* SET SOURCE DIMENSIONS */
+
+ WRITE_REG32 (DC3_FB_ACTIVE, ((starting_width - 1) << 16) |
+ (starting_height - 1));
+
+ /* SET SYNC POLARITIES */
+
+ temp = READ_VID32 (DF_DISPLAY_CONFIG);
+
+ temp &= ~(DF_DCFG_CRT_SYNC_SKW_MASK | DF_DCFG_PWR_SEQ_DLY_MASK |
+ DF_DCFG_CRT_HSYNC_POL | DF_DCFG_CRT_VSYNC_POL);
+
+ temp |= (DF_DCFG_CRT_SYNC_SKW_INIT |
+ DF_DCFG_PWR_SEQ_DLY_INIT |
+ DF_DCFG_GV_PAL_BYP);
+
+ if (mode_params->flags & VG_MODEFLAG_NEG_HSYNC)
+ temp |= DF_DCFG_CRT_HSYNC_POL;
+ if (mode_params->flags & VG_MODEFLAG_NEG_VSYNC)
+ temp |= DF_DCFG_CRT_VSYNC_POL;
+
+ WRITE_VID32 (DF_DISPLAY_CONFIG, temp);
+
+ WRITE_REG32 (DC3_DISPLAY_CFG, dcfg);
+ WRITE_REG32 (DC3_ARB_CFG, acfg);
+ WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+
+ /* RESTORE VALUE OF DC3_UNLOCK */
+
+ WRITE_REG32(DC3_UNLOCK, unlock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_bpp
+ *
+ * This routine changes the display BPP on the fly. It is intended only to
+ * switch between pixel depths of the same pixel size 24<->32 or 15<->16, NOT
+ * between pixel depths of differing sizes 16<->32
+ *---------------------------------------------------------------------------*/
+
+int vg_set_display_bpp (int bpp)
+{
+ unsigned long unlock, dcfg, bpp_mask;
+
+ switch (bpp)
+ {
+ case 8: bpp_mask = DC3_DCFG_DISP_MODE_8BPP; break;
+ case 24: bpp_mask = DC3_DCFG_DISP_MODE_24BPP; break;
+ case 32: bpp_mask = DC3_DCFG_DISP_MODE_32BPP; break;
+ case 12: bpp_mask = DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_12BPP; break;
+ case 15: bpp_mask = DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_15BPP; break;
+ case 16: bpp_mask = DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_16BPP; break;
+ default: return CIM_STATUS_INVALIDPARAMS;
+ }
+
+ unlock = READ_REG32 (DC3_UNLOCK);
+ dcfg = READ_REG32 (DC3_DISPLAY_CFG) & ~(DC3_DCFG_DISP_MODE_MASK | DC3_DCFG_16BPP_MODE_MASK);
+ dcfg |= bpp_mask;
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_DISPLAY_CFG, dcfg);
+ WRITE_REG32 (DC3_UNLOCK, unlock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_get_display_mode_index
+ *
+ * This routine searches the Cimarron mode table for a mode that matches the
+ * input parameters. If a match is found, the return value is the index into
+ * the mode table. If no match is found, the return value is -1.
+ *---------------------------------------------------------------------------*/
+
+int vg_get_display_mode_index (VG_QUERY_MODE *query)
+{
+ unsigned int mode;
+ unsigned long hz_flag = 0xFFFFFFFF;
+ unsigned long bpp_flag = 0xFFFFFFFF;
+ unsigned long enc_flag = 0xFFFFFFFF;
+ unsigned long tv_flag = 0;
+ unsigned long interlaced = 0;
+ unsigned long halfclock = 0;
+ long minimum = 0x7FFFFFFF;
+ long diff;
+ int match = -1;
+
+ if (!query || !query->query_flags)
+ return -1;
+
+ if (query->query_flags & VG_QUERYFLAG_REFRESH)
+ {
+ /* SET FLAGS TO MATCH REFRESH RATE */
+
+ if (query->hz == 56) hz_flag = VG_SUPPORTFLAG_56HZ;
+ else if (query->hz == 60) hz_flag = VG_SUPPORTFLAG_60HZ;
+ else if (query->hz == 70) hz_flag = VG_SUPPORTFLAG_70HZ;
+ else if (query->hz == 72) hz_flag = VG_SUPPORTFLAG_72HZ;
+ else if (query->hz == 75) hz_flag = VG_SUPPORTFLAG_75HZ;
+ else if (query->hz == 85) hz_flag = VG_SUPPORTFLAG_85HZ;
+ else if (query->hz == 90) hz_flag = VG_SUPPORTFLAG_90HZ;
+ else if (query->hz == 100) hz_flag = VG_SUPPORTFLAG_100HZ;
+ else hz_flag = 0;
+ }
+
+ if (query->query_flags & VG_QUERYFLAG_BPP)
+ {
+ /* SET BPP FLAGS TO LIMIT MODE SELECTION */
+
+ if (query->bpp == 8) bpp_flag = VG_SUPPORTFLAG_8BPP;
+ else if (query->bpp == 12) bpp_flag = VG_SUPPORTFLAG_12BPP;
+ else if (query->bpp == 15) bpp_flag = VG_SUPPORTFLAG_15BPP;
+ else if (query->bpp == 16) bpp_flag = VG_SUPPORTFLAG_16BPP;
+ else if (query->bpp == 24) bpp_flag = VG_SUPPORTFLAG_24BPP;
+ else if (query->bpp == 32) bpp_flag = VG_SUPPORTFLAG_32BPP;
+ else bpp_flag = 0;
+ }
+
+ if (query->query_flags & VG_QUERYFLAG_ENCODER)
+ {
+ /* SET ENCODER FLAGS TO LIMIT MODE SELECTION */
+
+ if (query->encoder == VG_ENCODER_ADV7171) enc_flag = VG_SUPPORTFLAG_ADV7171;
+ else if (query->encoder == VG_ENCODER_SAA7127) enc_flag = VG_SUPPORTFLAG_SAA7127;
+ else if (query->encoder == VG_ENCODER_FS454) enc_flag = VG_SUPPORTFLAG_FS454;
+ else if (query->encoder == VG_ENCODER_ADV7300) enc_flag = VG_SUPPORTFLAG_ADV7300;
+ else enc_flag = 0;
+ }
+
+ if (query->query_flags & VG_QUERYFLAG_TVMODE)
+ {
+ /* SET ENCODER FLAGS TO LIMIT MODE SELECTION */
+
+ if (query->tvmode == VG_TVMODE_NTSC) tv_flag = VG_SUPPORTFLAG_NTSC;
+ else if (query->tvmode == VG_TVMODE_PAL) tv_flag = VG_SUPPORTFLAG_PAL;
+ else if (query->tvmode == VG_TVMODE_480P) tv_flag = VG_SUPPORTFLAG_480P;
+ else if (query->tvmode == VG_TVMODE_720P) tv_flag = VG_SUPPORTFLAG_720P;
+ else if (query->tvmode == VG_TVMODE_1080I) tv_flag = VG_SUPPORTFLAG_1080I;
+ else if (query->tvmode == VG_TVMODE_6X4_NTSC) tv_flag = VG_SUPPORTFLAG_6X4_NTSC;
+ else if (query->tvmode == VG_TVMODE_8X6_NTSC) tv_flag = VG_SUPPORTFLAG_8X6_NTSC;
+ else if (query->tvmode == VG_TVMODE_10X7_NTSC) tv_flag = VG_SUPPORTFLAG_10X7_NTSC;
+ else if (query->tvmode == VG_TVMODE_6X4_PAL) tv_flag = VG_SUPPORTFLAG_6X4_PAL;
+ else if (query->tvmode == VG_TVMODE_8X6_PAL) tv_flag = VG_SUPPORTFLAG_8X6_PAL;
+ else if (query->tvmode == VG_TVMODE_10X7_PAL) tv_flag = VG_SUPPORTFLAG_10X7_PAL;
+ else tv_flag = 0xFFFFFFFF;
+ }
+
+ /* SET APPROPRIATE TV AND VOP FLAGS */
+
+ if (query->query_flags & VG_QUERYFLAG_INTERLACED)
+ interlaced = query->interlaced ? VG_MODEFLAG_INTERLACED : 0;
+ if (query->query_flags & VG_QUERYFLAG_HALFCLOCK)
+ halfclock = query->halfclock ? VG_MODEFLAG_HALFCLOCK : 0;
+
+ /* CHECK FOR INVALID REQUEST */
+
+ if (!hz_flag || !bpp_flag || !enc_flag || tv_flag == 0xFFFFFFFF)
+ return -1;
+
+ /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
+
+ for (mode = 0; mode < NUM_CIMARRON_DISPLAY_MODES; mode++)
+ {
+ if ( (!(query->query_flags & VG_QUERYFLAG_PANEL) ||
+ (CimarronDisplayModes[mode].internal_flags & VG_SUPPORTFLAG_PANEL)) &&
+ (!(query->query_flags & VG_QUERYFLAG_TVOUT) ||
+ (CimarronDisplayModes[mode].internal_flags & VG_SUPPORTFLAG_TVOUT)) &&
+ (!(query->query_flags & VG_QUERYFLAG_INTERLACED) ||
+ (CimarronDisplayModes[mode].flags & VG_MODEFLAG_INTERLACED) == interlaced) &&
+ (!(query->query_flags & VG_QUERYFLAG_HALFCLOCK) ||
+ (CimarronDisplayModes[mode].flags & VG_MODEFLAG_HALFCLOCK) == halfclock) &&
+ (!(query->query_flags & VG_QUERYFLAG_PANELWIDTH) ||
+ (CimarronDisplayModes[mode].panel_width == query->panel_width)) &&
+ (!(query->query_flags & VG_QUERYFLAG_PANELHEIGHT) ||
+ (CimarronDisplayModes[mode].panel_height == query->panel_height)) &&
+ (!(query->query_flags & VG_QUERYFLAG_ACTIVEWIDTH) ||
+ (CimarronDisplayModes[mode].hactive == query->active_width)) &&
+ (!(query->query_flags & VG_QUERYFLAG_ACTIVEHEIGHT) ||
+ (CimarronDisplayModes[mode].vactive == query->active_height)) &&
+ (!(query->query_flags & VG_QUERYFLAG_TOTALWIDTH) ||
+ (CimarronDisplayModes[mode].htotal == query->total_width)) &&
+ (!(query->query_flags & VG_QUERYFLAG_TOTALHEIGHT) ||
+ (CimarronDisplayModes[mode].vtotal == query->total_height)) &&
+ (!(query->query_flags & VG_QUERYFLAG_BPP) ||
+ (CimarronDisplayModes[mode].internal_flags & bpp_flag)) &&
+ (!(query->query_flags & VG_QUERYFLAG_REFRESH) ||
+ (CimarronDisplayModes[mode].internal_flags & hz_flag)) &&
+ (!(query->query_flags & VG_QUERYFLAG_ENCODER) ||
+ (CimarronDisplayModes[mode].internal_flags & enc_flag)) &&
+ (!(query->query_flags & VG_QUERYFLAG_TVMODE) ||
+ ((CimarronDisplayModes[mode].internal_flags & VG_SUPPORTFLAG_TVMODEMASK) == tv_flag)) &&
+ (!(query->query_flags & VG_QUERYFLAG_PIXELCLOCK) ||
+ (CimarronDisplayModes[mode].frequency == query->frequency)))
+ {
+ /* ALLOW SEARCHING BASED ON AN APPROXIMATE PIXEL CLOCK */
+
+ if (query->query_flags & VG_QUERYFLAG_PIXELCLOCK_APPROX)
+ {
+ diff = query->frequency - CimarronDisplayModes[mode].frequency;
+ if (diff < 0)
+ diff = -diff;
+
+ if (diff < minimum)
+ {
+ minimum = diff;
+ match = mode;
+ }
+ }
+ else
+ {
+ match = mode;
+ break;
+ }
+ }
+ }
+
+ /* RETURN DISPLAY MODE INDEX */
+
+ return match;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_get_display_mode_information
+ *
+ * This routine retrieves all information for a display mode contained
+ * within Cimarron's mode tables.
+ *---------------------------------------------------------------------------*/
+
+int vg_get_display_mode_information (unsigned int index, VG_DISPLAY_MODE *vg_mode)
+{
+ if (index > NUM_CIMARRON_DISPLAY_MODES)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ *vg_mode = CimarronDisplayModes[index];
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_get_display_mode_count
+ *
+ * This routine retrieves the count of all predefined Cimarron modes.
+ *---------------------------------------------------------------------------*/
+
+int vg_get_display_mode_count (void)
+{
+ return NUM_CIMARRON_DISPLAY_MODES;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_get_current_display_mode
+ *
+ * This routine retrieves the settings for the current display. This includes
+ * any panel settings.
+ *---------------------------------------------------------------------------*/
+
+int vg_get_current_display_mode (VG_DISPLAY_MODE *current_display, int *bpp)
+{
+ Q_WORD msr_value;
+ unsigned long active, blank, sync;
+ unsigned long i, m, n, p;
+ unsigned long genlk, irq, temp;
+ unsigned long flags = 0;
+ unsigned long iflags = 0;
+
+ /* READ THE CURRENT HORIZONTAL DISPLAY TIMINGS */
+
+ active = READ_REG32 (DC3_H_ACTIVE_TIMING);
+ blank = READ_REG32 (DC3_H_BLANK_TIMING);
+ sync = READ_REG32 (DC3_H_SYNC_TIMING);
+
+ current_display->hactive = (active & 0xFFF) + 1;
+ current_display->hblankstart = (blank & 0xFFF) + 1;
+ current_display->hsyncstart = (sync & 0xFFF) + 1;
+
+ current_display->htotal = ((active >> 16) & 0xFFF) + 1;
+ current_display->hblankend = ((blank >> 16) & 0xFFF) + 1;
+ current_display->hsyncend = ((sync >> 16) & 0xFFF) + 1;
+
+ /* READ THE CURRENT VERTICAL DISPLAY TIMINGS */
+
+ active = READ_REG32 (DC3_V_ACTIVE_TIMING);
+ blank = READ_REG32 (DC3_V_BLANK_TIMING);
+ sync = READ_REG32 (DC3_V_SYNC_TIMING);
+
+ current_display->vactive = (active & 0x7FF) + 1;
+ current_display->vblankstart = (blank & 0x7FF) + 1;
+ current_display->vsyncstart = (sync & 0x7FF) + 1;
+
+ current_display->vtotal = ((active >> 16) & 0x7FF) + 1;
+ current_display->vblankend = ((blank >> 16) & 0x7FF) + 1;
+ current_display->vsyncend = ((sync >> 16) & 0x7FF) + 1;
+
+ /* READ THE CURRENT EVEN FIELD VERTICAL DISPLAY TIMINGS */
+
+ active = READ_REG32 (DC3_V_ACTIVE_EVEN);
+ blank = READ_REG32 (DC3_V_BLANK_EVEN);
+ sync = READ_REG32 (DC3_V_SYNC_EVEN);
+
+ current_display->vactive_even = (active & 0x7FF) + 1;
+ current_display->vblankstart_even = (blank & 0x7FF) + 1;
+ current_display->vsyncstart_even = (sync & 0x7FF) + 1;
+
+ current_display->vtotal_even = ((active >> 16) & 0x7FF) + 1;
+ current_display->vblankend_even = ((blank >> 16) & 0x7FF) + 1;
+ current_display->vsyncend_even = ((sync >> 16) & 0x7FF) + 1;
+
+ /* READ THE CURRENT SOURCE DIMENSIONS */
+ /* The DC3_FB_ACTIVE register is only used when scaling is enabled. */
+ /* As the goal of this routine is to return a structure that can be */
+ /* passed to vg_set_custom_mode to exactly recreate the current mode, */
+ /* we must check the status of the scaler/filter. */
+
+ genlk = READ_REG32 (DC3_GENLK_CTL);
+ irq = READ_REG32 (DC3_IRQ_FILT_CTL);
+ temp = READ_REG32 (DC3_FB_ACTIVE);
+
+ current_display->src_height = (temp & 0xFFFF) + 1;
+ current_display->src_width = ((temp >> 16) & 0xFFF8) + 8;
+
+ /* READ THE CURRENT PANEL CONFIGURATION */
+ /* We can only infer some of the panel settings based on hardware */
+ /* (like when panning). We will instead assume that the current */
+ /* mode was set using Cimarron and use the panel variables inside */
+ /* Cimarron when returning the current mode information. */
+
+ if (vg3_panel_enable)
+ {
+ Q_WORD msr_value;
+
+ flags |= VG_MODEFLAG_PANELOUT;
+
+ current_display->panel_width = vg3_panel_width;
+ current_display->panel_height = vg3_panel_height;
+ current_display->mode_width = vg3_mode_width;
+ current_display->mode_height = vg3_mode_height;
+
+ if (READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_DCEN)
+ flags |= VG_MODEFLAG_CENTERED;
+
+ msr_read64 (MSR_DEVICE_GEODELX_DF, DF_MSR_PAD_SEL, &msr_value);
+ current_display->panel_tim1 = READ_VID32 (DF_VIDEO_PANEL_TIM1);
+ current_display->panel_tim2 = READ_VID32 (DF_VIDEO_PANEL_TIM2);
+ current_display->panel_dither_ctl = READ_VID32 (DF_DITHER_CONTROL);
+ current_display->panel_pad_sel_low = msr_value.low;
+ current_display->panel_pad_sel_high = msr_value.high;
+ }
+
+ /* SET MISCELLANEOUS MODE FLAGS */
+
+ /* INTERLACED */
+
+ if (irq & DC3_IRQFILT_INTL_EN)
+ {
+ flags |= VG_MODEFLAG_INTERLACED;
+ if (irq & DC3_IRQFILT_INTL_ADDR)
+ flags |= VG_MODEFLAG_INT_ADDRESS;
+ else if (genlk & DC3_GC_FLICKER_FILTER_ENABLE)
+ flags |= VG_MODEFLAG_INT_FLICKER;
+ else
+ flags |= VG_MODEFLAG_INT_LINEDOUBLE;
+ }
+
+ /* POLARITIES */
+
+ temp = READ_VID32 (DF_DISPLAY_CONFIG);
+ if (temp & DF_DCFG_CRT_HSYNC_POL)
+ flags |= VG_MODEFLAG_NEG_HSYNC;
+ if (temp & DF_DCFG_CRT_VSYNC_POL)
+ flags |= VG_MODEFLAG_NEG_VSYNC;
+
+ /* BPP */
+
+ temp = READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_DISP_MODE_MASK;
+ if (temp == DC3_DCFG_DISP_MODE_8BPP)
+ {
+ iflags |= VG_SUPPORTFLAG_8BPP;
+ *bpp = 8;
+ }
+ else if (temp == DC3_DCFG_DISP_MODE_24BPP)
+ {
+ iflags |= VG_SUPPORTFLAG_24BPP;
+ *bpp = 24;
+ }
+ else if (temp == DC3_DCFG_DISP_MODE_32BPP)
+ {
+ iflags |= VG_SUPPORTFLAG_32BPP;
+ *bpp = 32;
+ }
+ else if (temp == DC3_DCFG_DISP_MODE_16BPP)
+ {
+ temp = READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_16BPP_MODE_MASK;
+ if (temp == DC3_DCFG_16BPP)
+ {
+ iflags |= VG_SUPPORTFLAG_16BPP;
+ *bpp = 16;
+ }
+ else if (temp == DC3_DCFG_15BPP)
+ {
+ iflags |= VG_SUPPORTFLAG_15BPP;
+ *bpp = 15;
+ }
+ else if (temp == DC3_DCFG_12BPP)
+ {
+ iflags |= VG_SUPPORTFLAG_12BPP;
+ *bpp = 12;
+ }
+ }
+
+ /* TV RELATED FLAGS */
+
+ msr_read64 (MSR_DEVICE_GEODELX_DF, DF_MSR_PAD_SEL, &msr_value);
+ if (msr_value.high & DF_INVERT_VOP_CLOCK)
+ flags |= VG_MODEFLAG_TVOUT;
+
+ /* LINEAR PITCH */
+
+ temp = (READ_REG32 (DC3_GFX_PITCH) & 0x0000FFFF) << 3;
+ if (temp != 1024 && temp != 2048 && temp != 4096 && temp != 8192)
+ flags |= VG_MODEFLAG_LINEARPITCH;
+
+ /* SIMULTANEOUS CRT/FP */
+
+ msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
+ if (msr_value.low & DF_SIMULTANEOUS_CRT_FP)
+ flags |= VG_MODEFLAG_CRT_AND_FP;
+
+ /* SET PLL-RELATED FLAGS */
+
+ msr_read64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DOTPLL, &msr_value);
+ if (msr_value.high & GLCP_DOTPLL_DIV4)
+ flags |= VG_MODEFLAG_QVGA;
+ if (msr_value.low & GLCP_DOTPLL_HALFPIX)
+ flags |= VG_MODEFLAG_HALFCLOCK;
+
+ /* SAVE THE FLAGS IN THE MODE STRUCTURE */
+
+ current_display->internal_flags = iflags;
+ current_display->flags = flags;
+
+ /* READ PIXEL CLOCK FREQUENCY */
+ /* We first search for an exact match. If none is found, we try */
+ /* a fixed point calculation and return CIM_STATUS_INEXACTMATCH. */
+
+ for (i = 0; i < NUM_CIMARRON_PLL_FREQUENCIES; i++)
+ {
+ if (CimarronPLLFrequencies[i].pll_value == msr_value.high)
+ break;
+ }
+
+ if (i == NUM_CIMARRON_PLL_FREQUENCIES)
+ {
+ /* ATTEMPT 16.16 CALCULATION */
+ /* We assume the input frequency is 48 MHz, which is represented */
+ /* in 16.16 fixed point as 0x300000. The PLL calculation is: */
+ /* n + 1 */
+ /* Fout = 48.000 * -------------- */
+ /* m + 1 * p + 1 */
+
+ p = msr_value.high & 0xF;
+ n = (msr_value.high >> 4) & 0xFF;
+ m = (msr_value.high >> 12) & 0x7;
+ current_display->frequency = (0x300000 * (n + 1)) / ((p + 1) * (m + 1));
+
+ return CIM_STATUS_INEXACTMATCH;
+ }
+
+ current_display->frequency = CimarronPLLFrequencies[i].frequency;
+
+ /* NOW SEARCH FOR AN IDENTICAL MODE */
+ /* This is just to inform the user that an exact match was found. */
+ /* With an exact match, the user can use the refresh rate flag that */
+ /* is returned in the VG_DISPLAY_MODE structure. */
+
+ for (i = 0; i < NUM_CIMARRON_DISPLAY_MODES; i++)
+ {
+ if ((CimarronDisplayModes[i].flags & current_display->flags) &&
+ CimarronDisplayModes[i].frequency == current_display->frequency &&
+ CimarronDisplayModes[i].hactive == current_display->hactive &&
+ CimarronDisplayModes[i].hblankstart == current_display->hblankstart &&
+ CimarronDisplayModes[i].hsyncstart == current_display->hsyncstart &&
+ CimarronDisplayModes[i].hsyncend == current_display->hsyncend &&
+ CimarronDisplayModes[i].hblankend == current_display->hblankend &&
+ CimarronDisplayModes[i].htotal == current_display->htotal &&
+ CimarronDisplayModes[i].vactive == current_display->vactive &&
+ CimarronDisplayModes[i].vblankstart == current_display->vblankstart &&
+ CimarronDisplayModes[i].vsyncstart == current_display->vsyncstart &&
+ CimarronDisplayModes[i].vsyncend == current_display->vsyncend &&
+ CimarronDisplayModes[i].vblankend == current_display->vblankend &&
+ CimarronDisplayModes[i].vtotal == current_display->vtotal)
+ {
+ break;
+ }
+ }
+
+ if (i == NUM_CIMARRON_DISPLAY_MODES)
+ return CIM_STATUS_INEXACTMATCH;
+
+ current_display->internal_flags |= (CimarronDisplayModes[i].internal_flags & VG_SUPPORTFLAG_HZMASK);
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_scaler_filter_coefficients
+ *
+ * This routine sets the vertical and horizontal filter coefficients for
+ * graphics scaling. If either of the input arrays is specified as NULL, a
+ * set of default coeffecients will be used.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_scaler_filter_coefficients (long h_taps[][5], long v_taps[][3])
+{
+ unsigned long irqfilt, i;
+ unsigned long temp0, temp1;
+ unsigned long lock;
+
+ /* ENABLE ACCESS TO THE HORIZONTAL COEFFICIENTS */
+
+ irqfilt = READ_REG32 (DC3_IRQ_FILT_CTL);
+ irqfilt |= DC3_IRQFILT_H_FILT_SEL;
+
+ /* UNLOCK THE COEFFICIENT REGISTERS */
+
+ lock = READ_REG32 (DC3_UNLOCK);
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+ /* WRITE COEFFICIENTS */
+ /* Coefficient indexes do not auto-increment, so we must */
+ /* write the address for every phase */
+
+ for (i = 0; i < 256; i++)
+ {
+ WRITE_REG32 (DC3_IRQ_FILT_CTL, ((irqfilt & 0xFFFFFF00L) | i));
+
+ if (!h_taps)
+ {
+ temp0 = CimarronHorizontalGraphicsFilter[i][0];
+ temp1 = CimarronHorizontalGraphicsFilter[i][1];
+ }
+ else
+ {
+ temp0 = ((unsigned long)h_taps[i][0] & 0x3FF) |
+ (((unsigned long)h_taps[i][1] & 0x3FF) << 10) |
+ (((unsigned long)h_taps[i][2] & 0x3FF) << 20);
+
+ temp1 = ((unsigned long)h_taps[i][3] & 0x3FF) |
+ (((unsigned long)h_taps[i][4] & 0x3FF) << 10);
+ }
+ WRITE_REG32 (DC3_FILT_COEFF1, temp0);
+ WRITE_REG32 (DC3_FILT_COEFF2, temp1);
+ }
+
+ /* ENABLE ACCESS TO THE VERTICAL COEFFICIENTS */
+
+ irqfilt &= ~DC3_IRQFILT_H_FILT_SEL;
+
+ /* WRITE COEFFICIENTS */
+
+ for (i = 0; i < 256; i++)
+ {
+ WRITE_REG32 (DC3_IRQ_FILT_CTL, ((irqfilt & 0xFFFFFF00L) | i));
+
+ if (!v_taps)
+ {
+ temp0 = CimarronVerticalGraphicsFilter[i];
+ }
+ else
+ {
+ temp0 = ((unsigned long)v_taps[i][0] & 0x3FF) |
+ (((unsigned long)v_taps[i][1] & 0x3FF) << 10) |
+ (((unsigned long)v_taps[i][2] & 0x3FF) << 20);
+ }
+
+ WRITE_REG32 (DC3_FILT_COEFF1, temp0);
+ }
+
+ WRITE_REG32 (DC3_UNLOCK, lock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_configure_flicker_filter
+ *
+ * This routine updates the VG flicker filter settings when in an interlaced
+ * mode. Note that flicker filtering is enabled inside a mode set. This routine
+ * is provided to change from the default flicker filter setting of
+ * 1/4, 1/2, 1/4.
+ *---------------------------------------------------------------------------*/
+
+int vg_configure_flicker_filter (unsigned long flicker_strength, int flicker_alpha)
+{
+ unsigned long unlock;
+ unsigned long genlk_ctl;
+
+ /* CHECK FOR VALID FLICKER SETTING */
+
+ if (flicker_strength != VG_FLICKER_FILTER_NONE &&
+ flicker_strength != VG_FLICKER_FILTER_1_16 &&
+ flicker_strength != VG_FLICKER_FILTER_1_8 &&
+ flicker_strength != VG_FLICKER_FILTER_1_4 &&
+ flicker_strength != VG_FLICKER_FILTER_5_16)
+ {
+ return CIM_STATUS_INVALIDPARAMS;
+ }
+
+ unlock = READ_REG32 (DC3_UNLOCK);
+ genlk_ctl = READ_REG32 (DC3_GENLK_CTL) & ~(DC3_GC_FLICKER_FILTER_MASK | DC3_GC_ALPHA_FLICK_ENABLE);
+ genlk_ctl |= flicker_strength;
+ if (flicker_alpha)
+ genlk_ctl |= DC3_GC_ALPHA_FLICK_ENABLE;
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_GENLK_CTL, genlk_ctl);
+ WRITE_REG32 (DC3_UNLOCK, unlock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_clock_frequency
+ *
+ * This routine sets the frequency of the dot clock. The input to this routine
+ * is a 16.16 fraction. If an exact match is not found, this routine will program
+ * the closest available frequency and return CIM_STATUS_INEXACTMATCH.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_clock_frequency (unsigned long frequency, unsigned long pll_flags)
+{
+ Q_WORD msr_value;
+ unsigned long timeout;
+ unsigned long index = 0;
+ unsigned long unlock, i;
+ unsigned long pll_high, pll_low;
+ long diff, min = 0;
+
+ /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
+ /* Search the table for the closest frequency (16.16 format). */
+ /* This search is skipped if the user is manually specifying */
+ /* the MSR value. */
+
+ pll_low = 0;
+ if (!(pll_flags & VG_PLL_MANUAL))
+ {
+ min = (long)CimarronPLLFrequencies[0].frequency - (long)frequency;
+ if (min < 0L)
+ min = -min;
+
+ for (i = 1; i < NUM_CIMARRON_PLL_FREQUENCIES; i++)
+ {
+ diff = (long)CimarronPLLFrequencies[i].frequency - (long)frequency;
+ if (diff < 0L)
+ diff = -diff;
+
+ if (diff < min)
+ {
+ min = diff;
+ index = i;
+ }
+ }
+
+ pll_high = CimarronPLLFrequencies[index].pll_value & 0x00007FFF;
+ }
+ else
+ {
+ pll_high = frequency;
+ }
+
+ if (pll_flags & VG_PLL_DIVIDE_BY_2)
+ pll_low |= GLCP_DOTPLL_HALFPIX;
+ if (pll_flags & VG_PLL_DIVIDE_BY_4)
+ pll_high |= GLCP_DOTPLL_DIV4;
+ if (pll_flags & VG_PLL_BYPASS)
+ pll_low |= GLCP_DOTPLL_BYPASS;
+ if (pll_flags & VG_PLL_VIP_CLOCK)
+ pll_high |= GLCP_DOTPLL_VIPCLK;
+
+ /* VERIFY THAT WE ARE NOT WRITING WHAT IS ALREADY IN THE REGISTERS */
+ /* The Dot PLL reset bit is tied to VDD for flat panels. This can */
+ /* cause a brief drop in flat panel power, which can cause serious */
+ /* glitches on some panels. */
+
+ msr_read64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DOTPLL, &msr_value);
+
+ if ((msr_value.low & GLCP_DOTPLL_LOCK) &&
+ ((msr_value.low & (GLCP_DOTPLL_HALFPIX | GLCP_DOTPLL_BYPASS)) == pll_low) &&
+ (msr_value.high == pll_high))
+ {
+ return CIM_STATUS_OK;
+ }
+
+ /* PROGRAM THE SETTINGS WITH THE RESET BIT SET */
+ /* Clear the bypass bit to ensure that the programmed */
+ /* M, N and P values are being used. */
+
+ msr_value.high = pll_high;
+ msr_value.low &= ~(GLCP_DOTPLL_BYPASS | GLCP_DOTPLL_HALFPIX);
+ msr_value.low |= (pll_low | 0x00000001);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DOTPLL, &msr_value);
+
+ /* WAIT FOR THE LOCK BIT */
+ /* The PLL spec states that the PLL may take up to 100 us to */
+ /* properly lock. Furthermore, the lock signal is not 100% */
+ /* reliable. To address this, we add a hefty delay followed */
+ /* by a polling loop that times out after a 1000 reads. */
+
+ unlock = READ_REG32 (DC3_UNLOCK);
+ for (timeout = 0; timeout < 1280; timeout++)
+ WRITE_REG32 (DC3_UNLOCK, unlock);
+
+ for (timeout = 0; timeout < 1000; timeout++)
+ {
+ msr_read64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DOTPLL, &msr_value);
+ if (msr_value.low & GLCP_DOTPLL_LOCK)
+ break;
+ }
+
+ /* CLEAR THE RESET BIT */
+
+ msr_value.low &= 0xFFFFFFFE;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DOTPLL, &msr_value);
+
+ /* DID THE PLL SUCCESSFULLY LOCK? */
+
+ if (!(msr_value.low & GLCP_DOTPLL_LOCK))
+ return CIM_STATUS_NOLOCK;
+
+ /* RETURN THE APPROPRIATE CODE */
+
+ if (min == 0)
+ return CIM_STATUS_OK;
+ else
+ return CIM_STATUS_INEXACTMATCH;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_border_color
+ *
+ * This routine sets the color used as the border in centered panel modes.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_border_color (unsigned long border_color)
+{
+ unsigned long lock = READ_REG32 (DC3_UNLOCK);
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_PAL_ADDRESS, 0x104);
+ WRITE_REG32 (DC3_PAL_DATA, border_color);
+ WRITE_REG32 (DC3_UNLOCK, lock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_cursor_enable
+ *
+ * This routine enables or disables the hardware cursor. This routine should
+ * only be called after the hardware cursor has been completely configured.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_cursor_enable(int enable)
+{
+ unsigned long unlock, gcfg;
+
+ /* SET OR CLEAR CURSOR ENABLE BIT */
+
+ unlock = READ_REG32(DC3_UNLOCK);
+ gcfg = READ_REG32(DC3_GENERAL_CFG);
+ if (enable) gcfg |= DC3_GCFG_CURE;
+ else gcfg &= ~(DC3_GCFG_CURE);
+
+ /* WRITE NEW REGISTER VALUE */
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+ WRITE_REG32 (DC3_UNLOCK, unlock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_mono_cursor_colors
+ *
+ * This routine sets the colors of the hardware monochrome cursor.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_mono_cursor_colors (unsigned long bkcolor, unsigned long fgcolor)
+{
+ unsigned long lock = READ_REG32 (DC3_UNLOCK);
+
+ /* SET CURSOR COLORS */
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_PAL_ADDRESS, 0x100);
+ WRITE_REG32 (DC3_PAL_DATA, bkcolor);
+ WRITE_REG32 (DC3_PAL_DATA, fgcolor);
+ WRITE_REG32 (DC3_UNLOCK, lock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_cursor_position
+ *
+ * This routine sets the position of the hardware cursor. The cursor hotspots
+ * and memory offset must have been specified in an earlier call to
+ * a vg_set_cursor_shape_XX routine. The coordinates passed to this routine
+ * generally specify the focal point of the cursor, NOT the upper left coordinate of
+ * the cursor pattern. However, for operating systems that do not include a hotspot
+ * the input parameters may be negative.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_cursor_position (long xpos, long ypos, VG_PANNING_COORDINATES *panning)
+{
+ unsigned long unlock, memoffset;
+ unsigned long gcfg;
+ long x, xoffset;
+ long y, yoffset;
+
+ memoffset = vg3_cursor_offset;
+ x = xpos - (long) vg3_x_hotspot;
+ y = ypos - (long) vg3_y_hotspot;
+
+ /* HANDLE NEGATIVE COORDINATES */
+ /* This routine supports operating systems that use negative */
+ /* coordinates, instead of positive coordinates with an appropriate */
+ /* hotspot. */
+
+ if (xpos < 0) xpos = 0;
+ if (ypos < 0) ypos = 0;
+
+ if (x < -63) return CIM_STATUS_INVALIDPARAMS;
+ if (y < -63) return CIM_STATUS_INVALIDPARAMS;
+
+ if (vg3_panel_enable)
+ {
+ if ((vg3_mode_width > vg3_panel_width) || (vg3_mode_height > vg3_panel_height))
+ {
+ vg_pan_desktop (xpos, ypos, panning);
+ x = x - (unsigned short)vg3_delta_x;
+ y = y - (unsigned short)vg3_delta_y;
+ }
+ else
+ {
+ panning->start_x = 0;
+ panning->start_y = 0;
+ panning->start_updated = 0;
+ }
+ }
+
+ /* ADJUST OFFSETS */
+ /* Cursor movement and panning work as follows: The cursor position */
+ /* refers to where the hotspot of the cursor is located. However, for */
+ /* non-zero hotspots, the cursor buffer actually begins before the */
+ /* specified position. */
+
+ if (x < 0) { xoffset = -x; x = 0; }
+ else { xoffset = 0; }
+ if (y < 0) { yoffset = -y; y = 0; }
+ else { yoffset = 0; }
+
+ if (vg3_color_cursor) memoffset += (unsigned long) yoffset * 192;
+ else memoffset += (unsigned long) yoffset << 4;
+
+ /* SET COLOR CURSOR BIT */
+
+ gcfg = READ_REG32(DC3_GENERAL_CFG);
+ if (vg3_color_cursor)
+ gcfg |= DC3_GCFG_CLR_CUR;
+ else
+ gcfg &= ~DC3_GCFG_CLR_CUR;
+
+ /* SET CURSOR POSITION */
+
+ unlock = READ_REG32(DC3_UNLOCK);
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_CURS_ST_OFFSET, memoffset);
+ WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+ WRITE_REG32 (DC3_CURSOR_X, (unsigned long) x |
+ (((unsigned long) xoffset) << 11));
+ WRITE_REG32 (DC3_CURSOR_Y, (unsigned long) y |
+ (((unsigned long) yoffset) << 11));
+ WRITE_REG32 (DC3_UNLOCK, unlock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_mono_cursor_shape32
+ *
+ * This routine loads 32x32 cursor data into the cursor buffer in graphics memory.
+ * The outside of the GeodeLX cursor buffer is padded with transparency.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_mono_cursor_shape32 (unsigned long memoffset, unsigned long *andmask,
+ unsigned long *xormask, unsigned long x_hotspot, unsigned long y_hotspot)
+{
+ int i;
+
+ /* SAVE THE CURSOR OFFSET AND HOTSPOTS */
+ /* These are reused later when updating the cursor position, panning */
+ /* and clipping the cursor pointer. */
+
+ vg3_x_hotspot = x_hotspot;
+ vg3_y_hotspot = y_hotspot;
+ vg3_cursor_offset = memoffset;
+ vg3_color_cursor = 0;
+
+ for (i = 0; i < 32; i++)
+ {
+ /* EVEN QWORDS CONTAIN THE AND MASK */
+
+ WRITE_FB32 (memoffset, 0xFFFFFFFF);
+ WRITE_FB32 (memoffset + 4, andmask[i]);
+
+ /* ODD QWORDS CONTAIN THE XOR MASK */
+
+ WRITE_FB32 (memoffset + 8, 0x00000000);
+ WRITE_FB32 (memoffset + 12, xormask[i]);
+
+ memoffset += 16;
+ }
+
+ /* FILL THE LOWER HALF OF THE BUFFER WITH TRANSPARENT PIXELS */
+
+ for (i = 0; i < 32; i++)
+ {
+ WRITE_FB32 (memoffset, 0xFFFFFFFF);
+ WRITE_FB32 (memoffset + 4, 0xFFFFFFFF);
+ WRITE_FB32 (memoffset + 8, 0x00000000);
+ WRITE_FB32 (memoffset + 12, 0x00000000);
+
+ memoffset += 16;
+ }
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_mono_cursor_shape64
+ *
+ * This routine loads 64x64 cursor data into the cursor buffer in graphics memory.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_mono_cursor_shape64 (unsigned long memoffset, unsigned long *andmask,
+ unsigned long *xormask, unsigned long x_hotspot, unsigned long y_hotspot)
+{
+ int i;
+
+ /* SAVE THE CURSOR OFFSET AND HOTSPOTS */
+ /* These are reused later when updating the cursor position, panning */
+ /* and clipping the cursor pointer. */
+
+ vg3_x_hotspot = x_hotspot;
+ vg3_y_hotspot = y_hotspot;
+ vg3_cursor_offset = memoffset;
+ vg3_color_cursor = 0;
+
+ for (i = 0; i < 128; i += 2)
+ {
+ /* EVEN QWORDS CONTAIN THE AND MASK */
+ /* We invert the dwords to prevent the calling */
+ /* application from having to think in terms of Qwords. */
+ /* The hardware data order is actually 63:0, or 31:0 of */
+ /* the second dword followed by 31:0 of the first dword. */
+
+ WRITE_FB32 (memoffset, andmask[i + 1]);
+ WRITE_FB32 (memoffset + 4, andmask[i]);
+
+ /* ODD QWORDS CONTAIN THE XOR MASK */
+
+ WRITE_FB32 (memoffset + 8, xormask[i + 1]);
+ WRITE_FB32 (memoffset + 12, xormask[i]);
+
+ memoffset += 16;
+ }
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_color_cursor_shape
+ *
+ * This routine loads 8:8:8:8 cursor data into the color cursor buffer.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_color_cursor_shape (unsigned long memoffset, unsigned char *data,
+ unsigned long width, unsigned long height, long pitch,
+ unsigned long x_hotspot, unsigned long y_hotspot)
+{
+ unsigned long y;
+
+ /* SAVE THE CURSOR OFFSET AND HOTSPOTS */
+ /* These are reused later when updating the cursor position, panning */
+ /* and clipping the cursor pointer. */
+
+ vg3_x_hotspot = x_hotspot;
+ vg3_y_hotspot = y_hotspot;
+ vg3_cursor_offset = memoffset;
+ vg3_color_cursor = 1;
+
+ /* WRITE THE CURSOR DATA */
+ /* The outside edges of the color cursor are filled with transparency */
+ /* The cursor buffer dimensions are 48x64. */
+
+ for (y = 0; y < height; y++)
+ {
+ /* WRITE THE ACTIVE AND TRANSPARENT DATA */
+ /* We implement this as a macro in our dedication to squeaking */
+ /* every ounce of performance out of our code... */
+
+ WRITE_FB_STRING32 (memoffset, data, width);
+ WRITE_FB_CONSTANT ((memoffset + (width << 2)), 0, (48 - width));
+
+ /* INCREMENT PAST THE LINE */
+
+ memoffset += 192;
+ data += pitch;
+ }
+
+ /* WRITE THE EXTRA TRANSPARENT LINES */
+ /* Write the lines in one big bulk setting. */
+
+ WRITE_FB_CONSTANT (memoffset, 0, ((64 - height) * 48));
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_pan_desktop
+ *
+ * This routine sets the correct display offset based on the current cursor
+ * position.
+ *---------------------------------------------------------------------------*/
+
+int vg_pan_desktop (unsigned long x, unsigned long y, VG_PANNING_COORDINATES *panning)
+{
+ unsigned long modeShiftPerPixel;
+ unsigned long modeBytesPerScanline;
+ unsigned long startAddress;
+
+ /* TEST FOR NO-WORK */
+
+ if (x >= vg3_delta_x && x < (vg3_panel_width + vg3_delta_x) &&
+ y >= vg3_delta_y && y < (vg3_panel_height + vg3_delta_y))
+ {
+ panning->start_x = vg3_delta_x;
+ panning->start_y = vg3_delta_y;
+ panning->start_updated = 0;
+ return CIM_STATUS_OK;
+ }
+
+ if (vg3_bpp == 24) modeShiftPerPixel = 2;
+ else modeShiftPerPixel = (vg3_bpp + 7) >> 4;
+
+ modeBytesPerScanline = (READ_REG32 (DC3_GFX_PITCH) & 0x0000FFFF) << 3;
+
+ /* ADJUST PANNING VARIABLES WHEN CURSOR EXCEEDS BOUNDARY */
+ /* Test the boundary conditions for each coordinate and update */
+ /* all variables and the starting offset accordingly. */
+
+ if (x < vg3_delta_x)
+ vg3_delta_x = x;
+
+ else if (x >= (vg3_delta_x + vg3_panel_width))
+ vg3_delta_x = x - vg3_panel_width + 1;
+
+ if (y < vg3_delta_y)
+ vg3_delta_y = y;
+
+ else if (y >= (vg3_delta_y + vg3_panel_height))
+ vg3_delta_y = y - vg3_panel_height + 1;
+
+ /* CALCULATE THE START OFFSET */
+
+ startAddress = (vg3_delta_x << modeShiftPerPixel) + (vg3_delta_y * modeBytesPerScanline);
+
+ vg_set_display_offset (startAddress);
+
+ panning->start_updated = 1;
+ panning->start_x = vg3_delta_x;
+ panning->start_y = vg3_delta_y;
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_display_offset
+ *
+ * This routine sets the start address of the frame buffer. It is
+ * typically used to pan across a virtual desktop (frame buffer larger than
+ * the displayed screen) or to flip the display between multiple buffers.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_display_offset (unsigned long address)
+{
+ unsigned long lock, gcfg;
+
+ lock = READ_REG32 (DC3_UNLOCK);
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+ /* DISABLE COMPRESSION */
+ /* When setting a non-zero display offset, we must disable display */
+ /* compression. We could maintain a variable and re-enable */
+ /* compression when the offset returns to zero. However, that */
+ /* creates additional complexity for applications that perform */
+ /* graphics animation. Re-enabling compression each time would */
+ /* be tedious and slow for such applications, implying that they */
+ /* would have to disable compression before starting the animation. */
+ /* We will instead disable compression and force the user to */
+ /* re-enable compression when they are ready. */
+
+ if (address != 0)
+ {
+ if (READ_REG32 (DC3_GENERAL_CFG) & DC3_GCFG_CMPE)
+ {
+ gcfg = READ_REG32 (DC3_GENERAL_CFG);
+ WRITE_REG32 (DC3_GENERAL_CFG, (gcfg & ~(DC3_GCFG_CMPE | DC3_GCFG_DECE)));
+ }
+ }
+
+ WRITE_REG32 (DC3_FB_ST_OFFSET, address);
+ WRITE_REG32 (DC3_UNLOCK, lock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_display_pitch
+ *
+ * This routine sets the stride between successive lines of data in the frame
+ * buffer.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_display_pitch (unsigned long pitch)
+{
+ unsigned long temp, dvsize, dvtop, value;
+ unsigned long lock = READ_REG32(DC3_UNLOCK);
+
+ value = READ_REG32(DC3_GFX_PITCH) & 0xFFFF0000;
+ value |= (pitch >> 3);
+
+ /* PROGRAM THE DISPLAY PITCH */
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_GFX_PITCH, value);
+
+ /* SET THE COMPRESSION BEHAVIOR BASED ON THE PITCH */
+ /* Strides that are not a power of two will not work with line */
+ /* by line compression. For these cases, we enable full-screen */
+ /* compression. In this mode, any write to the frame buffer */
+ /* region marks the entire frame as dirty. Also, the DV line */
+ /* size must be updated when the pitch is programmed outside of */
+ /* the power of 2 range specified in a mode set. */
+
+ if (pitch > 4096) { dvsize = DC3_DV_LINE_SIZE_8192; }
+ else if (pitch > 2048) { dvsize = DC3_DV_LINE_SIZE_4096; }
+ else if (pitch > 1024) { dvsize = DC3_DV_LINE_SIZE_2048; }
+ else { dvsize = DC3_DV_LINE_SIZE_1024; }
+
+ temp = READ_REG32 (DC3_DV_CTL);
+ WRITE_REG32 (DC3_DV_CTL, (temp & ~DC3_DV_LINE_SIZE_MASK) | dvsize | 0x00000001);
+
+ value = READ_REG32 (DC3_GENERAL_CFG);
+
+ if (pitch == 1024 || pitch == 2048 || pitch == 4096 || pitch == 8192)
+ {
+ value &= ~DC3_GCFG_FDTY;
+ dvtop = 0;
+ }
+ else
+ {
+ value |= DC3_GCFG_FDTY;
+
+ dvtop = (READ_REG32 (DC3_FB_ACTIVE) & 0xFFF) + 1;
+ dvtop = ((dvtop * pitch) + 0x3FF) & 0xFFFFFC00;
+ dvtop |= DC3_DVTOP_ENABLE;
+ }
+
+ WRITE_REG32 (DC3_GENERAL_CFG, value);
+ WRITE_REG32 (DC3_DV_TOP, dvtop);
+ WRITE_REG32 (DC3_UNLOCK, lock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_display_palette_entry
+ *
+ * This routine sets a single 8BPP palette entry in the display controller.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_display_palette_entry (unsigned long index, unsigned long palette)
+{
+ unsigned long dcfg, unlock;
+
+ if (index > 0xFF)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ unlock = READ_REG32 (DC3_UNLOCK);
+ dcfg = READ_REG32 (DC3_DISPLAY_CFG);
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_DISPLAY_CFG, dcfg & ~DC3_DCFG_PALB);
+ WRITE_REG32 (DC3_UNLOCK, unlock);
+
+ WRITE_REG32 (DC3_PAL_ADDRESS, index);
+ WRITE_REG32 (DC3_PAL_DATA, palette);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_display_palette
+ *
+ * This routine sets the entire palette in the display controller.
+ * A pointer is provided to a 256 entry table of 32-bit X:R:G:B values.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_display_palette (unsigned long *palette)
+{
+ unsigned long unlock, dcfg, i;
+ WRITE_REG32 (DC3_PAL_ADDRESS, 0);
+
+ if (palette)
+ {
+ unlock = READ_REG32 (DC3_UNLOCK);
+ dcfg = READ_REG32 (DC3_DISPLAY_CFG);
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_DISPLAY_CFG, dcfg & ~DC3_DCFG_PALB);
+ WRITE_REG32 (DC3_UNLOCK, unlock);
+
+ for (i = 0; i < 256; i++)
+ WRITE_REG32 (DC3_PAL_DATA, palette[i]);
+
+ return CIM_STATUS_OK;
+ }
+ return CIM_STATUS_INVALIDPARAMS;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_set_compression_enable
+ *
+ * This routine enables or disables display compression.
+ *---------------------------------------------------------------------------*/
+
+int vg_set_compression_enable (int enable)
+{
+ Q_WORD msr_value;
+ unsigned long unlock, gcfg;
+ unsigned long temp;
+
+ unlock = READ_REG32 (DC3_UNLOCK);
+ gcfg = READ_REG32 (DC3_GENERAL_CFG);
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+ if (enable)
+ {
+ /* DO NOT ENABLE IF THE DISPLAY OFFSET IS NOT ZERO */
+
+ if (READ_REG32 (DC3_FB_ST_OFFSET) & 0x0FFFFFFF)
+ return CIM_STATUS_ERROR;
+
+ /* ENABLE BIT 1 IN THE VG SPARE MSR */
+ /* The bus can hang when the VG attempts to merge compression writes. */
+ /* No performance is lost due to the GeodeLink QUACK features in */
+ /* GeodeLX. We also enable the command word check for a valid */
+ /* compression header. */
+
+ msr_read64 (MSR_DEVICE_GEODELX_VG, DC3_SPARE_MSR, &msr_value);
+ msr_value.low |= DC3_SPARE_FIRST_REQ_MASK;
+ msr_value.low &= ~DC3_SPARE_DISABLE_CWD_CHECK;
+ msr_write64 (MSR_DEVICE_GEODELX_VG, DC3_SPARE_MSR, &msr_value);
+
+ /* CLEAR DIRTY/VALID BITS IN MEMORY CONTROLLER */
+ /* We don't want the controller to think that old lines are still */
+ /* valid. Writing a 1 to bit 0 of the DV Control register will force */
+ /* the hardware to clear all the valid bits. */
+
+ temp = READ_REG32 (DC3_DV_CTL);
+ WRITE_REG32 (DC3_DV_CTL, temp | 0x00000001);
+
+ /* ENABLE COMPRESSION BITS */
+
+ gcfg |= DC3_GCFG_CMPE | DC3_GCFG_DECE;
+ }
+ else
+ {
+ gcfg &= ~(DC3_GCFG_CMPE | DC3_GCFG_DECE);
+ }
+
+ WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+ WRITE_REG32 (DC3_UNLOCK, unlock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_configure_compression
+ *
+ * This routine configures all aspects of display compression, including pitch,
+ * size and the offset of the compression buffer.
+ *---------------------------------------------------------------------------*/
+
+int vg_configure_compression (VG_COMPRESSION_DATA *comp_data)
+{
+ unsigned long delta, size;
+ unsigned long comp_size, unlock;
+
+ /* CHECK FOR VALID PARAMETERS */
+ /* The maximum size for the compression buffer is 544 bytes (with */
+ /* the header) Also, the pitch cannot be less than the line size */
+ /* and the compression buffer offset must be 16-byte aligned. */
+
+ if (comp_data->size > 544 || comp_data->pitch < comp_data->size ||
+ comp_data->compression_offset & 0x0F)
+ {
+ return CIM_STATUS_INVALIDPARAMS;
+ }
+
+ /* SUBTRACT 32 FROM SIZE */
+ /* The display controller will actually write 4 extra QWords. So, */
+ /* if we assume that "size" refers to the allocated size, we must */
+ /* subtract 32 bytes. */
+
+ comp_size = comp_data->size - 32;
+
+ /* CALCULATE REGISTER VALUES */
+
+ unlock = READ_REG32 (DC3_UNLOCK);
+ size = READ_REG32 (DC3_LINE_SIZE) & ~DC3_LINE_SIZE_CBLS_MASK;
+ delta = READ_REG32 (DC3_GFX_PITCH) & ~DC3_GFX_PITCH_CBP_MASK;
+
+ size |= ((comp_size >> 3) + 1) << DC3_LINE_SIZE_CB_SHIFT;
+ delta |= ((comp_data->pitch >> 3) << 16);
+
+ /* WRITE COMPRESSION PARAMETERS */
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_CB_ST_OFFSET, comp_data->compression_offset);
+ WRITE_REG32 (DC3_LINE_SIZE, size);
+ WRITE_REG32 (DC3_GFX_PITCH, delta);
+ WRITE_REG32 (DC3_UNLOCK, unlock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_test_timing_active
+ *
+ * This routine checks the status of the display timing generator.
+ *---------------------------------------------------------------------------*/
+
+int vg_test_timing_active (void)
+{
+ if (READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_TGEN)
+ return 1;
+
+ return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_test_vertical_active
+ *
+ * This routine checks if the display is currently in the middle of a frame
+ * (not in the VBlank interval)
+ *---------------------------------------------------------------------------*/
+
+int vg_test_vertical_active (void)
+{
+ if (READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA)
+ return 0;
+
+ return 1;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_wait_vertical_blank
+ *
+ * This routine waits until the beginning of the vertical blank interval.
+ * When the display is already in vertical blank, this routine will wait until
+ * the beginning of the next vertical blank.
+ *---------------------------------------------------------------------------*/
+
+int vg_wait_vertical_blank(void)
+{
+ if (vg_test_timing_active())
+ {
+ while (!vg_test_vertical_active());
+ while (vg_test_vertical_active());
+ }
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_test_even_field
+ *
+ * This routine tests the odd/even status of the current VG output field.
+ *---------------------------------------------------------------------------*/
+
+int vg_test_even_field(void)
+{
+ if (READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_EVEN_FIELD)
+ return 1;
+
+ return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_configure_line_interrupt
+ *
+ * This routine configures the display controller's line count interrupt. This
+ * interrupt can be used to interrupt mid-frame or to interrupt at the beginning
+ * of vertical blank.
+ *---------------------------------------------------------------------------*/
+
+int vg_configure_line_interrupt (VG_INTERRUPT_PARAMS *interrupt_info)
+{
+ unsigned long irq_line, irq_enable;
+ unsigned long lock;
+
+ irq_line = READ_REG32 (DC3_IRQ_FILT_CTL);
+ irq_enable = READ_REG32 (DC3_IRQ);
+ lock = READ_REG32 (DC3_UNLOCK);
+
+ irq_line = (irq_line & ~DC3_IRQFILT_LINE_MASK) | ((interrupt_info->line << 16) & DC3_IRQFILT_LINE_MASK);
+
+ /* ENABLE OR DISABLE THE INTERRUPT */
+ /* The line count is set before enabling and after disabling to */
+ /* minimize spurious interrupts. The line count is set even */
+ /* when interrupts are disabled to allow polling-based or debug */
+ /* applications. */
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ if (interrupt_info->enable)
+ {
+ WRITE_REG32 (DC3_IRQ_FILT_CTL, irq_line);
+ WRITE_REG32 (DC3_IRQ, ((irq_enable & ~DC3_IRQ_MASK) | DC3_IRQ_STATUS));
+ }
+ else
+ {
+ WRITE_REG32 (DC3_IRQ, (irq_enable | DC3_IRQ_MASK));
+ WRITE_REG32 (DC3_IRQ_FILT_CTL, irq_line);
+ }
+ WRITE_REG32 (DC3_UNLOCK, lock);
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_test_and_clear_interrupt
+ *
+ * This routine resets any pending interrupt in the video generator. The return
+ * value indicates the interrupt status prior to the reset.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vg_test_and_clear_interrupt (void)
+{
+ unsigned long irq_enable;
+ unsigned long lock;
+
+ irq_enable = READ_REG32 (DC3_IRQ);
+ lock = READ_REG32 (DC3_UNLOCK);
+
+ /* NO ACTION IF INTERRUPTS ARE MASKED */
+ /* We are assuming that a driver or application will not want to receive */
+ /* the status of the interrupt when it is masked. */
+
+ if ((irq_enable & (DC3_IRQ_MASK | DC3_VSYNC_IRQ_MASK)) == (DC3_IRQ_MASK | DC3_VSYNC_IRQ_MASK))
+ return 0;
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_IRQ, irq_enable);
+ WRITE_REG32 (DC3_UNLOCK, lock);
+
+ return (irq_enable & (DC3_IRQ_STATUS | DC3_VSYNC_IRQ_STATUS));
+}
+
+/*---------------------------------------------------------------------------
+ * vg_test_flip_status
+ *
+ * This routine tests if a new display offset has been latched.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vg_test_flip_status (void)
+{
+ return (READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_FLIP);
+}
+
+/*---------------------------------------------------------------------------
+ * vg_save_state
+ *
+ * This routine saves all persistent VG state information.
+ *---------------------------------------------------------------------------*/
+
+int vg_save_state (VG_SAVE_RESTORE *vg_state)
+{
+ Q_WORD msr_value;
+ unsigned long irqfilt;
+ unsigned long offset, i;
+ unsigned long lock;
+
+ /* READ ALL CURRENT REGISTER SETTINGS */
+
+ vg_state->unlock = READ_REG32 (DC3_UNLOCK);
+ vg_state->gcfg = READ_REG32 (DC3_GENERAL_CFG);
+ vg_state->dcfg = READ_REG32 (DC3_DISPLAY_CFG);
+ vg_state->arb_cfg = READ_REG32 (DC3_ARB_CFG);
+ vg_state->fb_offset = READ_REG32 (DC3_FB_ST_OFFSET);
+ vg_state->cb_offset = READ_REG32 (DC3_CB_ST_OFFSET);
+ vg_state->cursor_offset = READ_REG32 (DC3_CURS_ST_OFFSET);
+ vg_state->video_y_offset = READ_REG32 (DC3_VID_Y_ST_OFFSET);
+ vg_state->video_u_offset = READ_REG32 (DC3_VID_U_ST_OFFSET);
+ vg_state->video_v_offset = READ_REG32 (DC3_VID_V_ST_OFFSET);
+ vg_state->dv_top = READ_REG32 (DC3_DV_TOP);
+ vg_state->line_size = READ_REG32 (DC3_LINE_SIZE);
+ vg_state->gfx_pitch = READ_REG32 (DC3_GFX_PITCH);
+ vg_state->video_yuv_pitch = READ_REG32 (DC3_VID_YUV_PITCH);
+ vg_state->h_active = READ_REG32 (DC3_H_ACTIVE_TIMING);
+ vg_state->h_blank = READ_REG32 (DC3_H_BLANK_TIMING);
+ vg_state->h_sync = READ_REG32 (DC3_H_SYNC_TIMING);
+ vg_state->v_active = READ_REG32 (DC3_V_ACTIVE_TIMING);
+ vg_state->v_blank = READ_REG32 (DC3_V_BLANK_TIMING);
+ vg_state->v_sync = READ_REG32 (DC3_V_SYNC_TIMING);
+ vg_state->fb_active = READ_REG32 (DC3_FB_ACTIVE);
+ vg_state->cursor_x = READ_REG32 (DC3_CURSOR_X);
+ vg_state->cursor_y = READ_REG32 (DC3_CURSOR_Y);
+ vg_state->vid_ds_delta = READ_REG32 (DC3_VID_DS_DELTA);
+ vg_state->fb_base = READ_REG32 (DC3_PHY_MEM_OFFSET);
+ vg_state->dv_ctl = READ_REG32 (DC3_DV_CTL);
+ vg_state->gfx_scale = READ_REG32 (DC3_GFX_SCALE);
+ vg_state->irq_ctl = READ_REG32 (DC3_IRQ_FILT_CTL);
+ vg_state->vbi_even_ctl = READ_REG32 (DC3_VBI_EVEN_CTL);
+ vg_state->vbi_odd_ctl = READ_REG32 (DC3_VBI_ODD_CTL);
+ vg_state->vbi_hor_ctl = READ_REG32 (DC3_VBI_HOR);
+ vg_state->vbi_odd_line_enable = READ_REG32 (DC3_VBI_LN_ODD);
+ vg_state->vbi_even_line_enable = READ_REG32 (DC3_VBI_LN_EVEN);
+ vg_state->vbi_pitch = READ_REG32 (DC3_VBI_PITCH);
+ vg_state->color_key = READ_REG32 (DC3_COLOR_KEY);
+ vg_state->color_key_mask = READ_REG32 (DC3_COLOR_MASK);
+ vg_state->color_key_x = READ_REG32 (DC3_CLR_KEY_X);
+ vg_state->color_key_y = READ_REG32 (DC3_CLR_KEY_Y);
+ vg_state->irq = READ_REG32 (DC3_IRQ);
+ vg_state->genlk_ctl = READ_REG32 (DC3_GENLK_CTL);
+ vg_state->vid_y_even_offset = READ_REG32 (DC3_VID_EVEN_Y_ST_OFFSET);
+ vg_state->vid_u_even_offset = READ_REG32 (DC3_VID_EVEN_U_ST_OFFSET);
+ vg_state->vid_v_even_offset = READ_REG32 (DC3_VID_EVEN_V_ST_OFFSET);
+ vg_state->vactive_even = READ_REG32 (DC3_V_ACTIVE_EVEN);
+ vg_state->vblank_even = READ_REG32 (DC3_V_BLANK_EVEN);
+ vg_state->vsync_even = READ_REG32 (DC3_V_SYNC_EVEN);
+
+ /* READ THE CURRENT PALETTE */
+
+ lock = READ_REG32 (DC3_UNLOCK);
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_PAL_ADDRESS, 0);
+ for (i = 0; i < 261; i++)
+ vg_state->palette[i] = READ_REG32 (DC3_PAL_DATA);
+
+ /* READ THE CURRENT FILTER COEFFICIENTS */
+
+ /* ENABLE ACCESS TO THE HORIZONTAL COEFFICIENTS */
+
+ irqfilt = READ_REG32 (DC3_IRQ_FILT_CTL);
+ irqfilt |= DC3_IRQFILT_H_FILT_SEL;
+
+ /* READ HORIZONTAL COEFFICIENTS */
+
+ for (i = 0; i < 256; i++)
+ {
+ WRITE_REG32 (DC3_IRQ_FILT_CTL, ((irqfilt & 0xFFFFFF00L) | i));
+
+ vg_state->h_coeff[(i << 1)] = READ_REG32 (DC3_FILT_COEFF1);
+ vg_state->h_coeff[(i << 1) + 1] = READ_REG32 (DC3_FILT_COEFF2);
+ }
+
+ /* ENABLE ACCESS TO THE VERTICAL COEFFICIENTS */
+
+ irqfilt &= ~DC3_IRQFILT_H_FILT_SEL;
+
+ /* READ COEFFICIENTS */
+
+ for (i = 0; i < 256; i++)
+ {
+ WRITE_REG32 (DC3_IRQ_FILT_CTL, ((irqfilt & 0xFFFFFF00L) | i));
+
+ vg_state->v_coeff[i] = READ_REG32 (DC3_FILT_COEFF1);
+ }
+
+ /* READ THE CURSOR DATA */
+
+ offset = READ_REG32 (DC3_CURS_ST_OFFSET) & 0x0FFFFFFF;
+ for (i = 0; i < 3072; i++)
+ vg_state->cursor_data[i] = READ_FB32 (offset + (i << 2));
+
+ /* READ THE CURRENT PLL */
+
+ msr_read64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DOTPLL, &msr_value);
+
+ vg_state->pll_flags = 0;
+ for (i = 0; i < NUM_CIMARRON_PLL_FREQUENCIES; i++)
+ {
+ if (CimarronPLLFrequencies[i].pll_value == (msr_value.high & 0x7FFF))
+ {
+ vg_state->dot_pll = CimarronPLLFrequencies[i].frequency;
+ break;
+ }
+ }
+
+ if (i == NUM_CIMARRON_PLL_FREQUENCIES)
+ {
+ /* NO MATCH */
+ /* Enter the frequency as a manual frequency. */
+
+ vg_state->dot_pll = msr_value.high;
+ vg_state->pll_flags |= VG_PLL_MANUAL;
+ }
+ if (msr_value.low & GLCP_DOTPLL_HALFPIX)
+ vg_state->pll_flags |= VG_PLL_DIVIDE_BY_2;
+ if (msr_value.low & GLCP_DOTPLL_BYPASS)
+ vg_state->pll_flags |= VG_PLL_BYPASS;
+ if (msr_value.high & GLCP_DOTPLL_DIV4)
+ vg_state->pll_flags |= VG_PLL_DIVIDE_BY_4;
+ if (msr_value.high & GLCP_DOTPLL_VIPCLK)
+ vg_state->pll_flags |= VG_PLL_VIP_CLOCK;
+
+ /* READ ALL VG MSRS */
+
+ msr_read64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_CAP, &(vg_state->msr_cap));
+ msr_read64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_CONFIG, &(vg_state->msr_config));
+ msr_read64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_SMI, &(vg_state->msr_smi));
+ msr_read64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_ERROR, &(vg_state->msr_error));
+ msr_read64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_PM, &(vg_state->msr_pm));
+ msr_read64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_DIAG, &(vg_state->msr_diag));
+ msr_read64 (MSR_DEVICE_GEODELX_VG, DC3_SPARE_MSR, &(vg_state->msr_spare));
+ msr_read64 (MSR_DEVICE_GEODELX_VG, DC3_RAM_CTL, &(vg_state->msr_ram_ctl));
+
+ WRITE_REG32 (DC3_UNLOCK, lock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_restore_state
+ *
+ * This routine restores all persistent VG state information.
+ *---------------------------------------------------------------------------*/
+
+int vg_restore_state (VG_SAVE_RESTORE *vg_state)
+{
+ unsigned long irqfilt, i;
+ unsigned long memoffset;
+
+ /* TEMPORARILY UNLOCK ALL REGISTERS */
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+ /* RESTORE THE FRAME BUFFER OFFSET */
+
+ WRITE_REG32 (DC3_PHY_MEM_OFFSET, vg_state->fb_base);
+
+ /* BLANK GCFG AND DCFG */
+
+ WRITE_REG32 (DC3_GENERAL_CFG, 0);
+ WRITE_REG32 (DC3_DISPLAY_CFG, 0);
+
+ /* RESTORE ALL REGISTERS */
+
+ WRITE_REG32 (DC3_ARB_CFG, vg_state->arb_cfg);
+ WRITE_REG32 (DC3_FB_ST_OFFSET, vg_state->fb_offset);
+ WRITE_REG32 (DC3_CB_ST_OFFSET, vg_state->cb_offset);
+ WRITE_REG32 (DC3_CURS_ST_OFFSET, vg_state->cursor_offset);
+ WRITE_REG32 (DC3_VID_Y_ST_OFFSET, vg_state->video_y_offset);
+ WRITE_REG32 (DC3_VID_U_ST_OFFSET, vg_state->video_u_offset);
+ WRITE_REG32 (DC3_VID_V_ST_OFFSET, vg_state->video_v_offset);
+ WRITE_REG32 (DC3_DV_TOP, vg_state->dv_top);
+ WRITE_REG32 (DC3_LINE_SIZE, vg_state->line_size);
+ WRITE_REG32 (DC3_GFX_PITCH, vg_state->gfx_pitch);
+ WRITE_REG32 (DC3_VID_YUV_PITCH, vg_state->video_yuv_pitch);
+ WRITE_REG32 (DC3_H_ACTIVE_TIMING, vg_state->h_active);
+ WRITE_REG32 (DC3_H_BLANK_TIMING, vg_state->h_blank);
+ WRITE_REG32 (DC3_H_SYNC_TIMING, vg_state->h_sync);
+ WRITE_REG32 (DC3_V_ACTIVE_TIMING, vg_state->v_active);
+ WRITE_REG32 (DC3_V_BLANK_TIMING, vg_state->v_blank);
+ WRITE_REG32 (DC3_V_SYNC_TIMING, vg_state->v_sync);
+ WRITE_REG32 (DC3_FB_ACTIVE, vg_state->fb_active);
+ WRITE_REG32 (DC3_CURSOR_X, vg_state->cursor_x);
+ WRITE_REG32 (DC3_CURSOR_Y, vg_state->cursor_y);
+ WRITE_REG32 (DC3_VID_DS_DELTA, vg_state->vid_ds_delta);
+ WRITE_REG32 (DC3_PHY_MEM_OFFSET, vg_state->fb_base);
+ WRITE_REG32 (DC3_DV_CTL, vg_state->dv_ctl | 0x00000001);
+ WRITE_REG32 (DC3_GFX_SCALE, vg_state->gfx_scale);
+ WRITE_REG32 (DC3_IRQ_FILT_CTL, vg_state->irq_ctl);
+ WRITE_REG32 (DC3_VBI_EVEN_CTL, vg_state->vbi_even_ctl);
+ WRITE_REG32 (DC3_VBI_ODD_CTL, vg_state->vbi_odd_ctl);
+ WRITE_REG32 (DC3_VBI_HOR, vg_state->vbi_hor_ctl);
+ WRITE_REG32 (DC3_VBI_LN_ODD, vg_state->vbi_odd_line_enable);
+ WRITE_REG32 (DC3_VBI_LN_EVEN, vg_state->vbi_even_line_enable);
+ WRITE_REG32 (DC3_VBI_PITCH, vg_state->vbi_pitch);
+ WRITE_REG32 (DC3_COLOR_KEY, vg_state->color_key);
+ WRITE_REG32 (DC3_COLOR_MASK, vg_state->color_key_mask);
+ WRITE_REG32 (DC3_CLR_KEY_X, vg_state->color_key_x);
+ WRITE_REG32 (DC3_CLR_KEY_Y, vg_state->color_key_y);
+ WRITE_REG32 (DC3_IRQ, vg_state->irq);
+ WRITE_REG32 (DC3_GENLK_CTL, vg_state->genlk_ctl);
+ WRITE_REG32 (DC3_VID_EVEN_Y_ST_OFFSET, vg_state->vid_y_even_offset);
+ WRITE_REG32 (DC3_VID_EVEN_U_ST_OFFSET, vg_state->vid_u_even_offset);
+ WRITE_REG32 (DC3_VID_EVEN_V_ST_OFFSET, vg_state->vid_v_even_offset);
+ WRITE_REG32 (DC3_V_ACTIVE_EVEN, vg_state->vactive_even);
+ WRITE_REG32 (DC3_V_BLANK_EVEN, vg_state->vblank_even);
+ WRITE_REG32 (DC3_V_SYNC_EVEN, vg_state->vsync_even);
+
+ /* RESTORE THE PALETTE */
+
+ WRITE_REG32 (DC3_PAL_ADDRESS, 0);
+ for (i = 0; i < 261; i++)
+ WRITE_REG32 (DC3_PAL_DATA, vg_state->palette[i]);
+
+ /* RESTORE THE HORIZONTAL FILTER COEFFICIENTS */
+
+ irqfilt = READ_REG32 (DC3_IRQ_FILT_CTL);
+ irqfilt |= DC3_IRQFILT_H_FILT_SEL;
+
+ for (i = 0; i < 256; i++)
+ {
+ WRITE_REG32 (DC3_IRQ_FILT_CTL, ((irqfilt & 0xFFFFFF00L) | i));
+ WRITE_REG32 (DC3_FILT_COEFF1, vg_state->h_coeff[(i << 1)]);
+ WRITE_REG32 (DC3_FILT_COEFF2, vg_state->h_coeff[(i << 1) + 1]);
+ }
+
+ /* RESTORE VERTICAL COEFFICIENTS */
+
+ irqfilt &= ~DC3_IRQFILT_H_FILT_SEL;
+
+ for (i = 0; i < 256; i++)
+ {
+ WRITE_REG32 (DC3_IRQ_FILT_CTL, ((irqfilt & 0xFFFFFF00L) | i));
+ WRITE_REG32 (DC3_FILT_COEFF1, vg_state->v_coeff[i]);
+ }
+
+ /* RESTORE THE CURSOR DATA */
+
+ memoffset = READ_REG32 (DC3_CURS_ST_OFFSET) & 0x0FFFFFFF;
+ WRITE_FB_STRING32 (memoffset, (unsigned char *)&(vg_state->cursor_data[0]), 3072);
+
+ /* RESTORE THE PLL */
+ /* Use a common routine to use common code to poll for lock bit */
+
+ vg_set_clock_frequency (vg_state->dot_pll, vg_state->pll_flags);
+
+ /* RESTORE ALL VG MSRS */
+
+ msr_write64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_CAP, &(vg_state->msr_cap));
+ msr_write64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_CONFIG, &(vg_state->msr_config));
+ msr_write64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_SMI, &(vg_state->msr_smi));
+ msr_write64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_ERROR, &(vg_state->msr_error));
+ msr_write64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_PM, &(vg_state->msr_pm));
+ msr_write64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_DIAG, &(vg_state->msr_diag));
+ msr_write64 (MSR_DEVICE_GEODELX_VG, DC3_SPARE_MSR, &(vg_state->msr_spare));
+ msr_write64 (MSR_DEVICE_GEODELX_VG, DC3_RAM_CTL, &(vg_state->msr_ram_ctl));
+
+ /* NOW RESTORE GCFG AND DCFG */
+
+ WRITE_REG32 (DC3_DISPLAY_CFG, vg_state->dcfg);
+ WRITE_REG32 (DC3_GENERAL_CFG, vg_state->gcfg);
+
+ /* FINALLY RESTORE UNLOCK */
+
+ WRITE_REG32 (DC3_UNLOCK, vg_state->unlock);
+
+ return CIM_STATUS_OK;
+}
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * CIMARRON VG READ ROUTINES
+ * These routines are included for use in diagnostics or when debugging. They
+ * can be optionally excluded from a project.
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+#if CIMARRON_INCLUDE_VG_READ_ROUTINES
+
+/*---------------------------------------------------------------------------
+ * vg_read_graphics_crc
+ *
+ * This routine reads the Cyclic Redundancy Check (CRC) value for the graphics
+ * frame.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vg_read_graphics_crc (int crc_source)
+{
+ unsigned long gcfg, unlock;
+ unsigned long crc, vbi_even;
+ unsigned long interlaced;
+ unsigned long line, field;
+
+ if (!(READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_TGEN))
+ return 0xFFFFFFFF;
+
+ unlock = READ_REG32 (DC3_UNLOCK);
+ gcfg = READ_REG32 (DC3_GENERAL_CFG);
+ vbi_even = READ_REG32 (DC3_VBI_EVEN_CTL);
+
+ vbi_even &= ~DC3_VBI_EVEN_ENABLE_CRC;
+
+ gcfg |= DC3_GCFG_SGRE | DC3_GCFG_CRC_MODE;
+ gcfg &= ~(DC3_GCFG_SGFR | DC3_GCFG_SIG_SEL | DC3_GCFG_FILT_SIG_SEL);
+
+ switch (crc_source)
+ {
+ case VG_CRC_SOURCE_PREFILTER_EVEN:
+ case VG_CRC_SOURCE_PREFILTER: gcfg |= DC3_GCFG_SIG_SEL; break;
+ case VG_CRC_SOURCE_PREFLICKER:
+ case VG_CRC_SOURCE_PREFLICKER_EVEN: gcfg |= DC3_GCFG_FILT_SIG_SEL; break;
+ case VG_CRC_SOURCE_POSTFLICKER:
+ case VG_CRC_SOURCE_POSTFLICKER_EVEN: /* NO WORK */ break;
+
+ default:
+ return 0xFFFFFFFF;
+ }
+
+ if (crc_source & VG_CRC_SOURCE_EVEN) field = 0;
+ else field = DC3_LNCNT_EVEN_FIELD;
+
+ if ((interlaced = (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)))
+ {
+ /* WAIT FOR THE BEGINNING OF THE FIELD (LINE 1-5) */
+ /* Note that we wait for the field to be odd when CRCing the even */
+ /* field and vice versa. This is because the CRC will not begin */
+ /* until the following field. */
+
+ do
+ {
+ line = READ_REG32 (DC3_LINE_CNT_STATUS);
+ } while ((line & DC3_LNCNT_EVEN_FIELD) != field ||
+ ((line & DC3_LNCNT_V_LINE_CNT) >> 16) < 10 ||
+ ((line & DC3_LNCNT_V_LINE_CNT) >> 16) > 15);
+ }
+ else
+ {
+ /* NON-INTERLACED - EVEN FIELD CRCS ARE INVALID */
+
+ if (crc_source & VG_CRC_SOURCE_EVEN)
+ return 0xFFFFFFFF;
+ }
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_VBI_EVEN_CTL, vbi_even);
+ WRITE_REG32 (DC3_GENERAL_CFG, gcfg & ~DC3_GCFG_SIGE);
+ WRITE_REG32 (DC3_GENERAL_CFG, gcfg | DC3_GCFG_SIGE);
+
+ /* WAIT FOR THE CRC TO BE COMPLETED */
+
+ while (!(READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_SIGC))
+ ;
+
+ /* READ THE COMPLETED CRC */
+
+ crc = READ_REG32 (DC3_PAL_DATA);
+
+ /* RESTORE THE PALETTE SETTINGS */
+
+ gcfg &= ~DC3_GCFG_SGRE;
+ WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+ WRITE_REG32 (DC3_UNLOCK, unlock);
+
+ return crc;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_read_window_crc
+ *
+ * This routine reads the Cyclic Redundancy Check (CRC) value for a sub-section
+ * of the frame.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vg_read_window_crc (int crc_source, unsigned long x, unsigned long y,
+ unsigned long width, unsigned long height)
+{
+ Q_WORD msr_value;
+ unsigned long crc = 0;
+ unsigned long hactive, hblankstart;
+ unsigned long htotal, hblankend;
+ unsigned long line, field;
+ unsigned long diag;
+
+ hactive = ((READ_REG32 (DC3_H_ACTIVE_TIMING)) & 0xFFF) + 1;
+ hblankstart = ((READ_REG32 (DC3_H_BLANK_TIMING)) & 0xFFF) + 1;
+ htotal = ((READ_REG32 (DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+ hblankend = ((READ_REG32 (DC3_H_BLANK_TIMING) >> 16) & 0xFFF) + 1;
+
+ /* TIMINGS MUST BE ACTIVE */
+
+ if (!(READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_TGEN))
+ return 0xFFFFFFFF;
+
+ /* DISABLE GLCP ACTIONS */
+
+ msr_value.low = 0;
+ msr_value.high = 0;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DIAGCTL, &msr_value);
+
+ if ((x == 0 && width == 1) || x == 1)
+ {
+ /* SPECIAL CASE FOR X == 0 */
+ /* The comparator output is a clock late in the MCP, so we cannot */
+ /* easily catch the first pixel. If the first pixel is desired, */
+ /* we will insert a special state machine to CRC just the first */
+ /* pixel. */
+
+ /* N2 - DISPE HIGH AND Y == 1 */
+ /* Goto state YState = 2 */
+
+ msr_value.high = 0x00000002;
+ msr_value.low = 0x00000C00;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL + 2, &msr_value);
+
+ /* M3 - DISPE HIGH AND Y == 0 */
+ /* Goto YState = 1 */
+
+ msr_value.high = 0x00000002;
+ msr_value.low = 0x00000A00;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETM0CTL + 3, &msr_value);
+
+ /* N3 - DISPE LOW */
+ /* Goto YState = 0 */
+
+ msr_value.high = 0x00080000;
+ msr_value.low = 0x00000000;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL + 3, &msr_value);
+
+ /* Y0 -> Y1 (SET M3) */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0x0000C000;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 18, &msr_value);
+
+ /* Y1 -> Y0 (SET N3) */
+
+ msr_value.low = 0x0000A000;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 17, &msr_value);
+
+ /* Y1 -> Y2 (SET N2) */
+
+ msr_value.low = 0x00000A00;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 19, &msr_value);
+
+ /* N5 (XSTATE = 10 && CMP2 <= V. COUNTER <= CMP3) && DISPE && Y == 0 */
+ /* CRC into REGB */
+
+ msr_value.high = 0x00000002;
+ msr_value.low = 0x10800B20;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL + 5, &msr_value);
+
+ /* N6 (XSTATE = 10 && CMP2 <= V. COUNTER <= CMP3) && DISPE && Y == 1 */
+ /* CRC into REGB */
+
+ msr_value.high = 0x00000002;
+ msr_value.low = 0x10800D20;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL + 6, &msr_value);
+ }
+
+ /* M4 (XSTATE = 00 AND VSYNC HIGH) */
+ /* Goto state 01 */
+ /* Note: VSync = H3A */
+
+ msr_value.high = 0x00000001;
+ msr_value.low = 0x000000A0;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETM0CTL + 4, &msr_value);
+
+ /* N0 (XSTATE = 01 AND VSYNC LOW) */
+ /* Goto state 02 */
+ /* Note: VSync low = H3B */
+
+ msr_value.high = 0x00040000;
+ msr_value.low = 0x000000C0;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL, &msr_value);
+
+ /* M5 (XSTATE = 10 AND VSYNC HIGH) */
+ /* Goto state 11 */
+
+ msr_value.high = 0x00000001;
+ msr_value.low = 0x00000120;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETM0CTL + 5, &msr_value);
+
+ /* N1 (XSTATE = 10 and DISPE HIGH) */
+ /* Increment H. Counter */
+ /* Note: DispE = H4 */
+
+ msr_value.high = 0x00000002;
+ msr_value.low = 0x00000120;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL + 1, &msr_value);
+
+ /* M0 (XSTATE = 10 and H. COUNTER == LIMIT) */
+ /* Clear H. Counter and increment V. Counter */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0x00000122;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETM0CTL, &msr_value);
+
+ /* N4 (XSTATE = 10 && CMP0 <= H. COUNTER <= CMP1 && CMP2 <= V. COUNTER <= CMP3) && DISPE */
+ /* CRC into REGB */
+
+ msr_value.high = 0x00000002;
+ msr_value.low = 0x10C20120;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_SETN0CTL + 4, &msr_value);
+
+ /* COMPARATOR 0 VALUE */
+ /* We subtract 1 to account for a pipeline delay in the GLCP. */
+ /* When the x coordinate is 0, we must play a special game. */
+ /* If the width is exactly 1, we will set up a state machine */
+ /* to only CRC the first pixel. Otherwise, we will set it */
+ /* as an OR combination of a state that CRCs the first pixel */
+ /* and a state that CRCs 1 clock delayed width (width - 1) */
+
+ msr_value.high = 0;
+ if (x > 1) msr_value.low = (x - 1) & 0xFFFF;
+ else msr_value.low = x;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPVAL0, &msr_value);
+
+ /* COMPARATOR 1 VALUE */
+
+ if ((x == 0 || x == 1) && width > 1) msr_value.low += width - 2;
+ else msr_value.low += width - 1;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPVAL0 + 2, &msr_value);
+
+ /* COMPARATOR 2 VALUE */
+
+ msr_value.low = y << 16;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPVAL0 + 4, &msr_value);
+
+ /* COMPARATOR 3 VALUE */
+
+ msr_value.low += (height - 1) << 16;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPVAL0 + 6, &msr_value);
+
+ /* COMPARATOR MASKS */
+ /* Comparators 0 and 1 refer to lower 16 bits of RegB */
+
+ msr_value.low = 0x0000FFFF;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPMASK0, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPMASK0 + 2, &msr_value);
+
+ /* Comparators 2 and 3 refer to upper 16 bits of RegB */
+
+ msr_value.low = 0xFFFF0000;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPMASK0 + 4, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_CMPMASK0 + 6, &msr_value);
+
+ /* SET REGB MASK */
+ /* We set the mask such that all all 32 bits of data are CRCed */
+
+ msr_value.low = 0xFFFFFFFF;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REGBMASK, &msr_value);
+
+ /* ACTIONS */
+
+ /* STATE 00->01 (SET 4M) */
+
+ msr_value.low = 0x000C0000;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 14, &msr_value);
+
+ /* STATE 01->10 (SET 0N) */
+
+ msr_value.low = 0x0000000A;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 15, &msr_value);
+
+ /* STATE 10->11 (SET 5M) */
+
+ msr_value.low = 0x00C00000;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 16, &msr_value);
+
+ /* CLEAR REGA WHEN TRANSITIONING TO STATE 10 */
+ /* Do not clear RegB as the initial value must be 0x00000001 */
+
+ msr_value.low = 0x0000000A;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0, &msr_value);
+
+ /* REGISTER ACTION 1 */
+ /* CRC into RegB if cmp0 <= h.counter <= cmp1 && cmp2 <= v. counter < cmp3 && 7 xstate = 10 */
+ /* Increment h.counter if xstate = 10 and HSync is low. */
+
+ msr_value.low = 0x000A00A0;
+ if (x == 0 && width == 1)
+ msr_value.low = 0x00A000A0;
+ else if (x == 1 && width == 1)
+ msr_value.low = 0x0A0000A0;
+ else if (x == 1 && width > 1)
+ msr_value.low |= 0x0A000000;
+
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 1, &msr_value);
+
+ /* REGISTER ACTION 2 */
+ /* Increment V. Counter in REGA */
+
+ msr_value.low = 0x0000000C;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 2, &msr_value);
+
+ /* SET REGB TO 0x00000001 */
+
+ msr_value.low = 0x00000001;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REGB, &msr_value);
+
+ /* SET XSTATE TO 0 */
+
+ msr_value.low = 0x00000000;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_XSTATE, &msr_value);
+
+ /* SET YSTATE TO 0 */
+
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_YSTATE, &msr_value);
+
+ /* CLEAR ALL OTHER ACTIONS */
+ /* This prevents side-effects from previous accesses to the GLCP */
+ /* debug logic. */
+
+ msr_value.low = 0x00000000;
+ msr_value.high = 0x00000000;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 3, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 4, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 5, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 6, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 7, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 8, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 9, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 10, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 11, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 12, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 13, &msr_value);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_ACTION0 + 20, &msr_value);
+
+ /* SET DIAG SETTINGS BASED ON DESIRED CRC */
+
+ if (crc_source == VG_CRC_SOURCE_POSTFLICKER || crc_source == VG_CRC_SOURCE_POSTFLICKER_EVEN)
+ {
+ diag = 0x80808086;
+
+ /* ENABLE HW CLOCK GATING AND SET GLCP CLOCK TO DOT CLOCK */
+
+ msr_value.high = 0;
+ msr_value.low = 5;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, MSR_GEODELINK_PM, &msr_value);
+ msr_value.low = 0;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DBGCLKCTL, &msr_value);
+ msr_value.low = 3;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DBGCLKCTL, &msr_value);
+
+ /* SET REGA LIMITS */
+ /* Lower counter uses pixels/line */
+ /* Upper counter is 0xFFFF to prevent rollover. */
+
+ msr_value.low = 0xFFFF0000 | (hactive - 1);
+ if (READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_DCEN)
+ {
+ msr_value.low += hblankstart - hactive;
+ msr_value.low += htotal - hblankend;
+ }
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REGAVAL, &msr_value);
+
+ /* USE H4 FUNCTION A FOR DISPE AND H4 FUNCTION B FOR NOT DISPE */
+ /* DISPE is bit 34 */
+
+ msr_value.high = 0x00000002;
+ msr_value.low = 0x20000FF0;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_H0CTL + 4, &msr_value);
+
+ /* USE H3 FUNCTION A FOR VSYNC AND H3 FUNCTION B FOR NOT VSYNC */
+ /* VSYNC is bit 32. */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0x002055AA;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_H0CTL + 3, &msr_value);
+ }
+ else if (crc_source == VG_CRC_SOURCE_PREFLICKER || crc_source == VG_CRC_SOURCE_PREFLICKER_EVEN)
+ {
+ diag = 0x801F8032;
+
+ /* ENABLE HW CLOCK GATING AND SET GLCP CLOCK TO GEODELINK CLOCK */
+
+ msr_value.high = 0;
+ msr_value.low = 5;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, MSR_GEODELINK_PM, &msr_value);
+ msr_value.low = 0;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DBGCLKCTL, &msr_value);
+ msr_value.low = 2;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DBGCLKCTL, &msr_value);
+
+ /* SET REGA LIMITS */
+ /* Lower counter uses pixels/line */
+ /* Upper counter is 0xFFFF to prevent rollover. */
+
+ msr_value.low = 0xFFFF0000 | (hactive - 1);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REGAVAL, &msr_value);
+
+ /* USE H4 FUNCTION A FOR DISPE AND H4 FUNCTION B FOR NOT DISPE */
+ /* DISPE is bit 47 */
+
+ msr_value.high = 0x00000002;
+ msr_value.low = 0xF0000FF0;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_H0CTL + 4, &msr_value);
+
+ /* USE H3 FUNCTION A FOR VSYNC AND H3 FUNCTION B FOR NOT VSYNC */
+ /* VSYNC is bit 45. */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0x002D55AA;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_H0CTL + 3, &msr_value);
+ }
+ else
+ {
+ /* PREFILTER CRC */
+
+ diag = 0x80138048;
+ msr_write64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_DIAG, &msr_value);
+
+ /* ENABLE HW CLOCK GATING AND SET GLCP CLOCK TO GEODELINK CLOCK */
+
+ msr_value.high = 0;
+ msr_value.low = 5;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, MSR_GEODELINK_PM, &msr_value);
+ msr_value.low = 0;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DBGCLKCTL, &msr_value);
+ msr_value.low = 2;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DBGCLKCTL, &msr_value);
+
+ /* SET REGA LIMITS */
+ /* Lower counter uses pixels/line */
+ /* Upper counter is 0xFFFF to prevent rollover. */
+ /* Note that we are assuming that the number of */
+ /* source pixels is specified in the FB_ACTIVE register */
+
+ msr_value.low = 0xFFFF0000 | ((READ_REG32 (DC3_FB_ACTIVE) >> 16) & 0xFFF);
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REGAVAL, &msr_value);
+
+ /* USE H4 FUNCTION A FOR DISPE AND H4 FUNCTION B FOR NOT DISPE */
+ /* DISPE is bit 55 */
+
+ msr_value.high = 0x00000003;
+ msr_value.low = 0x70000FF0;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_H0CTL + 4, &msr_value);
+
+ /* USE H3 FUNCTION A FOR VSYNC AND H3 FUNCTION B FOR NOT VSYNC */
+ /* VSYNC is bit 53. */
+
+ msr_value.high = 0x00000000;
+ msr_value.low = 0x003555AA;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_H0CTL + 3, &msr_value);
+ }
+
+ /* WAIT FOR THE CORRECT FIELD */
+ /* We use the VG line count and field indicator to determine when */
+ /* to kick off a CRC. */
+
+ if (crc_source & VG_CRC_SOURCE_EVEN) field = 0;
+ else field = DC3_LNCNT_EVEN_FIELD;
+
+ if (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)
+ {
+ /* WAIT FOR THE BEGINNING OF THE FIELD (LINE 1-5) */
+ /* Note that we wait for the field to be odd when CRCing the even */
+ /* field and vice versa. This is because the CRC will not begin */
+ /* until the following field. */
+
+ do
+ {
+ line = READ_REG32 (DC3_LINE_CNT_STATUS);
+ } while ((line & DC3_LNCNT_EVEN_FIELD) != field ||
+ ((line & DC3_LNCNT_V_LINE_CNT) >> 16) < 1 ||
+ ((line & DC3_LNCNT_V_LINE_CNT) >> 16) > 5);
+ }
+ else
+ {
+ /* NON-INTERLACED - EVEN FIELD CRCS ARE INVALID */
+
+ if (crc_source & VG_CRC_SOURCE_EVEN)
+ return 0xFFFFFFFF;
+ }
+
+ /* UPDATE VG DIAG OUTPUT */
+
+ msr_value.high = 0;
+ msr_value.low = diag;
+ msr_write64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_DIAG, &msr_value);
+
+ /* CONFIGURE DIAG CONTROL */
+ /* Set RegA action1 to increment lower 16 bits and clear at limit. (5) */
+ /* Set RegA action2 to increment upper 16 bits. (6) */
+ /* Set RegB action1 to CRC32 (1) */
+ /* Set all comparators to REGA override (0,1 lower mbus, 2,3 upper mbus) */
+ /* Enable all actions */
+
+ msr_value.low = 0x80EA20A0;
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DIAGCTL, &msr_value);
+
+ /* DELAY TWO FRAMES */
+
+ while (READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA);
+ while (!(READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA));
+ while (READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA);
+ while (!(READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA));
+ while (READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA);
+
+ /* VERIFY THAT XSTATE = 11 */
+
+ msr_read64 (MSR_DEVICE_GEODELX_GLCP, GLCP_XSTATE, &msr_value);
+ if ((msr_value.low & 3) == 3)
+ {
+ msr_read64 (MSR_DEVICE_GEODELX_GLCP, GLCP_REGB, &msr_value);
+
+ crc = msr_value.low;
+ }
+
+ /* DISABLE VG DIAG BUS OUTPUTS */
+
+ msr_value.low = 0x00000000;
+ msr_value.high = 0x00000000;
+ msr_write64 (MSR_DEVICE_GEODELX_VG, MSR_GEODELINK_DIAG, &msr_value);
+
+ /* DISABLE GLCP ACTIONS */
+
+ msr_write64 (MSR_DEVICE_GEODELX_GLCP, GLCP_DIAGCTL, &msr_value);
+
+ return crc;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_get_scaler_filter_coefficients
+ *
+ * This routine gets the vertical and horizontal filter coefficients for
+ * graphics scaling. The coefficients are sign extended to 32-bit values.
+ *---------------------------------------------------------------------------*/
+
+int vg_get_scaler_filter_coefficients (long h_taps[][5], long v_taps[][3])
+{
+ unsigned long irqfilt, i;
+ unsigned long temp;
+ long coeff0, coeff1, coeff2;
+ unsigned long lock;
+
+ /* ENABLE ACCESS TO THE HORIZONTAL COEFFICIENTS */
+
+ lock = READ_REG32 (DC3_UNLOCK);
+ irqfilt = READ_REG32 (DC3_IRQ_FILT_CTL);
+ irqfilt |= DC3_IRQFILT_H_FILT_SEL;
+
+ /* WRITE COEFFICIENTS */
+ /* Coefficient indexes do not auto-increment, so we must */
+ /* write the address for every phase */
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+ for (i = 0; i < 256; i++)
+ {
+ WRITE_REG32 (DC3_IRQ_FILT_CTL, ((irqfilt & 0xFFFFFF00L) | i));
+
+ temp = READ_REG32 (DC3_FILT_COEFF1);
+ coeff0 = (temp & 0x3FF);
+ coeff1 = (temp >> 10) & 0x3FF;
+ coeff2 = (temp >> 20) & 0x3FF;
+
+ h_taps[i][0] = (coeff0 << 22) >> 22;
+ h_taps[i][1] = (coeff1 << 22) >> 22;
+ h_taps[i][2] = (coeff2 << 22) >> 22;
+
+ temp = READ_REG32 (DC3_FILT_COEFF2);
+ coeff0 = (temp & 0x3FF);
+ coeff1 = (temp >> 10) & 0x3FF;
+
+ h_taps[i][3] = (coeff0 << 22) >> 22;
+ h_taps[i][4] = (coeff1 << 22) >> 22;
+ }
+
+ /* ENABLE ACCESS TO THE VERTICAL COEFFICIENTS */
+
+ irqfilt &= ~DC3_IRQFILT_H_FILT_SEL;
+
+ /* WRITE COEFFICIENTS */
+
+ for (i = 0; i < 256; i++)
+ {
+ WRITE_REG32 (DC3_IRQ_FILT_CTL, ((irqfilt & 0xFFFFFF00L) | i));
+
+ temp = READ_REG32 (DC3_FILT_COEFF1);
+ coeff0 = (temp & 0x3FF);
+ coeff1 = (temp >> 10) & 0x3FF;
+ coeff2 = (temp >> 20) & 0x3FF;
+
+ v_taps[i][0] = (coeff0 << 22) >> 22;
+ v_taps[i][1] = (coeff1 << 22) >> 22;
+ v_taps[i][2] = (coeff2 << 22) >> 22;
+ }
+
+ WRITE_REG32 (DC3_UNLOCK, lock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_get_flicker_filter_configuration
+ *
+ * This routine returns the current VG flicker filter configuration.
+ *---------------------------------------------------------------------------*/
+
+int vg_get_flicker_filter_configuration (unsigned long *strength, int *flicker_alpha)
+{
+ unsigned long genlk_ctl;
+
+ if (!strength || !flicker_alpha)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ genlk_ctl = READ_REG32 (DC3_GENLK_CTL);
+ *strength = genlk_ctl & DC3_GC_FLICKER_FILTER_MASK;
+ if (genlk_ctl & DC3_GC_ALPHA_FLICK_ENABLE)
+ *flicker_alpha = 1;
+ else
+ *flicker_alpha = 0;
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vg_get_display_pitch
+ *
+ * This routine returns the current stride between successive lines of frame
+ * buffer data.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vg_get_display_pitch (void)
+{
+ return ((READ_REG32 (DC3_GFX_PITCH) & 0x0000FFFF) << 3);
+}
+
+/*---------------------------------------------------------------------------
+ * vg_get_frame_buffer_line_size
+ *
+ * This routine returns the current size in bytes of one line of frame buffer
+ * data.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vg_get_frame_buffer_line_size (void)
+{
+ return ((READ_REG32 (DC3_LINE_SIZE) & 0x3FF) << 3);
+}
+
+/*---------------------------------------------------------------------------
+ * vg_get_current_vline
+ *
+ * This routine returns the number of the current line that is being displayed
+ * by the display controller.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vg_get_current_vline (void)
+{
+ unsigned long current_line;
+
+ /* READ THE REGISTER TWICE TO ENSURE THAT THE VALUE IS NOT TRANSITIONING */
+
+ do
+ {
+ current_line = READ_REG32(DC3_LINE_CNT_STATUS) & DC3_LNCNT_V_LINE_CNT;
+ }
+ while (current_line != (READ_REG32(DC3_LINE_CNT_STATUS) & DC3_LNCNT_V_LINE_CNT));
+
+ return (current_line >> 16);
+}
+
+/*---------------------------------------------------------------------------
+ * vg_get_display_offset
+ *
+ * This routine returns the offset into the frame buffer for the first pixel
+ * of the display.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vg_get_display_offset (void)
+{
+ return (READ_REG32(DC3_FB_ST_OFFSET) & 0x0FFFFFFF);
+}
+
+/*---------------------------------------------------------------------------
+ * vg_get_cursor_info
+ *
+ * This routine returns the current settings for the hardware cursor.
+ *---------------------------------------------------------------------------*/
+
+int vg_get_cursor_info (VG_CURSOR_DATA *cursor_data)
+{
+ unsigned long temp;
+
+ /* CURSOR OFFSET */
+
+ cursor_data->cursor_offset = READ_REG32 (DC3_CURS_ST_OFFSET) & 0x0FFFFFFF;
+
+ /* CURSOR X POSITION */
+
+ temp = READ_REG32 (DC3_CURSOR_X);
+ cursor_data->cursor_x = temp & 0x7FF;
+ cursor_data->clipx = (temp >> 11) & 0x3F;
+
+ /* CURSOR Y POSITION */
+
+ temp = READ_REG32 (DC3_CURSOR_Y);
+ cursor_data->cursor_y = temp & 0x7FF;
+ cursor_data->clipy = (temp >> 11) & 0x3F;
+
+ /* CURSOR COLORS */
+
+ WRITE_REG32 (DC3_PAL_ADDRESS, 0x100);
+ cursor_data->mono_color0 = READ_REG32 (DC3_PAL_DATA);
+ cursor_data->mono_color1 = READ_REG32 (DC3_PAL_DATA);
+
+ /* CURSOR ENABLES */
+
+ temp = READ_REG32 (DC3_GENERAL_CFG);
+ if (temp & DC3_GCFG_CURE) cursor_data->enable = 1;
+ else cursor_data->enable = 0;
+ if (temp & DC3_GCFG_CLR_CUR) cursor_data->color_cursor = 1;
+ else cursor_data->color_cursor = 0;
+
+ return CIM_STATUS_OK;
+}
+
+/*-----------------------------------------------------------------------------
+ * vg_get_display_palette_entry
+ *
+ * This routine reads a single entry in the 8BPP display palette.
+ *----------------------------------------------------------------------------*/
+
+int vg_get_display_palette_entry (unsigned long index, unsigned long *entry)
+{
+ if (index > 0xFF)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ WRITE_REG32 (DC3_PAL_ADDRESS, index);
+ *entry = READ_REG32 (DC3_PAL_DATA);
+
+ return CIM_STATUS_OK;
+}
+
+/*-----------------------------------------------------------------------------
+ * vg_get_border_color
+ *
+ * This routine reads the current border color for centered displays.
+ *----------------------------------------------------------------------------*/
+
+unsigned long vg_get_border_color (void)
+{
+ WRITE_REG32 (DC3_PAL_ADDRESS, 0x104);
+ return READ_REG32 (DC3_PAL_DATA);
+}
+
+/*-----------------------------------------------------------------------------
+ * vg_get_display_palette
+ *
+ * This routines reads the entire contents of the display palette into a buffer.
+ * The display palette consists of 256 X:R:G:B values.
+ *----------------------------------------------------------------------------*/
+
+int vg_get_display_palette (unsigned long *palette)
+{
+ unsigned long i;
+
+ if (palette)
+ {
+ WRITE_REG32 (DC3_PAL_ADDRESS, 0);
+ for (i = 0; i < 256; i++)
+ {
+ palette[i] = READ_REG32 (DC3_PAL_DATA);
+ }
+ return CIM_STATUS_OK;
+ }
+ return CIM_STATUS_INVALIDPARAMS;
+}
+
+/*-----------------------------------------------------------------------------
+ * vg_get_compression_info
+ *
+ * This routines reads the current status of the display compression hardware.
+ *----------------------------------------------------------------------------*/
+
+int vg_get_compression_info (VG_COMPRESSION_DATA *comp_data)
+{
+ comp_data->compression_offset = READ_REG32 (DC3_CB_ST_OFFSET) & 0x0FFFFFFF;
+ comp_data->pitch = (READ_REG32 (DC3_GFX_PITCH) >> 13) & 0x7FFF8;
+ comp_data->size = ((READ_REG32 (DC3_LINE_SIZE) >> (DC3_LINE_SIZE_CB_SHIFT - 3)) & 0x3F8) + 24;
+
+ return CIM_STATUS_OK;
+}
+
+/*-----------------------------------------------------------------------------
+ * vg_get_compression_enable
+ *
+ * This routines reads the current enable status of the display compression hardware.
+ *----------------------------------------------------------------------------*/
+
+int vg_get_compression_enable (void)
+{
+ if (READ_REG32 (DC3_GENERAL_CFG) & DC3_GCFG_CMPE)
+ return 1;
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------------------
+ * vg_get_valid_bit
+ *----------------------------------------------------------------------------*/
+
+int vg_get_valid_bit (int line)
+{
+ unsigned long offset;
+ unsigned long valid;
+ unsigned long lock;
+
+ lock = READ_REG32 (DC3_UNLOCK);
+ offset = READ_REG32 (DC3_PHY_MEM_OFFSET) & 0xFF000000;
+ offset |= line;
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_PHY_MEM_OFFSET, offset);
+ WRITE_REG32 (DC3_UNLOCK, lock);
+ valid = READ_REG32 (DC3_DV_ACC) & 2;
+
+ if (valid) return 1;
+ return 0;
+}
+
+#endif
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_vip.c xf86-video-nsc-2.8.1/src/cim/cim_vip.c
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_vip.c 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_vip.c 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,1565 @@
+ /*
+ *
+ * Copyright (C) 2005 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *
+ *
+ *
+ *
+ *
+ * Cimarron VIP configuration routines.
+ *
+ *
+ */
+
+/*---------------------------------------------------------------------------
+ * vip_initialize
+ *
+ * This routine initializes the internal module state and prepares the
+ * module for subsequent VIP orientated activities.
+ *---------------------------------------------------------------------------*/
+
+int vip_initialize(VIPSETMODEBUFFER *buffer)
+{
+ unsigned long vip_control1, vip_control2, vip_control3;
+
+ if (!buffer)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ vip_control1 = 0;
+ vip_control2 = 0;
+ vip_control3 = 0;
+
+ /* CONFIGURE CONTROL WORDS BASED ON MODE STRUCTURE */
+ /* Note that some of the input parameters match the register fields */
+ /* they represent. */
+
+ /* STREAM ENABLES */
+
+ vip_control1 |= buffer->stream_enables;
+
+ /* VIP CAPTURE MODE */
+
+ vip_control1 |= buffer->operating_mode;
+
+ /* HANDLE PLANAR CAPTURE */
+
+ if (buffer->flags & VIP_MODEFLAG_PLANARCAPTURE)
+ {
+ vip_control1 |= VIP_CONTROL1_PLANAR;
+
+ if (buffer->planar_capture == VIP_420CAPTURE_EVERYLINE)
+ {
+ vip_control1 |= VIP_CONTROL1_DISABLE_DECIMATION;
+ }
+ else if (buffer->planar_capture == VIP_420CAPTURE_ALTERNATINGFIELDS)
+ {
+ if (buffer->flags & VIP_MODEFLAG_PROGRESSIVE)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ vip_control1 |= VIP_CONTROL1_DISABLE_DECIMATION;
+ vip_control3 |= VIP_CONTROL3_DECIMATE_EVEN;
+ }
+ else if (buffer->planar_capture != VIP_420CAPTURE_ALTERNATINGLINES)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ /* CONFIGURE THE VIDEO FIFO THRESHOLD BASED ON THE FIFO DEPTH */
+
+ vip_control2 |= VIP_CONTROL2_DEFAULT_VIDTH_420 << VIP_CONTROL2_VIDTH_SHIFT;
+
+ }
+ else
+ {
+ vip_control2 |= VIP_CONTROL2_DEFAULT_VIDTH_422 << VIP_CONTROL2_VIDTH_SHIFT;
+ }
+
+ /* CONFIGURE DEFAULT ANCILARRY THRESHOLD AND VIDEO FLUSH VALUES */
+
+ vip_control2 |= VIP_CONTROL2_DEFAULT_ANCTH << VIP_CONTROL2_ANCTH_SHIFT;
+ vip_control1 |= VIP_CONTROL1_DEFAULT_ANC_FF << VIP_CONTROL1_ANC_FF_SHIFT;
+ vip_control1 |= VIP_CONTROL1_DEFAULT_VID_FF << VIP_CONTROL1_VID_FF_SHIFT;
+
+ /* PROGRAM VIP OPTIONS */
+ /* The options are sanitized based on the current configuration. */
+
+ if (buffer->flags & VIP_MODEFLAG_PROGRESSIVE)
+ vip_control1 |= VIP_CONTROL1_NON_INTERLACED;
+ else
+ {
+ if (buffer->flags & VIP_MODEFLAG_TOGGLEEACHFIELD)
+ vip_control3 |= VIP_CONTROL3_BASE_UPDATE;
+ if (buffer->flags & VIP_MODEFLAG_INVERTPOLARITY)
+ vip_control2 |= VIP_CONTROL2_INVERT_POLARITY;
+ }
+
+ if ((buffer->operating_mode == VIP_MODE_MSG ||
+ buffer->operating_mode == VIP_MODE_DATA) &&
+ (buffer->flags & VIP_MODEFLAG_FLIPMESSAGEWHENFULL))
+ {
+ vip_control1 |= VIP_CONTROL1_MSG_STRM_CTRL;
+ }
+
+ else if (buffer->operating_mode == VIP_MODE_VIP2_8BIT ||
+ buffer->operating_mode == VIP_MODE_VIP2_16BIT)
+ {
+ if (buffer->flags & VIP_MODEFLAG_ENABLEREPEATFLAG)
+ vip_control2 |= VIP_CONTROL2_REPEAT_ENABLE;
+ if (buffer->flags & VIP_MODEFLAG_INVERTTASKPOLARITY)
+ vip_control3 |= VIP_CONTROL3_TASK_POLARITY;
+ }
+
+ if (buffer->flags & VIP_MODEFLAG_DISABLEZERODETECT)
+ vip_control1 |= VIP_CONTROL1_DISABLE_ZERO_DETECT;
+ if (buffer->flags & VIP_MODEFLAG_10BITANCILLARY)
+ vip_control2 |= VIP_CONTROL2_ANC10;
+
+ /* WRITE THE CONTROL REGISTERS */
+ /* The control registers are kept 'live' to allow separate instances of */
+ /* Cimarron to control the VIP hardware. */
+
+ WRITE_VIP32 (VIP_CONTROL1, vip_control1);
+ WRITE_VIP32 (VIP_CONTROL2, vip_control2);
+ WRITE_VIP32 (VIP_CONTROL3, vip_control3);
+
+ /* CONFIGURE 601 PARAMETERS */
+
+ if (buffer->operating_mode == VIP_MODE_8BIT601 ||
+ buffer->operating_mode == VIP_MODE_16BIT601)
+ {
+ vip_update_601_params (&buffer->vip601_settings);
+ }
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_update_601_params
+ *
+ * This routine configures all aspects of 601 VIP data capture, including
+ * start and stop timings and input polarities.
+ *---------------------------------------------------------------------------*/
+
+int vip_update_601_params (VIP_601PARAMS *buffer)
+{
+ unsigned long vip_control3, vip_control1;
+
+ if (!buffer)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ vip_control1 = READ_VIP32 (VIP_CONTROL3);
+ vip_control3 = READ_VIP32 (VIP_CONTROL3);
+
+ if (buffer->flags & VIP_MODEFLAG_VSYNCACTIVEHIGH) vip_control3 |= VIP_CONTROL3_VSYNC_POLARITY;
+ else vip_control3 &= ~VIP_CONTROL3_VSYNC_POLARITY;
+ if (buffer->flags & VIP_MODEFLAG_HSYNCACTIVEHIGH) vip_control3 |= VIP_CONTROL3_HSYNC_POLARITY;
+ else vip_control3 &= ~VIP_CONTROL3_HSYNC_POLARITY;
+
+ WRITE_VIP32 (VIP_CONTROL3, vip_control3);
+ WRITE_VIP32 (VIP_601_HORZ_START, buffer->horz_start);
+ WRITE_VIP32 (VIP_601_VBI_START, buffer->vbi_start);
+ WRITE_VIP32 (VIP_601_VBI_END, buffer->vbi_start + buffer->vbi_height - 1);
+ WRITE_VIP32 (VIP_601_EVEN_START_STOP,
+ buffer->vert_start_even | ((buffer->vert_start_even + buffer->even_height - 1) << 16));
+ WRITE_VIP32 (VIP_601_ODD_START_STOP,
+ buffer->vert_start_odd | ((buffer->vert_start_odd + buffer->odd_height - 1) << 16));
+ WRITE_VIP32 (VIP_ODD_FIELD_DETECT,
+ buffer->odd_detect_start | (buffer->odd_detect_end << 16));
+
+ /* SPECIAL CASE FOR HORIZONTAL DATA */
+ /* 601 horizontal parameters are based on the number of clocks and not the */
+ /* number of pixels. */
+
+ if ((vip_control1 & VIP_CONTROL1_MODE_MASK) == VIP_MODE_16BIT601)
+ WRITE_VIP32 (VIP_601_HORZ_END, buffer->horz_start + (buffer->width << 1) + 3);
+ else
+ WRITE_VIP32 (VIP_601_HORZ_END, buffer->horz_start + buffer->width + 3);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_configure_capture_buffers
+ *
+ * This routine configures the base offsets for video, ancillary or message
+ * mode capture. The input structure can also contain multiple offsets, such
+ * that the calling application can avoid updating the structure for each flip.
+ *
+ * The new buffer addresses are written to the hardware registers although
+ * they may not be latched immediately. Calling vip_is_buffer_update_latched
+ * allows the determination of whether the update has occured.
+ *
+ * Review the Cimarron VIP API documentation to determine which buffer addresses are
+ * latched immediately.
+ *---------------------------------------------------------------------------*/
+
+int vip_configure_capture_buffers (int buffer_type, VIPINPUTBUFFER *buffer)
+{
+ VIPINPUTBUFFER_ADDR *offsets;
+ unsigned long cur_buffer = buffer->current_buffer;
+
+ if (!buffer)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ if (buffer_type == VIP_BUFFER_A || buffer_type == VIP_BUFFER_601)
+ {
+ offsets = &buffer->offsets[VIP_BUFFER_TASK_A];
+
+ /* SET VIDEO PITCH */
+
+ WRITE_VIP32 (VIP_TASKA_VID_PITCH, offsets->y_pitch | (offsets->uv_pitch << 16));
+
+ /* SET BASE OFFSETS */
+
+ if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
+ {
+ WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE, offsets->even_base[cur_buffer]);
+ WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE, offsets->odd_base[cur_buffer]);
+ if (buffer->flags & VIP_INPUTFLAG_VBI)
+ {
+ WRITE_VIP32 (VIP_TASKA_VBI_ODD_BASE, offsets->vbi_even_base);
+ WRITE_VIP32 (VIP_TASKA_VBI_EVEN_BASE, offsets->vbi_odd_base);
+ }
+ }
+ else
+ {
+ WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE, offsets->odd_base[cur_buffer]);
+ WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE, offsets->even_base[cur_buffer]);
+ if (buffer->flags & VIP_INPUTFLAG_VBI)
+ {
+ WRITE_VIP32 (VIP_TASKA_VBI_ODD_BASE, offsets->vbi_odd_base);
+ WRITE_VIP32 (VIP_TASKA_VBI_EVEN_BASE, offsets->vbi_even_base);
+ }
+ }
+
+ /* SET 4:2:0 OFFSETS */
+
+ if (buffer->flags & VIP_INPUTFLAG_PLANAR)
+ {
+ WRITE_VIP32 (VIP_TASKA_U_OFFSET, offsets->odd_uoffset);
+ WRITE_VIP32 (VIP_TASKA_V_OFFSET, offsets->odd_voffset);
+ WRITE_VIP32 (VIP_TASKA_U_EVEN_OFFSET, offsets->even_uoffset);
+ WRITE_VIP32 (VIP_TASKA_V_EVEN_OFFSET, offsets->even_voffset);
+ }
+ }
+ else if (buffer_type == VIP_BUFFER_B)
+ {
+ offsets = &buffer->offsets[VIP_BUFFER_TASK_B];
+
+ /* SET VIDEO PITCH */
+
+ WRITE_VIP32 (VIP_TASKB_VID_PITCH, offsets->y_pitch | (offsets->uv_pitch << 16));
+
+ /* SET BASE OFFSETS */
+
+ if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
+ {
+ WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE, offsets->even_base[cur_buffer]);
+ WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE, offsets->odd_base[cur_buffer]);
+ if (buffer->flags & VIP_INPUTFLAG_VBI)
+ {
+ WRITE_VIP32 (VIP_TASKB_VBI_ODD_BASE, offsets->vbi_even_base);
+ WRITE_VIP32 (VIP_TASKB_VBI_EVEN_BASE, offsets->vbi_odd_base);
+ }
+ }
+ else
+ {
+ WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE, offsets->odd_base[cur_buffer]);
+ WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE, offsets->even_base[cur_buffer]);
+ if (buffer->flags & VIP_INPUTFLAG_VBI)
+ {
+ WRITE_VIP32 (VIP_TASKB_VBI_ODD_BASE, offsets->vbi_odd_base);
+ WRITE_VIP32 (VIP_TASKB_VBI_EVEN_BASE, offsets->vbi_even_base);
+ }
+ }
+
+ /* SET 4:2:0 OFFSETS */
+
+ if (buffer->flags & VIP_INPUTFLAG_PLANAR)
+ {
+ WRITE_VIP32 (VIP_TASKB_U_OFFSET, offsets->odd_uoffset);
+ WRITE_VIP32 (VIP_TASKB_V_OFFSET, offsets->odd_voffset);
+ }
+ }
+ else if (buffer_type == VIP_BUFFER_ANC || buffer_type == VIP_BUFFER_MSG)
+ {
+ WRITE_VIP32(VIP_ANC_MSG1_BASE, buffer->ancillaryData.msg1_base);
+ WRITE_VIP32(VIP_ANC_MSG2_BASE, buffer->ancillaryData.msg2_base);
+ WRITE_VIP32(VIP_ANC_MSG_SIZE, buffer->ancillaryData.msg_size);
+ }
+ else
+ {
+ return CIM_STATUS_INVALIDPARAMS;
+ }
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_toggle_vip_video_offsets
+ *
+ * This routine updates the offsets for video capture. It is a simplified
+ * version of vip_configure_capture_buffers that is designed to be called from
+ * interrupt service routines or other buffer flipping applications that
+ * require low latency.
+ *---------------------------------------------------------------------------*/
+
+int vip_toggle_video_offsets (int buffer_type, VIPINPUTBUFFER *buffer)
+{
+ unsigned long cur_buffer = buffer->current_buffer;
+ VIPINPUTBUFFER_ADDR *offsets;
+
+ if (buffer_type == VIP_BUFFER_A)
+ {
+ offsets = &buffer->offsets[VIP_BUFFER_TASK_A];
+
+ /* SET BASE OFFSETS */
+
+ if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
+ {
+ WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE, offsets->even_base[cur_buffer]);
+ WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE, offsets->odd_base[cur_buffer]);
+ }
+ else
+ {
+ WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE, offsets->odd_base[cur_buffer]);
+ WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE, offsets->even_base[cur_buffer]);
+ }
+ }
+ else if (buffer_type == VIP_BUFFER_B)
+ {
+ offsets = &buffer->offsets[VIP_BUFFER_TASK_B];
+
+ /* SET BASE OFFSETS */
+
+ if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
+ {
+ WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE, offsets->even_base[cur_buffer]);
+ WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE, offsets->odd_base[cur_buffer]);
+ }
+ else
+ {
+ WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE, offsets->odd_base[cur_buffer]);
+ WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE, offsets->even_base[cur_buffer]);
+ }
+ }
+ else if (buffer_type == VIP_BUFFER_A_ODD)
+ {
+ offsets = &buffer->offsets[VIP_BUFFER_TASK_A];
+
+ /* SET BASE OFFSETS */
+
+ if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
+ WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE, offsets->even_base[cur_buffer]);
+ else
+ WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE, offsets->odd_base[cur_buffer]);
+ }
+ else if (buffer_type == VIP_BUFFER_A_EVEN)
+ {
+ offsets = &buffer->offsets[VIP_BUFFER_TASK_A];
+
+ /* SET BASE OFFSETS */
+
+ if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
+ WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE, offsets->odd_base[cur_buffer]);
+ else
+ WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE, offsets->even_base[cur_buffer]);
+ }
+ else if (buffer_type == VIP_BUFFER_B_ODD)
+ {
+ offsets = &buffer->offsets[VIP_BUFFER_TASK_B];
+
+ /* SET BASE OFFSETS */
+
+ if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
+ WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE, offsets->even_base[cur_buffer]);
+ else
+ WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE, offsets->odd_base[cur_buffer]);
+ }
+ else if (buffer_type == VIP_BUFFER_B_EVEN)
+ {
+ offsets = &buffer->offsets[VIP_BUFFER_TASK_B];
+
+ /* SET BASE OFFSETS */
+
+ if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
+ WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE, offsets->odd_base[cur_buffer]);
+ else
+ WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE, offsets->even_base[cur_buffer]);
+ }
+ else
+ return CIM_STATUS_INVALIDPARAMS;
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_set_capture_state
+ *
+ * This routine takes the current control word definition ( stored in locals )
+ * adds in the specified state, and writes the control word.
+ *---------------------------------------------------------------------------*/
+
+int vip_set_capture_state (unsigned long state)
+{
+ unsigned long vip_control1, vip_control3;
+
+ /* UPDATE THE CURRENT CAPTURE MODE */
+
+ vip_control1 = READ_VIP32 (VIP_CONTROL1);
+ vip_control3 = READ_VIP32 (VIP_CONTROL3);
+ vip_control1 &= ~VIP_CONTROL1_RUNMODE_MASK;
+ vip_control1 |= (state << VIP_CONTROL1_RUNMODE_SHIFT);
+
+ WRITE_VIP32 (VIP_CONTROL1, vip_control1);
+
+ if (state >= VIP_STARTCAPTUREATNEXTLINE)
+ {
+ /* WHACK VIP RESET */
+ /* The VIP can get confused when switching between capture settings, such as */
+ /* between linear and planar. We will thus whack VIP reset when enabling */
+ /* capture to ensure a pristine VIP state. */
+
+ WRITE_VIP32 (VIP_CONTROL1, vip_control1 | VIP_CONTROL1_RESET);
+ WRITE_VIP32 (VIP_CONTROL1, vip_control1 & ~VIP_CONTROL1_RESET);
+ WRITE_VIP32 (VIP_CONTROL3, vip_control3 | VIP_CONTROL3_FIFO_RESET);
+ }
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_terminate
+ *
+ * This routine stops VIP capture and resets the VIP internal state.
+ *---------------------------------------------------------------------------*/
+
+int vip_terminate (void)
+{
+ unsigned long timeout = 50000;
+
+ /* DISABLE AND CLEAR ALL VIP INTERRUPTS */
+
+ WRITE_VIP32 (VIP_INTERRUPT, VIP_ALL_INTERRUPTS | (VIP_ALL_INTERRUPTS >> 16));
+
+ /* DISABLE VIP CAPTURE */
+ /* We will try to let the VIP FIFO flush before shutting it down. */
+
+ WRITE_VIP32 (VIP_CONTROL1, 0);
+ while (timeout)
+ {
+ timeout--;
+ if (READ_VIP32 (VIP_STATUS) & VIP_STATUS_WRITES_COMPLETE)
+ break;
+ }
+
+ /* RESET THE HARDWARE REGISTERS */
+ /* Note that we enable VIP reset to allow clock gating to lower VIP */
+ /* power consumption. */
+
+ WRITE_VIP32 (VIP_CONTROL1, VIP_CONTROL1_RESET);
+ WRITE_VIP32 (VIP_CONTROL3, VIP_CONTROL3_FIFO_RESET);
+ WRITE_VIP32 (VIP_CONTROL2, 0);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_configure_fifo
+ *
+ * This routine sets the desired threshold or flush for the specified fifo.
+ *---------------------------------------------------------------------------*/
+
+int vip_configure_fifo (unsigned long fifo_type, unsigned long fifo_size)
+{
+ unsigned long vip_control1, vip_control2;
+
+ vip_control1 = READ_VIP32 (VIP_CONTROL1);
+ vip_control2 = READ_VIP32 (VIP_CONTROL2);
+
+ switch (fifo_type)
+ {
+ case VIP_VIDEOTHRESHOLD:
+ vip_control2 &= ~VIP_CONTROL2_VIDTH_MASK;
+ vip_control2 |= (fifo_size << VIP_CONTROL2_VIDTH_SHIFT) & VIP_CONTROL2_VIDTH_MASK;
+ break;
+
+ case VIP_ANCILLARYTHRESHOLD:
+ vip_control2 &= ~VIP_CONTROL2_ANCTH_MASK;
+ vip_control2 |= (fifo_size << VIP_CONTROL2_ANCTH_SHIFT) & VIP_CONTROL2_ANCTH_MASK;
+ break;
+
+ case VIP_VIDEOFLUSH:
+ vip_control1 &= ~VIP_CONTROL1_VID_FF_MASK;
+ vip_control1 |= ((fifo_size >> 2) << VIP_CONTROL1_VID_FF_SHIFT) & VIP_CONTROL1_VID_FF_MASK;
+ break;
+
+ case VIP_ANCILLARYFLUSH:
+ vip_control1 &= ~VIP_CONTROL1_ANC_FF_MASK;
+ vip_control1 |= ((fifo_size >> 2) << VIP_CONTROL1_ANC_FF_SHIFT) & VIP_CONTROL1_ANC_FF_MASK;
+ break;
+
+ default:
+ return CIM_STATUS_INVALIDPARAMS;
+ }
+
+ WRITE_VIP32 (VIP_CONTROL1, vip_control1);
+ WRITE_VIP32 (VIP_CONTROL2, vip_control2);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_set_interrupt_enable
+ *
+ * This routine accepts a mask of interrupts to be enabled/disabled and
+ * an enable flag.
+ *
+ * For each mask match, the interrupt will be enabled or disabled based on
+ * enable
+ *---------------------------------------------------------------------------*/
+
+int vip_set_interrupt_enable (unsigned long mask, int enable)
+{
+ /* CHECK IF ANY VALID INTERRUPTS ARE BEING CHANGED */
+
+ if (mask & VIP_ALL_INTERRUPTS)
+ {
+ unsigned long int_enable = READ_VIP32(VIP_INTERRUPT) & 0xFFFF;
+
+ /* SET OR CLEAR THE MASK BITS */
+ /* Note that the upper 16-bits of the register are 0 after this */
+ /* operation. This prevents us from indadvertently clearing a */
+ /* pending interrupt by enabling/disabling another one. */
+
+ if (enable) int_enable &= ~(mask >> 16);
+ else int_enable |= (mask >> 16);
+
+ WRITE_VIP32 (VIP_INTERRUPT, int_enable);
+ }
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_set_vsync_error
+ *
+ * This routine defines a region that is used to determine if the vsync is
+ * within an acceptable range. This definition is accomplished using
+ * a count and a vertical window. The count specifies the exact number
+ * of clocks expected for one field. The window parameters specify the number
+ * of clocks variation allowed before and after the expected vsync. For
+ * example, if vertical_count is 1000, window_before is 5 and window_after
+ * is 12, VSync will be considered valid if it occurs between 995 and 1012
+ * clocks after the last VSync. The total window size (window_before + window_after)
+ * cannot exceed 255.
+ *---------------------------------------------------------------------------*/
+
+int vip_set_vsync_error (unsigned long vertical_count, unsigned long window_before,
+ unsigned long window_after, int enable)
+{
+ unsigned long vip_control2 = READ_VIP32 (VIP_CONTROL2);
+ unsigned long temp;
+
+ if (enable)
+ {
+ /* CREATE THE VERTICAL WINDOW */
+ /* The VIP uses two counters. The first counter defines the minimum clock count */
+ /* before a valid VSync can occur. The second counter starts after the first */
+ /* completes and defines the acceptable region of variation. */
+
+ temp = ((window_before + window_after) << VIP_VSYNC_ERR_WINDOW_SHIFT) & VIP_VSYNC_ERR_WINDOW_MASK;
+ temp |= (vertical_count - window_before) & VIP_VSYNC_ERR_COUNT_MASK;
+
+ vip_control2 |= VIP_CONTROL2_VERTERROR_ENABLE;
+
+ WRITE_VIP32(VIP_VSYNC_ERR_COUNT, temp);
+ }
+ else
+ {
+ vip_control2 &= ~VIP_CONTROL2_VERTERROR_ENABLE;
+ }
+ WRITE_VIP32 (VIP_CONTROL2, vip_control2);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_max_address_enable
+ *
+ * This routine specifies the maximum address to which the the hardware should
+ * write during data storage. If this value is exceeded an error is generated,
+ * (this may be monitored using the appropriate interrupt flags - see
+ * vip_set_interrupt_enable)
+ *---------------------------------------------------------------------------*/
+
+int vip_max_address_enable (unsigned long max_address, int enable)
+{
+ unsigned long vip_control2 = READ_VIP32 (VIP_CONTROL2);
+
+ if (enable)
+ {
+ /* ENABLE THE CONTROL BIT */
+
+ vip_control2 |= VIP_CONTROL2_ADD_ERROR_ENABLE;
+
+ WRITE_VIP32(VIP_MAX_ADDRESS, max_address & VIP_MAXADDR_MASK);
+ }
+ else
+ {
+ /* DISABLE DETECTION */
+
+ vip_control2 &= ~VIP_CONTROL2_ADD_ERROR_ENABLE;
+ }
+ WRITE_VIP32 (VIP_CONTROL2, vip_control2);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_set_loopback_enable
+ *
+ * This routine enables/disables internal loopback functionality. When
+ * loopback is enabled, the VOP outputs are rerouted to the VIP inputs
+ * internal to the chip. No loopback connector is required.
+ *---------------------------------------------------------------------------*/
+
+int vip_set_loopback_enable(int enable)
+{
+ unsigned long vip_control2 = READ_VIP32 (VIP_CONTROL2);
+
+ if (enable) vip_control2 |= VIP_CONTROL2_LOOPBACK_ENABLE;
+ else vip_control2 &= ~VIP_CONTROL2_LOOPBACK_ENABLE;
+
+ WRITE_VIP32 (VIP_CONTROL2, vip_control2);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_configure_genlock
+ *
+ * This routine configures genlock functionality.
+ *---------------------------------------------------------------------------*/
+
+int vip_configure_genlock (VIPGENLOCKBUFFER *buffer)
+{
+ unsigned long vip_control1, vip_control2;
+ unsigned long unlock, genlk_ctl;
+
+ if (!buffer)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ unlock = READ_REG32 (DC3_UNLOCK);
+ genlk_ctl = READ_REG32 (DC3_GENLK_CTL);
+ vip_control1 = READ_VIP32 (VIP_CONTROL1);
+ vip_control2 = READ_VIP32 (VIP_CONTROL2);
+
+ /* UPDATE VIDEO DETECTION */
+ /* These flags are used to indicate the ways in which the VIP signal can */
+ /* be considered 'lost'. */
+
+ vip_control1 &= ~VIP_CONTROL1_VDE_FF_MASK;
+ vip_control2 &= ~(VIP_CONTROL2_FIELD2VG_MASK | VIP_CONTROL2_SYNC2VG_MASK);
+ vip_control1 |= buffer->vip_signal_loss;
+
+ /* UPDATE FIELD AND VSYNC INFORMATION */
+ /* These flags control how and when the even/odd field and Vsync */
+ /* information is communicated to the VG. */
+
+ vip_control2 |= buffer->field_to_vg;
+ vip_control2 |= buffer->vsync_to_vg;
+
+ /* ENABLE OR DISABLE GENLOCK TIMEOUT */
+ /* Enabling genlock timeout allows the VG to revert to its own sync */
+ /* timings when the VIP input is lost. Note that the VIP will not */
+ /* know the signal is lost unless the appropriate error detection */
+ /* flags have been enabled inside vip_initialize. */
+
+ if (buffer->enable_timeout) genlk_ctl |= DC3_GC_GENLOCK_TO_ENABLE;
+ else genlk_ctl &= ~DC3_GC_GENLOCK_TO_ENABLE;
+
+ genlk_ctl &= ~DC3_GC_GENLOCK_SKEW_MASK;
+ genlk_ctl |= buffer->genlock_skew & DC3_GC_GENLOCK_SKEW_MASK;
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_GENLK_CTL, genlk_ctl);
+ WRITE_VIP32 (VIP_CONTROL1, vip_control1);
+ WRITE_VIP32 (VIP_CONTROL2, vip_control2);
+ WRITE_REG32 (DC3_UNLOCK, unlock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_set_genlock_enable
+ *
+ * This routine enables/disables genlock inside the VG.
+ *---------------------------------------------------------------------------*/
+
+int vip_set_genlock_enable (int enable)
+{
+ unsigned long unlock, temp;
+
+ unlock = READ_REG32 (DC3_UNLOCK);
+ temp = READ_REG32 (DC3_GENLK_CTL);
+
+ if (enable) temp |= DC3_GC_GENLOCK_ENABLE;
+ else temp &= ~DC3_GC_GENLOCK_ENABLE;
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_GENLK_CTL, temp);
+ WRITE_REG32 (DC3_UNLOCK, unlock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_set_power_characteristics
+ *
+ * This routine takes a VIPPOWERBUFFER structure, and selectively sets the
+ * GeodeLink power and/or Vip clock power states.
+ *---------------------------------------------------------------------------*/
+
+int vip_set_power_characteristics (VIPPOWERBUFFER *buffer)
+{
+ Q_WORD q_word;
+
+ if (!buffer)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ q_word.low = q_word.high = 0;
+
+ /* ENABLE GEODELINK CLOCK GATING */
+
+ if (buffer->glink_clock_mode)
+ q_word.low |= VIP_MSR_POWER_GLINK;
+
+ /* ENABLE VIP CLOCK GATING */
+
+ if (buffer->vip_clock_mode)
+ q_word.low |= VIP_MSR_POWER_CLOCK;
+
+ /* WRITE THE NEW VALUE */
+
+ msr_write64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_PM, &q_word);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_set_priority_characteristics
+ *
+ * This routine programs the VIP GeodeLink priority characteristics
+ *---------------------------------------------------------------------------*/
+
+int vip_set_priority_characteristics (VIPPRIORITYBUFFER *buffer)
+{
+ Q_WORD q_word;
+
+ if (!buffer)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ q_word.low = q_word.high = 0;
+
+ q_word.low |= (buffer->secondary << VIP_MSR_MCR_SECOND_PRIORITY_SHIFT) & VIP_MSR_MCR_SECOND_PRIORITY_MASK;
+ q_word.low |= (buffer->primary << VIP_MSR_MCR_PRIMARY_PRIORITY_SHIFT) & VIP_MSR_MCR_PRIMARY_PRIORITY_MASK;
+ q_word.low |= (buffer->pid << VIP_MSR_MCR_PID_SHIFT) & VIP_MSR_MCR_PID_MASK;
+
+ msr_write64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CONFIG, &q_word);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_set_debug_characteristics
+ *
+ * This routine configures the debug data that is exposed over the diag bus.
+ *---------------------------------------------------------------------------*/
+
+int vip_set_debug_characteristics (VIPDEBUGBUFFER *buffer)
+{
+ Q_WORD q_word;
+
+ if (!buffer)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ q_word.low = q_word.high = 0;
+
+ q_word.high |= (buffer->bist << VIP_MSR_DIAG_BIST_SHIFT) & VIP_MSR_DIAG_BIST_WMASK;
+ q_word.low |= (buffer->enable_upper ? VIP_MSR_DIAG_MSB_ENABLE : 0x00000000);
+ q_word.low |= (buffer->select_upper << VIP_MSR_DIAG_SEL_UPPER_SHIFT) & VIP_MSR_DIAG_SEL_UPPER_MASK;
+ q_word.low |= (buffer->enable_lower ? VIP_MSR_DIAG_LSB_ENABLE : 0x00000000 );
+ q_word.low |= (buffer->select_lower << VIP_MSR_DIAG_SEL_LOWER_SHIFT) & VIP_MSR_DIAG_SEL_LOWER_MASK;
+
+ msr_write64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_DIAG, &q_word);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_configure_pages
+ *
+ * This routine sets the number of pages, and their offset from each other.
+ *---------------------------------------------------------------------------*/
+
+int vip_configure_pages (int page_count, unsigned long page_offset)
+{
+ unsigned long vip_control2 = READ_VIP32 (VIP_CONTROL2);
+
+ /* SET THE NEW PAGE COUNT */
+
+ vip_control2 &= ~VIP_CONTROL2_PAGECNT_MASK;
+ vip_control2 |= (page_count << VIP_CONTROL2_PAGECNT_SHIFT) & VIP_CONTROL2_PAGECNT_MASK;
+
+ /* WRITE THE PAGE OFFSET */
+
+ WRITE_VIP32 (VIP_CONTROL2, vip_control2);
+ WRITE_VIP32 (VIP_PAGE_OFFSET, page_offset);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_set_interrupt_line
+ *
+ * This routine sets the line at which a line interrupt should be generated.
+ *---------------------------------------------------------------------------*/
+
+int vip_set_interrupt_line (int line)
+{
+ WRITE_VIP32 (VIP_CURRENT_TARGET, (line << VIP_CTARGET_TLINE_SHIFT) & VIP_CTARGET_TLINE_MASK);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_reset
+ *
+ * This routine does a one-shot enable of the VIP hardware. It is useful
+ * for handling unrecoverable VIP errors.
+ *---------------------------------------------------------------------------*/
+
+int vip_reset (void)
+{
+ unsigned long vip_control1, vip_control3;
+
+ /* INVERT THE PAUSE BIT */
+
+ vip_control1 = READ_VIP32 (VIP_CONTROL1);
+ vip_control3 = READ_VIP32 (VIP_CONTROL3);
+
+ WRITE_VIP32 (VIP_CONTROL1, vip_control1 | VIP_CONTROL1_RESET);
+ WRITE_VIP32 (VIP_CONTROL1, vip_control1 & ~VIP_CONTROL1_RESET);
+ WRITE_VIP32 (VIP_CONTROL3, vip_control3 | VIP_CONTROL3_FIFO_RESET);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_set_subwindow_enable
+ *
+ * This routine turns on SubWindow capture, that is a portion of the incoming
+ * signal is captured rather than the entire frame. The window always has
+ * the same width as the frame, only the vertical component can be
+ * modified.
+ *---------------------------------------------------------------------------*/
+
+int vip_set_subwindow_enable (VIPSUBWINDOWBUFFER *buffer)
+{
+ unsigned long vip_control2;
+
+ if (!buffer)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ vip_control2 = READ_VIP32 (VIP_CONTROL2);
+ if (buffer->enable)
+ {
+ /* WRITE THE WINDOW VALUE */
+
+ WRITE_VIP32(VIP_VERTICAL_START_STOP,
+ ((buffer->stop << VIP_VSTART_VERTEND_SHIFT) & VIP_VSTART_VERTEND_MASK) |
+ ((buffer->start << VIP_VSTART_VERTSTART_SHIFT) & VIP_VSTART_VERTSTART_MASK));
+
+ /* ENABLE IN THE CONTROL REGISTER */
+
+ vip_control2 |= VIP_CONTROL2_SWC_ENABLE;
+ }
+ else
+ {
+ /* DISABLE SUBWINDOW CAPTURE IN THE CONTROL REGISTER */
+
+ vip_control2 &= ~VIP_CONTROL2_SWC_ENABLE;
+ }
+ WRITE_VIP32 (VIP_CONTROL2, vip_control2);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_reset_interrupt_state
+ *
+ * This routine resets the state of one or more interrupts.
+ *---------------------------------------------------------------------------*/
+
+int vip_reset_interrupt_state(unsigned long interrupt_mask)
+{
+ unsigned long temp;
+
+ temp = READ_VIP32(VIP_INTERRUPT);
+ WRITE_VIP32 (VIP_INTERRUPT, temp | (interrupt_mask & VIP_ALL_INTERRUPTS));
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_save_state
+ *
+ * This routine saves the necessary register contents in order to restore
+ * at a later point to the same state.
+ *
+ * NOTE: Capture state is forced to OFF in this routine
+ *---------------------------------------------------------------------------*/
+
+int vip_save_state(VIPSTATEBUFFER *save_buffer)
+{
+ if (!save_buffer)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ /* FORCE CAPTURE TO BE DISABLED */
+
+ vip_set_capture_state (VIP_STOPCAPTURE);
+
+ /* READ AND SAVE THE REGISTER CONTENTS */
+
+ save_buffer->control1 = READ_VIP32(VIP_CONTROL1);
+ save_buffer->control2 = READ_VIP32(VIP_CONTROL2);
+ save_buffer->vip_int = READ_VIP32(VIP_INTERRUPT);
+ save_buffer->current_target = READ_VIP32(VIP_CURRENT_TARGET);
+ save_buffer->max_address = READ_VIP32(VIP_MAX_ADDRESS);
+ save_buffer->taska_evenbase = READ_VIP32(VIP_TASKA_VID_EVEN_BASE);
+ save_buffer->taska_oddbase = READ_VIP32(VIP_TASKA_VID_ODD_BASE);
+ save_buffer->taska_vbi_evenbase = READ_VIP32(VIP_TASKA_VBI_EVEN_BASE);
+ save_buffer->taska_vbi_oddbase = READ_VIP32(VIP_TASKA_VBI_ODD_BASE);
+ save_buffer->taska_data_pitch = READ_VIP32(VIP_TASKA_VID_PITCH);
+ save_buffer->control3 = READ_VIP32(VIP_CONTROL3);
+ save_buffer->taska_v_oddoffset = READ_VIP32(VIP_TASKA_U_OFFSET);
+ save_buffer->taska_u_oddoffset = READ_VIP32(VIP_TASKA_V_OFFSET);
+ save_buffer->taskb_evenbase = READ_VIP32(VIP_TASKB_VID_EVEN_BASE);
+ save_buffer->taskb_oddbase = READ_VIP32(VIP_TASKB_VID_ODD_BASE);
+ save_buffer->taskb_vbi_evenbase = READ_VIP32(VIP_TASKB_VBI_EVEN_BASE);
+ save_buffer->taskb_vbi_oddbase = READ_VIP32(VIP_TASKB_VBI_ODD_BASE);
+ save_buffer->taskb_pitch = READ_VIP32(VIP_TASKB_VID_PITCH);
+ save_buffer->taskb_voffset = READ_VIP32(VIP_TASKB_U_OFFSET);
+ save_buffer->taskb_uoffset = READ_VIP32(VIP_TASKB_V_OFFSET);
+ save_buffer->msg1_base = READ_VIP32(VIP_ANC_MSG1_BASE);
+ save_buffer->msg2_base = READ_VIP32(VIP_ANC_MSG2_BASE);
+ save_buffer->msg_size = READ_VIP32(VIP_ANC_MSG_SIZE);
+ save_buffer->page_offset = READ_VIP32(VIP_PAGE_OFFSET);
+ save_buffer->vert_start_stop = READ_VIP32(VIP_VERTICAL_START_STOP);
+ save_buffer->vsync_err_count = READ_VIP32(VIP_VSYNC_ERR_COUNT);
+ save_buffer->taska_u_evenoffset = READ_VIP32(VIP_TASKA_U_EVEN_OFFSET);
+ save_buffer->taska_v_evenoffset = READ_VIP32(VIP_TASKA_V_EVEN_OFFSET);
+
+ /* READ ALL VIP MSRS */
+
+ msr_read64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CONFIG, &(save_buffer->msr_config));
+ msr_read64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_SMI, &(save_buffer->msr_smi));
+ msr_read64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_PM, &(save_buffer->msr_pm));
+ msr_read64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_DIAG, &(save_buffer->msr_diag));
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_restore_state
+ *
+ * This routine restores the state of the vip registers - which were
+ * previously saved using vip_save_state.
+ *---------------------------------------------------------------------------*/
+
+int vip_restore_state (VIPSTATEBUFFER *restore_buffer)
+{
+ if (!restore_buffer)
+ return CIM_STATUS_OK;
+
+ /* RESTORE THE REGISTERS */
+
+ WRITE_VIP32(VIP_CURRENT_TARGET, restore_buffer->current_target);
+ WRITE_VIP32(VIP_MAX_ADDRESS, restore_buffer->max_address);
+ WRITE_VIP32(VIP_TASKA_VID_EVEN_BASE, restore_buffer->taska_evenbase);
+ WRITE_VIP32(VIP_TASKA_VID_ODD_BASE, restore_buffer->taska_oddbase);
+ WRITE_VIP32(VIP_TASKA_VBI_EVEN_BASE, restore_buffer->taska_vbi_evenbase);
+ WRITE_VIP32(VIP_TASKA_VBI_ODD_BASE, restore_buffer->taska_vbi_oddbase);
+ WRITE_VIP32(VIP_TASKA_VID_PITCH, restore_buffer->taska_data_pitch);
+ WRITE_VIP32(VIP_CONTROL3, restore_buffer->control3);
+ WRITE_VIP32(VIP_TASKA_U_OFFSET, restore_buffer->taska_v_oddoffset);
+ WRITE_VIP32(VIP_TASKA_V_OFFSET, restore_buffer->taska_u_oddoffset);
+ WRITE_VIP32(VIP_TASKB_VID_EVEN_BASE, restore_buffer->taskb_evenbase);
+ WRITE_VIP32(VIP_TASKB_VID_ODD_BASE, restore_buffer->taskb_oddbase);
+ WRITE_VIP32(VIP_TASKB_VBI_EVEN_BASE, restore_buffer->taskb_vbi_evenbase);
+ WRITE_VIP32(VIP_TASKB_VBI_ODD_BASE, restore_buffer->taskb_vbi_oddbase);
+ WRITE_VIP32(VIP_TASKB_VID_PITCH, restore_buffer->taskb_pitch);
+ WRITE_VIP32(VIP_TASKB_U_OFFSET, restore_buffer->taskb_voffset);
+ WRITE_VIP32(VIP_TASKB_V_OFFSET, restore_buffer->taskb_uoffset);
+ WRITE_VIP32(VIP_ANC_MSG1_BASE, restore_buffer->msg1_base);
+ WRITE_VIP32(VIP_ANC_MSG2_BASE, restore_buffer->msg2_base);
+ WRITE_VIP32(VIP_ANC_MSG_SIZE, restore_buffer->msg_size);
+ WRITE_VIP32(VIP_PAGE_OFFSET, restore_buffer->page_offset);
+ WRITE_VIP32(VIP_VERTICAL_START_STOP, restore_buffer->vert_start_stop);
+ WRITE_VIP32(VIP_VSYNC_ERR_COUNT, restore_buffer->vsync_err_count);
+ WRITE_VIP32(VIP_TASKA_U_EVEN_OFFSET, restore_buffer->taska_u_evenoffset);
+ WRITE_VIP32(VIP_TASKA_V_EVEN_OFFSET, restore_buffer->taska_v_evenoffset);
+
+ /* RESTORE THE VIP MSRS */
+
+ msr_write64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CONFIG, &(restore_buffer->msr_config));
+ msr_write64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_SMI, &(restore_buffer->msr_smi));
+ msr_write64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_PM, &(restore_buffer->msr_pm));
+ msr_write64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_DIAG, &(restore_buffer->msr_diag));
+
+ /* RESTORE THE CONTROL WORDS LAST */
+
+ WRITE_VIP32(VIP_CONTROL1, restore_buffer->control1);
+ WRITE_VIP32(VIP_CONTROL2, restore_buffer->control2);
+ WRITE_VIP32(VIP_CONTROL3, restore_buffer->control3);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_get_interrupt_state
+ *
+ * This routine returns the current interrupt state of the system. The
+ * rv can be tested with the following flags to determine if the appropriate
+ * event has occured.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vip_get_interrupt_state(void)
+{
+ unsigned long interrupt_mask = READ_VIP32(VIP_INTERRUPT);
+
+ return (~(interrupt_mask << 16) & interrupt_mask & VIP_ALL_INTERRUPTS);
+}
+
+/*---------------------------------------------------------------------------
+ * vip_test_genlock_active
+ *
+ * This routine reads the live status of the genlock connection between the VIP
+ * and VG blocks.
+ *---------------------------------------------------------------------------*/
+
+int vip_test_genlock_active (void)
+{
+ if (READ_REG32 (DC3_GENLK_CTL) & DC3_GC_GENLK_ACTIVE)
+ return 1;
+
+ return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_test_signal_status
+ *
+ * This routine reads the live signal status coming into the VIP block.
+ *---------------------------------------------------------------------------*/
+
+int vip_test_signal_status (void)
+{
+ if (READ_REG32 (DC3_GENLK_CTL) & DC3_GC_VIP_VID_OK)
+ return 1;
+
+ return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_get_current_field
+ *
+ * This routine returns the current field being received.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vip_get_current_field (void)
+{
+ if (READ_VIP32(VIP_STATUS) & VIP_STATUS_FIELD)
+ return VIP_EVEN_FIELD;
+
+ return VIP_ODD_FIELD;
+}
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * CIMARRON VIP READ ROUTINES
+ * These routines are included for use in diagnostics or when debugging. They
+ * can be optionally excluded from a project.
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+#if CIMARRON_INCLUDE_VIP_READ_ROUTINES
+
+/*---------------------------------------------------------------------------
+ * vip_get_current_mode
+ *
+ * This routine reads the current VIP operating mode.
+ *---------------------------------------------------------------------------*/
+
+int vip_get_current_mode (VIPSETMODEBUFFER *buffer)
+{
+ unsigned long vip_control1, vip_control2, vip_control3;
+
+ if (!buffer)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ vip_control1 = READ_VIP32 (VIP_CONTROL1);
+ vip_control2 = READ_VIP32 (VIP_CONTROL2);
+ vip_control3 = READ_VIP32 (VIP_CONTROL3);
+
+ /* READ CURRENT OPERATING MODE AND ENABLES */
+
+ buffer->stream_enables = vip_control1 & VIP_ENABLE_ALL;
+ buffer->operating_mode = vip_control1 & VIP_CONTROL1_MODE_MASK;
+
+ /* READ CURRENT PLANAR CAPTURE SETTINGS */
+
+ buffer->flags = 0;
+ buffer->planar_capture = 0;
+ if (vip_control1 & VIP_CONTROL1_PLANAR)
+ {
+ buffer->flags |= VIP_MODEFLAG_PLANARCAPTURE;
+ if (vip_control1 & VIP_CONTROL1_DISABLE_DECIMATION)
+ {
+ if (vip_control3 & VIP_CONTROL3_DECIMATE_EVEN)
+ buffer->planar_capture = VIP_420CAPTURE_ALTERNATINGFIELDS;
+ else
+ buffer->planar_capture = VIP_420CAPTURE_EVERYLINE;
+ }
+ else
+ buffer->planar_capture = VIP_420CAPTURE_ALTERNATINGLINES;
+ }
+
+ /* READ MISCELLANEOUS FLAGS */
+
+ if (vip_control1 & VIP_CONTROL1_NON_INTERLACED)
+ buffer->flags |= VIP_MODEFLAG_PROGRESSIVE;
+ if (vip_control3 & VIP_CONTROL3_BASE_UPDATE)
+ buffer->flags |= VIP_MODEFLAG_TOGGLEEACHFIELD;
+ if (vip_control2 & VIP_CONTROL2_INVERT_POLARITY)
+ buffer->flags |= VIP_MODEFLAG_INVERTPOLARITY;
+ if (vip_control1 & VIP_CONTROL1_MSG_STRM_CTRL)
+ buffer->flags |= VIP_MODEFLAG_FLIPMESSAGEWHENFULL;
+ if (vip_control2 & VIP_CONTROL2_REPEAT_ENABLE)
+ buffer->flags |= VIP_MODEFLAG_ENABLEREPEATFLAG;
+ if (vip_control3 & VIP_CONTROL3_TASK_POLARITY)
+ buffer->flags |= VIP_MODEFLAG_INVERTTASKPOLARITY;
+ if (vip_control1 & VIP_CONTROL1_DISABLE_ZERO_DETECT)
+ buffer->flags |= VIP_MODEFLAG_DISABLEZERODETECT;
+ if (vip_control2 & VIP_CONTROL2_ANC10)
+ buffer->flags |= VIP_MODEFLAG_10BITANCILLARY;
+
+ /* READ THE CURRENT VIP 601 SETTINGS */
+
+ vip_get_601_configuration (&buffer->vip601_settings);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_get_601_configuration
+ *
+ * This routine returns the current 601 configuration information.
+ *---------------------------------------------------------------------------*/
+
+int vip_get_601_configuration (VIP_601PARAMS *buffer)
+{
+ unsigned long vip_control3, vip_control1;
+
+ if (!buffer)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ vip_control1 = READ_VIP32 (VIP_CONTROL3);
+ vip_control3 = READ_VIP32 (VIP_CONTROL3);
+
+ buffer->flags = 0;
+ if (vip_control3 & VIP_CONTROL3_VSYNC_POLARITY) buffer->flags |= VIP_MODEFLAG_VSYNCACTIVEHIGH;
+ if (vip_control3 & VIP_CONTROL3_HSYNC_POLARITY) buffer->flags |= VIP_MODEFLAG_HSYNCACTIVEHIGH;
+
+ buffer->horz_start = READ_VIP32 (VIP_601_HORZ_START);
+ buffer->vbi_start = READ_VIP32 (VIP_601_VBI_START);
+ buffer->vbi_height = READ_VIP32 (VIP_601_VBI_END) - buffer->vbi_start + 1;
+ buffer->vert_start_even = READ_VIP32 (VIP_601_EVEN_START_STOP) & 0xFFFF;
+ buffer->even_height = (READ_VIP32 (VIP_601_EVEN_START_STOP) >> 16) - buffer->vert_start_even + 1;
+ buffer->vert_start_odd = READ_VIP32 (VIP_601_ODD_START_STOP) & 0xFFFF;
+ buffer->odd_height = (READ_VIP32 (VIP_601_ODD_START_STOP) >> 16) - buffer->vert_start_odd + 1;
+ buffer->odd_detect_start = READ_VIP32 (VIP_ODD_FIELD_DETECT) & 0xFFFF;
+ buffer->odd_detect_end = READ_VIP32 (VIP_ODD_FIELD_DETECT) >> 16;
+
+ /* SPECIAL CASE FOR HORIZONTAL DATA */
+ /* 601 horizontal parameters are based on the number of clocks and not the */
+ /* number of pixels. */
+
+ if ((vip_control1 & VIP_CONTROL1_MODE_MASK) == VIP_MODE_16BIT601)
+ buffer->width = (READ_VIP32 (VIP_601_HORZ_END) - buffer->horz_start - 3) >> 1;
+ else
+ buffer->width = (READ_VIP32 (VIP_601_HORZ_END) - buffer->horz_start - 3);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_get_buffer_configuration
+ *
+ * This routine reads the current buffer configuration for Task A, Task B,
+ * ancillary or message data. The current_buffer member indicates which
+ * array index should hold the new values for Task A or Task B data.
+ *---------------------------------------------------------------------------*/
+
+int vip_get_buffer_configuration (int buffer_type, VIPINPUTBUFFER *buffer)
+{
+ unsigned long cur_buffer = buffer->current_buffer;
+ VIPINPUTBUFFER_ADDR *offsets;
+
+ if (!buffer)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ if (buffer_type == VIP_BUFFER_A)
+ {
+ offsets = &buffer->offsets[VIP_BUFFER_TASK_A];
+
+ /* READ VIDEO PITCH */
+
+ offsets->y_pitch = READ_VIP32 (VIP_TASKA_VID_PITCH) & 0xFFFF;
+ offsets->uv_pitch = READ_VIP32 (VIP_TASKA_VID_PITCH) >> 16;
+
+ /* READ BASE OFFSETS */
+
+ if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
+ {
+ offsets->even_base[cur_buffer] = READ_VIP32 (VIP_TASKA_VID_ODD_BASE);
+ offsets->odd_base[cur_buffer] = READ_VIP32 (VIP_TASKA_VID_EVEN_BASE);
+
+ if (buffer->flags & VIP_INPUTFLAG_VBI)
+ {
+ offsets->vbi_even_base = READ_VIP32 (VIP_TASKA_VBI_ODD_BASE);
+ offsets->vbi_odd_base = READ_VIP32 (VIP_TASKA_VBI_EVEN_BASE);
+ }
+ }
+ else
+ {
+ offsets->even_base[cur_buffer] = READ_VIP32 (VIP_TASKA_VID_EVEN_BASE);
+ offsets->odd_base[cur_buffer] = READ_VIP32 (VIP_TASKA_VID_ODD_BASE);
+
+ if (buffer->flags & VIP_INPUTFLAG_VBI)
+ {
+ offsets->vbi_even_base = READ_VIP32 (VIP_TASKA_VBI_EVEN_BASE);
+ offsets->vbi_odd_base = READ_VIP32 (VIP_TASKA_VBI_ODD_BASE);
+ }
+ }
+
+ /* READ 4:2:0 OFFSETS */
+
+ if (buffer->flags & VIP_INPUTFLAG_PLANAR)
+ {
+ offsets->odd_uoffset = READ_VIP32 (VIP_TASKA_U_OFFSET);
+ offsets->odd_voffset = READ_VIP32 (VIP_TASKA_V_OFFSET);
+ offsets->even_uoffset = READ_VIP32 (VIP_TASKA_U_EVEN_OFFSET);
+ offsets->even_voffset = READ_VIP32 (VIP_TASKA_V_EVEN_OFFSET);
+ }
+ }
+ else if (buffer_type == VIP_BUFFER_B)
+ {
+ offsets = &buffer->offsets[VIP_BUFFER_TASK_B];
+
+ /* READ VIDEO PITCH */
+
+ offsets->y_pitch = READ_VIP32 (VIP_TASKB_VID_PITCH) & 0xFFFF;
+ offsets->uv_pitch = READ_VIP32 (VIP_TASKB_VID_PITCH) >> 16;
+
+ /* READ BASE OFFSETS */
+
+ if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
+ {
+ offsets->even_base[cur_buffer] = READ_VIP32 (VIP_TASKB_VID_ODD_BASE);
+ offsets->odd_base[cur_buffer] = READ_VIP32 (VIP_TASKB_VID_EVEN_BASE);
+
+ if (buffer->flags & VIP_INPUTFLAG_VBI)
+ {
+ offsets->vbi_even_base = READ_VIP32 (VIP_TASKB_VBI_ODD_BASE);
+ offsets->vbi_odd_base = READ_VIP32 (VIP_TASKB_VBI_EVEN_BASE);
+ }
+ }
+ else
+ {
+ offsets->even_base[cur_buffer] = READ_VIP32 (VIP_TASKB_VID_EVEN_BASE);
+ offsets->odd_base[cur_buffer] = READ_VIP32 (VIP_TASKB_VID_ODD_BASE);
+
+ if (buffer->flags & VIP_INPUTFLAG_VBI)
+ {
+ offsets->vbi_even_base = READ_VIP32 (VIP_TASKB_VBI_EVEN_BASE);
+ offsets->vbi_odd_base = READ_VIP32 (VIP_TASKB_VBI_ODD_BASE);
+ }
+ }
+
+ /* READ 4:2:0 OFFSETS */
+
+ if (buffer->flags & VIP_INPUTFLAG_PLANAR)
+ {
+ offsets->odd_uoffset = READ_VIP32 (VIP_TASKB_U_OFFSET);
+ offsets->odd_voffset = READ_VIP32 (VIP_TASKB_V_OFFSET);
+ }
+ }
+ else if (buffer_type == VIP_BUFFER_ANC || buffer_type == VIP_BUFFER_MSG)
+ {
+ buffer->ancillaryData.msg1_base = READ_VIP32(VIP_ANC_MSG1_BASE);
+ buffer->ancillaryData.msg2_base = READ_VIP32(VIP_ANC_MSG2_BASE);
+ buffer->ancillaryData.msg_size = READ_VIP32(VIP_ANC_MSG_SIZE);
+ }
+ else
+ {
+ return CIM_STATUS_INVALIDPARAMS;
+ }
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_get_genlock_configuration
+ *
+ * This routine reads the current genlock configuration.
+ *---------------------------------------------------------------------------*/
+
+int vip_get_genlock_configuration (VIPGENLOCKBUFFER *buffer)
+{
+ unsigned long vip_control1, vip_control2;
+ unsigned long genlk_ctl;
+
+ if (!buffer)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ genlk_ctl = READ_REG32 (DC3_GENLK_CTL);
+ vip_control1 = READ_VIP32 (VIP_CONTROL1);
+ vip_control2 = READ_VIP32 (VIP_CONTROL2);
+
+ /* READ ERROR DETECTION, CURRENT FIELD AND CURRENT VSYNC */
+ /* These flags are used to indicate the ways in which the VIP signal can */
+ /* be considered 'lost'. */
+
+ buffer->vip_signal_loss = vip_control1 & VIP_CONTROL1_VDE_FF_MASK;
+ buffer->field_to_vg = vip_control2 & VIP_CONTROL2_FIELD2VG_MASK;
+ buffer->vsync_to_vg = vip_control2 & VIP_CONTROL2_SYNC2VG_MASK;
+
+ /* GENLOCK TIMEOUT ENABLE */
+
+ buffer->enable_timeout = 0;
+ if (genlk_ctl & DC3_GC_GENLOCK_TO_ENABLE)
+ buffer->enable_timeout = 1;
+
+ /* GENLOCK SKEW */
+
+ buffer->genlock_skew = genlk_ctl & DC3_GC_GENLOCK_SKEW_MASK;
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_get_genlock_enable
+ *
+ * This routine returns the current enable status of genlock in the VG.
+ *---------------------------------------------------------------------------*/
+
+int vip_get_genlock_enable (void)
+{
+ if (READ_REG32 (DC3_GENLK_CTL) & DC3_GC_GENLOCK_ENABLE)
+ return 1;
+
+ return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_is_buffer_update_latched
+ *
+ * This routine indicates whether changes to the VIP offsets have been latched by
+ * the hardware.
+ *---------------------------------------------------------------------------*/
+
+int vip_is_buffer_update_latched (void)
+{
+ return (!(READ_VIP32(VIP_STATUS) & VIP_STATUS_BASEREG_NOTUPDT));
+}
+
+/*---------------------------------------------------------------------------
+ * vip_get_capture_state
+ *
+ * This routine reads the current capture status of the VIP hardware.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vip_get_capture_state (void)
+{
+ return ((READ_VIP32(VIP_CONTROL1) & VIP_CONTROL1_RUNMODE_MASK) >> VIP_CONTROL1_RUNMODE_SHIFT);
+}
+
+/*---------------------------------------------------------------------------
+ * vip_get_current_line
+ *
+ * This routine returns the current line that is being processed.
+ *---------------------------------------------------------------------------*/
+
+unsigned long vip_get_current_line (void)
+{
+ return (READ_VIP32(VIP_CURRENT_TARGET) & VIP_CTARGET_CLINE_MASK);
+}
+
+/*---------------------------------------------------------------------------
+ * vip_read_fifo
+ *
+ * This routine reads from the specified fifo address. As the fifo access
+ * enable should be disabled when running in normal vip mode, this routine
+ * enables and disables access around the read.
+ * DIAGNOSTIC USE ONLY
+ *---------------------------------------------------------------------------*/
+
+unsigned long vip_read_fifo(unsigned long dwFifoAddress)
+{
+ unsigned long fifo_data;
+
+ /* ENABLE FIFO ACCESS */
+
+ vip_enable_fifo_access (1);
+
+ /* NOW READ THE DATA */
+
+ WRITE_VIP32(VIP_FIFO_ADDRESS, dwFifoAddress);
+ fifo_data = READ_VIP32(VIP_FIFO_DATA);
+
+ /* DISABLE FIFO ACCESS */
+
+ vip_enable_fifo_access (0);
+
+ return fifo_data;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_write_fifo
+ *
+ * SYNOPSIS:
+ * This routine writes to the specified fifo address. As the fifo access
+ * enable should be disabled when running in normal vip mode, this routine
+ * enables and disables access around the write.
+ * DIAGNOSTIC USE ONLY
+ *---------------------------------------------------------------------------*/
+
+int vip_write_fifo (unsigned long dwFifoAddress, unsigned long dwFifoData)
+{
+ /* ENABLE FIFO ACCESS */
+
+ vip_enable_fifo_access(1);
+
+ /* WRITE THE FIFO DATA */
+
+ WRITE_VIP32(VIP_FIFO_ADDRESS, dwFifoAddress);
+ WRITE_VIP32(VIP_FIFO_DATA, dwFifoData);
+
+ /* DISABLE FIFO ACCESS */
+
+ vip_enable_fifo_access(0);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_enable_fifo_access
+ *
+ * This routine enables/disables access to the vip fifo.
+ * DIAGNOSTIC USE ONLY
+ *---------------------------------------------------------------------------*/
+
+int vip_enable_fifo_access (int enable)
+{
+ unsigned long cw2;
+
+ cw2 = READ_VIP32(VIP_CONTROL2);
+
+ if (enable) cw2 |= VIP_CONTROL2_FIFO_ACCESS;
+ else cw2 &= ~VIP_CONTROL2_FIFO_ACCESS;
+
+ WRITE_VIP32(VIP_CONTROL2, cw2);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_get_power_characteristics
+ *
+ * This routine returns the current VIP clock gating state in a VIPPOWERBUFFER.
+ *---------------------------------------------------------------------------*/
+
+int vip_get_power_characteristics(VIPPOWERBUFFER *buffer)
+{
+ Q_WORD q_word;
+
+ if (!buffer)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ /* READ THE EXISTING STATE */
+
+ msr_read64(MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_PM, &q_word);
+
+ /* DECODE THE CLOCK GATING BITS */
+
+ buffer->glink_clock_mode = (int)(q_word.low & VIP_MSR_POWER_GLINK);
+ buffer->vip_clock_mode = (int)(q_word.low & VIP_MSR_POWER_CLOCK);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_get_priority_characteristics
+ *
+ * This routine returns the priority characteristics in the supplied
+ * VIPPRIORITYBUFFER.
+ *---------------------------------------------------------------------------*/
+
+int vip_get_priority_characteristics(VIPPRIORITYBUFFER *buffer)
+{
+ Q_WORD q_word;
+
+ if (!buffer)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ /* READ THE CURRENT STATE */
+
+ msr_read64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CONFIG, &q_word);
+
+ /* DECODE THE PRIORITIES */
+
+ buffer->secondary = (q_word.low & VIP_MSR_MCR_SECOND_PRIORITY_MASK) >> VIP_MSR_MCR_SECOND_PRIORITY_SHIFT;
+ buffer->primary = (q_word.low & VIP_MSR_MCR_PRIMARY_PRIORITY_MASK) >> VIP_MSR_MCR_PRIMARY_PRIORITY_SHIFT;
+ buffer->pid = q_word.low & VIP_MSR_MCR_PID_MASK;
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vip_get_capability_characteristics
+ *
+ * This routine returns revision information for the device.
+ *---------------------------------------------------------------------------*/
+
+int vip_get_capability_characteristics(VIPCAPABILITIESBUFFER *buffer)
+{
+ Q_WORD q_word ;
+
+ if (!buffer)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ /* READ THE CURRENT MSR CONTENTS */
+
+ msr_read64 (MSR_DEVICE_GEODELX_VIP, MSR_GEODELINK_CAP, &q_word);
+
+ /* DECODE THE REVISIONS */
+
+ buffer->revision_id = (q_word.low & VIP_MSR_CAP_REVID_MASK) >> VIP_MSR_CAP_REVID_SHIFT;
+ buffer->device_id = (q_word.low & VIP_MSR_CAP_DEVID_MASK) >> VIP_MSR_CAP_DEVID_SHIFT;
+ buffer->n_clock_domains = (q_word.low & VIP_MSR_CAP_NCLK_MASK) >> VIP_MSR_CAP_NCLK_SHIFT;
+ buffer->n_smi_registers = (q_word.low & VIP_MSR_CAP_NSMI_MASK) >> VIP_MSR_CAP_NSMI_SHIFT;
+
+ return CIM_STATUS_OK;
+}
+
+
+
+#endif
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cim_vop.c xf86-video-nsc-2.8.1/src/cim/cim_vop.c
--- xf86-video-nsc-2.8.1-orig/src/cim/cim_vop.c 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cim_vop.c 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,564 @@
+ /*
+ *
+ * Copyright (C) 2005 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *
+ *
+ *
+ *
+ *
+ * Cimarron VOP configuration routines.
+ *
+ *
+ */
+
+/*---------------------------------------------------------------------------
+ * vop_set_vbi_window
+ *
+ * This routine configures the output position and location in memory of
+ * VBI data.
+ *---------------------------------------------------------------------------*/
+
+int vop_set_vbi_window (VOPVBIWINDOWBUFFER *buffer)
+{
+ unsigned long unlock, temp;
+ unsigned long hstart, hstop;
+ unsigned long htotal, hsyncstart;
+
+ if (!buffer)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ unlock = READ_REG32 (DC3_UNLOCK);
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+ /* PROGRAM HORIZONTAL POSITION */
+ /* The horizontal position is a little tricky. The counter for the horizontal */
+ /* timings is reused for the VBI counter. Consequently, the horizontal start */
+ /* and stop values are based off the beginning of active data. However, the */
+ /* VG has a quirk. If the counter start position is before the beginning of */
+ /* HSync, it applies to the previous line. If the counter is after the */
+ /* beginning of HSync it applies to the current line. So, for one line */
+ /* the real range can be thought of as HSync_start to (HSync_start + htotal - 1). */
+ /* However, the counters must be between 0 and htotal - 1. When placing VBI */
+ /* data before the start of active data, the horizontal end position will thus */
+ /* be *less* than the horizontal start. */
+
+ htotal = ((READ_REG32 (DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+ hsyncstart = (READ_REG32 (DC3_H_SYNC_TIMING) & 0xFFF) + 1;
+
+ if (buffer->horz_from_hsync)
+ {
+ /* VERIFY THAT THE INPUT IS VALID */
+
+ if (buffer->horz_start < 0 || (buffer->horz_start + buffer->vbi_width) > htotal)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ hstart = buffer->horz_start + hsyncstart;
+ }
+ else
+ {
+ /* VERIFY THAT THE INPUT IS VALID */
+
+ if (buffer->horz_start < ((long)hsyncstart - (long)htotal) ||
+ buffer->horz_start > (long)hsyncstart ||
+ buffer->vbi_width > htotal)
+ {
+ return CIM_STATUS_INVALIDPARAMS;
+ }
+
+ hstart = buffer->horz_start + htotal;
+ }
+
+ hstop = hstart + buffer->vbi_width;
+ if (hstart > htotal) hstart -= htotal;
+ if (hstop > htotal) hstop -= htotal;
+ hstart--;
+ hstop--;
+ WRITE_REG32 (DC3_VBI_HOR, ((hstop << DC3_VBI_HOR_END_SHIFT) & DC3_VBI_HOR_END_MASK) |
+ (hstart & DC3_VBI_HOR_START_MASK));
+
+ /* WRITE LINE CAPTURE MASKS */
+
+ WRITE_REG32 (DC3_VBI_LN_ODD, ((buffer->odd_line_offset << DC3_VBI_ODD_LINE_SHIFT) & DC3_VBI_ODD_LINE_MASK) |
+ (buffer->odd_line_capture_mask & DC3_VBI_ODD_ENABLE_MASK));
+
+ WRITE_REG32 (DC3_VBI_LN_EVEN, ((buffer->even_line_offset << DC3_VBI_EVEN_LINE_SHIFT) & DC3_VBI_EVEN_LINE_MASK) |
+ (buffer->even_line_capture_mask & DC3_VBI_EVEN_ENABLE_MASK));
+
+ /* PROGRAM SOURCE OFFSETS */
+ /* Start with the even offsets. Note that we always enable 16-bit VBI, as this */
+ /* is the only way to get VBI data on each VOP clock. */
+
+ temp = READ_REG32 (DC3_VBI_EVEN_CTL) & ~DC3_VBI_EVEN_CTL_OFFSET_MASK;
+ temp |= DC3_VBI_EVEN_CTL_ENABLE_16;
+ if (buffer->enable_upscale)
+ temp |= DC3_VBI_EVEN_CTL_UPSCALE;
+ WRITE_REG32 (DC3_VBI_EVEN_CTL, temp | (buffer->even_address_offset & DC3_VBI_EVEN_CTL_OFFSET_MASK));
+
+ /* ODD OFFSET */
+
+ temp = READ_REG32 (DC3_VBI_ODD_CTL) & ~DC3_VBI_ODD_CTL_OFFSET_MASK;
+ WRITE_REG32 (DC3_VBI_ODD_CTL, temp | (buffer->odd_address_offset & DC3_VBI_ODD_CTL_OFFSET_MASK));
+
+ /* PITCH */
+
+ temp = ((buffer->data_size >> 3) << 16) | ((buffer->data_pitch >> 3) & 0x0000FFFF);
+ WRITE_REG32(DC3_VBI_PITCH, temp);
+
+ WRITE_REG32 (DC3_UNLOCK, unlock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vop_enable_vbi_output
+ *
+ * This routine enables/disables VBI fetching inside the video generator.
+ *---------------------------------------------------------------------------*/
+
+int vop_enable_vbi_output (int enable)
+{
+ unsigned long unlock, temp;
+
+ unlock = READ_REG32 (DC3_UNLOCK);
+ temp = READ_REG32 (DC3_VBI_EVEN_CTL);
+
+ if (enable) temp |= DC3_VBI_ENABLE;
+ else temp &= ~DC3_VBI_ENABLE;
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_VBI_EVEN_CTL, temp);
+ WRITE_REG32 (DC3_UNLOCK, unlock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vop_set_configuration
+ *
+ * This routine is passed a VOP_CONFIGURATION structure that contains all
+ * the necessary information to configure VOP output.
+ *---------------------------------------------------------------------------*/
+
+int vop_set_configuration (VOPCONFIGURATIONBUFFER *config)
+{
+ unsigned long vop_config = 0;
+ unsigned long alpha, control2;
+ unsigned long unlock;
+ unsigned long delta;
+ Q_WORD msr_value;
+ int rgb = 0;
+
+ if (!config)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ unlock = READ_REG32 (DC3_UNLOCK);
+ delta = READ_REG32 (DC3_VID_DS_DELTA) & DC3_DS_DELTA_MASK;
+
+ /* OVERRIDE THE OUTPUT SETTINGS TO ENABLE VOP OUTPUT */
+
+ if (config->mode != VOP_MODE_DISABLED)
+ {
+ msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
+ msr_value.low &= ~DF_CONFIG_OUTPUT_MASK;
+ msr_value.low |= DF_OUTPUT_VOP;
+ msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
+ }
+
+ /* SET THE UNIVERSAL VOP OPTIONS */
+
+ if (config->flags & VOP_FLAG_SWAP_UV) vop_config |= VOP_CONFIG_SWAPUV;
+ if (config->flags & VOP_FLAG_SWAP_VBI) vop_config |= VOP_CONFIG_SWAPVBI;
+
+ /* SET THE MODE SPECIFIC PARAMETERS */
+
+ if (config->mode == VOP_MODE_601)
+ {
+ vop_config |= config->vop601.flags;
+ vop_config |= config->vop601.vsync_shift;
+ vop_config |= VOP_CONFIG_ENABLE_601 | VOP_CONFIG_VIP2_0;
+
+ switch (config->vop601.output_mode)
+ {
+ case VOP_601_YUV_16BIT:
+ vop_config |= VOP_CONFIG_VIP2_16BIT;
+ break;
+ case VOP_601_YUV_4_4_4:
+ vop_config |= VOP_CONFIG_DISABLE_DECIMATE;
+ break;
+ case VOP_601_RGB_8_8_8:
+ vop_config |= VOP_CONFIG_DISABLE_DECIMATE | VOP_CONFIG_RGBMODE;
+ rgb = 1;
+ break;
+ }
+
+ if (config->vop601.vsync_shift == VOP_VSYNC_LATER_BY_X)
+ {
+ delta |= (config->vop601.vsync_shift_count & DC3_601_VSYNC_SHIFT_MASK);
+ delta |= DC3_601_VSYNC_SHIFT_ENABLE;
+ }
+ }
+ else
+ {
+ if (config->flags & VOP_FLAG_VBI) vop_config |= VOP_CONFIG_VBI;
+ if (config->flags & VOP_FLAG_TASK) vop_config |= VOP_CONFIG_TASK;
+ if (config->flags & VOP_FLAG_SINGLECHIPCOMPAT) vop_config |= VOP_CONFIG_SC_COMPATIBLE;
+ if (config->flags & VOP_FLAG_EXTENDEDSAV) vop_config |= VOP_CONFIG_EXTENDED_SAV;
+
+ switch (config->mode)
+ {
+ case VOP_MODE_DISABLED:
+ vop_config |= VOP_CONFIG_DISABLED;
+ break;
+ case VOP_MODE_VIP11:
+ vop_config |= VOP_CONFIG_VIP1_1;
+ break;
+ case VOP_MODE_CCIR656:
+ vop_config |= VOP_CONFIG_CCIR656;
+ break;
+ case VOP_MODE_VIP20_8BIT:
+ vop_config |= VOP_CONFIG_VIP2_0;
+ break;
+ case VOP_MODE_VIP20_16BIT:
+ vop_config |= VOP_CONFIG_VIP2_0 | VOP_CONFIG_VIP2_16BIT;
+ break;
+ }
+ }
+
+ /* SET THE 4:4:4 TO 4:2:2 DECIMATION ALGORITHM */
+
+ vop_config |= (config->conversion_mode);
+
+ /* SET THE VSYNC OUT OPTIONS */
+
+ control2 = READ_VIP32 (VIP_CONTROL2) & ~VIP_CONTROL2_SYNC2PIN_MASK;
+ control2 |= config->vsync_out;
+ WRITE_VIP32 (VIP_CONTROL2, control2);
+
+ /* FORCE THE CORRECT VOP COLOR SPACE */
+ /* The output of the mixer will be either RGB or YUV. We must enable */
+ /* or disable the VOP CSC based on the desired output format. */
+
+ alpha = READ_VID32 (DF_VID_ALPHA_CONTROL);
+ if (!(alpha & DF_CSC_GRAPHICS_RGB_TO_YUV))
+ {
+ /* RGB OUTPUT FROM THE MIXER */
+
+ if (!rgb) alpha |= DF_CSC_VOP_RGB_TO_YUV;
+ else alpha &= ~DF_CSC_VOP_RGB_TO_YUV;
+ }
+ else
+ {
+ /* YUV OUTPUT FROM THE MIXER */
+ /* As there is no YUV->RGB VOP conversion, we simply disable the */
+ /* VOP CSC and trust that the user is competent. */
+
+ alpha &= ~DF_CSC_VOP_RGB_TO_YUV;
+ }
+
+ /* AND WRITE THE CONFIGURATION */
+
+ WRITE_VID32 (DF_VID_ALPHA_CONTROL, alpha);
+ WRITE_VOP32(VOP_CONFIGURATION, vop_config);
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_VID_DS_DELTA, delta);
+ WRITE_REG32 (DC3_UNLOCK, unlock);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vop_save_state
+ *
+ * This routine saves the necessary register contents in order to restore
+ * at a later point to the same state. Note that the capture state is
+ * forced to OFF in this routine.
+ *---------------------------------------------------------------------------*/
+
+int vop_save_state (VOPSTATEBUFFER *save_buffer)
+{
+ if (!save_buffer)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ save_buffer->config = READ_VOP32(VOP_CONFIGURATION);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vop_restore_state
+ *
+ * This routine restores the state of the vop registers - which were
+ * previously saved using vop_save_state.
+ *---------------------------------------------------------------------------*/
+
+int vop_restore_state (VOPSTATEBUFFER *restore_buffer)
+{
+ if (!restore_buffer)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ WRITE_VOP32(VOP_CONFIGURATION, restore_buffer->config);
+
+ return CIM_STATUS_OK;
+}
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * CIMARRON VOP READ ROUTINES
+ * These routines are included for use in diagnostics or when debugging. They
+ * can be optionally excluded from a project.
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+#if CIMARRON_INCLUDE_VOP_READ_ROUTINES
+
+/*---------------------------------------------------------------------------
+ * vop_get_current_mode
+ *
+ * This routine reads the current VIP operating mode and stores it in the
+ * passed VOP_CONFIGURATION structure.
+ *---------------------------------------------------------------------------*/
+
+int vop_get_current_mode (VOPCONFIGURATIONBUFFER *config)
+{
+ unsigned long vop_config = 0;
+ unsigned long alpha;
+
+ if (!config)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ vop_config = READ_VOP32 (VOP_CONFIGURATION);
+ alpha = READ_VID32 (DF_VID_ALPHA_CONTROL);
+
+ /* READ THE CURRENT MODE */
+
+ switch (vop_config & VOP_CONFIG_MODE_MASK)
+ {
+ case VOP_CONFIG_DISABLED: config->mode = VOP_MODE_DISABLED; break;
+ case VOP_CONFIG_VIP1_1: config->mode = VOP_MODE_VIP11; break;
+ case VOP_CONFIG_CCIR656: config->mode = VOP_MODE_CCIR656; break;
+ case VOP_CONFIG_VIP2_0:
+
+ if (vop_config & VOP_CONFIG_ENABLE_601)
+ config->mode = VOP_MODE_601;
+ else if (vop_config & VOP_CONFIG_VIP2_16BIT)
+ config->mode = VOP_MODE_VIP20_16BIT;
+ else
+ config->mode = VOP_MODE_VIP20_8BIT;
+ break;
+ }
+
+ /* READ 601 SETTINGS */
+
+ config->vop601.flags = vop_config & (VOP_CONFIG_INVERT_DISPE |
+ VOP_CONFIG_INVERT_HSYNC | VOP_CONFIG_INVERT_VSYNC);
+
+ config->vop601.vsync_shift = vop_config & VOP_CONFIG_VSYNC_MASK;
+ config->vop601.vsync_shift_count = READ_REG32 (DC3_VID_DS_DELTA) & DC3_601_VSYNC_SHIFT_MASK;
+
+ if ((alpha & DF_CSC_GRAPHICS_RGB_TO_YUV) ||
+ (alpha & DF_CSC_VOP_RGB_TO_YUV))
+ {
+ /* YUV OUTPUT */
+
+ if (vop_config & VOP_CONFIG_DISABLE_DECIMATE)
+ config->vop601.output_mode = VOP_601_YUV_4_4_4;
+ else if (vop_config & VOP_CONFIG_VIP2_16BIT)
+ config->vop601.output_mode = VOP_601_YUV_16BIT;
+ else
+ config->vop601.output_mode = VOP_601_YUV_8BIT;
+ }
+ else
+ {
+ config->vop601.output_mode = VOP_601_RGB_8_8_8;
+ }
+
+ config->flags = 0;
+
+ /* READ THE UNIVERSAL VOP OPTIONS */
+
+ if (vop_config & VOP_CONFIG_SWAPUV) config->flags |= VOP_FLAG_SWAP_UV;
+ if (vop_config & VOP_CONFIG_SWAPVBI) config->flags |= VOP_FLAG_SWAP_VBI;
+ if (vop_config & VOP_CONFIG_VBI) config->flags |= VOP_FLAG_VBI;
+ if (vop_config & VOP_CONFIG_TASK) config->flags |= VOP_FLAG_TASK;
+ if (vop_config & VOP_CONFIG_SC_COMPATIBLE) config->flags |= VOP_FLAG_SINGLECHIPCOMPAT;
+ if (vop_config & VOP_CONFIG_EXTENDED_SAV) config->flags |= VOP_FLAG_EXTENDEDSAV;
+
+ config->conversion_mode = vop_config & VOP_CONFIG_422_MASK;
+
+ config->vsync_out = READ_VIP32 (VIP_CONTROL2) & VIP_CONTROL2_SYNC2PIN_MASK;
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vop_get_vbi_window
+ *
+ * This routine reads the current VBI configuration for VOP output.
+ *---------------------------------------------------------------------------*/
+
+int vop_get_vbi_configuration (VOPVBIWINDOWBUFFER *buffer)
+{
+ unsigned long temp;
+ unsigned long hstart, hstop;
+ unsigned long htotal, hsyncstart;
+
+ if (!buffer)
+ return CIM_STATUS_INVALIDPARAMS;
+
+ htotal = ((READ_REG32 (DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
+ hsyncstart = (READ_REG32 (DC3_H_SYNC_TIMING) & 0xFFF) + 1;
+
+ /* DECODE HORIZONTAL POSITION */
+ /* This is done according to the requested horizontal origin */
+
+ temp = READ_REG32 (DC3_VBI_HOR);
+ hstart = (temp & DC3_VBI_HOR_START_MASK) + 1;
+ hstop = ((temp & DC3_VBI_HOR_END_MASK) >> DC3_VBI_HOR_END_SHIFT) + 1;
+ if (buffer->horz_from_hsync)
+ {
+ buffer->horz_start = hstart + htotal - hsyncstart;
+ if (buffer->horz_start >= (long)htotal)
+ buffer->horz_start -= htotal;
+ }
+ else
+ {
+ if (hstart > hsyncstart)
+ buffer->horz_start = (long)hstart - (long)htotal;
+ else
+ buffer->horz_start = hstart;
+ }
+
+ if (hstop > hstart)
+ buffer->vbi_width = hstop - hstart;
+ else
+ buffer->vbi_width = (htotal - hstart) + hstop;
+
+ /* READ LINE MASKS */
+
+ temp = READ_REG32 (DC3_VBI_LN_ODD);
+ buffer->odd_line_offset = (temp & DC3_VBI_ODD_LINE_MASK) >> DC3_VBI_ODD_LINE_SHIFT;
+ buffer->odd_line_capture_mask = (temp & DC3_VBI_ODD_ENABLE_MASK);
+
+ temp = READ_REG32 (DC3_VBI_LN_EVEN);
+ buffer->even_line_offset = (temp & DC3_VBI_EVEN_LINE_MASK) >> DC3_VBI_EVEN_LINE_SHIFT;
+ buffer->even_line_capture_mask = (temp & DC3_VBI_EVEN_ENABLE_MASK);
+
+ /* READ VBI UPSCALE SETTINGS */
+
+ buffer->enable_upscale = 0;
+ temp = READ_REG32 (DC3_VBI_EVEN_CTL);
+ if (temp & DC3_VBI_EVEN_CTL_UPSCALE)
+ buffer->enable_upscale = 1;
+
+ /* READ SOURCE OFFSETS */
+
+ buffer->even_address_offset = temp & DC3_VBI_EVEN_CTL_OFFSET_MASK;
+ buffer->odd_address_offset = READ_REG32 (DC3_VBI_ODD_CTL) & DC3_VBI_ODD_CTL_OFFSET_MASK;
+
+ /* PITCH AND SIZE */
+
+ temp = READ_REG32 (DC3_VBI_PITCH);
+ buffer->data_size = (temp >> 16) << 3;
+ buffer->data_pitch = (temp & 0xFFFF);
+
+ return CIM_STATUS_OK;
+}
+
+/*---------------------------------------------------------------------------
+ * vop_get_vbi_enable
+ *
+ * This routine reads the current enable status of VBI output.
+ *---------------------------------------------------------------------------*/
+
+int vop_get_vbi_enable (void)
+{
+ if (READ_REG32 (DC3_VBI_EVEN_CTL) & DC3_VBI_ENABLE)
+ return 1;
+
+ return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * vop_get_crc
+ *
+ * This routine returns a CRC of the current VOP data
+ ---------------------------------------------------------------------------*/
+
+unsigned long vop_get_crc(void)
+{
+ unsigned long crc;
+ unsigned long config = READ_VOP32(VOP_CONFIGURATION);
+ unsigned long timeout = 1000;
+
+ if (!(READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_TGEN))
+ return 0xFFFFFFFF;
+
+ /* RESET CRC */
+
+ WRITE_VOP32 (VOP_CONFIGURATION, config & ~VOP_CONFIG_ENABLE_SIGNATURE);
+
+ /* WAIT FOR THE RESET TO BE LATCHED */
+
+ while ((READ_VOP32 (VOP_SIGNATURE) != 0x00000001) && timeout)
+ timeout--;
+
+ WRITE_VOP32 (VOP_CONFIGURATION, config | VOP_CONFIG_ENABLE_SIGNATURE);
+
+ /* WAIT UNTIL NOT ACTIVE, THEN ACTIVE, NOT ACTIVE, THEN ACTIVE */
+
+ while (!(READ_VOP32 (VOP_CONFIGURATION) & VOP_CONFIG_SIGVAL))
+ ;
+
+ crc = READ_VOP32 (VOP_SIGNATURE);
+
+ return crc;
+}
+
+/*---------------------------------------------------------------------------
+ * vop_read_vbi_crc
+ *
+ * This routine returns a CRC of the current VBI data
+ ---------------------------------------------------------------------------*/
+
+unsigned long vop_read_vbi_crc(void)
+{
+ unsigned long gcfg, unlock, vbi_even;
+ unsigned long crc;
+
+ if (!(READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_TGEN) ||
+ !(READ_REG32 (DC3_VBI_EVEN_CTL) & DC3_VBI_ENABLE))
+ {
+ return 0xFFFFFFFF;
+ }
+
+ unlock = READ_REG32 (DC3_UNLOCK);
+ gcfg = READ_REG32 (DC3_GENERAL_CFG);
+ vbi_even = READ_REG32 (DC3_VBI_EVEN_CTL);
+
+ gcfg |= DC3_GCFG_SGRE | DC3_GCFG_CRC_MODE;
+ gcfg &= ~(DC3_GCFG_SGFR | DC3_GCFG_SIG_SEL);
+ vbi_even |= DC3_VBI_EVEN_ENABLE_CRC;
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_VBI_EVEN_CTL, vbi_even);
+ WRITE_REG32 (DC3_GENERAL_CFG, gcfg & ~DC3_GCFG_SIGE);
+ WRITE_REG32 (DC3_GENERAL_CFG, gcfg | DC3_GCFG_SIGE);
+
+ /* WAIT FOR THE CRC TO BE COMPLETED */
+
+ while (!(READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_SIGC))
+ ;
+
+ /* READ THE COMPLETED CRC */
+
+ crc = READ_REG32 (DC3_PAL_DATA);
+
+ /* RESTORE THE PALETTE SETTINGS */
+
+ gcfg &= ~DC3_GCFG_SGRE;
+ WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+ WRITE_REG32 (DC3_UNLOCK, unlock);
+
+ return crc;
+}
+
+#endif
diff -urN xf86-video-nsc-2.8.1-orig/src/cim/cimarron.c xf86-video-nsc-2.8.1/src/cim/cimarron.c
--- xf86-video-nsc-2.8.1-orig/src/cim/cimarron.c 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim/cimarron.c 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,222 @@
+ /*
+ *
+ * Copyright (C) 2005 Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *
+ *
+ *
+ *
+ *
+ * Base include file for the Cimarron library. This file should be modified
+ * and included in any Cimarron-based project.
+ *
+ *
+ */
+
+/*----------------------------------------------------------------------*/
+/* MODULE SETTINGS */
+/* The following #defines affect which modules are included in the */
+/* project. */
+/*----------------------------------------------------------------------*/
+
+#define CIMARRON_INCLUDE_GP 1
+#define CIMARRON_INCLUDE_VG 1
+#define CIMARRON_INCLUDE_VIP 1
+#define CIMARRON_INCLUDE_VOP 1
+#define CIMARRON_INCLUDE_VIDEO 1
+#define CIMARRON_INCLUDE_INIT 1
+
+#define CIMARRON_INCLUDE_VG_READ_ROUTINES 1
+#define CIMARRON_INCLUDE_DF_READ_ROUTINES 1
+#define CIMARRON_INCLUDE_VIP_READ_ROUTINES 1
+#define CIMARRON_INCLUDE_VOP_READ_ROUTINES 1
+
+/*----------------------------------------------------------------------*/
+/* HARDWARE ACCESS SETTINGS */
+/* The following #defines affect how the Cimarron macros access the */
+/* hardware. The hardware access macros are broken up into groups. */
+/* Each group includes an enabling #define as well as several #define */
+/* options that modify the macro configuration that is included. */
+/* If the enabling define is deleted or all options are set to 0, the */
+/* corresponding macros must be implemented by the user. The */
+/* combinations are explained as follows: */
+/* must be manually defined by the user. This allows a user to use the */
+/* cim_defs.h file for only those macros that suit the needs of his/her */
+/* project. For example, a user may need custom implementations of the */
+/* I/O and MSR macros, but may still want to use the default macros to */
+/* read and write hardware registers. The combinations are explained as */
+/* follows: */
+/* */
+/* Register Group: */
+/* Disabling define: */
+/* CIMARRON_EXCLUDE_REGISTER_ACCESS_MACROS */
+/* Define this setting to exclude the register access macros. */
+/* This setting is the inverse of the other group settings in */
+/* that these macros are included by default. This allows the */
+/* cim_defs.h file to be included outside of cimarron.c for */
+/* basic operations. */
+/* */
+/* Memory Group: */
+/* Enabling define: */
+/* CIMARRON_INCLUDE_STRING_MACROS */
+/* Options: */
+/* CIMARRON_OPTIMIZE_ASSEMBLY */
+/* Set to 1 to allow the use of inline assembly when writing */
+/* large chunks of data to memory. Essentially, this allows */
+/* a rep movsd in place of a slower C for-loop. */
+/* CIMARRON_OPTIMIZE_FORLOOP */
+/* Define for C only data writes. */
+/* */
+/* MSR Group: */
+/* Enabling define: */
+/* CIMARRON_INCLUDE_MSR_MACROS */
+/* Options: */
+/* CIMARRON_MSR_DIRECT_ASM */
+/* Set to 1 to allow the use of the rdmsr and wrmsr opcodes in */
+/* inline assembly. */
+/* CIMARRON_MSR_VSA_IO */
+/* Set to 1 to access MSRs using a VSAII virtual register. */
+/* CIMARRON_MSR_KERNEL_ROUTINE */
+/* Set to 1 to access MSRs using a wrapper routine in the */
+/* Linux kernel. */
+/* */
+/* IO Group: */
+/* Enabling define: */
+/* CIMARRON_INCLUDE_IO_MACROS */
+/* Options: */
+/* CIMARRON_IO_DIRECT_ACCESS */
+/* Set to 1 to perform IO accesses using inline assembly. */
+/* CIMARRON_IO_ABSTRACTED_ASM */
+/* Set to 1 to perform IO using abstracted IO in Linux. */
+/* */
+/* Custom Group: */
+/* Disabling define: */
+/* CIMARRON_EXCLUDE_CUSTOM_MACROS */
+/* By default, the custom macros (the macros used by */
+/* gp_custom_convert_blt) are mapped to the normal command */
+/* string macros. Setting this to 1 allows the user to */
+/* create a custom implementation. */
+/*----------------------------------------------------------------------*/
+
+/* UNCOMMENT THE FOLLOWING LINE TO EXCLUDE BASIC REGISTER ACCESS MACROS */
+
+/* #define CIMARRON_EXCLUDE_REGISTER_ACCESS_MACROS */
+
+#define CIMARRON_INCLUDE_STRING_MACROS
+#define CIMARRON_OPTIMIZE_ASSEMBLY 1
+#define CIMARRON_OPTIMIZE_FORLOOP 0
+#define CIMARRON_OPTIMIZE_ABSTRACTED_ASM 0
+
+#define CIMARRON_INCLUDE_MSR_MACROS
+#define CIMARRON_MSR_DIRECT_ASM 0
+#define CIMARRON_MSR_VSA_IO 1
+#define CIMARRON_MSR_ABSTRACTED_ASM 0
+#define CIMARRON_MSR_KERNEL_ROUTINE 0
+
+#define CIMARRON_INCLUDE_IO_MACROS
+#define CIMARRON_IO_DIRECT_ACCESS 1
+#define CIMARRON_IO_ABSTRACTED_ASM 0
+
+/* UNCOMMENT THE FOLLOWING LINE TO IMPLEMENT CUSTOM MACROS FOR GP_CUSTOM_CONVERT_BLT */
+
+/* #define CIMARRON_EXCLUDE_CUSTOM_MACROS */
+
+/*----------------------------------------------------------------------*/
+/* MODULE VARIABLES */
+/* The following #defines affect how global variables in each Cimarron */
+/* module are defined. These variables can be made static (to prevent */
+/* naming conflicts) or they can be defined without the static keyword */
+/* (to allow extern references). */
+/*----------------------------------------------------------------------*/
+
+#if 1
+#define CIMARRON_STATIC static
+#else
+#define CIMARRON_STATIC
+#endif
+
+/*----------------------------------------------------------------------*/
+/* CIMARRON GLOBAL VARIABLES */
+/* These globals are used by the hardware access macros. They must be */
+/* initialized by the application to point to the memory-mapped */
+/* registers of their respective blocks. */
+/*----------------------------------------------------------------------*/
+
+unsigned char *cim_gp_ptr = (unsigned char *)0;
+unsigned char *cim_fb_ptr = (unsigned char *)0;
+unsigned char *cim_cmd_base_ptr = (unsigned char *)0;
+unsigned char *cim_cmd_ptr = (unsigned char *)0;
+unsigned char *cim_vid_ptr = (unsigned char *)0;
+unsigned char *cim_vip_ptr = (unsigned char *)0;
+unsigned char *cim_vg_ptr = (unsigned char *)0;
+
+/*----------------------------------------------------------------------*/
+/* INCLUDE RELEVANT CIMARRON HEADERS */
+/*----------------------------------------------------------------------*/
+
+/* HARDWARE REGISTER DEFINITIONS */
+
+#include "cim_regs.h"
+
+/* ROUTINE DEFINITIONS */
+/* All routines have a prototype, even those that are not included */
+/* via #ifdefs. This prevents the user from having to include the */
+/* correct #defines anywhere he/she wants to call a Cimarron routine. */
+
+#include "cim_rtns.h"
+
+/* HARDWARE ACCESS MACROS */
+
+#include "cim_defs.h"
+
+/*----------------------------------------------------------------------*/
+/* CIMARRON MODULES */
+/* Modules and sub-modules are included based on user settings. Note */
+/* that excluding one or more modules may result in functionality */
+/* holes. */
+/*----------------------------------------------------------------------*/
+
+/* GRAPHICS PROCESSOR */
+
+#if CIMARRON_INCLUDE_GP
+#include "cim_gp.c"
+#endif
+
+/* VIDEO GENERATOR */
+
+#if CIMARRON_INCLUDE_VG
+#include "cim_modes.c"
+#include "cim_vg.c"
+#endif
+
+/* DISPLAY FILTER */
+
+#if CIMARRON_INCLUDE_VIDEO
+#include "cim_filter.c"
+#include "cim_df.c"
+#endif
+
+/* INITIALIZATION AND DETECTION */
+
+#if CIMARRON_INCLUDE_INIT
+#include "cim_init.c"
+#endif
+
+/* VIP SUPPORT */
+
+#if CIMARRON_INCLUDE_VIP
+#include "cim_vip.c"
+#endif
+
+/* VOP SUPPORT */
+
+#if CIMARRON_INCLUDE_VOP
+#include "cim_vop.c"
+#endif
+
+/* MSR ACCESS */
+/* This module is used to access machine-specific registers. */
+/* It cannot be excluded from a project. */
+
+#include "cim_msr.c"
+
diff -urN xf86-video-nsc-2.8.1-orig/src/cim_dev.h xf86-video-nsc-2.8.1/src/cim_dev.h
--- xf86-video-nsc-2.8.1-orig/src/cim_dev.h 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cim_dev.h 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2003-2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice 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.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+/*
+ * */
+/*
+ * */
+
+#ifndef CIMDEV_H_
+#define CIMDEV_H_
+
+#define CIM_RESERVE_MEM 0x01
+#define CIM_FREE_MEM 0x02
+#define CIMDEV_MINOR_DEV 156
+
+/* Block flags */
+#define CIM_F_FREE 0x01 /* This block is marked as free */
+#define CIM_F_CMDBUF 0x02 /* GP command buffer flag */
+#define CIM_F_PRIVATE 0x04 /* This block is reserved only for its owner */
+#define CIM_F_PUBLIC 0x08 /* This block can be used by the world */
+
+typedef struct {
+
+ /* These fields get populated by the client */
+
+ char owner[10];
+ char name[15];
+ int flags;
+ int size;
+
+ /* These fields are populated by the device */
+
+ unsigned long offset;
+} cim_mem_req_t;
+
+typedef struct {
+ char owner[10];
+ unsigned long offset;
+} cim_mem_free_t;
+
+#endif
diff -urN xf86-video-nsc-2.8.1-orig/src/cimarron.c xf86-video-nsc-2.8.1/src/cimarron.c
--- xf86-video-nsc-2.8.1-orig/src/cimarron.c 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/cimarron.c 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2005 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice 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.
+ *
+ * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ * */
+/*
+ * */
+/*
+ * Base include file for the Cimarron library. This file should be modified
+ * and included in any Cimarron-based project.
+ * */
+
+/*----------------------------------------------------------------------*/
+/* MODULE SETTINGS */
+/* The following #defines affect which modules are included in the */
+/* project. */
+/*----------------------------------------------------------------------*/
+
+#define CIMARRON_INCLUDE_GP 1
+#define CIMARRON_INCLUDE_VG 1
+#define CIMARRON_INCLUDE_VIP 1
+#define CIMARRON_INCLUDE_VOP 1
+#define CIMARRON_INCLUDE_VIDEO 1
+#define CIMARRON_INCLUDE_INIT 1
+
+#define CIMARRON_INCLUDE_VG_READ_ROUTINES 1
+#define CIMARRON_INCLUDE_DF_READ_ROUTINES 1
+#define CIMARRON_INCLUDE_VIP_READ_ROUTINES 1
+#define CIMARRON_INCLUDE_VOP_READ_ROUTINES 1
+
+/*----------------------------------------------------------------------*/
+/* HARDWARE ACCESS SETTINGS */
+/* The following #defines affect how the Cimarron macros access the */
+/* hardware. The hardware access macros are broken up into groups. */
+/* Each group includes an enabling #define as well as several #define */
+/* options that modify the macro configuration that is included. */
+/* If the enabling define is deleted or all options are set to 0, the */
+/* corresponding macros must be implemented by the user. The */
+/* combinations are explained as follows: */
+/* must be manually defined by the user. This allows a user to use the */
+/* cim_defs.h file for only those macros that suit the needs of his/her */
+/* project. For example, a user may need custom implementations of the */
+/* I/O and MSR macros, but may still want to use the default macros to */
+/* read and write hardware registers. The combinations are explained as */
+/* follows: */
+/* */
+/* Register Group: */
+/* Disabling define: */
+/* CIMARRON_EXCLUDE_REGISTER_ACCESS_MACROS */
+/* Define this setting to exclude the register access macros. */
+/* This setting is the inverse of the other group settings in */
+/* that these macros are included by default. This allows the */
+/* cim_defs.h file to be included outside of cimarron.c for */
+/* basic operations. */
+/* */
+/* Memory Group: */
+/* Enabling define: */
+/* CIMARRON_INCLUDE_STRING_MACROS */
+/* Options: */
+/* CIMARRON_OPTIMIZE_ASSEMBLY */
+/* Set to 1 to allow the use of inline assembly when writing */
+/* large chunks of data to memory. Essentially, this allows */
+/* a rep movsd in place of a slower C for-loop. */
+/* CIMARRON_OPTIMIZE_FORLOOP */
+/* Define for C only data writes. */
+/* */
+/* MSR Group: */
+/* Enabling define: */
+/* CIMARRON_INCLUDE_MSR_MACROS */
+/* Options: */
+/* CIMARRON_MSR_DIRECT_ASM */
+/* Set to 1 to allow the use of the rdmsr and wrmsr opcodes in */
+/* inline assembly. */
+/* CIMARRON_MSR_VSA_IO */
+/* Set to 1 to access MSRs using a VSAII virtual register. */
+/* CIMARRON_MSR_KERNEL_ROUTINE */
+/* Set to 1 to access MSRs using a wrapper routine in the */
+/* Linux kernel. */
+/* */
+/* IO Group: */
+/* Enabling define: */
+/* CIMARRON_INCLUDE_IO_MACROS */
+/* Options: */
+/* CIMARRON_IO_DIRECT_ACCESS */
+/* Set to 1 to perform IO accesses using inline assembly. */
+/* CIMARRON_IO_ABSTRACTED_ASM */
+/* Set to 1 to perform IO using abstracted IO in Linux. */
+/* */
+/* Custom Group: */
+/* Disabling define: */
+/* CIMARRON_EXCLUDE_CUSTOM_MACROS */
+/* By default, the custom macros (the macros used by */
+/* gp_custom_convert_blt) are mapped to the normal command */
+/* string macros. Setting this to 1 allows the user to */
+/* create a custom implementation. */
+/*----------------------------------------------------------------------*/
+
+/* UNCOMMENT THE FOLLOWING LINE TO EXCLUDE BASIC REGISTER ACCESS MACROS */
+
+/* #define CIMARRON_EXCLUDE_REGISTER_ACCESS_MACROS */
+
+#define CIMARRON_INCLUDE_STRING_MACROS
+#define CIMARRON_OPTIMIZE_ASSEMBLY 0
+#define CIMARRON_OPTIMIZE_FORLOOP 0
+#define CIMARRON_OPTIMIZE_ABSTRACTED_ASM 1
+
+#define CIMARRON_INCLUDE_MSR_MACROS
+#define CIMARRON_MSR_DIRECT_ASM 0
+#define CIMARRON_MSR_VSA_IO 0
+#define CIMARRON_MSR_ABSTRACTED_ASM 1
+#define CIMARRON_MSR_KERNEL_ROUTINE 0
+
+#define CIMARRON_INCLUDE_IO_MACROS
+#define CIMARRON_IO_DIRECT_ACCESS 0
+#define CIMARRON_IO_ABSTRACTED_ASM 1
+
+/* UNCOMMENT THE FOLLOWING LINE TO IMPLEMENT CUSTOM MACROS FOR GP_CUSTOM_CONVERT_BLT */
+
+/* #define CIMARRON_EXCLUDE_CUSTOM_MACROS */
+
+/*----------------------------------------------------------------------*/
+/* MODULE VARIABLES */
+/* The following #defines affect how global variables in each Cimarron */
+/* module are defined. These variables can be made static (to prevent */
+/* naming conflicts) or they can be defined without the static keyword */
+/* (to allow extern references). */
+/*----------------------------------------------------------------------*/
+
+#if 1
+#define CIMARRON_STATIC static
+#else
+#define CIMARRON_STATIC
+#endif
+
+/*----------------------------------------------------------------------*/
+/* CIMARRON GLOBAL VARIABLES */
+/* These globals are used by the hardware access macros. They must be */
+/* initialized by the application to point to the memory-mapped */
+/* registers of their respective blocks. */
+/*----------------------------------------------------------------------*/
+
+unsigned char *cim_gp_ptr = (unsigned char *)0;
+unsigned char *cim_fb_ptr = (unsigned char *)0;
+unsigned char *cim_cmd_base_ptr = (unsigned char *)0;
+unsigned char *cim_cmd_ptr = (unsigned char *)0;
+unsigned char *cim_vid_ptr = (unsigned char *)0;
+unsigned char *cim_vip_ptr = (unsigned char *)0;
+unsigned char *cim_vg_ptr = (unsigned char *)0;
+
+/*----------------------------------------------------------------------*/
+/* INCLUDE RELEVANT CIMARRON HEADERS */
+/*----------------------------------------------------------------------*/
+
+/* HARDWARE REGISTER DEFINITIONS */
+
+#include "cim_regs.h"
+
+/* ROUTINE DEFINITIONS */
+/* All routines have a prototype, even those that are not included */
+/* via #ifdefs. This prevents the user from having to include the */
+/* correct #defines anywhere he/she wants to call a Cimarron routine. */
+
+#include "cim_rtns.h"
+
+/* HARDWARE ACCESS MACROS */
+
+#include "cim_defs.h"
+
+/*----------------------------------------------------------------------*/
+/* CIMARRON MODULES */
+/* Modules and sub-modules are included based on user settings. Note */
+/* that excluding one or more modules may result in functionality */
+/* holes. */
+/*----------------------------------------------------------------------*/
+
+/* GRAPHICS PROCESSOR */
+
+#if CIMARRON_INCLUDE_GP
+#include "cim_gp.c"
+#endif
+
+/* VIDEO GENERATOR */
+
+#if CIMARRON_INCLUDE_VG
+#include "cim_modes.c"
+#include "cim_vg.c"
+#endif
+
+/* DISPLAY FILTER */
+
+#if CIMARRON_INCLUDE_VIDEO
+#include "cim_filter.c"
+#include "cim_df.c"
+#endif
+
+/* INITIALIZATION AND DETECTION */
+
+#if CIMARRON_INCLUDE_INIT
+#include "cim_init.c"
+#endif
+
+/* VIP SUPPORT */
+
+#if CIMARRON_INCLUDE_VIP
+#include "cim_vip.c"
+#endif
+
+/* VOP SUPPORT */
+
+#if CIMARRON_INCLUDE_VOP
+#include "cim_vop.c"
+#endif
+
+/* MSR ACCESS */
+/* This module is used to access machine-specific registers. */
+/* It cannot be excluded from a project. */
+
+#include "cim_msr.c"
+
diff -urN xf86-video-nsc-2.8.1-orig/src/gfx/disp_gu3.c xf86-video-nsc-2.8.1/src/gfx/disp_gu3.c
--- xf86-video-nsc-2.8.1-orig/src/gfx/disp_gu3.c 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/gfx/disp_gu3.c 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,2422 @@
+ /*
+ *
+ *
+ * Copyright (C) Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *
+ *
+ *
+ *
+ *
+ * This file contains routines for the second generation display controller.
+ *
+ *
+ */
+
+void gu3_enable_compression(void); /* private routine definition */
+void gu3_disable_compression(void); /* private routine definition */
+int gfx_set_display_control(int sync_polarities); /* private routine definition */
+void gfx_reset_video (void);
+int gu3_set_specified_mode(DISPLAYMODE *pMode, int bpp);
+
+ /*-----------------------------------------------------------------------------
+ * WARNING!!!! INACCURATE DELAY MECHANISM
+ *
+ * In an effort to keep the code self contained and operating system
+ * independent, the delay loop just performs reads of a display controller
+ * register. This time will vary for faster processors. The delay can always
+ * be longer than intended, only effecting the time of the mode switch
+ * (obviously want it to still be under a second). Problems with the hardware
+ * only arise if the delay is not long enough.
+ *-----------------------------------------------------------------------------
+ */
+
+#define CSTL_READS_PER_MILLISECOND 15000L
+
+#if GFX_DISPLAY_DYNAMIC
+void gu3_delay_milliseconds(unsigned long milliseconds)
+#else
+void gfx_delay_milliseconds(unsigned long milliseconds)
+#endif
+{
+ /* ASSUME 300 MHZ 20 CLOCKS PER READ */
+
+ unsigned long loop;
+ loop = milliseconds * CSTL_READS_PER_MILLISECOND;
+ while (loop-- > 0)
+ {
+ READ_REG32 (DC3_UNLOCK);
+ }
+}
+
+#if GFX_DISPLAY_DYNAMIC
+void gu3_delay_microseconds(unsigned long microseconds)
+#else
+void gfx_delay_microseconds(unsigned long microseconds)
+#endif
+{
+ /* ASSUME 300 MHz, 2 CLOCKS PER INCREMENT */
+
+
+ unsigned long loop_count = microseconds * 15;
+
+ while (loop_count-- > 0)
+ {
+ READ_REG32 (DC3_UNLOCK);
+ }
+}
+
+/*-----------------------------------------------------------------------------
+ * GFX_SET_DISPLAY_BPP
+ *
+ * This routine programs the bpp in the display controller.
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_set_display_bpp(unsigned short bpp)
+#else
+int gfx_set_display_bpp(unsigned short bpp)
+#endif
+{
+ unsigned long dcfg, lock;
+
+ dcfg = READ_REG32 (DC3_DISPLAY_CFG) & ~(DC3_DCFG_DISP_MODE_MASK | DC3_DCFG_16BPP_MODE_MASK);
+ lock = READ_REG32 (DC3_UNLOCK);
+
+ switch (bpp)
+ {
+ case 12: dcfg |= (DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_12BPP); break;
+ case 15: dcfg |= (DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_15BPP); break;
+ case 16: dcfg |= (DC3_DCFG_DISP_MODE_16BPP | DC3_DCFG_16BPP); break;
+ case 32: dcfg |= (DC3_DCFG_DISP_MODE_24BPP); break;
+ case 8: dcfg |= (DC3_DCFG_DISP_MODE_8BPP); break;
+ default: return GFX_STATUS_BAD_PARAMETER;
+ }
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_DISPLAY_CFG, dcfg);
+ WRITE_REG32 (DC3_UNLOCK, lock);
+
+ /* SET BPP IN GRAPHICS PIPELINE */
+
+ gfx_set_bpp (bpp);
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------------------
+ * gu3_set_specified_mode (private routine)
+ * This routine uses the parameters in the specified display mode structure
+ * to program the display controller hardware.
+ *-----------------------------------------------------------------------------
+ */
+int gu3_set_specified_mode(DISPLAYMODE *pMode, int bpp)
+{
+ Q_WORD msr_value;
+ unsigned long unlock, value;
+ unsigned long acfg, gcfg, dcfg;
+ unsigned long size, pitch;
+ unsigned long bpp_mask, temp, dv_size;
+
+ /* CHECK WHETHER TIMING CHANGE IS ALLOWED */
+ /* Flag used for locking also overrides timing change restriction */
+
+ if (gfx_timing_lock && !(pMode->flags & GFX_MODE_LOCK_TIMING))
+ return GFX_STATUS_ERROR;
+
+ /* CLEAR PANNING OFFSETS */
+
+ DeltaX = 0;
+ DeltaY = 0;
+ panelLeft = 0;
+ panelTop = 0;
+
+ /* SET GLOBAL FLAG */
+
+ if (pMode->flags & GFX_MODE_LOCK_TIMING)
+ gfx_timing_lock = 1;
+
+ /* CHECK FOR VALID BPP */
+ /* As this function can be called directly from */
+ /* gfx_set_display_timings, we must correct any */
+ /* invalid bpp settings. */
+
+ switch (bpp)
+ {
+ case 12: bpp_mask = 0x00000900; break;
+ case 15: bpp_mask = 0x00000500; break;
+ case 16: bpp_mask = 0x00000100; break;
+ case 32: bpp_mask = 0x00000200; break;
+ default: bpp_mask = 0x00000000; bpp = 8; break;
+ }
+
+ gbpp = bpp;
+
+ /* DISABLE COMPRESSION */
+
+ gu3_disable_compression();
+
+ /* ALSO DISABLE VIDEO */
+ /* Use private "reset video" routine to do all that is needed. */
+ /* SC1200, for example, also disables the alpha blending regions. */
+
+ gfx_reset_video();
+
+ /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */
+
+ unlock = READ_REG32 (DC3_UNLOCK);
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+ /* READ THE CURRENT REGISTER VALUES */
+
+ gcfg = READ_REG32 (DC3_GENERAL_CFG);
+ dcfg = READ_REG32 (DC3_DISPLAY_CFG);
+
+ /* BLANK THE DISPLAY IN THE DISPLAY FILTER */
+
+ gfx_set_crt_enable (0);
+
+ /* DISABLE THE TIMING GENERATOR */
+
+ dcfg &= ~(unsigned long)DC3_DCFG_TGEN;
+ WRITE_REG32 (DC3_DISPLAY_CFG, dcfg);
+
+ /* DELAY: WAIT FOR PENDING MEMORY REQUESTS */
+ /* This delay is used to make sure that all pending requests to the */
+ /* memory controller have completed before disabling the FIFO load. */
+
+ gfx_delay_milliseconds(1);
+
+ /* DISABLE DISPLAY FIFO LOAD */
+
+ gcfg &= ~(unsigned long)DC3_GCFG_DFLE;
+ WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+
+ /* PRESERVE VIDEO INFORMATION */
+
+ gcfg &= (unsigned long)(DC3_GCFG_YUVM | DC3_GCFG_VDSE);
+ dcfg = 0;
+
+ /* DISABLE VGA */
+ /* VGA *MUST* be turned off before TGEN is enabled. If not, a condition */
+ /* will result where VGA Enable is waiting for a VSync to be latched but */
+ /* a VSync will not be generated until VGA is disabled. */
+
+ WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+
+ /* SET THE DOT CLOCK FREQUENCY */
+ /* Mask off the divide by two bit (bit 31) */
+
+ gfx_set_clock_frequency(pMode->frequency & 0x7FFFFFFF);
+
+ /* DELAY: WAIT FOR THE PLL TO SETTLE */
+ /* This allows the dot clock frequency that was just set to settle. */
+
+ gfx_delay_milliseconds(1);
+
+ /* SET THE GX DISPLAY CONTROLLER PARAMETERS */
+
+ WRITE_REG32 (DC3_FB_ST_OFFSET, 0);
+ WRITE_REG32 (DC3_CB_ST_OFFSET, 0);
+ WRITE_REG32 (DC3_CURS_ST_OFFSET, 0);
+
+ /* SET LINE SIZE AND PITCH */
+ /* 1. Flat Panels must use the mode width and not */
+ /* the timing width to set the pitch. */
+ /* 2. Mode sets will use a pitch that is aligned */
+ /* on a 1K boundary to preserve legacy. The */
+ /* pitch can be overridden by a subsequent call */
+ /* to gfx_set_display_pitch. */
+
+ if (PanelEnable)
+ size = ModeWidth;
+ else
+ size = pMode->hactive;
+
+ if (bpp > 8) size <<= 1;
+ if (bpp > 16) size <<= 1;
+
+ pitch = 1024;
+ dv_size = DC3_DV_LINE_SIZE_1024;
+
+ if (size > 1024)
+ {
+ pitch = 2048;
+ dv_size = DC3_DV_LINE_SIZE_2048;
+ }
+ if (size > 2048)
+ {
+ pitch = 4096;
+ dv_size = DC3_DV_LINE_SIZE_4096;
+ }
+ if (size > 4096)
+ {
+ pitch = 8192;
+ dv_size = DC3_DV_LINE_SIZE_8192;
+ }
+ WRITE_REG32(DC3_GFX_PITCH, pitch >> 3);
+
+ /* WRITE DIRTY/VALID CONTROL WITH LINE LENGTH */
+
+ temp = READ_REG32 (DC3_DV_CTL);
+ WRITE_REG32 (DC3_DV_CTL, (temp & ~DC3_DV_LINE_SIZE_MASK) | dv_size);
+
+ if (PanelEnable)
+ {
+ size = pMode->hactive;
+ if (bpp > 8) size <<= 1;
+ if (bpp > 16) size <<= 1;
+ }
+
+ WRITE_REG32 (DC3_LINE_SIZE, ((size >> 3)));
+
+ /* ALWAYS ENABLE VIDEO AND GRAPHICS DATA */
+ /* These bits are relics from a previous design and */
+ /* should always be enabled. */
+
+ dcfg |= (unsigned long)(DC3_DCFG_VDEN | DC3_DCFG_GDEN);
+
+ /* SET PIXEL FORMAT */
+
+ dcfg |= bpp_mask;
+
+ /* ENABLE TIMING GENERATOR, TIM. REG. UPDATES, PALETTE BYPASS */
+ /* AND VERT. INT. SELECT */
+
+ dcfg |= (unsigned long)(DC3_DCFG_TGEN | DC3_DCFG_TRUP | DC3_DCFG_PALB | DC3_DCFG_VISL);
+
+ /* SET FIFO PRIORITIES AND DISPLAY FIFO LOAD ENABLE */
+
+ gcfg |= 0x0000BA01;
+ dcfg |= 0x000EA000;
+ acfg = 0x001A0000;
+
+ /* SET THE DISPLAY CHARACTERISTICS FOR HIGH BANDWIDTH CASES */
+
+ gfx_msr_read (RC_ID_VG, DC3_VG_SPARE_MSR, &msr_value);
+ msr_value.low &= ~(VG_SPARE_DISABLE_CFIFO_HGO | VG_SPARE_VFIFO_ARB_SELECT |
+ VG_SPARE_LOAD_WM_LPEN_MASK | VG_SPARE_WM_LPEN_OVRD |
+ VG_SPARE_DISABLE_INIT_VID_PRI | VG_SPARE_DISABLE_VFIFO_WM);
+ msr_value.low |= VG_SPARE_DISABLE_CFIFO_HGO | VG_SPARE_VFIFO_ARB_SELECT;
+ gfx_msr_write (RC_ID_VG, DC3_VG_SPARE_MSR, &msr_value);
+ WRITE_REG32 (DC3_ARB_CFG, acfg);
+
+ /* ENABLE FLAT PANEL CENTERING */
+ /* For panel modes having a resolution smaller than the */
+ /* panel resolution, turn on data centering. */
+
+ if (PanelEnable && ModeWidth < PanelWidth)
+ dcfg |= DC3_DCFG_DCEN;
+
+ /* SET THE GRAPHICS SCALE */
+ /* We do not support graphics scaling, but we need to ensure that the */
+ /* scale is set correctly none the less. */
+
+ WRITE_REG32 (DC3_GFX_SCALE, 0x40004000);
+ WRITE_REG32 (DC3_IRQ_CTL, 0);
+
+ /* COMBINE AND SET TIMING VALUES */
+
+ value = (unsigned long) (pMode->hactive - 1) |
+ (((unsigned long) (pMode->htotal - 1)) << 16);
+ WRITE_REG32(DC3_H_ACTIVE_TIMING, value);
+ value = (unsigned long) (pMode->hblankstart - 1) |
+ (((unsigned long) (pMode->hblankend - 1)) << 16);
+ WRITE_REG32(DC3_H_BLANK_TIMING, value);
+ value = (unsigned long) (pMode->hsyncstart - 1) |
+ (((unsigned long) (pMode->hsyncend - 1)) << 16);
+ WRITE_REG32(DC3_H_SYNC_TIMING, value);
+ value = (unsigned long) (pMode->vactive - 1) |
+ (((unsigned long) (pMode->vtotal - 1)) << 16);
+ WRITE_REG32(DC3_V_ACTIVE_TIMING, value);
+ value = (unsigned long) (pMode->vblankstart - 1) |
+ (((unsigned long) (pMode->vblankend - 1)) << 16);
+ WRITE_REG32(DC3_V_BLANK_TIMING, value);
+ value = (unsigned long) (pMode->vsyncstart - 1) |
+ (((unsigned long) (pMode->vsyncend - 1)) << 16);
+ WRITE_REG32(DC3_V_SYNC_TIMING, value);
+
+ WRITE_REG32 (DC3_DISPLAY_CFG, dcfg);
+ WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+
+ /* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */
+
+ gfx_set_display_control (((pMode->flags & GFX_MODE_NEG_HSYNC) ? 1 : 0) |
+ ((pMode->flags & GFX_MODE_NEG_VSYNC) ? 2 : 0));
+
+ /* RESTORE VALUE OF DC3_UNLOCK */
+
+ WRITE_REG32(DC3_UNLOCK, unlock);
+
+ /* RESET THE PITCH VALUES IN THE GP */
+
+ gfx_reset_pitch ((unsigned short)pitch);
+
+ gfx_set_bpp ((unsigned short)bpp);
+
+ return GFX_STATUS_OK;
+}
+
+ /*----------------------------------------------------------------------------
+ * GFX_IS_DISPLAY_MODE_SUPPORTED
+ *
+ * This routine sets the specified display mode.
+ *
+ * Returns 1 if successful, 0 if mode could not be set.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_is_display_mode_supported(int xres, int yres, int bpp, int hz)
+#else
+int gfx_is_display_mode_supported(int xres, int yres, int bpp, int hz)
+#endif
+{
+ unsigned int mode;
+ unsigned long hz_flag = 0, bpp_flag = 0;
+
+ /* SET FLAGS TO MATCH REFRESH RATE */
+
+ if (hz == 56) hz_flag = GFX_MODE_56HZ;
+ if (hz == 60) hz_flag = GFX_MODE_60HZ;
+ if (hz == 70) hz_flag = GFX_MODE_70HZ;
+ if (hz == 72) hz_flag = GFX_MODE_72HZ;
+ if (hz == 75) hz_flag = GFX_MODE_75HZ;
+ if (hz == 85) hz_flag = GFX_MODE_85HZ;
+ if (hz == 90) hz_flag = GFX_MODE_90HZ;
+ if (hz == 100) hz_flag = GFX_MODE_100HZ;
+
+ /* SET BPP FLAGS TO LIMIT MODE SELECTION */
+
+ switch (bpp)
+ {
+ case 8: bpp_flag = GFX_MODE_8BPP; break;
+ case 12: bpp_flag = GFX_MODE_12BPP; break;
+ case 15: bpp_flag = GFX_MODE_15BPP; break;
+ case 16: bpp_flag = GFX_MODE_16BPP; break;
+ case 32: bpp_flag = GFX_MODE_24BPP; break;
+ default: return (-1);
+ }
+
+ /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
+
+ for (mode = 0; mode < NUM_RC_DISPLAY_MODES; mode++)
+ {
+ if ((DisplayParams[mode].hactive == (unsigned short)xres) &&
+ (DisplayParams[mode].vactive == (unsigned short)yres) &&
+ (DisplayParams[mode].flags & hz_flag) &&
+ (DisplayParams[mode].flags & bpp_flag))
+ {
+
+ /* CASTLE DOES NOT SUPPORT EMULATED VGA MODES */
+
+ if ((DisplayParams[mode].flags & GFX_MODE_PIXEL_DOUBLE) ||
+ (DisplayParams[mode].flags & GFX_MODE_LINE_DOUBLE))
+ continue;
+
+ /* SET THE DISPLAY CONTROLLER FOR THE SELECTED MODE */
+
+ return(mode);
+ }
+ }
+ return(-1);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_set_display_mode
+ *
+ * This routine sets the specified display mode.
+ *
+ * Returns 1 if successful, 0 if mode could not be set.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_set_display_mode(int xres, int yres, int bpp, int hz)
+#else
+int gfx_set_display_mode(int xres, int yres, int bpp, int hz)
+#endif
+{
+ int mode;
+
+ /* DISABLE FLAT PANEL */
+ /* Flat Panel settings are enabled by the function gfx_set_fixed_timings */
+ /* and disabled by gfx_set_display_mode. */
+
+ PanelEnable = 0;
+
+ mode = gfx_is_display_mode_supported(xres, yres, bpp, hz);
+ if(mode >= 0)
+ {
+ if (gu3_set_specified_mode(&DisplayParams[mode], bpp) == GFX_STATUS_OK)
+ return(1);
+ }
+ return(0);
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_SET_DISPLAY_TIMINGS
+ *
+ * This routine sets the display controller mode using the specified timing
+ * values (as opposed to using the tables internal to Durango).
+ *
+ * Returns GFX_STATUS_OK ON SUCCESS, GFX_STATUS_ERROR otherwise.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_set_display_timings(unsigned short bpp, unsigned short flags,
+ unsigned short hactive, unsigned short hblankstart,
+ unsigned short hsyncstart, unsigned short hsyncend,
+ unsigned short hblankend, unsigned short htotal,
+ unsigned short vactive, unsigned short vblankstart,
+ unsigned short vsyncstart, unsigned short vsyncend,
+ unsigned short vblankend, unsigned short vtotal,
+ unsigned long frequency)
+#else
+int gfx_set_display_timings(unsigned short bpp, unsigned short flags,
+ unsigned short hactive, unsigned short hblankstart,
+ unsigned short hsyncstart, unsigned short hsyncend,
+ unsigned short hblankend, unsigned short htotal,
+ unsigned short vactive, unsigned short vblankstart,
+ unsigned short vsyncstart, unsigned short vsyncend,
+ unsigned short vblankend, unsigned short vtotal,
+ unsigned long frequency)
+#endif
+{
+ /* SET MODE STRUCTURE WITH SPECIFIED VALUES */
+
+ gfx_display_mode.flags = 0;
+ if (flags & 1) gfx_display_mode.flags |= GFX_MODE_NEG_HSYNC;
+ if (flags & 2) gfx_display_mode.flags |= GFX_MODE_NEG_VSYNC;
+ if (flags & 0x1000) gfx_display_mode.flags |= GFX_MODE_LOCK_TIMING;
+ gfx_display_mode.hactive = hactive;
+ gfx_display_mode.hblankstart = hblankstart;
+ gfx_display_mode.hsyncstart = hsyncstart;
+ gfx_display_mode.hsyncend = hsyncend;
+ gfx_display_mode.hblankend = hblankend;
+ gfx_display_mode.htotal = htotal;
+ gfx_display_mode.vactive = vactive;
+ gfx_display_mode.vblankstart = vblankstart;
+ gfx_display_mode.vsyncstart = vsyncstart;
+ gfx_display_mode.vsyncend = vsyncend;
+ gfx_display_mode.vblankend = vblankend;
+ gfx_display_mode.vtotal = vtotal;
+ gfx_display_mode.frequency = frequency;
+
+ /* CALL ROUTINE TO SET MODE */
+
+ return (gu3_set_specified_mode(&gfx_display_mode, bpp));
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_SET_VTOTAL
+ *
+ * This routine sets the display controller vertical total to
+ * "vtotal". As a side effect it also sets vertical blank end.
+ * It should be used when only this value needs to be changed,
+ * due to speed considerations.
+ *
+ * Note: it is the caller's responsibility to make sure that
+ * a legal vtotal is used, i.e. that "vtotal" is greater than or
+ * equal to vsync end.
+ *
+ * Always returns 0.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_set_vtotal(unsigned short vtotal)
+#else
+int gfx_set_vtotal(unsigned short vtotal)
+#endif
+{
+ unsigned long unlock, dcfg, vactive, vblank;
+
+ /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */
+
+ unlock = READ_REG32(DC3_UNLOCK);
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+ /* READ THE CURRENT RC VALUES */
+
+ dcfg = READ_REG32 (DC3_DISPLAY_CFG);
+ vactive = READ_REG32 (DC3_V_ACTIVE_TIMING);
+ vblank = READ_REG32 (DC3_V_BLANK_TIMING);
+
+ /* DISABLE TIMING REGISTER UPDATES */
+
+ WRITE_REG32 (DC3_DISPLAY_CFG, dcfg & ~(unsigned long)DC3_DCFG_TRUP);
+
+ /* WRITE NEW TIMING VALUES */
+
+ WRITE_REG32 (DC3_V_ACTIVE_TIMING, (vactive & DC3_VAT_VA_MASK) | (unsigned long)(vtotal - 1) << 16);
+ WRITE_REG32 (DC3_V_BLANK_TIMING, (vblank & DC3_VBT_VBS_MASK) | (unsigned long)(vtotal - 1) << 16);
+
+ /* RESTORE OLD RC VALUES */
+
+ WRITE_REG32 (DC3_DISPLAY_CFG, dcfg);
+ WRITE_REG32 (DC3_UNLOCK, unlock);
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_pitch
+ *
+ * This routine sets the pitch of the frame buffer to the specified value.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_display_pitch(unsigned short pitch)
+#else
+void gfx_set_display_pitch(unsigned short pitch)
+#endif
+{
+ unsigned long value = 0;
+ unsigned long lock = READ_REG32(DC3_UNLOCK);
+
+ value = READ_REG32(DC3_GFX_PITCH) & 0xFFFF0000;
+ value |= (pitch >> 3);
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_GFX_PITCH, value);
+
+ /* SET RENDERING PITCHES TO MATCH */
+
+ gfx_reset_pitch(pitch);
+
+ /* SET THE FRAME DIRTY MODE */
+ /* Non-standard pitches, i.e. pitches that */
+ /* are not 1K, 2K or 4K must mark the entire */
+ /* frame as dirty when writing to the frame */
+ /* buffer. */
+
+ value = READ_REG32 (DC3_GENERAL_CFG);
+
+ if (pitch == 1024 || pitch == 2048 || pitch == 4096 || pitch == 8192)
+ value &= ~(unsigned long)(DC3_GCFG_FDTY);
+ else
+ value |= (unsigned long)(DC3_GCFG_FDTY);
+
+ WRITE_REG32 (DC3_GENERAL_CFG, value);
+ WRITE_REG32(DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_offset
+ *
+ * This routine sets the start address of the frame buffer. It is
+ * typically used to pan across a virtual desktop (frame buffer larger than
+ * the displayed screen) or to flip the display between multiple buffers.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_display_offset(unsigned long offset)
+#else
+void gfx_set_display_offset(unsigned long offset)
+#endif
+{
+ /* UPDATE FRAME BUFFER OFFSET */
+ unsigned long lock;
+ lock = READ_REG32(DC3_UNLOCK);
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+ /* START ADDRESS EFFECTS DISPLAY COMPRESSION */
+ /* Disable compression for non-zero start addresss values. */
+ /* Enable compression if offset is zero and comression is intended to */
+ /* be enabled from a previous call to "gfx_set_compression_enable". */
+ /* Compression should be disabled BEFORE the offset is changed */
+ /* and enabled AFTER the offset is changed. */
+
+ if (offset == 0)
+ {
+ WRITE_REG32(DC3_FB_ST_OFFSET, offset);
+ if (gfx_compression_enabled)
+ {
+ /* WAIT FOR THE OFFSET TO BE LATCHED */
+ gfx_wait_vertical_blank ();
+ gu3_enable_compression();
+ }
+ }
+ else
+ {
+ /* ONLY DISABLE COMPRESSION ONCE */
+
+ if (gfx_compression_active)
+ gu3_disable_compression();
+
+ WRITE_REG32(DC3_FB_ST_OFFSET, offset);
+ }
+
+ WRITE_REG32(DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_palette_entry
+ *
+ * This routine sets an palette entry in the display controller.
+ * A 32-bit X:R:G:B value.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_set_display_palette_entry(unsigned long index, unsigned long palette)
+#else
+int gfx_set_display_palette_entry(unsigned long index, unsigned long palette)
+#endif
+{
+ if (index > 0xFF)
+ return GFX_STATUS_BAD_PARAMETER;
+
+ WRITE_REG32(DC3_PAL_ADDRESS, index);
+ WRITE_REG32(DC3_PAL_DATA, palette);
+
+ return(0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_palette
+ *
+ * This routine sets the entire palette in the display controller.
+ * A pointer is provided to a 256 entry table of 32-bit X:R:G:B values.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_set_display_palette(unsigned long *palette)
+#else
+int gfx_set_display_palette(unsigned long *palette)
+#endif
+{
+ unsigned long i;
+ WRITE_REG32(DC3_PAL_ADDRESS, 0);
+
+ if (palette)
+ {
+ for (i = 0; i < 256; i++)
+ {
+ WRITE_REG32(DC3_PAL_DATA, palette[i]);
+ }
+ }
+ return(0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_enable
+ *
+ * This routine enables or disables the hardware cursor.
+ *
+ * WARNING: The cursor start offset must be set by setting the cursor
+ * position before calling this routine to assure that memory reads do not
+ * go past the end of graphics memory (this can hang GXm).
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_cursor_enable(int enable)
+#else
+void gfx_set_cursor_enable(int enable)
+#endif
+{
+ unsigned long unlock, gcfg;
+
+ /* SET OR CLEAR CURSOR ENABLE BIT */
+
+ unlock = READ_REG32(DC3_UNLOCK);
+ gcfg = READ_REG32(DC3_GENERAL_CFG);
+ if (enable) gcfg |= DC3_GCFG_CURE;
+ else gcfg &= ~(DC3_GCFG_CURE);
+
+ /* WRITE NEW REGISTER VALUE */
+
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_GENERAL_CFG, gcfg);
+ WRITE_REG32(DC3_UNLOCK, unlock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_colors
+ *
+ * This routine sets the colors of the hardware cursor.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
+#else
+void gfx_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor)
+#endif
+{
+ /* SET CURSOR COLORS */
+
+ WRITE_REG32(DC3_PAL_ADDRESS, 0x100);
+ WRITE_REG32(DC3_PAL_DATA, bkcolor);
+ WRITE_REG32(DC3_PAL_DATA, fgcolor);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_position
+ *
+ * This routine sets the position of the hardware cusror. The starting
+ * offset of the cursor buffer must be specified so that the routine can
+ * properly clip scanlines if the cursor is off the top of the screen.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_cursor_position(unsigned long memoffset,
+ unsigned short xpos, unsigned short ypos,
+ unsigned short xhotspot, unsigned short yhotspot)
+#else
+void gfx_set_cursor_position(unsigned long memoffset,
+ unsigned short xpos, unsigned short ypos,
+ unsigned short xhotspot, unsigned short yhotspot)
+#endif
+{
+ unsigned long unlock;
+
+ short x = (short) xpos - (short) xhotspot;
+ short y = (short) ypos - (short) yhotspot;
+ short xoffset = 0;
+ short yoffset = 0;
+ if (x < -63) return;
+ if (y < -63) return;
+
+ if (PanelEnable)
+ {
+ if (( ModeWidth > PanelWidth) || (ModeHeight > PanelHeight))
+ {
+ gfx_enable_panning(xpos, ypos);
+ x = x - (unsigned short)panelLeft;
+ y = y - (unsigned short)panelTop;
+ }
+ }
+
+ /* ADJUST OFFSETS */
+ /* Cursor movement and panning work as follows: The cursor position */
+ /* refers to where the hotspot of the cursor is located. However, for */
+ /* non-zero hotspots, the cursor buffer actually begins before the */
+ /* specified position. */
+
+ if (x < 0) { xoffset = -x; x = 0; }
+ if (y < 0) { yoffset = -y; y = 0; }
+ memoffset += (unsigned long) yoffset << 4;
+
+ /* SET CURSOR POSITION */
+
+ unlock = READ_REG32(DC3_UNLOCK);
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_CURS_ST_OFFSET, memoffset);
+ WRITE_REG32(DC3_CURSOR_X, (unsigned long) x |
+ (((unsigned long) xoffset) << 11));
+ WRITE_REG32(DC3_CURSOR_Y, (unsigned long) y |
+ (((unsigned long) yoffset) << 11));
+ WRITE_REG32(DC3_UNLOCK, unlock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_shape32
+ *
+ * This routine loads 32x32 cursor data into the cursor buffer in graphics memory.
+ * As the Castle cursor is actually 64x64, we must pad the outside of the
+ * cursor data with transparent pixels.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_cursor_shape32(unsigned long memoffset,
+ unsigned long *andmask, unsigned long *xormask)
+#else
+void gfx_set_cursor_shape32(unsigned long memoffset,
+ unsigned long *andmask, unsigned long *xormask)
+#endif
+{
+ int i;
+
+ for (i = 0; i < 32; i++)
+ {
+ /* EVEN QWORDS CONTAIN THE AND MASK */
+
+ WRITE_FB32 (memoffset, 0xFFFFFFFF);
+ WRITE_FB32 (memoffset + 4, andmask[i]);
+
+ /* ODD QWORDS CONTAIN THE XOR MASK */
+
+ WRITE_FB32 (memoffset + 8, 0x00000000);
+ WRITE_FB32 (memoffset + 12, xormask[i]);
+
+ memoffset += 16;
+ }
+
+ /* FILL THE LOWER HALF OF THE BUFFER WITH TRANSPARENT PIXELS */
+
+ for (i = 0; i < 32; i++)
+ {
+ WRITE_FB32 (memoffset, 0xFFFFFFFF);
+ WRITE_FB32 (memoffset + 4, 0xFFFFFFFF);
+ WRITE_FB32 (memoffset + 8, 0x00000000);
+ WRITE_FB32 (memoffset + 12, 0x00000000);
+
+ memoffset += 16;
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_cursor_shape64
+ *
+ * This routine loads 64x64 cursor data into the cursor buffer in graphics memory.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_cursor_shape64(unsigned long memoffset,
+ unsigned long *andmask, unsigned long *xormask)
+#else
+void gfx_set_cursor_shape64(unsigned long memoffset,
+ unsigned long *andmask, unsigned long *xormask)
+#endif
+{
+ int i;
+
+ for (i = 0; i < 128; i += 2)
+ {
+ /* EVEN QWORDS CONTAIN THE AND MASK */
+ /* We invert the dwords to prevent the calling */
+ /* application from having to think in terms of Qwords. */
+ /* The hardware data order is actually 63:0, or 31:0 of */
+ /* the second dword followed by 31:0 of the first dword. */
+
+ WRITE_FB32 (memoffset, andmask[i + 1]);
+ WRITE_FB32 (memoffset + 4, andmask[i]);
+
+ /* ODD QWORDS CONTAIN THE XOR MASK */
+
+ WRITE_FB32 (memoffset + 8, xormask[i + 1]);
+ WRITE_FB32 (memoffset + 12, xormask[i]);
+
+ memoffset += 16;
+ }
+}
+
+/*---------------------------------------------------------------------------
+ * gu3_enable_compression
+ *
+ * This is a private routine to this module (not exposed in the Durango API).
+ * It enables display compression.
+ *---------------------------------------------------------------------------
+ */
+void gu3_enable_compression(void)
+{
+ unsigned long unlock, gcfg, temp;
+
+ /* DO NOT ENABLE IF START ADDRESS IS NOT ZERO */
+
+ if (READ_REG32(DC3_FB_ST_OFFSET) & 0x0FFFFFFF)
+ return;
+
+ /* SET GLOBAL INDICATOR */
+
+ gfx_compression_active = 1;
+
+ /* CLEAR DIRTY/VALID BITS IN MEMORY CONTROLLER */
+ /* Software is required to do this before enabling compression. */
+ /* Don't want controller to think that old lines are still valid. */
+ /* Writing a 1 to bit 0 of the DV Control register will force the */
+ /* hardware to clear all the valid bits. */
+
+ unlock = READ_REG32 (DC3_UNLOCK);
+ temp = READ_REG32 (DC3_DV_CTL);
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_DV_CTL, temp | 0x00000001);
+
+ /* TURN ON COMPRESSION CONTROL BITS */
+
+ gcfg = READ_REG32 (DC3_GENERAL_CFG);
+ gcfg |= DC3_GCFG_CMPE | DC3_GCFG_DECE;
+
+ WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+ WRITE_REG32 (DC3_UNLOCK, unlock);
+}
+
+/*---------------------------------------------------------------------------
+ * gu3_disable_compression
+ *
+ * This is a private routine to this module (not exposed in the Durango API).
+ * It disables display compression.
+ *---------------------------------------------------------------------------
+ */
+void gu3_disable_compression(void)
+{
+ unsigned long unlock, gcfg;
+
+ /* SET GLOBAL INDICATOR */
+
+ gfx_compression_active = 0;
+
+ /* TURN OFF COMPRESSION CONTROL BITS */
+
+ unlock = READ_REG32(DC3_UNLOCK);
+ gcfg = READ_REG32(DC3_GENERAL_CFG);
+ gcfg &= ~(DC3_GCFG_CMPE | DC3_GCFG_DECE);
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+ WRITE_REG32 (DC3_UNLOCK, unlock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_enable
+ *
+ * This routine enables or disables display compression.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_set_compression_enable(int enable)
+#else
+int gfx_set_compression_enable(int enable)
+#endif
+{
+ /* SET GLOBAL VARIABLE FOR INDENDED STATE */
+ /* Compression can only be enabled for non-zero start address values. */
+ /* Keep state to enable compression on start address changes. */
+
+ gfx_compression_enabled = enable;
+ if (enable) gu3_enable_compression();
+ else gu3_disable_compression();
+ return(0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_offset
+ *
+ * This routine sets the base offset for the compression buffer.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_set_compression_offset(unsigned long offset)
+#else
+int gfx_set_compression_offset(unsigned long offset)
+#endif
+{
+ unsigned long lock;
+
+ /* MUST BE 16-BYTE ALIGNED FOR CASTLE */
+
+ if (offset & 0x0F) return(1);
+
+ /* SET REGISTER VALUE */
+
+ lock = READ_REG32(DC3_UNLOCK);
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_CB_ST_OFFSET, offset & 0x0FFFFFFF);
+ WRITE_REG32(DC3_UNLOCK, lock);
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_pitch
+ *
+ * This routine sets the pitch, in bytes, of the compression buffer.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_set_compression_pitch(unsigned short pitch)
+#else
+int gfx_set_compression_pitch(unsigned short pitch)
+#endif
+{
+ unsigned long lock, line_delta;
+
+ lock = READ_REG32(DC3_UNLOCK);
+
+ /* SET REGISTER VALUE */
+
+ line_delta = READ_REG32(DC3_GFX_PITCH) & 0x0000FFFF;
+ line_delta |= (((unsigned long)pitch << 13) & 0xFFFF0000);
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_GFX_PITCH, line_delta);
+ WRITE_REG32(DC3_UNLOCK, lock);
+ return(0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_compression_size
+ *
+ * This routine sets the line size of the compression buffer, which is the
+ * maximum number of bytes allowed to store a compressed line.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_set_compression_size(unsigned short size)
+#else
+int gfx_set_compression_size(unsigned short size)
+#endif
+{
+ unsigned long lock, buf_size;
+
+ /* SUBTRACT 32 FROM SIZE */
+ /* The display controller will actually write */
+ /* 4 extra QWords. So, if we assume that "size" */
+ /* refers to the allocated size, we must subtract */
+ /* 32 bytes. */
+
+ size -= 32;
+
+ /* SET REGISTER VALUE */
+
+ lock = READ_REG32(DC3_UNLOCK);
+ buf_size = READ_REG32(DC3_LINE_SIZE) & ~DC3_LINE_SIZE_CBLS_MASK;
+ buf_size |= ((((unsigned long)size >> 3) + 1) & 0x7F) << DC3_LINE_SIZE_CB_SHIFT;
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_LINE_SIZE, buf_size);
+ WRITE_REG32(DC3_UNLOCK, lock);
+ return(0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_color_key (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_color_key". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_display_video_color_key (unsigned long key, unsigned long mask, int enable)
+#else
+void gfx_set_display_video_color_key (unsigned long key, unsigned long mask, int enable)
+#endif
+{
+ unsigned long colorkey = 0;
+ unsigned long lock;
+
+ if (enable)
+ colorkey = (key & 0xFFFFFF) | DC3_CLR_KEY_ENABLE;
+
+ lock = READ_REG32 (DC3_UNLOCK);
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+
+ WRITE_REG32 (DC3_COLOR_KEY, colorkey);
+ WRITE_REG32 (DC3_COLOR_MASK, (mask & 0xFFFFFF));
+
+ WRITE_REG32 (DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_format (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_format". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_display_video_format(unsigned long format)
+#else
+void gfx_set_display_video_format(unsigned long format)
+#endif
+{
+ unsigned long gcfg, lock;
+
+ lock = READ_REG32 (DC3_UNLOCK);
+ gcfg = READ_REG32 (DC3_GENERAL_CFG);
+
+ switch (format)
+ {
+ case VIDEO_FORMAT_Y0Y1Y2Y3:
+ case VIDEO_FORMAT_Y3Y2Y1Y0:
+ case VIDEO_FORMAT_Y1Y0Y3Y2:
+ case VIDEO_FORMAT_Y1Y2Y3Y0:
+
+ gcfg |= DC3_GCFG_YUVM;
+ break;
+
+ default:
+
+ gcfg &= ~DC3_GCFG_YUVM;
+ break;
+ }
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+ WRITE_REG32 (DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_enable (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_enable". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_display_video_enable(int enable)
+#else
+void gfx_set_display_video_enable(int enable)
+#endif
+{
+ unsigned long lock, gcfg, dcfg;
+
+ /* READ CURRENT VALUES */
+
+ lock = READ_REG32 (DC3_UNLOCK);
+ gcfg = READ_REG32 (DC3_GENERAL_CFG);
+ dcfg = READ_REG32 (DC3_DISPLAY_CFG);
+
+ /* SET OR CLEAR VIDEO ENABLE IN GENERAL_CFG */
+
+ if (enable) gcfg |= DC3_GCFG_VIDE;
+ else gcfg &= ~DC3_GCFG_VIDE;
+
+ /* WRITE REGISTER */
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
+ WRITE_REG32 (DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_size (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_size". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_display_video_size(unsigned short width, unsigned short height)
+#else
+void gfx_set_display_video_size(unsigned short width, unsigned short height)
+#endif
+{
+ unsigned long lock, value, yuv_420;
+
+ /* READ CURRENT VALUES */
+
+ lock = READ_REG32 (DC3_UNLOCK);
+ value = READ_REG32 (DC3_LINE_SIZE) & ~DC3_LINE_SIZE_VLS_MASK;
+ yuv_420 = READ_REG32 (DC3_GENERAL_CFG) & DC3_GCFG_YUVM;
+
+ /* LINE WIDTH IS 1/4 FOR 4:2:0 VIDEO */
+ /* All data must be 32-byte aligned. */
+
+ if (yuv_420)
+ {
+ width >>= 1;
+ width = (width + 7) & 0xFFF8;
+ }
+ else
+ {
+ width <<= 1;
+ width = (width + 31) & 0xFFE0;
+ }
+
+ /* ONLY THE LINE SIZE IS PROGRAMMED IN THE DISPLAY CONTROLLER */
+ /* Shift by three less than the bit position to effect a divide by 8 */
+
+ value |= ((unsigned long)width << (DC3_LINE_SIZE_VB_SHIFT - 3)) & DC3_LINE_SIZE_VLS_MASK;
+
+ /* WRITE THE REGISTER */
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_LINE_SIZE, value);
+ WRITE_REG32 (DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_offset (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_set_video_offset". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_display_video_offset(unsigned long offset)
+#else
+void gfx_set_display_video_offset(unsigned long offset)
+#endif
+{
+ unsigned long lock;
+
+ lock = READ_REG32(DC3_UNLOCK);
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ offset &= 0x0FFFFFF0;
+ WRITE_REG32(DC3_VID_Y_ST_OFFSET, offset);
+ WRITE_REG32(DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_yuv_offsets (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by gfx_set_video_yuv_offsets. It abstracts the version
+ * of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_display_video_yuv_offsets(unsigned long yoffset, unsigned long uoffset,
+ unsigned long voffset)
+#else
+void gfx_set_display_video_yuv_offsets(unsigned long yoffset, unsigned long uoffset,
+ unsigned long voffset)
+#endif
+{
+ unsigned long lock;
+
+ lock = READ_REG32(DC3_UNLOCK);
+
+ yoffset &= 0x0FFFFFF0;
+ uoffset &= 0x0FFFFFF8;
+ voffset &= 0x0FFFFFF8;
+
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_VID_Y_ST_OFFSET, yoffset);
+ WRITE_REG32(DC3_VID_U_ST_OFFSET, uoffset);
+ WRITE_REG32(DC3_VID_V_ST_OFFSET, voffset);
+ WRITE_REG32(DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_display_video_yuv_pitch (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by gfx_set_video_yuv_pitch. It abstracts the version
+ * of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_set_display_video_yuv_pitch (unsigned long ypitch, unsigned long uvpitch)
+#else
+void gfx_set_display_video_yuv_pitch (unsigned long ypitch, unsigned long uvpitch)
+#endif
+{
+ unsigned long lock, pitch;
+
+ lock = READ_REG32(DC3_UNLOCK);
+
+ pitch = ((uvpitch << 13) & 0xFFFF0000) | ((ypitch >> 3) & 0xFFFF);
+
+ WRITE_REG32(DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32(DC3_VID_YUV_PITCH, pitch);
+ WRITE_REG32(DC3_UNLOCK, lock);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_test_timing_active
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_test_timing_active(void)
+#else
+int gfx_test_timing_active(void)
+#endif
+{
+ if (READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_TGEN)
+ return(1);
+ else return(0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_test_vertical_active
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_test_vertical_active(void)
+#else
+int gfx_test_vertical_active(void)
+#endif
+{
+ if (READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VNA)
+ return(0);
+
+ return(1);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_wait_vertical_blank
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_wait_vertical_blank(void)
+#else
+int gfx_wait_vertical_blank(void)
+#endif
+{
+ if (gfx_test_timing_active())
+ {
+ while(!gfx_test_vertical_active());
+ while(gfx_test_vertical_active());
+ }
+ return(0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_enable_panning
+ *
+ * This routine enables the panning when the Mode is bigger than the panel
+ * size.
+ *---------------------------------------------------------------------------
+ */
+
+#if GFX_DISPLAY_DYNAMIC
+void gu3_enable_panning(int x, int y)
+#else
+void gfx_enable_panning(int x, int y)
+#endif
+{
+ unsigned long modeBytesPerPixel;
+ unsigned long modeBytesPerScanline = 0;
+ unsigned long startAddress = 0;
+
+ modeBytesPerPixel = (gbpp + 7)/8;
+ modeBytesPerScanline = (READ_REG32 (DC3_GFX_PITCH) & 0x0000FFFF) << 3;
+
+ /* TEST FOR NO-WORK */
+
+ if (x >= DeltaX && x < ((int)PanelWidth + DeltaX) &&
+ y >= DeltaY && y < ((int)PanelHeight + DeltaY))
+ return;
+
+ /* ADJUST PANNING VARIABLES WHEN CURSOR EXCEEDS BOUNDARY */
+ /* Test the boundary conditions for each coordinate and update */
+ /* all variables and the starting offset accordingly. */
+
+ if (x < DeltaX)
+ DeltaX = x;
+
+ else if (x >= (DeltaX + (int)PanelWidth))
+ DeltaX = x - (int)PanelWidth + 1;
+
+ if (y < DeltaY)
+ DeltaY = y;
+
+ else if (y >= (DeltaY + (int)PanelHeight))
+ DeltaY = y - (int)PanelHeight + 1;
+
+ /* CALCULATE THE START OFFSET */
+
+ startAddress = (DeltaX * modeBytesPerPixel) + (DeltaY * modeBytesPerScanline);
+
+ gfx_set_display_offset(startAddress);
+
+ /* SET PANEL COORDINATES */
+ /* Panel's x position must be DWORD aligned */
+
+ panelTop = DeltaY;
+ panelLeft = DeltaX * modeBytesPerPixel;
+
+ if (panelLeft & 3)
+ panelLeft = (panelLeft & 0xFFFFFFFC) + 4;
+
+ panelLeft /= modeBytesPerPixel;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_fixed_timings
+ *---------------------------------------------------------------------------
+ */
+
+#if GFX_DISPLAY_DYNAMIC
+int gu3_set_fixed_timings(int panelResX, int panelResY, unsigned short width, unsigned short height, unsigned short bpp)
+#else
+int gfx_set_fixed_timings(int panelResX, int panelResY, unsigned short width, unsigned short height, unsigned short bpp)
+#endif
+{
+ unsigned int mode;
+
+ ModeWidth = width;
+ ModeHeight = height;
+ PanelWidth = (unsigned short)panelResX;
+ PanelHeight = (unsigned short)panelResY;
+ PanelEnable = 1;
+
+ /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
+ for (mode = 0; mode < NUM_FIXED_TIMINGS_MODES; mode++) {
+ if ((FixedParams[mode].xres == width) &&
+ (FixedParams[mode].yres == height) &&
+ (FixedParams[mode].panelresx == panelResX) &&
+ (FixedParams[mode].panelresy == panelResY)) {
+
+ /* SET THE 92xx FOR THE SELECTED MODE */
+ FIXEDTIMINGS *fmode = &FixedParams[mode];
+
+ gfx_set_display_timings(bpp, 3, fmode->hactive,fmode->hblankstart, fmode->hsyncstart, fmode->hsyncend,
+ fmode->hblankend, fmode->htotal, fmode->vactive, fmode->vblankstart,
+ fmode->vsyncstart, fmode->vsyncend, fmode->vblankend, fmode->vtotal, fmode->frequency);
+
+ return(1);
+ } /* end if() */
+ } /* end for() */
+
+ return(-1);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_set_panel_present
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_set_panel_present(int panelResX, int panelResY, unsigned short width, unsigned short height, unsigned short bpp)
+#else
+int gfx_set_panel_present(int panelResX, int panelResY, unsigned short width, unsigned short height, unsigned short bpp)
+#endif
+{
+ /* SET VALID BPP */
+ /* 16BPP is the default. */
+
+ if (bpp != 8 && bpp != 12 && bpp != 15 && bpp != 16 && bpp != 32)
+ bpp = 16;
+
+ /* RECORD PANEL PARAMETERS */
+ /* This routine does not touch any panel timings. It is used when custom panel */
+ /* settings are set up in advance by the BIOS or an application, but the */
+ /* application still requires access to other panel functionality provided by */
+ /* Durango (i.e. panning). */
+
+ ModeWidth = width;
+ ModeHeight = height;
+ PanelWidth = (unsigned short)panelResX;
+ PanelHeight = (unsigned short)panelResY;
+ PanelEnable = 1;
+ gbpp = bpp;
+
+ /* PROGRAM THE BPP IN THE DISPLAY CONTROLLER */
+
+ gfx_set_display_bpp (bpp);
+
+ return(GFX_STATUS_OK);
+}
+
+/* THE FOLLOWING READ ROUTINES ARE ALWAYS INCLUDED: */
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_pitch
+ *
+ * This routine returns the current pitch of the frame buffer, in bytes.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short gu3_get_display_pitch(void)
+#else
+unsigned short gfx_get_display_pitch(void)
+#endif
+{
+ return ((unsigned short)(READ_REG32 (DC3_GFX_PITCH) & 0x0000FFFF) << 3);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_mode_frequency_supported
+ *
+ * This routine examines if the requested mode with pixel frequency is supported.
+ *
+ * Returns >0 if successful , <0 if freq. could not be found and matched.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_mode_frequency_supported(int xres, int yres, int bpp, unsigned long frequency)
+#else
+int gfx_mode_frequency_supported(int xres, int yres, int bpp, unsigned long frequency)
+#endif
+{
+ unsigned int index;
+ unsigned long value;
+ unsigned long bpp_flag = 0;
+
+ switch (bpp)
+ {
+ case 8: bpp_flag = GFX_MODE_8BPP; break;
+ case 12: bpp_flag = GFX_MODE_12BPP; break;
+ case 15: bpp_flag = GFX_MODE_15BPP; break;
+ case 16: bpp_flag = GFX_MODE_16BPP; break;
+ case 32: bpp_flag = GFX_MODE_24BPP; break;
+ default: bpp_flag = GFX_MODE_8BPP; break;
+ }
+
+ for (index = 0; index < NUM_RC_DISPLAY_MODES; index++)
+ {
+ if ((DisplayParams[index].hactive == (unsigned int)xres) &&
+ (DisplayParams[index].vactive == (unsigned int)yres) &&
+ (DisplayParams[index].flags & bpp_flag) &&
+ (DisplayParams[index].frequency == frequency))
+ {
+ int hz=0;
+ value = DisplayParams[index].flags;
+
+ if (value & GFX_MODE_56HZ) hz = 56;
+ else if (value & GFX_MODE_60HZ) hz = 60;
+ else if (value & GFX_MODE_70HZ) hz = 70;
+ else if (value & GFX_MODE_72HZ) hz = 72;
+ else if (value & GFX_MODE_75HZ) hz = 75;
+ else if (value & GFX_MODE_85HZ) hz = 85;
+ else if (value & GFX_MODE_90HZ) hz = 90;
+ else if (value & GFX_MODE_100HZ) hz = 100;
+ return(hz);
+ }
+ }
+
+ return(-1);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_refreshrate_from_frequency
+ *
+ * This routine maps the frequency to close match refresh rate
+ *
+ * Returns .
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz, unsigned long frequency)
+#else
+int gfx_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz, unsigned long frequency)
+#endif
+{
+ unsigned int index, closematch=0;
+ unsigned long value;
+ unsigned long bpp_flag = 0;
+ long min, diff;
+
+ *hz = 60;
+
+ switch (bpp)
+ {
+ case 8: bpp_flag = GFX_MODE_8BPP; break;
+ case 12: bpp_flag = GFX_MODE_12BPP; break;
+ case 15: bpp_flag = GFX_MODE_15BPP; break;
+ case 16: bpp_flag = GFX_MODE_16BPP; break;
+ case 32: bpp_flag = GFX_MODE_24BPP; break;
+ default: bpp_flag = GFX_MODE_8BPP; break;
+ }
+
+ /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
+ /* Search the table for the closest frequency (16.16 format). */
+
+ min = 0x7fffffff;
+ for (index = 0; index < NUM_RC_DISPLAY_MODES; index++)
+ {
+ if ((DisplayParams[index].htotal == (unsigned int)xres) &&
+ (DisplayParams[index].vtotal == (unsigned int)yres) &&
+ (DisplayParams[index].flags & bpp_flag))
+ {
+ diff = (long)frequency - (long)DisplayParams[index].frequency;
+ if(diff < 0) diff = -diff;
+
+ if (diff < min)
+ {
+ min = diff;
+ closematch = index;
+ }
+ }
+ }
+
+ value = DisplayParams[closematch].flags;
+
+ if (value & GFX_MODE_56HZ) *hz = 56;
+ else if (value & GFX_MODE_60HZ) *hz = 60;
+ else if (value & GFX_MODE_70HZ) *hz = 70;
+ else if (value & GFX_MODE_72HZ) *hz = 72;
+ else if (value & GFX_MODE_75HZ) *hz = 75;
+ else if (value & GFX_MODE_85HZ) *hz = 85;
+ else if (value & GFX_MODE_90HZ) *hz = 90;
+ else if (value & GFX_MODE_100HZ) *hz = 100;
+
+ return(1);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_refreshrate_from_mode
+ *
+ * This routine is identical to the gfx_get_refreshrate_from_frequency,
+ * except that the active timing values are compared instead of the total
+ * values. Some modes (such as 70Hz and 72Hz) may be confused in this routine.
+ *
+ * Returns .
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz, unsigned long frequency)
+#else
+int gfx_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz, unsigned long frequency)
+#endif
+{
+ unsigned int index, closematch=0;
+ unsigned long value;
+ unsigned long bpp_flag = 0;
+ long min, diff;
+
+ *hz = 60;
+
+ switch (bpp)
+ {
+ case 8: bpp_flag = GFX_MODE_8BPP; break;
+ case 12: bpp_flag = GFX_MODE_12BPP; break;
+ case 15: bpp_flag = GFX_MODE_15BPP; break;
+ case 16: bpp_flag = GFX_MODE_16BPP; break;
+ case 32: bpp_flag = GFX_MODE_24BPP; break;
+ default: bpp_flag = GFX_MODE_8BPP; break;
+ }
+
+ /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
+ /* Search the table for the closest frequency (16.16 format). */
+
+ min = 0x7fffffff;
+ for (index = 0; index < NUM_RC_DISPLAY_MODES; index++)
+ {
+ if ((DisplayParams[index].hactive == (unsigned int)xres) &&
+ (DisplayParams[index].vactive == (unsigned int)yres) &&
+ (DisplayParams[index].flags & bpp_flag))
+ {
+ diff = (long)frequency - (long)DisplayParams[index].frequency;
+ if(diff < 0) diff = -diff;
+
+ if (diff < min)
+ {
+ min = diff;
+ closematch = index;
+ }
+ }
+ }
+
+ value = DisplayParams[closematch].flags;
+
+ if (value & GFX_MODE_56HZ) *hz = 56;
+ else if (value & GFX_MODE_60HZ) *hz = 60;
+ else if (value & GFX_MODE_70HZ) *hz = 70;
+ else if (value & GFX_MODE_72HZ) *hz = 72;
+ else if (value & GFX_MODE_75HZ) *hz = 75;
+ else if (value & GFX_MODE_85HZ) *hz = 85;
+ else if (value & GFX_MODE_90HZ) *hz = 90;
+ else if (value & GFX_MODE_100HZ) *hz = 100;
+
+ return(1);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_frequency_from_refreshrate
+ *
+ * This routine maps the refresh rate to the closest matching PLL frequency.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz, int *frequency)
+#else
+int gfx_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz, int *frequency)
+#endif
+{
+ unsigned int index;
+ int retval = -1;
+ unsigned long hz_flag = 0;
+ unsigned long bpp_flag = 0;
+
+ *frequency = 0;
+
+ if (hz == 56) hz_flag = GFX_MODE_56HZ;
+ else if (hz == 60) hz_flag = GFX_MODE_60HZ;
+ else if (hz == 70) hz_flag = GFX_MODE_70HZ;
+ else if (hz == 72) hz_flag = GFX_MODE_72HZ;
+ else if (hz == 75) hz_flag = GFX_MODE_75HZ;
+ else if (hz == 85) hz_flag = GFX_MODE_85HZ;
+ else if (hz == 90) hz_flag = GFX_MODE_90HZ;
+ else if (hz == 100) hz_flag = GFX_MODE_100HZ;
+
+ switch (bpp)
+ {
+ case 8: bpp_flag = GFX_MODE_8BPP; break;
+ case 12: bpp_flag = GFX_MODE_12BPP; break;
+ case 15: bpp_flag = GFX_MODE_15BPP; break;
+ case 16: bpp_flag = GFX_MODE_16BPP; break;
+ case 32: bpp_flag = GFX_MODE_24BPP; break;
+ default: bpp_flag = GFX_MODE_8BPP; break;
+ }
+
+ /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
+ /* Search the table for the closest frequency (16.16 format). */
+
+ for (index = 0; index < NUM_RC_DISPLAY_MODES; index++)
+ {
+ if ((DisplayParams[index].hactive == (unsigned short)xres) &&
+ (DisplayParams[index].vactive == (unsigned short)yres) &&
+ (DisplayParams[index].flags & bpp_flag) &&
+ (DisplayParams[index].flags & hz_flag))
+ {
+ *frequency = (int)DisplayParams[index].frequency;
+ retval = 1;
+ }
+ }
+ return retval;
+}
+
+
+/*---------------------------------------------------------------------------
+ * gfx_get_max_supported_pixel_clock
+ *
+ * This routine returns the maximum recommended speed for the pixel clock. The
+ * return value is an integer of the format xxxyyy, where xxx.yyy is the maximum
+ * floating point pixel clock speed.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long gu3_get_max_supported_pixel_clock (void)
+#else
+unsigned long gfx_get_max_supported_pixel_clock (void)
+#endif
+
+{
+ return 229500;
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_display_mode
+ *
+ * This routine gets the specified display mode.
+ *
+ * Returns >0 if successful and mode returned, <0 if mode could not be found.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_get_display_mode(int *xres, int *yres, int *bpp, int *hz)
+#else
+int gfx_get_display_mode(int *xres, int *yres, int *bpp, int *hz)
+#endif
+{
+ unsigned int mode=0;
+ unsigned long pll_freq = 0, bpp_flag = 0;
+
+ *xres = gfx_get_hactive();
+ *yres = gfx_get_vactive();
+ *bpp = gfx_get_display_bpp();
+ pll_freq = gfx_get_clock_frequency();
+
+ /* SET BPP FLAGS TO LIMIT MODE SELECTION */
+
+ switch (*bpp)
+ {
+ case 8: bpp_flag = GFX_MODE_8BPP; break;
+ case 12: bpp_flag = GFX_MODE_12BPP; break;
+ case 15: bpp_flag = GFX_MODE_15BPP; break;
+ case 16: bpp_flag = GFX_MODE_16BPP; break;
+ case 32: bpp_flag = GFX_MODE_24BPP; break;
+ default: bpp_flag = GFX_MODE_8BPP; break;
+ }
+
+ for (mode = 0; mode < NUM_RC_DISPLAY_MODES; mode++) {
+ if ((DisplayParams[mode].hactive == (unsigned int)*xres) &&
+ (DisplayParams[mode].vactive == (unsigned int)*yres) &&
+ (DisplayParams[mode].frequency == pll_freq) &&
+ (DisplayParams[mode].flags & bpp_flag)) {
+
+ pll_freq = DisplayParams[mode].flags;
+
+ if (pll_freq & GFX_MODE_56HZ) *hz = 56;
+ else if (pll_freq & GFX_MODE_60HZ) *hz = 60;
+ else if (pll_freq & GFX_MODE_70HZ) *hz = 70;
+ else if (pll_freq & GFX_MODE_72HZ) *hz = 72;
+ else if (pll_freq & GFX_MODE_75HZ) *hz = 75;
+ else if (pll_freq & GFX_MODE_85HZ) *hz = 85;
+ else if (pll_freq & GFX_MODE_90HZ) *hz = 90;
+ else if (pll_freq & GFX_MODE_100HZ) *hz = 100;
+
+ return(1);
+ }
+ }
+ return(-1);
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_GET_DISPLAY_DETAILS
+ *
+ * This routine gets the specified display mode.
+ *
+ * Returns 1 if successful, 0 if mode could not be get.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_get_display_details(unsigned int mode, int *xres, int *yres, int *hz)
+#else
+int gfx_get_display_details(unsigned int mode, int *xres, int *yres, int *hz)
+#endif
+{
+ if(mode < NUM_RC_DISPLAY_MODES)
+ {
+ if(DisplayParams[mode].flags & GFX_MODE_56HZ)
+ *hz = 56;
+ else if(DisplayParams[mode].flags & GFX_MODE_60HZ)
+ *hz = 60;
+ else if(DisplayParams[mode].flags & GFX_MODE_70HZ)
+ *hz = 70;
+ else if(DisplayParams[mode].flags & GFX_MODE_72HZ)
+ *hz = 72;
+ else if(DisplayParams[mode].flags & GFX_MODE_75HZ)
+ *hz = 75;
+ else if(DisplayParams[mode].flags & GFX_MODE_85HZ)
+ *hz = 85;
+ else if(DisplayParams[mode].flags & GFX_MODE_90HZ)
+ *hz = 90;
+ else if(DisplayParams[mode].flags & GFX_MODE_100HZ)
+ *hz = 100;
+
+ *xres = DisplayParams[mode].hactive;
+ *yres = DisplayParams[mode].vactive;
+
+ if (DisplayParams[mode].flags & GFX_MODE_PIXEL_DOUBLE)
+ *xres >>= 1;
+ if (DisplayParams[mode].flags & GFX_MODE_LINE_DOUBLE)
+ *yres >>= 1;
+
+ return(1);
+ }
+ return(0);
+}
+
+/*----------------------------------------------------------------------------
+ * GFX_GET_DISPLAY_MODE_COUNT
+ *
+ * This routine gets the number of available display modes.
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_get_display_mode_count(void)
+#else
+int gfx_get_display_mode_count(void)
+#endif
+{
+ return(NUM_RC_DISPLAY_MODES);
+}
+
+/*----------------------------------------------------------------------------
+ * gfx_get_frame_buffer_line_size
+ *
+ * Returns the current frame buffer line size, in bytes
+ *----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long gu3_get_frame_buffer_line_size(void)
+#else
+unsigned long gfx_get_frame_buffer_line_size(void)
+#endif
+{
+ return ((READ_REG32 (DC3_LINE_SIZE) & 0x3FF) << 3);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hactive
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short gu3_get_hactive(void)
+#else
+unsigned short gfx_get_hactive(void)
+#endif
+{
+ return((unsigned short)((READ_REG32(DC3_H_ACTIVE_TIMING) & 0x0FF8) + 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hsync_start
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short gu3_get_hsync_start(void)
+#else
+unsigned short gfx_get_hsync_start(void)
+#endif
+{
+ return ((unsigned short)((READ_REG32(DC3_H_SYNC_TIMING) & 0x0FF8) + 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hsync_end
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short gu3_get_hsync_end(void)
+#else
+unsigned short gfx_get_hsync_end(void)
+#endif
+{
+ return((unsigned short)(((READ_REG32(DC3_H_SYNC_TIMING) >> 16) & 0x0FF8) + 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_htotal
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short gu3_get_htotal(void)
+#else
+unsigned short gfx_get_htotal(void)
+#endif
+{
+ return((unsigned short)(((READ_REG32(DC3_H_ACTIVE_TIMING) >> 16) & 0x0FF8) + 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vactive
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short gu3_get_vactive(void)
+#else
+unsigned short gfx_get_vactive(void)
+#endif
+{
+ return((unsigned short)((READ_REG32(DC3_V_ACTIVE_TIMING) & 0x07FF) + 1));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vsync_end
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short gu3_get_vsync_end(void)
+#else
+unsigned short gfx_get_vsync_end(void)
+#endif
+{
+ return((unsigned short)(((READ_REG32(DC3_V_SYNC_TIMING) >> 16) & 0x07FF) + 1));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vtotal
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short gu3_get_vtotal(void)
+#else
+unsigned short gfx_get_vtotal(void)
+#endif
+{
+ return((unsigned short)(((READ_REG32(DC3_V_ACTIVE_TIMING) >> 16) & 0x07FF) + 1));
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_display_bpp
+ *
+ * This routine returns the current color depth of the active display.
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short gu3_get_display_bpp(void)
+#else
+unsigned short gfx_get_display_bpp(void)
+#endif
+{
+ unsigned long dcfg = READ_REG32 (DC3_DISPLAY_CFG);
+
+ switch ((dcfg & DC3_DCFG_DISP_MODE_MASK) >> 8)
+ {
+ case 0: return (8);
+ case 2: return (32);
+
+ case 1:
+
+ switch ((dcfg & DC3_DCFG_16BPP_MODE_MASK) >> 10)
+ {
+ case 0: return (16);
+ case 1: return (15);
+ case 2: return (12);
+ default: return (0);
+ }
+ }
+
+ /* INVALID SETTING */
+
+ return (0);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vline
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short gu3_get_vline(void)
+#else
+unsigned short gfx_get_vline(void)
+#endif
+{
+ unsigned long current_scan_line;
+
+ /* Read similar value twice to ensure that the value is not transitioning */
+
+ do current_scan_line = (READ_REG32(DC3_LINE_CNT_STATUS) & DC3_LNCNT_V_LINE_CNT);
+ while(current_scan_line != (READ_REG32(DC3_LINE_CNT_STATUS) & DC3_LNCNT_V_LINE_CNT));
+
+ return ((unsigned short)(current_scan_line >> 16));
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_display_offset
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long gu3_get_display_offset(void)
+#else
+unsigned long gfx_get_display_offset(void)
+#endif
+{
+ return (READ_REG32(DC3_FB_ST_OFFSET) & 0x0FFFFFFF);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_cursor_offset
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long gu3_get_cursor_offset(void)
+#else
+unsigned long gfx_get_cursor_offset(void)
+#endif
+{
+ return (READ_REG32(DC3_CURS_ST_OFFSET) & 0x0FFFFFFF);
+}
+
+#if GFX_READ_ROUTINES
+
+/*************************************************************/
+/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */
+/*************************************************************/
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hblank_start
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short gu3_get_hblank_start(void)
+#else
+unsigned short gfx_get_hblank_start(void)
+#endif
+{
+ return ((unsigned short)((READ_REG32(DC3_H_BLANK_TIMING) & 0x0FF8) + 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_hblank_end
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short gu3_get_hblank_end(void)
+#else
+unsigned short gfx_get_hblank_end(void)
+#endif
+{
+ return ((unsigned short)(((READ_REG32(DC3_H_BLANK_TIMING) >> 16) & 0x0FF8) + 8));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vblank_start
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short gu3_get_vblank_start(void)
+#else
+unsigned short gfx_get_vblank_start(void)
+#endif
+{
+ return ((unsigned short)((READ_REG32(DC3_V_BLANK_TIMING) & 0x07FF) + 1));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vsync_start
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short gu3_get_vsync_start(void)
+#else
+unsigned short gfx_get_vsync_start(void)
+#endif
+{
+ return ((unsigned short)((READ_REG32(DC3_V_SYNC_TIMING) & 0x07FF) + 1));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_vblank_end
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short gu3_get_vblank_end(void)
+#else
+unsigned short gfx_get_vblank_end(void)
+#endif
+{
+ return ((unsigned short)(((READ_REG32(DC3_V_BLANK_TIMING) >> 16) & 0x07FF) + 1));
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_display_palette_entry
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_get_display_palette_entry(unsigned long index, unsigned long *palette)
+#else
+int gfx_get_display_palette_entry(unsigned long index, unsigned long *palette)
+#endif
+{
+ if (index > 0xFF)
+ return GFX_STATUS_BAD_PARAMETER;
+
+ WRITE_REG32(DC3_PAL_ADDRESS, index);
+ *palette = READ_REG32(DC3_PAL_DATA);
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_display_palette
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_get_display_palette(unsigned long *palette)
+#else
+void gfx_get_display_palette(unsigned long *palette)
+#endif
+{
+ unsigned long i;
+
+ WRITE_REG32(DC3_PAL_ADDRESS, 0);
+ for (i = 0; i < 256; i++)
+ {
+ palette[i] = READ_REG32(DC3_PAL_DATA);
+ }
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_cursor_enable
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long gu3_get_cursor_enable(void)
+#else
+unsigned long gfx_get_cursor_enable(void)
+#endif
+{
+ return (READ_REG32(DC3_GENERAL_CFG) & DC3_GCFG_CURE);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_cursor_position
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long gu3_get_cursor_position(void)
+#else
+unsigned long gfx_get_cursor_position(void)
+#endif
+{
+ return((READ_REG32(DC3_CURSOR_X) & 0x07FF) |
+ ((READ_REG32(DC3_CURSOR_Y) << 16) & 0x07FF0000));
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_cursor_offset
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long gu3_get_cursor_clip(void)
+#else
+unsigned long gfx_get_cursor_clip(void)
+#endif
+{
+ return (((READ_REG32(DC3_CURSOR_X) >> 11) & 0x03F) |
+ ((READ_REG32(DC3_CURSOR_Y) << 5) & 0x3F0000));
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_cursor_color
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long gu3_get_cursor_color(int color)
+#else
+unsigned long gfx_get_cursor_color(int color)
+#endif
+{
+ if (color)
+ {
+ WRITE_REG32(DC3_PAL_ADDRESS, 0x101);
+ }
+ else
+ {
+ WRITE_REG32(DC3_PAL_ADDRESS, 0x100);
+ }
+ return READ_REG32(DC3_PAL_DATA);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_compression_enable
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_get_compression_enable(void)
+#else
+int gfx_get_compression_enable(void)
+#endif
+{
+ if (READ_REG32 (DC3_GENERAL_CFG) & DC3_GCFG_CMPE)
+ return (1);
+
+ return(0);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_compression_offset
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long gu3_get_compression_offset(void)
+#else
+unsigned long gfx_get_compression_offset(void)
+#endif
+{
+ return (READ_REG32(DC3_CB_ST_OFFSET) & 0x007FFFFF);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_compression_pitch
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short gu3_get_compression_pitch(void)
+#else
+unsigned short gfx_get_compression_pitch(void)
+#endif
+{
+ unsigned short pitch;
+ pitch = (unsigned short)(READ_REG32(DC3_GFX_PITCH) >> 16);
+ return (pitch << 3);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_compression_size
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned short gu3_get_compression_size(void)
+#else
+unsigned short gfx_get_compression_size(void)
+#endif
+{
+ unsigned short size;
+ size = (unsigned short)((READ_REG32(DC3_LINE_SIZE) >> DC3_LINE_SIZE_CB_SHIFT) & 0x7F) - 1;
+ return ((size << 3) + 32);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_valid_bit
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+int gu3_get_valid_bit(int line)
+#else
+int gfx_get_valid_bit(int line)
+#endif
+{
+ unsigned long lock;
+ unsigned long offset;
+ int valid;
+
+ lock = READ_REG32 (DC3_UNLOCK);
+ offset = READ_REG32 (DC3_PHY_MEM_OFFSET) & 0xFF000000;
+ offset |= line;
+
+ WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
+ WRITE_REG32 (DC3_PHY_MEM_OFFSET, offset);
+ WRITE_REG32 (DC3_UNLOCK, lock);
+ valid = (int)READ_REG32 (DC3_DV_ACC) & 2;
+
+ if (valid) return 1;
+ return 0;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_offset (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_get_video_offset". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long gu3_get_display_video_offset(void)
+#else
+unsigned long gfx_get_display_video_offset(void)
+#endif
+{
+ return (READ_REG32(DC3_VID_Y_ST_OFFSET) & 0x0FFFFFFF);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_yuv_offsets (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_get_video_yuv_offsets". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_get_display_video_yuv_offsets(unsigned long *yoffset, unsigned long *uoffset,
+ unsigned long *voffset)
+#else
+void gfx_get_display_video_yuv_offsets(unsigned long *yoffset, unsigned long *uoffset,
+ unsigned long *voffset)
+#endif
+{
+ *yoffset = (READ_REG32(DC3_VID_Y_ST_OFFSET) & 0x0FFFFFFF);
+ *uoffset = (READ_REG32(DC3_VID_U_ST_OFFSET) & 0x0FFFFFFF);
+ *voffset = (READ_REG32(DC3_VID_V_ST_OFFSET) & 0x0FFFFFFF);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_yuv_pitch (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_get_video_yuv_pitch". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+void gu3_get_display_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch)
+#else
+void gfx_get_display_video_yuv_pitch(unsigned long *ypitch, unsigned long *uvpitch)
+#endif
+{
+ unsigned long pitch = READ_REG32 (DC3_VID_YUV_PITCH);
+
+ *ypitch = ((pitch & 0xFFFF) << 3);
+ *uvpitch = (pitch >> 13) & 0x7FFF8;
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_size (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_get_video_size". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long gu3_get_display_video_size(void)
+#else
+unsigned long gfx_get_display_video_size(void)
+#endif
+{
+ /* RETURN THE LINE SIZE, AS THIS IS ALL THAT IS AVAILABLE */
+ /* Shift by three less to effect a multiply by 8. */
+
+ return((READ_REG32(DC3_LINE_SIZE) & DC3_LINE_SIZE_VLS_MASK) >> (DC3_LINE_SIZE_VB_SHIFT - 3));
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_color_key (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_get_video_color_key". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long gu3_get_display_video_color_key(void)
+#else
+unsigned long gfx_get_display_video_color_key(void)
+#endif
+{
+ return (READ_REG32 (DC3_COLOR_KEY) & 0xFFFFFF);
+}
+
+/*---------------------------------------------------------------------------
+ * gfx_get_display_video_color_key_mask (PRIVATE ROUTINE - NOT PART OF API)
+ *
+ * This routine is called by "gfx_get_video_color_key_mask". It abstracts the
+ * version of the display controller from the video overlay routines.
+ *---------------------------------------------------------------------------
+ */
+#if GFX_DISPLAY_DYNAMIC
+unsigned long gu3_get_display_video_color_key_mask(void)
+#else
+unsigned long gfx_get_display_video_color_key_mask(void)
+#endif
+{
+ return (READ_REG32 (DC3_COLOR_MASK) & 0xFFFFFF);
+}
+
+#endif /* GFX_READ_ROUTINES */
+
+/* END OF FILE */
diff -urN xf86-video-nsc-2.8.1-orig/src/gfx/init_gu3.c xf86-video-nsc-2.8.1/src/gfx/init_gu3.c
--- xf86-video-nsc-2.8.1-orig/src/gfx/init_gu3.c 1970-01-01 01:00:00.000000000 +0100
+++ xf86-video-nsc-2.8.1/src/gfx/init_gu3.c 2006-07-11 17:00:28.000000000 +0200
@@ -0,0 +1,135 @@
+ /*
+ *
+ *
+ * Copyright (C) Advanced Micro Devices, Inc. All Rights Reserved.
+ *
+ *
+ *
+ *
+ *
+ *
+ * This file contains routines used in Redcloud initialization.
+ *
+ *
+ */
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_core_freq
+ *
+ * Returns the core clock frequency of a GX3.
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long gu3_get_core_freq(void)
+#else
+unsigned long gfx_get_core_freq(void)
+#endif
+{
+ unsigned long value;
+
+ /* CPU SPEED IS REPORTED BY A VSM IN VSA II */
+ /* Virtual Register Class = 0x12 (Sysinfo) */
+ /* CPU Speed Register = 0x01 */
+
+ OUTW (0xAC1C, 0xFC53);
+ OUTW (0xAC1C, 0x1201);
+
+ value = (unsigned long)(INW (0xAC1E));
+
+ return (value);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_cpu_register_base
+ *
+ * This routine returns the base address for display controller registers.
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long gu3_get_cpu_register_base(void)
+#else
+unsigned long gfx_get_cpu_register_base(void)
+#endif
+{
+ return gfx_pci_config_read (0x80000918);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_graphics_register_base
+ *
+ * This routine returns the base address for the graphics acceleration.
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long gu3_get_graphics_register_base(void)
+#else
+unsigned long gfx_get_graphics_register_base(void)
+#endif
+{
+ return gfx_pci_config_read (0x80000914);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_frame_buffer_base
+ *
+ * This routine returns the base address for graphics memory.
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long gu3_get_frame_buffer_base(void)
+#else
+unsigned long gfx_get_frame_buffer_base(void)
+#endif
+{
+ return gfx_pci_config_read (0x80000910);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_frame_buffer_size
+ *
+ * This routine returns the total size of graphics memory, in bytes.
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long gu3_get_frame_buffer_size(void)
+#else
+unsigned long gfx_get_frame_buffer_size(void)
+#endif
+{
+ unsigned long value;
+
+ /* FRAME BUFFER SIZE IS REPORTED BY A VSM IN VSA II */
+ /* Virtual Register Class = 0x02 */
+ /* VG_MEM_SIZE (1MB units) = 0x00 */
+
+ OUTW (0xAC1C, 0xFC53);
+ OUTW (0xAC1C, 0x0200);
+
+ value = (unsigned long)(INW (0xAC1E)) & 0xFEl;
+
+ /* LIMIT FRAME BUFFER SIZE TO 16MB TO MATCH LEGACY */
+
+ if ((value << 20) > 0x1000000)
+ return 0x1000000;
+
+ return (value << 20);
+}
+
+/*-----------------------------------------------------------------------------
+ * gfx_get_vid_register_base
+ *
+ * This routine returns the base address for the video hardware.
+ *-----------------------------------------------------------------------------
+ */
+#if GFX_INIT_DYNAMIC
+unsigned long gu3_get_vid_register_base(void)
+#else
+unsigned long gfx_get_vid_register_base(void)
+#endif
+{
+ return gfx_pci_config_read (0x8000091C);
+}
+
+
+
+/* END OF FILE */
diff -urN xf86-video-nsc-2.8.1-orig/src/nsc.h xf86-video-nsc-2.8.1/src/nsc.h
--- xf86-video-nsc-2.8.1-orig/src/nsc.h 2006-04-07 21:33:01.000000000 +0200
+++ xf86-video-nsc-2.8.1/src/nsc.h 2006-07-11 18:11:59.000000000 +0200
@@ -142,8 +142,7 @@
#ifndef _NSC_GEODE_H_
#define _NSC_GEODE_H_
-#include
-#include
+// #include "config.h"
#include "xaa.h"
#include "xf86Cursor.h"
@@ -171,6 +170,15 @@
#define GEODEPTR(p) ((GeodePtr)((p)->driverPrivate))
+#define DEFAULT_IMG_LINE_BUFS 20
+#define DEFAULT_CLR_LINE_BUFS 20
+/* 64x64 cursor used as 32x32 */
+#define HW_CURSOR_W 64
+#define HW_CURSOR_H 64
+
+#define HW_ARGB_CURSOR_W 48
+#define HW_ARGB_CURSOR_H 64
+
#define DebugPort(_Val) gfx_outb(0x84, (_Val));
#define DEFAULT_NUM_OF_BUF 20 /* default # of buffers */
@@ -220,11 +228,28 @@
extern unsigned long gfx_ind(unsigned short port);
extern void gfx_outd(unsigned short port, unsigned long data);
+/* conflict with cim ... */
+#define Q_WORD QQ_WORD
#include "gfx_rtns.h"
-#include "gfx_defs.h"
-#include "gfx_regs.h"
+#undef Q_WORD
+
#include "panel.h"
+#include "cim_rtns.h"
+
+#define CIM_CMD_BFR_SZ 0x200000L
+#define CIM_CMD_BFR_MIN 0x20000L
+
+typedef struct __CIM_DISPLAYTIMING
+{
+ unsigned short wPitch;
+ unsigned short wBpp;
+
+ VG_DISPLAY_MODE vgDisplayMode;
+}
+CIM_DISPLAYTIMING, *CIM_PDISPLAYTIMING;
+
+
typedef struct __TVPARAMS
{
unsigned int dwFlags;
@@ -287,30 +312,76 @@
}
VESARec, *VESAPtr;
+#define LX 0x20
+#define LX_CRT 0x21
+#define LX_TFT 0x22
+
+/* output enable types */
+#define LX_OT_CRT 0x0001
+#define LX_OT_FP 0x0002
+#define LX_OT_VOP 0x0004
+#define LX_OT_DRGB 0x0008
+
+#define INT10_SUPPORT 1
+
typedef struct
{
/* Private struct for the server */
unsigned long cpu_version; /* [7:0] Type:1=GXLV,2=SC1400 */
- /* [15:8] Major version */
- /* [23:16] Minor version */
+ unsigned long cpu_revision;
unsigned long vid_version; /* [7:0] Type:1=CS5530,2=SC1400 */
+ INIT_BASE_ADDRESSES InitBaseAddress;
EntityInfoPtr pEnt;
ScreenBlockHandlerProcPtr BlockHandler; /* needed for video */
int DetectedChipSet;
int Chipset;
+
+ int cimFd;
+ unsigned long CmdBfrOffset;
+ unsigned long CmdBfrSize;
+ unsigned int EnabledOutput;
+ unsigned long FBTop;
+
unsigned long FBLinearAddr;
unsigned char *FBBase;
+ unsigned long FBAvail;
+ unsigned long FBOffset;
unsigned long FBSize;
unsigned int cpu_reg_size;
unsigned int gp_reg_size;
unsigned int vid_reg_size;
+
+ unsigned int vg_reg_size;
+ unsigned int vip_reg_size;
+
int Pitch;
+ int AccelPitch; /* accel pitch (may be ShadowPitch) */
+
Bool HWCursor;
+#ifdef ARGB_CURSOR
+ Bool cursor_argb;
+#endif
Bool NoAccel;
+ Bool CustomMode;
unsigned long VideoKey;
Bool TVSupport;
+ int tv_encoder;
+ int tv_bus_fmt;
+ int tv_flags;
+ int tv_601_fmt;
+ int tv_601_flags;
+ int tv_conversion;
+ int tv_vsync_shift;
+ int tv_vsync_shift_count;
+ int tv_vsync_select;
+ int tvox, tvoy;
+
+ int FPBiosResX, FPBiosResY;
+ int FPGeomDstSet, FPGeomDstX, FPGeomDstY;
+ int FPGeomActSet, FPGeomActX, FPGeomActY;
+
#if defined(STB_X)
GAL_TVPARAMS TvParam;
#else
@@ -329,14 +400,29 @@
int FPBF; /* freq */
int Rotate;
+ void (*Rotation)(int x,int y,int w,int h,int *newX,int *newY);
+ void (*RBltXlat)(int x,int y,int w,int h,int *newX,int *newY);
+
+
Bool ShadowFB;
unsigned char *ShadowPtr;
+ int ShadowSize;
int ShadowPitch;
+ int ShadowInFBMem;
+
+ int orig_virtX; /* original */
+ int orig_virtY;
+
+ int HDisplay; /* rotated */
+ int VDisplay;
+
void (*PointerMoved) (int index, int x, int y);
/* CloseScreen function. */
CloseScreenProcPtr CloseScreen;
Bool Compression;
+ VG_COMPRESSION_DATA CBData;
+
unsigned int CBOffset;
unsigned int CBPitch;
unsigned int CBSize;
@@ -351,8 +437,12 @@
/***Image Write structures ***/
/* offset in video memory for ImageWrite Buffers */
+ unsigned char **AccelImageWriteBuffers;
unsigned char **AccelImageWriteBufferOffsets;
int NoOfImgBuffers;
+ unsigned char **AccelColorExpandBuffers;
+ int NoOfColorExpandLines;
+
FBAreaPtr CompressionArea;
FBAreaPtr AccelImgArea;
/*****************************************/
@@ -366,21 +456,31 @@
DISPLAYTIMING FBgfxdisplaytiming;
TVTIMING FBtvtiming;
#endif /* STB_X */
+
+ CIM_DISPLAYTIMING FBcimdisplaytiming;
+
int FBVGAActive;
unsigned int FBTVActive;
unsigned int FBTVEnabled;
unsigned long FBDisplayOffset;
+ unsigned long PrevDisplayOffset;
VESAPtr vesa;
/* compression */
int FBCompressionEnable;
+
+ VG_COMPRESSION_DATA FBCBData;
+ VG_CURSOR_DATA FBCursor;
+
unsigned long FBCompressionOffset;
unsigned short FBCompressionPitch;
unsigned short FBCompressionSize;
/* Save the Cursor offset of the FB */
unsigned long FBCursorOffset;
+ unsigned char FBBIOSMode;
+
/*****************************************/
XAAInfoRecPtr AccelInfoRec;
@@ -421,6 +521,12 @@
OPTION_TV_SUPPORT,
OPTION_TV_OUTPUT,
OPTION_TV_OVERSCAN,
+ OPTION_TV_ENCODER,
+ OPTION_TV_BUS_FMT,
+ OPTION_TV_FLAGS,
+ OPTION_TV_601_FLAGS,
+ OPTION_TV_VSYNC_SELECT,
+ OPTION_TV_CONVERSION,
OPTION_SHADOW_FB,
OPTION_ROTATE,
OPTION_FLATPANEL,
@@ -429,7 +535,12 @@
OPTION_COLOR_KEY,
OPTION_OSM,
OPTION_OSM_IMG_BUFS,
- OPTION_DONT_PROGRAM
+ OPTION_OSM_CLR_BUFS,
+ OPTION_DONT_PROGRAM,
+ OPTION_CRTENABLE,
+ OPTION_CUSTOM_MODE,
+ OPTION_FP_DEST_GEOM,
+ OPTION_FP_ACTIVE_GEOM
}
GeodeOpts;
diff -urN xf86-video-nsc-2.8.1-orig/src/nsc_driver.c xf86-video-nsc-2.8.1/src/nsc_driver.c
--- xf86-video-nsc-2.8.1-orig/src/nsc_driver.c 2006-04-08 03:35:55.000000000 +0200
+++ xf86-video-nsc-2.8.1/src/nsc_driver.c 2006-07-11 17:00:28.000000000 +0200
@@ -227,6 +227,7 @@
extern void GX1SetupChipsetFPtr(ScrnInfoPtr pScrn);
extern void GX2SetupChipsetFPtr(ScrnInfoPtr pScrn);
+extern void LXSetupChipsetFPtr(ScrnInfoPtr pScrn);
#if !defined(STB_X)
extern unsigned char *XpressROMPtr;
@@ -251,13 +252,17 @@
#define GX2_CRT 0x6
#define GX2_TFT 0xA
+#define GFX_CPU_GEODELX 4
+
#define PCI_VENDOR_ID_CYRIX 0x1078
#define PCI_VENDOR_ID_NS 0x100B
+#define PCI_VENDOR_ID_AMD 0x1022
#define PCI_CHIP_5530 0x0104
#define PCI_CHIP_SC1200 0x0504
#define PCI_CHIP_SC1400 0x0104
#define PCI_CHIP_REDCLOUD 0x0030
+#define PCI_CHIP_GEODELX 0x2081
/* National Chip Models */
typedef struct _DEVICE_MODEL
@@ -272,6 +277,7 @@
{PCI_CHIP_SC1200, GX1},
{PCI_CHIP_SC1400, GX1},
{PCI_CHIP_REDCLOUD, GX2},
+ {PCI_CHIP_GEODELX, LX},
{-1, 0}
};
@@ -281,6 +287,7 @@
{PCI_CHIP_SC1200, "SC1200"},
{PCI_CHIP_SC1400, "SC1400"},
{PCI_CHIP_REDCLOUD, "REDCLOUD"},
+ {PCI_CHIP_GEODELX, "GeodeLX"},
{-1, NULL}
};
@@ -289,6 +296,7 @@
{PCI_CHIP_SC1200, PCI_CHIP_SC1200, RES_SHARED_VGA},
{PCI_CHIP_SC1400, PCI_CHIP_SC1400, RES_SHARED_VGA},
{PCI_CHIP_REDCLOUD, PCI_CHIP_REDCLOUD, RES_SHARED_VGA},
+ {PCI_CHIP_GEODELX, PCI_CHIP_GEODELX, RES_SHARED_VGA},
{-1, -1, RES_UNDEFINED},
};
@@ -300,11 +308,22 @@
{OPTION_TV_SUPPORT, "TV", OPTV_ANYSTR, {0}, FALSE},
{OPTION_TV_OUTPUT, "TV_Output", OPTV_ANYSTR, {0}, FALSE},
{OPTION_TV_OVERSCAN, "TVOverscan", OPTV_ANYSTR, {0}, FALSE},
+ {OPTION_TV_ENCODER, "TV_Encoder", OPTV_ANYSTR, {0}, FALSE},
+ {OPTION_TV_BUS_FMT, "TV_Bus_Fmt", OPTV_ANYSTR, {0}, FALSE},
+ {OPTION_TV_FLAGS, "TV_Flags", OPTV_ANYSTR, {0}, FALSE},
+ {OPTION_TV_601_FLAGS, "TV_601_Flags", OPTV_ANYSTR, {0}, FALSE},
+ {OPTION_TV_VSYNC_SELECT, "TV_Vsync_Select", OPTV_ANYSTR, {0}, FALSE},
+ {OPTION_TV_CONVERSION, "TV_Conversion", OPTV_ANYSTR, {0}, FALSE},
{OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE},
{OPTION_FLATPANEL, "FlatPanel", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_CRTENABLE, "CrtEnable", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE},
{OPTION_OSM_IMG_BUFS, "OSMImageBuffers", OPTV_INTEGER, {0}, FALSE},
+ {OPTION_OSM_CLR_BUFS, "OSMColorExpBuffers", OPTV_INTEGER, {0}, FALSE},
+ {OPTION_CUSTOM_MODE, "CustomMode", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_FP_DEST_GEOM, "FPDestGeom", OPTV_ANYSTR, {0}, FALSE},
+ {OPTION_FP_ACTIVE_GEOM, "FPActiveGeom", OPTV_ANYSTR, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
@@ -518,10 +537,19 @@
GeodeDebug(("NscProbe: Before MatchPciInstances!\n"));
/* PCI BUS */
if (xf86GetPciVideoInfo()) {
- numUsed = xf86MatchPciInstances(NSC_NAME, PCI_VENDOR_ID_NS,
- GeodeChipsets, GeodePCIchipsets,
- devSections, numDevSections,
- drv, &usedChips);
+ /* current AMD chips */
+ numUsed = xf86MatchPciInstances(NSC_NAME, PCI_VENDOR_ID_AMD,
+ GeodeChipsets, GeodePCIchipsets,
+ devSections, numDevSections,
+ drv, &usedChips);
+ if (numUsed <= 0) {
+ /* Former National chips */
+ numUsed = xf86MatchPciInstances(NSC_NAME, PCI_VENDOR_ID_NS,
+ GeodeChipsets, GeodePCIchipsets,
+ devSections, numDevSections,
+ drv, &usedChips);
+ }
+
if (numUsed <= 0) {
/* Check for old CYRIX vendor ID (5530) */
numUsed = xf86MatchPciInstances(NSC_NAME,
@@ -548,10 +576,19 @@
for (p_id = GeodePCIchipsets; p_id->numChipset != -1; p_id++) {
if (pEnt->chipset == p_id->numChipset) {
- CPUDetected = GX1;
- if (pEnt->chipset == PCI_CHIP_REDCLOUD)
+ switch( pEnt->chipset ) {
+ case PCI_CHIP_REDCLOUD:
CPUDetected = GX2;
- break;
+ GX2SetupChipsetFPtr(pScrn);
+ break;
+ case PCI_CHIP_GEODELX:
+ CPUDetected = LX;
+ LXSetupChipsetFPtr(pScrn);
+ break;
+ default:
+ CPUDetected = GX1;
+ GX1SetupChipsetFPtr(pScrn);
+ }
}
}
xfree(pEnt);
@@ -561,12 +598,6 @@
pScrn->name = NSC_NAME;
pScrn->Probe = NscProbe;
- if (CPUDetected == GX1) {
- GX1SetupChipsetFPtr(pScrn);
- } else { /* GX2 */
- GX2SetupChipsetFPtr(pScrn);
- }
-
foundScreen = TRUE;
xf86ConfigActivePciEntity(pScrn,
usedChips[i],
diff -urN xf86-video-nsc-2.8.1-orig/src/nsc_gx1_accel.c xf86-video-nsc-2.8.1/src/nsc_gx1_accel.c
--- xf86-video-nsc-2.8.1-orig/src/nsc_gx1_accel.c 2006-04-07 21:35:33.000000000 +0200
+++ xf86-video-nsc-2.8.1/src/nsc_gx1_accel.c 2006-07-11 17:00:28.000000000 +0200
@@ -159,6 +159,8 @@
#include "miline.h"
#include "xaarop.h"
#include "nsc.h"
+#include "gfx_defs.h"
+#include "gfx_regs.h"
#define SCR2SCREXP 0
diff -urN xf86-video-nsc-2.8.1-orig/src/nsc_gx1_driver.c xf86-video-nsc-2.8.1/src/nsc_gx1_driver.c
--- xf86-video-nsc-2.8.1-orig/src/nsc_gx1_driver.c 2006-04-04 14:06:57.000000000 +0200
+++ xf86-video-nsc-2.8.1/src/nsc_gx1_driver.c 2006-07-11 17:00:28.000000000 +0200
@@ -198,6 +198,8 @@
/* Our private include file (this also includes the durango headers) */
#include "nsc.h"
+#include "gfx_defs.h"
+#include "gfx_regs.h"
#if GEODE_TRACE
/* ANSI C does not allow var arg macros */
diff -urN xf86-video-nsc-2.8.1-orig/src/nsc_gx2_accel.c xf86-video-nsc-2.8.1/src/nsc_gx2_accel.c
--- xf86-video-nsc-2.8.1-orig/src/nsc_gx2_accel.c 2006-04-07 21:30:55.000000000 +0200
+++ xf86-video-nsc-2.8.1/src/nsc_gx2_accel.c 2006-07-11 17:00:28.000000000 +0200
@@ -153,6 +153,8 @@
#include "miline.h"
#include "xaarop.h"
#include "nsc.h"
+#include "gfx_defs.h"
+#include "gfx_regs.h"
#define DASHED_SUPPORT 0
#define IMGWRITE_SUPPORT 0
diff -urN xf86-video-nsc-2.8.1-orig/src/nsc_gx2_driver.c xf86-video-nsc-2.8.1/src/nsc_gx2_driver.c
--- xf86-video-nsc-2.8.1-orig/src/nsc_gx2_driver.c 2006-04-04 14:06:58.000000000 +0200
+++ xf86-video-nsc-2.8.1/src/nsc_gx2_driver.c 2006-07-11 17:00:28.000000000 +0200
@@ -162,8 +162,6 @@
#include "xf86PciInfo.h"
#include "xf86Pci.h"
-#define INT10_SUPPORT 1
-
/* Colormap handling stuff */
#include "xf86cmap.h"
@@ -196,6 +194,9 @@
/* Our private include file (this also includes the durango headers) */
#include "nsc.h"
+#include "gfx_defs.h"
+#include "gfx_regs.h"
+
#if !defined(STB_X)
#include "nsc_gx2_vga.c"
#endif /* STB_X */
@@ -635,7 +636,7 @@
rgb BitMask = { 0, 0, 0 };
if (pScreenInfo->depth > 16) {
- /* we are operating in 24 bpp, Readcloud */
+ /* we are operating in 24 bpp, Redcloud */
BitsPerComponent.red = 8;
BitsPerComponent.green = 8;
BitsPerComponent.blue = 8;