remove rga driver mmu buf malloc to prevent crash
authorzsq <zsq@rock-chips.com>
Mon, 15 Dec 2014 09:24:31 +0000 (17:24 +0800)
committerzsq <zsq@rock-chips.com>
Mon, 15 Dec 2014 09:24:31 +0000 (17:24 +0800)
drivers/video/rockchip/rga/rga.h
drivers/video/rockchip/rga/rga_drv.c
drivers/video/rockchip/rga/rga_mmu_info.c

index bd121895cc4e76b9f105fe263210a967f3176c42..833837fe7a45284dcdf88e320465b9aea5838e50 100755 (executable)
@@ -332,6 +332,16 @@ typedef struct TILE_INFO
 }\r
 TILE_INFO;\r
 \r
+struct rga_mmu_buf_t {\r
+    int32_t front;\r
+    int32_t back;\r
+    int32_t size;\r
+    int32_t curr;\r
+    unsigned int *buf;\r
+    unsigned int *buf_virtual;\r
+\r
+    struct page **pages;\r
+};\r
 \r
 /**\r
  * struct for process session which connect to rga\r
@@ -361,6 +371,7 @@ struct rga_reg {
     uint32_t  cmd_reg[RGA_REG_CMD_LEN];\r
 \r
     uint32_t *MMU_base;\r
+    uint32_t MMU_len;\r
     //atomic_t int_enable;\r
 \r
     //struct rga_req      req;\r
index 7664cafa1e6d551088ac5aad81f4afa700f3a05c..fb2f82586bab36b126b36b344023e754eafa8df5 100755 (executable)
@@ -55,7 +55,7 @@
 \r
 #define RGA_TEST_CASE 0\r
 \r
-#define RGA_TEST 0\r
+#define RGA_TEST 1\r
 #define RGA_TEST_TIME 0\r
 #define RGA_TEST_FLUSH_TIME 0\r
 #define RGA_INFO_BUS_ERROR 1\r
@@ -108,6 +108,8 @@ struct rga_drvdata {
 \r
 static struct rga_drvdata *drvdata;\r
 rga_service_info rga_service;\r
+struct rga_mmu_buf_t rga_mmu_buf;\r
+\r
 \r
 #if defined(CONFIG_ION_ROCKCHIP)\r
 extern struct ion_client *rockchip_ion_client_create(const char * name);\r
@@ -120,7 +122,7 @@ static void rga_try_set_reg(void);
 \r
 \r
 /* Logging */\r
-#define RGA_DEBUG 0\r
+#define RGA_DEBUG 1\r
 #if RGA_DEBUG\r
 #define DBG(format, args...) printk(KERN_DEBUG "%s: " format, DRIVER_NAME, ## args)\r
 #define ERR(format, args...) printk(KERN_ERR "%s: " format, DRIVER_NAME, ## args)\r
