rockchip/rga: add rga support yuv 10 bit
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / rga2 / rga2_mmu_info.c
index 35529aeac04676c18b17cfcdf145f4f9a77fd817..1b88c067ebfe303c1faa67c40fba6dfa4dd0035f 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/slab.h>\r
 #include <linux/memory.h>\r
 #include <linux/dma-mapping.h>\r
+#include <linux/scatterlist.h>\r
 #include <asm/memory.h>\r
 #include <asm/atomic.h>\r
 #include <asm/cacheflush.h>\r
@@ -66,15 +67,20 @@ static int rga2_mmu_buf_get_try(struct rga2_mmu_buf_t *t, uint32_t size)
 {\r
     mutex_lock(&rga2_service.lock);\r
     if((t->back - t->front) > t->size) {\r
-        if(t->front + size > t->back - t->size)\r
+        if(t->front + size > t->back - t->size) {\r
+           pr_info("front %d, back %d dsize %d size %d", t->front, t->back, t->size, size);\r
             return -1;\r
+       }\r
     }\r
     else {\r
-        if((t->front + size) > t->back)\r
+        if((t->front + size) > t->back) {\r
+           pr_info("front %d, back %d dsize %d size %d", t->front, t->back, t->size, size);\r
             return -1;\r
+       }\r
 \r
         if(t->front + size > t->size) {\r
             if (size > (t->back - t->size)) {\r
+               pr_info("front %d, back %d dsize %d size %d", t->front, t->back, t->size, size);\r
                 return -1;\r
             }\r
             t->front = 0;\r
@@ -85,23 +91,9 @@ static int rga2_mmu_buf_get_try(struct rga2_mmu_buf_t *t, uint32_t size)
     return 0;\r
 }\r
 \r
-#if 0\r
-static int rga2_mmu_buf_cal(struct rga2_mmu_buf_t *t, uint32_t size)\r
-{\r
-    if((t->front + size) > t->back) {\r
-        return -1;\r
-    }\r
-    else {\r
-        return 0;\r
-    }\r
-}\r
-#endif\r
-\r
-\r
-\r
-static int rga2_mem_size_cal(uint32_t Mem, uint32_t MemSize, uint32_t *StartAddr)\r
+static int rga2_mem_size_cal(unsigned long Mem, uint32_t MemSize, unsigned long *StartAddr)\r
 {\r
-    uint32_t start, end;\r
+    unsigned long start, end;\r
     uint32_t pageCount;\r
 \r
     end = (Mem + (MemSize + PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
@@ -111,14 +103,14 @@ static int rga2_mem_size_cal(uint32_t Mem, uint32_t MemSize, uint32_t *StartAddr
     return pageCount;\r
 }\r
 \r
-static int rga2_buf_size_cal(uint32_t yrgb_addr, uint32_t uv_addr, uint32_t v_addr,\r
-                                        int format, uint32_t w, uint32_t h, uint32_t *StartAddr )\r
+static int rga2_buf_size_cal(unsigned long yrgb_addr, unsigned long uv_addr, unsigned long v_addr,\r
+                                        int format, uint32_t w, uint32_t h, unsigned long *StartAddr )\r
 {\r
     uint32_t size_yrgb = 0;\r
     uint32_t size_uv = 0;\r
     uint32_t size_v = 0;\r
     uint32_t stride = 0;\r
-    uint32_t start, end;\r
+    unsigned long start, end;\r
     uint32_t pageCount;\r
 \r
     switch(format)\r
@@ -178,7 +170,6 @@ static int rga2_buf_size_cal(uint32_t yrgb_addr, uint32_t uv_addr, uint32_t v_ad
             size_yrgb = stride * h;\r
             size_uv = stride * h;\r
             start = MIN(yrgb_addr, uv_addr);\r
-\r
             start >>= PAGE_SHIFT;\r
             end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv));\r
             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
@@ -206,6 +197,8 @@ static int rga2_buf_size_cal(uint32_t yrgb_addr, uint32_t uv_addr, uint32_t v_ad
             end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv));\r
             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
             pageCount = end - start;\r
+            //printk("yrgb_addr = %.8x\n", yrgb_addr);\r
+            //printk("uv_addr = %.8x\n", uv_addr);\r
             break;\r
         case RGA2_FORMAT_YCbCr_420_P :\r
         case RGA2_FORMAT_YCrCb_420_P :\r
@@ -229,6 +222,18 @@ static int rga2_buf_size_cal(uint32_t yrgb_addr, uint32_t uv_addr, uint32_t v_ad
         case RK_FORMAT_BPP8 :\r
             break;\r
         #endif\r
+        case RGA2_FORMAT_YCbCr_420_SP_10B:\r
+        case RGA2_FORMAT_YCrCb_420_SP_10B:\r
+            stride = (w + 3) & (~3);\r
+            stride = stride;\r
+            size_yrgb = stride * h;\r
+            size_uv = (stride * (h >> 1));\r
+            start = MIN(yrgb_addr, uv_addr);\r
+            start >>= PAGE_SHIFT;\r
+            end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv));\r
+            end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
+            pageCount = end - start;\r
+            break;\r
         default :\r
             pageCount = 0;\r
             start = 0;\r
@@ -241,14 +246,13 @@ static int rga2_buf_size_cal(uint32_t yrgb_addr, uint32_t uv_addr, uint32_t v_ad
 \r
 static int rga2_MapUserMemory(struct page **pages,\r
                                             uint32_t *pageTable,\r
-                                            uint32_t Memory,\r
+                                            unsigned long Memory,\r
                                             uint32_t pageCount)\r
 {\r
     int32_t result;\r
     uint32_t i;\r
     uint32_t status;\r
-    uint32_t Address;\r
-    //uint32_t temp;\r
+    unsigned long Address;\r
 \r
     status = 0;\r
     Address = 0;\r
@@ -267,38 +271,23 @@ static int rga2_MapUserMemory(struct page **pages,
                 );\r
         up_read(&current->mm->mmap_sem);\r
 \r
-        #if 0\r
-        if(result <= 0 || result < pageCount)\r
-        {\r
-            status = 0;\r
-\r
-            for(i=0; i<pageCount; i++)\r
-            {\r
-                temp = armv7_va_to_pa((Memory + i) << PAGE_SHIFT);\r
-                if (temp == 0xffffffff)\r
-                {\r
-                    printk("rga find mmu phy ddr error\n ");\r
-                    status = RGA_OUT_OF_RESOURCES;\r
-                    break;\r
-                }\r
-\r
-                pageTable[i] = temp;\r
-            }\r
-\r
-            return status;\r
-        }\r
-        #else\r
         if(result <= 0 || result < pageCount)\r
         {\r
             struct vm_area_struct *vma;\r
 \r
+            if (result>0) {\r
+                           down_read(&current->mm->mmap_sem);\r
+                           for (i = 0; i < result; i++)\r
+                                   put_page(pages[i]);\r
+                           up_read(&current->mm->mmap_sem);\r
+                   }\r
+\r
             for(i=0; i<pageCount; i++)\r
             {\r
                 vma = find_vma(current->mm, (Memory + i) << PAGE_SHIFT);\r
 \r
                 if (vma)//&& (vma->vm_flags & VM_PFNMAP) )\r
                 {\r
-                    #if 1\r
                     do\r
                     {\r
                         pte_t       * pte;\r
@@ -344,29 +333,7 @@ static int rga2_MapUserMemory(struct page **pages,
                     }\r
                     while (0);\r
 \r
-                    #else\r
-                    do\r
-                    {\r
-                        pte_t       * pte;\r
-                        spinlock_t  * ptl;\r
-                        unsigned long pfn;\r
-                        pgd_t * pgd;\r
-                        pud_t * pud;\r
-                        pmd_t * pmd;\r
-\r
-                        pgd = pgd_offset(current->mm, (Memory + i) << PAGE_SHIFT);\r
-                        pud = pud_offset(pgd, (Memory + i) << PAGE_SHIFT);\r
-                        pmd = pmd_offset(pud, (Memory + i) << PAGE_SHIFT);\r
-                        pte = pte_offset_map_lock(current->mm, pmd, (Memory + i) << PAGE_SHIFT, &ptl);\r
-\r
-                        pfn = pte_pfn(*pte);\r
-                        Address = ((pfn << PAGE_SHIFT) | (((unsigned long)((Memory + i) << PAGE_SHIFT)) & ~PAGE_MASK));\r
-                        pte_unmap_unlock(pte, ptl);\r
-                    }\r
-                    while (0);\r
-                    #endif\r
-\r
-                    pageTable[i] = Address;\r
+                    pageTable[i] = (uint32_t)Address;\r
                 }\r
                 else\r
                 {\r
@@ -377,7 +344,6 @@ static int rga2_MapUserMemory(struct page **pages,
 \r
             return status;\r
         }\r
-        #endif\r
 \r
         /* Fill the page table. */\r
         for(i=0; i<pageCount; i++)\r
@@ -386,6 +352,11 @@ static int rga2_MapUserMemory(struct page **pages,
             pageTable[i] = page_to_phys(pages[i]);\r
         }\r
 \r
+        down_read(&current->mm->mmap_sem);\r
+               for (i = 0; i < result; i++)\r
+                       put_page(pages[i]);\r
+               up_read(&current->mm->mmap_sem);\r
+\r
         return 0;\r
     }\r
     while(0);\r
@@ -393,10 +364,47 @@ static int rga2_MapUserMemory(struct page **pages,
     return status;\r
 }\r
 \r
+static int rga2_MapION(struct sg_table *sg,\r
+                               uint32_t *Memory,\r
+                               int32_t  pageCount)\r
+{\r
+    uint32_t i;\r
+    uint32_t status;\r
+    unsigned long Address;\r
+    uint32_t mapped_size = 0;\r
+    uint32_t len;\r
+    struct scatterlist *sgl = sg->sgl;\r
+    uint32_t sg_num = 0;\r
+    uint32_t break_flag = 0;\r
+\r
+    status = 0;\r
+    Address = 0;\r
+    do {\r
+        len = sg_dma_len(sgl) >> PAGE_SHIFT;\r
+        Address = sg_phys(sgl);\r
+\r
+        for(i=0; i<len; i++) {\r
+            if (mapped_size + i >= pageCount) {\r
+                break_flag = 1;\r
+                break;\r
+            }\r
+            Memory[mapped_size + i] = (uint32_t)(Address + (i << PAGE_SHIFT));\r
+        }\r
+        if (break_flag)\r
+            break;\r
+        mapped_size += len;\r
+        sg_num += 1;\r
+    }\r
+    while((sgl = sg_next(sgl)) && (mapped_size < pageCount) && (sg_num < sg->nents));\r
+\r
+    return 0;\r
+}\r
+\r
+\r
 static int rga2_mmu_info_BitBlt_mode(struct rga2_reg *reg, struct rga2_req *req)\r
 {\r
     int Src0MemSize, DstMemSize, Src1MemSize;\r
-    uint32_t Src0Start, Src1Start, DstStart;\r
+    unsigned long Src0Start, Src1Start, DstStart;\r
     uint32_t AllSize;\r
     uint32_t *MMU_Base, *MMU_Base_phys;\r
     int ret;\r
@@ -411,8 +419,7 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_reg *reg, struct rga2_req *req)
     Src1MemSize = 0;\r
     DstMemSize  = 0;\r
 \r
-    do\r
-    {\r
+    do {\r
         /* cal src0 buf mmu info */\r
         if(req->mmu_info.src0_mmu_flag & 1) {\r
             Src0MemSize = rga2_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr,\r
@@ -448,14 +455,10 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_reg *reg, struct rga2_req *req)
         }\r
 \r
         /* Cal out the needed mem size */\r
-        AllSize = ((Src0MemSize+3)&(~3)) + ((Src1MemSize+3)&(~3)) + ((DstMemSize+3)&(~3));\r
-\r
-        pages = kzalloc((AllSize)* sizeof(struct page *), GFP_KERNEL);\r
-        if(pages == NULL) {\r
-            pr_err("RGA MMU malloc pages mem failed\n");\r
-            status = RGA2_MALLOC_ERROR;\r
-            break;\r
-        }\r
+        Src0MemSize = (Src0MemSize+15)&(~15);\r
+        Src1MemSize = (Src1MemSize+15)&(~15);\r
+        DstMemSize  = (DstMemSize+15)&(~15);\r
+        AllSize = Src0MemSize + Src1MemSize + DstMemSize;\r
 \r
         if (rga2_mmu_buf_get_try(&rga2_mmu_buf, AllSize)) {\r
             pr_err("RGA2 Get MMU mem failed\n");\r
@@ -463,13 +466,20 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_reg *reg, struct rga2_req *req)
             break;\r
         }\r
 \r
+        pages = rga2_mmu_buf.pages;\r
+\r
         mutex_lock(&rga2_service.lock);\r
         MMU_Base = rga2_mmu_buf.buf_virtual + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
         MMU_Base_phys = rga2_mmu_buf.buf + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
         mutex_unlock(&rga2_service.lock);\r
-\r
         if(Src0MemSize) {\r
-            ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0], Src0Start, Src0MemSize);\r
+            if (req->sg_src0) {\r
+                ret = rga2_MapION(req->sg_src0, &MMU_Base[0], Src0MemSize);\r
+            }\r
+            else {\r
+                ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0], Src0Start, Src0MemSize);\r
+            }\r
+\r
             if (ret < 0) {\r
                 pr_err("rga2 map src0 memory failed\n");\r
                 status = ret;\r
@@ -477,7 +487,7 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_reg *reg, struct rga2_req *req)
             }\r
 \r
             /* change the buf address in req struct */\r
-            req->mmu_info.src0_base_addr = (((uint32_t)MMU_Base_phys));\r
+            req->mmu_info.src0_base_addr = (((unsigned long)MMU_Base_phys));\r
             uv_size = (req->src.uv_addr - (Src0Start << PAGE_SHIFT)) >> PAGE_SHIFT;\r
             v_size = (req->src.v_addr - (Src0Start << PAGE_SHIFT)) >> PAGE_SHIFT;\r
 \r
@@ -486,10 +496,14 @@ 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);\r
         }\r
 \r
-        Src0MemSize = (Src0MemSize + 3) & (~3);\r
-\r
         if(Src1MemSize) {\r
-            ret = rga2_MapUserMemory(&pages[0], MMU_Base + Src0MemSize, Src1Start, Src1MemSize);\r
+            if (req->sg_src1) {\r
+                ret = rga2_MapION(req->sg_src1, MMU_Base + Src0MemSize, Src1MemSize);\r
+            }\r
+            else {\r
+                ret = rga2_MapUserMemory(&pages[0], MMU_Base + Src0MemSize, Src1Start, Src1MemSize);\r
+            }\r
+\r
             if (ret < 0) {\r
                 pr_err("rga2 map src1 memory failed\n");\r
                 status = ret;\r
@@ -497,14 +511,17 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_reg *reg, struct rga2_req *req)
             }\r
 \r
             /* change the buf address in req struct */\r
-            req->mmu_info.src1_base_addr = ((uint32_t)(MMU_Base_phys + Src0MemSize));\r
-            req->src1.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (Src1MemSize << PAGE_SHIFT);\r
+            req->mmu_info.src1_base_addr = ((unsigned long)(MMU_Base_phys + Src0MemSize));\r
+            req->src1.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK));\r
         }\r
 \r
