drm: add drm support
authorJiyu Yang <Jiyu.Yang@amlogic.com>
Fri, 14 Jul 2017 08:34:07 +0000 (16:34 +0800)
committerJiyu Yang <jiyu.yang@amlogic.com>
Thu, 20 Jul 2017 11:12:59 +0000 (19:12 +0800)
PD#147238: drm tempoperily bringup on 4.9

Change-Id: I3fa93b57404445985f5f3380f9b9a64161ff720a
Signed-off-by: Jiyu Yang <Jiyu.Yang@amlogic.com>
32 files changed:
MAINTAINERS
drivers/amlogic/Kconfig
drivers/amlogic/Makefile
drivers/amlogic/drm/Kconfig [moved from drivers/gpu/drm/meson/Kconfig with 100% similarity]
drivers/amlogic/drm/Makefile [new file with mode: 0644]
drivers/amlogic/drm/meson_canvas.c [moved from drivers/gpu/drm/meson/meson_canvas.c with 100% similarity]
drivers/amlogic/drm/meson_canvas.h [moved from drivers/gpu/drm/meson/meson_canvas.h with 100% similarity]
drivers/amlogic/drm/meson_crtc.c [moved from drivers/gpu/drm/meson/meson_crtc.c with 100% similarity]
drivers/amlogic/drm/meson_crtc.h [moved from drivers/gpu/drm/meson/meson_crtc.h with 100% similarity]
drivers/amlogic/drm/meson_dmabuf.c [new file with mode: 0644]
drivers/amlogic/drm/meson_dmabuf.h [new file with mode: 0644]
drivers/amlogic/drm/meson_drv.c [moved from drivers/gpu/drm/meson/meson_drv.c with 91% similarity]
drivers/amlogic/drm/meson_drv.h [moved from drivers/gpu/drm/meson/meson_drv.h with 100% similarity]
drivers/amlogic/drm/meson_gem.c [new file with mode: 0644]
drivers/amlogic/drm/meson_gem.h [new file with mode: 0644]
drivers/amlogic/drm/meson_plane.c [moved from drivers/gpu/drm/meson/meson_plane.c with 100% similarity]
drivers/amlogic/drm/meson_plane.h [moved from drivers/gpu/drm/meson/meson_plane.h with 100% similarity]
drivers/amlogic/drm/meson_registers.h [moved from drivers/gpu/drm/meson/meson_registers.h with 100% similarity]
drivers/amlogic/drm/meson_vclk.c [moved from drivers/gpu/drm/meson/meson_vclk.c with 100% similarity]
drivers/amlogic/drm/meson_vclk.h [moved from drivers/gpu/drm/meson/meson_vclk.h with 100% similarity]
drivers/amlogic/drm/meson_venc.c [moved from drivers/gpu/drm/meson/meson_venc.c with 100% similarity]
drivers/amlogic/drm/meson_venc.h [moved from drivers/gpu/drm/meson/meson_venc.h with 100% similarity]
drivers/amlogic/drm/meson_venc_cvbs.c [moved from drivers/gpu/drm/meson/meson_venc_cvbs.c with 100% similarity]
drivers/amlogic/drm/meson_venc_cvbs.h [moved from drivers/gpu/drm/meson/meson_venc_cvbs.h with 100% similarity]
drivers/amlogic/drm/meson_viu.c [moved from drivers/gpu/drm/meson/meson_viu.c with 100% similarity]
drivers/amlogic/drm/meson_viu.h [moved from drivers/gpu/drm/meson/meson_viu.h with 100% similarity]
drivers/amlogic/drm/meson_vpp.c [moved from drivers/gpu/drm/meson/meson_vpp.c with 100% similarity]
drivers/amlogic/drm/meson_vpp.h [moved from drivers/gpu/drm/meson/meson_vpp.h with 100% similarity]
drivers/gpu/drm/Kconfig
drivers/gpu/drm/Makefile
drivers/gpu/drm/meson/Makefile [deleted file]
include/linux/meson_ion.h [new file with mode: 0644]

