From f9d1b18ddac96f0efdb2ff78c8a8c426d7438310 Mon Sep 17 00:00:00 2001 From: Yu Qiaowei Date: Mon, 26 Jul 2021 21:01:21 +0800 Subject: [PATCH] video/rockchip: rga: adapt to kernel 5.10 1. Use dma_sync_single_for_device to flush cache. 2. Refer to RGA2 adaptation kernel 5.10. Signed-off-by: Yu Qiaowei Change-Id: Iebd7f092b8dd070661cde12fd8669d2bdf4001c3 --- drivers/video/rockchip/rga/RGA_API.h | 27 +++++- drivers/video/rockchip/rga/rga_drv.c | 39 +------- drivers/video/rockchip/rga/rga_mmu_info.c | 112 +++++++++++++--------- drivers/video/rockchip/rga/rga_mmu_info.h | 9 +- 4 files changed, 100 insertions(+), 87 deletions(-) diff --git a/drivers/video/rockchip/rga/RGA_API.h b/drivers/video/rockchip/rga/RGA_API.h index f13f666d822f..ade17d03e85c 100644 --- a/drivers/video/rockchip/rga/RGA_API.h +++ b/drivers/video/rockchip/rga/RGA_API.h @@ -1,13 +1,36 @@ /* SPDX-License-Identifier: GPL-2.0 */ #ifndef __RGA_API_H__ #define __RGA_API_H__ + +#include +#include #include "rga_reg_info.h" #include "rga.h" #define ENABLE 1 -#define DISABLE 0 - +#define DISABLE 0 + +struct rga_drvdata { + struct miscdevice miscdev; + struct device *dev; + void *rga_base; + int irq; + + struct delayed_work power_off_work; + void (*rga_irq_callback)(int rga_retval); //callback function used by aync call + struct wake_lock wake_lock; + + struct clk *pd_rga; + struct clk *aclk_rga; + struct clk *hclk_rga; + + //#if defined(CONFIG_ION_ROCKCHIP) + struct ion_client *ion_client; + //#endif + char *version; +}; + int32_t RGA_gen_two_pro(struct rga_req *msg, struct rga_req *msg1); diff --git a/drivers/video/rockchip/rga/rga_drv.c b/drivers/video/rockchip/rga/rga_drv.c index 28c552d721cc..f6ca9a2f332b 100644 --- a/drivers/video/rockchip/rga/rga_drv.c +++ b/drivers/video/rockchip/rga/rga_drv.c @@ -97,27 +97,7 @@ unsigned char RGA_NONUSE; unsigned char RGA_INT_FLAG; #endif -struct rga_drvdata { - struct miscdevice miscdev; - struct device *dev; - void *rga_base; - int irq; - - struct delayed_work power_off_work; - void (*rga_irq_callback)(int rga_retval); //callback function used by aync call - struct wake_lock wake_lock; - - struct clk *pd_rga; - struct clk *aclk_rga; - struct clk *hclk_rga; - - //#if defined(CONFIG_ION_ROCKCHIP) - struct ion_client *ion_client; - //#endif - char *version; -}; - -static struct rga_drvdata *drvdata; +struct rga_drvdata *drvdata; rga_service_info rga_service; struct rga_mmu_buf_t rga_mmu_buf; @@ -842,12 +822,7 @@ static void rga_try_set_reg(void) rga_copy_reg(reg, 0); rga_reg_from_wait_to_run(reg); - #ifdef CONFIG_ARM - dmac_flush_range(&rga_service.cmd_buff[0], &rga_service.cmd_buff[32]); - outer_flush_range(virt_to_phys(&rga_service.cmd_buff[0]),virt_to_phys(&rga_service.cmd_buff[32])); - #elif defined(CONFIG_ARM64) - __dma_flush_range(&rga_service.cmd_buff[0], &rga_service.cmd_buff[32]); - #endif + rga_dma_flush_range(&rga_service.cmd_buff[0], &rga_service.cmd_buff[32]); rga_soft_reset(); @@ -2235,15 +2210,7 @@ void rga_slt(void) memset(src1_buf, 0x50, 400 * 200 * 4); memset(dst1_buf, 0x00, 400 * 200 * 4); -#ifdef CONFIG_ARM - dmac_flush_range(&src1_buf[0], &src1_buf[400 * 200]); - outer_flush_range(virt_to_phys(&src1_buf[0]), virt_to_phys(&src1_buf[400 * 200])); - dmac_flush_range(&dst1_buf[0], &dst1_buf[400 * 200]); - outer_flush_range(virt_to_phys(&dst1_buf[0]), virt_to_phys(&dst1_buf[400 * 200])); -#elif defined(CONFIG_ARM64) - __dma_flush_range(&src1_buf[0], &src1_buf[400 * 200]); - __dma_flush_range(&dst1_buf[0], &dst1_buf[400 * 200]); -#endif + rga_dma_flush_range(&src1_buf[0], &src1_buf[400 * 200]); DBG("\n********************************\n"); DBG("************ RGA_TEST ************\n"); diff --git a/drivers/video/rockchip/rga/rga_mmu_info.c b/drivers/video/rockchip/rga/rga_mmu_info.c index a8d7e6263cda..8825183d92fc 100644 --- a/drivers/video/rockchip/rga/rga_mmu_info.c +++ b/drivers/video/rockchip/rga/rga_mmu_info.c @@ -28,7 +28,12 @@ extern struct rga_mmu_buf_t rga_mmu_buf; extern int RGA_CHECK_MODE; #endif -#define KERNEL_SPACE_VALID 0xc0000000 +#define KERNEL_SPACE_VALID 0xc0000000 + +void rga_dma_flush_range(void *pstart, void *pend) +{ + dma_sync_single_for_device(drvdata->dev, virt_to_phys(pstart), pend - pstart, DMA_TO_DEVICE); +} static int rga_mmu_buf_get(struct rga_mmu_buf_t *t, uint32_t size) { @@ -328,16 +333,29 @@ static int rga_MapUserMemory(struct page **pages, Address = 0; do { - down_read(¤t->mm->mmap_sem); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) + mmap_read_lock(current->mm); +#else + down_read(¤t->mm->mmap_sem); +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0) result = get_user_pages(current, current->mm, Memory << PAGE_SHIFT, pageCount, 1, 0, pages, NULL); -#else +#elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) result = get_user_pages_remote(current, current->mm, Memory << PAGE_SHIFT, pageCount, 1, pages, NULL, NULL); +#else + result = get_user_pages_remote(current->mm, Memory << PAGE_SHIFT, + pageCount, 1, pages, NULL, NULL); +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) + mmap_read_unlock(current->mm); +#else + up_read(¤t->mm->mmap_sem); #endif - up_read(¤t->mm->mmap_sem); #if 0 if(result <= 0 || result < pageCount) @@ -365,10 +383,18 @@ static int rga_MapUserMemory(struct page **pages, struct vm_area_struct *vma; if (result>0) { - down_read(¤t->mm->mmap_sem); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) + mmap_read_lock(current->mm); +#else + down_read(¤t->mm->mmap_sem); +#endif for (i = 0; i < result; i++) put_page(pages[i]); - up_read(¤t->mm->mmap_sem); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) + mmap_read_unlock(current->mm); +#else + up_read(¤t->mm->mmap_sem); +#endif } for(i=0; i= KERNEL_VERSION(5, 10, 0) + p4d_t * p4d; +#endif pud_t * pud; pgd = pgd_offset(current->mm, (Memory + i) << PAGE_SHIFT); @@ -393,7 +422,20 @@ static int rga_MapUserMemory(struct page **pages, break; } - pud = pud_offset(pgd, (Memory + i) << PAGE_SHIFT); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) + /* In the four-level page table, it will do nothing and return pgd. */ + p4d = p4d_offset(pgd, (Memory + i) << PAGE_SHIFT); + if (p4d_none(*p4d) || unlikely(p4d_bad(*p4d))) { + pr_err("RGA2 failed to get p4d, result = %d, pageCount = %d\n", + result, pageCount); + status = RGA_OUT_OF_RESOURCES; + break; + } + + pud = pud_offset(p4d, (Memory + i) << PAGE_SHIFT); +#else + pud = pud_offset(pgd, (Memory + i) << PAGE_SHIFT); +#endif if (pud) { pmd_t * pmd = pmd_offset(pud, (Memory + i) << PAGE_SHIFT); @@ -442,10 +484,18 @@ static int rga_MapUserMemory(struct page **pages, pageTable[i] = page_to_phys(pages[i]); } - down_read(¤t->mm->mmap_sem); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) + mmap_read_lock(current->mm); +#else + down_read(¤t->mm->mmap_sem); +#endif for (i = 0; i < result; i++) put_page(pages[i]); - up_read(¤t->mm->mmap_sem); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) + mmap_read_unlock(current->mm); +#else + up_read(¤t->mm->mmap_sem); +#endif return 0; } @@ -665,12 +715,7 @@ static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req) req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((SrcMemSize + uv_size) << PAGE_SHIFT); /* flush data to DDR */ - #ifdef CONFIG_ARM - dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); - outer_flush_range(virt_to_phys(MMU_Base), virt_to_phys(MMU_Base + AllSize + 1)); - #elif defined(CONFIG_ARM64) - __dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); - #endif + rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); reg->MMU_len = AllSize + 16; @@ -792,12 +837,7 @@ static int rga_mmu_info_color_palette_mode(struct rga_reg *reg, struct rga_req * reg->MMU_base = MMU_Base; /* flush data to DDR */ - #ifdef CONFIG_ARM - dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); - outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1)); - #elif defined(CONFIG_ARM64) - __dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); - #endif + rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); reg->MMU_len = AllSize + 16; @@ -878,12 +918,7 @@ static int rga_mmu_info_color_fill_mode(struct rga_reg *reg, struct rga_req *req reg->MMU_base = MMU_Base; /* flush data to DDR */ - #ifdef CONFIG_ARM - dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); - outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1)); - #elif defined(CONFIG_ARM64) - __dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); - #endif + rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); reg->MMU_len = AllSize + 16; @@ -1033,12 +1068,7 @@ static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req) reg->MMU_base = MMU_Base; /* flush data to DDR */ - #ifdef CONFIG_ARM - dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); - outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1)); - #elif defined(CONFIG_ARM64) - __dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); - #endif + rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); reg->MMU_len = AllSize + 16; @@ -1126,12 +1156,7 @@ static int rga_mmu_info_update_palette_table_mode(struct rga_reg *reg, struct rg reg->MMU_base = MMU_Base; /* flush data to DDR */ - #ifdef CONFIG_ARM - dmac_flush_range(MMU_Base, (MMU_Base + AllSize)); - outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize)); - #elif defined(CONFIG_ARM64) - __dma_flush_range(MMU_Base, (MMU_Base + AllSize)); - #endif + rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize)); if (pages != NULL) { @@ -1230,12 +1255,7 @@ static int rga_mmu_info_update_patten_buff_mode(struct rga_reg *reg, struct rga_ reg->MMU_base = MMU_Base; /* flush data to DDR */ - #ifdef CONFIG_ARM - dmac_flush_range(MMU_Base, (MMU_Base + AllSize)); - outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize)); - #elif defined(CONFIG_ARM64) - __dma_flush_range(MMU_Base, (MMU_Base + AllSize)); - #endif + rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize)); if (pages != NULL) { /* Free the page table */ diff --git a/drivers/video/rockchip/rga/rga_mmu_info.h b/drivers/video/rockchip/rga/rga_mmu_info.h index d828322613c0..3e70894c7ee7 100644 --- a/drivers/video/rockchip/rga/rga_mmu_info.h +++ b/drivers/video/rockchip/rga/rga_mmu_info.h @@ -2,7 +2,8 @@ #ifndef __RGA_MMU_INFO_H__ #define __RGA_MMU_INFO_H__ -#include "rga.h" +#include "rga.h" +#include "RGA_API.h" #ifndef MIN #define MIN(X, Y) ((X)<(Y)?(X):(Y)) @@ -11,8 +12,10 @@ #ifndef MAX #define MAX(X, Y) ((X)>(Y)?(X):(Y)) #endif - - + +extern struct rga_drvdata *drvdata; + +void rga_dma_flush_range(void *pstart, void *pend); int rga_set_mmu_info(struct rga_reg *reg, struct rga_req *req);