ngle_driver.c revision a7fd8e5e
1a7fd8e5eSmacallan/* $NetBSD: ngle_driver.c,v 1.1 2024/10/16 11:00:36 macallan Exp $ */
2a7fd8e5eSmacallan/*
3a7fd8e5eSmacallan * Copyright (c) 2024 Michael Lorenz
4a7fd8e5eSmacallan * All rights reserved.
5a7fd8e5eSmacallan *
6a7fd8e5eSmacallan * Redistribution and use in source and binary forms, with or without
7a7fd8e5eSmacallan * modification, are permitted provided that the following conditions
8a7fd8e5eSmacallan * are met:
9a7fd8e5eSmacallan *
10a7fd8e5eSmacallan *    - Redistributions of source code must retain the above copyright
11a7fd8e5eSmacallan *      notice, this list of conditions and the following disclaimer.
12a7fd8e5eSmacallan *    - Redistributions in binary form must reproduce the above
13a7fd8e5eSmacallan *      copyright notice, this list of conditions and the following
14a7fd8e5eSmacallan *      disclaimer in the documentation and/or other materials provided
15a7fd8e5eSmacallan *      with the distribution.
16a7fd8e5eSmacallan *
17a7fd8e5eSmacallan * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18a7fd8e5eSmacallan * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19a7fd8e5eSmacallan * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20a7fd8e5eSmacallan * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21a7fd8e5eSmacallan * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22a7fd8e5eSmacallan * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23a7fd8e5eSmacallan * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24a7fd8e5eSmacallan * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25a7fd8e5eSmacallan * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26a7fd8e5eSmacallan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27a7fd8e5eSmacallan * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28a7fd8e5eSmacallan * POSSIBILITY OF SUCH DAMAGE.
29a7fd8e5eSmacallan *
30a7fd8e5eSmacallan */
31a7fd8e5eSmacallan
32a7fd8e5eSmacallan/* a driver for HP's NGLE family of graphics chips */
33a7fd8e5eSmacallan
34a7fd8e5eSmacallan#ifdef HAVE_CONFIG_H
35a7fd8e5eSmacallan#include "config.h"
36a7fd8e5eSmacallan#endif
37a7fd8e5eSmacallan#include <sys/types.h>
38a7fd8e5eSmacallan#include <dev/ic/stireg.h>
39a7fd8e5eSmacallan
40a7fd8e5eSmacallan#include <fcntl.h>
41a7fd8e5eSmacallan#include <errno.h>
42a7fd8e5eSmacallan#include <sys/time.h>
43a7fd8e5eSmacallan#include <sys/mman.h>
44a7fd8e5eSmacallan#include <sys/ioctl.h>
45a7fd8e5eSmacallan#include <dev/wscons/wsconsio.h>
46a7fd8e5eSmacallan
47a7fd8e5eSmacallan/* all driver need this */
48a7fd8e5eSmacallan#include "xf86.h"
49a7fd8e5eSmacallan#include "xf86_OSproc.h"
50a7fd8e5eSmacallan
51a7fd8e5eSmacallan#include "mipointer.h"
52a7fd8e5eSmacallan#include "micmap.h"
53a7fd8e5eSmacallan#include "colormapst.h"
54a7fd8e5eSmacallan#include "xf86cmap.h"
55a7fd8e5eSmacallan#ifdef XvExtension
56a7fd8e5eSmacallan#include "xf86xv.h"
57a7fd8e5eSmacallan#endif
58a7fd8e5eSmacallan
59a7fd8e5eSmacallan/* for visuals */
60a7fd8e5eSmacallan#include "fb.h"
61a7fd8e5eSmacallan
62a7fd8e5eSmacallan#include "ngle.h"
63a7fd8e5eSmacallan
64a7fd8e5eSmacallan/* #include "wsconsio.h" */
65a7fd8e5eSmacallan
66a7fd8e5eSmacallan#define NGLE_DEFAULT_DEV "/dev/ttyE0"
67a7fd8e5eSmacallan
68a7fd8e5eSmacallanstatic pointer NGLESetup(pointer, pointer, int *, int *);
69a7fd8e5eSmacallanstatic Bool NGLEGetRec(ScrnInfoPtr);
70a7fd8e5eSmacallanstatic void NGLEFreeRec(ScrnInfoPtr);
71a7fd8e5eSmacallanstatic const OptionInfoRec * NGLEAvailableOptions(int, int);
72a7fd8e5eSmacallanstatic void NGLEIdentify(int);
73a7fd8e5eSmacallanstatic Bool NGLEProbe(DriverPtr, int);
74a7fd8e5eSmacallanstatic Bool NGLEPreInit(ScrnInfoPtr, int);
75a7fd8e5eSmacallanstatic Bool NGLEScreenInit(SCREEN_INIT_ARGS_DECL);
76a7fd8e5eSmacallanstatic Bool NGLECloseScreen(CLOSE_SCREEN_ARGS_DECL);
77a7fd8e5eSmacallanstatic Bool NGLEEnterVT(VT_FUNC_ARGS_DECL);
78a7fd8e5eSmacallanstatic void NGLELeaveVT(VT_FUNC_ARGS_DECL);
79a7fd8e5eSmacallanstatic Bool NGLESwitchMode(SWITCH_MODE_ARGS_DECL);
80a7fd8e5eSmacallanstatic int NGLEValidMode(SCRN_ARG_TYPE, DisplayModePtr, Bool, int);
81a7fd8e5eSmacallanstatic void NGLELoadPalette(ScrnInfoPtr, int, int *, LOCO *, VisualPtr);
82a7fd8e5eSmacallanstatic Bool NGLESaveScreen(ScreenPtr, int);
83a7fd8e5eSmacallanstatic void NGLESave(ScrnInfoPtr);
84a7fd8e5eSmacallanstatic void NGLERestore(ScrnInfoPtr);
85a7fd8e5eSmacallan
86a7fd8e5eSmacallan/* helper functions */
87a7fd8e5eSmacallanstatic int ngle_open(const char *);
88a7fd8e5eSmacallanstatic pointer ngle_mmap(size_t, off_t, int, int);
89a7fd8e5eSmacallan
90a7fd8e5eSmacallan#define VERSION			4000
91a7fd8e5eSmacallan#define NGLE_NAME		"ngle"
92a7fd8e5eSmacallan#define NGLE_DRIVER_NAME	"ngle"
93a7fd8e5eSmacallan#define NGLE_MAJOR_VERSION	0
94a7fd8e5eSmacallan#define NGLE_MINOR_VERSION	1
95a7fd8e5eSmacallan
96a7fd8e5eSmacallanDriverRec NGLE = {
97a7fd8e5eSmacallan	VERSION,
98a7fd8e5eSmacallan	NGLE_DRIVER_NAME,
99a7fd8e5eSmacallan	NGLEIdentify,
100a7fd8e5eSmacallan	NGLEProbe,
101a7fd8e5eSmacallan	NGLEAvailableOptions,
102a7fd8e5eSmacallan	NULL,
103a7fd8e5eSmacallan	0
104a7fd8e5eSmacallan};
105a7fd8e5eSmacallan
106a7fd8e5eSmacallan/* Supported "chipsets" */
107a7fd8e5eSmacallanstatic SymTabRec NGLEChipsets[] = {
108a7fd8e5eSmacallan	{ STI_DD_EG, "Visualize EG" },
109a7fd8e5eSmacallan	{ STI_DD_HCRX, "HCRX" },
110a7fd8e5eSmacallan	{ -1, NULL }
111a7fd8e5eSmacallan};
112a7fd8e5eSmacallan
113a7fd8e5eSmacallan/* Supported options */
114a7fd8e5eSmacallantypedef enum {
115a7fd8e5eSmacallan	OPTION_HW_CURSOR,
116a7fd8e5eSmacallan	OPTION_SW_CURSOR
117a7fd8e5eSmacallan} NGLEOpts;
118a7fd8e5eSmacallan
119a7fd8e5eSmacallanstatic const OptionInfoRec NGLEOptions[] = {
120a7fd8e5eSmacallan	{ OPTION_SW_CURSOR, "SWcursor",	OPTV_BOOLEAN,	{0}, FALSE },
121a7fd8e5eSmacallan	{ OPTION_HW_CURSOR, "HWcursor",	OPTV_BOOLEAN,	{0}, FALSE },
122a7fd8e5eSmacallan	{ -1, NULL, OPTV_NONE, {0}, FALSE}
123a7fd8e5eSmacallan};
124a7fd8e5eSmacallan
125a7fd8e5eSmacallanstatic XF86ModuleVersionInfo NGLEVersRec = {
126a7fd8e5eSmacallan	"ngle",
127a7fd8e5eSmacallan	"The NetBSD Foundation",
128a7fd8e5eSmacallan	MODINFOSTRING1,
129a7fd8e5eSmacallan	MODINFOSTRING2,
130a7fd8e5eSmacallan	XORG_VERSION_CURRENT,
131a7fd8e5eSmacallan	NGLE_MAJOR_VERSION, NGLE_MINOR_VERSION, 0,
132a7fd8e5eSmacallan	ABI_CLASS_VIDEODRV,
133a7fd8e5eSmacallan	ABI_VIDEODRV_VERSION,
134a7fd8e5eSmacallan	NULL,
135a7fd8e5eSmacallan	{0, 0, 0, 0}
136a7fd8e5eSmacallan};
137a7fd8e5eSmacallan
138a7fd8e5eSmacallan_X_EXPORT XF86ModuleData ngleModuleData = { &NGLEVersRec, NGLESetup, NULL };
139a7fd8e5eSmacallan
140a7fd8e5eSmacallanstatic pointer
141a7fd8e5eSmacallanNGLESetup(pointer module, pointer opts, int *errmaj, int *errmin)
142a7fd8e5eSmacallan{
143a7fd8e5eSmacallan	static Bool setupDone = FALSE;
144a7fd8e5eSmacallan	const char *osname;
145a7fd8e5eSmacallan
146a7fd8e5eSmacallan	if (!setupDone) {
147a7fd8e5eSmacallan		setupDone = TRUE;
148a7fd8e5eSmacallan		xf86AddDriver(&NGLE, module, 0);
149a7fd8e5eSmacallan		return (pointer)1;
150a7fd8e5eSmacallan	} else {
151a7fd8e5eSmacallan		if (errmaj != NULL)
152a7fd8e5eSmacallan			*errmaj = LDR_ONCEONLY;
153a7fd8e5eSmacallan		return NULL;
154a7fd8e5eSmacallan	}
155a7fd8e5eSmacallan}
156a7fd8e5eSmacallan
157a7fd8e5eSmacallanstatic Bool
158a7fd8e5eSmacallanNGLEGetRec(ScrnInfoPtr pScrn)
159a7fd8e5eSmacallan{
160a7fd8e5eSmacallan
161a7fd8e5eSmacallan	if (pScrn->driverPrivate != NULL)
162a7fd8e5eSmacallan		return TRUE;
163a7fd8e5eSmacallan
164a7fd8e5eSmacallan	pScrn->driverPrivate = xnfcalloc(sizeof(NGLERec), 1);
165a7fd8e5eSmacallan	return TRUE;
166a7fd8e5eSmacallan}
167a7fd8e5eSmacallan
168a7fd8e5eSmacallanstatic void
169a7fd8e5eSmacallanNGLEFreeRec(ScrnInfoPtr pScrn)
170a7fd8e5eSmacallan{
171a7fd8e5eSmacallan
172a7fd8e5eSmacallan	if (pScrn->driverPrivate == NULL)
173a7fd8e5eSmacallan		return;
174a7fd8e5eSmacallan	free(pScrn->driverPrivate);
175a7fd8e5eSmacallan	pScrn->driverPrivate = NULL;
176a7fd8e5eSmacallan}
177a7fd8e5eSmacallan
178a7fd8e5eSmacallanstatic const OptionInfoRec *
179a7fd8e5eSmacallanNGLEAvailableOptions(int chipid, int busid)
180a7fd8e5eSmacallan{
181a7fd8e5eSmacallan	return NGLEOptions;
182a7fd8e5eSmacallan}
183a7fd8e5eSmacallan
184a7fd8e5eSmacallanstatic void
185a7fd8e5eSmacallanNGLEIdentify(int flags)
186a7fd8e5eSmacallan{
187a7fd8e5eSmacallan	xf86PrintChipsets(NGLE_NAME, "driver for NGLE framebuffers",
188a7fd8e5eSmacallan			  NGLEChipsets);
189a7fd8e5eSmacallan}
190a7fd8e5eSmacallan
191a7fd8e5eSmacallan
192a7fd8e5eSmacallan#define priv_open_device(n)	open(n,O_RDWR|O_NONBLOCK|O_EXCL)
193a7fd8e5eSmacallan
194a7fd8e5eSmacallan/* Open the framebuffer device */
195a7fd8e5eSmacallanstatic int
196a7fd8e5eSmacallanngle_open(const char *dev)
197a7fd8e5eSmacallan{
198a7fd8e5eSmacallan	int fd = -1;
199a7fd8e5eSmacallan
200a7fd8e5eSmacallan	/* try argument from XF86Config first */
201a7fd8e5eSmacallan	if (dev == NULL || ((fd = priv_open_device(dev)) == -1)) {
202a7fd8e5eSmacallan		/* second: environment variable */
203a7fd8e5eSmacallan		dev = getenv("XDEVICE");
204a7fd8e5eSmacallan		if (dev == NULL || ((fd = priv_open_device(dev)) == -1)) {
205a7fd8e5eSmacallan			/* last try: default device */
206a7fd8e5eSmacallan			dev = NGLE_DEFAULT_DEV;
207a7fd8e5eSmacallan			if ((fd = priv_open_device(dev)) == -1) {
208a7fd8e5eSmacallan				return -1;
209a7fd8e5eSmacallan			}
210a7fd8e5eSmacallan		}
211a7fd8e5eSmacallan	}
212a7fd8e5eSmacallan	return fd;
213a7fd8e5eSmacallan}
214a7fd8e5eSmacallan
215a7fd8e5eSmacallan/* Map the framebuffer's memory */
216a7fd8e5eSmacallanstatic pointer
217a7fd8e5eSmacallanngle_mmap(size_t len, off_t off, int fd, int ro)
218a7fd8e5eSmacallan{
219a7fd8e5eSmacallan	pointer mapaddr;
220a7fd8e5eSmacallan
221a7fd8e5eSmacallan	/*
222a7fd8e5eSmacallan	 * try and make it private first, that way once we get it, an
223a7fd8e5eSmacallan	 * interloper, e.g. another server, can't get this frame buffer,
224a7fd8e5eSmacallan	 * and if another server already has it, this one won't.
225a7fd8e5eSmacallan	 */
226a7fd8e5eSmacallan	if (ro) {
227a7fd8e5eSmacallan		mapaddr = (pointer) mmap(NULL, len,
228a7fd8e5eSmacallan					 PROT_READ, MAP_SHARED,
229a7fd8e5eSmacallan					 fd, off);
230a7fd8e5eSmacallan		xf86Msg(X_ERROR, "mapping %08x read only\n", off);
231a7fd8e5eSmacallan	} else {
232a7fd8e5eSmacallan		mapaddr = (pointer) mmap(NULL, len,
233a7fd8e5eSmacallan					 PROT_READ | PROT_WRITE, MAP_SHARED,
234a7fd8e5eSmacallan					 fd, off);
235a7fd8e5eSmacallan		xf86Msg(X_ERROR, "mapping %08x read/write\n", off);
236a7fd8e5eSmacallan	}
237a7fd8e5eSmacallan	if (mapaddr == (pointer) -1) {
238a7fd8e5eSmacallan		mapaddr = NULL;
239a7fd8e5eSmacallan	}
240a7fd8e5eSmacallan#ifdef NGLE_DEBUG
241a7fd8e5eSmacallan	ErrorF("mmap returns: addr %p len 0x%x\n", mapaddr, len);
242a7fd8e5eSmacallan#endif
243a7fd8e5eSmacallan	return mapaddr;
244a7fd8e5eSmacallan}
245a7fd8e5eSmacallan
246a7fd8e5eSmacallanstatic Bool
247a7fd8e5eSmacallanNGLEProbe(DriverPtr drv, int flags)
248a7fd8e5eSmacallan{
249a7fd8e5eSmacallan	ScrnInfoPtr pScrn = NULL;
250a7fd8e5eSmacallan	int i, fd, entity, wstype;
251a7fd8e5eSmacallan       	GDevPtr *devSections;
252a7fd8e5eSmacallan	int numDevSections;
253a7fd8e5eSmacallan	char *dev;
254a7fd8e5eSmacallan	const char *name;
255a7fd8e5eSmacallan	uint32_t gid;
256a7fd8e5eSmacallan	Bool foundScreen = FALSE;
257a7fd8e5eSmacallan
258a7fd8e5eSmacallan	if ((numDevSections = xf86MatchDevice(NGLE_DRIVER_NAME,
259a7fd8e5eSmacallan					      &devSections)) <= 0)
260a7fd8e5eSmacallan		return FALSE;
261a7fd8e5eSmacallan
262a7fd8e5eSmacallan
263a7fd8e5eSmacallan	if ((fd = ngle_open(NGLE_DEFAULT_DEV)) == 0)
264a7fd8e5eSmacallan		return FALSE;
265a7fd8e5eSmacallan
266a7fd8e5eSmacallan	if (ioctl(fd, WSDISPLAYIO_GTYPE, &wstype) == -1)
267a7fd8e5eSmacallan		return FALSE;
268a7fd8e5eSmacallan
269a7fd8e5eSmacallan	if (wstype != WSDISPLAY_TYPE_STI)
270a7fd8e5eSmacallan		return FALSE;
271a7fd8e5eSmacallan
272a7fd8e5eSmacallan	if (ioctl(fd, GCID, &gid) == -1)
273a7fd8e5eSmacallan		return FALSE;
274a7fd8e5eSmacallan
275a7fd8e5eSmacallan	/* reject GIDs not in the table */
276a7fd8e5eSmacallan	if ((name = xf86TokenToString(NGLEChipsets, gid)) == NULL)
277a7fd8e5eSmacallan		return FALSE;
278a7fd8e5eSmacallan
279a7fd8e5eSmacallan	xf86Msg(X_INFO, "%s: found %s ( GID %08x )\n", __func__, name, gid);
280a7fd8e5eSmacallan
281a7fd8e5eSmacallan	if ( xf86DoConfigure && xf86DoConfigurePass1 ) {
282a7fd8e5eSmacallan		GDevPtr pGDev;
283a7fd8e5eSmacallan
284a7fd8e5eSmacallan		pGDev = xf86AddBusDeviceToConfigure(NGLE_DRIVER_NAME, BUS_NONE,
285a7fd8e5eSmacallan			NULL, 0);
286a7fd8e5eSmacallan		if (pGDev) {
287a7fd8e5eSmacallan			/*
288a7fd8e5eSmacallan			 * XF86Match???Instances() treat chipID and chipRev as
289a7fd8e5eSmacallan			 * overrides, so clobber them here.
290a7fd8e5eSmacallan			 */
291a7fd8e5eSmacallan			pGDev->chipID = pGDev->chipRev = -1;
292a7fd8e5eSmacallan	    	}
293a7fd8e5eSmacallan	}
294a7fd8e5eSmacallan
295a7fd8e5eSmacallan	if (flags & PROBE_DETECT) {
296a7fd8e5eSmacallan		return TRUE;
297a7fd8e5eSmacallan	}
298a7fd8e5eSmacallan
299a7fd8e5eSmacallan	if (numDevSections > 1) {
300a7fd8e5eSmacallan		xf86Msg(X_ERROR, "Ignoring additional device sections\n");
301a7fd8e5eSmacallan		numDevSections = 1;
302a7fd8e5eSmacallan	}
303a7fd8e5eSmacallan	/* ok, at this point we know we've got a NGLE */
304a7fd8e5eSmacallan	for (i = 0; i < numDevSections; i++) {
305a7fd8e5eSmacallan
306a7fd8e5eSmacallan		entity = xf86ClaimFbSlot(drv, 0, devSections[i], TRUE);
307a7fd8e5eSmacallan		pScrn = xf86ConfigFbEntity(NULL, 0, entity,
308a7fd8e5eSmacallan		    NULL, NULL, NULL, NULL);
309a7fd8e5eSmacallan		if (pScrn != NULL) {
310a7fd8e5eSmacallan			foundScreen = TRUE;
311a7fd8e5eSmacallan			pScrn->driverVersion = VERSION;
312a7fd8e5eSmacallan			pScrn->driverName = NGLE_DRIVER_NAME;
313a7fd8e5eSmacallan			pScrn->name = NGLE_NAME;
314a7fd8e5eSmacallan			pScrn->Probe = NGLEProbe;
315a7fd8e5eSmacallan			pScrn->PreInit = NGLEPreInit;
316a7fd8e5eSmacallan			pScrn->ScreenInit = NGLEScreenInit;
317a7fd8e5eSmacallan			pScrn->SwitchMode = NGLESwitchMode;
318a7fd8e5eSmacallan			pScrn->AdjustFrame = NULL;
319a7fd8e5eSmacallan			pScrn->EnterVT = NGLEEnterVT;
320a7fd8e5eSmacallan			pScrn->LeaveVT = NGLELeaveVT;
321a7fd8e5eSmacallan			pScrn->ValidMode = NGLEValidMode;
322a7fd8e5eSmacallan
323a7fd8e5eSmacallan		}
324a7fd8e5eSmacallan	}
325a7fd8e5eSmacallan	free(devSections);
326a7fd8e5eSmacallan	return foundScreen;
327a7fd8e5eSmacallan}
328a7fd8e5eSmacallan
329a7fd8e5eSmacallanstatic Bool
330a7fd8e5eSmacallanNGLEPreInit(ScrnInfoPtr pScrn, int flags)
331a7fd8e5eSmacallan{
332a7fd8e5eSmacallan	NGLEPtr fPtr;
333a7fd8e5eSmacallan	int default_depth, bitsperpixel, wstype;
334a7fd8e5eSmacallan	const char *dev;
335a7fd8e5eSmacallan	char *mod = NULL;
336a7fd8e5eSmacallan	const char *reqSym = NULL;
337a7fd8e5eSmacallan	Gamma zeros = {0.0, 0.0, 0.0};
338a7fd8e5eSmacallan	DisplayModePtr mode;
339a7fd8e5eSmacallan	MessageType from;
340a7fd8e5eSmacallan	rgb rgbzeros = { 0, 0, 0 }, masks;
341a7fd8e5eSmacallan
342a7fd8e5eSmacallan	if (flags & PROBE_DETECT) return FALSE;
343a7fd8e5eSmacallan
344a7fd8e5eSmacallan	if (pScrn->numEntities != 1) return FALSE;
345a7fd8e5eSmacallan
346a7fd8e5eSmacallan	pScrn->monitor = pScrn->confScreen->monitor;
347a7fd8e5eSmacallan
348a7fd8e5eSmacallan	NGLEGetRec(pScrn);
349a7fd8e5eSmacallan	fPtr = NGLEPTR(pScrn);
350a7fd8e5eSmacallan
351a7fd8e5eSmacallan	fPtr->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
352a7fd8e5eSmacallan
353a7fd8e5eSmacallan	dev = xf86FindOptionValue(fPtr->pEnt->device->options, "device");
354a7fd8e5eSmacallan	fPtr->fd = ngle_open(dev);
355a7fd8e5eSmacallan	if (fPtr->fd == -1) {
356a7fd8e5eSmacallan		return FALSE;
357a7fd8e5eSmacallan	}
358a7fd8e5eSmacallan
359a7fd8e5eSmacallan	if (ioctl(fPtr->fd, WSDISPLAYIO_GET_FBINFO, &fPtr->fbi) == -1) {
360a7fd8e5eSmacallan		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
361a7fd8e5eSmacallan			   "ioctl WSDISPLAY_GINFO: %s\n",
362a7fd8e5eSmacallan			   strerror(errno));
363a7fd8e5eSmacallan		return FALSE;
364a7fd8e5eSmacallan	}
365a7fd8e5eSmacallan	if (ioctl(fPtr->fd, WSDISPLAYIO_GTYPE, &wstype) == -1) {
366a7fd8e5eSmacallan		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
367a7fd8e5eSmacallan			   "ioctl WSDISPLAY_GTYPE: %s\n",
368a7fd8e5eSmacallan			   strerror(errno));
369a7fd8e5eSmacallan		return FALSE;
370a7fd8e5eSmacallan	}
371a7fd8e5eSmacallan
372a7fd8e5eSmacallan	/* Handle depth */
373a7fd8e5eSmacallan	default_depth = fPtr->fbi.fbi_bitsperpixel <= 24 ? fPtr->fbi.fbi_bitsperpixel : 24;
374a7fd8e5eSmacallan	bitsperpixel = fPtr->fbi.fbi_bitsperpixel == 15 ? 16 : fPtr->fbi.fbi_bitsperpixel;
375a7fd8e5eSmacallan	if (!xf86SetDepthBpp(pScrn, default_depth, default_depth,
376a7fd8e5eSmacallan		bitsperpixel,
377a7fd8e5eSmacallan		bitsperpixel >= 24 ? Support24bppFb|Support32bppFb : 0))
378a7fd8e5eSmacallan		return FALSE;
379a7fd8e5eSmacallan
380a7fd8e5eSmacallan	xf86PrintDepthBpp(pScrn);
381a7fd8e5eSmacallan
382a7fd8e5eSmacallan	/* color weight */
383a7fd8e5eSmacallan	masks.red =   0x00ff0000;
384a7fd8e5eSmacallan	masks.green = 0x0000ff00;
385a7fd8e5eSmacallan	masks.blue =  0x000000ff;
386a7fd8e5eSmacallan	if (!xf86SetWeight(pScrn, rgbzeros, masks))
387a7fd8e5eSmacallan		return FALSE;
388a7fd8e5eSmacallan
389a7fd8e5eSmacallan	/* visual init */
390a7fd8e5eSmacallan	if (!xf86SetDefaultVisual(pScrn, -1))
391a7fd8e5eSmacallan		return FALSE;
392a7fd8e5eSmacallan
393a7fd8e5eSmacallan	/* We don't currently support DirectColor at > 8bpp */
394a7fd8e5eSmacallan	if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
395a7fd8e5eSmacallan		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
396a7fd8e5eSmacallan			   " (%s) is not supported at depth %d\n",
397a7fd8e5eSmacallan			   xf86GetVisualName(pScrn->defaultVisual),
398a7fd8e5eSmacallan			   pScrn->depth);
399a7fd8e5eSmacallan		return FALSE;
400a7fd8e5eSmacallan	}
401a7fd8e5eSmacallan
402a7fd8e5eSmacallan	xf86SetGamma(pScrn,zeros);
403a7fd8e5eSmacallan
404a7fd8e5eSmacallan	pScrn->progClock = TRUE;
405a7fd8e5eSmacallan	pScrn->rgbBits   = 8;
406a7fd8e5eSmacallan	pScrn->chipset   = "NGLE";
407a7fd8e5eSmacallan	fPtr->fbmem_len = pScrn->videoRam  = fPtr->fbi.fbi_fbsize;
408a7fd8e5eSmacallan
409a7fd8e5eSmacallan	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vidmem: %dk\n",
410a7fd8e5eSmacallan		   pScrn->videoRam/1024);
411a7fd8e5eSmacallan
412a7fd8e5eSmacallan	/* handle options */
413a7fd8e5eSmacallan	xf86CollectOptions(pScrn, NULL);
414a7fd8e5eSmacallan	if (!(fPtr->Options = malloc(sizeof(NGLEOptions))))
415a7fd8e5eSmacallan		return FALSE;
416a7fd8e5eSmacallan	memcpy(fPtr->Options, NGLEOptions, sizeof(NGLEOptions));
417a7fd8e5eSmacallan	xf86ProcessOptions(pScrn->scrnIndex, fPtr->pEnt->device->options,
418a7fd8e5eSmacallan			   fPtr->Options);
419a7fd8e5eSmacallan
420a7fd8e5eSmacallan	/* fake video mode struct */
421a7fd8e5eSmacallan	mode = (DisplayModePtr)malloc(sizeof(DisplayModeRec));
422a7fd8e5eSmacallan	mode->prev = mode;
423a7fd8e5eSmacallan	mode->next = mode;
424a7fd8e5eSmacallan	mode->name = "NGLE current mode";
425a7fd8e5eSmacallan	mode->status = MODE_OK;
426a7fd8e5eSmacallan	mode->type = M_T_BUILTIN;
427a7fd8e5eSmacallan	mode->Clock = 0;
428a7fd8e5eSmacallan	mode->HDisplay = fPtr->fbi.fbi_width;
429a7fd8e5eSmacallan	mode->HSyncStart = 0;
430a7fd8e5eSmacallan	mode->HSyncEnd = 0;
431a7fd8e5eSmacallan	mode->HTotal = 0;
432a7fd8e5eSmacallan	mode->HSkew = 0;
433a7fd8e5eSmacallan	mode->VDisplay = fPtr->fbi.fbi_height;
434a7fd8e5eSmacallan	mode->VSyncStart = 0;
435a7fd8e5eSmacallan	mode->VSyncEnd = 0;
436a7fd8e5eSmacallan	mode->VTotal = 0;
437a7fd8e5eSmacallan	mode->VScan = 0;
438a7fd8e5eSmacallan	mode->Flags = 0;
439a7fd8e5eSmacallan	if (pScrn->modes != NULL) {
440a7fd8e5eSmacallan		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
441a7fd8e5eSmacallan		   "Ignoring mode specification from screen section\n");
442a7fd8e5eSmacallan	}
443a7fd8e5eSmacallan	pScrn->currentMode = pScrn->modes = mode;
444a7fd8e5eSmacallan	pScrn->virtualX = fPtr->fbi.fbi_width;
445a7fd8e5eSmacallan	pScrn->virtualY = fPtr->fbi.fbi_height;
446a7fd8e5eSmacallan	pScrn->displayWidth = 2048;
447a7fd8e5eSmacallan
448a7fd8e5eSmacallan	/* Set the display resolution */
449a7fd8e5eSmacallan	xf86SetDpi(pScrn, 0, 0);
450a7fd8e5eSmacallan
451a7fd8e5eSmacallan	from = X_DEFAULT;
452a7fd8e5eSmacallan	fPtr->HWCursor = TRUE;
453a7fd8e5eSmacallan	if (xf86GetOptValBool(fPtr->Options, OPTION_HW_CURSOR, &fPtr->HWCursor))
454a7fd8e5eSmacallan		from = X_CONFIG;
455a7fd8e5eSmacallan	if (xf86ReturnOptValBool(fPtr->Options, OPTION_SW_CURSOR, FALSE)) {
456a7fd8e5eSmacallan		from = X_CONFIG;
457a7fd8e5eSmacallan		fPtr->HWCursor = FALSE;
458a7fd8e5eSmacallan	}
459a7fd8e5eSmacallan	xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
460a7fd8e5eSmacallan		fPtr->HWCursor ? "HW" : "SW");
461a7fd8e5eSmacallan
462a7fd8e5eSmacallan	if (xf86LoadSubModule(pScrn, "fb") == NULL) {
463a7fd8e5eSmacallan		NGLEFreeRec(pScrn);
464a7fd8e5eSmacallan		return FALSE;
465a7fd8e5eSmacallan	}
466a7fd8e5eSmacallan
467a7fd8e5eSmacallan	if (xf86LoadSubModule(pScrn, "exa") == NULL) {
468a7fd8e5eSmacallan		NGLEFreeRec(pScrn);
469a7fd8e5eSmacallan		return FALSE;
470a7fd8e5eSmacallan	}
471a7fd8e5eSmacallan
472a7fd8e5eSmacallan	if (xf86LoadSubModule(pScrn, "ramdac") == NULL) {
473a7fd8e5eSmacallan		NGLEFreeRec(pScrn);
474a7fd8e5eSmacallan		return FALSE;
475a7fd8e5eSmacallan	}
476a7fd8e5eSmacallan
477a7fd8e5eSmacallan	return TRUE;
478a7fd8e5eSmacallan}
479a7fd8e5eSmacallan
480a7fd8e5eSmacallanstatic Bool
481a7fd8e5eSmacallanNGLEScreenInit(SCREEN_INIT_ARGS_DECL)
482a7fd8e5eSmacallan{
483a7fd8e5eSmacallan	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
484a7fd8e5eSmacallan	NGLEPtr fPtr = NGLEPTR(pScrn);
485a7fd8e5eSmacallan	VisualPtr visual;
486a7fd8e5eSmacallan	int ret, flags, width, height, i, j;
487a7fd8e5eSmacallan	int wsmode = WSDISPLAYIO_MODE_MAPPED;
488a7fd8e5eSmacallan	size_t len;
489a7fd8e5eSmacallan
490a7fd8e5eSmacallan#ifdef NGLE_DEBUG
491a7fd8e5eSmacallan	ErrorF("\tbitsPerPixel=%d, depth=%d, defaultVisual=%s\n"
492a7fd8e5eSmacallan	       "\tmask: %x,%x,%x, offset: %d,%d,%d\n",
493a7fd8e5eSmacallan	       pScrn->bitsPerPixel,
494a7fd8e5eSmacallan	       pScrn->depth,
495a7fd8e5eSmacallan	       xf86GetVisualName(pScrn->defaultVisual),
496a7fd8e5eSmacallan	       pScrn->mask.red,pScrn->mask.green,pScrn->mask.blue,
497a7fd8e5eSmacallan	       pScrn->offset.red,pScrn->offset.green,pScrn->offset.blue);
498a7fd8e5eSmacallan#endif
499a7fd8e5eSmacallan
500a7fd8e5eSmacallan	/* Switch to graphics mode - required before mmap */
501a7fd8e5eSmacallan	if (ioctl(fPtr->fd, WSDISPLAYIO_SMODE, &wsmode) == -1) {
502a7fd8e5eSmacallan		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
503a7fd8e5eSmacallan			   "ioctl WSDISPLAYIO_SMODE: %s\n",
504a7fd8e5eSmacallan			   strerror(errno));
505a7fd8e5eSmacallan		return FALSE;
506a7fd8e5eSmacallan	}
507a7fd8e5eSmacallan	fPtr->regs = ngle_mmap(0x40000, 0x80000000, fPtr->fd, 0);
508a7fd8e5eSmacallan
509a7fd8e5eSmacallan	if (fPtr->regs == NULL) {
510a7fd8e5eSmacallan		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
511a7fd8e5eSmacallan			   "ngle_mmap registers: %s\n", strerror(errno));
512a7fd8e5eSmacallan		return FALSE;
513a7fd8e5eSmacallan	}
514a7fd8e5eSmacallan
515a7fd8e5eSmacallan	fPtr->fbmem = ngle_mmap(fPtr->fbmem_len, 0, fPtr->fd, 0);
516a7fd8e5eSmacallan	if (fPtr->fbmem == NULL) {
517a7fd8e5eSmacallan		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
518a7fd8e5eSmacallan			   "ngle_mmap fb: %s\n", strerror(errno));
519a7fd8e5eSmacallan		return FALSE;
520a7fd8e5eSmacallan	}
521a7fd8e5eSmacallan
522a7fd8e5eSmacallan	NGLESave(pScrn);
523a7fd8e5eSmacallan	pScrn->vtSema = TRUE;
524a7fd8e5eSmacallan
525a7fd8e5eSmacallan	/* mi layer */
526a7fd8e5eSmacallan	miClearVisualTypes();
527a7fd8e5eSmacallan	if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
528a7fd8e5eSmacallan			      pScrn->rgbBits, TrueColor))
529a7fd8e5eSmacallan		return FALSE;
530a7fd8e5eSmacallan
531a7fd8e5eSmacallan	if (!miSetPixmapDepths())
532a7fd8e5eSmacallan		return FALSE;
533a7fd8e5eSmacallan
534a7fd8e5eSmacallan	height = pScrn->virtualY;
535a7fd8e5eSmacallan	width = pScrn->virtualX;
536a7fd8e5eSmacallan
537a7fd8e5eSmacallan	ret = fbScreenInit(pScreen,
538a7fd8e5eSmacallan			   fPtr->fbmem,
539a7fd8e5eSmacallan			   width, height,
540a7fd8e5eSmacallan			   pScrn->xDpi, pScrn->yDpi,
541a7fd8e5eSmacallan			   pScrn->displayWidth,
542a7fd8e5eSmacallan			   pScrn->bitsPerPixel);
543a7fd8e5eSmacallan
544a7fd8e5eSmacallan	if (!ret)
545a7fd8e5eSmacallan		return FALSE;
546a7fd8e5eSmacallan
547a7fd8e5eSmacallan	if (pScrn->bitsPerPixel > 8) {
548a7fd8e5eSmacallan		/* Fixup RGB ordering. */
549a7fd8e5eSmacallan		visual = pScreen->visuals + pScreen->numVisuals;
550a7fd8e5eSmacallan		while (--visual >= pScreen->visuals) {
551a7fd8e5eSmacallan			if ((visual->class | DynamicClass) == DirectColor) {
552a7fd8e5eSmacallan				visual->offsetRed   = pScrn->offset.red;
553a7fd8e5eSmacallan				visual->offsetGreen = pScrn->offset.green;
554a7fd8e5eSmacallan				visual->offsetBlue  = pScrn->offset.blue;
555a7fd8e5eSmacallan				visual->redMask     = pScrn->mask.red;
556a7fd8e5eSmacallan				visual->greenMask   = pScrn->mask.green;
557a7fd8e5eSmacallan				visual->blueMask    = pScrn->mask.blue;
558a7fd8e5eSmacallan			}
559a7fd8e5eSmacallan		}
560a7fd8e5eSmacallan	}
561a7fd8e5eSmacallan
562a7fd8e5eSmacallan	if (!fbPictureInit(pScreen, NULL, 0))
563a7fd8e5eSmacallan		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
564a7fd8e5eSmacallan			   "RENDER extension initialisation failed.");
565a7fd8e5eSmacallan
566a7fd8e5eSmacallan	xf86SetBlackWhitePixels(pScreen);
567a7fd8e5eSmacallan	xf86SetBackingStore(pScreen);
568a7fd8e5eSmacallan
569a7fd8e5eSmacallan	if (fPtr) {
570a7fd8e5eSmacallan		/* init accel here */
571a7fd8e5eSmacallan		//xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using acceleration\n");
572a7fd8e5eSmacallan	}
573a7fd8e5eSmacallan
574a7fd8e5eSmacallan	/* software cursor */
575a7fd8e5eSmacallan	miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
576a7fd8e5eSmacallan
577a7fd8e5eSmacallan	/* check for hardware cursor support */
578a7fd8e5eSmacallan	NGLESetupCursor(pScreen);
579a7fd8e5eSmacallan
580a7fd8e5eSmacallan	/* colormap */
581a7fd8e5eSmacallan	if (!miCreateDefColormap(pScreen))
582a7fd8e5eSmacallan		return FALSE;
583a7fd8e5eSmacallan
584a7fd8e5eSmacallan	flags = CMAP_RELOAD_ON_MODE_SWITCH;
585a7fd8e5eSmacallan	if(!xf86HandleColormaps(pScreen, 256, 8, NGLELoadPalette,
586a7fd8e5eSmacallan				NULL, flags))
587a7fd8e5eSmacallan		return FALSE;
588a7fd8e5eSmacallan
589a7fd8e5eSmacallan	pScreen->SaveScreen = NGLESaveScreen;
590a7fd8e5eSmacallan
591a7fd8e5eSmacallan#ifdef XvExtension
592a7fd8e5eSmacallan	{
593a7fd8e5eSmacallan		XF86VideoAdaptorPtr *ptr;
594a7fd8e5eSmacallan
595a7fd8e5eSmacallan		int n = xf86XVListGenericAdaptors(pScrn,&ptr);
596a7fd8e5eSmacallan		if (n) {
597a7fd8e5eSmacallan			xf86XVScreenInit(pScreen,ptr,n);
598a7fd8e5eSmacallan		}
599a7fd8e5eSmacallan	}
600a7fd8e5eSmacallan#endif
601a7fd8e5eSmacallan
602a7fd8e5eSmacallan	/* Wrap the current CloseScreen function */
603a7fd8e5eSmacallan	fPtr->CloseScreen = pScreen->CloseScreen;
604a7fd8e5eSmacallan	pScreen->CloseScreen = NGLECloseScreen;
605a7fd8e5eSmacallan
606a7fd8e5eSmacallan	return TRUE;
607a7fd8e5eSmacallan}
608a7fd8e5eSmacallan
609a7fd8e5eSmacallanstatic Bool
610a7fd8e5eSmacallanNGLECloseScreen(CLOSE_SCREEN_ARGS_DECL)
611a7fd8e5eSmacallan{
612a7fd8e5eSmacallan	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
613a7fd8e5eSmacallan	NGLEPtr fPtr = NGLEPTR(pScrn);
614a7fd8e5eSmacallan
615a7fd8e5eSmacallan	if (pScrn->vtSema) {
616a7fd8e5eSmacallan		NGLERestore(pScrn);
617a7fd8e5eSmacallan		if (munmap(fPtr->regs, 0x40000) == -1) {
618a7fd8e5eSmacallan			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
619a7fd8e5eSmacallan				   "munmap engine: %s\n", strerror(errno));
620a7fd8e5eSmacallan		}
621a7fd8e5eSmacallan
622a7fd8e5eSmacallan		if (munmap(fPtr->fbmem, fPtr->fbmem_len) == -1) {
623a7fd8e5eSmacallan			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
624a7fd8e5eSmacallan				   "munmap fb: %s\n", strerror(errno));
625a7fd8e5eSmacallan		}
626a7fd8e5eSmacallan
627a7fd8e5eSmacallan		fPtr->regs = NULL;
628a7fd8e5eSmacallan		fPtr->fbmem = NULL;
629a7fd8e5eSmacallan	}
630a7fd8e5eSmacallan	pScrn->vtSema = FALSE;
631a7fd8e5eSmacallan
632a7fd8e5eSmacallan	/* unwrap CloseScreen */
633a7fd8e5eSmacallan	pScreen->CloseScreen = fPtr->CloseScreen;
634a7fd8e5eSmacallan	return (*pScreen->CloseScreen)(pScreen);
635a7fd8e5eSmacallan}
636a7fd8e5eSmacallan
637a7fd8e5eSmacallanstatic Bool
638a7fd8e5eSmacallanNGLEEnterVT(VT_FUNC_ARGS_DECL)
639a7fd8e5eSmacallan{
640a7fd8e5eSmacallan	SCRN_INFO_PTR(arg);
641a7fd8e5eSmacallan
642a7fd8e5eSmacallan	pScrn->vtSema = TRUE;
643a7fd8e5eSmacallan	return TRUE;
644a7fd8e5eSmacallan}
645a7fd8e5eSmacallan
646a7fd8e5eSmacallanstatic void
647a7fd8e5eSmacallanNGLELeaveVT(VT_FUNC_ARGS_DECL)
648a7fd8e5eSmacallan{
649a7fd8e5eSmacallan}
650a7fd8e5eSmacallan
651a7fd8e5eSmacallanstatic Bool
652a7fd8e5eSmacallanNGLESwitchMode(SWITCH_MODE_ARGS_DECL)
653a7fd8e5eSmacallan{
654a7fd8e5eSmacallan
655a7fd8e5eSmacallan	/* Nothing else to do */
656a7fd8e5eSmacallan	return TRUE;
657a7fd8e5eSmacallan}
658a7fd8e5eSmacallan
659a7fd8e5eSmacallanstatic int
660a7fd8e5eSmacallanNGLEValidMode(SCRN_ARG_TYPE, DisplayModePtr mode, Bool verbose, int flags)
661a7fd8e5eSmacallan{
662a7fd8e5eSmacallan
663a7fd8e5eSmacallan	return MODE_OK;
664a7fd8e5eSmacallan}
665a7fd8e5eSmacallan
666a7fd8e5eSmacallanstatic void
667a7fd8e5eSmacallanNGLELoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
668a7fd8e5eSmacallan	       LOCO *colors, VisualPtr pVisual)
669a7fd8e5eSmacallan{
670a7fd8e5eSmacallan	NGLEPtr fPtr = NGLEPTR(pScrn);
671a7fd8e5eSmacallan	struct wsdisplay_cmap cmap;
672a7fd8e5eSmacallan	unsigned char red[256],green[256],blue[256];
673a7fd8e5eSmacallan	int i, indexMin=256, indexMax=0;
674a7fd8e5eSmacallan
675a7fd8e5eSmacallan	/* nothing to do if there is no color palette support */
676a7fd8e5eSmacallan	if (fPtr->fbi.fbi_subtype.fbi_cmapinfo.cmap_entries == 0)
677a7fd8e5eSmacallan		return;
678a7fd8e5eSmacallan
679a7fd8e5eSmacallan	cmap.count   = 1;
680a7fd8e5eSmacallan	cmap.red   = red;
681a7fd8e5eSmacallan	cmap.green = green;
682a7fd8e5eSmacallan	cmap.blue  = blue;
683a7fd8e5eSmacallan
684a7fd8e5eSmacallan	if (numColors == 1) {
685a7fd8e5eSmacallan		/* Optimisation */
686a7fd8e5eSmacallan		cmap.index = indices[0];
687a7fd8e5eSmacallan		red[0]   = colors[indices[0]].red;
688a7fd8e5eSmacallan		green[0] = colors[indices[0]].green;
689a7fd8e5eSmacallan		blue[0]  = colors[indices[0]].blue;
690a7fd8e5eSmacallan		if (ioctl(fPtr->fd,WSDISPLAYIO_PUTCMAP, &cmap) == -1)
691a7fd8e5eSmacallan			ErrorF("ioctl FBIOPUTCMAP: %s\n", strerror(errno));
692a7fd8e5eSmacallan	} else {
693a7fd8e5eSmacallan		/*
694a7fd8e5eSmacallan		 * Change all colors in 2 ioctls
695a7fd8e5eSmacallan		 * and limit the data to be transferred.
696a7fd8e5eSmacallan		 */
697a7fd8e5eSmacallan		for (i = 0; i < numColors; i++) {
698a7fd8e5eSmacallan			if (indices[i] < indexMin)
699a7fd8e5eSmacallan				indexMin = indices[i];
700a7fd8e5eSmacallan			if (indices[i] > indexMax)
701a7fd8e5eSmacallan				indexMax = indices[i];
702a7fd8e5eSmacallan		}
703a7fd8e5eSmacallan		cmap.index = indexMin;
704a7fd8e5eSmacallan		cmap.count = indexMax - indexMin + 1;
705a7fd8e5eSmacallan		cmap.red = &red[indexMin];
706a7fd8e5eSmacallan		cmap.green = &green[indexMin];
707a7fd8e5eSmacallan		cmap.blue = &blue[indexMin];
708a7fd8e5eSmacallan		/* Get current map. */
709a7fd8e5eSmacallan		if (ioctl(fPtr->fd, WSDISPLAYIO_GETCMAP, &cmap) == -1)
710a7fd8e5eSmacallan			ErrorF("ioctl FBIOGETCMAP: %s\n", strerror(errno));
711a7fd8e5eSmacallan		/* Change the colors that require updating. */
712a7fd8e5eSmacallan		for (i = 0; i < numColors; i++) {
713a7fd8e5eSmacallan			red[indices[i]]   = colors[indices[i]].red;
714a7fd8e5eSmacallan			green[indices[i]] = colors[indices[i]].green;
715a7fd8e5eSmacallan			blue[indices[i]]  = colors[indices[i]].blue;
716a7fd8e5eSmacallan		}
717a7fd8e5eSmacallan		/* Write the colormap back. */
718a7fd8e5eSmacallan		if (ioctl(fPtr->fd,WSDISPLAYIO_PUTCMAP, &cmap) == -1)
719a7fd8e5eSmacallan			ErrorF("ioctl FBIOPUTCMAP: %s\n", strerror(errno));
720a7fd8e5eSmacallan	}
721a7fd8e5eSmacallan}
722a7fd8e5eSmacallan
723a7fd8e5eSmacallanstatic Bool
724a7fd8e5eSmacallanNGLESaveScreen(ScreenPtr pScreen, int mode)
725a7fd8e5eSmacallan{
726a7fd8e5eSmacallan	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
727a7fd8e5eSmacallan	NGLEPtr fPtr = NGLEPTR(pScrn);
728a7fd8e5eSmacallan	int state;
729a7fd8e5eSmacallan
730a7fd8e5eSmacallan	if (!pScrn->vtSema)
731a7fd8e5eSmacallan		return TRUE;
732a7fd8e5eSmacallan
733a7fd8e5eSmacallan	if (mode != SCREEN_SAVER_FORCER) {
734a7fd8e5eSmacallan		state = xf86IsUnblank(mode)?WSDISPLAYIO_VIDEO_ON:
735a7fd8e5eSmacallan		                            WSDISPLAYIO_VIDEO_OFF;
736a7fd8e5eSmacallan		ioctl(fPtr->fd,
737a7fd8e5eSmacallan		      WSDISPLAYIO_SVIDEO, &state);
738a7fd8e5eSmacallan	}
739a7fd8e5eSmacallan	return TRUE;
740a7fd8e5eSmacallan}
741a7fd8e5eSmacallan
742a7fd8e5eSmacallan
743a7fd8e5eSmacallanstatic void
744a7fd8e5eSmacallanNGLESave(ScrnInfoPtr pScrn)
745a7fd8e5eSmacallan{
746a7fd8e5eSmacallan}
747a7fd8e5eSmacallan
748a7fd8e5eSmacallanstatic void
749a7fd8e5eSmacallanNGLERestore(ScrnInfoPtr pScrn)
750a7fd8e5eSmacallan{
751a7fd8e5eSmacallan	NGLEPtr fPtr = NGLEPTR(pScrn);
752a7fd8e5eSmacallan	int mode;
753a7fd8e5eSmacallan
754a7fd8e5eSmacallan	/* Restore the text mode */
755a7fd8e5eSmacallan	mode = WSDISPLAYIO_MODE_EMUL;
756a7fd8e5eSmacallan	if (ioctl(fPtr->fd, WSDISPLAYIO_SMODE, &mode) == -1) {
757a7fd8e5eSmacallan		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
758a7fd8e5eSmacallan			   "error setting text mode %s\n", strerror(errno));
759a7fd8e5eSmacallan	}
760a7fd8e5eSmacallan}
761