Module Name:    xsrc
Committed By:   mrg
Date:           Mon Jul 15 05:42:35 UTC 2019

Modified Files:
        xsrc/external/mit/libdrm/dist: xf86atomic.h xf86drm.c xf86drm.h
            xf86drmMode.c xf86drmMode.h
        xsrc/external/mit/libdrm/dist/amdgpu: amdgpu_bo.c
        xsrc/external/mit/libdrm/dist/include/drm: drm.h i915_drm.h
        xsrc/external/mit/libdrm/dist/tests/modetest: modetest.c

Log Message:
merge libdrm 2.4.99


To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.13 xsrc/external/mit/libdrm/dist/xf86atomic.h
cvs rdiff -u -r1.23 -r1.24 xsrc/external/mit/libdrm/dist/xf86drm.c
cvs rdiff -u -r1.9 -r1.10 xsrc/external/mit/libdrm/dist/xf86drm.h
cvs rdiff -u -r1.14 -r1.15 xsrc/external/mit/libdrm/dist/xf86drmMode.c
cvs rdiff -u -r1.8 -r1.9 xsrc/external/mit/libdrm/dist/xf86drmMode.h
cvs rdiff -u -r1.3 -r1.4 xsrc/external/mit/libdrm/dist/amdgpu/amdgpu_bo.c
cvs rdiff -u -r1.11 -r1.12 xsrc/external/mit/libdrm/dist/include/drm/drm.h
cvs rdiff -u -r1.6 -r1.7 xsrc/external/mit/libdrm/dist/include/drm/i915_drm.h
cvs rdiff -u -r1.12 -r1.13 \
    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.12 xsrc/external/mit/libdrm/dist/xf86atomic.h:1.13
