ge2d: ge2d cpu cost optimize [2/2]
authorPengcheng Chen <pengcheng.chen@amlogic.com>
Fri, 19 Apr 2019 03:20:34 +0000 (11:20 +0800)
committerTao Zeng <tao.zeng@amlogic.com>
Fri, 24 May 2019 09:14:55 +0000 (02:14 -0700)
PD#SWPL-7422

Problem:
ge2d ioctl have cpu usage issue

Solution:
1. dma buffer alloc gdc module,when dma buf exported, fd and phys
address can be recorded.driver can get phys address via fd internally.
2. dmabuf alloc by other driver module, need used gdc_dma_buffer_map/
gdc_dma_buffer_unmap to get phys address.

Verify:
Newman & W400 board

Change-Id: I78d03b52e574daf2e8b2d53eb8fdfde06357ebfe
Signed-off-by: Pengcheng Chen <pengcheng.chen@amlogic.com>
drivers/amlogic/media/common/ge2d/ge2d_dmabuf.c
drivers/amlogic/media/common/ge2d/ge2d_dmabuf.h
drivers/amlogic/media/common/ge2d/ge2d_wq.c

index 3ed7684..f024876 100644 (file)
@@ -504,6 +504,7 @@ int ge2d_dma_buffer_export(struct aml_dma_buffer *buffer,
 
        ge2d_log_dbg("buffer %d,exported as %d descriptor\n",
                index, ret);
+       buffer->gd_buffer[index].fd = ret;
        ge2d_exp_buf->fd = ret;
        return 0;
 }
@@ -578,26 +579,74 @@ attach_err:
        return ret;
 }
 
