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