diff --git a/drivers/video/rockchip/rga2/rga2.h b/drivers/video/rockchip/rga2/rga2.h index 80af65400edd..68268bb461c1 100644 --- a/drivers/video/rockchip/rga2/rga2.h +++ b/drivers/video/rockchip/rga2/rga2.h @@ -337,6 +337,18 @@ typedef struct rga_img_info_32_t } rga_img_info_32_t; +struct rga_dma_buffer_t { + /* DMABUF information */ + struct dma_buf *dma_buf; + struct dma_buf_attachment *attach; + struct sg_table *sgt; + + dma_addr_t iova; + unsigned long size; + void *vaddr; + enum dma_data_direction dir; +}; + struct rga_req { uint8_t render_mode; /* (enum) process mode sel */ @@ -578,14 +590,6 @@ struct rga2_req u8 rgb2yuv_mode; u8 buf_type; - struct sg_table *sg_src0; - struct sg_table *sg_src1; - struct sg_table *sg_dst; - struct sg_table *sg_els; - struct dma_buf_attachment *attach_src0; - struct dma_buf_attachment *attach_src1; - struct dma_buf_attachment *attach_dst; - struct dma_buf_attachment *attach_els; }; struct rga2_mmu_buf_t { @@ -726,15 +730,10 @@ struct rga2_reg { uint32_t MMU_len; bool MMU_map; - struct sg_table *sg_src0; - struct sg_table *sg_src1; - struct sg_table *sg_dst; - struct sg_table *sg_els; - - struct dma_buf_attachment *attach_src0; - struct dma_buf_attachment *attach_src1; - struct dma_buf_attachment *attach_dst; - struct dma_buf_attachment *attach_els; + struct rga_dma_buffer_t dma_buffer_src0; + struct rga_dma_buffer_t dma_buffer_src1; + struct rga_dma_buffer_t dma_buffer_dst; + struct rga_dma_buffer_t dma_buffer_els; }; struct rga2_service_info { diff --git a/drivers/video/rockchip/rga2/rga2_drv.c b/drivers/video/rockchip/rga2/rga2_drv.c index b203587a89fb..15064e7615fb 100644 --- a/drivers/video/rockchip/rga2/rga2_drv.c +++ b/drivers/video/rockchip/rga2/rga2_drv.c @@ -367,71 +367,6 @@ static int rga2_align_check(struct rga2_req *req) return 0; } -static int rga2_memory_check(void *vaddr, u32 w, u32 h, u32 format, int fd) -{ - int bits = 32; - int temp_data = 0; - void *one_line = kzalloc(w * 4, GFP_KERNEL); - - if (!one_line) { - ERR("kzalloc fail %s[%d]\n", __func__, __LINE__); - return 0; - } - switch (format) { - case RGA2_FORMAT_RGBA_8888: - case RGA2_FORMAT_RGBX_8888: - case RGA2_FORMAT_BGRA_8888: - case RGA2_FORMAT_BGRX_8888: - bits = 32; - break; - case RGA2_FORMAT_RGB_888: - case RGA2_FORMAT_BGR_888: - bits = 24; - break; - case RGA2_FORMAT_RGB_565: - case RGA2_FORMAT_RGBA_5551: - case RGA2_FORMAT_RGBA_4444: - case RGA2_FORMAT_BGR_565: - case RGA2_FORMAT_YCbCr_422_SP: - case RGA2_FORMAT_YCbCr_422_P: - case RGA2_FORMAT_YCrCb_422_SP: - case RGA2_FORMAT_YCrCb_422_P: - case RGA2_FORMAT_BGRA_5551: - case RGA2_FORMAT_BGRA_4444: - bits = 16; - break; - case RGA2_FORMAT_YCbCr_420_SP: - case RGA2_FORMAT_YCbCr_420_P: - case RGA2_FORMAT_YCrCb_420_SP: - case RGA2_FORMAT_YCrCb_420_P: - bits = 12; - break; - case RGA2_FORMAT_YCbCr_420_SP_10B: - case RGA2_FORMAT_YCrCb_420_SP_10B: - case RGA2_FORMAT_YCbCr_422_SP_10B: - case RGA2_FORMAT_YCrCb_422_SP_10B: - bits = 15; - break; - default: - INFO("un know format\n"); - kfree(one_line); - return -1; - } - temp_data = w * (h - 1) * bits >> 3; - if (fd > 0) { - INFO("vaddr is%p, bits is %d, fd check\n", vaddr, bits); - memcpy(one_line, (char *)vaddr + temp_data, w * bits >> 3); - INFO("fd check ok\n"); - } else { - INFO("vir addr memory check.\n"); - memcpy((void *)((char *)vaddr + temp_data), one_line, - w * bits >> 3); - INFO("vir addr check ok.\n"); - } - kfree(one_line); - return 0; -} - int rga2_scale_check(struct rga2_req *req) { u32 saw, sah, daw, dah; @@ -486,19 +421,6 @@ static void rga2_printf_cmd_buf(u32 *cmd_buf) dst_aw, dst_ah, dst_stride, dst_format); } -static bool is_yuv422p_format(u32 format) -{ - bool ret = false; - - switch (format) { - case RGA2_FORMAT_YCbCr_422_P: - case RGA2_FORMAT_YCrCb_422_P: - ret = true; - break; - } - return ret; -} - static inline void rga2_write(u32 b, u32 r) { *((volatile unsigned int *)(rga2_drvdata->rga_base + r)) = b; @@ -843,6 +765,14 @@ static struct rga2_reg * rga2_reg_init(rga2_session *session, struct rga2_req *r INIT_LIST_HEAD(®->session_link); INIT_LIST_HEAD(®->status_link); + ret = rga2_get_dma_info(reg, req); + if (ret < 0) { + pr_err("fail to get dma buffer info!\n"); + free_page((unsigned long)reg); + + return NULL; + } + if ((req->mmu_info.src0_mmu_flag & 1) || (req->mmu_info.src1_mmu_flag & 1) || (req->mmu_info.dst_mmu_flag & 1) || (req->mmu_info.els_mmu_flag & 1)) { @@ -861,16 +791,6 @@ static struct rga2_reg * rga2_reg_init(rga2_session *session, struct rga2_req *r return NULL; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) - reg->sg_src0 = req->sg_src0; - reg->sg_dst = req->sg_dst; - reg->sg_src1 = req->sg_src1; - reg->sg_els = req->sg_els; - reg->attach_src0 = req->attach_src0; - reg->attach_dst = req->attach_dst; - reg->attach_src1 = req->attach_src1; - reg->attach_els = req->attach_els; -#endif mutex_lock(&rga2_service.lock); list_add_tail(®->status_link, &rga2_service.waiting); @@ -1009,59 +929,6 @@ static void rga2_try_set_reg(void) } } } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) -static int rga2_put_dma_buf(struct rga2_req *req, struct rga2_reg *reg) -{ - struct dma_buf_attachment *attach = NULL; - struct sg_table *sgt = NULL; - struct dma_buf *dma_buf = NULL; - - if (!req && !reg) - return -EINVAL; - - attach = reg ? reg->attach_src0 : req->attach_src0; - sgt = reg ? reg->sg_src0 : req->sg_src0; - if (attach && sgt) - dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); - if (attach) { - dma_buf = attach->dmabuf; - dma_buf_detach(dma_buf, attach); - dma_buf_put(dma_buf); - } - - attach = reg ? reg->attach_dst : req->attach_dst; - sgt = reg ? reg->sg_dst : req->sg_dst; - if (attach && sgt) - dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); - if (attach) { - dma_buf = attach->dmabuf; - dma_buf_detach(dma_buf, attach); - dma_buf_put(dma_buf); - } - - attach = reg ? reg->attach_src1 : req->attach_src1; - sgt = reg ? reg->sg_src1 : req->sg_src1; - if (attach && sgt) - dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); - if (attach) { - dma_buf = attach->dmabuf; - dma_buf_detach(dma_buf, attach); - dma_buf_put(dma_buf); - } - - attach = reg ? reg->attach_els : req->attach_els; - sgt = reg ? reg->sg_els : req->sg_els; - if (attach && sgt) - dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); - if (attach) { - dma_buf = attach->dmabuf; - dma_buf_detach(dma_buf, attach); - dma_buf_put(dma_buf); - } - - return 0; -} -#endif static void rga2_del_running_list(void) { @@ -1077,9 +944,7 @@ static void rga2_del_running_list(void) else tbuf->back += reg->MMU_len; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) - rga2_put_dma_buf(NULL, reg); -#endif + rga2_put_dma_info(reg); atomic_sub(1, ®->session->task_running); atomic_sub(1, &rga2_service.total_running); @@ -1110,9 +975,7 @@ static void rga2_del_running_list_timeout(void) else tbuf->back += reg->MMU_len; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) - rga2_put_dma_buf(NULL, reg); -#endif + rga2_put_dma_info(reg); atomic_sub(1, ®->session->task_running); atomic_sub(1, &rga2_service.total_running); rga2_soft_reset(); @@ -1124,315 +987,6 @@ static void rga2_del_running_list_timeout(void) } return; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) -static int rga2_get_img_info(rga_img_info_t *img, - u8 mmu_flag, - struct sg_table **psgt, - struct dma_buf_attachment **pattach) -{ - struct dma_buf_attachment *attach = NULL; - struct device *rga_dev = NULL; - struct sg_table *sgt = NULL; - struct dma_buf *dma_buf = NULL; - u32 vir_w, vir_h; - int yrgb_addr = -1; - int ret = 0; - - rga_dev = rga2_drvdata->dev; - yrgb_addr = (int)img->yrgb_addr; - vir_w = img->vir_w; - vir_h = img->vir_h; - - if (yrgb_addr > 0) { - dma_buf = dma_buf_get(img->yrgb_addr); - if (IS_ERR(dma_buf)) { - ret = -EINVAL; - pr_err("dma_buf_get fail fd[%d]\n", yrgb_addr); - return ret; - } - - attach = dma_buf_attach(dma_buf, rga_dev); - if (IS_ERR(attach)) { - dma_buf_put(dma_buf); - ret = -EINVAL; - pr_err("Failed to attach dma_buf\n"); - return ret; - } -#ifdef CONFIG_ROCKCHIP_RGA2_DEBUGGER - if (RGA2_CHECK_MODE) { - void *vaddr = dma_buf_vmap(dma_buf); - if (vaddr) - rga2_memory_check(vaddr, img->vir_w, img->vir_h, - img->format, img->yrgb_addr); - dma_buf_vunmap(dma_buf, vaddr); - } -#endif - - *pattach = attach; - sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); - if (IS_ERR(sgt)) { - ret = -EINVAL; - pr_err("Failed to map src attachment\n"); - goto err_get_sg; - } - if (!mmu_flag) { - ret = -EINVAL; - pr_err("Fix it please enable iommu flag\n"); - goto err_get_sg; - } - - if (mmu_flag) { - *psgt = sgt; - img->yrgb_addr = img->uv_addr; - img->uv_addr = img->yrgb_addr + (vir_w * vir_h); - if (is_yuv422p_format(img->format)) - img->v_addr = img->uv_addr + (vir_w * vir_h) / 2; - else - img->v_addr = img->uv_addr + (vir_w * vir_h) / 4; - } - } else { - img->yrgb_addr = img->uv_addr; - img->uv_addr = img->yrgb_addr + (vir_w * vir_h); - if (is_yuv422p_format(img->format)) - img->v_addr = img->uv_addr + (vir_w * vir_h) / 2; - else - img->v_addr = img->uv_addr + (vir_w * vir_h) / 4; - } - - return ret; - -err_get_sg: - if (!IS_ERR(sgt) && sgt) - dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); - if (!IS_ERR(attach) && attach) { - dma_buf = attach->dmabuf; - dma_buf_detach(dma_buf, attach); - *pattach = NULL; - dma_buf_put(dma_buf); - } - return ret; -} - -static int rga2_get_dma_buf(struct rga2_req *req) -{ - struct dma_buf *dma_buf = NULL; - u8 mmu_flag = 0; - int ret = 0; - - req->sg_src0 = NULL; - req->sg_src1 = NULL; - req->sg_dst = NULL; - req->sg_els = NULL; - req->attach_src0 = NULL; - req->attach_dst = NULL; - req->attach_src1 = NULL; - req->attach_els = NULL; - mmu_flag = req->mmu_info.src0_mmu_flag; - ret = rga2_get_img_info(&req->src, mmu_flag, &req->sg_src0, - &req->attach_src0); - if (ret) { - pr_err("src:rga2_get_img_info fail\n"); - goto err_src; - } - - mmu_flag = req->mmu_info.dst_mmu_flag; - ret = rga2_get_img_info(&req->dst, mmu_flag, &req->sg_dst, - &req->attach_dst); - if (ret) { - pr_err("dst:rga2_get_img_info fail\n"); - goto err_dst; - } - - mmu_flag = req->mmu_info.src1_mmu_flag; - ret = rga2_get_img_info(&req->src1, mmu_flag, &req->sg_src1, - &req->attach_src1); - if (ret) { - pr_err("src1:rga2_get_img_info fail\n"); - goto err_src1; - } - - mmu_flag = req->mmu_info.els_mmu_flag; - ret = rga2_get_img_info(&req->pat, mmu_flag, &req->sg_els, - &req->attach_els); - if (ret) { - pr_err("els:rga2_get_img_info fail\n"); - goto err_els; - } - - return ret; - -err_els: - if (req->sg_src1 && req->attach_src1) { - dma_buf_unmap_attachment(req->attach_src1, - req->sg_src1, DMA_BIDIRECTIONAL); - dma_buf = req->attach_src1->dmabuf; - dma_buf_detach(dma_buf, req->attach_src1); - dma_buf_put(dma_buf); - } -err_src1: - if (req->sg_dst && req->attach_dst) { - dma_buf_unmap_attachment(req->attach_dst, - req->sg_dst, DMA_BIDIRECTIONAL); - dma_buf = req->attach_dst->dmabuf; - dma_buf_detach(dma_buf, req->attach_dst); - dma_buf_put(dma_buf); - } -err_dst: - if (req->sg_src0 && req->attach_src0) { - dma_buf_unmap_attachment(req->attach_src0, - req->sg_src0, DMA_BIDIRECTIONAL); - dma_buf = req->attach_src0->dmabuf; - dma_buf_detach(dma_buf, req->attach_src0); - dma_buf_put(dma_buf); - } -err_src: - - return ret; -} -#else -static int rga2_convert_dma_buf(struct rga2_req *req) -{ - struct ion_handle *hdl; - ion_phys_addr_t phy_addr; - size_t len; - int ret; - u32 src_vir_w, dst_vir_w; - void *vaddr = NULL; - - src_vir_w = req->src.vir_w; - dst_vir_w = req->dst.vir_w; - - req->sg_src0 = NULL; - req->sg_src1 = NULL; - req->sg_dst = NULL; - req->sg_els = NULL; - - if ((int)req->src.yrgb_addr > 0) { - hdl = ion_import_dma_buf(rga2_drvdata->ion_client, - req->src.yrgb_addr); - if (IS_ERR(hdl)) { - ret = PTR_ERR(hdl); - pr_err("RGA2 SRC ERROR ion buf handle\n"); - return ret; - } -#ifdef CONFIG_ROCKCHIP_RGA2_DEBUGGER - if (RGA2_CHECK_MODE) { - vaddr = ion_map_kernel(rga2_drvdata->ion_client, hdl); - if (vaddr) - rga2_memory_check(vaddr, req->src.vir_w, req->src.vir_h, - req->src.format, req->src.yrgb_addr); - ion_unmap_kernel(rga2_drvdata->ion_client, hdl); - } -#endif - if (req->mmu_info.src0_mmu_flag) { - req->sg_src0 = - ion_sg_table(rga2_drvdata->ion_client, hdl); - req->src.yrgb_addr = req->src.uv_addr; - req->src.uv_addr = - req->src.yrgb_addr + (src_vir_w * req->src.vir_h); - req->src.v_addr = - req->src.uv_addr + (src_vir_w * req->src.vir_h) / 4; - } else { - ion_phys(rga2_drvdata->ion_client, hdl, &phy_addr, &len); - req->src.yrgb_addr = phy_addr; - req->src.uv_addr = - req->src.yrgb_addr + (src_vir_w * req->src.vir_h); - req->src.v_addr = - req->src.uv_addr + (src_vir_w * req->src.vir_h) / 4; - } - ion_free(rga2_drvdata->ion_client, hdl); - } else { - req->src.yrgb_addr = req->src.uv_addr; - req->src.uv_addr = - req->src.yrgb_addr + (src_vir_w * req->src.vir_h); - req->src.v_addr = - req->src.uv_addr + (src_vir_w * req->src.vir_h) / 4; - } - - if ((int)req->dst.yrgb_addr > 0) { - hdl = ion_import_dma_buf(rga2_drvdata->ion_client, - req->dst.yrgb_addr); - if (IS_ERR(hdl)) { - ret = PTR_ERR(hdl); - pr_err("RGA2 DST ERROR ion buf handle\n"); - return ret; - } -#ifdef CONFIG_ROCKCHIP_RGA2_DEBUGGER - if (RGA2_CHECK_MODE) { - vaddr = ion_map_kernel(rga2_drvdata->ion_client, hdl); - if (vaddr) - rga2_memory_check(vaddr, req->dst.vir_w, req->dst.vir_h, - req->dst.format, req->dst.yrgb_addr); - ion_unmap_kernel(rga2_drvdata->ion_client, hdl); - } -#endif - if (req->mmu_info.dst_mmu_flag) { - req->sg_dst = - ion_sg_table(rga2_drvdata->ion_client, hdl); - req->dst.yrgb_addr = req->dst.uv_addr; - req->dst.uv_addr = - req->dst.yrgb_addr + (dst_vir_w * req->dst.vir_h); - req->dst.v_addr = - req->dst.uv_addr + (dst_vir_w * req->dst.vir_h) / 4; - } else { - ion_phys(rga2_drvdata->ion_client, hdl, &phy_addr, &len); - req->dst.yrgb_addr = phy_addr; - req->dst.uv_addr = - req->dst.yrgb_addr + (dst_vir_w * req->dst.vir_h); - req->dst.v_addr = - req->dst.uv_addr + (dst_vir_w * req->dst.vir_h) / 4; - } - ion_free(rga2_drvdata->ion_client, hdl); - } else { - req->dst.yrgb_addr = req->dst.uv_addr; - req->dst.uv_addr = - req->dst.yrgb_addr + (dst_vir_w * req->dst.vir_h); - req->dst.v_addr = - req->dst.uv_addr + (dst_vir_w * req->dst.vir_h) / 4; - } - - if ((int)req->src1.yrgb_addr > 0) { - hdl = ion_import_dma_buf(rga2_drvdata->ion_client, - req->src1.yrgb_addr); - if (IS_ERR(hdl)) { - ret = PTR_ERR(hdl); - pr_err("RGA2 ERROR ion buf handle\n"); - return ret; - } - if (req->mmu_info.dst_mmu_flag) { - req->sg_src1 = - ion_sg_table(rga2_drvdata->ion_client, hdl); - req->src1.yrgb_addr = req->src1.uv_addr; - req->src1.uv_addr = - req->src1.yrgb_addr + (req->src1.vir_w * req->src1.vir_h); - req->src1.v_addr = - req->src1.uv_addr + (req->src1.vir_w * req->src1.vir_h) / 4; - } else { - ion_phys(rga2_drvdata->ion_client, hdl, &phy_addr, &len); - req->src1.yrgb_addr = phy_addr; - req->src1.uv_addr = - req->src1.yrgb_addr + (req->src1.vir_w * req->src1.vir_h); - req->src1.v_addr = - req->src1.uv_addr + (req->src1.vir_w * req->src1.vir_h) / 4; - } - ion_free(rga2_drvdata->ion_client, hdl); - } else { - req->src1.yrgb_addr = req->src1.uv_addr; - req->src1.uv_addr = - req->src1.yrgb_addr + (req->src1.vir_w * req->src1.vir_h); - req->src1.v_addr = - req->src1.uv_addr + (req->src1.vir_w * req->src1.vir_h) / 4; - } - if (is_yuv422p_format(req->src.format)) - req->src.v_addr = req->src.uv_addr + (req->src.vir_w * req->src.vir_h) / 2; - if (is_yuv422p_format(req->dst.format)) - req->dst.v_addr = req->dst.uv_addr + (req->dst.vir_w * req->dst.vir_h) / 2; - if (is_yuv422p_format(req->src1.format)) - req->src1.v_addr = req->src1.uv_addr + (req->src1.vir_w * req->dst.vir_h) / 2; - - return 0; -} -#endif static int rga2_blit_flush_cache(rga2_session *session, struct rga2_req *req) { @@ -1446,19 +1000,13 @@ static int rga2_blit_flush_cache(rga2_session *session, struct rga2_req *req) ret = -ENOMEM; goto err_free_reg; } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) - if (rga2_get_dma_buf(req)) { - pr_err("RGA2 : DMA buf copy error\n"); - ret = -EFAULT; + + ret = rga2_get_dma_info(reg, req); + if (ret < 0) { + pr_err("fail to get dma buffer info!\n"); goto err_free_reg; } -#else - if (rga2_convert_dma_buf(req)) { - pr_err("RGA2 : DMA buf copy error\n"); - ret = -EFAULT; - goto err_free_reg; - } -#endif + if ((req->mmu_info.src0_mmu_flag & 1) || (req->mmu_info.src1_mmu_flag & 1) || (req->mmu_info.dst_mmu_flag & 1) || (req->mmu_info.els_mmu_flag & 1)) { reg->MMU_map = true; @@ -1487,54 +1035,26 @@ static int rga2_blit(rga2_session *session, struct rga2_req *req) int num = 0; struct rga2_reg *reg; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) - if (rga2_get_dma_buf(req)) { - pr_err("RGA2 : DMA buf copy error\n"); + /* check value if legal */ + ret = rga2_check_param(req); + if (ret == -EINVAL) { + pr_err("req argument is inval\n"); + return ret; + } + + reg = rga2_reg_init(session, req); + if (reg == NULL) { + pr_err("init reg fail\n"); return -EFAULT; } -#else - if (rga2_convert_dma_buf(req)) { - pr_err("RGA2 : DMA buf copy error\n"); - return -EFAULT; - } -#endif - do { - /* check value if legal */ - ret = rga2_check_param(req); - if(ret == -EINVAL) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) - pr_err("req argument is inval\n"); - goto err_put_dma_buf; -#else - pr_err("req argument is inval\n"); - break; -#endif - } - reg = rga2_reg_init(session, req); - if(reg == NULL) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) - pr_err("init reg fail\n"); - goto err_put_dma_buf; -#else - break; -#endif - } + num = 1; + mutex_lock(&rga2_service.lock); + atomic_add(num, &rga2_service.total_running); + rga2_try_set_reg(); + mutex_unlock(&rga2_service.lock); - num = 1; - mutex_lock(&rga2_service.lock); - atomic_add(num, &rga2_service.total_running); - rga2_try_set_reg(); - mutex_unlock(&rga2_service.lock); - - return 0; - } - while(0); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) -err_put_dma_buf: - rga2_put_dma_buf(req, NULL); -#endif - return -EFAULT; + return 0; } static int rga2_blit_async(rga2_session *session, struct rga2_req *req) diff --git a/drivers/video/rockchip/rga2/rga2_mmu_info.c b/drivers/video/rockchip/rga2/rga2_mmu_info.c index 51d20a77848e..6f38719f7242 100644 --- a/drivers/video/rockchip/rga2/rga2_mmu_info.c +++ b/drivers/video/rockchip/rga2/rga2_mmu_info.c @@ -19,11 +19,15 @@ #include #include #include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0)) +#include +#endif #include "rga2_mmu_info.h" #include "rga2_debugger.h" extern struct rga2_service_info rga2_service; extern struct rga2_mmu_buf_t rga2_mmu_buf; +extern struct rga2_drvdata_t *rga2_drvdata; //extern int mmu_buff_temp[1024]; @@ -118,6 +122,431 @@ static unsigned int armv7_va_to_pa(unsigned int v_addr) } #endif +static bool rga2_is_yuv422p_format(u32 format) +{ + bool ret = false; + + switch (format) { + case RGA2_FORMAT_YCbCr_422_P: + case RGA2_FORMAT_YCrCb_422_P: + ret = true; + break; + } + return ret; +} + +#ifdef CONFIG_ROCKCHIP_RGA2_DEBUGGER +static int rga2_memory_check(void *vaddr, u32 w, u32 h, u32 format, int fd) +{ + int bits = 32; + int temp_data = 0; + void *one_line = kzalloc(w * 4, GFP_KERNEL); + + if (!one_line) { + ERR("kzalloc fail %s[%d]\n", __func__, __LINE__); + return 0; + } + switch (format) { + case RGA2_FORMAT_RGBA_8888: + case RGA2_FORMAT_RGBX_8888: + case RGA2_FORMAT_BGRA_8888: + case RGA2_FORMAT_BGRX_8888: + bits = 32; + break; + case RGA2_FORMAT_RGB_888: + case RGA2_FORMAT_BGR_888: + bits = 24; + break; + case RGA2_FORMAT_RGB_565: + case RGA2_FORMAT_RGBA_5551: + case RGA2_FORMAT_RGBA_4444: + case RGA2_FORMAT_BGR_565: + case RGA2_FORMAT_YCbCr_422_SP: + case RGA2_FORMAT_YCbCr_422_P: + case RGA2_FORMAT_YCrCb_422_SP: + case RGA2_FORMAT_YCrCb_422_P: + case RGA2_FORMAT_BGRA_5551: + case RGA2_FORMAT_BGRA_4444: + bits = 16; + break; + case RGA2_FORMAT_YCbCr_420_SP: + case RGA2_FORMAT_YCbCr_420_P: + case RGA2_FORMAT_YCrCb_420_SP: + case RGA2_FORMAT_YCrCb_420_P: + bits = 12; + break; + case RGA2_FORMAT_YCbCr_420_SP_10B: + case RGA2_FORMAT_YCrCb_420_SP_10B: + case RGA2_FORMAT_YCbCr_422_SP_10B: + case RGA2_FORMAT_YCrCb_422_SP_10B: + bits = 15; + break; + default: + INFO("un know format\n"); + kfree(one_line); + return -1; + } + temp_data = w * (h - 1) * bits >> 3; + if (fd > 0) { + INFO("vaddr is%p, bits is %d, fd check\n", vaddr, bits); + memcpy(one_line, (char *)vaddr + temp_data, w * bits >> 3); + INFO("fd check ok\n"); + } else { + INFO("vir addr memory check.\n"); + memcpy((void *)((char *)vaddr + temp_data), one_line, + w * bits >> 3); + INFO("vir addr check ok.\n"); + } + kfree(one_line); + return 0; +} +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) +static int rga2_map_dma_buffer(struct rga_img_info_t *img, + struct rga_dma_buffer_t *rga_dma_buffer, + enum dma_data_direction dir) +{ + struct device *rga_dev = NULL; + struct dma_buf *dma_buf = NULL; + struct dma_buf_attachment *attach = NULL; + struct sg_table *sgt = NULL; + u32 vir_w, vir_h; + int fd = -1; + int ret = 0; + + rga_dev = rga2_drvdata->dev; + fd = (int)img->yrgb_addr; + vir_w = img->vir_w; + vir_h = img->vir_h; + + dma_buf = dma_buf_get(fd); + if (IS_ERR(dma_buf)) { + ret = -EINVAL; + pr_err("dma_buf_get fail fd[%d]\n", fd); + return ret; + } + + attach = dma_buf_attach(dma_buf, rga_dev); + if (IS_ERR(attach)) { + ret = -EINVAL; + pr_err("Failed to attach dma_buf\n"); + goto err_get_attach; + } + +#ifdef CONFIG_ROCKCHIP_RGA2_DEBUGGER + if (RGA2_CHECK_MODE) { + void *vaddr = dma_buf_vmap(dma_buf); + + if (vaddr) + rga2_memory_check(vaddr, img->vir_w, img->vir_h, + img->format, img->yrgb_addr); + dma_buf_vunmap(dma_buf, vaddr); + } +#endif + + sgt = dma_buf_map_attachment(attach, dir); + if (IS_ERR(sgt)) { + ret = -EINVAL; + pr_err("Failed to map src attachment\n"); + goto err_get_sgt; + } + + rga_dma_buffer->dma_buf = dma_buf; + rga_dma_buffer->attach = attach; + rga_dma_buffer->sgt = sgt; + rga_dma_buffer->size = sg_dma_len(sgt->sgl); + rga_dma_buffer->dir = dir; + + return ret; + +err_get_sgt: + if (attach) + dma_buf_detach(dma_buf, attach); +err_get_attach: + if (dma_buf) + dma_buf_put(dma_buf); + + return ret; +} + +static void rga2_unmap_dma_buffer(struct rga_dma_buffer_t *rga_dma_buffer) +{ + if (rga_dma_buffer->attach && rga_dma_buffer->sgt) + dma_buf_unmap_attachment(rga_dma_buffer->attach, + rga_dma_buffer->sgt, + rga_dma_buffer->dir); + if (rga_dma_buffer->attach) { + dma_buf_detach(rga_dma_buffer->dma_buf, rga_dma_buffer->attach); + dma_buf_put(rga_dma_buffer->dma_buf); + } +} + +static void rga2_convert_addr(struct rga_img_info_t *img) +{ + /* + * If it is not using dma fd, the virtual/phyical address is assigned + * to the address of the corresponding channel. + */ + img->yrgb_addr = img->uv_addr; + img->uv_addr = img->yrgb_addr + (img->vir_w * img->vir_h); + if (rga2_is_yuv422p_format(img->format)) + img->v_addr = img->uv_addr + (img->vir_w * img->vir_h) / 2; + else + img->v_addr = img->uv_addr + (img->vir_w * img->vir_h) / 4; +} + +int rga2_get_dma_info(struct rga2_reg *reg, struct rga2_req *req) +{ + uint32_t mmu_flag; + int ret; + + struct rga_dma_buffer_t *buffer_src0, *buffer_src1, *buffer_dst, *buffer_els; + struct rga_img_info_t *src0, *src1, *dst, *els; + + /* + * Since the life cycle of rga2_req cannot satisfy the release of + * dmabuffer after the task is over, the mapped dmabuffer is saved + * in rga2_reg. + */ + buffer_src0 = ®->dma_buffer_src0; + buffer_src1 = ®->dma_buffer_src1; + buffer_dst = ®->dma_buffer_dst; + buffer_els = ®->dma_buffer_els; + + src0 = &req->src; + src1 = &req->src1; + dst = &req->dst; + els = &req->pat; + + /* src0 chanel */ + mmu_flag = req->mmu_info.src0_mmu_flag; + if (unlikely(!mmu_flag && src0->yrgb_addr)) { + pr_err("Fix it please enable src0 mmu\n"); + return -EINVAL; + } else if (mmu_flag && src0->yrgb_addr) { + ret = rga2_map_dma_buffer(src0, buffer_src0, DMA_BIDIRECTIONAL); + if (ret < 0) { + pr_err("src0: can't map dma-buf\n"); + return ret; + } + } + rga2_convert_addr(src0); + + /* src1 chanel */ + mmu_flag = req->mmu_info.src1_mmu_flag; + if (unlikely(!mmu_flag && src1->yrgb_addr)) { + pr_err("Fix it please enable src1 mmu\n"); + ret = -EINVAL; + goto err_src1_channel; + } else if (mmu_flag && src1->yrgb_addr) { + ret = rga2_map_dma_buffer(src1, buffer_src1, DMA_BIDIRECTIONAL); + if (ret < 0) { + pr_err("src1: can't map dma-buf\n"); + goto err_src1_channel; + } + } + rga2_convert_addr(src1); + + /* dst chanel */ + mmu_flag = req->mmu_info.dst_mmu_flag; + if (unlikely(!mmu_flag && dst->yrgb_addr)) { + pr_err("Fix it please enable dst mmu\n"); + ret = -EINVAL; + goto err_dst_channel; + } else if (mmu_flag && dst->yrgb_addr) { + ret = rga2_map_dma_buffer(dst, buffer_dst, DMA_BIDIRECTIONAL); + if (ret < 0) { + pr_err("dst: can't map dma-buf\n"); + goto err_dst_channel; + } + } + rga2_convert_addr(dst); + + /* els chanel */ + mmu_flag = req->mmu_info.els_mmu_flag; + if (unlikely(!mmu_flag && els->yrgb_addr)) { + pr_err("Fix it please enable els mmu\n"); + ret = -EINVAL; + goto err_els_channel; + } else if (mmu_flag && els->yrgb_addr) { + ret = rga2_map_dma_buffer(els, buffer_els, DMA_BIDIRECTIONAL); + if (ret < 0) { + pr_err("els: can't map dma-buf\n"); + goto err_els_channel; + } + } + rga2_convert_addr(els); + + return 0; + +err_els_channel: + rga2_unmap_dma_buffer(buffer_dst); +err_dst_channel: + rga2_unmap_dma_buffer(buffer_src1); +err_src1_channel: + rga2_unmap_dma_buffer(buffer_src0); + + return ret; +} + +void rga2_put_dma_info(struct rga2_reg *reg) +{ + rga2_unmap_dma_buffer(®->dma_buffer_src0); + rga2_unmap_dma_buffer(®->dma_buffer_src1); + rga2_unmap_dma_buffer(®->dma_buffer_dst); + rga2_unmap_dma_buffer(®->dma_buffer_els); +} + +#else +static int rga2_get_dma_info(struct rga2_reg *reg, struct rga2_req *req) +{ + struct ion_handle *hdl; + ion_phys_addr_t phy_addr; + size_t len; + int ret; + u32 src_vir_w, dst_vir_w; + void *vaddr = NULL; + struct rga_dma_buffer_t *buffer_src0, *buffer_src1, *buffer_dst, *buffer_els; + + src_vir_w = req->src.vir_w; + dst_vir_w = req->dst.vir_w; + + buffer_src0 = ®->dma_buffer_src0; + buffer_src1 = ®->dma_buffer_src1; + buffer_dst = ®->dma_buffer_dst; + buffer_els = ®->dma_buffer_els; + + if ((int)req->src.yrgb_addr > 0) { + hdl = ion_import_dma_buf(rga2_drvdata->ion_client, + req->src.yrgb_addr); + if (IS_ERR(hdl)) { + ret = PTR_ERR(hdl); + pr_err("RGA2 SRC ERROR ion buf handle\n"); + return ret; + } +#ifdef CONFIG_ROCKCHIP_RGA2_DEBUGGER + if (RGA2_CHECK_MODE) { + vaddr = ion_map_kernel(rga2_drvdata->ion_client, hdl); + if (vaddr) + rga2_memory_check(vaddr, req->src.vir_w, req->src.vir_h, + req->src.format, req->src.yrgb_addr); + ion_unmap_kernel(rga2_drvdata->ion_client, hdl); + } +#endif + if (req->mmu_info.src0_mmu_flag) { + buffer_src0.sgt = + ion_sg_table(rga2_drvdata->ion_client, hdl); + req->src.yrgb_addr = req->src.uv_addr; + req->src.uv_addr = + req->src.yrgb_addr + (src_vir_w * req->src.vir_h); + req->src.v_addr = + req->src.uv_addr + (src_vir_w * req->src.vir_h) / 4; + } else { + ion_phys(rga2_drvdata->ion_client, hdl, &phy_addr, &len); + req->src.yrgb_addr = phy_addr; + req->src.uv_addr = + req->src.yrgb_addr + (src_vir_w * req->src.vir_h); + req->src.v_addr = + req->src.uv_addr + (src_vir_w * req->src.vir_h) / 4; + } + ion_free(rga2_drvdata->ion_client, hdl); + } else { + req->src.yrgb_addr = req->src.uv_addr; + req->src.uv_addr = + req->src.yrgb_addr + (src_vir_w * req->src.vir_h); + req->src.v_addr = + req->src.uv_addr + (src_vir_w * req->src.vir_h) / 4; + } + + if ((int)req->dst.yrgb_addr > 0) { + hdl = ion_import_dma_buf(rga2_drvdata->ion_client, + req->dst.yrgb_addr); + if (IS_ERR(hdl)) { + ret = PTR_ERR(hdl); + pr_err("RGA2 DST ERROR ion buf handle\n"); + return ret; + } +#ifdef CONFIG_ROCKCHIP_RGA2_DEBUGGER + if (RGA2_CHECK_MODE) { + vaddr = ion_map_kernel(rga2_drvdata->ion_client, hdl); + if (vaddr) + rga2_memory_check(vaddr, req->dst.vir_w, req->dst.vir_h, + req->dst.format, req->dst.yrgb_addr); + ion_unmap_kernel(rga2_drvdata->ion_client, hdl); + } +#endif + if (req->mmu_info.dst_mmu_flag) { + buffer_dst.sgt = + ion_sg_table(rga2_drvdata->ion_client, hdl); + req->dst.yrgb_addr = req->dst.uv_addr; + req->dst.uv_addr = + req->dst.yrgb_addr + (dst_vir_w * req->dst.vir_h); + req->dst.v_addr = + req->dst.uv_addr + (dst_vir_w * req->dst.vir_h) / 4; + } else { + ion_phys(rga2_drvdata->ion_client, hdl, &phy_addr, &len); + req->dst.yrgb_addr = phy_addr; + req->dst.uv_addr = + req->dst.yrgb_addr + (dst_vir_w * req->dst.vir_h); + req->dst.v_addr = + req->dst.uv_addr + (dst_vir_w * req->dst.vir_h) / 4; + } + ion_free(rga2_drvdata->ion_client, hdl); + } else { + req->dst.yrgb_addr = req->dst.uv_addr; + req->dst.uv_addr = + req->dst.yrgb_addr + (dst_vir_w * req->dst.vir_h); + req->dst.v_addr = + req->dst.uv_addr + (dst_vir_w * req->dst.vir_h) / 4; + } + + if ((int)req->src1.yrgb_addr > 0) { + hdl = ion_import_dma_buf(rga2_drvdata->ion_client, + req->src1.yrgb_addr); + if (IS_ERR(hdl)) { + ret = PTR_ERR(hdl); + pr_err("RGA2 ERROR ion buf handle\n"); + return ret; + } + if (req->mmu_info.dst_mmu_flag) { + buffer_src1.sgt = + ion_sg_table(rga2_drvdata->ion_client, hdl); + req->src1.yrgb_addr = req->src1.uv_addr; + req->src1.uv_addr = + req->src1.yrgb_addr + (req->src1.vir_w * req->src1.vir_h); + req->src1.v_addr = + req->src1.uv_addr + (req->src1.vir_w * req->src1.vir_h) / 4; + } else { + ion_phys(rga2_drvdata->ion_client, hdl, &phy_addr, &len); + req->src1.yrgb_addr = phy_addr; + req->src1.uv_addr = + req->src1.yrgb_addr + (req->src1.vir_w * req->src1.vir_h); + req->src1.v_addr = + req->src1.uv_addr + (req->src1.vir_w * req->src1.vir_h) / 4; + } + ion_free(rga2_drvdata->ion_client, hdl); + } else { + req->src1.yrgb_addr = req->src1.uv_addr; + req->src1.uv_addr = + req->src1.yrgb_addr + (req->src1.vir_w * req->src1.vir_h); + req->src1.v_addr = + req->src1.uv_addr + (req->src1.vir_w * req->src1.vir_h) / 4; + } + if (rga2_is_yuv422p_format(req->src.format)) + req->src.v_addr = req->src.uv_addr + (req->src.vir_w * req->src.vir_h) / 2; + if (rga2_is_yuv422p_format(req->dst.format)) + req->dst.v_addr = req->dst.uv_addr + (req->dst.vir_w * req->dst.vir_h) / 2; + if (rga2_is_yuv422p_format(req->src1.format)) + req->src1.v_addr = req->src1.uv_addr + (req->src1.vir_w * req->dst.vir_h) / 2; + + return 0; +} + +/* When the kernel version is lower than 4.4, no put buffer operation is required. */ +void rga2_put_dma_info(struct rga2_reg *reg) {} +#endif + static int rga2_mmu_buf_get(struct rga2_mmu_buf_t *t, uint32_t size) { mutex_lock(&rga2_service.lock); @@ -597,6 +1026,7 @@ static int rga2_mmu_flush_cache(struct rga2_reg *reg, struct rga2_req *req) int ret; int status; struct page **pages = NULL; + struct rga_dma_buffer_t *dma_buffer = NULL; MMU_Base = NULL; DstMemSize = 0; @@ -637,7 +1067,8 @@ static int rga2_mmu_flush_cache(struct rga2_reg *reg, struct rga2_req *req) mutex_unlock(&rga2_service.lock); if (DstMemSize) { - if (req->sg_dst) { + dma_buffer = ®->dma_buffer_dst; + if (dma_buffer->sgt) { status = -EINVAL; goto out; } else { @@ -678,6 +1109,8 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_reg *reg, struct rga2_req *req) int status; uint32_t uv_size, v_size; struct page **pages = NULL; + struct rga_dma_buffer_t *dma_buffer = NULL; + MMU_Base = NULL; Src0MemSize = 0; Src1MemSize = 0; @@ -749,8 +1182,10 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_reg *reg, struct rga2_req *req) mutex_unlock(&rga2_service.lock); if (Src0MemSize) { - if (req->sg_src0) { - ret = rga2_MapION(req->sg_src0, + dma_buffer = ®->dma_buffer_src0; + + if (dma_buffer->sgt) { + ret = rga2_MapION(dma_buffer->sgt, &MMU_Base[0], Src0MemSize); } else { ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0], @@ -788,9 +1223,12 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_reg *reg, struct rga2_req *req) req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (v_size << PAGE_SHIFT); } + if (Src1MemSize) { - if (req->sg_src1) { - ret = rga2_MapION(req->sg_src1, + dma_buffer = ®->dma_buffer_src1; + + if (dma_buffer->sgt) { + ret = rga2_MapION(dma_buffer->sgt, MMU_Base + Src0MemSize, Src1MemSize); } else { ret = rga2_MapUserMemory(&pages[0], @@ -813,8 +1251,10 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_reg *reg, struct rga2_req *req) req->src1.yrgb_addr = (req->src1.yrgb_addr & (~PAGE_MASK)); } if (DstMemSize) { - if (req->sg_dst) { - ret = rga2_MapION(req->sg_dst, MMU_Base + Src0MemSize + dma_buffer = ®->dma_buffer_dst; + + if (dma_buffer->sgt) { + ret = rga2_MapION(dma_buffer->sgt, MMU_Base + Src0MemSize + Src1MemSize, DstMemSize); } else if (req->alpha_mode_0 != 0 && req->bitblt_mode == 0) { /* The blend mode of src + dst => dst requires clean and invalidate */ @@ -900,6 +1340,7 @@ static int rga2_mmu_info_color_palette_mode(struct rga2_reg *reg, struct rga2_re uint8_t shift; uint32_t sw, byte_num; + struct rga_dma_buffer_t *dma_buffer = NULL; shift = 3 - (req->palette_mode & 3); sw = req->src.vir_w*req->src.vir_h; @@ -961,8 +1402,10 @@ static int rga2_mmu_info_color_palette_mode(struct rga2_reg *reg, struct rga2_re mutex_unlock(&rga2_service.lock); if(SrcMemSize) { - if (req->sg_src0) { - ret = rga2_MapION(req->sg_src0, + dma_buffer = ®->dma_buffer_src0; + + if (dma_buffer->sgt) { + ret = rga2_MapION(dma_buffer->sgt, &MMU_Base[0], SrcMemSize); } else { ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0], @@ -990,8 +1433,10 @@ static int rga2_mmu_info_color_palette_mode(struct rga2_reg *reg, struct rga2_re } if(DstMemSize) { - if (req->sg_dst) { - ret = rga2_MapION(req->sg_dst, + dma_buffer = ®->dma_buffer_dst; + + if (dma_buffer->sgt) { + ret = rga2_MapION(dma_buffer->sgt, MMU_Base + SrcMemSize, DstMemSize); } else { ret = rga2_MapUserMemory(&pages[0], MMU_Base + SrcMemSize, @@ -1045,6 +1490,7 @@ static int rga2_mmu_info_color_fill_mode(struct rga2_reg *reg, struct rga2_req * uint32_t *MMU_Base, *MMU_Base_phys; int ret; int status; + struct rga_dma_buffer_t *dma_buffer = NULL; DstMemSize = 0; DstPageCount = 0; @@ -1082,8 +1528,10 @@ static int rga2_mmu_info_color_fill_mode(struct rga2_reg *reg, struct rga2_req * mutex_unlock(&rga2_service.lock); if (DstMemSize) { - if (req->sg_dst) { - ret = rga2_MapION(req->sg_dst, &MMU_Base[0], DstMemSize); + dma_buffer = ®->dma_buffer_dst; + + if (dma_buffer->sgt) { + ret = rga2_MapION(dma_buffer->sgt, &MMU_Base[0], DstMemSize); } else { ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0], @@ -1133,6 +1581,7 @@ static int rga2_mmu_info_update_palette_table_mode(struct rga2_reg *reg, struct uint32_t AllSize; uint32_t *MMU_Base, *MMU_Base_phys; int ret, status; + struct rga_dma_buffer_t *dma_buffer = NULL; MMU_Base = NULL; LutPageCount = 0; @@ -1175,8 +1624,10 @@ static int rga2_mmu_info_update_palette_table_mode(struct rga2_reg *reg, struct mutex_unlock(&rga2_service.lock); if (LutMemSize) { - if (req->sg_els) { - ret = rga2_MapION(req->sg_els, + dma_buffer = ®->dma_buffer_els; + + if (dma_buffer->sgt) { + ret = rga2_MapION(dma_buffer->sgt, &MMU_Base[0], LutMemSize); } else { ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0], diff --git a/drivers/video/rockchip/rga2/rga2_mmu_info.h b/drivers/video/rockchip/rga2/rga2_mmu_info.h index 6809a4f40230..a823f2fe7c3a 100644 --- a/drivers/video/rockchip/rga2/rga2_mmu_info.h +++ b/drivers/video/rockchip/rga2/rga2_mmu_info.h @@ -28,5 +28,8 @@ int rga2_set_mmu_info(struct rga2_reg *reg, struct rga2_req *req); void rga2_dma_flush_range(void *pstart, void *pend); dma_addr_t rga2_dma_flush_page(struct page *page, int map); +int rga2_get_dma_info(struct rga2_reg *reg, struct rga2_req *req); +void rga2_put_dma_info(struct rga2_reg *reg); + #endif