drm: Branch 'master' - 2 commits

[email protected] (Rob Clark) Sat, 4 Nov 2017 21:24:34 +0000 (UTC)
Newsgroups gmane.comp.video.dri.patches
Message-ID <[email protected]>
 freedreno/freedreno_drmif.h    |    3 +++
 freedreno/freedreno_pipe.c     |   19 +++++++++++++++++--
 freedreno/freedreno_priv.h     |    3 ++-
 freedreno/kgsl/kgsl_pipe.c     |    3 ++-
 freedreno/kgsl/kgsl_priv.h     |    2 +-
 freedreno/msm/msm_drm.h        |   40 ++++++++++++++++++++++++++++++++++------
 freedreno/msm/msm_pipe.c       |   41 ++++++++++++++++++++++++++++++++++++++++-
 freedreno/msm/msm_priv.h       |    3 ++-
 freedreno/msm/msm_ringbuffer.c |    1 +
 9 files changed, 102 insertions(+), 13 deletions(-)

New commits:
commit 7064b2eae9c136162e5c7f25571d63f71d066887
Author: Rob Clark <[email protected]>
Date:   Wed Aug 23 17:08:39 2017 -0400

    freedreno: submit-queue context priority
    
    With a new-enough kernel to support prioritized submit-queues, we can
    expose priority level support to mesa.  Open a submit queue associated
    with the fd_pipe and pass it's id back to SUBMIT ioctl.
    
    Signed-off-by: Rob Clark <[email protected]>

diff --git a/freedreno/freedreno_drmif.h b/freedreno/freedreno_drmif.h
index 7a8073ff..c3b0d02a 100644
--- a/freedreno/freedreno_drmif.h
+++ b/freedreno/freedreno_drmif.h
@@ -61,6 +61,7 @@ enum fd_param_id {
 	FD_CHIP_ID,
 	FD_MAX_FREQ,
 	FD_TIMESTAMP,
+	FD_NR_RINGS,      /* # of rings == # of distinct priority levels */
 };
 
 /* bo flags: */
@@ -93,6 +94,7 @@ enum fd_version {
 	FD_VERSION_MADVISE = 1,            /* kernel supports madvise */
 	FD_VERSION_UNLIMITED_CMDS = 1,     /* submits w/ >4 cmd buffers (growable ringbuffer) */
 	FD_VERSION_FENCE_FD = 2,           /* submit command supports in/out fences */
+	FD_VERSION_SUBMIT_QUEUES = 3,      /* submit queues and multiple priority levels */
 };
 enum fd_version fd_device_version(struct fd_device *dev);
 
@@ -100,6 +102,7 @@ enum fd_version fd_device_version(struct fd_device *dev);
  */
 
 struct fd_pipe * fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id);
+struct fd_pipe * fd_pipe_new2(struct fd_device *dev, enum fd_pipe_id id, uint32_t prio);
 void fd_pipe_del(struct fd_pipe *pipe);
 int fd_pipe_get_param(struct fd_pipe *pipe, enum fd_param_id param,
 		uint64_t *value);
diff --git a/freedreno/freedreno_pipe.c b/freedreno/freedreno_pipe.c
index e69cb28c..1540474b 100644
--- a/freedreno/freedreno_pipe.c
+++ b/freedreno/freedreno_pipe.c
@@ -33,8 +33,12 @@
 #include "freedreno_drmif.h"
 #include "freedreno_priv.h"
 
+/**
+ * priority of zero is highest priority, and higher numeric values are
+ * lower priorities
+ */
 struct fd_pipe *
-fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id)
+fd_pipe_new2(struct fd_device *dev, enum fd_pipe_id id, uint32_t prio)
 {
 	struct fd_pipe *pipe;
 	uint64_t val;
@@ -44,7 +48,12 @@ fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id)
 		return NULL;
 	}
 
-	pipe = dev->funcs->pipe_new(dev, id);
+	if ((prio != 1) && (fd_device_version(dev) < FD_VERSION_SUBMIT_QUEUES)) {
+		ERROR_MSG("invalid priority!");
+		return NULL;
+	}
+
+	pipe = dev->funcs->pipe_new(dev, id, prio);
 	if (!pipe) {
 		ERROR_MSG("allocation failed");
 		return NULL;
@@ -59,6 +68,12 @@ fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id)
 	return pipe;
 }
 
