[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

libdrm: Changes to 'debian-unstable'



 Makefile.am                  |    2 
 configure.ac                 |    2 
 debian/changelog             |    8 +
 freedreno/freedreno_device.c |   12 ++
 freedreno/freedreno_drmif.h  |    1 
 freedreno/freedreno_priv.h   |    2 
 include/drm/i915_drm.h       |  113 ++++++++++++++++++++---
 intel/intel_bufmgr.h         |   12 +-
 intel/intel_bufmgr_gem.c     |   47 ++++++++-
 libkms/Makefile.am           |    5 +
 libkms/exynos.c              |  207 +++++++++++++++++++++++++++++++++++++++++++
 libkms/internal.h            |    2 
 libkms/linux.c               |    4 
 tests/kmstest/main.c         |    1 
 tests/modetest/modetest.c    |   35 +++++--
 xf86drm.h                    |    8 +
 xf86drmMode.c                |   19 +++
 17 files changed, 444 insertions(+), 36 deletions(-)

New commits:
commit 928d846a2dacc41d8aaf4a2c54f82b5df8e48fb7
Author: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Date:   Fri Jan 24 13:42:11 2014 +0100

    release to unstable

diff --git a/debian/changelog b/debian/changelog
index f1b5fa8..952fe3d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,4 @@
-libdrm (2.4.52-1) UNRELEASED; urgency=medium
+libdrm (2.4.52-1) unstable; urgency=medium
 
   [ Julien Cristau ]
   * Remove Cyril Brulebois from Uploaders.
@@ -6,7 +6,7 @@ libdrm (2.4.52-1) UNRELEASED; urgency=medium
   [ Maarten Lankhorst ]
   * New upstream release.
 
- -- Julien Cristau <jcristau@debian.org>  Mon, 20 Jan 2014 13:51:56 +0100
+ -- Maarten Lankhorst <maarten.lankhorst@ubuntu.com>  Fri, 24 Jan 2014 13:41:57 +0100
 
 libdrm (2.4.51-1) unstable; urgency=medium
 

commit c963bfdc76ce02aa20210b3314422b101bb12239
Author: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Date:   Fri Jan 24 13:40:35 2014 +0100

    New upstream release.

diff --git a/debian/changelog b/debian/changelog
index 6b22b7f..f1b5fa8 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,7 +1,11 @@
-libdrm (2.4.51-2) UNRELEASED; urgency=medium
+libdrm (2.4.52-1) UNRELEASED; urgency=medium
 
+  [ Julien Cristau ]
   * Remove Cyril Brulebois from Uploaders.
 
+  [ Maarten Lankhorst ]
+  * New upstream release.
+
  -- Julien Cristau <jcristau@debian.org>  Mon, 20 Jan 2014 13:51:56 +0100
 
 libdrm (2.4.51-1) unstable; urgency=medium

commit 46d451c9a9514df9de01df647a3f397c5b5d7d1a
Author: Kenneth Graunke <kenneth@whitecape.org>
Date:   Mon Jan 13 15:47:15 2014 -0800

    Bump the version to 2.4.52
    
    Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>

diff --git a/configure.ac b/configure.ac
index d0d051a..969fb83 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,7 +20,7 @@
 
 AC_PREREQ([2.63])
 AC_INIT([libdrm],
-        [2.4.51],
+        [2.4.52],
         [https://bugs.freedesktop.org/enter_bug.cgi?product=DRI],
         [libdrm])
 

commit edf17dbdaa525fe3a9abbbfafa768c556cfd7af2
Author: Kenneth Graunke <kenneth@whitecape.org>
Date:   Mon Jan 13 14:14:36 2014 -0800

    intel: Create a new drm_intel_bo offset64 field.
    
    The existing 'offset' field is unfortunately typed as 'unsigned long',
    which is unfortunately only 4 bytes with a 32-bit userspace.
    
    Traditionally, the hardware has only supported 32-bit virtual addresses,
    so even though the kernel uses a __u64, the value would always fit.
    
    However, Broadwell supports 48-bit addressing.  So with a 64-bit kernel,
    the card virtual address may be too large to fit in the 'offset' field.
    
    Ideally, we would change the type of 'offset' to be a uint64_t---but
    this would break the libdrm ABI.  Instead, we create a new 'offset64'
    field to hold the full 64-bit value from the kernel, and store the
    32-bit truncation in the existing 'offset' field, for compatibility.
    
    Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
    Reviewed-by: Eric Anholt <eric@anholt.net>
    Reviewed-by: Ben Widawsky <ben@bwidawsk.net>
    Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>

diff --git a/intel/intel_bufmgr.h b/intel/intel_bufmgr.h
index 2eb9742..9383c72 100644
--- a/intel/intel_bufmgr.h
+++ b/intel/intel_bufmgr.h
@@ -61,9 +61,8 @@ struct _drm_intel_bo {
 	unsigned long align;
 
 	/**
-	 * Last seen card virtual address (offset from the beginning of the
-	 * aperture) for the object.  This should be used to fill relocation
-	 * entries when calling drm_intel_bo_emit_reloc()
+	 * Deprecated field containing (possibly the low 32-bits of) the last
+	 * seen virtual card address.  Use offset64 instead.
 	 */
 	unsigned long offset;
 
@@ -84,6 +83,13 @@ struct _drm_intel_bo {
 	 * MM-specific handle for accessing object
 	 */
 	int handle;
+
+	/**
+	 * Last seen card virtual address (offset from the beginning of the
+	 * aperture) for the object.  This should be used to fill relocation
+	 * entries when calling drm_intel_bo_emit_reloc()
+	 */
+	uint64_t offset64;
 };
 
 enum aub_dump_bmp_format {
diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c
index e20e2c4..007a6d8 100644
--- a/intel/intel_bufmgr_gem.c
+++ b/intel/intel_bufmgr_gem.c
@@ -391,7 +391,7 @@ drm_intel_gem_dump_validation_list(drm_intel_bufmgr_gem *bufmgr_gem)
 			    (unsigned long long)bo_gem->relocs[j].offset,
 			    target_gem->gem_handle,
 			    target_gem->name,
-			    target_bo->offset,
+			    target_bo->offset64,
 			    bo_gem->relocs[j].delta);
 		}
 	}
@@ -911,6 +911,7 @@ drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr,
 
 	bo_gem->bo.size = open_arg.size;
 	bo_gem->bo.offset = 0;
+	bo_gem->bo.offset64 = 0;
 	bo_gem->bo.virtual = NULL;
 	bo_gem->bo.bufmgr = bufmgr;
 	bo_gem->name = name;
@@ -1706,7 +1707,7 @@ do_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
 	    target_bo_gem->gem_handle;
 	bo_gem->relocs[bo_gem->reloc_count].read_domains = read_domains;
 	bo_gem->relocs[bo_gem->reloc_count].write_domain = write_domain;
-	bo_gem->relocs[bo_gem->reloc_count].presumed_offset = target_bo->offset;
+	bo_gem->relocs[bo_gem->reloc_count].presumed_offset = target_bo->offset64;
 
 	bo_gem->reloc_target_info[bo_gem->reloc_count].bo = target_bo;
 	if (target_bo != bo)
@@ -1857,11 +1858,12 @@ drm_intel_update_buffer_offsets(drm_intel_bufmgr_gem *bufmgr_gem)
 		drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
 
 		/* Update the buffer offset */
-		if (bufmgr_gem->exec_objects[i].offset != bo->offset) {
+		if (bufmgr_gem->exec_objects[i].offset != bo->offset64) {
 			DBG("BO %d (%s) migrated: 0x%08lx -> 0x%08llx\n",
-			    bo_gem->gem_handle, bo_gem->name, bo->offset,
+			    bo_gem->gem_handle, bo_gem->name, bo->offset64,
 			    (unsigned long long)bufmgr_gem->exec_objects[i].
 			    offset);
+			bo->offset64 = bufmgr_gem->exec_objects[i].offset;
 			bo->offset = bufmgr_gem->exec_objects[i].offset;
 		}
 	}
@@ -1877,10 +1879,11 @@ drm_intel_update_buffer_offsets2 (drm_intel_bufmgr_gem *bufmgr_gem)
 		drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo;
 
 		/* Update the buffer offset */
-		if (bufmgr_gem->exec2_objects[i].offset != bo->offset) {
+		if (bufmgr_gem->exec2_objects[i].offset != bo->offset64) {
 			DBG("BO %d (%s) migrated: 0x%08lx -> 0x%08llx\n",
-			    bo_gem->gem_handle, bo_gem->name, bo->offset,
+			    bo_gem->gem_handle, bo_gem->name, bo->offset64,
 			    (unsigned long long)bufmgr_gem->exec2_objects[i].offset);
+			bo->offset64 = bufmgr_gem->exec2_objects[i].offset;
 			bo->offset = bufmgr_gem->exec2_objects[i].offset;
 		}
 	}
@@ -2388,6 +2391,7 @@ drm_intel_gem_bo_pin(drm_intel_bo *bo, uint32_t alignment)
 	if (ret != 0)
 		return -errno;
 
+	bo->offset64 = pin.offset;
 	bo->offset = pin.offset;
 	return 0;
 }

