pm_dac.c revision c35d236e
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/pm_dac.c,v 1.11tsi 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 48PermediaInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 49{ 50 GLINTPtr pGlint = GLINTPTR(pScrn); 51 GLINTRegPtr pReg = &pGlint->ModeReg[0]; 52 RamDacHWRecPtr pIBM = RAMDACHWPTR(pScrn); 53 RamDacRegRecPtr ramdacReg = &pIBM->ModeReg; 54 CARD32 temp1, temp2, temp3, temp4; 55 56 STOREREG(Aperture0, 0x00000000); 57 STOREREG(Aperture1, 0x00000000); 58 59 pReg->glintRegs[PMFramebufferWriteMask >> 3] = 0xFFFFFFFF; 60 pReg->glintRegs[PMBypassWriteMask >> 3] = 0xFFFFFFFF; 61 62 pReg->glintRegs[DFIFODis >> 3] = 1; 63 pReg->glintRegs[FIFODis >> 3] = 3; 64 65 temp1 = mode->CrtcHSyncStart - mode->CrtcHDisplay; 66 temp2 = mode->CrtcVSyncStart - mode->CrtcVDisplay; 67 temp3 = mode->CrtcHSyncEnd - mode->CrtcHSyncStart; 68 temp4 = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; 69 70 pReg->glintRegs[PMHTotal >> 3] = Shiftbpp(pScrn,mode->CrtcHTotal); 71 pReg->glintRegs[PMHsEnd >> 3] = Shiftbpp(pScrn, temp1 + temp3); 72 pReg->glintRegs[PMHsStart >> 3] = Shiftbpp(pScrn, temp1); 73 pReg->glintRegs[PMHbEnd >> 3] = Shiftbpp(pScrn, mode->CrtcHTotal - 74 mode->CrtcHDisplay); 75 pReg->glintRegs[PMHgEnd >> 3] = Shiftbpp(pScrn, mode->CrtcHTotal - 76 mode->CrtcHDisplay); 77 pReg->glintRegs[PMScreenStride >> 3] = 78 Shiftbpp(pScrn,pScrn->displayWidth>>1); 79 80 pReg->glintRegs[PMVTotal >> 3] = mode->CrtcVTotal; 81 pReg->glintRegs[PMVsEnd >> 3] = temp2 + temp4; 82 pReg->glintRegs[PMVsStart >> 3] = temp2; 83 pReg->glintRegs[PMVbEnd >> 3] = mode->CrtcVTotal - mode->CrtcVDisplay; 84 85 pReg->glintRegs[PMVideoControl >> 3] = 86 (((mode->Flags & V_PHSYNC) ? 0x1 : 0x3) << 3) | 87 (((mode->Flags & V_PVSYNC) ? 0x1 : 0x3) << 5) | 1; 88 89 pReg->glintRegs[VClkCtl >> 3] = 3; 90 pReg->glintRegs[PMScreenBase >> 3] = 0; 91 pReg->glintRegs[PMHTotal >> 3] -= 1; /* PMHTotal */ 92 pReg->glintRegs[PMHsStart >> 3] -= 1; /* PMHsStart */ 93 pReg->glintRegs[PMVTotal >> 3] -= 1; /* PMVTotal */ 94 pReg->glintRegs[ChipConfig >> 3] = GLINT_READ_REG(ChipConfig) & 0xFFFFFFFD; 95 96 switch(pGlint->RamDac->RamDacType) { 97 case IBM526_RAMDAC: 98 case IBM526DB_RAMDAC: 99 { 100 /* Get the programmable clock values */ 101 unsigned long m=0,n=0,p=0,c=0; 102 103 (void) IBMramdac526CalculateMNPCForClock(pGlint->RefClock, mode->Clock, 104 1, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p, &c); 105 106 ramdacReg->DacRegs[IBMRGB_m0] = m; 107 ramdacReg->DacRegs[IBMRGB_n0] = n; 108 ramdacReg->DacRegs[IBMRGB_p0] = p; 109 ramdacReg->DacRegs[IBMRGB_c0] = c; 110 111 ramdacReg->DacRegs[IBMRGB_pll_ctrl1] = 0x05; 112 ramdacReg->DacRegs[IBMRGB_pll_ctrl2] = 0x00; 113 114 p = 1; 115 (void) IBMramdac526CalculateMNPCForClock(pGlint->RefClock, mode->Clock, 116 0, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p, &c); 117 118 ramdacReg->DacRegs[IBMRGB_sysclk] = 0x05; 119 ramdacReg->DacRegs[IBMRGB_sysclk_m] = m; 120 ramdacReg->DacRegs[IBMRGB_sysclk_n] = n; 121 ramdacReg->DacRegs[IBMRGB_sysclk_p] = p; 122 ramdacReg->DacRegs[IBMRGB_sysclk_c] = c; 123 } 124 ramdacReg->DacRegs[IBMRGB_misc1] = SENS_DSAB_DISABLE | VRAM_SIZE_32; 125 ramdacReg->DacRegs[IBMRGB_misc2] = COL_RES_8BIT | PORT_SEL_VRAM; 126 if (pScrn->depth >= 24) 127 ramdacReg->DacRegs[IBMRGB_misc2] |= PCLK_SEL_LCLK; 128 else 129 ramdacReg->DacRegs[IBMRGB_misc2] |= PCLK_SEL_PLL; 130 ramdacReg->DacRegs[IBMRGB_misc3] = 0; 131 ramdacReg->DacRegs[IBMRGB_misc_clock] = 1; 132 ramdacReg->DacRegs[IBMRGB_sync] = 0; 133 ramdacReg->DacRegs[IBMRGB_hsync_pos] = 0; 134 ramdacReg->DacRegs[IBMRGB_pwr_mgmt] = 0; 135 ramdacReg->DacRegs[IBMRGB_dac_op] = 0; 136 ramdacReg->DacRegs[IBMRGB_pal_ctrl] = 0; 137 break; 138 case TI3026_RAMDAC: 139 { 140 /* Get the programmable clock values */ 141 unsigned long m=0,n=0,p=0; 142 unsigned long clock; 143 unsigned long q, VCO = 0; 144 145 clock = TIramdacCalculateMNPForClock(pGlint->RefClock, 146 mode->Clock, 1, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p); 147 148 STORERAMDAC(TIDAC_PIXEL_N, ((n & 0x3f) | 0xC0)); 149 STORERAMDAC(TIDAC_PIXEL_M, (m & 0x3f)); 150 STORERAMDAC(TIDAC_PIXEL_P, ((p & 0x03) | 0xbc)); 151 STORERAMDAC(TIDAC_PIXEL_VALID, TRUE); 152 153 if (pGlint->RamDac->RamDacType == (TI3026_RAMDAC)) 154 n = 65 - ((32 << 2) / pScrn->bitsPerPixel); 155 else 156 n = 65 - ((128 << 2) / pScrn->bitsPerPixel); 157 m = 61; 158 p = 0; 159 for (q = 0; q < 8; q++) { 160 if (q > 0) p = 3; 161 for ( ; p < 4; p++) { 162 VCO = ((clock * (q + 1) * (65 - m)) / (65 - n)) << (p + 1); 163 if (VCO >= 110000) { break; } 164 } 165 if (VCO >= 110000) { break; } 166 } 167 STORERAMDAC(TIDAC_clock_ctrl, (q | 0x38)); 168 169 STORERAMDAC(TIDAC_LOOP_N, ((n & 0x3f) | 0xC0)); 170 STORERAMDAC(TIDAC_LOOP_M, (m & 0x3f)); 171 STORERAMDAC(TIDAC_LOOP_P, ((p & 0x03) | 0xF0)); 172 STORERAMDAC(TIDAC_LOOP_VALID, TRUE); 173 break; 174 } 175 } 176 177 (*pGlint->RamDac->SetBpp)(pScrn, ramdacReg); 178 179 /* The permedia uses a 32bit data path, the TI ramdac code 180 * defaults to 64bit. So we knock it down to 32bit here */ 181 if (pGlint->RamDac->RamDacType == (TI3026_RAMDAC)) 182 ramdacReg->DacRegs[TIDAC_multiplex_ctrl] -= 1; 183 184 return(TRUE); 185} 186 187void 188PermediaSave(ScrnInfoPtr pScrn, GLINTRegPtr glintReg) 189{ 190 GLINTPtr pGlint = GLINTPTR(pScrn); 191 192 /* We can't rely on the vgahw layer copying the font information 193 * back properly, due to problems with MMIO access to VGA space 194 * so we memcpy the information using the slow routines */ 195 xf86SlowBcopy((CARD8*)pGlint->FbBase, (CARD8*)pGlint->VGAdata, 65536); 196 197 glintReg->glintRegs[Aperture0 >> 3] = GLINT_READ_REG(Aperture0); 198 glintReg->glintRegs[Aperture1 >> 3] = GLINT_READ_REG(Aperture1); 199 glintReg->glintRegs[PMFramebufferWriteMask] = 200 GLINT_READ_REG(PMFramebufferWriteMask); 201 glintReg->glintRegs[PMBypassWriteMask >> 3] = 202 GLINT_READ_REG(PMBypassWriteMask); 203 glintReg->glintRegs[DFIFODis >> 3] = GLINT_READ_REG(DFIFODis); 204 glintReg->glintRegs[FIFODis >> 3] = GLINT_READ_REG(FIFODis); 205 206 glintReg->glintRegs[PMHTotal >> 3] = GLINT_READ_REG(PMHTotal); 207 glintReg->glintRegs[PMHbEnd >> 3] = GLINT_READ_REG(PMHbEnd); 208 glintReg->glintRegs[PMHgEnd >> 3] = GLINT_READ_REG(PMHgEnd); 209 glintReg->glintRegs[PMScreenStride >> 3] = GLINT_READ_REG(PMScreenStride); 210 glintReg->glintRegs[PMHsStart >> 3] = GLINT_READ_REG(PMHsStart); 211 glintReg->glintRegs[PMHsEnd >> 3] = GLINT_READ_REG(PMHsEnd); 212 glintReg->glintRegs[PMVTotal >> 3] = GLINT_READ_REG(PMVTotal); 213 glintReg->glintRegs[PMVbEnd >> 3] = GLINT_READ_REG(PMVbEnd); 214 glintReg->glintRegs[PMVsStart >> 3] = GLINT_READ_REG(PMVsStart); 215 glintReg->glintRegs[PMVsEnd >> 3] = GLINT_READ_REG(PMVsEnd); 216 glintReg->glintRegs[PMScreenBase >> 3] = GLINT_READ_REG(PMScreenBase); 217 glintReg->glintRegs[PMVideoControl >> 3] = GLINT_READ_REG(PMVideoControl); 218 glintReg->glintRegs[VClkCtl >> 3] = GLINT_READ_REG(VClkCtl); 219 glintReg->glintRegs[ChipConfig >> 3] = GLINT_READ_REG(ChipConfig); 220} 221 222void 223PermediaRestore(ScrnInfoPtr pScrn, GLINTRegPtr pReg) 224{ 225 GLINTPtr pGlint = GLINTPTR(pScrn); 226 227 /* We can't rely on the vgahw layer copying the font information 228 * back properly, due to problems with MMIO access to VGA space 229 * so we memcpy the information using the slow routines */ 230 if (pGlint->STATE) 231 xf86SlowBcopy((CARD8*)pGlint->VGAdata, (CARD8*)pGlint->FbBase, 65536); 232 233 RESTOREREG(ChipConfig); 234 RESTOREREG(DFIFODis); 235 RESTOREREG(FIFODis); 236 RESTOREREG(Aperture0); 237 RESTOREREG(Aperture1); 238 RESTOREREG(PMFramebufferWriteMask); 239 RESTOREREG(PMBypassWriteMask); 240 RESTOREREG(PMVideoControl); 241 RESTOREREG(PMHgEnd); 242 RESTOREREG(VClkCtl); 243 RESTOREREG(PMHTotal); 244 RESTOREREG(PMHbEnd); 245 RESTOREREG(PMHsStart); 246 RESTOREREG(PMHsEnd); 247 RESTOREREG(PMVTotal); 248 RESTOREREG(PMVbEnd); 249 RESTOREREG(PMVsStart); 250 RESTOREREG(PMVsEnd); 251 RESTOREREG(PMScreenBase); 252 RESTOREREG(PMScreenStride); 253} 254