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