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