-        Src1MemSize = (Src1MemSize + 3) & (~3);\r
-\r
         if(DstMemSize) {\r
-            ret = rga2_MapUserMemory(&pages[0], MMU_Base + Src0MemSize + Src1MemSize, DstStart, DstMemSize);\r
+            if (req->sg_dst) {\r
+                ret = rga2_MapION(req->sg_dst, MMU_Base + Src0MemSize + Src1MemSize, DstMemSize);\r
+            }\r
+            else {\r
+                ret = rga2_MapUserMemory(&pages[0], MMU_Base + Src0MemSize + Src1MemSize, DstStart, DstMemSize);\r
+            }\r
             if (ret < 0) {\r
                 pr_err("rga2 map dst memory failed\n");\r
                 status = ret;\r
@@ -512,55 +529,41 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_reg *reg, struct rga2_req *req)
             }\r
 \r
             /* change the buf address in req struct */\r
-            req->mmu_info.dst_base_addr  = ((uint32_t)(MMU_Base_phys + Src0MemSize + Src1MemSize));\r
-            req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((Src0MemSize + Src1MemSize) << PAGE_SHIFT);\r
+            req->mmu_info.dst_base_addr  = ((unsigned long)(MMU_Base_phys + Src0MemSize + Src1MemSize));\r
+            req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK));\r
             uv_size = (req->dst.uv_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
             v_size = (req->dst.v_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
-            req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((Src0MemSize + Src1MemSize + uv_size) << PAGE_SHIFT);\r
-            req->dst.v_addr = (req->dst.v_addr & (~PAGE_MASK)) | ((Src0MemSize + Src1MemSize + v_size) << PAGE_SHIFT);\r
+            req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((uv_size) << PAGE_SHIFT);\r
+            req->dst.v_addr = (req->dst.v_addr & (~PAGE_MASK)) | ((v_size) << PAGE_SHIFT);\r
         }\r
 \r
         /* flush data to DDR */\r
+        #ifdef CONFIG_ARM\r
         dmac_flush_range(MMU_Base, (MMU_Base + AllSize));\r
         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize));\r
