From 2e5232b980eaa1074023a65dd7941e80b72a763c Mon Sep 17 00:00:00 2001 From: James Thomas Date: Fri, 20 Jun 2014 12:42:32 +0000 Subject: compositor-drm: Add support for Tegra Jetson TK1 Update configure.ac to add check for libdrm_tegra --- configure.ac | 18 ++++++++++ src/compositor-drm.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 110 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 97a77694..fbb2c8cf 100644 --- a/configure.ac +++ b/configure.ac @@ -133,6 +133,23 @@ fi PKG_CHECK_MODULES(LIBDRM, [libdrm], [AC_DEFINE(HAVE_LIBDRM, 1, [Define if libdrm is available]) have_libdrm=yes], have_libdrm=no) +AC_ARG_ENABLE(libdrm-tegra, + AS_HELP_STRING([--disable-libdrm-tegra], + [do not build support for nvidia Jetson TK1]),, + enable_libdrm_tegra=auto) + +if test "x$enable_libdrm_tegra" != "xno"; then + PKG_CHECK_MODULES(LIBDRM_TEGRA, + libdrm_tegra, + have_libdrm_tegra=yes, + have_libdrm_tegra=no) + if test "x$have_libdrm_tegra" = "xno" -a "x$enable_libdrm_tegra" = "xyes"; then + AC_MSG_ERROR([Tegra support explicitly requested, but libdrm_tegra not found]) + fi + AS_IF([test "x$have_libdrm_tegra" = "xyes"], + AC_DEFINE([HAVE_DRM_TEGRA], [1], [Enable tegra support in drm backend])) +fi + AC_ARG_ENABLE(x11-compositor, [ --enable-x11-compositor],, enable_x11_compositor=yes) AM_CONDITIONAL(ENABLE_X11_COMPOSITOR, test x$enable_x11_compositor = xyes) @@ -699,4 +716,5 @@ AC_MSG_RESULT([ libwebp Support ${have_webp} libunwind Support ${have_libunwind} VA H.264 encoding Support ${have_libva} + Tegra DRM Support ${have_libdrm_tegra} ]) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index e7417ff7..22f2afb8 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -45,6 +45,9 @@ #include #include +#ifdef HAVE_DRM_TEGRA +#include +#endif #include "compositor.h" #include "compositor-drm.h" @@ -227,6 +230,32 @@ static struct gl_renderer_interface *gl_renderer; static const char default_seat[] = "seat0"; +static int +drm_tegra_import(int fd, uint32_t handle) +{ + #ifdef HAVE_DRM_TEGRA + struct drm_tegra_gem_set_tiling args; + int err; + + memset(&args, 0, sizeof(args)); + args.handle = handle; + args.mode = DRM_TEGRA_GEM_TILING_MODE_BLOCK; + args.value = 4; + + err = ioctl(fd, DRM_IOCTL_TEGRA_GEM_SET_TILING, &args); + if (err < 0) { + weston_log("failed to set tiling parameters: %m\n"); + return -errno; + } + return 0; + #else + weston_log("DRM device is a tegra but weston compiled without " + "libdrm tegra"); + + return -1; + #endif +} + static void drm_output_set_cursor(struct drm_output *output); @@ -369,6 +398,32 @@ drm_fb_get_from_bo(struct gbm_bo *bo, fb->size = fb->stride * height; fb->fd = backend->drm.fd; + if (backend->drm.fd != backend->gbm.fd) { + int fd; + + ret = drmPrimeHandleToFD(backend->gbm.fd, fb->handle, 0, + &fd); + if (ret) { + weston_log("failed to export bo: %m\n"); + goto err_free; + } + + ret = drmPrimeFDToHandle(backend->drm.fd, fd, &fb->handle); + if (ret) { + weston_log("failed to import bo: %m\n"); + goto err_free; + } + + close(fd); + + ret = drm_tegra_import(backend->drm.fd, fb->handle); + if (ret < 0) { + weston_log("failed to import handle: %s\n", + strerror(-ret)); + goto err_free; + } + } + if (backend->min_width > width || width > backend->max_width || backend->min_height > height || height > backend->max_height) { @@ -1467,6 +1522,8 @@ on_drm_input(int fd, uint32_t mask, void *data) return 1; } + + static int init_drm(struct drm_backend *b, struct udev_device *device) { @@ -1497,8 +1554,14 @@ init_drm(struct drm_backend *b, struct udev_device *device) b->drm.fd = fd; b->drm.filename = strdup(filename); - b->gbm.fd = fd; - b->gbm.filename = b->drm.filename; + if (b->gbm.filename) { + fd = weston_launcher_open(b->compositor->launcher, b->gbm.filename, + O_RDWR); + b->gbm.fd = fd; + } else { + b->gbm.fd = fd; + b->gbm.filename = b->drm.filename; + } ret = drmGetCap(fd, DRM_CAP_TIMESTAMP_MONOTONIC, &cap); if (ret == 0 && cap == 1) @@ -2809,7 +2872,7 @@ find_primary_gpu(struct drm_backend *b, const char *seat) struct udev_enumerate *e; struct udev_list_entry *entry; const char *path, *device_seat, *id; - struct udev_device *device, *drm_device, *pci; + struct udev_device *device, *drm_device, *pci, *soc = NULL; e = udev_enumerate_new(b->udev); udev_enumerate_add_match_subsystem(e, "drm"); @@ -2840,6 +2903,32 @@ find_primary_gpu(struct drm_backend *b, const char *seat) drm_device = device; break; } + } else { + soc = udev_device_get_parent_with_subsystem_devtype( + device, + "soc", + NULL); + if (soc) { + id = udev_device_get_sysattr_value(soc, + "family"); + if (id && !strcmp(id, "Tegra")) { + if (drm_device) { + /* Previously have found the + * drm device, use this device + * as the GBM device + */ + if (udev_device_get_devnode( + device)) { + b->gbm.filename = strdup( + udev_device_get_devnode(device)); + break; + } + continue; + } + drm_device = device; + continue; + } + } } if (!drm_device) -- cgit v1.2.1