ngle_driver.c revision 727c6de2
1/* $NetBSD: ngle_driver.c,v 1.2 2024/10/21 13:40:53 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 = BINapp1I; 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 break; 382 } 383 xf86Msg(X_ERROR, "gid %08x fb access %08x\n", fPtr->gid, fPtr->fbacc); 384 385 /* Handle depth */ 386 default_depth = fPtr->fbi.fbi_bitsperpixel <= 24 ? fPtr->fbi.fbi_bitsperpixel : 24; 387 bitsperpixel = fPtr->fbi.fbi_bitsperpixel == 15 ? 16 : fPtr->fbi.fbi_bitsperpixel; 388 if (!xf86SetDepthBpp(pScrn, default_depth, default_depth, 389 bitsperpixel, 390 bitsperpixel >= 24 ? Support24bppFb|Support32bppFb : 0)) 391 return FALSE; 392 393 xf86PrintDepthBpp(pScrn); 394 395 /* color weight */ 396 masks.red = 0x00ff0000; 397 masks.green = 0x0000ff00; 398 masks.blue = 0x000000ff; 399 if (!xf86SetWeight(pScrn, rgbzeros, masks)) 400 return FALSE; 401 402 /* visual init */ 403 if (!xf86SetDefaultVisual(pScrn, -1)) 404 return FALSE; 405 406 /* We don't currently support DirectColor at > 8bpp */ 407 if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { 408 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" 409 " (%s) is not supported at depth %d\n", 410 xf86GetVisualName(pScrn->defaultVisual), 411 pScrn->depth); 412 return FALSE; 413 } 414 415 xf86SetGamma(pScrn,zeros); 416 417 pScrn->progClock = TRUE; 418 pScrn->rgbBits = 8; 419 pScrn->chipset = "NGLE"; 420 fPtr->fbmem_len = pScrn->videoRam = fPtr->fbi.fbi_fbsize; 421 422 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vidmem: %dk\n", 423 pScrn->videoRam/1024); 424 425 /* handle options */ 426 xf86CollectOptions(pScrn, NULL); 427 if (!(fPtr->Options = malloc(sizeof(NGLEOptions)))) 428 return FALSE; 429 memcpy(fPtr->Options, NGLEOptions, sizeof(NGLEOptions)); 430 xf86ProcessOptions(pScrn->scrnIndex, fPtr->pEnt->device->options, 431 fPtr->Options); 432 433 /* fake video mode struct */ 434 mode = (DisplayModePtr)malloc(sizeof(DisplayModeRec)); 435 mode->prev = mode; 436 mode->next = mode; 437 mode->name = "NGLE current mode"; 438 mode->status = MODE_OK; 439 mode->type = M_T_BUILTIN; 440 mode->Clock = 0; 441 mode->HDisplay = fPtr->fbi.fbi_width; 442 mode->HSyncStart = 0; 443 mode->HSyncEnd = 0; 444 mode->HTotal = 0; 445 mode->HSkew = 0; 446 mode->VDisplay = fPtr->fbi.fbi_height; 447 mode->VSyncStart = 0; 448 mode->VSyncEnd = 0; 449 mode->VTotal = 0; 450 mode->VScan = 0; 451 mode->Flags = 0; 452 if (pScrn->modes != NULL) { 453 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 454 "Ignoring mode specification from screen section\n"); 455 } 456 pScrn->currentMode = pScrn->modes = mode; 457 pScrn->virtualX = fPtr->fbi.fbi_width; 458 pScrn->virtualY = fPtr->fbi.fbi_height; 459 pScrn->displayWidth = 2048; 460 461 /* Set the display resolution */ 462 xf86SetDpi(pScrn, 0, 0); 463 464 from = X_DEFAULT; 465 fPtr->HWCursor = TRUE; 466 if (xf86GetOptValBool(fPtr->Options, OPTION_HW_CURSOR, &fPtr->HWCursor)) 467 from = X_CONFIG; 468 if (xf86ReturnOptValBool(fPtr->Options, OPTION_SW_CURSOR, FALSE)) { 469 from = X_CONFIG; 470 fPtr->HWCursor = FALSE; 471 } 472 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 473 fPtr->HWCursor ? "HW" : "SW"); 474 475 if (xf86LoadSubModule(pScrn, "fb") == NULL) { 476 NGLEFreeRec(pScrn); 477 return FALSE; 478 } 479 480 if (xf86LoadSubModule(pScrn, "exa") == NULL) { 481 NGLEFreeRec(pScrn); 482 return FALSE; 483 } 484 485 if (xf86LoadSubModule(pScrn, "ramdac") == NULL) { 486 NGLEFreeRec(pScrn); 487 return FALSE; 488 } 489 490 return TRUE; 491} 492 493static Bool 494NGLEScreenInit(SCREEN_INIT_ARGS_DECL) 495{ 496 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 497 NGLEPtr fPtr = NGLEPTR(pScrn); 498 VisualPtr visual; 499 int ret, flags, width, height, i, j; 500 int wsmode = WSDISPLAYIO_MODE_MAPPED; 501 size_t len; 502 503#ifdef NGLE_DEBUG 504 ErrorF("\tbitsPerPixel=%d, depth=%d, defaultVisual=%s\n" 505 "\tmask: %x,%x,%x, offset: %d,%d,%d\n", 506 pScrn->bitsPerPixel, 507 pScrn->depth, 508 xf86GetVisualName(pScrn->defaultVisual), 509 pScrn->mask.red,pScrn->mask.green,pScrn->mask.blue, 510 pScrn->offset.red,pScrn->offset.green,pScrn->offset.blue); 511#endif 512 513 /* Switch to graphics mode - required before mmap */ 514 if (ioctl(fPtr->fd, WSDISPLAYIO_SMODE, &wsmode) == -1) { 515 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 516 "ioctl WSDISPLAYIO_SMODE: %s\n", 517 strerror(errno)); 518 return FALSE; 519 } 520 fPtr->regs = ngle_mmap(0x400000, 0x80000000, fPtr->fd, 0); 521 522 if (fPtr->regs == NULL) { 523 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 524 "ngle_mmap registers: %s\n", strerror(errno)); 525 return FALSE; 526 } 527 528 fPtr->fbmem = ngle_mmap(fPtr->fbmem_len, 0, fPtr->fd, 0); 529 if (fPtr->fbmem == NULL) { 530 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 531 "ngle_mmap fb: %s\n", strerror(errno)); 532 return FALSE; 533 } 534 535 NGLESave(pScrn); 536 pScrn->vtSema = TRUE; 537 538 /* mi layer */ 539 miClearVisualTypes(); 540 if (!miSetVisualTypes(pScrn->depth, TrueColorMask, 541 pScrn->rgbBits, TrueColor)) 542 return FALSE; 543 544 if (!miSetPixmapDepths()) 545 return FALSE; 546 547 height = pScrn->virtualY; 548 width = pScrn->virtualX; 549 550 ret = fbScreenInit(pScreen, 551 fPtr->fbmem, 552 width, height, 553 pScrn->xDpi, pScrn->yDpi, 554 pScrn->displayWidth, 555 pScrn->bitsPerPixel); 556 557 if (!ret) 558 return FALSE; 559 560 if (pScrn->bitsPerPixel > 8) { 561 /* Fixup RGB ordering. */ 562 visual = pScreen->visuals + pScreen->numVisuals; 563 while (--visual >= pScreen->visuals) { 564 if ((visual->class | DynamicClass) == DirectColor) { 565 visual->offsetRed = pScrn->offset.red; 566 visual->offsetGreen = pScrn->offset.green; 567 visual->offsetBlue = pScrn->offset.blue; 568 visual->redMask = pScrn->mask.red; 569 visual->greenMask = pScrn->mask.green; 570 visual->blueMask = pScrn->mask.blue; 571 } 572 } 573 } 574 575 if (!fbPictureInit(pScreen, NULL, 0)) 576 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 577 "RENDER extension initialisation failed."); 578 579 xf86SetBlackWhitePixels(pScreen); 580 xf86SetBackingStore(pScreen); 581 582 if (fPtr) { 583 NGLEInitAccel(pScreen); 584 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using acceleration\n"); 585 } 586 587 /* software cursor */ 588 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 589 590 /* check for hardware cursor support */ 591 NGLESetupCursor(pScreen); 592 593 /* colormap */ 594 if (!miCreateDefColormap(pScreen)) 595 return FALSE; 596 597 flags = CMAP_RELOAD_ON_MODE_SWITCH; 598 if(!xf86HandleColormaps(pScreen, 256, 8, NGLELoadPalette, 599 NULL, flags)) 600 return FALSE; 601 602 pScreen->SaveScreen = NGLESaveScreen; 603 604#ifdef XvExtension 605 { 606 XF86VideoAdaptorPtr *ptr; 607 608 int n = xf86XVListGenericAdaptors(pScrn,&ptr); 609 if (n) { 610 xf86XVScreenInit(pScreen,ptr,n); 611 } 612 } 613#endif 614 615 /* Wrap the current CloseScreen function */ 616 fPtr->CloseScreen = pScreen->CloseScreen; 617 pScreen->CloseScreen = NGLECloseScreen; 618 619 return TRUE; 620} 621 622static Bool 623NGLECloseScreen(CLOSE_SCREEN_ARGS_DECL) 624{ 625 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 626 NGLEPtr fPtr = NGLEPTR(pScrn); 627 628 if (pScrn->vtSema) { 629 NGLERestore(pScrn); 630 if (munmap(fPtr->regs, 0x40000) == -1) { 631 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 632 "munmap engine: %s\n", strerror(errno)); 633 } 634 635 if (munmap(fPtr->fbmem, fPtr->fbmem_len) == -1) { 636 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 637 "munmap fb: %s\n", strerror(errno)); 638 } 639 640 fPtr->regs = NULL; 641 fPtr->fbmem = NULL; 642 } 643 pScrn->vtSema = FALSE; 644 645 /* unwrap CloseScreen */ 646 pScreen->CloseScreen = fPtr->CloseScreen; 647 return (*pScreen->CloseScreen)(pScreen); 648} 649 650static Bool 651NGLEEnterVT(VT_FUNC_ARGS_DECL) 652{ 653 SCRN_INFO_PTR(arg); 654 655 pScrn->vtSema = TRUE; 656 return TRUE; 657} 658 659static void 660NGLELeaveVT(VT_FUNC_ARGS_DECL) 661{ 662} 663 664static Bool 665NGLESwitchMode(SWITCH_MODE_ARGS_DECL) 666{ 667 668 /* Nothing else to do */ 669 return TRUE; 670} 671 672static int 673NGLEValidMode(SCRN_ARG_TYPE, DisplayModePtr mode, Bool verbose, int flags) 674{ 675 676 return MODE_OK; 677} 678 679static void 680NGLELoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, 681 LOCO *colors, VisualPtr pVisual) 682{ 683 NGLEPtr fPtr = NGLEPTR(pScrn); 684 struct wsdisplay_cmap cmap; 685 unsigned char red[256],green[256],blue[256]; 686 int i, indexMin=256, indexMax=0; 687 688 /* nothing to do if there is no color palette support */ 689 if (fPtr->fbi.fbi_subtype.fbi_cmapinfo.cmap_entries == 0) 690 return; 691 692 cmap.count = 1; 693 cmap.red = red; 694 cmap.green = green; 695 cmap.blue = blue; 696 697 if (numColors == 1) { 698 /* Optimisation */ 699 cmap.index = indices[0]; 700 red[0] = colors[indices[0]].red; 701 green[0] = colors[indices[0]].green; 702 blue[0] = colors[indices[0]].blue; 703 if (ioctl(fPtr->fd,WSDISPLAYIO_PUTCMAP, &cmap) == -1) 704 ErrorF("ioctl FBIOPUTCMAP: %s\n", strerror(errno)); 705 } else { 706 /* 707 * Change all colors in 2 ioctls 708 * and limit the data to be transferred. 709 */ 710 for (i = 0; i < numColors; i++) { 711 if (indices[i] < indexMin) 712 indexMin = indices[i]; 713 if (indices[i] > indexMax) 714 indexMax = indices[i]; 715 } 716 cmap.index = indexMin; 717 cmap.count = indexMax - indexMin + 1; 718 cmap.red = &red[indexMin]; 719 cmap.green = &green[indexMin]; 720 cmap.blue = &blue[indexMin]; 721 /* Get current map. */ 722 if (ioctl(fPtr->fd, WSDISPLAYIO_GETCMAP, &cmap) == -1) 723 ErrorF("ioctl FBIOGETCMAP: %s\n", strerror(errno)); 724 /* Change the colors that require updating. */ 725 for (i = 0; i < numColors; i++) { 726 red[indices[i]] = colors[indices[i]].red; 727 green[indices[i]] = colors[indices[i]].green; 728 blue[indices[i]] = colors[indices[i]].blue; 729 } 730 /* Write the colormap back. */ 731 if (ioctl(fPtr->fd,WSDISPLAYIO_PUTCMAP, &cmap) == -1) 732 ErrorF("ioctl FBIOPUTCMAP: %s\n", strerror(errno)); 733 } 734} 735 736static Bool 737NGLESaveScreen(ScreenPtr pScreen, int mode) 738{ 739 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 740 NGLEPtr fPtr = NGLEPTR(pScrn); 741 int state; 742 743 if (!pScrn->vtSema) 744 return TRUE; 745 746 if (mode != SCREEN_SAVER_FORCER) { 747 state = xf86IsUnblank(mode)?WSDISPLAYIO_VIDEO_ON: 748 WSDISPLAYIO_VIDEO_OFF; 749 ioctl(fPtr->fd, 750 WSDISPLAYIO_SVIDEO, &state); 751 } 752 return TRUE; 753} 754 755 756static void 757NGLESave(ScrnInfoPtr pScrn) 758{ 759} 760 761static void 762NGLERestore(ScrnInfoPtr pScrn) 763{ 764 NGLEPtr fPtr = NGLEPTR(pScrn); 765 int mode; 766 767 /* Restore the text mode */ 768 mode = WSDISPLAYIO_MODE_EMUL; 769 if (ioctl(fPtr->fd, WSDISPLAYIO_SMODE, &mode) == -1) { 770 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 771 "error setting text mode %s\n", strerror(errno)); 772 } 773} 774