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