summaryrefslogtreecommitdiff
path: root/src/atiwonderio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/atiwonderio.c')
-rw-r--r--src/atiwonderio.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/atiwonderio.c b/src/atiwonderio.c
new file mode 100644
index 00000000..064e49ed
--- /dev/null
+++ b/src/atiwonderio.c
@@ -0,0 +1,86 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiwonderio.c,v 1.4 2003/01/01 19:16:35 tsi Exp $ */
+/*
+ * Copyright 2000 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.
+ */
+
+#include "ati.h"
+#include "atichip.h"
+#include "atiwonderio.h"
+
+#ifndef AVOID_CPIO
+
+/*
+ * ATIModifyExtReg --
+ *
+ * This function is called to modify certain bits in an ATI extended VGA
+ * register while preserving its other bits. The function will not write the
+ * register if it turns out its value would not change. This helps prevent
+ * server hangs on older adapters.
+ */
+void
+ATIModifyExtReg
+(
+ ATIPtr pATI,
+ const CARD8 Index,
+ int CurrentValue,
+ const CARD8 CurrentMask,
+ CARD8 NewValue
+)
+{
+ /* Possibly retrieve the current value */
+ if (CurrentValue < 0)
+ CurrentValue = ATIGetExtReg(Index);
+
+ /* Compute new value */
+ NewValue &= (CARD8)(~CurrentMask);
+ NewValue |= CurrentValue & CurrentMask;
+
+ /* Check if value will be changed */
+ if (CurrentValue == NewValue)
+ return;
+
+ /*
+ * The following is taken from ATI's VGA Wonder programmer's reference
+ * manual which says that this is needed to "ensure the proper state of the
+ * 8/16 bit ROM toggle". I suspect a timing glitch appeared in the 18800
+ * after its die was cast. 18800-1 and later chips do not exhibit this
+ * problem.
+ */
+ if ((pATI->Chip <= ATI_CHIP_18800) && (Index == 0xB2U) &&
+ ((NewValue ^ 0x40U) & CurrentValue & 0x40U))
+ {
+ CARD8 misc = inb(R_GENMO);
+ CARD8 bb = ATIGetExtReg(0xBBU);
+
+ outb(GENMO, (misc & 0xF3U) | 0x04U | ((bb & 0x10U) >> 1));
+ CurrentValue &= (CARD8)(~0x40U);
+ ATIPutExtReg(0xB2U, CurrentValue);
+ ATIDelay(5);
+ outb(GENMO, misc);
+ ATIDelay(5);
+ if (CurrentValue != NewValue)
+ ATIPutExtReg(0xB2U, NewValue);
+ }
+ else
+ ATIPutExtReg(Index, NewValue);
+}
+
+#endif /* AVOID_CPIO */