Module Name:    xsrc
Committed By:   mrg
Date:           Mon Jul 20 02:27:06 UTC 2015

Modified Files:
        xsrc/external/mit/libdrm/dist: xf86atomic.h xf86drm.c xf86drm.h
            xf86drmMode.c xf86drmMode.h
        xsrc/external/mit/libdrm/dist/include/drm: drm.h i915_drm.h
        xsrc/external/mit/libdrm/dist/intel: intel_bufmgr_gem.c
        xsrc/external/mit/libdrm/dist/radeon: radeon_bo_gem.c radeon_cs_gem.c
            radeon_surface.c
        xsrc/external/mit/libdrm/dist/tests/modetest: modetest.c
Removed Files:
        xsrc/external/mit/libdrm/dist: libdrm.h
        xsrc/external/mit/libdrm/dist/exynos: fimg2d.h
        xsrc/external/mit/libdrm/dist/tests: gem_basic.c gem_flink.c gem_mmap.c
            gem_readwrite.c

Log Message:
merge libdrm 2.4.62.


To generate a diff of this commit:
cvs rdiff -u -r1.1.1.1 -r0 xsrc/external/mit/libdrm/dist/libdrm.h
cvs rdiff -u -r1.5 -r1.6 xsrc/external/mit/libdrm/dist/xf86atomic.h
cvs rdiff -u -r1.10 -r1.11 xsrc/external/mit/libdrm/dist/xf86drm.c
cvs rdiff -u -r1.4 -r1.5 xsrc/external/mit/libdrm/dist/xf86drm.h \
    xsrc/external/mit/libdrm/dist/xf86drmMode.h
cvs rdiff -u -r1.8 -r1.9 xsrc/external/mit/libdrm/dist/xf86drmMode.c
cvs rdiff -u -r1.1.1.2 -r0 xsrc/external/mit/libdrm/dist/exynos/fimg2d.h
cvs rdiff -u -r1.4 -r1.5 xsrc/external/mit/libdrm/dist/include/drm/drm.h
cvs rdiff -u -r1.2 -r1.3 xsrc/external/mit/libdrm/dist/include/drm/i915_drm.h
cvs rdiff -u -r1.10 -r1.11 \
    xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c
cvs rdiff -u -r1.5 -r1.6 xsrc/external/mit/libdrm/dist/radeon/radeon_bo_gem.c
cvs rdiff -u -r1.4 -r1.5 xsrc/external/mit/libdrm/dist/radeon/radeon_cs_gem.c
cvs rdiff -u -r1.6 -r1.7 \
    xsrc/external/mit/libdrm/dist/radeon/radeon_surface.c
cvs rdiff -u -r1.1.1.1 -r0 xsrc/external/mit/libdrm/dist/tests/gem_basic.c
cvs rdiff -u -r1.1.1.3 -r0 xsrc/external/mit/libdrm/dist/tests/gem_flink.c
cvs rdiff -u -r1.1.1.2 -r0 xsrc/external/mit/libdrm/dist/tests/gem_mmap.c \
    xsrc/external/mit/libdrm/dist/tests/gem_readwrite.c
cvs rdiff -u -r1.6 -r1.7 \
    xsrc/external/mit/libdrm/dist/tests/modetest/modetest.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: xsrc/external/mit/libdrm/dist/xf86atomic.h
