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