@@ -700,11 +702,14 @@ static void rga_del_running_list(void)
     {\r
         reg = list_entry(rga_service.running.next, struct rga_reg, status_link);\r
 \r
-        if(reg->MMU_base != NULL)\r
+        if(reg->MMU_len != 0)\r
         {\r
-            kfree(reg->MMU_base);\r
-            reg->MMU_base = NULL;\r
+            if (rga_mmu_buf.back + reg->MMU_len > 2*rga_mmu_buf.size)\r
+                rga_mmu_buf.back = reg->MMU_len + rga_mmu_buf.size;\r
+            else\r
+                rga_mmu_buf.back += reg->MMU_len;\r
         }\r
+\r
         atomic_sub(1, &reg->session->task_running);\r
         atomic_sub(1, &rga_service.total_running);\r
 \r
@@ -1339,27 +1344,32 @@ static int __init rga_init(void)
 \r
     /* malloc pre scale mid buf mmu table */\r
     mmu_buf = kzalloc(1024*8, GFP_KERNEL);\r
-    if(mmu_buf == NULL)\r
-    {\r
+    if(mmu_buf == NULL) {\r
         printk(KERN_ERR "RGA get Pre Scale buff failed. \n");\r
         return -1;\r
     }\r
 \r
     /* malloc 4 M buf */\r
-    for(i=0; i<1024; i++)\r
-    {\r
+    for(i=0; i<1024; i++) {\r
         buf_p = (uint32_t *)__get_free_page(GFP_KERNEL|__GFP_ZERO);\r
-        if(buf_p == NULL)\r
-        {\r
+        if(buf_p == NULL) {\r
             printk(KERN_ERR "RGA init pre scale buf falied\n");\r
             return -ENOMEM;\r
         }\r
-\r
         mmu_buf[i] = virt_to_phys((void *)((uint32_t)buf_p));\r
     }\r
 \r
     rga_service.pre_scale_buf = (uint32_t *)mmu_buf;\r
 \r
+    buf_p = kmalloc(1024*256, GFP_KERNEL);\r
+    rga_mmu_buf.buf_virtual = buf_p;\r
+    rga_mmu_buf.buf = (uint32_t *)virt_to_phys((void *)((uint32_t)buf_p));\r
+    rga_mmu_buf.front = 0;\r
+    rga_mmu_buf.back = 64*1024;\r
+    rga_mmu_buf.size = 64*1024;\r
+\r
+    rga_mmu_buf.pages = kmalloc((32768)* sizeof(struct page *), GFP_KERNEL);\r
+\r
        if ((ret = platform_driver_register(&rga_driver)) != 0)\r
        {\r
         printk(KERN_ERR "Platform device register failed (%d).\n", ret);\r
@@ -1413,6 +1423,13 @@ static void __exit rga_exit(void)
     if(rga_service.pre_scale_buf != NULL) {\r
         kfree((uint8_t *)rga_service.pre_scale_buf);\r
     }\r
+\r
+    if (rga_mmu_buf.buf_virtual)\r
+        kfree(rga_mmu_buf.buf_virtual);\r
+\r
+    if (rga_mmu_buf.pages)\r
+        kfree(rga_mmu_buf.pages);\r
+\r
        platform_driver_unregister(&rga_driver);\r
 }\r
 \r
index f2e82370b65ee0cb8e42a2a3755c2aed5a0f7601..56f2110bed2c41ffe7a3adad553c4635bb47d494 100755 (executable)
 #include <asm/atomic.h>\r
 #include <asm/cacheflush.h>\r
 #include "rga_mmu_info.h"\r
+#include <linux/delay.h>\r
 \r
 extern rga_service_info rga_service;\r
-//extern int mmu_buff_temp[1024];\r
+extern struct rga_mmu_buf_t rga_mmu_buf;\r
 \r
 #define KERNEL_SPACE_VALID    0xc0000000\r
 \r
-#define V7_VATOPA_SUCESS_MASK  (0x1)\r
-#define V7_VATOPA_GET_PADDR(X) (X & 0xFFFFF000)\r
-#define V7_VATOPA_GET_INER(X)          ((X>>4) & 7)\r
-#define V7_VATOPA_GET_OUTER(X)         ((X>>2) & 3)\r
-#define V7_VATOPA_GET_SH(X)            ((X>>7) & 1)\r
-#define V7_VATOPA_GET_NS(X)            ((X>>9) & 1)\r
-#define V7_VATOPA_GET_SS(X)            ((X>>1) & 1)\r
+static int rga_mmu_buf_get(struct rga_mmu_buf_t *t, uint32_t size)\r
+{\r
+    mutex_lock(&rga_service.lock);\r
+    t->front += size;\r
+    mutex_unlock(&rga_service.lock);\r
+\r
+    return 0;\r
+}\r
 \r
-#if 0\r
-static unsigned int armv7_va_to_pa(unsigned int v_addr)\r
+static int rga_mmu_buf_get_try(struct rga_mmu_buf_t *t, uint32_t size)\r
 {\r
-       unsigned int p_addr;\r
-       __asm__ volatile (      "mcr p15, 0, %1, c7, c8, 0\n"\r
-                                               "isb\n"\r
-                                               "dsb\n"\r
-                                               "mrc p15, 0, %0, c7, c4, 0\n"\r
-                                               : "=r" (p_addr)\r
-                                               : "r" (v_addr)\r
-                                               : "cc");\r
-\r
-       if (p_addr & V7_VATOPA_SUCESS_MASK)\r
-               return 0xFFFFFFFF;\r
-       else\r
-               return (V7_VATOPA_GET_SS(p_addr) ? 0xFFFFFFFF : V7_VATOPA_GET_PADDR(p_addr));\r
+    mutex_lock(&rga_service.lock);\r
+    if((t->back - t->front) > t->size) {\r
+        if(t->front + size > t->back - t->size)\r
+            return -1;\r
+    }\r
+    else {\r
+        if((t->front + size) > t->back)\r
+            return -1;\r
+\r
+        if(t->front + size > t->size) {\r
+            if (size > (t->back - t->size)) {\r
+                return -1;\r
+            }\r
+            t->front = 0;\r
+        }\r
+    }\r
+    mutex_unlock(&rga_service.lock);\r
+\r
+    return 0;\r
 }\r
-#endif\r
 \r
 static int rga_mem_size_cal(uint32_t Mem, uint32_t MemSize, uint32_t *StartAddr)\r
 {\r
@@ -297,7 +303,6 @@ static int rga_MapUserMemory(struct page **pages,
 \r
                 if (vma)//&& (vma->vm_flags & VM_PFNMAP) )\r
                 {\r
-                    #if 1\r
                     do\r
                     {\r
                         pte_t       * pte;\r
@@ -343,28 +348,6 @@ static int rga_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
                 }\r
                 else\r
@@ -399,31 +382,80 @@ static int rga_MapUserMemory(struct page **pages,
 \r
 static int rga_MapION(struct sg_table *sg,\r
                                uint32_t *Memory,\r
-                               int32_t  pageCount)\r
+                               int32_t  pageCount,\r
+                               uint32_t offset)\r
 {\r
     uint32_t i;\r
     uint32_t status;\r
     uint32_t Address;\r
     uint32_t mapped_size = 0;\r
-    uint32_t len;\r
+    uint32_t len = 0;\r
     struct scatterlist *sgl = sg->sgl;\r
     uint32_t sg_num = 0;\r
 \r
     status = 0;\r
     Address = 0;\r
-    do {\r
+    offset = offset >> PAGE_SHIFT;\r
+    if (offset != 0) {\r
+        do {\r
+            len += (sg_dma_len(sgl) >> PAGE_SHIFT);\r
+               if (len == offset) {\r
+                   sg_num += 1;\r
+                   break;\r
+           }\r
+           else {\r
+                if (len > offset)\r
+                     break;\r
+           }\r
+                sg_num += 1;\r
+        }\r
+        while((sgl = sg_next(sgl)) && (mapped_size < pageCount) && (sg_num < sg->nents));\r
+\r
+        sgl = sg->sgl;\r
+       len = 0;\r
+        do {\r
+            len += (sg_dma_len(sgl) >> PAGE_SHIFT);\r
+            sgl = sg_next(sgl);\r
+        }\r
+        while(--sg_num);\r
+\r
+        offset -= len;\r
+\r
         len = sg_dma_len(sgl) >> PAGE_SHIFT;\r
         Address = sg_phys(sgl);\r
+       Address += offset;\r
 \r
-        for(i=0; i<len; i++) {\r
-            Memory[mapped_size + i] = Address + (i << PAGE_SHIFT);\r
+        for(i=offset; i<len; i++) {\r
+             Memory[i - offset] = Address + (i << PAGE_SHIFT);\r
         }\r
+        mapped_size += (len - offset);\r
+        sg_num = 1;\r
+        sgl = sg_next(sgl);\r
+        do {\r
+            len = sg_dma_len(sgl) >> PAGE_SHIFT;\r
+            Address = sg_phys(sgl);\r
 \r
-        mapped_size += len;\r
-        sg_num += 1;\r
-    }\r
-    while((sgl = sg_next(sgl)) && (mapped_size < pageCount) && (sg_num < sg->nents));\r
+            for(i=0; i<len; i++) {\r
+                Memory[mapped_size + i] = Address + (i << PAGE_SHIFT);\r
+            }\r
 \r
+            mapped_size += len;\r
+            sg_num += 1;\r
+        }\r
+        while((sgl = sg_next(sgl)) && (mapped_size < pageCount) && (sg_num < sg->nents));\r
+    }\r
+    else {\r
+        do {\r
+            len = sg_dma_len(sgl) >> PAGE_SHIFT;\r
+            Address = sg_phys(sgl);\r
+            for(i=0; i<len; i++) {\r
+                Memory[mapped_size + i] = Address + (i << PAGE_SHIFT);\r
+            }\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
@@ -434,7 +466,7 @@ static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req)
     uint32_t SrcStart, DstStart;\r
     uint32_t i;\r
     uint32_t AllSize;\r
-    uint32_t *MMU_Base, *MMU_p;\r
+    uint32_t *MMU_Base, *MMU_p, *MMU_Base_phys;\r
     int ret;\r
     int status;\r
     uint32_t uv_size, v_size;\r
@@ -446,10 +478,8 @@ static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req)
     SrcMemSize = 0;\r
     DstMemSize = 0;\r
 \r
-    do\r
-    {\r
+    do {\r
         /* cal src buf mmu info */\r
-\r
         SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr,\r
                                         req->src.format, req->src.vir_w, req->src.act_h + req->src.y_offset,\r
                                         &SrcStart);\r
@@ -457,38 +487,35 @@ static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req)
             return -EINVAL;\r
         }\r
 \r
-\r
         /* cal dst buf mmu info */\r
 \r
         DstMemSize = rga_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
+        if(DstMemSize == 0)\r
             return -EINVAL;\r
-        }\r
 \r
         /* Cal out the needed mem size */\r
         SrcMemSize = (SrcMemSize + 15) & (~15);\r
         DstMemSize = (DstMemSize + 15) & (~15);\r
         AllSize = SrcMemSize + DstMemSize;\r
 \r
-        pages = kzalloc((AllSize + 1)* sizeof(struct page *), GFP_KERNEL);\r
-        if(pages == NULL) {\r
-            pr_err("RGA MMU malloc pages mem failed\n");\r
+        if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) {\r
+            pr_err("RGA Get MMU mem failed\n");\r
             status = RGA_MALLOC_ERROR;\r
             break;\r
         }\r
 \r
-        MMU_Base = kzalloc((AllSize + 1) * sizeof(uint32_t), GFP_KERNEL);\r
-        if(MMU_Base == NULL) {\r
-            pr_err("RGA MMU malloc MMU_Base point failed\n");\r
-            status = RGA_MALLOC_ERROR;\r
-            break;\r
-        }\r
+        mutex_lock(&rga_service.lock);\r
+        MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1));\r
+        MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1));\r
+        mutex_unlock(&rga_service.lock);\r
+\r
+        pages = rga_mmu_buf.pages;\r
 \r
         if((req->mmu_info.mmu_flag >> 8) & 1) {\r
             if (req->sg_src) {\r
-                ret = rga_MapION(req->sg_src, &MMU_Base[0], SrcMemSize);\r
+                ret = rga_MapION(req->sg_src, &MMU_Base[0], SrcMemSize, req->line_draw_info.flag);\r
             }\r
             else {\r
                 ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize);\r
@@ -514,7 +541,7 @@ static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req)
 \r
         if ((req->mmu_info.mmu_flag >> 10) & 1) {\r
             if (req->sg_dst) {\r
-                ret = rga_MapION(req->sg_dst, &MMU_Base[SrcMemSize], DstMemSize);\r
+                ret = rga_MapION(req->sg_dst, &MMU_Base[SrcMemSize], DstMemSize, req->line_draw_info.line_width);\r
             }\r
             else {\r
                 ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize);\r
@@ -531,13 +558,13 @@ static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req)
                 MMU_p[i] = (uint32_t)((DstStart + i) << PAGE_SHIFT);\r
         }\r
 \r
-        MMU_Base[AllSize] = MMU_Base[AllSize - 1];\r
+        MMU_Base[AllSize] = MMU_Base[AllSize-1];\r
 \r
         /* zsq\r
          * change the buf address in req struct\r
          */\r
 \r
-        req->mmu_info.base_addr = (virt_to_phys(MMU_Base)>>2);\r
+        req->mmu_info.base_addr = (uint32_t)MMU_Base_phys >> 2;\r
 \r
         uv_size = (req->src.uv_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
         v_size = (req->src.v_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
@@ -551,35 +578,19 @@ static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req)
         req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | (SrcMemSize << PAGE_SHIFT);\r
         req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((SrcMemSize + uv_size) << 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
         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
+        outer_flush_range(virt_to_phys(MMU_Base), virt_to_phys(MMU_Base + AllSize + 1));\r
 \r
-        status = 0;\r
+        rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16);\r
+        reg->MMU_len = AllSize + 16;\r
 \r
-        /* Free the page table */\r
-        if (pages != NULL) {\r
-            kfree(pages);\r
-        }\r
+        status = 0;\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
@@ -590,7 +601,7 @@ static int rga_mmu_info_color_palette_mode(struct rga_reg *reg, struct rga_req *
     struct page **pages = NULL;\r
     uint32_t i;\r
     uint32_t AllSize;\r
-    uint32_t *MMU_Base = NULL;\r
+    uint32_t *MMU_Base = NULL, *MMU_Base_phys = NULL;\r
     uint32_t *MMU_p;\r
     int ret, status;\r
     uint32_t stride;\r
@@ -603,9 +614,7 @@ static int rga_mmu_info_color_palette_mode(struct rga_reg *reg, struct rga_req *
     byte_num = sw >> shift;\r
     stride = (byte_num + 3) & (~3);\r
 \r
-    do\r
-    {\r
-\r
+    do {\r
         SrcMemSize = rga_mem_size_cal(req->src.yrgb_addr, stride, &SrcStart);\r
         if(SrcMemSize == 0) {\r
             return -EINVAL;\r
@@ -623,39 +632,40 @@ static int rga_mmu_info_color_palette_mode(struct rga_reg *reg, struct rga_req *
             return -EINVAL;\r
         }\r
 \r
-        AllSize = SrcMemSize + DstMemSize + CMDMemSize;\r
+        SrcMemSize = (SrcMemSize + 15) & (~15);\r
+        DstMemSize = (DstMemSize + 15) & (~15);\r
+        CMDMemSize = (CMDMemSize + 15) & (~15);\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
-            return -EINVAL;\r
-        }\r
+        AllSize = SrcMemSize + DstMemSize + CMDMemSize;\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
+        if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) {\r
+            pr_err("RGA Get MMU mem failed\n");\r
+            status = RGA_MALLOC_ERROR;\r
             break;\r
         }\r
 \r
+        mutex_lock(&rga_service.lock);\r
+        MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1));\r
+        MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1));\r
+        mutex_unlock(&rga_service.lock);\r
+\r
+        pages = rga_mmu_buf.pages;\r
+\r
         /* map CMD addr */\r
-        for(i=0; i<CMDMemSize; i++)\r
-        {\r
+        for(i=0; i<CMDMemSize; i++) {\r
             MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i)<<PAGE_SHIFT));\r
         }\r
 \r
         /* map src addr */\r
