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