cg6_driver.c revision 5eefee25
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 295eefee25Smacallan#include <string.h> 305eefee25Smacallan 315eefee25Smacallan#include "xf86.h" 325eefee25Smacallan#include "xf86_OSproc.h" 335eefee25Smacallan#include "xf86Version.h" 345eefee25Smacallan#include "mipointer.h" 355eefee25Smacallan#include "mibstore.h" 365eefee25Smacallan#include "micmap.h" 375eefee25Smacallan 385eefee25Smacallan#include "fb.h" 395eefee25Smacallan#include "xf86cmap.h" 405eefee25Smacallan#include "cg6.h" 415eefee25Smacallan 425eefee25Smacallanstatic const OptionInfoRec * CG6AvailableOptions(int chipid, int busid); 435eefee25Smacallanstatic void CG6Identify(int flags); 445eefee25Smacallanstatic Bool CG6Probe(DriverPtr drv, int flags); 455eefee25Smacallanstatic Bool CG6PreInit(ScrnInfoPtr pScrn, int flags); 465eefee25Smacallanstatic Bool CG6ScreenInit(int Index, ScreenPtr pScreen, int argc, 475eefee25Smacallan char **argv); 485eefee25Smacallanstatic Bool CG6EnterVT(int scrnIndex, int flags); 495eefee25Smacallanstatic void CG6LeaveVT(int scrnIndex, int flags); 505eefee25Smacallanstatic Bool CG6CloseScreen(int scrnIndex, ScreenPtr pScreen); 515eefee25Smacallanstatic Bool CG6SaveScreen(ScreenPtr pScreen, int mode); 525eefee25Smacallan 535eefee25Smacallan/* Required if the driver supports mode switching */ 545eefee25Smacallanstatic Bool CG6SwitchMode(int scrnIndex, DisplayModePtr mode, int flags); 555eefee25Smacallan/* Required if the driver supports moving the viewport */ 565eefee25Smacallanstatic void CG6AdjustFrame(int scrnIndex, int x, int y, int flags); 575eefee25Smacallan 585eefee25Smacallan/* Optional functions */ 595eefee25Smacallanstatic void CG6FreeScreen(int scrnIndex, int flags); 605eefee25Smacallanstatic ModeStatus CG6ValidMode(int scrnIndex, DisplayModePtr mode, 615eefee25Smacallan Bool verbose, int flags); 625eefee25Smacallan 635eefee25Smacallanvoid CG6Sync(ScrnInfoPtr pScrn); 645eefee25Smacallan 655eefee25Smacallan#define CG6_VERSION 4000 665eefee25Smacallan#define CG6_NAME "SUNCG6" 675eefee25Smacallan#define CG6_DRIVER_NAME "suncg6" 685eefee25Smacallan#define CG6_MAJOR_VERSION 1 695eefee25Smacallan#define CG6_MINOR_VERSION 1 705eefee25Smacallan#define CG6_PATCHLEVEL 0 715eefee25Smacallan 725eefee25Smacallan/* 735eefee25Smacallan * This contains the functions needed by the server after loading the driver 745eefee25Smacallan * module. It must be supplied, and gets passed back by the SetupProc 755eefee25Smacallan * function in the dynamic case. In the static case, a reference to this 765eefee25Smacallan * is compiled in, and this requires that the name of this DriverRec be 775eefee25Smacallan * an upper-case version of the driver name. 785eefee25Smacallan */ 795eefee25Smacallan 805eefee25Smacallan_X_EXPORT DriverRec SUNCG6 = { 815eefee25Smacallan CG6_VERSION, 825eefee25Smacallan CG6_DRIVER_NAME, 835eefee25Smacallan CG6Identify, 845eefee25Smacallan CG6Probe, 855eefee25Smacallan CG6AvailableOptions, 865eefee25Smacallan NULL, 875eefee25Smacallan 0 885eefee25Smacallan}; 895eefee25Smacallan 905eefee25Smacallantypedef enum { 915eefee25Smacallan OPTION_SW_CURSOR, 925eefee25Smacallan OPTION_HW_CURSOR, 935eefee25Smacallan OPTION_NOACCEL 945eefee25Smacallan} CG6Opts; 955eefee25Smacallan 965eefee25Smacallanstatic const OptionInfoRec CG6Options[] = { 975eefee25Smacallan { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, 985eefee25Smacallan { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, 995eefee25Smacallan { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 1005eefee25Smacallan { -1, NULL, OPTV_NONE, {0}, FALSE } 1015eefee25Smacallan}; 1025eefee25Smacallan 1035eefee25Smacallan#ifdef XFree86LOADER 1045eefee25Smacallan 1055eefee25Smacallanstatic MODULESETUPPROTO(cg6Setup); 1065eefee25Smacallan 1075eefee25Smacallanstatic XF86ModuleVersionInfo suncg6VersRec = 1085eefee25Smacallan{ 1095eefee25Smacallan "suncg6", 1105eefee25Smacallan MODULEVENDORSTRING, 1115eefee25Smacallan MODINFOSTRING1, 1125eefee25Smacallan MODINFOSTRING2, 1135eefee25Smacallan XORG_VERSION_CURRENT, 1145eefee25Smacallan CG6_MAJOR_VERSION, CG6_MINOR_VERSION, CG6_PATCHLEVEL, 1155eefee25Smacallan ABI_CLASS_VIDEODRV, 1165eefee25Smacallan ABI_VIDEODRV_VERSION, 1175eefee25Smacallan MOD_CLASS_VIDEODRV, 1185eefee25Smacallan {0,0,0,0} 1195eefee25Smacallan}; 1205eefee25Smacallan 1215eefee25Smacallan_X_EXPORT XF86ModuleData suncg6ModuleData = { &suncg6VersRec, cg6Setup, NULL }; 1225eefee25Smacallan 1235eefee25Smacallanpointer 1245eefee25Smacallancg6Setup(pointer module, pointer opts, int *errmaj, int *errmin) 1255eefee25Smacallan{ 1265eefee25Smacallan static Bool setupDone = FALSE; 1275eefee25Smacallan 1285eefee25Smacallan if (!setupDone) { 1295eefee25Smacallan setupDone = TRUE; 1305eefee25Smacallan xf86AddDriver(&SUNCG6, module, 0); 1315eefee25Smacallan 1325eefee25Smacallan /* 1335eefee25Smacallan * Modules that this driver always requires can be loaded here 1345eefee25Smacallan * by calling LoadSubModule(). 1355eefee25Smacallan */ 1365eefee25Smacallan 1375eefee25Smacallan /* 1385eefee25Smacallan * The return value must be non-NULL on success even though there 1395eefee25Smacallan * is no TearDownProc. 1405eefee25Smacallan */ 1415eefee25Smacallan return (pointer)TRUE; 1425eefee25Smacallan } else { 1435eefee25Smacallan if (errmaj) *errmaj = LDR_ONCEONLY; 1445eefee25Smacallan return NULL; 1455eefee25Smacallan } 1465eefee25Smacallan} 1475eefee25Smacallan 1485eefee25Smacallan#endif /* XFree86LOADER */ 1495eefee25Smacallan 1505eefee25Smacallanstatic Bool 1515eefee25SmacallanCG6GetRec(ScrnInfoPtr pScrn) 1525eefee25Smacallan{ 1535eefee25Smacallan /* 1545eefee25Smacallan * Allocate an Cg6Rec, and hook it into pScrn->driverPrivate. 1555eefee25Smacallan * pScrn->driverPrivate is initialised to NULL, so we can check if 1565eefee25Smacallan * the allocation has already been done. 1575eefee25Smacallan */ 1585eefee25Smacallan if (pScrn->driverPrivate != NULL) 1595eefee25Smacallan return TRUE; 1605eefee25Smacallan 1615eefee25Smacallan pScrn->driverPrivate = xnfcalloc(sizeof(Cg6Rec), 1); 1625eefee25Smacallan return TRUE; 1635eefee25Smacallan} 1645eefee25Smacallan 1655eefee25Smacallanstatic void 1665eefee25SmacallanCG6FreeRec(ScrnInfoPtr pScrn) 1675eefee25Smacallan{ 1685eefee25Smacallan Cg6Ptr pCg6; 1695eefee25Smacallan 1705eefee25Smacallan if (pScrn->driverPrivate == NULL) 1715eefee25Smacallan return; 1725eefee25Smacallan 1735eefee25Smacallan pCg6 = GET_CG6_FROM_SCRN(pScrn); 1745eefee25Smacallan 1755eefee25Smacallan xfree(pScrn->driverPrivate); 1765eefee25Smacallan pScrn->driverPrivate = NULL; 1775eefee25Smacallan 1785eefee25Smacallan return; 1795eefee25Smacallan} 1805eefee25Smacallan 1815eefee25Smacallanstatic const OptionInfoRec * 1825eefee25SmacallanCG6AvailableOptions(int chipid, int busid) 1835eefee25Smacallan{ 1845eefee25Smacallan return CG6Options; 1855eefee25Smacallan} 1865eefee25Smacallan 1875eefee25Smacallan/* Mandatory */ 1885eefee25Smacallanstatic void 1895eefee25SmacallanCG6Identify(int flags) 1905eefee25Smacallan{ 1915eefee25Smacallan xf86Msg(X_INFO, "%s: driver for CGsix (GX and Turbo GX)\n", CG6_NAME); 1925eefee25Smacallan} 1935eefee25Smacallan 1945eefee25Smacallan 1955eefee25Smacallan/* Mandatory */ 1965eefee25Smacallanstatic Bool 1975eefee25SmacallanCG6Probe(DriverPtr drv, int flags) 1985eefee25Smacallan{ 1995eefee25Smacallan int i; 2005eefee25Smacallan GDevPtr *devSections; 2015eefee25Smacallan int *usedChips; 2025eefee25Smacallan int numDevSections; 2035eefee25Smacallan int numUsed; 2045eefee25Smacallan Bool foundScreen = FALSE; 2055eefee25Smacallan EntityInfoPtr pEnt; 2065eefee25Smacallan 2075eefee25Smacallan /* 2085eefee25Smacallan * The aim here is to find all cards that this driver can handle, 2095eefee25Smacallan * and for the ones not already claimed by another driver, claim the 2105eefee25Smacallan * slot, and allocate a ScrnInfoRec. 2115eefee25Smacallan * 2125eefee25Smacallan * This should be a minimal probe, and it should under no circumstances 2135eefee25Smacallan * change the state of the hardware. Because a device is found, don't 2145eefee25Smacallan * assume that it will be used. Don't do any initialisations other than 2155eefee25Smacallan * the required ScrnInfoRec initialisations. Don't allocate any new 2165eefee25Smacallan * data structures. 2175eefee25Smacallan */ 2185eefee25Smacallan 2195eefee25Smacallan /* 2205eefee25Smacallan * Next we check, if there has been a chipset override in the config file. 2215eefee25Smacallan * For this we must find out if there is an active device section which 2225eefee25Smacallan * is relevant, i.e., which has no driver specified or has THIS driver 2235eefee25Smacallan * specified. 2245eefee25Smacallan */ 2255eefee25Smacallan 2265eefee25Smacallan if ((numDevSections = xf86MatchDevice(CG6_DRIVER_NAME, 2275eefee25Smacallan &devSections)) <= 0) { 2285eefee25Smacallan /* 2295eefee25Smacallan * There's no matching device section in the config file, so quit 2305eefee25Smacallan * now. 2315eefee25Smacallan */ 2325eefee25Smacallan return FALSE; 2335eefee25Smacallan } 2345eefee25Smacallan 2355eefee25Smacallan /* 2365eefee25Smacallan * We need to probe the hardware first. We then need to see how this 2375eefee25Smacallan * fits in with what is given in the config file, and allow the config 2385eefee25Smacallan * file info to override any contradictions. 2395eefee25Smacallan */ 2405eefee25Smacallan 2415eefee25Smacallan numUsed = xf86MatchSbusInstances(CG6_NAME, SBUS_DEVICE_CG6, 2425eefee25Smacallan devSections, numDevSections, 2435eefee25Smacallan drv, &usedChips); 2445eefee25Smacallan 2455eefee25Smacallan xfree(devSections); 2465eefee25Smacallan if (numUsed <= 0) 2475eefee25Smacallan return FALSE; 2485eefee25Smacallan 2495eefee25Smacallan if (flags & PROBE_DETECT) 2505eefee25Smacallan foundScreen = TRUE; 2515eefee25Smacallan else for (i = 0; i < numUsed; i++) { 2525eefee25Smacallan pEnt = xf86GetEntityInfo(usedChips[i]); 2535eefee25Smacallan 2545eefee25Smacallan /* 2555eefee25Smacallan * Check that nothing else has claimed the slots. 2565eefee25Smacallan */ 2575eefee25Smacallan if(pEnt->active) { 2585eefee25Smacallan ScrnInfoPtr pScrn; 2595eefee25Smacallan 2605eefee25Smacallan /* Allocate a ScrnInfoRec and claim the slot */ 2615eefee25Smacallan pScrn = xf86AllocateScreen(drv, 0); 2625eefee25Smacallan 2635eefee25Smacallan /* Fill in what we can of the ScrnInfoRec */ 2645eefee25Smacallan pScrn->driverVersion = CG6_VERSION; 2655eefee25Smacallan pScrn->driverName = CG6_DRIVER_NAME; 2665eefee25Smacallan pScrn->name = CG6_NAME; 2675eefee25Smacallan pScrn->Probe = CG6Probe; 2685eefee25Smacallan pScrn->PreInit = CG6PreInit; 2695eefee25Smacallan pScrn->ScreenInit = CG6ScreenInit; 2705eefee25Smacallan pScrn->SwitchMode = CG6SwitchMode; 2715eefee25Smacallan pScrn->AdjustFrame = CG6AdjustFrame; 2725eefee25Smacallan pScrn->EnterVT = CG6EnterVT; 2735eefee25Smacallan pScrn->LeaveVT = CG6LeaveVT; 2745eefee25Smacallan pScrn->FreeScreen = CG6FreeScreen; 2755eefee25Smacallan pScrn->ValidMode = CG6ValidMode; 2765eefee25Smacallan xf86AddEntityToScreen(pScrn, pEnt->index); 2775eefee25Smacallan foundScreen = TRUE; 2785eefee25Smacallan } 2795eefee25Smacallan xfree(pEnt); 2805eefee25Smacallan } 2815eefee25Smacallan xfree(usedChips); 2825eefee25Smacallan return foundScreen; 2835eefee25Smacallan} 2845eefee25Smacallan 2855eefee25Smacallan/* Mandatory */ 2865eefee25Smacallanstatic Bool 2875eefee25SmacallanCG6PreInit(ScrnInfoPtr pScrn, int flags) 2885eefee25Smacallan{ 2895eefee25Smacallan Cg6Ptr pCg6; 2905eefee25Smacallan sbusDevicePtr psdp; 2915eefee25Smacallan MessageType from; 2925eefee25Smacallan int i; 2935eefee25Smacallan 2945eefee25Smacallan if (flags & PROBE_DETECT) return FALSE; 2955eefee25Smacallan 2965eefee25Smacallan /* 2975eefee25Smacallan * Note: This function is only called once at server startup, and 2985eefee25Smacallan * not at the start of each server generation. This means that 2995eefee25Smacallan * only things that are persistent across server generations can 3005eefee25Smacallan * be initialised here. xf86Screens[] is (pScrn is a pointer to one 3015eefee25Smacallan * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex() 3025eefee25Smacallan * are too, and should be used for data that must persist across 3035eefee25Smacallan * server generations. 3045eefee25Smacallan * 3055eefee25Smacallan * Per-generation data should be allocated with 3065eefee25Smacallan * AllocateScreenPrivateIndex() from the ScreenInit() function. 3075eefee25Smacallan */ 3085eefee25Smacallan 3095eefee25Smacallan /* Allocate the Cg6Rec driverPrivate */ 3105eefee25Smacallan if (!CG6GetRec(pScrn)) { 3115eefee25Smacallan return FALSE; 3125eefee25Smacallan } 3135eefee25Smacallan pCg6 = GET_CG6_FROM_SCRN(pScrn); 3145eefee25Smacallan 3155eefee25Smacallan /* Set pScrn->monitor */ 3165eefee25Smacallan pScrn->monitor = pScrn->confScreen->monitor; 3175eefee25Smacallan 3185eefee25Smacallan /* This driver doesn't expect more than one entity per screen */ 3195eefee25Smacallan if (pScrn->numEntities > 1) 3205eefee25Smacallan return FALSE; 3215eefee25Smacallan /* This is the general case */ 3225eefee25Smacallan for (i = 0; i < pScrn->numEntities; i++) { 3235eefee25Smacallan EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[i]); 3245eefee25Smacallan 3255eefee25Smacallan /* CG6 is purely SBUS */ 3265eefee25Smacallan if (pEnt->location.type == BUS_SBUS) { 3275eefee25Smacallan psdp = xf86GetSbusInfoForEntity(pEnt->index); 3285eefee25Smacallan pCg6->psdp = psdp; 3295eefee25Smacallan } else 3305eefee25Smacallan return FALSE; 3315eefee25Smacallan } 3325eefee25Smacallan 3335eefee25Smacallan /********************* 3345eefee25Smacallan deal with depth 3355eefee25Smacallan *********************/ 3365eefee25Smacallan 3375eefee25Smacallan if (!xf86SetDepthBpp(pScrn, 0, 0, 0, NoDepth24Support)) { 3385eefee25Smacallan return FALSE; 3395eefee25Smacallan } else { 3405eefee25Smacallan /* Check that the returned depth is one we support */ 3415eefee25Smacallan switch (pScrn->depth) { 3425eefee25Smacallan case 8: 3435eefee25Smacallan /* OK */ 3445eefee25Smacallan break; 3455eefee25Smacallan default: 3465eefee25Smacallan xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 3475eefee25Smacallan "Given depth (%d) is not supported by this driver\n", 3485eefee25Smacallan pScrn->depth); 3495eefee25Smacallan return FALSE; 3505eefee25Smacallan } 3515eefee25Smacallan } 3525eefee25Smacallan 3535eefee25Smacallan /* Collect all of the relevant option flags (fill in pScrn->options) */ 3545eefee25Smacallan xf86CollectOptions(pScrn, NULL); 3555eefee25Smacallan /* Process the options */ 3565eefee25Smacallan if (!(pCg6->Options = xalloc(sizeof(CG6Options)))) 3575eefee25Smacallan return FALSE; 3585eefee25Smacallan memcpy(pCg6->Options, CG6Options, sizeof(CG6Options)); 3595eefee25Smacallan xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pCg6->Options); 3605eefee25Smacallan 3615eefee25Smacallan if (!xf86SetDefaultVisual(pScrn, -1)) 3625eefee25Smacallan return FALSE; 3635eefee25Smacallan 3645eefee25Smacallan /* 3655eefee25Smacallan * The new cmap code requires this to be initialised. 3665eefee25Smacallan */ 3675eefee25Smacallan 3685eefee25Smacallan { 3695eefee25Smacallan Gamma zeros = {0.0, 0.0, 0.0}; 3705eefee25Smacallan 3715eefee25Smacallan if (!xf86SetGamma(pScrn, zeros)) { 3725eefee25Smacallan return FALSE; 3735eefee25Smacallan } 3745eefee25Smacallan } 3755eefee25Smacallan 3765eefee25Smacallan /* Set the bits per RGB for 8bpp mode */ 3775eefee25Smacallan from = X_DEFAULT; 3785eefee25Smacallan 3795eefee25Smacallan /* determine whether we use hardware or software cursor */ 3805eefee25Smacallan 3815eefee25Smacallan pCg6->HWCursor = TRUE; 3825eefee25Smacallan if (xf86GetOptValBool(pCg6->Options, OPTION_HW_CURSOR, &pCg6->HWCursor)) 3835eefee25Smacallan from = X_CONFIG; 3845eefee25Smacallan if (xf86ReturnOptValBool(pCg6->Options, OPTION_SW_CURSOR, FALSE)) { 3855eefee25Smacallan from = X_CONFIG; 3865eefee25Smacallan pCg6->HWCursor = FALSE; 3875eefee25Smacallan } 3885eefee25Smacallan 3895eefee25Smacallan xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 3905eefee25Smacallan pCg6->HWCursor ? "HW" : "SW"); 3915eefee25Smacallan 3925eefee25Smacallan if (xf86ReturnOptValBool(pCg6->Options, OPTION_NOACCEL, FALSE)) { 3935eefee25Smacallan pCg6->NoAccel = TRUE; 3945eefee25Smacallan xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); 3955eefee25Smacallan } 3965eefee25Smacallan 3975eefee25Smacallan if (xf86LoadSubModule(pScrn, "fb") == NULL) { 3985eefee25Smacallan CG6FreeRec(pScrn); 3995eefee25Smacallan return FALSE; 4005eefee25Smacallan } 4015eefee25Smacallan 4025eefee25Smacallan if (pCg6->HWCursor && xf86LoadSubModule(pScrn, "ramdac") == NULL) { 4035eefee25Smacallan CG6FreeRec(pScrn); 4045eefee25Smacallan return FALSE; 4055eefee25Smacallan } 4065eefee25Smacallan 4075eefee25Smacallan /********************* 4085eefee25Smacallan set up clock and mode stuff 4095eefee25Smacallan *********************/ 4105eefee25Smacallan 4115eefee25Smacallan pScrn->progClock = TRUE; 4125eefee25Smacallan 4135eefee25Smacallan if(pScrn->display->virtualX || pScrn->display->virtualY) { 4145eefee25Smacallan xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 4155eefee25Smacallan "CG6 does not support a virtual desktop\n"); 4165eefee25Smacallan pScrn->display->virtualX = 0; 4175eefee25Smacallan pScrn->display->virtualY = 0; 4185eefee25Smacallan } 4195eefee25Smacallan 4205eefee25Smacallan xf86SbusUseBuiltinMode(pScrn, pCg6->psdp); 4215eefee25Smacallan pScrn->currentMode = pScrn->modes; 4225eefee25Smacallan pScrn->displayWidth = pScrn->virtualX; 4235eefee25Smacallan 4245eefee25Smacallan /* Set display resolution */ 4255eefee25Smacallan xf86SetDpi(pScrn, 0, 0); 4265eefee25Smacallan 4275eefee25Smacallan return TRUE; 4285eefee25Smacallan} 4295eefee25Smacallan 4305eefee25Smacallan/* Mandatory */ 4315eefee25Smacallan 4325eefee25Smacallan/* This gets called at the start of each server generation */ 4335eefee25Smacallan 4345eefee25Smacallanstatic Bool 4355eefee25SmacallanCG6ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 4365eefee25Smacallan{ 4375eefee25Smacallan ScrnInfoPtr pScrn; 4385eefee25Smacallan Cg6Ptr pCg6; 4395eefee25Smacallan int ret; 4405eefee25Smacallan 4415eefee25Smacallan /* 4425eefee25Smacallan * First get the ScrnInfoRec 4435eefee25Smacallan */ 4445eefee25Smacallan pScrn = xf86Screens[pScreen->myNum]; 4455eefee25Smacallan 4465eefee25Smacallan pCg6 = GET_CG6_FROM_SCRN(pScrn); 4475eefee25Smacallan 4485eefee25Smacallan /* Map the CG6 memory */ 4495eefee25Smacallan pCg6->fbc = 4505eefee25Smacallan xf86MapSbusMem (pCg6->psdp, CG6_FBC_VOFF, 4515eefee25Smacallan CG6_RAM_VOFF - CG6_FBC_VOFF + 4525eefee25Smacallan (pCg6->psdp->width * pCg6->psdp->height)); 4535eefee25Smacallan 4545eefee25Smacallan if (! pCg6->fbc) 4555eefee25Smacallan return FALSE; 4565eefee25Smacallan 4575eefee25Smacallan pCg6->fb = (unsigned char *)pCg6->fbc + CG6_RAM_VOFF - CG6_FBC_VOFF; 4585eefee25Smacallan pCg6->thc = (Cg6ThcPtr)((char *)pCg6->fbc + CG6_THC_VOFF - CG6_FBC_VOFF); 4595eefee25Smacallan 4605eefee25Smacallan /* Darken the screen for aesthetic reasons and set the viewport */ 4615eefee25Smacallan CG6SaveScreen(pScreen, SCREEN_SAVER_ON); 4625eefee25Smacallan 4635eefee25Smacallan /* 4645eefee25Smacallan * The next step is to setup the screen's visuals, and initialise the 4655eefee25Smacallan * framebuffer code. In cases where the framebuffer's default 4665eefee25Smacallan * choices for things like visual layouts and bits per RGB are OK, 4675eefee25Smacallan * this may be as simple as calling the framebuffer's ScreenInit() 4685eefee25Smacallan * function. If not, the visuals will need to be setup before calling 4695eefee25Smacallan * a fb ScreenInit() function and fixed up after. 4705eefee25Smacallan */ 4715eefee25Smacallan 4725eefee25Smacallan /* 4735eefee25Smacallan * Reset visual list. 4745eefee25Smacallan */ 4755eefee25Smacallan miClearVisualTypes(); 4765eefee25Smacallan 4775eefee25Smacallan /* Set the bits per RGB for 8bpp mode */ 4785eefee25Smacallan pScrn->rgbBits = 8; 4795eefee25Smacallan 4805eefee25Smacallan /* Setup the visuals we support. */ 4815eefee25Smacallan 4825eefee25Smacallan if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), 4835eefee25Smacallan pScrn->rgbBits, pScrn->defaultVisual)) 4845eefee25Smacallan return FALSE; 4855eefee25Smacallan 4865eefee25Smacallan miSetPixmapDepths (); 4875eefee25Smacallan 4885eefee25Smacallan /* 4895eefee25Smacallan * Call the framebuffer layer's ScreenInit function, and fill in other 4905eefee25Smacallan * pScreen fields. 4915eefee25Smacallan */ 4925eefee25Smacallan 4935eefee25Smacallan ret = fbScreenInit(pScreen, pCg6->fb, pScrn->virtualX, 4945eefee25Smacallan pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, 4955eefee25Smacallan pScrn->virtualX, 8); 4965eefee25Smacallan if (!ret) 4975eefee25Smacallan return FALSE; 4985eefee25Smacallan 4995eefee25Smacallan#ifdef RENDER 5005eefee25Smacallan fbPictureInit (pScreen, 0, 0); 5015eefee25Smacallan#endif 5025eefee25Smacallan 5035eefee25Smacallan miInitializeBackingStore(pScreen); 5045eefee25Smacallan xf86SetBackingStore(pScreen); 5055eefee25Smacallan xf86SetSilkenMouse(pScreen); 5065eefee25Smacallan 5075eefee25Smacallan xf86SetBlackWhitePixels(pScreen); 5085eefee25Smacallan 5095eefee25Smacallan#if 0 5105eefee25Smacallan if (!pCg6->NoAccel) { 5115eefee25Smacallan extern Bool CG6AccelInit(ScreenPtr pScreen, Cg6Ptr pCg6); 5125eefee25Smacallan 5135eefee25Smacallan if (!CG6AccelInit(pScreen, pCg6)) 5145eefee25Smacallan return FALSE; 5155eefee25Smacallan xf86Msg(X_INFO, "%s: Using acceleration\n", pCg6->psdp->device); 5165eefee25Smacallan } 5175eefee25Smacallan#endif 5185eefee25Smacallan 5195eefee25Smacallan /* Initialise cursor functions */ 5205eefee25Smacallan miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); 5215eefee25Smacallan 5225eefee25Smacallan /* Initialize HW cursor layer. 5235eefee25Smacallan Must follow software cursor initialization*/ 5245eefee25Smacallan if (pCg6->HWCursor) { 5255eefee25Smacallan extern Bool CG6HWCursorInit(ScreenPtr pScreen); 5265eefee25Smacallan 5275eefee25Smacallan if(!CG6HWCursorInit(pScreen)) { 5285eefee25Smacallan xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 5295eefee25Smacallan "Hardware cursor initialization failed\n"); 5305eefee25Smacallan return(FALSE); 5315eefee25Smacallan } 5325eefee25Smacallan xf86SbusHideOsHwCursor(pCg6->psdp); 5335eefee25Smacallan } 5345eefee25Smacallan 5355eefee25Smacallan /* Initialise default colourmap */ 5365eefee25Smacallan if (!miCreateDefColormap(pScreen)) 5375eefee25Smacallan return FALSE; 5385eefee25Smacallan 5395eefee25Smacallan if(!xf86SbusHandleColormaps(pScreen, pCg6->psdp)) 5405eefee25Smacallan return FALSE; 5415eefee25Smacallan 5425eefee25Smacallan pCg6->CloseScreen = pScreen->CloseScreen; 5435eefee25Smacallan pScreen->CloseScreen = CG6CloseScreen; 5445eefee25Smacallan pScreen->SaveScreen = CG6SaveScreen; 5455eefee25Smacallan 5465eefee25Smacallan /* Report any unused options (only for the first generation) */ 5475eefee25Smacallan if (serverGeneration == 1) { 5485eefee25Smacallan xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 5495eefee25Smacallan } 5505eefee25Smacallan 5515eefee25Smacallan /* unblank the screen */ 5525eefee25Smacallan CG6SaveScreen(pScreen, SCREEN_SAVER_OFF); 5535eefee25Smacallan 5545eefee25Smacallan /* Done */ 5555eefee25Smacallan return TRUE; 5565eefee25Smacallan} 5575eefee25Smacallan 5585eefee25Smacallan 5595eefee25Smacallan/* Usually mandatory */ 5605eefee25Smacallanstatic Bool 5615eefee25SmacallanCG6SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 5625eefee25Smacallan{ 5635eefee25Smacallan return TRUE; 5645eefee25Smacallan} 5655eefee25Smacallan 5665eefee25Smacallan 5675eefee25Smacallan/* 5685eefee25Smacallan * This function is used to initialize the Start Address - the first 5695eefee25Smacallan * displayed location in the video memory. 5705eefee25Smacallan */ 5715eefee25Smacallan/* Usually mandatory */ 5725eefee25Smacallanstatic void 5735eefee25SmacallanCG6AdjustFrame(int scrnIndex, int x, int y, int flags) 5745eefee25Smacallan{ 5755eefee25Smacallan /* we don't support virtual desktops */ 5765eefee25Smacallan return; 5775eefee25Smacallan} 5785eefee25Smacallan 5795eefee25Smacallan/* 5805eefee25Smacallan * This is called when VT switching back to the X server. Its job is 5815eefee25Smacallan * to reinitialise the video mode. 5825eefee25Smacallan */ 5835eefee25Smacallan 5845eefee25Smacallan/* Mandatory */ 5855eefee25Smacallanstatic Bool 5865eefee25SmacallanCG6EnterVT(int scrnIndex, int flags) 5875eefee25Smacallan{ 5885eefee25Smacallan ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 5895eefee25Smacallan Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn); 5905eefee25Smacallan 5915eefee25Smacallan if (pCg6->HWCursor) { 5925eefee25Smacallan xf86SbusHideOsHwCursor (pCg6->psdp); 5935eefee25Smacallan pCg6->CursorFg = 0; 5945eefee25Smacallan pCg6->CursorBg = 0; 5955eefee25Smacallan } 5965eefee25Smacallan return TRUE; 5975eefee25Smacallan} 5985eefee25Smacallan 5995eefee25Smacallan 6005eefee25Smacallan/* 6015eefee25Smacallan * This is called when VT switching away from the X server. 6025eefee25Smacallan */ 6035eefee25Smacallan 6045eefee25Smacallan/* Mandatory */ 6055eefee25Smacallanstatic void 6065eefee25SmacallanCG6LeaveVT(int scrnIndex, int flags) 6075eefee25Smacallan{ 6085eefee25Smacallan return; 6095eefee25Smacallan} 6105eefee25Smacallan 6115eefee25Smacallan 6125eefee25Smacallan/* 6135eefee25Smacallan * This is called at the end of each server generation. It restores the 6145eefee25Smacallan * original (text) mode. It should really also unmap the video memory too. 6155eefee25Smacallan */ 6165eefee25Smacallan 6175eefee25Smacallan/* Mandatory */ 6185eefee25Smacallanstatic Bool 6195eefee25SmacallanCG6CloseScreen(int scrnIndex, ScreenPtr pScreen) 6205eefee25Smacallan{ 6215eefee25Smacallan ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 6225eefee25Smacallan Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn); 6235eefee25Smacallan 6245eefee25Smacallan pScrn->vtSema = FALSE; 6255eefee25Smacallan 6265eefee25Smacallan xf86UnmapSbusMem(pCg6->psdp, pCg6->fbc, 6275eefee25Smacallan CG6_RAM_VOFF - CG6_FBC_VOFF + 6285eefee25Smacallan (pCg6->psdp->width * pCg6->psdp->height)); 6295eefee25Smacallan 6305eefee25Smacallan if (pCg6->HWCursor) 6315eefee25Smacallan xf86SbusHideOsHwCursor(pCg6->psdp); 6325eefee25Smacallan 6335eefee25Smacallan pScreen->CloseScreen = pCg6->CloseScreen; 6345eefee25Smacallan return (*pScreen->CloseScreen)(scrnIndex, pScreen); 6355eefee25Smacallan return FALSE; 6365eefee25Smacallan} 6375eefee25Smacallan 6385eefee25Smacallan 6395eefee25Smacallan/* Free up any per-generation data structures */ 6405eefee25Smacallan 6415eefee25Smacallan/* Optional */ 6425eefee25Smacallanstatic void 6435eefee25SmacallanCG6FreeScreen(int scrnIndex, int flags) 6445eefee25Smacallan{ 6455eefee25Smacallan CG6FreeRec(xf86Screens[scrnIndex]); 6465eefee25Smacallan} 6475eefee25Smacallan 6485eefee25Smacallan 6495eefee25Smacallan/* Checks if a mode is suitable for the selected chipset. */ 6505eefee25Smacallan 6515eefee25Smacallan/* Optional */ 6525eefee25Smacallanstatic ModeStatus 6535eefee25SmacallanCG6ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) 6545eefee25Smacallan{ 6555eefee25Smacallan if (mode->Flags & V_INTERLACE) 6565eefee25Smacallan return(MODE_BAD); 6575eefee25Smacallan 6585eefee25Smacallan return(MODE_OK); 6595eefee25Smacallan} 6605eefee25Smacallan 6615eefee25Smacallan/* Do screen blanking */ 6625eefee25Smacallan 6635eefee25Smacallan/* Mandatory */ 6645eefee25Smacallanstatic Bool 6655eefee25SmacallanCG6SaveScreen(ScreenPtr pScreen, int mode) 6665eefee25Smacallan{ 6675eefee25Smacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 6685eefee25Smacallan Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn); 6695eefee25Smacallan unsigned int tmp = pCg6->thc->thc_misc; 6705eefee25Smacallan 6715eefee25Smacallan switch(mode) 6725eefee25Smacallan { 6735eefee25Smacallan case SCREEN_SAVER_ON: 6745eefee25Smacallan case SCREEN_SAVER_CYCLE: 6755eefee25Smacallan tmp &= ~CG6_THC_MISC_SYNC_ENAB; 6765eefee25Smacallan break; 6775eefee25Smacallan case SCREEN_SAVER_OFF: 6785eefee25Smacallan case SCREEN_SAVER_FORCER: 6795eefee25Smacallan tmp |= CG6_THC_MISC_SYNC_ENAB; 6805eefee25Smacallan break; 6815eefee25Smacallan default: 6825eefee25Smacallan return FALSE; 6835eefee25Smacallan } 6845eefee25Smacallan 6855eefee25Smacallan pCg6->thc->thc_misc = tmp; 6865eefee25Smacallan return TRUE; 6875eefee25Smacallan} 6885eefee25Smacallan 6895eefee25Smacallan/* 6905eefee25Smacallan * This is the implementation of the Sync() function. 6915eefee25Smacallan */ 6925eefee25Smacallanvoid 6935eefee25SmacallanCG6Sync(ScrnInfoPtr pScrn) 6945eefee25Smacallan{ 6955eefee25Smacallan return; 6965eefee25Smacallan} 697