Initial commit
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / os-support / solaris / sun_agp.c
blobe97ab9ef9a1ab2b3b64830f44770cd8faf54cf86
1 /*
2 * Abstraction of the AGP GART interface.
4 * This version is for Solaris.
6 * Copyright © 2000 VA Linux Systems, Inc.
7 * Copyright © 2001 The XFree86 Project, Inc.
8 */
9 /* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the
13 * "Software"), to deal in the Software without restriction, including
14 * without limitation the rights to use, copy, modify, merge, publish,
15 * distribute, and/or sell copies of the Software, and to permit persons
16 * to whom the Software is furnished to do so, provided that the above
17 * copyright notice(s) and this permission notice appear in all copies of
18 * the Software and that both the above copyright notice(s) and this
19 * permission notice appear in supporting documentation.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
24 * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
25 * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
26 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
27 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
28 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
29 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
31 * Except as contained in this notice, the name of a copyright holder
32 * shall not be used in advertising or otherwise to promote the sale, use
33 * or other dealings in this Software without prior written authorization
34 * of the copyright holder.
37 #pragma ident "@(#)sun_agp.c 1.1 05/04/04 SMI"
39 #ifdef HAVE_XORG_CONFIG_H
40 #include <xorg-config.h>
41 #endif
43 #include <X11/X.h>
44 #include "xf86.h"
45 #include "xf86Priv.h"
46 #include "xf86_OSlib.h"
47 #include "xf86_OSproc.h"
48 #include <unistd.h>
49 #include <sys/ioccom.h>
50 #include <sys/types.h>
51 #include <fcntl.h>
52 #include "agpgart.h"
54 #ifndef AGP_DEVICE
55 #define AGP_DEVICE "/dev/agpgart"
56 #endif
57 /* AGP page size is independent of the host page size. */
58 #ifndef AGP_PAGE_SIZE
59 #define AGP_PAGE_SIZE 4096
60 #endif
62 static int gartFd = -1;
63 static int acquiredScreen = -1;
64 static Bool initDone = FALSE;
66 * Close /dev/agpgart. This frees all associated memory allocated during
67 * this server generation.
69 _X_EXPORT Bool
70 xf86GARTCloseScreen(int screenNum)
72 if (gartFd != -1) {
73 close(gartFd);
74 acquiredScreen = -1;
75 gartFd = -1;
76 initDone = FALSE;
78 xf86DrvMsg(screenNum, X_INFO,
79 "xf86GARTCloseScreen: device closed successfully\n");
82 return TRUE;
86 * Open /dev/agpgart. Keep it open until xf86GARTCloseScreen is called.
88 static Bool
89 GARTInit(int screenNum)
91 if (initDone)
92 return (gartFd != -1);
94 if (gartFd == -1)
95 gartFd = open(AGP_DEVICE, O_RDWR);
96 else
97 return FALSE;
99 if (gartFd == -1) {
100 xf86DrvMsg(screenNum, X_ERROR,
101 "GARTInit: Unable to open " AGP_DEVICE " (%s)\n",
102 strerror(errno));
103 return FALSE;
106 initDone = TRUE;
107 xf86DrvMsg(screenNum, X_INFO,
108 "GARTInit: " AGP_DEVICE " opened successfully\n");
110 return TRUE;
113 _X_EXPORT Bool
114 xf86AgpGARTSupported(void)
116 return (GARTInit(-1));
120 _X_EXPORT AgpInfoPtr
121 xf86GetAGPInfo(int screenNum)
123 agp_info_t agpinf;
124 AgpInfoPtr info;
126 if (!GARTInit(screenNum))
127 return NULL;
129 if ((info = xcalloc(sizeof(AgpInfo), 1)) == NULL) {
130 xf86DrvMsg(screenNum, X_ERROR,
131 "xf86GetAGPInfo: Failed to allocate AgpInfo\n");
132 return NULL;
135 if (ioctl(gartFd, AGPIOC_INFO, &agpinf) != 0) {
136 xf86DrvMsg(screenNum, X_ERROR,
137 "xf86GetAGPInfo: AGPIOC_INFO failed (%s)\n",
138 strerror(errno));
139 return NULL;
142 info->bridgeId = agpinf.agpi_devid;
143 info->agpMode = agpinf.agpi_mode;
144 info->base = agpinf.agpi_aperbase;
145 info->size = agpinf.agpi_apersize;
146 info->totalPages = (unsigned long)agpinf.agpi_pgtotal;
147 info->systemPages = (unsigned long)agpinf.agpi_pgsystem;
148 info->usedPages = (unsigned long)agpinf.agpi_pgused;
150 return info;
153 _X_EXPORT Bool
154 xf86AcquireGART(int screenNum)
157 if (!GARTInit(screenNum))
158 return FALSE;
160 if (acquiredScreen != screenNum) {
161 if (ioctl(gartFd, AGPIOC_ACQUIRE, 0) != 0) {
162 xf86DrvMsg(screenNum, X_WARNING,
163 "xf86AcquireGART: AGPIOC_ACQUIRE failed (%s)\n",
164 strerror(errno));
165 return FALSE;
167 acquiredScreen = screenNum;
168 xf86DrvMsg(screenNum, X_INFO,
169 "xf86AcquireGART: AGPIOC_ACQUIRE succeeded\n");
171 return TRUE;
174 _X_EXPORT Bool
175 xf86ReleaseGART(int screenNum)
178 if (!GARTInit(screenNum))
179 return FALSE;
181 if (acquiredScreen == screenNum) {
183 * The FreeBSD agp driver removes allocations on release.
184 * The Solaris driver doesn't. xf86ReleaseGART() is expected
185 * to give up access to the GART, but not to remove any
186 * allocations.
189 if (ioctl(gartFd, AGPIOC_RELEASE, 0) != 0) {
190 xf86DrvMsg(screenNum, X_WARNING,
191 "xf86ReleaseGART: AGPIOC_RELEASE failed (%s)\n",
192 strerror(errno));
193 return FALSE;
195 acquiredScreen = -1;
196 xf86DrvMsg(screenNum, X_INFO,
197 "xf86ReleaseGART: AGPIOC_RELEASE succeeded\n");
198 return TRUE;
200 return FALSE;
203 _X_EXPORT int
204 xf86AllocateGARTMemory(int screenNum, unsigned long size, int type,
205 unsigned long *physical)
207 agp_allocate_t alloc;
208 int pages;
211 * Allocates "size" bytes of GART memory (rounds up to the next
212 * page multiple) or type "type". A handle (key) for the allocated
213 * memory is returned. On error, the return value is -1.
214 * "size" should be larger than 0, or AGPIOC_ALLOCATE ioctl will
215 * return error.
218 if (!GARTInit(screenNum) || (acquiredScreen != screenNum))
219 return -1;
221 pages = (size / AGP_PAGE_SIZE);
222 if (size % AGP_PAGE_SIZE != 0)
223 pages++;
225 alloc.agpa_pgcount = pages;
226 alloc.agpa_type = type;
228 if (ioctl(gartFd, AGPIOC_ALLOCATE, &alloc) != 0) {
229 xf86DrvMsg(screenNum, X_WARNING, "xf86AllocateGARTMemory: "
230 "allocation of %d pages failed\n\t(%s)\n", pages,
231 strerror(errno));
232 return -1;
235 if (physical)
236 *physical = (unsigned long)alloc.agpa_physical;
238 return alloc.agpa_key;
241 _X_EXPORT Bool
242 xf86DeallocateGARTMemory(int screenNum, int key)
244 if (!GARTInit(screenNum) || (acquiredScreen != screenNum))
245 return FALSE;
247 if (ioctl(gartFd, AGPIOC_DEALLOCATE, (int *)key) != 0) {
248 xf86DrvMsg(screenNum, X_WARNING, "xf86DeAllocateGARTMemory: "
249 "deallocation of gart memory with key %d failed\n"
250 "\t(%s)\n", key, strerror(errno));
251 return FALSE;
254 return TRUE;
257 /* Bind GART memory with "key" at "offset" */
258 _X_EXPORT Bool
259 xf86BindGARTMemory(int screenNum, int key, unsigned long offset)
261 agp_bind_t bind;
262 int pageOffset;
264 if (!GARTInit(screenNum) || (acquiredScreen != screenNum))
265 return FALSE;
267 if (offset % AGP_PAGE_SIZE != 0) {
268 xf86DrvMsg(screenNum, X_WARNING, "xf86BindGARTMemory: "
269 "offset (0x%lx) is not page-aligned (%d)\n",
270 offset, AGP_PAGE_SIZE);
271 return FALSE;
273 pageOffset = offset / AGP_PAGE_SIZE;
275 xf86DrvMsgVerb(screenNum, X_INFO, 3,
276 "xf86BindGARTMemory: bind key %d at 0x%08lx "
277 "(pgoffset %d)\n", key, offset, pageOffset);
279 bind.agpb_pgstart = pageOffset;
280 bind.agpb_key = key;
282 if (ioctl(gartFd, AGPIOC_BIND, &bind) != 0) {
283 xf86DrvMsg(screenNum, X_WARNING, "xf86BindGARTMemory: "
284 "binding of gart memory with key %d\n"
285 "\tat offset 0x%lx failed (%s)\n",
286 key, offset, strerror(errno));
287 return FALSE;
290 return TRUE;
293 /* Unbind GART memory with "key" */
294 _X_EXPORT Bool
295 xf86UnbindGARTMemory(int screenNum, int key)
297 agp_unbind_t unbind;
299 if (!GARTInit(screenNum) || (acquiredScreen != screenNum))
300 return FALSE;
302 unbind.agpu_pri = 0;
303 unbind.agpu_key = key;
305 if (ioctl(gartFd, AGPIOC_UNBIND, &unbind) != 0) {
306 xf86DrvMsg(screenNum, X_WARNING, "xf86UnbindGARTMemory: "
307 "unbinding of gart memory with key %d "
308 "failed (%s)\n", key, strerror(errno));
309 return FALSE;
312 xf86DrvMsgVerb(screenNum, X_INFO, 3,
313 "xf86UnbindGARTMemory: unbind key %d\n", key);
315 return TRUE;
319 /* XXX Interface may change. */
320 _X_EXPORT Bool
321 xf86EnableAGP(int screenNum, CARD32 mode)
323 agp_setup_t setup;
325 if (!GARTInit(screenNum) || (acquiredScreen != screenNum))
326 return FALSE;
328 setup.agps_mode = mode;
329 if (ioctl(gartFd, AGPIOC_SETUP, &setup) != 0) {
330 xf86DrvMsg(screenNum, X_WARNING, "xf86EnableAGP: "
331 "AGPIOC_SETUP with mode %x failed (%s)\n",
332 mode, strerror(errno));
333 return FALSE;
336 return TRUE;