1dfe64dd3Smacallan/* modified from tdfx_dri.c, mga_dri.c */
2dfe64dd3Smacallan
3dfe64dd3Smacallan/*
4dfe64dd3Smacallan * DRI wrapper for 300 and 315 series
5dfe64dd3Smacallan *
6dfe64dd3Smacallan * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
7dfe64dd3Smacallan *
8dfe64dd3Smacallan * Preliminary 315/330 support by Thomas Winischhofer
9dfe64dd3Smacallan * Portions of Mesa 4/5 changes by Eric Anholt
10dfe64dd3Smacallan *
11dfe64dd3Smacallan * Licensed under the following terms:
12dfe64dd3Smacallan *
13dfe64dd3Smacallan * Permission to use, copy, modify, distribute, and sell this software and its
14dfe64dd3Smacallan * documentation for any purpose is hereby granted without fee, provided that
15dfe64dd3Smacallan * the above copyright notice appears in all copies and that both that copyright
16dfe64dd3Smacallan * notice and this permission notice appear in supporting documentation, and
17dfe64dd3Smacallan * and that the name of the copyright holder not be used in advertising
18dfe64dd3Smacallan * or publicity pertaining to distribution of the software without specific,
19dfe64dd3Smacallan * written prior permission. The copyright holder makes no representations
20dfe64dd3Smacallan * about the suitability of this software for any purpose.  It is provided
21dfe64dd3Smacallan * "as is" without expressed or implied warranty.
22dfe64dd3Smacallan *
23dfe64dd3Smacallan * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
24dfe64dd3Smacallan * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
25dfe64dd3Smacallan * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
26dfe64dd3Smacallan * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
27dfe64dd3Smacallan * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
28dfe64dd3Smacallan * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
29dfe64dd3Smacallan * PERFORMANCE OF THIS SOFTWARE.
30dfe64dd3Smacallan *
31dfe64dd3Smacallan * Previously taken and modified from tdfx_dri.c, mga_dri.c
32dfe64dd3Smacallan *
33dfe64dd3Smacallan * Authors:	Can-Ru Yeou, SiS Inc.
34dfe64dd3Smacallan *		Alan Hourihane, Wigan, England,
35dfe64dd3Smacallan *		Thomas Winischhofer <thomas@winischhofer.net>
36dfe64dd3Smacallan *		others.
37dfe64dd3Smacallan */
38dfe64dd3Smacallan#ifdef HAVE_CONFIG_H
39dfe64dd3Smacallan#include "config.h"
40dfe64dd3Smacallan#endif
41dfe64dd3Smacallan
42dfe64dd3Smacallan/* Jong 09/27/2007; added for PACKAGE_VERSION_MAJOR,... */
43dfe64dd3Smacallan#define  PACKAGE_VERSION_MAJOR   1
44dfe64dd3Smacallan#define  PACKAGE_VERSION_MINOR   1
45dfe64dd3Smacallan#define  PACKAGE_VERSION_PATCHLEVEL   0
46dfe64dd3Smacallan
47dfe64dd3Smacallan#include "xf86.h"
48dfe64dd3Smacallan#include "xf86_OSproc.h"
49dfe64dd3Smacallan#include "xf86Priv.h"
50dfe64dd3Smacallan
51dfe64dd3Smacallan#include "xf86PciInfo.h"
52dfe64dd3Smacallan#include "xf86Pci.h"
53dfe64dd3Smacallan#include "fb.h"
54dfe64dd3Smacallan#define PSZ 8
55dfe64dd3Smacallan/* #include "cfb.h" */
56dfe64dd3Smacallan#undef PSZ
57dfe64dd3Smacallan/* #include "cfb16.h" */
58dfe64dd3Smacallan/* #include "cfb32.h" */
59dfe64dd3Smacallan
60dfe64dd3Smacallan#include "miline.h"
61dfe64dd3Smacallan
62dfe64dd3Smacallan#include "GL/glxtokens.h"
63dfe64dd3Smacallan
64dfe64dd3Smacallan#include "xgi.h"
65dfe64dd3Smacallan#include "xgi_dri.h"
66dfe64dd3Smacallan
67dfe64dd3Smacallan#include "xgi_accel.h"
68dfe64dd3Smacallan#include "xgi_common.h"
69dfe64dd3Smacallan#include "drm.h"
70dfe64dd3Smacallan
71dfe64dd3Smacallanextern void GlxSetVisualConfigs(
72dfe64dd3Smacallan    int nconfigs,
73dfe64dd3Smacallan    __GLXvisualConfig *configs,
74dfe64dd3Smacallan    void **configprivs
75dfe64dd3Smacallan);
76dfe64dd3Smacallan
77dfe64dd3Smacallan#define PCIE_BUS_TYPE	2
78dfe64dd3Smacallan#define AGP_BUS_TYPE	1
79dfe64dd3Smacallan#define PCI_BUS_TYPE	0
80dfe64dd3Smacallan
81dfe64dd3Smacallan#define AGP_PAGE_SIZE 4096     /* Texture memory 8M  */
82dfe64dd3Smacallan/*#define AGP_PAGE_SIZE 5120*/ /* Texture memory 10M */
83dfe64dd3Smacallan#define AGP_PAGES 2048
84dfe64dd3Smacallan#define AGP_SIZE (AGP_PAGE_SIZE * AGP_PAGES)
85dfe64dd3Smacallan#define AGP_VTXBUF_PAGES 512
86dfe64dd3Smacallan#define AGP_VTXBUF_SIZE (AGP_PAGE_SIZE * AGP_VTXBUF_PAGES)
87dfe64dd3Smacallan
88dfe64dd3Smacallan/**
89dfe64dd3Smacallan * Base name of kernel DRM driver.
90dfe64dd3Smacallan *
91dfe64dd3Smacallan * Support for XG40 chips is included in the SiS DRM because the DMA and
92dfe64dd3Smacallan * interrupt handling for the chips is identical.
93dfe64dd3Smacallan */
94dfe64dd3Smacallanstatic const char XGIKernelDriverName[] = "sis";
95dfe64dd3Smacallan
96dfe64dd3Smacallanstatic const char XGIClientDriverName[] = "xgi";
97dfe64dd3Smacallan
98dfe64dd3Smacallanstatic Bool XGIInitVisualConfigs(ScreenPtr pScreen);
99dfe64dd3Smacallanstatic Bool XGICreateContext(ScreenPtr pScreen, VisualPtr visual,
100dfe64dd3Smacallan			      drm_context_t hwContext, void *pVisualConfigPriv,
101dfe64dd3Smacallan			      DRIContextType contextStore);
102dfe64dd3Smacallanstatic void XGIDestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
103dfe64dd3Smacallan			       DRIContextType contextStore);
104dfe64dd3Smacallanstatic void XGIDRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
105dfe64dd3Smacallan			       DRIContextType readContextType,
106dfe64dd3Smacallan			       void *readContextStore,
107dfe64dd3Smacallan			       DRIContextType writeContextType,
108dfe64dd3Smacallan			       void *writeContextStore);
109dfe64dd3Smacallanstatic void XGIDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index);
110dfe64dd3Smacallanstatic void XGIDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
111dfe64dd3Smacallan			       RegionPtr prgnSrc, CARD32 index);
112dfe64dd3Smacallan
113dfe64dd3Smacallanvoid xgiLostContext(ScreenPtr pScreen);
114dfe64dd3Smacallan
115dfe64dd3SmacallanULONG IsXGIAGPCard(ScreenPtr pScreen);
116dfe64dd3SmacallanULONG CheckAGPSlot(ScreenPtr pScreen, ULONG uNextLink);
117dfe64dd3Smacallan
118dfe64dd3Smacallanstatic Bool
119dfe64dd3SmacallanXGIInitVisualConfigs(ScreenPtr pScreen)
120dfe64dd3Smacallan{
121dfe64dd3Smacallan  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
122dfe64dd3Smacallan  XGIPtr pXGI = XGIPTR(pScrn);
123dfe64dd3Smacallan  int numConfigs = 0;
124dfe64dd3Smacallan  __GLXvisualConfig *pConfigs = 0;
125dfe64dd3Smacallan  XGIConfigPrivPtr pXGIConfigs = 0;
126dfe64dd3Smacallan  XGIConfigPrivPtr *pXGIConfigPtrs = 0;
127dfe64dd3Smacallan  int i, db, z_stencil, accum;
128dfe64dd3Smacallan  Bool useZ16 = FALSE;
129dfe64dd3Smacallan
130dfe64dd3Smacallan  if(getenv("XGI_FORCE_Z16")){
131dfe64dd3Smacallan    useZ16 = TRUE;
132dfe64dd3Smacallan  }
133dfe64dd3Smacallan
134dfe64dd3Smacallan  switch (pScrn->bitsPerPixel) {
135dfe64dd3Smacallan  case 8:
136dfe64dd3Smacallan  case 24:
137dfe64dd3Smacallan    break;
138dfe64dd3Smacallan  case 16:
139dfe64dd3Smacallan  case 32:
140dfe64dd3Smacallan    numConfigs = (useZ16)?8:16;
141dfe64dd3Smacallan
142dfe64dd3Smacallan    if (!(pConfigs = (__GLXvisualConfig*)xnfcalloc(sizeof(__GLXvisualConfig),
143dfe64dd3Smacallan						   numConfigs))) {
144dfe64dd3Smacallan      return FALSE;
145dfe64dd3Smacallan    }
146dfe64dd3Smacallan    if (!(pXGIConfigs = (XGIConfigPrivPtr)xnfcalloc(sizeof(XGIConfigPrivRec),
147dfe64dd3Smacallan						    numConfigs))) {
148dfe64dd3Smacallan      xfree(pConfigs);
149dfe64dd3Smacallan      return FALSE;
150dfe64dd3Smacallan    }
151dfe64dd3Smacallan    if (!(pXGIConfigPtrs = (XGIConfigPrivPtr*)xnfcalloc(sizeof(XGIConfigPrivPtr),
152dfe64dd3Smacallan							  numConfigs))) {
153dfe64dd3Smacallan      xfree(pConfigs);
154dfe64dd3Smacallan      xfree(pXGIConfigs);
155dfe64dd3Smacallan      return FALSE;
156dfe64dd3Smacallan    }
157dfe64dd3Smacallan    for (i=0; i<numConfigs; i++)
158dfe64dd3Smacallan      pXGIConfigPtrs[i] = &pXGIConfigs[i];
159dfe64dd3Smacallan
160dfe64dd3Smacallan    i = 0;
161dfe64dd3Smacallan    for (accum = 0; accum <= 1; accum++) {
162dfe64dd3Smacallan      for (z_stencil=0; z_stencil<(useZ16?2:4); z_stencil++) {
163dfe64dd3Smacallan        for (db = 0; db <= 1; db++) {
164dfe64dd3Smacallan          pConfigs[i].vid = -1;
165dfe64dd3Smacallan          pConfigs[i].class = -1;
166dfe64dd3Smacallan          pConfigs[i].rgba = TRUE;
167dfe64dd3Smacallan          pConfigs[i].redSize = -1;
168dfe64dd3Smacallan          pConfigs[i].greenSize = -1;
169dfe64dd3Smacallan          pConfigs[i].blueSize = -1;
170dfe64dd3Smacallan          pConfigs[i].redMask = -1;
171dfe64dd3Smacallan          pConfigs[i].greenMask = -1;
172dfe64dd3Smacallan          pConfigs[i].blueMask = -1;
173dfe64dd3Smacallan          pConfigs[i].alphaMask = 0;
174dfe64dd3Smacallan          if (accum) {
175dfe64dd3Smacallan            pConfigs[i].accumRedSize = 16;
176dfe64dd3Smacallan            pConfigs[i].accumGreenSize = 16;
177dfe64dd3Smacallan            pConfigs[i].accumBlueSize = 16;
178dfe64dd3Smacallan            pConfigs[i].accumAlphaSize = 16;
179dfe64dd3Smacallan          } else {
180dfe64dd3Smacallan            pConfigs[i].accumRedSize = 0;
181dfe64dd3Smacallan            pConfigs[i].accumGreenSize = 0;
182dfe64dd3Smacallan            pConfigs[i].accumBlueSize = 0;
183dfe64dd3Smacallan            pConfigs[i].accumAlphaSize = 0;
184dfe64dd3Smacallan          }
185dfe64dd3Smacallan          if (db)
186dfe64dd3Smacallan            pConfigs[i].doubleBuffer = TRUE;
187dfe64dd3Smacallan          else
188dfe64dd3Smacallan            pConfigs[i].doubleBuffer = FALSE;
189dfe64dd3Smacallan          pConfigs[i].stereo = FALSE;
190dfe64dd3Smacallan          pConfigs[i].bufferSize = -1;
191dfe64dd3Smacallan          switch (z_stencil){
192dfe64dd3Smacallan            case 0:
193dfe64dd3Smacallan              pConfigs[i].depthSize = 0;
194dfe64dd3Smacallan              pConfigs[i].stencilSize = 0;
195dfe64dd3Smacallan              break;
196dfe64dd3Smacallan            case 1:
197dfe64dd3Smacallan              pConfigs[i].depthSize = 16;
198dfe64dd3Smacallan              pConfigs[i].stencilSize = 0;
199dfe64dd3Smacallan              break;
200dfe64dd3Smacallan            case 2:
201dfe64dd3Smacallan              pConfigs[i].depthSize = 32;
202dfe64dd3Smacallan              pConfigs[i].stencilSize = 0;
203dfe64dd3Smacallan              break;
204dfe64dd3Smacallan            case 3:
205dfe64dd3Smacallan              pConfigs[i].depthSize = 24;
206dfe64dd3Smacallan              pConfigs[i].stencilSize = 8;
207dfe64dd3Smacallan              break;
208dfe64dd3Smacallan          }
209dfe64dd3Smacallan          pConfigs[i].auxBuffers = 0;
210dfe64dd3Smacallan          pConfigs[i].level = 0;
211dfe64dd3Smacallan          pConfigs[i].visualRating = GLX_NONE_EXT;
212dfe64dd3Smacallan          pConfigs[i].transparentPixel = 0;
213dfe64dd3Smacallan          pConfigs[i].transparentRed = 0;
214dfe64dd3Smacallan          pConfigs[i].transparentGreen = 0;
215dfe64dd3Smacallan          pConfigs[i].transparentBlue = 0;
216dfe64dd3Smacallan          pConfigs[i].transparentAlpha = 0;
217dfe64dd3Smacallan          pConfigs[i].transparentIndex = 0;
218dfe64dd3Smacallan          i++;
219dfe64dd3Smacallan        }
220dfe64dd3Smacallan      }
221dfe64dd3Smacallan    }
222dfe64dd3Smacallan    if (i != numConfigs) {
223dfe64dd3Smacallan      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
224dfe64dd3Smacallan                 "[drm] Incorrect initialization of visuals\n");
225dfe64dd3Smacallan      return FALSE;
226dfe64dd3Smacallan    }
227dfe64dd3Smacallan    break;
228dfe64dd3Smacallan  }
229dfe64dd3Smacallan
230dfe64dd3Smacallan  pXGI->numVisualConfigs = numConfigs;
231dfe64dd3Smacallan  pXGI->pVisualConfigs = pConfigs;
232dfe64dd3Smacallan  pXGI->pVisualConfigsPriv = pXGIConfigs;
233dfe64dd3Smacallan  GlxSetVisualConfigs(numConfigs, pConfigs, (void**)pXGIConfigPtrs);
234dfe64dd3Smacallan
235dfe64dd3Smacallan  return TRUE;
236dfe64dd3Smacallan}
237dfe64dd3Smacallan
238dfe64dd3SmacallanBool XGIDRIScreenInit(ScreenPtr pScreen)
239dfe64dd3Smacallan{
240dfe64dd3Smacallan#ifndef linux
241dfe64dd3Smacallan  return FALSE;
242dfe64dd3Smacallan#else /* linux */
243dfe64dd3Smacallan
244dfe64dd3Smacallan  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
245dfe64dd3Smacallan  XGIPtr pXGI = XGIPTR(pScrn);
246dfe64dd3Smacallan  DRIInfoPtr pDRIInfo;
247dfe64dd3Smacallan  XGIDRIPtr pXGIDRI;
248dfe64dd3Smacallan    drm_xgi_fb_t  fb;
249dfe64dd3Smacallan    int major, minor, patch;
250dfe64dd3Smacallan    drmVersionPtr drm_ver;
251dfe64dd3Smacallan
252dfe64dd3Smacallan
253dfe64dd3Smacallan   /* Check that the GLX, DRI, and DRM modules have been loaded by testing
254dfe64dd3Smacallan    * for canonical symbols in each module. */
255dfe64dd3Smacallan   if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) return FALSE;
256dfe64dd3Smacallan   if (!xf86LoaderCheckSymbol("DRIScreenInit"))       return FALSE;
257dfe64dd3Smacallan   if (!xf86LoaderCheckSymbol("drmAvailable"))        return FALSE;
258dfe64dd3Smacallan   if (!xf86LoaderCheckSymbol("DRIQueryVersion")) {
259dfe64dd3Smacallan      xf86DrvMsg(pScreen->myNum, X_ERROR,
260dfe64dd3Smacallan                 "XGIDRIScreenInit failed (libdri.a too old)\n");
261dfe64dd3Smacallan      return FALSE;
262dfe64dd3Smacallan   }
263dfe64dd3Smacallan
264dfe64dd3Smacallan    /* Make sure the server's DRI extension version matches the version the
265dfe64dd3Smacallan     * driver was built against.
266dfe64dd3Smacallan     */
267dfe64dd3Smacallan    DRIQueryVersion(&major, &minor, &patch);
268dfe64dd3Smacallan    if ((major != DRIINFO_MAJOR_VERSION) || (minor < DRIINFO_MINOR_VERSION)) {
269dfe64dd3Smacallan        xf86DrvMsg(pScreen->myNum, X_ERROR,
270dfe64dd3Smacallan                   "[drm] XGIDRIScreenInit failed (DRI version = %d.%d.%d, "
271dfe64dd3Smacallan                   "expected %d.%d.x). Disabling DRI.\n",
272dfe64dd3Smacallan                   major, minor, patch,
273dfe64dd3Smacallan                   DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION);
274dfe64dd3Smacallan        return FALSE;
275dfe64dd3Smacallan    }
276dfe64dd3Smacallan
277dfe64dd3Smacallan    pDRIInfo = DRICreateInfoRec();
278dfe64dd3Smacallan    if (!pDRIInfo) {
279dfe64dd3Smacallan        return FALSE;
280dfe64dd3Smacallan    }
281dfe64dd3Smacallan
282dfe64dd3Smacallan    pXGI->pDRIInfo = pDRIInfo;
283dfe64dd3Smacallan    pDRIInfo->drmDriverName = XGIKernelDriverName;
284dfe64dd3Smacallan    pDRIInfo->clientDriverName = XGIClientDriverName;
285dfe64dd3Smacallan    pDRIInfo->busIdString = DRICreatePCIBusID(pXGI->PciInfo);
286dfe64dd3Smacallan    pDRIInfo->ddxDriverMajorVersion = PACKAGE_VERSION_MAJOR;
287dfe64dd3Smacallan    pDRIInfo->ddxDriverMinorVersion = PACKAGE_VERSION_MINOR;
288dfe64dd3Smacallan    pDRIInfo->ddxDriverPatchVersion = PACKAGE_VERSION_PATCHLEVEL;
289dfe64dd3Smacallan    pDRIInfo->frameBufferPhysicalAddress = pXGI->FbAddress;
290dfe64dd3Smacallan    pDRIInfo->frameBufferSize = pXGI->FbMapSize;
291dfe64dd3Smacallan
292dfe64dd3Smacallan  /* ?? */
293dfe64dd3Smacallan  pDRIInfo->frameBufferStride = pXGI->scrnOffset;
294dfe64dd3Smacallan  pDRIInfo->ddxDrawableTableEntry = XGI_MAX_DRAWABLES;
295dfe64dd3Smacallan
296dfe64dd3Smacallan  if (SAREA_MAX_DRAWABLES < XGI_MAX_DRAWABLES)
297dfe64dd3Smacallan    pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES;
298dfe64dd3Smacallan  else
299dfe64dd3Smacallan    pDRIInfo->maxDrawableTableEntry = XGI_MAX_DRAWABLES;
300dfe64dd3Smacallan
301dfe64dd3Smacallan#ifdef NOT_DONE
302dfe64dd3Smacallan  /* FIXME need to extend DRI protocol to pass this size back to client
303dfe64dd3Smacallan   * for SAREA mapping that includes a device private record
304dfe64dd3Smacallan   */
305dfe64dd3Smacallan  pDRIInfo->SAREASize =
306dfe64dd3Smacallan    ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); /* round to page */
307dfe64dd3Smacallan  /* + shared memory device private rec */
308dfe64dd3Smacallan#else
309dfe64dd3Smacallan  /* For now the mapping works by using a fixed size defined
310dfe64dd3Smacallan   * in the SAREA header
311dfe64dd3Smacallan   */
312dfe64dd3Smacallan  if (sizeof(XF86DRISAREARec)+sizeof(XGISAREAPriv)>SAREA_MAX) {
313dfe64dd3Smacallan/* ErrorF("Data does not fit in SAREA\n"); */
314dfe64dd3Smacallan    return FALSE;
315dfe64dd3Smacallan  }
316dfe64dd3Smacallan  pDRIInfo->SAREASize = SAREA_MAX;
317dfe64dd3Smacallan#endif
318dfe64dd3Smacallan
319dfe64dd3Smacallan  if (!(pXGIDRI = (XGIDRIPtr)xnfcalloc(sizeof(XGIDRIRec),1))) {
320dfe64dd3Smacallan    DRIDestroyInfoRec(pXGI->pDRIInfo);
321dfe64dd3Smacallan    pXGI->pDRIInfo=0;
322dfe64dd3Smacallan    return FALSE;
323dfe64dd3Smacallan  }
324dfe64dd3Smacallan  pDRIInfo->devPrivate = pXGIDRI;
325dfe64dd3Smacallan  pDRIInfo->devPrivateSize = sizeof(XGIDRIRec);
326dfe64dd3Smacallan  pDRIInfo->contextSize = sizeof(XGIDRIContextRec);
327dfe64dd3Smacallan
328dfe64dd3Smacallan  pDRIInfo->CreateContext = XGICreateContext;
329dfe64dd3Smacallan  pDRIInfo->DestroyContext = XGIDestroyContext;
330dfe64dd3Smacallan  pDRIInfo->SwapContext = XGIDRISwapContext;
331dfe64dd3Smacallan  pDRIInfo->InitBuffers = XGIDRIInitBuffers;
332dfe64dd3Smacallan  pDRIInfo->MoveBuffers = XGIDRIMoveBuffers;
333dfe64dd3Smacallan  pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
334dfe64dd3Smacallan
335dfe64dd3Smacallan  if (!DRIScreenInit(pScreen, pDRIInfo, &pXGI->drmSubFD)) {
336dfe64dd3Smacallan    xfree(pDRIInfo->devPrivate);
337dfe64dd3Smacallan    pDRIInfo->devPrivate=0;
338dfe64dd3Smacallan    DRIDestroyInfoRec(pXGI->pDRIInfo);
339dfe64dd3Smacallan    pXGI->pDRIInfo=0;
340dfe64dd3Smacallan    pXGI->drmSubFD = -1;
341dfe64dd3Smacallan    return FALSE;
342dfe64dd3Smacallan  }
343dfe64dd3Smacallan
344dfe64dd3Smacallan    drm_ver = drmGetVersion(pXGI->drmSubFD);
345dfe64dd3Smacallan    if (drm_ver != NULL) {
346dfe64dd3Smacallan        major = drm_ver->version_major;
347dfe64dd3Smacallan        minor = drm_ver->version_minor;
348dfe64dd3Smacallan        patch = drm_ver->version_patchlevel;
349dfe64dd3Smacallan
350dfe64dd3Smacallan        drmFreeVersion(drm_ver);
351dfe64dd3Smacallan        drm_ver = NULL;
352dfe64dd3Smacallan    }
353dfe64dd3Smacallan    else {
354dfe64dd3Smacallan        major = 0;
355dfe64dd3Smacallan        minor = 0;
356dfe64dd3Smacallan        patch = 0;
357dfe64dd3Smacallan    }
358dfe64dd3Smacallan
359dfe64dd3Smacallan    if ((major != 1) || (minor < 3)) {
360dfe64dd3Smacallan        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
361dfe64dd3Smacallan                   "[drm] Incorrect kernel module version.  Expected 1.3.x, got %d.%d.%d\n",
362dfe64dd3Smacallan                   major, minor, patch);
363dfe64dd3Smacallan
364dfe64dd3Smacallan        XGIDRICloseScreen(pScreen);
365dfe64dd3Smacallan        return FALSE;
366dfe64dd3Smacallan    }
367dfe64dd3Smacallan    else {
368dfe64dd3Smacallan        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
369dfe64dd3Smacallan                   "[drm] Kernel module version is %d.%d.%d\n",
370dfe64dd3Smacallan                   major, minor, patch);
371dfe64dd3Smacallan    }
372dfe64dd3Smacallan
373dfe64dd3Smacallan  pXGIDRI->regs.size = XGIIOMAPSIZE;
374dfe64dd3Smacallan  pXGIDRI->regs.map = 0;
375dfe64dd3Smacallan  if (drmAddMap(pXGI->drmSubFD, (drm_handle_t)pXGI->IOAddress,
376dfe64dd3Smacallan		pXGIDRI->regs.size, DRM_REGISTERS, 0,
377dfe64dd3Smacallan		&pXGIDRI->regs.handle)<0)
378dfe64dd3Smacallan  {
379dfe64dd3Smacallan    XGIDRICloseScreen(pScreen);
380dfe64dd3Smacallan    return FALSE;
381dfe64dd3Smacallan  }
382dfe64dd3Smacallan
383dfe64dd3Smacallan  xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Registers = 0x%08lx\n",
384dfe64dd3Smacallan	     (unsigned long) pXGIDRI->regs.handle);
385dfe64dd3Smacallan
386dfe64dd3Smacallan    /* Initialize the framebuffer memory manager.
387dfe64dd3Smacallan     */
388dfe64dd3Smacallan    fb.offset = pXGI->DRIheapstart;
389dfe64dd3Smacallan    fb.size = pXGI->DRIheapend - pXGI->DRIheapstart;
390dfe64dd3Smacallan    drmCommandWrite(pXGI->drmSubFD, DRM_XGI_FB_INIT, &fb, sizeof(fb));
391dfe64dd3Smacallan    xf86DrvMsg(pScreen->myNum, X_INFO,
392dfe64dd3Smacallan               "[dri] Video RAM memory heap: 0x%0x to 0x%0x (%dKB)\n",
393dfe64dd3Smacallan               pXGI->DRIheapstart, pXGI->DRIheapend,
394dfe64dd3Smacallan               (int)((pXGI->DRIheapend - pXGI->DRIheapstart) >> 10));
395dfe64dd3Smacallan
396dfe64dd3Smacallan
397dfe64dd3Smacallan  /* AGP */
398dfe64dd3Smacallan  do{
399dfe64dd3Smacallan    pXGI->agpSize = 0;
400dfe64dd3Smacallan    pXGI->agpVtxBufSize = 0;
401dfe64dd3Smacallan    pXGIDRI->AGPVtxBufSize = 0;
402dfe64dd3Smacallan
403dfe64dd3Smacallan    /* jill note: IF not AGP, diable AGP memory allocate */
404dfe64dd3Smacallan    if (AGP_BUS_TYPE != IsXGIAGPCard(pScreen))
405dfe64dd3Smacallan	    break;
406dfe64dd3Smacallan
407dfe64dd3Smacallan    if (drmAgpAcquire(pXGI->drmSubFD) < 0) {
408dfe64dd3Smacallan      xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpAcquire failed\n");
409dfe64dd3Smacallan      break;
410dfe64dd3Smacallan    }
411dfe64dd3Smacallan
412dfe64dd3Smacallan    pXGI->agpSize = drmAgpSize(pXGI->drmSubFD);
413dfe64dd3Smacallan    if(pXGI->agpSize==0)
414dfe64dd3Smacallan    {
415dfe64dd3Smacallan      xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpSize =0\n");
416dfe64dd3Smacallan      break;
417dfe64dd3Smacallan    }
418dfe64dd3Smacallan
419dfe64dd3Smacallan    /* TODO: default value is 2x? */
420dfe64dd3Smacallan/* if (drmAgpEnable(pXGI->drmSubFD, drmAgpGetMode(pXGI->drmSubFD)&~0x0) < 0) {
421dfe64dd3Smacallan*/
422dfe64dd3Smacallan    /* Default to 1X agp mode */
423dfe64dd3Smacallan    if (drmAgpEnable(pXGI->drmSubFD, drmAgpGetMode(pXGI->drmSubFD)&~0x00000002) < 0) {
424dfe64dd3Smacallan      xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpEnable failed\n");
425dfe64dd3Smacallan      break;
426dfe64dd3Smacallan    }
427dfe64dd3Smacallan/* ErrorF("[drm] drmAgpEnabled succeeded\n"); */
428dfe64dd3Smacallan
429dfe64dd3Smacallan    if (drmAgpAlloc(pXGI->drmSubFD, pXGI->agpSize, 0, NULL, &pXGI->agpHandle) < 0) {
430dfe64dd3Smacallan      xf86DrvMsg(pScreen->myNum, X_ERROR,
431dfe64dd3Smacallan                 "[drm] drmAgpAlloc failed\n");
432dfe64dd3Smacallan      pXGI->agpSize = 0;
433dfe64dd3Smacallan      drmAgpRelease(pXGI->drmSubFD);
434dfe64dd3Smacallan      break;
435dfe64dd3Smacallan    }
436dfe64dd3Smacallan
437dfe64dd3Smacallan    /* Bind agp-gart table                       */
438dfe64dd3Smacallan    /* fill the phys addr. into gart table       */
439dfe64dd3Smacallan    /*********************************************/
440dfe64dd3Smacallan    if (drmAgpBind(pXGI->drmSubFD, pXGI->agpHandle, 0) < 0) {
441dfe64dd3Smacallan      xf86DrvMsg(pScreen->myNum, X_ERROR,
442dfe64dd3Smacallan                 "[drm] drmAgpBind failed\n");
443dfe64dd3Smacallan      drmAgpFree(pXGI->drmSubFD, pXGI->agpHandle);
444dfe64dd3Smacallan      drmAgpRelease(pXGI->drmSubFD);
445dfe64dd3Smacallan
446dfe64dd3Smacallan      break;
447dfe64dd3Smacallan    }
448dfe64dd3Smacallan
449dfe64dd3Smacallan/*    pXGI->agpSize = AGP_SIZE; */
450dfe64dd3Smacallan    pXGI->agpAddr = drmAgpBase(pXGI->drmSubFD);
451dfe64dd3Smacallan    /* pXGI->agpBase = */ /* Xserver connot access VtxBuf, bc. not mem-map */
452dfe64dd3Smacallan
453dfe64dd3Smacallan    /* any client can access this VtxBuf AGP area */
454dfe64dd3Smacallan    /* by mem-map pXGIDRI->agp.handle             */
455dfe64dd3Smacallan    /**********************************************/
456dfe64dd3Smacallan    pXGIDRI->agp.size = pXGI->agpSize;
457dfe64dd3Smacallan    if (drmAddMap(pXGI->drmSubFD, (drm_handle_t)0,
458dfe64dd3Smacallan                 pXGIDRI->agp.size, DRM_AGP, 0,
459dfe64dd3Smacallan                 &pXGIDRI->agp.handle) < 0) {
460dfe64dd3Smacallan      xf86DrvMsg(pScreen->myNum, X_ERROR,
461dfe64dd3Smacallan                 "[drm] Failed to map public agp area\n");
462dfe64dd3Smacallan      pXGIDRI->agp.size = 0;
463dfe64dd3Smacallan      break;
464dfe64dd3Smacallan    }
465dfe64dd3Smacallan
466dfe64dd3Smacallan#if 1 /* chiawen : remove this to 3d driver */
467dfe64dd3Smacallan    pXGI->agpVtxBufSize = AGP_VTXBUF_SIZE; /* 2MB */
468dfe64dd3Smacallan    pXGI->agpVtxBufAddr = pXGI->agpAddr;
469dfe64dd3Smacallan    pXGI->agpVtxBufBase = pXGI->agpVtxBufAddr - pXGI->agpAddr +
470dfe64dd3Smacallan                          pXGI->agpBase;
471dfe64dd3Smacallan    pXGI->agpVtxBufFree = 0;
472dfe64dd3Smacallan
473dfe64dd3Smacallan    pXGIDRI->AGPVtxBufOffset = pXGI->agpVtxBufAddr - pXGI->agpAddr;
474dfe64dd3Smacallan    pXGIDRI->AGPVtxBufSize = pXGI->agpVtxBufSize;
475dfe64dd3Smacallan
476dfe64dd3Smacallan    /* this AGP area is used for texture */
477dfe64dd3Smacallan    /*               is managed by drm   */
478dfe64dd3Smacallan    /*************************************/
479dfe64dd3Smacallan    {
480dfe64dd3Smacallan      drm_xgi_agp_t agp;
481dfe64dd3Smacallan
482dfe64dd3Smacallan      agp.offset = 0; /* AGP_VTXBUF_SIZE; */
483dfe64dd3Smacallan      agp.size = pXGI->agpSize; /* AGP_SIZE - AGP_VTXBUF_SIZE; */
484dfe64dd3Smacallan#ifdef DRM_IOCTL_XGI_AGP_INIT
485dfe64dd3Smacallan      ioctl(pXGI->drmSubFD, DRM_IOCTL_XGI_AGP_INIT, &agp);
486dfe64dd3Smacallan#endif
487dfe64dd3Smacallan#endif
488dfe64dd3Smacallan    }
489dfe64dd3Smacallan  }
490dfe64dd3Smacallan  while(0);
491dfe64dd3Smacallan
492dfe64dd3Smacallan  /* enable IRQ */
493dfe64dd3Smacallan  pXGI->irq = drmGetInterruptFromBusID(pXGI->drmSubFD,
494dfe64dd3Smacallan#ifdef XSERVER_LIBPCIACCESS
495dfe64dd3Smacallan				       ((pXGI->PciInfo->domain << 8)
496dfe64dd3Smacallan					| pXGI->PciInfo->bus),
497dfe64dd3Smacallan				       pXGI->PciInfo->dev,
498dfe64dd3Smacallan				       pXGI->PciInfo->func
499dfe64dd3Smacallan#else
500dfe64dd3Smacallan	       ((pciConfigPtr)pXGI->PciInfo->thisCard)->busnum,
501dfe64dd3Smacallan	       ((pciConfigPtr)pXGI->PciInfo->thisCard)->devnum,
502dfe64dd3Smacallan	       ((pciConfigPtr)pXGI->PciInfo->thisCard)->funcnum
503dfe64dd3Smacallan#endif
504dfe64dd3Smacallan				       );
505dfe64dd3Smacallan
506dfe64dd3Smacallan  if((drmCtlInstHandler(pXGI->drmSubFD, pXGI->irq)) != 0)
507dfe64dd3Smacallan    {
508dfe64dd3Smacallan      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
509dfe64dd3Smacallan		 "[drm] failure adding irq %d handler, stereo disabled\n",
510dfe64dd3Smacallan		 pXGI->irq);
511dfe64dd3Smacallan      pXGI->irqEnabled = FALSE;
512dfe64dd3Smacallan    }
513dfe64dd3Smacallan  else
514dfe64dd3Smacallan    {
515dfe64dd3Smacallan      pXGI->irqEnabled = TRUE;
516dfe64dd3Smacallan    }
517dfe64dd3Smacallan
518dfe64dd3Smacallan  pXGIDRI->irqEnabled = pXGI->irqEnabled;
519dfe64dd3Smacallan
520dfe64dd3Smacallan  if (!(XGIInitVisualConfigs(pScreen))) {
521dfe64dd3Smacallan    XGIDRICloseScreen(pScreen);
522dfe64dd3Smacallan    return FALSE;
523dfe64dd3Smacallan  }
524dfe64dd3Smacallan  xf86DrvMsg(pScrn->scrnIndex, X_INFO, "visual configs initialized\n" );
525dfe64dd3Smacallan
526dfe64dd3Smacallan  return TRUE;
527dfe64dd3Smacallan#endif /* linux */
528dfe64dd3Smacallan}
529dfe64dd3Smacallan
530dfe64dd3Smacallanvoid
531dfe64dd3SmacallanXGIDRICloseScreen(ScreenPtr pScreen)
532dfe64dd3Smacallan{
533dfe64dd3Smacallan  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
534dfe64dd3Smacallan  XGIPtr pXGI = XGIPTR(pScrn);
535dfe64dd3Smacallan
536dfe64dd3Smacallan  DRICloseScreen(pScreen);
537dfe64dd3Smacallan
538dfe64dd3Smacallan  if (pXGI->pDRIInfo) {
539dfe64dd3Smacallan    if (pXGI->pDRIInfo->devPrivate) {
540dfe64dd3Smacallan      xfree(pXGI->pDRIInfo->devPrivate);
541dfe64dd3Smacallan      pXGI->pDRIInfo->devPrivate=0;
542dfe64dd3Smacallan    }
543dfe64dd3Smacallan    DRIDestroyInfoRec(pXGI->pDRIInfo);
544dfe64dd3Smacallan    pXGI->pDRIInfo=0;
545dfe64dd3Smacallan  }
546dfe64dd3Smacallan  if (pXGI->pVisualConfigs) xfree(pXGI->pVisualConfigs);
547dfe64dd3Smacallan  if (pXGI->pVisualConfigsPriv) xfree(pXGI->pVisualConfigsPriv);
548dfe64dd3Smacallan
549dfe64dd3Smacallan  if(pXGI->agpSize){
550dfe64dd3Smacallan/* ErrorF("Freeing agp memory\n"); */
551dfe64dd3Smacallan     drmAgpFree(pXGI->drmSubFD, pXGI->agpHandle);
552dfe64dd3Smacallan/* ErrorF("releasing agp module\n"); */
553dfe64dd3Smacallan     drmAgpRelease(pXGI->drmSubFD);
554dfe64dd3Smacallan  }
555dfe64dd3Smacallan}
556dfe64dd3Smacallan
557dfe64dd3Smacallan/* TODO: xserver receives driver's swapping event and do something
558dfe64dd3Smacallan *       according the data initialized in this function
559dfe64dd3Smacallan */
560dfe64dd3Smacallanstatic Bool
561dfe64dd3SmacallanXGICreateContext(ScreenPtr pScreen, VisualPtr visual,
562dfe64dd3Smacallan		  drm_context_t hwContext, void *pVisualConfigPriv,
563dfe64dd3Smacallan		  DRIContextType contextStore)
564dfe64dd3Smacallan{
565dfe64dd3Smacallan  return TRUE;
566dfe64dd3Smacallan}
567dfe64dd3Smacallan
568dfe64dd3Smacallanstatic void
569dfe64dd3SmacallanXGIDestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
570dfe64dd3Smacallan		   DRIContextType contextStore)
571dfe64dd3Smacallan{
572dfe64dd3Smacallan}
573dfe64dd3Smacallan
574dfe64dd3SmacallanBool
575dfe64dd3SmacallanXGIDRIFinishScreenInit(ScreenPtr pScreen)
576dfe64dd3Smacallan{
577dfe64dd3Smacallan  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
578dfe64dd3Smacallan  XGIPtr pXGI = XGIPTR(pScrn);
579dfe64dd3Smacallan/*  XGIPtr pXGI = XGIPTR(pScrn); */
580dfe64dd3Smacallan  XGIDRIPtr pXGIDRI;
581dfe64dd3Smacallan
582dfe64dd3Smacallan  /*pXGI->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT;*/
583dfe64dd3Smacallan  pXGI->pDRIInfo->driverSwapMethod = DRI_SERVER_SWAP;
584dfe64dd3Smacallan
585dfe64dd3Smacallan  pXGIDRI=(XGIDRIPtr)pXGI->pDRIInfo->devPrivate;
586dfe64dd3Smacallan  pXGIDRI->deviceID=pXGI->Chipset;
587dfe64dd3Smacallan  pXGIDRI->revisionID=pXGI->ChipRev;
588dfe64dd3Smacallan  pXGIDRI->width=pScrn->virtualX;
589dfe64dd3Smacallan  pXGIDRI->height=pScrn->virtualY;
590dfe64dd3Smacallan  pXGIDRI->mem=pScrn->videoRam*1024;
591dfe64dd3Smacallan  pXGIDRI->bytesPerPixel= (pScrn->bitsPerPixel+7) / 8;
592dfe64dd3Smacallan  /* TODO */
593dfe64dd3Smacallan  pXGIDRI->scrnX=pXGIDRI->width;
594dfe64dd3Smacallan  pXGIDRI->scrnY=pXGIDRI->height;
595dfe64dd3Smacallan
596dfe64dd3Smacallan/*
597dfe64dd3Smacallan  pXGIDRI->textureOffset=pXGI->texOffset;
598dfe64dd3Smacallan  pXGIDRI->textureSize=pXGI->texSize;
599dfe64dd3Smacallan  pXGIDRI->fbOffset=pXGI->fbOffset;
600dfe64dd3Smacallan  pXGIDRI->backOffset=pXGI->backOffset;
601dfe64dd3Smacallan  pXGIDRI->depthOffset=pXGI->depthOffset;
602dfe64dd3Smacallan*/
603dfe64dd3Smacallan
604dfe64dd3Smacallan  /* set SAREA value */
605dfe64dd3Smacallan  {
606dfe64dd3Smacallan    XGISAREAPriv *saPriv;
607dfe64dd3Smacallan
608dfe64dd3Smacallan    saPriv=(XGISAREAPriv*)DRIGetSAREAPrivate(pScreen);
609dfe64dd3Smacallan    assert(saPriv);
610dfe64dd3Smacallan
611dfe64dd3Smacallan    saPriv->CtxOwner = -1;
612dfe64dd3Smacallan    saPriv->QueueLength = 0;
613dfe64dd3Smacallan    pXGI->cmdQueueLenPtr = &(saPriv->QueueLength);
614dfe64dd3Smacallan    saPriv->AGPVtxBufNext = 0;
615dfe64dd3Smacallan
616dfe64dd3Smacallan
617dfe64dd3Smacallan    saPriv->shareWPoffset = pXGI->cmdQueue_shareWP_only2D;
618dfe64dd3Smacallan    pXGI->pCQ_shareWritePort = &(saPriv->shareWPoffset);
619dfe64dd3Smacallan
620dfe64dd3Smacallan
621dfe64dd3Smacallan
622dfe64dd3Smacallan    Volari_Idle(pXGI);
623dfe64dd3Smacallan  }
624dfe64dd3Smacallan
625dfe64dd3Smacallan  return DRIFinishScreenInit(pScreen);
626dfe64dd3Smacallan}
627dfe64dd3Smacallan
628dfe64dd3Smacallanstatic void
629dfe64dd3SmacallanXGIDRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
630dfe64dd3Smacallan		   DRIContextType oldContextType, void *oldContext,
631dfe64dd3Smacallan		   DRIContextType newContextType, void *newContext)
632dfe64dd3Smacallan{
633dfe64dd3Smacallan  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
634dfe64dd3Smacallan  XGIPtr pXGI = XGIPTR(pScrn);
635dfe64dd3Smacallan
636dfe64dd3Smacallan  /* mEndPrimitive */
637dfe64dd3Smacallan  /*
638dfe64dd3Smacallan   * TODO: do this only if X-Server get lock. If kernel supports delayed
639dfe64dd3Smacallan   * signal, needless to do this
640dfe64dd3Smacallan   */
641dfe64dd3Smacallan  /*
642dfe64dd3Smacallan  *(pXGI->IOBase + 0X8B50) = 0xff;
643dfe64dd3Smacallan  *(unsigned int *)(pXGI->IOBase + 0x8B60) = -1;
644dfe64dd3Smacallan  */
645dfe64dd3Smacallan
646dfe64dd3Smacallan  Volari_Idle(pXGI);
647dfe64dd3Smacallan}
648dfe64dd3Smacallan
649dfe64dd3Smacallanstatic void
650dfe64dd3SmacallanXGIDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
651dfe64dd3Smacallan{
652dfe64dd3Smacallan  ScreenPtr pScreen = pWin->drawable.pScreen;
653dfe64dd3Smacallan  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
654dfe64dd3Smacallan  XGIPtr pXGI = XGIPTR(pScrn);
655dfe64dd3Smacallan
656dfe64dd3Smacallan  Volari_Idle(pXGI);
657dfe64dd3Smacallan}
658dfe64dd3Smacallan
659dfe64dd3Smacallanstatic void
660dfe64dd3SmacallanXGIDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
661dfe64dd3Smacallan		   RegionPtr prgnSrc, CARD32 index)
662dfe64dd3Smacallan{
663dfe64dd3Smacallan  ScreenPtr pScreen = pParent->drawable.pScreen;
664dfe64dd3Smacallan  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
665dfe64dd3Smacallan  XGIPtr pXGI = XGIPTR(pScrn);
666dfe64dd3Smacallan
667dfe64dd3Smacallan  Volari_Idle(pXGI);
668dfe64dd3Smacallan}
669dfe64dd3Smacallan
670dfe64dd3Smacallan#ifndef XSERVER_LIBPCIACCESS
671dfe64dd3Smacallan/**
672dfe64dd3Smacallan * Use this function to check AGP slot
673dfe64dd3Smacallan */
674dfe64dd3SmacallanULONG CheckAGPSlot(ScreenPtr pScreen, ULONG uNextLink)
675dfe64dd3Smacallan{
676dfe64dd3Smacallan	ULONG uBuffer = 0, uLink = 0, uValue = 0 ;
677dfe64dd3Smacallan	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
678dfe64dd3Smacallan	XGIPtr pXGI = XGIPTR(pScrn);
679dfe64dd3Smacallan
680dfe64dd3Smacallan	uBuffer = pciReadLong(pXGI->PciTag, uNextLink);
681dfe64dd3Smacallan	uLink = (uBuffer & 0xff00) >> 8;
682dfe64dd3Smacallan	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%s]uBuffer=0x%lx uNextLink=0x%lx, uLink=0x%lx\n", __FUNCTION__, uBuffer, uNextLink, uLink);
683dfe64dd3Smacallan
684dfe64dd3Smacallan	if ((uBuffer & 0xff) != 0x02)
685dfe64dd3Smacallan	{
686dfe64dd3Smacallan		if(uLink)
687dfe64dd3Smacallan			uValue = CheckAGPSlot(pScreen, uLink);
688dfe64dd3Smacallan		else
689dfe64dd3Smacallan			uValue = PCI_BUS_TYPE;
690dfe64dd3Smacallan	}
691dfe64dd3Smacallan	else
692dfe64dd3Smacallan		uValue = AGP_BUS_TYPE;
693dfe64dd3Smacallan
694dfe64dd3Smacallan    return uValue;
695dfe64dd3Smacallan}
696dfe64dd3Smacallan#endif
697dfe64dd3Smacallan
698dfe64dd3Smacallan/**
699dfe64dd3Smacallan * Use this function to check if the current card is AGP or PCI.
700dfe64dd3Smacallan */
701dfe64dd3SmacallanULONG IsXGIAGPCard(ScreenPtr pScreen)
702dfe64dd3Smacallan{
703dfe64dd3Smacallan    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
704dfe64dd3Smacallan    XGIPtr pXGI = XGIPTR(pScrn);
705dfe64dd3Smacallan
706dfe64dd3Smacallan
707dfe64dd3Smacallan#ifdef XSERVER_LIBPCIACCESS
708dfe64dd3Smacallan    const struct pci_agp_info *agp_info =
709dfe64dd3Smacallan	pci_device_get_agp_info(pXGI->PciInfo);
710dfe64dd3Smacallan
711dfe64dd3Smacallan    return (agp_info == NULL) ? PCI_BUS_TYPE : AGP_BUS_TYPE;
712dfe64dd3Smacallan#else
713dfe64dd3Smacallan	ULONG u34h = pciReadLong(pXGI->PciTag,0x34);
714dfe64dd3Smacallan	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%s] u34h=0x%lx\n", __FUNCTION__, u34h);
715dfe64dd3Smacallan
716dfe64dd3Smacallan	/* This value is read only and the default value should be 0x40;
717dfe64dd3Smacallan	* I have no idea why I should do this */
718dfe64dd3Smacallan	ULONG uLink = u34h & 0xff;
719dfe64dd3Smacallan
720dfe64dd3Smacallan	if (0 == uLink)
721dfe64dd3Smacallan	{
722dfe64dd3Smacallan		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%s] No Next ID, This is a PCI card\n", __FUNCTION__);
723dfe64dd3Smacallan		return PCI_BUS_TYPE;
724dfe64dd3Smacallan	}
725dfe64dd3Smacallan
726dfe64dd3Smacallan	ULONG uType = 0;
727dfe64dd3Smacallan	uType = CheckAGPSlot(pScreen, uLink);
728dfe64dd3Smacallan
729dfe64dd3Smacallan	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%s] This Card Type is %ld \n", __FUNCTION__, uType);
730dfe64dd3Smacallan
731dfe64dd3Smacallan	if (uType == PCI_BUS_TYPE)
732dfe64dd3Smacallan		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%s] This Card Type is PCI\n", __FUNCTION__);
733dfe64dd3Smacallan	if (uType == AGP_BUS_TYPE)
734dfe64dd3Smacallan		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%s] This Card Type is AGP\n", __FUNCTION__);
735dfe64dd3Smacallan	if (uType == PCIE_BUS_TYPE)
736dfe64dd3Smacallan		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%s] This Card Type is PCIExpress\n", __FUNCTION__);
737dfe64dd3Smacallan
738dfe64dd3Smacallan	return uType;
739dfe64dd3Smacallan#endif
740dfe64dd3Smacallan}
741