diff --git a/drivers/video/rockchip/rga/rga_drv.c b/drivers/video/rockchip/rga/rga_drv.c old mode 100755 new mode 100644 index 31a8da79984a..12c3845b8d89 --- a/drivers/video/rockchip/rga/rga_drv.c +++ b/drivers/video/rockchip/rga/rga_drv.c @@ -932,11 +932,84 @@ err_src: return ret; } +static struct rga_reg *rga_reg_init_2(rga_session *session, struct rga_req *req0, + struct rga_req *req1) +{ + int32_t ret; + struct rga_reg *reg0, *reg1; + + reg0 = NULL; + reg1 = NULL; + + do { + reg0 = kzalloc(sizeof(*reg0), GFP_KERNEL); + if (!reg0) { + pr_err("%s [%d] kmalloc fail in rga_reg_init\n", + __func__, __LINE__); + break; + } + + reg1 = kzalloc(sizeof(*reg1), GFP_KERNEL); + if (!reg1) { + pr_err("%s [%d] kmalloc fail in rga_reg_init\n", + __func__, __LINE__); + break; + } + + reg0->session = session; + INIT_LIST_HEAD(®0->session_link); + INIT_LIST_HEAD(®0->status_link); + + reg1->session = session; + INIT_LIST_HEAD(®1->session_link); + INIT_LIST_HEAD(®1->status_link); + + req0->mmu_info.mmu_flag &= (~(1 << 10)); + if (req0->mmu_info.mmu_en) { + ret = rga_set_mmu_info(reg0, req0); + if (ret < 0) { + pr_err("%s, [%d] set mmu info error\n", + __func__, __LINE__); + break; + } + } + + RGA_gen_reg_info(req0, (uint8_t *)reg0->cmd_reg); + req1->mmu_info.mmu_flag &= (~(1 << 8)); + if (req1->mmu_info.mmu_en) { + ret = rga_set_mmu_info(reg1, req1); + if (ret < 0) { + pr_err("%s, [%d] set mmu info error\n", + __func__, __LINE__); + break; + } + } + + RGA_gen_reg_info(req1, (uint8_t *)reg1->cmd_reg); + mutex_lock(&rga_service.lock); + list_add_tail(®0->status_link, &rga_service.waiting); + list_add_tail(®0->session_link, &session->waiting); + list_add_tail(®1->status_link, &rga_service.waiting); + list_add_tail(®1->session_link, &session->waiting); + mutex_unlock(&rga_service.lock); + + return reg1; + + } while (0); + + if (reg0) + kfree(reg0); + if (reg1) + kfree(reg1); + return NULL; +} + static int rga_blit(rga_session *session, struct rga_req *req) { - int ret = -1; - int num = 0; - struct rga_reg *reg; + int ret = -1; + int num = 0; + struct rga_reg *reg; + struct rga_req req2; uint32_t saw, sah, daw, dah; @@ -945,54 +1018,86 @@ static int rga_blit(rga_session *session, struct rga_req *req) daw = req->dst.act_w; dah = req->dst.act_h; - #if RGA_TEST - print_info(req); - #endif +#if RGA_TEST + print_info(req); +#endif if (rga_get_dma_buf(req)) { - printk("RGA : DMA buf copy error\n"); - return -EFAULT; - } - req->render_mode &= (~RGA_BUF_GEM_TYPE_MASK); - do { - if (((saw >> 1) >= daw) || ((sah >> 1) >= dah)) { - pr_err("unsupported to scaling less than 1/2 \n"); - goto err_put_dma_buf; - } - - if (((daw >> 3) >= saw) || ((dah >> 3) >= sah)) { - pr_err("unsupported to scaling more than 8 \n"); - goto err_put_dma_buf; - } - - - /* check value if legal */ - ret = rga_check_param(req); - if(ret == -EINVAL) { - printk("req argument is inval\n"); - goto err_put_dma_buf; - } - - reg = rga_reg_init(session, req); - if(reg == NULL) { - pr_err("init reg fail\n"); - goto err_put_dma_buf; - } - - num = 1; - - mutex_lock(&rga_service.lock); - atomic_add(num, &rga_service.total_running); - rga_try_set_reg(); - mutex_unlock(&rga_service.lock); - - return 0; + pr_err("RGA : DMA buf copy error\n"); + return -EFAULT; } - while(0); + req->render_mode &= (~RGA_BUF_GEM_TYPE_MASK); + do { + if ((req->render_mode == bitblt_mode) && (((saw >> 1) >= daw) || ((sah >> 1) >= dah))) { + /* generate 2 cmd for pre scale */ + if (((saw >> 3) > daw) || ((sah >> 3) > dah)) { + pr_err("unsupported to scaling less than 1/8\n"); + goto err_put_dma_buf; + } + if (((daw >> 3) > saw) || ((dah >> 3) > daw)) { + pr_err("unsupported to scaling more than 8\n"); + goto err_put_dma_buf; + } + ret = rga_check_param(req); + if (ret == -EINVAL) { + pr_err("req 0 argument is inval\n"); + goto err_put_dma_buf; + } + + ret = RGA_gen_two_pro(req, &req2); + if (ret == -EINVAL) { + pr_err("RGA_gen_two_pro err\n"); + goto err_put_dma_buf; + } + + ret = rga_check_param(req); + if (ret == -EINVAL) { + pr_err("req 1 argument is inval\n"); + goto err_put_dma_buf; + } + + ret = rga_check_param(&req2); + if (ret == -EINVAL) { + pr_err("req 2 argument is inval\n"); + goto err_put_dma_buf; + } + + reg = rga_reg_init_2(session, req, &req2); + if (!reg) { + pr_err("init2 reg fail\n"); + rga_put_dma_buf(&req2, NULL); + goto err_put_dma_buf; + } + rga_put_dma_buf(&req2, NULL); + num = 2; + } else { + /* check value if legal */ + ret = rga_check_param(req); + if (ret == -EINVAL) { + pr_err("req argument is inval\n"); + goto err_put_dma_buf; + } + + reg = rga_reg_init(session, req); + if (!reg) { + pr_err("init reg fail\n"); + goto err_put_dma_buf; + } + + num = 1; + } + + mutex_lock(&rga_service.lock); + atomic_add(num, &rga_service.total_running); + rga_try_set_reg(); + mutex_unlock(&rga_service.lock); + return 0; + + } while (0); err_put_dma_buf: rga_put_dma_buf(req, NULL); - return -EFAULT; + return -EFAULT; } static int rga_blit_async(rga_session *session, struct rga_req *req)