ag10e_driver.c revision 98bb403a
198bb403aSmacallan/* 298bb403aSmacallan * Fujitsu AG-10e framebuffer driver. 398bb403aSmacallan * 498bb403aSmacallan * Copyright (C) 2007 Michael Lorenz 598bb403aSmacallan * 698bb403aSmacallan * Permission is hereby granted, free of charge, to any person obtaining a copy 798bb403aSmacallan * of this software and associated documentation files (the "Software"), to deal 898bb403aSmacallan * in the Software without restriction, including without limitation the rights 998bb403aSmacallan * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 1098bb403aSmacallan * copies of the Software, and to permit persons to whom the Software is 1198bb403aSmacallan * furnished to do so, subject to the following conditions: 1298bb403aSmacallan * 1398bb403aSmacallan * The above copyright notice and this permission notice shall be included in 1498bb403aSmacallan * all copies or substantial portions of the Software. 1598bb403aSmacallan * 1698bb403aSmacallan * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1798bb403aSmacallan * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1898bb403aSmacallan * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1998bb403aSmacallan * JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 2098bb403aSmacallan * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 2198bb403aSmacallan * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2298bb403aSmacallan */ 2398bb403aSmacallan/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/suncg6/cg6_driver.c,v 1.12 2005/02/18 02:55:09 dawes Exp $ */ 2498bb403aSmacallan 2598bb403aSmacallan/* need this for PRIxPTR macro */ 2698bb403aSmacallan 2798bb403aSmacallan#ifdef HAVE_CONFIG_H 2898bb403aSmacallan#include "config.h" 2998bb403aSmacallan#endif 3098bb403aSmacallan 3198bb403aSmacallan#include <fcntl.h> 3298bb403aSmacallan#include <sys/time.h> 3398bb403aSmacallan#include <sys/types.h> 3498bb403aSmacallan#include <dev/sun/fbio.h> 3598bb403aSmacallan#include <dev/wscons/wsconsio.h> 3698bb403aSmacallan 3798bb403aSmacallan#include <machine/int_fmtio.h> 3898bb403aSmacallan#include "xf86.h" 3998bb403aSmacallan#include "xf86_OSproc.h" 4098bb403aSmacallan#include "xf86_ansic.h" 4198bb403aSmacallan#include "xf86Version.h" 4298bb403aSmacallan#include "mipointer.h" 4398bb403aSmacallan#include "mibstore.h" 4498bb403aSmacallan#include "micmap.h" 4598bb403aSmacallan 4698bb403aSmacallan#include "fb.h" 4798bb403aSmacallan#include "xf86cmap.h" 4898bb403aSmacallan#include "ag10e.h" 4998bb403aSmacallan#include "xf86sbusBus.h" 5098bb403aSmacallan 5198bb403aSmacallanstatic const OptionInfoRec * AG10EAvailableOptions(int chipid, int busid); 5298bb403aSmacallanstatic void AG10EIdentify(int flags); 5398bb403aSmacallanstatic Bool AG10EProbe(DriverPtr drv, int flags); 5498bb403aSmacallanstatic Bool AG10EPreInit(ScrnInfoPtr pScrn, int flags); 5598bb403aSmacallanstatic Bool AG10EScreenInit(int Index, ScreenPtr pScreen, int argc, 5698bb403aSmacallan char **argv); 5798bb403aSmacallanstatic Bool AG10EEnterVT(int scrnIndex, int flags); 5898bb403aSmacallanstatic void AG10ELeaveVT(int scrnIndex, int flags); 5998bb403aSmacallanstatic Bool AG10ECloseScreen(int scrnIndex, ScreenPtr pScreen); 6098bb403aSmacallanstatic Bool AG10ESaveScreen(ScreenPtr pScreen, int mode); 6198bb403aSmacallan 6298bb403aSmacallan/* Required if the driver supports mode switching */ 6398bb403aSmacallanstatic Bool AG10ESwitchMode(int scrnIndex, DisplayModePtr mode, int flags); 6498bb403aSmacallan/* Required if the driver supports moving the viewport */ 6598bb403aSmacallanstatic void AG10EAdjustFrame(int scrnIndex, int x, int y, int flags); 6698bb403aSmacallan 6798bb403aSmacallan/* Optional functions */ 6898bb403aSmacallanstatic void AG10EFreeScreen(int scrnIndex, int flags); 6998bb403aSmacallanstatic ModeStatus AG10EValidMode(int scrnIndex, DisplayModePtr mode, 7098bb403aSmacallan Bool verbose, int flags); 7198bb403aSmacallan 7298bb403aSmacallan#define VERSION 4000 7398bb403aSmacallan#define AG10E_NAME "AG10E" 7498bb403aSmacallan#define AG10E_DRIVER_NAME "ag10e" 7598bb403aSmacallan#define AG10E_MAJOR_VERSION 1 7698bb403aSmacallan#define AG10E_MINOR_VERSION 0 7798bb403aSmacallan#define AG10E_PATCHLEVEL 0 7898bb403aSmacallan 7998bb403aSmacallan/* 8098bb403aSmacallan * This contains the functions needed by the server after loading the driver 8198bb403aSmacallan * module. It must be supplied, and gets passed back by the SetupProc 8298bb403aSmacallan * function in the dynamic case. In the static case, a reference to this 8398bb403aSmacallan * is compiled in, and this requires that the name of this DriverRec be 8498bb403aSmacallan * an upper-case version of the driver name. 8598bb403aSmacallan */ 8698bb403aSmacallan 8798bb403aSmacallanDriverRec AG10E = { 8898bb403aSmacallan VERSION, 8998bb403aSmacallan AG10E_DRIVER_NAME, 9098bb403aSmacallan AG10EIdentify, 9198bb403aSmacallan AG10EProbe, 9298bb403aSmacallan AG10EAvailableOptions, 9398bb403aSmacallan NULL, 9498bb403aSmacallan 0 9598bb403aSmacallan}; 9698bb403aSmacallan 9798bb403aSmacallantypedef enum { 9898bb403aSmacallan OPTION_SW_CURSOR, 9998bb403aSmacallan OPTION_HW_CURSOR, 10098bb403aSmacallan OPTION_NOACCEL 10198bb403aSmacallan} AG10EOpts; 10298bb403aSmacallan 10398bb403aSmacallanstatic const OptionInfoRec AG10EOptions[] = { 10498bb403aSmacallan { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, 10598bb403aSmacallan { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, 10698bb403aSmacallan { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 10798bb403aSmacallan { -1, NULL, OPTV_NONE, {0}, FALSE } 10898bb403aSmacallan}; 10998bb403aSmacallan 11098bb403aSmacallanstatic const char *xaaSymbols[] = 11198bb403aSmacallan{ 11298bb403aSmacallan "XAACreateInfoRec", 11398bb403aSmacallan "XAADestroyInfoRec", 11498bb403aSmacallan "XAAInit", 11598bb403aSmacallan NULL 11698bb403aSmacallan}; 11798bb403aSmacallan 11898bb403aSmacallan#ifdef XFree86LOADER 11998bb403aSmacallan 12098bb403aSmacallanstatic MODULESETUPPROTO(AG10ESetup); 12198bb403aSmacallan 12298bb403aSmacallanstatic XF86ModuleVersionInfo AG10EVersRec = 12398bb403aSmacallan{ 12498bb403aSmacallan "ag10e", 12598bb403aSmacallan MODULEVENDORSTRING, 12698bb403aSmacallan MODINFOSTRING1, 12798bb403aSmacallan MODINFOSTRING2, 12898bb403aSmacallan XORG_VERSION_CURRENT, 12998bb403aSmacallan AG10E_MAJOR_VERSION, AG10E_MINOR_VERSION, AG10E_PATCHLEVEL, 13098bb403aSmacallan ABI_CLASS_VIDEODRV, 13198bb403aSmacallan ABI_VIDEODRV_VERSION, 13298bb403aSmacallan MOD_CLASS_VIDEODRV, 13398bb403aSmacallan {0,0,0,0} 13498bb403aSmacallan}; 13598bb403aSmacallan 13698bb403aSmacallan_X_EXPORT XF86ModuleData ag10eModuleData = { &AG10EVersRec, AG10ESetup, NULL }; 13798bb403aSmacallan 13898bb403aSmacallanstatic pointer 13998bb403aSmacallanAG10ESetup(pointer module, pointer opts, int *errmaj, int *errmin) 14098bb403aSmacallan{ 14198bb403aSmacallan static Bool setupDone = FALSE; 14298bb403aSmacallan 14398bb403aSmacallan if (!setupDone) { 14498bb403aSmacallan setupDone = TRUE; 14598bb403aSmacallan xf86AddDriver(&AG10E, module, 0); 14698bb403aSmacallan 14798bb403aSmacallan /* 14898bb403aSmacallan * Modules that this driver always requires can be loaded here 14998bb403aSmacallan * by calling LoadSubModule(). 15098bb403aSmacallan */ 15198bb403aSmacallan LoaderRefSymLists(xaaSymbols, NULL); 15298bb403aSmacallan 15398bb403aSmacallan /* 15498bb403aSmacallan * The return value must be non-NULL on success even though there 15598bb403aSmacallan * is no TearDownProc. 15698bb403aSmacallan */ 15798bb403aSmacallan return (pointer)TRUE; 15898bb403aSmacallan } else { 15998bb403aSmacallan if (errmaj) *errmaj = LDR_ONCEONLY; 16098bb403aSmacallan return NULL; 16198bb403aSmacallan } 16298bb403aSmacallan} 16398bb403aSmacallan 16498bb403aSmacallan#endif /* XFree86LOADER */ 16598bb403aSmacallan 16698bb403aSmacallanstatic Bool 16798bb403aSmacallanAG10EGetRec(ScrnInfoPtr pScrn) 16898bb403aSmacallan{ 16998bb403aSmacallan /* 17098bb403aSmacallan * Allocate an AG10ERec, and hook it into pScrn->driverPrivate. 17198bb403aSmacallan * pScrn->driverPrivate is initialised to NULL, so we can check if 17298bb403aSmacallan * the allocation has already been done. 17398bb403aSmacallan */ 17498bb403aSmacallan if (pScrn->driverPrivate != NULL) 17598bb403aSmacallan return TRUE; 17698bb403aSmacallan 17798bb403aSmacallan pScrn->driverPrivate = xnfcalloc(sizeof(AG10ERec), 1); 17898bb403aSmacallan return TRUE; 17998bb403aSmacallan} 18098bb403aSmacallan 18198bb403aSmacallanstatic void 18298bb403aSmacallanAG10EFreeRec(ScrnInfoPtr pScrn) 18398bb403aSmacallan{ 18498bb403aSmacallan AG10EPtr pAG10E; 18598bb403aSmacallan 18698bb403aSmacallan if (pScrn->driverPrivate == NULL) 18798bb403aSmacallan return; 18898bb403aSmacallan 18998bb403aSmacallan pAG10E = GET_AG10E_FROM_SCRN(pScrn); 19098bb403aSmacallan 19198bb403aSmacallan xfree(pScrn->driverPrivate); 19298bb403aSmacallan pScrn->driverPrivate = NULL; 19398bb403aSmacallan 19498bb403aSmacallan return; 19598bb403aSmacallan} 19698bb403aSmacallan 19798bb403aSmacallanstatic const OptionInfoRec * 19898bb403aSmacallanAG10EAvailableOptions(int chipid, int busid) 19998bb403aSmacallan{ 20098bb403aSmacallan return AG10EOptions; 20198bb403aSmacallan} 20298bb403aSmacallan 20398bb403aSmacallan/* Mandatory */ 20498bb403aSmacallanstatic void 20598bb403aSmacallanAG10EIdentify(int flags) 20698bb403aSmacallan{ 20798bb403aSmacallan xf86Msg(X_INFO, "%s: driver for Fujitsu AG-10e\n", AG10E_NAME); 20898bb403aSmacallan} 20998bb403aSmacallan 21098bb403aSmacallan 21198bb403aSmacallan/* Mandatory */ 21298bb403aSmacallanstatic Bool 21398bb403aSmacallanAG10EProbe(DriverPtr drv, int flags) 21498bb403aSmacallan{ 21598bb403aSmacallan int i; 21698bb403aSmacallan GDevPtr *devSections; 21798bb403aSmacallan int *usedChips; 21898bb403aSmacallan int numDevSections; 21998bb403aSmacallan int numUsed; 22098bb403aSmacallan Bool foundScreen = FALSE; 22198bb403aSmacallan EntityInfoPtr pEnt; 22298bb403aSmacallan 22398bb403aSmacallan /* 22498bb403aSmacallan * The aim here is to find all cards that this driver can handle, 22598bb403aSmacallan * and for the ones not already claimed by another driver, claim the 22698bb403aSmacallan * slot, and allocate a ScrnInfoRec. 22798bb403aSmacallan * 22898bb403aSmacallan * This should be a minimal probe, and it should under no circumstances 22998bb403aSmacallan * change the state of the hardware. Because a device is found, don't 23098bb403aSmacallan * assume that it will be used. Don't do any initialisations other than 23198bb403aSmacallan * the required ScrnInfoRec initialisations. Don't allocate any new 23298bb403aSmacallan * data structures. 23398bb403aSmacallan */ 23498bb403aSmacallan 23598bb403aSmacallan /* 23698bb403aSmacallan * Next we check, if there has been a chipset override in the config file. 23798bb403aSmacallan * For this we must find out if there is an active device section which 23898bb403aSmacallan * is relevant, i.e., which has no driver specified or has THIS driver 23998bb403aSmacallan * specified. 24098bb403aSmacallan */ 24198bb403aSmacallan 24298bb403aSmacallan if ((numDevSections = xf86MatchDevice(AG10E_DRIVER_NAME, 24398bb403aSmacallan &devSections)) <= 0) { 24498bb403aSmacallan /* 24598bb403aSmacallan * There's no matching device section in the config file, so quit 24698bb403aSmacallan * now. 24798bb403aSmacallan */ 24898bb403aSmacallan return FALSE; 24998bb403aSmacallan } 25098bb403aSmacallan 25198bb403aSmacallan /* 25298bb403aSmacallan * We need to probe the hardware first. We then need to see how this 25398bb403aSmacallan * fits in with what is given in the config file, and allow the config 25498bb403aSmacallan * file info to override any contradictions. 25598bb403aSmacallan */ 25698bb403aSmacallan 25798bb403aSmacallan numUsed = xf86MatchSbusInstances(AG10E_NAME, SBUS_DEVICE_AG10E, 25898bb403aSmacallan devSections, numDevSections, 25998bb403aSmacallan drv, &usedChips); 26098bb403aSmacallan 26198bb403aSmacallan xfree(devSections); 26298bb403aSmacallan if (numUsed <= 0) 26398bb403aSmacallan return FALSE; 26498bb403aSmacallan 26598bb403aSmacallan if (flags & PROBE_DETECT) 26698bb403aSmacallan foundScreen = TRUE; 26798bb403aSmacallan else for (i = 0; i < numUsed; i++) { 26898bb403aSmacallan pEnt = xf86GetEntityInfo(usedChips[i]); 26998bb403aSmacallan 27098bb403aSmacallan /* 27198bb403aSmacallan * Check that nothing else has claimed the slots. 27298bb403aSmacallan */ 27398bb403aSmacallan if(pEnt->active) { 27498bb403aSmacallan ScrnInfoPtr pScrn; 27598bb403aSmacallan 27698bb403aSmacallan /* Allocate a ScrnInfoRec and claim the slot */ 27798bb403aSmacallan pScrn = xf86AllocateScreen(drv, 0); 27898bb403aSmacallan 27998bb403aSmacallan /* Fill in what we can of the ScrnInfoRec */ 28098bb403aSmacallan pScrn->driverVersion = VERSION; 28198bb403aSmacallan pScrn->driverName = AG10E_DRIVER_NAME; 28298bb403aSmacallan pScrn->name = AG10E_NAME; 28398bb403aSmacallan pScrn->Probe = AG10EProbe; 28498bb403aSmacallan pScrn->PreInit = AG10EPreInit; 28598bb403aSmacallan pScrn->ScreenInit = AG10EScreenInit; 28698bb403aSmacallan pScrn->SwitchMode = AG10ESwitchMode; 28798bb403aSmacallan pScrn->AdjustFrame = AG10EAdjustFrame; 28898bb403aSmacallan pScrn->EnterVT = AG10EEnterVT; 28998bb403aSmacallan pScrn->LeaveVT = AG10ELeaveVT; 29098bb403aSmacallan pScrn->FreeScreen = AG10EFreeScreen; 29198bb403aSmacallan pScrn->ValidMode = AG10EValidMode; 29298bb403aSmacallan xf86AddEntityToScreen(pScrn, pEnt->index); 29398bb403aSmacallan foundScreen = TRUE; 29498bb403aSmacallan } 29598bb403aSmacallan xfree(pEnt); 29698bb403aSmacallan } 29798bb403aSmacallan xfree(usedChips); 29898bb403aSmacallan return foundScreen; 29998bb403aSmacallan} 30098bb403aSmacallan 30198bb403aSmacallan/* Mandatory */ 30298bb403aSmacallanstatic Bool 30398bb403aSmacallanAG10EPreInit(ScrnInfoPtr pScrn, int flags) 30498bb403aSmacallan{ 30598bb403aSmacallan AG10EPtr pAG10E; 30698bb403aSmacallan sbusDevicePtr psdp; 30798bb403aSmacallan rgb defaultWeight = {0, 0, 0}; 30898bb403aSmacallan MessageType from; 30998bb403aSmacallan int i; 31098bb403aSmacallan 31198bb403aSmacallan if (flags & PROBE_DETECT) return FALSE; 31298bb403aSmacallan 31398bb403aSmacallan /* 31498bb403aSmacallan * Note: This function is only called once at server startup, and 31598bb403aSmacallan * not at the start of each server generation. This means that 31698bb403aSmacallan * only things that are persistent across server generations can 31798bb403aSmacallan * be initialised here. xf86Screens[] is (pScrn is a pointer to one 31898bb403aSmacallan * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex() 31998bb403aSmacallan * are too, and should be used for data that must persist across 32098bb403aSmacallan * server generations. 32198bb403aSmacallan * 32298bb403aSmacallan * Per-generation data should be allocated with 32398bb403aSmacallan * AllocateScreenPrivateIndex() from the ScreenInit() function. 32498bb403aSmacallan */ 32598bb403aSmacallan 32698bb403aSmacallan /* Allocate the AG10ERec driverPrivate */ 32798bb403aSmacallan if (!AG10EGetRec(pScrn)) { 32898bb403aSmacallan return FALSE; 32998bb403aSmacallan } 33098bb403aSmacallan pAG10E = GET_AG10E_FROM_SCRN(pScrn); 33198bb403aSmacallan 33298bb403aSmacallan /* Set pScrn->monitor */ 33398bb403aSmacallan pScrn->monitor = pScrn->confScreen->monitor; 33498bb403aSmacallan 33598bb403aSmacallan /* This driver doesn't expect more than one entity per screen */ 33698bb403aSmacallan if (pScrn->numEntities > 1) 33798bb403aSmacallan return FALSE; 33898bb403aSmacallan /* This is the general case */ 33998bb403aSmacallan for (i = 0; i < pScrn->numEntities; i++) { 34098bb403aSmacallan EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[i]); 34198bb403aSmacallan 34298bb403aSmacallan /* AG10E is purely SBUS */ 34398bb403aSmacallan if (pEnt->location.type == BUS_SBUS) { 34498bb403aSmacallan psdp = xf86GetSbusInfoForEntity(pEnt->index); 34598bb403aSmacallan pAG10E->psdp = psdp; 34698bb403aSmacallan } else 34798bb403aSmacallan return FALSE; 34898bb403aSmacallan } 34998bb403aSmacallan 35098bb403aSmacallan /********************* 35198bb403aSmacallan deal with depth 35298bb403aSmacallan *********************/ 35398bb403aSmacallan 35498bb403aSmacallan if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) { 35598bb403aSmacallan return FALSE; 35698bb403aSmacallan } else { 35798bb403aSmacallan /* Check that the returned depth is one we support */ 35898bb403aSmacallan switch (pScrn->depth) { 35998bb403aSmacallan case 24: 36098bb403aSmacallan /* OK */ 36198bb403aSmacallan break; 36298bb403aSmacallan default: 36398bb403aSmacallan xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 36498bb403aSmacallan "Given depth (%d) is not supported by this driver\n", 36598bb403aSmacallan pScrn->depth); 36698bb403aSmacallan return FALSE; 36798bb403aSmacallan } 36898bb403aSmacallan } 36998bb403aSmacallan 37098bb403aSmacallan /* Collect all of the relevant option flags (fill in pScrn->options) */ 37198bb403aSmacallan xf86CollectOptions(pScrn, NULL); 37298bb403aSmacallan /* Process the options */ 37398bb403aSmacallan if (!(pAG10E->Options = xalloc(sizeof(AG10EOptions)))) 37498bb403aSmacallan return FALSE; 37598bb403aSmacallan memcpy(pAG10E->Options, AG10EOptions, sizeof(AG10EOptions)); 37698bb403aSmacallan xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pAG10E->Options); 37798bb403aSmacallan 37898bb403aSmacallan /* 37998bb403aSmacallan * The new cmap code requires this to be initialised. 38098bb403aSmacallan * this card supports HW gamma correction with 10 bit resolution - maybe 38198bb403aSmacallan * we should figure out how to use it 38298bb403aSmacallan */ 38398bb403aSmacallan 38498bb403aSmacallan { 38598bb403aSmacallan Gamma zeros = {0.0, 0.0, 0.0}; 38698bb403aSmacallan 38798bb403aSmacallan if (!xf86SetGamma(pScrn, zeros)) { 38898bb403aSmacallan return FALSE; 38998bb403aSmacallan } 39098bb403aSmacallan } 39198bb403aSmacallan 39298bb403aSmacallan from = X_DEFAULT; 39398bb403aSmacallan if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) 39498bb403aSmacallan return FALSE; 39598bb403aSmacallan 39698bb403aSmacallan if (!xf86SetDefaultVisual(pScrn, -1)) 39798bb403aSmacallan return FALSE; 39898bb403aSmacallan 39998bb403aSmacallan /* determine whether we use hardware or software cursor */ 40098bb403aSmacallan 40198bb403aSmacallan pAG10E->HWCursor = TRUE; 40298bb403aSmacallan if (xf86GetOptValBool(pAG10E->Options, OPTION_HW_CURSOR, &pAG10E->HWCursor)) 40398bb403aSmacallan from = X_CONFIG; 40498bb403aSmacallan if (xf86ReturnOptValBool(pAG10E->Options, OPTION_SW_CURSOR, FALSE)) { 40598bb403aSmacallan from = X_CONFIG; 40698bb403aSmacallan pAG10E->HWCursor = FALSE; 40798bb403aSmacallan } 40898bb403aSmacallan 40998bb403aSmacallan xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 41098bb403aSmacallan pAG10E->HWCursor ? "HW" : "SW"); 41198bb403aSmacallan 41298bb403aSmacallan if (xf86ReturnOptValBool(pAG10E->Options, OPTION_NOACCEL, FALSE)) { 41398bb403aSmacallan pAG10E->NoAccel = TRUE; 41498bb403aSmacallan xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); 41598bb403aSmacallan } 41698bb403aSmacallan 41798bb403aSmacallan if (xf86LoadSubModule(pScrn, "fb") == NULL) { 41898bb403aSmacallan AG10EFreeRec(pScrn); 41998bb403aSmacallan return FALSE; 42098bb403aSmacallan } 42198bb403aSmacallan 42298bb403aSmacallan if (pAG10E->HWCursor && xf86LoadSubModule(pScrn, "ramdac") == NULL) { 42398bb403aSmacallan AG10EFreeRec(pScrn); 42498bb403aSmacallan return FALSE; 42598bb403aSmacallan } 42698bb403aSmacallan 42798bb403aSmacallan if (pAG10E->HWCursor && xf86LoadSubModule(pScrn, "xaa") == NULL) { 42898bb403aSmacallan AG10EFreeRec(pScrn); 42998bb403aSmacallan return FALSE; 43098bb403aSmacallan } 43198bb403aSmacallan xf86LoaderReqSymLists(xaaSymbols, NULL); 43298bb403aSmacallan 43398bb403aSmacallan /********************* 43498bb403aSmacallan set up clock and mode stuff 43598bb403aSmacallan *********************/ 43698bb403aSmacallan 43798bb403aSmacallan pScrn->progClock = TRUE; 43898bb403aSmacallan 43998bb403aSmacallan if(pScrn->display->virtualX || pScrn->display->virtualY) { 44098bb403aSmacallan xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 44198bb403aSmacallan "AG10E does not support a virtual desktop\n"); 44298bb403aSmacallan pScrn->display->virtualX = 0; 44398bb403aSmacallan pScrn->display->virtualY = 0; 44498bb403aSmacallan } 44598bb403aSmacallan 44698bb403aSmacallan xf86SbusUseBuiltinMode(pScrn, pAG10E->psdp); 44798bb403aSmacallan pScrn->currentMode = pScrn->modes; 44898bb403aSmacallan pScrn->displayWidth = pScrn->virtualX; 44998bb403aSmacallan 45098bb403aSmacallan /* Set display resolution */ 45198bb403aSmacallan xf86SetDpi(pScrn, 0, 0); 45298bb403aSmacallan 45398bb403aSmacallan return TRUE; 45498bb403aSmacallan} 45598bb403aSmacallan 45698bb403aSmacallan/* Mandatory */ 45798bb403aSmacallan 45898bb403aSmacallan/* This gets called at the start of each server generation */ 45998bb403aSmacallan 46098bb403aSmacallanstatic Bool 46198bb403aSmacallanAG10EScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 46298bb403aSmacallan{ 46398bb403aSmacallan ScrnInfoPtr pScrn; 46498bb403aSmacallan AG10EPtr pAG10E; 46598bb403aSmacallan struct fbtype fb; 46698bb403aSmacallan sbusDevicePtr psdp; 46798bb403aSmacallan VisualPtr visual; 46898bb403aSmacallan int ret; 46998bb403aSmacallan 47098bb403aSmacallan pScrn = xf86Screens[pScreen->myNum]; 47198bb403aSmacallan pAG10E = GET_AG10E_FROM_SCRN(pScrn); 47298bb403aSmacallan psdp = pAG10E->psdp; 47398bb403aSmacallan 47498bb403aSmacallan /* 47598bb403aSmacallan * for some idiotic reason we need to check if the file descriptor is 47698bb403aSmacallan * really open here 47798bb403aSmacallan */ 47898bb403aSmacallan if (psdp->fd == -1) { 47998bb403aSmacallan psdp->fd = open(psdp->device, O_RDWR); 48098bb403aSmacallan if (psdp->fd == -1) 48198bb403aSmacallan return FALSE; 48298bb403aSmacallan } 48398bb403aSmacallan 48498bb403aSmacallan /* figure out how much VRAM we can map */ 48598bb403aSmacallan if ((ret = ioctl(pAG10E->psdp->fd, FBIOGTYPE, &fb)) != 0) { 48698bb403aSmacallan xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 48798bb403aSmacallan "ioctl(FBIOGTYPE) failed with %d\n", ret); 48898bb403aSmacallan return FALSE; 48998bb403aSmacallan } 49098bb403aSmacallan pAG10E->vidmem = fb.fb_size; 49198bb403aSmacallan 49298bb403aSmacallan /* Map AG10E memory areas */ 49398bb403aSmacallan 49498bb403aSmacallan pAG10E->regs = xf86MapSbusMem(psdp, pAG10E->vidmem, 0x10000); 49598bb403aSmacallan pAG10E->fb = xf86MapSbusMem(psdp, 0, pAG10E->vidmem); 49698bb403aSmacallan 49798bb403aSmacallan if (pAG10E->fb != NULL) { 49898bb403aSmacallan xf86DrvMsg(pScrn->scrnIndex, X_INFO, "mapped %d KB video RAM\n", 49998bb403aSmacallan pAG10E->vidmem >> 10); 50098bb403aSmacallan } 50198bb403aSmacallan 50298bb403aSmacallan if (!pAG10E->regs || !pAG10E->fb) { 50398bb403aSmacallan xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 50498bb403aSmacallan "xf86MapSbusMem failed regs:%" PRIxPTR " fb:%" PRIxPTR "\n", 50598bb403aSmacallan pAG10E->regs, pAG10E->fb); 50698bb403aSmacallan 50798bb403aSmacallan if (pAG10E->fb) { 50898bb403aSmacallan xf86UnmapSbusMem(psdp, pAG10E->fb, sizeof(*pAG10E->fb)); 50998bb403aSmacallan pAG10E->fb = NULL; 51098bb403aSmacallan } 51198bb403aSmacallan 51298bb403aSmacallan if (pAG10E->regs) { 51398bb403aSmacallan xf86UnmapSbusMem(psdp, pAG10E->regs, sizeof(*pAG10E->regs)); 51498bb403aSmacallan pAG10E->regs = NULL; 51598bb403aSmacallan } 51698bb403aSmacallan 51798bb403aSmacallan return FALSE; 51898bb403aSmacallan } 51998bb403aSmacallan pAG10E->IOOffset = 0; 52098bb403aSmacallan xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "vram: %d\n", 52198bb403aSmacallan (1 << ((GLINT_READ_REG(FBMemoryCtl) & 0xE0000000)>>29)) * 1024); 52298bb403aSmacallan 52398bb403aSmacallan /* 52498bb403aSmacallan * The next step is to setup the screen's visuals, and initialise the 52598bb403aSmacallan * framebuffer code. In cases where the framebuffer's default 52698bb403aSmacallan * choices for things like visual layouts and bits per RGB are OK, 52798bb403aSmacallan * this may be as simple as calling the framebuffer's ScreenInit() 52898bb403aSmacallan * function. If not, the visuals will need to be setup before calling 52998bb403aSmacallan * a fb ScreenInit() function and fixed up after. 53098bb403aSmacallan */ 53198bb403aSmacallan 53298bb403aSmacallan /* 53398bb403aSmacallan * Reset visual list. 53498bb403aSmacallan */ 53598bb403aSmacallan miClearVisualTypes(); 53698bb403aSmacallan 53798bb403aSmacallan /* Setup the visuals we support. */ 53898bb403aSmacallan if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), 53998bb403aSmacallan pScrn->rgbBits, pScrn->defaultVisual)) 54098bb403aSmacallan return FALSE; 54198bb403aSmacallan 54298bb403aSmacallan miSetPixmapDepths(); 54398bb403aSmacallan 54498bb403aSmacallan /* 54598bb403aSmacallan * Call the framebuffer layer's ScreenInit function, and fill in other 54698bb403aSmacallan * pScreen fields. 54798bb403aSmacallan */ 54898bb403aSmacallan 54998bb403aSmacallan ret = fbScreenInit(pScreen, pAG10E->fb, pScrn->virtualX, 55098bb403aSmacallan pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, 55198bb403aSmacallan pScrn->virtualX, pScrn->bitsPerPixel); 55298bb403aSmacallan /*if (!ret) 55398bb403aSmacallan return FALSE;*/ 55498bb403aSmacallan 55598bb403aSmacallan pAG10E->width=pScrn->virtualX; 55698bb403aSmacallan pAG10E->height=pScrn->virtualY; 55798bb403aSmacallan pAG10E->maxheight=(pAG10E->vidmem / (pAG10E->width << 2)) & 0xffff; 55898bb403aSmacallan 55998bb403aSmacallan fbPictureInit(pScreen, 0, 0); 56098bb403aSmacallan 56198bb403aSmacallan visual = pScreen->visuals + pScreen->numVisuals; 56298bb403aSmacallan while (--visual >= pScreen->visuals) { 56398bb403aSmacallan if ((visual->class | DynamicClass) == DirectColor) { 56498bb403aSmacallan visual->offsetRed = pScrn->offset.red; 56598bb403aSmacallan visual->offsetGreen = pScrn->offset.green; 56698bb403aSmacallan visual->offsetBlue = pScrn->offset.blue; 56798bb403aSmacallan visual->redMask = pScrn->mask.red; 56898bb403aSmacallan visual->greenMask = pScrn->mask.green; 56998bb403aSmacallan visual->blueMask = pScrn->mask.blue; 57098bb403aSmacallan } 57198bb403aSmacallan } 57298bb403aSmacallan 57398bb403aSmacallan miInitializeBackingStore(pScreen); 57498bb403aSmacallan xf86SetBackingStore(pScreen); 57598bb403aSmacallan xf86SetSilkenMouse(pScreen); 57698bb403aSmacallan 57798bb403aSmacallan xf86SetBlackWhitePixels(pScreen); 57898bb403aSmacallan 57998bb403aSmacallan if (!pAG10E->NoAccel) { 58098bb403aSmacallan if (!AG10EAccelInit(pScreen)) 58198bb403aSmacallan return FALSE; 58298bb403aSmacallan xf86Msg(X_INFO, "%s: Using acceleration\n", pAG10E->psdp->device); 58398bb403aSmacallan } 58498bb403aSmacallan /* setup DGA */ 58598bb403aSmacallan AG10EDGAInit(pScreen); 58698bb403aSmacallan 58798bb403aSmacallan /* Initialise cursor functions */ 58898bb403aSmacallan miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 58998bb403aSmacallan 59098bb403aSmacallan /* Initialize HW cursor layer. 59198bb403aSmacallan Must follow software cursor initialization*/ 59298bb403aSmacallan if (pAG10E->HWCursor) { 59398bb403aSmacallan if(!AG10EHWCursorInit(pScreen)) { 59498bb403aSmacallan xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 59598bb403aSmacallan "Hardware cursor initialization failed\n"); 59698bb403aSmacallan return(FALSE); 59798bb403aSmacallan } 59898bb403aSmacallan xf86SbusHideOsHwCursor(psdp); 59998bb403aSmacallan } 60098bb403aSmacallan 60198bb403aSmacallan /* Initialise default colourmap */ 60298bb403aSmacallan if (!miCreateDefColormap(pScreen)) 60398bb403aSmacallan return FALSE; 60498bb403aSmacallan 60598bb403aSmacallan if(!xf86SbusHandleColormaps(pScreen, psdp)) 60698bb403aSmacallan return FALSE; 60798bb403aSmacallan 60898bb403aSmacallan pAG10E->CloseScreen = pScreen->CloseScreen; 60998bb403aSmacallan pScreen->CloseScreen = AG10ECloseScreen; 61098bb403aSmacallan pScreen->SaveScreen = AG10ESaveScreen; 61198bb403aSmacallan 61298bb403aSmacallan /* Report any unused options (only for the first generation) */ 61398bb403aSmacallan if (serverGeneration == 1) { 61498bb403aSmacallan xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 61598bb403aSmacallan } 61698bb403aSmacallan 61798bb403aSmacallan /* unblank the screen */ 61898bb403aSmacallan AG10ESaveScreen(pScreen, SCREEN_SAVER_OFF); 61998bb403aSmacallan 62098bb403aSmacallan /* Done */ 62198bb403aSmacallan return TRUE; 62298bb403aSmacallan} 62398bb403aSmacallan 62498bb403aSmacallan 62598bb403aSmacallan/* Usually mandatory */ 62698bb403aSmacallanstatic Bool 62798bb403aSmacallanAG10ESwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 62898bb403aSmacallan{ 62998bb403aSmacallan return TRUE; 63098bb403aSmacallan} 63198bb403aSmacallan 63298bb403aSmacallan 63398bb403aSmacallan/* 63498bb403aSmacallan * This function is used to initialize the Start Address - the first 63598bb403aSmacallan * displayed location in the video memory. 63698bb403aSmacallan */ 63798bb403aSmacallan/* Usually mandatory */ 63898bb403aSmacallanstatic void 63998bb403aSmacallanAG10EAdjustFrame(int scrnIndex, int x, int y, int flags) 64098bb403aSmacallan{ 64198bb403aSmacallan /* we don't support virtual desktops */ 64298bb403aSmacallan return; 64398bb403aSmacallan} 64498bb403aSmacallan 64598bb403aSmacallan/* 64698bb403aSmacallan * This is called when VT switching back to the X server. Its job is 64798bb403aSmacallan * to reinitialise the video mode. 64898bb403aSmacallan */ 64998bb403aSmacallan 65098bb403aSmacallan/* Mandatory */ 65198bb403aSmacallanstatic Bool 65298bb403aSmacallanAG10EEnterVT(int scrnIndex, int flags) 65398bb403aSmacallan{ 65498bb403aSmacallan ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 65598bb403aSmacallan AG10EPtr pAG10E = GET_AG10E_FROM_SCRN(pScrn); 65698bb403aSmacallan 65798bb403aSmacallan if (pAG10E->HWCursor) { 65898bb403aSmacallan xf86SbusHideOsHwCursor(pAG10E->psdp); 65998bb403aSmacallan } 66098bb403aSmacallan return TRUE; 66198bb403aSmacallan} 66298bb403aSmacallan 66398bb403aSmacallan 66498bb403aSmacallan/* 66598bb403aSmacallan * This is called when VT switching away from the X server. 66698bb403aSmacallan */ 66798bb403aSmacallan 66898bb403aSmacallan/* Mandatory */ 66998bb403aSmacallanstatic void 67098bb403aSmacallanAG10ELeaveVT(int scrnIndex, int flags) 67198bb403aSmacallan{ 67298bb403aSmacallan return; 67398bb403aSmacallan} 67498bb403aSmacallan 67598bb403aSmacallan 67698bb403aSmacallan/* 67798bb403aSmacallan * This is called at the end of each server generation. It restores the 67898bb403aSmacallan * original (text) mode. It should really also unmap the video memory too. 67998bb403aSmacallan */ 68098bb403aSmacallan 68198bb403aSmacallan/* Mandatory */ 68298bb403aSmacallanstatic Bool 68398bb403aSmacallanAG10ECloseScreen(int scrnIndex, ScreenPtr pScreen) 68498bb403aSmacallan{ 68598bb403aSmacallan ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 68698bb403aSmacallan AG10EPtr pAG10E = GET_AG10E_FROM_SCRN(pScrn); 68798bb403aSmacallan sbusDevicePtr psdp = pAG10E->psdp; 68898bb403aSmacallan 68998bb403aSmacallan pScrn->vtSema = FALSE; 69098bb403aSmacallan 69198bb403aSmacallan xf86UnmapSbusMem(psdp, pAG10E->regs, 0x10000); 69298bb403aSmacallan xf86UnmapSbusMem(psdp, pAG10E->fb, pAG10E->vidmem); 69398bb403aSmacallan 69498bb403aSmacallan if (pAG10E->HWCursor) 69598bb403aSmacallan xf86SbusHideOsHwCursor(psdp); 69698bb403aSmacallan 69798bb403aSmacallan pScreen->CloseScreen = pAG10E->CloseScreen; 69898bb403aSmacallan return (*pScreen->CloseScreen)(scrnIndex, pScreen); 69998bb403aSmacallan return FALSE; 70098bb403aSmacallan} 70198bb403aSmacallan 70298bb403aSmacallan 70398bb403aSmacallan/* Free up any per-generation data structures */ 70498bb403aSmacallan 70598bb403aSmacallan/* Optional */ 70698bb403aSmacallanstatic void 70798bb403aSmacallanAG10EFreeScreen(int scrnIndex, int flags) 70898bb403aSmacallan{ 70998bb403aSmacallan AG10EFreeRec(xf86Screens[scrnIndex]); 71098bb403aSmacallan} 71198bb403aSmacallan 71298bb403aSmacallan 71398bb403aSmacallan/* Checks if a mode is suitable for the selected chipset. */ 71498bb403aSmacallan 71598bb403aSmacallan/* Optional */ 71698bb403aSmacallanstatic ModeStatus 71798bb403aSmacallanAG10EValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) 71898bb403aSmacallan{ 71998bb403aSmacallan if (mode->Flags & V_INTERLACE) 72098bb403aSmacallan return(MODE_NO_INTERLACE); 72198bb403aSmacallan 72298bb403aSmacallan return(MODE_OK); 72398bb403aSmacallan} 72498bb403aSmacallan 72598bb403aSmacallan/* Do screen blanking */ 72698bb403aSmacallan 72798bb403aSmacallan/* Mandatory */ 72898bb403aSmacallanstatic Bool 72998bb403aSmacallanAG10ESaveScreen(ScreenPtr pScreen, int mode) 73098bb403aSmacallan{ 73198bb403aSmacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 73298bb403aSmacallan AG10EPtr pAG10E = GET_AG10E_FROM_SCRN(pScrn); 73398bb403aSmacallan int flag; 73498bb403aSmacallan 73598bb403aSmacallan switch (mode) 73698bb403aSmacallan { 73798bb403aSmacallan case SCREEN_SAVER_ON: 73898bb403aSmacallan case SCREEN_SAVER_CYCLE: 73998bb403aSmacallan flag = 0; 74098bb403aSmacallan ioctl(pAG10E->psdp->fd, FBIOSVIDEO, &flag); 74198bb403aSmacallan break; 74298bb403aSmacallan case SCREEN_SAVER_OFF: 74398bb403aSmacallan case SCREEN_SAVER_FORCER: 74498bb403aSmacallan flag = 1; 74598bb403aSmacallan ioctl(pAG10E->psdp->fd, FBIOSVIDEO, &flag); 74698bb403aSmacallan break; 74798bb403aSmacallan default: 74898bb403aSmacallan return FALSE; 74998bb403aSmacallan } 75098bb403aSmacallan 75198bb403aSmacallan return TRUE; 75298bb403aSmacallan} 753