summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChih-Wei Huang <cwhuang@linux.org.tw>2015-04-19 14:17:51 +0800
committerChih-Wei Huang <cwhuang@linux.org.tw>2015-04-19 14:17:51 +0800
commit7e2e2ddd6a59af21b93e3638185bcbf69ca3cca5 (patch)
treed008a2a75a361d653e491578cd89c2e64aa481d5
parent68a74eb31f139ad285a49451cf2ca8271c54f9bb (diff)
parentdc21193e3252ba2d6526546ba1d0c02116baf3ee (diff)
downloadexternal_drm_gralloc-7e2e2ddd6a59af21b93e3638185bcbf69ca3cca5.zip
external_drm_gralloc-7e2e2ddd6a59af21b93e3638185bcbf69ca3cca5.tar.gz
external_drm_gralloc-7e2e2ddd6a59af21b93e3638185bcbf69ca3cca5.tar.bz2
Merge remote-tracking branch 'x86/kitkat-x86' into lollipop-x86
-rw-r--r--Android.mk16
-rw-r--r--gralloc_drm.c30
-rw-r--r--gralloc_drm.h1
-rw-r--r--gralloc_drm_freedreno.c206
-rw-r--r--gralloc_drm_nouveau.c264
-rw-r--r--gralloc_drm_pipe.c54
-rw-r--r--gralloc_drm_priv.h2
-rw-r--r--gralloc_drm_radeon.c2
-rw-r--r--pci_ids/pci_id_driver_map.h7
9 files changed, 454 insertions, 128 deletions
diff --git a/Android.mk b/Android.mk
index cda4321..0e56519 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) \
@@ -81,6 +83,8 @@ include $(CLEAR_VARS)
LOCAL_MODULE := libgralloc_drm
LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS := -std=c99
+
LOCAL_SRC_FILES := \
gralloc_drm.c \
gralloc_drm_kms.c
@@ -95,6 +99,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
@@ -121,6 +132,7 @@ LOCAL_SRC_FILES += gralloc_drm_pipe.c
LOCAL_CFLAGS += -DENABLE_PIPE
LOCAL_C_INCLUDES += \
external/mesa/include \
+ external/mesa/src \
external/mesa/src/gallium/include \
external/mesa/src/gallium/winsys \
external/mesa/src/gallium/drivers \
@@ -144,7 +156,9 @@ LOCAL_C_INCLUDES += \
endif
LOCAL_STATIC_LIBRARIES += \
- libmesa_gallium
+ libmesa_gallium \
+ libmesa_util \
+
LOCAL_SHARED_LIBRARIES += libdl
endif # DRM_USES_PIPE
include $(BUILD_SHARED_LIBRARY)
diff --git a/gralloc_drm.c b/gralloc_drm.c
index 31ac988..0f1ce72 100644
--- a/gralloc_drm.c
+++ b/gralloc_drm.c
@@ -70,25 +70,39 @@ init_drv_from_fd(int fd)
if (version->name) {
#ifdef ENABLE_PIPE
drv = gralloc_drm_drv_create_for_pipe(fd, version->name);
+ if (drv) {
+ ALOGI("create pipe for driver %s", version->name);
+ } else
#endif
+#ifdef ENABLE_FREEDRENO
+ if (!strcmp(version->name, "msm")) {
+ drv = gralloc_drm_drv_create_for_freedreno(fd);
+ ALOGI_IF(drv, "create freedreno for driver msm");
+ } else
+#endif
#ifdef ENABLE_INTEL
- if (!drv && !strcmp(version->name, "i915"))
+ if (!strcmp(version->name, "i915")) {
drv = gralloc_drm_drv_create_for_intel(fd);
+ ALOGI_IF(drv, "create intel for driver i915");
+ } else
#endif
#ifdef ENABLE_RADEON
- if (!drv && !strcmp(version->name, "radeon"))
+ if (!strcmp(version->name, "radeon")) {
drv = gralloc_drm_drv_create_for_radeon(fd);
+ ALOGI_IF(drv, "create radeon for driver radeon");
+ } else
#endif
#ifdef ENABLE_NOUVEAU
- if (!drv && !strcmp(version->name, "nouveau"))
+ if (!strcmp(version->name, "nouveau")) {
drv = gralloc_drm_drv_create_for_nouveau(fd);
+ ALOGI_IF(drv, "create nouveau for driver nouveau");
+ } else
#endif
- }
-
- if (!drv) {
- ALOGE("unsupported driver: %s", (version->name) ?
- version->name : "NULL");
+ if (!drv) {
+ ALOGE("unsupported driver: %s", (version->name) ?
+ version->name : "NULL");
+ }
}
drmFreeVersion(version);
diff --git a/gralloc_drm.h b/gralloc_drm.h
index c32aaf6..e53ecd9 100644
--- a/gralloc_drm.h
+++ b/gralloc_drm.h
@@ -31,6 +31,7 @@
extern "C" {
#endif
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define ALIGN(val, align) (((val) + (align) - 1) & ~((align) - 1))
struct gralloc_drm_t;
diff --git a/gralloc_drm_freedreno.c b/gralloc_drm_freedreno.c
new file mode 100644
index 0000000..3da5a65
--- /dev/null
+++ b/gralloc_drm_freedreno.c
@@ -0,0 +1,206 @@
+/*
+ * 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"
+
+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_nouveau.c b/gralloc_drm_nouveau.c
index 576966e..b93c564 100644
--- a/gralloc_drm_nouveau.c
+++ b/gralloc_drm_nouveau.c
@@ -32,30 +32,42 @@
#include <stdlib.h>
#include <errno.h>
#include <drm.h>
-#include <nouveau_drmif.h>
-#include <nouveau_channel.h>
-#include <nouveau_bo.h>
+#include <nouveau.h>
#include "gralloc_drm.h"
#include "gralloc_drm_priv.h"
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-
+#define NV_ARCH_03 0x03
+#define NV_ARCH_04 0x04
+#define NV_ARCH_10 0x10
+#define NV_ARCH_20 0x20
+#define NV_ARCH_30 0x30
+#define NV_ARCH_40 0x40
+#define NV_TESLA 0x50
+#define NV_FERMI 0xc0
+#define NV_KEPLER 0xe0
+#define NV_MAXWELL 0x110
+
+#define NV50_TILE_HEIGHT(m) (4 << ((m) >> 4))
#define NVC0_TILE_HEIGHT(m) (8 << ((m) >> 4))
-enum {
- NvDmaFB = 0xd8000001,
- NvDmaTT = 0xd8000002,
-};
+
+// Comment out the following to switch between the "sw_indicator disables all
+// tiling" and "sw_indicator zeroes the tile|surf_flags (object tiling?)".
+// Does the latter even make sense ... ? Going through the kernel on the
+// topic is slightly annoying :\
+
+#undef SW_INDICATOR_FULLY_DISABLES_TILING
struct nouveau_info {
struct gralloc_drm_drv_t base;
int fd;
+ uint32_t arch;
struct nouveau_device *dev;
- struct nouveau_channel *chan;
- int arch;
- int tiled_scanout;
+ struct nouveau_client *client;
+ struct nouveau_object *channel;
+ struct nouveau_pushbuf *pushbuf;
};
struct nouveau_buffer {
@@ -68,67 +80,77 @@ static struct nouveau_bo *alloc_bo(struct nouveau_info *info,
int width, int height, int cpp, int usage, int *pitch)
{
struct nouveau_bo *bo = NULL;
- int flags, tile_mode, tile_flags;
- int tiled, scanout;
+ union nouveau_bo_config cfg = {};
+ int flags;
+ int tiled, scanout, sw_indicator;
unsigned int align;
flags = NOUVEAU_BO_MAP | NOUVEAU_BO_VRAM;
- tile_mode = 0;
- tile_flags = 0;
scanout = !!(usage & GRALLOC_USAGE_HW_FB);
tiled = !(usage & (GRALLOC_USAGE_SW_READ_OFTEN |
GRALLOC_USAGE_SW_WRITE_OFTEN));
- if (!info->chan)
- tiled = 0;
- else if (scanout && info->tiled_scanout)
- tiled = 1;
- /* calculate pitch align */
- align = 64;
- if (info->arch >= 0x50) {
- if (scanout && !info->tiled_scanout)
- align = 256;
- else
+ sw_indicator = (usage & (GRALLOC_USAGE_SW_READ_OFTEN |
+ GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+ if (info->arch >= NV_TESLA) {
+ tiled = 1;
+ align = 64;
+ }
+ else {
+ if (scanout)
tiled = 1;
+ align = 64;
}
*pitch = ALIGN(width * cpp, align);
if (tiled) {
- if (info->arch >= 0xc0) {
+ if (info->arch >= NV_FERMI) {
if (height > 64)
- tile_mode = 0x40;
+ cfg.nvc0.tile_mode = 0x0040;
else if (height > 32)
- tile_mode = 0x30;
+ cfg.nvc0.tile_mode = 0x0030;
else if (height > 16)
- tile_mode = 0x20;
+ cfg.nvc0.tile_mode = 0x0020;
else if (height > 8)
- tile_mode = 0x10;
+ cfg.nvc0.tile_mode = 0x0010;
else
- tile_mode = 0x00;
+ cfg.nvc0.tile_mode = 0x0000;
- tile_flags = 0xfe00;
+#ifndef SW_INDICATOR_FULLY_DISABLES_TILING
+ if (sw_indicator)
+ cfg.nvc0.memtype = 0x0000;
+ else
+#endif
+ cfg.nvc0.memtype = 0x00fe;
- align = NVC0_TILE_HEIGHT(tile_mode);
+ align = NVC0_TILE_HEIGHT(cfg.nvc0.tile_mode);
height = ALIGN(height, align);
}
- else if (info->arch >= 0x50) {
+ else if (info->arch >= NV_TESLA) {
if (height > 32)
- tile_mode = 4;
+ cfg.nv50.tile_mode = 0x0040;
else if (height > 16)
- tile_mode = 3;
- else if (height > 8)
- tile_mode = 2;
- else if (height > 4)
- tile_mode = 1;
+ cfg.nv50.tile_mode = 0x0030;
+ else if (height > 8)
+ cfg.nv50.tile_mode = 0x0020;
+ else if (height > 4)
+ cfg.nv50.tile_mode = 0x0010;
else
- tile_mode = 0;
+ cfg.nv50.tile_mode = 0x0000;
- tile_flags = (scanout && cpp != 2) ? 0x7a00 : 0x7000;
+#ifndef SW_INDICATOR_FULLY_DISABLES_TILING
+ if (sw_indicator)
+ cfg.nv50.memtype = 0x0000;
+ else
+#endif
+ cfg.nv50.memtype = (scanout && cpp != 2) ?
+ 0x007a : 0x0070;
- align = 1 << (tile_mode + 2);
+ align = NV50_TILE_HEIGHT(cfg.nv50.tile_mode);
height = ALIGN(height, align);
}
else {
@@ -143,36 +165,45 @@ static struct nouveau_bo *alloc_bo(struct nouveau_info *info,
align |= align >> 16;
align++;
- align = MAX((info->dev->chipset >= 0x40) ? 1024 : 256,
- align);
+ align = MAX((info->dev->chipset >= NV_ARCH_40) ?
+ 1024 : 256, align);
/* adjust pitch */
*pitch = ALIGN(*pitch, align);
-
- tile_mode = *pitch;
+ cfg.nv04.surf_pitch = *pitch;
}
}
- if (cpp == 4)
- tile_flags |= NOUVEAU_BO_TILE_32BPP;
- else if (cpp == 2)
- tile_flags |= NOUVEAU_BO_TILE_16BPP;
+ if (info->arch < NV_TESLA) {
+#ifndef SW_INDICATOR_FULLY_DISABLES_TILING
+ if (sw_indicator)
+ cfg.nv04.surf_flags = 0x0000;
+ else
+#endif
+ if (cpp == 4)
+ cfg.nv04.surf_flags |= NV04_BO_32BPP;
+ else if (cpp == 2)
+ cfg.nv04.surf_flags |= NV04_BO_16BPP;
+ }
if (scanout)
- tile_flags |= NOUVEAU_BO_TILE_SCANOUT;
-
- if (nouveau_bo_new_tile(info->dev, flags, 0, *pitch * height,
- tile_mode, tile_flags, &bo)) {
- ALOGE("failed to allocate bo (flags 0x%x, size %d, tile_mode 0x%x, tile_flags 0x%x)",
- flags, *pitch * height, tile_mode, tile_flags);
+ flags |= NOUVEAU_BO_CONTIG;
+
+#ifdef SW_INDICATOR_FULLY_DISABLES_TILING
+ if (nouveau_bo_new(info->dev, flags, 0, *pitch * height, NULL, &bo)) {
+#else
+ if (nouveau_bo_new(info->dev, flags, 0, *pitch * height, &cfg, &bo)) {
+#endif
+ ALOGE("failed to allocate bo (flags 0x%x, size %d)",
+ flags, *pitch * height);
bo = NULL;
}
return bo;
}
-static struct gralloc_drm_bo_t *
-nouveau_alloc(struct gralloc_drm_drv_t *drv, struct gralloc_drm_handle_t *handle)
+static struct gralloc_drm_bo_t *nouveau_alloc(struct gralloc_drm_drv_t *drv,
+ struct gralloc_drm_handle_t *handle)
{
struct nouveau_info *info = (struct nouveau_info *) drv;
struct nouveau_buffer *nb;
@@ -189,7 +220,7 @@ nouveau_alloc(struct gralloc_drm_drv_t *drv, struct gralloc_drm_handle_t *handle
return NULL;
if (handle->name) {
- if (nouveau_bo_handle_ref(info->dev, handle->name, &nb->bo)) {
+ if (nouveau_bo_name_ref(info->dev, handle->name, &nb->bo)) {
ALOGE("failed to create nouveau bo from name %u",
handle->name);
free(nb);
@@ -203,8 +234,8 @@ nouveau_alloc(struct gralloc_drm_drv_t *drv, struct gralloc_drm_handle_t *handle
height = handle->height;
gralloc_drm_align_geometry(handle->format, &width, &height);
- nb->bo = alloc_bo(info, width, height,
- cpp, handle->usage, &pitch);
+ nb->bo = alloc_bo(info, width, height, cpp,
+ handle->usage, &pitch);
if (!nb->bo) {
ALOGE("failed to allocate nouveau bo %dx%dx%d",
handle->width, handle->height, cpp);
@@ -212,7 +243,7 @@ nouveau_alloc(struct gralloc_drm_drv_t *drv, struct gralloc_drm_handle_t *handle
return NULL;
}
- if (nouveau_bo_handle_get(nb->bo,
+ if (nouveau_bo_name_get(nb->bo,
(uint32_t *) &handle->name)) {
ALOGE("failed to flink nouveau bo");
nouveau_bo_ref(NULL, &nb->bo);
@@ -243,6 +274,7 @@ static int nouveau_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 nouveau_info *info = (struct nouveau_info *) drv;
struct nouveau_buffer *nb = (struct nouveau_buffer *) bo;
uint32_t flags;
int err;
@@ -252,7 +284,7 @@ static int nouveau_map(struct gralloc_drm_drv_t *drv,
flags |= NOUVEAU_BO_WR;
/* TODO if tiled, allocate a linear copy of bo in GART and map it */
- err = nouveau_bo_map(nb->bo, flags);
+ err = nouveau_bo_map(nb->bo, flags, info->client);
if (!err)
*addr = nb->bo->map;
@@ -262,9 +294,7 @@ static int nouveau_map(struct gralloc_drm_drv_t *drv,
static void nouveau_unmap(struct gralloc_drm_drv_t *drv,
struct gralloc_drm_bo_t *bo)
{
- struct nouveau_buffer *nb = (struct nouveau_buffer *) bo;
- /* TODO if tiled, unmap the linear bo and copy back */
- nouveau_bo_unmap(nb->bo);
+ /* The bo is implicitly unmapped at nouveau_bo_ref(NULL, bo) */
}
static void nouveau_init_kms_features(struct gralloc_drm_drv_t *drv,
@@ -282,7 +312,7 @@ static void nouveau_init_kms_features(struct gralloc_drm_drv_t *drv,
}
drm->mode_quirk_vmwgfx = 0;
- drm->swap_mode = (info->chan) ? DRM_SWAP_FLIP : DRM_SWAP_SETCRTC;
+ drm->swap_mode = DRM_SWAP_FLIP;
drm->mode_sync_flip = 1;
drm->swap_interval = 1;
drm->vblank_secondary = 0;
@@ -292,9 +322,10 @@ static void nouveau_destroy(struct gralloc_drm_drv_t *drv)
{
struct nouveau_info *info = (struct nouveau_info *) drv;
- if (info->chan)
- nouveau_channel_free(&info->chan);
- nouveau_device_close(&info->dev);
+ nouveau_pushbuf_del(&info->pushbuf);
+ nouveau_object_del(&info->channel);
+ nouveau_client_del(&info->client);
+ nouveau_device_del(&info->dev);
free(info);
}
@@ -302,31 +333,39 @@ static int nouveau_init(struct nouveau_info *info)
{
int err = 0;
- switch (info->dev->chipset & 0xf0) {
+ switch (info->dev->chipset & ~0xf) {
case 0x00:
- info->arch = 0x04;
+ info->arch = NV_ARCH_04;
break;
case 0x10:
- info->arch = 0x10;
+ info->arch = NV_ARCH_10;
break;
case 0x20:
- info->arch = 0x20;
+ info->arch = NV_ARCH_20;
break;
case 0x30:
- info->arch = 0x30;
+ info->arch = NV_ARCH_30;
break;
case 0x40:
case 0x60:
- info->arch = 0x40;
+ info->arch = NV_ARCH_40;
break;
case 0x50:
case 0x80:
case 0x90:
case 0xa0:
- info->arch = 0x50;
+ info->arch = NV_TESLA;
break;
case 0xc0:
- info->arch = 0xc0;
+ case 0xd0:
+ info->arch = NV_FERMI;
+ break;
+ case 0xe0:
+ case 0xf0:
+ info->arch = NV_KEPLER;
+ break;
+ case 0x110:
+ info->arch = NV_MAXWELL;
break;
default:
ALOGE("unknown nouveau chipset 0x%x", info->dev->chipset);
@@ -334,41 +373,78 @@ static int nouveau_init(struct nouveau_info *info)
break;
}
- info->tiled_scanout = (info->chan != NULL);
+ if (info->dev->drm_version < 0x01000000 && info->dev->chipset >= 0xc0) {
+ ALOGE("nouveau kernel module is too old 0x%x",
+ info->dev->drm_version);
+ err = -EINVAL;
+ }
return err;
}
-struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_nouveau(int fd)
+struct gralloc_drm_drv_t *
+gralloc_drm_drv_create_for_nouveau(int fd)
{
struct nouveau_info *info;
- int err;
+ struct nv04_fifo nv04_data = { .vram = 0xbeef0201, .gart = 0xbeef0202 };
+ struct nvc0_fifo nvc0_data = { };
+ int size, err;
+ void *data;
info = calloc(1, sizeof(*info));
if (!info)
return NULL;
info->fd = fd;
- err = nouveau_device_open_existing(&info->dev, 0, info->fd, 0);
+ err = nouveau_device_wrap(fd, 0, &info->dev);
if (err) {
- ALOGE("failed to create nouveau device");
+ ALOGE("failed to wrap existing nouveau device");
free(info);
return NULL;
}
- err = nouveau_channel_alloc(info->dev, NvDmaFB, NvDmaTT,
- 24 * 1024, &info->chan);
+ err = nouveau_init(info);
if (err) {
- /* make it non-fatal temporarily as it may require firmwares */
- ALOGW("failed to create nouveau channel");
- info->chan = NULL;
+ free(info);
+ return NULL;
}
- err = nouveau_init(info);
+ err = nouveau_client_new(info->dev, &info->client);
+ if (err) {
+ ALOGW("failed to create nouveau client: %d", err);
+ nouveau_device_del(&info->dev);
+ free(info);
+ return NULL;
+ }
+
+ if (info->dev->chipset < 0xc0) {
+ data = &nv04_data;
+ size = sizeof(nv04_data);
+ }
+ else {
+ data = &nvc0_data;
+ size = sizeof(nvc0_data);
+ }
+
+ err = nouveau_object_new(&info->dev->object, 0,
+ NOUVEAU_FIFO_CHANNEL_CLASS, data, size,
+ &info->channel);
+
+ if (err) {
+ ALOGE("failed to create nouveau channel: %d", err);
+ nouveau_client_del(&info->client);
+ nouveau_device_del(&info->dev);
+ free(info);
+ return NULL;
+ }
+
+ err = nouveau_pushbuf_new(info->client, info->channel,
+ 4, 32 * 1024, true, &info->pushbuf);
if (err) {
- if (info->chan)
- nouveau_channel_free(&info->chan);
- nouveau_device_close(&info->dev);
+ ALOGE("failed to allocate DMA push buffer: %d", err);
+ nouveau_object_del(&info->channel);
+ nouveau_client_del(&info->client);
+ nouveau_device_del(&info->dev);
free(info);
return NULL;
}
diff --git a/gralloc_drm_pipe.c b/gralloc_drm_pipe.c
index ec3e19d..64b1e56 100644
--- a/gralloc_drm_pipe.c
+++ b/gralloc_drm_pipe.c
@@ -26,6 +26,8 @@
#include <cutils/log.h>
#include <errno.h>
+#include <svga_types.h>
+#include <svga3d_types.h>
#include <pipe/p_screen.h>
#include <pipe/p_context.h>
#include <state_tracker/drm_driver.h>
@@ -60,19 +62,19 @@ static enum pipe_format get_pipe_format(int format)
switch (format) {
case HAL_PIXEL_FORMAT_RGBA_8888:
- fmt = PIPE_FORMAT_R8G8B8A8_UNORM;
+ fmt = SVGA3D_A8R8G8B8;
break;
case HAL_PIXEL_FORMAT_RGBX_8888:
- fmt = PIPE_FORMAT_R8G8B8X8_UNORM;
+ fmt = SVGA3D_X8R8G8B8;
break;
case HAL_PIXEL_FORMAT_RGB_888:
fmt = PIPE_FORMAT_R8G8B8_UNORM;
break;
case HAL_PIXEL_FORMAT_RGB_565:
- fmt = PIPE_FORMAT_B5G6R5_UNORM;
+ fmt = SVGA3D_R5G6B5;
break;
case HAL_PIXEL_FORMAT_BGRA_8888:
- fmt = PIPE_FORMAT_B8G8R8A8_UNORM;
+ fmt = SVGA3D_A8R8G8B8;
break;
case HAL_PIXEL_FORMAT_YV12:
case HAL_PIXEL_FORMAT_DRM_NV12:
@@ -368,6 +370,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 */
@@ -385,49 +389,49 @@ static void pipe_destroy(struct gralloc_drm_drv_t *drv)
static int pipe_init_screen(struct pipe_manager *pm)
{
- struct pipe_screen *screen = NULL;
+ struct pipe_screen *screen;
+#ifdef ENABLE_PIPE_FREEDRENO
+ if (strcmp(pm->driver, "msm"))
+ screen = fd_drm_screen_create(pm->fd);
+ else
+#endif
#ifdef ENABLE_PIPE_NOUVEAU
if (strcmp(pm->driver, "nouveau") == 0)
screen = nouveau_drm_screen_create(pm->fd);
+ else
#endif
#ifdef ENABLE_PIPE_R300
if (strcmp(pm->driver, "r300") == 0) {
- struct radeon_winsys *sws = radeon_drm_winsys_create(pm->fd);
+ struct radeon_winsys *sws =
+ radeon_drm_winsys_create(pm->fd, r300_screen_create);
- if (sws) {
- screen = r300_screen_create(sws);
- if (!screen)
- sws->destroy(sws);
- }
+ screen = sws ? sws->screen : NULL;
}
+ else
#endif
#ifdef ENABLE_PIPE_R600
if (strcmp(pm->driver, "r600") == 0) {
- struct radeon_winsys *sws = radeon_drm_winsys_create(pm->fd);
+ struct radeon_winsys *sws =
+ radeon_drm_winsys_create(pm->fd, r600_screen_create);
- if (sws) {
- screen = r600_screen_create(sws);
- if (!screen)
- sws->destroy(sws);
- }
+ screen = sws ? sws->screen : NULL;
}
+ else
#endif
#ifdef ENABLE_PIPE_VMWGFX
if (strcmp(pm->driver, "vmwgfx") == 0) {
struct svga_winsys_screen *sws =
svga_drm_winsys_screen_create(pm->fd);
- if (sws) {
- screen = svga_screen_create(sws);
- if (!screen)
- sws->destroy(sws);
- }
+ screen = sws ? svga_screen_create(sws) : NULL;
}
+ else
#endif
+ screen = NULL;
if (!screen) {
- ALOGW("failed to create screen for %s", pm->driver);
+ ALOGW("failed to create pipe screen for %s", pm->driver);
return -EINVAL;
}
@@ -520,6 +524,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);
diff --git a/gralloc_drm_radeon.c b/gralloc_drm_radeon.c
index be2ea9b..2911a45 100644
--- a/gralloc_drm_radeon.c
+++ b/gralloc_drm_radeon.c
@@ -45,8 +45,6 @@
#define RADEON_GPU_PAGE_SIZE 4096
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-
struct radeon_info {
struct gralloc_drm_drv_t base;
diff --git a/pci_ids/pci_id_driver_map.h b/pci_ids/pci_id_driver_map.h
index c3eec14..b89414a 100644
--- a/pci_ids/pci_id_driver_map.h
+++ b/pci_ids/pci_id_driver_map.h
@@ -53,6 +53,12 @@ static const int r600_chip_ids[] = {
#undef CHIPSET
};
+static const int radeonsi_chip_ids[] = {
+#define CHIPSET(chip, name, family) chip,
+#include "pci_ids/radeonsi_pci_ids.h"
+#undef CHIPSET
+};
+
static const int vmwgfx_chip_ids[] = {
#define CHIPSET(chip, name, family) chip,
#include "pci_ids/vmwgfx_pci_ids.h"
@@ -76,6 +82,7 @@ static const struct {
#endif
{ 0x1002, "r300", r300_chip_ids, ARRAY_SIZE(r300_chip_ids) },
{ 0x1002, "r600", r600_chip_ids, ARRAY_SIZE(r600_chip_ids) },
+ { 0x1002, "radeonsi", radeonsi_chip_ids, ARRAY_SIZE(radeonsi_chip_ids) },
{ 0x10de, "nouveau", NULL, -1 },
{ 0x15ad, "vmwgfx", vmwgfx_chip_ids, ARRAY_SIZE(vmwgfx_chip_ids) },
{ 0x0000, NULL, NULL, 0 },