diff options
-rw-r--r-- | configure.ac | 6 | ||||
-rw-r--r-- | src/Makefile.am | 13 | ||||
-rw-r--r-- | src/nv_driver.c | 2 | ||||
-rw-r--r-- | src/nv_wrap_drv.c | 169 |
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; +} + |