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