diff options
author | Tobias Jakobi <tjakobi@math.uni-bielefeld.de> | 2015-11-30 12:12:13 +0900 |
---|---|---|
committer | Emil Velikov <emil.l.velikov@gmail.com> | 2015-12-18 17:42:54 +0000 |
commit | 2191ed904f9301d25d16c8b462ab029a81810601 (patch) | |
tree | 8c9298cc4fdb5b87c2b391702683b588ddb7450c /exynos | |
parent | d6ffb997263402eebdcb029e061ae0221925f643 (diff) | |
download | libdrm-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-x | exynos/exynos-symbol-check | 1 | ||||
-rw-r--r-- | exynos/exynos_drm.c | 76 | ||||
-rw-r--r-- | exynos/exynos_drm.h | 12 | ||||
-rw-r--r-- | exynos/exynos_drmif.h | 26 |
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_ */ |