tx_dac.c revision 4f6cd06f
1/* 2 * Copyright 1997-2001 by Alan Hourihane <alanh@fairlite.demon.co.uk> 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 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of Alan Hourihane not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. Alan Hourihane 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 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL ALAN HOURIHANE 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 * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> 23 * Dirk Hohndel, <hohndel@suse.de> 24 * Stefan Dirsch, <sndirsch@suse.de> 25 * Helmut Fahrion, <hf@suse.de> 26 * 27 * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and 28 * Siemens Nixdorf Informationssysteme 29 */ 30/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/tx_dac.c,v 1.15tsi Exp $ */ 31 32#ifdef HAVE_CONFIG_H 33#include "config.h" 34#endif 35 36#include "xf86.h" 37#include "xf86_OSproc.h" 38 39#include "xf86PciInfo.h" 40#include "xf86Pci.h" 41 42#include "IBM.h" 43#include "TI.h" 44#include "glint_regs.h" 45#include "glint.h" 46 47Bool 48TXInit(ScrnInfoPtr pScrn, DisplayModePtr mode, GLINTRegPtr pReg) 49{ 50 GLINTPtr pGlint = GLINTPTR(pScrn); 51 RamDacHWRecPtr pRamDac = RAMDACHWPTR(pScrn); 52 RamDacRegRecPtr ramdacReg = &pRamDac->ModeReg; 53 CARD32 temp1, temp2, temp3, temp4; 54 55 if (pGlint->numMultiDevices == 2) { 56 STOREREG(GCSRAperture, GCSRSecondaryGLINTMapEn); 57 } 58 59 if (pGlint->MultiAperture) { 60 /* 61 * Setup HW 62 * 63 * Note: The order of discovery for the MX devices is dependent 64 * on which way the resource allocation code decides to scan the 65 * bus. This setup assumes the first MX found owns the even 66 * scanlines. Should the implementation change an scan the bus 67 * in the opposite direction, then simple invert the indices for 68 * MultiPciInfo below. If this is setup wrong, the bug will appear 69 * as incorrect scanline interleaving when software rendering. 70 */ 71 STOREREG(GMultGLINTAperture, pGlint->realWidth); 72 STOREREG(GMultGLINT1, PCI_REGION_BASE(pGlint->MultiPciInfo[0], 2, REGION_MEM) & 0xFF800000); 73 STOREREG(GMultGLINT2, PCI_REGION_BASE(pGlint->MultiPciInfo[1], 2, REGION_MEM) & 0xFF800000); 74 } 75 76 if (IS_GMX2000 || IS_GLORIAXXL) { 77 pReg->glintRegs[LBMemoryEDO >> 3] = GLINT_READ_REG(LBMemoryEDO); 78 pReg->glintRegs[LBMemoryEDO >> 3] &= ~(LBEDOMask | 79 LBEDOBankSizeMask | 80 LBTwoPageDetectorMask); 81 pReg->glintRegs[LBMemoryEDO >> 3] |= (LBEDOEnabled | 82 LBEDOBankSize4M | 83 LBTwoPageDetector); 84 pReg->glintRegs[LBMemoryCtl >> 3] = GLINT_READ_REG(LBMemoryCtl); 85 pReg->glintRegs[LBMemoryCtl >> 3] &= ~(LBNumBanksMask | 86 LBPageSizeMask | 87 LBRASCASLowMask | 88 LBRASPrechargeMask | 89 LBCASLowMask | 90 LBPageModeMask | 91 LBRefreshCountMask); 92 pReg->glintRegs[LBMemoryCtl >> 3] |= (LBNumBanks2 | 93 LBPageSize1024 | 94 LBRASCASLow2 | 95 LBRASPrecharge2 | 96 LBCASLow1 | 97 LBPageModeEnabled | 98 (0x20 << LBRefreshCountShift)); 99 } 100 101 STOREREG(Aperture0, 0); 102 STOREREG(Aperture1, 0); 103 104 STOREREG(DFIFODis, GLINT_READ_REG(DFIFODis) & 0xFFFFFFFE); 105 STOREREG(FIFODis, GLINT_READ_REG(FIFODis) | 0x01); 106 107 temp1 = mode->CrtcHSyncStart - mode->CrtcHDisplay; 108 temp2 = mode->CrtcVSyncStart - mode->CrtcVDisplay; 109 temp3 = mode->CrtcHSyncEnd - mode->CrtcHSyncStart; 110 temp4 = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; 111 112 STOREREG(VTGHLimit, Shiftbpp(pScrn, mode->CrtcHTotal)); 113 STOREREG(VTGHSyncEnd, Shiftbpp(pScrn, temp1 + temp3)); 114 STOREREG(VTGHSyncStart, Shiftbpp(pScrn, temp1)); 115 STOREREG(VTGHBlankEnd, 116 Shiftbpp(pScrn, mode->CrtcHTotal - mode->CrtcHDisplay)); 117 118 STOREREG(VTGVLimit, mode->CrtcVTotal); 119 STOREREG(VTGVSyncEnd, temp2 + temp4); 120 STOREREG(VTGVSyncStart, temp2); 121 STOREREG(VTGVBlankEnd, mode->CrtcVTotal - mode->CrtcVDisplay); 122 123 if (IS_GMX2000) { 124 STOREREG(VTGPolarity, 0xba); 125 } else { 126 STOREREG(VTGPolarity, (((mode->Flags & V_PHSYNC ? 0:2)<<2) | 127 ((mode->Flags & V_PVSYNC) ? 0 : 2) | (0xb0))); 128 } 129 130 STOREREG(VClkCtl, 0); 131 STOREREG(VTGVGateStart, mode->CrtcVTotal - mode->CrtcVDisplay - 1); 132 STOREREG(VTGVGateEnd, mode->CrtcVTotal - mode->CrtcVDisplay); 133 134 /* This is ugly */ 135 if (pGlint->UseFireGL3000) { 136 STOREREG(VTGSerialClk, 0x05); 137 STOREREG(VTGHGateStart, 138 Shiftbpp(pScrn, mode->CrtcHTotal - mode->CrtcHDisplay - 1)); 139 STOREREG(VTGHGateEnd, Shiftbpp(pScrn, mode->CrtcHTotal) - 1); 140 STOREREG(FBModeSel, 0x907); 141 STOREREG(VTGModeCtl, 0x00); 142 } else 143 if (IS_GMX2000) { 144 STOREREG(VTGSerialClk, 0x02); 145 STOREREG(VTGHGateStart, 146 Shiftbpp(pScrn, mode->CrtcHTotal - mode->CrtcHDisplay - 1)); 147 STOREREG(VTGHGateEnd, Shiftbpp(pScrn, mode->CrtcHTotal) - 1); 148 STOREREG(FBModeSel, 0x907); 149 STOREREG(VTGModeCtl, 0x04); 150 } else { 151 STOREREG(VTGSerialClk, 0x05); 152 STOREREG(VTGHGateStart, 153 Shiftbpp(pScrn, mode->CrtcHTotal - mode->CrtcHDisplay) - 2); 154 STOREREG(VTGHGateEnd, Shiftbpp(pScrn, mode->CrtcHTotal) - 2); 155 STOREREG(FBModeSel, 0x0A07); 156 STOREREG(VTGModeCtl, 0x44); 157 } 158 159 if (IS_GMX2000 || IS_GLORIAXXL) { 160 STOREREG(FBMemoryCtl, 0x800); /* Optimum memory timings */ 161 } else { 162 STOREREG(FBMemoryCtl, GLINT_READ_REG(FBMemoryCtl)); 163 } 164 165 /* Override FBModeSel for 300SX chip */ 166 if ( (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_300SX) || 167 ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) && 168 (pGlint->MultiChip == PCI_CHIP_300SX)) ) { 169 switch (pScrn->bitsPerPixel) { 170 case 8: 171 STOREREG(FBModeSel, 0x905); 172 break; 173 case 16: 174 STOREREG(FBModeSel, 0x903); 175 break; 176 case 32: 177 STOREREG(FBModeSel, 0x901); 178 break; 179 } 180 } 181 182 switch (pGlint->RamDac->RamDacType) { 183 case IBM526DB_RAMDAC: 184 case IBM526_RAMDAC: 185 { 186 /* Get the programmable clock values */ 187 unsigned long m=0,n=0,p=0,c=0; 188 189 (void) IBMramdac526CalculateMNPCForClock(pGlint->RefClock, mode->Clock, 190 1, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p, &c); 191 192 STORERAMDAC(IBMRGB_m0, m); 193 STORERAMDAC(IBMRGB_n0, n); 194 STORERAMDAC(IBMRGB_p0, p); 195 STORERAMDAC(IBMRGB_c0, c); 196 197 STORERAMDAC(IBMRGB_pll_ctrl1, 0x05); 198 STORERAMDAC(IBMRGB_pll_ctrl2, 0x00); 199 200 p = 1; 201 (void) IBMramdac526CalculateMNPCForClock(pGlint->RefClock, mode->Clock, 202 0, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p, &c); 203 204 STORERAMDAC(IBMRGB_sysclk, 0x05); 205 STORERAMDAC(IBMRGB_sysclk_m, m); 206 STORERAMDAC(IBMRGB_sysclk_n, n); 207 STORERAMDAC(IBMRGB_sysclk_p, p); 208 STORERAMDAC(IBMRGB_sysclk_c, c); 209 } 210 STORERAMDAC(IBMRGB_misc1, SENS_DSAB_DISABLE | VRAM_SIZE_64); 211 STORERAMDAC(IBMRGB_misc2, COL_RES_8BIT | PORT_SEL_VRAM | PCLK_SEL_PLL); 212 STORERAMDAC(IBMRGB_misc3, 0); 213 STORERAMDAC(IBMRGB_misc_clock, 1); 214 STORERAMDAC(IBMRGB_sync, 0); 215 STORERAMDAC(IBMRGB_hsync_pos, 0); 216 STORERAMDAC(IBMRGB_pwr_mgmt, 0); 217 STORERAMDAC(IBMRGB_dac_op, 0); 218 STORERAMDAC(IBMRGB_pal_ctrl, 0); 219 220 break; 221 case IBM640_RAMDAC: 222 { 223 /* Get the programmable clock values */ 224 unsigned long m=0,n=0,p=0,c=0; 225 226 (void) IBMramdac640CalculateMNPCForClock(pGlint->RefClock, mode->Clock, 227 1, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p, &c); 228 229 STORERAMDAC(RGB640_PLL_N, n); 230 STORERAMDAC(RGB640_PLL_M, m); 231 STORERAMDAC(RGB640_PLL_P, p<<1); 232 STORERAMDAC(RGB640_PLL_CTL, c | IBM640_PLL_EN); 233 STORERAMDAC(RGB640_AUX_PLL_CTL, 0); /* Disable AUX PLL */ 234 } 235 STORERAMDAC(RGB640_PIXEL_INTERLEAVE, 0x00); 236 237 temp1 = IBM640_RDBK | IBM640_VRAM; 238 if (pScrn->rgbBits == 8) 239 temp1 |= IBM640_PSIZE8; 240 STORERAMDAC(RGB640_VGA_CONTROL, temp1); 241 242 STORERAMDAC(RGB640_DAC_CONTROL, IBM640_DACENBL | IBM640_SHUNT); 243 STORERAMDAC(RGB640_OUTPUT_CONTROL, IBM640_RDAI | IBM640_WATCTL); 244 STORERAMDAC(RGB640_SYNC_CONTROL, 0x00); 245 STORERAMDAC(RGB640_VRAM_MASK0, 0xFF); 246 STORERAMDAC(RGB640_VRAM_MASK1, 0xFF); 247 STORERAMDAC(RGB640_VRAM_MASK2, 0x0F); 248 249 STOREREG(VTGModeCtl, 0x04); 250 break; 251 252 case TI3026_RAMDAC: 253 case TI3030_RAMDAC: 254 { 255 /* Get the programmable clock values */ 256 unsigned long m=0,n=0,p=0; 257 unsigned long clock; 258 unsigned long q, VCO = 0; 259 260 clock = TIramdacCalculateMNPForClock(pGlint->RefClock, 261 mode->Clock, 1, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p); 262 263 STORERAMDAC(TIDAC_PIXEL_N, ((n & 0x3f) | 0xC0)); 264 STORERAMDAC(TIDAC_PIXEL_M, (m & 0x3f)); 265 STORERAMDAC(TIDAC_PIXEL_P, ((p & 0x03) | 0xbc)); 266 STORERAMDAC(TIDAC_PIXEL_VALID, TRUE); 267 268 if (pGlint->RamDac->RamDacType == (TI3026_RAMDAC)) 269 n = 65 - ((64 << 2) / pScrn->bitsPerPixel); 270 else 271 n = 65 - ((128 << 2) / pScrn->bitsPerPixel); 272 m = 61; 273 p = 0; 274 for (q = 0; q < 8; q++) { 275 if (q > 0) p = 3; 276 for ( ; p < 4; p++) { 277 VCO = ((clock * (q + 1) * (65 - m)) / (65 - n)) << (p + 1); 278 if (VCO >= 110000) { break; } 279 } 280 if (VCO >= 110000) { break; } 281 } 282 STORERAMDAC(TIDAC_clock_ctrl, (q | 0x38)); 283 284 STORERAMDAC(TIDAC_LOOP_N, ((n & 0x3f) | 0xC0)); 285 STORERAMDAC(TIDAC_LOOP_M, (m & 0x3f)); 286 STORERAMDAC(TIDAC_LOOP_P, ((p & 0x03) | 0xF0)); 287 STORERAMDAC(TIDAC_LOOP_VALID, TRUE); 288 } 289 if (pGlint->RamDac->RamDacType == (TI3030_RAMDAC)) 290 STOREREG(VTGModeCtl, 0x04); 291 break; 292 } 293 294 /* Now use helper routines to setup bpp for this driver */ 295 (*pGlint->RamDac->SetBpp)(pScrn, ramdacReg); 296 297 return(TRUE); 298} 299 300void 301TXSave(ScrnInfoPtr pScrn, GLINTRegPtr pReg) 302{ 303 GLINTPtr pGlint = GLINTPTR(pScrn); 304 305 if (pGlint->numMultiDevices == 2) { 306 SAVEREG(GCSRAperture); 307 } 308 309 if (pGlint->MultiAperture) { 310 SAVEREG(GMultGLINTAperture); 311 SAVEREG(GMultGLINT1); 312 SAVEREG(GMultGLINT2); 313 } 314 315 SAVEREG(Aperture0); 316 SAVEREG(Aperture1); 317 318 SAVEREG(DFIFODis); 319 320 if (pGlint->Chipset != PCI_VENDOR_3DLABS_CHIP_300SX) { 321 SAVEREG(FIFODis); 322 SAVEREG(VTGModeCtl); 323 } 324 325 SAVEREG(VClkCtl); 326 SAVEREG(VTGPolarity); 327 SAVEREG(VTGHLimit); 328 SAVEREG(VTGHBlankEnd); 329 SAVEREG(VTGHSyncStart); 330 SAVEREG(VTGHSyncEnd); 331 SAVEREG(VTGVLimit); 332 SAVEREG(VTGVBlankEnd); 333 SAVEREG(VTGVSyncStart); 334 SAVEREG(VTGVSyncEnd); 335 SAVEREG(VTGVGateStart); 336 SAVEREG(VTGVGateEnd); 337 SAVEREG(VTGSerialClk); 338 SAVEREG(FBModeSel); 339 SAVEREG(VTGHGateStart); 340 SAVEREG(VTGHGateEnd); 341 SAVEREG(FBMemoryCtl); 342 343 if (IS_GMX2000 || IS_GLORIAXXL) { 344 SAVEREG(LBMemoryEDO); 345 SAVEREG(LBMemoryCtl); 346 } 347} 348 349void 350TXRestore(ScrnInfoPtr pScrn, GLINTRegPtr pReg) 351{ 352 GLINTPtr pGlint = GLINTPTR(pScrn); 353 354 if (pGlint->numMultiDevices == 2) { 355 RESTOREREG(GCSRAperture); 356 } 357 358 if (pGlint->MultiAperture) { 359 RESTOREREG(GMultGLINTAperture); 360 RESTOREREG(GMultGLINT1); 361 RESTOREREG(GMultGLINT2); 362 } 363 364 RESTOREREG(Aperture0); 365 RESTOREREG(Aperture1); 366 367 RESTOREREG(DFIFODis); 368 369 if (pGlint->Chipset != PCI_VENDOR_3DLABS_CHIP_300SX) { 370 RESTOREREG(FIFODis); 371 RESTOREREG(VTGModeCtl); 372 } 373 374 RESTOREREG(VTGPolarity); 375 RESTOREREG(VClkCtl); 376 RESTOREREG(VTGSerialClk); 377 RESTOREREG(VTGHLimit); 378 RESTOREREG(VTGHSyncStart); 379 RESTOREREG(VTGHSyncEnd); 380 RESTOREREG(VTGHBlankEnd); 381 RESTOREREG(VTGVLimit); 382 RESTOREREG(VTGVSyncStart); 383 RESTOREREG(VTGVSyncEnd); 384 RESTOREREG(VTGVBlankEnd); 385 RESTOREREG(VTGVGateStart); 386 RESTOREREG(VTGVGateEnd); 387 RESTOREREG(FBModeSel); 388 RESTOREREG(VTGHGateStart); 389 RESTOREREG(VTGHGateEnd); 390 RESTOREREG(FBMemoryCtl); 391 392 if (IS_GMX2000 || IS_GLORIAXXL) { 393 RESTOREREG(LBMemoryEDO); 394 RESTOREREG(LBMemoryCtl); 395 } 396} 397