+struct fd_pipe *
+fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id)
+{
+	return fd_pipe_new2(dev, id, 1);
+}
+
 void fd_pipe_del(struct fd_pipe *pipe)
 {
 	pipe->funcs->destroy(pipe);
diff --git a/freedreno/freedreno_priv.h b/freedreno/freedreno_priv.h
index 8dd3ee69..27307472 100644
--- a/freedreno/freedreno_priv.h
+++ b/freedreno/freedreno_priv.h
@@ -66,7 +66,8 @@ struct fd_device_funcs {
 			uint32_t flags, uint32_t *handle);
 	struct fd_bo * (*bo_from_handle)(struct fd_device *dev,
 			uint32_t size, uint32_t handle);
-	struct fd_pipe * (*pipe_new)(struct fd_device *dev, enum fd_pipe_id id);
+	struct fd_pipe * (*pipe_new)(struct fd_device *dev, enum fd_pipe_id id,
+			unsigned prio);
 	void (*destroy)(struct fd_device *dev);
 };
 
diff --git a/freedreno/kgsl/kgsl_pipe.c b/freedreno/kgsl/kgsl_pipe.c
index 8a39eb49..80bd1313 100644
--- a/freedreno/kgsl/kgsl_pipe.c
+++ b/freedreno/kgsl/kgsl_pipe.c
@@ -52,6 +52,7 @@ static int kgsl_pipe_get_param(struct fd_pipe *pipe,
 		return 0;
 	case FD_MAX_FREQ:
 	case FD_TIMESTAMP:
+	case FD_NR_RINGS:
 		/* unsupported on kgsl */
 		return -1;
 	default:
@@ -210,7 +211,7 @@ static int getprop(int fd, enum kgsl_property_type type,
 
 
 drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev,
-		enum fd_pipe_id id)
+		enum fd_pipe_id id, uint32_t prio)
 {
 	static const char *paths[] = {
 			[FD_PIPE_3D] = "/dev/kgsl-3d0",
diff --git a/freedreno/kgsl/kgsl_priv.h b/freedreno/kgsl/kgsl_priv.h
index 6ab64965..41b13920 100644
--- a/freedreno/kgsl/kgsl_priv.h
+++ b/freedreno/kgsl/kgsl_priv.h
@@ -103,7 +103,7 @@ drm_private void kgsl_pipe_post_submit(struct kgsl_pipe *pipe,
 drm_private void kgsl_pipe_process_pending(struct kgsl_pipe *pipe,
 		uint32_t timestamp);
 drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev,
-		enum fd_pipe_id id);
+		enum fd_pipe_id id, uint32_t prio);
 
 drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe,
 		uint32_t size);
diff --git a/freedreno/msm/msm_pipe.c b/freedreno/msm/msm_pipe.c
index f872e245..7395e573 100644
--- a/freedreno/msm/msm_pipe.c
+++ b/freedreno/msm/msm_pipe.c
@@ -71,6 +71,8 @@ static int msm_pipe_get_param(struct fd_pipe *pipe,
 		return query_param(pipe, MSM_PARAM_MAX_FREQ, value);
 	case FD_TIMESTAMP:
 		return query_param(pipe, MSM_PARAM_TIMESTAMP, value);
+	case FD_NR_RINGS:
+		return query_param(pipe, MSM_PARAM_NR_RINGS, value);
 	default:
 		ERROR_MSG("invalid param id: %d", param);
 		return -1;
@@ -83,6 +85,7 @@ static int msm_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp,
 	struct fd_device *dev = pipe->dev;
 	struct drm_msm_wait_fence req = {
 			.fence = timestamp,
+			.queueid = to_msm_pipe(pipe)->queue_id,
 	};
 	int ret;
 
@@ -97,9 +100,42 @@ static int msm_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp,
 	return 0;
 }
 
