Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

nouveau: pull in major libdrm rewrite

Redesigned primarily to allow us to better take advantage of BO's having
fixed GPU virtual addresses on GeForce 8 and up, and to reduce the overhead
of handling relocations on earlier chipsets.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
  • Loading branch information...
commit b7b78a85e237effe6e5b0113e7f58996c40e7e19 1 parent a38df61
Ben Skeggs authored
25 configure.ac
View
@@ -73,16 +73,16 @@ AC_ARG_ENABLE(radeon,
[Enable support for radeon's KMS API (default: auto)]),
[RADEON=$enableval], [RADEON=auto])
+AC_ARG_ENABLE(nouveau,
+ AS_HELP_STRING([--disable-nouveau],
+ [Enable support for nouveau's KMS API (default: auto)]),
+ [NOUVEAU=$enableval], [NOUVEAU=auto])
+
AC_ARG_ENABLE(vmwgfx-experimental-api,
AS_HELP_STRING([--enable-vmwgfx-experimental-api],
[Install vmwgfx's experimental kernel API header (default: disabled)]),
[VMWGFX=$enableval], [VMWGFX=no])
-AC_ARG_ENABLE(nouveau-experimental-api,
- AS_HELP_STRING([--enable-nouveau-experimental-api],
- [Enable support for nouveau's experimental API (default: disabled)]),
- [NOUVEAU=$enableval], [NOUVEAU=no])
-
AC_ARG_ENABLE(omap-experimental-api,
AS_HELP_STRING([--enable-omap-experimental-api],
[Enable support for OMAP's experimental API (default: disabled)]),
@@ -204,7 +204,7 @@ if test "x$HAVE_LIBUDEV" = xyes; then
fi
AM_CONDITIONAL(HAVE_LIBUDEV, [test "x$HAVE_LIBUDEV" = xyes])
-if test "x$INTEL" != "xno" -o "x$RADEON" != "xno"; then
+if test "x$INTEL" != "xno" -o "x$RADEON" != "xno" -o "x$NOUVEAU" != "xno"; then
# Check for atomic intrinsics
AC_CACHE_CHECK([for native atomic primitives], drm_cv_atomic_primitives,
[
@@ -252,7 +252,14 @@ if test "x$INTEL" != "xno" -o "x$RADEON" != "xno"; then
AC_MSG_WARN([Disabling libdrm_radeon. It depends on atomic operations, which were not found for your compiler/cpu. Try compiling with -march=native, or install the libatomics-op-dev package.])
RADEON=no
fi
-
+ if test "x$NOUVEAU" != "xauto"; then
+ if test "x$NOUVEAU" != "xno"; then
+ AC_MSG_ERROR([libdrm_nouveau depends upon atomic operations, which were not found for your compiler/cpu. Try compiling with -march=native, or install the libatomics-op-dev package, or, failing both of those, disable support for NVIDIA GPUs by passing --disable-nouveau to ./configure])
+ fi
+ else
+ AC_MSG_WARN([Disabling libdrm_nouveau. It depends on atomic operations, which were not found for your compiler/cpu. Try compiling with -march=native, or install the libatomics-op-dev package.])
+ NOUVEAU=no
+ fi
else
if test "x$INTEL" != "xno"; then
case $host_cpu in
@@ -263,6 +270,9 @@ if test "x$INTEL" != "xno" -o "x$RADEON" != "xno"; then
if test "x$RADEON" != "xno"; then
RADEON=yes
fi
+ if test "x$NOUVEAU" != "xno"; then
+ NOUVEAU=yes
+ fi
fi
fi
@@ -279,6 +289,7 @@ fi
AM_CONDITIONAL(HAVE_INTEL, [test "x$INTEL" != "xno"])
AM_CONDITIONAL(HAVE_RADEON, [test "x$RADEON" != "xno"])
+AM_CONDITIONAL(HAVE_NOUVEAU, [test "x$NOUVEAU" != "xno"])
if test "x$RADEON" = xyes; then
AC_DEFINE(HAVE_RADEON, 1, [Have radeon support])
fi
36 nouveau/Makefile.am
View
@@ -3,41 +3,23 @@ AM_CFLAGS = \
-I$(top_srcdir) \
-I$(top_srcdir)/nouveau \
$(PTHREADSTUBS_CFLAGS) \
- -I$(top_srcdir)/include/drm
+ -I$(top_srcdir)/include/drm \
+ -DDEBUG
libdrm_nouveau_la_LTLIBRARIES = libdrm_nouveau.la
libdrm_nouveau_ladir = $(libdir)
-libdrm_nouveau_la_LDFLAGS = -version-number 1:0:0 -no-undefined
+libdrm_nouveau_la_LDFLAGS = -version-number 2:0:0 -no-undefined
libdrm_nouveau_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
-libdrm_nouveau_la_SOURCES = \
- nouveau_device.c \
- nouveau_channel.c \
- nouveau_pushbuf.c \
- nouveau_grobj.c \
- nouveau_notifier.c \
- nouveau_bo.c \
- nouveau_resource.c \
- nouveau_private.h \
- nouveau_reloc.c
-
-libdrm_nouveaucommonincludedir = ${includedir}/nouveau
-libdrm_nouveaucommoninclude_HEADERS = \
- nouveau_device.h \
- nouveau_channel.h \
- nouveau_grobj.h \
- nouveau_notifier.h \
- nouveau_pushbuf.h \
- nv04_pushbuf.h \
- nvc0_pushbuf.h \
- nouveau_bo.h \
- nouveau_resource.h \
- nouveau_reloc.h
+libdrm_nouveau_la_SOURCES = nouveau.c \
+ pushbuf.c \
+ bufctx.c \
+ abi16.c \
+ private.h
libdrm_nouveauincludedir = ${includedir}/libdrm
-libdrm_nouveauinclude_HEADERS = \
- nouveau_drmif.h
+libdrm_nouveauinclude_HEADERS = nouveau.h
pkgconfigdir = @pkgconfigdir@
pkgconfig_DATA = libdrm_nouveau.pc
197 nouveau/abi16.c
View
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "private.h"
+
+int
+abi16_chan_nv04(struct nouveau_object *obj)
+{
+ struct nouveau_device *dev = (struct nouveau_device *)obj->parent;
+ struct drm_nouveau_channel_alloc req;
+ struct nv04_fifo *nv04 = obj->data;
+ int ret;
+
+ req.fb_ctxdma_handle = nv04->vram;
+ req.tt_ctxdma_handle = nv04->gart;
+
+ ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
+ &req, sizeof(req));
+ if (ret)
+ return ret;
+
+ nv04->base.channel = req.channel;
+ nv04->base.pushbuf = req.pushbuf_domains;
+ nv04->notify = req.notifier_handle;
+ nv04->base.object->handle = req.channel;
+ nv04->base.object->length = sizeof(*nv04);
+ return 0;
+}
+
+int
+abi16_chan_nvc0(struct nouveau_object *obj)
+{
+ struct nouveau_device *dev = (struct nouveau_device *)obj->parent;
+ struct drm_nouveau_channel_alloc req;
+ struct nvc0_fifo *nvc0 = obj->data;
+ int ret;
+
+ ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
+ &req, sizeof(req));
+ if (ret)
+ return ret;
+
+ nvc0->base.channel = req.channel;
+ nvc0->base.pushbuf = req.pushbuf_domains;
+ nvc0->base.object->handle = req.channel;
+ nvc0->base.object->length = sizeof(*nvc0);
+ return 0;
+}
+
+int
+abi16_engobj(struct nouveau_object *obj)
+{
+ struct drm_nouveau_grobj_alloc req = {
+ obj->parent->handle, obj->handle, obj->oclass
+ };
+ struct nouveau_device *dev;
+ int ret;
+
+ dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
+ ret = drmCommandWrite(dev->fd, DRM_NOUVEAU_GROBJ_ALLOC,
+ &req, sizeof(req));
+ if (ret)
+ return ret;
+
+ obj->length = sizeof(struct nouveau_object *);
+ return 0;
+}
+
+int
+abi16_ntfy(struct nouveau_object *obj)
+{
+ struct nv04_notify *ntfy = obj->data;
+ struct drm_nouveau_notifierobj_alloc req = {
+ obj->parent->handle, ntfy->object->handle, ntfy->length
+ };
+ struct nouveau_device *dev;
+ int ret;
+
+ dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
+ ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_NOTIFIEROBJ_ALLOC,
+ &req, sizeof(req));
+ if (ret)
+ return ret;
+
+ ntfy->offset = req.offset;
+ ntfy->object->length = sizeof(*ntfy);
+ return 0;
+}
+
+void
+abi16_bo_info(struct nouveau_bo *bo, struct drm_nouveau_gem_info *info)
+{
+ struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
+
+ nvbo->map_handle = info->map_handle;
+ bo->handle = info->handle;
+ bo->size = info->size;
+ bo->offset = info->offset;
+
+ bo->flags = 0;
+ if (info->domain & NOUVEAU_GEM_DOMAIN_VRAM)
+ bo->flags |= NOUVEAU_BO_VRAM;
+ if (info->domain & NOUVEAU_GEM_DOMAIN_GART)
+ bo->flags |= NOUVEAU_BO_GART;
+ if (!(info->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG))
+ bo->flags |= NOUVEAU_BO_CONTIG;
+ if (nvbo->map_handle)
+ bo->flags |= NOUVEAU_BO_MAP;
+
+ if (bo->device->chipset >= 0xc0) {
+ bo->config.nvc0.memtype = (info->tile_flags & 0xff00) >> 8;
+ bo->config.nvc0.tile_mode = info->tile_mode;
+ } else
+ if (bo->device->chipset >= 0x80 || bo->device->chipset == 0x50) {
+ bo->config.nv50.memtype = (info->tile_flags & 0x07f00) >> 8 |
+ (info->tile_flags & 0x30000) >> 9;
+ bo->config.nv50.tile_mode = info->tile_mode << 4;
+ } else {
+ bo->config.nv04.surf_flags = info->tile_flags & 7;
+ bo->config.nv04.surf_pitch = info->tile_mode;
+ }
+}
+
+int
+abi16_bo_init(struct nouveau_bo *bo, uint32_t alignment,
+ union nouveau_bo_config *config)
+{
+ struct nouveau_device *dev = bo->device;
+ struct drm_nouveau_gem_new req = {};
+ struct drm_nouveau_gem_info *info = &req.info;
+ int ret;
+
+ if (bo->flags & NOUVEAU_BO_VRAM)
+ info->domain |= NOUVEAU_GEM_DOMAIN_VRAM;
+ if (bo->flags & NOUVEAU_BO_GART)
+ info->domain |= NOUVEAU_GEM_DOMAIN_GART;
+ if (!info->domain)
+ info->domain |= NOUVEAU_GEM_DOMAIN_VRAM |
+ NOUVEAU_GEM_DOMAIN_GART;
+
+ if (bo->flags & NOUVEAU_BO_MAP)
+ info->domain |= NOUVEAU_GEM_DOMAIN_MAPPABLE;
+
+ if (!(bo->flags & NOUVEAU_BO_CONTIG))
+ info->tile_flags = NOUVEAU_GEM_TILE_NONCONTIG;
+
+ info->size = bo->size;
+ req.align = alignment;
+
+ if (config) {
+ if (dev->chipset >= 0xc0) {
+ info->tile_flags = (config->nvc0.memtype & 0xff) << 8;
+ info->tile_mode = config->nvc0.tile_mode;
+ } else
+ if (dev->chipset >= 0x80 || dev->chipset == 0x50) {
+ info->tile_flags = (config->nv50.memtype & 0x07f) << 8 |
+ (config->nv50.memtype & 0x180) << 9;
+ info->tile_mode = config->nv50.tile_mode >> 4;
+ } else {
+ info->tile_flags = config->nv04.surf_flags & 7;
+ info->tile_mode = config->nv04.surf_pitch;
+ }
+ }
+
+ if (!nouveau_device(dev)->have_bo_usage)
+ info->tile_flags &= 0x0000ff00;
+
+ ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_NEW,
+ &req, sizeof(req));
+ if (ret == 0)
+ abi16_bo_info(bo, &req.info);
+ return ret;
+}
170 nouveau/bufctx.c
View
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "libdrm_lists.h"
+
+#include "nouveau.h"
+#include "private.h"
+
+struct nouveau_bufref_priv {
+ struct nouveau_bufref base;
+ struct nouveau_bufref_priv *next;
+ struct nouveau_bufctx *bufctx;
+};
+
+static inline struct nouveau_bufref_priv *
+nouveau_bufref(struct nouveau_bufref *bctx)
+{
+ return (struct nouveau_bufref_priv *)bctx;
+}
+
+struct nouveau_bufbin_priv {
+ struct nouveau_bufref_priv *list;
+ int relocs;
+};
+
+struct nouveau_bufctx_priv {
+ struct nouveau_bufctx base;
+ struct nouveau_bufref_priv *free;
+ int nr_bins;
+ struct nouveau_bufbin_priv bins[];
+};
+
+static inline struct nouveau_bufctx_priv *
+nouveau_bufctx(struct nouveau_bufctx *bctx)
+{
+ return (struct nouveau_bufctx_priv *)bctx;
+}
+
+int
+nouveau_bufctx_new(struct nouveau_client *client, int bins,
+ struct nouveau_bufctx **pbctx)
+{
+ struct nouveau_bufctx_priv *priv;
+
+ priv = calloc(1, sizeof(*priv) + sizeof(priv->bins[0]) * bins);
+ if (priv) {
+ DRMINITLISTHEAD(&priv->base.head);
+ DRMINITLISTHEAD(&priv->base.pending);
+ DRMINITLISTHEAD(&priv->base.current);
+ priv->base.client = client;
+ priv->nr_bins = bins;
+ *pbctx = &priv->base;
+ return 0;
+ }
+
+ return -ENOMEM;
+}
+
+void
+nouveau_bufctx_del(struct nouveau_bufctx **pbctx)
+{
+ struct nouveau_bufctx_priv *pctx = nouveau_bufctx(*pbctx);
+ struct nouveau_bufref_priv *pref;
+ if (pctx) {
+ while (pctx->nr_bins--)
+ nouveau_bufctx_reset(&pctx->base, pctx->nr_bins);
+ while ((pref = pctx->free)) {
+ pctx->free = pref->next;
+ free(pref);
+ }
+ free(pctx);
+ *pbctx = NULL;
+ }
+}
+
+void
+nouveau_bufctx_reset(struct nouveau_bufctx *bctx, int bin)
+{
+ struct nouveau_bufctx_priv *pctx = nouveau_bufctx(bctx);
+ struct nouveau_bufbin_priv *pbin = &pctx->bins[bin];
+ struct nouveau_bufref_priv *pref;
+
+ while ((pref = pbin->list)) {
+ DRMLISTDELINIT(&pref->base.thead);
+ pbin->list = pref->next;
+ pref->next = pctx->free;
+ pctx->free = pref;
+ }
+
+ bctx->relocs -= pbin->relocs;
+ pbin->relocs = 0;
+}
+
+struct nouveau_bufref *
+nouveau_bufctx_refn(struct nouveau_bufctx *bctx, int bin,
+ struct nouveau_bo *bo, uint32_t flags)
+{
+ struct nouveau_bufctx_priv *pctx = nouveau_bufctx(bctx);
+ struct nouveau_bufbin_priv *pbin = &pctx->bins[bin];
+ struct nouveau_bufref_priv *pref = pctx->free;
+
+ if (!pref)
+ pref = malloc(sizeof(*pref));
+ else
+ pctx->free = pref->next;
+
+ if (pref) {
+ pref->base.bo = bo;
+ pref->base.flags = flags;
+ pref->base.packet = 0;
+
+ DRMLISTADDTAIL(&pref->base.thead, &bctx->pending);
+ pref->bufctx = bctx;
+ pref->next = pbin->list;
+ pbin->list = pref;
+ }
+
+ return &pref->base;
+}
+
+struct nouveau_bufref *
+nouveau_bufctx_mthd(struct nouveau_bufctx *bctx, int bin, uint32_t packet,
+ struct nouveau_bo *bo, uint64_t data, uint32_t flags,
+ uint32_t vor, uint32_t tor)
+{
+ struct nouveau_bufctx_priv *pctx = nouveau_bufctx(bctx);
+ struct nouveau_bufbin_priv *pbin = &pctx->bins[bin];
+ struct nouveau_bufref *bref = nouveau_bufctx_refn(bctx, bin, bo, flags);
+ if (bref) {
+ bref->packet = packet;
+ bref->data = data;
+ bref->vor = vor;
+ bref->tor = tor;
+ pbin->relocs++;
+ bctx->relocs++;
+ }
+ return bref;
+}
2  nouveau/libdrm_nouveau.pc.in
View
@@ -5,7 +5,7 @@ includedir=@includedir@
Name: libdrm_nouveau
Description: Userspace interface to nouveau kernel DRM services
-Version: 0.6
+Version: 2.4.33
Libs: -L${libdir} -ldrm_nouveau
Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/nouveau
Requires.private: libdrm
489 nouveau/nouveau.c
View
@@ -0,0 +1,489 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+#include <assert.h>
+#include <errno.h>
+#include <sys/mman.h>
+
+#include <xf86drm.h>
+#include <xf86atomic.h>
+#include "libdrm_lists.h"
+#include "nouveau_drm.h"
+
+#include "nouveau.h"
+#include "private.h"
+
+#ifdef DEBUG
+uint32_t nouveau_debug = 0;
+
+static void
+debug_init(char *args)
+{
+ if (args) {
+ int n = strtol(args, NULL, 0);
+ if (n >= 0)
+ nouveau_debug = n;
+ }
+}
+#endif
+
+/* this is the old libdrm's version of nouveau_device_wrap(), the symbol
+ * is kept here to prevent AIGLX from crashing if the DDX is linked against
+ * the new libdrm, but the DRI driver against the old
+ */
+int
+nouveau_device_open_existing(struct nouveau_device **pdev, int close, int fd,
+ drm_context_t ctx)
+{
+ return -EACCES;
+}
+
+int
+nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev)
+{
+ struct nouveau_device_priv *nvdev = calloc(1, sizeof(*nvdev));
+ struct nouveau_device *dev = &nvdev->base;
+ uint64_t chipset, vram, gart, bousage;
+ drmVersionPtr ver;
+ int ret;
+
+#ifdef DEBUG
+ debug_init(getenv("NOUVEAU_LIBDRM_DEBUG"));
+#endif
+
+ if (!nvdev)
+ return -ENOMEM;
+ nvdev->base.fd = fd;
+
+ ver = drmGetVersion(fd);
+ if (ver) dev->drm_version = (ver->version_major << 24) |
+ (ver->version_minor << 8) |
+ ver->version_patchlevel;
+ drmFreeVersion(ver);
+
+ if ( dev->drm_version != 0x00000010 &&
+ (dev->drm_version < 0x01000000 ||
+ dev->drm_version >= 0x02000000)) {
+ nouveau_device_del(&dev);
+ return -EINVAL;
+ }
+
+ ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_CHIPSET_ID, &chipset);
+ if (ret == 0)
+ ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_FB_SIZE, &vram);
+ if (ret == 0)
+ ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_AGP_SIZE, &gart);
+ if (ret) {
+ nouveau_device_del(&dev);
+ return ret;
+ }
+
+ ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_HAS_BO_USAGE, &bousage);
+ if (ret == 0)
+ nvdev->have_bo_usage = (bousage != 0);
+
+ nvdev->close = close;
+ DRMINITLISTHEAD(&nvdev->bo_list);
+ nvdev->base.object.oclass = NOUVEAU_DEVICE_CLASS;
+ nvdev->base.lib_version = 0x01000000;
+ nvdev->base.chipset = chipset;
+ nvdev->base.vram_size = vram;
+ nvdev->base.gart_size = gart;
+ nvdev->base.vram_limit = (nvdev->base.vram_size * 80) / 100;
+ nvdev->base.gart_limit = (nvdev->base.gart_size * 80) / 100;
+
+ *pdev = &nvdev->base;
+ return 0;
+}
+
+int
+nouveau_device_open(const char *busid, struct nouveau_device **pdev)
+{
+ int ret = -ENODEV, fd = drmOpen("nouveau", busid);
+ if (fd >= 0) {
+ ret = nouveau_device_wrap(fd, 1, pdev);
+ if (ret)
+ drmClose(fd);
+ }
+ return ret;
+}
+
+void
+nouveau_device_del(struct nouveau_device **pdev)
+{
+ struct nouveau_device_priv *nvdev = nouveau_device(*pdev);
+ if (nvdev) {
+ if (nvdev->close)
+ drmClose(nvdev->base.fd);
+ free(nvdev->client);
+ free(nvdev);
+ *pdev = NULL;
+ }
+}
+
+int
+nouveau_getparam(struct nouveau_device *dev, uint64_t param, uint64_t *value)
+{
+ struct drm_nouveau_getparam r = { param, 0 };
+ int fd = dev->fd, ret =
+ drmCommandWriteRead(fd, DRM_NOUVEAU_GETPARAM, &r, sizeof(r));
+ *value = r.value;
+ return ret;
+}
+
+int
+nouveau_setparam(struct nouveau_device *dev, uint64_t param, uint64_t value)
+{
+ struct drm_nouveau_setparam r = { param, value };
+ return drmCommandWrite(dev->fd, DRM_NOUVEAU_SETPARAM, &r, sizeof(r));
+}
+
+int
+nouveau_client_new(struct nouveau_device *dev, struct nouveau_client **pclient)
+{
+ struct nouveau_device_priv *nvdev = nouveau_device(dev);
+ struct nouveau_client_priv *pcli;
+ int id = 0, i, ret = -ENOMEM;
+ uint32_t *clients;
+
+ for (i = 0; i < nvdev->nr_client; i++) {
+ id = ffs(nvdev->client[i]) - 1;
+ if (id >= 0)
+ goto out;
+ }
+
+ clients = realloc(nvdev->client, sizeof(uint32_t) * (i + 1));
+ if (!clients)
+ return ret;
+ nvdev->client = clients;
+ nvdev->client[i] = 0;
+ nvdev->nr_client++;
+
+out:
+ pcli = calloc(1, sizeof(*pcli));
+ if (pcli) {
+ nvdev->client[i] |= (1 << id);
+ pcli->base.device = dev;
+ pcli->base.id = (i * 32) + id;
+ ret = 0;
+ }
+
+ *pclient = &pcli->base;
+ return ret;
+}
+
+void
+nouveau_client_del(struct nouveau_client **pclient)
+{
+ struct nouveau_client_priv *pcli = nouveau_client(*pclient);
+ struct nouveau_device_priv *nvdev;
+ if (pcli) {
+ int id = pcli->base.id;
+ nvdev = nouveau_device(pcli->base.device);
+ nvdev->client[id / 32] &= ~(1 << (id % 32));
+ free(pcli->kref);
+ free(pcli);
+ }
+}
+
+int
+nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
+ uint32_t oclass, void *data, uint32_t length,
+ struct nouveau_object **pobj)
+{
+ struct nouveau_device *dev;
+ struct nouveau_object *obj;
+ int ret = -EINVAL;
+
+ if (length == 0)
+ length = sizeof(struct nouveau_object *);
+ obj = malloc(sizeof(*obj) + length);
+ obj->parent = parent;
+ obj->handle = handle;
+ obj->oclass = oclass;
+ obj->length = length;
+ obj->data = obj + 1;
+ if (data)
+ memcpy(obj->data, data, length);
+ *(struct nouveau_object **)obj->data = obj;
+
+ dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
+ switch (parent->oclass) {
+ case NOUVEAU_DEVICE_CLASS:
+ switch (obj->oclass) {
+ case NOUVEAU_FIFO_CHANNEL_CLASS:
+ {
+ if (dev->chipset < 0xc0)
+ ret = abi16_chan_nv04(obj);
+ else
+ ret = abi16_chan_nvc0(obj);
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case NOUVEAU_FIFO_CHANNEL_CLASS:
+ switch (obj->oclass) {
+ case NOUVEAU_NOTIFIER_CLASS:
+ ret = abi16_ntfy(obj);
+ break;
+ default:
+ ret = abi16_engobj(obj);
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (ret) {
+ free(obj);
+ return ret;
+ }
+
+ *pobj = obj;
+ return 0;
+}
+
+void
+nouveau_object_del(struct nouveau_object **pobj)
+{
+ struct drm_nouveau_gpuobj_free req;
+ struct nouveau_object *obj = *pobj;
+ struct nouveau_device *dev;
+ if (obj) {
+ dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
+ req.channel = obj->parent->handle;
+ req.handle = obj->handle;
+ drmCommandWrite(dev->fd, DRM_NOUVEAU_GPUOBJ_FREE,
+ &req, sizeof(req));
+ }
+ free(obj);
+ *pobj = NULL;
+}
+
+void *
+nouveau_object_find(struct nouveau_object *obj, uint32_t pclass)
+{
+ while (obj && obj->oclass != pclass) {
+ obj = obj->parent;
+ if (pclass == NOUVEAU_PARENT_CLASS)
+ break;
+ }
+ return obj;
+}
+
+static void
+nouveau_bo_del(struct nouveau_bo *bo)
+{
+ struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
+ struct drm_gem_close req = { bo->handle };
+ DRMLISTDEL(&nvbo->head);
+ if (bo->map)
+ munmap(bo->map, bo->size);
+ drmIoctl(bo->device->fd, DRM_IOCTL_GEM_CLOSE, &req);
+ free(nvbo);
+}
+
+int
+nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, uint32_t align,
+ uint64_t size, union nouveau_bo_config *config,
+ struct nouveau_bo **pbo)
+{
+ struct nouveau_device_priv *nvdev = nouveau_device(dev);
+ struct nouveau_bo_priv *nvbo = calloc(1, sizeof(*nvbo));
+ struct nouveau_bo *bo = &nvbo->base;
+ int ret;
+
+ if (!nvbo)
+ return -ENOMEM;
+ atomic_set(&nvbo->refcnt, 1);
+ bo->device = dev;
+ bo->flags = flags;
+ bo->size = size;
+
+ ret = abi16_bo_init(bo, align, config);
+ if (ret) {
+ free(nvbo);
+ return ret;
+ }
+
+ DRMLISTADD(&nvbo->head, &nvdev->bo_list);
+
+ *pbo = bo;
+ return 0;
+}
+
+int
+nouveau_bo_wrap(struct nouveau_device *dev, uint32_t handle,
+ struct nouveau_bo **pbo)
+{
+ struct nouveau_device_priv *nvdev = nouveau_device(dev);
+ struct drm_nouveau_gem_info req = { .handle = handle };
+ struct nouveau_bo_priv *nvbo;
+ int ret;
+
+ DRMLISTFOREACHENTRY(nvbo, &nvdev->bo_list, head) {
+ if (nvbo->base.handle == handle) {
+ *pbo = NULL;
+ nouveau_bo_ref(&nvbo->base, pbo);
+ return 0;
+ }
+ }
+
+ ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_INFO,
+ &req, sizeof(req));
+ if (ret)
+ return ret;
+
+ nvbo = calloc(1, sizeof(*nvbo));
+ if (nvbo) {
+ atomic_set(&nvbo->refcnt, 1);
+ nvbo->base.device = dev;
+ abi16_bo_info(&nvbo->base, &req);
+ DRMLISTADD(&nvbo->head, &nvdev->bo_list);
+ *pbo = &nvbo->base;
+ return 0;
+ }
+
+ return -ENOMEM;
+}
+
+int
+nouveau_bo_name_ref(struct nouveau_device *dev, uint32_t name,
+ struct nouveau_bo **pbo)
+{
+ struct nouveau_device_priv *nvdev = nouveau_device(dev);
+ struct nouveau_bo_priv *nvbo;
+ struct drm_gem_open req = { .name = name };
+ int ret;
+
+ DRMLISTFOREACHENTRY(nvbo, &nvdev->bo_list, head) {
+ if (nvbo->name == name) {
+ *pbo = NULL;
+ nouveau_bo_ref(&nvbo->base, pbo);
+ return 0;
+ }
+ }
+
+ ret = drmIoctl(dev->fd, DRM_IOCTL_GEM_OPEN, &req);
+ if (ret == 0) {
+ ret = nouveau_bo_wrap(dev, req.handle, pbo);
+ nouveau_bo((*pbo))->name = name;
+ }
+
+ return ret;
+}
+
+int
+nouveau_bo_name_get(struct nouveau_bo *bo, uint32_t *name)
+{
+ struct drm_gem_flink req = { .handle = bo->handle };
+ struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
+ if (!nvbo->name) {
+ int ret = drmIoctl(bo->device->fd, DRM_IOCTL_GEM_FLINK, &req);
+ if (ret)
+ return ret;
+ nvbo->name = req.name;
+ }
+ *name = nvbo->name;
+ return 0;
+}
+
+void
+nouveau_bo_ref(struct nouveau_bo *bo, struct nouveau_bo **pref)
+{
+ struct nouveau_bo *ref = *pref;
+ if (bo) {
+ atomic_inc(&nouveau_bo(bo)->refcnt);
+ }
+ if (ref) {
+ if (atomic_dec_and_test(&nouveau_bo(ref)->refcnt))
+ nouveau_bo_del(ref);
+ }
+ *pref = bo;
+}
+
+int
+nouveau_bo_wait(struct nouveau_bo *bo, uint32_t access,
+ struct nouveau_client *client)
+{
+ struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
+ struct drm_nouveau_gem_cpu_prep req;
+ struct nouveau_pushbuf *push;
+ int ret = 0;
+
+ if (!(access & NOUVEAU_BO_RDWR))
+ return 0;
+
+ push = cli_push_get(client, bo);
+ if (push && push->channel)
+ nouveau_pushbuf_kick(push, push->channel);
+
+ if (!nvbo->name && !(nvbo->access & NOUVEAU_BO_WR) &&
+ !( access & NOUVEAU_BO_WR))
+ return 0;
+
+ req.handle = bo->handle;
+ req.flags = 0;
+ if (access & NOUVEAU_BO_WR)
+ req.flags |= NOUVEAU_GEM_CPU_PREP_WRITE;
+ if (access & NOUVEAU_BO_NOBLOCK)
+ req.flags |= NOUVEAU_GEM_CPU_PREP_NOWAIT;
+
+ do {
+ ret = drmCommandWrite(bo->device->fd,
+ DRM_NOUVEAU_GEM_CPU_PREP,
+ &req, sizeof(req));
+ } while (ret == -EAGAIN);
+
+ if (ret == 0)
+ nvbo->access = 0;
+ return ret;
+}
+
+int
+nouveau_bo_map(struct nouveau_bo *bo, uint32_t access,
+ struct nouveau_client *client)
+{
+ struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
+ if (bo->map == NULL) {
+ bo->map = mmap(0, bo->size, PROT_READ | PROT_WRITE,
+ MAP_SHARED, bo->device->fd, nvbo->map_handle);
+ if (bo->map == MAP_FAILED) {
+ bo->map = NULL;
+ return -errno;
+ }
+ }
+ return nouveau_bo_wait(bo, access, client);
+}
211 nouveau/nouveau.h
View
@@ -0,0 +1,211 @@
+#ifndef __NOUVEAU_H__
+#define __NOUVEAU_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#define NOUVEAU_DEVICE_CLASS 0x80000000
+#define NOUVEAU_FIFO_CHANNEL_CLASS 0x80000001
+#define NOUVEAU_NOTIFIER_CLASS 0x80000002
+#define NOUVEAU_PARENT_CLASS 0xffffffff
+
+struct nouveau_list {
+ struct nouveau_list *prev;
+ struct nouveau_list *next;
+};
+
+struct nouveau_object {
+ struct nouveau_object *parent;
+ uint64_t handle;
+ uint32_t oclass;
+ uint32_t length;
+ void *data;
+};
+
+struct nouveau_fifo {
+ struct nouveau_object *object;
+ uint32_t channel;
+ uint32_t pushbuf;
+ uint64_t unused1[3];
+};
+
+struct nv04_fifo {
+ struct nouveau_fifo base;
+ uint32_t vram;
+ uint32_t gart;
+ uint32_t notify;
+};
+
+struct nvc0_fifo {
+ struct nouveau_fifo base;
+};
+
+struct nv04_notify {
+ struct nouveau_object *object;
+ uint32_t offset;
+ uint32_t length;
+};
+
+int nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
+ uint32_t oclass, void *data, uint32_t length,
+ struct nouveau_object **);
+void nouveau_object_del(struct nouveau_object **);
+void *nouveau_object_find(struct nouveau_object *, uint32_t parent_class);
+
+struct nouveau_device {
+ struct nouveau_object object;
+ int fd;
+ uint32_t lib_version;
+ uint32_t drm_version;
+ uint32_t chipset;
+ uint64_t vram_size;
+ uint64_t gart_size;
+ uint64_t vram_limit;
+ uint64_t gart_limit;
+};
+
+int nouveau_device_wrap(int fd, int close, struct nouveau_device **);
+int nouveau_device_open(const char *busid, struct nouveau_device **);
+void nouveau_device_del(struct nouveau_device **);
+int nouveau_getparam(struct nouveau_device *, uint64_t param, uint64_t *value);
+int nouveau_setparam(struct nouveau_device *, uint64_t param, uint64_t value);
+
+struct nouveau_client {
+ struct nouveau_device *device;
+ int id;
+};
+
+int nouveau_client_new(struct nouveau_device *, struct nouveau_client **);
+void nouveau_client_del(struct nouveau_client **);
+
+union nouveau_bo_config {
+ struct {
+#define NV04_BO_16BPP 0x00000001
+#define NV04_BO_32BPP 0x00000002
+#define NV04_BO_ZETA 0x00000004
+ uint32_t surf_flags;
+ uint32_t surf_pitch;
+ } nv04;
+ struct {
+ uint32_t memtype;
+ uint32_t tile_mode;
+ } nv50;
+ struct {
+ uint32_t memtype;
+ uint32_t tile_mode;
+ } nvc0;
+ uint32_t data[8];
+};
+
+#define NOUVEAU_BO_VRAM 0x00000001
+#define NOUVEAU_BO_GART 0x00000002
+#define NOUVEAU_BO_APER (NOUVEAU_BO_VRAM | NOUVEAU_BO_GART)
+#define NOUVEAU_BO_RD 0x00000100
+#define NOUVEAU_BO_WR 0x00000200
+#define NOUVEAU_BO_RDWR (NOUVEAU_BO_RD | NOUVEAU_BO_WR)
+#define NOUVEAU_BO_NOBLOCK 0x00000400
+#define NOUVEAU_BO_LOW 0x00001000
+#define NOUVEAU_BO_HIGH 0x00002000
+#define NOUVEAU_BO_OR 0x00004000
+#define NOUVEAU_BO_MAP 0x80000000
+#define NOUVEAU_BO_CONTIG 0x40000000
+#define NOUVEAU_BO_NOSNOOP 0x20000000
+
+struct nouveau_bo {
+ struct nouveau_device *device;
+ uint32_t handle;
+ uint64_t size;
+ uint32_t flags;
+ uint64_t offset;
+ void *map;
+ union nouveau_bo_config config;
+};
+
+int nouveau_bo_new(struct nouveau_device *, uint32_t flags, uint32_t align,
+ uint64_t size, union nouveau_bo_config *,
+ struct nouveau_bo **);
+int nouveau_bo_wrap(struct nouveau_device *, uint32_t handle,
+ struct nouveau_bo **);
+int nouveau_bo_name_ref(struct nouveau_device *dev, uint32_t name,
+ struct nouveau_bo **);
+int nouveau_bo_name_get(struct nouveau_bo *, uint32_t *name);
+void nouveau_bo_ref(struct nouveau_bo *, struct nouveau_bo **);
+int nouveau_bo_map(struct nouveau_bo *, uint32_t access,
+ struct nouveau_client *);
+int nouveau_bo_wait(struct nouveau_bo *, uint32_t access,
+ struct nouveau_client *);
+
+struct nouveau_bufref {
+ struct nouveau_list thead;
+ struct nouveau_bo *bo;
+ uint32_t packet;
+ uint32_t flags;
+ uint32_t data;
+ uint32_t vor;
+ uint32_t tor;
+ uint32_t priv_data;
+ void *priv;
+};
+
+struct nouveau_bufctx {
+ struct nouveau_client *client;
+ struct nouveau_list head;
+ struct nouveau_list pending;
+ struct nouveau_list current;
+ int relocs;
+};
+
+int nouveau_bufctx_new(struct nouveau_client *, int bins,
+ struct nouveau_bufctx **);
+void nouveau_bufctx_del(struct nouveau_bufctx **);
+struct nouveau_bufref *
+nouveau_bufctx_refn(struct nouveau_bufctx *, int bin,
+ struct nouveau_bo *, uint32_t flags);
+struct nouveau_bufref *
+nouveau_bufctx_mthd(struct nouveau_bufctx *, int bin, uint32_t packet,
+ struct nouveau_bo *, uint64_t data, uint32_t flags,
+ uint32_t vor, uint32_t tor);
+void nouveau_bufctx_reset(struct nouveau_bufctx *, int bin);
+
+struct nouveau_pushbuf_krec;
+struct nouveau_pushbuf {
+ struct nouveau_client *client;
+ struct nouveau_object *channel;
+ struct nouveau_bufctx *bufctx;
+ void (*kick_notify)(struct nouveau_pushbuf *);
+ void *user_priv;
+ uint32_t rsvd_kick;
+ uint32_t flags;
+ uint32_t *cur;
+ uint32_t *end;
+};
+
+struct nouveau_pushbuf_refn {
+ struct nouveau_bo *bo;
+ uint32_t flags;
+};
+
+int nouveau_pushbuf_new(struct nouveau_client *, struct nouveau_object *channel,
+ int nr, uint32_t size, bool immediate,
+ struct nouveau_pushbuf **);
+void nouveau_pushbuf_del(struct nouveau_pushbuf **);
+int nouveau_pushbuf_space(struct nouveau_pushbuf *, uint32_t dwords,
+ uint32_t relocs, uint32_t pushes);
+void nouveau_pushbuf_data(struct nouveau_pushbuf *, struct nouveau_bo *,
+ uint64_t offset, uint64_t length);
+int nouveau_pushbuf_refn(struct nouveau_pushbuf *,
+ struct nouveau_pushbuf_refn *, int nr);
+/* Emits a reloc into the push buffer at the current position, you *must*
+ * have previously added the referenced buffer to a buffer context, and
+ * validated it against the current push buffer.
+ */
+void nouveau_pushbuf_reloc(struct nouveau_pushbuf *, struct nouveau_bo *,
+ uint32_t data, uint32_t flags,
+ uint32_t vor, uint32_t tor);
+int nouveau_pushbuf_validate(struct nouveau_pushbuf *);
+uint32_t nouveau_pushbuf_refd(struct nouveau_pushbuf *, struct nouveau_bo *);
+int nouveau_pushbuf_kick(struct nouveau_pushbuf *, struct nouveau_object *channel);
+struct nouveau_bufctx *
+nouveau_pushbuf_bufctx(struct nouveau_pushbuf *, struct nouveau_bufctx *);
+
+#endif
549 nouveau/nouveau_bo.c
View
@@ -1,549 +0,0 @@
-/*
- * Copyright 2007 Nouveau Project
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdint.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <assert.h>
-
-#include <sys/mman.h>
-
-#include "nouveau_private.h"
-
-int
-nouveau_bo_init(struct nouveau_device *dev)
-{
- return 0;
-}
-
-void
-nouveau_bo_takedown(struct nouveau_device *dev)
-{
-}
-
-static int
-nouveau_bo_info(struct nouveau_bo_priv *nvbo, struct drm_nouveau_gem_info *arg)
-{
- nvbo->handle = nvbo->base.handle = arg->handle;
- nvbo->domain = arg->domain;
- nvbo->size = arg->size;
- nvbo->offset = arg->offset;
- nvbo->map_handle = arg->map_handle;
- nvbo->base.tile_mode = arg->tile_mode;
- /* XXX - flag inverted for backwards compatibility */
- nvbo->base.tile_flags = arg->tile_flags ^ NOUVEAU_GEM_TILE_NONCONTIG;
- return 0;
-}
-
-static int
-nouveau_bo_allocated(struct nouveau_bo_priv *nvbo)
-{
- if (nvbo->sysmem || nvbo->handle)
- return 1;
- return 0;
-}
-
-static int
-nouveau_bo_ualloc(struct nouveau_bo_priv *nvbo)
-{
- if (nvbo->user || nvbo->sysmem) {
- assert(nvbo->sysmem);
- return 0;
- }
-
- nvbo->sysmem = malloc(nvbo->size);
- if (!nvbo->sysmem)
- return -ENOMEM;
-
- return 0;
-}
-
-static void
-nouveau_bo_ufree(struct nouveau_bo_priv *nvbo)
-{
- if (nvbo->sysmem) {
- if (!nvbo->user)
- free(nvbo->sysmem);
- nvbo->sysmem = NULL;
- }
-}
-
-static void
-nouveau_bo_kfree(struct nouveau_bo_priv *nvbo)
-{
- struct nouveau_device_priv *nvdev = nouveau_device(nvbo->base.device);
- struct drm_gem_close req;
-
- if (!nvbo->handle)
- return;
-
- if (nvbo->map) {
- munmap(nvbo->map, nvbo->size);
- nvbo->map = NULL;
- }
-
- req.handle = nvbo->handle;
- nvbo->handle = 0;
- drmIoctl(nvdev->fd, DRM_IOCTL_GEM_CLOSE, &req);
-}
-
-static int
-nouveau_bo_kalloc(struct nouveau_bo_priv *nvbo, struct nouveau_channel *chan)
-{
- struct nouveau_device_priv *nvdev = nouveau_device(nvbo->base.device);
- struct drm_nouveau_gem_new req;
- struct drm_nouveau_gem_info *info = &req.info;
- int ret;
-
- if (nvbo->handle)
- return 0;
-
- req.channel_hint = chan ? chan->id : 0;
- req.align = nvbo->align;
-
-
- info->size = nvbo->size;
- info->domain = 0;
-
- if (nvbo->flags & NOUVEAU_BO_VRAM)
- info->domain |= NOUVEAU_GEM_DOMAIN_VRAM;
- if (nvbo->flags & NOUVEAU_BO_GART)
- info->domain |= NOUVEAU_GEM_DOMAIN_GART;
- if (!info->domain) {
- info->domain |= (NOUVEAU_GEM_DOMAIN_VRAM |
- NOUVEAU_GEM_DOMAIN_GART);
- }
-
- if (nvbo->flags & NOUVEAU_BO_MAP)
- info->domain |= NOUVEAU_GEM_DOMAIN_MAPPABLE;
-
- info->tile_mode = nvbo->base.tile_mode;
- info->tile_flags = nvbo->base.tile_flags;
- /* XXX - flag inverted for backwards compatibility */
- info->tile_flags ^= NOUVEAU_GEM_TILE_NONCONTIG;
- if (!nvdev->has_bo_usage)
- info->tile_flags &= NOUVEAU_GEM_TILE_LAYOUT_MASK;
-
- ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_GEM_NEW,
- &req, sizeof(req));
- if (ret)
- return ret;
-
- nouveau_bo_info(nvbo, &req.info);
- return 0;
-}
-
-static int
-nouveau_bo_kmap(struct nouveau_bo_priv *nvbo)
-{
- struct nouveau_device_priv *nvdev = nouveau_device(nvbo->base.device);
-
- if (nvbo->map)
- return 0;
-
- if (!nvbo->map_handle)
- return -EINVAL;
-
- nvbo->map = mmap(0, nvbo->size, PROT_READ | PROT_WRITE,
- MAP_SHARED, nvdev->fd, nvbo->map_handle);
- if (nvbo->map == MAP_FAILED) {
- nvbo->map = NULL;
- return -errno;
- }
-
- return 0;
-}
-
-int
-nouveau_bo_new_tile(struct nouveau_device *dev, uint32_t flags, int align,
- int size, uint32_t tile_mode, uint32_t tile_flags,
- struct nouveau_bo **bo)
-{
- struct nouveau_bo_priv *nvbo;
- int ret;
-
- if (!dev || !bo || *bo)
- return -EINVAL;
-
- nvbo = calloc(1, sizeof(struct nouveau_bo_priv));
- if (!nvbo)
- return -ENOMEM;
- nvbo->base.device = dev;
- nvbo->base.size = size;
- nvbo->base.tile_mode = tile_mode;
- nvbo->base.tile_flags = tile_flags;
-
- nvbo->refcount = 1;
- nvbo->flags = flags;
- nvbo->size = size;
- nvbo->align = align;
-
- if (flags & (NOUVEAU_BO_VRAM | NOUVEAU_BO_GART)) {
- ret = nouveau_bo_kalloc(nvbo, NULL);
- if (ret) {
- nouveau_bo_ref(NULL, (void *)&nvbo);
- return ret;
- }
- }
-
- *bo = &nvbo->base;
- return 0;
-}
-
-int
-nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align,
- int size, struct nouveau_bo **bo)
-{
- return nouveau_bo_new_tile(dev, flags, align, size, 0, 0, bo);
-}
-
-int
-nouveau_bo_user(struct nouveau_device *dev, void *ptr, int size,
- struct nouveau_bo **bo)
-{
- struct nouveau_bo_priv *nvbo;
- int ret;
-
- ret = nouveau_bo_new(dev, NOUVEAU_BO_MAP, 0, size, bo);
- if (ret)
- return ret;
- nvbo = nouveau_bo(*bo);
-
- nvbo->sysmem = ptr;
- nvbo->user = 1;
- return 0;
-}
-
-int
-nouveau_bo_wrap(struct nouveau_device *dev, uint32_t handle,
- struct nouveau_bo **bo)
-{
- struct nouveau_device_priv *nvdev = nouveau_device(dev);
- struct drm_nouveau_gem_info req;
- struct nouveau_bo_priv *nvbo;
- int ret;
-
- ret = nouveau_bo_new(dev, 0, 0, 0, bo);
- if (ret)
- return ret;
- nvbo = nouveau_bo(*bo);
-
- req.handle = handle;
- ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_GEM_INFO,
- &req, sizeof(req));
- if (ret) {
- nouveau_bo_ref(NULL, bo);
- return ret;
- }
-
- nouveau_bo_info(nvbo, &req);
- nvbo->base.size = nvbo->size;
- return 0;
-}
-
-int
-nouveau_bo_handle_get(struct nouveau_bo *bo, uint32_t *handle)
-{
- struct nouveau_device_priv *nvdev = nouveau_device(bo->device);
- struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
- int ret;
-
- if (!bo || !handle)
- return -EINVAL;
-
- if (!nvbo->global_handle) {
- struct drm_gem_flink req;
-
- ret = nouveau_bo_kalloc(nvbo, NULL);
- if (ret)
- return ret;
-
- req.handle = nvbo->handle;
- ret = drmIoctl(nvdev->fd, DRM_IOCTL_GEM_FLINK, &req);
- if (ret) {
- nouveau_bo_kfree(nvbo);
- return ret;
- }
-
- nvbo->global_handle = req.name;
- }
-
- *handle = nvbo->global_handle;
- return 0;
-}
-
-int
-nouveau_bo_handle_ref(struct nouveau_device *dev, uint32_t handle,
- struct nouveau_bo **bo)
-{
- struct nouveau_device_priv *nvdev = nouveau_device(dev);
- struct nouveau_bo_priv *nvbo;
- struct drm_gem_open req;
- int ret;
-
- req.name = handle;
- ret = drmIoctl(nvdev->fd, DRM_IOCTL_GEM_OPEN, &req);
- if (ret) {
- nouveau_bo_ref(NULL, bo);
- return ret;
- }
-
- ret = nouveau_bo_wrap(dev, req.handle, bo);
- if (ret) {
- nouveau_bo_ref(NULL, bo);
- return ret;
- }
-
- nvbo = nouveau_bo(*bo);
- nvbo->base.handle = nvbo->handle;
- return 0;
-}
-
-static void
-nouveau_bo_del(struct nouveau_bo **bo)
-{
- struct nouveau_bo_priv *nvbo;
-
- if (!bo || !*bo)
- return;
- nvbo = nouveau_bo(*bo);
- *bo = NULL;
-
- if (--nvbo->refcount)
- return;
-
- if (nvbo->pending) {
- nvbo->pending = NULL;
- nouveau_pushbuf_flush(nvbo->pending_channel, 0);
- }
-
- nouveau_bo_ufree(nvbo);
- nouveau_bo_kfree(nvbo);
- free(nvbo);
-}
-
-int
-nouveau_bo_ref(struct nouveau_bo *ref, struct nouveau_bo **pbo)
-{
- if (!pbo)
- return -EINVAL;
-
- if (ref)
- nouveau_bo(ref)->refcount++;
-
- if (*pbo)
- nouveau_bo_del(pbo);
-
- *pbo = ref;
- return 0;
-}
-
-static int
-nouveau_bo_wait(struct nouveau_bo *bo, int cpu_write, int no_wait, int no_block)
-{
- struct nouveau_device_priv *nvdev = nouveau_device(bo->device);
- struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
- struct drm_nouveau_gem_cpu_prep req;
- int ret;
-
- if (!nvbo->global_handle && !nvbo->write_marker && !cpu_write)
- return 0;
-
- if (nvbo->pending &&
- (nvbo->pending->write_domains || cpu_write)) {
- nvbo->pending = NULL;
- nouveau_pushbuf_flush(nvbo->pending_channel, 0);
- }
-
- req.handle = nvbo->handle;
- req.flags = 0;
- if (cpu_write)
- req.flags |= NOUVEAU_GEM_CPU_PREP_WRITE;
- if (no_wait)
- req.flags |= NOUVEAU_GEM_CPU_PREP_NOWAIT;
- if (no_block)
- req.flags |= NOUVEAU_GEM_CPU_PREP_NOBLOCK;
-
- do {
- ret = drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GEM_CPU_PREP,
- &req, sizeof(req));
- } while (ret == -EAGAIN);
- if (ret)
- return ret;
-
- if (ret == 0)
- nvbo->write_marker = 0;
- return 0;
-}
-
-int
-nouveau_bo_map_range(struct nouveau_bo *bo, uint32_t delta, uint32_t size,
- uint32_t flags)
-{
- struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
- int ret;
-
- if (!nvbo || bo->map)
- return -EINVAL;
-
- if (!nouveau_bo_allocated(nvbo)) {
- if (nvbo->flags & (NOUVEAU_BO_VRAM | NOUVEAU_BO_GART)) {
- ret = nouveau_bo_kalloc(nvbo, NULL);
- if (ret)
- return ret;
- }
-
- if (!nouveau_bo_allocated(nvbo)) {
- ret = nouveau_bo_ualloc(nvbo);
- if (ret)
- return ret;
- }
- }
-
- if (nvbo->sysmem) {
- bo->map = (char *)nvbo->sysmem + delta;
- } else {
- ret = nouveau_bo_kmap(nvbo);
- if (ret)
- return ret;
-
- if (!(flags & NOUVEAU_BO_NOSYNC)) {
- ret = nouveau_bo_wait(bo, (flags & NOUVEAU_BO_WR),
- (flags & NOUVEAU_BO_NOWAIT), 0);
- if (ret)
- return ret;
-
- nvbo->map_refcnt++;
- }
-
- bo->map = (char *)nvbo->map + delta;
- }
-
- return 0;
-}
-
-void
-nouveau_bo_map_flush(struct nouveau_bo *bo, uint32_t delta, uint32_t size)
-{
-}
-
-int
-nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags)
-{
- return nouveau_bo_map_range(bo, 0, bo->size, flags);
-}
-
-void
-nouveau_bo_unmap(struct nouveau_bo *bo)
-{
- struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
-
- if (bo->map && !nvbo->sysmem && nvbo->map_refcnt) {
- struct nouveau_device_priv *nvdev = nouveau_device(bo->device);
- struct drm_nouveau_gem_cpu_fini req;
-
- req.handle = nvbo->handle;
- drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GEM_CPU_FINI,
- &req, sizeof(req));
- nvbo->map_refcnt--;
- }
-
- bo->map = NULL;
-}
-
-int
-nouveau_bo_busy(struct nouveau_bo *bo, uint32_t access)
-{
- return nouveau_bo_wait(bo, (access & NOUVEAU_BO_WR), 1, 1);
-}
-
-uint32_t
-nouveau_bo_pending(struct nouveau_bo *bo)
-{
- struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
- uint32_t flags;
-
- if (!nvbo->pending)
- return 0;
-
- flags = 0;
- if (nvbo->pending->read_domains)
- flags |= NOUVEAU_BO_RD;
- if (nvbo->pending->write_domains)
- flags |= NOUVEAU_BO_WR;
-
- return flags;
-}
-
-struct drm_nouveau_gem_pushbuf_bo *
-nouveau_bo_emit_buffer(struct nouveau_channel *chan, struct nouveau_bo *bo)
-{
- struct nouveau_pushbuf_priv *nvpb = &nouveau_channel(chan)->pb;
- struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
- struct drm_nouveau_gem_pushbuf_bo *pbbo;
- struct nouveau_bo *ref = NULL;
- int ret;
-
- if (nvbo->pending)
- return nvbo->pending;
-
- if (!nvbo->handle) {
- ret = nouveau_bo_kalloc(nvbo, chan);
- if (ret)
- return NULL;
-
- if (nvbo->sysmem) {
- void *sysmem_tmp = nvbo->sysmem;
-
- nvbo->sysmem = NULL;
- ret = nouveau_bo_map(bo, NOUVEAU_BO_WR);
- if (ret)
- return NULL;
- nvbo->sysmem = sysmem_tmp;
-
- memcpy(bo->map, nvbo->sysmem, nvbo->base.size);
- nouveau_bo_ufree(nvbo);
- nouveau_bo_unmap(bo);
- }
- }
-
- if (nvpb->nr_buffers >= NOUVEAU_GEM_MAX_BUFFERS)
- return NULL;
- pbbo = nvpb->buffers + nvpb->nr_buffers++;
- nvbo->pending = pbbo;
- nvbo->pending_channel = chan;
- nvbo->pending_refcnt = 0;
-
- nouveau_bo_ref(bo, &ref);
- pbbo->user_priv = (uint64_t)(unsigned long)ref;
- pbbo->handle = nvbo->handle;
- pbbo->valid_domains = NOUVEAU_GEM_DOMAIN_VRAM | NOUVEAU_GEM_DOMAIN_GART;
- pbbo->read_domains = 0;
- pbbo->write_domains = 0;
- pbbo->presumed.domain = nvbo->domain;
- pbbo->presumed.offset = nvbo->offset;
- pbbo->presumed.valid = 1;
- return pbbo;
-}
104 nouveau/nouveau_bo.h
View
@@ -1,104 +0,0 @@
-/*
- * Copyright 2007 Nouveau Project
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef __NOUVEAU_BO_H__
-#define __NOUVEAU_BO_H__
-
-/* Relocation/Buffer type flags */
-#define NOUVEAU_BO_VRAM (1 << 0)
-#define NOUVEAU_BO_GART (1 << 1)
-#define NOUVEAU_BO_RD (1 << 2)
-#define NOUVEAU_BO_WR (1 << 3)
-#define NOUVEAU_BO_RDWR (NOUVEAU_BO_RD | NOUVEAU_BO_WR)
-#define NOUVEAU_BO_MAP (1 << 4)
-#define NOUVEAU_BO_LOW (1 << 6)
-#define NOUVEAU_BO_HIGH (1 << 7)
-#define NOUVEAU_BO_OR (1 << 8)
-#define NOUVEAU_BO_INVAL (1 << 12)
-#define NOUVEAU_BO_NOSYNC (1 << 13)
-#define NOUVEAU_BO_NOWAIT (1 << 14)
-#define NOUVEAU_BO_IFLUSH (1 << 15)
-#define NOUVEAU_BO_DUMMY (1 << 31)
-
-#define NOUVEAU_BO_TILE_LAYOUT_MASK 0x0000ff00
-#define NOUVEAU_BO_TILE_16BPP 0x00000001
-#define NOUVEAU_BO_TILE_32BPP 0x00000002
-#define NOUVEAU_BO_TILE_ZETA 0x00000004
-#define NOUVEAU_BO_TILE_SCANOUT 0x00000008
-
-struct nouveau_bo {
- struct nouveau_device *device;
- uint32_t handle;
-
- uint64_t size;
- void *map;
-
- uint32_t tile_mode;
- uint32_t tile_flags;
-};
-
-int
-nouveau_bo_new(struct nouveau_device *, uint32_t flags, int align, int size,
- struct nouveau_bo **);
-
-int
-nouveau_bo_new_tile(struct nouveau_device *, uint32_t flags, int align,
- int size, uint32_t tile_mode, uint32_t tile_flags,
- struct nouveau_bo **);
-
-int
-nouveau_bo_user(struct nouveau_device *, void *ptr, int size,
- struct nouveau_bo **);
-
-int
-nouveau_bo_wrap(struct nouveau_device *, uint32_t handle, struct nouveau_bo **);
-
-int
-nouveau_bo_handle_get(struct nouveau_bo *, uint32_t *);
-
-int
-nouveau_bo_handle_ref(struct nouveau_device *, uint32_t handle,
- struct nouveau_bo **);
-
-int
-nouveau_bo_ref(struct nouveau_bo *, struct nouveau_bo **);
-
-int
-nouveau_bo_map_range(struct nouveau_bo *, uint32_t delta, uint32_t size,
- uint32_t flags);
-
-void
-nouveau_bo_map_flush(struct nouveau_bo *, uint32_t delta, uint32_t size);
-
-int
-nouveau_bo_map(struct nouveau_bo *, uint32_t flags);
-
-void
-nouveau_bo_unmap(struct nouveau_bo *);
-
-int
-nouveau_bo_busy(struct nouveau_bo *, uint32_t access);
-
-uint32_t
-nouveau_bo_pending(struct nouveau_bo *);
-
-#endif
142 nouveau/nouveau_channel.c
View
@@ -1,142 +0,0 @@
-/*
- * Copyright 2007 Nouveau Project
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#include "nouveau_private.h"
-
-int
-nouveau_channel_alloc(struct nouveau_device *dev, uint32_t fb_ctxdma,
- uint32_t tt_ctxdma, int pushbuf_size,
- struct nouveau_channel **chan)
-{
- struct nouveau_device_priv *nvdev = nouveau_device(dev);
- struct nouveau_channel_priv *nvchan;
- unsigned i;
- int ret;
-
- if (!nvdev || !chan || *chan)
- return -EINVAL;
-
- nvchan = calloc(1, sizeof(struct nouveau_channel_priv));
- if (!nvchan)
- return -ENOMEM;
- nvchan->base.device = dev;
-
- nvchan->drm.fb_ctxdma_handle = fb_ctxdma;
- nvchan->drm.tt_ctxdma_handle = tt_ctxdma;
- ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
- &nvchan->drm, sizeof(nvchan->drm));
- if (ret) {
- free(nvchan);
- return ret;
- }
-
- nvchan->base.id = nvchan->drm.channel;
- if (nouveau_grobj_ref(&nvchan->base, nvchan->drm.fb_ctxdma_handle,
- &nvchan->base.vram) ||
- nouveau_grobj_ref(&nvchan->base, nvchan->drm.tt_ctxdma_handle,
- &nvchan->base.gart)) {
- nouveau_channel_free((void *)&nvchan);
- return -EINVAL;
- }
-
- /* Mark all DRM-assigned subchannels as in-use */
- for (i = 0; i < nvchan->drm.nr_subchan; i++) {
- struct nouveau_grobj_priv *gr = calloc(1, sizeof(*gr));
-
- gr->base.bound = NOUVEAU_GROBJ_BOUND_EXPLICIT;
- gr->base.subc = i;
- gr->base.handle = nvchan->drm.subchan[i].handle;
- gr->base.grclass = nvchan->drm.subchan[i].grclass;
- gr->base.channel = &nvchan->base;
-
- nvchan->base.subc[i].gr = &gr->base;
- }
-
- if (dev->chipset < 0xc0) {
- ret = nouveau_bo_wrap(dev, nvchan->drm.notifier_handle,
- &nvchan->notifier_bo);
- if (!ret)
- ret = nouveau_bo_map(nvchan->notifier_bo,
- NOUVEAU_BO_RDWR);
- if (ret) {
- nouveau_channel_free((void *)&nvchan);
- return ret;
- }
-
- ret = nouveau_grobj_alloc(&nvchan->base, 0x00000000, 0x0030,
- &nvchan->base.nullobj);
- if (ret) {
- nouveau_channel_free((void *)&nvchan);
- return ret;
- }
- }
-
- ret = nouveau_pushbuf_init(&nvchan->base, pushbuf_size);
- if (ret) {
- nouveau_channel_free((void *)&nvchan);
- return ret;
- }
-
- *chan = &nvchan->base;
- return 0;
-}
-
-void
-nouveau_channel_free(struct nouveau_channel **chan)
-{
- struct nouveau_channel_priv *nvchan;
- struct nouveau_device_priv *nvdev;
- struct drm_nouveau_channel_free cf;
- unsigned i;
-
- if (!chan || !*chan)
- return;
- nvchan = nouveau_channel(*chan);
- (*chan)->flush_notify = NULL;
- *chan = NULL;
- nvdev = nouveau_device(nvchan->base.device);
-
- FIRE_RING(&nvchan->base);
-
- nouveau_pushbuf_fini(&nvchan->base);
- if (nvchan->notifier_bo) {
- nouveau_bo_unmap(nvchan->notifier_bo);
- nouveau_bo_ref(NULL, &nvchan->notifier_bo);
- }
-
- for (i = 0; i < nvchan->drm.nr_subchan; i++)
- free(nvchan->base.subc[i].gr);
-
- nouveau_grobj_free(&nvchan->base.vram);
- nouveau_grobj_free(&nvchan->base.gart);
- nouveau_grobj_free(&nvchan->base.nullobj);
-
- cf.channel = nvchan->drm.channel;
- drmCommandWrite(nvdev->fd, DRM_NOUVEAU_CHANNEL_FREE, &cf, sizeof(cf));
- free(nvchan);
-}
-
-
57 nouveau/nouveau_channel.h
View
@@ -1,57 +0,0 @@
-/*
- * Copyright 2007 Nouveau Project
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef __NOUVEAU_CHANNEL_H__
-#define __NOUVEAU_CHANNEL_H__
-
-struct nouveau_subchannel {
- struct nouveau_grobj *gr;
- unsigned sequence;
-};
-
-struct nouveau_channel {
- uint32_t *cur;
- uint32_t *end;
-
- struct nouveau_device *device;
- int id;
-
- struct nouveau_grobj *nullobj;
- struct nouveau_grobj *vram;
- struct nouveau_grobj *gart;
-
- void *user_private;
- void (*hang_notify)(struct nouveau_channel *);
- void (*flush_notify)(struct nouveau_channel *);
-
- struct nouveau_subchannel subc[8];
- unsigned subc_sequence;
-};
-
-int
-nouveau_channel_alloc(struct nouveau_device *, uint32_t fb, uint32_t tt,
- int pushbuf_size, struct nouveau_channel **);
-
-void
-nouveau_channel_free(struct nouveau_channel **);
-
-#endif
198 nouveau/nouveau_device.c
View
@@ -1,198 +0,0 @@
-/*
- * Copyright 2007 Nouveau Project
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#include "nouveau_private.h"
-
-int
-nouveau_device_open_existing(struct nouveau_device **dev, int close,
- int fd, drm_context_t ctx)
-{
- struct nouveau_device_priv *nvdev;
- drmVersionPtr ver;
- uint64_t value;
- int ret;
-
- if (!dev || *dev)
- return -EINVAL;
-
- nvdev = calloc(1, sizeof(*nvdev));
- if (!nvdev)
- return -ENOMEM;
- nvdev->fd = fd;
- nvdev->ctx = ctx;
- nvdev->needs_close = close;
-
- ver = drmGetVersion(fd);
- if (!ver) {
- nouveau_device_close((void *)&nvdev);
- return -EINVAL;
- }
-
- if ((ver->version_major == 0 && ver->version_patchlevel != 16) ||
- ver->version_major > 1) {
- nouveau_device_close((void *)&nvdev);
- return -EINVAL;
- }
-
- drmFreeVersion(ver);
-
- ret = nouveau_device_get_param(&nvdev->base,
- NOUVEAU_GETPARAM_VM_VRAM_BASE, &value);
- if (ret) {
- nouveau_device_close((void *)&nvdev);
- return ret;
- }
- nvdev->base.vm_vram_base = value;
-
- ret = nouveau_device_get_param(&nvdev->base,
- NOUVEAU_GETPARAM_FB_SIZE, &value);
- if (ret) {
- nouveau_device_close((void *)&nvdev);
- return ret;
- }
- nvdev->base.vm_vram_size = value;
-
- ret = nouveau_device_get_param(&nvdev->base,
- NOUVEAU_GETPARAM_AGP_SIZE, &value);
- if (ret) {
- nouveau_device_close((void *)&nvdev);
- return ret;
- }
- nvdev->base.vm_gart_size = value;
-
- ret = nouveau_bo_init(&nvdev->base);
- if (ret) {
- nouveau_device_close((void *)&nvdev);
- return ret;
- }
-
- ret = nouveau_device_get_param(&nvdev->base,
- NOUVEAU_GETPARAM_CHIPSET_ID, &value);
- if (ret) {
- nouveau_device_close((void *)&nvdev);
- return ret;
- }
- nvdev->base.chipset = value;
-
- ret = nouveau_device_get_param(&nvdev->base,
- NOUVEAU_GETPARAM_HAS_BO_USAGE, &value);
- if (!ret)
- nvdev->has_bo_usage = value;
-
- *dev = &nvdev->base;
- return 0;
-}
-
-int
-nouveau_device_open(struct nouveau_device **dev, const char *busid)
-{
- drm_context_t ctx;
- int fd, ret;
-
- if (!dev || *dev)
- return -EINVAL;
-
- fd = drmOpen("nouveau", busid);
- if (fd < 0)
- return -EINVAL;
-
- ret = drmCreateContext(fd, &ctx);
- if (ret) {
- drmClose(fd);
- return ret;
- }
-
- ret = nouveau_device_open_existing(dev, 1, fd, ctx);
- if (ret) {
- drmDestroyContext(fd, ctx);
- drmClose(fd);
- return ret;
- }
-
- return 0;
-}
-
-void
-nouveau_device_close(struct nouveau_device **dev)
-{
- struct nouveau_device_priv *nvdev;
-
- if (!dev || !*dev)
- return;
- nvdev = nouveau_device(*dev);
- *dev = NULL;
-
- nouveau_bo_takedown(&nvdev->base);
-
- if (nvdev->needs_close) {
- drmDestroyContext(nvdev->fd, nvdev->ctx);
- drmClose(nvdev->fd);
- }
- free(nvdev);
-}
-
-int
-nouveau_device_get_param(struct nouveau_device *dev,
- uint64_t param, uint64_t *value)
-{
- struct nouveau_device_priv *nvdev = nouveau_device(dev);
- struct drm_nouveau_getparam g;
- int ret;
-
- if (!nvdev || !value)
- return -EINVAL;
-
- g.param = param;
- ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_GETPARAM,
- &g, sizeof(g));
- if (ret)
- return ret;
-
- *value = g.value;
- return 0;
-}
-
-int
-nouveau_device_set_param(struct nouveau_device *dev,
- uint64_t param, uint64_t value)
-{
- struct nouveau_device_priv *nvdev = nouveau_device(dev);
- struct drm_nouveau_setparam s;
- int ret;
-
- if (!nvdev)
- return -EINVAL;
-
- s.param = param;
- s.value = value;
- ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_SETPARAM,
- &s, sizeof(s));
- if (ret)
- return ret;
-
- return 0;
-}
-
33 nouveau/nouveau_device.h
View
@@ -1,33 +0,0 @@
-/*
- * Copyright 2007 Nouveau Project
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef __NOUVEAU_DEVICE_H__
-#define __NOUVEAU_DEVICE_H__
-
-struct nouveau_device {
- unsigned chipset;
- uint64_t vm_vram_base;
- uint64_t vm_vram_size;
- uint64_t vm_gart_size;
-};
-
-#endif
58 nouveau/nouveau_drmif.h
View
@@ -1,58 +0,0 @@
-/*
- * Copyright 2008 Nouveau Project
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef __NOUVEAU_DRMIF_H__
-#define __NOUVEAU_DRMIF_H__
-
-#include <stdint.h>
-#include <xf86drm.h>
-
-#include "nouveau_device.h"
-
-struct nouveau_device_priv {
- struct nouveau_device base;
-
- int fd;
- drm_context_t ctx;
- drmLock *lock;
- int needs_close;
- int has_bo_usage;
-};
-#define nouveau_device(n) ((struct nouveau_device_priv *)(n))
-
-int
-nouveau_device_open_existing(struct nouveau_device **, int close,
- int fd, drm_context_t ctx);
-
-int
-nouveau_device_open(struct nouveau_device **, const char *busid);
-
-void
-nouveau_device_close(struct nouveau_device **);
-
-int
-nouveau_device_get_param(struct nouveau_device *, uint64_t param, uint64_t *v);
-
-int
-nouveau_device_set_param(struct nouveau_device *, uint64_t param, uint64_t val);
-
-#endif
148 nouveau/nouveau_grobj.c
View
@@ -1,148 +0,0 @@
-/*
- * Copyright 2007 Nouveau Project
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <stdlib.h>
-#include <errno.h>
-
-#include "nouveau_private.h"
-
-int
-nouveau_grobj_alloc(struct nouveau_channel *chan, uint32_t handle,
- int class, struct nouveau_grobj **grobj)
-{
- struct nouveau_device_priv *nvdev = nouveau_device(chan->device);
- struct nouveau_grobj_priv *nvgrobj;
- struct drm_nouveau_grobj_alloc g;
- int ret;
-
- if (!nvdev || !grobj || *grobj)
- return -EINVAL;
-
- nvgrobj = calloc(1, sizeof(*nvgrobj));
- if (!nvgrobj)
- return -ENOMEM;
- nvgrobj->base.channel = chan;
- nvgrobj->base.handle = handle;
- nvgrobj->base.grclass = class;
- nvgrobj->base.bound = NOUVEAU_GROBJ_UNBOUND;
- nvgrobj->base.subc = -1;
-
- g.channel = chan->id;
- g.handle = handle;
- g.class = class;
- ret = drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GROBJ_ALLOC,
- &g, sizeof(g));
- if (ret) {
- nouveau_grobj_free((void *)&nvgrobj);
- return ret;
- }
-
- *grobj = &nvgrobj->base;
- return 0;
-}
-
-int
-nouveau_grobj_ref(struct nouveau_channel *chan, uint32_t handle,
- struct nouveau_grobj **grobj)
-{
- struct nouveau_grobj_priv *nvgrobj;
-
- if (!chan || !grobj || *grobj)
- return -EINVAL;
-
- nvgrobj = calloc(1, sizeof(struct nouveau_grobj_priv));
- if (!nvgrobj)
- return -ENOMEM;
- nvgrobj->base.channel = chan;
- nvgrobj->base.handle = handle;
- nvgrobj->base.grclass = 0;
-
- *grobj = &nvgrobj->base;
- return 0;
-}
-
-void
-nouveau_grobj_free(struct nouveau_grobj **grobj)
-{
- struct nouveau_device_priv *nvdev;
- struct nouveau_channel_priv *chan;
- struct nouveau_grobj_priv *nvgrobj;
-
- if (!grobj || !*grobj)
- return;
- nvgrobj = nouveau_grobj(*grobj);
- *grobj = NULL;
-
-
- chan = nouveau_channel(nvgrobj->base.channel);
- nvdev = nouveau_device(chan->base.device);
-
- if (nvgrobj->base.grclass) {
- struct drm_nouveau_gpuobj_free f;
-
- FIRE_RING(&chan->base);
- f.channel = chan->drm.channel;
- f.handle = nvgrobj->base.handle;
- drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE,
- &f, sizeof(f));
- }
- if (nvgrobj->base.bound != NOUVEAU_GROBJ_UNBOUND)
- chan->base.subc[nvgrobj->base.subc].gr = NULL;
- free(nvgrobj);
-}
-
-void
-nouveau_grobj_autobind(struct nouveau_grobj *grobj)
-{
- struct nouveau_channel *chan = grobj->channel;
- struct nouveau_subchannel *subc = NULL;
- int i;
-
- for (i = 0; i < 8; i++) {
- struct nouveau_subchannel *scc = &grobj->channel->subc[i];
-
- if (scc->gr && scc->gr->bound == NOUVEAU_GROBJ_BOUND_EXPLICIT)
- continue;
-
- if (!subc || scc->sequence < subc->sequence)
- subc = scc;
- }
-
- if (subc->gr) {
- subc->gr->bound = NOUVEAU_GROBJ_UNBOUND;
- subc->gr->subc = -1;
- }
-
- subc->gr = grobj;
- subc->gr->bound = NOUVEAU_GROBJ_BOUND;
- subc->gr->subc = subc - &grobj->channel->subc[0];
-
- WAIT_RING(chan, 2);
- if (chan->device->chipset < 0xc0) {
- OUT_RING (chan, (1 << 18) | (grobj->subc << 13));
- OUT_RING (chan, grobj->handle);
- } else {
- OUT_RING (chan, (2 << 28) | (1 << 16) | (grobj->subc << 13));
- OUT_RING (chan, grobj->grclass);
- }
-}
-
48 nouveau/nouveau_grobj.h
View
@@ -1,48 +0,0 @@
-/*
- * Copyright 2007 Nouveau Project
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef __NOUVEAU_GROBJ_H__
-#define __NOUVEAU_GROBJ_H__
-
-#include "nouveau_channel.h"
-
-struct nouveau_grobj {
- struct nouveau_channel *channel;
- int grclass;
- uint32_t handle;
-
- enum {
- NOUVEAU_GROBJ_UNBOUND = 0,
- NOUVEAU_GROBJ_BOUND = 1,
- NOUVEAU_GROBJ_BOUND_EXPLICIT = 2
- } bound;
- int subc;
-};
-
-int nouveau_grobj_alloc(struct nouveau_channel *, uint32_t handle,
- int class, struct nouveau_grobj **);
-int nouveau_grobj_ref(struct nouveau_channel *, uint32_t handle,
- struct nouveau_grobj **);
-void nouveau_grobj_free(struct nouveau_grobj **);
-void nouveau_grobj_autobind(struct nouveau_grobj *);
-
-#endif
148 nouveau/nouveau_notifier.c
View
@@ -1,148 +0,0 @@
-/*
- * Copyright 2007 Nouveau Project
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <stdlib.h>
-#include <errno.h>
-#include <sys/time.h>
-
-#include "nouveau_private.h"
-
-#define NOTIFIER(__v) \
- struct nouveau_notifier_priv *nvnotify = nouveau_notifier(notifier); \
- volatile uint32_t *__v = (uint32_t *)((char *)nvnotify->map + (id * 32))
-
-int
-nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle,
- int count, struct nouveau_notifier **notifier)
-{
- struct nouveau_notifier_priv *nvnotify;
- int ret;
-
- if (!chan || !notifier || *notifier)
- return -EINVAL;
-
- nvnotify = calloc(1, sizeof(struct nouveau_notifier_priv));
- if (!nvnotify)
- return -ENOMEM;
- nvnotify->base.channel = chan;
- nvnotify->base.handle = handle;
-
- nvnotify->drm.channel = chan->id;
- nvnotify->drm.handle = handle;
- nvnotify->drm.size = (count * 32);
- if ((ret = drmCommandWriteRead(nouveau_device(chan->device)->fd,
- DRM_NOUVEAU_NOTIFIEROBJ_ALLOC,
- &nvnotify->drm,
- sizeof(nvnotify->drm)))) {
- nouveau_notifier_free((void *)&nvnotify);
- return ret;
- }
-
- nvnotify->map = (char *)nouveau_channel(chan)->notifier_bo->map +
- nvnotify->drm.offset;
- *notifier = &nvnotify->base;
- return 0;
-}
-
-void
-nouveau_notifier_free(struct nouveau_notifier **notifier)
-{
-
- struct nouveau_notifier_priv *nvnotify;
- struct nouveau_channel_priv *nvchan;
- struct nouveau_device_priv *nvdev;
- struct drm_nouveau_gpuobj_free f;
-
- if (!notifier || !*notifier)
- return;
- nvnotify = nouveau_notifier(*notifier);
- *notifier = NULL;
-
- nvchan = nouveau_channel(nvnotify->base.channel);
- nvdev = nouveau_device(nvchan->base.device);
-
- FIRE_RING(&nvchan->base);
-
- f.channel = nvchan->drm.channel;
- f.handle = nvnotify->base.handle;
- drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GPUOBJ_FREE, &f, sizeof(f));
- free(nvnotify);
-}
-
-void
-nouveau_notifier_reset(struct nouveau_notifier *notifier, int id)
-{
- NOTIFIER(n);
-
- n[NV_NOTIFY_TIME_0 /4] = 0x00000000;
- n[NV_NOTIFY_TIME_1 /4] = 0x00000000;
- n[NV_NOTIFY_RETURN_VALUE/4] = 0x00000000;
- n[NV_NOTIFY_STATE /4] = (NV_NOTIFY_STATE_STATUS_IN_PROCESS <<
- NV_NOTIFY_STATE_STATUS_SHIFT);
-}
-
-uint32_t
-nouveau_notifier_status(struct nouveau_notifier *notifier, int id)
-{
- NOTIFIER(n);
-
- return n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT;
-}
-
-uint32_t
-nouveau_notifier_return_val(struct nouveau_notifier *notifier, int id)
-{
- NOTIFIER(n);
-
- return n[NV_NOTIFY_RETURN_VALUE/4];
-}
-
-static inline double
-gettime(void)
-{
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
- return (double)tv.tv_sec + tv.tv_usec / 1000000.0;
-}
-
-int
-nouveau_notifier_wait_status(struct nouveau_notifier *notifier, int id,
- uint32_t status, double timeout)
-{
- NOTIFIER(n);
- double time = 0, t_start = gettime();
-
- while (time <= timeout) {
- uint32_t v;
-
- v = n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT;
- if (v == status)
- return 0;
-
- if (timeout)
- time = gettime() - t_start;
- }
-
- return -EBUSY;
-}
-
63 nouveau/nouveau_notifier.h
View
@@ -1,63 +0,0 @@
-/*
- * Copyright 2007 Nouveau Project
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef __NOUVEAU_NOTIFIER_H__
-#define __NOUVEAU_NOTIFIER_H__
-
-#define NV_NOTIFIER_SIZE 32
-#define NV_NOTIFY_TIME_0 0x00000000
-#define NV_NOTIFY_TIME_1 0x00000004
-#define NV_NOTIFY_RETURN_VALUE 0x00000008
-#define NV_NOTIFY_STATE 0x0000000C
-#define NV_NOTIFY_STATE_STATUS_MASK 0xFF000000
-#define NV_NOTIFY_STATE_STATUS_SHIFT 24
-#define NV_NOTIFY_STATE_STATUS_COMPLETED 0x00
-#define NV_NOTIFY_STATE_STATUS_IN_PROCESS 0x01
-#define NV_NOTIFY_STATE_ERROR_CODE_MASK 0x0000FFFF
-#define NV_NOTIFY_STATE_ERROR_CODE_SHIFT 0
-
-struct nouveau_notifier {
- struct nouveau_channel *channel;
- uint32_t handle;
-};
-
-int
-nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle, int count,
- struct nouveau_notifier **);
-
-void
-nouveau_notifier_free(struct nouveau_notifier **);
-
-void
-nouveau_notifier_reset(struct nouveau_notifier *, int id);
-
-uint32_t
-nouveau_notifier_status(struct nouveau_notifier *, int id);
-
-uint32_t