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