-int ge2d_dma_buffer_get_phys(struct aml_dma_cfg *cfg, unsigned long *addr)
+static int ge2d_dma_buffer_get_phys_internal(struct aml_dma_buffer *buffer,
+       int fd, unsigned long *addr)
+{
+       int i = 0, ret = -1;
+       struct aml_dma_buf *dma_buf;
+
+       for (i = 0; i < AML_MAX_DMABUF; i++) {
+               if (buffer->gd_buffer[i].alloc &&
+                       (fd == buffer->gd_buffer[i].fd)) {
+                       dma_buf = buffer->gd_buffer[i].mem_priv;
+                       *addr = dma_buf->dma_addr;
+                       ret = 0;
+                       break;
+               }
+       }
+       return ret;
+}
+
+int ge2d_dma_buffer_get_phys(struct aml_dma_buffer *buffer,
+       struct aml_dma_cfg *cfg, unsigned long *addr)
 {
        struct sg_table *sg_table;
        struct page *page;
-       int ret;
+       int ret = -1;
 
-       ret = ge2d_dma_buffer_map(cfg);
-       if (ret < 0) {
-               pr_err("gdc_dma_buffer_map failed\n");
-               return ret;
+       if (cfg == NULL || (cfg->fd < 0)) {
+               pr_err("error input param");
+               return -EINVAL;
        }
-       if (cfg->sg) {
-               sg_table = cfg->sg;
-               page = sg_page(sg_table->sgl);
-               *addr = PFN_PHYS(page_to_pfn(page));
-               ret = 0;
+       ret = ge2d_dma_buffer_get_phys_internal(buffer, cfg->fd, addr);
+       if (ret < 0) {
+               ret = ge2d_dma_buffer_map(cfg);
+               if (ret < 0) {
+                       pr_err("gdc_dma_buffer_map failed\n");
+                       return ret;
+               }
+               if (cfg->sg) {
+                       sg_table = cfg->sg;
+                       page = sg_page(sg_table->sgl);
+                       *addr = PFN_PHYS(page_to_pfn(page));
+                       ret = 0;
+               }
        }
        return ret;
 }
 
+int ge2d_dma_buffer_unmap_info(struct aml_dma_buffer *buffer,
+       struct aml_dma_cfg *cfg)
+{
+       int i, found = 0;
+
+       if (cfg == NULL || (cfg->fd < 0)) {
+               pr_err("error input param");
+               return -EINVAL;
+       }
+
+       for (i = 0; i < AML_MAX_DMABUF; i++) {
+               if (buffer->gd_buffer[i].alloc &&
+                       (cfg->fd == buffer->gd_buffer[i].fd)) {
+                       found = 1;
+                       break;
+               }
+       }
+       if (!found)
+               ge2d_dma_buffer_unmap(cfg);
+       return 0;
+}
+
 void ge2d_dma_buffer_unmap(struct aml_dma_cfg *cfg)
 {
        int fd = -1;
index c3c03d3..baf80c4 100644 (file)
@@ -45,6 +45,7 @@ struct aml_dma_buf {
 struct aml_dma_buf_priv {
        void *mem_priv;
        int index;
+       int fd;
        unsigned int alloc;
        struct dma_buf *dbuf;
 };
@@ -75,7 +76,10 @@ int ge2d_dma_buffer_export(struct aml_dma_buffer *buffer,
        struct ge2d_dmabuf_exp_s *ge2d_exp_buf);
 int ge2d_dma_buffer_map(struct aml_dma_cfg *cfg);
 void ge2d_dma_buffer_unmap(struct aml_dma_cfg *cfg);
-int ge2d_dma_buffer_get_phys(struct aml_dma_cfg *cfg, unsigned long *addr);
+int ge2d_dma_buffer_get_phys(struct aml_dma_buffer *buffer,
+       struct aml_dma_cfg *cfg, unsigned long *addr);
+int ge2d_dma_buffer_unmap_info(struct aml_dma_buffer *buffer,
+       struct aml_dma_cfg *cfg);
 void ge2d_dma_buffer_dma_flush(struct device *dev, int fd);
 void ge2d_dma_buffer_cache_flush(struct device *dev, int fd);
 #endif
index 6be65f7..1549b97 100644 (file)
@@ -120,6 +120,10 @@ static const int default_ge2d_color_lut[] = {
        GE2D_FORMAT_S32_ARGB,/* BPP_TYPE_32_ARGB=32, */
 };
 
+static int ge2d_buffer_get_phys(struct aml_dma_cfg *cfg,
+       unsigned long *addr);
+static int ge2d_buffer_unmap(struct aml_dma_cfg *cfg);
+
 static void ge2d_pre_init(void)
 {
        struct ge2d_gen_s ge2d_gen_cfg;
@@ -392,19 +396,19 @@ static int ge2d_process_work_queue(struct ge2d_context_s *wq)
                /* if dma buf detach it */
                for (i = 0; i < MAX_PLANE; i++) {
                        if (pitem->config.src_dma_cfg[i].dma_used) {
-                               ge2d_dma_buffer_unmap((struct aml_dma_cfg *
+                               ge2d_buffer_unmap((struct aml_dma_cfg *
                                        )pitem->config.src_dma_cfg[i].dma_cfg);
                                pitem->config.src_dma_cfg[i].dma_used = 0;
                                kfree(pitem->config.src_dma_cfg[i].dma_cfg);
                        }
                        if (pitem->config.src2_dma_cfg[i].dma_used) {
-                               ge2d_dma_buffer_unmap((struct aml_dma_cfg *
+                               ge2d_buffer_unmap((struct aml_dma_cfg *
                                        )pitem->config.src2_dma_cfg[i].dma_cfg);
                                pitem->config.src2_dma_cfg[i].dma_used = 0;
                                kfree(pitem->config.src2_dma_cfg[i].dma_cfg);
                        }
                        if (pitem->config.dst_dma_cfg[i].dma_used) {
-                               ge2d_dma_buffer_unmap((struct aml_dma_cfg *
+                               ge2d_buffer_unmap((struct aml_dma_cfg *
                                        )pitem->config.dst_dma_cfg[i].dma_cfg);
                                pitem->config.dst_dma_cfg[i].dma_used = 0;
                                kfree(pitem->config.dst_dma_cfg[i].dma_cfg);
@@ -1058,7 +1062,7 @@ static int build_ge2d_addr_config_dma(
                        dma_cfg->dev = &(ge2d_manager.pdev->dev);
                        dma_cfg->dir = dir;
                        cfg->dma_cfg = dma_cfg;
-                       ret = ge2d_dma_buffer_get_phys(dma_cfg, &addr_temp);
+                       ret = ge2d_buffer_get_phys(dma_cfg, &addr_temp);
                        if (ret != 0)
                                return ret;
                }
@@ -1231,7 +1235,7 @@ static int build_ge2d_config_ex_dma(struct ge2d_context_s *context,
                                dma_cfg->dev = &(ge2d_manager.pdev->dev);
                                dma_cfg->dir = dir;
                                cfg->dma_cfg = dma_cfg;
-                               ret = ge2d_dma_buffer_get_phys(dma_cfg, &addr);
+                               ret = ge2d_buffer_get_phys(dma_cfg, &addr);
                                if (ret != 0)
                                        return ret;
                                plane[i].addr = addr;
@@ -1239,10 +1243,10 @@ static int build_ge2d_config_ex_dma(struct ge2d_context_s *context,
                                *r_offset += 1;
 #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
                                canvas_config(index++, plane[i].addr,
-                                                 plane[i].w * bpp_value,
-                                                 plane[i].h,
-                                                 CANVAS_ADDR_NOWRAP,
-                                                 CANVAS_BLKMODE_LINEAR);
+                                       plane[i].w * bpp_value,
+                                       plane[i].h,
+                                       CANVAS_ADDR_NOWRAP,
+                                       CANVAS_BLKMODE_LINEAR);
 #endif
                        } else if (plane[i].addr) {
                                plane[i].addr += plane[0].addr;
@@ -1250,10 +1254,10 @@ static int build_ge2d_config_ex_dma(struct ge2d_context_s *context,
                                *r_offset += 1;
 #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
                                canvas_config(index++, plane[i].addr,
-                                             plane[i].w * bpp_value,
-                                             plane[i].h,
-                                             CANVAS_ADDR_NOWRAP,
-                                             CANVAS_BLKMODE_LINEAR);
+                                               plane[i].w * bpp_value,
+                                               plane[i].h,
+                                               CANVAS_ADDR_NOWRAP,
+                                               CANVAS_BLKMODE_LINEAR);
 #endif
                        }
                }
@@ -2543,6 +2547,16 @@ void ge2d_buffer_cache_flush(int dma_fd)
        ge2d_dma_buffer_cache_flush(dev, dma_fd);
 }
 
+static int ge2d_buffer_get_phys(struct aml_dma_cfg *cfg, unsigned long *addr)
+{
+       return ge2d_dma_buffer_get_phys(ge2d_manager.buffer, cfg, addr);
+}
+
+static int ge2d_buffer_unmap(struct aml_dma_cfg *cfg)
+{
+       return ge2d_dma_buffer_unmap_info(ge2d_manager.buffer, cfg);
+}
+
 struct ge2d_context_s *create_ge2d_work_queue(void)
 {
        int  i;