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