From: Thierry Reding <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: [RFC libdrm] Add NVIDIA Tegra support
Date: Tue, 4 Dec 2012 16:13:52 +0100 [thread overview]
Message-ID: <1354634032-9986-2-git-send-email-thierry.reding@avionic-design.de> (raw)
In-Reply-To: <1354634032-9986-1-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
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-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
---
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
diff --git a/Makefile.am b/Makefile.am
index 8ecd9d9..e90ae43 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -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)
diff --git a/configure.ac b/configure.ac
index 0c19929..72d6dfa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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 ""
diff --git a/include/drm/Makefile.am b/include/drm/Makefile.am
index 2923ab4..3e33ed0 100644
--- a/include/drm/Makefile.am
+++ b/include/drm/Makefile.am
@@ -35,6 +35,7 @@ klibdrminclude_HEADERS = \
radeon_drm.h \
savage_drm.h \
sis_drm.h \
+ tegra_drm.h \
via_drm.h \
mach64_drm.h
diff --git a/include/drm/tegra_drm.h b/include/drm/tegra_drm.h
new file mode 100644
index 0000000..eaec602
--- /dev/null
+++ b/include/drm/tegra_drm.h
@@ -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__ */
diff --git a/tegra/Makefile.am b/tegra/Makefile.am
new file mode 100644
index 0000000..65cd628
--- /dev/null
+++ b/tegra/Makefile.am
@@ -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
diff --git a/tegra/libdrm_tegra.pc.in b/tegra/libdrm_tegra.pc.in
new file mode 100644
index 0000000..f83c74c
--- /dev/null
+++ b/tegra/libdrm_tegra.pc.in
@@ -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
diff --git a/tegra/tegra.c b/tegra/tegra.c
new file mode 100644
index 0000000..d92eca5
--- /dev/null
+++ b/tegra/tegra.c
@@ -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;
+}
diff --git a/tegra/tegra.h b/tegra/tegra.h
new file mode 100644
index 0000000..619090c
--- /dev/null
+++ b/tegra/tegra.h
@@ -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__ */
diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c
index c91bb9d..913ede8 100644
--- a/tests/modetest/modetest.c
+++ b/tests/modetest/modetest.c
@@ -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];
diff --git a/tests/vbltest/vbltest.c b/tests/vbltest/vbltest.c
index 4fccd59..22a5339 100644
--- a/tests/vbltest/vbltest.c
+++ b/tests/vbltest/vbltest.c
@@ -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;
--
1.8.0.1
next prev parent reply other threads:[~2012-12-04 15:13 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-12-04 15:13 [RFC libdrm] Add NVIDIA Tegra support Thierry Reding
[not found] ` <1354634032-9986-1-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2012-12-04 15:13 ` Thierry Reding [this message]
2012-12-04 15:28 ` Rob Clark
[not found] ` <CAF6AEGum=cOxcHN1fBNfpLpm=bC-dXHZ_h2u96Ek4gwQSWSTtw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-12-04 15:38 ` Thierry Reding
[not found] ` <1354634032-9986-2-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2012-12-05 7:39 ` Arto Merilainen
[not found] ` <50BEFA1F.5090907-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-12-05 7:46 ` Thierry Reding
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1354634032-9986-2-git-send-email-thierry.reding@avionic-design.de \
--to=thierry.reding-rm9k5ik7kjkj5m59nbduvrnah6klmebb@public.gmane.org \
--cc=dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
--cc=linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.