ag10e_driver.c revision 98bb403a
1/* 2 * Fujitsu AG-10e framebuffer driver. 3 * 4 * Copyright (C) 2007 Michael Lorenz 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 */ 23/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/suncg6/cg6_driver.c,v 1.12 2005/02/18 02:55:09 dawes Exp $ */ 24 25/* need this for PRIxPTR macro */ 26 27#ifdef HAVE_CONFIG_H 28#include "config.h" 29#endif 30 31#include <fcntl.h> 32#include <sys/time.h> 33#include <sys/types.h> 34#include <dev/sun/fbio.h> 35#include <dev/wscons/wsconsio.h> 36 37#include <machine/int_fmtio.h> 38#include "xf86.h" 39#include "xf86_OSproc.h" 40#include "xf86_ansic.h" 41#include "xf86Version.h" 42#include "mipointer.h" 43#include "mibstore.h" 44#include "micmap.h" 45 46#include "fb.h" 47#include "xf86cmap.h" 48#include "ag10e.h" 49#include "xf86sbusBus.h" 50 51static const OptionInfoRec * AG10EAvailableOptions(int chipid, int busid); 52static void AG10EIdentify(int flags); 53static Bool AG10EProbe(DriverPtr drv, int flags); 54static Bool AG10EPreInit(ScrnInfoPtr pScrn, int flags); 55static Bool AG10EScreenInit(int Index, ScreenPtr pScreen, int argc, 56 char **argv); 57static Bool AG10EEnterVT(int scrnIndex, int flags); 58static void AG10ELeaveVT(int scrnIndex, int flags); 59static Bool AG10ECloseScreen(int scrnIndex, ScreenPtr pScreen); 60static Bool AG10ESaveScreen(ScreenPtr pScreen, int mode); 61 62/* Required if the driver supports mode switching */ 63static Bool AG10ESwitchMode(int scrnIndex, DisplayModePtr mode, int flags); 64/* Required if the driver supports moving the viewport */ 65static void AG10EAdjustFrame(int scrnIndex, int x, int y, int flags); 66 67/* Optional functions */ 68static void AG10EFreeScreen(int scrnIndex, int flags); 69static ModeStatus AG10EValidMode(int scrnIndex, DisplayModePtr mode, 70 Bool verbose, int flags); 71 72#define VERSION 4000 73#define AG10E_NAME "AG10E" 74#define AG10E_DRIVER_NAME "ag10e" 75#define AG10E_MAJOR_VERSION 1 76#define AG10E_MINOR_VERSION 0 77#define AG10E_PATCHLEVEL 0 78 79/* 80 * This contains the functions needed by the server after loading the driver 81 * module. It must be supplied, and gets passed back by the SetupProc 82 * function in the dynamic case. In the static case, a reference to this 83 * is compiled in, and this requires that the name of this DriverRec be 84 * an upper-case version of the driver name. 85 */ 86 87DriverRec AG10E = { 88 VERSION, 89 AG10E_DRIVER_NAME, 90 AG10EIdentify, 91 AG10EProbe, 92 AG10EAvailableOptions, 93 NULL, 94 0 95}; 96 97typedef enum { 98 OPTION_SW_CURSOR, 99 OPTION_HW_CURSOR, 100 OPTION_NOACCEL 101} AG10EOpts; 102 103static const OptionInfoRec AG10EOptions[] = { 104 { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, 105 { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, 106 { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 107 { -1, NULL, OPTV_NONE, {0}, FALSE } 108}; 109 110static const char *xaaSymbols[] = 111{ 112 "XAACreateInfoRec", 113 "XAADestroyInfoRec", 114 "XAAInit", 115 NULL 116}; 117 118#ifdef XFree86LOADER 119 120static MODULESETUPPROTO(AG10ESetup); 121 122static XF86ModuleVersionInfo AG10EVersRec = 123{ 124 "ag10e", 125 MODULEVENDORSTRING, 126 MODINFOSTRING1, 127 MODINFOSTRING2, 128 XORG_VERSION_CURRENT, 129 AG10E_MAJOR_VERSION, AG10E_MINOR_VERSION, AG10E_PATCHLEVEL, 130 ABI_CLASS_VIDEODRV, 131 ABI_VIDEODRV_VERSION, 132 MOD_CLASS_VIDEODRV, 133 {0,0,0,0} 134}; 135 136_X_EXPORT XF86ModuleData ag10eModuleData = { &AG10EVersRec, AG10ESetup, NULL }; 137 138static pointer 139AG10ESetup(pointer module, pointer opts, int *errmaj, int *errmin) 140{ 141 static Bool setupDone = FALSE; 142 143 if (!setupDone) { 144 setupDone = TRUE; 145 xf86AddDriver(&AG10E, module, 0); 146 147 /* 148 * Modules that this driver always requires can be loaded here 149 * by calling LoadSubModule(). 150 */ 151 LoaderRefSymLists(xaaSymbols, NULL); 152 153 /* 154 * The return value must be non-NULL on success even though there 155 * is no TearDownProc. 156 */ 157 return (pointer)TRUE; 158 } else { 159 if (errmaj) *errmaj = LDR_ONCEONLY; 160 return NULL; 161 } 162} 163 164#endif /* XFree86LOADER */ 165 166static Bool 167AG10EGetRec(ScrnInfoPtr pScrn) 168{ 169 /* 170 * Allocate an AG10ERec, and hook it into pScrn->driverPrivate. 171 * pScrn->driverPrivate is initialised to NULL, so we can check if 172 * the allocation has already been done. 173 */ 174 if (pScrn->driverPrivate != NULL) 175 return TRUE; 176 177 pScrn->driverPrivate = xnfcalloc(sizeof(AG10ERec), 1); 178 return TRUE; 179} 180 181static void 182AG10EFreeRec(ScrnInfoPtr pScrn) 183{ 184 AG10EPtr pAG10E; 185 186 if (pScrn->driverPrivate == NULL) 187 return; 188 189 pAG10E = GET_AG10E_FROM_SCRN(pScrn); 190 191 xfree(pScrn->driverPrivate); 192 pScrn->driverPrivate = NULL; 193 194 return; 195} 196 197static const OptionInfoRec * 198AG10EAvailableOptions(int chipid, int busid) 199{ 200 return AG10EOptions; 201} 202 203/* Mandatory */ 204static void 205AG10EIdentify(int flags) 206{ 207 xf86Msg(X_INFO, "%s: driver for Fujitsu AG-10e\n", AG10E_NAME); 208} 209 210 211/* Mandatory */ 212static Bool 213AG10EProbe(DriverPtr drv, int flags) 214{ 215 int i; 216 GDevPtr *devSections; 217 int *usedChips; 218 int numDevSections; 219 int numUsed; 220 Bool foundScreen = FALSE; 221 EntityInfoPtr pEnt; 222 223 /* 224 * The aim here is to find all cards that this driver can handle, 225 * and for the ones not already claimed by another driver, claim the 226 * slot, and allocate a ScrnInfoRec. 227 * 228 * This should be a minimal probe, and it should under no circumstances 229 * change the state of the hardware. Because a device is found, don't 230 * assume that it will be used. Don't do any initialisations other than 231 * the required ScrnInfoRec initialisations. Don't allocate any new 232 * data structures. 233 */ 234 235 /* 236 * Next we check, if there has been a chipset override in the config file. 237 * For this we must find out if there is an active device section which 238 * is relevant, i.e., which has no driver specified or has THIS driver 239 * specified. 240 */ 241 242 if ((numDevSections = xf86MatchDevice(AG10E_DRIVER_NAME, 243 &devSections)) <= 0) { 244 /* 245 * There's no matching device section in the config file, so quit 246 * now. 247 */ 248 return FALSE; 249 } 250 251 /* 252 * We need to probe the hardware first. We then need to see how this 253 * fits in with what is given in the config file, and allow the config 254 * file info to override any contradictions. 255 */ 256 257 numUsed = xf86MatchSbusInstances(AG10E_NAME, SBUS_DEVICE_AG10E, 258 devSections, numDevSections, 259 drv, &usedChips); 260 261 xfree(devSections); 262 if (numUsed <= 0) 263 return FALSE; 264 265 if (flags & PROBE_DETECT) 266 foundScreen = TRUE; 267 else for (i = 0; i < numUsed; i++) { 268 pEnt = xf86GetEntityInfo(usedChips[i]); 269 270 /* 271 * Check that nothing else has claimed the slots. 272 */ 273 if(pEnt->active) { 274 ScrnInfoPtr pScrn; 275 276 /* Allocate a ScrnInfoRec and claim the slot */ 277 pScrn = xf86AllocateScreen(drv, 0); 278 279 /* Fill in what we can of the ScrnInfoRec */ 280 pScrn->driverVersion = VERSION; 281 pScrn->driverName = AG10E_DRIVER_NAME; 282 pScrn->name = AG10E_NAME; 283 pScrn->Probe = AG10EProbe; 284 pScrn->PreInit = AG10EPreInit; 285 pScrn->ScreenInit = AG10EScreenInit; 286 pScrn->SwitchMode = AG10ESwitchMode; 287 pScrn->AdjustFrame = AG10EAdjustFrame; 288 pScrn->EnterVT = AG10EEnterVT; 289 pScrn->LeaveVT = AG10ELeaveVT; 290 pScrn->FreeScreen = AG10EFreeScreen; 291 pScrn->ValidMode = AG10EValidMode; 292 xf86AddEntityToScreen(pScrn, pEnt->index); 293 foundScreen = TRUE; 294 } 295 xfree(pEnt); 296 } 297 xfree(usedChips); 298 return foundScreen; 299} 300 301/* Mandatory */ 302static Bool 303AG10EPreInit(ScrnInfoPtr pScrn, int flags) 304{ 305 AG10EPtr pAG10E; 306 sbusDevicePtr psdp; 307 rgb defaultWeight = {0, 0, 0}; 308 MessageType from; 309 int i; 310 311 if (flags & PROBE_DETECT) return FALSE; 312 313 /* 314 * Note: This function is only called once at server startup, and 315 * not at the start of each server generation. This means that 316 * only things that are persistent across server generations can 317 * be initialised here. xf86Screens[] is (pScrn is a pointer to one 318 * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex() 319 * are too, and should be used for data that must persist across 320 * server generations. 321 * 322 * Per-generation data should be allocated with 323 * AllocateScreenPrivateIndex() from the ScreenInit() function. 324 */ 325 326 /* Allocate the AG10ERec driverPrivate */ 327 if (!AG10EGetRec(pScrn)) { 328 return FALSE; 329 } 330 pAG10E = GET_AG10E_FROM_SCRN(pScrn); 331 332 /* Set pScrn->monitor */ 333 pScrn->monitor = pScrn->confScreen->monitor; 334 335 /* This driver doesn't expect more than one entity per screen */ 336 if (pScrn->numEntities > 1) 337 return FALSE; 338 /* This is the general case */ 339 for (i = 0; i < pScrn->numEntities; i++) { 340 EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[i]); 341 342 /* AG10E is purely SBUS */ 343 if (pEnt->location.type == BUS_SBUS) { 344 psdp = xf86GetSbusInfoForEntity(pEnt->index); 345 pAG10E->psdp = psdp; 346 } else 347 return FALSE; 348 } 349 350 /********************* 351 deal with depth 352 *********************/ 353 354 if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) { 355 return FALSE; 356 } else { 357 /* Check that the returned depth is one we support */ 358 switch (pScrn->depth) { 359 case 24: 360 /* OK */ 361 break; 362 default: 363 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 364 "Given depth (%d) is not supported by this driver\n", 365 pScrn->depth); 366 return FALSE; 367 } 368 } 369 370 /* Collect all of the relevant option flags (fill in pScrn->options) */ 371 xf86CollectOptions(pScrn, NULL); 372 /* Process the options */ 373 if (!(pAG10E->Options = xalloc(sizeof(AG10EOptions)))) 374 return FALSE; 375 memcpy(pAG10E->Options, AG10EOptions, sizeof(AG10EOptions)); 376 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pAG10E->Options); 377 378 /* 379 * The new cmap code requires this to be initialised. 380 * this card supports HW gamma correction with 10 bit resolution - maybe 381 * we should figure out how to use it 382 */ 383 384 { 385 Gamma zeros = {0.0, 0.0, 0.0}; 386 387 if (!xf86SetGamma(pScrn, zeros)) { 388 return FALSE; 389 } 390 } 391 392 from = X_DEFAULT; 393 if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) 394 return FALSE; 395 396 if (!xf86SetDefaultVisual(pScrn, -1)) 397 return FALSE; 398 399 /* determine whether we use hardware or software cursor */ 400 401 pAG10E->HWCursor = TRUE; 402 if (xf86GetOptValBool(pAG10E->Options, OPTION_HW_CURSOR, &pAG10E->HWCursor)) 403 from = X_CONFIG; 404 if (xf86ReturnOptValBool(pAG10E->Options, OPTION_SW_CURSOR, FALSE)) { 405 from = X_CONFIG; 406 pAG10E->HWCursor = FALSE; 407 } 408 409 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 410 pAG10E->HWCursor ? "HW" : "SW"); 411 412 if (xf86ReturnOptValBool(pAG10E->Options, OPTION_NOACCEL, FALSE)) { 413 pAG10E->NoAccel = TRUE; 414 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); 415 } 416 417 if (xf86LoadSubModule(pScrn, "fb") == NULL) { 418 AG10EFreeRec(pScrn); 419 return FALSE; 420 } 421 422 if (pAG10E->HWCursor && xf86LoadSubModule(pScrn, "ramdac") == NULL) { 423 AG10EFreeRec(pScrn); 424 return FALSE; 425 } 426 427 if (pAG10E->HWCursor && xf86LoadSubModule(pScrn, "xaa") == NULL) { 428 AG10EFreeRec(pScrn); 429 return FALSE; 430 } 431 xf86LoaderReqSymLists(xaaSymbols, NULL); 432 433 /********************* 434 set up clock and mode stuff 435 *********************/ 436 437 pScrn->progClock = TRUE; 438 439 if(pScrn->display->virtualX || pScrn->display->virtualY) { 440 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 441 "AG10E does not support a virtual desktop\n"); 442 pScrn->display->virtualX = 0; 443 pScrn->display->virtualY = 0; 444 } 445 446 xf86SbusUseBuiltinMode(pScrn, pAG10E->psdp); 447 pScrn->currentMode = pScrn->modes; 448 pScrn->displayWidth = pScrn->virtualX; 449 450 /* Set display resolution */ 451 xf86SetDpi(pScrn, 0, 0); 452 453 return TRUE; 454} 455 456/* Mandatory */ 457 458/* This gets called at the start of each server generation */ 459 460static Bool 461AG10EScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 462{ 463 ScrnInfoPtr pScrn; 464 AG10EPtr pAG10E; 465 struct fbtype fb; 466 sbusDevicePtr psdp; 467 VisualPtr visual; 468 int ret; 469 470 pScrn = xf86Screens[pScreen->myNum]; 471 pAG10E = GET_AG10E_FROM_SCRN(pScrn); 472 psdp = pAG10E->psdp; 473 474 /* 475 * for some idiotic reason we need to check if the file descriptor is 476 * really open here 477 */ 478 if (psdp->fd == -1) { 479 psdp->fd = open(psdp->device, O_RDWR); 480 if (psdp->fd == -1) 481 return FALSE; 482 } 483 484 /* figure out how much VRAM we can map */ 485 if ((ret = ioctl(pAG10E->psdp->fd, FBIOGTYPE, &fb)) != 0) { 486 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 487 "ioctl(FBIOGTYPE) failed with %d\n", ret); 488 return FALSE; 489 } 490 pAG10E->vidmem = fb.fb_size; 491 492 /* Map AG10E memory areas */ 493 494 pAG10E->regs = xf86MapSbusMem(psdp, pAG10E->vidmem, 0x10000); 495 pAG10E->fb = xf86MapSbusMem(psdp, 0, pAG10E->vidmem); 496 497 if (pAG10E->fb != NULL) { 498 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "mapped %d KB video RAM\n", 499 pAG10E->vidmem >> 10); 500 } 501 502 if (!pAG10E->regs || !pAG10E->fb) { 503 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 504 "xf86MapSbusMem failed regs:%" PRIxPTR " fb:%" PRIxPTR "\n", 505 pAG10E->regs, pAG10E->fb); 506 507 if (pAG10E->fb) { 508 xf86UnmapSbusMem(psdp, pAG10E->fb, sizeof(*pAG10E->fb)); 509 pAG10E->fb = NULL; 510 } 511 512 if (pAG10E->regs) { 513 xf86UnmapSbusMem(psdp, pAG10E->regs, sizeof(*pAG10E->regs)); 514 pAG10E->regs = NULL; 515 } 516 517 return FALSE; 518 } 519 pAG10E->IOOffset = 0; 520 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "vram: %d\n", 521 (1 << ((GLINT_READ_REG(FBMemoryCtl) & 0xE0000000)>>29)) * 1024); 522 523 /* 524 * The next step is to setup the screen's visuals, and initialise the 525 * framebuffer code. In cases where the framebuffer's default 526 * choices for things like visual layouts and bits per RGB are OK, 527 * this may be as simple as calling the framebuffer's ScreenInit() 528 * function. If not, the visuals will need to be setup before calling 529 * a fb ScreenInit() function and fixed up after. 530 */ 531 532 /* 533 * Reset visual list. 534 */ 535 miClearVisualTypes(); 536 537 /* Setup the visuals we support. */ 538 if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), 539 pScrn->rgbBits, pScrn->defaultVisual)) 540 return FALSE; 541 542 miSetPixmapDepths(); 543 544 /* 545 * Call the framebuffer layer's ScreenInit function, and fill in other 546 * pScreen fields. 547 */ 548 549 ret = fbScreenInit(pScreen, pAG10E->fb, pScrn->virtualX, 550 pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, 551 pScrn->virtualX, pScrn->bitsPerPixel); 552 /*if (!ret) 553 return FALSE;*/ 554 555 pAG10E->width=pScrn->virtualX; 556 pAG10E->height=pScrn->virtualY; 557 pAG10E->maxheight=(pAG10E->vidmem / (pAG10E->width << 2)) & 0xffff; 558 559 fbPictureInit(pScreen, 0, 0); 560 561 visual = pScreen->visuals + pScreen->numVisuals; 562 while (--visual >= pScreen->visuals) { 563 if ((visual->class | DynamicClass) == DirectColor) { 564 visual->offsetRed = pScrn->offset.red; 565 visual->offsetGreen = pScrn->offset.green; 566 visual->offsetBlue = pScrn->offset.blue; 567 visual->redMask = pScrn->mask.red; 568 visual->greenMask = pScrn->mask.green; 569 visual->blueMask = pScrn->mask.blue; 570 } 571 } 572 573 miInitializeBackingStore(pScreen); 574 xf86SetBackingStore(pScreen); 575 xf86SetSilkenMouse(pScreen); 576 577 xf86SetBlackWhitePixels(pScreen); 578 579 if (!pAG10E->NoAccel) { 580 if (!AG10EAccelInit(pScreen)) 581 return FALSE; 582 xf86Msg(X_INFO, "%s: Using acceleration\n", pAG10E->psdp->device); 583 } 584 /* setup DGA */ 585 AG10EDGAInit(pScreen); 586 587 /* Initialise cursor functions */ 588 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 589 590 /* Initialize HW cursor layer. 591 Must follow software cursor initialization*/ 592 if (pAG10E->HWCursor) { 593 if(!AG10EHWCursorInit(pScreen)) { 594 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 595 "Hardware cursor initialization failed\n"); 596 return(FALSE); 597 } 598 xf86SbusHideOsHwCursor(psdp); 599 } 600 601 /* Initialise default colourmap */ 602 if (!miCreateDefColormap(pScreen)) 603 return FALSE; 604 605 if(!xf86SbusHandleColormaps(pScreen, psdp)) 606 return FALSE; 607 608 pAG10E->CloseScreen = pScreen->CloseScreen; 609 pScreen->CloseScreen = AG10ECloseScreen; 610 pScreen->SaveScreen = AG10ESaveScreen; 611 612 /* Report any unused options (only for the first generation) */ 613 if (serverGeneration == 1) { 614 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 615 } 616 617 /* unblank the screen */ 618 AG10ESaveScreen(pScreen, SCREEN_SAVER_OFF); 619 620 /* Done */ 621 return TRUE; 622} 623 624 625/* Usually mandatory */ 626static Bool 627AG10ESwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 628{ 629 return TRUE; 630} 631 632 633/* 634 * This function is used to initialize the Start Address - the first 635 * displayed location in the video memory. 636 */ 637/* Usually mandatory */ 638static void 639AG10EAdjustFrame(int scrnIndex, int x, int y, int flags) 640{ 641 /* we don't support virtual desktops */ 642 return; 643} 644 645/* 646 * This is called when VT switching back to the X server. Its job is 647 * to reinitialise the video mode. 648 */ 649 650/* Mandatory */ 651static Bool 652AG10EEnterVT(int scrnIndex, int flags) 653{ 654 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 655 AG10EPtr pAG10E = GET_AG10E_FROM_SCRN(pScrn); 656 657 if (pAG10E->HWCursor) { 658 xf86SbusHideOsHwCursor(pAG10E->psdp); 659 } 660 return TRUE; 661} 662 663 664/* 665 * This is called when VT switching away from the X server. 666 */ 667 668/* Mandatory */ 669static void 670AG10ELeaveVT(int scrnIndex, int flags) 671{ 672 return; 673} 674 675 676/* 677 * This is called at the end of each server generation. It restores the 678 * original (text) mode. It should really also unmap the video memory too. 679 */ 680 681/* Mandatory */ 682static Bool 683AG10ECloseScreen(int scrnIndex, ScreenPtr pScreen) 684{ 685 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 686 AG10EPtr pAG10E = GET_AG10E_FROM_SCRN(pScrn); 687 sbusDevicePtr psdp = pAG10E->psdp; 688 689 pScrn->vtSema = FALSE; 690 691 xf86UnmapSbusMem(psdp, pAG10E->regs, 0x10000); 692 xf86UnmapSbusMem(psdp, pAG10E->fb, pAG10E->vidmem); 693 694 if (pAG10E->HWCursor) 695 xf86SbusHideOsHwCursor(psdp); 696 697 pScreen->CloseScreen = pAG10E->CloseScreen; 698 return (*pScreen->CloseScreen)(scrnIndex, pScreen); 699 return FALSE; 700} 701 702 703/* Free up any per-generation data structures */ 704 705/* Optional */ 706static void 707AG10EFreeScreen(int scrnIndex, int flags) 708{ 709 AG10EFreeRec(xf86Screens[scrnIndex]); 710} 711 712 713/* Checks if a mode is suitable for the selected chipset. */ 714 715/* Optional */ 716static ModeStatus 717AG10EValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) 718{ 719 if (mode->Flags & V_INTERLACE) 720 return(MODE_NO_INTERLACE); 721 722 return(MODE_OK); 723} 724 725/* Do screen blanking */ 726 727/* Mandatory */ 728static Bool 729AG10ESaveScreen(ScreenPtr pScreen, int mode) 730{ 731 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 732 AG10EPtr pAG10E = GET_AG10E_FROM_SCRN(pScrn); 733 int flag; 734 735 switch (mode) 736 { 737 case SCREEN_SAVER_ON: 738 case SCREEN_SAVER_CYCLE: 739 flag = 0; 740 ioctl(pAG10E->psdp->fd, FBIOSVIDEO, &flag); 741 break; 742 case SCREEN_SAVER_OFF: 743 case SCREEN_SAVER_FORCER: 744 flag = 1; 745 ioctl(pAG10E->psdp->fd, FBIOSVIDEO, &flag); 746 break; 747 default: 748 return FALSE; 749 } 750 751 return TRUE; 752} 753