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