1e4da13eeSmacallan/*
2e4da13eeSmacallan * TCX framebuffer driver.
3e4da13eeSmacallan *
4e4da13eeSmacallan * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com)
5e4da13eeSmacallan *
6e4da13eeSmacallan * Permission is hereby granted, free of charge, to any person obtaining a copy
7e4da13eeSmacallan * of this software and associated documentation files (the "Software"), to deal
8e4da13eeSmacallan * in the Software without restriction, including without limitation the rights
9e4da13eeSmacallan * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10e4da13eeSmacallan * copies of the Software, and to permit persons to whom the Software is
11e4da13eeSmacallan * furnished to do so, subject to the following conditions:
12e4da13eeSmacallan *
13e4da13eeSmacallan * The above copyright notice and this permission notice shall be included in
14e4da13eeSmacallan * all copies or substantial portions of the Software.
15e4da13eeSmacallan *
16e4da13eeSmacallan * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17e4da13eeSmacallan * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18e4da13eeSmacallan * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19e4da13eeSmacallan * JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20e4da13eeSmacallan * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21e4da13eeSmacallan * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22e4da13eeSmacallan */
23e4da13eeSmacallan
24e4da13eeSmacallan#ifdef HAVE_CONFIG_H
25e4da13eeSmacallan#include "config.h"
26e4da13eeSmacallan#endif
27e4da13eeSmacallan
28ecc0bcc7Smacallan#include <fcntl.h>
29ecc0bcc7Smacallan#include <sys/types.h>
30ecc0bcc7Smacallan#include <sys/time.h>
31e4da13eeSmacallan#include <string.h>
3263884c0aSmacallan#include <sys/ioctl.h>
33ecc0bcc7Smacallan#include <dev/sun/fbio.h>
34ecc0bcc7Smacallan#include <dev/wscons/wsconsio.h>
35e4da13eeSmacallan
36e4da13eeSmacallan#include "xf86.h"
37e4da13eeSmacallan#include "xf86_OSproc.h"
38e4da13eeSmacallan#include "mipointer.h"
39e4da13eeSmacallan#include "micmap.h"
40e4da13eeSmacallan
41e4da13eeSmacallan#include "fb.h"
42e4da13eeSmacallan#include "xf86cmap.h"
43e4da13eeSmacallan#include "tcx.h"
44e4da13eeSmacallan
45e4da13eeSmacallanstatic const OptionInfoRec * TCXAvailableOptions(int chipid, int busid);
46e4da13eeSmacallanstatic void	TCXIdentify(int flags);
47e4da13eeSmacallanstatic Bool	TCXProbe(DriverPtr drv, int flags);
48e4da13eeSmacallanstatic Bool	TCXPreInit(ScrnInfoPtr pScrn, int flags);
497a5333bcSmrgstatic Bool	TCXScreenInit(SCREEN_INIT_ARGS_DECL);
507a5333bcSmrgstatic Bool	TCXEnterVT(VT_FUNC_ARGS_DECL);
517a5333bcSmrgstatic void	TCXLeaveVT(VT_FUNC_ARGS_DECL);
527a5333bcSmrgstatic Bool	TCXCloseScreen(CLOSE_SCREEN_ARGS_DECL);
53e4da13eeSmacallanstatic Bool	TCXSaveScreen(ScreenPtr pScreen, int mode);
54e4da13eeSmacallanstatic void	TCXInitCplane24(ScrnInfoPtr pScrn);
55e4da13eeSmacallan
56e4da13eeSmacallan/* Required if the driver supports mode switching */
577a5333bcSmrgstatic Bool	TCXSwitchMode(SWITCH_MODE_ARGS_DECL);
58e4da13eeSmacallan/* Required if the driver supports moving the viewport */
597a5333bcSmrgstatic void	TCXAdjustFrame(ADJUST_FRAME_ARGS_DECL);
60e4da13eeSmacallan
61e4da13eeSmacallan/* Optional functions */
627a5333bcSmrgstatic void	TCXFreeScreen(FREE_SCREEN_ARGS_DECL);
637a5333bcSmrgstatic ModeStatus TCXValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode,
64e4da13eeSmacallan			       Bool verbose, int flags);
65e4da13eeSmacallan
66e4da13eeSmacallanvoid TCXSync(ScrnInfoPtr pScrn);
67e4da13eeSmacallan
68d62aaaf2Smacallanstatic Bool TCXDriverFunc(ScrnInfoPtr, xorgDriverFuncOp, pointer);
69d62aaaf2Smacallan
70d62aaaf2Smacallan
71e4da13eeSmacallan#define TCX_VERSION 4000
72e4da13eeSmacallan#define TCX_NAME "SUNTCX"
73e4da13eeSmacallan#define TCX_DRIVER_NAME "suntcx"
74e4da13eeSmacallan#define TCX_MAJOR_VERSION PACKAGE_VERSION_MAJOR
75e4da13eeSmacallan#define TCX_MINOR_VERSION PACKAGE_VERSION_MINOR
76e4da13eeSmacallan#define TCX_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL
77e4da13eeSmacallan
78e4da13eeSmacallan/*
79e4da13eeSmacallan * This contains the functions needed by the server after loading the driver
80e4da13eeSmacallan * module.  It must be supplied, and gets passed back by the SetupProc
81e4da13eeSmacallan * function in the dynamic case.  In the static case, a reference to this
82e4da13eeSmacallan * is compiled in, and this requires that the name of this DriverRec be
83e4da13eeSmacallan * an upper-case version of the driver name.
84e4da13eeSmacallan */
85e4da13eeSmacallan
86e4da13eeSmacallan_X_EXPORT DriverRec SUNTCX = {
87e4da13eeSmacallan    TCX_VERSION,
88e4da13eeSmacallan    TCX_DRIVER_NAME,
89e4da13eeSmacallan    TCXIdentify,
90e4da13eeSmacallan    TCXProbe,
91e4da13eeSmacallan    TCXAvailableOptions,
92e4da13eeSmacallan    NULL,
93d62aaaf2Smacallan    0,
94d62aaaf2Smacallan    TCXDriverFunc
95e4da13eeSmacallan};
96e4da13eeSmacallan
97e4da13eeSmacallantypedef enum {
98e4da13eeSmacallan    OPTION_SW_CURSOR,
99ecc0bcc7Smacallan    OPTION_HW_CURSOR,
100ecc0bcc7Smacallan    OPTION_NOACCEL
101e4da13eeSmacallan} TCXOpts;
102e4da13eeSmacallan
103e4da13eeSmacallanstatic const OptionInfoRec TCXOptions[] = {
104e4da13eeSmacallan    { OPTION_SW_CURSOR,		"SWcursor",	OPTV_BOOLEAN,	{0}, FALSE },
105ecc0bcc7Smacallan    { OPTION_HW_CURSOR,		"HWcursor",	OPTV_BOOLEAN,	{0}, TRUE  },
106ecc0bcc7Smacallan    { OPTION_NOACCEL,		"NoAccel",	OPTV_BOOLEAN,	{0}, FALSE },
107e4da13eeSmacallan    { -1,			NULL,		OPTV_NONE,	{0}, FALSE }
108e4da13eeSmacallan};
109e4da13eeSmacallan
110e4da13eeSmacallanstatic MODULESETUPPROTO(tcxSetup);
111e4da13eeSmacallan
112e4da13eeSmacallanstatic XF86ModuleVersionInfo suntcxVersRec =
113e4da13eeSmacallan{
114e4da13eeSmacallan	"suntcx",
115e4da13eeSmacallan	MODULEVENDORSTRING,
116e4da13eeSmacallan	MODINFOSTRING1,
117e4da13eeSmacallan	MODINFOSTRING2,
118e4da13eeSmacallan	XORG_VERSION_CURRENT,
119e4da13eeSmacallan	TCX_MAJOR_VERSION, TCX_MINOR_VERSION, TCX_PATCHLEVEL,
120e4da13eeSmacallan	ABI_CLASS_VIDEODRV,
121e4da13eeSmacallan	ABI_VIDEODRV_VERSION,
122e4da13eeSmacallan	MOD_CLASS_VIDEODRV,
123e4da13eeSmacallan	{0,0,0,0}
124e4da13eeSmacallan};
125e4da13eeSmacallan
126e4da13eeSmacallan_X_EXPORT XF86ModuleData suntcxModuleData = { &suntcxVersRec, tcxSetup, NULL };
127e4da13eeSmacallan
128e4da13eeSmacallanpointer
129e4da13eeSmacallantcxSetup(pointer module, pointer opts, int *errmaj, int *errmin)
130e4da13eeSmacallan{
131e4da13eeSmacallan    static Bool setupDone = FALSE;
132e4da13eeSmacallan
133e4da13eeSmacallan    if (!setupDone) {
134e4da13eeSmacallan	setupDone = TRUE;
135d62aaaf2Smacallan	xf86AddDriver(&SUNTCX, module, HaveDriverFuncs);
136e4da13eeSmacallan
137e4da13eeSmacallan	/*
138e4da13eeSmacallan	 * Modules that this driver always requires can be loaded here
139e4da13eeSmacallan	 * by calling LoadSubModule().
140e4da13eeSmacallan	 */
141e4da13eeSmacallan
142e4da13eeSmacallan	/*
143e4da13eeSmacallan	 * The return value must be non-NULL on success even though there
144e4da13eeSmacallan	 * is no TearDownProc.
145e4da13eeSmacallan	 */
146e4da13eeSmacallan	return (pointer)TRUE;
147e4da13eeSmacallan    } else {
148e4da13eeSmacallan	if (errmaj) *errmaj = LDR_ONCEONLY;
149e4da13eeSmacallan	return NULL;
150e4da13eeSmacallan    }
151e4da13eeSmacallan}
152e4da13eeSmacallan
153e4da13eeSmacallanstatic Bool
154e4da13eeSmacallanTCXGetRec(ScrnInfoPtr pScrn)
155e4da13eeSmacallan{
156e4da13eeSmacallan    /*
157e4da13eeSmacallan     * Allocate an TcxRec, and hook it into pScrn->driverPrivate.
158e4da13eeSmacallan     * pScrn->driverPrivate is initialised to NULL, so we can check if
159e4da13eeSmacallan     * the allocation has already been done.
160e4da13eeSmacallan     */
161e4da13eeSmacallan    if (pScrn->driverPrivate != NULL)
162e4da13eeSmacallan	return TRUE;
163e4da13eeSmacallan
164e4da13eeSmacallan    pScrn->driverPrivate = xnfcalloc(sizeof(TcxRec), 1);
165e4da13eeSmacallan    return TRUE;
166e4da13eeSmacallan}
167e4da13eeSmacallan
168e4da13eeSmacallanstatic void
169e4da13eeSmacallanTCXFreeRec(ScrnInfoPtr pScrn)
170e4da13eeSmacallan{
171e4da13eeSmacallan    TcxPtr pTcx;
172e4da13eeSmacallan
173e4da13eeSmacallan    if (pScrn->driverPrivate == NULL)
174e4da13eeSmacallan	return;
175e4da13eeSmacallan
176e4da13eeSmacallan    pTcx = GET_TCX_FROM_SCRN(pScrn);
177e4da13eeSmacallan
1787a5333bcSmrg    free(pScrn->driverPrivate);
179e4da13eeSmacallan    pScrn->driverPrivate = NULL;
180e4da13eeSmacallan
181e4da13eeSmacallan    return;
182e4da13eeSmacallan}
183e4da13eeSmacallan
184e4da13eeSmacallanstatic const OptionInfoRec *
185e4da13eeSmacallanTCXAvailableOptions(int chipid, int busid)
186e4da13eeSmacallan{
187e4da13eeSmacallan    return TCXOptions;
188e4da13eeSmacallan}
189e4da13eeSmacallan
190e4da13eeSmacallan/* Mandatory */
191e4da13eeSmacallanstatic void
192e4da13eeSmacallanTCXIdentify(int flags)
193e4da13eeSmacallan{
194e4da13eeSmacallan    xf86Msg(X_INFO, "%s: driver for TCX\n", TCX_NAME);
195e4da13eeSmacallan}
196e4da13eeSmacallan
197e4da13eeSmacallan
198e4da13eeSmacallan/* Mandatory */
199e4da13eeSmacallanstatic Bool
200e4da13eeSmacallanTCXProbe(DriverPtr drv, int flags)
201e4da13eeSmacallan{
202e4da13eeSmacallan    int i;
203e4da13eeSmacallan    GDevPtr *devSections;
204e4da13eeSmacallan    int *usedChips;
205e4da13eeSmacallan    int numDevSections;
206e4da13eeSmacallan    int numUsed;
207e4da13eeSmacallan    Bool foundScreen = FALSE;
208e4da13eeSmacallan    EntityInfoPtr pEnt;
209e4da13eeSmacallan
210e4da13eeSmacallan    /*
211e4da13eeSmacallan     * The aim here is to find all cards that this driver can handle,
212e4da13eeSmacallan     * and for the ones not already claimed by another driver, claim the
213e4da13eeSmacallan     * slot, and allocate a ScrnInfoRec.
214e4da13eeSmacallan     *
215e4da13eeSmacallan     * This should be a minimal probe, and it should under no circumstances
216e4da13eeSmacallan     * change the state of the hardware.  Because a device is found, don't
217e4da13eeSmacallan     * assume that it will be used.  Don't do any initialisations other than
218e4da13eeSmacallan     * the required ScrnInfoRec initialisations.  Don't allocate any new
219e4da13eeSmacallan     * data structures.
220e4da13eeSmacallan     */
221e4da13eeSmacallan
222e4da13eeSmacallan    /*
223e4da13eeSmacallan     * Next we check, if there has been a chipset override in the config file.
224e4da13eeSmacallan     * For this we must find out if there is an active device section which
225e4da13eeSmacallan     * is relevant, i.e., which has no driver specified or has THIS driver
226e4da13eeSmacallan     * specified.
227e4da13eeSmacallan     */
228e4da13eeSmacallan
229e4da13eeSmacallan    if ((numDevSections = xf86MatchDevice(TCX_DRIVER_NAME,
230e4da13eeSmacallan					  &devSections)) <= 0) {
231e4da13eeSmacallan	/*
232e4da13eeSmacallan	 * There's no matching device section in the config file, so quit
233e4da13eeSmacallan	 * now.
234e4da13eeSmacallan	 */
235e4da13eeSmacallan	return FALSE;
236e4da13eeSmacallan    }
237e4da13eeSmacallan
238e4da13eeSmacallan    /*
239e4da13eeSmacallan     * We need to probe the hardware first.  We then need to see how this
240e4da13eeSmacallan     * fits in with what is given in the config file, and allow the config
241e4da13eeSmacallan     * file info to override any contradictions.
242e4da13eeSmacallan     */
243e4da13eeSmacallan
244e4da13eeSmacallan    numUsed = xf86MatchSbusInstances(TCX_NAME, SBUS_DEVICE_TCX,
245e4da13eeSmacallan		   devSections, numDevSections,
246e4da13eeSmacallan		   drv, &usedChips);
247e4da13eeSmacallan
2487a5333bcSmrg    free(devSections);
249e4da13eeSmacallan    if (numUsed <= 0)
250e4da13eeSmacallan	return FALSE;
251e4da13eeSmacallan
252e4da13eeSmacallan    if (flags & PROBE_DETECT)
253e4da13eeSmacallan	foundScreen = TRUE;
254e4da13eeSmacallan    else for (i = 0; i < numUsed; i++) {
255e4da13eeSmacallan	pEnt = xf86GetEntityInfo(usedChips[i]);
256e4da13eeSmacallan
257e4da13eeSmacallan	/*
258e4da13eeSmacallan	 * Check that nothing else has claimed the slots.
259e4da13eeSmacallan	 */
260e4da13eeSmacallan	if(pEnt->active) {
261e4da13eeSmacallan	    ScrnInfoPtr pScrn;
262e4da13eeSmacallan
263e4da13eeSmacallan	    /* Allocate a ScrnInfoRec and claim the slot */
264e4da13eeSmacallan	    pScrn = xf86AllocateScreen(drv, 0);
265e4da13eeSmacallan
266e4da13eeSmacallan	    /* Fill in what we can of the ScrnInfoRec */
267e4da13eeSmacallan	    pScrn->driverVersion = TCX_VERSION;
268e4da13eeSmacallan	    pScrn->driverName	 = TCX_DRIVER_NAME;
269e4da13eeSmacallan	    pScrn->name		 = TCX_NAME;
270e4da13eeSmacallan	    pScrn->Probe	 = TCXProbe;
271e4da13eeSmacallan	    pScrn->PreInit	 = TCXPreInit;
272e4da13eeSmacallan	    pScrn->ScreenInit	 = TCXScreenInit;
273e4da13eeSmacallan  	    pScrn->SwitchMode	 = TCXSwitchMode;
274e4da13eeSmacallan  	    pScrn->AdjustFrame	 = TCXAdjustFrame;
275e4da13eeSmacallan	    pScrn->EnterVT	 = TCXEnterVT;
276e4da13eeSmacallan	    pScrn->LeaveVT	 = TCXLeaveVT;
277e4da13eeSmacallan	    pScrn->FreeScreen	 = TCXFreeScreen;
278e4da13eeSmacallan	    pScrn->ValidMode	 = TCXValidMode;
279e4da13eeSmacallan	    xf86AddEntityToScreen(pScrn, pEnt->index);
280e4da13eeSmacallan	    foundScreen = TRUE;
281e4da13eeSmacallan	}
2827a5333bcSmrg	free(pEnt);
283e4da13eeSmacallan    }
2847a5333bcSmrg    free(usedChips);
285e4da13eeSmacallan    return foundScreen;
286e4da13eeSmacallan}
287e4da13eeSmacallan
288e4da13eeSmacallan/* Mandatory */
289e4da13eeSmacallanstatic Bool
290e4da13eeSmacallanTCXPreInit(ScrnInfoPtr pScrn, int flags)
291e4da13eeSmacallan{
292e4da13eeSmacallan    TcxPtr pTcx;
293e4da13eeSmacallan    sbusDevicePtr psdp = NULL;
294e4da13eeSmacallan    MessageType from;
29559d6bc2bSmacallan    int i, prom;
296e4da13eeSmacallan    int hwCursor, lowDepth;
297e4da13eeSmacallan
298e4da13eeSmacallan    if (flags & PROBE_DETECT) return FALSE;
299e4da13eeSmacallan
300e4da13eeSmacallan    /*
301e4da13eeSmacallan     * Note: This function is only called once at server startup, and
302e4da13eeSmacallan     * not at the start of each server generation.  This means that
303e4da13eeSmacallan     * only things that are persistent across server generations can
304e4da13eeSmacallan     * be initialised here.  xf86Screens[] is (pScrn is a pointer to one
305e4da13eeSmacallan     * of these).  Privates allocated using xf86AllocateScrnInfoPrivateIndex()
306e4da13eeSmacallan     * are too, and should be used for data that must persist across
307e4da13eeSmacallan     * server generations.
308e4da13eeSmacallan     *
309e4da13eeSmacallan     * Per-generation data should be allocated with
310e4da13eeSmacallan     * AllocateScreenPrivateIndex() from the ScreenInit() function.
311e4da13eeSmacallan     */
312e4da13eeSmacallan
313e4da13eeSmacallan    /* Allocate the TcxRec driverPrivate */
314e4da13eeSmacallan    if (!TCXGetRec(pScrn)) {
315e4da13eeSmacallan	return FALSE;
316e4da13eeSmacallan    }
317e4da13eeSmacallan    pTcx = GET_TCX_FROM_SCRN(pScrn);
318e4da13eeSmacallan
319e4da13eeSmacallan    /* Set pScrn->monitor */
320e4da13eeSmacallan    pScrn->monitor = pScrn->confScreen->monitor;
321e4da13eeSmacallan
322e4da13eeSmacallan    /* This driver doesn't expect more than one entity per screen */
323e4da13eeSmacallan    if (pScrn->numEntities > 1)
324e4da13eeSmacallan	return FALSE;
325e4da13eeSmacallan    /* This is the general case */
326e4da13eeSmacallan    for (i = 0; i < pScrn->numEntities; i++) {
327e4da13eeSmacallan	EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[i]);
328e4da13eeSmacallan
329e4da13eeSmacallan	/* TCX is purely AFX, but we handle it like SBUS */
330e4da13eeSmacallan	if (pEnt->location.type == BUS_SBUS) {
331e4da13eeSmacallan	    psdp = xf86GetSbusInfoForEntity(pEnt->index);
332e4da13eeSmacallan	    pTcx->psdp = psdp;
333e4da13eeSmacallan	} else
334e4da13eeSmacallan	    return FALSE;
335e4da13eeSmacallan    }
336e4da13eeSmacallan    if (psdp == NULL)
337e4da13eeSmacallan	return FALSE;
338e4da13eeSmacallan
339e4da13eeSmacallan    /**********************
340e4da13eeSmacallan    check card capabilities
341e4da13eeSmacallan    **********************/
342e4da13eeSmacallan    hwCursor = 0;
343e4da13eeSmacallan    lowDepth = 1;
34459d6bc2bSmacallan
34559d6bc2bSmacallan    prom = sparcPromInit();
34659d6bc2bSmacallan    hwCursor = sparcPromGetBool(&psdp->node, "hw-cursor");
34759d6bc2bSmacallan    lowDepth = sparcPromGetBool(&psdp->node, "tcx-8-bit");
348a332beb9Sjoerg    if ((pTcx->HasStipROP = sparcPromGetBool(&psdp->node, "stip-rop"))) {
3494525cf0bSmacallan	xf86Msg(X_PROBED, "stipple space supports ROPs\n");
3504525cf0bSmacallan    }
351ccae0d10Smacallan    pTcx->Is8bit = (lowDepth != 0);
352ecc0bcc7Smacallan    /* all S24 support a hardware cursor */
35359d6bc2bSmacallan    if (!lowDepth) {
354ecc0bcc7Smacallan	hwCursor = 1;
35559d6bc2bSmacallan	pTcx->vramsize = 0x100000;	/* size of the 8bit fb */
35659d6bc2bSmacallan    } else {
35759d6bc2bSmacallan	char *b;
35859d6bc2bSmacallan	int len = 4, v = 0;
35959d6bc2bSmacallan
36059d6bc2bSmacallan    	/* see if we have more than 1MB vram */
36159d6bc2bSmacallan	pTcx->vramsize = 0x100000;
362f832ee3dSmacallan	if (((b = sparcPromGetProperty(&psdp->node, "vram", &len)) != NULL)  &&
363f832ee3dSmacallan	     (len == 4)) {
36459d6bc2bSmacallan	    memcpy(&v, b, 4);
36559d6bc2bSmacallan	    if ((v > 0) && (v < 3))
36659d6bc2bSmacallan	    	pTcx->vramsize = 0x100000 * v;
36759d6bc2bSmacallan	}
3684525cf0bSmacallan	xf86Msg(X_PROBED, "found %d MB video memory\n", v);
36959d6bc2bSmacallan
37059d6bc2bSmacallan    }
37159d6bc2bSmacallan    if (prom)
37259d6bc2bSmacallan    	sparcPromClose();
373ecc0bcc7Smacallan
3744525cf0bSmacallan    xf86Msg(X_PROBED, "hardware cursor support %s\n",
3754525cf0bSmacallan      hwCursor ? "found" : "not found");
376ecc0bcc7Smacallan
377e4da13eeSmacallan    /*********************
378e4da13eeSmacallan    deal with depth
379e4da13eeSmacallan    *********************/
380e4da13eeSmacallan
381ccae0d10Smacallan    if (!xf86SetDepthBpp(pScrn, lowDepth ? 8 : 0, 0, 0,
382e4da13eeSmacallan			 lowDepth ? NoDepth24Support : Support32bppFb)) {
383e4da13eeSmacallan	return FALSE;
384e4da13eeSmacallan    } else {
385e4da13eeSmacallan	/* Check that the returned depth is one we support */
386e4da13eeSmacallan	switch (pScrn->depth) {
387e4da13eeSmacallan	case 8:
388e4da13eeSmacallan	    /* OK */
389e4da13eeSmacallan	    break;
390e4da13eeSmacallan	case 32:
391ecc0bcc7Smacallan	case 24:
392e4da13eeSmacallan	    /* unless lowDepth OK */
393e4da13eeSmacallan	    if (lowDepth) {
394e4da13eeSmacallan		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
395e4da13eeSmacallan			   "Given depth (32) not supported by hardware\n");
396e4da13eeSmacallan		return FALSE;
397e4da13eeSmacallan	    }
398e4da13eeSmacallan	    break;
399e4da13eeSmacallan	default:
400e4da13eeSmacallan	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
401e4da13eeSmacallan		       "Given depth (%d) is not supported by this driver\n",
402e4da13eeSmacallan		       pScrn->depth);
403e4da13eeSmacallan	    return FALSE;
404e4da13eeSmacallan	}
405e4da13eeSmacallan    }
406e4da13eeSmacallan
407e4da13eeSmacallan    /* Collect all of the relevant option flags (fill in pScrn->options) */
408e4da13eeSmacallan    xf86CollectOptions(pScrn, NULL);
409e4da13eeSmacallan    /* Process the options */
4107a5333bcSmrg    if (!(pTcx->Options = malloc(sizeof(TCXOptions))))
411e4da13eeSmacallan	return FALSE;
412e4da13eeSmacallan    memcpy(pTcx->Options, TCXOptions, sizeof(TCXOptions));
413e4da13eeSmacallan    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pTcx->Options);
414e4da13eeSmacallan
415e4da13eeSmacallan    /*
416e4da13eeSmacallan     * This must happen after pScrn->display has been set because
417e4da13eeSmacallan     * xf86SetWeight references it.
418e4da13eeSmacallan     */
419e4da13eeSmacallan    if (pScrn->depth > 8) {
420ecc0bcc7Smacallan	rgb weight = {0, 0, 0};
421e4da13eeSmacallan	rgb mask = {0xff, 0xff00, 0xff0000};
422e4da13eeSmacallan
423e4da13eeSmacallan	if (!xf86SetWeight(pScrn, weight, mask)) {
424e4da13eeSmacallan	    return FALSE;
425e4da13eeSmacallan	}
426e4da13eeSmacallan    }
427e4da13eeSmacallan
428e4da13eeSmacallan    if (!xf86SetDefaultVisual(pScrn, -1))
429e4da13eeSmacallan	return FALSE;
430e4da13eeSmacallan    else if (pScrn->depth > 8) {
431e4da13eeSmacallan	/* We don't currently support DirectColor */
432e4da13eeSmacallan	if (pScrn->defaultVisual != TrueColor) {
433e4da13eeSmacallan	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
434e4da13eeSmacallan		       " (%s) is not supported\n",
435e4da13eeSmacallan		       xf86GetVisualName(pScrn->defaultVisual));
436e4da13eeSmacallan	    return FALSE;
437e4da13eeSmacallan	}
438e4da13eeSmacallan    }
439e4da13eeSmacallan
440e4da13eeSmacallan    /*
441e4da13eeSmacallan     * The new cmap code requires this to be initialised.
442e4da13eeSmacallan     */
443e4da13eeSmacallan
444e4da13eeSmacallan    {
445e4da13eeSmacallan	Gamma zeros = {0.0, 0.0, 0.0};
446e4da13eeSmacallan
447e4da13eeSmacallan	if (!xf86SetGamma(pScrn, zeros)) {
448e4da13eeSmacallan	    return FALSE;
449e4da13eeSmacallan	}
450e4da13eeSmacallan    }
451e4da13eeSmacallan
452e4da13eeSmacallan    /* determine whether we use hardware or software cursor */
453e4da13eeSmacallan
454e4da13eeSmacallan    from = X_PROBED;
455e4da13eeSmacallan    pTcx->HWCursor = FALSE;
456e4da13eeSmacallan    if (hwCursor) {
457e4da13eeSmacallan	from = X_DEFAULT;
458e4da13eeSmacallan	pTcx->HWCursor = TRUE;
459e4da13eeSmacallan	if (xf86GetOptValBool(pTcx->Options, OPTION_HW_CURSOR, &pTcx->HWCursor))
460e4da13eeSmacallan	    from = X_CONFIG;
461e4da13eeSmacallan	if (xf86ReturnOptValBool(pTcx->Options, OPTION_SW_CURSOR, FALSE)) {
462e4da13eeSmacallan	    from = X_CONFIG;
463e4da13eeSmacallan	    pTcx->HWCursor = FALSE;
464e4da13eeSmacallan	}
465e4da13eeSmacallan    }
466ecc0bcc7Smacallan
467ecc0bcc7Smacallan    pTcx->NoAccel = FALSE;
468ecc0bcc7Smacallan    if (xf86ReturnOptValBool(pTcx->Options, OPTION_NOACCEL, FALSE)) {
469ecc0bcc7Smacallan	pTcx->NoAccel = TRUE;
470ecc0bcc7Smacallan	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
471ecc0bcc7Smacallan    }
472ecc0bcc7Smacallan
473e4da13eeSmacallan    xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
474e4da13eeSmacallan		pTcx->HWCursor ? "HW" : "SW");
475e4da13eeSmacallan
476e4da13eeSmacallan    if (xf86LoadSubModule(pScrn, "fb") == NULL) {
477e4da13eeSmacallan	TCXFreeRec(pScrn);
478e4da13eeSmacallan	return FALSE;
479e4da13eeSmacallan    }
480e4da13eeSmacallan
481e4da13eeSmacallan    if (pTcx->HWCursor && xf86LoadSubModule(pScrn, "ramdac") == NULL) {
482e4da13eeSmacallan	TCXFreeRec(pScrn);
483e4da13eeSmacallan	return FALSE;
484e4da13eeSmacallan    }
485e4da13eeSmacallan
486e4da13eeSmacallan    /*********************
487e4da13eeSmacallan    set up clock and mode stuff
488e4da13eeSmacallan    *********************/
489e4da13eeSmacallan
490e4da13eeSmacallan    pScrn->progClock = TRUE;
491e4da13eeSmacallan
492e4da13eeSmacallan    if(pScrn->display->virtualX || pScrn->display->virtualY) {
493e4da13eeSmacallan	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
494e4da13eeSmacallan		   "TCX does not support a virtual desktop\n");
495e4da13eeSmacallan	pScrn->display->virtualX = 0;
496e4da13eeSmacallan	pScrn->display->virtualY = 0;
497e4da13eeSmacallan    }
498e4da13eeSmacallan
499e4da13eeSmacallan    xf86SbusUseBuiltinMode(pScrn, pTcx->psdp);
500e4da13eeSmacallan    pScrn->currentMode = pScrn->modes;
501e4da13eeSmacallan    pScrn->displayWidth = pScrn->virtualX;
502e4da13eeSmacallan
503e4da13eeSmacallan    /* Set display resolution */
504e4da13eeSmacallan    xf86SetDpi(pScrn, 0, 0);
505e4da13eeSmacallan
506e4da13eeSmacallan    return TRUE;
507e4da13eeSmacallan}
508e4da13eeSmacallan
509e4da13eeSmacallan/* Mandatory */
510e4da13eeSmacallan
511e4da13eeSmacallan/* This gets called at the start of each server generation */
512e4da13eeSmacallan
513e4da13eeSmacallanstatic Bool
5147a5333bcSmrgTCXScreenInit(SCREEN_INIT_ARGS_DECL)
515e4da13eeSmacallan{
516e4da13eeSmacallan    ScrnInfoPtr pScrn;
517e4da13eeSmacallan    TcxPtr pTcx;
518e4da13eeSmacallan    VisualPtr visual;
519e4da13eeSmacallan    int ret;
520e4da13eeSmacallan
521e4da13eeSmacallan    /*
522e4da13eeSmacallan     * First get the ScrnInfoRec
523e4da13eeSmacallan     */
5247a5333bcSmrg    pScrn = xf86ScreenToScrn(pScreen);
525e4da13eeSmacallan
526e4da13eeSmacallan    pTcx = GET_TCX_FROM_SCRN(pScrn);
527e4da13eeSmacallan
528e4da13eeSmacallan    /* Map the TCX memory */
529f615cd97Smacallan    if (pScrn->depth == 8) {
530e4da13eeSmacallan	pTcx->fb =
53159d6bc2bSmacallan	    xf86MapSbusMem (pTcx->psdp, TCX_RAM8_VOFF, pTcx->vramsize);
532f615cd97Smacallan	pTcx->pitchshift = 0;
533f615cd97Smacallan    } else {
534e4da13eeSmacallan	pTcx->fb =
535ecc0bcc7Smacallan	    xf86MapSbusMem (pTcx->psdp, TCX_RAM24_VOFF, 1024 * 1024 * 4);
536e4da13eeSmacallan	pTcx->cplane =
537ecc0bcc7Smacallan	    xf86MapSbusMem (pTcx->psdp, TCX_CPLANE_VOFF, 1024 * 1024 * 4);
538f615cd97Smacallan	pTcx->pitchshift = 2;
539e4da13eeSmacallan	if (! pTcx->cplane)
540e4da13eeSmacallan	    return FALSE;
541e4da13eeSmacallan    }
542e4da13eeSmacallan    if (pTcx->HWCursor == TRUE) {
543e4da13eeSmacallan	pTcx->thc = xf86MapSbusMem (pTcx->psdp, TCX_THC_VOFF, 8192);
544e4da13eeSmacallan	if (! pTcx->thc)
545e4da13eeSmacallan	    return FALSE;
546e4da13eeSmacallan    }
547e4da13eeSmacallan
548ccae0d10Smacallan    if (pTcx->Is8bit) {
549ccae0d10Smacallan    	/* use STIP and BLIT on tcx */
55059d6bc2bSmacallan        pTcx->rblit = xf86MapSbusMem(pTcx->psdp, TCX_BLIT_VOFF, 8 * pTcx->vramsize);
551ccae0d10Smacallan        if (pTcx->rblit == NULL) {
552ccae0d10Smacallan	    xf86Msg(X_ERROR, "Couldn't map BLIT space\n");
553ccae0d10Smacallan	    return FALSE;
554ccae0d10Smacallan        }
55559d6bc2bSmacallan        pTcx->rstip = xf86MapSbusMem(pTcx->psdp, TCX_STIP_VOFF, 8 * pTcx->vramsize);
556ccae0d10Smacallan        if (pTcx->rstip == NULL) {
557ccae0d10Smacallan	    xf86Msg(X_ERROR, "Couldn't map STIP space\n");
558ccae0d10Smacallan	    return FALSE;
559ccae0d10Smacallan	}
560ccae0d10Smacallan    } else {
561ccae0d10Smacallan    	/* use RSTIP and RBLIT on S24 */
562ccae0d10Smacallan        pTcx->rblit = xf86MapSbusMem(pTcx->psdp, TCX_RBLIT_VOFF, 8 * 1024 * 1024);
563ccae0d10Smacallan        if (pTcx->rblit == NULL) {
564ccae0d10Smacallan	    xf86Msg(X_ERROR, "Couldn't map RBLIT space\n");
565ccae0d10Smacallan	    return FALSE;
566ccae0d10Smacallan        }
567ccae0d10Smacallan        pTcx->rstip = xf86MapSbusMem(pTcx->psdp, TCX_RSTIP_VOFF, 8 * 1024 * 1024);
568ccae0d10Smacallan        if (pTcx->rstip == NULL) {
569ccae0d10Smacallan	    xf86Msg(X_ERROR, "Couldn't map RSTIP space\n");
570ccae0d10Smacallan	    return FALSE;
571ccae0d10Smacallan	}
572ecc0bcc7Smacallan    }
573ecc0bcc7Smacallan
574e4da13eeSmacallan    if (! pTcx->fb)
575e4da13eeSmacallan	return FALSE;
576e4da13eeSmacallan
577e4da13eeSmacallan    /* Darken the screen for aesthetic reasons and set the viewport */
578e4da13eeSmacallan    TCXSaveScreen(pScreen, SCREEN_SAVER_ON);
579e4da13eeSmacallan
580e4da13eeSmacallan    /*
581e4da13eeSmacallan     * The next step is to setup the screen's visuals, and initialise the
582e4da13eeSmacallan     * framebuffer code.  In cases where the framebuffer's default
583e4da13eeSmacallan     * choices for things like visual layouts and bits per RGB are OK,
584e4da13eeSmacallan     * this may be as simple as calling the framebuffer's ScreenInit()
585e4da13eeSmacallan     * function.  If not, the visuals will need to be setup before calling
586e4da13eeSmacallan     * a fb ScreenInit() function and fixed up after.
587e4da13eeSmacallan     */
588e4da13eeSmacallan
589e4da13eeSmacallan    /*
590e4da13eeSmacallan     * Reset visual list.
591e4da13eeSmacallan     */
592e4da13eeSmacallan    miClearVisualTypes();
593e4da13eeSmacallan
594e4da13eeSmacallan    if (pScrn->depth == 8)
595e4da13eeSmacallan	/* Set the bits per RGB for 8bpp mode */
596e4da13eeSmacallan	pScrn->rgbBits = 8;
597e4da13eeSmacallan
598e4da13eeSmacallan    /* Setup the visuals we support. */
599e4da13eeSmacallan
600e4da13eeSmacallan    if (!miSetVisualTypes(pScrn->depth,
601e4da13eeSmacallan			  pScrn->depth != 8 ? TrueColorMask :
602e4da13eeSmacallan				miGetDefaultVisualMask(pScrn->depth),
603e4da13eeSmacallan			  pScrn->rgbBits, pScrn->defaultVisual))
604e4da13eeSmacallan	return FALSE;
605e4da13eeSmacallan
606e4da13eeSmacallan    miSetPixmapDepths ();
607e4da13eeSmacallan
608e4da13eeSmacallan    /*
609e4da13eeSmacallan     * Call the framebuffer layer's ScreenInit function, and fill in other
610e4da13eeSmacallan     * pScreen fields.
611e4da13eeSmacallan     */
612e4da13eeSmacallan
613e4da13eeSmacallan    if (pScrn->bitsPerPixel != 8)
614e4da13eeSmacallan	TCXInitCplane24(pScrn);
615e4da13eeSmacallan    ret = fbScreenInit(pScreen, pTcx->fb, pScrn->virtualX,
616e4da13eeSmacallan		       pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
617e4da13eeSmacallan		       pScrn->virtualX, pScrn->bitsPerPixel);
618e4da13eeSmacallan
619e4da13eeSmacallan    if (!ret)
620e4da13eeSmacallan	return FALSE;
621e4da13eeSmacallan
622e4da13eeSmacallan    xf86SetBlackWhitePixels(pScreen);
623e4da13eeSmacallan
624e4da13eeSmacallan    if (pScrn->bitsPerPixel > 8) {
625e4da13eeSmacallan	/* Fixup RGB ordering */
626e4da13eeSmacallan	visual = pScreen->visuals + pScreen->numVisuals;
627e4da13eeSmacallan	while (--visual >= pScreen->visuals) {
628e4da13eeSmacallan	    if ((visual->class | DynamicClass) == DirectColor) {
629e4da13eeSmacallan		visual->offsetRed = pScrn->offset.red;
630e4da13eeSmacallan		visual->offsetGreen = pScrn->offset.green;
631e4da13eeSmacallan		visual->offsetBlue = pScrn->offset.blue;
632e4da13eeSmacallan		visual->redMask = pScrn->mask.red;
633e4da13eeSmacallan		visual->greenMask = pScrn->mask.green;
634e4da13eeSmacallan		visual->blueMask = pScrn->mask.blue;
635e4da13eeSmacallan	    }
636e4da13eeSmacallan	}
637e4da13eeSmacallan    }
638e4da13eeSmacallan
639e4da13eeSmacallan#ifdef RENDER
640e4da13eeSmacallan    /* must be after RGB ordering fixed */
641e4da13eeSmacallan    fbPictureInit (pScreen, 0, 0);
642e4da13eeSmacallan#endif
643e4da13eeSmacallan
644ccae0d10Smacallan    if (!pTcx->NoAccel) {
645ecc0bcc7Smacallan        XF86ModReqInfo req;
646ecc0bcc7Smacallan        int errmaj, errmin;
647ecc0bcc7Smacallan
648ecc0bcc7Smacallan        memset(&req, 0, sizeof(XF86ModReqInfo));
649ecc0bcc7Smacallan        req.majorversion = 2;
650ecc0bcc7Smacallan        req.minorversion = 0;
651ecc0bcc7Smacallan        if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req,
652ecc0bcc7Smacallan            &errmaj, &errmin))
653ecc0bcc7Smacallan        {
654ecc0bcc7Smacallan            LoaderErrorMsg(NULL, "exa", errmaj, errmin);
655ecc0bcc7Smacallan            return FALSE;
656ecc0bcc7Smacallan        }
657ecc0bcc7Smacallan	if (!TcxInitAccel(pScreen))
658ecc0bcc7Smacallan	    return FALSE;
659ecc0bcc7Smacallan    }
660ecc0bcc7Smacallan
661e4da13eeSmacallan    xf86SetBackingStore(pScreen);
662e4da13eeSmacallan    xf86SetSilkenMouse(pScreen);
663e4da13eeSmacallan
664e4da13eeSmacallan    /* Initialise cursor functions */
665e4da13eeSmacallan    miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
666e4da13eeSmacallan
667e4da13eeSmacallan    /* Initialize HW cursor layer.
668e4da13eeSmacallan       Must follow software cursor initialization*/
669e4da13eeSmacallan    if (pTcx->HWCursor) {
670e4da13eeSmacallan	extern Bool TCXHWCursorInit(ScreenPtr pScreen);
671e4da13eeSmacallan
672e4da13eeSmacallan	if(!TCXHWCursorInit(pScreen)) {
673e4da13eeSmacallan	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
674e4da13eeSmacallan		       "Hardware cursor initialization failed\n");
675e4da13eeSmacallan	    return(FALSE);
676e4da13eeSmacallan	}
677e4da13eeSmacallan	xf86SbusHideOsHwCursor(pTcx->psdp);
678e4da13eeSmacallan    }
679e4da13eeSmacallan
680e4da13eeSmacallan    /* Initialise default colourmap */
681e4da13eeSmacallan    if (!miCreateDefColormap(pScreen))
682e4da13eeSmacallan	return FALSE;
683e4da13eeSmacallan
684e4da13eeSmacallan    if(pScrn->depth == 8 && !xf86SbusHandleColormaps(pScreen, pTcx->psdp))
685e4da13eeSmacallan	return FALSE;
686e4da13eeSmacallan
687e4da13eeSmacallan    pTcx->CloseScreen = pScreen->CloseScreen;
688e4da13eeSmacallan    pScreen->CloseScreen = TCXCloseScreen;
689e4da13eeSmacallan    pScreen->SaveScreen = TCXSaveScreen;
690e4da13eeSmacallan
691e4da13eeSmacallan    /* Report any unused options (only for the first generation) */
692e4da13eeSmacallan    if (serverGeneration == 1) {
693e4da13eeSmacallan	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
694e4da13eeSmacallan    }
695e4da13eeSmacallan
696e4da13eeSmacallan    /* unblank the screen */
697e4da13eeSmacallan    TCXSaveScreen(pScreen, SCREEN_SAVER_OFF);
698e4da13eeSmacallan
699e4da13eeSmacallan    /* Done */
700e4da13eeSmacallan    return TRUE;
701e4da13eeSmacallan}
702e4da13eeSmacallan
703e4da13eeSmacallan
704e4da13eeSmacallan/* Usually mandatory */
705e4da13eeSmacallanstatic Bool
7067a5333bcSmrgTCXSwitchMode(SWITCH_MODE_ARGS_DECL)
707e4da13eeSmacallan{
708e4da13eeSmacallan    return TRUE;
709e4da13eeSmacallan}
710e4da13eeSmacallan
711e4da13eeSmacallan
712e4da13eeSmacallan/*
713e4da13eeSmacallan * This function is used to initialize the Start Address - the first
714e4da13eeSmacallan * displayed location in the video memory.
715e4da13eeSmacallan */
716e4da13eeSmacallan/* Usually mandatory */
717e4da13eeSmacallanstatic void
7187a5333bcSmrgTCXAdjustFrame(ADJUST_FRAME_ARGS_DECL)
719e4da13eeSmacallan{
720e4da13eeSmacallan    /* we don't support virtual desktops */
721e4da13eeSmacallan    return;
722e4da13eeSmacallan}
723e4da13eeSmacallan
724e4da13eeSmacallan/*
725e4da13eeSmacallan * This is called when VT switching back to the X server.  Its job is
726e4da13eeSmacallan * to reinitialise the video mode.
727e4da13eeSmacallan */
728e4da13eeSmacallan
729e4da13eeSmacallan/* Mandatory */
730e4da13eeSmacallanstatic Bool
7317a5333bcSmrgTCXEnterVT(VT_FUNC_ARGS_DECL)
732e4da13eeSmacallan{
7337a5333bcSmrg    SCRN_INFO_PTR(arg);
734e4da13eeSmacallan    TcxPtr pTcx = GET_TCX_FROM_SCRN(pScrn);
735e4da13eeSmacallan
736e4da13eeSmacallan    if (pTcx->HWCursor) {
737e4da13eeSmacallan	xf86SbusHideOsHwCursor (pTcx->psdp);
738e4da13eeSmacallan	pTcx->CursorFg = 0;
739e4da13eeSmacallan	pTcx->CursorBg = 0;
740e4da13eeSmacallan    }
741e4da13eeSmacallan    if (pTcx->cplane) {
742e4da13eeSmacallan	TCXInitCplane24 (pScrn);
743e4da13eeSmacallan    }
744e4da13eeSmacallan    return TRUE;
745e4da13eeSmacallan}
746e4da13eeSmacallan
747e4da13eeSmacallan
748e4da13eeSmacallan/*
749e4da13eeSmacallan * This is called when VT switching away from the X server.
750e4da13eeSmacallan */
751e4da13eeSmacallan
752e4da13eeSmacallan/* Mandatory */
753e4da13eeSmacallanstatic void
7547a5333bcSmrgTCXLeaveVT(VT_FUNC_ARGS_DECL)
755e4da13eeSmacallan{
756e4da13eeSmacallan    return;
757e4da13eeSmacallan}
758e4da13eeSmacallan
759e4da13eeSmacallan
760e4da13eeSmacallan/*
761e4da13eeSmacallan * This is called at the end of each server generation.  It restores the
762e4da13eeSmacallan * original (text) mode.  It should really also unmap the video memory too.
763e4da13eeSmacallan */
764e4da13eeSmacallan
765e4da13eeSmacallan/* Mandatory */
766e4da13eeSmacallanstatic Bool
7677a5333bcSmrgTCXCloseScreen(CLOSE_SCREEN_ARGS_DECL)
768e4da13eeSmacallan{
7697a5333bcSmrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
770e4da13eeSmacallan    TcxPtr pTcx = GET_TCX_FROM_SCRN(pScrn);
771e4da13eeSmacallan
772e4da13eeSmacallan    pScrn->vtSema = FALSE;
773e4da13eeSmacallan    if (pScrn->depth == 8)
774e4da13eeSmacallan	xf86UnmapSbusMem(pTcx->psdp, pTcx->fb,
775e4da13eeSmacallan			 (pTcx->psdp->width * pTcx->psdp->height));
776e4da13eeSmacallan    else {
777e4da13eeSmacallan	xf86UnmapSbusMem(pTcx->psdp, pTcx->fb,
778e4da13eeSmacallan			 (pTcx->psdp->width * pTcx->psdp->height * 4));
779e4da13eeSmacallan	xf86UnmapSbusMem(pTcx->psdp, pTcx->cplane,
780e4da13eeSmacallan			 (pTcx->psdp->width * pTcx->psdp->height * 4));
781e4da13eeSmacallan    }
782e4da13eeSmacallan    if (pTcx->thc)
783180c47ecSmacallan	xf86UnmapSbusMem(pTcx->psdp, pTcx->thc, 8192);
784e4da13eeSmacallan
785e4da13eeSmacallan    if (pTcx->HWCursor)
786e4da13eeSmacallan	xf86SbusHideOsHwCursor (pTcx->psdp);
787e4da13eeSmacallan
788e4da13eeSmacallan    pScreen->CloseScreen = pTcx->CloseScreen;
7897a5333bcSmrg    return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
790e4da13eeSmacallan}
791e4da13eeSmacallan
792e4da13eeSmacallan
793e4da13eeSmacallan/* Free up any per-generation data structures */
794e4da13eeSmacallan
795e4da13eeSmacallan/* Optional */
796e4da13eeSmacallanstatic void
7977a5333bcSmrgTCXFreeScreen(FREE_SCREEN_ARGS_DECL)
798e4da13eeSmacallan{
7997a5333bcSmrg    SCRN_INFO_PTR(arg);
8007a5333bcSmrg    TCXFreeRec(pScrn);
801e4da13eeSmacallan}
802e4da13eeSmacallan
803e4da13eeSmacallan
804e4da13eeSmacallan/* Checks if a mode is suitable for the selected chipset. */
805e4da13eeSmacallan
806e4da13eeSmacallan/* Optional */
807e4da13eeSmacallanstatic ModeStatus
8087a5333bcSmrgTCXValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags)
809e4da13eeSmacallan{
810e4da13eeSmacallan    if (mode->Flags & V_INTERLACE)
811e4da13eeSmacallan	return(MODE_BAD);
812e4da13eeSmacallan
813e4da13eeSmacallan    return(MODE_OK);
814e4da13eeSmacallan}
815e4da13eeSmacallan
816e4da13eeSmacallan/* Do screen blanking */
817e4da13eeSmacallan
818e4da13eeSmacallan/* Mandatory */
819e4da13eeSmacallanstatic Bool
820e4da13eeSmacallanTCXSaveScreen(ScreenPtr pScreen, int mode)
821e4da13eeSmacallan    /* this function should blank the screen when unblank is FALSE and
822e4da13eeSmacallan       unblank it when unblank is TRUE -- it doesn't actually seem to be
823e4da13eeSmacallan       used for much though */
824e4da13eeSmacallan{
825ecc0bcc7Smacallan    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
826ecc0bcc7Smacallan    TcxPtr pTcx = GET_TCX_FROM_SCRN(pScrn);
827ecc0bcc7Smacallan    int fd = pTcx->psdp->fd, state;
828ecc0bcc7Smacallan
829ecc0bcc7Smacallan    /*
830ecc0bcc7Smacallan     * we're using ioctl() instead of just whacking the DAC because the
831ecc0bcc7Smacallan     * underlying driver will also turn off the backlight which we couldn't do
832ecc0bcc7Smacallan     * from here without adding lots more hardware dependencies
833ecc0bcc7Smacallan     */
834ecc0bcc7Smacallan    switch(mode)
835ecc0bcc7Smacallan    {
836ecc0bcc7Smacallan	case SCREEN_SAVER_ON:
837ecc0bcc7Smacallan	case SCREEN_SAVER_CYCLE:
838ecc0bcc7Smacallan    		state = 0;
839ecc0bcc7Smacallan		if(ioctl(fd, FBIOSVIDEO, &state) == -1)
840ecc0bcc7Smacallan		{
841ecc0bcc7Smacallan			/* complain */
842ecc0bcc7Smacallan		}
843ecc0bcc7Smacallan		break;
844ecc0bcc7Smacallan	case SCREEN_SAVER_OFF:
845ecc0bcc7Smacallan	case SCREEN_SAVER_FORCER:
846ecc0bcc7Smacallan    		state = 1;
847ecc0bcc7Smacallan		if(ioctl(fd, FBIOSVIDEO, &state) == -1)
848ecc0bcc7Smacallan		{
849ecc0bcc7Smacallan			/* complain */
850ecc0bcc7Smacallan		}
851ecc0bcc7Smacallan		break;
852ecc0bcc7Smacallan	default:
853ecc0bcc7Smacallan		return FALSE;
854ecc0bcc7Smacallan    }
855ecc0bcc7Smacallan
856e4da13eeSmacallan    return TRUE;
857e4da13eeSmacallan}
858e4da13eeSmacallan
859e4da13eeSmacallan/*
860e4da13eeSmacallan * This is the implementation of the Sync() function.
861e4da13eeSmacallan */
862e4da13eeSmacallanvoid
863e4da13eeSmacallanTCXSync(ScrnInfoPtr pScrn)
864e4da13eeSmacallan{
865e4da13eeSmacallan    return;
866e4da13eeSmacallan}
867e4da13eeSmacallan
868e4da13eeSmacallan/*
869e4da13eeSmacallan * This initializes CPLANE for 24 bit mode.
870e4da13eeSmacallan */
871e4da13eeSmacallanstatic void
872e4da13eeSmacallanTCXInitCplane24(ScrnInfoPtr pScrn)
873e4da13eeSmacallan{
874e4da13eeSmacallan    TcxPtr pTcx = GET_TCX_FROM_SCRN(pScrn);
875e4da13eeSmacallan    int size;
876e4da13eeSmacallan    unsigned int *p, *q;
877e4da13eeSmacallan
878e4da13eeSmacallan    if (!pTcx->cplane)
879e4da13eeSmacallan	return;
880e4da13eeSmacallan
881e4da13eeSmacallan    size = pScrn->virtualX * pScrn->virtualY;
882e4da13eeSmacallan    memset (pTcx->fb, 0, size * 4);
883e4da13eeSmacallan    p = pTcx->cplane;
884e4da13eeSmacallan    for (q = pTcx->cplane + size; p != q; p++)
885e4da13eeSmacallan	*p = (*p & 0xffffff) | TCX_CPLANE_MODE;
886e4da13eeSmacallan}
887d62aaaf2Smacallan
888d62aaaf2Smacallanstatic Bool
889d62aaaf2SmacallanTCXDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op,
890d62aaaf2Smacallan    pointer ptr)
891d62aaaf2Smacallan{
892d62aaaf2Smacallan	xorgHWFlags *flag;
893d62aaaf2Smacallan
894d62aaaf2Smacallan	switch (op) {
895d62aaaf2Smacallan	case GET_REQUIRED_HW_INTERFACES:
896d62aaaf2Smacallan		flag = (CARD32*)ptr;
897d62aaaf2Smacallan		(*flag) = HW_MMIO;
898d62aaaf2Smacallan		return TRUE;
899d62aaaf2Smacallan	default:
900d62aaaf2Smacallan		return FALSE;
901d62aaaf2Smacallan	}
902d62aaaf2Smacallan}
903