summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:55 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:55 +0000
commitb1d44d56b82021cf73fb3449faa9ddc4efd72a87 (patch)
treec69cdc593e0eb6e11d9f4b753c619ddd84a993ad
Initial revision
-rw-r--r--man/trident.man125
-rw-r--r--src/blade_accel.c704
-rw-r--r--src/image_accel.c647
-rw-r--r--src/trident.h346
-rw-r--r--src/trident_accel.c673
-rw-r--r--src/trident_bank.c95
-rw-r--r--src/trident_dac.c1200
-rw-r--r--src/trident_dga.c275
-rw-r--r--src/trident_driver.c3632
-rw-r--r--src/trident_i2c.c77
-rw-r--r--src/trident_regs.h395
-rw-r--r--src/trident_shadow.c260
-rw-r--r--src/trident_video.c1408
-rw-r--r--src/tridenthelper.c341
-rw-r--r--src/tridentramdac.c67
-rw-r--r--src/tvga_dac.c231
-rw-r--r--src/xp_accel.c601
17 files changed, 11077 insertions, 0 deletions
diff --git a/man/trident.man b/man/trident.man
new file mode 100644
index 0000000..a02fa43
--- /dev/null
+++ b/man/trident.man
@@ -0,0 +1,125 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident.man,v 1.12 2003/01/06 10:15:26 alanh Exp $
+.\" shorthand for double quote that works everywhere.
+.ds q \N'34'
+.TH TRIDENT __drivermansuffix__ __vendorversion__
+.SH NAME
+trident \- Trident video driver
+.SH SYNOPSIS
+.nf
+.B "Section \*qDevice\*q"
+.BI " Identifier \*q" devname \*q
+.B " Driver \*qtrident\*q"
+\ \ ...
+.B EndSection
+.fi
+.SH DESCRIPTION
+.B trident
+is an XFree86 driver for Trident video cards. The driver is
+accelerated, and provides support for the following framebuffer depths:
+1, 4, 8, 15, 16, and 24. Multi-head configurations are supported.
+The XvImage extension is supported on TGUI96xx and greater cards.
+.SH SUPPORTED HARDWARE
+The
+.B trident
+driver supports PCI,AGP and ISA video cards based on the following
+Trident chips:
+.TP 12
+.B Blade
+Blade3D, CyberBlade series i1, i7 (DSTN), i1, i1 (DSTN), Ai1, Ai1 (DSTN),
+CyberBlade/e4, CyberBladeXP, CyberBladeAi1/XP, BladeXP
+.TP 12
+.B Image
+3DImage975, 3DImage985, Cyber9520, Cyber9525, Cyber9397, Cyber9397DVD
+.TP 12
+.B ProVidia
+9682, 9685, Cyber9382, Cyber9385, Cyber9388
+.TP 12
+.B TGUI
+9440AGi, 9660, 9680
+.TP 12
+.B ISA/VLBus
+8900C, 8900D, 9000, 9200CXr, Cyber9320, 9400CXi, 9440AGi
+These cards have been ported but need furthur testing and may not work.
+.SH CONFIGURATION DETAILS
+Please refer to XF86Config(__filemansuffix__) for general configuration
+details. This section only covers configuration details specific to this
+driver.
+.PP
+The following driver
+.B Options
+are supported:
+.TP
+.BI "Option \*qSWCursor\*q \*q" boolean \*q
+Enable or disable the SW cursor. Default: off.
+.TP
+.BI "Option \*qNoAccel\*q \*q" boolean \*q
+Disable or enable acceleration. Default: acceleration is enabled.
+.TP
+.BI "Option \*qPciRetry\*q \*q" boolean \*q
+Enable or disable PCI retries. Default: off.
+.TP
+.BI "Option \*qCyberShadow\*q \*q" boolean \*q
+For Cyber chipsets only, turn off shadow registers. If you only see
+a partial display - this may be the option for you. Default: on.
+.TP
+.BI "Option \*qCyberStretch\*q \*q" boolean \*q
+For Cyber chipsets only, turn on stretching. When the resolution is lower
+than the LCD's screen, this option will stretch the graphics mode to
+fill the entire LCD. Default: off.
+.TP
+.BI "Option \*qShadowFB\*q \*q" boolean \*q
+Enable or disable use of the shadow framebuffer layer. Default: off.
+.TP
+.BI "Option \*qVideoKey\*q \*q" integer \*q
+This sets the default pixel value for the YUV video overlay key.
+Default: undefined.
+.TP
+.BI "Option \*qNoPciBurst\*q \*q" boolean \*q
+Turn off PCI burst mode, PCI Bursting is on by default.
+Default: off.
+.TP
+.BI "Option \*qXvHsync\*q \*q" integer \*q
+Override the default Horizontal-sync value for the Xv extension.
+This is used to center the Xv image on the screen. By default the values
+are assigned based on the video card.
+Default: 0.
+.TP
+.BI "Option \*qXvVsync\*q \*q" integer \*q
+Override the default Vertical-sync value for the Xv extension.
+This is used to center the Xv image on the screen. By default the values
+are assigned based on the video card.
+Default: 0.
+.TP
+.BI "Option \*qXvBskew\*q \*q" integer \*q
+Override the default Bottom skew value for the Xv extension.
+This is used to extend the Xv image on the screen at the bottom. By
+default the values are assigned based on the video card.
+Default: 0.
+.TP
+.BI "Option \*qXvRskew\*q \*q" integer \*q
+Override the default Right skew value for the Xv extension.
+This is used to extend the Xv image on the screen at the right. By
+default the values are assigned based on the video card.
+Default: 0.
+.TP
+.BI "Option \*qDisplay\*q \*q" string \*q
+Override the display.
+Possible values are \*qCRT\*q, \*qLCD\*q and \*qDual\*q.
+Please note that this option is only experimentally.
+Default: Use display active when X started.
+.TP
+.BI "Option \*qDisplay1400\*q \*q" boolean \*q
+Inform driver to expect 1400x1050 display instead of a 1280x1024.
+Default: off.
+.TP
+.BI "Option \*qGammaBrightness\*q \*q" string \*q
+Set display gamma value and brightness. \*q\fIstring\fP\*q is
+\*q\fIgamma\fP, \fIbrightness\fP\*q, where \fIgamma\fP is a floating
+point value greater than 0 and less or equal to 10. \fIbrightness\fP is
+an integer value greater or equal to 0 and less than 128.
+Default: gamma and brightness control is turned off.
+Note: This is not supported on all chipsets.
+.SH "SEE ALSO"
+XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__)
+.SH AUTHOR
+Author: Alan Hourihane
diff --git a/src/blade_accel.c b/src/blade_accel.c
new file mode 100644
index 0000000..e76860d
--- /dev/null
+++ b/src/blade_accel.c
@@ -0,0 +1,704 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane, Wigan, England.
+ *
+ * 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, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * Trident Blade3D accelerated options.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/blade_accel.c,v 1.18 2002/10/08 22:14:11 tsi Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "miline.h"
+
+#include "trident.h"
+#include "trident_regs.h"
+
+#include "xaarop.h"
+#include "xaalocal.h"
+
+static void BladeSync(ScrnInfoPtr pScrn);
+#if 0
+static void BladeSetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void BladeSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e,
+ int len, int octant);
+static void BladeSubsequentSolidTwoPointLine( ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int flags);
+static void BladeSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg,
+ int rop, unsigned int planemask, int length,
+ unsigned char *pattern);
+static void BladeSubsequentDashedTwoPointLine( ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int flags,
+ int phase);
+#endif
+static void BladeSetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void BladeSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h);
+static void BladeSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2,
+ int y2, int w, int h);
+static void BladeSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask,
+ int transparency_color);
+#if 0
+static void BladeSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void BladeSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int srcx, int srcy,
+ int offset);
+#endif
+static void BladeSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void BladeSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft);
+static void BladeSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2);
+static void BladeDisableClipping(ScrnInfoPtr pScrn);
+static void BladeSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int fg, int bg,
+ int rop, unsigned int planemask);
+static void BladeSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int x, int y,
+ int w, int h);
+#if 0
+static void BladeSetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int rop, unsigned int planemask, int trans_col);
+static void BladeSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int x, int y,
+ int w, int h);
+#endif
+static void BladeSetupForImageWrite(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int transparency_color,
+ int bpp, int depth);
+static void BladeSubsequentImageWriteRect(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h, int skipleft);
+
+static void
+BladeInitializeAccelerator(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ CARD32 stride;
+
+ stride = (pScrn->displayWidth >> 3) << 20;
+
+ BLADE_OUT(0x21C8, stride);
+ BLADE_OUT(0x21CC, stride);
+ BLADE_OUT(0x21D0, stride);
+ BLADE_OUT(0x21D4, stride);
+ switch (pScrn->depth) {
+ case 8:
+ stride |= 0<<29;
+ break;
+ case 15:
+ stride |= 5<<29;
+ break;
+ case 16:
+ stride |= 1<<29;
+ break;
+ case 24:
+ stride |= 2<<29;
+ break;
+ }
+ BLADE_OUT(0x21B8, 0);
+ BLADE_OUT(0x21B8, stride);
+ BLADE_OUT(0x21BC, stride);
+ BLADE_OUT(0x21C0, stride);
+ BLADE_OUT(0x21C4, stride);
+#if 0
+ /* It appears that the driver sometimes misdetects the RAM type, so we
+ * don't force this for now */
+ if (pTrident->HasSGRAM)
+ BLADE_OUT(0x2168, 1<<26); /* Enables Block Write if available (SGRAM) */
+ else
+ BLADE_OUT(0x2168, 0);
+#endif
+ BLADE_OUT(0x216C, 0);
+}
+
+Bool
+BladeAccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ BoxRec AvailFBArea;
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = (pTrident->FbMapSize - 4096) / (pScrn->displayWidth *
+ pScrn->bitsPerPixel / 8);
+ if (AvailFBArea.y2 > 2047) AvailFBArea.y2 = 2047;
+
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ if (pTrident->NoAccel)
+ return FALSE;
+
+ pTrident->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if (!infoPtr) return FALSE;
+
+ pTrident->InitializeAccelerator = BladeInitializeAccelerator;
+ BladeInitializeAccelerator(pScrn);
+
+ infoPtr->Flags = PIXMAP_CACHE |
+ LINEAR_FRAMEBUFFER |
+ OFFSCREEN_PIXMAPS;
+
+ infoPtr->Sync = BladeSync;
+
+ infoPtr->SetClippingRectangle = BladeSetClippingRectangle;
+ infoPtr->DisableClipping = BladeDisableClipping;
+
+#if 0
+ infoPtr->SolidLineFlags = 0;
+ infoPtr->SetupForSolidLine = BladeSetupForSolidLine;
+ infoPtr->SubsequentSolidTwoPointLine = BladeSubsequentSolidTwoPointLine;
+ infoPtr->SetupForDashedLine = BladeSetupForDashedLine;
+ infoPtr->SubsequentDashedTwoPointLine = BladeSubsequentDashedTwoPointLine;
+ infoPtr->DashPatternMaxLength = 16;
+ infoPtr->DashedLineFlags = LINE_PATTERN_LSBFIRST_LSBJUSTIFIED |
+ LINE_PATTERN_POWER_OF_2_ONLY;
+#endif
+
+ infoPtr->SolidFillFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidFill = BladeSetupForFillRectSolid;
+ infoPtr->SubsequentSolidFillRect = BladeSubsequentFillRectSolid;
+
+ infoPtr->ScreenToScreenCopyFlags = ONLY_TWO_BITBLT_DIRECTIONS |
+ NO_PLANEMASK |
+ NO_TRANSPARENCY;
+
+ infoPtr->SetupForScreenToScreenCopy =
+ BladeSetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy =
+ BladeSubsequentScreenToScreenCopy;
+
+ infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | NO_TRANSPARENCY |
+ BIT_ORDER_IN_BYTE_MSBFIRST |
+ HARDWARE_PATTERN_SCREEN_ORIGIN |
+ HARDWARE_PATTERN_PROGRAMMED_BITS;
+
+ infoPtr->SetupForMono8x8PatternFill =
+ BladeSetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ BladeSubsequentMono8x8PatternFillRect;
+
+#if 0
+ infoPtr->Color8x8PatternFillFlags =
+ HARDWARE_PATTERN_SCREEN_ORIGIN |
+ BIT_ORDER_IN_BYTE_MSBFIRST;
+
+ infoPtr->SetupForColor8x8PatternFill =
+ TridentSetupForColor8x8PatternFill;
+ infoPtr->SubsequentColor8x8PatternFillRect =
+ TridentSubsequentColor8x8PatternFillRect;
+
+ infoPtr->ScreenToScreenColorExpandFillFlags = 0;
+
+ infoPtr->SetupForScreenToScreenColorExpandFill =
+ BladeSetupForScreenToScreenColorExpand;
+ infoPtr->SubsequentScreenToScreenColorExpandFill =
+ BladeSubsequentScreenToScreenColorExpand;
+#endif
+
+ infoPtr->CPUToScreenColorExpandFillFlags = CPU_TRANSFER_PAD_DWORD |
+ LEFT_EDGE_CLIPPING |
+ SYNC_AFTER_COLOR_EXPAND |
+ NO_PLANEMASK |
+ BIT_ORDER_IN_BYTE_MSBFIRST |
+ SCANLINE_PAD_DWORD;
+ infoPtr->ColorExpandRange = 0x10000;
+ infoPtr->ColorExpandBase = pTrident->IOBase + 0x10000;
+ infoPtr->SetupForCPUToScreenColorExpandFill =
+ BladeSetupForCPUToScreenColorExpand;
+ infoPtr->SubsequentCPUToScreenColorExpandFill =
+ BladeSubsequentCPUToScreenColorExpand;
+
+ infoPtr->SetupForImageWrite = BladeSetupForImageWrite;
+ infoPtr->SubsequentImageWriteRect =
+ BladeSubsequentImageWriteRect;
+ infoPtr->ImageWriteFlags = NO_PLANEMASK |
+ LEFT_EDGE_CLIPPING |
+ CPU_TRANSFER_PAD_DWORD |
+ SYNC_AFTER_IMAGE_WRITE;
+ infoPtr->ImageWriteBase = pTrident->IOBase + 0x10000;
+ infoPtr->ImageWriteRange = 0x10000;
+
+ return(XAAInit(pScreen, infoPtr));
+}
+
+static void
+BladeSync(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int busy;
+ int cnt = 10000000;
+
+ if (pTrident->Clipping) BladeDisableClipping(pScrn);
+ BLADE_OUT(0x216C, 0);
+
+ BLADEBUSY(busy);
+ while (busy != 0) {
+ if (--cnt < 0) {
+ ErrorF("GE timeout\n");
+ BLADE_OUT(0x2124, 1<<7);
+ BLADE_OUT(0x2124, 0);
+ break;
+ }
+ BLADEBUSY(busy);
+ }
+}
+
+static void
+BladeSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask, int transparency_color)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ pTrident->BltScanDirection = 0;
+ if ((xdir < 0) || (ydir < 0)) pTrident->BltScanDirection |= 1<<1;
+
+#if 0
+ if (transparency_color != -1) {
+ BLADE_OUT(0x2168, transparency_color & 0xffffff);
+ pTrident->BltScanDirection |= 1<<6;
+ }
+#endif
+
+ REPLICATE(planemask);
+ if (planemask != -1) {
+ BLADE_OUT(0x2184, ~planemask);
+ pTrident->BltScanDirection |= 1<<5;
+ }
+ BLADE_OUT(0x2148, XAACopyROP[rop]);
+}
+
+static void
+BladeSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int clip = 0;
+
+ if (pTrident->Clipping) clip = 1;
+
+ BLADE_OUT(0x2144, 0xE0000000 | 1<<19 | 1<<4 | 1<<2 | pTrident->BltScanDirection | clip);
+
+ if (pTrident->BltScanDirection) {
+ BLADE_OUT(0x2100, (y1+h-1)<<16 | (x1+w-1));
+ BLADE_OUT(0x2104, y1<<16 | x1);
+ BLADE_OUT(0x2108, (y2+h-1)<<16 | (x2+w-1));
+ BLADE_OUT(0x210C, (y2&0xfff)<<16 | (x2&0xfff));
+ } else {
+ BLADE_OUT(0x2100, y1<<16 | x1);
+ BLADE_OUT(0x2104, (y1+h-1)<<16 | (x1+w-1));
+ BLADE_OUT(0x2108, y2<<16 | x2);
+ BLADE_OUT(0x210C, ((y2+h-1)&0xfff)<<16 | ((x2+w-1)&0xfff));
+ }
+}
+
+static void
+BladeSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ BLADE_OUT(0x2154, (y1&0x0fff)<<16 | (x1&0x0fff));
+ BLADE_OUT(0x2158, (y2&0x0fff)<<16 | (x2&0x0fff));
+ pTrident->Clipping = TRUE;
+}
+
+static void
+BladeDisableClipping(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ pTrident->Clipping = FALSE;
+}
+
+#if 0
+static void
+BladeSetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ REPLICATE(color);
+ BLADE_OUT(0x2160, color);
+ BLADE_OUT(0x2148, XAACopyROP[rop]);
+ pTrident->BltScanDirection = 0;
+ REPLICATE(planemask);
+ if (planemask != -1) {
+ BLADE_OUT(0x2184, ~planemask);
+ pTrident->BltScanDirection |= 1<<5;
+ }
+}
+
+static void
+BladeSubsequentSolidBresenhamLine( ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e, int len, int octant)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int tmp;
+ int D = 0, E = 0, ymajor = 0;
+
+
+ BLADE_OUT(0x2144, 0x20000000 | 3<<19 | 1<<4 | 2<<2 | (pTrident->Clipping ? 1: 0));
+
+ if (!(octant & YMAJOR)) {
+ if ((!(octant&XDECREASING)) && (!(octant&YDECREASING))) {E = 1; D = 0;}
+ if ((!(octant&XDECREASING)) && ( (octant&YDECREASING))) {E = 1; D = 1;}
+ if (( (octant&XDECREASING)) && (!(octant&YDECREASING))) {E = 1; D = 2;}
+ if (( (octant&XDECREASING)) && ( (octant&YDECREASING))) {E = 1; D = 3;}
+ ymajor = 0;
+ } else {
+ if ((!(octant&XDECREASING)) && (!(octant&YDECREASING))) {E = 0; D = 0;}
+ if ((!(octant&XDECREASING)) && ( (octant&YDECREASING))) {E = 0; D = 2;}
+ if (( (octant&XDECREASING)) && (!(octant&YDECREASING))) {E = 0; D = 1;}
+ if (( (octant&XDECREASING)) && ( (octant&YDECREASING))) {E = 0; D = 3;}
+ ymajor = 1<<21;
+ }
+
+ if (E) {
+ tmp = x; x = y; y = tmp;
+ }
+ BLADE_OUT(0x2130, 0x00000001);
+ if (D&0x02) {
+ BLADE_OUT(0x213C, 0x10000000 | 1<<25 | 1<<19 | 1<<17 | ymajor | ((x+len-1)<<4));
+ } else {
+ BLADE_OUT(0x213C, 0x10000000 | 1<<25 | 1<<19 | 1<<17 | ymajor | ((y+len-1)<<4));
+ }
+ BLADE_OUT(0x2140, E<<30 | (y&0xfff)<<20 | ((x&0xfff)<<4));
+ BLADE_OUT(0x2144, D<<30 | (((dmaj-dmin)&0xfff) << 16) | (-dmin&0xfff));
+ BLADE_OUT(0x2148, ((-(dmin+e)&0xfff) << 16));
+}
+
+static void
+BladeSubsequentSolidTwoPointLine( ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int flags)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+#if 0
+ if (flags & OMIT_LAST)
+ BladeSetClippingRectangle(pScrn,x1,y1,x2-1,y2-1);
+#endif
+
+ BLADE_OUT(0x2144, 0x20000000 | pTrident->BltScanDirection | 1<<19 | 1<<4 | 2<<2);
+ BLADE_OUT(0x2130, 0x3);
+ BLADE_OUT(0x2108, y1<<16 | x1);
+ BLADE_OUT(0x210C, (y2&0xfff)<<16 | (x2&0xfff));
+
+#if 0
+ if (flags & OMIT_LAST)
+ BladeDisableClipping(pScrn);
+#endif
+}
+
+static void
+BladeSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int length, unsigned char *pattern)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ pTrident->LinePattern = *((CARD16 *)pattern) & ((1<<length) - 1);
+ switch (length) {
+ case 2:
+ pTrident->LinePattern = pTrident->LinePattern | (pTrident->LinePattern << 2);
+ case 4:
+ pTrident->LinePattern = pTrident->LinePattern | (pTrident->LinePattern << 4);
+ case 8:
+ pTrident->LinePattern = pTrident->LinePattern | (pTrident->LinePattern << 8);
+ }
+
+ REPLICATE(fg);
+ REPLICATE(bg);
+ BLADE_OUT(0x2160, fg);
+ BLADE_OUT(0x2164, bg);
+ BLADE_OUT(0x2148, XAACopyROP[rop]);
+ pTrident->BltScanDirection = 0;
+ REPLICATE(planemask);
+ if (planemask != -1) {
+ BLADE_OUT(0x2184, ~planemask);
+ pTrident->BltScanDirection |= 1<<5;
+ }
+}
+
+static void
+BladeSubsequentDashedTwoPointLine( ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int flags, int phase)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if (flags & OMIT_LAST)
+ BladeSetClippingRectangle(pScrn,x1,y1,x2-1,y2-1);
+
+ BLADE_OUT(0x216C, (pTrident->LinePattern >> phase) | (pTrident->LinePattern << (16-phase)));
+ BLADE_OUT(0x2144, 0x20000000 | pTrident->BltScanDirection | 1<<27 | 1<<19 | 1<<4 | 2<<2);
+ BLADE_OUT(0x2108, y1<<16 | x1);
+ BLADE_OUT(0x210C, (y2&0xfff)<<16 | (x2&0xfff));
+
+ if (flags & OMIT_LAST)
+ BladeDisableClipping(pScrn);
+}
+#endif
+
+static void
+BladeSetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ REPLICATE(color);
+ BLADE_OUT(0x2160, color);
+ BLADE_OUT(0x2148, XAACopyROP[rop]);
+ pTrident->BltScanDirection = 0;
+ REPLICATE(planemask);
+ if (planemask != -1) {
+ BLADE_OUT(0x2184, ~planemask);
+ pTrident->BltScanDirection |= 1<<5;
+ }
+}
+
+static void
+BladeSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ BLADE_OUT(0x2144, 0x20000000 | pTrident->BltScanDirection | 1<<19 | 1<<4 | 2<<2 | (pTrident->Clipping ? 1:0));
+ BLADE_OUT(0x2108, y<<16 | x);
+ BLADE_OUT(0x210C, ((y+h-1)&0xfff)<<16 | ((x+w-1)&0xfff));
+}
+
+#if 0
+static void
+BladeSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ pTrident->ROP = rop;
+
+ REPLICATE(bg);
+ REPLICATE(fg);
+ IMAGE_OUT(0x44, fg);
+ IMAGE_OUT(0x48, bg);
+ IMAGE_OUT(0x20, 0x90000000 | XAACopyROP[rop]);
+ pTrident->BltScanDirection = 0;
+ REPLICATE(planemask);
+ if (planemask != -1) {
+ BLADE_OUT(0x2184, ~planemask);
+ pTrident->BltScanDirection |= 1<<5;
+ }
+}
+
+static void
+BladeSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int srcx, int srcy, int offset)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ IMAGE_OUT(0x00, srcy<<16 | srcx);
+ IMAGE_OUT(0x04, (srcy+h-1)<<16 | (srcx+w-1));
+ IMAGE_OUT(0x08, y<<16 | x);
+ IMAGE_OUT(0x0C, (y+h-1)<<16 | (x+w-1));
+
+ IMAGE_OUT(0x24, 0x80000000 | 3<<22 | 1<<7 | pTrident->BltScanDirection | (pTrident->ROP == GXcopy ? 0 : 1<<10) | offset<<25);
+}
+#endif
+
+static void
+BladeSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ pTrident->BltScanDirection = 0;
+ BLADE_OUT(0x2148, XAACopyROP[rop]);
+ if (bg == -1) {
+ pTrident->BltScanDirection |= 2<<19;
+ REPLICATE(fg);
+ BLADE_OUT(0x2160, fg);
+ BLADE_OUT(0x2164, ~fg);
+ } else {
+ pTrident->BltScanDirection |= 3<<19;
+ REPLICATE(fg);
+ REPLICATE(bg);
+ BLADE_OUT(0x2160, fg);
+ BLADE_OUT(0x2164, bg);
+ }
+ REPLICATE(planemask);
+ if (planemask != -1) {
+ BLADE_OUT(0x2184, ~planemask);
+ pTrident->BltScanDirection |= 1<<5;
+ }
+}
+
+static void
+BladeSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if (skipleft) BladeSetClippingRectangle(pScrn,x+skipleft,y,(x+w-1),(y+h-1));
+ BLADE_OUT(0x2144, 0xE0000000 | pTrident->BltScanDirection | 1<<4 | (skipleft ? 1 : 0));
+ BLADE_OUT(0x2108, (y&0xfff)<<16 | (x&0xfff));
+ BLADE_OUT(0x210C, ((y+h-1)&0xfff)<<16 | ((x+w-1)&0xfff));
+}
+
+static void
+BladeSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ BladeSync(pScrn);
+ BLADE_OUT(0x2148, XAAPatternROP[rop]);
+
+ if (bg == -1) {
+ REPLICATE(fg);
+ BLADE_OUT(0x216C, 0x80000000 | 1<<30);
+ BLADE_OUT(0x216C, 0x80000000 | 1<<28 | 1<<30);
+ BLADE_OUT(0x2170, patternx);
+ BLADE_OUT(0x2170, patterny);
+ BLADE_OUT(0x2174, fg);
+#if 0
+ BLADE_OUT(0x2178, ~fg);
+#endif
+ } else {
+ REPLICATE(fg);
+ REPLICATE(bg);
+ BLADE_OUT(0x216C, 0x80000000);
+ BLADE_OUT(0x216C, 0x80000000 | 1<<28);
+ BLADE_OUT(0x2170, patternx);
+ BLADE_OUT(0x2170, patterny);
+ BLADE_OUT(0x2174, fg);
+ BLADE_OUT(0x2178, bg);
+ }
+ pTrident->BltScanDirection = 0;
+ REPLICATE(planemask);
+ if (planemask != -1) {
+ BLADE_OUT(0x2184, ~planemask);
+ pTrident->BltScanDirection |= 1<<5;
+ }
+}
+
+static void
+BladeSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int x, int y,
+ int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int clip = 0;
+
+ if (pTrident->Clipping) clip = 1;
+ BLADE_OUT(0x2144, 0x20000000 | pTrident->BltScanDirection | 7<<12 | 1<<4 | 1<<19 | 2<<2 | clip);
+ BLADE_OUT(0x2108, y<<16 | x);
+ BLADE_OUT(0x210C, ((y+h-1)&0xfff)<<16 | ((x+w-1)&0xfff));
+}
+
+#if 0
+static void
+BladeSetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int rop,
+ unsigned int planemask,
+ int transparency_color)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ TGUI_PATLOC(((patterny * pScrn->displayWidth * pScrn->bitsPerPixel / 8) +
+ (patternx * pScrn->bitsPerPixel / 8)) >> 6);
+ pTrident->BltScanDirection = 0;
+ if (transparency_color != -1) {
+ BLADE_OUT(0x2168, transparency_color & 0xffffff);
+ pTrident->BltScanDirection |= 1<<6;
+ }
+ TGUI_FMIX(XAAPatternROP[rop]);
+ REPLICATE(planemask);
+ if (planemask != -1) {
+ BLADE_OUT(0x2184, ~planemask);
+ pTrident->BltScanDirection |= 1<<5;
+ }
+}
+
+static void
+BladeSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int x, int y,
+ int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ TGUI_DEST_XY(x,y);
+ TGUI_DIM_XY(w,h);
+ TGUI_COMMAND(GE_BLT);
+ CHECKCLIPPING;
+}
+#endif
+
+static void BladeSetupForImageWrite(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ BLADE_OUT(0x2148, XAACopyROP[rop]);
+ pTrident->BltScanDirection = 0;
+ REPLICATE(planemask);
+ if (planemask != -1) {
+ BLADE_OUT(0x2184, ~planemask);
+ pTrident->BltScanDirection |= 1<<5;
+ }
+}
+
+static void BladeSubsequentImageWriteRect(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if (skipleft) BladeSetClippingRectangle(pScrn,x+skipleft,y,(x+w-1),(y+h-1));
+ BLADE_OUT(0x2144, 0xE0000000 | 1<<19 | 1<<4 | pTrident->BltScanDirection | (skipleft ? 1 : 0));
+ BLADE_OUT(0x2108, y<<16 | (x&0xfff));
+ BLADE_OUT(0x210C, ((y+h-1)&0xfff)<<16 | ((x+w-1)&0xfff));
+}
diff --git a/src/image_accel.c b/src/image_accel.c
new file mode 100644
index 0000000..485f455
--- /dev/null
+++ b/src/image_accel.c
@@ -0,0 +1,647 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane, Wigan, England.
+ *
+ * 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, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * Trident 3DImage' accelerated options.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/image_accel.c,v 1.24 2001/10/28 03:33:51 tsi Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "miline.h"
+
+#include "trident.h"
+#include "trident_regs.h"
+
+#include "xaarop.h"
+#include "xaalocal.h"
+
+static void ImageSync(ScrnInfoPtr pScrn);
+static void ImageSyncClip(ScrnInfoPtr pScrn);
+#if 0
+static void ImageSetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void ImageSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e,
+ int len, int octant);
+#endif
+static void ImageSetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void ImageSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h);
+static void ImageSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2,
+ int y2, int w, int h);
+static void ImageSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask,
+ int transparency_color);
+static void ImageSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2);
+static void ImageDisableClipping(ScrnInfoPtr pScrn);
+static void ImageSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int fg, int bg,
+ int rop, unsigned int planemask);
+static void ImageSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int x, int y,
+ int w, int h);
+#if 0
+static void ImageSetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int rop, unsigned int planemask, int trans_col);
+static void ImageSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int x, int y,
+ int w, int h);
+#endif
+static void ImageSetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int transparency_color,
+ int bpp, int depth);
+static void ImageSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h, int skipleft);
+static void ImageSubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno);
+static void ImageSetupForScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void ImageSubsequentScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn, int x,
+ int y, int w, int h, int skipleft);
+static void ImageSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
+
+static void
+ImageInitializeAccelerator(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ switch (pScrn->depth) {
+ case 8:
+ pTrident->EngineOperation = 0;
+ break;
+ case 15:
+ pTrident->EngineOperation = 5;
+ break;
+ case 16:
+ pTrident->EngineOperation = 1;
+ break;
+ case 24:
+ pTrident->EngineOperation = 2;
+ break;
+ }
+ IMAGE_OUT(0x2120, 0xF0000000);
+ IMAGE_OUT(0x2120, 0x40000000 | pTrident->EngineOperation);
+ IMAGE_OUT(0x2120, 0x80000000);
+ IMAGE_OUT(0x2144, 0x00000000);
+ IMAGE_OUT(0x2148, 0x00000000);
+ IMAGE_OUT(0x2150, 0x00000000);
+ IMAGE_OUT(0x2154, 0x00000000);
+ IMAGE_OUT(0x2120, 0x60000000 |pScrn->displayWidth<<16 |pScrn->displayWidth);
+ IMAGE_OUT(0x216C, 0x00000000);
+ IMAGE_OUT(0x2170, 0x00000000);
+ IMAGE_OUT(0x217C, 0x00000000);
+ IMAGE_OUT(0x2120, 0x10000000);
+ IMAGE_OUT(0x2130, 2047 << 16 | 2047);
+ pTrident->Clipping = FALSE;
+ pTrident->DstEnable = FALSE;
+}
+
+Bool
+ImageAccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ BoxRec AvailFBArea;
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = (pTrident->FbMapSize - 4096) / (pScrn->displayWidth *
+ pScrn->bitsPerPixel / 8);
+ if (AvailFBArea.y2 > 2047) AvailFBArea.y2 = 2047;
+
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ if (pTrident->NoAccel)
+ return FALSE;
+
+ pTrident->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if (!infoPtr) return FALSE;
+
+ pTrident->InitializeAccelerator = ImageInitializeAccelerator;
+ ImageInitializeAccelerator(pScrn);
+
+ infoPtr->Flags = PIXMAP_CACHE |
+ LINEAR_FRAMEBUFFER |
+ OFFSCREEN_PIXMAPS;
+
+ infoPtr->Sync = ImageSync;
+
+#if 0
+ infoPtr->SetClippingRectangle = ImageSetClippingRectangle;
+ infoPtr->DisableClipping = ImageDisableClipping;
+ infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_FILL |
+ HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
+ HARDWARE_CLIP_MONO_8x8_FILL;
+#endif
+
+#if 0
+ infoPtr->SolidLineFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidLine = ImageSetupForSolidLine;
+ infoPtr->SolidBresenhamLineErrorTermBits = 13;
+ infoPtr->SubsequentSolidBresenhamLine = ImageSubsequentSolidBresenhamLine;
+ infoPtr->ClippingFlags |= HARDWARE_CLIP_SOLID_LINE;
+#endif
+
+ infoPtr->SolidFillFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidFill = ImageSetupForFillRectSolid;
+ infoPtr->SubsequentSolidFillRect = ImageSubsequentFillRectSolid;
+
+ infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK |
+ NO_TRANSPARENCY |
+ ONLY_TWO_BITBLT_DIRECTIONS;
+
+ infoPtr->SetupForScreenToScreenCopy =
+ ImageSetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy =
+ ImageSubsequentScreenToScreenCopy;
+
+ infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK |
+ BIT_ORDER_IN_BYTE_MSBFIRST |
+ HARDWARE_PATTERN_SCREEN_ORIGIN |
+ HARDWARE_PATTERN_PROGRAMMED_BITS;
+
+ infoPtr->SetupForMono8x8PatternFill =
+ ImageSetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ ImageSubsequentMono8x8PatternFillRect;
+
+#if 0
+ infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK |
+ NO_TRANSPARENCY |
+ HARDWARE_PATTERN_SCREEN_ORIGIN |
+ BIT_ORDER_IN_BYTE_MSBFIRST;
+
+ infoPtr->SetupForColor8x8PatternFill =
+ ImageSetupForColor8x8PatternFill;
+ infoPtr->SubsequentColor8x8PatternFillRect =
+ ImageSubsequentColor8x8PatternFillRect;
+ infoPtr->ClippingFlags |= HARDWARE_CLIP_COLOR_8x8_FILL;
+#endif
+
+ if (pTrident->Chipset != CYBER9397DVD) {
+ /* It seems as though the 9397DVD doesn't like the transfer window */
+ /* But then, I've also tried at the two port addresses too, with */
+ /* no luck. Disable for this chipset for now. I'd guess there's some */
+ /* extra setup needed for this chipset. */
+ infoPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK |
+ LEFT_EDGE_CLIPPING |
+ BIT_ORDER_IN_BYTE_MSBFIRST;
+
+ pTrident->XAAScanlineColorExpandBuffers[0] =
+ xnfalloc(((pScrn->virtualX + 63)) *4* (pScrn->bitsPerPixel / 8));
+
+ infoPtr->NumScanlineColorExpandBuffers = 1;
+ infoPtr->ScanlineColorExpandBuffers =
+ pTrident->XAAScanlineColorExpandBuffers;
+
+ infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
+ ImageSetupForScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
+ ImageSubsequentScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentColorExpandScanline =
+ ImageSubsequentColorExpandScanline;
+
+ infoPtr->ScanlineImageWriteFlags = NO_PLANEMASK |
+ LEFT_EDGE_CLIPPING;
+
+ infoPtr->SetupForScanlineImageWrite = ImageSetupForScanlineImageWrite;
+ infoPtr->SubsequentScanlineImageWriteRect =
+ ImageSubsequentScanlineImageWriteRect;
+ infoPtr->SubsequentImageWriteScanline = ImageSubsequentImageWriteScanline;
+
+ infoPtr->NumScanlineImageWriteBuffers = 1;
+ infoPtr->ScanlineImageWriteBuffers = pTrident->XAAImageScanlineBuffer;
+
+ pTrident->XAAImageScanlineBuffer[0] =
+ xnfalloc(pScrn->virtualX * pScrn->bitsPerPixel / 8);
+
+ infoPtr->ImageWriteBase = pTrident->IOBase + 0x10000;
+ }
+
+ return(XAAInit(pScreen, infoPtr));
+}
+
+static void
+ImageSync(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int busy;
+ int cnt = 5000000;
+
+ if (pTrident->Clipping) ImageDisableClipping(pScrn);
+ if (pTrident->DstEnable) {
+ IMAGE_OUT(0x2120, 0x70000000);
+ pTrident->DstEnable = FALSE;
+ }
+
+ IMAGEBUSY(busy);
+ while (busy != 0) {
+ if (--cnt < 0) {
+ ErrorF("GE timeout\n");
+ IMAGE_OUT(0x2164, 0x80000000);
+ }
+ IMAGEBUSY(busy);
+ }
+}
+
+static void
+ImageSyncClip(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int busy;
+ int cnt = 5000000;
+
+ IMAGEBUSY(busy);
+ while (busy != 0) {
+ if (--cnt < 0) {
+ ErrorF("GE timeout\n");
+ IMAGE_OUT(0x2164, 0x80000000);
+ }
+ IMAGEBUSY(busy);
+ }
+}
+
+static void
+ImageSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask, int transparency_color)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ pTrident->BltScanDirection = 0;
+ if ((xdir < 0) || (ydir < 0)) pTrident->BltScanDirection |= 1<<2;
+
+ IMAGE_OUT(0x2120, 0x80000000);
+ IMAGE_OUT(0x2120, 0x90000000 | XAACopyROP[rop]);
+
+ if (transparency_color != -1) {
+ IMAGE_OUT(0x2120, 0x70000000 | 1<<26 | (transparency_color&0xffffff));
+ pTrident->DstEnable = TRUE;
+ }
+}
+
+static void
+ImageSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if (pTrident->BltScanDirection) {
+ IMAGE_OUT(0x2100, (y1+h-1)<<16 | (x1+w-1));
+ IMAGE_OUT(0x2104, y1<<16 | x1);
+ IMAGE_OUT(0x2108, (y2+h-1)<<16 | (x2+w-1));
+ IMAGE_OUT(0x210C, y2<<16 | x2);
+ } else {
+ IMAGE_OUT(0x2100, y1<<16 | x1);
+ IMAGE_OUT(0x2104, (y1+h-1)<<16 | (x1+w-1));
+ IMAGE_OUT(0x2108, y2<<16 | x2);
+ IMAGE_OUT(0x210C, (y2+h-1)<<16 | (x2+w-1));
+ }
+
+ IMAGE_OUT(0x2124, 0x80000000 | 1<<7 | 1<<22 | 1<<10 | pTrident->BltScanDirection | (pTrident->Clipping ? 1 : 0));
+
+ if (!pTrident->UsePCIRetry)
+ ImageSyncClip(pScrn);
+}
+
+static void
+ImageSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ IMAGE_OUT(0x2120, 0x10000000 | ((y1&0xfff)<<16) | (x1&0xfff));
+ IMAGE_OUT(0x2130, ((y2&0xfff)<<16) | (x2&0xfff));
+ pTrident->Clipping = TRUE;
+}
+
+static void
+ImageDisableClipping(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ pTrident->Clipping = FALSE;
+}
+
+#if 0
+static void
+ImageSetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ REPLICATE(color);
+ IMAGE_OUT(0x2120, 0x84000000);
+ IMAGE_OUT(0x2120, 0x90000000 | XAACopyROP[rop]);
+ IMAGE_OUT(0x2144, color);
+}
+
+static void
+ImageSubsequentSolidBresenhamLine( ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e, int len, int octant)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int tmp;
+ int D = 0, E = 0, ymajor = 0;
+
+ IMAGE_OUT(0x2124, 0x20000000 | 3<<22 | 1<<10 | 1<<9 | (pTrident->Clipping ? 1:0));
+ if (!(octant & YMAJOR)) {
+ if ((!(octant&XDECREASING)) && (!(octant&YDECREASING))) {E = 1; D = 0;}
+ if ((!(octant&XDECREASING)) && ( (octant&YDECREASING))) {E = 1; D = 1;}
+ if (( (octant&XDECREASING)) && (!(octant&YDECREASING))) {E = 1; D = 2;}
+ if (( (octant&XDECREASING)) && ( (octant&YDECREASING))) {E = 1; D = 3;}
+ ymajor = 0;
+ } else {
+ if ((!(octant&XDECREASING)) && (!(octant&YDECREASING))) {E = 0; D = 0;}
+ if ((!(octant&XDECREASING)) && ( (octant&YDECREASING))) {E = 0; D = 2;}
+ if (( (octant&XDECREASING)) && (!(octant&YDECREASING))) {E = 0; D = 1;}
+ if (( (octant&XDECREASING)) && ( (octant&YDECREASING))) {E = 0; D = 3;}
+ ymajor = 1<<18;
+ }
+
+ if (E) {
+ tmp = x; x = y; y = tmp;
+ }
+ if (D&0x02) {
+ IMAGE_OUT(0x21FC, 0x20000000 | 1<<27 | 1<<19 | 1<<17 | ymajor | (x+len-1));
+ } else {
+ IMAGE_OUT(0x21FC, 0x20000000 | 1<<27 | 1<<19 | 1<<17 | ymajor | (y+len-1));
+ }
+ IMAGE_OUT(0x2100, E<<30 | (y&0xfff)<<16 | (x&0xfff));
+ IMAGE_OUT(0x2104, D<<30 | (((dmaj-dmin)&0xfff) << 16) | (-dmin&0xfff));
+ IMAGE_OUT(0x2108, ((-e&0xfff) << 16));
+
+ if (!pTrident->UsePCIRetry)
+ ImageSyncClip(pScrn);
+}
+#endif
+
+static void
+ImageSetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ REPLICATE(color);
+ IMAGE_OUT(0x2120, 0x80000000);
+ IMAGE_OUT(0x2120, 0x90000000 | XAACopyROP[rop]);
+ IMAGE_OUT(0x2144, color);
+}
+
+static void
+ImageSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if ((w<=0) || (h<=0))
+ return;
+
+ IMAGE_OUT(0x2108, ((y&0xfff)<<16) | (x&0xfff));
+ IMAGE_OUT(0x210C, (((y+h-1)&0xfff)<<16) | ((x+w-1)&0xfff));
+ IMAGE_OUT(0x2124, 0x80000000| 3<<22| 1<<10| 1<<9| (pTrident->Clipping?1:0));
+ if (!pTrident->UsePCIRetry)
+ ImageSyncClip(pScrn);
+}
+
+static
+void MoveDWORDS(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords )
+{
+ Bool extra = FALSE;
+ if (dwords & 0x01) extra = TRUE;
+ while(dwords & ~0x03) {
+ *dest = *src;
+ *(dest + 1) = *(src + 1);
+ *(dest + 2) = *(src + 2);
+ *(dest + 3) = *(src + 3);
+ src += 4;
+ dest += 4;
+ dwords -= 4;
+ }
+ if(!dwords) {
+ if (extra) *dest = 0x00000000;
+ return;
+ }
+ *dest = *src;
+ if(dwords == 1) {
+ if (extra) *(dest + 1) = 0x00000000;
+ return;
+ }
+ *(dest + 1) = *(src + 1);
+ if(dwords == 2) {
+ if (extra) *(dest + 2) = 0x00000000;
+ return;
+ }
+ *(dest + 2) = *(src + 2);
+ if (extra) *(dest + 3) = 0x00000000;
+}
+
+static void
+ImageSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ IMAGE_OUT(0x2120, 0x90000000 | XAAPatternROP[rop]);
+ if (bg == -1) {
+ REPLICATE(fg);
+ IMAGE_OUT(0x2120, 0x80000000 | 1<<27);
+ IMAGE_OUT(0x2130, patternx);
+ IMAGE_OUT(0x2134, patterny);
+ IMAGE_OUT(0x2150, fg);
+ IMAGE_OUT(0x2154, ~fg);
+ } else {
+ REPLICATE(bg);
+ REPLICATE(fg);
+ IMAGE_OUT(0x2120, 0x80000000 | 1<<27 | 1<<26);
+ IMAGE_OUT(0x2130, patternx);
+ IMAGE_OUT(0x2134, patterny);
+ IMAGE_OUT(0x2150, fg);
+ IMAGE_OUT(0x2154, bg);
+ }
+}
+
+static void
+ImageSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int x, int y,
+ int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ IMAGE_OUT(0x2108, ((y&0xfff)<<16) | (x&0xfff));
+ IMAGE_OUT(0x210C, (((y+h-1)&0xfff)<<16) | ((x+w-1)&0xfff));
+ IMAGE_OUT(0x2124, 0x80000000 | 7<<18 | 1<<22 | 1<<10 | 1<<9 | (pTrident->Clipping ? 1 : 0));
+ if (!pTrident->UsePCIRetry)
+ ImageSyncClip(pScrn);
+}
+
+#if 0
+static void
+ImageSetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int rop,
+ unsigned int planemask,
+ int transparency_color)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ IMAGE_OUT(0x2120, 0x90000000 | XAAPatternROP[rop]);
+ IMAGE_OUT(0x2120, 0x80000000 | 1<<26);
+ if (transparency_color != -1) {
+ IMAGE_OUT(0x2120, 0x70000000 | 1<<26 | (transparency_color&0xffffff));
+ pTrident->DstEnable = TRUE;
+ }
+}
+
+static void
+ImageSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int x, int y,
+ int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ IMAGE_OUT(0x2100, (patterny&0xfff)<<16 | (patternx&0xfff));
+ IMAGE_OUT(0x2104, (((patterny+h-1)&0xfff)<<16) | ((patternx+w-1)&0xfff));
+ IMAGE_OUT(0x2108, (y&0xfff)<<16 | (x&0xfff));
+ IMAGE_OUT(0x210C, (((y+h-1)&0xfff)<<16) | ((x+w-1)&0xfff));
+ IMAGE_OUT(0x2124, 0x80000000 | 1<<22 | 1<<10 | 1<<7 | (pTrident->Clipping ? 1 : 0));
+ if (!pTrident->UsePCIRetry)
+ ImageSyncClip(pScrn);
+}
+#endif
+
+static void
+ImageSetupForScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ IMAGE_OUT(0x2120, 0x80000000);
+ IMAGE_OUT(0x2120, 0x90000000 | XAACopyROP[rop]);
+ if (bg == -1) {
+ pTrident->ROP = 2<<22;
+ REPLICATE(fg);
+ IMAGE_OUT(0x2144, fg);
+ IMAGE_OUT(0x2148, ~fg);
+ } else {
+ pTrident->ROP = 3<<22;
+ REPLICATE(fg);
+ IMAGE_OUT(0x2144, fg);
+ REPLICATE(bg);
+ IMAGE_OUT(0x2148, bg);
+ }
+}
+
+static void
+ImageSubsequentScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ ImageSetClippingRectangle(pScrn,(x+skipleft),y,(x+w-1),(y+h-1));
+ IMAGE_OUT(0x2108, (y&0xfff)<<16 | (x&0xfff));
+ IMAGE_OUT(0x210C, (((y+h-1)&0xfff)<<16) | ((x+w-1)&0xfff));
+ IMAGE_OUT(0x2124, 0x80000000 | pTrident->ROP | 1<<10 | 1);
+ pTrident->dwords = (w + 31) >> 5;
+ pTrident->h = h;
+}
+
+static void
+ImageSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ XAAInfoRecPtr infoRec;
+ infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ MoveDWORDS((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)pTrident->XAAScanlineColorExpandBuffers[bufno], pTrident->dwords);
+
+ pTrident->h--;
+ if (!pTrident->h)
+ ImageSync(pScrn);
+}
+
+static void
+ImageSetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int transparency_color,
+ int bpp, int depth)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ IMAGE_OUT(0x2120, 0x90000000 | XAACopyROP[rop]);
+ if (transparency_color != -1) {
+ IMAGE_OUT(0x2120, 0x70000000 | 1<<26 | (transparency_color&0xffffff));
+ pTrident->DstEnable = TRUE;
+ }
+ IMAGE_OUT(0x2120, 0x80000000);
+}
+
+static void
+ImageSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, int x, int y,
+ int w, int h, int skipleft)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ ImageSetClippingRectangle(pScrn,(x+skipleft),y,(x+w-1),(y+h-1));
+ IMAGE_OUT(0x2108, ((y&0xfff)<<16) | (x&0xfff));
+ IMAGE_OUT(0x210C, (((y+h-1)&0xfff)<<16) | ((x+w-1)&0xfff));
+ IMAGE_OUT(0x2124, 0x80000000 | 1<<22 | 1<<10 | 1);
+ pTrident->dwords = ((w * (pScrn->bitsPerPixel/8)) + 3) >> 2;
+ pTrident->h = h;
+}
+
+
+static void
+ImageSubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ XAAInfoRecPtr infoRec;
+ infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ MoveDWORDS((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)pTrident->XAAImageScanlineBuffer[bufno], pTrident->dwords);
+
+ pTrident->h--;
+ if (!pTrident->h)
+ ImageSync(pScrn);
+}
diff --git a/src/trident.h b/src/trident.h
new file mode 100644
index 0000000..a73ae53
--- /dev/null
+++ b/src/trident.h
@@ -0,0 +1,346 @@
+/*
+ * Copyright 1992-2000 by Alan Hourihane <alanh@fairlite.demon.co.uk>
+ *
+ * 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, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident.h,v 1.56 2002/09/16 18:06:02 eich Exp $ */
+/*#define VBE_INFO*/
+
+#ifndef _TRIDENT_H_
+#define _TRIDENT_H_
+
+#include "xf86Cursor.h"
+#include "xaa.h"
+#include "xf86RamDac.h"
+#include "compiler.h"
+#include "vgaHW.h"
+#include "xf86i2c.h"
+#include "xf86int10.h"
+#include "shadowfb.h"
+#include "shadow.h"
+#include "xf86xv.h"
+#include "xf86Pci.h"
+#include "vbe.h"
+
+typedef struct {
+ unsigned char tridentRegs3x4[0x100];
+ unsigned char tridentRegs3CE[0x100];
+ unsigned char tridentRegs3C4[0x100];
+ unsigned char tridentRegsDAC[0x01];
+ unsigned char tridentRegsClock[0x03];
+ unsigned char DacRegs[0x300];
+} TRIDENTRegRec, *TRIDENTRegPtr;
+
+#define TRIDENTPTR(p) ((TRIDENTPtr)((p)->driverPrivate))
+
+typedef struct {
+ ScrnInfoPtr pScrn;
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+ EntityInfoPtr pEnt;
+ int Chipset;
+ int DACtype;
+ int RamDac;
+ int ChipRev;
+ int HwBpp;
+ int BppShift;
+ CARD32 IOAddress;
+ unsigned long FbAddress;
+ unsigned char * IOBase;
+ unsigned char * FbBase;
+ long FbMapSize;
+ IOADDRESS PIOBase;
+ Bool NoAccel;
+ Bool HWCursor;
+ Bool UsePCIRetry;
+ Bool UsePCIBurst;
+ Bool NewClockCode;
+ Bool Clipping;
+ Bool DstEnable;
+ Bool ROP;
+ Bool HasSGRAM;
+ Bool MUX;
+ Bool IsCyber;
+ Bool CyberShadow;
+ Bool CyberStretch;
+ Bool NoMMIO;
+ Bool MMIOonly;
+ Bool ShadowFB;
+ Bool Linear;
+ DGAModePtr DGAModes;
+ int numDGAModes;
+ Bool DGAactive;
+ int DGAViewportStatus;
+ unsigned char * ShadowPtr;
+ int ShadowPitch;
+ RefreshAreaFuncPtr RefreshArea;
+ void (*PointerMoved)(int index, int x, int y);
+ int Rotate;
+ float frequency;
+ unsigned char REGPCIReg;
+ unsigned char REGNewMode1;
+ CARD8 SaveClock1;
+ CARD8 SaveClock2;
+ CARD8 SaveClock3;
+ int MinClock;
+ int MaxClock;
+ int MUXThreshold;
+ int currentClock;
+ int MCLK;
+ int dwords;
+ int h;
+ int x;
+ int w;
+ int y;
+ int lcdMode;
+ Bool lcdActive;
+ Bool doInit;
+#ifdef READOUT
+ Bool DontSetClock;
+#endif
+ TRIDENTRegRec SavedReg;
+ TRIDENTRegRec ModeReg;
+ I2CBusPtr DDC;
+ CARD16 EngineOperation;
+ CARD32 PatternLocation;
+ CARD32 BltScanDirection;
+ CARD32 DrawFlag;
+ CARD16 LinePattern;
+ RamDacRecPtr RamDacRec;
+ xf86CursorInfoPtr CursorInfoRec;
+ xf86Int10InfoPtr Int10;
+ vbeInfoPtr pVbe;
+#ifdef VBE_INFO
+ vbeModeInfoPtr vbeModes;
+#endif
+ XAAInfoRecPtr AccelInfoRec;
+ CloseScreenProcPtr CloseScreen;
+ ScreenBlockHandlerProcPtr BlockHandler;
+ int panelWidth;
+ int panelHeight;
+ unsigned int (*ddc1Read)(ScrnInfoPtr);
+ CARD8* XAAScanlineColorExpandBuffers[2];
+ CARD8* XAAImageScanlineBuffer[1];
+ void (*InitializeAccelerator)(ScrnInfoPtr);
+#ifdef XvExtension
+ void (*VideoTimerCallback)(ScrnInfoPtr, Time);
+ XF86VideoAdaptorPtr adaptor;
+ int videoKey;
+ int hsync;
+ int hsync_rskew;
+ int vsync;
+ int vsync_bskew;
+ CARD32 videoFlags;
+ int keyOffset;
+#endif
+ int OverrideHsync;
+ int OverrideVsync;
+ int OverrideBskew;
+ int OverrideRskew;
+ OptionInfoPtr Options;
+ Bool shadowNew;
+ int displaySize;
+ int dspOverride;
+ Bool GammaBrightnessOn;
+ int brightness;
+ double gamma;
+ int FPDelay; /* just for debugging - will go away */
+} TRIDENTRec, *TRIDENTPtr;
+
+typedef struct {
+ CARD8 mode;
+ int display_x;
+ int display_y;
+ int clock;
+ int shadow_0;
+ int shadow_3;
+ int shadow_4;
+ int shadow_5;
+ int shadow_6;
+ int shadow_7;
+ int shadow_10;
+ int shadow_11;
+ int shadow_16;
+ int shadow_HiOrd;
+} tridentLCD;
+
+#define LCD_ACTIVE 0x01
+#define CRT_ACTIVE 0x02
+
+extern tridentLCD LCD[];
+
+typedef struct {
+ int x_res;
+ int y_res;
+ int mode;
+} biosMode;
+
+typedef struct {
+ int x_res;
+ int y_res;
+ CARD8 GR5a;
+ CARD8 GR5c;
+} newModes;
+
+/* Prototypes */
+
+Bool TRIDENTClockSelect(ScrnInfoPtr pScrn, int no);
+Bool TRIDENTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+void TRIDENTAdjustFrame(int scrnIndex, int x, int y, int flags);
+Bool TRIDENTDGAInit(ScreenPtr pScreen);
+Bool TRIDENTI2CInit(ScreenPtr pScreen);
+void TRIDENTInitVideo(ScreenPtr pScreen);
+void TRIDENTResetVideo(ScrnInfoPtr pScrn);
+unsigned int Tridentddc1Read(ScrnInfoPtr pScrn);
+void TVGARestore(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg);
+void TVGASave(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg);
+Bool TVGAInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+void TridentRestore(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg);
+void TridentSave(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg);
+Bool TridentInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+Bool TridentAccelInit(ScreenPtr pScreen);
+Bool XPAccelInit(ScreenPtr pScreen);
+Bool ImageAccelInit(ScreenPtr pScreen);
+Bool BladeAccelInit(ScreenPtr pScreen);
+Bool TridentHWCursorInit(ScreenPtr pScreen);
+int TridentFindMode(int xres, int yres, int depth);
+void TGUISetClock(ScrnInfoPtr pScrn, int clock, unsigned char *a, unsigned char *b);
+void TGUISetMCLK(ScrnInfoPtr pScrn, int clock, unsigned char *a, unsigned char *b);
+void tridentSetModeBIOS(ScrnInfoPtr pScrn, DisplayModePtr mode);
+void TridentOutIndReg(ScrnInfoPtr pScrn,
+ CARD32 reg, unsigned char mask, unsigned char data);
+unsigned char TridentInIndReg(ScrnInfoPtr pScrn, CARD32 reg);
+void TridentWriteAddress(ScrnInfoPtr pScrn, CARD32 index);
+void TridentReadAddress(ScrnInfoPtr pScrn, CARD32 index);
+void TridentWriteData(ScrnInfoPtr pScrn, unsigned char data);
+unsigned char TridentReadData(ScrnInfoPtr pScrn);
+void TridentLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies, LOCO *colors, VisualPtr pVisual);
+void TridentSetOverscan(ScrnInfoPtr pScrn, int overscan);
+int TGUISetRead(ScreenPtr pScreen, int bank);
+int TGUISetWrite(ScreenPtr pScreen, int bank);
+int TGUISetReadWrite(ScreenPtr pScreen, int bank);
+int TVGA8900SetRead(ScreenPtr pScreen, int bank);
+int TVGA8900SetWrite(ScreenPtr pScreen, int bank);
+int TVGA8900SetReadWrite(ScreenPtr pScreen, int bank);
+void TridentFindClock(ScrnInfoPtr pScrn, int clock);
+float CalculateMCLK(ScrnInfoPtr pScrn);
+void TRIDENTRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void TRIDENTShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf);
+void TRIDENTPointerMoved(int index, int x, int y);
+void TRIDENTRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void TRIDENTRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void TRIDENTRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void TRIDENTRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+
+/*
+ * Trident Chipset Definitions
+ */
+
+/* Supported chipsets */
+typedef enum {
+ TVGA8200LX,
+ TVGA8800BR,
+ TVGA8800CS,
+ TVGA8900B,
+ TVGA8900C,
+ TVGA8900CL,
+ TVGA8900D,
+ TVGA9000,
+ TVGA9000i,
+ TVGA9100B,
+ TVGA9200CXr,
+ TGUI9400CXi,
+ TGUI9420DGi,
+ TGUI9430DGi,
+ TGUI9440AGi,
+ CYBER9320,
+ TGUI9660,
+ TGUI9680,
+ PROVIDIA9682,
+ CYBER9382,
+ CYBER9385,
+ PROVIDIA9685,
+ CYBER9388,
+ CYBER9397,
+ CYBER9397DVD,
+ CYBER9520,
+ CYBER9525DVD,
+ IMAGE975,
+ IMAGE985,
+ BLADE3D,
+ CYBERBLADEI7,
+ CYBERBLADEI7D,
+ CYBERBLADEI1,
+ CYBERBLADEI1D,
+ CYBERBLADEAI1,
+ CYBERBLADEAI1D,
+ CYBERBLADEE4,
+ BLADEXP,
+ CYBERBLADEXPAI1
+} TRIDENTType;
+
+#define UseMMIO (pTrident->NoMMIO == FALSE)
+
+#define IsPciCard (pTrident->pEnt->location.type == BUS_PCI)
+
+#define IsPrimaryCard ((xf86IsPrimaryPci(pTrident->PciInfo)) || \
+ (xf86IsPrimaryIsa()))
+
+#define HAS_DST_TRANS ((pTrident->Chipset == PROVIDIA9682) || \
+ (pTrident->Chipset == PROVIDIA9685) || \
+ (pTrident->Chipset == BLADEXP) || \
+ (pTrident->Chipset == CYBERBLADEXPAI1))
+
+#define Is3Dchip ((pTrident->Chipset == CYBER9397) || \
+ (pTrident->Chipset == CYBER9397DVD) || \
+ (pTrident->Chipset == CYBER9520) || \
+ (pTrident->Chipset == CYBER9525DVD) || \
+ (pTrident->Chipset == CYBERBLADEE4) || \
+ (pTrident->Chipset == IMAGE975) || \
+ (pTrident->Chipset == IMAGE985) || \
+ (pTrident->Chipset == CYBERBLADEI7) || \
+ (pTrident->Chipset == CYBERBLADEI7D) || \
+ (pTrident->Chipset == CYBERBLADEI1) || \
+ (pTrident->Chipset == CYBERBLADEI1D) || \
+ (pTrident->Chipset == CYBERBLADEAI1) || \
+ (pTrident->Chipset == CYBERBLADEAI1D) || \
+ (pTrident->Chipset == BLADE3D) || \
+ (pTrident->Chipset == CYBERBLADEXPAI1) || \
+ (pTrident->Chipset == BLADEXP))
+
+/*
+ * Trident DAC's
+ */
+
+#define TKD8001 0
+#define TGUIDAC 1
+
+/*
+ * Video Flags
+ */
+
+#define VID_ZOOM_INV 0x1
+#define VID_ZOOM_MINI 0x2
+#define VID_OFF_SHIFT_4 0x4
+#define VID_ZOOM_NOMINI 0x8
+#define VID_DOUBLE_LINEBUFFER_FOR_WIDE_SRC 0x10
+#endif /* _TRIDENT_H_ */
+
diff --git a/src/trident_accel.c b/src/trident_accel.c
new file mode 100644
index 0000000..256e97e
--- /dev/null
+++ b/src/trident_accel.c
@@ -0,0 +1,673 @@
+/*
+ * Copyright 1992-2000 by Alan Hourihane, Wigan, England.
+ *
+ * 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, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * Trident accelerated options.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_accel.c,v 1.26 2003/02/12 21:46:42 tsi Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "miline.h"
+
+#include "trident.h"
+#include "trident_regs.h"
+
+#include "xaalocal.h"
+#include "xaarop.h"
+
+static void TridentSync(ScrnInfoPtr pScrn);
+static void TridentSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg,
+ int rop, unsigned int planemask, int length,
+ unsigned char *pattern);
+static void TridentSubsequentDashedBresenhamLine(ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e,
+ int len, int octant, int phase);
+static void TridentSetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void TridentSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e,
+ int len, int octant);
+static void TridentSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y,
+ int len, int dir);
+static void TridentSetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void TridentSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h);
+static void TridentSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2,
+ int y2, int w, int h);
+static void TridentSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask,
+ int transparency_color);
+static void TridentSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int fg, int bg,
+ int rop, unsigned int planemask);
+static void TridentSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int x, int y,
+ int w, int h);
+#if 0
+static void TridentSetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int rop, unsigned int planemask, int trans_col);
+static void TridentSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int x, int y,
+ int w, int h);
+#endif
+#if 0
+static void TridentSetupForScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void TridentSubsequentScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn, int x,
+ int y, int w, int h, int skipleft);
+static void TridentSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
+#endif
+
+
+static void
+TridentInitializeAccelerator(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ /* This forces updating the clipper */
+ pTrident->Clipping = TRUE;
+
+ CHECKCLIPPING;
+
+ if ( (pTrident->Chipset == PROVIDIA9682) ||
+ (pTrident->Chipset == CYBER9385) ||
+ (pTrident->Chipset == CYBER9382) )
+ pTrident->EngineOperation |= 0x100; /* Disable Clipping */
+
+ TGUI_OPERMODE(pTrident->EngineOperation);
+
+ pTrident->PatternLocation = pScrn->displayWidth*pScrn->bitsPerPixel/8;
+}
+
+Bool
+TridentAccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ BoxRec AvailFBArea;
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = (pTrident->FbMapSize - 4096) / (pScrn->displayWidth *
+ pScrn->bitsPerPixel / 8);
+
+ if (AvailFBArea.y2 > 2047) AvailFBArea.y2 = 2047;
+
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ if (pTrident->NoAccel)
+ return FALSE;
+
+ pTrident->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if (!infoPtr) return FALSE;
+
+ if (!(pTrident->Chipset == TGUI9440AGi && pScrn->bitsPerPixel > 8))
+ infoPtr->Flags = PIXMAP_CACHE |
+ OFFSCREEN_PIXMAPS |
+ LINEAR_FRAMEBUFFER;
+
+ pTrident->InitializeAccelerator = TridentInitializeAccelerator;
+ TridentInitializeAccelerator(pScrn);
+
+ infoPtr->PixmapCacheFlags = DO_NOT_BLIT_STIPPLES;
+
+ infoPtr->Sync = TridentSync;
+
+ infoPtr->SolidLineFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidLine = TridentSetupForSolidLine;
+ infoPtr->SolidBresenhamLineErrorTermBits = 12;
+ infoPtr->SubsequentSolidBresenhamLine = TridentSubsequentSolidBresenhamLine;
+ infoPtr->SubsequentSolidHorVertLine = TridentSubsequentSolidHorVertLine;
+
+ infoPtr->DashedLineFlags = LINE_PATTERN_MSBFIRST_LSBJUSTIFIED |
+ NO_PLANEMASK |
+ LINE_PATTERN_POWER_OF_2_ONLY;
+ infoPtr->SetupForDashedLine = TridentSetupForDashedLine;
+ infoPtr->DashedBresenhamLineErrorTermBits = 12;
+ infoPtr->SubsequentDashedBresenhamLine =
+ TridentSubsequentDashedBresenhamLine;
+ infoPtr->DashPatternMaxLength = 16;
+
+ infoPtr->SolidFillFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidFill = TridentSetupForFillRectSolid;
+ infoPtr->SubsequentSolidFillRect = TridentSubsequentFillRectSolid;
+
+ infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK;
+
+ if (!HAS_DST_TRANS) infoPtr->ScreenToScreenCopyFlags |= NO_TRANSPARENCY;
+
+ infoPtr->SetupForScreenToScreenCopy =
+ TridentSetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy =
+ TridentSubsequentScreenToScreenCopy;
+
+ if (!((pTrident->Chipset == PROVIDIA9685 ||
+ pTrident->Chipset == CYBER9388) && pScrn->bitsPerPixel > 8)) {
+ infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK |
+ HARDWARE_PATTERN_SCREEN_ORIGIN |
+ BIT_ORDER_IN_BYTE_MSBFIRST;
+
+ infoPtr->SetupForMono8x8PatternFill =
+ TridentSetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ TridentSubsequentMono8x8PatternFillRect;
+ }
+
+#if 0 /* Not convinced this works 100% yet */
+ infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK |
+ HARDWARE_PATTERN_SCREEN_ORIGIN |
+ BIT_ORDER_IN_BYTE_MSBFIRST;
+
+ if (!HAS_DST_TRANS) infoPtr->Color8x8PatternFillFlags |= NO_TRANSPARENCY;
+
+ infoPtr->SetupForColor8x8PatternFill =
+ TridentSetupForColor8x8PatternFill;
+ infoPtr->SubsequentColor8x8PatternFillRect =
+ TridentSubsequentColor8x8PatternFillRect;
+#endif
+
+#if 0 /* This is buggy, it only seems to work 95% of the time.... */
+ {
+ infoPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK |
+ NO_TRANSPARENCY |
+ BIT_ORDER_IN_BYTE_MSBFIRST;
+
+ pTrident->XAAScanlineColorExpandBuffers[0] =
+ xnfalloc(((pScrn->virtualX + 63)) *4* (pScrn->bitsPerPixel / 8));
+
+ infoPtr->NumScanlineColorExpandBuffers = 1;
+ infoPtr->ScanlineColorExpandBuffers =
+ pTrident->XAAScanlineColorExpandBuffers;
+
+ infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
+ TridentSetupForScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
+ TridentSubsequentScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentColorExpandScanline =
+ TridentSubsequentColorExpandScanline;
+ }
+#endif
+
+ return(XAAInit(pScreen, infoPtr));
+}
+
+static void
+TridentSync(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int count = 0, timeout = 0;
+ int busy;
+
+ TGUI_OPERMODE(pTrident->EngineOperation);
+
+ for (;;) {
+ BLTBUSY(busy);
+ if (busy != GE_BUSY) {
+ return;
+ }
+ count++;
+ if (count == 10000000) {
+ ErrorF("Trident: BitBLT engine time-out.\n");
+ count = 9990000;
+ timeout++;
+ if (timeout == 8) {
+ /* Reset BitBLT Engine */
+ TGUI_STATUS(0x00);
+ return;
+ }
+ }
+ }
+}
+
+static void
+TridentClearSync(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int count = 0, timeout = 0;
+ int busy;
+
+ for (;;) {
+ BLTBUSY(busy);
+ if (busy != GE_BUSY) {
+ return;
+ }
+ count++;
+ if (count == 10000000) {
+ ErrorF("Trident: BitBLT engine time-out.\n");
+ count = 9990000;
+ timeout++;
+ if (timeout == 8) {
+ /* Reset BitBLT Engine */
+ TGUI_STATUS(0x00);
+ return;
+ }
+ }
+ }
+}
+
+static void
+TridentSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask, int transparency_color)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int dst = 0;
+
+ pTrident->BltScanDirection = 0;
+ if (xdir < 0) pTrident->BltScanDirection |= XNEG;
+ if (ydir < 0) pTrident->BltScanDirection |= YNEG;
+
+ REPLICATE(transparency_color);
+ if (transparency_color != -1) {
+ if (pTrident->Chipset == PROVIDIA9685 ||
+ pTrident->Chipset == CYBER9388) {
+ dst |= 1<<16;
+ } else {
+ TGUI_OPERMODE(pTrident->EngineOperation | DST_ENABLE);
+ }
+ TGUI_CKEY(transparency_color);
+ }
+
+ TGUI_DRAWFLAG(pTrident->DrawFlag | pTrident->BltScanDirection | SCR2SCR | dst);
+ TGUI_FMIX(XAACopyROP[rop]);
+}
+
+static void
+TridentSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if (pTrident->BltScanDirection & YNEG) {
+ y1 = y1 + h - 1;
+ y2 = y2 + h - 1;
+ }
+ if (pTrident->BltScanDirection & XNEG) {
+ x1 = x1 + w - 1;
+ x2 = x2 + w - 1;
+ }
+ TGUI_SRC_XY(x1,y1);
+ TGUI_DEST_XY(x2,y2);
+ TGUI_DIM_XY(w,h);
+ TGUI_COMMAND(GE_BLT);
+ TridentClearSync(pScrn);
+}
+
+static void
+TridentSetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ pTrident->BltScanDirection = 0;
+ REPLICATE(color);
+ TGUI_FMIX(XAAPatternROP[rop]);
+ if (pTrident->Chipset == PROVIDIA9685 ||
+ pTrident->Chipset == CYBER9388) {
+ TGUI_FPATCOL(color);
+ } else {
+ TGUI_FCOLOUR(color);
+ }
+}
+
+static void
+TridentSubsequentSolidBresenhamLine( ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e, int len, int octant)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int tmp = pTrident->BltScanDirection;
+
+ if (octant & YMAJOR) tmp |= YMAJ;
+ if (octant & XDECREASING) tmp |= XNEG;
+ if (octant & YDECREASING) tmp |= YNEG;
+ TGUI_DRAWFLAG(pTrident->DrawFlag | SOLIDFILL | STENCIL | tmp);
+ TGUI_SRC_XY(dmin-dmaj,dmin);
+ TGUI_DEST_XY(x,y);
+ TGUI_DIM_XY(dmin+e,len);
+ TGUI_COMMAND(GE_BRESLINE);
+ TridentSync(pScrn);
+}
+
+static void
+TridentSubsequentSolidHorVertLine(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int len, int dir
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ TGUI_DRAWFLAG(pTrident->DrawFlag | SOLIDFILL);
+ if (dir == DEGREES_0) {
+ TGUI_DIM_XY(len,1);
+ TGUI_DEST_XY(x,y);
+ } else {
+ TGUI_DIM_XY(1,len);
+ TGUI_DEST_XY(x,y);
+ }
+ TGUI_COMMAND(GE_BLT);
+ TridentSync(pScrn);
+}
+
+void
+TridentSetupForDashedLine(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int length,
+ unsigned char *pattern
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ CARD32 *DashPattern = (CARD32*)pattern;
+ CARD32 NiceDashPattern = DashPattern[0];
+
+ NiceDashPattern = *((CARD16 *)pattern) & ((1<<length) - 1);
+ switch(length) {
+ case 2: NiceDashPattern |= NiceDashPattern << 2;
+ case 4: NiceDashPattern |= NiceDashPattern << 4;
+ case 8: NiceDashPattern |= NiceDashPattern << 8;
+ }
+ pTrident->BltScanDirection = 0;
+ REPLICATE(fg);
+ if (pTrident->Chipset == PROVIDIA9685 ||
+ pTrident->Chipset == CYBER9388) {
+ TGUI_FPATCOL(fg);
+ if (bg == -1) {
+ pTrident->BltScanDirection |= 1<<12;
+ TGUI_BPATCOL(~fg);
+ } else {
+ REPLICATE(bg);
+ TGUI_BPATCOL(bg);
+ }
+ } else {
+ TGUI_FCOLOUR(fg);
+ if (bg == -1) {
+ pTrident->BltScanDirection |= 1<<12;
+ TGUI_BCOLOUR(~fg);
+ } else {
+ REPLICATE(bg);
+ TGUI_BCOLOUR(bg);
+ }
+ }
+ TGUI_FMIX(XAAPatternROP[rop]);
+ pTrident->LinePattern = NiceDashPattern;
+}
+
+
+void
+TridentSubsequentDashedBresenhamLine(ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e, int len, int octant, int phase)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int tmp = pTrident->BltScanDirection;
+
+ if (octant & YMAJOR) tmp |= YMAJ;
+ if (octant & XDECREASING) tmp |= XNEG;
+ if (octant & YDECREASING) tmp |= YNEG;
+
+ TGUI_STYLE(((pTrident->LinePattern >> phase) |
+ (pTrident->LinePattern << (16-phase))) & 0x0000FFFF);
+ TGUI_DRAWFLAG(pTrident->DrawFlag | STENCIL | tmp);
+ TGUI_SRC_XY(dmin-dmaj,dmin);
+ TGUI_DEST_XY(x,y);
+ TGUI_DIM_XY(e+dmin,len);
+ TGUI_COMMAND(GE_BRESLINE);
+ TridentSync(pScrn);
+}
+
+static void
+TridentSetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int drawflag = 0;
+
+ REPLICATE(color);
+ TGUI_FMIX(XAAPatternROP[rop]);
+ if (pTrident->Chipset == PROVIDIA9685 ||
+ pTrident->Chipset == CYBER9388) {
+ TGUI_FPATCOL(color);
+ } else {
+ drawflag |= PATMONO;
+ TGUI_FCOLOUR(color);
+ }
+ TGUI_DRAWFLAG(pTrident->DrawFlag | SOLIDFILL | drawflag);
+}
+
+static void
+TridentSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ TGUI_DIM_XY(w,h);
+ TGUI_DEST_XY(x,y);
+ TGUI_COMMAND(GE_BLT);
+ TridentSync(pScrn);
+}
+
+#if 0
+static void MoveDWORDS(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords )
+{
+ while(dwords & ~0x03) {
+ *dest = *src;
+ *(dest + 1) = *(src + 1);
+ *(dest + 2) = *(src + 2);
+ *(dest + 3) = *(src + 3);
+ src += 4;
+ dest += 4;
+ dwords -= 4;
+ }
+ if (!dwords) return;
+ *dest = *src;
+ dest += 1;
+ src += 1;
+ if (dwords == 1) return;
+ *dest = *src;
+ dest += 1;
+ src += 1;
+ if (dwords == 2) return;
+ *dest = *src;
+ dest += 1;
+ src += 1;
+}
+#endif
+
+static void
+TridentSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int drawflag = 0;
+
+ REPLICATE(fg);
+ if (pTrident->Chipset == PROVIDIA9685 ||
+ pTrident->Chipset == CYBER9388)
+ TGUI_FPATCOL(fg);
+ else
+ TGUI_FCOLOUR(fg);
+
+ if (bg == -1) {
+ drawflag |= 1<<12;
+ if (pTrident->Chipset == PROVIDIA9685 ||
+ pTrident->Chipset == CYBER9388)
+ TGUI_BPATCOL(~fg);
+ else
+ TGUI_BCOLOUR(~fg);
+ } else {
+ REPLICATE(bg);
+ if (pTrident->Chipset == PROVIDIA9685 ||
+ pTrident->Chipset == CYBER9388)
+ TGUI_BPATCOL(bg);
+ else
+ TGUI_BCOLOUR(bg);
+ }
+
+ if (pTrident->Chipset == PROVIDIA9685 ||
+ pTrident->Chipset == CYBER9388) {
+ drawflag |= 7<<18;
+ }
+ TGUI_DRAWFLAG(pTrident->DrawFlag | PAT2SCR | PATMONO | drawflag);
+ TGUI_PATLOC(((patterny * pTrident->PatternLocation) +
+ (patternx * pScrn->bitsPerPixel / 8)) >> 6);
+ TGUI_FMIX(XAAPatternROP[rop]);
+}
+
+static void
+TridentSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int x, int y,
+ int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ TGUI_DEST_XY(x,y);
+ TGUI_DIM_XY(w,h);
+ TGUI_COMMAND(GE_BLT);
+ TridentSync(pScrn);
+}
+
+#if 0
+static void
+TridentSetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int rop,
+ unsigned int planemask,
+ int transparency_color)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int drawflag = 0;
+
+ REPLICATE(transparency_color);
+ if (transparency_color != -1) {
+ if (pTrident->Chipset == PROVIDIA9685 ||
+ pTrident->Chipset == CYBER9388) {
+ drawflag |= 1<<16;
+ } else {
+ TGUI_OPERMODE(pTrident->EngineOperation | DST_ENABLE);
+ }
+ TGUI_CKEY(transparency_color);
+ }
+
+ TGUI_DRAWFLAG(pTrident->DrawFlag | PAT2SCR | drawflag);
+ TGUI_PATLOC(((patterny * pTrident->PatternLocation) +
+ (patternx * pScrn->bitsPerPixel / 8)) >> 6);
+ TGUI_FMIX(XAAPatternROP[rop]);
+}
+
+static void
+TridentSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int x, int y,
+ int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ TGUI_DEST_XY(x,y);
+ TGUI_DIM_XY(w,h);
+ TGUI_COMMAND(GE_BLT);
+ TridentClearSync(pScrn);
+}
+#endif
+
+#if 0
+static void
+TridentSetupForScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int drawflag = SRCMONO;
+
+ REPLICATE(fg);
+ TGUI_FCOLOUR(fg);
+ if (bg == -1) {
+ drawflag |= 1<<12;
+ TGUI_BCOLOUR(~fg);
+ } else {
+ REPLICATE(bg);
+ TGUI_BCOLOUR(bg);
+ }
+
+ TGUI_SRC_XY(0,0);
+ TGUI_DRAWFLAG(drawflag);
+ TGUI_FMIX(XAACopyROP[rop]);
+}
+
+static void
+TridentSubsequentScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ pTrident->dwords = (w + 31) >> 5;
+ pTrident->h = h;
+ pTrident->y = y;
+ pTrident->x = x;
+ pTrident->w = w;
+
+ TGUI_DEST_XY(x,pTrident->y++);
+ TGUI_DIM_XY(w,1);
+ TGUI_COMMAND(GE_BLT);
+}
+
+static void
+TridentSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ XAAInfoRecPtr infoRec;
+ infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ MoveDWORDS((CARD32 *)pTrident->FbBase,
+ (CARD32 *)pTrident->XAAScanlineColorExpandBuffers[0],
+ pTrident->dwords);
+
+ pTrident->h--;
+ TridentSync(pScrn);
+ if (pTrident->h) {
+ TGUI_DEST_XY(pTrident->x,pTrident->y++);
+ TGUI_DIM_XY(pTrident->w,1);
+ TGUI_COMMAND(GE_BLT);
+ }
+}
+#endif
diff --git a/src/trident_bank.c b/src/trident_bank.c
new file mode 100644
index 0000000..056d64a
--- /dev/null
+++ b/src/trident_bank.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright 1992-2000 by Alan Hourihane, Wigan, England.
+ *
+ * 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, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Alan Hourihane, alanh@fairlite.demon.co.uk
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_bank.c,v 1.4 2000/12/07 16:48:04 alanh Exp $ */
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+#include "compiler.h"
+#include "trident.h"
+#include "trident_regs.h"
+
+int TVGA8900SetRead(ScreenPtr pScreen, int bank)
+{
+ ScrnInfoPtr pScrn;
+ TRIDENTPtr pTrident;
+ pScrn = xf86Screens[pScreen->myNum];
+ pTrident = TRIDENTPTR(pScrn);
+ OUTW(0x3c4, 0xC000 | (((bank & 0x3f) ^ 0x02)<<8)|0x0E);
+ return 0;
+}
+int TGUISetRead(ScreenPtr pScreen, int bank)
+{
+ ScrnInfoPtr pScrn;
+ TRIDENTPtr pTrident;
+ pScrn = xf86Screens[pScreen->myNum];
+ pTrident = TRIDENTPTR(pScrn);
+ OUTB(0x3d9, bank & 0xff);
+ return 0;
+}
+int TVGA8900SetWrite(ScreenPtr pScreen, int bank)
+{
+ ScrnInfoPtr pScrn;
+ TRIDENTPtr pTrident;
+ pScrn = xf86Screens[pScreen->myNum];
+ pTrident = TRIDENTPTR(pScrn);
+ OUTW(0x3c4, 0xC000 | (((bank & 0x3f) ^ 0x02)<<8)|0x0E);
+ return 0;
+}
+int TGUISetWrite(ScreenPtr pScreen, int bank)
+{
+ ScrnInfoPtr pScrn;
+ TRIDENTPtr pTrident;
+ pScrn = xf86Screens[pScreen->myNum];
+ pTrident = TRIDENTPTR(pScrn);
+ OUTB(0x3d8, bank & 0xff);
+ return 0;
+}
+int TVGA8900SetReadWrite(ScreenPtr pScreen, int bank)
+{
+ ScrnInfoPtr pScrn;
+ TRIDENTPtr pTrident;
+ pScrn = xf86Screens[pScreen->myNum];
+ pTrident = TRIDENTPTR(pScrn);
+ OUTW(0x3c4, 0xC000 | (((bank & 0x3f) ^ 0x02)<<8)|0x0E);
+ return 0;
+}
+int TGUISetReadWrite(ScreenPtr pScreen, int bank)
+{
+ ScrnInfoPtr pScrn;
+ TRIDENTPtr pTrident;
+ pScrn = xf86Screens[pScreen->myNum];
+ pTrident = TRIDENTPTR(pScrn);
+ OUTB(0x3d8, bank & 0xff);
+ OUTB(0x3d9, bank & 0xff);
+ return 0;
+}
diff --git a/src/trident_dac.c b/src/trident_dac.c
new file mode 100644
index 0000000..311dd81
--- /dev/null
+++ b/src/trident_dac.c
@@ -0,0 +1,1200 @@
+/*
+ * Copyright 1992-2000 by Alan Hourihane, Wigan, England.
+ *
+ * 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, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Alan Hourihane, alanh@fairlite.demon.co.uk
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c,v 1.70 2003/01/05 18:09:00 alanh Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Version.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "vgaHW.h"
+
+#include "trident.h"
+#include "trident_regs.h"
+
+
+static biosMode bios1[] = {
+ { 640, 480, 0x11 }
+};
+
+static biosMode bios4[] = {
+ { 320, 200, 0xd },
+ { 640, 200, 0xe },
+ { 640, 350, 0x11 },
+ { 640, 480, 0x12 },
+ { 800, 600, 0x5b },
+ { 1024, 768 , 0x5f },
+ { 1280, 1024, 0x63 },
+ { 1600, 1200, 0x65 }
+};
+
+static biosMode bios8[] = {
+ { 320, 200, 0x13 },
+ { 640, 400, 0x5c },
+ { 640, 480, 0x5d },
+ { 720, 480, 0x60 },
+ { 800, 600, 0x5e },
+ { 1024, 768, 0x62 },
+ { 1280, 1024, 0x64 },
+ { 1600, 1200, 0x66 }
+};
+
+static biosMode bios15[] = {
+ { 640, 400, 0x72 },
+ { 640, 480, 0x74 },
+ { 720, 480, 0x70 },
+ { 800, 600, 0x76 },
+ { 1024, 768, 0x78 },
+ { 1280, 1024, 0x7a },
+ { 1600, 1200, 0x7c }
+};
+
+static biosMode bios16[] = {
+ { 640, 400, 0x73 },
+ { 640, 480, 0x75 },
+ { 720, 480, 0x71 },
+ { 800, 600, 0x77 },
+ { 1024, 768, 0x79 },
+ { 1280, 1024, 0x7b },
+ { 1600, 1200, 0x7d }
+};
+
+static biosMode bios24[] = {
+ { 640, 400, 0x6b },
+ { 640, 480, 0x6c },
+ { 720, 480, 0x61 },
+ { 800, 600, 0x6d },
+ { 1024, 768, 0x6e }
+};
+
+static newModes newModeRegs [] = {
+ { 320, 200, 0x13, 0x30 },
+ { 640, 480, 0x13, 0x61 },
+ { 800, 600, 0x13, 0x61 },
+ { 1024, 768, 0x3b, 0x63 },
+ { 1280, 1024, 0x7b, 0x64 },
+ { 1400, 1050, 0x11, 0x7b }
+};
+
+int
+TridentFindMode(int xres, int yres, int depth)
+{
+ int xres_s;
+ int i, size;
+ biosMode *mode;
+
+ switch (depth) {
+ case 1:
+ size = sizeof(bios1) / sizeof(biosMode);
+ mode = bios1;
+ break;
+ case 4:
+ size = sizeof(bios4) / sizeof(biosMode);
+ mode = bios4;
+ break;
+ case 8:
+ size = sizeof(bios8) / sizeof(biosMode);
+ mode = bios8;
+ break;
+ case 15:
+ size = sizeof(bios15) / sizeof(biosMode);
+ mode = bios15;
+ break;
+ case 16:
+ size = sizeof(bios16) / sizeof(biosMode);
+ mode = bios16;
+ break;
+ case 24:
+ size = sizeof(bios24) / sizeof(biosMode);
+ mode = bios24;
+ break;
+ default:
+ return 0;
+ }
+
+ for (i = 0; i < size; i++) {
+ if (xres <= mode[i].x_res) {
+ xres_s = mode[i].x_res;
+ for (; i < size; i++) {
+ if (mode[i].x_res != xres_s)
+ return mode[i-1].mode;
+ if (yres <= mode[i].y_res)
+ return mode[i].mode;
+ }
+ }
+ }
+ return mode[size - 1].mode;
+}
+
+static void
+TridentFindNewMode(int xres, int yres, CARD8 *gr5a, CARD8 *gr5c)
+{
+ int xres_s;
+ int i, size;
+
+ size = sizeof(newModeRegs) / sizeof(newModes);
+
+ for (i = 0; i < size; i++) {
+ if (xres <= newModeRegs[i].x_res) {
+ xres_s = newModeRegs[i].x_res;
+ for (; i < size; i++) {
+ if (newModeRegs[i].x_res != xres_s
+ || yres <= newModeRegs[i].y_res) {
+ *gr5a = newModeRegs[i].GR5a;
+ *gr5c = newModeRegs[i].GR5c;
+ return;
+ }
+ }
+ }
+ }
+ *gr5a = newModeRegs[size - 1].GR5a;
+ *gr5c = newModeRegs[size - 1].GR5c;
+ return;
+}
+
+static void
+tridentSetBrightnessAndGamma(TRIDENTRegPtr tridentReg,
+ Bool on, double exp,int brightness)
+{
+ int pivots[] = {0,3,15,63,255};
+
+ double slope;
+ double y_0;
+ double x, x_prev = 0, y, y_prev = 0;
+ int i;
+ CARD8 i_slopes[4];
+ CARD8 intercepts[4];
+
+ if (!on) {
+ tridentReg->tridentRegs3C4[0xB4] &= ~0x80;
+ return;
+ }
+
+ for (i = 0; i < 4; i++) {
+ x = pivots[i + 1] / 255.0;
+ y = pow(x,exp);
+ slope = (y - y_prev) / (x - x_prev);
+ y_0 = y - x * slope;
+ {
+#define RND(x) ((((x) - (int) (x)) < 0.5) ? (int)(x) : (int)(x) + 1)
+ int val = slope;
+ if (val > 7)
+ i_slopes[i] = (3 << 4) | (RND(slope) & 0xf);
+ else if (val > 3)
+ i_slopes[i] = (2 << 4) | (RND(slope * 2) & 0xf);
+ else if (val > 1)
+ i_slopes[i] = (1 << 4) | (RND(slope * 4) & 0xf);
+ else
+ i_slopes[i] = (RND(slope * 8) & 0xf);
+#undef RND
+ }
+ intercepts[i] = (char)(y_0 * 256 / 4);
+ x_prev = x;
+ y_prev = y;
+ }
+
+ tridentReg->tridentRegs3C4[0xB4] = 0x80 | i_slopes[0];
+ tridentReg->tridentRegs3C4[0xB5] = i_slopes[1];
+ tridentReg->tridentRegs3C4[0xB6] = i_slopes[2];
+ tridentReg->tridentRegs3C4[0xB7] = i_slopes[3];
+ tridentReg->tridentRegs3C4[0xB8] = (intercepts[0] + brightness);
+ tridentReg->tridentRegs3C4[0xB9] = (intercepts[1] + brightness);
+ tridentReg->tridentRegs3C4[0xBA] = (intercepts[2] + brightness);
+ tridentReg->tridentRegs3C4[0xBB] = (intercepts[3] + brightness);
+}
+
+Bool
+TridentInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ TRIDENTRegPtr pReg = &pTrident->ModeReg;
+
+ int vgaIOBase;
+ int offset = 0;
+ int clock = pTrident->currentClock;
+ CARD8 protect = 0;
+ Bool fullSize = FALSE;
+ Bool isShadow = FALSE;
+
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr regp = &hwp->ModeReg;
+ vgaRegPtr vgaReg = &hwp->ModeReg;
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ /* Unprotect */
+ if (pTrident->Chipset > PROVIDIA9685) {
+ OUTB(0x3C4, Protection);
+ protect = INB(0x3C5);
+ OUTB(0x3C5, 0x92);
+ }
+
+ OUTB(0x3C4, 0x0B); INB(0x3C5); /* Ensure we are in New Mode */
+
+ pReg->tridentRegs3x4[PixelBusReg] = 0x00;
+ pReg->tridentRegsDAC[0x00] = 0x00;
+ pReg->tridentRegs3C4[NewMode2] = 0x20;
+ OUTB(0x3CE, MiscExtFunc);
+ pReg->tridentRegs3CE[MiscExtFunc] = INB(0x3CF) & 0xF0;
+ pReg->tridentRegs3x4[GraphEngReg] = 0x00;
+ pReg->tridentRegs3x4[PreEndControl] = 0;
+ pReg->tridentRegs3x4[PreEndFetch] = 0;
+
+ pReg->tridentRegs3x4[CRTHiOrd] = (((mode->CrtcVBlankEnd-1) & 0x400)>>4) |
+ (((mode->CrtcVTotal - 2) & 0x400) >> 3) |
+ ((mode->CrtcVSyncStart & 0x400) >> 5) |
+ (((mode->CrtcVDisplay - 1) & 0x400) >> 6)|
+ 0x08;
+
+ pReg->tridentRegs3x4[HorizOverflow] = ((mode->CrtcHTotal & 0x800) >> 11) |
+ ((mode->CrtcHBlankStart & 0x800)>>7);
+
+ if (pTrident->IsCyber) {
+ Bool LCDActive;
+#ifdef READOUT
+ Bool ShadowModeActive;
+#endif
+ int i = pTrident->lcdMode;
+#ifdef READOUT
+ OUTB(0x3CE, CyberControl);
+ ShadowModeActive = ((INB(0x3CF) & 0x81) == 0x81);
+#endif
+ OUTB(0x3CE, FPConfig);
+ pReg->tridentRegs3CE[FPConfig] = INB(0x3CF);
+ if (pTrident->dspOverride) {
+ if (pTrident->dspOverride & LCD_ACTIVE) {
+ pReg->tridentRegs3CE[FPConfig] |= 0x10;
+ LCDActive = TRUE;
+ } else {
+ pReg->tridentRegs3CE[FPConfig] &= ~0x10;
+ LCDActive = FALSE;
+ }
+ if (pTrident->dspOverride & CRT_ACTIVE)
+ pReg->tridentRegs3CE[FPConfig] |= 0x20;
+ else
+ pReg->tridentRegs3CE[FPConfig] &= ~0x20;
+ } else {
+ LCDActive = (pReg->tridentRegs3CE[FPConfig] & 0x10);
+ }
+
+ OUTB(0x3CE, CyberEnhance);
+#if 0
+ pReg->tridentRegs3CE[CyberEnhance] = INB(0x3CF);
+#else
+ pReg->tridentRegs3CE[CyberEnhance] = INB(0x3CF) & 0x8F;
+ if (mode->CrtcVDisplay > 1024)
+ pReg->tridentRegs3CE[CyberEnhance] |= 0x50;
+ else
+ if (mode->CrtcVDisplay > 768)
+ pReg->tridentRegs3CE[CyberEnhance] |= 0x30;
+ else
+ if (mode->CrtcVDisplay > 600)
+ pReg->tridentRegs3CE[CyberEnhance] |= 0x20;
+ else
+ if (mode->CrtcVDisplay > 480)
+ pReg->tridentRegs3CE[CyberEnhance] |= 0x10;
+#endif
+ OUTB(0x3CE, CyberControl);
+ pReg->tridentRegs3CE[CyberControl] = INB(0x3CF);
+
+ OUTB(0x3CE,HorStretch);
+ pReg->tridentRegs3CE[HorStretch] = INB(0x3CF);
+ OUTB(0x3CE,VertStretch);
+ pReg->tridentRegs3CE[VertStretch] = INB(0x3CF);
+
+#ifdef READOUT
+ if ((!((pReg->tridentRegs3CE[VertStretch] & 1) ||
+ (pReg->tridentRegs3CE[HorStretch] & 1)))
+ && (!LCDActive || ShadowModeActive))
+ {
+ unsigned char tmp;
+
+ SHADOW_ENABLE(tmp);
+ OUTB(vgaIOBase + 4,0);
+ pReg->tridentRegs3x4[0x0] = INB(vgaIOBase + 5);
+ OUTB(vgaIOBase + 4,3);
+ pReg->tridentRegs3x4[0x3] = INB(vgaIOBase + 5);
+ OUTB(vgaIOBase + 4,4);
+ pReg->tridentRegs3x4[0x4] = INB(vgaIOBase + 5);
+ OUTB(vgaIOBase + 4,5);
+ pReg->tridentRegs3x4[0x5] = INB(vgaIOBase + 5);
+ OUTB(vgaIOBase + 4,0x6);
+ pReg->tridentRegs3x4[0x6] = INB(vgaIOBase + 5);
+ SHADOW_RESTORE(tmp);
+ } else
+#endif
+ {
+ if (i != 0xff) {
+ pReg->tridentRegs3x4[0x0] = LCD[i].shadow_0;
+ pReg->tridentRegs3x4[0x1] = regp->CRTC[1];
+ pReg->tridentRegs3x4[0x2] = regp->CRTC[2];
+ pReg->tridentRegs3x4[0x3] = LCD[i].shadow_3;
+ pReg->tridentRegs3x4[0x4] = LCD[i].shadow_4;
+ pReg->tridentRegs3x4[0x5] = LCD[i].shadow_5;
+ pReg->tridentRegs3x4[0x6] = LCD[i].shadow_6;
+ xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,
+ "Overriding Horizontal timings.\n");
+ }
+ }
+
+ if (i != 0xff) {
+ pReg->tridentRegs3x4[0x7] = LCD[i].shadow_7;
+ pReg->tridentRegs3x4[0x10] = LCD[i].shadow_10;
+ pReg->tridentRegs3x4[0x11] = LCD[i].shadow_11;
+ pReg->tridentRegs3x4[0x12] = regp->CRTC[0x12];
+ pReg->tridentRegs3x4[0x15] = regp->CRTC[0x15];
+ pReg->tridentRegs3x4[0x16] = LCD[i].shadow_16;
+ if (LCDActive) {
+ pReg->tridentRegs3x4[CRTHiOrd] = LCD[i].shadow_HiOrd;
+ }
+
+ fullSize = (pScrn->currentMode->HDisplay == LCD[i].display_x)
+ && (pScrn->currentMode->VDisplay == LCD[i].display_y);
+ }
+
+ /* copy over common bits from normal VGA */
+
+ pReg->tridentRegs3x4[0x7] &= ~0x4A;
+ pReg->tridentRegs3x4[0x7] |= (vgaReg->CRTC[0x7] & 0x4A);
+
+ if (LCDActive && fullSize) {
+ regp->CRTC[0] = pReg->tridentRegs3x4[0];
+ regp->CRTC[3] = pReg->tridentRegs3x4[3];
+ regp->CRTC[4] = pReg->tridentRegs3x4[4];
+ regp->CRTC[5] = pReg->tridentRegs3x4[5];
+ regp->CRTC[6] = pReg->tridentRegs3x4[6];
+ regp->CRTC[7] = pReg->tridentRegs3x4[7];
+ regp->CRTC[0x10] = pReg->tridentRegs3x4[0x10];
+ regp->CRTC[0x11] = pReg->tridentRegs3x4[0x11];
+ regp->CRTC[0x16] = pReg->tridentRegs3x4[0x16];
+ }
+ if (LCDActive && !fullSize) {
+ /*
+ * Set negative h/vsync polarity to center display nicely
+ * Seems to work on several systems.
+ */
+ regp->MiscOutReg |= 0xC0;
+ /*
+ * If the LCD is active and we don't fill the entire screen
+ * and the previous mode was stretched we may need help from
+ * the BIOS to set all registers for the unstreched mode.
+ */
+ pTrident->doInit = ((pReg->tridentRegs3CE[HorStretch] & 1)
+ || (pReg->tridentRegs3CE[VertStretch] & 1));
+ pReg->tridentRegs3CE[CyberControl] |= 0x81;
+ xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"Shadow on\n");
+ isShadow = TRUE;
+ } else {
+ pReg->tridentRegs3CE[CyberControl] &= 0x7E;
+ xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"Shadow off\n");
+ }
+ if (pTrident->FPDelay < 6) {
+ pReg->tridentRegs3CE[CyberControl] &= 0xC7;
+ pReg->tridentRegs3CE[CyberControl] |= (pTrident->FPDelay + 2) << 3;
+ }
+
+ if (pTrident->CyberShadow) {
+ pReg->tridentRegs3CE[CyberControl] &= 0x7E;
+ isShadow = FALSE;
+ xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"Forcing Shadow off\n");
+ }
+
+ xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"H-timing shadow registers:"
+ " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
+ pReg->tridentRegs3x4[0], pReg->tridentRegs3x4[3],
+ pReg->tridentRegs3x4[4], pReg->tridentRegs3x4[5]);
+ xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"H-timing registers: "
+ " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
+ regp->CRTC[0], regp->CRTC[1], regp->CRTC[2],
+ regp->CRTC[3], regp->CRTC[4], regp->CRTC[5]);
+ xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"V-timing shadow registers: "
+ "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x"
+ " 0x%2.2x (0x%2.2x)\n",
+ pReg->tridentRegs3x4[6], pReg->tridentRegs3x4[7],
+ pReg->tridentRegs3x4[0x10],pReg->tridentRegs3x4[0x11],
+ pReg->tridentRegs3x4[0x16],
+ pReg->tridentRegs3x4[CRTHiOrd]);
+ xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"V-timing registers: "
+ "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
+ "0x%2.2x 0x%2.2x 0x%2.2x\n",
+ regp->CRTC[6], regp->CRTC[7], regp->CRTC[0x10],
+ regp->CRTC[0x11],regp->CRTC[0x12],
+ regp->CRTC[0x14],regp->CRTC[0x16]);
+
+
+ /* disable stretching, enable centering */
+ pReg->tridentRegs3CE[VertStretch] &= 0xFC;
+ pReg->tridentRegs3CE[VertStretch] |= 0x80;
+ pReg->tridentRegs3CE[HorStretch] &= 0xFC;
+ pReg->tridentRegs3CE[HorStretch] |= 0x80;
+#if 1
+ {
+ int mul = pScrn->bitsPerPixel >> 3;
+ int val;
+
+ if (!mul) mul = 1;
+
+ /* this is what my BIOS does */
+ val = (pScrn->currentMode->HDisplay * mul / 8) + 16;
+
+ pReg->tridentRegs3x4[PreEndControl] = ((val >> 8) < 2 ? 2 :0)
+ | ((val >> 8) & 0x01);
+ pReg->tridentRegs3x4[PreEndFetch] = val & 0xff;
+ }
+#else
+ OUTB(vgaIOBase + 4,PreEndControl);
+ pReg->tridentRegs3x4[PreEndControl] = INB(vgaIOBase + 5);
+ OUTB(vgaIOBase + 4,PreEndFetch);
+ pReg->tridentRegs3x4[PreEndFetch] = INB(vgaIOBase + 5);
+#endif
+ /* set mode */
+ if (pTrident->Chipset < BLADEXP) {
+ pReg->tridentRegs3CE[BiosMode] = TridentFindMode(
+ pScrn->currentMode->HDisplay,
+ pScrn->currentMode->VDisplay,
+ pScrn->depth);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 1,
+ "Setting BIOS Mode: %x\n",
+ pReg->tridentRegs3CE[BiosMode]);
+ } else {
+ TridentFindNewMode(pScrn->currentMode->HDisplay,
+ pScrn->currentMode->VDisplay,
+ &pReg->tridentRegs3CE[BiosNewMode1],
+ &pReg->tridentRegs3CE[BiosNewMode2]);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 1,
+ "Setting BIOS Mode Regs: %x %x\n",
+ pReg->tridentRegs3CE[BiosNewMode1],
+ pReg->tridentRegs3CE[BiosNewMode2]);
+ };
+
+ /* no stretch */
+ if (pTrident->Chipset != CYBERBLADEXPAI1)
+ pReg->tridentRegs3CE[BiosReg] = 0;
+ else
+ pReg->tridentRegs3CE[BiosReg] = 8;
+
+ if (pTrident->CyberStretch) {
+ pReg->tridentRegs3CE[VertStretch] |= 0x01;
+ pReg->tridentRegs3CE[HorStretch] |= 0x01;
+ xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"Enabling StretchMode\n");
+ }
+ }
+
+ /* Enable Chipset specific options */
+ switch (pTrident->Chipset) {
+ case CYBERBLADEXPAI1:
+ case BLADEXP:
+ case CYBERBLADEI7:
+ case CYBERBLADEI7D:
+ case CYBERBLADEI1:
+ case CYBERBLADEI1D:
+ case CYBERBLADEAI1:
+ case CYBERBLADEAI1D:
+ case CYBERBLADEE4:
+ case BLADE3D:
+ OUTB(vgaIOBase + 4, RAMDACTiming);
+ pReg->tridentRegs3x4[RAMDACTiming] = INB(vgaIOBase + 5) | 0x0F;
+ /* Fall Through */
+ case CYBER9520:
+ case CYBER9525DVD:
+ case CYBER9397DVD:
+ case CYBER9397:
+ case IMAGE975:
+ case IMAGE985:
+ case CYBER9388:
+ if (pScrn->bitsPerPixel >= 8)
+ pReg->tridentRegs3CE[MiscExtFunc] |= 0x10;
+ else
+ pReg->tridentRegs3CE[MiscExtFunc] &= ~0x10;
+ if (!pReg->tridentRegs3x4[PreEndControl])
+ pReg->tridentRegs3x4[PreEndControl] = 0x01;
+ if (!pReg->tridentRegs3x4[PreEndFetch])
+ pReg->tridentRegs3x4[PreEndFetch] = 0xFF;
+ /* Fall Through */
+ case PROVIDIA9685:
+ case CYBER9385:
+ pReg->tridentRegs3x4[Enhancement0] = 0x40;
+ /* Fall Through */
+ case PROVIDIA9682:
+ case CYBER9382:
+ if (pTrident->UsePCIRetry)
+ pReg->tridentRegs3x4[PCIRetry] = 0xDF;
+ else
+ pReg->tridentRegs3x4[PCIRetry] = 0x1F;
+ /* Fall Through */
+ case TGUI9660:
+ case TGUI9680:
+ if (pTrident->MUX && pScrn->bitsPerPixel == 8) {
+ pReg->tridentRegs3x4[PixelBusReg] |= 0x01; /* 16bit bus */
+ pReg->tridentRegs3C4[NewMode2] |= 0x02; /* half clock */
+ pReg->tridentRegsDAC[0x00] |= 0x20; /* mux mode */
+ }
+ }
+
+ /* Defaults for all trident chipsets follows */
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ case 4:
+ offset = pScrn->displayWidth >> 4;
+ break;
+ case 8:
+ pReg->tridentRegs3CE[MiscExtFunc] |= 0x02;
+ offset = pScrn->displayWidth >> 3;
+ break;
+ case 16:
+ pReg->tridentRegs3CE[MiscExtFunc] |= 0x02;
+ offset = pScrn->displayWidth >> 2;
+ if (pScrn->depth == 15)
+ pReg->tridentRegsDAC[0x00] = 0x10;
+ else
+ pReg->tridentRegsDAC[0x00] = 0x30;
+ pReg->tridentRegs3x4[PixelBusReg] = 0x04;
+ /* Reload with any chipset specific stuff here */
+ if (pTrident->Chipset >= TGUI9660)
+ pReg->tridentRegs3x4[PixelBusReg] |= 0x01;
+ if (pTrident->Chipset == TGUI9440AGi) {
+ pReg->tridentRegs3CE[MiscExtFunc] |= 0x08;/*Clock Division / 2*/
+ clock *= 2; /* Double the clock */
+ }
+ break;
+ case 24:
+ pReg->tridentRegs3CE[MiscExtFunc] |= 0x02;
+ offset = (pScrn->displayWidth * 3) >> 3;
+ pReg->tridentRegs3x4[PixelBusReg] = 0x29;
+ pReg->tridentRegsDAC[0x00] = 0xD0;
+ if (pTrident->Chipset == CYBERBLADEE4) {
+ OUTB(vgaIOBase+ 4, New32);
+ pReg->tridentRegs3x4[New32] = INB(vgaIOBase + 5) & 0x7F;
+ }
+ break;
+ case 32:
+ pReg->tridentRegs3CE[MiscExtFunc] |= 0x02;
+ if (pTrident->Chipset != CYBERBLADEE4
+ && pTrident->Chipset != CYBERBLADEXPAI1) {
+ /* Clock Division by 2*/
+ pReg->tridentRegs3CE[MiscExtFunc] |= 0x08;
+ clock *= 2; /* Double the clock */
+ }
+ offset = pScrn->displayWidth >> 1;
+ pReg->tridentRegs3x4[PixelBusReg] = 0x09;
+ pReg->tridentRegsDAC[0x00] = 0xD0;
+ if (pTrident->Chipset == CYBERBLADEE4
+ || pTrident->Chipset == CYBERBLADEXPAI1) {
+ OUTB(vgaIOBase+ 4, New32);
+ pReg->tridentRegs3x4[New32] = INB(vgaIOBase + 5) | 0x80;
+ /* With new mode 32bpp we set the packed flag */
+ pReg->tridentRegs3x4[PixelBusReg] |= 0x20;
+ }
+ break;
+ }
+ pReg->tridentRegs3x4[Offset] = offset & 0xFF;
+
+ {
+ CARD8 a, b;
+ TGUISetClock(pScrn, clock, &a, &b);
+ pReg->tridentRegsClock[0x00] = (regp->MiscOutReg & 0xF3) | 0x08;
+ pReg->tridentRegsClock[0x01] = a;
+ pReg->tridentRegsClock[0x02] = b;
+ if (pTrident->MCLK > 0) {
+ TGUISetMCLK(pScrn, pTrident->MCLK, &a, &b);
+ pReg->tridentRegsClock[0x03] = a;
+ pReg->tridentRegsClock[0x04] = b;
+ }
+ }
+
+ pReg->tridentRegs3C4[NewMode1] = 0xC0;
+ pReg->tridentRegs3C4[Protection] = 0x92;
+
+ pReg->tridentRegs3x4[LinearAddReg] = 0;
+ if (pTrident->Linear) {
+ /* This is used for VLB, when we support it again in 4.0 */
+ if (pTrident->Chipset < CYBER9385)
+ pReg->tridentRegs3x4[LinearAddReg] |=
+ ((pTrident->FbAddress >> 24) << 6)|
+ ((pTrident->FbAddress >> 20) & 0x0F);
+ /* Turn on linear mapping */
+ pReg->tridentRegs3x4[LinearAddReg] |= 0x20;
+ } else {
+ pReg->tridentRegs3CE[MiscExtFunc] |= 0x04;
+ }
+
+ pReg->tridentRegs3x4[CRTCModuleTest] =
+ (mode->Flags & V_INTERLACE ? 0x84 : 0x80);
+
+ OUTB(vgaIOBase+ 4, InterfaceSel);
+ pReg->tridentRegs3x4[InterfaceSel] = INB(vgaIOBase + 5) | 0x40;
+
+ OUTB(vgaIOBase+ 4, Performance);
+ pReg->tridentRegs3x4[Performance] = INB(vgaIOBase + 5);
+ if (pTrident->Chipset < BLADEXP)
+ pReg->tridentRegs3x4[Performance] |= 0x10;
+
+ OUTB(vgaIOBase+ 4, DRAMControl);
+ pReg->tridentRegs3x4[DRAMControl] = INB(vgaIOBase + 5) | 0x10;
+
+ if (pTrident->IsCyber && !pTrident->MMIOonly)
+ pReg->tridentRegs3x4[DRAMControl] |= 0x20;
+
+ if (pTrident->NewClockCode && pTrident->Chipset <= CYBER9397DVD) {
+ OUTB(vgaIOBase + 4, ClockControl);
+ pReg->tridentRegs3x4[ClockControl] = INB(vgaIOBase + 5) | 0x01;
+ }
+
+ OUTB(vgaIOBase+ 4, AddColReg);
+ pReg->tridentRegs3x4[AddColReg] = INB(vgaIOBase + 5) & 0xEF;
+ pReg->tridentRegs3x4[AddColReg] |= (offset & 0x100) >> 4;
+
+ if (pTrident->Chipset >= TGUI9660) {
+ pReg->tridentRegs3x4[AddColReg] &= 0xDF;
+ pReg->tridentRegs3x4[AddColReg] |= (offset & 0x200) >> 4;
+ }
+
+ if (IsPciCard && UseMMIO) {
+ if (!pTrident->NoAccel)
+ pReg->tridentRegs3x4[GraphEngReg] |= 0x80;
+ } else {
+ if (!pTrident->NoAccel)
+ pReg->tridentRegs3x4[GraphEngReg] |= 0x82;
+ }
+
+ OUTB(0x3CE, MiscIntContReg);
+ pReg->tridentRegs3CE[MiscIntContReg] = INB(0x3CF) | 0x04;
+
+ /* Fix hashing problem in > 8bpp on 9320 chipset */
+ if (pTrident->Chipset == CYBER9320 && pScrn->bitsPerPixel > 8)
+ pReg->tridentRegs3CE[MiscIntContReg] &= ~0x80;
+
+ OUTB(vgaIOBase+ 4, PCIReg);
+ if (IsPciCard && UseMMIO)
+ pReg->tridentRegs3x4[PCIReg] = INB(vgaIOBase + 5) & 0xF9;
+ else
+ pReg->tridentRegs3x4[PCIReg] = INB(vgaIOBase + 5) & 0xF8;
+
+ /* Enable PCI Bursting on capable chips */
+ if (pTrident->Chipset >= TGUI9660) {
+ if(pTrident->UsePCIBurst) {
+ pReg->tridentRegs3x4[PCIReg] |= 0x06;
+ } else {
+ pReg->tridentRegs3x4[PCIReg] &= 0xF9;
+ }
+ }
+
+ if (pTrident->Chipset >= CYBER9388) {
+ if (pTrident->GammaBrightnessOn)
+ xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,
+ "Setting Gamma: %f Brightness: %i\n",
+ pTrident->gamma, pTrident->brightness);
+ tridentSetBrightnessAndGamma(pReg,
+ pTrident->GammaBrightnessOn,
+ pTrident->gamma, pTrident->brightness);
+ }
+
+ /* Video */
+ OUTB(0x3C4,0x20);
+ pReg->tridentRegs3C4[SSetup] = INB(0x3C5) | 0x4;
+ pReg->tridentRegs3C4[SKey] = 0x00;
+ pReg->tridentRegs3C4[SPKey] = 0xC0;
+ OUTB(0x3C4,0x12);
+ pReg->tridentRegs3C4[Threshold] = INB(0x3C5);
+ if (pScrn->bitsPerPixel > 16)
+ pReg->tridentRegs3C4[Threshold] =
+ (pReg->tridentRegs3C4[Threshold] & 0xf0) | 0x2;
+
+ /* restore */
+ if (pTrident->Chipset > PROVIDIA9685) {
+ OUTB(0x3C4, Protection);
+ OUTB(0x3C5, protect);
+ }
+
+ return(TRUE);
+}
+
+void
+TridentRestore(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ CARD8 temp;
+ int vgaIOBase;
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ if (pTrident->Chipset > PROVIDIA9685) {
+ OUTB(0x3C4, Protection);
+ OUTB(0x3C5, 0x92);
+ }
+#if 0
+ if (pTrident->doInit && pTrident->Int10) {
+ OUTW_3CE(BiosReg);
+ }
+#endif
+ /* Goto New Mode */
+ OUTB(0x3C4, 0x0B);
+ temp = INB(0x3C5);
+
+ /* Unprotect registers */
+ OUTW(0x3C4, ((0xC0 ^ 0x02) << 8) | NewMode1);
+
+ temp = INB(0x3C8);
+ temp = INB(0x3C6);
+ temp = INB(0x3C6);
+ temp = INB(0x3C6);
+ temp = INB(0x3C6);
+ OUTB(0x3C6, tridentReg->tridentRegsDAC[0x00]);
+ temp = INB(0x3C8);
+
+ OUTW_3x4(CRTCModuleTest);
+ OUTW_3x4(LinearAddReg);
+ OUTW_3C4(NewMode2);
+ OUTW_3x4(CursorControl);
+ OUTW_3x4(CRTHiOrd);
+ OUTW_3x4(HorizOverflow);
+ OUTW_3x4(AddColReg);
+ OUTW_3x4(GraphEngReg);
+ OUTW_3x4(Performance);
+ OUTW_3x4(InterfaceSel);
+ OUTW_3x4(DRAMControl);
+ OUTW_3x4(PixelBusReg);
+ OUTW_3x4(PCIReg);
+ OUTW_3x4(PCIRetry);
+ OUTW_3CE(MiscIntContReg);
+ OUTW_3CE(MiscExtFunc);
+ OUTW_3x4(Offset);
+ if (pTrident->NewClockCode && pTrident->Chipset <= CYBER9397DVD)
+ OUTW_3x4(ClockControl);
+ if (pTrident->Chipset >= CYBER9388) {
+ OUTW_3C4(Threshold);
+ OUTW_3C4(SSetup);
+ OUTW_3C4(SKey);
+ OUTW_3C4(SPKey);
+ OUTW_3x4(PreEndControl);
+ OUTW_3x4(PreEndFetch);
+ OUTW_3C4(GBslope1);
+ OUTW_3C4(GBslope2);
+ OUTW_3C4(GBslope3);
+ OUTW_3C4(GBslope4);
+ OUTW_3C4(GBintercept1);
+ OUTW_3C4(GBintercept2);
+ OUTW_3C4(GBintercept3);
+ OUTW_3C4(GBintercept4);
+ }
+ if (pTrident->Chipset >= CYBER9385) OUTW_3x4(Enhancement0);
+ if (pTrident->Chipset >= BLADE3D) OUTW_3x4(RAMDACTiming);
+ if (pTrident->Chipset == CYBERBLADEE4) OUTW_3x4(New32);
+ if (pTrident->IsCyber) {
+ CARD8 tmp;
+
+ OUTW_3CE(VertStretch);
+ OUTW_3CE(HorStretch);
+ if (pTrident->Chipset < BLADEXP) {
+ OUTW_3CE(BiosMode);
+ } else {
+ OUTW_3CE(BiosNewMode1);
+ OUTW_3CE(BiosNewMode2);
+ };
+ OUTW_3CE(BiosReg);
+ OUTW_3CE(FPConfig);
+ OUTW_3CE(CyberControl);
+ OUTW_3CE(CyberEnhance);
+ SHADOW_ENABLE(tmp);
+ OUTW_3x4(0x0);
+ if (pTrident->shadowNew) {
+ OUTW_3x4(0x1);
+ OUTW_3x4(0x2);
+ }
+ OUTW_3x4(0x3);
+ OUTW_3x4(0x4);
+ OUTW_3x4(0x5);
+ OUTW_3x4(0x6);
+ OUTW_3x4(0x7);
+ OUTW_3x4(0x10);
+ OUTW_3x4(0x11);
+ if (pTrident->shadowNew) {
+ OUTW_3x4(0x12);
+ OUTW_3x4(0x15);
+ }
+ OUTW_3x4(0x16);
+ SHADOW_RESTORE(tmp);
+ }
+
+ if (Is3Dchip) {
+#ifdef READOUT
+ if (!pTrident->DontSetClock)
+#endif
+ {
+ OUTW(0x3C4, (tridentReg->tridentRegsClock[0x01])<<8 | ClockLow);
+ OUTW(0x3C4, (tridentReg->tridentRegsClock[0x02])<<8 | ClockHigh);
+ }
+ if (pTrident->MCLK > 0) {
+ OUTW(0x3C4,(tridentReg->tridentRegsClock[0x03])<<8 | MCLKLow);
+ OUTW(0x3C4,(tridentReg->tridentRegsClock[0x04])<<8 | MCLKHigh);
+ }
+ } else {
+#ifdef READOUT
+ if (!pTrident->DontSetClock)
+#endif
+ {
+ OUTB(0x43C8, tridentReg->tridentRegsClock[0x01]);
+ OUTB(0x43C9, tridentReg->tridentRegsClock[0x02]);
+ }
+ if (pTrident->MCLK > 0) {
+ OUTB(0x43C6, tridentReg->tridentRegsClock[0x03]);
+ OUTB(0x43C7, tridentReg->tridentRegsClock[0x04]);
+ }
+ }
+#ifdef READOUT
+ if (!pTrident->DontSetClock)
+#endif
+ {
+ OUTB(0x3C2, tridentReg->tridentRegsClock[0x00]);
+ }
+
+ if (pTrident->Chipset > PROVIDIA9685) {
+ OUTB(0x3C4, Protection);
+ OUTB(0x3C5, tridentReg->tridentRegs3C4[Protection]);
+ }
+
+ OUTW(0x3C4, ((tridentReg->tridentRegs3C4[NewMode1] ^ 0x02) << 8)| NewMode1);
+}
+
+void
+TridentSave(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ CARD8 temp;
+ int vgaIOBase;
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ /* Goto New Mode */
+ OUTB(0x3C4, 0x0B);
+ temp = INB(0x3C5);
+
+ INB_3C4(NewMode1);
+ if (pTrident->Chipset > PROVIDIA9685)
+ INB_3C4(Protection);
+
+ /* Unprotect registers */
+ OUTW(0x3C4, ((0xC0 ^ 0x02) << 8) | NewMode1);
+ if (pTrident->Chipset > PROVIDIA9685)
+ OUTW(0x3C4, (0x92 << 8) | Protection);
+
+ INB_3x4(Offset);
+ INB_3x4(LinearAddReg);
+ INB_3x4(CRTCModuleTest);
+ INB_3x4(CRTHiOrd);
+ INB_3x4(HorizOverflow);
+ INB_3x4(Performance);
+ INB_3x4(InterfaceSel);
+ INB_3x4(DRAMControl);
+ INB_3x4(AddColReg);
+ INB_3x4(PixelBusReg);
+ INB_3x4(GraphEngReg);
+ INB_3x4(PCIReg);
+ INB_3x4(PCIRetry);
+ if (pTrident->NewClockCode && pTrident->Chipset <= CYBER9397DVD)
+ INB_3x4(ClockControl);
+ if (pTrident->Chipset >= CYBER9388) {
+ INB_3C4(Threshold);
+ INB_3C4(SSetup);
+ INB_3C4(SKey);
+ INB_3C4(SPKey);
+ INB_3x4(PreEndControl);
+ INB_3x4(PreEndFetch);
+ INB_3C4(GBslope1);
+ INB_3C4(GBslope2);
+ INB_3C4(GBslope3);
+ INB_3C4(GBslope4);
+ INB_3C4(GBintercept1);
+ INB_3C4(GBintercept2);
+ INB_3C4(GBintercept3);
+ INB_3C4(GBintercept4);
+ }
+ if (pTrident->Chipset >= CYBER9385) INB_3x4(Enhancement0);
+ if (pTrident->Chipset >= BLADE3D) INB_3x4(RAMDACTiming);
+ if (pTrident->Chipset == CYBERBLADEE4) INB_3x4(New32);
+ if (pTrident->IsCyber) {
+ CARD8 tmp;
+ INB_3CE(VertStretch);
+ INB_3CE(HorStretch);
+ if (pTrident->Chipset < BLADEXP) {
+ INB_3CE(BiosMode);
+ } else {
+ INB_3CE(BiosNewMode1);
+ INB_3CE(BiosNewMode2);
+ }
+ INB_3CE(BiosReg);
+ INB_3CE(FPConfig);
+ INB_3CE(CyberControl);
+ INB_3CE(CyberEnhance);
+ SHADOW_ENABLE(tmp);
+ INB_3x4(0x0);
+ if (pTrident->shadowNew) {
+ INB_3x4(0x1);
+ INB_3x4(0x2);
+ }
+ INB_3x4(0x3);
+ INB_3x4(0x4);
+ INB_3x4(0x5);
+ INB_3x4(0x6);
+ INB_3x4(0x7);
+ INB_3x4(0x10);
+ INB_3x4(0x11);
+ if (pTrident->shadowNew) {
+ INB_3x4(0x12);
+ INB_3x4(0x15);
+ }
+ INB_3x4(0x16);
+ SHADOW_RESTORE(tmp);
+ }
+
+ /* save cursor registers */
+ INB_3x4(CursorControl);
+
+ INB_3CE(MiscExtFunc);
+ INB_3CE(MiscIntContReg);
+
+ temp = INB(0x3C8);
+ temp = INB(0x3C6);
+ temp = INB(0x3C6);
+ temp = INB(0x3C6);
+ temp = INB(0x3C6);
+ tridentReg->tridentRegsDAC[0x00] = INB(0x3C6);
+ temp = INB(0x3C8);
+
+ tridentReg->tridentRegsClock[0x00] = INB(0x3CC);
+ if (Is3Dchip) {
+ OUTB(0x3C4, ClockLow);
+ tridentReg->tridentRegsClock[0x01] = INB(0x3C5);
+ OUTB(0x3C4, ClockHigh);
+ tridentReg->tridentRegsClock[0x02] = INB(0x3C5);
+ if (pTrident->MCLK > 0) {
+ OUTB(0x3C4, MCLKLow);
+ tridentReg->tridentRegsClock[0x03] = INB(0x3C5);
+ OUTB(0x3C4, MCLKHigh);
+ tridentReg->tridentRegsClock[0x04] = INB(0x3C5);
+ }
+ } else {
+ tridentReg->tridentRegsClock[0x01] = INB(0x43C8);
+ tridentReg->tridentRegsClock[0x02] = INB(0x43C9);
+ if (pTrident->MCLK > 0) {
+ tridentReg->tridentRegsClock[0x03] = INB(0x43C6);
+ tridentReg->tridentRegsClock[0x04] = INB(0x43C7);
+ }
+ }
+
+ INB_3C4(NewMode2);
+
+ /* Protect registers */
+ OUTW_3C4(NewMode1);
+}
+
+static void
+TridentShowCursor(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int vgaIOBase;
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ /* 64x64 */
+ OUTW(vgaIOBase + 4, 0xC150);
+}
+
+static void
+TridentHideCursor(ScrnInfoPtr pScrn) {
+ int vgaIOBase;
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ OUTW(vgaIOBase + 4, 0x4150);
+}
+
+static void
+TridentSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ int vgaIOBase;
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ if (x < 0) {
+ OUTW(vgaIOBase + 4, (-x)<<8 | 0x46);
+ x = 0;
+ } else
+ OUTW(vgaIOBase + 4, 0x0046);
+
+ if (y < 0) {
+ OUTW(vgaIOBase + 4, (-y)<<8 | 0x47);
+ y = 0;
+ } else
+ OUTW(vgaIOBase + 4, 0x0047);
+
+ OUTW(vgaIOBase + 4, (x&0xFF)<<8 | 0x40);
+ OUTW(vgaIOBase + 4, (x&0x0F00) | 0x41);
+ OUTW(vgaIOBase + 4, (y&0xFF)<<8 | 0x42);
+ OUTW(vgaIOBase + 4, (y&0x0F00) | 0x43);
+}
+
+static void
+TridentSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ int vgaIOBase;
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+ OUTW(vgaIOBase + 4, (fg & 0x000000FF)<<8 | 0x48);
+ OUTW(vgaIOBase + 4, (fg & 0x0000FF00) | 0x49);
+ OUTW(vgaIOBase + 4, (fg & 0x00FF0000)>>8 | 0x4A);
+ OUTW(vgaIOBase + 4, (fg & 0xFF000000)>>16 | 0x4B);
+ OUTW(vgaIOBase + 4, (bg & 0x000000FF)<<8 | 0x4C);
+ OUTW(vgaIOBase + 4, (bg & 0x0000FF00) | 0x4D);
+ OUTW(vgaIOBase + 4, (bg & 0x00FF0000)>>8 | 0x4E);
+ OUTW(vgaIOBase + 4, (bg & 0xFF000000)>>16 | 0x4F);
+}
+
+static void
+TridentLoadCursorImage(
+ ScrnInfoPtr pScrn,
+ CARD8 *src
+)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int vgaIOBase;
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ memcpy((CARD8 *)pTrident->FbBase + (pScrn->videoRam * 1024) - 4096,
+ src, pTrident->CursorInfoRec->MaxWidth *
+ pTrident->CursorInfoRec->MaxHeight / 4);
+
+ OUTW(vgaIOBase + 4, (((pScrn->videoRam-4) & 0xFF) << 8) | 0x44);
+ OUTW(vgaIOBase + 4, ((pScrn->videoRam-4) & 0xFF00) | 0x45);
+}
+
+static Bool
+TridentUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if (pTrident->MUX && pScrn->bitsPerPixel == 8) return FALSE;
+
+ if (!pTrident->HWCursor) return FALSE;
+
+ return TRUE;
+}
+
+Bool
+TridentHWCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+ int memory = pScrn->displayWidth * pScrn->virtualY * pScrn->bitsPerPixel/8;
+
+ if (memory > (pScrn->videoRam * 1024 - 4096)) return FALSE;
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr) return FALSE;
+
+ pTrident->CursorInfoRec = infoPtr;
+
+ infoPtr->MaxWidth = 64;
+ infoPtr->MaxHeight = 64;
+ infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+ HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 |
+ ((pTrident->Chipset == CYBERBLADEE4) ?
+ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP : 0);
+ infoPtr->SetCursorColors = TridentSetCursorColors;
+ infoPtr->SetCursorPosition = TridentSetCursorPosition;
+ infoPtr->LoadCursorImage = TridentLoadCursorImage;
+ infoPtr->HideCursor = TridentHideCursor;
+ infoPtr->ShowCursor = TridentShowCursor;
+ infoPtr->UseHWCursor = TridentUseHWCursor;
+
+ return(xf86InitCursor(pScreen, infoPtr));
+}
+
+unsigned int
+Tridentddc1Read(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+ CARD8 temp;
+
+ /* New mode */
+ OUTB(0x3C4, 0x0B); temp = INB(0x3C5);
+
+ OUTB(0x3C4, NewMode1);
+ temp = INB(0x3C5);
+ OUTB(0x3C5, temp | 0x80);
+
+ /* Define SDA as input */
+ OUTW(vgaIOBase + 4, (0x04 << 8) | I2C);
+
+ OUTW(0x3C4, (temp << 8) | NewMode1);
+
+ /* Wait until vertical retrace is in progress. */
+ while (INB(vgaIOBase + 0xA) & 0x08);
+ while (!(INB(vgaIOBase + 0xA) & 0x08));
+
+ /* Get the result */
+ OUTB(vgaIOBase + 4, I2C);
+ return ( INB(vgaIOBase + 5) & 0x01 );
+}
+
+void TridentSetOverscan(
+ ScrnInfoPtr pScrn,
+ int overscan
+){
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ if (overscan < 0 || overscan > 255)
+ return;
+
+ hwp->enablePalette(hwp);
+ hwp->writeAttr(hwp, OVERSCAN, overscan);
+ hwp->disablePalette(hwp);
+}
+
+void TridentLoadPalette(
+ ScrnInfoPtr pScrn,
+ int numColors,
+ int *indicies,
+ LOCO *colors,
+ VisualPtr pVisual
+){
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int i, index;
+ for(i = 0; i < numColors; i++) {
+ index = indicies[i];
+ OUTB(0x3C6, 0xFF);
+ DACDelay(hwp);
+ OUTB(0x3c8, index);
+ DACDelay(hwp);
+ OUTB(0x3c9, colors[index].red);
+ DACDelay(hwp);
+ OUTB(0x3c9, colors[index].green);
+ DACDelay(hwp);
+ OUTB(0x3c9, colors[index].blue);
+ DACDelay(hwp);
+ }
+}
+
diff --git a/src/trident_dga.c b/src/trident_dga.c
new file mode 100644
index 0000000..4045194
--- /dev/null
+++ b/src/trident_dga.c
@@ -0,0 +1,275 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dga.c,v 1.4 2002/10/08 22:14:11 tsi Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "trident.h"
+#include "trident_regs.h"
+#include "dgaproc.h"
+
+
+static Bool TRIDENT_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
+ int *, int *, int *);
+static Bool TRIDENT_SetMode(ScrnInfoPtr, DGAModePtr);
+static void TRIDENT_Sync(ScrnInfoPtr);
+static int TRIDENT_GetViewport(ScrnInfoPtr);
+static void TRIDENT_SetViewport(ScrnInfoPtr, int, int, int);
+static void TRIDENT_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
+static void TRIDENT_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
+#if 0
+static void TRIDENT_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
+ unsigned long);
+#endif
+
+static
+DGAFunctionRec TRIDENTDGAFuncs = {
+ TRIDENT_OpenFramebuffer,
+ NULL,
+ TRIDENT_SetMode,
+ TRIDENT_SetViewport,
+ TRIDENT_GetViewport,
+ TRIDENT_Sync,
+ TRIDENT_FillRect,
+ TRIDENT_BlitRect,
+#if 0
+ TRIDENT_BlitTransRect
+#else
+ NULL
+#endif
+};
+
+Bool
+TRIDENTDGAInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ DGAModePtr modes = NULL, newmodes = NULL, currentMode;
+ DisplayModePtr pMode, firstMode;
+ int Bpp = pScrn->bitsPerPixel >> 3;
+ int num = 0;
+ Bool oneMore;
+
+ pMode = firstMode = pScrn->modes;
+
+ while(pMode) {
+
+ if(0 /*pScrn->displayWidth != pMode->HDisplay*/) {
+ newmodes = xrealloc(modes, (num + 2) * sizeof(DGAModeRec));
+ oneMore = TRUE;
+ } else {
+ newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec));
+ oneMore = FALSE;
+ }
+
+ if(!newmodes) {
+ xfree(modes);
+ return FALSE;
+ }
+ modes = newmodes;
+
+SECOND_PASS:
+
+ currentMode = modes + num;
+ num++;
+
+ currentMode->mode = pMode;
+ currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;
+ if(!pTrident->NoAccel)
+ currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
+ if(pMode->Flags & V_DBLSCAN)
+ currentMode->flags |= DGA_DOUBLESCAN;
+ if(pMode->Flags & V_INTERLACE)
+ currentMode->flags |= DGA_INTERLACED;
+ currentMode->byteOrder = pScrn->imageByteOrder;
+ currentMode->depth = pScrn->depth;
+ currentMode->bitsPerPixel = pScrn->bitsPerPixel;
+ currentMode->red_mask = pScrn->mask.red;
+ currentMode->green_mask = pScrn->mask.green;
+ currentMode->blue_mask = pScrn->mask.blue;
+ currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor;
+ currentMode->viewportWidth = pMode->HDisplay;
+ currentMode->viewportHeight = pMode->VDisplay;
+ currentMode->xViewportStep = 1;
+ currentMode->yViewportStep = 1;
+ currentMode->viewportFlags = DGA_FLIP_RETRACE;
+ currentMode->offset = 0;
+ currentMode->address = pTrident->FbBase;
+
+ if(oneMore) { /* first one is narrow width */
+ currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L;
+ currentMode->imageWidth = pMode->HDisplay;
+ currentMode->imageHeight = pMode->VDisplay;
+ currentMode->pixmapWidth = currentMode->imageWidth;
+ currentMode->pixmapHeight = currentMode->imageHeight;
+ currentMode->maxViewportX = currentMode->imageWidth -
+ currentMode->viewportWidth;
+ /* this might need to get clamped to some maximum */
+ currentMode->maxViewportY = currentMode->imageHeight -
+ currentMode->viewportHeight;
+ oneMore = FALSE;
+ goto SECOND_PASS;
+ } else {
+ currentMode->bytesPerScanline =
+ ((pScrn->displayWidth * Bpp) + 3) & ~3L;
+ currentMode->imageWidth = pScrn->displayWidth;
+ currentMode->imageHeight = pMode->VDisplay;
+ currentMode->pixmapWidth = currentMode->imageWidth;
+ currentMode->pixmapHeight = currentMode->imageHeight;
+ currentMode->maxViewportX = currentMode->imageWidth -
+ currentMode->viewportWidth;
+ /* this might need to get clamped to some maximum */
+ currentMode->maxViewportY = currentMode->imageHeight -
+ currentMode->viewportHeight;
+ }
+
+ pMode = pMode->next;
+ if(pMode == firstMode)
+ break;
+ }
+
+ pTrident->numDGAModes = num;
+ pTrident->DGAModes = modes;
+
+ return DGAInit(pScreen, &TRIDENTDGAFuncs, modes, num);
+}
+
+
+static Bool
+TRIDENT_SetMode(
+ ScrnInfoPtr pScrn,
+ DGAModePtr pMode
+){
+ static int OldDisplayWidth[MAXSCREENS];
+ int index = pScrn->pScreen->myNum;
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if(!pMode) { /* restore the original mode */
+ /* put the ScreenParameters back */
+
+ pScrn->displayWidth = OldDisplayWidth[index];
+
+ TRIDENTSwitchMode(index, pScrn->currentMode, 0);
+ pTrident->DGAactive = FALSE;
+ } else {
+ if(!pTrident->DGAactive) { /* save the old parameters */
+ OldDisplayWidth[index] = pScrn->displayWidth;
+
+ pTrident->DGAactive = TRUE;
+ }
+
+ pScrn->displayWidth = pMode->bytesPerScanline /
+ (pMode->bitsPerPixel >> 3);
+
+ TRIDENTSwitchMode(index, pMode->mode, 0);
+ }
+
+ return TRUE;
+}
+
+
+
+static int
+TRIDENT_GetViewport(
+ ScrnInfoPtr pScrn
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ return pTrident->DGAViewportStatus;
+}
+
+static void
+TRIDENT_SetViewport(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int flags
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ TRIDENTAdjustFrame(pScrn->pScreen->myNum, x, y, flags);
+ pTrident->DGAViewportStatus = 0; /* TRIDENTAdjustFrame loops until finished */
+}
+
+static void
+TRIDENT_FillRect (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned long color
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if(pTrident->AccelInfoRec) {
+ (*pTrident->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
+ (*pTrident->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ SET_SYNC_FLAG(pTrident->AccelInfoRec);
+ }
+}
+
+static void
+TRIDENT_Sync(
+ ScrnInfoPtr pScrn
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if(pTrident->AccelInfoRec) {
+ (*pTrident->AccelInfoRec->Sync)(pScrn);
+ }
+}
+
+static void
+TRIDENT_BlitRect(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if(pTrident->AccelInfoRec) {
+ int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
+ int ydir = (srcy < dsty) ? -1 : 1;
+
+ (*pTrident->AccelInfoRec->SetupForScreenToScreenCopy)(
+ pScrn, xdir, ydir, GXcopy, ~0, -1);
+ (*pTrident->AccelInfoRec->SubsequentScreenToScreenCopy)(
+ pScrn, srcx, srcy, dstx, dsty, w, h);
+ SET_SYNC_FLAG(pTrident->AccelInfoRec);
+ }
+}
+
+#if 0
+static void
+TRIDENT_BlitTransRect(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty,
+ unsigned long color
+){
+ /* this one should be separate since the XAA function would
+ prohibit usage of ~0 as the key */
+}
+#endif
+
+static Bool
+TRIDENT_OpenFramebuffer(
+ ScrnInfoPtr pScrn,
+ char **name,
+ unsigned char **mem,
+ int *size,
+ int *offset,
+ int *flags
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ *name = NULL; /* no special device */
+ *mem = (unsigned char*)pTrident->FbAddress;
+ *size = pTrident->FbMapSize;
+ *offset = 0;
+ *flags = DGA_NEED_ROOT;
+
+ return TRUE;
+}
diff --git a/src/trident_driver.c b/src/trident_driver.c
new file mode 100644
index 0000000..a75d4fe
--- /dev/null
+++ b/src/trident_driver.c
@@ -0,0 +1,3632 @@
+/*
+ * Copyright 1992-2000 by Alan Hourihane, Wigan, England.
+ *
+ * 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, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Alan Hourihane, alanh@fairlite.demon.co.uk
+ * Re-written for XFree86 v4.0
+ *
+ * Previous driver (pre-XFree86 v4.0) by
+ * Alan Hourihane, alanh@fairlite.demon.co.uk
+ * David Wexelblat (major contributor)
+ * Massimiliano Ghilardi, max@Linuz.sns.it, some fixes to the
+ * clockchip programming code.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_driver.c,v 1.176 2003/02/11 03:41:38 dawes Exp $ */
+
+#include "xf1bpp.h"
+#include "xf4bpp.h"
+#include "fb.h"
+
+#include "mibank.h"
+#include "micmap.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86_ansic.h"
+#include "xf86Version.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86cmap.h"
+#include "vgaHW.h"
+#include "xf86RAC.h"
+#include "vbe.h"
+#include "dixstruct.h"
+#include "compiler.h"
+
+#include "mipointer.h"
+
+#include "mibstore.h"
+#include "shadow.h"
+#include "trident.h"
+#include "trident_regs.h"
+
+#define _XF86DGA_SERVER_
+#include "extensions/xf86dgastr.h"
+
+#include "globals.h"
+#define DPMS_SERVER
+#include "extensions/dpms.h"
+
+#ifdef XvExtension
+#include "xf86xv.h"
+#endif
+
+static const OptionInfoRec * TRIDENTAvailableOptions(int chipid, int busid);
+static void TRIDENTIdentify(int flags);
+static Bool TRIDENTProbe(DriverPtr drv, int flags);
+static Bool TRIDENTPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool TRIDENTScreenInit(int Index, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool TRIDENTEnterVT(int scrnIndex, int flags);
+static void TRIDENTLeaveVT(int scrnIndex, int flags);
+static Bool TRIDENTCloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool TRIDENTSaveScreen(ScreenPtr pScreen, int mode);
+
+/* Optional functions */
+static void TRIDENTFreeScreen(int scrnIndex, int flags);
+static int TRIDENTValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
+ int flags);
+
+/* Internally used functions */
+static Bool TRIDENTMapMem(ScrnInfoPtr pScrn);
+static Bool TRIDENTUnmapMem(ScrnInfoPtr pScrn);
+static void TRIDENTSave(ScrnInfoPtr pScrn);
+static void TRIDENTRestore(ScrnInfoPtr pScrn);
+static Bool TRIDENTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static void TRIDENTBlockHandler(int, pointer, pointer, pointer);
+
+static void TRIDENTEnableMMIO(ScrnInfoPtr pScrn);
+static void TRIDENTDisableMMIO(ScrnInfoPtr pScrn);
+static void PC98TRIDENTInit(ScrnInfoPtr pScrn);
+static void PC98TRIDENTEnable(ScrnInfoPtr pScrn);
+static void PC98TRIDENTDisable(ScrnInfoPtr pScrn);
+static void PC98TRIDENT96xxInit(ScrnInfoPtr pScrn);
+static void PC98TRIDENT96xxEnable(ScrnInfoPtr pScrn);
+static void PC98TRIDENT96xxDisable(ScrnInfoPtr pScrn);
+static void PC98TRIDENT9385Init(ScrnInfoPtr pScrn);
+static void PC98TRIDENT9385Enable(ScrnInfoPtr pScrn);
+static void PC98TRIDENT9385Disable(ScrnInfoPtr pScrn);
+
+/*
+ * This is intentionally screen-independent. It indicates the binding
+ * choice made in the first PreInit.
+ */
+static int pix24bpp = 0;
+
+#define VERSION 4000
+#define TRIDENT_NAME "TRIDENT"
+#define TRIDENT_DRIVER_NAME "trident"
+#define TRIDENT_MAJOR_VERSION 1
+#define TRIDENT_MINOR_VERSION 0
+#define TRIDENT_PATCHLEVEL 0
+
+/*
+ * This contains the functions needed by the server after loading the driver
+ * module. It must be supplied, and gets passed back by the SetupProc
+ * function 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.
+ */
+
+DriverRec TRIDENT = {
+ VERSION,
+ TRIDENT_DRIVER_NAME,
+ TRIDENTIdentify,
+ TRIDENTProbe,
+ TRIDENTAvailableOptions,
+ NULL,
+ 0
+};
+
+static SymTabRec TRIDENTChipsets[] = {
+ { TVGA9000, "tvga9000" },
+ { TVGA9000i, "tvga9000i" },
+ { TVGA8900C, "tvga8900c" },
+ { TVGA8900D, "tvga8900d" },
+ { TVGA9200CXr, "tvga9200cxr" },
+ { TGUI9400CXi, "tgui9400cxi" },
+ { CYBER9320, "cyber9320" },
+ { CYBER9388, "cyber9388" },
+ { CYBER9397, "cyber9397" },
+ { CYBER9397DVD, "cyber9397dvd" },
+ { CYBER9520, "cyber9520" },
+ { CYBER9525DVD, "cyber9525dvd" },
+ { CYBERBLADEE4, "cyberblade/e4" },
+ { TGUI9420DGi, "tgui9420dgi" },
+ { TGUI9440AGi, "tgui9440agi" },
+ { TGUI9660, "tgui9660" },
+ { TGUI9680, "tgui9680" },
+ { PROVIDIA9682, "providia9682" },
+ { PROVIDIA9685, "providia9685" },
+ { CYBER9382, "cyber9382" },
+ { CYBER9385, "cyber9385" },
+ { IMAGE975, "3dimage975" },
+ { IMAGE985, "3dimage985" },
+ { BLADE3D, "blade3d" },
+ { CYBERBLADEI7, "cyberbladei7" },
+ { CYBERBLADEI7D, "cyberbladei7d" },
+ { CYBERBLADEI1, "cyberbladei1" },
+ { CYBERBLADEI1D, "cyberbladei1d" },
+ { CYBERBLADEAI1, "cyberbladeAi1" },
+ { CYBERBLADEAI1D, "cyberbladeAi1d" },
+ { BLADEXP, "bladeXP" },
+ { CYBERBLADEXPAI1, "cyberbladeXPAi1" },
+ { -1, NULL }
+};
+
+static IsaChipsets TRIDENTISAchipsets[] = {
+ { TVGA9000, RES_EXCLUSIVE_VGA },
+ { TVGA9000i, RES_EXCLUSIVE_VGA },
+ { TVGA8900C, RES_EXCLUSIVE_VGA },
+ { TVGA8900D, RES_EXCLUSIVE_VGA },
+ { TVGA9200CXr, RES_EXCLUSIVE_VGA },
+ { TGUI9400CXi, RES_EXCLUSIVE_VGA },
+ { CYBER9320, RES_EXCLUSIVE_VGA },
+ { TGUI9440AGi, RES_EXCLUSIVE_VGA },
+ { -1, RES_UNDEFINED }
+};
+
+static PciChipsets TRIDENTPciChipsets[] = {
+ { CYBER9320, PCI_CHIP_9320, RES_SHARED_VGA },
+ { CYBER9388, PCI_CHIP_9388, RES_SHARED_VGA },
+ { CYBER9397, PCI_CHIP_9397, RES_SHARED_VGA },
+ { CYBER9397DVD, PCI_CHIP_939A, RES_SHARED_VGA },
+ { CYBER9520, PCI_CHIP_9520, RES_SHARED_VGA },
+ { CYBER9525DVD, PCI_CHIP_9525, RES_SHARED_VGA },
+ { CYBERBLADEE4, PCI_CHIP_9540, RES_SHARED_VGA },
+ { TGUI9420DGi, PCI_CHIP_9420, RES_SHARED_VGA },
+ { TGUI9440AGi, PCI_CHIP_9440, RES_SHARED_VGA },
+ { TGUI9660, PCI_CHIP_9660, RES_SHARED_VGA },
+ { TGUI9680, PCI_CHIP_9660, RES_SHARED_VGA },
+ { PROVIDIA9682, PCI_CHIP_9660, RES_SHARED_VGA },
+ { PROVIDIA9685, PCI_CHIP_9660, RES_SHARED_VGA },
+ { CYBER9382, PCI_CHIP_9660, RES_SHARED_VGA },
+ { CYBER9385, PCI_CHIP_9660, RES_SHARED_VGA },
+ { IMAGE975, PCI_CHIP_9750, RES_SHARED_VGA },
+ { IMAGE985, PCI_CHIP_9850, RES_SHARED_VGA },
+ { BLADE3D, PCI_CHIP_9880, RES_SHARED_VGA },
+ { CYBERBLADEI7, PCI_CHIP_8400, RES_SHARED_VGA },
+ { CYBERBLADEI7D, PCI_CHIP_8420, RES_SHARED_VGA },
+ { CYBERBLADEI1, PCI_CHIP_8500, RES_SHARED_VGA },
+ { CYBERBLADEI1D, PCI_CHIP_8520, RES_SHARED_VGA },
+ { CYBERBLADEAI1, PCI_CHIP_8600, RES_SHARED_VGA },
+ { CYBERBLADEAI1D, PCI_CHIP_8620, RES_SHARED_VGA },
+ { BLADEXP, PCI_CHIP_9910, RES_SHARED_VGA },
+ { CYBERBLADEXPAI1, PCI_CHIP_8820, RES_SHARED_VGA },
+ { -1, -1, RES_UNDEFINED }
+};
+
+typedef enum {
+ OPTION_SW_CURSOR,
+ OPTION_PCI_RETRY,
+ OPTION_RGB_BITS,
+ OPTION_NOACCEL,
+ OPTION_SETMCLK,
+ OPTION_MUX_THRESHOLD,
+ OPTION_SHADOW_FB,
+ OPTION_ROTATE,
+ OPTION_MMIO_ONLY,
+ OPTION_VIDEO_KEY,
+ OPTION_NOMMIO,
+ OPTION_NOPCIBURST,
+ OPTION_CYBER_SHADOW,
+ OPTION_CYBER_STRETCH,
+ OPTION_XV_HSYNC,
+ OPTION_XV_VSYNC,
+ OPTION_XV_BSKEW,
+ OPTION_XV_RSKEW,
+ OPTION_FP_DELAY,
+ OPTION_1400_DISPLAY,
+ OPTION_DISPLAY,
+ OPTION_GB
+} TRIDENTOpts;
+
+static const OptionInfoRec TRIDENTOptions[] = {
+ { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SETMCLK, "SetMClk", OPTV_FREQ, {0}, FALSE },
+ { OPTION_MUX_THRESHOLD, "MUXThreshold", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE },
+ { OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_NOMMIO, "NoMMIO", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOPCIBURST, "NoPciBurst", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_MMIO_ONLY, "MMIOonly", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_CYBER_SHADOW, "CyberShadow", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_CYBER_STRETCH, "CyberStretch", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_XV_HSYNC, "XvHsync", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_XV_VSYNC, "XvVsync", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_XV_BSKEW, "XvBskew", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_XV_RSKEW, "XvRskew", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_FP_DELAY, "FpDelay", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_1400_DISPLAY, "Display1400", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_DISPLAY, "Display", OPTV_ANYSTR, {0}, FALSE },
+ { OPTION_GB, "GammaBrightness", OPTV_ANYSTR, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+/* Clock Limits */
+static int ClockLimit[] = {
+ 80000,
+ 80000,
+ 80000,
+ 80000,
+ 80000,
+ 80000,
+ 80000,
+ 80000,
+ 80000,
+ 80000,
+ 80000,
+ 80000,
+ 80000,
+ 80000,
+ 90000,
+ 90000,
+ 135000,
+ 135000,
+ 170000,
+ 170000,
+ 170000,
+ 170000,
+ 170000,
+ 170000,
+ 170000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+};
+
+static int ClockLimit16bpp[] = {
+ 40000,
+ 40000,
+ 40000,
+ 40000,
+ 40000,
+ 40000,
+ 40000,
+ 40000,
+ 40000,
+ 40000,
+ 40000,
+ 40000,
+ 40000,
+ 40000,
+ 45000,
+ 45000,
+ 90000,
+ 90000,
+ 135000,
+ 135000,
+ 170000,
+ 170000,
+ 170000,
+ 170000,
+ 170000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+};
+
+static int ClockLimit24bpp[] = {
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 40000,
+ 40000,
+ 70000,
+ 70000,
+ 70000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+};
+
+static int ClockLimit32bpp[] = {
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 40000,
+ 40000,
+ 70000,
+ 70000,
+ 70000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+};
+
+/*
+ * These are fixed modelines for all physical display dimensions the
+ * chipsets supports on FPs. Most of them are not tested yet.
+ */
+#if 0
+tridentLCD LCD[] = { /* 0 3 4 5 6 7 10 11 16 */
+ { 0,"640x480",25200,0x5f,0x82,0x54,0x80,0xb,0x3e,0xea,0x8c,0xb,0x08},
+ { 1,"800x600",40000,0x7f,0x99,0x69,0x99,0x72,0xf0,0x59,0x2d,0x5e,0x08},
+ { 2,"1024x768",65000,0xa3,/*0x6*/ 0x98,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08},
+ { 3,"1024x768",65000,0xa3,/*0x6*/ 0x98,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08}, /*0x96*/
+ { 4,"1280x1024",108000,0xa3,0x6,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08},
+ { 5,"1024x600",50500 ,0xa3,0x6,0x8f,0xa0,0xb,0x3e,0xea,0x8c,0xb,0x08},
+ { 0xff,"", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+};
+#else
+#if 0
+tridentLCD LCD[] = {
+ { 1,640,480,25200,0x5f,0x82,0x54,0x80,0xb,0x3e,0xea,0x8c,0xb,0x08},
+ { 3,800,600,40000,0x7f,0x82,0x6b,0x1b,0x72,0xf8,0x58,0x8c,0x72,0x08},
+ { 2,1024,768,65000,0xa3,/*0x6*/0x98,0x8f,0xa0,0x24,0xf5,0x0f,0x24,0x0a,0x08},
+ { 0,1280,1024,108000,0xce,0x81,0xa6,0x9a,0x27,0x50,0x00,0x03,0x26,0xa8},
+ { 0xff,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+};
+#else
+tridentLCD LCD[] = {
+ { 1,640,480,25200,0x5f,0x80,0x52,0x1e,0xb,0x3e,0xea,0x0c,0xb,0x08},
+ { 3,800,600,40000,0x7f,0x00,0x69,0x7f,0x72,0xf0,0x59,0x0d,0x00,0x08},
+ { 2,1024,768,65000,0xa3,0x00,0x84,0x94,0x24,0xf5,0x03,0x09,0x24,0x08},
+ { 0,1280,1024,108000,0xce,0x91,0xa6,0x14,0x28,0x5a,0x01,0x04,0x28,0xa8},
+ { 4,1400,1050,122000,0xe6,0xcd,0xba,0x1d,0x38,0x00,0x1c,0x28,0x28,0xf8},
+ { 0xff,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+};
+#endif
+#endif
+
+static const char *xaaSymbols[] = {
+ "XAACopyROP",
+ "XAACreateInfoRec",
+ "XAADestroyInfoRec",
+ "XAAFillSolidRects",
+ "XAAInit",
+ "XAAPatternROP",
+ "XAAScreenIndex",
+ NULL
+};
+
+static const char *vgahwSymbols[] = {
+ "vgaHWBlankScreen",
+ "vgaHWFreeHWRec",
+ "vgaHWGetHWRec",
+ "vgaHWGetIOBase",
+ "vgaHWGetIndex",
+ "vgaHWInit",
+ "vgaHWLock",
+ "vgaHWMapMem",
+ "vgaHWProtect",
+ "vgaHWRestore",
+ "vgaHWSave",
+ "vgaHWSaveScreen",
+ "vgaHWSetMmioFuncs",
+ "vgaHWUnlock",
+ NULL
+};
+
+static const char *miscfbSymbols[] = {
+ "xf1bppScreenInit",
+ "xf4bppScreenInit",
+ NULL
+};
+
+static const char *fbSymbols[] = {
+ "fbPictureInit",
+ "fbScreenInit",
+ NULL
+};
+
+static const char *ramdacSymbols[] = {
+ "xf86CreateCursorInfoRec",
+ "xf86DestroyCursorInfoRec",
+ "xf86InitCursor",
+ NULL
+};
+
+static const char *ddcSymbols[] = {
+ "xf86PrintEDID",
+ "xf86SetDDCproperties",
+ NULL
+};
+
+static const char *i2cSymbols[] = {
+ "xf86CreateI2CBusRec",
+ "xf86I2CBusInit",
+ NULL
+};
+
+static const char *int10Symbols[] = {
+ "xf86ExecX86int10",
+ "xf86FreeInt10",
+ "xf86InitInt10",
+ NULL
+};
+
+static const char *shadowSymbols[] = {
+ "shadowInit",
+ NULL
+};
+
+static const char *vbeSymbols[] = {
+ "VBEInit",
+ "vbeDoEDID",
+ "vbeFree",
+ NULL
+};
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(tridentSetup);
+
+static XF86ModuleVersionInfo tridentVersRec =
+{
+ "trident",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ TRIDENT_MAJOR_VERSION, TRIDENT_MINOR_VERSION, TRIDENT_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV, /* This is a video driver */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+XF86ModuleData tridentModuleData = { &tridentVersRec, tridentSetup, NULL };
+
+pointer
+tridentSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&TRIDENT, module, 0);
+ LoaderRefSymLists(vgahwSymbols, fbSymbols, i2cSymbols, vbeSymbols,
+ miscfbSymbols, ramdacSymbols, int10Symbols,
+ xaaSymbols, shadowSymbols, NULL);
+ return (pointer)TRUE;
+ }
+
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+}
+
+#endif /* XFree86LOADER */
+
+static Bool
+TRIDENTGetRec(ScrnInfoPtr pScrn)
+{
+ /*
+ * Allocate an TRIDENTRec, and hook it into pScrn->driverPrivate.
+ * pScrn->driverPrivate is initialised to NULL, so we can check if
+ * the allocation has already been done.
+ */
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(TRIDENTRec), 1);
+ /* Initialise it */
+
+ return TRUE;
+}
+
+static void
+TRIDENTFreeRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+static void
+TRIDENTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ CARD8 DPMSCont, PMCont, temp;
+
+ if (!pScrn->vtSema)
+ return;
+
+ OUTB(0x3C4, 0x0E);
+ temp = INB(0x3C5);
+ OUTB(0x3C5, 0xC2);
+ OUTB(0x83C8, 0x04); /* Read DPMS Control */
+ PMCont = INB(0x83C6) & 0xFC;
+ OUTB(0x3CE, 0x23);
+ DPMSCont = INB(0x3CF) & 0xFC;
+ switch (PowerManagementMode)
+ {
+ case DPMSModeOn:
+ /* Screen: On, HSync: On, VSync: On */
+ PMCont |= 0x03;
+ DPMSCont |= 0x00;
+ break;
+ case DPMSModeStandby:
+ /* Screen: Off, HSync: Off, VSync: On */
+ PMCont |= 0x02;
+ DPMSCont |= 0x01;
+ break;
+ case DPMSModeSuspend:
+ /* Screen: Off, HSync: On, VSync: Off */
+ PMCont |= 0x02;
+ DPMSCont |= 0x02;
+ break;
+ case DPMSModeOff:
+ /* Screen: Off, HSync: Off, VSync: Off */
+ PMCont |= 0x00;
+ DPMSCont |= 0x03;
+ break;
+ }
+ OUTB(0x3CF, DPMSCont);
+ OUTB(0x83C8, 0x04);
+ OUTB(0x83C6, PMCont);
+ OUTW(0x3C4, (temp<<8) | 0x0E);
+}
+
+static void
+TRIDENTBlockHandler (
+ int i,
+ pointer blockData,
+ pointer pTimeout,
+ pointer pReadmask
+){
+ ScreenPtr pScreen = screenInfo.screens[i];
+ ScrnInfoPtr pScrn = xf86Screens[i];
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ pScreen->BlockHandler = pTrident->BlockHandler;
+ (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
+ pScreen->BlockHandler = TRIDENTBlockHandler;
+
+ if(pTrident->VideoTimerCallback) {
+ UpdateCurrentTime();
+ (*pTrident->VideoTimerCallback)(pScrn, currentTime.milliseconds);
+ }
+}
+
+static const OptionInfoRec *
+TRIDENTAvailableOptions(int chipid, int busid)
+{
+ return TRIDENTOptions;
+}
+
+/* Mandatory */
+static void
+TRIDENTIdentify(int flags)
+{
+ xf86PrintChipsets(TRIDENT_NAME, "driver for Trident chipsets", TRIDENTChipsets);
+}
+
+static void
+TRIDENTFix1bpp(ScrnInfoPtr pScrn) {
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+/* In 1 bpp we have color 0 at LUT 0 and color 1 at LUT 0x3f.
+ This makes white and black look right (otherwise they were both
+ black. I'm sure there's a better way to do that, just lazy to
+ search the docs. */
+
+ (*hwp->writeDacWriteAddr)(hwp, 0x00);
+ (*hwp->writeDacData)(hwp, 0x00);
+ (*hwp->writeDacData)(hwp, 0x00);
+ (*hwp->writeDacData)(hwp, 0x00);
+
+ (*hwp->writeDacWriteAddr)(hwp, 0x3F);
+ (*hwp->writeDacData)(hwp, 0x3F);
+ (*hwp->writeDacData)(hwp, 0x3F);
+ (*hwp->writeDacData)(hwp, 0x3F);
+}
+
+Bool
+TRIDENTClockSelect(ScrnInfoPtr pScrn, int no)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ unsigned char temp;
+
+ /*
+ * CS0 and CS1 are in MiscOutReg
+ *
+ * For 8900B, 8900C, 8900CL and 9000, CS2 is bit 0 of
+ * New Mode Control Register 2.
+ *
+ * For 8900CL, CS3 is bit 4 of Old Mode Control Register 1.
+ *
+ * For 9000, CS3 is bit 6 of New Mode Control Register 2.
+ *
+ * For TGUI, we don't use the ClockSelect function at all.
+ */
+ switch(no) {
+ case CLK_REG_SAVE:
+ pTrident->SaveClock1 = INB(0x3CC);
+ if (pTrident->Chipset != TVGA8800CS) {
+ if ( (pScrn->numClocks == 16) &&
+ (pTrident->Chipset != TVGA9000) &&
+ (pTrident->Chipset != TVGA9000i) )
+ {
+ OUTW(0x3C4, 0x000B); /* Switch to Old Mode */
+ OUTB(0x3C4, 0x0E); pTrident->SaveClock3 = INB(0x3C5);
+ }
+ OUTB(0x3C4, 0x0B);
+ INB(0x3C5); /* Now to New Mode */
+ OUTB(0x3C4, 0x0D); pTrident->SaveClock2 = INB(0x3C5);
+ }
+ break;
+ case CLK_REG_RESTORE:
+ OUTB(0x3C2, pTrident->SaveClock1);
+ if (pTrident->Chipset != TVGA8800CS) {
+ if ( (pScrn->numClocks == 16) &&
+ (pTrident->Chipset != TVGA9000) &&
+ (pTrident->Chipset != TVGA9000i) )
+ {
+ OUTW(0x3C4, 0x000B); /* Switch to Old Mode */
+ OUTW(0x3C4, (pTrident->SaveClock3 << 8) | 0x0E);
+ }
+ OUTB(0x3C4, 0x0B);
+ INB(0x3C5); /* Now to New Mode */
+ OUTW(0x3C4, (pTrident->SaveClock2 << 8) | 0x0D);
+ }
+ break;
+ default:
+ /*
+ * Do CS0 and CS1
+ */
+ temp = INB(0x3CC);
+ OUTB(0x3C2, (temp & 0xF3) | ((no << 2) & 0x0C));
+ if (pTrident->Chipset != TVGA8800CS) {
+ if ( (pScrn->numClocks == 16) &&
+ (pTrident->Chipset != TVGA9000) &&
+ (pTrident->Chipset != TVGA9000i) )
+ {
+ /*
+ * Go to Old Mode for CS3.
+ */
+ OUTW(0x3C4, 0x000B); /* Switch to Old Mode */
+ OUTB(0x3C4, 0x0E);
+ temp = INB(0x3C5) & 0xEF;
+ temp |= (no & 0x08) << 1;
+ OUTB(0x3C5, temp);
+ }
+ /*
+ * Go to New Mode for CS2 and TVGA9000 CS3.
+ */
+ OUTB(0x3C4, 0x0B);
+ INB(0x3C5); /* Now to New Mode */
+ OUTB(0x3C4, 0x0D);
+ /*
+ * Bits 1 & 2 are dividers - set to 0 to get no
+ * clock division.
+ */
+ temp = INB(0x3C5) & 0xF8;
+ temp |= (no & 0x04) >> 2;
+ if ( (pTrident->Chipset == TVGA9000) ||
+ (pTrident->Chipset == TVGA9000i) )
+ {
+ temp &= ~0x40;
+ temp |= (no & 0x08) << 3;
+ }
+ OUTB(0x3C5, temp);
+ }
+ }
+ return(TRUE);
+}
+
+static int
+TridentFindIsaDevice(GDevPtr dev)
+{
+ int found = -1;
+ unsigned char temp, origVal, newVal;
+
+ /*
+ * Check first that we have a Trident card.
+ */
+ outb(0x3C4, 0x0B);
+ temp = inb(0x3C5); /* Save old value */
+ outb(0x3C4, 0x0B); /* Switch to Old Mode */
+ outb(0x3C5, 0x00);
+ inb(0x3C5); /* Now to New Mode */
+ outb(0x3C4, 0x0E);
+ origVal = inb(0x3C5);
+ outb(0x3C5, 0x00);
+ newVal = inb(0x3C5) & 0x0F;
+ outb(0x3C5, (origVal ^ 0x02));
+
+ /*
+ * Is it a Trident card ??
+ */
+ if (newVal != 2) {
+ /*
+ * Nope, so quit
+ */
+ outb(0x3C4, 0x0B); /* Restore value of 0x0B */
+ outb(0x3C5, temp);
+ outb(0x3C4, 0x0E);
+ outb(0x3C5, origVal);
+ return found;
+ }
+
+ outb(0x3C4, 0x0B);
+ temp = inb(0x3C5);
+ switch (temp) {
+ case 0x01:
+ found = TVGA8800BR;
+ break;
+ case 0x02:
+ found = TVGA8800CS;
+ break;
+ case 0x03:
+ found = TVGA8900B;
+ break;
+ case 0x04:
+ case 0x13:
+ found = TVGA8900C;
+ break;
+ case 0x23:
+ found = TVGA9000;
+ break;
+ case 0x33:
+ found = TVGA8900D;
+ break;
+ case 0x43:
+ found = TVGA9000i;
+ break;
+ case 0x53:
+ found = TVGA9200CXr;
+ break;
+ case 0x63:
+ found = TVGA9100B;
+ break;
+ case 0x73:
+ case 0xC3:
+ found = TGUI9420DGi;
+ break;
+ case 0x83:
+ found = TVGA8200LX;
+ break;
+ case 0x93:
+ found = TGUI9400CXi;
+ break;
+ case 0xA3:
+ found = CYBER9320;
+ break;
+ case 0xD3:
+ found = TGUI9660;
+ break;
+ case 0xE3:
+ found = TGUI9440AGi;
+ break;
+ case 0xF3:
+ found = TGUI9430DGi;
+ break;
+ }
+ return found;
+}
+
+
+/* Mandatory */
+static Bool
+TRIDENTProbe(DriverPtr drv, int flags)
+{
+ int i;
+ GDevPtr *devSections;
+ int *usedChips = NULL;
+ int numDevSections;
+ int numUsed;
+ Bool foundScreen = FALSE;
+
+ if ((numDevSections = xf86MatchDevice(TRIDENT_DRIVER_NAME,
+ &devSections)) <= 0) {
+ /*
+ * There's no matching device section in the config file, so quit
+ * now.
+ */
+ return FALSE;
+ }
+
+ /*
+ * While we're VGA-dependent, can really only have one such instance, but
+ * we'll ignore that.
+ */
+
+ /*
+ * We need to probe the hardware first. We then need to see how this
+ * fits in with what is given in the config file, and allow the config
+ * file info to override any contradictions.
+ */
+
+ /*
+ * All of the cards this driver supports are PCI, so the "probing" just
+ * amounts to checking the PCI data that the server has already collected.
+ */
+ if (xf86GetPciVideoInfo()) {
+ numUsed = xf86MatchPciInstances(TRIDENT_NAME, PCI_VENDOR_TRIDENT,
+ TRIDENTChipsets, TRIDENTPciChipsets, devSections,
+ numDevSections, drv, &usedChips);
+
+ if (numUsed > 0) {
+ if (flags & PROBE_DETECT)
+ foundScreen = TRUE;
+ else for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn = NULL;
+
+ if ((pScrn = xf86ConfigPciEntity(pScrn, 0,usedChips[i],
+ TRIDENTPciChipsets, NULL,
+ NULL, NULL, NULL, NULL))) {
+ /* Fill in what we can of the ScrnInfoRec */
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = TRIDENT_DRIVER_NAME;
+ pScrn->name = TRIDENT_NAME;
+ pScrn->Probe = TRIDENTProbe;
+ pScrn->PreInit = TRIDENTPreInit;
+ pScrn->ScreenInit = TRIDENTScreenInit;
+ pScrn->SwitchMode = TRIDENTSwitchMode;
+ pScrn->AdjustFrame = TRIDENTAdjustFrame;
+ pScrn->EnterVT = TRIDENTEnterVT;
+ pScrn->LeaveVT = TRIDENTLeaveVT;
+ pScrn->FreeScreen = TRIDENTFreeScreen;
+ pScrn->ValidMode = TRIDENTValidMode;
+ foundScreen = TRUE;
+ }
+ }
+ xfree(usedChips);
+ }
+ }
+
+ /* Isa Bus */
+ numUsed = xf86MatchIsaInstances(TRIDENT_NAME,TRIDENTChipsets,
+ TRIDENTISAchipsets,
+ drv,TridentFindIsaDevice,devSections,
+ numDevSections,&usedChips);
+ if (numUsed > 0) {
+ if (flags & PROBE_DETECT)
+ foundScreen = TRUE;
+ else for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn = NULL;
+ if ((pScrn = xf86ConfigIsaEntity(pScrn,0,usedChips[i],
+ TRIDENTISAchipsets,NULL,
+ NULL,NULL,NULL,NULL))) {
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = TRIDENT_DRIVER_NAME;
+ pScrn->name = TRIDENT_NAME;
+ pScrn->Probe = TRIDENTProbe;
+ pScrn->PreInit = TRIDENTPreInit;
+ pScrn->ScreenInit = TRIDENTScreenInit;
+ pScrn->SwitchMode = TRIDENTSwitchMode;
+ pScrn->AdjustFrame = TRIDENTAdjustFrame;
+ pScrn->EnterVT = TRIDENTEnterVT;
+ pScrn->LeaveVT = TRIDENTLeaveVT;
+ pScrn->FreeScreen = TRIDENTFreeScreen;
+ pScrn->ValidMode = TRIDENTValidMode;
+ foundScreen = TRUE;
+ }
+ }
+ xfree(usedChips);
+ }
+
+ xfree(devSections);
+ return foundScreen;
+}
+
+/*
+ * GetAccelPitchValues -
+ *
+ * This function returns a list of display width (pitch) values that can
+ * be used in accelerated mode.
+ */
+static int *
+GetAccelPitchValues(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int *linePitches = NULL;
+ int lines[4] = { 512, 1024, 2048, 4096 }; /* 9440AGi */
+ int i, n = 0;
+
+ if (pTrident->Chipset >= BLADEXP) {
+ lines[0] = 1024;
+ lines[1] = 2048;
+ lines[2] = 4096;
+ lines[3] = 8192;
+ }
+
+ for (i = 0; i < 4; i++) {
+ n++;
+ linePitches = xnfrealloc(linePitches, n * sizeof(int));
+ linePitches[n - 1] = lines[i];
+ }
+
+ /* Mark the end of the list */
+ if (n > 0) {
+ linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int));
+ linePitches[n] = 0;
+ }
+ return linePitches;
+}
+
+static void
+TRIDENTProbeDDC(ScrnInfoPtr pScrn, int index)
+{
+ vbeInfoPtr pVbe;
+ if (xf86LoadSubModule(pScrn, "vbe")) {
+ pVbe = VBEInit(NULL,index);
+ ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
+ vbeFree(pVbe);
+ }
+}
+
+/* Mandatory */
+static Bool
+TRIDENTPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ TRIDENTPtr pTrident;
+ vgaHWPtr hwp;
+ MessageType from;
+ CARD8 videoram, videorammask;
+ char *ramtype = NULL, *chipset = NULL;
+ Bool Support24bpp;
+ int vgaIOBase;
+ float mclk;
+ double real;
+ int i, NoClocks = 16;
+ CARD8 revision;
+ ClockRangePtr clockRanges;
+ char *mod = NULL;
+ const char *Sym = "";
+ Bool ddcLoaded = FALSE;
+ char *s;
+
+ /* Allocate the TRIDENTRec driverPrivate */
+ if (!TRIDENTGetRec(pScrn)) {
+ return FALSE;
+ }
+ pTrident = TRIDENTPTR(pScrn);
+ pTrident->pScrn = pScrn;
+
+ if (pScrn->numEntities > 1)
+ return FALSE;
+ /* This is the general case */
+ for (i = 0; i<pScrn->numEntities; i++) {
+ pTrident->pEnt = xf86GetEntityInfo(pScrn->entityList[i]);
+ if (pTrident->pEnt->resources) return FALSE;
+ pTrident->Chipset = pTrident->pEnt->chipset;
+ pScrn->chipset = (char *)xf86TokenToString(TRIDENTChipsets,
+ pTrident->pEnt->chipset);
+ /* This driver can handle ISA and PCI buses */
+ if (pTrident->pEnt->location.type == BUS_PCI) {
+ pTrident->PciInfo = xf86GetPciInfoForEntity(pTrident->pEnt->index);
+ pTrident->PciTag = pciTag(pTrident->PciInfo->bus,
+ pTrident->PciInfo->device,
+ pTrident->PciInfo->func);
+ pTrident->Linear = TRUE;
+ } else {
+ pTrident->Linear = FALSE;
+ }
+ }
+
+ if (flags & PROBE_DETECT) {
+ TRIDENTProbeDDC(pScrn, pTrident->pEnt->index);
+ return TRUE;
+ }
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /*
+ * The first thing we should figure out is the depth, bpp, etc.
+ * Our default depth is 8, so pass it to the helper function.
+ * Our preference for depth 24 is 24bpp, so tell it that too.
+ */
+ if (!xf86SetDepthBpp(pScrn, 8, 8, 8, Support24bppFb | Support32bppFb |
+ SupportConvert32to24 /*| PreferConvert32to24*/)) {
+ return FALSE;
+ } else {
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 1:
+ case 4:
+ case 8:
+ if (pScrn->bitsPerPixel != pScrn->depth) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d)/ fbbpp (%d) is not supported by this driver\n",
+ pScrn->depth, pScrn->bitsPerPixel);
+ return FALSE;
+ }
+ break;
+ case 15:
+ case 16:
+ if (pScrn->bitsPerPixel != 16) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d)/ fbbpp (%d) is not supported by this driver\n",
+ pScrn->depth, pScrn->bitsPerPixel);
+ return FALSE;
+ }
+ break;
+ case 24:
+ if ((pScrn->bitsPerPixel != 24) && (pScrn->bitsPerPixel != 32)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d)/ fbbpp (%d) is not supported by this driver\n",
+ pScrn->depth, pScrn->bitsPerPixel);
+ return FALSE;
+ }
+ /* OK */
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ xf86PrintDepthBpp(pScrn);
+
+ /* Get the depth24 pixmap format */
+ if (pScrn->depth == 24 && pix24bpp == 0)
+ pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+
+ /* The vgahw module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "vgahw"))
+ return FALSE;
+
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ /*
+ * Allocate a vgaHWRec
+ */
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+
+ hwp = VGAHWPTR(pScrn);
+ vgaHWGetIOBase(hwp);
+ vgaIOBase = hwp->IOBase;
+ pTrident->PIOBase = hwp->PIOOffset;
+
+ xf86SetOperatingState(resVga, pTrident->pEnt->index, ResUnusedOpr);
+
+ /* The ramdac module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "ramdac"))
+ return FALSE;
+
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+
+ /*
+ * This must happen after pScrn->display has been set because
+ * xf86SetWeight references it.
+ */
+ if (pScrn->depth > 8) {
+ /* The defaults are OK for us */
+ rgb zeros = {0, 0, 0};
+
+ if (!xf86SetWeight(pScrn, zeros, zeros)) {
+ return FALSE;
+ } else {
+ /* XXX check that weight returned is supported */
+ ;
+ }
+ }
+
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ } else {
+ /* We don't currently support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ /*
+ * The new cmap layer needs this to be initialised.
+ */
+
+ {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros)) {
+ return FALSE;
+ }
+ }
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /* Process the options */
+ if (!(pTrident->Options = xalloc(sizeof(TRIDENTOptions))))
+ return FALSE;
+ memcpy(pTrident->Options, TRIDENTOptions, sizeof(TRIDENTOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pTrident->Options);
+
+ /* Set the bits per RGB for 8bpp mode */
+ if (pScrn->depth <= 8) {
+ /* XXX This is here just to test options. */
+ /* Default to 8 */
+ pScrn->rgbBits = 6;
+#if 0
+ if (xf86GetOptValInteger(pTrident->Options, OPTION_RGB_BITS,
+ &pScrn->rgbBits)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n",
+ pScrn->rgbBits);
+ }
+#endif
+ }
+ from = X_DEFAULT;
+ pTrident->HWCursor = TRUE;
+ if (xf86ReturnOptValBool(pTrident->Options, OPTION_SW_CURSOR, FALSE)) {
+ from = X_CONFIG;
+ pTrident->HWCursor = FALSE;
+ }
+ if (xf86ReturnOptValBool(pTrident->Options, OPTION_NOACCEL, FALSE)) {
+ pTrident->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
+ }
+ if (xf86ReturnOptValBool(pTrident->Options, OPTION_PCI_RETRY, FALSE)) {
+ pTrident->UsePCIRetry = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n");
+ }
+ pTrident->UsePCIBurst = TRUE;
+ if (xf86ReturnOptValBool(pTrident->Options, OPTION_NOPCIBURST, FALSE)) {
+ pTrident->UsePCIBurst = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI Burst disbled\n");
+ }
+ if (xf86ReturnOptValBool(pTrident->Options, OPTION_1400_DISPLAY, FALSE)) {
+ pTrident->displaySize = 1400;
+ }
+ if(xf86GetOptValInteger(pTrident->Options, OPTION_VIDEO_KEY,
+ &(pTrident->videoKey))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n",
+ pTrident->videoKey);
+ } else {
+ pTrident->videoKey = (1 << pScrn->offset.red) |
+ (1 << pScrn->offset.green) |
+ (((pScrn->mask.blue >> pScrn->offset.blue) - 1)
+ << pScrn->offset.blue);
+ }
+ if (xf86ReturnOptValBool(pTrident->Options, OPTION_NOMMIO, FALSE)) {
+ pTrident->NoMMIO = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MMIO Disabled\n");
+ }
+ if (xf86ReturnOptValBool(pTrident->Options, OPTION_MMIO_ONLY, FALSE)) {
+ if (pTrident->NoMMIO)
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MMIO only cannot be set"
+ " with NoMMIO\n");
+ else {
+ pTrident->MMIOonly = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MMIO only enabled\n");
+ }
+ }
+
+ pTrident->dspOverride = 0;
+ if ((s = xf86GetOptValString(pTrident->Options, OPTION_DISPLAY))) {
+ if(!xf86NameCmp(s, "CRT")) {
+ pTrident->dspOverride = CRT_ACTIVE;
+ xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"LCD off CRT on\n");
+ } else if (!xf86NameCmp(s, "LCD")) {
+ pTrident->dspOverride = LCD_ACTIVE;
+ xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"LCD on CRT off\n");
+ } else if (!xf86NameCmp(s, "Dual")) {
+ pTrident->dspOverride = LCD_ACTIVE | CRT_ACTIVE;
+ xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"LCD on CRT on\n");
+ } else
+ xf86DrvMsg(pScrn->scrnIndex,X_ERROR,
+ "%s is an unknown display option\n",s);
+ }
+ if ((s = xf86GetOptValString(pTrident->Options, OPTION_GB))) {
+ int brightness = -1;
+ double gamma = -1.0;
+ Bool error = FALSE;
+ int i;
+
+ i = sscanf(s,"%lf %i",&gamma,&brightness);
+
+ if (i != 2 || brightness == -1 || gamma == -1.0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Invalid Gamma/Brightness argument: %s\n",s);
+ error = TRUE;
+ } else {
+ if (brightness < 0 || brightness > 128) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "brightness out of range [0,128]: %i\n",brightness);
+ error = TRUE;
+ }
+ if (gamma <= 0.0 || gamma > 10.0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "gamma out of range (0,10.0]: %f\n",gamma);
+ error = TRUE;
+ }
+ }
+
+ if (!error) {
+ pTrident->GammaBrightnessOn = TRUE;
+ pTrident->gamma = gamma;
+ pTrident->brightness = brightness;
+ xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"Gamma: %f Brightness: %i\n",
+ gamma,brightness);
+ }
+ }
+
+ /* The following is a temporary hack */
+ pTrident->FPDelay = 7; /* invalid value */
+ if (xf86GetOptValInteger(pTrident->Options, OPTION_FP_DELAY,
+ &pTrident->FPDelay)) {
+ if (pTrident->FPDelay < -2 || pTrident->FPDelay > 5) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "FPDelay %i out if range "
+ "(-2 < FPDelay < 5)\n",pTrident->FPDelay);
+ pTrident->FPDelay = 7;
+ } else
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "FP Delay set to %i\n",
+ pTrident->FPDelay);
+ }
+ if (xf86ReturnOptValBool(pTrident->Options, OPTION_CYBER_SHADOW, FALSE)) {
+ pTrident->CyberShadow = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Cyber Shadow enabled\n");
+ }
+ if (xf86ReturnOptValBool(pTrident->Options, OPTION_CYBER_STRETCH, FALSE)) {
+ pTrident->CyberStretch = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Cyber Stretch enabled\n");
+ }
+
+ pTrident->MUXThreshold = 90000; /* 90MHz */
+ if (xf86GetOptValInteger(pTrident->Options, OPTION_MUX_THRESHOLD,
+ &pTrident->MUXThreshold)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MUX Threshold set to %d\n",
+ pTrident->MUXThreshold);
+ }
+ pTrident->OverrideHsync = 0;
+ if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_HSYNC,
+ &pTrident->OverrideHsync)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Hsync set to %d\n",
+ pTrident->OverrideHsync);
+ }
+ pTrident->OverrideVsync = 0;
+ if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_VSYNC,
+ &pTrident->OverrideVsync)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Vsync set to %d\n",
+ pTrident->OverrideVsync);
+ }
+ pTrident->OverrideHsync = 0;
+ if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_HSYNC,
+ &pTrident->OverrideHsync)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Hsync set to %d\n",
+ pTrident->OverrideHsync);
+ }
+ pTrident->OverrideVsync = 0;
+ if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_VSYNC,
+ &pTrident->OverrideVsync)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Vsync set to %d\n",
+ pTrident->OverrideVsync);
+ }
+ pTrident->OverrideRskew = 0;
+ if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_RSKEW,
+ &pTrident->OverrideRskew)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Rskew set to %d\n",
+ pTrident->OverrideRskew);
+ }
+ pTrident->OverrideBskew = 0;
+ if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_BSKEW,
+ &pTrident->OverrideBskew)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Bskew set to %d\n",
+ pTrident->OverrideBskew);
+ }
+ if (xf86ReturnOptValBool(pTrident->Options, OPTION_SHADOW_FB, FALSE)) {
+ if (!pTrident->Linear)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Ignoring Option SHADOW_FB"
+ " in non-Linear Mode\n");
+ else if (pScrn->depth < 8)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Tgnoring Option SHADOW_FB"
+ " when depth < 8");
+ else {
+ pTrident->ShadowFB = TRUE;
+ pTrident->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using \"Shadow Framebuffer\" - acceleration disabled\n");
+ }
+ }
+ pTrident->Rotate = 0;
+ if ((s = xf86GetOptValString(pTrident->Options, OPTION_ROTATE))) {
+ if (!pTrident->Linear)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Ignoring Option ROTATE "
+ "in non-Linear Mode\n");
+ else if (pScrn->depth < 8)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Ignoring Option ROTATE "
+ "when depth < 8");
+ else {
+ if(!xf86NameCmp(s, "CW")) {
+ /* accel is disabled below for shadowFB */
+ pTrident->ShadowFB = TRUE;
+ pTrident->NoAccel = TRUE;
+ pTrident->HWCursor = FALSE;
+ pTrident->Rotate = 1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Rotating screen clockwise - acceleration disabled\n");
+ } else if(!xf86NameCmp(s, "CCW")) {
+ pTrident->ShadowFB = TRUE;
+ pTrident->NoAccel = TRUE;
+ pTrident->HWCursor = FALSE;
+ pTrident->Rotate = -1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen"
+ "counter clockwise - acceleration disabled\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid"
+ "value for Option \"Rotate\"\n", s);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Valid options are \"CW\" or \"CCW\"\n");
+ }
+ }
+ }
+
+ /* FIXME ACCELERATION */
+ if (!UseMMIO) pTrident->NoAccel = TRUE;
+
+ if (pTrident->Linear) {
+ if (pTrident->pEnt->device->MemBase != 0) {
+ /*
+ * XXX Should check that the config file value matches one of the
+ * PCI base address values.
+ */
+ pTrident->FbAddress = pTrident->pEnt->device->MemBase;
+ from = X_CONFIG;
+ } else {
+ if (IsPciCard)
+ pTrident->FbAddress = pTrident->PciInfo->memBase[0]& 0xFFFFFFF0;
+ else
+ pTrident->FbAddress = 0xA0000;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
+ (unsigned long)pTrident->FbAddress);
+ }
+
+ if (UseMMIO) {
+ if (pTrident->pEnt->device->IOBase != 0) {
+ /*
+ * XXX Should check that the config file value matches one of the
+ * PCI base address values.
+ */
+ pTrident->IOAddress = pTrident->pEnt->device->IOBase;
+ from = X_CONFIG;
+ } else {
+ if (IsPciCard)
+ pTrident->IOAddress = pTrident->PciInfo->memBase[1]& 0xFFFFC000;
+ else
+ /* FIXME - Multihead UNAWARE */
+ pTrident->IOAddress = 0xBF000;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex,X_PROBED,"IO registers at 0x%lX\n",
+ pTrident->IOAddress);
+ }
+
+ /* Register the PCI-assigned resources. */
+ if (xf86RegisterResources(pTrident->pEnt->index, NULL, ResExclusive)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86RegisterResources() found resource conflicts\n");
+ return FALSE;
+ }
+
+ /* Initialize VBE if possible
+ * Don't move this past MMIO enable!!
+ * PIO access will be blocked
+ * when MMIO is turned on!
+ */
+
+ if (xf86LoadSubModule(pScrn, "vbe")) {
+ xf86MonPtr pMon;
+ vbeInfoPtr pVbe;
+
+ xf86LoaderReqSymLists(vbeSymbols, NULL);
+ pVbe = VBEInit(NULL,pTrident->pEnt->index);
+ pMon = vbeDoEDID(pVbe, NULL);
+#ifdef VBE_INFO
+ {
+ VbeInfoBlock* vbeInfoBlockPtr;
+ if ((vbeInfoBlockPtr = VBEGetVBEInfo(pVbe))) {
+ pTrident->vbeModes = VBEBuildVbeModeList(pVbe,vbeInfoBlockPtr);
+ VBEFreeVBEInfo(vbeInfoBlockPtr);
+ }
+ }
+#endif
+ vbeFree(pVbe);
+ if (pMon) {
+ if (!xf86LoadSubModule(pScrn, "ddc")) {
+ TRIDENTFreeRec(pScrn);
+ return FALSE;
+ } else {
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+ xf86SetDDCproperties(pScrn,xf86PrintEDID(pMon));
+ ddcLoaded = TRUE;
+ }
+ }
+
+ }
+
+ if (IsPciCard && UseMMIO) {
+ if (!TRIDENTMapMem(pScrn))
+ return FALSE;
+
+ TRIDENTEnableMMIO(pScrn);
+ }
+
+ OUTB(0x3C4, RevisionID); revision = INB(0x3C5);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Revision is %d\n",revision);
+
+ pScrn->progClock = TRUE;
+ pTrident->EngineOperation = 0x00;
+ pTrident->IsCyber = FALSE;
+ pTrident->HasSGRAM = FALSE;
+ pTrident->NewClockCode = FALSE;
+ pTrident->MUX = FALSE;
+ Support24bpp = FALSE;
+
+ OUTB(vgaIOBase + 4, InterfaceSel);
+
+ switch (pTrident->Chipset) {
+ case TVGA9000:
+ case TVGA9000i:
+ pScrn->progClock = FALSE;
+ NoClocks = 16;
+ pTrident->NoMMIO = TRUE;
+ pTrident->NoAccel = TRUE;
+ pTrident->HWCursor = FALSE;
+ chipset = "TVGA9000/9000i";
+ ramtype = "Standard DRAM";
+ if (pTrident->UsePCIRetry)
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
+ pTrident->UsePCIRetry = FALSE; /* Not Supported */
+ pTrident->frequency = NTSC;
+ break;
+ case TVGA9100B:
+ pScrn->progClock = FALSE;
+ NoClocks = 8;
+ pTrident->NoMMIO = TRUE;
+ pTrident->NoAccel = TRUE;
+ pTrident->HWCursor = FALSE;
+ chipset = "TVGA9100B";
+ ramtype = "Standard DRAM";
+ if (pTrident->UsePCIRetry)
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
+ pTrident->UsePCIRetry = FALSE; /* Not Supported */
+ pTrident->frequency = NTSC;
+ break;
+ case TVGA8900B:
+ pScrn->progClock = FALSE;
+ NoClocks = 8;
+ pTrident->NoMMIO = TRUE;
+ pTrident->NoAccel = TRUE;
+ pTrident->HWCursor = FALSE;
+ chipset = "TVGA8900B";
+ ramtype = "Standard DRAM";
+ if (pTrident->UsePCIRetry)
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
+ pTrident->UsePCIRetry = FALSE; /* Not Supported */
+ pTrident->frequency = NTSC;
+ break;
+ case TVGA8900C:
+ pScrn->progClock = FALSE;
+ NoClocks = 16;
+ pTrident->NoMMIO = TRUE;
+ pTrident->NoAccel = TRUE;
+ pTrident->HWCursor = FALSE;
+ chipset = "TVGA8900C";
+ ramtype = "Standard DRAM";
+ if (pTrident->UsePCIRetry)
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
+ pTrident->UsePCIRetry = FALSE; /* Not Supported */
+ pTrident->frequency = NTSC;
+ break;
+ case TVGA8900D:
+ pScrn->progClock = FALSE;
+ NoClocks = 16;
+ pTrident->NoMMIO = TRUE;
+ pTrident->NoAccel = TRUE;
+ pTrident->HWCursor = FALSE;
+ chipset = "TVGA8900D";
+ ramtype = "Standard DRAM";
+ if (pTrident->UsePCIRetry)
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
+ pTrident->UsePCIRetry = FALSE; /* Not Supported */
+ pTrident->frequency = NTSC;
+ break;
+ case TVGA9200CXr:
+ pScrn->progClock = FALSE;
+ NoClocks = 16;
+ pTrident->NoMMIO = TRUE;
+ pTrident->NoAccel = TRUE;
+ pTrident->HWCursor = FALSE;
+ chipset = "TVGA9200CXr";
+ ramtype = "Standard DRAM";
+ if (pTrident->UsePCIRetry)
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
+ pTrident->UsePCIRetry = FALSE; /* Not Supported */
+ pTrident->frequency = NTSC;
+ break;
+ case TGUI9400CXi:
+ pScrn->progClock = FALSE;
+ NoClocks = 16;
+ pTrident->NoMMIO = TRUE;
+ pTrident->NoAccel = TRUE;
+ pTrident->HWCursor = FALSE;
+ chipset = "TVGA9200CXr";
+ ramtype = "Standard DRAM";
+ if (pTrident->UsePCIRetry)
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
+ pTrident->UsePCIRetry = FALSE; /* Not Supported */
+ pTrident->frequency = NTSC;
+ break;
+ case TGUI9440AGi:
+ pTrident->ddc1Read = Tridentddc1Read;
+ pTrident->HWCursor = FALSE;
+ chipset = "TGUI9440AGi";
+ ramtype = "Standard DRAM";
+ if (pTrident->UsePCIRetry)
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
+ pTrident->UsePCIRetry = FALSE; /* Not Supported */
+ pTrident->frequency = NTSC;
+ break;
+ case CYBER9320:
+ pTrident->ddc1Read = Tridentddc1Read;
+ chipset = "Cyber9320";
+ ramtype = "Standard DRAM";
+ if (pTrident->UsePCIRetry)
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
+ pTrident->UsePCIRetry = FALSE; /* Not Supported */
+ break;
+ /* Trident didn't update the PCI ID's and so we have to detemine
+ * which chips are right ! Then override pTrident->Chipset to
+ * correct values */
+ case TGUI9660:
+ pTrident->ddc1Read = Tridentddc1Read;
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
+ ramtype = "EDO Ram";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C)
+ ramtype = "Standard DRAM";
+ switch (revision) {
+ case 0x00:
+ chipset = "TGUI9660";
+ pTrident->Chipset = TGUI9660;
+ if (pTrident->UsePCIRetry)
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
+ pTrident->UsePCIRetry = FALSE; /* Not Supported */
+ break;
+ case 0x01:
+ chipset = "TGUI9680";
+ pTrident->Chipset = TGUI9680;
+ if (pTrident->UsePCIRetry)
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
+ pTrident->UsePCIRetry = FALSE; /* Not Supported */
+ break;
+ case 0x10:
+ chipset = "ProVidia 9682";
+ Support24bpp = TRUE;
+ pTrident->Chipset = PROVIDIA9682;
+ break;
+ case 0x21:
+ chipset = "ProVidia 9685";
+ Support24bpp = TRUE;
+ pTrident->NewClockCode = TRUE;
+ pTrident->Chipset = PROVIDIA9685;
+ break;
+ case 0x22:
+ case 0x23:
+ chipset = "Cyber 9397";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
+ ramtype = "EDO Ram";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
+ ramtype = "SDRAM";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
+ pTrident->HasSGRAM = TRUE;
+ ramtype = "SGRAM";
+ }
+ pTrident->NewClockCode = TRUE;
+ pTrident->Chipset = CYBER9397;
+ pTrident->IsCyber = TRUE;
+ break;
+ case 0x2a:
+ chipset = "Cyber 9397/DVD";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
+ ramtype = "EDO Ram";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
+ ramtype = "SDRAM";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
+ pTrident->HasSGRAM = TRUE;
+ ramtype = "SGRAM";
+ }
+ pTrident->NewClockCode = TRUE;
+ pTrident->Chipset = CYBER9397DVD;
+ pTrident->IsCyber = TRUE;
+ break;
+ case 0x30:
+ case 0x33:
+ case 0x34:
+ case 0x35:
+ case 0xB3:
+ chipset = "Cyber 9385";
+ pTrident->NewClockCode = TRUE;
+ pTrident->Chipset = CYBER9385;
+ pTrident->IsCyber = TRUE;
+ break;
+ case 0x38:
+ case 0x3A:
+ chipset = "Cyber 9385-1";
+ pTrident->NewClockCode = TRUE;
+ pTrident->Chipset = CYBER9385;
+ pTrident->IsCyber = TRUE;
+ break;
+ case 0x40:
+ case 0x41:
+ case 0x42:
+ case 0x43:
+ chipset = "Cyber 9382";
+ pTrident->NewClockCode = TRUE;
+ pTrident->Chipset = CYBER9382;
+ pTrident->IsCyber = TRUE;
+ break;
+ case 0x4A:
+ chipset = "Cyber 9388";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
+ ramtype = "EDO Ram";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
+ ramtype = "SDRAM";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
+ pTrident->HasSGRAM = TRUE;
+ ramtype = "SGRAM";
+ }
+ pTrident->NewClockCode = TRUE;
+ pTrident->Chipset = CYBER9388;
+ pTrident->IsCyber = TRUE;
+ break;
+ default:
+ chipset = "Unknown";
+ pTrident->Chipset = TGUI9660;
+ break;
+ }
+ break;
+ case CYBER9388:
+ pTrident->ddc1Read = Tridentddc1Read;
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
+ ramtype = "EDO Ram";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
+ ramtype = "SDRAM";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
+ pTrident->HasSGRAM = TRUE;
+ ramtype = "SGRAM";
+ }
+ pTrident->IsCyber = TRUE;
+ Support24bpp = TRUE;
+ chipset = "Cyber 9388";
+ pTrident->NewClockCode = TRUE;
+ break;
+ case CYBER9397:
+ pTrident->ddc1Read = Tridentddc1Read;
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
+ ramtype = "EDO Ram";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
+ ramtype = "SDRAM";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
+ pTrident->HasSGRAM = TRUE;
+ ramtype = "SGRAM";
+ }
+ pTrident->IsCyber = TRUE;
+ Support24bpp = TRUE;
+ chipset = "Cyber 9397";
+ pTrident->NewClockCode = TRUE;
+ break;
+ case CYBER9397DVD:
+ pTrident->ddc1Read = Tridentddc1Read;
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
+ ramtype = "EDO Ram";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
+ ramtype = "SDRAM";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
+ pTrident->HasSGRAM = TRUE;
+ ramtype = "SGRAM";
+ }
+ pTrident->IsCyber = TRUE;
+ Support24bpp = TRUE;
+ chipset = "Cyber 9397/DVD";
+ pTrident->NewClockCode = TRUE;
+ break;
+ case CYBER9520:
+ pTrident->ddc1Read = Tridentddc1Read;
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
+ ramtype = "EDO Ram";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
+ ramtype = "SDRAM";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
+ pTrident->HasSGRAM = TRUE;
+ ramtype = "SGRAM";
+ }
+ pTrident->IsCyber = TRUE;
+ Support24bpp = TRUE;
+ chipset = "Cyber 9520";
+ pTrident->NewClockCode = TRUE;
+ break;
+ case CYBER9525DVD:
+ pTrident->ddc1Read = Tridentddc1Read;
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
+ ramtype = "EDO Ram";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
+ ramtype = "SDRAM";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
+ pTrident->HasSGRAM = TRUE;
+ ramtype = "SGRAM";
+ }
+ pTrident->IsCyber = TRUE;
+ Support24bpp = TRUE;
+ chipset = "Cyber 9525/DVD";
+ pTrident->NewClockCode = TRUE;
+ break;
+ case CYBERBLADEE4:
+ pTrident->ddc1Read = Tridentddc1Read;
+ ramtype = "SDRAM";
+ pTrident->IsCyber = TRUE;
+ Support24bpp = TRUE;
+ chipset = "CyberBlade e4/128";
+ pTrident->NewClockCode = TRUE;
+ break;
+ case IMAGE975:
+ pTrident->ddc1Read = Tridentddc1Read;
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
+ ramtype = "EDO Ram";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
+ ramtype = "SDRAM";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
+ pTrident->HasSGRAM = TRUE;
+ ramtype = "SGRAM";
+ }
+ Support24bpp = TRUE;
+ chipset = "3DImage975";
+ pTrident->NewClockCode = TRUE;
+ break;
+ case IMAGE985:
+ pTrident->ddc1Read = Tridentddc1Read;
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x04)
+ ramtype = "EDO Ram";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
+ ramtype = "SDRAM";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
+ pTrident->HasSGRAM = TRUE;
+ ramtype = "SGRAM";
+ }
+ Support24bpp = TRUE;
+ chipset = "3DImage985";
+ pTrident->NewClockCode = TRUE;
+ break;
+ case BLADE3D:
+ pTrident->ddc1Read = Tridentddc1Read;
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x08)
+ ramtype = "SDRAM";
+ if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
+ pTrident->HasSGRAM = TRUE;
+ ramtype = "SGRAM";
+ }
+ Support24bpp = TRUE;
+ chipset = "Blade3D";
+ pTrident->NewClockCode = TRUE;
+ pTrident->frequency = NTSC;
+ break;
+ case CYBERBLADEI7:
+ pTrident->ddc1Read = Tridentddc1Read;
+ ramtype = "SDRAM";
+ /* pTrident->IsCyber = TRUE; VIA MVP4 integrated Desktop version */
+ Support24bpp = TRUE;
+ chipset = "CyberBlade/i7/VIA MVP4";
+ pTrident->NewClockCode = TRUE;
+ pTrident->frequency = NTSC;
+ break;
+ case CYBERBLADEI7D:
+ pTrident->ddc1Read = Tridentddc1Read;
+ ramtype = "SDRAM";
+ pTrident->IsCyber = TRUE;
+ Support24bpp = TRUE;
+ chipset = "CyberBlade/DSTN/i7";
+ pTrident->NewClockCode = TRUE;
+ pTrident->frequency = NTSC;
+ break;
+ case CYBERBLADEI1:
+ pTrident->ddc1Read = Tridentddc1Read;
+ ramtype = "SDRAM";
+ pTrident->IsCyber = TRUE;
+ Support24bpp = TRUE;
+ chipset = "CyberBlade/i1";
+ pTrident->NewClockCode = TRUE;
+ pTrident->frequency = NTSC;
+ break;
+ case CYBERBLADEI1D:
+ pTrident->ddc1Read = Tridentddc1Read;
+ ramtype = "SDRAM";
+ pTrident->IsCyber = TRUE;
+ Support24bpp = TRUE;
+ chipset = "CyberBlade/DSTN/i1";
+ pTrident->NewClockCode = TRUE;
+ pTrident->frequency = NTSC;
+ break;
+ case CYBERBLADEAI1:
+ pTrident->ddc1Read = Tridentddc1Read;
+ ramtype = "SDRAM";
+ pTrident->IsCyber = TRUE;
+ Support24bpp = TRUE;
+ chipset = "CyberBlade/Ai1";
+ pTrident->NewClockCode = TRUE;
+ pTrident->frequency = NTSC;
+ break;
+ case CYBERBLADEAI1D:
+ pTrident->ddc1Read = Tridentddc1Read;
+ ramtype = "SDRAM";
+ pTrident->IsCyber = TRUE;
+ Support24bpp = TRUE;
+ chipset = "CyberBlade/DSTN/Ai1";
+ pTrident->NewClockCode = TRUE;
+ pTrident->frequency = NTSC;
+ break;
+ case BLADEXP: /* 0x9910 */
+ pTrident->ddc1Read = Tridentddc1Read;
+ ramtype = "SGRAM";
+ pTrident->HasSGRAM = TRUE;
+ Support24bpp = TRUE;
+ pTrident->NewClockCode = TRUE;
+ pTrident->frequency = NTSC;
+ OUTB(0x3C4, 0x5D);
+ if (pTrident->PciInfo->subsysVendor != 0x1023) {
+ chipset = "CyberBladeXP";
+ pTrident->IsCyber = TRUE;
+ } else
+ if (!(INB(0x3C5) & 0x01)) {
+ chipset = "BladeXP";
+ } else {
+ CARD8 mem1, mem2;
+ OUTB(vgaIOBase + 0x04, SPR);
+ mem1 = INB(vgaIOBase + 5);
+ OUTB(vgaIOBase + 0x04, 0xC1);
+ mem2 = INB(vgaIOBase + 5);
+ if ((mem1 & 0x0e) && (mem2 == 0x11)) {
+ chipset = "BladeT64";
+ } else {
+ chipset = "BladeT16";
+ }
+ }
+ break;
+ case CYBERBLADEXPAI1:
+ pTrident->ddc1Read = Tridentddc1Read;
+ ramtype = "SGRAM";
+ pTrident->HasSGRAM = TRUE;
+ pTrident->IsCyber = TRUE;
+ pTrident->shadowNew = TRUE;
+ Support24bpp = TRUE;
+ chipset = "CyberBladeXPAi1";
+ pTrident->NewClockCode = TRUE;
+ pTrident->frequency = NTSC;
+ break;
+ }
+
+ if (!pScrn->progClock) {
+ pScrn->numClocks = NoClocks;
+ xf86GetClocks(pScrn, NoClocks, TRIDENTClockSelect,
+ vgaHWProtect, vgaHWBlankScreen,
+ vgaIOBase + 0x0A, 0x08, 1, 28322);
+ from = X_PROBED;
+ xf86ShowClocks(pScrn, from);
+ }
+
+ if (!chipset) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No support for \"%s\"\n",
+ pScrn->chipset);
+ if (IsPciCard && UseMMIO) {
+ TRIDENTDisableMMIO(pScrn);
+ TRIDENTUnmapMem(pScrn);
+ }
+ return FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Found %s chip\n", chipset);
+ if (ramtype)
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "RAM type is %s\n", ramtype);
+
+ if (pScrn->bitsPerPixel == 24 && !Support24bpp) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "No support for 24bpp on this chipset, use -pixmap32.\n");
+ if (IsPciCard && UseMMIO) {
+ TRIDENTDisableMMIO(pScrn);
+ TRIDENTUnmapMem(pScrn);
+ }
+ return FALSE;
+ }
+
+ /* HW bpp matches reported bpp */
+ pTrident->HwBpp = pScrn->bitsPerPixel;
+
+ /* Due to bugs in the chip, turn it off */
+ if (pTrident->Chipset >= CYBERBLADEI7 && pTrident->Chipset <= CYBERBLADEAI1D)
+ pTrident->HWCursor = FALSE;
+
+ from = X_PROBED;
+ if (pTrident->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = pTrident->pEnt->device->videoRam;
+ from = X_CONFIG;
+
+ /* Due to only 12bits of cursor location, if user has overriden
+ * disable the cursor automatically */
+ if (pTrident->Chipset >= CYBER9397 && pTrident->Chipset < CYBERBLADEE4)
+ if (pTrident->pEnt->device->videoRam > 4096)
+ pTrident->HWCursor = FALSE;
+ } else {
+ if (pTrident->Chipset == CYBER9525DVD) {
+ pScrn->videoRam = 2560;
+ } else
+ {
+ OUTB(vgaIOBase + 4, SPR);
+ videoram = INB(vgaIOBase + 5);
+ if (pTrident->Chipset < TGUI9440AGi)
+ videorammask = 0x07;
+ else
+ videorammask = 0x0F;
+ switch (videoram & videorammask) {
+ case 0x01:
+ pScrn->videoRam = 512;
+ break;
+ case 0x02: /* XP */
+ pScrn->videoRam = 6144;
+ break;
+ case 0x03:
+ pScrn->videoRam = 1024;
+ break;
+ case 0x04:
+ /*
+ * 8MB, but - hw cursor can't store above 4MB
+ * This only affects Image series chipsets, but for
+ * some reason, reports suggest that the 9397DVD isn't
+ * affected. XXX needs furthur investigation !
+ */
+ if (pTrident->HWCursor && (pTrident->Chipset != CYBER9397DVD) &&
+ (pTrident->Chipset < CYBERBLADEE4)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Found 8MB board, using 4MB\n");
+ pScrn->videoRam = 4096;
+ } else
+ pScrn->videoRam = 8192;
+ break;
+ case 0x06: /* XP */
+ pScrn->videoRam = 10240;
+ break;
+ case 0x07:
+ pScrn->videoRam = 2048;
+ break;
+ case 0x08: /* XP */
+ pScrn->videoRam = 12288;
+ break;
+ case 0x0A: /* XP */
+ pScrn->videoRam = 14336;
+ break;
+ case 0x0C: /* XP */
+ pScrn->videoRam = 16384;
+ break;
+ case 0x0E: /* XP */
+ OUTB(vgaIOBase + 4, 0xC1);
+ switch (INB(vgaIOBase + 5) & 0x11) {
+ case 0x00:
+ pScrn->videoRam = 20480;
+ break;
+ case 0x01:
+ pScrn->videoRam = 24576;
+ break;
+ case 0x10:
+ pScrn->videoRam = 28672;
+ break;
+ case 0x11:
+ pScrn->videoRam = 32768;
+ break;
+ }
+ break;
+ case 0x0F:
+ pScrn->videoRam = 4096;
+ break;
+ default:
+ pScrn->videoRam = 1024;
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Unable to determine VideoRam, defaulting to 1MB\n",
+ pScrn->videoRam);
+ break;
+ }
+ }
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ pTrident->HWCursor ? "HW" : "SW");
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+
+ if (pTrident->IsCyber) {
+ unsigned char mod, dsp, dsp1;
+
+ pTrident->lcdMode = 0xff;
+
+ OUTB(0x3CE,0x42);
+ dsp = INB(0x3CF);
+ OUTB(0x3CE,0x43);
+ dsp1 = INB(0x3CF);
+ OUTB(0x3CE,0x52);
+ mod = INB(0x3CF);
+ /*
+ * Only allow display size override if 1280x1024 is detected
+ * Currently 1400x1050 is supported - which is detected as
+ * 1280x1024
+ */
+ if (pTrident->displaySize) {
+ if (((mod >> 4) & 3) == 0) {
+ for (i = 0; LCD[i].mode != 0xff; i++) {
+ if (pTrident->displaySize == LCD[i].display_x)
+ pTrident->lcdMode = LCD[i].mode;
+ }
+ xf86DrvMsg(pScrn->scrnIndex,
+ X_CONFIG,"%s Panel %ix%i found\n",
+ (dsp & 0x80) ? "TFT" :
+ ((dsp1 & 0x20) ? "DSTN" : "STN"),
+ LCD[i].display_x,LCD[i].display_y);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex,X_WARNING,
+ "Display size override only for 1280x1024\n");
+ pTrident->displaySize = 0;
+ }
+ }
+
+ if (!pTrident->displaySize) {
+ for (i = 0; LCD[i].mode != 0xff; i++) {
+ if (LCD[i].mode == ((mod >> 4) & 3)) {
+ pTrident->lcdMode = i;
+ xf86DrvMsg(pScrn->scrnIndex,
+ X_PROBED,"%s Panel %ix%i found\n",
+ (dsp & 0x80) ? "TFT" :
+ ((dsp1 & 0x20) ? "DSTN" : "STN"),
+ LCD[i].display_x,LCD[i].display_y);
+ }
+ }
+ }
+ if (pTrident->dspOverride) {
+ if (pTrident->dspOverride & LCD_ACTIVE)
+ pTrident->lcdActive = TRUE;
+ else
+ pTrident->lcdActive = FALSE;
+ } else {
+ OUTB(0x3CE, FPConfig);
+ pTrident->lcdActive = (INB(0x3CF) & 0x10);
+ }
+ }
+
+ pTrident->MCLK = 0;
+ mclk = CalculateMCLK(pScrn);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Memory Clock is %3.2f MHz\n", mclk);
+ if (xf86GetOptValFreq(pTrident->Options, OPTION_SETMCLK, OPTUNITS_MHZ,
+ &real)) {
+ pTrident->MCLK = (int)(real * 1000.0);
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Setting new Memory Clock to %3.2f MHz\n",
+ (float)(pTrident->MCLK / 1000));
+ }
+
+ /* Set the min pixel clock */
+ pTrident->MinClock = 12000; /* XXX Guess, need to check this */
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
+ pTrident->MinClock / 1000);
+
+ /*
+ * If the user has specified ramdac speed in the XF86Config
+ * file, we respect that setting.
+ */
+ if (pTrident->pEnt->device->dacSpeeds[0]) {
+ int speed = 0;
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP8];
+ break;
+ case 16:
+ speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP16];
+ break;
+ case 24:
+ speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP24];
+ break;
+ case 32:
+ speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP32];
+ break;
+ }
+ if (speed == 0)
+ pTrident->MaxClock = pTrident->pEnt->device->dacSpeeds[0];
+ else
+ pTrident->MaxClock = speed;
+ from = X_CONFIG;
+ } else {
+ switch (pScrn->bitsPerPixel) {
+ case 16:
+ pTrident->MaxClock = ClockLimit16bpp[pTrident->Chipset];
+ break;
+ case 24:
+ pTrident->MaxClock = ClockLimit24bpp[pTrident->Chipset];
+ break;
+ case 32:
+ pTrident->MaxClock = ClockLimit32bpp[pTrident->Chipset];
+ break;
+ default:
+ pTrident->MaxClock = ClockLimit[pTrident->Chipset];
+ break;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
+ pTrident->MaxClock / 1000);
+
+ /*
+ * Setup the ClockRanges, which describe what clock ranges are available,
+ * and what sort of modes they can be used for.
+ */
+ clockRanges = xnfcalloc(sizeof(ClockRange), 1);
+ clockRanges->next = NULL;
+ if (!pScrn->progClock) {
+ if (pScrn->videoRam < 1024)
+ clockRanges->ClockMulFactor = 2;
+ if (pScrn->bitsPerPixel == 16)
+ clockRanges->ClockMulFactor = 2;
+ }
+ clockRanges->minClock = pTrident->MinClock;
+ clockRanges->maxClock = pTrident->MaxClock;
+ clockRanges->clockIndex = -1; /* programmable */
+ clockRanges->interlaceAllowed = TRUE;
+ clockRanges->doubleScanAllowed = FALSE; /* XXX check this */
+
+ /*
+ * xf86ValidateModes will check that the mode HTotal and VTotal values
+ * don't exceed the chipset's limit if pScrn->maxHValue and
+ * pScrn->maxVValue are set. Since our TRIDENTValidMode() already takes
+ * care of this, we don't worry about setting them here.
+ */
+
+ if ((pScrn->depth < 8) ||
+ (pScrn->bitsPerPixel == 24)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Disabling Engine due to 24bpp or < 8bpp.\n");
+ pTrident->NoAccel = TRUE;
+ }
+
+ /* Select valid modes from those available */
+ if (pTrident->NoAccel || Is3Dchip) {
+ /*
+ * XXX Assuming min pitch 256, max 4096
+ * XXX Assuming min height 128, max 4096
+ */
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ NULL, 256, 4096,
+ pScrn->bitsPerPixel, 128, 4096,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pTrident->FbMapSize,
+ LOOKUP_BEST_REFRESH);
+ } else {
+ /*
+ * XXX Assuming min height 128, max 2048
+ */
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ GetAccelPitchValues(pScrn), 0, 0,
+ pScrn->bitsPerPixel, 128, 2048,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pTrident->FbMapSize,
+ LOOKUP_BEST_REFRESH);
+ }
+
+ if (i == -1) {
+ if (IsPciCard && UseMMIO) {
+ TRIDENTDisableMMIO(pScrn);
+ TRIDENTUnmapMem(pScrn);
+ }
+ TRIDENTFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrn);
+
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ if (IsPciCard && UseMMIO) {
+ TRIDENTDisableMMIO(pScrn);
+ TRIDENTUnmapMem(pScrn);
+ }
+ TRIDENTFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+ /* Set the current mode to the first in the list */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrn);
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /* Load bpp-specific modules */
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ pTrident->EngineOperation |= 0x00;
+ mod = "xf1bpp";
+ Sym = "xf1bppScreenInit";
+ break;
+ case 4:
+ pTrident->EngineOperation |= 0x00;
+ mod = "xf4bpp";
+ Sym = "xf4bppScreenInit";
+ break;
+ case 8:
+ pTrident->EngineOperation |= 0x00;
+ mod = "fb";
+ break;
+ case 16:
+ pTrident->EngineOperation |= 0x01;
+ mod = "fb";
+ break;
+ case 24:
+ pTrident->EngineOperation |= 0x03;
+ mod = "fb";
+ break;
+ case 32:
+ pTrident->EngineOperation |= 0x02;
+ mod = "fb";
+ break;
+ }
+
+ if (mod && xf86LoadSubModule(pScrn, mod) == NULL) {
+ if (IsPciCard && UseMMIO) {
+ TRIDENTDisableMMIO(pScrn);
+ TRIDENTUnmapMem(pScrn);
+ }
+ TRIDENTFreeRec(pScrn);
+ return FALSE;
+ }
+
+ if (mod) {
+ if (Sym) {
+ xf86LoaderReqSymbols(Sym, NULL);
+ } else {
+ xf86LoaderReqSymLists(fbSymbols, NULL);
+ }
+ }
+
+ if (!xf86LoadSubModule(pScrn, "i2c")) {
+ if (IsPciCard && UseMMIO) {
+ TRIDENTDisableMMIO(pScrn);
+ TRIDENTUnmapMem(pScrn);
+ }
+ TRIDENTFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(i2cSymbols, NULL);
+
+ /* Load shadow if needed */
+ if (pTrident->ShadowFB) {
+ if (!xf86LoadSubModule(pScrn, "shadow")) {
+ TRIDENTFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(shadowSymbols, NULL);
+ }
+
+ /* Load XAA if needed */
+ if (!pTrident->NoAccel) {
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ if (IsPciCard && UseMMIO) {
+ TRIDENTDisableMMIO(pScrn);
+ TRIDENTUnmapMem(pScrn);
+ }
+ TRIDENTFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+
+ switch (pScrn->displayWidth * pScrn->bitsPerPixel / 8) {
+ case 512:
+ case 8192:
+ pTrident->EngineOperation |= 0x00;
+ break;
+ case 1024:
+ pTrident->EngineOperation |= 0x04;
+ break;
+ case 2048:
+ pTrident->EngineOperation |= 0x08;
+ break;
+ case 4096:
+ pTrident->EngineOperation |= 0x0C;
+ break;
+ }
+ }
+
+ /* Load DDC if needed */
+ /* This gives us DDC1 - we should be able to get DDC2B using i2c */
+
+ if (! ddcLoaded)
+ if (!xf86LoadSubModule(pScrn, "ddc")) {
+ if (IsPciCard && UseMMIO) {
+ TRIDENTDisableMMIO(pScrn);
+ TRIDENTUnmapMem(pScrn);
+ }
+ TRIDENTFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+
+ if (IsPciCard && UseMMIO) {
+ TRIDENTDisableMMIO(pScrn);
+ TRIDENTUnmapMem(pScrn);
+ }
+
+
+ pTrident->FbMapSize = pScrn->videoRam * 1024;
+
+ pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+
+ if (pTrident->IsCyber && pTrident->MMIOonly)
+ pScrn->racIoFlags = 0;
+ else
+ pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+
+ return TRUE;
+}
+
+/*
+ * Map the framebuffer and MMIO memory.
+ */
+
+static Bool
+TRIDENTMapMem(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ int mapsize = 0x10000;
+
+ if (Is3Dchip) mapsize = 0x20000;
+
+ if (IsPciCard && UseMMIO)
+ pTrident->IOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ pTrident->PciTag, pTrident->IOAddress, mapsize);
+ else {
+ pTrident->IOBase = xf86MapDomainMemory(pScrn->scrnIndex, VIDMEM_MMIO,
+ pTrident->PciTag, pTrident->IOAddress, 0x1000);
+ pTrident->IOBase += 0xF00;
+ }
+
+ if (pTrident->IOBase == NULL)
+ return FALSE;
+
+ if (pTrident->Linear) {
+ if (pTrident->FbMapSize != 0) {
+ pTrident->FbBase = xf86MapPciMem(pScrn->scrnIndex,
+ VIDMEM_FRAMEBUFFER,
+ pTrident->PciTag,
+ (unsigned long)pTrident->FbAddress,
+ pTrident->FbMapSize);
+ if (pTrident->FbBase == NULL)
+ return FALSE;
+ }
+ }
+ else
+ pTrident->FbBase = hwp->Base;
+
+ return TRUE;
+}
+
+/*
+ * Unmap the framebuffer and MMIO memory.
+ */
+
+static Bool
+TRIDENTUnmapMem(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int mapsize = 0x10000;
+
+ if (Is3Dchip) mapsize = 0x20000;
+
+ /*
+ * Unmap IO registers to virtual address space
+ */
+ if (IsPciCard && UseMMIO)
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->IOBase, mapsize);
+ else {
+ pTrident->IOBase -= 0xF00;
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->IOBase, 0x1000);
+ }
+ pTrident->IOBase = NULL;
+
+ if (pTrident->Linear) {
+ if (pTrident->FbMapSize != 0) {
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->FbBase,
+ pTrident->FbMapSize);
+ pTrident->FbBase = NULL;
+ }
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * This function saves the video state.
+ */
+static void
+TRIDENTSave(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident;
+ vgaRegPtr vgaReg;
+ TRIDENTRegPtr tridentReg;
+
+ pTrident = TRIDENTPTR(pScrn);
+ vgaReg = &VGAHWPTR(pScrn)->SavedReg;
+ tridentReg = &pTrident->SavedReg;
+
+ vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_CMAP |
+ (IsPrimaryCard ? VGA_SR_FONTS : 0));
+
+ if (pScrn->progClock)
+ TridentSave(pScrn, tridentReg);
+ else
+ TVGASave(pScrn, tridentReg);
+}
+
+
+/*
+ * Initialise a new mode. This is currently still using the old
+ * "initialise struct, restore/write struct to HW" model. That could
+ * be changed.
+ */
+
+static Bool
+TRIDENTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg;
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ TRIDENTRegPtr tridentReg;
+ int clock;
+
+ TridentFindClock(pScrn,mode->Clock);
+
+ clock = pTrident->currentClock;
+
+ switch (pTrident->Chipset) {
+ case TGUI9660:
+ case TGUI9680:
+ case PROVIDIA9682:
+ case PROVIDIA9685:
+ case IMAGE975:
+ case IMAGE985:
+ case BLADE3D:
+ case CYBERBLADEI7:
+ case CYBERBLADEI7D:
+ case CYBERBLADEI1:
+ case CYBERBLADEI1D:
+ case CYBERBLADEAI1:
+ case CYBERBLADEAI1D:
+ case CYBER9520:
+ case CYBER9525DVD:
+ case CYBERBLADEE4:
+ case CYBER9397:
+ case CYBER9397DVD:
+ case BLADEXP:
+ case CYBERBLADEXPAI1:
+ /* Get ready for MUX mode */
+ if (pTrident->MUX &&
+ pScrn->bitsPerPixel == 8 &&
+ !mode->CrtcHAdjusted) {
+ mode->CrtcHDisplay >>= 1;
+ mode->CrtcHSyncStart >>= 1;
+ mode->CrtcHSyncEnd >>= 1;
+ mode->CrtcHBlankStart >>= 1;
+ mode->CrtcHBlankEnd >>= 1;
+ mode->CrtcHTotal >>= 1;
+ mode->CrtcHAdjusted = TRUE;
+ }
+ break;
+ default:
+ if (pScrn->videoRam < 1024 &&
+ !mode->CrtcHAdjusted) {
+ mode->CrtcHDisplay <<= 1;
+ mode->CrtcHSyncStart <<= 1;
+ mode->CrtcHSyncEnd <<= 1;
+ mode->CrtcHBlankStart <<= 1;
+ mode->CrtcHBlankEnd <<= 1;
+ mode->CrtcHTotal <<= 1;
+ mode->CrtcHAdjusted = TRUE;
+ }
+ break;
+ }
+
+ vgaHWUnlock(hwp);
+ /* Initialise the ModeReg values */
+ if (!vgaHWInit(pScrn, mode))
+ return FALSE;
+ pScrn->vtSema = TRUE;
+ /*
+ * We used to do this at a later time.
+ * Now since READOUT isn't defined any more
+ * we do it here.
+ * The original NOTE read:
+ * TridentInit() has to modify registers
+ * that have already been set by vgaHWRestore().
+ * So we call it _after_ vgaHWRestore() has
+ * programmed these registers.
+ */
+ if (pScrn->progClock) {
+ if (!TridentInit(pScrn, mode))
+ return FALSE;
+ } else {
+ if (!TVGAInit(pScrn, mode))
+ return FALSE;
+ }
+
+ /* Program the registers */
+ vgaHWProtect(pScrn, TRUE);
+ vgaReg = &hwp->ModeReg;
+ tridentReg = &pTrident->ModeReg;
+
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
+ if (pScrn->progClock)
+ TridentRestore(pScrn, tridentReg);
+ else
+ TVGARestore(pScrn, tridentReg);
+
+ vgaHWProtect(pScrn, FALSE);
+
+ if (xf86IsPc98())
+ PC98TRIDENTEnable(pScrn);
+
+ return TRUE;
+}
+
+/*
+ * Restore the initial (text) mode.
+ */
+static void
+TRIDENTRestore(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp;
+ vgaRegPtr vgaReg;
+ TRIDENTPtr pTrident;
+ TRIDENTRegPtr tridentReg;
+
+ hwp = VGAHWPTR(pScrn);
+ pTrident = TRIDENTPTR(pScrn);
+ vgaReg = &hwp->SavedReg;
+ tridentReg = &pTrident->SavedReg;
+
+ vgaHWProtect(pScrn, TRUE);
+
+ if (pScrn->progClock)
+ TridentRestore(pScrn, tridentReg);
+ else
+ TVGARestore(pScrn, tridentReg);
+
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_CMAP |
+ (IsPrimaryCard ? VGA_SR_FONTS : 0));
+
+ vgaHWProtect(pScrn, FALSE);
+}
+
+
+/* Mandatory */
+
+/* This gets called at the start of each server generation */
+
+static Bool
+TRIDENTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ /* The vgaHW references will disappear one day */
+ ScrnInfoPtr pScrn;
+ vgaHWPtr hwp;
+ int vgaIOBase;
+ TRIDENTPtr pTrident;
+ int ret;
+ VisualPtr visual;
+ unsigned char *FBStart;
+ int width, height, displayWidth;
+
+ /*
+ * First get the ScrnInfoRec
+ */
+ pScrn = xf86Screens[pScreen->myNum];
+ pTrident = TRIDENTPTR(pScrn);
+
+ if (IsPrimaryCard) {
+ if (!vgaHWMapMem(pScrn))
+ return FALSE;
+ }
+
+ /* Map the TRIDENT memory and MMIO areas */
+ if (!TRIDENTMapMem(pScrn))
+ return FALSE;
+
+ if (!xf86IsPc98()) {
+#ifdef VBE_INFO
+ if (pTrident->vbeModes) {
+ pTrident->pVbe = VBEInit(NULL,pTrident->pEnt->index);
+ pTrident->Int10 = pTrident->pVbe->pInt10;
+ } else
+#endif
+ {
+ if (xf86LoadSubModule(pScrn, "int10")) {
+ xf86LoaderReqSymLists(int10Symbols, NULL);
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Initializing int10\n");
+ pTrident->Int10 = xf86InitInt10(pTrident->pEnt->index);
+ }
+ }
+ }
+
+ hwp = VGAHWPTR(pScrn);
+
+ if (IsPciCard && UseMMIO) {
+ TRIDENTEnableMMIO(pScrn);
+
+ /* Initialize the MMIO vgahw functions */
+ vgaHWSetMmioFuncs(hwp, pTrident->IOBase, 0);
+ }
+
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ /* Save the current state */
+ TRIDENTSave(pScrn);
+
+ /*
+ * Some Trident chip on PC-9821 needs setup,
+ * because VGA chip is not initialized by VGA BIOS.
+ */
+ if (IsPciCard && xf86IsPc98()) {
+ PC98TRIDENTInit(pScrn);
+ } else tridentSetModeBIOS(pScrn,pScrn->currentMode);
+
+ /* Initialise the first mode */
+ if (!TRIDENTModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+
+ /* Darken the screen for aesthetic reasons and set the viewport */
+ TRIDENTSaveScreen(pScreen, SCREEN_SAVER_ON);
+ TRIDENTAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ /*
+ * The next step is to setup the screen's visuals, and initialise the
+ * framebuffer code. In cases where the framebuffer's default
+ * choices for things like visual layouts and bits per RGB are OK,
+ * this may be as simple as calling the framebuffer's ScreenInit()
+ * function. If not, the visuals will need to be setup before calling
+ * a fb ScreenInit() function and fixed up after.
+ *
+ * For most PC hardware at depths >= 8, the defaults that cfb uses
+ * are not appropriate. In this driver, we fixup the visuals after.
+ */
+
+ /*
+ * Reset visual list.
+ */
+ miClearVisualTypes();
+
+ /* Setup the visuals we support. */
+
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual)) {
+ if (pTrident->pVbe)
+ vbeFree(pTrident->pVbe);
+ else
+ xf86FreeInt10(pTrident->Int10);
+ return FALSE;
+ }
+
+ miSetPixmapDepths ();
+
+ /* FIXME - we don't do shadowfb for < 4 */
+ displayWidth = pScrn->displayWidth;
+ if (pTrident->Rotate) {
+ height = pScrn->virtualX;
+ width = pScrn->virtualY;
+ } else {
+ width = pScrn->virtualX;
+ height = pScrn->virtualY;
+ }
+
+ if(pTrident->ShadowFB) {
+ pTrident->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
+ pTrident->ShadowPtr = xalloc(pTrident->ShadowPitch * height);
+ displayWidth = pTrident->ShadowPitch / (pScrn->bitsPerPixel >> 3);
+ FBStart = pTrident->ShadowPtr;
+ } else {
+ pTrident->ShadowFB = FALSE;
+ pTrident->ShadowPtr = NULL;
+ FBStart = pTrident->FbBase;
+ }
+
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ ret = xf1bppScreenInit(pScreen, FBStart, width,
+ height, pScrn->xDpi, pScrn->yDpi,
+ displayWidth);
+ break;
+ case 4:
+ ret = xf4bppScreenInit(pScreen, FBStart, width,
+ height, pScrn->xDpi, pScrn->yDpi,
+ displayWidth);
+ break;
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ ret = fbScreenInit(pScreen, FBStart, width,
+ height, pScrn->xDpi, pScrn->yDpi,
+ displayWidth, pScrn->bitsPerPixel);
+
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid bpp (%d) in TRIDENTScrnInit\n",
+ pScrn->bitsPerPixel);
+ ret = FALSE;
+ break;
+ }
+ if (!ret) {
+ if (pTrident->pVbe)
+ vbeFree(pTrident->pVbe);
+ else
+ xf86FreeInt10(pTrident->Int10);
+ return FALSE;
+ }
+ if (pScrn->bitsPerPixel > 8) {
+ /* 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;
+ }
+ }
+ } else {
+ if (pScrn->bitsPerPixel == 1) {
+ TRIDENTFix1bpp(pScrn);
+ }
+ }
+
+ /* must be after RGB ordering fixed */
+ if (pScrn->bitsPerPixel > 4)
+ fbPictureInit (pScreen, 0, 0);
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ pTrident->BlockHandler = pScreen->BlockHandler;
+ pScreen->BlockHandler = TRIDENTBlockHandler;
+
+ if (!pTrident->ShadowFB)
+ TRIDENTDGAInit(pScreen);
+
+ if (!pTrident->Linear) {
+ miBankInfoPtr pBankInfo;
+
+ /* Setup the vga banking variables */
+ pBankInfo = xnfcalloc(sizeof(miBankInfoRec),1);
+ if (pBankInfo == NULL) {
+ if (pTrident->pVbe)
+ vbeFree(pTrident->pVbe);
+ else
+ xf86FreeInt10(pTrident->Int10);
+ return FALSE;
+ }
+ pBankInfo->pBankA = pTrident->FbBase;
+ pBankInfo->pBankB = pTrident->FbBase;
+ pBankInfo->BankSize = 0x10000;
+ pBankInfo->nBankDepth = (pScrn->depth == 4) ? 1 : pScrn->depth;
+
+ pBankInfo->SetSourceBank =
+ (miBankProcPtr)TVGA8900SetRead;
+ pBankInfo->SetDestinationBank =
+ (miBankProcPtr)TVGA8900SetWrite;
+ pBankInfo->SetSourceAndDestinationBanks =
+ (miBankProcPtr)TVGA8900SetReadWrite;
+ if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY,
+ pScrn->displayWidth, pBankInfo)) {
+ xfree(pBankInfo);
+ pBankInfo = NULL;
+ if (pTrident->pVbe)
+ vbeFree(pTrident->pVbe);
+ else
+ xf86FreeInt10(pTrident->Int10);
+ return FALSE;
+ }
+ }
+
+ if (Is3Dchip) {
+ if ((pTrident->Chipset == CYBERBLADEI7) ||
+ (pTrident->Chipset == CYBERBLADEI7D) ||
+ (pTrident->Chipset == CYBERBLADEI1) ||
+ (pTrident->Chipset == CYBERBLADEI1D) ||
+ (pTrident->Chipset == CYBERBLADEAI1) ||
+ (pTrident->Chipset == CYBERBLADEAI1D) ||
+ (pTrident->Chipset == CYBERBLADEE4) ||
+ (pTrident->Chipset == BLADE3D))
+ BladeAccelInit(pScreen);
+ else
+ if (pTrident->Chipset >= BLADEXP)
+ XPAccelInit(pScreen);
+ else
+ ImageAccelInit(pScreen);
+ } else {
+ TridentAccelInit(pScreen);
+ }
+
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ /* Initialise cursor functions */
+ miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
+
+ if (pScrn->bitsPerPixel < 8)
+ pTrident->HWCursor = FALSE;
+
+ if (pTrident->HWCursor) {
+ xf86SetSilkenMouse(pScreen);
+ TridentHWCursorInit(pScreen);
+ }
+
+ /* Initialise default colourmap */
+ if (!miCreateDefColormap(pScreen)) {
+ if (pTrident->pVbe)
+ vbeFree(pTrident->pVbe);
+ else
+ xf86FreeInt10(pTrident->Int10);
+ return FALSE;
+ }
+ if(!xf86HandleColormaps(pScreen, 256, 6, TridentLoadPalette,
+ TridentSetOverscan, CMAP_RELOAD_ON_MODE_SWITCH|CMAP_PALETTED_TRUECOLOR)) {
+ if (pTrident->pVbe)
+ vbeFree(pTrident->pVbe);
+ else
+ xf86FreeInt10(pTrident->Int10);
+ return FALSE;
+ }
+ if(pTrident->ShadowFB) {
+ if(pTrident->Rotate) {
+ if (!pTrident->PointerMoved) {
+ pTrident->PointerMoved = pScrn->PointerMoved;
+ pScrn->PointerMoved = TRIDENTPointerMoved;
+ }
+ switch (pScrn->bitsPerPixel) {
+ case 8: pTrident->RefreshArea = TRIDENTRefreshArea8; break;
+ case 16: pTrident->RefreshArea = TRIDENTRefreshArea16; break;
+ case 24: pTrident->RefreshArea = TRIDENTRefreshArea24; break;
+ case 32: pTrident->RefreshArea = TRIDENTRefreshArea32; break;
+ }
+ } else {
+ pTrident->RefreshArea = TRIDENTRefreshArea;
+ }
+ shadowInit (pScreen, TRIDENTShadowUpdate, 0);
+ }
+
+ xf86DPMSInit(pScreen, (DPMSSetProcPtr)TRIDENTDisplayPowerManagementSet, 0);
+
+ pScrn->memPhysBase = pTrident->FbAddress;
+ pScrn->fbOffset = 0;
+
+#ifdef XvExtension
+ if (pTrident->Chipset >= TGUI9660)
+ TRIDENTInitVideo(pScreen);
+#endif
+
+ pTrident->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = TRIDENTCloseScreen;
+ pScreen->SaveScreen = TRIDENTSaveScreen;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+#if 0
+ TRIDENTI2CInit(pScreen);
+
+ xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex,pTrident->DDC));
+#endif
+
+ return TRUE;
+}
+
+/* Usually mandatory */
+Bool
+TRIDENTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ return TRIDENTModeInit(xf86Screens[scrnIndex], mode);
+}
+
+
+/*
+ * This function is used to initialize the Start Address - the first
+ * displayed location in the video memory.
+ */
+/* Usually mandatory */
+void
+TRIDENTAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ TRIDENTPtr pTrident;
+ vgaHWPtr hwp;
+ int base = y * pScrn->displayWidth + x;
+ int vgaIOBase;
+ CARD8 temp;
+
+ hwp = VGAHWPTR(pScrn);
+ pTrident = TRIDENTPTR(pScrn);
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ switch (pScrn->bitsPerPixel) {
+ case 4:
+ base >>= 3;
+ break;
+ case 8:
+ if (pScrn->progClock)
+ base = (base & 0xFFFFFFF8) >> 2;
+ else
+ base = (base & 0xFFFFFFF8) >> 3;
+ break;
+ case 16:
+ base >>= 1;
+ break;
+ case 24:
+ base = (((base + 1) & ~0x03) * 3) >> 2;
+ break;
+ case 32:
+ break;
+ }
+
+ /* CRT bits 0-15 */
+ OUTW(vgaIOBase + 4, (base & 0x00FF00) | 0x0C);
+ OUTW(vgaIOBase + 4, ((base & 0x00FF) << 8) | 0x0D);
+ /* CRT bit 16 */
+ OUTB(vgaIOBase + 4, CRTCModuleTest); temp = INB(vgaIOBase + 5) & 0xDF;
+ OUTB(vgaIOBase + 5, temp | ((base & 0x10000) >> 11));
+ /* CRT bit 17-19 */
+ OUTB(vgaIOBase + 4, CRTHiOrd); temp = INB(vgaIOBase + 5) & 0xF8;
+ OUTB(vgaIOBase + 5, temp | ((base & 0xE0000) >> 17));
+}
+
+
+/*
+ * This is called when VT switching back to the X server. Its job is
+ * to reinitialise the video mode.
+ */
+
+/* Mandatory */
+static Bool
+TRIDENTEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if (IsPciCard && UseMMIO) TRIDENTEnableMMIO(pScrn);
+
+ /* Should we re-save the text mode on each VT enter? */
+ if (!TRIDENTModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+
+ if (pTrident->InitializeAccelerator)
+ pTrident->InitializeAccelerator(pScrn);
+
+ return TRUE;
+}
+
+
+/*
+ * This is called when VT switching away from the X server. Its job is
+ * to restore the previous (text) mode.
+ *
+ * We may wish to remap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static void
+TRIDENTLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ TRIDENTRestore(pScrn);
+ vgaHWLock(hwp);
+
+ if (xf86IsPc98())
+ PC98TRIDENTDisable(pScrn);
+
+ if (IsPciCard && UseMMIO) TRIDENTDisableMMIO(pScrn);
+}
+
+
+/*
+ * This is called at the end of each server generation. It restores the
+ * original (text) mode. It should really also unmap the video memory too.
+ */
+
+/* Mandatory */
+static Bool
+TRIDENTCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if (xf86IsPc98())
+ PC98TRIDENTDisable(pScrn);
+
+ if (pScrn->vtSema) {
+ TRIDENTRestore(pScrn);
+ vgaHWLock(hwp);
+ if (IsPciCard && UseMMIO) TRIDENTDisableMMIO(pScrn);
+ TRIDENTUnmapMem(pScrn);
+ }
+ if (pTrident->AccelInfoRec)
+ XAADestroyInfoRec(pTrident->AccelInfoRec);
+ if (pTrident->CursorInfoRec)
+ xf86DestroyCursorInfoRec(pTrident->CursorInfoRec);
+ if (pTrident->ShadowPtr)
+ xfree(pTrident->ShadowPtr);
+ if (pTrident->DGAModes)
+ xfree(pTrident->DGAModes);
+ pScrn->vtSema = FALSE;
+
+ if(pTrident->BlockHandler)
+ pScreen->BlockHandler = pTrident->BlockHandler;
+
+ if (pTrident->pVbe)
+ vbeFree(pTrident->pVbe);
+ else
+ xf86FreeInt10(pTrident->Int10);
+ pScreen->CloseScreen = pTrident->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+
+/* Free up any per-generation data structures */
+
+/* Optional */
+static void
+TRIDENTFreeScreen(int scrnIndex, int flags)
+{
+ if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+ TRIDENTFreeRec(xf86Screens[scrnIndex]);
+}
+
+
+/* Checks if a mode is suitable for the selected chipset. */
+
+/* Optional */
+static int
+TRIDENTValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if (pTrident->lcdActive && (pTrident->lcdMode != 0xff)){
+ if (((mode->HDisplay > LCD[pTrident->lcdMode].display_x)
+ || (mode->VDisplay > LCD[pTrident->lcdMode].display_y))) {
+ xf86DrvMsg(scrnIndex,X_INFO, "Removing mode (%dx%d) "
+ "larger than the LCD panel (%dx%d)\n",
+ mode->HDisplay,
+ mode->VDisplay,
+ LCD[pTrident->lcdMode].display_x,
+ LCD[pTrident->lcdMode].display_y);
+ return(MODE_BAD);
+ }
+ if (((float)mode->HDisplay/(float)mode->VDisplay) > 2.0) {
+ xf86DrvMsg(scrnIndex,X_INFO, "Removing mode (%dx%d) "
+ "unusual aspect ratio\n",
+ mode->HDisplay,
+ mode->VDisplay);
+ return(MODE_BAD);
+ }
+ }
+ return (MODE_OK);
+}
+
+/* Do screen blanking */
+
+/* Mandatory */
+static Bool
+TRIDENTSaveScreen(ScreenPtr pScreen, int mode)
+{
+ return vgaHWSaveScreen(pScreen, mode);
+}
+
+static void
+TRIDENTEnableMMIO(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ IOADDRESS vgaIOBase = pTrident->PIOBase + VGAHWPTR(pScrn)->IOBase;
+ CARD8 temp = 0, protect = 0;
+
+ /*
+ * Skip MMIO Enable in PC-9821 PCI Trident Card!!
+ * Because of lack of non PCI VGA port
+ */
+ if (IsPciCard && xf86IsPc98())
+ return;
+
+ /* Goto New Mode */
+ outb(pTrident->PIOBase + 0x3C4, 0x0B);
+ inb(pTrident->PIOBase + 0x3C5);
+
+ /* Unprotect registers */
+ if (pTrident->Chipset > PROVIDIA9685) {
+ outb(pTrident->PIOBase + 0x3C4, Protection);
+ protect = inb(pTrident->PIOBase + 0x3C5);
+ outb(pTrident->PIOBase + 0x3C5, 0x92);
+ }
+ outb(pTrident->PIOBase + 0x3C4, NewMode1);
+ temp = inb(pTrident->PIOBase + 0x3C5);
+ outb(pTrident->PIOBase + 0x3C5, 0x80);
+
+ /* Enable MMIO */
+ outb(vgaIOBase + 4, PCIReg);
+ pTrident->REGPCIReg = inb(vgaIOBase + 5);
+ outb(vgaIOBase + 5, pTrident->REGPCIReg | 0x01); /* Enable it */
+
+ /* Protect registers */
+ if (pTrident->Chipset > PROVIDIA9685) {
+ OUTB(0x3C4, Protection);
+ OUTB(0x3C5, protect);
+ }
+ OUTB(0x3C4, NewMode1);
+ OUTB(0x3C5, temp);
+}
+
+static void
+TRIDENTDisableMMIO(ScrnInfoPtr pScrn)
+{
+ int vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+ CARD8 temp = 0, protect = 0;
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ /*
+ * Skip MMIO Disable in PC-9821 PCI Trident Card!!
+ * Because of lack of non PCI VGA port
+ */
+ if (IsPciCard && xf86IsPc98())
+ return;
+
+ /* Goto New Mode */
+ OUTB(0x3C4, 0x0B); temp = INB(0x3C5);
+
+ /* Unprotect registers */
+ OUTB(0x3C4, NewMode1); temp = INB(0x3C5);
+ OUTB(0x3C5, 0x80);
+ if (pTrident->Chipset > PROVIDIA9685) {
+ OUTB(0x3C4, Protection);
+ protect = INB(0x3C5);
+ OUTB(0x3C5, 0x92);
+ }
+
+ /* Disable MMIO access */
+ OUTB(vgaIOBase + 4, PCIReg);
+ pTrident->REGPCIReg = INB(vgaIOBase + 5);
+ OUTB(vgaIOBase + 5, pTrident->REGPCIReg & 0xFE);
+
+ /* Protect registers */
+ if (pTrident->Chipset > PROVIDIA9685) {
+ outb(pTrident->PIOBase + 0x3C4, Protection);
+ outb(pTrident->PIOBase + 0x3C5, protect);
+ }
+ outb(pTrident->PIOBase + 0x3C4, NewMode1);
+ outb(pTrident->PIOBase + 0x3C5, temp);
+}
+
+/* Initialize VGA Block for Trident Chip on PC-98x1 */
+static void
+PC98TRIDENTInit(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ switch (pTrident->Chipset) {
+ case TGUI9660:
+ case TGUI9680:
+ case PROVIDIA9682:
+ PC98TRIDENT96xxInit(pScrn);
+ break;
+ case CYBER9320:
+ case CYBER9385:
+ PC98TRIDENT9385Init(pScrn);
+ break;
+ default: /* Run 96xx code as default */
+ PC98TRIDENT96xxInit(pScrn);
+ break;
+ }
+}
+
+static void
+PC98TRIDENTEnable(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ switch (pTrident->Chipset) {
+ case TGUI9660:
+ case TGUI9680:
+ case PROVIDIA9682:
+ PC98TRIDENT96xxEnable(pScrn);
+ break;
+ case CYBER9320:
+ case CYBER9385:
+ PC98TRIDENT9385Enable(pScrn);
+ break;
+ default: /* Run 96xx code as default */
+ PC98TRIDENT96xxEnable(pScrn);
+ break;
+ }
+}
+
+static void
+PC98TRIDENTDisable(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ switch (pTrident->Chipset) {
+ case TGUI9660:
+ case TGUI9680:
+ case PROVIDIA9682:
+ PC98TRIDENT96xxDisable(pScrn);
+ break;
+ case CYBER9320:
+ case CYBER9385:
+ PC98TRIDENT9385Disable(pScrn);
+ break;
+ default: /* Run 96xx code as default */
+ PC98TRIDENT96xxDisable(pScrn);
+ break;
+ }
+}
+
+/* Initialize VGA Block for Cyber9385 on PC-98x1 */
+static void
+PC98TRIDENT9385Init(ScrnInfoPtr pScrn)
+{
+/* Nothing to initialize */
+}
+
+static void
+PC98TRIDENT9385Enable(ScrnInfoPtr pScrn)
+{
+ outb(0xFAC, 0x02);
+}
+
+static void
+PC98TRIDENT9385Disable(ScrnInfoPtr pScrn)
+{
+ outb(0xFAC, 0x00);
+}
+
+/* Initialize VGA Block for Trident96xx on PC-98x1 */
+static void
+PC98TRIDENT96xxInit(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CARD8 temp = 0;
+
+ vgaHWProtect(pScrn, TRUE);
+
+ /* Video SusSystem Enable */
+ temp = INB(0x3CC);
+ OUTB(0x3C2, temp | 0xC3);
+ /* Switch Old */
+ OUTB(0x3C4, 0x0B); temp = INB(0x3C5);
+ OUTW(0x3C4, 0x0B | (temp << 8));
+ /* Select Configuration Port 1 */
+ OUTB(0x3C4, 0x0E); temp = INB(0x3C5);
+ OUTW(0x3C4, 0x0E | ((temp | 0x20) << 8));
+
+ OUTB(0x3C4, 0x0c);
+ if((INB(0x3C5) & 0x10) == 0x10)
+ {
+ OUTB(0x3C4, 0x0E | (temp << 8));
+ OUTB(0x94, 0x00);
+ OUTB(0x102, 0x01);
+ OUTB(0x94, 0x20);
+ temp = INB(0x3C3);
+ OUTB(0x3C3, temp | 0x01);
+ } else {
+ OUTB(0x3C4, 0x0E | (temp << 8));
+ OUTB(0x46E8, 0x10);
+ OUTB(0x102, 0x01);
+ OUTB(0x46E8, 0x08);
+ }
+
+ INB(0x3DA);
+ OUTB(0x3C0,0x10);
+ OUTB(0x3C0,0x41);
+
+ /* Register Unlock */
+ vgaHWUnlock(hwp);
+ OUTB(0x3C4, 0x0B); temp = INB(0x3C5); /* Switch New */
+ OUTB(0x3C4, 0x0E); temp = INB(0x3C5);
+ OUTW(0x3C4, 0x0E | ((temp | 0x80) << 8));
+
+ /* For Speed Up [Facoor 2 at Xengine] */
+ OUTW(0x3D4, 0x3820); /* Command FIFO Register */
+ OUTW(0x3D4, 0x2020); /* Command FIFO Register */
+ /* Latency Control Registers 0x30 - 0x32 */
+ /* Parameter Range 0x00 - 0x0F */
+ /* Tune these parameter to avoid GE Timeout */
+ OUTW(0x3D4, 0x0E30); /* Display Queue Latency Control */
+ /* 8bpp GE No Timeout Parameter 0x0D - 0x0F for PC-9821Xa7 TGUi9680 */
+ OUTW(0x3D4, 0x0031); /* Frame Buffer Latency Control */
+ OUTW(0x3D4, 0x0032); /* Display & Frame Buffer Latency Control */
+ OUTW(0x3D4, 0x213B); /* Clock and Tuning */
+
+ /* MCLK Init */
+ OUTB(0x43C6, 0xAF); OUTB(0x43C7, 0x00); /* 80.0MHz */
+#if 0
+ /* Sample MCLKs */
+ OUTB(0x43C6, 0xAF); OUTB(0x43C7, 0x00); /* 80.0MHz */
+ OUTB(0x43C6, 0xA7); OUTB(0x43C7, 0x00); /* 77.0MHz */
+ OUTB(0x43C6, 0x8E); OUTB(0x43C7, 0x00); /* 75.0MHz */
+ OUTB(0x43C6, 0x86); OUTB(0x43C7, 0x00); /* 72.0MHz */
+ OUTB(0x43C6, 0x8F); OUTB(0x43C7, 0x00); /* 67.2MHz */
+ OUTB(0x43C6, 0xD5); OUTB(0x43C7, 0x02); /* 61.6MHz */
+#endif
+
+ /* Register Lock */
+ OUTB(0x3C4, 0x0B); temp = INB(0x3C5); /* Switch New */
+ OUTB(0x3C4, 0x0E); temp = INB(0x3C5);
+ OUTW(0x3C4, 0x0E | ((temp & 0x7F) << 8));
+ vgaHWLock(hwp);
+
+ vgaHWProtect(pScrn, FALSE);
+}
+
+static void
+PC98TRIDENT96xxEnable(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ CARD8 temp = 0;
+
+ outb(0x68, 0x0E);
+ outb(0x6A, 0x07);
+ outb(0x6A, 0x8F);
+ outb(0x6A, 0x06);
+
+ vgaHWProtect(pScrn, TRUE);
+
+ OUTB(0x3D4, 0x23); temp = INB(0x3D5);
+ OUTW(0x3D4, 0x23 | ((temp & 0xDF) << 8));
+
+ OUTB(0x3D4, 0x29); temp = INB(0x3D5);
+ OUTW(0x3D4, 0x29 | ((temp | 0x04) << 8));
+
+ OUTB(0x83C8, 0x04); temp = INB(0x83c6);
+ OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp | 0x06));
+
+ OUTB(0x83C8, 0x04); temp = INB(0x83c6);
+ OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp | 0x08));
+
+ OUTB(0x3CE, 0x23); temp = INB(0x3CF);
+ OUTW(0x3CE, 0x23 | ((temp & 0xFC) << 8));
+
+ OUTB(0x83C8, 0x04); temp = INB(0x83c6);
+ OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp | 0x01));
+
+ OUTB(0x3C4, 0x01); temp = INB(0x3C5);
+ OUTW(0x3C4, 0x01 | ((temp & 0xEF) << 8));
+
+ vgaHWProtect(pScrn, FALSE);
+
+ outb(0xFAC, 0x02);
+}
+
+static void
+PC98TRIDENT96xxDisable(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ CARD8 temp = 0;
+
+ outb(0xFAC, 0x00);
+
+ vgaHWProtect(pScrn, TRUE);
+
+ OUTB(0x3C4, 0x01); temp = INB(0x3C5);
+ OUTW(0x3C4, 0x01 | ((temp | 0x10) << 8));
+
+ OUTB(0x83C8, 0x04); temp = INB(0x83c6);
+ OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xFE));
+
+ OUTB(0x3CE, 0x23); temp = INB(0x3CF);
+ OUTW(0x3CE, 0x23 | (((temp & 0xFC) | 0x01) << 8));
+
+ OUTB(0x83C8, 0x04); temp = INB(0x83c6);
+ OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xFD));
+
+ OUTB(0x83C8, 0x04); temp = INB(0x83c6);
+ OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xCF));
+
+ OUTB(0x83C8, 0x04); temp = INB(0x83c6);
+ OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xF7));
+
+ OUTB(0x83C8, 0x04); temp = INB(0x83c6);
+ OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xFB));
+
+ OUTB(0x3D4, 0x29); temp = INB(0x3D5);
+ OUTW(0x3D4, 0x29 | ((temp & 0xFB) << 8));
+
+ OUTB(0x3D4, 0x23); temp = INB(0x3D5);
+ OUTW(0x3D4, 0x23 | ((temp | 0x20) << 8));
+
+ vgaHWProtect(pScrn, FALSE);
+
+ outb(0x6A, 0x07);
+ outb(0x6A, 0x8E);
+ outb(0x6A, 0x06);
+ outb(0x68, 0x0F);
+}
+
+
+/*
+ * This is a terrible hack! If we are on a notebook in a stretched
+ * mode and don't want full screen we use the BIOS to set an unstreched
+ * mode.
+ */
+void
+tridentSetModeBIOS(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+
+#ifdef VBE_INFO
+ if (pTrident->vbeModes) {
+ vbeSaveRestoreRec vbesr;
+ vbesr.stateMode = VBECalcVbeModeIndex(pTrident->vbeModes,
+ mode, pScrn->bitsPerPixel);
+ vbesr.pstate = NULL;
+ if (vbesr.stateMode) {
+ if (IsPciCard && UseMMIO)
+ TRIDENTDisableMMIO(pScrn);
+ VBEVesaSaveRestore(pTrident->pVbe,&vbesr,MODE_RESTORE);
+ if (IsPciCard && UseMMIO)
+ TRIDENTEnableMMIO(pScrn);
+ return;
+ } else
+ xf86DrvMsg(pScrn->scrnIndex,X_WARNING,"No BIOS Mode matches "
+ "%ix%I@%ibpp\n",mode->HDisplay,mode->VDisplay,
+ pScrn->bitsPerPixel);
+ }
+#endif
+ /* This function is only for LCD screens, and also when we have
+ * int10 available */
+
+ if (pTrident->IsCyber && pTrident->lcdMode && pTrident->Int10) {
+ int i = pTrident->lcdMode;
+ if ((pScrn->currentMode->HDisplay != LCD[i].display_x) /* !fullsize? */
+ || (pScrn->currentMode->VDisplay != LCD[i].display_y)) {
+ if (pTrident->lcdActive) { /* LCD Active ?*/
+ int h_str, v_str;
+
+ OUTB(0x3CE,HorStretch); h_str = INB(0x3CF) & 0x01;
+ OUTB(0x3CE,VertStretch); v_str = INB(0x3CF) & 0x01;
+ if (h_str || v_str) {
+ OUTB(0x3C4, 0x11); OUTB(0x3C5, 0x92);
+ OUTW(0x3CE, BiosReg );
+ pTrident->Int10->ax = 0x3;
+ pTrident->Int10->num = 0x10;
+ if (IsPciCard && UseMMIO)
+ TRIDENTDisableMMIO(pScrn);
+ xf86ExecX86int10(pTrident->Int10);
+ if (IsPciCard && UseMMIO)
+ TRIDENTEnableMMIO(pScrn);
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/trident_i2c.c b/src/trident_i2c.c
new file mode 100644
index 0000000..1fd23ad
--- /dev/null
+++ b/src/trident_i2c.c
@@ -0,0 +1,77 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_i2c.c,v 1.5 1999/10/13 20:02:30 alanh Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+
+#include "vgaHW.h"
+
+#include "trident.h"
+#include "trident_regs.h"
+
+static void
+TRIDENTI2CPutBits(I2CBusPtr b, int clock, int data) {
+ unsigned int reg = 0x0C;
+ TRIDENTPtr pTrident = ((TRIDENTPtr)b->DriverPrivate.ptr);
+ int vgaIOBase = VGAHWPTR(pTrident->pScrn)->IOBase;
+
+#if 0
+ if(!TRIDENTI2CSwitchToBus(b))
+ return FALSE;
+#endif
+
+ if(clock) reg |= 2;
+ if(data) reg |= 1;
+ OUTB(vgaIOBase + 4, I2C);
+ OUTB(vgaIOBase + 5, reg);
+#if 0
+ ErrorF("TRIDENTI2CPutBits: %d %d\n", clock, data);
+#endif
+}
+
+static void
+TRIDENTI2CGetBits(I2CBusPtr b, int *clock, int *data) {
+ unsigned int reg;
+ TRIDENTPtr pTrident = ((TRIDENTPtr)b->DriverPrivate.ptr);
+ int vgaIOBase = VGAHWPTR(pTrident->pScrn)->IOBase;
+
+#if 0
+ if(!TRIDENTI2CSwitchToBus(b))
+ return FALSE;
+#endif
+
+ OUTB(vgaIOBase + 4, I2C);
+ reg = INB(vgaIOBase + 5);
+ *clock = (reg & 0x02) != 0;
+ *data = (reg & 0x01) != 0;
+#if 0
+ ErrorF("TRIDENTI2CGetBits: %d %d\n", *clock, *data);
+#endif
+}
+
+Bool
+TRIDENTI2CInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ I2CBusPtr I2CPtr;
+
+ I2CPtr = xf86CreateI2CBusRec();
+
+ pTrident->DDC = I2CPtr;
+
+ I2CPtr->BusName = "DDC";
+ I2CPtr->scrnIndex = pScrn->scrnIndex;
+ I2CPtr->I2CPutBits = TRIDENTI2CPutBits;
+ I2CPtr->I2CGetBits = TRIDENTI2CGetBits;
+ I2CPtr->DriverPrivate.ptr = pTrident;
+
+ if(!xf86I2CBusInit(I2CPtr))
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/src/trident_regs.h b/src/trident_regs.h
new file mode 100644
index 0000000..3cce902
--- /dev/null
+++ b/src/trident_regs.h
@@ -0,0 +1,395 @@
+/*
+ * Copyright 1992-2000 by Alan Hourihane, Wigan, England.
+ *
+ * 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, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Alan Hourihane, alanh@fairlite.demon.co.uk
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_regs.h,v 1.26 2002/09/16 18:06:03 eich Exp $ */
+
+#define DEBUG 1
+
+#define NTSC 14.31818
+#define PAL 17.73448
+
+/* General Registers */
+#define SPR 0x1F /* Software Programming Register (videoram) */
+
+/* 3C4 */
+#define RevisionID 0x09
+#define ConfPort1 0x0C
+#define ConfPort2 0x0C
+#define NewMode2 0x0D
+#define OldMode2 0x00 /* Should be 0x0D - dealt with in trident_dac.c */
+#define OldMode1 0x0E
+#define NewMode1 0x0E
+#define Protection 0x11
+#define Threshold 0x12
+#define MCLKLow 0x16
+#define MCLKHigh 0x17
+#define ClockLow 0x18
+#define ClockHigh 0x19
+#define SSetup 0x20
+#define SKey 0x37
+#define SPKey 0x57
+#define GBslope1 0xB4
+#define GBslope2 0xB5
+#define GBslope3 0xB6
+#define GBslope4 0xB7
+#define GBintercept1 0xB8
+#define GBintercept2 0xB9
+#define GBintercept3 0xBA
+#define GBintercept4 0xBB
+
+/* 3x4 */
+#define Offset 0x13
+#define Underline 0x14
+#define CRTCMode 0x17
+#define CRTCModuleTest 0x1E
+#define FIFOControl 0x20
+#define LinearAddReg 0x21
+#define DRAMTiming 0x23
+#define New32 0x23
+#define RAMDACTiming 0x25
+#define CRTHiOrd 0x27
+#define AddColReg 0x29
+#define InterfaceSel 0x2A
+#define HorizOverflow 0x2B
+#define GETest 0x2D
+#define Performance 0x2F
+#define GraphEngReg 0x36
+#define I2C 0x37
+#define PixelBusReg 0x38
+#define PCIReg 0x39
+#define DRAMControl 0x3A
+#define MiscContReg 0x3C
+#define CursorXLow 0x40
+#define CursorXHigh 0x41
+#define CursorYLow 0x42
+#define CursorYHigh 0x43
+#define CursorLocLow 0x44
+#define CursorLocHigh 0x45
+#define CursorXOffset 0x46
+#define CursorYOffset 0x47
+#define CursorFG1 0x48
+#define CursorFG2 0x49
+#define CursorFG3 0x4A
+#define CursorFG4 0x4B
+#define CursorBG1 0x4C
+#define CursorBG2 0x4D
+#define CursorBG3 0x4E
+#define CursorBG4 0x4F
+#define CursorControl 0x50
+#define PCIRetry 0x55
+#define PreEndControl 0x56
+#define PreEndFetch 0x57
+#define PCIMaster 0x60
+#define Enhancement0 0x62
+#define NewEDO 0x64
+#define TVinterface 0xC0
+#define TVMode 0xC1
+#define ClockControl 0xCF
+
+
+/* 3CE */
+#define MiscExtFunc 0x0F
+#define MiscIntContReg 0x2F
+#define CyberControl 0x30
+#define CyberEnhance 0x31
+#define FPConfig 0x33
+#define VertStretch 0x52
+#define HorStretch 0x53
+#define BiosMode 0x5c
+#define BiosNewMode1 0x5a
+#define BiosNewMode2 0x5c
+#define BiosReg 0x5d
+
+/* Graphics Engine for 9420/9430 */
+
+#define GER_INDEX 0x210A
+#define GER_BYTE0 0x210C
+#define GER_BYTE1 0x210D
+#define GER_BYTE2 0x210E
+#define GER_BYTE3 0x210F
+#define MMIOBASE 0x7C
+#define OLDGER_STATUS 0x90
+#define OLDGER_MWIDTH 0xB8
+#define OLDGER_MFORMAT 0xBC
+#define OLDGER_STYLE 0xC4
+#define OLDGER_FMIX 0xC8
+#define OLDGER_BMIX 0xC8
+#define OLDGER_FCOLOUR 0xD8
+#define OLDGER_BCOLOUR 0xDC
+#define OLDGER_DIMXY 0xE0
+#define OLDGER_DESTLINEAR 0xE4
+#define OLDGER_DESTXY 0xF8
+#define OLDGER_COMMAND 0xFC
+#define OLDGE_FILL 0x000A0000 /* Area Fill */
+
+/* Graphics Engine for 9440/9660/9680 */
+
+#define GER_STATUS 0x2120
+#define GE_BUSY 0x80
+#define GER_OPERMODE 0x2122 /* Byte for 9440, Word for 96xx */
+#define DST_ENABLE 0x200 /* Destination Transparency */
+#define GER_COMMAND 0x2124
+#define GE_NOP 0x00 /* No Operation */
+#define GE_BLT 0x01 /* BitBLT ROP3 only */
+#define GE_BLT_ROP4 0x02 /* BitBLT ROP4 (96xx only) */
+#define GE_SCANLINE 0x03 /* Scan Line */
+#define GE_BRESLINE 0x04 /* Bresenham Line */
+#define GE_SHVECTOR 0x05 /* Short Vector */
+#define GE_FASTLINE 0x06 /* Fast Line (96xx only) */
+#define GE_TRAPEZ 0x07 /* Trapezoidal fill (96xx only) */
+#define GE_ELLIPSE 0x08 /* Ellipse (96xx only) (RES) */
+#define GE_ELLIP_FILL 0x09 /* Ellipse Fill (96xx only) (RES)*/
+#define GER_FMIX 0x2127
+#define GER_DRAWFLAG 0x2128 /* long */
+#define FASTMODE 1<<28
+#define STENCIL 0x8000
+#define SOLIDFILL 0x4000
+#define TRANS_ENABLE 0x1000
+#define TRANS_REVERSE 0x2000
+#define YMAJ 0x0400
+#define XNEG 0x0200
+#define YNEG 0x0100
+#define SRCMONO 0x0040
+#define PATMONO 0x0020
+#define SCR2SCR 0x0004
+#define PAT2SCR 0x0002
+#define GER_FCOLOUR 0x212C /* Word for 9440, long for 96xx */
+#define GER_BCOLOUR 0x2130 /* Word for 9440, long for 96xx */
+#define GER_PATLOC 0x2134 /* Word */
+#define GER_DEST_XY 0x2138
+#define GER_DEST_X 0x2138 /* Word */
+#define GER_DEST_Y 0x213A /* Word */
+#define GER_SRC_XY 0x213C
+#define GER_SRC_X 0x213C /* Word */
+#define GER_SRC_Y 0x213E /* Word */
+#define GER_DIM_XY 0x2140
+#define GER_DIM_X 0x2140 /* Word */
+#define GER_DIM_Y 0x2142 /* Word */
+#define GER_STYLE 0x2144 /* Long */
+#define GER_CKEY 0x2168 /* Long */
+#define GER_FPATCOL 0x2178
+#define GER_BPATCOL 0x217C
+#define GER_PATTERN 0x2180 /* from 0x2180 to 0x21FF */
+
+/* Additional - Graphics Engine for 96xx */
+#define GER_SRCCLIP_XY 0x2148
+#define GER_SRCCLIP_X 0x2148 /* Word */
+#define GER_SRCCLIP_Y 0x214A /* Word */
+#define GER_DSTCLIP_XY 0x214C
+#define GER_DSTCLIP_X 0x214C /* Word */
+#define GER_DSTCLIP_Y 0x214E /* Word */
+
+/* Defines for IMAGE Graphics Engine */
+#define IMAGE_GE_STATUS 0x2164
+#define IMAGE_GE_DRAWENV 0x2120
+
+/* Defines for BLADE Graphics Engine */
+#define BLADE_GE_STATUS 0x2120
+#define BLADE_XP_GER_OPERMODE 0x2125
+
+#define REPLICATE(r) \
+{ \
+ if (pScrn->bitsPerPixel == 16) { \
+ r = ((r & 0xFFFF) << 16) | (r & 0xFFFF); \
+ } else \
+ if (pScrn->bitsPerPixel == 8) { \
+ r &= 0xFF; \
+ r |= (r<<8); \
+ r |= (r<<16); \
+ } \
+}
+
+#define CHECKCLIPPING \
+ if (pTrident->Clipping) { \
+ pTrident->Clipping = FALSE; \
+ if (pTrident->Chipset < PROVIDIA9682) { \
+ TGUI_SRCCLIP_XY(0,0); \
+ TGUI_DSTCLIP_XY(4095,2047); \
+ } \
+ }
+
+
+/* Merge XY */
+#define XY_MERGE(x,y) \
+ ((((CARD32)(y)&0xFFFF) << 16) | ((CARD32)(x) & 0xffff))
+#define XP_XY_MERGE(y,x) \
+ ((((CARD32)(y)&0xFFFF) << 16) | ((CARD32)(x) & 0xffff))
+
+#define TRIDENT_WRITE_REG(v,r) \
+ MMIO_OUT32(pTrident->IOBase,(r),(v))
+
+#define TRIDENT_READ_REG(r) \
+ MMIO_IN32(pTrident->IOBase,(r))
+
+#define OUTB(addr, data) \
+{ \
+ if (IsPciCard && UseMMIO) { \
+ MMIO_OUT8(pTrident->IOBase, addr, data); \
+ } else { \
+ outb(pTrident->PIOBase + (addr), data); \
+ } \
+}
+#define OUTW(addr, data) \
+{ \
+ if (IsPciCard && UseMMIO) { \
+ MMIO_OUT16(pTrident->IOBase, addr, data); \
+ } else { \
+ outw(pTrident->PIOBase + (addr), data); \
+ } \
+}
+#define INB(addr) \
+( \
+ (IsPciCard && UseMMIO) ? \
+ MMIO_IN8(pTrident->IOBase, addr) : \
+ inb(pTrident->PIOBase + (addr)) \
+)
+
+#define OUTW_3C4(reg) \
+ OUTW(0x3C4, (tridentReg->tridentRegs3C4[reg])<<8 | (reg))
+#define OUTW_3CE(reg) \
+ OUTW(0x3CE, (tridentReg->tridentRegs3CE[reg])<<8 | (reg))
+#define OUTW_3x4(reg) \
+ OUTW(vgaIOBase + 4, (tridentReg->tridentRegs3x4[reg])<<8 | (reg))
+#define INB_3x4(reg) \
+ OUTB(vgaIOBase + 4, reg); \
+ tridentReg->tridentRegs3x4[reg] = INB(vgaIOBase + 5)
+#define INB_3C4(reg) \
+ OUTB(0x3C4, reg); \
+ tridentReg->tridentRegs3C4[reg] = INB(0x3C5);
+#define INB_3CE(reg) \
+ OUTB(0x3CE, reg); \
+ tridentReg->tridentRegs3CE[reg] = INB(0x3CF);
+
+#define VIDEOOUT(val,reg) \
+ if (pTrident->Chipset >= CYBER9397) { \
+ OUTW(0x3C4, (val << 8) | reg); \
+ } else { \
+ OUTB(0x83C8, reg); \
+ OUTB(0x83C6, val); \
+ }
+
+
+#define BLTBUSY(b) \
+ (b = MMIO_IN8(pTrident->IOBase,GER_STATUS) & GE_BUSY)
+#define OLDBLTBUSY(b) \
+ (b = MMIO_IN8(pTrident->IOBase,OLDGER_STATUS) & GE_BUSY)
+#define IMAGE_STATUS(c) \
+ MMIO_OUT32(pTrident->IOBase, IMAGE_GE_STATUS, (c))
+#define TGUI_STATUS(c) \
+ MMIO_OUT8(pTrident->IOBase, GER_STATUS, (c))
+#define OLDTGUI_STATUS(c) \
+ MMIO_OUT8(pTrident->IOBase, OLDGER_STATUS, (c))
+#define TGUI_OPERMODE(c) \
+ MMIO_OUT16(pTrident->IOBase, GER_OPERMODE, (c))
+#define BLADE_XP_OPERMODE(c) \
+ MMIO_OUT8(pTrident->IOBase, BLADE_XP_GER_OPERMODE, (c))
+/* XXX */
+#define OLDTGUI_OPERMODE(c) \
+ { \
+ MMIO_OUT16(pTrident->IOBase, OLDGER_MWIDTH, \
+ vga256InfoRec.displayWidth - 1); \
+ MMIO_OUT8(pTrident->IOBase, OLDGER_MFORMAT, (c)); \
+ }
+#define TGUI_FCOLOUR(c) \
+ MMIO_OUT32(pTrident->IOBase, GER_FCOLOUR, (c))
+#define TGUI_FPATCOL(c) \
+ MMIO_OUT32(pTrident->IOBase, GER_FPATCOL, (c))
+#define OLDTGUI_FCOLOUR(c) \
+ MMIO_OUT32(pTrident->IOBase, OLDGER_FCOLOUR, (c))
+#define TGUI_BCOLOUR(c) \
+ MMIO_OUT32(pTrident->IOBase, GER_BCOLOUR, (c))
+#define TGUI_BPATCOL(c) \
+ MMIO_OUT32(pTrident->IOBase, GER_BPATCOL, (c))
+#define OLDTGUI_BCOLOUR(c) \
+ MMIO_OUT32(pTrident->IOBase, OLDGER_BCOLOUR, (c))
+#define IMAGE_DRAWENV(c) \
+ MMIO_OUT32(pTrident->IOBase, IMAGE_GE_DRAWENV, (c))
+#define TGUI_DRAWFLAG(c) \
+ MMIO_OUT32(pTrident->IOBase, GER_DRAWFLAG, (c))
+#define OLDTGUI_STYLE(c) \
+ MMIO_OUT16(pTrident->IOBase, OLDGER_STYLE, (c))
+#define TGUI_FMIX(c) \
+ MMIO_OUT8(pTrident->IOBase, GER_FMIX, (c))
+#define OLDTGUI_FMIX(c) \
+ MMIO_OUT8(pTrident->IOBase, OLDGER_FMIX, (c))
+#define OLDTGUI_BMIX(c) \
+ MMIO_OUT8(pTrident->IOBase, OLDGER_BMIX, (c))
+#define TGUI_DIM_XY(w,h) \
+ MMIO_OUT32(pTrident->IOBase, GER_DIM_XY, XY_MERGE((w)-1,(h)-1))
+#define XP_DIM_XY(w,h) \
+ MMIO_OUT32(pTrident->IOBase, GER_DIM_XY, XY_MERGE((h),(w)))
+#define TGUI_STYLE(c) \
+ MMIO_OUT32(pTrident->IOBase, GER_STYLE, (c))
+#define OLDTGUI_DIMXY(w,h) \
+ MMIO_OUT32(pTrident->IOBase, OLDGER_DIMXY, XY_MERGE((w)-1,(h)-1))
+#define TGUI_SRC_XY(x,y) \
+ MMIO_OUT32(pTrident->IOBase, GER_SRC_XY, XY_MERGE(x,y))
+#define XP_SRC_XY(x,y) \
+ MMIO_OUT32(pTrident->IOBase, GER_SRC_XY, XP_XY_MERGE(x,y))
+#define TGUI_DEST_XY(x,y) \
+ MMIO_OUT32(pTrident->IOBase, GER_DEST_XY, XY_MERGE(x,y))
+#define XP_DEST_XY(x,y) \
+ MMIO_OUT32(pTrident->IOBase, GER_DEST_XY, XP_XY_MERGE(x,y))
+#define OLDTGUI_DESTXY(x,y) \
+ MMIO_OUT32(pTrident->IOBase, OLDGER_DESTXY, XY_MERGE(x,y))
+#define OLDTGUI_DESTLINEAR(c) \
+ MMIO_OUT32(pTrident->IOBase, OLDGER_DESTLINEAR, (c))
+#define TGUI_SRCCLIP_XY(x,y) \
+ MMIO_OUT32(pTrident->IOBase, GER_SRCCLIP_XY, XY_MERGE(x,y))
+#define TGUI_DSTCLIP_XY(x,y) \
+ MMIO_OUT32(pTrident->IOBase, GER_DSTCLIP_XY, XY_MERGE(x,y))
+#define TGUI_PATLOC(addr) \
+ MMIO_OUT16(pTrident->IOBase, GER_PATLOC, (addr))
+#define TGUI_CKEY(c) \
+ MMIO_OUT32(pTrident->IOBase, GER_CKEY, (c))
+#define IMAGEBUSY(b) \
+ (b = MMIO_IN32(pTrident->IOBase,IMAGE_GE_STATUS) & 0xF0000000)
+#define BLADEBUSY(b) \
+ (b = MMIO_IN32(pTrident->IOBase,BLADE_GE_STATUS) & 0xFA800000)
+#define IMAGE_OUT(addr, c) \
+ MMIO_OUT32(pTrident->IOBase, addr, (c))
+#define BLADE_OUT(addr, c) \
+ MMIO_OUT32(pTrident->IOBase, addr, (c))
+#define TGUI_OUTL(addr, c) \
+ MMIO_OUT32(pTrident->IOBase, addr, (c))
+#define TGUI_COMMAND(c) \
+ MMIO_OUT8(pTrident->IOBase, GER_COMMAND, (c))
+#define OLDTGUI_COMMAND(c) \
+ do { \
+ OLDTGUI_OPERMODE(GE_OP); \
+ OLDTGUISync(); \
+ MMIO_OUT32(pTrident->IOBase, OLDGER_COMMAND, (c)); \
+ } while (0)
+
+/* Cyber FP support */
+#define SHADOW_ENABLE(oldval) \
+ do {\
+ OUTB(0x3CE, CyberControl); \
+ oldval = INB(0x3CF);\
+ OUTB(0x3CF,oldval | (1 << 6));\
+ } while (0)
+#define SHADOW_RESTORE(val) \
+ do {\
+ OUTB(0x3CE, CyberControl); \
+ OUTB(0x3CF,val); \
+ } while (0);
diff --git a/src/trident_shadow.c b/src/trident_shadow.c
new file mode 100644
index 0000000..75b24d3
--- /dev/null
+++ b/src/trident_shadow.c
@@ -0,0 +1,260 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_shadow.c,v 1.3 2001/06/14 02:23:50 keithp Exp $ */
+
+/*
+ Copyright (c) 1999, 2000 The XFree86 Project Inc.
+ based on code written by Mark Vojkovich <markv@valinux.com>
+*/
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86_ansic.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "shadowfb.h"
+#include "servermd.h"
+#include "trident.h"
+
+void
+TRIDENTRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int width, height, Bpp, FBPitch;
+ unsigned char *src, *dst;
+
+ Bpp = pScrn->bitsPerPixel >> 3;
+ FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
+
+ while(num--) {
+ width = (pbox->x2 - pbox->x1) * Bpp;
+ height = pbox->y2 - pbox->y1;
+ src = pTrident->ShadowPtr + (pbox->y1 * pTrident->ShadowPitch) +
+ (pbox->x1 * Bpp);
+ dst = pTrident->FbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
+
+ while(height--) {
+ memcpy(dst, src, width);
+ dst += FBPitch;
+ src += pTrident->ShadowPitch;
+ }
+
+ pbox++;
+ }
+}
+
+void
+TRIDENTShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
+{
+ RegionPtr damage = &pBuf->damage;
+ ScrnInfoPtr pScrn;
+ pScrn = xf86Screens[pScreen->myNum];
+
+ (TRIDENTPTR(pScrn))->RefreshArea (pScrn, REGION_NUM_RECTS(damage),
+ REGION_RECTS(damage));
+}
+
+void
+TRIDENTPointerMoved(int index, int x, int y)
+{
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int newX, newY;
+
+ if(pTrident->Rotate == 1) {
+ newX = pScrn->pScreen->height - y - 1;
+ newY = x;
+ } else {
+ newX = y;
+ newY = pScrn->pScreen->width - x - 1;
+ }
+
+ (*pTrident->PointerMoved)(index, newX, newY);
+}
+
+void
+TRIDENTRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int count, width, height, y1, y2, dstPitch, srcPitch;
+ CARD8 *dstPtr, *srcPtr, *src;
+ CARD32 *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -pTrident->Rotate * pTrident->ShadowPitch;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ y1 = pbox->y1 & ~3;
+ y2 = (pbox->y2 + 3) & ~3;
+ height = (y2 - y1) >> 2; /* in dwords */
+
+ if(pTrident->Rotate == 1) {
+ dstPtr = pTrident->FbBase +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
+ srcPtr = pTrident->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = pTrident->FbBase +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
+ srcPtr = pTrident->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = (CARD32*)dstPtr;
+ count = height;
+ while(count--) {
+ *(dst++) = src[0] | (src[srcPitch] << 8) |
+ (src[srcPitch * 2] << 16) |
+ (src[srcPitch * 3] << 24);
+ src += srcPitch * 4;
+ }
+ srcPtr += pTrident->Rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+
+void
+TRIDENTRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int count, width, height, y1, y2, dstPitch, srcPitch;
+ CARD16 *dstPtr, *srcPtr, *src;
+ CARD32 *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -pTrident->Rotate * pTrident->ShadowPitch >> 1;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ y1 = pbox->y1 & ~1;
+ y2 = (pbox->y2 + 1) & ~1;
+ height = (y2 - y1) >> 1; /* in dwords */
+
+ if(pTrident->Rotate == 1) {
+ dstPtr = (CARD16*)pTrident->FbBase +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
+ srcPtr = (CARD16*)pTrident->ShadowPtr +
+ ((1 - y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = (CARD16*)pTrident->FbBase +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
+ srcPtr = (CARD16*)pTrident->ShadowPtr +
+ (y1 * srcPitch) + pbox->x2 - 1;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = (CARD32*)dstPtr;
+ count = height;
+ while(count--) {
+ *(dst++) = src[0] | (src[srcPitch] << 16);
+ src += srcPitch * 2;
+ }
+ srcPtr += pTrident->Rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+
+/* this one could be faster */
+void
+TRIDENTRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int count, width, height, y1, y2, dstPitch, srcPitch;
+ CARD8 *dstPtr, *srcPtr, *src;
+ CARD32 *dst;
+
+ dstPitch = BitmapBytePad(pScrn->displayWidth * 24);
+ srcPitch = -pTrident->Rotate * pTrident->ShadowPitch;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ y1 = pbox->y1 & ~3;
+ y2 = (pbox->y2 + 3) & ~3;
+ height = (y2 - y1) >> 2; /* blocks of 3 dwords */
+
+ if(pTrident->Rotate == 1) {
+ dstPtr = pTrident->FbBase +
+ (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3);
+ srcPtr = pTrident->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3);
+ } else {
+ dstPtr = pTrident->FbBase +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3);
+ srcPtr = pTrident->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = (CARD32*)dstPtr;
+ count = height;
+ while(count--) {
+ dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) |
+ (src[srcPitch] << 24);
+ dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) |
+ (src[srcPitch * 2] << 16) |
+ (src[(srcPitch * 2) + 1] << 24);
+ dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) |
+ (src[(srcPitch * 3) + 1] << 16) |
+ (src[(srcPitch * 3) + 2] << 24);
+ dst += 3;
+ src += srcPitch * 4;
+ }
+ srcPtr += pTrident->Rotate * 3;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+void
+TRIDENTRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int count, width, height, dstPitch, srcPitch;
+ CARD32 *dstPtr, *srcPtr, *src, *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -pTrident->Rotate * pTrident->ShadowPitch >> 2;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ height = pbox->y2 - pbox->y1;
+
+ if(pTrident->Rotate == 1) {
+ dstPtr = (CARD32*)pTrident->FbBase +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2;
+ srcPtr = (CARD32*)pTrident->ShadowPtr +
+ ((1 - pbox->y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = (CARD32*)pTrident->FbBase +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1;
+ srcPtr = (CARD32*)pTrident->ShadowPtr +
+ (pbox->y1 * srcPitch) + pbox->x2 - 1;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = dstPtr;
+ count = height;
+ while(count--) {
+ *(dst++) = *src;
+ src += srcPitch;
+ }
+ srcPtr += pTrident->Rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+
diff --git a/src/trident_video.c b/src/trident_video.c
new file mode 100644
index 0000000..9c29629
--- /dev/null
+++ b/src/trident_video.c
@@ -0,0 +1,1408 @@
+/*
+ * Copyright 1992-2000 by Alan Hourihane, Wigan, England.
+ *
+ * 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, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Alan Hourihane, alanh@fairlite.demon.co.uk
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_video.c,v 1.31 2002/12/22 18:54:43 alanh Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86fbman.h"
+#include "regionstr.h"
+
+#include "trident.h"
+#include "trident_regs.h"
+#include "Xv.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "dixstruct.h"
+#include "fourcc.h"
+
+#define OFF_DELAY 800 /* milliseconds */
+#define FREE_DELAY 60000
+
+#define OFF_TIMER 0x01
+#define FREE_TIMER 0x02
+#define CLIENT_VIDEO_ON 0x04
+
+#define TIMER_MASK (OFF_TIMER | FREE_TIMER)
+
+static XF86VideoAdaptorPtr TRIDENTSetupImageVideo(ScreenPtr);
+static void TRIDENTInitOffscreenImages(ScreenPtr);
+static void TRIDENTStopVideo(ScrnInfoPtr, pointer, Bool);
+static int TRIDENTSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer);
+static int TRIDENTGetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer);
+static void TRIDENTQueryBestSize(ScrnInfoPtr, Bool,
+ short, short, short, short, unsigned int *, unsigned int *, pointer);
+static int TRIDENTPutImage( ScrnInfoPtr,
+ short, short, short, short, short, short, short, short,
+ int, unsigned char*, short, short, Bool, RegionPtr, pointer);
+static int TRIDENTQueryImageAttributes(ScrnInfoPtr,
+ int, unsigned short *, unsigned short *, int *, int *);
+static void TRIDENTVideoTimerCallback(ScrnInfoPtr pScrn, Time time);
+static void tridentSetVideoContrast(TRIDENTPtr pTrident,int value);
+static void tridentSetVideoParameters(TRIDENTPtr pTrident, int brightness,
+ int saturation, int hue);
+void tridentFixFrame(ScrnInfoPtr pScrn, int *fixFrame);
+static void WaitForSync(ScrnInfoPtr pScrn);
+
+#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
+
+static Atom xvColorKey, xvSaturation, xvBrightness, xvHUE, xvContrast;
+
+void TRIDENTInitVideo(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
+ XF86VideoAdaptorPtr newAdaptor = NULL;
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int num_adaptors;
+
+ /*
+ * The following has been tested on:
+ *
+ * 9525 : flags: None
+ * Cyber9397(DVD) : flags: VID_ZOOM_NOMINI
+ * CyberBlade/i7: flags: VID_ZOOM_INV | VID_ZOOM_MINI
+ * CyberBlade/i1: flags: VID_ZOOM_INV | VID_ZOOM_MINI
+ * CyberBlade/Ai1: flags: VID_ZOOM_INV
+ * Cyber 9540 : flags: VID_ZOOM_INV | VID_SHIFT_4
+ * CyberXPm8 : flags: VID_ZOOM_INV | VID_SHIFT_4
+ *
+ * When you make changes make sure not to break these
+ * Add new chipsets to this list.
+ */
+ if (pTrident->Chipset >= BLADE3D) {
+ pTrident->videoFlags = VID_ZOOM_INV ;
+ if (pTrident->Chipset <= CYBERBLADEI1D)
+ pTrident->videoFlags |= VID_ZOOM_MINI;
+ else if (pTrident->Chipset < CYBERBLADEAI1 /* verified EE */
+ || pTrident->Chipset > CYBERBLADEAI1D)
+ pTrident->videoFlags |= VID_OFF_SHIFT_4;
+ }
+ if (pTrident->Chipset == CYBER9397 || pTrident->Chipset == CYBER9397DVD)
+ pTrident->videoFlags = VID_ZOOM_NOMINI;
+
+ if (pTrident->Chipset == CYBER9397DVD || pTrident->Chipset >= CYBER9525DVD)
+ pTrident->videoFlags |= VID_DOUBLE_LINEBUFFER_FOR_WIDE_SRC;
+
+ newAdaptor = TRIDENTSetupImageVideo(pScreen);
+ TRIDENTInitOffscreenImages(pScreen);
+
+ num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
+
+ if(newAdaptor) {
+ if(!num_adaptors) {
+ num_adaptors = 1;
+ adaptors = &newAdaptor;
+ } else {
+ newAdaptors = /* need to free this someplace */
+ xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*));
+ if(newAdaptors) {
+ memcpy(newAdaptors, adaptors, num_adaptors *
+ sizeof(XF86VideoAdaptorPtr));
+ newAdaptors[num_adaptors] = newAdaptor;
+ adaptors = newAdaptors;
+ num_adaptors++;
+ }
+ }
+ }
+
+ if(num_adaptors)
+ xf86XVScreenInit(pScreen, adaptors, num_adaptors);
+
+ if(newAdaptors)
+ xfree(newAdaptors);
+
+ if (pTrident->videoFlags)
+ xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,3,
+ "Trident Video Flags: %s %s %s\n",
+ pTrident->videoFlags & VID_ZOOM_INV ? "VID_ZOOM_INV" : "",
+ pTrident->videoFlags & VID_ZOOM_MINI ? "VID_ZOOM_MINI" : "", pTrident->videoFlags & VID_OFF_SHIFT_4 ? "VID_OFF_SHIFT_4"
+ : "",
+ pTrident->videoFlags & VID_ZOOM_NOMINI ? "VID_ZOOM_NOMINI"
+ : "");
+
+}
+
+/* client libraries expect an encoding */
+static XF86VideoEncodingRec DummyEncoding[1] =
+{
+ {
+ 0,
+ "XV_IMAGE",
+ 1024, 1024,
+ {1, 1}
+ }
+};
+
+#define NUM_FORMATS 4
+
+static XF86VideoFormatRec Formats[NUM_FORMATS] =
+{
+ {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
+};
+
+#ifdef TRIDENT_XV_GAMMA
+#define NUM_ATTRIBUTES 6
+#else
+#define NUM_ATTRIBUTES 5
+#endif
+
+static XF86AttributeRec Attributes[NUM_ATTRIBUTES] =
+{
+ {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
+ {XvSettable | XvGettable, 0, 187, "XV_SATURATION"},
+ {XvSettable | XvGettable, 0, 0x3F, "XV_BRIGHTNESS"},
+ {XvSettable | XvGettable, 0, 360 , "XV_HUE"},
+ {XvSettable | XvGettable, 0, 7, "XV_CONTRAST"}
+};
+
+#if 0
+# define NUM_IMAGES 4
+#else
+# define NUM_IMAGES 4
+#endif
+
+static XF86ImageRec Images[NUM_IMAGES] =
+{
+#if 0
+ {
+ 0x35315652,
+ XvRGB,
+ LSBFirst,
+ {'R','V','1','5',
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ 16,
+ XvPacked,
+ 1,
+ 15, 0x001F, 0x03E0, 0x7C00,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ {'R','V','B',0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ XvTopToBottom
+ },
+#endif
+ {
+ 0x36315652,
+ XvRGB,
+ LSBFirst,
+ {'R','V','1','6',
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ 16,
+ XvPacked,
+ 1,
+ 16, 0xF800, 0x07E0, 0x001F,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ {'R','V','B',0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ XvTopToBottom
+ },
+ XVIMAGE_YV12,
+ XVIMAGE_YUY2
+};
+
+typedef struct {
+ FBLinearPtr linear;
+ RegionRec clip;
+ CARD32 colorKey;
+ CARD8 Saturation;
+ CARD8 Brightness;
+ CARD16 HUE;
+ INT8 Contrast;
+ CARD32 videoStatus;
+ Time offTime;
+ Time freeTime;
+ int fixFrame;
+} TRIDENTPortPrivRec, *TRIDENTPortPrivPtr;
+
+
+#define GET_PORT_PRIVATE(pScrn) \
+ (TRIDENTPortPrivPtr)((TRIDENTPTR(pScrn))->adaptor->pPortPrivates[0].ptr)
+
+void TRIDENTResetVideo(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ TRIDENTPortPrivPtr pPriv = pTrident->adaptor->pPortPrivates[0].ptr;
+ int vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+ int red, green, blue;
+ int tmp;
+
+ if (pTrident->Chipset >= CYBER9388) {
+ OUTW(vgaIOBase + 4, 0x80B9);
+ OUTW(vgaIOBase + 4, 0x00BE);
+ OUTW(0x3C4, 0xC057);
+ OUTW(0x3C4, 0x3420);
+ OUTW(0x3C4, 0x3037);
+ } else {
+ if (pTrident->Chipset >= PROVIDIA9682) {
+ OUTB(0x83C8, 0x57);
+ OUTB(0x83C6, 0xC0);
+ OUTW(vgaIOBase + 4, 0x26BE);
+ } else {
+ OUTB(0x83C8, 0x37);
+ OUTB(0x83C6, 0x01);
+ OUTB(0x83C8, 0x00);
+ OUTB(0x83C6, 0x00);
+ }
+ }
+
+ if (pTrident->Chipset >= BLADEXP) {
+ OUTW(0x3C4, 0x007A);
+ OUTW(0x3C4, 0x007D);
+ }
+ switch (pScrn->depth) {
+ case 8:
+ VIDEOOUT(pPriv->colorKey, pTrident->keyOffset);
+ VIDEOOUT(0x00, (pTrident->keyOffset + 1));
+ VIDEOOUT(0x00, (pTrident->keyOffset + 2));
+ VIDEOOUT(0xFF, (pTrident->keyOffset + 4));
+ VIDEOOUT(0x00, (pTrident->keyOffset + 5));
+ VIDEOOUT(0x00, (pTrident->keyOffset + 6));
+ break;
+ default:
+ red = (pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red;
+ green = (pPriv->colorKey & pScrn->mask.green) >> pScrn->offset.green;
+ blue = (pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset.blue;
+ switch (pScrn->depth) {
+ case 15:
+ tmp = (red << 10) | (green << 5) | (blue);
+ VIDEOOUT((tmp & 0xff), pTrident->keyOffset);
+ VIDEOOUT((tmp & 0xff00)>>8, (pTrident->keyOffset + 1));
+ VIDEOOUT(0x00, (pTrident->keyOffset + 2));
+ VIDEOOUT(0xFF, (pTrident->keyOffset + 4));
+ VIDEOOUT(0xFF, (pTrident->keyOffset + 5));
+ VIDEOOUT(0x00, (pTrident->keyOffset + 6));
+ break;
+ case 16:
+ tmp = (red << 11) | (green << 5) | (blue);
+ VIDEOOUT((tmp & 0xff), pTrident->keyOffset);
+ VIDEOOUT((tmp & 0xff00)>>8, (pTrident->keyOffset + 1));
+ VIDEOOUT(0x00, (pTrident->keyOffset + 2));
+ VIDEOOUT(0xFF, (pTrident->keyOffset + 4));
+ VIDEOOUT(0xFF, (pTrident->keyOffset + 5));
+ VIDEOOUT(0x00, (pTrident->keyOffset + 6));
+ break;
+ case 24:
+ VIDEOOUT(blue, pTrident->keyOffset);
+ VIDEOOUT(green, (pTrident->keyOffset + 1));
+ VIDEOOUT(red, (pTrident->keyOffset + 2));
+ VIDEOOUT(0xFF, (pTrident->keyOffset + 4));
+ VIDEOOUT(0xFF, (pTrident->keyOffset + 5));
+ VIDEOOUT(0xFF, (pTrident->keyOffset + 6));
+ break;
+ }
+ }
+
+ if (pTrident->Chipset >= CYBER9388) {
+ tridentSetVideoContrast(pTrident,pPriv->Contrast);
+ tridentSetVideoParameters(pTrident,pPriv->Brightness,pPriv->Saturation,
+ pPriv->HUE);
+ }
+
+ OUTW(vgaIOBase + 4, 0x848E);
+}
+
+
+static XF86VideoAdaptorPtr
+TRIDENTSetupImageVideo(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ XF86VideoAdaptorPtr adapt;
+ TRIDENTPortPrivPtr pPriv;
+
+ if(!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) +
+ sizeof(TRIDENTPortPrivRec) +
+ sizeof(DevUnion))))
+ return NULL;
+
+ adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+ adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ adapt->name = "Trident Backend Scaler";
+ adapt->nEncodings = 1;
+ adapt->pEncodings = DummyEncoding;
+ adapt->nFormats = NUM_FORMATS;
+ adapt->pFormats = Formats;
+ adapt->nPorts = 1;
+ adapt->pPortPrivates = (DevUnion*)(&adapt[1]);
+ pPriv = (TRIDENTPortPrivPtr)(&adapt->pPortPrivates[1]);
+ adapt->pPortPrivates[0].ptr = (pointer)(pPriv);
+ adapt->pAttributes = Attributes;
+ adapt->nImages = NUM_IMAGES;
+ if (pTrident->Chipset >= CYBER9388) {
+ adapt->nAttributes = NUM_ATTRIBUTES;
+ } else {
+ adapt->nAttributes = 1; /* Just colorkey */
+ }
+ adapt->pImages = Images;
+ adapt->PutVideo = NULL;
+ adapt->PutStill = NULL;
+ adapt->GetVideo = NULL;
+ adapt->GetStill = NULL;
+ adapt->StopVideo = TRIDENTStopVideo;
+ adapt->SetPortAttribute = TRIDENTSetPortAttribute;
+ adapt->GetPortAttribute = TRIDENTGetPortAttribute;
+ adapt->QueryBestSize = TRIDENTQueryBestSize;
+ adapt->PutImage = TRIDENTPutImage;
+ adapt->QueryImageAttributes = TRIDENTQueryImageAttributes;
+
+ pPriv->colorKey = pTrident->videoKey & ((1 << pScrn->depth) - 1);
+ pPriv->Brightness = 45;
+ pPriv->Saturation = 80;
+ pPriv->Contrast = 4;
+ pPriv->HUE = 0;
+ pPriv->videoStatus = 0;
+ pPriv->fixFrame = 100;
+
+ /* gotta uninit this someplace */
+ REGION_INIT(pScreen, &pPriv->clip, NullBox, 0);
+
+ pTrident->adaptor = adapt;
+
+ xvColorKey = MAKE_ATOM("XV_COLORKEY");
+
+ if (pTrident->Chipset >= CYBER9388) {
+ xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
+ xvSaturation = MAKE_ATOM("XV_SATURATION");
+ xvHUE = MAKE_ATOM("XV_HUE");
+ xvContrast = MAKE_ATOM("XV_CONTRAST");
+ }
+
+ if (pTrident->Chipset >= PROVIDIA9682)
+ pTrident->keyOffset = 0x50;
+ else
+ pTrident->keyOffset = 0x30;
+
+ TRIDENTResetVideo(pScrn);
+
+ return adapt;
+}
+
+
+static Bool
+RegionsEqual(RegionPtr A, RegionPtr B)
+{
+ int *dataA, *dataB;
+ int num;
+
+ num = REGION_NUM_RECTS(A);
+ if(num != REGION_NUM_RECTS(B))
+ return FALSE;
+
+ if((A->extents.x1 != B->extents.x1) ||
+ (A->extents.x2 != B->extents.x2) ||
+ (A->extents.y1 != B->extents.y1) ||
+ (A->extents.y2 != B->extents.y2))
+ return FALSE;
+
+ dataA = (int*)REGION_RECTS(A);
+ dataB = (int*)REGION_RECTS(B);
+
+ while(num--) {
+ if((dataA[0] != dataB[0]) || (dataA[1] != dataB[1]))
+ return FALSE;
+ dataA += 2;
+ dataB += 2;
+ }
+
+ return TRUE;
+}
+
+#define DummyScreen screenInfo.screens[0]
+
+static void
+TRIDENTStopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ TRIDENTPortPrivPtr pPriv = (TRIDENTPortPrivPtr)data;
+ int vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
+
+ if(shutdown) {
+ if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
+ OUTW(vgaIOBase + 4, 0x0091);
+ WaitForSync(pScrn);
+ OUTW(vgaIOBase + 4, 0x848E);
+ }
+ if(pPriv->linear) {
+ xf86FreeOffscreenLinear(pPriv->linear);
+ pPriv->linear = NULL;
+ }
+ pPriv->videoStatus = 0;
+ } else {
+ if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
+ pPriv->videoStatus |= OFF_TIMER;
+ pPriv->offTime = currentTime.milliseconds + OFF_DELAY;
+ pTrident->VideoTimerCallback = TRIDENTVideoTimerCallback;
+ }
+ }
+}
+
+#undef PI
+#define PI 3.14159265
+
+static void
+tridentSetVideoContrast(TRIDENTPtr pTrident,int value)
+{
+ OUTW(0x3C4, (((value & 0x7)|((value & 0x7) << 4)) << 8) | 0xBC);
+}
+
+static void
+tridentSetVideoParameters(TRIDENTPtr pTrident, int brightness,
+ int saturation, int hue)
+{
+ double dtmp;
+ CARD8 sign, tmp, tmp1;
+
+ if (brightness >= 0x20)
+ brightness -= 0x20;
+ else
+ brightness += 0x20;
+ dtmp = sin((double)hue / 180.0 * PI) * saturation / 12.5;
+ sign = (dtmp < 0) ? 1 << 1 : 0;
+ tmp1 = ((int)fabs(dtmp) >> 4) & 0x1;
+ tmp = brightness << 2 | sign | tmp1;
+ OUTW(0x3C4, tmp << 8 | 0xB1);
+
+ tmp1 = ((int)fabs(dtmp) & 0x7 ) << 5;
+ dtmp = cos((double)hue / 180.0 * PI) * saturation / 12.5;
+ sign = (dtmp < 0) ? 1 << 4 : 0;
+ tmp1 |= (int)fabs(dtmp) & 0xf;
+ tmp = sign | tmp1;
+ OUTW(0x3C4, tmp << 8 | 0xB0);
+}
+
+static int
+TRIDENTSetPortAttribute(
+ ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 value,
+ pointer data
+){
+ TRIDENTPortPrivPtr pPriv = (TRIDENTPortPrivPtr)data;
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if(attribute == xvColorKey) {
+ int red, green, blue;
+ int tmp;
+ pPriv->colorKey = value;
+ switch (pScrn->depth) {
+ case 8:
+ VIDEOOUT(pPriv->colorKey, pTrident->keyOffset);
+ VIDEOOUT(0x00, (pTrident->keyOffset + 1));
+ VIDEOOUT(0x00, (pTrident->keyOffset + 2));
+ break;
+ default:
+ red = (pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red;
+ green = (pPriv->colorKey & pScrn->mask.green) >> pScrn->offset.green;
+ blue = (pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset.blue;
+ switch (pScrn->depth) {
+ case 15:
+ tmp = (red << 10) | (green << 5) | (blue);
+ VIDEOOUT((tmp&0xff), pTrident->keyOffset);
+ VIDEOOUT((tmp&0xff00)>>8, (pTrident->keyOffset + 1));
+ VIDEOOUT(0x00, (pTrident->keyOffset + 2));
+ break;
+ case 16:
+ tmp = (red << 11) | (green << 5) | (blue);
+ VIDEOOUT((tmp&0xff), pTrident->keyOffset);
+ VIDEOOUT((tmp&0xff00)>>8, (pTrident->keyOffset + 1));
+ VIDEOOUT(0x00, (pTrident->keyOffset + 2));
+ break;
+ case 24:
+ VIDEOOUT(blue, pTrident->keyOffset);
+ VIDEOOUT(green, (pTrident->keyOffset + 1));
+ VIDEOOUT(red, (pTrident->keyOffset + 2));
+ break;
+ }
+ }
+ REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
+ } else if (attribute == xvBrightness) {
+ if ((value < 0) || (value > 0x3f))
+ return BadValue;
+ pPriv->Brightness = value;
+ tridentSetVideoParameters(pTrident, pPriv->Brightness, pPriv->Saturation,
+ pPriv->HUE);
+ } else if (attribute == xvSaturation) {
+ if ((value < 0) || (value > 187))
+ return BadValue;
+ pPriv->Saturation = value;
+ tridentSetVideoParameters(pTrident, pPriv->Brightness, pPriv->Saturation,
+ pPriv->HUE);
+ } else if (attribute == xvHUE) {
+ if ((value < 0) || (value > 360))
+ return BadValue;
+ pPriv->HUE = value;
+ tridentSetVideoParameters(pTrident, pPriv->Brightness, pPriv->Saturation,
+ pPriv->HUE);
+ } else if (attribute == xvContrast) {
+ if ((value < 0) || (value > 7))
+ return BadValue;
+ pPriv->Contrast = value;
+ tridentSetVideoContrast(pTrident,value);
+ } else
+ return BadMatch;
+
+ return Success;
+}
+
+static int
+TRIDENTGetPortAttribute(
+ ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 *value,
+ pointer data
+){
+ TRIDENTPortPrivPtr pPriv = (TRIDENTPortPrivPtr)data;
+
+ if(attribute == xvColorKey) {
+ *value = pPriv->colorKey;
+ } else if(attribute == xvBrightness) {
+ *value = pPriv->Brightness;
+ } else if(attribute == xvSaturation) {
+ *value = pPriv->Saturation;
+ } else if (attribute == xvHUE) {
+ *value = pPriv->HUE;
+ } else if (attribute == xvContrast) {
+ *value = pPriv->Contrast;
+ } else
+ return BadMatch;
+
+ return Success;
+}
+
+static void
+TRIDENTQueryBestSize(
+ ScrnInfoPtr pScrn,
+ Bool motion,
+ short vid_w, short vid_h,
+ short drw_w, short drw_h,
+ unsigned int *p_w, unsigned int *p_h,
+ pointer data
+){
+ *p_w = drw_w;
+ *p_h = drw_h;
+
+ if(*p_w > 16384) *p_w = 16384;
+}
+
+
+static void
+TRIDENTCopyData(
+ unsigned char *src,
+ unsigned char *dst,
+ int srcPitch,
+ int dstPitch,
+ int h,
+ int w
+){
+ w <<= 1;
+ while(h--) {
+ memcpy(dst, src, w);
+ src += srcPitch;
+ dst += dstPitch;
+ }
+}
+
+static void
+TRIDENTCopyMungedData(
+ unsigned char *src1,
+ unsigned char *src2,
+ unsigned char *src3,
+ unsigned char *dst1,
+ int srcPitch,
+ int srcPitch2,
+ int dstPitch,
+ int h,
+ int w
+){
+ CARD32 *dst = (CARD32*)dst1;
+ int i, j;
+
+ dstPitch >>= 2;
+ w >>= 1;
+
+ for(j = 0; j < h; j++) {
+ for(i = 0; i < w; i++) {
+ dst[i] = src1[i << 1] | (src1[(i << 1) + 1] << 16) |
+ (src3[i] << 8) | (src2[i] << 24);
+ }
+ dst += dstPitch;
+ src1 += srcPitch;
+ if(j & 1) {
+ src2 += srcPitch2;
+ src3 += srcPitch2;
+ }
+ }
+}
+
+static FBLinearPtr
+TRIDENTAllocateMemory(
+ ScrnInfoPtr pScrn,
+ FBLinearPtr linear,
+ int size
+){
+ ScreenPtr pScreen;
+ FBLinearPtr new_linear;
+
+ if(linear) {
+ if(linear->size >= size)
+ return linear;
+
+ if(xf86ResizeOffscreenLinear(linear, size))
+ return linear;
+
+ xf86FreeOffscreenLinear(linear);
+ }
+
+ pScreen = screenInfo.screens[pScrn->scrnIndex];
+
+ new_linear = xf86AllocateOffscreenLinear(pScreen, size, 16,
+ NULL, NULL, NULL);
+
+ if(!new_linear) {
+ int max_size;
+
+ xf86QueryLargestOffscreenLinear(pScreen, &max_size, 16,
+ PRIORITY_EXTREME);
+
+ if(max_size < size)
+ return NULL;
+
+ xf86PurgeUnlockedOffscreenAreas(pScreen);
+ new_linear = xf86AllocateOffscreenLinear(pScreen, size, 16,
+ NULL, NULL, NULL);
+ }
+
+ return new_linear;
+}
+
+static void
+TRIDENTDisplayVideo(
+ ScrnInfoPtr pScrn,
+ int id,
+ int offset,
+ short width, short height,
+ int pitch,
+ int x1, int y1, int x2, int y2,
+ BoxPtr dstBox,
+ short src_w, short src_h,
+ short drw_w, short drw_h
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+ int zoomx1, zoomx2, zoomy1, zoomy2;
+ int tx1,tx2;
+ int ty1,ty2;
+
+ switch(id) {
+ case 0x35315652: /* RGB15 */
+ case 0x36315652: /* RGB16 */
+ if (pTrident->Chipset >= CYBER9388) {
+ OUTW(vgaIOBase + 4, 0x22BF);
+ OUTW(vgaIOBase + 4, 0x248F);
+ } else {
+ OUTW(vgaIOBase + 4, 0x118F);
+ }
+ break;
+ case FOURCC_YV12: /* YV12 */
+ case FOURCC_YUY2: /* YUY2 */
+ default:
+ if (pTrident->Chipset >= CYBER9388) {
+ OUTW(vgaIOBase + 4, 0x00BF);
+ OUTW(vgaIOBase + 4, 0x208F);
+ } else {
+ OUTW(vgaIOBase + 4, 0x108F);
+ }
+ break;
+ }
+ tx1 = dstBox->x1 + pTrident->hsync;
+ tx2 = dstBox->x2 + pTrident->hsync + pTrident->hsync_rskew;
+ ty1 = dstBox->y1 + pTrident->vsync - 2;
+ ty2 = dstBox->y2 + pTrident->vsync + 2 + pTrident->vsync_bskew;
+
+ OUTW(vgaIOBase + 4, (tx1 & 0xff) <<8 | 0x86);
+ OUTW(vgaIOBase + 4, (tx1 & 0xff00) | 0x87);
+ OUTW(vgaIOBase + 4, (ty1 & 0xff) <<8 | 0x88);
+ OUTW(vgaIOBase + 4, (ty1 & 0xff00) | 0x89);
+ OUTW(vgaIOBase + 4, (tx2 & 0xff) <<8 | 0x8A);
+ OUTW(vgaIOBase + 4, (tx2 & 0xff00) | 0x8B);
+ OUTW(vgaIOBase + 4, (ty2 & 0xff) <<8 | 0x8C);
+ OUTW(vgaIOBase + 4, (ty2 & 0xff00) | 0x8D);
+
+ offset += (x1 >> 15) & ~0x01;
+
+ if (pTrident->videoFlags & VID_OFF_SHIFT_4)
+ offset = offset >> 4;
+ else
+ offset = offset >> 3;
+
+ OUTW(vgaIOBase + 4, (((width<<1) & 0xff)<<8) | 0x90);
+ OUTW(vgaIOBase + 4, ((width<<1) & 0xff00) | 0x91);
+ OUTW(vgaIOBase + 4, ((offset) & 0xff) << 8 | 0x92);
+ OUTW(vgaIOBase + 4, ((offset) & 0xff00) | 0x93);
+ OUTW(vgaIOBase + 4, ((offset) & 0x070000) >> 8 | 0x94);
+
+ /* Horizontal Zoom */
+ if (pTrident->videoFlags & VID_ZOOM_INV) {
+ if ((pTrident->videoFlags & VID_ZOOM_MINI) && src_w > drw_w)
+ zoomx2 = (int)((float)drw_w/(float)src_w * 1024)
+ | (((int)((float)src_w/(float)drw_w) - 1)&7)<<10 | 0x8000;
+ else
+ zoomx2 = (int)(float)src_w/(float)drw_w * 1024;
+
+ OUTW(vgaIOBase + 4, (zoomx2&0xff)<<8 | 0x80);
+ OUTW(vgaIOBase + 4, (zoomx2&0x9f00) | 0x81);
+ } else {
+ if (drw_w == src_w
+ || ((pTrident->videoFlags & VID_ZOOM_NOMINI) && (src_w > drw_w))) {
+ OUTW(vgaIOBase + 4, 0x0080);
+ OUTW(vgaIOBase + 4, 0x0081);
+ } else
+ if (drw_w > src_w) {
+ float z;
+
+ z = (float)((drw_w)/(float)src_w) - 1.0;
+
+ zoomx1 = z;
+ zoomx2 = (z - (int)zoomx1 ) * 1024;
+
+ OUTW(vgaIOBase + 4, (zoomx2&0xff)<<8 | 0x80);
+ OUTW(vgaIOBase + 4, (zoomx1&0x0f)<<10 | (zoomx2&0x0300) |0x81);
+ } else {
+ zoomx1 = ((float)drw_w/(float)src_w);
+ zoomx2 = ( ((float)drw_w/(float)src_w) - (int)zoomx1 ) * 1024;
+ OUTW(vgaIOBase + 4, (zoomx2&0xff)<<8 | 0x80);
+ OUTW(vgaIOBase + 4, (zoomx2&0x0300)|
+ (((int)((float)src_w/(float)drw_w)-1)&7)<<10 | 0x8081);
+ }
+ }
+
+ /* Vertical Zoom */
+ if (pTrident->videoFlags & VID_ZOOM_INV) {
+ if ((pTrident->videoFlags & VID_ZOOM_MINI) && src_h > drw_h)
+ zoomy2 = (int)(( ((float)drw_h/(float)src_h)) * 1024)
+ | (((int)((float)src_h/(float)drw_h)-1)&7)<<10
+ | 0x8000;
+ else
+ zoomy2 = ( ((float)src_h/(float)drw_h)) * 1024;
+ OUTW(vgaIOBase + 4, (zoomy2&0xff)<<8 | 0x82);
+ OUTW(vgaIOBase + 4, (zoomy2&0x9f00) | 0x0083);
+ } else {
+ if (drw_h == src_h
+ || ((pTrident->videoFlags & VID_ZOOM_NOMINI) && (src_h > drw_h))) {
+ OUTW(vgaIOBase + 4, 0x0082);
+ OUTW(vgaIOBase + 4, 0x0083);
+ } else
+ if (drw_h > src_h) {
+ float z;
+
+ z = (float)drw_h/(float)src_h - 1;
+ zoomy1 = z;
+ zoomy2 = (z - (int)zoomy1 ) * 1024;
+
+ OUTW(vgaIOBase + 4, (zoomy2&0xff)<<8 | 0x82);
+ OUTW(vgaIOBase + 4, (zoomy1&0x0f)<<10 | (zoomy2&0x0300) |0x83);
+ } else {
+ zoomy1 = ((float)drw_h/(float)src_h);
+ zoomy2 = ( ((float)drw_h/(float)src_h) - (int)zoomy1 ) * 1024;
+ OUTW(vgaIOBase + 4, (zoomy2&0xff)<<8 | 0x82);
+ OUTW(vgaIOBase + 4, (zoomy2&0x0300)|
+ (((int)((float)src_h/(float)drw_h)-1)&7)<<10 | 0x8083);
+ }
+ }
+
+ if (pTrident->Chipset >= CYBER9388) {
+ int lb = (width+2) >> 2;
+
+ OUTW(vgaIOBase + 4, ((lb & 0x100)>>1) | 0x0895);
+ OUTW(vgaIOBase + 4, (lb & 0xFF)<<8 | 0x0096);
+ if ((pTrident->videoFlags & VID_DOUBLE_LINEBUFFER_FOR_WIDE_SRC)
+ && (src_w > 384)) {
+ OUTW(0x3C4, 0x0497); /* 2x line buffers */
+ } else {
+ OUTW(0x3C4, 0x0097); /* 1x line buffers */
+ }
+ OUTW(vgaIOBase + 4, 0x8097);
+ OUTW(vgaIOBase + 4, 0x00BA);
+ OUTW(vgaIOBase + 4, 0x00BB);
+ OUTW(vgaIOBase + 4, 0xFFBC);
+ OUTW(vgaIOBase + 4, 0xFFBD);
+ OUTW(vgaIOBase + 4, 0x04BE);
+ OUTW(vgaIOBase + 4, 0x948E);
+ } else {
+
+ OUTW(vgaIOBase + 4, ((((id == FOURCC_YV12) || (id == FOURCC_YUY2))
+ ? (width >> 2) : (width >> 6)) << 8) | 0x95);
+ OUTW(vgaIOBase + 4, ((((id == FOURCC_YV12) || (id == FOURCC_YUY2))
+ ? ((width+2) >> 2) : ((width+2) >> 6)) << 8) |0x96);
+
+ OUTW(vgaIOBase + 4, 0x948E);
+ OUTB(0x83C8, 0x00);
+ OUTB(0x83C6, 0x95);
+ }
+}
+
+static int
+TRIDENTPutImage(
+ ScrnInfoPtr pScrn,
+ short src_x, short src_y,
+ short drw_x, short drw_y,
+ short src_w, short src_h,
+ short drw_w, short drw_h,
+ int id, unsigned char* buf,
+ short width, short height,
+ Bool sync,
+ RegionPtr clipBoxes, pointer data
+){
+ TRIDENTPortPrivPtr pPriv = (TRIDENTPortPrivPtr)data;
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ INT32 x1, x2, y1, y2;
+ unsigned char *dst_start;
+ int pitch, new_size, offset, offset2 = 0, offset3 = 0;
+ int srcPitch, srcPitch2 = 0, dstPitch;
+ int top, left, npixels, nlines, bpp;
+ BoxRec dstBox;
+ CARD32 tmp;
+
+ /* Clip */
+ x1 = src_x;
+ x2 = src_x + src_w;
+ y1 = src_y;
+ y2 = src_y + src_h;
+
+ dstBox.x1 = drw_x;
+ dstBox.x2 = drw_x + drw_w;
+ dstBox.y1 = drw_y;
+ dstBox.y2 = drw_y + drw_h;
+
+ if(!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes,
+ width, height))
+ return Success;
+
+ dstBox.x1 -= pScrn->frameX0;
+ dstBox.x2 -= pScrn->frameX0;
+ dstBox.y1 -= pScrn->frameY0;
+ dstBox.y2 -= pScrn->frameY0;
+
+ bpp = pScrn->bitsPerPixel >> 3;
+ pitch = bpp * pScrn->displayWidth;
+
+ dstPitch = ((width << 1) + 15) & ~15;
+ new_size = ((dstPitch * height) + bpp - 1) / bpp;
+ switch(id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ srcPitch = (width + 3) & ~3;
+ offset2 = srcPitch * height;
+ srcPitch2 = ((width >> 1) + 3) & ~3;
+ offset3 = (srcPitch2 * (height >> 1)) + offset2;
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ srcPitch = (width << 1);
+ break;
+ }
+
+ if(!(pPriv->linear = TRIDENTAllocateMemory(pScrn, pPriv->linear, new_size)))
+ return BadAlloc;
+
+ /* copy data */
+ top = y1 >> 16;
+ left = (x1 >> 16) & ~1;
+ npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left;
+ left <<= 1;
+
+ offset = pPriv->linear->offset * bpp;
+
+ dst_start = pTrident->FbBase + offset + left + (top * dstPitch);
+
+ switch(id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ top &= ~1;
+ tmp = ((top >> 1) * srcPitch2) + (left >> 2);
+ offset2 += tmp;
+ offset3 += tmp;
+ if(id == FOURCC_I420) {
+ tmp = offset2;
+ offset2 = offset3;
+ offset3 = tmp;
+ }
+ nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
+ TRIDENTCopyMungedData(buf + (top * srcPitch) + (left >> 1),
+ buf + offset2, buf + offset3, dst_start,
+ srcPitch, srcPitch2, dstPitch, nlines, npixels);
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ buf += (top * srcPitch) + left;
+ nlines = ((y2 + 0xffff) >> 16) - top;
+ TRIDENTCopyData(buf, dst_start, srcPitch, dstPitch, nlines, npixels);
+ break;
+ }
+
+ /* update cliplist */
+ if(!RegionsEqual(&pPriv->clip, clipBoxes)) {
+ /* update cliplist */
+ REGION_COPY(pScreen, &pPriv->clip, clipBoxes);
+ xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
+ }
+
+ offset += top * dstPitch;
+
+ tridentFixFrame(pScrn,&pPriv->fixFrame);
+ TRIDENTDisplayVideo(pScrn, id, offset, width, height, dstPitch,
+ x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
+
+ pPriv->videoStatus = CLIENT_VIDEO_ON;
+
+ return Success;
+}
+
+static int
+TRIDENTQueryImageAttributes(
+ ScrnInfoPtr pScrn,
+ int id,
+ unsigned short *w, unsigned short *h,
+ int *pitches, int *offsets
+){
+ int size, tmp;
+
+ if(*w > 1024) *w = 1024;
+ if(*h > 1024) *h = 1024;
+
+ *w = (*w + 1) & ~1;
+ if(offsets) offsets[0] = 0;
+
+ switch(id) {
+ case FOURCC_YV12: /* YV12 */
+ *h = (*h + 1) & ~1;
+ size = (*w + 3) & ~3;
+ if(pitches) pitches[0] = size;
+ size *= *h;
+ if(offsets) offsets[1] = size;
+ tmp = ((*w >> 1) + 3) & ~3;
+ if(pitches) pitches[1] = pitches[2] = tmp;
+ tmp *= (*h >> 1);
+ size += tmp;
+ if(offsets) offsets[2] = size;
+ size += tmp;
+ break;
+ default: /* RGB15, RGB16, YUY2 */
+ size = *w << 1;
+ if(pitches) pitches[0] = size;
+ size *= *h;
+ break;
+ }
+
+ return size;
+}
+
+/****************** Offscreen stuff ***************/
+
+typedef struct {
+ FBLinearPtr linear;
+ Bool isOn;
+} OffscreenPrivRec, * OffscreenPrivPtr;
+
+static int
+TRIDENTAllocateSurface(
+ ScrnInfoPtr pScrn,
+ int id,
+ unsigned short w,
+ unsigned short h,
+ XF86SurfacePtr surface
+){
+ FBLinearPtr linear;
+ int pitch, fbpitch, size, bpp;
+ OffscreenPrivPtr pPriv;
+
+ if((w > 1024) || (h > 1024))
+ return BadAlloc;
+
+ w = (w + 1) & ~1;
+ pitch = ((w << 1) + 15) & ~15;
+ bpp = pScrn->bitsPerPixel >> 3;
+ fbpitch = bpp * pScrn->displayWidth;
+ size = ((pitch * h) + bpp - 1) / bpp;
+
+ if(!(linear = TRIDENTAllocateMemory(pScrn, NULL, size)))
+ return BadAlloc;
+
+ surface->width = w;
+ surface->height = h;
+
+ if(!(surface->pitches = xalloc(sizeof(int)))) {
+ xf86FreeOffscreenLinear(linear);
+ return BadAlloc;
+ }
+ if(!(surface->offsets = xalloc(sizeof(int)))) {
+ xfree(surface->pitches);
+ xf86FreeOffscreenLinear(linear);
+ return BadAlloc;
+ }
+ if(!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) {
+ xfree(surface->pitches);
+ xfree(surface->offsets);
+ xf86FreeOffscreenLinear(linear);
+ return BadAlloc;
+ }
+
+ pPriv->linear = linear;
+ pPriv->isOn = FALSE;
+
+ surface->pScrn = pScrn;
+ surface->id = id;
+ surface->pitches[0] = pitch;
+ surface->offsets[0] = linear->offset * bpp;
+ surface->devPrivate.ptr = (pointer)pPriv;
+
+ return Success;
+}
+
+static int
+TRIDENTStopSurface(
+ XF86SurfacePtr surface
+){
+ OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
+
+ if(pPriv->isOn) {
+ TRIDENTPtr pTrident = TRIDENTPTR(surface->pScrn);
+ int vgaIOBase = VGAHWPTR(surface->pScrn)->IOBase;
+
+ OUTW(vgaIOBase + 4, 0x0091);
+ WaitForSync(surface->pScrn);
+ OUTW(vgaIOBase + 4, 0x848E);
+ pPriv->isOn = FALSE;
+ }
+
+ return Success;
+}
+
+
+static int
+TRIDENTFreeSurface(
+ XF86SurfacePtr surface
+){
+ OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
+
+ if(pPriv->isOn)
+ TRIDENTStopSurface(surface);
+ xf86FreeOffscreenLinear(pPriv->linear);
+ xfree(surface->pitches);
+ xfree(surface->offsets);
+ xfree(surface->devPrivate.ptr);
+
+ return Success;
+}
+
+static int
+TRIDENTGetSurfaceAttribute(
+ ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 *value
+){
+ return TRIDENTGetPortAttribute(pScrn, attribute, value,
+ (pointer)(GET_PORT_PRIVATE(pScrn)));
+}
+
+static int
+TRIDENTSetSurfaceAttribute(
+ ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 value
+){
+ return TRIDENTSetPortAttribute(pScrn, attribute, value,
+ (pointer)(GET_PORT_PRIVATE(pScrn)));
+}
+
+static int
+TRIDENTDisplaySurface(
+ XF86SurfacePtr surface,
+ short src_x, short src_y,
+ short drw_x, short drw_y,
+ short src_w, short src_h,
+ short drw_w, short drw_h,
+ RegionPtr clipBoxes
+){
+ OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
+ ScrnInfoPtr pScrn = surface->pScrn;
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ TRIDENTPortPrivPtr portPriv = pTrident->adaptor->pPortPrivates[0].ptr;
+ INT32 x1, y1, x2, y2;
+ BoxRec dstBox;
+
+ x1 = src_x;
+ x2 = src_x + src_w;
+ y1 = src_y;
+ y2 = src_y + src_h;
+
+ dstBox.x1 = drw_x;
+ dstBox.x2 = drw_x + drw_w;
+ dstBox.y1 = drw_y;
+ dstBox.y2 = drw_y + drw_h;
+
+ if(!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes,
+ surface->width, surface->height))
+ {
+ return Success;
+ }
+
+ dstBox.x1 -= pScrn->frameX0;
+ dstBox.x2 -= pScrn->frameX0;
+ dstBox.y1 -= pScrn->frameY0;
+ dstBox.y2 -= pScrn->frameY0;
+
+ TRIDENTResetVideo(pScrn);
+
+ tridentFixFrame(pScrn,&portPriv->fixFrame);
+ TRIDENTDisplayVideo(pScrn, surface->id, surface->offsets[0],
+ surface->width, surface->height, surface->pitches[0],
+ x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
+
+ xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes);
+
+ pPriv->isOn = TRUE;
+ /* we've prempted the XvImage stream so set its free timer */
+ if(portPriv->videoStatus & CLIENT_VIDEO_ON) {
+ REGION_EMPTY(pScrn->pScreen, &portPriv->clip);
+ UpdateCurrentTime();
+ portPriv->videoStatus = FREE_TIMER;
+ portPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
+ pTrident->VideoTimerCallback = TRIDENTVideoTimerCallback;
+ }
+
+ return Success;
+}
+
+static void
+TRIDENTInitOffscreenImages(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ XF86OffscreenImagePtr offscreenImages;
+
+ /* need to free this someplace */
+ if(!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec))))
+ return;
+
+ offscreenImages[0].image = &Images[0];
+ offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES |
+ VIDEO_CLIP_TO_VIEWPORT;
+ offscreenImages[0].alloc_surface = TRIDENTAllocateSurface;
+ offscreenImages[0].free_surface = TRIDENTFreeSurface;
+ offscreenImages[0].display = TRIDENTDisplaySurface;
+ offscreenImages[0].stop = TRIDENTStopSurface;
+ offscreenImages[0].setAttribute = TRIDENTSetSurfaceAttribute;
+ offscreenImages[0].getAttribute = TRIDENTGetSurfaceAttribute;
+ offscreenImages[0].max_width = 1024;
+ offscreenImages[0].max_height = 1024;
+ if (pTrident->Chipset >= CYBER9388) {
+ offscreenImages[0].num_attributes = NUM_ATTRIBUTES;
+ } else {
+ offscreenImages[0].num_attributes = 1; /* just colorkey */
+ }
+ offscreenImages[0].attributes = Attributes;
+
+ xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1);
+}
+
+static void
+TRIDENTVideoTimerCallback(ScrnInfoPtr pScrn, Time time)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ TRIDENTPortPrivPtr pPriv = pTrident->adaptor->pPortPrivates[0].ptr;
+ int vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ if(pPriv->videoStatus & TIMER_MASK) {
+ if(pPriv->videoStatus & OFF_TIMER) {
+ if(pPriv->offTime < time) {
+ OUTW(vgaIOBase + 4, 0x0091);
+ WaitForSync(pScrn);
+ OUTW(vgaIOBase + 4, 0x848E);
+ pPriv->videoStatus = FREE_TIMER;
+ pPriv->freeTime = time + FREE_DELAY;
+ }
+ } else { /* FREE_TIMER */
+ if(pPriv->freeTime < time) {
+ if(pPriv->linear) {
+ xf86FreeOffscreenLinear(pPriv->linear);
+ pPriv->linear = NULL;
+ }
+ pPriv->videoStatus = 0;
+ pTrident->VideoTimerCallback = NULL;
+ }
+ }
+ } else /* shouldn't get here */
+ pTrident->VideoTimerCallback = NULL;
+}
+
+ /* Calculate skew offsets for video overlay */
+
+
+void
+tridentFixFrame(ScrnInfoPtr pScrn, int *fixFrame)
+{
+
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+ int HTotal, HSyncStart;
+ int VTotal, VSyncStart;
+ int h_off = 0;
+ int v_off = 0;
+ unsigned char CRTC[0x11];
+ Bool isShadow;
+ unsigned char shadow = 0;
+
+ if ((*fixFrame)++ < 100)
+ return;
+
+ *fixFrame = 0;
+
+ OUTB(0x3CE, CyberControl);
+ isShadow = ((INB(0x3CF) & 0x81) == 0x81);
+
+ if (isShadow)
+ SHADOW_ENABLE(shadow);
+
+ OUTB(vgaIOBase + 4, 0x0);
+ CRTC[0x0] = INB(vgaIOBase + 5);
+ OUTB(vgaIOBase + 4, 0x4);
+ CRTC[0x4] = INB(vgaIOBase + 5);
+ OUTB(vgaIOBase + 4, 0x5);
+ CRTC[0x5] = INB(vgaIOBase + 5);
+ OUTB(vgaIOBase + 4, 0x6);
+ CRTC[0x6] = INB(vgaIOBase + 5);
+ OUTB(vgaIOBase + 4, 0x7);
+ CRTC[0x7] = INB(vgaIOBase + 5);
+ OUTB(vgaIOBase + 4, 0x10);
+ CRTC[0x10] = INB(vgaIOBase + 5);
+
+ HTotal = CRTC[0] << 3;
+ VTotal = CRTC[6]
+ | ((CRTC[7] & (1<<0)) << 8)
+ | ((CRTC[7] & (1<<5)) << 4);
+ HSyncStart = (CRTC[4]
+ + ((CRTC[5] >> 5) & 0x3)) << 3;
+ VSyncStart = CRTC[0x10]
+ | ((CRTC[7] & (1<<2)) << 6)
+ | ((CRTC[7] & (1<<7)) << 2);
+
+ if (isShadow) {
+ SHADOW_RESTORE(shadow);
+ if (pTrident->lcdMode != 0xff) {
+ h_off = (LCD[pTrident->lcdMode].display_x
+ - pScrn->currentMode->HDisplay) >> 1;
+ v_off = (LCD[pTrident->lcdMode].display_y
+ - pScrn->currentMode->VDisplay) >> 1;
+ }
+ }
+
+ pTrident->hsync = (HTotal - HSyncStart) + 23 + h_off;
+ pTrident->vsync = (VTotal - VSyncStart) - 2 + v_off;
+ pTrident->hsync_rskew = 0;
+ pTrident->vsync_bskew = 0;
+
+ /*
+ * HACK !! As awful as this is, it appears to be the only way....Sigh!
+ * We have XvHsync and XvVsync as options now, which adjust
+ * at the very end of this function. It'll be helpful for now
+ * and we can get more data on some of these skew values.
+ */
+ switch (pTrident->Chipset) {
+ case TGUI9680:
+ /* Furthur tweaking needed */
+ pTrident->hsync -= 84;
+ pTrident->vsync += 2;
+ break;
+ case PROVIDIA9682:
+ /* Furthur tweaking needed */
+ pTrident->hsync += 7;
+ break;
+ case PROVIDIA9685:
+ /* Spot on */
+ break;
+ case BLADEXP:
+ case CYBERBLADEXPAI1:
+ pTrident->hsync -= 15;
+ pTrident->hsync_rskew = 3;
+ break;
+ case BLADE3D:
+ if (pScrn->depth == 24)
+ pTrident->hsync -= 8;
+ else
+ pTrident->hsync -= 6;
+ break;
+ case CYBERBLADEI7:
+ case CYBERBLADEI7D:
+ case CYBERBLADEI1:
+ case CYBERBLADEI1D:
+ pTrident->hsync -= 8;
+ break;
+ case CYBERBLADEAI1:
+ pTrident->hsync -= 7;
+ break;
+ case CYBERBLADEAI1D:
+ pTrident->vsync += 2;
+ pTrident->vsync_bskew = -4;
+ pTrident->hsync -= 5;
+ break;
+ case CYBERBLADEE4:
+ pTrident->hsync -= 8;
+ break;
+ case CYBER9397:
+ pTrident->hsync -= 1;
+ pTrident->vsync -= 0;
+ pTrident->vsync_bskew = 0;
+ break;
+ case CYBER9397DVD:
+ pTrident->hsync_rskew = -1;
+ pTrident->vsync_bskew = -1;
+ break;
+ }
+ pTrident->hsync+=pTrident->OverrideHsync;
+ pTrident->vsync+=pTrident->OverrideVsync;
+ pTrident->hsync_rskew += pTrident->OverrideRskew;
+ pTrident->vsync_bskew += pTrident->OverrideBskew;
+}
+
+static void
+WaitForSync(ScrnInfoPtr pScrn)
+{
+ register vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ while (!(hwp->readST01(hwp)&0x8)) {};
+ while (hwp->readST01(hwp)&0x8) {};
+}
diff --git a/src/tridenthelper.c b/src/tridenthelper.c
new file mode 100644
index 0000000..f8e5905
--- /dev/null
+++ b/src/tridenthelper.c
@@ -0,0 +1,341 @@
+/*
+ * Copyright 1992-2000 by Alan Hourihane, Wigan, England.
+ *
+ * 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, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Alan Hourihane, alanh@fairlite.demon.co.uk
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/tridenthelper.c,v 1.20 2001/10/28 03:33:52 tsi Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Version.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "vgaHW.h"
+
+#include "trident.h"
+#include "trident_regs.h"
+
+static void IsClearTV(ScrnInfoPtr pScrn);
+
+void
+TGUISetClock(ScrnInfoPtr pScrn, int clock, CARD8 *a, CARD8 *b)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int powerup[4] = { 1,2,4,8 };
+ int clock_diff = 750;
+ int freq, ffreq;
+ int m, n, k;
+ int p, q, r, s;
+ int endn, endm, endk, startk;
+
+ p = q = r = s = 0;
+
+ IsClearTV(pScrn);
+
+ if (pTrident->NewClockCode)
+ {
+ endn = 255;
+ endm = 63;
+ endk = 2;
+ if (clock >= 100000) startk = 0; else
+ if (clock >= 50000) startk = 1; else
+ startk = 2;
+ }
+ else
+ {
+ endn = 121;
+ endm = 31;
+ endk = 1;
+ if (clock > 50000) startk = 1; else
+ startk = 0;
+ }
+
+ freq = clock;
+
+ for (k=startk;k<=endk;k++)
+ for (n=0;n<=endn;n++)
+ for (m=1;m<=endm;m++)
+ {
+ ffreq = ( ( ((n + 8) * pTrident->frequency) / ((m + 2) * powerup[k]) ) * 1000);
+ if ((ffreq > freq - clock_diff) && (ffreq < freq + clock_diff))
+ {
+/*
+ * It seems that the 9440 docs have this STRICT limitation, although
+ * most 9440 boards seem to cope. 96xx/Cyber chips don't need this limit
+ * so, I'm gonna remove it and it allows lower clocks < 25.175 too !
+ */
+#ifdef STRICT
+ if ( (n+8)*100/(m+2) < 978 && (n+8)*100/(m+2) > 349 ) {
+#endif
+ clock_diff = (freq > ffreq) ? freq - ffreq : ffreq - freq;
+ p = n; q = m; r = k; s = ffreq;
+#ifdef STRICT
+ }
+#endif
+ }
+ }
+
+ if (s == 0)
+ {
+ FatalError("Unable to set programmable clock.\n"
+ "Frequency %d is not a valid clock.\n"
+ "Please modify XF86Config for a new clock.\n",
+ freq);
+ }
+
+ if (pTrident->NewClockCode)
+ {
+ /* N is all 8bits */
+ *a = p;
+ /* M is first 6bits, with K last 2bits */
+ *b = (q & 0x3F) | (r << 6);
+ }
+ else
+ {
+ /* N is first 7bits, first M bit is 8th bit */
+ *a = ((1 & q) << 7) | p;
+ /* first 4bits are rest of M, 1bit for K value */
+ *b = (((q & 0xFE) >> 1) | (r << 4));
+ }
+ xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,3,"Found Clock %6.2f n=%i m=%i"
+ " k=%i\n",clock/1000.,p,q,r);
+}
+
+static void
+IsClearTV(ScrnInfoPtr pScrn)
+{
+ int vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ CARD8 temp;
+
+ if (pTrident->frequency != 0) return;
+
+ OUTB(vgaIOBase + 4, 0xC0);
+ temp = INB(vgaIOBase + 5);
+ if (temp & 0x80)
+ pTrident->frequency = PAL;
+ else
+ pTrident->frequency = NTSC;
+}
+
+void
+TridentFindClock(ScrnInfoPtr pScrn, int clock)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ pTrident->MUX = FALSE;
+#ifdef READOUT
+ pTrident->DontSetClock = FALSE;
+#endif
+ pTrident->currentClock = clock;
+
+ if (pTrident->IsCyber) {
+ Bool LCDActive;
+#ifdef READOUT
+ Bool ShadowModeActive;
+ Bool HStretch;
+ Bool VStretch;
+#endif
+ OUTB(0x3CE, FPConfig);
+ LCDActive = (INB(0x3CF) & 0x10);
+#ifdef READOUT
+ OUTB(0x3CE,HorStretch);
+ HStretch = (INB(0x3CF) & 0x01);
+ OUTB(0x3CE,VertStretch);
+ VStretch = (INB(0x3CF) & 0x01);
+
+ if (!(VStretch || HStretch) && LCDActive) {
+ CARD8 temp;
+ temp = INB(0x3C8);
+ temp = INB(0x3C6);
+ temp = INB(0x3C6);
+ temp = INB(0x3C6);
+ temp = INB(0x3C6);
+ pTrident->MUX = ((INB(0x3C6) & 0x20) == 0x20);
+ temp = INB(0x3C8);
+ pTrident->DontSetClock = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Keeping Clock for LCD Mode\n");
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO,"MUX is %s\n",pTrident->MUX?
+ "on":"off");
+ return;
+
+ } else
+#endif
+ {
+ if (pTrident->lcdMode != 0xff && LCDActive)
+ pTrident->currentClock = clock = LCD[pTrident->lcdMode].clock;
+ }
+
+ }
+ if (clock > pTrident->MUXThreshold) pTrident->MUX = TRUE;
+ else pTrident->MUX = FALSE;
+
+}
+
+float
+CalculateMCLK(ScrnInfoPtr pScrn)
+{
+ int vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int a,b;
+ int m,n,k;
+ float freq = 0.0;
+ int powerup[4] = { 1,2,4,8 };
+ CARD8 temp;
+
+ if (pTrident->HasSGRAM) {
+ OUTB(vgaIOBase + 4, 0x28);
+ switch(INB(vgaIOBase + 5) & 0x07) {
+ case 0:
+ freq = 60;
+ break;
+ case 1:
+ freq = 78;
+ break;
+ case 2:
+ freq = 90;
+ break;
+ case 3:
+ freq = 120;
+ break;
+ case 4:
+ freq = 66;
+ break;
+ case 5:
+ freq = 83;
+ break;
+ case 6:
+ freq = 100;
+ break;
+ case 7:
+ freq = 132;
+ break;
+ }
+ } else {
+ OUTB(0x3C4, NewMode1);
+ temp = INB(0x3C5);
+
+ OUTB(0x3C5, 0xC2);
+ if (!Is3Dchip) {
+ a = INB(0x43C6);
+ b = INB(0x43C7);
+ } else {
+ OUTB(0x3C4, 0x16);
+ a = INB(0x3C5);
+ OUTB(0x3C4, 0x17);
+ b = INB(0x3C5);
+ }
+
+ OUTB(0x3C4, NewMode1);
+ OUTB(0x3C5, temp);
+
+ IsClearTV(pScrn);
+
+ if (pTrident->NewClockCode) {
+ m = b & 0x3F;
+ n = a;
+ k = (b & 0xC0) >> 6;
+ } else {
+ m = (a & 0x07);
+ k = (b & 0x02) >> 1;
+ n = ((a & 0xF8)>>3)|((b&0x01)<<5);
+ }
+
+ freq = ((n+8)*pTrident->frequency)/((m+2)*powerup[k]);
+ }
+ return (freq);
+}
+
+void
+TGUISetMCLK(ScrnInfoPtr pScrn, int clock, CARD8 *a, CARD8 *b)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int powerup[4] = { 1,2,4,8 };
+ int clock_diff = 750;
+ int freq, ffreq;
+ int m,n,k;
+ int p, q, r, s;
+ int startn, endn;
+ int endm, endk;
+
+ p = q = r = s = 0;
+
+ IsClearTV(pScrn);
+
+ if (pTrident->NewClockCode)
+ {
+ startn = 64;
+ endn = 255;
+ endm = 63;
+ endk = 3;
+ }
+ else
+ {
+ startn = 0;
+ endn = 121;
+ endm = 31;
+ endk = 1;
+ }
+
+ freq = clock;
+
+ if (!pTrident->HasSGRAM) {
+ for (k=0;k<=endk;k++)
+ for (n=startn;n<=endn;n++)
+ for (m=1;m<=endm;m++) {
+ ffreq = ((((n+8)*pTrident->frequency)/((m+2)*powerup[k]))*1000);
+ if ((ffreq > freq - clock_diff) && (ffreq < freq + clock_diff))
+ {
+ clock_diff = (freq > ffreq) ? freq - ffreq : ffreq - freq;
+ p = n; q = m; r = k; s = ffreq;
+ }
+ }
+
+ if (s == 0)
+ {
+ FatalError("Unable to set memory clock.\n"
+ "Frequency %d is not a valid clock.\n"
+ "Please modify XF86Config for a new clock.\n",
+ freq);
+ }
+
+ if (pTrident->NewClockCode)
+ {
+ /* N is all 8bits */
+ *a = p;
+ /* M is first 6bits, with K last 2bits */
+ *b = (q & 0x3F) | (r << 6);
+ }
+ else
+ {
+ /* N is first 7bits, first M bit is 8th bit */
+ *a = ((1 & q) << 7) | p;
+ /* first 4bits are rest of M, 1bit for K value */
+ *b = (((q & 0xFE) >> 1) | (r << 4));
+ }
+ }
+}
+
+
+
+
diff --git a/src/tridentramdac.c b/src/tridentramdac.c
new file mode 100644
index 0000000..f4117b9
--- /dev/null
+++ b/src/tridentramdac.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright 1992-2000 by Alan Hourihane, Wigan, England.
+ *
+ * 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, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * TridentOutIndReg() and TridentInIndReg() are used to access
+ * the indirect Trident RAMDAC registers only.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/tridentramdac.c,v 1.4 2000/12/07 16:48:06 alanh Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "trident_regs.h"
+#include "trident.h"
+
+void
+TridentWriteAddress(ScrnInfoPtr pScrn, CARD32 index)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ MMIO_OUTB(0x3C6, 0xFF);
+ MMIO_OUTB(0x3C8, index);
+}
+
+void
+TridentWriteData(ScrnInfoPtr pScrn, unsigned char data)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ MMIO_OUTB(0x3C9, data);
+}
+
+void
+TridentReadAddress(ScrnInfoPtr pScrn, CARD32 index)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ MMIO_OUTB(0x3C6, 0xFF);
+ MMIO_OUTB(0x3C7, index);
+}
+
+unsigned char
+TridentReadData(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ return(MMIO_INB(0x3C9));
+}
diff --git a/src/tvga_dac.c b/src/tvga_dac.c
new file mode 100644
index 0000000..2d5a7ec
--- /dev/null
+++ b/src/tvga_dac.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright 1992-1999 by Alan Hourihane, Wigan, England.
+ *
+ * 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, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Alan Hourihane, alanh@fairlite.demon.co.uk
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/tvga_dac.c,v 1.6 2002/03/29 18:33:29 alanh Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Version.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "vgaHW.h"
+
+#include "trident.h"
+#include "trident_regs.h"
+
+Bool
+TVGAInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ TRIDENTRegPtr pReg = &pTrident->ModeReg;
+ int vgaIOBase;
+ int offset = 0;
+ int clock = mode->Clock;
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ OUTB(0x3C4, 0x0B); INB(0x3C5); /* Ensure we are in New Mode */
+
+ pReg->tridentRegsDAC[0x00] = 0x00;
+ OUTB(0x3C4, ConfPort2);
+ pReg->tridentRegs3C4[ConfPort2] = INB(0x3C5);
+ OUTB(0x3CE, MiscExtFunc);
+ pReg->tridentRegs3CE[MiscExtFunc] = INB(0x3CF) & 0xF0;
+ OUTB(vgaIOBase + 4, FIFOControl);
+ pReg->tridentRegs3x4[FIFOControl] = INB(vgaIOBase + 5) | 0x24;
+
+ if (pScrn->bitsPerPixel >= 8) {
+ /* YUK ! here we have to mess with old mode operation */
+ OUTB(0x3C4, 0x0B); OUTB(0x3C5, 0x00); /* Goto Old Mode */
+ OUTB(0x3C4, OldMode2 + NewMode2);
+ pReg->tridentRegs3C4[OldMode2] = 0x10;
+ OUTB(0x3C4, 0x0B); INB(0x3C5); /* Back to New Mode */
+ pReg->tridentRegs3x4[Underline] = 0x40;
+ if (pTrident->Chipset < TGUI9440AGi)
+ pReg->tridentRegs3x4[CRTCMode] = 0xA3;
+ }
+
+ if (pScrn->videoRam > 512)
+ pReg->tridentRegs3C4[ConfPort2] |= 0x20;
+ else
+ pReg->tridentRegs3C4[ConfPort2] &= 0xDF;
+
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ case 4:
+ offset = pScrn->displayWidth >> 4;
+ break;
+ case 8:
+ if (pScrn->videoRam < 1024)
+ offset = pScrn->displayWidth >> 3;
+ else
+ offset = pScrn->displayWidth >> 4;
+ pReg->tridentRegs3CE[MiscExtFunc] |= 0x02;
+ break;
+ case 16:
+ pReg->tridentRegs3CE[MiscExtFunc] |= 0x02;
+ offset = pScrn->displayWidth >> 3;
+ /* Reload with any chipset specific stuff here */
+ if (pTrident->Chipset == TVGA8900D) {
+ if (pScrn->depth == 15)
+ pReg->tridentRegsDAC[0x00] = 0xA0;
+ else
+ pReg->tridentRegsDAC[0x00] = 0xE0;
+ pReg->tridentRegs3CE[MiscExtFunc] |= 0x08; /* Clock Div by 2*/
+ clock *= 2; /* Double the clock */
+ }
+ break;
+ case 24:
+ pReg->tridentRegs3CE[MiscExtFunc] |= 0x02;
+ offset = (pScrn->displayWidth * 3) >> 3;
+ pReg->tridentRegsDAC[0x00] = 0xD0;
+ break;
+ case 32:
+ pReg->tridentRegs3CE[MiscExtFunc] |= 0x02;
+ pReg->tridentRegs3CE[MiscExtFunc] |= 0x08; /* Clock Division by 2*/
+ clock *= 2; /* Double the clock */
+ offset = pScrn->displayWidth >> 1;
+ pReg->tridentRegsDAC[0x00] = 0x42;
+ break;
+ }
+ pReg->tridentRegs3x4[Offset] = offset & 0xFF;
+
+ pReg->tridentRegsClock[0x00] = mode->ClockIndex;
+
+ pReg->tridentRegs3C4[NewMode1] = 0x80;
+
+ if (pTrident->Linear)
+ pReg->tridentRegs3x4[LinearAddReg] = ((pTrident->FbAddress >> 24) << 6)|
+ ((pTrident->FbAddress >> 20) & 0x0F)|
+ 0x20;
+ else {
+ pReg->tridentRegs3CE[MiscExtFunc] |= 0x04;
+ pReg->tridentRegs3x4[LinearAddReg] = 0;
+ }
+
+ pReg->tridentRegs3x4[CRTCModuleTest] =
+ (mode->Flags & V_INTERLACE ? 0x84 : 0x80);
+ OUTB(vgaIOBase+ 4, AddColReg);
+ pReg->tridentRegs3x4[AddColReg] = (INB(vgaIOBase + 5) & 0xCF) |
+ ((offset & 0x100) >> 4);
+
+ return(TRUE);
+}
+
+void
+TVGARestore(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ CARD8 temp;
+ int vgaIOBase;
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ /* Goto Old Mode */
+ OUTB(0x3C4, 0x0B);
+ OUTB(0x3C5, 0x00);
+ OUTB(0x3C4, OldMode2 + NewMode2);
+ OUTB(0x3C5, tridentReg->tridentRegs3C4[OldMode2]);
+
+ /* Goto New Mode */
+ OUTB(0x3C4, 0x0B);
+ temp = INB(0x3C5);
+
+ /* Unprotect registers */
+ OUTW(0x3C4, (0x80 << 8) | NewMode1);
+
+ temp = INB(0x3C8);
+ temp = INB(0x3C6);
+ temp = INB(0x3C6);
+ temp = INB(0x3C6);
+ temp = INB(0x3C6);
+ OUTB(0x3C6, tridentReg->tridentRegsDAC[0x00]);
+ temp = INB(0x3C8);
+
+ OUTW_3x4(CRTCModuleTest);
+ OUTW_3x4(LinearAddReg);
+ OUTW_3x4(FIFOControl);
+ OUTW_3C4(ConfPort2);
+ if (pScrn->bitsPerPixel >= 8) {
+ OUTW_3x4(Underline);
+ if (pTrident->Chipset < TGUI9440AGi)
+ OUTW_3x4(CRTCMode);
+ }
+ OUTW_3x4(AddColReg);
+ OUTW_3CE(MiscExtFunc);
+ OUTW_3x4(Offset);
+
+ TRIDENTClockSelect(pScrn, tridentReg->tridentRegsClock[0x00]);
+
+ OUTW(0x3C4, ((tridentReg->tridentRegs3C4[NewMode1]) << 8)| NewMode1);
+}
+
+void
+TVGASave(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ CARD8 temp;
+ int vgaIOBase;
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ temp = INB(0x3C8);
+ temp = INB(0x3C6);
+ temp = INB(0x3C6);
+ temp = INB(0x3C6);
+ temp = INB(0x3C6);
+ tridentReg->tridentRegsDAC[0x00] = INB(0x3C6);
+ temp = INB(0x3C8);
+
+ /* Goto Old Mode */
+ OUTB(0x3C4, 0x0B);
+ OUTB(0x3C5, 0x00);
+ OUTB(0x3C4, OldMode2 + NewMode2);
+ tridentReg->tridentRegs3C4[OldMode2] = INB(0x3C5);
+
+ /* Goto New Mode */
+ OUTB(0x3C4, 0x0B);
+ temp = INB(0x3C5);
+
+ INB_3C4(NewMode1);
+
+ /* Unprotect registers */
+ OUTW(0x3C4, ((0x80 ^ 0x02) << 8) | NewMode1);
+ OUTW(vgaIOBase + 4, (0x92 << 8) | NewMode1);
+
+ if (pScrn->bitsPerPixel >= 8) {
+ INB_3x4(Underline);
+ if (pTrident->Chipset < TGUI9440AGi)
+ INB_3x4(CRTCMode);
+ }
+ INB_3x4(LinearAddReg);
+ INB_3x4(FIFOControl);
+ INB_3x4(CRTCModuleTest);
+ INB_3x4(AddColReg);
+ INB_3CE(MiscExtFunc);
+ INB_3C4(ConfPort2);
+
+ TRIDENTClockSelect(pScrn, CLK_REG_SAVE);
+
+ /* Protect registers */
+ OUTW_3C4(NewMode1);
+}
diff --git a/src/xp_accel.c b/src/xp_accel.c
new file mode 100644
index 0000000..f6f0b63
--- /dev/null
+++ b/src/xp_accel.c
@@ -0,0 +1,601 @@
+/*
+ * Copyright 1992-2002 by Alan Hourihane, Sychdyn, North Wales, UK.
+ *
+ * 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, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * BladeXP accelerated options.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/xp_accel.c,v 1.4 2002/10/09 16:38:20 tsi Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "miline.h"
+
+#include "trident.h"
+#include "trident_regs.h"
+
+#include "xaalocal.h"
+#include "xaarop.h"
+
+static void XPSync(ScrnInfoPtr pScrn);
+#if 0
+static void XPSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg,
+ int rop, unsigned int planemask, int length,
+ unsigned char *pattern);
+static void XPSubsequentDashedBresenhamLine(ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e,
+ int len, int octant, int phase);
+static void XPSetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void XPSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e,
+ int len, int octant);
+#endif
+static void XPSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y,
+ int len, int dir);
+static void XPSetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void XPSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h);
+static void XPSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2,
+ int y2, int w, int h);
+static void XPSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask,
+ int transparency_color);
+static void XPSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int fg, int bg,
+ int rop, unsigned int planemask);
+static void XPSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int x, int y,
+ int w, int h);
+#if 0
+static void XPSetupForScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void XPSubsequentScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn, int x,
+ int y, int w, int h, int skipleft);
+static void XPSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
+#endif
+
+static void
+XPInitializeAccelerator(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int shift;
+
+ /* This forces updating the clipper */
+ pTrident->Clipping = TRUE;
+
+ CHECKCLIPPING;
+
+ BLADE_XP_OPERMODE(pTrident->EngineOperation);
+ pTrident->EngineOperation |= 0x40;
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ default: /* Muffle compiler */
+ shift = 18;
+ break;
+ case 16:
+ shift = 19;
+ break;
+ case 32:
+ shift = 20;
+ break;
+ }
+ MMIO_OUT32(pTrident->IOBase, 0x2154, (pScrn->displayWidth) << shift);
+ MMIO_OUT32(pTrident->IOBase, 0x2150, (pScrn->displayWidth) << shift);
+ MMIO_OUT8(pTrident->IOBase, 0x2126, 3);
+}
+
+Bool
+XPAccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ BoxRec AvailFBArea;
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = (pTrident->FbMapSize - 4096) / (pScrn->displayWidth *
+ pScrn->bitsPerPixel / 8);
+
+ if (AvailFBArea.y2 > 2047) AvailFBArea.y2 = 2047;
+
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ if (pTrident->NoAccel)
+ return FALSE;
+
+ pTrident->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if (!infoPtr) return FALSE;
+
+ infoPtr->Flags = PIXMAP_CACHE |
+ OFFSCREEN_PIXMAPS |
+ LINEAR_FRAMEBUFFER;
+
+ pTrident->InitializeAccelerator = XPInitializeAccelerator;
+ XPInitializeAccelerator(pScrn);
+
+ infoPtr->Sync = XPSync;
+
+#if 0 /* TO DO for the XP */
+ infoPtr->SolidLineFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidLine = XPSetupForSolidLine;
+ infoPtr->SolidBresenhamLineErrorTermBits = 12;
+ infoPtr->SubsequentSolidBresenhamLine = XPSubsequentSolidBresenhamLine;
+
+ infoPtr->DashedLineFlags = LINE_PATTERN_MSBFIRST_LSBJUSTIFIED |
+ NO_PLANEMASK |
+ LINE_PATTERN_POWER_OF_2_ONLY;
+ infoPtr->SetupForDashedLine = XPSetupForDashedLine;
+ infoPtr->DashedBresenhamLineErrorTermBits = 12;
+ infoPtr->SubsequentDashedBresenhamLine =
+ XPSubsequentDashedBresenhamLine;
+ infoPtr->DashPatternMaxLength = 16;
+#endif
+
+ infoPtr->SolidFillFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidFill = XPSetupForFillRectSolid;
+ infoPtr->SubsequentSolidFillRect = XPSubsequentFillRectSolid;
+ infoPtr->SubsequentSolidHorVertLine = XPSubsequentSolidHorVertLine;
+
+ infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | NO_TRANSPARENCY;
+
+ infoPtr->SetupForScreenToScreenCopy =
+ XPSetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy =
+ XPSubsequentScreenToScreenCopy;
+
+ infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK |
+ HARDWARE_PATTERN_PROGRAMMED_BITS |
+ BIT_ORDER_IN_BYTE_MSBFIRST;
+
+ infoPtr->SetupForMono8x8PatternFill =
+ XPSetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ XPSubsequentMono8x8PatternFillRect;
+
+#if 0 /* Needs fixing */
+ infoPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK |
+ BIT_ORDER_IN_BYTE_MSBFIRST;
+
+ pTrident->XAAScanlineColorExpandBuffers[0] =
+ xnfalloc(((pScrn->virtualX + 63)) *4* (pScrn->bitsPerPixel / 8));
+
+ infoPtr->NumScanlineColorExpandBuffers = 1;
+ infoPtr->ScanlineColorExpandBuffers =
+ pTrident->XAAScanlineColorExpandBuffers;
+
+ infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
+ XPSetupForScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
+ XPSubsequentScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentColorExpandScanline =
+ XPSubsequentColorExpandScanline;
+#endif
+
+ return(XAAInit(pScreen, infoPtr));
+}
+
+static void
+XPSync(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int count = 0, timeout = 0;
+ int busy;
+
+ BLADE_XP_OPERMODE(pTrident->EngineOperation);
+
+ for (;;) {
+ BLTBUSY(busy);
+ if (busy != GE_BUSY) {
+ return;
+ }
+ count++;
+ if (count == 10000000) {
+ ErrorF("XP: BitBLT engine time-out.\n");
+ count = 9990000;
+ timeout++;
+ if (timeout == 8) {
+ /* Reset BitBLT Engine */
+ TGUI_STATUS(0x00);
+ return;
+ }
+ }
+ }
+}
+
+static void
+XPClearSync(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int count = 0, timeout = 0;
+ int busy;
+
+ for (;;) {
+ BLTBUSY(busy);
+ if (busy != GE_BUSY) {
+ return;
+ }
+ count++;
+ if (count == 10000000) {
+ ErrorF("XP: BitBLT engine time-out.\n");
+ count = 9990000;
+ timeout++;
+ if (timeout == 8) {
+ /* Reset BitBLT Engine */
+ TGUI_STATUS(0x00);
+ return;
+ }
+ }
+ }
+}
+
+static void
+XPSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask, int transparency_color)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int dst = 0;
+
+ pTrident->BltScanDirection = 0;
+ if (xdir < 0) pTrident->BltScanDirection |= XNEG;
+ if (ydir < 0) pTrident->BltScanDirection |= YNEG;
+
+ REPLICATE(transparency_color);
+ if (transparency_color != -1) {
+ dst |= 3<<16;
+ MMIO_OUT32(pTrident->IOBase, 0x2134, transparency_color);
+ }
+
+ TGUI_DRAWFLAG(pTrident->BltScanDirection | SCR2SCR | dst);
+ TGUI_FMIX(XAACopyROP[rop]);
+}
+
+static void
+XPSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if (pTrident->BltScanDirection & YNEG) {
+ y1 = y1 + h - 1;
+ y2 = y2 + h - 1;
+ }
+ if (pTrident->BltScanDirection & XNEG) {
+ x1 = x1 + w - 1;
+ x2 = x2 + w - 1;
+ }
+ XP_SRC_XY(x1,y1);
+ XP_DEST_XY(x2,y2);
+ XP_DIM_XY(w,h);
+ TGUI_COMMAND(GE_BLT);
+ XPClearSync(pScrn);
+}
+
+#if 0
+static void
+XPSetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ pTrident->BltScanDirection = 0;
+ REPLICATE(color);
+ TGUI_FMIX(XAAPatternROP[rop]);
+ if (pTrident->Chipset >= PROVIDIA9685) {
+ TGUI_FPATCOL(color);
+ } else {
+ TGUI_FCOLOUR(color);
+ }
+}
+
+static void
+XPSubsequentSolidBresenhamLine( ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e, int len, int octant)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int tmp = pTrident->BltScanDirection;
+
+ if (octant & YMAJOR) tmp |= YMAJ;
+ if (octant & XDECREASING) tmp |= XNEG;
+ if (octant & YDECREASING) tmp |= YNEG;
+ TGUI_DRAWFLAG(SOLIDFILL | STENCIL | tmp);
+ XP_SRC_XY(dmin-dmaj,dmin);
+ XP_DEST_XY(x,y);
+ XP_DIM_XY(dmin+e,len);
+ TGUI_COMMAND(GE_BRESLINE);
+ XPSync(pScrn);
+}
+#endif
+
+static void
+XPSubsequentSolidHorVertLine(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int len, int dir
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ TGUI_DRAWFLAG(SOLIDFILL);
+ if (dir == DEGREES_0) {
+ XP_DIM_XY(len,1);
+ XP_DEST_XY(x,y);
+ } else {
+ XP_DIM_XY(1,len);
+ XP_DEST_XY(x,y);
+ }
+ TGUI_COMMAND(GE_BLT);
+ XPSync(pScrn);
+}
+
+#if 0
+void
+XPSetupForDashedLine(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int length,
+ unsigned char *pattern
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ CARD32 *DashPattern = (CARD32*)pattern;
+ CARD32 NiceDashPattern = DashPattern[0];
+
+ NiceDashPattern = *((CARD16 *)pattern) & ((1<<length) - 1);
+ switch(length) {
+ case 2: NiceDashPattern |= NiceDashPattern << 2;
+ case 4: NiceDashPattern |= NiceDashPattern << 4;
+ case 8: NiceDashPattern |= NiceDashPattern << 8;
+ }
+ pTrident->BltScanDirection = 0;
+ REPLICATE(fg);
+ if (pTrident->Chipset >= PROVIDIA9685) {
+ TGUI_FPATCOL(fg);
+ if (bg == -1) {
+ pTrident->BltScanDirection |= 1<<12;
+ TGUI_BPATCOL(~fg);
+ } else {
+ REPLICATE(bg);
+ TGUI_BPATCOL(bg);
+ }
+ } else {
+ TGUI_FCOLOUR(fg);
+ if (bg == -1) {
+ pTrident->BltScanDirection |= 1<<12;
+ TGUI_BCOLOUR(~fg);
+ } else {
+ REPLICATE(bg);
+ TGUI_BCOLOUR(bg);
+ }
+ }
+ TGUI_FMIX(XAAPatternROP[rop]);
+ pTrident->LinePattern = NiceDashPattern;
+}
+
+void
+XPSubsequentDashedBresenhamLine(ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e, int len, int octant, int phase)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int tmp = pTrident->BltScanDirection;
+
+ if (octant & YMAJOR) tmp |= YMAJ;
+ if (octant & XDECREASING) tmp |= XNEG;
+ if (octant & YDECREASING) tmp |= YNEG;
+
+ TGUI_STYLE(((pTrident->LinePattern >> phase) |
+ (pTrident->LinePattern << (16-phase))) & 0x0000FFFF);
+ TGUI_DRAWFLAG(STENCIL | tmp);
+ XP_SRC_XY(dmin-dmaj,dmin);
+ XP_DEST_XY(x,y);
+ XP_DIM_XY(e+dmin,len);
+ TGUI_COMMAND(GE_BRESLINE);
+ XPSync(pScrn);
+}
+#endif
+
+static void
+XPSetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ REPLICATE(color);
+ TGUI_FMIX(XAAPatternROP[rop]);
+ MMIO_OUT32(pTrident->IOBase, 0x2158, color);
+ TGUI_DRAWFLAG(SOLIDFILL);
+}
+
+static void
+XPSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ XP_DIM_XY(w,h);
+ XP_DEST_XY(x,y);
+ TGUI_COMMAND(GE_BLT);
+ XPSync(pScrn);
+}
+
+#if 0
+static void MoveDWORDS(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords )
+{
+ while(dwords & ~0x03) {
+ *dest = *src;
+ *(dest + 1) = *(src + 1);
+ *(dest + 2) = *(src + 2);
+ *(dest + 3) = *(src + 3);
+ src += 4;
+ dest += 4;
+ dwords -= 4;
+ }
+ if (!dwords) return;
+ *dest = *src;
+ dest += 1;
+ src += 1;
+ if (dwords == 1) return;
+ *dest = *src;
+ dest += 1;
+ src += 1;
+ if (dwords == 2) return;
+ *dest = *src;
+ dest += 1;
+ src += 1;
+}
+#endif
+
+#if 0
+static void MoveDWORDS_FixedBase(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords )
+{
+ while(dwords & ~0x03) {
+ *dest = *src;
+ *dest = *(src + 1);
+ *dest = *(src + 2);
+ *dest = *(src + 3);
+ dwords -= 4;
+ src += 4;
+ }
+
+ if(!dwords) return;
+ *dest = *src;
+ if(dwords == 1) return;
+ *dest = *(src + 1);
+ if(dwords == 2) return;
+ *dest = *(src + 2);
+}
+#endif
+
+
+static void
+XPSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int drawflag = 0;
+
+ REPLICATE(fg);
+ MMIO_OUT32(pTrident->IOBase, 0x2158, fg);
+
+ if (bg == -1) {
+ drawflag |= 1<<12;
+ MMIO_OUT32(pTrident->IOBase, 0x215C, ~fg);
+ } else {
+ REPLICATE(bg);
+ MMIO_OUT32(pTrident->IOBase, 0x215C, bg);
+ }
+
+ drawflag |= 7<<18;
+ TGUI_DRAWFLAG(PATMONO | drawflag);
+ MMIO_OUT32(pTrident->IOBase, 0x2180, patternx);
+ MMIO_OUT32(pTrident->IOBase, 0x2184, patterny);
+ TGUI_FMIX(XAAPatternROP[rop]);
+}
+
+static void
+XPSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int x, int y,
+ int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ XP_DEST_XY(x,y);
+ XP_DIM_XY(w,h);
+ TGUI_COMMAND(GE_BLT);
+ XPSync(pScrn);
+}
+
+#if 0
+static void
+XPSetupForScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ TGUI_FMIX(XAACopyROP[rop]);
+ if (bg == -1) {
+ TGUI_DRAWFLAG(SRCMONO | 1<<12);
+ REPLICATE(fg);
+ TGUI_FCOLOUR(fg);
+ } else {
+ TGUI_DRAWFLAG(SRCMONO);
+ REPLICATE(fg);
+ REPLICATE(bg);
+ TGUI_FCOLOUR(fg);
+ TGUI_BCOLOUR(bg);
+ }
+}
+
+static void
+XPSubsequentScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ pTrident->dwords = (w + 31) >> 5;
+ pTrident->h = h;
+
+ XP_DEST_XY(x,y);
+ XP_DIM_XY(w>>1,h);
+ TGUI_COMMAND(GE_BLT);
+}
+
+static void
+XPSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ XAAInfoRecPtr infoRec;
+ infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ MoveDWORDS_FixedBase((CARD32 *)pTrident->IOBase + 0x2160,
+ (CARD32 *)pTrident->XAAScanlineColorExpandBuffers[0],
+ pTrident->dwords);
+
+ pTrident->h--;
+ if (pTrident->h)
+ XPSync(pScrn);
+}
+#endif