+        #elif defined(CONFIG_ARM64)\r
+        __dma_flush_range(MMU_Base, (MMU_Base + AllSize));\r
+        #endif\r
 \r
         rga2_mmu_buf_get(&rga2_mmu_buf, AllSize);\r
         reg->MMU_len = AllSize;\r
 \r
         status = 0;\r
 \r
-        /* Free the page table */\r
-        if (pages != NULL) {\r
-            kfree(pages);\r
-        }\r
-\r
         return status;\r
     }\r
     while(0);\r
 \r
-\r
-    /* Free the page table */\r
-    if (pages != NULL) {\r
-        kfree(pages);\r
-    }\r
-\r
-    /* Free MMU table */\r
-    if(MMU_Base != NULL) {\r
-        kfree(MMU_Base);\r
-    }\r
-\r
     return status;\r
 }\r
 \r
 static int rga2_mmu_info_color_palette_mode(struct rga2_reg *reg, struct rga2_req *req)\r
 {\r
-    int SrcMemSize, DstMemSize, CMDMemSize;\r
-    uint32_t SrcStart, DstStart, CMDStart;\r
+    int SrcMemSize, DstMemSize;\r
+    unsigned long SrcStart, DstStart;\r
     struct page **pages = NULL;\r
-    uint32_t i;\r
     uint32_t AllSize;\r
-    uint32_t *MMU_Base = NULL;\r
-    uint32_t *MMU_p;\r
+    uint32_t *MMU_Base = NULL, *MMU_Base_phys;\r
     int ret, status;\r
     uint32_t stride;\r
 \r
@@ -568,146 +571,112 @@ static int rga2_mmu_info_color_palette_mode(struct rga2_reg *reg, struct rga2_re
     uint16_t sw, byte_num;\r
 \r
     shift = 3 - (req->palette_mode & 3);\r
-    sw = req->src.vir_w;\r
+    sw = req->src.vir_w*req->src.vir_h;\r
     byte_num = sw >> shift;\r
     stride = (byte_num + 3) & (~3);\r
 \r
-    do\r
-    {\r
+    SrcStart = 0;
+    DstStart = 0;
+    SrcMemSize = 0;\r
+    DstMemSize = 0;\r
 \r
-        SrcMemSize = rga2_mem_size_cal(req->src.yrgb_addr, stride, &SrcStart);\r
-        if(SrcMemSize == 0) {\r
-            return -EINVAL;\r
+    do {\r
+        if (req->mmu_info.src0_mmu_flag) {\r
+            SrcMemSize = rga2_mem_size_cal(req->src.yrgb_addr, stride, &SrcStart);\r
+            if(SrcMemSize == 0) {\r
+                return -EINVAL;\r
+            }\r
         }\r
 \r
-        DstMemSize = rga2_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
-                                        req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
-                                        &DstStart);\r
-        if(DstMemSize == 0) {\r
-            return -EINVAL;\r
+        if (req->mmu_info.dst_mmu_flag) {\r
+            DstMemSize = rga2_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
+                                            req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
+                                            &DstStart);\r
+            if(DstMemSize == 0) {\r
+                return -EINVAL;\r
+            }\r
         }\r
 \r
-        CMDMemSize = rga2_mem_size_cal((uint32_t)rga2_service.cmd_buff, RGA2_CMD_BUF_SIZE, &CMDStart);\r
-        if(CMDMemSize == 0) {\r
-            return -EINVAL;\r
-        }\r
+        SrcMemSize = (SrcMemSize + 15) & (~15);\r
+        DstMemSize = (DstMemSize + 15) & (~15);\r
 \r
-        AllSize = SrcMemSize + DstMemSize + CMDMemSize;\r
+        AllSize = SrcMemSize + DstMemSize;\r
 \r
-        pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
+        if (rga2_mmu_buf_get_try(&rga2_mmu_buf, AllSize)) {\r
+            pr_err("RGA2 Get MMU mem failed\n");\r
+            status = RGA2_MALLOC_ERROR;\r
+            break;\r
+        }\r
+\r
+        pages = rga2_mmu_buf.pages;\r
         if(pages == NULL) {\r
             pr_err("RGA MMU malloc pages mem failed\n");\r
             return -EINVAL;\r
         }\r
 \r
-        MMU_Base = kzalloc(AllSize * sizeof(uint32_t), GFP_KERNEL);\r
-        if(MMU_Base == NULL) {\r
-            pr_err("RGA MMU malloc MMU_Base point failed\n");\r
-            break;\r
-        }\r
-\r
-        /* map CMD addr */\r
-        for(i=0; i<CMDMemSize; i++)\r
-        {\r
-            MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i)<<PAGE_SHIFT));\r
-        }\r
+        mutex_lock(&rga2_service.lock);\r
+        MMU_Base = rga2_mmu_buf.buf_virtual + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
+        MMU_Base_phys = rga2_mmu_buf.buf + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
+        mutex_unlock(&rga2_service.lock);\r
 \r
-        /* map src addr */\r
-        if (req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
-        {\r
-            ret = rga2_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
-            if (ret < 0)\r
-            {\r
-                pr_err("rga map src memory failed\n");\r
+        if(SrcMemSize) {\r
+            ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize);\r
+            if (ret < 0) {\r
+                pr_err("rga2 map src0 memory failed\n");\r
                 status = ret;\r
                 break;\r
             }\r
-        }\r
-        else\r
-        {\r
-            MMU_p = MMU_Base + CMDMemSize;\r
 \r
-            for(i=0; i<SrcMemSize; i++)\r
-            {\r
-                MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
-            }\r
+            /* change the buf address in req struct */\r
+            req->mmu_info.src0_base_addr = (((unsigned long)MMU_Base_phys));\r
+            req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK));\r
         }\r
 \r
-        /* map dst addr */\r
-        if (req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
-        {\r
-            ret = rga2_MapUserMemory(&pages[CMDMemSize + SrcMemSize], &MMU_Base[CMDMemSize + SrcMemSize], DstStart, DstMemSize);\r
-            if (ret < 0)\r
-            {\r
-                pr_err("rga map dst memory failed\n");\r
+        if(DstMemSize) {\r
+            ret = rga2_MapUserMemory(&pages[0], MMU_Base + SrcMemSize, DstStart, DstMemSize);\r
+            if (ret < 0) {\r
+                pr_err("rga2 map dst memory failed\n");\r
                 status = ret;\r
                 break;\r
             }\r
-        }\r
-        else\r
-        {\r
-            MMU_p = MMU_Base + CMDMemSize + SrcMemSize;\r
 \r
-            for(i=0; i<DstMemSize; i++)\r
-            {\r
-                MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT));\r
-            }\r
+            /* change the buf address in req struct */\r
+            req->mmu_info.dst_base_addr  = ((unsigned long)(MMU_Base_phys + SrcMemSize));\r
+            req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK));\r
         }\r
 \r
