cg14_driver.c revision 7a5333bc
1/* 2 * CG14 framebuffer driver. 3 * 4 * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com) 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 24#ifdef HAVE_CONFIG_H 25#include "config.h" 26#endif 27 28#include <sys/ioctl.h> 29#include <string.h> 30#include <sys/ioctl.h> 31 32#include "xf86.h" 33#include "xf86_OSproc.h" 34#include "mipointer.h" 35#include "micmap.h" 36 37#include "fb.h" 38#include "xf86cmap.h" 39#include "shadow.h" 40#include "cg14.h" 41 42#if 0 43#define static 44#endif 45 46#include "compat-api.h" 47 48static const OptionInfoRec * CG14AvailableOptions(int chipid, int busid); 49static void CG14Identify(int flags); 50static Bool CG14Probe(DriverPtr drv, int flags); 51static Bool CG14PreInit(ScrnInfoPtr pScrn, int flags); 52static Bool CG14ScreenInit(SCREEN_INIT_ARGS_DECL); 53static Bool CG14EnterVT(VT_FUNC_ARGS_DECL); 54static void CG14LeaveVT(VT_FUNC_ARGS_DECL); 55static Bool CG14CloseScreen(CLOSE_SCREEN_ARGS_DECL); 56static Bool CG14SaveScreen(ScreenPtr pScreen, int mode); 57static void CG14InitCplane24(ScrnInfoPtr pScrn); 58static void CG14ExitCplane24(ScrnInfoPtr pScrn); 59static void *CG14WindowLinear(ScreenPtr, CARD32, CARD32, int, CARD32 *, 60 void *); 61 62/* Required if the driver supports mode switching */ 63static Bool CG14SwitchMode(SWITCH_MODE_ARGS_DECL); 64/* Required if the driver supports moving the viewport */ 65static void CG14AdjustFrame(ADJUST_FRAME_ARGS_DECL); 66 67/* Optional functions */ 68static void CG14FreeScreen(FREE_SCREEN_ARGS_DECL); 69static ModeStatus CG14ValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, 70 Bool verbose, int flags); 71 72void CG14Sync(ScrnInfoPtr pScrn); 73 74#define CG14_VERSION 4000 75#define CG14_NAME "SUNCG14" 76#define CG14_DRIVER_NAME "suncg14" 77#define CG14_MAJOR_VERSION PACKAGE_VERSION_MAJOR 78#define CG14_MINOR_VERSION PACKAGE_VERSION_MINOR 79#define CG14_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL 80 81/* 82 * This contains the functions needed by the server after loading the driver 83 * module. It must be supplied, and gets passed back by the SetupProc 84 * function in the dynamic case. In the static case, a reference to this 85 * is compiled in, and this requires that the name of this DriverRec be 86 * an upper-case version of the driver name. 87 */ 88 89_X_EXPORT DriverRec SUNCG14 = { 90 CG14_VERSION, 91 CG14_DRIVER_NAME, 92 CG14Identify, 93 CG14Probe, 94 CG14AvailableOptions, 95 NULL, 96 0 97}; 98 99typedef enum { 100 OPTION_SHADOW_FB, 101 OPTION_HW_CURSOR, 102 OPTION_SW_CURSOR 103} CG14Opts; 104 105static const OptionInfoRec CG14Options[] = { 106 { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, TRUE}, 107 { -1, NULL, OPTV_NONE, {0}, FALSE } 108}; 109 110#ifdef XFree86LOADER 111 112static MODULESETUPPROTO(cg14Setup); 113 114static XF86ModuleVersionInfo suncg14VersRec = 115{ 116 "suncg14", 117 MODULEVENDORSTRING, 118 MODINFOSTRING1, 119 MODINFOSTRING2, 120 XORG_VERSION_CURRENT, 121 CG14_MAJOR_VERSION, CG14_MINOR_VERSION, CG14_PATCHLEVEL, 122 ABI_CLASS_VIDEODRV, 123 ABI_VIDEODRV_VERSION, 124 MOD_CLASS_VIDEODRV, 125 {0,0,0,0} 126}; 127 128_X_EXPORT XF86ModuleData suncg14ModuleData = { 129 &suncg14VersRec, 130 cg14Setup, 131 NULL 132}; 133 134pointer 135cg14Setup(pointer module, pointer opts, int *errmaj, int *errmin) 136{ 137 static Bool setupDone = FALSE; 138 139 if (!setupDone) { 140 setupDone = TRUE; 141 xf86AddDriver(&SUNCG14, module, 0); 142 143 /* 144 * Modules that this driver always requires can be loaded here 145 * by calling LoadSubModule(). 146 */ 147 148 /* 149 * The return value must be non-NULL on success even though there 150 * is no TearDownProc. 151 */ 152 return (pointer)TRUE; 153 } else { 154 if (errmaj) *errmaj = LDR_ONCEONLY; 155 return NULL; 156 } 157} 158 159#endif /* XFree86LOADER */ 160 161static Bool 162CG14GetRec(ScrnInfoPtr pScrn) 163{ 164 /* 165 * Allocate an Cg14Rec, and hook it into pScrn->driverPrivate. 166 * pScrn->driverPrivate is initialised to NULL, so we can check if 167 * the allocation has already been done. 168 */ 169 if (pScrn->driverPrivate != NULL) 170 return TRUE; 171 172 pScrn->driverPrivate = xnfcalloc(sizeof(Cg14Rec), 1); 173 return TRUE; 174} 175 176static void 177CG14FreeRec(ScrnInfoPtr pScrn) 178{ 179 Cg14Ptr pCg14; 180 181 if (pScrn->driverPrivate == NULL) 182 return; 183 184 pCg14 = GET_CG14_FROM_SCRN(pScrn); 185 186 free(pScrn->driverPrivate); 187 pScrn->driverPrivate = NULL; 188 189 return; 190} 191 192static const OptionInfoRec * 193CG14AvailableOptions(int chipid, int busid) 194{ 195 return CG14Options; 196} 197 198/* Mandatory */ 199static void 200CG14Identify(int flags) 201{ 202 xf86Msg(X_INFO, "%s: driver for CG14\n", CG14_NAME); 203} 204 205 206/* Mandatory */ 207static Bool 208CG14Probe(DriverPtr drv, int flags) 209{ 210 int i; 211 GDevPtr *devSections; 212 int *usedChips; 213 int numDevSections; 214 int numUsed; 215 Bool foundScreen = FALSE; 216 EntityInfoPtr pEnt; 217 218 /* 219 * The aim here is to find all cards that this driver can handle, 220 * and for the ones not already claimed by another driver, claim the 221 * slot, and allocate a ScrnInfoRec. 222 * 223 * This should be a minimal probe, and it should under no circumstances 224 * change the state of the hardware. Because a device is found, don't 225 * assume that it will be used. Don't do any initialisations other than 226 * the required ScrnInfoRec initialisations. Don't allocate any new 227 * data structures. 228 */ 229 230 /* 231 * Next we check, if there has been a chipset override in the config file. 232 * For this we must find out if there is an active device section which 233 * is relevant, i.e., which has no driver specified or has THIS driver 234 * specified. 235 */ 236 237 if ((numDevSections = xf86MatchDevice(CG14_DRIVER_NAME, 238 &devSections)) <= 0) { 239 /* 240 * There's no matching device section in the config file, so quit 241 * now. 242 */ 243 return FALSE; 244 } 245 246 /* 247 * We need to probe the hardware first. We then need to see how this 248 * fits in with what is given in the config file, and allow the config 249 * file info to override any contradictions. 250 */ 251 252 numUsed = xf86MatchSbusInstances(CG14_NAME, SBUS_DEVICE_CG14, 253 devSections, numDevSections, 254 drv, &usedChips); 255 256 free(devSections); 257 if (numUsed <= 0) 258 return FALSE; 259 260 if (flags & PROBE_DETECT) 261 foundScreen = TRUE; 262 else for (i = 0; i < numUsed; i++) { 263 pEnt = xf86GetEntityInfo(usedChips[i]); 264 265 /* 266 * Check that nothing else has claimed the slots. 267 */ 268 if(pEnt->active) { 269 ScrnInfoPtr pScrn; 270 271 /* Allocate a ScrnInfoRec and claim the slot */ 272 pScrn = xf86AllocateScreen(drv, 0); 273 274 /* Fill in what we can of the ScrnInfoRec */ 275 pScrn->driverVersion = CG14_VERSION; 276 pScrn->driverName = CG14_DRIVER_NAME; 277 pScrn->name = CG14_NAME; 278 pScrn->Probe = CG14Probe; 279 pScrn->PreInit = CG14PreInit; 280 pScrn->ScreenInit = CG14ScreenInit; 281 pScrn->SwitchMode = CG14SwitchMode; 282 pScrn->AdjustFrame = CG14AdjustFrame; 283 pScrn->EnterVT = CG14EnterVT; 284 pScrn->LeaveVT = CG14LeaveVT; 285 pScrn->FreeScreen = CG14FreeScreen; 286 pScrn->ValidMode = CG14ValidMode; 287 xf86AddEntityToScreen(pScrn, pEnt->index); 288 foundScreen = TRUE; 289 } 290 free(pEnt); 291 } 292 free(usedChips); 293 return foundScreen; 294} 295 296/* Mandatory */ 297static Bool 298CG14PreInit(ScrnInfoPtr pScrn, int flags) 299{ 300 Cg14Ptr pCg14; 301 sbusDevicePtr psdp = NULL; 302 int i, from; 303 304 if (flags & PROBE_DETECT) return FALSE; 305 306 /* 307 * Note: This function is only called once at server startup, and 308 * not at the start of each server generation. This means that 309 * only things that are persistent across server generations can 310 * be initialised here. xf86Screens[] is (pScrn is a pointer to one 311 * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex() 312 * are too, and should be used for data that must persist across 313 * server generations. 314 * 315 * Per-generation data should be allocated with 316 * AllocateScreenPrivateIndex() from the ScreenInit() function. 317 */ 318 319 /* Allocate the Cg14Rec driverPrivate */ 320 if (!CG14GetRec(pScrn)) { 321 return FALSE; 322 } 323 pCg14 = GET_CG14_FROM_SCRN(pScrn); 324 325 /* Set pScrn->monitor */ 326 pScrn->monitor = pScrn->confScreen->monitor; 327 328 /* This driver doesn't expect more than one entity per screen */ 329 if (pScrn->numEntities > 1) 330 return FALSE; 331 /* This is the general case */ 332 for (i = 0; i < pScrn->numEntities; i++) { 333 EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[i]); 334 335 /* CG14 is purely AFX, but we handle it like SBUS */ 336 if (pEnt->location.type == BUS_SBUS) { 337 psdp = xf86GetSbusInfoForEntity(pEnt->index); 338 pCg14->psdp = psdp; 339 } else 340 return FALSE; 341 } 342 if (psdp == NULL) 343 return FALSE; 344 345 /********************* 346 deal with depth 347 *********************/ 348 349 if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb|Support32bppFb)) 350 return FALSE; 351 /* Check that the returned depth is one we support */ 352 switch (pScrn->depth) { 353 case 32: 354 case 24: 355 /* OK */ 356 break; 357 default: 358 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 359 "Given depth (%d) is not supported by this driver\n", 360 pScrn->depth); 361 return FALSE; 362 } 363 364 /* Collect all of the relevant option flags (fill in pScrn->options) */ 365 xf86CollectOptions(pScrn, NULL); 366 /* Process the options */ 367 if (!(pCg14->Options = malloc(sizeof(CG14Options)))) 368 return FALSE; 369 memcpy(pCg14->Options, CG14Options, sizeof(CG14Options)); 370 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pCg14->Options); 371 pCg14->use_shadow = xf86ReturnOptValBool(pCg14->Options, OPTION_SHADOW_FB, 372 TRUE); 373 374 /* 375 * This must happen after pScrn->display has been set because 376 * xf86SetWeight references it. 377 */ 378 if (pScrn->depth > 8) { 379 rgb weight = {0, 0, 0}; 380 rgb mask = {0xff, 0xff00, 0xff0000}; 381 382 if (!xf86SetWeight(pScrn, weight, mask)) { 383 return FALSE; 384 } 385 } 386 387 if (!xf86SetDefaultVisual(pScrn, -1)) 388 return FALSE; 389 else if (pScrn->depth > 8) { 390 /* We don't currently support DirectColor */ 391 if (pScrn->defaultVisual != TrueColor) { 392 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" 393 " (%s) is not supported\n", 394 xf86GetVisualName(pScrn->defaultVisual)); 395 return FALSE; 396 } 397 } 398 399 /* 400 * The new cmap code requires this to be initialised. 401 */ 402 403 { 404 Gamma zeros = {0.0, 0.0, 0.0}; 405 406 if (!xf86SetGamma(pScrn, zeros)) { 407 return FALSE; 408 } 409 } 410 411 if (xf86LoadSubModule(pScrn, "fb") == NULL) { 412 CG14FreeRec(pScrn); 413 return FALSE; 414 } 415 416 if (pCg14->use_shadow) { 417 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using shadow framebuffer\n"); 418 if (xf86LoadSubModule(pScrn, "shadow") == NULL) { 419 CG14FreeRec(pScrn); 420 return FALSE; 421 } 422 } 423 424 from = X_DEFAULT; 425 pCg14->HWCursor = TRUE; 426 if (xf86GetOptValBool(pCg14->Options, OPTION_HW_CURSOR, &pCg14->HWCursor)) 427 from = X_CONFIG; 428 if (xf86ReturnOptValBool(pCg14->Options, OPTION_SW_CURSOR, FALSE)) { 429 from = X_CONFIG; 430 pCg14->HWCursor = FALSE; 431 } 432 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 433 pCg14->HWCursor ? "HW" : "SW"); 434 435 /********************* 436 set up clock and mode stuff 437 *********************/ 438 439 pScrn->progClock = TRUE; 440 441 if(pScrn->display->virtualX || pScrn->display->virtualY) { 442 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 443 "CG14 does not support a virtual desktop\n"); 444 pScrn->display->virtualX = 0; 445 pScrn->display->virtualY = 0; 446 } 447 448 xf86SbusUseBuiltinMode(pScrn, pCg14->psdp); 449 pScrn->currentMode = pScrn->modes; 450 pScrn->displayWidth = pScrn->virtualX; 451 452 /* Set display resolution */ 453 xf86SetDpi(pScrn, 0, 0); 454 455 return TRUE; 456} 457 458static Bool 459CG14CreateScreenResources(ScreenPtr pScreen) 460{ 461 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 462 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 463 PixmapPtr pPixmap; 464 Bool ret; 465 466 pScreen->CreateScreenResources = pCg14->CreateScreenResources; 467 ret = pScreen->CreateScreenResources(pScreen); 468 pScreen->CreateScreenResources = CG14CreateScreenResources; 469 470 if (!ret) 471 return FALSE; 472 473 pPixmap = pScreen->GetScreenPixmap(pScreen); 474 475 if (!shadowAdd(pScreen, pPixmap, shadowUpdatePackedWeak(), 476 CG14WindowLinear, 0, NULL)) { 477 return FALSE; 478 } 479 return TRUE; 480} 481 482 483static Bool 484CG14ShadowInit(ScreenPtr pScreen) 485{ 486 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 487 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 488 489 if (!shadowSetup(pScreen)) { 490 return FALSE; 491 } 492 493 pCg14->CreateScreenResources = pScreen->CreateScreenResources; 494 pScreen->CreateScreenResources = CG14CreateScreenResources; 495 496 return TRUE; 497} 498/* Mandatory */ 499 500/* This gets called at the start of each server generation */ 501 502static Bool 503CG14ScreenInit(SCREEN_INIT_ARGS_DECL) 504{ 505 ScrnInfoPtr pScrn; 506 Cg14Ptr pCg14; 507 VisualPtr visual; 508 int ret; 509 510 /* 511 * First get the ScrnInfoRec 512 */ 513 pScrn = xf86ScreenToScrn(pScreen); 514 515 pCg14 = GET_CG14_FROM_SCRN(pScrn); 516 517 /* Map the CG14 memory */ 518 pCg14->fb = xf86MapSbusMem (pCg14->psdp, CG14_BGR_VOFF, 4 * 519 (pCg14->psdp->width * pCg14->psdp->height)); 520 pCg14->x32 = xf86MapSbusMem (pCg14->psdp, CG14_X32_VOFF, 521 (pCg14->psdp->width * pCg14->psdp->height)); 522 pCg14->xlut = xf86MapSbusMem (pCg14->psdp, CG14_XLUT_VOFF, 4096); 523 pCg14->curs = xf86MapSbusMem (pCg14->psdp, CG14_CURSOR_VOFF, 4096); 524 525 pCg14->width = pCg14->psdp->width; 526 pCg14->height = pCg14->psdp->height; 527 528 if (! pCg14->fb || !pCg14->x32 || !pCg14->xlut || !pCg14->curs) { 529 xf86Msg(X_ERROR, 530 "can't mmap something: fd %08x x32 %08x xlut %08x cursor %08x\n", 531 (uint32_t)pCg14->fb, (uint32_t)pCg14->x32, (uint32_t)pCg14->xlut, 532 (uint32_t)pCg14->curs); 533 return FALSE; 534 } 535 536 /* Darken the screen for aesthetic reasons and set the viewport */ 537 CG14SaveScreen(pScreen, SCREEN_SAVER_ON); 538 539 /* 540 * The next step is to setup the screen's visuals, and initialise the 541 * framebuffer code. In cases where the framebuffer's default 542 * choices for things like visual layouts and bits per RGB are OK, 543 * this may be as simple as calling the framebuffer's ScreenInit() 544 * function. If not, the visuals will need to be setup before calling 545 * a fb ScreenInit() function and fixed up after. 546 */ 547 548 /* 549 * Reset visual list. 550 */ 551 miClearVisualTypes(); 552 553 /* Setup the visuals we support. */ 554 555 if (!miSetVisualTypes(pScrn->depth, TrueColorMask, 556 pScrn->rgbBits, pScrn->defaultVisual)) 557 return FALSE; 558 559 miSetPixmapDepths (); 560 561 if (pCg14->use_shadow) { 562 pCg14->shadow = xcalloc(1, pScrn->virtualX * pScrn->virtualY * 4); 563 564 if (!pCg14->shadow) { 565 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 566 "Failed to allocate shadow framebuffer\n"); 567 return FALSE; 568 } 569 } 570 571 /* 572 * Call the framebuffer layer's ScreenInit function, and fill in other 573 * pScreen fields. 574 */ 575 576 CG14InitCplane24(pScrn); 577 ret = fbScreenInit(pScreen, pCg14->use_shadow ? pCg14->shadow : pCg14->fb, 578 pScrn->virtualX, 579 pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, 580 pScrn->virtualX, pScrn->bitsPerPixel); 581 582 if (!ret) 583 return FALSE; 584 585#if 0 586 /* must be after RGB ordering fixed */ 587 fbPictureInit (pScreen, 0, 0); 588 589 if (pCg14->use_shadow && !CG14ShadowInit(pScreen)) { 590 xf86DrvMsg(scrnIndex, X_ERROR, 591 "shadow framebuffer initialization failed\n"); 592 return FALSE; 593 } 594 595 miInitializeBackingStore(pScreen); 596#endif 597 598 xf86SetBackingStore(pScreen); 599 xf86SetSilkenMouse(pScreen); 600 601 xf86SetBlackWhitePixels(pScreen); 602 603 if (pScrn->bitsPerPixel > 8) { 604 /* Fixup RGB ordering */ 605 visual = pScreen->visuals + pScreen->numVisuals; 606 while (--visual >= pScreen->visuals) { 607 if ((visual->class | DynamicClass) == DirectColor) { 608 visual->offsetRed = pScrn->offset.red; 609 visual->offsetGreen = pScrn->offset.green; 610 visual->offsetBlue = pScrn->offset.blue; 611 visual->redMask = pScrn->mask.red; 612 visual->greenMask = pScrn->mask.green; 613 visual->blueMask = pScrn->mask.blue; 614 } 615 } 616 } 617 618 /* Initialise cursor functions */ 619 miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); 620 621 /* check for hardware cursor support */ 622 if (pCg14->HWCursor) 623 CG14SetupCursor(pScreen); 624 625 /* Initialise default colourmap */ 626 if (!miCreateDefColormap(pScreen)) 627 return FALSE; 628 629 pCg14->CloseScreen = pScreen->CloseScreen; 630 pScreen->CloseScreen = CG14CloseScreen; 631 pScreen->SaveScreen = CG14SaveScreen; 632 633 /* Report any unused options (only for the first generation) */ 634 if (serverGeneration == 1) { 635 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 636 } 637 638 /* unblank the screen */ 639 CG14SaveScreen(pScreen, SCREEN_SAVER_OFF); 640 641 /* Done */ 642 return TRUE; 643} 644 645 646/* Usually mandatory */ 647static Bool 648CG14SwitchMode(SWITCH_MODE_ARGS_DECL) 649{ 650 xf86Msg(X_ERROR, "CG14SwitchMode\n"); 651 return TRUE; 652} 653 654 655/* 656 * This function is used to initialize the Start Address - the first 657 * displayed location in the video memory. 658 */ 659/* Usually mandatory */ 660static void 661CG14AdjustFrame(ADJUST_FRAME_ARGS_DECL) 662{ 663 /* we don't support virtual desktops */ 664 return; 665} 666 667/* 668 * This is called when VT switching back to the X server. Its job is 669 * to reinitialise the video mode. 670 */ 671 672/* Mandatory */ 673static Bool 674CG14EnterVT(VT_FUNC_ARGS_DECL) 675{ 676 SCRN_INFO_PTR(arg); 677 678 CG14InitCplane24 (pScrn); 679 return TRUE; 680} 681 682 683/* 684 * This is called when VT switching away from the X server. 685 */ 686 687/* Mandatory */ 688static void 689CG14LeaveVT(VT_FUNC_ARGS_DECL) 690{ 691 SCRN_INFO_PTR(arg); 692 693 CG14ExitCplane24 (pScrn); 694 return; 695} 696 697 698/* 699 * This is called at the end of each server generation. It restores the 700 * original (text) mode. It should really also unmap the video memory too. 701 */ 702 703/* Mandatory */ 704static Bool 705CG14CloseScreen(CLOSE_SCREEN_ARGS_DECL) 706{ 707 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 708 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 709 PixmapPtr pPixmap; 710 711 if (pCg14->use_shadow) { 712 713 pPixmap = pScreen->GetScreenPixmap(pScreen); 714 shadowRemove(pScreen, pPixmap); 715 pCg14->use_shadow = FALSE; 716 } 717 718 pScrn->vtSema = FALSE; 719 CG14ExitCplane24 (pScrn); 720 xf86UnmapSbusMem(pCg14->psdp, pCg14->fb, 721 (pCg14->psdp->width * pCg14->psdp->height * 4)); 722 xf86UnmapSbusMem(pCg14->psdp, pCg14->x32, 723 (pCg14->psdp->width * pCg14->psdp->height)); 724 xf86UnmapSbusMem(pCg14->psdp, pCg14->xlut, 4096); 725 xf86UnmapSbusMem(pCg14->psdp, pCg14->curs, 4096); 726 727 pScreen->CloseScreen = pCg14->CloseScreen; 728 return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS); 729} 730 731static void * 732CG14WindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, 733 CARD32 *size, void *closure) 734{ 735 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 736 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 737 738 *size = pCg14->width << 2; 739 return (CARD8 *)pCg14->fb + row * (pCg14->width << 2) + offset; 740} 741 742/* Free up any per-generation data structures */ 743 744/* Optional */ 745static void 746CG14FreeScreen(FREE_SCREEN_ARGS_DECL) 747{ 748 SCRN_INFO_PTR(arg); 749 CG14FreeRec(pScrn); 750} 751 752 753/* Checks if a mode is suitable for the selected chipset. */ 754 755/* Optional */ 756static ModeStatus 757CG14ValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) 758{ 759 if (mode->Flags & V_INTERLACE) 760 return(MODE_BAD); 761 762 return(MODE_OK); 763} 764 765/* Do screen blanking */ 766 767/* Mandatory */ 768static Bool 769CG14SaveScreen(ScreenPtr pScreen, int mode) 770{ 771 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 772 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 773 int state; 774 switch(mode) { 775 case SCREEN_SAVER_ON: 776 case SCREEN_SAVER_CYCLE: 777 state = FBVIDEO_OFF; 778 ioctl(pCg14->psdp->fd, FBIOSVIDEO, &state); 779 break; 780 case SCREEN_SAVER_OFF: 781 case SCREEN_SAVER_FORCER: 782 state = FBVIDEO_ON; 783 ioctl(pCg14->psdp->fd, FBIOSVIDEO, &state); 784 break; 785 default: 786 return FALSE; 787 } 788 return TRUE; 789} 790 791/* 792 * This is the implementation of the Sync() function. 793 */ 794void 795CG14Sync(ScrnInfoPtr pScrn) 796{ 797 return; 798} 799 800/* 801 * This initializes the card for 24 bit mode. 802 */ 803static void 804CG14InitCplane24(ScrnInfoPtr pScrn) 805{ 806 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 807 int size, bpp; 808 809 size = pScrn->virtualX * pScrn->virtualY; 810 bpp = 32; 811 ioctl (pCg14->psdp->fd, CG14_SET_PIXELMODE, &bpp); 812 memset (pCg14->fb, 0, size * 4); 813 memset (pCg14->x32, 0, size); 814 memset (pCg14->xlut, 0, 0x200); 815} 816 817/* 818 * This initializes the card for 8 bit mode. 819 */ 820static void 821CG14ExitCplane24(ScrnInfoPtr pScrn) 822{ 823 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 824 int bpp = 8; 825 826 ioctl (pCg14->psdp->fd, CG14_SET_PIXELMODE, &bpp); 827} 828