ffb_driver.c revision 7a5333bc
1dbbd9e4bSmacallan/* 2dbbd9e4bSmacallan * Creator, Creator3D and Elite3D framebuffer driver. 3dbbd9e4bSmacallan * 4dbbd9e4bSmacallan * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com) 5dbbd9e4bSmacallan * 6dbbd9e4bSmacallan * Permission is hereby granted, free of charge, to any person obtaining a copy 7dbbd9e4bSmacallan * of this software and associated documentation files (the "Software"), to deal 8dbbd9e4bSmacallan * in the Software without restriction, including without limitation the rights 9dbbd9e4bSmacallan * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10dbbd9e4bSmacallan * copies of the Software, and to permit persons to whom the Software is 11dbbd9e4bSmacallan * furnished to do so, subject to the following conditions: 12dbbd9e4bSmacallan * 13dbbd9e4bSmacallan * The above copyright notice and this permission notice shall be included in 14dbbd9e4bSmacallan * all copies or substantial portions of the Software. 15dbbd9e4bSmacallan * 16dbbd9e4bSmacallan * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17dbbd9e4bSmacallan * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18dbbd9e4bSmacallan * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19dbbd9e4bSmacallan * JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20dbbd9e4bSmacallan * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21dbbd9e4bSmacallan * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22dbbd9e4bSmacallan */ 23dbbd9e4bSmacallan 24dbbd9e4bSmacallan#ifdef HAVE_CONFIG_H 25dbbd9e4bSmacallan#include "config.h" 26dbbd9e4bSmacallan#endif 27dbbd9e4bSmacallan 28dbbd9e4bSmacallan#include <string.h> 29dbbd9e4bSmacallan 30dbbd9e4bSmacallan#include "xf86.h" 31dbbd9e4bSmacallan#include "xf86_OSproc.h" 32dbbd9e4bSmacallan#include "mipointer.h" 33dbbd9e4bSmacallan#include "micmap.h" 34dbbd9e4bSmacallan#include "fb.h" 35dbbd9e4bSmacallan 36dbbd9e4bSmacallan#include "xf86cmap.h" 37dbbd9e4bSmacallan 38dbbd9e4bSmacallan#include "ffb.h" 39dbbd9e4bSmacallan 40dbbd9e4bSmacallanstatic const OptionInfoRec * FFBAvailableOptions(int chipid, int busid); 41dbbd9e4bSmacallanstatic void FFBIdentify(int flags); 42dbbd9e4bSmacallanstatic Bool FFBProbe(DriverPtr drv, int flags); 43dbbd9e4bSmacallanstatic Bool FFBPreInit(ScrnInfoPtr pScrn, int flags); 447a5333bcSmrgstatic Bool FFBScreenInit(SCREEN_INIT_ARGS_DECL); 457a5333bcSmrgstatic Bool FFBEnterVT(VT_FUNC_ARGS_DECL); 467a5333bcSmrgstatic void FFBLeaveVT(VT_FUNC_ARGS_DECL); 477a5333bcSmrgstatic Bool FFBCloseScreen(CLOSE_SCREEN_ARGS_DECL); 48dbbd9e4bSmacallanstatic Bool FFBSaveScreen(ScreenPtr pScreen, int mode); 49dbbd9e4bSmacallanstatic void FFBDPMSSet(ScrnInfoPtr pScrn, int mode, int flags); 50dbbd9e4bSmacallan 51dbbd9e4bSmacallan/* Required if the driver supports mode switching */ 527a5333bcSmrgstatic Bool FFBSwitchMode(SWITCH_MODE_ARGS_DECL); 53dbbd9e4bSmacallan/* Required if the driver supports moving the viewport */ 547a5333bcSmrgstatic void FFBAdjustFrame(ADJUST_FRAME_ARGS_DECL); 55dbbd9e4bSmacallan 56dbbd9e4bSmacallan/* Optional functions */ 577a5333bcSmrgstatic void FFBFreeScreen(FREE_SCREEN_ARGS_DECL); 587a5333bcSmrgstatic ModeStatus FFBValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, 59dbbd9e4bSmacallan Bool verbose, int flags); 60dbbd9e4bSmacallanstatic void FFBDPMSMode(ScrnInfoPtr pScrn, int DPMSMode, int flags); 61dbbd9e4bSmacallan/* ffb_dga.c */ 62dbbd9e4bSmacallanextern void FFB_InitDGA(ScreenPtr pScreen); 63dbbd9e4bSmacallan 64dbbd9e4bSmacallanvoid FFBSync(ScrnInfoPtr pScrn); 65dbbd9e4bSmacallan 665d1b25cdSmacallanstatic Bool FFBDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, 675d1b25cdSmacallan pointer ptr); 685d1b25cdSmacallan 69dbbd9e4bSmacallan#define FFB_VERSION 4000 70dbbd9e4bSmacallan#define FFB_NAME "SUNFFB" 71dbbd9e4bSmacallan#define FFB_DRIVER_NAME "sunffb" 72dbbd9e4bSmacallan#define FFB_MAJOR_VERSION PACKAGE_VERSION_MAJOR 73dbbd9e4bSmacallan#define FFB_MINOR_VERSION PACKAGE_VERSION_MINOR 74dbbd9e4bSmacallan#define FFB_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL 75dbbd9e4bSmacallan 76dbbd9e4bSmacallan/* 77dbbd9e4bSmacallan * This contains the functions needed by the server after loading the driver 78dbbd9e4bSmacallan * module. It must be supplied, and gets passed back by the SetupProc 79dbbd9e4bSmacallan * function in the dynamic case. In the static case, a reference to this 80dbbd9e4bSmacallan * is compiled in, and this requires that the name of this DriverRec be 81dbbd9e4bSmacallan * an upper-case version of the driver name. 82dbbd9e4bSmacallan */ 83dbbd9e4bSmacallan 84dbbd9e4bSmacallan_X_EXPORT DriverRec SUNFFB = { 85dbbd9e4bSmacallan FFB_VERSION, 86dbbd9e4bSmacallan FFB_DRIVER_NAME, 87dbbd9e4bSmacallan FFBIdentify, 88dbbd9e4bSmacallan FFBProbe, 89dbbd9e4bSmacallan FFBAvailableOptions, 90dbbd9e4bSmacallan NULL, 915d1b25cdSmacallan 0, 925d1b25cdSmacallan FFBDriverFunc 93dbbd9e4bSmacallan}; 94dbbd9e4bSmacallan 95dbbd9e4bSmacallantypedef enum { 96dbbd9e4bSmacallan OPTION_SW_CURSOR, 97dbbd9e4bSmacallan OPTION_HW_CURSOR, 98dbbd9e4bSmacallan OPTION_NOACCEL 99dbbd9e4bSmacallan} FFBOpts; 100dbbd9e4bSmacallan 101dbbd9e4bSmacallanstatic const OptionInfoRec FFBOptions[] = { 102dbbd9e4bSmacallan { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, 103dbbd9e4bSmacallan { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, 104dbbd9e4bSmacallan { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 105dbbd9e4bSmacallan { -1, NULL, OPTV_NONE, {0}, FALSE } 106dbbd9e4bSmacallan}; 107dbbd9e4bSmacallan 108dbbd9e4bSmacallan#ifdef XFree86LOADER 109dbbd9e4bSmacallan 110dbbd9e4bSmacallanstatic MODULESETUPPROTO(ffbSetup); 111dbbd9e4bSmacallan 112dbbd9e4bSmacallanstatic XF86ModuleVersionInfo sunffbVersRec = 113dbbd9e4bSmacallan{ 114dbbd9e4bSmacallan "sunffb", 115dbbd9e4bSmacallan MODULEVENDORSTRING, 116dbbd9e4bSmacallan MODINFOSTRING1, 117dbbd9e4bSmacallan MODINFOSTRING2, 118dbbd9e4bSmacallan XORG_VERSION_CURRENT, 119dbbd9e4bSmacallan FFB_MAJOR_VERSION, FFB_MINOR_VERSION, FFB_PATCHLEVEL, 120dbbd9e4bSmacallan ABI_CLASS_VIDEODRV, 121dbbd9e4bSmacallan ABI_VIDEODRV_VERSION, 122dbbd9e4bSmacallan MOD_CLASS_VIDEODRV, 123dbbd9e4bSmacallan {0,0,0,0} 124dbbd9e4bSmacallan}; 125dbbd9e4bSmacallan 126dbbd9e4bSmacallan_X_EXPORT XF86ModuleData sunffbModuleData = { &sunffbVersRec, ffbSetup, NULL }; 127dbbd9e4bSmacallan 128dbbd9e4bSmacallanpointer 129dbbd9e4bSmacallanffbSetup(pointer module, pointer opts, int *errmaj, int *errmin) 130dbbd9e4bSmacallan{ 131dbbd9e4bSmacallan static Bool setupDone = FALSE; 132dbbd9e4bSmacallan 133dbbd9e4bSmacallan if (!setupDone) { 134dbbd9e4bSmacallan setupDone = TRUE; 1355d1b25cdSmacallan xf86AddDriver(&SUNFFB, module, HaveDriverFuncs); 136dbbd9e4bSmacallan 137dbbd9e4bSmacallan /* 138dbbd9e4bSmacallan * Modules that this driver always requires can be loaded here 139dbbd9e4bSmacallan * by calling LoadSubModule(). 140dbbd9e4bSmacallan */ 141dbbd9e4bSmacallan 142dbbd9e4bSmacallan /* 143dbbd9e4bSmacallan * The return value must be non-NULL on success even though there 144dbbd9e4bSmacallan * is no TearDownProc. 145dbbd9e4bSmacallan */ 146dbbd9e4bSmacallan return (pointer)TRUE; 147dbbd9e4bSmacallan } else { 148dbbd9e4bSmacallan if (errmaj) *errmaj = LDR_ONCEONLY; 149dbbd9e4bSmacallan return NULL; 150dbbd9e4bSmacallan } 151dbbd9e4bSmacallan} 152dbbd9e4bSmacallan 153dbbd9e4bSmacallan#endif /* XFree86LOADER */ 154dbbd9e4bSmacallan 155dbbd9e4bSmacallanstatic Bool 156dbbd9e4bSmacallanFFBGetRec(ScrnInfoPtr pScrn) 157dbbd9e4bSmacallan{ 158dbbd9e4bSmacallan /* 159dbbd9e4bSmacallan * Allocate an FFBRec, and hook it into pScrn->driverPrivate. 160dbbd9e4bSmacallan * pScrn->driverPrivate is initialised to NULL, so we can check if 161dbbd9e4bSmacallan * the allocation has already been done. 162dbbd9e4bSmacallan */ 163dbbd9e4bSmacallan if (pScrn->driverPrivate != NULL) 164dbbd9e4bSmacallan return TRUE; 165dbbd9e4bSmacallan 166dbbd9e4bSmacallan pScrn->driverPrivate = xnfcalloc(sizeof(FFBRec), 1); 167dbbd9e4bSmacallan return TRUE; 168dbbd9e4bSmacallan} 169dbbd9e4bSmacallan 170dbbd9e4bSmacallanstatic void 171dbbd9e4bSmacallanFFBFreeRec(ScrnInfoPtr pScrn) 172dbbd9e4bSmacallan{ 173dbbd9e4bSmacallan FFBPtr pFfb; 174dbbd9e4bSmacallan 175dbbd9e4bSmacallan if (pScrn->driverPrivate == NULL) 176dbbd9e4bSmacallan return; 177dbbd9e4bSmacallan 178dbbd9e4bSmacallan pFfb = GET_FFB_FROM_SCRN(pScrn); 179dbbd9e4bSmacallan 1807a5333bcSmrg free(pScrn->driverPrivate); 181dbbd9e4bSmacallan pScrn->driverPrivate = NULL; 182dbbd9e4bSmacallan 183dbbd9e4bSmacallan return; 184dbbd9e4bSmacallan} 185dbbd9e4bSmacallan 186dbbd9e4bSmacallanstatic const OptionInfoRec * 187dbbd9e4bSmacallanFFBAvailableOptions(int chipid, int busid) 188dbbd9e4bSmacallan{ 189dbbd9e4bSmacallan return FFBOptions; 190dbbd9e4bSmacallan} 191dbbd9e4bSmacallan 192dbbd9e4bSmacallan/* Mandatory */ 193dbbd9e4bSmacallanstatic void 194dbbd9e4bSmacallanFFBIdentify(int flags) 195dbbd9e4bSmacallan{ 196dbbd9e4bSmacallan xf86Msg(X_INFO, "%s: driver for Creator, Creator 3D and Elite 3D\n", FFB_NAME); 197dbbd9e4bSmacallan} 198dbbd9e4bSmacallan 199dbbd9e4bSmacallan 200dbbd9e4bSmacallan/* Mandatory */ 201dbbd9e4bSmacallanstatic Bool 202dbbd9e4bSmacallanFFBProbe(DriverPtr drv, int flags) 203dbbd9e4bSmacallan{ 204dbbd9e4bSmacallan int i; 205dbbd9e4bSmacallan GDevPtr *devSections; 206dbbd9e4bSmacallan int *usedChips; 207dbbd9e4bSmacallan int numDevSections; 208dbbd9e4bSmacallan int numUsed; 209dbbd9e4bSmacallan Bool foundScreen = FALSE; 210dbbd9e4bSmacallan EntityInfoPtr pEnt; 211dbbd9e4bSmacallan 212dbbd9e4bSmacallan /* 213dbbd9e4bSmacallan * The aim here is to find all cards that this driver can handle, 214dbbd9e4bSmacallan * and for the ones not already claimed by another driver, claim the 215dbbd9e4bSmacallan * slot, and allocate a ScrnInfoRec. 216dbbd9e4bSmacallan * 217dbbd9e4bSmacallan * This should be a minimal probe, and it should under no circumstances 218dbbd9e4bSmacallan * change the state of the hardware. Because a device is found, don't 219dbbd9e4bSmacallan * assume that it will be used. Don't do any initialisations other than 220dbbd9e4bSmacallan * the required ScrnInfoRec initialisations. Don't allocate any new 221dbbd9e4bSmacallan * data structures. 222dbbd9e4bSmacallan */ 223dbbd9e4bSmacallan 224dbbd9e4bSmacallan /* 225dbbd9e4bSmacallan * Next we check, if there has been a chipset override in the config file. 226dbbd9e4bSmacallan * For this we must find out if there is an active device section which 227dbbd9e4bSmacallan * is relevant, i.e., which has no driver specified or has THIS driver 228dbbd9e4bSmacallan * specified. 229dbbd9e4bSmacallan */ 230dbbd9e4bSmacallan 231dbbd9e4bSmacallan if ((numDevSections = xf86MatchDevice(FFB_DRIVER_NAME, 232dbbd9e4bSmacallan &devSections)) <= 0) { 233dbbd9e4bSmacallan /* 234dbbd9e4bSmacallan * There's no matching device section in the config file, so quit 235dbbd9e4bSmacallan * now. 236dbbd9e4bSmacallan */ 237dbbd9e4bSmacallan return FALSE; 238dbbd9e4bSmacallan } 239dbbd9e4bSmacallan 240dbbd9e4bSmacallan /* 241dbbd9e4bSmacallan * We need to probe the hardware first. We then need to see how this 242dbbd9e4bSmacallan * fits in with what is given in the config file, and allow the config 243dbbd9e4bSmacallan * file info to override any contradictions. 244dbbd9e4bSmacallan */ 245dbbd9e4bSmacallan 246dbbd9e4bSmacallan numUsed = xf86MatchSbusInstances(FFB_NAME, SBUS_DEVICE_FFB, 247dbbd9e4bSmacallan devSections, numDevSections, 248dbbd9e4bSmacallan drv, &usedChips); 249dbbd9e4bSmacallan 2507a5333bcSmrg free(devSections); 251dbbd9e4bSmacallan if (numUsed <= 0) 252dbbd9e4bSmacallan return FALSE; 253dbbd9e4bSmacallan 254dbbd9e4bSmacallan if (flags & PROBE_DETECT) 255dbbd9e4bSmacallan foundScreen = TRUE; 256dbbd9e4bSmacallan else for (i = 0; i < numUsed; i++) { 257dbbd9e4bSmacallan pEnt = xf86GetEntityInfo(usedChips[i]); 258dbbd9e4bSmacallan 259dbbd9e4bSmacallan /* 260dbbd9e4bSmacallan * Check that nothing else has claimed the slots. 261dbbd9e4bSmacallan */ 262dbbd9e4bSmacallan if(pEnt->active) { 263dbbd9e4bSmacallan ScrnInfoPtr pScrn; 264dbbd9e4bSmacallan 265dbbd9e4bSmacallan /* Allocate a ScrnInfoRec and claim the slot */ 266dbbd9e4bSmacallan pScrn = xf86AllocateScreen(drv, 0); 267dbbd9e4bSmacallan 268dbbd9e4bSmacallan /* Fill in what we can of the ScrnInfoRec */ 269dbbd9e4bSmacallan pScrn->driverVersion = FFB_VERSION; 270dbbd9e4bSmacallan pScrn->driverName = FFB_DRIVER_NAME; 271dbbd9e4bSmacallan pScrn->name = FFB_NAME; 272dbbd9e4bSmacallan pScrn->Probe = FFBProbe; 273dbbd9e4bSmacallan pScrn->PreInit = FFBPreInit; 274dbbd9e4bSmacallan pScrn->ScreenInit = FFBScreenInit; 275dbbd9e4bSmacallan pScrn->SwitchMode = FFBSwitchMode; 276dbbd9e4bSmacallan pScrn->AdjustFrame = FFBAdjustFrame; 277dbbd9e4bSmacallan pScrn->EnterVT = FFBEnterVT; 278dbbd9e4bSmacallan pScrn->LeaveVT = FFBLeaveVT; 279dbbd9e4bSmacallan pScrn->FreeScreen = FFBFreeScreen; 280dbbd9e4bSmacallan pScrn->ValidMode = FFBValidMode; 281dbbd9e4bSmacallan xf86AddEntityToScreen(pScrn, pEnt->index); 282dbbd9e4bSmacallan foundScreen = TRUE; 283dbbd9e4bSmacallan } 2847a5333bcSmrg free(pEnt); 285dbbd9e4bSmacallan } 2867a5333bcSmrg free(usedChips); 287dbbd9e4bSmacallan return foundScreen; 288dbbd9e4bSmacallan} 289dbbd9e4bSmacallan 290dbbd9e4bSmacallan/* Mandatory */ 291dbbd9e4bSmacallanstatic Bool 292dbbd9e4bSmacallanFFBPreInit(ScrnInfoPtr pScrn, int flags) 293dbbd9e4bSmacallan{ 294dbbd9e4bSmacallan FFBPtr pFfb; 295dbbd9e4bSmacallan sbusDevicePtr psdp; 296dbbd9e4bSmacallan MessageType from; 297dbbd9e4bSmacallan int i; 298dbbd9e4bSmacallan 299dbbd9e4bSmacallan if (flags & PROBE_DETECT) return FALSE; 300dbbd9e4bSmacallan 301dbbd9e4bSmacallan /* 302dbbd9e4bSmacallan * Note: This function is only called once at server startup, and 303dbbd9e4bSmacallan * not at the start of each server generation. This means that 304dbbd9e4bSmacallan * only things that are persistent across server generations can 305dbbd9e4bSmacallan * be initialised here. xf86Screens[] is (pScrn is a pointer to one 306dbbd9e4bSmacallan * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex() 307dbbd9e4bSmacallan * are too, and should be used for data that must persist across 308dbbd9e4bSmacallan * server generations. 309dbbd9e4bSmacallan * 310dbbd9e4bSmacallan * Per-generation data should be allocated with 311dbbd9e4bSmacallan * AllocateScreenPrivateIndex() from the ScreenInit() function. 312dbbd9e4bSmacallan */ 313dbbd9e4bSmacallan 314dbbd9e4bSmacallan /* Allocate the FFBRec driverPrivate */ 315dbbd9e4bSmacallan if (!FFBGetRec(pScrn)) 316dbbd9e4bSmacallan return FALSE; 317dbbd9e4bSmacallan 318dbbd9e4bSmacallan pFfb = GET_FFB_FROM_SCRN(pScrn); 319dbbd9e4bSmacallan 320dbbd9e4bSmacallan /* Set pScrn->monitor */ 321dbbd9e4bSmacallan pScrn->monitor = pScrn->confScreen->monitor; 322dbbd9e4bSmacallan 323dbbd9e4bSmacallan /* This driver doesn't expect more than one entity per screen */ 324dbbd9e4bSmacallan if (pScrn->numEntities > 1) 325dbbd9e4bSmacallan return FALSE; 326dbbd9e4bSmacallan /* This is the general case */ 327dbbd9e4bSmacallan for (i = 0; i < pScrn->numEntities; i++) { 328dbbd9e4bSmacallan EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[i]); 329dbbd9e4bSmacallan 330dbbd9e4bSmacallan /* FFB is purely UPA (but we handle it as SBUS) */ 331dbbd9e4bSmacallan if (pEnt->location.type == BUS_SBUS) { 332dbbd9e4bSmacallan psdp = xf86GetSbusInfoForEntity(pEnt->index); 333dbbd9e4bSmacallan pFfb->psdp = psdp; 334dbbd9e4bSmacallan } else 335dbbd9e4bSmacallan return FALSE; 336dbbd9e4bSmacallan } 337dbbd9e4bSmacallan 338dbbd9e4bSmacallan /********************* 339dbbd9e4bSmacallan deal with depth 340dbbd9e4bSmacallan *********************/ 341dbbd9e4bSmacallan 342dbbd9e4bSmacallan if (!xf86SetDepthBpp(pScrn, 24, 0, 32, Support32bppFb)) { 343dbbd9e4bSmacallan return FALSE; 344dbbd9e4bSmacallan } else { 345dbbd9e4bSmacallan /* Check that the returned depth is one we support */ 346dbbd9e4bSmacallan switch (pScrn->depth) { 347dbbd9e4bSmacallan case 24: 348dbbd9e4bSmacallan /* OK */ 349dbbd9e4bSmacallan break; 350dbbd9e4bSmacallan default: 351dbbd9e4bSmacallan xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 352dbbd9e4bSmacallan "Given depth (%d) is not supported by this driver\n", 353dbbd9e4bSmacallan pScrn->depth); 354dbbd9e4bSmacallan return FALSE; 355dbbd9e4bSmacallan } 356dbbd9e4bSmacallan } 357dbbd9e4bSmacallan 358dbbd9e4bSmacallan /* Collect all of the relevant option flags (fill in pScrn->options) */ 359dbbd9e4bSmacallan xf86CollectOptions(pScrn, NULL); 360dbbd9e4bSmacallan /* Process the options */ 3617a5333bcSmrg if (!(pFfb->Options = malloc(sizeof(FFBOptions)))) 362dbbd9e4bSmacallan return FALSE; 363dbbd9e4bSmacallan memcpy(pFfb->Options, FFBOptions, sizeof(FFBOptions)); 364dbbd9e4bSmacallan xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pFfb->Options); 365dbbd9e4bSmacallan 366dbbd9e4bSmacallan /* 367dbbd9e4bSmacallan * This must happen after pScrn->display has been set because 368dbbd9e4bSmacallan * xf86SetWeight references it. 369dbbd9e4bSmacallan */ 370dbbd9e4bSmacallan if (pScrn->depth > 8) { 371dbbd9e4bSmacallan rgb weight = {8, 8, 8}; 372dbbd9e4bSmacallan rgb mask = {0xff, 0xff00, 0xff0000}; 373dbbd9e4bSmacallan 374dbbd9e4bSmacallan if (!xf86SetWeight(pScrn, weight, mask)) { 375dbbd9e4bSmacallan return FALSE; 376dbbd9e4bSmacallan } 377dbbd9e4bSmacallan } 378dbbd9e4bSmacallan 379dbbd9e4bSmacallan if (!xf86SetDefaultVisual(pScrn, -1)) 380dbbd9e4bSmacallan return FALSE; 381dbbd9e4bSmacallan 382dbbd9e4bSmacallan /* 383dbbd9e4bSmacallan * The new cmap code requires this to be initialised. 384dbbd9e4bSmacallan */ 385dbbd9e4bSmacallan 386dbbd9e4bSmacallan { 387dbbd9e4bSmacallan Gamma zeros = {0.0, 0.0, 0.0}; 388dbbd9e4bSmacallan 389dbbd9e4bSmacallan if (!xf86SetGamma(pScrn, zeros)) { 390dbbd9e4bSmacallan return FALSE; 391dbbd9e4bSmacallan } 392dbbd9e4bSmacallan } 393dbbd9e4bSmacallan 394dbbd9e4bSmacallan /* Set the bits per RGB for 8bpp mode */ 395dbbd9e4bSmacallan from = X_DEFAULT; 396dbbd9e4bSmacallan 397dbbd9e4bSmacallan /* determine whether we use hardware or software cursor */ 398dbbd9e4bSmacallan 399dbbd9e4bSmacallan pFfb->HWCursor = TRUE; 400dbbd9e4bSmacallan if (xf86GetOptValBool(pFfb->Options, OPTION_HW_CURSOR, &pFfb->HWCursor)) 401dbbd9e4bSmacallan from = X_CONFIG; 402dbbd9e4bSmacallan if (xf86ReturnOptValBool(pFfb->Options, OPTION_SW_CURSOR, FALSE)) { 403dbbd9e4bSmacallan from = X_CONFIG; 404dbbd9e4bSmacallan pFfb->HWCursor = FALSE; 405dbbd9e4bSmacallan } 406dbbd9e4bSmacallan 407dbbd9e4bSmacallan xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 408dbbd9e4bSmacallan pFfb->HWCursor ? "HW" : "SW"); 409dbbd9e4bSmacallan 410dbbd9e4bSmacallan if (xf86ReturnOptValBool(pFfb->Options, OPTION_NOACCEL, FALSE)) { 411dbbd9e4bSmacallan pFfb->NoAccel = TRUE; 412dbbd9e4bSmacallan xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); 413dbbd9e4bSmacallan } 414dbbd9e4bSmacallan 415dbbd9e4bSmacallan if (xf86LoadSubModule(pScrn, "fb") == NULL) { 416dbbd9e4bSmacallan FFBFreeRec(pScrn); 417dbbd9e4bSmacallan return FALSE; 418dbbd9e4bSmacallan } 419dbbd9e4bSmacallan 420dbbd9e4bSmacallan if (xf86LoadSubModule(pScrn, "xaa") == NULL) { 421dbbd9e4bSmacallan FFBFreeRec(pScrn); 422dbbd9e4bSmacallan return FALSE; 423dbbd9e4bSmacallan } 424dbbd9e4bSmacallan 425dbbd9e4bSmacallan if (pFfb->HWCursor && xf86LoadSubModule(pScrn, "ramdac") == NULL) { 426dbbd9e4bSmacallan FFBFreeRec(pScrn); 427dbbd9e4bSmacallan return FALSE; 428dbbd9e4bSmacallan } 429dbbd9e4bSmacallan 430dbbd9e4bSmacallan if (xf86LoadSubModule(pScrn, "dbe") == NULL) { 431dbbd9e4bSmacallan FFBFreeRec(pScrn); 432dbbd9e4bSmacallan return FALSE; 433dbbd9e4bSmacallan } 434dbbd9e4bSmacallan 435dbbd9e4bSmacallan 436dbbd9e4bSmacallan /********************* 437dbbd9e4bSmacallan set up clock and mode stuff 438dbbd9e4bSmacallan *********************/ 439dbbd9e4bSmacallan 440dbbd9e4bSmacallan pScrn->progClock = TRUE; 441dbbd9e4bSmacallan 442dbbd9e4bSmacallan if(pScrn->display->virtualX || pScrn->display->virtualY) { 443dbbd9e4bSmacallan xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 444dbbd9e4bSmacallan "FFB does not support a virtual desktop\n"); 445dbbd9e4bSmacallan pScrn->display->virtualX = 0; 446dbbd9e4bSmacallan pScrn->display->virtualY = 0; 447dbbd9e4bSmacallan } 448dbbd9e4bSmacallan 449dbbd9e4bSmacallan xf86SbusUseBuiltinMode(pScrn, pFfb->psdp); 450dbbd9e4bSmacallan pScrn->currentMode = pScrn->modes; 451dbbd9e4bSmacallan pScrn->displayWidth = pScrn->virtualX; 452dbbd9e4bSmacallan 453dbbd9e4bSmacallan /* Set display resolution */ 454dbbd9e4bSmacallan xf86SetDpi(pScrn, 0, 0); 455dbbd9e4bSmacallan 456dbbd9e4bSmacallan return TRUE; 457dbbd9e4bSmacallan} 458dbbd9e4bSmacallan 459dbbd9e4bSmacallan/* Determine the FFB/AFB board type. We need this information even 460dbbd9e4bSmacallan * if acceleration is disabled because the ramdac support layer needs 461dbbd9e4bSmacallan * to know what kind of FFB/AFB this is. 462dbbd9e4bSmacallan */ 463dbbd9e4bSmacallanstatic void 464dbbd9e4bSmacallanFFBProbeBoardType(FFBPtr pFfb) 465dbbd9e4bSmacallan{ 466dbbd9e4bSmacallan ffb_fbcPtr ffb = pFfb->regs; 467dbbd9e4bSmacallan volatile unsigned int *afb_fem; 468dbbd9e4bSmacallan unsigned int val; 469dbbd9e4bSmacallan 470dbbd9e4bSmacallan afb_fem = ((volatile unsigned int *) ((char *)ffb + 0x1540)); 471dbbd9e4bSmacallan val = *afb_fem; 472dbbd9e4bSmacallan val &= 0x7f; 473dbbd9e4bSmacallan 474dbbd9e4bSmacallan xf86Msg(X_INFO, "%s: ", pFfb->psdp->device); 475dbbd9e4bSmacallan if (val == 0x3f || val == 0x07 || val == 0x01) { 476dbbd9e4bSmacallan /* When firmware has not been loaded onto AFB we 477dbbd9e4bSmacallan * just assume it is an M6 board. 478dbbd9e4bSmacallan */ 479dbbd9e4bSmacallan if (val == 0x3f || val != 0x07) { 480dbbd9e4bSmacallan pFfb->ffb_type = afb_m6; 481dbbd9e4bSmacallan ErrorF("AFB: Detected Elite3D/M6.\n"); 482dbbd9e4bSmacallan } else { 483dbbd9e4bSmacallan pFfb->ffb_type = afb_m3; 484dbbd9e4bSmacallan ErrorF("AFB: Detected Elite3D/M3.\n"); 485dbbd9e4bSmacallan } 486dbbd9e4bSmacallan 487dbbd9e4bSmacallan /* These attributes are invariant on AFB. */ 488dbbd9e4bSmacallan pFfb->has_double_res = 0; 489dbbd9e4bSmacallan pFfb->has_z_buffer = 1; 490dbbd9e4bSmacallan pFfb->has_double_buffer = 1; 491dbbd9e4bSmacallan } else { 492dbbd9e4bSmacallan unsigned char sbits; 493e33a93fdSmrg 494dbbd9e4bSmacallan /* Read the board strapping bits twice, because sometimes 495dbbd9e4bSmacallan * the strapping pins can get misrouted to the bus interface 496dbbd9e4bSmacallan * on the first attempt. The second attempt will get the 497dbbd9e4bSmacallan * correct value. 498dbbd9e4bSmacallan */ 499dbbd9e4bSmacallan sbits = *((volatile unsigned char *)pFfb->strapping_bits); 500dbbd9e4bSmacallan sbits = *((volatile unsigned char *)pFfb->strapping_bits); 501dbbd9e4bSmacallan switch (sbits & 0x78) { 502dbbd9e4bSmacallan case (0x0 << 5) | (0x0 << 3): 503dbbd9e4bSmacallan pFfb->ffb_type = ffb1_prototype; 504dbbd9e4bSmacallan ErrorF("Detected FFB1 pre-FCS prototype, "); 505dbbd9e4bSmacallan break; 506dbbd9e4bSmacallan case (0x0 << 5) | (0x1 << 3): 507dbbd9e4bSmacallan pFfb->ffb_type = ffb1_standard; 508dbbd9e4bSmacallan ErrorF("Detected FFB1, "); 509dbbd9e4bSmacallan break; 510dbbd9e4bSmacallan case (0x0 << 5) | (0x3 << 3): 511dbbd9e4bSmacallan pFfb->ffb_type = ffb1_speedsort; 512dbbd9e4bSmacallan ErrorF("Detected FFB1-SpeedSort, "); 513dbbd9e4bSmacallan break; 514dbbd9e4bSmacallan case (0x1 << 5) | (0x0 << 3): 515dbbd9e4bSmacallan pFfb->ffb_type = ffb2_prototype; 516dbbd9e4bSmacallan ErrorF("Detected FFB2/vertical pre-FCS prototype, "); 517dbbd9e4bSmacallan break; 518dbbd9e4bSmacallan case (0x1 << 5) | (0x1 << 3): 519dbbd9e4bSmacallan pFfb->ffb_type = ffb2_vertical; 520dbbd9e4bSmacallan ErrorF("Detected FFB2/vertical, "); 521dbbd9e4bSmacallan break; 522dbbd9e4bSmacallan case (0x1 << 5) | (0x2 << 3): 523dbbd9e4bSmacallan pFfb->ffb_type = ffb2_vertical_plus; 524dbbd9e4bSmacallan ErrorF("Detected FFB2+/vertical, "); 525dbbd9e4bSmacallan break; 526dbbd9e4bSmacallan case (0x2 << 5) | (0x0 << 3): 527dbbd9e4bSmacallan pFfb->ffb_type = ffb2_horizontal; 528dbbd9e4bSmacallan ErrorF("Detected FFB2/horizontal, "); 529dbbd9e4bSmacallan break; 530dbbd9e4bSmacallan case (0x2 << 5) | (0x2 << 3): 531dbbd9e4bSmacallan pFfb->ffb_type = ffb2_horizontal; 532dbbd9e4bSmacallan ErrorF("Detected FFB2+/horizontal, "); 533dbbd9e4bSmacallan break; 534dbbd9e4bSmacallan default: 535dbbd9e4bSmacallan pFfb->ffb_type = ffb2_vertical; 536dbbd9e4bSmacallan ErrorF("Unknown boardID[%08x], assuming FFB2, ", sbits); 537dbbd9e4bSmacallan break; 538dbbd9e4bSmacallan }; 539dbbd9e4bSmacallan 540dbbd9e4bSmacallan if (sbits & (1 << 2)) { 541dbbd9e4bSmacallan ErrorF("DoubleRES, "); 542dbbd9e4bSmacallan pFfb->has_double_res = 1; 543dbbd9e4bSmacallan } else { 544dbbd9e4bSmacallan pFfb->has_double_res = 0; 545dbbd9e4bSmacallan } 546dbbd9e4bSmacallan if (sbits & (1 << 1)) { 547dbbd9e4bSmacallan ErrorF("Z-buffer, "); 548dbbd9e4bSmacallan pFfb->has_z_buffer = 1; 549dbbd9e4bSmacallan } else { 550dbbd9e4bSmacallan pFfb->has_z_buffer = 0; 551dbbd9e4bSmacallan } 552dbbd9e4bSmacallan if (sbits & (1 << 0)) { 553dbbd9e4bSmacallan /* This state really means to the driver that the double 554dbbd9e4bSmacallan * buffers are available for hw accelerate Dbe. When the 555dbbd9e4bSmacallan * FFB is in high-resolution mode, the buffers are combined 556dbbd9e4bSmacallan * into one single large framebuffer. So in high-resolution 557dbbd9e4bSmacallan * hw accelerated double-buffering is not available. 558dbbd9e4bSmacallan */ 559dbbd9e4bSmacallan if ((ffb->fbcfg0 & FFB_FBCFG0_RES_MASK) != FFB_FBCFG0_RES_HIGH) 560dbbd9e4bSmacallan pFfb->has_double_buffer = 1; 561dbbd9e4bSmacallan else 562dbbd9e4bSmacallan pFfb->has_double_buffer = 0; 563dbbd9e4bSmacallan } else { 564dbbd9e4bSmacallan pFfb->has_double_buffer = 0; 565dbbd9e4bSmacallan } 566dbbd9e4bSmacallan if (pFfb->has_double_buffer) 567dbbd9e4bSmacallan ErrorF("Double-buffered.\n"); 568dbbd9e4bSmacallan else 569dbbd9e4bSmacallan ErrorF("Single-buffered.\n"); 570dbbd9e4bSmacallan } 571dbbd9e4bSmacallan} 572dbbd9e4bSmacallan 573dbbd9e4bSmacallan/* Mandatory */ 574dbbd9e4bSmacallan 575dbbd9e4bSmacallan/* This gets called at the start of each server generation */ 576dbbd9e4bSmacallan 577dbbd9e4bSmacallanstatic Bool 5787a5333bcSmrgFFBScreenInit(SCREEN_INIT_ARGS_DECL) 579dbbd9e4bSmacallan{ 580dbbd9e4bSmacallan ScrnInfoPtr pScrn; 581dbbd9e4bSmacallan FFBPtr pFfb; 582dbbd9e4bSmacallan int ret; 583dbbd9e4bSmacallan unsigned int afb_fem; 584dbbd9e4bSmacallan VisualPtr visual; 585dbbd9e4bSmacallan 586dbbd9e4bSmacallan /* 587dbbd9e4bSmacallan * First get the ScrnInfoRec 588dbbd9e4bSmacallan */ 5897a5333bcSmrg pScrn = xf86ScreenToScrn(pScreen); 590dbbd9e4bSmacallan 591dbbd9e4bSmacallan pFfb = GET_FFB_FROM_SCRN(pScrn); 592dbbd9e4bSmacallan 593dbbd9e4bSmacallan /* Map the FFB framebuffer, for each view. */ 594dbbd9e4bSmacallan 595dbbd9e4bSmacallan /* 24-bit RGB Dumb view */ 596dbbd9e4bSmacallan pFfb->fb = pFfb->dfb24 = 597dbbd9e4bSmacallan xf86MapSbusMem (pFfb->psdp, FFB_DFB24_VOFF, 0x1000000); 598dbbd9e4bSmacallan 599dbbd9e4bSmacallan if (! pFfb->dfb24) 600dbbd9e4bSmacallan return FALSE; 601dbbd9e4bSmacallan 602dbbd9e4bSmacallan /* 8-bit R Dumb view */ 603dbbd9e4bSmacallan pFfb->dfb8r = 604dbbd9e4bSmacallan xf86MapSbusMem (pFfb->psdp, FFB_DFB8R_VOFF, 0x400000); 605dbbd9e4bSmacallan 606dbbd9e4bSmacallan if (! pFfb->dfb8r) 607dbbd9e4bSmacallan return FALSE; 608dbbd9e4bSmacallan 609dbbd9e4bSmacallan /* 8-bit X Dumb view */ 610dbbd9e4bSmacallan pFfb->dfb8x = 611dbbd9e4bSmacallan xf86MapSbusMem (pFfb->psdp, FFB_DFB8X_VOFF, 0x400000); 612dbbd9e4bSmacallan 613dbbd9e4bSmacallan if (! pFfb->dfb8x) 614dbbd9e4bSmacallan return FALSE; 615dbbd9e4bSmacallan 616dbbd9e4bSmacallan /* 32-bit RGB Smart view */ 617dbbd9e4bSmacallan pFfb->sfb32 = 618dbbd9e4bSmacallan xf86MapSbusMem (pFfb->psdp, FFB_SFB32_VOFF, 0x1000000); 619dbbd9e4bSmacallan 620dbbd9e4bSmacallan if (!pFfb->sfb32) 621dbbd9e4bSmacallan return FALSE; 622dbbd9e4bSmacallan 623dbbd9e4bSmacallan /* 8-bit R Smart view */ 624dbbd9e4bSmacallan pFfb->sfb8r = 625dbbd9e4bSmacallan xf86MapSbusMem(pFfb->psdp, FFB_SFB8R_VOFF, 0x400000); 626dbbd9e4bSmacallan 627dbbd9e4bSmacallan if (!pFfb->sfb8r) 628dbbd9e4bSmacallan return FALSE; 629dbbd9e4bSmacallan 630dbbd9e4bSmacallan /* 8-bit X Smart view */ 631dbbd9e4bSmacallan pFfb->sfb8x = 632dbbd9e4bSmacallan xf86MapSbusMem(pFfb->psdp, FFB_SFB8X_VOFF, 0x400000); 633dbbd9e4bSmacallan 634dbbd9e4bSmacallan if (!pFfb->sfb8x) 635dbbd9e4bSmacallan return FALSE; 636dbbd9e4bSmacallan 637dbbd9e4bSmacallan /* Map the rendering pipeline */ 638dbbd9e4bSmacallan pFfb->regs = 639dbbd9e4bSmacallan xf86MapSbusMem (pFfb->psdp, FFB_FBC_REGS_VOFF, 16384); 640dbbd9e4bSmacallan 641dbbd9e4bSmacallan if (! pFfb->regs) 642dbbd9e4bSmacallan return FALSE; 643dbbd9e4bSmacallan 644dbbd9e4bSmacallan /* Map the ramdac */ 645dbbd9e4bSmacallan pFfb->dac = 646dbbd9e4bSmacallan xf86MapSbusMem (pFfb->psdp, FFB_DAC_VOFF, 8192); 647dbbd9e4bSmacallan 648dbbd9e4bSmacallan if (! pFfb->dac) 649dbbd9e4bSmacallan return FALSE; 650dbbd9e4bSmacallan 651dbbd9e4bSmacallan /* Map the board strapping bits */ 652dbbd9e4bSmacallan pFfb->strapping_bits = (volatile unsigned int *) 653dbbd9e4bSmacallan xf86MapSbusMem(pFfb->psdp, FFB_EXP_VOFF, 8192); 654dbbd9e4bSmacallan 655dbbd9e4bSmacallan if (! pFfb->strapping_bits) 656dbbd9e4bSmacallan return FALSE; 657e33a93fdSmrg 658dbbd9e4bSmacallan /* Probe for the type of FFB/AFB we have. */ 659dbbd9e4bSmacallan FFBProbeBoardType(pFfb); 660dbbd9e4bSmacallan 661dbbd9e4bSmacallan /* Now that we have the board type, we can init the ramdac layer. */ 662dbbd9e4bSmacallan if (FFBDacInit(pFfb) == FALSE) 663dbbd9e4bSmacallan return FALSE; 664dbbd9e4bSmacallan 665dbbd9e4bSmacallan /* OK, a fun gross hack to detect if this is 666dbbd9e4bSmacallan * AFB and if so whether the correct firmware 667dbbd9e4bSmacallan * has been loaded. The machine will flatline 668dbbd9e4bSmacallan * if you try to use certain acceleration features 669dbbd9e4bSmacallan * without the full firmware loaded. 670dbbd9e4bSmacallan * 671dbbd9e4bSmacallan * The bootup Elite3D/AFB firmware is minimal, and 672dbbd9e4bSmacallan * will leave the FloatEnableMask register at a 673dbbd9e4bSmacallan * value of 0x01. Creator{,3D} lacks the FEM register 674dbbd9e4bSmacallan * and will return a "nonsense" value on attempts to 675dbbd9e4bSmacallan * read this location. After experimentation, an 676dbbd9e4bSmacallan * appropriate definition for "nonsense" seems to 677dbbd9e4bSmacallan * be anything with all low 7 bits not 0x3f, 0x07, 678dbbd9e4bSmacallan * of 0x01. 679dbbd9e4bSmacallan * 680dbbd9e4bSmacallan * If the FEM register is non-zero and is some value 681dbbd9e4bSmacallan * other than 0x1 (usually 0x3f or 0x7 depending upon 682dbbd9e4bSmacallan * whether the card has 3 or 6 floats) we can assume 683dbbd9e4bSmacallan * the correct firmware has been loaded. -DaveM 684dbbd9e4bSmacallan */ 685dbbd9e4bSmacallan afb_fem = *(unsigned int *)((char *)pFfb->regs + 0x1540); 686dbbd9e4bSmacallan if ((afb_fem & 0x7f) != 0x3f && 687dbbd9e4bSmacallan (afb_fem & 0x7f) != 0x07 && 688dbbd9e4bSmacallan (afb_fem & 0x7f) != 0x01) 689dbbd9e4bSmacallan xf86Msg(X_INFO, "%s: Detected Creator/Creator3D\n", pFfb->psdp->device); 690dbbd9e4bSmacallan else { 691dbbd9e4bSmacallan xf86Msg(X_INFO, "%s: Detected Elite3D M3/M6, checking firmware...\n", pFfb->psdp->device); 692dbbd9e4bSmacallan if (afb_fem == 0x1) { 693dbbd9e4bSmacallan xf86Msg(X_INFO, "%s: ... AFB firmware not loaded\n", pFfb->psdp->device); 694dbbd9e4bSmacallan if (!pFfb->NoAccel) { 695dbbd9e4bSmacallan xf86Msg(X_WARNING, "%s: Forcing no acceleration on Elite3D M3/M6\n", pFfb->psdp->device); 696dbbd9e4bSmacallan pFfb->NoAccel = TRUE; 697dbbd9e4bSmacallan } 698dbbd9e4bSmacallan } else 699dbbd9e4bSmacallan xf86Msg(X_INFO, "%s: ... AFB firmware is loaded\n", pFfb->psdp->device); 700dbbd9e4bSmacallan } 701dbbd9e4bSmacallan 702dbbd9e4bSmacallan /* Darken the screen for aesthetic reasons and set the viewport */ 7036adf905bSmacallan /* XXX can't do this yet */ 7046adf905bSmacallan /* FFBSaveScreen(pScreen, SCREEN_SAVER_ON);*/ 705dbbd9e4bSmacallan 706dbbd9e4bSmacallan /* 707dbbd9e4bSmacallan * The next step is to setup the screen's visuals, and initialise the 708dbbd9e4bSmacallan * framebuffer code. In cases where the framebuffer's default 709dbbd9e4bSmacallan * choices for things like visual layouts and bits per RGB are OK, 710dbbd9e4bSmacallan * this may be as simple as calling the framebuffer's ScreenInit() 711dbbd9e4bSmacallan * function. If not, the visuals will need to be setup before calling 712dbbd9e4bSmacallan * a fb ScreenInit() function and fixed up after. 713dbbd9e4bSmacallan */ 714dbbd9e4bSmacallan 715dbbd9e4bSmacallan /* 716dbbd9e4bSmacallan * Reset visual list. 717dbbd9e4bSmacallan */ 718dbbd9e4bSmacallan miClearVisualTypes(); 719dbbd9e4bSmacallan 720dbbd9e4bSmacallan /* Setup the visuals we support. */ 721dbbd9e4bSmacallan if (!miSetVisualTypes(24, TrueColorMask, 722dbbd9e4bSmacallan pScrn->rgbBits, TrueColor)) 723dbbd9e4bSmacallan return FALSE; 724dbbd9e4bSmacallan 725dbbd9e4bSmacallan if (!miSetPixmapDepths()) 726dbbd9e4bSmacallan return FALSE; 727dbbd9e4bSmacallan 728dbbd9e4bSmacallan /* 729dbbd9e4bSmacallan * Call the framebuffer layer's ScreenInit function, and fill in other 730dbbd9e4bSmacallan * pScreen fields. 731dbbd9e4bSmacallan */ 732dbbd9e4bSmacallan ret = fbScreenInit(pScreen, (pFfb->NoAccel ? pFfb->dfb24 : pFfb->sfb32), 733dbbd9e4bSmacallan pScrn->virtualX, pScrn->virtualY, 734dbbd9e4bSmacallan pScrn->xDpi, pScrn->yDpi, 735dbbd9e4bSmacallan 2048, 32); 736dbbd9e4bSmacallan 737dbbd9e4bSmacallan if (!ret) 738dbbd9e4bSmacallan return FALSE; 739dbbd9e4bSmacallan 740dbbd9e4bSmacallan if (pScrn->bitsPerPixel > 8) { 741dbbd9e4bSmacallan /* Fixup RGB ordering */ 742dbbd9e4bSmacallan visual = pScreen->visuals + pScreen->numVisuals; 743dbbd9e4bSmacallan while (--visual >= pScreen->visuals) { 744dbbd9e4bSmacallan if ((visual->class | DynamicClass) == DirectColor) { 745dbbd9e4bSmacallan visual->offsetRed = pScrn->offset.red; 746dbbd9e4bSmacallan visual->offsetGreen = pScrn->offset.green; 747dbbd9e4bSmacallan visual->offsetBlue = pScrn->offset.blue; 748dbbd9e4bSmacallan visual->redMask = pScrn->mask.red; 749dbbd9e4bSmacallan visual->greenMask = pScrn->mask.green; 750dbbd9e4bSmacallan visual->blueMask = pScrn->mask.blue; 751dbbd9e4bSmacallan } 752dbbd9e4bSmacallan } 753dbbd9e4bSmacallan } 754dbbd9e4bSmacallan 755dbbd9e4bSmacallan if (!fbPictureInit(pScreen, NULL, 0) && 756dbbd9e4bSmacallan (serverGeneration == 1)) 757dbbd9e4bSmacallan xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 758dbbd9e4bSmacallan "RENDER extension initialisation failed.\n"); 759dbbd9e4bSmacallan 760dbbd9e4bSmacallan xf86SetBlackWhitePixels(pScreen); 761dbbd9e4bSmacallan 762dbbd9e4bSmacallan if (!pFfb->NoAccel) { 763dbbd9e4bSmacallan if (!FFBAccelInit(pScreen, pFfb)) 764dbbd9e4bSmacallan return FALSE; 765dbbd9e4bSmacallan xf86Msg(X_INFO, "%s: Using acceleration\n", pFfb->psdp->device); 766dbbd9e4bSmacallan } 767dbbd9e4bSmacallan 768dbbd9e4bSmacallan 769dbbd9e4bSmacallan xf86SetBackingStore(pScreen); 770dbbd9e4bSmacallan xf86SetSilkenMouse(pScreen); 771dbbd9e4bSmacallan 772dbbd9e4bSmacallan /* Initialise cursor functions */ 773dbbd9e4bSmacallan miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); 774dbbd9e4bSmacallan 775dbbd9e4bSmacallan /* Initialize HW cursor layer. 776dbbd9e4bSmacallan * Must follow software cursor initialization. 777dbbd9e4bSmacallan */ 778dbbd9e4bSmacallan if (pFfb->HWCursor) { 779dbbd9e4bSmacallan if(!FFBHWCursorInit(pScreen)) { 780dbbd9e4bSmacallan xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 781dbbd9e4bSmacallan "Hardware cursor initialization failed\n"); 782dbbd9e4bSmacallan return(FALSE); 783dbbd9e4bSmacallan } 784dbbd9e4bSmacallan xf86SbusHideOsHwCursor(pFfb->psdp); 785dbbd9e4bSmacallan } 786dbbd9e4bSmacallan 787dbbd9e4bSmacallan /* Initialise default colourmap. */ 788dbbd9e4bSmacallan if (!miCreateDefColormap(pScreen)) 789dbbd9e4bSmacallan return FALSE; 790dbbd9e4bSmacallan 791dbbd9e4bSmacallan /* Initialize colormap layer. 792dbbd9e4bSmacallan * Must follow initialization of the default colormap. 793dbbd9e4bSmacallan */ 794dbbd9e4bSmacallan if (!xf86HandleColormaps(pScreen, 256, 8, 795dbbd9e4bSmacallan FFBDacLoadPalette, NULL, 796dbbd9e4bSmacallan CMAP_LOAD_EVEN_IF_OFFSCREEN | 797dbbd9e4bSmacallan CMAP_RELOAD_ON_MODE_SWITCH)) 798dbbd9e4bSmacallan return FALSE; 799dbbd9e4bSmacallan 800dbbd9e4bSmacallan /* Setup DGA support. */ 801dbbd9e4bSmacallan if (!pFfb->NoAccel) 802dbbd9e4bSmacallan FFB_InitDGA(pScreen); 803dbbd9e4bSmacallan 804dbbd9e4bSmacallan xf86DPMSInit(pScreen, FFBDPMSSet, 0); 805dbbd9e4bSmacallan 806dbbd9e4bSmacallan pFfb->CloseScreen = pScreen->CloseScreen; 807dbbd9e4bSmacallan pScreen->CloseScreen = FFBCloseScreen; 808dbbd9e4bSmacallan pScreen->SaveScreen = FFBSaveScreen; 809dbbd9e4bSmacallan 810dbbd9e4bSmacallan (void) xf86DPMSInit(pScreen, FFBDPMSMode, 0); 811dbbd9e4bSmacallan 812dbbd9e4bSmacallan /* Report any unused options (only for the first generation) */ 813dbbd9e4bSmacallan if (serverGeneration == 1) { 814dbbd9e4bSmacallan xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 815dbbd9e4bSmacallan } 816dbbd9e4bSmacallan 817dbbd9e4bSmacallan /* unblank the screen */ 8186adf905bSmacallan /* XXX since we didn't blank it we don't need to unblank it here */ 8196adf905bSmacallan /* FFBSaveScreen(pScreen, SCREEN_SAVER_OFF); */ 820dbbd9e4bSmacallan 821dbbd9e4bSmacallan /* Done */ 822dbbd9e4bSmacallan return TRUE; 823dbbd9e4bSmacallan} 824dbbd9e4bSmacallan 825dbbd9e4bSmacallan 826dbbd9e4bSmacallan/* Usually mandatory */ 827dbbd9e4bSmacallanstatic Bool 8287a5333bcSmrgFFBSwitchMode(SWITCH_MODE_ARGS_DECL) 829dbbd9e4bSmacallan{ 830dbbd9e4bSmacallan return TRUE; 831dbbd9e4bSmacallan} 832dbbd9e4bSmacallan 833dbbd9e4bSmacallan 834dbbd9e4bSmacallan/* 835dbbd9e4bSmacallan * This function is used to initialize the Start Address - the first 836dbbd9e4bSmacallan * displayed location in the video memory. 837dbbd9e4bSmacallan */ 838dbbd9e4bSmacallan/* Usually mandatory */ 839dbbd9e4bSmacallanstatic void 8407a5333bcSmrgFFBAdjustFrame(ADJUST_FRAME_ARGS_DECL) 841dbbd9e4bSmacallan{ 842dbbd9e4bSmacallan /* we don't support virtual desktops */ 843dbbd9e4bSmacallan return; 844dbbd9e4bSmacallan} 845dbbd9e4bSmacallan 846dbbd9e4bSmacallan/* 847dbbd9e4bSmacallan * This is called when VT switching back to the X server. Its job is 848dbbd9e4bSmacallan * to reinitialise the video mode. 849dbbd9e4bSmacallan */ 850dbbd9e4bSmacallan 851dbbd9e4bSmacallan/* Mandatory */ 852dbbd9e4bSmacallanstatic Bool 8537a5333bcSmrgFFBEnterVT(VT_FUNC_ARGS_DECL) 854dbbd9e4bSmacallan{ 8557a5333bcSmrg SCRN_INFO_PTR(arg); 856dbbd9e4bSmacallan FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 857dbbd9e4bSmacallan 858dbbd9e4bSmacallan pFfb->vtSema = FALSE; 859dbbd9e4bSmacallan if (!pFfb->NoAccel) 860dbbd9e4bSmacallan CreatorVtChange (pScrn->pScreen, TRUE); 861dbbd9e4bSmacallan if (pFfb->HWCursor) 862dbbd9e4bSmacallan xf86SbusHideOsHwCursor (pFfb->psdp); 863dbbd9e4bSmacallan 864dbbd9e4bSmacallan FFBDacEnterVT(pFfb); 865dbbd9e4bSmacallan 866dbbd9e4bSmacallan return TRUE; 867dbbd9e4bSmacallan} 868dbbd9e4bSmacallan 869dbbd9e4bSmacallan 870dbbd9e4bSmacallan/* 871dbbd9e4bSmacallan * This is called when VT switching away from the X server. 872dbbd9e4bSmacallan */ 873dbbd9e4bSmacallan 874dbbd9e4bSmacallan/* Mandatory */ 875dbbd9e4bSmacallanstatic void 8767a5333bcSmrgFFBLeaveVT(VT_FUNC_ARGS_DECL) 877dbbd9e4bSmacallan{ 8787a5333bcSmrg SCRN_INFO_PTR(arg); 879dbbd9e4bSmacallan FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 880dbbd9e4bSmacallan 881dbbd9e4bSmacallan FFBDacLeaveVT(pFfb); 882dbbd9e4bSmacallan 883dbbd9e4bSmacallan if (!pFfb->NoAccel) 884dbbd9e4bSmacallan CreatorVtChange (pScrn->pScreen, FALSE); 885dbbd9e4bSmacallan 886dbbd9e4bSmacallan if (pFfb->HWCursor) 887dbbd9e4bSmacallan xf86SbusHideOsHwCursor (pFfb->psdp); 888dbbd9e4bSmacallan 889dbbd9e4bSmacallan pFfb->vtSema = TRUE; 890dbbd9e4bSmacallan return; 891dbbd9e4bSmacallan} 892dbbd9e4bSmacallan 893dbbd9e4bSmacallan 894dbbd9e4bSmacallan/* 895dbbd9e4bSmacallan * This is called at the end of each server generation. It restores the 896dbbd9e4bSmacallan * original (text) mode. It should really also unmap the video memory too. 897dbbd9e4bSmacallan */ 898dbbd9e4bSmacallan 899dbbd9e4bSmacallan/* Mandatory */ 900dbbd9e4bSmacallanstatic Bool 9017a5333bcSmrgFFBCloseScreen(CLOSE_SCREEN_ARGS_DECL) 902dbbd9e4bSmacallan{ 9037a5333bcSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 904dbbd9e4bSmacallan FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 905dbbd9e4bSmacallan 906cc45f3ffSmacallan FFBDacCursorEnableDisable(pFfb, 0); 907dbbd9e4bSmacallan /* Restore kernel ramdac state before we unmap registers. */ 908dbbd9e4bSmacallan FFBDacFini(pFfb); 909dbbd9e4bSmacallan 910dbbd9e4bSmacallan pScrn->vtSema = FALSE; 911dbbd9e4bSmacallan 912dbbd9e4bSmacallan xf86UnmapSbusMem(pFfb->psdp, pFfb->dfb24, 0x1000000); 913dbbd9e4bSmacallan xf86UnmapSbusMem(pFfb->psdp, pFfb->dfb8r, 0x400000); 914dbbd9e4bSmacallan xf86UnmapSbusMem(pFfb->psdp, pFfb->dfb8x, 0x400000); 915dbbd9e4bSmacallan xf86UnmapSbusMem(pFfb->psdp, pFfb->sfb32, 0x1000000); 916dbbd9e4bSmacallan xf86UnmapSbusMem(pFfb->psdp, pFfb->sfb8r, 0x400000); 917dbbd9e4bSmacallan xf86UnmapSbusMem(pFfb->psdp, pFfb->sfb8x, 0x400000); 918dbbd9e4bSmacallan xf86UnmapSbusMem(pFfb->psdp, pFfb->regs, 16384); 919dbbd9e4bSmacallan xf86UnmapSbusMem(pFfb->psdp, pFfb->dac, 8192); 920dbbd9e4bSmacallan xf86UnmapSbusMem(pFfb->psdp, (void *)pFfb->strapping_bits, 8192); 921dbbd9e4bSmacallan 922dbbd9e4bSmacallan if (pFfb->HWCursor) 923dbbd9e4bSmacallan xf86SbusHideOsHwCursor (pFfb->psdp); 924dbbd9e4bSmacallan 925dbbd9e4bSmacallan pScreen->CloseScreen = pFfb->CloseScreen; 9267a5333bcSmrg return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS); 927dbbd9e4bSmacallan} 928dbbd9e4bSmacallan 929dbbd9e4bSmacallan 930dbbd9e4bSmacallan/* Free up any per-generation data structures */ 931dbbd9e4bSmacallan 932dbbd9e4bSmacallan/* Optional */ 933dbbd9e4bSmacallanstatic void 9347a5333bcSmrgFFBFreeScreen(FREE_SCREEN_ARGS_DECL) 935dbbd9e4bSmacallan{ 9367a5333bcSmrg SCRN_INFO_PTR(arg); 9377a5333bcSmrg FFBFreeRec(pScrn); 938dbbd9e4bSmacallan} 939dbbd9e4bSmacallan 940dbbd9e4bSmacallan 941dbbd9e4bSmacallan/* Checks if a mode is suitable for the selected chipset. */ 942dbbd9e4bSmacallan 943dbbd9e4bSmacallan/* Optional */ 944dbbd9e4bSmacallanstatic ModeStatus 9457a5333bcSmrgFFBValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) 946dbbd9e4bSmacallan{ 947dbbd9e4bSmacallan if (mode->Flags & V_INTERLACE) 948dbbd9e4bSmacallan return MODE_BAD; 949dbbd9e4bSmacallan 950dbbd9e4bSmacallan return MODE_OK; 951dbbd9e4bSmacallan} 952dbbd9e4bSmacallan 953dbbd9e4bSmacallan/* Do screen blanking */ 954dbbd9e4bSmacallan 955dbbd9e4bSmacallan/* Mandatory */ 956dbbd9e4bSmacallanstatic Bool 957dbbd9e4bSmacallanFFBSaveScreen(ScreenPtr pScreen, int mode) 958dbbd9e4bSmacallan /* This function blanks the screen when mode=SCREEN_SAVER_ON and 959dbbd9e4bSmacallan unblanks it when mode=SCREEN_SAVER_OFF. It is used internally in the 960dbbd9e4bSmacallan FFBScreenInit code `for aesthetic reasons,' and it is used for 961dbbd9e4bSmacallan blanking if you set "xset s on s blank." The work (such as it is) is 962dbbd9e4bSmacallan done in "ffb_dac.c" `for aesthetic reasons.' 963dbbd9e4bSmacallan */ 964dbbd9e4bSmacallan{ 965dbbd9e4bSmacallan 966ec319841Smacallan return FFBDacSaveScreen(pScreen, mode); 967dbbd9e4bSmacallan} 968dbbd9e4bSmacallan 969dbbd9e4bSmacallanstatic void 970dbbd9e4bSmacallanFFBDPMSSet(ScrnInfoPtr pScrn, int mode, int flags) 971dbbd9e4bSmacallan{ 972dbbd9e4bSmacallan FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 973dbbd9e4bSmacallan 974dbbd9e4bSmacallan FFBDacDPMSMode(pFfb, mode, 0); 975dbbd9e4bSmacallan} 976dbbd9e4bSmacallan 977dbbd9e4bSmacallan/* 978dbbd9e4bSmacallan * This is the implementation of the Sync() function. 979dbbd9e4bSmacallan */ 980dbbd9e4bSmacallanvoid 981dbbd9e4bSmacallanFFBSync(ScrnInfoPtr pScrn) 982dbbd9e4bSmacallan{ 983dbbd9e4bSmacallan return; 984dbbd9e4bSmacallan} 985dbbd9e4bSmacallan 986dbbd9e4bSmacallan/* 987dbbd9e4bSmacallan Hook for DPMS Mode. 988dbbd9e4bSmacallan*/ 989dbbd9e4bSmacallan 990dbbd9e4bSmacallanstatic void 991dbbd9e4bSmacallanFFBDPMSMode(ScrnInfoPtr pScrn, int DPMSMode, int flags) 992dbbd9e4bSmacallan{ 993dbbd9e4bSmacallan FFBDacDPMSMode(GET_FFB_FROM_SCRN(pScrn), DPMSMode, flags); 994dbbd9e4bSmacallan} 9955d1b25cdSmacallan 9965d1b25cdSmacallanstatic Bool 9975d1b25cdSmacallanFFBDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, 9985d1b25cdSmacallan pointer ptr) 9995d1b25cdSmacallan{ 10005d1b25cdSmacallan xorgHWFlags *flag; 10015d1b25cdSmacallan 10025d1b25cdSmacallan switch (op) { 10035d1b25cdSmacallan case GET_REQUIRED_HW_INTERFACES: 10045d1b25cdSmacallan flag = (CARD32*)ptr; 10055d1b25cdSmacallan (*flag) = HW_MMIO; 10065d1b25cdSmacallan return TRUE; 10075d1b25cdSmacallan default: 10085d1b25cdSmacallan return FALSE; 10095d1b25cdSmacallan } 10105d1b25cdSmacallan} 10115d1b25cdSmacallan 1012