132b578d3Smrg/* 232b578d3Smrg * Copyright 2001 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org 332b578d3Smrg * 432b578d3Smrg * Permission to use, copy, modify, distribute, and sell this software and its 532b578d3Smrg * documentation for any purpose is hereby granted without fee, provided that 632b578d3Smrg * the above copyright notice appear in all copies and that both that copyright 732b578d3Smrg * notice and this permission notice appear in supporting documentation, and 832b578d3Smrg * that the name of Marc Aurele La France not be used in advertising or 932b578d3Smrg * publicity pertaining to distribution of the software without specific, 1032b578d3Smrg * written prior permission. Marc Aurele La France makes no representations 1132b578d3Smrg * about the suitability of this software for any purpose. It is provided 1232b578d3Smrg * "as-is" without express or implied warranty. 1332b578d3Smrg * 1432b578d3Smrg * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1532b578d3Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 1632b578d3Smrg * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1732b578d3Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1832b578d3Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1932b578d3Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2032b578d3Smrg * PERFORMANCE OF THIS SOFTWARE. 2132b578d3Smrg */ 2232b578d3Smrg 2332b578d3Smrg#ifdef HAVE_CONFIG_H 2432b578d3Smrg#include "config.h" 2532b578d3Smrg#endif 2632b578d3Smrg 2732b578d3Smrg#include "ati.h" 2832b578d3Smrg#include "aticrtc.h" 2932b578d3Smrg#include "atimach64io.h" 3032b578d3Smrg#include "atirgb514.h" 3132b578d3Smrg 3232b578d3Smrg/* 3332b578d3Smrg * ATIRGB514PreInit -- 3432b578d3Smrg * 3532b578d3Smrg * This function fills in the IBM RGB 514 portion of an ATIHWRec that is common 3632b578d3Smrg * to all video modes generated by the server. 3732b578d3Smrg */ 3832b578d3Smrgvoid 3932b578d3SmrgATIRGB514PreInit 4032b578d3Smrg( 4132b578d3Smrg ATIPtr pATI, 4232b578d3Smrg ATIHWPtr pATIHW 4332b578d3Smrg) 4432b578d3Smrg{ 4532b578d3Smrg /* Get a work copy of IBM RGB 514 registers */ 4632b578d3Smrg ATIRGB514Save(pATI, pATIHW); 4732b578d3Smrg 4832b578d3Smrg /* Miscellaneous Clock Control */ 4932b578d3Smrg pATIHW->ibmrgb514[0x0002U] = 0x01U; 5032b578d3Smrg 5132b578d3Smrg /* Sync Control */ 5232b578d3Smrg pATIHW->ibmrgb514[0x0003U] &= ~0x80U; 5332b578d3Smrg 5432b578d3Smrg /* Horizontal Sync Control */ 5532b578d3Smrg pATIHW->ibmrgb514[0x0004U] = 0x00U; 5632b578d3Smrg 5732b578d3Smrg /* Power Management */ 5832b578d3Smrg pATIHW->ibmrgb514[0x0005U] = 0x00U; 5932b578d3Smrg 6032b578d3Smrg /* DAC Operation */ 6132b578d3Smrg pATIHW->ibmrgb514[0x0006U] &= ~0x04U; 6232b578d3Smrg 6332b578d3Smrg /* Palette Control */ 6432b578d3Smrg pATIHW->ibmrgb514[0x0007U] = 0x00U; 6532b578d3Smrg 6632b578d3Smrg /* PLL Control */ 6732b578d3Smrg pATIHW->ibmrgb514[0x0010U] = 0x01U; 6832b578d3Smrg 6932b578d3Smrg /* Cursor control */ 7032b578d3Smrg pATIHW->ibmrgb514[0x0030U] &= ~0x03U; /* For now */ 7132b578d3Smrg 7232b578d3Smrg /* Border (i.e. overscan) */ 7332b578d3Smrg pATIHW->ibmrgb514[0x0060U] = 0x00U; 7432b578d3Smrg pATIHW->ibmrgb514[0x0061U] = 0x00U; 7532b578d3Smrg pATIHW->ibmrgb514[0x0062U] = 0x00U; 7632b578d3Smrg 7732b578d3Smrg /* Miscellaneous Control */ 7832b578d3Smrg pATIHW->ibmrgb514[0x0070U] &= ~0x20U; 7932b578d3Smrg pATIHW->ibmrgb514[0x0071U] = 0x41U; /* See workaround in ATIRGB514Set() */ 8032b578d3Smrg 8132b578d3Smrg#ifndef AVOID_CPIO 8232b578d3Smrg 8332b578d3Smrg if (pATIHW->crtc == ATI_CRTC_VGA) 8432b578d3Smrg { 8532b578d3Smrg /* Pixel Format */ 8632b578d3Smrg pATIHW->ibmrgb514[0x000AU] = 0x03U; 8732b578d3Smrg 8832b578d3Smrg /* Miscellaneous Control */ 8932b578d3Smrg pATIHW->ibmrgb514[0x0070U] |= 0x40U; 9032b578d3Smrg 9132b578d3Smrg /* VRAM Mask */ 9232b578d3Smrg pATIHW->ibmrgb514[0x0090U] = 0x03U; 9332b578d3Smrg } 9432b578d3Smrg else 9532b578d3Smrg 9632b578d3Smrg#endif /* AVOID_CPIO */ 9732b578d3Smrg 9832b578d3Smrg { 9932b578d3Smrg /* Miscellaneous Control */ 10032b578d3Smrg pATIHW->ibmrgb514[0x0070U] &= ~0x40U; 10132b578d3Smrg 10232b578d3Smrg /* VRAM Mask */ 10332b578d3Smrg pATIHW->ibmrgb514[0x0090U] = 0x00U; 10432b578d3Smrg pATIHW->ibmrgb514[0x0091U] = 0x00U; 10532b578d3Smrg 10632b578d3Smrg /* Pixel Format */ 10732b578d3Smrg switch (pATI->depth) 10832b578d3Smrg { 10932b578d3Smrg case 8: 11032b578d3Smrg pATIHW->ibmrgb514[0x000AU] = 0x03U; 11132b578d3Smrg pATIHW->ibmrgb514[0x000BU] = 0x00U; 11232b578d3Smrg break; 11332b578d3Smrg 11432b578d3Smrg case 15: 11532b578d3Smrg pATIHW->ibmrgb514[0x000AU] = 0x04U; 11632b578d3Smrg pATIHW->ibmrgb514[0x000CU] = 0xC4U; 11732b578d3Smrg break; 11832b578d3Smrg 11932b578d3Smrg case 16: 12032b578d3Smrg pATIHW->ibmrgb514[0x000AU] = 0x04U; 12132b578d3Smrg pATIHW->ibmrgb514[0x000CU] = 0xC6U; 12232b578d3Smrg break; 12332b578d3Smrg 12432b578d3Smrg case 24: 12532b578d3Smrg if (pATI->bitsPerPixel == 24) 12632b578d3Smrg { 12732b578d3Smrg pATIHW->ibmrgb514[0x000AU] = 0x05U; 12832b578d3Smrg pATIHW->ibmrgb514[0x000DU] = 0x01U; 12932b578d3Smrg } 13032b578d3Smrg else 13132b578d3Smrg { 13232b578d3Smrg pATIHW->ibmrgb514[0x000AU] = 0x06U; 13332b578d3Smrg pATIHW->ibmrgb514[0x000EU] = 0x03U; 13432b578d3Smrg } 13532b578d3Smrg break; 13632b578d3Smrg 13732b578d3Smrg default: 13832b578d3Smrg break; 13932b578d3Smrg } 14032b578d3Smrg } 14132b578d3Smrg 14232b578d3Smrg if (pATI->rgbBits == 8) 14332b578d3Smrg pATIHW->ibmrgb514[0x0071U] |= 0x04U; 14432b578d3Smrg} 14532b578d3Smrg 14632b578d3Smrg/* 14732b578d3Smrg * ATIRGB514Save -- 14832b578d3Smrg * 14932b578d3Smrg * This function saves IBM RGB514 related data into an ATIHWRec. 15032b578d3Smrg */ 15132b578d3Smrgvoid 15232b578d3SmrgATIRGB514Save 15332b578d3Smrg( 15432b578d3Smrg ATIPtr pATI, 15532b578d3Smrg ATIHWPtr pATIHW 15632b578d3Smrg) 15732b578d3Smrg{ 15832b578d3Smrg CARD32 crtc_gen_cntl, dac_cntl; 15932b578d3Smrg CARD8 index_lo, index_hi, index_ctl; 16032b578d3Smrg int Index; 16132b578d3Smrg 16232b578d3Smrg /* Temporarily switch to Mach64 CRTC */ 16332b578d3Smrg crtc_gen_cntl = inr(CRTC_GEN_CNTL); 16432b578d3Smrg if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN)) 16532b578d3Smrg outr(CRTC_GEN_CNTL, crtc_gen_cntl | CRTC_EXT_DISP_EN); 16632b578d3Smrg 16732b578d3Smrg /* Temporarily switch to IBM RGB 514 registers */ 16832b578d3Smrg dac_cntl = inr(DAC_CNTL) & ~(DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3); 16932b578d3Smrg outr(DAC_CNTL, dac_cntl | DAC_EXT_SEL_RS2); 17032b578d3Smrg 17132b578d3Smrg index_lo = in8(M64_DAC_WRITE); 17232b578d3Smrg index_hi = in8(M64_DAC_DATA); 17332b578d3Smrg index_ctl = in8(M64_DAC_READ); 17432b578d3Smrg 17532b578d3Smrg out8(M64_DAC_WRITE, 0x00U); 17632b578d3Smrg out8(M64_DAC_DATA, 0x00U); 17732b578d3Smrg out8(M64_DAC_READ, 0x01U); /* Auto-increment */ 17832b578d3Smrg 17932b578d3Smrg /* Save IBM RGB 514 registers */ 18032b578d3Smrg for (Index = 0; Index < NumberOf(pATIHW->ibmrgb514); Index++) 18132b578d3Smrg { 18232b578d3Smrg /* Need to rewrite the index every so often... */ 18332b578d3Smrg if ((Index == 0x0100) || (Index == 0x0500)) 18432b578d3Smrg { 18532b578d3Smrg out8(M64_DAC_WRITE, 0); 18632b578d3Smrg out8(M64_DAC_DATA, Index >> 8); 18732b578d3Smrg } 18832b578d3Smrg pATIHW->ibmrgb514[Index] = in8(M64_DAC_MASK); 18932b578d3Smrg } 19032b578d3Smrg 19132b578d3Smrg /* Restore registers */ 19232b578d3Smrg out8(M64_DAC_WRITE, index_lo); 19332b578d3Smrg out8(M64_DAC_DATA, index_hi); 19432b578d3Smrg out8(M64_DAC_READ, index_ctl); 19532b578d3Smrg outr(DAC_CNTL, dac_cntl); 19632b578d3Smrg if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN)) 19732b578d3Smrg outr(CRTC_GEN_CNTL, crtc_gen_cntl); 19832b578d3Smrg} 19932b578d3Smrg 20032b578d3Smrg/* 20132b578d3Smrg * ATIRGB514Calculate -- 20232b578d3Smrg * 20332b578d3Smrg * This function fills in the IBM RGB 514 portion of an ATIHWRec that is 20432b578d3Smrg * specific to a display mode. pATIHW->ibmrgb514 has already been 20532b578d3Smrg * initialised by a previous call to ATIRGB514PreInit(). 20632b578d3Smrg */ 20732b578d3Smrgvoid 20832b578d3SmrgATIRGB514Calculate 20932b578d3Smrg( 21032b578d3Smrg ATIPtr pATI, 21132b578d3Smrg ATIHWPtr pATIHW, 21232b578d3Smrg DisplayModePtr pMode 21332b578d3Smrg) 21432b578d3Smrg{ 21532b578d3Smrg if (pATI->OptionCSync || (pMode->Flags & (V_CSYNC | V_PCSYNC))) 21632b578d3Smrg pATIHW->ibmrgb514[0x0006U] |= 0x08U; 21732b578d3Smrg else 21832b578d3Smrg pATIHW->ibmrgb514[0x0006U] &= ~0x08U; 21932b578d3Smrg 22032b578d3Smrg if (pMode->Flags & V_INTERLACE) 22132b578d3Smrg pATIHW->ibmrgb514[0x0071U] |= 0x20U; 22232b578d3Smrg else 22332b578d3Smrg pATIHW->ibmrgb514[0x0071U] &= ~0x20U; 22432b578d3Smrg} 22532b578d3Smrg 22632b578d3Smrg/* 22732b578d3Smrg * ATIRGB514Set -- 22832b578d3Smrg * 22932b578d3Smrg * This function is called to set an IBM RGB514's registers. 23032b578d3Smrg */ 23132b578d3Smrgvoid 23232b578d3SmrgATIRGB514Set 23332b578d3Smrg( 23432b578d3Smrg ATIPtr pATI, 23532b578d3Smrg ATIHWPtr pATIHW 23632b578d3Smrg) 23732b578d3Smrg{ 23832b578d3Smrg CARD32 crtc_gen_cntl, dac_cntl; 23932b578d3Smrg CARD8 index_lo, index_hi, index_ctl; 24032b578d3Smrg int Index; 24132b578d3Smrg 24232b578d3Smrg /* Temporarily switch to Mach64 CRTC */ 24332b578d3Smrg crtc_gen_cntl = inr(CRTC_GEN_CNTL); 24432b578d3Smrg if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN)) 24532b578d3Smrg outr(CRTC_GEN_CNTL, crtc_gen_cntl | CRTC_EXT_DISP_EN); 24632b578d3Smrg 24732b578d3Smrg /* Temporarily switch to IBM RGB 514 registers */ 24832b578d3Smrg dac_cntl = inr(DAC_CNTL) & ~(DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3); 24932b578d3Smrg outr(DAC_CNTL, dac_cntl | DAC_EXT_SEL_RS2); 25032b578d3Smrg 25132b578d3Smrg index_lo = in8(M64_DAC_WRITE); 25232b578d3Smrg index_hi = in8(M64_DAC_DATA); 25332b578d3Smrg index_ctl = in8(M64_DAC_READ); 25432b578d3Smrg 25532b578d3Smrg out8(M64_DAC_WRITE, 0x00U); 25632b578d3Smrg out8(M64_DAC_DATA, 0x00U); 25732b578d3Smrg out8(M64_DAC_READ, 0x01U); /* Auto-increment */ 25832b578d3Smrg 25932b578d3Smrg /* Load IBM RGB 514 registers */ 26032b578d3Smrg for (Index = 0; Index < NumberOf(pATIHW->ibmrgb514); Index++) 26132b578d3Smrg out8(M64_DAC_MASK, pATIHW->ibmrgb514[Index]); 26232b578d3Smrg 26332b578d3Smrg#ifndef AVOID_CPIO 26432b578d3Smrg 26532b578d3Smrg /* Deal with documented anomaly */ 26632b578d3Smrg if (pATIHW->crtc == ATI_CRTC_VGA) 26732b578d3Smrg { 26832b578d3Smrg /* Reset Miscellaneous Control 2 */ 26932b578d3Smrg out8(M64_DAC_WRITE, 0x71U); 27032b578d3Smrg out8(M64_DAC_DATA, 0x00U); 27132b578d3Smrg out8(M64_DAC_MASK, pATIHW->ibmrgb514[0x0071U] & ~0x41U); 27232b578d3Smrg } 27332b578d3Smrg 27432b578d3Smrg#endif /* AVOID_CPIO */ 27532b578d3Smrg 27632b578d3Smrg /* Restore registers */ 27732b578d3Smrg out8(M64_DAC_WRITE, index_lo); 27832b578d3Smrg out8(M64_DAC_DATA, index_hi); 27932b578d3Smrg out8(M64_DAC_READ, index_ctl); 28032b578d3Smrg outr(DAC_CNTL, dac_cntl); 28132b578d3Smrg if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN)) 28232b578d3Smrg outr(CRTC_GEN_CNTL, crtc_gen_cntl); 28332b578d3Smrg} 284