igs_driver.c revision ce2d3770
1/* $OpenBSD: wsfb_driver.c,v 1.19 2003/04/27 16:42:32 matthieu Exp $ */ 2/* $NetBSD: igs_driver.c,v 1.12 2016/08/16 01:27:46 mrg Exp $ */ 3/* 4 * Copyright (c) 2001 Matthieu Herrb 5 * 2009 Michael Lorenz 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * - Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * - Redistributions in binary form must reproduce the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer in the documentation and/or other materials provided 17 * with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 23 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 * 32 */ 33 34/* 35 * Based on fbdev.c written by: 36 * 37 * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> 38 * Michel Dänzer, <michdaen@iiic.ethz.ch> 39 */ 40 41 /* 42 * a driver for IGS CyberPro 2010 graphics controllers 43 * adapted from wsfb 44 */ 45 46#ifdef HAVE_CONFIG_H 47#include "config.h" 48#endif 49 50#include <fcntl.h> 51#include <sys/types.h> 52#include <sys/time.h> 53#include <sys/ioctl.h> 54#include <unistd.h> 55#include <errno.h> 56#include <dev/wscons/wsconsio.h> 57 58/* all driver need this */ 59#include "xf86.h" 60#include "xf86_OSproc.h" 61 62#include "mipointer.h" 63#include "micmap.h" 64#include "colormapst.h" 65#include "xf86cmap.h" 66#include "shadow.h" 67#include "dgaproc.h" 68 69/* Everything using inb/outb, etc needs "compiler.h" */ 70#include "compiler.h" 71 72/* for visuals */ 73#include "fb.h" 74 75#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 7 76#include "xf86Resources.h" 77#include "xf86RAC.h" 78#endif 79 80#ifdef XvExtension 81#include "xf86xv.h" 82#endif 83 84#include "igs.h" 85 86#include <sys/mman.h> 87 88#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) > 6 89#define xf86LoaderReqSymLists(...) do {} while (0) 90#define LoaderRefSymLists(...) do {} while (0) 91#define xf86LoaderReqSymbols(...) do {} while (0) 92#endif 93 94#define DEBUG 0 95 96#if DEBUG 97# define TRACE_ENTER(str) ErrorF("igs: " str " %d\n",pScrn->scrnIndex) 98# define TRACE_EXIT(str) ErrorF("igs: " str " done\n") 99# define TRACE(str) ErrorF("igs trace: " str "\n") 100#else 101# define TRACE_ENTER(str) 102# define TRACE_EXIT(str) 103# define TRACE(str) 104#endif 105 106#define IGS_DEFAULT_DEV "/dev/ttyE0" 107 108/* Prototypes */ 109#ifdef XFree86LOADER 110static pointer IgsSetup(pointer, pointer, int *, int *); 111#endif 112static Bool IgsGetRec(ScrnInfoPtr); 113static void IgsFreeRec(ScrnInfoPtr); 114static const OptionInfoRec * IgsAvailableOptions(int, int); 115static void IgsIdentify(int); 116static Bool IgsProbe(DriverPtr, int); 117static Bool IgsPreInit(ScrnInfoPtr, int); 118static Bool IgsScreenInit(int, ScreenPtr, int, char **); 119static Bool IgsCloseScreen(int, ScreenPtr); 120static void *IgsWindowLinear(ScreenPtr, CARD32, CARD32, int, CARD32 *, 121 void *); 122static Bool IgsEnterVT(int, int); 123static void IgsLeaveVT(int, int); 124static Bool IgsSwitchMode(int, DisplayModePtr, int); 125static int IgsValidMode(int, DisplayModePtr, Bool, int); 126static void IgsLoadPalette(ScrnInfoPtr, int, int *, LOCO *, VisualPtr); 127static Bool IgsSaveScreen(ScreenPtr, int); 128static void IgsSave(ScrnInfoPtr); 129static void IgsRestore(ScrnInfoPtr); 130 131/* dga stuff */ 132#ifdef XFreeXDGA 133static Bool IgsDGAOpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 134 int *, int *, int *); 135static Bool IgsDGASetMode(ScrnInfoPtr, DGAModePtr); 136static void IgsDGASetViewport(ScrnInfoPtr, int, int, int); 137static Bool IgsDGAInit(ScrnInfoPtr, ScreenPtr); 138#endif 139static Bool IgsDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, 140 pointer ptr); 141 142/* helper functions */ 143static pointer igs_mmap(size_t, off_t, int); 144 145/* 146 * This is intentionally screen-independent. It indicates the binding 147 * choice made in the first PreInit. 148 */ 149static int pix24bpp = 0; 150 151#define IGS_VERSION 4000 152#define IGS_NAME "igs" 153#define IGS_DRIVER_NAME "igs" 154 155_X_EXPORT DriverRec IGS = { 156 IGS_VERSION, 157 IGS_DRIVER_NAME, 158 IgsIdentify, 159 IgsProbe, 160 IgsAvailableOptions, 161 NULL, 162 0, 163 IgsDriverFunc 164}; 165 166/* Supported "chipsets" */ 167static SymTabRec IgsChipsets[] = { 168 { 0, "CyberPro 2010" }, 169 { -1, NULL } 170}; 171 172/* Supported options */ 173typedef enum { 174 OPTION_NOACCEL, 175 OPTION_HW_CURSOR, 176 OPTION_SW_CURSOR 177} IgsOpts; 178 179static const OptionInfoRec IgsOptions[] = { 180 { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, 181 { -1, NULL, OPTV_NONE, {0}, FALSE} 182}; 183 184/* Symbols needed from other modules */ 185static const char *fbSymbols[] = { 186 "fbPictureInit", 187 "fbScreenInit", 188 NULL 189}; 190static const char *shadowSymbols[] = { 191 "shadowAdd", 192 "shadowSetup", 193 "shadowUpdatePacked", 194 "shadowUpdatePackedWeak", 195 "shadowUpdateRotatePacked", 196 "shadowUpdateRotatePackedWeak", 197 NULL 198}; 199 200static const char *ramdacSymbols[] = { 201 "xf86CreateCursorInfoRec", 202 "xf86DestroyCursorInfoRec", 203 "xf86InitCursor", 204 NULL 205}; 206 207#ifdef XFree86LOADER 208static XF86ModuleVersionInfo IgsVersRec = { 209 "igs", 210 "The NetBSD Foundation", 211 MODINFOSTRING1, 212 MODINFOSTRING2, 213 XORG_VERSION_CURRENT, 214 PACKAGE_VERSION_MAJOR, 215 PACKAGE_VERSION_MINOR, 216 PACKAGE_VERSION_PATCHLEVEL, 217 ABI_CLASS_VIDEODRV, 218 ABI_VIDEODRV_VERSION, 219 NULL, 220 {0, 0, 0, 0} 221}; 222 223_X_EXPORT XF86ModuleData igsModuleData = { &IgsVersRec, IgsSetup, NULL }; 224 225static pointer 226IgsSetup(pointer module, pointer opts, int *errmaj, int *errmin) 227{ 228 static Bool setupDone = FALSE; 229 const char *osname; 230 231 /* Check that we're being loaded on a OpenBSD or NetBSD system */ 232 LoaderGetOS(&osname, NULL, NULL, NULL); 233 if (!osname || (strcmp(osname, "openbsd") != 0 && 234 strcmp(osname, "netbsd") != 0)) { 235 if (errmaj) 236 *errmaj = LDR_BADOS; 237 if (errmin) 238 *errmin = 0; 239 return NULL; 240 } 241 if (!setupDone) { 242 setupDone = TRUE; 243 xf86AddDriver(&IGS, module, HaveDriverFuncs); 244 LoaderRefSymLists(fbSymbols, shadowSymbols, ramdacSymbols, 245 NULL); 246 return (pointer)1; 247 } else { 248 if (errmaj != NULL) 249 *errmaj = LDR_ONCEONLY; 250 return NULL; 251 } 252} 253#endif /* XFree86LOADER */ 254 255static Bool 256IgsGetRec(ScrnInfoPtr pScrn) 257{ 258 259 if (pScrn->driverPrivate != NULL) 260 return TRUE; 261 262 pScrn->driverPrivate = xnfcalloc(sizeof(IgsRec), 1); 263 return TRUE; 264} 265 266static void 267IgsFreeRec(ScrnInfoPtr pScrn) 268{ 269 270 if (pScrn->driverPrivate == NULL) 271 return; 272 xfree(pScrn->driverPrivate); 273 pScrn->driverPrivate = NULL; 274} 275 276static const OptionInfoRec * 277IgsAvailableOptions(int chipid, int busid) 278{ 279 return IgsOptions; 280} 281 282static void 283IgsIdentify(int flags) 284{ 285 xf86PrintChipsets(IGS_NAME, "driver for IGS CyberPro 2010", 286 IgsChipsets); 287} 288 289#define priv_open_device(n) open(n,O_RDWR|O_NONBLOCK|O_EXCL) 290 291/* Open the framebuffer device */ 292static int 293igs_open(char *dev) 294{ 295 int fd = -1; 296 297 /* try argument from XF86Config first */ 298 if (dev == NULL || ((fd = priv_open_device(dev)) == -1)) { 299 /* second: environment variable */ 300 dev = getenv("XDEVICE"); 301 if (dev == NULL || ((fd = priv_open_device(dev)) == -1)) { 302 /* last try: default device */ 303 dev = IGS_DEFAULT_DEV; 304 if ((fd = priv_open_device(dev)) == -1) { 305 return -1; 306 } 307 } 308 } 309 return fd; 310} 311/* Map the framebuffer's memory */ 312static pointer 313igs_mmap(size_t len, off_t off, int fd) 314{ 315 int pagemask, mapsize; 316 caddr_t addr; 317 pointer mapaddr; 318 319 pagemask = getpagesize() - 1; 320 mapsize = ((int) len + pagemask) & ~pagemask; 321 addr = 0; 322 323 /* 324 * try and make it private first, that way once we get it, an 325 * interloper, e.g. another server, can't get this frame buffer, 326 * and if another server already has it, this one won't. 327 */ 328 mapaddr = (pointer) mmap(addr, mapsize, 329 PROT_READ | PROT_WRITE, MAP_SHARED, 330 fd, off); 331 if (mapaddr == MAP_FAILED) { 332 mapaddr = NULL; 333 } 334#if DEBUG 335 ErrorF("mmap returns: addr %p len 0x%x\n", mapaddr, mapsize); 336#endif 337 return mapaddr; 338} 339 340static int 341igsFindIsaDevice(GDevPtr dev) 342{ 343 int found = -1; 344 uint8_t id0, id1, rev; 345 346 /* read chip ID from extended VGA registers */ 347 id0 = igs_ext_read(IGS_EXT_CHIP_ID0); 348 id1 = igs_ext_read(IGS_EXT_CHIP_ID1); 349 rev = igs_ext_read(IGS_EXT_CHIP_REV); 350 xf86Msg(X_ERROR, "%s: %x %x %x\n", __func__, id0, id1, rev); 351 if ((id0 == 0xa4) && (id1 == 8)) 352 found = 0; 353 return found; 354} 355 356static Bool 357IgsProbe(DriverPtr drv, int flags) 358{ 359 ScrnInfoPtr pScrn = NULL; 360 IgsPtr cPtr; 361 Bool foundScreen = FALSE; 362 int numDevSections, numUsed; 363 GDevPtr *devSections; 364 int *usedChips; 365 int i, chipset, entity; 366 367 /* 368 * Find the config file Device sections that match this 369 * driver, and return if there are none. 370 */ 371 if ((numDevSections = xf86MatchDevice(IGS_DRIVER_NAME, 372 &devSections)) <= 0) { 373 return FALSE; 374 } 375 376 /* Isa Bus */ 377 if ((numDevSections = 378 xf86MatchDevice(IGS_DRIVER_NAME, &devSections)) > 0) { 379 for (i = 0; i < numDevSections; i++) { 380 if ((chipset = igsFindIsaDevice(devSections[i])) > -1) { 381 if ( xf86DoConfigure && xf86DoConfigurePass1 ) { 382 xf86AddBusDeviceToConfigure(IGS_DRIVER_NAME, BUS_ISA, 383 NULL, chipset); 384 } 385 if (flags & PROBE_DETECT) { 386 return TRUE; 387 } 388 if (!xf86CheckStrOption(devSections[i]->options, "BusID", 389 "ISA")) { 390 continue; 391 } 392 393 pScrn = NULL; 394 entity = xf86ClaimFbSlot(drv, 0, devSections[i], TRUE); 395 pScrn = xf86ConfigFbEntity(NULL, 0, entity, NULL, NULL, 396 NULL, NULL); 397 pScrn->driverVersion = IGS_VERSION; 398 pScrn->driverName = IGS_DRIVER_NAME; 399 pScrn->name = IGS_NAME; 400 pScrn->Probe = IgsProbe; 401 pScrn->PreInit = IgsPreInit; 402 pScrn->ScreenInit = IgsScreenInit; 403 pScrn->SwitchMode = IgsSwitchMode; 404 pScrn->AdjustFrame = NULL; 405 pScrn->EnterVT = IgsEnterVT; 406 pScrn->LeaveVT = IgsLeaveVT; 407 pScrn->ValidMode = IgsValidMode; 408 if (!IgsGetRec(pScrn)) { 409 return FALSE; 410 } 411 cPtr = IGSPTR(pScrn); 412 cPtr->Chipset = chipset; 413 cPtr->fb_paddr = 414 ((uint32_t)igs_ext_read(IGS_EXT_LINA_HI)) << 24; 415 xf86Msg(X_ERROR, "Aperture at %08lx\n", cPtr->fb_paddr); 416 } 417 } 418 } 419 420 xfree(devSections); 421 return foundScreen; 422} 423 424static Bool 425IgsPreInit(ScrnInfoPtr pScrn, int flags) 426{ 427 IgsPtr fPtr; 428 int default_depth, vram_size = 2 * 1024 * 1024; 429 char *dev, *s; 430 char *mod = NULL; 431 const char *reqSym = NULL; 432 Gamma zeros = {0.0, 0.0, 0.0}; 433 DisplayModePtr mode; 434 MessageType from; 435 436 if (flags & PROBE_DETECT) return FALSE; 437 438 TRACE_ENTER("PreInit"); 439 440 if (pScrn->numEntities != 1) return FALSE; 441 442 pScrn->monitor = pScrn->confScreen->monitor; 443 444 IgsGetRec(pScrn); 445 fPtr = IGSPTR(pScrn); 446 447 fPtr->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 448 449#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 450 pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; 451 pScrn->racIoFlags = pScrn->racMemFlags; 452#endif 453 454 dev = xf86FindOptionValue(fPtr->pEnt->device->options, "device"); 455 fPtr->fd = igs_open(dev); 456 if (fPtr->fd == -1) { 457 return FALSE; 458 } 459 460 if (ioctl(fPtr->fd, WSDISPLAYIO_GINFO, &fPtr->info) == -1) { 461 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 462 "ioctl WSDISPLAY_GINFO: %s\n", 463 strerror(errno)); 464 return FALSE; 465 } 466 467 /* Handle depth */ 468 default_depth = fPtr->info.depth <= 24 ? fPtr->info.depth : 24; 469 if (!xf86SetDepthBpp(pScrn, default_depth, default_depth, 470 fPtr->info.depth, 471 fPtr->info.depth >= 24 ? Support24bppFb|Support32bppFb : 0)) 472 return FALSE; 473 474 /* Check consistency */ 475 if (pScrn->bitsPerPixel != fPtr->info.depth) { 476 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 477 "specified depth (%d) or bpp (%d) doesn't match " 478 "framebuffer depth (%d)\n", pScrn->depth, 479 pScrn->bitsPerPixel, fPtr->info.depth); 480 return FALSE; 481 } 482 xf86PrintDepthBpp(pScrn); 483 484 /* Get the depth24 pixmap format */ 485 if (pScrn->depth == 24 && pix24bpp == 0) 486 pix24bpp = xf86GetBppFromDepth(pScrn, 24); 487 488 /* color weight */ 489 if (pScrn->depth > 8) { 490 rgb zeros = { 0, 0, 0 }, masks; 491 492 masks.red = 0; 493 masks.green = 0; 494 masks.blue = 0; 495 496 if (!xf86SetWeight(pScrn, zeros, masks)) 497 return FALSE; 498 } 499 500 /* visual init */ 501 if (!xf86SetDefaultVisual(pScrn, -1)) 502 return FALSE; 503 504 /* We don't currently support DirectColor at > 8bpp */ 505 if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { 506 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" 507 " (%s) is not supported at depth %d\n", 508 xf86GetVisualName(pScrn->defaultVisual), 509 pScrn->depth); 510 return FALSE; 511 } 512 513 xf86SetGamma(pScrn,zeros); 514 515 pScrn->progClock = TRUE; 516 pScrn->rgbBits = 8; 517 pScrn->chipset = "igs"; 518 pScrn->videoRam = vram_size; 519 520 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vidmem: %dk\n", 521 pScrn->videoRam/1024); 522 523 /* handle options */ 524 xf86CollectOptions(pScrn, NULL); 525 if (!(fPtr->Options = xalloc(sizeof(IgsOptions)))) 526 return FALSE; 527 memcpy(fPtr->Options, IgsOptions, sizeof(IgsOptions)); 528 xf86ProcessOptions(pScrn->scrnIndex, fPtr->pEnt->device->options, 529 fPtr->Options); 530 531 /* fake video mode struct */ 532 mode = (DisplayModePtr)xalloc(sizeof(DisplayModeRec)); 533 mode->prev = mode; 534 mode->next = mode; 535 mode->name = "igs current mode"; 536 mode->status = MODE_OK; 537 mode->type = M_T_BUILTIN; 538 mode->Clock = 0; 539 mode->HDisplay = fPtr->info.width; 540 mode->HSyncStart = 0; 541 mode->HSyncEnd = 0; 542 mode->HTotal = 0; 543 mode->HSkew = 0; 544 mode->VDisplay = fPtr->info.height; 545 mode->VSyncStart = 0; 546 mode->VSyncEnd = 0; 547 mode->VTotal = 0; 548 mode->VScan = 0; 549 mode->Flags = 0; 550 if (pScrn->modes != NULL) { 551 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 552 "Ignoring mode specification from screen section\n"); 553 } 554 pScrn->currentMode = pScrn->modes = mode; 555 pScrn->virtualX = fPtr->info.width; 556 pScrn->virtualY = fPtr->info.height; 557 pScrn->displayWidth = pScrn->virtualX; 558 559 /* Set the display resolution */ 560 xf86SetDpi(pScrn, 0, 0); 561 562 from = X_DEFAULT; 563 fPtr->HWCursor = TRUE; 564 if (xf86GetOptValBool(fPtr->Options, OPTION_HW_CURSOR, &fPtr->HWCursor)) 565 from = X_CONFIG; 566 if (xf86ReturnOptValBool(fPtr->Options, OPTION_SW_CURSOR, FALSE)) { 567 from = X_CONFIG; 568 fPtr->HWCursor = FALSE; 569 } 570 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 571 fPtr->HWCursor ? "HW" : "SW"); 572 573 if (xf86GetOptValBool(fPtr->Options, OPTION_NOACCEL, &fPtr->no_accel)) 574 from = X_CONFIG; 575 576 xf86DrvMsg(pScrn->scrnIndex, from, "%s acceleration\n", 577 fPtr->no_accel ? "disabling" : "enabling"); 578 579 /* Load bpp-specific modules */ 580 switch(pScrn->bitsPerPixel) { 581 default: 582 mod = "fb"; 583 break; 584 } 585 586 if (mod && xf86LoadSubModule(pScrn, mod) == NULL) { 587 IgsFreeRec(pScrn); 588 return FALSE; 589 } 590 591 if (xf86LoadSubModule(pScrn, "ramdac") == NULL) { 592 IgsFreeRec(pScrn); 593 return FALSE; 594 } 595 596 if (mod) { 597 if (reqSym) { 598 xf86LoaderReqSymbols(reqSym, NULL); 599 } else { 600 xf86LoaderReqSymLists(fbSymbols, NULL); 601 } 602 } 603 TRACE_EXIT("PreInit"); 604 return TRUE; 605} 606 607static Bool 608IgsCreateScreenResources(ScreenPtr pScreen) 609{ 610 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 611 IgsPtr fPtr = IGSPTR(pScrn); 612 PixmapPtr pPixmap; 613 Bool ret; 614 615 pScreen->CreateScreenResources = fPtr->CreateScreenResources; 616 ret = pScreen->CreateScreenResources(pScreen); 617 pScreen->CreateScreenResources = IgsCreateScreenResources; 618 619 if (!ret) 620 return FALSE; 621 622 pPixmap = pScreen->GetScreenPixmap(pScreen); 623 624 if (!shadowAdd(pScreen, pPixmap, shadowUpdatePackedWeak(), 625 IgsWindowLinear, FALSE, NULL)) { 626 return FALSE; 627 } 628 return TRUE; 629} 630 631 632static Bool 633IgsShadowInit(ScreenPtr pScreen) 634{ 635 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 636 IgsPtr fPtr = IGSPTR(pScrn); 637 638 if (!shadowSetup(pScreen)) 639 return FALSE; 640 fPtr->CreateScreenResources = pScreen->CreateScreenResources; 641 pScreen->CreateScreenResources = IgsCreateScreenResources; 642 643 return TRUE; 644} 645 646static Bool 647IgsScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 648{ 649 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 650 IgsPtr fPtr = IGSPTR(pScrn); 651 VisualPtr visual; 652 int ret, flags, ncolors; 653 int wsmode = WSDISPLAYIO_MODE_MAPPED; 654 size_t len; 655 656 TRACE_ENTER("IgsScreenInit"); 657#if DEBUG 658 ErrorF("\tbitsPerPixel=%d, depth=%d, defaultVisual=%s\n" 659 "\tmask: %x,%x,%x, offset: %u,%u,%u\n", 660 pScrn->bitsPerPixel, 661 pScrn->depth, 662 xf86GetVisualName(pScrn->defaultVisual), 663 pScrn->mask.red,pScrn->mask.green,pScrn->mask.blue, 664 pScrn->offset.red,pScrn->offset.green,pScrn->offset.blue); 665#endif 666 fPtr->linebytes = fPtr->info.width * (fPtr->info.depth >> 3); 667 668 /* Switch to graphics mode - required before mmap */ 669 if (ioctl(fPtr->fd, WSDISPLAYIO_SMODE, &wsmode) == -1) { 670 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 671 "ioctl WSDISPLAYIO_SMODE: %s\n", 672 strerror(errno)); 673 return FALSE; 674 } 675 676 /* find our aperture */ 677 678 /* assume 2MB for now, until I add actual RAM size probing */ 679 len = 2 * 1024 * 1024; 680 fPtr->fbmem = igs_mmap(len, fPtr->fb_paddr, fPtr->fd); 681 682 if (fPtr->fbmem == NULL) { 683 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 684 "igs_mmap(fb): %s\n", strerror(errno)); 685 return FALSE; 686 } 687 fPtr->fbmem_len = len - 1024; /* leave room for the hw cursor */ 688 689 fPtr->reg = igs_mmap(4096, 690 fPtr->fb_paddr + IGS_MEM_MMIO_SELECT + IGS_COP_BASE_B, fPtr->fd); 691 if (fPtr->reg == NULL) { 692 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 693 "igs_mmap(registers): %s\n", strerror(errno)); 694 return FALSE; 695 } 696 xf86Msg(X_ERROR, "0x10: %08x\n", *(uint32_t *)(fPtr->reg + 0x10)); 697 698 IgsSave(pScrn); 699 pScrn->vtSema = TRUE; 700 701 /* mi layer */ 702 miClearVisualTypes(); 703 if (pScrn->bitsPerPixel > 8) { 704 if (!miSetVisualTypes(pScrn->depth, TrueColorMask, 705 pScrn->rgbBits, TrueColor)) 706 return FALSE; 707 } else { 708 if (!miSetVisualTypes(pScrn->depth, 709 miGetDefaultVisualMask(pScrn->depth), 710 pScrn->rgbBits, pScrn->defaultVisual)) 711 return FALSE; 712 } 713 if (!miSetPixmapDepths()) 714 return FALSE; 715 716 fPtr->fbstart = fPtr->fbmem; 717 718 switch (pScrn->bitsPerPixel) { 719 case 8: 720 case 16: 721 case 24: 722 case 32: 723 ret = fbScreenInit(pScreen, 724 fPtr->fbstart, 725 pScrn->virtualX, pScrn->virtualY, 726 pScrn->xDpi, pScrn->yDpi, 727 pScrn->displayWidth, pScrn->bitsPerPixel); 728 break; 729 default: 730 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 731 "Unsupported bpp: %d", pScrn->bitsPerPixel); 732 return FALSE; 733 } /* case */ 734 735 if (!ret) 736 return FALSE; 737 738 if (pScrn->bitsPerPixel > 8) { 739 /* Fixup RGB ordering */ 740 visual = pScreen->visuals + pScreen->numVisuals; 741 while (--visual >= pScreen->visuals) { 742 if ((visual->class | DynamicClass) == DirectColor) { 743 visual->offsetRed = pScrn->offset.red; 744 visual->offsetGreen = pScrn->offset.green; 745 visual->offsetBlue = pScrn->offset.blue; 746 visual->redMask = pScrn->mask.red; 747 visual->greenMask = pScrn->mask.green; 748 visual->blueMask = pScrn->mask.blue; 749 } 750 } 751 } 752 753 if (pScrn->bitsPerPixel >= 8) { 754 if (!fbPictureInit(pScreen, NULL, 0)) 755 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 756 "RENDER extension initialisation failed."); 757 } 758 759#ifdef XFreeXDGA 760 IgsDGAInit(pScrn, pScreen); 761#endif 762 763 xf86SetBlackWhitePixels(pScreen); 764 xf86SetBackingStore(pScreen); 765 766 /* setup acceleration */ 767 if (!fPtr->no_accel) { 768 XF86ModReqInfo req; 769 int errmaj, errmin; 770 771 memset(&req, 0, sizeof(XF86ModReqInfo)); 772 req.majorversion = 2; 773 req.minorversion = 0; 774 if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req, 775 &errmaj, &errmin)) { 776 LoaderErrorMsg(NULL, "exa", errmaj, errmin); 777 return FALSE; 778 } 779 if (!IgsInitAccel(pScreen)) 780 fPtr->no_accel = 1; 781 } 782 783 /* software cursor */ 784 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 785 786 /* check for hardware cursor support */ 787 if (fPtr->HWCursor) 788 IgsSetupCursor(pScreen); 789 790 /* colormap */ 791 if (!miCreateDefColormap(pScreen)) 792 return FALSE; 793 flags = CMAP_RELOAD_ON_MODE_SWITCH; 794 ncolors = fPtr->info.cmsize; 795 /* on StaticGray visuals, fake a 256 entries colormap */ 796 if (ncolors == 0) 797 ncolors = 256; 798 if(!xf86HandleColormaps(pScreen, ncolors, 8, IgsLoadPalette, 799 NULL, flags)) 800 return FALSE; 801 802 pScreen->SaveScreen = IgsSaveScreen; 803 804#ifdef XvExtension 805 { 806 XF86VideoAdaptorPtr *ptr; 807 808 int n = xf86XVListGenericAdaptors(pScrn,&ptr); 809 if (n) { 810 xf86XVScreenInit(pScreen,ptr,n); 811 } 812 } 813#endif 814 815 /* Wrap the current CloseScreen function */ 816 fPtr->CloseScreen = pScreen->CloseScreen; 817 pScreen->CloseScreen = IgsCloseScreen; 818 819 TRACE_EXIT("IgsScreenInit"); 820 return TRUE; 821} 822 823static Bool 824IgsCloseScreen(int scrnIndex, ScreenPtr pScreen) 825{ 826 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 827 IgsPtr fPtr = IGSPTR(pScrn); 828 829 TRACE_ENTER("IgsCloseScreen"); 830 831 if (pScrn->vtSema) { 832 IgsRestore(pScrn); 833 if (munmap(fPtr->fbmem, fPtr->fbmem_len) == -1) { 834 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 835 "munmap: %s\n", strerror(errno)); 836 } 837 838 fPtr->fbmem = NULL; 839 } 840#ifdef XFreeXDGA 841 if (fPtr->pDGAMode) { 842 xfree(fPtr->pDGAMode); 843 fPtr->pDGAMode = NULL; 844 fPtr->nDGAMode = 0; 845 } 846#endif 847 pScrn->vtSema = FALSE; 848 849 /* unwrap CloseScreen */ 850 pScreen->CloseScreen = fPtr->CloseScreen; 851 return (*pScreen->CloseScreen)(scrnIndex, pScreen); 852} 853 854static void * 855IgsWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, 856 CARD32 *size, void *closure) 857{ 858 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 859 IgsPtr fPtr = IGSPTR(pScrn); 860 861 if (fPtr->linebytes) 862 *size = fPtr->linebytes; 863 else { 864 if (ioctl(fPtr->fd, WSDISPLAYIO_LINEBYTES, size) == -1) 865 return NULL; 866 fPtr->linebytes = *size; 867 } 868 return ((CARD8 *)fPtr->fbmem + row *fPtr->linebytes + offset); 869} 870 871static Bool 872IgsEnterVT(int scrnIndex, int flags) 873{ 874 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 875 876 TRACE_ENTER("EnterVT"); 877 pScrn->vtSema = TRUE; 878 return TRUE; 879} 880 881static void 882IgsLeaveVT(int scrnIndex, int flags) 883{ 884#if DEBUG 885 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 886#endif 887 888 TRACE_ENTER("LeaveVT"); 889} 890 891static Bool 892IgsSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 893{ 894#if DEBUG 895 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 896#endif 897 898 TRACE_ENTER("SwitchMode"); 899 /* Nothing else to do */ 900 return TRUE; 901} 902 903static int 904IgsValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) 905{ 906#if DEBUG 907 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 908#endif 909 910 TRACE_ENTER("ValidMode"); 911 return MODE_OK; 912} 913 914static void 915IgsLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, 916 LOCO *colors, VisualPtr pVisual) 917{ 918 IgsPtr fPtr = IGSPTR(pScrn); 919 struct wsdisplay_cmap cmap; 920 unsigned char red[256],green[256],blue[256]; 921 int i, indexMin=256, indexMax=0; 922 923 TRACE_ENTER("LoadPalette"); 924 925 cmap.count = 1; 926 cmap.red = red; 927 cmap.green = green; 928 cmap.blue = blue; 929 930 if (numColors == 1) { 931 /* Optimisation */ 932 cmap.index = indices[0]; 933 red[0] = colors[indices[0]].red; 934 green[0] = colors[indices[0]].green; 935 blue[0] = colors[indices[0]].blue; 936 if (ioctl(fPtr->fd,WSDISPLAYIO_PUTCMAP, &cmap) == -1) 937 ErrorF("ioctl FBIOPUTCMAP: %s\n", strerror(errno)); 938 } else { 939 /* Change all colors in 2 syscalls */ 940 /* and limit the data to be transfered */ 941 for (i = 0; i < numColors; i++) { 942 if (indices[i] < indexMin) 943 indexMin = indices[i]; 944 if (indices[i] > indexMax) 945 indexMax = indices[i]; 946 } 947 cmap.index = indexMin; 948 cmap.count = indexMax - indexMin + 1; 949 cmap.red = &red[indexMin]; 950 cmap.green = &green[indexMin]; 951 cmap.blue = &blue[indexMin]; 952 /* Get current map */ 953 if (ioctl(fPtr->fd, WSDISPLAYIO_GETCMAP, &cmap) == -1) 954 ErrorF("ioctl FBIOGETCMAP: %s\n", strerror(errno)); 955 /* Change the colors that require updating */ 956 for (i = 0; i < numColors; i++) { 957 red[indices[i]] = colors[indices[i]].red; 958 green[indices[i]] = colors[indices[i]].green; 959 blue[indices[i]] = colors[indices[i]].blue; 960 } 961 /* Write the colormap back */ 962 if (ioctl(fPtr->fd,WSDISPLAYIO_PUTCMAP, &cmap) == -1) 963 ErrorF("ioctl FBIOPUTCMAP: %s\n", strerror(errno)); 964 } 965 TRACE_EXIT("LoadPalette"); 966} 967 968static Bool 969IgsSaveScreen(ScreenPtr pScreen, int mode) 970{ 971 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 972 IgsPtr fPtr = IGSPTR(pScrn); 973 int state; 974 975 TRACE_ENTER("SaveScreen"); 976 977 if (!pScrn->vtSema) 978 return TRUE; 979 980 if (mode != SCREEN_SAVER_FORCER) { 981 state = xf86IsUnblank(mode)?WSDISPLAYIO_VIDEO_ON: 982 WSDISPLAYIO_VIDEO_OFF; 983 ioctl(fPtr->fd, 984 WSDISPLAYIO_SVIDEO, &state); 985 } 986 return TRUE; 987} 988 989 990static void 991IgsSave(ScrnInfoPtr pScrn) 992{ 993 IgsPtr fPtr = IGSPTR(pScrn); 994 995 TRACE_ENTER("IgsSave"); 996 997 if (fPtr->info.cmsize == 0) 998 return; 999 1000} 1001 1002static void 1003IgsRestore(ScrnInfoPtr pScrn) 1004{ 1005 IgsPtr fPtr = IGSPTR(pScrn); 1006 int mode; 1007 1008 TRACE_ENTER("IgsRestore"); 1009 1010 /* Clear the screen */ 1011 memset(fPtr->fbmem, 0, fPtr->fbmem_len); 1012 1013 /* Restore the text mode */ 1014 mode = WSDISPLAYIO_MODE_EMUL; 1015 if (ioctl(fPtr->fd, WSDISPLAYIO_SMODE, &mode) == -1) { 1016 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1017 "error setting text mode %s\n", strerror(errno)); 1018 } 1019 TRACE_EXIT("IgsRestore"); 1020} 1021 1022#ifdef XFreeXDGA 1023/*********************************************************************** 1024 * DGA stuff 1025 ***********************************************************************/ 1026 1027static Bool 1028IgsDGAOpenFramebuffer(ScrnInfoPtr pScrn, char **DeviceName, 1029 unsigned char **ApertureBase, int *ApertureSize, 1030 int *ApertureOffset, int *flags) 1031{ 1032 *DeviceName = NULL; /* No special device */ 1033 *ApertureBase = (unsigned char *)(pScrn->memPhysBase); 1034 *ApertureSize = pScrn->videoRam; 1035 *ApertureOffset = pScrn->fbOffset; 1036 *flags = 0; 1037 1038 return TRUE; 1039} 1040 1041static Bool 1042IgsDGASetMode(ScrnInfoPtr pScrn, DGAModePtr pDGAMode) 1043{ 1044 DisplayModePtr pMode; 1045 int scrnIdx = pScrn->pScreen->myNum; 1046 int frameX0, frameY0; 1047 1048 if (pDGAMode) { 1049 pMode = pDGAMode->mode; 1050 frameX0 = frameY0 = 0; 1051 } else { 1052 if (!(pMode = pScrn->currentMode)) 1053 return TRUE; 1054 1055 frameX0 = pScrn->frameX0; 1056 frameY0 = pScrn->frameY0; 1057 } 1058 1059 if (!(*pScrn->SwitchMode)(scrnIdx, pMode, 0)) 1060 return FALSE; 1061 (*pScrn->AdjustFrame)(scrnIdx, frameX0, frameY0, 0); 1062 1063 return TRUE; 1064} 1065 1066static void 1067IgsDGASetViewport(ScrnInfoPtr pScrn, int x, int y, int flags) 1068{ 1069 (*pScrn->AdjustFrame)(pScrn->pScreen->myNum, x, y, flags); 1070} 1071 1072static int 1073IgsDGAGetViewport(ScrnInfoPtr pScrn) 1074{ 1075 return (0); 1076} 1077 1078static DGAFunctionRec IgsDGAFunctions = 1079{ 1080 IgsDGAOpenFramebuffer, 1081 NULL, /* CloseFramebuffer */ 1082 IgsDGASetMode, 1083 IgsDGASetViewport, 1084 IgsDGAGetViewport, 1085 NULL, /* Sync */ 1086 NULL, /* FillRect */ 1087 NULL, /* BlitRect */ 1088 NULL, /* BlitTransRect */ 1089}; 1090 1091static void 1092IgsDGAAddModes(ScrnInfoPtr pScrn) 1093{ 1094 IgsPtr fPtr = IGSPTR(pScrn); 1095 DisplayModePtr pMode = pScrn->modes; 1096 DGAModePtr pDGAMode; 1097 1098 do { 1099 pDGAMode = xrealloc(fPtr->pDGAMode, 1100 (fPtr->nDGAMode + 1) * sizeof(DGAModeRec)); 1101 if (!pDGAMode) 1102 break; 1103 1104 fPtr->pDGAMode = pDGAMode; 1105 pDGAMode += fPtr->nDGAMode; 1106 (void)memset(pDGAMode, 0, sizeof(DGAModeRec)); 1107 1108 ++fPtr->nDGAMode; 1109 pDGAMode->mode = pMode; 1110 pDGAMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; 1111 pDGAMode->byteOrder = pScrn->imageByteOrder; 1112 pDGAMode->depth = pScrn->depth; 1113 pDGAMode->bitsPerPixel = pScrn->bitsPerPixel; 1114 pDGAMode->red_mask = pScrn->mask.red; 1115 pDGAMode->green_mask = pScrn->mask.green; 1116 pDGAMode->blue_mask = pScrn->mask.blue; 1117 pDGAMode->visualClass = pScrn->bitsPerPixel > 8 ? 1118 TrueColor : PseudoColor; 1119 pDGAMode->xViewportStep = 1; 1120 pDGAMode->yViewportStep = 1; 1121 pDGAMode->viewportWidth = pMode->HDisplay; 1122 pDGAMode->viewportHeight = pMode->VDisplay; 1123 1124 if (fPtr->linebytes) 1125 pDGAMode->bytesPerScanline = fPtr->linebytes; 1126 else { 1127 ioctl(fPtr->fd, WSDISPLAYIO_LINEBYTES, 1128 &fPtr->linebytes); 1129 pDGAMode->bytesPerScanline = fPtr->linebytes; 1130 } 1131 1132 pDGAMode->imageWidth = pMode->HDisplay; 1133 pDGAMode->imageHeight = pMode->VDisplay; 1134 pDGAMode->pixmapWidth = pDGAMode->imageWidth; 1135 pDGAMode->pixmapHeight = pDGAMode->imageHeight; 1136 pDGAMode->maxViewportX = pScrn->virtualX - 1137 pDGAMode->viewportWidth; 1138 pDGAMode->maxViewportY = pScrn->virtualY - 1139 pDGAMode->viewportHeight; 1140 1141 pDGAMode->address = fPtr->fbstart; 1142 1143 pMode = pMode->next; 1144 } while (pMode != pScrn->modes); 1145} 1146 1147static Bool 1148IgsDGAInit(ScrnInfoPtr pScrn, ScreenPtr pScreen) 1149{ 1150 IgsPtr fPtr = IGSPTR(pScrn); 1151 1152 if (pScrn->depth < 8) 1153 return FALSE; 1154 1155 if (!fPtr->nDGAMode) 1156 IgsDGAAddModes(pScrn); 1157 1158 return (DGAInit(pScreen, &IgsDGAFunctions, 1159 fPtr->pDGAMode, fPtr->nDGAMode)); 1160} 1161#endif 1162 1163static Bool 1164IgsDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, 1165 pointer ptr) 1166{ 1167 xorgHWFlags *flag; 1168 1169 switch (op) { 1170 case GET_REQUIRED_HW_INTERFACES: 1171 flag = (CARD32*)ptr; 1172 (*flag) = HW_IO | HW_MMIO; 1173 return TRUE; 1174 default: 1175 return FALSE; 1176 } 1177} 1178 1179