--- xsrc/external/mit/libdrm/dist/xf86atomic.h:1.12	Mon Mar  4 08:36:42 2019
+++ xsrc/external/mit/libdrm/dist/xf86atomic.h	Mon Jul 15 05:42:34 2019
@@ -101,8 +101,6 @@ typedef struct { volatile LIBDRM_ATOMIC_
 #error libdrm requires atomic operations, please define them for your CPU/compiler.
 #endif
 
-#undef HAS_ATOMIC_OPS
-
 static inline int atomic_add_unless(atomic_t *v, int add, int unless)
 {
 	int c, old;

Index: xsrc/external/mit/libdrm/dist/xf86drm.c
diff -u xsrc/external/mit/libdrm/dist/xf86drm.c:1.23 xsrc/external/mit/libdrm/dist/xf86drm.c:1.24
--- xsrc/external/mit/libdrm/dist/xf86drm.c:1.23	Mon Mar  4 08:36:42 2019
+++ xsrc/external/mit/libdrm/dist/xf86drm.c	Mon Jul 15 05:42:34 2019
@@ -183,7 +183,7 @@ drm_public void drmFree(void *pt)
 }
 
 /**
- * Call ioctl, restarting if it is interupted
+ * Call ioctl, restarting if it is interrupted
  */
 drm_public int
 drmIoctl(int fd, unsigned long request, void *arg)
@@ -293,7 +293,7 @@ static int drmMatchBusID(const char *id1
  *
  * \internal
  * Checks for failure. If failure was caused by signal call chown again.
- * If any other failure happened then it will output error mesage using
+ * If any other failure happened then it will output error message using
  * drmMsg() call.
  */
 #if !UDEV
@@ -754,8 +754,8 @@ drm_public int drmOpen(const char *name,
  */
 drm_public int drmOpenWithType(const char *name, const char *busid, int type)
 {
-    if (!drmAvailable() && name != NULL && drm_server_info &&
-        drm_server_info->load_module) {
+    if (name != NULL && drm_server_info &&
+        drm_server_info->load_module && !drmAvailable()) {
         /* try to load the kernel module */
         if (!drm_server_info->load_module(name)) {
             drmMsg("[drm] failed to load kernel module \"%s\"\n", name);
@@ -1462,7 +1462,7 @@ drm_public int drmDMA(int fd, drmDMAReqP
  *
  * \param fd file descriptor.
  * \param context context.
- * \param flags flags that determine the sate of the hardware when the function
+ * \param flags flags that determine the state of the hardware when the function
  * returns.
  *
  * \return always zero.
@@ -2747,6 +2747,24 @@ drm_public int drmDropMaster(int fd)
         return drmIoctl(fd, DRM_IOCTL_DROP_MASTER, NULL);
 }
 
+drm_public int drmIsMaster(int fd)
+{
+        /* Detect master by attempting something that requires master.
+         *
+         * Authenticating magic tokens requires master and 0 is an
+         * internal kernel detail which we could use. Attempting this on
+         * a master fd would fail therefore fail with EINVAL because 0
+         * is invalid.
+         *
+         * A non-master fd will fail with EACCES, as the kernel checks
+         * for master before attempting to do anything else.
+         *
+         * Since we don't want to leak implementation details, use
+         * EACCES.
+         */
+        return drmAuthMagic(fd, 0) != -EACCES;
+}
+
 drm_public char *drmGetDeviceNameFromFd(int fd)
 {
     char name[128];
@@ -3682,69 +3700,97 @@ free_device:
     return ret;
 }
 
-static int drmParsePlatformBusInfo(int maj, int min, drmPlatformBusInfoPtr info)
+static int drmParseOFBusInfo(int maj, int min, char *fullname)
 {
 #ifdef __linux__
-    char path[PATH_MAX + 1], *name;
+    char path[PATH_MAX + 1], *name, *tmp_name;
 
     snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
 
     name = sysfs_uevent_get(path, "OF_FULLNAME");
-    if (!name)
-        return -ENOENT;
+    tmp_name = name;
+    if (!name) {
+        /* If the device lacks OF data, pick the MODALIAS info */
+        name = sysfs_uevent_get(path, "MODALIAS");
+        if (!name)
+            return -ENOENT;
+
+        /* .. and strip the MODALIAS=[platform,usb...]: part. */
+        tmp_name = strrchr(name, ':');
+        if (!tmp_name) {
+            free(name);
+            return -ENOENT;
+        }
+        tmp_name++;
+    }
 
-    strncpy(info->fullname, name, DRM_PLATFORM_DEVICE_NAME_LEN);
-    info->fullname[DRM_PLATFORM_DEVICE_NAME_LEN - 1] = '\0';
+    strncpy(fullname, tmp_name, DRM_PLATFORM_DEVICE_NAME_LEN);
+    fullname[DRM_PLATFORM_DEVICE_NAME_LEN - 1] = '\0';
     free(name);
 
     return 0;
 #else
-#warning "Missing implementation of drmParsePlatformBusInfo"
+#warning "Missing implementation of drmParseOFBusInfo"
     return -EINVAL;
 #endif
 }
 
-static int drmParsePlatformDeviceInfo(int maj, int min,
-                                      drmPlatformDeviceInfoPtr info)
+static int drmParseOFDeviceInfo(int maj, int min, char ***compatible)
 {
 #ifdef __linux__
-    char path[PATH_MAX + 1], *value;
+    char path[PATH_MAX + 1], *value, *tmp_name;
     unsigned int count, i;
     int err;
 
     snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
 
     value = sysfs_uevent_get(path, "OF_COMPATIBLE_N");
-    if (!value)
-        return -ENOENT;
-
-    sscanf(value, "%u", &count);
-    free(value);
+    if (value) {
+        sscanf(value, "%u", &count);
+        free(value);
+    } else {
+        /* Assume one entry if the device lack OF data */
+        count = 1;
+    }
 
-    info->compatible = calloc(count + 1, sizeof(*info->compatible));
-    if (!info->compatible)
+    *compatible = calloc(count + 1, sizeof(char *));
+    if (!*compatible)
         return -ENOMEM;
 
     for (i = 0; i < count; i++) {
         value = sysfs_uevent_get(path, "OF_COMPATIBLE_%u", i);
+        tmp_name = value;
         if (!value) {
-            err = -ENOENT;
-            goto free;
+            /* If the device lacks OF data, pick the MODALIAS info */
+            value = sysfs_uevent_get(path, "MODALIAS");
+            if (!value) {
+                err = -ENOENT;
+                goto free;
+            }
+
+            /* .. and strip the MODALIAS=[platform,usb...]: part. */
+            tmp_name = strrchr(value, ':');
+            if (!tmp_name) {
+                free(value);
+                return -ENOENT;
+            }
+            tmp_name = strdup(tmp_name + 1);
+            free(value);
         }
 
-        info->compatible[i] = value;
+        (*compatible)[i] = tmp_name;
     }
 
     return 0;
 
 free:
     while (i--)
-        free(info->compatible[i]);
+        free((*compatible)[i]);
 
-    free(info->compatible);
+    free(*compatible);
     return err;
 #else
-#warning "Missing implementation of drmParsePlatformDeviceInfo"
+#warning "Missing implementation of drmParseOFDeviceInfo"
     return -EINVAL;
 #endif
 }
@@ -3767,7 +3813,7 @@ static int drmProcessPlatformDevice(drmD
 
     dev->businfo.platform = (drmPlatformBusInfoPtr)ptr;
 
-    ret = drmParsePlatformBusInfo(maj, min, dev->businfo.platform);
+    ret = drmParseOFBusInfo(maj, min, dev->businfo.platform->fullname);
     if (ret < 0)
         goto free_device;
 
@@ -3775,7 +3821,7 @@ static int drmProcessPlatformDevice(drmD
         ptr += sizeof(drmPlatformBusInfo);
         dev->deviceinfo.platform = (drmPlatformDeviceInfoPtr)ptr;
 
-        ret = drmParsePlatformDeviceInfo(maj, min, dev->deviceinfo.platform);
+        ret = drmParseOFDeviceInfo(maj, min, &dev->deviceinfo.platform->compatible);
         if (ret < 0)
             goto free_device;
     }
@@ -3789,73 +3835,6 @@ free_device:
     return ret;
 }
 
-static int drmParseHost1xBusInfo(int maj, int min, drmHost1xBusInfoPtr info)
-{
-#ifdef __linux__
-    char path[PATH_MAX + 1], *name;
-
-    snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
-
-    name = sysfs_uevent_get(path, "OF_FULLNAME");
-    if (!name)
-        return -ENOENT;
-
-    strncpy(info->fullname, name, DRM_HOST1X_DEVICE_NAME_LEN);
-    info->fullname[DRM_HOST1X_DEVICE_NAME_LEN - 1] = '\0';
-    free(name);
-
-    return 0;
-#else
-#warning "Missing implementation of drmParseHost1xBusInfo"
-    return -EINVAL;
-#endif
-}
-
-static int drmParseHost1xDeviceInfo(int maj, int min,
-                                    drmHost1xDeviceInfoPtr info)
-{
-#ifdef __linux__
-    char path[PATH_MAX + 1], *value;
-    unsigned int count, i;
-    int err;
-
-    snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
-
-    value = sysfs_uevent_get(path, "OF_COMPATIBLE_N");
-    if (!value)
-        return -ENOENT;
-
-    sscanf(value, "%u", &count);
-    free(value);
-
-    info->compatible = calloc(count + 1, sizeof(*info->compatible));
-    if (!info->compatible)
-        return -ENOMEM;
-
-    for (i = 0; i < count; i++) {
-        value = sysfs_uevent_get(path, "OF_COMPATIBLE_%u", i);
-        if (!value) {
-            err = -ENOENT;
-            goto free;
-        }
-
-        info->compatible[i] = value;
-    }
-
-    return 0;
-
-free:
-    while (i--)
-        free(info->compatible[i]);
-
-    free(info->compatible);
-    return err;
-#else
-#warning "Missing implementation of drmParseHost1xDeviceInfo"
-    return -EINVAL;
-#endif
-}
-
 static int drmProcessHost1xDevice(drmDevicePtr *device,
                                   const char *node, int node_type,
                                   int maj, int min, bool fetch_deviceinfo,
@@ -3874,7 +3853,7 @@ static int drmProcessHost1xDevice(drmDev
 
     dev->businfo.host1x = (drmHost1xBusInfoPtr)ptr;
 
-    ret = drmParseHost1xBusInfo(maj, min, dev->businfo.host1x);
+    ret = drmParseOFBusInfo(maj, min, dev->businfo.host1x->fullname);
     if (ret < 0)
         goto free_device;
 
@@ -3882,7 +3861,7 @@ static int drmProcessHost1xDevice(drmDev
         ptr += sizeof(drmHost1xBusInfo);
         dev->deviceinfo.host1x = (drmHost1xDeviceInfoPtr)ptr;
 
-        ret = drmParseHost1xDeviceInfo(maj, min, dev->deviceinfo.host1x);
+        ret = drmParseOFDeviceInfo(maj, min, &dev->deviceinfo.host1x->compatible);
         if (ret < 0)
             goto free_device;
     }
@@ -4449,3 +4428,80 @@ drm_public int drmSyncobjSignal(int fd, 
     ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_SIGNAL, &args);
     return ret;
 }
+
+drm_public int drmSyncobjTimelineSignal(int fd, const uint32_t *handles,
+					uint64_t *points, uint32_t handle_count)
+{
+    struct drm_syncobj_timeline_array args;
+    int ret;
+
+    memclear(args);
+    args.handles = (uintptr_t)handles;
+    args.points = (uintptr_t)points;
+    args.count_handles = handle_count;
+
+    ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, &args);
+    return ret;
+}
+
+drm_public int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t *points,
+				      unsigned num_handles,
+				      int64_t timeout_nsec, unsigned flags,
+				      uint32_t *first_signaled)
+{
+    struct drm_syncobj_timeline_wait args;
+    int ret;
+
+    memclear(args);
+    args.handles = (uintptr_t)handles;
+    args.points = (uintptr_t)points;
+    args.timeout_nsec = timeout_nsec;
+    args.count_handles = num_handles;
+    args.flags = flags;
+
+    ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, &args);
+    if (ret < 0)
+        return -errno;
+
+    if (first_signaled)
+        *first_signaled = args.first_signaled;
+    return ret;
+}
+
+
+drm_public int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
+			       uint32_t handle_count)
+{
+    struct drm_syncobj_timeline_array args;
+    int ret;
+
+    memclear(args);
+    args.handles = (uintptr_t)handles;
+    args.points = (uintptr_t)points;
+    args.count_handles = handle_count;
+
+    ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, &args);
+    if (ret)
+        return ret;
+    return 0;
+}
+
+drm_public int drmSyncobjTransfer(int fd,
+				  uint32_t dst_handle, uint64_t dst_point,
+				  uint32_t src_handle, uint64_t src_point,
+				  uint32_t flags)
+{
+    struct drm_syncobj_transfer args;
+    int ret;
+
+    memclear(args);
+    args.src_handle = src_handle;
+    args.dst_handle = dst_handle;
+    args.src_point = src_point;
+    args.dst_point = dst_point;
+    args.flags = flags;
+
+    ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TRANSFER, &args);
+
+    return ret;
+}

Index: xsrc/external/mit/libdrm/dist/xf86drm.h
diff -u xsrc/external/mit/libdrm/dist/xf86drm.h:1.9 xsrc/external/mit/libdrm/dist/xf86drm.h:1.10
--- xsrc/external/mit/libdrm/dist/xf86drm.h:1.9	Wed Mar 14 07:19:26 2018
+++ xsrc/external/mit/libdrm/dist/xf86drm.h	Mon Jul 15 05:42:34 2019
@@ -742,6 +742,7 @@ extern void drmMsg(const char *format, .
 
 extern int drmSetMaster(int fd);
 extern int drmDropMaster(int fd);
+extern int drmIsMaster(int fd);
 
 #define DRM_EVENT_CONTEXT_VERSION 4
 
@@ -884,6 +885,18 @@ extern int drmSyncobjWait(int fd, uint32
 			  uint32_t *first_signaled);
 extern int drmSyncobjReset(int fd, const uint32_t *handles, uint32_t handle_count);
 extern int drmSyncobjSignal(int fd, const uint32_t *handles, uint32_t handle_count);
+extern int drmSyncobjTimelineSignal(int fd, const uint32_t *handles,
+				    uint64_t *points, uint32_t handle_count);
+extern int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t *points,
+				  unsigned num_handles,
+				  int64_t timeout_nsec, unsigned flags,
+				  uint32_t *first_signaled);
+extern int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
+			   uint32_t handle_count);
+extern int drmSyncobjTransfer(int fd,
+			      uint32_t dst_handle, uint64_t dst_point,
+			      uint32_t src_handle, uint64_t src_point,
+			      uint32_t flags);
 
 #if defined(__cplusplus)
 }

