summaryrefslogtreecommitdiff
path: root/src/atirgb514.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/atirgb514.c')
-rw-r--r--src/atirgb514.c280
1 files changed, 280 insertions, 0 deletions
diff --git a/src/atirgb514.c b/src/atirgb514.c
new file mode 100644
index 00000000..bedb7940
--- /dev/null
+++ b/src/atirgb514.c
@@ -0,0 +1,280 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atirgb514.c,v 1.4 2003/01/01 19:16:34 tsi Exp $ */
+/*
+ * Copyright 2001 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 "aticrtc.h"
+#include "atimach64io.h"
+#include "atirgb514.h"
+
+/*
+ * ATIRGB514PreInit --
+ *
+ * This function fills in the IBM RGB 514 portion of an ATIHWRec that is common
+ * to all video modes generated by the server.
+ */
+void
+ATIRGB514PreInit
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ /* Get a work copy of IBM RGB 514 registers */
+ ATIRGB514Save(pATI, pATIHW);
+
+ /* Miscellaneous Clock Control */
+ pATIHW->ibmrgb514[0x0002U] = 0x01U;
+
+ /* Sync Control */
+ pATIHW->ibmrgb514[0x0003U] &= ~0x80U;
+
+ /* Horizontal Sync Control */
+ pATIHW->ibmrgb514[0x0004U] = 0x00U;
+
+ /* Power Management */
+ pATIHW->ibmrgb514[0x0005U] = 0x00U;
+
+ /* DAC Operation */
+ pATIHW->ibmrgb514[0x0006U] &= ~0x04U;
+
+ /* Palette Control */
+ pATIHW->ibmrgb514[0x0007U] = 0x00U;
+
+ /* PLL Control */
+ pATIHW->ibmrgb514[0x0010U] = 0x01U;
+
+ /* Cursor control */
+ pATIHW->ibmrgb514[0x0030U] &= ~0x03U; /* For now */
+
+ /* Border (i.e. overscan) */
+ pATIHW->ibmrgb514[0x0060U] = 0x00U;
+ pATIHW->ibmrgb514[0x0061U] = 0x00U;
+ pATIHW->ibmrgb514[0x0062U] = 0x00U;
+
+ /* Miscellaneous Control */
+ pATIHW->ibmrgb514[0x0070U] &= ~0x20U;
+ pATIHW->ibmrgb514[0x0071U] = 0x41U; /* See workaround in ATIRGB514Set() */
+
+#ifndef AVOID_CPIO
+
+ if (pATIHW->crtc == ATI_CRTC_VGA)
+ {
+ /* Pixel Format */
+ pATIHW->ibmrgb514[0x000AU] = 0x03U;
+
+ /* Miscellaneous Control */
+ pATIHW->ibmrgb514[0x0070U] |= 0x40U;
+
+ /* VRAM Mask */
+ pATIHW->ibmrgb514[0x0090U] = 0x03U;
+ }
+ else
+
+#endif /* AVOID_CPIO */
+
+ {
+ /* Miscellaneous Control */
+ pATIHW->ibmrgb514[0x0070U] &= ~0x40U;
+
+ /* VRAM Mask */
+ pATIHW->ibmrgb514[0x0090U] = 0x00U;
+ pATIHW->ibmrgb514[0x0091U] = 0x00U;
+
+ /* Pixel Format */
+ switch (pATI->depth)
+ {
+ case 8:
+ pATIHW->ibmrgb514[0x000AU] = 0x03U;
+ pATIHW->ibmrgb514[0x000BU] = 0x00U;
+ break;
+
+ case 15:
+ pATIHW->ibmrgb514[0x000AU] = 0x04U;
+ pATIHW->ibmrgb514[0x000CU] = 0xC4U;
+ break;
+
+ case 16:
+ pATIHW->ibmrgb514[0x000AU] = 0x04U;
+ pATIHW->ibmrgb514[0x000CU] = 0xC6U;
+ break;
+
+ case 24:
+ if (pATI->bitsPerPixel == 24)
+ {
+ pATIHW->ibmrgb514[0x000AU] = 0x05U;
+ pATIHW->ibmrgb514[0x000DU] = 0x01U;
+ }
+ else
+ {
+ pATIHW->ibmrgb514[0x000AU] = 0x06U;
+ pATIHW->ibmrgb514[0x000EU] = 0x03U;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (pATI->rgbBits == 8)
+ pATIHW->ibmrgb514[0x0071U] |= 0x04U;
+}
+
+/*
+ * ATIRGB514Save --
+ *
+ * This function saves IBM RGB514 related data into an ATIHWRec.
+ */
+void
+ATIRGB514Save
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ CARD32 crtc_gen_cntl, dac_cntl;
+ CARD8 index_lo, index_hi, index_ctl;
+ int Index;
+
+ /* Temporarily switch to Mach64 CRTC */
+ crtc_gen_cntl = inr(CRTC_GEN_CNTL);
+ if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN))
+ outr(CRTC_GEN_CNTL, crtc_gen_cntl | CRTC_EXT_DISP_EN);
+
+ /* Temporarily switch to IBM RGB 514 registers */
+ dac_cntl = inr(DAC_CNTL) & ~(DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3);
+ outr(DAC_CNTL, dac_cntl | DAC_EXT_SEL_RS2);
+
+ index_lo = in8(M64_DAC_WRITE);
+ index_hi = in8(M64_DAC_DATA);
+ index_ctl = in8(M64_DAC_READ);
+
+ out8(M64_DAC_WRITE, 0x00U);
+ out8(M64_DAC_DATA, 0x00U);
+ out8(M64_DAC_READ, 0x01U); /* Auto-increment */
+
+ /* Save IBM RGB 514 registers */
+ for (Index = 0; Index < NumberOf(pATIHW->ibmrgb514); Index++)
+ {
+ /* Need to rewrite the index every so often... */
+ if ((Index == 0x0100) || (Index == 0x0500))
+ {
+ out8(M64_DAC_WRITE, 0);
+ out8(M64_DAC_DATA, Index >> 8);
+ }
+ pATIHW->ibmrgb514[Index] = in8(M64_DAC_MASK);
+ }
+
+ /* Restore registers */
+ out8(M64_DAC_WRITE, index_lo);
+ out8(M64_DAC_DATA, index_hi);
+ out8(M64_DAC_READ, index_ctl);
+ outr(DAC_CNTL, dac_cntl);
+ if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN))
+ outr(CRTC_GEN_CNTL, crtc_gen_cntl);
+}
+
+/*
+ * ATIRGB514Calculate --
+ *
+ * This function fills in the IBM RGB 514 portion of an ATIHWRec that is
+ * specific to a display mode. pATIHW->ibmrgb514 has already been
+ * initialised by a previous call to ATIRGB514PreInit().
+ */
+void
+ATIRGB514Calculate
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW,
+ DisplayModePtr pMode
+)
+{
+ if (pATI->OptionCSync || (pMode->Flags & (V_CSYNC | V_PCSYNC)))
+ pATIHW->ibmrgb514[0x0006U] |= 0x08U;
+ else
+ pATIHW->ibmrgb514[0x0006U] &= ~0x08U;
+
+ if (pMode->Flags & V_INTERLACE)
+ pATIHW->ibmrgb514[0x0071U] |= 0x20U;
+ else
+ pATIHW->ibmrgb514[0x0071U] &= ~0x20U;
+}
+
+/*
+ * ATIRGB514Set --
+ *
+ * This function is called to set an IBM RGB514's registers.
+ */
+void
+ATIRGB514Set
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ CARD32 crtc_gen_cntl, dac_cntl;
+ CARD8 index_lo, index_hi, index_ctl;
+ int Index;
+
+ /* Temporarily switch to Mach64 CRTC */
+ crtc_gen_cntl = inr(CRTC_GEN_CNTL);
+ if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN))
+ outr(CRTC_GEN_CNTL, crtc_gen_cntl | CRTC_EXT_DISP_EN);
+
+ /* Temporarily switch to IBM RGB 514 registers */
+ dac_cntl = inr(DAC_CNTL) & ~(DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3);
+ outr(DAC_CNTL, dac_cntl | DAC_EXT_SEL_RS2);
+
+ index_lo = in8(M64_DAC_WRITE);
+ index_hi = in8(M64_DAC_DATA);
+ index_ctl = in8(M64_DAC_READ);
+
+ out8(M64_DAC_WRITE, 0x00U);
+ out8(M64_DAC_DATA, 0x00U);
+ out8(M64_DAC_READ, 0x01U); /* Auto-increment */
+
+ /* Load IBM RGB 514 registers */
+ for (Index = 0; Index < NumberOf(pATIHW->ibmrgb514); Index++)
+ out8(M64_DAC_MASK, pATIHW->ibmrgb514[Index]);
+
+#ifndef AVOID_CPIO
+
+ /* Deal with documented anomaly */
+ if (pATIHW->crtc == ATI_CRTC_VGA)
+ {
+ /* Reset Miscellaneous Control 2 */
+ out8(M64_DAC_WRITE, 0x71U);
+ out8(M64_DAC_DATA, 0x00U);
+ out8(M64_DAC_MASK, pATIHW->ibmrgb514[0x0071U] & ~0x41U);
+ }
+
+#endif /* AVOID_CPIO */
+
+ /* Restore registers */
+ out8(M64_DAC_WRITE, index_lo);
+ out8(M64_DAC_DATA, index_hi);
+ out8(M64_DAC_READ, index_ctl);
+ outr(DAC_CNTL, dac_cntl);
+ if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN))
+ outr(CRTC_GEN_CNTL, crtc_gen_cntl);
+}