drm_vpu: logo memory manage in drm_vpu
authorpengcheng chen <pengcheng.chen@amlogic.com>
Thu, 19 Apr 2018 08:53:20 +0000 (16:53 +0800)
committerpengcheng chen <pengcheng.chen@amlogic.com>
Fri, 20 Apr 2018 08:37:18 +0000 (16:37 +0800)
PD#160546: drm_vpu: logo memory manage in drm_vpu

Change-Id: I590caf78301f09f71dc005559a79656e8ff9c206
Signed-off-by: pengcheng chen <pengcheng.chen@amlogic.com>
arch/arm64/boot/dts/amlogic/g12a_s905d2_u200_drm_buildroot.dts
drivers/amlogic/drm/am_meson_vpu.c

index 04a3981..41244d0 100644 (file)
@@ -25,6 +25,9 @@
 #include <linux/of_device.h>
 #include <linux/of.h>
 #include <linux/component.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/dma-contiguous.h>
+#include <linux/cma.h>
 #ifdef CONFIG_DRM_MESON_USE_ION
 #include <ion/ion_priv.h>
 #endif
@@ -214,6 +217,10 @@ static struct osd_device_data_s osd_g12a = {
 };
 
 static struct osd_device_data_s osd_meson_dev;
+static u32 logo_memsize;
+static struct page *logo_page;
+static struct delayed_work osd_dwork;
+static struct platform_device *gp_dev;
 
 int am_meson_crtc_dts_info_set(const void *dt_match_data)
 {
@@ -671,6 +678,20 @@ static irqreturn_t am_meson_vpu_irq(int irq, void *arg)
        return IRQ_HANDLED;
 }
 
+static void mem_free_work(struct work_struct *work)
+{
+       if (logo_memsize > 0) {
+#ifdef CONFIG_CMA
+               pr_info("%s, free memory: addr:0x%x\n",
+                       __func__, logo_memsize);
+
+               dma_release_from_contiguous(&(gp_dev->dev),
+                       logo_page,
+                       logo_memsize >> PAGE_SHIFT);
+#endif
+       }
+}
+
 static int am_meson_vpu_bind(struct device *dev,
                                struct device *master, void *data)
 {
@@ -678,7 +699,9 @@ static int am_meson_vpu_bind(struct device *dev,
        struct drm_device *drm_dev = data;
        struct meson_drm *private = drm_dev->dev_private;
        struct am_meson_crtc *amcrtc;
-
+#ifdef CONFIG_CMA
+       struct cma *cma;
+#endif
        int ret, irq;
 
        /* Allocate crtc struct */
@@ -708,6 +731,33 @@ static int am_meson_vpu_bind(struct device *dev,
        /* IRQ is initially disabled; it gets enabled in crtc_enable */
        disable_irq(amcrtc->irq);
 
+       /* init reserved memory */
+       ret = of_reserved_mem_device_init(&pdev->dev);
+       if (ret != 0)
+               dev_err(dev, "failed to init reserved memory\n");
+       else {
+#ifdef CONFIG_CMA
+               gp_dev = pdev;
+               cma = dev_get_cma_area(&pdev->dev);
+               if (cma) {
+                       logo_memsize = cma_get_size(cma);
+                       pr_info("reserved memory base:0x%llx, size:0x%x\n",
+                               cma_get_base(cma), logo_memsize);
+                       if (logo_memsize > 0) {
+                               logo_page = dma_alloc_from_contiguous(
+                                       &pdev->dev,
+                                       logo_memsize >> PAGE_SHIFT,
+                                       0);
+                               if (!logo_page) {
+                                       pr_err("allocate buffer failed:%d\n",
+                                               logo_memsize);
+                               }
+                       }
+               } else
+                       pr_info("------ NO CMA\n");
+#endif
+       }
+
        ret = am_meson_plane_create(private);
        if (ret)
                return ret;
@@ -717,6 +767,8 @@ static int am_meson_vpu_bind(struct device *dev,
                return ret;
 
        am_meson_register_crtc_funcs(private->crtc, &meson_private_crtc_funcs);
+       INIT_DELAYED_WORK(&osd_dwork, mem_free_work);
+       schedule_delayed_work(&osd_dwork, msecs_to_jiffies(60 * 1000));
 
        return 0;
 }