commit 02f93c21e6e1c3dad9d99349989daa84a8c0b5fb
Author: Eric Anholt <eric@anholt.net>
Date:   Wed Jan 15 00:38:39 2014 -0800

    intel: Track whether a buffer is idle to avoid trips to the kernel.
    
    I've seen a number of apps spending unreasonable amounts of time in
    drm_intel_bo_busy during the buffer mapping process.
    
    We can't track idleness in general, in the case of buffers shared
    across processes.  But this should significantly reduce our overhead
    for checking for busy on things like VBOs.
    
    Improves (unoptimized) glamor x11perf -f8text by 0.243334% +/-
    0.161498% (n=1549), which has formerly been spending about .5% of its
    time hitting the kernel for drm_intel_gem_bo_busy().
    
    Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>

diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c
index ad722dd..e20e2c4 100644
--- a/intel/intel_bufmgr_gem.c
+++ b/intel/intel_bufmgr_gem.c
@@ -212,6 +212,15 @@ struct _drm_intel_bo_gem {
 	bool reusable;
 
 	/**
+	 * Boolean of whether the GPU is definitely not accessing the buffer.
+	 *
+	 * This is only valid when reusable, since non-reusable
+	 * buffers are those that have been shared wth other
+	 * processes, so we don't know their state.
+	 */
+	bool idle;
+
+	/**
 	 * Size in bytes of this buffer and its relocation descendents.
 	 *
 	 * Used to avoid costly tree walking in
@@ -567,11 +576,19 @@ drm_intel_gem_bo_busy(drm_intel_bo *bo)
 	struct drm_i915_gem_busy busy;
 	int ret;
 
+	if (bo_gem->reusable && bo_gem->idle)
+		return false;
+
 	VG_CLEAR(busy);
 	busy.handle = bo_gem->gem_handle;
 
 	ret = drmIoctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_BUSY, &busy);
-
+	if (ret == 0) {
+		bo_gem->idle = !busy.busy;
+		return busy.busy;
+	} else {
+		return false;
+	}
 	return (ret == 0 && busy.busy);
 }
 
@@ -2219,6 +2236,8 @@ drm_intel_gem_bo_exec(drm_intel_bo *bo, int used,
 		drm_intel_bo *bo = bufmgr_gem->exec_bos[i];
 		drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
 
+		bo_gem->idle = false;
+
 		/* Disconnect the buffer from the validate list */
 		bo_gem->validate_index = -1;
 		bufmgr_gem->exec_bos[i] = NULL;
@@ -2314,6 +2333,8 @@ skip_execution:
 		drm_intel_bo *bo = bufmgr_gem->exec_bos[i];
 		drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo;
 
+		bo_gem->idle = false;
+
 		/* Disconnect the buffer from the validate list */
 		bo_gem->validate_index = -1;
 		bufmgr_gem->exec_bos[i] = NULL;

commit 734de7093db296912da0027e4fa1094f60787c11
Author: Eric Anholt <eric@anholt.net>
Date:   Sat Dec 28 22:06:51 2013 -0800

    drm: Initialize or valgrind-clear modesetting ioctl arguments.
    
    Fixes valgrind complaints in the modesetting driver.  I tried to
    follow each ioctl's pattern for whether it was initializing just the
    in values, or both in and out values.
    
    Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>

diff --git a/Makefile.am b/Makefile.am
index f726036..826c30d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -59,6 +59,8 @@ libdrm_la_LDFLAGS = -version-number 2:4:0 -no-undefined
 libdrm_la_LIBADD = @CLOCK_LIB@
 
 libdrm_la_CPPFLAGS = -I$(top_srcdir)/include/drm
+AM_CFLAGS = \
+	$(VALGRIND_CFLAGS)
 
 libdrm_la_SOURCES =				\
 	xf86drm.c				\
diff --git a/xf86drmMode.c b/xf86drmMode.c
index 6b60c35..dd7966e 100644
--- a/xf86drmMode.c
+++ b/xf86drmMode.c
@@ -41,6 +41,10 @@
 #include <sys/ioctl.h>
 #include <stdio.h>
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include "xf86drmMode.h"
 #include "xf86drm.h"
 #include <drm.h>
@@ -49,6 +53,16 @@
 #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 U642VOID(x) ((void *)(unsigned long)(x))
 #define VOID2U64(x) ((uint64_t)(unsigned long)(x))
 
@@ -245,6 +259,7 @@ int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
 	struct drm_mode_fb_cmd f;
 	int ret;
 
+	VG_CLEAR(f);
 	f.width  = width;
 	f.height = height;
 	f.pitch  = pitch;
@@ -335,6 +350,7 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
 	struct drm_mode_crtc crtc;
 	drmModeCrtcPtr r;
 
+	VG_CLEAR(crtc);
 	crtc.crtc_id = crtcId;
 
 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETCRTC, &crtc))
