summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Hourihane <alanh@tungstengraphics.com>2007-03-28 15:11:23 +0100
committerAlan Hourihane <alanh@tungstengraphics.com>2007-03-28 15:11:23 +0100
commit430440787c85eb8b3a8ff2b33b8bd408a72658f0 (patch)
tree7610dd372a1ec2630fc69cbc724afab1bbf515cb
Initial commit of the vermilion driver
-rw-r--r--COPYING12
-rw-r--r--ChangeLog84
-rw-r--r--Makefile.am22
-rwxr-xr-xautogen.sh12
-rw-r--r--configure.ac77
-rw-r--r--man/Makefile.am59
-rw-r--r--man/vermilion.man74
-rw-r--r--src/Makefile.am41
-rw-r--r--src/vermilion.c1415
-rw-r--r--src/vermilion.h223
-rw-r--r--src/vermilion_accel.c255
-rw-r--r--src/vermilion_kernel.h81
-rw-r--r--src/vermilion_mbx.h117
-rw-r--r--src/vermilion_mode.c316
-rw-r--r--src/vermilion_panels.c63
-rw-r--r--src/vermilion_reg.h187
-rw-r--r--src/vermilion_sys.c444
-rw-r--r--src/vermilion_sys.h87
18 files changed, 3569 insertions, 0 deletions
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..7f33cbf
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,12 @@
+This is a stub file. This package has not yet had its complete licensing
+information compiled. Please see the individual source files for details on
+your rights to use and modify this software.
+
+Please submit updated COPYING files to the Xorg bugzilla:
+
+https://bugs.freedesktop.org/enter_bug.cgi?product=xorg
+
+All licensing questions regarding this software should be directed at the
+Xorg mailing list:
+
+http://lists.freedesktop.org/mailman/listinfo/xorg
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..9095e7b
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,84 @@
+2006-04-07 Adam Jackson <ajax@freedesktop.org>
+
+ * configure.ac:
+ * src/nsc_driver.c:
+ Bump to 2.8.1 for Xv changes.
+
+2006-04-07 Aaron Plattner <aplattner@nvidia.com>
+
+ * src/nsc_gx1_video.c: (GX1PutImage):
+ * src/nsc_gx2_video.c: (GX2PutImage):
+ Add a DrawablePtr argument to the XV functions to pave the way for
+ redirected video.
+
+2006-04-07 Adam Jackson <ajax@freedesktop.org>
+
+ * configure.ac:
+ * src/durango.c:
+ * src/nsc.h:
+ * src/nsc_driver.c:
+ * src/nsc_galstub.c:
+ * src/nsc_gx1_accel.c:
+ * src/nsc_gx1_cursor.c:
+ * src/nsc_gx1_dga.c:
+ * src/nsc_gx1_driver.c:
+ * src/nsc_gx1_shadow.c:
+ * src/nsc_gx1_video.c:
+ * src/nsc_gx2_accel.c:
+ * src/nsc_gx2_cursor.c:
+ * src/nsc_gx2_dga.c:
+ * src/nsc_gx2_driver.c:
+ * src/nsc_gx2_shadow.c:
+ * src/nsc_gx2_video.c:
+ Unlibcwrap. Bump server version requirement. Bump to 2.8.0.
+
+2006-02-27 Alan Coopersmith <alan.coopersmith@sun.com>
+
+ * man/nsc.man:
+ Typo fix (Nicholas Joly, XFree86 bugzilla #1658)
+
+2005-12-20 Kevin E. Martin <kem-at-freedesktop-dot-org>
+
+ * configure.ac:
+ Update package version for X11R7 release.
+
+2005-12-14 Kevin E. Martin <kem-at-freedesktop-dot-org>
+
+ * configure.ac:
+ Update package version number for final X11R7 release candidate.
+
+2005-12-06 Kevin E. Martin <kem-at-freedesktop-dot-org>
+
+ * man/Makefile.am:
+ Change *man_SOURCES ==> *man_PRE to fix autotools warnings.
+
+2005-12-03 Kevin E. Martin <kem-at-freedesktop-dot-org>
+
+ * configure.ac:
+ Update package version number for X11R7 RC3 release.
+
+2005-12-01 Kevin E. Martin <kem-at-freedesktop-dot-org>
+
+ * configure.ac:
+ Remove extraneous AC_MSG_RESULT.
+
+2005-11-29 Adam Jackson <ajax@freedesktop.org>
+
+ * configure.ac:
+ Only build dlloader modules by default.
+
+2005-11-15 Kevin E. Martin <kem-at-freedesktop-dot-org>
+
+ * configure.ac:
+ Add check for DGA extension to fix issues when building with
+ separate build roots.
+
+2005-11-09 Kevin E. Martin <kem-at-freedesktop-dot-org>
+
+ * configure.ac:
+ Update package version number for X11R7 RC2 release.
+
+2005-11-01 Kevin E. Martin <kem-at-freedesktop-dot-org>
+
+ * configure.ac:
+ Update pkgcheck dependencies to work with separate build roots.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..7052905
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,22 @@
+# Copyright 2005 Adam Jackson.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# on the rights to use, copy, modify, merge, publish, distribute, sub
+# license, and/or sell copies of the Software, and to permit persons to whom
+# the Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+# ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+AUTOMAKE_OPTIONS = foreign
+SUBDIRS = src man
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..904cd67
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,12 @@
+#! /bin/sh
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd $srcdir
+
+autoreconf -v --install || exit 1
+cd $ORIGDIR || exit $?
+
+$srcdir/configure --enable-maintainer-mode "$@"
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..de5072a
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,77 @@
+# Copyright 2005 Adam Jackson.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# on the rights to use, copy, modify, merge, publish, distribute, sub
+# license, and/or sell copies of the Software, and to permit persons to whom
+# the Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+# ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Process this file with autoconf to produce a configure script
+
+AC_PREREQ(2.57)
+AC_INIT([xf86-video-vermilion],
+ 1.0.0,
+ [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
+ xf86-video-vermilion)
+
+AC_CONFIG_SRCDIR([Makefile.am])
+AM_CONFIG_HEADER([config.h])
+AC_CONFIG_AUX_DIR(.)
+
+AM_INIT_AUTOMAKE([dist-bzip2])
+
+AM_MAINTAINER_MODE
+
+# Checks for programs.
+AC_DISABLE_STATIC
+AC_PROG_LIBTOOL
+AC_PROG_CC
+
+AH_TOP([#include "xorg-server.h"])
+
+AC_ARG_WITH(xorg-module-dir,
+ AC_HELP_STRING([--with-xorg-module-dir=DIR],
+ [Default xorg module directory [[default=$libdir/xorg/modules]]]),
+ [moduledir="$withval"],
+ [moduledir="$libdir/xorg/modules"])
+
+# Checks for extensions
+XORG_DRIVER_CHECK_EXT(RENDER, renderproto)
+XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto)
+XORG_DRIVER_CHECK_EXT(XFreeXDGA, xf86dgaproto)
+
+# Checks for pkg-config packages
+PKG_CHECK_MODULES(XORG, [xorg-server >= 1.0.99.901 xproto fontsproto $REQUIRED_MODULES])
+sdkdir=$(pkg-config --variable=sdkdir xorg-server)
+
+# Checks for libraries.
+
+# Checks for header files.
+AC_HEADER_STDC
+
+AC_SUBST([XORG_CFLAGS])
+AC_SUBST([moduledir])
+
+DRIVER_NAME=vermilion
+AC_SUBST([DRIVER_NAME])
+
+XORG_MANPAGE_SECTIONS
+XORG_RELEASE_VERSION
+
+AC_OUTPUT([
+ Makefile
+ src/Makefile
+ man/Makefile
+])
diff --git a/man/Makefile.am b/man/Makefile.am
new file mode 100644
index 0000000..bf7ec17
--- /dev/null
+++ b/man/Makefile.am
@@ -0,0 +1,59 @@
+# $Id$
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation.
+#
+# 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 OPEN GROUP 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.
+#
+# Except as contained in this notice, the name of the copyright holders shall
+# not be used in advertising or otherwise to promote the sale, use or
+# other dealings in this Software without prior written authorization
+# from the copyright holders.
+#
+
+drivermandir = $(DRIVER_MAN_DIR)
+
+driverman_PRE = @DRIVER_NAME@.man
+
+driverman_DATA = $(driverman_PRE:man=@DRIVER_MAN_SUFFIX@)
+
+EXTRA_DIST = @DRIVER_NAME@.man
+
+CLEANFILES = $(driverman_DATA)
+
+SED = sed
+
+# Strings to replace in man pages
+XORGRELSTRING = @PACKAGE_STRING@
+ XORGMANNAME = X Version 11
+
+MAN_SUBSTS = \
+ -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \
+ -e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \
+ -e 's|__xservername__|Xorg|g' \
+ -e 's|__xconfigfile__|xorg.conf|g' \
+ -e 's|__projectroot__|$(prefix)|g' \
+ -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \
+ -e 's|__drivermansuffix__|$(DRIVER_MAN_SUFFIX)|g' \
+ -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \
+ -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \
+ -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g'
+
+SUFFIXES = .$(DRIVER_MAN_SUFFIX) .man
+
+.man.$(DRIVER_MAN_SUFFIX):
+ sed $(MAN_SUBSTS) < $< > $@
diff --git a/man/vermilion.man b/man/vermilion.man
new file mode 100644
index 0000000..bb99a11
--- /dev/null
+++ b/man/vermilion.man
@@ -0,0 +1,74 @@
+.\" shorthand for double quote that works everywhere.
+.ds q \N'34'
+.TH VERMILION __drivermansuffix__ __vendorversion__
+.SH NAME
+vermilion \- Generic VERMILION video driver
+.SH SYNOPSIS
+.nf
+.B "Section \*qDevice\*q"
+.BI " Identifier \*q" devname \*q
+.B " Driver \*qvermilion\*q"
+\ \ ...
+.B EndSection
+.fi
+.SH DESCRIPTION
+.B vermilion
+is an __xservername__ driver for generic VERMILION video cards. It can drive most
+VERMILION-compatible video cards, but only makes use of the basic standard
+VERMILION core that is common to these cards. The driver supports depths 15
+and 24.
+.SH SUPPORTED HARDWARE
+The
+.B vermilion
+driver supports most VERMILION-compatible video cards. There are some known
+exceptions, and those should be listed here.
+.SH CONFIGURATION DETAILS
+Please refer to __xconfigfile__(__filemansuffix__) for general configuration
+details. This section only covers configuration details specific to this
+driver.
+.PP
+The driver auto-detects the presence of VERMILION-compatible hardware. The
+.B ChipSet
+name may optionally be specified in the config file
+.B \*qDevice\*q
+section, and will override the auto-detection:
+.PP
+.RS 4
+"vermilion"
+.RE
+.PP
+The following driver
+.B Options
+are supported:
+.TP
+.BI "Option \*qShadowFB\*q \*q" boolean \*q
+Enable or disable use of the shadow framebuffer layer. This is currently
+enabled for depth 15 because of hardware restrictions, but disabled for
+depth 24 where the accelerator is used to give higher performance.
+.TP
+.BI "Option \*qPanelType\*q \*q" integer \*q
+Sets the panel timing constraints to the timing of one of the
+pre-programmed panel types, and makes sure that the panel and panel
+backlight are switched on an off as appropriate. If this value is set
+to \*q-1\*q the driver ignores any panel timings and avoids trying to
+manipulate panel and backlight power. The currently supported values are:
+\*q-1\*q; don't assmume any panel timing constraints and
+\*q0\*q, assume that the connected panel is a SHARP LQ150X1LGN2A. Default: \*q0\*q.
+.TP
+.BI "Option \*qFusedClock\*q \*q" integer \*q
+The driver by default supports a set of 9 discrete dotclocks. These
+clocks are: (given as MHz (index)): 6.75(0), 13.5(1), 27.0(2), 29.7(3),
+37.125(4), 54.0(5), 59.4(6), 74.25(7) and 120.0(8). The driver can be
+forced to support only one of these clocks by giving the corresponding
+index as argument to this option. If an index of \*q-1\*q is given,
+the driver will support all of the above clocks. Default: \*q-1\* (All
+clocks supported).
+.TP
+.BI "Option \*qDebug\*q \*q" boolean \*q
+Enable a debug printout of the modesetting registers. Default: false.
+
+.SH "SEE ALSO"
+__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgcfg(__appmansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
+.SH AUTHORS
+Authors include: Michel Danzer <michel-at-tungstengraphics-dot-com>, Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> and Alan Hourihane <alanh-at-tungstengraphics-dot-com>
+.TP
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..37141c3
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,41 @@
+# Copyright 2005 Adam Jackson.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# on the rights to use, copy, modify, merge, publish, distribute, sub
+# license, and/or sell copies of the Software, and to permit persons to whom
+# the Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+# ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+# this is obnoxious:
+# -module lets us name the module exactly how we want
+# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
+# _ladir passes a dummy rpath to libtool so the thing will actually link
+# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
+AM_CFLAGS = @XORG_CFLAGS@
+vermilion_drv_la_LTLIBRARIES = vermilion_drv.la
+vermilion_drv_la_LDFLAGS = -module -avoid-version
+vermilion_drv_ladir = @moduledir@/drivers
+
+vermilion_drv_la_SOURCES = \
+ vermilion.c \
+ vermilion.h \
+ vermilion_accel.c \
+ vermilion_kernel.h \
+ vermilion_mbx.h \
+ vermilion_mode.c \
+ vermilion_panels.c \
+ vermilion_reg.h \
+ vermilion_sys.c \
+ vermilion_sys.h
diff --git a/src/vermilion.c b/src/vermilion.c
new file mode 100644
index 0000000..6686b59
--- /dev/null
+++ b/src/vermilion.c
@@ -0,0 +1,1415 @@
+/**************************************************************************
+ *
+ * Copyright (c) Intel Corp. 2007.
+ * All Rights Reserved.
+ *
+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ * develop this driver.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors:
+ * Michel Dänzer <michel-at-tungstengraphics-dot-com>
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Alan Hourihane <alanh-at-tungstengraphics-dot-com>
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+
+#include "vermilion_kernel.h"
+#include "vermilion.h"
+#include "vermilion_reg.h"
+
+/* All drivers initialising the SW cursor need this */
+#include "mipointer.h"
+
+/* All drivers implementing backing store need this */
+#include "mibstore.h"
+
+/* Colormap handling */
+#include "micmap.h"
+#include "xf86cmap.h"
+
+/* DPMS */
+#define DPMS_SERVER
+#include <X11/extensions/dpms.h>
+#include "xf86Priv.h"
+
+#define KERNELNAME "Vermilion Range"
+#define PROCFB "/proc/fb"
+#define DEVFB "/dev/fb"
+
+/* Mandatory functions */
+static const OptionInfoRec *VERMILIONAvailableOptions(int chipid, int busid);
+static void VERMILIONIdentify(int flags);
+static Bool VERMILIONProbe(DriverPtr drv, int flags);
+static Bool VERMILIONPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool VERMILIONScreenInit(int Index, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool VERMILIONEnterVT(int scrnIndex, int flags);
+static void VERMILIONLeaveVT(int scrnIndex, int flags);
+static Bool VERMILIONCloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool VERMILIONSaveScreen(ScreenPtr pScreen, int mode);
+
+static Bool VERMILIONSwitchMode(int scrnIndex, DisplayModePtr pMode,
+ int flags);
+static Bool VERMILIONSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode);
+static void VERMILIONAdjustFrame(int scrnIndex, int x, int y, int flags);
+static void VERMILIONFreeScreen(int scrnIndex, int flags);
+static void VERMILIONFreeRec(ScrnInfoPtr pScrn);
+
+static void
+VERMILIONDisplayPowerManagementSet(ScrnInfoPtr pScrn, int mode, int flags);
+
+/* locally used functions */
+static Bool VERMILIONMapMem(ScrnInfoPtr pScrn);
+static void VERMILIONUnmapMem(ScrnInfoPtr pScrn);
+static void VERMILIONLoadPalette(ScrnInfoPtr pScrn, int numColors,
+ int *indices, LOCO * colors, VisualPtr pVisual);
+static Bool VERMILIONRestore(ScrnInfoPtr pScrn);
+static Bool VERMILIONSave(ScrnInfoPtr pScrn);
+
+#ifndef makedev
+#define makedev(x,y) ((dev_t)(((x) << 8) | (y)))
+#endif
+
+/*
+ * This contains the functions needed by the server after loading the
+ * driver module. It must be supplied, and gets added the driver list by
+ * the Module Setup funtion in the dynamic case. In the static case a
+ * reference to this is compiled in, and this requires that the name of
+ * this DriverRec be an upper-case version of the driver name.
+ */
+
+_X_EXPORT DriverRec VERMILION = {
+ VERMILION_VERSION,
+ VERMILION_DRIVER_NAME,
+ VERMILIONIdentify,
+ VERMILIONProbe,
+ VERMILIONAvailableOptions,
+ NULL,
+ 0
+};
+
+#define PCI_CHIP_VERMILION 0x5009
+#define PCI_CHIP_VM_MBX 0x5002
+
+enum GenericTypes
+{
+ CHIP_VERMILION
+};
+
+/* Supported chipsets */
+static SymTabRec VERMILIONChipsets[] = {
+ {CHIP_VERMILION, "vermilion"},
+ {-1, NULL}
+};
+
+static PciChipsets VERMILIONPCIchipsets[] = {
+ {CHIP_VERMILION, PCI_CHIP_VERMILION, NULL},
+ {-1, -1, RES_UNDEFINED},
+};
+
+typedef enum
+{
+ OPTION_SHADOWFB,
+ OPTION_ACCEL,
+ OPTION_FUSEDCLOCK,
+ OPTION_PANELTYPE,
+ OPTION_DEBUG
+} VERMILIONOpts;
+
+static const OptionInfoRec VERMILIONOptions[] = {
+ {OPTION_SHADOWFB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_ACCEL, "Accel", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_FUSEDCLOCK, "FusedClock", OPTV_INTEGER, {0}, FALSE},
+ {OPTION_PANELTYPE, "PanelType", OPTV_INTEGER, {0}, FALSE},
+ {OPTION_DEBUG, "Debug", OPTV_BOOLEAN, {0}, FALSE},
+ {-1, NULL, OPTV_NONE, {0}, FALSE}
+};
+
+/*
+ * List of symbols from other modules that this module references. This
+ * list is used to tell the loader that it is OK for symbols here to be
+ * unresolved providing that it hasn't been told that they haven't been
+ * told that they are essential via a call to xf86LoaderReqSymbols() or
+ * xf86LoaderReqSymLists(). The purpose is this is to avoid warnings about
+ * unresolved symbols that are not required.
+ */
+
+static const char *fbSymbols[] = {
+ "fbPictureInit",
+ "fbScreenInit",
+ NULL
+};
+
+static const char *wfbSymbols[] = {
+ "wfbPictureInit",
+ "wfbScreenInit",
+ NULL
+};
+
+static const char *shadowSymbols[] = {
+ "shadowAdd",
+ "shadowAlloc",
+ "shadowInit",
+ "shadowSetup",
+ NULL
+};
+
+static const char *xaaSymbols[] = {
+ "XAACreateInfoRec",
+ "XAADestroyInfoRec",
+ "XAAInit",
+ "XAAGetCopyROP",
+ "XAAGetPatternROP",
+ NULL
+};
+
+static const char *ddcSymbols[] = {
+ "xf86PrintEDID",
+ "xf86SetDDCproperties",
+ NULL
+};
+
+#ifdef XFree86LOADER
+
+/* Module loader interface */
+static MODULESETUPPROTO(vermilionSetup);
+
+static XF86ModuleVersionInfo vermilionVersionRec = {
+ "vermilion",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XORG_VERSION_CURRENT,
+ VERMILION_MAJOR_VERSION, VERMILION_MINOR_VERSION, VERMILION_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV, /* This is a video driver */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0, 0, 0, 0}
+};
+
+/*
+ * This data is accessed by the loader. The name must be the module name
+ * followed by "ModuleData".
+ */
+_X_EXPORT XF86ModuleData vermilionModuleData =
+ { &vermilionVersionRec, vermilionSetup, NULL };
+
+static pointer
+vermilionSetup(pointer Module, pointer Options, int *ErrorMajor,
+ int *ErrorMinor)
+{
+ static Bool Initialised = FALSE;
+
+ if (!Initialised) {
+ Initialised = TRUE;
+ xf86AddDriver(&VERMILION, Module, 0);
+ LoaderRefSymLists(fbSymbols, wfbSymbols, ddcSymbols, shadowSymbols, xaaSymbols,
+ NULL);
+ return (pointer) TRUE;
+ }
+
+ if (ErrorMajor)
+ *ErrorMajor = LDR_ONCEONLY;
+ return (NULL);
+}
+
+#endif
+
+static const OptionInfoRec *
+VERMILIONAvailableOptions(int chipid, int busid)
+{
+ return (VERMILIONOptions);
+}
+
+static void
+VERMILIONIdentify(int flags)
+{
+ xf86PrintChipsets(VERMILION_NAME, "driver for VERMILION chipsets",
+ VERMILIONChipsets);
+}
+
+/*
+ * This function is called once, at the start of the first server generation to
+ * do a minimal probe for supported hardware.
+ */
+
+static Bool
+VERMILIONProbe(DriverPtr drv, int flags)
+{
+ Bool foundScreen = FALSE;
+ int numDevSections, numUsed;
+ GDevPtr *devSections;
+ int *usedChips;
+ int i;
+
+ /*
+ * Find the config file Device sections that match this
+ * driver, and return if there are none.
+ */
+ if ((numDevSections = xf86MatchDevice(VERMILION_NAME, &devSections)) <= 0)
+ return (FALSE);
+
+ /* PCI BUS */
+ if (xf86GetPciVideoInfo()) {
+ numUsed = xf86MatchPciInstances(VERMILION_NAME, PCI_VENDOR_INTEL,
+ VERMILIONChipsets, VERMILIONPCIchipsets,
+ devSections, numDevSections, drv, &usedChips);
+ if (numUsed > 0) {
+ if (flags & PROBE_DETECT)
+ foundScreen = TRUE;
+ else {
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn = NULL;
+
+ /* Allocate a ScrnInfoRec */
+ if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
+ VERMILIONPCIchipsets, NULL,
+ NULL, NULL, NULL, NULL))) {
+ pScrn->driverVersion = VERMILION_VERSION;
+ pScrn->driverName = VERMILION_DRIVER_NAME;
+ pScrn->name = VERMILION_NAME;
+ pScrn->Probe = VERMILIONProbe;
+ pScrn->PreInit = VERMILIONPreInit;
+ pScrn->ScreenInit = VERMILIONScreenInit;
+ pScrn->SwitchMode = VERMILIONSwitchMode;
+ pScrn->AdjustFrame = VERMILIONAdjustFrame;
+ pScrn->EnterVT = VERMILIONEnterVT;
+ pScrn->LeaveVT = VERMILIONLeaveVT;
+ pScrn->FreeScreen = VERMILIONFreeScreen;
+ pScrn->ValidMode = VERMILIONValidMode;
+ foundScreen = TRUE;
+ }
+ }
+ }
+ xfree(usedChips);
+ }
+ }
+
+ xfree(devSections);
+
+ return (foundScreen);
+}
+
+static VERMILIONPtr
+VERMILIONGetRec(ScrnInfoPtr pScrn)
+{
+ if (!pScrn->driverPrivate)
+ pScrn->driverPrivate = xcalloc(sizeof(VERMILIONRec), 1);
+
+ return ((VERMILIONPtr) pScrn->driverPrivate);
+}
+
+static void
+VERMILIONFreeRec(ScrnInfoPtr pScrn)
+{
+ VERMILIONPtr pVermilion = VERMILIONGetRec(pScrn);
+
+ xfree(pVermilion->monitor);
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+void *
+VERMILIONMapPciVideo(ScrnInfoPtr pScrn, char *deviceType,
+ PCITAG tag,
+ unsigned long offset, unsigned long size, char type, int mapType)
+{
+ void *ptr;
+
+ if (type) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s device had incorrect pci "
+ "resource type %d\n", deviceType, (int)type);
+ return NULL;
+ }
+
+ ptr = xf86MapPciMem(pScrn->scrnIndex, mapType, tag, offset, size);
+ if (ptr) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Mapped %s memory at "
+ "offset 0x%08lx size %lu\n", deviceType, offset, size);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not map %s memory at "
+ "offset 0x%08lx size %lu\n", deviceType, offset, size);
+ }
+ return ptr;
+
+}
+
+static int
+VERMILIONKernelOpen(ScrnInfoPtr pScrn)
+{
+#define PROCBUFSIZE 100
+
+ FILE *proc;
+ char buffer[PROCBUFSIZE];
+ Bool found = FALSE;
+ char *eptr;
+ int device;
+ int ret = -1;
+
+ proc = fopen(PROCFB, "r");
+
+ if (proc == NULL)
+ goto out;
+
+ while (!feof(proc)) {
+ fgets(buffer, PROCBUFSIZE, proc);
+ if (strstr(buffer, KERNELNAME) == NULL)
+ continue;
+ found = TRUE;
+ break;
+ }
+
+ if (!found)
+ goto out;
+
+ device = strtol(buffer, &eptr, 10);
+ if (buffer == eptr)
+ goto out;
+
+ ret = snprintf(buffer, PROCBUFSIZE, "%s%d", DEVFB, device);
+ if (ret < 0 || ret >= PROCBUFSIZE) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = open(buffer, O_RDWR);
+ if (ret < 0) {
+ /* If we can't get /dev/fbX, then try /dev/fb/X */
+ ret = snprintf(buffer, PROCBUFSIZE, "%s/%d", DEVFB, device);
+ if (ret < 0 || ret >= PROCBUFSIZE) {
+ ret = -1;
+ goto out;
+ }
+ ret = open(buffer, O_RDWR);
+ }
+
+ out:
+ fclose(proc);
+ return ret;
+}
+
+void
+VERMILIONUnmap(void *virtual)
+{
+}
+
+static Bool
+VERMILIONPreInitAccel(ScrnInfoPtr pScrn)
+{
+ VERMILIONPtr pVermilion = VERMILIONGetRec(pScrn);
+ MessageType from;
+
+ from =
+ xf86GetOptValBool(pVermilion->Options, OPTION_ACCEL,
+ &pVermilion->accelOn)
+ ? X_CONFIG : X_DEFAULT;
+
+ if (pVermilion->accelOn) {
+ if (!xf86LoadSubModule(pScrn, "xaa"))
+ return FALSE;
+
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Acceleration %sabled\n",
+ pVermilion->accelOn ? "en" : "dis");
+
+ return TRUE;
+}
+
+static Bool
+VERMILIONPreInitShadowFB(ScrnInfoPtr pScrn)
+{
+ VERMILIONPtr pVermilion = VERMILIONGetRec(pScrn);
+ MessageType from;
+
+ from =
+ xf86GetOptValBool(pVermilion->Options, OPTION_SHADOWFB,
+ &pVermilion->shadowFB)
+ ? X_CONFIG : X_DEFAULT;
+
+ if (pVermilion->shadowFB) {
+ if (!xf86LoadSubModule(pScrn, "shadow"))
+ return FALSE;
+
+ xf86LoaderReqSymLists(shadowSymbols, NULL);
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Shadow framebuffer %sabled\n",
+ pVermilion->shadowFB ? "en" : "dis");
+
+ return TRUE;
+}
+
+static int
+VERMILIONAllocInstance(ScrnInfoPtr pScrn)
+{
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+
+ int ret;
+ vml_init_t arg;
+ vml_init_req_t *req = &arg.req;
+ vml_init_rep_t *rep = &arg.rep;
+
+ req->major = VML_KI_MAJOR;
+ req->minor = VML_KI_MINOR;
+ req->pipe = 0;
+ req->vdc_tag.bus = pVermilion->pciInfo->bus;
+ req->vdc_tag.slot = pVermilion->pciInfo->device;
+ req->vdc_tag.function = pVermilion->pciInfo->func;
+
+ ret = ioctl(pVermilion->fbFD, VML_INIT_DEVICE, &arg);
+
+ if (!ret) {
+ pVermilion->fbSize = rep->vram_contig_size;
+ pScrn->memPhysBase = rep->vram_offset;
+ pVermilion->kernelmbx = pciTag(rep->gpu_tag.bus,
+ rep->gpu_tag.slot, rep->gpu_tag.function);
+ ErrorF("AllocInstance 0x%08lx %ld\n", pScrn->memPhysBase, pVermilion->fbSize);
+ }
+
+ return ret;
+}
+
+/*
+ * This function is called once for each screen at the start of the first
+ * server generation to initialise the screen for all server generations.
+ */
+static Bool
+VERMILIONPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ VERMILIONPtr pVermilion;
+ VERMILIONSys *sys;
+ DisplayModePtr pMode;
+ Gamma gzeros = { 0.0, 0.0, 0.0 };
+ rgb rzeros = { 0, 0, 0 };
+ pointer pDDCModule;
+ int i;
+ int ret;
+ int mbxCount;
+ MessageType from;
+ unsigned ssVendor, ssDevice;
+ const char *ssName, *fbmod, **fbsym;
+
+ ClockRangePtr clockRanges;
+
+ if (flags & PROBE_DETECT)
+ return (FALSE);
+
+ pVermilion = VERMILIONGetRec(pScrn);
+ pVermilion->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+
+ if (pVermilion->pEnt->location.type == BUS_PCI) {
+ pVermilion->pciInfo =
+ xf86GetPciInfoForEntity(pVermilion->pEnt->index);
+ pVermilion->pciTag =
+ pciTag(pVermilion->pciInfo->bus, pVermilion->pciInfo->device,
+ pVermilion->pciInfo->func);
+ }
+
+ pVermilion->fbFD = VERMILIONKernelOpen(pScrn);
+
+ if (pVermilion->fbFD < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to open the %s kernel fb driver. Make sure it is loaded.\n",
+ KERNELNAME);
+ return FALSE;
+ }
+
+ ret = VERMILIONAllocInstance(pScrn);
+
+ if (ret) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to allocate a vermilion device: %s. Check kernel output.\n",
+ strerror(errno));
+ return FALSE;
+ }
+
+ pVermilion->sys = sys = VERMILIONCreateSys(pScrn);
+ if (!sys) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to determine system type.\n");
+ return FALSE;
+ }
+ sys->subSys(sys, &ssName, &ssVendor, &ssDevice);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Subsystem Vendor 0x%04x Device 0x%04x.\n", ssVendor, ssDevice);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "This is a %s board.\n", ssName);
+
+ pVermilion->device = xf86GetDevFromEntity(pScrn->entityList[0],
+ pScrn->entityInstanceList[0]);
+
+ mbxCount = 0;
+ do {
+ pVermilion->mbx = xf86FindPciDeviceVendor(PCI_VENDOR_INTEL,
+ PCI_CHIP_VM_MBX, mbxCount, NULL);
+
+ /*
+ * Check that the mbx device is the one the kernel allocated for us.
+ */
+
+ if (pVermilion->mbx &&
+ pciTag(pVermilion->mbx->bus,
+ pVermilion->mbx->device,
+ pVermilion->mbx->func) == pVermilion->kernelmbx)
+ break;
+
+ mbxCount++;
+ } while (pVermilion->mbx);
+
+ if (!pVermilion->mbx) {
+ ErrorF("Could not find MBX device\n");
+ return FALSE;
+ }
+
+ if (!xf86SetDepthBpp(pScrn, 15, 0, 0, Support32bppFb)) {
+ return (FALSE);
+ }
+ if (pScrn->depth != 15 && pScrn->depth != 24) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Invalid depth %d, only 15 and 24 supported\n", pScrn->depth);
+ return (FALSE);
+ }
+ xf86PrintDepthBpp(pScrn);
+
+ if (pScrn->depth == 15) {
+ fbmod = "wfb";
+ fbsym = wfbSymbols;
+ } else {
+ fbmod = "fb";
+ fbsym = fbSymbols;
+ }
+
+ /* Load (w)fb module */
+ if (!xf86LoadSubModule(pScrn, fbmod))
+ return (FALSE);
+
+ xf86LoaderReqSymLists(fbsym, NULL);
+
+ pScrn->chipset = "vermilion";
+ pScrn->monitor = pScrn->confScreen->monitor;
+ pScrn->rgbBits = 8;
+ pScrn->videoRam = pVermilion->fbSize / 1024;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Linear framebuffer at 0x%lX\n",
+ (unsigned long)pScrn->memPhysBase);
+
+ if (xf86RegisterResources(pVermilion->pEnt->index, NULL, ResExclusive)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86RegisterResources() found resource conflicts\n");
+ return FALSE;
+ }
+
+ /* color weight */
+ if (!xf86SetWeight(pScrn, rzeros, rzeros)) {
+ return (FALSE);
+ }
+ /* visual init */
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return (FALSE);
+ }
+
+ /* We can't do this until we have a
+ * pScrn->display. */
+ xf86CollectOptions(pScrn, NULL);
+ if (!(pVermilion->Options = xalloc(sizeof(VERMILIONOptions))))
+ return (FALSE);
+
+ memcpy(pVermilion->Options, VERMILIONOptions, sizeof(VERMILIONOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pVermilion->Options);
+
+ pVermilion->shadowFB = FALSE;
+ pVermilion->accelOn = TRUE;
+
+ if (!VERMILIONPreInitShadowFB(pScrn))
+ return (FALSE);
+
+ if (!pVermilion->shadowFB && !VERMILIONPreInitAccel(pScrn))
+ return (FALSE);
+
+ /*
+ * Check panel option.
+ */
+
+ pVermilion->panel = sys->panel(sys);
+ from = xf86GetOptValInteger(pVermilion->Options, OPTION_PANELTYPE,
+ &pVermilion->panel)
+ ? X_CONFIG : X_DEFAULT;
+
+ if (pVermilion->panel >= VERMILIONNumPanels) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unknown panel type %d\n", pVermilion->panel);
+ return FALSE;
+ }
+ pVermilion->usePanel = (pVermilion->panel >= 0);
+ if (pVermilion->usePanel) {
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Using panel type %d, which is a %s.\n",
+ pVermilion->panel, VERMILIONPanels[pVermilion->panel]->name);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, from, "Not using panel\n");
+ }
+
+ pScrn->progClock = sys->progClock(sys);
+
+ if (!pScrn->progClock)
+ sys->clocks(sys, &pScrn->numClocks, pScrn->clock);
+
+ pVermilion->fusedClockIndex = -1;
+ from = xf86GetOptValInteger(pVermilion->Options, OPTION_FUSEDCLOCK,
+ &pVermilion->fusedClockIndex)
+ ? X_CONFIG : X_DEFAULT;
+
+ if (pVermilion->panel >= pScrn->numClocks) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unknown fused clock index %d\n", pVermilion->fusedClockIndex);
+ return FALSE;
+ }
+ pVermilion->fusedClock = (pVermilion->fusedClockIndex >= 0);
+ if (pVermilion->fusedClock) {
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Fused dotclock index %d which is %d kHz.\n",
+ pVermilion->fusedClockIndex,
+ pScrn->clock[pVermilion->fusedClockIndex]);
+ }
+
+ pVermilion->debug = FALSE;
+ from =
+ xf86GetOptValBool(pVermilion->Options, OPTION_DEBUG,
+ &pVermilion->debug)
+ ? X_CONFIG : X_DEFAULT;
+
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Modesetting debugging printout is %sabled.\n",
+ pVermilion->debug ? "en" : "dis");
+
+ xf86SetGamma(pScrn, gzeros);
+
+ /* Load ddc module */
+ if ((pDDCModule = xf86LoadSubModule(pScrn, "ddc")) == NULL) {
+#if 0
+ if ((pVermilion->monitor =
+ vbeDoEDID(pVermilion->pVbe, pDDCModule)) != NULL) {
+ xf86PrintEDID(pVermilion->monitor);
+ }
+#endif
+ xf86UnloadSubModule(pDDCModule);
+ }
+
+ if ((pScrn->monitor->DDC = pVermilion->monitor) != NULL)
+ xf86SetDDCproperties(pScrn, pVermilion->monitor);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Searching for matching VERMILION mode(s):\n");
+
+ clockRanges = xnfcalloc(sizeof(ClockRange), 1);
+ clockRanges->next = NULL;
+ sys->clockRanges(sys, &clockRanges->minClock, &clockRanges->maxClock);
+ clockRanges->clockIndex = -1;
+ clockRanges->interlaceAllowed = FALSE;
+ clockRanges->doubleScanAllowed = FALSE;
+ pVermilion->cpp = pScrn->bitsPerPixel >> 3;
+ pScrn->xInc = 1;
+
+ if (pVermilion->fusedClock) {
+ pScrn->clock[0] = pScrn->clock[pVermilion->fusedClockIndex];
+ pScrn->numClocks = 1;
+ }
+
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes,
+ clockRanges, NULL, 0, 2048, 64 << 3, 0, 2048,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY, pScrn->videoRam * 1024,
+ pVermilion->usePanel ? LOOKUP_CLOSEST_CLOCK : LOOKUP_BEST_REFRESH);
+
+ if (i <= 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes\n");
+ return (FALSE);
+ }
+
+ pVermilion->stride = pVermilion->cpp * pScrn->displayWidth;
+ xf86PruneDriverModes(pScrn);
+
+ pMode = pScrn->modes;
+ pScrn->currentMode = pScrn->modes;
+ xf86PrintModes(pScrn);
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+
+ if (pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes\n");
+ return (FALSE);
+ }
+
+ return (TRUE);
+}
+
+void
+VERMILIONUpdatePackedDepth15(ScreenPtr pScreen, shadowBufPtr pBuf)
+{
+ RegionPtr damage = &pBuf->damage;
+ PixmapPtr pShadow = pBuf->pPixmap;
+ int nbox = REGION_NUM_RECTS(damage);
+ BoxPtr pbox = REGION_RECTS(damage);
+ FbBits *shaBase, *shaLine, *sha;
+ FbStride shaStride;
+ int scrBase, scrLine, scr;
+ int shaBpp;
+ int shaXoff, shaYoff; /* XXX assumed to be zero */
+ int x, y, w, h, width;
+ int i;
+ FbBits *winBase = NULL, *win;
+ CARD32 winSize;
+
+ fbGetDrawable(&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff,
+ shaYoff);
+ while (nbox--) {
+ x = pbox->x1 * shaBpp;
+ y = pbox->y1;
+ w = (pbox->x2 - pbox->x1) * shaBpp;
+ h = pbox->y2 - pbox->y1;
+
+ scrLine = (x >> FB_SHIFT);
+ shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
+
+ x &= FB_MASK;
+ w = (w + x + FB_MASK) >> FB_SHIFT;
+
+ while (h--) {
+ winSize = 0;
+ scrBase = 0;
+ width = w;
+ scr = scrLine;
+ sha = shaLine;
+ while (width) {
+ /* how much remains in this window */
+ i = scrBase + winSize - scr;
+ if (i <= 0 || scr < scrBase) {
+ winBase = (FbBits *) (*pBuf->window) (pScreen,
+ y,
+ scr * sizeof(FbBits),
+ SHADOW_WINDOW_WRITE, &winSize, pBuf->closure);
+ if (!winBase)
+ return;
+ scrBase = scr;
+ winSize /= sizeof(FbBits);
+ i = winSize;
+ }
+ win = winBase + (scr - scrBase);
+ if (i > width)
+ i = width;
+ width -= i;
+ scr += i;
+ /* Here we set the high bit on upload for depth 15 because
+ * the hardware requires it. - AlanH.
+ */
+ while (i--)
+ *win++ = 0x80008000 | *sha++;
+ }
+ shaLine += shaStride;
+ y++;
+ }
+ pbox++;
+ }
+}
+
+void
+VERMILIONUpdatePackedDepth24(ScreenPtr pScreen, shadowBufPtr pBuf)
+{
+ RegionPtr damage = &pBuf->damage;
+ PixmapPtr pShadow = pBuf->pPixmap;
+ int nbox = REGION_NUM_RECTS(damage);
+ BoxPtr pbox = REGION_RECTS(damage);
+ FbBits *shaBase, *shaLine, *sha;
+ FbStride shaStride;
+ int scrBase, scrLine, scr;
+ int shaBpp;
+ int shaXoff, shaYoff; /* XXX assumed to be zero */
+ int x, y, w, h, width;
+ int i;
+ FbBits *winBase = NULL, *win;
+ CARD32 winSize;
+
+ fbGetDrawable(&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff,
+ shaYoff);
+ while (nbox--) {
+ x = pbox->x1 * shaBpp;
+ y = pbox->y1;
+ w = (pbox->x2 - pbox->x1) * shaBpp;
+ h = pbox->y2 - pbox->y1;
+
+ scrLine = (x >> FB_SHIFT);
+ shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
+
+ x &= FB_MASK;
+ w = (w + x + FB_MASK) >> FB_SHIFT;
+
+ while (h--) {
+ winSize = 0;
+ scrBase = 0;
+ width = w;
+ scr = scrLine;
+ sha = shaLine;
+ while (width) {
+ /* how much remains in this window */
+ i = scrBase + winSize - scr;
+ if (i <= 0 || scr < scrBase) {
+ winBase = (FbBits *) (*pBuf->window) (pScreen,
+ y,
+ scr * sizeof(FbBits),
+ SHADOW_WINDOW_WRITE, &winSize, pBuf->closure);
+ if (!winBase)
+ return;
+ scrBase = scr;
+ winSize /= sizeof(FbBits);
+ i = winSize;
+ }
+ win = winBase + (scr - scrBase);
+ if (i > width)
+ i = width;
+ width -= i;
+ scr += i;
+ while (i--)
+ *win++ = *sha++;
+ }
+ shaLine += shaStride;
+ y++;
+ }
+ pbox++;
+ }
+}
+
+static void *
+VERMILIONWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode,
+ CARD32 * size, void *closure)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VERMILIONPtr pVermilion = VERMILIONGetRec(pScrn);
+
+ if (!pScrn->vtSema)
+ return NULL;
+
+ *size = pVermilion->stride;
+
+ return ((CARD8 *) pVermilion->fbMap + row * (*size) + offset);
+}
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+#error VERMILIONReadMemory and VERMILIONWriteMemory only work on little endian
+#endif
+
+static FbBits
+VERMILIONReadMemory(const void *src, int size)
+{
+ FbBits bits = 0;
+
+ memcpy(&bits, src, size);
+
+ return bits;
+}
+
+static void
+VERMILIONWriteMemoryPassthru(void *dst, FbBits value, int size)
+{
+ memcpy(dst, &value, size);
+}
+
+static void
+VERMILIONWriteMemorySetAlpha(void *dst, FbBits value, int size)
+{
+ switch (size) {
+ case 4:
+ value |= 0x80008000;
+ break;
+ case 3:
+ case 2:
+ value |= 0x8000;
+ case 1:
+ break;
+ default:
+ FatalError("Unsupported size %d in %s", size, __func__);
+ }
+
+ memcpy(dst, &value, size);
+}
+
+static void
+VERMILIONSetupWrap(ReadMemoryProcPtr *pRead, WriteMemoryProcPtr *pWrite,
+ DrawablePtr pDraw)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pDraw->pScreen->myNum];
+ VERMILIONPtr pVermilion = VERMILIONGetRec(pScrn);
+ PixmapPtr pPixmap;
+
+ if (pDraw->type == DRAWABLE_WINDOW)
+ pPixmap = pScreen->GetWindowPixmap((WindowPtr)pDraw);
+ else
+ pPixmap = (PixmapPtr)pDraw;
+
+ if (pScrn->depth == 15 && pPixmap->devPrivate.ptr >= pVermilion->fbMap &&
+ (char*)pPixmap->devPrivate.ptr < ((char*)pVermilion->fbMap +
+ pVermilion->fbSize)) {
+ *pWrite = VERMILIONWriteMemorySetAlpha;
+ } else {
+ *pWrite = VERMILIONWriteMemoryPassthru;
+ }
+
+ *pRead = VERMILIONReadMemory;
+}
+
+static void
+VERMILIONFinishWrap(DrawablePtr pDraw)
+{
+}
+
+static Bool
+VERMILIONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ VERMILIONPtr pVermilion = VERMILIONGetRec(pScrn);
+ VisualPtr visual;
+ int flags;
+ char *fbstart;
+ VERMILIONSys *sys = pVermilion->sys;
+
+ if (!VERMILIONMapMem(pScrn)) {
+ return (FALSE);
+ }
+
+ /* save current video state */
+ VERMILIONSave(pScrn);
+
+ /* set the viewport */
+ VERMILIONAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ /* Clear framebuffer contents before setting initial mode to prevent garbage
+ * or even screen contents from a previous session from being visible.
+ */
+
+ if (pScrn->bitsPerPixel == 32) {
+ memset(pVermilion->fbMap, 0, pScrn->virtualY * pVermilion->stride);
+ } else {
+ /* For 16 bpp, make sure the alpha bit is set. Gets trashed later on
+ * unfortunately.
+ */
+ int y = pScrn->virtualY;
+
+ while (y--) {
+ int x;
+ CARD32 *pixels = (CARD32 *) ((char *)pVermilion->fbMap +
+ y * pVermilion->stride);
+
+ for (x = pScrn->virtualX; x; x -= 2, pixels++)
+ *pixels = 0x80008000;
+ }
+ }
+
+ if (pVermilion->usePanel) {
+ sys->panelOn(sys);
+ }
+
+ /* set first video mode */
+ if (!VERMILIONSetMode(pScrn, pScrn->currentMode))
+ return (FALSE);
+
+ /* Blank the screen for aesthetic reasons. */
+ VERMILIONSaveScreen(pScreen, SCREEN_SAVER_ON);
+
+ /* mi layer */
+ miClearVisualTypes();
+ if (!xf86SetDefaultVisual(pScrn, -1))
+ return (FALSE);
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
+ pScrn->rgbBits, TrueColor))
+ return (FALSE);
+ if (!miSetPixmapDepths())
+ return (FALSE);
+
+ /* shadowfb */
+ if (pVermilion->shadowFB) {
+ if ((pVermilion->shadowmem =
+ shadowAlloc(pScrn->displayWidth, pScrn->virtualY,
+ pScrn->bitsPerPixel)) == NULL) {
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Allocation of shadow memory failed\n");
+ return FALSE;
+ }
+ fbstart = pVermilion->shadowmem;
+ } else {
+ fbstart = pVermilion->fbMap;
+ }
+
+ if (!(pScrn->depth == 15 ?
+ wfbScreenInit(pScreen, fbstart, pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
+ pScrn->bitsPerPixel, VERMILIONSetupWrap,
+ VERMILIONFinishWrap) :
+ fbScreenInit(pScreen, fbstart, pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
+ pScrn->bitsPerPixel)))
+ return (FALSE);
+
+ /* Fixup RGB ordering */
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+
+ /* must be after RGB ordering fixed */
+ if (pScrn->depth == 15)
+ wfbPictureInit(pScreen, 0, 0);
+ else
+ fbPictureInit(pScreen, 0, 0);
+
+ if (pVermilion->shadowFB &&
+ (!shadowSetup(pScreen) || !shadowAdd(pScreen, NULL,
+ pScrn->depth ==
+ 15 ? VERMILIONUpdatePackedDepth15 :
+ VERMILIONUpdatePackedDepth24, VERMILIONWindowLinear, 0,
+ NULL))) {
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Shadow framebuffer initialization failed.\n");
+ return FALSE;
+ }
+
+ xf86SetBlackWhitePixels(pScreen);
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ /* Enable acceleration */
+ if (!pVermilion->shadowFB && pVermilion->accelOn) {
+ if (!VERMILIONAccelInit(pScreen)) {
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Acceleration initialization failed\n");
+ pVermilion->accelOn = FALSE;
+ }
+ }
+
+ /* software cursor */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ /* colormap */
+ if (!miCreateDefColormap(pScreen))
+ return (FALSE);
+
+ flags = CMAP_RELOAD_ON_MODE_SWITCH;
+
+ if (!xf86HandleColormaps(pScreen, 256, 8,
+ VERMILIONLoadPalette, NULL, flags))
+ return (FALSE);
+
+ pVermilion->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = VERMILIONCloseScreen;
+ pScreen->SaveScreen = VERMILIONSaveScreen;
+
+ xf86DPMSInit(pScreen, VERMILIONDisplayPowerManagementSet, 0);
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1)
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+
+ return (TRUE);
+}
+
+static Bool
+VERMILIONEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+ VERMILIONSys *sys = pVermilion->sys;
+
+ VERMILIONAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ if (!VERMILIONSetMode(pScrn, pScrn->currentMode))
+ return FALSE;
+
+ /* Power up the panel */
+ if (pVermilion->usePanel) {
+ sys->panelOn(sys);
+ }
+
+ return TRUE;
+}
+
+static void
+VERMILIONLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+
+ if (pVermilion->accel)
+ (*pVermilion->accel->Sync) (pScrn);
+
+ /* clear the framebuffer when we switch */
+ memset(pVermilion->fbMap, 0, pScrn->virtualY * pVermilion->stride);
+
+ VERMILIONDisablePipe(pScrn);
+ VERMILIONRestore(pScrn);
+
+ pScrn->vtSema = FALSE;
+}
+
+static Bool
+VERMILIONCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+
+ if (pVermilion->accel) {
+ (*pVermilion->accel->Sync) (pScrn);
+ XAADestroyInfoRec(pVermilion->accel);
+ pVermilion->accel = NULL;
+ }
+
+ if (pScrn->vtSema) {
+ VERMILIONDisablePipe(pScrn);
+ VERMILIONRestore(pScrn);
+ VERMILIONUnmapMem(pScrn);
+ }
+ pScrn->vtSema = FALSE;
+
+ pScreen->CloseScreen = pVermilion->CloseScreen;
+ return pScreen->CloseScreen(scrnIndex, pScreen);
+}
+
+static Bool
+VERMILIONSwitchMode(int scrnIndex, DisplayModePtr pMode, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+
+ if (pVermilion->accel)
+ (*pVermilion->accel->Sync) (pScrn);
+
+ return VERMILIONSetMode(xf86Screens[scrnIndex], pMode);
+}
+
+/* Set a graphics mode */
+static Bool
+VERMILIONSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
+{
+ pScrn->vtSema = VERMILIONDoSetMode(pScrn, pMode, 1);
+ return pScrn->vtSema;
+}
+
+static void
+VERMILIONAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+
+ VERMILIONSetGraphicsOffset(pScrn, x, y);
+ pVermilion->x = x;
+ pVermilion->y = y;
+}
+
+static void
+VERMILIONFreeScreen(int scrnIndex, int flags)
+{
+ VERMILIONFreeRec(xf86Screens[scrnIndex]);
+}
+
+static Bool
+VERMILIONMapMem(ScrnInfoPtr pScrn)
+{
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+
+ if (pVermilion->fbMap != NULL)
+ return (TRUE);
+
+ pVermilion->mbxRegsBase = NULL;
+ pVermilion->vdcRegsBase = NULL;
+
+ pVermilion->fbMap = mmap(NULL, pVermilion->fbSize, PROT_READ | PROT_WRITE,
+ MAP_SHARED, pVermilion->fbFD, 0);
+
+ if (!pVermilion->fbMap || pVermilion->fbMap == MAP_FAILED) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to map video memory\n");
+ return FALSE;
+ }
+
+ pVermilion->mbxSize = 1 << pVermilion->mbx->size[0];
+ pVermilion->mbxRegsBase = VERMILIONMapPciVideo(pScrn, "MBX",
+ pciTag(pVermilion->mbx->bus,
+ pVermilion->mbx->device,
+ pVermilion->mbx->func),
+ pVermilion->mbx->memBase[0],
+ pVermilion->mbxSize, pVermilion->mbx->type[0], VIDMEM_MMIO);
+
+ if (!pVermilion->mbxRegsBase) {
+ VERMILIONUnmapMem(pScrn);
+ return FALSE;
+ }
+
+ pVermilion->vdcSize = 1 << pVermilion->pciInfo->size[0];
+ pVermilion->vdcRegsBase = VERMILIONMapPciVideo(pScrn, "Video Controller",
+ pVermilion->pciTag,
+ pVermilion->pciInfo->memBase[0],
+ pVermilion->vdcSize, pVermilion->pciInfo->type[0], VIDMEM_MMIO);
+
+ if (!pVermilion->vdcRegsBase) {
+ VERMILIONUnmapMem(pScrn);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+VERMILIONUnmapMem(ScrnInfoPtr pScrn)
+{
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+
+ if (pVermilion->fbMap != NULL) {
+ munmap(pVermilion->fbMap, pVermilion->fbSize);
+ pVermilion->fbMap = NULL;
+ }
+
+ if (pVermilion->mbxRegsBase != NULL) {
+ xf86UnMapVidMem(pScrn->scrnIndex, pVermilion->mbxRegsBase,
+ pVermilion->mbxSize);
+ pVermilion->mbxRegsBase = NULL;
+ }
+
+ if (pVermilion->vdcRegsBase != NULL) {
+ xf86UnMapVidMem(pScrn->scrnIndex, pVermilion->vdcRegsBase,
+ pVermilion->vdcSize);
+ pVermilion->vdcRegsBase = NULL;
+ }
+}
+
+static void
+VERMILIONLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
+ LOCO * colors, VisualPtr pVisual)
+{
+ /*
+ * Do we ever use this function?
+ */
+}
+
+static Bool
+VERMILIONSaveScreen(ScreenPtr pScreen, int mode)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+ Bool on = xf86IsUnblank(mode);
+ VERMILIONSys *sys = pVermilion->sys;
+
+ if (on)
+ SetTimeSinceLastInputEvent();
+
+ if (pScrn->vtSema) {
+ VERMILIONBlankScreen(pScrn, !on);
+ /* Power up the panel */
+ if (pVermilion->usePanel) {
+ if (on) {
+ sys->backlightOn(sys);
+ } else {
+ sys->backlightOff(sys);
+ }
+ }
+ }
+
+ return (TRUE);
+}
+
+Bool
+VERMILIONSave(ScrnInfoPtr pScrn)
+{
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+ VERMILIONSys *sys = pVermilion->sys;
+
+ sys->save(sys);
+ return (TRUE);
+}
+
+Bool
+VERMILIONRestore(ScrnInfoPtr pScrn)
+{
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+ VERMILIONSys *sys = pVermilion->sys;
+
+ sys->restore(sys);
+ return (TRUE);
+}
+
+static void
+VERMILIONDisplayPowerManagementSet(ScrnInfoPtr pScrn, int mode, int flags)
+{
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+ VERMILIONSys *sys = pVermilion->sys;
+
+ if (!pScrn->vtSema)
+ return;
+
+ switch (mode) {
+ case DPMSModeOn:
+ if (pVermilion->usePanel) {
+ sys->panelOn(sys);
+ sys->backlightOn(sys);
+ }
+ VERMILIONDoSetMode(pScrn, &pVermilion->curMode, 1);
+ /* Screen: On; HSync: On, VSync: On */
+ break;
+ case DPMSModeStandby:
+ if (pVermilion->usePanel) {
+ sys->backlightOff(sys);
+ }
+ /* Screen: Off; HSync: Off, VSync: On -- Not Supported */
+ break;
+ case DPMSModeSuspend:
+ if (pVermilion->usePanel) {
+ sys->backlightOff(sys);
+ sys->panelOff(sys);
+ }
+ /* Screen: Off; HSync: On, VSync: Off -- Not Supported */
+ break;
+ case DPMSModeOff:
+ if (pVermilion->usePanel) {
+ sys->backlightOff(sys);
+ sys->panelOff(sys);
+ }
+ VERMILIONDisablePipe(pScrn);
+ /* Screen: Off; HSync: Off, VSync: Off */
+ break;
+ }
+}
diff --git a/src/vermilion.h b/src/vermilion.h
new file mode 100644
index 0000000..ba222cd
--- /dev/null
+++ b/src/vermilion.h
@@ -0,0 +1,223 @@
+/**************************************************************************
+ *
+ * Copyright (c) Intel Corp. 2007.
+ * All Rights Reserved.
+ *
+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ * develop this driver.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors:
+ * Michel Dänzer <michel-at-tungstengraphics-dot-com>
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Alan Hourihane <alanh-at-tungstengraphics-dot-com>
+ */
+
+#ifndef _VERMILION_H_
+#define _VERMILION_H_
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+
+#include "compiler.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+#include "vgaHW.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+/* VBE/DDC support */
+#include "vbe.h"
+#include "vbeModes.h"
+#include "xf86DDC.h"
+
+/* ShadowFB support */
+#include "shadow.h"
+
+/* Int 10 support */
+#include "xf86int10.h"
+
+/* bank switching */
+#include "mibank.h"
+
+/* Dga definitions */
+#include "dgaproc.h"
+
+#include "xf86Resources.h"
+#include "xf86RAC.h"
+
+#include "fb.h"
+#define wfbPictureInit fbPictureInit
+
+#include "xaa.h"
+#include "vermilion_sys.h"
+
+#define VERMILION_VERSION 4000
+#define VERMILION_NAME "VERMILION"
+#define VERMILION_DRIVER_NAME "vermilion"
+#define VERMILION_MAJOR_VERSION 1
+#define VERMILION_MINOR_VERSION 0
+#define VERMILION_PATCHLEVEL 0
+
+ /*XXX*/ typedef struct _VERMILIONRec
+{
+ EntityInfoPtr pEnt;
+ GDevPtr device;
+ pciVideoPtr pciInfo;
+ PCITAG pciTag;
+ xf86MonPtr monitor;
+ CloseScreenProcPtr CloseScreen;
+ OptionInfoPtr Options;
+
+ IOADDRESS ioBase;
+ pciVideoPtr mbx;
+ int fbFD;
+
+/*
+ * Map
+ */
+ void *fbMap;
+ CARD32 *vdcRegsBase;
+ CARD32 *mbxRegsBase;
+ unsigned long fbSize;
+ unsigned long mbxSize;
+ unsigned long vdcSize;
+ unsigned long mchSize;
+
+/*
+ * Mode info
+ */
+
+ int x;
+ int y;
+ int cpp;
+ unsigned stride;
+ DisplayModeRec curMode;
+/*
+ * Panel
+ */
+ Bool usePanel;
+ int panel;
+
+/*
+ * System info
+ */
+ VERMILIONSys *sys;
+ PCITAG kernelmbx;
+ Bool fusedClock;
+ int fusedClockIndex;
+
+/*
+ * Acceleration
+ */
+ Bool accelOn;
+ XAAInfoRecPtr accel;
+ CARD32 mbxBpp;
+ CARD32 mbxFBDevAddr;
+ CARD32 *slavePort;
+ CARD32 FifoSlots;
+ volatile CARD32 *mbxSyncMap;
+ CARD32 mbxSyncDevAddr;
+ CARD32 ROP;
+ CARD32 transEnable;
+ CARD32 fillColour;
+ CARD32 dir;
+
+/*
+ * ShadowFB
+ */
+ char *shadowmem;
+ Bool shadowFB;
+
+/*
+ * Debug modesetting
+ */
+ Bool debug;
+
+} VERMILIONRec, *VERMILIONPtr;
+
+typedef struct _VERMILIONPanelRec
+{
+ char *name;
+ int clockMax; /* kHz */
+ int clockMin; /* kHz */
+ int hActMax; /* Clocks */
+ int hActMin; /* Clocks */
+ int hTotMax; /* Clocks */
+ int hTotMin; /* Clocks */
+ int vActMax; /* Lines */
+ int vActMin; /* Lines */
+ int vTotMax; /* Lines */
+ int vTotMin; /* Lines */
+ int hPerMax; /* ns */
+ int hPerMin; /* ns */
+ float gamma; /* [] */
+} VERMILIONPanelRec, *VERMILIONPanelPtr;
+
+#define VERMILIONPTR(_pScrn) ((VERMILIONPtr) (_pScrn)->driverPrivate)
+#define ALIGN_TO(_a, _b) (((_a) + (_b) - 1) & ~((_b) - 1))
+
+/*
+ * vermilion_accel.c
+ */
+
+extern Bool VERMILIONAccelInit(ScreenPtr pScreen);
+
+/*
+ * vermilion_mode.c
+ */
+
+extern Bool
+VERMILIONDoSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode,
+ Bool plane_enable);
+extern ModeStatus
+VERMILIONValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
+ int flags);
+extern void VERMILIONSetGraphicsOffset(ScrnInfoPtr pScrn, int x, int y);
+extern int VERMILIONBlankScreen(ScrnInfoPtr pScrn, Bool blank);
+extern int VERMILIONDimScreen(ScrnInfoPtr pScrn, CARD8 level);
+extern void VERMILIONDisablePipe(ScrnInfoPtr pScrn);
+void VERMILIONWaitForVblank(ScrnInfoPtr pScrn);
+
+/*
+ * vermilion_panels.c
+ */
+
+extern VERMILIONPanelPtr VERMILIONPanels[];
+extern int VERMILIONNumPanels;
+
+/*
+ * vermilion.c
+ */
+
+extern void * VERMILIONMapPciVideo(ScrnInfoPtr pScrn, char *deviceType,
+ PCITAG tag, unsigned long offset,
+ unsigned long size, char type, int mapType);
+
+#endif /* _VERMILION_H_ */
diff --git a/src/vermilion_accel.c b/src/vermilion_accel.c
new file mode 100644
index 0000000..14b835d
--- /dev/null
+++ b/src/vermilion_accel.c
@@ -0,0 +1,255 @@
+/**************************************************************************
+ *
+ * Copyright (c) Intel Corp. 2007.
+ * All Rights Reserved.
+ *
+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ * develop this driver.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Alan Hourihane <alanh@tungstengraphics.com>
+ * Michel Dänzer <michel@tungstengraphics.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "miline.h"
+
+#include "vermilion.h"
+#include "vermilion_mbx.h"
+
+#include "xaarop.h"
+
+static void mbxSync(ScrnInfoRec * pScrn);
+static void mbxSetupForFillRectSolid(ScrnInfoRec * pScrn, int color,
+ int rop, unsigned int planemask);
+static void mbxSubsequentFillRectSolid(ScrnInfoRec * pScrn, int x,
+ int y, int w, int h);
+static void mbxSubsequentScreenToScreenCopy(ScrnInfoRec * pScrn,
+ int x1, int y1, int x2, int y2, int w, int h);
+static void mbxSetupForScreenToScreenCopy(ScrnInfoRec * pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask, int transparency_color);
+
+#define MBX_SYNC_MAP_SIZE 4
+
+Bool
+VERMILIONAccelInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+ XAAInfoRecPtr infoPtr;
+ BoxRec AvailFBArea;
+
+ switch (pScrn->depth) {
+ case 15:
+ pVermilion->mbxBpp = MBX2D_SRC_555RGB;
+ break;
+ case 24:
+ pVermilion->mbxBpp = MBX2D_SRC_8888ARGB;
+ break;
+ default:
+ return FALSE;
+ }
+
+ pVermilion->accel = infoPtr = XAACreateInfoRec();
+ if (!infoPtr)
+ return FALSE;
+
+ infoPtr->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER;
+
+ infoPtr->Sync = mbxSync;
+
+ infoPtr->SolidFillFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidFill = mbxSetupForFillRectSolid;
+ infoPtr->SubsequentSolidFillRect = mbxSubsequentFillRectSolid;
+
+ infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK;
+ infoPtr->SetupForScreenToScreenCopy = mbxSetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy = mbxSubsequentScreenToScreenCopy;
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 =
+ (pVermilion->fbSize - MBX_SYNC_MAP_SIZE) / pVermilion->stride;
+
+ if (AvailFBArea.y2 > 4095)
+ AvailFBArea.y2 = 4095;
+
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ if (!XAAInit(pScreen, infoPtr))
+ return FALSE;
+
+ pVermilion->mbxFBDevAddr = pScrn->memPhysBase;
+
+ /* Reserve DWORD at the end of the framebuffer for mbxSync() */
+ pVermilion->mbxSyncDevAddr = pVermilion->mbxFBDevAddr +
+ pVermilion->fbSize - MBX_SYNC_MAP_SIZE;
+ pVermilion->mbxSyncMap = (CARD32 *) ((char *)pVermilion->fbMap +
+ pVermilion->fbSize - MBX_SYNC_MAP_SIZE);
+
+ pVermilion->slavePort = (CARD32 *) ((char *)pVermilion->mbxRegsBase +
+ MBX_SP_2D_SYS_PHYS_OFFSET);
+
+ return TRUE;
+}
+
+static void
+mbxSync(ScrnInfoRec * pScrn)
+{
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+ unsigned int sync_val;
+ volatile CARD32 *fb_sync_val;
+ CARD32 auBltPacket[7];
+
+ fb_sync_val = pVermilion->mbxSyncMap;
+ sync_val = ((*fb_sync_val) + 1) % 65536;
+
+ WAITFIFO(7);
+
+ auBltPacket[0] = MBX2D_DST_CTRL_BH | MBX2D_SRC_8888ARGB;
+ auBltPacket[1] = pVermilion->mbxSyncDevAddr;
+ auBltPacket[2] = MBX2D_BLIT_BH | ROP_P << 8 | ROP_P;
+ auBltPacket[3] = sync_val;
+ auBltPacket[4] = (0 & 0xffff) << 16 | (0 & 0xffff);
+ auBltPacket[5] = (1 & 0xffff) << 16 | (1 & 0xffff);
+ auBltPacket[6] = MBX2D_FENCE_BH;
+
+ WRITESLAVEPORTDATA(7);
+
+ while (*fb_sync_val != sync_val) {
+#if 0
+ ErrorF("WAITING 0x%x 0x%x\n", *fb_sync_val, sync_val);
+#endif
+ usleep(10);
+ }
+}
+
+static void
+mbxSetupForScreenToScreenCopy(ScrnInfoRec * pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask, int transparency_color)
+{
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+ CARD32 auBltPacket[4];
+
+ pVermilion->transEnable = 0;
+
+ pVermilion->ROP = XAAGetCopyROP(rop);
+
+ pVermilion->dir = MBX2D_TEXTCOPY_TL2BR;
+ if (xdir < 0)
+ pVermilion->dir |= MBX2D_TEXTCOPY_TR2BL;
+ if (ydir < 0)
+ pVermilion->dir |= MBX2D_TEXTCOPY_BL2TR;
+
+ if (transparency_color != -1) {
+ pVermilion->transEnable = MBX2D_SRCCK_REJECT;
+
+ WAITFIFO(3);
+
+ auBltPacket[0] = MBX2D_CTRL_BH | MBX2D_SRCCK_CTRL;
+ if (pScrn->depth == 15)
+ auBltPacket[1] = transparency_color | transparency_color << 16;
+ else
+ auBltPacket[1] = transparency_color;
+ auBltPacket[2] = 0xffffffff;
+
+ WRITESLAVEPORTDATA(3);
+ }
+
+ WAITFIFO(4);
+
+ auBltPacket[0] = MBX2D_SRC_CTRL_BH | MBX2D_SRC_FBMEM | pVermilion->mbxBpp;
+ auBltPacket[0] |= pVermilion->stride;
+ auBltPacket[1] = pVermilion->mbxFBDevAddr;
+ auBltPacket[2] = MBX2D_DST_CTRL_BH | pVermilion->mbxBpp;
+ auBltPacket[2] |= pVermilion->stride;
+ auBltPacket[3] = pVermilion->mbxFBDevAddr;
+ WRITESLAVEPORTDATA(4);
+}
+
+static void
+mbxSubsequentScreenToScreenCopy(ScrnInfoRec * pScrn, int x1, int y1,
+ int x2, int y2, int w, int h)
+{
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+ CARD32 auBltPacket[5];
+
+ WAITFIFO(5);
+
+ auBltPacket[0] = MBX2D_SRC_OFF_BH | (x1 & 0xffff) << 14 | (y1 & 0xffff);
+ auBltPacket[1] = MBX2D_BLIT_BH | pVermilion->transEnable |
+ MBX2D_USE_PAT | pVermilion->dir |
+ (pVermilion->ROP & 0xff) << 8 | (pVermilion->ROP & 0xff);
+ auBltPacket[2] = (x2 & 0xffff) << 16 | (y2 & 0xffff);
+ auBltPacket[3] = ((x2 + w) & 0xffff) << 16 | ((y2 + h) & 0xffff);
+ auBltPacket[4] = MBX2D_FENCE_BH;
+
+ WRITESLAVEPORTDATA(5);
+}
+
+static void
+mbxSetupForFillRectSolid(ScrnInfoRec * pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+ CARD32 auBltPacket[2];
+
+ pVermilion->ROP = XAAGetPatternROP(rop);
+
+ if (pScrn->depth == 15) {
+ color |= 0x8000;
+ }
+
+ pVermilion->fillColour = color;
+
+ WAITFIFO(2);
+
+ auBltPacket[0] = MBX2D_DST_CTRL_BH | pVermilion->mbxBpp;
+ auBltPacket[0] |= pVermilion->stride;
+ auBltPacket[1] = pVermilion->mbxFBDevAddr;
+ WRITESLAVEPORTDATA(2);
+}
+
+static void
+mbxSubsequentFillRectSolid(ScrnInfoRec * pScrn, int x, int y, int w, int h)
+{
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+ CARD32 auBltPacket[5];
+
+ WAITFIFO(5);
+
+ auBltPacket[0] = MBX2D_BLIT_BH |
+ (pVermilion->ROP & 0xff) << 8 | (pVermilion->ROP & 0xff);
+ auBltPacket[1] = pVermilion->fillColour;
+ auBltPacket[2] = (x & 0xffff) << 16 | (y & 0xffff);
+ auBltPacket[3] = ((x + w) & 0xffff) << 16 | ((y + h) & 0xffff);
+ auBltPacket[4] = MBX2D_FENCE_BH;
+ WRITESLAVEPORTDATA(5);
+}
diff --git a/src/vermilion_kernel.h b/src/vermilion_kernel.h
new file mode 100644
index 0000000..071de51
--- /dev/null
+++ b/src/vermilion_kernel.h
@@ -0,0 +1,81 @@
+/**************************************************************************
+ *
+ * Copyright (c) Intel Corp. 2007.
+ * All Rights Reserved.
+ *
+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ * develop this driver.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors:
+ * Michel Dänzer <michel-at-tungstengraphics-dot-com>
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Alan Hourihane <alanh-at-tungstengraphics-dot-com>
+ */
+#ifndef _VERMILION_KERNEL_H_
+#define _VERMILION_KERNEL_H_
+
+#ifdef __KERNEL__
+#include<linux/ioctl.h>
+#include<linux/types.h>
+#else
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#define __u64 uint64_t
+#endif
+
+#define VML_KI_MAJOR 2
+#define VML_KI_MINOR 0
+
+typedef struct {
+ unsigned bus;
+ unsigned slot;
+ unsigned function;
+} vml_pci_tag;
+
+typedef struct {
+ vml_pci_tag gpu_tag;
+ __u64 vram_offset;
+ __u64 vram_contig_size;
+ __u64 vram_total_size;
+} vml_init_rep_t;
+
+typedef struct {
+ unsigned major;
+ unsigned minor;
+ vml_pci_tag vdc_tag;
+ unsigned pipe;
+} vml_init_req_t;
+
+typedef union {
+ vml_init_req_t req;
+ vml_init_rep_t rep;
+} vml_init_t;
+
+#define VML_IOC_MAGIC 0xD0
+#define VML_INIT_DEVICE _IOWR(VML_IOC_MAGIC, 0, vml_init_t)
+#define VML_IOC_MAXNR 0
+
+#endif
diff --git a/src/vermilion_mbx.h b/src/vermilion_mbx.h
new file mode 100644
index 0000000..4859455
--- /dev/null
+++ b/src/vermilion_mbx.h
@@ -0,0 +1,117 @@
+/**************************************************************************
+ *
+ * Copyright (c) Intel Corp. 2007.
+ * All Rights Reserved.
+ *
+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ * develop this driver.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Alan Hourihane <alanh@tungstengraphics.com>
+ * Michel Dänzer <michel@tungstengraphics.com>
+ */
+
+#ifndef _VERMILION_MBX_H_
+#define _VERMILION_MBX_H_
+
+#ifndef XFree86LOADER
+#include <sys/mman.h>
+#endif
+
+#define ReadHWReg(ui32Offset) *(volatile CARD32*)((char*)pVermilion->mbxRegsBase+ui32Offset)
+
+#define MBX1_GLOBREG_INT_STATUS 0x012C
+#define MBX1_INT_TA_FREEVCOUNT_MASK 0x00FF0000
+#define MBX1_INT_TA_FREEVCOUNT_SHIFT 16
+
+/*
+ MBX Slave Port's offset into the register aperture
+*/
+#define MBX_SP_2D_SYS_PHYS_OFFSET 0xA00000
+
+/*
+ MBX Slave Port FIFO Size (in units of `Bits per Write Bus Width')
+ Includes 5 slot safety factor for fullness register latency
+*/
+#define MBX1_SP_FIFO_DWSIZE 123
+
+/*
+ Macro to extract FIFO space from HW register value
+*/
+#define MBX_EXTRACT_FIFO_COUNT(x) (((x) & MBX1_INT_TA_FREEVCOUNT_MASK) >> MBX1_INT_TA_FREEVCOUNT_SHIFT)
+
+static __inline__ void
+MBXAcquireFifoSpace(VERMILIONPtr pVermilion, CARD32 n)
+{
+ while (pVermilion->FifoSlots < n) {
+ /* read fifo space from HW */
+ pVermilion->FifoSlots = (MBX1_SP_FIFO_DWSIZE -
+ MBX_EXTRACT_FIFO_COUNT(ReadHWReg(MBX1_GLOBREG_INT_STATUS)));
+ }
+}
+
+static __inline__ void
+MBXWriteSlavePortBatch(VERMILIONPtr pVermilion, void *pvLinDataAddr,
+ CARD32 ui32DWORDs)
+{
+ CARD32 *pui32LinDataAddr = (CARD32 *) pvLinDataAddr;
+ CARD32 *pui32LinPortAddrBase = pVermilion->slavePort;
+
+ /* write to the slaveport */
+ while (ui32DWORDs--) {
+ *pui32LinPortAddrBase = *pui32LinDataAddr++;
+ }
+}
+
+#define WRITESLAVEPORTDATA(n) \
+ (void) MBXWriteSlavePortBatch ( pVermilion, auBltPacket, n );
+
+#define WAITFIFO(n) \
+ MBXAcquireFifoSpace(pVermilion, n); \
+ pVermilion->FifoSlots -= n;
+
+/*
+ * Block headers
+ */
+#define MBX2D_CTRL_BH 0x20000000
+#define MBX2D_SRC_OFF_BH 0x30000000
+#define MBX2D_FENCE_BH 0x70000000 /* Flush between two blits */
+#define MBX2D_BLIT_BH 0x80000000
+#define MBX2D_SRC_CTRL_BH 0x90000000
+#define MBX2D_DST_CTRL_BH 0xA0000000
+
+#define MBX2D_USE_PAT 0x00010000
+
+#define MBX2D_TEXTCOPY_TL2BR 0x00000000
+#define MBX2D_TEXTCOPY_TR2BL 0x00800000
+#define MBX2D_TEXTCOPY_BL2TR 0x01000000
+
+#define MBX2D_SRCCK_REJECT 0x00100000
+#define MBX2D_SRCCK_CTRL 0x00000001
+
+#define MBX2D_SRC_FBMEM 0x04000000
+#define MBX2D_SRC_555RGB 0x00040000
+#define MBX2D_SRC_8888ARGB 0x00060000
+
+#endif /* _VERMILION_MBX_H_ */
diff --git a/src/vermilion_mode.c b/src/vermilion_mode.c
new file mode 100644
index 0000000..0d55371
--- /dev/null
+++ b/src/vermilion_mode.c
@@ -0,0 +1,316 @@
+/**************************************************************************
+ *
+ * Copyright (c) Intel Corp. 2007.
+ * All Rights Reserved.
+ *
+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ * develop this driver.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors:
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Part of this code is taken from the xf86-video-intel driver.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vermilion.h"
+#include "vermilion_reg.h"
+#include <math.h>
+
+void
+VERMILIONSetGraphicsOffset(ScrnInfoPtr pScrn, int x, int y)
+{
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+
+ VML_WRITE32(VML_DSPCADDR, (CARD32) pScrn->memPhysBase +
+ y * pVermilion->stride + x * pVermilion->cpp);
+ (void)VML_READ32(VML_DSPCADDR);
+}
+
+static int
+VERMILIONNearestClock(ScrnInfoPtr pScrn, int clock, int *index)
+{
+ *index = xf86GetNearestClock(pScrn, clock, FALSE, 1, 1, NULL);
+
+ return pScrn->clock[*index];
+}
+
+ModeStatus
+VERMILIONValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
+ int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+ int realClock;
+ int hPeriod;
+ int dummy;
+
+ xf86DrvMsg(scrnIndex, X_INFO, "VERMILIONValidMode: Validating %s (%d)\n",
+ mode->name, mode->Clock);
+
+ realClock = VERMILIONNearestClock(pScrn, mode->Clock, &dummy);
+
+ if (mode->Flags & V_INTERLACE)
+ return MODE_NO_INTERLACE;
+
+ if (pVermilion->usePanel) {
+ VERMILIONPanelPtr panel = VERMILIONPanels[pVermilion->panel];
+
+ if (realClock < panel->clockMin)
+ return MODE_CLOCK_LOW;
+ if (realClock > panel->clockMax)
+ return MODE_CLOCK_HIGH;
+ if (mode->CrtcHTotal < panel->hTotMin ||
+ mode->CrtcHTotal > panel->hTotMax)
+ return MODE_BAD_HVALUE;
+ if (mode->CrtcHDisplay < panel->hActMin ||
+ mode->CrtcHDisplay > panel->hActMax)
+ return MODE_BAD_HVALUE;
+ if (mode->CrtcVTotal < panel->vTotMin ||
+ mode->CrtcVTotal > panel->vTotMax)
+ return MODE_BAD_VVALUE;
+ if (mode->CrtcVDisplay < panel->vActMin ||
+ mode->CrtcVDisplay > panel->vActMax)
+ return MODE_BAD_VVALUE;
+
+ hPeriod = mode->CrtcHTotal * 10000 / (realClock / 100);
+ if (hPeriod < panel->hPerMin || hPeriod > panel->hPerMax) {
+ return MODE_H_ILLEGAL;
+ }
+ }
+ return MODE_OK;
+}
+
+void
+VERMILIONWaitForVblank(ScrnInfoPtr pScrn)
+{
+ /* Wait for 20ms, i.e. one cycle at 50hz. */
+ usleep(20000);
+}
+
+int
+VERMILIONBlankScreen(ScrnInfoPtr pScrn, Bool blank)
+{
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+ CARD32 cur = VML_READ32(VML_PIPEACONF);
+
+ /*
+ * We'd like to force planes off here, but then we can't
+ * force them on again. Hw bug?
+ */
+
+ if (blank) {
+ VML_WRITE32(VML_PIPEACONF, cur | VML_PIPE_FORCE_BORDER);
+ } else {
+ VML_WRITE32(VML_PIPEACONF, cur & ~VML_PIPE_FORCE_BORDER);
+ }
+ (void)VML_READ32(VML_PIPEACONF);
+ return TRUE;
+
+}
+
+void
+VERMILIONDisablePipe(ScrnInfoPtr pScrn)
+{
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+
+ /* Disable the MDVO pad */
+ VML_WRITE32(VML_RCOMPSTAT, 0);
+ while (!(VML_READ32(VML_RCOMPSTAT) & VML_MDVO_VDC_I_RCOMP)) ;
+
+ /* Disable display planes */
+ VML_WRITE32(VML_DSPCCNTR, VML_READ32(VML_DSPCCNTR) & ~VML_GFX_ENABLE);
+ (void)VML_READ32(VML_DSPCCNTR);
+ /* Wait for vblank for the disable to take effect */
+ VERMILIONWaitForVblank(pScrn);
+
+ /* Next, disable display pipes */
+ VML_WRITE32(VML_PIPEACONF, 0);
+ (void)VML_READ32(VML_PIPEACONF);
+}
+
+void
+VERMILIONDumpRegs(ScrnInfoPtr pScrn)
+{
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+ ErrorF("Modesetting register dump:\n");
+ ErrorF("\tHTOTAL_A : 0x%08x\n",
+ (unsigned) VML_READ32(VML_HTOTAL_A));
+ ErrorF("\tHBLANK_A : 0x%08x\n",
+ (unsigned) VML_READ32(VML_HBLANK_A));
+ ErrorF("\tHSYNC_A : 0x%08x\n",
+ (unsigned) VML_READ32(VML_HSYNC_A));
+ ErrorF("\tVTOTAL_A : 0x%08x\n",
+ (unsigned) VML_READ32(VML_VTOTAL_A));
+ ErrorF("\tVBLANK_A : 0x%08x\n",
+ (unsigned) VML_READ32(VML_VBLANK_A));
+ ErrorF("\tVSYNC_A : 0x%08x\n",
+ (unsigned) VML_READ32(VML_VSYNC_A));
+ ErrorF("\tDSPCSTRIDE : 0x%08x\n",
+ (unsigned) VML_READ32(VML_DSPCSTRIDE));
+ ErrorF("\tDSPCSIZE : 0x%08x\n",
+ (unsigned) VML_READ32(VML_DSPCSIZE));
+ ErrorF("\tDSPCPOS : 0x%08x\n",
+ (unsigned) VML_READ32(VML_DSPCPOS));
+ ErrorF("\tDSPARB : 0x%08x\n",
+ (unsigned) VML_READ32(VML_DSPARB));
+ ErrorF("\tDSPCADDR : 0x%08x\n",
+ (unsigned) VML_READ32(VML_DSPCADDR));
+ ErrorF("\tBCLRPAT_A : 0x%08x\n",
+ (unsigned) VML_READ32(VML_BCLRPAT_A));
+ ErrorF("\tCANVSCLR_A : 0x%08x\n",
+ (unsigned) VML_READ32(VML_CANVSCLR_A));
+ ErrorF("\tPIPEASRC : 0x%08x\n",
+ (unsigned) VML_READ32(VML_PIPEASRC));
+ ErrorF("\tPIPEACONF : 0x%08x\n",
+ (unsigned) VML_READ32(VML_PIPEACONF));
+ ErrorF("\tDSPCCNTR : 0x%08x\n",
+ (unsigned) VML_READ32(VML_DSPCCNTR));
+ ErrorF("\tRCOMPSTAT : 0x%08x\n",
+ (unsigned) VML_READ32(VML_RCOMPSTAT));
+ ErrorF("End of modesetting register dump.\n");
+}
+
+
+/*
+ * Sets the given video mode.
+ */
+
+Bool
+VERMILIONDoSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, Bool plane_enable)
+{
+ VERMILIONPtr pVermilion = VERMILIONPTR(pScrn);
+ VERMILIONSys *sys = pVermilion->sys;
+ CARD32 htot, hblank, hsync, vtot, vblank, vsync, dspcntr;
+ CARD32 pipesrc, dspsize;
+ int pixelClock;
+ Bool ret = FALSE;
+ int index;
+
+ if (VERMILIONValidMode(pScrn->scrnIndex, pMode, FALSE, 0) != MODE_OK)
+ goto done;
+
+#if 0
+ if (I830ModesEqual(&pVermilion->curMode, pMode))
+ return TRUE;
+#endif
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Requested pix clock: %d\n",
+ pMode->Clock);
+
+ htot = (pMode->CrtcHDisplay - 1) | ((pMode->CrtcHTotal - 1) << 16);
+ hblank =
+ (pMode->CrtcHBlankStart - 1) | ((pMode->CrtcHBlankEnd - 1) << 16);
+ hsync = (pMode->CrtcHSyncStart - 1) | ((pMode->CrtcHSyncEnd - 1) << 16);
+ vtot = (pMode->CrtcVDisplay - 1) | ((pMode->CrtcVTotal - 1) << 16);
+ vblank =
+ (pMode->CrtcVBlankStart - 1) | ((pMode->CrtcVBlankEnd - 1) << 16);
+ vsync = (pMode->CrtcVSyncStart - 1) | ((pMode->CrtcVSyncEnd - 1) << 16);
+ pipesrc = ((pMode->HDisplay - 1) << 16) | (pMode->VDisplay - 1);
+ dspsize = ((pMode->VDisplay - 1) << 16) | (pMode->HDisplay - 1);
+ pixelClock = VERMILIONNearestClock(pScrn, pMode->Clock, &index);
+
+ if (pVermilion->debug) {
+ ErrorF
+ ("hact: %d htot: %d hbstart: %d hbend: %d hsyncstart: %d hsyncend: %d\n",
+ (int)(htot & 0xffff) + 1, (int)(htot >> 16) + 1,
+ (int)(hblank & 0xffff) + 1, (int)(hblank >> 16) + 1,
+ (int)(hsync & 0xffff) + 1, (int)(hsync >> 16) + 1);
+ ErrorF
+ ("vact: %d vtot: %d vbstart: %d vbend: %d vsyncstart: %d vsyncend: %d\n",
+ (int)(vtot & 0xffff) + 1, (int)(vtot >> 16) + 1,
+ (int)(vblank & 0xffff) + 1, (int)(vblank >> 16) + 1,
+ (int)(vsync & 0xffff) + 1, (int)(vsync >> 16) + 1);
+ ErrorF("pipesrc: %dx%d, dspsize: %dx%d\n", (int)(pipesrc >> 16) + 1,
+ (int)(pipesrc & 0xffff) + 1, (int)(dspsize & 0xffff) + 1,
+ (int)(dspsize >> 16) + 1);
+ ErrorF("Actual Pixel clock is %d kHz\n"
+ "\t Horizontal frequency is %.1f kHz\n"
+ "\t Vertical frequency is %.1f Hz\n",
+ pixelClock,
+ (float)pixelClock / (float)(pMode->CrtcHTotal),
+ (float)pixelClock / (float)(pMode->CrtcHTotal) /
+ (float)(pMode->CrtcVTotal) * 1000.);
+ }
+ dspcntr = VML_GFX_ENABLE | VML_GFX_GAMMABYPASS;
+ switch (pScrn->depth) {
+ case 15:
+ dspcntr |= VML_GFX_ARGB1555;
+ break;
+ case 24:
+ dspcntr |= VML_GFX_RGB0888;
+ break;
+ default:
+ ErrorF("Unknown display BPP\n");
+ goto done;
+ }
+
+ /* Finally, set the mode. */
+ VERMILIONDisablePipe(pScrn);
+ mem_barrier();
+
+ /* Set pixel clock */
+ if (!sys->setClock(sys, pixelClock))
+ return FALSE;
+
+ VML_WRITE32(VML_HTOTAL_A, htot);
+ VML_WRITE32(VML_HBLANK_A, hblank);
+ VML_WRITE32(VML_HSYNC_A, hsync);
+ VML_WRITE32(VML_VTOTAL_A, vtot);
+ VML_WRITE32(VML_VBLANK_A, vblank);
+ VML_WRITE32(VML_VSYNC_A, vsync);
+ VML_WRITE32(VML_DSPCSTRIDE, pVermilion->stride);
+ VML_WRITE32(VML_DSPCSIZE, dspsize);
+ VML_WRITE32(VML_DSPCPOS, 0x00000000);
+ VML_WRITE32(VML_DSPARB, VML_FIFO_DEFAULT);
+ /* Black border color */
+ VML_WRITE32(VML_BCLRPAT_A, 0x00000000);
+ /* Black canvas color */
+ VML_WRITE32(VML_CANVSCLR_A, 0x00000000);
+ VML_WRITE32(VML_PIPEASRC, pipesrc);
+ (void)VML_READ32(VML_PIPEASRC);
+ mem_barrier();
+
+ /* Then, turn the pipe on first. */
+ VML_WRITE32(VML_PIPEACONF, VML_PIPE_ENABLE);
+ (void)VML_READ32(VML_PIPEACONF);
+ mem_barrier();
+
+ VML_WRITE32(VML_DSPCCNTR, dspcntr);
+ VERMILIONSetGraphicsOffset(pScrn, pVermilion->x, pVermilion->y);
+
+ /* Enable the MDVO pad */
+ VML_WRITE32(VML_RCOMPSTAT, VML_MDVO_PAD_ENABLE);
+ while (!(VML_READ32(VML_RCOMPSTAT) &
+ (VML_MDVO_VDC_I_RCOMP | VML_MDVO_PAD_ENABLE))) ;
+
+ pVermilion->curMode = *pMode;
+ if (pVermilion->debug)
+ VERMILIONDumpRegs(pScrn);
+ ret = TRUE;
+ done:
+ return ret;
+}
diff --git a/src/vermilion_panels.c b/src/vermilion_panels.c
new file mode 100644
index 0000000..6efdc4a
--- /dev/null
+++ b/src/vermilion_panels.c
@@ -0,0 +1,63 @@
+/**************************************************************************
+ *
+ * Copyright (c) Intel Corp. 2007.
+ * All Rights Reserved.
+ *
+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ * develop this driver.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/* Authors:
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ */
+
+#include "vermilion.h"
+#include "vermilion_reg.h"
+
+/*
+ * Add panel timing information and gamma here.
+ */
+
+/* SHARP LQ150X1LGN2A */
+static VERMILIONPanelRec panel0 = {
+ "SHARP LQ150X1LGN2A",
+ 80000,
+ 50000,
+ 1024,
+ 1024,
+ 1720,
+ 1056,
+ 768,
+ 768,
+ 990,
+ 773,
+ 23400,
+ 16000,
+ 1.0
+};
+
+VERMILIONPanelPtr VERMILIONPanels[] = {
+ &panel0
+};
+
+int VERMILIONNumPanels = sizeof(VERMILIONPanels) / sizeof(VERMILIONPanelPtr);
diff --git a/src/vermilion_reg.h b/src/vermilion_reg.h
new file mode 100644
index 0000000..6b5ff0b
--- /dev/null
+++ b/src/vermilion_reg.h
@@ -0,0 +1,187 @@
+/**************************************************************************
+ *
+ * Copyright (c) Intel Corp. 2007.
+ * All Rights Reserved.
+ *
+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ * develop this driver.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ */
+
+#ifndef _VERMILION_REG_H_
+#define _VERMILION_REG_H_
+
+#define VML_READ32(_offs) \
+ (*((volatile CARD32 *) ((volatile CARD8 *)pVermilion->vdcRegsBase + (_offs))))
+#define VML_WRITE32(__offs, _data) \
+ (VML_READ32(__offs) = (_data));
+
+/*
+ * Display controller registers:
+ */
+
+/* Display controller 10-bit color representation */
+
+#define VML_R_MASK 0x3FF00000
+#define VML_R_SHIFT 20
+#define VML_G_MASK 0x000FFC00
+#define VML_G_SHIFT 10
+#define VML_B_MASK 0x000003FF
+#define VML_B_SHIFT 0
+
+/* Graphics plane control */
+#define VML_DSPCCNTR 0x00072180
+#define VML_GFX_ENABLE 0x80000000
+#define VML_GFX_GAMMABYPASS 0x40000000
+#define VML_GFX_ARGB1555 0x0C000000
+#define VML_GFX_RGB0888 0x18000000
+#define VML_GFX_ARGB8888 0x1C000000
+#define VML_GFX_ALPHACONST 0x00800000
+#define VML_GFX_CONST_ALPHA 0x000000FF
+
+/* Graphics plane start address. Pixel aligned. */
+#define VML_DSPCADDR 0x00072184
+
+/* Graphics plane stride register. */
+#define VML_DSPCSTRIDE 0x00072188
+
+/* Graphics plane position register. */
+#define VML_DSPCPOS 0x0007218C
+#define VML_POS_YMASK 0x0FFF0000
+#define VML_POS_YSHIFT 16
+#define VML_POS_XMASK 0x00000FFF
+#define VML_POS_XSHIFT 0
+
+/* Graphics plane height and width */
+#define VML_DSPCSIZE 0x00072190
+#define VML_SIZE_HMASK 0x0FFF0000
+#define VML_SIZE_HSHIFT 16
+#define VML_SISE_WMASK 0x00000FFF
+#define VML_SIZE_WSHIFT 0
+
+/* Graphics plane gamma correction lookup table registers (129 * 32 bits) */
+#define VML_DSPCGAMLUT 0x00072200
+
+/* Pixel video output configuration register */
+#define VML_PVOCONFIG 0x00061140
+#define VML_CONFIG_BASE 0x80000000
+#define VML_CONFIG_PIXEL_SWAP 0x04000000
+#define VML_CONFIG_DE_INV 0x01000000
+#define VML_CONFIG_HREF_INV 0x00400000
+#define VML_CONFIG_VREF_INV 0x00100000
+#define VML_CONFIG_CLK_INV 0x00040000
+#define VML_CONFIG_CLK_DIV2 0x00010000
+#define VML_CONFIG_ESTRB_INV 0x00008000
+
+/* Pipe A Horizontal total register */
+#define VML_HTOTAL_A 0x00060000
+#define VML_HTOTAL_MASK 0x1FFF0000
+#define VML_HTOTAL_SHIFT 16
+#define VML_HTOTAL_VAL 8192
+#define VML_HACTIVE_MASK 0x000007FF
+#define VML_HACTIVE_SHIFT 0
+#define VML_HACTIVE_VAL 4096
+
+/* Pipe A Horizontal Blank register */
+#define VML_HBLANK_A 0x00060004
+#define VML_HBLANK_END_MASK 0x1FFF0000
+#define VML_HBLANK_END_SHIFT 16
+#define VML_HBLANK_END_VAL 8192
+#define VML_HBLANK_START_MASK 0x00001FFF
+#define VML_HBLANK_START_SHIFT 0
+#define VML_HBLANK_START_VAL 8192
+
+/* Pipe A Horizontal Sync register */
+#define VML_HSYNC_A 0x00060008
+#define VML_HSYNC_END_MASK 0x1FFF0000
+#define VML_HSYNC_END_SHIFT 16
+#define VML_HSYNC_END_VAL 8192
+#define VML_HSYNC_START_MASK 0x00001FFF
+#define VML_HSYNC_START_SHIFT 0
+#define VML_HSYNC_START_VAL 8192
+
+/* Pipe A Vertical total register */
+#define VML_VTOTAL_A 0x0006000C
+#define VML_VTOTAL_MASK 0x1FFF0000
+#define VML_VTOTAL_SHIFT 16
+#define VML_VTOTAL_VAL 8192
+#define VML_VACTIVE_MASK 0x000007FF
+#define VML_VACTIVE_SHIFT 0
+#define VML_VACTIVE_VAL 4096
+
+/* Pipe A Vertical Blank register */
+#define VML_VBLANK_A 0x00060010
+#define VML_VBLANK_END_MASK 0x1FFF0000
+#define VML_VBLANK_END_SHIFT 16
+#define VML_VBLANK_END_VAL 8192
+#define VML_VBLANK_START_MASK 0x00001FFF
+#define VML_VBLANK_START_SHIFT 0
+#define VML_VBLANK_START_VAL 8192
+
+/* Pipe A Vertical Sync register */
+#define VML_VSYNC_A 0x00060014
+#define VML_VSYNC_END_MASK 0x1FFF0000
+#define VML_VSYNC_END_SHIFT 16
+#define VML_VSYNC_END_VAL 8192
+#define VML_VSYNC_START_MASK 0x00001FFF
+#define VML_VSYNC_START_SHIFT 0
+#define VML_VSYNC_START_VAL 8192
+
+/* Pipe A Source Image size (minus one - equal to active size)
+ * Programmable while pipe is enabled.
+ */
+#define VML_PIPEASRC 0x0006001C
+#define VML_PIPEASRC_HMASK 0x0FFF0000
+#define VML_PIPEASRC_HSHIFT 16
+#define VML_PIPEASRC_VMASK 0x00000FFF
+#define VML_PIPEASRC_VSHIFT 0
+
+/* Pipe A Border Color Pattern register (10 bit color) */
+#define VML_BCLRPAT_A 0x00060020
+
+/* Pipe A Canvas Color register (10 bit color) */
+#define VML_CANVSCLR_A 0x00060024
+
+/* Pipe A Configuration register */
+#define VML_PIPEACONF 0x00070008
+#define VML_PIPE_BASE 0x00000000
+#define VML_PIPE_ENABLE 0x80000000
+#define VML_PIPE_FORCE_BORDER 0x02000000
+#define VML_PIPE_PLANES_OFF 0x00080000
+#define VML_PIPE_ARGB_OUTPUT_MODE 0x00040000
+
+/* Pipe A FIFO setting */
+#define VML_DSPARB 0x00070030
+#define VML_FIFO_DEFAULT 0x00001D9C
+
+/* MDVO rcomp status & pads control register */
+#define VML_RCOMPSTAT 0x00070048
+#define VML_MDVO_VDC_I_RCOMP 0x80000000
+#define VML_MDVO_POWERSAVE_OFF 0x00000008
+#define VML_MDVO_PAD_ENABLE 0x00000004
+#define VML_MDVO_PULLDOWN_ENABLE 0x00000001
+
+#endif
diff --git a/src/vermilion_sys.c b/src/vermilion_sys.c
new file mode 100644
index 0000000..56fd4db
--- /dev/null
+++ b/src/vermilion_sys.c
@@ -0,0 +1,444 @@
+/**************************************************************************
+ *
+ * Copyright (c) Intel Corp. 2007.
+ * All Rights Reserved.
+ *
+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ * develop this driver.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors:
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vermilion_kernel.h"
+#include "vermilion.h"
+
+typedef enum
+{
+ carilloRanch = 0,
+ numSystems
+} VERMILIONSysID;
+
+typedef struct
+{
+ VERMILIONSysID sysID;
+ CARD32 subsys0;
+ CARD32 subsys1;
+ const char *sysName;
+} VERMILIONSubSystem;
+
+/*
+ * We can possibly identify the board type
+ * based on the PCI subsystem ids
+ * of the host bridge?
+ * See the sys initialization function below.
+ */
+
+static VERMILIONSubSystem vSystems[] = {
+ {carilloRanch, 0x8086, 0x5001, "Carillo Ranch"}
+};
+
+/*
+*****************************************************************************
+* Carillo Ranch System info.
+*/
+
+/* The LVDS- and panel power controls sits on the
+ GPIO port of the ISA bridge. */
+
+#define VML_CR_DEVICE_LPC 0x27B8
+#define VML_CR_REG_GPIOBAR 0x48
+#define VML_CR_REG_GPIOEN 0x4C
+#define VML_CR_GPIOEN_BIT (1 << 4)
+#define VML_CR_PANEL_PORT 0x38
+#define VML_CR_LVDS_ON 0x00000001
+#define VML_CR_PANEL_ON 0x00000002
+#define VML_CR_BACKLIGHT_OFF 0x00000004
+
+/* The PLL Clock register sits on Host bridge */
+#define VML_CR_DEVICE_MCH 0x5001
+#define VML_CR_REG_MCHBAR 0x44
+#define VML_CR_REG_MCHEN 0x54
+#define VML_CR_MCHEN_BIT (1 << 28)
+#define VML_CR_MCHMAP_SIZE 4096
+#define VML_CR_REG_CLOCK 0xc3c
+#define VML_CR_CLOCK_SHIFT 8
+#define VML_CR_CLOCK_MASK 0x00000f00
+
+typedef struct _CRSys
+{
+ CARD32 mchBAR;
+ unsigned char *mchRegsBase;
+ CARD32 gpioBAR;
+ CARD32 savedPanelState;
+ CARD32 savedClock;
+ ScrnInfoPtr pScrn;
+} CRSys;
+
+static const unsigned vermilionCRClocks[] = {
+ 6750,
+ 13500,
+ 27000,
+ 29700,
+ 37125,
+ 54000,
+ 59400,
+ 74250,
+ 120000
+ /*
+ * There are more clocks, but they are disabled on the CR board.
+ */
+};
+
+static const unsigned vermilionCRClockBits[] = {
+ 0x0a,
+ 0x09,
+ 0x08,
+ 0x07,
+ 0x06,
+ 0x05,
+ 0x04,
+ 0x03,
+ 0x0b
+};
+
+static const unsigned vermilionCRNumClocks =
+ sizeof(vermilionCRClocks) / sizeof(unsigned);
+
+static pointer
+VERMILIONCRInit(ScrnInfoPtr pScrn)
+{
+ CRSys *crSys;
+ CARD32 devEn;
+ PCITAG curTag;
+ PCITAG mchTag = pciTag(0x00, 0x00, 0x00);
+ PCITAG lpcTag = pciTag(0x00, 0x1f, 0x00);
+
+ crSys = (CRSys *) calloc(sizeof(*crSys), 1);
+ if (!crSys) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Out of memory.\n");
+ return NULL;
+ }
+ crSys->pScrn = pScrn;
+
+ curTag = pciFindFirst((VML_CR_DEVICE_MCH << 16) | PCI_VENDOR_INTEL,
+ 0xffffffff);
+ if (curTag != mchTag) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not find Carillo Ranch "
+ "MCH device.\n");
+ goto out_err;
+ }
+
+ devEn = (CARD32) pciReadLong(mchTag, VML_CR_REG_MCHEN);
+ if (!(devEn & VML_CR_MCHEN_BIT)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Carillo Ranch MCH device "
+ "was not enabled.\n");
+ goto out_err;
+ }
+
+ crSys->mchBAR = (CARD32) pciReadLong(mchTag, VML_CR_REG_MCHBAR);
+ crSys->mchRegsBase =
+ VERMILIONMapPciVideo(pScrn, "MCH",
+ mchTag, crSys->mchBAR, VML_CR_MCHMAP_SIZE, 0, VIDMEM_MMIO);
+ if (!crSys->mchRegsBase)
+ goto out_err;
+
+ /*
+ * Get the gpio bar.
+ */
+
+ curTag = pciFindFirst((VML_CR_DEVICE_LPC << 16) | PCI_VENDOR_INTEL,
+ 0xffffffff);
+ if (curTag != lpcTag) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not find Carillo Ranch "
+ "LPC device.\n");
+ goto out_err;
+ }
+
+ devEn = pciReadByte(lpcTag, VML_CR_REG_GPIOEN);
+ if (!(devEn & VML_CR_GPIOEN_BIT)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Carillo Ranch GPIO "
+ "was not enabled.\n");
+ goto out_err;
+ }
+
+ crSys->gpioBAR = (CARD32) pciReadLong(lpcTag, VML_CR_REG_GPIOBAR) & ~0x3F;
+ return crSys;
+
+ out_err:
+
+ if (crSys->mchRegsBase)
+ xf86UnMapVidMem(crSys->pScrn->scrnIndex, crSys->mchRegsBase,
+ VML_CR_MCHMAP_SIZE);
+
+ free(crSys);
+ return NULL;
+}
+
+static void
+VERMILIONCRSysDestroy(VERMILIONSys * sys)
+{
+ CRSys *crSys = (CRSys *) sys->priv;
+
+ if (crSys->mchRegsBase)
+ xf86UnMapVidMem(crSys->pScrn->scrnIndex, crSys->mchRegsBase,
+ VML_CR_MCHMAP_SIZE);
+
+ free(crSys);
+ free(sys);
+}
+
+static void
+VERMILIONCRPanelOn(const VERMILIONSys * sys)
+{
+ CRSys *crSys = (CRSys *) sys->priv;
+ CARD32 addr = crSys->gpioBAR + VML_CR_PANEL_PORT;
+ CARD32 cur = inl(addr);
+
+ if (!(cur & VML_CR_PANEL_ON)) {
+ /* Make sure LVDS controller is down. */
+ if (cur & 0x00000001) {
+ cur &= ~VML_CR_LVDS_ON;
+ outl(addr, cur);
+ }
+ /* Power up Panel */
+ usleep(100000);
+ cur |= VML_CR_PANEL_ON;
+ outl(addr, cur);
+ }
+
+ /* Power up LVDS controller */
+
+ if (!(cur & VML_CR_LVDS_ON)) {
+ usleep(100000);
+ outl(addr, cur | VML_CR_LVDS_ON);
+ }
+}
+
+void
+VERMILIONCRPanelOff(const VERMILIONSys * sys)
+{
+ CRSys *crSys = (CRSys *) sys->priv;
+ CARD32 addr = crSys->gpioBAR + VML_CR_PANEL_PORT;
+ CARD32 cur = inl(addr);
+
+ /* Power down LVDS controller first to avoid high currents */
+ if (cur & VML_CR_LVDS_ON) {
+ cur &= ~VML_CR_LVDS_ON;
+ outl(addr, cur);
+ }
+ if (cur & VML_CR_PANEL_ON) {
+ usleep(100000);
+ outl(addr, cur & ~VML_CR_PANEL_ON);
+ }
+}
+
+void
+VERMILIONCRBacklightOn(const VERMILIONSys * sys)
+{
+ CRSys *crSys = (CRSys *) sys->priv;
+ CARD32 addr = crSys->gpioBAR + VML_CR_PANEL_PORT;
+ CARD32 cur = inl(addr);
+
+ if (cur & VML_CR_BACKLIGHT_OFF) {
+ cur &= ~VML_CR_BACKLIGHT_OFF;
+ outl(addr, cur);
+ }
+}
+
+void
+VERMILIONCRBacklightOff(const VERMILIONSys * sys)
+{
+ CRSys *crSys = (CRSys *) sys->priv;
+ CARD32 addr = crSys->gpioBAR + VML_CR_PANEL_PORT;
+ CARD32 cur = inl(addr);
+
+ if (!(cur & VML_CR_BACKLIGHT_OFF)) {
+ cur |= VML_CR_BACKLIGHT_OFF;
+ outl(addr, cur);
+ }
+}
+
+static Bool
+VERMILIONCRSysRestore(VERMILIONSys * sys)
+{
+ CRSys *crSys = (CRSys *) sys->priv;
+ volatile CARD32 *clockReg = (volatile CARD32 *)
+ (crSys->mchRegsBase + VML_CR_REG_CLOCK);
+
+ CARD32 cur = crSys->savedPanelState;
+
+ if (cur & VML_CR_BACKLIGHT_OFF) {
+ VERMILIONCRBacklightOff(sys);
+ } else {
+ VERMILIONCRBacklightOn(sys);
+ }
+
+ if (cur & VML_CR_PANEL_ON) {
+ VERMILIONCRPanelOn(sys);
+ } else {
+ VERMILIONCRPanelOff(sys);
+ if (cur & VML_CR_LVDS_ON) {
+ ;
+ /* Will not power up LVDS controller while panel is off */
+ }
+ }
+
+ *clockReg = crSys->savedClock;
+ (void)*clockReg;
+
+ return TRUE;
+}
+
+static Bool
+VERMILIONCRSysSave(VERMILIONSys * sys)
+{
+ CRSys *crSys = (CRSys *) sys->priv;
+ volatile CARD32 *clockReg = (volatile CARD32 *)
+ (crSys->mchRegsBase + VML_CR_REG_CLOCK);
+
+ crSys->savedPanelState = inl(crSys->gpioBAR + VML_CR_PANEL_PORT);
+ crSys->savedClock = *clockReg;
+
+ return TRUE;
+}
+
+static Bool
+VERMILIONCRSetClock(VERMILIONSys * sys, int clock)
+{
+ CRSys *crSys = (CRSys *) sys->priv;
+ volatile CARD32 *clockReg = (volatile CARD32 *)
+ (crSys->mchRegsBase + VML_CR_REG_CLOCK);
+ int index;
+ CARD32 clockVal;
+
+ index = xf86GetNearestClock(crSys->pScrn, clock, FALSE, 1, 1, NULL);
+ if (vermilionCRClocks[index] != clock)
+ return FALSE;
+
+ clockVal = *clockReg & ~VML_CR_CLOCK_MASK;
+ clockVal = vermilionCRClockBits[index] << VML_CR_CLOCK_SHIFT;
+ *clockReg = clockVal;
+ (void)*clockReg;
+
+ return TRUE;
+}
+
+static void
+VERMILIONCRClocks(const VERMILIONSys * sys, int *numClocks, int clocks[])
+{
+ unsigned i;
+
+ *numClocks = vermilionCRNumClocks;
+ for (i = 0; i < vermilionCRNumClocks; ++i) {
+ clocks[i] = vermilionCRClocks[i];
+ }
+}
+
+/*
+*********************Generic functions******************************
+*/
+
+static void
+VERMILIONGenericSubSys(VERMILIONSys * sys, char const **name,
+ unsigned *id0, unsigned *id1)
+{
+ VERMILIONSubSystem *subSys = &vSystems[(VERMILIONSysID) sys->id];
+
+ *name = subSys->sysName;
+ *id0 = subSys->subsys0;
+ *id1 = subSys->subsys1;
+}
+
+static Bool
+VERMILIONFalse(VERMILIONSys * sys)
+{
+ return FALSE;
+}
+
+static int
+VERMILIONPanel0(const VERMILIONSys * sys)
+{
+ return 0;
+}
+
+static void
+VERMILIONGenericClockRanges(const VERMILIONSys * sys, int *low, int *high)
+{
+ *low = 6500;
+ *high = 120000;
+}
+
+VERMILIONSys *
+VERMILIONCreateSys(ScrnInfoPtr pScrn)
+{
+ VERMILIONSys *sys;
+ VERMILIONSysID sysID;
+
+ sys = (VERMILIONSys *) malloc(sizeof(*sys));
+ if (!sys)
+ goto out_error;
+
+ /*
+ * Add a smart way to detect board id here.
+ */
+
+ sysID = carilloRanch;
+
+ sys->id = (int)sysID;
+ switch (sysID) {
+ case carilloRanch:
+ sys->priv = VERMILIONCRInit(pScrn);
+ if (!sys->priv)
+ goto out_error;
+
+ sys->subSys = VERMILIONGenericSubSys;
+ sys->save = VERMILIONCRSysSave;
+ sys->restore = VERMILIONCRSysRestore;
+ sys->destroy = VERMILIONCRSysDestroy;
+ sys->progClock = VERMILIONFalse;
+ sys->clockRanges = VERMILIONGenericClockRanges;
+ sys->clocks = VERMILIONCRClocks;
+ sys->setClock = VERMILIONCRSetClock;
+ sys->panel = VERMILIONPanel0;
+ sys->panelOn = VERMILIONCRPanelOn;
+ sys->panelOff = VERMILIONCRPanelOff;
+ sys->backlightOn = VERMILIONCRBacklightOn;
+ sys->backlightOff = VERMILIONCRBacklightOff;
+ break;
+ default:
+ goto out_error;
+ }
+
+ return sys;
+
+ out_error:
+ if (sys)
+ free(sys);
+ return NULL;
+}
diff --git a/src/vermilion_sys.h b/src/vermilion_sys.h
new file mode 100644
index 0000000..a8680c5
--- /dev/null
+++ b/src/vermilion_sys.h
@@ -0,0 +1,87 @@
+/**************************************************************************
+ *
+ * Copyright (c) Intel Corp. 2007.
+ * All Rights Reserved.
+ *
+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ * develop this driver.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors:
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ */
+
+#ifndef _VERMILION_SYS_H_
+#define _VERMILION_SYS_H_
+
+struct _VERMILIONSysPriv;
+
+typedef struct _VERMILIONSys
+{
+
+ /*
+ * Subsystem identifier:
+ */
+
+ void (*subSys) (struct _VERMILIONSys * sys,
+ const char **name, unsigned *id0, unsigned *id1);
+ /*
+ * Save / Restore;
+ */
+
+ int (*save) (struct _VERMILIONSys * sys);
+ int (*restore) (struct _VERMILIONSys * sys);
+
+ /*
+ * PLL programming;
+ */
+
+ void (*destroy) (struct _VERMILIONSys * sys);
+ Bool(*progClock) (struct _VERMILIONSys * sys);
+ void (*clockRanges) (const struct _VERMILIONSys * sys, int *low,
+ int *high);
+ void (*clocks) (const struct _VERMILIONSys * sys, int *numClocks,
+ int clocks[]);
+ Bool(*setClock) (struct _VERMILIONSys * sys, int clock);
+
+ /*
+ * Panel type and functions.
+ */
+
+ int (*panel) (const struct _VERMILIONSys * sys);
+ void (*panelOn) (const struct _VERMILIONSys * sys);
+ void (*panelOff) (const struct _VERMILIONSys * sys);
+ void (*backlightOn) (const struct _VERMILIONSys * sys);
+ void (*backlightOff) (const struct _VERMILIONSys * sys);
+
+ /*
+ * Private information.
+ */
+ int id;
+ pointer *priv;
+} VERMILIONSys;
+
+VERMILIONSys *VERMILIONCreateSys(ScrnInfoPtr pScrn);
+
+#endif