[PATCH xf86-video-amdgpu 03/13] Add DRM event queue helpers

Michel Dänzer michel at daenzer.net
Tue Jun 2 02:21:21 PDT 2015


From: Michel Dänzer <michel.daenzer at amd.com>

(Cherry picked from radeon commit b4af8a327ed8420f0ff4ea0f113f4a59406ed4d3)

Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
 src/Makefile.am        |   4 +-
 src/amdgpu_drm_queue.c | 181 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/amdgpu_drm_queue.h |  56 +++++++++++++++
 src/amdgpu_kms.c       |   4 ++
 4 files changed, 244 insertions(+), 1 deletion(-)
 create mode 100644 src/amdgpu_drm_queue.c
 create mode 100644 src/amdgpu_drm_queue.h

diff --git a/src/Makefile.am b/src/Makefile.am
index 3fe1cd0..8e91472 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -28,7 +28,8 @@
 
 amdgpu_drv_la_LIBADD = $(PCIACCESS_LIBS) $(LIBDRM_AMDGPU_LIBS) $(GBM_LIBS)
 
-AMDGPU_KMS_SRCS=amdgpu_dri2.c amdgpu_kms.c drmmode_display.c amdgpu_bo_helper.c
+AMDGPU_KMS_SRCS=amdgpu_bo_helper.c amdgpu_dri2.c amdgpu_drm_queue.c amdgpu_kms.c \
+	drmmode_display.c
 
 AM_CFLAGS = \
             @GBM_CFLAGS@ \
@@ -57,6 +58,7 @@ amdgpu_drv_la_SOURCES += \
 EXTRA_DIST = \
 	compat-api.h \
 	amdgpu_bo_helper.h \
+	amdgpu_drm_queue.h \
 	amdgpu_glamor.h \
 	amdgpu_drv.h \
 	amdgpu_list.h \
