summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2014-08-01 20:02:02 +0100
committerChih-Wei Huang <cwhuang@linux.org.tw>2015-01-16 20:22:22 +0800
commitc46b2ee2cace20f67b0c5e1121e1973a7678fd60 (patch)
treee2c5397b180e13befbf514c90ea2b2554ba6032d
parent00ba5a9ddd04b44cebf2bbd6014da57f06413d5e (diff)
downloadexternal_drm_gralloc-c46b2ee2cace20f67b0c5e1121e1973a7678fd60.zip
external_drm_gralloc-c46b2ee2cace20f67b0c5e1121e1973a7678fd60.tar.gz
external_drm_gralloc-c46b2ee2cace20f67b0c5e1121e1973a7678fd60.tar.bz2
freedreno: completely untested initial support
v2: [Emil Velikov] - drmGetVersion returns the kernel module name. - Add it to the build :) - freedreno_map returns void * while gralloc::map expects int. Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
-rw-r--r--Android.mk9
-rw-r--r--gralloc_drm.c4
-rw-r--r--gralloc_drm_freedreno.c209
-rw-r--r--gralloc_drm_pipe.c10
-rw-r--r--gralloc_drm_priv.h2
5 files changed, 234 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk
index c701b6e..116225a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -23,6 +23,7 @@
DRM_GPU_DRIVERS := $(strip $(filter-out swrast, $(BOARD_GPU_DRIVERS)))
+freedreno_drivers := freedreno
intel_drivers := i915 i965 i915g ilo
radeon_drivers := r300g r600g
nouveau_drivers := nouveau
@@ -30,6 +31,7 @@ vmwgfx_drivers := vmwgfx
valid_drivers := \
prebuilt \
+ $(freedreno_drivers) \
$(intel_drivers) \
$(radeon_drivers) \
$(nouveau_drivers) \
@@ -95,6 +97,13 @@ LOCAL_SHARED_LIBRARIES := \
libcutils \
libhardware_legacy \
+ifneq ($(filter $(freedreno_drivers), $(DRM_GPU_DRIVERS)),)
+LOCAL_SRC_FILES += gralloc_drm_freedreno.c
+LOCAL_C_INCLUDES += external/drm/freedreno
+LOCAL_CFLAGS += -DENABLE_FREEDRENO
+LOCAL_SHARED_LIBRARIES += libdrm_freedreno
+endif
+
ifneq ($(filter $(intel_drivers), $(DRM_GPU_DRIVERS)),)
LOCAL_SRC_FILES += gralloc_drm_intel.c
LOCAL_C_INCLUDES += external/drm/intel
diff --git a/gralloc_drm.c b/gralloc_drm.c
index bd752cb..c53e556 100644
--- a/gralloc_drm.c
+++ b/gralloc_drm.c
@@ -73,6 +73,10 @@ init_drv_from_fd(int fd)
ALOGI_IF(drv, "create pipe for driver %s", version->name);
#endif
+#ifdef ENABLE_FREEDRENO
+ if (!drv && !strcmp(version->name, "msm"))
+ drv = gralloc_drm_drv_create_for_freedreno(fd);
+#endif
#ifdef ENABLE_INTEL
if (!drv && !strcmp(version->name, "i915")) {
drv = gralloc_drm_drv_create_for_intel(fd);
diff --git a/gralloc_drm_freedreno.c b/gralloc_drm_freedreno.c
new file mode 100644
index 0000000..10b0939
--- /dev/null
+++ b/gralloc_drm_freedreno.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2011 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright (C) 2011 LunarG Inc.
+ * Copyright (C) 2014 Rob Clark <robclark@freedesktop.org>
+ *
+ * Based on xf86-video-nouveau, which has
+ *
+ * Copyright © 2007 Red Hat, Inc.
+ * Copyright © 2008 Maarten Maathuis
+ *
+ * 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 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.
+ */
+
+#define LOG_TAG "GRALLOC-FREEDRENO"
+
+#include <cutils/log.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <drm.h>
+#include <freedreno_drmif.h>
+
+#include "gralloc_drm.h"
+#include "gralloc_drm_priv.h"
+
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#define ALIGN(val, align) (((val) + (align) - 1) & ~((align) - 1))
+
+struct fd_info {
+ struct gralloc_drm_drv_t base;
+
+ int fd;
+ struct fd_device *dev;
+};
+
+struct fd_buffer {
+ struct gralloc_drm_bo_t base;
+
+ struct fd_bo *bo;
+};
+
+static struct fd_bo *alloc_bo(struct fd_info *info,
+ int width, int height, int cpp, int usage, int *pitch)
+{
+ struct fd_bo *bo = NULL;
+ int flags, size;
+
+ /* TODO need a scanout flag if (usage & GRALLOC_USAGE_HW_FB).. */
+ flags = DRM_FREEDRENO_GEM_CACHE_WCOMBINE;
+
+ *pitch = ALIGN(width, 32) * cpp;
+ size = *pitch * height;
+
+ return fd_bo_new(info->dev, size, flags);
+}
+
+static struct gralloc_drm_bo_t *
+fd_alloc(struct gralloc_drm_drv_t *drv, struct gralloc_drm_handle_t *handle)
+{
+ struct fd_info *info = (struct fd_info *) drv;
+ struct fd_buffer *fd_buf;
+ int cpp;
+
+ cpp = gralloc_drm_get_bpp(handle->format);
+ if (!cpp) {
+ ALOGE("unrecognized format 0x%x", handle->format);
+ return NULL;
+ }
+
+ fd_buf = calloc(1, sizeof(*fd_buf));
+ if (!fd_buf)
+ return NULL;
+
+ if (handle->name) {
+ fd_buf->bo = fd_bo_from_name(info->dev, handle->name);
+ if (!fd_buf->bo) {
+ ALOGE("failed to create fd bo from name %u",
+ handle->name);
+ free(fd_buf);
+ return NULL;
+ }
+ }
+ else {
+ int width, height, pitch;
+
+ width = handle->width;
+ height = handle->height;
+ gralloc_drm_align_geometry(handle->format, &width, &height);
+
+ fd_buf->bo = alloc_bo(info, width, height,
+ cpp, handle->usage, &pitch);
+ if (!fd_buf->bo) {
+ ALOGE("failed to allocate fd bo %dx%dx%d",
+ handle->width, handle->height, cpp);
+ free(fd_buf);
+ return NULL;
+ }
+
+ if (fd_bo_get_name(fd_buf->bo, (uint32_t *) &handle->name)) {
+ ALOGE("failed to flink fd bo");
+ fd_bo_del(fd_buf->bo);
+ free(fd_buf);
+ return NULL;
+ }
+
+ handle->stride = pitch;
+ }
+
+ if (handle->usage & GRALLOC_USAGE_HW_FB)
+ fd_buf->base.fb_handle = fd_bo_handle(fd_buf->bo);
+
+ fd_buf->base.handle = handle;
+
+ return &fd_buf->base;
+}
+
+static void fd_free(struct gralloc_drm_drv_t *drv,
+ struct gralloc_drm_bo_t *bo)
+{
+ struct fd_buffer *fd_buf = (struct fd_buffer *) bo;
+ fd_bo_del(fd_buf->bo);
+ free(fd_buf);
+}
+
+static int fd_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 fd_buffer *fd_buf = (struct fd_buffer *) bo;
+ if (fd_bo_map(fd_buf->bo))
+ return 0;
+ return -errno;
+}
+
+static void fd_unmap(struct gralloc_drm_drv_t *drv,
+ struct gralloc_drm_bo_t *bo)
+{
+ // TODO should add fd_bo_unmap() to libdrm_freedreno someday..
+}
+
+static void fd_init_kms_features(struct gralloc_drm_drv_t *drv,
+ struct gralloc_drm_t *drm)
+{
+ struct fd_info *info = (struct fd_info *) drv;
+
+ switch (drm->primary.fb_format) {
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ case HAL_PIXEL_FORMAT_RGB_565:
+ break;
+ default:
+ drm->primary.fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
+ break;
+ }
+
+ drm->mode_quirk_vmwgfx = 0;
+ drm->swap_mode = DRM_SWAP_FLIP;
+ drm->mode_sync_flip = 1;
+ drm->swap_interval = 1;
+ drm->vblank_secondary = 0;
+}
+
+static void fd_destroy(struct gralloc_drm_drv_t *drv)
+{
+ struct fd_info *info = (struct fd_info *) drv;
+ fd_device_del(info->dev);
+ free(info);
+}
+
+struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_freedreno(int fd)
+{
+ struct fd_info *info;
+ int err;
+
+ info = calloc(1, sizeof(*info));
+ if (!info)
+ return NULL;
+
+ info->fd = fd;
+ info->dev = fd_device_new_dup(info->fd);
+ if (!info->dev) {
+ ALOGE("failed to create fd device");
+ free(info);
+ return NULL;
+ }
+
+ info->base.destroy = fd_destroy;
+ info->base.init_kms_features = fd_init_kms_features;
+ info->base.alloc = fd_alloc;
+ info->base.free = fd_free;
+ info->base.map = fd_map;
+ info->base.unmap = fd_unmap;
+
+ return &info->base;
+} \ No newline at end of file
diff --git a/gralloc_drm_pipe.c b/gralloc_drm_pipe.c
index ec3e19d..1183ba1 100644
--- a/gralloc_drm_pipe.c
+++ b/gralloc_drm_pipe.c
@@ -368,6 +368,8 @@ static void pipe_destroy(struct gralloc_drm_drv_t *drv)
FREE(pm);
}
+/* for freedreno */
+#include "freedreno/drm/freedreno_drm_public.h"
/* for nouveau */
#include "nouveau/drm/nouveau_drm_public.h"
/* for r300 */
@@ -387,6 +389,10 @@ static int pipe_init_screen(struct pipe_manager *pm)
{
struct pipe_screen *screen = NULL;
+#ifdef ENABLE_PIPE_FREEDRENO
+ if (strcmp(pm->driver, "msm"))
+ screen = fd_drm_screen_create(pm->fd);
+#endif
#ifdef ENABLE_PIPE_NOUVEAU
if (strcmp(pm->driver, "nouveau") == 0)
screen = nouveau_drm_screen_create(pm->fd);
@@ -520,6 +526,10 @@ static int pipe_find_driver(struct pipe_manager *pm, const char *name)
driver = "vmwgfx";
err = 0;
}
+ if (strcmp(name, "msm") == 0) {
+ driver = "msm";
+ err = 0;
+ }
}
if (!err)
diff --git a/gralloc_drm_priv.h b/gralloc_drm_priv.h
index 1a36cc1..fd3b72e 100644
--- a/gralloc_drm_priv.h
+++ b/gralloc_drm_priv.h
@@ -197,6 +197,8 @@ 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_freedreno(int fd);
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_nouveau(int fd);