cg6_driver.c revision 4d26f1c6
15eefee25Smacallan/* 25eefee25Smacallan * GX and Turbo GX framebuffer driver. 35eefee25Smacallan * 45eefee25Smacallan * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com) 55eefee25Smacallan * 65eefee25Smacallan * Permission is hereby granted, free of charge, to any person obtaining a copy 75eefee25Smacallan * of this software and associated documentation files (the "Software"), to deal 85eefee25Smacallan * in the Software without restriction, including without limitation the rights 95eefee25Smacallan * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 105eefee25Smacallan * copies of the Software, and to permit persons to whom the Software is 115eefee25Smacallan * furnished to do so, subject to the following conditions: 125eefee25Smacallan * 135eefee25Smacallan * The above copyright notice and this permission notice shall be included in 145eefee25Smacallan * all copies or substantial portions of the Software. 155eefee25Smacallan * 165eefee25Smacallan * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 175eefee25Smacallan * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 185eefee25Smacallan * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 195eefee25Smacallan * JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 205eefee25Smacallan * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 215eefee25Smacallan * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 225eefee25Smacallan */ 235eefee25Smacallan/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/suncg6/cg6_driver.c,v 1.7 2002/12/06 16:44:38 tsi Exp $ */ 245eefee25Smacallan 255eefee25Smacallan#ifdef HAVE_CONFIG_H 265eefee25Smacallan#include "config.h" 275eefee25Smacallan#endif 285eefee25Smacallan 294d26f1c6Smacallan/* need this for PRIxPTR macro */ 304d26f1c6Smacallan#include <machine/int_fmtio.h> 314d26f1c6Smacallan 325eefee25Smacallan#include <string.h> 335eefee25Smacallan 345eefee25Smacallan#include "xf86.h" 355eefee25Smacallan#include "xf86_OSproc.h" 365eefee25Smacallan#include "xf86Version.h" 375eefee25Smacallan#include "mipointer.h" 385eefee25Smacallan#include "mibstore.h" 395eefee25Smacallan#include "micmap.h" 405eefee25Smacallan 415eefee25Smacallan#include "fb.h" 425eefee25Smacallan#include "xf86cmap.h" 435eefee25Smacallan#include "cg6.h" 445eefee25Smacallan 455eefee25Smacallanstatic const OptionInfoRec * CG6AvailableOptions(int chipid, int busid); 465eefee25Smacallanstatic void CG6Identify(int flags); 475eefee25Smacallanstatic Bool CG6Probe(DriverPtr drv, int flags); 485eefee25Smacallanstatic Bool CG6PreInit(ScrnInfoPtr pScrn, int flags); 495eefee25Smacallanstatic Bool CG6ScreenInit(int Index, ScreenPtr pScreen, int argc, 505eefee25Smacallan char **argv); 515eefee25Smacallanstatic Bool CG6EnterVT(int scrnIndex, int flags); 525eefee25Smacallanstatic void CG6LeaveVT(int scrnIndex, int flags); 535eefee25Smacallanstatic Bool CG6CloseScreen(int scrnIndex, ScreenPtr pScreen); 545eefee25Smacallanstatic Bool CG6SaveScreen(ScreenPtr pScreen, int mode); 555eefee25Smacallan 565eefee25Smacallan/* Required if the driver supports mode switching */ 575eefee25Smacallanstatic Bool CG6SwitchMode(int scrnIndex, DisplayModePtr mode, int flags); 585eefee25Smacallan/* Required if the driver supports moving the viewport */ 595eefee25Smacallanstatic void CG6AdjustFrame(int scrnIndex, int x, int y, int flags); 605eefee25Smacallan 615eefee25Smacallan/* Optional functions */ 625eefee25Smacallanstatic void CG6FreeScreen(int scrnIndex, int flags); 635eefee25Smacallanstatic ModeStatus CG6ValidMode(int scrnIndex, DisplayModePtr mode, 645eefee25Smacallan Bool verbose, int flags); 655eefee25Smacallan 665eefee25Smacallanvoid CG6Sync(ScrnInfoPtr pScrn); 675eefee25Smacallan 685eefee25Smacallan#define CG6_VERSION 4000 695eefee25Smacallan#define CG6_NAME "SUNCG6" 705eefee25Smacallan#define CG6_DRIVER_NAME "suncg6" 715eefee25Smacallan#define CG6_MAJOR_VERSION 1 725eefee25Smacallan#define CG6_MINOR_VERSION 1 735eefee25Smacallan#define CG6_PATCHLEVEL 0 745eefee25Smacallan 755eefee25Smacallan/* 765eefee25Smacallan * This contains the functions needed by the server after loading the driver 775eefee25Smacallan * module. It must be supplied, and gets passed back by the SetupProc 785eefee25Smacallan * function in the dynamic case. In the static case, a reference to this 795eefee25Smacallan * is compiled in, and this requires that the name of this DriverRec be 805eefee25Smacallan * an upper-case version of the driver name. 815eefee25Smacallan */ 825eefee25Smacallan 835eefee25Smacallan_X_EXPORT DriverRec SUNCG6 = { 845eefee25Smacallan CG6_VERSION, 855eefee25Smacallan CG6_DRIVER_NAME, 865eefee25Smacallan CG6Identify, 875eefee25Smacallan CG6Probe, 885eefee25Smacallan CG6AvailableOptions, 895eefee25Smacallan NULL, 905eefee25Smacallan 0 915eefee25Smacallan}; 925eefee25Smacallan 935eefee25Smacallantypedef enum { 945eefee25Smacallan OPTION_SW_CURSOR, 955eefee25Smacallan OPTION_HW_CURSOR, 965eefee25Smacallan OPTION_NOACCEL 975eefee25Smacallan} CG6Opts; 985eefee25Smacallan 995eefee25Smacallanstatic const OptionInfoRec CG6Options[] = { 1005eefee25Smacallan { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, 1015eefee25Smacallan { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, 1025eefee25Smacallan { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 1035eefee25Smacallan { -1, NULL, OPTV_NONE, {0}, FALSE } 1045eefee25Smacallan}; 1055eefee25Smacallan 1064d26f1c6Smacallanstatic const char *xaaSymbols[] = 1074d26f1c6Smacallan{ 1084d26f1c6Smacallan "XAACreateInfoRec", 1094d26f1c6Smacallan "XAADestroyInfoRec", 1104d26f1c6Smacallan "XAAInit", 1114d26f1c6Smacallan NULL 1124d26f1c6Smacallan}; 1134d26f1c6Smacallan 1145eefee25Smacallan#ifdef XFree86LOADER 1155eefee25Smacallan 1165eefee25Smacallanstatic MODULESETUPPROTO(cg6Setup); 1175eefee25Smacallan 1185eefee25Smacallanstatic XF86ModuleVersionInfo suncg6VersRec = 1195eefee25Smacallan{ 1205eefee25Smacallan "suncg6", 1215eefee25Smacallan MODULEVENDORSTRING, 1225eefee25Smacallan MODINFOSTRING1, 1235eefee25Smacallan MODINFOSTRING2, 1245eefee25Smacallan XORG_VERSION_CURRENT, 1255eefee25Smacallan CG6_MAJOR_VERSION, CG6_MINOR_VERSION, CG6_PATCHLEVEL, 1265eefee25Smacallan ABI_CLASS_VIDEODRV, 1275eefee25Smacallan ABI_VIDEODRV_VERSION, 1285eefee25Smacallan MOD_CLASS_VIDEODRV, 1295eefee25Smacallan {0,0,0,0} 1305eefee25Smacallan}; 1315eefee25Smacallan 1325eefee25Smacallan_X_EXPORT XF86ModuleData suncg6ModuleData = { &suncg6VersRec, cg6Setup, NULL }; 1335eefee25Smacallan 1345eefee25Smacallanpointer 1355eefee25Smacallancg6Setup(pointer module, pointer opts, int *errmaj, int *errmin) 1365eefee25Smacallan{ 1375eefee25Smacallan static Bool setupDone = FALSE; 1385eefee25Smacallan 1395eefee25Smacallan if (!setupDone) { 1405eefee25Smacallan setupDone = TRUE; 1415eefee25Smacallan xf86AddDriver(&SUNCG6, module, 0); 1425eefee25Smacallan 1435eefee25Smacallan /* 1445eefee25Smacallan * Modules that this driver always requires can be loaded here 1455eefee25Smacallan * by calling LoadSubModule(). 1465eefee25Smacallan */ 1475eefee25Smacallan 1485eefee25Smacallan /* 1495eefee25Smacallan * The return value must be non-NULL on success even though there 1505eefee25Smacallan * is no TearDownProc. 1515eefee25Smacallan */ 1525eefee25Smacallan return (pointer)TRUE; 1535eefee25Smacallan } else { 1545eefee25Smacallan if (errmaj) *errmaj = LDR_ONCEONLY; 1555eefee25Smacallan return NULL; 1565eefee25Smacallan } 1575eefee25Smacallan} 1585eefee25Smacallan 1595eefee25Smacallan#endif /* XFree86LOADER */ 1605eefee25Smacallan 1615eefee25Smacallanstatic Bool 1625eefee25SmacallanCG6GetRec(ScrnInfoPtr pScrn) 1635eefee25Smacallan{ 1645eefee25Smacallan /* 1655eefee25Smacallan * Allocate an Cg6Rec, and hook it into pScrn->driverPrivate. 1665eefee25Smacallan * pScrn->driverPrivate is initialised to NULL, so we can check if 1675eefee25Smacallan * the allocation has already been done. 1685eefee25Smacallan */ 1695eefee25Smacallan if (pScrn->driverPrivate != NULL) 1705eefee25Smacallan return TRUE; 1715eefee25Smacallan 1725eefee25Smacallan pScrn->driverPrivate = xnfcalloc(sizeof(Cg6Rec), 1); 1735eefee25Smacallan return TRUE; 1745eefee25Smacallan} 1755eefee25Smacallan 1765eefee25Smacallanstatic void 1775eefee25SmacallanCG6FreeRec(ScrnInfoPtr pScrn) 1785eefee25Smacallan{ 1795eefee25Smacallan Cg6Ptr pCg6; 1805eefee25Smacallan 1815eefee25Smacallan if (pScrn->driverPrivate == NULL) 1825eefee25Smacallan return; 1835eefee25Smacallan 1845eefee25Smacallan pCg6 = GET_CG6_FROM_SCRN(pScrn); 1855eefee25Smacallan 1865eefee25Smacallan xfree(pScrn->driverPrivate); 1875eefee25Smacallan pScrn->driverPrivate = NULL; 1885eefee25Smacallan 1895eefee25Smacallan return; 1905eefee25Smacallan} 1915eefee25Smacallan 1925eefee25Smacallanstatic const OptionInfoRec * 1935eefee25SmacallanCG6AvailableOptions(int chipid, int busid) 1945eefee25Smacallan{ 1955eefee25Smacallan return CG6Options; 1965eefee25Smacallan} 1975eefee25Smacallan 1985eefee25Smacallan/* Mandatory */ 1995eefee25Smacallanstatic void 2005eefee25SmacallanCG6Identify(int flags) 2015eefee25Smacallan{ 2025eefee25Smacallan xf86Msg(X_INFO, "%s: driver for CGsix (GX and Turbo GX)\n", CG6_NAME); 2035eefee25Smacallan} 2045eefee25Smacallan 2055eefee25Smacallan 2065eefee25Smacallan/* Mandatory */ 2075eefee25Smacallanstatic Bool 2085eefee25SmacallanCG6Probe(DriverPtr drv, int flags) 2095eefee25Smacallan{ 2105eefee25Smacallan int i; 2115eefee25Smacallan GDevPtr *devSections; 2125eefee25Smacallan int *usedChips; 2135eefee25Smacallan int numDevSections; 2145eefee25Smacallan int numUsed; 2155eefee25Smacallan Bool foundScreen = FALSE; 2165eefee25Smacallan EntityInfoPtr pEnt; 2175eefee25Smacallan 2185eefee25Smacallan /* 2195eefee25Smacallan * The aim here is to find all cards that this driver can handle, 2205eefee25Smacallan * and for the ones not already claimed by another driver, claim the 2215eefee25Smacallan * slot, and allocate a ScrnInfoRec. 2225eefee25Smacallan * 2235eefee25Smacallan * This should be a minimal probe, and it should under no circumstances 2245eefee25Smacallan * change the state of the hardware. Because a device is found, don't 2255eefee25Smacallan * assume that it will be used. Don't do any initialisations other than 2265eefee25Smacallan * the required ScrnInfoRec initialisations. Don't allocate any new 2275eefee25Smacallan * data structures. 2285eefee25Smacallan */ 2295eefee25Smacallan 2305eefee25Smacallan /* 2315eefee25Smacallan * Next we check, if there has been a chipset override in the config file. 2325eefee25Smacallan * For this we must find out if there is an active device section which 2335eefee25Smacallan * is relevant, i.e., which has no driver specified or has THIS driver 2345eefee25Smacallan * specified. 2355eefee25Smacallan */ 2365eefee25Smacallan 2375eefee25Smacallan if ((numDevSections = xf86MatchDevice(CG6_DRIVER_NAME, 2385eefee25Smacallan &devSections)) <= 0) { 2395eefee25Smacallan /* 2405eefee25Smacallan * There's no matching device section in the config file, so quit 2415eefee25Smacallan * now. 2425eefee25Smacallan */ 2435eefee25Smacallan return FALSE; 2445eefee25Smacallan } 2455eefee25Smacallan 2465eefee25Smacallan /* 2475eefee25Smacallan * We need to probe the hardware first. We then need to see how this 2485eefee25Smacallan * fits in with what is given in the config file, and allow the config 2495eefee25Smacallan * file info to override any contradictions. 2505eefee25Smacallan */ 2515eefee25Smacallan 2525eefee25Smacallan numUsed = xf86MatchSbusInstances(CG6_NAME, SBUS_DEVICE_CG6, 2535eefee25Smacallan devSections, numDevSections, 2545eefee25Smacallan drv, &usedChips); 2555eefee25Smacallan 2565eefee25Smacallan xfree(devSections); 2575eefee25Smacallan if (numUsed <= 0) 2585eefee25Smacallan return FALSE; 2595eefee25Smacallan 2605eefee25Smacallan if (flags & PROBE_DETECT) 2615eefee25Smacallan foundScreen = TRUE; 2625eefee25Smacallan else for (i = 0; i < numUsed; i++) { 2635eefee25Smacallan pEnt = xf86GetEntityInfo(usedChips[i]); 2645eefee25Smacallan 2655eefee25Smacallan /* 2665eefee25Smacallan * Check that nothing else has claimed the slots. 2675eefee25Smacallan */ 2685eefee25Smacallan if(pEnt->active) { 2695eefee25Smacallan ScrnInfoPtr pScrn; 2705eefee25Smacallan 2715eefee25Smacallan /* Allocate a ScrnInfoRec and claim the slot */ 2725eefee25Smacallan pScrn = xf86AllocateScreen(drv, 0); 2735eefee25Smacallan 2745eefee25Smacallan /* Fill in what we can of the ScrnInfoRec */ 2755eefee25Smacallan pScrn->driverVersion = CG6_VERSION; 2765eefee25Smacallan pScrn->driverName = CG6_DRIVER_NAME; 2775eefee25Smacallan pScrn->name = CG6_NAME; 2785eefee25Smacallan pScrn->Probe = CG6Probe; 2795eefee25Smacallan pScrn->PreInit = CG6PreInit; 2805eefee25Smacallan pScrn->ScreenInit = CG6ScreenInit; 2815eefee25Smacallan pScrn->SwitchMode = CG6SwitchMode; 2825eefee25Smacallan pScrn->AdjustFrame = CG6AdjustFrame; 2835eefee25Smacallan pScrn->EnterVT = CG6EnterVT; 2845eefee25Smacallan pScrn->LeaveVT = CG6LeaveVT; 2855eefee25Smacallan pScrn->FreeScreen = CG6FreeScreen; 2865eefee25Smacallan pScrn->ValidMode = CG6ValidMode; 2875eefee25Smacallan xf86AddEntityToScreen(pScrn, pEnt->index); 2885eefee25Smacallan foundScreen = TRUE; 2895eefee25Smacallan } 2905eefee25Smacallan xfree(pEnt); 2915eefee25Smacallan } 2925eefee25Smacallan xfree(usedChips); 2935eefee25Smacallan return foundScreen; 2945eefee25Smacallan} 2955eefee25Smacallan 2965eefee25Smacallan/* Mandatory */ 2975eefee25Smacallanstatic Bool 2985eefee25SmacallanCG6PreInit(ScrnInfoPtr pScrn, int flags) 2995eefee25Smacallan{ 3005eefee25Smacallan Cg6Ptr pCg6; 3015eefee25Smacallan sbusDevicePtr psdp; 3025eefee25Smacallan MessageType from; 3035eefee25Smacallan int i; 3045eefee25Smacallan 3055eefee25Smacallan if (flags & PROBE_DETECT) return FALSE; 3065eefee25Smacallan 3075eefee25Smacallan /* 3085eefee25Smacallan * Note: This function is only called once at server startup, and 3095eefee25Smacallan * not at the start of each server generation. This means that 3105eefee25Smacallan * only things that are persistent across server generations can 3115eefee25Smacallan * be initialised here. xf86Screens[] is (pScrn is a pointer to one 3125eefee25Smacallan * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex() 3135eefee25Smacallan * are too, and should be used for data that must persist across 3145eefee25Smacallan * server generations. 3155eefee25Smacallan * 3165eefee25Smacallan * Per-generation data should be allocated with 3175eefee25Smacallan * AllocateScreenPrivateIndex() from the ScreenInit() function. 3185eefee25Smacallan */ 3195eefee25Smacallan 3205eefee25Smacallan /* Allocate the Cg6Rec driverPrivate */ 3215eefee25Smacallan if (!CG6GetRec(pScrn)) { 3225eefee25Smacallan return FALSE; 3235eefee25Smacallan } 3245eefee25Smacallan pCg6 = GET_CG6_FROM_SCRN(pScrn); 3255eefee25Smacallan 3265eefee25Smacallan /* Set pScrn->monitor */ 3275eefee25Smacallan pScrn->monitor = pScrn->confScreen->monitor; 3285eefee25Smacallan 3295eefee25Smacallan /* This driver doesn't expect more than one entity per screen */ 3305eefee25Smacallan if (pScrn->numEntities > 1) 3315eefee25Smacallan return FALSE; 3325eefee25Smacallan /* This is the general case */ 3335eefee25Smacallan for (i = 0; i < pScrn->numEntities; i++) { 3345eefee25Smacallan EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[i]); 3355eefee25Smacallan 3365eefee25Smacallan /* CG6 is purely SBUS */ 3375eefee25Smacallan if (pEnt->location.type == BUS_SBUS) { 3385eefee25Smacallan psdp = xf86GetSbusInfoForEntity(pEnt->index); 3395eefee25Smacallan pCg6->psdp = psdp; 3405eefee25Smacallan } else 3415eefee25Smacallan return FALSE; 3425eefee25Smacallan } 3435eefee25Smacallan 3445eefee25Smacallan /********************* 3455eefee25Smacallan deal with depth 3465eefee25Smacallan *********************/ 3475eefee25Smacallan 3485eefee25Smacallan if (!xf86SetDepthBpp(pScrn, 0, 0, 0, NoDepth24Support)) { 3495eefee25Smacallan return FALSE; 3505eefee25Smacallan } else { 3515eefee25Smacallan /* Check that the returned depth is one we support */ 3525eefee25Smacallan switch (pScrn->depth) { 3535eefee25Smacallan case 8: 3545eefee25Smacallan /* OK */ 3555eefee25Smacallan break; 3565eefee25Smacallan default: 3575eefee25Smacallan xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 3585eefee25Smacallan "Given depth (%d) is not supported by this driver\n", 3595eefee25Smacallan pScrn->depth); 3605eefee25Smacallan return FALSE; 3615eefee25Smacallan } 3625eefee25Smacallan } 3635eefee25Smacallan 3645eefee25Smacallan /* Collect all of the relevant option flags (fill in pScrn->options) */ 3655eefee25Smacallan xf86CollectOptions(pScrn, NULL); 3665eefee25Smacallan /* Process the options */ 3675eefee25Smacallan if (!(pCg6->Options = xalloc(sizeof(CG6Options)))) 3685eefee25Smacallan return FALSE; 3695eefee25Smacallan memcpy(pCg6->Options, CG6Options, sizeof(CG6Options)); 3705eefee25Smacallan xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pCg6->Options); 3715eefee25Smacallan 3725eefee25Smacallan if (!xf86SetDefaultVisual(pScrn, -1)) 3735eefee25Smacallan return FALSE; 3745eefee25Smacallan 3755eefee25Smacallan /* 3765eefee25Smacallan * The new cmap code requires this to be initialised. 3775eefee25Smacallan */ 3785eefee25Smacallan 3795eefee25Smacallan { 3805eefee25Smacallan Gamma zeros = {0.0, 0.0, 0.0}; 3815eefee25Smacallan 3825eefee25Smacallan if (!xf86SetGamma(pScrn, zeros)) { 3835eefee25Smacallan return FALSE; 3845eefee25Smacallan } 3855eefee25Smacallan } 3865eefee25Smacallan 3875eefee25Smacallan /* Set the bits per RGB for 8bpp mode */ 3885eefee25Smacallan from = X_DEFAULT; 3895eefee25Smacallan 3905eefee25Smacallan /* determine whether we use hardware or software cursor */ 3915eefee25Smacallan 3925eefee25Smacallan pCg6->HWCursor = TRUE; 3935eefee25Smacallan if (xf86GetOptValBool(pCg6->Options, OPTION_HW_CURSOR, &pCg6->HWCursor)) 3945eefee25Smacallan from = X_CONFIG; 3955eefee25Smacallan if (xf86ReturnOptValBool(pCg6->Options, OPTION_SW_CURSOR, FALSE)) { 3965eefee25Smacallan from = X_CONFIG; 3975eefee25Smacallan pCg6->HWCursor = FALSE; 3985eefee25Smacallan } 3995eefee25Smacallan 4005eefee25Smacallan xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 4015eefee25Smacallan pCg6->HWCursor ? "HW" : "SW"); 4025eefee25Smacallan 4035eefee25Smacallan if (xf86ReturnOptValBool(pCg6->Options, OPTION_NOACCEL, FALSE)) { 4045eefee25Smacallan pCg6->NoAccel = TRUE; 4055eefee25Smacallan xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); 4065eefee25Smacallan } 4075eefee25Smacallan 4085eefee25Smacallan if (xf86LoadSubModule(pScrn, "fb") == NULL) { 4095eefee25Smacallan CG6FreeRec(pScrn); 4105eefee25Smacallan return FALSE; 4115eefee25Smacallan } 4125eefee25Smacallan 4135eefee25Smacallan if (pCg6->HWCursor && xf86LoadSubModule(pScrn, "ramdac") == NULL) { 4145eefee25Smacallan CG6FreeRec(pScrn); 4155eefee25Smacallan return FALSE; 4165eefee25Smacallan } 4175eefee25Smacallan 4184d26f1c6Smacallan if (pCg6->HWCursor && xf86LoadSubModule(pScrn, "xaa") == NULL) { 4194d26f1c6Smacallan CG6FreeRec(pScrn); 4204d26f1c6Smacallan return FALSE; 4214d26f1c6Smacallan } 4224d26f1c6Smacallan xf86LoaderReqSymLists(xaaSymbols, NULL); 4234d26f1c6Smacallan 4245eefee25Smacallan /********************* 4255eefee25Smacallan set up clock and mode stuff 4265eefee25Smacallan *********************/ 4275eefee25Smacallan 4285eefee25Smacallan pScrn->progClock = TRUE; 4295eefee25Smacallan 4305eefee25Smacallan if(pScrn->display->virtualX || pScrn->display->virtualY) { 4315eefee25Smacallan xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 4325eefee25Smacallan "CG6 does not support a virtual desktop\n"); 4335eefee25Smacallan pScrn->display->virtualX = 0; 4345eefee25Smacallan pScrn->display->virtualY = 0; 4355eefee25Smacallan } 4365eefee25Smacallan 4375eefee25Smacallan xf86SbusUseBuiltinMode(pScrn, pCg6->psdp); 4385eefee25Smacallan pScrn->currentMode = pScrn->modes; 4395eefee25Smacallan pScrn->displayWidth = pScrn->virtualX; 4405eefee25Smacallan 4415eefee25Smacallan /* Set display resolution */ 4425eefee25Smacallan xf86SetDpi(pScrn, 0, 0); 4435eefee25Smacallan 4445eefee25Smacallan return TRUE; 4455eefee25Smacallan} 4465eefee25Smacallan 4475eefee25Smacallan/* Mandatory */ 4485eefee25Smacallan 4495eefee25Smacallan/* This gets called at the start of each server generation */ 4505eefee25Smacallan 4515eefee25Smacallanstatic Bool 4525eefee25SmacallanCG6ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 4535eefee25Smacallan{ 4545eefee25Smacallan ScrnInfoPtr pScrn; 4555eefee25Smacallan Cg6Ptr pCg6; 4564d26f1c6Smacallan sbusDevicePtr psdp; 4575eefee25Smacallan int ret; 4585eefee25Smacallan 4595eefee25Smacallan /* 4605eefee25Smacallan * First get the ScrnInfoRec 4615eefee25Smacallan */ 4625eefee25Smacallan pScrn = xf86Screens[pScreen->myNum]; 4635eefee25Smacallan pCg6 = GET_CG6_FROM_SCRN(pScrn); 4644d26f1c6Smacallan psdp = pCg6->psdp; 4655eefee25Smacallan 4665eefee25Smacallan /* Map the CG6 memory */ 4675eefee25Smacallan 4684d26f1c6Smacallan pCg6->fbc = xf86MapSbusMem(psdp, CG6_FBC_VOFF, sizeof(*pCg6->fbc)); 4694d26f1c6Smacallan pCg6->thc = xf86MapSbusMem(psdp, CG6_THC_VOFF, sizeof(*pCg6->thc)); 4705eefee25Smacallan 4714d26f1c6Smacallan /* 4724d26f1c6Smacallan * XXX need something better here - we rely on the OS to allow mmap()ing 4734d26f1c6Smacallan * usable VRAM ONLY. Works with NetBSD, may crash and burn on other OSes. 4744d26f1c6Smacallan */ 4754d26f1c6Smacallan pCg6->vidmem = 2 * 1024 * 1024; 4764d26f1c6Smacallan pCg6->fb = xf86MapSbusMem(psdp, CG6_RAM_VOFF, pCg6->vidmem); 4774d26f1c6Smacallan 4784d26f1c6Smacallan if (pCg6->fb == NULL) { 4794d26f1c6Smacallan /* mapping 2MB failed - try 1MB */ 4804d26f1c6Smacallan pCg6->vidmem = 1024 * 1024; 4814d26f1c6Smacallan pCg6->fb = xf86MapSbusMem(psdp, CG6_RAM_VOFF, pCg6->vidmem); 4824d26f1c6Smacallan } 4834d26f1c6Smacallan 4844d26f1c6Smacallan if (pCg6->fb == NULL) { 4854d26f1c6Smacallan /* we can't map all video RAM - fall back to width*height */ 4864d26f1c6Smacallan pCg6->vidmem = psdp->width * psdp->height; 4874d26f1c6Smacallan pCg6->fb = xf86MapSbusMem(psdp, CG6_RAM_VOFF, pCg6->vidmem); 4884d26f1c6Smacallan } 4894d26f1c6Smacallan 4904d26f1c6Smacallan if (pCg6->fb != NULL) { 4914d26f1c6Smacallan xf86DrvMsg(pScrn->scrnIndex, X_INFO, "mapped %d KB video RAM\n", 4924d26f1c6Smacallan pCg6->vidmem >> 10); 4934d26f1c6Smacallan } 4944d26f1c6Smacallan 4954d26f1c6Smacallan if (!pCg6->fbc || !pCg6->thc || !pCg6->fb) { 4964d26f1c6Smacallan xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 4974d26f1c6Smacallan "xf86MapSbusMem failed fbc:%" PRIxPTR " fb:%" PRIxPTR 4984d26f1c6Smacallan " thc:%" PRIxPTR "\n", 4994d26f1c6Smacallan pCg6->fbc, pCg6->fb, pCg6->thc ); 5004d26f1c6Smacallan 5014d26f1c6Smacallan if (pCg6->fbc) { 5024d26f1c6Smacallan xf86UnmapSbusMem(psdp, pCg6->fbc, sizeof(*pCg6->fbc)); 5034d26f1c6Smacallan pCg6->fbc = NULL; 5044d26f1c6Smacallan } 5054d26f1c6Smacallan 5064d26f1c6Smacallan if (pCg6->thc) { 5074d26f1c6Smacallan xf86UnmapSbusMem(psdp, pCg6->thc, sizeof(*pCg6->thc)); 5084d26f1c6Smacallan pCg6->thc = NULL; 5094d26f1c6Smacallan } 5104d26f1c6Smacallan 5114d26f1c6Smacallan if (pCg6->fb) { 5124d26f1c6Smacallan xf86UnmapSbusMem(psdp, pCg6->fb, pCg6->vidmem); 5134d26f1c6Smacallan pCg6->fb = NULL; 5144d26f1c6Smacallan } 5154d26f1c6Smacallan 5164d26f1c6Smacallan return FALSE; 5174d26f1c6Smacallan } 5185eefee25Smacallan 5195eefee25Smacallan /* Darken the screen for aesthetic reasons and set the viewport */ 5205eefee25Smacallan CG6SaveScreen(pScreen, SCREEN_SAVER_ON); 5215eefee25Smacallan 5225eefee25Smacallan /* 5235eefee25Smacallan * The next step is to setup the screen's visuals, and initialise the 5245eefee25Smacallan * framebuffer code. In cases where the framebuffer's default 5255eefee25Smacallan * choices for things like visual layouts and bits per RGB are OK, 5265eefee25Smacallan * this may be as simple as calling the framebuffer's ScreenInit() 5275eefee25Smacallan * function. If not, the visuals will need to be setup before calling 5285eefee25Smacallan * a fb ScreenInit() function and fixed up after. 5295eefee25Smacallan */ 5305eefee25Smacallan 5315eefee25Smacallan /* 5325eefee25Smacallan * Reset visual list. 5335eefee25Smacallan */ 5345eefee25Smacallan miClearVisualTypes(); 5355eefee25Smacallan 5365eefee25Smacallan /* Set the bits per RGB for 8bpp mode */ 5375eefee25Smacallan pScrn->rgbBits = 8; 5385eefee25Smacallan 5395eefee25Smacallan /* Setup the visuals we support. */ 5405eefee25Smacallan 5415eefee25Smacallan if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), 5425eefee25Smacallan pScrn->rgbBits, pScrn->defaultVisual)) 5435eefee25Smacallan return FALSE; 5445eefee25Smacallan 5455eefee25Smacallan miSetPixmapDepths (); 5465eefee25Smacallan 5475eefee25Smacallan /* 5485eefee25Smacallan * Call the framebuffer layer's ScreenInit function, and fill in other 5495eefee25Smacallan * pScreen fields. 5505eefee25Smacallan */ 5515eefee25Smacallan 5525eefee25Smacallan ret = fbScreenInit(pScreen, pCg6->fb, pScrn->virtualX, 5535eefee25Smacallan pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, 5545eefee25Smacallan pScrn->virtualX, 8); 5555eefee25Smacallan if (!ret) 5565eefee25Smacallan return FALSE; 5575eefee25Smacallan 5584d26f1c6Smacallan pCg6->width=pScrn->virtualX; 5594d26f1c6Smacallan pCg6->height=pScrn->virtualY; 5604d26f1c6Smacallan pCg6->maxheight=(pCg6->vidmem/pCg6->width)&0xffff; 5614d26f1c6Smacallan 5625eefee25Smacallan fbPictureInit (pScreen, 0, 0); 5635eefee25Smacallan 5645eefee25Smacallan miInitializeBackingStore(pScreen); 5655eefee25Smacallan xf86SetBackingStore(pScreen); 5665eefee25Smacallan xf86SetSilkenMouse(pScreen); 5675eefee25Smacallan 5685eefee25Smacallan xf86SetBlackWhitePixels(pScreen); 5695eefee25Smacallan 5705eefee25Smacallan if (!pCg6->NoAccel) { 5714d26f1c6Smacallan BoxRec bx; 5724d26f1c6Smacallan pCg6->pXAA=XAACreateInfoRec(); 5734d26f1c6Smacallan CG6AccelInit(pScrn); 5744d26f1c6Smacallan bx.x1=bx.y1=0; 5754d26f1c6Smacallan bx.x2=pCg6->width; 5764d26f1c6Smacallan bx.y2=pCg6->maxheight; 5774d26f1c6Smacallan xf86InitFBManager(pScreen,&bx); 5784d26f1c6Smacallan if(!XAAInit(pScreen, pCg6->pXAA)) 5794d26f1c6Smacallan return FALSE; 5804d26f1c6Smacallan 5814d26f1c6Smacallan xf86Msg(X_INFO, "%s: Using acceleration\n", pCg6->psdp->device); 5825eefee25Smacallan } 5834d26f1c6Smacallan 5844d26f1c6Smacallan /* setup DGA */ 5854d26f1c6Smacallan Cg6DGAInit(pScreen); 5864d26f1c6Smacallan 5875eefee25Smacallan 5885eefee25Smacallan /* Initialise cursor functions */ 5895eefee25Smacallan miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); 5905eefee25Smacallan 5915eefee25Smacallan /* Initialize HW cursor layer. 5925eefee25Smacallan Must follow software cursor initialization*/ 5935eefee25Smacallan if (pCg6->HWCursor) { 5945eefee25Smacallan extern Bool CG6HWCursorInit(ScreenPtr pScreen); 5955eefee25Smacallan 5965eefee25Smacallan if(!CG6HWCursorInit(pScreen)) { 5975eefee25Smacallan xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 5985eefee25Smacallan "Hardware cursor initialization failed\n"); 5995eefee25Smacallan return(FALSE); 6005eefee25Smacallan } 6015eefee25Smacallan xf86SbusHideOsHwCursor(pCg6->psdp); 6025eefee25Smacallan } 6035eefee25Smacallan 6045eefee25Smacallan /* Initialise default colourmap */ 6055eefee25Smacallan if (!miCreateDefColormap(pScreen)) 6065eefee25Smacallan return FALSE; 6075eefee25Smacallan 6085eefee25Smacallan if(!xf86SbusHandleColormaps(pScreen, pCg6->psdp)) 6095eefee25Smacallan return FALSE; 6105eefee25Smacallan 6115eefee25Smacallan pCg6->CloseScreen = pScreen->CloseScreen; 6125eefee25Smacallan pScreen->CloseScreen = CG6CloseScreen; 6135eefee25Smacallan pScreen->SaveScreen = CG6SaveScreen; 6145eefee25Smacallan 6155eefee25Smacallan /* Report any unused options (only for the first generation) */ 6165eefee25Smacallan if (serverGeneration == 1) { 6175eefee25Smacallan xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 6185eefee25Smacallan } 6195eefee25Smacallan 6205eefee25Smacallan /* unblank the screen */ 6215eefee25Smacallan CG6SaveScreen(pScreen, SCREEN_SAVER_OFF); 6225eefee25Smacallan 6235eefee25Smacallan /* Done */ 6245eefee25Smacallan return TRUE; 6255eefee25Smacallan} 6265eefee25Smacallan 6275eefee25Smacallan 6285eefee25Smacallan/* Usually mandatory */ 6295eefee25Smacallanstatic Bool 6305eefee25SmacallanCG6SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 6315eefee25Smacallan{ 6325eefee25Smacallan return TRUE; 6335eefee25Smacallan} 6345eefee25Smacallan 6355eefee25Smacallan 6365eefee25Smacallan/* 6375eefee25Smacallan * This function is used to initialize the Start Address - the first 6385eefee25Smacallan * displayed location in the video memory. 6395eefee25Smacallan */ 6405eefee25Smacallan/* Usually mandatory */ 6415eefee25Smacallanstatic void 6425eefee25SmacallanCG6AdjustFrame(int scrnIndex, int x, int y, int flags) 6435eefee25Smacallan{ 6445eefee25Smacallan /* we don't support virtual desktops */ 6455eefee25Smacallan return; 6465eefee25Smacallan} 6475eefee25Smacallan 6485eefee25Smacallan/* 6495eefee25Smacallan * This is called when VT switching back to the X server. Its job is 6505eefee25Smacallan * to reinitialise the video mode. 6515eefee25Smacallan */ 6525eefee25Smacallan 6535eefee25Smacallan/* Mandatory */ 6545eefee25Smacallanstatic Bool 6555eefee25SmacallanCG6EnterVT(int scrnIndex, int flags) 6565eefee25Smacallan{ 6575eefee25Smacallan ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 6585eefee25Smacallan Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn); 6595eefee25Smacallan 6605eefee25Smacallan if (pCg6->HWCursor) { 6615eefee25Smacallan xf86SbusHideOsHwCursor (pCg6->psdp); 6625eefee25Smacallan pCg6->CursorFg = 0; 6635eefee25Smacallan pCg6->CursorBg = 0; 6645eefee25Smacallan } 6655eefee25Smacallan return TRUE; 6665eefee25Smacallan} 6675eefee25Smacallan 6685eefee25Smacallan 6695eefee25Smacallan/* 6705eefee25Smacallan * This is called when VT switching away from the X server. 6715eefee25Smacallan */ 6725eefee25Smacallan 6735eefee25Smacallan/* Mandatory */ 6745eefee25Smacallanstatic void 6755eefee25SmacallanCG6LeaveVT(int scrnIndex, int flags) 6765eefee25Smacallan{ 6775eefee25Smacallan return; 6785eefee25Smacallan} 6795eefee25Smacallan 6805eefee25Smacallan 6815eefee25Smacallan/* 6825eefee25Smacallan * This is called at the end of each server generation. It restores the 6835eefee25Smacallan * original (text) mode. It should really also unmap the video memory too. 6845eefee25Smacallan */ 6855eefee25Smacallan 6865eefee25Smacallan/* Mandatory */ 6875eefee25Smacallanstatic Bool 6885eefee25SmacallanCG6CloseScreen(int scrnIndex, ScreenPtr pScreen) 6895eefee25Smacallan{ 6905eefee25Smacallan ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 6915eefee25Smacallan Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn); 6925eefee25Smacallan 6935eefee25Smacallan pScrn->vtSema = FALSE; 6945eefee25Smacallan 6955eefee25Smacallan xf86UnmapSbusMem(pCg6->psdp, pCg6->fbc, 6965eefee25Smacallan CG6_RAM_VOFF - CG6_FBC_VOFF + 6975eefee25Smacallan (pCg6->psdp->width * pCg6->psdp->height)); 6985eefee25Smacallan 6995eefee25Smacallan if (pCg6->HWCursor) 7005eefee25Smacallan xf86SbusHideOsHwCursor(pCg6->psdp); 7015eefee25Smacallan 7025eefee25Smacallan pScreen->CloseScreen = pCg6->CloseScreen; 7035eefee25Smacallan return (*pScreen->CloseScreen)(scrnIndex, pScreen); 7045eefee25Smacallan return FALSE; 7055eefee25Smacallan} 7065eefee25Smacallan 7075eefee25Smacallan 7085eefee25Smacallan/* Free up any per-generation data structures */ 7095eefee25Smacallan 7105eefee25Smacallan/* Optional */ 7115eefee25Smacallanstatic void 7125eefee25SmacallanCG6FreeScreen(int scrnIndex, int flags) 7135eefee25Smacallan{ 7145eefee25Smacallan CG6FreeRec(xf86Screens[scrnIndex]); 7155eefee25Smacallan} 7165eefee25Smacallan 7175eefee25Smacallan 7185eefee25Smacallan/* Checks if a mode is suitable for the selected chipset. */ 7195eefee25Smacallan 7205eefee25Smacallan/* Optional */ 7215eefee25Smacallanstatic ModeStatus 7225eefee25SmacallanCG6ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) 7235eefee25Smacallan{ 7245eefee25Smacallan if (mode->Flags & V_INTERLACE) 7255eefee25Smacallan return(MODE_BAD); 7265eefee25Smacallan 7275eefee25Smacallan return(MODE_OK); 7285eefee25Smacallan} 7295eefee25Smacallan 7305eefee25Smacallan/* Do screen blanking */ 7315eefee25Smacallan 7325eefee25Smacallan/* Mandatory */ 7335eefee25Smacallanstatic Bool 7345eefee25SmacallanCG6SaveScreen(ScreenPtr pScreen, int mode) 7355eefee25Smacallan{ 7365eefee25Smacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 7375eefee25Smacallan Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn); 7385eefee25Smacallan unsigned int tmp = pCg6->thc->thc_misc; 7395eefee25Smacallan 7405eefee25Smacallan switch(mode) 7415eefee25Smacallan { 7425eefee25Smacallan case SCREEN_SAVER_ON: 7435eefee25Smacallan case SCREEN_SAVER_CYCLE: 7445eefee25Smacallan tmp &= ~CG6_THC_MISC_SYNC_ENAB; 7455eefee25Smacallan break; 7465eefee25Smacallan case SCREEN_SAVER_OFF: 7475eefee25Smacallan case SCREEN_SAVER_FORCER: 7485eefee25Smacallan tmp |= CG6_THC_MISC_SYNC_ENAB; 7495eefee25Smacallan break; 7505eefee25Smacallan default: 7515eefee25Smacallan return FALSE; 7525eefee25Smacallan } 7535eefee25Smacallan 7545eefee25Smacallan pCg6->thc->thc_misc = tmp; 7555eefee25Smacallan return TRUE; 7565eefee25Smacallan} 7575eefee25Smacallan 7585eefee25Smacallan/* 7595eefee25Smacallan * This is the implementation of the Sync() function. 7605eefee25Smacallan */ 7615eefee25Smacallanvoid 7625eefee25SmacallanCG6Sync(ScrnInfoPtr pScrn) 7635eefee25Smacallan{ 7645eefee25Smacallan return; 7655eefee25Smacallan} 766