atirgb514.c revision 32b578d3
1/* 2 * Copyright 2001 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that copyright 7 * notice and this permission notice appear in supporting documentation, and 8 * that the name of Marc Aurele La France not be used in advertising or 9 * publicity pertaining to distribution of the software without specific, 10 * written prior permission. Marc Aurele La France makes no representations 11 * about the suitability of this software for any purpose. It is provided 12 * "as-is" without express or implied warranty. 13 * 14 * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 16 * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 */ 22 23#ifdef HAVE_CONFIG_H 24#include "config.h" 25#endif 26 27#include "ati.h" 28#include "aticrtc.h" 29#include "atimach64io.h" 30#include "atirgb514.h" 31 32/* 33 * ATIRGB514PreInit -- 34 * 35 * This function fills in the IBM RGB 514 portion of an ATIHWRec that is common 36 * to all video modes generated by the server. 37 */ 38void 39ATIRGB514PreInit 40( 41 ATIPtr pATI, 42 ATIHWPtr pATIHW 43) 44{ 45 /* Get a work copy of IBM RGB 514 registers */ 46 ATIRGB514Save(pATI, pATIHW); 47 48 /* Miscellaneous Clock Control */ 49 pATIHW->ibmrgb514[0x0002U] = 0x01U; 50 51 /* Sync Control */ 52 pATIHW->ibmrgb514[0x0003U] &= ~0x80U; 53 54 /* Horizontal Sync Control */ 55 pATIHW->ibmrgb514[0x0004U] = 0x00U; 56 57 /* Power Management */ 58 pATIHW->ibmrgb514[0x0005U] = 0x00U; 59 60 /* DAC Operation */ 61 pATIHW->ibmrgb514[0x0006U] &= ~0x04U; 62 63 /* Palette Control */ 64 pATIHW->ibmrgb514[0x0007U] = 0x00U; 65 66 /* PLL Control */ 67 pATIHW->ibmrgb514[0x0010U] = 0x01U; 68 69 /* Cursor control */ 70 pATIHW->ibmrgb514[0x0030U] &= ~0x03U; /* For now */ 71 72 /* Border (i.e. overscan) */ 73 pATIHW->ibmrgb514[0x0060U] = 0x00U; 74 pATIHW->ibmrgb514[0x0061U] = 0x00U; 75 pATIHW->ibmrgb514[0x0062U] = 0x00U; 76 77 /* Miscellaneous Control */ 78 pATIHW->ibmrgb514[0x0070U] &= ~0x20U; 79 pATIHW->ibmrgb514[0x0071U] = 0x41U; /* See workaround in ATIRGB514Set() */ 80 81#ifndef AVOID_CPIO 82 83 if (pATIHW->crtc == ATI_CRTC_VGA) 84 { 85 /* Pixel Format */ 86 pATIHW->ibmrgb514[0x000AU] = 0x03U; 87 88 /* Miscellaneous Control */ 89 pATIHW->ibmrgb514[0x0070U] |= 0x40U; 90 91 /* VRAM Mask */ 92 pATIHW->ibmrgb514[0x0090U] = 0x03U; 93 } 94 else 95 96#endif /* AVOID_CPIO */ 97 98 { 99 /* Miscellaneous Control */ 100 pATIHW->ibmrgb514[0x0070U] &= ~0x40U; 101 102 /* VRAM Mask */ 103 pATIHW->ibmrgb514[0x0090U] = 0x00U; 104 pATIHW->ibmrgb514[0x0091U] = 0x00U; 105 106 /* Pixel Format */ 107 switch (pATI->depth) 108 { 109 case 8: 110 pATIHW->ibmrgb514[0x000AU] = 0x03U; 111 pATIHW->ibmrgb514[0x000BU] = 0x00U; 112 break; 113 114 case 15: 115 pATIHW->ibmrgb514[0x000AU] = 0x04U; 116 pATIHW->ibmrgb514[0x000CU] = 0xC4U; 117 break; 118 119 case 16: 120 pATIHW->ibmrgb514[0x000AU] = 0x04U; 121 pATIHW->ibmrgb514[0x000CU] = 0xC6U; 122 break; 123 124 case 24: 125 if (pATI->bitsPerPixel == 24) 126 { 127 pATIHW->ibmrgb514[0x000AU] = 0x05U; 128 pATIHW->ibmrgb514[0x000DU] = 0x01U; 129 } 130 else 131 { 132 pATIHW->ibmrgb514[0x000AU] = 0x06U; 133 pATIHW->ibmrgb514[0x000EU] = 0x03U; 134 } 135 break; 136 137 default: 138 break; 139 } 140 } 141 142 if (pATI->rgbBits == 8) 143 pATIHW->ibmrgb514[0x0071U] |= 0x04U; 144} 145 146/* 147 * ATIRGB514Save -- 148 * 149 * This function saves IBM RGB514 related data into an ATIHWRec. 150 */ 151void 152ATIRGB514Save 153( 154 ATIPtr pATI, 155 ATIHWPtr pATIHW 156) 157{ 158 CARD32 crtc_gen_cntl, dac_cntl; 159 CARD8 index_lo, index_hi, index_ctl; 160 int Index; 161 162 /* Temporarily switch to Mach64 CRTC */ 163 crtc_gen_cntl = inr(CRTC_GEN_CNTL); 164 if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN)) 165 outr(CRTC_GEN_CNTL, crtc_gen_cntl | CRTC_EXT_DISP_EN); 166 167 /* Temporarily switch to IBM RGB 514 registers */ 168 dac_cntl = inr(DAC_CNTL) & ~(DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3); 169 outr(DAC_CNTL, dac_cntl | DAC_EXT_SEL_RS2); 170 171 index_lo = in8(M64_DAC_WRITE); 172 index_hi = in8(M64_DAC_DATA); 173 index_ctl = in8(M64_DAC_READ); 174 175 out8(M64_DAC_WRITE, 0x00U); 176 out8(M64_DAC_DATA, 0x00U); 177 out8(M64_DAC_READ, 0x01U); /* Auto-increment */ 178 179 /* Save IBM RGB 514 registers */ 180 for (Index = 0; Index < NumberOf(pATIHW->ibmrgb514); Index++) 181 { 182 /* Need to rewrite the index every so often... */ 183 if ((Index == 0x0100) || (Index == 0x0500)) 184 { 185 out8(M64_DAC_WRITE, 0); 186 out8(M64_DAC_DATA, Index >> 8); 187 } 188 pATIHW->ibmrgb514[Index] = in8(M64_DAC_MASK); 189 } 190 191 /* Restore registers */ 192 out8(M64_DAC_WRITE, index_lo); 193 out8(M64_DAC_DATA, index_hi); 194 out8(M64_DAC_READ, index_ctl); 195 outr(DAC_CNTL, dac_cntl); 196 if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN)) 197 outr(CRTC_GEN_CNTL, crtc_gen_cntl); 198} 199 200/* 201 * ATIRGB514Calculate -- 202 * 203 * This function fills in the IBM RGB 514 portion of an ATIHWRec that is 204 * specific to a display mode. pATIHW->ibmrgb514 has already been 205 * initialised by a previous call to ATIRGB514PreInit(). 206 */ 207void 208ATIRGB514Calculate 209( 210 ATIPtr pATI, 211 ATIHWPtr pATIHW, 212 DisplayModePtr pMode 213) 214{ 215 if (pATI->OptionCSync || (pMode->Flags & (V_CSYNC | V_PCSYNC))) 216 pATIHW->ibmrgb514[0x0006U] |= 0x08U; 217 else 218 pATIHW->ibmrgb514[0x0006U] &= ~0x08U; 219 220 if (pMode->Flags & V_INTERLACE) 221 pATIHW->ibmrgb514[0x0071U] |= 0x20U; 222 else 223 pATIHW->ibmrgb514[0x0071U] &= ~0x20U; 224} 225 226/* 227 * ATIRGB514Set -- 228 * 229 * This function is called to set an IBM RGB514's registers. 230 */ 231void 232ATIRGB514Set 233( 234 ATIPtr pATI, 235 ATIHWPtr pATIHW 236) 237{ 238 CARD32 crtc_gen_cntl, dac_cntl; 239 CARD8 index_lo, index_hi, index_ctl; 240 int Index; 241 242 /* Temporarily switch to Mach64 CRTC */ 243 crtc_gen_cntl = inr(CRTC_GEN_CNTL); 244 if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN)) 245 outr(CRTC_GEN_CNTL, crtc_gen_cntl | CRTC_EXT_DISP_EN); 246 247 /* Temporarily switch to IBM RGB 514 registers */ 248 dac_cntl = inr(DAC_CNTL) & ~(DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3); 249 outr(DAC_CNTL, dac_cntl | DAC_EXT_SEL_RS2); 250 251 index_lo = in8(M64_DAC_WRITE); 252 index_hi = in8(M64_DAC_DATA); 253 index_ctl = in8(M64_DAC_READ); 254 255 out8(M64_DAC_WRITE, 0x00U); 256 out8(M64_DAC_DATA, 0x00U); 257 out8(M64_DAC_READ, 0x01U); /* Auto-increment */ 258 259 /* Load IBM RGB 514 registers */ 260 for (Index = 0; Index < NumberOf(pATIHW->ibmrgb514); Index++) 261 out8(M64_DAC_MASK, pATIHW->ibmrgb514[Index]); 262 263#ifndef AVOID_CPIO 264 265 /* Deal with documented anomaly */ 266 if (pATIHW->crtc == ATI_CRTC_VGA) 267 { 268 /* Reset Miscellaneous Control 2 */ 269 out8(M64_DAC_WRITE, 0x71U); 270 out8(M64_DAC_DATA, 0x00U); 271 out8(M64_DAC_MASK, pATIHW->ibmrgb514[0x0071U] & ~0x41U); 272 } 273 274#endif /* AVOID_CPIO */ 275 276 /* Restore registers */ 277 out8(M64_DAC_WRITE, index_lo); 278 out8(M64_DAC_DATA, index_hi); 279 out8(M64_DAC_READ, index_ctl); 280 outr(DAC_CNTL, dac_cntl); 281 if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN)) 282 outr(CRTC_GEN_CNTL, crtc_gen_cntl); 283} 284