-\r
-        /* zsq\r
-         * change the buf address in req struct\r
-         * for the reason of lie to MMU\r
-         */\r
-        req->mmu_info.src0_base_addr = (virt_to_phys(MMU_Base)>>2);\r
-        req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
-        req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((CMDMemSize + SrcMemSize) << PAGE_SHIFT);\r
-\r
-\r
-        /*record the malloc buf for the cmd end to release*/\r
-        reg->MMU_base = MMU_Base;\r
-\r
         /* flush data to DDR */\r
-        dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
-        outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));\r
-\r
-        /* Free the page table */\r
-        if (pages != NULL) {\r
-            kfree(pages);\r
-        }\r
+        #ifdef CONFIG_ARM\r
+        dmac_flush_range(MMU_Base, (MMU_Base + AllSize));\r
+        outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize));\r
+        #elif defined(CONFIG_ARM64)\r
+        __dma_flush_range(MMU_Base, (MMU_Base + AllSize));\r
+        #endif\r
 \r
-        return status;\r
+        rga2_mmu_buf_get(&rga2_mmu_buf, AllSize);\r
+        reg->MMU_len = AllSize;\r
 \r
+        return 0;\r
     }\r
     while(0);\r
 \r
-    /* Free the page table */\r
-    if (pages != NULL) {\r
-        kfree(pages);\r
-    }\r
-\r
-    /* Free mmu table */\r
-    if (MMU_Base != NULL) {\r
-        kfree(MMU_Base);\r
-    }\r
-\r
     return 0;\r
 }\r
 \r
 static int rga2_mmu_info_color_fill_mode(struct rga2_reg *reg, struct rga2_req *req)\r
 {\r
     int DstMemSize;\r
-    uint32_t DstStart;\r
+    unsigned long DstStart;\r
     struct page **pages = NULL;\r
     uint32_t AllSize;\r
     uint32_t *MMU_Base, *MMU_Base_phys;\r
     int ret;\r
     int status;\r
 \r
+    DstMemSize = 0;
     MMU_Base = NULL;\r
 \r
-    do\r
-    {\r
+    do {\r
         if(req->mmu_info.dst_mmu_flag & 1) {\r
             DstMemSize = rga2_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
                                         req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
@@ -717,14 +686,9 @@ static int rga2_mmu_info_color_fill_mode(struct rga2_reg *reg, struct rga2_req *
             }\r
         }\r
 \r
-        AllSize = (DstMemSize + 3) & (~3);\r
+        AllSize = (DstMemSize + 15) & (~15);\r
 \r
-        pages = kzalloc((AllSize)* sizeof(struct page *), GFP_KERNEL);\r
-        if(pages == NULL) {\r
-            pr_err("RGA2 MMU malloc pages mem failed\n");\r
-            status = RGA2_MALLOC_ERROR;\r
-            break;\r
-        }\r
+        pages = rga2_mmu_buf.pages;\r
 \r
         if(rga2_mmu_buf_get_try(&rga2_mmu_buf, AllSize)) {\r
            pr_err("RGA2 Get MMU mem failed\n");\r
@@ -737,9 +701,13 @@ static int rga2_mmu_info_color_fill_mode(struct rga2_reg *reg, struct rga2_req *
         MMU_Base = rga2_mmu_buf.buf_virtual + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
         mutex_unlock(&rga2_service.lock);\r
 \r
-        if (DstMemSize)\r
-        {\r
-            ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0], DstStart, DstMemSize);\r
+        if (DstMemSize) {\r
+            if (req->sg_dst) {\r
+                ret = rga2_MapION(req->sg_dst, &MMU_Base[0], DstMemSize);\r
+            }\r
+            else {\r
+                ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0], DstStart, DstMemSize);\r
+            }\r
             if (ret < 0) {\r
                 pr_err("rga2 map dst memory failed\n");\r
                 status = ret;\r
@@ -747,135 +715,97 @@ static int rga2_mmu_info_color_fill_mode(struct rga2_reg *reg, struct rga2_req *
             }\r
 \r
             /* change the buf address in req struct */\r
-            req->mmu_info.src0_base_addr = (((uint32_t)MMU_Base_phys)>>4);\r
+            req->mmu_info.dst_base_addr = ((unsigned long)MMU_Base_phys);\r
             req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK));\r
         }\r
 \r
         /* flush data to DDR */\r
+        #ifdef CONFIG_ARM\r
         dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));\r
