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