@@ -368,6 +384,7 @@ int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
 {
 	struct drm_mode_crtc crtc;
 
+	VG_CLEAR(crtc);
 	crtc.x             = x;
 	crtc.y             = y;
 	crtc.crtc_id       = crtcId;
@@ -436,6 +453,7 @@ drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id)
 	drmModeEncoderPtr r = NULL;
 
 	enc.encoder_id = encoder_id;
+	enc.crtc_id = 0;
 	enc.encoder_type = 0;
 	enc.possible_crtcs = 0;
 	enc.possible_clones = 0;
@@ -580,6 +598,7 @@ drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id)
 	struct drm_mode_get_property prop;
 	drmModePropertyPtr r;
 
+	VG_CLEAR(prop);
 	prop.prop_id = property_id;
 	prop.count_enum_blobs = 0;
 	prop.count_values = 0;

commit cb4bc8ead63cb213a26bcc8d14b2b44d9fb967da
Author: Keith Packard <keithp@keithp.com>
Date:   Sun Jan 12 10:32:57 2014 -0800

    Mark debug_print with __attribute__ ((format(__printf__, 1, 0)))
    
    the drmServerInfo member, debug_print, takes a printf format string
    and varargs list. Tell the compiler about it.
    
    Signed-off-by: Keith Packard <keithp@keithp.com>
    Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>