+static int open_submitqueue(struct fd_device *dev, uint32_t prio,
+		uint32_t *queue_id)
+{
+	struct drm_msm_submitqueue req = {
+		.flags = 0,
+		.prio = prio,
+	};
+	int ret;
+
+	if (fd_device_version(dev) < FD_VERSION_SUBMIT_QUEUES) {
+		*queue_id = 0;
+		return 0;
+	}
+
+	ret = drmCommandWriteRead(dev->fd, DRM_MSM_SUBMITQUEUE_NEW, &req, sizeof(req));
+	if (ret) {
+		ERROR_MSG("could not create submitqueue! %d (%s)", ret, strerror(errno));
+		return ret;
+	}
+
+	*queue_id = req.id;
+	return 0;
+}
+
+static void close_submitqueue(struct fd_device *dev, uint32_t queue_id)
+{
+	if (fd_device_version(dev) < FD_VERSION_SUBMIT_QUEUES)
+		return;
+
+	drmCommandWrite(dev->fd, DRM_MSM_SUBMITQUEUE_CLOSE, &queue_id, sizeof(queue_id));
+}
+
 static void msm_pipe_destroy(struct fd_pipe *pipe)
 {
 	struct msm_pipe *msm_pipe = to_msm_pipe(pipe);
+	close_submitqueue(pipe->dev, msm_pipe->queue_id);
 	free(msm_pipe);
 }
 
@@ -122,7 +158,7 @@ static uint64_t get_param(struct fd_pipe *pipe, uint32_t param)
 }
 
 drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev,
-		enum fd_pipe_id id)
+		enum fd_pipe_id id, uint32_t prio)
 {
 	static const uint32_t pipe_id[] = {
 			[FD_PIPE_3D] = MSM_PIPE_3D0,
@@ -157,6 +193,9 @@ drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev,
 	INFO_MSG(" Chip-id:         0x%08x", msm_pipe->chip_id);
 	INFO_MSG(" GMEM size:       0x%08x", msm_pipe->gmem);
 
+	if (open_submitqueue(dev, prio, &msm_pipe->queue_id))
+		goto fail;
+
 	return pipe;
 fail:
 	if (pipe)
diff --git a/freedreno/msm/msm_priv.h b/freedreno/msm/msm_priv.h
index 6d670aab..88ac3aa4 100644
--- a/freedreno/msm/msm_priv.h
+++ b/freedreno/msm/msm_priv.h
@@ -56,6 +56,7 @@ struct msm_pipe {
 	uint32_t gpu_id;
 	uint32_t gmem;
 	uint32_t chip_id;
+	uint32_t queue_id;
 };
 
 static inline struct msm_pipe * to_msm_pipe(struct fd_pipe *x)
@@ -64,7 +65,7 @@ static inline struct msm_pipe * to_msm_pipe(struct fd_pipe *x)
 }
 
 drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev,
-		enum fd_pipe_id id);
+		enum fd_pipe_id id, uint32_t prio);
 
 drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe,
 		uint32_t size);
diff --git a/freedreno/msm/msm_ringbuffer.c b/freedreno/msm/msm_ringbuffer.c
index 5b28feaa..c75bb169 100644
--- a/freedreno/msm/msm_ringbuffer.c
+++ b/freedreno/msm/msm_ringbuffer.c
@@ -401,6 +401,7 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
 	struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
 	struct drm_msm_gem_submit req = {
 			.flags = to_msm_pipe(ring->pipe)->pipe,
+			.queueid = to_msm_pipe(ring->pipe)->queue_id,
 	};
 	uint32_t i;
 	int ret;
commit 62e0767b816cb52b35226d439090ef580bd60b01
Author: Rob Clark <[email protected]>
Date:   Wed Aug 23 15:00:12 2017 -0400

    freedreno: sync uapi header (driver version 1.3.0)
    
    Signed-off-by: Rob Clark <[email protected]>

