cg14_driver.c revision 1bd6d369
1f7ec340bSmacallan/*
2f7ec340bSmacallan * CG14 framebuffer driver.
3f7ec340bSmacallan *
4f7ec340bSmacallan * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com)
5f7ec340bSmacallan *
6f7ec340bSmacallan * Permission is hereby granted, free of charge, to any person obtaining a copy
7f7ec340bSmacallan * of this software and associated documentation files (the "Software"), to deal
8f7ec340bSmacallan * in the Software without restriction, including without limitation the rights
9f7ec340bSmacallan * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10f7ec340bSmacallan * copies of the Software, and to permit persons to whom the Software is
11f7ec340bSmacallan * furnished to do so, subject to the following conditions:
12f7ec340bSmacallan *
13f7ec340bSmacallan * The above copyright notice and this permission notice shall be included in
14f7ec340bSmacallan * all copies or substantial portions of the Software.
15f7ec340bSmacallan *
16f7ec340bSmacallan * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17f7ec340bSmacallan * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18f7ec340bSmacallan * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19f7ec340bSmacallan * JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20f7ec340bSmacallan * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21f7ec340bSmacallan * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22f7ec340bSmacallan */
23f7ec340bSmacallan
24f7ec340bSmacallan#ifdef HAVE_CONFIG_H
25f7ec340bSmacallan#include "config.h"
26f7ec340bSmacallan#endif
27f7ec340bSmacallan
28f7ec340bSmacallan#include <string.h>
29f7ec340bSmacallan
30f7ec340bSmacallan#include "xf86.h"
31f7ec340bSmacallan#include "xf86_OSproc.h"
32f7ec340bSmacallan#include "mipointer.h"
33f7ec340bSmacallan#include "mibstore.h"
34f7ec340bSmacallan#include "micmap.h"
35f7ec340bSmacallan
36f7ec340bSmacallan#include "fb.h"
37f7ec340bSmacallan#include "xf86cmap.h"
38f7ec340bSmacallan#include "cg14.h"
39f7ec340bSmacallan
40f7ec340bSmacallanstatic const OptionInfoRec * CG14AvailableOptions(int chipid, int busid);
41f7ec340bSmacallanstatic void	CG14Identify(int flags);
42f7ec340bSmacallanstatic Bool	CG14Probe(DriverPtr drv, int flags);
43f7ec340bSmacallanstatic Bool	CG14PreInit(ScrnInfoPtr pScrn, int flags);
44f7ec340bSmacallanstatic Bool	CG14ScreenInit(int Index, ScreenPtr pScreen, int argc,
45f7ec340bSmacallan			      char **argv);
46f7ec340bSmacallanstatic Bool	CG14EnterVT(int scrnIndex, int flags);
47f7ec340bSmacallanstatic void	CG14LeaveVT(int scrnIndex, int flags);
48f7ec340bSmacallanstatic Bool	CG14CloseScreen(int scrnIndex, ScreenPtr pScreen);
49f7ec340bSmacallanstatic Bool	CG14SaveScreen(ScreenPtr pScreen, int mode);
50f7ec340bSmacallanstatic void	CG14InitCplane24(ScrnInfoPtr pScrn);
51f7ec340bSmacallanstatic void	CG14ExitCplane24(ScrnInfoPtr pScrn);
52f7ec340bSmacallan
53f7ec340bSmacallan/* Required if the driver supports mode switching */
54f7ec340bSmacallanstatic Bool	CG14SwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
55f7ec340bSmacallan/* Required if the driver supports moving the viewport */
56f7ec340bSmacallanstatic void	CG14AdjustFrame(int scrnIndex, int x, int y, int flags);
57f7ec340bSmacallan
58f7ec340bSmacallan/* Optional functions */
59f7ec340bSmacallanstatic void	CG14FreeScreen(int scrnIndex, int flags);
60f7ec340bSmacallanstatic ModeStatus CG14ValidMode(int scrnIndex, DisplayModePtr mode,
61f7ec340bSmacallan				Bool verbose, int flags);
62f7ec340bSmacallan
63f7ec340bSmacallanvoid CG14Sync(ScrnInfoPtr pScrn);
64f7ec340bSmacallan
65f7ec340bSmacallan#define CG14_VERSION 4000
66f7ec340bSmacallan#define CG14_NAME "SUNCG14"
67f7ec340bSmacallan#define CG14_DRIVER_NAME "suncg14"
68766a8447Smrg#define CG14_MAJOR_VERSION PACKAGE_VERSION_MAJOR
69766a8447Smrg#define CG14_MINOR_VERSION PACKAGE_VERSION_MINOR
70766a8447Smrg#define CG14_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL
71f7ec340bSmacallan
72f7ec340bSmacallan/*
73f7ec340bSmacallan * This contains the functions needed by the server after loading the driver
74f7ec340bSmacallan * module.  It must be supplied, and gets passed back by the SetupProc
75f7ec340bSmacallan * function in the dynamic case.  In the static case, a reference to this
76f7ec340bSmacallan * is compiled in, and this requires that the name of this DriverRec be
77f7ec340bSmacallan * an upper-case version of the driver name.
78f7ec340bSmacallan */
79f7ec340bSmacallan
80f7ec340bSmacallan_X_EXPORT DriverRec SUNCG14 = {
81f7ec340bSmacallan    CG14_VERSION,
82f7ec340bSmacallan    CG14_DRIVER_NAME,
83f7ec340bSmacallan    CG14Identify,
84f7ec340bSmacallan    CG14Probe,
85f7ec340bSmacallan    CG14AvailableOptions,
86f7ec340bSmacallan    NULL,
87f7ec340bSmacallan    0
88f7ec340bSmacallan};
89f7ec340bSmacallan
90f7ec340bSmacallanstatic const OptionInfoRec CG14Options[] = {
91f7ec340bSmacallan    { -1,			NULL,		OPTV_NONE,	{0}, FALSE }
92f7ec340bSmacallan};
93f7ec340bSmacallan
94f7ec340bSmacallan#ifdef XFree86LOADER
95f7ec340bSmacallan
96f7ec340bSmacallanstatic MODULESETUPPROTO(cg14Setup);
97f7ec340bSmacallan
98f7ec340bSmacallanstatic XF86ModuleVersionInfo suncg14VersRec =
99f7ec340bSmacallan{
100f7ec340bSmacallan	"suncg14",
101f7ec340bSmacallan	MODULEVENDORSTRING,
102f7ec340bSmacallan	MODINFOSTRING1,
103f7ec340bSmacallan	MODINFOSTRING2,
104f7ec340bSmacallan	XORG_VERSION_CURRENT,
105f7ec340bSmacallan	CG14_MAJOR_VERSION, CG14_MINOR_VERSION, CG14_PATCHLEVEL,
106f7ec340bSmacallan	ABI_CLASS_VIDEODRV,
107f7ec340bSmacallan	ABI_VIDEODRV_VERSION,
108f7ec340bSmacallan	MOD_CLASS_VIDEODRV,
109f7ec340bSmacallan	{0,0,0,0}
110f7ec340bSmacallan};
111f7ec340bSmacallan
112f7ec340bSmacallan_X_EXPORT XF86ModuleData suncg14ModuleData = {
113f7ec340bSmacallan	&suncg14VersRec,
114f7ec340bSmacallan	cg14Setup,
115f7ec340bSmacallan	NULL
116f7ec340bSmacallan};
117f7ec340bSmacallan
118f7ec340bSmacallanpointer
119f7ec340bSmacallancg14Setup(pointer module, pointer opts, int *errmaj, int *errmin)
120f7ec340bSmacallan{
121f7ec340bSmacallan    static Bool setupDone = FALSE;
122f7ec340bSmacallan
123f7ec340bSmacallan    if (!setupDone) {
124f7ec340bSmacallan	setupDone = TRUE;
125f7ec340bSmacallan	xf86AddDriver(&SUNCG14, module, 0);
126f7ec340bSmacallan
127f7ec340bSmacallan	/*
128f7ec340bSmacallan	 * Modules that this driver always requires can be loaded here
129f7ec340bSmacallan	 * by calling LoadSubModule().
130f7ec340bSmacallan	 */
131f7ec340bSmacallan
132f7ec340bSmacallan	/*
133f7ec340bSmacallan	 * The return value must be non-NULL on success even though there
134f7ec340bSmacallan	 * is no TearDownProc.
135f7ec340bSmacallan	 */
136f7ec340bSmacallan	return (pointer)TRUE;
137f7ec340bSmacallan    } else {
138f7ec340bSmacallan	if (errmaj) *errmaj = LDR_ONCEONLY;
139f7ec340bSmacallan	return NULL;
140f7ec340bSmacallan    }
141f7ec340bSmacallan}
142f7ec340bSmacallan
143f7ec340bSmacallan#endif /* XFree86LOADER */
144f7ec340bSmacallan
145f7ec340bSmacallanstatic Bool
146f7ec340bSmacallanCG14GetRec(ScrnInfoPtr pScrn)
147f7ec340bSmacallan{
148f7ec340bSmacallan    /*
149f7ec340bSmacallan     * Allocate an Cg14Rec, and hook it into pScrn->driverPrivate.
150f7ec340bSmacallan     * pScrn->driverPrivate is initialised to NULL, so we can check if
151f7ec340bSmacallan     * the allocation has already been done.
152f7ec340bSmacallan     */
153f7ec340bSmacallan    if (pScrn->driverPrivate != NULL)
154f7ec340bSmacallan	return TRUE;
155f7ec340bSmacallan
156f7ec340bSmacallan    pScrn->driverPrivate = xnfcalloc(sizeof(Cg14Rec), 1);
157f7ec340bSmacallan    return TRUE;
158f7ec340bSmacallan}
159f7ec340bSmacallan
160f7ec340bSmacallanstatic void
161f7ec340bSmacallanCG14FreeRec(ScrnInfoPtr pScrn)
162f7ec340bSmacallan{
163f7ec340bSmacallan    Cg14Ptr pCg14;
164f7ec340bSmacallan
165f7ec340bSmacallan    if (pScrn->driverPrivate == NULL)
166f7ec340bSmacallan	return;
167f7ec340bSmacallan
168f7ec340bSmacallan    pCg14 = GET_CG14_FROM_SCRN(pScrn);
169f7ec340bSmacallan
170f7ec340bSmacallan    xfree(pScrn->driverPrivate);
171f7ec340bSmacallan    pScrn->driverPrivate = NULL;
172f7ec340bSmacallan
173f7ec340bSmacallan    return;
174f7ec340bSmacallan}
175f7ec340bSmacallan
176f7ec340bSmacallanstatic const OptionInfoRec *
177f7ec340bSmacallanCG14AvailableOptions(int chipid, int busid)
178f7ec340bSmacallan{
179f7ec340bSmacallan    return CG14Options;
180f7ec340bSmacallan}
181f7ec340bSmacallan
182f7ec340bSmacallan/* Mandatory */
183f7ec340bSmacallanstatic void
184f7ec340bSmacallanCG14Identify(int flags)
185f7ec340bSmacallan{
186f7ec340bSmacallan    xf86Msg(X_INFO, "%s: driver for CG14\n", CG14_NAME);
187f7ec340bSmacallan}
188f7ec340bSmacallan
189f7ec340bSmacallan
190f7ec340bSmacallan/* Mandatory */
191f7ec340bSmacallanstatic Bool
192f7ec340bSmacallanCG14Probe(DriverPtr drv, int flags)
193f7ec340bSmacallan{
194f7ec340bSmacallan    int i;
195f7ec340bSmacallan    GDevPtr *devSections;
196f7ec340bSmacallan    int *usedChips;
197f7ec340bSmacallan    int numDevSections;
198f7ec340bSmacallan    int numUsed;
199f7ec340bSmacallan    Bool foundScreen = FALSE;
200f7ec340bSmacallan    EntityInfoPtr pEnt;
201f7ec340bSmacallan
202f7ec340bSmacallan    /*
203f7ec340bSmacallan     * The aim here is to find all cards that this driver can handle,
204f7ec340bSmacallan     * and for the ones not already claimed by another driver, claim the
205f7ec340bSmacallan     * slot, and allocate a ScrnInfoRec.
206f7ec340bSmacallan     *
207f7ec340bSmacallan     * This should be a minimal probe, and it should under no circumstances
208f7ec340bSmacallan     * change the state of the hardware.  Because a device is found, don't
209f7ec340bSmacallan     * assume that it will be used.  Don't do any initialisations other than
210f7ec340bSmacallan     * the required ScrnInfoRec initialisations.  Don't allocate any new
211f7ec340bSmacallan     * data structures.
212f7ec340bSmacallan     */
213f7ec340bSmacallan
214f7ec340bSmacallan    /*
215f7ec340bSmacallan     * Next we check, if there has been a chipset override in the config file.
216f7ec340bSmacallan     * For this we must find out if there is an active device section which
217f7ec340bSmacallan     * is relevant, i.e., which has no driver specified or has THIS driver
218f7ec340bSmacallan     * specified.
219f7ec340bSmacallan     */
220f7ec340bSmacallan
221f7ec340bSmacallan    if ((numDevSections = xf86MatchDevice(CG14_DRIVER_NAME,
222f7ec340bSmacallan					  &devSections)) <= 0) {
223f7ec340bSmacallan	/*
224f7ec340bSmacallan	 * There's no matching device section in the config file, so quit
225f7ec340bSmacallan	 * now.
226f7ec340bSmacallan	 */
227f7ec340bSmacallan	return FALSE;
228f7ec340bSmacallan    }
229f7ec340bSmacallan
230f7ec340bSmacallan    /*
231f7ec340bSmacallan     * We need to probe the hardware first.  We then need to see how this
232f7ec340bSmacallan     * fits in with what is given in the config file, and allow the config
233f7ec340bSmacallan     * file info to override any contradictions.
234f7ec340bSmacallan     */
235f7ec340bSmacallan
236f7ec340bSmacallan    numUsed = xf86MatchSbusInstances(CG14_NAME, SBUS_DEVICE_CG14,
237f7ec340bSmacallan		   devSections, numDevSections,
238f7ec340bSmacallan		   drv, &usedChips);
239f7ec340bSmacallan
240f7ec340bSmacallan    xfree(devSections);
241f7ec340bSmacallan    if (numUsed <= 0)
242f7ec340bSmacallan	return FALSE;
243f7ec340bSmacallan
244f7ec340bSmacallan    if (flags & PROBE_DETECT)
245f7ec340bSmacallan	foundScreen = TRUE;
246f7ec340bSmacallan    else for (i = 0; i < numUsed; i++) {
247f7ec340bSmacallan	pEnt = xf86GetEntityInfo(usedChips[i]);
248f7ec340bSmacallan
249f7ec340bSmacallan	/*
250f7ec340bSmacallan	 * Check that nothing else has claimed the slots.
251f7ec340bSmacallan	 */
252f7ec340bSmacallan	if(pEnt->active) {
253f7ec340bSmacallan	    ScrnInfoPtr pScrn;
254f7ec340bSmacallan
255f7ec340bSmacallan	    /* Allocate a ScrnInfoRec and claim the slot */
256f7ec340bSmacallan	    pScrn = xf86AllocateScreen(drv, 0);
257f7ec340bSmacallan
258f7ec340bSmacallan	    /* Fill in what we can of the ScrnInfoRec */
259f7ec340bSmacallan	    pScrn->driverVersion = CG14_VERSION;
260f7ec340bSmacallan	    pScrn->driverName	 = CG14_DRIVER_NAME;
261f7ec340bSmacallan	    pScrn->name		 = CG14_NAME;
262f7ec340bSmacallan	    pScrn->Probe	 = CG14Probe;
263f7ec340bSmacallan	    pScrn->PreInit	 = CG14PreInit;
264f7ec340bSmacallan	    pScrn->ScreenInit	 = CG14ScreenInit;
265f7ec340bSmacallan  	    pScrn->SwitchMode	 = CG14SwitchMode;
266f7ec340bSmacallan  	    pScrn->AdjustFrame	 = CG14AdjustFrame;
267f7ec340bSmacallan	    pScrn->EnterVT	 = CG14EnterVT;
268f7ec340bSmacallan	    pScrn->LeaveVT	 = CG14LeaveVT;
269f7ec340bSmacallan	    pScrn->FreeScreen	 = CG14FreeScreen;
270f7ec340bSmacallan	    pScrn->ValidMode	 = CG14ValidMode;
271f7ec340bSmacallan	    xf86AddEntityToScreen(pScrn, pEnt->index);
272f7ec340bSmacallan	    foundScreen = TRUE;
273f7ec340bSmacallan	}
274f7ec340bSmacallan	xfree(pEnt);
275f7ec340bSmacallan    }
276f7ec340bSmacallan    xfree(usedChips);
277f7ec340bSmacallan    return foundScreen;
278f7ec340bSmacallan}
279f7ec340bSmacallan
280f7ec340bSmacallan/* Mandatory */
281f7ec340bSmacallanstatic Bool
282f7ec340bSmacallanCG14PreInit(ScrnInfoPtr pScrn, int flags)
283f7ec340bSmacallan{
284f7ec340bSmacallan    Cg14Ptr pCg14;
285f7ec340bSmacallan    sbusDevicePtr psdp = NULL;
286f7ec340bSmacallan    int i;
287f7ec340bSmacallan
288f7ec340bSmacallan    if (flags & PROBE_DETECT) return FALSE;
289f7ec340bSmacallan
290f7ec340bSmacallan    /*
291f7ec340bSmacallan     * Note: This function is only called once at server startup, and
292f7ec340bSmacallan     * not at the start of each server generation.  This means that
293f7ec340bSmacallan     * only things that are persistent across server generations can
294f7ec340bSmacallan     * be initialised here.  xf86Screens[] is (pScrn is a pointer to one
295f7ec340bSmacallan     * of these).  Privates allocated using xf86AllocateScrnInfoPrivateIndex()
296f7ec340bSmacallan     * are too, and should be used for data that must persist across
297f7ec340bSmacallan     * server generations.
298f7ec340bSmacallan     *
299f7ec340bSmacallan     * Per-generation data should be allocated with
300f7ec340bSmacallan     * AllocateScreenPrivateIndex() from the ScreenInit() function.
301f7ec340bSmacallan     */
302f7ec340bSmacallan
303f7ec340bSmacallan    /* Allocate the Cg14Rec driverPrivate */
304f7ec340bSmacallan    if (!CG14GetRec(pScrn)) {
305f7ec340bSmacallan	return FALSE;
306f7ec340bSmacallan    }
307f7ec340bSmacallan    pCg14 = GET_CG14_FROM_SCRN(pScrn);
308f7ec340bSmacallan
309f7ec340bSmacallan    /* Set pScrn->monitor */
310f7ec340bSmacallan    pScrn->monitor = pScrn->confScreen->monitor;
311f7ec340bSmacallan
312f7ec340bSmacallan    /* This driver doesn't expect more than one entity per screen */
313f7ec340bSmacallan    if (pScrn->numEntities > 1)
314f7ec340bSmacallan	return FALSE;
315f7ec340bSmacallan    /* This is the general case */
316f7ec340bSmacallan    for (i = 0; i < pScrn->numEntities; i++) {
317f7ec340bSmacallan	EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[i]);
318f7ec340bSmacallan
319f7ec340bSmacallan	/* CG14 is purely AFX, but we handle it like SBUS */
320f7ec340bSmacallan	if (pEnt->location.type == BUS_SBUS) {
321f7ec340bSmacallan	    psdp = xf86GetSbusInfoForEntity(pEnt->index);
322f7ec340bSmacallan	    pCg14->psdp = psdp;
323f7ec340bSmacallan	} else
324f7ec340bSmacallan	    return FALSE;
325f7ec340bSmacallan    }
326f7ec340bSmacallan    if (psdp == NULL)
327f7ec340bSmacallan	return FALSE;
328f7ec340bSmacallan
329f7ec340bSmacallan    /*********************
330f7ec340bSmacallan    deal with depth
331f7ec340bSmacallan    *********************/
332f7ec340bSmacallan
333b73528caSmacallan    if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb|Support32bppFb))
334b73528caSmacallan		return FALSE;
335b73528caSmacallan    /* Check that the returned depth is one we support */
336b73528caSmacallan    switch (pScrn->depth) {
337f7ec340bSmacallan	case 32:
338b73528caSmacallan	case 24:
339f7ec340bSmacallan	    /* OK */
340f7ec340bSmacallan	    break;
341f7ec340bSmacallan	default:
342f7ec340bSmacallan	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
343f7ec340bSmacallan		       "Given depth (%d) is not supported by this driver\n",
344f7ec340bSmacallan		       pScrn->depth);
345f7ec340bSmacallan	    return FALSE;
346f7ec340bSmacallan    }
347f7ec340bSmacallan
348f7ec340bSmacallan    /* Collect all of the relevant option flags (fill in pScrn->options) */
349f7ec340bSmacallan    xf86CollectOptions(pScrn, NULL);
350f7ec340bSmacallan    /* Process the options */
351f7ec340bSmacallan    if (!(pCg14->Options = xalloc(sizeof(CG14Options))))
352f7ec340bSmacallan	return FALSE;
353f7ec340bSmacallan    memcpy(pCg14->Options, CG14Options, sizeof(CG14Options));
354f7ec340bSmacallan    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pCg14->Options);
355f7ec340bSmacallan
356f7ec340bSmacallan    /*
357f7ec340bSmacallan     * This must happen after pScrn->display has been set because
358f7ec340bSmacallan     * xf86SetWeight references it.
359f7ec340bSmacallan     */
360f7ec340bSmacallan    if (pScrn->depth > 8) {
361b73528caSmacallan	rgb weight = {0, 0, 0};
362f7ec340bSmacallan	rgb mask = {0xff, 0xff00, 0xff0000};
363f7ec340bSmacallan
364f7ec340bSmacallan	if (!xf86SetWeight(pScrn, weight, mask)) {
365f7ec340bSmacallan	    return FALSE;
366f7ec340bSmacallan	}
367f7ec340bSmacallan    }
368f7ec340bSmacallan
369f7ec340bSmacallan    if (!xf86SetDefaultVisual(pScrn, -1))
370f7ec340bSmacallan	return FALSE;
371f7ec340bSmacallan    else if (pScrn->depth > 8) {
372f7ec340bSmacallan	/* We don't currently support DirectColor */
373f7ec340bSmacallan	if (pScrn->defaultVisual != TrueColor) {
374f7ec340bSmacallan	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
375f7ec340bSmacallan		       " (%s) is not supported\n",
376f7ec340bSmacallan		       xf86GetVisualName(pScrn->defaultVisual));
377f7ec340bSmacallan	    return FALSE;
378f7ec340bSmacallan	}
379f7ec340bSmacallan    }
380f7ec340bSmacallan
381f7ec340bSmacallan    /*
382f7ec340bSmacallan     * The new cmap code requires this to be initialised.
383f7ec340bSmacallan     */
384f7ec340bSmacallan
385f7ec340bSmacallan    {
386f7ec340bSmacallan	Gamma zeros = {0.0, 0.0, 0.0};
387f7ec340bSmacallan
388f7ec340bSmacallan	if (!xf86SetGamma(pScrn, zeros)) {
389f7ec340bSmacallan	    return FALSE;
390f7ec340bSmacallan	}
391f7ec340bSmacallan    }
392f7ec340bSmacallan
393f7ec340bSmacallan    if (xf86LoadSubModule(pScrn, "fb") == NULL) {
394f7ec340bSmacallan	CG14FreeRec(pScrn);
395f7ec340bSmacallan	return FALSE;
396f7ec340bSmacallan    }
397f7ec340bSmacallan
398f7ec340bSmacallan    /*********************
399f7ec340bSmacallan    set up clock and mode stuff
400f7ec340bSmacallan    *********************/
401f7ec340bSmacallan
402f7ec340bSmacallan    pScrn->progClock = TRUE;
403f7ec340bSmacallan
404f7ec340bSmacallan    if(pScrn->display->virtualX || pScrn->display->virtualY) {
405f7ec340bSmacallan	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
406f7ec340bSmacallan		   "CG14 does not support a virtual desktop\n");
407f7ec340bSmacallan	pScrn->display->virtualX = 0;
408f7ec340bSmacallan	pScrn->display->virtualY = 0;
409f7ec340bSmacallan    }
410f7ec340bSmacallan
411f7ec340bSmacallan    xf86SbusUseBuiltinMode(pScrn, pCg14->psdp);
412f7ec340bSmacallan    pScrn->currentMode = pScrn->modes;
413f7ec340bSmacallan    pScrn->displayWidth = pScrn->virtualX;
414f7ec340bSmacallan
415f7ec340bSmacallan    /* Set display resolution */
416f7ec340bSmacallan    xf86SetDpi(pScrn, 0, 0);
417f7ec340bSmacallan
418f7ec340bSmacallan    return TRUE;
419f7ec340bSmacallan}
420f7ec340bSmacallan
421f7ec340bSmacallan/* Mandatory */
422f7ec340bSmacallan
423f7ec340bSmacallan/* This gets called at the start of each server generation */
424f7ec340bSmacallan
425f7ec340bSmacallanstatic Bool
426f7ec340bSmacallanCG14ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
427f7ec340bSmacallan{
428f7ec340bSmacallan    ScrnInfoPtr pScrn;
429f7ec340bSmacallan    Cg14Ptr pCg14;
430f7ec340bSmacallan    VisualPtr visual;
431f7ec340bSmacallan    int ret;
432f7ec340bSmacallan
433f7ec340bSmacallan    /*
434f7ec340bSmacallan     * First get the ScrnInfoRec
435f7ec340bSmacallan     */
436f7ec340bSmacallan    pScrn = xf86Screens[pScreen->myNum];
437f7ec340bSmacallan
438f7ec340bSmacallan    pCg14 = GET_CG14_FROM_SCRN(pScrn);
439f7ec340bSmacallan
440f7ec340bSmacallan    /* Map the CG14 memory */
441f7ec340bSmacallan    pCg14->fb = xf86MapSbusMem (pCg14->psdp, CG14_BGR_VOFF, 4 *
442f7ec340bSmacallan				(pCg14->psdp->width * pCg14->psdp->height));
443f7ec340bSmacallan    pCg14->x32 = xf86MapSbusMem (pCg14->psdp, CG14_X32_VOFF,
444f7ec340bSmacallan				 (pCg14->psdp->width * pCg14->psdp->height));
445f7ec340bSmacallan    pCg14->xlut = xf86MapSbusMem (pCg14->psdp, CG14_XLUT_VOFF, 4096);
446f7ec340bSmacallan
447b73528caSmacallan    if (! pCg14->fb || !pCg14->x32 || !pCg14->xlut) {
448b73528caSmacallan    	xf86Msg(X_ERROR, "can't mmap something: fd %08x  x32 %08x xlut %08x\n",
449b73528caSmacallan	    (uint32_t)pCg14->fb, (uint32_t)pCg14->x32, (uint32_t)pCg14->xlut);
450f7ec340bSmacallan	return FALSE;
451b73528caSmacallan    }
452f7ec340bSmacallan
453f7ec340bSmacallan    /* Darken the screen for aesthetic reasons and set the viewport */
454f7ec340bSmacallan    CG14SaveScreen(pScreen, SCREEN_SAVER_ON);
455f7ec340bSmacallan
456f7ec340bSmacallan    /*
457f7ec340bSmacallan     * The next step is to setup the screen's visuals, and initialise the
458f7ec340bSmacallan     * framebuffer code.  In cases where the framebuffer's default
459f7ec340bSmacallan     * choices for things like visual layouts and bits per RGB are OK,
460f7ec340bSmacallan     * this may be as simple as calling the framebuffer's ScreenInit()
461f7ec340bSmacallan     * function.  If not, the visuals will need to be setup before calling
462f7ec340bSmacallan     * a fb ScreenInit() function and fixed up after.
463f7ec340bSmacallan     */
464f7ec340bSmacallan
465f7ec340bSmacallan    /*
466f7ec340bSmacallan     * Reset visual list.
467f7ec340bSmacallan     */
468f7ec340bSmacallan    miClearVisualTypes();
469f7ec340bSmacallan
470f7ec340bSmacallan    /* Setup the visuals we support. */
471f7ec340bSmacallan
472f7ec340bSmacallan    if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
473f7ec340bSmacallan			  pScrn->rgbBits, pScrn->defaultVisual))
474f7ec340bSmacallan	return FALSE;
475f7ec340bSmacallan
476f7ec340bSmacallan    miSetPixmapDepths ();
477f7ec340bSmacallan
478f7ec340bSmacallan    /*
479f7ec340bSmacallan     * Call the framebuffer layer's ScreenInit function, and fill in other
480f7ec340bSmacallan     * pScreen fields.
481f7ec340bSmacallan     */
482f7ec340bSmacallan
483f7ec340bSmacallan    CG14InitCplane24(pScrn);
484f7ec340bSmacallan    ret = fbScreenInit(pScreen, pCg14->fb, pScrn->virtualX,
485f7ec340bSmacallan		       pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
486f7ec340bSmacallan		       pScrn->virtualX, pScrn->bitsPerPixel);
487f7ec340bSmacallan
488f7ec340bSmacallan    if (!ret)
489f7ec340bSmacallan	return FALSE;
490f7ec340bSmacallan
491f7ec340bSmacallan    miInitializeBackingStore(pScreen);
492f7ec340bSmacallan    xf86SetBackingStore(pScreen);
493f7ec340bSmacallan    xf86SetSilkenMouse(pScreen);
494f7ec340bSmacallan
495f7ec340bSmacallan    xf86SetBlackWhitePixels(pScreen);
496f7ec340bSmacallan
497f7ec340bSmacallan    if (pScrn->bitsPerPixel > 8) {
498f7ec340bSmacallan	/* Fixup RGB ordering */
499f7ec340bSmacallan	visual = pScreen->visuals + pScreen->numVisuals;
500f7ec340bSmacallan	while (--visual >= pScreen->visuals) {
501f7ec340bSmacallan	    if ((visual->class | DynamicClass) == DirectColor) {
502f7ec340bSmacallan		visual->offsetRed = pScrn->offset.red;
503f7ec340bSmacallan		visual->offsetGreen = pScrn->offset.green;
504f7ec340bSmacallan		visual->offsetBlue = pScrn->offset.blue;
505f7ec340bSmacallan		visual->redMask = pScrn->mask.red;
506f7ec340bSmacallan		visual->greenMask = pScrn->mask.green;
507f7ec340bSmacallan		visual->blueMask = pScrn->mask.blue;
508f7ec340bSmacallan	    }
509f7ec340bSmacallan	}
510f7ec340bSmacallan    }
511f7ec340bSmacallan
512f7ec340bSmacallan#ifdef RENDER
513f7ec340bSmacallan    /* must be after RGB ordering fixed */
514f7ec340bSmacallan    fbPictureInit (pScreen, 0, 0);
515f7ec340bSmacallan#endif
516f7ec340bSmacallan
517f7ec340bSmacallan    /* Initialise cursor functions */
518f7ec340bSmacallan    miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
519f7ec340bSmacallan
520f7ec340bSmacallan    /* Initialise default colourmap */
521f7ec340bSmacallan    if (!miCreateDefColormap(pScreen))
522f7ec340bSmacallan	return FALSE;
523f7ec340bSmacallan
524f7ec340bSmacallan    pCg14->CloseScreen = pScreen->CloseScreen;
525f7ec340bSmacallan    pScreen->CloseScreen = CG14CloseScreen;
526f7ec340bSmacallan    pScreen->SaveScreen = CG14SaveScreen;
527f7ec340bSmacallan
528f7ec340bSmacallan    /* Report any unused options (only for the first generation) */
529f7ec340bSmacallan    if (serverGeneration == 1) {
530f7ec340bSmacallan	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
531f7ec340bSmacallan    }
532f7ec340bSmacallan
533f7ec340bSmacallan    /* unblank the screen */
534f7ec340bSmacallan    CG14SaveScreen(pScreen, SCREEN_SAVER_OFF);
535f7ec340bSmacallan
536f7ec340bSmacallan    /* Done */
537f7ec340bSmacallan    return TRUE;
538f7ec340bSmacallan}
539f7ec340bSmacallan
540f7ec340bSmacallan
541f7ec340bSmacallan/* Usually mandatory */
542f7ec340bSmacallanstatic Bool
543f7ec340bSmacallanCG14SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
544f7ec340bSmacallan{
545b73528caSmacallan    xf86Msg(X_ERROR, "CG14SwitchMode\n");
546f7ec340bSmacallan    return TRUE;
547f7ec340bSmacallan}
548f7ec340bSmacallan
549f7ec340bSmacallan
550f7ec340bSmacallan/*
551f7ec340bSmacallan * This function is used to initialize the Start Address - the first
552f7ec340bSmacallan * displayed location in the video memory.
553f7ec340bSmacallan */
554f7ec340bSmacallan/* Usually mandatory */
555f7ec340bSmacallanstatic void
556f7ec340bSmacallanCG14AdjustFrame(int scrnIndex, int x, int y, int flags)
557f7ec340bSmacallan{
558f7ec340bSmacallan    /* we don't support virtual desktops */
559f7ec340bSmacallan    return;
560f7ec340bSmacallan}
561f7ec340bSmacallan
562f7ec340bSmacallan/*
563f7ec340bSmacallan * This is called when VT switching back to the X server.  Its job is
564f7ec340bSmacallan * to reinitialise the video mode.
565f7ec340bSmacallan */
566f7ec340bSmacallan
567f7ec340bSmacallan/* Mandatory */
568f7ec340bSmacallanstatic Bool
569f7ec340bSmacallanCG14EnterVT(int scrnIndex, int flags)
570f7ec340bSmacallan{
571f7ec340bSmacallan    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
572f7ec340bSmacallan
573f7ec340bSmacallan    CG14InitCplane24 (pScrn);
574f7ec340bSmacallan    return TRUE;
575f7ec340bSmacallan}
576f7ec340bSmacallan
577f7ec340bSmacallan
578f7ec340bSmacallan/*
579f7ec340bSmacallan * This is called when VT switching away from the X server.
580f7ec340bSmacallan */
581f7ec340bSmacallan
582f7ec340bSmacallan/* Mandatory */
583f7ec340bSmacallanstatic void
584f7ec340bSmacallanCG14LeaveVT(int scrnIndex, int flags)
585f7ec340bSmacallan{
586f7ec340bSmacallan    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
587f7ec340bSmacallan
588f7ec340bSmacallan    CG14ExitCplane24 (pScrn);
589f7ec340bSmacallan    return;
590f7ec340bSmacallan}
591f7ec340bSmacallan
592f7ec340bSmacallan
593f7ec340bSmacallan/*
594f7ec340bSmacallan * This is called at the end of each server generation.  It restores the
595f7ec340bSmacallan * original (text) mode.  It should really also unmap the video memory too.
596f7ec340bSmacallan */
597f7ec340bSmacallan
598f7ec340bSmacallan/* Mandatory */
599f7ec340bSmacallanstatic Bool
600f7ec340bSmacallanCG14CloseScreen(int scrnIndex, ScreenPtr pScreen)
601f7ec340bSmacallan{
602f7ec340bSmacallan    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
603f7ec340bSmacallan    Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn);
604f7ec340bSmacallan
605f7ec340bSmacallan    pScrn->vtSema = FALSE;
606b73528caSmacallan    CG14ExitCplane24 (pScrn);
607f7ec340bSmacallan    xf86UnmapSbusMem(pCg14->psdp, pCg14->fb,
608f7ec340bSmacallan		     (pCg14->psdp->width * pCg14->psdp->height * 4));
609f7ec340bSmacallan    xf86UnmapSbusMem(pCg14->psdp, pCg14->x32,
610f7ec340bSmacallan		     (pCg14->psdp->width * pCg14->psdp->height));
611f7ec340bSmacallan    xf86UnmapSbusMem(pCg14->psdp, pCg14->xlut, 4096);
612f7ec340bSmacallan
613f7ec340bSmacallan    pScreen->CloseScreen = pCg14->CloseScreen;
614f7ec340bSmacallan    return (*pScreen->CloseScreen)(scrnIndex, pScreen);
615f7ec340bSmacallan    return FALSE;
616f7ec340bSmacallan}
617f7ec340bSmacallan
618f7ec340bSmacallan
619f7ec340bSmacallan/* Free up any per-generation data structures */
620f7ec340bSmacallan
621f7ec340bSmacallan/* Optional */
622f7ec340bSmacallanstatic void
623f7ec340bSmacallanCG14FreeScreen(int scrnIndex, int flags)
624f7ec340bSmacallan{
625f7ec340bSmacallan    CG14FreeRec(xf86Screens[scrnIndex]);
626f7ec340bSmacallan}
627f7ec340bSmacallan
628f7ec340bSmacallan
629f7ec340bSmacallan/* Checks if a mode is suitable for the selected chipset. */
630f7ec340bSmacallan
631f7ec340bSmacallan/* Optional */
632f7ec340bSmacallanstatic ModeStatus
633f7ec340bSmacallanCG14ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
634f7ec340bSmacallan{
635f7ec340bSmacallan    if (mode->Flags & V_INTERLACE)
636f7ec340bSmacallan	return(MODE_BAD);
637f7ec340bSmacallan
638f7ec340bSmacallan    return(MODE_OK);
639f7ec340bSmacallan}
640f7ec340bSmacallan
641f7ec340bSmacallan/* Do screen blanking */
642f7ec340bSmacallan
643f7ec340bSmacallan/* Mandatory */
644f7ec340bSmacallanstatic Bool
645f7ec340bSmacallanCG14SaveScreen(ScreenPtr pScreen, int mode)
646f7ec340bSmacallan{
6471bd6d369Smacallan    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
6481bd6d369Smacallan    Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn);
6491bd6d369Smacallan    int state;
6501bd6d369Smacallan    switch(mode) {
6511bd6d369Smacallan	case SCREEN_SAVER_ON:
6521bd6d369Smacallan	case SCREEN_SAVER_CYCLE:
6531bd6d369Smacallan		state = FBVIDEO_OFF;
6541bd6d369Smacallan		ioctl(pCg14->psdp->fd, FBIOSVIDEO, &state);
6551bd6d369Smacallan		break;
6561bd6d369Smacallan	case SCREEN_SAVER_OFF:
6571bd6d369Smacallan	case SCREEN_SAVER_FORCER:
6581bd6d369Smacallan		state = FBVIDEO_ON;
6591bd6d369Smacallan		ioctl(pCg14->psdp->fd, FBIOSVIDEO, &state);
6601bd6d369Smacallan		break;
6611bd6d369Smacallan	default:
6621bd6d369Smacallan		return FALSE;
6631bd6d369Smacallan    }
664f7ec340bSmacallan    return TRUE;
665f7ec340bSmacallan}
666f7ec340bSmacallan
667f7ec340bSmacallan/*
668f7ec340bSmacallan * This is the implementation of the Sync() function.
669f7ec340bSmacallan */
670f7ec340bSmacallanvoid
671f7ec340bSmacallanCG14Sync(ScrnInfoPtr pScrn)
672f7ec340bSmacallan{
673f7ec340bSmacallan    return;
674f7ec340bSmacallan}
675f7ec340bSmacallan
676f7ec340bSmacallan/*
677f7ec340bSmacallan * This initializes the card for 24 bit mode.
678f7ec340bSmacallan */
679f7ec340bSmacallanstatic void
680f7ec340bSmacallanCG14InitCplane24(ScrnInfoPtr pScrn)
681f7ec340bSmacallan{
682f7ec340bSmacallan  Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn);
683f7ec340bSmacallan  int size, bpp;
684f7ec340bSmacallan
685f7ec340bSmacallan  size = pScrn->virtualX * pScrn->virtualY;
686f7ec340bSmacallan  bpp = 32;
687f7ec340bSmacallan  ioctl (pCg14->psdp->fd, CG14_SET_PIXELMODE, &bpp);
688f7ec340bSmacallan  memset (pCg14->fb, 0, size * 4);
689f7ec340bSmacallan  memset (pCg14->x32, 0, size);
690f7ec340bSmacallan  memset (pCg14->xlut, 0, 0x200);
691f7ec340bSmacallan}
692f7ec340bSmacallan
693f7ec340bSmacallan/*
694f7ec340bSmacallan * This initializes the card for 8 bit mode.
695f7ec340bSmacallan */
696f7ec340bSmacallanstatic void
697f7ec340bSmacallanCG14ExitCplane24(ScrnInfoPtr pScrn)
698f7ec340bSmacallan{
699f7ec340bSmacallan  Cg14Ptr pCg14 = GET_CG14_FROM_SCRN(pScrn);
700f7ec340bSmacallan  int bpp = 8;
701f7ec340bSmacallan
702f7ec340bSmacallan  ioctl (pCg14->psdp->fd, CG14_SET_PIXELMODE, &bpp);
7031bd6d369Smacallan}
704