summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/atiaudio.c47
-rw-r--r--src/atiaudio.h52
-rw-r--r--src/atidecoder.c47
-rw-r--r--src/atidecoder.h52
-rw-r--r--src/atii2c.c387
-rw-r--r--src/atii2c.h50
-rw-r--r--src/atimach64accel.c862
-rw-r--r--src/atimach64accel.h38
-rw-r--r--src/atimach64cursor.c400
-rw-r--r--src/atimach64cursor.h33
-rw-r--r--src/atimach64i2c.c466
-rw-r--r--src/atimach64i2c.h34
-rw-r--r--src/atimach64xv.c1493
-rw-r--r--src/atimach64xv.h40
-rw-r--r--src/atituner.c174
-rw-r--r--src/atituner.h70
16 files changed, 4245 insertions, 0 deletions
diff --git a/src/atiaudio.c b/src/atiaudio.c
new file mode 100644
index 00000000..ada83301
--- /dev/null
+++ b/src/atiaudio.c
@@ -0,0 +1,47 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiaudio.c,v 1.1 2003/07/24 22:08:27 tsi Exp $ */
+/*
+ * Copyright 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+ *
+ * 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 Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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.
+ */
+
+#include "atiaudio.h"
+
+/*
+ * Audio chip definitions.
+ */
+const char *ATIAudioNames[] =
+{
+ "Philips TEA5582",
+ "Mono with audio mux",
+ "Philips TDA9850",
+ "Sony CXA2020S",
+ "ITT MSP3410D",
+ "Crystal CS4236B",
+ "Philips TDA9851",
+ "ITT MSP3415",
+ "ITT MSP3430",
+ "Unknown type (9)",
+ "Unknown type (10)",
+ "Unknown type (11)",
+ "Unknown type (12)",
+ "Unknown type (13)",
+ "Unknown type (14)",
+ "No audio"
+};
diff --git a/src/atiaudio.h b/src/atiaudio.h
new file mode 100644
index 00000000..19080d2b
--- /dev/null
+++ b/src/atiaudio.h
@@ -0,0 +1,52 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiaudio.h,v 1.1 2003/07/24 22:08:27 tsi Exp $ */
+/*
+ * Copyright 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+ *
+ * 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 Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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.
+ */
+
+#ifndef ___ATIAUDIO_H___
+#define ___ATIAUDIO_H___ 1
+
+/*
+ * Audio chip definitions.
+ */
+typedef enum
+{
+ ATI_AUDIO_TEA5582,
+ ATI_AUDIO_MONO,
+ ATI_AUDIO_TDA9850,
+ ATI_AUDIO_CXA2020S,
+ ATI_AUDIO_MSP3410D,
+ ATI_AUDIO_CS4236B,
+ ATI_AUDIO_TDA9851,
+ ATI_AUDIO_MSP3415,
+ ATI_AUDIO_MSP3430,
+ ATI_AUDIO_9,
+ ATI_AUDIO_10,
+ ATI_AUDIO_11,
+ ATI_AUDIO_12,
+ ATI_AUDIO_13,
+ ATI_AUDIO_14,
+ ATI_AUDIO_NONE
+} ATIAudioType;
+
+extern const char *ATIAudioNames[];
+
+#endif /* ___ATIAUDIO_H___ */
diff --git a/src/atidecoder.c b/src/atidecoder.c
new file mode 100644
index 00000000..aee37416
--- /dev/null
+++ b/src/atidecoder.c
@@ -0,0 +1,47 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atidecoder.c,v 1.1 2003/07/24 22:08:28 tsi Exp $ */
+/*
+ * Copyright 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+ *
+ * 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 Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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.
+ */
+
+#include "atidecoder.h"
+
+/*
+ * Video decoder definitions.
+ */
+const char *ATIDecoderNames[] =
+{
+ "No decoder",
+ "BrookTree BT819",
+ "Brooktree BT829",
+ "Brooktree BT829A",
+ "Philips SA7111",
+ "Philips SA7112",
+ "ATI Rage Theater",
+ "Unknown type (7)",
+ "Unknown type (8)",
+ "Unknown type (9)",
+ "Unknown type (10)",
+ "Unknown type (11)",
+ "Unknown type (12)",
+ "Unknown type (13)",
+ "Unknown type (14)",
+ "Unknown type (15)"
+};
diff --git a/src/atidecoder.h b/src/atidecoder.h
new file mode 100644
index 00000000..e88b89f7
--- /dev/null
+++ b/src/atidecoder.h
@@ -0,0 +1,52 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atidecoder.h,v 1.1 2003/07/24 22:08:28 tsi Exp $ */
+/*
+ * Copyright 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+ *
+ * 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 Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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.
+ */
+
+#ifndef ___ATIDECODER_H___
+#define ___ATIDECODER_H___ 1
+
+/*
+ * Video decoder definitions.
+ */
+typedef enum
+{
+ ATI_DECODER_NONE,
+ ATI_DECODER_BT819,
+ ATI_DECODER_BT829,
+ ATI_DECODER_BT829A,
+ ATI_DECODER_SA7111,
+ ATI_DECODER_SA7112,
+ ATI_DECODER_THEATER,
+ ATI_DECODER_7,
+ ATI_DECODER_8,
+ ATI_DECODER_9,
+ ATI_DECODER_10,
+ ATI_DECODER_11,
+ ATI_DECODER_12,
+ ATI_DECODER_13,
+ ATI_DECODER_14,
+ ATI_DECODER_15
+} ATIDecoderType;
+
+extern const char *ATIDecoderNames[];
+
+#endif /* ___ATIDECODER_H___ */
diff --git a/src/atii2c.c b/src/atii2c.c
new file mode 100644
index 00000000..95296537
--- /dev/null
+++ b/src/atii2c.c
@@ -0,0 +1,387 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atii2c.c,v 1.3 2003/11/10 18:41:20 tsi Exp $ */
+/*
+ * Copyright 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+ *
+ * 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 Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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.
+ */
+
+#include "atiadapter.h"
+#include "atii2c.h"
+#include "atiload.h"
+#include "atimach64i2c.h"
+#include "atistruct.h"
+
+#include "xf86.h"
+
+/* This is derived from GATOS code, with a liberal sprinkling of bug fixes */
+
+/*
+ * Some local macros for use by the mid-level I2C functions.
+ */
+
+#define ATII2CDelay \
+ (*pI2CBus->I2CUDelay)(pI2CBus, pI2CBus->HoldTime)
+
+
+#define ATII2CSCLDirOff \
+ if (pATII2C->SCLDir != 0) \
+ (*pATII2C->I2CSetBits)(pATII2C, pATI, \
+ pATII2C->I2CCur & ~pATII2C->SCLDir)
+
+#define ATII2CSCLDirOn \
+ if (pATII2C->SCLDir != 0) \
+ (*pATII2C->I2CSetBits)(pATII2C, pATI, \
+ pATII2C->I2CCur | pATII2C->SCLDir)
+
+#define ATII2CSDADirOff \
+ if (pATII2C->SDADir != 0) \
+ (*pATII2C->I2CSetBits)(pATII2C, pATI, \
+ pATII2C->I2CCur & ~pATII2C->SDADir)
+
+#define ATII2CSDADirOn \
+ if (pATII2C->SDADir != 0) \
+ (*pATII2C->I2CSetBits)(pATII2C, pATI, \
+ pATII2C->I2CCur | pATII2C->SDADir)
+
+
+#define ATII2CSCLBitGet \
+ ((*pATII2C->I2CGetBits)(pATI) & pATII2C->SCLGet)
+
+#define ATII2CSCLBitOff \
+ do \
+ { \
+ (*pATII2C->I2CSetBits)(pATII2C, pATI, \
+ pATII2C->I2CCur & ~pATII2C->SCLSet); \
+ ATII2CDelay; \
+ } while (0)
+
+#define ATII2CSCLBitOn \
+ do \
+ { \
+ (*pATII2C->I2CSetBits)(pATII2C, pATI, \
+ pATII2C->I2CCur | pATII2C->SCLSet); \
+ do /* Wait until all devices have released SCL */ \
+ { \
+ ATII2CDelay; \
+ } while (ATII2CSCLBitGet == 0); \
+ } while (0)
+
+
+#define ATII2CSDABitGet \
+ ((*pATII2C->I2CGetBits)(pATI) & pATII2C->SDAGet)
+
+#define ATII2CSDABitOff \
+ do \
+ { \
+ (*pATII2C->I2CSetBits)(pATII2C, pATI, \
+ pATII2C->I2CCur & ~pATII2C->SDASet); \
+ ATII2CDelay; \
+ } while (0)
+
+#define ATII2CSDABitOn \
+ do \
+ { \
+ (*pATII2C->I2CSetBits)(pATII2C, pATI, \
+ pATII2C->I2CCur | pATII2C->SDASet); \
+ ATII2CDelay; \
+ } while (0)
+
+#define ATII2CSDABitSet(_flag) \
+ do \
+ { \
+ if (_flag) \
+ ATII2CSDABitOn; \
+ else \
+ ATII2CSDABitOff; \
+ } while (0)
+
+
+/*
+ * ATII2CAddress --
+ *
+ * This function puts a Start bit and an 8-bit address on the I2C bus.
+ */
+static Bool
+ATII2CAddress
+(
+ I2CDevPtr pI2CDev,
+ I2CSlaveAddr Address
+)
+{
+ I2CBusPtr pI2CBus = pI2CDev->pI2CBus;
+ ATII2CPtr pATII2C = pI2CBus->DriverPrivate.ptr;
+ ATIPtr pATI = pATII2C->pATI;
+
+ /*
+ * Set I2C line directions to out-bound. SCL will remain out-bound until
+ * next I2C Stop.
+ */
+ ATII2CSCLDirOn;
+ ATII2CSDADirOn;
+
+ /*
+ * Send Start bit. This is a pull-down of the data line while the clock
+ * line is pulled up.
+ */
+ ATII2CSDABitOn;
+ ATII2CSCLBitOn;
+ ATII2CSDABitOff;
+ ATII2CSCLBitOff;
+
+ /* Send low byte of device address */
+ if ((*pI2CBus->I2CPutByte)(pI2CDev, (I2CByte)Address))
+ {
+ /* Send top byte of address, if appropriate */
+ if (((Address & 0x00F8U) != 0x00F0U) &&
+ ((Address & 0x00FEU) != 0x0000U))
+ return TRUE;
+
+ if ((*pI2CBus->I2CPutByte)(pI2CDev, (I2CByte)(Address >> 8)))
+ return TRUE;
+ }
+
+ /* Kill I2C transaction on failure */
+ (*pI2CBus->I2CStop)(pI2CDev);
+ return FALSE;
+}
+
+/*
+ * ATII2CStop --
+ *
+ * This function puts a stop signal on the I2C bus.
+ */
+static void
+ATII2CStop
+(
+ I2CDevPtr pI2CDev
+)
+{
+ I2CBusPtr pI2CBus = pI2CDev->pI2CBus;
+ ATII2CPtr pATII2C = pI2CBus->DriverPrivate.ptr;
+ ATIPtr pATI = pATII2C->pATI;
+
+ ATII2CSDADirOn; /* Set data line direction to out-bound */
+
+ /*
+ * Send Stop bit. This is a pull-up of the data line while the clock line
+ * is pulled up.
+ */
+ ATII2CSDABitOff;
+ ATII2CSCLBitOn;
+ ATII2CSDABitOn;
+ ATII2CSCLBitOff;
+
+ /* Reset I2C line directions to in-bound */
+ ATII2CSCLDirOff;
+ ATII2CSDADirOff;
+}
+
+/*
+ * ATII2CPutByte --
+ *
+ * This function puts an 8-bit value on the I2C bus, starting with its MSB.
+ */
+static Bool
+ATII2CPutByte
+(
+ I2CDevPtr pI2CDev,
+ I2CByte Data
+)
+{
+ I2CBusPtr pI2CBus = pI2CDev->pI2CBus;
+ ATII2CPtr pATII2C = pI2CBus->DriverPrivate.ptr;
+ ATIPtr pATI = pATII2C->pATI;
+ int i;
+ Bool Result;
+
+ ATII2CSDADirOn; /* Set data line direction to out-bound */
+
+ /* Send data byte */
+ for (i = 0; i < 8; i++)
+ {
+ ATII2CSDABitSet(Data & 0x80U);
+ ATII2CSCLBitOn;
+ ATII2CSCLBitOff;
+
+ Data <<= 1;
+ }
+
+ ATII2CSDABitOn; /* Release data line */
+
+ ATII2CSDADirOff; /* Set data line direction to in-bound */
+
+ ATII2CSCLBitOn; /* Start bit-read clock pulse */
+
+ /* Get [N]ACK bit */
+ if (ATII2CSDABitGet)
+ Result = FALSE;
+ else
+ Result = TRUE;
+
+ ATII2CSCLBitOff; /* End clock pulse */
+
+ return Result;
+}
+
+/*
+ * ATII2CGetByte --
+ *
+ * This function retrieves an 8-bit value from the I2C bus.
+ */
+static Bool
+ATII2CGetByte
+(
+ I2CDevPtr pI2CDev,
+ I2CByte *pData,
+ Bool Last
+)
+{
+ I2CBusPtr pI2CBus = pI2CDev->pI2CBus;
+ ATII2CPtr pATII2C = pI2CBus->DriverPrivate.ptr;
+ ATIPtr pATI = pATII2C->pATI;
+ unsigned long Value = 1;
+
+ do
+ {
+ ATII2CSCLBitOn; /* Start bit-read clock pulse */
+
+ /* Accumulate bit into byte value */
+ Value <<= 1;
+ if (ATII2CSDABitGet)
+ Value++;
+
+ ATII2CSCLBitOff; /* End clock pulse */
+ } while (Value <= (unsigned long)((I2CByte)(-1)));
+
+ *pData = (I2CByte)Value;
+
+ ATII2CSDADirOn; /* Set data line direction to out-bound */
+
+ /* Send [N]ACK bit */
+ ATII2CSDABitSet(Last);
+ ATII2CSCLBitOn;
+ ATII2CSCLBitOff;
+
+ if (!Last)
+ ATII2CSDABitOn; /* Release data line */
+
+ ATII2CSDADirOff; /* Set data line direction to in-bound */
+
+ return TRUE;
+}
+
+/*
+ * ATICreateI2CBusRec --
+ *
+ * This function is called to initialise an I2CBusRec.
+ */
+I2CBusPtr
+ATICreateI2CBusRec
+(
+ int iScreen,
+ ATIPtr pATI,
+ char *BusName
+)
+{
+ I2CBusPtr pI2CBus;
+ ATII2CPtr pATII2C = xnfcalloc(1, SizeOf(ATII2CRec));
+
+ if (!(pI2CBus = xf86CreateI2CBusRec()))
+ {
+ xf86DrvMsg(iScreen, X_WARNING, "Unable to allocate I2C Bus record.\n");
+ xfree(pATII2C);
+ return NULL;
+ }
+
+ /* Fill in generic structure fields */
+ pI2CBus->BusName = BusName;
+ pI2CBus->scrnIndex = iScreen;
+
+ pI2CBus->I2CAddress = ATII2CAddress;
+ pI2CBus->I2CStop = ATII2CStop;
+ pI2CBus->I2CPutByte = ATII2CPutByte;
+ pI2CBus->I2CGetByte = ATII2CGetByte;
+
+ pI2CBus->DriverPrivate.ptr = pATII2C;
+
+ pATII2C->pATI = pATI;
+
+ if (xf86I2CBusInit(pI2CBus))
+ return pI2CBus;
+
+ xf86DrvMsg(iScreen, X_WARNING,
+ "I2C bus %s initialisation failure.\n", BusName);
+ xf86DestroyI2CBusRec(pI2CBus, TRUE, TRUE);
+ xfree(pATII2C);
+ return NULL;
+}
+
+/*
+ * ATII2CPreInit --
+ *
+ * This is called by ATIPreInit() to create I2C bus record(s) for the adapter.
+ */
+void
+ATII2CPreInit
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI
+)
+{
+ switch (pATI->Adapter)
+ {
+ case ATI_ADAPTER_MACH64:
+ if (!ATILoadModule(pScreenInfo, "i2c", ATIi2cSymbols))
+ return;
+
+ ATIMach64I2CPreInit(pScreenInfo, pATI);
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*
+ * ATII2CFreeScreen --
+ *
+ * This is called by ATIFreeScreen() to remove the driver's I2C interface.
+ */
+void
+ATII2CFreeScreen
+(
+ int iScreen
+)
+{
+ I2CBusPtr pI2CBus, *ppI2CBus;
+ ATII2CPtr pATII2C;
+ int nI2CBus;
+
+ nI2CBus = xf86I2CGetScreenBuses(iScreen, &ppI2CBus);
+ while (--nI2CBus >= 0)
+ {
+ pI2CBus = ppI2CBus[nI2CBus];
+ pATII2C = pI2CBus->DriverPrivate.ptr;
+
+ xf86DestroyI2CBusRec(pI2CBus, TRUE, TRUE);
+ xfree(pATII2C);
+ }
+
+ xfree(ppI2CBus);
+}
diff --git a/src/atii2c.h b/src/atii2c.h
new file mode 100644
index 00000000..ddc0d977
--- /dev/null
+++ b/src/atii2c.h
@@ -0,0 +1,50 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atii2c.h,v 1.1 2003/07/24 22:08:28 tsi Exp $ */
+/*
+ * Copyright 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+ *
+ * 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 Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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.
+ */
+
+#ifndef ___ATII2C_H___
+#define ___ATII2C_H___ 1
+
+#include "atipriv.h"
+#include "atiproto.h"
+
+#include "xf86str.h"
+
+#include "xf86i2c.h"
+
+typedef struct _ATII2CRec ATII2CRec, *ATII2CPtr;
+
+struct _ATII2CRec
+{
+ ATIPtr pATI;
+ void (*I2CSetBits) FunctionPrototype((ATII2CPtr, ATIPtr, CARD32));
+ CARD32 (*I2CGetBits) FunctionPrototype((ATIPtr));
+ CARD32 SCLDir, SCLGet, SCLSet;
+ CARD32 SDADir, SDAGet, SDASet;
+ CARD32 I2CCur;
+};
+
+extern void ATII2CPreInit FunctionPrototype((ScrnInfoPtr, ATIPtr));
+extern I2CBusPtr ATICreateI2CBusRec FunctionPrototype((int, ATIPtr, char *));
+extern void ATII2CFreeScreen FunctionPrototype((int));
+
+#endif /* ___ATII2C_H___ */
diff --git a/src/atimach64accel.c b/src/atimach64accel.c
new file mode 100644
index 00000000..12029187
--- /dev/null
+++ b/src/atimach64accel.c
@@ -0,0 +1,862 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64accel.c,v 1.1 2003/04/23 21:51:28 tsi Exp $ */
+/*
+ * Copyright 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+ *
+ * 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 Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 1999-2000 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "ati.h"
+#include "atichip.h"
+#include "atimach64accel.h"
+#include "atimach64io.h"
+#include "atipriv.h"
+#include "atiregs.h"
+
+#include "miline.h"
+
+/* Used to test MMIO cache integrity in ATIMach64Sync() */
+#define TestRegisterCaching(_Register) \
+ if (RegisterIsCached(_Register) && \
+ (CacheSlot(_Register) != inm(_Register))) \
+ { \
+ UncacheRegister(_Register); \
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, \
+ #_Register " MMIO write cache disabled!\n"); \
+ }
+
+/*
+ * X-to-Mach64 mix translation table.
+ */
+static CARD8 ATIMach64ALU[16] =
+{
+ MIX_0, /* GXclear */
+ MIX_AND, /* GXand */
+ MIX_SRC_AND_NOT_DST, /* GXandReverse */
+ MIX_SRC, /* GXcopy */
+ MIX_NOT_SRC_AND_DST, /* GXandInverted */
+ MIX_DST, /* GXnoop */
+ MIX_XOR, /* GXxor */
+ MIX_OR, /* GXor */
+ MIX_NOR, /* GXnor */
+ MIX_XNOR, /* GXequiv */
+ MIX_NOT_DST, /* GXinvert */
+ MIX_SRC_OR_NOT_DST, /* GXorReverse */
+ MIX_NOT_SRC, /* GXcopyInverted */
+ MIX_NOT_SRC_OR_DST, /* GXorInverted */
+ MIX_NAND, /* GXnand */
+ MIX_1 /* GXset */
+};
+
+/*
+ * ATIMach64ValidateClip --
+ *
+ * This function ensures the current scissor settings do not interfere with
+ * the current draw request.
+ */
+static void
+ATIMach64ValidateClip
+(
+ ATIPtr pATI,
+ int sc_left,
+ int sc_right,
+ int sc_top,
+ int sc_bottom
+)
+{
+ if ((sc_left < (int)pATI->sc_left) || (sc_right > (int)pATI->sc_right))
+ {
+ outf(SC_LEFT_RIGHT, pATI->sc_left_right);
+ pATI->sc_left = pATI->NewHW.sc_left;
+ pATI->sc_right = pATI->NewHW.sc_right;
+ }
+
+ if ((sc_top < (int)pATI->sc_top) || (sc_bottom > (int)pATI->sc_bottom))
+ {
+ outf(SC_TOP_BOTTOM, pATI->sc_top_bottom);
+ pATI->sc_top = pATI->NewHW.sc_top;
+ pATI->sc_bottom = pATI->NewHW.sc_bottom;
+ }
+}
+
+/*
+ * ATIMach64Sync --
+ *
+ * This is called to wait for the draw engine to become idle.
+ */
+void
+ATIMach64Sync
+(
+ ScrnInfoPtr pScreenInfo
+)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ ATIMach64WaitForIdle(pATI);
+ if (pATI->pXAAInfo)
+ pATI->pXAAInfo->NeedToSync = FALSE;
+
+ if (pATI->OptionMMIOCache && pATI->OptionTestMMIOCache)
+ {
+ /*
+ * For debugging purposes, attempt to verify that each cached register
+ * should actually be cached.
+ */
+ TestRegisterCaching(SRC_CNTL);
+
+ TestRegisterCaching(HOST_CNTL);
+
+ TestRegisterCaching(PAT_REG0);
+ TestRegisterCaching(PAT_REG1);
+ TestRegisterCaching(PAT_CNTL);
+
+ if (RegisterIsCached(SC_LEFT_RIGHT) && /* Special case */
+ (CacheSlot(SC_LEFT_RIGHT) !=
+ (SetWord(inm(SC_RIGHT), 1) | SetWord(inm(SC_LEFT), 0))))
+ {
+ UncacheRegister(SC_LEFT_RIGHT);
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "SC_LEFT_RIGHT write cache disabled!\n");
+ }
+
+ if (RegisterIsCached(SC_TOP_BOTTOM) && /* Special case */
+ (CacheSlot(SC_TOP_BOTTOM) !=
+ (SetWord(inm(SC_BOTTOM), 1) | SetWord(inm(SC_TOP), 0))))
+ {
+ UncacheRegister(SC_TOP_BOTTOM);
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "SC_TOP_BOTTOM write cache disabled!\n");
+ }
+
+ TestRegisterCaching(DP_BKGD_CLR);
+ TestRegisterCaching(DP_FRGD_CLR);
+ TestRegisterCaching(DP_WRITE_MASK);
+ TestRegisterCaching(DP_MIX);
+
+ TestRegisterCaching(CLR_CMP_CLR);
+ TestRegisterCaching(CLR_CMP_MSK);
+ TestRegisterCaching(CLR_CMP_CNTL);
+
+ if (pATI->Block1Base)
+ {
+ TestRegisterCaching(OVERLAY_Y_X_START);
+ TestRegisterCaching(OVERLAY_Y_X_END);
+
+ TestRegisterCaching(OVERLAY_GRAPHICS_KEY_CLR);
+ TestRegisterCaching(OVERLAY_GRAPHICS_KEY_MSK);
+
+ TestRegisterCaching(OVERLAY_KEY_CNTL);
+
+ TestRegisterCaching(OVERLAY_SCALE_INC);
+ TestRegisterCaching(OVERLAY_SCALE_CNTL);
+
+ TestRegisterCaching(SCALER_HEIGHT_WIDTH);
+
+ TestRegisterCaching(SCALER_TEST);
+
+ TestRegisterCaching(VIDEO_FORMAT);
+
+ if (pATI->Chip < ATI_CHIP_264VTB)
+ {
+ TestRegisterCaching(BUF0_OFFSET);
+ TestRegisterCaching(BUF0_PITCH);
+ TestRegisterCaching(BUF1_OFFSET);
+ TestRegisterCaching(BUF1_PITCH);
+ }
+ else
+ {
+ TestRegisterCaching(SCALER_BUF0_OFFSET);
+ TestRegisterCaching(SCALER_BUF1_OFFSET);
+ TestRegisterCaching(SCALER_BUF_PITCH);
+
+ TestRegisterCaching(OVERLAY_EXCLUSIVE_HORZ);
+ TestRegisterCaching(OVERLAY_EXCLUSIVE_VERT);
+
+ if (pATI->Chip >= ATI_CHIP_264GTPRO)
+ {
+ TestRegisterCaching(SCALER_COLOUR_CNTL);
+
+ TestRegisterCaching(SCALER_H_COEFF0);
+ TestRegisterCaching(SCALER_H_COEFF1);
+ TestRegisterCaching(SCALER_H_COEFF2);
+ TestRegisterCaching(SCALER_H_COEFF3);
+ TestRegisterCaching(SCALER_H_COEFF4);
+
+ TestRegisterCaching(SCALER_BUF0_OFFSET_U);
+ TestRegisterCaching(SCALER_BUF0_OFFSET_V);
+ TestRegisterCaching(SCALER_BUF1_OFFSET_U);
+ TestRegisterCaching(SCALER_BUF1_OFFSET_V);
+ }
+ }
+ }
+ }
+
+ /*
+ * For VTB's and later, the first CPU read of the framebuffer will return
+ * zeroes, so do it here. This appears to be due to some kind of engine
+ * caching of framebuffer data I haven't found any way of disabling, or
+ * otherwise circumventing. Thanks to Mark Vojkovich for the suggestion.
+ */
+ pATI = *(volatile ATIPtr *)pATI->pMemory;
+}
+
+/*
+ * ATIMach64SetupForScreenToScreenCopy --
+ *
+ * This function sets up the draw engine for a series of screen-to-screen copy
+ * operations.
+ */
+static void
+ATIMach64SetupForScreenToScreenCopy
+(
+ ScrnInfoPtr pScreenInfo,
+ int xdir,
+ int ydir,
+ int rop,
+ unsigned int planemask,
+ int TransparencyColour
+)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ ATIMach64WaitForFIFO(pATI, 3);
+ outf(DP_WRITE_MASK, planemask);
+ outf(DP_SRC, DP_MONO_SRC_ALLONES |
+ SetBits(SRC_BLIT, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC));
+ outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX));
+
+#ifdef AVOID_DGA
+
+ if (TransparencyColour == -1)
+
+#else /* AVOID_DGA */
+
+ if (!pATI->XAAForceTransBlit && (TransparencyColour == -1))
+
+#endif /* AVOID_DGA */
+
+ {
+ outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE);
+ }
+ else
+ {
+ ATIMach64WaitForFIFO(pATI, 2);
+ outf(CLR_CMP_CLR, TransparencyColour);
+ outf(CLR_CMP_CNTL, CLR_CMP_FN_EQUAL | CLR_CMP_SRC_2D);
+ }
+
+ pATI->dst_cntl = 0;
+
+ if (ydir > 0)
+ pATI->dst_cntl |= DST_Y_DIR;
+ if (xdir > 0)
+ pATI->dst_cntl |= DST_X_DIR;
+
+ if (pATI->XModifier == 1)
+ outf(DST_CNTL, pATI->dst_cntl);
+ else
+ pATI->dst_cntl |= DST_24_ROT_EN;
+}
+
+/*
+ * ATIMach64SubsequentScreenToScreenCopy --
+ *
+ * This function performs a screen-to-screen copy operation.
+ */
+static void
+ATIMach64SubsequentScreenToScreenCopy
+(
+ ScrnInfoPtr pScreenInfo,
+ int xSrc,
+ int ySrc,
+ int xDst,
+ int yDst,
+ int w,
+ int h
+)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ xSrc *= pATI->XModifier;
+ xDst *= pATI->XModifier;
+ w *= pATI->XModifier;
+
+ /* Disable clipping if it gets in the way */
+ ATIMach64ValidateClip(pATI, xDst, xDst + w - 1, yDst, yDst + h - 1);
+
+ if (!(pATI->dst_cntl & DST_X_DIR))
+ {
+ xSrc += w - 1;
+ xDst += w - 1;
+ }
+
+ if (!(pATI->dst_cntl & DST_Y_DIR))
+ {
+ ySrc += h - 1;
+ yDst += h - 1;
+ }
+
+ if (pATI->XModifier != 1)
+ outf(DST_CNTL, pATI->dst_cntl | SetBits((xDst / 4) % 6, DST_24_ROT));
+
+ ATIMach64WaitForFIFO(pATI, 4);
+ outf(SRC_Y_X, SetWord(xSrc, 1) | SetWord(ySrc, 0));
+ outf(SRC_WIDTH1, w);
+ outf(DST_Y_X, SetWord(xDst, 1) | SetWord(yDst, 0));
+ outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0));
+}
+
+/*
+ * ATIMach64SetupForSolidFill --
+ *
+ * This function sets up the draw engine for a series of solid fills.
+ */
+static void
+ATIMach64SetupForSolidFill
+(
+ ScrnInfoPtr pScreenInfo,
+ int colour,
+ int rop,
+ unsigned int planemask
+)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ ATIMach64WaitForFIFO(pATI, 5);
+ outf(DP_WRITE_MASK, planemask);
+ outf(DP_SRC, DP_MONO_SRC_ALLONES |
+ SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC));
+ outf(DP_FRGD_CLR, colour);
+ outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX));
+
+ outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE);
+
+ if (pATI->XModifier == 1)
+ outf(DST_CNTL, DST_X_DIR | DST_Y_DIR);
+}
+
+/*
+ * ATIMach64SubsequentSolidFillRect --
+ *
+ * This function performs a solid rectangle fill.
+ */
+static void
+ATIMach64SubsequentSolidFillRect
+(
+ ScrnInfoPtr pScreenInfo,
+ int x,
+ int y,
+ int w,
+ int h
+)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ if (pATI->XModifier != 1)
+ {
+ x *= pATI->XModifier;
+ w *= pATI->XModifier;
+
+ outf(DST_CNTL, SetBits((x / 4) % 6, DST_24_ROT) |
+ (DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN));
+ }
+
+ /* Disable clipping if it gets in the way */
+ ATIMach64ValidateClip(pATI, x, x + w - 1, y, y + h - 1);
+
+ ATIMach64WaitForFIFO(pATI, 2);
+ outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0));
+ outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0));
+}
+
+/*
+ * ATIMach64SetupForSolidLine --
+ *
+ * This function sets up the draw engine for a series of solid lines. It is
+ * not used for 24bpp because the engine doesn't support it.
+ */
+static void
+ATIMach64SetupForSolidLine
+(
+ ScrnInfoPtr pScreenInfo,
+ int colour,
+ int rop,
+ unsigned int planemask
+)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ ATIMach64WaitForFIFO(pATI, 5);
+ outf(DP_WRITE_MASK, planemask);
+ outf(DP_SRC, DP_MONO_SRC_ALLONES |
+ SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC));
+ outf(DP_FRGD_CLR, colour);
+ outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX));
+
+ outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE);
+
+ ATIMach64ValidateClip(pATI, pATI->NewHW.sc_left, pATI->NewHW.sc_right,
+ pATI->NewHW.sc_top, pATI->NewHW.sc_bottom);
+}
+
+/*
+ * ATIMach64SubsequentSolidHorVertLine --
+ *
+ * This is called to draw a solid horizontal or vertical line. This does a
+ * one-pixel wide solid fill.
+ */
+static void
+ATIMach64SubsequentSolidHorVertLine
+(
+ ScrnInfoPtr pScreenInfo,
+ int x,
+ int y,
+ int len,
+ int dir
+)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ ATIMach64WaitForFIFO(pATI, 3);
+ outf(DST_CNTL, DST_X_DIR | DST_Y_DIR);
+ outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0));
+
+ if (dir == DEGREES_0)
+ outf(DST_HEIGHT_WIDTH, SetWord(len, 1) | SetWord(1, 0));
+ else /* if (dir == DEGREES_270) */
+ outf(DST_HEIGHT_WIDTH, SetWord(1, 1) | SetWord(len, 0));
+}
+
+/*
+ * ATIMach64SubsequentSolidBresenhamLine --
+ *
+ * This function draws a line using the Bresenham line engine.
+ */
+static void
+ATIMach64SubsequentSolidBresenhamLine
+(
+ ScrnInfoPtr pScreenInfo,
+ int x,
+ int y,
+ int major,
+ int minor,
+ int err,
+ int len,
+ int octant
+)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ CARD32 dst_cntl = DST_LAST_PEL;
+
+ if (octant & YMAJOR)
+ dst_cntl |= DST_Y_MAJOR;
+
+ if (!(octant & XDECREASING))
+ dst_cntl |= DST_X_DIR;
+
+ if (!(octant & YDECREASING))
+ dst_cntl |= DST_Y_DIR;
+
+ ATIMach64WaitForFIFO(pATI, 6);
+ outf(DST_CNTL, dst_cntl);
+ outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0));
+ outf(DST_BRES_ERR, minor + err);
+ outf(DST_BRES_INC, minor);
+ outf(DST_BRES_DEC, minor - major);
+ outf(DST_BRES_LNTH, len);
+}
+
+/*
+ * ATIMach64SetupForMono8x8PatternFill --
+ *
+ * This function sets up the draw engine for a series of 8x8 1bpp pattern
+ * fills.
+ */
+static void
+ATIMach64SetupForMono8x8PatternFill
+(
+ ScrnInfoPtr pScreenInfo,
+ int patx,
+ int paty,
+ int fg,
+ int bg,
+ int rop,
+ unsigned int planemask
+)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ ATIMach64WaitForFIFO(pATI, 3);
+ outf(DP_WRITE_MASK, planemask);
+ outf(DP_SRC, DP_MONO_SRC_PATTERN |
+ SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC));
+ outf(DP_FRGD_CLR, fg);
+
+ if (bg == -1)
+ {
+ outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX) |
+ SetBits(MIX_DST, DP_BKGD_MIX));
+ }
+ else
+ {
+ ATIMach64WaitForFIFO(pATI, 2);
+ outf(DP_BKGD_CLR, bg);
+ outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX) |
+ SetBits(ATIMach64ALU[rop], DP_BKGD_MIX));
+ }
+
+ ATIMach64WaitForFIFO(pATI, 4);
+ outf(PAT_REG0, patx);
+ outf(PAT_REG1, paty);
+ outf(PAT_CNTL, PAT_MONO_EN);
+
+ outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE);
+
+ if (pATI->XModifier == 1)
+ outf(DST_CNTL, DST_X_DIR | DST_Y_DIR);
+}
+
+/*
+ * ATIMach64SubsequentMono8x8PatternFillRect --
+ *
+ * This function performs an 8x8 1bpp pattern fill.
+ */
+static void
+ATIMach64SubsequentMono8x8PatternFillRect
+(
+ ScrnInfoPtr pScreenInfo,
+ int patx,
+ int paty,
+ int x,
+ int y,
+ int w,
+ int h
+)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ if (pATI->XModifier != 1)
+ {
+ x *= pATI->XModifier;
+ w *= pATI->XModifier;
+
+ outf(DST_CNTL, SetBits((x / 4) % 6, DST_24_ROT) |
+ (DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN));
+ }
+
+ /* Disable clipping if it gets in the way */
+ ATIMach64ValidateClip(pATI, x, x + w - 1, y, y + h - 1);
+
+ ATIMach64WaitForFIFO(pATI, 2);
+ outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0));
+ outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0));
+}
+
+/*
+ * ATIMach64SetupForScanlineCPUToScreenColorExpandFill --
+ *
+ * This function sets up the engine for a series of colour expansion fills.
+ */
+static void
+ATIMach64SetupForScanlineCPUToScreenColorExpandFill
+(
+ ScrnInfoPtr pScreenInfo,
+ int fg,
+ int bg,
+ int rop,
+ unsigned int planemask
+)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ ATIMach64WaitForFIFO(pATI, 3);
+ outf(DP_WRITE_MASK, planemask);
+ outf(DP_SRC, DP_MONO_SRC_HOST |
+ SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC));
+ outf(DP_FRGD_CLR, fg);
+
+ if (bg == -1)
+ {
+ outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX) |
+ SetBits(MIX_DST, DP_BKGD_MIX));
+ }
+ else
+ {
+ ATIMach64WaitForFIFO(pATI, 2);
+ outf(DP_BKGD_CLR, bg);
+ outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX) |
+ SetBits(ATIMach64ALU[rop], DP_BKGD_MIX));
+ }
+
+ outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE);
+
+ if (pATI->XModifier == 1)
+ outf(DST_CNTL, DST_X_DIR | DST_Y_DIR);
+}
+
+/*
+ * ATIMach64SubsequentScanlineCPUToScreenColorExpandFill --
+ *
+ * This function sets up the engine for a single colour expansion fill.
+ */
+static void
+ATIMach64SubsequentScanlineCPUToScreenColorExpandFill
+(
+ ScrnInfoPtr pScreenInfo,
+ int x,
+ int y,
+ int w,
+ int h,
+ int skipleft
+)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ if (pATI->XModifier != 1)
+ {
+ x *= pATI->XModifier;
+ w *= pATI->XModifier;
+ skipleft *= pATI->XModifier;
+
+ outf(DST_CNTL, SetBits((x / 4) % 6, DST_24_ROT) |
+ (DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN));
+ }
+
+ pATI->ExpansionBitmapWidth = (w + 31) / 32;
+
+ ATIMach64WaitForFIFO(pATI, 3);
+ pATI->sc_left = x + skipleft;
+ pATI->sc_right = x + w - 1;
+ outf(SC_LEFT_RIGHT,
+ SetWord(pATI->sc_right, 1) | SetWord(pATI->sc_left, 0));
+ outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0));
+ outf(DST_HEIGHT_WIDTH,
+ SetWord(pATI->ExpansionBitmapWidth * 32, 1) | SetWord(h, 0));
+}
+
+/*
+ * ATIMach64SubsequentColorExpandScanline --
+ *
+ * This function feeds a bitmap scanline to the engine for a colour expansion
+ * fill. This is written to do burst transfers for those platforms that can do
+ * them, and to improve CPU/engine concurrency.
+ */
+static void
+ATIMach64SubsequentColorExpandScanline
+(
+ ScrnInfoPtr pScreenInfo,
+ int iBuffer
+)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ CARD32 *pBitmapData = pATI->ExpansionBitmapScanlinePtr[iBuffer];
+ int w = pATI->ExpansionBitmapWidth;
+ int nDWord;
+
+ while (w > 0)
+ {
+ /*
+ * Transfers are done in chunks of up to 64 bytes in length (32 on
+ * earlier controllers).
+ */
+ nDWord = w;
+ if (nDWord > pATI->nHostFIFOEntries)
+ nDWord = pATI->nHostFIFOEntries;
+
+ /* Make enough FIFO slots available */
+ ATIMach64WaitForFIFO(pATI, nDWord);
+
+ /*
+ * Always start transfers on a chuck-sized boundary. Note that
+ * HOST_DATA_0 is actually on a 512-byte boundary, but *pBitmapData can
+ * only be guaranteed to be on a chunk-sized boundary.
+ *
+ * Transfer current chunk. With any luck, the compiler won't mangle
+ * this too badly...
+ */
+
+# if defined(ATIMove32)
+
+ {
+ ATIMove32(pATI->pHOST_DATA, pBitmapData, nDWord);
+ }
+
+# else
+
+ {
+ volatile CARD32 *pDst;
+ CARD32 *pSrc;
+ unsigned int iDWord;
+
+ iDWord = 16 - nDWord;
+ pDst = (volatile CARD32 *)pATI->pHOST_DATA - iDWord;
+ pSrc = pBitmapData - iDWord;
+
+ switch (iDWord)
+ {
+ case 0: MMIO_MOVE32(pDst + 0, 0, *(pSrc + 0));
+ case 1: MMIO_MOVE32(pDst + 1, 0, *(pSrc + 1));
+ case 2: MMIO_MOVE32(pDst + 2, 0, *(pSrc + 2));
+ case 3: MMIO_MOVE32(pDst + 3, 0, *(pSrc + 3));
+ case 4: MMIO_MOVE32(pDst + 4, 0, *(pSrc + 4));
+ case 5: MMIO_MOVE32(pDst + 5, 0, *(pSrc + 5));
+ case 6: MMIO_MOVE32(pDst + 6, 0, *(pSrc + 6));
+ case 7: MMIO_MOVE32(pDst + 7, 0, *(pSrc + 7));
+ case 8: MMIO_MOVE32(pDst + 8, 0, *(pSrc + 8));
+ case 9: MMIO_MOVE32(pDst + 9, 0, *(pSrc + 9));
+ case 10: MMIO_MOVE32(pDst + 10, 0, *(pSrc + 10));
+ case 11: MMIO_MOVE32(pDst + 11, 0, *(pSrc + 11));
+ case 12: MMIO_MOVE32(pDst + 12, 0, *(pSrc + 12));
+ case 13: MMIO_MOVE32(pDst + 13, 0, *(pSrc + 13));
+ case 14: MMIO_MOVE32(pDst + 14, 0, *(pSrc + 14));
+ case 15: MMIO_MOVE32(pDst + 15, 0, *(pSrc + 15));
+
+ default: /* Muffle compiler */
+ break;
+ }
+ }
+
+# endif
+
+ /* Step to next chunk */
+ pBitmapData += nDWord;
+ w -= nDWord;
+ pATI->nAvailableFIFOEntries -= nDWord;
+ }
+
+ pATI->EngineIsBusy = TRUE;
+}
+
+/*
+ * ATIMach64AccelInit --
+ *
+ * This function fills in structure fields needed for acceleration on Mach64
+ * variants.
+ */
+int
+ATIMach64AccelInit
+(
+ ATIPtr pATI,
+ XAAInfoRecPtr pXAAInfo
+)
+{
+ /* This doesn't seem quite right... */
+ if (pATI->XModifier == 1)
+ {
+ pXAAInfo->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS;
+
+#ifndef AVOID_CPIO
+
+ if (!pATI->BankInfo.BankSize)
+
+#endif /* AVOID_CPIO */
+
+ {
+ pXAAInfo->Flags |= LINEAR_FRAMEBUFFER;
+ }
+ }
+
+ /* Sync */
+ pXAAInfo->Sync = ATIMach64Sync;
+
+ /* Screen-to-screen copy */
+ pXAAInfo->SetupForScreenToScreenCopy = ATIMach64SetupForScreenToScreenCopy;
+ pXAAInfo->SubsequentScreenToScreenCopy =
+ ATIMach64SubsequentScreenToScreenCopy;
+
+ /* Solid fills */
+ pXAAInfo->SetupForSolidFill = ATIMach64SetupForSolidFill;
+ pXAAInfo->SubsequentSolidFillRect = ATIMach64SubsequentSolidFillRect;
+
+ /* 8x8 mono pattern fills */
+ pXAAInfo->Mono8x8PatternFillFlags =
+
+#if X_BYTE_ORDER != X_LITTLE_ENDIAN
+
+ BIT_ORDER_IN_BYTE_MSBFIRST |
+
+#endif /* X_BYTE_ORDER */
+
+ HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_SCREEN_ORIGIN;
+ pXAAInfo->SetupForMono8x8PatternFill = ATIMach64SetupForMono8x8PatternFill;
+ pXAAInfo->SubsequentMono8x8PatternFillRect =
+ ATIMach64SubsequentMono8x8PatternFillRect;
+
+ /*
+ * Use scanline version of colour expansion, not only for the non-ix86
+ * case, but also to avoid PCI retries.
+ */
+ pXAAInfo->ScanlineCPUToScreenColorExpandFillFlags =
+ LEFT_EDGE_CLIPPING | LEFT_EDGE_CLIPPING_NEGATIVE_X |
+ CPU_TRANSFER_PAD_DWORD | SCANLINE_PAD_DWORD;
+ if (pATI->XModifier != 1)
+ pXAAInfo->ScanlineCPUToScreenColorExpandFillFlags |= TRIPLE_BITS_24BPP;
+ pXAAInfo->NumScanlineColorExpandBuffers = 1;
+
+ /* Align bitmap data on a 64-byte boundary */
+ pATI->ExpansionBitmapWidth = /* DWord size in bits */
+ ((pATI->displayWidth * pATI->XModifier) + 31) & ~31U;
+ pATI->ExpansionBitmapScanlinePtr[1] =
+ (CARD32 *)xnfalloc((pATI->ExpansionBitmapWidth >> 3) + 63);
+ pATI->ExpansionBitmapScanlinePtr[0] =
+ (pointer)(((unsigned long)pATI->ExpansionBitmapScanlinePtr[1] + 63) &
+ ~63UL);
+ pXAAInfo->ScanlineColorExpandBuffers =
+ (CARD8 **)pATI->ExpansionBitmapScanlinePtr;
+ pXAAInfo->SetupForScanlineCPUToScreenColorExpandFill =
+ ATIMach64SetupForScanlineCPUToScreenColorExpandFill;
+ pXAAInfo->SubsequentScanlineCPUToScreenColorExpandFill =
+ ATIMach64SubsequentScanlineCPUToScreenColorExpandFill;
+ pXAAInfo->SubsequentColorExpandScanline =
+ ATIMach64SubsequentColorExpandScanline;
+
+ /* The engine does not support the following primitives for 24bpp */
+ if (pATI->XModifier != 1)
+ return ATIMach64MaxY;
+
+ /* Solid lines */
+ pXAAInfo->SetupForSolidLine = ATIMach64SetupForSolidLine;
+ pXAAInfo->SubsequentSolidHorVertLine = ATIMach64SubsequentSolidHorVertLine;
+ pXAAInfo->SubsequentSolidBresenhamLine =
+ ATIMach64SubsequentSolidBresenhamLine;
+
+ return ATIMach64MaxY;
+}
diff --git a/src/atimach64accel.h b/src/atimach64accel.h
new file mode 100644
index 00000000..88f90a05
--- /dev/null
+++ b/src/atimach64accel.h
@@ -0,0 +1,38 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64accel.h,v 1.1 2003/04/23 21:51:29 tsi Exp $ */
+/*
+ * Copyright 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+ *
+ * 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 Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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.
+ */
+
+#ifndef ___ATIMACH64ACCEL_H___
+#define ___ATIMACH64ACCEL_H___ 1
+
+#include "atipriv.h"
+#include "atiproto.h"
+
+#include "xaa.h"
+
+#define ATIMach64MaxX 8191
+#define ATIMach64MaxY 32767
+
+extern int ATIMach64AccelInit FunctionPrototype((ATIPtr, XAAInfoRecPtr));
+extern void ATIMach64Sync FunctionPrototype((ScrnInfoPtr));
+
+#endif /* ___ATIMACH64ACCEL_H___ */
diff --git a/src/atimach64cursor.c b/src/atimach64cursor.c
new file mode 100644
index 00000000..8cd76dba
--- /dev/null
+++ b/src/atimach64cursor.c
@@ -0,0 +1,400 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64cursor.c,v 1.1 2003/04/23 21:51:29 tsi Exp $ */
+/*
+ * Copyright 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+ *
+ * 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 Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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.
+ */
+
+#include "ati.h"
+#include "aticrtc.h"
+#include "atimach64accel.h"
+#include "atimach64cursor.h"
+#include "atimach64io.h"
+
+/*
+ * ATIMach64SetCursorColours --
+ *
+ * Set hardware cursor foreground and background colours.
+ */
+static void
+ATIMach64SetCursorColours
+(
+ ScrnInfoPtr pScreenInfo,
+ int fg,
+ int bg
+)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ outr(CUR_CLR0, SetBits(fg, CUR_CLR));
+ outr(CUR_CLR1, SetBits(bg, CUR_CLR));
+}
+
+/*
+ * ATIMach64SetCursorPosition --
+ *
+ * Set position of hardware cursor.
+ */
+static void
+ATIMach64SetCursorPosition
+(
+ ScrnInfoPtr pScreenInfo,
+ int x,
+ int y
+)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ CARD16 CursorXOffset, CursorYOffset;
+
+ /* Adjust x & y when the cursor is partially obscured */
+ if (x < 0)
+ {
+ if ((CursorXOffset = -x) > 63)
+ CursorXOffset = 63;
+ x = 0;
+ }
+ else
+ {
+ CursorXOffset = pScreenInfo->frameX1 - pScreenInfo->frameX0;
+ if (x > CursorXOffset)
+ x = CursorXOffset;
+ CursorXOffset = 0;
+ }
+
+ if (y < 0)
+ {
+ if ((CursorYOffset = -y) > 63)
+ CursorYOffset = 63;
+ y = 0;
+ }
+ else
+ {
+ CursorYOffset = pScreenInfo->frameY1 - pScreenInfo->frameY0;
+ if (y > CursorYOffset)
+ y = CursorYOffset;
+ CursorYOffset = 0;
+ }
+
+ /* Adjust for multiscanned modes */
+ if (pScreenInfo->currentMode->Flags & V_DBLSCAN)
+ y *= 2;
+ if (pScreenInfo->currentMode->VScan > 1)
+ y *= pScreenInfo->currentMode->VScan;
+
+ do
+ {
+ if (CursorYOffset != pATI->CursorYOffset)
+ {
+ pATI->CursorYOffset = CursorYOffset;
+ outr(CUR_OFFSET, ((CursorYOffset << 4) + pATI->CursorOffset) >> 3);
+ }
+ else if (CursorXOffset == pATI->CursorXOffset)
+ break;
+
+ pATI->CursorXOffset = CursorXOffset;
+ outr(CUR_HORZ_VERT_OFF, SetBits(CursorXOffset, CUR_HORZ_OFF) |
+ SetBits(CursorYOffset, CUR_VERT_OFF));
+ } while (0);
+
+ outr(CUR_HORZ_VERT_POSN,
+ SetBits(x, CUR_HORZ_POSN) | SetBits(y, CUR_VERT_POSN));
+}
+
+/*
+ * ATIMach64LoadCursorImage --
+ *
+ * Copy hardware cursor image into offscreen video memory.
+ */
+static void
+ATIMach64LoadCursorImage
+(
+ ScrnInfoPtr pScreenInfo,
+ CARD8 *pImage
+)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ CARD32 *pSrc = (pointer)pImage;
+ volatile CARD32 *pDst = pATI->pCursorImage;
+
+ /* Synchronise video memory accesses */
+ ATIMach64Sync(pScreenInfo);
+
+# if defined(ATIMove32)
+
+ {
+ ATIMove32(pDst, pSrc, 256);
+ }
+
+# else
+
+ {
+ /* This is lengthy, but it does maximise burst modes */
+ pDst[ 0] = pSrc[ 0]; pDst[ 1] = pSrc[ 1];
+ pDst[ 2] = pSrc[ 2]; pDst[ 3] = pSrc[ 3];
+ pDst[ 4] = pSrc[ 4]; pDst[ 5] = pSrc[ 5];
+ pDst[ 6] = pSrc[ 6]; pDst[ 7] = pSrc[ 7];
+ pDst[ 8] = pSrc[ 8]; pDst[ 9] = pSrc[ 9];
+ pDst[ 10] = pSrc[ 10]; pDst[ 11] = pSrc[ 11];
+ pDst[ 12] = pSrc[ 12]; pDst[ 13] = pSrc[ 13];
+ pDst[ 14] = pSrc[ 14]; pDst[ 15] = pSrc[ 15];
+ pDst[ 16] = pSrc[ 16]; pDst[ 17] = pSrc[ 17];
+ pDst[ 18] = pSrc[ 18]; pDst[ 19] = pSrc[ 19];
+ pDst[ 20] = pSrc[ 20]; pDst[ 21] = pSrc[ 21];
+ pDst[ 22] = pSrc[ 22]; pDst[ 23] = pSrc[ 23];
+ pDst[ 24] = pSrc[ 24]; pDst[ 25] = pSrc[ 25];
+ pDst[ 26] = pSrc[ 26]; pDst[ 27] = pSrc[ 27];
+ pDst[ 28] = pSrc[ 28]; pDst[ 29] = pSrc[ 29];
+ pDst[ 30] = pSrc[ 30]; pDst[ 31] = pSrc[ 31];
+ pDst[ 32] = pSrc[ 32]; pDst[ 33] = pSrc[ 33];
+ pDst[ 34] = pSrc[ 34]; pDst[ 35] = pSrc[ 35];
+ pDst[ 36] = pSrc[ 36]; pDst[ 37] = pSrc[ 37];
+ pDst[ 38] = pSrc[ 38]; pDst[ 39] = pSrc[ 39];
+ pDst[ 40] = pSrc[ 40]; pDst[ 41] = pSrc[ 41];
+ pDst[ 42] = pSrc[ 42]; pDst[ 43] = pSrc[ 43];
+ pDst[ 44] = pSrc[ 44]; pDst[ 45] = pSrc[ 45];
+ pDst[ 46] = pSrc[ 46]; pDst[ 47] = pSrc[ 47];
+ pDst[ 48] = pSrc[ 48]; pDst[ 49] = pSrc[ 49];
+ pDst[ 50] = pSrc[ 50]; pDst[ 51] = pSrc[ 51];
+ pDst[ 52] = pSrc[ 52]; pDst[ 53] = pSrc[ 53];
+ pDst[ 54] = pSrc[ 54]; pDst[ 55] = pSrc[ 55];
+ pDst[ 56] = pSrc[ 56]; pDst[ 57] = pSrc[ 57];
+ pDst[ 58] = pSrc[ 58]; pDst[ 59] = pSrc[ 59];
+ pDst[ 60] = pSrc[ 60]; pDst[ 61] = pSrc[ 61];
+ pDst[ 62] = pSrc[ 62]; pDst[ 63] = pSrc[ 63];
+ pDst[ 64] = pSrc[ 64]; pDst[ 65] = pSrc[ 65];
+ pDst[ 66] = pSrc[ 66]; pDst[ 67] = pSrc[ 67];
+ pDst[ 68] = pSrc[ 68]; pDst[ 69] = pSrc[ 69];
+ pDst[ 70] = pSrc[ 70]; pDst[ 71] = pSrc[ 71];
+ pDst[ 72] = pSrc[ 72]; pDst[ 73] = pSrc[ 73];
+ pDst[ 74] = pSrc[ 74]; pDst[ 75] = pSrc[ 75];
+ pDst[ 76] = pSrc[ 76]; pDst[ 77] = pSrc[ 77];
+ pDst[ 78] = pSrc[ 78]; pDst[ 79] = pSrc[ 79];
+ pDst[ 80] = pSrc[ 80]; pDst[ 81] = pSrc[ 81];
+ pDst[ 82] = pSrc[ 82]; pDst[ 83] = pSrc[ 83];
+ pDst[ 84] = pSrc[ 84]; pDst[ 85] = pSrc[ 85];
+ pDst[ 86] = pSrc[ 86]; pDst[ 87] = pSrc[ 87];
+ pDst[ 88] = pSrc[ 88]; pDst[ 89] = pSrc[ 89];
+ pDst[ 90] = pSrc[ 90]; pDst[ 91] = pSrc[ 91];
+ pDst[ 92] = pSrc[ 92]; pDst[ 93] = pSrc[ 93];
+ pDst[ 94] = pSrc[ 94]; pDst[ 95] = pSrc[ 95];
+ pDst[ 96] = pSrc[ 96]; pDst[ 97] = pSrc[ 97];
+ pDst[ 98] = pSrc[ 98]; pDst[ 99] = pSrc[ 99];
+ pDst[100] = pSrc[100]; pDst[101] = pSrc[101];
+ pDst[102] = pSrc[102]; pDst[103] = pSrc[103];
+ pDst[104] = pSrc[104]; pDst[105] = pSrc[105];
+ pDst[106] = pSrc[106]; pDst[107] = pSrc[107];
+ pDst[108] = pSrc[108]; pDst[109] = pSrc[109];
+ pDst[110] = pSrc[110]; pDst[111] = pSrc[111];
+ pDst[112] = pSrc[112]; pDst[113] = pSrc[113];
+ pDst[114] = pSrc[114]; pDst[115] = pSrc[115];
+ pDst[116] = pSrc[116]; pDst[117] = pSrc[117];
+ pDst[118] = pSrc[118]; pDst[119] = pSrc[119];
+ pDst[120] = pSrc[120]; pDst[121] = pSrc[121];
+ pDst[122] = pSrc[122]; pDst[123] = pSrc[123];
+ pDst[124] = pSrc[124]; pDst[125] = pSrc[125];
+ pDst[126] = pSrc[126]; pDst[127] = pSrc[127];
+ pDst[128] = pSrc[128]; pDst[129] = pSrc[129];
+ pDst[130] = pSrc[130]; pDst[131] = pSrc[131];
+ pDst[132] = pSrc[132]; pDst[133] = pSrc[133];
+ pDst[134] = pSrc[134]; pDst[135] = pSrc[135];
+ pDst[136] = pSrc[136]; pDst[137] = pSrc[137];
+ pDst[138] = pSrc[138]; pDst[139] = pSrc[139];
+ pDst[140] = pSrc[140]; pDst[141] = pSrc[141];
+ pDst[142] = pSrc[142]; pDst[143] = pSrc[143];
+ pDst[144] = pSrc[144]; pDst[145] = pSrc[145];
+ pDst[146] = pSrc[146]; pDst[147] = pSrc[147];
+ pDst[148] = pSrc[148]; pDst[149] = pSrc[149];
+ pDst[150] = pSrc[150]; pDst[151] = pSrc[151];
+ pDst[152] = pSrc[152]; pDst[153] = pSrc[153];
+ pDst[154] = pSrc[154]; pDst[155] = pSrc[155];
+ pDst[156] = pSrc[156]; pDst[157] = pSrc[157];
+ pDst[158] = pSrc[158]; pDst[159] = pSrc[159];
+ pDst[160] = pSrc[160]; pDst[161] = pSrc[161];
+ pDst[162] = pSrc[162]; pDst[163] = pSrc[163];
+ pDst[164] = pSrc[164]; pDst[165] = pSrc[165];
+ pDst[166] = pSrc[166]; pDst[167] = pSrc[167];
+ pDst[168] = pSrc[168]; pDst[169] = pSrc[169];
+ pDst[170] = pSrc[170]; pDst[171] = pSrc[171];
+ pDst[172] = pSrc[172]; pDst[173] = pSrc[173];
+ pDst[174] = pSrc[174]; pDst[175] = pSrc[175];
+ pDst[176] = pSrc[176]; pDst[177] = pSrc[177];
+ pDst[178] = pSrc[178]; pDst[179] = pSrc[179];
+ pDst[180] = pSrc[180]; pDst[181] = pSrc[181];
+ pDst[182] = pSrc[182]; pDst[183] = pSrc[183];
+ pDst[184] = pSrc[184]; pDst[185] = pSrc[185];
+ pDst[186] = pSrc[186]; pDst[187] = pSrc[187];
+ pDst[188] = pSrc[188]; pDst[189] = pSrc[189];
+ pDst[190] = pSrc[190]; pDst[191] = pSrc[191];
+ pDst[192] = pSrc[192]; pDst[193] = pSrc[193];
+ pDst[194] = pSrc[194]; pDst[195] = pSrc[195];
+ pDst[196] = pSrc[196]; pDst[197] = pSrc[197];
+ pDst[198] = pSrc[198]; pDst[199] = pSrc[199];
+ pDst[200] = pSrc[200]; pDst[201] = pSrc[201];
+ pDst[202] = pSrc[202]; pDst[203] = pSrc[203];
+ pDst[204] = pSrc[204]; pDst[205] = pSrc[205];
+ pDst[206] = pSrc[206]; pDst[207] = pSrc[207];
+ pDst[208] = pSrc[208]; pDst[209] = pSrc[209];
+ pDst[210] = pSrc[210]; pDst[211] = pSrc[211];
+ pDst[212] = pSrc[212]; pDst[213] = pSrc[213];
+ pDst[214] = pSrc[214]; pDst[215] = pSrc[215];
+ pDst[216] = pSrc[216]; pDst[217] = pSrc[217];
+ pDst[218] = pSrc[218]; pDst[219] = pSrc[219];
+ pDst[220] = pSrc[220]; pDst[221] = pSrc[221];
+ pDst[222] = pSrc[222]; pDst[223] = pSrc[223];
+ pDst[224] = pSrc[224]; pDst[225] = pSrc[225];
+ pDst[226] = pSrc[226]; pDst[227] = pSrc[227];
+ pDst[228] = pSrc[228]; pDst[229] = pSrc[229];
+ pDst[230] = pSrc[230]; pDst[231] = pSrc[231];
+ pDst[232] = pSrc[232]; pDst[233] = pSrc[233];
+ pDst[234] = pSrc[234]; pDst[235] = pSrc[235];
+ pDst[236] = pSrc[236]; pDst[237] = pSrc[237];
+ pDst[238] = pSrc[238]; pDst[239] = pSrc[239];
+ pDst[240] = pSrc[240]; pDst[241] = pSrc[241];
+ pDst[242] = pSrc[242]; pDst[243] = pSrc[243];
+ pDst[244] = pSrc[244]; pDst[245] = pSrc[245];
+ pDst[246] = pSrc[246]; pDst[247] = pSrc[247];
+ pDst[248] = pSrc[248]; pDst[249] = pSrc[249];
+ pDst[250] = pSrc[250]; pDst[251] = pSrc[251];
+ pDst[252] = pSrc[252]; pDst[253] = pSrc[253];
+ pDst[254] = pSrc[254]; pDst[255] = pSrc[255];
+ }
+
+#endif
+
+}
+
+/*
+ * ATIMach64HideCursor --
+ *
+ * Turn off hardware cursor.
+ */
+static void
+ATIMach64HideCursor
+(
+ ScrnInfoPtr pScreenInfo
+)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ if (!(pATI->NewHW.gen_test_cntl & GEN_CUR_EN))
+ return;
+
+ pATI->NewHW.gen_test_cntl &= ~GEN_CUR_EN;
+ out8(GEN_TEST_CNTL, GetByte(pATI->NewHW.gen_test_cntl, 0));
+}
+
+/*
+ * ATIMach64ShowCursor --
+ *
+ * Turn on hardware cursor.
+ */
+static void
+ATIMach64ShowCursor
+(
+ ScrnInfoPtr pScreenInfo
+)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ if (pATI->NewHW.gen_test_cntl & GEN_CUR_EN)
+ return;
+
+ pATI->NewHW.gen_test_cntl |= GEN_CUR_EN;
+ out8(GEN_TEST_CNTL, GetByte(pATI->NewHW.gen_test_cntl, 0));
+}
+
+/*
+ * ATIMach64UseHWCursor --
+ *
+ * Notify cursor layer whether a hardware cursor is configured.
+ */
+static Bool
+ATIMach64UseHWCursor
+(
+ ScreenPtr pScreen,
+ CursorPtr pCursor
+)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ if (!pATI->CursorBase)
+ return FALSE;
+
+#ifndef AVOID_CPIO
+
+ /*
+ * For some reason, the hardware cursor isn't vertically scaled when a VGA
+ * doublescanned or multiscanned mode is in effect.
+ */
+ if (pATI->NewHW.crtc == ATI_CRTC_MACH64)
+ return TRUE;
+ if ((pScreenInfo->currentMode->Flags & V_DBLSCAN) ||
+ (pScreenInfo->currentMode->VScan > 1))
+ return FALSE;
+
+#endif /* AVOID_CPIO */
+
+ return TRUE;
+}
+
+/*
+ * ATIMach64CursorInit --
+ *
+ * Initialise xf86CursorInfoRec fields with information specific to Mach64
+ * variants.
+ */
+Bool
+ATIMach64CursorInit
+(
+ xf86CursorInfoPtr pCursorInfo
+)
+{
+ /*
+ * For Mach64 variants, toggling hardware cursors off and on causes display
+ * artifacts. Ask the cursor support layers to always paint the cursor
+ * (whether or not it is entirely transparent) and to not hide the cursor
+ * when reloading its image. The two remaining reasons for turning off the
+ * hardware cursor are when it moves to a different screen or on a switch
+ * to a different virtual console.
+ */
+ pCursorInfo->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_INVERT_MASK |
+ HARDWARE_CURSOR_SHOW_TRANSPARENT |
+ HARDWARE_CURSOR_UPDATE_UNHIDDEN |
+ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
+
+#if X_BYTE_ORDER != X_LITTLE_ENDIAN
+
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+
+#endif /* X_BYTE_ORDER */
+
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1;
+ pCursorInfo->MaxWidth = pCursorInfo->MaxHeight = 64;
+
+ pCursorInfo->SetCursorColors = ATIMach64SetCursorColours;
+ pCursorInfo->SetCursorPosition = ATIMach64SetCursorPosition;
+ pCursorInfo->LoadCursorImage = ATIMach64LoadCursorImage;
+ pCursorInfo->HideCursor = ATIMach64HideCursor;
+ pCursorInfo->ShowCursor = ATIMach64ShowCursor;
+ pCursorInfo->UseHWCursor = ATIMach64UseHWCursor;
+
+ return TRUE;
+}
diff --git a/src/atimach64cursor.h b/src/atimach64cursor.h
new file mode 100644
index 00000000..6439f131
--- /dev/null
+++ b/src/atimach64cursor.h
@@ -0,0 +1,33 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64cursor.h,v 1.1 2003/04/23 21:51:29 tsi Exp $ */
+/*
+ * Copyright 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+ *
+ * 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 Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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.
+ */
+
+#ifndef ___ATIMACH64CURSOR_H___
+#define ___ATIMACH64CURSOR_H___ 1
+
+#include "atiproto.h"
+
+#include "xf86Cursor.h"
+
+extern Bool ATIMach64CursorInit FunctionPrototype((xf86CursorInfoPtr));
+
+#endif /* ___ATIMACH64CURSOR_H___ */
diff --git a/src/atimach64i2c.c b/src/atimach64i2c.c
new file mode 100644
index 00000000..4cb565f6
--- /dev/null
+++ b/src/atimach64i2c.c
@@ -0,0 +1,466 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64i2c.c,v 1.1 2003/07/24 22:08:28 tsi Exp $ */
+/*
+ * Copyright 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+ *
+ * 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 Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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.
+ */
+
+#include "ati.h"
+#include "atichip.h"
+#include "atii2c.h"
+#include "atimach64i2c.h"
+#include "atimach64io.h"
+#include "atituner.h"
+
+/* MPP_CONFIG register values */
+#define MPP_INIT pATI->NewHW.mpp_config
+
+#define MPP_WRITE (MPP_INIT )
+#define MPP_WRITEINC (MPP_INIT | (MPP_AUTO_INC_EN ))
+#define MPP_READ (MPP_INIT | ( MPP_BUFFER_MODE_PREFETCH))
+#define MPP_READINC (MPP_INIT | (MPP_AUTO_INC_EN | MPP_BUFFER_MODE_PREFETCH))
+
+/*
+ * ATIMach64MPPWaitForIdle --
+ *
+ * Support function to wait for the Multimedia Peripheral Port to become idle.
+ * Currently, this function's return value indicates whether or not the port
+ * became idle within 512 polling iterations. For now, this value is ignored
+ * by the rest of the code, but might be used in the future.
+ */
+static Bool
+ATIMach64MPPWaitForIdle
+(
+ ATIPtr pATI
+)
+{
+ CARD32 Count = 0x0200;
+
+ while (in8(MPP_CONFIG + 3) & GetByte(MPP_BUSY, 3))
+ {
+ if (!--Count)
+ return FALSE;
+ usleep(1); /* XXX Excessive? */
+ }
+
+ return TRUE;
+}
+
+/*
+ * ATIMach64MPPSetAddress --
+ *
+ * Sets a 16-bit ImpacTV address on the Multimedia Peripheral Port.
+ */
+static void
+ATIMach64MPPSetAddress
+(
+ ATIPtr pATI,
+ CARD16 Address
+)
+{
+ ATIMach64MPPWaitForIdle(pATI);
+ outr(MPP_CONFIG, MPP_WRITEINC);
+ outr(MPP_ADDR, 0x00000008U);
+ out8(MPP_DATA, (CARD8)Address);
+ ATIMach64MPPWaitForIdle(pATI);
+ out8(MPP_DATA, (CARD8)(Address >> 8));
+ ATIMach64MPPWaitForIdle(pATI);
+ outr(MPP_CONFIG, MPP_WRITE);
+ outr(MPP_ADDR, 0x00000018U);
+ ATIMach64MPPWaitForIdle(pATI);
+}
+
+/*
+ * ATIMach64ImpacTVProbe --
+ *
+ * This probes for an ImpacTV chip and returns its chip ID, or 0.
+ */
+static int
+ATIMach64ImpacTVProbe
+(
+ int iScreen,
+ ATIPtr pATI
+)
+{
+ CARD8 ChipID = 0;
+
+ /* Assume ATIModePreInit() has already been called */
+ outr(MPP_STROBE_SEQ, pATI->NewHW.mpp_strobe_seq);
+ outr(TVO_CNTL, pATI->NewHW.tvo_cntl);
+
+ outr(MPP_CONFIG, MPP_READ);
+ ATIMach64MPPWaitForIdle(pATI);
+ outr(MPP_ADDR, 0x0000000AU);
+ if (!(ChipID = in8(MPP_DATA)))
+ {
+ ATIMach64MPPWaitForIdle(pATI);
+ outr(MPP_ADDR, 0x00000023U);
+ if ((ChipID = in8(MPP_DATA)) != 0x54U)
+ {
+ ATIMach64MPPWaitForIdle(pATI);
+ outr(MPP_ADDR, 0x0000000BU);
+ ChipID = in8(MPP_DATA);
+ }
+ }
+ ATIMach64MPPWaitForIdle(pATI);
+ outr(MPP_CONFIG, MPP_WRITE);
+
+ if (ChipID)
+ xf86DrvMsg(iScreen, X_PROBED, "ImpacTV chip ID 0x%02X detected.\n",
+ ChipID);
+
+ return (int)(CARD16)ChipID;
+}
+
+/*
+ * ATIMach64ImpacTVSetBits --
+ *
+ * Controls I2C SDA and SCL lines through ImpacTV.
+ */
+static void
+ATIMach64ImpacTVSetBits
+(
+ ATII2CPtr pATII2C,
+ ATIPtr pATI,
+ CARD32 Bits
+)
+{
+ pATII2C->I2CCur = Bits;
+
+ ATIMach64MPPSetAddress(pATI, IT_I2C_CNTL);
+
+ outr(MPP_CONFIG, MPP_WRITE);
+
+ out8(MPP_DATA, (CARD8)Bits);
+
+ ATIMach64MPPWaitForIdle(pATI);
+}
+
+/*
+ * ATIMach64ImpacTVGetBits --
+ *
+ * Returns the status of an ImpacTV's I2C control lines.
+ */
+static CARD32
+ATIMach64ImpacTVGetBits
+(
+ ATIPtr pATI
+)
+{
+ ATIMach64MPPSetAddress(pATI, IT_I2C_CNTL);
+
+ outr(MPP_CONFIG, MPP_READ);
+
+ ATIMach64MPPWaitForIdle(pATI);
+
+ return in8(MPP_DATA);
+}
+
+/*
+ * ATIMach64I2C_CNTLSetBits --
+ *
+ * Controls SDA and SCL lines through a 3D Rage Pro's hardware assisted I2C.
+ */
+static void
+ATIMach64I2C_CNTLSetBits
+(
+ ATII2CPtr pATII2C,
+ ATIPtr pATI,
+ CARD32 Bits
+)
+{
+ pATII2C->I2CCur = Bits;
+
+ out8(I2C_CNTL_0 + 1, (CARD8)Bits);
+}
+
+/*
+ * ATIMach64I2C_CNTLGetBits --
+ *
+ * Returns the status of a 3D Rage Pro's hardware assisted I2C control lines.
+ */
+static CARD32
+ATIMach64I2C_CNTLGetBits
+(
+ ATIPtr pATI
+)
+{
+ return in8(I2C_CNTL_0 + 1);
+}
+
+/*
+ * ATIMach64GP_IOSetBits --
+ *
+ * Controls SDA and SCL control lines through a Mach64's GP_IO register.
+ */
+static void
+ATIMach64GP_IOSetBits
+(
+ ATII2CPtr pATII2C,
+ ATIPtr pATI,
+ CARD32 Bits
+)
+{
+ pATII2C->I2CCur = Bits;
+
+ outr(GP_IO, Bits);
+}
+
+/*
+ * ATIMach64GP_IOGetBits --
+ *
+ * Returns the status of I2C control lines through a Mach64's GP_IO register.
+ */
+static CARD32
+ATIMach64GP_IOGetBits
+(
+ ATIPtr pATI
+)
+{
+ return inr(GP_IO);
+}
+
+#define GPIO1_MASK \
+ (DAC_GIO_STATE_1 | DAC_GIO_DIR_1)
+#define GPIO2_MASK \
+ (GEN_GIO2_DATA_OUT | GEN_GIO2_DATA_IN | GEN_GIO2_WRITE)
+
+/*
+ * ATIMach64DAC_GENSetBits --
+ *
+ * Controls SDA and SCL control lines through a Mach64's GEN_TEST_CNTL and
+ * DAC_CNTL registers.
+ */
+static void
+ATIMach64DAC_GENSetBits
+(
+ ATII2CPtr pATII2C,
+ ATIPtr pATI,
+ CARD32 Bits
+)
+{
+ CARD32 tmp;
+
+ pATII2C->I2CCur = Bits;
+
+ tmp = inr(DAC_CNTL) & ~GPIO1_MASK;
+ outr(DAC_CNTL, tmp | (Bits & GPIO1_MASK));
+ tmp = inr(GEN_TEST_CNTL) & ~GPIO2_MASK;
+ outr(GEN_TEST_CNTL, tmp | (Bits & GPIO2_MASK));
+}
+
+/*
+ * ATIMach64DAC_GENGetBits --
+ *
+ * Returns the status of I2C control lines through a Mach64's GEN_TEST_CNTL and
+ * DAC_CNTL registers.
+ */
+static CARD32
+ATIMach64DAC_GENGetBits
+(
+ ATIPtr pATI
+)
+{
+ return (inr(DAC_CNTL) & GPIO1_MASK) | (inr(GEN_TEST_CNTL) & GPIO2_MASK);
+}
+
+/*
+ * ATITVAddOnProbe --
+ *
+ * Probe for an ATI-TV add-on card at specific addresses on an I2C bus.
+ */
+static Bool
+ATITVAddOnProbe
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ I2CBusPtr pI2CBus
+)
+{
+ I2CDevPtr pI2CDev = xnfcalloc(1, SizeOf(I2CDevRec));
+ int Index;
+ I2CByte tmp;
+
+ static const CARD8 ATITVAddOnAddresses[] = {0x70, 0x40, 0x78, 0x72, 0x42};
+
+ pI2CDev->DevName = "ATI-TV Add-on";
+ pI2CDev->pI2CBus = pI2CBus;
+ pI2CDev->StartTimeout = pI2CBus->StartTimeout;
+ pI2CDev->BitTimeout = pI2CBus->BitTimeout;
+ pI2CDev->AcknTimeout = pI2CBus->AcknTimeout;
+ pI2CDev->ByteTimeout = pI2CBus->ByteTimeout;
+
+ for (Index = 0; Index < NumberOf(ATITVAddOnAddresses); Index++)
+ {
+ pI2CDev->SlaveAddr = ATITVAddOnAddresses[Index];
+
+ if (xf86I2CFindDev(pI2CBus, pI2CDev->SlaveAddr))
+ continue;
+
+ tmp = 0xFFU;
+
+ if (!(*pI2CBus->I2CWriteRead)(pI2CDev, &tmp, 1, NULL, 0) ||
+ !(*pI2CBus->I2CWriteRead)(pI2CDev, NULL, 0, &tmp, 1) ||
+ (tmp == 0xFFU) || ((tmp = tmp & 0x1FU) == /*ATI_TUNER_NONE*/0))
+ continue;
+
+ if (!xf86I2CDevInit(pI2CDev))
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Failed to register I2C device for ATI-TV add-on.\n");
+ break;
+ }
+
+ if (pATI->Tuner != tmp)
+ {
+ if (pATI->Tuner != ATI_TUNER_NONE)
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Tuner type mismatch: BIOS 0x%x, ATI-TV 0x%x.\n",
+ pATI->Tuner, tmp);
+
+ pATI->Tuner = tmp;
+ }
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "%s tuner detected on ATI-TV add-on adapter at I2C bus address"
+ " 0x%2x.\n", ATITuners[pATI->Tuner].name, pI2CDev->SlaveAddr);
+
+ return TRUE;
+ }
+
+ xfree(pI2CDev);
+ return FALSE;
+}
+
+/*
+ * ATIMach64I2CPreInit --
+ *
+ * This function potentially allocates an I2CBusRec and initialises it with
+ * ATI-specific and Mach64-specific information.
+ */
+void
+ATIMach64I2CPreInit
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI
+)
+{
+ I2CBusPtr pI2CBus;
+ ATII2CPtr pATII2C;
+
+ if ((pATI->Chip < ATI_CHIP_264CT) || (pATI->Chip >= ATI_CHIP_Mach64))
+ return;
+
+ /* Create an I2CBusRec and generically prime it */
+ if (!(pI2CBus = ATICreateI2CBusRec(pScreenInfo->scrnIndex, pATI, "Mach64")))
+ return;
+
+ pATII2C = pI2CBus->DriverPrivate.ptr;
+
+ switch (pATI->Chip)
+ {
+ case ATI_CHIP_264GTPRO:
+ case ATI_CHIP_264LTPRO:
+ case ATI_CHIP_264XL:
+ case ATI_CHIP_MOBILITY:
+ /*
+ * These have I2C-specific registers. Assume older I2C access
+ * mechanisms are inoperative.
+ */
+ pATII2C->I2CSetBits = ATIMach64I2C_CNTLSetBits;
+ pATII2C->I2CGetBits = ATIMach64I2C_CNTLGetBits;
+ pATII2C->SCLDir = pATII2C->SDADir = 0;
+ pATII2C->SCLGet = pATII2C->SCLSet = GetByte(I2C_CNTL_SCL, 1);
+ pATII2C->SDAGet = pATII2C->SDASet = GetByte(I2C_CNTL_SDA, 1);
+
+ out8(I2C_CNTL_1 + 2, GetByte(I2C_SEL, 2));
+ out8(I2C_CNTL_0 + 0,
+ GetByte(I2C_CNTL_STAT | I2C_CNTL_HPTR_RST, 0));
+ break;
+
+ case ATI_CHIP_264VTB:
+ case ATI_CHIP_264GTB:
+ case ATI_CHIP_264VT3:
+ case ATI_CHIP_264GTDVD:
+ case ATI_CHIP_264LT:
+ case ATI_CHIP_264VT4:
+ case ATI_CHIP_264GT2C:
+ /* If an ImpacTV chip is found, use it to provide I2C access */
+ if (ATIMach64ImpacTVProbe(pScreenInfo->scrnIndex, pATI))
+ {
+ pATII2C->I2CSetBits = ATIMach64ImpacTVSetBits;
+ pATII2C->I2CGetBits = ATIMach64ImpacTVGetBits;
+ pATII2C->SCLDir = IT_SCL_DIR;
+ pATII2C->SCLGet = IT_SCL_GET;
+ pATII2C->SCLSet = IT_SCL_SET;
+ pATII2C->SDADir = IT_SDA_DIR;
+ pATII2C->SDAGet = IT_SDA_GET;
+ pATII2C->SDASet = IT_SDA_SET;
+
+ ATIMach64MPPSetAddress(pATI, IT_I2C_CNTL);
+ outr(MPP_CONFIG, MPP_WRITEINC);
+ out8(MPP_DATA, 0x00U);
+ out8(MPP_DATA, 0x55U);
+ out8(MPP_DATA, 0x00U);
+ out8(MPP_DATA, 0x00U);
+ ATIMach64MPPWaitForIdle(pATI);
+ break;
+ }
+ /* Otherwise, fall through to the older case */
+
+ case ATI_CHIP_264VT:
+ case ATI_CHIP_264GT:
+ /* First try GIO pins 11 (clock) and 4 (data) */
+ pATII2C->I2CSetBits = ATIMach64GP_IOSetBits;
+ pATII2C->I2CGetBits = ATIMach64GP_IOGetBits;
+ pATII2C->SCLDir = GP_IO_DIR_B;
+ pATII2C->SCLGet = pATII2C->SCLSet = GP_IO_B;
+ pATII2C->SDADir = GP_IO_DIR_4;
+ pATII2C->SDAGet = pATII2C->SDASet = GP_IO_4;
+
+ if (ATITVAddOnProbe(pScreenInfo, pATI, pI2CBus))
+ break;
+
+ /* Next, try pins 10 (clock) and 12 (data) */
+ pATII2C->SCLDir = GP_IO_DIR_A;
+ pATII2C->SCLGet = pATII2C->SCLSet = GP_IO_A;
+ pATII2C->SDADir = GP_IO_DIR_C;
+ pATII2C->SDAGet = pATII2C->SDASet = GP_IO_C;
+
+ if (ATITVAddOnProbe(pScreenInfo, pATI, pI2CBus))
+ break;
+ /* Otherwise, fall back to ATI's first I2C implementation */
+
+ default:
+ /*
+ * First generation integrated controllers access GIO pin 1 (clock)
+ * though DAC_CNTL, and pin 2 (data) through GEN_TEST_CNTL.
+ */
+ pATII2C->I2CSetBits = ATIMach64DAC_GENSetBits;
+ pATII2C->I2CGetBits = ATIMach64DAC_GENGetBits;
+ pATII2C->SCLDir = DAC_GIO_DIR_1;
+ pATII2C->SCLGet = pATII2C->SCLSet = DAC_GIO_STATE_1;
+ pATII2C->SDADir = GEN_GIO2_WRITE;
+ pATII2C->SDAGet = GEN_GIO2_DATA_IN;
+ pATII2C->SDASet = GEN_GIO2_DATA_OUT;
+
+ (void)ATITVAddOnProbe(pScreenInfo, pATI, pI2CBus);
+ break;
+ }
+}
diff --git a/src/atimach64i2c.h b/src/atimach64i2c.h
new file mode 100644
index 00000000..99309523
--- /dev/null
+++ b/src/atimach64i2c.h
@@ -0,0 +1,34 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64i2c.h,v 1.1 2003/07/24 22:08:28 tsi Exp $ */
+/*
+ * Copyright 1997 through 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+ *
+ * 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 Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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.
+ */
+
+#ifndef ___ATIMACH64I2C_H___
+#define ___ATIMACH64I2C_H___ 1
+
+#include "atipriv.h"
+#include "atiproto.h"
+
+#include "xf86str.h"
+
+extern void ATIMach64I2CPreInit FunctionPrototype((ScrnInfoPtr, ATIPtr));
+
+#endif /* ___ATIMACH64I2C_H___ */
diff --git a/src/atimach64xv.c b/src/atimach64xv.c
new file mode 100644
index 00000000..92fe7ecc
--- /dev/null
+++ b/src/atimach64xv.c
@@ -0,0 +1,1493 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64xv.c,v 1.7 2003/11/10 18:22:18 tsi Exp $ */
+/*
+ * Copyright 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+ *
+ * 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 Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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.
+ */
+
+#include "ati.h"
+#include "atiaccel.h"
+#include "atichip.h"
+#include "atimach64accel.h"
+#include "atimach64io.h"
+#include "atimach64xv.h"
+
+#include "Xv.h"
+#include "fourcc.h"
+
+#define MAKE_ATOM(string) MakeAtom(string, strlen(string), TRUE)
+#define MaxScale (CARD32)(CARD16)(-1)
+
+static unsigned long ATIMach64XVAtomGeneration = (unsigned long)(-1);
+
+static XF86VideoEncodingRec ATIMach64VideoEncoding_A[] =
+{
+ { 0, "XV_IMAGE", 384, 2048, {1, 1} }
+};
+#define nATIMach64VideoEncoding_A NumberOf(ATIMach64VideoEncoding_A)
+
+static XF86VideoEncodingRec ATIMach64VideoEncoding_B[] =
+{
+ { 0, "XV_IMAGE", 720, 2048, {1, 1} }
+};
+#define nATIMach64VideoEncoding_B NumberOf(ATIMach64VideoEncoding_B)
+
+/* nATIMach64VideoEncoding_[AB] should be equal */
+#define nATIMach64VideoEncoding nATIMach64VideoEncoding_A
+
+static XF86VideoFormatRec ATIMach64VideoFormat[] =
+{
+ { 8, TrueColor},
+ { 8, DirectColor},
+ { 8, PseudoColor},
+ { 8, GrayScale},
+ { 8, StaticGray},
+ { 8, StaticColor},
+ {15, TrueColor},
+ {16, TrueColor},
+ {24, TrueColor},
+ {15, DirectColor},
+ {16, DirectColor},
+ {24, DirectColor}
+};
+#define nATIMach64VideoFormat NumberOf(ATIMach64VideoFormat)
+
+static XF86AttributeRec ATIMach64Attribute[] =
+{
+ /* These are only supported on the Rage Pro and later ... */
+ {
+ XvSettable | XvGettable,
+ -1000, 1000,
+ "XV_SATURATION"
+ },
+ {
+ XvSettable | XvGettable,
+ -1000, 1000,
+ "XV_BRIGHTNESS"
+ },
+ {
+ XvSettable | XvGettable,
+ -1000, 1000,
+ "XV_COLOUR"
+ },
+ {
+ XvSettable | XvGettable,
+ -1000, 1000,
+ "XV_COLOR"
+ },
+
+ /* Local attributes, odds and ends for compatibility, etc... */
+ {
+ XvSettable | XvGettable,
+ 0, 1,
+ "XV_AUTOPAINT_COLOURKEY"
+ },
+ {
+ XvSettable | XvGettable,
+ 0, 1,
+ "XV_AUTOPAINT_COLORKEY"
+ },
+ {
+ XvSettable | XvGettable,
+ 0, (1 << 24) - 1,
+ "XV_COLOURKEY"
+ },
+ {
+ XvSettable | XvGettable,
+ 0, (1 << 24) - 1,
+ "XV_COLORKEY"
+ },
+ {
+ XvSettable | XvGettable,
+ 0, (1 << 24) - 1,
+ "XV_COLOURKEY_MASK"
+ },
+ {
+ XvSettable | XvGettable,
+ 0, (1 << 24) - 1,
+ "XV_COLORKEY_MASK"
+ },
+ {
+ XvSettable,
+ 0, 0,
+ "XV_SET_DEFAULTS"
+ },
+ { /* Keep last */
+ XvSettable | XvGettable,
+ 0, 1,
+ "XV_DOUBLE_BUFFER"
+ }
+};
+#define nATIMach64Attribute NumberOf(ATIMach64Attribute)
+
+static XF86ImageRec ATIMach64Image[] =
+{
+ XVIMAGE_YUY2,
+ XVIMAGE_UYVY,
+ XVIMAGE_YV12,
+ XVIMAGE_I420
+};
+#define nATIMach64Image NumberOf(ATIMach64Image)
+
+/* A local XVideo adaptor attribute record */
+typedef struct _ATIMach64Attribute
+{
+ Atom AttributeID;
+ INT32 MaxValue; /* ... for the hardware */
+ void (*SetAttribute) NestedPrototype((ATIPtr, INT32));
+ INT32 (*GetAttribute) NestedPrototype((ATIPtr));
+} ATIMach64AttributeRec, *ATIMach64AttributePtr;
+
+/* Functions to get/set XVideo adaptor attributes */
+
+static void
+ATIMach64SetSaturationAttribute
+(
+ ATIPtr pATI,
+ INT32 Value
+)
+{
+ /* Set the register */
+ pATI->NewHW.scaler_colour_cntl &=
+ ~(SCALE_SATURATION_U | SCALE_SATURATION_V);
+ pATI->NewHW.scaler_colour_cntl |= SetBits(Value, SCALE_SATURATION_U) |
+ SetBits(Value, SCALE_SATURATION_V);
+ outf(SCALER_COLOUR_CNTL, pATI->NewHW.scaler_colour_cntl);
+}
+
+static INT32
+ATIMach64GetSaturationAttribute
+(
+ ATIPtr pATI
+)
+{
+ return (INT32)GetBits(pATI->NewHW.scaler_colour_cntl, SCALE_SATURATION_U);
+}
+
+static void
+ATIMach64SetBrightnessAttribute
+(
+ ATIPtr pATI,
+ INT32 Value
+)
+{
+ /* Set the register */
+ pATI->NewHW.scaler_colour_cntl &= ~SCALE_BRIGHTNESS;
+ pATI->NewHW.scaler_colour_cntl |= SetBits(Value, SCALE_BRIGHTNESS);
+ outf(SCALER_COLOUR_CNTL, pATI->NewHW.scaler_colour_cntl);
+}
+
+static INT32
+ATIMach64GetBrightnessAttribute
+(
+ ATIPtr pATI
+)
+{
+ return (INT32)GetBits(pATI->NewHW.scaler_colour_cntl, SCALE_BRIGHTNESS);
+}
+
+static void
+ATIMach64SetDoubleBufferAttribute
+(
+ ATIPtr pATI,
+ INT32 Value
+)
+{
+ pATI->DoubleBuffer = Value;
+}
+
+static INT32
+ATIMach64GetDoubleBufferAttribute
+(
+ ATIPtr pATI
+)
+{
+ return (int)pATI->DoubleBuffer;
+}
+
+static void
+ATIMach64SetAutoPaintAttribute
+(
+ ATIPtr pATI,
+ INT32 Value
+)
+{
+ pATI->AutoPaint = Value;
+}
+
+static INT32
+ATIMach64GetAutoPaintAttribute
+(
+ ATIPtr pATI
+)
+{
+ return (int)pATI->AutoPaint;
+}
+
+static void
+ATIMach64SetColourKeyAttribute
+(
+ ATIPtr pATI,
+ INT32 Value
+)
+{
+ pATI->NewHW.overlay_graphics_key_clr =
+ (CARD32)(Value & ((1 << pATI->depth) - 1));
+ outf(OVERLAY_GRAPHICS_KEY_CLR, pATI->NewHW.overlay_graphics_key_clr);
+}
+
+static INT32
+ATIMach64GetColourKeyAttribute
+(
+ ATIPtr pATI
+)
+{
+ return (INT32)pATI->NewHW.overlay_graphics_key_clr;
+}
+
+static void
+ATIMach64SetColourKeyMaskAttribute
+(
+ ATIPtr pATI,
+ INT32 Value
+)
+{
+ pATI->NewHW.overlay_graphics_key_msk =
+ (CARD32)(Value & ((1 << pATI->depth) - 1));
+ outf(OVERLAY_GRAPHICS_KEY_MSK, pATI->NewHW.overlay_graphics_key_msk);
+}
+
+static INT32
+ATIMach64GetColourKeyMaskAttribute
+(
+ ATIPtr pATI
+)
+{
+ return (INT32)pATI->NewHW.overlay_graphics_key_msk;
+}
+
+/*
+ * ATIMach64SetDefaultAttributes --
+ *
+ * This function calls other functions to set default values for the various
+ * attributes of an XVideo port.
+ */
+static void
+ATIMach64SetDefaultAttributes
+(
+ ATIPtr pATI,
+ INT32 Value
+)
+{
+ ATIMach64SetAutoPaintAttribute(pATI, TRUE);
+ ATIMach64SetDoubleBufferAttribute(pATI, FALSE);
+ ATIMach64SetColourKeyMaskAttribute(pATI, (1 << pATI->depth) - 1);
+ ATIMach64SetColourKeyAttribute(pATI, (3 << ((2 * pATI->depth) / 3)) |
+ (2 << ((1 * pATI->depth) / 3)) |
+ (1 << ((0 * pATI->depth) / 3)));
+
+ if (pATI->Chip < ATI_CHIP_264GTPRO)
+ return;
+
+ ATIMach64SetBrightnessAttribute(pATI, 32);
+ ATIMach64SetSaturationAttribute(pATI, 16);
+}
+
+/*
+ * There is a one-to-one correspondance between elements of the following array
+ * and those of ATIMach64Attribute.
+ */
+static ATIMach64AttributeRec ATIMach64AttributeInfo[nATIMach64Attribute] =
+{
+ { /* SATURATION */
+ 0, 23,
+ ATIMach64SetSaturationAttribute,
+ ATIMach64GetSaturationAttribute
+ },
+ { /* BRIGHTNESS */
+ 0, 63,
+ ATIMach64SetBrightnessAttribute,
+ ATIMach64GetBrightnessAttribute
+ },
+ { /* COLOUR */
+ 0, 23,
+ ATIMach64SetSaturationAttribute,
+ ATIMach64GetSaturationAttribute
+ },
+ { /* COLOR */
+ 0, 23,
+ ATIMach64SetSaturationAttribute,
+ ATIMach64GetSaturationAttribute
+ },
+ { /* AUTOPAINT_COLOURKEY */
+ 0, 1,
+ ATIMach64SetAutoPaintAttribute,
+ ATIMach64GetAutoPaintAttribute
+ },
+ { /* AUTOPAINT_COLORKEY */
+ 0, 1,
+ ATIMach64SetAutoPaintAttribute,
+ ATIMach64GetAutoPaintAttribute
+ },
+ { /* COLOURKEY */
+ 0, (1 << 24) - 1,
+ ATIMach64SetColourKeyAttribute,
+ ATIMach64GetColourKeyAttribute
+ },
+ { /* COLORKEY */
+ 0, (1 << 24) - 1,
+ ATIMach64SetColourKeyAttribute,
+ ATIMach64GetColourKeyAttribute
+ },
+ { /* COLOURKEY_MASK */
+ 0, (1 << 24) - 1,
+ ATIMach64SetColourKeyMaskAttribute,
+ ATIMach64GetColourKeyMaskAttribute
+ },
+ { /* COLORKEY_MASK */
+ 0, (1 << 24) - 1,
+ ATIMach64SetColourKeyMaskAttribute,
+ ATIMach64GetColourKeyMaskAttribute
+ },
+ { /* SET_DEFAULTS */
+ 0, 0,
+ ATIMach64SetDefaultAttributes,
+ NULL
+ },
+ { /* DOUBLE_BUFFER */
+ 0, 1,
+ ATIMach64SetDoubleBufferAttribute,
+ ATIMach64GetDoubleBufferAttribute
+ }
+};
+
+/*
+ * ATIMach64FindAttribute --
+ *
+ * This function is called to locate an Xv attribute's table entry.
+ */
+static int
+ATIMach64FindPortAttribute
+(
+ ATIPtr pATI,
+ Atom AttributeID
+)
+{
+ int iAttribute;
+
+ if (pATI->Chip < ATI_CHIP_264GTPRO)
+ iAttribute = 4;
+ else
+ iAttribute = 0;
+
+ for (; iAttribute < nATIMach64Attribute; iAttribute++)
+ if (AttributeID == ATIMach64AttributeInfo[iAttribute].AttributeID)
+ return iAttribute;
+
+ return -1;
+}
+
+/*
+ * ATIMach64SetPortAttribute --
+ *
+ * This function sets the value of a particular port's attribute.
+ */
+static int
+ATIMach64SetPortAttribute
+(
+ ScrnInfoPtr pScreenInfo,
+ Atom AttributeID,
+ INT32 Value,
+ pointer pATI
+)
+{
+ INT32 Range;
+ int iAttribute;
+
+ if (((iAttribute = ATIMach64FindPortAttribute(pATI, AttributeID)) < 0) ||
+ !ATIMach64AttributeInfo[iAttribute].SetAttribute)
+ return BadMatch;
+
+ Range = ATIMach64Attribute[iAttribute].max_value -
+ ATIMach64Attribute[iAttribute].min_value;
+
+ if (Range >= 0)
+ {
+ /* Limit and scale the value */
+ Value -= ATIMach64Attribute[iAttribute].min_value;
+
+ if (Value < 0)
+ Value = 0;
+ else if (Value > Range)
+ Value = Range;
+
+ if (Range != ATIMach64AttributeInfo[iAttribute].MaxValue)
+ {
+ if (ATIMach64AttributeInfo[iAttribute].MaxValue > 0)
+ Value *= ATIMach64AttributeInfo[iAttribute].MaxValue;
+ if (Range > 0)
+ Value /= Range;
+ }
+ }
+
+ (*ATIMach64AttributeInfo[iAttribute].SetAttribute)(pATI, Value);
+
+ return Success;
+}
+
+/*
+ * ATIMach64SetPortAttribute --
+ *
+ * This function retrieves the value of a particular port's attribute.
+ */
+static int
+ATIMach64GetPortAttribute
+(
+ ScrnInfoPtr pScreenInfo,
+ Atom AttributeID,
+ INT32 *Value,
+ pointer pATI
+)
+{
+ INT32 Range;
+ int iAttribute;
+
+ if (!Value ||
+ ((iAttribute = ATIMach64FindPortAttribute(pATI, AttributeID)) < 0) ||
+ !ATIMach64AttributeInfo[iAttribute].GetAttribute)
+ return BadMatch;
+
+ *Value = (*ATIMach64AttributeInfo[iAttribute].GetAttribute)(pATI);
+
+ Range = ATIMach64Attribute[iAttribute].max_value -
+ ATIMach64Attribute[iAttribute].min_value;
+
+ if (Range >= 0)
+ {
+ if (Range != ATIMach64AttributeInfo[iAttribute].MaxValue)
+ {
+ /* (Un-)scale the value */
+ if (Range > 0)
+ *Value *= Range;
+ if (ATIMach64AttributeInfo[iAttribute].MaxValue > 0)
+ *Value /= ATIMach64AttributeInfo[iAttribute].MaxValue;
+ }
+
+ *Value += ATIMach64Attribute[iAttribute].min_value;
+ }
+
+ return Success;
+}
+
+/*
+ * ATIMach64RemoveLinearCallback --
+ *
+ * This is called by the framebuffer manager to release the offscreen XVideo
+ * buffer after the video has been temporarily disabled due to its window being
+ * iconified or completely occluded.
+ */
+static void
+ATIMach64RemoveLinearCallback
+(
+ FBLinearPtr pLinear
+)
+{
+ ATIPtr pATI = ATIPTR(xf86Screens[pLinear->pScreen->myNum]);
+
+ pATI->pXVBuffer = NULL;
+ outf(OVERLAY_SCALE_CNTL, SCALE_EN);
+}
+
+/*
+ * ATIMach64StopVideo --
+ *
+ * This is called to stop displaying a video. Note that, to prevent jittering
+ * this doesn't actually turn off the overlay unless 'Cleanup' is TRUE, i.e.
+ * when the video is to be actually stopped rather than temporarily disabled.
+ */
+static void
+ATIMach64StopVideo
+(
+ ScrnInfoPtr pScreenInfo,
+ pointer Data,
+ Bool Cleanup
+)
+{
+ ScreenPtr pScreen = pScreenInfo->pScreen;
+ ATIPtr pATI = Data;
+
+ if (pATI->ActiveSurface)
+ return;
+
+ REGION_EMPTY(pScreen, &pATI->VideoClip);
+
+ if (!Cleanup)
+ {
+ /*
+ * Free offscreen buffer if/when its allocation is needed by XAA's
+ * pixmap cache.
+ */
+ if (pATI->pXVBuffer)
+ pATI->pXVBuffer->RemoveLinearCallback =
+ ATIMach64RemoveLinearCallback;
+ return;
+ }
+
+ pATI->pXVBuffer = ATIResizeOffscreenLinear(pScreen, pATI->pXVBuffer, 0);
+ outf(OVERLAY_SCALE_CNTL, SCALE_EN);
+}
+
+/*
+ * ATIMach64QueryBestSize --
+ *
+ * Quoting XVideo docs:
+ *
+ * This function provides the client with a way to query what the destination
+ * dimensions would end up being if they were to request that an area
+ * VideoWidth by VideoHeight from the video stream be scaled to rectangle of
+ * DrawableWidth by DrawableHeight on the screen. Since it is not expected
+ * that all hardware will be able to get the target dimensions exactly, it is
+ * important that the driver provide this function.
+ */
+static void
+ATIMach64QueryBestSize
+(
+ ScrnInfoPtr pScreenInfo,
+ Bool Motion,
+ short VideoWidth,
+ short VideoHeight,
+ short DrawableWidth,
+ short DrawableHeight,
+ unsigned int *Width,
+ unsigned int *Height,
+ pointer pATI
+)
+{
+ *Width = DrawableWidth;
+ *Height = DrawableHeight;
+}
+
+/*
+ * ATIMach64QueryImageAttributes --
+ *
+ * Quoting XVideo docs:
+ *
+ * This function is called to let the driver specify how data for a particular
+ * image of size Width by Height should be stored. Sometimes only the size and
+ * corrected width and height are needed. In that case pitches and offsets are
+ * NULL. The size of the memory required for the image is returned by this
+ * function. The width and height of the requested image can be altered by the
+ * driver to reflect format limitations (such as component sampling periods
+ * that are larger than one). If pPitch and pOffset are not NULL, these will
+ * be arrays with as many elements in them as there are planes in the image
+ * format. The driver should specify the pitch (in bytes) of each scanline in
+ * the particular plane as well as the offset to that plane (in bytes) from the
+ * beginning of the image.
+ */
+static int
+ATIMach64QueryImageAttributes
+(
+ ScrnInfoPtr pScreenInfo,
+ int ImageID,
+ unsigned short *Width,
+ unsigned short *Height,
+ int *pPitch,
+ int *pOffset
+)
+{
+ int Size, tmp;
+
+ if (!Width || !Height)
+ return 0;
+
+ if (*Width > 2048)
+ *Width = 2048;
+ else
+ *Width = (*Width + 1) & ~1;
+
+ if (*Height > 2048)
+ *Height = 2048;
+
+ if (pOffset)
+ pOffset[0] = 0;
+
+ switch (ImageID)
+ {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ *Height = (*Height + 1) & ~1;
+ Size = (*Width + 3) & ~3;
+ if (pPitch)
+ pPitch[0] = Size;
+ Size *= *Height;
+ if (pOffset)
+ pOffset[1] = Size;
+ tmp = ((*Width >> 1) + 3) & ~3;
+ if (pPitch)
+ pPitch[1] = pPitch[2] = tmp;
+ tmp *= (*Height >> 1);
+ Size += tmp;
+ if (pOffset)
+ pOffset[2] = Size;
+ Size += tmp;
+ break;
+
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ Size = *Width << 1;
+ if (pPitch)
+ pPitch[0] = Size;
+ Size *= *Height;
+ break;
+
+ default:
+ Size = 0;
+ break;
+ }
+
+ return Size;
+}
+
+/*
+ * ATIMach64ScaleVideo --
+ *
+ * This function is called to calculate overlay scaling factors.
+ */
+static void
+ATIMach64ScaleVideo
+(
+ ATIPtr pATI,
+ DisplayModePtr pMode,
+ int SrcW,
+ int SrcH,
+ int DstW,
+ int DstH,
+ CARD32 *pHScale,
+ CARD32 *pVScale
+)
+{
+ int Shift;
+
+ *pHScale = ATIDivide(SrcW, DstW,
+ GetBits(pATI->NewHW.pll_vclk_cntl, PLL_ECP_DIV) + 12, 0);
+
+ Shift = 12;
+ if (pMode->Flags & V_INTERLACE)
+ Shift++;
+
+ if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0))
+ {
+ if (pMode->VDisplay < pATI->LCDVertical)
+ {
+ SrcH *= pMode->VDisplay;
+ DstH *= pATI->LCDVertical;
+ }
+ }
+ else
+ {
+ if (pMode->Flags & V_DBLSCAN)
+ Shift--;
+ if (pMode->VScan > 1)
+ DstH *= pMode->VScan;
+ }
+
+ *pVScale = ATIDivide(SrcH, DstH, Shift, 0);
+}
+
+/*
+ * ATIMach64ClipVideo --
+ *
+ * Clip the video (both source and destination) and make various other
+ * adjustments.
+ */
+static Bool
+ATIMach64ClipVideo
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ int ImageID,
+ short SrcX,
+ short SrcY,
+ short SrcW,
+ short SrcH,
+ short DstX,
+ short DstY,
+ short *DstW,
+ short *DstH,
+ short Width,
+ short Height,
+ RegionPtr pClip,
+ BoxPtr pDstBox,
+ INT32 *SrcX1,
+ INT32 *SrcX2,
+ INT32 *SrcY1,
+ INT32 *SrcY2,
+ int *SrcLeft,
+ int *SrcTop
+)
+{
+ CARD32 HScale, VScale;
+
+ /* Check hardware limits */
+ if ((Height <= 0) || (Height > 2048) || (Width <= 0) || (Width > 720) ||
+ ((Width > 384) && (pATI->Chip < ATI_CHIP_264VTB)))
+ return FALSE;
+
+ ATIMach64ScaleVideo(pATI, pScreenInfo->currentMode,
+ SrcW, SrcH, *DstW, *DstH, &HScale, &VScale);
+ if (!HScale || !VScale)
+ return FALSE;
+ if (HScale > MaxScale)
+ *DstW = (*DstW * HScale) / MaxScale;
+ if (VScale > MaxScale)
+ *DstH = (*DstH * HScale) / MaxScale;
+
+ /* Clip both the source and the destination */
+ *SrcX1 = SrcX;
+ *SrcX2 = SrcX + SrcW;
+ *SrcY1 = SrcY;
+ *SrcY2 = SrcY + SrcH;
+
+ pDstBox->x1 = DstX;
+ pDstBox->x2 = DstX + *DstW;
+ pDstBox->y1 = DstY;
+ pDstBox->y2 = DstY + *DstH;
+
+ if (!xf86XVClipVideoHelper(pDstBox, SrcX1, SrcX2, SrcY1, SrcY2,
+ pClip, Width, Height))
+ return FALSE;
+
+ /*
+ * Reset overlay scaler origin. This prevents jittering during
+ * viewport panning or while the video is being moved or gradually
+ * obscured/unobscured.
+ */
+ pDstBox->x1 = DstX;
+ pDstBox->y1 = DstY;
+
+ /* Translate to the current viewport */
+ pDstBox->x1 -= pScreenInfo->frameX0;
+ pDstBox->x2 -= pScreenInfo->frameX0;
+ pDstBox->y1 -= pScreenInfo->frameY0;
+ pDstBox->y2 -= pScreenInfo->frameY0;
+
+ *SrcLeft = *SrcTop = 0;
+
+ /*
+ * If the overlay scaler origin ends up outside the current viewport, move
+ * it to the viewport's top left corner. This unavoidably causes a slight
+ * jittering in the image (even with double-buffering).
+ */
+ if (pDstBox->x1 < 0)
+ {
+ *SrcLeft = ((-pDstBox->x1 * SrcW) / *DstW) & ~1;
+ pDstBox->x1 = 0;
+ }
+
+ if (pDstBox->y1 < 0)
+ {
+ *SrcTop = (-pDstBox->y1 * SrcH) / *DstH;
+ pDstBox->y1 = 0;
+
+ switch (ImageID)
+ {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ *SrcTop = (*SrcTop + 1) & ~1;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+#ifdef ATIMove32
+
+/* A faster intercept */
+#undef xf86XVCopyPacked
+#define xf86XVCopyPacked ATIMach64XVCopyPacked
+
+static void
+ATIMach64XVCopyPacked
+(
+ const CARD8 *pSrc,
+ CARD8 *pDst,
+ int SrcPitch,
+ int DstPitch,
+ int Height,
+ int Width
+)
+{
+ Width >>= 1;
+ while (--Height >= 0)
+ {
+ ATIMove32(pDst, pSrc, Width);
+ pSrc += SrcPitch;
+ pDst += DstPitch;
+ }
+}
+
+#endif
+
+/*
+ * ATIMach64DisplayVideo --
+ *
+ * This function programmes Mach64 registers needed to display a video.
+ */
+static void
+ATIMach64DisplayVideo
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ BoxPtr pDstBox,
+ int ImageID,
+ int Offset,
+ int Pitch,
+ short SrcW,
+ short SrcH,
+ short DstW,
+ short DstH,
+ short Width,
+ short Height
+)
+{
+ DisplayModePtr pMode = pScreenInfo->currentMode;
+ CARD32 HScale, VScale;
+
+ if (pMode->VScan > 1)
+ {
+ pDstBox->y1 *= pMode->VScan;
+ pDstBox->y2 *= pMode->VScan;
+ }
+ if (pMode->Flags & V_DBLSCAN)
+ {
+ pDstBox->y1 <<= 1;
+ pDstBox->y2 <<= 1;
+ }
+
+ /* Recalculate overlay scale factors */
+ ATIMach64ScaleVideo(pATI, pMode, SrcW, SrcH, DstW, DstH, &HScale, &VScale);
+
+ pATI->NewHW.video_format &= ~SCALER_IN;
+ if (ImageID == FOURCC_UYVY)
+ pATI->NewHW.video_format |= SCALER_IN_YVYU422;
+ else
+ pATI->NewHW.video_format |= SCALER_IN_VYUY422;
+
+ ATIMach64WaitForFIFO(pATI, 8);
+ outq(OVERLAY_Y_X_START, OVERLAY_Y_X_END, OVERLAY_LOCK_START |
+ SetWord(pDstBox->x1, 1) | SetWord(pDstBox->y1, 0),
+ SetWord(pDstBox->x2 - 1, 1) | SetWord(pDstBox->y2 - 1, 0));
+ outf(OVERLAY_SCALE_INC, SetWord(HScale, 1) | SetWord(VScale, 0));
+ outf(SCALER_HEIGHT_WIDTH, SetWord(Width, 1) | SetWord(Height, 0));
+ outf(VIDEO_FORMAT, pATI->NewHW.video_format);
+
+ if (pATI->Chip < ATI_CHIP_264VTB)
+ {
+ outf(BUF0_OFFSET, Offset);
+ outf(BUF0_PITCH, Pitch);
+ }
+ else
+ {
+ outf(SCALER_BUF0_OFFSET, Offset);
+ outf(SCALER_BUF_PITCH, Pitch);
+ }
+
+ outf(OVERLAY_SCALE_CNTL, SCALE_PIX_EXPAND | OVERLAY_EN | SCALE_EN);
+}
+
+/*
+ * ATIMach64PutImage --
+ *
+ * This function is called to put a video image on the screen.
+ */
+static int
+ATIMach64PutImage
+(
+ ScrnInfoPtr pScreenInfo,
+ short SrcX,
+ short SrcY,
+ short DstX,
+ short DstY,
+ short SrcW,
+ short SrcH,
+ short DstW,
+ short DstH,
+ int ImageID,
+ unsigned char *Buffer,
+ short Width,
+ short Height,
+ Bool Synchronise,
+ RegionPtr pClip,
+ pointer Data
+)
+{
+ ATIPtr pATI = Data;
+ ScreenPtr pScreen;
+ INT32 SrcX1, SrcX2, SrcY1, SrcY2;
+ BoxRec DstBox;
+ int SrcPitch, SrcPitchUV, DstPitch, DstSize;
+ int SrcTop, SrcLeft, DstWidth, DstHeight;
+ int Top, Bottom, Left, Right, nLine, nPixel, Offset;
+ int OffsetV, OffsetU;
+ int tmp;
+ CARD8 *pDst;
+
+ if (pATI->ActiveSurface)
+ return Success;
+
+ if (!ATIMach64ClipVideo(pScreenInfo, pATI, ImageID,
+ SrcX, SrcY, SrcW, SrcH,
+ DstX, DstY, &DstW, &DstH,
+ Width, Height, pClip, &DstBox,
+ &SrcX1, &SrcX2, &SrcY1, &SrcY2,
+ &SrcLeft, &SrcTop))
+ return Success;
+
+ pScreen = pScreenInfo->pScreen;
+
+ DstWidth = Width - SrcLeft;
+ DstHeight = Height - SrcTop;
+
+ /*
+ * Allocate an offscreen buffer for the entire source, even though only a
+ * subset of the source will be copied into it.
+ */
+ DstPitch = /* bytes */
+ (DstWidth + DstWidth + 15) & ~15;
+ DstSize = /* pixels */
+ ((DstPitch * DstHeight) + pATI->AdjustDepth - 1) / pATI->AdjustDepth;
+
+ pATI->pXVBuffer = ATIResizeOffscreenLinear(pScreen, pATI->pXVBuffer,
+ (pATI->DoubleBuffer + 1) * DstSize);
+
+ if (!pATI->pXVBuffer)
+ {
+ if (!pATI->DoubleBuffer)
+ return BadAlloc;
+
+ pATI->pXVBuffer =
+ ATIResizeOffscreenLinear(pScreen, pATI->pXVBuffer, DstSize);
+
+ if (!pATI->pXVBuffer)
+ return BadAlloc;
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Video image double-buffering downgraded to single-buffering\n due"
+ " to insufficient video memory.\n");
+ pATI->DoubleBuffer = pATI->CurrentBuffer = 0;
+ }
+ else
+ {
+ /* Possibly switch buffers */
+ pATI->CurrentBuffer = pATI->DoubleBuffer - pATI->CurrentBuffer;
+ }
+
+ /* Synchronise video memory accesses */
+ ATIMach64Sync(pScreenInfo);
+
+ Offset = (pATI->pXVBuffer->offset * pATI->AdjustDepth) +
+ (pATI->CurrentBuffer * DstSize * pATI->AdjustDepth);
+ pDst = pATI->pMemoryLE;
+ pDst += Offset;
+
+ switch (ImageID)
+ {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ Left = (SrcX1 >> 16) & ~1;
+ Right = ((SrcX2 + 0x1FFFF) >> 16) & ~1;
+ Top = (SrcY1 >> 16) & ~1;
+ Bottom = ((SrcY2 + 0x1FFFF) >> 16) & ~1;
+
+ if ((Right < Width) && ((SrcX1 & 0x1FFFF) <= (SrcX2 & 0x1FFFF)))
+ Right += 2;
+ if ((Bottom < Height) && ((SrcY1 & 0x1FFFF) <= (SrcY2 & 0x1FFFF)))
+ Bottom += 2;
+
+ nPixel = Right - Left;
+ nLine = Bottom - Top;
+
+ SrcPitch = (Width + 3) & ~3;
+ OffsetV = SrcPitch * Height;
+ SrcPitchUV = ((Width >> 1) + 3) & ~3;
+ OffsetU = ((Height >> 1) * SrcPitchUV) + OffsetV;
+
+ tmp = ((Top >> 1) * SrcPitchUV) + (Left >> 1);
+ OffsetV += tmp;
+ OffsetU += tmp;
+
+ if (ImageID == FOURCC_I420)
+ {
+ tmp = OffsetV;
+ OffsetV = OffsetU;
+ OffsetU = tmp;
+ }
+
+ pDst += ((Top - SrcTop) * DstPitch) + ((Left - SrcLeft) << 1);
+
+ xf86XVCopyYUV12ToPacked(Buffer + (Top * SrcPitch) + Left,
+ Buffer + OffsetV, Buffer + OffsetU, pDst, SrcPitch, SrcPitchUV,
+ DstPitch, nLine, nPixel);
+ break;
+
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ Left = (SrcX1 >> 16) & ~1;
+ Right = ((SrcX2 + 0x1FFFF) >> 16) & ~1;
+ Top = SrcY1 >> 16;
+ Bottom = (SrcY2 + 0x0FFFF) >> 16;
+
+ if ((Right < Width) && ((SrcX1 & 0x1FFFF) <= (SrcX2 & 0x1FFFF)))
+ Right += 2;
+ if ((Bottom < Height) && ((SrcY1 & 0x0FFFF) <= (SrcY2 & 0x0FFFF)))
+ Bottom++;
+
+ nPixel = Right - Left;
+ nLine = Bottom - Top;
+
+ SrcPitch = Width << 1;
+ Buffer += (Top * SrcPitch) + (Left << 1);
+ pDst += ((Top - SrcTop) * DstPitch) + ((Left - SrcLeft) << 1);
+
+ xf86XVCopyPacked(Buffer, pDst, SrcPitch, DstPitch, nLine, nPixel);
+ break;
+ }
+
+ if (!REGION_EQUAL(pScreen, &pATI->VideoClip, pClip))
+ {
+ REGION_COPY(pScreen, &pATI->VideoClip, pClip);
+ if (pATI->AutoPaint)
+ xf86XVFillKeyHelper(pScreen, pATI->NewHW.overlay_graphics_key_clr,
+ pClip);
+ }
+
+ ATIMach64DisplayVideo(pScreenInfo, pATI, &DstBox, ImageID,
+ Offset, DstPitch / 2, SrcW, SrcH, DstW, DstH, DstWidth, DstHeight);
+
+ return Success;
+}
+
+/*
+ * ATIMach64AllocateSurface --
+ *
+ * This function allocates an offscreen buffer (called a "surface") for use by
+ * an external driver such as 'v4l'.
+ */
+static int
+ATIMach64AllocateSurface
+(
+ ScrnInfoPtr pScreenInfo,
+ int ImageID,
+ unsigned short Width,
+ unsigned short Height,
+ XF86SurfacePtr pSurface
+)
+{
+ ScreenPtr pScreen;
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ if (pATI->ActiveSurface)
+ return BadAlloc;
+
+ if ((Height <= 0) || (Height > 2048) || (Width <= 0) || (Width > 720) ||
+ ((Width > 384) && (pATI->Chip < ATI_CHIP_264VTB)))
+ return BadValue;
+
+ Width = (Width + 1) & ~1;
+ pATI->SurfacePitch = ((Width << 1) + 15) & ~15;
+
+ pScreen = pScreenInfo->pScreen;
+
+ pATI->pXVBuffer = ATIResizeOffscreenLinear(pScreen, pATI->pXVBuffer,
+ ((Height * pATI->SurfacePitch) + pATI->AdjustDepth - 1) /
+ pATI->AdjustDepth);
+ if (!pATI->pXVBuffer)
+ return BadAlloc;
+
+ pATI->SurfaceOffset = pATI->pXVBuffer->offset * pATI->AdjustDepth;
+
+ pSurface->pScrn = pScreenInfo;
+ pSurface->id = ImageID;
+ pSurface->width = Width;
+ pSurface->height = Height;
+ pSurface->pitches = &pATI->SurfacePitch;
+ pSurface->offsets = &pATI->SurfaceOffset;
+ pSurface->devPrivate.ptr = pATI;
+
+ /* Stop the video */
+ outf(OVERLAY_SCALE_CNTL, SCALE_EN);
+ REGION_EMPTY(pScreen, &pATI->VideoClip);
+ pATI->ActiveSurface = TRUE;
+
+ return Success;
+}
+
+/*
+ * ATIMach64FreeSurface --
+ *
+ * This function called to free a surface's offscreen buffer.
+ */
+static int
+ATIMach64FreeSurface
+(
+ XF86SurfacePtr pSurface
+)
+{
+ ATIPtr pATI = pSurface->devPrivate.ptr;
+
+ if (!pATI->ActiveSurface)
+ return Success;
+
+ outf(OVERLAY_SCALE_CNTL, SCALE_EN);
+ pATI->pXVBuffer = ATIResizeOffscreenLinear(pSurface->pScrn->pScreen,
+ pATI->pXVBuffer, 0);
+ pATI->ActiveSurface = FALSE;
+
+ return Success;
+}
+
+/*
+ * ATIMach64DisplaySurface --
+ *
+ * This function is called to display a video surface.
+ */
+static int
+ATIMach64DisplaySurface
+(
+ XF86SurfacePtr pSurface,
+ short SrcX,
+ short SrcY,
+ short DstX,
+ short DstY,
+ short SrcW,
+ short SrcH,
+ short DstW,
+ short DstH,
+ RegionPtr pClip
+)
+{
+ ATIPtr pATI = pSurface->devPrivate.ptr;
+ ScrnInfoPtr pScreenInfo;
+ int ImageID;
+ short Width, Height;
+ BoxRec DstBox;
+ INT32 SrcX1, SrcX2, SrcY1, SrcY2;
+ int SrcLeft, SrcTop, SrcPitch, Offset;
+
+ if (!pATI->ActiveSurface)
+ return Success;
+
+ pScreenInfo = pSurface->pScrn;
+ ImageID = pSurface->id;
+ Width = pSurface->width;
+ Height = pSurface->height;
+
+ if (!ATIMach64ClipVideo(pScreenInfo, pATI, ImageID,
+ SrcX, SrcY, SrcW, SrcH,
+ DstX, DstY, &DstW, &DstH,
+ Width, Height, pClip, &DstBox,
+ &SrcX1, &SrcX2, &SrcY1, &SrcY2,
+ &SrcLeft, &SrcTop))
+ return Success;
+
+ xf86XVFillKeyHelper(pScreenInfo->pScreen,
+ pATI->NewHW.overlay_graphics_key_clr, pClip);
+
+ SrcPitch = pSurface->pitches[0];
+ Offset = pSurface->offsets[0] + (SrcTop * SrcPitch) + (SrcLeft << 1);
+ ATIMach64DisplayVideo(pScreenInfo, pATI, &DstBox, ImageID,
+ Offset, SrcPitch, SrcW, SrcH, DstW, DstH, Width, Height);
+
+ return Success;
+}
+
+/*
+ * ATIMach64StopSurface --
+ *
+ * This function is called to stop the overlaid display of a video surface.
+ */
+static int
+ATIMach64StopSurface
+(
+ XF86SurfacePtr pSurface
+)
+{
+ ATIPtr pATI = pSurface->devPrivate.ptr;
+
+ if (pATI->ActiveSurface)
+ outf(OVERLAY_SCALE_CNTL, SCALE_EN);
+
+ return Success;
+}
+
+/*
+ * ATIMach64GetSurfaceAttribute --
+ *
+ * Retrieve the value of an XVideo attribute.
+ */
+static int
+ATIMach64GetSurfaceAttribute
+(
+ ScrnInfoPtr pScreenInfo,
+ Atom AttributeID,
+ INT32 *Value
+)
+{
+ return ATIMach64GetPortAttribute(pScreenInfo, AttributeID, Value,
+ ATIPTR(pScreenInfo));
+}
+
+/*
+ * ATIMach64SetSurfaceAttribute
+ *
+ * Set the value of an XVideo attribute.
+ */
+static int
+ATIMach64SetSurfaceAttribute
+(
+ ScrnInfoPtr pScreenInfo,
+ Atom AttributeID,
+ INT32 Value
+)
+{
+ return ATIMach64SetPortAttribute(pScreenInfo, AttributeID, Value,
+ ATIPTR(pScreenInfo));
+}
+
+/* XVideo surface registration data */
+static XF86OffscreenImageRec ATIMach64Surface_A[] =
+{
+ {
+ &ATIMach64Image[0], /* YUY2 */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ ATIMach64AllocateSurface,
+ ATIMach64FreeSurface,
+ ATIMach64DisplaySurface,
+ ATIMach64StopSurface,
+ ATIMach64GetSurfaceAttribute,
+ ATIMach64SetSurfaceAttribute,
+ 384, 2048,
+ nATIMach64Attribute - 5, /* No double-buffering */
+ ATIMach64Attribute + 4 /* No saturation nor brightness */
+ },
+ {
+ &ATIMach64Image[1], /* UYVY */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ ATIMach64AllocateSurface,
+ ATIMach64FreeSurface,
+ ATIMach64DisplaySurface,
+ ATIMach64StopSurface,
+ ATIMach64GetSurfaceAttribute,
+ ATIMach64SetSurfaceAttribute,
+ 384, 2048,
+ nATIMach64Attribute - 5, /* No double-buffering */
+ ATIMach64Attribute + 4 /* No saturation nor brightness */
+ }
+};
+#define nATIMach64Surface_A NumberOf(ATIMach64Surface_A)
+
+static XF86OffscreenImageRec ATIMach64Surface_B[] =
+{
+ {
+ &ATIMach64Image[0], /* YUY2 */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ ATIMach64AllocateSurface,
+ ATIMach64FreeSurface,
+ ATIMach64DisplaySurface,
+ ATIMach64StopSurface,
+ ATIMach64GetSurfaceAttribute,
+ ATIMach64SetSurfaceAttribute,
+ 720, 2048,
+ nATIMach64Attribute - 5, /* No double-buffering */
+ ATIMach64Attribute + 4 /* No saturation nor brightness */
+ },
+ {
+ &ATIMach64Image[1], /* UYVY */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ ATIMach64AllocateSurface,
+ ATIMach64FreeSurface,
+ ATIMach64DisplaySurface,
+ ATIMach64StopSurface,
+ ATIMach64GetSurfaceAttribute,
+ ATIMach64SetSurfaceAttribute,
+ 720, 2048,
+ nATIMach64Attribute - 5, /* No double-buffering */
+ ATIMach64Attribute + 4 /* No saturation nor brightness */
+ }
+};
+#define nATIMach64Surface_B NumberOf(ATIMach64Surface_B)
+
+static XF86OffscreenImageRec ATIMach64Surface_C[] =
+{
+ {
+ &ATIMach64Image[0], /* YUY2 */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ ATIMach64AllocateSurface,
+ ATIMach64FreeSurface,
+ ATIMach64DisplaySurface,
+ ATIMach64StopSurface,
+ ATIMach64GetSurfaceAttribute,
+ ATIMach64SetSurfaceAttribute,
+ 720, 2048,
+ nATIMach64Attribute - 1, /* No double-buffering */
+ ATIMach64Attribute
+ },
+ {
+ &ATIMach64Image[1], /* UYVY */
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT,
+ ATIMach64AllocateSurface,
+ ATIMach64FreeSurface,
+ ATIMach64DisplaySurface,
+ ATIMach64StopSurface,
+ ATIMach64GetSurfaceAttribute,
+ ATIMach64SetSurfaceAttribute,
+ 720, 2048,
+ nATIMach64Attribute - 1, /* No double-buffering */
+ ATIMach64Attribute
+ }
+};
+#define nATIMach64Surface_C NumberOf(ATIMach64Surface_C)
+
+/*
+ * ATIMach64XVInitialiseAdaptor --
+ *
+ * This function is called to make a Mach64's hardware overlay support
+ * available as an XVideo adaptor.
+ */
+int
+ATIMach64XVInitialiseAdaptor
+(
+ ScreenPtr pScreen,
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ XF86VideoAdaptorPtr **pppAdaptor
+)
+{
+ XF86VideoAdaptorPtr pAdaptor;
+ int Index;
+
+ if (!pATI->Block1Base)
+ return 0;
+
+ if (!(pAdaptor = xf86XVAllocateVideoAdaptorRec(pScreenInfo)))
+ return 0;
+
+ *pppAdaptor = xnfalloc(sizeof(pAdaptor));
+ **pppAdaptor = pAdaptor;
+
+ pAdaptor->nPorts = 1;
+ pAdaptor->pPortPrivates = pATI->XVPortPrivate;
+ pATI->XVPortPrivate[0].ptr = pATI;
+
+ pAdaptor->type = XvInputMask | XvImageMask | XvWindowMask;
+ pAdaptor->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ pAdaptor->name = "ATI Mach64 Back-end Overlay Scaler";
+
+ if (pATI->Chip < ATI_CHIP_264VTB)
+ {
+ pAdaptor->nEncodings = nATIMach64VideoEncoding_A;
+ pAdaptor->pEncodings = ATIMach64VideoEncoding_A;
+ }
+ else
+ {
+ pAdaptor->nEncodings = nATIMach64VideoEncoding_B;
+ pAdaptor->pEncodings = ATIMach64VideoEncoding_B;
+ }
+
+ pAdaptor->nFormats = nATIMach64VideoFormat;
+ pAdaptor->pFormats = ATIMach64VideoFormat;
+
+ pAdaptor->nAttributes = nATIMach64Attribute;
+ pAdaptor->pAttributes = ATIMach64Attribute;
+
+ if (pATI->Chip < ATI_CHIP_264GTPRO)
+ {
+ /* Older controllers don't have brightness or saturation controls */
+ pAdaptor->nAttributes -= 4;
+ pAdaptor->pAttributes += 4;
+ }
+
+ pAdaptor->nImages = nATIMach64Image;
+ pAdaptor->pImages = ATIMach64Image;
+
+ pAdaptor->StopVideo = ATIMach64StopVideo;
+ pAdaptor->SetPortAttribute = ATIMach64SetPortAttribute;
+ pAdaptor->GetPortAttribute = ATIMach64GetPortAttribute;
+ pAdaptor->QueryBestSize = ATIMach64QueryBestSize;
+ pAdaptor->PutImage = ATIMach64PutImage;
+ pAdaptor->QueryImageAttributes = ATIMach64QueryImageAttributes;
+
+ REGION_NULL(pScreen, &pATI->VideoClip);
+ pATI->ActiveSurface = FALSE;
+
+ if (ATIMach64XVAtomGeneration != serverGeneration)
+ {
+ /* Refresh static data */
+ ATIMach64XVAtomGeneration = serverGeneration;
+
+ Index = nATIMach64Attribute - pAdaptor->nAttributes;
+ for (; Index < nATIMach64Attribute; Index++)
+ ATIMach64AttributeInfo[Index].AttributeID =
+ MAKE_ATOM(ATIMach64Attribute[Index].name);
+ }
+
+ ATIMach64SetDefaultAttributes(pATI, 0);
+
+ if (pATI->Chip < ATI_CHIP_264VTB)
+ {
+ xf86XVRegisterOffscreenImages(pScreen,
+ ATIMach64Surface_A, nATIMach64Surface_A);
+ }
+ else if (pATI->Chip < ATI_CHIP_264GTPRO)
+ {
+ xf86XVRegisterOffscreenImages(pScreen,
+ ATIMach64Surface_B, nATIMach64Surface_B);
+ }
+ else
+ {
+ xf86XVRegisterOffscreenImages(pScreen,
+ ATIMach64Surface_C, nATIMach64Surface_C);
+ }
+
+ return 1;
+}
+
+/*
+ * ATIMach64CloseXVideo --
+ *
+ * This function is called during screen termination to clean up after
+ * initialisation of Mach64 XVideo support.
+ */
+void
+ATIMach64CloseXVideo
+(
+ ScreenPtr pScreen,
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI
+)
+{
+ ATIMach64StopVideo(pScreenInfo, pATI, TRUE);
+
+ REGION_UNINIT(pScreen, &pATI->VideoClip);
+}
diff --git a/src/atimach64xv.h b/src/atimach64xv.h
new file mode 100644
index 00000000..8d5c07c9
--- /dev/null
+++ b/src/atimach64xv.h
@@ -0,0 +1,40 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64xv.h,v 1.1 2003/04/23 21:51:29 tsi Exp $ */
+/*
+ * Copyright 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+ *
+ * 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 Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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.
+ */
+
+#ifndef ___ATIMACH64XV_H___
+#define ___ATIMACH64XV_H___ 1
+
+#include "atipriv.h"
+#include "atiproto.h"
+
+#include "xf86str.h"
+#include "xf86xv.h"
+
+extern int ATIMach64XVInitialiseAdaptor
+ FunctionPrototype((ScreenPtr, ScrnInfoPtr, ATIPtr,
+ XF86VideoAdaptorPtr **));
+
+extern void ATIMach64CloseXVideo
+ FunctionPrototype((ScreenPtr, ScrnInfoPtr, ATIPtr));
+
+#endif /* ___ATIMACH64XV_H___ */
diff --git a/src/atituner.c b/src/atituner.c
new file mode 100644
index 00000000..55dc7c2e
--- /dev/null
+++ b/src/atituner.c
@@ -0,0 +1,174 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atituner.c,v 1.1 2003/07/24 22:08:28 tsi Exp $ */
+/*
+ * Copyright 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+ *
+ * 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 Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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.
+ */
+
+#include "atituner.h"
+
+/* Temporary interface glitch */
+#if 0
+# include "fi12x6.h"
+#else
+ typedef enum {
+ FI12x6_TYPE_UNKNOWN = -1,
+ FI12x6_TYPE_FI1236 = 0,
+ FI12x6_TYPE_FI1216,
+ FI12x6_TYPE_FI1216MF,
+ FI12x6_TYPE_TEMIC_FN5AL,
+ FI12x6_TYPE_MT2032,
+ FI12x6_TYPE_MAX /* Must be last */
+ } FI12x6TunerType;
+#endif
+
+/*
+ * TV tuner definitions.
+ */
+const SymTabRec ATITuners[] =
+{
+ {
+ FI12x6_TYPE_UNKNOWN,
+ "No tuner"
+ },
+ {
+ FI12x6_TYPE_FI1236,
+ "Philips FI1236 MK1 NTSC M/N North America"
+ },
+ {
+ FI12x6_TYPE_FI1236,
+ "Philips FI1236 MK2 NTSC M/N Japan"
+ },
+ {
+ FI12x6_TYPE_FI1216,
+ "Philips FI1216 MK2 PAL B/G"
+ },
+ {
+ FI12x6_TYPE_UNKNOWN,
+ "Philips FI1246 MK2 PAL I"
+ },
+ {
+ FI12x6_TYPE_FI1216MF,
+ "Philips FI1216 MF MK2 PAL B/G, SECAM L/L"
+ },
+ {
+ FI12x6_TYPE_FI1236,
+ "Philips FI1236 MK2 NTSC M/N North America"
+ },
+ {
+ FI12x6_TYPE_UNKNOWN,
+ "Philips FI1256 MK2 SECAM D/K"
+ },
+ {
+ FI12x6_TYPE_FI1236,
+ "Philips FM1236 MK2 NTSC M/N North America"
+ },
+ {
+ FI12x6_TYPE_FI1216,
+ "Philips FI1216 MK2 PAL B/G - External Tuner POD"
+ },
+ {
+ FI12x6_TYPE_UNKNOWN,
+ "Philips FI1246 MK2 PAL I - External Tuner POD"
+ },
+ {
+ FI12x6_TYPE_FI1216MF,
+ "Philips FI1216 MF MK2 PAL B/G, SECAM L/L - External Tuner POD"
+ },
+ {
+ FI12x6_TYPE_FI1236,
+ "Philips FI1236 MK2 NTSC M/N North America - External Tuner POD"
+ },
+ {
+ FI12x6_TYPE_TEMIC_FN5AL,
+ "Temic FN5AL.RF3X7595 PAL I/B/G/DK & SECAM DK"
+ },
+ {
+ FI12x6_TYPE_FI1216MF,
+ "Philips FQ1216 ME/P"
+ },
+ {
+ FI12x6_TYPE_UNKNOWN,
+ "Unknown type (15)"
+ },
+ {
+ FI12x6_TYPE_UNKNOWN,
+ "Alps TSBH5 NTSC M/N North America"
+ },
+ {
+ FI12x6_TYPE_UNKNOWN,
+ "Alps TSC?? NTSC M/N North America"
+ },
+ {
+ FI12x6_TYPE_UNKNOWN,
+ "Alps TSCH5 NTSC M/N North America with FM"
+ },
+ {
+ FI12x6_TYPE_UNKNOWN,
+ "Unknown type (19)"
+ },
+ {
+ FI12x6_TYPE_UNKNOWN,
+ "Unknown type (20)"
+ },
+ {
+ FI12x6_TYPE_UNKNOWN,
+ "Unknown type (21)"
+ },
+ {
+ FI12x6_TYPE_UNKNOWN,
+ "Unknown type (22)"
+ },
+ {
+ FI12x6_TYPE_UNKNOWN,
+ "Unknown type (23)"
+ },
+ {
+ FI12x6_TYPE_UNKNOWN,
+ "Unknown type (24)"
+ },
+ {
+ FI12x6_TYPE_UNKNOWN,
+ "Unknown type (25)"
+ },
+ {
+ FI12x6_TYPE_UNKNOWN,
+ "Unknown type (26)"
+ },
+ {
+ FI12x6_TYPE_UNKNOWN,
+ "Unknown type (27)"
+ },
+ {
+ FI12x6_TYPE_UNKNOWN,
+ "Unknown type (28)"
+ },
+ {
+ FI12x6_TYPE_MT2032,
+ "Microtune MT2032"
+ },
+ {
+ FI12x6_TYPE_UNKNOWN,
+ "Unknown type (30)"
+ },
+ {
+ FI12x6_TYPE_UNKNOWN,
+ "Unknown type (31)"
+ }
+};
diff --git a/src/atituner.h b/src/atituner.h
new file mode 100644
index 00000000..0c3c67f4
--- /dev/null
+++ b/src/atituner.h
@@ -0,0 +1,70 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atituner.h,v 1.1 2003/07/24 22:08:28 tsi Exp $ */
+/*
+ * Copyright 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+ *
+ * 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 Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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.
+ */
+
+#ifndef ___ATITUNER_H___
+#define ___ATITUNER_H___ 1
+
+#include "xf86str.h"
+
+/*
+ * TV Tuner definitions. Most of these are from Philips.
+ */
+typedef enum
+{
+ ATI_TUNER_NONE,
+ ATI_TUNER_FI1236MK1NA,
+ ATI_TUNER_FI1236MK2J,
+ ATI_TUNER_FI1216MK2BG,
+ ATI_TUNER_FI1246MK2I,
+ ATI_TUNER_FI1216MFMK2,
+ ATI_TUNER_FI1236MK2NA,
+ ATI_TUNER_FI1256MK2DK,
+ ATI_TUNER_FM1236MK2NA,
+ ATI_TUNER_FI1216MK2BGEXT,
+ ATI_TUNER_FI1246MK2IEXT,
+ ATI_TUNER_FI1216MFMK2EXT,
+ ATI_TUNER_FI1236MK2NAEXT,
+ ATI_TUNER_TEMIC_FN5AL,
+ ATI_TUNER_FQ1216MEP,
+ ATI_TUNER_15,
+ ATI_TUNER_ALPS_TSBH5,
+ ATI_TUNER_ALPS_TSCXX,
+ ATI_TUNER_ALPS_TSCH5,
+ ATI_TUNER_19,
+ ATI_TUNER_20,
+ ATI_TUNER_21,
+ ATI_TUNER_22,
+ ATI_TUNER_23,
+ ATI_TUNER_24,
+ ATI_TUNER_25,
+ ATI_TUNER_26,
+ ATI_TUNER_27,
+ ATI_TUNER_28,
+ ATI_TUNER_MT2032,
+ ATI_TUNER_30,
+ ATI_TUNER_31
+} ATITunerType;
+
+extern const SymTabRec ATITuners[];
+
+#endif /* ___ATITUNER_H___ */