diff --git a/freedreno/msm/msm_drm.h b/freedreno/msm/msm_drm.h
index ed4c8d47..dac49e59 100644
--- a/freedreno/msm/msm_drm.h
+++ b/freedreno/msm/msm_drm.h
@@ -73,6 +73,8 @@ struct drm_msm_timespec {
 #define MSM_PARAM_CHIP_ID    0x03
 #define MSM_PARAM_MAX_FREQ   0x04
 #define MSM_PARAM_TIMESTAMP  0x05
+#define MSM_PARAM_GMEM_BASE  0x06
+#define MSM_PARAM_NR_RINGS   0x07
 
 struct drm_msm_param {
 	__u32 pipe;           /* in, MSM_PIPE_x */
@@ -104,10 +106,14 @@ struct drm_msm_gem_new {
 	__u32 handle;         /* out */
 };
 
+#define MSM_INFO_IOVA	0x01
+
+#define MSM_INFO_FLAGS (MSM_INFO_IOVA)
+
 struct drm_msm_gem_info {
 	__u32 handle;         /* in */
-	__u32 pad;
-	__u64 offset;         /* out, offset to pass to mmap() */
+	__u32 flags;	      /* in - combination of MSM_INFO_* flags */
+	__u64 offset;         /* out, mmap() offset or iova */
 };
 
 #define MSM_PREP_READ        0x01
@@ -167,7 +173,7 @@ struct drm_msm_gem_submit_cmd {
 	__u32 size;           /* in, cmdstream size */
 	__u32 pad;
 	__u32 nr_relocs;      /* in, number of submit_reloc's */
-	__u64 __user relocs;  /* in, ptr to array of submit_reloc's */
+	__u64 relocs;         /* in, ptr to array of submit_reloc's */
 };
 
 /* Each buffer referenced elsewhere in the cmdstream submit (ie. the
@@ -211,9 +217,10 @@ struct drm_msm_gem_submit {
 	__u32 fence;          /* out */
 	__u32 nr_bos;         /* in, number of submit_bo's */
 	__u32 nr_cmds;        /* in, number of submit_cmd's */
-	__u64 __user bos;     /* in, ptr to array of submit_bo's */
-	__u64 __user cmds;    /* in, ptr to array of submit_cmd's */
+	__u64 bos;            /* in, ptr to array of submit_bo's */
+	__u64 cmds;           /* in, ptr to array of submit_cmd's */
 	__s32 fence_fd;       /* in/out fence fd (see MSM_SUBMIT_FENCE_FD_IN/OUT) */
+	__u32 queueid;         /* in, submitqueue id */
 };
 
 /* The normal way to synchronize with the GPU is just to CPU_PREP on
@@ -227,6 +234,7 @@ struct drm_msm_wait_fence {
 	__u32 fence;          /* in */
 	__u32 pad;
 	struct drm_msm_timespec timeout;   /* in */
+	__u32 queueid;         /* in, submitqueue id */
 };
 
 /* madvise provides a way to tell the kernel in case a buffers contents
@@ -250,6 +258,20 @@ struct drm_msm_gem_madvise {
 	__u32 retained;       /* out, whether backing store still exists */
 };
 
+/*
+ * Draw queues allow the user to set specific submission parameter. Command
+ * submissions specify a specific submitqueue to use.  ID 0 is reserved for
+ * backwards compatibility as a "default" submitqueue
+ */
+
+#define MSM_SUBMITQUEUE_FLAGS (0)
+
+struct drm_msm_submitqueue {
+	__u32 flags;   /* in, MSM_SUBMITQUEUE_x */
+	__u32 prio;    /* in, Priority level */
+	__u32 id;      /* out, identifier */
+};
+
 #define DRM_MSM_GET_PARAM              0x00
 /* placeholder:
 #define DRM_MSM_SET_PARAM              0x01
@@ -261,7 +283,11 @@ struct drm_msm_gem_madvise {
 #define DRM_MSM_GEM_SUBMIT             0x06
 #define DRM_MSM_WAIT_FENCE             0x07
 #define DRM_MSM_GEM_MADVISE            0x08
-#define DRM_MSM_NUM_IOCTLS             0x09
+/* placeholder:
+#define DRM_MSM_GEM_SVM_NEW            0x09
+ */
+#define DRM_MSM_SUBMITQUEUE_NEW        0x0A
+#define DRM_MSM_SUBMITQUEUE_CLOSE      0x0B
 
 #define DRM_IOCTL_MSM_GET_PARAM        DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GET_PARAM, struct drm_msm_param)
 #define DRM_IOCTL_MSM_GEM_NEW          DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_NEW, struct drm_msm_gem_new)
@@ -271,6 +297,8 @@ struct drm_msm_gem_madvise {
 #define DRM_IOCTL_MSM_GEM_SUBMIT       DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_SUBMIT, struct drm_msm_gem_submit)
 #define DRM_IOCTL_MSM_WAIT_FENCE       DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_WAIT_FENCE, struct drm_msm_wait_fence)
 #define DRM_IOCTL_MSM_GEM_MADVISE      DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_MADVISE, struct drm_msm_gem_madvise)
+#define DRM_IOCTL_MSM_SUBMITQUEUE_NEW    DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_NEW, struct drm_msm_submitqueue)
+#define DRM_IOCTL_MSM_SUBMITQUEUE_CLOSE  DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_CLOSE, __u32)
 
 #if defined(__cplusplus)
 }

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
--