igs_driver.c revision 5c92892b
1/* $OpenBSD: wsfb_driver.c,v 1.19 2003/04/27 16:42:32 matthieu Exp $ */ 2/* $NetBSD: igs_driver.c,v 1.8 2011/05/30 15:11:33 christos 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 MODULEVENDORSTRING, 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 /* Load bpp-specific modules */ 575 switch(pScrn->bitsPerPixel) { 576 default: 577 mod = "fb"; 578 break; 579 } 580 581 if (mod && xf86LoadSubModule(pScrn, mod) == NULL) { 582 IgsFreeRec(pScrn); 583 return FALSE; 584 } 585 586 if (xf86LoadSubModule(pScrn, "ramdac") == NULL) { 587 IgsFreeRec(pScrn); 588 return FALSE; 589 } 590 591 if (mod) { 592 if (reqSym) { 593 xf86LoaderReqSymbols(reqSym, NULL); 594 } else { 595 xf86LoaderReqSymLists(fbSymbols, NULL); 596 } 597 } 598 TRACE_EXIT("PreInit"); 599 return TRUE; 600} 601 602static Bool 603IgsCreateScreenResources(ScreenPtr pScreen) 604{ 605 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 606 IgsPtr fPtr = IGSPTR(pScrn); 607 PixmapPtr pPixmap; 608 Bool ret; 609 610 pScreen->CreateScreenResources = fPtr->CreateScreenResources; 611 ret = pScreen->CreateScreenResources(pScreen); 612 pScreen->CreateScreenResources = IgsCreateScreenResources; 613 614 if (!ret) 615 return FALSE; 616 617 pPixmap = pScreen->GetScreenPixmap(pScreen); 618 619 if (!shadowAdd(pScreen, pPixmap, shadowUpdatePackedWeak(), 620 IgsWindowLinear, FALSE, NULL)) { 621 return FALSE; 622 } 623 return TRUE; 624} 625 626 627static Bool 628IgsShadowInit(ScreenPtr pScreen) 629{ 630 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 631 IgsPtr fPtr = IGSPTR(pScrn); 632 633 if (!shadowSetup(pScreen)) 634 return FALSE; 635 fPtr->CreateScreenResources = pScreen->CreateScreenResources; 636 pScreen->CreateScreenResources = IgsCreateScreenResources; 637 638 return TRUE; 639} 640 641static Bool 642IgsScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 643{ 644 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 645 IgsPtr fPtr = IGSPTR(pScrn); 646 VisualPtr visual; 647 int ret, flags, ncolors; 648 int wsmode = WSDISPLAYIO_MODE_DUMBFB; 649 size_t len; 650 651 TRACE_ENTER("IgsScreenInit"); 652#if DEBUG 653 ErrorF("\tbitsPerPixel=%d, depth=%d, defaultVisual=%s\n" 654 "\tmask: %x,%x,%x, offset: %u,%u,%u\n", 655 pScrn->bitsPerPixel, 656 pScrn->depth, 657 xf86GetVisualName(pScrn->defaultVisual), 658 pScrn->mask.red,pScrn->mask.green,pScrn->mask.blue, 659 pScrn->offset.red,pScrn->offset.green,pScrn->offset.blue); 660#endif 661 fPtr->linebytes = fPtr->info.width * (fPtr->info.depth >> 3); 662 663 /* Switch to graphics mode - required before mmap */ 664 if (ioctl(fPtr->fd, WSDISPLAYIO_SMODE, &wsmode) == -1) { 665 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 666 "ioctl WSDISPLAYIO_SMODE: %s\n", 667 strerror(errno)); 668 return FALSE; 669 } 670 671 /* find our aperturwe */ 672 673 /* assume 2MB for now, until I add actual RAM size probing */ 674 len = 2 * 1024 * 1024; 675 fPtr->fbmem = igs_mmap(len, fPtr->fb_paddr, fPtr->fd); 676 677 if (fPtr->fbmem == NULL) { 678 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 679 "igs_mmap(fb): %s\n", strerror(errno)); 680 return FALSE; 681 } 682 fPtr->fbmem_len = len - 1024; /* leave room for the hw cursor */ 683 684 fPtr->reg = igs_mmap(4096, 685 fPtr->fb_paddr + IGS_MEM_MMIO_SELECT + IGS_COP_BASE_B, fPtr->fd); 686 if (fPtr->reg == NULL) { 687 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 688 "igs_mmap(registers): %s\n", strerror(errno)); 689 return FALSE; 690 } 691 xf86Msg(X_ERROR, "0x10: %08x\n", *(uint32_t *)(fPtr->reg + 0x10)); 692 693 IgsSave(pScrn); 694 pScrn->vtSema = TRUE; 695 696 /* mi layer */ 697 miClearVisualTypes(); 698 if (pScrn->bitsPerPixel > 8) { 699 if (!miSetVisualTypes(pScrn->depth, TrueColorMask, 700 pScrn->rgbBits, TrueColor)) 701 return FALSE; 702 } else { 703 if (!miSetVisualTypes(pScrn->depth, 704 miGetDefaultVisualMask(pScrn->depth), 705 pScrn->rgbBits, pScrn->defaultVisual)) 706 return FALSE; 707 } 708 if (!miSetPixmapDepths()) 709 return FALSE; 710 711 fPtr->fbstart = fPtr->fbmem; 712 713 switch (pScrn->bitsPerPixel) { 714 case 8: 715 case 16: 716 case 24: 717 case 32: 718 ret = fbScreenInit(pScreen, 719 fPtr->fbstart, 720 pScrn->virtualX, pScrn->virtualY, 721 pScrn->xDpi, pScrn->yDpi, 722 pScrn->displayWidth, pScrn->bitsPerPixel); 723 break; 724 default: 725 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 726 "Unsupported bpp: %d", pScrn->bitsPerPixel); 727 return FALSE; 728 } /* case */ 729 730 if (!ret) 731 return FALSE; 732 733 if (pScrn->bitsPerPixel > 8) { 734 /* Fixup RGB ordering */ 735 visual = pScreen->visuals + pScreen->numVisuals; 736 while (--visual >= pScreen->visuals) { 737 if ((visual->class | DynamicClass) == DirectColor) { 738 visual->offsetRed = pScrn->offset.red; 739 visual->offsetGreen = pScrn->offset.green; 740 visual->offsetBlue = pScrn->offset.blue; 741 visual->redMask = pScrn->mask.red; 742 visual->greenMask = pScrn->mask.green; 743 visual->blueMask = pScrn->mask.blue; 744 } 745 } 746 } 747 748 if (pScrn->bitsPerPixel >= 8) { 749 if (!fbPictureInit(pScreen, NULL, 0)) 750 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 751 "RENDER extension initialisation failed."); 752 } 753 754#ifdef XFreeXDGA 755 IgsDGAInit(pScrn, pScreen); 756#endif 757 758 xf86SetBlackWhitePixels(pScreen); 759 miInitializeBackingStore(pScreen); 760 xf86SetBackingStore(pScreen); 761 762 /* setup acceleration */ 763 if (1) { 764 XF86ModReqInfo req; 765 int errmaj, errmin; 766 767 memset(&req, 0, sizeof(XF86ModReqInfo)); 768 req.majorversion = 2; 769 req.minorversion = 0; 770 if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req, 771 &errmaj, &errmin)) { 772 LoaderErrorMsg(NULL, "exa", errmaj, errmin); 773 return FALSE; 774 } 775 if (!IgsInitAccel(pScreen)) 776 return FALSE; 777 } 778 779 /* software cursor */ 780 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 781 782 /* check for hardware cursor support */ 783 if (fPtr->HWCursor) 784 IgsSetupCursor(pScreen); 785 786 /* colormap */ 787 if (!miCreateDefColormap(pScreen)) 788 return FALSE; 789 flags = CMAP_RELOAD_ON_MODE_SWITCH; 790 ncolors = fPtr->info.cmsize; 791 /* on StaticGray visuals, fake a 256 entries colormap */ 792 if (ncolors == 0) 793 ncolors = 256; 794 if(!xf86HandleColormaps(pScreen, ncolors, 8, IgsLoadPalette, 795 NULL, flags)) 796 return FALSE; 797 798 pScreen->SaveScreen = IgsSaveScreen; 799 800#ifdef XvExtension 801 { 802 XF86VideoAdaptorPtr *ptr; 803 804 int n = xf86XVListGenericAdaptors(pScrn,&ptr); 805 if (n) { 806 xf86XVScreenInit(pScreen,ptr,n); 807 } 808 } 809#endif 810 811 /* Wrap the current CloseScreen function */ 812 fPtr->CloseScreen = pScreen->CloseScreen; 813 pScreen->CloseScreen = IgsCloseScreen; 814 815 TRACE_EXIT("IgsScreenInit"); 816 return TRUE; 817} 818 819static Bool 820IgsCloseScreen(int scrnIndex, ScreenPtr pScreen) 821{ 822 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 823 IgsPtr fPtr = IGSPTR(pScrn); 824 825 TRACE_ENTER("IgsCloseScreen"); 826 827 if (pScrn->vtSema) { 828 IgsRestore(pScrn); 829 if (munmap(fPtr->fbmem, fPtr->fbmem_len) == -1) { 830 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 831 "munmap: %s\n", strerror(errno)); 832 } 833 834 fPtr->fbmem = NULL; 835 } 836#ifdef XFreeXDGA 837 if (fPtr->pDGAMode) { 838 xfree(fPtr->pDGAMode); 839 fPtr->pDGAMode = NULL; 840 fPtr->nDGAMode = 0; 841 } 842#endif 843 pScrn->vtSema = FALSE; 844 845 /* unwrap CloseScreen */ 846 pScreen->CloseScreen = fPtr->CloseScreen; 847 return (*pScreen->CloseScreen)(scrnIndex, pScreen); 848} 849 850static void * 851IgsWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, 852 CARD32 *size, void *closure) 853{ 854 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 855 IgsPtr fPtr = IGSPTR(pScrn); 856 857 if (fPtr->linebytes) 858 *size = fPtr->linebytes; 859 else { 860 if (ioctl(fPtr->fd, WSDISPLAYIO_LINEBYTES, size) == -1) 861 return NULL; 862 fPtr->linebytes = *size; 863 } 864 return ((CARD8 *)fPtr->fbmem + row *fPtr->linebytes + offset); 865} 866 867static Bool 868IgsEnterVT(int scrnIndex, int flags) 869{ 870 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 871 872 TRACE_ENTER("EnterVT"); 873 pScrn->vtSema = TRUE; 874 return TRUE; 875} 876 877static void 878IgsLeaveVT(int scrnIndex, int flags) 879{ 880#if DEBUG 881 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 882#endif 883 884 TRACE_ENTER("LeaveVT"); 885} 886 887static Bool 888IgsSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 889{ 890#if DEBUG 891 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 892#endif 893 894 TRACE_ENTER("SwitchMode"); 895 /* Nothing else to do */ 896 return TRUE; 897} 898 899static int 900IgsValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) 901{ 902#if DEBUG 903 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 904#endif 905 906 TRACE_ENTER("ValidMode"); 907 return MODE_OK; 908} 909 910static void 911IgsLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, 912 LOCO *colors, VisualPtr pVisual) 913{ 914 IgsPtr fPtr = IGSPTR(pScrn); 915 struct wsdisplay_cmap cmap; 916 unsigned char red[256],green[256],blue[256]; 917 int i, indexMin=256, indexMax=0; 918 919 TRACE_ENTER("LoadPalette"); 920 921 cmap.count = 1; 922 cmap.red = red; 923 cmap.green = green; 924 cmap.blue = blue; 925 926 if (numColors == 1) { 927 /* Optimisation */ 928 cmap.index = indices[0]; 929 red[0] = colors[indices[0]].red; 930 green[0] = colors[indices[0]].green; 931 blue[0] = colors[indices[0]].blue; 932 if (ioctl(fPtr->fd,WSDISPLAYIO_PUTCMAP, &cmap) == -1) 933 ErrorF("ioctl FBIOPUTCMAP: %s\n", strerror(errno)); 934 } else { 935 /* Change all colors in 2 syscalls */ 936 /* and limit the data to be transfered */ 937 for (i = 0; i < numColors; i++) { 938 if (indices[i] < indexMin) 939 indexMin = indices[i]; 940 if (indices[i] > indexMax) 941 indexMax = indices[i]; 942 } 943 cmap.index = indexMin; 944 cmap.count = indexMax - indexMin + 1; 945 cmap.red = &red[indexMin]; 946 cmap.green = &green[indexMin]; 947 cmap.blue = &blue[indexMin]; 948 /* Get current map */ 949 if (ioctl(fPtr->fd, WSDISPLAYIO_GETCMAP, &cmap) == -1) 950 ErrorF("ioctl FBIOGETCMAP: %s\n", strerror(errno)); 951 /* Change the colors that require updating */ 952 for (i = 0; i < numColors; i++) { 953 red[indices[i]] = colors[indices[i]].red; 954 green[indices[i]] = colors[indices[i]].green; 955 blue[indices[i]] = colors[indices[i]].blue; 956 } 957 /* Write the colormap back */ 958 if (ioctl(fPtr->fd,WSDISPLAYIO_PUTCMAP, &cmap) == -1) 959 ErrorF("ioctl FBIOPUTCMAP: %s\n", strerror(errno)); 960 } 961 TRACE_EXIT("LoadPalette"); 962} 963 964static Bool 965IgsSaveScreen(ScreenPtr pScreen, int mode) 966{ 967 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 968 IgsPtr fPtr = IGSPTR(pScrn); 969 int state; 970 971 TRACE_ENTER("SaveScreen"); 972 973 if (!pScrn->vtSema) 974 return TRUE; 975 976 if (mode != SCREEN_SAVER_FORCER) { 977 state = xf86IsUnblank(mode)?WSDISPLAYIO_VIDEO_ON: 978 WSDISPLAYIO_VIDEO_OFF; 979 ioctl(fPtr->fd, 980 WSDISPLAYIO_SVIDEO, &state); 981 } 982 return TRUE; 983} 984 985 986static void 987IgsSave(ScrnInfoPtr pScrn) 988{ 989 IgsPtr fPtr = IGSPTR(pScrn); 990 991 TRACE_ENTER("IgsSave"); 992 993 if (fPtr->info.cmsize == 0) 994 return; 995 996} 997 998static void 999IgsRestore(ScrnInfoPtr pScrn) 1000{ 1001 IgsPtr fPtr = IGSPTR(pScrn); 1002 int mode; 1003 1004 TRACE_ENTER("IgsRestore"); 1005 1006 /* Clear the screen */ 1007 memset(fPtr->fbmem, 0, fPtr->fbmem_len); 1008 1009 /* Restore the text mode */ 1010 mode = WSDISPLAYIO_MODE_EMUL; 1011 if (ioctl(fPtr->fd, WSDISPLAYIO_SMODE, &mode) == -1) { 1012 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1013 "error setting text mode %s\n", strerror(errno)); 1014 } 1015 TRACE_EXIT("IgsRestore"); 1016} 1017 1018#ifdef XFreeXDGA 1019/*********************************************************************** 1020 * DGA stuff 1021 ***********************************************************************/ 1022 1023static Bool 1024IgsDGAOpenFramebuffer(ScrnInfoPtr pScrn, char **DeviceName, 1025 unsigned char **ApertureBase, int *ApertureSize, 1026 int *ApertureOffset, int *flags) 1027{ 1028 *DeviceName = NULL; /* No special device */ 1029 *ApertureBase = (unsigned char *)(pScrn->memPhysBase); 1030 *ApertureSize = pScrn->videoRam; 1031 *ApertureOffset = pScrn->fbOffset; 1032 *flags = 0; 1033 1034 return TRUE; 1035} 1036 1037static Bool 1038IgsDGASetMode(ScrnInfoPtr pScrn, DGAModePtr pDGAMode) 1039{ 1040 DisplayModePtr pMode; 1041 int scrnIdx = pScrn->pScreen->myNum; 1042 int frameX0, frameY0; 1043 1044 if (pDGAMode) { 1045 pMode = pDGAMode->mode; 1046 frameX0 = frameY0 = 0; 1047 } else { 1048 if (!(pMode = pScrn->currentMode)) 1049 return TRUE; 1050 1051 frameX0 = pScrn->frameX0; 1052 frameY0 = pScrn->frameY0; 1053 } 1054 1055 if (!(*pScrn->SwitchMode)(scrnIdx, pMode, 0)) 1056 return FALSE; 1057 (*pScrn->AdjustFrame)(scrnIdx, frameX0, frameY0, 0); 1058 1059 return TRUE; 1060} 1061 1062static void 1063IgsDGASetViewport(ScrnInfoPtr pScrn, int x, int y, int flags) 1064{ 1065 (*pScrn->AdjustFrame)(pScrn->pScreen->myNum, x, y, flags); 1066} 1067 1068static int 1069IgsDGAGetViewport(ScrnInfoPtr pScrn) 1070{ 1071 return (0); 1072} 1073 1074static DGAFunctionRec IgsDGAFunctions = 1075{ 1076 IgsDGAOpenFramebuffer, 1077 NULL, /* CloseFramebuffer */ 1078 IgsDGASetMode, 1079 IgsDGASetViewport, 1080 IgsDGAGetViewport, 1081 NULL, /* Sync */ 1082 NULL, /* FillRect */ 1083 NULL, /* BlitRect */ 1084 NULL, /* BlitTransRect */ 1085}; 1086 1087static void 1088IgsDGAAddModes(ScrnInfoPtr pScrn) 1089{ 1090 IgsPtr fPtr = IGSPTR(pScrn); 1091 DisplayModePtr pMode = pScrn->modes; 1092 DGAModePtr pDGAMode; 1093 1094 do { 1095 pDGAMode = xrealloc(fPtr->pDGAMode, 1096 (fPtr->nDGAMode + 1) * sizeof(DGAModeRec)); 1097 if (!pDGAMode) 1098 break; 1099 1100 fPtr->pDGAMode = pDGAMode; 1101 pDGAMode += fPtr->nDGAMode; 1102 (void)memset(pDGAMode, 0, sizeof(DGAModeRec)); 1103 1104 ++fPtr->nDGAMode; 1105 pDGAMode->mode = pMode; 1106 pDGAMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; 1107 pDGAMode->byteOrder = pScrn->imageByteOrder; 1108 pDGAMode->depth = pScrn->depth; 1109 pDGAMode->bitsPerPixel = pScrn->bitsPerPixel; 1110 pDGAMode->red_mask = pScrn->mask.red; 1111 pDGAMode->green_mask = pScrn->mask.green; 1112 pDGAMode->blue_mask = pScrn->mask.blue; 1113 pDGAMode->visualClass = pScrn->bitsPerPixel > 8 ? 1114 TrueColor : PseudoColor; 1115 pDGAMode->xViewportStep = 1; 1116 pDGAMode->yViewportStep = 1; 1117 pDGAMode->viewportWidth = pMode->HDisplay; 1118 pDGAMode->viewportHeight = pMode->VDisplay; 1119 1120 if (fPtr->linebytes) 1121 pDGAMode->bytesPerScanline = fPtr->linebytes; 1122 else { 1123 ioctl(fPtr->fd, WSDISPLAYIO_LINEBYTES, 1124 &fPtr->linebytes); 1125 pDGAMode->bytesPerScanline = fPtr->linebytes; 1126 } 1127 1128 pDGAMode->imageWidth = pMode->HDisplay; 1129 pDGAMode->imageHeight = pMode->VDisplay; 1130 pDGAMode->pixmapWidth = pDGAMode->imageWidth; 1131 pDGAMode->pixmapHeight = pDGAMode->imageHeight; 1132 pDGAMode->maxViewportX = pScrn->virtualX - 1133 pDGAMode->viewportWidth; 1134 pDGAMode->maxViewportY = pScrn->virtualY - 1135 pDGAMode->viewportHeight; 1136 1137 pDGAMode->address = fPtr->fbstart; 1138 1139 pMode = pMode->next; 1140 } while (pMode != pScrn->modes); 1141} 1142 1143static Bool 1144IgsDGAInit(ScrnInfoPtr pScrn, ScreenPtr pScreen) 1145{ 1146 IgsPtr fPtr = IGSPTR(pScrn); 1147 1148 if (pScrn->depth < 8) 1149 return FALSE; 1150 1151 if (!fPtr->nDGAMode) 1152 IgsDGAAddModes(pScrn); 1153 1154 return (DGAInit(pScreen, &IgsDGAFunctions, 1155 fPtr->pDGAMode, fPtr->nDGAMode)); 1156} 1157#endif 1158 1159static Bool 1160IgsDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, 1161 pointer ptr) 1162{ 1163 xorgHWFlags *flag; 1164 1165 switch (op) { 1166 case GET_REQUIRED_HW_INTERFACES: 1167 flag = (CARD32*)ptr; 1168 (*flag) = HW_IO | HW_MMIO; 1169 return TRUE; 1170 default: 1171 return FALSE; 1172 } 1173} 1174 1175