10724dadfSmrg
24a041c5bSmacallan/*
34a041c5bSmacallan * Leo (ZX) framebuffer driver.
44a041c5bSmacallan *
54a041c5bSmacallan * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com)
64a041c5bSmacallan *
74a041c5bSmacallan * Permission is hereby granted, free of charge, to any person obtaining a copy
84a041c5bSmacallan * of this software and associated documentation files (the "Software"), to deal
94a041c5bSmacallan * in the Software without restriction, including without limitation the rights
104a041c5bSmacallan * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
114a041c5bSmacallan * copies of the Software, and to permit persons to whom the Software is
124a041c5bSmacallan * furnished to do so, subject to the following conditions:
134a041c5bSmacallan *
144a041c5bSmacallan * The above copyright notice and this permission notice shall be included in
154a041c5bSmacallan * all copies or substantial portions of the Software.
164a041c5bSmacallan *
174a041c5bSmacallan * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
184a041c5bSmacallan * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
194a041c5bSmacallan * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
204a041c5bSmacallan * JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
214a041c5bSmacallan * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
224a041c5bSmacallan * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
234a041c5bSmacallan */
244a041c5bSmacallan
254a041c5bSmacallan#ifdef HAVE_CONFIG_H
264a041c5bSmacallan#include "config.h"
274a041c5bSmacallan#endif
284a041c5bSmacallan
294a041c5bSmacallan#include <string.h>
304a041c5bSmacallan
314a041c5bSmacallan#include "xf86.h"
324a041c5bSmacallan#include "xf86_OSproc.h"
334a041c5bSmacallan#include "mipointer.h"
344a041c5bSmacallan#include "micmap.h"
354a041c5bSmacallan
364a041c5bSmacallan#include "fb.h"
374a041c5bSmacallan#include "xf86cmap.h"
384a041c5bSmacallan#include "leo.h"
394a041c5bSmacallan
404a041c5bSmacallanstatic const OptionInfoRec * LeoAvailableOptions(int chipid, int busid);
414a041c5bSmacallanstatic void	LeoIdentify(int flags);
424a041c5bSmacallanstatic Bool	LeoProbe(DriverPtr drv, int flags);
434a041c5bSmacallanstatic Bool	LeoPreInit(ScrnInfoPtr pScrn, int flags);
447a5333bcSmrgstatic Bool	LeoScreenInit(SCREEN_INIT_ARGS_DECL);
457a5333bcSmrgstatic Bool	LeoEnterVT(VT_FUNC_ARGS_DECL);
467a5333bcSmrgstatic void	LeoLeaveVT(VT_FUNC_ARGS_DECL);
477a5333bcSmrgstatic Bool	LeoCloseScreen(CLOSE_SCREEN_ARGS_DECL);
484a041c5bSmacallanstatic Bool	LeoSaveScreen(ScreenPtr pScreen, int mode);
494a041c5bSmacallan
504a041c5bSmacallan/* Required if the driver supports mode switching */
517a5333bcSmrgstatic Bool	LeoSwitchMode(SWITCH_MODE_ARGS_DECL);
524a041c5bSmacallan/* Required if the driver supports moving the viewport */
537a5333bcSmrgstatic void	LeoAdjustFrame(ADJUST_FRAME_ARGS_DECL);
544a041c5bSmacallan
554a041c5bSmacallan/* Optional functions */
567a5333bcSmrgstatic void	LeoFreeScreen(FREE_SCREEN_ARGS_DECL);
577a5333bcSmrgstatic ModeStatus LeoValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode,
584a041c5bSmacallan			       Bool verbose, int flags);
594a041c5bSmacallan
604a041c5bSmacallanvoid LeoSync(ScrnInfoPtr pScrn);
614a041c5bSmacallan
624a041c5bSmacallan#define LEO_VERSION 4000
634a041c5bSmacallan#define LEO_NAME "SUNLEO"
644a041c5bSmacallan#define LEO_DRIVER_NAME "sunleo"
654a041c5bSmacallan#define LEO_MAJOR_VERSION PACKAGE_VERSION_MAJOR
664a041c5bSmacallan#define LEO_MINOR_VERSION PACKAGE_VERSION_MINOR
674a041c5bSmacallan#define LEO_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL
684a041c5bSmacallan
694a041c5bSmacallan/*
704a041c5bSmacallan * This contains the functions needed by the server after loading the driver
714a041c5bSmacallan * module.  It must be supplied, and gets passed back by the SetupProc
724a041c5bSmacallan * function in the dynamic case.  In the static case, a reference to this
734a041c5bSmacallan * is compiled in, and this requires that the name of this DriverRec be
744a041c5bSmacallan * an upper-case version of the driver name.
754a041c5bSmacallan */
764a041c5bSmacallan
774a041c5bSmacallan_X_EXPORT DriverRec SUNLEO = {
784a041c5bSmacallan    LEO_VERSION,
794a041c5bSmacallan    LEO_DRIVER_NAME,
804a041c5bSmacallan    LeoIdentify,
814a041c5bSmacallan    LeoProbe,
824a041c5bSmacallan    LeoAvailableOptions,
834a041c5bSmacallan    NULL,
844a041c5bSmacallan    0
854a041c5bSmacallan};
864a041c5bSmacallan
874a041c5bSmacallantypedef enum {
884a041c5bSmacallan    OPTION_SW_CURSOR,
894a041c5bSmacallan    OPTION_HW_CURSOR,
904a041c5bSmacallan    OPTION_NOACCEL
914a041c5bSmacallan} LeoOpts;
924a041c5bSmacallan
934a041c5bSmacallanstatic const OptionInfoRec LeoOptions[] = {
944a041c5bSmacallan    { OPTION_SW_CURSOR,		"SWcursor",	OPTV_BOOLEAN,	{0}, FALSE },
954a041c5bSmacallan    { OPTION_HW_CURSOR,		"HWcursor",	OPTV_BOOLEAN,	{0}, FALSE },
964a041c5bSmacallan    { OPTION_NOACCEL,		"NoAccel",	OPTV_BOOLEAN,	{0}, FALSE },
974a041c5bSmacallan    { -1,			NULL,		OPTV_NONE,	{0}, FALSE }
984a041c5bSmacallan};
994a041c5bSmacallan
1004a041c5bSmacallan#ifdef XFree86LOADER
1014a041c5bSmacallan
1024a041c5bSmacallanstatic MODULESETUPPROTO(leoSetup);
1034a041c5bSmacallan
1044a041c5bSmacallanstatic XF86ModuleVersionInfo sunleoVersRec =
1054a041c5bSmacallan{
1064a041c5bSmacallan	"sunleo",
1074a041c5bSmacallan	MODULEVENDORSTRING,
1084a041c5bSmacallan	MODINFOSTRING1,
1094a041c5bSmacallan	MODINFOSTRING2,
1104a041c5bSmacallan	XORG_VERSION_CURRENT,
1114a041c5bSmacallan	LEO_MAJOR_VERSION, LEO_MINOR_VERSION, LEO_PATCHLEVEL,
1124a041c5bSmacallan	ABI_CLASS_VIDEODRV,
1134a041c5bSmacallan	ABI_VIDEODRV_VERSION,
1144a041c5bSmacallan	MOD_CLASS_VIDEODRV,
1154a041c5bSmacallan	{0,0,0,0}
1164a041c5bSmacallan};
1174a041c5bSmacallan
1184a041c5bSmacallan_X_EXPORT XF86ModuleData sunleoModuleData = { &sunleoVersRec, leoSetup, NULL };
1194a041c5bSmacallan
1204a041c5bSmacallanpointer
1214a041c5bSmacallanleoSetup(pointer module, pointer opts, int *errmaj, int *errmin)
1224a041c5bSmacallan{
1234a041c5bSmacallan    static Bool setupDone = FALSE;
1244a041c5bSmacallan
1254a041c5bSmacallan    if (!setupDone) {
1264a041c5bSmacallan	setupDone = TRUE;
1274a041c5bSmacallan	xf86AddDriver(&SUNLEO, module, 0);
1284a041c5bSmacallan
1294a041c5bSmacallan	/*
1304a041c5bSmacallan	 * Modules that this driver always requires can be loaded here
1314a041c5bSmacallan	 * by calling LoadSubModule().
1324a041c5bSmacallan	 */
1334a041c5bSmacallan
1344a041c5bSmacallan	/*
1354a041c5bSmacallan	 * The return value must be non-NULL on success even though there
1364a041c5bSmacallan	 * is no TearDownProc.
1374a041c5bSmacallan	 */
1384a041c5bSmacallan	return (pointer)TRUE;
1394a041c5bSmacallan    } else {
1404a041c5bSmacallan	if (errmaj) *errmaj = LDR_ONCEONLY;
1414a041c5bSmacallan	return NULL;
1424a041c5bSmacallan    }
1434a041c5bSmacallan}
1444a041c5bSmacallan
1454a041c5bSmacallan#endif /* XFree86LOADER */
1464a041c5bSmacallan
1474a041c5bSmacallanstatic Bool
1484a041c5bSmacallanLeoGetRec(ScrnInfoPtr pScrn)
1494a041c5bSmacallan{
1504a041c5bSmacallan    /*
1514a041c5bSmacallan     * Allocate an LeoRec, and hook it into pScrn->driverPrivate.
1524a041c5bSmacallan     * pScrn->driverPrivate is initialised to NULL, so we can check if
1534a041c5bSmacallan     * the allocation has already been done.
1544a041c5bSmacallan     */
1554a041c5bSmacallan    if (pScrn->driverPrivate != NULL)
1564a041c5bSmacallan	return TRUE;
1574a041c5bSmacallan
1584a041c5bSmacallan    pScrn->driverPrivate = xnfcalloc(sizeof(LeoRec), 1);
1594a041c5bSmacallan    return TRUE;
1604a041c5bSmacallan}
1614a041c5bSmacallan
1624a041c5bSmacallanstatic void
1634a041c5bSmacallanLeoFreeRec(ScrnInfoPtr pScrn)
1644a041c5bSmacallan{
1654a041c5bSmacallan    LeoPtr pLeo;
1664a041c5bSmacallan
1674a041c5bSmacallan    if (pScrn->driverPrivate == NULL)
1684a041c5bSmacallan	return;
1694a041c5bSmacallan
1704a041c5bSmacallan    pLeo = GET_LEO_FROM_SCRN(pScrn);
1714a041c5bSmacallan
1727a5333bcSmrg    free(pScrn->driverPrivate);
1734a041c5bSmacallan    pScrn->driverPrivate = NULL;
1744a041c5bSmacallan
1754a041c5bSmacallan    return;
1764a041c5bSmacallan}
1774a041c5bSmacallan
1784a041c5bSmacallanstatic const OptionInfoRec *
1794a041c5bSmacallanLeoAvailableOptions(int chipid, int busid)
1804a041c5bSmacallan{
1814a041c5bSmacallan    return LeoOptions;
1824a041c5bSmacallan}
1834a041c5bSmacallan
1844a041c5bSmacallan/* Mandatory */
1854a041c5bSmacallanstatic void
1864a041c5bSmacallanLeoIdentify(int flags)
1874a041c5bSmacallan{
1884a041c5bSmacallan    xf86Msg(X_INFO, "%s: driver for Leo (ZX)\n", LEO_NAME);
1894a041c5bSmacallan}
1904a041c5bSmacallan
1914a041c5bSmacallan
1924a041c5bSmacallan/* Mandatory */
1934a041c5bSmacallanstatic Bool
1944a041c5bSmacallanLeoProbe(DriverPtr drv, int flags)
1954a041c5bSmacallan{
1964a041c5bSmacallan    int i;
1974a041c5bSmacallan    GDevPtr *devSections;
1984a041c5bSmacallan    int *usedChips;
1994a041c5bSmacallan    int numDevSections;
2004a041c5bSmacallan    int numUsed;
2014a041c5bSmacallan    Bool foundScreen = FALSE;
2024a041c5bSmacallan    EntityInfoPtr pEnt;
2034a041c5bSmacallan
2044a041c5bSmacallan    /*
2054a041c5bSmacallan     * The aim here is to find all cards that this driver can handle,
2064a041c5bSmacallan     * and for the ones not already claimed by another driver, claim the
2074a041c5bSmacallan     * slot, and allocate a ScrnInfoRec.
2084a041c5bSmacallan     *
2094a041c5bSmacallan     * This should be a minimal probe, and it should under no circumstances
2104a041c5bSmacallan     * change the state of the hardware.  Because a device is found, don't
2114a041c5bSmacallan     * assume that it will be used.  Don't do any initialisations other than
2124a041c5bSmacallan     * the required ScrnInfoRec initialisations.  Don't allocate any new
2134a041c5bSmacallan     * data structures.
2144a041c5bSmacallan     */
2154a041c5bSmacallan
2164a041c5bSmacallan    /*
2174a041c5bSmacallan     * Next we check, if there has been a chipset override in the config file.
2184a041c5bSmacallan     * For this we must find out if there is an active device section which
2194a041c5bSmacallan     * is relevant, i.e., which has no driver specified or has THIS driver
2204a041c5bSmacallan     * specified.
2214a041c5bSmacallan     */
2224a041c5bSmacallan
2234a041c5bSmacallan    if ((numDevSections = xf86MatchDevice(LEO_DRIVER_NAME,
2244a041c5bSmacallan					  &devSections)) <= 0) {
2254a041c5bSmacallan	/*
2264a041c5bSmacallan	 * There's no matching device section in the config file, so quit
2274a041c5bSmacallan	 * now.
2284a041c5bSmacallan	 */
2294a041c5bSmacallan	return FALSE;
2304a041c5bSmacallan    }
2314a041c5bSmacallan
2324a041c5bSmacallan    /*
2334a041c5bSmacallan     * We need to probe the hardware first.  We then need to see how this
2344a041c5bSmacallan     * fits in with what is given in the config file, and allow the config
2354a041c5bSmacallan     * file info to override any contradictions.
2364a041c5bSmacallan     */
2374a041c5bSmacallan
2384a041c5bSmacallan    numUsed = xf86MatchSbusInstances(LEO_NAME, SBUS_DEVICE_LEO,
2394a041c5bSmacallan		   devSections, numDevSections,
2404a041c5bSmacallan		   drv, &usedChips);
2414a041c5bSmacallan
2427a5333bcSmrg    free(devSections);
2434a041c5bSmacallan    if (numUsed <= 0)
2444a041c5bSmacallan	return FALSE;
2454a041c5bSmacallan
2464a041c5bSmacallan    if (flags & PROBE_DETECT)
2474a041c5bSmacallan	foundScreen = TRUE;
2484a041c5bSmacallan    else for (i = 0; i < numUsed; i++) {
2494a041c5bSmacallan	pEnt = xf86GetEntityInfo(usedChips[i]);
2504a041c5bSmacallan
2514a041c5bSmacallan	/*
2524a041c5bSmacallan	 * Check that nothing else has claimed the slots.
2534a041c5bSmacallan	 */
2544a041c5bSmacallan	if(pEnt->active) {
2554a041c5bSmacallan	    ScrnInfoPtr pScrn;
2564a041c5bSmacallan
2574a041c5bSmacallan	    /* Allocate a ScrnInfoRec and claim the slot */
2584a041c5bSmacallan	    pScrn = xf86AllocateScreen(drv, 0);
2594a041c5bSmacallan
2604a041c5bSmacallan	    /* Fill in what we can of the ScrnInfoRec */
2614a041c5bSmacallan	    pScrn->driverVersion = LEO_VERSION;
2624a041c5bSmacallan	    pScrn->driverName	 = LEO_DRIVER_NAME;
2634a041c5bSmacallan	    pScrn->name		 = LEO_NAME;
2644a041c5bSmacallan	    pScrn->Probe	 = LeoProbe;
2654a041c5bSmacallan	    pScrn->PreInit	 = LeoPreInit;
2664a041c5bSmacallan	    pScrn->ScreenInit	 = LeoScreenInit;
2674a041c5bSmacallan  	    pScrn->SwitchMode	 = LeoSwitchMode;
2684a041c5bSmacallan  	    pScrn->AdjustFrame	 = LeoAdjustFrame;
2694a041c5bSmacallan	    pScrn->EnterVT	 = LeoEnterVT;
2704a041c5bSmacallan	    pScrn->LeaveVT	 = LeoLeaveVT;
2714a041c5bSmacallan	    pScrn->FreeScreen	 = LeoFreeScreen;
2724a041c5bSmacallan	    pScrn->ValidMode	 = LeoValidMode;
2734a041c5bSmacallan	    xf86AddEntityToScreen(pScrn, pEnt->index);
2744a041c5bSmacallan	    foundScreen = TRUE;
2754a041c5bSmacallan	}
2767a5333bcSmrg	free(pEnt);
2774a041c5bSmacallan    }
2787a5333bcSmrg    free(usedChips);
2794a041c5bSmacallan    return foundScreen;
2804a041c5bSmacallan}
2814a041c5bSmacallan
2824a041c5bSmacallan/* Mandatory */
2834a041c5bSmacallanstatic Bool
2844a041c5bSmacallanLeoPreInit(ScrnInfoPtr pScrn, int flags)
2854a041c5bSmacallan{
2864a041c5bSmacallan    LeoPtr pLeo;
2874a041c5bSmacallan    sbusDevicePtr psdp;
2884a041c5bSmacallan    MessageType from;
2894a041c5bSmacallan    int i;
2904a041c5bSmacallan
2914a041c5bSmacallan    if (flags & PROBE_DETECT) return FALSE;
2924a041c5bSmacallan
2934a041c5bSmacallan    /*
2944a041c5bSmacallan     * Note: This function is only called once at server startup, and
2954a041c5bSmacallan     * not at the start of each server generation.  This means that
2964a041c5bSmacallan     * only things that are persistent across server generations can
2974a041c5bSmacallan     * be initialised here.  xf86Screens[] is (pScrn is a pointer to one
2984a041c5bSmacallan     * of these).  Privates allocated using xf86AllocateScrnInfoPrivateIndex()
2994a041c5bSmacallan     * are too, and should be used for data that must persist across
3004a041c5bSmacallan     * server generations.
3014a041c5bSmacallan     *
3024a041c5bSmacallan     * Per-generation data should be allocated with
3034a041c5bSmacallan     * AllocateScreenPrivateIndex() from the ScreenInit() function.
3044a041c5bSmacallan     */
3054a041c5bSmacallan
3064a041c5bSmacallan    /* Allocate the LeoRec driverPrivate */
3074a041c5bSmacallan    if (!LeoGetRec(pScrn)) {
3084a041c5bSmacallan	return FALSE;
3094a041c5bSmacallan    }
3104a041c5bSmacallan    pLeo = GET_LEO_FROM_SCRN(pScrn);
3114a041c5bSmacallan
3124a041c5bSmacallan    /* Set pScrn->monitor */
3134a041c5bSmacallan    pScrn->monitor = pScrn->confScreen->monitor;
3144a041c5bSmacallan
3154a041c5bSmacallan    /* This driver doesn't expect more than one entity per screen */
3164a041c5bSmacallan    if (pScrn->numEntities > 1)
3174a041c5bSmacallan	return FALSE;
3184a041c5bSmacallan    /* This is the general case */
3194a041c5bSmacallan    for (i = 0; i < pScrn->numEntities; i++) {
3204a041c5bSmacallan	EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[i]);
3214a041c5bSmacallan
3224a041c5bSmacallan	/* LEO is purely SBUS */
3234a041c5bSmacallan	if (pEnt->location.type == BUS_SBUS) {
3244a041c5bSmacallan	    psdp = xf86GetSbusInfoForEntity(pEnt->index);
3254a041c5bSmacallan	    pLeo->psdp = psdp;
3264a041c5bSmacallan	} else
3274a041c5bSmacallan	    return FALSE;
3284a041c5bSmacallan    }
3294a041c5bSmacallan
3304a041c5bSmacallan    /*********************
3314a041c5bSmacallan    deal with depth
3324a041c5bSmacallan    *********************/
3334a041c5bSmacallan
3344a041c5bSmacallan    if (!xf86SetDepthBpp(pScrn, 32, 0, 32, Support32bppFb)) {
3354a041c5bSmacallan	return FALSE;
3364a041c5bSmacallan    } else {
3374a041c5bSmacallan	/* Check that the returned depth is one we support */
3384a041c5bSmacallan	switch (pScrn->depth) {
3394a041c5bSmacallan	case 32:
340832e5c3bSmacallan	case 24:
3414a041c5bSmacallan	    /* OK */
3424a041c5bSmacallan	    break;
3434a041c5bSmacallan	default:
3444a041c5bSmacallan	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3454a041c5bSmacallan		       "Given depth (%d) is not supported by this driver\n",
3464a041c5bSmacallan		       pScrn->depth);
3474a041c5bSmacallan	    return FALSE;
3484a041c5bSmacallan	}
3494a041c5bSmacallan    }
3504a041c5bSmacallan
3514a041c5bSmacallan    /* Collect all of the relevant option flags (fill in pScrn->options) */
3524a041c5bSmacallan    xf86CollectOptions(pScrn, NULL);
3534a041c5bSmacallan    /* Process the options */
3547a5333bcSmrg    if (!(pLeo->Options = malloc(sizeof(LeoOptions))))
3554a041c5bSmacallan	return FALSE;
3564a041c5bSmacallan    memcpy(pLeo->Options, LeoOptions, sizeof(LeoOptions));
3574a041c5bSmacallan    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pLeo->Options);
3584a041c5bSmacallan
3594a041c5bSmacallan    /*
3604a041c5bSmacallan     * This must happen after pScrn->display has been set because
3614a041c5bSmacallan     * xf86SetWeight references it.
3624a041c5bSmacallan     */
3634a041c5bSmacallan    if (pScrn->depth > 8) {
364832e5c3bSmacallan	rgb weight = {0, 0, 0};
3654a041c5bSmacallan	rgb mask = {0xff, 0xff00, 0xff0000};
3664a041c5bSmacallan
3674a041c5bSmacallan	if (!xf86SetWeight(pScrn, weight, mask)) {
3684a041c5bSmacallan	    return FALSE;
3694a041c5bSmacallan	}
3704a041c5bSmacallan    }
3714a041c5bSmacallan
3724a041c5bSmacallan    if (!xf86SetDefaultVisual(pScrn, -1)) {
3734a041c5bSmacallan	return FALSE;
3744a041c5bSmacallan    } else {
3754a041c5bSmacallan	/* We don't currently support DirectColor */
3764a041c5bSmacallan	if (pScrn->defaultVisual != TrueColor) {
3774a041c5bSmacallan	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
3784a041c5bSmacallan		       " (%s) is not supported\n",
3794a041c5bSmacallan		       xf86GetVisualName(pScrn->defaultVisual));
3804a041c5bSmacallan	    return FALSE;
3814a041c5bSmacallan	}
3824a041c5bSmacallan    }
3834a041c5bSmacallan
3844a041c5bSmacallan    /*
3854a041c5bSmacallan     * The new cmap code requires this to be initialised.
3864a041c5bSmacallan     */
3874a041c5bSmacallan
3884a041c5bSmacallan    {
3894a041c5bSmacallan	Gamma zeros = {0.0, 0.0, 0.0};
3904a041c5bSmacallan
3914a041c5bSmacallan	if (!xf86SetGamma(pScrn, zeros)) {
3924a041c5bSmacallan	    return FALSE;
3934a041c5bSmacallan	}
3944a041c5bSmacallan    }
3954a041c5bSmacallan
3964a041c5bSmacallan    /* Set the bits per RGB for 8bpp mode */
3974a041c5bSmacallan    from = X_DEFAULT;
3984a041c5bSmacallan
3994a041c5bSmacallan    /* determine whether we use hardware or software cursor */
4004a041c5bSmacallan
4014a041c5bSmacallan    pLeo->HWCursor = TRUE;
4024a041c5bSmacallan    if (xf86GetOptValBool(pLeo->Options, OPTION_HW_CURSOR, &pLeo->HWCursor))
4034a041c5bSmacallan	from = X_CONFIG;
4044a041c5bSmacallan    if (xf86ReturnOptValBool(pLeo->Options, OPTION_SW_CURSOR, FALSE)) {
4054a041c5bSmacallan	from = X_CONFIG;
4064a041c5bSmacallan	pLeo->HWCursor = FALSE;
4074a041c5bSmacallan    }
4084a041c5bSmacallan
4094a041c5bSmacallan    xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
4104a041c5bSmacallan		pLeo->HWCursor ? "HW" : "SW");
4114a041c5bSmacallan
4124a041c5bSmacallan    if (xf86ReturnOptValBool(pLeo->Options, OPTION_NOACCEL, FALSE)) {
4134a041c5bSmacallan	pLeo->NoAccel = TRUE;
4144a041c5bSmacallan	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
4154a041c5bSmacallan    }
4164a041c5bSmacallan
4174a041c5bSmacallan    if (xf86LoadSubModule(pScrn, "fb") == NULL) {
4184a041c5bSmacallan	LeoFreeRec(pScrn);
4194a041c5bSmacallan	return FALSE;
4204a041c5bSmacallan    }
4214a041c5bSmacallan
4224a041c5bSmacallan    if (pLeo->HWCursor && xf86LoadSubModule(pScrn, "ramdac") == NULL) {
4234a041c5bSmacallan	LeoFreeRec(pScrn);
4244a041c5bSmacallan	return FALSE;
4254a041c5bSmacallan    }
4264a041c5bSmacallan
4274a041c5bSmacallan    /*********************
4284a041c5bSmacallan    set up clock and mode stuff
4294a041c5bSmacallan    *********************/
4304a041c5bSmacallan
4314a041c5bSmacallan    pScrn->progClock = TRUE;
4324a041c5bSmacallan
4334a041c5bSmacallan    if(pScrn->display->virtualX || pScrn->display->virtualY) {
4344a041c5bSmacallan	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
4354a041c5bSmacallan		   "Leo does not support a virtual desktop\n");
4364a041c5bSmacallan	pScrn->display->virtualX = 0;
4374a041c5bSmacallan	pScrn->display->virtualY = 0;
4384a041c5bSmacallan    }
4394a041c5bSmacallan
4404a041c5bSmacallan    xf86SbusUseBuiltinMode(pScrn, pLeo->psdp);
4414a041c5bSmacallan    pScrn->currentMode = pScrn->modes;
4424a041c5bSmacallan    pScrn->displayWidth = pScrn->virtualX;
4434a041c5bSmacallan
4444a041c5bSmacallan    /* Set display resolution */
4454a041c5bSmacallan    xf86SetDpi(pScrn, 0, 0);
4464a041c5bSmacallan
4474a041c5bSmacallan    return TRUE;
4484a041c5bSmacallan}
4494a041c5bSmacallan
4504a041c5bSmacallan/* Mandatory */
4514a041c5bSmacallan
4524a041c5bSmacallan/* This gets called at the start of each server generation */
4534a041c5bSmacallan
4544a041c5bSmacallanstatic Bool
4557a5333bcSmrgLeoScreenInit(SCREEN_INIT_ARGS_DECL)
4564a041c5bSmacallan{
4574a041c5bSmacallan    ScrnInfoPtr pScrn;
4584a041c5bSmacallan    LeoPtr pLeo;
4594a041c5bSmacallan    int ret;
4604a041c5bSmacallan    VisualPtr visual;
4614a041c5bSmacallan    extern Bool LeoAccelInit(ScreenPtr pScreen, LeoPtr pLeo);
4624a041c5bSmacallan
4634a041c5bSmacallan    /*
4644a041c5bSmacallan     * First get the ScrnInfoRec
4654a041c5bSmacallan     */
4667a5333bcSmrg    pScrn = xf86ScreenToScrn(pScreen);
4674a041c5bSmacallan
4684a041c5bSmacallan    pLeo = GET_LEO_FROM_SCRN(pScrn);
4694a041c5bSmacallan
4704a041c5bSmacallan    /* Map the Leo memory */
4714a041c5bSmacallan    pLeo->fb =
4724a041c5bSmacallan	xf86MapSbusMem (pLeo->psdp, LEO_FB0_VOFF, 0x803000);
4734a041c5bSmacallan
4744a041c5bSmacallan    if (! pLeo->fb)
4754a041c5bSmacallan	return FALSE;
4764a041c5bSmacallan
4774a041c5bSmacallan    /* Darken the screen for aesthetic reasons and set the viewport */
4784a041c5bSmacallan    LeoSaveScreen(pScreen, SCREEN_SAVER_ON);
4794a041c5bSmacallan
4804a041c5bSmacallan    /*
4814a041c5bSmacallan     * The next step is to setup the screen's visuals, and initialise the
4824a041c5bSmacallan     * framebuffer code.  In cases where the framebuffer's default
4834a041c5bSmacallan     * choices for things like visual layouts and bits per RGB are OK,
4844a041c5bSmacallan     * this may be as simple as calling the framebuffer's ScreenInit()
4854a041c5bSmacallan     * function.  If not, the visuals will need to be setup before calling
4864a041c5bSmacallan     * a fb ScreenInit() function and fixed up after.
4874a041c5bSmacallan     */
4884a041c5bSmacallan
4894a041c5bSmacallan    /*
4904a041c5bSmacallan     * Reset visual list.
4914a041c5bSmacallan     */
4924a041c5bSmacallan    miClearVisualTypes();
4934a041c5bSmacallan
4944a041c5bSmacallan    /* Setup the visuals we support. */
4954a041c5bSmacallan
4964a041c5bSmacallan    if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits,
4974a041c5bSmacallan			  pScrn->defaultVisual))
4984a041c5bSmacallan	return FALSE;
4994a041c5bSmacallan
5004a041c5bSmacallan    /*
5014a041c5bSmacallan     * Call the framebuffer layer's ScreenInit function, and fill in other
5024a041c5bSmacallan     * pScreen fields.
5034a041c5bSmacallan     */
5044a041c5bSmacallan
5054a041c5bSmacallan    ret = fbScreenInit(pScreen, pLeo->fb, pScrn->virtualX,
5064a041c5bSmacallan		       pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
5074a041c5bSmacallan		       2048, pScrn->bitsPerPixel);
5084a041c5bSmacallan    if (!ret)
5094a041c5bSmacallan	return FALSE;
5104a041c5bSmacallan
5114a041c5bSmacallan    xf86SetBackingStore(pScreen);
5124a041c5bSmacallan    xf86SetSilkenMouse(pScreen);
5134a041c5bSmacallan
5144a041c5bSmacallan    xf86SetBlackWhitePixels(pScreen);
5154a041c5bSmacallan
5164a041c5bSmacallan    if (pScrn->bitsPerPixel > 8) {
5174a041c5bSmacallan        /* Fixup RGB ordering */
5184a041c5bSmacallan        visual = pScreen->visuals + pScreen->numVisuals;
5194a041c5bSmacallan        while (--visual >= pScreen->visuals) {
5204a041c5bSmacallan	    if ((visual->class | DynamicClass) == DirectColor) {
5214a041c5bSmacallan		visual->offsetRed = pScrn->offset.red;
5224a041c5bSmacallan		visual->offsetGreen = pScrn->offset.green;
5234a041c5bSmacallan		visual->offsetBlue = pScrn->offset.blue;
5244a041c5bSmacallan		visual->redMask = pScrn->mask.red;
5254a041c5bSmacallan		visual->greenMask = pScrn->mask.green;
5264a041c5bSmacallan		visual->blueMask = pScrn->mask.blue;
5274a041c5bSmacallan	    }
5284a041c5bSmacallan	}
5294a041c5bSmacallan    }
5304a041c5bSmacallan
5314a041c5bSmacallan    if (!LeoAccelInit(pScreen, pLeo))
5324a041c5bSmacallan	return FALSE;
5334a041c5bSmacallan
5344a041c5bSmacallan    if (!pLeo->NoAccel)
5354a041c5bSmacallan	xf86Msg(X_INFO, "%s: Using acceleration\n", pLeo->psdp->device);
5364a041c5bSmacallan
5374a041c5bSmacallan    /* Initialise cursor functions */
5384a041c5bSmacallan    miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
5394a041c5bSmacallan
5404a041c5bSmacallan    /* Initialize HW cursor layer.
5414a041c5bSmacallan       Must follow software cursor initialization*/
5424a041c5bSmacallan    if (pLeo->HWCursor) {
5434a041c5bSmacallan	extern Bool LeoHWCursorInit(ScreenPtr pScreen);
5444a041c5bSmacallan
5454a041c5bSmacallan	if(!LeoHWCursorInit(pScreen)) {
5464a041c5bSmacallan	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
5474a041c5bSmacallan		       "Hardware cursor initialization failed\n");
5484a041c5bSmacallan	    return(FALSE);
5494a041c5bSmacallan	}
5504a041c5bSmacallan	xf86SbusHideOsHwCursor(pLeo->psdp);
5514a041c5bSmacallan    }
5524a041c5bSmacallan
5534a041c5bSmacallan    /* Initialise default colourmap */
5544a041c5bSmacallan    if (!miCreateDefColormap(pScreen))
5554a041c5bSmacallan	return FALSE;
5564a041c5bSmacallan
5574a041c5bSmacallan    pLeo->CloseScreen = pScreen->CloseScreen;
5584a041c5bSmacallan    pScreen->CloseScreen = LeoCloseScreen;
5594a041c5bSmacallan    pScreen->SaveScreen = LeoSaveScreen;
5604a041c5bSmacallan
5614a041c5bSmacallan    /* Report any unused options (only for the first generation) */
5624a041c5bSmacallan    if (serverGeneration == 1) {
5634a041c5bSmacallan	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
5644a041c5bSmacallan    }
5654a041c5bSmacallan
5664a041c5bSmacallan    /* unblank the screen */
5674a041c5bSmacallan    LeoSaveScreen(pScreen, SCREEN_SAVER_OFF);
5684a041c5bSmacallan
5694a041c5bSmacallan    /* Done */
5704a041c5bSmacallan    return TRUE;
5714a041c5bSmacallan}
5724a041c5bSmacallan
5734a041c5bSmacallan
5744a041c5bSmacallan/* Usually mandatory */
5754a041c5bSmacallanstatic Bool
5767a5333bcSmrgLeoSwitchMode(SWITCH_MODE_ARGS_DECL)
5774a041c5bSmacallan{
5784a041c5bSmacallan    return TRUE;
5794a041c5bSmacallan}
5804a041c5bSmacallan
5814a041c5bSmacallan
5824a041c5bSmacallan/*
5834a041c5bSmacallan * This function is used to initialize the Start Address - the first
5844a041c5bSmacallan * displayed location in the video memory.
5854a041c5bSmacallan */
5864a041c5bSmacallan/* Usually mandatory */
5874a041c5bSmacallanstatic void
5887a5333bcSmrgLeoAdjustFrame(ADJUST_FRAME_ARGS_DECL)
5894a041c5bSmacallan{
5904a041c5bSmacallan    /* we don't support virtual desktops */
5914a041c5bSmacallan    return;
5924a041c5bSmacallan}
5934a041c5bSmacallan
5944a041c5bSmacallanextern void LeoVtChange (ScreenPtr pScreen, int enter);
5954a041c5bSmacallan
5964a041c5bSmacallan/*
5974a041c5bSmacallan * This is called when VT switching back to the X server.  Its job is
5984a041c5bSmacallan * to reinitialise the video mode.
5994a041c5bSmacallan */
6004a041c5bSmacallan
6014a041c5bSmacallan/* Mandatory */
6024a041c5bSmacallanstatic Bool
6037a5333bcSmrgLeoEnterVT(VT_FUNC_ARGS_DECL)
6044a041c5bSmacallan{
6057a5333bcSmrg    SCRN_INFO_PTR(arg);
6064a041c5bSmacallan    LeoPtr pLeo = GET_LEO_FROM_SCRN(pScrn);
6074a041c5bSmacallan
6084a041c5bSmacallan    pLeo->vtSema = FALSE;
6094a041c5bSmacallan    LeoVtChange (pScrn->pScreen, TRUE);
6104a041c5bSmacallan    if (pLeo->HWCursor)
6114a041c5bSmacallan	xf86SbusHideOsHwCursor (pLeo->psdp);
6124a041c5bSmacallan    return TRUE;
6134a041c5bSmacallan}
6144a041c5bSmacallan
6154a041c5bSmacallan
6164a041c5bSmacallan/*
6174a041c5bSmacallan * This is called when VT switching away from the X server.
6184a041c5bSmacallan */
6194a041c5bSmacallan
6204a041c5bSmacallan/* Mandatory */
6214a041c5bSmacallanstatic void
6227a5333bcSmrgLeoLeaveVT(VT_FUNC_ARGS_DECL)
6234a041c5bSmacallan{
6247a5333bcSmrg    SCRN_INFO_PTR(arg);
6254a041c5bSmacallan    LeoPtr pLeo = GET_LEO_FROM_SCRN(pScrn);
6264a041c5bSmacallan
6274a041c5bSmacallan    LeoVtChange (pScrn->pScreen, FALSE);
6284a041c5bSmacallan    pLeo->vtSema = TRUE;
6294a041c5bSmacallan}
6304a041c5bSmacallan
6314a041c5bSmacallan
6324a041c5bSmacallan/*
6334a041c5bSmacallan * This is called at the end of each server generation.  It restores the
6344a041c5bSmacallan * original (text) mode.  It should really also unmap the video memory too.
6354a041c5bSmacallan */
6364a041c5bSmacallan
6374a041c5bSmacallan/* Mandatory */
6384a041c5bSmacallanstatic Bool
6397a5333bcSmrgLeoCloseScreen(CLOSE_SCREEN_ARGS_DECL)
6404a041c5bSmacallan{
6417a5333bcSmrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
6424a041c5bSmacallan    LeoPtr pLeo = GET_LEO_FROM_SCRN(pScrn);
6434a041c5bSmacallan
6444a041c5bSmacallan    pScrn->vtSema = FALSE;
6454a041c5bSmacallan    xf86UnmapSbusMem(pLeo->psdp, pLeo->fb, 0x803000);
6464a041c5bSmacallan
6474a041c5bSmacallan    if (pLeo->HWCursor)
6484a041c5bSmacallan	xf86SbusHideOsHwCursor (pLeo->psdp);
6494a041c5bSmacallan
6504a041c5bSmacallan    pScreen->CloseScreen = pLeo->CloseScreen;
6517a5333bcSmrg    return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
6524a041c5bSmacallan    return FALSE;
6534a041c5bSmacallan}
6544a041c5bSmacallan
6554a041c5bSmacallan
6564a041c5bSmacallan/* Free up any per-generation data structures */
6574a041c5bSmacallan
6584a041c5bSmacallan/* Optional */
6594a041c5bSmacallanstatic void
6607a5333bcSmrgLeoFreeScreen(FREE_SCREEN_ARGS_DECL)
6614a041c5bSmacallan{
6620724dadfSmrg    SCRN_INFO_PTR(arg);
6637a5333bcSmrg    LeoFreeRec(pScrn);
6644a041c5bSmacallan}
6654a041c5bSmacallan
6664a041c5bSmacallan
6674a041c5bSmacallan/* Checks if a mode is suitable for the selected chipset. */
6684a041c5bSmacallan
6694a041c5bSmacallan/* Optional */
6704a041c5bSmacallanstatic ModeStatus
6717a5333bcSmrgLeoValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags)
6724a041c5bSmacallan{
6734a041c5bSmacallan    if (mode->Flags & V_INTERLACE)
6744a041c5bSmacallan	return(MODE_BAD);
6754a041c5bSmacallan
6764a041c5bSmacallan    return(MODE_OK);
6774a041c5bSmacallan}
6784a041c5bSmacallan
6794a041c5bSmacallan/* Do screen blanking */
6804a041c5bSmacallan
6814a041c5bSmacallan/* Mandatory */
6824a041c5bSmacallanstatic Bool
6834a041c5bSmacallanLeoSaveScreen(ScreenPtr pScreen, int mode)
6844a041c5bSmacallan    /* this function should blank the screen when unblank is FALSE and
6854a041c5bSmacallan       unblank it when unblank is TRUE -- it doesn't actually seem to be
6864a041c5bSmacallan       used for much though */
6874a041c5bSmacallan{
6884a041c5bSmacallan    return TRUE;
6894a041c5bSmacallan}
6904a041c5bSmacallan
6914a041c5bSmacallan/*
6924a041c5bSmacallan * This is the implementation of the Sync() function.
6934a041c5bSmacallan */
6944a041c5bSmacallanvoid
6954a041c5bSmacallanLeoSync(ScrnInfoPtr pScrn)
6964a041c5bSmacallan{
6974a041c5bSmacallan    return;
6984a041c5bSmacallan}
699