diff -u xsrc/external/mit/libdrm/dist/xf86atomic.h:1.5 xsrc/external/mit/libdrm/dist/xf86atomic.h:1.6
--- xsrc/external/mit/libdrm/dist/xf86atomic.h:1.5	Sat Dec 13 21:39:07 2014
+++ xsrc/external/mit/libdrm/dist/xf86atomic.h	Mon Jul 20 02:27:05 2015
@@ -49,7 +49,8 @@ typedef struct {
 # define atomic_read(x) ((x)->atomic)
 # define atomic_set(x, val) ((x)->atomic = (val))
 # define atomic_inc(x) ((void) __sync_fetch_and_add (&(x)->atomic, 1))
-# define atomic_dec_and_test(x) (__sync_fetch_and_add (&(x)->atomic, -1) == 1)
+# define atomic_inc_return(x) (__sync_add_and_fetch (&(x)->atomic, 1))
+# define atomic_dec_and_test(x) (__sync_add_and_fetch (&(x)->atomic, -1) == 0)
 # define atomic_add(x, v) ((void) __sync_add_and_fetch(&(x)->atomic, (v)))
 # define atomic_dec(x, v) ((void) __sync_sub_and_fetch(&(x)->atomic, (v)))
 # define atomic_cmpxchg(x, oldv, newv) __sync_val_compare_and_swap (&(x)->atomic, oldv, newv)
@@ -68,6 +69,7 @@ typedef struct {
 # define atomic_read(x) AO_load_full(&(x)->atomic)
 # define atomic_set(x, val) AO_store_full(&(x)->atomic, (val))
 # define atomic_inc(x) ((void) AO_fetch_and_add1_full(&(x)->atomic))
+# define atomic_inc_return(x) (AO_fetch_and_add1_full(&(x)->atomic) + 1)
 # define atomic_add(x, v) ((void) AO_fetch_and_add_full(&(x)->atomic, (v)))
 # define atomic_dec(x, v) ((void) AO_fetch_and_add_full(&(x)->atomic, -(v)))
 # define atomic_dec_and_test(x) (AO_fetch_and_sub1_full(&(x)->atomic) == 1)
@@ -75,33 +77,23 @@ typedef struct {
 
 #endif
 
-#if defined(__sun) && !defined(HAS_ATOMIC_OPS)  /* Solaris & OpenSolaris */
+#if (defined(__sun) || defined(__NetBSD__)) && !defined(HAS_ATOMIC_OPS)  /* Solaris & OpenSolaris & NetBSD */
 
 #include <sys/atomic.h>
 #define HAS_ATOMIC_OPS 1
 
-typedef struct { uint_t atomic; } atomic_t;
-
-# define atomic_read(x) (int) ((x)->atomic)
-# define atomic_set(x, val) ((x)->atomic = (uint_t)(val))
-# define atomic_inc(x) (atomic_inc_uint (&(x)->atomic))
-# define atomic_dec_and_test(x) (atomic_dec_uint_nv(&(x)->atomic) == 0)
-# define atomic_add(x, v) (atomic_add_int(&(x)->atomic, (v)))
-# define atomic_dec(x, v) (atomic_add_int(&(x)->atomic, -(v)))
-# define atomic_cmpxchg(x, oldv, newv) atomic_cas_uint (&(x)->atomic, oldv, newv)
-
+#if defined(__NetBSD__)
+#define LIBDRM_ATOMIC_TYPE int
+#else
+#define LIBDRM_ATOMIC_TYPE uint_t
 #endif
 
-#if defined(__NetBSD__) && !defined(HAS_ATOMIC_OPS)  /* NetBSD */
-
-#include <sys/atomic.h>
-#define HAS_ATOMIC_OPS 1
-
-typedef struct { int atomic; } atomic_t;
+typedef struct { LIBDRM_ATOMIC_TYPE atomic; } atomic_t;
 
 # define atomic_read(x) (int) ((x)->atomic)
-# define atomic_set(x, val) ((x)->atomic = (val))
+# define atomic_set(x, val) ((x)->atomic = (LIBDRM_ATOMIC_TYPE)(val))
 # define atomic_inc(x) (atomic_inc_uint (&(x)->atomic))
+# define atomic_inc_return (atomic_inc_uint_nv(&(x)->atomic))
 # define atomic_dec_and_test(x) (atomic_dec_uint_nv(&(x)->atomic) == 0)
 # define atomic_add(x, v) (atomic_add_int(&(x)->atomic, (v)))
 # define atomic_dec(x, v) (atomic_add_int(&(x)->atomic, -(v)))

Index: xsrc/external/mit/libdrm/dist/xf86drm.c
diff -u xsrc/external/mit/libdrm/dist/xf86drm.c:1.10 xsrc/external/mit/libdrm/dist/xf86drm.c:1.11
--- xsrc/external/mit/libdrm/dist/xf86drm.c:1.10	Sun Dec 14 23:52:45 2014
+++ xsrc/external/mit/libdrm/dist/xf86drm.c	Mon Jul 20 02:27:05 2015
@@ -40,6 +40,8 @@
 #include <string.h>
 #include <strings.h>
 #include <ctype.h>
+#include <dirent.h>
+#include <stddef.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <signal.h>
@@ -50,6 +52,9 @@
 #include <sys/ioctl.h>
 #include <sys/time.h>
 #include <stdarg.h>
+#ifdef HAVE_SYS_MKDEV_H
+# include <sys/mkdev.h> /* defines major(), minor(), and makedev() on Solaris */
+#endif
 
 /* Not all systems have MAP_FAILED defined */
 #ifndef MAP_FAILED
@@ -57,7 +62,7 @@
 #endif
 
 #include "xf86drm.h"
-#include "libdrm.h"
+#include "libdrm_macros.h"
 
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
 #define DRM_MAJOR 145
@@ -86,8 +91,7 @@
 
 #define DRM_MSG_VERBOSITY 3
 
-#define DRM_NODE_CONTROL 0
-#define DRM_NODE_RENDER 1
+#define memclear(s) memset(&s, 0, sizeof(s))
 
 static drmServerInfoPtr drm_server_info;
 
@@ -111,11 +115,6 @@ drmDebugPrint(const char *format, va_lis
     return vfprintf(stderr, format, ap);
 }
 
-typedef int DRM_PRINTFLIKE(1, 0) (*debug_msg_func_t)(const char *format,
-						     va_list ap);
-
-static debug_msg_func_t drm_debug_print = drmDebugPrint;
-
 void
 drmMsg(const char *format, ...)
 {
@@ -127,18 +126,12 @@ drmMsg(const char *format, ...)
 	if (drm_server_info) {
 	  drm_server_info->debug_print(format,ap);
 	} else {
-	  drm_debug_print(format, ap);
+	  drmDebugPrint(format, ap);
 	}
 	va_end(ap);
     }
 }
 
-void
-drmSetDebugMsgFunction(debug_msg_func_t debug_msg_ptr)
-{
-    drm_debug_print = debug_msg_ptr;
-}
-
 static void *drmHashTable = NULL; /* Context switch callbacks */
 
 void *drmGetHashTable(void)
@@ -148,16 +141,12 @@ void *drmGetHashTable(void)
 
 void *drmMalloc(int size)
 {
-    void *pt;
-    if ((pt = malloc(size)))
-	memset(pt, 0, size);
-    return pt;
+    return calloc(1, size);
 }
 
 void drmFree(void *pt)
 {
-    if (pt)
-	free(pt);
+    free(pt);
 }
 
 /**
@@ -274,6 +263,7 @@ static int drmMatchBusID(const char *id1
  * If any other failure happened then it will output error mesage using
  * drmMsg() call.
  */
+#if !defined(UDEV)
 static int chown_check_return(const char *path, uid_t owner, gid_t group)
 {
 	int rv;
@@ -289,6 +279,7 @@ static int chown_check_return(const char
 			path, errno, strerror(errno));
 	return -1;
 }
+#endif
 
 /**
  * Open the DRM device, creating it if necessary.
@@ -303,24 +294,41 @@ static int chown_check_return(const char
  * special file node with the major and minor numbers specified by \p dev and
  * parent directory if necessary and was called by root.
  */
-static int drmOpenDevice(long dev, int minor, int type)
+static int drmOpenDevice(dev_t dev, int minor, int type)
 {
     stat_t          st;
+    const char      *dev_name;
     char            buf[64];
     int             fd;
     mode_t          devmode = DRM_DEV_MODE, serv_mode;
+    gid_t           serv_group;
+#if !defined(UDEV)
     int             isroot  = !geteuid();
     uid_t           user    = DRM_DEV_UID;
-    gid_t           group   = DRM_DEV_GID, serv_group;
-    
-    sprintf(buf, type ? DRM_DEV_NAME : DRM_CONTROL_DEV_NAME, DRM_DIR_NAME, minor);
+    gid_t           group   = DRM_DEV_GID;
+#endif
+
+    switch (type) {
+    case DRM_NODE_PRIMARY:
+	    dev_name = DRM_DEV_NAME;
+	    break;
+    case DRM_NODE_CONTROL:
+	    dev_name = DRM_CONTROL_DEV_NAME;
+	    break;
+    case DRM_NODE_RENDER:
+	    dev_name = DRM_RENDER_DEV_NAME;
+	    break;
+    default:
+	    return -EINVAL;
+    };
+
+    sprintf(buf, dev_name, DRM_DIR_NAME, minor);
     drmMsg("drmOpenDevice: node name is %s\n", buf);
 
     if (drm_server_info) {
 	drm_server_info->get_perms(&serv_group, &serv_mode);
 	devmode  = serv_mode ? serv_mode : DRM_DEV_MODE;
 	devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
-	group = (serv_group >= 0) ? serv_group : DRM_DEV_GID;
     }
 
 #if !defined(UDEV)
@@ -341,6 +349,7 @@ static int drmOpenDevice(long dev, int m
     }
 
     if (drm_server_info) {
+	group = ((int)serv_group >= 0) ? serv_group : DRM_DEV_GID;
 	chown_check_return(buf, user, group);
 	chmod(buf, devmode);
     }
@@ -418,11 +427,26 @@ static int drmOpenMinor(int minor, int c
 {
     int  fd;
     char buf[64];
+    const char *dev_name;
     
     if (create)
 	return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type);
     
-    sprintf(buf, type ? DRM_DEV_NAME : DRM_CONTROL_DEV_NAME, DRM_DIR_NAME, minor);
+    switch (type) {
+    case DRM_NODE_PRIMARY:
+	    dev_name = DRM_DEV_NAME;
+	    break;
+    case DRM_NODE_CONTROL:
+	    dev_name = DRM_CONTROL_DEV_NAME;
+	    break;
+    case DRM_NODE_RENDER:
+	    dev_name = DRM_RENDER_DEV_NAME;
+	    break;
+    default:
+	    return -EINVAL;
+    };
+
+    sprintf(buf, dev_name, DRM_DIR_NAME, minor);
     if ((fd = open(buf, O_RDWR, 0)) >= 0)
 	return fd;
     return -errno;
@@ -445,7 +469,7 @@ int drmAvailable(void)
     int           retval = 0;
     int           fd;
 
-    if ((fd = drmOpenMinor(0, 1, DRM_NODE_RENDER)) < 0) {
+    if ((fd = drmOpenMinor(0, 1, DRM_NODE_PRIMARY)) < 0) {
 #ifdef __linux__
 	/* Try proc for backward Linux compatibility */
 	if (!access("/proc/dri/0", R_OK))
@@ -463,11 +487,56 @@ int drmAvailable(void)
     return retval;
 }
 
+static int drmGetMinorBase(int type)
+{
+    switch (type) {
+    case DRM_NODE_PRIMARY:
+        return 0;
+    case DRM_NODE_CONTROL:
+        return 64;
+    case DRM_NODE_RENDER:
+        return 128;
+    default:
+        return -1;
+    };
+}
+
+static int drmGetMinorType(int minor)
+{
+    int type = minor >> 6;
+
+    if (minor < 0)
+        return -1;
+
+    switch (type) {
+    case DRM_NODE_PRIMARY:
+    case DRM_NODE_CONTROL:
+    case DRM_NODE_RENDER:
+        return type;
+    default:
+        return -1;
+    }
+}
+
+static const char *drmGetMinorName(int type)
+{
+    switch (type) {
+    case DRM_NODE_PRIMARY:
+        return "card";
+    case DRM_NODE_CONTROL:
+        return "controlD";
+    case DRM_NODE_RENDER:
+        return "renderD";
+    default:
+        return NULL;
+    }
+}
 
 /**
  * Open the device by bus ID.
  *
  * \param busid bus ID.
+ * \param type device node type.
  *
  * \return a file descriptor on success, or a negative value on error.
  *
@@ -477,16 +546,20 @@ int drmAvailable(void)
  *
  * \sa drmOpenMinor() and drmGetBusid().
  */
-static int drmOpenByBusid(const char *busid)
+static int drmOpenByBusid(const char *busid, int type)
 {
     int        i, pci_domain_ok = 1;
     int        fd;
     const char *buf;
     drmSetVersion sv;
+    int        base = drmGetMinorBase(type);
+
+    if (base < 0)
+        return -1;
 
     drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid);
-    for (i = 0; i < DRM_MAX_MINOR; i++) {
-	fd = drmOpenMinor(i, 1, DRM_NODE_RENDER);
+    for (i = base; i < base + DRM_MAX_MINOR; i++) {
+	fd = drmOpenMinor(i, 1, type);
 	drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd);
 	if (fd >= 0) {
 	    /* We need to try for 1.4 first for proper PCI domain support
@@ -526,6 +599,7 @@ static int drmOpenByBusid(const char *bu
  * Open the device by name.
  *
  * \param name driver name.
+ * \param type the device node type.
  * 
  * \return a file descriptor on success, or a negative value on error.
  * 
@@ -536,19 +610,23 @@ static int drmOpenByBusid(const char *bu
  * 
  * \sa drmOpenMinor(), drmGetVersion() and drmGetBusid().
  */
-static int drmOpenByName(const char *name)
+static int drmOpenByName(const char *name, int type)
 {
     int           i;
     int           fd;
     drmVersionPtr version;
     char *        id;
+    int           base = drmGetMinorBase(type);
+
+    if (base < 0)
+        return -1;
 
     /*
      * Open the first minor number that matches the driver name and isn't
      * already in use.  If it's in use it will have a busid assigned already.
      */
-    for (i = 0; i < DRM_MAX_MINOR; i++) {
-	if ((fd = drmOpenMinor(i, 1, DRM_NODE_RENDER)) >= 0) {
+    for (i = base; i < base + DRM_MAX_MINOR; i++) {
+	if ((fd = drmOpenMinor(i, 1, type)) >= 0) {
 	    if ((version = drmGetVersion(fd))) {
 		if (!strcmp(version->name, name)) {
 		    drmFreeVersion(version);
@@ -590,9 +668,9 @@ static int drmOpenByName(const char *nam
 			for (devstring = ++pt; *pt && *pt != ' '; ++pt)
 			    ;
 			if (*pt) { /* Found busid */
-			    return drmOpenByBusid(++pt);
+			    return drmOpenByBusid(++pt, type);
 			} else { /* No busid */
-			    return drmOpenDevice(strtol(devstring, NULL, 0),i, DRM_NODE_RENDER);
+			    return drmOpenDevice(strtol(devstring, NULL, 0),i, type);
 			}
 		    }
 		}
@@ -622,8 +700,29 @@ static int drmOpenByName(const char *nam
  */
 int drmOpen(const char *name, const char *busid)
 {
+    return drmOpenWithType(name, busid, DRM_NODE_PRIMARY);
+}
+
+/**
+ * Open the DRM device with specified type.
+ *
+ * Looks up the specified name and bus ID, and opens the device found.  The
+ * entry in /dev/dri is created if necessary and if called by root.
+ *
+ * \param name driver name. Not referenced if bus ID is supplied.
+ * \param busid bus ID. Zero if not known.
+ * \param type the device node type to open, PRIMARY, CONTROL or RENDER
+ *
+ * \return a file descriptor on success, or a negative value on error.
+ *
+ * \internal
+ * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName()
+ * otherwise.
+ */
+int drmOpenWithType(const char *name, const char *busid, int type)
+{
     if (!drmAvailable() && name != NULL && drm_server_info) {
-	/* try to load the kernel */
+	/* try to load the kernel module */
 	if (!drm_server_info->load_module(name)) {
 	    drmMsg("[drm] failed to load kernel module \"%s\"\n", name);
 	    return -1;
@@ -631,13 +730,13 @@ int drmOpen(const char *name, const char
     }
 
     if (busid) {
-	int fd = drmOpenByBusid(busid);
+	int fd = drmOpenByBusid(busid, type);
 	if (fd >= 0)
 	    return fd;
     }
     
     if (name)
-	return drmOpenByName(name);
+	return drmOpenByName(name, type);
 
     return -1;
 }
@@ -647,6 +746,11 @@ int drmOpenControl(int minor)
     return drmOpenMinor(minor, 0, DRM_NODE_CONTROL);
 }
 
+int drmOpenRender(int minor)
+{
+    return drmOpenMinor(minor, 0, DRM_NODE_RENDER);
+}
+
 /**
  * Free the version information returned by drmGetVersion().
  *
@@ -731,12 +835,7 @@ drmVersionPtr drmGetVersion(int fd)
     drmVersionPtr retval;
     drm_version_t *version = drmMalloc(sizeof(*version));
 
-    version->name_len    = 0;
-    version->name        = NULL;
-    version->date_len    = 0;
-    version->date        = NULL;
-    version->desc_len    = 0;
-    version->desc        = NULL;
+    memclear(*version);
 
     if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) {
 	drmFreeKernelVersion(version);
@@ -804,9 +903,12 @@ drmVersionPtr drmGetLibVersion(int fd)
 
 int drmGetCap(int fd, uint64_t capability, uint64_t *value)
 {
-	struct drm_get_cap cap = { capability, 0 };
+	struct drm_get_cap cap;
 	int ret;
 
+	memclear(cap);
+	cap.capability = capability;
+
 	ret = drmIoctl(fd, DRM_IOCTL_GET_CAP, &cap);
 	if (ret)
 		return ret;
@@ -817,7 +919,11 @@ int drmGetCap(int fd, uint64_t capabilit
 
 int drmSetClientCap(int fd, uint64_t capability, uint64_t value)
 {
-	struct drm_set_client_cap cap  = { capability, value };
+	struct drm_set_client_cap cap;
+
+	memclear(cap);
+	cap.capability = capability;
+	cap.value = value;
 
 	return drmIoctl(fd, DRM_IOCTL_SET_CLIENT_CAP, &cap);
 }
@@ -852,8 +958,7 @@ char *drmGetBusid(int fd)
 {
     drm_unique_t u;
 
-    u.unique_len = 0;
-    u.unique     = NULL;
+    memclear(u);
 
     if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
 	return NULL;
@@ -882,6 +987,7 @@ int drmSetBusid(int fd, const char *busi
 {
     drm_unique_t u;
 
+    memclear(u);
     u.unique     = (char *)busid;
     u.unique_len = strlen(busid);
 
@@ -895,6 +1001,8 @@ int drmGetMagic(int fd, drm_magic_t * ma
 {
     drm_auth_t auth;
 
+    memclear(auth);
+
     *magic = 0;
     if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth))
 	return -errno;
@@ -906,6 +1014,7 @@ int drmAuthMagic(int fd, drm_magic_t mag
 {
     drm_auth_t auth;
 
+    memclear(auth);
     auth.magic = magic;
     if (drmIoctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth))
 	return -errno;
@@ -967,9 +1076,9 @@ int drmAddMap(int fd, drm_handle_t offse
 {
     drm_map_t map;
 
+    memclear(map);
     map.offset  = offset;
     map.size    = size;
-    map.handle  = 0;
     map.type    = type;
     map.flags   = flags;
     if (drmIoctl(fd, DRM_IOCTL_ADD_MAP, &map))
@@ -983,6 +1092,7 @@ int drmRmMap(int fd, drm_handle_t handle
 {
     drm_map_t map;
 
+    memclear(map);
     map.handle = (void *)(uintptr_t)handle;
 
     if(drmIoctl(fd, DRM_IOCTL_RM_MAP, &map))
@@ -1011,10 +1121,9 @@ int drmAddBufs(int fd, int count, int si
 {
     drm_buf_desc_t request;
 
+    memclear(request);
     request.count     = count;
     request.size      = size;
-    request.low_mark  = 0;
-    request.high_mark = 0;
     request.flags     = flags;
     request.agp_start = agp_offset;
 
@@ -1028,8 +1137,7 @@ int drmMarkBufs(int fd, double low, doub
     drm_buf_info_t info;
     int            i;
 
-    info.count = 0;
-    info.list  = NULL;
+    memclear(info);
 
     if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info))
 	return -EINVAL;
@@ -1079,6 +1187,7 @@ int drmFreeBufs(int fd, int count, int *
 {
     drm_buf_free_t request;
 
+    memclear(request);
     request.count = count;
     request.list  = list;
     if (drmIoctl(fd, DRM_IOCTL_FREE_BUFS, &request))
@@ -1167,8 +1276,7 @@ drmBufInfoPtr drmGetBufInfo(int fd)
     drmBufInfoPtr  retval;
     int            i;
 
-    info.count = 0;
-    info.list  = NULL;
+    memclear(info);
 
     if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info))
 	return NULL;
@@ -1218,9 +1326,7 @@ drmBufMapPtr drmMapBufs(int fd)
     drmBufMapPtr  retval;
     int           i;
 
-    bufs.count = 0;
-    bufs.list  = NULL;
-    bufs.virtual = NULL;
+    memclear(bufs);
     if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs))
 	return NULL;
 
@@ -1336,6 +1442,7 @@ int drmGetLock(int fd, drm_context_t con
 {
     drm_lock_t lock;
 
+    memclear(lock);
     lock.context = context;
     lock.flags   = 0;
     if (flags & DRM_LOCK_READY)      lock.flags |= _DRM_LOCK_READY;
@@ -1366,8 +1473,8 @@ int drmUnlock(int fd, drm_context_t cont
 {
     drm_lock_t lock;
 
+    memclear(lock);
     lock.context = context;
-    lock.flags   = 0;
     return drmIoctl(fd, DRM_IOCTL_UNLOCK, &lock);
 }
 
@@ -1378,8 +1485,7 @@ drm_context_t *drmGetReservedContextList
     drm_context_t * retval;
     int           i;
 
-    res.count    = 0;
-    res.contexts = NULL;
+    memclear(res);
     if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res))
 	return NULL;
 
@@ -1432,7 +1538,7 @@ int drmCreateContext(int fd, drm_context
 {
     drm_ctx_t ctx;
 
-    ctx.flags = 0;	/* Modified with functions below */
+    memclear(ctx);
     if (drmIoctl(fd, DRM_IOCTL_ADD_CTX, &ctx))
 	return -errno;
     *handle = ctx.handle;
@@ -1443,6 +1549,7 @@ int drmSwitchToContext(int fd, drm_conte
 {
     drm_ctx_t ctx;
 
+    memclear(ctx);
     ctx.handle = context;
     if (drmIoctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx))
 	return -errno;
@@ -1459,8 +1566,8 @@ int drmSetContextFlags(int fd, drm_conte
      * X server (which promises to maintain hardware context), or in the
      * client-side library when buffers are swapped on behalf of two threads.
      */
+    memclear(ctx);
     ctx.handle = context;
-    ctx.flags  = 0;
     if (flags & DRM_CONTEXT_PRESERVED)
 	ctx.flags |= _DRM_CONTEXT_PRESERVED;
     if (flags & DRM_CONTEXT_2DONLY)
@@ -1475,6 +1582,7 @@ int drmGetContextFlags(int fd, drm_conte
 {
     drm_ctx_t ctx;
 
+    memclear(ctx);
     ctx.handle = context;
     if (drmIoctl(fd, DRM_IOCTL_GET_CTX, &ctx))
 	return -errno;
@@ -1506,6 +1614,8 @@ int drmGetContextFlags(int fd, drm_conte
 int drmDestroyContext(int fd, drm_context_t handle)
 {
     drm_ctx_t ctx;
+
+    memclear(ctx);
     ctx.handle = handle;
     if (drmIoctl(fd, DRM_IOCTL_RM_CTX, &ctx))
 	return -errno;
@@ -1515,6 +1625,8 @@ int drmDestroyContext(int fd, drm_contex
 int drmCreateDrawable(int fd, drm_drawable_t *handle)
 {
     drm_draw_t draw;
+
+    memclear(draw);
     if (drmIoctl(fd, DRM_IOCTL_ADD_DRAW, &draw))
 	return -errno;
     *handle = draw.handle;
@@ -1524,6 +1636,8 @@ int drmCreateDrawable(int fd, drm_drawab
 int drmDestroyDrawable(int fd, drm_drawable_t handle)
 {
     drm_draw_t draw;
+
+    memclear(draw);
     draw.handle = handle;
     if (drmIoctl(fd, DRM_IOCTL_RM_DRAW, &draw))
 	return -errno;
@@ -1536,6 +1650,7 @@ int drmUpdateDrawableInfo(int fd, drm_dr
 {
     drm_update_draw_t update;
 
+    memclear(update);
     update.handle = handle;
     update.type = type;
     update.num = num;
@@ -1601,6 +1716,7 @@ int drmAgpEnable(int fd, unsigned long m
 {
     drm_agp_mode_t m;
 
+    memclear(m);
     m.mode = mode;
     if (drmIoctl(fd, DRM_IOCTL_AGP_ENABLE, &m))
 	return -errno;
@@ -1629,9 +1745,9 @@ int drmAgpAlloc(int fd, unsigned long si
 {
     drm_agp_buffer_t b;
 
+    memclear(b);
     *handle = DRM_AGP_NO_HANDLE;
     b.size   = size;
-    b.handle = 0;
     b.type   = type;
     if (drmIoctl(fd, DRM_IOCTL_AGP_ALLOC, &b))
 	return -errno;
@@ -1658,7 +1774,7 @@ int drmAgpFree(int fd, drm_handle_t hand
 {
     drm_agp_buffer_t b;
 
-    b.size   = 0;
+    memclear(b);
     b.handle = handle;
     if (drmIoctl(fd, DRM_IOCTL_AGP_FREE, &b))
 	return -errno;
@@ -1683,6 +1799,7 @@ int drmAgpBind(int fd, drm_handle_t hand
 {
     drm_agp_binding_t b;
 
+    memclear(b);
     b.handle = handle;
     b.offset = offset;
     if (drmIoctl(fd, DRM_IOCTL_AGP_BIND, &b))
@@ -1707,8 +1824,8 @@ int drmAgpUnbind(int fd, drm_handle_t ha
 {
     drm_agp_binding_t b;
 
+    memclear(b);
     b.handle = handle;
-    b.offset = 0;
     if (drmIoctl(fd, DRM_IOCTL_AGP_UNBIND, &b))
 	return -errno;
     return 0;
@@ -1730,6 +1847,8 @@ int drmAgpVersionMajor(int fd)
 {
     drm_agp_info_t i;
 
+    memclear(i);
+
     if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
 	return -errno;
     return i.agp_version_major;
@@ -1751,6 +1870,8 @@ int drmAgpVersionMinor(int fd)
 {
     drm_agp_info_t i;
 
+    memclear(i);
+
     if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
 	return -errno;
     return i.agp_version_minor;
@@ -1772,6 +1893,8 @@ unsigned long drmAgpGetMode(int fd)
 {
     drm_agp_info_t i;
 
+    memclear(i);
+
     if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
 	return 0;
     return i.mode;
@@ -1793,6 +1916,8 @@ unsigned long drmAgpBase(int fd)
 {
     drm_agp_info_t i;
 
+    memclear(i);
+
     if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
 	return 0;
     return i.aperture_base;
@@ -1814,6 +1939,8 @@ unsigned long drmAgpSize(int fd)
 {
     drm_agp_info_t i;
 
+    memclear(i);
+
     if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
 	return 0;
     return i.aperture_size;
@@ -1835,6 +1962,8 @@ unsigned long drmAgpMemoryUsed(int fd)
 {
     drm_agp_info_t i;
 
+    memclear(i);
+
     if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
 	return 0;
     return i.memory_used;
@@ -1856,6 +1985,8 @@ unsigned long drmAgpMemoryAvail(int fd)
 {
     drm_agp_info_t i;
 
+    memclear(i);
+
     if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
 	return 0;
     return i.memory_allowed;
@@ -1877,6 +2008,8 @@ unsigned int drmAgpVendorId(int fd)
 {
     drm_agp_info_t i;
 
+    memclear(i);
+
     if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
 	return 0;
     return i.id_vendor;
@@ -1898,6 +2031,8 @@ unsigned int drmAgpDeviceId(int fd)
 {
     drm_agp_info_t i;
 
+    memclear(i);
+
     if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
 	return 0;
     return i.id_device;
@@ -1907,9 +2042,10 @@ int drmScatterGatherAlloc(int fd, unsign
 {
     drm_scatter_gather_t sg;
 
+    memclear(sg);
+
     *handle = 0;
     sg.size   = size;
-    sg.handle = 0;
     if (drmIoctl(fd, DRM_IOCTL_SG_ALLOC, &sg))
 	return -errno;
     *handle = sg.handle;
@@ -1920,7 +2056,7 @@ int drmScatterGatherFree(int fd, drm_han
 {
     drm_scatter_gather_t sg;
 
-    sg.size   = 0;
+    memclear(sg);
     sg.handle = handle;
     if (drmIoctl(fd, DRM_IOCTL_SG_FREE, &sg))
 	return -errno;
@@ -2011,6 +2147,7 @@ int drmCtlInstHandler(int fd, int irq)
 {
     drm_control_t ctl;
 
+    memclear(ctl);
     ctl.func  = DRM_INST_HANDLER;
     ctl.irq   = irq;
     if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl))
@@ -2034,6 +2171,7 @@ int drmCtlUninstHandler(int fd)
 {
     drm_control_t ctl;
 
+    memclear(ctl);
     ctl.func  = DRM_UNINST_HANDLER;
     ctl.irq   = 0;
     if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl))
@@ -2045,8 +2183,8 @@ int drmFinish(int fd, int context, drmLo
 {
     drm_lock_t lock;
 
+    memclear(lock);
     lock.context = context;
-    lock.flags   = 0;
     if (flags & DRM_LOCK_READY)      lock.flags |= _DRM_LOCK_READY;
     if (flags & DRM_LOCK_QUIESCENT)  lock.flags |= _DRM_LOCK_QUIESCENT;
     if (flags & DRM_LOCK_FLUSH)      lock.flags |= _DRM_LOCK_FLUSH;
@@ -2076,6 +2214,7 @@ int drmGetInterruptFromBusID(int fd, int
 {
     drm_irq_busid_t p;
 
+    memclear(p);
     p.busnum  = busnum;
     p.devnum  = devnum;
     p.funcnum = funcnum;
@@ -2118,6 +2257,7 @@ int drmAddContextPrivateMapping(int fd, 
 {
     drm_ctx_priv_map_t map;
 
+    memclear(map);
     map.ctx_id = ctx_id;
     map.handle = (void *)(uintptr_t)handle;
 
@@ -2131,6 +2271,7 @@ int drmGetContextPrivateMapping(int fd, 
 {
     drm_ctx_priv_map_t map;
 
+    memclear(map);
     map.ctx_id = ctx_id;
 
     if (drmIoctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map))
@@ -2147,6 +2288,7 @@ int drmGetMap(int fd, int idx, drm_handl
 {
     drm_map_t map;
 
+    memclear(map);
     map.offset = idx;
     if (drmIoctl(fd, DRM_IOCTL_GET_MAP, &map))
 	return -errno;
@@ -2164,6 +2306,7 @@ int drmGetClient(int fd, int idx, int *a
 {
     drm_client_t client;
 
+    memclear(client);
     client.idx = idx;
     if (drmIoctl(fd, DRM_IOCTL_GET_CLIENT, &client))
 	return -errno;
@@ -2178,8 +2321,9 @@ int drmGetClient(int fd, int idx, int *a
 int drmGetStats(int fd, drmStatsT *stats)
 {
     drm_stats_t s;
-    int         i;
+    unsigned    i;
 
+    memclear(s);
     if (drmIoctl(fd, DRM_IOCTL_GET_STATS, &s))
 	return -errno;
 
@@ -2317,6 +2461,7 @@ int drmSetInterfaceVersion(int fd, drmSe
     int retcode = 0;
     drm_set_version_t sv;
 
+    memclear(sv);
     sv.drm_di_major = version->drm_di_major;
     sv.drm_di_minor = version->drm_di_minor;
     sv.drm_dd_major = version->drm_dd_major;
@@ -2348,12 +2493,11 @@ int drmSetInterfaceVersion(int fd, drmSe
  */
 int drmCommandNone(int fd, unsigned long drmCommandIndex)
 {
-    void *data = NULL; /* dummy */
     unsigned long request;
 
     request = DRM_IO( DRM_COMMAND_BASE + drmCommandIndex);
 
-    if (drmIoctl(fd, request, data)) {
+    if (drmIoctl(fd, request, NULL)) {
 	return -errno;
     }
     return 0;
@@ -2450,6 +2594,7 @@ static struct {
     char *BusID;
     int fd;
     int refcount;
+    int type;
 } connection[DRM_MAX_FDS];
 
 static int nr_fds = 0;
@@ -2458,23 +2603,30 @@ int drmOpenOnce(void *unused, 
 		const char *BusID,
 		int *newlyopened)
 {
+    return drmOpenOnceWithType(BusID, newlyopened, DRM_NODE_PRIMARY);
+}
+
+int drmOpenOnceWithType(const char *BusID, int *newlyopened, int type)
+{
     int i;
     int fd;
    
     for (i = 0; i < nr_fds; i++)
-	if (strcmp(BusID, connection[i].BusID) == 0) {
+	if ((strcmp(BusID, connection[i].BusID) == 0) &&
+	    (connection[i].type == type)) {
 	    connection[i].refcount++;
 	    *newlyopened = 0;
 	    return connection[i].fd;
 	}
 
-    fd = drmOpen(unused, BusID);
+    fd = drmOpenWithType(NULL, BusID, type);
     if (fd <= 0 || nr_fds == DRM_MAX_FDS)
 	return fd;
    
     connection[nr_fds].BusID = strdup(BusID);
     connection[nr_fds].fd = fd;
     connection[nr_fds].refcount = 1;
+    connection[nr_fds].type = type;
     *newlyopened = 1;
 
     if (0)
@@ -2508,12 +2660,12 @@ void drmCloseOnce(int fd)
 
 int drmSetMaster(int fd)
 {
-	return ioctl(fd, DRM_IOCTL_SET_MASTER, 0);
+	return drmIoctl(fd, DRM_IOCTL_SET_MASTER, NULL);
 }
 
 int drmDropMaster(int fd)
 {
-	return ioctl(fd, DRM_IOCTL_DROP_MASTER, 0);
+	return drmIoctl(fd, DRM_IOCTL_DROP_MASTER, NULL);
 }
 
 char *drmGetDeviceNameFromFd(int fd)
@@ -2542,11 +2694,35 @@ char *drmGetDeviceNameFromFd(int fd)
 	return strdup(name);
 }
 
+int drmGetNodeTypeFromFd(int fd)
+{
+	struct stat sbuf;
+	int maj, min, type;
+
+	if (fstat(fd, &sbuf))
+		return -1;
+
+	maj = major(sbuf.st_rdev);
+	min = minor(sbuf.st_rdev);
+
+	if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	type = drmGetMinorType(min);
+	if (type == -1)
+		errno = ENODEV;
+	return type;
+}
+
 int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd)
 {
 	struct drm_prime_handle args;
 	int ret;
 
+	memclear(args);
+	args.fd = -1;
 	args.handle = handle;
 	args.flags = flags;
 	ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args);
@@ -2562,8 +2738,8 @@ int drmPrimeFDToHandle(int fd, int prime
 	struct drm_prime_handle args;
 	int ret;
 
+	memclear(args);
 	args.fd = prime_fd;
-	args.flags = 0;
 	ret = drmIoctl(fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &args);
 	if (ret)
 		return ret;
@@ -2571,3 +2747,72 @@ int drmPrimeFDToHandle(int fd, int prime
 	*handle = args.handle;
 	return 0;
 }
+
+static char *drmGetMinorNameForFD(int fd, int type)
+{
+#ifdef __linux__
+	DIR *sysdir;
+	struct dirent *pent, *ent;
+	struct stat sbuf;
+	const char *name = drmGetMinorName(type);
+	int len;
+	char dev_name[64], buf[64];
+	long name_max;
+	int maj, min;
+
+	if (!name)
+		return NULL;
+
+	len = strlen(name);
+
+	if (fstat(fd, &sbuf))
+		return NULL;
+
+	maj = major(sbuf.st_rdev);
+	min = minor(sbuf.st_rdev);
+
+	if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
+		return NULL;
+
+	snprintf(buf, sizeof(buf), "/sys/dev/char/%d:%d/device/drm", maj, min);
+
+	sysdir = opendir(buf);
+	if (!sysdir)
+		return NULL;
+
+	name_max = fpathconf(dirfd(sysdir), _PC_NAME_MAX);
+	if (name_max == -1)
+		goto out_close_dir;
+
+	pent = malloc(offsetof(struct dirent, d_name) + name_max + 1);
+	if (pent == NULL)
+		 goto out_close_dir;
+
+	while (readdir_r(sysdir, pent, &ent) == 0 && ent != NULL) {
+		if (strncmp(ent->d_name, name, len) == 0) {
+			free(pent);
+			closedir(sysdir);
+
+			snprintf(dev_name, sizeof(dev_name), DRM_DIR_NAME "/%s",
+				 ent->d_name);
+			return strdup(dev_name);
+		}
+	}
+
+	free(pent);
+
+out_close_dir:
+	closedir(sysdir);
+#endif
+	return NULL;
+}
+
+char *drmGetPrimaryDeviceNameFromFd(int fd)
+{
+	return drmGetMinorNameForFD(fd, DRM_NODE_PRIMARY);
+}
+
+char *drmGetRenderDeviceNameFromFd(int fd)
+{
+	return drmGetMinorNameForFD(fd, DRM_NODE_RENDER);
+}

Index: xsrc/external/mit/libdrm/dist/xf86drm.h
diff -u xsrc/external/mit/libdrm/dist/xf86drm.h:1.4 xsrc/external/mit/libdrm/dist/xf86drm.h:1.5
--- xsrc/external/mit/libdrm/dist/xf86drm.h:1.4	Fri Jul 11 19:57:33 2014
+++ xsrc/external/mit/libdrm/dist/xf86drm.h	Mon Jul 20 02:27:05 2015
@@ -83,6 +83,7 @@ extern "C" {
 #define DRM_DIR_NAME  "/dev/dri"
 #define DRM_DEV_NAME  "%s/card%d"
 #define DRM_CONTROL_DEV_NAME  "%s/controlD%d"
+#define DRM_RENDER_DEV_NAME  "%s/renderD%d"
 #define DRM_PROC_NAME "/proc/dri/" /* For backward Linux compatibility */
 
 #define DRM_ERR_NO_DEVICE  (-1001)
@@ -560,7 +561,15 @@ do {	register unsigned int __old __asm("
 /* General user-level programmer's API: unprivileged */
 extern int           drmAvailable(void);
 extern int           drmOpen(const char *name, const char *busid);
-extern int drmOpenControl(int minor);
+
+#define DRM_NODE_PRIMARY 0
+#define DRM_NODE_CONTROL 1
+#define DRM_NODE_RENDER  2
+extern int           drmOpenWithType(const char *name, const char *busid,
+                                     int type);
+
+extern int           drmOpenControl(int minor);
+extern int           drmOpenRender(int minor);
 extern int           drmClose(int fd);
 extern drmVersionPtr drmGetVersion(int fd);
 extern drmVersionPtr drmGetLibVersion(int fd);
@@ -712,6 +721,7 @@ extern int  drmSLLookupNeighbors(void *l
 				 unsigned long *next_key, void **next_value);
 
 extern int drmOpenOnce(void *unused, const char *BusID, int *newlyopened);
+extern int drmOpenOnceWithType(const char *BusID, int *newlyopened, int type);
 extern void drmCloseOnce(int fd);
 extern void drmMsg(const char *format, ...) DRM_PRINTFLIKE(1, 2);
 
@@ -743,10 +753,14 @@ typedef struct _drmEventContext {
 extern int drmHandleEvent(int fd, drmEventContextPtr evctx);
 
 extern char *drmGetDeviceNameFromFd(int fd);
+extern int drmGetNodeTypeFromFd(int fd);
 
 extern int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd);
 extern int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle);
 
+extern char *drmGetPrimaryDeviceNameFromFd(int fd);
+extern char *drmGetRenderDeviceNameFromFd(int fd);
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif
Index: xsrc/external/mit/libdrm/dist/xf86drmMode.h
diff -u xsrc/external/mit/libdrm/dist/xf86drmMode.h:1.4 xsrc/external/mit/libdrm/dist/xf86drmMode.h:1.5
--- xsrc/external/mit/libdrm/dist/xf86drmMode.h:1.4	Fri Jan 23 08:25:08 2015
+++ xsrc/external/mit/libdrm/dist/xf86drmMode.h	Mon Jul 20 02:27:05 2015
@@ -240,7 +240,7 @@ typedef struct _drmModeProperty {
 	uint32_t *blob_ids; /* store the blob IDs */
 } drmModePropertyRes, *drmModePropertyPtr;
 
-static inline int drm_property_type_is(drmModePropertyPtr property,
+static __inline int drm_property_type_is(drmModePropertyPtr property,
 		uint32_t type)
 {
 	/* instanceof for props.. handles extended type vs original types: */
@@ -422,10 +422,23 @@ drmModeEncoderPtr drmModeGetEncoder(int 
  */
 
 /**
- * Retrive information about the connector connectorId.
+ * Retrieve all information about the connector connectorId. This will do a
+ * forced probe on the connector to retrieve remote information such as EDIDs
+ * from the display device.
  */
 extern drmModeConnectorPtr drmModeGetConnector(int fd,
-		uint32_t connectorId);
+					       uint32_t connectorId);
+
+/**
+ * Retrieve current information, i.e the currently active mode and encoder,
+ * about the connector connectorId. This will not do any probing on the
+ * connector or remote device, and only reports what is currently known.
+ * For the complete set of modes and encoders associated with the connector
+ * use drmModeGetConnector() which will do a probe to determine any display
+ * link changes first.
+ */
+extern drmModeConnectorPtr drmModeGetConnectorCurrent(int fd,
+						      uint32_t connector_id);
 
 /**
  * Attaches the given mode to an connector.
@@ -471,6 +484,30 @@ extern int drmModeObjectSetProperty(int 
 				    uint32_t object_type, uint32_t property_id,
 				    uint64_t value);
 
+
+typedef struct _drmModeAtomicReq drmModeAtomicReq, *drmModeAtomicReqPtr;
+
+extern drmModeAtomicReqPtr drmModeAtomicAlloc(void);
+extern drmModeAtomicReqPtr drmModeAtomicDuplicate(drmModeAtomicReqPtr req);
+extern int drmModeAtomicMerge(drmModeAtomicReqPtr base,
+			      drmModeAtomicReqPtr augment);
+extern void drmModeAtomicFree(drmModeAtomicReqPtr req);
+extern int drmModeAtomicGetCursor(drmModeAtomicReqPtr req);
+extern void drmModeAtomicSetCursor(drmModeAtomicReqPtr req, int cursor);
+extern int drmModeAtomicAddProperty(drmModeAtomicReqPtr req,
+				    uint32_t object_id,
+				    uint32_t property_id,
+				    uint64_t value);
+extern int drmModeAtomicCommit(int fd,
+			       drmModeAtomicReqPtr req,
+			       uint32_t flags,
+			       void *user_data);
+
+extern int drmModeCreatePropertyBlob(int fd, const void *data, size_t size,
+				     uint32_t *id);
+extern int drmModeDestroyPropertyBlob(int fd, uint32_t id);
+
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif

Index: xsrc/external/mit/libdrm/dist/xf86drmMode.c
diff -u xsrc/external/mit/libdrm/dist/xf86drmMode.c:1.8 xsrc/external/mit/libdrm/dist/xf86drmMode.c:1.9
--- xsrc/external/mit/libdrm/dist/xf86drmMode.c:1.8	Sat Dec 13 21:41:19 2014
+++ xsrc/external/mit/libdrm/dist/xf86drmMode.c	Mon Jul 20 02:27:05 2015
@@ -37,14 +37,18 @@
  * TODO the types we are after are defined in diffrent headers on diffrent
  * platforms find which headers to include to get uint32_t
  */
-#include <stdint.h>
-#include <sys/ioctl.h>
-#include <stdio.h>
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdbool.h>
+
 #include "xf86drmMode.h"
 #include "xf86drm.h"
 #include <drm.h>
@@ -53,15 +57,7 @@
 #include <unistd.h>
 #include <errno.h>
 
-#ifdef HAVE_VALGRIND
-#include <valgrind.h>
-#include <memcheck.h>
-#define VG(x) x
-#else
-#define VG(x)
-#endif
-
-#define VG_CLEAR(s) VG(memset(&s, 0, sizeof(s)))
+#define memclear(s) memset(&s, 0, sizeof(s))
 
 #define U642VOID(x) ((void *)(unsigned long)(x))
 #define VOID2U64(x) ((uint64_t)(unsigned long)(x))
@@ -76,7 +72,7 @@ static inline int DRM_IOCTL(int fd, unsi
  * Util functions
  */
 
-void* drmAllocCpy(void *array, int count, int entry_size)
+static void* drmAllocCpy(char *array, int count, int entry_size)
 {
 	char *r;
 	int i;
@@ -164,7 +160,7 @@ drmModeResPtr drmModeGetResources(int fd
 	drmModeResPtr r = 0;
 
 retry:
-	memset(&res, 0, sizeof(struct drm_mode_card_res));
+	memclear(res);
 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res))
 		return 0;
 
@@ -259,7 +255,7 @@ int drmModeAddFB(int fd, uint32_t width,
 	struct drm_mode_fb_cmd f;
 	int ret;
 
-	VG_CLEAR(f);
+	memclear(f);
 	f.width  = width;
 	f.height = height;
 	f.pitch  = pitch;
@@ -282,6 +278,7 @@ int drmModeAddFB2(int fd, uint32_t width
 	struct drm_mode_fb_cmd2 f;
 	int ret;
 
+	memclear(f);
 	f.width  = width;
 	f.height = height;
 	f.pixel_format = pixel_format;
@@ -300,8 +297,6 @@ int drmModeAddFB2(int fd, uint32_t width
 int drmModeRmFB(int fd, uint32_t bufferId)
 {
 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_RMFB, &bufferId);
-
-
 }
 
 drmModeFBPtr drmModeGetFB(int fd, uint32_t buf)
@@ -309,6 +304,7 @@ drmModeFBPtr drmModeGetFB(int fd, uint32
 	struct drm_mode_fb_cmd info;
 	drmModeFBPtr r;
 
+	memclear(info);
 	info.fb_id = buf;
 
 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETFB, &info))
@@ -331,8 +327,9 @@ drmModeFBPtr drmModeGetFB(int fd, uint32
 int drmModeDirtyFB(int fd, uint32_t bufferId,
 		   drmModeClipPtr clips, uint32_t num_clips)
 {
-	struct drm_mode_fb_dirty_cmd dirty = { 0 };
+	struct drm_mode_fb_dirty_cmd dirty;
 
+	memclear(dirty);
 	dirty.fb_id = bufferId;
 	dirty.clips_ptr = VOID2U64(clips);
 	dirty.num_clips = num_clips;
@@ -350,7 +347,7 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, ui
 	struct drm_mode_crtc crtc;
 	drmModeCrtcPtr r;
 
-	VG_CLEAR(crtc);
+	memclear(crtc);
 	crtc.crtc_id = crtcId;
 
 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETCRTC, &crtc))
@@ -384,7 +381,7 @@ int drmModeSetCrtc(int fd, uint32_t crtc
 {
 	struct drm_mode_crtc crtc;
 
-	VG_CLEAR(crtc);
+	memclear(crtc);
 	crtc.x             = x;
 	crtc.y             = y;
 	crtc.crtc_id       = crtcId;
@@ -394,8 +391,7 @@ int drmModeSetCrtc(int fd, uint32_t crtc
 	if (mode) {
 	  memcpy(&crtc.mode, mode, sizeof(struct drm_mode_modeinfo));
 	  crtc.mode_valid = 1;
-	} else
-	  crtc.mode_valid = 0;
+	}
 
 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETCRTC, &crtc);
 }
@@ -408,6 +404,7 @@ int drmModeSetCursor(int fd, uint32_t cr
 {
 	struct drm_mode_cursor arg;
 
+	memclear(arg);
 	arg.flags = DRM_MODE_CURSOR_BO;
 	arg.crtc_id = crtcId;
 	arg.width = width;
@@ -421,6 +418,7 @@ int drmModeSetCursor2(int fd, uint32_t c
 {
 	struct drm_mode_cursor2 arg;
 
+	memclear(arg);
 	arg.flags = DRM_MODE_CURSOR_BO;
 	arg.crtc_id = crtcId;
 	arg.width = width;
@@ -436,6 +434,7 @@ int drmModeMoveCursor(int fd, uint32_t c
 {
 	struct drm_mode_cursor arg;
 
+	memclear(arg);
 	arg.flags = DRM_MODE_CURSOR_MOVE;
 	arg.crtc_id = crtcId;
 	arg.x = x;
@@ -452,11 +451,8 @@ drmModeEncoderPtr drmModeGetEncoder(int 
 	struct drm_mode_get_encoder enc;
 	drmModeEncoderPtr r = NULL;
 
+	memclear(enc);
 	enc.encoder_id = encoder_id;
-	enc.crtc_id = 0;
-	enc.encoder_type = 0;
-	enc.possible_crtcs = 0;
-	enc.possible_clones = 0;
 
 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETENCODER, &enc))
 		return 0;
@@ -476,19 +472,23 @@ drmModeEncoderPtr drmModeGetEncoder(int 
 /*
  * Connector manipulation
  */
-
-drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id)
+static drmModeConnectorPtr
+_drmModeGetConnector(int fd, uint32_t connector_id, int probe)
 {
 	struct drm_mode_get_connector conn, counts;
 	drmModeConnectorPtr r = NULL;
 
-retry:
-	memset(&conn, 0, sizeof(struct drm_mode_get_connector));
+	memclear(conn);
 	conn.connector_id = connector_id;
+	if (!probe) {
+		conn.count_modes = 1;
+		conn.modes_ptr = VOID2U64(drmMalloc(sizeof(struct drm_mode_modeinfo)));
+	}
 
 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn))
 		return 0;
 
+retry:
 	counts = conn;
 
 	if (conn.count_props) {
@@ -504,6 +504,9 @@ retry:
 		conn.modes_ptr = VOID2U64(drmMalloc(conn.count_modes*sizeof(struct drm_mode_modeinfo)));
 		if (!conn.modes_ptr)
 			goto err_allocs;
+	} else {
+		conn.count_modes = 1;
+		conn.modes_ptr = VOID2U64(drmMalloc(sizeof(struct drm_mode_modeinfo)));
 	}
 
 	if (conn.count_encoders) {
@@ -572,10 +575,21 @@ err_allocs:
 	return r;
 }
 
+drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id)
+{
+	return _drmModeGetConnector(fd, connector_id, 1);
+}
+
+drmModeConnectorPtr drmModeGetConnectorCurrent(int fd, uint32_t connector_id)
+{
+	return _drmModeGetConnector(fd, connector_id, 0);
+}
+
 int drmModeAttachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info)
 {
 	struct drm_mode_mode_cmd res;
 
+	memclear(res);
 	memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo));
 	res.connector_id = connector_id;
 
@@ -586,6 +600,7 @@ int drmModeDetachMode(int fd, uint32_t c
 {
 	struct drm_mode_mode_cmd res;
 
+	memclear(res);
 	memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo));
 	res.connector_id = connector_id;
 
@@ -598,13 +613,8 @@ drmModePropertyPtr drmModeGetProperty(in
 	struct drm_mode_get_property prop;
 	drmModePropertyPtr r;
 
-	VG_CLEAR(prop);
+	memclear(prop);
 	prop.prop_id = property_id;
-	prop.count_enum_blobs = 0;
-	prop.count_values = 0;
-	prop.flags = 0;
-	prop.enum_blob_ptr = 0;
-	prop.values_ptr = 0;
 
 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop))
 		return 0;
@@ -667,8 +677,7 @@ drmModePropertyBlobPtr drmModeGetPropert
 	struct drm_mode_get_blob blob;
 	drmModePropertyBlobPtr r;
 
-	blob.length = 0;
-	blob.data = 0;
+	memclear(blob);
 	blob.blob_id = blob_id;
 
 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
@@ -708,6 +717,7 @@ int drmModeConnectorSetProperty(int fd, 
 {
 	struct drm_mode_connector_set_property osp;
 
+	memclear(osp);
 	osp.connector_id = connector_id;
 	osp.prop_id = property_id;
 	osp.value = value;
@@ -831,6 +841,7 @@ int drmModeCrtcGetGamma(int fd, uint32_t
 {
 	struct drm_mode_crtc_lut l;
 
+	memclear(l);
 	l.crtc_id = crtc_id;
 	l.gamma_size = size;
 	l.red = VOID2U64(red);
@@ -845,6 +856,7 @@ int drmModeCrtcSetGamma(int fd, uint32_t
 {
 	struct drm_mode_crtc_lut l;
 
+	memclear(l);
 	l.crtc_id = crtc_id;
 	l.gamma_size = size;
 	l.red = VOID2U64(red);
@@ -867,7 +879,7 @@ int drmHandleEvent(int fd, drmEventConte
 	len = read(fd, buffer, sizeof buffer);
 	if (len == 0)
 		return 0;
-	if (len < sizeof *e)
+	if (len < (int)sizeof *e)
 		return -1;
 
 	i = 0;
@@ -910,11 +922,11 @@ int drmModePageFlip(int fd, uint32_t crt
 {
 	struct drm_mode_crtc_page_flip flip;
 
+	memclear(flip);
 	flip.fb_id = fb_id;
 	flip.crtc_id = crtc_id;
 	flip.user_data = VOID2U64(user_data);
 	flip.flags = flags;
-	flip.reserved = 0;
 
 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip);
 }
@@ -929,6 +941,7 @@ int drmModeSetPlane(int fd, uint32_t pla
 {
 	struct drm_mode_set_plane s;
 
+	memclear(s);
 	s.plane_id = plane_id;
 	s.crtc_id = crtc_id;
 	s.fb_id = fb_id;
@@ -952,7 +965,7 @@ drmModePlanePtr drmModeGetPlane(int fd, 
 	drmModePlanePtr r = 0;
 
 retry:
-	memset(&ovr, 0, sizeof(struct drm_mode_get_plane));
+	memclear(ovr);
 	ovr.plane_id = plane_id;
 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANE, &ovr))
 		return 0;
@@ -1012,7 +1025,7 @@ drmModePlaneResPtr drmModeGetPlaneResour
 	drmModePlaneResPtr r = 0;
 
 retry:
-	memset(&res, 0, sizeof(struct drm_mode_get_plane_res));
+	memclear(res);
 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &res))
 		return 0;
 
@@ -1069,7 +1082,7 @@ drmModeObjectPropertiesPtr drmModeObject
 	uint32_t count;
 
 retry:
-	memset(&properties, 0, sizeof(struct drm_mode_obj_get_properties));
+	memclear(properties);
 	properties.obj_id = object_id;
 	properties.obj_type = object_type;
 
@@ -1135,6 +1148,7 @@ int drmModeObjectSetProperty(int fd, uin
 {
 	struct drm_mode_obj_set_property prop;
 
+	memclear(prop);
 	prop.value = value;
 	prop.prop_id = property_id;
 	prop.obj_id = object_id;
@@ -1142,3 +1156,274 @@ int drmModeObjectSetProperty(int fd, uin
 
 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_OBJ_SETPROPERTY, &prop);
 }
+
+typedef struct _drmModeAtomicReqItem drmModeAtomicReqItem, *drmModeAtomicReqItemPtr;
+
+struct _drmModeAtomicReqItem {
+	uint32_t object_id;
+	uint32_t property_id;
+	uint64_t value;
+};
+
+struct _drmModeAtomicReq {
+	uint32_t cursor;
+	uint32_t size_items;
+	drmModeAtomicReqItemPtr items;
+};
+
+drmModeAtomicReqPtr drmModeAtomicAlloc(void)
+{
+	drmModeAtomicReqPtr req;
+
+	req = drmMalloc(sizeof *req);
+	if (!req)
+		return NULL;
+
+	req->items = NULL;
+	req->cursor = 0;
+	req->size_items = 0;
+
+	return req;
+}
+
+drmModeAtomicReqPtr drmModeAtomicDuplicate(drmModeAtomicReqPtr old)
+{
+	drmModeAtomicReqPtr new;
+
+	new = drmMalloc(sizeof *new);
+	if (!new)
+		return NULL;
+
+	new->cursor = old->cursor;
+	new->size_items = old->size_items;
+
+	if (old->size_items) {
+		new->items = drmMalloc(old->size_items * sizeof(*new->items));
+		if (!new->items) {
+			free(new);
+			return NULL;
+		}
+		memcpy(new->items, old->items,
+		       old->size_items * sizeof(*new->items));
+	} else {
+		new->items = NULL;
+	}
+
+	return new;
+}
+
+int drmModeAtomicMerge(drmModeAtomicReqPtr base, drmModeAtomicReqPtr augment)
+{
+	if (!augment || augment->cursor == 0)
+		return 0;
+
+	if (base->cursor + augment->cursor >= base->size_items) {
+		drmModeAtomicReqItemPtr new;
+		int saved_size = base->size_items;
+
+		base->size_items = base->cursor + augment->cursor;
+		new = realloc(base->items,
+			      base->size_items * sizeof(*base->items));
+		if (!new) {
+			base->size_items = saved_size;
+			return -ENOMEM;
+		}
+		base->items = new;
+	}
+
+	memcpy(&base->items[base->cursor], augment->items,
+	       augment->cursor * sizeof(*augment->items));
+	base->cursor += augment->cursor;
+
+	return 0;
+}
+
+int drmModeAtomicGetCursor(drmModeAtomicReqPtr req)
+{
+	return req->cursor;
+}
+
+void drmModeAtomicSetCursor(drmModeAtomicReqPtr req, int cursor)
+{
+	req->cursor = cursor;
+}
+
+int drmModeAtomicAddProperty(drmModeAtomicReqPtr req,
+			     uint32_t object_id,
+			     uint32_t property_id,
+			     uint64_t value)
+{
+	if (req->cursor >= req->size_items) {
+		drmModeAtomicReqItemPtr new;
+
+		req->size_items += 16;
+		new = realloc(req->items, req->size_items * sizeof(*req->items));
+		if (!new) {
+			req->size_items -= 16;
+			return -ENOMEM;
+		}
+		req->items = new;
+	}
+
+	req->items[req->cursor].object_id = object_id;
+	req->items[req->cursor].property_id = property_id;
+	req->items[req->cursor].value = value;
+	req->cursor++;
+
+	return req->cursor;
+}
+
+void drmModeAtomicFree(drmModeAtomicReqPtr req)
+{
+	if (!req)
+		return;
+
+	if (req->items)
+		drmFree(req->items);
+	drmFree(req);
+}
+
+static int sort_req_list(const void *misc, const void *other)
+{
+	const drmModeAtomicReqItem *first = misc;
+	const drmModeAtomicReqItem *second = other;
+
+	if (first->object_id < second->object_id)
+		return -1;
+	else if (first->object_id > second->object_id)
+		return 1;
+	else
+		return second->property_id - first->property_id;
+}
+
+int drmModeAtomicCommit(int fd, drmModeAtomicReqPtr req, uint32_t flags,
+			void *user_data)
+{
+	drmModeAtomicReqPtr sorted = drmModeAtomicDuplicate(req);
+	struct drm_mode_atomic atomic;
+	uint32_t *objs_ptr = NULL;
+	uint32_t *count_props_ptr = NULL;
+	uint32_t *props_ptr = NULL;
+	uint64_t *prop_values_ptr = NULL;
+	uint32_t last_obj_id = 0;
+	uint32_t i;
+	int obj_idx = -1;
+	int ret = -1;
+
+	if (!sorted)
+		return -ENOMEM;
+
+	memclear(atomic);
+
+	/* Sort the list by object ID, then by property ID. */
+	qsort(sorted->items, sorted->cursor, sizeof(*sorted->items),
+	      sort_req_list);
+
+	/* Now the list is sorted, eliminate duplicate property sets. */
+	for (i = 0; i < sorted->cursor; i++) {
+		if (sorted->items[i].object_id != last_obj_id) {
+			atomic.count_objs++;
+			last_obj_id = sorted->items[i].object_id;
+		}
+
+		if (i == sorted->cursor - 1)
+			continue;
+
+		if (sorted->items[i].object_id != sorted->items[i + 1].object_id ||
+		    sorted->items[i].property_id != sorted->items[i + 1].property_id)
+			continue;
+
+		memmove(&sorted->items[i], &sorted->items[i + 1],
+			(sorted->cursor - i - 1) * sizeof(*sorted->items));
+		sorted->cursor--;
+	}
+
+	objs_ptr = drmMalloc(atomic.count_objs * sizeof objs_ptr[0]);
+	if (!objs_ptr) {
+		errno = ENOMEM;
+		goto out;
+	}
+
+	count_props_ptr = drmMalloc(atomic.count_objs * sizeof count_props_ptr[0]);
+	if (!count_props_ptr) {
+		errno = ENOMEM;
+		goto out;
+	}
+
+	props_ptr = drmMalloc(sorted->cursor * sizeof props_ptr[0]);
+	if (!props_ptr) {
+		errno = ENOMEM;
+		goto out;
+	}
+
+	prop_values_ptr = drmMalloc(sorted->cursor * sizeof prop_values_ptr[0]);
+	if (!prop_values_ptr) {
+		errno = ENOMEM;
+		goto out;
+	}
+
+	for (i = 0, last_obj_id = 0; i < sorted->cursor; i++) {
+		if (sorted->items[i].object_id != last_obj_id) {
+			obj_idx++;
+			objs_ptr[obj_idx] = sorted->items[i].object_id;
+			last_obj_id = objs_ptr[obj_idx];
+		}
+
+		count_props_ptr[obj_idx]++;
+		props_ptr[i] = sorted->items[i].property_id;
+		prop_values_ptr[i] = sorted->items[i].value;
+
+	}
+
+	atomic.flags = flags;
+	atomic.objs_ptr = VOID2U64(objs_ptr);
+	atomic.count_props_ptr = VOID2U64(count_props_ptr);
+	atomic.props_ptr = VOID2U64(props_ptr);
+	atomic.prop_values_ptr = VOID2U64(prop_values_ptr);
+	atomic.user_data = VOID2U64(user_data);
+
+	ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_ATOMIC, &atomic);
+
+out:
+	drmFree(objs_ptr);
+	drmFree(count_props_ptr);
+	drmFree(props_ptr);
+	drmFree(prop_values_ptr);
+	drmModeAtomicFree(sorted);
+
+	return ret;
+}
+
+int
+drmModeCreatePropertyBlob(int fd, const void *data, size_t length, uint32_t *id)
+{
+	struct drm_mode_create_blob create;
+	int ret;
+
+	if (length >= 0xffffffff)
+		return -ERANGE;
+
+	memclear(create);
+
+	create.length = length;
+	create.data = (uintptr_t) data;
+	create.blob_id = 0;
+	*id = 0;
+
+	ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_CREATEPROPBLOB, &create);
+	if (ret != 0)
+		return ret;
+
+	*id = create.blob_id;
+	return 0;
+}
+
+int
+drmModeDestroyPropertyBlob(int fd, uint32_t id)
+{
+	struct drm_mode_destroy_blob destroy;
+
+	memclear(destroy);
+	destroy.blob_id = id;
+	return DRM_IOCTL(fd, DRM_IOCTL_MODE_DESTROYPROPBLOB, &destroy);
+}

Index: xsrc/external/mit/libdrm/dist/include/drm/drm.h
diff -u xsrc/external/mit/libdrm/dist/include/drm/drm.h:1.4 xsrc/external/mit/libdrm/dist/include/drm/drm.h:1.5
--- xsrc/external/mit/libdrm/dist/include/drm/drm.h:1.4	Sun Dec 14 23:52:45 2014
+++ xsrc/external/mit/libdrm/dist/include/drm/drm.h	Mon Jul 20 02:27:05 2015
@@ -635,6 +635,13 @@ struct drm_get_cap {
  */
 #define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2
 
+/**
+ * DRM_CLIENT_CAP_ATOMIC
+ *
+ * If set to 1, the DRM core will allow atomic modesetting requests.
+ */
+#define DRM_CLIENT_CAP_ATOMIC		3
+
 /** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */
 struct drm_set_client_cap {
 	__u64 capability;
@@ -758,6 +765,9 @@ struct drm_prime_handle {
 #define DRM_IOCTL_MODE_OBJ_GETPROPERTIES	DRM_IOWR(0xB9, struct drm_mode_obj_get_properties)
 #define DRM_IOCTL_MODE_OBJ_SETPROPERTY	DRM_IOWR(0xBA, struct drm_mode_obj_set_property)
 #define DRM_IOCTL_MODE_CURSOR2		DRM_IOWR(0xBB, struct drm_mode_cursor2)
+#define DRM_IOCTL_MODE_ATOMIC		DRM_IOWR(0xBC, struct drm_mode_atomic)
+#define DRM_IOCTL_MODE_CREATEPROPBLOB	DRM_IOWR(0xBD, struct drm_mode_create_blob)
+#define DRM_IOCTL_MODE_DESTROYPROPBLOB	DRM_IOWR(0xBE, struct drm_mode_destroy_blob)
 
 /**
  * Device specific ioctls should only be in their respective headers

Index: xsrc/external/mit/libdrm/dist/include/drm/i915_drm.h
diff -u xsrc/external/mit/libdrm/dist/include/drm/i915_drm.h:1.2 xsrc/external/mit/libdrm/dist/include/drm/i915_drm.h:1.3
--- xsrc/external/mit/libdrm/dist/include/drm/i915_drm.h:1.2	Fri Feb  6 19:26:09 2015
+++ xsrc/external/mit/libdrm/dist/include/drm/i915_drm.h	Mon Jul 20 02:27:05 2015
@@ -224,6 +224,8 @@ typedef struct _drm_i915_sarea {
 #define DRM_I915_REG_READ		0x31
 #define DRM_I915_GET_RESET_STATS	0x32
 #define DRM_I915_GEM_USERPTR		0x33
+#define DRM_I915_GEM_CONTEXT_GETPARAM	0x34
+#define DRM_I915_GEM_CONTEXT_SETPARAM	0x35
 
 #define DRM_IOCTL_I915_INIT		DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
 #define DRM_IOCTL_I915_FLUSH		DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -274,7 +276,9 @@ typedef struct _drm_i915_sarea {
 #define DRM_IOCTL_I915_GEM_CONTEXT_DESTROY	DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_DESTROY, struct drm_i915_gem_context_destroy)
 #define DRM_IOCTL_I915_REG_READ			DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_REG_READ, struct drm_i915_reg_read)
 #define DRM_IOCTL_I915_GET_RESET_STATS		DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GET_RESET_STATS, struct drm_i915_reset_stats)
-#define DRM_IOCTL_I915_GEM_USERPTR		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_USERPTR,  struct drm_i915_gem_userptr)
+#define DRM_IOCTL_I915_GEM_USERPTR			DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_USERPTR, struct drm_i915_gem_userptr)
+#define DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM	DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_GETPARAM, struct drm_i915_gem_context_param)
+#define DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM	DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_SETPARAM, struct drm_i915_gem_context_param)
 
 /* Allow drivers to submit batchbuffers directly to hardware, relying
  * on the security mechanisms provided by hardware.
@@ -340,6 +344,12 @@ typedef struct drm_i915_irq_wait {
 #define I915_PARAM_HAS_EXEC_HANDLE_LUT   26
 #define I915_PARAM_HAS_WT     	 	 27
 #define I915_PARAM_CMD_PARSER_VERSION	 28
+#define I915_PARAM_HAS_COHERENT_PHYS_GTT 29
+#define I915_PARAM_MMAP_VERSION          30
+#define I915_PARAM_HAS_BSD2		 31
+#define I915_PARAM_REVISION              32
+#define I915_PARAM_SUBSLICE_TOTAL	 33
+#define I915_PARAM_EU_TOTAL		 34
 
 typedef struct drm_i915_getparam {
 	int param;
@@ -487,6 +497,14 @@ struct drm_i915_gem_mmap {
 	 * This is a fixed-size type for 32/64 compatibility.
 	 */
 	__u64 addr_ptr;
+
+	/**
+	 * Flags for extended behaviour.
+	 *
+	 * Added in version 2.
+	 */
+	__u64 flags;
+#define I915_MMAP_WC 0x1
 };
 
 struct drm_i915_gem_mmap_gtt {
@@ -736,7 +754,13 @@ struct drm_i915_gem_execbuffer2 {
  */
 #define I915_EXEC_HANDLE_LUT		(1<<12)
 
-#define __I915_EXEC_UNKNOWN_FLAGS -(I915_EXEC_HANDLE_LUT<<1)
+/** Used for switching BSD rings on the platforms with two BSD rings */
+#define I915_EXEC_BSD_MASK		(3<<13)
+#define I915_EXEC_BSD_DEFAULT		(0<<13) /* default ping-pong mode */
+#define I915_EXEC_BSD_RING1		(1<<13)
+#define I915_EXEC_BSD_RING2		(2<<13)
+
+#define __I915_EXEC_UNKNOWN_FLAGS -(1<<15)
 
 #define I915_EXEC_CONTEXT_ID_MASK	(0xffffffff)
 #define i915_execbuffer2_set_context_id(eb2, context) \
@@ -876,6 +900,12 @@ struct drm_i915_gem_get_tiling {
 	 * mmap mapping.
 	 */
 	__u32 swizzle_mode;
+
+	/**
+	 * Returned address bit 6 swizzling required for CPU access through
+	 * mmap mapping whilst bound.
+	 */
+	__u32 phys_swizzle_mode;
 };
 
 struct drm_i915_gem_get_aperture {
@@ -1059,11 +1089,19 @@ struct drm_i915_gem_userptr {
 #define I915_USERPTR_READ_ONLY 0x1
 #define I915_USERPTR_UNSYNCHRONIZED 0x80000000
 	/**
-	* Returned handle for the object.
-	*
-	* Object handles are nonzero.
-	*/
+	 * Returned handle for the object.
+	 *
+	 * Object handles are nonzero.
+	 */
 	__u32 handle;
 };
 
+struct drm_i915_gem_context_param {
+	__u32 ctx_id;
+	__u32 size;
+	__u64 param;
+#define I915_CONTEXT_PARAM_BAN_PERIOD 0x1
+	__u64 value;
+};
+
 #endif /* _I915_DRM_H_ */

Index: xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c
diff -u xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c:1.10 xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c:1.11
--- xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c:1.10	Fri Jan 23 08:25:08 2015
+++ xsrc/external/mit/libdrm/dist/intel/intel_bufmgr_gem.c	Mon Jul 20 02:27:06 2015
@@ -57,7 +57,7 @@
 #ifndef ETIME
 #define ETIME ETIMEDOUT
 #endif
-#include "libdrm.h"
+#include "libdrm_macros.h"
 #include "libdrm_lists.h"
 #include "intel_bufmgr.h"
 #include "intel_bufmgr_priv.h"
@@ -75,7 +75,7 @@
 #define VG(x)
 #endif
 
-#define VG_CLEAR(s) VG(memset(&s, 0, sizeof(s)))
+#define memclear(s) memset(&s, 0, sizeof(s))
 
 #define DBG(...) do {					\
 	if (bufmgr_gem->bufmgr.debug)			\
@@ -133,6 +133,11 @@ typedef struct _drm_intel_bufmgr_gem {
 	unsigned int has_vebox : 1;
 	bool fenced_relocs;
 
+	struct {
+		void *ptr;
+		uint32_t handle;
+	} userptr_active;
+
 	char *aub_filename;
 	FILE *aub_file;
 	uint32_t aub_offset;
@@ -594,7 +599,7 @@ drm_intel_gem_bo_busy(drm_intel_bo *bo)
 	if (bo_gem->reusable && bo_gem->idle)
 		return false;
 
-	VG_CLEAR(busy);
+	memclear(busy);
 	busy.handle = bo_gem->gem_handle;
 
 	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_BUSY, &busy);
@@ -613,7 +618,7 @@ drm_intel_gem_bo_madvise_internal(drm_in
 {
 	struct drm_i915_gem_madvise madv;
 
-	VG_CLEAR(madv);
+	memclear(madv);
 	madv.handle = bo_gem->gem_handle;
 	madv.madv = state;
 	madv.retained = 1;
@@ -742,7 +747,7 @@ retry:
 
 		bo_gem->bo.size = bo_size;
 
-		VG_CLEAR(create);
+		memclear(create);
 		create.size = bo_size;
 
 		ret = drmIoctl(bufmgr_gem->fd,
@@ -889,7 +894,7 @@ drm_intel_gem_bo_alloc_userptr(drm_intel
 
 	bo_gem->bo.size = size;
 
-	VG_CLEAR(userptr);
+	memclear(userptr);
 	userptr.user_ptr = (__u64)((unsigned long)addr);
 	userptr.user_size = size;
 	userptr.flags = flags;
@@ -937,13 +942,77 @@ drm_intel_gem_bo_alloc_userptr(drm_intel
 	return &bo_gem->bo;
 }
 
+static bool
+has_userptr(drm_intel_bufmgr_gem *bufmgr_gem)
+{
+	int ret;
+	void *ptr;
+	long pgsz;
+	struct drm_i915_gem_userptr userptr;
+
+	pgsz = sysconf(_SC_PAGESIZE);
+	assert(pgsz > 0);
+
+	ret = posix_memalign(&ptr, pgsz, pgsz);
+	if (ret) {
+		DBG("Failed to get a page (%ld) for userptr detection!\n",
+			pgsz);
+		return false;
+	}
+
+	memclear(userptr);
+	userptr.user_ptr = (__u64)(unsigned long)ptr;
+	userptr.user_size = pgsz;
+
+retry:
+	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_USERPTR, &userptr);
+	if (ret) {
+		if (errno == ENODEV && userptr.flags == 0) {
+			userptr.flags = I915_USERPTR_UNSYNCHRONIZED;
+			goto retry;
+		}
+		free(ptr);
+		return false;
+	}
+
+	/* We don't release the userptr bo here as we want to keep the
+	 * kernel mm tracking alive for our lifetime. The first time we
+	 * create a userptr object the kernel has to install a mmu_notifer
+	 * which is a heavyweight operation (e.g. it requires taking all
+	 * mm_locks and stop_machine()).
+	 */
+
+	bufmgr_gem->userptr_active.ptr = ptr;
+	bufmgr_gem->userptr_active.handle = userptr.handle;
+
+	return true;
+}
+
+static drm_intel_bo *
+check_bo_alloc_userptr(drm_intel_bufmgr *bufmgr,
+		       const char *name,
+		       void *addr,
+		       uint32_t tiling_mode,
+		       uint32_t stride,
+		       unsigned long size,
+		       unsigned long flags)
+{
+	if (has_userptr((drm_intel_bufmgr_gem *)bufmgr))
+		bufmgr->bo_alloc_userptr = drm_intel_gem_bo_alloc_userptr;
+	else
+		bufmgr->bo_alloc_userptr = NULL;
+
+	return drm_intel_bo_alloc_userptr(bufmgr, name, addr,
+					  tiling_mode, stride, size, flags);
+}
+
 /**
  * Returns a drm_intel_bo wrapping the given buffer object handle.
  *
  * This can be used when one application needs to pass a buffer object
  * to another.
  */
-drm_public drm_intel_bo *
+drm_intel_bo *
 drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr,
 				  const char *name,
 				  unsigned int handle)
@@ -973,7 +1042,7 @@ drm_intel_bo_gem_create_from_name(drm_in
 		}
 	}
 
-	VG_CLEAR(open_arg);
+	memclear(open_arg);
 	open_arg.name = handle;
 	ret = drmIoctl(bufmgr_gem->fd,
 		       DRM_IOCTL_GEM_OPEN,
@@ -1018,7 +1087,7 @@ drm_intel_bo_gem_create_from_name(drm_in
 	bo_gem->global_name = handle;
 	bo_gem->reusable = false;
 
-	VG_CLEAR(get_tiling);
+	memclear(get_tiling);
 	get_tiling.handle = bo_gem->gem_handle;
 	ret = drmIoctl(bufmgr_gem->fd,
 		       DRM_IOCTL_I915_GEM_GET_TILING,
@@ -1061,7 +1130,7 @@ drm_intel_gem_bo_free(drm_intel_bo *bo)
 	}
 
 	/* Close this object */
-	VG_CLEAR(close);
+	memclear(close);
 	close.handle = bo_gem->gem_handle;
 	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CLOSE, &close);
 	if (ret != 0) {
@@ -1293,9 +1362,8 @@ static int drm_intel_gem_bo_map(drm_inte
 		DBG("bo_map: %d (%s), map_count=%d\n",
 		    bo_gem->gem_handle, bo_gem->name, bo_gem->map_count);
 
-		VG_CLEAR(mmap_arg);
+		memclear(mmap_arg);
 		mmap_arg.handle = bo_gem->gem_handle;
-		mmap_arg.offset = 0;
 		mmap_arg.size = bo->size;
 		ret = drmIoctl(bufmgr_gem->fd,
 			       DRM_IOCTL_I915_GEM_MMAP,
@@ -1317,7 +1385,7 @@ static int drm_intel_gem_bo_map(drm_inte
 	    bo_gem->mem_virtual);
 	bo->virtual = bo_gem->mem_virtual;
 
-	VG_CLEAR(set_domain);
+	memclear(set_domain);
 	set_domain.handle = bo_gem->gem_handle;
 	set_domain.read_domains = I915_GEM_DOMAIN_CPU;
 	if (write_enable)
@@ -1363,7 +1431,7 @@ map_gtt(drm_intel_bo *bo)
 		DBG("bo_map_gtt: mmap %d (%s), map_count=%d\n",
 		    bo_gem->gem_handle, bo_gem->name, bo_gem->map_count);
 
-		VG_CLEAR(mmap_arg);
+		memclear(mmap_arg);
 		mmap_arg.handle = bo_gem->gem_handle;
 
 		/* Get the fake offset back... */
@@ -1404,7 +1472,7 @@ map_gtt(drm_intel_bo *bo)
 	return 0;
 }
 
-drm_public int
+int
 drm_intel_gem_bo_map_gtt(drm_intel_bo *bo)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
@@ -1429,7 +1497,7 @@ drm_intel_gem_bo_map_gtt(drm_intel_bo *b
 	 * tell it when we're about to use things if we had done
 	 * rendering and it still happens to be bound to the GTT.
 	 */
-	VG_CLEAR(set_domain);
+	memclear(set_domain);
 	set_domain.handle = bo_gem->gem_handle;
 	set_domain.read_domains = I915_GEM_DOMAIN_GTT;
 	set_domain.write_domain = I915_GEM_DOMAIN_GTT;
@@ -1463,7 +1531,7 @@ drm_intel_gem_bo_map_gtt(drm_intel_bo *b
  * undefined).
  */
 
-drm_public int
+int
 drm_intel_gem_bo_map_unsynchronized(drm_intel_bo *bo)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
@@ -1528,7 +1596,7 @@ static int drm_intel_gem_bo_unmap(drm_in
 		 * Unlike GTT set domains, this only does work if the
 		 * buffer should be scanout-related.
 		 */
-		VG_CLEAR(sw_finish);
+		memclear(sw_finish);
 		sw_finish.handle = bo_gem->gem_handle;
 		ret = drmIoctl(bufmgr_gem->fd,
 			       DRM_IOCTL_I915_GEM_SW_FINISH,
@@ -1552,7 +1620,7 @@ static int drm_intel_gem_bo_unmap(drm_in
 	return ret;
 }
 
-drm_public int
+int
 drm_intel_gem_bo_unmap_gtt(drm_intel_bo *bo)
 {
 	return drm_intel_gem_bo_unmap(bo);
@@ -1570,7 +1638,7 @@ drm_intel_gem_bo_subdata(drm_intel_bo *b
 	if (bo_gem->is_userptr)
 		return -EINVAL;
 
-	VG_CLEAR(pwrite);
+	memclear(pwrite);
 	pwrite.handle = bo_gem->gem_handle;
 	pwrite.offset = offset;
 	pwrite.size = size;
@@ -1595,7 +1663,7 @@ drm_intel_gem_get_pipe_from_crtc_id(drm_
 	struct drm_i915_get_pipe_from_crtc_id get_pipe_from_crtc_id;
 	int ret;
 
-	VG_CLEAR(get_pipe_from_crtc_id);
+	memclear(get_pipe_from_crtc_id);
 	get_pipe_from_crtc_id.crtc_id = crtc_id;
 	ret = drmIoctl(bufmgr_gem->fd,
 		       DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID,
@@ -1625,7 +1693,7 @@ drm_intel_gem_bo_get_subdata(drm_intel_b
 	if (bo_gem->is_userptr)
 		return -EINVAL;
 
-	VG_CLEAR(pread);
+	memclear(pread);
 	pread.handle = bo_gem->gem_handle;
 	pread.offset = offset;
 	pread.size = size;
@@ -1673,8 +1741,11 @@ drm_intel_gem_bo_wait_rendering(drm_inte
  * not guarantee that the buffer is re-issued via another thread, or an flinked
  * handle. Userspace must make sure this race does not occur if such precision
  * is important.
+ *
+ * Note that some kernels have broken the inifite wait for negative values
+ * promise, upgrade to latest stable kernels if this is the case.
  */
-drm_public int
+int
 drm_intel_gem_bo_wait(drm_intel_bo *bo, int64_t timeout_ns)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
@@ -1693,9 +1764,9 @@ drm_intel_gem_bo_wait(drm_intel_bo *bo, 
 		}
 	}
 
+	memclear(wait);
 	wait.bo_handle = bo_gem->gem_handle;
 	wait.timeout_ns = timeout_ns;
-	wait.flags = 0;
 	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_WAIT, &wait);
 	if (ret == -1)
 		return -errno;
@@ -1710,7 +1781,7 @@ drm_intel_gem_bo_wait(drm_intel_bo *bo, 
  * In combination with drm_intel_gem_bo_pin() and manual fence management, we
  * can do tiled pixmaps this way.
  */
-drm_public void
+void
 drm_intel_gem_bo_start_gtt_access(drm_intel_bo *bo, int write_enable)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
@@ -1718,7 +1789,7 @@ drm_intel_gem_bo_start_gtt_access(drm_in
 	struct drm_i915_gem_set_domain set_domain;
 	int ret;
 
-	VG_CLEAR(set_domain);
+	memclear(set_domain);
 	set_domain.handle = bo_gem->gem_handle;
 	set_domain.read_domains = I915_GEM_DOMAIN_GTT;
 	set_domain.write_domain = write_enable ? I915_GEM_DOMAIN_GTT : 0;
@@ -1737,7 +1808,8 @@ static void
 drm_intel_bufmgr_gem_destroy(drm_intel_bufmgr *bufmgr)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
-	int i;
+	struct drm_gem_close close_bo;
+	int i, ret;
 
 	free(bufmgr_gem->exec2_objects);
 	free(bufmgr_gem->exec_objects);
@@ -1761,6 +1833,18 @@ drm_intel_bufmgr_gem_destroy(drm_intel_b
 		}
 	}
 
+	/* Release userptr bo kept hanging around for optimisation. */
+	if (bufmgr_gem->userptr_active.ptr) {
+		memclear(close_bo);
+		close_bo.handle = bufmgr_gem->userptr_active.handle;
+		ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CLOSE, &close_bo);
+		free(bufmgr_gem->userptr_active.ptr);
+		if (ret)
+			fprintf(stderr,
+				"Failed to release test userptr object! (%d) "
+				"i915 kernel driver may not be sane!\n", errno);
+	}
+
 	free(bufmgr);
 }
 
@@ -1873,7 +1957,7 @@ drm_intel_gem_bo_emit_reloc_fence(drm_in
 				read_domains, write_domain, true);
 }
 
-drm_public int
+int
 drm_intel_gem_bo_get_reloc_count(drm_intel_bo *bo)
 {
 	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
@@ -1894,7 +1978,7 @@ drm_intel_gem_bo_get_reloc_count(drm_int
  * Any further drm_intel_bufmgr_check_aperture_space() queries
  * involving this buffer in the tree are undefined after this call.
  */
-drm_public void
+void
 drm_intel_gem_bo_clear_relocs(drm_intel_bo *bo, int start)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
@@ -2232,7 +2316,7 @@ aub_build_dump_ringbuffer(drm_intel_bufm
 	bufmgr_gem->aub_offset += 4096;
 }
 
-drm_public void
+void
 drm_intel_gem_bo_aub_dump_bmp(drm_intel_bo *bo,
 			      int x1, int y1, int width, int height,
 			      enum aub_dump_bmp_format format,
@@ -2340,7 +2424,7 @@ drm_intel_gem_bo_exec(drm_intel_bo *bo, 
 	 */
 	drm_intel_add_validate_buffer(bo);
 
-	VG_CLEAR(execbuf);
+	memclear(execbuf);
 	execbuf.buffers_ptr = (uintptr_t) bufmgr_gem->exec_objects;
 	execbuf.buffer_count = bufmgr_gem->exec_count;
 	execbuf.batch_start_offset = 0;
@@ -2427,7 +2511,7 @@ do_exec2(drm_intel_bo *bo, int used, drm
 	 */
 	drm_intel_add_validate_buffer2(bo, 0);
 
-	VG_CLEAR(execbuf);
+	memclear(execbuf);
 	execbuf.buffers_ptr = (uintptr_t)bufmgr_gem->exec2_objects;
 	execbuf.buffer_count = bufmgr_gem->exec_count;
 	execbuf.batch_start_offset = 0;
@@ -2503,7 +2587,7 @@ drm_intel_gem_bo_mrb_exec2(drm_intel_bo 
 			flags);
 }
 
-drm_public int
+int
 drm_intel_gem_bo_context_exec(drm_intel_bo *bo, drm_intel_context *ctx,
 			      int used, unsigned int flags)
 {
@@ -2518,7 +2602,7 @@ drm_intel_gem_bo_pin(drm_intel_bo *bo, u
 	struct drm_i915_gem_pin pin;
 	int ret;
 
-	VG_CLEAR(pin);
+	memclear(pin);
 	pin.handle = bo_gem->gem_handle;
 	pin.alignment = alignment;
 
@@ -2541,7 +2625,7 @@ drm_intel_gem_bo_unpin(drm_intel_bo *bo)
 	struct drm_i915_gem_unpin unpin;
 	int ret;
 
-	VG_CLEAR(unpin);
+	memclear(unpin);
 	unpin.handle = bo_gem->gem_handle;
 
 	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_UNPIN, &unpin);
@@ -2628,7 +2712,7 @@ drm_intel_gem_bo_get_tiling(drm_intel_bo
 	return 0;
 }
 
-drm_public drm_intel_bo *
+drm_intel_bo *
 drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr *bufmgr, int prime_fd, int size)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
@@ -2697,7 +2781,7 @@ drm_intel_bo_gem_create_from_prime(drm_i
 	DRMLISTADDTAIL(&bo_gem->name_list, &bufmgr_gem->named);
 	pthread_mutex_unlock(&bufmgr_gem->lock);
 
-	VG_CLEAR(get_tiling);
+	memclear(get_tiling);
 	get_tiling.handle = bo_gem->gem_handle;
 	ret = drmIoctl(bufmgr_gem->fd,
 		       DRM_IOCTL_I915_GEM_GET_TILING,
@@ -2714,7 +2798,7 @@ drm_intel_bo_gem_create_from_prime(drm_i
 	return &bo_gem->bo;
 }
 
-drm_public int
+int
 drm_intel_bo_gem_export_to_prime(drm_intel_bo *bo, int *prime_fd)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
@@ -2744,7 +2828,7 @@ drm_intel_gem_bo_flink(drm_intel_bo *bo,
 	if (!bo_gem->global_name) {
 		struct drm_gem_flink flink;
 
-		VG_CLEAR(flink);
+		memclear(flink);
 		flink.handle = bo_gem->gem_handle;
 
 		pthread_mutex_lock(&bufmgr_gem->lock);
@@ -2774,7 +2858,7 @@ drm_intel_gem_bo_flink(drm_intel_bo *bo,
  * size is only bounded by how many buffers of that size we've managed to have
  * in flight at once.
  */
-drm_public void
+void
 drm_intel_bufmgr_gem_enable_reuse(drm_intel_bufmgr *bufmgr)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bufmgr;
@@ -2789,7 +2873,7 @@ drm_intel_bufmgr_gem_enable_reuse(drm_in
  * allocation.  If this option is not enabled, all relocs will have fence
  * register allocated.
  */
-drm_public void
+void
 drm_intel_bufmgr_gem_enable_fenced_relocs(drm_intel_bufmgr *bufmgr)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
@@ -3061,7 +3145,7 @@ init_cache_buckets(drm_intel_bufmgr_gem 
 	}
 }
 
-drm_public void
+void
 drm_intel_bufmgr_gem_set_vma_cache_size(drm_intel_bufmgr *bufmgr, int limit)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
@@ -3079,7 +3163,7 @@ static int
 get_pci_device_id(drm_intel_bufmgr_gem *bufmgr_gem)
 {
 	char *devid_override;
-	int devid;
+	int devid = 0;
 	int ret;
 	drm_i915_getparam_t gp;
 
@@ -3091,8 +3175,7 @@ get_pci_device_id(drm_intel_bufmgr_gem *
 		}
 	}
 
-	VG_CLEAR(devid);
-	VG_CLEAR(gp);
+	memclear(gp);
 	gp.param = I915_PARAM_CHIPSET_ID;
 	gp.value = &devid;
 	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
@@ -3103,7 +3186,7 @@ get_pci_device_id(drm_intel_bufmgr_gem *
 	return devid;
 }
 
-drm_public int
+int
 drm_intel_bufmgr_gem_get_devid(drm_intel_bufmgr *bufmgr)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
@@ -3117,7 +3200,7 @@ drm_intel_bufmgr_gem_get_devid(drm_intel
  * This function has to be called before drm_intel_bufmgr_gem_set_aub_dump()
  * for it to have any effect.
  */
-drm_public void
+void
 drm_intel_bufmgr_gem_set_aub_filename(drm_intel_bufmgr *bufmgr,
 				      const char *filename)
 {
@@ -3136,7 +3219,7 @@ drm_intel_bufmgr_gem_set_aub_filename(dr
  * You can set up a GTT and upload your objects into the referenced
  * space, then send off batchbuffers and get BMPs out the other end.
  */
-drm_public void
+void
 drm_intel_bufmgr_gem_set_aub_dump(drm_intel_bufmgr *bufmgr, int enable)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
@@ -3193,7 +3276,7 @@ drm_intel_bufmgr_gem_set_aub_dump(drm_in
 	}
 }
 
-drm_public drm_intel_context *
+drm_intel_context *
 drm_intel_gem_context_create(drm_intel_bufmgr *bufmgr)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr;
@@ -3205,7 +3288,7 @@ drm_intel_gem_context_create(drm_intel_b
 	if (!context)
 		return NULL;
 
-	VG_CLEAR(create);
+	memclear(create);
 	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_CONTEXT_CREATE, &create);
 	if (ret != 0) {
 		DBG("DRM_IOCTL_I915_GEM_CONTEXT_CREATE failed: %s\n",
@@ -3220,7 +3303,7 @@ drm_intel_gem_context_create(drm_intel_b
 	return context;
 }
 
-drm_public void
+void
 drm_intel_gem_context_destroy(drm_intel_context *ctx)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem;
@@ -3230,7 +3313,7 @@ drm_intel_gem_context_destroy(drm_intel_
 	if (ctx == NULL)
 		return;
 
-	VG_CLEAR(destroy);
+	memclear(destroy);
 
 	bufmgr_gem = (drm_intel_bufmgr_gem *)ctx->bufmgr;
 	destroy.ctx_id = ctx->ctx_id;
@@ -3243,7 +3326,7 @@ drm_intel_gem_context_destroy(drm_intel_
 	free(ctx);
 }
 
-drm_public int
+int
 drm_intel_get_reset_stats(drm_intel_context *ctx,
 			  uint32_t *reset_count,
 			  uint32_t *active,
@@ -3256,7 +3339,7 @@ drm_intel_get_reset_stats(drm_intel_cont
 	if (ctx == NULL)
 		return -EINVAL;
 
-	memset(&stats, 0, sizeof(stats));
+	memclear(stats);
 
 	bufmgr_gem = (drm_intel_bufmgr_gem *)ctx->bufmgr;
 	stats.ctx_id = ctx->ctx_id;
@@ -3277,7 +3360,7 @@ drm_intel_get_reset_stats(drm_intel_cont
 	return ret;
 }
 
-drm_public int
+int
 drm_intel_reg_read(drm_intel_bufmgr *bufmgr,
 		   uint32_t offset,
 		   uint64_t *result)
@@ -3286,7 +3369,7 @@ drm_intel_reg_read(drm_intel_bufmgr *buf
 	struct drm_i915_reg_read reg_read;
 	int ret;
 
-	VG_CLEAR(reg_read);
+	memclear(reg_read);
 	reg_read.offset = offset;
 
 	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_REG_READ, &reg_read);
@@ -3295,6 +3378,37 @@ drm_intel_reg_read(drm_intel_bufmgr *buf
 	return ret;
 }
 
+int
+drm_intel_get_subslice_total(int fd, unsigned int *subslice_total)
+{
+	drm_i915_getparam_t gp;
+	int ret;
+
+	memclear(gp);
+	gp.value = (int*)subslice_total;
+	gp.param = I915_PARAM_SUBSLICE_TOTAL;
+	ret = drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
+	if (ret)
+		return -errno;
+
+	return 0;
+}
+
+int
+drm_intel_get_eu_total(int fd, unsigned int *eu_total)
+{
+	drm_i915_getparam_t gp;
+	int ret;
+
+	memclear(gp);
+	gp.value = (int*)eu_total;
+	gp.param = I915_PARAM_EU_TOTAL;
+	ret = drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
+	if (ret)
+		return -errno;
+
+	return 0;
+}
 
 /**
  * Annotate the given bo for use in aub dumping.
@@ -3317,7 +3431,7 @@ drm_intel_reg_read(drm_intel_bufmgr *buf
  * default state (no annotations), call this function with a \c count
  * of zero.
  */
-drm_public void
+void
 drm_intel_bufmgr_gem_set_aub_annotations(drm_intel_bo *bo,
 					 drm_intel_aub_annotation *annotations,
 					 unsigned count)
@@ -3372,59 +3486,13 @@ drm_intel_bufmgr_gem_unref(drm_intel_buf
 	}
 }
 
-static bool
-has_userptr(drm_intel_bufmgr_gem *bufmgr_gem)
-{
-	int ret;
-	void *ptr;
-	long pgsz;
-	struct drm_i915_gem_userptr userptr;
-	struct drm_gem_close close_bo;
-
-	pgsz = sysconf(_SC_PAGESIZE);
-	assert(pgsz > 0);
-
-	ret = posix_memalign(&ptr, pgsz, pgsz);
-	if (ret) {
-		DBG("Failed to get a page (%ld) for userptr detection!\n",
-			pgsz);
-		return false;
-	}
-
-	memset(&userptr, 0, sizeof(userptr));
-	userptr.user_ptr = (__u64)(unsigned long)ptr;
-	userptr.user_size = pgsz;
-
-retry:
-	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_USERPTR, &userptr);
-	if (ret) {
-		if (errno == ENODEV && userptr.flags == 0) {
-			userptr.flags = I915_USERPTR_UNSYNCHRONIZED;
-			goto retry;
-		}
-		free(ptr);
-		return false;
-	}
-
-	close_bo.handle = userptr.handle;
-	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CLOSE, &close_bo);
-	free(ptr);
-	if (ret) {
-		fprintf(stderr, "Failed to release test userptr object! (%d) "
-				"i915 kernel driver may not be sane!\n", errno);
-		return false;
-	}
-
-	return true;
-}
-
 /**
  * Initializes the GEM buffer manager, which uses the kernel to allocate, map,
  * and manage map buffer objections.
  *
  * \param fd File descriptor of the opened DRM device.
  */
-drm_public drm_intel_bufmgr *
+drm_intel_bufmgr *
 drm_intel_bufmgr_gem_init(int fd, int batch_size)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem;
@@ -3452,6 +3520,7 @@ drm_intel_bufmgr_gem_init(int fd, int ba
 		goto exit;
 	}
 
+	memclear(aperture);
 	ret = drmIoctl(bufmgr_gem->fd,
 		       DRM_IOCTL_I915_GEM_GET_APERTURE,
 		       &aperture);
@@ -3501,7 +3570,7 @@ drm_intel_bufmgr_gem_init(int fd, int ba
 		bufmgr_gem->gtt_size -= 256*1024*1024;
 	}
 
-	VG_CLEAR(gp);
+	memclear(gp);
 	gp.value = &tmp;
 
 	gp.param = I915_PARAM_HAS_EXECBUF2;
@@ -3521,9 +3590,7 @@ drm_intel_bufmgr_gem_init(int fd, int ba
 	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);
 	bufmgr_gem->has_relaxed_fencing = ret == 0;
 
-	if (has_userptr(bufmgr_gem))
-		bufmgr_gem->bufmgr.bo_alloc_userptr =
-			drm_intel_gem_bo_alloc_userptr;
+	bufmgr_gem->bufmgr.bo_alloc_userptr = check_bo_alloc_userptr;
 
 	gp.param = I915_PARAM_HAS_WAIT_TIMEOUT;
 	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GETPARAM, &gp);

Index: xsrc/external/mit/libdrm/dist/radeon/radeon_bo_gem.c
diff -u xsrc/external/mit/libdrm/dist/radeon/radeon_bo_gem.c:1.5 xsrc/external/mit/libdrm/dist/radeon/radeon_bo_gem.c:1.6
--- xsrc/external/mit/libdrm/dist/radeon/radeon_bo_gem.c:1.5	Sat Dec 13 21:39:07 2014
+++ xsrc/external/mit/libdrm/dist/radeon/radeon_bo_gem.c	Mon Jul 20 02:27:06 2015
@@ -37,7 +37,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include "libdrm.h"
+#include "libdrm_macros.h"
 #include "xf86drm.h"
 #include "xf86atomic.h"
 #include "drm.h"
@@ -284,7 +284,7 @@ static struct radeon_bo_funcs bo_gem_fun
     bo_is_busy,
 };
 
-drm_public struct radeon_bo_manager *radeon_bo_manager_gem_ctor(int fd)
+struct radeon_bo_manager *radeon_bo_manager_gem_ctor(int fd)
 {
     struct bo_manager_gem *bomg;
 
@@ -297,7 +297,7 @@ drm_public struct radeon_bo_manager *rad
     return (struct radeon_bo_manager*)bomg;
 }
 
-drm_public void radeon_bo_manager_gem_dtor(struct radeon_bo_manager *bom)
+void radeon_bo_manager_gem_dtor(struct radeon_bo_manager *bom)
 {
     struct bo_manager_gem *bomg = (struct bo_manager_gem*)bom;
 
@@ -307,21 +307,21 @@ drm_public void radeon_bo_manager_gem_dt
     free(bomg);
 }
 
-drm_public uint32_t
+uint32_t
 radeon_gem_name_bo(struct radeon_bo *bo)
 {
     struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
     return bo_gem->name;
 }
 
-drm_public void *
+void *
 radeon_gem_get_reloc_in_cs(struct radeon_bo *bo)
 {
     struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
     return &bo_gem->reloc_in_cs;
 }
 
-drm_public int
+int
 radeon_gem_get_kernel_name(struct radeon_bo *bo, uint32_t *name)
 {
     struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
@@ -343,7 +343,7 @@ radeon_gem_get_kernel_name(struct radeon
     return 0;
 }
 
-drm_public int
+int
 radeon_gem_set_domain(struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain)
 {
     struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
@@ -361,7 +361,7 @@ radeon_gem_set_domain(struct radeon_bo *
     return r;
 }
 
-drm_public int radeon_gem_prime_share_bo(struct radeon_bo *bo, int *handle)
+int radeon_gem_prime_share_bo(struct radeon_bo *bo, int *handle)
 {
     struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
     int ret;
@@ -370,7 +370,7 @@ drm_public int radeon_gem_prime_share_bo
     return ret;
 }
 
-drm_public struct radeon_bo *
+struct radeon_bo *
 radeon_gem_bo_open_prime(struct radeon_bo_manager *bom, int fd_handle, uint32_t size)
 {
     struct radeon_bo_gem *bo;

Index: xsrc/external/mit/libdrm/dist/radeon/radeon_cs_gem.c
diff -u xsrc/external/mit/libdrm/dist/radeon/radeon_cs_gem.c:1.4 xsrc/external/mit/libdrm/dist/radeon/radeon_cs_gem.c:1.5
--- xsrc/external/mit/libdrm/dist/radeon/radeon_cs_gem.c:1.4	Sat Dec 13 21:39:07 2014
+++ xsrc/external/mit/libdrm/dist/radeon/radeon_cs_gem.c	Mon Jul 20 02:27:06 2015
@@ -44,13 +44,16 @@
 #include "radeon_cs_gem.h"
 #include "radeon_bo_gem.h"
 #include "drm.h"
-#include "libdrm.h"
+#include "libdrm_macros.h"
 #include "xf86drm.h"
 #include "xf86atomic.h"
 #include "radeon_drm.h"
-#include "bof.h"
 
+/* Add LIBDRM_RADEON_BOF_FILES to libdrm_radeon_la_SOURCES when building with BOF_DUMP */
 #define CS_BOF_DUMP 0
+#if CS_BOF_DUMP
+#include "bof.h"
+#endif
 
 struct radeon_cs_manager_gem {
     struct radeon_cs_manager    base;
@@ -537,7 +540,7 @@ static int radeon_get_device_id(int fd, 
     return r;
 }
 
-drm_public struct radeon_cs_manager *radeon_cs_manager_gem_ctor(int fd)
+struct radeon_cs_manager *radeon_cs_manager_gem_ctor(int fd)
 {
     struct radeon_cs_manager_gem *csm;
 
@@ -551,7 +554,7 @@ drm_public struct radeon_cs_manager *rad
     return &csm->base;
 }
 
-drm_public void radeon_cs_manager_gem_dtor(struct radeon_cs_manager *csm)
+void radeon_cs_manager_gem_dtor(struct radeon_cs_manager *csm)
 {
     free(csm);
 }

Index: xsrc/external/mit/libdrm/dist/radeon/radeon_surface.c
diff -u xsrc/external/mit/libdrm/dist/radeon/radeon_surface.c:1.6 xsrc/external/mit/libdrm/dist/radeon/radeon_surface.c:1.7
--- xsrc/external/mit/libdrm/dist/radeon/radeon_surface.c:1.6	Fri Jan 23 08:25:08 2015
+++ xsrc/external/mit/libdrm/dist/radeon/radeon_surface.c	Mon Jul 20 02:27:06 2015
@@ -37,7 +37,7 @@
 #include <string.h>
 #include <sys/ioctl.h>
 #include "drm.h"
-#include "libdrm.h"
+#include "libdrm_macros.h"
 #include "xf86drm.h"
 #include "radeon_drm.h"
 #include "radeon_surface.h"
@@ -785,7 +785,7 @@ static int eg_surface_init_1d_miptrees(s
 {
     unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
     int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
-    /* Old libdrm headers didn't have stencil_level in it. This prevents crashes. */
+    /* Old libdrm_macros.headers didn't have stencil_level in it. This prevents crashes. */
     struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
     struct radeon_surface_level *stencil_level =
         (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
@@ -807,7 +807,7 @@ static int eg_surface_init_2d_miptrees(s
 {
     unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
     int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
-    /* Old libdrm headers didn't have stencil_level in it. This prevents crashes. */
+    /* Old libdrm_macros.headers didn't have stencil_level in it. This prevents crashes. */
     struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
     struct radeon_surface_level *stencil_level =
         (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
@@ -2400,7 +2400,7 @@ static int cik_surface_best(struct radeo
 /* ===========================================================================
  * public API
  */
-drm_public struct radeon_surface_manager *
+struct radeon_surface_manager *
 radeon_surface_manager_new(int fd)
 {
     struct radeon_surface_manager *surf_man;
@@ -2449,7 +2449,7 @@ out_err:
     return NULL;
 }
 
-drm_public void
+void
 radeon_surface_manager_free(struct radeon_surface_manager *surf_man)
 {
     free(surf_man);
@@ -2522,7 +2522,7 @@ static int radeon_surface_sanity(struct 
     return 0;
 }
 
-drm_public int
+int
 radeon_surface_init(struct radeon_surface_manager *surf_man,
                     struct radeon_surface *surf)
 {
@@ -2539,7 +2539,7 @@ radeon_surface_init(struct radeon_surfac
     return surf_man->surface_init(surf_man, surf);
 }
 
-drm_public int
+int
 radeon_surface_best(struct radeon_surface_manager *surf_man,
                     struct radeon_surface *surf)
 {

Index: xsrc/external/mit/libdrm/dist/tests/modetest/modetest.c
diff -u xsrc/external/mit/libdrm/dist/tests/modetest/modetest.c:1.6 xsrc/external/mit/libdrm/dist/tests/modetest/modetest.c:1.7
--- xsrc/external/mit/libdrm/dist/tests/modetest/modetest.c:1.6	Fri Jan 23 08:25:08 2015
+++ xsrc/external/mit/libdrm/dist/tests/modetest/modetest.c	Mon Jul 20 02:27:06 2015
@@ -50,6 +50,7 @@
 #include <inttypes.h>
 #include <unistd.h>
 #include <string.h>
+#include <strings.h>
 #include <errno.h>
 #include <sys/poll.h>
 #include <sys/time.h>
@@ -110,6 +111,7 @@ struct device {
 
 		unsigned int fb_id;
 		struct bo *bo;
+		struct bo *cursor_bo;
 	} mode;
 };
 
@@ -140,6 +142,9 @@ struct type_name encoder_type_names[] = 
 	{ DRM_MODE_ENCODER_TMDS, "TMDS" },
 	{ DRM_MODE_ENCODER_LVDS, "LVDS" },
 	{ DRM_MODE_ENCODER_TVDAC, "TVDAC" },
+	{ DRM_MODE_ENCODER_VIRTUAL, "Virtual" },
+	{ DRM_MODE_ENCODER_DSI, "DSI" },
+	{ DRM_MODE_ENCODER_DPMST, "DPMST" },
 };
 
 static type_name_fn(encoder_type)
@@ -168,6 +173,8 @@ struct type_name connector_type_names[] 
 	{ DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" },
 	{ DRM_MODE_CONNECTOR_TV, "TV" },
 	{ DRM_MODE_CONNECTOR_eDP, "eDP" },
+	{ DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
+	{ DRM_MODE_CONNECTOR_DSI, "DSI" },
 };
 
 static type_name_fn(connector_type)
@@ -554,11 +561,11 @@ static struct resources *get_resources(s
 	struct resources *res;
 	int i;
 
-	res = malloc(sizeof *res);
+	res = calloc(1, sizeof(*res));
 	if (res == 0)
 		return NULL;
 
-	memset(res, 0, sizeof *res);
+	drmSetClientCap(dev->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
 
 	drmSetClientCap(dev->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
 
@@ -569,19 +576,14 @@ static struct resources *get_resources(s
 		goto error;
 	}
 
-	res->crtcs = malloc(res->res->count_crtcs * sizeof *res->crtcs);
-	res->encoders = malloc(res->res->count_encoders * sizeof *res->encoders);
-	res->connectors = malloc(res->res->count_connectors * sizeof *res->connectors);
-	res->fbs = malloc(res->res->count_fbs * sizeof *res->fbs);
+	res->crtcs = calloc(res->res->count_crtcs, sizeof(*res->crtcs));
+	res->encoders = calloc(res->res->count_encoders, sizeof(*res->encoders));
+	res->connectors = calloc(res->res->count_connectors, sizeof(*res->connectors));
+	res->fbs = calloc(res->res->count_fbs, sizeof(*res->fbs));
 
 	if (!res->crtcs || !res->encoders || !res->connectors || !res->fbs)
 		goto error;
 
-	memset(res->crtcs , 0, res->res->count_crtcs * sizeof *res->crtcs);
-	memset(res->encoders, 0, res->res->count_encoders * sizeof *res->encoders);
-	memset(res->connectors, 0, res->res->count_connectors * sizeof *res->connectors);
-	memset(res->fbs, 0, res->res->count_fbs * sizeof *res->fbs);
-
 #define get_resource(_res, __res, type, Type)					\
 	do {									\
 		int i;								\
@@ -616,8 +618,8 @@ static struct resources *get_resources(s
 					strerror(errno));			\
 				continue;					\
 			}							\
-			obj->props_info = malloc(obj->props->count_props *	\
-						 sizeof *obj->props_info);	\
+			obj->props_info = calloc(obj->props->count_props,	\
+						 sizeof(*obj->props_info));	\
 			if (!obj->props_info)					\
 				continue;					\
 			for (j = 0; j < obj->props->count_props; ++j)		\
@@ -639,12 +641,10 @@ static struct resources *get_resources(s
 		return res;
 	}
 
-	res->planes = malloc(res->plane_res->count_planes * sizeof *res->planes);
+	res->planes = calloc(res->plane_res->count_planes, sizeof(*res->planes));
 	if (!res->planes)
 		goto error;
 
-	memset(res->planes, 0, res->plane_res->count_planes * sizeof *res->planes);
-
 	get_resource(res, plane_res, plane, Plane);
 	get_properties(res, plane_res, plane, PLANE);
 
@@ -730,6 +730,7 @@ struct plane_arg {
 	uint32_t w, h;
 	double scale;
 	unsigned int fb_id;
+	struct bo *bo;
 	char format_str[5]; /* need to leave room for terminating \0 */
 	unsigned int fourcc;
 };
@@ -961,10 +962,22 @@ page_flip_handler(int fd, unsigned int f
 	}
 }
 
+static bool format_support(const drmModePlanePtr ovr, uint32_t fmt)
+{
+	unsigned int i;
+
+	for (i = 0; i < ovr->count_formats; ++i) {
+		if (ovr->formats[i] == fmt)
+			return true;
+	}
+
+	return false;
+}
+
 static int set_plane(struct device *dev, struct plane_arg *p)
 {
 	drmModePlane *ovr;
-	uint32_t handles[4], pitches[4], offsets[4] = {0}; /* we only use [0] */
+	uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
 	uint32_t plane_id = 0;
 	struct bo *plane_bo;
 	uint32_t plane_flags = 0;
@@ -991,7 +1004,7 @@ static int set_plane(struct device *dev,
 
 	for (i = 0; i < dev->resources->plane_res->count_planes && !plane_id; i++) {
 		ovr = dev->resources->planes[i].plane;
-		if (!ovr)
+		if (!ovr || !format_support(ovr, p->fourcc))
 			continue;
 
 		if ((ovr->possible_crtcs & (1 << pipe)) && !ovr->crtc_id)
@@ -1012,6 +1025,8 @@ static int set_plane(struct device *dev,
 	if (plane_bo == NULL)
 		return -1;
 
+	p->bo = plane_bo;
+
 	/* just use single plane format for now.. */
 	if (drmModeAddFB2(dev->fd, p->w, p->h, p->fourcc,
 			handles, pitches, offsets, &p->fb_id, plane_flags)) {
@@ -1044,9 +1059,22 @@ static int set_plane(struct device *dev,
 	return 0;
 }
 
+static void clear_planes(struct device *dev, struct plane_arg *p, unsigned int count)
+{
+	unsigned int i;
+
+	for (i = 0; i < count; i++) {
+		if (p[i].fb_id)
+			drmModeRmFB(dev->fd, p[i].fb_id);
+		if (p[i].bo)
+			bo_destroy(p[i].bo);
+	}
+}
+
+
 static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int count)
 {
-	uint32_t handles[4], pitches[4], offsets[4] = {0}; /* we only use [0] */
+	uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
 	unsigned int fb_id;
 	struct bo *bo;
 	unsigned int i;
@@ -1055,6 +1083,7 @@ static void set_mode(struct device *dev,
 
 	dev->mode.width = 0;
 	dev->mode.height = 0;
+	dev->mode.fb_id = 0;
 
 	for (i = 0; i < count; i++) {
 		struct pipe_arg *pipe = &pipes[i];
@@ -1073,6 +1102,8 @@ static void set_mode(struct device *dev,
 	if (bo == NULL)
 		return;
 
+	dev->mode.bo = bo;
+
 	ret = drmModeAddFB2(dev->fd, dev->mode.width, dev->mode.height,
 			    pipes[0].fourcc, handles, pitches, offsets, &fb_id, 0);
 	if (ret) {
@@ -1081,6 +1112,8 @@ static void set_mode(struct device *dev,
 		return;
 	}
 
+	dev->mode.fb_id = fb_id;
+
 	x = 0;
 	for (i = 0; i < count; i++) {
 		struct pipe_arg *pipe = &pipes[i];
@@ -1108,9 +1141,14 @@ static void set_mode(struct device *dev,
 			return;
 		}
 	}
+}
 
-	dev->mode.bo = bo;
-	dev->mode.fb_id = fb_id;
+static void clear_mode(struct device *dev)
+{
+	if (dev->mode.fb_id)
+		drmModeRmFB(dev->fd, dev->mode.fb_id);
+	if (dev->mode.bo)
+		bo_destroy(dev->mode.bo);
 }
 
 static void set_planes(struct device *dev, struct plane_arg *p, unsigned int count)
@@ -1125,7 +1163,7 @@ static void set_planes(struct device *de
 
 static void set_cursors(struct device *dev, struct pipe_arg *pipes, unsigned int count)
 {
-	uint32_t handles[4], pitches[4], offsets[4] = {0}; /* we only use [0] */
+	uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
 	struct bo *bo;
 	unsigned int i;
 	int ret;
@@ -1142,6 +1180,8 @@ static void set_cursors(struct device *d
 	if (bo == NULL)
 		return;
 
+	dev->mode.cursor_bo = bo;
+
 	for (i = 0; i < count; i++) {
 		struct pipe_arg *pipe = &pipes[i];
 		ret = cursor_init(dev->fd, handles[0],
@@ -1161,11 +1201,14 @@ static void set_cursors(struct device *d
 static void clear_cursors(struct device *dev)
 {
 	cursor_stop();
+
+	if (dev->mode.cursor_bo)
+		bo_destroy(dev->mode.cursor_bo);
 }
 
 static void test_page_flip(struct device *dev, struct pipe_arg *pipes, unsigned int count)
 {
-	uint32_t handles[4], pitches[4], offsets[4] = {0}; /* we only use [0] */
+	uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
 	unsigned int other_fb_id;
 	struct bo *other_bo;
 	drmEventContext evctx;
@@ -1183,7 +1226,7 @@ static void test_page_flip(struct device
 			    &other_fb_id, 0);
 	if (ret) {
 		fprintf(stderr, "failed to add fb: %s\n", strerror(errno));
-		return;
+		goto err;
 	}
 
 	for (i = 0; i < count; i++) {
@@ -1197,7 +1240,7 @@ static void test_page_flip(struct device
 				      pipe);
 		if (ret) {
 			fprintf(stderr, "failed to page flip: %s\n", strerror(errno));
-			return;
+			goto err_rmfb;
 		}
 		gettimeofday(&pipe->start, NULL);
 		pipe->swap_count = 0;
@@ -1249,6 +1292,9 @@ static void test_page_flip(struct device
 		drmHandleEvent(dev->fd, &evctx);
 	}
 
+err_rmfb:
+	drmModeRmFB(dev->fd, other_fb_id);
+err:
 	bo_destroy(other_bo);
 }
 
@@ -1272,7 +1318,7 @@ static int parse_connector(struct pipe_a
 			pipe->num_cons++;
 	}
 
-	pipe->con_ids = malloc(pipe->num_cons * sizeof *pipe->con_ids);
+	pipe->con_ids = calloc(pipe->num_cons, sizeof(*pipe->con_ids));
 	if (pipe->con_ids == NULL)
 		return -1;
 
@@ -1327,8 +1373,6 @@ static int parse_plane(struct plane_arg 
 {
 	char *end;
 
-	memset(plane, 0, sizeof *plane);
-
 	plane->crtc_id = strtoul(p, &end, 10);
 	if (*end != ':')
 		return -EINVAL;
@@ -1453,7 +1497,7 @@ int main(int argc, char **argv)
 	int drop_master = 0;
 	int test_vsync = 0;
 	int test_cursor = 0;
-	const char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos", "tilcdc", "msm", "sti", "tegra" };
+	const char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos", "tilcdc", "msm", "sti", "tegra", "imx-drm", "rockchip", "atmel-hlcdc" };
 	char *device = NULL;
 	char *module = NULL;
 	unsigned int i;
@@ -1500,6 +1544,7 @@ int main(int argc, char **argv)
 				fprintf(stderr, "memory allocation failed\n");
 				return 1;
 			}
+			memset(&plane_args[plane_count], 0, sizeof(*plane_args));
 
 			if (parse_plane(&plane_args[plane_count], optarg) < 0)
 				usage(argv[0]);
@@ -1517,6 +1562,7 @@ int main(int argc, char **argv)
 				fprintf(stderr, "memory allocation failed\n");
 				return 1;
 			}
+			memset(&pipe_args[count], 0, sizeof(*pipe_args));
 
 			if (parse_connector(&pipe_args[count], optarg) < 0)
 				usage(argv[0]);
@@ -1536,6 +1582,7 @@ int main(int argc, char **argv)
 				fprintf(stderr, "memory allocation failed\n");
 				return 1;
 			}
+			memset(&prop_args[prop_count], 0, sizeof(*prop_args));
 
 			if (parse_property(&prop_args[prop_count], optarg) < 0)
 				usage(argv[0]);

Reply via email to