index 7a91f58..55fdb30 100644 (file)
@@ -13572,6 +13572,7 @@ F: drivers/amlogic/dispaly/*
 AMLOGIC ION device
 M: Simon Zheng <simon.zheng@amlogic.com>
 F:     drivers/amlogic/media/common/ion_dev/*
+F:     include/linux/meson_ion.h
 
 AMLOGIC multimedia osd & ge2d
 M:     Pengcheng Chen <pengcheng.chen@amlogic.com>
@@ -14002,3 +14003,13 @@ F: sound/soc/amlogic/auge/*
 F: sound/soc/codecs/amlogic/pdm_dummy.c
 F: sound/soc/codecs/amlogic/tlv320adc3101.c
 
+DRM DRIVERS FOR AMLOGIC SOCS
+M:     Neil Armstrong <narmstrong@baylibre.com>
+L:     dri-devel@lists.freedesktop.org
+L:     linux-amlogic@lists.infradead.org
+W:     http://linux-meson.com/
+S:     Supported
+F:     drivers/amlogic/drm/
+F:     Documentation/devicetree/bindings/display/amlogic,meson-vpu.txt
+F:     Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.txt
+T:     git git://anongit.freedesktop.org/drm/drm-misc
index 6cccc5a..78d4a3d 100644 (file)
@@ -109,5 +109,8 @@ source "drivers/amlogic/irblaster/Kconfig"
 source "drivers/amlogic/iio/Kconfig"
 
 source "drivers/amlogic/ddr_window/Kconfig"
+
+source "drivers/amlogic/drm/Kconfig"
+
 endmenu
 endif
index 198d21d..35a0bce 100644 (file)
@@ -93,3 +93,5 @@ obj-$(CONFIG_AMLOGIC_IRBLASTER) += irblaster/
 obj-$(CONFIG_AMLOGIC_IIO)       += iio/
 
 obj-$(AMLOGIC_DDR_WINDOW_TOOL)       += ddr_window/
+
+obj-$(CONFIG_DRM_MESON)        += drm/
diff --git a/drivers/amlogic/drm/Makefile b/drivers/amlogic/drm/Makefile
new file mode 100644 (file)
index 0000000..93c47c4
--- /dev/null
@@ -0,0 +1,5 @@
+meson-y := meson_drv.o  meson_gem.o meson_dmabuf.o
+#meson-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_canvas.o meson_plane.o meson_crtc.o meson_venc_cvbs.o
+
+obj-$(CONFIG_DRM_MESON) += meson.o
+ccflags-y += -Idrivers/staging/android/
diff --git a/drivers/amlogic/drm/meson_dmabuf.c b/drivers/amlogic/drm/meson_dmabuf.c
new file mode 100644 (file)
index 0000000..aba629d
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * drivers/amlogic/drm/meson_dmabuf.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <drm/drmP.h>
+#include <linux/dma-buf.h>
+#include <ion/ion.h>
+
+#include "meson_gem.h"
+#include "meson_dmabuf.h"
+
+struct dma_buf *meson_dmabuf_prime_export(struct drm_device *drm_dev,
+                               struct drm_gem_object *obj, int flags)
+{
+       struct meson_gem_object *meson_gem_obj;
+       struct ion_handle *handle;
+
+       meson_gem_obj = container_of(obj, struct meson_gem_object, base);
+       handle = meson_gem_obj->handle;
+
+       if (!handle)
+               return ERR_PTR(-EINVAL);
+
+       return ion_share_dma_buf(handle->client, handle);
+}
+
+struct drm_gem_object *meson_dmabuf_prime_import(struct drm_device *drm_dev,
+                                               struct dma_buf *dma_buf)
+{
+       struct dma_buf_attachment *attach;
+       struct sg_table *sgt;
+       struct meson_gem_object *meson_gem_obj;
+       int ret;
+
+       attach = dma_buf_attach(dma_buf, drm_dev->dev);
+       if (IS_ERR(attach))
+               return ERR_PTR(-EINVAL);
+
+       get_dma_buf(dma_buf);
+
+       sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
+       if (IS_ERR_OR_NULL(sgt)) {
+               ret = PTR_ERR(sgt);
+               goto err_buf_detach;
+       }
+
+       meson_gem_obj = meson_drm_gem_init(drm_dev, dma_buf->size);
+       if (!meson_gem_obj) {
+               ret = -ENOMEM;
+               goto err_unmap_attach;
+       }
+
+       meson_gem_obj->sgt = sgt;
+       meson_gem_obj->base.import_attach = attach;
+
+       return &meson_gem_obj->base;
+
+err_unmap_attach:
+       dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
+err_buf_detach:
+       dma_buf_detach(dma_buf, attach);
+       dma_buf_put(dma_buf);
+
+       return ERR_PTR(ret);
+}
diff --git a/drivers/amlogic/drm/meson_dmabuf.h b/drivers/amlogic/drm/meson_dmabuf.h
new file mode 100644 (file)
index 0000000..3afcf0b
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * drivers/amlogic/drm/meson_dmabuf.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef _MESON_DRM_DMABUF_H_
+#define _MESON_DRM_DMABUF_H_
+
+struct dma_buf *meson_dmabuf_prime_export(struct drm_device *drm_dev,
+                               struct drm_gem_object *obj, int flags);
+
+struct drm_gem_object *meson_dmabuf_prime_import(struct drm_device *drm_dev,
+                                               struct dma_buf *dma_buf);
+
+#endif /* MESON_DRM_DMABUF_H */
similarity index 91%
rename from drivers/gpu/drm/meson/meson_drv.c
rename to drivers/amlogic/drm/meson_drv.c
index ff1f601..b8e58db 100644 (file)
 #include <linux/of_graph.h>
 
 #include <drm/drmP.h>
