summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/chips.man218
-rw-r--r--src/ct_BlitMM.h140
-rw-r--r--src/ct_Blitter.h168
-rw-r--r--src/ct_BltHiQV.h178
-rw-r--r--src/ct_accel.c1737
-rw-r--r--src/ct_bank.c626
-rw-r--r--src/ct_cursor.c481
-rw-r--r--src/ct_ddc.c282
-rw-r--r--src/ct_dga.c316
-rw-r--r--src/ct_driver.c7487
-rw-r--r--src/ct_driver.h553
-rw-r--r--src/ct_regs.c535
-rw-r--r--src/ct_shadow.c243
-rw-r--r--src/ct_video.c1163
-rw-r--r--util/AsmMacros.h450
-rw-r--r--util/dRegs.c305
-rw-r--r--util/mRegs.c186
-rw-r--r--util/modClock.c412
18 files changed, 15480 insertions, 0 deletions
diff --git a/man/chips.man b/man/chips.man
new file mode 100644
index 0000000..ad05ba6
--- /dev/null
+++ b/man/chips.man
@@ -0,0 +1,218 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/chips.man,v 1.5 2002/01/04 21:22:27 tsi Exp $
+.\" shorthand for double quote that works everywhere.
+.ds q \N'34'
+.TH CHIPS __drivermansuffix__ __vendorversion__
+.SH NAME
+chips \- Chips and Technologies video driver
+.SH SYNOPSIS
+.nf
+.B "Section \*qDevice\*q"
+.BI " Identifier \*q" devname \*q
+.B " Driver \*qchips\*q"
+\ \ ...
+.B EndSection
+.fi
+.SH DESCRIPTION
+.B chips
+is an XFree86 driver for Chips and Technologies video processors. The majority
+of the Chips and Technologies chipsets are supported by this driver. In general
+the limitation on the capabilities of this driver are determined by the
+chipset on which it is run. Where possible, this driver provides full
+acceleration and supports the following depths: 1, 4, 8, 15, 16, 24 and on
+the latest chipsets an 8+16 overlay mode. All visual types are supported for
+depth 1, 4 and 8 and both TrueColor and DirectColor visuals are supported
+where possible. Multi-head configurations are supported on PCI or AGP buses.
+.SH SUPPORTED HARDWARE
+The
+.B chips
+driver supports video processors on most of the bus types currently available.
+The chipsets supported fall into one of three architectural classes. A
+.B basic
+architecture, the
+.B WinGine
+architecture and the newer
+.B HiQV
+architecture.
+.PP
+.B Basic Architecture
+.PP
+The supported chipsets are
+.B ct65520, ct65525, ct65530, ct65535, ct65540, ct65545, ct65546
+and
+.B ct65548
+.PP
+Color depths 1, 4 and 8 are supported on all chipsets, while depths 15, 16
+and 24 are supported only on the
+.B 65540, 65545, 65546
+and
+.B 65548
+chipsets. The driver is accelerated when used with the
+.B 65545, 65546
+or
+.B 65548
+chipsets, however the DirectColor visual is not available.
+.PP
+.B Wingine Architecture
+.PP
+The supported chipsets are
+.B ct64200
+and
+.B ct64300
+.PP
+Color depths 1, 4 and 8 are supported on both chipsets, while depths 15, 16
+and 24 are supported only on the
+.B 64300
+chipsets. The driver is accelerated when used with the
+.B 64300
+chipsets, however the DirectColor visual is not available.
+.PP
+.B HiQV Architecture
+.PP
+The supported chipsets are
+.B ct65550, ct65554, ct65555, ct68554, ct69000
+and
+.B ct69030
+.PP
+Color depths 1, 4, 8, 15, 16, 24 and 8+16 are supported on all chipsets.
+The DirectColor visual is supported on all color depths except the 8+16
+overlay mode. Full acceleration is supplied for all chipsets.
+.SH CONFIGURATION DETAILS
+Please refer to XF86Config(__filemansuffix__) for general configuration
+details. This section only covers configuration details specific to this
+driver.
+.PP
+The driver auto-detects the chipset type, but the following
+.B ChipSet
+names may optionally be specified in the config file
+.B \*qDevice\*q
+section, and will override the auto-detection:
+.PP
+.RS 4
+"ct65520", "ct65525", "ct65530", "ct65535", "ct65540", "ct65545", "ct65546",
+"ct65548", "ct65550", "ct65554", "ct65555", "ct68554", "ct69000", "ct69030",
+"ct64200", "ct64300".
+.RE
+.PP
+The driver will auto-detect the amount of video memory present for all
+chipsets. But maybe overridden with the
+.B VideoRam
+entry in the config file
+.B \*qDevice\*q
+section.
+.PP
+The following driver
+.B Options
+are supported, on one or more of the supported chipsets:
+.TP
+.BI "Option \*qNoAccel\*q \*q" boolean \*q
+Disable or enable acceleration. Default: acceleration is enabled.
+.TP
+.BI "Option \*qNoLinear\*q \*q" boolean \*q
+Disables linear addressing in cases where it is enabled by default.
+Default: off
+.TP
+.BI "Option \*qLinear\*q \*q" boolean \*q
+Enables linear addressing in cases where it is disabled by default.
+Default: off
+.TP
+.BI "Option \*qHWCursor\*q \*q" boolean \*q
+Enable or disable the HW cursor. Default: on.
+.TP
+.BI "Option \*qSWCursor\*q \*q" boolean \*q
+Enable or disable the HW cursor. Default: off.
+.TP
+.BI "Option \*qSTN\*q \*q" boolean \*q
+Force detection of STN screen type. Default: off.
+.TP
+.BI "Option \*qUseModeline\*q \*q" boolean \*q
+Reprogram flat panel timings with values from the modeline. Default: off
+.TP
+.BI "Option \*qFixPanelSize\*q \*q" boolean \*q
+Reprogram flat panel size with values from the modeline. Default: off
+.TP
+.BI "Option \*qNoStretch\*q \*q" boolean \*q
+This option disables the stretching on a mode on a flat panel to fill the
+screen. Default: off
+.TP
+.BI "Option \*qLcdCenter\*q \*q" boolean \*q
+Center the mode displayed on the flat panel on the screen. Default: off
+.TP
+.BI "Option \*qHWclocks\*q \*q" boolean \*q
+Force the use of fixed hardware clocks on chips that support both fixed
+and programmable clocks. Default: off
+.TP
+.BI "Option \*qUseVclk1\*q \*q" boolean \*q
+Use the Vclk1 programmable clock on
+.B HiQV
+chipsets instead of Vclk2. Default: off
+.TP
+.BI "Option \*qFPClock8\*q \*q" float \*q
+.TP
+.BI "Option \*qFPClock16\*q \*q" float \*q
+.TP
+.BI "Option \*qFPClock24\*q \*q" float \*q
+.TP
+.BI "Option \*qFPClock32\*q \*q" float \*q
+Force the use of a particular video clock speed for use with the
+flat panel at a specified depth
+.TP
+.BI "Option \*qMMIO\*q \*q" boolean \*q
+Force the use of memory mapped IO for acceleration registers. Default: off
+.TP
+.BI "Option \*qFullMMIO\*q \*q" boolean \*q
+Force the use of memory mapped IO where it can be used. Default: off
+.TP
+.BI "Option \*qSuspendHack\*q \*q" boolean \*q
+Force driver to leave centering and stretching registers alone. This
+can fix some laptop suspend/resume problems. Default: off
+.TP
+.BI "Option \*qOverlay\*q"
+Enable 8+24 overlay mode. Only appropriate for depth 24. Default: off.
+.TP
+.BI "Option \*qColorKey\*q \*q" integer \*q
+Set the colormap index used for the transparency key for the depth 8 plane
+when operating in 8+16 overlay mode. The value must be in the range
+2\-255. Default: 255.
+.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 \*qShadowFB\*q \*q" boolean \*q
+Enable or disable use of the shadow framebuffer layer. Default: off.
+.TP
+.BI "Option \*qSyncOnGreen\*q \*q" boolean \*q
+Enable or disable combining the sync signals with the green signal.
+Default: off.
+.TP
+.BI "Option \*qShowCache\*q \*q" boolean \*q
+Enable or disable viewing offscreen memory. Used for debugging only
+Default: off.
+.TP
+.BI "Option \*q18bitBus\*q \*q" boolean \*q
+Force the driver to assume that the flat panel has an 18bit data bus.
+Default: off.
+.TP
+.BI "Option \*qCrt2Memory\*q \*q" integer \*q
+In a dual-head mode (69030 only) this option selects the amount of memory
+to set aside for the second head. If not specified, half the memory is used.
+Default: off.
+.TP
+.BI "Option \*qDualRefresh\*q \*q" integer \*q
+The 69030 supports independent refresh rates on its two display channels.
+This mode of operations uses additional memory bandwidth and thus limits
+the maximum colour depth and refresh rate that can be achieved, and so is
+off by default. Using this option forces the use of an independent refresh
+rate on the two screens.
+Default: off.
+.SH "SEE ALSO"
+XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__)
+.PP
+You are also recommended to read the README.chips file that comes with all
+XFree86 distributions, which discusses the
+.B chips
+driver in more detail.
+.SH AUTHORS
+Authors include: Jon Block, Mike Hollick, Regis Cridlig, Nozomi Ytow,
+Egbert Eich, David Bateman and Xavier Ducoin
+
diff --git a/src/ct_BlitMM.h b/src/ct_BlitMM.h
new file mode 100644
index 0000000..7660241
--- /dev/null
+++ b/src/ct_BlitMM.h
@@ -0,0 +1,140 @@
+/* $XConsortium: ct_BlitMM.h /main/2 1996/10/25 10:28:31 kaleb $ */
+
+
+
+
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_BlitMM.h,v 1.5 2002/11/25 14:04:58 eich Exp $ */
+
+/* Definitions for the Chips and Technology BitBLT engine communication. */
+/* These are done using Memory Mapped IO, of the registers */
+/* BitBLT modes for register 93D0. */
+
+#define ctPATCOPY 0xF0
+#define ctTOP2BOTTOM 0x100
+#define ctBOTTOM2TOP 0x000
+#define ctLEFT2RIGHT 0x200
+#define ctRIGHT2LEFT 0x000
+#define ctSRCFG 0x400
+#define ctSRCMONO 0x800
+#define ctPATMONO 0x1000
+#define ctBGTRANSPARENT 0x2000
+#define ctSRCSYSTEM 0x4000
+#define ctPATSOLID 0x80000L
+#define ctPATSTART0 0x00000L
+#define ctPATSTART1 0x10000L
+#define ctPATSTART2 0x20000L
+#define ctPATSTART3 0x30000L
+#define ctPATSTART4 0x40000L
+#define ctPATSTART5 0x50000L
+#define ctPATSTART6 0x60000L
+#define ctPATSTART7 0x70000L
+
+/* Macros to do useful things with the C&T BitBLT engine */
+#define ctBLTWAIT \
+ {HW_DEBUG(0x4); \
+ while(MMIO_IN32(cPtr->MMIOBase, MR(0x4)) & 0x00100000){};}
+
+#define ctSETROP(op) \
+ {HW_DEBUG(0x4); MMIO_OUT32(cPtr->MMIOBase, MR(0x4), op);}
+
+#define ctSETSRCADDR(srcAddr) \
+ {HW_DEBUG(0x5); \
+ MMIO_OUT32(cPtr->MMIOBase, MR(0x5),(srcAddr)&0x7FFFFFL);}
+
+#define ctSETDSTADDR(dstAddr) \
+{HW_DEBUG(0x6); \
+ MMIO_OUT32(cPtr->MMIOBase, MR(0x6), (dstAddr)&0x7FFFFFL);}
+
+#define ctSETPITCH(srcPitch,dstPitch) \
+{HW_DEBUG(0x0); \
+ MMIO_OUT32(cPtr->MMIOBase, MR(0x0),(((dstPitch)&0xFFFF)<<16)| \
+ ((srcPitch)&0xFFFF));}
+
+#define ctSETHEIGHTWIDTHGO(Height,Width)\
+{HW_DEBUG(0x7); \
+ MMIO_OUT32(cPtr->MMIOBase, MR(0x7), (((Height)&0xFFFF)<<16)| \
+ ((Width)&0xFFFF));}
+
+#define ctSETPATSRCADDR(srcAddr)\
+{HW_DEBUG(0x1); \
+ MMIO_OUT32(cPtr->MMIOBase, MR(0x1),(srcAddr)&0x1FFFFFL);}
+
+#define ctSETBGCOLOR8(c) {\
+ HW_DEBUG(0x2); \
+ if ((cAcl->bgColor != (c)) || (cAcl->bgColor == -1)) { \
+ cAcl->bgColor = (c); \
+ MMIO_OUT32(cPtr->MMIOBase, MR(0x2),\
+ ((((((c)&0xFF)<<8)|((c)&0xFF))<<16) | \
+ ((((c)&0xFF)<<8)|((c)&0xFF)))); \
+ } \
+}
+
+#define ctSETBGCOLOR16(c) {\
+ HW_DEBUG(0x2); \
+ if ((cAcl->bgColor != (c)) || (cAcl->bgColor == -1)) { \
+ cAcl->bgColor = (c); \
+ MMIO_OUT32(cPtr->MMIOBase, MR(0x2), \
+ ((((c)&0xFFFF)<<16)|((c)&0xFFFF))); \
+ } \
+}
+
+/* As the 6554x doesn't support 24bpp colour expansion this doesn't work,
+ * It is here only for later use with the 65550 */
+#define ctSETBGCOLOR24(c) {\
+ HW_DEBUG(0x2); \
+ if ((cAcl->bgColor != (c)) || (cAcl->bgColor == -1)) { \
+ cAcl->bgColor = (c); \
+ MMIO_OUT32(cPtr->MMIOBase, MR(0x2),((c)&0xFFFFFF)); \
+ } \
+}
+
+#define ctSETFGCOLOR8(c) {\
+ HW_DEBUG(0x3); \
+ if ((cAcl->fgColor != (c)) || (cAcl->fgColor == -1)) { \
+ cAcl->fgColor = (c); \
+ MMIO_OUT32(cPtr->MMIOBase, MR(0x3), \
+ ((((((c)&0xFF)<<8)|((c)&0xFF))<<16) | \
+ ((((c)&0xFF)<<8)|((c)&0xFF)))); \
+ } \
+}
+
+#define ctSETFGCOLOR16(c) {\
+ HW_DEBUG(0x3); \
+ if ((cAcl->fgColor != (c)) || (cAcl->fgColor == -1)) { \
+ cAcl->fgColor = (c); \
+ MMIO_OUT32(cPtr->MMIOBase, MR(0x3), \
+ ((((c)&0xFFFF)<<16)|((c)&0xFFFF))); \
+ } \
+}
+
+/* As the 6554x doesn't support 24bpp colour expansion this doesn't work,
+ * It is here only for later use with the 65550 */
+#define ctSETFGCOLOR24(c) {\
+ HW_DEBUG(0x3); \
+ if ((cAcl->fgColor != (c)) || (cAcl->fgColor == -1)) { \
+ cAcl->fgColor = (c); \
+ MMIO_OUT32(cPtr->MMIOBase, MR(0x3),((c)&0xFFFFFF)); \
+ } \
+}
+
+/* Define a Macro to replicate a planemask 64 times and write to address
+ * allocated for planemask pattern */
+#define ctWRITEPLANEMASK8(mask,addr) { \
+ if (cAcl->planemask != (mask&0xFF)) { \
+ cAcl->planemask = (mask&0xFF); \
+ memset((unsigned char *)cPtr->FbBase + addr, (mask&0xFF), 64); \
+ } \
+}
+
+#define ctWRITEPLANEMASK16(mask,addr) { \
+ if (cAcl->planemask != (mask&0xFFFF)) { \
+ cAcl->planemask = (mask&0xFFFF); \
+ { int i; \
+ for (i = 0; i < 64; i++) { \
+ memcpy((unsigned char *)cPtr->FbBase + addr \
+ + i * 2, &mask, 2); \
+ } \
+ } \
+ } \
+}
diff --git a/src/ct_Blitter.h b/src/ct_Blitter.h
new file mode 100644
index 0000000..ecb84f1
--- /dev/null
+++ b/src/ct_Blitter.h
@@ -0,0 +1,168 @@
+/* $XConsortium: ct_Blitter.h /main/2 1996/10/25 10:28:37 kaleb $ */
+
+
+
+
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_Blitter.h,v 1.4 2002/01/25 21:55:58 tsi Exp $ */
+
+/* Definitions for the Chips and Technology BitBLT engine communication. */
+/* registers */
+/* Do not read 87D0 while BitBLT is active */
+/* 83D0: 11-0 source offset, width of 'screen' */
+/* 15-12 reserved (0) */
+/* 27-16 destination offset, width of screen */
+/* 31-28 reserved (0) */
+/* 87D0: 20-0 pattern (alinged 8 pixel x 8 line) pointer */
+/* 31-21 reserved (0) */
+/* 8BD0: 15-0 backgroud colour */
+/* 31-6 duplicate of 15-0 */
+/* 8FD0: 15-0 foregroud/solid colour */
+/* 31-6 duplicate of 15-0 */
+/* 93D0: 7-0 ROP, same as MS-Windows */
+/* 8 BitBLT Y direction, if 0 bottom to top, 1 top to bottom */
+/* 9 BitBLT X direction, if 0 right to left, 1 left to right */
+/* 10 source data, if 0 source is selected bit 14, 1 foregourd colour */
+/* 11 source depth, if 0 source is colour, */
+/* 1 source is monochrome(Font expansion) */
+/* 12 pattern depth, if 0 colour, else monochrome */
+/* 13 background, if 0 opaque (8BD0), else transparent */
+/* 14 BitBLT source, if 0 screen, else system memory */
+/* 15 reserved (0, destination?) */
+/* 18-16 starting row of 8x8 pattern */
+/* 19 if 1 solid pattern (Brush), else bitmap */
+/* 20(R) BitBLT status, if 1 active */
+/* 23-21 reserved (0) */
+/* 27-24 vacancy in buffer */
+/* 31-25 reserved (0) */
+/* 97D0: 20-0 source address (byte aligned) */
+/* 31-21 reserved (0) */
+/* 9BD0: 20-0 destination address (byte aligned) */
+/* 31-21 reserved (0) */
+/* 9FD0: 11-0 number of bytes to be transferred per line */
+/* 15-12 reserved (0) */
+/* 27-16 height in lines of the block to be transferred */
+/* 31-28 reserved (0) */
+
+/* BitBLT modes for register 93D0. */
+
+#define ctPATCOPY 0xF0
+#define ctTOP2BOTTOM 0x100
+#define ctBOTTOM2TOP 0x000
+#define ctLEFT2RIGHT 0x200
+#define ctRIGHT2LEFT 0x000
+#define ctSRCFG 0x400
+#define ctSRCMONO 0x800
+#define ctPATMONO 0x1000
+#define ctBGTRANSPARENT 0x2000
+#define ctSRCSYSTEM 0x4000
+#define ctPATSOLID 0x80000L
+#define ctPATSTART0 0x00000L
+#define ctPATSTART1 0x10000L
+#define ctPATSTART2 0x20000L
+#define ctPATSTART3 0x30000L
+#define ctPATSTART4 0x40000L
+#define ctPATSTART5 0x50000L
+#define ctPATSTART6 0x60000L
+#define ctPATSTART7 0x70000L
+
+/* Macros to do useful things with the C&T BitBLT engine */
+
+#define ctBLTWAIT \
+ {HW_DEBUG(0x4+2); while(inw(cPtr->PIOBase+DR(0x4)+2)&0x10){};}
+
+#define ctSETROP(op) \
+ {HW_DEBUG(0x4); outl(cPtr->PIOBase+DR(0x4),(op));}
+
+#define ctSETSRCADDR(srcAddr) \
+ {HW_DEBUG(0x5); outl(cPtr->PIOBase+DR(0x5),((srcAddr)&0x1FFFFFL));}
+
+#define ctSETDSTADDR(dstAddr) \
+ {HW_DEBUG(0x6); outl(cPtr->PIOBase+DR(0x6),((dstAddr)&0x1FFFFFL));}
+
+#define ctSETPITCH(srcPitch,dstPitch) \
+ {HW_DEBUG(0x0); outl(cPtr->PIOBase+DR(0x0),(((dstPitch)<<16)|(srcPitch)));}
+
+/* Note that this command signal a blit to commence */
+#define ctSETHEIGHTWIDTHGO(Height,Width)\
+ {HW_DEBUG(0x7); outl(cPtr->PIOBase+DR(0x7),(((Height)<<16)|(Width)));}
+
+#define ctSETPATSRCADDR(srcAddr)\
+ {HW_DEBUG(0x1); outl(cPtr->PIOBase+DR(0x1),((srcAddr)&0x1FFFFFL));}
+
+/* I can't help pointing out at this point that I'm not complaining
+ * about the american spelling of Colour!! [DGB] */
+
+#define ctSETBGCOLOR8(c) {\
+ HW_DEBUG(0x2); \
+ if ((cAcl->bgColor != (c)) || (cAcl->bgColor == -1)) { \
+ cAcl->bgColor = (c); \
+ outl(cPtr->PIOBase+DR(0x2),((((((c)&0xFF)<<8)|((c)&0xFF))<<16) | \
+ ((((c)&0xFF)<<8)|((c)&0xFF)))); \
+ } \
+}
+
+#define ctSETBGCOLOR16(c) {\
+ HW_DEBUG(0x2); \
+ if ((cAcl->bgColor != (c)) || (cAcl->bgColor == -1)) { \
+ cAcl->bgColor = (c); \
+ outl(cPtr->PIOBase+DR(0x2),((((c)&0xFFFF)<<16)|((c)&0xFFFF))); \
+ } \
+}
+
+/* As the 6554x doesn't support 24bpp colour expansion this doesn't work */
+#define ctSETBGCOLOR24(c) {\
+ HW_DEBUG(0x2); \
+ if ((cAcl->bgColor != (c)) || (cAcl->bgColor == -1)) { \
+ cAcl->bgColor = (c); \
+ outl(cPtr->PIOBase+DR(0x2),(c)&0xFFFFFF); \
+ } \
+}
+
+#define ctSETFGCOLOR8(c) {\
+ HW_DEBUG(0x3); \
+ if ((cAcl->fgColor != (c)) || (cAcl->fgColor == -1)) { \
+ cAcl->fgColor = (c); \
+ outl(cPtr->PIOBase+DR(0x3),((((((c)&0xFF)<<8)|((c)&0xFF))<<16) | \
+ ((((c)&0xFF)<<8)|((c)&0xFF)))); \
+ } \
+}
+
+#define ctSETFGCOLOR16(c) {\
+ HW_DEBUG(0x3); \
+ if ((cAcl->fgColor != (c)) || (cAcl->fgColor == -1)) { \
+ cAcl->fgColor = (c); \
+ outl(cPtr->PIOBase+DR(0x3),((((c)&0xFFFF)<<16)|((c)&0xFFFF))); \
+ } \
+}
+
+/* As the 6554x doesn't support 24bpp colour expansion this doesn't work */
+#define ctSETFGCOLOR24(c) {\
+ HW_DEBUG(0x3); \
+ if ((cAcl->fgColor != (c)) || (cAcl->fgColor == -1)) { \
+ cAcl->fgColor = (c); \
+ outl(cPtr->PIOBase+DR(0x3),(c)&0xFFFFFF); \
+ } \
+}
+
+/* Define a Macro to replicate a planemask 64 times and write to address
+ * allocated for planemask pattern */
+#define ctWRITEPLANEMASK8(mask,addr) { \
+ if (cAcl->planemask != (mask&0xFF)) { \
+ cAcl->planemask = (mask&0xFF); \
+ memset((unsigned char *)cPtr->FbBase + addr, (mask&0xFF), 64); \
+ } \
+}
+
+#define ctWRITEPLANEMASK16(mask,addr) { \
+ if (cAcl->planemask != (mask&0xFFFF)) { \
+ cAcl->planemask = (mask&0xFFFF); \
+ { int i; \
+ for (i = 0; i < 64; i++) { \
+ memcpy((unsigned char *)cPtr->FbBase + addr \
+ + i * 2, &mask, 2); \
+ } \
+ } \
+ } \
+}
+
diff --git a/src/ct_BltHiQV.h b/src/ct_BltHiQV.h
new file mode 100644
index 0000000..6f135bd
--- /dev/null
+++ b/src/ct_BltHiQV.h
@@ -0,0 +1,178 @@
+/* $XConsortium: ct_BltHiQV.h /main/2 1996/10/25 10:28:43 kaleb $ */
+
+
+
+
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_BltHiQV.h,v 1.12 2002/11/25 14:04:58 eich Exp $ */
+
+/* Definitions for the Chips and Technology BitBLT engine communication. */
+/* These are done using Memory Mapped IO, of the registers */
+/* BitBLT modes for register 93D0. */
+
+#define ctPATCOPY 0xF0
+#define ctLEFT2RIGHT 0x000
+#define ctRIGHT2LEFT 0x100
+#define ctTOP2BOTTOM 0x000
+#define ctBOTTOM2TOP 0x200
+#define ctSRCSYSTEM 0x400
+#define ctDSTSYSTEM 0x800
+#define ctSRCMONO 0x1000
+#define ctBGTRANSPARENT 0x22000
+#define ctCOLORTRANSENABLE 0x4000
+#define ctCOLORTRANSDISABLE 0x0
+#define ctCOLORTRANSDST 0x8000
+#define ctCOLORTRANSROP 0x0
+#define ctCOLORTRANSEQUAL 0x10000L
+#define ctCOLORTRANSNEQUAL 0x0
+#define ctPATMONO 0x40000L
+#define ctPATSOLID 0x80000L
+#define ctPATSTART0 0x000000L
+#define ctPATSTART1 0x100000L
+#define ctPATSTART2 0x200000L
+#define ctPATSTART3 0x300000L
+#define ctPATSTART4 0x400000L
+#define ctPATSTART5 0x500000L
+#define ctPATSTART6 0x600000L
+#define ctPATSTART7 0x700000L
+#define ctSRCFG 0x000000L /* Where is this for the 65550?? */
+
+/* The Monochrome expansion register setup */
+#define ctCLIPLEFT(clip) ((clip)&0x3F)
+#define ctCLIPRIGHT(clip) (((clip)&0x3F) << 8)
+#define ctSRCDISCARD(clip) (((clip)&0x3F) << 16)
+#define ctBITALIGN 0x1000000L
+#define ctBYTEALIGN 0x2000000L
+#define ctWORDALIGN 0x3000000L
+#define ctDWORDALIGN 0x4000000L
+#define ctQWORDALIGN 0x5000000L
+/* This shouldn't be used because not all chip rev's
+ * have BR09 and BR0A, and I haven't even defined
+ * macros to write to these registers
+ */
+#define ctEXPCOLSEL 0x8000000L
+
+/* Macros to do useful things with the C&T BitBLT engine */
+
+/* For some odd reason the blitter busy bit occasionly "locks up" when
+ * it gets polled to fast. However I have observed this behavior only
+ * when doing ScreenToScreenColorExpandFill on a 65550. This operation
+ * was broken anyway (the source offest register is not observed) therefore
+ * no action was taken.
+ *
+ * This function uses indirect access to XR20 to test whether the blitter
+ * is busy. If the cost of doing this is too high then other options will
+ * need to be considered.
+ *
+ * Note that BR04[31] can't be used as some C&T chipsets lockup when reading
+ * the BRxx registers.
+ */
+#define ctBLTWAIT \
+ {int timeout; \
+ timeout = 0; \
+ for (;;) { \
+ if (cPtr->Chipset >= CHIPS_CT69000 ) { \
+ if (!(MMIO_IN32(cPtr->MMIOBase,BR(0x4))&(1<<31)))\
+ break; \
+ } else { \
+ if (!(cPtr->readXR(cPtr,0x20) & 0x1)) break; \
+ } \
+ timeout++; \
+ if ((cPtr->Chipset < CHIPS_CT69000 && \
+ (timeout > 100000)) || timeout > 300000) { \
+ unsigned char tmp; \
+ ErrorF("timeout\n"); \
+ tmp = cPtr->readXR(cPtr, 0x20); \
+ cPtr->writeXR(cPtr, 0x20, ((tmp & 0xFD) | 0x2)); \
+ xf86UDelay(10000); \
+ cPtr->writeXR(cPtr, 0x20, (tmp & 0xFD)); \
+ break; \
+ } \
+ } \
+ }
+
+#define ctSETROP(op) \
+ MMIO_OUT32(cPtr->MMIOBase, BR(0x4), op)
+
+#define ctSETMONOCTL(op) \
+ MMIO_OUT32(cPtr->MMIOBase, BR(0x3), op)
+
+#define ctSETSRCADDR(srcAddr) \
+ MMIO_OUT32(cPtr->MMIOBase, BR(0x6), (srcAddr)&0x7FFFFFL)
+
+#define ctSETDSTADDR(dstAddr) \
+ MMIO_OUT32(cPtr->MMIOBase, BR(0x7), (dstAddr)&0x7FFFFFL)
+
+#define ctSETPITCH(srcPitch,dstPitch) \
+ MMIO_OUT32(cPtr->MMIOBase, BR(0x0), (((dstPitch)&0xFFFF)<<16)| \
+ ((srcPitch)&0xFFFF))
+
+#define ctSETHEIGHTWIDTHGO(Height,Width)\
+ MMIO_OUT32(cPtr->MMIOBase, BR(0x8), (((Height)&0xFFFF)<<16)| \
+ ((Width)&0xFFFF))
+
+#define ctSETPATSRCADDR(srcAddr)\
+ MMIO_OUT32(cPtr->MMIOBase, BR(0x5), (srcAddr)&0x7FFFFFL)
+
+#define ctSETBGCOLOR8(c) {\
+ if ((cAcl->bgColor != (c)) || (cAcl->bgColor == -1)) { \
+ cAcl->bgColor = (c); \
+ MMIO_OUT32(cPtr->MMIOBase, BR(0x1), ((c)&0xFF)); \
+ } \
+}
+
+#define ctSETBGCOLOR16(c) {\
+ if ((cAcl->bgColor != (c)) || (cAcl->bgColor == -1)) { \
+ cAcl->bgColor = (c); \
+ MMIO_OUT32(cPtr->MMIOBase, BR(0x1), ((c)&0xFFFF)); \
+ } \
+}
+
+#define ctSETBGCOLOR24(c) {\
+ if ((cAcl->bgColor != (c)) || (cAcl->bgColor == -1)) { \
+ cAcl->bgColor = (c); \
+ MMIO_OUT32(cPtr->MMIOBase, BR(0x1), ((c)&0xFFFFFF)); \
+ } \
+}
+
+#define ctSETFGCOLOR8(c) {\
+ if ((cAcl->fgColor != (c)) || (cAcl->fgColor == -1)) { \
+ cAcl->fgColor = (c); \
+ MMIO_OUT32(cPtr->MMIOBase, BR(0x2), ((c)&0xFF)); \
+ } \
+}
+
+#define ctSETFGCOLOR16(c) {\
+ if ((cAcl->fgColor != (c)) || (cAcl->fgColor == -1)) { \
+ cAcl->fgColor = (c); \
+ MMIO_OUT32(cPtr->MMIOBase, BR(0x2), ((c)&0xFFFF)); \
+ } \
+}
+
+#define ctSETFGCOLOR24(c) {\
+ if ((cAcl->fgColor != (c)) || (cAcl->fgColor == -1)) { \
+ cAcl->fgColor = (c); \
+ MMIO_OUT32(cPtr->MMIOBase, BR(0x2), ((c)&0xFFFFFF)); \
+ } \
+}
+
+/* Define a Macro to replicate a planemask 64 times and write to address
+ * allocated for planemask pattern */
+#define ctWRITEPLANEMASK8(mask,addr) { \
+ if (cAcl->planemask != (mask&0xFF)) { \
+ cAcl->planemask = (mask&0xFF); \
+ memset((unsigned char *)cPtr->FbBase + addr, (mask&0xFF), 64); \
+ } \
+}
+
+#define ctWRITEPLANEMASK16(mask,addr) { \
+ if (cAcl->planemask != (mask&0xFFFF)) { \
+ cAcl->planemask = (mask&0xFFFF); \
+ { int i; \
+ for (i = 0; i < 64; i++) { \
+ memcpy((unsigned char *)cPtr->FbBase + addr \
+ + i * 2, &mask, 2); \
+ } \
+ } \
+ } \
+}
diff --git a/src/ct_accel.c b/src/ct_accel.c
new file mode 100644
index 0000000..d936291
--- /dev/null
+++ b/src/ct_accel.c
@@ -0,0 +1,1737 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_accel.c,v 1.40 2002/11/25 14:04:58 eich Exp $ */
+/*
+ * Copyright 1996, 1997, 1998 by David Bateman <dbateman@ee.uts.edu.au>
+ * Modified 1997, 1998 by Nozomi Ytow
+ *
+ * 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 the authors not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHORS 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.
+ */
+
+/*
+ * When monochrome tiles/stipples are cached on the HiQV chipsets the
+ * pitch of the monochrome data is the displayWidth. The HiQV manuals
+ * state that the source pitch is ignored with monochrome data, and so
+ * "offically" there the XAA cached monochrome data can't be used. But
+ * it appears that by not setting the monochrome source alignment in
+ * BR03, the monochrome source pitch is forced to the displayWidth!!
+ *
+ * To enable the use of this undocumented feature, uncomment the define
+ * below.
+ */
+#define UNDOCUMENTED_FEATURE
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that use XAA need this */
+#include "xf86fbman.h"
+
+/* Our driver specific include file */
+#include "ct_driver.h"
+
+#if !defined(UNIXCPP) || defined(ANSICPP)
+#define CATNAME(prefix,subname) prefix##subname
+#else
+#define CATNAME(prefix,subname) prefix/**/subname
+#endif
+
+#ifdef CHIPS_MMIO
+#ifdef CHIPS_HIQV
+#include "ct_BltHiQV.h"
+#define CTNAME(subname) CATNAME(CHIPSHiQV,subname)
+#else
+#include "ct_BlitMM.h"
+#define CTNAME(subname) CATNAME(CHIPSMMIO,subname)
+#endif
+#else
+#include "ct_Blitter.h"
+#define CTNAME(subname) CATNAME(CHIPS,subname)
+#endif
+
+#ifdef DEBUG
+# define DEBUG_P(x) ErrorF(x"\n");
+#elif defined X_DEBUG
+# define DEBUG_P(x) snprintf(CTNAME(accel_debug),1024,x"\n");
+#else
+# define DEBUG_P(x) /**/
+#endif
+
+#ifdef X_DEBUG
+static char CTNAME(accel_debug)[1024];
+#endif
+
+#ifdef CHIPS_HIQV
+static void CTNAME(DepthChange)(ScrnInfoPtr pScrn, int depth);
+#endif
+static void CTNAME(8SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void CTNAME(16SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void CTNAME(24SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void CTNAME(SubsequentSolidFillRect)(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h);
+#ifndef CHIPS_HIQV
+static void CTNAME(24SubsequentSolidFillRect)(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h);
+#else
+static void CTNAME(32SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void CTNAME(32SubsequentSolidFillRect)(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h);
+#endif
+static void CTNAME(SetupForScreenToScreenCopy)(ScrnInfoPtr pScrn, int xdir,
+ int ydir, int rop, unsigned int planemask,
+ int trans);
+static void CTNAME(SubsequentScreenToScreenCopy)(ScrnInfoPtr pScrn,
+ int srcX, int srcY, int dstX, int dstY,
+ int w, int h);
+static void CTNAME(SetupForCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn, int fg,
+ int bg, int rop, unsigned int planemask);
+static void CTNAME(SubsequentCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft);
+#ifndef CHIPS_HIQV
+static XAACacheInfoPtr CTNAME(CacheMonoStipple)(ScrnInfoPtr pScrn,
+ PixmapPtr pPix);
+#endif
+#if !defined(CHIPS_HIQV) || defined(UNDOCUMENTED_FEATURE)
+static void CTNAME(SetupForScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void CTNAME(SubsequentScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int srcx, int srcy, int skipleft);
+#endif
+static void CTNAME(SetupForMono8x8PatternFill)(ScrnInfoPtr pScrn,
+ int patx, int paty, int fg, int bg,
+ int rop, unsigned int planemask);
+static void CTNAME(SubsequentMono8x8PatternFillRect)(ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int x, int y, int w, int h );
+static void CTNAME(SetupForColor8x8PatternFill)(ScrnInfoPtr pScrn,
+ int patx, int paty, int rop,
+ unsigned int planemask, int trans);
+static void CTNAME(SubsequentColor8x8PatternFillRect)(ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int x, int y, int w, int h );
+#ifndef CHIPS_HIQV
+static void CTNAME(SetupForImageWrite)(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask,
+ int transparency_color, int bpp, int depth);
+static void CTNAME(SubsequentImageWriteRect)(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft);
+#else
+static void CTNAME(WritePixmap)(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int rop,
+ unsigned int planemask, int trans, int bpp, int depth);
+#if 0
+static void CTNAME(ReadPixmap)(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *dst, int dstwidth, int bpp, int depth);
+#endif
+#endif
+
+
+Bool
+CTNAME(AccelInit)(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ DEBUG_P("AccelInit");
+ cPtr->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if(!infoPtr) return FALSE;
+
+ /*
+ * Setup some global variables
+ */
+ cAcl->BytesPerPixel = pScrn->bitsPerPixel >> 3;
+ cAcl->BitsPerPixel = pScrn->bitsPerPixel;
+ cAcl->PitchInBytes = pScrn->displayWidth * cAcl->BytesPerPixel;
+ cAcl->planemask = -1;
+ cAcl->bgColor = -1;
+ cAcl->fgColor = -1;
+ cAcl->FbOffset = 0;
+
+ /*
+ * Set up the main acceleration flags.
+ */
+ if (cAcl->CacheEnd > cAcl->CacheStart) infoPtr->Flags = PIXMAP_CACHE;
+
+ if (cPtr->Flags & ChipsLinearSupport)
+ infoPtr->Flags |= OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER;
+
+ infoPtr->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES;
+
+ /*
+ * The following line installs a "Sync" function, that waits for
+ * all coprocessor operations to complete.
+ */
+ infoPtr->Sync = CTNAME(Sync);
+
+ /*
+ * Setup a Screen to Screen copy (BitBLT) primitive
+ */
+#ifndef CHIPS_HIQV
+ infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY;
+ if (cAcl->BitsPerPixel == 24)
+ infoPtr->ScreenToScreenCopyFlags |= NO_PLANEMASK;
+#else
+ infoPtr->ScreenToScreenCopyFlags = 0;
+ if ((cAcl->BitsPerPixel == 24) || (cAcl->BitsPerPixel == 32))
+ infoPtr->ScreenToScreenCopyFlags |= NO_PLANEMASK;
+
+ /* A Chips and Technologies application notes says that some
+ * 65550 have a bug that prevents 16bpp transparency. It probably
+ * applies to 24 bpp as well (Someone with a 65550 care to check?).
+ * Selection of this controlled in Probe.
+ */
+ if (!(cPtr->Flags & ChipsColorTransparency))
+ infoPtr->ScreenToScreenCopyFlags |= NO_TRANSPARENCY;
+#endif
+
+ infoPtr->SetupForScreenToScreenCopy = CTNAME(SetupForScreenToScreenCopy);
+ infoPtr->SubsequentScreenToScreenCopy =
+ CTNAME(SubsequentScreenToScreenCopy);
+
+ /*
+ * Install the low-level functions for drawing solid filled rectangles.
+ */
+ infoPtr->SolidFillFlags |= NO_PLANEMASK;
+ switch (cAcl->BitsPerPixel) {
+ case 8 :
+ infoPtr->SetupForSolidFill = CTNAME(8SetupForSolidFill);
+ infoPtr->SubsequentSolidFillRect = CTNAME(SubsequentSolidFillRect);
+ break;
+ case 16 :
+ infoPtr->SetupForSolidFill = CTNAME(16SetupForSolidFill);
+ infoPtr->SubsequentSolidFillRect = CTNAME(SubsequentSolidFillRect);
+ break;
+ case 24 :
+ infoPtr->SetupForSolidFill = CTNAME(24SetupForSolidFill);
+#ifdef CHIPS_HIQV
+ infoPtr->SubsequentSolidFillRect = CTNAME(SubsequentSolidFillRect);
+#else
+ /*
+ * The version of this function here uses three different
+ * algorithms in an attempt to maximise performance. One
+ * for RGB_EQUAL, another for !RGB_EQUAL && GXCOPY_ONLY
+ * and yet another for !RGB_EQUAL && !GXCOPY_ONLY. The
+ * first two versions use the 8bpp engine for the fill,
+ * whilst the second uses a framebuffer routine to create
+ * one scanline of the fill in off screen memory which is
+ * then used by a CopyArea function with a complex ROP.
+ */
+ infoPtr->SubsequentSolidFillRect = CTNAME(24SubsequentSolidFillRect);
+ if (cAcl->ScratchAddress < 0)
+ infoPtr->ScreenToScreenCopyFlags |= GXCOPY_ONLY;
+#endif
+ break;
+#ifdef CHIPS_HIQV
+ case 32:
+ if (cAcl->ScratchAddress > 0) {
+ infoPtr->SetupForSolidFill = CTNAME(32SetupForSolidFill);
+ infoPtr->SubsequentSolidFillRect =
+ CTNAME(32SubsequentSolidFillRect);
+ }
+ break;
+#endif
+ }
+
+#ifdef CHIPS_HIQV
+ /* At 32bpp we can't use the other acceleration */
+ if (cAcl->BitsPerPixel == 32) goto chips_imagewrite;
+#endif
+
+ /*
+ * Setup the functions that perform monochrome colour expansion
+ */
+
+#ifdef CHIPS_HIQV
+ infoPtr->CPUToScreenColorExpandFillFlags =
+ BIT_ORDER_IN_BYTE_MSBFIRST | CPU_TRANSFER_PAD_QWORD |
+ LEFT_EDGE_CLIPPING | LEFT_EDGE_CLIPPING_NEGATIVE_X |
+ ROP_NEEDS_SOURCE;
+#ifdef UNDOCUMENTED_FEATURE
+ infoPtr->ScreenToScreenColorExpandFillFlags = BIT_ORDER_IN_BYTE_MSBFIRST
+ | LEFT_EDGE_CLIPPING;
+#endif
+ if (cAcl->BitsPerPixel == 24) {
+ infoPtr->CPUToScreenColorExpandFillFlags |= NO_PLANEMASK;
+#ifdef UNDOCUMENTED_FEATURE
+ infoPtr->ScreenToScreenColorExpandFillFlags |= NO_PLANEMASK;
+#endif
+ }
+ /* The ct65550 has problems with transparency which leads to video
+ * corruption unless disabled.
+ */
+ if (!(cPtr->Flags & ChipsColorTransparency)) {
+ infoPtr->CPUToScreenColorExpandFillFlags |= NO_TRANSPARENCY;
+#ifdef UNDOCUMENTED_FEATURE
+ infoPtr->ScreenToScreenColorExpandFillFlags |= NO_TRANSPARENCY;
+#endif
+ }
+#else
+ infoPtr->CPUToScreenColorExpandFillFlags =
+ BIT_ORDER_IN_BYTE_MSBFIRST | CPU_TRANSFER_PAD_DWORD |
+ ROP_NEEDS_SOURCE;
+ infoPtr->ScreenToScreenColorExpandFillFlags = BIT_ORDER_IN_BYTE_MSBFIRST;
+ infoPtr->CacheColorExpandDensity = 8;
+
+ if (cAcl->BitsPerPixel == 24)
+ infoPtr->CPUToScreenColorExpandFillFlags |= TRIPLE_BITS_24BPP |
+ RGB_EQUAL | NO_PLANEMASK;
+#endif
+
+ infoPtr->SetupForCPUToScreenColorExpandFill =
+ CTNAME(SetupForCPUToScreenColorExpandFill);
+ infoPtr->SubsequentCPUToScreenColorExpandFill =
+ CTNAME(SubsequentCPUToScreenColorExpandFill);
+
+#ifndef CHIPS_HIQV
+ if (cAcl->BitsPerPixel != 24) {
+#endif
+#if !defined(CHIPS_HIQV) || defined(UNDOCUMENTED_FEATURE)
+ infoPtr->SetupForScreenToScreenColorExpandFill =
+ CTNAME(SetupForScreenToScreenColorExpandFill);
+ infoPtr->SubsequentScreenToScreenColorExpandFill =
+ CTNAME(SubsequentScreenToScreenColorExpandFill);
+#endif
+#ifndef CHIPS_HIQV
+ infoPtr->CacheMonoStipple = CTNAME(CacheMonoStipple);
+ }
+#endif
+
+ infoPtr->ColorExpandBase = (unsigned char *)cAcl->BltDataWindow;
+ infoPtr->ColorExpandRange = 64 * 1024;
+
+ /* Mono 8x8 pattern fills */
+ infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK |
+ BIT_ORDER_IN_BYTE_MSBFIRST | HARDWARE_PATTERN_SCREEN_ORIGIN;
+
+#ifdef CHIPS_HIQV
+ infoPtr->SetupForMono8x8PatternFill =
+ CTNAME(SetupForMono8x8PatternFill);
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ CTNAME(SubsequentMono8x8PatternFillRect);
+ if (cAcl->BitsPerPixel == 24)
+ infoPtr->MonoPatternPitch = 8; /* Need 8 byte alignment */
+#else
+ if (cAcl->BitsPerPixel != 24) {
+ infoPtr->SetupForMono8x8PatternFill =
+ CTNAME(SetupForMono8x8PatternFill);
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ CTNAME(SubsequentMono8x8PatternFillRect);
+ }
+#endif
+
+ /* Color 8x8 pattern fills, must have a displayWidth divisible by 64 */
+ if (!(pScrn->displayWidth % 64)) {
+#ifdef CHIPS_HIQV
+ infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK |
+ HARDWARE_PATTERN_SCREEN_ORIGIN;
+ if (!(cPtr->Flags & ChipsColorTransparency))
+ infoPtr->Color8x8PatternFillFlags |= NO_TRANSPARENCY;
+#else
+ infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK |
+ HARDWARE_PATTERN_SCREEN_ORIGIN | NO_TRANSPARENCY;
+#endif
+
+ if (cAcl->BitsPerPixel != 24) {
+ infoPtr->SetupForColor8x8PatternFill =
+ CTNAME(SetupForColor8x8PatternFill);
+ infoPtr->SubsequentColor8x8PatternFillRect =
+ CTNAME(SubsequentColor8x8PatternFillRect);
+ }
+ }
+
+#ifdef CHIPS_HIQV
+chips_imagewrite:
+#endif
+
+ /* Setup for the Image Write functions */
+#ifdef CHIPS_HIQV
+ infoPtr->WritePixmapFlags = CPU_TRANSFER_PAD_QWORD | LEFT_EDGE_CLIPPING
+ | LEFT_EDGE_CLIPPING_NEGATIVE_X | ROP_NEEDS_SOURCE;
+
+ if (!(cPtr->Flags & ChipsColorTransparency))
+ infoPtr->WritePixmapFlags |= NO_TRANSPARENCY;
+ if ((cAcl->BitsPerPixel == 24) || (cAcl->BitsPerPixel == 32))
+ infoPtr->WritePixmapFlags |= NO_PLANEMASK;
+
+ infoPtr->WritePixmap = CTNAME(WritePixmap);
+#if 0 /* Not used by XAA as yet, but coming soon */
+ if (cPtr->Flags & ChipsImageReadSupport) {
+ infoPtr->ReadPixmapFlags = CPU_TRANSFER_PAD_QWORD | ROP_NEEDS_SOURCE;
+ infoPtr->ReadPixmap = CTNAME(ReadPixmap);
+ }
+#endif
+
+#else
+ infoPtr->SetupForImageWrite = CTNAME(SetupForImageWrite);
+ infoPtr->SubsequentImageWriteRect = CTNAME(SubsequentImageWriteRect);
+ infoPtr->ImageWriteBase = (unsigned char *)cAcl->BltDataWindow;
+ infoPtr->ImageWriteRange = 64 * 1024;
+ infoPtr->ImageWriteFlags = NO_TRANSPARENCY | CPU_TRANSFER_PAD_DWORD
+ | ROP_NEEDS_SOURCE;
+ if ((cAcl->BitsPerPixel == 24) || (cAcl->BitsPerPixel == 32))
+ infoPtr->ImageWriteFlags |= NO_PLANEMASK;
+#endif
+
+
+#ifdef CHIPS_HIQV
+ if (XAAInit(pScreen, infoPtr)) {
+ if (cPtr->Flags & ChipsOverlay8plus16)
+ return(XAAInitDualFramebufferOverlay(pScreen,
+ CTNAME(DepthChange)));
+ else
+ return TRUE;
+ } else
+ return FALSE;
+#else
+ return(XAAInit(pScreen, infoPtr));
+#endif
+}
+
+#ifdef CHIPS_HIQV
+void
+CTNAME(DepthChange)(ScrnInfoPtr pScrn, int depth)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ unsigned char mode;
+
+ DEBUG_P("DepthChange");
+ switch (depth) {
+ case 8 :
+ cPtr->AccelInfoRec->SetupForSolidFill = CTNAME(8SetupForSolidFill);
+ mode = 0x00; /* BitBLT engine to 8bpp */
+ cAcl->BytesPerPixel = 1;
+ cAcl->FbOffset = 0;
+ cAcl->BitsPerPixel = 8;
+ break;
+ default :
+ cPtr->AccelInfoRec->SetupForSolidFill = CTNAME(16SetupForSolidFill);
+ mode = 0x10; /* BitBLT engine to 16bpp */
+ cAcl->BytesPerPixel = 2;
+ cAcl->FbOffset = cPtr->FbOffset16;
+ cAcl->BitsPerPixel = 16;
+ break;
+ }
+ cAcl->PitchInBytes = pScrn->displayWidth * cAcl->BytesPerPixel;
+ ctBLTWAIT;
+ cPtr->writeXR(cPtr, 0x20, mode); /* Change BitBLT engine mode */
+}
+#endif
+
+void
+CTNAME(Sync)(ScrnInfoPtr pScrn)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ DEBUG_P("sync");
+ ctBLTWAIT;
+}
+
+static void
+CTNAME(8SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ DEBUG_P("8SetupForSolidFill");
+ ctBLTWAIT;
+ ctSETBGCOLOR8(color);
+ ctSETFGCOLOR8(color);
+ ctSETROP(ChipsAluConv2[rop & 0xF] | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ctPATSOLID | ctPATMONO);
+ ctSETPITCH(0, cAcl->PitchInBytes);
+}
+
+static void
+CTNAME(16SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ DEBUG_P("16SetupForSolidFill");
+ ctBLTWAIT;
+ ctSETBGCOLOR16(color);
+ ctSETFGCOLOR16(color);
+ ctSETROP(ChipsAluConv2[rop & 0xF] | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ctPATSOLID | ctPATMONO);
+ ctSETPITCH(0, cAcl->PitchInBytes);
+}
+
+#ifdef CHIPS_HIQV
+static void
+CTNAME(24SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ DEBUG_P("24SetupForSolidFill");
+ ctBLTWAIT;
+ ctSETBGCOLOR24(color);
+ ctSETFGCOLOR24(color);
+ ctSETROP(ChipsAluConv2[rop & 0xF] | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ctPATSOLID | ctPATMONO);
+ ctSETPITCH(0, cAcl->PitchInBytes);
+}
+
+static void
+CTNAME(32SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ DEBUG_P("32SetupForSolidFill");
+ ctBLTWAIT;
+ memset((unsigned char *)cPtr->FbBase + cAcl->ScratchAddress, 0xAA, 8);
+ ctSETFGCOLOR16((color & 0xFFFF));
+ ctSETBGCOLOR16(((color >> 16) & 0xFFFF));
+ ctSETROP(ChipsAluConv2[rop & 0xF] | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ctPATMONO);
+ ctSETPATSRCADDR(cAcl->ScratchAddress);
+ ctSETPITCH(1, cAcl->PitchInBytes);
+}
+
+static void
+CTNAME(32SubsequentSolidFillRect)(ScrnInfoPtr pScrn, int x, int y, int w,
+ int h)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ unsigned int destaddr;
+ destaddr = (y * pScrn->displayWidth + x) << 2;
+ w <<= 2;
+ DEBUG_P("32SubsequentSolidFillRect");
+ ctBLTWAIT;
+ ctSETDSTADDR(destaddr);
+ ctSETHEIGHTWIDTHGO(h, w);
+}
+#else
+
+static void
+CTNAME(24SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ unsigned char pixel1, pixel2, pixel3;
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ DEBUG_P("24SetupForSolidFill");
+ cAcl->rgb24equal = (((((color & 0xFF) == ((color & 0xFF00) >> 8)) &&
+ ((color & 0xFF) == ((color & 0xFF0000) >> 16)))) ||
+ /* Check the rop for paranoid reasons */
+ (rop == GXclear) || (rop == GXnoop) ||
+ (rop == GXinvert) || (rop == GXset));
+ if (cAcl->rgb24equal) {
+ cAcl->CommandFlags = ChipsAluConv2[rop & 0xF] | ctTOP2BOTTOM |
+ ctLEFT2RIGHT | ctPATSOLID | ctPATMONO;
+ ctBLTWAIT;
+ ctSETFGCOLOR8(color&0xFF);
+ ctSETBGCOLOR8(color&0xFF);
+ ctSETPITCH(0, cAcl->PitchInBytes);
+ } else {
+ cAcl->rop24bpp = rop;
+ if (rop == GXcopy) {
+ pixel3 = color & 0xFF;
+ pixel2 = (color >> 8) & 0xFF;
+ pixel1 = (color >> 16) & 0xFF;
+ cAcl->fgpixel = pixel1;
+ cAcl->bgpixel = pixel2;
+ cAcl->fillindex = 0;
+ cAcl->fastfill = FALSE;
+
+ /* Test for the special case where two of the byte of the
+ * 24bpp colour are the same. This can double the speed
+ */
+ if (pixel1 == pixel2) {
+ cAcl->fgpixel = pixel3;
+ cAcl->bgpixel = pixel1;
+ cAcl->fastfill = TRUE;
+ cAcl->fillindex = 1;
+ } else if (pixel1 == pixel3) {
+ cAcl->fgpixel = pixel2;
+ cAcl->bgpixel = pixel1;
+ cAcl->fastfill = TRUE;
+ cAcl->fillindex = 2;
+ } else if (pixel2 == pixel3) {
+ cAcl->fastfill = TRUE;
+ } else {
+ cAcl->xorpixel = pixel2 ^ pixel3;
+ }
+
+ cAcl->CommandFlags = ctSRCMONO | ctSRCSYSTEM | ctTOP2BOTTOM |
+ ctLEFT2RIGHT;
+ ctBLTWAIT;
+ if (cAcl->fastfill) {
+ ctSETFGCOLOR8(cAcl->fgpixel);
+ }
+ ctSETBGCOLOR8(cAcl->bgpixel);
+ ctSETSRCADDR(0);
+ ctSETPITCH(0, cAcl->PitchInBytes);
+ } else {
+ if (cAcl->color24bpp != color) {
+ cAcl->color24bpp = color;
+ cAcl->width24bpp = 0;
+ }
+ cAcl->rop24bpp = rop;
+ ctBLTWAIT;
+ ctSETROP(ctTOP2BOTTOM | ctLEFT2RIGHT | ChipsAluConv[rop & 0xF]);
+ ctSETPITCH(cAcl->PitchInBytes, cAcl->PitchInBytes);
+ }
+ }
+}
+
+static void
+CTNAME(24SubsequentSolidFillRect)(ScrnInfoPtr pScrn, int x, int y, int w,
+ int h)
+{
+ static unsigned int dwords[3] = { 0x24499224, 0x92244992, 0x49922449};
+ int srcaddr, destaddr, line, i;
+ register int width;
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ DEBUG_P("24SubsequentSolidFillRect");
+ if (cAcl->rgb24equal) {
+ destaddr = y * pScrn->displayWidth + x;
+ destaddr += destaddr << 1;
+ ctBLTWAIT;
+ ctSETROP(cAcl->CommandFlags);
+ ctSETDSTADDR(destaddr);
+ ctSETHEIGHTWIDTHGO(h, (w + (w << 1)));
+ } else {
+ if (cAcl->rop24bpp == GXcopy ) {
+ unsigned int *base = (unsigned int *)cAcl->BltDataWindow;
+ destaddr = y * cAcl->PitchInBytes + x * 3;
+ w *= 3;
+ width = ((w + 31) & ~31) >> 5;
+
+ ctBLTWAIT;
+ ctSETDSTADDR(destaddr);
+
+ if (!cAcl->fastfill) ctSETFGCOLOR8(cAcl->fgpixel);
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv[GXcopy & 0xF]);
+ ctSETDSTADDR(destaddr);
+ if (cAcl->fastfill) {
+ ctSETHEIGHTWIDTHGO(h, w);
+ line = 0;
+ while (line < h) {
+ base = (unsigned int *)cAcl->BltDataWindow;
+ for (i = 0; i < width; i++) {
+ *base++ = dwords[((cAcl->fillindex + i) % 3)];
+ }
+ line++;
+ }
+ } else {
+ ctSETHEIGHTWIDTHGO(1, w);
+ i = 0;
+ while(i < width){
+ *base++ = dwords[(i++ % 3)];
+ }
+ for(line = 0; (h >> line ) > 1; line++){;}
+ i = 0;
+ ctBLTWAIT;
+ ctSETFGCOLOR8(cAcl->xorpixel);
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv[GXxor & 0xF] |
+ ctBGTRANSPARENT);
+ ctSETDSTADDR(destaddr);
+ ctSETHEIGHTWIDTHGO(1, w);
+ base = (unsigned int *)cAcl->BltDataWindow;
+ while(i < width) {
+ *base++ = dwords[((++i) % 3)];
+ }
+ srcaddr = destaddr;
+ if(line){
+ i = 0;
+ ctBLTWAIT;
+ ctSETROP(ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv[GXcopy & 0xF]);
+ ctSETPITCH(cAcl->PitchInBytes, cAcl->PitchInBytes);
+ ctSETSRCADDR(srcaddr);
+
+ while(i < line){
+ destaddr = srcaddr + (cAcl->PitchInBytes << i);
+ ctBLTWAIT;
+ ctSETDSTADDR(destaddr);
+ ctSETHEIGHTWIDTHGO((1 << i), w);
+ i++;
+ }
+
+ if((1 << line) < h){
+ destaddr = srcaddr + (cAcl->PitchInBytes << line);
+ ctBLTWAIT;
+ ctSETDSTADDR(destaddr);
+ ctSETHEIGHTWIDTHGO(h-(1 << line), w);
+ }
+
+ ctBLTWAIT;
+ ctSETROP(ctSRCMONO | ctSRCSYSTEM | ctTOP2BOTTOM |
+ ctLEFT2RIGHT | ChipsAluConv[GXcopy & 0xF]);
+ ctSETSRCADDR(0);
+ ctSETPITCH(0, cAcl->PitchInBytes);
+ }
+ }
+ } else {
+ register unsigned char *base;
+ if (cAcl->width24bpp < w) {
+ base = (unsigned char *)cPtr->FbBase + cAcl->ScratchAddress +
+ ((3 * cAcl->width24bpp + 3) & ~0x3);
+ width = w - cAcl->width24bpp;
+ ctBLTWAIT;
+ /* Load of a single scanline into framebuffer */
+ while (width > 0) {
+ *(unsigned int *)base = cAcl->color24bpp |
+ (cAcl->color24bpp << 24);
+ *(unsigned int *)(base + 4) = (cAcl->color24bpp >> 8) |
+ (cAcl->color24bpp << 16);
+ *(unsigned int *)(base + 8) = (cAcl->color24bpp >> 16) |
+ (cAcl->color24bpp << 8);
+ base += 12;
+ width -= 4;
+ }
+ cAcl->width24bpp = w - width;
+ }
+ line = 0;
+ destaddr = 3 * (y * pScrn->displayWidth + x);
+ w *= cAcl->BytesPerPixel;
+ while (line < h) {
+ ctBLTWAIT;
+ ctSETSRCADDR(cAcl->ScratchAddress);
+ ctSETDSTADDR(destaddr);
+ ctSETHEIGHTWIDTHGO(1, w);
+ destaddr += (3 * pScrn->displayWidth);
+ line++;
+ }
+ }
+ }
+}
+#endif
+
+static void
+CTNAME(SubsequentSolidFillRect)(ScrnInfoPtr pScrn, int x, int y, int w,
+ int h)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ int destaddr;
+
+ DEBUG_P("SubsequentSolidFillRect");
+ destaddr = (y * pScrn->displayWidth + x) * cAcl->BytesPerPixel;
+#ifdef CHIPS_HIQV
+ destaddr += cAcl->FbOffset;
+#endif
+ w *= cAcl->BytesPerPixel;
+ ctBLTWAIT;
+ ctSETDSTADDR(destaddr);
+ ctSETHEIGHTWIDTHGO(h, w);
+}
+
+/*
+ * Screen-to-screen BitBLT.
+ *
+ */
+
+static void
+CTNAME(SetupForScreenToScreenCopy)(ScrnInfoPtr pScrn, int xdir, int ydir,
+ int rop, unsigned int planemask, int trans)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ DEBUG_P("SetupForScreenToScreenCopy");
+ cAcl->CommandFlags = 0;
+
+ /* Set up the blit direction. */
+ if (ydir < 0)
+ cAcl->CommandFlags |= ctBOTTOM2TOP;
+ else
+ cAcl->CommandFlags |= ctTOP2BOTTOM;
+ if (xdir < 0)
+ cAcl->CommandFlags |= ctRIGHT2LEFT;
+ else
+ cAcl->CommandFlags |= ctLEFT2RIGHT;
+#ifdef CHIPS_HIQV
+ if (trans != -1) {
+ cAcl->CommandFlags |= ctCOLORTRANSENABLE | ctCOLORTRANSROP |
+ ctCOLORTRANSNEQUAL;
+ ctBLTWAIT;
+ /* BR03[0x27] sometimes set after reset, so must ensure it is zero */
+ ctSETMONOCTL(ctDWORDALIGN);
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ ctSETBGCOLOR8(trans);
+ break;
+ case 16:
+ ctSETBGCOLOR16(trans);
+ break;
+ case 24:
+ ctSETBGCOLOR24(trans);
+ break;
+ }
+ } else
+#endif
+ ctBLTWAIT;
+ switch (cAcl->BitsPerPixel) {
+#if 0
+ case 8:
+ if ((planemask & 0xFF) == 0xFF) {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
+ } else {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv3[rop & 0xF]);
+ ctSETPATSRCADDR(cAcl->ScratchAddress);
+ ctWRITEPLANEMASK8(planemask, cAcl->ScratchAddress);
+ }
+ break;
+ case 16:
+ if ((planemask & 0xFFFF) == 0xFFFF) {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
+ } else {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv3[rop & 0xF]);
+ ctSETPATSRCADDR(cAcl->ScratchAddress);
+ ctWRITEPLANEMASK16(planemask, cAcl->ScratchAddress);
+ }
+ break;
+#endif
+ default:
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
+ break;
+ }
+ ctSETPITCH(cAcl->PitchInBytes, cAcl->PitchInBytes);
+}
+
+static void
+CTNAME(SubsequentScreenToScreenCopy)(ScrnInfoPtr pScrn, int srcX, int srcY,
+ int dstX, int dstY, int w, int h)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ unsigned int srcaddr, destaddr;
+
+ DEBUG_P("SubsequentScreenToScreenCopy");
+#ifdef CHIPS_HIQV
+ if (cAcl->CommandFlags & ctBOTTOM2TOP) {
+ srcaddr = (srcY + h - 1) * pScrn->displayWidth;
+ destaddr = (dstY + h - 1) * pScrn->displayWidth;
+ } else {
+ srcaddr = srcY * pScrn->displayWidth;
+ destaddr = dstY * pScrn->displayWidth;
+ }
+ if (cAcl->CommandFlags & ctRIGHT2LEFT) {
+ srcaddr = ( srcaddr + srcX + w ) * cAcl->BytesPerPixel - 1 ;
+ destaddr = ( destaddr + dstX + w ) * cAcl->BytesPerPixel - 1;
+ } else {
+ srcaddr = (srcaddr + srcX) * cAcl->BytesPerPixel;
+ destaddr = (destaddr + dstX) * cAcl->BytesPerPixel;
+ }
+ srcaddr += cAcl->FbOffset;
+ destaddr += cAcl->FbOffset;
+#else
+ if (cAcl->CommandFlags & ctTOP2BOTTOM) {
+ srcaddr = srcY * pScrn->displayWidth;
+ destaddr = dstY * pScrn->displayWidth;
+ } else {
+ srcaddr = (srcY + h - 1) * pScrn->displayWidth;
+ destaddr = (dstY + h - 1) * pScrn->displayWidth;
+ }
+ if (cAcl->CommandFlags & ctLEFT2RIGHT) {
+ srcaddr = (srcaddr + srcX) * cAcl->BytesPerPixel;
+ destaddr = (destaddr + dstX) * cAcl->BytesPerPixel;
+ } else {
+ srcaddr = ( srcaddr + srcX + w ) * cAcl->BytesPerPixel - 1 ;
+ destaddr = ( destaddr + dstX + w ) * cAcl->BytesPerPixel - 1;
+ }
+#endif
+ w *= cAcl->BytesPerPixel;
+ ctBLTWAIT;
+ ctSETSRCADDR(srcaddr);
+ ctSETDSTADDR(destaddr);
+ ctSETHEIGHTWIDTHGO(h, w);
+}
+
+
+static void
+CTNAME(SetupForCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn, int fg,
+ int bg, int rop, unsigned int planemask)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ DEBUG_P("SetupForCPUToScreenColorExpandFill");
+ ctBLTWAIT;
+ cAcl->CommandFlags = 0;
+ if (bg == -1) {
+ cAcl->CommandFlags |= ctBGTRANSPARENT; /* Background = Destination */
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ ctSETFGCOLOR8(fg);
+ break;
+ case 16:
+ ctSETFGCOLOR16(fg);
+ break;
+ case 24:
+#ifdef CHIPS_HIQV
+ ctSETFGCOLOR24(fg);
+#else
+ ctSETFGCOLOR8(fg);
+#endif
+ break;
+ }
+ }
+ else {
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ ctSETBGCOLOR8(bg);
+ ctSETFGCOLOR8(fg);
+ break;
+ case 16:
+ ctSETBGCOLOR16(bg);
+ ctSETFGCOLOR16(fg);
+ break;
+ case 24:
+#ifdef CHIPS_HIQV
+ ctSETBGCOLOR24(bg);
+ ctSETFGCOLOR24(fg);
+#else
+ ctSETBGCOLOR8(bg);
+ ctSETFGCOLOR8(fg);
+#endif
+ break;
+ }
+ }
+
+#ifdef CHIPS_HIQV
+ ctSETMONOCTL(ctDWORDALIGN);
+#endif
+
+ ctSETSRCADDR(0);
+
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ if ((planemask & 0xFF) == 0xFF) {
+ ctSETROP(ctSRCSYSTEM | ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv[rop & 0xF] | cAcl->CommandFlags);
+ } else {
+ ctSETROP(ctSRCSYSTEM | ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv3[rop & 0xF] | cAcl->CommandFlags);
+ ctSETPATSRCADDR(cAcl->ScratchAddress);
+ ctWRITEPLANEMASK8(planemask, cAcl->ScratchAddress);
+ }
+ break;
+ case 16:
+ if ((planemask & 0xFFFF) == 0xFFFF) {
+ ctSETROP(ctSRCSYSTEM | ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv[rop & 0xF] | cAcl->CommandFlags);
+ } else {
+ ctSETROP(ctSRCSYSTEM | ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv3[rop & 0xF] | cAcl->CommandFlags);
+ ctSETPATSRCADDR(cAcl->ScratchAddress);
+ ctWRITEPLANEMASK16(planemask, cAcl->ScratchAddress);
+ }
+ break;
+ default:
+ ctSETROP(ctSRCSYSTEM | ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv[rop & 0xF] | cAcl->CommandFlags);
+ break;
+ }
+ ctSETPITCH(0, cAcl->PitchInBytes);
+}
+
+static void
+CTNAME(SubsequentCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ int destaddr;
+
+ DEBUG_P("SubsequentCPUToScreenColorExpandFill");
+ destaddr = (y * pScrn->displayWidth + x + skipleft) *
+ cAcl->BytesPerPixel;
+#ifdef CHIPS_HIQV
+ destaddr += cAcl->FbOffset;
+#endif
+ w = (w - skipleft) * cAcl->BytesPerPixel;
+ ctBLTWAIT;
+ ctSETDSTADDR(destaddr);
+#ifdef CHIPS_HIQV
+ ctSETMONOCTL(ctDWORDALIGN | ctCLIPLEFT(skipleft));
+#endif
+ ctSETHEIGHTWIDTHGO(h, w);
+}
+
+#if !defined(CHIPS_HIQV) || defined(UNDOCUMENTED_FEATURE)
+static void
+CTNAME(SetupForScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ DEBUG_P("SetupForScreenToScreenColorExpandFill");
+ cAcl->CommandFlags = 0;
+ ctBLTWAIT;
+ if (bg == -1) {
+ cAcl->CommandFlags |= ctBGTRANSPARENT; /* Background = Destination */
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ ctSETFGCOLOR8(fg);
+ break;
+ case 16:
+ ctSETFGCOLOR16(fg);
+ break;
+ case 24:
+#ifdef CHIPS_HIQV
+ ctSETFGCOLOR24(fg);
+#else
+ ctSETFGCOLOR8(fg);
+#endif
+ break;
+ }
+ }
+ else {
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ ctSETBGCOLOR8(bg);
+ ctSETFGCOLOR8(fg);
+ break;
+ case 16:
+ ctSETBGCOLOR16(bg);
+ ctSETFGCOLOR16(fg);
+ break;
+ case 24:
+#ifdef CHIPS_HIQV
+ ctSETBGCOLOR24(bg);
+ ctSETFGCOLOR24(fg);
+#else
+ ctSETBGCOLOR8(bg);
+ ctSETFGCOLOR8(fg);
+#endif
+ break;
+ }
+ }
+
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ if ((planemask & 0xFF) == 0xFF) {
+ ctSETROP(ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv[rop & 0xF] | cAcl->CommandFlags);
+ } else {
+ ctSETROP(ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv3[rop & 0xF] | cAcl->CommandFlags);
+ ctSETPATSRCADDR(cAcl->ScratchAddress);
+ ctWRITEPLANEMASK8(planemask, cAcl->ScratchAddress);
+ }
+ break;
+ case 16:
+ if ((planemask & 0xFFFF) == 0xFFFF) {
+ ctSETROP(ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv[rop & 0xF] | cAcl->CommandFlags);
+ } else {
+ ctSETROP(ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv3[rop & 0xF] | cAcl->CommandFlags);
+ ctSETPATSRCADDR(cAcl->ScratchAddress);
+ ctWRITEPLANEMASK16(planemask, cAcl->ScratchAddress);
+ }
+ break;
+ default:
+ ctSETROP(ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv[rop & 0xF] | cAcl->CommandFlags);
+ break;
+ }
+ ctSETPITCH(cAcl->PitchInBytes, cAcl->PitchInBytes);
+}
+#endif
+#ifndef CHIPS_HIQV
+/*
+ * The non-HiQV chips don't have left-edge clippling of monochrome sources.
+ * However you can have the monochrome source starting on a byte boundary.
+ * Hence have 8 rotated copies of the monochrome source to simulate left
+ * edge clipping with these chips. This requires the XAACacheMonoStipple
+ * function to be replaced, if we are to use ScreenToScreenColorExpand.
+ */
+
+static XAACacheInfoPtr
+CTNAME(CacheMonoStipple)(ScrnInfoPtr pScrn, PixmapPtr pPix)
+{
+ int w = pPix->drawable.width;
+ int h = pPix->drawable.height;
+ XAAInfoRecPtr infoRec = (CHIPSPTR(pScrn))->AccelInfoRec;
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache, cacheRoot = NULL;
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ int i, j, max = 0, funcNo, pad, dwords, bpp = cAcl->BitsPerPixel;
+ int *current;
+ StippleScanlineProcPtr StippleFunc;
+ unsigned char *data, *srcPtr, *dstPtr;
+
+ DEBUG_P("CacheMonoStipple");
+ if((h <= 128) && (w <= 128 * bpp / 8)) {
+ if(pCachePriv->Info128) {
+ cacheRoot = pCachePriv->Info128;
+ max = pCachePriv->Num128x128;
+ current = &pCachePriv->Current128;
+ } else {
+ cacheRoot = pCachePriv->InfoPartial;
+ max = pCachePriv->NumPartial;
+ current = &pCachePriv->CurrentPartial;
+ }
+ } else if((h <= 256) && (w <= 256 * bpp / 8)){
+ cacheRoot = pCachePriv->Info256;
+ max = pCachePriv->Num256x256;
+ current = &pCachePriv->Current256;
+ } else if((h <= 512) && (w <= 512 * bpp / 8)){
+ cacheRoot = pCachePriv->Info512;
+ max = pCachePriv->Num512x512;
+ current = &pCachePriv->Current512;
+ } else { /* something's wrong */
+ ErrorF("Something's wrong in XAACacheMonoStipple()\n");
+ return pCachePriv->Info128;
+ }
+
+ pCache = cacheRoot;
+
+ /* lets look for it */
+ for(i = 0; i < max; i++, pCache++) {
+ if((pCache->serialNumber == pPix->drawable.serialNumber) &&
+ (pCache->fg == -1) && (pCache->bg == -1)) {
+ pCache->trans_color = -1;
+ dwords =
+ cAcl->SlotWidth = ((pCache->w * bpp) >> 5) >> 1;
+ return pCache;
+ }
+ }
+
+ pCache = &cacheRoot[(*current)++];
+ if(*current >= max) *current = 0;
+
+ pCache->serialNumber = pPix->drawable.serialNumber;
+ pCache->trans_color = pCache->bg = pCache->fg = -1;
+ pCache->orig_w = w; pCache->orig_h = h;
+
+ if(w <= 32) {
+ if(w & (w - 1)) funcNo = 1;
+ else funcNo = 0;
+ } else funcNo = 2;
+
+ pad = (((pCache->w * bpp) + 31) >> 5) << 2;
+ dstPtr = data = (unsigned char*)ALLOCATE_LOCAL(pad * pCache->h);
+ srcPtr = (unsigned char*)pPix->devPrivate.ptr;
+ StippleFunc = XAAStippleScanlineFuncMSBFirst[funcNo];
+
+ dwords = ((pCache->w * bpp) >> 5) >> 3;
+ cAcl->SlotWidth = dwords << 2;
+
+ for(i = 0; i < h; i++) {
+ for(j = 0; j < 8; j++) {
+ (*StippleFunc)((CARD32*)dstPtr + j * dwords,
+ (CARD32*)srcPtr, j, w, dwords);
+ }
+ srcPtr += pPix->devKind;
+ dstPtr += pad;
+ }
+
+ while((h<<1) <= pCache->h) {
+ memcpy(data + (pad * h), data, pad * h);
+ h <<= 1;
+ }
+
+ if(h < pCache->h)
+ memcpy(data + (pad * h), data, pad * (pCache->h - h));
+
+ (*infoRec->WritePixmapToCache)(
+ pScrn, pCache->x, pCache->y, pCache->w, pCache->h, data,
+ pad, bpp, pScrn->depth);
+
+ DEALLOCATE_LOCAL(data);
+
+ return pCache;
+}
+#endif
+#if !defined(CHIPS_HIQV) || defined(UNDOCUMENTED_FEATURE)
+static void
+CTNAME(SubsequentScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int srcx, int srcy, int skipleft)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ int srcaddr, destaddr;
+
+ DEBUG_P("SubsequentScreenToScreenColorExpandFill");
+#ifdef CHIPS_HIQV
+ srcaddr = (srcy * pScrn->displayWidth + srcx) * cAcl->BytesPerPixel
+ + ((skipleft & ~0x3F) >> 3);
+ if ( y < pScrn->virtualY)
+ srcaddr += cAcl->FbOffset;
+ else
+ srcaddr += cPtr->FbOffset16;
+#else
+ srcaddr = (srcy * pScrn->displayWidth + srcx) * cAcl->BytesPerPixel
+ + ((skipleft & 0x07) * cAcl->SlotWidth)
+ + ((skipleft & ~0x07) >> 3);
+#endif
+ destaddr = (y * pScrn->displayWidth + x) * cAcl->BytesPerPixel;
+#ifdef CHIPS_HIQV
+ destaddr += cAcl->FbOffset;
+#endif
+ w *= cAcl->BytesPerPixel;
+ ctBLTWAIT;
+#ifdef CHIPS_HIQV
+ if ((y >= pScrn->virtualY) && (cPtr->Flags & ChipsOverlay8plus16) &&
+ (pScrn->depth == 8))
+ ctSETPITCH(cAcl->PitchInBytes << 1, cAcl->PitchInBytes);
+#endif
+ ctSETSRCADDR(srcaddr);
+ ctSETDSTADDR(destaddr);
+#ifdef CHIPS_HIQV
+ ctSETMONOCTL(ctCLIPLEFT(skipleft & 0x3F));
+#endif
+ ctSETHEIGHTWIDTHGO(h, w);
+}
+#endif
+static void
+CTNAME(SetupForColor8x8PatternFill)(ScrnInfoPtr pScrn, int patx, int paty,
+ int rop, unsigned int planemask,
+ int trans)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ unsigned int patternaddr;
+
+ DEBUG_P("SetupForColor8x8PatternFill");
+ cAcl->CommandFlags = ChipsAluConv2[rop & 0xF] | ctTOP2BOTTOM |
+ ctLEFT2RIGHT;
+ patternaddr = (paty * pScrn->displayWidth +
+ (patx & ~0x3F)) * cAcl->BytesPerPixel;
+ cAcl->patternyrot = (patx & 0x3F) >> 3;
+#ifdef CHIPS_HIQV
+ if (cPtr->Flags & ChipsOverlay8plus16)
+ patternaddr += cPtr->FbOffset16;
+#endif
+
+ ctBLTWAIT;
+ ctSETPATSRCADDR(patternaddr);
+#ifdef CHIPS_HIQV
+ if (trans != -1) {
+ cAcl->CommandFlags |= ctCOLORTRANSENABLE | ctCOLORTRANSROP |
+ ctCOLORTRANSNEQUAL;
+ ctSETMONOCTL(ctDWORDALIGN);
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ ctSETBGCOLOR8(trans);
+ break;
+ case 16:
+ ctSETBGCOLOR16(trans);
+ break;
+ case 24:
+ ctSETBGCOLOR24(trans);
+ break;
+ }
+ } else
+#endif
+ ctSETPITCH(8 * cAcl->BytesPerPixel, cAcl->PitchInBytes);
+}
+
+static void
+CTNAME(SubsequentColor8x8PatternFillRect)(ScrnInfoPtr pScrn, int patx, int paty,
+ int x, int y, int w, int h)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ unsigned int destaddr;
+
+ DEBUG_P("SubsequentColor8x8PatternFillRect");
+ destaddr = (y * pScrn->displayWidth + x) * cAcl->BytesPerPixel;
+#ifdef CHIPS_HIQV
+ destaddr += cAcl->FbOffset;
+#endif
+ w *= cAcl->BytesPerPixel;
+ ctBLTWAIT;
+ ctSETDSTADDR(destaddr);
+#ifdef CHIPS_HIQV
+ ctSETROP(cAcl->CommandFlags | (((y + cAcl->patternyrot) & 0x7) << 20));
+#else
+ ctSETROP(cAcl->CommandFlags | (((y + cAcl->patternyrot) & 0x7) << 16));
+#endif
+ ctSETHEIGHTWIDTHGO(h, w);
+}
+
+static void
+CTNAME(SetupForMono8x8PatternFill)(ScrnInfoPtr pScrn, int patx, int paty,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ unsigned int patternaddr;
+
+ DEBUG_P("SetupForMono8x8PatternFill");
+ cAcl->CommandFlags = ctPATMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv2[rop & 0xF];
+
+#ifdef CHIPS_HIQV
+ patternaddr = paty * pScrn->displayWidth + patx;
+ if (cPtr->Flags & ChipsOverlay8plus16)
+ patternaddr = patternaddr * 2 + cPtr->FbOffset16;
+ else
+ patternaddr *= cAcl->BytesPerPixel;
+#else
+ patternaddr = (paty * pScrn->displayWidth + patx) * cAcl->BytesPerPixel;
+#endif
+ ctBLTWAIT;
+ ctSETPATSRCADDR(patternaddr);
+ if (bg == -1) {
+ cAcl->CommandFlags |= ctBGTRANSPARENT; /* Background = Destination */
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ ctSETFGCOLOR8(fg);
+ break;
+ case 16:
+ ctSETFGCOLOR16(fg);
+ break;
+ case 24:
+ ctSETFGCOLOR24(fg);
+ break;
+ }
+ }
+ else {
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ ctSETBGCOLOR8(bg);
+ ctSETFGCOLOR8(fg);
+ break;
+ case 16:
+ ctSETBGCOLOR16(bg);
+ ctSETFGCOLOR16(fg);
+ break;
+ case 24:
+ ctSETBGCOLOR24(bg);
+ ctSETFGCOLOR24(fg);
+ break;
+ }
+ }
+#ifdef CHIPS_HIQV
+ ctSETMONOCTL(ctDWORDALIGN);
+#endif
+ ctSETPITCH(1,cAcl->PitchInBytes);
+}
+
+static void
+CTNAME(SubsequentMono8x8PatternFillRect)(ScrnInfoPtr pScrn, int patx,
+ int paty, int x, int y, int w, int h )
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ int destaddr;
+ DEBUG_P("SubsequentMono8x8PatternFillRect");
+ destaddr = (y * pScrn->displayWidth + x) * cAcl->BytesPerPixel;
+#ifdef CHIPS_HIQV
+ destaddr += cAcl->FbOffset;
+#endif
+ w *= cAcl->BytesPerPixel;
+
+ ctBLTWAIT;
+ ctSETDSTADDR(destaddr);
+#ifdef CHIPS_HIQV
+ ctSETROP(cAcl->CommandFlags | ((y & 0x7) << 20));
+#else
+ ctSETROP(cAcl->CommandFlags | ((y & 0x7) << 16));
+#endif
+ ctSETHEIGHTWIDTHGO(h, w);
+}
+
+#ifndef CHIPS_HIQV
+static void
+CTNAME(SetupForImageWrite)(ScrnInfoPtr pScrn, int rop, unsigned int planemask,
+ int transparency_color, int bpp, int depth)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ DEBUG_P("SetupForImageWrite");
+ cAcl->CommandFlags = ctSRCSYSTEM | ctTOP2BOTTOM | ctLEFT2RIGHT;
+ ctBLTWAIT;
+
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ if ((planemask & 0xFF) == 0xFF) {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
+ } else {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv3[rop & 0xF]);
+ ctSETPATSRCADDR(cAcl->ScratchAddress);
+ ctWRITEPLANEMASK8(planemask, cAcl->ScratchAddress);
+ }
+ break;
+ case 16:
+ if ((planemask & 0xFFFF) == 0xFFFF) {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
+ } else {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv3[rop & 0xF]);
+ ctSETPATSRCADDR(cAcl->ScratchAddress);
+ ctWRITEPLANEMASK16(planemask, cAcl->ScratchAddress);
+ }
+ break;
+ default:
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
+ break;
+ }
+ ctSETSRCADDR(0);
+}
+
+static void
+CTNAME(SubsequentImageWriteRect)(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ int skipleft)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ int destaddr = (y * pScrn->displayWidth + x) * cAcl->BytesPerPixel;
+ DEBUG_P("SubsequentImageWriteRect");
+ w *= cAcl->BytesPerPixel;
+ ctBLTWAIT;
+ ctSETPITCH(((w + 3) & ~0x3), cAcl->PitchInBytes);
+ ctSETDSTADDR(destaddr);
+ ctSETHEIGHTWIDTHGO(h, w);
+}
+
+#else
+/*
+ * Copyright 1997
+ * Digital Equipment Corporation. All rights reserved.
+ * This software is furnished under license and may be used and copied only in
+ * accordance with the following terms and conditions. Subject to these
+ * conditions, you may download, copy, install, use, modify and distribute
+ * this software in source and/or binary form. No title or ownership is
+ * transferred hereby.
+ * 1) Any source code used, modified or distributed must reproduce and retain
+ * this copyright notice and list of conditions as they appear in the
+ * source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or logo of Digital
+ * Equipment Corporation. Neither the "Digital Equipment Corporation" name
+ * nor any trademark or logo of Digital Equipment Corporation may be used
+ * to endorse or promote products derived from this software without the
+ * prior written permission of Digital Equipment Corporation.
+ *
+ * 3) This software is provided "AS-IS" and any express or implied warranties,
+ * including but not limited to, any implied warranties of merchantability,
+ * fitness for a particular purpose, or non-infringement are disclaimed. In
+ * no event shall DIGITAL be liable for any damages whatsoever, and in
+ * particular, DIGITAL shall not be liable for special, indirect,
+ * consequential, or incidental damages or damages for lost profits, loss
+ * of revenue or loss of use, whether such damages arise in contract,
+ * negligence, tort, under statute, in equity, at law or otherwise, even if
+ * advised of the possibility of such damage.
+ */
+
+/* The code below comes from the idea supplied by the people at DEC, like
+ * the copyright above says. But its had to go through a large evolution
+ * to fit it into the new design for XFree86 4.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;
+ }
+ switch(dwords){
+ case 1:
+ *dest = *src;
+ break;
+ case 2:
+ *dest = *src;
+ *(dest + 1) = *(src + 1);
+ break;
+ case 3:
+ *dest = *src;
+ *(dest + 1) = *(src + 1);
+ *(dest + 2) = *(src + 2);
+ break;
+ }
+}
+
+static __inline__ void
+MoveDataFromCPU(unsigned char *src, unsigned char *dest, int srcwidth,
+ int window, int h, int dwords)
+{
+ if(srcwidth == (dwords << 2)) {
+ int decrement = window / dwords;
+ while(h > decrement) {
+ MoveDWORDS((CARD32*)dest, (CARD32*)src, dwords * decrement);
+ src += (srcwidth * decrement);
+ h -= decrement;
+ }
+ if(h) {
+ MoveDWORDS((CARD32*)dest, (CARD32*)src, dwords * h);
+ }
+ } else {
+ while(h--) {
+ MoveDWORDS((CARD32*)dest, (CARD32*)src, dwords);
+ src += srcwidth;
+ }
+ }
+}
+
+static __inline__ void
+MoveDataToCPU(unsigned char *src, unsigned char *dest, int dstwidth,
+ int window, int h, int dwords)
+{
+ if(dstwidth == (dwords << 2)) {
+ int decrement = window / dwords;
+ while(h > decrement) {
+ MoveDWORDS((CARD32*)dest, (CARD32*)src, dwords * decrement);
+ dest += (dstwidth * decrement);
+ h -= decrement;
+ }
+ if(h) {
+ MoveDWORDS((CARD32*)dest, (CARD32*)src, dwords * h);
+ }
+ } else {
+ while(h--) {
+ MoveDWORDS((CARD32*)dest, (CARD32*)src, dwords);
+ dest += dstwidth;
+ }
+ }
+}
+
+static void
+CTNAME(WritePixmap)(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int rop,
+ unsigned int planemask, int trans, int bpp, int depth)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ unsigned int bytesPerLine;
+ unsigned int byteWidthSrc;
+ unsigned int destpitch;
+ int dwords;
+ int skipleft;
+ int destaddr;
+
+ DEBUG_P("WritePixmap");
+#ifdef DEBUG
+ ErrorF("WritePixmap x %d, y %d, w %d, h %d, src 0x%X, srcwidth %d, rop 0x%X, planemask 0x%X, trans 0x%X, bpp %d, depth %d\n", x, y, w, h, src, srcwidth, rop, planemask, trans, bpp, depth);
+#endif
+ bytesPerLine = w * (bpp >> 3);
+ byteWidthSrc = ((srcwidth * (bpp >> 3) + 3L) & ~0x3L);
+ cAcl->CommandFlags = ctSRCSYSTEM | ctLEFT2RIGHT | ctTOP2BOTTOM;
+ skipleft = (unsigned long)src & 0x7;
+ src = (unsigned char *)((unsigned long)src & ~0x7L);
+ dwords = (((skipleft + bytesPerLine + 0x7) & ~0x7)) >> 2;
+ destaddr = (y * pScrn->displayWidth + x) * (bpp >> 3);
+ destpitch = pScrn->displayWidth * (bpp >> 3);
+ if ((y >= pScrn->virtualY) && (cPtr->Flags & ChipsOverlay8plus16))
+ destaddr += cPtr->FbOffset16;
+ else
+ destaddr += cAcl->FbOffset;
+
+ ctBLTWAIT;
+
+ if (trans != -1) {
+ cAcl->CommandFlags |= ctCOLORTRANSENABLE | ctCOLORTRANSROP |
+ ctCOLORTRANSNEQUAL;
+ ctSETMONOCTL(ctDWORDALIGN);
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ ctSETBGCOLOR8(trans);
+ break;
+ case 16:
+ ctSETBGCOLOR16(trans);
+ break;
+ case 24:
+ ctSETBGCOLOR24(trans);
+ break;
+ }
+ }
+
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ if ((planemask & 0xFF) == 0xFF) {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
+ } else {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv3[rop & 0xF]);
+ ctSETPATSRCADDR(cAcl->ScratchAddress);
+ ctWRITEPLANEMASK8(planemask, cAcl->ScratchAddress);
+ }
+ break;
+ case 16:
+ if ((planemask & 0xFFFF) == 0xFFFF) {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
+ } else {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv3[rop & 0xF]);
+ ctSETPATSRCADDR(cAcl->ScratchAddress);
+ ctWRITEPLANEMASK16(planemask, cAcl->ScratchAddress);
+ }
+ break;
+ default:
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
+ break;
+ }
+
+ /*
+ *
+ * CT6555X requires quad-word padding, but XAA provides double-word
+ * padding. If the width of a region to be transferred happens to be
+ * quad-word aligned, the transfer is straightforward. If the
+ * region is double-word aligned, a pair of contiguous scanlines
+ * is quad-word aligned. In latter case, we can use interleaved
+ * transfer twice. It is faster than transfer line by line.
+ *
+ */
+
+ ctSETSRCADDR(skipleft);
+ ctSETDSTADDR(destaddr);
+
+ if ((byteWidthSrc & 0x7) == 0) { /* quad-word aligned */
+
+ ctSETPITCH(byteWidthSrc, destpitch);
+ ctSETHEIGHTWIDTHGO(h, bytesPerLine);
+
+ MoveDataFromCPU((unsigned char *)src,
+ (unsigned char *)cAcl->BltDataWindow,
+ srcwidth, 16384, h, dwords);
+
+ } else {
+ unsigned int vert = h;
+
+ h = (vert + 1) >> 1;
+
+ ctSETPITCH(byteWidthSrc << 1, destpitch << 1);
+ ctSETHEIGHTWIDTHGO(h, bytesPerLine);
+
+ MoveDataFromCPU((unsigned char *)src,
+ (unsigned char *)cAcl->BltDataWindow,
+ srcwidth<<1, 16384, h, dwords);
+
+ h = vert >> 1;
+ src += srcwidth;
+ y++;
+
+ destaddr = (y * pScrn->displayWidth + x) * (bpp >> 3);
+ if ((y >= pScrn->virtualY) && (cPtr->Flags & ChipsOverlay8plus16))
+ destaddr += cPtr->FbOffset16;
+ else
+ destaddr += cAcl->FbOffset;
+
+ ctBLTWAIT;
+ ctSETDSTADDR(destaddr);
+ ctSETHEIGHTWIDTHGO(h, bytesPerLine);
+
+ MoveDataFromCPU((unsigned char *)src,
+ (unsigned char *)cAcl->BltDataWindow,
+ srcwidth<<1, 16384, h, dwords);
+ }
+
+ cPtr->AccelInfoRec->NeedToSync = TRUE;
+}
+
+#if 0
+static void
+CTNAME(ReadPixmap)(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *dst, int dstwidth, int bpp, int depth)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ unsigned int bytesPerLine;
+ unsigned int byteWidthDst;
+ unsigned int srcpitch;
+ int dwords;
+ int srcaddr;
+
+ DEBUG_P("ReadPixmap");
+ bytesPerLine = w * (bpp >> 3);
+ byteWidthDst = ((dstwidth * (bpp >> 3) + 3L) & ~0x3L);
+ dwords = (((bytesPerLine + 0x7) & ~0x7)) >> 2;
+ srcaddr = (y * pScrn->displayWidth + x) * (bpp >> 3);
+ srcpitch = pScrn->displayWidth * (bpp >> 3);
+ if ((y >= pScrn->virtualY) && (cPtr->Flags & ChipsOverlay8plus16))
+ srcaddr += cPtr->FbOffset16;
+ else
+ srcaddr += cAcl->FbOffset;
+
+ ctBLTWAIT;
+ ctSETROP( ctDSTSYSTEM | ctLEFT2RIGHT | ctTOP2BOTTOM |
+ ChipsAluConv[GXcopy & 0xF]);
+ ctSETDSTADDR(0);
+ ctSETSRCADDR(srcaddr);
+
+ if ((byteWidthDst & 0x7) == 0) { /* quad-word aligned */
+
+ ctSETPITCH(srcpitch, byteWidthDst);
+ ctSETHEIGHTWIDTHGO(h, bytesPerLine);
+
+ MoveDataToCPU((unsigned char *)cAcl->BltDataWindow,
+ (unsigned char *)dst, dstwidth, 16384, h, dwords);
+
+ } else {
+ unsigned int vert = h;
+
+ h = (vert + 1) >> 1;
+
+ ctSETPITCH(srcpitch << 1, byteWidthDst << 1);
+ ctSETHEIGHTWIDTHGO(h, bytesPerLine);
+
+ MoveDataToCPU((unsigned char *)cAcl->BltDataWindow,
+ (unsigned char *)dst, dstwidth<<1, 16384, h, dwords);
+
+ h = vert >> 1;
+ dst += dstwidth;
+ y++;
+ srcaddr = (y * pScrn->displayWidth + x) * (bpp >> 3);
+ if ((y >= pScrn->virtualY) && (cPtr->Flags & ChipsOverlay8plus16))
+ srcaddr += cPtr->FbOffset16;
+ else
+ srcaddr += cAcl->FbOffset;
+ ctBLTWAIT;
+ ctSETSRCADDR(srcaddr);
+ ctSETHEIGHTWIDTHGO(h, bytesPerLine);
+
+ MoveDataToCPU((unsigned char *)cAcl->BltDataWindow,
+ (unsigned char *)dst, dstwidth<<1, 16384, h, dwords);
+ }
+
+ cPtr->AccelInfoRec->NeedToSync = TRUE;
+}
+#endif /* ReadPixmap */
+
+#endif
diff --git a/src/ct_bank.c b/src/ct_bank.c
new file mode 100644
index 0000000..1e478ee
--- /dev/null
+++ b/src/ct_bank.c
@@ -0,0 +1,626 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_bank.c,v 1.6 2002/01/25 21:55:58 tsi Exp $ */
+
+/*
+ * Copyright 1997
+ * Digital Equipment Corporation. All rights reserved.
+ * This software is furnished under license and may be used and copied only in
+ * accordance with the following terms and conditions. Subject to these
+ * conditions, you may download, copy, install, use, modify and distribute
+ * this software in source and/or binary form. No title or ownership is
+ * transferred hereby.
+ * 1) Any source code used, modified or distributed must reproduce and retain
+ * this copyright notice and list of conditions as they appear in the
+ * source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or logo of Digital
+ * Equipment Corporation. Neither the "Digital Equipment Corporation" name
+ * nor any trademark or logo of Digital Equipment Corporation may be used
+ * to endorse or promote products derived from this software without the
+ * prior written permission of Digital Equipment Corporation.
+ *
+ * 3) This software is provided "AS-IS" and any express or implied warranties,
+ * including but not limited to, any implied warranties of merchantability,
+ * fitness for a particular purpose, or non-infringement are disclaimed. In
+ * no event shall DIGITAL be liable for any damages whatsoever, and in
+ * particular, DIGITAL shall not be liable for special, indirect,
+ * consequential, or incidental damages or damages for lost profits, loss
+ * of revenue or loss of use, whether such damages arise in contract,
+ * negligence, tort, under statute, in equity, at law or otherwise, even if
+ * advised of the possibility of such damage.
+ */
+#define PSZ 8
+
+/*
+ * Define DIRECT_REGISTER_ACCESS if you want to bypass the wrapped register
+ * access functions
+ */
+/* #define DIRECT_REGISTER_ACCESS */
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+/* Everything using inb/outb, etc needs "compiler.h" */
+#include "compiler.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"
+
+/* Driver specific headers */
+#include "ct_driver.h"
+
+#ifdef __arm32__
+/*#include <machine/sysarch.h>*/
+#define arm32_drain_writebuf() sysarch(1, 0)
+#define ChipsBank(pScreen) CHIPSPTR(xf86Screens[pScreen->myNum])->Bank
+#endif
+
+#ifdef DIRECT_REGISTER_ACCESS
+int
+CHIPSSetRead(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ outw(cPtr->PIOBase + 0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x10));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+
+int
+CHIPSSetWrite(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ outw(cPtr->PIOBase + 0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x11));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+
+int
+CHIPSSetReadWrite(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ outw(cPtr->PIOBase + 0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x10));
+ outw(cPtr->PIOBase + 0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x11));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSSetReadPlanar(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ outw(cPtr->PIOBase + 0x3D6, ((((bank << 5) & 0xFF) << 8) | 0x10));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSSetWritePlanar(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ outw(cPtr->PIOBase + 0x3D6, ((((bank << 5) & 0xFF) << 8) | 0x11));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSSetReadWritePlanar(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ outw(cPtr->PIOBase + 0x3D6, ((((bank << 5) & 0xFF) << 8) | 0x10));
+ outw(cPtr->PIOBase + 0x3D6, ((((bank << 5) & 0xFF) << 8) | 0x11));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSWINSetRead(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+ register unsigned char tmp;
+
+ outw(cPtr->PIOBase + 0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x10));
+ outb(cPtr->PIOBase + 0x3D6, 0x0C);
+ tmp = inb(cPtr->PIOBase + 0x3D7) & 0xEF;
+ outw(cPtr->PIOBase + 0x3D6, (((((bank >> 1) & 0x10) | tmp) << 8) | 0x0C));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+
+int
+CHIPSWINSetWrite(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+ register unsigned char tmp;
+
+ outw(cPtr->PIOBase + 0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x11));
+ outb(cPtr->PIOBase + 0x3D6, 0x0C);
+ tmp = inb(cPtr->PIOBase + 0x3D7) & 0xBF;
+ outw(cPtr->PIOBase + 0x3D6, (((((bank << 1) & 0x40) | tmp) << 8) | 0x0C));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSWINSetReadWrite(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+ register unsigned char tmp;
+
+ outw(cPtr->PIOBase + 0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x10));
+ outw(cPtr->PIOBase + 0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x11));
+ outb(cPtr->PIOBase + 0x3D6, 0x0C);
+ tmp = inb(cPtr->PIOBase + 0x3D7) & 0xAF;
+ outw(cPtr->PIOBase + 0x3D6,
+ (((((bank << 1) & 0x40) | ((bank >> 1) & 0x10) | tmp) << 8) | 0x0C));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSWINSetReadPlanar(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+ register unsigned char tmp;
+
+ outw(cPtr->PIOBase + 0x3D6, ((((bank << 5) & 0xFF) << 8) | 0x10));
+ outb(cPtr->PIOBase + 0x3D6, 0x0C);
+ tmp = inb(cPtr->PIOBase + 0x3D7) & 0xEF;
+ outw(cPtr->PIOBase + 0x3D6, (((((bank << 1) & 0x10) | tmp) << 8) | 0x0C));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSWINSetWritePlanar(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+ register unsigned char tmp;
+
+ outw(cPtr->PIOBase + 0x3D6, ((((bank << 5) & 0xFF) << 8) | 0x11));
+ outb(cPtr->PIOBase + 0x3D6, 0x0C);
+ tmp = inb(cPtr->PIOBase + 0x3D7) & 0xBF;
+ outw(cPtr->PIOBase + 0x3D6, (((((bank << 3) & 0x40) | tmp) << 8) | 0x0C));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSWINSetReadWritePlanar(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+ register unsigned char tmp;
+
+ outw(cPtr->PIOBase + 0x3D6, ((((bank << 5) & 0xFF) << 8) | 0x10));
+ outw(cPtr->PIOBase + 0x3D6, ((((bank << 5) & 0xFF) << 8) | 0x11));
+ outb(cPtr->PIOBase + 0x3D6, 0x0C);
+ tmp = inb(cPtr->PIOBase + 0x3D7) & 0xAF;
+ outw(cPtr->PIOBase + 0x3D6,
+ (((((bank << 3) & 0x40) | ((bank << 1) & 0x10) | tmp) << 8) | 0x0C));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSHiQVSetReadWrite(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ outw(cPtr->PIOBase + 0x3D6, (((bank & 0x7F) << 8) | 0x0E));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSHiQVSetReadWritePlanar(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ outw(cPtr->PIOBase + 0x3D6, ((((bank << 2) & 0x7F) << 8) | 0x0E));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+#else /* DIRECT_REGISTER_ACCESS */
+
+int
+CHIPSSetRead(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ cPtr->writeXR(cPtr, 0x10, ((bank << 3) & 0xFF));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+
+int
+CHIPSSetWrite(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ cPtr->writeXR(cPtr, 0x11, ((bank << 3) & 0xFF));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+
+int
+CHIPSSetReadWrite(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ cPtr->writeXR(cPtr, 0x10, ((bank << 3) & 0xFF));
+ cPtr->writeXR(cPtr, 0x11, ((bank << 3) & 0xFF));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSSetReadPlanar(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ cPtr->writeXR(cPtr, 0x10, ((bank << 5) & 0xFF));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSSetWritePlanar(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ cPtr->writeXR(cPtr, 0x11, ((bank << 5) & 0xFF));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSSetReadWritePlanar(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ cPtr->writeXR(cPtr, 0x10, ((bank << 5) & 0xFF));
+ cPtr->writeXR(cPtr, 0x11, ((bank << 5) & 0xFF));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSWINSetRead(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+ register unsigned char tmp;
+
+ cPtr->writeXR(cPtr, 0x10, ((bank << 3) & 0xFF));
+ tmp = cPtr->readXR(cPtr, 0x0C) & 0xEF;
+ cPtr->writeXR(cPtr, 0x0C, ((bank >> 1) & 0x10) | tmp);
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+
+int
+CHIPSWINSetWrite(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+ register unsigned char tmp;
+
+ cPtr->writeXR(cPtr, 0x11, ((bank << 3) & 0xFF));
+ tmp = cPtr->readXR(cPtr, 0x0C) & 0xBF;
+ cPtr->writeXR(cPtr, 0x0C, ((bank << 1) & 0x40) | tmp);
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSWINSetReadWrite(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+ register unsigned char tmp;
+
+ cPtr->writeXR(cPtr, 0x10, ((bank << 3) & 0xFF));
+ cPtr->writeXR(cPtr, 0x11, ((bank << 3) & 0xFF));
+ tmp = cPtr->readXR(cPtr, 0x0C) & 0xAF;
+ cPtr->writeXR(cPtr, 0x0C, ((bank << 1) & 0x40) | ((bank >> 1) & 0x10) | tmp);
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSWINSetReadPlanar(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+ register unsigned char tmp;
+
+ cPtr->writeXR(cPtr, 0x10, ((bank << 5) & 0xFF));
+ tmp = cPtr->readXR(cPtr, 0x0C) & 0xEF;
+ cPtr->writeXR(cPtr, 0x0C, ((bank << 1) & 0x10) | tmp);
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSWINSetWritePlanar(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+ register unsigned char tmp;
+
+ cPtr->writeXR(cPtr, 0x11, ((bank << 5) & 0xFF));
+ tmp = cPtr->readXR(cPtr, 0x0C) & 0xBF;
+ cPtr->writeXR(cPtr, 0x0C, ((bank << 3) & 0x40) | tmp);
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSWINSetReadWritePlanar(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+ register unsigned char tmp;
+
+ cPtr->writeXR(cPtr, 0x10, ((bank << 5) & 0xFF));
+ cPtr->writeXR(cPtr, 0x11, ((bank << 5) & 0xFF));
+ tmp = cPtr->readXR(cPtr, 0x0C) & 0xAF;
+ cPtr->writeXR(cPtr, 0x0C, ((bank << 3) & 0x40) | ((bank << 1) & 0x10) | tmp);
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSHiQVSetReadWrite(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ cPtr->writeXR(cPtr, 0x0E, bank & 0x7F);
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSHiQVSetReadWritePlanar(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ cPtr->writeXR(cPtr, 0x0E, (bank << 2) & 0x7F);
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+#endif
diff --git a/src/ct_cursor.c b/src/ct_cursor.c
new file mode 100644
index 0000000..44a7e8a
--- /dev/null
+++ b/src/ct_cursor.c
@@ -0,0 +1,481 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_cursor.c,v 1.27 2002/11/25 14:04:58 eich Exp $ */
+
+/*
+ * Copyright 1994 The XFree86 Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * DAVID WEXELBLAT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Hardware Cursor for Trident utilizing XAA Cursor code.
+ * Written by Alan Hourihane <alanh@fairlite.demon.co.uk>
+ * Modified for Chips and Technologies by David Bateman <dbateman@eng.uts.edu.au>
+ */
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+/* Everything using inb/outb, etc needs "compiler.h" */
+#include "compiler.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 "xf86Cursor.h"
+
+/* Driver specific headers */
+#include "ct_driver.h"
+
+/* Sync function, maybe this should check infoRec->NeedToSync before syncing */
+#define CURSOR_SYNC(pScrn) \
+ if (IS_HiQV(cPtr)) { \
+ CHIPSHiQVSync(pScrn); \
+ } else { \
+ if(!cPtr->UseMMIO) { \
+ CHIPSSync(pScrn); \
+ } else { \
+ CHIPSMMIOSync(pScrn); \
+ } \
+ }
+
+/* Swing your cursor bytes round and round... yeehaw! */
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+#define P_SWAP32( a , b ) \
+ ((char *)a)[0] = ((char *)b)[3]; \
+ ((char *)a)[1] = ((char *)b)[2]; \
+ ((char *)a)[2] = ((char *)b)[1]; \
+ ((char *)a)[3] = ((char *)b)[0]
+
+#define P_SWAP16( a , b ) \
+ ((char *)a)[0] = ((char *)b)[1]; \
+ ((char *)a)[1] = ((char *)b)[0]; \
+ ((char *)a)[2] = ((char *)b)[3]; \
+ ((char *)a)[3] = ((char *)b)[2]
+#endif
+
+static void
+CHIPSShowCursor(ScrnInfoPtr pScrn)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ unsigned char tmp;
+
+ CURSOR_SYNC(pScrn);
+
+ /* turn the cursor on */
+ if (IS_HiQV(cPtr)) {
+ tmp = cPtr->readXR(cPtr, 0xA0);
+ cPtr->writeXR(cPtr, 0xA0, (tmp & 0xF8) | 5);
+ if (cPtr->UseDualChannel &&
+ (! xf86IsEntityShared(pScrn->entityList[0]))) {
+ unsigned int IOSS, MSS;
+ IOSS = cPtr->readIOSS(cPtr);
+ MSS = cPtr->readMSS(cPtr);
+ cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) |
+ IOSS_PIPE_B));
+ cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), ((cPtr->storeMSS &
+ MSS_MASK) | MSS_PIPE_B));
+ tmp = cPtr->readXR(cPtr, 0xA0);
+ cPtr->writeXR(cPtr, 0xA0, (tmp & 0xF8) | 5);
+ cPtr->writeIOSS(cPtr, IOSS);
+ cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), MSS);
+ }
+ } else {
+ if(!cPtr->UseMMIO) {
+ HW_DEBUG(0x8);
+ outw(cPtr->PIOBase+DR(0x8), 0x21);
+ } else {
+ HW_DEBUG(DR(8));
+ /* Used to be: MMIOmemw(MR(8)) = 0x21; */
+ MMIOmeml(MR(8)) = 0x21;
+ }
+ }
+ cPtr->HWCursorShown = TRUE;
+}
+
+static void
+CHIPSHideCursor(ScrnInfoPtr pScrn)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ unsigned char tmp;
+
+ CURSOR_SYNC(pScrn);
+
+ /* turn the cursor off */
+ if (IS_HiQV(cPtr)) {
+ tmp = cPtr->readXR(cPtr, 0xA0);
+ cPtr->writeXR(cPtr, 0xA0, tmp & 0xF8);
+ if (cPtr->UseDualChannel &&
+ (! xf86IsEntityShared(pScrn->entityList[0]))) {
+ unsigned int IOSS, MSS;
+ IOSS = cPtr->readIOSS(cPtr);
+ MSS = cPtr->readMSS(cPtr);
+ cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) |
+ IOSS_PIPE_B));
+ cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), ((cPtr->storeMSS &
+ MSS_MASK) | MSS_PIPE_B));
+ tmp = cPtr->readXR(cPtr, 0xA0);
+ cPtr->writeXR(cPtr, 0xA0, tmp & 0xF8);
+ cPtr->writeIOSS(cPtr, IOSS);
+ cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), MSS);
+ }
+ } else {
+ if(!cPtr->UseMMIO) {
+ HW_DEBUG(0x8);
+ outw(cPtr->PIOBase+DR(0x8), 0x20);
+ } else {
+ HW_DEBUG(DR(0x8));
+ /* Used to be: MMIOmemw(DR(0x8)) = 0x20; */
+ MMIOmeml(DR(0x8)) = 0x20;
+ }
+ }
+ cPtr->HWCursorShown = FALSE;
+}
+
+static void
+CHIPSSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ CURSOR_SYNC(pScrn);
+
+ if (pScrn->currentMode->Flags & V_DBLSCAN)
+ y *= 2;
+
+ if (x < 0)
+ x = ~(x-1) | 0x8000;
+ if (y < 0)
+ y = ~(y-1) | 0x8000;
+
+ /* Program the cursor origin (offset into the cursor bitmap). */
+ if (IS_HiQV(cPtr)) {
+ cPtr->writeXR(cPtr, 0xA4, x & 0xFF);
+ cPtr->writeXR(cPtr, 0xA5, (x >> 8) & 0x87);
+ cPtr->writeXR(cPtr, 0xA6, y & 0xFF);
+ cPtr->writeXR(cPtr, 0xA7, (y >> 8) & 0x87);
+ if (cPtr->UseDualChannel &&
+ (! xf86IsEntityShared(pScrn->entityList[0]))) {
+ unsigned int IOSS, MSS;
+ IOSS = cPtr->readIOSS(cPtr);
+ MSS = cPtr->readMSS(cPtr);
+ cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) |
+ IOSS_PIPE_B));
+ cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), ((cPtr->storeMSS &
+ MSS_MASK) | MSS_PIPE_B));
+ cPtr->writeXR(cPtr, 0xA4, x & 0xFF);
+ cPtr->writeXR(cPtr, 0xA5, (x >> 8) & 0x87);
+ cPtr->writeXR(cPtr, 0xA6, y & 0xFF);
+ cPtr->writeXR(cPtr, 0xA7, (y >> 8) & 0x87);
+ cPtr->writeIOSS(cPtr, IOSS);
+ cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), MSS);
+ }
+ } else {
+ CARD32 xy;
+
+ xy = y;
+ xy = (xy << 16) | x;
+ if(!cPtr->UseMMIO) {
+ HW_DEBUG(0xB);
+ outl(cPtr->PIOBase+DR(0xB), xy);
+ } else {
+ HW_DEBUG(MR(0xB));
+ MMIOmeml(MR(0xB)) = xy;
+ }
+ }
+}
+
+static void
+CHIPSSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CARD32 packedcolfg, packedcolbg;
+
+ CURSOR_SYNC(pScrn);
+
+ if (IS_HiQV(cPtr)) {
+ unsigned char xr80;
+
+ /* Enable extended palette addressing */
+ xr80 = cPtr->readXR(cPtr, 0x80);
+ cPtr->writeXR(cPtr, 0x80, xr80 | 0x1);
+
+ /* Write the new colours to the extended VGA palette. Palette
+ * index is incremented after each write, so only write index
+ * once
+ */
+ hwp->writeDacWriteAddr(hwp, 0x04);
+ if (xr80 & 0x80) {
+ /* 8bit DAC */
+ hwp->writeDacData(hwp, (bg >> 16) & 0xFF);
+ hwp->writeDacData(hwp, (bg >> 8) & 0xFF);
+ hwp->writeDacData(hwp, bg & 0xFF);
+ hwp->writeDacData(hwp, (fg >> 16) & 0xFF);
+ hwp->writeDacData(hwp, (fg >> 8) & 0xFF);
+ hwp->writeDacData(hwp, fg & 0xFF);
+ } else {
+ /* 6bit DAC */
+ hwp->writeDacData(hwp, (bg >> 18) & 0xFF);
+ hwp->writeDacData(hwp, (bg >> 10) & 0xFF);
+ hwp->writeDacData(hwp, (bg >> 2) & 0xFF);
+ hwp->writeDacData(hwp, (fg >> 18) & 0xFF);
+ hwp->writeDacData(hwp, (fg >> 10) & 0xFF);
+ hwp->writeDacData(hwp, (fg >> 2) & 0xFF);
+ }
+ /* Enable normal palette addressing */
+ cPtr->writeXR(cPtr, 0x80, xr80);
+
+ if (cPtr->UseDualChannel &&
+ (! xf86IsEntityShared(pScrn->entityList[0]))) {
+ unsigned int IOSS, MSS;
+ IOSS = cPtr->readIOSS(cPtr);
+ MSS = cPtr->readMSS(cPtr);
+ cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) |
+ IOSS_PIPE_B));
+ cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) |
+ MSS_PIPE_B));
+ /* Enable extended palette addressing */
+ xr80 = cPtr->readXR(cPtr, 0x80);
+ cPtr->writeXR(cPtr, 0x80, xr80 | 0x1);
+
+ /* Write the new colours to the extended VGA palette. Palette
+ * index is incremented after each write, so only write index
+ * once
+ */
+ hwp->writeDacWriteAddr(hwp, 0x04);
+ if (xr80 & 0x80) {
+ /* 8bit DAC */
+ hwp->writeDacData(hwp, (bg >> 16) & 0xFF);
+ hwp->writeDacData(hwp, (bg >> 8) & 0xFF);
+ hwp->writeDacData(hwp, bg & 0xFF);
+ hwp->writeDacData(hwp, (fg >> 16) & 0xFF);
+ hwp->writeDacData(hwp, (fg >> 8) & 0xFF);
+ hwp->writeDacData(hwp, fg & 0xFF);
+ } else {
+ /* 6bit DAC */
+ hwp->writeDacData(hwp, (bg >> 18) & 0xFF);
+ hwp->writeDacData(hwp, (bg >> 10) & 0xFF);
+ hwp->writeDacData(hwp, (bg >> 2) & 0xFF);
+ hwp->writeDacData(hwp, (fg >> 18) & 0xFF);
+ hwp->writeDacData(hwp, (fg >> 10) & 0xFF);
+ hwp->writeDacData(hwp, (fg >> 2) & 0xFF);
+ }
+ /* Enable normal palette addressing */
+ cPtr->writeXR(cPtr, 0x80, xr80);
+ cPtr->writeIOSS(cPtr, IOSS);
+ cPtr->writeMSS(cPtr, hwp, MSS);
+ }
+ } else if (IS_Wingine(cPtr)) {
+ outl(cPtr->PIOBase+DR(0xA), (bg & 0xFFFFFF));
+ outl(cPtr->PIOBase+DR(0x9), (fg & 0xFFFFFF));
+ } else {
+ packedcolfg = ((fg & 0xF80000) >> 8) | ((fg & 0xFC00) >> 5)
+ | ((fg & 0xF8) >> 3);
+ packedcolbg = ((bg & 0xF80000) >> 8) | ((bg & 0xFC00) >> 5)
+ | ((bg & 0xF8) >> 3);
+ packedcolfg = (packedcolfg << 16) | packedcolbg;
+ if(!cPtr->UseMMIO) {
+ HW_DEBUG(0x9);
+ outl(cPtr->PIOBase+DR(0x9), packedcolfg);
+ } else {
+ MMIOmeml(MR(0x9)) = packedcolfg;
+ HW_DEBUG(MR(0x9));
+ }
+ }
+}
+
+static void
+CHIPSLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ CARD32 *s = (pointer)src;
+ CARD32 *d = (pointer)(cPtr->FbBase + cAcl->CursorAddress);
+ int y;
+#endif
+
+ CURSOR_SYNC(pScrn);
+
+ if (cPtr->cursorDelay) {
+ usleep(200000);
+ cPtr->cursorDelay = FALSE;
+ }
+
+ if (IS_Wingine(cPtr)) {
+ int i;
+ CARD32 *tmp = (CARD32 *)src;
+
+ outl(cPtr->PIOBase+DR(0x8),0x20);
+ for (i=0; i<64; i++) {
+ outl(cPtr->PIOBase+DR(0xC),*(CARD32 *)tmp);
+ tmp++;
+ }
+ } else {
+ if (cPtr->Flags & ChipsLinearSupport) {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ /* On big endian machines we must flip our cursor image around. */
+ switch(cAcl->BytesPerPixel) {
+ case 4:
+ case 3:
+ for (y = 0; y < 64; y++) {
+ P_SWAP32(d,s);
+ d++; s++;
+ P_SWAP32(d,s);
+ d++; s++;
+ P_SWAP32(d,s);
+ d++; s++;
+ P_SWAP32(d,s);
+ d++; s++;
+ }
+ break;
+ case 2:
+ for (y = 0; y < 64; y++) {
+ P_SWAP16(d,s);
+ d++; s++;
+ P_SWAP16(d,s);
+ d++; s++;
+ P_SWAP16(d,s);
+ d++; s++;
+ P_SWAP16(d,s);
+ d++; s++;
+ P_SWAP16(d,s);
+ d++; s++;
+ }
+ break;
+ default:
+ for (y = 0; y < 64; y++) {
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ }
+ }
+#else
+ memcpy((unsigned char *)cPtr->FbBase + cAcl->CursorAddress,
+ src, cPtr->CursorInfoRec->MaxWidth *
+ cPtr->CursorInfoRec->MaxHeight / 4);
+#endif
+ } else {
+ /*
+ * The cursor can only be in the last 16K of video memory,
+ * which fits in the last banking window.
+ */
+ if (IS_HiQV(cPtr))
+ if (pScrn->bitsPerPixel < 8)
+ CHIPSHiQVSetReadWritePlanar(pScrn->pScreen,
+ (int)(cAcl->CursorAddress >> 16));
+ else
+ CHIPSHiQVSetReadWrite(pScrn->pScreen,
+ (int)(cAcl->CursorAddress >> 16));
+ else
+ if (pScrn->bitsPerPixel < 8)
+ CHIPSSetWritePlanar(pScrn->pScreen,
+ (int)(cAcl->CursorAddress >> 16));
+ else
+ CHIPSSetWrite(pScrn->pScreen,
+ (int)(cAcl->CursorAddress >> 16));
+ memcpy((unsigned char *)cPtr->FbBase + (cAcl->CursorAddress &
+ 0xFFFF), src, cPtr->CursorInfoRec->MaxWidth *
+ cPtr->CursorInfoRec->MaxHeight / 4);
+ }
+ }
+
+ /* set cursor address here or we loose the cursor on video mode change */
+ if (IS_HiQV(cPtr)) {
+ cPtr->writeXR(cPtr, 0xA2, (cAcl->CursorAddress >> 8) & 0xFF);
+ cPtr->writeXR(cPtr, 0xA3, (cAcl->CursorAddress >> 16) & 0x3F);
+ if (cPtr->UseDualChannel &&
+ (! xf86IsEntityShared(pScrn->entityList[0]))) {
+ unsigned int IOSS, MSS;
+ IOSS = cPtr->readIOSS(cPtr);
+ MSS = cPtr->readMSS(cPtr);
+ cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) |
+ IOSS_PIPE_B));
+ cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), ((cPtr->storeMSS &
+ MSS_MASK) | MSS_PIPE_B));
+ cPtr->writeXR(cPtr, 0xA2, (cAcl->CursorAddress >> 8) & 0xFF);
+ cPtr->writeXR(cPtr, 0xA3, (cAcl->CursorAddress >> 16) & 0x3F);
+ cPtr->writeIOSS(cPtr, IOSS);
+ cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), MSS);
+ }
+ } else if (!IS_Wingine(cPtr)) {
+ if (!cPtr->UseMMIO) {
+ HW_DEBUG(0xC);
+ outl(cPtr->PIOBase+DR(0xC), cAcl->CursorAddress);
+ } else {
+ HW_DEBUG(MR(0xC));
+ MMIOmeml(MR(0xC)) = cAcl->CursorAddress;
+ }
+ }
+}
+
+static Bool
+CHIPSUseHWCursor(ScreenPtr pScr, CursorPtr pCurs)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScr->myNum]);
+ return ((cPtr->Flags & ChipsHWCursor) != 0);
+}
+
+Bool
+CHIPSCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr) return FALSE;
+
+ cPtr->CursorInfoRec = infoPtr;
+
+ infoPtr->Flags =
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+#endif
+ HARDWARE_CURSOR_INVERT_MASK |
+ HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
+ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP;
+
+ if (IS_HiQV(cPtr)) {
+ infoPtr->Flags |= HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64;
+ infoPtr->MaxHeight = 64;
+ infoPtr->MaxWidth = 64;
+ } else if (IS_Wingine(cPtr)) {
+ infoPtr->Flags |= HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED;
+ infoPtr->MaxHeight = 32;
+ infoPtr->MaxWidth = 32;
+ } else {
+ infoPtr->Flags |= HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8;
+ infoPtr->MaxHeight = 32;
+ infoPtr->MaxWidth = 32;
+ }
+
+ infoPtr->SetCursorColors = CHIPSSetCursorColors;
+ infoPtr->SetCursorPosition = CHIPSSetCursorPosition;
+ infoPtr->LoadCursorImage = CHIPSLoadCursorImage;
+ infoPtr->HideCursor = CHIPSHideCursor;
+ infoPtr->ShowCursor = CHIPSShowCursor;
+ infoPtr->UseHWCursor = CHIPSUseHWCursor;
+
+ return(xf86InitCursor(pScreen, infoPtr));
+}
+
diff --git a/src/ct_ddc.c b/src/ct_ddc.c
new file mode 100644
index 0000000..0286685
--- /dev/null
+++ b/src/ct_ddc.c
@@ -0,0 +1,282 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_ddc.c,v 1.8 2001/05/09 19:57:04 dbateman Exp $ */
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+/* Everything using inb/outb, etc needs "compiler.h" */
+#include "compiler.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 "ct_driver.h"
+
+static Bool chips_TestI2C(int scrnIndex);
+static Bool chips_setI2CBits(I2CBusPtr I2CPtr, ScrnInfoPtr pScrn);
+
+static unsigned int
+chips_ddc1Read(ScrnInfoPtr pScrn)
+{
+ unsigned char ddc_mask = ((CHIPSPtr)pScrn->driverPrivate)->ddc_mask;
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ register unsigned int tmp;
+
+ while ((hwp->readST01(hwp)) & 0x08){};
+ while (!(hwp->readST01(hwp)) & 0x08){};
+ tmp = cPtr->readXR(cPtr, 0x63);
+ return (tmp & ddc_mask);
+}
+
+void
+chips_ddc1(ScrnInfoPtr pScrn)
+{
+ unsigned char FR0B, FR0C, XR62;
+ unsigned char mask_c = 0x00;
+ unsigned char val, tmp_val;
+ int i;
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Probing for DDC1\n");
+
+ FR0C = cPtr->readFR(cPtr, 0x0C);
+ XR62 = cPtr->readXR(cPtr, 0x62);
+ switch (cPtr->Chipset) {
+ case CHIPS_CT65550:
+ cPtr->ddc_mask = 0x1F; /* GPIO 0-4 */
+ FR0B = cPtr->readFR(cPtr, 0x0B);
+ if (!(FR0B & 0x10)) /* GPIO 2 is used as 32 kHz input */
+ cPtr->ddc_mask &= 0xFB;
+ if (cPtr->Bus == ChipsVLB) /* GPIO 3-7 are used as address bits */
+ cPtr->ddc_mask &= 0x07;
+ break;
+ case CHIPS_CT65554:
+ case CHIPS_CT65555:
+ case CHIPS_CT68554:
+ cPtr->ddc_mask = 0x0F; /* GPIO 0-3 */
+ break;
+ case CHIPS_CT69000:
+ case CHIPS_CT69030:
+ cPtr->ddc_mask = 0x9F; /* GPIO 0-4,7? */
+ break;
+ default:
+ cPtr->ddc_mask = 0x0C; /* GPIO 2,3 */
+ break;
+ }
+ if (!(FR0C & 0x80)) { /* GPIO 1 is not available */
+ mask_c |= 0xC0;
+ cPtr->ddc_mask &= 0xFE;
+ }
+ if (!(FR0C & 0x10)) { /* GPIO 0 is not available */
+ mask_c |= 0x18;
+ cPtr->ddc_mask &= 0xFD;
+ }
+
+ /* set GPIO 0,1 to read if available */
+ cPtr->writeFR(cPtr, 0x0C, (FR0C & mask_c) | (~mask_c & 0x90));
+ /* set remaining GPIO to read */
+ cPtr->writeXR(cPtr, 0x62, 0x00);
+
+ val = chips_ddc1Read(pScrn);
+ for (i = 0; i < 70; i++) {
+ tmp_val = chips_ddc1Read(pScrn);
+ if (tmp_val != val)
+ break;
+ }
+ cPtr->ddc_mask = val ^ tmp_val;
+ if (cPtr->ddc_mask)
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DDC1 found\n");
+ else return;
+
+ xf86PrintEDID(xf86DoEDID_DDC1(pScrn->scrnIndex,vgaHWddc1SetSpeed,
+ chips_ddc1Read));
+
+ /* restore */
+ cPtr->writeFR(cPtr, 0x0C, FR0C);
+ cPtr->writeXR(cPtr, 0x62, XR62);
+}
+
+static void
+chips_I2CGetBits(I2CBusPtr b, int *clock, int *data)
+{
+ CHIPSI2CPtr pI2C_c = (CHIPSI2CPtr) (b->DriverPrivate.ptr);
+ unsigned char FR0C, XR62, val;
+
+ FR0C = pI2C_c->cPtr->readFR(pI2C_c->cPtr, 0x0C);
+ if (pI2C_c->i2cDataBit & 0x01 || pI2C_c->i2cClockBit & 0x01)
+ FR0C = (FR0C & 0xE7) | 0x10;
+ if (pI2C_c->i2cDataBit & 0x02 || pI2C_c->i2cClockBit & 0x02)
+ FR0C = (FR0C & 0x3F) | 0x80;
+ XR62 = pI2C_c->cPtr->readXR(pI2C_c->cPtr, 0x62);
+ XR62 &= (~pI2C_c->i2cDataBit) & (~pI2C_c->i2cClockBit);
+ pI2C_c->cPtr->writeFR(pI2C_c->cPtr, 0x0C, FR0C);
+ pI2C_c->cPtr->writeXR(pI2C_c->cPtr, 0x62, XR62);
+ val = pI2C_c->cPtr->readXR(pI2C_c->cPtr, 0x63);
+ *clock = (val & pI2C_c->i2cClockBit) != 0;
+ *data = (val & pI2C_c->i2cDataBit) != 0;
+}
+
+static void
+chips_I2CPutBits(I2CBusPtr b, int clock, int data)
+{
+ CHIPSI2CPtr pI2C_c = (CHIPSI2CPtr) (b->DriverPrivate.ptr);
+ unsigned char FR0C, XR62, val;
+
+ FR0C = pI2C_c->cPtr->readFR(pI2C_c->cPtr, 0x0C);
+ if (((pI2C_c->i2cDataBit & 0x01) && data)
+ || ((pI2C_c->i2cClockBit & 0x01) && clock))
+ FR0C |= 0x18;
+ else if ((pI2C_c->i2cDataBit & 0x01)
+ || (pI2C_c->i2cClockBit & 0x01))
+ FR0C |= 0x10;
+ if (((pI2C_c->i2cDataBit & 0x02) && data)
+ || ((pI2C_c->i2cClockBit & 0x02) && clock))
+ FR0C |= 0xC0;
+ else if ((pI2C_c->i2cDataBit & 0x02)
+ || (pI2C_c->i2cClockBit & 0x02))
+ FR0C |= 0x80;
+ XR62 = pI2C_c->cPtr->readXR(pI2C_c->cPtr, 0x62);
+ XR62 = (XR62 & ~pI2C_c->i2cClockBit) | (clock ? pI2C_c->i2cClockBit : 0);
+ XR62 = (XR62 & ~pI2C_c->i2cDataBit) | (data ? pI2C_c->i2cDataBit : 0);
+ pI2C_c->cPtr->writeFR(pI2C_c->cPtr, 0x0C, FR0C);
+ pI2C_c->cPtr->writeXR(pI2C_c->cPtr, 0x62, XR62);
+ val = pI2C_c->cPtr->readXR(pI2C_c->cPtr, 0x63);
+ val = (val & ~pI2C_c->i2cClockBit) | (clock ? pI2C_c->i2cClockBit : 0);
+ val = (val & ~pI2C_c->i2cDataBit) | (data ? pI2C_c->i2cDataBit : 0);
+ pI2C_c->cPtr->writeXR(pI2C_c->cPtr, 0x63, val);
+}
+
+
+Bool
+chips_i2cInit(ScrnInfoPtr pScrn)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ I2CBusPtr I2CPtr;
+
+ I2CPtr = xf86CreateI2CBusRec();
+ if(!I2CPtr) return FALSE;
+
+ cPtr->I2C = I2CPtr;
+
+ I2CPtr->BusName = "DDC";
+ I2CPtr->scrnIndex = pScrn->scrnIndex;
+ I2CPtr->I2CPutBits = chips_I2CPutBits;
+ I2CPtr->I2CGetBits = chips_I2CGetBits;
+ I2CPtr->DriverPrivate.ptr = xalloc(sizeof(CHIPSI2CRec));
+ ((CHIPSI2CPtr)(I2CPtr->DriverPrivate.ptr))->cPtr = cPtr;
+
+ if (!xf86I2CBusInit(I2CPtr))
+ return FALSE;
+
+ if (!chips_setI2CBits(I2CPtr, pScrn))
+ return FALSE;
+
+ return TRUE;
+}
+
+static Bool
+chips_setI2CBits(I2CBusPtr b, ScrnInfoPtr pScrn)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSI2CPtr pI2C_c = (CHIPSI2CPtr) (b->DriverPrivate.ptr);
+ unsigned char FR0B, FR0C;
+ unsigned char bits, data_bits, clock_bits;
+ int i,j;
+
+ FR0C = cPtr->readFR(cPtr, 0x0C);
+ switch (cPtr->Chipset) {
+ case CHIPS_CT65550:
+ bits = 0x1F; /* GPIO 0-4 */
+ FR0B = cPtr->readFR(cPtr, 0x0B);
+ if (!(FR0B & 0x10)) /* GPIO 2 is used as 32 kHz input */
+ bits &= 0xFB;
+ pI2C_c->i2cDataBit = 0x01;
+ pI2C_c->i2cClockBit = 0x02;
+ if (cPtr->Bus == ChipsVLB) /* GPIO 3-7 are used as address bits */
+ bits &= 0x07;
+ break;
+ case CHIPS_CT65554:
+ case CHIPS_CT65555:
+ case CHIPS_CT68554:
+ bits = 0x0F; /* GPIO 0-3 */
+ pI2C_c->i2cDataBit = 0x04;
+ pI2C_c->i2cClockBit = 0x08;
+ break;
+ case CHIPS_CT69000:
+ case CHIPS_CT69030:
+ bits = 0x9F; /* GPIO 0-4,7? */
+ pI2C_c->i2cDataBit = 0x04;
+ pI2C_c->i2cClockBit = 0x08;
+ break;
+ default:
+ bits = 0x0C; /* GPIO 2,3 */
+ pI2C_c->i2cDataBit = 0x04;
+ pI2C_c->i2cClockBit = 0x08;
+ break;
+ }
+ if (!(FR0C & 0x80)) { /* GPIO 1 is not available */
+ bits &= 0xFE;
+ }
+ if (!(FR0C & 0x10)) { /* GPIO 0 is not available */
+ bits &= 0xFD;
+ }
+ pI2C_c->i2cClockBit &= bits;
+ pI2C_c->i2cDataBit &= bits;
+ /*
+ * first we test out the "favorite" GPIO bits ie. the ones suggested
+ * by the data book; if we don't succeed test all other combinations
+ * of possible GPIO pins as data/clock lines as the manufacturer might
+ * have its own ideas.
+ */
+ if (chips_TestI2C(pScrn->scrnIndex)) return TRUE;
+
+ data_bits = bits;
+ pI2C_c->i2cDataBit = 0x01;
+ for (i = 0; i<8; i++) {
+ if (data_bits & 0x01) {
+ clock_bits = bits;
+ pI2C_c->i2cClockBit = 0x01;
+ for (j = 0; j<8; j++) {
+ if (clock_bits & 0x01)
+ if (chips_TestI2C(pScrn->scrnIndex)) return TRUE;
+ clock_bits >>= 1;
+ pI2C_c->i2cClockBit <<= 1;
+ }
+ }
+ data_bits >>= 1;
+ pI2C_c->i2cDataBit <<= 1;
+ }
+ /*
+ * We haven't found a valid clock/data line combination - that
+ * doesn't mean there aren't any. We just haven't received an
+ * answer from the relevant DDC I2C addresses. We'll have to wait
+ * and see, if this is too restrictive (eg one wants to use I2C
+ * for something else than DDC we might have to probe more addresses
+ * or just fall back to the "favorite" GPIO lines.
+ */
+ return FALSE;
+}
+
+static Bool
+chips_TestI2C(int scrnIndex)
+{
+ int i;
+ I2CBusPtr b;
+
+ b = xf86I2CFindBus(scrnIndex, "DDC");
+ if (b == NULL) return FALSE;
+ else {
+ for(i = 0xA0; i < 0xA8; i += 2)
+ if(xf86I2CProbeAddress(b, i))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
diff --git a/src/ct_dga.c b/src/ct_dga.c
new file mode 100644
index 0000000..3d0fe26
--- /dev/null
+++ b/src/ct_dga.c
@@ -0,0 +1,316 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_dga.c,v 1.5 2002/11/25 14:04:58 eich 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 "ct_driver.h"
+#include "dgaproc.h"
+
+
+static Bool CHIPS_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
+ int *, int *, int *);
+static Bool CHIPS_SetMode(ScrnInfoPtr, DGAModePtr);
+static int CHIPS_GetViewport(ScrnInfoPtr);
+static void CHIPS_SetViewport(ScrnInfoPtr, int, int, int);
+static void CHIPS_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
+static void CHIPS_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
+#if 0
+static void CHIPS_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
+ unsigned long);
+#endif
+
+static
+DGAFunctionRec CHIPS_DGAFuncs = {
+ CHIPS_OpenFramebuffer,
+ NULL,
+ CHIPS_SetMode,
+ CHIPS_SetViewport,
+ CHIPS_GetViewport,
+ CHIPSSync,
+ CHIPS_FillRect,
+ CHIPS_BlitRect,
+#if 0
+ CHIPS_BlitTransRect
+#else
+ NULL
+#endif
+};
+
+static
+DGAFunctionRec CHIPS_MMIODGAFuncs = {
+ CHIPS_OpenFramebuffer,
+ NULL,
+ CHIPS_SetMode,
+ CHIPS_SetViewport,
+ CHIPS_GetViewport,
+ CHIPSMMIOSync,
+ CHIPS_FillRect,
+ CHIPS_BlitRect,
+#if 0
+ CHIPS_BlitTransRect
+#else
+ NULL
+#endif
+};
+
+static
+DGAFunctionRec CHIPS_HiQVDGAFuncs = {
+ CHIPS_OpenFramebuffer,
+ NULL,
+ CHIPS_SetMode,
+ CHIPS_SetViewport,
+ CHIPS_GetViewport,
+ CHIPSHiQVSync,
+ CHIPS_FillRect,
+ CHIPS_BlitRect,
+#if 0
+ CHIPS_BlitTransRect
+#else
+ NULL
+#endif
+};
+
+
+Bool
+CHIPSDGAInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ DGAModePtr modes = NULL, newmodes = NULL, currentMode;
+ DisplayModePtr pMode, firstMode;
+ int Bpp = pScrn->bitsPerPixel >> 3;
+ int num = 0;
+ Bool oneMore;
+ int imlines = (pScrn->videoRam * 1024) /
+ (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3));
+
+ 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(cPtr->Flags & ChipsAccelSupport)
+ currentMode->flags |= (cPtr->Flags & ChipsAccelSupport)
+ ? (DGA_FILL_RECT | DGA_BLIT_RECT) : 0;
+ 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 | DGA_FLIP_IMMEDIATE;
+ currentMode->offset = 0;
+ currentMode->address = cPtr->FbBase;
+
+ if(oneMore) { /* first one is narrow width */
+ currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L;
+ currentMode->imageWidth = pMode->HDisplay;
+ currentMode->imageHeight = imlines;
+ 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 = imlines;
+ 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;
+ }
+
+ cPtr->numDGAModes = num;
+ cPtr->DGAModes = modes;
+
+ if (IS_HiQV(cPtr)) {
+ return DGAInit(pScreen, &CHIPS_HiQVDGAFuncs, modes, num);
+ } else {
+ if(!cPtr->UseMMIO) {
+ return DGAInit(pScreen, &CHIPS_DGAFuncs, modes, num);
+ } else {
+ return DGAInit(pScreen, &CHIPS_MMIODGAFuncs, modes, num);
+ }
+ }
+}
+
+
+static Bool
+CHIPS_SetMode(
+ ScrnInfoPtr pScrn,
+ DGAModePtr pMode
+){
+ static int OldDisplayWidth[MAXSCREENS];
+ int index = pScrn->pScreen->myNum;
+
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ if (!pMode) { /* restore the original mode */
+ /* put the ScreenParameters back */
+ if (cPtr->DGAactive) {
+ pScrn->displayWidth = OldDisplayWidth[index];
+ pScrn->EnterVT(pScrn->scrnIndex,0);
+
+ cPtr->DGAactive = FALSE;
+ }
+ } else {
+ if(!cPtr->DGAactive) { /* save the old parameters */
+ OldDisplayWidth[index] = pScrn->displayWidth;
+ pScrn->LeaveVT(pScrn->scrnIndex,0);
+ cPtr->DGAactive = TRUE;
+ }
+
+ pScrn->displayWidth = pMode->bytesPerScanline /
+ (pMode->bitsPerPixel >> 3);
+
+ CHIPSSwitchMode(index, pMode->mode, 0);
+ }
+
+ return TRUE;
+}
+
+
+
+static int
+CHIPS_GetViewport(
+ ScrnInfoPtr pScrn
+){
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ return cPtr->DGAViewportStatus;
+}
+
+static void
+CHIPS_SetViewport(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int flags
+ ){
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ if (flags & DGA_FLIP_RETRACE) {
+ while ((hwp->readST01(hwp)) & 0x08){};
+ while (!(hwp->readST01(hwp)) & 0x08){};
+ }
+
+ CHIPSAdjustFrame(pScrn->pScreen->myNum, x, y, flags);
+ cPtr->DGAViewportStatus = 0; /* CHIPSAdjustFrame loops until finished */
+}
+
+static void
+CHIPS_FillRect (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned long color
+){
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ if(cPtr->AccelInfoRec) {
+ (*cPtr->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
+ (*cPtr->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ SET_SYNC_FLAG(cPtr->AccelInfoRec);
+ }
+}
+
+static void
+CHIPS_BlitRect(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty
+){
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ if(cPtr->AccelInfoRec) {
+ int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
+ int ydir = (srcy < dsty) ? -1 : 1;
+
+ (*cPtr->AccelInfoRec->SetupForScreenToScreenCopy)(
+ pScrn, xdir, ydir, GXcopy, ~0, -1);
+ (*cPtr->AccelInfoRec->SubsequentScreenToScreenCopy)(
+ pScrn, srcx, srcy, dstx, dsty, w, h);
+ SET_SYNC_FLAG(cPtr->AccelInfoRec);
+ }
+}
+
+#if 0
+static void
+CHIPS_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
+CHIPS_OpenFramebuffer(
+ ScrnInfoPtr pScrn,
+ char **name,
+ unsigned char **mem,
+ int *size,
+ int *offset,
+ int *flags
+){
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ *name = NULL; /* no special device */
+ *mem = (unsigned char*)cPtr->FbAddress;
+ *size = cPtr->FbMapSize;
+ *offset = 0;
+ *flags = DGA_NEED_ROOT;
+
+ return TRUE;
+}
diff --git a/src/ct_driver.c b/src/ct_driver.c
new file mode 100644
index 0000000..2aa6cc2
--- /dev/null
+++ b/src/ct_driver.c
@@ -0,0 +1,7487 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_driver.c,v 1.122 2002/11/25 14:04:58 eich Exp $ */
+
+/*
+ * Copyright 1993 by Jon Block <block@frc.com>
+ * Modified by Mike Hollick <hollick@graphics.cis.upenn.edu>
+ * Modified 1994 by Régis Cridlig <cridlig@dmi.ens.fr>
+ *
+ * Major Contributors to XFree86 3.2
+ * Modified 1995/6 by Nozomi Ytow
+ * Modified 1996 by Egbert Eich <eich@xfree86.org>
+ * Modified 1996 by David Bateman <dbateman@club-internet.fr>
+ * Modified 1996 by Xavier Ducoin <xavier@rd.lectra.fr>
+ *
+ * Contributors to XFree86 3.2
+ * Modified 1995/6 by Ken Raeburn <raeburn@raeburn.org>
+ * Modified 1996 by Shigehiro Nomura <nomura@sm.sony.co.jp>
+ * Modified 1996 by Marc de Courville <marc@courville.org>
+ * Modified 1996 by Adam Sulmicki <adam@cfar.umd.edu>
+ * Modified 1996 by Jens Maurer <jmaurer@cck.uni-kl.de>
+ *
+ * Large parts rewritten for XFree86 4.0
+ * Modified 1998 by David Bateman <dbateman@club-internet.fr>
+ * Modified 1998 by Egbert Eich <eich@xfree86.org>
+ * Modified 1998 by Nozomi Ytow
+ *
+ * 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 the authors not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHORS 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.
+ */
+/*
+ * Copyright 1997
+ * Digital Equipment Corporation. All rights reserved.
+ * This software is furnished under license and may be used and copied only in
+ * accordance with the following terms and conditions. Subject to these
+ * conditions, you may download, copy, install, use, modify and distribute
+ * this software in source and/or binary form. No title or ownership is
+ * transferred hereby.
+ * 1) Any source code used, modified or distributed must reproduce and retain
+ * this copyright notice and list of conditions as they appear in the
+ * source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or logo of Digital
+ * Equipment Corporation. Neither the "Digital Equipment Corporation" name
+ * nor any trademark or logo of Digital Equipment Corporation may be used
+ * to endorse or promote products derived from this software without the
+ * prior written permission of Digital Equipment Corporation.
+ *
+ * 3) This software is provided "AS-IS" and any express or implied warranties,
+ * including but not limited to, any implied warranties of merchantability,
+ * fitness for a particular purpose, or non-infringement are disclaimed. In
+ * no event shall DIGITAL be liable for any damages whatsoever, and in
+ * particular, DIGITAL shall not be liable for special, indirect,
+ * consequential, or incidental damages or damages for lost profits, loss
+ * of revenue or loss of use, whether such damages arise in contract,
+ * negligence, tort, under statute, in equity, at law or otherwise, even if
+ * advised of the possibility of such damage.
+ */
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+/* Everything using inb/outb, etc needs "compiler.h" */
+#include "compiler.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"
+
+/* This is used for module versioning */
+#include "xf86Version.h"
+
+/* Standard resources are defined here */
+#include "xf86Resources.h"
+
+/* All drivers using the vgahw module need this */
+#include "vgaHW.h"
+
+/* All drivers initialising the SW cursor need this */
+#include "mipointer.h"
+
+/* All drivers implementing backing store need this */
+#include "mibstore.h"
+
+/* All drivers using the mi banking wrapper need this */
+#include "mibank.h"
+
+/* All drivers using the mi colormap manipulation need this */
+#include "micmap.h"
+
+#include "fb.h"
+#include "cfb8_16.h"
+
+
+/* Needed for the 1 and 4 bpp framebuffers */
+#include "xf1bpp.h"
+#include "xf4bpp.h"
+
+/* Needed by Resources Access Control (RAC) */
+#include "xf86RAC.h"
+
+/* int10 */
+#include "xf86int10.h"
+#include "vbe.h"
+
+/* Needed by the Shadow Framebuffer */
+#include "shadowfb.h"
+
+/* Needed for replacement LoadPalette function for Gamma Correction */
+#include "xf86cmap.h"
+
+#include "dixstruct.h"
+
+/* Driver specific headers */
+#include "ct_driver.h"
+
+/* Mandatory functions */
+static const OptionInfoRec * CHIPSAvailableOptions(int chipid, int busid);
+static void CHIPSIdentify(int flags);
+static Bool CHIPSProbe(DriverPtr drv, int flags);
+static Bool CHIPSPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool CHIPSScreenInit(int Index, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool CHIPSEnterVT(int scrnIndex, int flags);
+static void CHIPSLeaveVT(int scrnIndex, int flags);
+static Bool CHIPSCloseScreen(int scrnIndex, ScreenPtr pScreen);
+static void CHIPSFreeScreen(int scrnIndex, int flags);
+static int CHIPSValidMode(int scrnIndex, DisplayModePtr mode,
+ Bool verbose, int flags);
+static Bool CHIPSSaveScreen(ScreenPtr pScreen, int mode);
+
+/* Internally used functions */
+static int chipsFindIsaDevice(GDevPtr dev);
+static Bool chipsClockSelect(ScrnInfoPtr pScrn, int no);
+Bool chipsModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static void chipsSave(ScrnInfoPtr pScrn, vgaRegPtr VgaSave,
+ CHIPSRegPtr ChipsSave);
+static void chipsRestore(ScrnInfoPtr pScrn, vgaRegPtr VgaReg,
+ CHIPSRegPtr ChipsReg, Bool restoreFonts);
+static void chipsLock(ScrnInfoPtr pScrn);
+static void chipsUnlock(ScrnInfoPtr pScrn);
+static void chipsClockSave(ScrnInfoPtr pScrn, CHIPSClockPtr Clock);
+static void chipsClockLoad(ScrnInfoPtr pScrn, CHIPSClockPtr Clock);
+static Bool chipsClockFind(ScrnInfoPtr pScrn, int no, CHIPSClockPtr Clock);
+static void chipsCalcClock(ScrnInfoPtr pScrn, int Clock,
+ unsigned char *vclk);
+static int chipsGetHWClock(ScrnInfoPtr pScrn);
+static Bool chipsPreInit655xx(ScrnInfoPtr pScrn, int flags);
+static Bool chipsPreInitHiQV(ScrnInfoPtr pScrn, int flags);
+static Bool chipsPreInitWingine(ScrnInfoPtr pScrn, int flags);
+static int chipsSetMonitor(ScrnInfoPtr pScrn);
+static Bool chipsMapMem(ScrnInfoPtr pScrn);
+static Bool chipsUnmapMem(ScrnInfoPtr pScrn);
+static void chipsProtect(ScrnInfoPtr pScrn, Bool on);
+static void chipsBlankScreen(ScrnInfoPtr pScrn, Bool unblank);
+static void chipsRestoreExtendedRegs(ScrnInfoPtr pScrn, CHIPSRegPtr Regs);
+static void chipsRestoreStretching(ScrnInfoPtr pScrn,
+ unsigned char ctHorizontalStretch,
+ unsigned char ctVerticalStretch);
+static Bool chipsModeInitHiQV(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static Bool chipsModeInitWingine(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static Bool chipsModeInit655xx(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static int chipsVideoMode(int vgaBitsPerPixel,int displayHSize,
+ int displayVSize);
+static void chipsDisplayPowerManagementSet(ScrnInfoPtr pScrn,
+ int PowerManagementMode, int flags);
+static void chipsHWCursorOn(CHIPSPtr cPtr, ScrnInfoPtr pScrn);
+static void chipsHWCursorOff(CHIPSPtr cPtr, ScrnInfoPtr pScrn);
+static void chipsFixResume(ScrnInfoPtr pScrn);
+static void chipsLoadPalette(ScrnInfoPtr pScrn, int numColors,
+ int *indices, LOCO *colors, VisualPtr pVisual);
+static void chipsLoadPalette16(ScrnInfoPtr pScrn, int numColors,
+ int *indices, LOCO *colors, VisualPtr pVisual);
+static void chipsSetPanelType(CHIPSPtr cPtr);
+static void chipsBlockHandler(int, pointer, pointer, pointer);
+
+/*
+ * This is intentionally screen-independent. It indicates the binding
+ * choice made in the first PreInit.
+ */
+static int pix24bpp = 0;
+
+/*
+ * Index of Entity
+ */
+static int CHIPSEntityIndex = -1;
+
+
+/* Set the non-documented SAR04 register for overlay/video */
+#define SAR04
+
+/*
+ * Initialise some arrays that are used in multiple instances of the
+ * acceleration code. Set them up here as its a convenient place to do it.
+ */
+/* alu to C&T conversion for use with source data */
+int ChipsAluConv[] =
+{
+ 0x00, /* dest = 0; GXclear, 0 */
+ 0x88, /* dest &= src; GXand, 0x1 */
+ 0x44, /* dest = src & ~dest; GXandReverse, 0x2 */
+ 0xCC, /* dest = src; GXcopy, 0x3 */
+ 0x22, /* dest &= ~src; GXandInverted, 0x4 */
+ 0xAA, /* dest = dest; GXnoop, 0x5 */
+ 0x66, /* dest = ^src; GXxor, 0x6 */
+ 0xEE, /* dest |= src; GXor, 0x7 */
+ 0x11, /* dest = ~src & ~dest;GXnor, 0x8 */
+ 0x99, /* dest ^= ~src ;GXequiv, 0x9 */
+ 0x55, /* dest = ~dest; GXInvert, 0xA */
+ 0xDD, /* dest = src|~dest ;GXorReverse, 0xB */
+ 0x33, /* dest = ~src; GXcopyInverted, 0xC */
+ 0xBB, /* dest |= ~src; GXorInverted, 0xD */
+ 0x77, /* dest = ~src|~dest ;GXnand, 0xE */
+ 0xFF, /* dest = 0xFF; GXset, 0xF */
+};
+
+/* alu to C&T conversion for use with pattern data */
+int ChipsAluConv2[] =
+{
+ 0x00, /* dest = 0; GXclear, 0 */
+ 0xA0, /* dest &= src; GXand, 0x1 */
+ 0x50, /* dest = src & ~dest; GXandReverse, 0x2 */
+ 0xF0, /* dest = src; GXcopy, 0x3 */
+ 0x0A, /* dest &= ~src; GXandInverted, 0x4 */
+ 0xAA, /* dest = dest; GXnoop, 0x5 */
+ 0x5A, /* dest = ^src; GXxor, 0x6 */
+ 0xFA, /* dest |= src; GXor, 0x7 */
+ 0x05, /* dest = ~src & ~dest;GXnor, 0x8 */
+ 0xA5, /* dest ^= ~src ;GXequiv, 0x9 */
+ 0x55, /* dest = ~dest; GXInvert, 0xA */
+ 0xF5, /* dest = src|~dest ;GXorReverse, 0xB */
+ 0x0F, /* dest = ~src; GXcopyInverted, 0xC */
+ 0xAF, /* dest |= ~src; GXorInverted, 0xD */
+ 0x5F, /* dest = ~src|~dest ;GXnand, 0xE */
+ 0xFF, /* dest = 0xFF; GXset, 0xF */
+};
+
+/* alu to C&T conversion for use with pattern data as a planemask */
+int ChipsAluConv3[] =
+{
+ 0x0A, /* dest = 0; GXclear, 0 */
+ 0x8A, /* dest &= src; GXand, 0x1 */
+ 0x4A, /* dest = src & ~dest; GXandReverse, 0x2 */
+ 0xCA, /* dest = src; GXcopy, 0x3 */
+ 0x2A, /* dest &= ~src; GXandInverted, 0x4 */
+ 0xAA, /* dest = dest; GXnoop, 0x5 */
+ 0x6A, /* dest = ^src; GXxor, 0x6 */
+ 0xEA, /* dest |= src; GXor, 0x7 */
+ 0x1A, /* dest = ~src & ~dest;GXnor, 0x8 */
+ 0x9A, /* dest ^= ~src ;GXequiv, 0x9 */
+ 0x5A, /* dest = ~dest; GXInvert, 0xA */
+ 0xDA, /* dest = src|~dest ;GXorReverse, 0xB */
+ 0x3A, /* dest = ~src; GXcopyInverted, 0xC */
+ 0xBA, /* dest |= ~src; GXorInverted, 0xD */
+ 0x7A, /* dest = ~src|~dest ;GXnand, 0xE */
+ 0xFA, /* dest = 0xFF; GXset, 0xF */
+};
+
+/* The addresses of the acceleration registers */
+unsigned int ChipsReg32HiQV[] =
+{
+ 0x00, /* BR00 Source and Destination offset register */
+ 0x04, /* BR01 Color expansion background color */
+ 0x08, /* BR02 Color expansion foreground color */
+ 0x0C, /* BR03 Monochrome source control register */
+ 0x10, /* BR04 BitBLT control register */
+ 0x14, /* BR05 Pattern address register */
+ 0x18, /* BR06 Source address register */
+ 0x1C, /* BR07 Destination address register */
+ 0x20 /* BR08 Destination width and height register */
+};
+
+unsigned int ChipsReg32[] =
+{
+ /*BitBLT */
+ 0x83D0, /*DR0 src/dest offset */
+ 0x87D0, /*DR1 BitBlt. address of freeVram? */
+ 0x8BD0, /*DR2 BitBlt. paintBrush, or tile pat.*/
+ 0x8FD0, /*DR3 */
+ 0x93D0, /*DR4 BitBlt. */
+ 0x97D0, /*DR5 BitBlt. srcAddr, or 0 in VRAM */
+ 0x9BD0, /*DR6 BitBlt. dest? */
+ 0x9FD0, /*DR7 BitBlt. width << 16 | height */
+ /*H/W cursor */
+ 0xA3D0, /*DR8 write/erase cursor */
+ /*bit 0-1 if 0 cursor is not shown
+ * if 1 32x32 cursor
+ * if 2 64x64 cursor
+ * if 3 128x128 cursor
+ */
+ /* bit 7 if 1 cursor is not shown */
+ /* bit 9 cursor expansion in X */
+ /* bit 10 cursor expansion in Y */
+ 0xA7D0, /* DR9 foreGroundCursorColor */
+ 0xABD0, /* DR0xA backGroundCursorColor */
+ 0xAFD0, /* DR0xB cursorPosition */
+ /* bit 0-7 x coordinate */
+ /* bit 8-14 0 */
+ /* bit 15 x signum */
+ /* bit 16-23 y coordinate */
+ /* bit 24-30 0 */
+ /* bit 31 y signum */
+ 0xB3D0, /* DR0xC address of cursor pattern */
+};
+
+#if defined(__arm32__) && defined(__NetBSD__)
+/*
+ * Built in TV output modes: These modes have been tested on NetBSD with
+ * CT65550 and StrongARM. They give what seems to be the best output for
+ * a roughly 640x480 display. To enable one of the built in modes, add
+ * the identifier "NTSC" or "PAL" to the list of modes in the appropriate
+ * "Display" subsection of the "Screen" section in the XF86Config file.
+ * Note that the call to xf86SetTVOut(), which tells the kernel to enable
+ * TV output results in hardware specific actions. There must be code to
+ * support this in the kernel or TV output won't work.
+ */
+static DisplayModeRec ChipsPALMode = {
+ NULL, NULL, /* prev, next */
+ "PAL", /* identifier of this mode */
+ MODE_OK, /* mode status */
+ M_T_BUILTIN, /* mode type */
+ 15000, /* Clock frequency */
+ 776, /* HDisplay */
+ 800, /* HSyncStart */
+ 872, /* HSyncEnd */
+ 960, /* HTotal */
+ 0, /* HSkew */
+ 585, /* VDisplay */
+ 590, /* VSyncStart */
+ 595, /* VSyncEnd */
+ 625, /* VTotal */
+ 0, /* VScan */
+ V_INTERLACE, /* Flags */
+ -1, /* ClockIndex */
+ 15000, /* SynthClock */
+ 776, /* CRTC HDisplay */
+ 800, /* CRTC HBlankStart */
+ 800, /* CRTC HSyncStart */
+ 872, /* CRTC HSyncEnd */
+ 872, /* CRTC HBlankEnd */
+ 960, /* CRTC HTotal */
+ 0, /* CRTC HSkew */
+ 585, /* CRTC VDisplay */
+ 590, /* CRTC VBlankStart */
+ 590, /* CRTC VSyncStart */
+ 595, /* CRTC VSyncEnd */
+ 595, /* CRTC VBlankEnd */
+ 625, /* CRTC VTotal */
+ FALSE, /* CrtcHAdjusted */
+ FALSE, /* CrtcVAdjusted */
+ 0, /* PrivSize */
+ NULL, /* Private */
+ 0.0, /* HSync */
+ 0.0 /* VRefresh */
+};
+
+/*
+** So far, it looks like SECAM uses the same values as PAL
+*/
+static DisplayModeRec ChipsSECAMMode = {
+ NULL, /* prev */
+ &ChipsPALMode, /* next */
+ "SECAM", /* identifier of this mode */
+ MODE_OK, /* mode status */
+ M_T_BUILTIN, /* mode type */
+ 15000, /* Clock frequency */
+ 776, /* HDisplay */
+ 800, /* HSyncStart */
+ 872, /* HSyncEnd */
+ 960, /* HTotal */
+ 0, /* HSkew */
+ 585, /* VDisplay */
+ 590, /* VSyncStart */
+ 595, /* VSyncEnd */
+ 625, /* VTotal */
+ 0, /* VScan */
+ V_INTERLACE, /* Flags */
+ -1, /* ClockIndex */
+ 15000, /* SynthClock */
+ 776, /* CRTC HDisplay */
+ 800, /* CRTC HBlankStart */
+ 800, /* CRTC HSyncStart */
+ 872, /* CRTC HSyncEnd */
+ 872, /* CRTC HBlankEnd */
+ 960, /* CRTC HTotal */
+ 0, /* CRTC HSkew */
+ 585, /* CRTC VDisplay */
+ 590, /* CRTC VBlankStart */
+ 590, /* CRTC VSyncStart */
+ 595, /* CRTC VSyncEnd */
+ 595, /* CRTC VBlankEnd */
+ 625, /* CRTC VTotal */
+ FALSE, /* CrtcHAdjusted */
+ FALSE, /* CrtcVAdjusted */
+ 0, /* PrivSize */
+ NULL, /* Private */
+ 0.0, /* HSync */
+ 0.0 /* VRefresh */
+};
+
+
+static DisplayModeRec ChipsNTSCMode = {
+ NULL, /* prev */
+ &ChipsSECAMMode,/* next */
+ "NTSC", /* identifier of this mode */
+ MODE_OK, /* mode status */
+ M_T_BUILTIN, /* mode type */
+ 11970, /* Clock frequency */
+ 584, /* HDisplay */
+ 640, /* HSyncStart */
+ 696, /* HSyncEnd */
+ 760, /* HTotal */
+ 0, /* HSkew */
+ 450, /* VDisplay */
+ 479, /* VSyncStart */
+ 485, /* VSyncEnd */
+ 525, /* VTotal */
+ 0, /* VScan */
+ V_INTERLACE | V_NVSYNC | V_NHSYNC , /* Flags */
+ -1, /* ClockIndex */
+ 11970, /* SynthClock */
+ 584, /* CRTC HDisplay */
+ 640, /* CRTC HBlankStart */
+ 640, /* CRTC HSyncStart */
+ 696, /* CRTC HSyncEnd */
+ 696, /* CRTC HBlankEnd */
+ 760, /* CRTC HTotal */
+ 0, /* CRTC HSkew */
+ 450, /* CRTC VDisplay */
+ 479, /* CRTC VBlankStart */
+ 479, /* CRTC VSyncStart */
+ 485, /* CRTC VSyncEnd */
+ 485, /* CRTC VBlankEnd */
+ 525, /* CRTC VTotal */
+ FALSE, /* CrtcHAdjusted */
+ FALSE, /* CrtcVAdjusted */
+ 0, /* PrivSize */
+ NULL, /* Private */
+ 0.0, /* HSync */
+ 0.0 /* VRefresh */
+};
+#endif
+
+#define VERSION 4000
+#define CHIPS_NAME "CHIPS"
+#define CHIPS_DRIVER_NAME "chips"
+#define CHIPS_MAJOR_VERSION 1
+#define CHIPS_MINOR_VERSION 0
+#define CHIPS_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 CHIPS = {
+ VERSION,
+ CHIPS_DRIVER_NAME,
+ CHIPSIdentify,
+ CHIPSProbe,
+ CHIPSAvailableOptions,
+ NULL,
+ 0
+};
+
+static SymTabRec CHIPSChipsets[] = {
+ { CHIPS_CT65520, "ct65520" },
+ { CHIPS_CT65525, "ct65525" },
+ { CHIPS_CT65530, "ct65530" },
+ { CHIPS_CT65535, "ct65535" },
+ { CHIPS_CT65540, "ct65540" },
+ { CHIPS_CT65545, "ct65545" },
+ { CHIPS_CT65546, "ct65546" },
+ { CHIPS_CT65548, "ct65548" },
+ { CHIPS_CT65550, "ct65550" },
+ { CHIPS_CT65554, "ct65554" },
+ { CHIPS_CT65555, "ct65555" },
+ { CHIPS_CT68554, "ct68554" },
+ { CHIPS_CT69000, "ct69000" },
+ { CHIPS_CT69030, "ct69030" },
+ { CHIPS_CT64200, "ct64200" },
+ { CHIPS_CT64300, "ct64300" },
+ { -1, NULL }
+};
+
+/* Conversion PCI ID to chipset name */
+static PciChipsets CHIPSPCIchipsets[] = {
+ { CHIPS_CT65545, PCI_CHIP_65545, RES_SHARED_VGA },
+ { CHIPS_CT65548, PCI_CHIP_65548, RES_SHARED_VGA },
+ { CHIPS_CT65550, PCI_CHIP_65550, RES_SHARED_VGA },
+ { CHIPS_CT65554, PCI_CHIP_65554, RES_SHARED_VGA },
+ { CHIPS_CT65555, PCI_CHIP_65555, RES_SHARED_VGA },
+ { CHIPS_CT68554, PCI_CHIP_68554, RES_SHARED_VGA },
+ { CHIPS_CT69000, PCI_CHIP_69000, RES_SHARED_VGA },
+ { CHIPS_CT69030, PCI_CHIP_69030, RES_SHARED_VGA },
+ { -1, -1, RES_UNDEFINED}
+};
+
+static IsaChipsets CHIPSISAchipsets[] = {
+ { CHIPS_CT65520, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT65525, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT65530, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT65535, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT65540, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT65545, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT65546, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT65548, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT65550, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT65554, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT65555, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT68554, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT69000, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT69030, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT64200, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT64300, RES_EXCLUSIVE_VGA },
+ { -1, RES_UNDEFINED }
+};
+
+/* The options supported by the Chips and Technologies Driver */
+typedef enum {
+ OPTION_LINEAR,
+ OPTION_NOACCEL,
+ OPTION_HW_CLKS,
+ OPTION_SW_CURSOR,
+ OPTION_HW_CURSOR,
+ OPTION_STN,
+ OPTION_USE_MODELINE,
+ OPTION_LCD_STRETCH,
+ OPTION_LCD_CENTER,
+ OPTION_MMIO,
+ OPTION_FULL_MMIO,
+ OPTION_SUSPEND_HACK,
+ OPTION_RGB_BITS,
+ OPTION_SYNC_ON_GREEN,
+ OPTION_PANEL_SIZE,
+ OPTION_18_BIT_BUS,
+ OPTION_SHOWCACHE,
+ OPTION_SHADOW_FB,
+ OPTION_OVERLAY,
+ OPTION_COLOR_KEY,
+ OPTION_VIDEO_KEY,
+ OPTION_FP_CLOCK_8,
+ OPTION_FP_CLOCK_16,
+ OPTION_FP_CLOCK_24,
+ OPTION_FP_CLOCK_32,
+ OPTION_SET_MCLK,
+ OPTION_ROTATE,
+ OPTION_NO_TMED,
+ OPTION_CRT2_MEM,
+ OPTION_DUAL_REFRESH,
+ OPTION_CRT_CLK_INDX,
+ OPTION_FP_CLK_INDX,
+ OPTION_FP_MODE
+} CHIPSOpts;
+
+static const OptionInfoRec Chips655xxOptions[] = {
+ { OPTION_LINEAR, "Linear", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CLKS, "HWclocks", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_STN, "STN", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_USE_MODELINE, "UseModeline", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_LCD_STRETCH, "NoStretch", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_LCD_CENTER, "LcdCenter", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_MMIO, "MMIO", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SUSPEND_HACK, "SuspendHack", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_PANEL_SIZE, "FixPanelSize", OPTV_BOOLEAN, {0}, FALSE },
+#if 0
+ { OPTION_RGB_BITS, "RGBbits", OPTV_INTEGER, {0}, FALSE },
+#endif
+ { OPTION_18_BIT_BUS, "18BitBus", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE },
+ { OPTION_SET_MCLK, "SetMclk", OPTV_FREQ, {0}, FALSE },
+ { OPTION_FP_CLOCK_8, "FPClock8", OPTV_FREQ, {0}, FALSE },
+ { OPTION_FP_CLOCK_16, "FPClock16", OPTV_FREQ, {0}, FALSE },
+ { OPTION_FP_CLOCK_24, "FPClock24", OPTV_FREQ, {0}, FALSE },
+ { OPTION_FP_MODE, "FPMode", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+static const OptionInfoRec ChipsWingineOptions[] = {
+ { OPTION_LINEAR, "Linear", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CLKS, "HWclocks", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+#if 0
+ { OPTION_RGB_BITS, "RGBbits", OPTV_INTEGER, {0}, FALSE },
+#endif
+ { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+static const OptionInfoRec ChipsHiQVOptions[] = {
+ { OPTION_LINEAR, "Linear", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_STN, "STN", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_USE_MODELINE, "UseModeline", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_LCD_STRETCH, "NoStretch", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_LCD_CENTER, "LcdCenter", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_MMIO, "MMIO", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_FULL_MMIO, "FullMMIO", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SUSPEND_HACK, "SuspendHack", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_PANEL_SIZE, "FixPanelSize", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_RGB_BITS, "RGBbits", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_SYNC_ON_GREEN, "SyncOnGreen", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE },
+ { OPTION_OVERLAY, "Overlay", OPTV_ANYSTR, {0}, FALSE },
+ { OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_FP_CLOCK_8, "FPClock8", OPTV_FREQ, {0}, FALSE },
+ { OPTION_FP_CLOCK_16, "FPClock16", OPTV_FREQ, {0}, FALSE },
+ { OPTION_FP_CLOCK_24, "FPClock24", OPTV_FREQ, {0}, FALSE },
+ { OPTION_FP_CLOCK_32, "FPClock32", OPTV_FREQ, {0}, FALSE },
+ { OPTION_SET_MCLK, "SetMclk", OPTV_FREQ, {0}, FALSE },
+ { OPTION_NO_TMED, "NoTMED", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_CRT2_MEM, "Crt2Memory", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_DUAL_REFRESH, "DualRefresh", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_CRT_CLK_INDX, "CrtClkIndx", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_FP_CLK_INDX, "FPClkIndx", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_FP_MODE, "FPMode", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+/*
+ * List of symbols from other modules that this module references. This
+ * list is used to tell the loader that it is OK for symbols here to be
+ * unresolved providing that it hasn't been told that they haven't been
+ * told that they are essential via a call to xf86LoaderReqSymbols() or
+ * xf86LoaderReqSymLists(). The purpose is this is to avoid warnings about
+ * unresolved symbols that are not required.
+ */
+
+static const char *vgahwSymbols[] = {
+ "vgaHWAllocDefaultRegs",
+ "vgaHWFreeHWRec",
+ "vgaHWGetHWRec",
+ "vgaHWGetIOBase",
+ "vgaHWGetIndex",
+ "vgaHWHBlankKGA",
+ "vgaHWInit",
+ "vgaHWLock",
+ "vgaHWMapMem",
+ "vgaHWProtect",
+ "vgaHWRestore",
+ "vgaHWSave",
+ "vgaHWUnlock",
+ "vgaHWVBlankKGA",
+ "vgaHWddc1SetSpeed",
+ NULL
+};
+
+static const char *miscfbSymbols[] = {
+ "xf1bppScreenInit",
+ "xf4bppScreenInit",
+ "cfb8_16ScreenInit",
+ NULL
+};
+
+static const char *fbSymbols[] = {
+ "fbScreenInit",
+ "fbPictureInit",
+ NULL
+};
+
+static const char *xaaSymbols[] = {
+ "XAACreateInfoRec",
+ "XAADestroyInfoRec",
+ "XAAFillSolidRects" ,
+ "XAAInit",
+ "XAAInitDualFramebufferOverlay",
+ "XAAStippleScanlineFuncMSBFirst",
+ NULL
+};
+
+static const char *ramdacSymbols[] = {
+ "xf86CreateCursorInfoRec",
+ "xf86DestroyCursorInfoRec",
+ "xf86InitCursor",
+ NULL
+};
+
+static const char *ddcSymbols[] = {
+ "xf86DoEDID_DDC1",
+ "xf86DoEDID_DDC2",
+ "xf86PrintEDID",
+ "xf86SetDDCproperties",
+ NULL
+};
+
+static const char *i2cSymbols[] = {
+ "xf86CreateI2CBusRec",
+ "xf86I2CBusInit",
+ "xf86I2CFindBus",
+ "xf86I2CProbeAddress",
+ NULL
+};
+
+static const char *shadowSymbols[] = {
+ "ShadowFBInit",
+ NULL
+};
+
+static const char *vbeSymbols[] = {
+ "VBEInit",
+ "vbeDoEDID",
+ "vbeFree",
+ NULL
+};
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(chipsSetup);
+
+static XF86ModuleVersionInfo chipsVersRec =
+{
+ "chips",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ CHIPS_MAJOR_VERSION, CHIPS_MINOR_VERSION, CHIPS_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+/*
+ * This is the module init data.
+ * Its name has to be the driver name followed by ModuleData
+ */
+XF86ModuleData chipsModuleData = { &chipsVersRec, chipsSetup, NULL };
+
+static pointer
+chipsSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&CHIPS, module, 0);
+
+ /*
+ * Modules that this driver always requires can be loaded here
+ * by calling LoadSubModule().
+ */
+
+ /*
+ * Tell the loader about symbols from other modules that this module
+ * might refer to.
+ */
+ LoaderRefSymLists(vgahwSymbols, miscfbSymbols, fbSymbols, xaaSymbols,
+ ramdacSymbols, ddcSymbols, i2cSymbols,
+ shadowSymbols, vbeSymbols, NULL);
+
+ /*
+ * The return value must be non-NULL on success even though there
+ * is no TearDownProc.
+ */
+ return (pointer)1;
+ } else {
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+
+#endif /* XFree86LOADER */
+
+static Bool
+CHIPSGetRec(ScrnInfoPtr pScrn)
+{
+ /*
+ * Allocate a CHIPSRec, 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(CHIPSRec), 1);
+
+ if (pScrn->driverPrivate == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+CHIPSFreeRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+/* Mandatory */
+static void
+CHIPSIdentify(int flags)
+{
+ xf86PrintChipsets(CHIPS_NAME, "Driver for Chips and Technologies chipsets",
+ CHIPSChipsets);
+}
+
+static const OptionInfoRec *
+CHIPSAvailableOptions(int chipid, int busid)
+{
+ int chip = chipid & 0x0000ffff;
+
+ if (busid == BUS_ISA) {
+ if ((chip == CHIPS_CT64200) || (chip == CHIPS_CT64300))
+ return ChipsWingineOptions;
+ }
+ if (busid == BUS_PCI) {
+ if ((chip >= CHIPS_CT65550) && (chip <= CHIPS_CT69030))
+ return ChipsHiQVOptions;
+ }
+ return Chips655xxOptions;
+}
+
+/* Mandatory */
+static Bool
+CHIPSProbe(DriverPtr drv, int flags)
+{
+ Bool foundScreen = FALSE;
+ int numDevSections, numUsed;
+ GDevPtr *devSections;
+ int *usedChips;
+ int i;
+
+ /*
+ * Find the config file Device sections that match this
+ * driver, and return if there are none.
+ */
+ if ((numDevSections = xf86MatchDevice(CHIPS_DRIVER_NAME,
+ &devSections)) <= 0) {
+ return FALSE;
+ }
+ /* PCI BUS */
+ if (xf86GetPciVideoInfo() ) {
+ numUsed = xf86MatchPciInstances(CHIPS_NAME, PCI_VENDOR_CHIPSTECH,
+ CHIPSChipsets, CHIPSPCIchipsets,
+ devSections,numDevSections, drv,
+ &usedChips);
+ if (numUsed > 0) {
+ if (flags & PROBE_DETECT)
+ foundScreen = TRUE;
+ else for (i = 0; i < numUsed; i++) {
+ EntityInfoPtr pEnt;
+ /* Allocate a ScrnInfoRec */
+ ScrnInfoPtr pScrn = NULL;
+ if ((pScrn = xf86ConfigPciEntity(pScrn,0,usedChips[i],
+ CHIPSPCIchipsets,NULL,
+ NULL,NULL,NULL,NULL))){
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = CHIPS_DRIVER_NAME;
+ pScrn->name = CHIPS_NAME;
+ pScrn->Probe = CHIPSProbe;
+ pScrn->PreInit = CHIPSPreInit;
+ pScrn->ScreenInit = CHIPSScreenInit;
+ pScrn->SwitchMode = CHIPSSwitchMode;
+ pScrn->AdjustFrame = CHIPSAdjustFrame;
+ pScrn->EnterVT = CHIPSEnterVT;
+ pScrn->LeaveVT = CHIPSLeaveVT;
+ pScrn->FreeScreen = CHIPSFreeScreen;
+ pScrn->ValidMode = CHIPSValidMode;
+ foundScreen = TRUE;
+ }
+
+ /*
+ * For cards that can do dual head per entity, mark the entity
+ * as sharable.
+ */
+ pEnt = xf86GetEntityInfo(usedChips[i]);
+ if (pEnt->chipset == CHIPS_CT69030) {
+ CHIPSEntPtr cPtrEnt = NULL;
+ DevUnion *pPriv;
+
+ xf86SetEntitySharable(usedChips[i]);
+ /* Allocate an entity private if necessary */
+ if (CHIPSEntityIndex < 0)
+ CHIPSEntityIndex = xf86AllocateEntityPrivateIndex();
+ pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+ CHIPSEntityIndex);
+ if (!pPriv->ptr) {
+ pPriv->ptr = xnfcalloc(sizeof(CHIPSEntRec), 1);
+ cPtrEnt = pPriv->ptr;
+ cPtrEnt->lastInstance = -1;
+ } else {
+ cPtrEnt = pPriv->ptr;
+ }
+ /*
+ * Set the entity instance for this instance of the
+ * driver. For dual head per card, instance 0 is the
+ * "master" instance, driving the primary head, and
+ * instance 1 is the "slave".
+ */
+ cPtrEnt->lastInstance++;
+ xf86SetEntityInstanceForScreen(pScrn, pScrn->entityList[0],
+ cPtrEnt->lastInstance);
+ }
+
+ }
+ xfree(usedChips);
+ }
+ }
+
+ /* Isa Bus */
+ numUsed = xf86MatchIsaInstances(CHIPS_NAME,CHIPSChipsets,CHIPSISAchipsets,
+ drv,chipsFindIsaDevice,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],
+ CHIPSISAchipsets,NULL,
+ NULL,NULL,NULL,NULL))) {
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = CHIPS_DRIVER_NAME;
+ pScrn->name = CHIPS_NAME;
+ pScrn->Probe = CHIPSProbe;
+ pScrn->PreInit = CHIPSPreInit;
+ pScrn->ScreenInit = CHIPSScreenInit;
+ pScrn->SwitchMode = CHIPSSwitchMode;
+ pScrn->AdjustFrame = CHIPSAdjustFrame;
+ pScrn->EnterVT = CHIPSEnterVT;
+ pScrn->LeaveVT = CHIPSLeaveVT;
+ pScrn->FreeScreen = CHIPSFreeScreen;
+ pScrn->ValidMode = CHIPSValidMode;
+ foundScreen = TRUE;
+ }
+ xfree(usedChips);
+ }
+ }
+
+ xfree(devSections);
+ return foundScreen;
+}
+
+static int
+chipsFindIsaDevice(GDevPtr dev)
+{
+ int found = -1;
+ unsigned char tmp;
+
+ /*
+ * This function has the only direct register access in the C&T driver.
+ * All other register access through functions to allow for full MMIO.
+ */
+ outb(0x3D6, 0x00);
+ tmp = inb(0x3D7);
+
+ switch (tmp & 0xF0) {
+ case 0x70: /* CT65520 */
+ found = CHIPS_CT65520; break;
+ case 0x80: /* CT65525 or CT65530 */
+ found = CHIPS_CT65530; break;
+ case 0xA0: /* CT64200 */
+ found = CHIPS_CT64200; break;
+ case 0xB0: /* CT64300 */
+ found = CHIPS_CT64300; break;
+ case 0xC0: /* CT65535 */
+ found = CHIPS_CT65535; break;
+ default:
+ switch (tmp & 0xF8) {
+ case 0xD0: /* CT65540 */
+ found = CHIPS_CT65540; break;
+ case 0xD8: /* CT65545 or CT65546 or CT65548 */
+ switch (tmp & 7) {
+ case 3:
+ found = CHIPS_CT65546; break;
+ case 4:
+ found = CHIPS_CT65548; break;
+ default:
+ found = CHIPS_CT65545; break;
+
+ }
+ break;
+ default:
+ if (tmp == 0x2C) {
+ outb(0x3D6, 0x01);
+ tmp = inb(0x3D7);
+ if (tmp != 0x10) break;
+ outb(0x3D6, 0x02);
+ tmp = inb(0x3D7);
+ switch (tmp) {
+ case 0xE0: /* CT65550 */
+ found = CHIPS_CT65550; break;
+ case 0xE4: /* CT65554 */
+ found = CHIPS_CT65554; break;
+ case 0xE5: /* CT65555 */
+ found = CHIPS_CT65555; break;
+ case 0xF4: /* CT68554 */
+ found = CHIPS_CT68554; break;
+ case 0xC0: /* CT69000 */
+ found = CHIPS_CT69000; break;
+ case 0x30: /* CT69030 */
+ outb(0x3D6, 0x03);
+ tmp = inb(0x3D7);
+ if (tmp == 0xC)
+ found = CHIPS_CT69030;
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ }
+ break;
+ }
+ /* We only want ISA/VL Bus - so check for PCI Bus */
+ if(found > CHIPS_CT65548) {
+ outb(0x3D6, 0x08);
+ tmp = inb(0x3D7);
+ if(tmp & 0x01) found = -1;
+ } else if(found > CHIPS_CT65535) {
+ outb(0x3D6, 0x01);
+ tmp = inb(0x3D7);
+ if ((tmp & 0x07) == 0x06) found = -1;
+ }
+ return found;
+}
+
+/* Mandatory */
+Bool
+CHIPSPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ pciVideoPtr pciPtr;
+ ClockRangePtr clockRanges;
+ int i;
+ CHIPSPtr cPtr;
+ Bool res = FALSE;
+ CHIPSEntPtr cPtrEnt = NULL;
+
+ if (flags & PROBE_DETECT) return FALSE;
+
+ /* The vgahw module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "vgahw"))
+ return FALSE;
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ /* Allocate the ChipsRec driverPrivate */
+ if (!CHIPSGetRec(pScrn)) {
+ return FALSE;
+ }
+ cPtr = CHIPSPTR(pScrn);
+
+ /* XXX Check the number of entities, and fail if it isn't one. */
+ if (pScrn->numEntities != 1)
+ return FALSE;
+
+ /* Since the capabilities are determined by the chipset the very
+ * first thing to do is, figure out the chipset and its capabilities
+ */
+
+ /* This is the general case */
+ for (i = 0; i<pScrn->numEntities; i++) {
+ cPtr->pEnt = xf86GetEntityInfo(pScrn->entityList[i]);
+ if (cPtr->pEnt->resources) return FALSE;
+ cPtr->Chipset = cPtr->pEnt->chipset;
+ pScrn->chipset = (char *)xf86TokenToString(CHIPSChipsets,
+ cPtr->pEnt->chipset);
+ if ((cPtr->Chipset == CHIPS_CT64200) ||
+ (cPtr->Chipset == CHIPS_CT64300)) cPtr->Flags |= ChipsWingine;
+ if ((cPtr->Chipset >= CHIPS_CT65550) &&
+ (cPtr->Chipset <= CHIPS_CT69030)) cPtr->Flags |= ChipsHiQV;
+
+ /* This driver can handle ISA and PCI buses */
+ if (cPtr->pEnt->location.type == BUS_PCI) {
+ pciPtr = xf86GetPciInfoForEntity(cPtr->pEnt->index);
+ cPtr->PciInfo = pciPtr;
+ cPtr->PciTag = pciTag(cPtr->PciInfo->bus,
+ cPtr->PciInfo->device,
+ cPtr->PciInfo->func);
+ }
+ }
+ /* INT10 */
+#if 0
+ if (xf86LoadSubModule(pScrn, "int10")) {
+ xf86Int10InfoPtr pInt;
+ xf86LoaderReqSymLists(int10Symbols, NULL);
+#if 1
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO,"initializing int10\n");
+ pInt = xf86InitInt10(cPtr->pEnt->index);
+ xf86FreeInt10(pInt);
+#endif
+ }
+#endif
+
+ if (xf86LoadSubModule(pScrn, "vbe")) {
+ xf86LoaderReqSymLists(vbeSymbols, NULL);
+ cPtr->pVbe = VBEInit(NULL,cPtr->pEnt->index);
+ }
+
+ /* Now that we've identified the chipset, setup the capabilities flags */
+ switch (cPtr->Chipset) {
+ case CHIPS_CT69030:
+ cPtr->Flags |= ChipsDualChannelSupport;
+ case CHIPS_CT69000:
+ cPtr->Flags |= ChipsFullMMIOSupport;
+ /* Fall through */
+ case CHIPS_CT65555:
+ cPtr->Flags |= ChipsImageReadSupport; /* Does the 69000 support it? */
+ /* Fall through */
+ case CHIPS_CT68554:
+ cPtr->Flags |= ChipsTMEDSupport;
+ /* Fall through */
+ case CHIPS_CT65554:
+ case CHIPS_CT65550:
+ cPtr->Flags |= ChipsGammaSupport;
+ cPtr->Flags |= ChipsVideoSupport;
+ /* Fall through */
+ case CHIPS_CT65548:
+ case CHIPS_CT65546:
+ case CHIPS_CT65545:
+ cPtr->Flags |= ChipsMMIOSupport;
+ /* Fall through */
+ case CHIPS_CT64300:
+ cPtr->Flags |= ChipsAccelSupport;
+ /* Fall through */
+ case CHIPS_CT65540:
+ cPtr->Flags |= ChipsHDepthSupport;
+ cPtr->Flags |= ChipsDPMSSupport;
+ /* Fall through */
+ case CHIPS_CT65535:
+ case CHIPS_CT65530:
+ case CHIPS_CT65525:
+ cPtr->Flags |= ChipsLinearSupport;
+ /* Fall through */
+ case CHIPS_CT64200:
+ case CHIPS_CT65520:
+ break;
+ }
+
+ /* Check for shared entities */
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ if (!(cPtr->Flags & ChipsDualChannelSupport))
+ return FALSE;
+
+ /* Make sure entity is PCI for now, though this might not be needed. */
+ if (cPtr->pEnt->location.type != BUS_PCI)
+ return FALSE;
+
+ /* Allocate an entity private if necessary */
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0],
+ CHIPSEntityIndex)->ptr;
+ cPtr->entityPrivate = cPtrEnt;
+ }
+#if 0
+ /* Set cPtr->device to the relevant Device section */
+ cPtr->device = xf86GetDevFromEntity(pScrn->entityList[0],
+ pScrn->entityInstanceList[0]);
+#endif
+ }
+
+ /* Set the driver to use the PIO register functions by default */
+ CHIPSSetStdExtFuncs(cPtr);
+
+ /* Call the device specific PreInit */
+ if (IS_HiQV(cPtr))
+ res = chipsPreInitHiQV(pScrn, flags);
+ else if (IS_Wingine(cPtr))
+ res = chipsPreInitWingine(pScrn, flags);
+ else
+ res = chipsPreInit655xx(pScrn, flags);
+
+ if (cPtr->UseFullMMIO)
+ chipsUnmapMem(pScrn);
+
+ if (!res) {
+ vbeFree(cPtr->pVbe);
+ cPtr->pVbe = NULL;
+ return FALSE;
+ }
+
+/*********/
+ /*
+ * 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;
+ clockRanges->ClockMulFactor = cPtr->ClockMulFactor;
+ clockRanges->minClock = cPtr->MinClock;
+ clockRanges->maxClock = cPtr->MaxClock;
+ clockRanges->clockIndex = -1; /* programmable */
+ if (cPtr->PanelType & ChipsLCD) {
+ clockRanges->interlaceAllowed = FALSE;
+ clockRanges->doubleScanAllowed = FALSE;
+ } else {
+ clockRanges->interlaceAllowed = TRUE;
+ clockRanges->doubleScanAllowed = TRUE;
+ }
+ /*
+ * Reduce the amount of video ram for the modes, so that they
+ * don't overlap with the DSTN framebuffer
+ */
+ pScrn->videoRam -= (cPtr->FrameBufferSize + 1023) / 1024;
+
+ cPtr->Rounding = 8 * (pScrn->bitsPerPixel <= 8 ? 8
+ : pScrn->bitsPerPixel);
+
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ NULL, 256, 2048, cPtr->Rounding,
+ 128, 2048, pScrn->display->virtualX,
+ pScrn->display->virtualY, cPtr->FbMapSize,
+ LOOKUP_BEST_REFRESH);
+
+ if (i == -1) {
+ vbeFree(cPtr->pVbe);
+ cPtr->pVbe = NULL;
+ CHIPSFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /*
+ * Put the DSTN framebuffer back into the video ram
+ */
+ pScrn->videoRam += (cPtr->FrameBufferSize + 1023) / 1024;
+
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrn);
+
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ vbeFree(cPtr->pVbe);
+ cPtr->pVbe = NULL;
+ CHIPSFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /*
+ * Set the CRTC parameters for all of the modes based on the type
+ * of mode, and the chipset's interlace requirements.
+ *
+ * Calling this is required if the mode->Crtc* values are used by the
+ * driver and if the driver doesn't provide code to set them. They
+ * are not pre-initialised at all.
+ */
+ 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);
+
+ /* If monitor resolution is set on the command line, use it */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /* Load bpp-specific modules */
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ if (xf86LoadSubModule(pScrn, "xf1bpp") == NULL) {
+ vbeFree(cPtr->pVbe);
+ cPtr->pVbe = NULL;
+ CHIPSFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymbols("xf1bppScreenInit", NULL);
+ break;
+ case 4:
+ if (xf86LoadSubModule(pScrn, "xf4bpp") == NULL) {
+ vbeFree(cPtr->pVbe);
+ cPtr->pVbe = NULL;
+ CHIPSFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymbols("xf4bppScreenInit", NULL);
+ break;
+ case 16:
+ if (cPtr->Flags & ChipsOverlay8plus16) {
+ if (xf86LoadSubModule(pScrn, "xf8_16bpp") == NULL) {
+ vbeFree(cPtr->pVbe);
+ cPtr->pVbe = NULL;
+ CHIPSFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymbols("cfb8_16bppScreenInit", NULL);
+ break;
+ }
+ default:
+ if (xf86LoadSubModule(pScrn, "fb") == NULL) {
+ vbeFree(cPtr->pVbe);
+ cPtr->pVbe = NULL;
+ CHIPSFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(fbSymbols, NULL);
+ break;
+ }
+
+ if (cPtr->Flags & ChipsAccelSupport) {
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ vbeFree(cPtr->pVbe);
+ cPtr->pVbe = NULL;
+ CHIPSFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+ }
+
+ if (cPtr->Flags & ChipsShadowFB) {
+ if (!xf86LoadSubModule(pScrn, "shadowfb")) {
+ vbeFree(cPtr->pVbe);
+ cPtr->pVbe = NULL;
+ CHIPSFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(shadowSymbols, NULL);
+ }
+
+ if (cPtr->Accel.UseHWCursor) {
+ if (!xf86LoadSubModule(pScrn, "ramdac")) {
+ vbeFree(cPtr->pVbe);
+ cPtr->pVbe = NULL;
+ CHIPSFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+ }
+
+ if (cPtr->Flags & ChipsLinearSupport)
+ xf86SetOperatingState(resVgaMem, cPtr->pEnt->index, ResDisableOpr);
+
+ if (cPtr->MMIOBaseVGA)
+ xf86SetOperatingState(resVgaIo, cPtr->pEnt->index, ResDisableOpr);
+ vbeFree(cPtr->pVbe);
+ cPtr->pVbe = NULL;
+ return TRUE;
+}
+
+static Bool
+chipsPreInitHiQV(ScrnInfoPtr pScrn, int flags)
+{
+ int bytesPerPixel;
+ unsigned char tmp;
+ MessageType from;
+ int i;
+ unsigned int Probed[3], FPclkI, CRTclkI;
+ double real;
+ int val, indx;
+ const char *s;
+ pointer pVbeModule = NULL;
+
+ vgaHWPtr hwp;
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSEntPtr cPtrEnt = NULL;
+ CHIPSPanelSizePtr Size = &cPtr->PanelSize;
+ CHIPSMemClockPtr MemClk = &cPtr->MemClock;
+ CHIPSClockPtr SaveClk = &(cPtr->SavedReg.Clock);
+ resRange linearRes[] = { {ResExcMemBlock|ResBios|ResBus,0,0},_END };
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /* All HiQV chips support 16/24/32 bpp */
+ 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:
+ case 15:
+ case 16:
+ case 24:
+ case 32:
+ /* OK */
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ }
+ xf86PrintDepthBpp(pScrn);
+
+ /* Get the depth24 pixmap format */
+ if (pScrn->depth == 24 && pix24bpp == 0)
+ pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+
+ /*
+ * Allocate a vgaHWRec, this must happen after xf86SetDepthBpp for 1bpp
+ */
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+
+ hwp = VGAHWPTR(pScrn);
+ vgaHWGetIOBase(hwp);
+ cPtr->PIOBase = hwp->PIOOffset;
+
+ /*
+ * Must allow ensure that storage for the 2nd set of vga registers is
+ * allocated for dual channel cards
+ */
+ if ((cPtr->Flags & ChipsDualChannelSupport) &&
+ (! xf86IsEntityShared(pScrn->entityList[0])))
+ vgaHWAllocDefaultRegs(&(cPtr->VgaSavedReg2));
+
+ /*
+ * 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;
+
+ /* The gamma fields must be initialised when using the new cmap code */
+ if (pScrn->depth > 1) {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros))
+ return FALSE;
+ }
+
+ bytesPerPixel = max(1, pScrn->bitsPerPixel >> 3);
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+ /* Process the options */
+ if (!(cPtr->Options = xalloc(sizeof(ChipsHiQVOptions))))
+ return FALSE;
+ memcpy(cPtr->Options, ChipsHiQVOptions, sizeof(ChipsHiQVOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, cPtr->Options);
+
+ /* Set the bits per RGB */
+ if (pScrn->depth > 1) {
+ /* Default to 6, is this right for HiQV?? */
+ pScrn->rgbBits = 8;
+ if (xf86GetOptValInteger(cPtr->Options, OPTION_RGB_BITS, &val)) {
+ if (val == 6 || val == 8) {
+ pScrn->rgbBits = val;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to "
+ "%d\n", pScrn->rgbBits);
+ } else
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Invalid number of "
+ "rgb bits %d\n", val);
+ }
+ }
+ if ((cPtr->Flags & ChipsAccelSupport) &&
+ (xf86ReturnOptValBool(cPtr->Options, OPTION_NOACCEL, FALSE))) {
+ cPtr->Flags &= ~ChipsAccelSupport;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
+ }
+
+ from = X_DEFAULT;
+ if (pScrn->bitsPerPixel < 8) {
+ /* Default to SW cursor for 1/4 bpp */
+ cPtr->Accel.UseHWCursor = FALSE;
+ } else {
+ cPtr->Accel.UseHWCursor = TRUE;
+ }
+ if (xf86GetOptValBool(cPtr->Options, OPTION_HW_CURSOR,
+ &cPtr->Accel.UseHWCursor))
+ from = X_CONFIG;
+ if (xf86GetOptValBool(cPtr->Options, OPTION_SW_CURSOR,
+ &cPtr->Accel.UseHWCursor)) {
+ from = X_CONFIG;
+ cPtr->Accel.UseHWCursor = !cPtr->Accel.UseHWCursor;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ (cPtr->Accel.UseHWCursor) ? "HW" : "SW");
+
+ /* Default to nonlinear for < 8bpp and linear for >= 8bpp. */
+ if (pScrn->bitsPerPixel < 8) {
+ if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, FALSE)) {
+ cPtr->Flags &= ~ChipsLinearSupport;
+ from = X_CONFIG;
+ }
+ } else if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, TRUE)) {
+ cPtr->Flags &= ~ChipsLinearSupport;
+ from = X_CONFIG;
+ }
+
+ /* linear base */
+ if (cPtr->Flags & ChipsLinearSupport) {
+ if (cPtr->pEnt->location.type == BUS_PCI) {
+ /* Tack on 0x800000 to access the big-endian aperture? */
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ cPtr->FbAddress = (cPtr->PciInfo->memBase[0] & 0xff800000) + 0x800000L;
+#else
+ cPtr->FbAddress = cPtr->PciInfo->memBase[0] & 0xff800000;
+#endif
+ from = X_PROBED;
+ if (xf86RegisterResources(cPtr->pEnt->index,NULL,ResNone))
+ cPtr->Flags &= ~ChipsLinearSupport;
+ } else {
+ if (cPtr->pEnt->device->MemBase) {
+ cPtr->FbAddress = cPtr->pEnt->device->MemBase;
+ from = X_CONFIG;
+ } else {
+ cPtr->FbAddress = ((unsigned int)
+ (cPtr->readXR(cPtr, 0x06))) << 24;
+ cPtr->FbAddress |= ((unsigned int)
+ (0x80 & (cPtr->readXR(cPtr, 0x05)))) << 16;
+ from = X_PROBED;
+ }
+ linearRes[0].rBegin = cPtr->FbAddress;
+ linearRes[0].rEnd = cPtr->FbAddress + 0x800000;
+ if (xf86RegisterResources(cPtr->pEnt->index,linearRes,ResNone)) {
+ cPtr->Flags &= ~ChipsLinearSupport;
+ from = X_PROBED;
+ }
+ }
+ }
+ if (cPtr->Flags & ChipsLinearSupport) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Enabling linear addressing\n");
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "base address is set at 0x%X.\n", cPtr->FbAddress);
+ cPtr->IOAddress = cPtr->FbAddress + 0x400000L;
+ } else
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Disabling linear addressing\n");
+
+ if ((s = xf86GetOptValString(cPtr->Options, OPTION_ROTATE))
+ || xf86ReturnOptValBool(cPtr->Options, OPTION_SHADOW_FB, FALSE)) {
+ if (!(cPtr->Flags & ChipsLinearSupport)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Option \"ShadowFB\" ignored. Not supported without linear addressing\n");
+ } else if (pScrn->depth < 8) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Option \"ShadowFB\" ignored. Not supported at this depth.\n");
+ } else {
+ cPtr->Rotate = 0;
+ if (s) {
+ if(!xf86NameCmp(s, "CW")) {
+ /* accel is disabled below for shadowFB */
+ cPtr->Flags |= ChipsShadowFB;
+ cPtr->Rotate = 1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Rotating screen clockwise\n");
+ } else if(!xf86NameCmp(s, "CCW")) {
+ cPtr->Flags |= ChipsShadowFB;
+ cPtr->Rotate = -1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen"
+ "counter clockwise\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");
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using \"Shadow Framebuffer\"\n");
+ cPtr->Flags |= ChipsShadowFB;
+ }
+ }
+ }
+
+ if ((s = xf86GetOptValString(cPtr->Options, OPTION_OVERLAY))) {
+ if (!*s || !xf86NameCmp(s, "8,16") || !xf86NameCmp(s, "16,8")) {
+ if (pScrn->bitsPerPixel == 16) {
+ if (cPtr->Flags & ChipsLinearSupport) {
+ cPtr->Flags |= ChipsOverlay8plus16;
+ if(!xf86GetOptValInteger(
+ cPtr->Options, OPTION_COLOR_KEY, &(pScrn->colorKey)))
+ pScrn->colorKey = TRANSPARENCY_KEY;
+ pScrn->overlayFlags = OVERLAY_8_16_DUALFB;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "PseudoColor overlay enabled.\n");
+ if (!xf86IsOptionSet(cPtr->Options, OPTION_LCD_STRETCH))
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ " - Forcing option \"NoStretch\".\n");
+ if (!xf86IsOptionSet(cPtr->Options, OPTION_LCD_CENTER))
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ " - Forcing option \"LcdCenter\".\n");
+ if (cPtr->Flags & ChipsShadowFB) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ " - Disabling \"Shadow Framebuffer\".\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ " Not support with option \"8Plus16\".\n");
+ cPtr->Flags &= ~ChipsShadowFB;
+ cPtr->Rotate = 0;
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Option \"Overlay\" ignored. Not supported without linear addressing\n");
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Option \"Overlay\" is not supported in this configuration\n");
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "\"%s\" is not a valid value for Option \"Overlay\"\n", s);
+ }
+ }
+
+ if (!(cPtr->Flags & ChipsOverlay8plus16)) {
+ if(xf86GetOptValInteger(cPtr->Options, OPTION_VIDEO_KEY,
+ &(cPtr->videoKey))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n",
+ cPtr->videoKey);
+ } else {
+ cPtr->videoKey = (1 << pScrn->offset.red) |
+ (1 << pScrn->offset.green) |
+ (((pScrn->mask.blue >> pScrn->offset.blue) - 1)
+ << pScrn->offset.blue);
+ }
+ }
+
+ if (cPtr->Flags & ChipsShadowFB) {
+ if (cPtr->Flags & ChipsAccelSupport) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "HW acceleration is not supported with shadow fb\n");
+ cPtr->Flags &= ~ChipsAccelSupport;
+ }
+ if (cPtr->Rotate && cPtr->Accel.UseHWCursor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "HW cursor is not supported with rotate\n");
+ cPtr->Accel.UseHWCursor = FALSE;
+ }
+ }
+
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_MMIO, TRUE)) {
+ cPtr->UseMMIO = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using MMIO\n");
+
+ /* Are we using MMIO mapping of VGA registers */
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_FULL_MMIO, FALSE)) {
+ if ((cPtr->Flags & ChipsLinearSupport)
+ && (cPtr->Flags & ChipsFullMMIOSupport)
+ && (cPtr->pEnt->location.type == BUS_PCI)) {
+
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Enabling Full MMIO\n");
+ cPtr->UseFullMMIO = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using Full MMIO\n");
+
+ /*
+ * We need to map the framebuffer to read/write regs.
+ * but can't do that without the FbMapSize. So need to
+ * fake value for PreInit. This isn't a problem as
+ * framebuffer isn't actually used in PreInit
+ */
+ cPtr->FbMapSize = 1024 * 1024;
+
+ /* Map the linear framebuffer */
+ if (!chipsMapMem(pScrn))
+ return FALSE;
+
+ /* Setup the MMIO register functions */
+ if (cPtr->MMIOBaseVGA) {
+ CHIPSSetMmioExtFuncs(cPtr);
+ CHIPSHWSetMmioFuncs(pScrn, cPtr->MMIOBaseVGA, 0x0);
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "FULL_MMIO option ignored\n");
+ }
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,"Disabling MMIO: "
+ "no acceleration, no hw_cursor\n");
+ cPtr->UseMMIO = FALSE;
+ cPtr->Accel.UseHWCursor = FALSE;
+ cPtr->Flags &= ~ChipsAccelSupport;
+ }
+
+
+ if (cPtr->Flags & ChipsDualChannelSupport) {
+
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0],
+ CHIPSEntityIndex)->ptr;
+#if 1
+ /*
+ * XXX This assumes that the lower number screen is always the
+ * "master" head, and that the "master" is the first CRTC. This
+ * can result in unexpected behaviour when the config file marks
+ * the primary CRTC as the second screen.
+ */
+ if (xf86IsPrimInitDone(pScrn->entityList[0]))
+#else
+ /*
+ * This is an alternative version that determines which is the
+ * secondary CRTC from the screen field in cPtr->pEnt->device.
+ * It doesn't currently work because there are things that assume
+ * the primary CRTC is initialised first.
+ */
+ if (cPtr->pEnt->device->screen == 1)
+
+#endif
+ {
+ /* This is the second crtc */
+ cPtr->SecondCrtc = TRUE;
+ cPtr->UseDualChannel = TRUE;
+ } else
+ cPtr->SecondCrtc = FALSE;
+
+ } else {
+ if (xf86ReturnOptValBool(cPtr->Options,
+ OPTION_DUAL_REFRESH, FALSE)) {
+ cPtr->Flags |= ChipsDualRefresh;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Dual Refresh mode enabled\n");
+ cPtr->UseDualChannel = TRUE;
+ }
+ }
+
+ /* Store IOSS/MSS so that we can restore them */
+ cPtr->storeIOSS = cPtr->readIOSS(cPtr);
+ cPtr->storeMSS = cPtr->readMSS(cPtr);
+ DUALOPEN;
+ }
+
+ /* memory size */
+ if (cPtr->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = cPtr->pEnt->device->videoRam;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+ } else {
+ /* not given, probe it */
+ switch (cPtr->Chipset) {
+ case CHIPS_CT69030:
+ /* The ct69030 has 4Mb of SGRAM integrated */
+ pScrn->videoRam = 4096;
+ break;
+ case CHIPS_CT69000:
+ /* The ct69000 has 2Mb of SGRAM integrated */
+ pScrn->videoRam = 2048;
+ break;
+ case CHIPS_CT65550:
+ /* XR43: DRAM interface */
+ /* bit 2-1: memory size */
+ /* 0: 1024 kB */
+ /* 1: 2048 kB */
+ /* 2: reserved */
+ /* 3: reserved */
+ switch (((cPtr->readXR(cPtr, 0x43)) & 0x06) >> 1) {
+ case 0:
+ pScrn->videoRam = 1024;
+ break;
+ case 1:
+ case 2:
+ case 3:
+ pScrn->videoRam = 2048;
+ break;
+ }
+ break;
+ default:
+ /* XRE0: Software reg */
+ /* bit 3-0: memory size */
+ /* 0: 512k */
+ /* 1: 1024k */
+ /* 2: 1536k(1.5M)*/
+ /* 3: 2048k */
+ /* 7: 4096k */
+ tmp = (cPtr->readXR(cPtr, 0xE0)) & 0xF;
+ switch (tmp) {
+ case 0:
+ pScrn->videoRam = 512;
+ break;
+ case 1:
+ pScrn->videoRam = 1024;
+ break;
+ case 2:
+ pScrn->videoRam = 1536;
+ break;
+ case 3:
+ pScrn->videoRam = 2048;
+ break;
+ case 7:
+ pScrn->videoRam = 4096;
+ break;
+ default:
+ pScrn->videoRam = 1024;
+ break;
+ }
+ break;
+ }
+ }
+
+ if ((cPtr->Flags & ChipsDualChannelSupport) &&
+ (xf86IsEntityShared(pScrn->entityList[0]))) {
+ /*
+ * This takes gives either half or the amount of memory specified
+ * with the Crt2Memory option
+ */
+ if(cPtr->SecondCrtc == FALSE) {
+ int crt2mem = -1, adjust;
+
+ xf86GetOptValInteger(cPtr->Options, OPTION_CRT2_MEM, &crt2mem);
+ if (crt2mem > 0) {
+ adjust = crt2mem;
+ from = X_CONFIG;
+ } else {
+ adjust = pScrn->videoRam / 2;
+ from = X_DEFAULT;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "CRT2 will use %dK of VideoRam\n",
+ adjust);
+
+ cPtrEnt->mastervideoRam = pScrn->videoRam - adjust;
+ pScrn->videoRam = cPtrEnt->mastervideoRam;
+ cPtrEnt->slavevideoRam = adjust;
+ cPtrEnt->masterFbAddress = cPtr->FbAddress;
+ cPtr->FbMapSize =
+ cPtrEnt->masterFbMapSize = pScrn->videoRam * 1024;
+ cPtrEnt->slaveFbMapSize = cPtrEnt->slavevideoRam * 1024;
+ } else {
+ cPtrEnt->slaveFbAddress = cPtr->FbAddress +
+ cPtrEnt->masterFbAddress;
+ cPtr->FbMapSize = cPtrEnt->slaveFbMapSize;
+ pScrn->videoRam = cPtrEnt->slavevideoRam;
+ }
+ cPtrEnt->refCount++;
+ } else {
+ /* Normal Handling of video ram etc */
+ cPtr->FbMapSize = pScrn->videoRam * 1024;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+
+ /* Store register values that might be messed up by a suspend resume */
+ /* Do this early as some of the other code in PreInit relies on it */
+ cPtr->SuspendHack.vgaIOBaseFlag = ((hwp->readMiscOut(hwp)) & 0x01);
+ cPtr->IOBase = (unsigned int)(cPtr->SuspendHack.vgaIOBaseFlag ?
+ 0x3D0 : 0x3B0);
+
+ /*
+ * Do DDC here: if VESA BIOS detects an external monitor it
+ * might switch. SetPanelType() will detect this.
+ */
+ if ((pVbeModule = xf86LoadSubModule(pScrn, "ddc"))) {
+ Bool ddc_done = FALSE;
+ xf86MonPtr pMon;
+
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+
+ if (cPtr->pVbe) {
+ if ((pMon
+ = xf86PrintEDID(vbeDoEDID(cPtr->pVbe, pVbeModule))) != NULL) {
+ ddc_done = TRUE;
+ xf86SetDDCproperties(pScrn,pMon);
+ }
+ }
+
+ if (!ddc_done)
+ if (xf86LoadSubModule(pScrn, "i2c")) {
+ xf86LoaderReqSymLists(i2cSymbols,NULL);
+
+ if (chips_i2cInit(pScrn)) {
+ if ((pMon = xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex,
+ cPtr->I2C))) != NULL)
+ ddc_done = TRUE;
+ xf86SetDDCproperties(pScrn,pMon);
+ }
+ }
+ if (!ddc_done)
+ chips_ddc1(pScrn);
+ }
+
+ /*test STN / TFT */
+ tmp = cPtr->readFR(cPtr, 0x10);
+
+ /* XR51 or FR10: DISPLAY TYPE REGISTER */
+ /* XR51[1-0] or FR10[1:0] for ct65550 : PanelType, */
+ /* 0 = Single Panel Single Drive, 3 = Dual Panel Dual Drive */
+ switch (tmp & 0x3) {
+ case 0:
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_STN, FALSE)) {
+ cPtr->PanelType |= ChipsSS;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "SS-STN probed\n");
+ } else {
+ cPtr->PanelType |= ChipsTFT;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "TFT probed\n");
+ }
+ break;
+ case 2:
+ cPtr->PanelType |= ChipsDS;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DS-STN probed\n");
+ case 3:
+ cPtr->PanelType |= ChipsDD;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DD-STN probed\n");
+ break;
+ default:
+ break;
+ }
+
+ chipsSetPanelType(cPtr);
+ from = X_PROBED;
+ {
+ Bool fp_mode;
+ if (xf86GetOptValBool(cPtr->Options, OPTION_FP_MODE, &fp_mode)) {
+ if (fp_mode) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing FP Mode on\n");
+ cPtr->PanelType |= ChipsLCD;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing FP Mode off\n");
+ cPtr->PanelType = ~ChipsLCD;
+ }
+ from = X_CONFIG;
+ }
+ }
+ if ((cPtr->PanelType & ChipsLCD) && (cPtr->PanelType & ChipsCRT))
+ xf86DrvMsg(pScrn->scrnIndex, from, "LCD/CRT\n");
+ else if (cPtr->PanelType & ChipsLCD)
+ xf86DrvMsg(pScrn->scrnIndex, from, "LCD\n");
+ else if (cPtr->PanelType & ChipsCRT) {
+ xf86DrvMsg(pScrn->scrnIndex, from, "CRT\n");
+ /* monitor info */
+#if 1
+ cPtr->Monitor = chipsSetMonitor(pScrn);
+#endif
+ }
+ /* screen size */
+ /*
+ * In LCD mode / dual mode we want to derive the timing values from
+ * the ones preset by bios
+ */
+ if (cPtr->PanelType & ChipsLCD) {
+
+ /* for 65550 we only need H/VDisplay values for screen size */
+ unsigned char fr25, tmp1;
+#ifdef DEBUG
+ unsigned char fr26;
+ char tmp2;
+#endif
+ fr25 = cPtr->readFR(cPtr, 0x25);
+ tmp = cPtr->readFR(cPtr, 0x20);
+ Size->HDisplay = ((tmp + ((fr25 & 0x0F) << 8)) + 1) << 3;
+ tmp = cPtr->readFR(cPtr, 0x30);
+ tmp1 = cPtr->readFR(cPtr, 0x35);
+ Size->VDisplay = ((tmp1 & 0x0F) << 8) + tmp + 1;
+#ifdef DEBUG
+ tmp = cPtr->readFR(cPtr, 0x21);
+ Size->HRetraceStart = ((tmp + ((fr25 & 0xF0) << 4)) + 1) << 3;
+ tmp1 = cPtr->readFR(cPtr, 0x22);
+ tmp2 = (tmp1 & 0x1F) - (tmp & 0x3F);
+ Size->HRetraceEnd = ((((tmp2 < 0) ? (tmp2 + 0x40) : tmp2) << 3)
+ + Size->HRetraceStart);
+ tmp = cPtr->readFR(cPtr, 0x23);
+ fr26 = cPtr->readFR(cPtr, 0x26);
+ Size->HTotal = ((tmp + ((fr26 & 0x0F) << 8)) + 5) << 3;
+ xf86ErrorF("x=%i, y=%i; xSync=%i, xSyncEnd=%i, xTotal=%i\n",
+ Size->HDisplay, Size->VDisplay,
+ Size->HRetraceStart,Size->HRetraceEnd,
+ Size->HTotal);
+#endif
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Display Size: x=%i; y=%i\n",
+ Size->HDisplay, Size->VDisplay);
+ /* Warn the user if the panel size has been overridden by
+ * the modeline values
+ */
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_PANEL_SIZE, FALSE)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Display size overridden by modelines.\n");
+ }
+ }
+
+ /* Frame Buffer */ /* for LCDs */
+ if (IS_STN(cPtr->PanelType)) {
+ tmp = cPtr->readFR(cPtr, 0x1A); /*Frame Buffer Ctrl. */
+ if (tmp & 1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Frame Buffer used\n");
+ if (!(tmp & 0x80)) {
+ /* Formula for calculating the size of the framebuffer. 3
+ * bits per pixel 10 pixels per 32 bit dword. If frame
+ * acceleration is enabled the size can be halved.
+ */
+ cPtr->FrameBufferSize = ( Size->HDisplay *
+ Size->VDisplay / 5 ) * ((tmp & 2) ? 1 : 2);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Using embedded Frame Buffer, size %d bytes\n",
+ cPtr->FrameBufferSize);
+ } else
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Using external Frame Buffer used\n");
+ }
+ if (tmp & 2)
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Frame accelerator enabled\n");
+ }
+
+ /* bus type */
+ tmp = (cPtr->readXR(cPtr, 0x08)) & 1;
+ if (tmp == 1) { /*PCI */
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "PCI Bus\n");
+ cPtr->Bus = ChipsPCI;
+ } else { /* XR08: Linear addressing base, not for PCI */
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VL Bus\n");
+ cPtr->Bus = ChipsVLB;
+ }
+
+ /* disable acceleration for 1 and 4 bpp */
+ if (pScrn->bitsPerPixel < 8) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Disabling acceleration for %d bpp\n", pScrn->bitsPerPixel);
+ cPtr->Flags &= ~ChipsAccelSupport;
+ }
+
+ /* Set the flags for Colour transparency. This is dependent
+ * on the revision on the chip. Until exactly which chips
+ * have this bug are found, only allow 8bpp Colour transparency */
+ if ((pScrn->bitsPerPixel == 8) || ((cPtr->Chipset >= CHIPS_CT65555) &&
+ (pScrn->bitsPerPixel >= 8) && (pScrn->bitsPerPixel <= 24)))
+ cPtr->Flags |= ChipsColorTransparency;
+ else
+ cPtr->Flags &= ~ChipsColorTransparency;
+
+ /* DAC info */
+ if (!((cPtr->readXR(cPtr, 0xD0)) & 0x01))
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Internal DAC disabled\n");
+
+ /* MMIO address offset */
+ cPtr->Regs32 = ChipsReg32HiQV;
+
+ /* sync reset ignored on this chipset */
+ cPtr->SyncResetIgn = TRUE; /* !! */
+
+ /* We use a programmable clock */
+ pScrn->numClocks = 26; /* Some number */
+ pScrn->progClock = TRUE;
+ cPtr->ClockType = HiQV_STYLE | TYPE_PROGRAMMABLE;
+
+ if (cPtr->pEnt->device->textClockFreq > 0) {
+ SaveClk->Clock = cPtr->pEnt->device->textClockFreq;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using textclock freq: %7.3f.\n",
+ SaveClk->Clock/1000.0);
+ } else
+ SaveClk->Clock = 0;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Using programmable clocks\n");
+
+ /* Set the maximum memory clock. */
+ switch (cPtr->Chipset) {
+ case CHIPS_CT65550:
+ if (((cPtr->readXR(cPtr, 0x04)) & 0xF) < 6)
+ MemClk->Max = 38000; /* Revision A chips */
+ else
+ MemClk->Max = 50000; /* Revision B chips */
+ break;
+ case CHIPS_CT65554:
+ case CHIPS_CT65555:
+ case CHIPS_CT68554:
+ MemClk->Max = 55000;
+ break;
+ case CHIPS_CT69000:
+ MemClk->Max = 83000;
+ break;
+ case CHIPS_CT69030:
+ MemClk->Max = 100000;
+ break;
+ }
+
+ /* Probe the dot clocks */
+ for (i = 0; i < 3; i++) {
+ unsigned int N,M,PSN,P,VCO_D;
+ int offset = i * 4;
+
+ tmp = cPtr->readXR(cPtr,0xC2 + offset);
+ M = (cPtr->readXR(cPtr, 0xC0 + offset)
+ | (tmp & 0x03)) + 2;
+ N = (cPtr->readXR(cPtr, 0xC1 + offset)
+ | (( tmp >> 4) & 0x03)) + 2;
+ tmp = cPtr->readXR(cPtr, 0xC3 + offset);
+ PSN = (cPtr->Chipset == CHIPS_CT69000 || cPtr->Chipset == CHIPS_CT69030)
+ ? 1 : (((tmp & 0x1) ? 1 : 4) * ((tmp & 0x02) ? 5 : 1));
+ VCO_D = ((tmp & 0x04) ? ((cPtr->Chipset == CHIPS_CT69000 ||
+ cPtr->Chipset == CHIPS_CT69030) ? 1 : 16) : 4);
+ P = ((tmp & 0x70) >> 4);
+ Probed[i] = VCO_D * Fref / N;
+ Probed[i] = Probed[i] * M / (PSN * (1 << P));
+ Probed[i] = Probed[i] / 1000;
+ }
+ CRTclkI = (hwp->readMiscOut(hwp) >> 2) & 0x03;
+ if (CRTclkI == 3) CRTclkI = 2;
+ if (cPtr->Chipset == CHIPS_CT69030)
+ FPclkI = (cPtr->readFR(cPtr, 0x01) >> 2) & 0x3;
+ else
+ FPclkI = (cPtr->readFR(cPtr, 0x03) >> 2) & 0x3;
+ if (FPclkI == 3) FPclkI = 2;
+ for (i = 0; i < 3; i++) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Dot clock %i: %7.3f MHz",i,
+ (float)(Probed[i])/1000.);
+ if (FPclkI == i) xf86ErrorF(" FPclk");
+ if (CRTclkI == i) xf86ErrorF(" CRTclk");
+ xf86ErrorF("\n");
+ }
+ cPtr->FPclock = Probed[FPclkI];
+ cPtr->FPclkInx = FPclkI;
+ if (CRTclkI == FPclkI) {
+ if (FPclkI == 2)
+ CRTclkI = 1;
+ else
+ CRTclkI = 2;
+ }
+ cPtr->CRTclkInx = CRTclkI;
+
+
+ /*
+ * Some chips seem to dislike some clocks in one of the PLL's. Give
+ * the user the oppurtunity to change it
+ */
+ if (xf86GetOptValInteger(cPtr->Options, OPTION_CRT_CLK_INDX, &indx)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Force CRT Clock index to %d\n",
+ indx);
+ cPtr->CRTclkInx = indx;
+
+ if (xf86GetOptValInteger(cPtr->Options, OPTION_FP_CLK_INDX, &indx)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Force FP Clock index to %d\n", indx);
+ cPtr->FPclkInx = indx;
+ } else {
+ if (indx == cPtr->FPclkInx) {
+ if (indx == 2)
+ cPtr->FPclkInx = 1;
+ else
+ cPtr->FPclkInx = indx + 1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "FP Clock index forced to %d\n", cPtr->FPclkInx);
+ }
+ }
+ } else if (xf86GetOptValInteger(cPtr->Options, OPTION_FP_CLK_INDX,
+ &indx)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Force FP Clock index to %d\n", indx);
+ cPtr->FPclkInx = indx;
+ if (indx == cPtr->CRTclkInx) {
+ if (indx == 2)
+ cPtr->CRTclkInx = 1;
+ else
+ cPtr->CRTclkInx = indx + 1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "CRT Clock index forced to %d\n", cPtr->CRTclkInx);
+ }
+ }
+
+
+ /* Probe the memory clock currently in use */
+ MemClk->xrCC = cPtr->readXR(cPtr, 0xCC);
+ MemClk->M = (MemClk->xrCC & 0x7F) + 2;
+ MemClk->xrCD = cPtr->readXR(cPtr, 0xCD);
+ MemClk->N = (MemClk->xrCD & 0x7F) + 2;
+ MemClk->xrCE = cPtr->readXR(cPtr, 0xCE);
+ MemClk->PSN = (MemClk->xrCE & 0x1) ? 1 : 4;
+ MemClk->P = ((MemClk->xrCE & 0x70) >> 4);
+ /* Be careful with the calculation of ProbeClk as it can overflow */
+ MemClk->ProbedClk = 4 * Fref / MemClk->N;
+ MemClk->ProbedClk = MemClk->ProbedClk * MemClk->M / (MemClk->PSN *
+ (1 << MemClk->P));
+ MemClk->ProbedClk = MemClk->ProbedClk / 1000;
+ MemClk->Clk = MemClk->ProbedClk;
+
+ if (xf86GetOptValFreq(cPtr->Options, OPTION_SET_MCLK, OPTUNITS_MHZ, &real)) {
+ int mclk = (int)(real * 1000.0);
+ if (mclk <= MemClk->Max) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using memory clock of %7.3f MHz\n",
+ (float)(mclk/1000.));
+
+ /* Only alter the memory clock if the desired memory clock differs
+ * by 50kHz from the one currently being used.
+ */
+ if (abs(mclk - MemClk->ProbedClk) > 50) {
+ unsigned char vclk[3];
+
+ MemClk->Clk = mclk;
+ chipsCalcClock(pScrn, MemClk->Clk, vclk);
+ MemClk->M = vclk[1] + 2;
+ MemClk->N = vclk[2] + 2;
+ MemClk->P = (vclk[0] & 0x70) >> 4;
+ MemClk->PSN = (vclk[0] & 0x1) ? 1 : 4;
+ MemClk->xrCC = vclk[1];
+ MemClk->xrCD = vclk[2];
+ MemClk->xrCE = 0x80 || vclk[0];
+ }
+ } else
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Memory clock of %7.3f MHz exceeds limit of %7.3f MHz\n",
+ (float)(mclk/1000.),
+ (float)(MemClk->Max/1000.));
+ } else
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Probed memory clock of %7.3f MHz\n",
+ (float)(MemClk->ProbedClk/1000.));
+
+ cPtr->ClockMulFactor = 1;
+
+ /* Set the min pixel clock */
+ cPtr->MinClock = 11000; /* XXX Guess, need to check this */
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %7.3f MHz\n",
+ (float)(cPtr->MinClock / 1000.));
+ /* Set the max pixel clock */
+ switch (cPtr->Chipset) {
+ case CHIPS_CT69030:
+ cPtr->MaxClock = 170000;
+ break;
+ case CHIPS_CT69000:
+ cPtr->MaxClock = 135000;
+ break;
+ case CHIPS_CT68554:
+ case CHIPS_CT65555:
+ cPtr->MaxClock = 110000;
+ break;
+ case CHIPS_CT65554:
+ cPtr->MaxClock = 95000;
+ break;
+ case CHIPS_CT65550:
+ if (((cPtr->readXR(cPtr, 0x04)) & 0xF) < 6) {
+ if ((cPtr->readFR(cPtr, 0x0A)) & 2) {
+ /*5V Vcc */
+ cPtr->MaxClock = 100000;
+ } else {
+ /*3.3V Vcc */
+ cPtr->MaxClock = 80000;
+ }
+ } else
+ cPtr->MaxClock = 95000; /* Revision B */
+ break;
+ }
+
+ /* Check if maxClock is limited by the MemClk. Only 70% to allow for */
+ /* RAS/CAS. Extra byte per memory clock needed if framebuffer used */
+ /* Extra byte if the overlay plane is activated */
+ /* We have a 64bit wide memory bus on the 69030 and 69000, and 32bits */
+ /* on the others. Thus multiply by a suitable factor */
+ if ((cPtr->Chipset == CHIPS_CT69030) || (cPtr->Chipset == CHIPS_CT69000)) {
+ if (cPtr->FrameBufferSize && (cPtr->PanelType & ChipsLCD))
+ if (cPtr->Flags & ChipsOverlay8plus16 )
+ cPtr->MaxClock = min(cPtr->MaxClock, MemClk->Clk * 8 * 0.7 / 4);
+ else
+ cPtr->MaxClock = min(cPtr->MaxClock,
+ MemClk->Clk * 8 * 0.7 / (bytesPerPixel + 1));
+ else
+ if (cPtr->Flags & ChipsOverlay8plus16)
+ cPtr->MaxClock = min(cPtr->MaxClock, MemClk->Clk * 8 * 0.7 / 3);
+ else
+ cPtr->MaxClock = min(cPtr->MaxClock,
+ MemClk->Clk * 8 * 0.7 / bytesPerPixel);
+ } else {
+ if (cPtr->FrameBufferSize && (cPtr->PanelType & ChipsLCD))
+ if (cPtr->Flags & ChipsOverlay8plus16 )
+ cPtr->MaxClock = min(cPtr->MaxClock, MemClk->Clk * 4 * 0.7 / 4);
+ else
+ cPtr->MaxClock = min(cPtr->MaxClock,
+ MemClk->Clk * 4 * 0.7 / (bytesPerPixel + 1));
+ else
+ if (cPtr->Flags & ChipsOverlay8plus16)
+ cPtr->MaxClock = min(cPtr->MaxClock, MemClk->Clk * 4 * 0.7 / 3);
+ else
+ cPtr->MaxClock = min(cPtr->MaxClock,
+ MemClk->Clk * 4 * 0.7 / bytesPerPixel);
+ }
+
+
+
+ if (cPtr->pEnt->device->dacSpeeds[0]) {
+ int speed = 0;
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ case 4:
+ case 8:
+ speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP8];
+ break;
+ case 16:
+ speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP16];
+ break;
+ case 24:
+ speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP24];
+ break;
+ case 32:
+ speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP32];
+ break;
+ }
+
+ if (speed == 0)
+ speed = cPtr->pEnt->device->dacSpeeds[0];
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "User max pixel clock of %7.3f MHz overrides %7.3f MHz limit\n",
+ (float)(speed / 1000.), (float)(cPtr->MaxClock / 1000.));
+ cPtr->MaxClock = speed;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Max pixel clock is %7.3f MHz\n",
+ (float)(cPtr->MaxClock / 1000.));
+ }
+ /*
+ * Prepare the FPclock:
+ * if FPclock <= MaxClock : don't modify the FP clock.
+ * else set FPclock to 90% of MaxClock.
+ */
+ real = 0.;
+ switch(bytesPerPixel) {
+ case 1:
+ if (xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_8, OPTUNITS_MHZ, &real))
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "FP clock %7.3f MHz requested\n",real);
+ break;
+ case 2:
+ if (xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_16, OPTUNITS_MHZ, &real))
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "FP clock %7.3f MHz requested\n",real);
+ break;
+ case 3:
+ if (xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_24, OPTUNITS_MHZ, &real))
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "FP clock %7.3f MHz requested\n",real);
+ break;
+ case 4:
+ if (xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_32, OPTUNITS_MHZ, &real))
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "FP clock %7.3f MHz requested\n",real);
+ break;
+ }
+ val = (int) (real * 1000.);
+ if (val && val >= cPtr->MinClock && val <= cPtr->MaxClock)
+ cPtr->FPclock = val;
+ else if (cPtr->FPclock > cPtr->MaxClock)
+ cPtr->FPclock = (int)((float)cPtr->MaxClock * 0.9);
+ else
+ cPtr->FPclock = 0; /* special value */
+ cPtr->FPClkModified = FALSE;
+ if (cPtr->FPclock)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "FP clock set to %7.3f MHz\n",
+ (float)(cPtr->FPclock / 1000.));
+
+#if defined(__arm32__) && defined(__NetBSD__)
+ ChipsPALMode.next = pScrn->monitor->Modes;
+ pScrn->monitor->Modes = &ChipsNTSCMode;
+#endif
+
+
+ if (cPtr->Flags & ChipsDualChannelSupport) {
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ if (cPtr->SecondCrtc == TRUE) {
+ cPtrEnt->slaveActive = FALSE;
+ } else {
+ cPtrEnt->masterActive = FALSE;
+ }
+ }
+ /* Put IOSS/MSS back to normal */
+ cPtr->writeIOSS(cPtr, cPtr->storeIOSS);
+ cPtr->writeMSS(cPtr, hwp, cPtr->storeMSS);
+
+ xf86SetPrimInitDone(pScrn->entityList[0]);
+ }
+
+ return TRUE;
+}
+
+static Bool
+chipsPreInitWingine(ScrnInfoPtr pScrn, int flags)
+{
+ int i, bytesPerPixel, NoClocks = 0;
+ unsigned char tmp;
+ MessageType from;
+ vgaHWPtr hwp;
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSClockPtr SaveClk = &(cPtr->SavedReg.Clock);
+ Bool useLinear = FALSE;
+ char *s;
+ resRange linearRes[] = { {ResExcMemBlock|ResBios|ResBus,0,0},_END };
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ if (cPtr->Flags & ChipsHDepthSupport)
+ i = xf86SetDepthBpp(pScrn, 8, 8, 8, Support24bppFb |
+ SupportConvert32to24 | PreferConvert32to24);
+ else
+ i = xf86SetDepthBpp(pScrn, 8, 8, 8, NoDepth24Support);
+
+ if (!i)
+ return FALSE;
+ else {
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 1:
+ case 4:
+ case 8:
+ /* OK */
+ break;
+ case 15:
+ case 16:
+ case 24:
+ if (cPtr->Flags & ChipsHDepthSupport)
+ break; /* OK */
+ /* fall through */
+ 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);
+
+ /*
+ * Allocate a vgaHWRec, this must happen after xf86SetDepthBpp for 1bpp
+ */
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+
+ hwp = VGAHWPTR(pScrn);
+ vgaHWGetIOBase(hwp);
+
+ /*
+ * 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;
+
+ /* The gamma fields must be initialised when using the new cmap code */
+ if (pScrn->depth > 1) {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros))
+ return FALSE;
+ }
+
+ /* Store register values that might be messed up by a suspend resume */
+ /* Do this early as some of the other code in PreInit relies on it */
+ cPtr->SuspendHack.xr02 = (cPtr->readXR(cPtr, 0x02)) & 0x18;
+ cPtr->SuspendHack.xr03 = (cPtr->readXR(cPtr, 0x03)) & 0x0A;
+ cPtr->SuspendHack.xr14 = (cPtr->readXR(cPtr, 0x14)) & 0x20;
+ cPtr->SuspendHack.xr15 = cPtr->readXR(cPtr, 0x15);
+
+ cPtr->SuspendHack.vgaIOBaseFlag = ((hwp->readMiscOut(hwp)) & 0x01);
+ cPtr->IOBase = (unsigned int)(cPtr->SuspendHack.vgaIOBaseFlag ?
+ 0x3D0 : 0x3B0);
+
+ bytesPerPixel = max(1, pScrn->bitsPerPixel >> 3);
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /* Process the options */
+ if (!(cPtr->Options = xalloc(sizeof(ChipsWingineOptions))))
+ return FALSE;
+ memcpy(cPtr->Options, ChipsWingineOptions, sizeof(ChipsWingineOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, cPtr->Options);
+
+ /* Set the bits per RGB */
+ if (pScrn->depth > 1) {
+ /* Default to 6, is this right?? */
+ pScrn->rgbBits = 6;
+#if 0
+ if (xf86GetOptValInteger(cPtr->Options, OPTION_RGB_BITS,
+ &pScrn->rgbBits)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n",
+ pScrn->rgbBits);
+ }
+#endif
+ }
+ if ((cPtr->Flags & ChipsAccelSupport) &&
+ (xf86ReturnOptValBool(cPtr->Options, OPTION_NOACCEL, FALSE))) {
+ cPtr->Flags &= ~ChipsAccelSupport;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
+ }
+
+ from = X_DEFAULT;
+ if (pScrn->bitsPerPixel < 8) {
+ /* Default to SW cursor for 1/4 bpp */
+ cPtr->Accel.UseHWCursor = FALSE;
+ } else {
+ cPtr->Accel.UseHWCursor = TRUE;
+ }
+ if (xf86GetOptValBool(cPtr->Options, OPTION_HW_CURSOR,
+ &cPtr->Accel.UseHWCursor))
+ from = X_CONFIG;
+ if (xf86GetOptValBool(cPtr->Options, OPTION_SW_CURSOR,
+ &cPtr->Accel.UseHWCursor)) {
+ from = X_CONFIG;
+ cPtr->Accel.UseHWCursor = !cPtr->Accel.UseHWCursor;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ (cPtr->Accel.UseHWCursor) ? "HW" : "SW");
+
+ /* memory size */
+ if (cPtr->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = cPtr->pEnt->device->videoRam;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+ } else {
+ /* not given, probe it */
+ /* XR0F: Software flags 0 */
+ /* bit 1-0: memory size */
+ /* 0: 256 kB */
+ /* 1: 512 kB */
+ /* 2: 1024 kB */
+ /* 3: 1024 kB */
+
+ switch ((cPtr->readXR(cPtr, 0x0F)) & 3) {
+ case 0:
+ pScrn->videoRam = 256;
+ break;
+ case 1:
+ pScrn->videoRam = 512;
+ break;
+ case 2:
+ pScrn->videoRam = 1024;
+ break;
+ case 3:
+ pScrn->videoRam = 2048;
+ break;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+ }
+ cPtr->FbMapSize = pScrn->videoRam * 1024;
+
+ /* Default to nonlinear for < 8bpp and linear for >= 8bpp. */
+ if (cPtr->Flags & ChipsLinearSupport) useLinear = TRUE;
+ if (pScrn->bitsPerPixel < 8) {
+ if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, FALSE)) {
+ useLinear = FALSE;
+ from = X_CONFIG;
+ }
+ } else if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, TRUE)) {
+ useLinear = FALSE;
+ from = X_CONFIG;
+ }
+
+ /* linear base */
+ if (useLinear) {
+ unsigned char mask = 0xF8;
+ if (pScrn->videoRam == 1024)
+ mask = 0xF0;
+ else if (pScrn->videoRam == 2048)
+ mask = 0xE0;
+ if (cPtr->pEnt->device->MemBase) {
+ cPtr->FbAddress = cPtr->pEnt->device->MemBase
+ & ((0xFF << 24) | (mask << 16));
+ from = X_CONFIG;
+ } else {
+ cPtr->FbAddress = ((0xFF & (cPtr->readXR(cPtr, 0x09))) << 24);
+ cPtr->FbAddress |= ((mask & (cPtr->readXR(cPtr, 0x08))) << 16);
+ from = X_PROBED;
+ }
+ linearRes[0].rBegin = cPtr->FbAddress;
+ linearRes[0].rEnd = cPtr->FbAddress + 0x800000;
+ if (xf86RegisterResources(cPtr->pEnt->index,linearRes,ResNone)) {
+ useLinear = FALSE;
+ from = X_PROBED;
+ }
+ }
+
+ if (useLinear) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Enabling linear addressing\n");
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "base address is set at 0x%X.\n", cPtr->FbAddress);
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_MMIO, FALSE) &&
+ (cPtr->Flags & ChipsMMIOSupport)) {
+ cPtr->UseMMIO = TRUE;
+ cPtr->IOAddress = cPtr->FbAddress + 0x200000L;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Enabling MMIO\n");
+ }
+ } else {
+ if (cPtr->Flags & ChipsLinearSupport)
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Disabling linear addressing\n");
+ cPtr->Flags &= ~ChipsLinearSupport;
+ }
+
+ if ((s = xf86GetOptValString(cPtr->Options, OPTION_ROTATE))
+ || xf86ReturnOptValBool(cPtr->Options, OPTION_SHADOW_FB, FALSE)) {
+ if (!(cPtr->Flags & ChipsLinearSupport)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Option \"ShadowFB\" ignored. Not supported without linear addressing\n");
+ } else if (pScrn->depth < 8) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Option \"ShadowFB\" ignored. Not supported at this depth.\n");
+ } else {
+ cPtr->Rotate = 0;
+ if (s) {
+ if(!xf86NameCmp(s, "CW")) {
+ /* accel is disabled below for shadowFB */
+ cPtr->Flags |= ChipsShadowFB;
+ cPtr->Rotate = 1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Rotating screen clockwise\n");
+ } else if(!xf86NameCmp(s, "CCW")) {
+ cPtr->Flags |= ChipsShadowFB;
+ cPtr->Rotate = -1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen"
+ "counter clockwise\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");
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using \"Shadow Framebuffer\"\n");
+ cPtr->Flags |= ChipsShadowFB;
+ }
+ }
+ }
+ if (cPtr->Flags & ChipsShadowFB) {
+ if (cPtr->Flags & ChipsAccelSupport) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "HW acceleration is not supported with shadow fb\n");
+ cPtr->Flags &= ~ChipsAccelSupport;
+ }
+ if (cPtr->Rotate && cPtr->Accel.UseHWCursor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "HW cursor is not supported with rotate\n");
+ cPtr->Accel.UseHWCursor = FALSE;
+ }
+ }
+
+ cPtr->PanelType |= ChipsCRT;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT\n");
+
+ /* monitor info */
+ cPtr->Monitor = chipsSetMonitor(pScrn);
+
+ /* bus type */
+ tmp = cPtr->readXR(cPtr, 0x01) & 3;
+ switch (tmp) {
+ case 0:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ISA Bus\n");
+ cPtr->Bus = ChipsISA;
+ break;
+ case 3:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VL Bus\n");
+ cPtr->Bus = ChipsVLB;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Unknown Bus\n");
+ cPtr->Bus = ChipsUnknown;
+ break;
+ }
+
+ /* disable acceleration for 1 and 4 bpp */
+ if (pScrn->bitsPerPixel < 8) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Disabling acceleration for %d bpp\n", pScrn->bitsPerPixel);
+ cPtr->Flags &= ~ChipsAccelSupport;
+ }
+
+ /* 32bit register address offsets */
+ if ((cPtr->Flags & ChipsAccelSupport) ||
+ (cPtr->Accel.UseHWCursor)) {
+ cPtr->Regs32 = xnfalloc(sizeof(ChipsReg32));
+ tmp = cPtr->readXR(cPtr, 0x07);
+ for( i = 0; i < (sizeof(ChipsReg32) / sizeof(ChipsReg32[0])); i++) {
+ cPtr->Regs32[i] = ((ChipsReg32[i] & 0x7E03)) | ((tmp & 0x80)
+ << 8)| ((tmp & 0x7F) << 2);
+#ifdef DEBUG
+ ErrorF("DR[%X] = %X\n",i,cPtr->Regs32[i]);
+#endif
+ }
+ linearRes[0].type = ResExcIoSparse | ResBios | ResBus;
+ linearRes[0].rBase = cPtr->Regs32[0];
+ linearRes[0].rMask = 0x83FC;
+ if (xf86RegisterResources(cPtr->pEnt->index,linearRes,ResNone)) {
+ if (cPtr->Flags & ChipsAccelSupport) {
+ cPtr->Flags &= ~ChipsAccelSupport;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Cannot allocate IO registers: "
+ "Disabling acceleration\n");
+ }
+ if (cPtr->Accel.UseHWCursor) {
+ cPtr->Accel.UseHWCursor = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Cannot allocate IO registers: "
+ "Disabling HWCursor\n");
+ }
+ }
+ }
+
+ cPtr->ClockMulFactor = ((pScrn->bitsPerPixel >= 8) ? bytesPerPixel : 1);
+ if (cPtr->ClockMulFactor != 1)
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Clocks scaled by %d\n", cPtr->ClockMulFactor);
+
+ /* Clock type */
+ switch (cPtr->Chipset) {
+ case CHIPS_CT64200:
+ NoClocks = 4;
+ cPtr->ClockType = WINGINE_1_STYLE | TYPE_HW;
+ break;
+ default:
+ if (!((cPtr->readXR(cPtr, 0x01)) & 0x10)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Using external clock generator\n");
+ NoClocks = 4;
+ cPtr->ClockType = WINGINE_1_STYLE | TYPE_HW;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Using internal clock generator\n");
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_HW_CLKS, FALSE)) {
+ NoClocks = 3;
+ cPtr->ClockType = WINGINE_2_STYLE | TYPE_HW;
+ } else {
+ NoClocks = 26; /* some number */
+ cPtr->ClockType = WINGINE_2_STYLE | TYPE_PROGRAMMABLE;
+ pScrn->progClock = TRUE;
+ }
+ }
+ }
+
+ if (cPtr->ClockType & TYPE_PROGRAMMABLE) {
+ pScrn->numClocks = NoClocks;
+ if(cPtr->pEnt->device->textClockFreq > 0) {
+ SaveClk->Clock = cPtr->pEnt->device->textClockFreq;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using textclock freq: %7.3f.\n",
+ SaveClk->Clock/1000.0);
+ } else
+ SaveClk->Clock = CRT_TEXT_CLK_FREQ;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Using programmable clocks\n");
+ } else { /* TYPE_PROGRAMMABLE */
+ SaveClk->Clock = chipsGetHWClock(pScrn);
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using textclock clock %i.\n",
+ SaveClk->Clock);
+ if (!cPtr->pEnt->device->numclocks) {
+ pScrn->numClocks = NoClocks;
+ xf86GetClocks(pScrn, NoClocks, chipsClockSelect,
+ chipsProtect, chipsBlankScreen,
+ cPtr->IOBase + 0x0A, 0x08, 1, 28322);
+ from = X_PROBED;
+ } else {
+ pScrn->numClocks = cPtr->pEnt->device->numclocks;
+ if (pScrn->numClocks > NoClocks) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Too many Clocks specified in configuration file.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "\t\tAt most %d clocks may be specified\n", NoClocks);
+ pScrn->numClocks= NoClocks;
+ }
+ for (i = 0; i < pScrn->numClocks; i++)
+ pScrn->clock[i] = cPtr->pEnt->device->clock[i];
+ from = X_CONFIG;
+ }
+ xf86ShowClocks(pScrn, from);
+ }
+
+ /* Set the min pixel clock */
+ /* XXX Guess, need to check this */
+ cPtr->MinClock = 11000 / cPtr->ClockMulFactor;
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %7.3f MHz\n",
+ (float)(cPtr->MinClock / 1000.));
+ /* maximal clock */
+ switch (cPtr->Chipset) {
+ case CHIPS_CT64200:
+ cPtr->MaxClock = 80000 / cPtr->ClockMulFactor;
+ break;
+ case CHIPS_CT64300:
+ cPtr->MaxClock = 85000 / cPtr->ClockMulFactor;
+ break;
+ }
+
+ if (cPtr->pEnt->device->dacSpeeds[0]) {
+ int speed = 0;
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ case 4:
+ case 8:
+ speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP8];
+ break;
+ case 16:
+ speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP16];
+ break;
+ case 24:
+ speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP24];
+ break;
+ }
+ if (speed == 0)
+ cPtr->MaxClock = cPtr->pEnt->device->dacSpeeds[0];
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "User max pixel clock of %7.3f MHz overrides %7.3f MHz limit\n",
+ (float)(cPtr->MaxClock / 1000.), (float)(speed / 1000.));
+ cPtr->MaxClock = speed;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Max pixel clock is %7.3f MHz\n",
+ (float)(cPtr->MaxClock / 1000.));
+ }
+
+ if (xf86LoadSubModule(pScrn, "ddc")) {
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+ if (cPtr->pVbe)
+ xf86SetDDCproperties(pScrn,xf86PrintEDID(vbeDoEDID(cPtr->pVbe, NULL)));
+ }
+ return TRUE;
+}
+
+static Bool
+chipsPreInit655xx(ScrnInfoPtr pScrn, int flags)
+{
+ int i, bytesPerPixel, NoClocks = 0;
+ unsigned char tmp;
+ MessageType from;
+ vgaHWPtr hwp;
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSPanelSizePtr Size = &cPtr->PanelSize;
+ CHIPSClockPtr SaveClk = &(cPtr->SavedReg.Clock);
+ Bool useLinear = FALSE;
+ char *s;
+ resRange linearRes[] = { {ResExcMemBlock|ResBios|ResBus,0,0},_END };
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ if (cPtr->Flags & ChipsHDepthSupport)
+ i = xf86SetDepthBpp(pScrn, 8, 8, 8, Support24bppFb |
+ SupportConvert32to24 | PreferConvert32to24);
+ else
+ i = xf86SetDepthBpp(pScrn, 8, 8, 8, NoDepth24Support);
+
+ if (!i)
+ return FALSE;
+ else {
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 1:
+ case 4:
+ case 8:
+ /* OK */
+ break;
+ case 15:
+ case 16:
+ case 24:
+ if (cPtr->Flags & ChipsHDepthSupport)
+ break; /* OK */
+ /* fall through */
+ 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);
+
+ /*
+ * Allocate a vgaHWRec, this must happen after xf86SetDepthBpp for 1bpp
+ */
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+
+ hwp = VGAHWPTR(pScrn);
+ vgaHWGetIOBase(hwp);
+
+ /*
+ * 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;
+
+ /* The gamma fields must be initialised when using the new cmap code */
+ if (pScrn->depth > 1) {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros))
+ return FALSE;
+ }
+
+ /* Store register values that might be messed up by a suspend resume */
+ /* Do this early as some of the other code in PreInit relies on it */
+ cPtr->SuspendHack.xr02 = (cPtr->readXR(cPtr, 0x02)) & 0x18;
+ cPtr->SuspendHack.xr03 = (cPtr->readXR(cPtr, 0x03)) & 0x0A;
+ cPtr->SuspendHack.xr14 = (cPtr->readXR(cPtr, 0x14)) & 0x20;
+ cPtr->SuspendHack.xr15 = cPtr->readXR(cPtr, 0x15);
+
+ cPtr->SuspendHack.vgaIOBaseFlag = ((hwp->readMiscOut(hwp)) & 0x01);
+ cPtr->IOBase = cPtr->SuspendHack.vgaIOBaseFlag ? 0x3D0 : 0x3B0;
+
+ bytesPerPixel = max(1, pScrn->bitsPerPixel >> 3);
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /* Process the options */
+ if (!(cPtr->Options = xalloc(sizeof(Chips655xxOptions))))
+ return FALSE;
+ memcpy(cPtr->Options, Chips655xxOptions, sizeof(Chips655xxOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, cPtr->Options);
+
+ /* Set the bits per RGB */
+ if (pScrn->depth > 1) {
+ /* Default to 6, is this right */
+ pScrn->rgbBits = 6;
+#if 0
+ if (xf86GetOptValInteger(cPtr->Options, OPTION_RGB_BITS,
+ &pScrn->rgbBits)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n",
+ pScrn->rgbBits);
+ }
+#endif
+ }
+ if ((cPtr->Flags & ChipsAccelSupport) &&
+ (xf86ReturnOptValBool(cPtr->Options, OPTION_NOACCEL, FALSE))) {
+ cPtr->Flags &= ~ChipsAccelSupport;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
+ }
+
+ from = X_DEFAULT;
+ if (pScrn->bitsPerPixel < 8) {
+ /* Default to SW cursor for 1/4 bpp */
+ cPtr->Accel.UseHWCursor = FALSE;
+ } else {
+ cPtr->Accel.UseHWCursor = TRUE;
+ }
+ if (xf86GetOptValBool(cPtr->Options, OPTION_HW_CURSOR,
+ &cPtr->Accel.UseHWCursor))
+ from = X_CONFIG;
+ if (xf86GetOptValBool(cPtr->Options, OPTION_SW_CURSOR,
+ &cPtr->Accel.UseHWCursor)) {
+ from = X_CONFIG;
+ cPtr->Accel.UseHWCursor = !cPtr->Accel.UseHWCursor;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ (cPtr->Accel.UseHWCursor) ? "HW" : "SW");
+
+ /* memory size */
+ if (cPtr->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = cPtr->pEnt->device->videoRam;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+ } else {
+ /* not given, probe it */
+ /* XR0F: Software flags 0 */
+ /* bit 1-0: memory size */
+ /* 0: 256 kB */
+ /* 1: 512 kB */
+ /* 2: 1024 kB */
+ /* 3: 1024 kB */
+
+ switch ((cPtr->readXR(cPtr, 0x0F)) & 3) {
+ case 0:
+ pScrn->videoRam = 256;
+ break;
+ case 1:
+ pScrn->videoRam = 512;
+ break;
+ case 2:
+ case 3:
+ pScrn->videoRam = 1024;
+ break;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+ }
+ cPtr->FbMapSize = pScrn->videoRam * 1024;
+
+ /* Default to nonlinear for < 8bpp and linear for >= 8bpp. */
+ if (cPtr->Flags & ChipsLinearSupport) useLinear = TRUE;
+ if (pScrn->bitsPerPixel < 8) {
+ if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, FALSE)) {
+ useLinear = FALSE;
+ from = X_CONFIG;
+ }
+ } else if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, TRUE)) {
+ useLinear = FALSE;
+ from = X_CONFIG;
+ }
+
+ /* linear base */
+ if (useLinear) {
+ unsigned char mask;
+ if (cPtr->Chipset == CHIPS_CT65535) {
+ mask = (pScrn->videoRam > 512) ? 0xF8 :0xFC;
+ if (cPtr->Bus == ChipsISA)
+ mask &= 0x7F;
+ } else if (cPtr->Bus == ChipsISA) {
+ mask = 0x0F;
+ } else {
+ mask = 0xFF;
+ tmp = cPtr->readXR(cPtr, 0x01);
+ if(tmp & 0x40)
+ mask &= 0x3F;
+ if(!(tmp & 0x80))
+ mask &= 0xCF;
+ }
+ if (cPtr->pEnt->location.type == BUS_PCI) {
+ cPtr->FbAddress = cPtr->PciInfo->memBase[0] & 0xff800000;
+ if (xf86RegisterResources(cPtr->pEnt->index,NULL,ResNone))
+ useLinear = FALSE;
+ from = X_PROBED;
+ } else {
+ if (cPtr->pEnt->device->MemBase) {
+ cPtr->FbAddress = cPtr->pEnt->device->MemBase;
+ if (cPtr->Chipset == CHIPS_CT65535)
+ cPtr->FbAddress &= (mask << 17);
+ else if (cPtr->Chipset > CHIPS_CT65535)
+ cPtr->FbAddress &= (mask << 20);
+ from = X_CONFIG;
+ } else {
+ if (cPtr->Chipset <= CHIPS_CT65530) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "base address assumed at 0xC00000!\n");
+ cPtr->FbAddress = 0xC00000;
+ from = X_CONFIG;
+ } else if (cPtr->Chipset == CHIPS_CT65535) {
+ cPtr->FbAddress =
+ ((mask & (cPtr->readXR(cPtr, 0x08))) << 17);
+ } else {
+ cPtr->FbAddress =
+ ((mask & (cPtr->readXR(cPtr, 0x08))) << 20);
+ }
+ from = X_PROBED;
+ }
+ linearRes[0].rBegin = cPtr->FbAddress;
+ linearRes[0].rEnd = cPtr->FbAddress + 0x800000;
+ if (xf86RegisterResources(cPtr->pEnt->index,linearRes,ResNone)) {
+ useLinear = FALSE;
+ from = X_PROBED;
+ }
+ }
+ }
+
+ if (useLinear) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Enabling linear addressing\n");
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "base address is set at 0x%X.\n", cPtr->FbAddress);
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_MMIO, FALSE) &&
+ (cPtr->Flags & ChipsMMIOSupport)) {
+ cPtr->UseMMIO = TRUE;
+ cPtr->IOAddress = cPtr->FbAddress + 0x200000L;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Enabling MMIO\n");
+ }
+ } else {
+ if (cPtr->Flags & ChipsLinearSupport)
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Disabling linear addressing\n");
+ cPtr->Flags &= ~ChipsLinearSupport;
+ }
+
+ if ((s = xf86GetOptValString(cPtr->Options, OPTION_ROTATE))
+ || xf86ReturnOptValBool(cPtr->Options, OPTION_SHADOW_FB, FALSE)) {
+ if (!(cPtr->Flags & ChipsLinearSupport)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Option \"ShadowFB\" ignored. Not supported without linear addressing\n");
+ } else if (pScrn->depth < 8) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Option \"ShadowFB\" ignored. Not supported at this depth.\n");
+ } else {
+ cPtr->Rotate = 0;
+ if (s) {
+ if(!xf86NameCmp(s, "CW")) {
+ /* accel is disabled below for shadowFB */
+ cPtr->Flags |= ChipsShadowFB;
+ cPtr->Rotate = 1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Rotating screen clockwise\n");
+ } else if(!xf86NameCmp(s, "CCW")) {
+ cPtr->Flags |= ChipsShadowFB;
+ cPtr->Rotate = -1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen"
+ "counter clockwise\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");
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using \"Shadow Framebuffer\"\n");
+ cPtr->Flags |= ChipsShadowFB;
+ }
+ }
+ }
+ if (cPtr->Flags & ChipsShadowFB) {
+ if (cPtr->Flags & ChipsAccelSupport) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "HW acceleration is not supported with shadow fb\n");
+ cPtr->Flags &= ~ChipsAccelSupport;
+ }
+ if (cPtr->Rotate && cPtr->Accel.UseHWCursor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "HW cursor is not supported with rotate\n");
+ cPtr->Accel.UseHWCursor = FALSE;
+ }
+ }
+
+ /*test STN / TFT */
+ tmp = cPtr->readXR(cPtr, 0x51);
+
+ /* XR51 or FR10: DISPLAY TYPE REGISTER */
+ /* XR51[1-0] or FR10[1:0] for ct65550 : PanelType, */
+ /* 0 = Single Panel Single Drive, 3 = Dual Panel Dual Drive */
+ switch (tmp & 0x3) {
+ case 0:
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_STN, FALSE)) {
+ cPtr->PanelType |= ChipsSS;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "SS-STN probed\n");
+ } else {
+ cPtr->PanelType |= ChipsTFT;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "TFT probed\n");
+ }
+ break;
+ case 2:
+ cPtr->PanelType |= ChipsDS;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DS-STN probed\n");
+ case 3:
+ cPtr->PanelType |= ChipsDD;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DD-STN probed\n");
+ break;
+ default:
+ break;
+ }
+
+ chipsSetPanelType(cPtr);
+ from = X_PROBED;
+ {
+ Bool fp_mode;
+ if (xf86GetOptValBool(cPtr->Options, OPTION_FP_MODE, &fp_mode)) {
+ if (fp_mode) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing FP Mode on\n");
+ cPtr->PanelType |= ChipsLCD;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing FP Mode off\n");
+ cPtr->PanelType = ~ChipsLCD;
+ }
+ from = X_CONFIG;
+ }
+ }
+ if ((cPtr->PanelType & ChipsLCD) && (cPtr->PanelType & ChipsCRT))
+ xf86DrvMsg(pScrn->scrnIndex, from, "LCD/CRT\n");
+ else if (cPtr->PanelType & ChipsLCD)
+ xf86DrvMsg(pScrn->scrnIndex, from, "LCD\n");
+ else if (cPtr->PanelType & ChipsCRT) {
+ xf86DrvMsg(pScrn->scrnIndex, from, "CRT\n");
+ /* monitor info */
+ cPtr->Monitor = chipsSetMonitor(pScrn);
+ }
+
+ /* screen size */
+ /*
+ * In LCD mode / dual mode we want to derive the timing values from
+ * the ones preset by bios
+ */
+ if (cPtr->PanelType & ChipsLCD) {
+ unsigned char xr17, tmp1;
+ char tmp2;
+
+ xr17 = cPtr->readXR(cPtr, 0x17);
+ tmp = cPtr->readXR(cPtr, 0x1B);
+ Size->HTotal =((tmp + ((xr17 & 0x01) << 8)) + 5) << 3;
+ tmp = cPtr->readXR(cPtr, 0x1C);
+ Size->HDisplay = ((tmp + ((xr17 & 0x02) << 7)) + 1) << 3;
+ tmp = cPtr->readXR(cPtr, 0x19);
+ Size->HRetraceStart = ((tmp + ((xr17 & 0x04) << 9)) + 1) << 3;
+ tmp1 = cPtr->readXR(cPtr, 0x1A);
+ tmp2 = (tmp1 & 0x1F) + ((xr17 & 0x08) << 2) - (tmp & 0x3F);
+ Size->HRetraceEnd = ((((tmp2 < 0) ? (tmp2 + 0x40) : tmp2) << 3)
+ + Size->HRetraceStart);
+ tmp1 = cPtr->readXR(cPtr, 0x65);
+ tmp = cPtr->readXR(cPtr, 0x68);
+ Size->VDisplay = ((tmp1 & 0x02) << 7)
+ + ((tmp1 & 0x40) << 3) + tmp + 1;
+ tmp = cPtr->readXR(cPtr, 0x66);
+ Size->VRetraceStart = ((tmp1 & 0x04) << 6)
+ + ((tmp1 & 0x80) << 2) + tmp + 1;
+ tmp = cPtr->readXR(cPtr, 0x64);
+ Size->VTotal = ((tmp1 & 0x01) << 8)
+ + ((tmp1 & 0x20) << 4) + tmp + 2;
+#ifdef DEBUG
+ ErrorF("x=%i, y=%i; xSync=%i, xSyncEnd=%i, xTotal=%i\n",
+ Size->HDisplay, Size->VDisplay,
+ Size->HRetraceStart, Size->HRetraceEnd,
+ Size->HTotal);
+#endif
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Display Size: x=%i; y=%i\n",
+ Size->HDisplay, Size->VDisplay);
+ /* Warn the user if the panel size has been overridden by
+ * the modeline values
+ */
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_PANEL_SIZE, FALSE)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Display size overridden by modelines.\n");
+ }
+ }
+
+ /* Frame Buffer */ /* for LCDs */
+ if (IS_STN(cPtr->PanelType)) {
+ tmp = cPtr->readXR(cPtr, 0x6F); /*Frame Buffer Ctrl. */
+ if (tmp & 1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Frame Buffer used\n");
+ if ((cPtr->Chipset > CHIPS_CT65530) && !(tmp & 0x80)) {
+ /* Formula for calculating the size of the framebuffer. 3
+ * bits per pixel 10 pixels per 32 bit dword. If frame
+ * acceleration is enabled the size can be halved.
+ */
+ cPtr->FrameBufferSize = ( Size->HDisplay *
+ Size->VDisplay / 5 ) * ((tmp & 2) ? 1 : 2);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Using embedded Frame Buffer, size %d bytes\n",
+ cPtr->FrameBufferSize);
+ } else
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Using external Frame Buffer used\n");
+ }
+ if (tmp & 2)
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Frame accelerator enabled\n");
+ }
+
+ /* bus type */
+ if (cPtr->Chipset > CHIPS_CT65535) {
+ tmp = (cPtr->readXR(cPtr, 0x01)) & 7;
+ if (tmp == 6) { /*PCI */
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "PCI Bus\n");
+ cPtr->Bus = ChipsPCI;
+ if ((cPtr->Chipset == CHIPS_CT65545) ||
+ (cPtr->Chipset == CHIPS_CT65546)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "32Bit IO not supported on 65545 PCI\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "\tenabling MMIO\n");
+ cPtr->UseMMIO = TRUE;
+ cPtr->IOAddress = cPtr->FbAddress + 0x200000L;
+ }
+
+ } else { /* XR08: Linear addressing base, not for PCI */
+ switch (tmp) {
+ case 3:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CPU Direct\n");
+ cPtr->Bus = ChipsCPUDirect;
+ break;
+ case 5:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ISA Bus\n");
+ cPtr->Bus = ChipsISA;
+ break;
+ case 7:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VL Bus\n");
+ cPtr->Bus = ChipsVLB;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Unknown Bus\n");
+ }
+ }
+ } else {
+ tmp = (cPtr->readXR(cPtr, 0x01)) & 3;
+ switch (tmp) {
+ case 0:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "PI Bus\n");
+ cPtr->Bus = ChipsPIB;
+ break;
+ case 1:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "MC Bus\n");
+ cPtr->Bus = ChipsMCB;
+ break;
+ case 2:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VL Bus\n");
+ cPtr->Bus = ChipsVLB;
+ break;
+ case 3:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ISA Bus\n");
+ cPtr->Bus = ChipsISA;
+ break;
+ }
+ }
+
+ if (!(cPtr->Bus == ChipsPCI) && (cPtr->UseMMIO)) {
+ cPtr->UseMMIO = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "MMIO only supported on PCI Bus. Disabling MMIO\n");
+ }
+
+ /* disable acceleration for 1 and 4 bpp */
+ if (pScrn->bitsPerPixel < 8) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Disabling acceleration for %d bpp\n", pScrn->bitsPerPixel);
+ cPtr->Flags &= ~ChipsAccelSupport;
+ }
+
+ if ((cPtr->Chipset == CHIPS_CT65530) &&
+ (cPtr->Flags & ChipsLinearSupport)) {
+ /* linear mode is no longer default on ct65530 since it */
+ /* requires additional hardware which some manufacturers*/
+ /* might not provide. */
+ if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, FALSE))
+ cPtr->Flags &= ~ChipsLinearSupport;
+
+ /* Test wether linear addressing is possible on 65530 */
+ /* on the 65530 only the A19 select scheme can be used*/
+ /* for linear addressing since MEMW is used on ISA bus*/
+ /* systems. */
+ /* A19 however is used if video memory is > 512 Mb */
+ if ((cPtr->Bus == ChipsISA) && (pScrn->videoRam > 512)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "User selected linear fb not supported by HW!\n");
+ cPtr->Flags &= ~ChipsLinearSupport;
+ }
+ }
+
+ /* DAC info */
+ if ((cPtr->readXR(cPtr, 0x06)) & 0x02)
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Internal DAC disabled\n");
+
+ /* MMIO address offset */
+ if (cPtr->UseMMIO)
+ cPtr->Regs32 = ChipsReg32;
+ else if ((cPtr->Flags & ChipsAccelSupport) ||
+ (cPtr->Accel.UseHWCursor)) {
+ cPtr->Regs32 = xnfalloc(sizeof(ChipsReg32));
+ tmp = cPtr->readXR(cPtr, 0x07);
+ for (i = 0; i < (sizeof(ChipsReg32)/sizeof(ChipsReg32[0])); i++) {
+ cPtr->Regs32[i] =
+ ((ChipsReg32[i] & 0x7E03)) | ((tmp & 0x80)<< 8)
+ | ((tmp & 0x7F) << 2);
+#ifdef DEBUG
+ ErrorF("DR[%X] = %X\n",i,cPtr->Regs32[i]);
+#endif
+ }
+ linearRes[0].type = ResExcIoSparse | ResBios | ResBus;
+ linearRes[0].rBase = cPtr->Regs32[0];
+ linearRes[0].rMask = 0x83FC;
+ if (xf86RegisterResources(cPtr->pEnt->index,linearRes,ResNone)) {
+ if (cPtr->Flags & ChipsAccelSupport) {
+ cPtr->Flags &= ~ChipsAccelSupport;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Cannot allocate IO registers: "
+ "Disabling acceleration\n");
+ }
+ if (cPtr->Accel.UseHWCursor) {
+ cPtr->Accel.UseHWCursor = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Cannot allocate IO registers: "
+ "Disabling HWCursor\n");
+ }
+ }
+ }
+
+ /* sync reset ignored on this chipset */
+ if (cPtr->Chipset > CHIPS_CT65530) {
+ tmp = cPtr->readXR(cPtr, 0x0E);
+ if (tmp & 0x80)
+ cPtr->SyncResetIgn = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Synchronous reset %signored.\n",
+ (cPtr->SyncResetIgn ? "" : "not "));
+ }
+
+ cPtr->ClockMulFactor = ((pScrn->bitsPerPixel >= 8) ? bytesPerPixel : 1);
+ if (cPtr->ClockMulFactor != 1)
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Clocks scaled by %d\n", cPtr->ClockMulFactor);
+ /* We use a programmable clock */
+ switch (cPtr->Chipset) {
+ case CHIPS_CT65520:
+ case CHIPS_CT65525:
+ case CHIPS_CT65530:
+ NoClocks = 4; /* Some number */
+ cPtr->ClockType = OLD_STYLE | TYPE_HW;
+ break;
+ default:
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_HW_CLKS, FALSE)) {
+ NoClocks = 5; /* Some number */
+ cPtr->ClockType = NEW_STYLE | TYPE_HW;
+ } else {
+ NoClocks = 26; /* Some number */
+ cPtr->ClockType = NEW_STYLE | TYPE_PROGRAMMABLE;
+ pScrn->progClock = TRUE;
+ }
+ }
+
+ if (cPtr->ClockType & TYPE_PROGRAMMABLE) {
+ pScrn->numClocks = NoClocks;
+ if (cPtr->pEnt->device->textClockFreq > 0) {
+ SaveClk->Clock = cPtr->pEnt->device->textClockFreq;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using textclock freq: %7.3f.\n",
+ SaveClk->Clock/1000.0);
+ } else
+ SaveClk->Clock = ((cPtr->PanelType & ChipsLCDProbed) ?
+ LCD_TEXT_CLK_FREQ : CRT_TEXT_CLK_FREQ);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Using programmable clocks\n");
+ } else { /* TYPE_PROGRAMMABLE */
+ SaveClk->Clock = chipsGetHWClock(pScrn);
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using textclock clock %i.\n",
+ SaveClk->Clock);
+ if (!cPtr->pEnt->device->numclocks) {
+ pScrn->numClocks = NoClocks;
+ xf86GetClocks(pScrn, NoClocks, chipsClockSelect,
+ chipsProtect, chipsBlankScreen,
+ cPtr->IOBase + 0x0A, 0x08, 1, 28322);
+ from = X_PROBED;
+ } else {
+ pScrn->numClocks = cPtr->pEnt->device->numclocks;
+ if (pScrn->numClocks > NoClocks) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Too many Clocks specified in configuration file.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "\t\tAt most %d clocks may be specified\n", NoClocks);
+ pScrn->numClocks = NoClocks;
+ }
+ for (i = 0; i < pScrn->numClocks; i++)
+ pScrn->clock[i] = cPtr->pEnt->device->clock[i];
+ from = X_CONFIG;
+ }
+ xf86ShowClocks(pScrn, from);
+ }
+ /* Set the min pixel clock */
+ /* XXX Guess, need to check this */
+ cPtr->MinClock = 11000 / cPtr->ClockMulFactor;
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %7.3f MHz\n",
+ (float)(cPtr->MinClock / 1000.));
+ /* Set the max pixel clock */
+ switch (cPtr->Chipset) {
+ case CHIPS_CT65546:
+ case CHIPS_CT65548:
+ /* max VCLK is 80 MHz, max MCLK is 75 MHz for CT65548 */
+ /* It is not sure for CT65546, but it works with 60 nsec EDODRAM */
+ cPtr->MaxClock = 80000 / cPtr->ClockMulFactor;
+ break;
+ default:
+ if ((cPtr->readXR(cPtr, 0x6C)) & 2) {
+ /*5V Vcc */
+ cPtr->MaxClock = 68000 / cPtr->ClockMulFactor;
+ } else {
+ /*3.3V Vcc */
+ cPtr->MaxClock = 56000 / cPtr->ClockMulFactor;
+ }
+ }
+
+ if (cPtr->pEnt->device->dacSpeeds[0]) {
+ int speed = 0;
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ case 4:
+ case 8:
+ speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP8];
+ break;
+ case 16:
+ speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP16];
+ break;
+ case 24:
+ speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP24];
+ break;
+ }
+ if (speed == 0)
+ cPtr->MaxClock = cPtr->pEnt->device->dacSpeeds[0];
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "User max pixel clock of %7.3f MHz overrides %7.3f MHz limit\n",
+ (float)(cPtr->MaxClock / 1000.), (float)(speed / 1000.));
+ cPtr->MaxClock = speed;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Max pixel clock is %7.3f MHz\n",
+ (float)(cPtr->MaxClock / 1000.));
+ }
+
+ /* FP clock */
+ if (cPtr->ClockType & TYPE_PROGRAMMABLE) {
+ double real = 0;
+
+ switch(bytesPerPixel) {
+ case 1:
+ xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_8,
+ OPTUNITS_MHZ, &real);
+ break;
+ case 2:
+ xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_16,
+ OPTUNITS_MHZ, &real);
+ break;
+ case 3:
+ xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_24,
+ OPTUNITS_MHZ, &real);
+ break;
+ }
+
+ if (real > 0) {
+ int val;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "FP clock %7.3f MHz requested\n",real);
+ val = (int) (real * 1000.);
+ if (val && (val >= cPtr->MinClock)
+ && (val <= cPtr->MaxClock))
+ cPtr->FPclock = val * cPtr->ClockMulFactor;
+ else if (val > cPtr->MaxClock)
+ cPtr->FPclock = (int)((float)cPtr->MaxClock
+ * cPtr->ClockMulFactor * 0.9);
+ else
+ cPtr->FPclock = 0; /* special value */
+ } else
+ cPtr->FPclock = 0; /* special value */
+
+ if (cPtr->FPclock)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "FP clock set to %7.3f MHz\n",
+ (float)(cPtr->FPclock / 1000.));
+ } else {
+ if (xf86IsOptionSet(cPtr->Options, OPTION_SET_MCLK))
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "FP clock option not supported for this chipset\n");
+ }
+
+ /* Memory Clock */
+ if (cPtr->ClockType & TYPE_PROGRAMMABLE) {
+ double real;
+
+ switch (cPtr->Chipset) {
+ case CHIPS_CT65546:
+ case CHIPS_CT65548:
+ /* max MCLK is 75 MHz for CT65548 */
+ cPtr->MemClock.Max = 75000;
+ break;
+ default:
+ if ((cPtr->readXR(cPtr, 0x6C)) & 2) {
+ /*5V Vcc */
+ cPtr->MemClock.Max = 68000;
+ } else {
+ /*3.3V Vcc */
+ cPtr->MemClock.Max = 56000;
+ }
+ }
+
+ if (xf86GetOptValFreq(cPtr->Options, OPTION_SET_MCLK,
+ OPTUNITS_MHZ, &real)) {
+ int mclk = (int)(real * 1000.0);
+ if (mclk <= cPtr->MemClock.Max) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using memory clock of %7.3f MHz\n",
+ (float)(mclk/1000.));
+ cPtr->MemClock.Clk = mclk;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Memory clock of %7.3f MHz exceeds limit of "
+ "%7.3f MHz\n",(float)(mclk/1000.),
+ (float)(cPtr->MemClock.Max/1000.));
+ cPtr->MemClock.Clk = cPtr->MemClock.Max * 0.9;
+ }
+ } else
+ cPtr->MemClock.Clk = 0;
+ } else
+ if (xf86IsOptionSet(cPtr->Options, OPTION_SET_MCLK))
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Memory clock option not supported for this chipset\n");
+
+ if (xf86LoadSubModule(pScrn, "ddc")) {
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+ if (cPtr->pVbe)
+ xf86SetDDCproperties(pScrn,xf86PrintEDID(vbeDoEDID(cPtr->pVbe, NULL)));
+ }
+ return TRUE;
+}
+
+
+/* Mandatory */
+static Bool
+CHIPSEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSEntPtr cPtrEnt;
+
+ if (cPtr->Flags & ChipsDualChannelSupport) {
+ cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0],
+ CHIPSEntityIndex)->ptr;
+ DUALOPEN;
+ }
+ /* Should we re-save the text mode on each VT enter? */
+ if(!chipsModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+ if ((!(cPtr->Flags & ChipsOverlay8plus16))
+ && (cPtr->Flags & ChipsVideoSupport)
+ && (cPtr->Flags & ChipsLinearSupport))
+ CHIPSResetVideo(pScrn);
+
+ /*xf86UDelay(50000);*/
+ chipsHWCursorOn(cPtr, pScrn);
+ /* cursor settle delay */
+ xf86UDelay(50000);
+ CHIPSAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ xf86UDelay(50000);
+ return TRUE;
+}
+
+/* Mandatory */
+static void
+CHIPSLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ CHIPSEntPtr cPtrEnt;
+
+ /* Invalidate the cached acceleration registers */
+ cAcl->planemask = -1;
+ cAcl->fgColor = -1;
+ cAcl->bgColor = -1;
+
+ if (cPtr->Flags & ChipsDualChannelSupport) {
+ cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0],
+ CHIPSEntityIndex)->ptr;
+ if (cPtr->UseDualChannel)
+ DUALREOPEN;
+ DUALCLOSE;
+ } else {
+ chipsHWCursorOff(cPtr, pScrn);
+ chipsRestore(pScrn, &(VGAHWPTR(pScrn))->SavedReg, &cPtr->SavedReg,
+ TRUE);
+ chipsLock(pScrn);
+ }
+}
+
+
+static void
+chipsLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
+ VisualPtr pVisual)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ int i, index, shift ;
+ CHIPSEntPtr cPtrEnt;
+
+ shift = ((pScrn->depth == 15) &&
+ (!(cPtr->Flags & ChipsOverlay8plus16))) ? 3 : 0;
+
+ if (cPtr->UseDualChannel) {
+ cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0],
+ CHIPSEntityIndex)->ptr;
+ DUALREOPEN;
+ }
+
+ for (i = 0; i < numColors; i++) {
+ index = indices[i];
+ hwp->writeDacWriteAddr(hwp,index << shift);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index].red);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index].green);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index].blue);
+ DACDelay(hwp);
+ }
+
+ if (cPtr->UseDualChannel &&
+ (! xf86IsEntityShared(pScrn->entityList[0]))) {
+ unsigned int IOSS, MSS;
+ IOSS = cPtr->readIOSS(cPtr);
+ MSS = cPtr->readMSS(cPtr);
+ cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) |
+ IOSS_PIPE_B));
+ cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | MSS_PIPE_B));
+
+ for (i = 0; i < numColors; i++) {
+ index = indices[i];
+ hwp->writeDacWriteAddr(hwp,index << shift);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index].red);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index].green);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index].blue);
+ DACDelay(hwp);
+ }
+ cPtr->writeIOSS(cPtr, IOSS);
+ cPtr->writeMSS(cPtr, hwp, MSS);
+ }
+
+ /* This shouldn't be necessary, but we'll play safe. */
+ hwp->disablePalette(hwp);
+}
+
+static void
+chipsLoadPalette16(ScrnInfoPtr pScrn, int numColors, int *indices,
+ LOCO *colors, VisualPtr pVisual)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSEntPtr cPtrEnt;
+
+ int i, index;
+
+ if (cPtr->UseDualChannel) {
+ cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0],
+ CHIPSEntityIndex)->ptr;
+ DUALREOPEN;
+ }
+
+ for (i = 0; i < numColors; i++) {
+ index = indices[i];
+ hwp->writeDacWriteAddr(hwp, index << 2);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index >> 1].red);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index].green);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index >> 1].blue);
+ DACDelay(hwp);
+ }
+
+
+ if (cPtr->UseDualChannel &&
+ (! xf86IsEntityShared(pScrn->entityList[0]))) {
+ unsigned int IOSS, MSS;
+ IOSS = cPtr->readIOSS(cPtr);
+ MSS = cPtr->readMSS(cPtr);
+ cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) |
+ IOSS_PIPE_B));
+ cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | MSS_PIPE_B));
+
+ for (i = 0; i < numColors; i++) {
+ index = indices[i];
+ hwp->writeDacWriteAddr(hwp, index << 2);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index >> 1].red);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index].green);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index >> 1].blue);
+ DACDelay(hwp);
+ }
+
+ cPtr->writeIOSS(cPtr, IOSS);
+ cPtr->writeMSS(cPtr, hwp, MSS);
+ }
+
+ /* This shouldn't be necessary, but we'll play safe. */
+ hwp->disablePalette(hwp);
+}
+
+/* Mandatory */
+static Bool
+CHIPSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ vgaHWPtr hwp;
+ CHIPSPtr cPtr;
+ CHIPSACLPtr cAcl;
+ int ret;
+ int init_picture = 0;
+ VisualPtr visual;
+ int allocatebase, freespace, currentaddr;
+ unsigned int racflag = 0;
+ unsigned char *FBStart;
+ int height, width, displayWidth;
+ CHIPSEntPtr cPtrEnt = NULL;
+#ifdef DEBUG
+ ErrorF("CHIPSScreenInit\n");
+#endif
+
+ /*
+ * we need to get the ScrnInfoRec for this screen, so let's allocate
+ * one first thing
+ */
+ cPtr = CHIPSPTR(pScrn);
+ cAcl = CHIPSACLPTR(pScrn);
+
+ hwp = VGAHWPTR(pScrn);
+ hwp->MapSize = 0x10000; /* Standard 64k VGA window */
+
+ /* Map the VGA memory */
+ if (!vgaHWMapMem(pScrn))
+ return FALSE;
+
+ /* Map the Chips memory and possible MMIO areas */
+ if (!chipsMapMem(pScrn))
+ return FALSE;
+
+ /* Setup a pointer to the overlay if needed */
+ if (cPtr->Flags & ChipsOverlay8plus16) {
+ cPtr->FbOffset16 = pScrn->displayWidth * pScrn->virtualY;
+ cPtr->FbSize16 = (pScrn->displayWidth << 1) * pScrn->virtualY;
+ if (cPtr->FbSize16 > (cPtr->FbMapSize - cPtr->FrameBufferSize)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Too little memory for overlay. Disabling.\n");
+ cPtr->Flags &= ~ChipsOverlay8plus16;
+ }
+ if ((pScrn->displayWidth > 1024) || (pScrn->virtualY > 1024)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Max overlay Width/Height 1024 pixels. Disabling.\n");
+ cPtr->Flags &= ~ChipsOverlay8plus16;
+ }
+ }
+
+ /* Setup the MMIO register access functions if need */
+ if (cPtr->UseFullMMIO && cPtr->MMIOBaseVGA) {
+ CHIPSSetMmioExtFuncs(cPtr);
+ CHIPSHWSetMmioFuncs(pScrn, cPtr->MMIOBaseVGA, 0x0);
+ }
+
+ if (cPtr->Flags & ChipsDualChannelSupport) {
+ cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0],
+ CHIPSEntityIndex)->ptr;
+ DUALOPEN;
+ }
+
+#if defined(__arm32__) && defined(__NetBSD__)
+ if (strcmp(pScrn->currentMode->name,"PAL") == 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using built-in PAL TV mode\n");
+ cPtr->TVMode = XMODE_PAL;
+ } else if (strcmp(pScrn->currentMode->name,"SECAM") == 0){
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using built-in SECAM TV mode\n");
+ cPtr->TVMode = XMODE_SECAM;
+ } else if (strcmp(pScrn->currentMode->name,"NTSC") == 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using built-in NTSC TV mode\n");
+ cPtr->TVMode = XMODE_NTSC;
+ } else
+ cPtr->TVMode = XMODE_RGB;
+#endif
+
+ /*
+ * next we save the current state and setup the first mode
+ */
+ if ((cPtr->Flags & ChipsDualChannelSupport) &&
+ (! xf86IsEntityShared(pScrn->entityList[0]))) {
+ unsigned int IOSS, MSS;
+ IOSS = cPtr->readIOSS(cPtr);
+ MSS = cPtr->readMSS(cPtr);
+ cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) |
+ IOSS_PIPE_A));
+ cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | MSS_PIPE_A));
+ chipsSave(pScrn, &hwp->SavedReg, &cPtr->SavedReg);
+ cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) |
+ IOSS_PIPE_B));
+ cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | MSS_PIPE_B));
+ chipsSave(pScrn, &cPtr->VgaSavedReg2, &cPtr->SavedReg2);
+ cPtr->writeIOSS(cPtr, IOSS);
+ cPtr->writeMSS(cPtr, hwp, MSS);
+ } else
+ chipsSave(pScrn, &hwp->SavedReg, &cPtr->SavedReg);
+
+ if (!chipsModeInit(pScrn,pScrn->currentMode))
+ return FALSE;
+ CHIPSSaveScreen(pScreen,SCREEN_SAVER_ON);
+ CHIPSAdjustFrame(pScrn->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 ((pScrn->bitsPerPixel == 16) && (cPtr->Flags & ChipsOverlay8plus16)){
+ if (!miSetVisualTypes(8, PseudoColorMask | GrayScaleMask,
+ pScrn->rgbBits, PseudoColor))
+ return FALSE;
+ if (!miSetVisualTypes(16, TrueColorMask, pScrn->rgbBits, TrueColor))
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ }
+ miSetPixmapDepths ();
+
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+ if ((cPtr->Flags & ChipsShadowFB) && cPtr->Rotate) {
+ height = pScrn->virtualX;
+ width = pScrn->virtualY;
+ } else {
+ width = pScrn->virtualX;
+ height = pScrn->virtualY;
+ }
+
+ if(cPtr->Flags & ChipsShadowFB) {
+ cPtr->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
+ cPtr->ShadowPtr = xalloc(cPtr->ShadowPitch * height);
+ displayWidth = cPtr->ShadowPitch / (pScrn->bitsPerPixel >> 3);
+ FBStart = cPtr->ShadowPtr;
+ } else {
+ cPtr->ShadowPtr = NULL;
+ displayWidth = pScrn->displayWidth;
+ FBStart = cPtr->FbBase;
+ }
+
+ 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 16:
+ if (cPtr->Flags & ChipsOverlay8plus16) {
+ ret = cfb8_16ScreenInit(pScreen, (unsigned char *)FBStart +
+ cPtr->FbOffset16, FBStart, width,
+ height, pScrn->xDpi, pScrn->yDpi,
+ displayWidth, displayWidth);
+ break;
+ }
+ default:
+ ret = fbScreenInit(pScreen, FBStart,
+ width,height,
+ pScrn->xDpi, pScrn->yDpi,
+ displayWidth,pScrn->bitsPerPixel);
+ init_picture = 1;
+ break;
+ }
+
+ if (!ret)
+ return FALSE;
+
+ if (pScrn->depth > 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;
+ }
+ }
+ }
+
+ /* must be after RGB ordering fixed */
+ if (init_picture)
+ fbPictureInit (pScreen, 0, 0);
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ cPtr->BlockHandler = pScreen->BlockHandler;
+ pScreen->BlockHandler = chipsBlockHandler;
+
+ if ( (pScrn->depth >= 8))
+ CHIPSDGAInit(pScreen);
+
+ cPtr->HWCursorShown = FALSE;
+
+ if (!(cPtr->Flags & ChipsLinearSupport)) {
+ miBankInfoPtr pBankInfo;
+
+ /* Setup the vga banking variables */
+ pBankInfo = (miBankInfoPtr)xnfcalloc(sizeof(miBankInfoRec),1);
+ if (pBankInfo == NULL)
+ return FALSE;
+
+#if defined(__arm32__)
+ cPtr->Bank = -1;
+#endif
+ pBankInfo->pBankA = hwp->Base;
+ pBankInfo->pBankB = (unsigned char *)hwp->Base + 0x08000;
+ pBankInfo->BankSize = 0x08000;
+ pBankInfo->nBankDepth = (pScrn->depth == 4) ? 1 : pScrn->depth;
+
+ if (IS_HiQV(cPtr)) {
+ pBankInfo->pBankB = hwp->Base;
+ pBankInfo->BankSize = 0x10000;
+ if (pScrn->bitsPerPixel < 8) {
+ pBankInfo->SetSourceBank =
+ (miBankProcPtr)CHIPSHiQVSetReadWritePlanar;
+ pBankInfo->SetDestinationBank =
+ (miBankProcPtr)CHIPSHiQVSetReadWritePlanar;
+ pBankInfo->SetSourceAndDestinationBanks =
+ (miBankProcPtr)CHIPSHiQVSetReadWritePlanar;
+ } else {
+ pBankInfo->SetSourceBank =
+ (miBankProcPtr)CHIPSHiQVSetReadWrite;
+ pBankInfo->SetDestinationBank =
+ (miBankProcPtr)CHIPSHiQVSetReadWrite;
+ pBankInfo->SetSourceAndDestinationBanks =
+ (miBankProcPtr)CHIPSHiQVSetReadWrite;
+ }
+ } else {
+ if (IS_Wingine(cPtr)) {
+ if (pScrn->bitsPerPixel < 8) {
+ pBankInfo->SetSourceBank =
+ (miBankProcPtr)CHIPSWINSetReadPlanar;
+ pBankInfo->SetDestinationBank =
+ (miBankProcPtr)CHIPSWINSetWritePlanar;
+ pBankInfo->SetSourceAndDestinationBanks =
+ (miBankProcPtr)CHIPSWINSetReadWritePlanar;
+ } else {
+ pBankInfo->SetSourceBank = (miBankProcPtr)CHIPSWINSetRead;
+ pBankInfo->SetDestinationBank =
+ (miBankProcPtr)CHIPSWINSetWrite;
+ pBankInfo->SetSourceAndDestinationBanks =
+ (miBankProcPtr)CHIPSWINSetReadWrite;
+ }
+ } else {
+ if (pScrn->bitsPerPixel < 8) {
+ pBankInfo->SetSourceBank =
+ (miBankProcPtr)CHIPSSetReadPlanar;
+ pBankInfo->SetDestinationBank =
+ (miBankProcPtr)CHIPSSetWritePlanar;
+ pBankInfo->SetSourceAndDestinationBanks =
+ (miBankProcPtr)CHIPSSetReadWritePlanar;
+ } else {
+ pBankInfo->SetSourceBank = (miBankProcPtr)CHIPSSetRead;
+ pBankInfo->SetDestinationBank =
+ (miBankProcPtr)CHIPSSetWrite;
+ pBankInfo->SetSourceAndDestinationBanks =
+ (miBankProcPtr)CHIPSSetReadWrite;
+ }
+ }
+ }
+ if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY,
+ pScrn->displayWidth, pBankInfo)) {
+ xfree(pBankInfo);
+ pBankInfo = NULL;
+ return FALSE;
+ }
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ /* Initialise cursor functions */
+ miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
+
+ } else {
+ /* !!! Only support linear addressing for now. This might change */
+ /* Setup pointers to free space in video ram */
+#define CHIPSALIGN(size, align) (currentaddr - ((currentaddr - size) & ~align))
+ allocatebase = (pScrn->videoRam<<10) - cPtr->FrameBufferSize;
+
+ if (pScrn->bitsPerPixel < 8)
+ freespace = allocatebase - pScrn->displayWidth *
+ pScrn->virtualY / 2;
+ else if ((pScrn->bitsPerPixel == 16) && (cPtr->Flags & ChipsOverlay8plus16))
+ freespace = allocatebase - pScrn->displayWidth *
+ pScrn->virtualY - cPtr->FbSize16;
+ else
+ freespace = allocatebase - pScrn->displayWidth *
+ pScrn->virtualY * (pScrn->bitsPerPixel >> 3);
+
+ if ((cPtr->Flags & ChipsDualChannelSupport) &&
+ (cPtr->SecondCrtc == TRUE)) {
+ currentaddr = allocatebase + cPtrEnt->masterFbMapSize;
+ } else
+ currentaddr = allocatebase;
+ if (serverGeneration == 1)
+ xf86DrvMsg(scrnIndex, X_PROBED,
+ "%d bytes off-screen memory available\n", freespace);
+
+ /*
+ * Allocate video memory to store the hardware cursor. Allocate 1kB
+ * vram to the cursor, with 1kB alignment for 6554x's and 4kb alignment
+ * for 65550's. Wingine cursor is stored in registers and so no memory
+ * is needed.
+ */
+ if (cAcl->UseHWCursor) {
+ cAcl->CursorAddress = -1;
+ if (IS_HiQV(cPtr)) {
+ if (CHIPSALIGN(1024, 0xFFF) <= freespace) {
+ currentaddr -= CHIPSALIGN(1024, 0xFFF);
+ freespace -= CHIPSALIGN(1024, 0xFFF);
+ cAcl->CursorAddress = currentaddr;
+ }
+ } else if (IS_Wingine(cPtr)) {
+ cAcl->CursorAddress = 0;
+ } else if (CHIPSALIGN(1024, 0x3FF) <= freespace) {
+ currentaddr -= CHIPSALIGN(1024, 0x3FF);
+ freespace -= CHIPSALIGN(1024, 0x3FF);
+ cAcl->CursorAddress = currentaddr;
+ }
+ if (cAcl->CursorAddress == -1)
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Too little space for H/W cursor.\n");
+ }
+
+ cAcl->CacheEnd = currentaddr;
+
+ /* Setup the acceleration primitives */
+ /* Calculate space needed of offscreen pixmaps etc. */
+ if (cPtr->Flags & ChipsAccelSupport) {
+ /*
+ * A scratch area is now allocated in the video ram. This is used
+ * at 8 and 16 bpp to simulate a planemask with a complex ROP, and
+ * at 24 and 32 bpp to aid in accelerating solid fills
+ */
+ cAcl->ScratchAddress = -1;
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ if (CHIPSALIGN(64, 0x3F) <= freespace) {
+ currentaddr -= CHIPSALIGN(64, 0x3F);
+ freespace -= CHIPSALIGN(64, 0x3F);
+ cAcl->ScratchAddress = currentaddr;
+ }
+ break;
+ case 16:
+ if (CHIPSALIGN(128, 0x7F) <= freespace) {
+ currentaddr -= CHIPSALIGN(128, 0x7F);
+ freespace -= CHIPSALIGN(128, 0x7F);
+ cAcl->ScratchAddress = currentaddr;
+ }
+ break;
+ case 24:
+ /* One scanline of data used for solid fill */
+ if (!IS_HiQV(cPtr)) {
+ if (CHIPSALIGN(3 * (pScrn->displayWidth + 4), 0x3)
+ <= freespace) {
+ currentaddr -= CHIPSALIGN(3 * (pScrn->displayWidth
+ + 4), 0x3);
+ freespace -= CHIPSALIGN(3 * (pScrn->displayWidth + 4),
+ 0x3);
+ cAcl->ScratchAddress = currentaddr;
+ }
+ }
+ break;
+ case 32:
+ /* 16bpp 8x8 mono pattern fill for solid fill. QWORD aligned */
+ if (IS_HiQV(cPtr)) {
+ if (CHIPSALIGN(8, 0x7) <= freespace) {
+ currentaddr -= CHIPSALIGN(8, 0x7);
+ freespace -= CHIPSALIGN(8, 0x7);
+ cAcl->ScratchAddress = currentaddr;
+ }
+ }
+ break;
+ }
+
+ /* Setup the boundaries of the pixmap cache */
+ cAcl->CacheStart = currentaddr - freespace;
+ cAcl->CacheEnd = currentaddr;
+
+ if (cAcl->CacheStart >= cAcl->CacheEnd) {
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Too little space for pixmap cache.\n");
+ cAcl->CacheStart = 0;
+ cAcl->CacheEnd = 0;
+ }
+
+ if (IS_HiQV(cPtr))
+ cAcl->BltDataWindow = (unsigned char *)cPtr->MMIOBase
+ + 0x10000L;
+ else
+ cAcl->BltDataWindow = cPtr->FbBase;
+
+ }
+ /*
+ * Initialize FBManager:
+ * we do even with no acceleration enabled
+ * so that video support can allocate space.
+ */
+
+ {
+ BoxRec AvailFBArea;
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = cAcl->CacheEnd /
+ (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3));
+
+ if (!(cPtr->Flags & ChipsOverlay8plus16)) {
+ xf86InitFBManager(pScreen, &AvailFBArea);
+ }
+ }
+ if (cPtr->Flags & ChipsAccelSupport) {
+ if (IS_HiQV(cPtr)) {
+ CHIPSHiQVAccelInit(pScreen);
+ } else if (cPtr->UseMMIO) {
+ CHIPSMMIOAccelInit(pScreen);
+ } else {
+ CHIPSAccelInit(pScreen);
+ }
+ }
+
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+#ifdef ENABLE_SILKEN_MOUSE
+ xf86SetSilkenMouse(pScreen);
+#endif
+
+ /* Initialise cursor functions */
+ miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
+
+ if ((cAcl->UseHWCursor) && (cAcl->CursorAddress != -1)) {
+ /* HW cursor functions */
+ if (!CHIPSCursorInit(pScreen)) {
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Hardware cursor initialization failed\n");
+ return FALSE;
+ }
+ }
+ }
+
+ if (cPtr->Flags & ChipsShadowFB) {
+ RefreshAreaFuncPtr refreshArea = chipsRefreshArea;
+
+ if(cPtr->Rotate) {
+ if (!cPtr->PointerMoved) {
+ cPtr->PointerMoved = pScrn->PointerMoved;
+ pScrn->PointerMoved = chipsPointerMoved;
+ }
+
+ switch(pScrn->bitsPerPixel) {
+ case 8: refreshArea = chipsRefreshArea8; break;
+ case 16: refreshArea = chipsRefreshArea16; break;
+ case 24: refreshArea = chipsRefreshArea24; break;
+ case 32: refreshArea = chipsRefreshArea32; break;
+ }
+ }
+ ShadowFBInit(pScreen, refreshArea);
+ }
+
+ /* Initialise default colourmap */
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+
+ if ((cPtr->Flags & ChipsOverlay8plus16) && (pScrn->bitsPerPixel == 16)) {
+ if(!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits, chipsLoadPalette,
+ NULL, CMAP_RELOAD_ON_MODE_SWITCH))
+ return FALSE;
+ } else {
+ if(!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits,
+ (pScrn->depth == 16 ? chipsLoadPalette16 : chipsLoadPalette),
+ NULL, CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR))
+ return FALSE;
+ }
+
+ racflag = RAC_COLORMAP;
+ if (cAcl->UseHWCursor)
+ racflag |= RAC_CURSOR;
+ racflag |= (RAC_FB | RAC_VIEWPORT);
+ /* XXX Check if I/O and Mem flags need to be the same. */
+ pScrn->racIoFlags = pScrn->racMemFlags = racflag;
+#ifdef ENABLE_SILKEN_MOUSE
+ xf86SetSilkenMouse(pScreen);
+#endif
+
+ if ((!(cPtr->Flags & ChipsOverlay8plus16))
+ && (cPtr->Flags & ChipsVideoSupport)
+ && (cPtr->Flags & ChipsLinearSupport)) {
+ CHIPSInitVideo(pScreen);
+ }
+
+ pScreen->SaveScreen = CHIPSSaveScreen;
+
+ /* Setup DPMS mode */
+ if (cPtr->Flags & ChipsDPMSSupport)
+ xf86DPMSInit(pScreen, (DPMSSetProcPtr)chipsDisplayPowerManagementSet,
+ 0);
+
+#if 0 /* #### Shouldn't be needed */
+ /* Dual head, needs to fix framebuffer memory address */
+ if ((cPtr->Flags & ChipsDualChannelSupport) &&
+ (cPtr->SecondCrtc == TRUE))
+ pScrn->memPhysBase = cPtr->FbAddress + cPtrEnt->masterFbMapSize;
+#endif
+
+ /* Wrap the current CloseScreen function */
+ cPtr->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = CHIPSCloseScreen;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+ return TRUE;
+}
+
+/* Mandatory */
+Bool
+CHIPSSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSEntPtr cPtrEnt;
+
+#ifdef DEBUG
+ ErrorF("CHIPSSwitchMode\n");
+#endif
+ if (cPtr->UseDualChannel) {
+ cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0],
+ CHIPSEntityIndex)->ptr;
+ DUALREOPEN;
+ }
+
+ return chipsModeInit(xf86Screens[scrnIndex], mode);
+}
+
+/* Mandatory */
+void
+CHIPSAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSEntPtr cPtrEnt;
+
+ int Base;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ unsigned char tmp;
+
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_SHOWCACHE, FALSE) && y) {
+ int lastline = cPtr->FbMapSize /
+ ((pScrn->displayWidth * pScrn->bitsPerPixel) / 8);
+ lastline -= pScrn->currentMode->VDisplay;
+ y += pScrn->virtualY - 1;
+ if (y > lastline) y = lastline;
+ }
+
+ Base = y * pScrn->displayWidth + x;
+
+ /* calculate base bpp dep. */
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ case 4:
+ Base >>= 3;
+ break;
+ case 16:
+ if (!(cPtr->Flags & ChipsOverlay8plus16))
+ Base >>= 1;
+ else
+ Base >>= 2;
+ break;
+ case 24:
+ if (!IS_HiQV(cPtr))
+ Base = (Base >> 2) * 3;
+ else
+ Base = (Base >> 3) * 6; /* 65550 seems to need 64bit alignment */
+ break;
+ case 32:
+ break;
+ default: /* 8bpp */
+ Base >>= 2;
+ break;
+ }
+
+ if (cPtr->UseDualChannel) {
+ cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0],
+ CHIPSEntityIndex)->ptr;
+ DUALREOPEN;
+ }
+
+ /* write base to chip */
+ /*
+ * These are the generic starting address registers.
+ */
+ chipsFixResume(pScrn);
+ hwp->writeCrtc(hwp, 0x0C, (Base & 0xFF00) >> 8);
+ hwp->writeCrtc(hwp, 0x0D, Base & 0xFF);
+ if (IS_HiQV(cPtr)) {
+ if (((cPtr->readXR(cPtr, 0x09)) & 0x1) == 0x1)
+ hwp->writeCrtc(hwp, 0x40, ((Base & 0x0F0000) >> 16) | 0x80);
+ } else {
+ tmp = cPtr->readXR(cPtr, 0x0C);
+ cPtr->writeXR(cPtr, 0x0C, ((Base & (IS_Wingine(cPtr) ? 0x0F0000 :
+ 0x030000)) >> 16) | (tmp & 0xF8));
+ }
+
+ if (cPtr->UseDualChannel &&
+ (! xf86IsEntityShared(pScrn->entityList[0]))) {
+ unsigned int IOSS, MSS;
+ IOSS = cPtr->readIOSS(cPtr);
+ MSS = cPtr->readMSS(cPtr);
+ cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) |
+ IOSS_PIPE_B));
+ cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | MSS_PIPE_B));
+
+ chipsFixResume(pScrn);
+ hwp->writeCrtc(hwp, 0x0C, (Base & 0xFF00) >> 8);
+ hwp->writeCrtc(hwp, 0x0D, Base & 0xFF);
+ if (((cPtr->readXR(cPtr, 0x09)) & 0x1) == 0x1)
+ hwp->writeCrtc(hwp, 0x40, ((Base & 0x0F0000) >> 16) | 0x80);
+
+ cPtr->writeIOSS(cPtr, IOSS);
+ cPtr->writeMSS(cPtr, hwp, MSS);
+ }
+
+ if (cPtr->Flags & ChipsOverlay8plus16) {
+ Base = (Base << 3) & ~(unsigned long)0xF;
+
+ cPtr->writeMR(cPtr, 0x22, (cPtr->FbOffset16 + Base) & 0xF8);
+ cPtr->writeMR(cPtr, 0x23, ((cPtr->FbOffset16 + Base) >> 8) & 0xFF);
+ cPtr->writeMR(cPtr, 0x24, ((cPtr->FbOffset16 + Base) >> 16) & 0xFF);
+ }
+
+}
+
+/* Mandatory */
+static Bool
+CHIPSCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSEntPtr cPtrEnt;
+
+ if(pScrn->vtSema){ /*§§§*/
+ if (cPtr->Flags & ChipsDualChannelSupport) {
+ cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0],
+ CHIPSEntityIndex)->ptr;
+ if (cPtr->UseDualChannel)
+ DUALREOPEN;
+ DUALCLOSE;
+ } else {
+ chipsHWCursorOff(cPtr, pScrn);
+ chipsRestore(pScrn, &(VGAHWPTR(pScrn))->SavedReg, &cPtr->SavedReg,
+ TRUE);
+ chipsLock(pScrn);
+ }
+ chipsUnmapMem(pScrn);
+ }
+
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ DevUnion *pPriv;
+ pPriv = xf86GetEntityPrivate(pScrn->entityList[0], CHIPSEntityIndex);
+ cPtrEnt = pPriv->ptr;
+ cPtrEnt->refCount--;
+ }
+ if (cPtr->AccelInfoRec)
+ XAADestroyInfoRec(cPtr->AccelInfoRec);
+ if (cPtr->CursorInfoRec)
+ xf86DestroyCursorInfoRec(cPtr->CursorInfoRec);
+ if (cPtr->ShadowPtr)
+ xfree(cPtr->ShadowPtr);
+ if (cPtr->DGAModes)
+ xfree(cPtr->DGAModes);
+ pScrn->vtSema = FALSE;
+ if(cPtr->BlockHandler)
+ pScreen->BlockHandler = cPtr->BlockHandler;
+
+ pScreen->CloseScreen = cPtr->CloseScreen; /*§§§*/
+ xf86ClearPrimInitDone(pScrn->entityList[0]);
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);/*§§§*/
+}
+
+/* Optional */
+static void
+CHIPSFreeScreen(int scrnIndex, int flags)
+{
+ if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+ CHIPSFreeRec(xf86Screens[scrnIndex]);
+}
+
+/* Optional */
+static int
+CHIPSValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ if (flags & MODECHECK_FINAL) {
+ /* Don't subtract FrambufferSize here as it should be subtracted already */
+ if ((cPtr->Flags & ChipsOverlay8plus16)
+ && ((pScrn->videoRam<<10) - pScrn->displayWidth * 3 * pScrn->virtualY
+ < 0))
+ return MODE_MEM;
+ }
+ /* The tests here need to be expanded */
+ if ((mode->Flags & V_INTERLACE) && (cPtr->PanelType & ChipsLCD))
+ return MODE_NO_INTERLACE;
+ if ((cPtr->PanelType & ChipsLCD)
+ && ((cPtr->PanelSize.HDisplay < mode->HDisplay)
+ || (cPtr->PanelSize.VDisplay < mode->VDisplay)))
+ return MODE_PANEL;
+
+ return MODE_OK;
+}
+
+/*
+ * DPMS Control registers
+ *
+ * XR73 6554x and 64300 (what about 65535?)
+ * XR61 6555x
+ * 0 HSync Powerdown data
+ * 1 HSync Select 1=Powerdown
+ * 2 VSync Powerdown data
+ * 3 VSync Select 1=Powerdown
+ */
+
+static void
+chipsDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
+ int flags)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSEntPtr cPtrEnt;
+
+ unsigned char dpmsreg, seqreg, lcdoff, tmp;
+
+ if (!pScrn->vtSema)
+ return;
+
+ xf86EnableAccess(pScrn);
+ switch (PowerManagementMode) {
+ case DPMSModeOn:
+ /* Screen: On; HSync: On, VSync: On */
+ dpmsreg = 0x00;
+ seqreg = 0x00;
+ lcdoff = 0x0;
+ break;
+ case DPMSModeStandby:
+ /* Screen: Off; HSync: Off, VSync: On */
+ dpmsreg = 0x02;
+ seqreg = 0x20;
+ lcdoff = 0x0;
+ break;
+ case DPMSModeSuspend:
+ /* Screen: Off; HSync: On, VSync: Off */
+ dpmsreg = 0x08;
+ seqreg = 0x20;
+ lcdoff = 0x1;
+ break;
+ case DPMSModeOff:
+ /* Screen: Off; HSync: Off, VSync: Off */
+ dpmsreg = 0x0A;
+ seqreg = 0x20;
+ lcdoff = 0x1;
+ break;
+ default:
+ return;
+ }
+
+ if (cPtr->UseDualChannel) {
+ cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0],
+ CHIPSEntityIndex)->ptr;
+ DUALREOPEN;
+ }
+
+ seqreg |= hwp->readSeq(hwp, 0x01) & ~0x20;
+ hwp->writeSeq(hwp, 0x01, seqreg);
+ if (IS_HiQV(cPtr)) {
+ tmp = cPtr->readXR(cPtr, 0x61);
+ cPtr->writeXR(cPtr, 0x61, (tmp & 0xF0) | dpmsreg);
+ } else {
+ tmp = cPtr->readXR(cPtr, 0x73);
+ cPtr->writeXR(cPtr, 0x73, (tmp & 0xF0) | dpmsreg);
+ }
+
+ /* Turn off the flat panel */
+ if (cPtr->PanelType & ChipsLCDProbed) {
+ if (IS_HiQV(cPtr)) {
+ if (cPtr->Chipset == CHIPS_CT69030) {
+#if 0
+ /* Where is this for the 69030?? */
+ tmp = cPtr->readFR(cPtr, 0x05);
+ if (lcdoff)
+ cPtr->writeFR(cPtr, 0x05, tmp | 0x08);
+ else
+ cPtr->writeFR(cPtr, 0x05, tmp & 0xF7);
+#endif
+ } else {
+ tmp = cPtr->readFR(cPtr, 0x05);
+ if (lcdoff)
+ cPtr->writeFR(cPtr, 0x05, tmp | 0x08);
+ else
+ cPtr->writeFR(cPtr, 0x05, tmp & 0xF7);
+ }
+ } else {
+ tmp = cPtr->readXR(cPtr, 0x52);
+ if (lcdoff)
+ cPtr->writeXR(cPtr, 0x52, tmp | 0x08);
+ else
+ cPtr->writeXR(cPtr, 0x52, tmp & 0xF7);
+ }
+ }
+}
+
+static Bool
+CHIPSSaveScreen(ScreenPtr pScreen, int mode)
+{
+ ScrnInfoPtr pScrn = NULL; /* §§§ */
+ Bool unblank;
+
+ unblank = xf86IsUnblank(mode);
+
+ if (pScreen != NULL)
+ pScrn = xf86Screens[pScreen->myNum];
+
+ if (unblank)
+ SetTimeSinceLastInputEvent();
+
+ if ((pScrn != NULL) && pScrn->vtSema) { /* §§§ */
+ chipsBlankScreen(pScrn, unblank);
+ }
+ return (TRUE);
+}
+
+static Bool
+chipsClockSelect(ScrnInfoPtr pScrn, int no)
+{
+ CHIPSClockReg TmpClock;
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ switch (no) {
+ case CLK_REG_SAVE:
+ chipsClockSave(pScrn, &cPtr->SaveClock);
+ break;
+
+ case CLK_REG_RESTORE:
+ chipsClockLoad(pScrn, &cPtr->SaveClock);
+ break;
+
+ default:
+ if (!chipsClockFind(pScrn, no, &TmpClock))
+ return (FALSE);
+ chipsClockLoad(pScrn, &TmpClock);
+ }
+ return (TRUE);
+}
+
+/*
+ *
+ * Fout = (Fref * 4 * M) / (PSN * N * (1 << P) )
+ * Fvco = (Fref * 4 * M) / (PSN * N)
+ * where
+ * M = XR31+2
+ * N = XR32+2
+ * P = XR30[3:1]
+ * PSN = XR30[0]? 1:4
+ *
+ * constraints:
+ * 4 MHz <= Fref <= 20 MHz (typ. 14.31818 MHz)
+ * 150 kHz <= Fref/(PSN * N) <= 2 MHz
+ * 48 MHz <= Fvco <= 220 MHz
+ * 2 < M < 128
+ * 2 < N < 128
+ */
+
+static void
+chipsClockSave(ScrnInfoPtr pScrn, CHIPSClockPtr Clock)
+{
+ unsigned char tmp;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ unsigned char Type = cPtr->ClockType;
+ CHIPSEntPtr cPtrEnt;
+
+ Clock->msr = hwp->readMiscOut(hwp)&0xFE; /* save standard VGA clock reg */
+ switch (Type & GET_STYLE) {
+ case HiQV_STYLE:
+ /* save alternate clock select reg.*/
+ /* The 69030 FP clock select is at FR01 instead */
+ if (cPtr->UseDualChannel) {
+ cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0],
+ CHIPSEntityIndex)->ptr;
+ DUALREOPEN;
+ }
+
+ if (cPtr->Flags & ChipsDualChannelSupport)
+ Clock->fr03 = cPtr->readFR(cPtr, 0x01);
+ else
+ Clock->fr03 = cPtr->readFR(cPtr, 0x03);
+ if (!Clock->Clock) { /* save HiQV console clock */
+ tmp = cPtr->CRTclkInx << 2;
+ cPtr->CRTClk[0] = cPtr->readXR(cPtr, 0xC0 + tmp);
+ cPtr->CRTClk[1] = cPtr->readXR(cPtr, 0xC1 + tmp);
+ cPtr->CRTClk[2] = cPtr->readXR(cPtr, 0xC2 + tmp);
+ cPtr->CRTClk[3] = cPtr->readXR(cPtr, 0xC3 + tmp);
+ tmp = cPtr->FPclkInx << 2;
+ cPtr->FPClk[0] = cPtr->readXR(cPtr, 0xC0 + tmp);
+ cPtr->FPClk[1] = cPtr->readXR(cPtr, 0xC1 + tmp);
+ cPtr->FPClk[2] = cPtr->readXR(cPtr, 0xC2 + tmp);
+ cPtr->FPClk[3] = cPtr->readXR(cPtr, 0xC3 + tmp);
+ }
+ break;
+ case OLD_STYLE:
+ Clock->fcr = hwp->readFCR(hwp);
+ Clock->xr02 = cPtr->readXR(cPtr, 0x02);
+ Clock->xr54 = cPtr->readXR(cPtr, 0x54); /* save alternate clock select reg.*/
+ break;
+ case WINGINE_1_STYLE:
+ case WINGINE_2_STYLE:
+ break;
+ case NEW_STYLE:
+ Clock->xr54 = cPtr->readXR(cPtr, 0x54); /* save alternate clock select reg.*/
+ Clock->xr33 = cPtr->readXR(cPtr, 0x33); /* get status of MCLK/VCLK sel reg.*/
+ break;
+ }
+#ifdef DEBUG
+ ErrorF("saved \n");
+#endif
+}
+
+static Bool
+chipsClockFind(ScrnInfoPtr pScrn, int no, CHIPSClockPtr Clock)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ unsigned char Type = cPtr->ClockType;
+ CHIPSEntPtr cPtrEnt;
+
+ if (no > (pScrn->numClocks - 1))
+ return (FALSE);
+
+ if (cPtr->UseDualChannel) {
+ cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0],
+ CHIPSEntityIndex)->ptr;
+ DUALREOPEN;
+ }
+
+ switch (Type & GET_STYLE) {
+ case HiQV_STYLE:
+ Clock->msr = cPtr->CRTclkInx << 2;
+ Clock->fr03 = cPtr->FPclkInx << 2;
+ Clock->Clock = pScrn->currentMode->Clock;
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_USE_MODELINE, FALSE)) {
+ Clock->FPClock = pScrn->currentMode->Clock;
+ } else
+ Clock->FPClock = cPtr->FPclock;
+ break;
+ case NEW_STYLE:
+ if (Type & TYPE_HW) {
+ Clock->msr = (no == 4 ? 3 << 2: (no & 0x01) << 2);
+ Clock->xr54 = Clock->msr;
+ Clock->xr33 = no > 1 ? 0x80 : 0;
+ } else {
+ Clock->msr = 3 << 2;
+ Clock->xr33 = 0;
+ Clock->xr54 = Clock->msr;
+ /* update panel type in case somebody switched.
+ * This should be handled more generally:
+ * On mode switch DDC should be reread, all
+ * display dependent data should be reevaluated.
+ * This will be built in when we start Display
+ * HotPlug support.
+ * Until then we have to do it here as somebody
+ * might have switched displays on us and we only
+ * have one programmable clock which needs to
+ * be shared for CRT and LCD.
+ */
+ chipsSetPanelType(cPtr);
+ {
+ Bool fp_m;
+ if (cPtr->Options
+ && xf86GetOptValBool(cPtr->Options, OPTION_FP_MODE, &fp_m)) {
+ if (fp_m)
+ cPtr->PanelType |= ChipsLCD;
+ else
+ cPtr->PanelType = ~ChipsLCD;
+ }
+ }
+
+ if ((cPtr->PanelType & ChipsLCD) && cPtr->FPclock)
+ Clock->Clock = cPtr->FPclock;
+ else
+ Clock->Clock = pScrn->currentMode->SynthClock;
+ }
+ break;
+ case OLD_STYLE:
+ if (no > 3) {
+ Clock->msr = 3 << 2;
+ Clock->fcr = no & 0x03;
+ Clock->xr02 = 0;
+ Clock->xr54 = Clock->msr & (Clock->fcr << 4);
+ } else {
+ Clock->msr = (no << 2) & 0x4;
+ Clock->fcr = 0;
+ Clock->xr02 = no & 0x02;
+ Clock->xr54 = Clock->msr;
+ }
+ break;
+ case WINGINE_1_STYLE:
+ Clock->msr = no << 2;
+ case WINGINE_2_STYLE:
+ if (Type & TYPE_HW) {
+ Clock->msr = (no == 2 ? 3 << 2: (no & 0x01) << 2);
+ Clock->xr33 = 0;
+ } else {
+ Clock->msr = 3 << 2;
+ Clock->xr33 = 0;
+ Clock->Clock = pScrn->currentMode->SynthClock;
+ }
+ break;
+ }
+ Clock->msr |= (hwp->readMiscOut(hwp) & 0xF2);
+
+#ifdef DEBUG
+ ErrorF("found\n");
+#endif
+ return (TRUE);
+}
+
+
+static int
+chipsGetHWClock(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ unsigned char Type = cPtr->ClockType;
+ unsigned char tmp, tmp1;
+
+ if (!(Type & TYPE_HW))
+ return 0; /* shouldn't happen */
+
+ switch (Type & GET_STYLE) {
+ case WINGINE_1_STYLE:
+ return ((hwp->readMiscOut(hwp) & 0x0C) >> 2);
+ case WINGINE_2_STYLE:
+ tmp = ((hwp->readMiscOut(hwp) & 0x04) >> 2);
+ return (tmp > 2) ? 2 : tmp;
+ case OLD_STYLE:
+ if (!(cPtr->PanelType & ChipsLCDProbed))
+ tmp = hwp->readMiscOut(hwp);
+ else
+ tmp = cPtr->readXR(cPtr, 0x54);
+ if (tmp & 0x08) {
+ if (!(cPtr->PanelType & ChipsLCDProbed))
+ tmp = hwp->readFCR(hwp) & 0x03;
+ else
+ tmp = (tmp >> 4) & 0x03;
+ return (tmp + 4);
+ } else {
+ tmp = (tmp >> 2) & 0x01;
+ tmp1 = cPtr->readXR(cPtr, 0x02);
+ return (tmp + (tmp1 & 0x02));
+ }
+ case NEW_STYLE:
+ if (cPtr->PanelType & ChipsLCDProbed) {
+ tmp = cPtr->readXR(cPtr, 0x54);
+ } else
+ tmp = hwp->readMiscOut(hwp);
+ tmp = (tmp & 0x0C) >> 2;
+ if (tmp > 1) return 4;
+ tmp1 = cPtr->readXR(cPtr, 0x33);
+ tmp1 = (tmp1 & 0x80) >> 6; /* iso mode 25.175/28.322 or 32/36 MHz */
+ return (tmp + tmp1); /* ^=0 ^=1 ^=4 ^=5 */
+ default: /* we should never get here */
+ return (0);
+ }
+}
+
+static void
+chipsClockLoad(ScrnInfoPtr pScrn, CHIPSClockPtr Clock)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ unsigned char Type = cPtr->ClockType;
+ volatile unsigned char tmp, tmpmsr, tmpfcr, tmp02;
+ volatile unsigned char tmp33, tmp54, tmpf03;
+ unsigned char vclk[3];
+
+ tmpmsr = hwp->readMiscOut(hwp); /* read msr, needed for all styles */
+
+ switch (Type & GET_STYLE) {
+ case HiQV_STYLE:
+ /* save alternate clock select reg. */
+ /* The 69030 FP clock select is at FR01 instead */
+ if (cPtr->Flags & ChipsDualChannelSupport) {
+ tmpf03 = cPtr->readFR(cPtr, 0x01);
+ } else
+ tmpf03 = cPtr->readFR(cPtr, 0x03);
+ /* select fixed clock 0 before tampering with VCLK select */
+ hwp->writeMiscOut(hwp, (tmpmsr & ~0x0D) |
+ cPtr->SuspendHack.vgaIOBaseFlag);
+ /* The 69030 FP clock select is at FR01 instead */
+ if (cPtr->Flags & ChipsDualChannelSupport) {
+ cPtr->writeFR(cPtr, 0x01, (tmpf03 & ~0x0C) | 0x04);
+ } else
+ cPtr->writeFR(cPtr, 0x03, (tmpf03 & ~0x0C) | 0x04);
+ if (!Clock->Clock) { /* Hack to load saved console clock */
+ tmp = cPtr->CRTclkInx << 2;
+ cPtr->writeXR(cPtr, 0xC0 + tmp, (cPtr->CRTClk[0] & 0xFF));
+ cPtr->writeXR(cPtr, 0xC1 + tmp, (cPtr->CRTClk[1] & 0xFF));
+ cPtr->writeXR(cPtr, 0xC2 + tmp, (cPtr->CRTClk[2] & 0xFF));
+ cPtr->writeXR(cPtr, 0xC3 + tmp, (cPtr->CRTClk[3] & 0xFF));
+
+ if (cPtr->FPClkModified) {
+ usleep(10000); /* let VCO stabilize */
+ tmp = cPtr->FPclkInx << 2;
+ cPtr->writeXR(cPtr, 0xC0 + tmp, (cPtr->FPClk[0] & 0xFF));
+ cPtr->writeXR(cPtr, 0xC1 + tmp, (cPtr->FPClk[1] & 0xFF));
+ cPtr->writeXR(cPtr, 0xC2 + tmp, (cPtr->FPClk[2] & 0xFF));
+ cPtr->writeXR(cPtr, 0xC3 + tmp, (cPtr->FPClk[3] & 0xFF));
+ }
+ } else {
+ /*
+ * Don't use the extra 2 bits in the M, N registers available
+ * on the HiQV, so write zero to 0xCA
+ */
+ chipsCalcClock(pScrn, Clock->Clock, vclk);
+ tmp = cPtr->CRTclkInx << 2;
+ cPtr->writeXR(cPtr, 0xC0 + tmp, (vclk[1] & 0xFF));
+ cPtr->writeXR(cPtr, 0xC1 + tmp, (vclk[2] & 0xFF));
+ cPtr->writeXR(cPtr, 0xC2 + tmp, 0x0);
+ cPtr->writeXR(cPtr, 0xC3 + tmp, (vclk[0] & 0xFF));
+ if (Clock->FPClock) {
+ usleep(10000); /* let VCO stabilize */
+ chipsCalcClock(pScrn, Clock->FPClock, vclk);
+ tmp = cPtr->FPclkInx << 2;
+ cPtr->writeXR(cPtr, 0xC0 + tmp, (vclk[1] & 0xFF));
+ cPtr->writeXR(cPtr, 0xC1 + tmp, (vclk[2] & 0xFF));
+ cPtr->writeXR(cPtr, 0xC2 + tmp, 0x0);
+ cPtr->writeXR(cPtr, 0xC3 + tmp, (vclk[0] & 0xFF));
+ cPtr->FPClkModified = TRUE;
+ }
+ }
+ usleep(10000); /* Let VCO stabilise */
+ /* The 69030 FP clock select is at FR01 instead */
+ if (cPtr->Flags & ChipsDualChannelSupport) {
+ cPtr->writeFR(cPtr, 0x01, ((tmpf03 & ~0x0C) |
+ (Clock->fr03 & 0x0C)));
+ } else
+ cPtr->writeFR(cPtr, 0x03, ((tmpf03 & ~0x0C) |
+ (Clock->fr03 & 0x0C)));
+ break;
+ case WINGINE_1_STYLE:
+ break;
+ case WINGINE_2_STYLE:
+ /* Only write to soft clock registers if we really need to */
+ if ((Type & GET_TYPE) == TYPE_PROGRAMMABLE) {
+ /* select fixed clock 0 before tampering with VCLK select */
+ hwp->writeMiscOut(hwp, (tmpmsr & ~0x0D) |
+ cPtr->SuspendHack.vgaIOBaseFlag);
+ chipsCalcClock(pScrn, Clock->Clock, vclk);
+ tmp33 = cPtr->readXR(cPtr, 0x33); /* get status of MCLK/VCLK select reg */
+ cPtr->writeXR(cPtr, 0x33, tmp33 & ~0x20);
+ cPtr->writeXR(cPtr, 0x30, vclk[0]);
+ cPtr->writeXR(cPtr, 0x31, vclk[1]); /* restore VCLK regs. */
+ cPtr->writeXR(cPtr, 0x32, vclk[2]);
+ /* cPtr->writeXR(cPtr, 0x33, tmp33 & ~0x20);*/
+ usleep(10000); /* Let VCO stabilise */
+ }
+ break;
+ case OLD_STYLE:
+ tmp02 = cPtr->readXR(cPtr, 0x02);
+ tmp54 = cPtr->readXR(cPtr, 0x54);
+ tmpfcr = hwp->readFCR(hwp);
+ cPtr->writeXR(cPtr, 0x02, ((tmp02 & ~0x02) | (Clock->xr02 & 0x02)));
+ cPtr->writeXR(cPtr, 0x54, ((tmp54 & 0xF0) | (Clock->xr54 & ~0xF0)));
+ hwp->writeFCR(hwp, (tmpfcr & ~0x03) & Clock->fcr);
+ break;
+ case NEW_STYLE:
+ tmp33 = cPtr->readXR(cPtr, 0x33); /* get status of MCLK/VCLK select reg */
+ tmp54 = cPtr->readXR(cPtr, 0x54);
+ /* Only write to soft clock registers if we really need to */
+ if ((Type & GET_TYPE) == TYPE_PROGRAMMABLE) {
+ /* select fixed clock 0 before tampering with VCLK select */
+ hwp->writeMiscOut(hwp, (tmpmsr & ~0x0D) |
+ cPtr->SuspendHack.vgaIOBaseFlag);
+ cPtr->writeXR(cPtr, 0x54, (tmp54 & 0xF3));
+ /* if user wants to set the memory clock, do it first */
+ if (cPtr->MemClock.Clk) {
+ chipsCalcClock(pScrn, cPtr->MemClock.Clk, vclk);
+ /* close eyes, hold breath ....*/
+ cPtr->writeXR(cPtr, 0x33, tmp33 | 0x20);
+ cPtr->writeXR(cPtr, 0x30, vclk[0]);
+ cPtr->writeXR(cPtr, 0x31, vclk[1]);
+ cPtr->writeXR(cPtr, 0x32, vclk[2]);
+ usleep(10000);
+ }
+ chipsCalcClock(pScrn, Clock->Clock, vclk);
+ cPtr->writeXR(cPtr, 0x33, tmp33 & ~0x20);
+ cPtr->writeXR(cPtr, 0x30, vclk[0]);
+ cPtr->writeXR(cPtr, 0x31, vclk[1]); /* restore VCLK regs. */
+ cPtr->writeXR(cPtr, 0x32, vclk[2]);
+ /* cPtr->writeXR(cPtr, 0x33, tmp33 & ~0x20);*/
+ usleep(10000); /* Let VCO stabilise */
+ }
+ cPtr->writeXR(cPtr, 0x33, ((tmp33 & ~0x80) | (Clock->xr33 & 0x80)));
+ cPtr->writeXR(cPtr, 0x54, ((tmp54 & 0xF3) | (Clock->xr54 & ~0xF3)));
+ break;
+ }
+ hwp->writeMiscOut(hwp, (Clock->msr & 0xFE) |
+ cPtr->SuspendHack.vgaIOBaseFlag);
+#ifdef DEBUG
+ ErrorF("restored\n");
+#endif
+}
+
+/*
+ * This is Ken Raeburn's <raeburn@raeburn.org> clock
+ * calculation code just modified a little bit to fit in here.
+ */
+
+static void
+chipsCalcClock(ScrnInfoPtr pScrn, int Clock, unsigned char *vclk)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ int M, N, P = 0, PSN = 0, PSNx = 0;
+
+ int bestM = 0, bestN = 0, bestP = 0, bestPSN = 0;
+ double bestError, abest = 42, bestFout = 0;
+ double target;
+
+ double Fvco, Fout;
+ double error, aerror;
+
+ int M_min = 3;
+
+ /* Hack to deal with problem of Toshiba 720CDT clock */
+ int M_max = (IS_HiQV(cPtr) && cPtr->Chipset != CHIPS_CT69000 &&
+ cPtr->Chipset != CHIPS_CT69030) ? 63 : 127;
+
+ /* @@@ < CHIPS_CT690x0 ?? */
+
+ /* Other parameters available on the 65548 but not the 65545, and
+ * not documented in the Clock Synthesizer doc in rev 1.0 of the
+ * 65548 datasheet:
+ *
+ * + XR30[4] = 0, VCO divider loop uses divide by 4 (same as 65545)
+ * 1, VCO divider loop uses divide by 16
+ *
+ * + XR30[5] = 1, reference clock is divided by 5
+ *
+ * Other parameters available on the 65550 and not on the 65545
+ *
+ * + XRCB[2] = 0, VCO divider loop uses divide by 4 (same as 65545)
+ * 1, VCO divider loop uses divide by 16
+ *
+ * + XRCB[1] = 1, reference clock is divided by 5
+ *
+ * + XRCB[7] = Vclk = Mclk
+ *
+ * + XRCA[0:1] = 2 MSB of a 10 bit M-Divisor
+ *
+ * + XRCA[4:5] = 2 MSB of a 10 bit N-Divisor
+ *
+ * I haven't put in any support for those here. For simplicity,
+ * they should be set to 0 on the 65548, and left untouched on
+ * earlier chips.
+ *
+ * Other parameters available on the 690x0
+ *
+ * + The 690x0 has no reference clock divider, so PSN must
+ * always be 1.
+ * XRCB[0:1] are reserved according to the data book
+ */
+
+
+ target = Clock * 1000;
+
+ /* @@@ >= CHIPS_CT690x0 ?? */
+ for (PSNx = ((cPtr->Chipset == CHIPS_CT69000) ||
+ (cPtr->Chipset == CHIPS_CT69030)) ? 1 : 0; PSNx <= 1; PSNx++) {
+ int low_N, high_N;
+ double Fref4PSN;
+
+ PSN = PSNx ? 1 : 4;
+
+ low_N = 3;
+ high_N = 127;
+
+ while (Fref / (PSN * low_N) > (((cPtr->Chipset == CHIPS_CT69000) ||
+ (cPtr->Chipset == CHIPS_CT69030)) ? 5.0e6 : 2.0e6))
+ low_N++;
+ while (Fref / (PSN * high_N) < 150.0e3)
+ high_N--;
+
+ Fref4PSN = Fref * 4 / PSN;
+ for (N = low_N; N <= high_N; N++) {
+ double tmp = Fref4PSN / N;
+
+ /* @@@ < CHIPS_CT690x0 ?? */
+ for (P = (IS_HiQV(cPtr) && (cPtr->Chipset != CHIPS_CT69000) &&
+ (cPtr->Chipset != CHIPS_CT69030)) ? 1 : 0;
+ P <= 5; P++) {
+ /* to force post divisor on Toshiba 720CDT */
+ double Fvco_desired = target * (1 << P);
+ double M_desired = Fvco_desired / tmp;
+
+ /* Which way will M_desired be rounded? Do all three just to
+ * be safe. */
+ int M_low = M_desired - 1;
+ int M_hi = M_desired + 1;
+
+ if (M_hi < M_min || M_low > M_max)
+ continue;
+
+ if (M_low < M_min)
+ M_low = M_min;
+ if (M_hi > M_max)
+ M_hi = M_max;
+
+ for (M = M_low; M <= M_hi; M++) {
+ Fvco = tmp * M;
+ /* @@@ >= CHIPS_CT690x0 ?? */
+ if (Fvco <= ((cPtr->Chipset == CHIPS_CT69000 ||
+ cPtr->Chipset == CHIPS_CT69030) ? 100.0e6 : 48.0e6))
+ continue;
+ if (Fvco > 220.0e6)
+ break;
+
+ Fout = Fvco / (1 << P);
+
+ error = (target - Fout) / target;
+
+ aerror = (error < 0) ? -error : error;
+ if (aerror < abest) {
+ abest = aerror;
+ bestError = error;
+ bestM = M;
+ bestN = N;
+ bestP = P;
+ bestPSN = PSN;
+ bestFout = Fout;
+ }
+ }
+ }
+ }
+ }
+ /* @@@ >= CHIPS_CT690x0 ?? */
+ vclk[0] = (bestP << (IS_HiQV(cPtr) ? 4 : 1)) +
+ (((cPtr->Chipset == CHIPS_CT69000) || (cPtr->Chipset == CHIPS_CT69030))
+ ? 0 : (bestPSN == 1));
+ vclk[1] = bestM - 2;
+ vclk[2] = bestN - 2;
+#ifdef DEBUG
+ ErrorF("Freq. selected: %.2f MHz, vclk[0]=%X, vclk[1]=%X, vclk[2]=%X\n",
+ (float)(Clock / 1000.), vclk[0], vclk[1], vclk[2]);
+ ErrorF("Freq. set: %.2f MHz\n", bestFout / 1.0e6);
+#endif
+}
+
+static void
+chipsSave(ScrnInfoPtr pScrn, vgaRegPtr VgaSave, CHIPSRegPtr ChipsSave)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ int i;
+ unsigned char tmp;
+#ifdef DEBUG
+ ErrorF("chipsSave\n");
+#endif
+
+ /* set registers that we can program the controller */
+ /* bank 0 */
+ if (IS_HiQV(cPtr)) {
+ cPtr->writeXR(cPtr, 0x0E, 0x00);
+ } else {
+ cPtr->writeXR(cPtr, 0x10, 0x00);
+ cPtr->writeXR(cPtr, 0x11, 0x00);
+ tmp = cPtr->readXR(cPtr, 0x0C) & ~0x50; /* WINgine stores MSB here */
+ cPtr->writeXR(cPtr, 0x0C, tmp);
+ }
+ chipsFixResume(pScrn);
+ tmp = cPtr->readXR(cPtr, 0x02);
+ cPtr->writeXR(cPtr, 0x02, tmp & ~0x18);
+ /* get generic registers */
+ vgaHWSave(pScrn, VgaSave, VGA_SR_ALL);
+
+ /* save clock */
+ chipsClockSave(pScrn, &ChipsSave->Clock);
+
+ /* save extended registers */
+ if (IS_HiQV(cPtr)) {
+ for (i = 0; i < 0xFF; i++) {
+#ifdef SAR04
+ /* Save SAR04 multimedia register correctly */
+ if (i == 0x4F)
+ cPtr->writeXR(cPtr, 0x4E, 0x04);
+#endif
+ ChipsSave->XR[i] = cPtr->readXR(cPtr,i);
+#ifdef DEBUG
+ ErrorF("XS%X - %X\n", i, ChipsSave->XR[i]);
+#endif
+ }
+ for (i = 0; i < 0x80; i++) {
+ ChipsSave->FR[i] = cPtr->readFR(cPtr, i);
+#ifdef DEBUG
+ ErrorF("FS%X - %X\n", i, ChipsSave->FR[i]);
+#endif
+ }
+ for (i = 0; i < 0x80; i++) {
+ ChipsSave->MR[i] = cPtr->readMR(cPtr, i);
+#ifdef DEBUG
+ ErrorF("MS%X - %X\n", i, ChipsSave->FR[i]);
+#endif
+ }
+ /* Save CR0-CR40 even though we don't use them, so they can be
+ * printed */
+ for (i = 0x0; i < 0x80; i++) {
+ ChipsSave->CR[i] = hwp->readCrtc(hwp, i);
+#ifdef DEBUG
+ ErrorF("CS%X - %X\n", i, ChipsSave->CR[i]);
+#endif
+ }
+ } else {
+ for (i = 0; i < 0x7D; i++) { /* don't touch XR7D and XR7F on WINGINE */
+ ChipsSave->XR[i] = cPtr->readXR(cPtr, i);
+#ifdef DEBUG
+ ErrorF("XS%X - %X\n", i, ChipsSave->XR[i]);
+#endif
+ }
+ }
+}
+
+Bool
+chipsModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+#ifdef DEBUG
+ ErrorF("chipsModeInit\n");
+#endif
+#if 0
+ *(int*)0xFFFFFF0 = 0;
+ ErrorF("done\n");
+#endif
+
+ chipsUnlock(pScrn);
+ chipsFixResume(pScrn);
+
+ if (cPtr->Accel.UseHWCursor)
+ cPtr->Flags |= ChipsHWCursor;
+ else
+ cPtr->Flags &= ~ChipsHWCursor;
+ /*
+ * We need to delay cursor loading after resetting the video mode
+ * to give the engine a chance to recover.
+ */
+ cPtr->cursorDelay = TRUE;
+
+ if (IS_HiQV(cPtr))
+ return chipsModeInitHiQV(pScrn, mode);
+ else if (IS_Wingine(cPtr))
+ return chipsModeInitWingine(pScrn, mode);
+ else
+ return chipsModeInit655xx(pScrn, mode);
+}
+
+/*
+ * The timing register of the C&T FP chipsets are organized
+ * as follows:
+ * The chipsets have two sets of timing registers:
+ * the standard horizontal and vertical timing registers for
+ * display size, blank start, sync start, sync end, blank end
+ * and total size at their default VGA locations and extensions
+ * and the alternate horizontal and vertical timing registers for
+ * display size, sync start, sync end and total size.
+ * In LCD and mixed (LCD+CRT) mode the alternate timing registers
+ * control the timing. The alternate horizontal and vertical display
+ * size registers are set to the physical pixel size of the display.
+ * Normally the alternalte registers are set by the BIOS to optimized
+ * values.
+ * While the horizontal an vertical refresh rates are fixed independent
+ * of the visible display size to ensure optimal performace of both
+ * displays they can be adapted to the screen resolution and CRT
+ * requirements in CRT mode by programming the standard timing registers
+ * in the VGA fashion.
+ * In LCD and mixed mode the _standard_ horizontal and vertical display
+ * size registers control the size of the _visible_ part of the display
+ * in contast to the _physical_ size of the display which is specified
+ * by the _alternate_ horizontal and vertical display size registers.
+ * The size of the visible should always be equal or less than the
+ * physical size.
+ * For the 69030 chipsets, the CRT and LCD display channels are seperate
+ * and so can be driven independently.
+ */
+static Bool
+chipsModeInitHiQV(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ int i;
+ int lcdHTotal, lcdHDisplay;
+ int lcdVTotal, lcdVDisplay;
+ int lcdHRetraceStart, lcdHRetraceEnd;
+ int lcdVRetraceStart, lcdVRetraceEnd;
+ int lcdHSyncStart;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSRegPtr ChipsNew;
+ vgaRegPtr ChipsStd;
+ unsigned int tmp;
+
+ ChipsNew = &cPtr->ModeReg;
+ ChipsStd = &hwp->ModeReg;
+
+
+ /*
+ * Possibly fix up the panel size, if the manufacture is stupid
+ * enough to set it incorrectly in text modes
+ */
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_PANEL_SIZE, FALSE)) {
+ cPtr->PanelSize.HDisplay = mode->CrtcHDisplay;
+ cPtr->PanelSize.VDisplay = mode->CrtcVDisplay;
+ }
+
+ /* generic init */
+ if (!vgaHWInit(pScrn, mode)) {
+ ErrorF("bomb 1\n");
+ return (FALSE);
+ }
+ pScrn->vtSema = TRUE;
+
+ /* init clock */
+ if (!chipsClockFind(pScrn, mode->ClockIndex, &ChipsNew->Clock)) {
+ ErrorF("bomb 2\n");
+ return (FALSE);
+ }
+
+ /* Give Warning if the dual display mode will cause problems */
+ /* Note 64bit wide memory bus assumed (as in 69000 and 69030 */
+ if (cPtr->UseDualChannel && ((cPtr->SecondCrtc == TRUE) ||
+ (cPtr->Flags & ChipsDualRefresh))) {
+ if (((ChipsNew->Clock.FPClock + ChipsNew->Clock.Clock) *
+ (max(1, pScrn->bitsPerPixel >> 3) +
+ ((cPtr->FrameBufferSize && (cPtr->PanelType & ChipsLCD)) ?
+ 1 : 0)) / (8 * 0.7)) > cPtr->MemClock.Max) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Memory bandwidth requirements exceeded by dual-channel\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ " mode. Display might be corrupted!!!\n");
+ }
+ }
+
+ /* get C&T Specific Registers */
+ for (i = 0; i < 0xFF; i++) {
+#ifdef SAR04
+ /* Save SAR04 multimedia register correctly */
+ if (i == 0x4F)
+ cPtr->writeXR(cPtr, 0x4E, 0x04);
+#endif
+ ChipsNew->XR[i] = cPtr->readXR(cPtr, i);
+ }
+ for (i = 0; i < 0x80; i++) {
+ ChipsNew->FR[i] = cPtr->readFR(cPtr, i);
+ }
+ for (i = 0; i < 0x80; i++) {
+ ChipsNew->MR[i] = cPtr->readMR(cPtr, i);
+ }
+ for (i = 0x30; i < 0x80; i++) { /* These are the CT extended CRT regs */
+ ChipsNew->CR[i] = hwp->readCrtc(hwp, i);
+ }
+
+ /*
+ * Here all of the other fields of 'ChipsNew' get filled in, to
+ * handle the SVGA extended registers. It is also allowable
+ * to override generic registers whenever necessary.
+ */
+
+ /* some generic settings */
+ if (pScrn->depth == 1) {
+ ChipsStd->Attribute[0x10] = 0x03; /* mode */
+ } else {
+ ChipsStd->Attribute[0x10] = 0x01; /* mode */
+ }
+ if ((pScrn->bitsPerPixel == 16) && (cPtr->Flags & ChipsOverlay8plus16)) {
+ /* Make sure that the overlay isn't visible in the overscan region */
+ if (ChipsStd->Attribute[0x11] == pScrn->colorKey)
+ ChipsStd->Attribute[0x11] = pScrn->colorKey - 1;
+ } else
+ ChipsStd->Attribute[0x11] = 0x00; /* overscan (border) color */
+ ChipsStd->Attribute[0x12] = 0x0F; /* enable all color planes */
+ ChipsStd->Attribute[0x13] = 0x00; /* horiz pixel panning 0 */
+
+ ChipsStd->Graphics[0x05] = 0x00; /* normal read/write mode */
+
+ /* set virtual screen width */
+ tmp = pScrn->displayWidth >> 3;
+ if (pScrn->bitsPerPixel == 16) {
+ if (!(cPtr->Flags & ChipsOverlay8plus16))
+ tmp <<= 1; /* double the width of the buffer */
+ } else if (pScrn->bitsPerPixel == 24) {
+ tmp += tmp << 1;
+ } else if (pScrn->bitsPerPixel == 32) {
+ tmp <<= 2;
+ } else if (pScrn->bitsPerPixel < 8) {
+ tmp >>= 1;
+ }
+ ChipsStd->CRTC[0x13] = tmp & 0xFF;
+ ChipsNew->CR[0x41] = (tmp >> 8) & 0x0F;
+
+ /* Set paging mode on the HiQV32 architecture, if required */
+ if (!(cPtr->Flags & ChipsLinearSupport) || (pScrn->bitsPerPixel < 8))
+ ChipsNew->XR[0x0A] |= 0x1;
+
+ ChipsNew->XR[0x09] |= 0x1; /* Enable extended CRT registers */
+ ChipsNew->XR[0x0E] = 0; /* Single map */
+ ChipsNew->XR[0x40] |= 0x2; /* Don't wrap at 256kb */
+ ChipsNew->XR[0x81] &= 0xF8;
+ if (pScrn->bitsPerPixel >= 8) {
+ ChipsNew->XR[0x40] |= 0x1; /* High Resolution. XR40[1] reserved? */
+ ChipsNew->XR[0x81] |= 0x2; /* 256 Color Video */
+ }
+ ChipsNew->XR[0x80] |= 0x10; /* Enable cursor output on P0 and P1 */
+ if (pScrn->depth > 1) {
+ if (pScrn->rgbBits == 8)
+ ChipsNew->XR[0x80] |= 0x80;
+ else
+ ChipsNew->XR[0x80] &= ~0x80;
+ }
+
+ if (abs(cPtr->MemClock.Clk - cPtr->MemClock.ProbedClk) > 50) {
+ /* set mem clk */
+ ChipsNew->XR[0xCC] = cPtr->MemClock.xrCC;
+ ChipsNew->XR[0xCD] = cPtr->MemClock.xrCD;
+ ChipsNew->XR[0xCE] = cPtr->MemClock.xrCE;
+ }
+
+ /* Set the 69030 dual channel settings */
+ if (cPtr->Flags & ChipsDualChannelSupport) {
+ ChipsNew->FR[0x01] &= 0xFC;
+ if ((cPtr->SecondCrtc == FALSE) && (cPtr->PanelType & ChipsLCD))
+ ChipsNew->FR[0x01] |= 0x02;
+ else
+ ChipsNew->FR[0x01] |= 0x01;
+ ChipsNew->FR[0x02] &= 0xCC;
+ if ((cPtr->SecondCrtc == TRUE) || (cPtr->Flags & ChipsDualRefresh))
+ ChipsNew->FR[0x02] |= 0x01; /* Set DAC to pipe B */
+ else
+ ChipsNew->FR[0x02] &= 0xFE; /* Set DAC to pipe A */
+
+ if (cPtr->PanelType & ChipsLCD)
+ ChipsNew->FR[0x02] |= 0x20; /* Enable the LCD output */
+ if (cPtr->PanelType & ChipsCRT)
+ ChipsNew->FR[0x02] |= 0x10; /* Enable the CRT output */
+ }
+
+ /* linear specific */
+ if (cPtr->Flags & ChipsLinearSupport) {
+ ChipsNew->XR[0x0A] |= 0x02; /* Linear Addressing Mode */
+ ChipsNew->XR[0x20] = 0x0; /*BitBLT Draw Mode for 8 */
+ ChipsNew->XR[0x05] =
+ (unsigned char)((cPtr->FbAddress >> 16) & 0xFF);
+ ChipsNew->XR[0x06] =
+ (unsigned char)((cPtr->FbAddress >> 24) & 0xFF);
+ }
+
+ /* panel timing */
+ /* By default don't set panel timings, but allow it as an option */
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_USE_MODELINE, FALSE)) {
+ lcdHTotal = (mode->CrtcHTotal >> 3) - 5;
+ lcdHDisplay = (cPtr->PanelSize.HDisplay >> 3) - 1;
+ lcdHRetraceStart = (mode->CrtcHSyncStart >> 3);
+ lcdHRetraceEnd = (mode->CrtcHSyncEnd >> 3);
+ lcdHSyncStart = lcdHRetraceStart - 2;
+
+ lcdVTotal = mode->CrtcVTotal - 2;
+ lcdVDisplay = cPtr->PanelSize.VDisplay - 1;
+ lcdVRetraceStart = mode->CrtcVSyncStart;
+ lcdVRetraceEnd = mode->CrtcVSyncEnd;
+
+ ChipsNew->FR[0x20] = lcdHDisplay & 0xFF;
+ ChipsNew->FR[0x21] = lcdHRetraceStart & 0xFF;
+ ChipsNew->FR[0x25] = ((lcdHRetraceStart & 0xF00) >> 4) |
+ ((lcdHDisplay & 0xF00) >> 8);
+ ChipsNew->FR[0x22] = lcdHRetraceEnd & 0x1F;
+ ChipsNew->FR[0x23] = lcdHTotal & 0xFF;
+ ChipsNew->FR[0x24] = (lcdHSyncStart >> 3) & 0xFF;
+ ChipsNew->FR[0x26] = (ChipsNew->FR[0x26] & ~0x1F)
+ | ((lcdHTotal & 0xF00) >> 8)
+ | (((lcdHSyncStart >> 3) & 0x100) >> 4);
+ ChipsNew->FR[0x27] &= 0x7F;
+
+ ChipsNew->FR[0x30] = lcdVDisplay & 0xFF;
+ ChipsNew->FR[0x31] = lcdVRetraceStart & 0xFF;
+ ChipsNew->FR[0x35] = ((lcdVRetraceStart & 0xF00) >> 4)
+ | ((lcdVDisplay & 0xF00) >> 8);
+ ChipsNew->FR[0x32] = lcdVRetraceEnd & 0x0F;
+ ChipsNew->FR[0x33] = lcdVTotal & 0xFF;
+ ChipsNew->FR[0x34] = (lcdVTotal - lcdVRetraceStart) & 0xFF;
+ ChipsNew->FR[0x36] = ((lcdVTotal & 0xF00) >> 8) |
+ (((lcdVTotal - lcdVRetraceStart) & 0x700) >> 4);
+ ChipsNew->FR[0x37] |= 0x80;
+ }
+
+ /* Set up the extended CRT registers of the HiQV32 chips */
+ ChipsNew->CR[0x30] = ((mode->CrtcVTotal - 2) & 0xF00) >> 8;
+ ChipsNew->CR[0x31] = ((mode->CrtcVDisplay - 1) & 0xF00) >> 8;
+ ChipsNew->CR[0x32] = (mode->CrtcVSyncStart & 0xF00) >> 8;
+ ChipsNew->CR[0x33] = (mode->CrtcVBlankStart & 0xF00) >> 8;
+ if ((cPtr->Chipset == CHIPS_CT69000) || (cPtr->Chipset == CHIPS_CT69030)) {
+ /* The 690xx has overflow bits for the horizontal values as well */
+ ChipsNew->CR[0x38] = (((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8;
+#if 0
+ /* We need to redo the overscan voodoo from vgaHW.c */
+ ChipsStd->CRTC[3] = (ChipsStd->CRTC[3] & ~0x1F)
+ | (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F);
+ ChipsStd->CRTC[5] = (ChipsStd->CRTC[5] & ~0x80)
+ | ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2);
+ ChipsNew->CR[0x3C] = ((mode->CrtcHBlankEnd >> 3) - 1) & 0xC0;
+ if ((mode->CrtcHBlankEnd >> 3) == (mode->CrtcHTotal >> 3)) {
+ int i = (ChipsStd->CRTC[3] & 0x1F)
+ | ((ChipsStd->CRTC[5] & 0x80) >> 2)
+ | (ChipsNew->CR[0x3C] & 0xC0);
+ if ((i-- > (ChipsStd->CRTC[2])) &&
+ (mode->CrtcHBlankEnd == mode->CrtcHTotal))
+ i = 0;
+ ChipsStd->CRTC[3] = (ChipsStd->CRTC[3] & ~0x1F) | (i & 0x1F);
+ ChipsStd->CRTC[5] = (ChipsStd->CRTC[5] & ~0x80) | ((i << 2) &0x80);
+ ChipsNew->CR[0x3C] = (i & 0xC0);
+ }
+#else
+ ChipsNew->CR[0x3C] = vgaHWHBlankKGA(mode, ChipsStd, 8, 0) << 6;
+#endif
+ } else
+ vgaHWHBlankKGA(mode, ChipsStd, 6, 0);
+ vgaHWVBlankKGA(mode, ChipsStd, 8, 0);
+
+ ChipsNew->CR[0x40] |= 0x80;
+
+ /* centering/stretching */
+ if (!xf86ReturnOptValBool(cPtr->Options, OPTION_SUSPEND_HACK, FALSE)) {
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_LCD_STRETCH, FALSE) ||
+ (cPtr->Flags & ChipsOverlay8plus16)) {
+ ChipsNew->FR[0x40] &= 0xDF; /* Disable Horizontal stretching */
+ ChipsNew->FR[0x48] &= 0xFB; /* Disable vertical stretching */
+ ChipsNew->XR[0xA0] = 0x10; /* Disable cursor stretching */
+ } else {
+ ChipsNew->FR[0x40] |= 0x21; /* Enable Horizontal stretching */
+ ChipsNew->FR[0x48] |= 0x05; /* Enable vertical stretching */
+ ChipsNew->XR[0xA0] = 0x70; /* Enable cursor stretching */
+ if (cPtr->Accel.UseHWCursor
+ && cPtr->PanelSize.HDisplay && cPtr->PanelSize.VDisplay
+ && (cPtr->PanelSize.HDisplay != mode->CrtcHDisplay)
+ && (cPtr->PanelSize.VDisplay != mode->CrtcVDisplay)) {
+ if(cPtr->Accel.UseHWCursor)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Disabling HW Cursor on stretched LCD\n");
+ cPtr->Flags &= ~ChipsHWCursor;
+ }
+ }
+ }
+
+ if ((xf86ReturnOptValBool(cPtr->Options, OPTION_LCD_CENTER, FALSE))
+ || (cPtr->Flags & ChipsOverlay8plus16)) {
+ ChipsNew->FR[0x40] |= 0x3; /* Enable Horizontal centering */
+ ChipsNew->FR[0x48] |= 0x3; /* Enable Vertical centering */
+ } else {
+ ChipsNew->FR[0x40] &= 0xFD; /* Disable Horizontal centering */
+ ChipsNew->FR[0x48] &= 0xFD; /* Disable Vertical centering */
+ }
+
+ /* sync on green */
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_SYNC_ON_GREEN, FALSE))
+ ChipsNew->XR[0x82] |=0x02;
+
+ /* software mode flag */
+ ChipsNew->XR[0xE2] = chipsVideoMode(((cPtr->Flags & ChipsOverlay8plus16) ?
+ 8 : pScrn->depth), (cPtr->PanelType & ChipsLCD) ?
+ min(mode->CrtcHDisplay, cPtr->PanelSize.HDisplay) :
+ mode->CrtcHDisplay, mode->CrtcVDisplay);
+#ifdef DEBUG
+ ErrorF("VESA Mode: %Xh\n", ChipsNew->XR[0xE2]);
+#endif
+
+ /* sync. polarities */
+ if ((mode->Flags & (V_PHSYNC | V_NHSYNC))
+ && (mode->Flags & (V_PVSYNC | V_NVSYNC))) {
+ if (mode->Flags & (V_PHSYNC | V_NHSYNC)) {
+ if (mode->Flags & V_PHSYNC)
+ ChipsNew->FR[0x08] &= 0xBF; /* Alt. CRT Hsync positive */
+ else
+ ChipsNew->FR[0x08] |= 0x40; /* Alt. CRT Hsync negative */
+ }
+ if (mode->Flags & (V_PVSYNC | V_NVSYNC)) {
+ if (mode->Flags & V_PVSYNC)
+ ChipsNew->FR[0x08] &= 0x7F; /* Alt. CRT Vsync positive */
+ else
+ ChipsNew->FR[0x08] |= 0x80; /* Alt. CRT Vsync negative */
+ }
+ }
+ if (mode->Flags & (V_PCSYNC | V_NCSYNC)) {
+ ChipsNew->FR[0x0B] |= 0x20;
+ if (mode->Flags & V_PCSYNC) {
+ ChipsNew->FR[0x08] &= 0x7F; /* Alt. CRT Vsync positive */
+ ChipsNew->FR[0x08] &= 0xBF; /* Alt. CRT Hsync positive */
+ ChipsStd->MiscOutReg &= 0x7F;
+ ChipsStd->MiscOutReg &= 0xBF;
+ } else {
+ ChipsNew->FR[0x08] |= 0x80; /* Alt. CRT Vsync negative */
+ ChipsNew->FR[0x08] |= 0x40; /* Alt. CRT Hsync negative */
+ ChipsStd->MiscOutReg |= 0x40;
+ ChipsStd->MiscOutReg |= 0x80;
+ }
+ }
+ /* bpp depend */
+ if ((pScrn->bitsPerPixel == 16) && (!(cPtr->Flags & ChipsOverlay8plus16))) {
+ ChipsNew->XR[0x81] = (ChipsNew->XR[0x81] & 0xF0) | 0x4;
+ if (cPtr->Flags & ChipsGammaSupport)
+ ChipsNew->XR[0x82] |= 0x0C;
+ /* 16bpp = 5-5-5 */
+ ChipsNew->FR[0x10] |= 0x0C; /*Colour Panel */
+ ChipsNew->XR[0x20] = 0x10; /*BitBLT Draw Mode for 16 bpp */
+ if (pScrn->weight.green != 5)
+ ChipsNew->XR[0x81] |= 0x01; /*16bpp */
+ } else if (pScrn->bitsPerPixel == 24) {
+ ChipsNew->XR[0x81] = (ChipsNew->XR[0x81] & 0xF0) | 0x6;
+ if (cPtr->Flags & ChipsGammaSupport)
+ ChipsNew->XR[0x82] |= 0x0C;
+ /* 24bpp colour */
+ ChipsNew->XR[0x20] = 0x20; /*BitBLT Draw Mode for 24 bpp */
+ } else if (pScrn->bitsPerPixel == 32) {
+ ChipsNew->XR[0x81] = (ChipsNew->XR[0x81] & 0xF0) | 0x7;
+ if (cPtr->Flags & ChipsGammaSupport)
+ ChipsNew->XR[0x82] |= 0x0C;
+ /* 32bpp colour */
+ ChipsNew->XR[0x20] = 0x10; /*BitBLT Mode for 16bpp used at 32bpp */
+ }
+
+ /*CRT only */
+ if (!(cPtr->PanelType & ChipsLCD)) {
+ if (mode->Flags & V_INTERLACE) {
+ ChipsNew->CR[0x70] = 0x80 /* set interlace */
+ | (((((mode->CrtcHDisplay >> 3) - 1) >> 1) - 6) & 0x7F);
+ /*
+ ** Double VDisplay to get back the full screen value, otherwise
+ ** you only see half the picture.
+ */
+ mode->CrtcVDisplay = mode->VDisplay;
+ tmp = ChipsStd->CRTC[7] & ~0x42;
+ ChipsStd->CRTC[7] = (tmp |
+ ((((mode->CrtcVDisplay -1) & 0x100) >> 7 ) |
+ (((mode->CrtcVDisplay -1) & 0x200) >> 3 )));
+ ChipsStd->CRTC[0x12] = (mode->CrtcVDisplay -1) & 0xFF;
+ ChipsNew->CR[0x31] = ((mode->CrtcVDisplay - 1) & 0xF00) >> 8;
+ } else {
+ ChipsNew->CR[0x70] &= ~0x80; /* unset interlace */
+ }
+ }
+
+#if defined(__arm32__) && defined(__NetBSD__)
+ if (cPtr->TVMode != XMODE_RGB) {
+ /*
+ * Put the console into TV Out mode.
+ */
+ xf86SetTVOut(cPtr->TVMode);
+
+ ChipsNew->CR[0x72] = (mode->CrtcHTotal >> 1) >> 3;/* First horizontal
+ * serration pulse */
+ ChipsNew->CR[0x73] = mode->CrtcHTotal >> 3; /* Second pulse */
+ ChipsNew->CR[0x74] = (((mode->HSyncEnd - mode->HSyncStart) >> 3) - 1)
+ & 0x1F; /* equalization pulse */
+
+ if (cPtr->TVMode == XMODE_PAL || cPtr->TVMode == XMODE_SECAM) {
+ ChipsNew->CR[0x71] = 0xA0; /* PAL support with blanking delay */
+ } else {
+ ChipsNew->CR[0x71] = 0x20; /* NTSC support with blanking delay */
+ }
+ } else { /* XMODE_RGB */
+ /*
+ * Put the console into RGB Out mode.
+ */
+ xf86SetRGBOut();
+ }
+#endif
+
+ /* STN specific */
+ if (IS_STN(cPtr->PanelType)) {
+ ChipsNew->FR[0x11] &= ~0x03; /* FRC clear */
+ ChipsNew->FR[0x11] &= ~0x8C; /* Dither clear */
+ ChipsNew->FR[0x11] |= 0x01; /* 16 frame FRC */
+ ChipsNew->FR[0x11] |= 0x84; /* Dither */
+ if ((cPtr->Flags & ChipsTMEDSupport) &&
+ !xf86ReturnOptValBool(cPtr->Options, OPTION_NO_TMED, FALSE)) {
+ ChipsNew->FR[0x73] &= 0x4F; /* Clear TMED */
+ ChipsNew->FR[0x73] |= 0x80; /* Enable TMED */
+ ChipsNew->FR[0x73] |= 0x30; /* TMED 256 Shades of RGB */
+ }
+ if (cPtr->PanelType & ChipsDD) /* Shift Clock Mask. Use to get */
+ ChipsNew->FR[0x12] |= 0x4; /* rid of line in DSTN screens */
+ }
+
+ /*
+ * The zero position of the overlay does not align with the zero
+ * position of the display. The skew is dependent on the depth,
+ * display type and refresh rate. Calculate the skew before setting
+ * the X and Y dimensions of the overlay. These values are needed
+ * both by the overlay and XvImages. So calculate and store them
+ */
+ if (cPtr->PanelType & ChipsLCD) {
+ cPtr->OverlaySkewX = (((ChipsNew->FR[0x23] & 0xFF)
+ - (ChipsNew->FR[0x20] & 0xFF) + 3) << 3)
+ - 1;
+ cPtr->OverlaySkewY = (ChipsNew->FR[0x33]
+ + ((ChipsNew->FR[0x36] & 0xF) << 8)
+ - (ChipsNew->FR[0x31] & 0xF0)
+ - (ChipsNew->FR[0x32] & 0x0F)
+ - ((ChipsNew->FR[0x35] & 0xF0) << 4));
+ if (cPtr->PanelSize.HDisplay > mode->CrtcHDisplay)
+ cPtr->OverlaySkewX += (cPtr->PanelSize.HDisplay -
+ mode->CrtcHDisplay) / 2;
+ if (cPtr->PanelSize.VDisplay > mode->CrtcVDisplay)
+ cPtr->OverlaySkewY += (cPtr->PanelSize.VDisplay -
+ mode->CrtcVDisplay) / 2;
+ } else {
+ cPtr->OverlaySkewX = mode->CrtcHTotal - mode->CrtcHBlankStart - 9;
+ cPtr->OverlaySkewY = mode->CrtcVTotal - mode->CrtcVSyncEnd - 1;
+
+ if (mode->Flags & V_INTERLACE) {
+ /*
+ * This handles 1024 and 1280 interlaced modes only. Its
+ * pretty arbitrary, but its what C&T recommends
+ */
+ if (mode->CrtcHDisplay == 1024)
+ cPtr->OverlaySkewY += 5;
+ if (mode->CrtcHDisplay == 1280)
+ cPtr->OverlaySkewY *= 2;
+
+ }
+ }
+
+ /* mask for viewport granularity */
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ cPtr->viewportMask = ~7U;
+ break;
+ case 16:
+ cPtr->viewportMask = ~3U;
+ break;
+ case 24:
+ cPtr->viewportMask = ~7U;
+ break;
+ case 32:
+ cPtr->viewportMask = ~0U;
+ break;
+ default:
+ cPtr->viewportMask = ~7U;
+ }
+
+ /* Turn off multimedia by default as it degrades performance */
+ ChipsNew->XR[0xD0] &= 0x0f;
+
+ /* Setup the video/overlay */
+ if (cPtr->Flags & ChipsOverlay8plus16) {
+ ChipsNew->XR[0xD0] |= 0x10; /* Force the Multimedia engine on */
+#ifdef SAR04
+ ChipsNew->XR[0x4F] = 0x2A; /* SAR04 >352 pixel overlay width */
+#endif
+ ChipsNew->MR[0x1E] &= 0xE0; /* Set Zoom and Direction */
+ if ((!(cPtr->PanelType & ChipsLCD)) && (mode->Flags & V_INTERLACE))
+ ChipsNew->MR[0x1E] |= 0x10; /* Interlace */
+ ChipsNew->MR[0x1F] &= 0x14; /* Mask reserved bits */
+ ChipsNew->MR[0x1F] |= 0x08; /* RGB 16bpp */
+ if (pScrn->weight.green == 5)
+ ChipsNew->MR[0x1F] |= 0x01; /* RGB 15bpp */
+
+ ChipsNew->MR[0x20] &= 0x03; /* Mask reserved bits */
+ ChipsNew->MR[0x20] |= 0x80; /* Auto Centre, Use mem ptr1 */
+ ChipsNew->MR[0x22] = cPtr->FbOffset16 & 0xF8; /* Setup Pointer 1 */
+ ChipsNew->MR[0x23] = (cPtr->FbOffset16 >> 8) & 0xFF;
+ ChipsNew->MR[0x24] = (cPtr->FbOffset16 >> 16) & 0xFF;
+ ChipsNew->MR[0x25] = cPtr->FbOffset16 & 0xF8; /* Setup Pointer 2 */
+ ChipsNew->MR[0x26] = (cPtr->FbOffset16 >> 8) & 0xFF;
+ ChipsNew->MR[0x27] = (cPtr->FbOffset16 >> 16) & 0xFF;
+ ChipsNew->MR[0x28] = (pScrn->displayWidth >> 2) - 1; /* Width */
+ ChipsNew->MR[0x34] = (pScrn->displayWidth >> 2) - 1;
+
+ /* Left Edge of Overlay */
+ ChipsNew->MR[0x2A] = cPtr->OverlaySkewX;
+ ChipsNew->MR[0x2B] &= 0xF8; /* Mask reserved bits */
+ ChipsNew->MR[0x2B] |= ((cPtr->OverlaySkewX >> 8) & 0x7);
+ /* Right Edge of Overlay */
+ ChipsNew->MR[0x2C] = (cPtr->OverlaySkewX + pScrn->displayWidth -
+ 1) & 0xFF;
+ ChipsNew->MR[0x2D] &= 0xF8; /* Mask reserved bits */
+ ChipsNew->MR[0x2D] |= ((cPtr->OverlaySkewX + pScrn->displayWidth -
+ 1) >> 8) & 0x07;
+ /* Top Edge of Overlay */
+ ChipsNew->MR[0x2E] = cPtr->OverlaySkewY;
+ ChipsNew->MR[0x2F] &= 0xF8;
+ ChipsNew->MR[0x2F] |= ((cPtr->OverlaySkewY >> 8) & 0x7);
+ /* Bottom Edge of Overlay*/
+ ChipsNew->MR[0x30] = (cPtr->OverlaySkewY + pScrn->virtualY - 1 )& 0xFF;
+ ChipsNew->MR[0x31] &= 0xF8; /* Mask reserved bits */
+ ChipsNew->MR[0x31] |= ((cPtr->OverlaySkewY + pScrn->virtualY -
+ 1 ) >> 8) & 0x07;
+
+ ChipsNew->MR[0x3C] &= 0x18; /* Mask reserved bits */
+ ChipsNew->MR[0x3C] |= 0x07; /* Enable keyed overlay window */
+ ChipsNew->MR[0x3D] = 0x00;
+ ChipsNew->MR[0x3E] = 0x00;
+ ChipsNew->MR[0x3F] = pScrn->colorKey; /* 8bpp transparency key */
+ ChipsNew->MR[0x40] = 0xFF;
+ ChipsNew->MR[0x41] = 0xFF;
+ ChipsNew->MR[0x42] = 0x00;
+ } else if (cPtr->Flags & ChipsVideoSupport) {
+#if 0 /* if we do this even though video isn't playing we kill performance */
+ ChipsNew->XR[0xD0] |= 0x10; /* Force the Multimedia engine on */
+#endif
+#ifdef SAR04
+ ChipsNew->XR[0x4F] = 0x2A; /* SAR04 >352 pixel overlay width */
+#endif
+ ChipsNew->MR[0x3C] &= 0x18; /* Ensure that the overlay is off */
+ cPtr->VideoZoomMax = 0x100;
+
+ if (cPtr->Chipset == CHIPS_CT65550) {
+ tmp = cPtr->readXR(cPtr, 0x04);
+ if (tmp < 0x02) /* 65550 ES0 has */
+ cPtr->VideoZoomMax = 0x40; /* 0x40 max zoom */
+ }
+ }
+
+ /* Program the registers */
+ /*vgaHWProtect(pScrn, TRUE);*/
+
+ if (cPtr->Chipset <= CHIPS_CT69000) {
+ ChipsNew->FR[0x01] &= ~0x03;
+ if (cPtr->PanelType & ChipsLCD)
+ ChipsNew->FR[0x01] |= 0x02;
+ else
+ ChipsNew->FR[0x01] |= 0x01;
+ }
+ if ((cPtr->Flags & ChipsDualChannelSupport) &&
+ (!xf86IsEntityShared(pScrn->entityList[0]))) {
+ unsigned char IOSS, MSS, tmpfr01;
+
+
+ IOSS = cPtr->readIOSS(cPtr);
+ MSS = cPtr->readMSS(cPtr);
+ cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) |
+ IOSS_PIPE_A));
+ cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) |
+ MSS_PIPE_A));
+ chipsRestore(pScrn, ChipsStd, ChipsNew, FALSE);
+ cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) |
+ IOSS_PIPE_B));
+ cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) |
+ MSS_PIPE_B));
+ /*
+ * Hack:: Force Pipe-B on for dual refresh, and off elsewise
+ */
+ tmpfr01 = ChipsNew->FR[0x01];
+ ChipsNew->FR[0x01] &= 0xFC;
+ if (cPtr->UseDualChannel)
+ ChipsNew->FR[0x01] |= 0x01;
+ chipsRestore(pScrn, ChipsStd, ChipsNew, FALSE);
+ ChipsNew->FR[0x01] = tmpfr01;
+ cPtr->writeIOSS(cPtr, IOSS);
+ cPtr->writeMSS(cPtr, hwp, MSS);
+ } else {
+ chipsRestore(pScrn, ChipsStd, ChipsNew, FALSE);
+ }
+
+ /*vgaHWProtect(pScrn, FALSE);*/
+ usleep(100000); /* prevents cursor corruption seen on a TECRA 510 */
+
+ return(TRUE);
+}
+
+static Bool
+chipsModeInitWingine(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ int i, bytesPerPixel;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSRegPtr ChipsNew;
+ vgaRegPtr ChipsStd;
+ unsigned int tmp;
+
+ ChipsNew = &cPtr->ModeReg;
+ ChipsStd = &hwp->ModeReg;
+
+ bytesPerPixel = pScrn->bitsPerPixel >> 3;
+
+ /*
+ * This chipset seems to have problems if
+ * HBlankEnd is choosen equals HTotal
+ */
+ if (!mode->CrtcHAdjusted)
+ mode->CrtcHBlankEnd = min(mode->CrtcHSyncEnd, mode->CrtcHTotal - 2);
+
+ /* correct the timings for 16/24 bpp */
+ if (pScrn->bitsPerPixel == 16) {
+ if (!mode->CrtcHAdjusted) {
+ mode->CrtcHDisplay++;
+ mode->CrtcHDisplay <<= 1;
+ mode->CrtcHDisplay--;
+ mode->CrtcHSyncStart <<= 1;
+ mode->CrtcHSyncEnd <<= 1;
+ mode->CrtcHBlankStart <<= 1;
+ mode->CrtcHBlankEnd <<= 1;
+ mode->CrtcHTotal <<= 1;
+ mode->CrtcHAdjusted = TRUE;
+ }
+ } else if (pScrn->bitsPerPixel == 24) {
+ if (!mode->CrtcHAdjusted) {
+ mode->CrtcHDisplay++;
+ mode->CrtcHDisplay += ((mode->CrtcHDisplay) << 1);
+ mode->CrtcHDisplay--;
+ mode->CrtcHSyncStart += ((mode->CrtcHSyncStart) << 1);
+ mode->CrtcHSyncEnd += ((mode->CrtcHSyncEnd) << 1);
+ mode->CrtcHBlankStart += ((mode->CrtcHBlankStart) << 1);
+ mode->CrtcHBlankEnd += ((mode->CrtcHBlankEnd) << 1);
+ mode->CrtcHTotal += ((mode->CrtcHTotal) << 1);
+ mode->CrtcHAdjusted = TRUE;
+ }
+ }
+
+ /* generic init */
+ if (!vgaHWInit(pScrn, mode)) {
+ ErrorF("bomb 3\n");
+ return (FALSE);
+ }
+ pScrn->vtSema = TRUE;
+
+ /* init clock */
+ if (!chipsClockFind(pScrn, mode->ClockIndex, &ChipsNew->Clock)) {
+ ErrorF("bomb 4\n");
+ return (FALSE);
+ }
+
+ /* get C&T Specific Registers */
+ for (i = 0; i < 0x7D; i++) { /* don't touch XR7D and XR7F on WINGINE */
+ ChipsNew->XR[i] = cPtr->readXR(cPtr, i);
+ }
+
+ /* some generic settings */
+ if (pScrn->bitsPerPixel == 1) {
+ ChipsStd->Attribute[0x10] = 0x03; /* mode */
+ } else {
+ ChipsStd->Attribute[0x10] = 0x01; /* mode */
+ }
+ ChipsStd->Attribute[0x11] = 0x00; /* overscan (border) color */
+ ChipsStd->Attribute[0x12] = 0x0F; /* enable all color planes */
+ ChipsStd->Attribute[0x13] = 0x00; /* horiz pixel panning 0 */
+
+ ChipsStd->Graphics[0x05] = 0x00; /* normal read/write mode */
+
+
+ /* set virtual screen width */
+ if (pScrn->bitsPerPixel >= 8)
+ ChipsStd->CRTC[0x13] = (pScrn->displayWidth * bytesPerPixel) >> 3;
+ else
+ ChipsStd->CRTC[0x13] = pScrn->displayWidth >> 4;
+
+
+ /* set C&T Specific Registers */
+ /* set virtual screen width */
+ if (pScrn->bitsPerPixel >= 8)
+ tmp = (pScrn->displayWidth >> 4) * bytesPerPixel;
+ else
+ tmp = (pScrn->displayWidth >> 5);
+ ChipsNew->XR[0x0D] = (tmp & 0x80) >> 5;
+
+ ChipsNew->XR[0x04] |= 4; /* enable addr counter bits 16-17 */
+ /* XR04: Memory control 1 */
+ /* bit 2: Memory Wraparound */
+ /* Enable CRTC addr counter bits 16-17 if set */
+
+ ChipsNew->XR[0x0B] |= 0x07; /* extended mode, dual pages enabled */
+ ChipsNew->XR[0x0B] &= ~0x10; /* linear mode off */
+ /* XR0B: CPU paging */
+ /* bit 0: Memory mapping mode */
+ /* VGA compatible if 0 (default) */
+ /* Extended mode (mapping for > 256 kB mem) if 1 */
+ /* bit 1: CPU single/dual mapping */
+ /* 0, CPU uses only a single map to access (default) */
+ /* 1, CPU uses two maps to access */
+ /* bit 2: CPU address divide by 4 */
+
+ ChipsNew->XR[0x10] = 0; /* XR10: Single/low map */
+ ChipsNew->XR[0x11] = 0; /* XR11: High map */
+ ChipsNew->XR[0x0C] &= ~0x50; /* MSB for XR10 & XR11 */
+ if (pScrn->bitsPerPixel >= 8) {
+ ChipsNew->XR[0x28] |= 0x10; /* 256-color video */
+ } else {
+ ChipsNew->XR[0x28] &= 0xEF; /* 16-color video */
+ }
+ /* set up extended display timings */
+ /* in CRTonly mode this is simple: only set overflow for CR00-CR06 */
+ ChipsNew->XR[0x17] = ((((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8)
+ | ((((mode->CrtcHDisplay >> 3) - 1) & 0x100) >> 7)
+ | ((((mode->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6)
+ | ((((mode->CrtcHSyncEnd >> 3)) & 0x20) >> 2)
+ | ((((mode->CrtcHBlankStart >> 3) - 1) & 0x100) >> 4)
+ | ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x40) >> 1);
+
+
+ ChipsNew->XR[0x16] = (((mode->CrtcVTotal -2) & 0x400) >> 10 )
+ | (((mode->CrtcVDisplay -1) & 0x400) >> 9 )
+ | ((mode->CrtcVSyncStart & 0x400) >> 8 )
+ | (((mode->CrtcVBlankStart) & 0x400) >> 6 );
+
+ /* set video mode */
+ ChipsNew->XR[0x2B] = chipsVideoMode(pScrn->depth, mode->CrtcHDisplay, mode->CrtcVDisplay);
+#ifdef DEBUG
+ ErrorF("VESA Mode: %Xh\n", ChipsNew->XR[0x2B]);
+#endif
+
+ /* set some linear specific registers */
+ if (cPtr->Flags & ChipsLinearSupport) {
+ /* enable linear addressing */
+ ChipsNew->XR[0x0B] &= 0xFD; /* dual page clear */
+ ChipsNew->XR[0x0B] |= 0x10; /* linear mode on */
+
+ ChipsNew->XR[0x08] =
+ (unsigned char)((cPtr->FbAddress >> 16) & 0xFF);
+ ChipsNew->XR[0x09] =
+ (unsigned char)((cPtr->FbAddress >> 24) & 0xFF);
+
+ /* general setup */
+ ChipsNew->XR[0x40] = 0x01; /*BitBLT Draw Mode for 8 and 24 bpp */
+ }
+
+ /* common general setup */
+ ChipsNew->XR[0x52] |= 0x01; /* Refresh count */
+ ChipsNew->XR[0x0F] &= 0xEF; /* not Hi-/True-Colour */
+ ChipsNew->XR[0x02] &= 0xE7; /* Attr. Cont. default access */
+ /* use ext. regs. for hor. in dual */
+ ChipsNew->XR[0x06] &= 0xF3; /* bpp clear */
+
+ /* bpp depend */
+ /*XR06: Palette control */
+ /* bit 0: Pixel Data Pin Diag, 0 for flat panel pix. data (def) */
+ /* bit 1: Internal DAC disable */
+ /* bit 3-2: Colour depth, 0 for 4 or 8 bpp, 1 for 16(5-5-5) bpp, */
+ /* 2 for 24 bpp, 3 for 16(5-6-5)bpp */
+ /* bit 4: Enable PC Video Overlay on colour key */
+ /* bit 5: Bypass Internal VGA palette */
+ /* bit 7-6: Colour reduction select, 0 for NTSC (default), */
+ /* 1 for Equivalent weighting, 2 for green only, */
+ /* 3 for Colour w/o reduction */
+ /* XR50 Panel Format Register 1 */
+ /* bit 1-0: Frame Rate Control; 00, No FRC; */
+ /* 01, 16-frame FRC for colour STN and monochrome */
+ /* 10, 2-frame FRC for colour TFT or monochrome; */
+ /* 11, reserved */
+ /* bit 3-2: Dither Enable */
+ /* 00, disable dithering; 01, enable dithering */
+ /* for 256 mode */
+ /* 10, enable dithering for all modes; 11, reserved */
+ /* bit6-4: Clock Divide (CD) */
+ /* 000, Shift Clock Freq = Dot Clock Freq; */
+ /* 001, SClk = DClk/2; 010 SClk = DClk/4; */
+ /* 011, SClk = DClk/8; 100 SClk = DClk/16; */
+ /* bit 7: TFT data width */
+ /* 0, 16 bit(565RGB); 1, 24bit (888RGB) */
+ if (pScrn->bitsPerPixel == 16) {
+ ChipsNew->XR[0x06] |= 0xC4; /*15 or 16 bpp colour */
+ ChipsNew->XR[0x0F] |= 0x10; /*Hi-/True-Colour */
+ ChipsNew->XR[0x40] = 0x02; /*BitBLT Draw Mode for 16 bpp */
+ if (pScrn->weight.green != 5)
+ ChipsNew->XR[0x06] |= 0x08; /*16bpp */
+ } else if (pScrn->bitsPerPixel == 24) {
+ ChipsNew->XR[0x06] |= 0xC8; /*24 bpp colour */
+ ChipsNew->XR[0x0F] |= 0x10; /*Hi-/True-Colour */
+ }
+
+ /*CRT only: interlaced mode */
+ if (mode->Flags & V_INTERLACE) {
+ ChipsNew->XR[0x28] |= 0x20; /* set interlace */
+ /* empirical value */
+ tmp = ((((mode->CrtcHDisplay >> 3) - 1) >> 1)
+ - 6 * (pScrn->bitsPerPixel >= 8 ? bytesPerPixel : 1 ));
+ ChipsNew->XR[0x19] = tmp & 0xFF;
+ ChipsNew->XR[0x17] |= ((tmp & 0x100) >> 1); /* overflow */
+ ChipsNew->XR[0x0F] &= ~0x40; /* set SW-Flag */
+ } else {
+ ChipsNew->XR[0x28] &= ~0x20; /* unset interlace */
+ ChipsNew->XR[0x0F] |= 0x40; /* set SW-Flag */
+ }
+
+ /* Program the registers */
+ /*vgaHWProtect(pScrn, TRUE);*/
+ chipsRestore(pScrn, ChipsStd, ChipsNew, FALSE);
+ /*vgaHWProtect(pScrn, FALSE);*/
+
+ return (TRUE);
+}
+
+static Bool
+chipsModeInit655xx(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ int i, bytesPerPixel;
+ int lcdHTotal, lcdHDisplay;
+ int lcdVTotal, lcdVDisplay;
+ int lcdHRetraceStart, lcdHRetraceEnd;
+ int lcdVRetraceStart, lcdVRetraceEnd;
+ int HSyncStart, HDisplay;
+ int CrtcHDisplay;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSRegPtr ChipsNew;
+ vgaRegPtr ChipsStd;
+ unsigned int tmp;
+
+ ChipsNew = &cPtr->ModeReg;
+ ChipsStd = &hwp->ModeReg;
+
+ bytesPerPixel = pScrn->bitsPerPixel >> 3;
+
+ /*
+ * Possibly fix up the panel size, if the manufacture is stupid
+ * enough to set it incorrectly in text modes
+ */
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_PANEL_SIZE, FALSE)) {
+ cPtr->PanelSize.HDisplay = mode->CrtcHDisplay;
+ cPtr->PanelSize.VDisplay = mode->CrtcVDisplay;
+ }
+
+ /*
+ * This chipset seems to have problems if
+ * HBlankEnd is choosen equals HTotal
+ */
+ if (!mode->CrtcHAdjusted)
+ mode->CrtcHBlankEnd = min(mode->CrtcHSyncEnd, mode->CrtcHTotal - 2);
+
+ /* correct the timings for 16/24 bpp */
+ if (pScrn->bitsPerPixel == 16) {
+ if (!mode->CrtcHAdjusted) {
+ mode->CrtcHDisplay++;
+ mode->CrtcHDisplay <<= 1;
+ mode->CrtcHDisplay--;
+ mode->CrtcHSyncStart <<= 1;
+ mode->CrtcHSyncEnd <<= 1;
+ mode->CrtcHBlankStart <<= 1;
+ mode->CrtcHBlankEnd <<= 1;
+ mode->CrtcHTotal <<= 1;
+ mode->CrtcHAdjusted = TRUE;
+ }
+ } else if (pScrn->bitsPerPixel == 24) {
+ if (!mode->CrtcHAdjusted) {
+ mode->CrtcHDisplay++;
+ mode->CrtcHDisplay += ((mode->CrtcHDisplay) << 1);
+ mode->CrtcHDisplay--;
+ mode->CrtcHSyncStart += ((mode->CrtcHSyncStart) << 1);
+ mode->CrtcHSyncEnd += ((mode->CrtcHSyncEnd) << 1);
+ mode->CrtcHBlankStart += ((mode->CrtcHBlankStart) << 1);
+ mode->CrtcHBlankEnd += ((mode->CrtcHBlankEnd) << 1);
+ mode->CrtcHTotal += ((mode->CrtcHTotal) << 1);
+ mode->CrtcHAdjusted = TRUE;
+ }
+ }
+
+ /* store orig. HSyncStart needed for flat panel mode */
+ HSyncStart = mode->CrtcHSyncStart / (pScrn->bitsPerPixel >= 8 ?
+ bytesPerPixel : 1 ) - 16;
+ HDisplay = (mode->CrtcHDisplay + 1) / (pScrn->bitsPerPixel >= 8 ?
+ bytesPerPixel : 1 );
+
+ /* generic init */
+ if (!vgaHWInit(pScrn, mode)) {
+ ErrorF("bomb 5\n");
+ return (FALSE);
+ }
+ pScrn->vtSema = TRUE;
+
+ /* init clock */
+ if (!chipsClockFind(pScrn, mode->ClockIndex, &ChipsNew->Clock)) {
+ ErrorF("bomb 6\n");
+ return (FALSE);
+ }
+
+ /* get C&T Specific Registers */
+ for (i = 0; i < 0x80; i++) {
+ ChipsNew->XR[i] = cPtr->readXR(cPtr, i);
+ }
+
+ /* some generic settings */
+ if (pScrn->bitsPerPixel == 1) {
+ ChipsStd->Attribute[0x10] = 0x03; /* mode */
+ } else {
+ ChipsStd->Attribute[0x10] = 0x01; /* mode */
+ }
+ ChipsStd->Attribute[0x11] = 0x00; /* overscan (border) color */
+ ChipsStd->Attribute[0x12] = 0x0F; /* enable all color planes */
+ ChipsStd->Attribute[0x13] = 0x00; /* horiz pixel panning 0 */
+
+ ChipsStd->Graphics[0x05] = 0x00; /* normal read/write mode */
+
+ /* set virtual screen width */
+ if (pScrn->bitsPerPixel >= 8)
+ ChipsStd->CRTC[0x13] = (pScrn->displayWidth * bytesPerPixel) >> 3;
+ else
+ ChipsStd->CRTC[0x13] = pScrn->displayWidth >> 4;
+
+
+ /* set C&T Specific Registers */
+ /* set virtual screen width */
+ ChipsNew->XR[0x1E] = ChipsStd->CRTC[0x13]; /* alternate offset */
+ /*databook is not clear about 0x1E might be needed for 65520/30 */
+ if (pScrn->bitsPerPixel >= 8)
+ tmp = (pScrn->displayWidth * bytesPerPixel) >> 2;
+ else
+ tmp = pScrn->displayWidth >> 3;
+ ChipsNew->XR[0x0D] = (tmp & 0x01) | ((tmp << 1) & 0x02) ;
+
+ ChipsNew->XR[0x04] |= 4; /* enable addr counter bits 16-17 */
+ /* XR04: Memory control 1 */
+ /* bit 2: Memory Wraparound */
+ /* Enable CRTC addr counter bits 16-17 if set */
+
+ ChipsNew->XR[0x0B] |= 0x07; /* extended mode, dual pages enabled */
+ ChipsNew->XR[0x0B] &= ~0x10; /* linear mode off */
+ /* XR0B: CPU paging */
+ /* bit 0: Memory mapping mode */
+ /* VGA compatible if 0 (default) */
+ /* Extended mode (mapping for > 256 kB mem) if 1 */
+ /* bit 1: CPU single/dual mapping */
+ /* 0, CPU uses only a single map to access (default) */
+ /* 1, CPU uses two maps to access */
+ /* bit 2: CPU address divide by 4 */
+
+ ChipsNew->XR[0x10] = 0; /* XR10: Single/low map */
+ ChipsNew->XR[0x11] = 0; /* XR11: High map */
+ if (pScrn->bitsPerPixel >= 8) {
+ ChipsNew->XR[0x28] |= 0x10; /* 256-color video */
+ } else {
+ ChipsNew->XR[0x28] &= 0xEF; /* 16-color video */
+ }
+ /* set up extended display timings */
+ if (!(cPtr->PanelType & ChipsLCD)) {
+ /* in CRTonly mode this is simple: only set overflow for CR00-CR06 */
+ ChipsNew->XR[0x17] = ((((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8)
+ | ((((mode->CrtcHDisplay >> 3) - 1) & 0x100) >> 7)
+ | ((((mode->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6)
+ | ((((mode->CrtcHSyncEnd >> 3)) & 0x20) >> 2)
+ | ((((mode->CrtcHBlankStart >> 3) - 1) & 0x100) >> 4)
+ | ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x40) >> 1);
+
+ ChipsNew->XR[0x16] = (((mode->CrtcVTotal -2) & 0x400) >> 10 )
+ | (((mode->CrtcVDisplay -1) & 0x400) >> 9 )
+ | ((mode->CrtcVSyncStart & 0x400) >> 8 )
+ | (((mode->CrtcVBlankStart) & 0x400) >> 6 );
+ } else {
+ /* horizontal timing registers */
+ /* in LCD/dual mode use saved bios values to derive timing values if
+ * not told otherwise */
+ if (!xf86ReturnOptValBool(cPtr->Options, OPTION_USE_MODELINE, FALSE)) {
+ lcdHTotal = cPtr->PanelSize.HTotal;
+ lcdHRetraceStart = cPtr->PanelSize.HRetraceStart;
+ lcdHRetraceEnd = cPtr->PanelSize.HRetraceEnd;
+ if (pScrn->bitsPerPixel == 16) {
+ lcdHRetraceStart <<= 1;
+ lcdHRetraceEnd <<= 1;
+ lcdHTotal <<= 1;
+ } else if (pScrn->bitsPerPixel == 24) {
+ lcdHRetraceStart += (lcdHRetraceStart << 1);
+ lcdHRetraceEnd += (lcdHRetraceEnd << 1);
+ lcdHTotal += (lcdHTotal << 1);
+ }
+ lcdHRetraceStart -=8; /* HBlank = HRetrace - 1: for */
+ lcdHRetraceEnd -=8; /* compatibility with vgaHW.c */
+ } else {
+ /* use modeline values if bios values don't work */
+ lcdHTotal = mode->CrtcHTotal;
+ lcdHRetraceStart = mode->CrtcHSyncStart;
+ lcdHRetraceEnd = mode->CrtcHSyncEnd;
+ }
+ /* The chip takes the size of the visible display area from the
+ * CRTC values. We use bios screensize for LCD in LCD/dual mode
+ * wether or not we use modeline for LCD. This way we can specify
+ * always specify a smaller than default display size on LCD
+ * by writing it to the CRTC registers. */
+ lcdHDisplay = cPtr->PanelSize.HDisplay;
+ if (pScrn->bitsPerPixel == 16) {
+ lcdHDisplay++;
+ lcdHDisplay <<= 1;
+ lcdHDisplay--;
+ } else if (pScrn->bitsPerPixel == 24) {
+ lcdHDisplay++;
+ lcdHDisplay += (lcdHDisplay << 1);
+ lcdHDisplay--;
+ }
+ lcdHTotal = (lcdHTotal >> 3) - 5;
+ lcdHDisplay = (lcdHDisplay >> 3) - 1;
+ lcdHRetraceStart = (lcdHRetraceStart >> 3);
+ lcdHRetraceEnd = (lcdHRetraceEnd >> 3);
+ /* This ugly hack is needed because CR01 and XR1C share the 8th bit!*/
+ CrtcHDisplay = ((mode->CrtcHDisplay >> 3) - 1);
+ if ((lcdHDisplay & 0x100) != (CrtcHDisplay & 0x100)) {
+ xf86ErrorF("This display configuration might cause problems !\n");
+ lcdHDisplay = 255;
+ }
+
+ /* now init register values */
+ ChipsNew->XR[0x17] = (((lcdHTotal) & 0x100) >> 8)
+ | ((lcdHDisplay & 0x100) >> 7)
+ | ((lcdHRetraceStart & 0x100) >> 6)
+ | (((lcdHRetraceEnd) & 0x20) >> 2);
+
+ ChipsNew->XR[0x19] = lcdHRetraceStart & 0xFF;
+ ChipsNew->XR[0x1A] = lcdHRetraceEnd & 0x1F;
+
+ /* XR1B: Alternate horizontal total */
+ /* used in all flat panel mode with horiz. compression disabled, */
+ /* CRT CGA text and graphic modes and Hercules graphics mode */
+ /* similar to CR00, actual value - 5 */
+ ChipsNew->XR[0x1B] = lcdHTotal & 0xFF;
+
+ /*XR1C: Alternate horizontal blank start (CRT mode) */
+ /* /horizontal panel size (FP mode) */
+ /* FP horizontal panel size (FP mode), */
+ /* actual value - 1 (in characters unit) */
+ /* CRT horizontal blank start (CRT mode) */
+ /* similar to CR02, actual value - 1 */
+ ChipsNew->XR[0x1C] = lcdHDisplay & 0xFF;
+
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_USE_MODELINE, FALSE)) {
+ /* for ext. packed pixel mode on 64520/64530 */
+ /* no need to rescale: used only in 65530 */
+ ChipsNew->XR[0x21] = lcdHRetraceStart & 0xFF;
+ ChipsNew->XR[0x22] = lcdHRetraceEnd & 0x1F;
+ ChipsNew->XR[0x23] = lcdHTotal & 0xFF;
+
+ /* vertical timing registers */
+ lcdVTotal = mode->CrtcVTotal - 2;
+ lcdVDisplay = cPtr->PanelSize.VDisplay - 1;
+ lcdVRetraceStart = mode->CrtcVSyncStart;
+ lcdVRetraceEnd = mode->CrtcVSyncEnd;
+
+ ChipsNew->XR[0x64] = lcdVTotal & 0xFF;
+ ChipsNew->XR[0x66] = lcdVRetraceStart & 0xFF;
+ ChipsNew->XR[0x67] = lcdVRetraceEnd & 0x0F;
+ ChipsNew->XR[0x68] = lcdVDisplay & 0xFF;
+ ChipsNew->XR[0x65] = ((lcdVTotal & 0x100) >> 8)
+ | ((lcdVDisplay & 0x100) >> 7)
+ | ((lcdVRetraceStart & 0x100) >> 6)
+ | ((lcdVRetraceStart & 0x400) >> 7)
+ | ((lcdVTotal & 0x400) >> 6)
+ | ((lcdVTotal & 0x200) >> 4)
+ | ((lcdVDisplay & 0x200) >> 3)
+ | ((lcdVRetraceStart & 0x200) >> 2);
+
+ /*
+ * These are important: 0x2C specifies the numbers of lines
+ * (hsync pulses) between vertical blank start and vertical
+ * line total, 0x2D specifies the number of clock ticks? to
+ * horiz. blank start ( caution ! 16bpp/24bpp modes: that's
+ * why we need HSyncStart - can't use mode->CrtcHSyncStart)
+ */
+ tmp = ((cPtr->PanelType & ChipsDD) && !(ChipsNew->XR[0x6F] & 0x02))
+ ? 1 : 0; /* double LP delay, FLM: 2 lines iff DD+no acc*/
+ /* Currently we support 2 FLM schemes: #1: FLM coincides with
+ * VTotal ie. the delay is programmed to the difference bet-
+ * ween lctVTotal and lcdVRetraceStart. #2: FLM coincides
+ * lcdVRetraceStart - in this case FLM delay will be turned
+ * off. To decide which scheme to use we compare the value of
+ * XR2C set by the bios to the two schemes. The one that fits
+ * better will be used.
+ */
+
+ if (ChipsNew->XR[0x2C] < abs((cPtr->PanelSize.VTotal -
+ cPtr->PanelSize.VRetraceStart - tmp - 1) -
+ ChipsNew->XR[0x2C]))
+ ChipsNew->XR[0x2F] |= 0x80; /* turn FLM delay off */
+ ChipsNew->XR[0x2C] = lcdVTotal - lcdVRetraceStart - tmp;
+ /*ChipsNew->XR[0x2D] = (HSyncStart >> (3 - tmp)) & 0xFF;*/
+ ChipsNew->XR[0x2D] = (HDisplay >> (3 - tmp)) & 0xFF;
+ ChipsNew->XR[0x2F] = (ChipsNew->XR[0x2F] & 0xDF)
+ | (((HSyncStart >> (3 - tmp)) & 0x100) >> 3);
+ }
+
+ /* set stretching/centering */
+ if (!xf86ReturnOptValBool(cPtr->Options, OPTION_SUSPEND_HACK, FALSE)) {
+ ChipsNew->XR[0x51] |= 0x40; /* enable FP compensation */
+ ChipsNew->XR[0x55] |= 0x01; /* enable horiz. compensation */
+ ChipsNew->XR[0x57] |= 0x01; /* enable horiz. compensation */
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_LCD_STRETCH,
+ FALSE)) {
+ if (mode->CrtcHDisplay < 1489) /* HWBug */
+ ChipsNew->XR[0x55] |= 0x02; /* enable h-centering */
+ else if (pScrn->bitsPerPixel == 24)
+ ChipsNew->XR[0x56] = (lcdHDisplay - CrtcHDisplay) >> 1;
+ } else {
+ ChipsNew->XR[0x55] &= 0xFD; /* disable h-centering */
+ ChipsNew->XR[0x56] = 0;
+ }
+ ChipsNew->XR[0x57] = 0x03; /* enable v-comp disable v-stretch */
+ if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LCD_STRETCH,
+ FALSE)) {
+ ChipsNew->XR[0x55] |= 0x20; /* enable h-comp disable h-double*/
+ ChipsNew->XR[0x57] |= 0x60; /* Enable vertical stretching */
+ tmp = (mode->CrtcVDisplay / (cPtr->PanelSize.VDisplay -
+ mode->CrtcVDisplay + 1));
+ if (tmp) {
+ if (cPtr->PanelSize.HDisplay
+ && cPtr->PanelSize.VDisplay
+ && (cPtr->PanelSize.HDisplay != mode->CrtcHDisplay)
+ && (cPtr->PanelSize.VDisplay != mode->CrtcVDisplay)) {
+ /* Possible H/W bug? */
+ if(cPtr->Accel.UseHWCursor)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Disabling HW Cursor on stretched LCD\n");
+ cPtr->Flags &= ~ChipsHWCursor;
+ }
+ }
+ if (cPtr->Flags & ChipsHWCursor)
+ tmp = (tmp == 0 ? 1 : tmp); /* Bug when doubling */
+ ChipsNew->XR[0x5A] = tmp > 0x0F ? 0 : (unsigned char)tmp;
+ } else {
+ ChipsNew->XR[0x55] &= 0xDF; /* disable h-comp, h-double */
+ ChipsNew->XR[0x57] &= 0x9F; /* disable vertical stretching */
+ }
+ }
+ }
+
+ /* set video mode */
+ ChipsNew->XR[0x2B] = chipsVideoMode(pScrn->depth, (cPtr->PanelType & ChipsLCD) ?
+ min(HDisplay, cPtr->PanelSize.HDisplay) : HDisplay,cPtr->PanelSize.VDisplay);
+#ifdef DEBUG
+ ErrorF("VESA Mode: %Xh\n", ChipsNew->XR[0x2B]);
+#endif
+
+ /* set some linear specific registers */
+ if (cPtr->Flags & ChipsLinearSupport) {
+ /* enable linear addressing */
+ ChipsNew->XR[0x0B] &= 0xFD; /* dual page clear */
+ ChipsNew->XR[0x0B] |= 0x10; /* linear mode on */
+ if (cPtr->Chipset == CHIPS_CT65535)
+ ChipsNew->XR[0x08] = (unsigned char)(cPtr->FbAddress >> 17);
+ else if (cPtr->Chipset > CHIPS_CT65535)
+ ChipsNew->XR[0x08] = (unsigned char)(cPtr->FbAddress >> 20);
+ else {
+ /* Its probably set correctly by BIOS anyway. Leave it alone */
+ /* 65525 - 65530 require XR04[6] set for greater than 512k of */
+ /* ram. We only correct obvious bugs; VL probably uses MEMR/MEMW*/
+ if (cPtr->Bus == ChipsISA)
+ ChipsNew->XR[0x04] &= ~0x40; /* A19 sceme */
+ if (pScrn->videoRam > 512)
+ ChipsNew->XR[0x04] |= 0x40; /* MEMR/MEMW sceme */
+ }
+
+ /* general setup */
+ ChipsNew->XR[0x03] |= 0x08; /* High bandwidth on 65548 */
+ ChipsNew->XR[0x40] = 0x01; /*BitBLT Draw Mode for 8 and 24 bpp */
+ }
+
+ /* common general setup */
+ ChipsNew->XR[0x52] |= 0x01; /* Refresh count */
+ ChipsNew->XR[0x0F] &= 0xEF; /* not Hi-/True-Colour */
+ ChipsNew->XR[0x02] |= 0x01; /* 16bit CPU Memory Access */
+ ChipsNew->XR[0x02] &= 0xE3; /* Attr. Cont. default access */
+ /* use ext. regs. for hor. in dual */
+ ChipsNew->XR[0x06] &= 0xF3; /* bpp clear */
+
+ /* PCI */
+ if (cPtr->Bus == ChipsPCI)
+ ChipsNew->XR[0x03] |= 0x40; /*PCI burst */
+
+ /* sync. polarities */
+ if ((mode->Flags & (V_PHSYNC | V_NHSYNC))
+ && (mode->Flags & (V_PVSYNC | V_NVSYNC))) {
+ if (mode->Flags & (V_PHSYNC | V_NHSYNC)) {
+ if (mode->Flags & V_PHSYNC) {
+ ChipsNew->XR[0x55] &= 0xBF; /* CRT Hsync positive */
+ } else {
+ ChipsNew->XR[0x55] |= 0x40; /* CRT Hsync negative */
+ }
+ }
+ if (mode->Flags & (V_PVSYNC | V_NVSYNC)) {
+ if (mode->Flags & V_PVSYNC) {
+ ChipsNew->XR[0x55] &= 0x7F; /* CRT Vsync positive */
+ } else {
+ ChipsNew->XR[0x55] |= 0x80; /* CRT Vsync negative */
+ }
+ }
+ }
+
+ /* bpp depend */
+ /*XR06: Palette control */
+ /* bit 0: Pixel Data Pin Diag, 0 for flat panel pix. data (def) */
+ /* bit 1: Internal DAC disable */
+ /* bit 3-2: Colour depth, 0 for 4 or 8 bpp, 1 for 16(5-5-5) bpp, */
+ /* 2 for 24 bpp, 3 for 16(5-6-5)bpp */
+ /* bit 4: Enable PC Video Overlay on colour key */
+ /* bit 5: Bypass Internal VGA palette */
+ /* bit 7-6: Colour reduction select, 0 for NTSC (default), */
+ /* 1 for Equivalent weighting, 2 for green only, */
+ /* 3 for Colour w/o reduction */
+ /* XR50 Panel Format Register 1 */
+ /* bit 1-0: Frame Rate Control; 00, No FRC; */
+ /* 01, 16-frame FRC for colour STN and monochrome */
+ /* 10, 2-frame FRC for colour TFT or monochrome; */
+ /* 11, reserved */
+ /* bit 3-2: Dither Enable */
+ /* 00, disable dithering; 01, enable dithering */
+ /* for 256 mode */
+ /* 10, enable dithering for all modes; 11, reserved */
+ /* bit6-4: Clock Divide (CD) */
+ /* 000, Shift Clock Freq = Dot Clock Freq; */
+ /* 001, SClk = DClk/2; 010 SClk = DClk/4; */
+ /* 011, SClk = DClk/8; 100 SClk = DClk/16; */
+ /* bit 7: TFT data width */
+ /* 0, 16 bit(565RGB); 1, 24bit (888RGB) */
+ if (pScrn->bitsPerPixel == 16) {
+ ChipsNew->XR[0x06] |= 0xC4; /*15 or 16 bpp colour */
+ ChipsNew->XR[0x0F] |= 0x10; /*Hi-/True-Colour */
+ ChipsNew->XR[0x40] = 0x02; /*BitBLT Draw Mode for 16 bpp */
+ if (pScrn->weight.green != 5)
+ ChipsNew->XR[0x06] |= 0x08; /*16bpp */
+ } else if (pScrn->bitsPerPixel == 24) {
+ ChipsNew->XR[0x06] |= 0xC8; /*24 bpp colour */
+ ChipsNew->XR[0x0F] |= 0x10; /*Hi-/True-Colour */
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_18_BIT_BUS, FALSE)) {
+ ChipsNew->XR[0x50] &= 0x7F; /*18 bit TFT data width */
+ } else {
+ ChipsNew->XR[0x50] |= 0x80; /*24 bit TFT data width */
+ }
+ }
+
+ /*CRT only: interlaced mode */
+ if (!(cPtr->PanelType & ChipsLCD)) {
+ if (mode->Flags & V_INTERLACE){
+ ChipsNew->XR[0x28] |= 0x20; /* set interlace */
+ /* empirical value */
+ tmp = ((((mode->CrtcHDisplay >> 3) - 1) >> 1)
+ - 6 * (pScrn->bitsPerPixel >= 8 ? bytesPerPixel : 1 ));
+ if(cPtr->Chipset < CHIPS_CT65535)
+ ChipsNew->XR[0x19] = tmp & 0xFF;
+ else
+ ChipsNew->XR[0x29] = tmp & 0xFF;
+ ChipsNew->XR[0x0F] &= ~0x40; /* set SW-Flag */
+ } else {
+ ChipsNew->XR[0x28] &= ~0x20; /* unset interlace */
+ ChipsNew->XR[0x0F] |= 0x40; /* set SW-Flag */
+ }
+ }
+
+ /* STN specific */
+ if (IS_STN(cPtr->PanelType)) {
+ ChipsNew->XR[0x50] &= ~0x03; /* FRC clear */
+ ChipsNew->XR[0x50] |= 0x01; /* 16 frame FRC */
+ ChipsNew->XR[0x50] &= ~0x0C; /* Dither clear */
+ ChipsNew->XR[0x50] |= 0x08; /* Dither all modes */
+ if (cPtr->Chipset == CHIPS_CT65548) {
+ ChipsNew->XR[0x03] |= 0x20; /* CRT I/F priority */
+ ChipsNew->XR[0x04] |= 0x10; /* RAS precharge 65548 */
+ }
+ }
+
+ /* This stuff was emprically derived several years ago. Not sure its
+ * still needed, and I'd love to get rid of it as its ugly
+ */
+ switch (cPtr->Chipset) {
+ case CHIPS_CT65545: /*jet mini *//*DEC HighNote Ultra DSTN */
+ ChipsNew->XR[0x03] |= 0x10; /* do not hold off CPU for palette acc*/
+ break;
+ case CHIPS_CT65546: /*CT 65546, only for Toshiba */
+ ChipsNew->XR[0x05] |= 0x80; /* EDO RAM enable */
+ break;
+ }
+
+ if (cPtr->PanelType & ChipsLCD)
+ ChipsNew->XR[0x51] |= 0x02;
+ else
+ ChipsNew->XR[0x51] &= ~0x02;
+
+ /* Program the registers */
+ /*vgaHWProtect(pScrn, TRUE);*/
+ chipsRestore(pScrn, ChipsStd, ChipsNew, FALSE);
+ /*vgaHWProtect(pScrn, FALSE);*/
+
+ return (TRUE);
+}
+
+static void
+chipsRestore(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, CHIPSRegPtr ChipsReg,
+ Bool restoreFonts)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ unsigned char tmp = 0;
+
+ /*vgaHWProtect(pScrn, TRUE);*/
+
+ /* set registers so that we can program the controller */
+ if (IS_HiQV(cPtr)) {
+ cPtr->writeXR(cPtr, 0x0E, 0x00);
+ if (cPtr->Flags & ChipsDualChannelSupport) {
+ tmp = cPtr->readFR(cPtr, 0x01); /* Disable pipeline */
+ cPtr->writeFR(cPtr, 0x01, (tmp & 0xFC));
+ cPtr->writeFR(cPtr, 0x02, 0x00); /* CRT/FP off */
+ }
+ } else {
+ cPtr->writeXR(cPtr, 0x10, 0x00);
+ cPtr->writeXR(cPtr, 0x11, 0x00);
+ tmp = cPtr->readXR(cPtr, 0x0C) & ~0x50; /* WINgine stores MSB here */
+ cPtr->writeXR(cPtr, 0x0C, tmp);
+ cPtr->writeXR(cPtr, 0x15, 0x00); /* unprotect all registers */
+ tmp = cPtr->readXR(cPtr, 0x14);
+ cPtr->writeXR(cPtr, 0x14, tmp & ~0x20); /* enable vsync on ST01 */
+ }
+
+ chipsFixResume(pScrn);
+
+ /*
+ * Wait for vsync if sequencer is running - stop sequencer.
+ * Only do if sync reset is ignored. Dual pipeline capable
+ * chips have pipeline forced off here, so we don't care.
+ */
+ if ((cPtr->SyncResetIgn) && (!(cPtr->Flags & ChipsDualChannelSupport))) {
+ while (((hwp->readST01(hwp)) & 0x08) == 0x08); /* VSync off */
+ while (((hwp->readST01(hwp)) & 0x08) == 0x00); /* VSync on */
+ hwp->writeSeq(hwp, 0x07, 0x00); /* reset hsync - just in case... */
+ }
+
+ /* set the clock */
+ chipsClockLoad(pScrn, &ChipsReg->Clock);
+ /* chipsClockLoad() sets this so we don't want vgaHWRestore() change it */
+ VgaReg->MiscOutReg = inb(cPtr->PIOBase + 0x3CC);
+
+ /* set extended regs */
+ chipsRestoreExtendedRegs(pScrn, ChipsReg);
+#if 0
+ /* if people complain about lock ups or blank screens -- reenable */
+ /* set CRTC registers - do it before sequencer restarts */
+ for (i=0; i<25; i++)
+ hwp->writeCrtc(hwp, i, VgaReg->CRTC[i]);
+#endif
+ /* set generic registers */
+ /*
+ * Enabling writing to the colourmap causes 69030's to lock.
+ * Anyone care to explain to me why ????
+ */
+ if (cPtr->Flags & ChipsDualChannelSupport) {
+ /* Enable pipeline if needed */
+ cPtr->writeFR(cPtr, 0x01, ChipsReg->FR[0x01]);
+ cPtr->writeFR(cPtr, 0x02, ChipsReg->FR[0x02]);
+ vgaHWRestore(pScrn, VgaReg, VGA_SR_MODE |
+ (restoreFonts ? VGA_SR_FONTS : 0));
+ } else {
+ vgaHWRestore(pScrn, VgaReg, VGA_SR_MODE | VGA_SR_CMAP |
+ (restoreFonts ? VGA_SR_FONTS : 0));
+ }
+
+ /* set stretching registers */
+ if (IS_HiQV(cPtr)) {
+ chipsRestoreStretching(pScrn, (unsigned char)ChipsReg->FR[0x40],
+ (unsigned char)ChipsReg->FR[0x48]);
+#if 0
+ /* if people report about stretching not working -- reenable */
+ /* why twice ? :
+ * sometimes the console is not well restored even if these registers
+ * are good, re-write the registers works around it
+ */
+ chipsRestoreStretching(pScrn, (unsigned char)ChipsReg->FR[0x40],
+ (unsigned char)ChipsReg->FR[0x48]);
+#endif
+ } else if (!IS_Wingine(cPtr))
+ chipsRestoreStretching(pScrn, (unsigned char)ChipsReg->XR[0x55],
+ (unsigned char)ChipsReg->XR[0x57]);
+
+ /* perform a synchronous reset */
+ if (!cPtr->SyncResetIgn) {
+ if (!IS_HiQV(cPtr)) {
+ /* enable syncronous reset on 655xx */
+ tmp = cPtr->readXR(cPtr, 0x0E);
+ cPtr->writeXR(cPtr, 0x0E, tmp & 0x7F);
+ }
+ hwp->writeSeq(hwp, 0x00, 0x01);
+ usleep(10000);
+ hwp->writeSeq(hwp, 0x00, 0x03);
+ if (!IS_HiQV(cPtr))
+ cPtr->writeXR(cPtr, 0x0E, tmp);
+ }
+ /* Flag valid start address, if using CRT extensions */
+ if (IS_HiQV(cPtr) && (ChipsReg->XR[0x09] & 0x1) == 0x1) {
+ tmp = hwp->readCrtc(hwp, 0x40);
+ hwp->writeCrtc(hwp, 0x40, tmp | 0x80);
+ }
+
+ /* Fix resume again here, as Nozomi seems to need it */
+ chipsFixResume(pScrn);
+ /*vgaHWProtect(pScrn, FALSE);*/
+
+#if 0
+ /* Enable pipeline if needed */
+ if (cPtr->Flags & ChipsDualChannelSupport) {
+ cPtr->writeFR(cPtr, 0x01, ChipsReg->FR[0x01]);
+ cPtr->writeFR(cPtr, 0x02, ChipsReg->FR[0x02]);
+ }
+#endif
+}
+
+static void
+chipsRestoreExtendedRegs(ScrnInfoPtr pScrn, CHIPSRegPtr Regs)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ int i;
+ unsigned char tmp;
+
+ if (IS_HiQV(cPtr)) {
+ /* set extended regs */
+ for (i = 0; i < 0x43; i++) {
+ if ((cPtr->readXR(cPtr, i)) != Regs->XR[i])
+ cPtr->writeXR(cPtr, i, Regs->XR[i]);
+ }
+
+ /* Set SAR04 multimedia register correctly */
+ if ((cPtr->Flags & ChipsOverlay8plus16)
+ || (cPtr->Flags & ChipsVideoSupport)) {
+#ifdef SAR04
+ cPtr->writeXR(cPtr, 0x4E, 0x04);
+ if (cPtr->readXR(cPtr, 0x4F) != Regs->XR[0x4F])
+ cPtr->writeXR(cPtr, 0x4F, Regs->XR[0x4F]);
+#endif
+ }
+
+ /* Don't touch reserved memory control registers */
+ for (i = 0x50; i < 0xBF; i++) {
+ if ((cPtr->readXR(cPtr, i)) != Regs->XR[i])
+ cPtr->writeXR(cPtr, i, Regs->XR[i]);
+ }
+ /* Don't touch VCLK regs, but fix up MClk */
+
+ /* set mem clock */
+ tmp = cPtr->readXR(cPtr, 0xCE); /* Select Fixed MClk before */
+ cPtr->writeXR(cPtr, 0xCE, tmp & 0x7F);
+ if ((cPtr->readXR(cPtr, 0xCC)) != Regs->XR[0xCC])
+ cPtr->writeXR(cPtr, 0xCC, Regs->XR[0xCC]);
+ if ((cPtr->readXR(cPtr, 0xCD)) != Regs->XR[0xCD])
+ cPtr->writeXR(cPtr, 0xCD, Regs->XR[0xCD]);
+ if ((cPtr->readXR(cPtr, 0xCE)) != Regs->XR[0xCE])
+ cPtr->writeXR(cPtr, 0xCE, Regs->XR[0xCE]);
+
+ /* set flat panel regs. */
+ for (i = 0xD0; i < 0xFF; i++) {
+ if ((cPtr->readXR(cPtr, i)) != Regs->XR[i])
+ cPtr->writeXR(cPtr, i, Regs->XR[i]);
+ }
+
+ for (i = 0; i < 0x80; i++) {
+ /* Don't touch alternate clock select reg. */
+ if ((i == 0x01) && (cPtr->Chipset == CHIPS_CT69030)) {
+ /* restore the non clock bits */
+ tmp = cPtr->readFR(cPtr, 0x01);
+ cPtr->writeFR(cPtr, 0x01, ((Regs->FR[0x01] & 0xF0) |
+ (tmp & ~0xF0)));
+ continue;
+ }
+
+ if ((i == 0x02) && (cPtr->Chipset == CHIPS_CT69030))
+ /* keep pipeline disabled till we are ready */
+ continue;
+
+ if ((i == 0x03) && (cPtr->Chipset != CHIPS_CT69030)) {
+ /* restore the non clock bits */
+ tmp = cPtr->readFR(cPtr, 0x03);
+ cPtr->writeFR(cPtr, 0x03, ((Regs->FR[0x03] & 0xC3) |
+ (tmp & ~0xC3)));
+ continue;
+ }
+
+ if ((i > 0x03) && (cPtr->Chipset != CHIPS_CT69030) &&
+ (cPtr->SecondCrtc == TRUE))
+ continue;
+
+ if ( (i == 0x40) || (i==0x48)) {
+ /* !! set stretching but disable compensation */
+ cPtr->writeFR(cPtr, i, Regs->FR[i] & 0xFE);
+ continue ; /* some registers must be set before FR40/FR48 */
+ }
+ if ((cPtr->readFR(cPtr, i)) != Regs->FR[i]) {
+ cPtr->writeFR(cPtr, i, Regs->FR[i]);
+ }
+ }
+
+ /* set the multimedia regs */
+ for (i = 0x02; i < 0x80; i++) {
+ if ( (i == 0x43) || (i == 0x44))
+ continue;
+ if ((cPtr->readMR(cPtr, i)) != Regs->MR[i])
+ cPtr->writeMR(cPtr, i, Regs->MR[i]);
+ }
+
+ /* set extended crtc regs. */
+ for (i = 0x30; i < 0x80; i++) {
+ if ((hwp->readCrtc(hwp, i)) != Regs->CR[i])
+ hwp->writeCrtc(hwp, i, Regs->CR[i]);
+ }
+ } else {
+ /* set extended regs. */
+ for (i = 0; i < 0x30; i++) {
+ if ((cPtr->readXR(cPtr, i)) != Regs->XR[i])
+ cPtr->writeXR(cPtr, i, Regs->XR[i]);
+ }
+ cPtr->writeXR(cPtr, 0x15, 0x00); /* unprotect just in case ... */
+ /* Don't touch MCLK/VCLK regs. */
+ for (i = 0x34; i < 0x54; i++) {
+ if ((cPtr->readXR(cPtr, i)) != Regs->XR[i])
+ cPtr->writeXR(cPtr, i, Regs->XR[i]);
+ }
+ tmp = cPtr->readXR(cPtr, 0x54); /* restore the non clock bits */
+ cPtr->writeXR(cPtr, 0x54, ((Regs->XR[0x54] & 0xF3) | (tmp & ~0xF3)));
+ cPtr->writeXR(cPtr, 0x55, Regs->XR[0x55] & 0xFE); /* h-comp off */
+ cPtr->writeXR(cPtr, 0x56, Regs->XR[0x56]);
+ cPtr->writeXR(cPtr, 0x57, Regs->XR[0x57] & 0xFE); /* v-comp off */
+ for (i=0x58; i < 0x7D; i++) {/* don't touch XR7D and XR7F on WINGINE */
+ if ((cPtr->readXR(cPtr, i)) != Regs->XR[i])
+ cPtr->writeXR(cPtr, i, Regs->XR[i]);
+ }
+ }
+#ifdef DEBUG
+ /* debug - dump out all the extended registers... */
+ if (IS_HiQV(cPtr)) {
+ for (i = 0; i < 0xFF; i++) {
+ ErrorF("XR%X - %X : %X\n", i, Regs->XR[i],
+ cPtr->readXR(cPtr, i));
+ }
+ for (i = 0; i < 0x80; i++) {
+ ErrorF("FR%X - %X : %X\n", i, Regs->FR[i],
+ cPtr->readFR(cPtr, i));
+ }
+ } else {
+ for (i = 0; i < 0x80; i++) {
+ ErrorF("XR%X - %X : %X\n", i, Regs->XR[i],
+ cPtr->readXR(cPtr, i));
+ }
+ }
+#endif
+}
+
+static void
+chipsRestoreStretching(ScrnInfoPtr pScrn, unsigned char ctHorizontalStretch,
+ unsigned char ctVerticalStretch)
+{
+ unsigned char tmp;
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ /* write to regs. */
+ if (IS_HiQV(cPtr)) {
+ tmp = cPtr->readFR(cPtr, 0x48);
+ cPtr->writeFR(cPtr, 0x48, (tmp & 0xFE) | (ctVerticalStretch & 0x01));
+ tmp = cPtr->readFR(cPtr, 0x40);
+ cPtr->writeFR(cPtr, 0x40, (tmp & 0xFE) | (ctHorizontalStretch & 0x01));
+ } else {
+ tmp = cPtr->readXR(cPtr, 0x55);
+ cPtr->writeXR(cPtr, 0x55, (tmp & 0xFE) | (ctHorizontalStretch & 0x01));
+ tmp = cPtr->readXR(cPtr, 0x57);
+ cPtr->writeXR(cPtr, 0x57, (tmp & 0xFE) | (ctVerticalStretch & 0x01));
+ }
+
+ usleep(20000); /* to be active */
+}
+
+static int
+chipsVideoMode(int depth, int displayHSize,
+ int displayVSize)
+{
+ /* 4 bpp 8 bpp 16 bpp 18 bpp 24 bpp 32 bpp */
+ /* 640 0x20 0x30 0x40 - 0x50 - */
+ /* 800 0x22 0x32 0x42 - 0x52 - */
+ /*1024 0x24 0x34 0x44 - 0x54 - for 1024x768 */
+ /*1024 - 0x36 0x47 - 0x56 - for 1024x600 */
+ /*1152 0x27 0x37 0x47 - 0x57 - */
+ /*1280 0x28 0x38 0x49 - - - */
+ /*1600 0x2C 0x3C 0x4C 0x5D - - */
+ /*This value is only for BIOS.... */
+
+ int videoMode = 0;
+
+ switch (depth) {
+ case 1:
+ case 4:
+ videoMode = 0x20;
+ break;
+ case 8:
+ videoMode = 0x30;
+ break;
+ case 15:
+ videoMode = 0x40;
+ break;
+ case 16:
+ videoMode = 0x41;
+ break;
+ default:
+ videoMode = 0x50;
+ break;
+ }
+
+ switch (displayHSize) {
+ case 800:
+ videoMode |= 0x02;
+ break;
+ case 1024:
+ videoMode |= 0x04;
+ if(displayVSize < 768)
+ videoMode |= 0x02;
+ break;
+ case 1152:
+ videoMode |= 0x07;
+ break;
+ case 1280:
+ videoMode |= 0x08;
+ break;
+ case 1600:
+ videoMode |= 0x0C; /*0x0A??*/
+ break;
+ }
+
+ return videoMode;
+}
+
+
+/*
+ * Map the framebuffer and MMIO memory.
+ */
+
+static Bool
+chipsMapMem(ScrnInfoPtr pScrn)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSEntPtr cPtrEnt;
+
+ if (cPtr->Flags & ChipsLinearSupport) {
+ if (cPtr->UseMMIO) {
+ if (IS_HiQV(cPtr)) {
+ if (cPtr->Bus == ChipsPCI)
+ cPtr->MMIOBase = xf86MapPciMem(pScrn->scrnIndex,
+ VIDMEM_MMIO_32BIT,cPtr->PciTag, cPtr->IOAddress,
+ 0x20000L);
+ else
+ cPtr->MMIOBase = xf86MapVidMem(pScrn->scrnIndex,
+ VIDMEM_MMIO_32BIT, cPtr->IOAddress, 0x20000L);
+ } else {
+ if (cPtr->Bus == ChipsPCI)
+ cPtr->MMIOBase = xf86MapPciMem(pScrn->scrnIndex,
+ VIDMEM_MMIO_32BIT, cPtr->PciTag, cPtr->IOAddress,
+ 0x10000L);
+ else
+ cPtr->MMIOBase = xf86MapVidMem(pScrn->scrnIndex,
+ VIDMEM_MMIO_32BIT, cPtr->IOAddress, 0x10000L);
+ }
+
+ if (cPtr->MMIOBase == NULL)
+ return FALSE;
+ }
+ if (cPtr->FbMapSize) {
+ unsigned long Addr = (unsigned long)cPtr->FbAddress;
+ unsigned int Map = cPtr->FbMapSize;
+
+ if ((cPtr->Flags & ChipsDualChannelSupport) &&
+ (xf86IsEntityShared(pScrn->entityList[0]))) {
+ cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0],
+ CHIPSEntityIndex)->ptr;
+ if(cPtr->SecondCrtc == FALSE) {
+ Addr = cPtrEnt->masterFbAddress;
+ Map = cPtrEnt->masterFbMapSize;
+ } else {
+ Addr = cPtrEnt->slaveFbAddress;
+ Map = cPtrEnt->slaveFbMapSize;
+ }
+ }
+
+ if (cPtr->Bus == ChipsPCI)
+ cPtr->FbBase = xf86MapPciMem(pScrn->scrnIndex,VIDMEM_FRAMEBUFFER,
+ cPtr->PciTag, Addr, Map);
+
+ else
+ cPtr->FbBase = xf86MapVidMem(pScrn->scrnIndex,VIDMEM_FRAMEBUFFER,
+ Addr, Map);
+
+ if (cPtr->FbBase == NULL)
+ return FALSE;
+ }
+ if (cPtr->Flags & ChipsFullMMIOSupport) {
+ cPtr->MMIOBaseVGA = xf86MapPciMem(pScrn->scrnIndex,
+ VIDMEM_MMIO,cPtr->PciTag,
+ cPtr->IOAddress, 0x2000L);
+ /* 69030 MMIO Fix.
+ *
+ * The hardware lets us map the PipeB data registers
+ * into the MMIO address space normally occupied by PipeA,
+ * but it doesn't allow remapping of the index registers.
+ * So we're forced to map a separate MMIO space for each
+ * pipe and to toggle between them as necessary. -GHB
+ */
+ if (cPtr->Flags & ChipsDualChannelSupport)
+ cPtr->MMIOBasePipeB = xf86MapPciMem(pScrn->scrnIndex,
+ VIDMEM_MMIO,cPtr->PciTag,
+ cPtr->IOAddress + 0x800000, 0x2000L);
+
+ cPtr->MMIOBasePipeA = cPtr->MMIOBaseVGA;
+ }
+ } else {
+ /* In paged mode Base is the VGA window at 0xA0000 */
+ cPtr->FbBase = hwp->Base;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Unmap the framebuffer and MMIO memory.
+ */
+
+static Bool
+chipsUnmapMem(ScrnInfoPtr pScrn)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ if (cPtr->Flags & ChipsLinearSupport) {
+ if (IS_HiQV(cPtr)) {
+ if (cPtr->MMIOBase)
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)cPtr->MMIOBase,
+ 0x20000);
+ if (cPtr->MMIOBasePipeB)
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)cPtr->MMIOBasePipeB,
+ 0x20000);
+ cPtr->MMIOBasePipeB = NULL;
+ } else {
+ if (cPtr->MMIOBase)
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)cPtr->MMIOBase,
+ 0x10000);
+ }
+ cPtr->MMIOBase = NULL;
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)cPtr->FbBase,
+ cPtr->FbMapSize);
+ }
+ cPtr->FbBase = NULL;
+
+ return TRUE;
+}
+
+static void
+chipsProtect(ScrnInfoPtr pScrn, Bool on)
+{
+ vgaHWProtect(pScrn, on);
+}
+
+static void
+chipsBlankScreen(ScrnInfoPtr pScrn, Bool unblank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ unsigned char scrn;
+ CHIPSEntPtr cPtrEnt;
+
+ if (cPtr->UseDualChannel) {
+ cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0],
+ CHIPSEntityIndex)->ptr;
+ DUALREOPEN;
+ }
+
+ /* fix things that could be messed up by suspend/resume */
+ if (!IS_HiQV(cPtr))
+ cPtr->writeXR(cPtr, 0x15, 0x00);
+
+ scrn = hwp->readSeq(hwp, 0x01);
+
+ if (unblank) {
+ scrn &= 0xDF; /* enable screen */
+ } else {
+ scrn |= 0x20; /* blank screen */
+ }
+
+ /* synchronous reset - stop counters */
+ if (!cPtr->SyncResetIgn) {
+ hwp->writeSeq(hwp, 0x00, 0x01);
+ }
+
+ hwp->writeSeq(hwp, 0x01, scrn); /* change mode */
+
+ /* end reset - start counters */
+ if (!cPtr->SyncResetIgn) {
+ hwp->writeSeq(hwp, 0x00, 0x03);
+ }
+
+ if ((cPtr->UseDualChannel) &&
+ (! xf86IsEntityShared(pScrn->entityList[0]))) {
+ unsigned int IOSS, MSS;
+ IOSS = cPtr->readIOSS(cPtr);
+ MSS = cPtr->readMSS(cPtr);
+ cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) |
+ IOSS_PIPE_B));
+ cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | MSS_PIPE_B));
+
+ /* fix things that could be messed up by suspend/resume */
+ if (!IS_HiQV(cPtr))
+ cPtr->writeXR(cPtr, 0x15, 0x00);
+
+ scrn = hwp->readSeq(hwp, 0x01);
+
+ if (unblank) {
+ scrn &= 0xDF; /* enable screen */
+ } else {
+ scrn |= 0x20; /* blank screen */
+ }
+
+ /* synchronous reset - stop counters */
+ if (!cPtr->SyncResetIgn) {
+ hwp->writeSeq(hwp, 0x00, 0x01);
+ }
+
+ hwp->writeSeq(hwp, 0x01, scrn); /* change mode */
+
+ /* end reset - start counters */
+ if (!cPtr->SyncResetIgn) {
+ hwp->writeSeq(hwp, 0x00, 0x03);
+ }
+
+ cPtr->writeIOSS(cPtr, IOSS);
+ cPtr->writeMSS(cPtr, hwp, MSS);
+ }
+
+}
+
+static void
+chipsLock(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ unsigned char tmp;
+
+ vgaHWLock(hwp);
+
+ if (!IS_HiQV(cPtr)) {
+ /* group protection attribute controller access */
+ cPtr->writeXR(cPtr, 0x15, cPtr->SuspendHack.xr15);
+ tmp = cPtr->readXR(cPtr, 0x02);
+ cPtr->writeXR(cPtr, 0x02, (tmp & ~0x18) | cPtr->SuspendHack.xr02);
+ tmp = cPtr->readXR(cPtr, 0x14);
+ cPtr->writeXR(cPtr, 0x14, (tmp & ~0x20) | cPtr->SuspendHack.xr14);
+
+ /* reset 32 bit register access */
+ if (cPtr->Chipset > CHIPS_CT65540) {
+ tmp = cPtr->readXR(cPtr, 0x03);
+ cPtr->writeXR(cPtr, 0x03, (tmp & ~0x0A) | cPtr->SuspendHack.xr03);
+ }
+ }
+}
+
+static void
+chipsUnlock(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ unsigned char tmp;
+
+ if (!IS_HiQV(cPtr)) {
+ /* group protection attribute controller access */
+ cPtr->writeXR(cPtr, 0x15, 0x00);
+ tmp = cPtr->readXR(cPtr, 0x02);
+ cPtr->writeXR(cPtr, 0x02, (tmp & ~0x18));
+ tmp = cPtr->readXR(cPtr, 0x14);
+ cPtr->writeXR(cPtr, 0x14, (tmp & ~0x20));
+ /* enable 32 bit register access */
+ if (cPtr->Chipset > CHIPS_CT65540) {
+ cPtr->writeXR(cPtr, 0x03, cPtr->SuspendHack.xr03 | 0x0A);
+ }
+ }
+ vgaHWUnlock(hwp);
+}
+
+static void
+chipsHWCursorOn(CHIPSPtr cPtr, ScrnInfoPtr pScrn)
+{
+ /* enable HW cursor */
+ if (cPtr->HWCursorShown) {
+ if (IS_HiQV(cPtr)) {
+ cPtr->writeXR(cPtr, 0xA0, cPtr->HWCursorContents & 0xFF);
+ if (cPtr->UseDualChannel &&
+ (! xf86IsEntityShared(pScrn->entityList[0]))) {
+ unsigned int IOSS, MSS;
+ IOSS = cPtr->readIOSS(cPtr);
+ MSS = cPtr->readMSS(cPtr);
+ cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) |
+ IOSS_PIPE_B));
+ cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), ((cPtr->storeMSS &
+ MSS_MASK) | MSS_PIPE_B));
+ cPtr->writeXR(cPtr, 0xA0, cPtr->HWCursorContents & 0xFF);
+ cPtr->writeIOSS(cPtr, IOSS);
+ cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), MSS);
+ }
+ } else {
+ HW_DEBUG(0x8);
+ if (cPtr->UseMMIO) {
+ MMIOmeml(DR(0x8)) = cPtr->HWCursorContents;
+ } else {
+ outl(cPtr->PIOBase + DR(0x8), cPtr->HWCursorContents);
+ }
+ }
+ }
+}
+
+static void
+chipsHWCursorOff(CHIPSPtr cPtr, ScrnInfoPtr pScrn)
+{
+ /* disable HW cursor */
+ if (cPtr->HWCursorShown) {
+ if (IS_HiQV(cPtr)) {
+ cPtr->HWCursorContents = cPtr->readXR(cPtr, 0xA0);
+ cPtr->writeXR(cPtr, 0xA0, cPtr->HWCursorContents & 0xF8);
+ } else {
+ HW_DEBUG(0x8);
+ if (cPtr->UseMMIO) {
+ cPtr->HWCursorContents = MMIOmeml(DR(0x8));
+ /* Below used to be MMIOmemw() change back if problem!!! */
+ /* Also see ct_cursor.c */
+ MMIOmeml(DR(0x8)) = cPtr->HWCursorContents & 0xFFFE;
+ } else {
+ cPtr->HWCursorContents = inl(cPtr->PIOBase + DR(0x8));
+ outw(cPtr->PIOBase + DR(0x8), cPtr->HWCursorContents & 0xFFFE);
+ }
+ }
+ }
+}
+
+void
+chipsFixResume(ScrnInfoPtr pScrn)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ unsigned char tmp;
+
+ /* fix things that could be messed up by suspend/resume */
+ if (!IS_HiQV(cPtr))
+ cPtr->writeXR(cPtr, 0x15, 0x00);
+ tmp = hwp->readMiscOut(hwp);
+ hwp->writeMiscOut(hwp, (tmp & 0xFE) | cPtr->SuspendHack.vgaIOBaseFlag);
+ tmp = hwp->readCrtc(hwp, 0x11);
+ hwp->writeCrtc(hwp, 0x11, (tmp & 0x7F));
+}
+
+static char
+chipsTestDACComp(ScrnInfoPtr pScrn, unsigned char a, unsigned char b,
+ unsigned char c)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ unsigned char type;
+
+ hwp->writeDacWriteAddr(hwp, 0x00);
+ while ((hwp->readST01(hwp)) & 0x08){}; /* wait for vsync to end */
+ while (!(hwp->readST01(hwp)) & 0x08){}; /* wait for new vsync */
+ hwp->writeDacData(hwp, a); /* set pattern */
+ hwp->writeDacData(hwp, b);
+ hwp->writeDacData(hwp, c);
+ while (!(hwp->readST01(hwp)) & 0x01){}; /* wait for hsync to end */
+ while ((hwp->readST01(hwp)) & 0x01){}; /* wait for hsync to end */
+ type = hwp->readST00(hwp); /* read comparator */
+ return (type & 0x10);
+}
+
+static int
+chipsProbeMonitor(ScrnInfoPtr pScrn)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ unsigned char dacmask;
+ unsigned char dacdata[3];
+ unsigned char xr1, xr2;
+ int type = 2; /* no monitor */
+ unsigned char IOSS=0, MSS=0, tmpfr02=0, tmpfr01a=0, tmpfr01b=0;
+
+ /* Dual channel display, enable both pipelines */
+ if (cPtr->Flags & ChipsDualChannelSupport) {
+ IOSS = cPtr->readIOSS(cPtr);
+ MSS = cPtr->readMSS(cPtr);
+ tmpfr02 = cPtr->readFR(cPtr,0x02);
+ cPtr->writeFR(cPtr, 0x02, (tmpfr02 & 0xCF)); /* CRT/FP off */
+ usleep(1000);
+ cPtr->writeIOSS(cPtr, ((IOSS & IOSS_MASK) | IOSS_PIPE_A));
+ cPtr->writeMSS(cPtr, hwp, ((MSS & MSS_MASK) | MSS_PIPE_A));
+ tmpfr01a = cPtr->readFR(cPtr,0x01);
+ if ((tmpfr01a & 0x3) != 0x01)
+ cPtr->writeFR(cPtr, 0x01, ((tmpfr01a & 0xFC) | 0x1));
+ cPtr->writeIOSS(cPtr, ((IOSS & IOSS_MASK) | IOSS_PIPE_B));
+ cPtr->writeMSS(cPtr, hwp, ((MSS & MSS_MASK) | MSS_PIPE_B));
+ tmpfr01b = cPtr->readFR(cPtr,0x01);
+ if ((tmpfr01b & 0x3) != 0x01)
+ cPtr->writeFR(cPtr, 0x01, ((tmpfr01b & 0xFC) | 0x1));
+ cPtr->writeIOSS(cPtr, IOSS);
+ cPtr->writeMSS(cPtr, hwp, MSS);
+ cPtr->writeFR(cPtr, 0x02, (tmpfr02 & 0xCF) | 0x10); /* CRT on/FP off*/
+ }
+
+ dacmask = hwp->readDacMask(hwp); /* save registers */
+ hwp->writeDacMask(hwp, 0x00);
+ hwp->writeDacReadAddr(hwp, 0x00);
+
+ dacdata[0]=hwp->readDacData(hwp);
+ dacdata[1]=hwp->readDacData(hwp);
+ dacdata[2]=hwp->readDacData(hwp);
+
+ if (!IS_HiQV(cPtr)) {
+ xr1 = cPtr->readXR(cPtr, 0x06);
+ xr2 = cPtr->readXR(cPtr, 0x1F);
+ cPtr->writeXR(cPtr, 0x06, xr1 & 0xF1); /* turn on dac */
+ cPtr->writeXR(cPtr, 0x1F, xr2 & 0x7F); /* enable comp */
+ } else {
+ xr1 = cPtr->readXR(cPtr, 0x81);
+ xr2 = cPtr->readXR(cPtr, 0xD0);
+ cPtr->writeXR(cPtr, 0x81,(xr1 & 0xF0));
+ cPtr->writeXR(cPtr, 0xD0,(xr2 | 0x03));
+ }
+ if (chipsTestDACComp(pScrn, 0x12,0x12,0x12)) { /* test patterns */
+ if (chipsTestDACComp(pScrn,0x14,0x14,0x14)) /* taken from */
+ if (!chipsTestDACComp(pScrn,0x2D,0x14,0x14)) /* BIOS */
+ if (!chipsTestDACComp(pScrn,0x14,0x2D,0x14))
+ if (!chipsTestDACComp(pScrn,0x14,0x14,0x2D))
+ if (!chipsTestDACComp(pScrn,0x2D,0x2D,0x2D))
+ type = 0; /* color monitor */
+ } else {
+ if (chipsTestDACComp(pScrn,0x04,0x12,0x04))
+ if (!chipsTestDACComp(pScrn,0x1E,0x12,0x04))
+ if (!chipsTestDACComp(pScrn,0x04,0x2D,0x04))
+ if (!chipsTestDACComp(pScrn,0x1E,0x16,0x15))
+ if (chipsTestDACComp(pScrn,0x00,0x00,0x00))
+ type = 1; /* monochrome */
+ }
+
+ hwp->writeDacWriteAddr(hwp, 0x00); /* restore registers */
+ hwp->writeDacData(hwp, dacdata[0]);
+ hwp->writeDacData(hwp, dacdata[1]);
+ hwp->writeDacData(hwp, dacdata[2]);
+ hwp->writeDacMask(hwp, dacmask);
+ if (!IS_HiQV(cPtr)) {
+ cPtr->writeXR(cPtr,0x06,xr1);
+ cPtr->writeXR(cPtr,0x1F,xr2);
+ } else {
+ cPtr->writeXR(cPtr,0x81,xr1);
+ cPtr->writeXR(cPtr,0xD0,xr2);
+ }
+
+ if (cPtr->Flags & ChipsDualChannelSupport) {
+ cPtr->writeIOSS(cPtr, ((IOSS & IOSS_MASK) | IOSS_PIPE_A));
+ cPtr->writeMSS(cPtr, hwp, ((MSS & MSS_MASK) | MSS_PIPE_A));
+ cPtr->writeFR(cPtr, 0x01, tmpfr01a);
+ cPtr->writeIOSS(cPtr, ((IOSS & IOSS_MASK) | IOSS_PIPE_B));
+ cPtr->writeMSS(cPtr, hwp, ((MSS & MSS_MASK) | MSS_PIPE_B));
+ cPtr->writeFR(cPtr, 0x01, tmpfr01b);
+ usleep(1000);
+ cPtr->writeIOSS(cPtr, IOSS);
+ cPtr->writeMSS(cPtr, hwp, MSS);
+ cPtr->writeFR(cPtr, 0x02, tmpfr02);
+ }
+
+ return type;
+}
+
+static int
+chipsSetMonitor(ScrnInfoPtr pScrn)
+{
+ int tmp= chipsProbeMonitor(pScrn);
+
+ switch (tmp) {
+ case 0:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Color monitor detected\n");
+ break;
+ case 1:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Monochrome monitor detected\n");
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "No monitor detected\n");
+ }
+ return (tmp);
+}
+
+static void
+chipsSetPanelType(CHIPSPtr cPtr)
+{
+ CARD8 tmp;
+
+ if (IS_HiQV(cPtr)) {
+ if (cPtr->Chipset == CHIPS_CT69030) {
+ tmp = cPtr->readFR(cPtr, 0x00);
+ if (tmp & 0x20) {
+ /* FR02: DISPLAY TYPE REGISTER */
+ /* FR02[4] = CRT, FR02[5] = FlatPanel */
+ tmp = cPtr->readFR(cPtr, 0x02);
+ if (tmp & 0x10)
+ cPtr->PanelType |= ChipsCRT;
+ if (tmp & 0x20)
+ cPtr->PanelType |= ChipsLCD | ChipsLCDProbed;
+ } else {
+ cPtr->PanelType |= ChipsCRT;
+ }
+ } else {
+ /* test LCD */
+ /* FR01: DISPLAY TYPE REGISTER */
+ /* FR01[1:0]: Display Type, 01 = CRT, 10 = FlatPanel */
+ /* LCD */
+ tmp = cPtr->readFR(cPtr, 0x01);
+ if ((tmp & 0x03) == 0x02) {
+ cPtr->PanelType |= ChipsLCD;
+ }
+ tmp = cPtr->readXR(cPtr,0xD0);
+ if (tmp & 0x01) {
+ cPtr->PanelType |= ChipsCRT;
+ }
+ }
+ } else {
+ tmp = cPtr->readXR(cPtr, 0x51);
+ /* test LCD */
+ /* XR51: DISPLAY TYPE REGISTER */
+ /* XR51[2]: Display Type, 0 = CRT, 1 = FlatPanel */
+ if (tmp & 0x04) {
+ cPtr->PanelType |= ChipsLCD | ChipsLCDProbed;
+ }
+ if ((cPtr->readXR(cPtr, 0x06)) & 0x02) {
+ cPtr->PanelType |= ChipsCRT;
+ }
+ }
+}
+
+static void
+chipsBlockHandler (
+ int i,
+ pointer blockData,
+ pointer pTimeout,
+ pointer pReadmask
+){
+ ScreenPtr pScreen = screenInfo.screens[i];
+ ScrnInfoPtr pScrn = xf86Screens[i];
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ pScreen->BlockHandler = cPtr->BlockHandler;
+ (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
+ pScreen->BlockHandler = chipsBlockHandler;
+
+ if(cPtr->VideoTimerCallback) {
+ UpdateCurrentTime();
+ (*cPtr->VideoTimerCallback)(pScrn, currentTime.milliseconds);
+ }
+}
diff --git a/src/ct_driver.h b/src/ct_driver.h
new file mode 100644
index 0000000..831ac9b
--- /dev/null
+++ b/src/ct_driver.h
@@ -0,0 +1,553 @@
+/* $XConsortium: ct_driver.h /main/3 1996/10/27 11:49:29 kaleb $ */
+/*
+ * Modified 1996 by Egbert Eich <eich@xfree86.org>
+ * Modified 1996 by David Bateman <dbateman@club-internet.fr>
+ *
+ * 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 the authors not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHORS 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.
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_driver.h,v 1.34 2002/01/25 21:56:00 tsi Exp $ */
+
+
+#ifndef _CT_DRIVER_H_
+#define _CT_DRIVER_H_
+
+#include "xaa.h"
+#include "vbe.h"
+#include "xaalocal.h" /* XAA internals as we replace some of XAA */
+#include "xf86Cursor.h"
+#include "xf86i2c.h"
+#include "xf86DDC.h"
+#include "xf86xv.h"
+#include "vgaHW.h"
+
+/* Supported chipsets */
+typedef enum {
+ CHIPS_CT65520,
+ CHIPS_CT65525,
+ CHIPS_CT65530,
+ CHIPS_CT65535,
+ CHIPS_CT65540,
+ CHIPS_CT65545,
+ CHIPS_CT65546,
+ CHIPS_CT65548,
+ CHIPS_CT65550,
+ CHIPS_CT65554,
+ CHIPS_CT65555,
+ CHIPS_CT68554,
+ CHIPS_CT69000,
+ CHIPS_CT69030,
+ CHIPS_CT64200,
+ CHIPS_CT64300
+} CHIPSType;
+
+/* Clock related */
+typedef struct {
+ unsigned char msr; /* Dot Clock Related */
+ unsigned char fcr;
+ unsigned char xr02;
+ unsigned char xr03;
+ unsigned char xr33;
+ unsigned char xr54;
+ unsigned char fr03;
+ int Clock;
+ int FPClock;
+} CHIPSClockReg, *CHIPSClockPtr;
+
+typedef struct {
+ unsigned int ProbedClk;
+ unsigned int Max; /* Memory Clock Related */
+ unsigned int Clk;
+ unsigned char M;
+ unsigned char N;
+ unsigned char P;
+ unsigned char PSN;
+ unsigned char xrCC;
+ unsigned char xrCD;
+ unsigned char xrCE;
+} CHIPSMemClockReg, *CHIPSMemClockPtr;
+
+#define TYPE_HW 0x01
+#define TYPE_PROGRAMMABLE 0x02
+#define GET_TYPE 0x0F
+#define OLD_STYLE 0x10
+#define NEW_STYLE 0x20
+#define HiQV_STYLE 0x30
+#define WINGINE_1_STYLE 0x40 /* 64300: external clock; 4 clocks */
+#define WINGINE_2_STYLE 0x50 /* 64300: internal clock; 2 hw-clocks */
+#define GET_STYLE 0xF0
+#define LCD_TEXT_CLK_FREQ 25000 /* lcd textclock if TYPE_PROGRAMMABLE */
+#define CRT_TEXT_CLK_FREQ 28322 /* crt textclock if TYPE_PROGRAMMABLE */
+#define Fref 14318180 /* The reference clock in Hertz */
+
+/* The capability flags for the C&T chipsets */
+#define ChipsLinearSupport 0x00000001
+#define ChipsAccelSupport 0x00000002
+#define ChipsFullMMIOSupport 0x00000004
+#define ChipsMMIOSupport 0x00000008
+#define ChipsHDepthSupport 0x00000010
+#define ChipsDPMSSupport 0x00000020
+#define ChipsTMEDSupport 0x00000040
+#define ChipsGammaSupport 0x00000080
+#define ChipsVideoSupport 0x00000100
+#define ChipsDualChannelSupport 0x00000200
+#define ChipsDualRefresh 0x00000400
+
+/* Options flags for the C&T chipsets */
+#define ChipsHWCursor 0x00001000
+#define ChipsShadowFB 0x00002000
+#define ChipsOverlay8plus16 0x00004000
+#define ChipsUseNewFB 0x00008000
+
+/* Architecture type flags */
+#define ChipsHiQV 0x00010000
+#define ChipsWingine 0x00020000
+#define IS_Wingine(x) ((x->Flags) & ChipsWingine)
+#define IS_HiQV(x) ((x->Flags) & ChipsHiQV)
+
+/* Acceleration flags for the C&T chipsets */
+#define ChipsColorTransparency 0x0100000
+#define ChipsImageReadSupport 0x0200000
+
+/* Overlay Transparency Key */
+#define TRANSPARENCY_KEY 255
+
+/* Flag Bus Types */
+#define ChipsUnknown 0
+#define ChipsISA 1
+#define ChipsVLB 2
+#define ChipsPCI 3
+#define ChipsCPUDirect 4
+#define ChipsPIB 5
+#define ChipsMCB 6
+
+/* Macro's to select the 32 bit acceleration registers */
+#define DR(x) cPtr->Regs32[x] /* For CT655xx naming scheme */
+#define MR(x) cPtr->Regs32[x] /* CT655xx MMIO naming scheme */
+#define BR(x) cPtr->Regs32[x] /* For HiQV naming scheme */
+#define MMIOmeml(x) *(CARD32 *)(cPtr->MMIOBase + (x))
+#if 0
+#define MMIOmemw(x) *(CARD16 *)(cPtr->MMIOBase + (x))
+#endif
+/* Monitor or flat panel type flags */
+#define ChipsCRT 0x0010
+#define ChipsLCD 0x1000
+#define ChipsLCDProbed 0x2000
+#define ChipsTFT 0x0100
+#define ChipsDS 0x0200
+#define ChipsDD 0x0400
+#define ChipsSS 0x0800
+#define IS_STN(x) ((x) & 0xE00)
+
+/* Dual channel register enable masks */
+#define IOSS_MASK 0xE0
+#define IOSS_BOTH 0x13
+#define IOSS_PIPE_A 0x11
+#define IOSS_PIPE_B 0x1E
+#define MSS_MASK 0xF0
+#define MSS_BOTH 0x0B
+#define MSS_PIPE_A 0x02
+#define MSS_PIPE_B 0x05
+/* Aggregate value of MSS shadow bits -GHB */
+#define MSS_SHADOW 0x07
+
+/* Storage for the registers of the C&T chipsets */
+typedef struct {
+ unsigned char XR[0xFF];
+ unsigned char CR[0x80];
+ unsigned char FR[0x80];
+ unsigned char MR[0x80];
+ CHIPSClockReg Clock;
+} CHIPSRegRec, *CHIPSRegPtr;
+
+/* Storage for the flat panel size */
+typedef struct {
+ int HDisplay;
+ int HRetraceStart;
+ int HRetraceEnd;
+ int HTotal;
+ int VDisplay;
+ int VRetraceStart;
+ int VTotal;
+} CHIPSPanelSizeRec, *CHIPSPanelSizePtr;
+
+/* Some variables needed in the XAA acceleration */
+typedef struct {
+ /* General variable */
+ unsigned int CommandFlags;
+ unsigned int BytesPerPixel;
+ unsigned int BitsPerPixel;
+ unsigned int FbOffset;
+ unsigned int PitchInBytes;
+ unsigned int ScratchAddress;
+ /* 64k for color expansion and imagewrites */
+ unsigned char * BltDataWindow;
+ /* Hardware cursor address */
+ unsigned int CursorAddress;
+ Bool UseHWCursor;
+ /* Boundaries of the pixmap cache */
+ unsigned int CacheStart;
+ unsigned int CacheEnd;
+ /* Storage for pattern mask */
+ int planemask;
+ /* Storage for foreground and background color */
+ int fgColor;
+ int bgColor;
+ /* For the 8x8 pattern fills */
+ int patternyrot;
+ /* For cached stipple fills */
+ int SlotWidth;
+ /* Variables for the 24bpp fill */
+ unsigned char fgpixel;
+ unsigned char bgpixel;
+ unsigned char xorpixel;
+ Bool fastfill;
+ Bool rgb24equal;
+ int fillindex;
+ unsigned int width24bpp;
+ unsigned int color24bpp;
+ unsigned int rop24bpp;
+} CHIPSACLRec, *CHIPSACLPtr;
+#define CHIPSACLPTR(p) &((CHIPSPtr)((p)->driverPrivate))->Accel
+
+/* Storage for some register values that are messed up by suspend/resumes */
+typedef struct {
+ unsigned char xr02;
+ unsigned char xr03;
+ unsigned char xr14;
+ unsigned char xr15;
+ unsigned char vgaIOBaseFlag;
+} CHIPSSuspendHackRec, *CHIPSSuspendHackPtr;
+
+/* The functions to access the C&T extended registers */
+typedef struct _CHIPSRec *CHIPSPtr;
+typedef CARD8 (*chipsReadXRPtr)(CHIPSPtr cPtr, CARD8 index);
+typedef void (*chipsWriteXRPtr)(CHIPSPtr cPtr, CARD8 index, CARD8 value);
+typedef CARD8 (*chipsReadFRPtr)(CHIPSPtr cPtr, CARD8 index);
+typedef void (*chipsWriteFRPtr)(CHIPSPtr cPtr, CARD8 index, CARD8 value);
+typedef CARD8 (*chipsReadMRPtr)(CHIPSPtr cPtr, CARD8 index);
+typedef void (*chipsWriteMRPtr)(CHIPSPtr cPtr, CARD8 index, CARD8 value);
+typedef CARD8 (*chipsReadMSSPtr)(CHIPSPtr cPtr);
+typedef void (*chipsWriteMSSPtr)(CHIPSPtr cPtr, vgaHWPtr hwp, CARD8 value);
+typedef CARD8 (*chipsReadIOSSPtr)(CHIPSPtr cPtr);
+typedef void (*chipsWriteIOSSPtr)(CHIPSPtr cPtr, CARD8 value);
+
+/* The privates of the C&T driver */
+#define CHIPSPTR(p) ((CHIPSPtr)((p)->driverPrivate))
+
+
+typedef struct {
+ int lastInstance;
+ int refCount;
+ CARD32 masterFbAddress;
+ long masterFbMapSize;
+ CARD32 slaveFbAddress;
+ long slaveFbMapSize;
+ int mastervideoRam;
+ int slavevideoRam;
+ Bool masterOpen;
+ Bool slaveOpen;
+ Bool masterActive;
+ Bool slaveActive;
+} CHIPSEntRec, *CHIPSEntPtr;
+
+
+typedef struct _CHIPSRec {
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+ int Chipset;
+ EntityInfoPtr pEnt;
+ IOADDRESS PIOBase;
+ CARD32 IOAddress;
+ unsigned long FbAddress;
+ unsigned int IOBase;
+ unsigned char * FbBase;
+ unsigned char * MMIOBase;
+ unsigned char * MMIOBaseVGA;
+ unsigned char * MMIOBasePipeA;
+ unsigned char * MMIOBasePipeB;
+ long FbMapSize;
+ unsigned char * ShadowPtr;
+ int ShadowPitch;
+ int Rotate;
+ void (*PointerMoved)(int index, int x, int y);
+ int FbOffset16;
+ int FbSize16;
+ OptionInfoPtr Options;
+ CHIPSPanelSizeRec PanelSize;
+ int FrameBufferSize;
+ Bool SyncResetIgn;
+ Bool UseMMIO;
+ Bool UseFullMMIO;
+ Bool UseDualChannel;
+ int Monitor;
+ int MinClock;
+ int MaxClock;
+ CHIPSClockReg SaveClock; /* Storage for ClockSelect */
+ CHIPSMemClockReg MemClock;
+ unsigned char ClockType;
+ unsigned char CRTClk[4];
+ unsigned char FPClk[4];
+ int FPclock;
+ int FPclkInx;
+ int CRTclkInx;
+ Bool FPClkModified;
+ int ClockMulFactor;
+ int Rounding;
+ CHIPSSuspendHackRec SuspendHack;
+ CARD32 PanelType;
+ CHIPSRegRec ModeReg;
+ CHIPSRegRec SavedReg;
+ CHIPSRegRec SavedReg2;
+ vgaRegRec VgaSavedReg2;
+ unsigned int * Regs32;
+ unsigned int Flags;
+ CARD32 Bus;
+ XAAInfoRecPtr AccelInfoRec;
+ xf86CursorInfoPtr CursorInfoRec;
+ CHIPSACLRec Accel;
+ unsigned int HWCursorContents;
+ Bool HWCursorShown;
+ DGAModePtr DGAModes;
+ int numDGAModes;
+ Bool DGAactive;
+ int DGAViewportStatus;
+ CloseScreenProcPtr CloseScreen;
+ ScreenBlockHandlerProcPtr BlockHandler;
+ void (*VideoTimerCallback)(ScrnInfoPtr, Time);
+ int videoKey;
+ XF86VideoAdaptorPtr adaptor;
+ int OverlaySkewX;
+ int OverlaySkewY;
+ int VideoZoomMax;
+ Bool SecondCrtc;
+ CHIPSEntPtr entityPrivate;
+ unsigned char storeMSS;
+ unsigned char storeIOSS;
+#ifdef __arm32__
+#ifdef __NetBSD__
+ int TVMode;
+#endif
+ int Bank;
+#endif
+ unsigned char ddc_mask;
+ I2CBusPtr I2C;
+ vbeInfoPtr pVbe;
+ chipsReadXRPtr readXR;
+ chipsWriteXRPtr writeXR;
+ chipsReadFRPtr readFR;
+ chipsWriteFRPtr writeFR;
+ chipsReadMRPtr readMR;
+ chipsWriteMRPtr writeMR;
+ chipsReadMSSPtr readMSS;
+ chipsWriteMSSPtr writeMSS;
+ chipsReadIOSSPtr readIOSS;
+ chipsWriteIOSSPtr writeIOSS;
+ Bool cursorDelay;
+ unsigned int viewportMask;
+} CHIPSRec;
+
+typedef struct _CHIPSi2c {
+ unsigned char i2cClockBit;
+ unsigned char i2cDataBit;
+ CHIPSPtr cPtr;
+} CHIPSI2CRec, *CHIPSI2CPtr;
+
+/* External variables */
+extern int ChipsAluConv[];
+extern int ChipsAluConv2[];
+extern int ChipsAluConv3[];
+extern unsigned int ChipsReg32[];
+extern unsigned int ChipsReg32HiQV[];
+
+/* Prototypes */
+
+void CHIPSAdjustFrame(int scrnIndex, int x, int y, int flags);
+Bool CHIPSSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+
+/* video */
+void CHIPSInitVideo(ScreenPtr pScreen);
+void CHIPSResetVideo(ScrnInfoPtr pScrn);
+
+/* banking */
+int CHIPSSetRead(ScreenPtr pScreen, int bank);
+int CHIPSSetWrite(ScreenPtr pScreen, int bank);
+int CHIPSSetReadWrite(ScreenPtr pScreen, int bank);
+int CHIPSSetReadPlanar(ScreenPtr pScreen, int bank);
+int CHIPSSetWritePlanar(ScreenPtr pScreen, int bank);
+int CHIPSSetReadWritePlanar(ScreenPtr pScreen, int bank);
+int CHIPSWINSetRead(ScreenPtr pScreen, int bank);
+int CHIPSWINSetWrite(ScreenPtr pScreen, int bank);
+int CHIPSWINSetReadWrite(ScreenPtr pScreen, int bank);
+int CHIPSWINSetReadPlanar(ScreenPtr pScreen, int bank);
+int CHIPSWINSetWritePlanar(ScreenPtr pScreen, int bank);
+int CHIPSWINSetReadWritePlanar(ScreenPtr pScreen, int bank);
+int CHIPSHiQVSetReadWrite(ScreenPtr pScreen, int bank);
+int CHIPSHiQVSetReadWritePlanar(ScreenPtr pScreen, int bank);
+
+/* acceleration */
+Bool CHIPSAccelInit(ScreenPtr pScreen);
+void CHIPSSync(ScrnInfoPtr pScrn);
+Bool CHIPSMMIOAccelInit(ScreenPtr pScreen);
+void CHIPSMMIOSync(ScrnInfoPtr pScrn);
+Bool CHIPSHiQVAccelInit(ScreenPtr pScreen);
+void CHIPSHiQVSync(ScrnInfoPtr pScrn);
+Bool CHIPSCursorInit(ScreenPtr pScreen);
+
+/* register access functions */
+void CHIPSSetStdExtFuncs(CHIPSPtr cPtr);
+void CHIPSSetMmioExtFuncs(CHIPSPtr cPtr);
+void CHIPSHWSetMmioFuncs(ScrnInfoPtr pScrn, CARD8 *base, int offset);
+
+/* ddc */
+extern void chips_ddc1(ScrnInfoPtr pScrn);
+extern Bool chips_i2cInit(ScrnInfoPtr pScrn);
+
+/* dga */
+Bool CHIPSDGAInit(ScreenPtr pScreen);
+
+/* shadow fb */
+void chipsRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void chipsRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void chipsRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void chipsRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void chipsRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void chipsPointerMoved(int index, int x, int y);
+
+
+/*
+ * Some macros for switching display channels. NOTE... It appears that we
+ * can't write to both display channels at the same time, and so the options
+ * MSS_BOTH and IOSS_BOTH should not be used. Need to get around this by set
+ * dual channel mode to pipe A by default and handling multiple channel writes
+ * in ModeInit..
+ */
+
+#define DUALOPEN \
+ { \
+ /* Set the IOSS/MSS registers to point to the right register set */ \
+ if (xf86IsEntityShared(pScrn->entityList[0])) { \
+ if (cPtr->SecondCrtc == TRUE) { \
+ cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | \
+ IOSS_PIPE_B)); \
+ cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), ((cPtr->storeMSS & \
+ MSS_MASK) | MSS_PIPE_B)); \
+ cPtrEnt->slaveOpen = TRUE; \
+ cPtrEnt->slaveActive = TRUE; \
+ cPtrEnt->masterActive = FALSE; \
+ } else { \
+ cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | \
+ IOSS_PIPE_A)); \
+ cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), ((cPtr->storeMSS & \
+ MSS_MASK) | MSS_PIPE_A)); \
+ cPtrEnt->masterOpen = TRUE; \
+ cPtrEnt->masterActive = TRUE; \
+ cPtrEnt->slaveActive = FALSE; \
+ } \
+ } else { \
+ cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | \
+ IOSS_PIPE_A)); \
+ cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), ((cPtr->storeMSS & \
+ MSS_MASK) | MSS_PIPE_A)); \
+ } \
+ }
+
+#define DUALREOPEN \
+ { \
+ if (xf86IsEntityShared(pScrn->entityList[0])) { \
+ if (cPtr->SecondCrtc == TRUE) { \
+ if (! cPtrEnt->slaveActive) { \
+ cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | \
+ IOSS_PIPE_B)); \
+ cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), ((cPtr->storeMSS & \
+ MSS_MASK) | MSS_PIPE_B)); \
+ cPtrEnt->slaveOpen = TRUE; \
+ cPtrEnt->slaveActive = TRUE; \
+ cPtrEnt->masterActive = FALSE; \
+ } \
+ } else { \
+ if (! cPtrEnt->masterActive) { \
+ cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | \
+ IOSS_PIPE_A)); \
+ cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), ((cPtr->storeMSS & \
+ MSS_MASK) | MSS_PIPE_A)); \
+ cPtrEnt->masterOpen = TRUE; \
+ cPtrEnt->masterActive = TRUE; \
+ cPtrEnt->slaveActive = FALSE; \
+ } \
+ } \
+ } \
+ }
+
+#define DUALCLOSE \
+ { \
+ if (! xf86IsEntityShared(pScrn->entityList[0])) { \
+ cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | \
+ IOSS_PIPE_A)); \
+ cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), ((cPtr->storeMSS & \
+ MSS_MASK) | MSS_PIPE_A)); \
+ chipsHWCursorOff(cPtr, pScrn); \
+ chipsRestore(pScrn, &(VGAHWPTR(pScrn))->SavedReg, \
+ &cPtr->SavedReg, TRUE); \
+ chipsLock(pScrn); \
+ cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | \
+ IOSS_PIPE_B)); \
+ cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), ((cPtr->storeMSS & \
+ MSS_MASK) | MSS_PIPE_B)); \
+ chipsHWCursorOff(cPtr, pScrn); \
+ chipsRestore(pScrn, &cPtr->VgaSavedReg2, &cPtr->SavedReg2, TRUE); \
+ cPtr->writeIOSS(cPtr, cPtr->storeIOSS); \
+ cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), cPtr->storeMSS); \
+ chipsLock(pScrn); \
+ } else { \
+ chipsHWCursorOff(cPtr, pScrn); \
+ chipsRestore(pScrn, &(VGAHWPTR(pScrn))->SavedReg, &cPtr->SavedReg,\
+ TRUE); \
+ if (cPtr->SecondCrtc == TRUE) { \
+ cPtrEnt->slaveActive = FALSE; \
+ cPtrEnt->slaveOpen = FALSE; \
+ if (! cPtrEnt->masterActive) { \
+ cPtr->writeIOSS(cPtr, cPtr->storeIOSS); \
+ cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), cPtr->storeMSS); \
+ chipsLock(pScrn); \
+ } \
+ } else { \
+ cPtrEnt->masterActive = FALSE; \
+ cPtrEnt->masterOpen = FALSE; \
+ if (! cPtrEnt->slaveActive) { \
+ cPtr->writeIOSS(cPtr, cPtr->storeIOSS); \
+ cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), cPtr->storeMSS); \
+ chipsLock(pScrn); \
+ } \
+ } \
+ } \
+ }
+
+
+/* To aid debugging of 32 bit register access we make the following defines */
+/*
+#define DEBUG
+#define CT_HW_DEBUG
+*/
+#if defined(DEBUG) & defined(CT_HW_DEBUG)
+#define HW_DEBUG(x) {usleep(500000); ErrorF("Register/Address: 0x%X\n",x);}
+#else
+#define HW_DEBUG(x)
+#endif
+#endif
diff --git a/src/ct_regs.c b/src/ct_regs.c
new file mode 100644
index 0000000..201ac5c
--- /dev/null
+++ b/src/ct_regs.c
@@ -0,0 +1,535 @@
+/*
+ * Created 1998 by David Bateman <dbateman@eng.uts.edu.au>
+ *
+ * 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 the authors not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHORS 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.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_regs.c,v 1.8 2002/01/25 21:56:00 tsi Exp $ */
+
+/*
+ * The functions in this file are used to read/write the C&T extension register
+ * and supply MMIO replacements of the VGA register access functions in
+ * vgaHW.c for chips that support MMIO access (eg 69000). Unlike the MGA
+ * chips, for instance, the C&T chipsets don't have a direct mapping between
+ * the MMIO mapped vga registers and the PIO versions.
+ *
+ * In General, these are the ONLY supported way of access the video processors
+ * registers. Exception are
+ *
+ * 1) chipsFindIsaDevice, where we don't know the chipset and so we don't know
+ * if the chipset supports MMIO access to its VGA registers, and we don't
+ * know the chips MemBase address and so can't map the VGA registers even
+ * if the chip did support MMIO. This effectively limits the use of non-PCI
+ * MMIO and multihead to a single card accessing 0x3D6/0x3D7. I.E. You can
+ * only have a single C&T card in a non-PCI multihead arrangement. Also as
+ * ISA has no method to disable I/O access to a card ISA multihead will
+ * never be supported.
+ *
+ * 2) ct_Blitter.h, ct_BlitMM.h and ct_BltHiQV.h, where speed is crucial and
+ * we know exactly whether we are using MMIO or PIO.
+ *
+ * 3) The 6554x 32bit DRxx in ct_cursor.c where the choice between MMIO and
+ * PIO is made explicitly
+ */
+
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+/* Everything using inb/outb, etc needs "compiler.h" */
+#include "compiler.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"
+
+/* This is used for module versioning */
+#include "xf86Version.h"
+
+/* Driver specific headers */
+#include "ct_driver.h"
+
+#define CHIPS_MONO_STAT_1 0x3BA
+#define CHIPS_STAT_0 0x3BA
+#define CHIPS_MSS 0x3CB
+#define CHIPS_IOSS 0x3CD
+#define CHIPS_FR_INDEX 0x3D0
+#define CHIPS_FR_DATA 0x3D1
+#define CHIPS_MR_INDEX 0x3D2
+#define CHIPS_MR_DATA 0x3D3
+#define CHIPS_XR_INDEX 0x3D6
+#define CHIPS_XR_DATA 0x3D7
+#define CHIPS_COLOR_STAT_1 0x3DA
+
+#define CHIPS_MMIO_MONO_CRTC_INDEX 0x768
+#define CHIPS_MMIO_MONO_CRTC_DATA 0x769
+#define CHIPS_MMIO_MONO_STAT_1 0x774
+#define CHIPS_MMIO_ATTR_INDEX 0x780
+#define CHIPS_MMIO_ATTR_DATA_W 0x780
+#define CHIPS_MMIO_ATTR_DATA_R 0x781
+#define CHIPS_MMIO_STAT_0 0x784
+#define CHIPS_MMIO_MISC_OUT_W 0x784
+#define CHIPS_MMIO_SEQ_INDEX 0x788
+#define CHIPS_MMIO_SEQ_DATA 0x789
+#define CHIPS_MMIO_DAC_MASK 0x78C
+#define CHIPS_MMIO_DAC_READ_ADDR 0x78D
+#define CHIPS_MMIO_DAC_WRITE_ADDR 0x790
+#define CHIPS_MMIO_DAC_DATA 0x791
+#define CHIPS_MMIO_FEATURE_R 0x794
+#define CHIPS_MMIO_MSS 0x795
+#define CHIPS_MMIO_MISC_OUT_R 0x798
+#define CHIPS_MMIO_IOSS 0x799
+#define CHIPS_MMIO_GRAPH_INDEX 0x79C
+#define CHIPS_MMIO_GRAPH_DATA 0x79D
+#define CHIPS_MMIO_FR_INDEX 0x7A0
+#define CHIPS_MMIO_FR_DATA 0x7A1
+#define CHIPS_MMIO_MR_INDEX 0x7A4
+#define CHIPS_MMIO_MR_DATA 0x7A5
+#define CHIPS_MMIO_COLOR_CRTC_INDEX 0x7A8
+#define CHIPS_MMIO_COLOR_CRTC_DATA 0x7A9
+#define CHIPS_MMIO_XR_INDEX 0x7AC
+#define CHIPS_MMIO_XR_DATA 0x7AD
+#define CHIPS_MMIO_COLOR_STAT_1 0x7B4
+
+/*
+ * PIO Access to the C&T extension registers
+ */
+void
+chipsStdWriteXR(CHIPSPtr cPtr, CARD8 index, CARD8 value)
+{
+ outb(cPtr->PIOBase + CHIPS_XR_INDEX, index);
+ outb(cPtr->PIOBase + CHIPS_XR_DATA, value);
+}
+
+static CARD8
+chipsStdReadXR(CHIPSPtr cPtr, CARD8 index)
+{
+ outb(cPtr->PIOBase + CHIPS_XR_INDEX, index);
+ return inb(cPtr->PIOBase + CHIPS_XR_DATA);
+}
+
+static void
+chipsStdWriteFR(CHIPSPtr cPtr, CARD8 index, CARD8 value)
+{
+ outb(cPtr->PIOBase + CHIPS_FR_INDEX, index);
+ outb(cPtr->PIOBase + CHIPS_FR_DATA, value);
+}
+
+static CARD8
+chipsStdReadFR(CHIPSPtr cPtr, CARD8 index)
+{
+ outb(cPtr->PIOBase + CHIPS_FR_INDEX, index);
+ return inb(cPtr->PIOBase + CHIPS_FR_DATA);
+}
+
+static void
+chipsStdWriteMR(CHIPSPtr cPtr, CARD8 index, CARD8 value)
+{
+ outb(cPtr->PIOBase + CHIPS_MR_INDEX, index);
+ outb(cPtr->PIOBase + CHIPS_MR_DATA, value);
+}
+
+static CARD8
+chipsStdReadMR(CHIPSPtr cPtr, CARD8 index)
+{
+ outb(cPtr->PIOBase + CHIPS_MR_INDEX, index);
+ return inb(cPtr->PIOBase + CHIPS_MR_DATA);
+}
+
+static void
+chipsStdWriteMSS(CHIPSPtr cPtr, vgaHWPtr hwp, CARD8 value)
+{
+ outb(cPtr->PIOBase + CHIPS_MSS, value);
+}
+
+static CARD8
+chipsStdReadMSS(CHIPSPtr cPtr)
+{
+ return inb(cPtr->PIOBase + CHIPS_MSS);
+}
+
+static void
+chipsStdWriteIOSS(CHIPSPtr cPtr, CARD8 value)
+{
+ outb(cPtr->PIOBase + CHIPS_IOSS, value);
+}
+
+static CARD8
+chipsStdReadIOSS(CHIPSPtr cPtr)
+{
+ return inb(cPtr->PIOBase + CHIPS_IOSS);
+}
+
+void
+CHIPSSetStdExtFuncs(CHIPSPtr cPtr)
+{
+ cPtr->writeFR = chipsStdWriteFR;
+ cPtr->readFR = chipsStdReadFR;
+ cPtr->writeMR = chipsStdWriteMR;
+ cPtr->readMR = chipsStdReadMR;
+ cPtr->writeXR = chipsStdWriteXR;
+ cPtr->readXR = chipsStdReadXR;
+ cPtr->writeMSS = chipsStdWriteMSS;
+ cPtr->readMSS = chipsStdReadMSS;
+ cPtr->writeIOSS = chipsStdWriteIOSS;
+ cPtr->readIOSS = chipsStdReadIOSS;
+}
+
+/*
+ * MMIO Access to the C&T extension registers
+ */
+
+#define chipsminb(p) MMIO_IN8(cPtr->MMIOBaseVGA, (p))
+#define chipsmoutb(p,v) MMIO_OUT8(cPtr->MMIOBaseVGA, (p),(v))
+
+static void
+chipsMmioWriteXR(CHIPSPtr cPtr, CARD8 index, CARD8 value)
+{
+ chipsmoutb(CHIPS_MMIO_XR_INDEX, index);
+ chipsmoutb(CHIPS_MMIO_XR_DATA, value);
+}
+
+static CARD8
+chipsMmioReadXR(CHIPSPtr cPtr, CARD8 index)
+{
+ chipsmoutb(CHIPS_MMIO_XR_INDEX, index);
+ return chipsminb(CHIPS_MMIO_XR_DATA);
+}
+
+static void
+chipsMmioWriteFR(CHIPSPtr cPtr, CARD8 index, CARD8 value)
+{
+ chipsmoutb(CHIPS_MMIO_FR_INDEX, index);
+ chipsmoutb(CHIPS_MMIO_FR_DATA, value);
+}
+
+static CARD8
+chipsMmioReadFR(CHIPSPtr cPtr, CARD8 index)
+{
+ chipsmoutb(CHIPS_MMIO_FR_INDEX, index);
+ return chipsminb(CHIPS_MMIO_FR_DATA);
+}
+
+static void
+chipsMmioWriteMR(CHIPSPtr cPtr, CARD8 index, CARD8 value)
+{
+ chipsmoutb(CHIPS_MMIO_MR_INDEX, index);
+ chipsmoutb(CHIPS_MMIO_MR_DATA, value);
+}
+
+static CARD8
+chipsMmioReadMR(CHIPSPtr cPtr, CARD8 index)
+{
+ chipsmoutb(CHIPS_MMIO_MR_INDEX, index);
+ return chipsminb(CHIPS_MMIO_MR_DATA);
+}
+
+static void
+chipsMmioWriteMSS(CHIPSPtr cPtr, vgaHWPtr hwp, CARD8 value)
+{
+ /* 69030 MMIO Fix.
+ *
+ * <value> determines which MMIOBase to use; either
+ * Pipe A or Pipe B. -GHB
+ */
+ if ((value & MSS_SHADOW) == MSS_PIPE_B)
+ cPtr->MMIOBaseVGA = cPtr->MMIOBasePipeB;
+ else
+ cPtr->MMIOBaseVGA = cPtr->MMIOBasePipeA;
+
+ hwp->MMIOBase = cPtr->MMIOBaseVGA;
+
+ /* Since our Pipe constants don't set bit 3 of MSS, the value
+ * written here has no effect on the hardware's behavior. It
+ * does allow us to use the value returned by readMSS() to key
+ * the above logic, though. -GHB
+ */
+ chipsmoutb(CHIPS_MMIO_MSS, value);
+}
+
+static CARD8
+chipsMmioReadMSS(CHIPSPtr cPtr)
+{
+ return chipsminb(CHIPS_MMIO_MSS);
+}
+
+static void
+chipsMmioWriteIOSS(CHIPSPtr cPtr, CARD8 value)
+{
+ chipsmoutb(CHIPS_MMIO_IOSS, value);
+}
+
+static CARD8
+chipsMmioReadIOSS(CHIPSPtr cPtr)
+{
+ return chipsminb(CHIPS_MMIO_IOSS);
+}
+
+void
+CHIPSSetMmioExtFuncs(CHIPSPtr cPtr)
+{
+ cPtr->writeFR = chipsMmioWriteFR;
+ cPtr->readFR = chipsMmioReadFR;
+ cPtr->writeMR = chipsMmioWriteMR;
+ cPtr->readMR = chipsMmioReadMR;
+ cPtr->writeXR = chipsMmioWriteXR;
+ cPtr->readXR = chipsMmioReadXR;
+ cPtr->writeMSS = chipsMmioWriteMSS;
+ cPtr->readMSS = chipsMmioReadMSS;
+ cPtr->writeIOSS = chipsMmioWriteIOSS;
+ cPtr->readIOSS = chipsMmioReadIOSS;
+}
+
+/*
+ * MMIO versions of the VGA register access functions.
+ */
+
+#define minb(p) MMIO_IN8(hwp->MMIOBase, (p))
+#define moutb(p,v) MMIO_OUT8(hwp->MMIOBase, (p),(v))
+
+static void
+chipsMmioWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ if (hwp->IOBase == VGA_IOBASE_MONO) {
+ moutb(CHIPS_MMIO_MONO_CRTC_INDEX, index);
+ moutb(CHIPS_MMIO_MONO_CRTC_DATA, value);
+ } else {
+ moutb(CHIPS_MMIO_COLOR_CRTC_INDEX, index);
+ moutb(CHIPS_MMIO_COLOR_CRTC_DATA, value);
+ }
+}
+
+static CARD8
+chipsMmioReadCrtc(vgaHWPtr hwp, CARD8 index)
+{
+ if (hwp->IOBase == VGA_IOBASE_MONO) {
+ moutb(CHIPS_MMIO_MONO_CRTC_INDEX, index);
+ return minb(CHIPS_MMIO_MONO_CRTC_DATA);
+ } else {
+ moutb(CHIPS_MMIO_COLOR_CRTC_INDEX, index);
+ return minb(CHIPS_MMIO_COLOR_CRTC_DATA);
+ }
+}
+
+static void
+chipsMmioWriteGr(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ moutb(CHIPS_MMIO_GRAPH_INDEX, index);
+ moutb(CHIPS_MMIO_GRAPH_DATA, value);
+}
+
+static CARD8
+chipsMmioReadGr(vgaHWPtr hwp, CARD8 index)
+{
+ moutb(CHIPS_MMIO_GRAPH_INDEX, index);
+ return minb(CHIPS_MMIO_GRAPH_DATA);
+}
+
+static void
+chipsMmioWriteSeq(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ moutb(CHIPS_MMIO_SEQ_INDEX, index);
+ moutb(CHIPS_MMIO_SEQ_DATA, value);
+}
+
+static CARD8
+chipsMmioReadSeq(vgaHWPtr hwp, CARD8 index)
+{
+ moutb(CHIPS_MMIO_SEQ_INDEX, index);
+ return minb(CHIPS_MMIO_SEQ_DATA);
+}
+
+static void
+chipsMmioWriteAttr(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ CARD8 tmp;
+
+ if (hwp->paletteEnabled)
+ index &= ~0x20;
+ else
+ index |= 0x20;
+
+ if (hwp->IOBase == VGA_IOBASE_MONO)
+ tmp = minb(CHIPS_MMIO_MONO_STAT_1);
+ else
+ tmp = minb(CHIPS_MMIO_COLOR_STAT_1);
+ moutb(CHIPS_MMIO_ATTR_INDEX, index);
+ moutb(CHIPS_MMIO_ATTR_DATA_W, value);
+}
+
+static CARD8
+chipsMmioReadAttr(vgaHWPtr hwp, CARD8 index)
+{
+ CARD8 tmp;
+
+ if (hwp->paletteEnabled)
+ index &= ~0x20;
+ else
+ index |= 0x20;
+
+ if (hwp->IOBase == VGA_IOBASE_MONO)
+ tmp = minb(CHIPS_MMIO_MONO_STAT_1);
+ else
+ tmp = minb(CHIPS_MMIO_COLOR_STAT_1);
+ moutb(CHIPS_MMIO_ATTR_INDEX, index);
+ return minb(CHIPS_MMIO_ATTR_DATA_R);
+}
+
+static void
+chipsMmioWriteMiscOut(vgaHWPtr hwp, CARD8 value)
+{
+ moutb(CHIPS_MMIO_MISC_OUT_W, value);
+}
+
+static CARD8
+chipsMmioReadMiscOut(vgaHWPtr hwp)
+{
+ return minb(CHIPS_MMIO_MISC_OUT_R);
+}
+
+static void
+chipsMmioEnablePalette(vgaHWPtr hwp)
+{
+ CARD8 tmp;
+
+ if (hwp->IOBase == VGA_IOBASE_MONO)
+ tmp = minb(CHIPS_MMIO_MONO_STAT_1);
+ else
+ tmp = minb(CHIPS_MMIO_COLOR_STAT_1);
+ moutb(CHIPS_MMIO_ATTR_INDEX, 0x00);
+ hwp->paletteEnabled = TRUE;
+}
+
+static void
+chipsMmioDisablePalette(vgaHWPtr hwp)
+{
+ CARD8 tmp;
+
+ if (hwp->IOBase == VGA_IOBASE_MONO)
+ tmp = minb(CHIPS_MMIO_MONO_STAT_1);
+ else
+ tmp = minb(CHIPS_MMIO_COLOR_STAT_1);
+ moutb(CHIPS_MMIO_ATTR_INDEX, 0x20);
+ hwp->paletteEnabled = FALSE;
+}
+
+static void
+chipsMmioWriteDacMask(vgaHWPtr hwp, CARD8 value)
+{
+ moutb(CHIPS_MMIO_DAC_MASK, value);
+}
+
+static CARD8
+chipsMmioReadDacMask(vgaHWPtr hwp)
+{
+ return minb(CHIPS_MMIO_DAC_MASK);
+}
+
+static void
+chipsMmioWriteDacReadAddr(vgaHWPtr hwp, CARD8 value)
+{
+ moutb(CHIPS_MMIO_DAC_READ_ADDR, value);
+}
+
+static void
+chipsMmioWriteDacWriteAddr(vgaHWPtr hwp, CARD8 value)
+{
+ moutb(CHIPS_MMIO_DAC_WRITE_ADDR, value);
+}
+
+static void
+chipsMmioWriteDacData(vgaHWPtr hwp, CARD8 value)
+{
+ moutb(CHIPS_MMIO_DAC_DATA, value);
+}
+
+static CARD8
+chipsMmioReadDacData(vgaHWPtr hwp)
+{
+ return minb(CHIPS_MMIO_DAC_DATA);
+}
+
+static CARD8
+chipsMmioReadST00(vgaHWPtr hwp)
+{
+ return minb(CHIPS_MMIO_STAT_0);
+}
+
+static CARD8
+chipsMmioReadST01(vgaHWPtr hwp)
+{
+ if (hwp->IOBase == VGA_IOBASE_MONO)
+ return minb(CHIPS_MMIO_MONO_STAT_1);
+ else
+ return minb(CHIPS_MMIO_COLOR_STAT_1);
+}
+
+static CARD8
+chipsMmioReadFCR(vgaHWPtr hwp)
+{
+ return minb(CHIPS_MMIO_FEATURE_R);
+}
+
+static void
+chipsMmioWriteFCR(vgaHWPtr hwp, CARD8 value)
+{
+ if (hwp->IOBase == VGA_IOBASE_MONO) {
+ moutb(CHIPS_MMIO_MONO_STAT_1, value);
+ } else {
+ moutb(CHIPS_MMIO_COLOR_STAT_1, value);
+ }
+}
+
+void
+CHIPSHWSetMmioFuncs(ScrnInfoPtr pScrn, CARD8 *base, int offset)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ hwp->writeCrtc = chipsMmioWriteCrtc;
+ hwp->readCrtc = chipsMmioReadCrtc;
+ hwp->writeGr = chipsMmioWriteGr;
+ hwp->readGr = chipsMmioReadGr;
+ hwp->writeAttr = chipsMmioWriteAttr;
+ hwp->readAttr = chipsMmioReadAttr;
+ hwp->writeSeq = chipsMmioWriteSeq;
+ hwp->readSeq = chipsMmioReadSeq;
+ hwp->writeMiscOut = chipsMmioWriteMiscOut;
+ hwp->readMiscOut = chipsMmioReadMiscOut;
+ hwp->enablePalette = chipsMmioEnablePalette;
+ hwp->disablePalette = chipsMmioDisablePalette;
+ hwp->writeDacMask = chipsMmioWriteDacMask;
+ hwp->readDacMask = chipsMmioReadDacMask;
+ hwp->writeDacWriteAddr = chipsMmioWriteDacWriteAddr;
+ hwp->writeDacReadAddr = chipsMmioWriteDacReadAddr;
+ hwp->writeDacData = chipsMmioWriteDacData;
+ hwp->readDacData = chipsMmioReadDacData;
+ hwp->readST00 = chipsMmioReadST00;
+ hwp->readST01 = chipsMmioReadST01;
+ hwp->readFCR = chipsMmioReadFCR;
+ hwp->writeFCR = chipsMmioWriteFCR;
+ hwp->MMIOBase = base;
+ hwp->MMIOOffset = offset;
+}
+
+
+
+
diff --git a/src/ct_shadow.c b/src/ct_shadow.c
new file mode 100644
index 0000000..ecbb642
--- /dev/null
+++ b/src/ct_shadow.c
@@ -0,0 +1,243 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_shadow.c,v 1.1 2000/02/08 13:13:13 eich Exp $ */
+
+#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 "ct_driver.h"
+
+void
+chipsRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ CHIPSPtr cPtr = CHIPSPTR(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 = cPtr->ShadowPtr + (pbox->y1 * cPtr->ShadowPitch) +
+ (pbox->x1 * Bpp);
+ dst = cPtr->FbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
+
+ while(height--) {
+ memcpy(dst, src, width);
+ dst += FBPitch;
+ src += cPtr->ShadowPitch;
+ }
+
+ pbox++;
+ }
+}
+
+void
+chipsPointerMoved(int index, int x, int y)
+{
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ int newX, newY;
+
+ if(cPtr->Rotate == 1) {
+ newX = pScrn->pScreen->height - y - 1;
+ newY = x;
+ } else {
+ newX = y;
+ newY = pScrn->pScreen->width - x - 1;
+ }
+
+ (*cPtr->PointerMoved)(index, newX, newY);
+}
+
+void
+chipsRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ int count, width, height, y1, y2, dstPitch, srcPitch;
+ CARD8 *dstPtr, *srcPtr, *src;
+ CARD32 *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -cPtr->Rotate * cPtr->ShadowPitch;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ y1 = pbox->y1 & ~3;
+ y2 = (pbox->y2 + 3) & ~3;
+ height = (y2 - y1) >> 2; /* in dwords */
+
+ if(cPtr->Rotate == 1) {
+ dstPtr = cPtr->FbBase +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
+ srcPtr = cPtr->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = cPtr->FbBase +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
+ srcPtr = cPtr->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 += cPtr->Rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+
+void
+chipsRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ int count, width, height, y1, y2, dstPitch, srcPitch;
+ CARD16 *dstPtr, *srcPtr, *src;
+ CARD32 *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -cPtr->Rotate * cPtr->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(cPtr->Rotate == 1) {
+ dstPtr = (CARD16*)cPtr->FbBase +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
+ srcPtr = (CARD16*)cPtr->ShadowPtr +
+ ((1 - y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = (CARD16*)cPtr->FbBase +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
+ srcPtr = (CARD16*)cPtr->ShadowPtr +
+ (y1 * srcPitch) + pbox->x2 - 1;
+/* ErrorF("dst: %x base: %x\n",dstPtr,cPtr->FbBase);*/
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = (CARD32*)dstPtr;
+ count = height;
+ while(count--) {
+ *(dst++) = src[0] | (src[srcPitch] << 16);
+ src += srcPitch * 2;
+ }
+ srcPtr += cPtr->Rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+
+/* this one could be faster */
+void
+chipsRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ int count, width, height, y1, y2, dstPitch, srcPitch;
+ CARD8 *dstPtr, *srcPtr, *src;
+ CARD32 *dst;
+
+ dstPitch = BitmapBytePad(pScrn->displayWidth * 24);
+ srcPitch = -cPtr->Rotate * cPtr->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(cPtr->Rotate == 1) {
+ dstPtr = cPtr->FbBase +
+ (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3);
+ srcPtr = cPtr->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3);
+ } else {
+ dstPtr = cPtr->FbBase +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3);
+ srcPtr = cPtr->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 += cPtr->Rotate * 3;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+void
+chipsRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ int count, width, height, dstPitch, srcPitch;
+ CARD32 *dstPtr, *srcPtr, *src, *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -cPtr->Rotate * cPtr->ShadowPitch >> 2;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ height = pbox->y2 - pbox->y1;
+
+ if(cPtr->Rotate == 1) {
+ dstPtr = (CARD32*)cPtr->FbBase +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2;
+ srcPtr = (CARD32*)cPtr->ShadowPtr +
+ ((1 - pbox->y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = (CARD32*)cPtr->FbBase +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1;
+ srcPtr = (CARD32*)cPtr->ShadowPtr +
+ (pbox->y1 * srcPitch) + pbox->x2 - 1;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = dstPtr;
+ count = height;
+ while(count--) {
+ *(dst++) = *src;
+ src += srcPitch;
+ }
+ srcPtr += cPtr->Rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
diff --git a/src/ct_video.c b/src/ct_video.c
new file mode 100644
index 0000000..f5a824e
--- /dev/null
+++ b/src/ct_video.c
@@ -0,0 +1,1163 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_video.c,v 1.12 2002/11/25 14:04:58 eich 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 "ct_driver.h"
+#include "Xv.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "dixstruct.h"
+#include "fourcc.h"
+
+#define OFF_DELAY 200 /* milliseconds */
+#define FREE_DELAY 60000
+
+#define OFF_TIMER 0x01
+#define FREE_TIMER 0x02
+#define CLIENT_VIDEO_ON 0x04
+
+#define TIMER_MASK (OFF_TIMER | FREE_TIMER)
+
+#ifndef XvExtension
+void CHIPSInitVideo(ScreenPtr pScreen) {}
+void CHIPSResetVideo(ScrnInfoPtr pScrn) {}
+#else
+
+static XF86VideoAdaptorPtr CHIPSSetupImageVideo(ScreenPtr);
+static void CHIPSInitOffscreenImages(ScreenPtr);
+static void CHIPSStopVideo(ScrnInfoPtr, pointer, Bool);
+static int CHIPSSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer);
+static int CHIPSGetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer);
+static void CHIPSQueryBestSize(ScrnInfoPtr, Bool,
+ short, short, short, short, unsigned int *, unsigned int *, pointer);
+static int CHIPSPutImage( ScrnInfoPtr,
+ short, short, short, short, short, short, short, short,
+ int, unsigned char*, short, short, Bool, RegionPtr, pointer);
+static int CHIPSQueryImageAttributes(ScrnInfoPtr,
+ int, unsigned short *, unsigned short *, int *, int *);
+static void CHIPSVideoTimerCallback(ScrnInfoPtr pScrn, Time time);
+
+
+#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
+
+static Atom xvColorKey;
+
+void
+CHIPSInitVideo(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
+ XF86VideoAdaptorPtr newAdaptor = NULL;
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ int num_adaptors;
+
+ if (!(cPtr->Flags & ChipsOverlay8plus16) &&
+ (cPtr->Flags & ChipsVideoSupport)) {
+ newAdaptor = CHIPSSetupImageVideo(pScreen);
+ CHIPSInitOffscreenImages(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);
+}
+
+/* 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}
+};
+
+#define NUM_ATTRIBUTES 1
+
+static XF86AttributeRec Attributes[NUM_ATTRIBUTES] =
+{
+ {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}
+};
+
+#define NUM_IMAGES 4
+
+static XF86ImageRec Images[NUM_IMAGES] =
+{
+ {
+ 0x35315652,
+ XvRGB,
+ LSBFirst,
+ {'R','V','1','5',
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ 16,
+ XvPacked,
+ 1,
+ 15, 0x7C00, 0x03E0, 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
+ },
+ {
+ 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;
+ CARD32 videoStatus;
+ Time offTime;
+ Time freeTime;
+ Bool doubleBuffer;
+ Bool manualDoubleBuffer;
+ int currentBuffer;
+} CHIPSPortPrivRec, *CHIPSPortPrivPtr;
+
+
+#define GET_PORT_PRIVATE(pScrn) \
+ (CHIPSPortPrivPtr)((CHIPSPTR(pScrn))->adaptor->pPortPrivates[0].ptr)
+
+void
+CHIPSResetVideo(ScrnInfoPtr pScrn)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSPortPrivPtr pPriv = cPtr->adaptor->pPortPrivates[0].ptr;
+ unsigned char mr3c;
+ int red, green, blue;
+
+ if (cPtr->Flags & ChipsAccelSupport)
+ CHIPSHiQVSync(pScrn);
+
+ mr3c = cPtr->readMR(cPtr, 0x3C);
+ cPtr->writeMR(cPtr, 0x3C, (mr3c | 0x6));
+ switch (pScrn->depth) {
+ case 8:
+ cPtr->writeMR(cPtr, 0x3D, 0x00);
+ cPtr->writeMR(cPtr, 0x3E, 0x00);
+ cPtr->writeMR(cPtr, 0x3F, (pPriv->colorKey & 0xFF));
+ cPtr->writeMR(cPtr, 0x40, 0xFF);
+ cPtr->writeMR(cPtr, 0x41, 0xFF);
+ cPtr->writeMR(cPtr, 0x42, 0x00);
+ 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:
+ cPtr->writeMR(cPtr, 0x3D, (red << 3));
+ cPtr->writeMR(cPtr, 0x3E, (green << 3));
+ cPtr->writeMR(cPtr, 0x3F, (blue << 3));
+ cPtr->writeMR(cPtr, 0x40, 0x07);
+ cPtr->writeMR(cPtr, 0x41, 0x07);
+ cPtr->writeMR(cPtr, 0x42, 0x07);
+ break;
+ case 16:
+ cPtr->writeMR(cPtr, 0x3D, (red << 3));
+ cPtr->writeMR(cPtr, 0x3E, (green << 2));
+ cPtr->writeMR(cPtr, 0x3F, (blue << 3));
+ cPtr->writeMR(cPtr, 0x40, 0x07);
+ cPtr->writeMR(cPtr, 0x41, 0x03);
+ cPtr->writeMR(cPtr, 0x42, 0x07);
+ break;
+ case 24:
+ cPtr->writeMR(cPtr, 0x3D, red);
+ cPtr->writeMR(cPtr, 0x3E, green);
+ cPtr->writeMR(cPtr, 0x3F, blue);
+ cPtr->writeMR(cPtr, 0x40, 0x00);
+ cPtr->writeMR(cPtr, 0x41, 0x00);
+ cPtr->writeMR(cPtr, 0x42, 0x00);
+ break;
+ }
+ }
+}
+
+
+static XF86VideoAdaptorPtr
+CHIPSSetupImageVideo(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ XF86VideoAdaptorPtr adapt;
+ CHIPSPortPrivPtr pPriv;
+
+ if(!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) +
+ sizeof(CHIPSPortPrivRec) +
+ sizeof(DevUnion))))
+ return NULL;
+
+ adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+ adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ adapt->name = "Chips and Technologies Backend Scaler";
+ adapt->nEncodings = 1;
+ adapt->pEncodings = DummyEncoding;
+ adapt->nFormats = NUM_FORMATS;
+ adapt->pFormats = Formats;
+ adapt->nPorts = 1;
+ adapt->pPortPrivates = (DevUnion*)(&adapt[1]);
+ pPriv = (CHIPSPortPrivPtr)(&adapt->pPortPrivates[1]);
+ adapt->pPortPrivates[0].ptr = (pointer)(pPriv);
+ adapt->pAttributes = Attributes;
+ adapt->nImages = NUM_IMAGES;
+ adapt->nAttributes = NUM_ATTRIBUTES;
+ adapt->pImages = Images;
+ adapt->PutVideo = NULL;
+ adapt->PutStill = NULL;
+ adapt->GetVideo = NULL;
+ adapt->GetStill = NULL;
+ adapt->StopVideo = CHIPSStopVideo;
+ adapt->SetPortAttribute = CHIPSSetPortAttribute;
+ adapt->GetPortAttribute = CHIPSGetPortAttribute;
+ adapt->QueryBestSize = CHIPSQueryBestSize;
+ adapt->PutImage = CHIPSPutImage;
+ adapt->QueryImageAttributes = CHIPSQueryImageAttributes;
+
+ pPriv->colorKey = cPtr->videoKey;
+ pPriv->videoStatus = 0;
+ pPriv->doubleBuffer = TRUE;
+ pPriv->manualDoubleBuffer = FALSE;
+ pPriv->currentBuffer = 0;
+
+ /* gotta uninit this someplace */
+ REGION_INIT(pScreen, &pPriv->clip, NullBox, 0);
+
+ cPtr->adaptor = adapt;
+
+ xvColorKey = MAKE_ATOM("XV_COLORKEY");
+
+ CHIPSResetVideo(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;
+}
+
+
+/* CHIPSClipVideo -
+
+ Takes the dst box in standard X BoxRec form (top and left
+ edges inclusive, bottom and right exclusive). The new dst
+ box is returned. The source boundaries are given (x1, y1
+ inclusive, x2, y2 exclusive) and returned are the new source
+ boundaries in 16.16 fixed point.
+*/
+
+static Bool
+CHIPSClipVideo(
+ BoxPtr dst,
+ INT32 *x1,
+ INT32 *x2,
+ INT32 *y1,
+ INT32 *y2,
+ RegionPtr reg,
+ INT32 width,
+ INT32 height
+){
+ INT32 vscale, hscale, delta;
+ BoxPtr extents = REGION_EXTENTS(DummyScreen, reg);
+ int diff;
+
+ hscale = ((*x2 - *x1) << 16) / (dst->x2 - dst->x1);
+ vscale = ((*y2 - *y1) << 16) / (dst->y2 - dst->y1);
+
+ *x1 <<= 16; *x2 <<= 16;
+ *y1 <<= 16; *y2 <<= 16;
+
+ diff = extents->x1 - dst->x1;
+ if(diff > 0) {
+ dst->x1 = extents->x1;
+ *x1 += diff * hscale;
+ }
+ diff = dst->x2 - extents->x2;
+ if(diff > 0) {
+ dst->x2 = extents->x2;
+ *x2 -= diff * hscale;
+ }
+ diff = extents->y1 - dst->y1;
+ if(diff > 0) {
+ dst->y1 = extents->y1;
+ *y1 += diff * vscale;
+ }
+ diff = dst->y2 - extents->y2;
+ if(diff > 0) {
+ dst->y2 = extents->y2;
+ *y2 -= diff * vscale;
+ }
+
+ if(*x1 < 0) {
+ diff = (- *x1 + hscale - 1)/ hscale;
+ dst->x1 += diff;
+ *x1 += diff * hscale;
+ }
+ delta = *x2 - (width << 16);
+ if(delta > 0) {
+ diff = (delta + hscale - 1)/ hscale;
+ dst->x2 -= diff;
+ *x2 -= diff * hscale;
+ }
+ if(*x1 >= *x2) return FALSE;
+
+ if(*y1 < 0) {
+ diff = (- *y1 + vscale - 1)/ vscale;
+ dst->y1 += diff;
+ *y1 += diff * vscale;
+ }
+ delta = *y2 - (height << 16);
+ if(delta > 0) {
+ diff = (delta + vscale - 1)/ vscale;
+ dst->y2 -= diff;
+ *y2 -= diff * vscale;
+ }
+ if(*y1 >= *y2) return FALSE;
+
+ if((dst->x1 != extents->x1) || (dst->x2 != extents->x2) ||
+ (dst->y1 != extents->y1) || (dst->y2 != extents->y2))
+ {
+ RegionRec clipReg;
+ REGION_INIT(DummyScreen, &clipReg, dst, 1);
+ REGION_INTERSECT(DummyScreen, reg, reg, &clipReg);
+ REGION_UNINIT(DummyScreen, &clipReg);
+ }
+ return TRUE;
+}
+
+static void
+CHIPSStopVideo(ScrnInfoPtr pScrn, pointer data, Bool shadow)
+{
+ CHIPSPortPrivPtr pPriv = (CHIPSPortPrivPtr)data;
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ unsigned char mr3c, tmp;
+
+ REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
+ if (cPtr->Flags & ChipsAccelSupport)
+ CHIPSHiQVSync(pScrn);
+ if(shadow) {
+ if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
+ mr3c = cPtr->readMR(cPtr, 0x3C);
+ cPtr->writeMR(cPtr, 0x3C, (mr3c & 0xFE));
+ tmp = cPtr->readXR(cPtr, 0xD0);
+ cPtr->writeXR(cPtr, 0xD0, (tmp & 0xf));
+ }
+ 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;
+ cPtr->VideoTimerCallback = CHIPSVideoTimerCallback;
+ }
+ }
+}
+
+static int
+CHIPSSetPortAttribute(
+ ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 value,
+ pointer data
+){
+ CHIPSPortPrivPtr pPriv = (CHIPSPortPrivPtr)data;
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ if (cPtr->Flags & ChipsAccelSupport)
+ CHIPSHiQVSync(pScrn);
+ if(attribute == xvColorKey) {
+ int red, green, blue;
+ pPriv->colorKey = value;
+ switch (pScrn->depth) {
+ case 8:
+ cPtr->writeMR(cPtr, 0x3D, 0x00);
+ cPtr->writeMR(cPtr, 0x3E, 0x00);
+ cPtr->writeMR(cPtr, 0x3F, (pPriv->colorKey & 0xFF));
+ 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:
+ cPtr->writeMR(cPtr, 0x3D, (red << 3));
+ cPtr->writeMR(cPtr, 0x3E, (green << 3));
+ cPtr->writeMR(cPtr, 0x3F, (blue << 3));
+ break;
+ case 16:
+ cPtr->writeMR(cPtr, 0x3D, (red << 3));
+ cPtr->writeMR(cPtr, 0x3E, (green << 2));
+ cPtr->writeMR(cPtr, 0x3F, (blue << 3));
+ break;
+ case 24:
+ cPtr->writeMR(cPtr, 0x3D, red);
+ cPtr->writeMR(cPtr, 0x3E, green);
+ cPtr->writeMR(cPtr, 0x3F, blue);
+ break;
+ }
+ }
+ REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
+ } else return BadMatch;
+
+ return Success;
+}
+
+static int
+CHIPSGetPortAttribute(
+ ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 *value,
+ pointer data
+){
+ CHIPSPortPrivPtr pPriv = (CHIPSPortPrivPtr)data;
+
+ if(attribute == xvColorKey) {
+ *value = pPriv->colorKey;
+ } else return BadMatch;
+
+ return Success;
+}
+
+static void
+CHIPSQueryBestSize(
+ 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
+CHIPSCopyData(
+ 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
+CHIPSCopyMungedData(
+ 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
+CHIPSAllocateMemory(
+ 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 int
+CHIPSSetCurrentPlaybackBuffer(CHIPSPtr cPtr, int n)
+{
+
+ CARD8 mr20;
+ mr20 = cPtr->readMR(cPtr, 0x20);
+ mr20 &= ~0x1B;
+ if (!n) mr20 |= 0x10;
+ cPtr->writeMR(cPtr, 0x22, mr20);
+ return n;
+}
+
+static int
+CHIPSWaitGetNextFrame(CHIPSPtr cPtr)
+{
+ volatile CARD8 mr20;
+ volatile CARD8 mr21;
+
+ mr20 = cPtr->readMR(cPtr, 0x20);
+ while (1) {
+ mr21 = cPtr->readMR(cPtr, 0x21);
+ if (!(mr20 & (1 << 5)) || !(mr21 & 1))
+ break;
+ }
+ mr20 &= ~0x4;
+ mr20 = cPtr->readMR(cPtr, 0x20);
+ return (mr21 & 2)? 0 : 1;
+}
+
+static void
+CHIPSDisplayVideo(
+ 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,
+ Bool triggerBufSwitch
+){
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
+ DisplayModePtr mode = pScrn->currentMode;
+ unsigned char tmp, m1f, m1e;
+ int buffer = pPriv->currentBuffer;
+
+ if (cPtr->Flags & ChipsAccelSupport)
+ CHIPSHiQVSync(pScrn);
+
+ tmp = cPtr->readXR(cPtr, 0xD0);
+ cPtr->writeXR(cPtr, 0xD0, (tmp | 0x10));
+
+ m1e = cPtr->readMR(cPtr, 0x1E);
+ m1e &= 0xE0; /* Set Zoom and Direction */
+ if ((!(cPtr->PanelType & ChipsLCD)) && (mode->Flags & V_INTERLACE))
+ m1e |= 0x10;
+
+ m1f = cPtr->readMR(cPtr, 0x1F);
+ m1f = (m1f & 0x14); /* Mask reserved bits, unset interpolation */
+ switch(id) {
+ case 0x35315652: /* RGB15 */
+ m1f |= 0x09;
+ break;
+ case 0x36315652: /* RGB16 */
+ m1f |= 0x08;
+ break;
+ case FOURCC_YV12: /* YV12 */
+ /* m1f |= 0x03 */
+ m1f |= 0x00;
+ break;
+ case FOURCC_YUY2: /* YUY2 */
+ default:
+ m1f |= 0x00; /* Do nothing here */
+ break;
+ }
+
+ offset += (x1 >> 15) & ~0x01;
+ /* Setup Pointer 1 */
+ if (!buffer || pPriv->manualDoubleBuffer || !pPriv->doubleBuffer) {
+ cPtr->writeMR(cPtr, 0x22, (offset & 0xF8));
+ cPtr->writeMR(cPtr, 0x23, ((offset >> 8) & 0xFF));
+ cPtr->writeMR(cPtr, 0x24, ((offset >> 16) & 0xFF));
+ }
+ /* Setup Pointer 2 */
+ if ((buffer && !pPriv->manualDoubleBuffer) || !pPriv->doubleBuffer) {
+ cPtr->writeMR(cPtr, 0x25, (offset & 0xF8));
+ cPtr->writeMR(cPtr, 0x26, ((offset >> 8) & 0xFF));
+ cPtr->writeMR(cPtr, 0x27, ((offset >> 16) & 0xFF));
+ }
+
+
+ tmp = cPtr->readMR(cPtr, 0x04);
+ if (pPriv->doubleBuffer && !pPriv->manualDoubleBuffer && triggerBufSwitch)
+ tmp |= 0x18;
+ cPtr->writeMR(cPtr, 0x04, tmp);
+
+ tmp = cPtr->readMR(cPtr, 0x20);
+ tmp &= 0xC3;
+ if (pPriv->doubleBuffer && !pPriv->manualDoubleBuffer && triggerBufSwitch)
+ tmp |= ((1 << 2 | 1 << 5) | ((buffer) ? (1 << 4) : 0));
+ cPtr->writeMR(cPtr, 0x20, tmp);
+
+ cPtr->writeMR(cPtr, 0x28, ((width >> 2) - 1)); /* Width */
+ cPtr->writeMR(cPtr, 0x34, ((width >> 2) - 1));
+
+ /* Left Edge of Overlay */
+ cPtr->writeMR(cPtr, 0x2A, ((cPtr->OverlaySkewX + dstBox->x1) & 0xFF));
+ tmp = cPtr->readMR(cPtr, 0x2B);
+ tmp = (tmp & 0xF8) + (((cPtr->OverlaySkewX + dstBox->x1) >> 8) & 0x07);
+ cPtr->writeMR(cPtr, 0x2B, tmp);
+ /* Right Edge of Overlay */
+ cPtr->writeMR(cPtr, 0x2C, ((cPtr->OverlaySkewX + dstBox->x2 -1)
+ & 0xFF));
+ tmp = cPtr->readMR(cPtr, 0x2D);
+ tmp = (tmp & 0xF8) + (((cPtr->OverlaySkewX + dstBox->x2 - 1) >> 8) & 0x07);
+ cPtr->writeMR(cPtr, 0x2D, tmp);
+ /* Top Edge of Overlay */
+ cPtr->writeMR(cPtr, 0x2E, ((cPtr->OverlaySkewY + dstBox->y1) & 0xFF));
+ tmp = cPtr->readMR(cPtr, 0x2F);
+ tmp = (tmp & 0xF8) + (((cPtr->OverlaySkewY + dstBox->y1) >> 8) & 0x07);
+ cPtr->writeMR(cPtr, 0x2F, tmp);
+ /* Bottom Edge of Overlay*/
+ cPtr->writeMR(cPtr, 0x30, ((cPtr->OverlaySkewY + dstBox->y2 - 1) & 0xFF));
+ tmp = cPtr->readMR(cPtr, 0x31);
+ tmp = (tmp & 0xF8) + (((cPtr->OverlaySkewY + dstBox->y2 - 1) >> 8) & 0x07);
+ cPtr->writeMR(cPtr, 0x31, tmp);
+
+ /* Horizontal Zoom */
+ if (drw_w > src_w) {
+ m1f = m1f | 0x20; /* set H-interpolation */
+ m1e = m1e | 0x04;
+ tmp = cPtr->VideoZoomMax * src_w / drw_w;
+ cPtr->writeMR(cPtr, 0x32, tmp);
+ }
+
+ /* Vertical Zoom */
+ if (drw_h > src_h) {
+ m1f = m1f | 0x80;
+ m1e = m1e | 0x08; /* set V-interpolation */
+ tmp = cPtr->VideoZoomMax * src_h / drw_h ;
+ cPtr->writeMR(cPtr, 0x33, tmp);
+ }
+ cPtr->writeMR(cPtr, 0x1F, m1f);
+ cPtr->writeMR(cPtr, 0x1E, m1e);
+
+ tmp = cPtr->readMR(cPtr, 0x3C);
+ cPtr->writeMR(cPtr, 0x3C, (tmp | 0x7));
+ if (cPtr->Flags & ChipsAccelSupport)
+ CHIPSHiQVSync(pScrn);
+}
+
+static int
+CHIPSPutImage(
+ 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
+){
+ CHIPSPortPrivPtr pPriv = (CHIPSPortPrivPtr)data;
+ CHIPSPtr cPtr = CHIPSPTR(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;
+
+ if(drw_w > 16384) drw_w = 16384;
+
+ /* 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 (!CHIPSClipVideo(&dstBox, &x1, &x2, &y1, &y2, clipBoxes, width, height))
+ return Success;
+
+ dstBox.x1 -= pScrn->frameX0 & cPtr->viewportMask;
+ dstBox.x2 -= pScrn->frameX0 & cPtr->viewportMask;
+ 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;
+ if (pPriv->doubleBuffer)
+ new_size <<= 1;
+
+ switch(id) {
+ case FOURCC_YV12: /* YV12 */
+ srcPitch = (width + 3) & ~3;
+ offset2 = srcPitch * height;
+ srcPitch2 = ((width >> 1) + 3) & ~3;
+ offset3 = (srcPitch2 * (height >> 1)) + offset2;
+ break;
+ default: /* RGB15, RGB16, YUY2 */
+ srcPitch = (width << 1);
+ break;
+ }
+
+ if(!(pPriv->linear = CHIPSAllocateMemory(pScrn, pPriv->linear, new_size))) {
+ if (pPriv->doubleBuffer &&
+ (pPriv->linear = CHIPSAllocateMemory(pScrn, pPriv->linear,
+ new_size >> 1))) {
+ new_size >>= 1;
+ pPriv->doubleBuffer = FALSE;
+ } else
+ 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;
+ if (!pPriv->manualDoubleBuffer)
+ pPriv->currentBuffer = CHIPSWaitGetNextFrame(cPtr);
+ if(pPriv->doubleBuffer && pPriv->currentBuffer)
+ offset += (new_size * bpp) >> 1;
+
+ dst_start = cPtr->FbBase + offset + left + (top * dstPitch);
+
+ switch(id) {
+ case FOURCC_YV12: /* YV12 */
+ top &= ~1;
+ tmp = ((top >> 1) * srcPitch2) + (left >> 2);
+ offset2 += tmp;
+ offset3 += tmp;
+ nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
+ CHIPSCopyMungedData(buf + (top * srcPitch) + (left >> 1),
+ buf + offset2, buf + offset3, dst_start,
+ srcPitch, srcPitch2, dstPitch, nlines, npixels);
+ break;
+ default: /* RGB15, RGB16, YUY2 */
+ buf += (top * srcPitch) + left;
+ nlines = ((y2 + 0xffff) >> 16) - top;
+ CHIPSCopyData(buf, dst_start, srcPitch, dstPitch, nlines, npixels);
+ break;
+ }
+
+ /* update cliplist */
+ if(!RegionsEqual(&pPriv->clip, clipBoxes)) {
+ REGION_COPY(pScreen, &pPriv->clip, clipBoxes);
+ xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
+ }
+
+ offset += top * dstPitch;
+ CHIPSDisplayVideo(pScrn, id, offset, width, height, dstPitch,
+ x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h, TRUE);
+
+ pPriv->videoStatus = CLIENT_VIDEO_ON;
+
+ if (pPriv->manualDoubleBuffer)
+ pPriv->currentBuffer ^= 1;
+
+ return Success;
+}
+
+static int
+CHIPSQueryImageAttributes(
+ 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;
+}
+
+
+static void
+CHIPSVideoTimerCallback(ScrnInfoPtr pScrn, Time time)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
+ unsigned char mr3c;
+
+ if(pPriv->videoStatus & TIMER_MASK) {
+ if(pPriv->videoStatus & OFF_TIMER) {
+ if(pPriv->offTime < time) {
+ if (cPtr->Flags & ChipsAccelSupport)
+ CHIPSHiQVSync(pScrn);
+ mr3c = cPtr->readMR(cPtr, 0x3C);
+ cPtr->writeMR(cPtr, 0x3C, (mr3c & 0xFE));
+ pPriv->videoStatus = FREE_TIMER;
+ pPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
+ }
+ } else { /* FREE_TIMER */
+ if(pPriv->freeTime < time) {
+ if(pPriv->linear) {
+ xf86FreeOffscreenLinear(pPriv->linear);
+ pPriv->linear = NULL;
+ }
+ pPriv->videoStatus = 0;
+ cPtr->VideoTimerCallback = NULL;
+ }
+ }
+ } else /* shouldn't get here */
+ cPtr->VideoTimerCallback = NULL;
+}
+
+
+/****************** Offscreen stuff ***************/
+
+typedef struct {
+ FBLinearPtr linear;
+ Bool isOn;
+} OffscreenPrivRec, * OffscreenPrivPtr;
+
+static int
+CHIPSAllocateSurface(
+ 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 = CHIPSAllocateMemory(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
+CHIPSStopSurface(
+ XF86SurfacePtr surface
+){
+ OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
+
+ if(pPriv->isOn) {
+ CHIPSPtr cPtr = CHIPSPTR(surface->pScrn);
+ unsigned char mr3c, tmp;
+ tmp = cPtr->readXR(cPtr, 0xD0);
+ cPtr->writeXR(cPtr, 0xD0, (tmp & 0xf));
+ mr3c = cPtr->readMR(cPtr, 0x3C);
+ cPtr->writeMR(cPtr, 0x3C, (mr3c & 0xFE));
+ pPriv->isOn = FALSE;
+ }
+
+ return Success;
+}
+
+
+static int
+CHIPSFreeSurface(
+ XF86SurfacePtr surface
+){
+ OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
+
+ if(pPriv->isOn)
+ CHIPSStopSurface(surface);
+ xf86FreeOffscreenLinear(pPriv->linear);
+ xfree(surface->pitches);
+ xfree(surface->offsets);
+ xfree(surface->devPrivate.ptr);
+
+ return Success;
+}
+
+static int
+CHIPSGetSurfaceAttribute(
+ ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 *value
+){
+ return CHIPSGetPortAttribute(pScrn, attribute, value,
+ (pointer)(GET_PORT_PRIVATE(pScrn)));
+}
+
+static int
+CHIPSSetSurfaceAttribute(
+ ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 value
+){
+ return CHIPSSetPortAttribute(pScrn, attribute, value,
+ (pointer)(GET_PORT_PRIVATE(pScrn)));
+}
+
+
+static int
+CHIPSDisplaySurface(
+ 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;
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSPortPrivPtr portPriv = GET_PORT_PRIVATE(pScrn);
+ 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(!CHIPSClipVideo(&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;
+
+ if (portPriv->doubleBuffer)
+ portPriv->currentBuffer = CHIPSSetCurrentPlaybackBuffer(cPtr,0);
+ else
+ portPriv->currentBuffer = 0;
+
+ CHIPSDisplayVideo(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, FALSE);
+ xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes);
+
+ pPriv->isOn = TRUE;
+ if(portPriv->videoStatus & CLIENT_VIDEO_ON) {
+ REGION_EMPTY(pScrn->pScreen, &portPriv->clip);
+ UpdateCurrentTime();
+ portPriv->videoStatus = FREE_TIMER;
+ portPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
+ cPtr->VideoTimerCallback = CHIPSVideoTimerCallback;
+ }
+
+ return Success;
+}
+
+
+static void
+CHIPSInitOffscreenImages(ScreenPtr pScreen)
+{
+ 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 = CHIPSAllocateSurface;
+ offscreenImages[0].free_surface = CHIPSFreeSurface;
+ offscreenImages[0].display = CHIPSDisplaySurface;
+ offscreenImages[0].stop = CHIPSStopSurface;
+ offscreenImages[0].setAttribute = CHIPSSetSurfaceAttribute;
+ offscreenImages[0].getAttribute = CHIPSGetSurfaceAttribute;
+ offscreenImages[0].max_width = 1024;
+ offscreenImages[0].max_height = 1024;
+ offscreenImages[0].num_attributes = NUM_ATTRIBUTES;
+ offscreenImages[0].attributes = Attributes;
+
+ xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1);
+}
+
+#endif /* !XvExtension */
diff --git a/util/AsmMacros.h b/util/AsmMacros.h
new file mode 100644
index 0000000..feb5ce0
--- /dev/null
+++ b/util/AsmMacros.h
@@ -0,0 +1,450 @@
+/* $XConsortium: AsmMacros.h /main/13 1996/10/25 11:33:12 kaleb $ */
+/*
+ * (c) Copyright 1993,1994 by David Wexelblat <dwex@xfree86.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * DAVID WEXELBLAT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of David Wexelblat shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from David Wexelblat.
+ *
+ */
+/*
+ * Copyright 1997
+ * Digital Equipment Corporation. All rights reserved.
+ * This software is furnished under license and may be used and copied only in
+ * accordance with the following terms and conditions. Subject to these
+ * conditions, you may download, copy, install, use, modify and distribute
+ * this software in source and/or binary form. No title or ownership is
+ * transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce and retain
+ * this copyright notice and list of conditions as they appear in the source
+ * file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or logo of Digital
+ * Equipment Corporation. Neither the "Digital Equipment Corporation" name
+ * nor any trademark or logo of Digital Equipment Corporation may be used
+ * to endorse or promote products derived from this software without the
+ * prior written permission of Digital Equipment Corporation.
+ *
+ * 3) This software is provided "AS-IS" and any express or implied warranties,
+ * including but not limited to, any implied warranties of merchantability,
+ * fitness for a particular purpose, or non-infringement are disclaimed. In
+ * no event shall DIGITAL be liable for any damages whatsoever, and in
+ * particular, DIGITAL shall not be liable for special, indirect,
+ * consequential, or incidental damages or damages for
+ * lost profits, loss of revenue or loss of use, whether such damages arise
+ * in contract,
+ * negligence, tort, under statute, in equity, at law or otherwise, even if
+ * advised of the possibility of such damage.
+ *
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/util/AsmMacros.h,v 1.1 2001/11/16 21:13:34 tsi Exp $ */
+
+#if defined(__GNUC__)
+#if defined(linux) && (defined(__alpha__) || defined(__ia64__))
+#undef inb
+#undef inw
+#undef inl
+#undef outb
+#undef outw
+#undef outl
+#define inb _inb
+#define inw _inw
+#define inl _inl
+#define outb(p,v) _outb((v),(p))
+#define outw(p,v) _outw((v),(p))
+#define outl(p,v) _outl((v),(p))
+#else
+#if defined(__sparc__)
+#ifndef ASI_PL
+#define ASI_PL 0x88
+#endif
+
+static __inline__ void
+outb(port, val)
+unsigned long port;
+char val;
+{
+ __asm__ __volatile__("stba %0, [%1] %2" : : "r" (val), "r" (port), "i" (ASI_PL));
+}
+
+static __inline__ void
+outw(port, val)
+unsigned long port;
+char val;
+{
+ __asm__ __volatile__("stha %0, [%1] %2" : : "r" (val), "r" (port), "i" (ASI_PL));
+}
+
+static __inline__ void
+outl(port, val)
+unsigned long port;
+char val;
+{
+ __asm__ __volatile__("sta %0, [%1] %2" : : "r" (val), "r" (port), "i" (ASI_PL));
+}
+
+static __inline__ unsigned int
+inb(port)
+unsigned long port;
+{
+ unsigned char ret;
+ __asm__ __volatile__("lduba [%1] %2, %0" : "=r" (ret) : "r" (port), "i" (ASI_PL));
+ return ret;
+}
+
+static __inline__ unsigned int
+inw(port)
+unsigned long port;
+{
+ unsigned char ret;
+ __asm__ __volatile__("lduha [%1] %2, %0" : "=r" (ret) : "r" (port), "i" (ASI_PL));
+ return ret;
+}
+
+static __inline__ unsigned int
+inl(port)
+unsigned long port;
+{
+ unsigned char ret;
+ __asm__ __volatile__("lda [%1] %2, %0" : "=r" (ret) : "r" (port), "i" (ASI_PL));
+ return ret;
+}
+#else
+#ifdef __arm32__
+unsigned int IOPortBase; /* Memory mapped I/O port area */
+
+static __inline__ void
+outb(port, val)
+ short port;
+ char val;
+{
+ if ((unsigned short)port >= 0x400) return;
+
+ *(volatile unsigned char*)(((unsigned short)(port))+IOPortBase) = val;
+}
+
+static __inline__ void
+outw(port, val)
+ short port;
+ short val;
+{
+ if ((unsigned short)port >= 0x400) return;
+
+ *(volatile unsigned short*)(((unsigned short)(port))+IOPortBase) = val;
+}
+
+static __inline__ void
+outl(port, val)
+ short port;
+ int val;
+{
+ if ((unsigned short)port >= 0x400) return;
+
+ *(volatile unsigned long*)(((unsigned short)(port))+IOPortBase) = val;
+}
+
+static __inline__ unsigned int
+inb(port)
+ short port;
+{
+ if ((unsigned short)port >= 0x400) return((unsigned int)-1);
+
+ return(*(volatile unsigned char*)(((unsigned short)(port))+IOPortBase));
+}
+
+static __inline__ unsigned int
+inw(port)
+ short port;
+{
+ if ((unsigned short)port >= 0x400) return((unsigned int)-1);
+
+ return(*(volatile unsigned short*)(((unsigned short)(port))+IOPortBase));
+}
+
+static __inline__ unsigned int
+inl(port)
+ short port;
+{
+ if ((unsigned short)port >= 0x400) return((unsigned int)-1);
+
+ return(*(volatile unsigned long*)(((unsigned short)(port))+IOPortBase));
+}
+#else /* __arm32__ */
+#if defined(Lynx) && defined(__powerpc__)
+extern unsigned char *ioBase;
+
+static volatile void
+eieio()
+{
+ __asm__ __volatile__ ("eieio");
+}
+
+static void
+outb(port, value)
+short port;
+unsigned char value;
+{
+ *(uchar *)(ioBase + port) = value; eieio();
+}
+
+static void
+outw(port, value)
+short port;
+unsigned short value;
+{
+ *(unsigned short *)(ioBase + port) = value; eieio();
+}
+
+static void
+outl(port, value)
+short port;
+unsigned long value;
+{
+ *(unsigned long *)(ioBase + port) = value; eieio();
+}
+
+static unsigned char
+inb(port)
+short port;
+{
+ unsigned char val;
+
+ val = *((unsigned char *)(ioBase + port)); eieio();
+ return(val);
+}
+
+static unsigned short
+inw(port)
+short port;
+{
+ unsigned short val;
+
+ val = *((unsigned short *)(ioBase + port)); eieio();
+ return(val);
+}
+
+static unsigned long
+inl(port)
+short port;
+{
+ unsigned long val;
+
+ val = *((unsigned long *)(ioBase + port)); eieio();
+ return(val);
+}
+
+#else
+#if defined(__FreeBSD__) && defined(__alpha__)
+
+#include <sys/types.h>
+
+extern void outb(u_int32_t port, u_int8_t val);
+extern void outw(u_int32_t port, u_int16_t val);
+extern void outl(u_int32_t port, u_int32_t val);
+extern u_int8_t inb(u_int32_t port);
+extern u_int16_t inw(u_int32_t port);
+extern u_int32_t inl(u_int32_t port);
+
+#else
+#ifdef GCCUSESGAS
+static __inline__ void
+outb(port, val)
+short port;
+char val;
+{
+ __asm__ __volatile__("outb %0,%1" : :"a" (val), "d" (port));
+}
+
+static __inline__ void
+outw(port, val)
+short port;
+short val;
+{
+ __asm__ __volatile__("outw %0,%1" : :"a" (val), "d" (port));
+}
+
+static __inline__ void
+outl(port, val)
+short port;
+unsigned int val;
+{
+ __asm__ __volatile__("outl %0,%1" : :"a" (val), "d" (port));
+}
+
+static __inline__ unsigned int
+inb(port)
+short port;
+{
+ unsigned char ret;
+ __asm__ __volatile__("inb %1,%0" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+static __inline__ unsigned int
+inw(port)
+short port;
+{
+ unsigned short ret;
+ __asm__ __volatile__("inw %1,%0" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+static __inline__ unsigned int
+inl(port)
+short port;
+{
+ unsigned int ret;
+ __asm__ __volatile__("inl %1,%0" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+#else /* GCCUSESGAS */
+
+static __inline__ void
+outb(port, val)
+ short port;
+ char val;
+{
+ __asm__ __volatile__("out%B0 (%1)" : :"a" (val), "d" (port));
+}
+
+static __inline__ void
+outw(port, val)
+ short port;
+ short val;
+{
+ __asm__ __volatile__("out%W0 (%1)" : :"a" (val), "d" (port));
+}
+
+static __inline__ void
+outl(port, val)
+ short port;
+ unsigned int val;
+{
+ __asm__ __volatile__("out%L0 (%1)" : :"a" (val), "d" (port));
+}
+
+static __inline__ unsigned int
+inb(port)
+ short port;
+{
+ unsigned int ret;
+ __asm__ __volatile__("in%B0 (%1)" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+static __inline__ unsigned int
+inw(port)
+ short port;
+{
+ unsigned int ret;
+ __asm__ __volatile__("in%W0 (%1)" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+static __inline__ unsigned int
+inl(port)
+ short port;
+{
+ unsigned int ret;
+ __asm__ __volatile__("in%L0 (%1)" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+#endif /* GCCUSESGAS */
+#endif /* Lynx && __powerpc__ */
+#endif /* arm32 */
+#endif /* linux && __sparc__ */
+#endif /* linux && __alpha__ */
+#endif /* __FreeBSD__ && __alpha__ */
+
+#if defined(linux) || defined(__arm32__) || (defined(Lynx) && defined(__powerpc__))
+
+#define intr_disable()
+#define intr_enable()
+
+#else
+
+static __inline__ void
+intr_disable()
+{
+ __asm__ __volatile__("cli");
+}
+
+static __inline__ void
+intr_enable()
+{
+ __asm__ __volatile__("sti");
+}
+
+#endif /* else !linux && !__arm32__ */
+
+#else /* __GNUC__ */
+
+#if defined(_MINIX) && defined(_ACK)
+
+/* inb, outb, inw and outw are defined in the library */
+/* ... but I've no idea if the same is true for inl & outl */
+
+u8_t inb(U16_t);
+void outb(U16_t, U8_t);
+u16_t inw(U16_t);
+void outw(U16_t, U16_t);
+u32_t inl(U16_t);
+void outl(U16_t, U32_t);
+
+#else /* not _MINIX and _ACK */
+
+# if defined(__STDC__) && (__STDC__ == 1)
+# ifndef NCR
+# define asm __asm
+# endif
+# endif
+# ifdef SVR4
+# include <sys/types.h>
+# ifndef __USLC__
+# define __USLC__
+# endif
+# endif
+#ifndef SCO325
+# include <sys/inline.h>
+#else
+# include "../common/scoasm.h"
+#endif
+#define intr_disable() asm("cli")
+#define intr_enable() asm("sti")
+
+#endif /* _MINIX and _ACK */
+#endif /* __GNUC__ */
diff --git a/util/dRegs.c b/util/dRegs.c
new file mode 100644
index 0000000..0c8ee62
--- /dev/null
+++ b/util/dRegs.c
@@ -0,0 +1,305 @@
+/* $XConsortium: dRegs.c /main/2 1996/10/27 11:49:40 kaleb $ */
+
+
+
+
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/util/dRegs.c,v 1.9 2001/11/16 21:13:34 tsi Exp $ */
+
+#ifdef __NetBSD__
+# include <sys/types.h>
+# include <machine/pio.h>
+# include <machine/sysarch.h>
+#else
+# if defined(SVR4) && defined(i386)
+# include <sys/types.h>
+# ifdef NCR
+ /* broken NCR <sys/sysi86.h> */
+# define __STDC
+# include <sys/sysi86.h>
+# undef __STDC
+# else
+# include <sys/sysi86.h>
+# endif
+# ifdef SVR4
+# if !defined(sun)
+# include <sys/seg.h>
+# endif
+# endif
+# include <sys/v86.h>
+# if defined(sun)
+# include <sys/psw.h>
+# endif
+# endif
+# include "AsmMacros.h"
+#endif /* NetBSD */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef __NetBSD__
+# define SET_IOPL() i386_iopl(3)
+# define RESET_IOPL() i386_iopl(0)
+#else
+# if defined(SVR4) && defined(i386)
+# ifndef SI86IOPL
+# define SET_IOPL() sysi86(SI86V86,V86SC_IOPL,PS_IOPL)
+# define RESET_IOPL() sysi86(SI86V86,V86SC_IOPL,0)
+# else
+# define SET_IOPL() sysi86(SI86IOPL,3)
+# define RESET_IOPL() sysi86(SI86IOPL,0)
+# endif
+# else
+# ifdef linux
+# define SET_IOPL() iopl(3)
+# define RESET_IOPL() iopl(0)
+# else
+# define SET_IOPL() (void)0
+# define RESET_IOPL() (void)0
+# endif
+# endif
+#endif
+
+int main(void)
+{
+ int i, HTotal, HDisplay, HSyncStart, HSyncEnd,
+ VTotal, VDisplay, VSyncStart, VSyncEnd;
+ unsigned char storeReg, bpp, shift, IOSS = 0, MSS = 0, again = 0;
+ unsigned short port;
+ int isHiQV = 0;
+ int is69030 = 0;
+
+ SET_IOPL();
+
+ printf("0x3C6\t0x%X\n",inw(0x3C6));
+
+/* Check to see if the Chip is HiQV */
+ outb(0x3D6,0x02);
+ storeReg = inb(0x3D7);
+ if (storeReg == 0xE0 /* CT65550 */
+ || storeReg == 0xE4 /* CT65554 */
+ || storeReg == 0xE5 /* CT65555 */
+ || storeReg == 0xF4 /* CT68554 */
+ || storeReg == 0xC0) /* CT69000 */
+ {
+ isHiQV = 1;
+ } else if (storeReg == 0x30) {
+ outb(0x3D6,0x03);
+ storeReg = inb(0x3D7);
+ if (storeReg == 0xC) {
+ isHiQV = 1;
+ is69030 = 1;
+ IOSS=inb(0x3CD);
+ MSS=inb(0x3CB);
+ outb(0x3CD,((IOSS&0xE0)| 0x11)); /* Select Channel 0 */
+ outb(0x3CB,((MSS&0xF0)| 0x8));
+ again = 1;
+ printf("Pipeline A:\n");
+ }
+ }
+
+ again:
+ printf("port 0x3D6 (C&T)\n");
+ storeReg = inb(0x3D6);
+ shift = 3;
+ if (isHiQV==1) {
+ outw(0x102,1); /*global enable, VGA awake*/
+ printf("0x%2.2X\n",inb(0x3C3)&0xFF);
+ outb(0x3C3,0); /*disable VGA*/
+ outb(0x3C3,1); /*enable VGA*/
+ for(i = 0;i < 0xFF;i++){
+ outb(0x3D6,i);
+ printf("XR 0x%2.2X\t0x%2.2X\n",i,inb(0x3D7)&0xFF);
+ }
+ outb(0x3D6,0xE2);
+ bpp = inb(0x3D7)&0xF0;
+ } else {
+ outb(0x3D6, 0x70);
+ outw(0x3D6, (inw(0x3D6) | 0x8070));
+ outw(0x46E8,0x0016); /*setup mode*/
+ outw(0x102,1); /*global enable, VGA awake*/
+ outw(0x46E8,0x000E); /*exit from setup mode*/
+ printf("0x%2.2X\n",inb(0x3C3)&0xFF);
+ outb(0x3C3,0); /*disable VGA*/
+ outw(0x46E8,0x0000); /*exit from setup mode*/
+ outw(0x46E8,0x000E); /*exit from setup mode*/
+ outb(0x3C3,1); /*enable VGA*/
+ outw(0x46E8,0x0000); /*exit from setup mode*/
+ for(i = 0;i < 0x80;i++){
+ outb(0x3D6,i);
+ printf("XR 0x%2.2X\t0x%2.2X\n",i,inb(0x3D7)&0xFF);
+ }
+ outb(0x3D6,0x2B);
+ bpp = inb(0x3D7)&0xF0;
+ }
+
+ switch(bpp){
+ case 0x20:
+ bpp = 4;
+ break;
+ case 0x30:
+ bpp = 8;
+ break;
+ case 0x40:
+ bpp = 16;
+ shift = 2;
+ break;
+ case 0x50:
+ bpp = 24;
+ break;
+ default:
+ bpp = 0;
+ }
+ outb(0x3D6,storeReg);
+
+ printf("\nport 0x3D4 (CRTC)\n");
+ storeReg = inb(0x3D4);
+ if (isHiQV==1) {
+ for(i = 0;i < 0x7F;i++){
+ outb(0x3D4,i);
+ printf("CR 0x%2.2X\t0x%2.2X\n",i,inb(0x3D5)&0xFF);
+ }
+ outb(0x3D4,storeReg);
+ printf("\nport 0x3D0 (Flat Panel)\n");
+ storeReg = inb(0x3D0);
+ for(i = 0;i < 0x7F;i++){
+ outb(0x3D0,i);
+ printf("FR 0x%2.2X\t0x%2.2X\n",i,inb(0x3D1)&0xFF);
+ }
+ outb(0x3D1,storeReg);
+ printf("\nport 0x3D2 (Multimedia)\n");
+ storeReg = inb(0x3D2);
+ for(i = 0;i < 0x7F;i++){
+ outb(0x3D2,i);
+ printf("MR 0x%2.2X\t0x%2.2X\n",i,inb(0x3D3)&0xFF);
+ }
+ outb(0x3D3,storeReg);
+ } else {
+ for(i = 0;i < 0x40;i++){
+ outb(0x3D4,i);
+ printf("CR 0x%2.2X\t0x%2.2X\n",i,inb(0x3D5)&0xFF);
+ }
+ outb(0x3D4,storeReg);
+ }
+
+
+ printf("port 0x3CE (GC)\n");
+ storeReg = inb(0x3CE);
+ for(i = 0;i < 0x10;i++){
+ outb(0x3CE,i);
+ printf("GC 0x%2.2X\t0x%2.2X\n",i,inb(0x3CF)&0xFF);
+ }
+ outb(0x3CE,storeReg);
+ printf("port 0x3C4 (Sequencer)\n");
+ storeReg = inb(0x3C4);
+ for(i = 0;i < 0x10;i++){
+ outb(0x3C4,i);
+ printf("SQ 0x%2.2X\t0x%X2.2\n",i,inb(0x3C5)&0xFF);
+ }
+ outb(0x3C4,storeReg);
+
+
+ printf("port 0x3C0 (Attribute)\n");
+ inb(0x3DA);
+ storeReg = inb(0x3C0);
+ for(i = 0;i < 0xFF;i++){
+ inb(0x3DA);
+ outb(0x3C0,i);
+ printf("AT 0x%2.2X\t0x%2.2X\n",i,inb(0x3C1)&0xFF);
+ }
+ inb(0x3DA);
+ outb(0x3C0,storeReg);
+
+ printf("0x3CC\t0x%X\n",inb(0x3CC)&0xFF);
+ printf("0x3C2\t0x%X\n",inb(0x3C2)&0xFF);
+ printf("0x3C3\t0x%X\n",inb(0x3C2)&0xFF);
+ printf("0x3CA\t0x%X\n",inb(0x3CA)&0xFF);
+ printf("0x3DA\t0x%X\n",inb(0x3DA)&0xFF);
+
+ printf("\nRAMDAC\nport\tvalue\n");
+ for(port = 0x83C6; port < 0x83CA;port++){
+ printf("0x%4X\t0x%4X\n",port,inw(port));
+ }
+
+ if (isHiQV!=1) {
+ printf("\nBitBLT\nport\tvalue\n");
+ for(port = 0x83D0; port <= 0x9FD0;port+=0x400){
+ printf("0x%4.4X\t0x%4X\n",port,inw(port));
+ }
+
+ printf("\nH/W cursor\nport\tvalue\n");
+ for(port = 0xA3D0; port <= 0xB3D0;port+=0x400){
+ printf("0x%4.4X\t0x%4X\n",port,inw(port));
+ }
+
+
+ outb(0x3D6, 0x70);
+ outw(0x3D6, (inw(0x3D6) | 0x8070));
+
+ printf("0x46E8\t0x%8X\n",inl(0x46E8));
+ printf("0x4AE8\t0x%8X\n",inl(0x4AE8));
+ printf("0x102\t0x%8X\n",inl(0x102));
+ printf("0x103\t0x%8X\n",inl(0x103));
+
+ }
+
+ storeReg = inb(0x3D4);
+ {
+ outb(0x3D4,0);
+ HTotal = ((inb(0x3D5)&0xFF) + 5) << shift;
+ outb(0x3D4,1);
+ HDisplay = ((inb(0x3D5)&0xFF) + 1) << shift;
+ outb(0x3D4,4);
+ HSyncStart = ((inb(0x3D5)&0xFF) + 1) << shift;
+ outb(0x3D4,5);
+ HSyncEnd = inb(0x3D5)&0x1F;
+ outb(0x3D4,5);
+ HSyncEnd += HSyncStart >> shift;
+ HSyncEnd <<= shift;
+
+ outb(0x3D4,6);
+ VTotal = inb(0x3D5)&0xFF;
+ outb(0x3D4,7);
+ VTotal |= (inb(0x3D5)&0x1) << 8;
+ VTotal |= (inb(0x3D5)&0x20) << 4;
+ VTotal += 2;
+ VDisplay = (inb(0x3D5)&0x2) << 7;
+ VDisplay |= (inb(0x3D5)&0x40) << 3;
+ VSyncStart = (inb(0x3D5)&0x4) << 6;
+ VSyncStart |= (inb(0x3D5)&0x80) << 2;
+ outb(0x3D4,0x12);
+ VDisplay |= inb(0x3D5)&0xFF;
+ VDisplay += 1;
+ outb(0x3D4,0x10);
+ VSyncStart |= inb(0x3D5)&0xFF;
+
+ outb(0x3D4,0x11);
+ VSyncEnd = inb(0x3D5)&0xF;
+ VSyncEnd += VSyncStart;
+
+ }
+ outb(0x3D4,storeReg);
+
+ printf("\nModeLine with port 0x3D4 (CRTC) %d %d %d %d %d %d %d %d\n",
+ HDisplay, HSyncStart, HSyncEnd, HTotal,
+ VDisplay, VSyncStart, VSyncEnd, VTotal);
+
+
+ if (is69030==1) {
+ if (again==1) {
+ again=0;
+ printf("\n\nPipeline B:\n");
+ outb(0x3CD,((IOSS&0xE0)| 0x1F)); /* Select Channel 1 */
+ outb(0x3CB,((MSS&0xF0)| 0xF));
+ goto again;
+ } else {
+ outb(0x3CD,IOSS);
+ outb(0x3CB,MSS);
+ printf("\n\n0x3CB\t0x%X (MSS)\n",inb(0x3CB)&0xFF);
+ printf("0x3CD\t0x%X (IOSS)\n",inb(0x3CD)&0xFF);
+ }
+ }
+ RESET_IOPL();
+ return 0;
+}
diff --git a/util/mRegs.c b/util/mRegs.c
new file mode 100644
index 0000000..4d8da11
--- /dev/null
+++ b/util/mRegs.c
@@ -0,0 +1,186 @@
+/* $XConsortium: mRegs.c /main/2 1996/10/27 11:49:43 kaleb $ */
+
+
+
+
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/util/mRegs.c,v 1.6 2001/11/16 21:13:34 tsi Exp $ */
+
+#ifdef __NetBSD__
+# include <sys/types.h>
+# include <machine/pio.h>
+# include <machine/sysarch.h>
+#else
+# if defined(SVR4) && defined(i386)
+# include <sys/types.h>
+# ifdef NCR
+ /* broken NCR <sys/sysi86.h> */
+# define __STDC
+# include <sys/sysi86.h>
+# undef __STDC
+# else
+# include <sys/sysi86.h>
+# endif
+# ifdef SVR4
+# if !defined(sun)
+# include <sys/seg.h>
+# endif
+# endif
+# include <sys/v86.h>
+# if defined(sun)
+# include <sys/psw.h>
+# endif
+# endif
+# include "AsmMacros.h"
+#endif /* NetBSD */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef __NetBSD__
+# define SET_IOPL() i386_iopl(3)
+# define RESET_IOPL() i386_iopl(0)
+#else
+# if defined(SVR4) && defined(i386)
+# ifndef SI86IOPL
+# define SET_IOPL() sysi86(SI86V86,V86SC_IOPL,PS_IOPL)
+# define RESET_IOPL() sysi86(SI86V86,V86SC_IOPL,0)
+# else
+# define SET_IOPL() sysi86(SI86IOPL,3)
+# define RESET_IOPL() sysi86(SI86IOPL,0)
+# endif
+# else
+# ifdef linux
+# define SET_IOPL() iopl(3)
+# define RESET_IOPL() iopl(0)
+# else
+# define SET_IOPL() (void)0
+# define RESET_IOPL() (void)0
+# endif
+# endif
+#endif
+
+int hex2int(char* str);
+
+int main(int argc, char** argv)
+{
+ int i, value, index = 0;
+ char c, cport;
+ char* str;
+ unsigned int port, port1 = 0;
+ int query = 0;
+
+ if(argc < 2) {
+ printf("usage: %s [Cvvxx [Cvvxx]] [Dxx]\n",argv[0]);
+ printf(" where C = A|a write vv to ARxx\n");
+ printf(" = C|c write vv to CRxx\n");
+ printf(" = F|f write vv to FRxx (6555x only)\n");
+ printf(" = G|g write vv to GRxx\n");
+ printf(" = M|m write vv to MRxx (6555x only)\n");
+ printf(" = S|s write vv to SRxx\n");
+ printf(" = X|x write vv to XRxx\n");
+ printf(" where D = Y|y write xx to FCR\n");
+ printf(" = Z|z write vv to MSR\n");
+ printf(" xx is in hexadecimal\n");
+ printf(" vv is in hexadecimal or '?' for query\n");
+ }
+
+ SET_IOPL();
+
+ for(i = 1; i < argc; i++){
+ value = 0;
+ str = argv[i];
+ c = *str++;
+ switch (c) {
+ case 'f':
+ case 'F':
+ cport = 'F';
+ port = 0x3D0;
+ break;
+ case 'c':
+ case 'C':
+ cport = 'C';
+ port = 0x3D4;
+ break;
+ case 'x':
+ case 'X':
+ cport = 'X';
+ port = 0x3D6;
+ break;
+ case 'g':
+ case 'G':
+ cport = 'G';
+ port = 0x3CE;
+ break;
+ case 'a':
+ case 'A':
+ cport = 'A';
+ port = 0x3C0;
+ break;
+ case 's':
+ case 'S':
+ cport = 'S';
+ port = 0x3C4;
+ break;
+ case 'm':
+ case 'M':
+ cport = 'M';
+ port = 0x3D2;
+ break;
+ case 'y':
+ case 'Y':
+ cport = 'Y';
+ port = 0x3DA;
+ port1 = 0x3CA;
+ break;
+ case 'z':
+ case 'Z':
+ cport = 'Z';
+ port = 0x3C2;
+ port1 = 0x3CC;
+ break;
+ default:
+ continue;
+ break;
+ }
+ if ((cport != 'Z') && (cport != 'Y')) index = inb(port);
+ while ((c = *str++)) {
+ if (c == '?') {
+ query = 1;
+ }
+ if(c >= '0' && c <= '9')
+ value = (value << 4) | (c - '0'); /*ASCII assumed*/
+ else if(c >= 'A' && c < 'G')
+ value = (value << 4) | (c - 'A'+10); /*ASCII assumed*/
+ else if(c >= 'a' && c < 'g')
+ value = (value << 4) | (c - 'a'+10); /*ASCII assumed*/
+ }
+ if ((cport != 'Z') && (cport != 'Y')) outb(port,value&0xFF);
+ if (query) {
+ if ((cport != 'Z') && (cport != 'Y'))
+ printf("%cR%X: 0x%X\n", cport, value & 0xFF,
+ inb(port+1)&0xFF);
+ else
+ if (cport == 'Z')
+ printf("MSR: 0x%X\n", inb(port1)&0xFF);
+ else
+ printf("FCR: 0x%X\n", inb(port1)&0xFF);
+ } else {
+ if ((cport != 'Z') && (cport != 'Y')) {
+ printf("%cR%X: 0x%X -> 0x%X\n", cport, value & 0xFF,
+ inb(port+1)&0xFF, (value&0xFF00)>>8);
+ outw(port, value);
+ outb(port, index &0xFF);
+ } else {
+ if (cport == 'Z')
+ printf("MSR: 0x%X -> 0x%X\n", inb(port1)&0xFF, value&0xFF);
+ else
+ printf("FCR: 0x%X -> 0x%X\n", inb(port1)&0xFF, value&0xFF);
+ outb(port, value & 0xFF);
+ }
+ }
+ }
+ RESET_IOPL();
+ return 0;
+}
diff --git a/util/modClock.c b/util/modClock.c
new file mode 100644
index 0000000..cce4f84
--- /dev/null
+++ b/util/modClock.c
@@ -0,0 +1,412 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/util/modClock.c,v 1.6 2001/11/16 21:13:34 tsi Exp $ */
+
+#ifdef __NetBSD__
+# include <sys/types.h>
+# include <machine/pio.h>
+# include <machine/sysarch.h>
+#else
+# if defined(SVR4) && defined(i386)
+# include <sys/types.h>
+# ifdef NCR
+ /* broken NCR <sys/sysi86.h> */
+# define __STDC
+# include <sys/sysi86.h>
+# undef __STDC
+# else
+# include <sys/sysi86.h>
+# endif
+# ifdef SVR4
+# if !defined(sun)
+# include <sys/seg.h>
+# endif
+# endif
+# include <sys/v86.h>
+# if defined(sun)
+# include <sys/psw.h>
+# endif
+# endif
+# include "AsmMacros.h"
+#endif /* NetBSD */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifndef Lynx
+#include <fnmatch.h>
+#endif
+
+#ifdef __NetBSD__
+# define SET_IOPL() i386_iopl(3)
+# define RESET_IOPL() i386_iopl(0)
+#else
+# if defined(SVR4) && defined(i386)
+# ifndef SI86IOPL
+# define SET_IOPL() sysi86(SI86V86,V86SC_IOPL,PS_IOPL)
+# define RESET_IOPL() sysi86(SI86V86,V86SC_IOPL,0)
+# else
+# define SET_IOPL() sysi86(SI86IOPL,3)
+# define RESET_IOPL() sysi86(SI86IOPL,0)
+# endif
+# else
+# ifdef linux
+# define SET_IOPL() iopl(3)
+# define RESET_IOPL() iopl(0)
+# else
+# define SET_IOPL() (void)0
+# define RESET_IOPL() (void)0
+# endif
+# endif
+#endif
+
+#define tolerance 0.01 /* +/- 1% */
+
+
+#define CT65520 0x1
+#define CT65525 0x2
+#define CT65530 0x3
+#define CT64200 0x4
+
+#define CT65535 0x11
+#define CT65540 0x12
+#define CT65545 0x13
+#define CT65546 0x14
+#define CT65548 0x15
+#define CT64300 0x16
+
+#define CT65550 0x31
+#define CT65554 0x32
+#define CT65555 0x33
+#define CT68554 0x34
+#define CT69000 0x35
+#define CT69030 0x36
+
+#define IS_Programmable(X) X&0x10
+#define IS_HiQV(X) X&0x20
+
+#define DotClk 0
+#define MemClk 1
+#define IS_MemClk(X) X&0x1
+
+int compute_clock (
+ unsigned int ChipType,
+ double target,
+ double Fref,
+ unsigned int ClkMaxN,
+ unsigned int ClkMaxM,
+ unsigned int *bestM,
+ unsigned int *bestN,
+ unsigned int *bestP,
+ unsigned int *bestPSN) {
+
+ unsigned int M, N, P, PSN, PSNx;
+
+ double bestError = 0, abest = 42, bestFout = 0;
+
+ double Fvco, Fout;
+ double error, aerror;
+
+ unsigned int M_min = 3;
+ unsigned int M_max = ClkMaxM;
+
+ if (target < 1e6){
+ fprintf (stderr, "MHz assumed, changed to %g MHz\n", target);
+ target *= 1e6;
+ }
+
+ if (target > 220.0e6) {
+ fprintf (stderr, "too large\n");
+ return 1;
+ }
+
+ /* Other parameters available onthe 65548 but not the 65545, and
+ not documented in the Clock Synthesizer doc in rev 1.0 of the
+ 65548 datasheet:
+
+ + XR30[4] = 0, VCO divider loop uses divide by 4 (same as 65545)
+ 1, VCO divider loop uses divide by 16
+
+ + XR30[5] = 1, reference clock is divided by 5
+
+ I haven't put in any support for those here. For simplicity,
+ they should be set to 0 on the 65548, and left untouched on
+ earlier chips. */
+
+ for (PSNx = ((ChipType == CT69000) || (ChipType == CT69030)) ? 1 : 0;
+ PSNx <= 1; PSNx++) {
+ unsigned int low_N, high_N;
+ double Fref4PSN;
+
+ PSN = PSNx ? 1 : 4;
+
+ low_N = 3;
+ high_N = ClkMaxN;
+
+ while (Fref / (PSN * low_N) > (((ChipType == CT69000) ||
+ (ChipType == CT69030)) ? 5.0e6 : 2.0e6))
+ low_N++;
+ while (Fref / (PSN * high_N) < 150.0e3)
+ high_N--;
+
+ Fref4PSN = Fref * 4 / PSN;
+ for (N = low_N; N <= high_N; N++) {
+ double tmp = Fref4PSN / N;
+
+ for (P = (IS_HiQV(ChipType) && (ChipType != CT69000) &&
+ (ChipType != CT69030)) ? 1 : 0; P <= 5; P++) {
+ double Fvco_desired = target * (1 << P);
+ double M_desired = Fvco_desired / tmp;
+ /* Which way will M_desired be rounded? Do all three just to
+ be safe. */
+ unsigned int M_low = M_desired - 1;
+ unsigned int M_hi = M_desired + 1;
+
+ if (M_hi < M_min || M_low > M_max)
+ continue;
+
+ if (M_low < M_min)
+ M_low = M_min;
+ if (M_hi > M_max)
+ M_hi = M_max;
+
+ for (M = M_low; M <= M_hi; M++) {
+ Fvco = tmp * M;
+ if (Fvco <= ((ChipType == CT69000) || (ChipType == CT69030) ?
+ 100e6 : 48.0e6))
+ continue;
+ if (Fvco > 220.0e6)
+ break;
+
+ Fout = Fvco / (1 << P);
+
+ error = (target - Fout) / target;
+
+ aerror = (error < 0) ? -error : error;
+ if (aerror < abest) {
+ abest = aerror;
+ bestError = error;
+ *bestM = M;
+ *bestN = N;
+ *bestP = P;
+ *bestPSN = PSN;
+ bestFout = Fout;
+ }
+ }
+ }
+ }
+ }
+
+ if (abest < tolerance) {
+ printf ("best: M=%d N=%d P=%d PSN=%d\n", *bestM, *bestN, *bestP, *bestPSN);
+
+ if (bestFout > 1.0e6)
+ printf ("Fout = %g MHz", bestFout / 1.0e6);
+ else if (bestFout > 1.0e3)
+ printf ("Fout = %g kHz", bestFout / 1.0e3);
+ else
+ printf ("Fout = %g Hz", bestFout);
+ printf (", error = %g\n", bestError);
+ return 0;
+ }
+ printf ("can't do it with less than %g error\n", bestError);
+ return 1;
+}
+
+int set_clock(
+ unsigned int ChipType,
+ unsigned int ClockType,
+ unsigned int ProgClock,
+ unsigned int M,
+ unsigned int N,
+ unsigned int P,
+ unsigned int PSN) {
+
+ unsigned int tmp, idx;
+
+ SET_IOPL();
+
+ idx = inb(0x3D6);
+ if (IS_HiQV(ChipType)) {
+ if (IS_MemClk(ClockType)) {
+ printf ("XRCC = 0x%02X\n", M - 2);
+ printf ("XRCD = 0x%02X\n", N - 2);
+ printf ("XRCE = 0x%02X\n", (0x80 | (P * 16 + (PSN == 1))));
+
+ outb(0x3D6, 0xCE); /* Select Fix MClk before */
+ tmp = inb(0x3D7);
+ outb(0x3D7, tmp & 0x7F);
+ outb(0x3D6, 0xCC);
+ outb(0x3D7, (M - 2));
+ outb(0x3D6, 0xCD);
+ outb(0x3D7, (N - 2));
+ outb(0x3D6, 0xCE);
+ outb(0x3D7, (0x80 | (P * 16 + (PSN == 1))));
+ } else {
+ printf ("XR%X = 0x%02X\n", 0xC0 + 4 * ProgClock, M - 2);
+ printf ("XR%X = 0x%02X\n", 0xC1 + 4 * ProgClock, N - 2);
+ printf ("XR%X = 0x%02X\n", 0xC2 + 4 * ProgClock, 0);
+ printf ("XR%X = 0x%02X\n", 0xC3 + 4 * ProgClock, P * 16 + (PSN == 1));
+
+ outb(0x3D6, 0xC0 + 4 * ProgClock);
+ outb(0x3D7, (M - 2));
+ outb(0x3D6, 0xC1 + 4 * ProgClock);
+ outb(0x3D7, (N - 2));
+ outb(0x3D6, 0xC2 + 4 * ProgClock);
+ outb(0x3D7, 0x0);
+ outb(0x3D6, 0xC3 + 4 * ProgClock);
+ outb(0x3D7, (P * 16 + (PSN == 1)));
+ }
+ } else {
+ printf ("XR30 = 0x%02X\n", P * 2 + (PSN == 1));
+ printf ("XR31 = 0x%02X\n", M - 2);
+ printf ("XR32 = 0x%02X\n", N - 2);
+ outb(0x3D6, 0x33);
+ tmp = inb(0x3D7);
+ if (IS_MemClk(ClockType)) {
+ outb(0x3D7, tmp | 0x20);
+ } else {
+ outb(0x3D7, tmp & ~0x20);
+ }
+ outb(0x3D6, 0x30);
+ outb(0x3D7, (P * 2 + (PSN == 1)));
+ outb(0x3D6, 0x31);
+ outb(0x3D7, (M - 2));
+ outb(0x3D6, 0x32);
+ outb(0x3D7, (N - 2));
+ outb(0x3D6, 0x33);
+ outb(0x3D7, tmp);
+ }
+ outb(0x3D6, idx);
+ RESET_IOPL();
+ return 0;
+}
+
+unsigned int probe_chip(void) {
+
+ unsigned int ChipType, temp;
+
+ SET_IOPL();
+
+ outb(0x3D6, 0x00);
+ temp = inb(0x3D7);
+ ChipType = 0;
+ if (temp != 0xA5) {
+ if ((temp & 0xF0) == 0x70) {
+ ChipType = CT65520;
+ }
+ if ((temp & 0xF0) == 0x80) { /* could also be a 65525 */
+ ChipType = CT65530;
+ }
+ if ((temp & 0xF0) == 0xA0) {
+ ChipType = CT64200;
+ }
+ if ((temp & 0xF0) == 0xB0) {
+ ChipType = CT64300;
+ }
+ if ((temp & 0xF0) == 0xC0) {
+ ChipType = CT65535;
+ }
+ if ((temp & 0xF8) == 0xD0) {
+ ChipType = CT65540;
+ }
+ if ((temp & 0xF8) == 0xD8) {
+ switch (temp & 0x07) {
+ case 3:
+ ChipType = CT65546;
+ break;
+ case 4:
+ ChipType = CT65548;
+ break;
+ default:
+ ChipType = CT65545;
+ }
+ }
+ }
+ /* At this point the chip could still be a HiQV, so check for
+ * that. This test needs some looking at */
+ if ((temp != 0) && (ChipType == 0)) {
+ outb(0x3D6, 0x02);
+ temp = inb(0x03D7);
+ if (temp == 0xE0) {
+ ChipType = CT65550;
+ }
+ if (temp == 0xE4) {
+ ChipType = CT65554;
+ }
+ if (temp == 0xE5) {
+ ChipType = CT65555;
+ }
+ if (temp == 0xF4) {
+ ChipType = CT68554;
+ }
+ if (temp == 0xC0) {
+ ChipType = CT69000;
+ }
+ if (temp == 0x30) {
+ outb(0x3D6, 0x03);
+ temp = inb(0x03D7);
+ if (temp == 0x0C) ChipType = CT69030;
+ }
+ }
+
+ RESET_IOPL();
+
+ if (ChipType == 0) { /* failure */
+ fprintf(stderr, "Not a Chips and Technologies Chipset\n");
+ }
+
+ return ChipType;
+}
+
+
+int main (int argc, char *argv[]) {
+ double target;
+ double Fref = 14318180;
+ unsigned int M, N, P, PSN, ChipType, ClockType, progclock;
+
+ switch (argc) {
+ case 2:
+ progclock = 2;
+ target = atof (argv[1]);
+ break;
+ case 3:
+ progclock = abs(atof (argv[1]));
+ target = atof (argv[2]);
+ break;
+ default:
+ fprintf (stderr, "usage: %s [-0|-1|-2] freq\n", argv[0]);
+ return 1;
+ }
+
+ ClockType = DotClk;
+#ifndef Lynx
+ if (! fnmatch("*memClock",argv[0],FNM_PATHNAME)) {
+#else
+ if (strstr("memClock",argv[0]) != NULL) {
+#endif
+ ClockType = MemClk;
+ }
+
+ ChipType = probe_chip();
+ if (!ChipType) {
+ return 1;
+ }
+
+ if (! IS_Programmable(ChipType)) {
+ fprintf(stderr, "No programmable Clock!\n");
+ return 1;
+ }
+
+ if (IS_HiQV(ChipType)) {
+ if (! compute_clock(ChipType, target, Fref, 63, 127, &M, &N, &P, &PSN)) {
+ return set_clock(ChipType, ClockType, progclock, M, N, P, PSN);
+ } else {
+ return 1;
+ }
+ } else {
+ if (! compute_clock(ChipType, target, Fref, 127, 127, &M, &N, &P, &PSN)) {
+ return set_clock(ChipType, ClockType, progclock, M, N, P, PSN);
+ } else {
+ return 1;
+ }
+ }
+}