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