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 30f1295e53Smrg#include "ffb.h" 31f1295e53Smrg 32dbbd9e4bSmacallan#include "xf86.h" 33dbbd9e4bSmacallan#include "xf86_OSproc.h" 34dbbd9e4bSmacallan#include "mipointer.h" 35dbbd9e4bSmacallan#include "micmap.h" 36dbbd9e4bSmacallan#include "fb.h" 37dbbd9e4bSmacallan 38dbbd9e4bSmacallan#include "xf86cmap.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, 9889b0bd4cSmacallan OPTION_ACCELMETHOD, 99dbbd9e4bSmacallan OPTION_NOACCEL 100dbbd9e4bSmacallan} FFBOpts; 101dbbd9e4bSmacallan 102dbbd9e4bSmacallanstatic const OptionInfoRec FFBOptions[] = { 103dbbd9e4bSmacallan { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, 104dbbd9e4bSmacallan { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, 105dbbd9e4bSmacallan { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 10689b0bd4cSmacallan { OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE }, 107dbbd9e4bSmacallan { -1, NULL, OPTV_NONE, {0}, FALSE } 108dbbd9e4bSmacallan}; 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 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 1787a5333bcSmrg free(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 2487a5333bcSmrg free(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 } 2827a5333bcSmrg free(pEnt); 283dbbd9e4bSmacallan } 2847a5333bcSmrg free(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 */ 3597a5333bcSmrg if (!(pFfb->Options = malloc(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 (pFfb->HWCursor && xf86LoadSubModule(pScrn, "ramdac") == NULL) { 419dbbd9e4bSmacallan FFBFreeRec(pScrn); 420dbbd9e4bSmacallan return FALSE; 421dbbd9e4bSmacallan } 422dbbd9e4bSmacallan 423dbbd9e4bSmacallan if (xf86LoadSubModule(pScrn, "dbe") == NULL) { 424dbbd9e4bSmacallan FFBFreeRec(pScrn); 425dbbd9e4bSmacallan return FALSE; 426dbbd9e4bSmacallan } 427dbbd9e4bSmacallan 428dbbd9e4bSmacallan 429dbbd9e4bSmacallan /********************* 430dbbd9e4bSmacallan set up clock and mode stuff 431dbbd9e4bSmacallan *********************/ 432dbbd9e4bSmacallan 433dbbd9e4bSmacallan pScrn->progClock = TRUE; 434dbbd9e4bSmacallan 435dbbd9e4bSmacallan if(pScrn->display->virtualX || pScrn->display->virtualY) { 436dbbd9e4bSmacallan xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 437dbbd9e4bSmacallan "FFB does not support a virtual desktop\n"); 438dbbd9e4bSmacallan pScrn->display->virtualX = 0; 439dbbd9e4bSmacallan pScrn->display->virtualY = 0; 440dbbd9e4bSmacallan } 441dbbd9e4bSmacallan 442dbbd9e4bSmacallan xf86SbusUseBuiltinMode(pScrn, pFfb->psdp); 443dbbd9e4bSmacallan pScrn->currentMode = pScrn->modes; 444dbbd9e4bSmacallan pScrn->displayWidth = pScrn->virtualX; 445dbbd9e4bSmacallan 446dbbd9e4bSmacallan /* Set display resolution */ 447dbbd9e4bSmacallan xf86SetDpi(pScrn, 0, 0); 448dbbd9e4bSmacallan 449dbbd9e4bSmacallan return TRUE; 450dbbd9e4bSmacallan} 451dbbd9e4bSmacallan 452dbbd9e4bSmacallan/* Determine the FFB/AFB board type. We need this information even 453dbbd9e4bSmacallan * if acceleration is disabled because the ramdac support layer needs 454dbbd9e4bSmacallan * to know what kind of FFB/AFB this is. 455dbbd9e4bSmacallan */ 456dbbd9e4bSmacallanstatic void 457dbbd9e4bSmacallanFFBProbeBoardType(FFBPtr pFfb) 458dbbd9e4bSmacallan{ 459dbbd9e4bSmacallan ffb_fbcPtr ffb = pFfb->regs; 460dbbd9e4bSmacallan volatile unsigned int *afb_fem; 461dbbd9e4bSmacallan unsigned int val; 462dbbd9e4bSmacallan 463dbbd9e4bSmacallan afb_fem = ((volatile unsigned int *) ((char *)ffb + 0x1540)); 464dbbd9e4bSmacallan val = *afb_fem; 465dbbd9e4bSmacallan val &= 0x7f; 466dbbd9e4bSmacallan 467dbbd9e4bSmacallan xf86Msg(X_INFO, "%s: ", pFfb->psdp->device); 468dbbd9e4bSmacallan if (val == 0x3f || val == 0x07 || val == 0x01) { 469dbbd9e4bSmacallan /* When firmware has not been loaded onto AFB we 470dbbd9e4bSmacallan * just assume it is an M6 board. 471dbbd9e4bSmacallan */ 472dbbd9e4bSmacallan if (val == 0x3f || val != 0x07) { 473dbbd9e4bSmacallan pFfb->ffb_type = afb_m6; 474dbbd9e4bSmacallan ErrorF("AFB: Detected Elite3D/M6.\n"); 475dbbd9e4bSmacallan } else { 476dbbd9e4bSmacallan pFfb->ffb_type = afb_m3; 477dbbd9e4bSmacallan ErrorF("AFB: Detected Elite3D/M3.\n"); 478dbbd9e4bSmacallan } 479dbbd9e4bSmacallan 480dbbd9e4bSmacallan /* These attributes are invariant on AFB. */ 481dbbd9e4bSmacallan pFfb->has_double_res = 0; 482dbbd9e4bSmacallan pFfb->has_z_buffer = 1; 483dbbd9e4bSmacallan pFfb->has_double_buffer = 1; 484dbbd9e4bSmacallan } else { 485dbbd9e4bSmacallan unsigned char sbits; 486e33a93fdSmrg 487dbbd9e4bSmacallan /* Read the board strapping bits twice, because sometimes 488dbbd9e4bSmacallan * the strapping pins can get misrouted to the bus interface 489dbbd9e4bSmacallan * on the first attempt. The second attempt will get the 490dbbd9e4bSmacallan * correct value. 491dbbd9e4bSmacallan */ 492dbbd9e4bSmacallan sbits = *((volatile unsigned char *)pFfb->strapping_bits); 493dbbd9e4bSmacallan sbits = *((volatile unsigned char *)pFfb->strapping_bits); 494dbbd9e4bSmacallan switch (sbits & 0x78) { 495dbbd9e4bSmacallan case (0x0 << 5) | (0x0 << 3): 496dbbd9e4bSmacallan pFfb->ffb_type = ffb1_prototype; 497dbbd9e4bSmacallan ErrorF("Detected FFB1 pre-FCS prototype, "); 498dbbd9e4bSmacallan break; 499dbbd9e4bSmacallan case (0x0 << 5) | (0x1 << 3): 500dbbd9e4bSmacallan pFfb->ffb_type = ffb1_standard; 501dbbd9e4bSmacallan ErrorF("Detected FFB1, "); 502dbbd9e4bSmacallan break; 503dbbd9e4bSmacallan case (0x0 << 5) | (0x3 << 3): 504dbbd9e4bSmacallan pFfb->ffb_type = ffb1_speedsort; 505dbbd9e4bSmacallan ErrorF("Detected FFB1-SpeedSort, "); 506dbbd9e4bSmacallan break; 507dbbd9e4bSmacallan case (0x1 << 5) | (0x0 << 3): 508dbbd9e4bSmacallan pFfb->ffb_type = ffb2_prototype; 509dbbd9e4bSmacallan ErrorF("Detected FFB2/vertical pre-FCS prototype, "); 510dbbd9e4bSmacallan break; 511dbbd9e4bSmacallan case (0x1 << 5) | (0x1 << 3): 512dbbd9e4bSmacallan pFfb->ffb_type = ffb2_vertical; 513dbbd9e4bSmacallan ErrorF("Detected FFB2/vertical, "); 514dbbd9e4bSmacallan break; 515dbbd9e4bSmacallan case (0x1 << 5) | (0x2 << 3): 516dbbd9e4bSmacallan pFfb->ffb_type = ffb2_vertical_plus; 517dbbd9e4bSmacallan ErrorF("Detected FFB2+/vertical, "); 518dbbd9e4bSmacallan break; 519dbbd9e4bSmacallan case (0x2 << 5) | (0x0 << 3): 520dbbd9e4bSmacallan pFfb->ffb_type = ffb2_horizontal; 521dbbd9e4bSmacallan ErrorF("Detected FFB2/horizontal, "); 522dbbd9e4bSmacallan break; 523dbbd9e4bSmacallan case (0x2 << 5) | (0x2 << 3): 524dbbd9e4bSmacallan pFfb->ffb_type = ffb2_horizontal; 525dbbd9e4bSmacallan ErrorF("Detected FFB2+/horizontal, "); 526dbbd9e4bSmacallan break; 527dbbd9e4bSmacallan default: 528dbbd9e4bSmacallan pFfb->ffb_type = ffb2_vertical; 529dbbd9e4bSmacallan ErrorF("Unknown boardID[%08x], assuming FFB2, ", sbits); 530dbbd9e4bSmacallan break; 531dbbd9e4bSmacallan }; 532dbbd9e4bSmacallan 533dbbd9e4bSmacallan if (sbits & (1 << 2)) { 534dbbd9e4bSmacallan ErrorF("DoubleRES, "); 535dbbd9e4bSmacallan pFfb->has_double_res = 1; 536dbbd9e4bSmacallan } else { 537dbbd9e4bSmacallan pFfb->has_double_res = 0; 538dbbd9e4bSmacallan } 539dbbd9e4bSmacallan if (sbits & (1 << 1)) { 540dbbd9e4bSmacallan ErrorF("Z-buffer, "); 541dbbd9e4bSmacallan pFfb->has_z_buffer = 1; 542dbbd9e4bSmacallan } else { 543dbbd9e4bSmacallan pFfb->has_z_buffer = 0; 544dbbd9e4bSmacallan } 545dbbd9e4bSmacallan if (sbits & (1 << 0)) { 546dbbd9e4bSmacallan /* This state really means to the driver that the double 547dbbd9e4bSmacallan * buffers are available for hw accelerate Dbe. When the 548dbbd9e4bSmacallan * FFB is in high-resolution mode, the buffers are combined 549dbbd9e4bSmacallan * into one single large framebuffer. So in high-resolution 550dbbd9e4bSmacallan * hw accelerated double-buffering is not available. 551dbbd9e4bSmacallan */ 552dbbd9e4bSmacallan if ((ffb->fbcfg0 & FFB_FBCFG0_RES_MASK) != FFB_FBCFG0_RES_HIGH) 553dbbd9e4bSmacallan pFfb->has_double_buffer = 1; 554dbbd9e4bSmacallan else 555dbbd9e4bSmacallan pFfb->has_double_buffer = 0; 556dbbd9e4bSmacallan } else { 557dbbd9e4bSmacallan pFfb->has_double_buffer = 0; 558dbbd9e4bSmacallan } 559dbbd9e4bSmacallan if (pFfb->has_double_buffer) 560dbbd9e4bSmacallan ErrorF("Double-buffered.\n"); 561dbbd9e4bSmacallan else 562dbbd9e4bSmacallan ErrorF("Single-buffered.\n"); 563dbbd9e4bSmacallan } 564dbbd9e4bSmacallan} 565dbbd9e4bSmacallan 566dbbd9e4bSmacallan/* Mandatory */ 567dbbd9e4bSmacallan 568dbbd9e4bSmacallan/* This gets called at the start of each server generation */ 569dbbd9e4bSmacallan 570dbbd9e4bSmacallanstatic Bool 5717a5333bcSmrgFFBScreenInit(SCREEN_INIT_ARGS_DECL) 572dbbd9e4bSmacallan{ 573dbbd9e4bSmacallan ScrnInfoPtr pScrn; 574dbbd9e4bSmacallan FFBPtr pFfb; 575dbbd9e4bSmacallan int ret; 576dbbd9e4bSmacallan unsigned int afb_fem; 577dbbd9e4bSmacallan VisualPtr visual; 578dbbd9e4bSmacallan 579dbbd9e4bSmacallan /* 580dbbd9e4bSmacallan * First get the ScrnInfoRec 581dbbd9e4bSmacallan */ 5827a5333bcSmrg pScrn = xf86ScreenToScrn(pScreen); 583dbbd9e4bSmacallan 584dbbd9e4bSmacallan pFfb = GET_FFB_FROM_SCRN(pScrn); 585dbbd9e4bSmacallan 586dbbd9e4bSmacallan /* Map the FFB framebuffer, for each view. */ 587dbbd9e4bSmacallan 588dbbd9e4bSmacallan /* 24-bit RGB Dumb view */ 589dbbd9e4bSmacallan pFfb->fb = pFfb->dfb24 = 590dbbd9e4bSmacallan xf86MapSbusMem (pFfb->psdp, FFB_DFB24_VOFF, 0x1000000); 591dbbd9e4bSmacallan 592dbbd9e4bSmacallan if (! pFfb->dfb24) 593dbbd9e4bSmacallan return FALSE; 594dbbd9e4bSmacallan 595dbbd9e4bSmacallan /* 8-bit R Dumb view */ 596dbbd9e4bSmacallan pFfb->dfb8r = 597dbbd9e4bSmacallan xf86MapSbusMem (pFfb->psdp, FFB_DFB8R_VOFF, 0x400000); 598dbbd9e4bSmacallan 599dbbd9e4bSmacallan if (! pFfb->dfb8r) 600dbbd9e4bSmacallan return FALSE; 601dbbd9e4bSmacallan 602dbbd9e4bSmacallan /* 8-bit X Dumb view */ 603dbbd9e4bSmacallan pFfb->dfb8x = 604dbbd9e4bSmacallan xf86MapSbusMem (pFfb->psdp, FFB_DFB8X_VOFF, 0x400000); 605dbbd9e4bSmacallan 606dbbd9e4bSmacallan if (! pFfb->dfb8x) 607dbbd9e4bSmacallan return FALSE; 608dbbd9e4bSmacallan 609dbbd9e4bSmacallan /* 32-bit RGB Smart view */ 610dbbd9e4bSmacallan pFfb->sfb32 = 611dbbd9e4bSmacallan xf86MapSbusMem (pFfb->psdp, FFB_SFB32_VOFF, 0x1000000); 612dbbd9e4bSmacallan 613dbbd9e4bSmacallan if (!pFfb->sfb32) 614dbbd9e4bSmacallan return FALSE; 615dbbd9e4bSmacallan 616dbbd9e4bSmacallan /* 8-bit R Smart view */ 617dbbd9e4bSmacallan pFfb->sfb8r = 618dbbd9e4bSmacallan xf86MapSbusMem(pFfb->psdp, FFB_SFB8R_VOFF, 0x400000); 619dbbd9e4bSmacallan 620dbbd9e4bSmacallan if (!pFfb->sfb8r) 621dbbd9e4bSmacallan return FALSE; 622dbbd9e4bSmacallan 623dbbd9e4bSmacallan /* 8-bit X Smart view */ 624dbbd9e4bSmacallan pFfb->sfb8x = 625dbbd9e4bSmacallan xf86MapSbusMem(pFfb->psdp, FFB_SFB8X_VOFF, 0x400000); 626dbbd9e4bSmacallan 627dbbd9e4bSmacallan if (!pFfb->sfb8x) 628dbbd9e4bSmacallan return FALSE; 629dbbd9e4bSmacallan 630dbbd9e4bSmacallan /* Map the rendering pipeline */ 631dbbd9e4bSmacallan pFfb->regs = 632dbbd9e4bSmacallan xf86MapSbusMem (pFfb->psdp, FFB_FBC_REGS_VOFF, 16384); 633dbbd9e4bSmacallan 634dbbd9e4bSmacallan if (! pFfb->regs) 635dbbd9e4bSmacallan return FALSE; 636dbbd9e4bSmacallan 637dbbd9e4bSmacallan /* Map the ramdac */ 638dbbd9e4bSmacallan pFfb->dac = 639dbbd9e4bSmacallan xf86MapSbusMem (pFfb->psdp, FFB_DAC_VOFF, 8192); 640dbbd9e4bSmacallan 641dbbd9e4bSmacallan if (! pFfb->dac) 642dbbd9e4bSmacallan return FALSE; 643dbbd9e4bSmacallan 644dbbd9e4bSmacallan /* Map the board strapping bits */ 645dbbd9e4bSmacallan pFfb->strapping_bits = (volatile unsigned int *) 646dbbd9e4bSmacallan xf86MapSbusMem(pFfb->psdp, FFB_EXP_VOFF, 8192); 647dbbd9e4bSmacallan 648dbbd9e4bSmacallan if (! pFfb->strapping_bits) 649dbbd9e4bSmacallan return FALSE; 650e33a93fdSmrg 651dbbd9e4bSmacallan /* Probe for the type of FFB/AFB we have. */ 652dbbd9e4bSmacallan FFBProbeBoardType(pFfb); 653dbbd9e4bSmacallan 654dbbd9e4bSmacallan /* Now that we have the board type, we can init the ramdac layer. */ 655dbbd9e4bSmacallan if (FFBDacInit(pFfb) == FALSE) 656dbbd9e4bSmacallan return FALSE; 657dbbd9e4bSmacallan 658dbbd9e4bSmacallan /* OK, a fun gross hack to detect if this is 659dbbd9e4bSmacallan * AFB and if so whether the correct firmware 660dbbd9e4bSmacallan * has been loaded. The machine will flatline 661dbbd9e4bSmacallan * if you try to use certain acceleration features 662dbbd9e4bSmacallan * without the full firmware loaded. 663dbbd9e4bSmacallan * 664dbbd9e4bSmacallan * The bootup Elite3D/AFB firmware is minimal, and 665dbbd9e4bSmacallan * will leave the FloatEnableMask register at a 666dbbd9e4bSmacallan * value of 0x01. Creator{,3D} lacks the FEM register 667dbbd9e4bSmacallan * and will return a "nonsense" value on attempts to 668dbbd9e4bSmacallan * read this location. After experimentation, an 669dbbd9e4bSmacallan * appropriate definition for "nonsense" seems to 670dbbd9e4bSmacallan * be anything with all low 7 bits not 0x3f, 0x07, 671dbbd9e4bSmacallan * of 0x01. 672dbbd9e4bSmacallan * 673dbbd9e4bSmacallan * If the FEM register is non-zero and is some value 674dbbd9e4bSmacallan * other than 0x1 (usually 0x3f or 0x7 depending upon 675dbbd9e4bSmacallan * whether the card has 3 or 6 floats) we can assume 676dbbd9e4bSmacallan * the correct firmware has been loaded. -DaveM 677dbbd9e4bSmacallan */ 678dbbd9e4bSmacallan afb_fem = *(unsigned int *)((char *)pFfb->regs + 0x1540); 679dbbd9e4bSmacallan if ((afb_fem & 0x7f) != 0x3f && 680dbbd9e4bSmacallan (afb_fem & 0x7f) != 0x07 && 681dbbd9e4bSmacallan (afb_fem & 0x7f) != 0x01) 682dbbd9e4bSmacallan xf86Msg(X_INFO, "%s: Detected Creator/Creator3D\n", pFfb->psdp->device); 683dbbd9e4bSmacallan else { 684dbbd9e4bSmacallan xf86Msg(X_INFO, "%s: Detected Elite3D M3/M6, checking firmware...\n", pFfb->psdp->device); 685dbbd9e4bSmacallan if (afb_fem == 0x1) { 686dbbd9e4bSmacallan xf86Msg(X_INFO, "%s: ... AFB firmware not loaded\n", pFfb->psdp->device); 687dbbd9e4bSmacallan if (!pFfb->NoAccel) { 688dbbd9e4bSmacallan xf86Msg(X_WARNING, "%s: Forcing no acceleration on Elite3D M3/M6\n", pFfb->psdp->device); 689dbbd9e4bSmacallan pFfb->NoAccel = TRUE; 690dbbd9e4bSmacallan } 691dbbd9e4bSmacallan } else 692dbbd9e4bSmacallan xf86Msg(X_INFO, "%s: ... AFB firmware is loaded\n", pFfb->psdp->device); 693dbbd9e4bSmacallan } 694dbbd9e4bSmacallan 695dbbd9e4bSmacallan /* Darken the screen for aesthetic reasons and set the viewport */ 6966adf905bSmacallan /* XXX can't do this yet */ 6976adf905bSmacallan /* FFBSaveScreen(pScreen, SCREEN_SAVER_ON);*/ 698dbbd9e4bSmacallan 699dbbd9e4bSmacallan /* 700dbbd9e4bSmacallan * The next step is to setup the screen's visuals, and initialise the 701dbbd9e4bSmacallan * framebuffer code. In cases where the framebuffer's default 702dbbd9e4bSmacallan * choices for things like visual layouts and bits per RGB are OK, 703dbbd9e4bSmacallan * this may be as simple as calling the framebuffer's ScreenInit() 704dbbd9e4bSmacallan * function. If not, the visuals will need to be setup before calling 705dbbd9e4bSmacallan * a fb ScreenInit() function and fixed up after. 706dbbd9e4bSmacallan */ 707dbbd9e4bSmacallan 708dbbd9e4bSmacallan /* 709dbbd9e4bSmacallan * Reset visual list. 710dbbd9e4bSmacallan */ 711dbbd9e4bSmacallan miClearVisualTypes(); 712dbbd9e4bSmacallan 713dbbd9e4bSmacallan /* Setup the visuals we support. */ 714dbbd9e4bSmacallan if (!miSetVisualTypes(24, TrueColorMask, 715dbbd9e4bSmacallan pScrn->rgbBits, TrueColor)) 716dbbd9e4bSmacallan return FALSE; 717dbbd9e4bSmacallan 718dbbd9e4bSmacallan if (!miSetPixmapDepths()) 719dbbd9e4bSmacallan return FALSE; 720dbbd9e4bSmacallan 721dbbd9e4bSmacallan /* 722dbbd9e4bSmacallan * Call the framebuffer layer's ScreenInit function, and fill in other 723dbbd9e4bSmacallan * pScreen fields. 724dbbd9e4bSmacallan */ 725dbbd9e4bSmacallan ret = fbScreenInit(pScreen, (pFfb->NoAccel ? pFfb->dfb24 : pFfb->sfb32), 726dbbd9e4bSmacallan pScrn->virtualX, pScrn->virtualY, 727dbbd9e4bSmacallan pScrn->xDpi, pScrn->yDpi, 728dbbd9e4bSmacallan 2048, 32); 729dbbd9e4bSmacallan 730dbbd9e4bSmacallan if (!ret) 731dbbd9e4bSmacallan return FALSE; 732dbbd9e4bSmacallan 733dbbd9e4bSmacallan if (pScrn->bitsPerPixel > 8) { 734dbbd9e4bSmacallan /* Fixup RGB ordering */ 735dbbd9e4bSmacallan visual = pScreen->visuals + pScreen->numVisuals; 736dbbd9e4bSmacallan while (--visual >= pScreen->visuals) { 737dbbd9e4bSmacallan if ((visual->class | DynamicClass) == DirectColor) { 738dbbd9e4bSmacallan visual->offsetRed = pScrn->offset.red; 739dbbd9e4bSmacallan visual->offsetGreen = pScrn->offset.green; 740dbbd9e4bSmacallan visual->offsetBlue = pScrn->offset.blue; 741dbbd9e4bSmacallan visual->redMask = pScrn->mask.red; 742dbbd9e4bSmacallan visual->greenMask = pScrn->mask.green; 743dbbd9e4bSmacallan visual->blueMask = pScrn->mask.blue; 744dbbd9e4bSmacallan } 745dbbd9e4bSmacallan } 746dbbd9e4bSmacallan } 747dbbd9e4bSmacallan 748dbbd9e4bSmacallan if (!fbPictureInit(pScreen, NULL, 0) && 749dbbd9e4bSmacallan (serverGeneration == 1)) 750dbbd9e4bSmacallan xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 751dbbd9e4bSmacallan "RENDER extension initialisation failed.\n"); 752dbbd9e4bSmacallan 753dbbd9e4bSmacallan xf86SetBlackWhitePixels(pScreen); 754dbbd9e4bSmacallan 755dbbd9e4bSmacallan if (!pFfb->NoAccel) { 75689b0bd4cSmacallan char *optstr; 75789b0bd4cSmacallan optstr = (char *)xf86GetOptValString(pFfb->Options, OPTION_ACCELMETHOD); 75880d4424cSmacallan#ifdef HAVE_XAA_H 75989b0bd4cSmacallan if (optstr == NULL) optstr = "xaa"; 76080d4424cSmacallan#else 76180d4424cSmacallan if (optstr == NULL) optstr = "exa"; 76280d4424cSmacallan#endif 76389b0bd4cSmacallan if (xf86NameCmp(optstr, "EXA") == 0) { 76489b0bd4cSmacallan xf86Msg(X_INFO, "using EXA\n"); 76525ad54caSmrg if (xf86LoadSubModule(pScrn, "exa") == NULL || 76625ad54caSmrg !FFBInitEXA(pScreen)) { 76725ad54caSmrg pFfb->NoAccel = TRUE; 76825ad54caSmrg return FALSE; 76989b0bd4cSmacallan } 77080d4424cSmacallan } 77180d4424cSmacallan#ifdef HAVE_XAA_H 77280d4424cSmacallan else if (xf86NameCmp(optstr, "XAA") == 0) { 77389b0bd4cSmacallan xf86Msg(X_INFO, "using XAA\n"); 77425ad54caSmrg if (xf86LoadSubModule(pScrn, "xaa") == NULL || 77525ad54caSmrg !FFBAccelInit(pScreen, pFfb)) { 77625ad54caSmrg pFfb->NoAccel = TRUE; 77725ad54caSmrg return FALSE; 77889b0bd4cSmacallan } 77989b0bd4cSmacallan } 78080d4424cSmacallan#endif 781dbbd9e4bSmacallan } 782dbbd9e4bSmacallan 783dbbd9e4bSmacallan 784dbbd9e4bSmacallan xf86SetBackingStore(pScreen); 785dbbd9e4bSmacallan xf86SetSilkenMouse(pScreen); 786dbbd9e4bSmacallan 787dbbd9e4bSmacallan /* Initialise cursor functions */ 788dbbd9e4bSmacallan miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); 789dbbd9e4bSmacallan 790dbbd9e4bSmacallan /* Initialize HW cursor layer. 791dbbd9e4bSmacallan * Must follow software cursor initialization. 792dbbd9e4bSmacallan */ 793dbbd9e4bSmacallan if (pFfb->HWCursor) { 794dbbd9e4bSmacallan if(!FFBHWCursorInit(pScreen)) { 795dbbd9e4bSmacallan xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 796dbbd9e4bSmacallan "Hardware cursor initialization failed\n"); 797dbbd9e4bSmacallan return(FALSE); 798dbbd9e4bSmacallan } 799dbbd9e4bSmacallan xf86SbusHideOsHwCursor(pFfb->psdp); 800dbbd9e4bSmacallan } 801dbbd9e4bSmacallan 802dbbd9e4bSmacallan /* Initialise default colourmap. */ 803dbbd9e4bSmacallan if (!miCreateDefColormap(pScreen)) 804dbbd9e4bSmacallan return FALSE; 805dbbd9e4bSmacallan 806dbbd9e4bSmacallan /* Initialize colormap layer. 807dbbd9e4bSmacallan * Must follow initialization of the default colormap. 808dbbd9e4bSmacallan */ 809dbbd9e4bSmacallan if (!xf86HandleColormaps(pScreen, 256, 8, 810dbbd9e4bSmacallan FFBDacLoadPalette, NULL, 811dbbd9e4bSmacallan CMAP_LOAD_EVEN_IF_OFFSCREEN | 812dbbd9e4bSmacallan CMAP_RELOAD_ON_MODE_SWITCH)) 813dbbd9e4bSmacallan return FALSE; 814dbbd9e4bSmacallan 815dbbd9e4bSmacallan /* Setup DGA support. */ 816dbbd9e4bSmacallan if (!pFfb->NoAccel) 817dbbd9e4bSmacallan FFB_InitDGA(pScreen); 818dbbd9e4bSmacallan 819dbbd9e4bSmacallan xf86DPMSInit(pScreen, FFBDPMSSet, 0); 820dbbd9e4bSmacallan 821dbbd9e4bSmacallan pFfb->CloseScreen = pScreen->CloseScreen; 822dbbd9e4bSmacallan pScreen->CloseScreen = FFBCloseScreen; 823dbbd9e4bSmacallan pScreen->SaveScreen = FFBSaveScreen; 824dbbd9e4bSmacallan 825dbbd9e4bSmacallan (void) xf86DPMSInit(pScreen, FFBDPMSMode, 0); 826dbbd9e4bSmacallan 827dbbd9e4bSmacallan /* Report any unused options (only for the first generation) */ 828dbbd9e4bSmacallan if (serverGeneration == 1) { 829dbbd9e4bSmacallan xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 830dbbd9e4bSmacallan } 831dbbd9e4bSmacallan 832dbbd9e4bSmacallan /* unblank the screen */ 8336adf905bSmacallan /* XXX since we didn't blank it we don't need to unblank it here */ 8346adf905bSmacallan /* FFBSaveScreen(pScreen, SCREEN_SAVER_OFF); */ 835dbbd9e4bSmacallan 836dbbd9e4bSmacallan /* Done */ 837dbbd9e4bSmacallan return TRUE; 838dbbd9e4bSmacallan} 839dbbd9e4bSmacallan 840dbbd9e4bSmacallan 841dbbd9e4bSmacallan/* Usually mandatory */ 842dbbd9e4bSmacallanstatic Bool 8437a5333bcSmrgFFBSwitchMode(SWITCH_MODE_ARGS_DECL) 844dbbd9e4bSmacallan{ 845dbbd9e4bSmacallan return TRUE; 846dbbd9e4bSmacallan} 847dbbd9e4bSmacallan 848dbbd9e4bSmacallan 849dbbd9e4bSmacallan/* 850dbbd9e4bSmacallan * This function is used to initialize the Start Address - the first 851dbbd9e4bSmacallan * displayed location in the video memory. 852dbbd9e4bSmacallan */ 853dbbd9e4bSmacallan/* Usually mandatory */ 854dbbd9e4bSmacallanstatic void 8557a5333bcSmrgFFBAdjustFrame(ADJUST_FRAME_ARGS_DECL) 856dbbd9e4bSmacallan{ 857dbbd9e4bSmacallan /* we don't support virtual desktops */ 858dbbd9e4bSmacallan return; 859dbbd9e4bSmacallan} 860dbbd9e4bSmacallan 861dbbd9e4bSmacallan/* 862dbbd9e4bSmacallan * This is called when VT switching back to the X server. Its job is 863dbbd9e4bSmacallan * to reinitialise the video mode. 864dbbd9e4bSmacallan */ 865dbbd9e4bSmacallan 866dbbd9e4bSmacallan/* Mandatory */ 867dbbd9e4bSmacallanstatic Bool 8687a5333bcSmrgFFBEnterVT(VT_FUNC_ARGS_DECL) 869dbbd9e4bSmacallan{ 8707a5333bcSmrg SCRN_INFO_PTR(arg); 871dbbd9e4bSmacallan FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 872dbbd9e4bSmacallan 873dbbd9e4bSmacallan pFfb->vtSema = FALSE; 874dbbd9e4bSmacallan if (!pFfb->NoAccel) 875dbbd9e4bSmacallan CreatorVtChange (pScrn->pScreen, TRUE); 876dbbd9e4bSmacallan if (pFfb->HWCursor) 877dbbd9e4bSmacallan xf86SbusHideOsHwCursor (pFfb->psdp); 878dbbd9e4bSmacallan 879dbbd9e4bSmacallan FFBDacEnterVT(pFfb); 880dbbd9e4bSmacallan 881dbbd9e4bSmacallan return TRUE; 882dbbd9e4bSmacallan} 883dbbd9e4bSmacallan 884dbbd9e4bSmacallan 885dbbd9e4bSmacallan/* 886dbbd9e4bSmacallan * This is called when VT switching away from the X server. 887dbbd9e4bSmacallan */ 888dbbd9e4bSmacallan 889dbbd9e4bSmacallan/* Mandatory */ 890dbbd9e4bSmacallanstatic void 8917a5333bcSmrgFFBLeaveVT(VT_FUNC_ARGS_DECL) 892dbbd9e4bSmacallan{ 8937a5333bcSmrg SCRN_INFO_PTR(arg); 894dbbd9e4bSmacallan FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 895dbbd9e4bSmacallan 896dbbd9e4bSmacallan FFBDacLeaveVT(pFfb); 897dbbd9e4bSmacallan 898dbbd9e4bSmacallan if (!pFfb->NoAccel) 899dbbd9e4bSmacallan CreatorVtChange (pScrn->pScreen, FALSE); 900dbbd9e4bSmacallan 901dbbd9e4bSmacallan if (pFfb->HWCursor) 902dbbd9e4bSmacallan xf86SbusHideOsHwCursor (pFfb->psdp); 903dbbd9e4bSmacallan 904dbbd9e4bSmacallan pFfb->vtSema = TRUE; 905dbbd9e4bSmacallan return; 906dbbd9e4bSmacallan} 907dbbd9e4bSmacallan 908dbbd9e4bSmacallan 909dbbd9e4bSmacallan/* 910dbbd9e4bSmacallan * This is called at the end of each server generation. It restores the 911dbbd9e4bSmacallan * original (text) mode. It should really also unmap the video memory too. 912dbbd9e4bSmacallan */ 913dbbd9e4bSmacallan 914dbbd9e4bSmacallan/* Mandatory */ 915dbbd9e4bSmacallanstatic Bool 9167a5333bcSmrgFFBCloseScreen(CLOSE_SCREEN_ARGS_DECL) 917dbbd9e4bSmacallan{ 9187a5333bcSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 919dbbd9e4bSmacallan FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 920dbbd9e4bSmacallan 921cc45f3ffSmacallan FFBDacCursorEnableDisable(pFfb, 0); 922dbbd9e4bSmacallan /* Restore kernel ramdac state before we unmap registers. */ 923dbbd9e4bSmacallan FFBDacFini(pFfb); 924dbbd9e4bSmacallan 925dbbd9e4bSmacallan pScrn->vtSema = FALSE; 926dbbd9e4bSmacallan 927dbbd9e4bSmacallan xf86UnmapSbusMem(pFfb->psdp, pFfb->dfb24, 0x1000000); 928dbbd9e4bSmacallan xf86UnmapSbusMem(pFfb->psdp, pFfb->dfb8r, 0x400000); 929dbbd9e4bSmacallan xf86UnmapSbusMem(pFfb->psdp, pFfb->dfb8x, 0x400000); 930dbbd9e4bSmacallan xf86UnmapSbusMem(pFfb->psdp, pFfb->sfb32, 0x1000000); 931dbbd9e4bSmacallan xf86UnmapSbusMem(pFfb->psdp, pFfb->sfb8r, 0x400000); 932dbbd9e4bSmacallan xf86UnmapSbusMem(pFfb->psdp, pFfb->sfb8x, 0x400000); 933dbbd9e4bSmacallan xf86UnmapSbusMem(pFfb->psdp, pFfb->regs, 16384); 934dbbd9e4bSmacallan xf86UnmapSbusMem(pFfb->psdp, pFfb->dac, 8192); 935dbbd9e4bSmacallan xf86UnmapSbusMem(pFfb->psdp, (void *)pFfb->strapping_bits, 8192); 936dbbd9e4bSmacallan 937dbbd9e4bSmacallan if (pFfb->HWCursor) 938dbbd9e4bSmacallan xf86SbusHideOsHwCursor (pFfb->psdp); 939dbbd9e4bSmacallan 940dbbd9e4bSmacallan pScreen->CloseScreen = pFfb->CloseScreen; 9417a5333bcSmrg return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS); 942dbbd9e4bSmacallan} 943dbbd9e4bSmacallan 944dbbd9e4bSmacallan 945dbbd9e4bSmacallan/* Free up any per-generation data structures */ 946dbbd9e4bSmacallan 947dbbd9e4bSmacallan/* Optional */ 948dbbd9e4bSmacallanstatic void 9497a5333bcSmrgFFBFreeScreen(FREE_SCREEN_ARGS_DECL) 950dbbd9e4bSmacallan{ 9517a5333bcSmrg SCRN_INFO_PTR(arg); 9527a5333bcSmrg FFBFreeRec(pScrn); 953dbbd9e4bSmacallan} 954dbbd9e4bSmacallan 955dbbd9e4bSmacallan 956dbbd9e4bSmacallan/* Checks if a mode is suitable for the selected chipset. */ 957dbbd9e4bSmacallan 958dbbd9e4bSmacallan/* Optional */ 959dbbd9e4bSmacallanstatic ModeStatus 9607a5333bcSmrgFFBValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) 961dbbd9e4bSmacallan{ 962dbbd9e4bSmacallan if (mode->Flags & V_INTERLACE) 963dbbd9e4bSmacallan return MODE_BAD; 964dbbd9e4bSmacallan 965dbbd9e4bSmacallan return MODE_OK; 966dbbd9e4bSmacallan} 967dbbd9e4bSmacallan 968dbbd9e4bSmacallan/* Do screen blanking */ 969dbbd9e4bSmacallan 970dbbd9e4bSmacallan/* Mandatory */ 971dbbd9e4bSmacallanstatic Bool 972dbbd9e4bSmacallanFFBSaveScreen(ScreenPtr pScreen, int mode) 973dbbd9e4bSmacallan /* This function blanks the screen when mode=SCREEN_SAVER_ON and 974dbbd9e4bSmacallan unblanks it when mode=SCREEN_SAVER_OFF. It is used internally in the 975dbbd9e4bSmacallan FFBScreenInit code `for aesthetic reasons,' and it is used for 976dbbd9e4bSmacallan blanking if you set "xset s on s blank." The work (such as it is) is 977dbbd9e4bSmacallan done in "ffb_dac.c" `for aesthetic reasons.' 978dbbd9e4bSmacallan */ 979dbbd9e4bSmacallan{ 980dbbd9e4bSmacallan 981ec319841Smacallan return FFBDacSaveScreen(pScreen, mode); 982dbbd9e4bSmacallan} 983dbbd9e4bSmacallan 984dbbd9e4bSmacallanstatic void 985dbbd9e4bSmacallanFFBDPMSSet(ScrnInfoPtr pScrn, int mode, int flags) 986dbbd9e4bSmacallan{ 987dbbd9e4bSmacallan FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 988dbbd9e4bSmacallan 989dbbd9e4bSmacallan FFBDacDPMSMode(pFfb, mode, 0); 990dbbd9e4bSmacallan} 991dbbd9e4bSmacallan 992dbbd9e4bSmacallan/* 993dbbd9e4bSmacallan * This is the implementation of the Sync() function. 994dbbd9e4bSmacallan */ 995dbbd9e4bSmacallanvoid 996dbbd9e4bSmacallanFFBSync(ScrnInfoPtr pScrn) 997dbbd9e4bSmacallan{ 998dbbd9e4bSmacallan return; 999dbbd9e4bSmacallan} 1000dbbd9e4bSmacallan 1001dbbd9e4bSmacallan/* 1002dbbd9e4bSmacallan Hook for DPMS Mode. 1003dbbd9e4bSmacallan*/ 1004dbbd9e4bSmacallan 1005dbbd9e4bSmacallanstatic void 1006dbbd9e4bSmacallanFFBDPMSMode(ScrnInfoPtr pScrn, int DPMSMode, int flags) 1007dbbd9e4bSmacallan{ 1008dbbd9e4bSmacallan FFBDacDPMSMode(GET_FFB_FROM_SCRN(pScrn), DPMSMode, flags); 1009dbbd9e4bSmacallan} 10105d1b25cdSmacallan 10115d1b25cdSmacallanstatic Bool 10125d1b25cdSmacallanFFBDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, 10135d1b25cdSmacallan pointer ptr) 10145d1b25cdSmacallan{ 10155d1b25cdSmacallan xorgHWFlags *flag; 10165d1b25cdSmacallan 10175d1b25cdSmacallan switch (op) { 10185d1b25cdSmacallan case GET_REQUIRED_HW_INTERFACES: 10195d1b25cdSmacallan flag = (CARD32*)ptr; 10205d1b25cdSmacallan (*flag) = HW_MMIO; 10215d1b25cdSmacallan return TRUE; 10225d1b25cdSmacallan default: 10235d1b25cdSmacallan return FALSE; 10245d1b25cdSmacallan } 10255d1b25cdSmacallan} 10265d1b25cdSmacallan 1027