1/* 2 * Driver for the SGI Indy's Newport graphics card 3 * 4 * This driver is based on the newport.c & newport_con.c kernel code 5 * 6 * (c) 2000-2002 Guido Guenther <agx@sigxcpu.org> 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * of this software and associated documentation files (the "Software"), to deal 10 * in the Software without restriction, including without limitation the rights 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * copies of the Software, and to permit persons to whom the Software is fur- 13 * nished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included in 16 * all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- 20 * NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 22 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- 23 * NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 * Except as contained in this notice, the name of the XFree86 Project shall not 26 * be used in advertising or otherwise to promote the sale, use or other deal- 27 * ings in this Software without prior written authorization from the XFree86 28 * Project. 29 * 30 */ 31 32#ifdef HAVE_CONFIG_H 33#include "config.h" 34#endif 35 36#if defined(__NetBSD__) 37#include <fcntl.h> 38#include <dev/wscons/wsconsio.h> 39#include <sys/ioctl.h> 40#endif 41 42/* function prototypes, common data structures & generic includes */ 43#include "newport.h" 44 45/* Drivers using the mi SW cursor need: */ 46#include "mipointer.h" 47/* Drivers using the mi colourmap code need: */ 48#include "micmap.h" 49 50/* Drivers using fb need: */ 51#include "fb.h" 52 53/* Drivers using the shadow frame buffer need: */ 54#include "shadowfb.h" 55 56/* Xv Extension */ 57#include "xf86xv.h" 58#include <X11/extensions/Xv.h> 59 60#include <string.h> 61#include <stdio.h> 62#include <unistd.h> 63 64#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) > 6 65#define xf86LoaderReqSymLists(...) do {} while (0) 66#define LoaderRefSymLists(...) do {} while (0) 67#endif 68 69#define NEWPORT_VERSION 4000 70#define NEWPORT_NAME "NEWPORT" 71#define NEWPORT_DRIVER_NAME "newport" 72#define NEWPORT_MAJOR_VERSION PACKAGE_VERSION_MAJOR 73#define NEWPORT_MINOR_VERSION PACKAGE_VERSION_MINOR 74#define NEWPORT_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL 75 76 77/* Prototypes ------------------------------------------------------- */ 78static void NewportIdentify(int flags); 79static const OptionInfoRec * NewportAvailableOptions(int chipid, int busid); 80static Bool NewportProbe(DriverPtr drv, int flags); 81static Bool NewportPreInit(ScrnInfoPtr pScrn, int flags); 82static Bool NewportScreenInit(int Index, ScreenPtr pScreen, int argc, char **argv); 83static Bool NewportEnterVT(int scrnIndex, int flags); 84static void NewportLeaveVT(int scrnIndex, int flags); 85static Bool NewportCloseScreen(int scrnIndex, ScreenPtr pScreen); 86static Bool NewportSaveScreen(ScreenPtr pScreen, int mode); 87static unsigned NewportHWProbe(unsigned probedIDs[]); /* return number of found boards */ 88static Bool NewportModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); 89static void NewportRestore(ScrnInfoPtr pScrn, Bool Closing); 90static Bool NewportGetRec(ScrnInfoPtr pScrn); 91static Bool NewportFreeRec(ScrnInfoPtr pScrn); 92static Bool NewportMapRegs(ScrnInfoPtr pScrn); 93static void NewportUnmapRegs(ScrnInfoPtr pScrn); 94static Bool NewportProbeCardInfo(ScrnInfoPtr pScrn); 95/* ------------------------------------------------------------------ */ 96 97_X_EXPORT DriverRec NEWPORT = { 98 NEWPORT_VERSION, 99 NEWPORT_DRIVER_NAME, 100 NewportIdentify, 101 NewportProbe, 102 NewportAvailableOptions, 103 NULL, 104 0 105}; 106 107/* Supported "chipsets" */ 108#define CHIP_XL 0x1 109 110static SymTabRec NewportChipsets[] = { 111 { CHIP_XL, "XL" }, 112 {-1, NULL } 113}; 114 115static MODULESETUPPROTO(newportSetup); 116 117static XF86ModuleVersionInfo newportVersRec = 118{ 119 "newport", 120 MODULEVENDORSTRING, 121 MODINFOSTRING1, 122 MODINFOSTRING2, 123 XORG_VERSION_CURRENT, 124/* 125 XF86_VERSION_CURRENT, 126*/ 127 NEWPORT_MAJOR_VERSION, NEWPORT_MINOR_VERSION, NEWPORT_PATCHLEVEL, 128 ABI_CLASS_VIDEODRV, 129 ABI_VIDEODRV_VERSION, 130 MOD_CLASS_VIDEODRV, 131 {0,0,0,0} 132}; 133 134_X_EXPORT XF86ModuleData newportModuleData = { 135 &newportVersRec, 136 newportSetup, 137 NULL 138}; 139 140static pointer 141newportSetup(pointer module, pointer opts, int *errmaj, int *errmin) 142{ 143 static Bool setupDone = FALSE; 144 145/* This module should be loaded only once, but check to be sure. */ 146 if (!setupDone) { 147 /* 148 * Modules that this driver always requires may be loaded 149 * here by calling LoadSubModule(). 150 */ 151 setupDone = TRUE; 152 xf86AddDriver(&NEWPORT, module, 0); 153 154 /* 155 * The return value must be non-NULL on success even though 156 * there is no TearDownProc. 157 */ 158 return (pointer)1; 159 } else { 160 if (errmaj) *errmaj = LDR_ONCEONLY; 161 return NULL; 162 } 163} 164 165typedef enum { 166 OPTION_BITPLANES, 167 OPTION_BUS_ID, 168 OPTION_HWCURSOR, 169 OPTION_NOACCEL 170} NewportOpts; 171 172/* Supported options */ 173static const OptionInfoRec NewportOptions [] = { 174 { OPTION_BITPLANES, "bitplanes", OPTV_INTEGER, {0}, FALSE }, 175 { OPTION_BUS_ID, "BusID", OPTV_INTEGER, {0}, FALSE }, 176 { OPTION_HWCURSOR, "HWCursor", OPTV_BOOLEAN, {0}, FALSE }, 177 { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 178 { -1, NULL, OPTV_NONE, {0}, FALSE } 179}; 180 181/* ------------------------------------------------------------------ */ 182 183static Bool 184NewportGetRec(ScrnInfoPtr pScrn) 185{ 186 NewportPtr pNewport; 187 if (pScrn->driverPrivate != NULL) 188 return TRUE; 189 pScrn->driverPrivate = xnfcalloc(sizeof(NewportRec), 1); 190 191 pNewport = NEWPORTPTR(pScrn); 192 pNewport->pNewportRegs = NULL; 193 194 return TRUE; 195} 196 197static Bool 198NewportFreeRec(ScrnInfoPtr pScrn) 199{ 200 free(pScrn->driverPrivate); 201 pScrn->driverPrivate = NULL; 202 return TRUE; 203} 204 205static void 206NewportIdentify(int flags) 207{ 208 xf86PrintChipsets( NEWPORT_NAME, "driver for Newport Graphics Card", 209 NewportChipsets); 210} 211 212static Bool 213NewportProbe(DriverPtr drv, int flags) 214{ 215 int numDevSections, numUsed, i, j, busID; 216 Bool foundScreen = FALSE; 217 GDevPtr *devSections; 218 GDevPtr dev = NULL; 219#ifndef XSERVER_LIBPCIACCESS 220 resRange range[] = { {ResExcMemBlock ,0,0}, _END }; 221#endif 222 unsigned probedIDs[NEWPORT_MAX_BOARDS]; 223 memType base; 224 if ((numDevSections = xf86MatchDevice(NEWPORT_DRIVER_NAME, &devSections)) <= 0) 225 return FALSE; 226 227 numUsed = NewportHWProbe(probedIDs); 228 if ( numUsed <= 0 ) 229 return FALSE; 230 231 if ( xf86DoConfigure && xf86DoConfigurePass1 ) { 232 GDevPtr pGDev; 233 for (i = 0; i < numUsed; i++) { 234 pGDev = xf86AddBusDeviceToConfigure(NEWPORT_DRIVER_NAME, 235 BUS_NONE, NULL, 0); 236 if (pGDev) { 237 /* 238 * XF86Match???Instances() treat chipID and 239 * chipRev as overrides, so clobber them here. 240 */ 241 pGDev->chipID = pGDev->chipRev = -1; 242 } 243 } 244 } 245 246 if(flags & PROBE_DETECT) { 247 foundScreen = TRUE; 248 } else { 249 for (i = 0; i < numDevSections; i++) { 250 dev = devSections[i]; 251 busID = xf86SetIntOption(dev->options, "BusID", 0); 252 253 for( j = 0; j < numUsed; j++) { 254 if ( busID == probedIDs[j] ) { 255 int entity; 256 ScrnInfoPtr pScrn = NULL; 257 258 entity = xf86ClaimNoSlot(drv, 0, dev, TRUE); 259#ifndef XSERVER_LIBPCIACCESS 260 base = (NEWPORT_BASE_ADDR0 261 + busID * NEWPORT_BASE_OFFSET); 262 RANGE(range[0], base, base + sizeof(NewportRegs),\ 263 ResExcMemBlock); 264#endif 265 pScrn = xf86AllocateScreen(drv, 0); 266 xf86AddEntityToScreen(pScrn, entity); 267 pScrn->driverVersion = NEWPORT_VERSION; 268 pScrn->driverName = NEWPORT_DRIVER_NAME; 269 pScrn->name = NEWPORT_NAME; 270 pScrn->Probe = NewportProbe; 271 pScrn->PreInit = NewportPreInit; 272 pScrn->ScreenInit = NewportScreenInit; 273 pScrn->EnterVT = NewportEnterVT; 274 pScrn->LeaveVT = NewportLeaveVT; 275 pScrn->driverPrivate = (void*)(long)busID; 276 foundScreen = TRUE; 277 break; 278 } 279 } 280 } 281 } 282 free(devSections); 283 return foundScreen; 284} 285 286/* most of this is from DESIGN.TXT s20.3.6 */ 287static Bool 288NewportPreInit(ScrnInfoPtr pScrn, int flags) 289{ 290 int i, busID; 291 NewportPtr pNewport; 292 MessageType from; 293 ClockRangePtr clockRanges; 294 295 if (flags & PROBE_DETECT) return FALSE; 296 297 if (pScrn->numEntities != 1) 298 return FALSE; 299 300 busID = (long)(pScrn->driverPrivate); 301 pScrn->driverPrivate = NULL; 302 303 /* Fill in the monitor field */ 304 pScrn->monitor = pScrn->confScreen->monitor; 305 306#ifdef NEWPORT_USE32BPP 307 if (!xf86SetDepthBpp(pScrn, 24, 32, 32, Support32bppFb)) 308 return FALSE; 309#else 310 if (!xf86SetDepthBpp(pScrn, 24, 0, 0, 311 Support24bppFb | SupportConvert32to24 | 312 PreferConvert32to24 )) 313 return FALSE; 314#endif 315 switch( pScrn->depth ) { 316 /* check if the returned depth is one we support */ 317 case 8: 318 case 24: 319 /* OK */ 320 break; 321 default: 322 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 323 "Given depth (%d) is not supported by Newport driver\n", 324 pScrn->depth); 325 return FALSE; 326 } 327 xf86PrintDepthBpp(pScrn); 328 329 /* Set bits per RGB for 8bpp */ 330 if( pScrn->depth == 8) 331 pScrn->rgbBits = 8; 332 333 /* Set Default Weight */ 334 if( pScrn->depth > 8 ) { 335#ifdef NEWPORT_USE32BPP 336 rgb w = {8, 8, 8}; 337 rgb m = {0x0000FF, 0x00FF00, 0xFF0000}; 338 if (!xf86SetWeight(pScrn, w, m)) 339 return FALSE; 340#else 341 rgb zeros = {0, 0, 0}; 342 if (!xf86SetWeight(pScrn, zeros, zeros)) 343 return FALSE; 344#endif 345 } 346 347 if (!xf86SetDefaultVisual(pScrn, -1)) { 348 return FALSE; 349 } else { 350 if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { 351 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" 352 " (%s) is not supported at depth %d\n", 353 xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); 354 return FALSE; 355 } 356 } 357 358 { /* Set default Gamma */ 359 Gamma zeros = {0.0, 0.0, 0.0}; 360 361 if (!xf86SetGamma(pScrn, zeros)) { 362 return FALSE; 363 } 364 } 365 366 /* Allocate the NewportRec driverPrivate */ 367 if (!NewportGetRec(pScrn)) { 368 return FALSE; 369 } 370 pNewport = NEWPORTPTR(pScrn); 371 pNewport->busID = busID; 372 373 pScrn->memPhysBase = 0; 374 pScrn->fbOffset = 0; 375 376 /* We use a programmable clock */ 377 pScrn->progClock = TRUE; 378 379 /* Fill in pScrn->options) */ 380 xf86CollectOptions(pScrn, NULL); 381 if (!(pNewport->Options = malloc(sizeof(NewportOptions)))) 382 return FALSE; 383 memcpy(pNewport->Options, NewportOptions, sizeof(NewportOptions)); 384 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pNewport->Options); 385 386 /* Set fields in ScreenInfoRec && NewportRec */ 387 pScrn->videoRam = 1280 * (pScrn->bitsPerPixel >> 3); 388 389 /* get revisions of REX3, etc. */ 390 if( ! NewportMapRegs(pScrn)) 391 return FALSE; 392 NewportProbeCardInfo(pScrn); 393 NewportUnmapRegs(pScrn); 394 395 from=X_PROBED; 396 xf86DrvMsg(pScrn->scrnIndex, from, 397 "Newport Graphics Revisions: Board: %d, Rex3: %c, Cmap: %c, Xmap9: %c\n", 398 pNewport->board_rev, pNewport->rex3_rev, 399 pNewport->cmap_rev, pNewport->xmap9_rev); 400 401 if ( (xf86GetOptValInteger(pNewport->Options, OPTION_BITPLANES, 402 &pNewport->bitplanes))) 403 from = X_CONFIG; 404 xf86DrvMsg(pScrn->scrnIndex, from, "Newport has %d bitplanes\n", 405 pNewport->bitplanes); 406 407 if ( pScrn->depth > pNewport->bitplanes ) { 408 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ 409 "Display depth(%d) > number of bitplanes on Newport board(%d)\n", \ 410 pScrn->depth, pNewport->bitplanes); 411 return FALSE; 412 } 413 if ( ( pNewport->bitplanes != 8 ) && ( pNewport->bitplanes != 24 ) ) { 414 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ 415 "Number of bitplanes on newport must be either 8 or 24 not %d\n", \ 416 pNewport->bitplanes); 417 return FALSE; 418 } 419 420 from=X_DEFAULT; 421 pNewport->hwCursor = TRUE; 422 if (xf86GetOptValBool(pNewport->Options, OPTION_HWCURSOR, &pNewport->hwCursor)) 423 from = X_CONFIG; 424 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 425 pNewport->hwCursor ? "HW" : "SW"); 426 427 /* Set up clock ranges that are alway ok */ 428 /* XXX: Use information from VC2 here */ 429 clockRanges = xnfcalloc(sizeof(ClockRange),1); 430 clockRanges->next = NULL; 431 clockRanges->minClock = 10000; 432 clockRanges->maxClock = 300000; 433 clockRanges->clockIndex = -1; /* programmable */ 434 clockRanges->interlaceAllowed = TRUE; 435 clockRanges->doubleScanAllowed = TRUE; 436 437 /* see above note */ 438 /* There is currently only an 1280x1024 mode */ 439 i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 440 pScrn->display->modes, clockRanges, 441 NULL, 256, 2048, 442 pScrn->bitsPerPixel, 128, 2048, 443 pScrn->display->virtualX, 444 pScrn->display->virtualY, 445 pScrn->videoRam * 1024, 446 LOOKUP_BEST_REFRESH); 447 448 if (i == -1) { 449 NewportFreeRec(pScrn); 450 return FALSE; 451 } 452 453 xf86PruneDriverModes(pScrn); 454 if( i == 0 || pScrn->modes == NULL) { 455 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); 456 NewportFreeRec(pScrn); 457 return FALSE; 458 } 459 460 /* unnecessary, but do it to get a valid ScrnInfoRec */ 461 xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); 462 463 /* Set the current mode to the first in the list */ 464 pScrn->currentMode = pScrn->modes; 465 466 /* Print the list of modes being used */ 467 xf86PrintModes(pScrn); 468 xf86SetDpi (pScrn, 0, 0); 469 470 /* Load FB module */ 471 if (!xf86LoadSubModule (pScrn, "fb")) { 472 NewportFreeRec(pScrn); 473 return FALSE; 474 } 475 476 /* Load ramdac modules */ 477 if (pNewport->hwCursor) { 478 if (!xf86LoadSubModule(pScrn, "ramdac")) { 479 NewportFreeRec(pScrn); 480 return FALSE; 481 } 482 } 483 484 /* Load ShadowFB module */ 485 if (!xf86LoadSubModule(pScrn, "shadowfb")) { 486 NewportFreeRec(pScrn); 487 return FALSE; 488 } 489 490 /* Load XAA module */ 491 if (!xf86LoadSubModule(pScrn, "xaa")) { 492 NewportFreeRec(pScrn); 493 return FALSE; 494 } 495 xf86LoaderReqSymLists(xaaSymbols, NULL); 496 return TRUE; 497} 498 499 500Bool 501NewportXAAScreenInit(ScreenPtr pScreen); 502 503 504static Bool 505NewportScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) 506{ 507 ScrnInfoPtr pScrn; 508 NewportPtr pNewport; 509 VisualPtr visual; 510 BOOL ret; 511 int i; 512 513 /* First get a pointer to our private info */ 514 pScrn = xf86Screens[pScreen->myNum]; 515 pNewport = NEWPORTPTR(pScrn); 516 517 /* map the Newportregs until the server dies */ 518 if( ! NewportMapRegs(pScrn)) 519 return FALSE; 520 521 /* Reset visual list. */ 522 miClearVisualTypes(); 523 524 if (!miSetVisualTypes(pScrn->depth, pScrn->depth != 8 ? TrueColorMask : 525 miGetDefaultVisualMask(pScrn->depth), 526 pScrn->rgbBits, pScrn->defaultVisual)) 527 return FALSE; 528 529 miSetPixmapDepths (); 530 531 pNewport->Bpp = pScrn->bitsPerPixel >> 3; 532 /* Setup the stuff for the shadow framebuffer */ 533 pNewport->ShadowPitch = (( pScrn->virtualX * pNewport->Bpp ) + 3) & ~3L; 534 pNewport->ShadowPtr = xnfalloc(pNewport->ShadowPitch * pScrn->virtualY); 535 536 if (!NewportModeInit(pScrn, pScrn->currentMode)) 537 return FALSE; 538 539 ret = fbScreenInit(pScreen, pNewport->ShadowPtr, 540 pScrn->virtualX, pScrn->virtualY, 541 pScrn->xDpi, pScrn->yDpi, 542 pScrn->displayWidth, 543 pScrn->bitsPerPixel); 544 545 if(!ret) 546 return FALSE; 547 548 /* we need rgb ordering if bitsPerPixel > 8 */ 549 if (pScrn->bitsPerPixel > 8) { 550 for (i = 0, visual = pScreen->visuals; 551 i < pScreen->numVisuals; i++, visual++) { 552 if ((visual->class | DynamicClass) == DirectColor) { 553 visual->offsetRed = pScrn->offset.red; 554 visual->offsetGreen = pScrn->offset.green; 555 visual->offsetBlue = pScrn->offset.blue; 556 visual->redMask = pScrn->mask.red; 557 visual->greenMask = pScrn->mask.green; 558 visual->blueMask = pScrn->mask.blue; 559 /* 560 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bitplanes R:%d:%08X G:%d:%08X B:%d:%08X\n", 561 visual->offsetRed, visual->redMask, 562 visual->offsetGreen, visual->greenMask, 563 visual->offsetBlue, visual->blueMask); 564 */ 565 } 566 } 567 } 568 569 /* must be after RGB ordering fixed */ 570 if (!fbPictureInit(pScreen, NULL, 0)) 571 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 572 "RENDER extension initialisation failed.\n"); 573 574 xf86SetBackingStore(pScreen); 575 576 xf86SetBlackWhitePixels(pScreen); 577#ifdef NEWPORT_ACCEL 578 pNewport->NoAccel = FALSE; 579 if (xf86ReturnOptValBool(pNewport->Options, OPTION_NOACCEL, FALSE)) 580 { 581 pNewport->NoAccel = TRUE; 582 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); 583 } 584 if (!pNewport->NoAccel) { 585 if (!xf86LoadSubModule(pScrn, "xaa")) 586 pNewport->NoAccel = TRUE; 587 } 588#if 0 589 if (pScrn->bitsPerPixel < 24) 590 { /* not implemented yet */ 591 pNewport->NoAccel = TRUE; 592 } 593#endif 594 pNewport->pXAAInfoRec = NULL; 595 if (!pNewport->NoAccel) 596 { 597 if (!NewportXAAScreenInit(pScreen)) 598 return FALSE; 599 } 600#endif 601 /* Initialize software cursor */ 602 if(!miDCInitialize(pScreen, xf86GetPointerScreenFuncs())) 603 return FALSE; 604 605 /* Initialize hardware cursor */ 606 if(pNewport->hwCursor) 607 if(!NewportHWCursorInit(pScreen)) { 608 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 609 "Hardware cursor initialization failed\n"); 610 return FALSE; 611 } 612 613 /* Initialise default colourmap */ 614 if (!miCreateDefColormap(pScreen)) 615 return FALSE; 616 617 /* Install our LoadPalette funciton */ 618 if(!xf86HandleColormaps(pScreen, 256, 8, NewportLoadPalette, 0, 619 CMAP_RELOAD_ON_MODE_SWITCH )) { 620 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 621 "Colormap initialization failed\n"); 622 return FALSE; 623 } 624#ifdef NEWPORT_ACCEL 625 if (pNewport->NoAccel) 626#endif 627 /* Initialise shadow frame buffer */ 628 if(!ShadowFBInit(pScreen, (pNewport->Bpp == 1) ? &NewportRefreshArea8 : 629 &NewportRefreshArea24)) { 630 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 631 "ShadowFB initialization failed\n"); 632 return FALSE; 633 } 634 635 { 636 XF86VideoAdaptorPtr *ptr; 637 int n; 638 639 n = xf86XVListGenericAdaptors(pScrn,&ptr); 640 if (n) { 641 xf86XVScreenInit(pScreen, ptr, n); 642 } 643 } 644 645 pScreen->SaveScreen = NewportSaveScreen; 646 /* Wrap the current CloseScreen function */ 647 pNewport->CloseScreen = pScreen->CloseScreen; 648 pScreen->CloseScreen = NewportCloseScreen; 649 650 if (serverGeneration == 1) { 651 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 652 } 653 NewportModeInit(pScrn, pScrn->currentMode); 654 return TRUE; 655} 656 657/* called when switching away from a VT */ 658static Bool 659NewportEnterVT(int scrnIndex, int flags) 660{ 661 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 662 return NewportModeInit(pScrn, pScrn->currentMode); 663} 664 665/* called when switching to a VT */ 666static void 667NewportLeaveVT(int scrnIndex, int flags) 668{ 669 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 670 NewportRestore(pScrn, FALSE); 671} 672 673/* called at the end of each server generation */ 674static Bool 675NewportCloseScreen(int scrnIndex, ScreenPtr pScreen) 676{ 677 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 678 NewportPtr pNewport = NEWPORTPTR(pScrn); 679#ifdef NEWPORT_ACCEL 680 if (pNewport->pXAAInfoRec && !pNewport->NoAccel) 681 { 682 XAADestroyInfoRec(pNewport->pXAAInfoRec); 683 pNewport->pXAAInfoRec = NULL; 684 } 685#endif 686 687 NewportRestore(pScrn, TRUE); 688 free(pNewport->ShadowPtr); 689 690 /* unmap the Newport's registers from memory */ 691 NewportUnmapRegs(pScrn); 692 pScrn->vtSema = FALSE; 693 694 pScreen->CloseScreen = pNewport->CloseScreen; 695 return (*pScreen->CloseScreen)(scrnIndex, pScreen); 696} 697 698/* Blank or unblank the screen */ 699static Bool 700NewportSaveScreen(ScreenPtr pScreen, int mode) 701{ 702 ScrnInfoPtr pScrn; 703 NewportPtr pNewport; 704 NewportRegsPtr pNewportRegs; 705 Bool unblank; 706 707 if (!pScreen) 708 return TRUE; 709 710 unblank = xf86IsUnblank(mode); 711 pScrn = xf86Screens[pScreen->myNum]; 712 713 if (!pScrn->vtSema) 714 return TRUE; 715 716 pNewport = NEWPORTPTR(pScrn); 717 pNewportRegs = NEWPORTPTR(pScrn)->pNewportRegs; 718 719 if (unblank) 720 pNewport->vc2ctrl |= VC2_CTRL_EDISP; 721 else 722 pNewport->vc2ctrl &= ~VC2_CTRL_EDISP; 723 NewportVc2Set( pNewportRegs, VC2_IREG_CONTROL, pNewport->vc2ctrl); 724 return TRUE; 725} 726 727 728static const OptionInfoRec * 729NewportAvailableOptions(int chipid, int busid) 730{ 731 return NewportOptions; 732} 733 734 735/* This sets up the actual mode on the Newport */ 736static Bool 737NewportModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 738{ 739 int width, height; 740 NewportPtr pNewport = NEWPORTPTR(pScrn); 741 NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); 742 743 width = mode->HDisplay; 744 height = mode->VDisplay; 745 if ((width > 1280) || (width < 1024) || 746 (height < 768) || (height > 1024)) { 747 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ 748 "Width = %d and height = %d is not supported by by this driver\n", width, height); 749 return FALSE; 750 } 751 752 pScrn->vtSema = TRUE; 753 /* first backup the necessary registers... */ 754 NewportBackupRex3(pScrn); 755 if( pNewport->hwCursor ) 756 NewportBackupVc2Cursor( pScrn ); 757 NewportBackupVc2(pScrn); 758 NewportBackupPalette(pScrn); 759 NewportBackupXmap9s( pScrn ); 760 /* ...then setup the hardware */ 761 pNewport->drawmode1 = DM1_RGBPLANES | 762 NPORT_DMODE1_CCLT | 763 NPORT_DMODE1_CCEQ | 764 NPORT_DMODE1_CCGT | 765 NPORT_DMODE1_LOSRC; 766 if( pNewport->Bpp == 1) { /* 8bpp */ 767 pNewport->drawmode1 |= NPORT_DMODE1_DD8 | 768 NPORT_DMODE1_HD8 | 769 NPORT_DMODE1_RWPCKD; 770 } else { /* 24bpp */ 771 CARD32 mode = 0L; 772 LOCO col; 773 int i; 774 775 /* tell the xmap9s that we are using 24bpp */ 776 NewportBfwait(pNewport->pNewportRegs); 777 pNewportRegs->set.dcbmode = (DCB_XMAP_ALL | 778 W_DCB_XMAP9_PROTOCOL | XM9_CRS_CONFIG | NPORT_DMODE_W1 ); 779 pNewportRegs->set.dcbdata0.bytes.b3 &= 780 ~(XM9_8_BITPLANES | XM9_PUPMODE); 781 NewportBfwait(pNewport->pNewportRegs); 782 /* set up the mode register for 24bpp */ 783 mode = XM9_MREG_PIX_SIZE_24BPP | XM9_MREG_PIX_MODE_RGB2 784 | XM9_MREG_GAMMA_BYPASS; 785 for (i = 0; i < 32; i++) 786 NewportXmap9SetModeRegister( pNewportRegs , i, mode); 787 788 /* select the set up mode register */ 789 NewportBfwait(pNewport->pNewportRegs); 790 pNewportRegs->set.dcbmode = (DCB_XMAP_ALL | W_DCB_XMAP9_PROTOCOL | 791 XM9_CRS_MODE_REG_INDEX | NPORT_DMODE_W1 ); 792 pNewportRegs->set.dcbdata0.bytes.b3 = 0; 793 794 pNewport->drawmode1 |= 795 /* set drawdepth to 24 bit */ 796 NPORT_DMODE1_DD24 | 797 /* turn on RGB mode */ 798 NPORT_DMODE1_RGBMD | 799 /* turn on 8888 = RGBA pixel packing */ 800 NPORT_DMODE1_HD32 | NPORT_DMODE1_RWPCKD; 801 /* 802 * After setting up XMAP9 we have to reinitialize the CMAP for 803 * whatever reason (the docs say nothing about it). 804 */ 805 806 807 for (i = 0; i < 256; i++) { 808 col.red = col.green = col.blue = i; 809 NewportCmapSetRGB(NEWPORTREGSPTR(pScrn), i, col); 810 } 811 for (i = 0; i < 256; i++) { 812 col.red = col.green = col.blue = i; 813 NewportCmapSetRGB(NEWPORTREGSPTR(pScrn), i + 0x1f00, 814 col); 815 } 816 817 } 818 /* blank the framebuffer */ 819 NewportWait(pNewportRegs); 820 pNewportRegs->set.drawmode0 = (NPORT_DMODE0_DRAW | 821 NPORT_DMODE0_DOSETUP | 822 NPORT_DMODE0_STOPX | NPORT_DMODE0_STOPY | 823 NPORT_DMODE0_BLOCK); 824 pNewportRegs->set.drawmode1 = pNewport->drawmode1 | 825 NPORT_DMODE1_FCLR | 826 NPORT_DMODE1_RGBMD; 827 pNewportRegs->set.colorvram = 0; 828 pNewportRegs->set.xystarti = 0; 829 pNewportRegs->go.xyendi = ( (1279+64) << 16) | 1023; 830 831 /* default drawmode */ 832 NewportWait(pNewportRegs); 833 pNewportRegs->set.drawmode1 = pNewport->drawmode1; 834 835 /* XXX: Lazy mode on: just use the textmode value */ 836 pNewport->vc2ctrl = pNewport->txt_vc2ctrl; 837 838 return TRUE; 839} 840 841 842/* 843 * This will actually restore the saved state 844 * (either when switching back to a VT or when the server is going down) 845 * Closing is true if the X server is really going down 846 */ 847static void 848NewportRestore(ScrnInfoPtr pScrn, Bool Closing) 849{ 850 NewportPtr pNewport = NEWPORTPTR(pScrn); 851 852 /* Restore backed up registers */ 853 NewportRestoreRex3( pScrn ); 854 if( pNewport->hwCursor ) 855 NewportRestoreVc2Cursor( pScrn ); 856 NewportRestoreVc2( pScrn ); 857 NewportRestorePalette( pScrn ); 858 NewportRestoreXmap9s( pScrn ); 859} 860 861 862/* Probe for the Newport card ;) */ 863/* XXX: we need a better probe here in order to support multihead! */ 864static unsigned 865NewportHWProbe(unsigned probedIDs[]) 866{ 867 unsigned hasNewport = 0; 868 869#if defined(__NetBSD__) 870 int fd, type, i; 871 872 probedIDs[0] = 0; 873 874 fd = open("/dev/ttyE0", O_RDONLY, 0); 875 i = ioctl(fd, WSDISPLAYIO_GTYPE, &type); 876 close(fd); 877 878 if ( (i == 0) && ( type == WSDISPLAY_TYPE_NEWPORT) ) 879 hasNewport = 1; 880#else 881 FILE* cpuinfo; 882 char line[80]; 883 if ((cpuinfo = fopen("/proc/cpuinfo", "r"))) { 884 while(fgets(line, 80, cpuinfo) != NULL) { 885 if(strstr(line, "SGI Indy") != NULL) { 886 hasNewport = 1; 887 probedIDs[0] = 0; 888 break; 889 } 890 if(strstr(line, "SGI Indigo2") != NULL) { 891 hasNewport = 1; 892 probedIDs[0] = 1; 893 break; 894 } 895 } 896 fclose(cpuinfo); 897 } 898#endif 899 return hasNewport; 900} 901 902/* Probe for Chipset revisions */ 903static Bool NewportProbeCardInfo(ScrnInfoPtr pScrn) 904{ 905 unsigned int tmp,cmap_rev; 906 NewportPtr pNewport = NEWPORTPTR(pScrn); 907 NewportRegsPtr pNewportRegs = pNewport->pNewportRegs; 908 909 NewportWait(pNewportRegs); 910 pNewportRegs->set.dcbmode = (DCB_CMAP0 | NCMAP_PROTOCOL | 911 NCMAP_REGADDR_RREG | NPORT_DMODE_W1); 912 tmp = pNewportRegs->set.dcbdata0.bytes.b3; 913 pNewport->board_rev = (tmp >> 4) & 7; 914 pNewport->bitplanes = ((pNewport->board_rev > 1) && (tmp & 0x80)) ? 8 : 24; 915 cmap_rev = tmp & 7; 916 pNewport->cmap_rev = (char)('A'+(cmap_rev ? (cmap_rev+1):0)); 917 pNewport->rex3_rev = (char)('A'+(pNewportRegs->cset.ustat & 7)); 918 919 pNewportRegs->set.dcbmode = (DCB_XMAP0 | R_DCB_XMAP9_PROTOCOL | 920 XM9_CRS_REVISION | NPORT_DMODE_W1); 921 pNewport->xmap9_rev = (char)('A'+(pNewportRegs->set.dcbdata0.bytes.b3 & 7)); 922 923 /* XXX: read possible modes from VC2 here */ 924 return TRUE; 925} 926 927 928/* map NewportRegs */ 929static Bool 930NewportMapRegs(ScrnInfoPtr pScrn) 931{ 932 NewportPtr pNewport = NEWPORTPTR(pScrn); 933 934#if defined(__NetBSD__) 935 pNewport->pNewportRegs = xf86MapVidMem(pScrn->scrnIndex, 936 VIDMEM_MMIO, NEWPORT_REGISTERS, sizeof(NewportRegs)); 937#else 938 pNewport->pNewportRegs = xf86MapVidMem(pScrn->scrnIndex, 939 VIDMEM_MMIO, 940 NEWPORT_BASE_ADDR0 + pNewport->busID * 941 NEWPORT_BASE_OFFSET, sizeof(NewportRegs)); 942#endif 943 if ( ! pNewport->pNewportRegs ) { 944 xf86Msg(X_ERROR, "can't map registers\n"); 945 return FALSE; 946 } 947 return TRUE; 948} 949 950/* unmap NewportRegs */ 951static void 952NewportUnmapRegs(ScrnInfoPtr pScrn) 953{ 954 NewportPtr pNewport = NEWPORTPTR(pScrn); 955 956 xf86UnMapVidMem( pScrn->scrnIndex, pNewport->pNewportRegs, 957 sizeof(NewportRegs)); 958 pNewport->pNewportRegs = NULL; 959} 960