summaryrefslogtreecommitdiff
path: root/exynos
diff options
context:
space:
mode:
authorTobias Jakobi <tjakobi@math.uni-bielefeld.de>2015-11-30 12:12:13 +0900
committerEmil Velikov <emil.l.velikov@gmail.com>2015-12-18 17:42:54 +0000
commit2191ed904f9301d25d16c8b462ab029a81810601 (patch)
tree8c9298cc4fdb5b87c2b391702683b588ddb7450c /exynos
parentd6ffb997263402eebdcb029e061ae0221925f643 (diff)
downloadlibdrm-2191ed904f9301d25d16c8b462ab029a81810601.tar.gz
libdrm-2191ed904f9301d25d16c8b462ab029a81810601.tar.bz2
libdrm-2191ed904f9301d25d16c8b462ab029a81810601.zip
exynos: Introduce exynos_handle_event()
Used to handle kernel events specific to the Exynos platform. Currently only G2D events are handled. Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
Diffstat (limited to 'exynos')
-rwxr-xr-xexynos/exynos-symbol-check1
-rw-r--r--exynos/exynos_drm.c76
-rw-r--r--exynos/exynos_drm.h12
-rw-r--r--exynos/exynos_drmif.h26
4 files changed, 115 insertions, 0 deletions
diff --git a/exynos/exynos-symbol-check b/exynos/exynos-symbol-check
index 1a1be89e..c3ddbe4d 100755
--- a/exynos/exynos-symbol-check
+++ b/exynos/exynos-symbol-check
@@ -22,6 +22,7 @@ exynos_device_destroy
exynos_prime_fd_to_handle
exynos_prime_handle_to_fd
exynos_vidi_connection
+exynos_handle_event
g2d_blend
g2d_copy
g2d_copy_with_scale
diff --git a/exynos/exynos_drm.c b/exynos/exynos_drm.c
index df9b8ed4..e689781d 100644
--- a/exynos/exynos_drm.c
+++ b/exynos/exynos_drm.c
@@ -32,6 +32,7 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
+#include <unistd.h>
#include <sys/mman.h>
#include <linux/stddef.h>
@@ -42,6 +43,8 @@
#include "exynos_drm.h"
#include "exynos_drmif.h"
+#define U642VOID(x) ((void *)(unsigned long)(x))
+
/*
* Create exynos drm device object.
*
@@ -374,3 +377,76 @@ exynos_vidi_connection(struct exynos_device *dev, uint32_t connect,
return 0;
}
+
+static void
+exynos_handle_vendor(int fd, struct drm_event *e, void *ctx)
+{
+ struct drm_exynos_g2d_event *g2d;
+ struct exynos_event_context *ectx = ctx;
+
+ switch (e->type) {
+ case DRM_EXYNOS_G2D_EVENT:
+ if (ectx->version < 1 || ectx->g2d_event_handler == NULL)
+ break;
+ g2d = (struct drm_exynos_g2d_event *)e;
+ ectx->g2d_event_handler(fd, g2d->cmdlist_no, g2d->tv_sec,
+ g2d->tv_usec, U642VOID(g2d->user_data));
+ break;
+
+ default:
+ break;
+ }
+}
+
+int
+exynos_handle_event(struct exynos_device *dev, struct exynos_event_context *ctx)
+{
+ char buffer[1024];
+ int len, i;
+ struct drm_event *e;
+ struct drm_event_vblank *vblank;
+ drmEventContextPtr evctx = &ctx->base;
+
+ /* The DRM read semantics guarantees that we always get only
+ * complete events. */
+ len = read(dev->fd, buffer, sizeof buffer);
+ if (len == 0)
+ return 0;
+ if (len < (int)sizeof *e)
+ return -1;
+
+ i = 0;
+ while (i < len) {
+ e = (struct drm_event *) &buffer[i];
+ switch (e->type) {
+ case DRM_EVENT_VBLANK:
+ if (evctx->version < 1 ||
+ evctx->vblank_handler == NULL)
+ break;
+ vblank = (struct drm_event_vblank *) e;
+ evctx->vblank_handler(dev->fd,
+ vblank->sequence,
+ vblank->tv_sec,
+ vblank->tv_usec,
+ U642VOID (vblank->user_data));
+ break;
+ case DRM_EVENT_FLIP_COMPLETE:
+ if (evctx->version < 2 ||
+ evctx->page_flip_handler == NULL)
+ break;
+ vblank = (struct drm_event_vblank *) e;
+ evctx->page_flip_handler(dev->fd,
+ vblank->sequence,
+ vblank->tv_sec,
+ vblank->tv_usec,
+ U642VOID (vblank->user_data));
+ break;
+ default:
+ exynos_handle_vendor(dev->fd, e, evctx);
+ break;
+ }
+ i += e->length;
+ }
+
+ return 0;
+}
diff --git a/exynos/exynos_drm.h b/exynos/exynos_drm.h
index 256c02f0..c3af0ac5 100644
--- a/exynos/exynos_drm.h
+++ b/exynos/exynos_drm.h
@@ -157,4 +157,16 @@ struct drm_exynos_g2d_exec {
#define DRM_IOCTL_EXYNOS_G2D_EXEC DRM_IOWR(DRM_COMMAND_BASE + \
DRM_EXYNOS_G2D_EXEC, struct drm_exynos_g2d_exec)
+/* EXYNOS specific events */
+#define DRM_EXYNOS_G2D_EVENT 0x80000000
+
+struct drm_exynos_g2d_event {
+ struct drm_event base;
+ __u64 user_data;
+ __u32 tv_sec;
+ __u32 tv_usec;
+ __u32 cmdlist_no;
+ __u32 reserved;
+};
+
#endif
diff --git a/exynos/exynos_drmif.h b/exynos/exynos_drmif.h
index c7c1d442..626e3998 100644
--- a/exynos/exynos_drmif.h
+++ b/exynos/exynos_drmif.h
@@ -54,6 +54,25 @@ struct exynos_bo {
uint32_t name;
};
+#define EXYNOS_EVENT_CONTEXT_VERSION 1
+
+/*
+ * Exynos Event Context structure.
+ *
+ * @base: base context (for core events).
+ * @version: version info similar to the one in 'drmEventContext'.
+ * @g2d_event_handler: handler for G2D events.
+ */
+struct exynos_event_context {
+ drmEventContext base;
+
+ int version;
+
+ void (*g2d_event_handler)(int fd, unsigned int cmdlist_no,
+ unsigned int tv_sec, unsigned int tv_usec,
+ void *user_data);
+};
+
/*
* device related functions:
*/
@@ -83,4 +102,11 @@ int exynos_prime_fd_to_handle(struct exynos_device *dev, int fd,
int exynos_vidi_connection(struct exynos_device *dev, uint32_t connect,
uint32_t ext, void *edid);
+/*
+ * event handling related functions:
+ */
+int exynos_handle_event(struct exynos_device *dev,
+ struct exynos_event_context *ctx);
+
+
#endif /* EXYNOS_DRMIF_H_ */