cg14_driver.c revision a61c6651
1/* 2 * CG14 framebuffer driver. 3 * 4 * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com) 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 */ 23 24#ifdef HAVE_CONFIG_H 25#include "config.h" 26#endif 27 28#include <unistd.h> 29#include <sys/ioctl.h> 30#include <string.h> 31#include <sys/ioctl.h> 32 33#include "xf86.h" 34#include "xf86_OSproc.h" 35#include "mipointer.h" 36#include "micmap.h" 37 38#include "fb.h" 39#include "xf86cmap.h" 40#include "shadow.h" 41#include "cg14.h" 42 43#if 0 44#define static 45#endif 46 47#include "compat-api.h" 48 49static const OptionInfoRec * CG14AvailableOptions(int chipid, int busid); 50static void CG14Identify(int flags); 51static Bool CG14Probe(DriverPtr drv, int flags); 52static Bool CG14PreInit(ScrnInfoPtr pScrn, int flags); 53static Bool CG14ScreenInit(SCREEN_INIT_ARGS_DECL); 54static Bool CG14EnterVT(VT_FUNC_ARGS_DECL); 55static void CG14LeaveVT(VT_FUNC_ARGS_DECL); 56static Bool CG14CloseScreen(CLOSE_SCREEN_ARGS_DECL); 57static Bool CG14SaveScreen(ScreenPtr pScreen, int mode); 58static void CG14InitCplane24(ScrnInfoPtr pScrn); 59static void CG14ExitCplane24(ScrnInfoPtr pScrn); 60static void *CG14WindowLinear(ScreenPtr, CARD32, CARD32, int, CARD32 *, 61 void *); 62static Bool CG14DriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, 63 pointer ptr); 64 65/* Required if the driver supports mode switching */ 66static Bool CG14SwitchMode(SWITCH_MODE_ARGS_DECL); 67/* Required if the driver supports moving the viewport */ 68static void CG14AdjustFrame(ADJUST_FRAME_ARGS_DECL); 69 70/* Optional functions */ 71static void CG14FreeScreen(FREE_SCREEN_ARGS_DECL); 72static ModeStatus CG14ValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, 73 Bool verbose, int flags); 74 75void CG14Sync(ScrnInfoPtr pScrn); 76 77#define CG14_VERSION 4000 78#define CG14_NAME "SUNCG14" 79#define CG14_DRIVER_NAME "suncg14" 80#define CG14_MAJOR_VERSION PACKAGE_VERSION_MAJOR 81#define CG14_MINOR_VERSION PACKAGE_VERSION_MINOR 82#define CG14_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL 83 84/* 85 * This contains the functions needed by the server after loading the driver 86 * module. It must be supplied, and gets passed back by the SetupProc 87 * function in the dynamic case. In the static case, a reference to this 88 * is compiled in, and this requires that the name of this DriverRec be 89 * an upper-case version of the driver name. 90 */ 91 92_X_EXPORT DriverRec SUNCG14 = { 93 CG14_VERSION, 94 CG14_DRIVER_NAME, 95 CG14Identify, 96 CG14Probe, 97 CG14AvailableOptions, 98 NULL, 99 0, 100 CG14DriverFunc 101}; 102 103typedef enum { 104 OPTION_SHADOW_FB, 105 OPTION_HW_CURSOR, 106 OPTION_SW_CURSOR, 107 OPTION_ACCEL, 108 OPTION_XRENDER 109} CG14Opts; 110 111static const OptionInfoRec CG14Options[] = { 112 { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, TRUE}, 113 { OPTION_ACCEL, "Accel", OPTV_BOOLEAN, {0}, TRUE}, 114 { OPTION_XRENDER, "XRender", OPTV_BOOLEAN, {0}, FALSE}, 115 { -1, NULL, OPTV_NONE, {0}, FALSE } 116}; 117 118static MODULESETUPPROTO(cg14Setup); 119 120static XF86ModuleVersionInfo suncg14VersRec = 121{ 122 "suncg14", 123 MODULEVENDORSTRING, 124 MODINFOSTRING1, 125 MODINFOSTRING2, 126 XORG_VERSION_CURRENT, 127 CG14_MAJOR_VERSION, CG14_MINOR_VERSION, CG14_PATCHLEVEL, 128 ABI_CLASS_VIDEODRV, 129 ABI_VIDEODRV_VERSION, 130 MOD_CLASS_VIDEODRV, 131 {0,0,0,0} 132}; 133 134_X_EXPORT XF86ModuleData suncg14ModuleData = { 135 &suncg14VersRec, 136 cg14Setup, 137 NULL 138}; 139 140pointer 141cg14Setup(pointer module, pointer opts, int *errmaj, int *errmin) 142{ 143 static Bool setupDone = FALSE; 144 145 if (!setupDone) { 146 setupDone = TRUE; 147 xf86AddDriver(&SUNCG14, module, HaveDriverFuncs); 148 149 /* 150 * Modules that this driver always requires can be loaded here 151 * by calling LoadSubModule(). 152 */ 153 154 /* 155 * The return value must be non-NULL on success even though there 156 * is no TearDownProc. 157 */ 158 return (pointer)TRUE; 159 } else { 160 if (errmaj) *errmaj = LDR_ONCEONLY; 161 return NULL; 162 } 163} 164 165static Bool 166CG14GetRec(ScrnInfoPtr pScrn) 167{ 168 /* 169 * Allocate an Cg14Rec, and hook it into pScrn->driverPrivate. 170 * pScrn->driverPrivate is initialised to NULL, so we can check if 171 * the allocation has already been done. 172 */ 173 if (pScrn->driverPrivate != NULL) 174 return TRUE; 175 176 pScrn->driverPrivate = xnfcalloc(sizeof(Cg14Rec), 1); 177 return TRUE; 178} 179 180static void 181CG14FreeRec(ScrnInfoPtr pScrn) 182{ 183 Cg14Ptr pCg14; 184 185 if (pScrn->driverPrivate == NULL) 186 return; 187 188 pCg14 = GET_CG14_FROM_SCRN(pScrn); 189 190 free(pScrn->driverPrivate); 191 pScrn->driverPrivate = NULL; 192 193 return; 194} 195 196static const OptionInfoRec * 197CG14AvailableOptions(int chipid, int busid) 198{ 199 return CG14Options; 200} 201 202/* Mandatory */ 203static void 204CG14Identify(int flags) 205{ 206 xf86Msg(X_INFO, "%s: driver for CG14\n", CG14_NAME); 207} 208 209 210/* Mandatory */ 211static Bool 212CG14Probe(DriverPtr drv, int flags) 213{ 214 int i; 215 GDevPtr *devSections; 216 int *usedChips; 217 int numDevSections; 218 int numUsed; 219 Bool foundScreen = FALSE; 220 EntityInfoPtr pEnt; 221 222 /* 223 * The aim here is to find all cards that this driver can handle, 224 * and for the ones not already claimed by another driver, claim the 225 * slot, and allocate a ScrnInfoRec. 226 * 227 * This should be a minimal probe, and it should under no circumstances 228 * change the state of the hardware. Because a device is found, don't 229 * assume that it will be used. Don't do any initialisations other than 230 * the required ScrnInfoRec initialisations. Don't allocate any new 231 * data structures. 232 */ 233 234 /* 235 * Next we check, if there has been a chipset override in the config file. 236 * For this we must find out if there is an active device section which 237 * is relevant, i.e., which has no driver specified or has THIS driver 238 * specified. 239 */ 240 241 if ((numDevSections = xf86MatchDevice(CG14_DRIVER_NAME, 242 &devSections)) <= 0) { 243 /* 244 * There's no matching device section in the config file, so quit 245 * now. 246 */ 247 return FALSE; 248 } 249 250 /* 251 * We need to probe the hardware first. We then need to see how this 252 * fits in with what is given in the config file, and allow the config 253 * file info to override any contradictions. 254 */ 255 256 numUsed = xf86MatchSbusInstances(CG14_NAME, SBUS_DEVICE_CG14, 257 devSections, numDevSections, 258 drv, &usedChips); 259 260 free(devSections); 261 if (numUsed <= 0) 262 return FALSE; 263 264 if (flags & PROBE_DETECT) 265 foundScreen = TRUE; 266 else for (i = 0; i < numUsed; i++) { 267 pEnt = xf86GetEntityInfo(usedChips[i]); 268 269 /* 270 * Check that nothing else has claimed the slots. 271 */ 272 if(pEnt->active) { 273 ScrnInfoPtr pScrn; 274 275 /* Allocate a ScrnInfoRec and claim the slot */ 276 pScrn = xf86AllocateScreen(drv, 0); 277 278 /* Fill in what we can of the ScrnInfoRec */ 279 pScrn->driverVersion = CG14_VERSION; 280 pScrn->driverName = CG14_DRIVER_NAME; 281 pScrn->name = CG14_NAME; 282 pScrn->Probe = CG14Probe; 283 pScrn->PreInit = CG14PreInit; 284 pScrn->ScreenInit = CG14ScreenInit; 285 pScrn->SwitchMode = CG14SwitchMode; 286 pScrn->AdjustFrame = CG14AdjustFrame; 287 pScrn->EnterVT = CG14EnterVT; 288 pScrn->LeaveVT = CG14LeaveVT; 289 pScrn->FreeScreen = CG14FreeScreen; 290 pScrn->ValidMode = CG14ValidMode; 291 xf86AddEntityToScreen(pScrn, pEnt->index); 292 foundScreen = TRUE; 293 } 294 free(pEnt); 295 } 296 free(usedChips); 297 return foundScreen; 298} 299 300/* Mandatory */ 301static Bool 302CG14PreInit(ScrnInfoPtr pScrn, int flags) 303{ 304 Cg14Ptr pCg14; 305 sbusDevicePtr psdp = NULL; 306 int i, from, size, len, reg[6], prom; 307 char *ptr; 308 309 if (flags & PROBE_DETECT) return FALSE; 310 311 /* 312 * Note: This function is only called once at server startup, and 313 * not at the start of each server generation. This means that 314 * only things that are persistent across server generations can 315 * be initialised here. xf86Screens[] is (pScrn is a pointer to one 316 * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex() 317 * are too, and should be used for data that must persist across 318 * server generations. 319 * 320 * Per-generation data should be allocated with 321 * AllocateScreenPrivateIndex() from the ScreenInit() function. 322 */ 323 324 /* Allocate the Cg14Rec driverPrivate */ 325 if (!CG14GetRec(pScrn)) { 326 return FALSE; 327 } 328 pCg14 = GET_CG14_FROM_SCRN(pScrn); 329 330 /* Set pScrn->monitor */ 331 pScrn->monitor = pScrn->confScreen->monitor; 332 333 /* This driver doesn't expect more than one entity per screen */ 334 if (pScrn->numEntities > 1) 335 return FALSE; 336 /* This is the general case */ 337 for (i = 0; i < pScrn->numEntities; i++) { 338 EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[i]); 339 340 /* CG14 is purely AFX, but we handle it like SBUS */ 341 if (pEnt->location.type == BUS_SBUS) { 342 psdp = xf86GetSbusInfoForEntity(pEnt->index); 343 pCg14->psdp = psdp; 344 } else 345 return FALSE; 346 } 347 if (psdp == NULL) 348 return FALSE; 349 350 pCg14->memsize = 4 * 1024 * 1024; /* always safe */ 351 len = 24; 352 prom = sparcPromInit(); 353 if ((ptr = sparcPromGetProperty(&psdp->node, "reg", &len))) { 354 if (len >= 24) { 355 memcpy(reg, ptr, 24); 356 size = reg[5]; 357 xf86Msg(X_INFO, "memsize from reg: %d MB\n", size >> 20); 358 if (size > pCg14->memsize) 359 pCg14->memsize = size; 360 } 361 } 362 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "found %d MB video memory\n", 363 pCg14->memsize >> 20); 364 /********************* 365 deal with depth 366 *********************/ 367 368 if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb|Support32bppFb)) 369 return FALSE; 370 371 /* Check that the returned depth is one we support */ 372 switch (pScrn->depth) { 373 case 32: 374 case 24: 375 case 16: 376 case 8: 377 /* OK */ 378 break; 379 default: 380 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 381 "Given depth (%d) is not supported by this driver\n", 382 pScrn->depth); 383 return FALSE; 384 } 385 386 /* Collect all of the relevant option flags (fill in pScrn->options) */ 387 xf86CollectOptions(pScrn, NULL); 388 /* Process the options */ 389 if (!(pCg14->Options = malloc(sizeof(CG14Options)))) 390 return FALSE; 391 memcpy(pCg14->Options, CG14Options, sizeof(CG14Options)); 392 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pCg14->Options); 393 pCg14->use_shadow = xf86ReturnOptValBool(pCg14->Options, OPTION_SHADOW_FB, 394 TRUE); 395 pCg14->use_accel = xf86ReturnOptValBool(pCg14->Options, OPTION_ACCEL, 396 TRUE); 397 pCg14->use_xrender = xf86ReturnOptValBool(pCg14->Options, OPTION_XRENDER, 398 FALSE); 399 400 if (pScrn->depth < 24) { 401 if (pCg14->use_xrender) 402 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling xrender on depth < 24\n"); 403 pCg14->use_xrender = FALSE; 404 } 405 406 /* 407 * This must happen after pScrn->display has been set because 408 * xf86SetWeight references it. 409 */ 410 if (pScrn->depth > 16) { 411 rgb weight = {0, 0, 0}; 412 rgb mask = {0xff, 0xff00, 0xff0000}; 413 414 if (!xf86SetWeight(pScrn, weight, mask)) { 415 return FALSE; 416 } 417 } else if (pScrn->depth > 8) { 418 rgb zeroes = {0, 0, 0}; 419 420 if (!xf86SetWeight(pScrn, zeroes, zeroes)) { 421 return FALSE; 422 } 423 } 424 if (!xf86SetDefaultVisual(pScrn, -1)) 425 return FALSE; 426 else if (pScrn->depth > 8) { 427 /* We don't currently support DirectColor */ 428 if (pScrn->defaultVisual != TrueColor) { 429 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" 430 " (%s) is not supported\n", 431 xf86GetVisualName(pScrn->defaultVisual)); 432 return FALSE; 433 } 434 } 435 436 /* 437 * The new cmap code requires this to be initialised. 438 */ 439 440 { 441 Gamma zeros = {0.0, 0.0, 0.0}; 442 443 if (!xf86SetGamma(pScrn, zeros)) { 444 return FALSE; 445 } 446 } 447 448 if (xf86LoadSubModule(pScrn, "fb") == NULL) { 449 CG14FreeRec(pScrn); 450 return FALSE; 451 } 452 453 if (pCg14->use_shadow) { 454 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using shadow framebuffer\n"); 455 if (xf86LoadSubModule(pScrn, "shadow") == NULL) { 456 CG14FreeRec(pScrn); 457 return FALSE; 458 } 459 } 460 461 from = X_DEFAULT; 462 pCg14->HWCursor = TRUE; 463 if (xf86GetOptValBool(pCg14->Options, OPTION_HW_CURSOR, &pCg14->HWCursor)) 464 from = X_CONFIG; 465 if (xf86ReturnOptValBool(pCg14->Options, OPTION_SW_CURSOR, FALSE)) { 466 from = X_CONFIG; 467 pCg14->HWCursor = FALSE; 468 } 469 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 470 pCg14->HWCursor ? "HW" : "SW"); 471 472 /********************* 473 set up clock and mode stuff 474 *********************/ 475 476 pScrn->progClock = TRUE; 477 478 if(pScrn->display->virtualX || pScrn->display->virtualY) { 479 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 480 "CG14 does not support a virtual desktop\n"); 481 pScrn->display->virtualX = 0; 482 pScrn->display->virtualY = 0; 483 } 484 485 xf86SbusUseBuiltinMode(pScrn, pCg14->psdp); 486 pScrn->currentMode = pScrn->modes; 487 pScrn->displayWidth = pScrn->virtualX; 488 489 /* Set display resolution */ 490 xf86SetDpi(pScrn, 0, 0); 491 492 return TRUE; 493} 494 495static void 496CG14UpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf) 497{ 498 shadowUpdatePacked(pScreen, pBuf); 499} 500 501static Bool 502CG14CreateScreenResources(ScreenPtr pScreen) 503{ 504 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 505 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 506 PixmapPtr pPixmap; 507 Bool ret; 508 509 pScreen->CreateScreenResources = pCg14->CreateScreenResources; 510 ret = pScreen->CreateScreenResources(pScreen); 511 pScreen->CreateScreenResources = CG14CreateScreenResources; 512 513 if (!ret) 514 return FALSE; 515 516 pPixmap = pScreen->GetScreenPixmap(pScreen); 517 518 if (!shadowAdd(pScreen, pPixmap, CG14UpdatePacked, 519 CG14WindowLinear, 0, NULL)) { 520 return FALSE; 521 } 522 return TRUE; 523} 524 525 526static Bool 527CG14ShadowInit(ScreenPtr pScreen) 528{ 529 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 530 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 531 532 if (!shadowSetup(pScreen)) { 533 return FALSE; 534 } 535 536 pCg14->CreateScreenResources = pScreen->CreateScreenResources; 537 pScreen->CreateScreenResources = CG14CreateScreenResources; 538 539 return TRUE; 540} 541/* Mandatory */ 542 543/* This gets called at the start of each server generation */ 544 545static Bool 546CG14ScreenInit(SCREEN_INIT_ARGS_DECL) 547{ 548 ScrnInfoPtr pScrn; 549 Cg14Ptr pCg14; 550 VisualPtr visual; 551 int ret, have_accel = 0; 552 553 /* 554 * First get the ScrnInfoRec 555 */ 556 pScrn = xf86ScreenToScrn(pScreen); 557 558 pCg14 = GET_CG14_FROM_SCRN(pScrn); 559 560 /* Map the CG14 memory */ 561 pCg14->fb = xf86MapSbusMem (pCg14->psdp, CG14_DIRECT_VOFF, pCg14->memsize); 562 pCg14->x32 = xf86MapSbusMem (pCg14->psdp, CG14_X32_VOFF, 563 (pCg14->psdp->width * pCg14->psdp->height)); 564 pCg14->xlut = xf86MapSbusMem (pCg14->psdp, CG14_XLUT_VOFF, 4096); 565 pCg14->curs = xf86MapSbusMem (pCg14->psdp, CG14_CURSOR_VOFF, 4096); 566 567 pCg14->sxreg = xf86MapSbusMem (pCg14->psdp, CG14_SXREG_VOFF, 4096); 568 pCg14->sxio = xf86MapSbusMem (pCg14->psdp, CG14_SXIO_VOFF, 0x04000000); 569 have_accel = (pCg14->sxreg != NULL) && (pCg14->sxio != NULL); 570 571 if (have_accel) { 572 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 573 "found kernel support for SX acceleration\n"); 574 } 575 have_accel = have_accel & pCg14->use_accel; 576 if (have_accel) { 577 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "using acceleration\n"); 578 if (pCg14->use_shadow) 579 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "disabling shadow\n"); 580 pCg14->use_shadow = FALSE; 581 } 582 583 pCg14->width = pCg14->psdp->width; 584 pCg14->height = pCg14->psdp->height; 585 586 if (! pCg14->fb || !pCg14->x32 || !pCg14->xlut || !pCg14->curs) { 587 xf86Msg(X_ERROR, 588 "can't mmap something: fd %08x x32 %08x xlut %08x cursor %08x\n", 589 (uint32_t)pCg14->fb, (uint32_t)pCg14->x32, (uint32_t)pCg14->xlut, 590 (uint32_t)pCg14->curs); 591 return FALSE; 592 } 593 594 /* Darken the screen for aesthetic reasons and set the viewport */ 595 CG14SaveScreen(pScreen, SCREEN_SAVER_ON); 596 597 /* 598 * The next step is to setup the screen's visuals, and initialise the 599 * framebuffer code. In cases where the framebuffer's default 600 * choices for things like visual layouts and bits per RGB are OK, 601 * this may be as simple as calling the framebuffer's ScreenInit() 602 * function. If not, the visuals will need to be setup before calling 603 * a fb ScreenInit() function and fixed up after. 604 */ 605 606 /* 607 * Reset visual list. 608 */ 609 miClearVisualTypes(); 610 611 /* Set the bits per RGB for 8bpp mode */ 612 pScrn->rgbBits = 8; 613 614 /* Setup the visuals we support. */ 615 if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), 616 pScrn->rgbBits, pScrn->defaultVisual)) 617 return FALSE; 618 619 miSetPixmapDepths (); 620 621 if (pCg14->use_shadow) { 622 pCg14->shadow = malloc(pScrn->virtualX * pScrn->virtualY * 4); 623 624 if (!pCg14->shadow) { 625 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 626 "Failed to allocate shadow framebuffer\n"); 627 return FALSE; 628 } 629 } 630 631 /* 632 * Call the framebuffer layer's ScreenInit function, and fill in other 633 * pScreen fields. 634 */ 635 636 CG14InitCplane24(pScrn); 637 638 ret = fbScreenInit(pScreen, pCg14->use_shadow ? pCg14->shadow : pCg14->fb, 639 pScrn->virtualX, 640 pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, 641 pScrn->virtualX, pScrn->bitsPerPixel); 642 643 if (!ret) 644 return FALSE; 645 646 /* must be after RGB ordering fixed */ 647 fbPictureInit (pScreen, 0, 0); 648 649 if (pCg14->use_shadow && !CG14ShadowInit(pScreen)) { 650 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 651 "shadow framebuffer initialization failed\n"); 652 return FALSE; 653 } 654 655 xf86SetBackingStore(pScreen); 656 xf86SetSilkenMouse(pScreen); 657 658 xf86SetBlackWhitePixels(pScreen); 659 660 if (pScrn->bitsPerPixel > 8) { 661 /* Fixup RGB ordering */ 662 visual = pScreen->visuals + pScreen->numVisuals; 663 while (--visual >= pScreen->visuals) { 664 if ((visual->class | DynamicClass) == DirectColor) { 665 visual->offsetRed = pScrn->offset.red; 666 visual->offsetGreen = pScrn->offset.green; 667 visual->offsetBlue = pScrn->offset.blue; 668 visual->redMask = pScrn->mask.red; 669 visual->greenMask = pScrn->mask.green; 670 visual->blueMask = pScrn->mask.blue; 671 } 672 } 673 } 674 675 /* setup acceleration */ 676 if (have_accel) { 677 XF86ModReqInfo req; 678 int errmaj, errmin; 679 680 memset(&req, 0, sizeof(XF86ModReqInfo)); 681 req.majorversion = 2; 682 req.minorversion = 0; 683 if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req, 684 &errmaj, &errmin)) { 685 LoaderErrorMsg(NULL, "exa", errmaj, errmin); 686 return FALSE; 687 } 688 if (!CG14InitAccel(pScreen)) 689 have_accel = FALSE; 690 } 691 692 693 /* Initialise cursor functions */ 694 miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); 695 696 /* check for hardware cursor support */ 697 if (pCg14->HWCursor) 698 CG14SetupCursor(pScreen); 699 700 /* Initialise default colourmap */ 701 if (!miCreateDefColormap(pScreen)) 702 return FALSE; 703 704 if(!xf86SbusHandleColormaps(pScreen, pCg14->psdp)) 705 return FALSE; 706 707 pCg14->CloseScreen = pScreen->CloseScreen; 708 pScreen->CloseScreen = CG14CloseScreen; 709 pScreen->SaveScreen = CG14SaveScreen; 710 711 /* Report any unused options (only for the first generation) */ 712 if (serverGeneration == 1) { 713 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 714 } 715 716 /* unblank the screen */ 717 CG14SaveScreen(pScreen, SCREEN_SAVER_OFF); 718 719 /* Done */ 720 return TRUE; 721} 722 723 724/* Usually mandatory */ 725static Bool 726CG14SwitchMode(SWITCH_MODE_ARGS_DECL) 727{ 728 xf86Msg(X_ERROR, "CG14SwitchMode\n"); 729 return TRUE; 730} 731 732 733/* 734 * This function is used to initialize the Start Address - the first 735 * displayed location in the video memory. 736 */ 737/* Usually mandatory */ 738static void 739CG14AdjustFrame(ADJUST_FRAME_ARGS_DECL) 740{ 741 /* we don't support virtual desktops */ 742 return; 743} 744 745/* 746 * This is called when VT switching back to the X server. Its job is 747 * to reinitialise the video mode. 748 */ 749 750/* Mandatory */ 751static Bool 752CG14EnterVT(VT_FUNC_ARGS_DECL) 753{ 754 SCRN_INFO_PTR(arg); 755 756 CG14InitCplane24 (pScrn); 757 return TRUE; 758} 759 760 761/* 762 * This is called when VT switching away from the X server. 763 */ 764 765/* Mandatory */ 766static void 767CG14LeaveVT(VT_FUNC_ARGS_DECL) 768{ 769 SCRN_INFO_PTR(arg); 770 771 CG14ExitCplane24 (pScrn); 772 return; 773} 774 775 776/* 777 * This is called at the end of each server generation. It restores the 778 * original (text) mode. It should really also unmap the video memory too. 779 */ 780 781/* Mandatory */ 782static Bool 783CG14CloseScreen(CLOSE_SCREEN_ARGS_DECL) 784{ 785 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 786 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 787 PixmapPtr pPixmap; 788 789 if (pCg14->use_shadow) { 790 791 pPixmap = pScreen->GetScreenPixmap(pScreen); 792 shadowRemove(pScreen, pPixmap); 793 pCg14->use_shadow = FALSE; 794 } 795 796 pScrn->vtSema = FALSE; 797 CG14ExitCplane24 (pScrn); 798 xf86UnmapSbusMem(pCg14->psdp, pCg14->fb, pCg14->memsize); 799 xf86UnmapSbusMem(pCg14->psdp, pCg14->x32, 800 (pCg14->psdp->width * pCg14->psdp->height)); 801 xf86UnmapSbusMem(pCg14->psdp, pCg14->xlut, 4096); 802 xf86UnmapSbusMem(pCg14->psdp, pCg14->curs, 4096); 803 804 pScreen->CloseScreen = pCg14->CloseScreen; 805 return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS); 806} 807 808static void * 809CG14WindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, 810 CARD32 *size, void *closure) 811{ 812 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 813 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 814 int mul = (pScrn->bitsPerPixel >> 3); 815 816 *size = pCg14->width * mul; 817 return (CARD8 *)pCg14->fb + row * (pCg14->width * mul) + offset; 818} 819 820/* Free up any per-generation data structures */ 821 822/* Optional */ 823static void 824CG14FreeScreen(FREE_SCREEN_ARGS_DECL) 825{ 826 SCRN_INFO_PTR(arg); 827 CG14FreeRec(pScrn); 828} 829 830 831/* Checks if a mode is suitable for the selected chipset. */ 832 833/* Optional */ 834static ModeStatus 835CG14ValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) 836{ 837 if (mode->Flags & V_INTERLACE) 838 return(MODE_BAD); 839 840 return(MODE_OK); 841} 842 843/* Do screen blanking */ 844 845/* Mandatory */ 846static Bool 847CG14SaveScreen(ScreenPtr pScreen, int mode) 848{ 849 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 850 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 851 int state; 852 switch(mode) { 853 case SCREEN_SAVER_ON: 854 case SCREEN_SAVER_CYCLE: 855 state = FBVIDEO_OFF; 856 ioctl(pCg14->psdp->fd, FBIOSVIDEO, &state); 857 break; 858 case SCREEN_SAVER_OFF: 859 case SCREEN_SAVER_FORCER: 860 state = FBVIDEO_ON; 861 ioctl(pCg14->psdp->fd, FBIOSVIDEO, &state); 862 break; 863 default: 864 return FALSE; 865 } 866 return TRUE; 867} 868 869/* 870 * This is the implementation of the Sync() function. 871 */ 872void 873CG14Sync(ScrnInfoPtr pScrn) 874{ 875 return; 876} 877 878/* 879 * This initializes the card for 24 bit mode. 880 */ 881static void 882CG14InitCplane24(ScrnInfoPtr pScrn) 883{ 884 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 885 int size, bpp = 0; 886 887 size = pScrn->virtualX * pScrn->virtualY; 888 switch (pScrn->bitsPerPixel) { 889 case 8: 890 case 16: 891 bpp = pScrn->bitsPerPixel; 892 break; 893 case 24: 894 case 32: 895 bpp = 32; 896 default: 897 xf86Msg(X_ERROR, "Unsupported depth %d\n", pScrn->bitsPerPixel); 898 } 899 if (bpp == 0) return; 900 ioctl (pCg14->psdp->fd, CG14_SET_PIXELMODE, &bpp); 901 memset (pCg14->fb, 0, size * (bpp >> 3)); 902 memset (pCg14->x32, 0, size); 903#ifndef __NetBSD__ 904 memset (pCg14->xlut, 0, 0x200); 905#endif 906} 907 908/* 909 * This initializes the card for 8 bit mode. 910 */ 911static void 912CG14ExitCplane24(ScrnInfoPtr pScrn) 913{ 914 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 915 int bpp = 8; 916 917 ioctl (pCg14->psdp->fd, CG14_SET_PIXELMODE, &bpp); 918} 919 920 921static Bool 922CG14DriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, 923 pointer ptr) 924{ 925 xorgHWFlags *flag; 926 927 switch (op) { 928 case GET_REQUIRED_HW_INTERFACES: 929 flag = (CARD32*)ptr; 930 (*flag) = HW_MMIO; 931 return TRUE; 932 default: 933 return FALSE; 934 } 935} 936