diff --git a/drivers/video/rockchip/rga3/include/rga2_mmu_info.h b/drivers/video/rockchip/rga3/include/rga2_mmu_info.h index 46a4be331f1d..a8550328f599 100644 --- a/drivers/video/rockchip/rga3/include/rga2_mmu_info.h +++ b/drivers/video/rockchip/rga3/include/rga2_mmu_info.h @@ -12,28 +12,25 @@ */ #define RGA2_PHY_PAGE_SIZE (((8192 * 8192 * 4) / 4096) + 1) -struct rga2_mmu_info_t { +struct rga_mmu_base { + unsigned int *buf_virtual; + struct page **pages; + u8 buf_order; + u8 pages_order; + int32_t front; int32_t back; int32_t size; int32_t curr; - unsigned int *buf; - unsigned int *buf_virtual; - - struct page **pages; - - u8 buf_order; - u8 pages_order; }; -int rga2_user_memory_check(struct page **pages, u32 w, u32 h, u32 format, int flag); +int rga_user_memory_check(struct page **pages, u32 w, u32 h, u32 format, int flag); +int rga_set_mmu_base(struct rga_job *job, struct rga2_req *req); +unsigned int *rga_mmu_buf_get(struct rga_mmu_base *mmu_base, uint32_t size); -int rga2_set_mmu_base(struct rga_job *job, struct rga2_req *req); +struct rga_mmu_base *rga_mmu_base_init(size_t size); +void rga_mmu_base_free(struct rga_mmu_base **mmu_base); -unsigned int *rga2_mmu_buf_get(uint32_t size); - -int rga2_mmu_base_init(void); -void rga2_mmu_base_free(void); #endif diff --git a/drivers/video/rockchip/rga3/include/rga_drv.h b/drivers/video/rockchip/rga3/include/rga_drv.h index 87afc8f5f43f..7c254fbfe982 100644 --- a/drivers/video/rockchip/rga3/include/rga_drv.h +++ b/drivers/video/rockchip/rga3/include/rga_drv.h @@ -368,6 +368,7 @@ struct rga_drvdata_t { struct rga_scheduler_t *scheduler[RGA_MAX_SCHEDULER]; int num_of_scheduler; + struct rga_mmu_base *mmu_base; struct delayed_work power_off_work; diff --git a/drivers/video/rockchip/rga3/rga2_mmu_info.c b/drivers/video/rockchip/rga3/rga2_mmu_info.c index b2ec85f0f0c2..328845dc3dc4 100644 --- a/drivers/video/rockchip/rga3/rga2_mmu_info.c +++ b/drivers/video/rockchip/rga3/rga2_mmu_info.c @@ -13,15 +13,13 @@ #include "rga_job.h" #include "rga_common.h" -struct rga2_mmu_info_t rga2_mmu_info; - static void rga2_dma_sync_flush_range(void *pstart, void *pend, struct rga_scheduler_t *scheduler) { dma_sync_single_for_device(scheduler->dev, virt_to_phys(pstart), pend - pstart, DMA_TO_DEVICE); } -int rga2_user_memory_check(struct page **pages, u32 w, u32 h, u32 format, int flag) +int rga_user_memory_check(struct page **pages, u32 w, u32 h, u32 format, int flag) { int bits; void *vaddr = NULL; @@ -59,7 +57,7 @@ int rga2_user_memory_check(struct page **pages, u32 w, u32 h, u32 format, int fl return 0; } -int rga2_set_mmu_base(struct rga_job *job, struct rga2_req *req) +int rga_set_mmu_base(struct rga_job *job, struct rga2_req *req) { if (job->src_buffer.page_table) { rga2_dma_sync_flush_range(job->src_buffer.page_table, @@ -101,7 +99,7 @@ int rga2_set_mmu_base(struct rga_job *job, struct rga2_req *req) return 0; } -static int rga2_mmu_buf_get_try(struct rga2_mmu_info_t *t, uint32_t size) +static int rga_mmu_buf_get_try(struct rga_mmu_base *t, uint32_t size) { int ret = 0; @@ -134,98 +132,97 @@ out: return ret; } -unsigned int *rga2_mmu_buf_get(uint32_t size) +unsigned int *rga_mmu_buf_get(struct rga_mmu_base *mmu_base, uint32_t size) { int ret; - unsigned int *mmu_base = NULL; + unsigned int *buf = NULL; + + WARN_ON(!mutex_is_locked(&rga_drvdata->lock)); size = ALIGN(size, 16); - mutex_lock(&rga_drvdata->lock); - - ret = rga2_mmu_buf_get_try(&rga2_mmu_info, size); + ret = rga_mmu_buf_get_try(mmu_base, size); if (ret < 0) { pr_err("Get MMU mem failed\n"); - mutex_unlock(&rga_drvdata->lock); return NULL; } - mmu_base = rga2_mmu_info.buf_virtual + rga2_mmu_info.front; + buf = mmu_base->buf_virtual + mmu_base->front; - rga2_mmu_info.front += size; + mmu_base->front += size; - if (rga2_mmu_info.back + size > 2 * rga2_mmu_info.size) - rga2_mmu_info.back = size + rga2_mmu_info.size; + if (mmu_base->back + size > 2 * mmu_base->size) + mmu_base->back = size + mmu_base->size; else - rga2_mmu_info.back += size; + mmu_base->back += size; - mutex_unlock(&rga_drvdata->lock); - - return mmu_base; + return buf; } -int rga2_mmu_base_init(void) +struct rga_mmu_base *rga_mmu_base_init(size_t size) { int order = 0; - uint32_t *buf_p; - uint32_t *buf; + struct rga_mmu_base *mmu_base; + + mmu_base = kzalloc(sizeof(*mmu_base), GFP_KERNEL); + if (mmu_base == NULL) { + pr_err("Cannot alloc mmu_base!\n"); + return ERR_PTR(-ENOMEM); + } /* * malloc pre scale mid buf mmu table: - * RGA2_PHY_PAGE_SIZE * channel_num * address_size + * size * channel_num * address_size */ - order = get_order(RGA2_PHY_PAGE_SIZE * 3 * sizeof(buf_p)); - buf_p = (uint32_t *) __get_free_pages(GFP_KERNEL | GFP_DMA32, order); - if (buf_p == NULL) { + order = get_order(size * 3 * sizeof(*mmu_base->buf_virtual)); + mmu_base->buf_virtual = (uint32_t *) __get_free_pages(GFP_KERNEL | GFP_DMA32, order); + if (mmu_base->buf_virtual == NULL) { pr_err("Can not alloc pages for mmu_page_table\n"); - return -ENOMEM; + goto err_free_mmu_base; } + mmu_base->buf_order = order; - rga2_mmu_info.buf_order = order; - - order = get_order(RGA2_PHY_PAGE_SIZE * sizeof(struct page *)); - rga2_mmu_info.pages = - (struct page **)__get_free_pages(GFP_KERNEL | GFP_DMA32, order); - if (rga2_mmu_info.pages == NULL) { - pr_err("Can not alloc pages for rga2_mmu_info.pages\n"); + order = get_order(size * sizeof(*mmu_base->pages)); + mmu_base->pages = (struct page **)__get_free_pages(GFP_KERNEL | GFP_DMA32, order); + if (mmu_base->pages == NULL) { + pr_err("Can not alloc pages for mmu_base->pages\n"); goto err_free_buf_virtual; } + mmu_base->pages_order = order; - rga2_mmu_info.pages_order = order; + mmu_base->front = 0; + mmu_base->back = RGA2_PHY_PAGE_SIZE * 3; + mmu_base->size = RGA2_PHY_PAGE_SIZE * 3; -#if (defined(CONFIG_ARM) && defined(CONFIG_ARM_LPAE)) - buf = - (uint32_t *) (uint32_t) - virt_to_phys((void *)((unsigned long)buf_p)); -#else - buf = (uint32_t *) virt_to_phys((void *)((unsigned long)buf_p)); -#endif - rga2_mmu_info.buf_virtual = buf_p; - rga2_mmu_info.buf = buf; - rga2_mmu_info.front = 0; - rga2_mmu_info.back = RGA2_PHY_PAGE_SIZE * 3; - rga2_mmu_info.size = RGA2_PHY_PAGE_SIZE * 3; - - return 0; + return mmu_base; err_free_buf_virtual: - free_pages((unsigned long)buf_p, rga2_mmu_info.buf_order); - rga2_mmu_info.buf_order = 0; + free_pages((unsigned long)mmu_base->buf_virtual, mmu_base->buf_order); + mmu_base->buf_order = 0; - return -ENOMEM; +err_free_mmu_base: + kfree(mmu_base); + + return ERR_PTR(-ENOMEM); } -void rga2_mmu_base_free(void) +void rga_mmu_base_free(struct rga_mmu_base **mmu_base) { - if (rga2_mmu_info.buf_virtual != NULL) { - free_pages((unsigned long)rga2_mmu_info.buf_virtual, rga2_mmu_info.buf_order); - rga2_mmu_info.buf_virtual = NULL; - rga2_mmu_info.buf_order = 0; + struct rga_mmu_base *base = *mmu_base; + + if (base->buf_virtual != NULL) { + free_pages((unsigned long)base->buf_virtual, base->buf_order); + base->buf_virtual = NULL; + base->buf_order = 0; } - if (rga2_mmu_info.pages != NULL) { - free_pages((unsigned long)rga2_mmu_info.pages, rga2_mmu_info.pages_order); - rga2_mmu_info.pages = NULL; - rga2_mmu_info.pages_order = 0; + if (base->pages != NULL) { + free_pages((unsigned long)base->pages, base->pages_order); + base->pages = NULL; + base->pages_order = 0; } + + kfree(base); + *mmu_base = NULL; } + diff --git a/drivers/video/rockchip/rga3/rga2_reg_info.c b/drivers/video/rockchip/rga3/rga2_reg_info.c index 17e4356d2b8c..abc9df4451bf 100644 --- a/drivers/video/rockchip/rga3/rga2_reg_info.c +++ b/drivers/video/rockchip/rga3/rga2_reg_info.c @@ -14,8 +14,6 @@ #include "rga_hw_config.h" #include "rga_debugger.h" -extern struct rga2_mmu_info_t rga2_mmu_info; - unsigned int rga2_rop_code[256] = { 0x00000007, 0x00000451, 0x00006051, 0x00800051, 0x00007041, 0x00800041, 0x00804830, 0x000004f0,//0 @@ -2246,7 +2244,7 @@ int rga2_init_reg(struct rga_job *job) return -EINVAL; } - ret = rga2_set_mmu_base(job, &req); + ret = rga_set_mmu_base(job, &req); if (ret < 0) { pr_err("%s, [%d] set mmu info error\n", __func__, __LINE__); diff --git a/drivers/video/rockchip/rga3/rga_drv.c b/drivers/video/rockchip/rga3/rga_drv.c index ae0d4c7ac818..271ffcb30ee9 100644 --- a/drivers/video/rockchip/rga3/rga_drv.c +++ b/drivers/video/rockchip/rga3/rga_drv.c @@ -1394,11 +1394,13 @@ static int rga_drv_probe(struct platform_device *pdev) data->num_of_scheduler++; +#ifndef CONFIG_ROCKCHIP_FPGA for (i = scheduler->num_clks - 1; i >= 0; i--) if (!IS_ERR(scheduler->clks[i])) clk_disable_unprepare(scheduler->clks[i]); pm_runtime_put_sync(&pdev->dev); +#endif //CONFIG_ROCKCHIP_FPGA pr_info("%s probe successfully\n", dev_driver_string(dev)); @@ -1480,10 +1482,14 @@ static int __init rga_init(void) } for (i = 0; i < rga_drvdata->num_of_scheduler; i++) { - if (rga_drvdata->scheduler[i]->data->mmu == RGA_MMU) { - ret = rga2_mmu_base_init(); - if (ret) { - pr_err("rga2 mmu base init failed!\n"); + struct rga_scheduler_t *scheduler = rga_drvdata->scheduler[i]; + + if (scheduler->data->mmu == RGA_MMU) { + rga_drvdata->mmu_base = rga_mmu_base_init(RGA2_PHY_PAGE_SIZE); + if (IS_ERR(rga_drvdata->mmu_base)) { + dev_err(scheduler->dev, "rga mmu base init failed!\n"); + ret = PTR_ERR(rga_drvdata->mmu_base); + rga_drvdata->mmu_base = NULL; goto err_unregister_rga2; } @@ -1518,7 +1524,8 @@ static int __init rga_init(void) return 0; err_free_mmu_base: - rga2_mmu_base_free(); + if (rga_drvdata->mmu_base) + rga_mmu_base_free(&rga_drvdata->mmu_base); err_unregister_rga2: platform_driver_unregister(&rga2_driver); @@ -1537,7 +1544,8 @@ err_free_drvdata: static void __exit rga_exit(void) { - rga2_mmu_base_free(); + if (rga_drvdata->mmu_base) + rga_mmu_base_free(&rga_drvdata->mmu_base); #ifdef CONFIG_ROCKCHIP_RGA_DEBUGGER rga_debugger_remove(&rga_drvdata->debugger); diff --git a/drivers/video/rockchip/rga3/rga_mm.c b/drivers/video/rockchip/rga3/rga_mm.c index 6752596d55ef..7098ecd0ac38 100644 --- a/drivers/video/rockchip/rga3/rga_mm.c +++ b/drivers/video/rockchip/rga3/rga_mm.c @@ -1140,11 +1140,16 @@ static int rga_mm_set_mmu_base(struct rga_job *job, return -ENOMEM; } } else { - page_table = rga2_mmu_buf_get(page_count); + mutex_lock(&rga_drvdata->lock); + + page_table = rga_mmu_buf_get(rga_drvdata->mmu_base, page_count); if (page_table == NULL) { pr_err("mmu_buf get error!\n"); + mutex_unlock(&rga_drvdata->lock); return -EFAULT; } + + mutex_unlock(&rga_drvdata->lock); } sgt = rga_mm_lookup_sgt(job_buf->y_addr, job->core); @@ -1194,11 +1199,16 @@ static int rga_mm_set_mmu_base(struct rga_job *job, return -ENOMEM; } } else { - page_table = rga2_mmu_buf_get(page_count); + mutex_lock(&rga_drvdata->lock); + + page_table = rga_mmu_buf_get(rga_drvdata->mmu_base, page_count); if (page_table == NULL) { pr_err("mmu_buf get error!\n"); + mutex_unlock(&rga_drvdata->lock); return -EFAULT; } + + mutex_unlock(&rga_drvdata->lock); } sgt = rga_mm_lookup_sgt(job_buf->addr, job->core);