ngle_driver.c revision f8e8ce30
1/* $NetBSD: ngle_driver.c,v 1.6 2024/10/27 11:09:37 macallan Exp $ */ 2/* 3 * Copyright (c) 2024 Michael Lorenz 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * - Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * - Redistributions in binary form must reproduce the above 13 * copyright notice, this list of conditions and the following 14 * disclaimer in the documentation and/or other materials provided 15 * with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 * 30 */ 31 32/* a driver for HP's NGLE family of graphics chips */ 33 34#ifdef HAVE_CONFIG_H 35#include "config.h" 36#endif 37#include <sys/types.h> 38#include <dev/ic/stireg.h> 39 40#include <fcntl.h> 41#include <errno.h> 42#include <sys/time.h> 43#include <sys/mman.h> 44#include <sys/ioctl.h> 45#include <dev/wscons/wsconsio.h> 46 47/* all driver need this */ 48#include "xf86.h" 49#include "xf86_OSproc.h" 50 51#include "mipointer.h" 52#include "micmap.h" 53#include "colormapst.h" 54#include "xf86cmap.h" 55#ifdef XvExtension 56#include "xf86xv.h" 57#endif 58 59/* for visuals */ 60#include "fb.h" 61 62#include "ngle.h" 63 64/* #include "wsconsio.h" */ 65 66#define NGLE_DEFAULT_DEV "/dev/ttyE0" 67 68static pointer NGLESetup(pointer, pointer, int *, int *); 69static Bool NGLEGetRec(ScrnInfoPtr); 70static void NGLEFreeRec(ScrnInfoPtr); 71static const OptionInfoRec * NGLEAvailableOptions(int, int); 72static void NGLEIdentify(int); 73static Bool NGLEProbe(DriverPtr, int); 74static Bool NGLEPreInit(ScrnInfoPtr, int); 75static Bool NGLEScreenInit(SCREEN_INIT_ARGS_DECL); 76static Bool NGLECloseScreen(CLOSE_SCREEN_ARGS_DECL); 77static Bool NGLEEnterVT(VT_FUNC_ARGS_DECL); 78static void NGLELeaveVT(VT_FUNC_ARGS_DECL); 79static Bool NGLESwitchMode(SWITCH_MODE_ARGS_DECL); 80static int NGLEValidMode(SCRN_ARG_TYPE, DisplayModePtr, Bool, int); 81static void NGLELoadPalette(ScrnInfoPtr, int, int *, LOCO *, VisualPtr); 82static Bool NGLESaveScreen(ScreenPtr, int); 83static void NGLESave(ScrnInfoPtr); 84static void NGLERestore(ScrnInfoPtr); 85 86/* helper functions */ 87static int ngle_open(const char *); 88static pointer ngle_mmap(size_t, off_t, int, int); 89 90#define VERSION 4000 91#define NGLE_NAME "ngle" 92#define NGLE_DRIVER_NAME "ngle" 93#define NGLE_MAJOR_VERSION 0 94#define NGLE_MINOR_VERSION 1 95 96DriverRec NGLE = { 97 VERSION, 98 NGLE_DRIVER_NAME, 99 NGLEIdentify, 100 NGLEProbe, 101 NGLEAvailableOptions, 102 NULL, 103 0 104}; 105 106/* Supported "chipsets" */ 107static SymTabRec NGLEChipsets[] = { 108 { STI_DD_EG, "Visualize EG" }, 109 { STI_DD_HCRX, "HCRX" }, 110 { -1, NULL } 111}; 112 113/* Supported options */ 114typedef enum { 115 OPTION_HW_CURSOR, 116 OPTION_SW_CURSOR 117} NGLEOpts; 118 119static const OptionInfoRec NGLEOptions[] = { 120 { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, 121 { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, 122 { -1, NULL, OPTV_NONE, {0}, FALSE} 123}; 124 125static XF86ModuleVersionInfo NGLEVersRec = { 126 "ngle", 127 "The NetBSD Foundation", 128 MODINFOSTRING1, 129 MODINFOSTRING2, 130 XORG_VERSION_CURRENT, 131 NGLE_MAJOR_VERSION, NGLE_MINOR_VERSION, 0, 132 ABI_CLASS_VIDEODRV, 133 ABI_VIDEODRV_VERSION, 134 NULL, 135 {0, 0, 0, 0} 136}; 137 138_X_EXPORT XF86ModuleData ngleModuleData = { &NGLEVersRec, NGLESetup, NULL }; 139 140static pointer 141NGLESetup(pointer module, pointer opts, int *errmaj, int *errmin) 142{ 143 static Bool setupDone = FALSE; 144 const char *osname; 145 146 if (!setupDone) { 147 setupDone = TRUE; 148 xf86AddDriver(&NGLE, module, 0); 149 return (pointer)1; 150 } else { 151 if (errmaj != NULL) 152 *errmaj = LDR_ONCEONLY; 153 return NULL; 154 } 155} 156 157static Bool 158NGLEGetRec(ScrnInfoPtr pScrn) 159{ 160 161 if (pScrn->driverPrivate != NULL) 162 return TRUE; 163 164 pScrn->driverPrivate = xnfcalloc(sizeof(NGLERec), 1); 165 return TRUE; 166} 167 168static void 169NGLEFreeRec(ScrnInfoPtr pScrn) 170{ 171 172 if (pScrn->driverPrivate == NULL) 173 return; 174 free(pScrn->driverPrivate); 175 pScrn->driverPrivate = NULL; 176} 177 178static const OptionInfoRec * 179NGLEAvailableOptions(int chipid, int busid) 180{ 181 return NGLEOptions; 182} 183 184static void 185NGLEIdentify(int flags) 186{ 187 xf86PrintChipsets(NGLE_NAME, "driver for NGLE framebuffers", 188 NGLEChipsets); 189} 190 191 192#define priv_open_device(n) open(n,O_RDWR|O_NONBLOCK|O_EXCL) 193 194/* Open the framebuffer device */ 195static int 196ngle_open(const char *dev) 197{ 198 int fd = -1; 199 200 /* try argument from XF86Config first */ 201 if (dev == NULL || ((fd = priv_open_device(dev)) == -1)) { 202 /* second: environment variable */ 203 dev = getenv("XDEVICE"); 204 if (dev == NULL || ((fd = priv_open_device(dev)) == -1)) { 205 /* last try: default device */ 206 dev = NGLE_DEFAULT_DEV; 207 if ((fd = priv_open_device(dev)) == -1) { 208 return -1; 209 } 210 } 211 } 212 return fd; 213} 214 215/* Map the framebuffer's memory */ 216static pointer 217ngle_mmap(size_t len, off_t off, int fd, int ro) 218{ 219 pointer mapaddr; 220 221 /* 222 * try and make it private first, that way once we get it, an 223 * interloper, e.g. another server, can't get this frame buffer, 224 * and if another server already has it, this one won't. 225 */ 226 if (ro) { 227 mapaddr = (pointer) mmap(NULL, len, 228 PROT_READ, MAP_SHARED, 229 fd, off); 230 xf86Msg(X_ERROR, "mapping %08x read only\n", off); 231 } else { 232 mapaddr = (pointer) mmap(NULL, len, 233 PROT_READ | PROT_WRITE, MAP_SHARED, 234 fd, off); 235 xf86Msg(X_ERROR, "mapping %08x read/write\n", off); 236 } 237 if (mapaddr == (pointer) -1) { 238 mapaddr = NULL; 239 } 240#ifdef NGLE_DEBUG 241 ErrorF("mmap returns: addr %p len 0x%x\n", mapaddr, len); 242#endif 243 return mapaddr; 244} 245 246static Bool 247NGLEProbe(DriverPtr drv, int flags) 248{ 249 ScrnInfoPtr pScrn = NULL; 250 int i, fd, entity, wstype; 251 GDevPtr *devSections; 252 int numDevSections; 253 char *dev; 254 const char *name; 255 uint32_t gid; 256 Bool foundScreen = FALSE; 257 258 if ((numDevSections = xf86MatchDevice(NGLE_DRIVER_NAME, 259 &devSections)) <= 0) 260 return FALSE; 261 262 263 if ((fd = ngle_open(NGLE_DEFAULT_DEV)) == 0) 264 return FALSE; 265 266 if (ioctl(fd, WSDISPLAYIO_GTYPE, &wstype) == -1) 267 return FALSE; 268 269 if (wstype != WSDISPLAY_TYPE_STI) 270 return FALSE; 271 272 if (ioctl(fd, GCID, &gid) == -1) 273 return FALSE; 274 275 /* reject GIDs not in the table */ 276 if ((name = xf86TokenToString(NGLEChipsets, gid)) == NULL) 277 return FALSE; 278 279 xf86Msg(X_INFO, "%s: found %s ( GID %08x )\n", __func__, name, gid); 280 281 if ( xf86DoConfigure && xf86DoConfigurePass1 ) { 282 GDevPtr pGDev; 283 284 pGDev = xf86AddBusDeviceToConfigure(NGLE_DRIVER_NAME, BUS_NONE, 285 NULL, 0); 286 if (pGDev) { 287 /* 288 * XF86Match???Instances() treat chipID and chipRev as 289 * overrides, so clobber them here. 290 */ 291 pGDev->chipID = pGDev->chipRev = -1; 292 } 293 } 294 295 if (flags & PROBE_DETECT) { 296 return TRUE; 297 } 298 299 if (numDevSections > 1) { 300 xf86Msg(X_ERROR, "Ignoring additional device sections\n"); 301 numDevSections = 1; 302 } 303 /* ok, at this point we know we've got a NGLE */ 304 for (i = 0; i < numDevSections; i++) { 305 306 entity = xf86ClaimFbSlot(drv, 0, devSections[i], TRUE); 307 pScrn = xf86ConfigFbEntity(NULL, 0, entity, 308 NULL, NULL, NULL, NULL); 309 if (pScrn != NULL) { 310 foundScreen = TRUE; 311 pScrn->driverVersion = VERSION; 312 pScrn->driverName = NGLE_DRIVER_NAME; 313 pScrn->name = NGLE_NAME; 314 pScrn->Probe = NGLEProbe; 315 pScrn->PreInit = NGLEPreInit; 316 pScrn->ScreenInit = NGLEScreenInit; 317 pScrn->SwitchMode = NGLESwitchMode; 318 pScrn->AdjustFrame = NULL; 319 pScrn->EnterVT = NGLEEnterVT; 320 pScrn->LeaveVT = NGLELeaveVT; 321 pScrn->ValidMode = NGLEValidMode; 322 323 } 324 } 325 free(devSections); 326 return foundScreen; 327} 328 329static Bool 330NGLEPreInit(ScrnInfoPtr pScrn, int flags) 331{ 332 NGLEPtr fPtr; 333 int default_depth, bitsperpixel, gid; 334 const char *dev; 335 char *mod = NULL; 336 const char *reqSym = NULL; 337 Gamma zeros = {0.0, 0.0, 0.0}; 338 DisplayModePtr mode; 339 MessageType from; 340 rgb rgbzeros = { 0, 0, 0 }, masks; 341 342 if (flags & PROBE_DETECT) return FALSE; 343 344 if (pScrn->numEntities != 1) return FALSE; 345 346 pScrn->monitor = pScrn->confScreen->monitor; 347 348 NGLEGetRec(pScrn); 349 fPtr = NGLEPTR(pScrn); 350 351 fPtr->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 352 353 dev = xf86FindOptionValue(fPtr->pEnt->device->options, "device"); 354 fPtr->fd = ngle_open(dev); 355 if (fPtr->fd == -1) { 356 return FALSE; 357 } 358 359 if (ioctl(fPtr->fd, WSDISPLAYIO_GET_FBINFO, &fPtr->fbi) == -1) { 360 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 361 "ioctl WSDISPLAY_GINFO: %s\n", 362 strerror(errno)); 363 return FALSE; 364 } 365 366 if (ioctl(fPtr->fd, GCID, &gid) == -1) 367 return FALSE; 368 369 fPtr->gid = gid; 370 fPtr->fbacc = 0; 371 372 switch (gid) { 373 case STI_DD_EG: 374 fPtr->buf = BINapp0I; 375 fPtr->fbacc = BA(IndexedDcd, Otc04, Ots08, AddrByte, 0, fPtr->buf, 0); 376 break; 377 case STI_DD_HCRX: 378 /* XXX BINovly if in 8 bit */ 379 fPtr->buf = BINapp0F8; 380 fPtr->fbacc = BA(IndexedDcd, Otc04, Ots08, AddrLong, 0, fPtr->buf, 0); 381 /* 382 * XXX 383 * we don't know yet how much usable video memory we 384 * have but EXA gets cranky if there is no off screen 385 * memory at all, so we give it one line and cross 386 * fingers 387 */ 388 fPtr->fbi.fbi_fbsize += 8192; 389 break; 390 } 391 xf86Msg(X_ERROR, "gid %08x fb access %08x\n", fPtr->gid, fPtr->fbacc); 392 393 /* Handle depth */ 394 default_depth = fPtr->fbi.fbi_bitsperpixel <= 24 ? fPtr->fbi.fbi_bitsperpixel : 24; 395 bitsperpixel = fPtr->fbi.fbi_bitsperpixel == 15 ? 16 : fPtr->fbi.fbi_bitsperpixel; 396 if (!xf86SetDepthBpp(pScrn, default_depth, default_depth, 397 bitsperpixel, 398 bitsperpixel >= 24 ? Support24bppFb|Support32bppFb : 0)) 399 return FALSE; 400 401 xf86PrintDepthBpp(pScrn); 402 403 /* color weight */ 404 masks.red = 0x00ff0000; 405 masks.green = 0x0000ff00; 406 masks.blue = 0x000000ff; 407 if (!xf86SetWeight(pScrn, rgbzeros, masks)) 408 return FALSE; 409 410 /* visual init */ 411 if (!xf86SetDefaultVisual(pScrn, -1)) 412 return FALSE; 413 414 /* We don't currently support DirectColor at > 8bpp */ 415 if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { 416 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" 417 " (%s) is not supported at depth %d\n", 418 xf86GetVisualName(pScrn->defaultVisual), 419 pScrn->depth); 420 return FALSE; 421 } 422 423 xf86SetGamma(pScrn,zeros); 424 425 pScrn->progClock = TRUE; 426 pScrn->rgbBits = 8; 427 pScrn->chipset = "NGLE"; 428 fPtr->fbmem_len = pScrn->videoRam = fPtr->fbi.fbi_fbsize; 429 430 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vidmem: %dk\n", 431 pScrn->videoRam/1024); 432 433 /* handle options */ 434 xf86CollectOptions(pScrn, NULL); 435 if (!(fPtr->Options = malloc(sizeof(NGLEOptions)))) 436 return FALSE; 437 memcpy(fPtr->Options, NGLEOptions, sizeof(NGLEOptions)); 438 xf86ProcessOptions(pScrn->scrnIndex, fPtr->pEnt->device->options, 439 fPtr->Options); 440 441 /* fake video mode struct */ 442 mode = (DisplayModePtr)malloc(sizeof(DisplayModeRec)); 443 mode->prev = mode; 444 mode->next = mode; 445 mode->name = "NGLE current mode"; 446 mode->status = MODE_OK; 447 mode->type = M_T_BUILTIN; 448 mode->Clock = 0; 449 mode->HDisplay = fPtr->fbi.fbi_width; 450 mode->HSyncStart = 0; 451 mode->HSyncEnd = 0; 452 mode->HTotal = 0; 453 mode->HSkew = 0; 454 mode->VDisplay = fPtr->fbi.fbi_height; 455 mode->VSyncStart = 0; 456 mode->VSyncEnd = 0; 457 mode->VTotal = 0; 458 mode->VScan = 0; 459 mode->Flags = 0; 460 if (pScrn->modes != NULL) { 461 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 462 "Ignoring mode specification from screen section\n"); 463 } 464 pScrn->currentMode = pScrn->modes = mode; 465 pScrn->virtualX = fPtr->fbi.fbi_width; 466 pScrn->virtualY = fPtr->fbi.fbi_height; 467 pScrn->displayWidth = 2048; 468 469 /* Set the display resolution */ 470 xf86SetDpi(pScrn, 0, 0); 471 472 from = X_DEFAULT; 473 fPtr->HWCursor = TRUE; 474 if (xf86GetOptValBool(fPtr->Options, OPTION_HW_CURSOR, &fPtr->HWCursor)) 475 from = X_CONFIG; 476 if (xf86ReturnOptValBool(fPtr->Options, OPTION_SW_CURSOR, FALSE)) { 477 from = X_CONFIG; 478 fPtr->HWCursor = FALSE; 479 } 480 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 481 fPtr->HWCursor ? "HW" : "SW"); 482 483 if (xf86LoadSubModule(pScrn, "fb") == NULL) { 484 NGLEFreeRec(pScrn); 485 return FALSE; 486 } 487 488 if (xf86LoadSubModule(pScrn, "exa") == NULL) { 489 NGLEFreeRec(pScrn); 490 return FALSE; 491 } 492 493 if (xf86LoadSubModule(pScrn, "ramdac") == NULL) { 494 NGLEFreeRec(pScrn); 495 return FALSE; 496 } 497 498 return TRUE; 499} 500 501static Bool 502NGLEScreenInit(SCREEN_INIT_ARGS_DECL) 503{ 504 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 505 NGLEPtr fPtr = NGLEPTR(pScrn); 506 VisualPtr visual; 507 int ret, flags, width, height, i, j; 508 int wsmode = WSDISPLAYIO_MODE_MAPPED; 509 size_t len; 510 511#ifdef NGLE_DEBUG 512 ErrorF("\tbitsPerPixel=%d, depth=%d, defaultVisual=%s\n" 513 "\tmask: %x,%x,%x, offset: %d,%d,%d\n", 514 pScrn->bitsPerPixel, 515 pScrn->depth, 516 xf86GetVisualName(pScrn->defaultVisual), 517 pScrn->mask.red,pScrn->mask.green,pScrn->mask.blue, 518 pScrn->offset.red,pScrn->offset.green,pScrn->offset.blue); 519#endif 520 521 /* Switch to graphics mode - required before mmap */ 522 if (ioctl(fPtr->fd, WSDISPLAYIO_SMODE, &wsmode) == -1) { 523 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 524 "ioctl WSDISPLAYIO_SMODE: %s\n", 525 strerror(errno)); 526 return FALSE; 527 } 528 fPtr->regs = ngle_mmap(0x400000, 0x80000000, fPtr->fd, 0); 529 530 if (fPtr->regs == NULL) { 531 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 532 "ngle_mmap registers: %s\n", strerror(errno)); 533 return FALSE; 534 } 535 536 fPtr->fbmem = ngle_mmap(fPtr->fbmem_len, 0, fPtr->fd, 0); 537 if (fPtr->fbmem == NULL) { 538 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 539 "ngle_mmap fb: %s\n", strerror(errno)); 540 return FALSE; 541 } 542 543 NGLESave(pScrn); 544 pScrn->vtSema = TRUE; 545 546 /* mi layer */ 547 miClearVisualTypes(); 548 if (pScrn->bitsPerPixel > 8) { 549 if (!miSetVisualTypes(pScrn->depth, TrueColorMask, 550 pScrn->rgbBits, TrueColor)) 551 return FALSE; 552 } else { 553 if (!miSetVisualTypes(pScrn->depth, 554 miGetDefaultVisualMask(pScrn->depth), 555 pScrn->rgbBits, pScrn->defaultVisual)) 556 return FALSE; 557 } 558 559 if (!miSetPixmapDepths()) 560 return FALSE; 561 562 height = pScrn->virtualY; 563 width = pScrn->virtualX; 564 565 ret = fbScreenInit(pScreen, 566 fPtr->fbmem, 567 width, height, 568 pScrn->xDpi, pScrn->yDpi, 569 pScrn->displayWidth, 570 pScrn->bitsPerPixel); 571 572 if (!ret) 573 return FALSE; 574 575 if (pScrn->bitsPerPixel > 8) { 576 /* Fixup RGB ordering. */ 577 visual = pScreen->visuals + pScreen->numVisuals; 578 while (--visual >= pScreen->visuals) { 579 if ((visual->class | DynamicClass) == DirectColor) { 580 visual->offsetRed = pScrn->offset.red; 581 visual->offsetGreen = pScrn->offset.green; 582 visual->offsetBlue = pScrn->offset.blue; 583 visual->redMask = pScrn->mask.red; 584 visual->greenMask = pScrn->mask.green; 585 visual->blueMask = pScrn->mask.blue; 586 } 587 } 588 } 589 590 if (!fbPictureInit(pScreen, NULL, 0)) 591 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 592 "RENDER extension initialisation failed."); 593 594 xf86SetBlackWhitePixels(pScreen); 595 xf86SetBackingStore(pScreen); 596 597 if (fPtr) { 598 NGLEInitAccel(pScreen); 599 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using acceleration\n"); 600 } 601 602 /* software cursor */ 603 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 604 605 /* check for hardware cursor support */ 606 NGLESetupCursor(pScreen); 607 608 /* colormap */ 609 if (!miCreateDefColormap(pScreen)) 610 return FALSE; 611 612 flags = CMAP_RELOAD_ON_MODE_SWITCH; 613 if(!xf86HandleColormaps(pScreen, 256, 8, NGLELoadPalette, 614 NULL, flags)) 615 return FALSE; 616 617 pScreen->SaveScreen = NGLESaveScreen; 618 619#ifdef XvExtension 620 { 621 XF86VideoAdaptorPtr *ptr; 622 623 int n = xf86XVListGenericAdaptors(pScrn,&ptr); 624 if (n) { 625 xf86XVScreenInit(pScreen,ptr,n); 626 } 627 } 628#endif 629 630 /* Wrap the current CloseScreen function */ 631 fPtr->CloseScreen = pScreen->CloseScreen; 632 pScreen->CloseScreen = NGLECloseScreen; 633 634 return TRUE; 635} 636 637static Bool 638NGLECloseScreen(CLOSE_SCREEN_ARGS_DECL) 639{ 640 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 641 NGLEPtr fPtr = NGLEPTR(pScrn); 642 643 if (pScrn->vtSema) { 644 NGLERestore(pScrn); 645 if (munmap(fPtr->regs, 0x40000) == -1) { 646 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 647 "munmap engine: %s\n", strerror(errno)); 648 } 649 650 if (munmap(fPtr->fbmem, fPtr->fbmem_len) == -1) { 651 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 652 "munmap fb: %s\n", strerror(errno)); 653 } 654 655 fPtr->regs = NULL; 656 fPtr->fbmem = NULL; 657 } 658 pScrn->vtSema = FALSE; 659 660 /* unwrap CloseScreen */ 661 pScreen->CloseScreen = fPtr->CloseScreen; 662 return (*pScreen->CloseScreen)(pScreen); 663} 664 665static Bool 666NGLEEnterVT(VT_FUNC_ARGS_DECL) 667{ 668 SCRN_INFO_PTR(arg); 669 670 pScrn->vtSema = TRUE; 671 return TRUE; 672} 673 674static void 675NGLELeaveVT(VT_FUNC_ARGS_DECL) 676{ 677} 678 679static Bool 680NGLESwitchMode(SWITCH_MODE_ARGS_DECL) 681{ 682 683 /* Nothing else to do */ 684 return TRUE; 685} 686 687static int 688NGLEValidMode(SCRN_ARG_TYPE, DisplayModePtr mode, Bool verbose, int flags) 689{ 690 691 return MODE_OK; 692} 693 694static void 695NGLELoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, 696 LOCO *colors, VisualPtr pVisual) 697{ 698 NGLEPtr fPtr = NGLEPTR(pScrn); 699 struct wsdisplay_cmap cmap; 700 unsigned char red[256],green[256],blue[256]; 701 int i, indexMin=256, indexMax=0; 702 703 /* nothing to do if there is no color palette support */ 704 if (fPtr->fbi.fbi_subtype.fbi_cmapinfo.cmap_entries == 0) 705 return; 706 707 cmap.count = 1; 708 cmap.red = red; 709 cmap.green = green; 710 cmap.blue = blue; 711 712 if (numColors == 1) { 713 /* Optimisation */ 714 cmap.index = indices[0]; 715 red[0] = colors[indices[0]].red; 716 green[0] = colors[indices[0]].green; 717 blue[0] = colors[indices[0]].blue; 718 if (ioctl(fPtr->fd,WSDISPLAYIO_PUTCMAP, &cmap) == -1) 719 ErrorF("ioctl FBIOPUTCMAP: %s\n", strerror(errno)); 720 } else { 721 /* 722 * Change all colors in 2 ioctls 723 * and limit the data to be transferred. 724 */ 725 for (i = 0; i < numColors; i++) { 726 if (indices[i] < indexMin) 727 indexMin = indices[i]; 728 if (indices[i] > indexMax) 729 indexMax = indices[i]; 730 } 731 cmap.index = indexMin; 732 cmap.count = indexMax - indexMin + 1; 733 cmap.red = &red[indexMin]; 734 cmap.green = &green[indexMin]; 735 cmap.blue = &blue[indexMin]; 736 /* Get current map. */ 737 if (ioctl(fPtr->fd, WSDISPLAYIO_GETCMAP, &cmap) == -1) 738 ErrorF("ioctl FBIOGETCMAP: %s\n", strerror(errno)); 739 /* Change the colors that require updating. */ 740 for (i = 0; i < numColors; i++) { 741 red[indices[i]] = colors[indices[i]].red; 742 green[indices[i]] = colors[indices[i]].green; 743 blue[indices[i]] = colors[indices[i]].blue; 744 } 745 /* Write the colormap back. */ 746 if (ioctl(fPtr->fd,WSDISPLAYIO_PUTCMAP, &cmap) == -1) 747 ErrorF("ioctl FBIOPUTCMAP: %s\n", strerror(errno)); 748 } 749 fPtr->hwmode = -1; 750} 751 752static Bool 753NGLESaveScreen(ScreenPtr pScreen, int mode) 754{ 755 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 756 NGLEPtr fPtr = NGLEPTR(pScrn); 757 int state; 758 759 if (!pScrn->vtSema) 760 return TRUE; 761 762 if (mode != SCREEN_SAVER_FORCER) { 763 state = xf86IsUnblank(mode)?WSDISPLAYIO_VIDEO_ON: 764 WSDISPLAYIO_VIDEO_OFF; 765 ioctl(fPtr->fd, 766 WSDISPLAYIO_SVIDEO, &state); 767 } 768 return TRUE; 769} 770 771 772static void 773NGLESave(ScrnInfoPtr pScrn) 774{ 775} 776 777static void 778NGLERestore(ScrnInfoPtr pScrn) 779{ 780 NGLEPtr fPtr = NGLEPTR(pScrn); 781 int mode; 782 783 /* Restore the text mode */ 784 mode = WSDISPLAYIO_MODE_EMUL; 785 if (ioctl(fPtr->fd, WSDISPLAYIO_SMODE, &mode) == -1) { 786 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 787 "error setting text mode %s\n", strerror(errno)); 788 } 789} 790