+        #elif defined(CONFIG_ARM64)\r
+        __dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
+        #endif\r
 \r
-        rga2_mmu_buf_get_try(&rga2_mmu_buf, AllSize);\r
-\r
-        /* Free the page table */\r
-        if (pages != NULL)\r
-            kfree(pages);\r
+        rga2_mmu_buf_get(&rga2_mmu_buf, AllSize);\r
 \r
         return 0;\r
     }\r
     while(0);\r
 \r
-    if (pages != NULL)\r
-        kfree(pages);\r
-\r
-    if (MMU_Base != NULL)\r
-        kfree(MMU_Base);\r
-\r
     return status;\r
 }\r
 \r
 \r
 static int rga2_mmu_info_update_palette_table_mode(struct rga2_reg *reg, struct rga2_req *req)\r
 {\r
-    int SrcMemSize, CMDMemSize;\r
-    uint32_t SrcStart, CMDStart;\r
+    int SrcMemSize;\r
+    unsigned long SrcStart;\r
     struct page **pages = NULL;\r
-    uint32_t i;\r
     uint32_t AllSize;\r
-    uint32_t *MMU_Base, *MMU_p;\r
+    uint32_t *MMU_Base, *MMU_Base_phys;\r
     int ret, status;\r
 \r
     MMU_Base = NULL;\r
 \r
-    do\r
-    {\r
+    do {\r
         /* cal src buf mmu info */\r
-        SrcMemSize = rga2_mem_size_cal(req->src.yrgb_addr, req->src.vir_w * req->src.vir_h, &SrcStart);\r
+        SrcMemSize = rga2_mem_size_cal(req->pat.yrgb_addr, req->pat.vir_w * req->pat.vir_h, &SrcStart);\r
         if(SrcMemSize == 0) {\r
             return -EINVAL;\r
         }\r
 \r
-        /* cal cmd buf mmu info */\r
-        CMDMemSize = rga2_mem_size_cal((uint32_t)rga2_service.cmd_buff, RGA2_CMD_BUF_SIZE, &CMDStart);\r
-        if(CMDMemSize == 0) {\r
-            return -EINVAL;\r
-        }\r
+        SrcMemSize = (SrcMemSize + 15) & (~15);\r
+        AllSize = SrcMemSize;\r
 \r
-        AllSize = SrcMemSize + CMDMemSize;\r
-\r
-        pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
-        if(pages == NULL) {\r
-            pr_err("RGA MMU malloc pages mem failed\n");\r
+        if (rga2_mmu_buf_get_try(&rga2_mmu_buf, AllSize)) {\r
+            pr_err("RGA2 Get MMU mem failed\n");\r
             status = RGA2_MALLOC_ERROR;\r
             break;\r
         }\r
 \r
-        MMU_Base = kzalloc((AllSize + 1)* sizeof(uint32_t), GFP_KERNEL);\r
-        if(pages == NULL) {\r
-            pr_err("RGA MMU malloc MMU_Base point failed\n");\r
-            status = RGA2_MALLOC_ERROR;\r
-            break;\r
-        }\r
+        mutex_lock(&rga2_service.lock);\r
+        MMU_Base = rga2_mmu_buf.buf_virtual + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
+        MMU_Base_phys = rga2_mmu_buf.buf + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
+        mutex_unlock(&rga2_service.lock);\r
 \r
-        for(i=0; i<CMDMemSize; i++) {\r
-            MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i) << PAGE_SHIFT));\r
-        }\r
+        pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
 \r
-        if (req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
-        {\r
-            ret = rga2_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
+        if(SrcMemSize) {\r
+            ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize);\r
             if (ret < 0) {\r
-                pr_err("rga map src memory failed\n");\r
-                return -EINVAL;\r
+                pr_err("rga2 map palette memory failed\n");\r
+                status = ret;\r
+                break;\r
             }\r
-        }\r
-        else\r
-        {\r
-            MMU_p = MMU_Base + CMDMemSize;\r
 \r
-                for(i=0; i<SrcMemSize; i++)\r
-                {\r
-                    MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
-                }\r
+            /* change the buf address in req struct */\r
+            req->mmu_info.src0_base_addr = (((unsigned long)MMU_Base_phys));\r
+            req->pat.yrgb_addr = (req->pat.yrgb_addr & (~PAGE_MASK));\r
         }\r
 \r
-        /* zsq\r
-         * change the buf address in req struct\r
-         * for the reason of lie to MMU\r
-         */\r
-        req->mmu_info.src0_base_addr = (virt_to_phys(MMU_Base) >> 2);\r
-\r
-        req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
-\r
-        /*record the malloc buf for the cmd end to release*/\r
-        reg->MMU_base = MMU_Base;\r
-\r
         /* flush data to DDR */\r
+        #ifdef CONFIG_ARM\r
         dmac_flush_range(MMU_Base, (MMU_Base + AllSize));\r
-        outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize));\r
+        outer_flush_range(virt_to_phys(MMU_Base), virt_to_phys(MMU_Base + AllSize));\r
+        #elif defined(CONFIG_ARM64)\r
+        __dma_flush_range(MMU_Base, (MMU_Base + AllSize));\r
+        #endif\r
 \r
