diff options
author | Tomasz Figa <tfiga@google.com> | 2015-06-05 03:57:45 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-06-05 03:57:45 +0000 |
commit | cd2a04a3e41a93e621f7e2c3c90eda68c3954f2d (patch) | |
tree | 1dabb90309920e9e750a3e11665c7842b3da2fab | |
parent | c6099c5de758c6fe8347458832f89f796f7a715d (diff) | |
parent | 47e7aba999eeca7b2db97ca388bc9c42524eec8e (diff) | |
download | drm_gralloc-cd2a04a3e41a93e621f7e2c3c90eda68c3954f2d.tar.gz |
am 47e7aba9: drm_gralloc: Add support for Rockchip DRM
* commit '47e7aba999eeca7b2db97ca388bc9c42524eec8e':
drm_gralloc: Add support for Rockchip DRM
-rw-r--r-- | Android.mk | 8 | ||||
-rw-r--r-- | gralloc_drm.cpp | 4 | ||||
-rw-r--r-- | gralloc_drm_priv.h | 1 | ||||
-rw-r--r-- | gralloc_drm_rockchip.c | 185 |
4 files changed, 198 insertions, 0 deletions
@@ -25,6 +25,7 @@ DRM_GPU_DRIVERS := $(strip $(filter-out swrast, $(BOARD_GPU_DRIVERS))) intel_drivers := i915 i965 i915g ilo radeon_drivers := r300g r600g +rockchip_drivers := rockchip nouveau_drivers := nouveau vmwgfx_drivers := vmwgfx @@ -32,6 +33,7 @@ valid_drivers := \ prebuilt \ $(intel_drivers) \ $(radeon_drivers) \ + $(rockchip_drivers) \ $(nouveau_drivers) \ $(vmwgfx_drivers) @@ -116,6 +118,12 @@ LOCAL_CFLAGS += -DENABLE_NOUVEAU LOCAL_SHARED_LIBRARIES += libdrm_nouveau endif +ifneq ($(filter $(rockchip_drivers), $(DRM_GPU_DRIVERS)),) +LOCAL_SRC_FILES += gralloc_drm_rockchip.c +LOCAL_CFLAGS += -DENABLE_ROCKCHIP +LOCAL_SHARED_LIBRARIES += libdrm_rockchip +endif + ifeq ($(strip $(DRM_USES_PIPE)),true) LOCAL_SRC_FILES += gralloc_drm_pipe.c LOCAL_CFLAGS += -DENABLE_PIPE diff --git a/gralloc_drm.cpp b/gralloc_drm.cpp index ebff717..6f90a84 100644 --- a/gralloc_drm.cpp +++ b/gralloc_drm.cpp @@ -79,6 +79,10 @@ init_drv_from_fd(int fd) if (!drv && !strcmp(version->name, "radeon")) drv = gralloc_drm_drv_create_for_radeon(fd); #endif +#ifdef ENABLE_ROCKCHIP + if (!drv && !strcmp(version->name, "rockchip")) + drv = gralloc_drm_drv_create_for_rockchip(fd); +#endif #ifdef ENABLE_NOUVEAU if (!drv && !strcmp(version->name, "nouveau")) drv = gralloc_drm_drv_create_for_nouveau(fd); diff --git a/gralloc_drm_priv.h b/gralloc_drm_priv.h index 9a87b78..24c398f 100644 --- a/gralloc_drm_priv.h +++ b/gralloc_drm_priv.h @@ -91,6 +91,7 @@ struct gralloc_drm_bo_t { struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_pipe(int fd, const char *name); struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_intel(int fd); struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_radeon(int fd); +struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_rockchip(int fd); struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_nouveau(int fd); #ifdef __cplusplus diff --git a/gralloc_drm_rockchip.c b/gralloc_drm_rockchip.c new file mode 100644 index 0000000..b383208 --- /dev/null +++ b/gralloc_drm_rockchip.c @@ -0,0 +1,185 @@ +#define LOG_TAG "GRALLOC-ROCKCHIP" + +#include <cutils/log.h> +#include <stdlib.h> +#include <errno.h> +#include <drm.h> +#include <rockchip/rockchip_drmif.h> + +#include "gralloc_drm.h" +#include "gralloc_drm_priv.h" + +#define UNUSED(...) (void)(__VA_ARGS__) + +struct rockchip_info { + struct gralloc_drm_drv_t base; + + struct rockchip_device *rockchip; + int fd; +}; + +struct rockchip_buffer { + struct gralloc_drm_bo_t base; + + struct rockchip_bo *bo; +}; + +static void drm_gem_rockchip_destroy(struct gralloc_drm_drv_t *drv) +{ + struct rockchip_info *info = (struct rockchip_info *)drv; + + if (info->rockchip) + rockchip_device_destroy(info->rockchip); + free(info); +} + +static struct gralloc_drm_bo_t *drm_gem_rockchip_alloc( + struct gralloc_drm_drv_t *drv, + struct gralloc_drm_handle_t *handle) +{ + struct rockchip_info *info = (struct rockchip_info *)drv; + struct rockchip_buffer *buf; + struct drm_gem_close args; + int ret, cpp, pitch; + uint32_t size, gem_handle; + + buf = calloc(1, sizeof(*buf)); + if (!buf) { + ALOGE("Failed to allocate buffer wrapper\n"); + return NULL; + } + + cpp = gralloc_drm_get_bpp(handle->format); + if (!cpp) { + ALOGE("unrecognized format 0x%x", handle->format); + return NULL; + } + + gralloc_drm_align_geometry(handle->format, + &handle->width, &handle->height); + + /* TODO: We need to sort out alignment */ + pitch = ALIGN(handle->width * cpp, 64); + size = handle->height * pitch; + + if (handle->prime_fd >= 0) { + ret = drmPrimeFDToHandle(info->fd, handle->prime_fd, + &gem_handle); + if (ret) { + char *c = NULL; + ALOGE("failed to convert prime fd to handle %d ret=%d", + handle->prime_fd, ret); + *c = 0; + goto err; + } + ALOGV("Got handle %d for fd %d\n", gem_handle, handle->prime_fd); + + buf->bo = rockchip_bo_from_handle(info->rockchip, gem_handle, + 0, size); + if (!buf->bo) { + ALOGE("failed to wrap bo handle=%d size=%d\n", + gem_handle, size); + + memset(&args, 0, sizeof(args)); + args.handle = gem_handle; + drmIoctl(info->fd, DRM_IOCTL_GEM_CLOSE, &args); + return NULL; + } + } else { + buf->bo = rockchip_bo_create(info->rockchip, size, 0); + if (!buf->bo) { + ALOGE("failed to allocate bo %dx%dx%dx%d\n", + handle->height, pitch, cpp, size); + goto err; + } + + gem_handle = rockchip_bo_handle(buf->bo); + ret = drmPrimeHandleToFD(info->fd, gem_handle, 0, + &handle->prime_fd); + ALOGV("Got fd %d for handle %d\n", handle->prime_fd, gem_handle); + if (ret) { + ALOGE("failed to get prime fd %d", ret); + goto err_unref; + } + + buf->base.fb_handle = gem_handle; + } + + handle->name = 0; + handle->stride = pitch; + buf->base.handle = handle; + + return &buf->base; + +err_unref: + rockchip_bo_destroy(buf->bo); +err: + free(buf); + return NULL; +} + +static void drm_gem_rockchip_free(struct gralloc_drm_drv_t *drv, + struct gralloc_drm_bo_t *bo) +{ + struct rockchip_buffer *buf = (struct rockchip_buffer *)bo; + + UNUSED(drv); + + if (bo->handle && bo->handle->prime_fd) + close(bo->handle->prime_fd); + + /* TODO: Is destroy correct here? */ + rockchip_bo_destroy(buf->bo); + free(buf); +} + +static int drm_gem_rockchip_map(struct gralloc_drm_drv_t *drv, + struct gralloc_drm_bo_t *bo, int x, int y, int w, int h, + int enable_write, void **addr) +{ + struct rockchip_buffer *buf = (struct rockchip_buffer *)bo; + + UNUSED(drv, x, y, w, h, enable_write); + + *addr = rockchip_bo_map(buf->bo); + if (!*addr) { + ALOGE("failed to map bo\n"); + return -1; + } + + return 0; +} + +static void drm_gem_rockchip_unmap(struct gralloc_drm_drv_t *drv, + struct gralloc_drm_bo_t *bo) +{ + UNUSED(drv, bo); +} + +struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_rockchip(int fd) +{ + struct rockchip_info *info; + int ret; + + info = calloc(1, sizeof(*info)); + if (!info) { + ALOGE("Failed to allocate rockchip gralloc device\n"); + return NULL; + } + + info->rockchip = rockchip_device_create(fd); + if (!info->rockchip) { + ALOGE("Failed to create new rockchip instance\n"); + free(info); + return NULL; + } + + info->fd = fd; + info->base.destroy = drm_gem_rockchip_destroy; + info->base.alloc = drm_gem_rockchip_alloc; + info->base.free = drm_gem_rockchip_free; + info->base.map = drm_gem_rockchip_map; + info->base.unmap = drm_gem_rockchip_unmap; + + return &info->base; +} |