diff --git a/src/amdgpu_drm_queue.c b/src/amdgpu_drm_queue.c
new file mode 100644
index 0000000..9bec658
--- /dev/null
+++ b/src/amdgpu_drm_queue.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ * Copyright © 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Dave Airlie <airlied at redhat.com>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <xorg-server.h>
+
+#include "amdgpu_drv.h"
+#include "amdgpu_drm_queue.h"
+#include "amdgpu_list.h"
+
+
+struct amdgpu_drm_queue_entry {
+	struct xorg_list list;
+	uint64_t id;
+	void *data;
+	ClientPtr client;
+	ScrnInfoPtr scrn;
+	amdgpu_drm_handler_proc handler;
+	amdgpu_drm_abort_proc abort;
+};
+
+static int amdgpu_drm_queue_refcnt;
+static struct xorg_list amdgpu_drm_queue;
+
+
+/*
+ * Handle a DRM event
+ */
+void
+amdgpu_drm_queue_handler(int fd, unsigned int frame, unsigned int sec,
+			 unsigned int usec, void *user_ptr)
+{
+	struct amdgpu_drm_queue_entry *user_data = user_ptr;
+	struct amdgpu_drm_queue_entry *e, *tmp;
+
+	xorg_list_for_each_entry_safe(e, tmp, &amdgpu_drm_queue, list) {
+		if (e == user_data) {
+			xorg_list_del(&e->list);
+			e->handler(e->scrn, frame,
+				   (uint64_t)sec * 1000000 + usec, e->data);
+			free(e);
+			break;
+		}
+	}
+}
+
+/*
+ * Enqueue a potential drm response; when the associated response
+ * appears, we've got data to pass to the handler from here
+ */
+struct amdgpu_drm_queue_entry *
+amdgpu_drm_queue_alloc(ScrnInfoPtr scrn, ClientPtr client,
+		       uint64_t id, void *data,
+		       amdgpu_drm_handler_proc handler,
+		       amdgpu_drm_abort_proc abort)
+{
+	struct amdgpu_drm_queue_entry *e;
+
+	e = calloc(1, sizeof(struct amdgpu_drm_queue_entry));
+	if (!e)
+		return NULL;
+
+	e->client = client;
+	e->scrn = scrn;
+	e->id = id;
+	e->data = data;
+	e->handler = handler;
+	e->abort = abort;
+
+	xorg_list_add(&e->list, &amdgpu_drm_queue);
+
+	return e;
+}
+
+/*
+ * Abort one queued DRM entry, removing it
+ * from the list, calling the abort function and
+ * freeing the memory
+ */
+static void
+amdgpu_drm_abort_one(struct amdgpu_drm_queue_entry *e)
+{
+	xorg_list_del(&e->list);
+	e->abort(e->scrn, e->data);
+	free(e);
+}
+
+/*
+ * Abort drm queue entries for a client
+ */
+void
+amdgpu_drm_abort_client(ClientPtr client)
+{
+	struct amdgpu_drm_queue_entry *e, *tmp;
+
+	xorg_list_for_each_entry_safe(e, tmp, &amdgpu_drm_queue, list) {
+		if (e->client == client)
+			amdgpu_drm_abort_one(e);
+	}
+}
+
+/*
+ * Abort specific drm queue entry
+ */
+void
+amdgpu_drm_abort_entry(struct amdgpu_drm_queue_entry *entry)
+{
+	amdgpu_drm_abort_one(entry);
+}
+
+/*
+ * Abort specific drm queue entry by ID
+ */
+void
+amdgpu_drm_abort_id(uint64_t id)
+{
+	struct amdgpu_drm_queue_entry *e, *tmp;
+
+	xorg_list_for_each_entry_safe(e, tmp, &amdgpu_drm_queue, list) {
+		if (e->id == id) {
+			amdgpu_drm_abort_one(e);
+			break;
+		}
+	}
+}
+
+/*
+ * Initialize the DRM event queue
+ */
+void
+amdgpu_drm_queue_init()
+{
+	if (amdgpu_drm_queue_refcnt++)
+		return;
+
+	xorg_list_init(&amdgpu_drm_queue);
+}
+
+/*
+ * Deinitialize the DRM event queue
+ */
+void
+amdgpu_drm_queue_close(ScrnInfoPtr scrn)
+{
+	struct amdgpu_drm_queue_entry *e, *tmp;
+
+	xorg_list_for_each_entry_safe(e, tmp, &amdgpu_drm_queue, list) {
+		if (e->scrn == scrn)
+			amdgpu_drm_abort_one(e);
+	}
+
+	amdgpu_drm_queue_refcnt--;
+}
diff --git a/src/amdgpu_drm_queue.h b/src/amdgpu_drm_queue.h
new file mode 100644
index 0000000..96841f6
--- /dev/null
+++ b/src/amdgpu_drm_queue.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ * Copyright © 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Dave Airlie <airlied at redhat.com>
+ *
+ */
+
+#ifndef _AMDGPU_DRM_QUEUE_H_
+#define _AMDGPU_DRM_QUEUE_H_
+
+#define AMDGPU_DRM_QUEUE_CLIENT_DEFAULT serverClient
+#define AMDGPU_DRM_QUEUE_ID_DEFAULT ~0ULL
+
+struct amdgpu_drm_queue_entry;
+
+typedef void (*amdgpu_drm_handler_proc)(ScrnInfoPtr scrn, uint32_t seq,
+					uint64_t usec, void *data);
+typedef void (*amdgpu_drm_abort_proc)(ScrnInfoPtr scrn, void *data);
+
+void amdgpu_drm_queue_handler(int fd, unsigned int frame,
+			      unsigned int tv_sec, unsigned int tv_usec,
+			      void *user_ptr);
+struct amdgpu_drm_queue_entry *amdgpu_drm_queue_alloc(ScrnInfoPtr scrn,
+						      ClientPtr client,
+						      uint64_t id,
+						      void *data,
+						      amdgpu_drm_handler_proc handler,
+						      amdgpu_drm_abort_proc abort);
+void amdgpu_drm_abort_client(ClientPtr client);
+void amdgpu_drm_abort_entry(struct amdgpu_drm_queue_entry *entry);
+void amdgpu_drm_abort_id(uint64_t id);
+void amdgpu_drm_queue_init();
+void amdgpu_drm_queue_close(ScrnInfoPtr scrn);
+
+#endif /* _AMDGPU_DRM_QUEUE_H_ */
diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index 16a7449..71a4aa7 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -32,6 +32,7 @@
 #include <sys/ioctl.h>
 /* Driver data structures */
 #include "amdgpu_drv.h"
+#include "amdgpu_drm_queue.h"
 #include "amdgpu_glamor.h"
 #include "amdgpu_probe.h"
 #include "micmap.h"
@@ -529,6 +530,8 @@ Bool AMDGPUPreInit_KMS(ScrnInfoPtr pScrn, int flags)
 	if (!AMDGPUPreInitAccel_KMS(pScrn))
 		goto fail;
 
+	amdgpu_drm_queue_init();
+
 	AMDGPUSetupCapabilities(pScrn);
 
 	/* don't enable tiling if accel is not enabled */
@@ -696,6 +699,7 @@ static Bool AMDGPUCloseScreen_KMS(CLOSE_SCREEN_ARGS_DECL)
 		       "AMDGPUCloseScreen\n");
 
 	drmmode_uevent_fini(pScrn, &info->drmmode);
+	amdgpu_drm_queue_close(pScrn);
 
 	DeleteCallback(&FlushCallback, amdgpu_flush_callback, pScrn);
 
-- 
2.1.4



More information about the xorg-driver-ati mailing list