cg14_driver.c revision fe196524
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 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 /* Setup the visuals we support. */ 599 600 if (!miSetVisualTypes(pScrn->depth, TrueColorMask, 601 pScrn->rgbBits, pScrn->defaultVisual)) 602 return FALSE; 603 604 miSetPixmapDepths (); 605 606 if (pCg14->use_shadow) { 607 pCg14->shadow = malloc(pScrn->virtualX * pScrn->virtualY * 4); 608 609 if (!pCg14->shadow) { 610 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 611 "Failed to allocate shadow framebuffer\n"); 612 return FALSE; 613 } 614 } 615 616 /* 617 * Call the framebuffer layer's ScreenInit function, and fill in other 618 * pScreen fields. 619 */ 620 621 CG14InitCplane24(pScrn); 622 ret = fbScreenInit(pScreen, pCg14->use_shadow ? pCg14->shadow : pCg14->fb, 623 pScrn->virtualX, 624 pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, 625 pScrn->virtualX, pScrn->bitsPerPixel); 626 627 if (!ret) 628 return FALSE; 629 630 /* must be after RGB ordering fixed */ 631 fbPictureInit (pScreen, 0, 0); 632 633 if (pCg14->use_shadow && !CG14ShadowInit(pScreen)) { 634 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 635 "shadow framebuffer initialization failed\n"); 636 return FALSE; 637 } 638 639 xf86SetBackingStore(pScreen); 640 xf86SetSilkenMouse(pScreen); 641 642 xf86SetBlackWhitePixels(pScreen); 643 644 if (pScrn->bitsPerPixel > 8) { 645 /* Fixup RGB ordering */ 646 visual = pScreen->visuals + pScreen->numVisuals; 647 while (--visual >= pScreen->visuals) { 648 if ((visual->class | DynamicClass) == DirectColor) { 649 visual->offsetRed = pScrn->offset.red; 650 visual->offsetGreen = pScrn->offset.green; 651 visual->offsetBlue = pScrn->offset.blue; 652 visual->redMask = pScrn->mask.red; 653 visual->greenMask = pScrn->mask.green; 654 visual->blueMask = pScrn->mask.blue; 655 } 656 } 657 } 658 659 /* setup acceleration */ 660 if (have_accel) { 661 XF86ModReqInfo req; 662 int errmaj, errmin; 663 664 memset(&req, 0, sizeof(XF86ModReqInfo)); 665 req.majorversion = 2; 666 req.minorversion = 0; 667 if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req, 668 &errmaj, &errmin)) { 669 LoaderErrorMsg(NULL, "exa", errmaj, errmin); 670 return FALSE; 671 } 672 if (!CG14InitAccel(pScreen)) 673 have_accel = FALSE; 674 } 675 676 677 /* Initialise cursor functions */ 678 miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); 679 680 /* check for hardware cursor support */ 681 if (pCg14->HWCursor) 682 CG14SetupCursor(pScreen); 683 684 /* Initialise default colourmap */ 685 if (!miCreateDefColormap(pScreen)) 686 return FALSE; 687 688 pCg14->CloseScreen = pScreen->CloseScreen; 689 pScreen->CloseScreen = CG14CloseScreen; 690 pScreen->SaveScreen = CG14SaveScreen; 691 692 /* Report any unused options (only for the first generation) */ 693 if (serverGeneration == 1) { 694 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 695 } 696 697 /* unblank the screen */ 698 CG14SaveScreen(pScreen, SCREEN_SAVER_OFF); 699 700 /* Done */ 701 return TRUE; 702} 703 704 705/* Usually mandatory */ 706static Bool 707CG14SwitchMode(SWITCH_MODE_ARGS_DECL) 708{ 709 xf86Msg(X_ERROR, "CG14SwitchMode\n"); 710 return TRUE; 711} 712 713 714/* 715 * This function is used to initialize the Start Address - the first 716 * displayed location in the video memory. 717 */ 718/* Usually mandatory */ 719static void 720CG14AdjustFrame(ADJUST_FRAME_ARGS_DECL) 721{ 722 /* we don't support virtual desktops */ 723 return; 724} 725 726/* 727 * This is called when VT switching back to the X server. Its job is 728 * to reinitialise the video mode. 729 */ 730 731/* Mandatory */ 732static Bool 733CG14EnterVT(VT_FUNC_ARGS_DECL) 734{ 735 SCRN_INFO_PTR(arg); 736 737 CG14InitCplane24 (pScrn); 738 return TRUE; 739} 740 741 742/* 743 * This is called when VT switching away from the X server. 744 */ 745 746/* Mandatory */ 747static void 748CG14LeaveVT(VT_FUNC_ARGS_DECL) 749{ 750 SCRN_INFO_PTR(arg); 751 752 CG14ExitCplane24 (pScrn); 753 return; 754} 755 756 757/* 758 * This is called at the end of each server generation. It restores the 759 * original (text) mode. It should really also unmap the video memory too. 760 */ 761 762/* Mandatory */ 763static Bool 764CG14CloseScreen(CLOSE_SCREEN_ARGS_DECL) 765{ 766 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 767 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 768 PixmapPtr pPixmap; 769 770 if (pCg14->use_shadow) { 771 772 pPixmap = pScreen->GetScreenPixmap(pScreen); 773 shadowRemove(pScreen, pPixmap); 774 pCg14->use_shadow = FALSE; 775 } 776 777 pScrn->vtSema = FALSE; 778 CG14ExitCplane24 (pScrn); 779 xf86UnmapSbusMem(pCg14->psdp, pCg14->fb, 780 (pCg14->psdp->width * pCg14->psdp->height * 4)); 781 xf86UnmapSbusMem(pCg14->psdp, pCg14->x32, 782 (pCg14->psdp->width * pCg14->psdp->height)); 783 xf86UnmapSbusMem(pCg14->psdp, pCg14->xlut, 4096); 784 xf86UnmapSbusMem(pCg14->psdp, pCg14->curs, 4096); 785 786 pScreen->CloseScreen = pCg14->CloseScreen; 787 return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS); 788} 789 790static void * 791CG14WindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, 792 CARD32 *size, void *closure) 793{ 794 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 795 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 796 797 *size = pCg14->width << 2; 798 return (CARD8 *)pCg14->fb + row * (pCg14->width << 2) + offset; 799} 800 801/* Free up any per-generation data structures */ 802 803/* Optional */ 804static void 805CG14FreeScreen(FREE_SCREEN_ARGS_DECL) 806{ 807 SCRN_INFO_PTR(arg); 808 CG14FreeRec(pScrn); 809} 810 811 812/* Checks if a mode is suitable for the selected chipset. */ 813 814/* Optional */ 815static ModeStatus 816CG14ValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) 817{ 818 if (mode->Flags & V_INTERLACE) 819 return(MODE_BAD); 820 821 return(MODE_OK); 822} 823 824/* Do screen blanking */ 825 826/* Mandatory */ 827static Bool 828CG14SaveScreen(ScreenPtr pScreen, int mode) 829{ 830 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 831 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 832 int state; 833 switch(mode) { 834 case SCREEN_SAVER_ON: 835 case SCREEN_SAVER_CYCLE: 836 state = FBVIDEO_OFF; 837 ioctl(pCg14->psdp->fd, FBIOSVIDEO, &state); 838 break; 839 case SCREEN_SAVER_OFF: 840 case SCREEN_SAVER_FORCER: 841 state = FBVIDEO_ON; 842 ioctl(pCg14->psdp->fd, FBIOSVIDEO, &state); 843 break; 844 default: 845 return FALSE; 846 } 847 return TRUE; 848} 849 850/* 851 * This is the implementation of the Sync() function. 852 */ 853void 854CG14Sync(ScrnInfoPtr pScrn) 855{ 856 return; 857} 858 859/* 860 * This initializes the card for 24 bit mode. 861 */ 862static void 863CG14InitCplane24(ScrnInfoPtr pScrn) 864{ 865 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 866 int size, bpp; 867 868 size = pScrn->virtualX * pScrn->virtualY; 869 bpp = 32; 870 ioctl (pCg14->psdp->fd, CG14_SET_PIXELMODE, &bpp); 871 memset (pCg14->fb, 0, size * 4); 872 memset (pCg14->x32, 0, size); 873 memset (pCg14->xlut, 0, 0x200); 874} 875 876/* 877 * This initializes the card for 8 bit mode. 878 */ 879static void 880CG14ExitCplane24(ScrnInfoPtr pScrn) 881{ 882 Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn); 883 int bpp = 8; 884 885 ioctl (pCg14->psdp->fd, CG14_SET_PIXELMODE, &bpp); 886} 887 888 889static Bool 890CG14DriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, 891 pointer ptr) 892{ 893 xorgHWFlags *flag; 894 895 switch (op) { 896 case GET_REQUIRED_HW_INTERFACES: 897 flag = (CARD32*)ptr; 898 (*flag) = HW_MMIO; 899 return TRUE; 900 default: 901 return FALSE; 902 } 903} 904