diff --git a/xf86drm.h b/xf86drm.h
index 1e763a3..5e170f8 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -92,8 +92,14 @@ extern "C" {
 typedef unsigned int  drmSize,     *drmSizePtr;	    /**< For mapped regions */
 typedef void          *drmAddress, **drmAddressPtr; /**< For mapped regions */
 
+#if (__GNUC__ >= 3)
+#define DRM_PRINTFLIKE(f, a) __attribute__ ((format(__printf__, f, a)))
+#else
+#define DRM_PRINTFLIKE(f, a)
+#endif
+
 typedef struct _drmServerInfo {
-  int (*debug_print)(const char *format, va_list ap);
+  int (*debug_print)(const char *format, va_list ap) DRM_PRINTFLIKE(1,0);
   int (*load_module)(const char *name);
   void (*get_perms)(gid_t *, mode_t *);
 } drmServerInfo, *drmServerInfoPtr;

commit 8279c8fb498785ea2700c6cc4a3456d7e1134665
Author: Rob Clark <robclark@freedesktop.org>
Date:   Sun Jan 12 08:27:36 2014 -0500

    freedreno: add fd_device_new_dup()
    
    There seem to be some cases (I've noticed this switching resolution in
    some games, for example) where the fd can get closed() before the device
    and all it's bo's are destroyed.  Which, if the drm device is opened
    again and bo's are allocated with the same handles, results that when
    the first pipe_screen/pipe_context is destroyed causes the first dev to
    close handles for bo's allocated by the second device.
    
    The easy solution to that is to add a mode where the fd_device creates
    it's own private fd (a dup()).
    
    Signed-off-by: Rob Clark <robclark@freedesktop.org>

diff --git a/freedreno/freedreno_device.c b/freedreno/freedreno_device.c
index 6486983..23e086b 100644
--- a/freedreno/freedreno_device.c
+++ b/freedreno/freedreno_device.c
@@ -135,6 +135,16 @@ struct fd_device * fd_device_new(int fd)
 	return dev;
 }
 
+/* like fd_device_new() but creates it's own private dup() of the fd
+ * which is close()d when the device is finalized.
+ */
+struct fd_device * fd_device_new_dup(int fd)
+{
+	struct fd_device *dev = fd_device_new(dup(fd));
+	dev->closefd = 1;
+	return dev;
+}
+
 struct fd_device * fd_device_ref(struct fd_device *dev)
 {
 	atomic_inc(&dev->refcnt);
@@ -147,6 +157,8 @@ static void fd_device_del_impl(struct fd_device *dev)
 	drmHashDestroy(dev->handle_table);
 	drmHashDestroy(dev->name_table);
 	drmHashDelete(dev_table, dev->fd);
+	if (dev->closefd)
+		close(dev->fd);
 	dev->funcs->destroy(dev);
 }
 
