From patchwork Wed Feb 19 16:04:49 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 3682191 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 59168BF13A for ; Wed, 19 Feb 2014 16:05:31 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A01E72016C for ; Wed, 19 Feb 2014 16:05:29 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id B28AA201BA for ; Wed, 19 Feb 2014 16:05:27 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4573FFAE56; Wed, 19 Feb 2014 08:05:15 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-bk0-f43.google.com (mail-bk0-f43.google.com [209.85.214.43]) by gabe.freedesktop.org (Postfix) with ESMTP id 1ADCBF9D7A for ; Wed, 19 Feb 2014 08:05:00 -0800 (PST) Received: by mail-bk0-f43.google.com with SMTP id mx12so264427bkb.2 for ; Wed, 19 Feb 2014 08:05:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; bh=eoMXpK+l9+Cgfxn6gaEtco+Pud6VFaIs/hhdz8g71ew=; b=nfGmfgkDXQYEgKIcA24wrxVtF0KLrbWkNp6DwtSOyXJt8nurTqvhoB4VGTCuncWLkZ hpVZ4efnJLGMl0Y8/lpsxJHAgoZp17TfBRhYZR69I+7D8qvQwKGIsFQeZs9x6qxvO4aG IZFLA/Ra+MC1VbzsDTM9c/VeKh1naC2zGJey/zMVUBLJFkhYcEQ1DDAP8q6Cotm3vInE Mzas5zWlTZwCHWoYioWgAOBTgMIqHoI1di+T/ba8PcKLCTNG6h30VWVRi2i6oBhzvkZn PcgQOPWcGUqIdMt5pi2Y/WKn4dmE7mU2Ut32C58kM8TfRWb2gtgTqfPdzRvWOOZBRqpl 1Mxw== X-Received: by 10.204.65.129 with SMTP id j1mr398452bki.121.1392825900136; Wed, 19 Feb 2014 08:05:00 -0800 (PST) Received: from localhost (port-25108.pppoe.wtnet.de. [46.59.159.204]) by mx.google.com with ESMTPSA id yv9sm923602bkb.0.2014.02.19.08.04.58 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 19 Feb 2014 08:04:59 -0800 (PST) From: Thierry Reding To: dri-devel@lists.freedesktop.org Subject: [RFC libdrm 2/6] libdrm: Add NVIDIA Tegra support Date: Wed, 19 Feb 2014 17:04:49 +0100 Message-Id: <1392825893-7380-3-git-send-email-thierry.reding@gmail.com> X-Mailer: git-send-email 1.8.4.2 In-Reply-To: <1392825893-7380-1-git-send-email-thierry.reding@gmail.com> References: <1392825893-7380-1-git-send-email-thierry.reding@gmail.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dri-devel-bounces@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org X-Spam-Status: No, score=-4.6 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Thierry Reding 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 Signed-off-by: Erik Faye-Lund Signed-off-by: Thierry Reding --- Makefile.am | 6 +- configure.ac | 15 ++- include/drm/Makefile.am | 1 + include/drm/tegra_drm.h | 157 ++++++++++++++++++++++++++++ tegra/Makefile.am | 20 ++++ tegra/libdrm_tegra.pc.in | 11 ++ tegra/private.h | 58 +++++++++++ tegra/tegra.c | 253 ++++++++++++++++++++++++++++++++++++++++++++++ tegra/tegra.h | 47 +++++++++ tests/modetest/modetest.c | 2 +- tests/vbltest/vbltest.c | 2 +- 11 files changed, 568 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/private.h create mode 100644 tegra/tegra.c create mode 100644 tegra/tegra.h diff --git a/Makefile.am b/Makefile.am index 826c30d0c0d9..14c402dce74f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -51,7 +51,11 @@ if HAVE_FREEDRENO FREEDRENO_SUBDIR = freedreno endif -SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) $(EXYNOS_SUBDIR) $(FREEDRENO_SUBDIR) tests include man +if HAVE_TEGRA +TEGRA_SUBDIR = tegra +endif + +SUBDIRS = . $(LIBKMS_SUBDIR) $(INTEL_SUBDIR) $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR) $(OMAP_SUBDIR) $(EXYNOS_SUBDIR) $(FREEDRENO_SUBDIR) $(TEGRA_SUBDIR) tests include man libdrm_la_LTLIBRARIES = libdrm.la libdrm_ladir = $(libdir) diff --git a/configure.ac b/configure.ac index 3f4164238494..752a70592933 100644 --- a/configure.ac +++ b/configure.ac @@ -98,6 +98,11 @@ AC_ARG_ENABLE(freedreno-experimental-api, [Enable support for freedreno's experimental API (default: disabled)]), [FREEDRENO=$enableval], [FREEDRENO=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]) + AC_ARG_ENABLE(install-test-programs, AS_HELP_STRING([--enable-install-test-programs], [Install test programs (default: no)]), @@ -218,6 +223,11 @@ if test "x$FREEDRENO" = xyes; then AC_DEFINE(HAVE_FREEDRENO, 1, [Have freedreno 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 + AM_CONDITIONAL(HAVE_INSTALL_TESTS, [test "x$INSTALL_TESTS" = xyes]) if test "x$INSTALL_TESTS" = xyes; then AC_DEFINE(HAVE_INSTALL_TESTS, 1, [Install test programs]) @@ -269,7 +279,7 @@ else fi AM_CONDITIONAL([HAVE_MANPAGES_STYLESHEET], [test "x$HAVE_MANPAGES_STYLESHEET" = "xyes"]) -if test "x$INTEL" != "xno" -o "x$RADEON" != "xno" -o "x$NOUVEAU" != "xno" -o "x$OMAP" != "xno" -o "x$FREEDRENO" != "xno"; then +if test "x$INTEL" != "xno" -o "x$RADEON" != "xno" -o "x$NOUVEAU" != "xno" -o "x$OMAP" != "xno" -o "x$FREEDRENO" != "xno" -o "x$TEGRA" != "xno"; then # Check for atomic intrinsics AC_CACHE_CHECK([for native atomic primitives], drm_cv_atomic_primitives, [ @@ -402,6 +412,8 @@ AC_CONFIG_FILES([ exynos/libdrm_exynos.pc freedreno/Makefile freedreno/libdrm_freedreno.pc + tegra/Makefile + tegra/libdrm_tegra.pc tests/Makefile tests/modeprint/Makefile tests/modetest/Makefile @@ -426,4 +438,5 @@ echo " Nouveau API $NOUVEAU" echo " OMAP API $OMAP" echo " EXYNOS API $EXYNOS" echo " Freedreno API $FREEDRENO" +echo " Tegra API $TEGRA" echo "" diff --git a/include/drm/Makefile.am b/include/drm/Makefile.am index 2bc34d2ffd9f..f591abc45152 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 \ qxl_drm.h diff --git a/include/drm/tegra_drm.h b/include/drm/tegra_drm.h new file mode 100644 index 000000000000..956ed8aa9d98 --- /dev/null +++ b/include/drm/tegra_drm.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2012-2013, NVIDIA CORPORATION. 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS 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 _UAPI_TEGRA_DRM_H_ +#define _UAPI_TEGRA_DRM_H_ + +#include + +#define DRM_TEGRA_GEM_CREATE_TILED (1 << 0) +#define DRM_TEGRA_GEM_CREATE_BOTTOM_UP (1 << 1) + +struct drm_tegra_gem_create { + __u64 size; + __u32 flags; + __u32 handle; +}; + +struct drm_tegra_gem_mmap { + __u32 handle; + __u32 offset; +}; + +struct drm_tegra_syncpt_read { + __u32 id; + __u32 value; +}; + +struct drm_tegra_syncpt_incr { + __u32 id; + __u32 pad; +}; + +struct drm_tegra_syncpt_wait { + __u32 id; + __u32 thresh; + __u32 timeout; + __u32 value; +}; + +#define DRM_TEGRA_NO_TIMEOUT (0xffffffff) + +struct drm_tegra_open_channel { + __u32 client; + __u32 pad; + __u64 context; +}; + +struct drm_tegra_close_channel { + __u64 context; +}; + +struct drm_tegra_get_syncpt { + __u64 context; + __u32 index; + __u32 id; +}; + +struct drm_tegra_get_syncpt_base { + __u64 context; + __u32 syncpt; + __u32 id; +}; + +struct drm_tegra_syncpt { + __u32 id; + __u32 incrs; +}; + +struct drm_tegra_cmdbuf { + __u32 handle; + __u32 offset; + __u32 words; + __u32 pad; +}; + +struct drm_tegra_reloc { + struct { + __u32 handle; + __u32 offset; + } cmdbuf; + struct { + __u32 handle; + __u32 offset; + } target; + __u32 shift; + __u32 pad; +}; + +struct drm_tegra_waitchk { + __u32 handle; + __u32 offset; + __u32 syncpt; + __u32 thresh; +}; + +struct drm_tegra_submit { + __u64 context; + __u32 num_syncpts; + __u32 num_cmdbufs; + __u32 num_relocs; + __u32 num_waitchks; + __u32 waitchk_mask; + __u32 timeout; + __u32 pad; + __u64 syncpts; + __u64 cmdbufs; + __u64 relocs; + __u64 waitchks; + __u32 fence; /* Return value */ + + __u32 reserved[5]; /* future expansion */ +}; + +#define DRM_TEGRA_GEM_CREATE 0x00 +#define DRM_TEGRA_GEM_MMAP 0x01 +#define DRM_TEGRA_SYNCPT_READ 0x02 +#define DRM_TEGRA_SYNCPT_INCR 0x03 +#define DRM_TEGRA_SYNCPT_WAIT 0x04 +#define DRM_TEGRA_OPEN_CHANNEL 0x05 +#define DRM_TEGRA_CLOSE_CHANNEL 0x06 +#define DRM_TEGRA_GET_SYNCPT 0x07 +#define DRM_TEGRA_SUBMIT 0x08 +#define DRM_TEGRA_GET_SYNCPT_BASE 0x09 + +#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_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_MMAP, struct drm_tegra_gem_mmap) +#define DRM_IOCTL_TEGRA_SYNCPT_READ DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_SYNCPT_READ, struct drm_tegra_syncpt_read) +#define DRM_IOCTL_TEGRA_SYNCPT_INCR DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_SYNCPT_INCR, struct drm_tegra_syncpt_incr) +#define DRM_IOCTL_TEGRA_SYNCPT_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_SYNCPT_WAIT, struct drm_tegra_syncpt_wait) +#define DRM_IOCTL_TEGRA_OPEN_CHANNEL DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_OPEN_CHANNEL, struct drm_tegra_open_channel) +#define DRM_IOCTL_TEGRA_CLOSE_CHANNEL DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_CLOSE_CHANNEL, struct drm_tegra_open_channel) +#define DRM_IOCTL_TEGRA_GET_SYNCPT DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GET_SYNCPT, struct drm_tegra_get_syncpt) +#define DRM_IOCTL_TEGRA_SUBMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_SUBMIT, struct drm_tegra_submit) +#define DRM_IOCTL_TEGRA_GET_SYNCPT_BASE DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GET_SYNCPT_BASE, struct drm_tegra_get_syncpt_base) + +#endif diff --git a/tegra/Makefile.am b/tegra/Makefile.am new file mode 100644 index 000000000000..1b83145b120d --- /dev/null +++ b/tegra/Makefile.am @@ -0,0 +1,20 @@ +AM_CPPFLAGS = \ + -I$(top_srcdir) \ + -I$(top_srcdir)/include/drm + +AM_CFLAGS = \ + $(VISIBILITY_CFLAGS) + +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 000000000000..2e06f49c6fba --- /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: @PACKAGE_VERSION@ +Libs: -L${libdir} -ldrm_tegra +Cflags: -I${includedir} -I${includedir}/libdrm +Requires.private: libdrm diff --git a/tegra/private.h b/tegra/private.h new file mode 100644 index 000000000000..ec69295c2cf8 --- /dev/null +++ b/tegra/private.h @@ -0,0 +1,58 @@ +/* + * Copyright © 2012, 2013 Thierry Reding + * Copyright © 2013 Erik Faye-Lund + * Copyright © 2014 NVIDIA Corporation + * + * 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_PRIVATE_H__ +#define __DRM_TEGRA_PRIVATE_H__ 1 + +#include +#include + +#include + +#include "tegra.h" + +#if defined(HAVE_VISIBILITY) +# define drm_private __attribute__((visibility("hidden"))) +# define drm_public __attribute__((visibility("default"))) +#else +# define drm_private +# define drm_public +#endif + +struct drm_tegra { + bool close; + int fd; +}; + +struct drm_tegra_bo { + struct drm_tegra *drm; + uint32_t handle; + uint32_t offset; + uint32_t flags; + uint32_t size; + atomic_t ref; + void *map; +}; + +#endif /* __DRM_TEGRA_PRIVATE_H__ */ diff --git a/tegra/tegra.c b/tegra/tegra.c new file mode 100644 index 000000000000..8c48ae7c30a1 --- /dev/null +++ b/tegra/tegra.c @@ -0,0 +1,253 @@ +/* + * Copyright © 2012, 2013 Thierry Reding + * Copyright © 2013 Erik Faye-Lund + * Copyright © 2014 NVIDIA Corporation + * + * 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 +#include +#include + +#include + +#include + +#include + +#include "private.h" + +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 drm_tegra *drm = bo->drm; + struct drm_gem_close args; + + if (bo->map) + munmap(bo->map, bo->size); + + memset(&args, 0, sizeof(args)); + args.handle = bo->handle; + + drmIoctl(drm->fd, DRM_IOCTL_GEM_CLOSE, &args); + + free(bo); +} + +static int drm_tegra_wrap(struct drm_tegra **drmp, int fd, bool close) +{ + struct drm_tegra *drm; + int err; + + if (fd < 0 || !drmp) + return -EINVAL; + + drm = calloc(1, sizeof(*drm)); + if (!drm) + return -ENOMEM; + + drm->close = close; + drm->fd = fd; + + *drmp = drm; + + return 0; +} + +drm_public +int drm_tegra_new(struct drm_tegra **drmp, int fd) +{ + bool supported = false; + drmVersionPtr version; + + version = drmGetVersion(fd); + if (!version) + return -ENOMEM; + + if (!strncmp(version->name, "tegra", version->name_len)) + supported = true; + + drmFreeVersion(version); + + if (!supported) + return -ENOTSUP; + + return drm_tegra_wrap(drmp, fd, false); +} + +drm_public +void drm_tegra_close(struct drm_tegra *drm) +{ + if (!drm) + return; + + if (drm->close) + close(drm->fd); + + free(drm); +} + +drm_public +int drm_tegra_bo_new(struct drm_tegra_bo **bop, struct drm_tegra *drm, + uint32_t flags, uint32_t size) +{ + struct drm_tegra_gem_create args; + struct drm_tegra_bo *bo; + int err; + + if (!drm || size == 0 || !bop) + return -EINVAL; + + bo = calloc(1, sizeof(*bo)); + if (!bo) + return -ENOMEM; + + atomic_set(&bo->ref, 1); + bo->flags = flags; + bo->size = size; + bo->drm = drm; + + memset(&args, 0, sizeof(args)); + args.flags = flags; + args.size = size; + + err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_CREATE, &args, + sizeof(args)); + if (err < 0) { + err = -errno; + free(bo); + return err; + } + + bo->handle = args.handle; + + *bop = bo; + + return 0; +} + +drm_public +int drm_tegra_bo_wrap(struct drm_tegra_bo **bop, struct drm_tegra *drm, + uint32_t handle, uint32_t flags, size_t size) +{ + struct drm_tegra_bo *bo; + + if (!drm || !bop) + return -EINVAL; + + bo = calloc(1, sizeof(*bo)); + if (!bo) + return -ENOMEM; + + atomic_set(&bo->ref, 1); + bo->handle = handle; + bo->flags = flags; + bo->size = size; + bo->drm = drm; + + *bop = bo; + + return 0; +} + +drm_public +struct drm_tegra_bo *drm_tegra_bo_get(struct drm_tegra_bo *bo) +{ + if (bo) + atomic_inc(&bo->ref); + + return bo; +} + +drm_public +void drm_tegra_bo_put(struct drm_tegra_bo *bo) +{ + if (bo && atomic_dec_and_test(&bo->ref)) + drm_tegra_bo_free(bo); +} + +drm_public +int drm_tegra_bo_get_handle(struct drm_tegra_bo *bo, uint32_t *handle) +{ + if (!bo || !handle) + return -EINVAL; + + *handle = bo->handle; + + return 0; +} + +drm_public +int drm_tegra_bo_map(struct drm_tegra_bo *bo, void **ptr) +{ + struct drm_tegra *drm = bo->drm; + + if (!bo->map) { + struct drm_tegra_gem_mmap args; + int err; + + memset(&args, 0, sizeof(args)); + args.handle = bo->handle; + + err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_MMAP, &args, + sizeof(args)); + if (err < 0) + return -errno; + + bo->offset = args.offset; + + bo->map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, + drm->fd, bo->offset); + if (bo->map == MAP_FAILED) { + bo->map = NULL; + return -errno; + } + } + + if (ptr) + *ptr = bo->map; + + return 0; +} + +drm_public +int drm_tegra_bo_unmap(struct drm_tegra_bo *bo) +{ + if (!bo) + return -EINVAL; + + if (!bo->map) + return 0; + + if (munmap(bo->map, bo->size)) + return -errno; + + bo->map = NULL; + + return 0; +} diff --git a/tegra/tegra.h b/tegra/tegra.h new file mode 100644 index 000000000000..0731cb3bd4dc --- /dev/null +++ b/tegra/tegra.h @@ -0,0 +1,47 @@ +/* + * Copyright © 2012, 2013 Thierry Reding + * Copyright © 2013 Erik Faye-Lund + * Copyright © 2014 NVIDIA Corporation + * + * 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 +#include + +struct drm_tegra_bo; +struct drm_tegra; + +int drm_tegra_new(struct drm_tegra **drmp, int fd); +void drm_tegra_close(struct drm_tegra *drm); + +int drm_tegra_bo_new(struct drm_tegra_bo **bop, struct drm_tegra *drm, + uint32_t flags, uint32_t size); +int drm_tegra_bo_wrap(struct drm_tegra_bo **bop, struct drm_tegra *drm, + uint32_t handle, uint32_t flags, uint32_t size); +struct drm_tegra_bo *drm_tegra_bo_get(struct drm_tegra_bo *bo); +void drm_tegra_bo_put(struct drm_tegra_bo *bo); +int drm_tegra_bo_get_handle(struct drm_tegra_bo *bo, uint32_t *handle); +int drm_tegra_bo_map(struct drm_tegra_bo *bo, void **ptr); +int drm_tegra_bo_unmap(struct drm_tegra_bo *bo); + +#endif /* __DRM_TEGRA_H__ */ diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index bc9c9988dec7..4212963f8ff0 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c @@ -1386,7 +1386,7 @@ int main(int argc, char **argv) int encoders = 0, connectors = 0, crtcs = 0, planes = 0, framebuffers = 0; int drop_master = 0; int test_vsync = 0; - const char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos", "tilcdc", "msm" }; + const char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos", "tilcdc", "msm", "tegra" }; char *device = NULL; char *module = NULL; unsigned int i; diff --git a/tests/vbltest/vbltest.c b/tests/vbltest/vbltest.c index 2a09d28ed00a..e4b200bf0c3c 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", "omapdrm", "tilcdc", "msm" }; + char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "exynos", "omapdrm", "tilcdc", "msm", "tegra" }; drmVBlank vbl; drmEventContext evctx; struct vbl_info handler_info;