summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac6
-rw-r--r--src/Makefile.am13
-rw-r--r--src/nv_driver.c2
-rw-r--r--src/nv_wrap_drv.c169
4 files changed, 183 insertions, 7 deletions
diff --git a/configure.ac b/configure.ac
index f5df8ad..7ffb3b2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -67,9 +67,9 @@ XORG_DRIVER_CHECK_EXT(XV, videoproto)
XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto)
# Checks for pkg-config packages
-PKG_CHECK_MODULES(LIBDRM_NOUVEAU, libdrm_nouveau)
-AC_SUBST(LIBDRM_NOUVEAU_CFLAGS)
-AC_SUBST(LIBDRM_NOUVEAU_LIBS)
+PKG_CHECK_MODULES(LIBDRM_NOUVEAU16, libdrm_nouveau16)
+AC_SUBST(LIBDRM_NOUVEAU16_CFLAGS)
+AC_SUBST(LIBDRM_NOUVEAU16_LIBS)
PKG_CHECK_MODULES(XORG, [xorg-server >= 1.7] xproto fontsproto libdrm xf86driproto $REQUIRED_MODULES)
PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1],
diff --git a/src/Makefile.am b/src/Makefile.am
index b5f7c86..49bedc0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -23,12 +23,19 @@
# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
# _ladir passes a dummy rpath to libtool so the thing will actually link
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
-AM_CFLAGS = @XORG_CFLAGS@ @LIBDRM_NOUVEAU_CFLAGS@
+
nouveau_drv_la_LTLIBRARIES = nouveau_drv.la
-nouveau_drv_la_LDFLAGS = -module -avoid-version @LIBDRM_NOUVEAU_LIBS@
+nouveau_drv_la_LDFLAGS = -module -avoid-version
nouveau_drv_ladir = @moduledir@/drivers
+nouveau_drv_la_SOURCES = nv_wrap_drv.c
+
+
+AM_CFLAGS = @XORG_CFLAGS@ @LIBDRM_NOUVEAU16_CFLAGS@
+nouveau16_drv_la_LTLIBRARIES = nouveau16_drv.la
+nouveau16_drv_la_LDFLAGS = -module -avoid-version @LIBDRM_NOUVEAU16_LIBS@
+nouveau16_drv_ladir = @moduledir@/drivers
-nouveau_drv_la_SOURCES = \
+nouveau16_drv_la_SOURCES = \
nouveau_local.h \
nouveau_exa.c nouveau_xv.c nouveau_dri2.c \
nouveau_wfb.c \
diff --git a/src/nv_driver.c b/src/nv_driver.c
index 4b00e3d..4ce1cf7 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -128,7 +128,7 @@ static XF86ModuleVersionInfo nouveauVersRec =
{0,0,0,0}
};
-_X_EXPORT XF86ModuleData nouveauModuleData = { &nouveauVersRec, nouveauSetup, NULL };
+_X_EXPORT XF86ModuleData nouveau16ModuleData = { &nouveauVersRec, nouveauSetup, NULL };
static pointer
nouveauSetup(pointer module, pointer opts, int *errmaj, int *errmin)
diff --git a/src/nv_wrap_drv.c b/src/nv_wrap_drv.c
new file mode 100644
index 0000000..c916b99
--- /dev/null
+++ b/src/nv_wrap_drv.c
@@ -0,0 +1,169 @@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include <unistd.h>
+#include <stdint.h>
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+
+#include "xf86.h"
+
+#include "xf86_OSproc.h"
+#include <pciaccess.h>
+#include <xf86drm.h>
+
+#include "nv_const.h"
+
+#define NOUVEAU_DRIVER_NAME "nouveau"
+
+static MODULESETUPPROTO(nouveauSetup);
+static XF86ModuleVersionInfo nouveauVersRec =
+{
+ "nouveau",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XORG_VERSION_CURRENT,
+ NV_MAJOR_VERSION, NV_MINOR_VERSION, NV_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV, /* This is a video driver */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+_X_EXPORT XF86ModuleData nouveauModuleData = { &nouveauVersRec, nouveauSetup, NULL };
+
+/* take from ati wrapper */
+/* domain defines (stolen from xserver) */
+#if (defined(__alpha__) || defined(__ia64__)) && defined (linux)
+# define PCI_DOM_MASK 0x01fful
+#else
+# define PCI_DOM_MASK 0x0ffu
+#endif
+
+#define PCI_DOM_FROM_BUS(bus) (((bus) >> 8) & (PCI_DOM_MASK))
+#define PCI_BUS_NO_DOMAIN(bus) ((bus) & 0xffu)
+
+static struct pci_device*
+nv_device_get_from_busid(int bus, int dev, int func)
+{
+ return pci_device_find_by_slot(PCI_DOM_FROM_BUS(bus),
+ PCI_BUS_NO_DOMAIN(bus),
+ dev,
+ func);
+}
+
+static char *
+nv_DRICreatePCIBusID(const struct pci_device * dev)
+{
+ char *busID;
+
+ busID = xalloc(20);
+ if (busID == NULL)
+ return NULL;
+
+ snprintf(busID, 20, "pci:%04x:%02x:%02x.%d", dev->domain, dev->bus,
+ dev->dev, dev->func);
+
+ return busID;
+}
+
+static struct pci_device *
+nv_device_get_primary(void)
+{
+ struct pci_device *device = NULL;
+ struct pci_device_iterator *device_iter;
+
+ device_iter = pci_slot_match_iterator_create(NULL);
+
+ while ((device = pci_device_next(device_iter)) != NULL) {
+ if (xf86IsPrimaryPci(device))
+ break;
+ }
+
+ pci_iterator_destroy(device_iter);
+
+ return device;
+}
+
+/* get drm patchlevel */
+static int
+nv_drm_patchlevel_probe(struct pci_device *device)
+
+{
+ int fd;
+ drmVersion *version;
+ char *busid;
+ int pl;
+
+ busid = nv_DRICreatePCIBusID(device);
+
+ fd = drmOpen("nouveau", busid);
+ if (fd < 0)
+ return -1;
+
+ version = drmGetVersion(fd);
+ xf86DrvMsg(-1, X_INFO, "[drm] nouveau interface version: %d.%d.%d\n",
+ version->version_major, version->version_minor,
+ version->version_patchlevel);
+ pl = version->version_patchlevel;
+ drmFree(version);
+
+ drmClose(fd);
+ return pl;
+}
+
+void
+nouveau_find_subdriver(pointer options)
+{
+ char driver_name[64];
+ int nNVDev;
+ GDevPtr *NVDevs;
+ int pl;
+ int i;
+ nNVDev = xf86MatchDevice(NOUVEAU_DRIVER_NAME, &NVDevs);
+
+ for (i = 0; i < nNVDev; i++) {
+ GDevPtr nv_gdev = NVDevs[i];
+ struct pci_device *device = NULL;
+
+ if (nv_gdev->busID) {
+ int bus, dev, func;
+
+ if (!xf86ParsePciBusString(nv_gdev->busID, &bus, &dev, &func))
+ continue;
+ device = nv_device_get_from_busid(bus, dev, func);
+ } else {
+ device = nv_device_get_primary();
+ }
+ if (!device)
+ continue;
+
+ pl = nv_drm_patchlevel_probe(device);
+
+ if (pl < 0)
+ continue;
+
+ snprintf(driver_name, 63, "nouveau%d", pl);
+
+ xf86LoadOneModule(driver_name, options);
+ break;
+ }
+}
+
+static pointer
+nouveauSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool Inited = FALSE;
+
+ if (!Inited) {
+ Inited = TRUE;
+ nouveau_find_subdriver(opts);
+ }
+
+ return (pointer)TRUE;
+}
+