diff --git a/freedreno/freedreno_drmif.h b/freedreno/freedreno_drmif.h
index 6a40ab8..f3a01af 100644
--- a/freedreno/freedreno_drmif.h
+++ b/freedreno/freedreno_drmif.h
@@ -72,6 +72,7 @@ enum fd_param_id {
  */
 
 struct fd_device * fd_device_new(int fd);
+struct fd_device * fd_device_new_dup(int fd);
 struct fd_device * fd_device_ref(struct fd_device *dev);
 void fd_device_del(struct fd_device *dev);
 
diff --git a/freedreno/freedreno_priv.h b/freedreno/freedreno_priv.h
index 061d807..d5cf9f9 100644
--- a/freedreno/freedreno_priv.h
+++ b/freedreno/freedreno_priv.h
@@ -84,6 +84,8 @@ struct fd_device {
 	struct fd_bo_bucket cache_bucket[14 * 4];
 	int num_buckets;
 	time_t time;
+
+	int closefd;        /* call close(fd) upon destruction */
 };
 
 void fd_cleanup_bo_cache(struct fd_device *dev, time_t time);

commit de0970203091618834e4753c14d5169770797800
Author: Vincent ABRIOU <vincent.abriou@st.com>
Date:   Fri Jan 10 11:02:33 2014 +0100

    modetest: add the possibility to select the refresh frequency for a mode
    
    When mode is selected we only give the name of the mode as parameter.
    But sometime, two different modes have the same name but not
    the same vrefresh frequency.
    This patch give the possibility to select a mode by its name
    and optionally by its refresh frequency.
    
    Signed-off-by: Vincent Abriou <vincent.abriou@st.com>
    Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
    Signed-off-by: Rob Clark <robclark@freedesktop.org>

diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c
index 51c4e6d..bc9c998 100644
--- a/tests/modetest/modetest.c
+++ b/tests/modetest/modetest.c
@@ -693,6 +693,7 @@ struct pipe_arg {
 	uint32_t crtc_id;
 	char mode_str[64];
 	char format_str[5];
+	unsigned int vrefresh;
 	unsigned int fourcc;
 	drmModeModeInfo *mode;
 	struct crtc *crtc;
@@ -714,7 +715,8 @@ struct plane_arg {
 };
 
 static drmModeModeInfo *
-connector_find_mode(struct device *dev, uint32_t con_id, const char *mode_str)
+connector_find_mode(struct device *dev, uint32_t con_id, const char *mode_str,
+        const unsigned int vrefresh)
 {
 	drmModeConnector *connector;
 	drmModeModeInfo *mode;
@@ -726,8 +728,16 @@ connector_find_mode(struct device *dev, uint32_t con_id, const char *mode_str)
 
 	for (i = 0; i < connector->count_modes; i++) {
 		mode = &connector->modes[i];
-		if (!strcmp(mode->name, mode_str))
-			return mode;
+		if (!strcmp(mode->name, mode_str)) {
+			/* If the vertical refresh frequency is not specified then return the
+			 * first mode that match with the name. Else, return the mode that match
+			 * the name and the specified vertical refresh frequency.
+			 */
+			if (vrefresh == 0)
+				return mode;
+			else if (mode->vrefresh == vrefresh)
+				return mode;
+		}
 	}
 
 	return NULL;
@@ -789,7 +799,7 @@ static int pipe_find_crtc_and_mode(struct device *dev, struct pipe_arg *pipe)
 
 	for (i = 0; i < (int)pipe->num_cons; i++) {
 		mode = connector_find_mode(dev, pipe->con_ids[i],
-					   pipe->mode_str);
+					   pipe->mode_str, pipe->vrefresh);
 		if (mode == NULL) {
 			fprintf(stderr,
 				"failed to find mode \"%s\" for connector %u\n",
@@ -1059,8 +1069,8 @@ static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int co
 		if (pipe->mode == NULL)
 			continue;
 
-		printf("setting mode %s@%s on connectors ",
-		       pipe->mode_str, pipe->format_str);
+		printf("setting mode %s-%dHz@%s on connectors ",
+		       pipe->mode_str, pipe->mode->vrefresh, pipe->format_str);
 		for (j = 0; j < pipe->num_cons; ++j)
 			printf("%u, ", pipe->con_ids[j]);
 		printf("crtc %d\n", pipe->crtc->crtc->crtc_id);
@@ -1192,6 +1202,7 @@ static int parse_connector(struct pipe_arg *pipe, const char *arg)
 	const char *p;
 	char *endp;
 
+	pipe->vrefresh = 0;
 	pipe->crtc_id = (uint32_t)-1;
 	strcpy(pipe->format_str, "XR24");
 
@@ -1226,11 +1237,19 @@ static int parse_connector(struct pipe_arg *pipe, const char *arg)
 
 	arg = endp + 1;
 
-	p = strchrnul(arg, '@');
+	/* Search for the vertical refresh or the format. */
+	p = strpbrk(arg, "-@");
+	if (p == NULL)
+		p = arg + strlen(arg);
 	len = min(sizeof pipe->mode_str - 1, (unsigned int)(p - arg));
 	strncpy(pipe->mode_str, arg, len);
 	pipe->mode_str[len] = '\0';
 
+	if (*p == '-') {
+		pipe->vrefresh = strtoul(p + 1, &endp, 10);
+		p = endp;
+	}
+
 	if (*p == '@') {
 		strncpy(pipe->format_str, p + 1, 4);
 		pipe->format_str[4] = '\0';
@@ -1323,7 +1342,7 @@ static void usage(char *name)
 
 	fprintf(stderr, "\n Test options:\n\n");
 	fprintf(stderr, "\t-P <crtc_id>:<w>x<h>[+<x>+<y>][*<scale>][@<format>]\tset a plane\n");
-	fprintf(stderr, "\t-s <connector_id>[,<connector_id>][@<crtc_id>]:<mode>[@<format>]\tset a mode\n");
+	fprintf(stderr, "\t-s <connector_id>[,<connector_id>][@<crtc_id>]:<mode>[-<vrefresh>][@<format>]\tset a mode\n");
 	fprintf(stderr, "\t-v\ttest vsynced page flipping\n");
 	fprintf(stderr, "\t-w <obj_id>:<prop_name>:<value>\tset property\n");
 

commit 3732ef59eb1198d6a4cb5b8bbca6b155c53529f6
Author: Hyungwon Hwang <human.hwang@samsung.com>
Date:   Fri Jan 10 16:44:30 2014 +0900

    tests/kmstest: support exynos
    
    In this patch, to support exynos for KMS, Exynos KMS driver is newly added.
    Also, Exynos is added to the list of kmstest supported modules.
    
    Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
    Signed-off-by: Rob Clark <robclark@freedesktop.org>

diff --git a/libkms/Makefile.am b/libkms/Makefile.am
index 215450a..449a73b 100644
--- a/libkms/Makefile.am
+++ b/libkms/Makefile.am
@@ -31,6 +31,11 @@ if HAVE_RADEON
 libkms_la_SOURCES += radeon.c
 endif
 
+if HAVE_EXYNOS
+libkms_la_SOURCES += exynos.c
+AM_CFLAGS += -I$(top_srcdir)/exynos
+endif
+
 libkmsincludedir = ${includedir}/libkms
 libkmsinclude_HEADERS = libkms.h
 
diff --git a/libkms/exynos.c b/libkms/exynos.c
new file mode 100644
index 0000000..93e36a1
--- /dev/null
+++ b/libkms/exynos.c
@@ -0,0 +1,207 @@
+/* exynos.c
+ *
+ * Copyright 2009 Samsung Electronics Co., Ltd.
+ * Authors:
+ *	SooChan Lim <sc1.lim@samsung.com>
+ *      Sangjin LEE <lsj119@samsung.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#define HAVE_STDINT_H
+#define _FILE_OFFSET_BITS 64
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "internal.h"
+
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include "xf86drm.h"
+
+#include "exynos_drm.h"
+
+struct exynos_bo
+{
+	struct kms_bo base;
+	unsigned map_count;
+};
+
+static int
+exynos_get_prop(struct kms_driver *kms, unsigned key, unsigned *out)
+{
+	switch (key) {
+	case KMS_BO_TYPE:
+		*out = KMS_BO_TYPE_SCANOUT_X8R8G8B8 | KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int
+exynos_destroy(struct kms_driver *kms)
+{
+	free(kms);
+	return 0;
+}
+
+static int
+exynos_bo_create(struct kms_driver *kms,
+		 const unsigned width, const unsigned height,
+		 const enum kms_bo_type type, const unsigned *attr,
+		 struct kms_bo **out)
+{
+	struct drm_exynos_gem_create arg;
+	unsigned size, pitch;
+	struct exynos_bo *bo;
+	int i, ret;
+
+	for (i = 0; attr[i]; i += 2) {
+		switch (attr[i]) {
+		case KMS_WIDTH:
+		case KMS_HEIGHT:
+		case KMS_BO_TYPE:
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+
+	bo = calloc(1, sizeof(*bo));
+	if (!bo)
+		return -ENOMEM;
+
+	if (type == KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8) {
+		pitch = 64 * 4;
+		size = 64 * 64 * 4;
+	} else if (type == KMS_BO_TYPE_SCANOUT_X8R8G8B8) {
+		pitch = width * 4;
+		pitch = (pitch + 512 - 1) & ~(512 - 1);
+		size = pitch * ((height + 4 - 1) & ~(4 - 1));
+	} else {
+		return -EINVAL;
+	}
+
+	memset(&arg, 0, sizeof(arg));
+	arg.size = size;
+
+	ret = drmCommandWriteRead(kms->fd, DRM_EXYNOS_GEM_CREATE, &arg, sizeof(arg));
+	if (ret)
+		goto err_free;
+
+	bo->base.kms = kms;
+	bo->base.handle = arg.handle;
+	bo->base.size = size;
+	bo->base.pitch = pitch;
+
+	*out = &bo->base;
+
+	return 0;
+
+err_free:
+	free(bo);
+	return ret;
+}
+
+static int
+exynos_bo_get_prop(struct kms_bo *bo, unsigned key, unsigned *out)
+{
+	switch (key) {
+	default:
+		return -EINVAL;
+	}
+}
+
+static int
+exynos_bo_map(struct kms_bo *_bo, void **out)
+{
+	struct exynos_bo *bo = (struct exynos_bo *)_bo;
+	struct drm_exynos_gem_map_off arg;
+	void *map = NULL;
+	int ret;
+
+	if (bo->base.ptr) {
+		bo->map_count++;
+		*out = bo->base.ptr;
+		return 0;
+	}
+
+	memset(&arg, 0, sizeof(arg));
+	arg.handle = bo->base.handle;
+
+	ret = drmCommandWriteRead(bo->base.kms->fd, DRM_EXYNOS_GEM_MAP_OFFSET, &arg, sizeof(arg));
+	if (ret)
+		return ret;
+
+	map = mmap(0, bo->base.size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->base.kms->fd, arg.offset);
+	if (map == MAP_FAILED)
+		return -errno;
+
+	bo->base.ptr = map;
+	bo->map_count++;
+	*out = bo->base.ptr;
+
+	return 0;
+}
+
+static int
+exynos_bo_unmap(struct kms_bo *_bo)
+{
+	struct exynos_bo *bo = (struct exynos_bo *)_bo;
+	bo->map_count--;
+	return 0;
+}
+
+static int
+exynos_bo_destroy(struct kms_bo *_bo)
+{
+	struct exynos_bo *bo = (struct exynos_bo *)_bo;
+	struct drm_gem_close arg;
+	int ret;
+
+	if (bo->base.ptr) {
+		/* XXX Sanity check map_count */
+		munmap(bo->base.ptr, bo->base.size);
+		bo->base.ptr = NULL;
+	}
+
+	memset(&arg, 0, sizeof(arg));
+	arg.handle = bo->base.handle;
+
+	ret = drmIoctl(bo->base.kms->fd, DRM_IOCTL_GEM_CLOSE, &arg);
+	if (ret)
+		return -errno;
+
+	free(bo);
+	return 0;
+}
+
+int
+exynos_create(int fd, struct kms_driver **out)
+{
+	struct kms_driver *kms;
+
+	kms = calloc(1, sizeof(*kms));
+	if (!kms)
+		return -ENOMEM;
+
+	kms->fd = fd;
+
+	kms->bo_create = exynos_bo_create;
+	kms->bo_map = exynos_bo_map;
+	kms->bo_unmap = exynos_bo_unmap;
+	kms->bo_get_prop = exynos_bo_get_prop;
+	kms->bo_destroy = exynos_bo_destroy;
+	kms->get_prop = exynos_get_prop;
+	kms->destroy = exynos_destroy;
+	*out = kms;
+
+	return 0;
+}
diff --git a/libkms/internal.h b/libkms/internal.h
index 5e2501e..f831b57 100644
--- a/libkms/internal.h
+++ b/libkms/internal.h
@@ -74,4 +74,6 @@ int nouveau_create(int fd, struct kms_driver **out);
 
 int radeon_create(int fd, struct kms_driver **out);
 
+int exynos_create(int fd, struct kms_driver **out);
+
 #endif
diff --git a/libkms/linux.c b/libkms/linux.c
index eec0162..9b4f29e 100644
--- a/libkms/linux.c
+++ b/libkms/linux.c
@@ -115,6 +115,10 @@ linux_from_sysfs(int fd, struct kms_driver **out)
 	else if (!strcmp(name, "radeon"))
 		ret = radeon_create(fd, out);
 #endif
+#ifdef HAVE_EXYNOS
+	else if (!strcmp(name, "exynos"))
+		ret = exynos_create(fd, out);
+#endif
 	else
 		ret = -ENOSYS;
 
diff --git a/tests/kmstest/main.c b/tests/kmstest/main.c
index 5df0a38..449d75f 100644
--- a/tests/kmstest/main.c
+++ b/tests/kmstest/main.c
@@ -61,6 +61,7 @@ char *drivers[] = {
 	"radeon",
 	"nouveau",
 	"vmwgfx",
+	"exynos",
 	NULL
 };
 

commit a254cb50414a5def5c872a765c0dd1295a550c6b
Author: Ben Widawsky <benjamin.widawsky@intel.com>
Date:   Thu Jan 2 11:36:59 2014 -0800

    intel: Merge latest i915_drm.h
    
    This was not done as a straight copy because reset_stats IOCTL landed in
    libdrm before upstream kernel.
    
    Signed-off-by: Ben Widawsky <ben@bwidawsk.net>

diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index c1914d6..2f4eb8c 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -27,12 +27,36 @@
 #ifndef _I915_DRM_H_
 #define _I915_DRM_H_
 
-#include "drm.h"
+#include <drm.h>
 
 /* Please note that modifications to all structs defined here are
  * subject to backwards-compatibility constraints.
  */
 
+/**
+ * DOC: uevents generated by i915 on it's device node
+ *
+ * I915_L3_PARITY_UEVENT - Generated when the driver receives a parity mismatch
+ *	event from the gpu l3 cache. Additional information supplied is ROW,
+ *	BANK, SUBBANK, SLICE of the affected cacheline. Userspace should keep
+ *	track of these events and if a specific cache-line seems to have a
+ *	persistent error remap it with the l3 remapping tool supplied in
+ *	intel-gpu-tools.  The value supplied with the event is always 1.
+ *
+ * I915_ERROR_UEVENT - Generated upon error detection, currently only via
+ *	hangcheck. The error detection event is a good indicator of when things
+ *	began to go badly. The value supplied with the event is a 1 upon error
+ *	detection, and a 0 upon reset completion, signifying no more error
+ *	exists. NOTE: Disabling hangcheck or reset via module parameter will
+ *	cause the related events to not be seen.
+ *
+ * I915_RESET_UEVENT - Event is generated just before an attempt to reset the
+ *	the GPU. The value supplied with the event is always 1. NOTE: Disable
+ *	reset via module parameter will cause this event to not be seen.
+ */
+#define I915_L3_PARITY_UEVENT		"L3_PARITY_ERROR"
+#define I915_ERROR_UEVENT		"ERROR"
+#define I915_RESET_UEVENT		"RESET"
 
 /* Each region is a minimum of 16k, and there are at most 255 of them.
  */
@@ -195,8 +219,8 @@ typedef struct _drm_i915_sarea {
 #define DRM_I915_GEM_WAIT	0x2c
 #define DRM_I915_GEM_CONTEXT_CREATE	0x2d
 #define DRM_I915_GEM_CONTEXT_DESTROY	0x2e
-#define DRM_I915_GEM_SET_CACHEING	0x2f
-#define DRM_I915_GEM_GET_CACHEING	0x30
+#define DRM_I915_GEM_SET_CACHING	0x2f
+#define DRM_I915_GEM_GET_CACHING	0x30
 #define DRM_I915_REG_READ		0x31
 #define DRM_I915_GET_RESET_STATS	0x32
 
@@ -223,8 +247,8 @@ typedef struct _drm_i915_sarea {
 #define DRM_IOCTL_I915_GEM_PIN		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin)
 #define DRM_IOCTL_I915_GEM_UNPIN	DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin)
 #define DRM_IOCTL_I915_GEM_BUSY		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy)
-#define DRM_IOCTL_I915_GEM_SET_CACHEING		DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_SET_CACHEING, struct drm_i915_gem_cacheing)
-#define DRM_IOCTL_I915_GEM_GET_CACHEING		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_GET_CACHEING, struct drm_i915_gem_cacheing)
+#define DRM_IOCTL_I915_GEM_SET_CACHING		DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_SET_CACHING, struct drm_i915_gem_caching)
+#define DRM_IOCTL_I915_GEM_GET_CACHING		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_GET_CACHING, struct drm_i915_gem_caching)
 #define DRM_IOCTL_I915_GEM_THROTTLE	DRM_IO ( DRM_COMMAND_BASE + DRM_I915_GEM_THROTTLE)
 #define DRM_IOCTL_I915_GEM_ENTERVT	DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT)
 #define DRM_IOCTL_I915_GEM_LEAVEVT	DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT)
@@ -305,7 +329,14 @@ typedef struct drm_i915_irq_wait {
 #define I915_PARAM_HAS_LLC     	 	 17
 #define I915_PARAM_HAS_ALIASING_PPGTT	 18
 #define I915_PARAM_HAS_WAIT_TIMEOUT	 19
-#define I915_PARAM_HAS_VEBOX            22
+#define I915_PARAM_HAS_SEMAPHORES	 20
+#define I915_PARAM_HAS_PRIME_VMAP_FLUSH	 21
+#define I915_PARAM_HAS_VEBOX		 22
+#define I915_PARAM_HAS_SECURE_BATCHES	 23
+#define I915_PARAM_HAS_PINNED_BATCHES	 24
+#define I915_PARAM_HAS_EXEC_NO_RELOC	 25
+#define I915_PARAM_HAS_EXEC_HANDLE_LUT   26
+#define I915_PARAM_HAS_WT     	 	 27
 
 typedef struct drm_i915_getparam {
 	int param;
@@ -626,7 +657,11 @@ struct drm_i915_gem_exec_object2 {
 	__u64 offset;
 
 #define EXEC_OBJECT_NEEDS_FENCE (1<<0)
+#define EXEC_OBJECT_NEEDS_GTT	(1<<1)
+#define EXEC_OBJECT_WRITE	(1<<2)
+#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_WRITE<<1)
 	__u64 flags;
+
 	__u64 rsvd1;
 	__u64 rsvd2;
 };
@@ -672,6 +707,34 @@ struct drm_i915_gem_execbuffer2 {
 /** Resets the SO write offset registers for transform feedback on gen7. */


Reply to: