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