cg14_driver.c revision 25ad54ca
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 /* Check that the returned depth is one we support */ 371 switch (pScrn->depth) { 372 case 32: 373 case 24: 374 case 8: 375 /* OK */ 376 break; 377 default: 378 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 379 "Given depth (%d) is not supported by this driver\n", 380 pScrn->depth); 381 return FALSE; 382 } 383 384 /* Collect all of the relevant option flags (fill in pScrn->options) */ 385 xf86CollectOptions(pScrn, NULL); 386 /* Process the options */ 387 if (!(pCg14->Options = malloc(sizeof(CG14Options)))) 388 return FALSE; 389 memcpy(pCg14->Options, CG14Options, sizeof(CG14Options)); 390 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pCg14->Options); 391 pCg14->use_shadow = xf86ReturnOptValBool(pCg14->Options, OPTION_SHADOW_FB, 392 TRUE); 393 pCg14->use_accel = xf86ReturnOptValBool(pCg14->Options, OPTION_ACCEL, 394 TRUE); 395 pCg14->use_xrender = xf86ReturnOptValBool(pCg14->Options, OPTION_XRENDER, 396 FALSE); 397 398 /* 399 * This must happen after pScrn->display has been set because 400 * xf86SetWeight references it. 401 */ 402 if (pScrn->depth > 8) { 403 rgb weight = {0, 0, 0}; 404 rgb mask = {0xff, 0xff00, 0xff0000}; 405 406 if (!xf86SetWeight(pScrn, weight, mask)) { 407 return FALSE; 408 } 409 } 410 411 if (!xf86SetDefaultVisual(pScrn, -1)) 412 return FALSE; 413 else if (pScrn->depth > 8) { 414 /* We don't currently support DirectColor */ 415 if (pScrn->defaultVisual != TrueColor) { 416 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" 417 " (%s) is not supported\n", 418 xf86GetVisualName(pScrn->defaultVisual)); 419 return FALSE; 420 } 421 } 422 423 /* 424 * The new cmap code requires this to be initialised. 425 */ 426 427 { 428 Gamma zeros = {0.0, 0.0, 0.0}; 429 430 if (!xf86SetGamma(pScrn, zeros)) { 431 return FALSE; 432 } 433 } 434 435 if (xf86LoadSubModule(pScrn, "fb") == NULL) { 436 CG14FreeRec(pScrn); 437 return FALSE; 438 } 439 440 if (pCg14->use_shadow) { 441 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using shadow framebuffer\n"); 442 if (xf86LoadSubModule(pScrn, "shadow") == NULL) { 443 CG14FreeRec(pScrn); 444 return FALSE; 445 } 446 } 447 448 from = X_DEFAULT; 449 pCg14->HWCursor = TRUE; 450 if (xf86GetOptValBool(pCg14->Options, OPTION_HW_CURSOR, &pCg14->HWCursor)) 451 from = X_CONFIG; 452 if (xf86ReturnOptValBool(pCg14->Options, OPTION_SW_CURSOR, FALSE)) { 453 from = X_CONFIG; 454 pCg14->HWCursor = FALSE; 455 } 456 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 457 pCg14->HWCursor ? "HW" : "SW"); 458 459 /********************* 460 set up clock and mode stuff 461 *********************/ 462 463 pScrn->progClock = TRUE; 464 465 if(pScrn->display->virtualX || pScrn->display->virtualY) { 466 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 467 "CG14 does not support a virtual desktop\n"); 468 pScrn->display->virtualX = 0; 469 pScrn->display->virtualY = 0; 470 } 471 472 xf86SbusUseBuiltinMode(pScrn, pCg14->psdp); 473 pScrn->currentMode = pScrn->modes; 474 pScrn->displayWidth = pScrn->virtualX; 475 476 /* Set display resolution */ 477 xf86SetDpi(pScrn, 0, 0); 478 479 return TRUE; 480} 481 482static void 483CG14UpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf) 484{ 485 shadowUpdatePacked(pScreen, pBuf); 486} 487 488static Bool 489CG14CreateScreenResources(ScreenPtr pScreen) 490{ 491 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 492 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 493 PixmapPtr pPixmap; 494 Bool ret; 495 496 pScreen->CreateScreenResources = pCg14->CreateScreenResources; 497 ret = pScreen->CreateScreenResources(pScreen); 498 pScreen->CreateScreenResources = CG14CreateScreenResources; 499 500 if (!ret) 501 return FALSE; 502 503 pPixmap = pScreen->GetScreenPixmap(pScreen); 504 505 if (!shadowAdd(pScreen, pPixmap, CG14UpdatePacked, 506 CG14WindowLinear, 0, NULL)) { 507 return FALSE; 508 } 509 return TRUE; 510} 511 512 513static Bool 514CG14ShadowInit(ScreenPtr pScreen) 515{ 516 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 517 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 518 519 if (!shadowSetup(pScreen)) { 520 return FALSE; 521 } 522 523 pCg14->CreateScreenResources = pScreen->CreateScreenResources; 524 pScreen->CreateScreenResources = CG14CreateScreenResources; 525 526 return TRUE; 527} 528/* Mandatory */ 529 530/* This gets called at the start of each server generation */ 531 532static Bool 533CG14ScreenInit(SCREEN_INIT_ARGS_DECL) 534{ 535 ScrnInfoPtr pScrn; 536 Cg14Ptr pCg14; 537 VisualPtr visual; 538 int ret, have_accel = 0; 539 540 /* 541 * First get the ScrnInfoRec 542 */ 543 pScrn = xf86ScreenToScrn(pScreen); 544 545 pCg14 = GET_CG14_FROM_SCRN(pScrn); 546 547 /* Map the CG14 memory */ 548 pCg14->fb = xf86MapSbusMem (pCg14->psdp, CG14_DIRECT_VOFF, pCg14->memsize); 549 pCg14->x32 = xf86MapSbusMem (pCg14->psdp, CG14_X32_VOFF, 550 (pCg14->psdp->width * pCg14->psdp->height)); 551 pCg14->xlut = xf86MapSbusMem (pCg14->psdp, CG14_XLUT_VOFF, 4096); 552 pCg14->curs = xf86MapSbusMem (pCg14->psdp, CG14_CURSOR_VOFF, 4096); 553 554 pCg14->sxreg = xf86MapSbusMem (pCg14->psdp, CG14_SXREG_VOFF, 4096); 555 pCg14->sxio = xf86MapSbusMem (pCg14->psdp, CG14_SXIO_VOFF, 0x04000000); 556 have_accel = (pCg14->sxreg != NULL) && (pCg14->sxio != NULL); 557 558 if (have_accel) { 559 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 560 "found kernel support for SX acceleration\n"); 561 } 562 have_accel = have_accel & pCg14->use_accel; 563 if (have_accel) { 564 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "using acceleration\n"); 565 if (pCg14->use_shadow) 566 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "disabling shadow\n"); 567 pCg14->use_shadow = FALSE; 568 } 569 570 pCg14->width = pCg14->psdp->width; 571 pCg14->height = pCg14->psdp->height; 572 573 if (! pCg14->fb || !pCg14->x32 || !pCg14->xlut || !pCg14->curs) { 574 xf86Msg(X_ERROR, 575 "can't mmap something: fd %08x x32 %08x xlut %08x cursor %08x\n", 576 (uint32_t)pCg14->fb, (uint32_t)pCg14->x32, (uint32_t)pCg14->xlut, 577 (uint32_t)pCg14->curs); 578 return FALSE; 579 } 580 581 /* Darken the screen for aesthetic reasons and set the viewport */ 582 CG14SaveScreen(pScreen, SCREEN_SAVER_ON); 583 584 /* 585 * The next step is to setup the screen's visuals, and initialise the 586 * framebuffer code. In cases where the framebuffer's default 587 * choices for things like visual layouts and bits per RGB are OK, 588 * this may be as simple as calling the framebuffer's ScreenInit() 589 * function. If not, the visuals will need to be setup before calling 590 * a fb ScreenInit() function and fixed up after. 591 */ 592 593 /* 594 * Reset visual list. 595 */ 596 miClearVisualTypes(); 597 598 /* Set the bits per RGB for 8bpp mode */ 599 pScrn->rgbBits = 8; 600 601 /* Setup the visuals we support. */ 602 if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), 603 pScrn->rgbBits, pScrn->defaultVisual)) 604 return FALSE; 605 606 miSetPixmapDepths (); 607 608 if (pCg14->use_shadow) { 609 pCg14->shadow = malloc(pScrn->virtualX * pScrn->virtualY * 4); 610 611 if (!pCg14->shadow) { 612 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 613 "Failed to allocate shadow framebuffer\n"); 614 return FALSE; 615 } 616 } 617 618 /* 619 * Call the framebuffer layer's ScreenInit function, and fill in other 620 * pScreen fields. 621 */ 622 623 CG14InitCplane24(pScrn); 624 625 ret = fbScreenInit(pScreen, pCg14->use_shadow ? pCg14->shadow : pCg14->fb, 626 pScrn->virtualX, 627 pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, 628 pScrn->virtualX, pScrn->bitsPerPixel); 629 630 if (!ret) 631 return FALSE; 632 633 /* must be after RGB ordering fixed */ 634 fbPictureInit (pScreen, 0, 0); 635 636 if (pCg14->use_shadow && !CG14ShadowInit(pScreen)) { 637 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 638 "shadow framebuffer initialization failed\n"); 639 return FALSE; 640 } 641 642 xf86SetBackingStore(pScreen); 643 xf86SetSilkenMouse(pScreen); 644 645 xf86SetBlackWhitePixels(pScreen); 646 647 if (pScrn->bitsPerPixel > 8) { 648 /* Fixup RGB ordering */ 649 visual = pScreen->visuals + pScreen->numVisuals; 650 while (--visual >= pScreen->visuals) { 651 if ((visual->class | DynamicClass) == DirectColor) { 652 visual->offsetRed = pScrn->offset.red; 653 visual->offsetGreen = pScrn->offset.green; 654 visual->offsetBlue = pScrn->offset.blue; 655 visual->redMask = pScrn->mask.red; 656 visual->greenMask = pScrn->mask.green; 657 visual->blueMask = pScrn->mask.blue; 658 } 659 } 660 } 661 662 /* setup acceleration */ 663 if (have_accel) { 664 XF86ModReqInfo req; 665 int errmaj, errmin; 666 667 memset(&req, 0, sizeof(XF86ModReqInfo)); 668 req.majorversion = 2; 669 req.minorversion = 0; 670 if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req, 671 &errmaj, &errmin)) { 672 LoaderErrorMsg(NULL, "exa", errmaj, errmin); 673 return FALSE; 674 } 675 if (!CG14InitAccel(pScreen)) 676 have_accel = FALSE; 677 } 678 679 680 /* Initialise cursor functions */ 681 miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); 682 683 /* check for hardware cursor support */ 684 if (pCg14->HWCursor) 685 CG14SetupCursor(pScreen); 686 687 /* Initialise default colourmap */ 688 if (!miCreateDefColormap(pScreen)) 689 return FALSE; 690 691 if(!xf86SbusHandleColormaps(pScreen, pCg14->psdp)) 692 return FALSE; 693 694 pCg14->CloseScreen = pScreen->CloseScreen; 695 pScreen->CloseScreen = CG14CloseScreen; 696 pScreen->SaveScreen = CG14SaveScreen; 697 698 /* Report any unused options (only for the first generation) */ 699 if (serverGeneration == 1) { 700 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 701 } 702 703 /* unblank the screen */ 704 CG14SaveScreen(pScreen, SCREEN_SAVER_OFF); 705 706 /* Done */ 707 return TRUE; 708} 709 710 711/* Usually mandatory */ 712static Bool 713CG14SwitchMode(SWITCH_MODE_ARGS_DECL) 714{ 715 xf86Msg(X_ERROR, "CG14SwitchMode\n"); 716 return TRUE; 717} 718 719 720/* 721 * This function is used to initialize the Start Address - the first 722 * displayed location in the video memory. 723 */ 724/* Usually mandatory */ 725static void 726CG14AdjustFrame(ADJUST_FRAME_ARGS_DECL) 727{ 728 /* we don't support virtual desktops */ 729 return; 730} 731 732/* 733 * This is called when VT switching back to the X server. Its job is 734 * to reinitialise the video mode. 735 */ 736 737/* Mandatory */ 738static Bool 739CG14EnterVT(VT_FUNC_ARGS_DECL) 740{ 741 SCRN_INFO_PTR(arg); 742 743 CG14InitCplane24 (pScrn); 744 return TRUE; 745} 746 747 748/* 749 * This is called when VT switching away from the X server. 750 */ 751 752/* Mandatory */ 753static void 754CG14LeaveVT(VT_FUNC_ARGS_DECL) 755{ 756 SCRN_INFO_PTR(arg); 757 758 CG14ExitCplane24 (pScrn); 759 return; 760} 761 762 763/* 764 * This is called at the end of each server generation. It restores the 765 * original (text) mode. It should really also unmap the video memory too. 766 */ 767 768/* Mandatory */ 769static Bool 770CG14CloseScreen(CLOSE_SCREEN_ARGS_DECL) 771{ 772 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 773 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 774 PixmapPtr pPixmap; 775 776 if (pCg14->use_shadow) { 777 778 pPixmap = pScreen->GetScreenPixmap(pScreen); 779 shadowRemove(pScreen, pPixmap); 780 pCg14->use_shadow = FALSE; 781 } 782 783 pScrn->vtSema = FALSE; 784 CG14ExitCplane24 (pScrn); 785 xf86UnmapSbusMem(pCg14->psdp, pCg14->fb, pCg14->memsize); 786 xf86UnmapSbusMem(pCg14->psdp, pCg14->x32, 787 (pCg14->psdp->width * pCg14->psdp->height)); 788 xf86UnmapSbusMem(pCg14->psdp, pCg14->xlut, 4096); 789 xf86UnmapSbusMem(pCg14->psdp, pCg14->curs, 4096); 790 791 pScreen->CloseScreen = pCg14->CloseScreen; 792 return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS); 793} 794 795static void * 796CG14WindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, 797 CARD32 *size, void *closure) 798{ 799 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 800 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 801 int shift = (pScrn->bitsPerPixel > 8) ? 2 : 0; 802 803 *size = pCg14->width << shift; 804 return (CARD8 *)pCg14->fb + row * (pCg14->width << shift) + offset; 805} 806 807/* Free up any per-generation data structures */ 808 809/* Optional */ 810static void 811CG14FreeScreen(FREE_SCREEN_ARGS_DECL) 812{ 813 SCRN_INFO_PTR(arg); 814 CG14FreeRec(pScrn); 815} 816 817 818/* Checks if a mode is suitable for the selected chipset. */ 819 820/* Optional */ 821static ModeStatus 822CG14ValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) 823{ 824 if (mode->Flags & V_INTERLACE) 825 return(MODE_BAD); 826 827 return(MODE_OK); 828} 829 830/* Do screen blanking */ 831 832/* Mandatory */ 833static Bool 834CG14SaveScreen(ScreenPtr pScreen, int mode) 835{ 836 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 837 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 838 int state; 839 switch(mode) { 840 case SCREEN_SAVER_ON: 841 case SCREEN_SAVER_CYCLE: 842 state = FBVIDEO_OFF; 843 ioctl(pCg14->psdp->fd, FBIOSVIDEO, &state); 844 break; 845 case SCREEN_SAVER_OFF: 846 case SCREEN_SAVER_FORCER: 847 state = FBVIDEO_ON; 848 ioctl(pCg14->psdp->fd, FBIOSVIDEO, &state); 849 break; 850 default: 851 return FALSE; 852 } 853 return TRUE; 854} 855 856/* 857 * This is the implementation of the Sync() function. 858 */ 859void 860CG14Sync(ScrnInfoPtr pScrn) 861{ 862 return; 863} 864 865/* 866 * This initializes the card for 24 bit mode. 867 */ 868static void 869CG14InitCplane24(ScrnInfoPtr pScrn) 870{ 871 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 872 int size, bpp; 873 874 size = pScrn->virtualX * pScrn->virtualY; 875 if (pScrn->bitsPerPixel > 8) { 876 bpp = 32; 877 } else 878 bpp = 8; 879 ioctl (pCg14->psdp->fd, CG14_SET_PIXELMODE, &bpp); 880 memset (pCg14->fb, 0, size * (bpp >> 3)); 881 memset (pCg14->x32, 0, size); 882 memset (pCg14->xlut, 0, 0x200); 883} 884 885/* 886 * This initializes the card for 8 bit mode. 887 */ 888static void 889CG14ExitCplane24(ScrnInfoPtr pScrn) 890{ 891 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 892 int bpp = 8; 893 894 ioctl (pCg14->psdp->fd, CG14_SET_PIXELMODE, &bpp); 895} 896 897 898static Bool 899CG14DriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, 900 pointer ptr) 901{ 902 xorgHWFlags *flag; 903 904 switch (op) { 905 case GET_REQUIRED_HW_INTERFACES: 906 flag = (CARD32*)ptr; 907 (*flag) = HW_MMIO; 908 return TRUE; 909 default: 910 return FALSE; 911 } 912} 913