-        if (pages != NULL) {\r
-            /* Free the page table */\r
-            kfree(pages);\r
-        }\r
+        rga2_mmu_buf_get(&rga2_mmu_buf, AllSize);\r
+        reg->MMU_len = AllSize;\r
 \r
         return 0;\r
     }\r
     while(0);\r
 \r
-    if (pages != NULL)\r
-        kfree(pages);\r
-\r
-    if (MMU_Base != NULL)\r
-        kfree(MMU_Base);\r
-\r
     return status;\r
 }\r
 \r
 static int rga2_mmu_info_update_patten_buff_mode(struct rga2_reg *reg, struct rga2_req *req)\r
 {\r
     int SrcMemSize, CMDMemSize;\r
-    uint32_t SrcStart, CMDStart;\r
+    unsigned long SrcStart, CMDStart;\r
     struct page **pages = NULL;\r
     uint32_t i;\r
     uint32_t AllSize;\r
@@ -884,9 +814,7 @@ static int rga2_mmu_info_update_patten_buff_mode(struct rga2_reg *reg, struct rg
 \r
     MMU_Base = MMU_p = 0;\r
 \r
-    do\r
-    {\r
-\r
+    do {\r
         /* cal src buf mmu info */\r
         SrcMemSize = rga2_mem_size_cal(req->pat.yrgb_addr, req->pat.act_w * req->pat.act_h * 4, &SrcStart);\r
         if(SrcMemSize == 0) {\r
@@ -894,26 +822,16 @@ static int rga2_mmu_info_update_patten_buff_mode(struct rga2_reg *reg, struct rg
         }\r
 \r
         /* cal cmd buf mmu info */\r
-        CMDMemSize = rga2_mem_size_cal((uint32_t)rga2_service.cmd_buff, RGA2_CMD_BUF_SIZE, &CMDStart);\r
+        CMDMemSize = rga2_mem_size_cal((unsigned long)rga2_service.cmd_buff, RGA2_CMD_BUF_SIZE, &CMDStart);\r
         if(CMDMemSize == 0) {\r
             return -EINVAL;\r
         }\r
 \r
         AllSize = SrcMemSize + CMDMemSize;\r
 \r
-        pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
-        if(pages == NULL) {\r
-            pr_err("RGA MMU malloc pages mem failed\n");\r
-            status = RGA2_MALLOC_ERROR;\r
-            break;\r
-        }\r
+        pages = rga2_mmu_buf.pages;\r
 \r
         MMU_Base = kzalloc(AllSize * sizeof(uint32_t), GFP_KERNEL);\r
-        if(pages == NULL) {\r
-            pr_err("RGA MMU malloc MMU_Base point failed\n");\r
-            status = RGA2_MALLOC_ERROR;\r
-            break;\r
-        }\r
 \r
         for(i=0; i<CMDMemSize; i++) {\r
             MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i) << PAGE_SHIFT));\r
@@ -950,25 +868,18 @@ static int rga2_mmu_info_update_patten_buff_mode(struct rga2_reg *reg, struct rg
         reg->MMU_base = MMU_Base;\r
 \r
         /* flush data to DDR */\r
+        #ifdef CONFIG_ARM\r
         dmac_flush_range(MMU_Base, (MMU_Base + AllSize));\r
         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize));\r
-\r
-        if (pages != NULL) {\r
-            /* Free the page table */\r
-            kfree(pages);\r
-        }\r
+        #elif defined(CONFIG_ARM64)\r
+        __dma_flush_range(MMU_Base, (MMU_Base + AllSize));\r
+        #endif\r
 \r
         return 0;\r
 \r
     }\r
     while(0);\r
 \r
-    if (pages != NULL)\r
-        kfree(pages);\r
-\r
-    if (MMU_Base != NULL)\r
-        kfree(MMU_Base);\r
-\r
     return status;\r
 }\r
 \r