[PATCH 2/2] compositor-drm: Add support for Tegra Jetson TK1

Rob Clark robdclark at gmail.com
Sat Jun 21 04:37:16 PDT 2014


On Fri, Jun 20, 2014 at 12:12 PM, James Thomas
<james.thomas at codethink.co.uk> wrote:
> Update configure.ac to add check for libdrm_tegra
> ---
>  configure.ac         | 18 ++++++++++
>  src/compositor-drm.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 111 insertions(+), 3 deletions(-)
>
> diff --git a/configure.ac b/configure.ac
> index b4511fc..ece4a0c 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -110,6 +110,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)
> @@ -555,4 +572,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 19d1e47..89eed71 100644
> --- a/src/compositor-drm.c
> +++ b/src/compositor-drm.c
> @@ -42,6 +42,9 @@
>
>  #include <gbm.h>
>  #include <libudev.h>
> +#ifdef HAVE_DRM_TEGRA
> +#include <tegra_drm.h>
> +#endif
>
>  #include "libbacklight.h"
>  #include "compositor.h"
> @@ -211,6 +214,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);
>
> @@ -351,6 +380,32 @@ drm_fb_get_from_bo(struct gbm_bo *bo,
>         fb->size = fb->stride * height;
>         fb->fd = compositor->drm.fd;
>
> +       if (compositor->drm.fd != compositor->gbm.fd) {
> +               int fd;
> +
> +               ret = drmPrimeHandleToFD(compositor->gbm.fd, fb->handle, 0,
> +                                        &fd);
> +               if (ret) {
> +                       weston_log("failed to export bo: %m\n");
> +                       goto err_free;
> +               }
> +
> +               ret = drmPrimeFDToHandle(compositor->drm.fd, fd, &fb->handle);
> +               if (ret) {
> +                       weston_log("failed to import bo: %m\n");
> +                       goto err_free;
> +               }
> +
> +               close(fd);
> +
> +               ret = drm_tegra_import(compositor->drm.fd, fb->handle);
> +               if (ret < 0) {
> +                       weston_log("failed to import handle: %s\n",
> +                                  strerror(-ret));
> +                       goto err_free;
> +               }
> +       }
> +
>         if (compositor->min_width > width || width > compositor->max_width ||
>             compositor->min_height > height ||
>             height > compositor->max_height) {
> @@ -1265,6 +1320,8 @@ on_drm_input(int fd, uint32_t mask, void *data)
>         return 1;
>  }
>
> +
> +
>  static int
>  init_drm(struct drm_compositor *ec, struct udev_device *device)
>  {
> @@ -1294,8 +1351,14 @@ init_drm(struct drm_compositor *ec, struct udev_device *device)
>         ec->drm.fd = fd;
>         ec->drm.filename = strdup(filename);
>
> -       ec->gbm.fd = fd;
> -       ec->gbm.filename = ec->drm.filename;
> +       if (ec->gbm.filename) {
> +               fd = weston_launcher_open(ec->base.launcher, ec->gbm.filename,
> +                                         O_RDWR);
> +               ec->gbm.fd = fd;
> +       } else {
> +               ec->gbm.fd = fd;
> +               ec->gbm.filename = ec->drm.filename;
> +       }
>
>         ret = drmGetCap(fd, DRM_CAP_TIMESTAMP_MONOTONIC, &cap);
>         if (ret == 0 && cap == 1)
> @@ -2500,7 +2563,7 @@ find_primary_gpu(struct drm_compositor *ec, 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(ec->udev);
>         udev_enumerate_add_match_subsystem(e, "drm");
> @@ -2510,6 +2573,7 @@ find_primary_gpu(struct drm_compositor *ec, const char *seat)
>         drm_device = NULL;
>         udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
>                 path = udev_list_entry_get_name(entry);
> +               weston_log("udev path = %s\n", path);
>                 device = udev_device_new_from_syspath(ec->udev, path);
>                 if (!device)
>                         continue;
> @@ -2531,6 +2595,32 @@ find_primary_gpu(struct drm_compositor *ec, 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")) {


Just one minor, perhaps not very helpful comment...

This separate display vs gpu device is actually going to be the more
common case for SoC devices.  It would be a very good candidate to
*somehow* extract this sort of logic out into some helper library so
it can be shared between different wayland compositors.  No idea if
that should be libdrm or something new?  Or perhaps we could somehow
expose some attributes/flags from kernel or gbm to hint about what
device to use for rendering vs display so that the compositor could
automagically do the right thing?

But we'll need the same sort of thing for etnaviv and someday lima.
And would be nice if each different wayland compositor did not have to
be patched every time there was a new combination of SoC (display
controller) vs. gpu.

BR,
-R

> +                                       if (drm_device) {
> +                                               /* Previously have found the
> +                                                * drm device, use this device
> +                                                * as the GBM device
> +                                                */
> +                                               if (udev_device_get_devnode(
> +                                                               device)) {
> +                                                       ec->gbm.filename = strdup(
> +                                                               udev_device_get_devnode(device));
> +                                                       break;
> +                                               }
> +                                               continue;
> +                                       }
> +                                       drm_device = device;
> +                                       continue;
> +                               }
> +                       }
>                 }
>
>                 if (!drm_device)
> --
> 1.9.3
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list