1/* $NetBSD: ngle_driver.c,v 1.11 2025/02/20 18:53:48 christos 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}, TRUE }, 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 %08tx 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 %08tx 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 if ( xf86DoConfigure && xf86DoConfigurePass1 ) { 281 GDevPtr pGDev; 282 283 pGDev = xf86AddBusDeviceToConfigure(NGLE_DRIVER_NAME, BUS_NONE, 284 NULL, 0); 285 if (pGDev) { 286 /* 287 * XF86Match???Instances() treat chipID and chipRev as 288 * overrides, so clobber them here. 289 */ 290 pGDev->chipID = pGDev->chipRev = -1; 291 } 292 } 293 294 if (flags & PROBE_DETECT) { 295 return TRUE; 296 } 297 298 /* ok, at this point we know we've got a NGLE */ 299 for (i = 0; i < numDevSections; i++) { 300 301 entity = xf86ClaimFbSlot(drv, 0, devSections[i], TRUE); 302 pScrn = xf86ConfigFbEntity(NULL, 0, entity, 303 NULL, NULL, NULL, NULL); 304 if (pScrn != NULL) { 305 foundScreen = TRUE; 306 pScrn->driverVersion = VERSION; 307 pScrn->driverName = NGLE_DRIVER_NAME; 308 pScrn->name = NGLE_NAME; 309 pScrn->Probe = NGLEProbe; 310 pScrn->PreInit = NGLEPreInit; 311 pScrn->ScreenInit = NGLEScreenInit; 312 pScrn->SwitchMode = NGLESwitchMode; 313 pScrn->AdjustFrame = NULL; 314 pScrn->EnterVT = NGLEEnterVT; 315 pScrn->LeaveVT = NGLELeaveVT; 316 pScrn->ValidMode = NGLEValidMode; 317 318 } 319 } 320 free(devSections); 321 return foundScreen; 322} 323 324static Bool 325NGLEPreInit(ScrnInfoPtr pScrn, int flags) 326{ 327 NGLEPtr fPtr; 328 int default_depth, bitsperpixel, gid; 329 const char *dev; 330 char *mod = NULL; 331 const char *reqSym = NULL; 332 Gamma zeros = {0.0, 0.0, 0.0}; 333 DisplayModePtr mode; 334 MessageType from; 335 rgb rgbzeros = { 0, 0, 0 }, masks; 336 337 if (flags & PROBE_DETECT) return FALSE; 338 339 if (pScrn->numEntities != 1) return FALSE; 340 341 pScrn->monitor = pScrn->confScreen->monitor; 342 343 NGLEGetRec(pScrn); 344 fPtr = NGLEPTR(pScrn); 345 346 fPtr->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 347 348 dev = xf86FindOptionValue(fPtr->pEnt->device->options, "device"); 349 fPtr->fd = ngle_open(dev); 350 if (fPtr->fd == -1) { 351 return FALSE; 352 } 353 354 if (ioctl(fPtr->fd, WSDISPLAYIO_GET_FBINFO, &fPtr->fbi) == -1) { 355 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 356 "ioctl WSDISPLAY_GINFO: %s\n", 357 strerror(errno)); 358 return FALSE; 359 } 360 361 if (ioctl(fPtr->fd, GCID, &gid) == -1) 362 return FALSE; 363 364 fPtr->gid = gid; 365 fPtr->fbacc = 0; 366 367 switch (gid) { 368 case STI_DD_EG: 369 fPtr->buf = BINapp0I; 370 fPtr->fbacc = BA(IndexedDcd, Otc04, Ots08, AddrByte, 0, fPtr->buf, 0); 371 fPtr->reglen = 0x400000; 372 break; 373 case STI_DD_HCRX: 374 /* XXX BINovly if in 8 bit */ 375 fPtr->buf = BINapp0F8; 376 fPtr->fbacc = BA(IndexedDcd, Otc04, Ots08, AddrLong, 0, fPtr->buf, 0); 377 /* 378 * XXX 379 * we don't know yet how much usable video memory we 380 * have but EXA gets cranky if there is no off screen 381 * memory at all, so we give it one line and cross 382 * fingers 383 */ 384 fPtr->fbi.fbi_fbsize += 8192; 385 fPtr->reglen = 0x400000; 386 break; 387 case STI_DD_SUMMIT: 388 fPtr->reglen = 0x1000000; 389 break; 390 } 391 xf86Msg(X_INFO, "%s: found %s ( GID %08x )\n", 392 __func__, xf86TokenToString(NGLEChipsets, gid), gid); 393 394 /* Handle depth */ 395 default_depth = fPtr->fbi.fbi_bitsperpixel <= 24 ? fPtr->fbi.fbi_bitsperpixel : 24; 396 bitsperpixel = fPtr->fbi.fbi_bitsperpixel == 15 ? 16 : fPtr->fbi.fbi_bitsperpixel; 397 if (!xf86SetDepthBpp(pScrn, default_depth, default_depth, 398 bitsperpixel, 399 bitsperpixel >= 24 ? Support24bppFb|Support32bppFb : 0)) 400 return FALSE; 401 402 xf86PrintDepthBpp(pScrn); 403 404 /* color weight */ 405 masks.red = 0x00ff0000; 406 masks.green = 0x0000ff00; 407 masks.blue = 0x000000ff; 408 if (!xf86SetWeight(pScrn, rgbzeros, masks)) 409 return FALSE; 410 411 /* visual init */ 412 if (!xf86SetDefaultVisual(pScrn, -1)) 413 return FALSE; 414 415 /* We don't currently support DirectColor at > 8bpp */ 416 if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { 417 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" 418 " (%s) is not supported at depth %d\n", 419 xf86GetVisualName(pScrn->defaultVisual), 420 pScrn->depth); 421 return FALSE; 422 } 423 424 xf86SetGamma(pScrn,zeros); 425 426 pScrn->progClock = TRUE; 427 pScrn->rgbBits = 8; 428 pScrn->chipset = "NGLE"; 429 fPtr->fbmem_len = pScrn->videoRam = fPtr->fbi.fbi_fbsize; 430 431 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vidmem: %dk\n", 432 pScrn->videoRam/1024); 433 434 /* handle options */ 435 xf86CollectOptions(pScrn, NULL); 436 if (!(fPtr->Options = malloc(sizeof(NGLEOptions)))) 437 return FALSE; 438 memcpy(fPtr->Options, NGLEOptions, sizeof(NGLEOptions)); 439 xf86ProcessOptions(pScrn->scrnIndex, fPtr->pEnt->device->options, 440 fPtr->Options); 441 442 /* fake video mode struct */ 443 mode = (DisplayModePtr)malloc(sizeof(DisplayModeRec)); 444 mode->prev = mode; 445 mode->next = mode; 446 mode->name = "NGLE current mode"; 447 mode->status = MODE_OK; 448 mode->type = M_T_BUILTIN; 449 mode->Clock = 0; 450 mode->HDisplay = fPtr->fbi.fbi_width; 451 mode->HSyncStart = 0; 452 mode->HSyncEnd = 0; 453 mode->HTotal = 0; 454 mode->HSkew = 0; 455 mode->VDisplay = fPtr->fbi.fbi_height; 456 mode->VSyncStart = 0; 457 mode->VSyncEnd = 0; 458 mode->VTotal = 0; 459 mode->VScan = 0; 460 mode->Flags = 0; 461 if (pScrn->modes != NULL) { 462 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 463 "Ignoring mode specification from screen section\n"); 464 } 465 pScrn->currentMode = pScrn->modes = mode; 466 pScrn->virtualX = fPtr->fbi.fbi_width; 467 pScrn->virtualY = fPtr->fbi.fbi_height; 468 pScrn->displayWidth = 2048; 469 470 /* Set the display resolution */ 471 xf86SetDpi(pScrn, 0, 0); 472 473 from = X_DEFAULT; 474 fPtr->HWCursor = FALSE; 475 if (xf86GetOptValBool(fPtr->Options, OPTION_HW_CURSOR, &fPtr->HWCursor)) { 476 from = X_CONFIG; 477 fPtr->HWCursor = TRUE; 478 } 479 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 480 fPtr->HWCursor ? "HW" : "SW"); 481 482 if (xf86LoadSubModule(pScrn, "fb") == NULL) { 483 NGLEFreeRec(pScrn); 484 return FALSE; 485 } 486 487 if (xf86LoadSubModule(pScrn, "exa") == NULL) { 488 NGLEFreeRec(pScrn); 489 return FALSE; 490 } 491 492 return TRUE; 493} 494 495static Bool 496NGLEScreenInit(SCREEN_INIT_ARGS_DECL) 497{ 498 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 499 NGLEPtr fPtr = NGLEPTR(pScrn); 500 VisualPtr visual; 501 int ret, flags, width, height, i, j; 502 int wsmode = WSDISPLAYIO_MODE_MAPPED; 503 size_t len; 504 505#ifdef NGLE_DEBUG 506 ErrorF("\tbitsPerPixel=%d, depth=%d, defaultVisual=%s\n" 507 "\tmask: %x,%x,%x, offset: %d,%d,%d\n", 508 pScrn->bitsPerPixel, 509 pScrn->depth, 510 xf86GetVisualName(pScrn->defaultVisual), 511 pScrn->mask.red,pScrn->mask.green,pScrn->mask.blue, 512 pScrn->offset.red,pScrn->offset.green,pScrn->offset.blue); 513#endif 514 515 /* Switch to graphics mode - required before mmap */ 516 if (ioctl(fPtr->fd, WSDISPLAYIO_SMODE, &wsmode) == -1) { 517 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 518 "ioctl WSDISPLAYIO_SMODE: %s\n", 519 strerror(errno)); 520 return FALSE; 521 } 522 523 fPtr->regs = ngle_mmap(fPtr->reglen, 0x80000000, fPtr->fd, 0); 524 525 if (fPtr->regs == NULL) { 526 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 527 "ngle_mmap registers: %s\n", strerror(errno)); 528 return FALSE; 529 } 530 531 fPtr->fbmem = ngle_mmap(fPtr->fbmem_len, 0, fPtr->fd, 0); 532 if (fPtr->fbmem == NULL) { 533 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 534 "ngle_mmap fb: %s\n", strerror(errno)); 535 return FALSE; 536 } 537 538 NGLESave(pScrn); 539 pScrn->vtSema = TRUE; 540 541 /* mi layer */ 542 miClearVisualTypes(); 543 if (pScrn->bitsPerPixel > 8) { 544 if (!miSetVisualTypes(pScrn->depth, TrueColorMask, 545 pScrn->rgbBits, TrueColor)) 546 return FALSE; 547 } else { 548 if (!miSetVisualTypes(pScrn->depth, 549 miGetDefaultVisualMask(pScrn->depth), 550 pScrn->rgbBits, pScrn->defaultVisual)) 551 return FALSE; 552 } 553 554 if (!miSetPixmapDepths()) 555 return FALSE; 556 557 height = pScrn->virtualY; 558 width = pScrn->virtualX; 559 560 ret = fbScreenInit(pScreen, 561 fPtr->fbmem, 562 width, height, 563 pScrn->xDpi, pScrn->yDpi, 564 pScrn->displayWidth, 565 pScrn->bitsPerPixel); 566 567 if (!ret) 568 return FALSE; 569 570 if (pScrn->bitsPerPixel > 8) { 571 /* Fixup RGB ordering. */ 572 visual = pScreen->visuals + pScreen->numVisuals; 573 while (--visual >= pScreen->visuals) { 574 if ((visual->class | DynamicClass) == DirectColor) { 575 visual->offsetRed = pScrn->offset.red; 576 visual->offsetGreen = pScrn->offset.green; 577 visual->offsetBlue = pScrn->offset.blue; 578 visual->redMask = pScrn->mask.red; 579 visual->greenMask = pScrn->mask.green; 580 visual->blueMask = pScrn->mask.blue; 581 } 582 } 583 } 584 585 if (!fbPictureInit(pScreen, NULL, 0)) 586 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 587 "RENDER extension initialisation failed."); 588 589 xf86SetBlackWhitePixels(pScreen); 590 xf86SetBackingStore(pScreen); 591 592 if (fPtr) { 593 if (fPtr->gid == STI_DD_SUMMIT) { 594 SummitInitAccel(pScreen); 595 } else 596 NGLEInitAccel(pScreen); 597 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using acceleration\n"); 598 } 599 600 /* software cursor */ 601 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 602 603 /* check for hardware cursor support */ 604 if (fPtr->gid == STI_DD_SUMMIT) { 605 SummitSetupCursor(pScreen); 606 } else 607 NGLESetupCursor(pScreen); 608 609 /* colormap */ 610 if (!miCreateDefColormap(pScreen)) 611 return FALSE; 612 613 flags = CMAP_RELOAD_ON_MODE_SWITCH; 614 if(!xf86HandleColormaps(pScreen, 256, 8, NGLELoadPalette, 615 NULL, flags)) 616 return FALSE; 617 618 pScreen->SaveScreen = NGLESaveScreen; 619 620#ifdef XvExtension 621 { 622 XF86VideoAdaptorPtr *ptr; 623 624 int n = xf86XVListGenericAdaptors(pScrn,&ptr); 625 if (n) { 626 xf86XVScreenInit(pScreen,ptr,n); 627 } 628 } 629#endif 630 631 /* Wrap the current CloseScreen function */ 632 fPtr->CloseScreen = pScreen->CloseScreen; 633 pScreen->CloseScreen = NGLECloseScreen; 634 635 return TRUE; 636} 637 638static Bool 639NGLECloseScreen(CLOSE_SCREEN_ARGS_DECL) 640{ 641 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 642 NGLEPtr fPtr = NGLEPTR(pScrn); 643 644 if (pScrn->vtSema) { 645 NGLERestore(pScrn); 646 if (munmap(fPtr->regs, fPtr->reglen) == -1) { 647 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 648 "munmap engine: %s\n", strerror(errno)); 649 } 650 651 if (munmap(fPtr->fbmem, fPtr->fbmem_len) == -1) { 652 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 653 "munmap fb: %s\n", strerror(errno)); 654 } 655 656 fPtr->regs = NULL; 657 fPtr->fbmem = NULL; 658 } 659 pScrn->vtSema = FALSE; 660 661 /* unwrap CloseScreen */ 662 pScreen->CloseScreen = fPtr->CloseScreen; 663 return (*pScreen->CloseScreen)(pScreen); 664} 665 666static Bool 667NGLEEnterVT(VT_FUNC_ARGS_DECL) 668{ 669 SCRN_INFO_PTR(arg); 670 671 pScrn->vtSema = TRUE; 672 return TRUE; 673} 674 675static void 676NGLELeaveVT(VT_FUNC_ARGS_DECL) 677{ 678} 679 680static Bool 681NGLESwitchMode(SWITCH_MODE_ARGS_DECL) 682{ 683 684 /* Nothing else to do */ 685 return TRUE; 686} 687 688static int 689NGLEValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) 690{ 691 692 return MODE_OK; 693} 694 695static void 696NGLELoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, 697 LOCO *colors, VisualPtr pVisual) 698{ 699 NGLEPtr fPtr = NGLEPTR(pScrn); 700 struct wsdisplay_cmap cmap; 701 unsigned char red[256],green[256],blue[256]; 702 int i, indexMin=256, indexMax=0; 703 704 /* nothing to do if there is no color palette support */ 705 if (fPtr->fbi.fbi_subtype.fbi_cmapinfo.cmap_entries == 0) 706 return; 707 708 cmap.count = 1; 709 cmap.red = red; 710 cmap.green = green; 711 cmap.blue = blue; 712 713 if (numColors == 1) { 714 /* Optimisation */ 715 cmap.index = indices[0]; 716 red[0] = colors[indices[0]].red; 717 green[0] = colors[indices[0]].green; 718 blue[0] = colors[indices[0]].blue; 719 if (ioctl(fPtr->fd,WSDISPLAYIO_PUTCMAP, &cmap) == -1) 720 ErrorF("ioctl FBIOPUTCMAP: %s\n", strerror(errno)); 721 } else { 722 /* 723 * Change all colors in 2 ioctls 724 * and limit the data to be transferred. 725 */ 726 for (i = 0; i < numColors; i++) { 727 if (indices[i] < indexMin) 728 indexMin = indices[i]; 729 if (indices[i] > indexMax) 730 indexMax = indices[i]; 731 } 732 cmap.index = indexMin; 733 cmap.count = indexMax - indexMin + 1; 734 cmap.red = &red[indexMin]; 735 cmap.green = &green[indexMin]; 736 cmap.blue = &blue[indexMin]; 737 /* Get current map. */ 738 if (ioctl(fPtr->fd, WSDISPLAYIO_GETCMAP, &cmap) == -1) 739 ErrorF("ioctl FBIOGETCMAP: %s\n", strerror(errno)); 740 /* Change the colors that require updating. */ 741 for (i = 0; i < numColors; i++) { 742 red[indices[i]] = colors[indices[i]].red; 743 green[indices[i]] = colors[indices[i]].green; 744 blue[indices[i]] = colors[indices[i]].blue; 745 } 746 /* Write the colormap back. */ 747 if (ioctl(fPtr->fd,WSDISPLAYIO_PUTCMAP, &cmap) == -1) 748 ErrorF("ioctl FBIOPUTCMAP: %s\n", strerror(errno)); 749 } 750 fPtr->hwmode = -1; 751} 752 753static Bool 754NGLESaveScreen(ScreenPtr pScreen, int mode) 755{ 756 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 757 NGLEPtr fPtr = NGLEPTR(pScrn); 758 int state; 759 760 if (!pScrn->vtSema) 761 return TRUE; 762 763 if (mode != SCREEN_SAVER_FORCER) { 764 state = xf86IsUnblank(mode)?WSDISPLAYIO_VIDEO_ON: 765 WSDISPLAYIO_VIDEO_OFF; 766 ioctl(fPtr->fd, 767 WSDISPLAYIO_SVIDEO, &state); 768 } 769 return TRUE; 770} 771 772 773static void 774NGLESave(ScrnInfoPtr pScrn) 775{ 776} 777 778static void 779NGLERestore(ScrnInfoPtr pScrn) 780{ 781 NGLEPtr fPtr = NGLEPTR(pScrn); 782 int mode; 783 784 /* Restore the text mode */ 785 mode = WSDISPLAYIO_MODE_EMUL; 786 if (ioctl(fPtr->fd, WSDISPLAYIO_SMODE, &mode) == -1) { 787 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 788 "error setting text mode %s\n", strerror(errno)); 789 } 790} 791