From b1da92efe6d989224c86b0e0e688a793059a54d7 Mon Sep 17 00:00:00 2001 From: Tony Zlatinski Date: Wed, 19 Sep 2012 00:26:29 -0500 Subject: OMAPKMSLIB: Fixed the KMS Lib alloc/free/map --- Android.mk | 2 +- libkms/omap.c | 159 ++++++++++++++++++++++++++++++++-------------- tests/modetest/modetest.c | 2 +- 3 files changed, 112 insertions(+), 51 deletions(-) diff --git a/Android.mk b/Android.mk index e0833941..b09e693e 100644 --- a/Android.mk +++ b/Android.mk @@ -70,7 +70,7 @@ LOCAL_C_INCLUDES += \ LOCAL_MODULE := libkms LOCAL_MODULE_TAGS := optional -LOCAL_SHARED_LIBRARIES := libdrm +LOCAL_SHARED_LIBRARIES := libdrm libdrm_omap include $(BUILD_SHARED_LIBRARY) diff --git a/libkms/omap.c b/libkms/omap.c index 0ac52671..32d248c4 100644 --- a/libkms/omap.c +++ b/libkms/omap.c @@ -41,16 +41,45 @@ #include #include "xf86drm.h" +#include + #include "omap_drm.h" +#include "omap_drmif.h" + +#ifndef PAGE_SHIFT +# define PAGE_SHIFT 12 +#endif + +/* align x to next highest multiple of 2^n */ +#define ALIGN2(x,n) (((x) + ((1 << (n)) - 1)) & ~((1 << (n)) - 1)) + +#ifndef container_of +#define container_of(ptr, type, member) \ + (type *)((char *)(ptr) - (char *) &((type *)0)->member) +#endif + +#define MSG(fmt, ...) \ + do { fprintf(stderr, fmt "\n", ##__VA_ARGS__); } while (0) +#define ERROR(fmt, ...) \ + do { fprintf(stderr, "ERROR:%s:%d: " fmt "\n", __func__, __LINE__, ##__VA_ARGS__); } while (0) + +#define to_display_kms(x) container_of(x, struct display_kms, kms) +struct display_kms { + struct kms_driver kms; + struct omap_device *dev; + uint32_t width, height; + uint32_t bo_flags; +}; struct omap_kms_bo { struct kms_bo base; + struct omap_bo * omap_bo; unsigned map_count; }; static int -omap_get_prop(struct kms_driver *kms, unsigned key, unsigned *out) +omapkms_get_prop(struct kms_driver *kms, unsigned key, unsigned *out) { switch (key) { case KMS_BO_TYPE: @@ -63,7 +92,7 @@ omap_get_prop(struct kms_driver *kms, unsigned key, unsigned *out) } static int -omap_bo_create(struct kms_driver *kms, +omapkms_bo_create(struct kms_driver *kms, const unsigned width, const unsigned height, const enum kms_bo_type type, const unsigned *attr, struct kms_bo **out) @@ -72,6 +101,9 @@ omap_bo_create(struct kms_driver *kms, struct omap_kms_bo *bo = NULL; struct drm_omap_gem_new arg; int i, ret; + uint32_t bpp; + struct display_kms *disp = to_display_kms(kms); + uint32_t bo_flags = disp->bo_flags; for (i = 0; attr[i]; i += 2) { switch (attr[i]) { @@ -90,17 +122,36 @@ omap_bo_create(struct kms_driver *kms, if (!bo) return -ENOMEM; - memset(&arg, 0, sizeof(arg)); - arg.size.bytes = size; + bpp = 32; + + if ((bo_flags & OMAP_BO_TILED) == OMAP_BO_TILED) { + bo_flags &= ~OMAP_BO_TILED; + if (bpp == 8) { + bo_flags |= OMAP_BO_TILED_8; + } else if (bpp == 16) { + bo_flags |= OMAP_BO_TILED_16; + } else if (bpp == 32) { + bo_flags |= OMAP_BO_TILED_32; + } + } - ret = drmCommandWriteRead(kms->fd, DRM_OMAP_GEM_NEW, &arg, sizeof(arg)); - if (ret) - goto err_free; + bo_flags |= OMAP_BO_WC; + + if (bo_flags & OMAP_BO_TILED) { + bo->omap_bo = omap_bo_new_tiled(disp->dev, width, height, bo_flags); + } else { + bo->omap_bo = omap_bo_new(disp->dev, width * height * bpp / 8, bo_flags); + } + + if (bo->omap_bo) { + bo->base.handle = omap_bo_handle(bo->omap_bo); + bo->base.pitch = width * bpp / 8; + if (bo_flags & OMAP_BO_TILED) + bo->base.pitch = ALIGN2(bo->base.pitch, PAGE_SHIFT); + } bo->base.kms = kms; - bo->base.handle = arg.handle; - bo->base.size = size; - bo->base.pitch = pitch; + bo->base.size = bo->base.pitch * height; *out = &bo->base; @@ -112,7 +163,7 @@ err_free: } static int -omap_bo_get_prop(struct kms_bo *bo, unsigned key, unsigned *out) +omapkms_bo_get_prop(struct kms_bo *bo, unsigned key, unsigned *out) { switch (key) { default: @@ -121,29 +172,26 @@ omap_bo_get_prop(struct kms_bo *bo, unsigned key, unsigned *out) } static int -_omap_bo_map(struct kms_bo *_bo, void **out) +omapkms_bo_map(struct kms_bo *_bo, void **out) { struct omap_kms_bo *bo = (struct omap_kms_bo *)_bo; - void *map = NULL; - int ret; + + if(bo->base.ptr == NULL) { + omap_bo_cpu_prep(bo->omap_bo, OMAP_GEM_WRITE /* | OMAP_GEM_READ */); + bo->base.ptr = omap_bo_map(bo->omap_bo); + } if (bo->base.ptr) { bo->map_count++; - *out = bo->base.ptr; - return 0; } - /* TODO: Map buffer */ - - bo->base.ptr = NULL; - bo->map_count++; *out = bo->base.ptr; - return 0; + return (bo->base.ptr) ? 0 : -1; } static int -omap_bo_unmap(struct kms_bo *_bo) +omapkms_bo_unmap(struct kms_bo *_bo) { struct omap_kms_bo *bo = (struct omap_kms_bo *)_bo; @@ -154,62 +202,75 @@ omap_bo_unmap(struct kms_bo *_bo) if(bo->map_count == 0) { - /* TODO: UnMap buffer */ + omap_bo_cpu_fini(bo->omap_bo, OMAP_GEM_WRITE /* | OMAP_GEM_READ */); + bo->base.ptr = NULL; } return 0; } static int -omap_bo_destroy(struct kms_bo *_bo) +omapkms_bo_destroy(struct kms_bo *_bo) { struct omap_kms_bo *bo = (struct omap_kms_bo *)_bo; - struct drm_gem_close arg; - int ret; - if (bo->base.ptr) { - /* XXX Sanity check map_count */ - munmap(bo->base.ptr, bo->base.size); - bo->base.ptr = NULL; - } - - memset(&arg, 0, sizeof(arg)); - arg.handle = bo->base.handle; - - ret = drmIoctl(bo->base.kms->fd, DRM_IOCTL_GEM_CLOSE, &arg); - if (ret) - return -errno; + omap_bo_del(bo->omap_bo); free(bo); + return 0; } static int -omap_destroy(struct kms_driver *kms) +omapkms_destroy(struct kms_driver *kms) { - free(kms); + struct display_kms *disp = to_display_kms(kms); + + if(disp->dev) + { + omap_device_del(disp->dev); + disp->dev = NULL; + } + + free(disp); + return 0; } int omap_create(int fd, struct kms_driver **out) { + struct display_kms *disp = NULL; struct kms_driver *kms; - kms = calloc(1, sizeof(*kms)); - if (!kms) + disp = calloc(1, sizeof(*disp)); + if (!disp) return -ENOMEM; + kms = &disp->kms; + kms->fd = fd; - kms->bo_create = omap_bo_create; - kms->bo_map = _omap_bo_map; - kms->bo_unmap = omap_bo_unmap; - kms->bo_get_prop = omap_bo_get_prop; - kms->bo_destroy = omap_bo_destroy; - kms->get_prop = omap_get_prop; - kms->destroy = omap_destroy; + kms->bo_create = omapkms_bo_create; + kms->bo_map = omapkms_bo_map; + kms->bo_unmap = omapkms_bo_unmap; + kms->bo_get_prop = omapkms_bo_get_prop; + kms->bo_destroy = omapkms_bo_destroy; + kms->get_prop = omapkms_get_prop; + kms->destroy = omapkms_destroy; *out = kms; + disp->dev = omap_device_new(fd); + if (!disp->dev) { + ERROR("couldn't create device"); + goto fail; + } + + disp->bo_flags = OMAP_BO_SCANOUT; + return 0; + +fail: + free(disp); + return -ENOMEM; } diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index ce62163d..ff45dc9a 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c @@ -949,7 +949,7 @@ int main(int argc, char **argv) int c; int encoders = 0, connectors = 0, crtcs = 0, planes = 0, framebuffers = 0; int test_vsync = 0; - char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos" }; + char *modules[] = { /* "i915", "radeon", "nouveau", "vmwgfx", */ "omapdrm" /*, "exynos" */}; unsigned int i; int count = 0, plane_count = 0; struct connector con_args[2]; -- cgit v1.2.3-54-g00ecf