-        if (req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
-        {\r
+        if (req->src.yrgb_addr < KERNEL_SPACE_VALID) {\r
             ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
-            if (ret < 0)\r
-            {\r
+            if (ret < 0) {\r
                 pr_err("rga map src memory failed\n");\r
                 status = ret;\r
                 break;\r
             }\r
         }\r
-        else\r
-        {\r
+        else {\r
             MMU_p = MMU_Base + CMDMemSize;\r
 \r
             for(i=0; i<SrcMemSize; i++)\r
@@ -665,24 +675,18 @@ static int rga_mmu_info_color_palette_mode(struct rga_reg *reg, struct rga_req *
         }\r
 \r
         /* map dst addr */\r
-        if (req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
-        {\r
+        if (req->src.yrgb_addr < KERNEL_SPACE_VALID) {\r
             ret = rga_MapUserMemory(&pages[CMDMemSize + SrcMemSize], &MMU_Base[CMDMemSize + SrcMemSize], DstStart, DstMemSize);\r
-            if (ret < 0)\r
-            {\r
+            if (ret < 0) {\r
                 pr_err("rga map dst memory failed\n");\r
                 status = ret;\r
                 break;\r
             }\r
         }\r
-        else\r
-        {\r
+        else {\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
         }\r
 \r
 \r
@@ -694,7 +698,6 @@ static int rga_mmu_info_color_palette_mode(struct rga_reg *reg, struct rga_req *
         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
@@ -702,26 +705,14 @@ static int rga_mmu_info_color_palette_mode(struct rga_reg *reg, struct rga_req *
         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
+        rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16);\r
+        reg->MMU_len = AllSize + 16;\r
 \r
         return status;\r
 \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
@@ -732,7 +723,7 @@ static int rga_mmu_info_color_fill_mode(struct rga_reg *reg, struct rga_req *req
     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_p, *MMU_Base_phys;\r
     int ret;\r
     int status;\r
 \r
@@ -747,25 +738,24 @@ static int rga_mmu_info_color_fill_mode(struct rga_reg *reg, struct rga_req *req
             return -EINVAL;\r
         }\r
 \r
-        AllSize = DstMemSize;\r
+        AllSize = (DstMemSize + 15) & (~15);\r
 \r
-        pages = kzalloc((AllSize + 1)* sizeof(struct page *), GFP_KERNEL);\r
-        if(pages == NULL) {\r
-            pr_err("RGA MMU malloc pages mem failed\n");\r
-            status = RGA_MALLOC_ERROR;\r
-            break;\r
-        }\r
+        pages = rga_mmu_buf.pages;\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
+        if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) {\r
+            pr_err("RGA Get MMU mem failed\n");\r
             status = RGA_MALLOC_ERROR;\r
             break;\r
         }\r
 \r
+        mutex_lock(&rga_service.lock);\r
+        MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1));\r
+        MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1));\r
+        mutex_unlock(&rga_service.lock);\r
+\r
         if (req->dst.yrgb_addr < KERNEL_SPACE_VALID) {\r
             if (req->sg_dst) {\r
-                ret = rga_MapION(req->sg_dst, &MMU_Base[0], DstMemSize);\r
+                ret = rga_MapION(req->sg_dst, &MMU_Base[0], DstMemSize, req->line_draw_info.line_width);\r
             }\r
             else {\r
                 ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], DstStart, DstMemSize);\r
@@ -788,7 +778,7 @@ static int rga_mmu_info_color_fill_mode(struct rga_reg *reg, struct rga_req *req
          * change the buf address in req struct\r
          */\r
 \r
-        req->mmu_info.base_addr = (virt_to_phys(MMU_Base)>>2);\r
+        req->mmu_info.base_addr = ((uint32_t)(MMU_Base_phys)>>2);\r
         req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK));\r
 \r
         /*record the malloc buf for the cmd end to release*/\r
@@ -798,20 +788,13 @@ static int rga_mmu_info_color_fill_mode(struct rga_reg *reg, struct rga_req *req
         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
+        rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16);\r
+        reg->MMU_len = AllSize + 16;\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
@@ -1052,7 +1035,7 @@ static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req)
     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_p, *MMU_Base_phys;\r
     int ret;\r
     int status;\r
     uint32_t uv_size, v_size;\r
@@ -1076,30 +1059,28 @@ static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req)
             return -EINVAL;\r
         }\r
 \r
+           SrcMemSize = (SrcMemSize + 15) & (~15);\r
+           DstMemSize = (DstMemSize + 15) & (~15);\r
+\r
         AllSize = SrcMemSize + DstMemSize;\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 = RGA_MALLOC_ERROR;\r
-            break;\r
-        }\r
+        pages = rga_mmu_buf.pages;\r
 \r
-        /*\r
-         * Allocate MMU Index mem\r
-         * This mem release in run_to_done fun\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
+        if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) {\r
+            pr_err("RGA Get MMU mem failed\n");\r
             status = RGA_MALLOC_ERROR;\r
             break;\r
         }\r
 \r
+        mutex_lock(&rga_service.lock);\r
+        MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1));\r
+        MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1));\r
+        mutex_unlock(&rga_service.lock);\r
+\r
         /* map src pages */\r
         if ((req->mmu_info.mmu_flag >> 8) & 1) {\r
             if (req->sg_src) {\r
-                ret = rga_MapION(req->sg_src, &MMU_Base[0], SrcMemSize);\r
+                ret = rga_MapION(req->sg_src, &MMU_Base[0], SrcMemSize,req->line_draw_info.flag);\r
             }\r
             else {\r
                 ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize);\r
@@ -1119,7 +1100,7 @@ static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req)
 \r
         if((req->mmu_info.mmu_flag >> 10) & 1) {\r
             if (req->sg_dst) {\r
-                ret = rga_MapION(req->sg_dst, &MMU_Base[SrcMemSize], DstMemSize);\r
+                ret = rga_MapION(req->sg_dst, &MMU_Base[SrcMemSize], DstMemSize, req->line_draw_info.line_width);\r
             }\r
             else {\r
                 ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize);\r
@@ -1145,14 +1126,14 @@ static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req)
             }\r
         }\r
 \r
-        MMU_Base[AllSize] = MMU_Base[AllSize - 1];\r
+        MMU_Base[AllSize] = MMU_Base[AllSize];\r
 \r
         /* zsq\r
          * change the buf address in req struct\r
          * for the reason of lie to MMU\r
          */\r
 \r
-        req->mmu_info.base_addr = (virt_to_phys(MMU_Base)>>2);\r
+        req->mmu_info.base_addr = ((uint32_t)(MMU_Base_phys)>>2);\r
 \r
         uv_size = (req->src.uv_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
         v_size = (req->src.v_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
@@ -1175,22 +1156,13 @@ static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req)
         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
-        {\r
-            kfree(pages);\r
-        }\r
+           rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16);\r
+        reg->MMU_len = AllSize + 16;\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