+
+/* #define MUSE */
+#ifdef MUSE
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_flip_work.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_plane_helper.h>
+#endif
+
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_fb_cma_helper.h>
 #include <drm/drm_rect.h>
@@ -47,6 +52,8 @@
 #include "meson_venc.h"
 #include "meson_canvas.h"
 #include "meson_registers.h"
+#include "meson_gem.h"
+#include "meson_dmabuf.h"
 
 #define DRIVER_NAME "meson"
 #define DRIVER_DESC "Amlogic Meson DRM driver"
  * - Powering Up HDMI controller and PHY
  */
 
+#ifdef MUSE
 static void meson_fb_output_poll_changed(struct drm_device *dev)
 {
        struct meson_drm *priv = dev->dev_private;
 
        drm_fbdev_cma_hotplug_event(priv->fbdev);
 }
-
 static const struct drm_mode_config_funcs meson_mode_config_funcs = {
        .output_poll_changed = meson_fb_output_poll_changed,
        .atomic_check        = drm_atomic_helper_check,
@@ -106,6 +113,7 @@ static irqreturn_t meson_irq(int irq, void *arg)
 
        return IRQ_HANDLED;
 }
+#endif
 
 static const struct file_operations fops = {
        .owner          = THIS_MODULE,
@@ -122,6 +130,9 @@ static const struct file_operations fops = {
 };
 
 static struct drm_driver meson_driver = {
+       .driver_features        =  DRIVER_GEM | DRIVER_PRIME,
+
+#ifdef MUSE
        .driver_features        = DRIVER_HAVE_IRQ | DRIVER_GEM |
                                  DRIVER_MODESET | DRIVER_PRIME |
                                  DRIVER_ATOMIC,
@@ -133,24 +144,22 @@ static struct drm_driver meson_driver = {
 
        /* IRQ */
        .irq_handler            = meson_irq,
+#endif
 
        /* PRIME Ops */
        .prime_handle_to_fd     = drm_gem_prime_handle_to_fd,
        .prime_fd_to_handle     = drm_gem_prime_fd_to_handle,
-       .gem_prime_import       = drm_gem_prime_import,
-       .gem_prime_export       = drm_gem_prime_export,
-       .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
-       .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
-       .gem_prime_vmap         = drm_gem_cma_prime_vmap,
-       .gem_prime_vunmap       = drm_gem_cma_prime_vunmap,
-       .gem_prime_mmap         = drm_gem_cma_prime_mmap,
+       .gem_prime_import       = meson_dmabuf_prime_import,
+       .gem_prime_export       = meson_dmabuf_prime_export,
 
        /* GEM Ops */
-       .dumb_create            = drm_gem_cma_dumb_create,
-       .dumb_destroy           = drm_gem_dumb_destroy,
-       .dumb_map_offset        = drm_gem_cma_dumb_map_offset,
-       .gem_free_object_unlocked = drm_gem_cma_free_object,
-       .gem_vm_ops             = &drm_gem_cma_vm_ops,
+       .open                           = meson_drm_gem_open,
+       .postclose                      = meson_drm_gem_close,
+       .dumb_create            = meson_drm_gem_dumb_create,
+       .dumb_destroy           = meson_drm_gem_dumb_destroy,
+       .dumb_map_offset        = meson_drm_gem_dumb_map_offset,
+       .gem_free_object        = meson_drm_gem_free_object,
+       .gem_vm_ops                     = &drm_gem_cma_vm_ops,
 
        /* Misc */
        .fops                   = &fops,
@@ -161,6 +170,7 @@ static struct drm_driver meson_driver = {
        .minor                  = 0,
 };
 
+#ifdef MUSE
 static bool meson_vpu_has_available_connectors(struct device *dev)
 {
        struct device_node *ep, *remote;
@@ -182,21 +192,25 @@ static struct regmap_config meson_regmap_config = {
        .reg_stride     = 4,
        .max_register   = 0x1000,
 };
+#endif
 
 static int meson_drv_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct meson_drm *priv;
        struct drm_device *drm;
+       int ret;
+
+#ifdef MUSE
        struct resource *res;
        void __iomem *regs;
-       int ret;
 
        /* Checks if an output connector is available */
        if (!meson_vpu_has_available_connectors(dev)) {
                dev_err(dev, "No output connector available\n");
                return -ENODEV;
        }
+#endif
 
        drm = drm_dev_alloc(&meson_driver, dev);
        if (IS_ERR(drm))
@@ -211,6 +225,7 @@ static int meson_drv_probe(struct platform_device *pdev)
        priv->drm = drm;
        priv->dev = dev;
 
+#ifdef MUSE
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpu");
        regs = devm_ioremap_resource(dev, res);
        if (IS_ERR(regs))
@@ -287,6 +302,7 @@ static int meson_drv_probe(struct platform_device *pdev)
        }
 
        drm_kms_helper_poll_init(drm);
+#endif
 
        platform_set_drvdata(pdev, priv);
 
@@ -297,7 +313,11 @@ static int meson_drv_probe(struct platform_device *pdev)
        return 0;
 
 free_drm:
+       DRM_DEBUG("free-drm");
+
+#ifdef MUSE
        drm_dev_unref(drm);
+#endif
 
        return ret;
 }
@@ -305,14 +325,18 @@ free_drm:
 static int meson_drv_remove(struct platform_device *pdev)
 {
        struct drm_device *drm = dev_get_drvdata(&pdev->dev);
+#ifdef MUSE
        struct meson_drm *priv = drm->dev_private;
+#endif
 
        drm_dev_unregister(drm);
+#ifdef MUSE
        drm_kms_helper_poll_fini(drm);
        drm_fbdev_cma_fini(priv->fbdev);
        drm_mode_config_cleanup(drm);
        drm_vblank_cleanup(drm);
        drm_dev_unref(drm);
+#endif
 
        return 0;
 }
diff --git a/drivers/amlogic/drm/meson_gem.c b/drivers/amlogic/drm/meson_gem.c
new file mode 100644 (file)
index 0000000..28d68f0
--- /dev/null
@@ -0,0 +1,313 @@
+/*
+ * drivers/amlogic/drm/meson_gem.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_gem.h>
+#include <drm/drm_vma_manager.h>
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <ion/ion.h>
+#include <linux/meson_ion.h>
+
+#include "meson_drv.h"
+#include "meson_gem.h"
+
+
+struct meson_gem_object *meson_drm_gem_init(struct drm_device *dev,
+               unsigned long size)
+{
+       struct meson_gem_object *meson_gem_obj;
+       struct drm_gem_object *obj;
+       int ret;
+
+       meson_gem_obj = kzalloc(sizeof(*meson_gem_obj), GFP_KERNEL);
+       if (!meson_gem_obj)
+               return NULL;
+
+       meson_gem_obj->size = size;
+       obj = &meson_gem_obj->base;
+
+       ret = drm_gem_object_init(dev, obj, size);
+       if (ret < 0) {
+               DRM_ERROR("failed to initialize gem object\n");
+               kfree(meson_gem_obj);
+               return NULL;
+       }
+
+       DRM_DEBUG("created file object = 0x%lx\n", (unsigned long)obj->filp);
+
+       return meson_gem_obj;
+}
+
+static int meson_drm_alloc_buf(struct ion_client *client,
+               struct meson_gem_object *meson_gem_obj, int flags)
+{
+       if (!client)
+               return -EINVAL;
+
+       if (!meson_gem_obj)
+               return -EINVAL;
+
+       meson_gem_obj->handle = ion_alloc(client,
+                       meson_gem_obj->size,
+                       0,
+                       (1 << ION_HEAP_TYPE_SYSTEM),
+                       0);
+
+       if (!meson_gem_obj->handle)
+               return -ENOMEM;
+
+       return 0;
+}
+
+static struct meson_gem_object *meson_drm_gem_create(struct drm_device *dev,
+               unsigned int flags,
+               unsigned long size,
+               struct ion_client *client)
+{
+       struct meson_gem_object *meson_gem_obj;
+       int ret;
+
+       if (!size) {
+               DRM_ERROR("invalid size.\n");
+               return ERR_PTR(-EINVAL);
+       }
+
+       size = round_up(size, PAGE_SIZE);
+       meson_gem_obj = meson_drm_gem_init(dev, size);
+       if (!meson_gem_obj) {
+               ret = -ENOMEM;
+               return ERR_PTR(ret);
+       }
+
+       ret = meson_drm_alloc_buf(client, meson_gem_obj, flags);
+       if (ret < 0)
+               goto err_gem_fini;
+
+       return meson_gem_obj;
+
+err_gem_fini:
+       drm_gem_object_release(&meson_gem_obj->base);
+       kfree(meson_gem_obj);
+       return ERR_PTR(ret);
+}
+
+static int meson_drm_gem_handle_create(struct drm_gem_object *obj,
+               struct drm_file *file_priv,
+               unsigned int *handle)
+{
+       int ret;
+
+       /*
+        * allocate a id of idr table where the obj is registered
+        * and handle has the id what user can see.
+        */
+       ret = drm_gem_handle_create(file_priv, obj, handle);
+       if (ret)
+               return ret;
+
+       DRM_DEBUG("gem handle = 0x%x\n", *handle);
+
+       /* drop reference from allocate - handle holds it now. */
+       drm_gem_object_unreference_unlocked(obj);
+
+       return 0;
+}
+
+static void meson_drm_free_buf(struct drm_device *dev,
+               struct meson_gem_object *meson_gem_obj)
+{
+       struct ion_client *client = NULL;
+
+       if (meson_gem_obj->handle) {
+               client = meson_gem_obj->handle->client;
+               ion_free(client, meson_gem_obj->handle);
+       } else {
+               DRM_ERROR("meson_gem_obj handle is null\n");
+       }
+}
+
+void meson_drm_gem_destroy(struct meson_gem_object *meson_gem_obj)
+{
+       struct drm_gem_object *obj;
+
+       obj = &meson_gem_obj->base;
+
+       DRM_DEBUG("handle count = %d\n", obj->handle_count);
+
+       /*
+        * do not release memory region from exporter.
+        *
+        * the region will be released by exporter
+        * once dmabuf's refcount becomes 0.
+        */
+       if (obj->import_attach)
+               goto out;
+
+       meson_drm_free_buf(obj->dev, meson_gem_obj);
+
+out:
+
+       drm_gem_free_mmap_offset(obj);
+
+       /* release file pointer to gem object. */
+       drm_gem_object_release(obj);
+
+       kfree(meson_gem_obj);
+       meson_gem_obj = NULL;
+}
+
+int meson_drm_gem_dumb_create(struct drm_file *file_priv,
+               struct drm_device *dev, struct drm_mode_create_dumb *args)
+{
+       int ret = 0;
+       struct meson_gem_object *meson_gem_obj;
+       struct drm_meson_file_private *f = file_priv->driver_priv;
+
+       struct ion_client *client = (struct ion_client *) f->client;
+       int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
+
+       args->pitch = ALIGN(min_pitch, 64);
+       if (args->size < args->pitch * args->height)
+               args->size = args->pitch * args->height;
+
+       meson_gem_obj = meson_drm_gem_create(dev, 0, args->size, client);
+
+       if (IS_ERR(meson_gem_obj))
+               return PTR_ERR(meson_gem_obj);
+
+       ret = meson_drm_gem_handle_create(&meson_gem_obj->base, file_priv,
+                       &args->handle);
+       if (ret) {
+               meson_drm_gem_destroy(meson_gem_obj);
+               return ret;
+       }
+
+       return 0;
+}
+
+int meson_drm_gem_dumb_map_offset(struct drm_file *file_priv,
+               struct drm_device *dev, uint32_t handle,
+               uint64_t *offset)
+{
+       struct drm_gem_object *obj;
+       int ret = 0;
+
+       mutex_lock(&dev->struct_mutex);
+
+       /*
+        * get offset of memory allocated for drm framebuffer.
+        * - this callback would be called by user application
+        *      with DRM_IOCTL_MODE_MAP_DUMB command.
+        */
+
+       obj = drm_gem_object_lookup(file_priv, handle);
+       if (!obj) {
+               DRM_ERROR("failed to lookup gem object.\n");
+               ret = -EINVAL;
+               goto unlock;
+       }
+
+       ret = drm_gem_create_mmap_offset(obj);
+       if (ret)
+               goto out;
+
+       *offset = drm_vma_node_offset_addr(&obj->vma_node);
+       DRM_DEBUG("offset = 0x%lx\n", (unsigned long)*offset);
+
+out:
+       drm_gem_object_unreference(obj);
+unlock:
+       mutex_unlock(&dev->struct_mutex);
+       return ret;
+}
+
+void meson_drm_gem_free_object(struct drm_gem_object *obj)
+{
+       struct meson_gem_object *meson_gem_obj;
+
+       meson_gem_obj = container_of(obj, struct meson_gem_object, base);
+
+       if (obj->import_attach)
+               drm_prime_gem_destroy(obj, meson_gem_obj->sgt);
+
+       meson_drm_gem_destroy(meson_gem_obj);
+}
+
+int meson_drm_gem_dumb_destroy(struct drm_file *file,
+               struct drm_device *dev,
+               uint32_t handle)
+{
+       struct drm_gem_object *obj;
+
+       spin_lock(&file->table_lock);
+       obj = idr_find(&file->object_idr, handle);
+       if (obj == NULL) {
+               spin_unlock(&file->table_lock);
+               return -EINVAL;
+       }
+       spin_unlock(&file->table_lock);
+
+       drm_gem_handle_delete(file, handle);
+
+       /*
+        * we still have a reference to dma_buf because the ion_handle,
+        * when gem obj handle count become zero and refcount is 1.
+        * It will not release when dma_buf_ops.release is called.
+        * we have to drop it here.
+        * drop the reference on the export fd holds
+        */
+
+       if (obj->handle_count == 0 &&
+                       atomic_read(&obj->refcount.refcount) == 1)
+               drm_gem_object_unreference_unlocked(obj);
+
+       return 0;
+}
+
+int meson_drm_gem_open(struct drm_device *dev, struct drm_file *file)
+{
+       struct drm_meson_file_private *file_priv;
+
+       file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
+       if (!file_priv) {
+               DRM_ERROR("drm_meson file private alloc fail\n");
+               return -ENOMEM;
+       }
+
+       file_priv->client = meson_ion_client_create(-1, "meson-gem");
+       if (!file_priv->client) {
+               DRM_ERROR("open ion client error\n");
+               return -EFAULT;
+       }
+
+       DRM_DEBUG("open ion client: %p\n", file_priv->client);
+       file->driver_priv = (void *) file_priv;
+       return 0;
+}
+
+void meson_drm_gem_close(struct drm_device *dev, struct drm_file *file)
+{
+       struct drm_meson_file_private *file_priv = file->driver_priv;
+       struct ion_client *gem_ion_client = file_priv->client;
+
+       if (gem_ion_client) {
+               DRM_DEBUG(" destroy ion client: %p\n", gem_ion_client);
+               ion_client_destroy(gem_ion_client);
+       }
+}
diff --git a/drivers/amlogic/drm/meson_gem.h b/drivers/amlogic/drm/meson_gem.h
new file mode 100644 (file)
index 0000000..3766ae9
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * drivers/amlogic/drm/meson_gem.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __MESON_GEM_H
+#define __MESON_GEM_H
+#include  <drm/drm_gem.h>
+#include <ion/ion_priv.h>
+
+struct drm_meson_file_private {
+       struct ion_client *client;
+};
+
+struct meson_gem_object {
+       struct drm_gem_object base;
+       struct ion_handle *handle;
+       struct sg_table *sgt;
+       unsigned long size;
+       unsigned int flags;
+};
+
+/* create memory region for drm */
+int meson_drm_gem_dumb_create(struct drm_file *file_priv,
+                struct drm_device *dev,
+                struct drm_mode_create_dumb *args);
+
+/* map memory region for drm to user space. */
+int meson_drm_gem_dumb_map_offset(struct drm_file *file_priv,
+                struct drm_device *dev, uint32_t handle,
+                uint64_t *offset);
+
+/* free gem object. */
+void meson_drm_gem_free_object(struct drm_gem_object *gem_obj);
+
+struct meson_gem_object *meson_drm_gem_init(struct drm_device *dev,
+                unsigned long size);
+
+int meson_drm_gem_dumb_destroy(struct drm_file *file,
+                struct drm_device *dev,
+                uint32_t handle);
+
+int meson_drm_gem_open(struct drm_device *dev, struct drm_file *file);
+void meson_drm_gem_close(struct drm_device *dev, struct drm_file *file);
+
+#endif /* __MESON_GEM_H */
index c25cfd1..43cb33d 100644 (file)
@@ -224,8 +224,6 @@ source "drivers/gpu/drm/hisilicon/Kconfig"
 
 source "drivers/gpu/drm/mediatek/Kconfig"
 
-source "drivers/gpu/drm/meson/Kconfig"
-
 # Keep legacy drivers last
 
 menuconfig DRM_LEGACY
index 47e7c45..25c7204 100644 (file)
@@ -79,7 +79,6 @@ obj-$(CONFIG_DRM_TEGRA) += tegra/
 obj-$(CONFIG_DRM_STI) += sti/
 obj-$(CONFIG_DRM_IMX) += imx/
 obj-$(CONFIG_DRM_MEDIATEK) += mediatek/
-obj-$(CONFIG_DRM_MESON)        += meson/
 obj-y                  += i2c/
 obj-y                  += panel/
 obj-y                  += bridge/
diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile
deleted file mode 100644 (file)
index 2591978..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-meson-y := meson_drv.o meson_plane.o meson_crtc.o meson_venc_cvbs.o
-meson-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_canvas.o
-
-obj-$(CONFIG_DRM_MESON) += meson.o
diff --git a/include/linux/meson_ion.h b/include/linux/meson_ion.h
new file mode 100644 (file)
index 0000000..ce19cb0
--- /dev/null
@@ -0,0 +1 @@
+#include "../../drivers/amlogic/media/common/ion_dev/meson_ion.h"