@@ -49,7 +49,11 @@ if HAVE_EXYNOS
EXYNOS_SUBDIR = exynos
endif
-SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) $(EXYNOS_SUBDIR) tests include man
+if HAVE_TEGRA
+TEGRA_SUBDIR = tegra
+endif
+
+SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) $(EXYNOS_SUBDIR) $(TEGRA_SUBDIR) tests include man
libdrm_la_LTLIBRARIES = libdrm.la
libdrm_ladir = $(libdir)
@@ -114,6 +114,11 @@ AC_ARG_ENABLE(exynos-experimental-api,
[Enable support for EXYNOS's experimental API (default: disabled)]),
[EXYNOS=$enableval], [EXYNOS=no])
+AC_ARG_ENABLE(tegra-experimental-api,
+ AS_HELP_STRING([--enable-tegra-experimental-api],
+ [Enable support for Tegra's experimental API (default: disabled)]),
+ [TEGRA=$enableval], [TEGRA=no])
+
dnl ===========================================================================
dnl check compiler flags
AC_DEFUN([LIBDRM_CC_TRY_FLAG], [
@@ -222,6 +227,11 @@ if test "x$EXYNOS" = xyes; then
AC_DEFINE(HAVE_EXYNOS, 1, [Have EXYNOS support])
fi
+AM_CONDITIONAL(HAVE_TEGRA, [test "x$TEGRA" = xyes])
+if test "x$TEGRA" = xyes; then
+ AC_DEFINE(HAVE_TEGRA, 1, [Have Tegra support])
+fi
+
AC_ARG_ENABLE([cairo-tests],
[AS_HELP_STRING([--enable-cairo-tests],
[Enable support for Cairo rendering in tests (default: auto)])],
@@ -247,7 +257,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" -o "x$NOUVEAU" != "xno" -o "x$OMAP" != "xno"; then
+if test "x$INTEL" != "xno" -o "x$RADEON" != "xno" -o "x$NOUVEAU" != "xno" -o "x$OMAP" != "xno" -o "x$TEGRA" != "xno"; then
# Check for atomic intrinsics
AC_CACHE_CHECK([for native atomic primitives], drm_cv_atomic_primitives,
[
@@ -358,6 +368,8 @@ AC_CONFIG_FILES([
omap/libdrm_omap.pc
exynos/Makefile
exynos/libdrm_exynos.pc
+ tegra/Makefile
+ tegra/libdrm_tegra.pc
tests/Makefile
tests/modeprint/Makefile
tests/modetest/Makefile
@@ -380,4 +392,5 @@ echo " Radeon API $RADEON"
echo " Nouveau API $NOUVEAU"
echo " OMAP API $OMAP"
echo " EXYNOS API $EXYNOS"
+echo " Tegra API $TEGRA"
echo ""
@@ -35,6 +35,7 @@ klibdrminclude_HEADERS = \
radeon_drm.h \
savage_drm.h \
sis_drm.h \
+ tegra_drm.h \
via_drm.h \
mach64_drm.h
new file mode 100644
@@ -0,0 +1,48 @@
+/*
+ * Copyright © 2012 Thierry Reding
+ * All Rights Reserved.
+ *
+ * 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 (including the next
+ * paragraph) 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
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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 __TEGRA_DRM_H__
+#define __TEGRA_DRM_H__
+
+struct drm_tegra_gem_create {
+ uint32_t handle;
+ uint32_t offset;
+ uint32_t flags;
+ uint32_t size;
+};
+
+struct drm_tegra_gem_info {
+ uint32_t handle;
+ uint32_t offset;
+ uint32_t flags;
+ uint32_t size;
+};
+
+#define DRM_TEGRA_GEM_CREATE 0x40
+#define DRM_TEGRA_GEM_INFO 0x41
+
+#define DRM_IOCTL_TEGRA_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_CREATE, struct drm_tegra_gem_create)
+#define DRM_IOCTL_TEGRA_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_INFO, struct drm_tegra_gem_info)
+
+#endif /* __TEGRA_DRM_H__ */
new file mode 100644
@@ -0,0 +1,17 @@
+AM_CPPFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/include/drm
+
+libdrm_tegra_ladir = $(libdir)
+libdrm_tegra_la_LTLIBRARIES = libdrm_tegra.la
+libdrm_tegra_la_LDFLAGS = -version-number 0:0:0 -no-undefined
+libdrm_tegra_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
+
+libdrm_tegra_la_SOURCES = \
+ tegra.c
+
+libdrm_tegraincludedir = ${includedir}/libdrm
+libdrm_tegrainclude_HEADERS = tegra.h
+
+pkgconfigdir = @pkgconfigdir@
+pkgconfig_DATA = libdrm_tegra.pc
new file mode 100644
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libdrm_tegra
+Description: Userspace interface to Tegra kernel DRM services
+Version: 2.4.40
+Libs: -L${libdir} -ldrm_tegra
+Cflags: -I${includedir} -I${includedir}/libdrm
+Requires.private: libdrm
new file mode 100644
@@ -0,0 +1,227 @@
+/*
+ * Copyright © 2012 Thierry Reding
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include <sys/mman.h>
+
+#include <libdrm_lists.h>
+#include <xf86atomic.h>
+#include <xf86drm.h>
+
+#include <tegra_drm.h>
+
+#include "tegra.h"
+
+struct drm_tegra {
+ drmMMListHead bo_list;
+ int fd;
+};
+struct tegra_bo {
+ struct drm_tegra_bo base;
+ drmMMListHead list;
+ atomic_t ref;
+};
+
+static inline struct tegra_bo *tegra_bo(struct drm_tegra_bo *bo)
+{
+ return (struct tegra_bo *)bo;
+}
+
+static void drm_tegra_bo_free(struct drm_tegra_bo *bo)
+{
+ struct tegra_bo *priv = tegra_bo(bo);
+ struct drm_gem_close args;
+
+ DRMLISTDEL(&priv->list);
+
+ if (bo->map)
+ munmap(bo->map, bo->size);
+
+ memset(&args, 0, sizeof(args));
+ args.handle = bo->handle;
+
+ drmIoctl(bo->device->fd, DRM_IOCTL_GEM_CLOSE, &args);
+
+ free(bo);
+}
+
+int drm_tegra_open(const char *path, struct drm_tegra **devicep)
+{
+ struct drm_tegra *device;
+ int err;
+
+ if (!path || !devicep)
+ return -EINVAL;
+
+ device = calloc(1, sizeof(*device));
+ if (!device)
+ return -ENOMEM;
+
+ DRMINITLISTHEAD(&device->bo_list);
+
+ device->fd = open(path, O_RDWR);
+ if (device->fd < 0) {
+ err = -errno;
+ free(device);
+ return err;
+ }
+
+ *devicep = device;
+
+ return 0;
+}
+
+void drm_tegra_close(struct drm_tegra *device)
+{
+ if (device) {
+ close(device->fd);
+ free(device);
+ }
+}
+
+int drm_tegra_bo_new(struct drm_tegra *device, uint32_t flags, uint32_t size,
+ struct drm_tegra_bo **bop)
+{
+ struct drm_tegra_gem_create args;
+ struct drm_tegra_bo *bo;
+ struct tegra_bo *priv;
+ int err;
+
+ if (!device || size == 0 || !bop)
+ return -EINVAL;
+
+ bo = calloc(1, sizeof(*bo));
+ if (!bo)
+ return -ENOMEM;
+
+ priv = tegra_bo(bo);
+
+ DRMLISTINITHEAD(&priv->list);
+ atomic_set(&priv->ref, 1);
+ bo->device = device;
+ bo->flags = flags;
+ bo->size = size;
+
+ memset(&args, 0, sizeof(args));
+ args.flags = flags;
+ args.size = size;
+
+ err = drmCommandWriteRead(device->fd, DRM_TEGRA_GEM_CREATE, &args,
+ sizeof(args));
+ if (err < 0) {
+ err = -errno;
+ free(bo);
+ return err;
+ }
+
+ DRMLISTADD(&priv->list, &device->bo_list);
+ bo->handle = args.handle;
+ bo->offset = args.offset;
+
+ *bop = bo;
+
+ return 0;
+}
+
+int drm_tegra_bo_open(struct drm_tegra *device, uint32_t handle,
+ struct drm_tegra_bo **bop)
+{
+ struct drm_tegra_gem_info args;
+ struct drm_tegra_bo *bo;
+ struct tegra_bo *priv;
+ int err;
+
+ if (!device || !bop)
+ return -EINVAL;
+
+ bo = calloc(1, sizeof(*bo));
+ if (!bo)
+ return -ENOMEM;
+
+ priv = tegra_bo(bo);
+
+ DRMLISTINITHEAD(&priv->list);
+ atomic_set(&priv->ref, 1);
+ bo->device = device;
+
+ memset(&args, 0, sizeof(args));
+ args.handle = handle;
+
+ err = drmCommandWriteRead(device->fd, DRM_TEGRA_GEM_INFO, &args,
+ sizeof(args));
+ if (err < 0) {
+ err = -errno;
+ free(bo);
+ return err;
+ }
+
+ DRMLISTADD(&priv->list, &device->bo_list);
+ bo->handle = args.handle;
+ bo->offset = args.offset;
+ bo->flags = args.flags;
+ bo->size = args.size;
+
+ *bop = bo;
+
+ return 0;
+}
+
+struct drm_tegra_bo *drm_tegra_bo_get(struct drm_tegra_bo *bo)
+{
+ if (bo) {
+ struct tegra_bo *priv = tegra_bo(bo);
+ atomic_inc(&priv->ref);
+ }
+
+ return bo;
+}
+
+void drm_tegra_bo_put(struct drm_tegra_bo *bo)
+{
+ if (bo) {
+ struct tegra_bo *priv = tegra_bo(bo);
+
+ if (atomic_dec_and_test(&priv->ref))
+ drm_tegra_bo_free(bo);
+ }
+}
+
+int drm_tegra_bo_map(struct drm_tegra_bo *bo)
+{
+ if (!bo->map) {
+ bo->map = mmap(0, bo->size, PROT_READ | PROT_WRITE,
+ MAP_SHARED, bo->device->fd, bo->offset);
+ if (bo->map == MAP_FAILED) {
+ bo->map = NULL;
+ return -errno;
+ }
+ }
+
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,51 @@
+/*
+ * Copyright © 2012 Thierry Reding
+ *
+ * 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.
+ */
+
+#ifndef __DRM_TEGRA_H__
+#define __DRM_TEGRA_H__ 1
+
+#include <stdint.h>
+#include <stdlib.h>
+
+struct drm_tegra;
+
+struct drm_tegra_bo {
+ struct drm_tegra *device;
+ uint32_t handle;
+ uint32_t offset;
+ uint32_t flags;
+ uint32_t size;
+ void *map;
+};
+
+int drm_tegra_open(const char *path, struct drm_tegra **devicep);
+void drm_tegra_close(struct drm_tegra *device);
+
+int drm_tegra_bo_new(struct drm_tegra *device, uint32_t flags, uint32_t size,
+ struct drm_tegra_bo **bop);
+int drm_tegra_bo_open(struct drm_tegra *device, uint32_t handle,
+ struct drm_tegra_bo **bop);
+int drm_tegra_bo_map(struct drm_tegra_bo *bo);
+struct drm_tegra_bo *drm_tegra_bo_get(struct drm_tegra_bo *bo);
+void drm_tegra_bo_put(struct drm_tegra_bo *bo);
+
+#endif /* __DRM_TEGRA_H__ */
@@ -939,7 +939,7 @@ int main(int argc, char **argv)
int c;
int encoders = 0, connectors = 0, crtcs = 0, planes = 0, framebuffers = 0;
int test_vsync = 0;
- char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos" };
+ char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos", "tegra" };
unsigned int i;
int count = 0, plane_count = 0;
struct connector con_args[2];
@@ -103,7 +103,7 @@ static void usage(char *name)
int main(int argc, char **argv)
{
int i, c, fd, ret;
- char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "exynos" };
+ char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "exynos", "tegra" };
drmVBlank vbl;
drmEventContext evctx;
struct vbl_info handler_info;
Add the libdrm_tegra helper library to encapsulate Tegra-specific interfaces to the DRM. Furthermore, Tegra is added to the list of supported chips in the modetest and vbltest programs. Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de> --- Makefile.am | 6 +- configure.ac | 15 ++- include/drm/Makefile.am | 1 + include/drm/tegra_drm.h | 48 ++++++++++ tegra/Makefile.am | 17 ++++ tegra/libdrm_tegra.pc.in | 11 +++ tegra/tegra.c | 227 ++++++++++++++++++++++++++++++++++++++++++++++ tegra/tegra.h | 51 +++++++++++ tests/modetest/modetest.c | 2 +- tests/vbltest/vbltest.c | 2 +- 10 files changed, 376 insertions(+), 4 deletions(-) create mode 100644 include/drm/tegra_drm.h create mode 100644 tegra/Makefile.am create mode 100644 tegra/libdrm_tegra.pc.in create mode 100644 tegra/tegra.c create mode 100644 tegra/tegra.h