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