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