diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-25 19:28:36 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-25 19:28:36 +0000 |
commit | 0a53864f9581196604d04fd28b4e94a9b0b73d18 (patch) | |
tree | 9b2bb4434bc2be3f3dbd14a96e06647be46c152c | |
parent | c56aaef79028261e0a3be0c86ffd3f16b6bdd9ba (diff) |
Initial revisionXORG-STABLE
-rw-r--r-- | src/atiaudio.c | 47 | ||||
-rw-r--r-- | src/atiaudio.h | 52 | ||||
-rw-r--r-- | src/atidecoder.c | 47 | ||||
-rw-r--r-- | src/atidecoder.h | 52 | ||||
-rw-r--r-- | src/atii2c.c | 387 | ||||
-rw-r--r-- | src/atii2c.h | 50 | ||||
-rw-r--r-- | src/atimach64accel.c | 862 | ||||
-rw-r--r-- | src/atimach64accel.h | 38 | ||||
-rw-r--r-- | src/atimach64cursor.c | 400 | ||||
-rw-r--r-- | src/atimach64cursor.h | 33 | ||||
-rw-r--r-- | src/atimach64i2c.c | 466 | ||||
-rw-r--r-- | src/atimach64i2c.h | 34 | ||||
-rw-r--r-- | src/atimach64xv.c | 1493 | ||||
-rw-r--r-- | src/atimach64xv.h | 40 | ||||
-rw-r--r-- | src/atituner.c | 174 | ||||
-rw-r--r-- | src/atituner.h | 70 |
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___ */ |