diff --git a/drivers/amlogic/media/common/ge2d/ge2d_dmabuf.c b/drivers/amlogic/media/common/ge2d/ge2d_dmabuf.c index 5225e72d91ea..046cb1e0f4de 100644 --- a/drivers/amlogic/media/common/ge2d/ge2d_dmabuf.c +++ b/drivers/amlogic/media/common/ge2d/ge2d_dmabuf.c @@ -515,6 +515,7 @@ int ge2d_dma_buffer_map(struct aml_dma_cfg *cfg) cfg->attach = d_att; cfg->vaddr = vaddr; cfg->sg = sg; + ge2d_log_dbg("%s\n", __func__); return ret; vmap_err: @@ -549,7 +550,6 @@ int ge2d_dma_buffer_get_phys(struct aml_dma_cfg *cfg, unsigned long *addr) *addr = PFN_PHYS(page_to_pfn(page)); ret = 0; } - ge2d_dma_buffer_unmap(cfg); return ret; } @@ -586,6 +586,8 @@ void ge2d_dma_buffer_unmap(struct aml_dma_cfg *cfg) dma_buf_detach(dbuf, d_att); dma_buf_put(dbuf); + + ge2d_log_dbg("%s\n", __func__); } void ge2d_dma_buffer_dma_flush(struct device *dev, int fd) diff --git a/drivers/amlogic/media/common/ge2d/ge2d_wq.c b/drivers/amlogic/media/common/ge2d/ge2d_wq.c index 7084a14475b4..2420c2856d9b 100644 --- a/drivers/amlogic/media/common/ge2d/ge2d_wq.c +++ b/drivers/amlogic/media/common/ge2d/ge2d_wq.c @@ -335,7 +335,25 @@ static int ge2d_process_work_queue(struct ge2d_context_s *wq) pos = pos->next; list_move_tail(&pitem->list, &wq->free_queue); spin_unlock(&wq->lock); - + /* if dma buf detach it */ + if (pitem->config.src_dma_cfg.dma_used) { + ge2d_dma_buffer_unmap((struct aml_dma_cfg * + )pitem->config.src_dma_cfg.dma_cfg); + pitem->config.src_dma_cfg.dma_used = 0; + kfree(pitem->config.src_dma_cfg.dma_cfg); + } + if (pitem->config.src2_dma_cfg.dma_used) { + ge2d_dma_buffer_unmap((struct aml_dma_cfg * + )pitem->config.src2_dma_cfg.dma_cfg); + pitem->config.src2_dma_cfg.dma_used = 0; + kfree(pitem->config.src2_dma_cfg.dma_cfg); + } + if (pitem->config.dst_dma_cfg.dma_used) { + ge2d_dma_buffer_unmap((struct aml_dma_cfg * + )pitem->config.dst_dma_cfg.dma_cfg); + pitem->config.dst_dma_cfg.dma_used = 0; + kfree(pitem->config.dst_dma_cfg.dma_cfg); + } pitem = (struct ge2d_queue_item_s *)pos; } while (pos != head); ge2d_manager.last_wq = wq; @@ -352,6 +370,29 @@ static irqreturn_t ge2d_wq_handle(int irq_number, void *para) return IRQ_HANDLED; } +struct ge2d_dma_cfg_s *ge2d_wq_get_dma_cfg(struct ge2d_context_s *wq, + unsigned int data_type) +{ + struct ge2d_dma_cfg_s *dma_cfg = NULL; + + switch (data_type) { + case AML_GE2D_SRC: + dma_cfg = &wq->config.src_dma_cfg; + break; + case AML_GE2D_SRC2: + dma_cfg = &wq->config.src2_dma_cfg; + break; + case AML_GE2D_DST: + dma_cfg = &wq->config.dst_dma_cfg; + break; + default: + ge2d_log_err("wrong data_type\n"); + break; + } + + return dma_cfg; +} + struct ge2d_src1_data_s *ge2d_wq_get_src_data(struct ge2d_context_s *wq) { return &wq->config.src1_data; @@ -930,11 +971,13 @@ static int build_ge2d_addr_config_ion( } static int build_ge2d_addr_config_dma( + struct ge2d_context_s *context, struct config_planes_ion_s *plane, unsigned int format, unsigned int *addr, unsigned int *stride, - unsigned int dir + unsigned int dir, + unsigned int data_type ) { int ret = -1; @@ -946,12 +989,19 @@ static int build_ge2d_addr_config_dma( bpp_value); if (plane) { if (plane[0].shared_fd) { - struct aml_dma_cfg cfg; + struct ge2d_dma_cfg_s *cfg = NULL; + struct aml_dma_cfg *dma_cfg = NULL; - cfg.fd = plane[0].shared_fd; - cfg.dev = &(ge2d_manager.pdev->dev); - cfg.dir = dir; - ret = ge2d_dma_buffer_get_phys(&cfg, &addr_temp); + cfg = ge2d_wq_get_dma_cfg(context, data_type); + if (!cfg) + return -1; + cfg->dma_used = 1; + dma_cfg = kzalloc(sizeof(*dma_cfg), GFP_KERNEL); + dma_cfg->fd = plane[0].shared_fd; + 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); if (ret != 0) return ret; } @@ -1110,12 +1160,14 @@ static int build_ge2d_config_ex_ion(struct config_planes_ion_s *plane, } return ret; } -static int build_ge2d_config_ex_dma(struct config_planes_ion_s *plane, +static int build_ge2d_config_ex_dma(struct ge2d_context_s *context, + struct config_planes_ion_s *plane, unsigned int format, unsigned int *canvas_index, int index, unsigned int *r_offset, - unsigned int dir) + unsigned int dir, + unsigned int data_type) { int bpp_value = bpp(format); int ret = -1; @@ -1125,12 +1177,19 @@ static int build_ge2d_config_ex_dma(struct config_planes_ion_s *plane, index &= 0xff; if (plane) { if (plane[0].shared_fd) { - struct aml_dma_cfg cfg; + struct ge2d_dma_cfg_s *cfg = NULL; + struct aml_dma_cfg *dma_cfg = NULL; - cfg.fd = plane[0].shared_fd; - cfg.dev = &(ge2d_manager.pdev->dev); - cfg.dir = dir; - ret = ge2d_dma_buffer_get_phys(&cfg, &addr); + cfg = ge2d_wq_get_dma_cfg(context, data_type); + if (!cfg) + return -1; + cfg->dma_used = 1; + dma_cfg = kzalloc(sizeof(*dma_cfg), GFP_KERNEL); + dma_cfg->fd = plane[0].shared_fd; + 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); ge2d_log_info("phys: addr=%lx\n", addr); if (ret != 0) return ret; @@ -2017,11 +2076,13 @@ int ge2d_context_config_ex_mem(struct ge2d_context_s *context, } else if (ge2d_config_mem->src1_mem_alloc_type == AML_GE2D_MEM_DMABUF) { if (build_ge2d_addr_config_dma( + context, &ge2d_config->src_planes[0], ge2d_config->src_para.format, &src_addr, &src_stride, - DMA_TO_DEVICE) < 0) + DMA_TO_DEVICE, + AML_GE2D_SRC) < 0) return -1; ge2d_log_dbg("ge2d dma alloc phy_addr:0x%x,stride=0x%x,format:0x%x\n", src_addr, @@ -2045,13 +2106,15 @@ int ge2d_context_config_ex_mem(struct ge2d_context_s *context, } else if (ge2d_config_mem->src1_mem_alloc_type == AML_GE2D_MEM_DMABUF) { if (build_ge2d_config_ex_dma( + context, &ge2d_config->src_planes[0], ge2d_config->src_para.format, &index, ALLOC_CANVAS_INDEX + alloc_canvas_offset, &alloc_canvas_offset, - DMA_TO_DEVICE) < 0) + DMA_TO_DEVICE, + AML_GE2D_SRC) < 0) return -1; ge2d_config->src_para.canvas_index = index; ge2d_log_dbg("ge2d dma alloc canvas index:0x%x, format:0x%x\n", @@ -2126,11 +2189,13 @@ int ge2d_context_config_ex_mem(struct ge2d_context_s *context, } else if (ge2d_config_mem->src2_mem_alloc_type == AML_GE2D_MEM_DMABUF) { if (build_ge2d_addr_config_dma( + context, &ge2d_config->src2_planes[0], ge2d_config->src2_para.format, &src2_addr, &src2_stride, - DMA_TO_DEVICE) < 0) + DMA_TO_DEVICE, + AML_GE2D_SRC2) < 0) return -1; ge2d_log_dbg("ge2d dma alloc phy_addr:0x%x,stride=0x%x,format:0x%x\n", src2_addr, @@ -2154,13 +2219,15 @@ int ge2d_context_config_ex_mem(struct ge2d_context_s *context, } else if (ge2d_config_mem->src2_mem_alloc_type == AML_GE2D_MEM_DMABUF) { if (build_ge2d_config_ex_dma( + context, &ge2d_config->src2_planes[0], ge2d_config->src2_para.format, &index, ALLOC_CANVAS_INDEX + alloc_canvas_offset, &alloc_canvas_offset, - DMA_TO_DEVICE) < 0) + DMA_TO_DEVICE, + AML_GE2D_SRC2) < 0) return -1; ge2d_config->src2_para.canvas_index = index; ge2d_log_dbg("ge2d src2 dma alloc, canvas index:0x%x,format:0x%x\n", @@ -2238,11 +2305,13 @@ int ge2d_context_config_ex_mem(struct ge2d_context_s *context, } else if (ge2d_config_mem->dst_mem_alloc_type == AML_GE2D_MEM_DMABUF) { if (build_ge2d_addr_config_dma( + context, &ge2d_config->dst_planes[0], ge2d_config->dst_para.format, &dst_addr, &dst_stride, - DMA_FROM_DEVICE) < 0) + DMA_FROM_DEVICE, + AML_GE2D_DST) < 0) return -1; ge2d_log_dbg("ge2d dma alloc phy_addr:0x%x,stride=0x%x,format:0x%x\n", dst_addr, @@ -2266,13 +2335,15 @@ int ge2d_context_config_ex_mem(struct ge2d_context_s *context, } else if (ge2d_config_mem->dst_mem_alloc_type == AML_GE2D_MEM_DMABUF) { if (build_ge2d_config_ex_dma( + context, &ge2d_config->dst_planes[0], ge2d_config->dst_para.format, &index, ALLOC_CANVAS_INDEX + alloc_canvas_offset, &alloc_canvas_offset, - DMA_FROM_DEVICE) < 0) + DMA_FROM_DEVICE, + AML_GE2D_DST) < 0) return -1; ge2d_config->dst_para.canvas_index = index; ge2d_log_dbg("ge2d: dst dma alloc, index:0x%x, format:0x%x\n", diff --git a/include/linux/amlogic/media/ge2d/ge2d.h b/include/linux/amlogic/media/ge2d/ge2d.h index 0ba9bd374936..c536a83cc00b 100644 --- a/include/linux/amlogic/media/ge2d/ge2d.h +++ b/include/linux/amlogic/media/ge2d/ge2d.h @@ -609,6 +609,11 @@ struct ge2d_cmd_s { unsigned char hang_flag; }; +struct ge2d_dma_cfg_s { + int dma_used; + void *dma_cfg; +}; + struct ge2d_config_s { struct ge2d_gen_s gen; struct ge2d_src1_data_s src1_data; @@ -619,6 +624,9 @@ struct ge2d_config_s { unsigned int v_scale_coef_type; unsigned int h_scale_coef_type; unsigned int update_flag; + struct ge2d_dma_cfg_s src_dma_cfg; + struct ge2d_dma_cfg_s src2_dma_cfg; + struct ge2d_dma_cfg_s dst_dma_cfg; }; struct ge2d_dma_buf_s { @@ -627,6 +635,13 @@ struct ge2d_dma_buf_s { int len; }; +enum ge2d_data_type_e { + AML_GE2D_SRC, + AML_GE2D_SRC2, + AML_GE2D_DST, + AML_GE2D_TYPE_INVALID, +}; + enum ge2d_src_dst_e { OSD0_OSD0 = 0, OSD0_OSD1,