pm2_dac.c revision 933f9f8f
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 * Michel Dänzer, <michdaen@iiic.ethz.ch> 27 * 28 * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and 29 * Siemens Nixdorf Informationssysteme 30 */ 31/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_dac.c,v 1.26tsi Exp $ */ 32 33#ifdef HAVE_CONFIG_H 34#include "config.h" 35#endif 36 37#include <X11/Xarch.h> 38#include "xf86.h" 39#include "xf86_OSproc.h" 40 41#include "xf86PciInfo.h" 42#include "xf86Pci.h" 43 44#include "glint_regs.h" 45#include "glint.h" 46 47#define INITIALFREQERR 100000 48#define MINCLK 110000 /* VCO frequency range */ 49#define MAXCLK 250000 50 51static unsigned long 52PM2DAC_CalculateMNPCForClock 53( 54 unsigned long reqclock, /* In kHz units */ 55 unsigned long refclock, /* In kHz units */ 56 unsigned char *rm, /* M Out */ 57 unsigned char *rn, /* N Out */ 58 unsigned char *rp /* P Out */ 59 ) 60{ 61 unsigned char m, n, p; 62 unsigned long f; 63 long freqerr, lowestfreqerr = INITIALFREQERR; 64 unsigned long clock,actualclock = 0; 65 66 for (n = 2; n <= 14; n++) { 67 for (m = 2; m != 0; m++) { /* this is a char, so this counts to 255 */ 68 f = refclock * m / n; 69 if ( (f < MINCLK) || (f > MAXCLK) ) 70 continue; 71 for (p = 0; p <= 4; p++) { 72 clock = f >> p; 73 freqerr = reqclock - clock; 74 if (freqerr < 0) 75 freqerr = -freqerr; 76 if (freqerr < lowestfreqerr) { 77 *rn = n; 78 *rm = m; 79 *rp = p; 80 lowestfreqerr = freqerr; 81 actualclock = clock; 82#ifdef DEBUG 83 ErrorF("Best %ld diff %ld\n",actualclock,freqerr); 84#endif 85 } 86 } 87 } 88 } 89 90 return(actualclock); 91} 92 93Bool 94Permedia2Init(ScrnInfoPtr pScrn, DisplayModePtr mode) 95{ 96 GLINTPtr pGlint = GLINTPTR(pScrn); 97 GLINTRegPtr pReg = &pGlint->ModeReg[0]; 98 CARD32 temp1, temp2, temp3, temp4; 99 100 pReg->glintRegs[Aperture0 >> 3] = 0; 101 pReg->glintRegs[Aperture1 >> 3] = 0; 102 pReg->glintRegs[PMFramebufferWriteMask >> 3] = 0xFFFFFFFF; 103 pReg->glintRegs[PMBypassWriteMask >> 3] = 0xFFFFFFFF; 104 105 pReg->glintRegs[DFIFODis >> 3] = 0; 106 pReg->glintRegs[FIFODis >> 3] = 1; 107 108 if (pGlint->UseBlockWrite) 109 pReg->glintRegs[PMMemConfig >> 3] = GLINT_READ_REG(PMMemConfig) | 1<<21; 110 111 112 temp1 = mode->CrtcHSyncStart - mode->CrtcHDisplay; 113 temp2 = mode->CrtcVSyncStart - mode->CrtcVDisplay; 114 temp3 = mode->CrtcHSyncEnd - mode->CrtcHSyncStart; 115 temp4 = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; 116 117 pReg->glintRegs[PMHTotal >> 3] = Shiftbpp(pScrn,mode->CrtcHTotal); 118 pReg->glintRegs[PMHsEnd >> 3] = Shiftbpp(pScrn, temp1 + temp3); 119 pReg->glintRegs[PMHsStart >> 3] = Shiftbpp(pScrn, temp1); 120 pReg->glintRegs[PMHbEnd >> 3] = 121 Shiftbpp(pScrn,mode->CrtcHTotal-mode->CrtcHDisplay); 122 pReg->glintRegs[PMScreenStride >> 3] = 123 Shiftbpp(pScrn,pScrn->displayWidth>>1); 124 125 pReg->glintRegs[PMVTotal >> 3] = mode->CrtcVTotal; 126 pReg->glintRegs[PMVsEnd >> 3] = temp2 + temp4; 127 pReg->glintRegs[PMVsStart >> 3] = temp2; 128 pReg->glintRegs[PMVbEnd >> 3] = mode->CrtcVTotal - mode->CrtcVDisplay; 129 130 /* The hw cursor needs /VSYNC to recognize vert retrace. We'll stick 131 both sync lines to active high here and if needed invert them 132 using the RAMDAC's MCR below. */ 133 pReg->glintRegs[PMVideoControl >> 3] = 134 (1 << 5) | (1 << 3) | 1; 135 136 if (pScrn->bitsPerPixel > 8) { 137 /* When != 8bpp then we stick the RAMDAC into 64bit mode */ 138 /* And reduce the horizontal timings by half */ 139 pReg->glintRegs[PMVideoControl >> 3] |= 1<<16; 140 pReg->glintRegs[PMHTotal >> 3] >>= 1; 141 pReg->glintRegs[PMHsEnd >> 3] >>= 1; 142 pReg->glintRegs[PMHsStart >> 3] >>= 1; 143 pReg->glintRegs[PMHbEnd >> 3] >>= 1; 144 } 145 146 pReg->glintRegs[VClkCtl >> 3] = (GLINT_READ_REG(VClkCtl) & 0xFFFFFFFC); 147 pReg->glintRegs[PMScreenBase >> 3] = 0; 148 pReg->glintRegs[PMHTotal >> 3] -= 1; 149 pReg->glintRegs[PMHsStart >> 3] -= 1; 150 pReg->glintRegs[PMVTotal >> 3] -= 1; 151 152 pReg->glintRegs[ChipConfig >> 3] = GLINT_READ_REG(ChipConfig) & 0xFFFFFFDD; 153 154 pReg->DacRegs[PM2DACIndexMDCR] = 0x00; /* Disable Overlay */ 155 156 { 157 /* Get the programmable clock values */ 158 unsigned char m,n,p; 159 160 (void) PM2DAC_CalculateMNPCForClock(mode->Clock,pGlint->RefClock, 161 &m,&n,&p); 162 pReg->DacRegs[PM2DACIndexClockAM] = m; 163 pReg->DacRegs[PM2DACIndexClockAN] = n; 164 pReg->DacRegs[PM2DACIndexClockAP] = p|0x08; 165 } 166 167 if (pScrn->rgbBits == 8) 168 pReg->DacRegs[PM2DACIndexMCR] = 0x02; /* 8bit DAC */ 169 else 170 pReg->DacRegs[PM2DACIndexMCR] = 0x00; /* 6bit DAC */ 171 172 if (!(mode->Flags & V_PHSYNC)) 173 pReg->DacRegs[PM2DACIndexMCR] |= 0x04; /* invert hsync */ 174 if (!(mode->Flags & V_PVSYNC)) 175 pReg->DacRegs[PM2DACIndexMCR] |= 0x08; /* invert vsync */ 176 177 switch (pScrn->bitsPerPixel) 178 { 179 case 8: 180 pReg->DacRegs[PM2DACIndexCMR] = PM2DAC_RGB | PM2DAC_GRAPHICS | 181 PM2DAC_CI8; 182 break; 183 case 16: 184 if (pScrn->depth == 15) { 185 pReg->DacRegs[PM2DACIndexCMR] = PM2DAC_RGB | PM2DAC_TRUECOLOR| 186 PM2DAC_GRAPHICS | PM2DAC_5551; 187 } else { 188 pReg->DacRegs[PM2DACIndexCMR] = PM2DAC_RGB | PM2DAC_TRUECOLOR| 189 PM2DAC_GRAPHICS | PM2DAC_565; 190 } 191 break; 192 case 24: 193 pReg->DacRegs[PM2DACIndexCMR] = PM2DAC_RGB | PM2DAC_TRUECOLOR| 194 PM2DAC_GRAPHICS | PM2DAC_PACKED; 195 break; 196 case 32: 197 pReg->DacRegs[PM2DACIndexCMR] = PM2DAC_RGB | 198 PM2DAC_GRAPHICS | PM2DAC_8888; 199 if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) { 200 pReg->DacRegs[PM2DACIndexColorKeyControl] = 0x11; 201 pReg->DacRegs[PM2DACIndexColorKeyOverlay] = pScrn->colorKey; 202 } else 203 pReg->DacRegs[PM2DACIndexCMR] |= PM2DAC_TRUECOLOR; 204 break; 205 } 206 207 return(TRUE); 208} 209 210void 211Permedia2Save(ScrnInfoPtr pScrn, GLINTRegPtr glintReg) 212{ 213 GLINTPtr pGlint = GLINTPTR(pScrn); 214 int i; 215 216 /* We can't rely on the vgahw layer copying the font information 217 * back properly, due to problems with MMIO access to VGA space 218 * so we memcpy the information using the slow routines */ 219 xf86SlowBcopy((CARD8*)pGlint->FbBase, (CARD8*)pGlint->VGAdata, 65536); 220 221 glintReg->glintRegs[Aperture0 >> 3] = GLINT_READ_REG(Aperture0); 222 glintReg->glintRegs[Aperture1 >> 3] = GLINT_READ_REG(Aperture1); 223 glintReg->glintRegs[PMFramebufferWriteMask >> 3] = 224 GLINT_READ_REG(PMFramebufferWriteMask); 225 glintReg->glintRegs[PMBypassWriteMask >> 3] = GLINT_READ_REG(PMBypassWriteMask); 226 glintReg->glintRegs[DFIFODis >> 3] = GLINT_READ_REG(DFIFODis); 227 glintReg->glintRegs[FIFODis >> 3] = GLINT_READ_REG(FIFODis); 228 /* We only muck about with PMMemConfig, if user wants to */ 229 if (pGlint->UseBlockWrite) 230 glintReg->glintRegs[PMMemConfig >> 3] = GLINT_READ_REG(PMMemConfig); 231 glintReg->glintRegs[PMHTotal >> 3] = GLINT_READ_REG(PMHTotal); 232 glintReg->glintRegs[PMHbEnd >> 3] = GLINT_READ_REG(PMHbEnd); 233 glintReg->glintRegs[PMHbEnd >> 3] = GLINT_READ_REG(PMHgEnd); 234 glintReg->glintRegs[PMScreenStride >> 3] = GLINT_READ_REG(PMScreenStride); 235 glintReg->glintRegs[PMHsStart >> 3] = GLINT_READ_REG(PMHsStart); 236 glintReg->glintRegs[PMHsEnd >> 3] = GLINT_READ_REG(PMHsEnd); 237 glintReg->glintRegs[PMVTotal >> 3] = GLINT_READ_REG(PMVTotal); 238 glintReg->glintRegs[PMVbEnd >> 3] = GLINT_READ_REG(PMVbEnd); 239 glintReg->glintRegs[PMVsStart >> 3] = GLINT_READ_REG(PMVsStart); 240 glintReg->glintRegs[PMVsEnd >> 3] = GLINT_READ_REG(PMVsEnd); 241 glintReg->glintRegs[PMScreenBase >> 3] = GLINT_READ_REG(PMScreenBase); 242 glintReg->glintRegs[PMVideoControl >> 3] = GLINT_READ_REG(PMVideoControl); 243 glintReg->glintRegs[VClkCtl >> 3] = GLINT_READ_REG(VClkCtl); 244 glintReg->glintRegs[ChipConfig >> 3] = GLINT_READ_REG(ChipConfig); 245 246 for (i=0;i<768;i++) { 247 Permedia2ReadAddress(pScrn, i); 248 glintReg->cmap[i] = Permedia2ReadData(pScrn); 249 } 250 251 glintReg->DacRegs[PM2DACIndexColorKeyOverlay] = 252 Permedia2InIndReg(pScrn, PM2DACIndexColorKeyOverlay); 253 glintReg->DacRegs[PM2DACIndexColorKeyControl] = 254 Permedia2InIndReg(pScrn, PM2DACIndexColorKeyControl); 255 glintReg->DacRegs[PM2DACIndexMCR] = 256 Permedia2InIndReg(pScrn, PM2DACIndexMCR); 257 glintReg->DacRegs[PM2DACIndexMDCR] = 258 Permedia2InIndReg(pScrn, PM2DACIndexMDCR); 259 glintReg->DacRegs[PM2DACIndexCMR] = 260 Permedia2InIndReg(pScrn, PM2DACIndexCMR); 261 262 glintReg->DacRegs[PM2DACIndexClockAM] = 263 Permedia2InIndReg(pScrn, PM2DACIndexClockAM); 264 glintReg->DacRegs[PM2DACIndexClockAN] = 265 Permedia2InIndReg(pScrn, PM2DACIndexClockAN); 266 glintReg->DacRegs[PM2DACIndexClockAP] = 267 Permedia2InIndReg(pScrn, PM2DACIndexClockAP); 268} 269 270void 271Permedia2Restore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg) 272{ 273 GLINTPtr pGlint = GLINTPTR(pScrn); 274 int i; 275 276 /* We can't rely on the vgahw layer copying the font information 277 * back properly, due to problems with MMIO access to VGA space 278 * so we memcpy the information using the slow routines */ 279 if (pGlint->STATE) 280 xf86SlowBcopy((CARD8*)pGlint->VGAdata, (CARD8*)pGlint->FbBase, 65536); 281 282#if 0 283 GLINT_SLOW_WRITE_REG(0, ResetStatus); 284 while(GLINT_READ_REG(ResetStatus) != 0) { 285 xf86MsgVerb(X_INFO, 2, "Resetting Engine - Please Wait.\n"); 286 }; 287#endif 288 289 GLINT_SLOW_WRITE_REG(0xFF, PM2DACReadMask); 290 291 GLINT_SLOW_WRITE_REG(glintReg->glintRegs[Aperture0 >> 3], Aperture0); 292 GLINT_SLOW_WRITE_REG(glintReg->glintRegs[Aperture1 >> 3], Aperture1); 293 GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMFramebufferWriteMask >> 3], 294 PMFramebufferWriteMask); 295 GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMBypassWriteMask >> 3], 296 PMBypassWriteMask); 297 GLINT_SLOW_WRITE_REG(glintReg->glintRegs[DFIFODis >> 3], DFIFODis); 298 GLINT_SLOW_WRITE_REG(glintReg->glintRegs[FIFODis >> 3], FIFODis); 299 /* We only muck about with PMMemConfig, if user wants to */ 300 if (pGlint->UseBlockWrite) 301 GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMMemConfig >> 3],PMMemConfig); 302 GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVideoControl >> 3], 303 PMVideoControl); 304 GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHbEnd >> 3], PMHgEnd); 305 GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMScreenBase >> 3], PMScreenBase); 306 GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VClkCtl >> 3], VClkCtl); 307 GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMScreenStride >> 3], 308 PMScreenStride); 309 GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHTotal >> 3], PMHTotal); 310 GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHbEnd >> 3], PMHbEnd); 311 GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHsStart >> 3], PMHsStart); 312 GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHsEnd >> 3], PMHsEnd); 313 GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVTotal >> 3], PMVTotal); 314 GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVbEnd >> 3], PMVbEnd); 315 GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVsStart >> 3], PMVsStart); 316 GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVsEnd >> 3], PMVsEnd); 317 GLINT_SLOW_WRITE_REG(glintReg->glintRegs[ChipConfig >> 3], ChipConfig); 318 319 Permedia2OutIndReg(pScrn, PM2DACIndexColorKeyOverlay, 0x00, 320 glintReg->DacRegs[PM2DACIndexColorKeyOverlay]); 321 Permedia2OutIndReg(pScrn, PM2DACIndexColorKeyControl, 0x00, 322 glintReg->DacRegs[PM2DACIndexColorKeyControl]); 323 Permedia2OutIndReg(pScrn, PM2DACIndexMCR, 0x00, 324 glintReg->DacRegs[PM2DACIndexMCR]); 325 Permedia2OutIndReg(pScrn, PM2DACIndexMDCR, 0x00, 326 glintReg->DacRegs[PM2DACIndexMDCR]); 327 Permedia2OutIndReg(pScrn, PM2DACIndexCMR, 0x00, 328 glintReg->DacRegs[PM2DACIndexCMR]); 329 330 Permedia2OutIndReg(pScrn, PM2DACIndexClockAM, 0x00, 331 glintReg->DacRegs[PM2DACIndexClockAM]); 332 Permedia2OutIndReg(pScrn, PM2DACIndexClockAN, 0x00, 333 glintReg->DacRegs[PM2DACIndexClockAN]); 334 Permedia2OutIndReg(pScrn, PM2DACIndexClockAP, 0x00, 335 glintReg->DacRegs[PM2DACIndexClockAP]); 336 337 for (i=0;i<768;i++) { 338 Permedia2WriteAddress(pScrn, i); 339 Permedia2WriteData(pScrn, glintReg->cmap[i]); 340 } 341} 342 343static void 344Permedia2ShowCursor(ScrnInfoPtr pScrn) 345{ 346 /* Enable cursor - X11 mode */ 347 Permedia2OutIndReg(pScrn, PM2DACCursorControl, 0x00, 0x43); 348} 349 350static void 351Permedia2HideCursor(ScrnInfoPtr pScrn) 352{ 353 /* Disable cursor */ 354 Permedia2OutIndReg(pScrn, PM2DACCursorControl, 0x00, 0x00); 355} 356 357static void 358Permedia2LoadCursorImage( 359 ScrnInfoPtr pScrn, 360 unsigned char *src 361) 362{ 363 GLINTPtr pGlint = GLINTPTR(pScrn); 364 int i; 365 366 GLINT_SLOW_WRITE_REG(0x00, PM2DACWriteAddress); 367 for (i=0; i<1024; i++) { 368 GLINT_SLOW_WRITE_REG(*(src++), PM2DACCursorData); 369 } 370} 371 372static void 373Permedia2SetCursorPosition( 374 ScrnInfoPtr pScrn, 375 int x, int y 376) 377{ 378 GLINTPtr pGlint = GLINTPTR(pScrn); 379 380 x += 64; 381 y += 64; 382 383 /* Output position - "only" 11 bits of location documented */ 384 385 GLINT_WRITE_REG(x & 0xFF, PM2DACCursorXLsb); 386 GLINT_WRITE_REG((x>>8) & 0x07, PM2DACCursorXMsb); 387 GLINT_WRITE_REG(y & 0xFF, PM2DACCursorYLsb); 388 GLINT_WRITE_REG((y>>8) & 0x07, PM2DACCursorYMsb); 389} 390 391static void 392Permedia2SetCursorColors( 393 ScrnInfoPtr pScrn, 394 int bg, int fg 395) 396{ 397 GLINTPtr pGlint = GLINTPTR(pScrn); 398 /* The Permedia2 cursor is always 8 bits so shift 8, not 10 */ 399 400 GLINT_SLOW_WRITE_REG(1, PM2DACCursorColorAddress); 401 /* Background color */ 402 GLINT_SLOW_WRITE_REG(bg >> 0, PM2DACCursorColorData); 403 GLINT_SLOW_WRITE_REG(bg >> 8, PM2DACCursorColorData); 404 GLINT_SLOW_WRITE_REG(bg >> 16, PM2DACCursorColorData); 405 406 /* Foreground color */ 407 GLINT_SLOW_WRITE_REG(fg >> 0, PM2DACCursorColorData); 408 GLINT_SLOW_WRITE_REG(fg >> 8, PM2DACCursorColorData); 409 GLINT_SLOW_WRITE_REG(fg >> 16, PM2DACCursorColorData); 410} 411 412static Bool 413Permedia2UseHWCursor(ScreenPtr pScr, CursorPtr pCurs) 414{ 415 return TRUE; 416} 417 418Bool 419Permedia2HWCursorInit(ScreenPtr pScreen) 420{ 421 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 422 GLINTPtr pGlint = GLINTPTR(pScrn); 423 xf86CursorInfoPtr infoPtr; 424 425 infoPtr = xf86CreateCursorInfoRec(); 426 if(!infoPtr) return FALSE; 427 428 pGlint->CursorInfoRec = infoPtr; 429 430 infoPtr->MaxWidth = 64; 431 infoPtr->MaxHeight = 64; 432 infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 433#if X_BYTE_ORDER == X_LITTLE_ENDIAN 434 HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | 435#endif 436 HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED; 437 infoPtr->SetCursorColors = Permedia2SetCursorColors; 438 infoPtr->SetCursorPosition = Permedia2SetCursorPosition; 439 infoPtr->LoadCursorImage = Permedia2LoadCursorImage; 440 infoPtr->HideCursor = Permedia2HideCursor; 441 infoPtr->ShowCursor = Permedia2ShowCursor; 442 infoPtr->UseHWCursor = Permedia2UseHWCursor; 443 444 return(xf86InitCursor(pScreen, infoPtr)); 445} 446 447/* I2C Functions */ 448 449void 450Permedia2I2CUDelay(I2CBusPtr b, int usec) 451{ 452 GLINTPtr pGlint = (GLINTPtr) b->DriverPrivate.ptr; 453 CARD32 ct1 = GLINT_READ_REG(PMCount); 454 CARD32 ct2 = usec * 100; 455 456 if (GLINT_READ_REG(PMCount) != ct1) 457 while ((GLINT_READ_REG(PMCount) - ct1) < ct2); 458} 459 460void 461Permedia2I2CPutBits(I2CBusPtr b, int scl, int sda) 462{ 463 GLINTPtr pGlint = (GLINTPtr) b->DriverPrivate.ptr; 464 int r = (pGlint->DDCBus == b) ? PMDDCData : VSSerialBusControl; 465/* 466 This is bogus. 467 All this line does is to preserve the USE_MONID bit if set which prevents 468 the i2c bits from doing anything 469 CARD32 v = GLINT_READ_REG(r) & ~(ClkOut | DataOut); 470*/ 471 CARD32 v = 0; 472 473 if (scl > 0) v |= ClkOut; 474 if (sda > 0) v |= DataOut; 475 476 GLINT_WRITE_REG(v, r); 477} 478 479void 480Permedia2I2CGetBits(I2CBusPtr b, int *scl, int *sda) 481{ 482 GLINTPtr pGlint = (GLINTPtr) b->DriverPrivate.ptr; 483 CARD32 v = GLINT_READ_REG((pGlint->DDCBus == b) ? 484 PMDDCData : VSSerialBusControl); 485 486 *scl = (v & ClkIn) > 0; 487 *sda = (v & DataIn) > 0; 488} 489 490void 491Permedia2PreInit(ScrnInfoPtr pScrn) 492{ 493#if defined(__alpha__) 494 GLINTPtr pGlint = GLINTPTR(pScrn); 495 496 /* 497 * On Alpha, we have to init secondary PM2 cards, since 498 * int10 cannot be run on the OEMed cards with VGA disable 499 * jumpers. 500 */ 501 if (!xf86IsPrimaryPci(pGlint->PciInfo)) { 502 if ( IS_GLORIASYNERGY ) { 503 504 /* PM2DAC_CalculateMNPCForClock(80000, 14318, &m, &n, &p); */ 505 Permedia2OutIndReg(pScrn, PM2DACIndexMemClockM, 0x00, 0x7b); 506 Permedia2OutIndReg(pScrn, PM2DACIndexMemClockN, 0x00, 0x0b); 507 Permedia2OutIndReg(pScrn, PM2DACIndexMemClockP, 0x00, 0x09); 508 509 GLINT_SLOW_WRITE_REG( 0x20, PMBootAddress); 510 GLINT_SLOW_WRITE_REG( 0xe6002021, PMMemConfig); 511 } 512 } 513#endif /* __alpha__ */ 514} 515