Index: xsrc/external/mit/libdrm/dist/xf86drmMode.c
diff -u xsrc/external/mit/libdrm/dist/xf86drmMode.c:1.14 xsrc/external/mit/libdrm/dist/xf86drmMode.c:1.15
--- xsrc/external/mit/libdrm/dist/xf86drmMode.c:1.14	Thu Jan 10 08:59:43 2019
+++ xsrc/external/mit/libdrm/dist/xf86drmMode.c	Mon Jul 15 05:42:34 2019
@@ -650,7 +650,7 @@ drm_public drmModePropertyPtr drmModeGet
 	}
 
 	if (!(r = drmMalloc(sizeof(*r))))
-		return NULL;
+		goto err_allocs;
 
 	r->prop_id = prop.prop_id;
 	r->count_values = prop.count_values;
@@ -1259,7 +1259,7 @@ drm_public drmModeAtomicReqPtr drmModeAt
 			return NULL;
 		}
 		memcpy(new->items, old->items,
-		       old->size_items * sizeof(*new->items));
+		       old->cursor * sizeof(*new->items));
 	} else {
 		new->items = NULL;
 	}
@@ -1322,12 +1322,13 @@ drm_public int drmModeAtomicAddProperty(
 		return -EINVAL;
 
 	if (req->cursor >= req->size_items) {
+		const uint32_t item_size_inc = getpagesize() / sizeof(*req->items);
 		drmModeAtomicReqItemPtr new;
 
-		req->size_items += 16;
+		req->size_items += item_size_inc;
 		new = realloc(req->items, req->size_items * sizeof(*req->items));
 		if (!new) {
-			req->size_items -= 16;
+			req->size_items -= item_size_inc;
 			return -ENOMEM;
 		}
 		req->items = new;

Index: xsrc/external/mit/libdrm/dist/xf86drmMode.h
diff -u xsrc/external/mit/libdrm/dist/xf86drmMode.h:1.8 xsrc/external/mit/libdrm/dist/xf86drmMode.h:1.9
--- xsrc/external/mit/libdrm/dist/xf86drmMode.h:1.8	Wed Mar 14 07:19:26 2018
+++ xsrc/external/mit/libdrm/dist/xf86drmMode.h	Mon Jul 15 05:42:34 2019
@@ -49,12 +49,12 @@ extern "C" {
  * header defining uint32_t, int32_t and uint16_t.
  *
  * It aims to provide a randr1.2 compatible interface for modesettings in the
- * kernel, the interface is also ment to be used by libraries like EGL.
+ * kernel, the interface is also meant to be used by libraries like EGL.
  *
  * More information can be found in randrproto.txt which can be found here:
  * http://gitweb.freedesktop.org/?p=xorg/proto/randrproto.git
  *
- * There are some major diffrences to be noted. Unlike the randr1.2 proto you
+ * There are some major differences to be noted. Unlike the randr1.2 proto you
  * need to create the memory object of the framebuffer yourself with the ttm
  * buffer object interface. This object needs to be pinned.
  */
@@ -348,7 +348,7 @@ extern void drmModeFreePlane( drmModePla
 extern void drmModeFreePlaneResources(drmModePlaneResPtr ptr);
 
 /**
- * Retrives all of the resources associated with a card.
+ * Retrieves all of the resources associated with a card.
  */
 extern drmModeResPtr drmModeGetResources(int fd);
 
@@ -357,7 +357,7 @@ extern drmModeResPtr drmModeGetResources
  */
 
 /**
- * Retrive information about framebuffer bufferId
+ * Retrieve information about framebuffer bufferId
  */
 extern drmModeFBPtr drmModeGetFB(int fd, uint32_t bufferId);
 
@@ -397,7 +397,7 @@ extern int drmModeDirtyFB(int fd, uint32
  */
 
 /**
- * Retrive information about the ctrt crtcId
+ * Retrieve information about the ctrt crtcId
  */
 extern drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId);
 

Index: xsrc/external/mit/libdrm/dist/amdgpu/amdgpu_bo.c
diff -u xsrc/external/mit/libdrm/dist/amdgpu/amdgpu_bo.c:1.3 xsrc/external/mit/libdrm/dist/amdgpu/amdgpu_bo.c:1.4
--- xsrc/external/mit/libdrm/dist/amdgpu/amdgpu_bo.c:1.3	Mon Mar  4 08:36:42 2019
+++ xsrc/external/mit/libdrm/dist/amdgpu/amdgpu_bo.c	Mon Jul 15 05:42:34 2019
@@ -39,13 +39,12 @@
 #include "amdgpu_internal.h"
 #include "util_math.h"
 
-static void amdgpu_close_kms_handle(amdgpu_device_handle dev,
-				     uint32_t handle)
+static int amdgpu_close_kms_handle(int fd, uint32_t handle)
 {
 	struct drm_gem_close args = {};
 
 	args.handle = handle;
-	drmIoctl(dev->fd, DRM_IOCTL_GEM_CLOSE, &args);
+	return drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &args);
 }
 
 static int amdgpu_bo_create(amdgpu_device_handle dev,
@@ -54,11 +53,18 @@ static int amdgpu_bo_create(amdgpu_devic
 			    amdgpu_bo_handle *buf_handle)
 {
 	struct amdgpu_bo *bo;
+	int r;
 
 	bo = calloc(1, sizeof(struct amdgpu_bo));
 	if (!bo)
 		return -ENOMEM;
 
+	r = handle_table_insert(&dev->bo_handles, handle, bo);
+	if (r) {
+		free(bo);
+		return r;
+	}
+
 	atomic_set(&bo->refcount, 1);
 	bo->dev = dev;
 	bo->alloc_size = size;
@@ -90,19 +96,14 @@ drm_public int amdgpu_bo_alloc(amdgpu_de
 	if (r)
 		goto out;
 
+	pthread_mutex_lock(&dev->bo_table_mutex);
 	r = amdgpu_bo_create(dev, alloc_buffer->alloc_size, args.out.handle,
 			     buf_handle);
+	pthread_mutex_unlock(&dev->bo_table_mutex);
 	if (r) {
-		amdgpu_close_kms_handle(dev, args.out.handle);
-		goto out;
+		amdgpu_close_kms_handle(dev->fd, args.out.handle);
 	}
 
-	pthread_mutex_lock(&dev->bo_table_mutex);
-	r = handle_table_insert(&dev->bo_handles, (*buf_handle)->handle,
-				*buf_handle);
-	pthread_mutex_unlock(&dev->bo_table_mutex);
-	if (r)
-		amdgpu_bo_free(*buf_handle);
 out:
 	return r;
 }
@@ -214,11 +215,8 @@ static int amdgpu_bo_export_flink(amdgpu
 
 	bo->flink_name = flink.name;
 
-	if (bo->dev->flink_fd != bo->dev->fd) {
-		struct drm_gem_close args = {};
-		args.handle = handle;
-		drmIoctl(bo->dev->flink_fd, DRM_IOCTL_GEM_CLOSE, &args);
-	}
+	if (bo->dev->flink_fd != bo->dev->fd)
+		amdgpu_close_kms_handle(bo->dev->flink_fd, handle);
 
 	pthread_mutex_lock(&bo->dev->bo_table_mutex);
 	r = handle_table_insert(&bo->dev->bo_flink_names, bo->flink_name, bo);
@@ -261,7 +259,6 @@ drm_public int amdgpu_bo_import(amdgpu_d
 		     struct amdgpu_bo_import_result *output)
 {
 	struct drm_gem_open open_arg = {};
-	struct drm_gem_close close_arg = {};
 	struct amdgpu_bo *bo = NULL;
 	uint32_t handle = 0, flink_name = 0;
 	uint64_t alloc_size = 0;
@@ -345,12 +342,12 @@ drm_public int amdgpu_bo_import(amdgpu_d
 			close(dma_fd);
 			if (r)
 				goto free_bo_handle;
-			close_arg.handle = open_arg.handle;
-			r = drmIoctl(dev->flink_fd, DRM_IOCTL_GEM_CLOSE,
-				     &close_arg);
+			r = amdgpu_close_kms_handle(dev->flink_fd,
+						    open_arg.handle);
 			if (r)
 				goto free_bo_handle;
 		}
+		open_arg.handle = 0;
 		break;
 
 	case amdgpu_bo_handle_type_dma_buf_fd:
@@ -368,15 +365,12 @@ drm_public int amdgpu_bo_import(amdgpu_d
 	if (r)
 		goto free_bo_handle;
 
-	r = handle_table_insert(&dev->bo_handles, bo->handle, bo);
-	if (r)
-		goto free_bo_handle;
 	if (flink_name) {
 		bo->flink_name = flink_name;
 		r = handle_table_insert(&dev->bo_flink_names, flink_name,
 					bo);
 		if (r)
-			goto remove_handle;
+			goto free_bo_handle;
 
 	}
 
@@ -385,17 +379,14 @@ drm_public int amdgpu_bo_import(amdgpu_d
 	pthread_mutex_unlock(&dev->bo_table_mutex);
 	return 0;
 
-remove_handle:
-	handle_table_remove(&dev->bo_handles, bo->handle);
 free_bo_handle:
-	if (flink_name && !close_arg.handle && open_arg.handle) {
-		close_arg.handle = open_arg.handle;
-		drmIoctl(dev->flink_fd, DRM_IOCTL_GEM_CLOSE, &close_arg);
-	}
+	if (flink_name && open_arg.handle)
+		amdgpu_close_kms_handle(dev->flink_fd, open_arg.handle);
+
 	if (bo)
 		amdgpu_bo_free(bo);
 	else
-		amdgpu_close_kms_handle(dev, handle);
+		amdgpu_close_kms_handle(dev->fd, handle);
 unlock:
 	pthread_mutex_unlock(&dev->bo_table_mutex);
 	return r;
@@ -424,12 +415,13 @@ drm_public int amdgpu_bo_free(amdgpu_bo_
 			amdgpu_bo_cpu_unmap(bo);
 		}
 
-		amdgpu_close_kms_handle(dev, bo->handle);
+		amdgpu_close_kms_handle(dev->fd, bo->handle);
 		pthread_mutex_destroy(&bo->cpu_access_mutex);
 		free(bo);
 	}
 
 	pthread_mutex_unlock(&dev->bo_table_mutex);
+
 	return 0;
 }
 
@@ -602,18 +594,13 @@ drm_public int amdgpu_create_bo_from_use
 	if (r)
 		goto out;
 
+	pthread_mutex_lock(&dev->bo_table_mutex);
 	r = amdgpu_bo_create(dev, size, args.handle, buf_handle);
+	pthread_mutex_unlock(&dev->bo_table_mutex);
 	if (r) {
-		amdgpu_close_kms_handle(dev, args.handle);
-		goto out;
+		amdgpu_close_kms_handle(dev->fd, args.handle);
 	}
 
-	pthread_mutex_lock(&dev->bo_table_mutex);
-	r = handle_table_insert(&dev->bo_handles, (*buf_handle)->handle,
-				*buf_handle);
-	pthread_mutex_unlock(&dev->bo_table_mutex);
-	if (r)
-		amdgpu_bo_free(*buf_handle);
 out:
 	return r;
 }

Index: xsrc/external/mit/libdrm/dist/include/drm/drm.h
diff -u xsrc/external/mit/libdrm/dist/include/drm/drm.h:1.11 xsrc/external/mit/libdrm/dist/include/drm/drm.h:1.12
--- xsrc/external/mit/libdrm/dist/include/drm/drm.h:1.11	Thu Jan 10 08:59:43 2019
+++ xsrc/external/mit/libdrm/dist/include/drm/drm.h	Mon Jul 15 05:42:34 2019
@@ -44,6 +44,7 @@ typedef unsigned int drm_handle_t;
 
 #else /* One of the BSDs */
 
+#include <stdint.h>
 #include <sys/ioccom.h>
 #include <sys/types.h>
 #ifndef __linux_sized_types__
@@ -646,6 +647,7 @@ struct drm_gem_open {
 #define DRM_CAP_PAGE_FLIP_TARGET	0x11
 #define DRM_CAP_CRTC_IN_VBLANK_EVENT	0x12
 #define DRM_CAP_SYNCOBJ		0x13
+#define DRM_CAP_SYNCOBJ_TIMELINE	0x14
 
 /** DRM_IOCTL_GET_CAP ioctl argument type */
 struct drm_get_cap {
@@ -732,8 +734,18 @@ struct drm_syncobj_handle {
 	__u32 pad;
 };
 
+struct drm_syncobj_transfer {
+	__u32 src_handle;
+	__u32 dst_handle;
+	__u64 src_point;
+	__u64 dst_point;
+	__u32 flags;
+	__u32 pad;
+};
+
 #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0)
 #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1)
+#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE (1 << 2) /* wait for time point to become available */
 struct drm_syncobj_wait {
 	__u64 handles;
 	/* absolute timeout */
@@ -744,12 +756,33 @@ struct drm_syncobj_wait {
 	__u32 pad;
 };
 
+struct drm_syncobj_timeline_wait {
+	__u64 handles;
+	/* wait on specific timeline point for every handles*/
+	__u64 points;
+	/* absolute timeout */
+	__s64 timeout_nsec;
+	__u32 count_handles;
+	__u32 flags;
+	__u32 first_signaled; /* only valid when not waiting all */
+	__u32 pad;
+};
+
+
 struct drm_syncobj_array {
 	__u64 handles;
 	__u32 count_handles;
 	__u32 pad;
 };
 
+struct drm_syncobj_timeline_array {
+	__u64 handles;
+	__u64 points;
+	__u32 count_handles;
+	__u32 pad;
+};
+
+
 /* Query current scanout sequence number */
 struct drm_crtc_get_sequence {
 	__u32 crtc_id;		/* requested crtc_id */
@@ -906,6 +939,11 @@ extern "C" {
 #define DRM_IOCTL_MODE_GET_LEASE	DRM_IOWR(0xC8, struct drm_mode_get_lease)
 #define DRM_IOCTL_MODE_REVOKE_LEASE	DRM_IOWR(0xC9, struct drm_mode_revoke_lease)
 
+#define DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT	DRM_IOWR(0xCA, struct drm_syncobj_timeline_wait)
+#define DRM_IOCTL_SYNCOBJ_QUERY		DRM_IOWR(0xCB, struct drm_syncobj_timeline_array)
+#define DRM_IOCTL_SYNCOBJ_TRANSFER	DRM_IOWR(0xCC, struct drm_syncobj_transfer)
+#define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL	DRM_IOWR(0xCD, struct drm_syncobj_timeline_array)
+
 /**
  * Device specific ioctls should only be in their respective headers
  * The device specific ioctl range is from 0x40 to 0x9f.

Index: xsrc/external/mit/libdrm/dist/include/drm/i915_drm.h
diff -u xsrc/external/mit/libdrm/dist/include/drm/i915_drm.h:1.6 xsrc/external/mit/libdrm/dist/include/drm/i915_drm.h:1.7
--- xsrc/external/mit/libdrm/dist/include/drm/i915_drm.h:1.6	Thu Jan 10 08:59:43 2019
+++ xsrc/external/mit/libdrm/dist/include/drm/i915_drm.h	Mon Jul 15 05:42:34 2019
@@ -63,6 +63,28 @@ extern "C" {
 #define I915_RESET_UEVENT		"RESET"
 
 /*
+ * i915_user_extension: Base class for defining a chain of extensions
+ *
+ * Many interfaces need to grow over time. In most cases we can simply
+ * extend the struct and have userspace pass in more data. Another option,
+ * as demonstrated by Vulkan's approach to providing extensions for forward
+ * and backward compatibility, is to use a list of optional structs to
+ * provide those extra details.
+ *
+ * The key advantage to using an extension chain is that it allows us to
+ * redefine the interface more easily than an ever growing struct of
+ * increasing complexity, and for large parts of that interface to be
+ * entirely optional. The downside is more pointer chasing; chasing across
+ * the boundary with pointers encapsulated inside u64.
+ */
+struct i915_user_extension {
+	__u64 next_extension;
+	__u32 name;
+	__u32 flags; /* All undefined bits must be zero. */
+	__u32 rsvd[4]; /* Reserved for future use; must be zero. */
+};
+
+/*
  * MOCS indexes used for GPU surfaces, defining the cacheability of the
  * surface data and the coherency for this data wrt. CPU vs. GPU accesses.
  */
@@ -99,6 +121,8 @@ enum drm_i915_gem_engine_class {
 	I915_ENGINE_CLASS_VIDEO		= 2,
 	I915_ENGINE_CLASS_VIDEO_ENHANCE	= 3,
 
+	/* should be kept compact */
+
 	I915_ENGINE_CLASS_INVALID	= -1
 };
 
@@ -319,6 +343,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_I915_PERF_ADD_CONFIG	0x37
 #define DRM_I915_PERF_REMOVE_CONFIG	0x38
 #define DRM_I915_QUERY			0x39
+/* Must be kept compact -- no holes */
 
 #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)
@@ -367,6 +392,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_IOCTL_I915_GET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey)
 #define DRM_IOCTL_I915_GEM_WAIT		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_WAIT, struct drm_i915_gem_wait)
 #define DRM_IOCTL_I915_GEM_CONTEXT_CREATE	DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE, struct drm_i915_gem_context_create)
+#define DRM_IOCTL_I915_GEM_CONTEXT_CREATE_EXT	DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE, struct drm_i915_gem_context_create_ext)
 #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)
@@ -412,6 +438,14 @@ typedef struct drm_i915_irq_wait {
 	int irq_seq;
 } drm_i915_irq_wait_t;
 
+/*
+ * Different modes of per-process Graphics Translation Table,
+ * see I915_PARAM_HAS_ALIASING_PPGTT
+ */
+#define I915_GEM_PPGTT_NONE	0
+#define I915_GEM_PPGTT_ALIASING	1
+#define I915_GEM_PPGTT_FULL	2
+
 /* Ioctl to query kernel params:
  */
 #define I915_PARAM_IRQ_ACTIVE            1
@@ -468,6 +502,7 @@ typedef struct drm_i915_irq_wait {
 #define   I915_SCHEDULER_CAP_ENABLED	(1ul << 0)
 #define   I915_SCHEDULER_CAP_PRIORITY	(1ul << 1)
 #define   I915_SCHEDULER_CAP_PREEMPTION	(1ul << 2)
+#define   I915_SCHEDULER_CAP_SEMAPHORES	(1ul << 3)
 
 #define I915_PARAM_HUC_STATUS		 42
 
@@ -485,7 +520,7 @@ typedef struct drm_i915_irq_wait {
 #define I915_PARAM_HAS_EXEC_FENCE	 44
 
 /* Query whether DRM_I915_GEM_EXECBUFFER2 supports the ability to capture
- * user specified bufffers for post-mortem debugging of GPU hangs. See
+ * user specified buffers for post-mortem debugging of GPU hangs. See
  * EXEC_OBJECT_CAPTURE.
  */
 #define I915_PARAM_HAS_EXEC_CAPTURE	 45
@@ -551,6 +586,8 @@ typedef struct drm_i915_irq_wait {
  */
 #define I915_PARAM_MMAP_GTT_COHERENT	52
 
+/* Must be kept compact -- no holes and well documented */
+
 typedef struct drm_i915_getparam {
 	__s32 param;
 	/*
@@ -566,6 +603,7 @@ typedef struct drm_i915_getparam {
 #define I915_SETPARAM_TEX_LRU_LOG_GRANULARITY             2
 #define I915_SETPARAM_ALLOW_BATCHBUFFER                   3
 #define I915_SETPARAM_NUM_USED_FENCES                     4
+/* Must be kept compact -- no holes */
 
 typedef struct drm_i915_setparam {
 	int param;
@@ -964,7 +1002,7 @@ struct drm_i915_gem_execbuffer2 {
 	 * struct drm_i915_gem_exec_fence *fences.
 	 */
 	__u64 cliprects_ptr;
-#define I915_EXEC_RING_MASK              (7<<0)
+#define I915_EXEC_RING_MASK              (0x3f)
 #define I915_EXEC_DEFAULT                (0<<0)
 #define I915_EXEC_RENDER                 (1<<0)
 #define I915_EXEC_BSD                    (2<<0)
@@ -1112,32 +1150,34 @@ struct drm_i915_gem_busy {
 	 * as busy may become idle before the ioctl is completed.
 	 *
 	 * Furthermore, if the object is busy, which engine is busy is only
-	 * provided as a guide. There are race conditions which prevent the
-	 * report of which engines are busy from being always accurate.
-	 * However, the converse is not true. If the object is idle, the
-	 * result of the ioctl, that all engines are idle, is accurate.
+	 * provided as a guide and only indirectly by reporting its class
+	 * (there may be more than one engine in each class). There are race
+	 * conditions which prevent the report of which engines are busy from
+	 * being always accurate.  However, the converse is not true. If the
+	 * object is idle, the result of the ioctl, that all engines are idle,
+	 * is accurate.
 	 *
 	 * The returned dword is split into two fields to indicate both
-	 * the engines on which the object is being read, and the
-	 * engine on which it is currently being written (if any).
+	 * the engine classess on which the object is being read, and the
+	 * engine class on which it is currently being written (if any).
 	 *
 	 * The low word (bits 0:15) indicate if the object is being written
 	 * to by any engine (there can only be one, as the GEM implicit
 	 * synchronisation rules force writes to be serialised). Only the
-	 * engine for the last write is reported.
+	 * engine class (offset by 1, I915_ENGINE_CLASS_RENDER is reported as
+	 * 1 not 0 etc) for the last write is reported.
 	 *
-	 * The high word (bits 16:31) are a bitmask of which engines are
-	 * currently reading from the object. Multiple engines may be
+	 * The high word (bits 16:31) are a bitmask of which engines classes
+	 * are currently reading from the object. Multiple engines may be
 	 * reading from the object simultaneously.
 	 *
-	 * The value of each engine is the same as specified in the
-	 * EXECBUFFER2 ioctl, i.e. I915_EXEC_RENDER, I915_EXEC_BSD etc.
-	 * Note I915_EXEC_DEFAULT is a symbolic value and is mapped to
-	 * the I915_EXEC_RENDER engine for execution, and so it is never
+	 * The value of each engine class is the same as specified in the
+	 * I915_CONTEXT_SET_ENGINES parameter and via perf, i.e.
+	 * I915_ENGINE_CLASS_RENDER, I915_ENGINE_CLASS_COPY, etc.
 	 * reported as active itself. Some hardware may have parallel
 	 * execution engines, e.g. multiple media engines, which are
-	 * mapped to the same identifier in the EXECBUFFER2 ioctl and
-	 * so are not separately reported for busyness.
+	 * mapped to the same class identifier and so are not separately
+	 * reported for busyness.
 	 *
 	 * Caveat emptor:
 	 * Only the boolean result of this query is reliable; that is whether
@@ -1180,7 +1220,7 @@ struct drm_i915_gem_caching {
 	__u32 handle;
 
 	/**
-	 * Cacheing level to apply or return value
+	 * Caching level to apply or return value
 	 *
 	 * bits0-15 are for generic caching control (i.e. the above defined
 	 * values). bits16-31 are reserved for platform-specific variations
@@ -1404,16 +1444,159 @@ struct drm_i915_gem_wait {
 };
 
 struct drm_i915_gem_context_create {
-	/*  output: id of new context*/
-	__u32 ctx_id;
+	__u32 ctx_id; /* output: id of new context*/
 	__u32 pad;
 };
 
+struct drm_i915_gem_context_create_ext {
+	__u32 ctx_id; /* output: id of new context*/
+	__u32 flags;
+#define I915_CONTEXT_CREATE_FLAGS_USE_EXTENSIONS	(1u << 0)
+#define I915_CONTEXT_CREATE_FLAGS_UNKNOWN \
+	(-(I915_CONTEXT_CREATE_FLAGS_USE_EXTENSIONS << 1))
+	__u64 extensions;
+};
+
+struct drm_i915_gem_context_param {
+	__u32 ctx_id;
+	__u32 size;
+	__u64 param;
+#define I915_CONTEXT_PARAM_BAN_PERIOD	0x1
+#define I915_CONTEXT_PARAM_NO_ZEROMAP	0x2
+#define I915_CONTEXT_PARAM_GTT_SIZE	0x3
+#define I915_CONTEXT_PARAM_NO_ERROR_CAPTURE	0x4
+#define I915_CONTEXT_PARAM_BANNABLE	0x5
+#define I915_CONTEXT_PARAM_PRIORITY	0x6
+#define   I915_CONTEXT_MAX_USER_PRIORITY	1023 /* inclusive */
+#define   I915_CONTEXT_DEFAULT_PRIORITY		0
+#define   I915_CONTEXT_MIN_USER_PRIORITY	-1023 /* inclusive */
+	/*
+	 * When using the following param, value should be a pointer to
+	 * drm_i915_gem_context_param_sseu.
+	 */
+#define I915_CONTEXT_PARAM_SSEU		0x7
+
+/*
+ * Not all clients may want to attempt automatic recover of a context after
+ * a hang (for example, some clients may only submit very small incremental
+ * batches relying on known logical state of previous batches which will never
+ * recover correctly and each attempt will hang), and so would prefer that
+ * the context is forever banned instead.
+ *
+ * If set to false (0), after a reset, subsequent (and in flight) rendering
+ * from this context is discarded, and the client will need to create a new
+ * context to use instead.
+ *
+ * If set to true (1), the kernel will automatically attempt to recover the
+ * context by skipping the hanging batch and executing the next batch starting
+ * from the default context state (discarding the incomplete logical context
+ * state lost due to the reset).
+ *
+ * On creation, all new contexts are marked as recoverable.
+ */
+#define I915_CONTEXT_PARAM_RECOVERABLE	0x8
+/* Must be kept compact -- no holes and well documented */
+
+	__u64 value;
+};
+
+/**
+ * Context SSEU programming
+ *
+ * It may be necessary for either functional or performance reason to configure
+ * a context to run with a reduced number of SSEU (where SSEU stands for Slice/
+ * Sub-slice/EU).
+ *
+ * This is done by configuring SSEU configuration using the below
+ * @struct drm_i915_gem_context_param_sseu for every supported engine which
+ * userspace intends to use.
+ *
+ * Not all GPUs or engines support this functionality in which case an error
+ * code -ENODEV will be returned.
+ *
+ * Also, flexibility of possible SSEU configuration permutations varies between
+ * GPU generations and software imposed limitations. Requesting such a
+ * combination will return an error code of -EINVAL.
+ *
+ * NOTE: When perf/OA is active the context's SSEU configuration is ignored in
+ * favour of a single global setting.
+ */
+struct drm_i915_gem_context_param_sseu {
+	/*
+	 * Engine class & instance to be configured or queried.
+	 */
+	__u16 engine_class;
+	__u16 engine_instance;
+
+	/*
+	 * Unused for now. Must be cleared to zero.
+	 */
+	__u32 flags;
+
+	/*
+	 * Mask of slices to enable for the context. Valid values are a subset
+	 * of the bitmask value returned for I915_PARAM_SLICE_MASK.
+	 */
+	__u64 slice_mask;
+
+	/*
+	 * Mask of subslices to enable for the context. Valid values are a
+	 * subset of the bitmask value return by I915_PARAM_SUBSLICE_MASK.
+	 */
+	__u64 subslice_mask;
+
+	/*
+	 * Minimum/Maximum number of EUs to enable per subslice for the
+	 * context. min_eus_per_subslice must be inferior or equal to
+	 * max_eus_per_subslice.
+	 */
+	__u16 min_eus_per_subslice;
+	__u16 max_eus_per_subslice;
+
+	/*
+	 * Unused for now. Must be cleared to zero.
+	 */
+	__u32 rsvd;
+};
+
+struct drm_i915_gem_context_create_ext_setparam {
+#define I915_CONTEXT_CREATE_EXT_SETPARAM 0
+	struct i915_user_extension base;
+	struct drm_i915_gem_context_param param;
+};
+
 struct drm_i915_gem_context_destroy {
 	__u32 ctx_id;
 	__u32 pad;
 };
 
+/*
+ * DRM_I915_GEM_VM_CREATE -
+ *
+ * Create a new virtual memory address space (ppGTT) for use within a context
+ * on the same file. Extensions can be provided to configure exactly how the
+ * address space is setup upon creation.
+ *
+ * The id of new VM (bound to the fd) for use with I915_CONTEXT_PARAM_VM is
+ * returned in the outparam @id.
+ *
+ * No flags are defined, with all bits reserved and must be zero.
+ *
+ * An extension chain maybe provided, starting with @extensions, and terminated
+ * by the @next_extension being 0. Currently, no extensions are defined.
+ *
+ * DRM_I915_GEM_VM_DESTROY -
+ *
+ * Destroys a previously created VM id, specified in @id.
+ *
+ * No extensions or flags are allowed currently, and so must be zero.
+ */
+struct drm_i915_gem_vm_control {
+	__u64 extensions;
+	__u32 flags;
+	__u32 vm_id;
+};
+
 struct drm_i915_reg_read {
 	/*
 	 * Register offset.
@@ -1426,6 +1609,7 @@ struct drm_i915_reg_read {
 
 	__u64 val; /* Return value */
 };
+
 /* Known registers:
  *
  * Render engine timestamp - 0x2358 + 64bit - gen7+
@@ -1465,22 +1649,6 @@ struct drm_i915_gem_userptr {
 	__u32 handle;
 };
 
-struct drm_i915_gem_context_param {
-	__u32 ctx_id;
-	__u32 size;
-	__u64 param;
-#define I915_CONTEXT_PARAM_BAN_PERIOD	0x1
-#define I915_CONTEXT_PARAM_NO_ZEROMAP	0x2
-#define I915_CONTEXT_PARAM_GTT_SIZE	0x3
-#define I915_CONTEXT_PARAM_NO_ERROR_CAPTURE	0x4
-#define I915_CONTEXT_PARAM_BANNABLE	0x5
-#define I915_CONTEXT_PARAM_PRIORITY	0x6
-#define   I915_CONTEXT_MAX_USER_PRIORITY	1023 /* inclusive */
-#define   I915_CONTEXT_DEFAULT_PRIORITY		0
-#define   I915_CONTEXT_MIN_USER_PRIORITY	-1023 /* inclusive */
-	__u64 value;
-};
-
 enum drm_i915_oa_format {
 	I915_OA_FORMAT_A13 = 1,	    /* HSW only */
 	I915_OA_FORMAT_A29,	    /* HSW only */
@@ -1642,6 +1810,7 @@ struct drm_i915_perf_oa_config {
 struct drm_i915_query_item {
 	__u64 query_id;
 #define DRM_I915_QUERY_TOPOLOGY_INFO    1
+/* Must be kept compact -- no holes and well documented */
 
 	/*
 	 * When set to zero by userspace, this is filled with the size of the

Index: xsrc/external/mit/libdrm/dist/tests/modetest/modetest.c
diff -u xsrc/external/mit/libdrm/dist/tests/modetest/modetest.c:1.12 xsrc/external/mit/libdrm/dist/tests/modetest/modetest.c:1.13
--- xsrc/external/mit/libdrm/dist/tests/modetest/modetest.c:1.12	Thu Jan 10 08:59:43 2019
+++ xsrc/external/mit/libdrm/dist/tests/modetest/modetest.c	Mon Jul 15 05:42:34 2019
@@ -67,6 +67,9 @@
 #include "buffers.h"
 #include "cursor.h"
 
+static enum util_fill_pattern primary_fill = UTIL_PATTERN_SMPTE;
+static enum util_fill_pattern secondary_fill = UTIL_PATTERN_TILES;
+
 struct crtc {
 	drmModeCrtc *crtc;
 	drmModeObjectProperties *props;
@@ -293,6 +296,8 @@ static const char *modifier_to_string(ui
 		return "NVIDIA_16BX2_BLOCK(5)";
 	case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED:
 		return "MOD_BROADCOM_VC4_T_TILED";
+	case DRM_FORMAT_MOD_QCOM_COMPRESSED:
+		return "QCOM_COMPRESSED";
 	default:
 		return "(UNKNOWN MODIFIER)";
 	}
@@ -946,9 +951,10 @@ struct property_arg {
 	char name[DRM_PROP_NAME_LEN+1];
 	uint32_t prop_id;
 	uint64_t value;
+	bool optional;
 };
 
-static void set_property(struct device *dev, struct property_arg *p)
+static bool set_property(struct device *dev, struct property_arg *p)
 {
 	drmModeObjectProperties *props = NULL;
 	drmModePropertyRes **props_info = NULL;
@@ -980,13 +986,13 @@ static void set_property(struct device *
 	if (p->obj_type == 0) {
 		fprintf(stderr, "Object %i not found, can't set property\n",
 			p->obj_id);
-			return;
+		return false;
 	}
 
 	if (!props) {
 		fprintf(stderr, "%s %i has no properties\n",
 			obj_type, p->obj_id);
-		return;
+		return false;
 	}
 
 	for (i = 0; i < (int)props->count_props; ++i) {
@@ -997,9 +1003,10 @@ static void set_property(struct device *
 	}
 
 	if (i == (int)props->count_props) {
-		fprintf(stderr, "%s %i has no %s property\n",
-			obj_type, p->obj_id, p->name);
-		return;
+		if (!p->optional)
+			fprintf(stderr, "%s %i has no %s property\n",
+				obj_type, p->obj_id, p->name);
+		return false;
 	}
 
 	p->prop_id = props->props[i];
@@ -1013,6 +1020,8 @@ static void set_property(struct device *
 	if (ret < 0)
 		fprintf(stderr, "failed to set %s %i property %s to %" PRIu64 ": %s\n",
 			obj_type, p->obj_id, p->name, p->value, strerror(errno));
+
+	return true;
 }
 
 /* -------------------------------------------------------------------------- */
@@ -1070,6 +1079,55 @@ static void add_property(struct device *
 	set_property(dev, &p);
 }
 
+static bool add_property_optional(struct device *dev, uint32_t obj_id,
+				  const char *name, uint64_t value)
+{
+	struct property_arg p;
+
+	p.obj_id = obj_id;
+	strcpy(p.name, name);
+	p.value = value;
+	p.optional = true;
+
+	return set_property(dev, &p);
+}
+
+static void set_gamma(struct device *dev, unsigned crtc_id, unsigned fourcc)
+{
+	unsigned blob_id = 0;
+	/* TODO: support 1024-sized LUTs, when the use-case arises */
+	struct drm_color_lut gamma_lut[256];
+	int i, ret;
+
+	if (fourcc == DRM_FORMAT_C8) {
+		/* TODO: Add C8 support for more patterns */
+		util_smpte_c8_gamma(256, gamma_lut);
+		drmModeCreatePropertyBlob(dev->fd, gamma_lut, sizeof(gamma_lut), &blob_id);
+	} else {
+		for (i = 0; i < 256; i++) {
+			gamma_lut[i].red =
+			gamma_lut[i].green =
+			gamma_lut[i].blue = i << 8;
+		}
+	}
+
+	add_property_optional(dev, crtc_id, "DEGAMMA_LUT", 0);
+	add_property_optional(dev, crtc_id, "CTM", 0);
+	if (!add_property_optional(dev, crtc_id, "GAMMA_LUT", blob_id)) {
+		uint16_t r[256], g[256], b[256];
+
+		for (i = 0; i < 256; i++) {
+			r[i] = gamma_lut[i].red;
+			g[i] = gamma_lut[i].green;
+			b[i] = gamma_lut[i].blue;
+		}
+
+		ret = drmModeCrtcSetGamma(dev->fd, crtc_id, 256, r, g, b);
+		if (ret)
+			fprintf(stderr, "failed to set gamma: %s\n", strerror(errno));
+	}
+}
+
 static int atomic_set_plane(struct device *dev, struct plane_arg *p,
 							int pattern, bool update)
 {
@@ -1204,7 +1262,7 @@ static int set_plane(struct device *dev,
 		p->w, p->h, p->format_str, plane_id);
 
 	plane_bo = bo_create(dev->fd, p->fourcc, p->w, p->h, handles,
-			     pitches, offsets, UTIL_PATTERN_TILES);
+			     pitches, offsets, secondary_fill);
 	if (plane_bo == NULL)
 		return -1;
 
@@ -1245,12 +1303,14 @@ static int set_plane(struct device *dev,
 static void atomic_set_planes(struct device *dev, struct plane_arg *p,
 			      unsigned int count, bool update)
 {
-	unsigned int i, pattern = UTIL_PATTERN_SMPTE;
+	unsigned int i, pattern = primary_fill;
 
 	/* set up planes */
 	for (i = 0; i < count; i++) {
 		if (i > 0)
-			pattern = UTIL_PATTERN_TILES;
+			pattern = secondary_fill;
+		else
+			set_gamma(dev, p[i].crtc_id, p[i].fourcc);
 
 		if (atomic_set_plane(dev, &p[i], pattern, update))
 			return;
@@ -1333,8 +1393,8 @@ static void atomic_set_mode(struct devic
 		if (pipe->mode == NULL)
 			continue;
 
-		printf("setting mode %s-%dHz@%s on connectors ",
-		       pipe->mode_str, pipe->mode->vrefresh, pipe->format_str);
+		printf("setting mode %s-%dHz on connectors ",
+		       pipe->mode_str, pipe->mode->vrefresh);
 		for (j = 0; j < pipe->num_cons; ++j) {
 			printf("%s, ", pipe->cons[j]);
 			add_property(dev, pipe->con_ids[j], "CRTC_ID", pipe->crtc->crtc->crtc_id);
@@ -1393,7 +1453,7 @@ static void set_mode(struct device *dev,
 
 	bo = bo_create(dev->fd, pipes[0].fourcc, dev->mode.width,
 		       dev->mode.height, handles, pitches, offsets,
-		       UTIL_PATTERN_SMPTE);
+		       primary_fill);
 	if (bo == NULL)
 		return;
 
@@ -1435,6 +1495,8 @@ static void set_mode(struct device *dev,
 			fprintf(stderr, "failed to set mode: %s\n", strerror(errno));
 			return;
 		}
+
+		set_gamma(dev, pipe->crtc->crtc->crtc_id, pipe->fourcc);
 	}
 }
 
@@ -1709,11 +1771,8 @@ static int parse_plane(struct plane_arg 
 	}
 
 	if (*end == '@') {
-		p = end + 1;
-		if (strlen(p) != 4)
-			return -EINVAL;
-
-		strcpy(plane->format_str, p);
+		strncpy(plane->format_str, end + 1, 4);
+		plane->format_str[4] = '\0';
 	} else {
 		strcpy(plane->format_str, "XR24");
 	}
@@ -1738,6 +1797,18 @@ static int parse_property(struct propert
 	return 0;
 }
 
+static void parse_fill_patterns(char *arg)
+{
+	char *fill = strtok(arg, ",");
+	if (!fill)
+		return;
+	primary_fill = util_pattern_enum(fill);
+	fill = strtok(NULL, ",");
+	if (!fill)
+		return;
+	secondary_fill = util_pattern_enum(fill);
+}
+
 static void usage(char *name)
 {
 	fprintf(stderr, "usage: %s [-acDdefMPpsCvw]\n", name);
@@ -1755,6 +1826,7 @@ static void usage(char *name)
 	fprintf(stderr, "\t-v\ttest vsynced page flipping\n");
 	fprintf(stderr, "\t-w <obj_id>:<prop_name>:<value>\tset property\n");
 	fprintf(stderr, "\t-a \tuse atomic API\n");
+	fprintf(stderr, "\t-F pattern1,pattern2\tspecify fill patterns\n");
 
 	fprintf(stderr, "\n Generic options:\n\n");
 	fprintf(stderr, "\t-d\tdrop master after mode set\n");
@@ -1818,7 +1890,7 @@ static int pipe_resolve_connectors(struc
 	return 0;
 }
 
-static char optstr[] = "acdD:efM:P:ps:Cvw:";
+static char optstr[] = "acdD:efF:M:P:ps:Cvw:";
 
 int main(int argc, char **argv)
 {
@@ -1867,6 +1939,9 @@ int main(int argc, char **argv)
 		case 'f':
 			framebuffers = 1;
 			break;
+		case 'F':
+			parse_fill_patterns(optarg);
+			break;
 		case 'M':
 			module = optarg;
 			/* Preserve the default behaviour of dumping all information. */

Reply via email to