16d300f0aSchristos/* $NetBSD: ngle_driver.c,v 1.11 2025/02/20 18:53:48 christos 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" },
1107517da51Smacallan	{ STI_DD_SUMMIT, "Visualize FX 2/4/6"},
111a7fd8e5eSmacallan	{ -1, NULL }
112a7fd8e5eSmacallan};
113a7fd8e5eSmacallan
114a7fd8e5eSmacallan/* Supported options */
115a7fd8e5eSmacallantypedef enum {
116a7fd8e5eSmacallan	OPTION_HW_CURSOR,
1177517da51Smacallan	OPTION_DEVICE
118a7fd8e5eSmacallan} NGLEOpts;
119a7fd8e5eSmacallan
120a7fd8e5eSmacallanstatic const OptionInfoRec NGLEOptions[] = {
1217a5287f7Smacallan	{ OPTION_HW_CURSOR, "HWcursor",	OPTV_BOOLEAN,	{0}, TRUE },
1227517da51Smacallan	{ OPTION_DEVICE,    "Device",   OPTV_ANYSTR,    {0}, FALSE },
123a7fd8e5eSmacallan	{ -1, NULL, OPTV_NONE, {0}, FALSE}
124a7fd8e5eSmacallan};
125a7fd8e5eSmacallan
126a7fd8e5eSmacallanstatic XF86ModuleVersionInfo NGLEVersRec = {
127a7fd8e5eSmacallan	"ngle",
128a7fd8e5eSmacallan	"The NetBSD Foundation",
129a7fd8e5eSmacallan	MODINFOSTRING1,
130a7fd8e5eSmacallan	MODINFOSTRING2,
131a7fd8e5eSmacallan	XORG_VERSION_CURRENT,
132a7fd8e5eSmacallan	NGLE_MAJOR_VERSION, NGLE_MINOR_VERSION, 0,
133a7fd8e5eSmacallan	ABI_CLASS_VIDEODRV,
134a7fd8e5eSmacallan	ABI_VIDEODRV_VERSION,
135a7fd8e5eSmacallan	NULL,
136a7fd8e5eSmacallan	{0, 0, 0, 0}
137a7fd8e5eSmacallan};
138a7fd8e5eSmacallan
139a7fd8e5eSmacallan_X_EXPORT XF86ModuleData ngleModuleData = { &NGLEVersRec, NGLESetup, NULL };
140a7fd8e5eSmacallan
141a7fd8e5eSmacallanstatic pointer
142a7fd8e5eSmacallanNGLESetup(pointer module, pointer opts, int *errmaj, int *errmin)
143a7fd8e5eSmacallan{
144a7fd8e5eSmacallan	static Bool setupDone = FALSE;
145a7fd8e5eSmacallan	const char *osname;
146a7fd8e5eSmacallan
147a7fd8e5eSmacallan	if (!setupDone) {
148a7fd8e5eSmacallan		setupDone = TRUE;
149a7fd8e5eSmacallan		xf86AddDriver(&NGLE, module, 0);
150a7fd8e5eSmacallan		return (pointer)1;
151a7fd8e5eSmacallan	} else {
152a7fd8e5eSmacallan		if (errmaj != NULL)
153a7fd8e5eSmacallan			*errmaj = LDR_ONCEONLY;
154a7fd8e5eSmacallan		return NULL;
155a7fd8e5eSmacallan	}
156a7fd8e5eSmacallan}
157a7fd8e5eSmacallan
158a7fd8e5eSmacallanstatic Bool
159a7fd8e5eSmacallanNGLEGetRec(ScrnInfoPtr pScrn)
160a7fd8e5eSmacallan{
161a7fd8e5eSmacallan
162a7fd8e5eSmacallan	if (pScrn->driverPrivate != NULL)
163a7fd8e5eSmacallan		return TRUE;
164a7fd8e5eSmacallan
165a7fd8e5eSmacallan	pScrn->driverPrivate = xnfcalloc(sizeof(NGLERec), 1);
166a7fd8e5eSmacallan	return TRUE;
167a7fd8e5eSmacallan}
168a7fd8e5eSmacallan
169a7fd8e5eSmacallanstatic void
170a7fd8e5eSmacallanNGLEFreeRec(ScrnInfoPtr pScrn)
171a7fd8e5eSmacallan{
172a7fd8e5eSmacallan
173a7fd8e5eSmacallan	if (pScrn->driverPrivate == NULL)
174a7fd8e5eSmacallan		return;
175a7fd8e5eSmacallan	free(pScrn->driverPrivate);
176a7fd8e5eSmacallan	pScrn->driverPrivate = NULL;
177a7fd8e5eSmacallan}
178a7fd8e5eSmacallan
179a7fd8e5eSmacallanstatic const OptionInfoRec *
180a7fd8e5eSmacallanNGLEAvailableOptions(int chipid, int busid)
181a7fd8e5eSmacallan{
182a7fd8e5eSmacallan	return NGLEOptions;
183a7fd8e5eSmacallan}
184a7fd8e5eSmacallan
185a7fd8e5eSmacallanstatic void
186a7fd8e5eSmacallanNGLEIdentify(int flags)
187a7fd8e5eSmacallan{
188a7fd8e5eSmacallan	xf86PrintChipsets(NGLE_NAME, "driver for NGLE framebuffers",
189a7fd8e5eSmacallan			  NGLEChipsets);
190a7fd8e5eSmacallan}
191a7fd8e5eSmacallan
192a7fd8e5eSmacallan
193a7fd8e5eSmacallan#define priv_open_device(n)	open(n,O_RDWR|O_NONBLOCK|O_EXCL)
194a7fd8e5eSmacallan
195a7fd8e5eSmacallan/* Open the framebuffer device */
196a7fd8e5eSmacallanstatic int
197a7fd8e5eSmacallanngle_open(const char *dev)
198a7fd8e5eSmacallan{
199a7fd8e5eSmacallan	int fd = -1;
200a7fd8e5eSmacallan
201a7fd8e5eSmacallan	/* try argument from XF86Config first */
202a7fd8e5eSmacallan	if (dev == NULL || ((fd = priv_open_device(dev)) == -1)) {
203a7fd8e5eSmacallan		/* second: environment variable */
204a7fd8e5eSmacallan		dev = getenv("XDEVICE");
205a7fd8e5eSmacallan		if (dev == NULL || ((fd = priv_open_device(dev)) == -1)) {
206a7fd8e5eSmacallan			/* last try: default device */
207a7fd8e5eSmacallan			dev = NGLE_DEFAULT_DEV;
208a7fd8e5eSmacallan			if ((fd = priv_open_device(dev)) == -1) {
209a7fd8e5eSmacallan				return -1;
210a7fd8e5eSmacallan			}
211a7fd8e5eSmacallan		}
212a7fd8e5eSmacallan	}
213a7fd8e5eSmacallan	return fd;
214a7fd8e5eSmacallan}
215a7fd8e5eSmacallan
216a7fd8e5eSmacallan/* Map the framebuffer's memory */
217a7fd8e5eSmacallanstatic pointer
218a7fd8e5eSmacallanngle_mmap(size_t len, off_t off, int fd, int ro)
219a7fd8e5eSmacallan{
220a7fd8e5eSmacallan	pointer mapaddr;
221a7fd8e5eSmacallan
222a7fd8e5eSmacallan	/*
223a7fd8e5eSmacallan	 * try and make it private first, that way once we get it, an
224a7fd8e5eSmacallan	 * interloper, e.g. another server, can't get this frame buffer,
225a7fd8e5eSmacallan	 * and if another server already has it, this one won't.
226a7fd8e5eSmacallan	 */
227a7fd8e5eSmacallan	if (ro) {
228a7fd8e5eSmacallan		mapaddr = (pointer) mmap(NULL, len,
229a7fd8e5eSmacallan					 PROT_READ, MAP_SHARED,
230a7fd8e5eSmacallan					 fd, off);
2316d300f0aSchristos		xf86Msg(X_ERROR, "mapping %08tx read only\n", off);
232a7fd8e5eSmacallan	} else {
233a7fd8e5eSmacallan		mapaddr = (pointer) mmap(NULL, len,
234a7fd8e5eSmacallan					 PROT_READ | PROT_WRITE, MAP_SHARED,
235a7fd8e5eSmacallan					 fd, off);
2366d300f0aSchristos		xf86Msg(X_ERROR, "mapping %08tx read/write\n", off);
237a7fd8e5eSmacallan	}
238a7fd8e5eSmacallan	if (mapaddr == (pointer) -1) {
239a7fd8e5eSmacallan		mapaddr = NULL;
240a7fd8e5eSmacallan	}
241a7fd8e5eSmacallan#ifdef NGLE_DEBUG
242a7fd8e5eSmacallan	ErrorF("mmap returns: addr %p len 0x%x\n", mapaddr, len);
243a7fd8e5eSmacallan#endif
244a7fd8e5eSmacallan	return mapaddr;
245a7fd8e5eSmacallan}
246a7fd8e5eSmacallan
247a7fd8e5eSmacallanstatic Bool
248a7fd8e5eSmacallanNGLEProbe(DriverPtr drv, int flags)
249a7fd8e5eSmacallan{
250a7fd8e5eSmacallan	ScrnInfoPtr pScrn = NULL;
251a7fd8e5eSmacallan	int i, fd, entity, wstype;
252a7fd8e5eSmacallan       	GDevPtr *devSections;
253a7fd8e5eSmacallan	int numDevSections;
254a7fd8e5eSmacallan	char *dev;
255a7fd8e5eSmacallan	const char *name;
256a7fd8e5eSmacallan	uint32_t gid;
257a7fd8e5eSmacallan	Bool foundScreen = FALSE;
258a7fd8e5eSmacallan
259a7fd8e5eSmacallan	if ((numDevSections = xf86MatchDevice(NGLE_DRIVER_NAME,
260a7fd8e5eSmacallan					      &devSections)) <= 0)
261a7fd8e5eSmacallan		return FALSE;
262a7fd8e5eSmacallan
263a7fd8e5eSmacallan
264a7fd8e5eSmacallan	if ((fd = ngle_open(NGLE_DEFAULT_DEV)) == 0)
265a7fd8e5eSmacallan		return FALSE;
266a7fd8e5eSmacallan
267a7fd8e5eSmacallan	if (ioctl(fd, WSDISPLAYIO_GTYPE, &wstype) == -1)
268a7fd8e5eSmacallan		return FALSE;
269a7fd8e5eSmacallan
270a7fd8e5eSmacallan	if (wstype != WSDISPLAY_TYPE_STI)
271a7fd8e5eSmacallan		return FALSE;
272a7fd8e5eSmacallan
273a7fd8e5eSmacallan	if (ioctl(fd, GCID, &gid) == -1)
274a7fd8e5eSmacallan		return FALSE;
275a7fd8e5eSmacallan
276a7fd8e5eSmacallan	/* reject GIDs not in the table */
277a7fd8e5eSmacallan	if ((name = xf86TokenToString(NGLEChipsets, gid)) == NULL)
278a7fd8e5eSmacallan		return FALSE;
279a7fd8e5eSmacallan
280a7fd8e5eSmacallan	if ( xf86DoConfigure && xf86DoConfigurePass1 ) {
281a7fd8e5eSmacallan		GDevPtr pGDev;
282a7fd8e5eSmacallan
283a7fd8e5eSmacallan		pGDev = xf86AddBusDeviceToConfigure(NGLE_DRIVER_NAME, BUS_NONE,
284a7fd8e5eSmacallan			NULL, 0);
285a7fd8e5eSmacallan		if (pGDev) {
286a7fd8e5eSmacallan			/*
287a7fd8e5eSmacallan			 * XF86Match???Instances() treat chipID and chipRev as
288a7fd8e5eSmacallan			 * overrides, so clobber them here.
289a7fd8e5eSmacallan			 */
290a7fd8e5eSmacallan			pGDev->chipID = pGDev->chipRev = -1;
291a7fd8e5eSmacallan	    	}
292a7fd8e5eSmacallan	}
293a7fd8e5eSmacallan
294a7fd8e5eSmacallan	if (flags & PROBE_DETECT) {
295a7fd8e5eSmacallan		return TRUE;
296a7fd8e5eSmacallan	}
297a7fd8e5eSmacallan
298a7fd8e5eSmacallan	/* ok, at this point we know we've got a NGLE */
299a7fd8e5eSmacallan	for (i = 0; i < numDevSections; i++) {
300a7fd8e5eSmacallan
301a7fd8e5eSmacallan		entity = xf86ClaimFbSlot(drv, 0, devSections[i], TRUE);
302a7fd8e5eSmacallan		pScrn = xf86ConfigFbEntity(NULL, 0, entity,
303a7fd8e5eSmacallan		    NULL, NULL, NULL, NULL);
304a7fd8e5eSmacallan		if (pScrn != NULL) {
305a7fd8e5eSmacallan			foundScreen = TRUE;
306a7fd8e5eSmacallan			pScrn->driverVersion = VERSION;
307a7fd8e5eSmacallan			pScrn->driverName = NGLE_DRIVER_NAME;
308a7fd8e5eSmacallan			pScrn->name = NGLE_NAME;
309a7fd8e5eSmacallan			pScrn->Probe = NGLEProbe;
310a7fd8e5eSmacallan			pScrn->PreInit = NGLEPreInit;
311a7fd8e5eSmacallan			pScrn->ScreenInit = NGLEScreenInit;
312a7fd8e5eSmacallan			pScrn->SwitchMode = NGLESwitchMode;
313a7fd8e5eSmacallan			pScrn->AdjustFrame = NULL;
314a7fd8e5eSmacallan			pScrn->EnterVT = NGLEEnterVT;
315a7fd8e5eSmacallan			pScrn->LeaveVT = NGLELeaveVT;
316a7fd8e5eSmacallan			pScrn->ValidMode = NGLEValidMode;
317a7fd8e5eSmacallan
318a7fd8e5eSmacallan		}
319a7fd8e5eSmacallan	}
320a7fd8e5eSmacallan	free(devSections);
321a7fd8e5eSmacallan	return foundScreen;
322a7fd8e5eSmacallan}
323a7fd8e5eSmacallan
324a7fd8e5eSmacallanstatic Bool
325a7fd8e5eSmacallanNGLEPreInit(ScrnInfoPtr pScrn, int flags)
326a7fd8e5eSmacallan{
327a7fd8e5eSmacallan	NGLEPtr fPtr;
328727c6de2Smacallan	int default_depth, bitsperpixel, gid;
329a7fd8e5eSmacallan	const char *dev;
330a7fd8e5eSmacallan	char *mod = NULL;
331a7fd8e5eSmacallan	const char *reqSym = NULL;
332a7fd8e5eSmacallan	Gamma zeros = {0.0, 0.0, 0.0};
333a7fd8e5eSmacallan	DisplayModePtr mode;
334a7fd8e5eSmacallan	MessageType from;
335a7fd8e5eSmacallan	rgb rgbzeros = { 0, 0, 0 }, masks;
336a7fd8e5eSmacallan
337a7fd8e5eSmacallan	if (flags & PROBE_DETECT) return FALSE;
338a7fd8e5eSmacallan
339a7fd8e5eSmacallan	if (pScrn->numEntities != 1) return FALSE;
340a7fd8e5eSmacallan
341a7fd8e5eSmacallan	pScrn->monitor = pScrn->confScreen->monitor;
342a7fd8e5eSmacallan
343a7fd8e5eSmacallan	NGLEGetRec(pScrn);
344a7fd8e5eSmacallan	fPtr = NGLEPTR(pScrn);
345a7fd8e5eSmacallan
346a7fd8e5eSmacallan	fPtr->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
347a7fd8e5eSmacallan
348a7fd8e5eSmacallan	dev = xf86FindOptionValue(fPtr->pEnt->device->options, "device");
349a7fd8e5eSmacallan	fPtr->fd = ngle_open(dev);
350a7fd8e5eSmacallan	if (fPtr->fd == -1) {
351a7fd8e5eSmacallan		return FALSE;
352a7fd8e5eSmacallan	}
353a7fd8e5eSmacallan
354a7fd8e5eSmacallan	if (ioctl(fPtr->fd, WSDISPLAYIO_GET_FBINFO, &fPtr->fbi) == -1) {
355a7fd8e5eSmacallan		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
356a7fd8e5eSmacallan			   "ioctl WSDISPLAY_GINFO: %s\n",
357a7fd8e5eSmacallan			   strerror(errno));
358a7fd8e5eSmacallan		return FALSE;
359a7fd8e5eSmacallan	}
360727c6de2Smacallan
361727c6de2Smacallan	if (ioctl(fPtr->fd, GCID, &gid) == -1)
362a7fd8e5eSmacallan		return FALSE;
363727c6de2Smacallan
364727c6de2Smacallan	fPtr->gid = gid;
365727c6de2Smacallan	fPtr->fbacc = 0;
366727c6de2Smacallan
367727c6de2Smacallan	switch (gid) {
368727c6de2Smacallan		case STI_DD_EG:
369bc460d0dSmacallan			fPtr->buf = BINapp0I;
370727c6de2Smacallan			fPtr->fbacc = BA(IndexedDcd, Otc04, Ots08, AddrByte, 0, fPtr->buf, 0);
3717517da51Smacallan			fPtr->reglen = 0x400000;
372727c6de2Smacallan			break;
373727c6de2Smacallan		case STI_DD_HCRX:
374727c6de2Smacallan			/* XXX BINovly if in 8 bit */
375727c6de2Smacallan			fPtr->buf = BINapp0F8;
376727c6de2Smacallan			fPtr->fbacc = BA(IndexedDcd, Otc04, Ots08, AddrLong, 0, fPtr->buf, 0);
377ce159321Smacallan			/*
378ce159321Smacallan			 * XXX
379ce159321Smacallan			 * we don't know yet how much usable video memory we
380ce159321Smacallan			 * have but EXA gets cranky if there is no off screen
381ce159321Smacallan			 * memory at all, so we give it one line and cross
382ce159321Smacallan			 * fingers
383ce159321Smacallan			 */
384ce159321Smacallan			fPtr->fbi.fbi_fbsize += 8192;
3857517da51Smacallan			fPtr->reglen = 0x400000;
3867517da51Smacallan			break;
3877517da51Smacallan		case STI_DD_SUMMIT:
3887517da51Smacallan			fPtr->reglen = 0x1000000;
3897517da51Smacallan			break;
390a7fd8e5eSmacallan	}
3913441c0edSmacallan	xf86Msg(X_INFO, "%s: found %s ( GID %08x )\n",
3923441c0edSmacallan	    __func__, xf86TokenToString(NGLEChipsets, gid), gid);
393727c6de2Smacallan
394a7fd8e5eSmacallan	/* Handle depth */
395a7fd8e5eSmacallan	default_depth = fPtr->fbi.fbi_bitsperpixel <= 24 ? fPtr->fbi.fbi_bitsperpixel : 24;
396a7fd8e5eSmacallan	bitsperpixel = fPtr->fbi.fbi_bitsperpixel == 15 ? 16 : fPtr->fbi.fbi_bitsperpixel;
397a7fd8e5eSmacallan	if (!xf86SetDepthBpp(pScrn, default_depth, default_depth,
398a7fd8e5eSmacallan		bitsperpixel,
399a7fd8e5eSmacallan		bitsperpixel >= 24 ? Support24bppFb|Support32bppFb : 0))
400a7fd8e5eSmacallan		return FALSE;
401a7fd8e5eSmacallan
402a7fd8e5eSmacallan	xf86PrintDepthBpp(pScrn);
403a7fd8e5eSmacallan
404a7fd8e5eSmacallan	/* color weight */
405a7fd8e5eSmacallan	masks.red =   0x00ff0000;
406a7fd8e5eSmacallan	masks.green = 0x0000ff00;
407a7fd8e5eSmacallan	masks.blue =  0x000000ff;
408a7fd8e5eSmacallan	if (!xf86SetWeight(pScrn, rgbzeros, masks))
409a7fd8e5eSmacallan		return FALSE;
410a7fd8e5eSmacallan
411a7fd8e5eSmacallan	/* visual init */
412a7fd8e5eSmacallan	if (!xf86SetDefaultVisual(pScrn, -1))
413a7fd8e5eSmacallan		return FALSE;
414a7fd8e5eSmacallan
415a7fd8e5eSmacallan	/* We don't currently support DirectColor at > 8bpp */
416a7fd8e5eSmacallan	if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
417a7fd8e5eSmacallan		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
418a7fd8e5eSmacallan			   " (%s) is not supported at depth %d\n",
419a7fd8e5eSmacallan			   xf86GetVisualName(pScrn->defaultVisual),
420a7fd8e5eSmacallan			   pScrn->depth);
421a7fd8e5eSmacallan		return FALSE;
422a7fd8e5eSmacallan	}
423a7fd8e5eSmacallan
424a7fd8e5eSmacallan	xf86SetGamma(pScrn,zeros);
425a7fd8e5eSmacallan
426a7fd8e5eSmacallan	pScrn->progClock = TRUE;
427a7fd8e5eSmacallan	pScrn->rgbBits   = 8;
428a7fd8e5eSmacallan	pScrn->chipset   = "NGLE";
429a7fd8e5eSmacallan	fPtr->fbmem_len = pScrn->videoRam  = fPtr->fbi.fbi_fbsize;
430a7fd8e5eSmacallan
431a7fd8e5eSmacallan	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vidmem: %dk\n",
432a7fd8e5eSmacallan		   pScrn->videoRam/1024);
433a7fd8e5eSmacallan
434a7fd8e5eSmacallan	/* handle options */
435a7fd8e5eSmacallan	xf86CollectOptions(pScrn, NULL);
436a7fd8e5eSmacallan	if (!(fPtr->Options = malloc(sizeof(NGLEOptions))))
437a7fd8e5eSmacallan		return FALSE;
438a7fd8e5eSmacallan	memcpy(fPtr->Options, NGLEOptions, sizeof(NGLEOptions));
439a7fd8e5eSmacallan	xf86ProcessOptions(pScrn->scrnIndex, fPtr->pEnt->device->options,
440a7fd8e5eSmacallan			   fPtr->Options);
441a7fd8e5eSmacallan
442a7fd8e5eSmacallan	/* fake video mode struct */
443a7fd8e5eSmacallan	mode = (DisplayModePtr)malloc(sizeof(DisplayModeRec));
444a7fd8e5eSmacallan	mode->prev = mode;
445a7fd8e5eSmacallan	mode->next = mode;
446a7fd8e5eSmacallan	mode->name = "NGLE current mode";
447a7fd8e5eSmacallan	mode->status = MODE_OK;
448a7fd8e5eSmacallan	mode->type = M_T_BUILTIN;
449a7fd8e5eSmacallan	mode->Clock = 0;
450a7fd8e5eSmacallan	mode->HDisplay = fPtr->fbi.fbi_width;
451a7fd8e5eSmacallan	mode->HSyncStart = 0;
452a7fd8e5eSmacallan	mode->HSyncEnd = 0;
453a7fd8e5eSmacallan	mode->HTotal = 0;
454a7fd8e5eSmacallan	mode->HSkew = 0;
455a7fd8e5eSmacallan	mode->VDisplay = fPtr->fbi.fbi_height;
456a7fd8e5eSmacallan	mode->VSyncStart = 0;
457a7fd8e5eSmacallan	mode->VSyncEnd = 0;
458a7fd8e5eSmacallan	mode->VTotal = 0;
459a7fd8e5eSmacallan	mode->VScan = 0;
460a7fd8e5eSmacallan	mode->Flags = 0;
461a7fd8e5eSmacallan	if (pScrn->modes != NULL) {
462a7fd8e5eSmacallan		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
463a7fd8e5eSmacallan		   "Ignoring mode specification from screen section\n");
464a7fd8e5eSmacallan	}
465a7fd8e5eSmacallan	pScrn->currentMode = pScrn->modes = mode;
466a7fd8e5eSmacallan	pScrn->virtualX = fPtr->fbi.fbi_width;
467a7fd8e5eSmacallan	pScrn->virtualY = fPtr->fbi.fbi_height;
468a7fd8e5eSmacallan	pScrn->displayWidth = 2048;
469a7fd8e5eSmacallan
470a7fd8e5eSmacallan	/* Set the display resolution */
471a7fd8e5eSmacallan	xf86SetDpi(pScrn, 0, 0);
472a7fd8e5eSmacallan
473a7fd8e5eSmacallan	from = X_DEFAULT;
4747517da51Smacallan	fPtr->HWCursor = FALSE;
4757517da51Smacallan	if (xf86GetOptValBool(fPtr->Options, OPTION_HW_CURSOR, &fPtr->HWCursor)) {
476a7fd8e5eSmacallan		from = X_CONFIG;
4777517da51Smacallan		fPtr->HWCursor = TRUE;
478a7fd8e5eSmacallan	}
479a7fd8e5eSmacallan	xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
480a7fd8e5eSmacallan		fPtr->HWCursor ? "HW" : "SW");
481a7fd8e5eSmacallan
482a7fd8e5eSmacallan	if (xf86LoadSubModule(pScrn, "fb") == NULL) {
483a7fd8e5eSmacallan		NGLEFreeRec(pScrn);
484a7fd8e5eSmacallan		return FALSE;
485a7fd8e5eSmacallan	}
486a7fd8e5eSmacallan
487a7fd8e5eSmacallan	if (xf86LoadSubModule(pScrn, "exa") == NULL) {
488a7fd8e5eSmacallan		NGLEFreeRec(pScrn);
489a7fd8e5eSmacallan		return FALSE;
490a7fd8e5eSmacallan	}
491a7fd8e5eSmacallan
492a7fd8e5eSmacallan	return TRUE;
493a7fd8e5eSmacallan}
494a7fd8e5eSmacallan
495a7fd8e5eSmacallanstatic Bool
496a7fd8e5eSmacallanNGLEScreenInit(SCREEN_INIT_ARGS_DECL)
497a7fd8e5eSmacallan{
498a7fd8e5eSmacallan	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
499a7fd8e5eSmacallan	NGLEPtr fPtr = NGLEPTR(pScrn);
500a7fd8e5eSmacallan	VisualPtr visual;
501a7fd8e5eSmacallan	int ret, flags, width, height, i, j;
502a7fd8e5eSmacallan	int wsmode = WSDISPLAYIO_MODE_MAPPED;
503a7fd8e5eSmacallan	size_t len;
504a7fd8e5eSmacallan
505a7fd8e5eSmacallan#ifdef NGLE_DEBUG
506a7fd8e5eSmacallan	ErrorF("\tbitsPerPixel=%d, depth=%d, defaultVisual=%s\n"
507a7fd8e5eSmacallan	       "\tmask: %x,%x,%x, offset: %d,%d,%d\n",
508a7fd8e5eSmacallan	       pScrn->bitsPerPixel,
509a7fd8e5eSmacallan	       pScrn->depth,
510a7fd8e5eSmacallan	       xf86GetVisualName(pScrn->defaultVisual),
511a7fd8e5eSmacallan	       pScrn->mask.red,pScrn->mask.green,pScrn->mask.blue,
512a7fd8e5eSmacallan	       pScrn->offset.red,pScrn->offset.green,pScrn->offset.blue);
513a7fd8e5eSmacallan#endif
514a7fd8e5eSmacallan
515a7fd8e5eSmacallan	/* Switch to graphics mode - required before mmap */
516a7fd8e5eSmacallan	if (ioctl(fPtr->fd, WSDISPLAYIO_SMODE, &wsmode) == -1) {
517a7fd8e5eSmacallan		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
518a7fd8e5eSmacallan			   "ioctl WSDISPLAYIO_SMODE: %s\n",
519a7fd8e5eSmacallan			   strerror(errno));
520a7fd8e5eSmacallan		return FALSE;
521a7fd8e5eSmacallan	}
5227517da51Smacallan
5237517da51Smacallan	fPtr->regs = ngle_mmap(fPtr->reglen, 0x80000000, fPtr->fd, 0);
524a7fd8e5eSmacallan
525a7fd8e5eSmacallan	if (fPtr->regs == NULL) {
526a7fd8e5eSmacallan		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
527a7fd8e5eSmacallan			   "ngle_mmap registers: %s\n", strerror(errno));
528a7fd8e5eSmacallan		return FALSE;
529a7fd8e5eSmacallan	}
530a7fd8e5eSmacallan
531a7fd8e5eSmacallan	fPtr->fbmem = ngle_mmap(fPtr->fbmem_len, 0, fPtr->fd, 0);
532a7fd8e5eSmacallan	if (fPtr->fbmem == NULL) {
533a7fd8e5eSmacallan		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
534a7fd8e5eSmacallan			   "ngle_mmap fb: %s\n", strerror(errno));
535a7fd8e5eSmacallan		return FALSE;
536a7fd8e5eSmacallan	}
537a7fd8e5eSmacallan
538a7fd8e5eSmacallan	NGLESave(pScrn);
539a7fd8e5eSmacallan	pScrn->vtSema = TRUE;
540a7fd8e5eSmacallan
541a7fd8e5eSmacallan	/* mi layer */
542a7fd8e5eSmacallan	miClearVisualTypes();
54388c8ff34Smacallan	if (pScrn->bitsPerPixel > 8) {
54488c8ff34Smacallan		if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
54588c8ff34Smacallan				      pScrn->rgbBits, TrueColor))
54688c8ff34Smacallan			return FALSE;
54788c8ff34Smacallan	} else {
54888c8ff34Smacallan		if (!miSetVisualTypes(pScrn->depth,
54988c8ff34Smacallan				      miGetDefaultVisualMask(pScrn->depth),
55088c8ff34Smacallan				      pScrn->rgbBits, pScrn->defaultVisual))
55188c8ff34Smacallan			return FALSE;
55288c8ff34Smacallan	}
553a7fd8e5eSmacallan
554a7fd8e5eSmacallan	if (!miSetPixmapDepths())
555a7fd8e5eSmacallan		return FALSE;
556a7fd8e5eSmacallan
557a7fd8e5eSmacallan	height = pScrn->virtualY;
558a7fd8e5eSmacallan	width = pScrn->virtualX;
559a7fd8e5eSmacallan
560a7fd8e5eSmacallan	ret = fbScreenInit(pScreen,
561a7fd8e5eSmacallan			   fPtr->fbmem,
562a7fd8e5eSmacallan			   width, height,
563a7fd8e5eSmacallan			   pScrn->xDpi, pScrn->yDpi,
564a7fd8e5eSmacallan			   pScrn->displayWidth,
565a7fd8e5eSmacallan			   pScrn->bitsPerPixel);
566a7fd8e5eSmacallan
567a7fd8e5eSmacallan	if (!ret)
568a7fd8e5eSmacallan		return FALSE;
569a7fd8e5eSmacallan
570a7fd8e5eSmacallan	if (pScrn->bitsPerPixel > 8) {
571a7fd8e5eSmacallan		/* Fixup RGB ordering. */
572a7fd8e5eSmacallan		visual = pScreen->visuals + pScreen->numVisuals;
573a7fd8e5eSmacallan		while (--visual >= pScreen->visuals) {
574a7fd8e5eSmacallan			if ((visual->class | DynamicClass) == DirectColor) {
575a7fd8e5eSmacallan				visual->offsetRed   = pScrn->offset.red;
576a7fd8e5eSmacallan				visual->offsetGreen = pScrn->offset.green;
577a7fd8e5eSmacallan				visual->offsetBlue  = pScrn->offset.blue;
578a7fd8e5eSmacallan				visual->redMask     = pScrn->mask.red;
579a7fd8e5eSmacallan				visual->greenMask   = pScrn->mask.green;
580a7fd8e5eSmacallan				visual->blueMask    = pScrn->mask.blue;
581a7fd8e5eSmacallan			}
582a7fd8e5eSmacallan		}
583a7fd8e5eSmacallan	}
584a7fd8e5eSmacallan
585a7fd8e5eSmacallan	if (!fbPictureInit(pScreen, NULL, 0))
586a7fd8e5eSmacallan		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
587a7fd8e5eSmacallan			   "RENDER extension initialisation failed.");
588a7fd8e5eSmacallan
589a7fd8e5eSmacallan	xf86SetBlackWhitePixels(pScreen);
590a7fd8e5eSmacallan	xf86SetBackingStore(pScreen);
591a7fd8e5eSmacallan
592a7fd8e5eSmacallan	if (fPtr) {
5937517da51Smacallan		if (fPtr->gid == STI_DD_SUMMIT) {
5947517da51Smacallan			SummitInitAccel(pScreen);
5957517da51Smacallan		} else
5967517da51Smacallan			NGLEInitAccel(pScreen);
597727c6de2Smacallan		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using acceleration\n");
598a7fd8e5eSmacallan	}
599a7fd8e5eSmacallan
600a7fd8e5eSmacallan	/* software cursor */
601a7fd8e5eSmacallan	miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
602a7fd8e5eSmacallan
603a7fd8e5eSmacallan	/* check for hardware cursor support */
6047a5287f7Smacallan	if (fPtr->gid == STI_DD_SUMMIT) {
6057a5287f7Smacallan		SummitSetupCursor(pScreen);
6067a5287f7Smacallan	} else
6077a5287f7Smacallan		NGLESetupCursor(pScreen);
608a7fd8e5eSmacallan
609a7fd8e5eSmacallan	/* colormap */
610a7fd8e5eSmacallan	if (!miCreateDefColormap(pScreen))
611a7fd8e5eSmacallan		return FALSE;
612a7fd8e5eSmacallan
613a7fd8e5eSmacallan	flags = CMAP_RELOAD_ON_MODE_SWITCH;
614a7fd8e5eSmacallan	if(!xf86HandleColormaps(pScreen, 256, 8, NGLELoadPalette,
615a7fd8e5eSmacallan				NULL, flags))
616a7fd8e5eSmacallan		return FALSE;
617a7fd8e5eSmacallan
618a7fd8e5eSmacallan	pScreen->SaveScreen = NGLESaveScreen;
619a7fd8e5eSmacallan
620a7fd8e5eSmacallan#ifdef XvExtension
621a7fd8e5eSmacallan	{
622a7fd8e5eSmacallan		XF86VideoAdaptorPtr *ptr;
623a7fd8e5eSmacallan
624a7fd8e5eSmacallan		int n = xf86XVListGenericAdaptors(pScrn,&ptr);
625a7fd8e5eSmacallan		if (n) {
626a7fd8e5eSmacallan			xf86XVScreenInit(pScreen,ptr,n);
627a7fd8e5eSmacallan		}
628a7fd8e5eSmacallan	}
629a7fd8e5eSmacallan#endif
630a7fd8e5eSmacallan
631a7fd8e5eSmacallan	/* Wrap the current CloseScreen function */
632a7fd8e5eSmacallan	fPtr->CloseScreen = pScreen->CloseScreen;
633a7fd8e5eSmacallan	pScreen->CloseScreen = NGLECloseScreen;
634a7fd8e5eSmacallan
635a7fd8e5eSmacallan	return TRUE;
636a7fd8e5eSmacallan}
637a7fd8e5eSmacallan
638a7fd8e5eSmacallanstatic Bool
639a7fd8e5eSmacallanNGLECloseScreen(CLOSE_SCREEN_ARGS_DECL)
640a7fd8e5eSmacallan{
641a7fd8e5eSmacallan	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
642a7fd8e5eSmacallan	NGLEPtr fPtr = NGLEPTR(pScrn);
643a7fd8e5eSmacallan
644a7fd8e5eSmacallan	if (pScrn->vtSema) {
645a7fd8e5eSmacallan		NGLERestore(pScrn);
6467517da51Smacallan		if (munmap(fPtr->regs, fPtr->reglen) == -1) {
647a7fd8e5eSmacallan			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
648a7fd8e5eSmacallan				   "munmap engine: %s\n", strerror(errno));
649a7fd8e5eSmacallan		}
650a7fd8e5eSmacallan
651a7fd8e5eSmacallan		if (munmap(fPtr->fbmem, fPtr->fbmem_len) == -1) {
652a7fd8e5eSmacallan			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
653a7fd8e5eSmacallan				   "munmap fb: %s\n", strerror(errno));
654a7fd8e5eSmacallan		}
655a7fd8e5eSmacallan
656a7fd8e5eSmacallan		fPtr->regs = NULL;
657a7fd8e5eSmacallan		fPtr->fbmem = NULL;
658a7fd8e5eSmacallan	}
659a7fd8e5eSmacallan	pScrn->vtSema = FALSE;
660a7fd8e5eSmacallan
661a7fd8e5eSmacallan	/* unwrap CloseScreen */
662a7fd8e5eSmacallan	pScreen->CloseScreen = fPtr->CloseScreen;
663a7fd8e5eSmacallan	return (*pScreen->CloseScreen)(pScreen);
664a7fd8e5eSmacallan}
665a7fd8e5eSmacallan
666a7fd8e5eSmacallanstatic Bool
667a7fd8e5eSmacallanNGLEEnterVT(VT_FUNC_ARGS_DECL)
668a7fd8e5eSmacallan{
669a7fd8e5eSmacallan	SCRN_INFO_PTR(arg);
670a7fd8e5eSmacallan
671a7fd8e5eSmacallan	pScrn->vtSema = TRUE;
672a7fd8e5eSmacallan	return TRUE;
673a7fd8e5eSmacallan}
674a7fd8e5eSmacallan
675a7fd8e5eSmacallanstatic void
676a7fd8e5eSmacallanNGLELeaveVT(VT_FUNC_ARGS_DECL)
677a7fd8e5eSmacallan{
678a7fd8e5eSmacallan}
679a7fd8e5eSmacallan
680a7fd8e5eSmacallanstatic Bool
681a7fd8e5eSmacallanNGLESwitchMode(SWITCH_MODE_ARGS_DECL)
682a7fd8e5eSmacallan{
683a7fd8e5eSmacallan
684a7fd8e5eSmacallan	/* Nothing else to do */
685a7fd8e5eSmacallan	return TRUE;
686a7fd8e5eSmacallan}
687a7fd8e5eSmacallan
688a7fd8e5eSmacallanstatic int
6896d300f0aSchristosNGLEValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags)
690a7fd8e5eSmacallan{
691a7fd8e5eSmacallan
692a7fd8e5eSmacallan	return MODE_OK;
693a7fd8e5eSmacallan}
694a7fd8e5eSmacallan
695a7fd8e5eSmacallanstatic void
696a7fd8e5eSmacallanNGLELoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
697a7fd8e5eSmacallan	       LOCO *colors, VisualPtr pVisual)
698a7fd8e5eSmacallan{
699a7fd8e5eSmacallan	NGLEPtr fPtr = NGLEPTR(pScrn);
700a7fd8e5eSmacallan	struct wsdisplay_cmap cmap;
701a7fd8e5eSmacallan	unsigned char red[256],green[256],blue[256];
702a7fd8e5eSmacallan	int i, indexMin=256, indexMax=0;
703a7fd8e5eSmacallan
704a7fd8e5eSmacallan	/* nothing to do if there is no color palette support */
705a7fd8e5eSmacallan	if (fPtr->fbi.fbi_subtype.fbi_cmapinfo.cmap_entries == 0)
706a7fd8e5eSmacallan		return;
707a7fd8e5eSmacallan
708a7fd8e5eSmacallan	cmap.count   = 1;
709a7fd8e5eSmacallan	cmap.red   = red;
710a7fd8e5eSmacallan	cmap.green = green;
711a7fd8e5eSmacallan	cmap.blue  = blue;
712a7fd8e5eSmacallan
713a7fd8e5eSmacallan	if (numColors == 1) {
714a7fd8e5eSmacallan		/* Optimisation */
715a7fd8e5eSmacallan		cmap.index = indices[0];
716a7fd8e5eSmacallan		red[0]   = colors[indices[0]].red;
717a7fd8e5eSmacallan		green[0] = colors[indices[0]].green;
718a7fd8e5eSmacallan		blue[0]  = colors[indices[0]].blue;
719a7fd8e5eSmacallan		if (ioctl(fPtr->fd,WSDISPLAYIO_PUTCMAP, &cmap) == -1)
720a7fd8e5eSmacallan			ErrorF("ioctl FBIOPUTCMAP: %s\n", strerror(errno));
721a7fd8e5eSmacallan	} else {
722a7fd8e5eSmacallan		/*
723a7fd8e5eSmacallan		 * Change all colors in 2 ioctls
724a7fd8e5eSmacallan		 * and limit the data to be transferred.
725a7fd8e5eSmacallan		 */
726a7fd8e5eSmacallan		for (i = 0; i < numColors; i++) {
727a7fd8e5eSmacallan			if (indices[i] < indexMin)
728a7fd8e5eSmacallan				indexMin = indices[i];
729a7fd8e5eSmacallan			if (indices[i] > indexMax)
730a7fd8e5eSmacallan				indexMax = indices[i];
731a7fd8e5eSmacallan		}
732a7fd8e5eSmacallan		cmap.index = indexMin;
733a7fd8e5eSmacallan		cmap.count = indexMax - indexMin + 1;
734a7fd8e5eSmacallan		cmap.red = &red[indexMin];
735a7fd8e5eSmacallan		cmap.green = &green[indexMin];
736a7fd8e5eSmacallan		cmap.blue = &blue[indexMin];
737a7fd8e5eSmacallan		/* Get current map. */
738a7fd8e5eSmacallan		if (ioctl(fPtr->fd, WSDISPLAYIO_GETCMAP, &cmap) == -1)
739a7fd8e5eSmacallan			ErrorF("ioctl FBIOGETCMAP: %s\n", strerror(errno));
740a7fd8e5eSmacallan		/* Change the colors that require updating. */
741a7fd8e5eSmacallan		for (i = 0; i < numColors; i++) {
742a7fd8e5eSmacallan			red[indices[i]]   = colors[indices[i]].red;
743a7fd8e5eSmacallan			green[indices[i]] = colors[indices[i]].green;
744a7fd8e5eSmacallan			blue[indices[i]]  = colors[indices[i]].blue;
745a7fd8e5eSmacallan		}
746a7fd8e5eSmacallan		/* Write the colormap back. */
747a7fd8e5eSmacallan		if (ioctl(fPtr->fd,WSDISPLAYIO_PUTCMAP, &cmap) == -1)
748a7fd8e5eSmacallan			ErrorF("ioctl FBIOPUTCMAP: %s\n", strerror(errno));
749a7fd8e5eSmacallan	}
750f8e8ce30Smacallan	fPtr->hwmode = -1;
751a7fd8e5eSmacallan}
752a7fd8e5eSmacallan
753a7fd8e5eSmacallanstatic Bool
754a7fd8e5eSmacallanNGLESaveScreen(ScreenPtr pScreen, int mode)
755a7fd8e5eSmacallan{
756a7fd8e5eSmacallan	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
757a7fd8e5eSmacallan	NGLEPtr fPtr = NGLEPTR(pScrn);
758a7fd8e5eSmacallan	int state;
759a7fd8e5eSmacallan
760a7fd8e5eSmacallan	if (!pScrn->vtSema)
761a7fd8e5eSmacallan		return TRUE;
762a7fd8e5eSmacallan
763a7fd8e5eSmacallan	if (mode != SCREEN_SAVER_FORCER) {
764a7fd8e5eSmacallan		state = xf86IsUnblank(mode)?WSDISPLAYIO_VIDEO_ON:
765a7fd8e5eSmacallan		                            WSDISPLAYIO_VIDEO_OFF;
766a7fd8e5eSmacallan		ioctl(fPtr->fd,
767a7fd8e5eSmacallan		      WSDISPLAYIO_SVIDEO, &state);
768a7fd8e5eSmacallan	}
769a7fd8e5eSmacallan	return TRUE;
770a7fd8e5eSmacallan}
771a7fd8e5eSmacallan
772a7fd8e5eSmacallan
773a7fd8e5eSmacallanstatic void
774a7fd8e5eSmacallanNGLESave(ScrnInfoPtr pScrn)
775a7fd8e5eSmacallan{
776a7fd8e5eSmacallan}
777a7fd8e5eSmacallan
778a7fd8e5eSmacallanstatic void
779a7fd8e5eSmacallanNGLERestore(ScrnInfoPtr pScrn)
780a7fd8e5eSmacallan{
781a7fd8e5eSmacallan	NGLEPtr fPtr = NGLEPTR(pScrn);
782a7fd8e5eSmacallan	int mode;
783a7fd8e5eSmacallan
784a7fd8e5eSmacallan	/* Restore the text mode */
785a7fd8e5eSmacallan	mode = WSDISPLAYIO_MODE_EMUL;
786a7fd8e5eSmacallan	if (ioctl(fPtr->fd, WSDISPLAYIO_SMODE, &mode) == -1) {
787a7fd8e5eSmacallan		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
788a7fd8e5eSmacallan			   "error setting text mode %s\n", strerror(errno));
789a7fd8e5eSmacallan	}
790a7fd8e5eSmacallan}
791