Merge remote-tracking branch 'stable/linux-3.0.y' into develop-3.0
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / rga / rga_mmu_info.c
1 \r
2 \r
3 #include <linux/version.h>\r
4 #include <linux/init.h>\r
5 #include <linux/module.h>\r
6 #include <linux/fs.h>\r
7 #include <linux/sched.h>\r
8 #include <linux/signal.h>\r
9 #include <linux/pagemap.h>\r
10 #include <linux/seq_file.h>\r
11 #include <linux/mm.h>\r
12 #include <linux/mman.h>\r
13 #include <linux/sched.h>\r
14 #include <linux/slab.h>\r
15 #include <linux/memory.h>\r
16 #include <linux/dma-mapping.h>\r
17 #include <asm/memory.h>\r
18 #include <asm/atomic.h>\r
19 #include <asm/cacheflush.h>\r
20 #include "rga_mmu_info.h"\r
21 \r
22 extern rga_service_info rga_service;\r
23 //extern int mmu_buff_temp[1024];\r
24 \r
25 #define KERNEL_SPACE_VALID    0xc0000000\r
26 \r
27 #define V7_VATOPA_SUCESS_MASK   (0x1)\r
28 #define V7_VATOPA_GET_PADDR(X)  (X & 0xFFFFF000)\r
29 #define V7_VATOPA_GET_INER(X)           ((X>>4) & 7)\r
30 #define V7_VATOPA_GET_OUTER(X)          ((X>>2) & 3)\r
31 #define V7_VATOPA_GET_SH(X)             ((X>>7) & 1)\r
32 #define V7_VATOPA_GET_NS(X)             ((X>>9) & 1)\r
33 #define V7_VATOPA_GET_SS(X)             ((X>>1) & 1)\r
34 \r
35 #if 0\r
36 static unsigned int armv7_va_to_pa(unsigned int v_addr)\r
37 {\r
38         unsigned int p_addr;\r
39         __asm__ volatile (      "mcr p15, 0, %1, c7, c8, 0\n" \r
40                                                 "isb\n"\r
41                                                 "dsb\n"\r
42                                                 "mrc p15, 0, %0, c7, c4, 0\n"\r
43                                                 : "=r" (p_addr)\r
44                                                 : "r" (v_addr)\r
45                                                 : "cc");\r
46 \r
47         if (p_addr & V7_VATOPA_SUCESS_MASK)\r
48                 return 0xFFFFFFFF;\r
49         else\r
50                 return (V7_VATOPA_GET_SS(p_addr) ? 0xFFFFFFFF : V7_VATOPA_GET_PADDR(p_addr));\r
51 }\r
52 #endif\r
53 \r
54 static int rga_mem_size_cal(uint32_t Mem, uint32_t MemSize, uint32_t *StartAddr) \r
55 {\r
56     uint32_t start, end;\r
57     uint32_t pageCount;\r
58 \r
59     end = (Mem + (MemSize + PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
60     start = Mem >> PAGE_SHIFT;\r
61     pageCount = end - start;\r
62     *StartAddr = start;\r
63     return pageCount;    \r
64 }\r
65 \r
66 static int rga_buf_size_cal(uint32_t yrgb_addr, uint32_t uv_addr, uint32_t v_addr, \r
67                                         int format, uint32_t w, uint32_t h, uint32_t *StartAddr ) \r
68 {\r
69     uint32_t size_yrgb = 0;\r
70     uint32_t size_uv = 0;\r
71     uint32_t size_v = 0;\r
72     uint32_t stride = 0;\r
73     uint32_t start, end;\r
74     uint32_t pageCount;\r
75        \r
76     switch(format)\r
77     {\r
78         case RK_FORMAT_RGBA_8888 :\r
79             stride = (w * 4 + 3) & (~3);\r
80             size_yrgb = stride*h;\r
81             end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
82             start = yrgb_addr >> PAGE_SHIFT;\r
83             pageCount = end - start;            \r
84             break;\r
85         case RK_FORMAT_RGBX_8888 :\r
86             stride = (w * 4 + 3) & (~3);\r
87             size_yrgb = stride*h;\r
88             end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
89             start = yrgb_addr >> PAGE_SHIFT;\r
90             pageCount = end - start;\r
91             break;\r
92         case RK_FORMAT_RGB_888 :\r
93             stride = (w * 3 + 3) & (~3);\r
94             size_yrgb = stride*h;\r
95             end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
96             start = yrgb_addr >> PAGE_SHIFT;\r
97             pageCount = end - start;\r
98             break;\r
99         case RK_FORMAT_BGRA_8888 :\r
100             size_yrgb = w*h*4;\r
101             end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
102             start = yrgb_addr >> PAGE_SHIFT;\r
103             pageCount = end - start;\r
104             break;\r
105         case RK_FORMAT_RGB_565 :\r
106             stride = (w*2 + 3) & (~3);            \r
107             size_yrgb = stride * h;\r
108             end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
109             start = yrgb_addr >> PAGE_SHIFT;\r
110             pageCount = end - start;\r
111             break;\r
112         case RK_FORMAT_RGBA_5551 :\r
113             stride = (w*2 + 3) & (~3);            \r
114             size_yrgb = stride * h;\r
115             end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
116             start = yrgb_addr >> PAGE_SHIFT;\r
117             pageCount = end - start;\r
118             break;\r
119         case RK_FORMAT_RGBA_4444 :\r
120             stride = (w*2 + 3) & (~3);            \r
121             size_yrgb = stride * h;\r
122             end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
123             start = yrgb_addr >> PAGE_SHIFT;\r
124             pageCount = end - start;\r
125             break;\r
126         case RK_FORMAT_BGR_888 :\r
127             stride = (w*3 + 3) & (~3);            \r
128             size_yrgb = stride * h;\r
129             end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
130             start = yrgb_addr >> PAGE_SHIFT;\r
131             pageCount = end - start;\r
132             break;\r
133 \r
134         /* YUV FORMAT */\r
135         case RK_FORMAT_YCbCr_422_SP :\r
136             stride = (w + 3) & (~3);\r
137             size_yrgb = stride * h;\r
138             size_uv = stride * h;\r
139             start = MIN(yrgb_addr, uv_addr);\r
140             start >>= PAGE_SHIFT; \r
141             end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv));\r
142             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
143             pageCount = end - start;            \r
144             break;\r
145         case RK_FORMAT_YCbCr_422_P :\r
146             stride = (w + 3) & (~3);\r
147             size_yrgb = stride * h;\r
148             size_uv = ((stride >> 1) * h);\r
149             size_v = ((stride >> 1) * h);\r
150             start = MIN(MIN(yrgb_addr, uv_addr), v_addr);\r
151             start = start >> PAGE_SHIFT; \r
152             end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v));\r
153             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
154             pageCount = end - start;            \r
155             break;\r
156         case RK_FORMAT_YCbCr_420_SP :\r
157             stride = (w + 3) & (~3);\r
158             size_yrgb = stride * h;\r
159             size_uv = (stride * (h >> 1));            \r
160             start = MIN(yrgb_addr, uv_addr);\r
161             start >>= PAGE_SHIFT; \r
162             end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv));\r
163             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
164             pageCount = end - start;\r
165             break;\r
166         case RK_FORMAT_YCbCr_420_P :\r
167             stride = (w + 3) & (~3);\r
168             size_yrgb = stride * h;\r
169             size_uv = ((stride >> 1) * (h >> 1));\r
170             size_v = ((stride >> 1) * (h >> 1));\r
171             start = MIN(MIN(yrgb_addr, uv_addr), v_addr);\r
172             start >>= PAGE_SHIFT; \r
173             end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v));\r
174             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
175             pageCount = end - start;            \r
176             break;\r
177 \r
178         case RK_FORMAT_YCrCb_422_SP :\r
179             stride = (w + 3) & (~3);\r
180             size_yrgb = stride * h;\r
181             size_uv = stride * h;\r
182             start = MIN(yrgb_addr, uv_addr);\r
183             start >>= PAGE_SHIFT; \r
184             end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv));\r
185             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
186             pageCount = end - start;\r
187             break;\r
188         case RK_FORMAT_YCrCb_422_P :\r
189             stride = (w + 3) & (~3);\r
190             size_yrgb = stride * h;\r
191             size_uv = ((stride >> 1) * h);\r
192             size_v = ((stride >> 1) * h);\r
193             start = MIN(MIN(yrgb_addr, uv_addr), v_addr);\r
194             start >>= PAGE_SHIFT; \r
195             end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v));\r
196             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
197             pageCount = end - start;\r
198             break;\r
199             \r
200         case RK_FORMAT_YCrCb_420_SP :\r
201             stride = (w + 3) & (~3);\r
202             size_yrgb = stride * h;\r
203             size_uv = (stride * (h >> 1));            \r
204             start = MIN(yrgb_addr, uv_addr);\r
205             start >>= PAGE_SHIFT; \r
206             end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv));\r
207             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
208             pageCount = end - start;\r
209             break;\r
210         case RK_FORMAT_YCrCb_420_P :\r
211             stride = (w + 3) & (~3);\r
212             size_yrgb = stride * h;\r
213             size_uv = ((stride >> 1) * (h >> 1));\r
214             size_v = ((stride >> 1) * (h >> 1));\r
215             start = MIN(MIN(yrgb_addr, uv_addr), v_addr);\r
216             start >>= PAGE_SHIFT; \r
217             end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v));\r
218             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
219             pageCount = end - start;\r
220             break;\r
221         #if 0    \r
222         case RK_FORMAT_BPP1 :            \r
223             break;\r
224         case RK_FORMAT_BPP2 :\r
225             break;\r
226         case RK_FORMAT_BPP4 :\r
227             break;\r
228         case RK_FORMAT_BPP8 :\r
229             break;\r
230         #endif    \r
231         default :\r
232             pageCount = 0;\r
233             start = 0;\r
234             break;\r
235     }\r
236 \r
237     *StartAddr = start;\r
238     return pageCount;    \r
239 }\r
240 \r
241 static int rga_MapUserMemory(struct page **pages, \r
242                                             uint32_t *pageTable, \r
243                                             uint32_t Memory, \r
244                                             uint32_t pageCount)\r
245 {\r
246     int32_t result;\r
247     uint32_t i;\r
248     uint32_t status;\r
249     uint32_t Address;\r
250     //uint32_t temp;\r
251     \r
252     status = 0;\r
253     Address = 0;\r
254     \r
255     do\r
256     {    \r
257         down_read(&current->mm->mmap_sem);\r
258         result = get_user_pages(current,\r
259                 current->mm,\r
260                 Memory << PAGE_SHIFT,\r
261                 pageCount,\r
262                 1,\r
263                 0,\r
264                 pages,\r
265                 NULL\r
266                 );\r
267         up_read(&current->mm->mmap_sem);\r
268 \r
269         #if 0                \r
270         if(result <= 0 || result < pageCount) \r
271         {\r
272             status = 0;\r
273 \r
274             for(i=0; i<pageCount; i++)\r
275             {   \r
276                 temp = armv7_va_to_pa((Memory + i) << PAGE_SHIFT);\r
277                 if (temp == 0xffffffff)\r
278                 {\r
279                     printk("rga find mmu phy ddr error\n ");\r
280                     status = RGA_OUT_OF_RESOURCES;\r
281                     break;\r
282                 }\r
283                 \r
284                 pageTable[i] = temp;                \r
285             }\r
286 \r
287             return status;\r
288         }\r
289         #else\r
290         if(result <= 0 || result < pageCount) \r
291         {\r
292             struct vm_area_struct *vma;\r
293 \r
294             for(i=0; i<pageCount; i++)\r
295             {                \r
296                 vma = find_vma(current->mm, (Memory + i) << PAGE_SHIFT);\r
297 \r
298                 if (vma)//&& (vma->vm_flags & VM_PFNMAP) )\r
299                 {\r
300                     do\r
301                     {\r
302                         pte_t       * pte;\r
303                         spinlock_t  * ptl;\r
304                         unsigned long pfn;                                                                        \r
305                         pgd_t * pgd;\r
306                         pud_t * pud;\r
307                         \r
308                         pgd = pgd_offset(current->mm, (Memory + i) << PAGE_SHIFT);\r
309 \r
310                         if(pgd_val(*pgd) == 0)\r
311                         {\r
312                             printk("rga pgd value is zero \n");\r
313                             break;\r
314                         }\r
315                         \r
316                         pud = pud_offset(pgd, (Memory + i) << PAGE_SHIFT);\r
317                         if (pud)\r
318                         {\r
319                             pmd_t * pmd = pmd_offset(pud, (Memory + i) << PAGE_SHIFT);\r
320                             if (pmd)\r
321                             {\r
322                                 pte = pte_offset_map_lock(current->mm, pmd, (Memory + i) << PAGE_SHIFT, &ptl);\r
323                                 if (!pte)\r
324                                 {\r
325                                     break;\r
326                                 }\r
327                             }\r
328                             else\r
329                             {\r
330                                 break;\r
331                             }\r
332                         }\r
333                         else\r
334                         {\r
335                             break;\r
336                         }\r
337 \r
338                         pfn = pte_pfn(*pte);\r
339                         Address = ((pfn << PAGE_SHIFT) | (((unsigned long)((Memory + i) << PAGE_SHIFT)) & ~PAGE_MASK));                        \r
340                         pte_unmap_unlock(pte, ptl);                                                                        \r
341                     }\r
342                     while (0);\r
343 \r
344                     pageTable[i] = Address;\r
345                 }\r
346                 else\r
347                 {\r
348                     status = RGA_OUT_OF_RESOURCES;\r
349                     break;\r
350                 }     \r
351             }\r
352             \r
353             return status;\r
354         }\r
355         #endif\r
356 \r
357         /* Fill the page table. */\r
358         for(i=0; i<pageCount; i++) \r
359         {\r
360             /* Get the physical address from page struct. */\r
361             pageTable[i] = page_to_phys(pages[i]);\r
362         }\r
363 \r
364         return 0;\r
365     }\r
366     while(0);\r
367     \r
368     return status;\r
369 }\r
370 \r
371 static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req)\r
372 {    \r
373     int SrcMemSize, DstMemSize;\r
374     uint32_t SrcStart, DstStart;   \r
375     uint32_t i;\r
376     uint32_t AllSize;\r
377     uint32_t *MMU_Base, *MMU_p;\r
378     int ret;\r
379     int status;\r
380     uint32_t uv_size, v_size;\r
381 \r
382     struct page **pages = NULL;\r
383 \r
384     MMU_Base = NULL;\r
385     \r
386     do\r
387     {               \r
388         /* cal src buf mmu info */                     \r
389         SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr,\r
390                                         req->src.format, req->src.vir_w, req->src.act_h + req->src.y_offset,\r
391                                         &SrcStart);\r
392         if(SrcMemSize == 0) {\r
393             return -EINVAL;                \r
394         }\r
395       \r
396         /* cal dst buf mmu info */    \r
397         DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
398                                         req->dst.format, req->dst.vir_w, req->dst.act_h + req->dst.y_offset,\r
399                                         &DstStart);        \r
400         if(DstMemSize == 0) {\r
401             return -EINVAL; \r
402         }\r
403                 \r
404         /* Cal out the needed mem size */\r
405         AllSize = SrcMemSize + DstMemSize;\r
406                            \r
407         pages = kzalloc((AllSize + 1)* sizeof(struct page *), GFP_KERNEL);\r
408         if(pages == NULL) {\r
409             pr_err("RGA MMU malloc pages mem failed\n");\r
410             status = RGA_MALLOC_ERROR;\r
411             break;                \r
412         }\r
413         \r
414         MMU_Base = kzalloc((AllSize + 1) * sizeof(uint32_t), GFP_KERNEL);\r
415         if(MMU_Base == NULL) {\r
416             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
417             status = RGA_MALLOC_ERROR;\r
418             break;                \r
419         }\r
420 \r
421         if(req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
422         {               \r
423             ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize);\r
424             if (ret < 0) {\r
425                 pr_err("rga map src memory failed\n");\r
426                 status = ret;\r
427                 break;\r
428             }            \r
429         }\r
430         else\r
431         {\r
432             MMU_p = MMU_Base;\r
433             \r
434             if(req->src.yrgb_addr == (uint32_t)rga_service.pre_scale_buf)\r
435             {\r
436                 /* Down scale ratio over 2, Last prc    */\r
437                 /* MMU table copy from pre scale table  */\r
438                 \r
439                 for(i=0; i<SrcMemSize; i++)\r
440                 {\r
441                     MMU_p[i] = rga_service.pre_scale_buf[i];\r
442                 }                \r
443             }\r
444             else\r
445             {                      \r
446                 for(i=0; i<SrcMemSize; i++)\r
447                 {\r
448                     MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
449                 }                \r
450             }            \r
451         }\r
452         \r
453         if (req->dst.yrgb_addr < KERNEL_SPACE_VALID)\r
454         {     \r
455             #if 0\r
456             ktime_t start, end;\r
457             start = ktime_get();\r
458             #endif            \r
459             ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize);\r
460             if (ret < 0) {\r
461                 pr_err("rga map dst memory failed\n");\r
462                 status = ret;\r
463                 break;\r
464             }\r
465 \r
466             #if 0\r
467             end = ktime_get();\r
468             end = ktime_sub(end, start);\r
469             printk("dst mmu map time = %d\n", (int)ktime_to_us(end));\r
470             #endif\r
471         }\r
472         else\r
473         {\r
474             MMU_p = MMU_Base + SrcMemSize;\r
475             \r
476             for(i=0; i<DstMemSize; i++)\r
477             {\r
478                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT));\r
479             }                   \r
480         }\r
481 \r
482         MMU_Base[AllSize] = MMU_Base[AllSize - 1];\r
483 \r
484         /* zsq \r
485          * change the buf address in req struct     \r
486          */\r
487         \r
488         req->mmu_info.base_addr = (virt_to_phys(MMU_Base)>>2);\r
489 \r
490         uv_size = (req->src.uv_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
491         v_size = (req->src.v_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
492         \r
493         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK));\r
494         req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (uv_size << PAGE_SHIFT);\r
495         req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (v_size << PAGE_SHIFT);\r
496 \r
497         req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | (SrcMemSize << PAGE_SHIFT);\r
498                 \r
499         /*record the malloc buf for the cmd end to release*/\r
500         reg->MMU_base = MMU_Base;\r
501         \r
502         /* flush data to DDR */\r
503         dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
504         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));\r
505 \r
506         status = 0;\r
507                \r
508         /* Free the page table */        \r
509         if (pages != NULL) {\r
510             kfree(pages);\r
511         }\r
512 \r
513         return status;\r
514     }\r
515     while(0);\r
516 \r
517     \r
518     /* Free the page table */        \r
519     if (pages != NULL) {\r
520         kfree(pages);\r
521     }\r
522 \r
523     /* Free MMU table */\r
524     if(MMU_Base != NULL) {\r
525         kfree(MMU_Base);\r
526     }\r
527 \r
528     return status;\r
529 }\r
530 \r
531 static int rga_mmu_info_color_palette_mode(struct rga_reg *reg, struct rga_req *req)\r
532 {\r
533     int SrcMemSize, DstMemSize, CMDMemSize;\r
534     uint32_t SrcStart, DstStart, CMDStart;\r
535     struct page **pages = NULL;\r
536     uint32_t i;\r
537     uint32_t AllSize;\r
538     uint32_t *MMU_Base = NULL;\r
539     uint32_t *MMU_p;\r
540     int ret, status;\r
541     uint32_t stride;\r
542 \r
543     uint8_t shift;\r
544     uint16_t sw, byte_num;\r
545     \r
546     shift = 3 - (req->palette_mode & 3);\r
547     sw = req->src.vir_w;\r
548     byte_num = sw >> shift;\r
549     stride = (byte_num + 3) & (~3);\r
550 \r
551     do\r
552     {\r
553                          \r
554         SrcMemSize = rga_mem_size_cal(req->src.yrgb_addr, stride, &SrcStart);\r
555         if(SrcMemSize == 0) {\r
556             return -EINVAL;                \r
557         }\r
558 \r
559         DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
560                                         req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
561                                         &DstStart);\r
562         if(DstMemSize == 0) {\r
563             return -EINVAL; \r
564         }\r
565 \r
566         CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);\r
567         if(CMDMemSize == 0) {\r
568             return -EINVAL; \r
569         }\r
570 \r
571         AllSize = SrcMemSize + DstMemSize + CMDMemSize;\r
572                    \r
573         pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
574         if(pages == NULL) {\r
575             pr_err("RGA MMU malloc pages mem failed\n");\r
576             return -EINVAL;                \r
577         }\r
578 \r
579         MMU_Base = kzalloc(AllSize * sizeof(uint32_t), GFP_KERNEL);\r
580         if(MMU_Base == NULL) {\r
581             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
582             break;            \r
583         }\r
584 \r
585         /* map CMD addr */\r
586         for(i=0; i<CMDMemSize; i++) \r
587         {\r
588             MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i)<<PAGE_SHIFT));\r
589         }\r
590 \r
591         /* map src addr */\r
592         if (req->src.yrgb_addr < KERNEL_SPACE_VALID) \r
593         {            \r
594             ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
595             if (ret < 0) \r
596             {\r
597                 pr_err("rga map src memory failed\n");\r
598                 status = ret;\r
599                 break;            \r
600             }\r
601         }\r
602         else\r
603         {\r
604             MMU_p = MMU_Base + CMDMemSize;\r
605             \r
606             for(i=0; i<SrcMemSize; i++)\r
607             {\r
608                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
609             }\r
610         }\r
611 \r
612         /* map dst addr */\r
613         if (req->src.yrgb_addr < KERNEL_SPACE_VALID) \r
614         {\r
615             ret = rga_MapUserMemory(&pages[CMDMemSize + SrcMemSize], &MMU_Base[CMDMemSize + SrcMemSize], DstStart, DstMemSize);\r
616             if (ret < 0) \r
617             {\r
618                 pr_err("rga map dst memory failed\n");\r
619                 status = ret;\r
620                 break;\r
621             }\r
622         }\r
623         else\r
624         {\r
625             MMU_p = MMU_Base + CMDMemSize + SrcMemSize;\r
626             \r
627             for(i=0; i<DstMemSize; i++)\r
628             {\r
629                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT));\r
630             }\r
631         }\r
632         \r
633 \r
634         /* zsq \r
635          * change the buf address in req struct\r
636          * for the reason of lie to MMU \r
637          */\r
638         req->mmu_info.base_addr = (virt_to_phys(MMU_Base)>>2);    \r
639         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
640         req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((CMDMemSize + SrcMemSize) << PAGE_SHIFT);\r
641 \r
642 \r
643         /*record the malloc buf for the cmd end to release*/\r
644         reg->MMU_base = MMU_Base;\r
645 \r
646         /* flush data to DDR */\r
647         dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
648         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));\r
649 \r
650         /* Free the page table */\r
651         if (pages != NULL) {            \r
652             kfree(pages);\r
653         }\r
654 \r
655         return status;\r
656 \r
657     }\r
658     while(0);\r
659 \r
660     /* Free the page table */\r
661     if (pages != NULL) {            \r
662         kfree(pages);\r
663     }\r
664 \r
665     /* Free mmu table */\r
666     if (MMU_Base != NULL) {\r
667         kfree(MMU_Base);\r
668     }\r
669 \r
670     return 0;\r
671 }\r
672 \r
673 static int rga_mmu_info_color_fill_mode(struct rga_reg *reg, struct rga_req *req)\r
674 {\r
675     int DstMemSize;\r
676     uint32_t DstStart;\r
677     struct page **pages = NULL;\r
678     uint32_t i;\r
679     uint32_t AllSize;\r
680     uint32_t *MMU_Base, *MMU_p;\r
681     int ret;\r
682     int status;\r
683 \r
684     MMU_Base = NULL;\r
685 \r
686     do\r
687     {                         \r
688         DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
689                                         req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
690                                         &DstStart);\r
691         if(DstMemSize == 0) {\r
692             return -EINVAL; \r
693         }\r
694 \r
695         AllSize = DstMemSize;\r
696                    \r
697         pages = kzalloc((AllSize + 1)* sizeof(struct page *), GFP_KERNEL);\r
698         if(pages == NULL) {\r
699             pr_err("RGA MMU malloc pages mem failed\n");\r
700             status = RGA_MALLOC_ERROR; \r
701             break;\r
702         }\r
703         \r
704         MMU_Base = kzalloc((AllSize + 1) * sizeof(uint32_t), GFP_KERNEL);\r
705         if(pages == NULL) {\r
706             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
707             status = RGA_MALLOC_ERROR;\r
708             break;                \r
709         }\r
710 \r
711         if (req->dst.yrgb_addr < KERNEL_SPACE_VALID) \r
712         {\r
713             ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], DstStart, DstMemSize);\r
714             if (ret < 0) {\r
715                 pr_err("rga map dst memory failed\n");\r
716                 status = ret;\r
717                 break;\r
718             }\r
719         }\r
720         else\r
721         {\r
722             MMU_p = MMU_Base;\r
723             \r
724             for(i=0; i<DstMemSize; i++)\r
725             {\r
726                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT));\r
727             }\r
728         }\r
729 \r
730         MMU_Base[AllSize] = MMU_Base[AllSize - 1];        \r
731                             \r
732         /* zsq \r
733          * change the buf address in req struct \r
734          */\r
735          \r
736         req->mmu_info.base_addr = (virt_to_phys(MMU_Base)>>2);    \r
737         req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK));\r
738                \r
739         /*record the malloc buf for the cmd end to release*/\r
740         reg->MMU_base = MMU_Base;\r
741 \r
742         /* flush data to DDR */\r
743         dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
744         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));\r
745 \r
746         /* Free the page table */\r
747         if (pages != NULL)             \r
748             kfree(pages);\r
749 \r
750         return 0;\r
751     }\r
752     while(0);\r
753 \r
754     if (pages != NULL)    \r
755         kfree(pages);\r
756 \r
757     if (MMU_Base != NULL)\r
758         kfree(MMU_Base);\r
759     \r
760     return status;\r
761 }\r
762 \r
763 \r
764 static int rga_mmu_info_line_point_drawing_mode(struct rga_reg *reg, struct rga_req *req)\r
765 {\r
766     int DstMemSize;\r
767     uint32_t DstStart;\r
768     struct page **pages = NULL;\r
769     uint32_t i;\r
770     uint32_t AllSize;\r
771     uint32_t *MMU_Base, *MMU_p;\r
772     int ret, status;\r
773 \r
774     MMU_Base = NULL;\r
775 \r
776     do\r
777     {    \r
778         /* cal dst buf mmu info */                     \r
779         DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
780                                         req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
781                                         &DstStart);\r
782         if(DstMemSize == 0) {\r
783             return -EINVAL; \r
784         }\r
785 \r
786         AllSize = DstMemSize;\r
787                    \r
788         pages = kzalloc((AllSize + 1) * sizeof(struct page *), GFP_KERNEL);\r
789         if(pages == NULL) {\r
790             pr_err("RGA MMU malloc pages mem failed\n");\r
791             status = RGA_MALLOC_ERROR;\r
792             break;\r
793         }\r
794         \r
795         MMU_Base = kzalloc((AllSize + 1) * sizeof(uint32_t), GFP_KERNEL);\r
796         if(pages == NULL) {\r
797             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
798             status = RGA_MALLOC_ERROR;\r
799             break;\r
800         }\r
801 \r
802         if (req->dst.yrgb_addr < KERNEL_SPACE_VALID)\r
803         {\r
804             ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], DstStart, DstMemSize);\r
805             if (ret < 0) {\r
806                 pr_err("rga map dst memory failed\n");\r
807                 status = ret;\r
808                 break;\r
809             }\r
810         }\r
811         else\r
812         {\r
813             MMU_p = MMU_Base;\r
814             \r
815             for(i=0; i<DstMemSize; i++)\r
816             {\r
817                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT));\r
818             }\r
819         }\r
820 \r
821         /* zsq \r
822          * change the buf address in req struct\r
823          * for the reason of lie to MMU \r
824          */\r
825         req->mmu_info.base_addr = (virt_to_phys(MMU_Base) >> 2);    \r
826         req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK));\r
827        \r
828         \r
829         /*record the malloc buf for the cmd end to release*/\r
830         reg->MMU_base = MMU_Base;\r
831 \r
832         /* flush data to DDR */\r
833         dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
834         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));\r
835 \r
836         /* Free the page table */\r
837         if (pages != NULL) {            \r
838             kfree(pages);\r
839         } \r
840 \r
841         return 0;\r
842 \r
843     }\r
844     while(0);\r
845 \r
846     if (pages != NULL)\r
847         kfree(pages);\r
848 \r
849     if (MMU_Base != NULL)\r
850         kfree(MMU_Base);\r
851 \r
852     return status;\r
853 }\r
854 \r
855 static int rga_mmu_info_blur_sharp_filter_mode(struct rga_reg *reg, struct rga_req *req)\r
856 {\r
857     int SrcMemSize, DstMemSize;\r
858     uint32_t SrcStart, DstStart;\r
859     struct page **pages = NULL;\r
860     uint32_t i;\r
861     uint32_t AllSize;\r
862     uint32_t *MMU_Base, *MMU_p;\r
863     int ret, status;\r
864     uint32_t uv_size, v_size;\r
865 \r
866     MMU_Base = NULL;\r
867     \r
868     do\r
869     {\r
870         /* cal src buf mmu info */                     \r
871         SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr,\r
872                                         req->src.format, req->src.vir_w, req->src.vir_h,\r
873                                         &SrcStart);\r
874         if(SrcMemSize == 0) {\r
875             return -EINVAL;                \r
876         }\r
877 \r
878         /* cal dst buf mmu info */    \r
879         DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
880                                         req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
881                                         &DstStart);\r
882         if(DstMemSize == 0) {\r
883             return -EINVAL; \r
884         }\r
885 \r
886         AllSize = SrcMemSize + DstMemSize;\r
887                    \r
888         pages = kzalloc((AllSize + 1) * sizeof(struct page *), GFP_KERNEL);\r
889         if(pages == NULL) {\r
890             pr_err("RGA MMU malloc pages mem failed\n");\r
891             status = RGA_MALLOC_ERROR;\r
892             break;    \r
893         }\r
894         \r
895         MMU_Base = kzalloc((AllSize + 1)* sizeof(uint32_t), GFP_KERNEL);\r
896         if(pages == NULL) {\r
897             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
898             status = RGA_MALLOC_ERROR;\r
899             break;   \r
900         }\r
901 \r
902         if (req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
903         {\r
904             ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize);\r
905             if (ret < 0) \r
906             {\r
907                 pr_err("rga map src memory failed\n");\r
908                 status = ret;\r
909                 break;\r
910             }\r
911         }\r
912         else\r
913         {\r
914             MMU_p = MMU_Base;\r
915             \r
916             for(i=0; i<SrcMemSize; i++)\r
917             {\r
918                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
919             }            \r
920         }\r
921 \r
922         \r
923         if (req->dst.yrgb_addr < KERNEL_SPACE_VALID)\r
924         {\r
925             ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize);\r
926             if (ret < 0) \r
927             {\r
928                 pr_err("rga map dst memory failed\n");\r
929                 status = ret;\r
930                 break;\r
931             }\r
932         }\r
933         else\r
934         {\r
935             MMU_p = MMU_Base + SrcMemSize;\r
936             \r
937             for(i=0; i<DstMemSize; i++)\r
938             {\r
939                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT));\r
940             }\r
941         }\r
942 \r
943         MMU_Base[AllSize] = MMU_Base[AllSize - 1];\r
944 \r
945         /* zsq \r
946          * change the buf address in req struct\r
947          * for the reason of lie to MMU \r
948          */\r
949         req->mmu_info.base_addr = (virt_to_phys(MMU_Base) >> 2);\r
950 \r
951         uv_size = (req->src.uv_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
952         v_size = (req->src.v_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
953         \r
954         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK));\r
955         req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (uv_size << PAGE_SHIFT);\r
956         req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (v_size << PAGE_SHIFT);\r
957 \r
958         uv_size = (req->dst.uv_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
959         v_size = (req->dst.v_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
960 \r
961         req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | (SrcMemSize << PAGE_SHIFT);\r
962         req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((SrcMemSize + uv_size) << PAGE_SHIFT);\r
963         req->dst.v_addr = (req->dst.v_addr & (~PAGE_MASK)) | ((SrcMemSize + v_size) << PAGE_SHIFT);\r
964         \r
965         \r
966         /*record the malloc buf for the cmd end to release*/\r
967         reg->MMU_base = MMU_Base;\r
968 \r
969         /* flush data to DDR */\r
970         dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
971         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));\r
972 \r
973         /* Free the page table */\r
974         if (pages != NULL) {        \r
975             kfree(pages);\r
976         }  \r
977 \r
978         return 0;\r
979     }\r
980     while(0);\r
981 \r
982     if (pages != NULL)\r
983         kfree(pages);\r
984 \r
985     if (MMU_Base != NULL)\r
986         kfree(MMU_Base);\r
987 \r
988     return status;\r
989 }\r
990 \r
991 \r
992 \r
993 static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req)\r
994 {\r
995     int SrcMemSize, DstMemSize;\r
996     uint32_t SrcStart, DstStart;\r
997     struct page **pages = NULL;\r
998     uint32_t i;\r
999     uint32_t AllSize;\r
1000     uint32_t *MMU_Base, *MMU_p;\r
1001     int ret;\r
1002     int status;\r
1003     uint32_t uv_size, v_size;\r
1004 \r
1005     MMU_Base = NULL;\r
1006 \r
1007     do\r
1008     {\r
1009         /* cal src buf mmu info */                     \r
1010         SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr,\r
1011                                         req->src.format, req->src.vir_w, req->src.vir_h,\r
1012                                         &SrcStart);\r
1013         if(SrcMemSize == 0) {\r
1014             return -EINVAL;                \r
1015         }\r
1016 \r
1017         /* cal dst buf mmu info */    \r
1018         DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
1019                                         req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
1020                                         &DstStart);\r
1021         if(DstMemSize == 0) {\r
1022             return -EINVAL; \r
1023         }\r
1024 \r
1025         AllSize = SrcMemSize + DstMemSize;\r
1026                    \r
1027         pages = kzalloc((AllSize)* sizeof(struct page *), GFP_KERNEL);\r
1028         if(pages == NULL) \r
1029         {\r
1030             pr_err("RGA MMU malloc pages mem failed\n");\r
1031             status = RGA_MALLOC_ERROR;\r
1032             break;                \r
1033         }\r
1034 \r
1035         /* \r
1036          * Allocate MMU Index mem\r
1037          * This mem release in run_to_done fun \r
1038          */\r
1039         MMU_Base = kzalloc((AllSize + 1) * sizeof(uint32_t), GFP_KERNEL);\r
1040         if(pages == NULL) {\r
1041             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
1042             status = RGA_MALLOC_ERROR;            \r
1043             break;                \r
1044         }\r
1045 \r
1046         /* map src pages */\r
1047         if (req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
1048         {\r
1049             ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize);\r
1050             if (ret < 0) {\r
1051                 pr_err("rga map src memory failed\n");\r
1052                 status = ret;\r
1053                 break;\r
1054             }\r
1055         }\r
1056         else\r
1057         {\r
1058             MMU_p = MMU_Base;\r
1059             \r
1060             for(i=0; i<SrcMemSize; i++)\r
1061             {\r
1062                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
1063             } \r
1064         }\r
1065 \r
1066         \r
1067         if(req->dst.yrgb_addr >= KERNEL_SPACE_VALID) \r
1068         {   \r
1069             /* kernel space */\r
1070             MMU_p = MMU_Base + SrcMemSize;\r
1071 \r
1072             if(req->dst.yrgb_addr == (uint32_t)rga_service.pre_scale_buf)\r
1073             {\r
1074                 for(i=0; i<DstMemSize; i++)\r
1075                 {\r
1076                     MMU_p[i] = rga_service.pre_scale_buf[i];\r
1077                 }\r
1078             }\r
1079             else\r
1080             {\r
1081                 for(i=0; i<DstMemSize; i++) \r
1082                 {\r
1083                     MMU_p[i] = virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT));        \r
1084                 }    \r
1085             }                                    \r
1086         }\r
1087         else \r
1088         {\r
1089             /* user space */\r
1090             ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize);\r
1091             if (ret < 0) \r
1092             {\r
1093                 pr_err("rga map dst memory failed\n");\r
1094                 status = ret;\r
1095                 break;\r
1096             }        \r
1097         }\r
1098 \r
1099         MMU_Base[AllSize] = MMU_Base[AllSize - 1];\r
1100 \r
1101         /* zsq \r
1102          * change the buf address in req struct\r
1103          * for the reason of lie to MMU \r
1104          */\r
1105         \r
1106         req->mmu_info.base_addr = (virt_to_phys(MMU_Base)>>2);\r
1107 \r
1108         uv_size = (req->src.uv_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
1109         v_size = (req->src.v_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
1110 \r
1111         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK));\r
1112         req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (uv_size << PAGE_SHIFT);\r
1113         req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (v_size << PAGE_SHIFT);\r
1114 \r
1115         uv_size = (req->dst.uv_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
1116         v_size = (req->dst.v_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
1117 \r
1118         req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((SrcMemSize) << PAGE_SHIFT);\r
1119         req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((SrcMemSize + uv_size) << PAGE_SHIFT);\r
1120         req->dst.v_addr = (req->dst.v_addr & (~PAGE_MASK)) | ((SrcMemSize + v_size) << PAGE_SHIFT);\r
1121 \r
1122         /*record the malloc buf for the cmd end to release*/\r
1123         reg->MMU_base = MMU_Base;\r
1124 \r
1125         /* flush data to DDR */\r
1126         dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
1127         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));\r
1128 \r
1129         /* Free the page table */\r
1130         if (pages != NULL) \r
1131         {            \r
1132             kfree(pages);\r
1133         }  \r
1134 \r
1135         return 0;\r
1136     }\r
1137     while(0);\r
1138 \r
1139     if (pages != NULL)\r
1140         kfree(pages);\r
1141 \r
1142     if (MMU_Base != NULL)\r
1143         kfree(MMU_Base);\r
1144 \r
1145     return status;\r
1146 }\r
1147 \r
1148 \r
1149 static int rga_mmu_info_update_palette_table_mode(struct rga_reg *reg, struct rga_req *req)\r
1150 {\r
1151     int SrcMemSize, CMDMemSize;\r
1152     uint32_t SrcStart, CMDStart;\r
1153     struct page **pages = NULL;\r
1154     uint32_t i;\r
1155     uint32_t AllSize;\r
1156     uint32_t *MMU_Base, *MMU_p;\r
1157     int ret, status;\r
1158 \r
1159     MMU_Base = NULL;\r
1160 \r
1161     do\r
1162     {    \r
1163         /* cal src buf mmu info */                     \r
1164         SrcMemSize = rga_mem_size_cal(req->src.yrgb_addr, req->src.vir_w * req->src.vir_h, &SrcStart);\r
1165         if(SrcMemSize == 0) {\r
1166             return -EINVAL;                \r
1167         }\r
1168 \r
1169         /* cal cmd buf mmu info */\r
1170         CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);\r
1171         if(CMDMemSize == 0) {\r
1172             return -EINVAL; \r
1173         }\r
1174 \r
1175         AllSize = SrcMemSize + CMDMemSize;\r
1176                    \r
1177         pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
1178         if(pages == NULL) {\r
1179             pr_err("RGA MMU malloc pages mem failed\n");\r
1180             status = RGA_MALLOC_ERROR;\r
1181             break;    \r
1182         }\r
1183         \r
1184         MMU_Base = kzalloc((AllSize + 1)* sizeof(uint32_t), GFP_KERNEL);\r
1185         if(pages == NULL) {\r
1186             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
1187             status = RGA_MALLOC_ERROR;\r
1188             break;                \r
1189         }\r
1190 \r
1191         for(i=0; i<CMDMemSize; i++) {\r
1192             MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i) << PAGE_SHIFT));\r
1193         }\r
1194 \r
1195         if (req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
1196         {\r
1197             ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
1198             if (ret < 0) {\r
1199                 pr_err("rga map src memory failed\n");\r
1200                 return -EINVAL;\r
1201             }\r
1202         }\r
1203         else\r
1204         {\r
1205             MMU_p = MMU_Base + CMDMemSize;\r
1206                 \r
1207                 for(i=0; i<SrcMemSize; i++)\r
1208                 {\r
1209                     MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
1210                 } \r
1211         }\r
1212 \r
1213         /* zsq \r
1214          * change the buf address in req struct\r
1215          * for the reason of lie to MMU \r
1216          */\r
1217         req->mmu_info.base_addr = (virt_to_phys(MMU_Base) >> 2);\r
1218         \r
1219         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);    \r
1220         \r
1221         /*record the malloc buf for the cmd end to release*/\r
1222         reg->MMU_base = MMU_Base;\r
1223 \r
1224         /* flush data to DDR */\r
1225         dmac_flush_range(MMU_Base, (MMU_Base + AllSize));\r
1226         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize));\r
1227 \r
1228         if (pages != NULL) {\r
1229             /* Free the page table */\r
1230             kfree(pages);\r
1231         }  \r
1232 \r
1233         return 0;\r
1234     }\r
1235     while(0);\r
1236 \r
1237     if (pages != NULL)\r
1238         kfree(pages);\r
1239 \r
1240     if (MMU_Base != NULL)\r
1241         kfree(MMU_Base);\r
1242 \r
1243     return status;\r
1244 }\r
1245 \r
1246 static int rga_mmu_info_update_patten_buff_mode(struct rga_reg *reg, struct rga_req *req)\r
1247 {\r
1248     int SrcMemSize, CMDMemSize;\r
1249     uint32_t SrcStart, CMDStart;\r
1250     struct page **pages = NULL;\r
1251     uint32_t i;\r
1252     uint32_t AllSize;\r
1253     uint32_t *MMU_Base, *MMU_p;\r
1254     int ret, status;\r
1255 \r
1256     MMU_Base = MMU_p = 0;\r
1257 \r
1258     do\r
1259     {\r
1260 \r
1261         /* cal src buf mmu info */                     \r
1262         SrcMemSize = rga_mem_size_cal(req->pat.yrgb_addr, req->pat.vir_w * req->pat.vir_h * 4, &SrcStart);\r
1263         if(SrcMemSize == 0) {\r
1264             return -EINVAL;                \r
1265         }\r
1266 \r
1267         /* cal cmd buf mmu info */\r
1268         CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);\r
1269         if(CMDMemSize == 0) {\r
1270             return -EINVAL; \r
1271         }\r
1272 \r
1273         AllSize = SrcMemSize + CMDMemSize;\r
1274                    \r
1275         pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
1276         if(pages == NULL) {\r
1277             pr_err("RGA MMU malloc pages mem failed\n");\r
1278             status = RGA_MALLOC_ERROR;\r
1279             break;                \r
1280         }\r
1281         \r
1282         MMU_Base = kzalloc(AllSize * sizeof(uint32_t), GFP_KERNEL);\r
1283         if(pages == NULL) {\r
1284             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
1285             status = RGA_MALLOC_ERROR;\r
1286             break;                \r
1287         }\r
1288 \r
1289         for(i=0; i<CMDMemSize; i++) {\r
1290             MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i) << PAGE_SHIFT));\r
1291         }\r
1292 \r
1293         if (req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
1294         {\r
1295             ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
1296             if (ret < 0) {\r
1297                 pr_err("rga map src memory failed\n");\r
1298                 status = ret;\r
1299                 break;\r
1300             }\r
1301         }\r
1302         else\r
1303         {\r
1304             MMU_p = MMU_Base + CMDMemSize;\r
1305                 \r
1306             for(i=0; i<SrcMemSize; i++)\r
1307             {\r
1308                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
1309             } \r
1310         }\r
1311 \r
1312         /* zsq \r
1313          * change the buf address in req struct\r
1314          * for the reason of lie to MMU \r
1315          */\r
1316         req->mmu_info.base_addr = (virt_to_phys(MMU_Base) >> 2);\r
1317         \r
1318         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);    \r
1319         \r
1320         /*record the malloc buf for the cmd end to release*/\r
1321         reg->MMU_base = MMU_Base;\r
1322 \r
1323         /* flush data to DDR */\r
1324         dmac_flush_range(MMU_Base, (MMU_Base + AllSize));\r
1325         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize));\r
1326 \r
1327         if (pages != NULL) {\r
1328             /* Free the page table */\r
1329             kfree(pages);\r
1330         }\r
1331 \r
1332         return 0;\r
1333 \r
1334     }\r
1335     while(0);\r
1336 \r
1337     if (pages != NULL)\r
1338         kfree(pages);\r
1339 \r
1340     if (MMU_Base != NULL)\r
1341         kfree(MMU_Base);\r
1342 \r
1343     return status;\r
1344 }\r
1345 \r
1346 int rga_set_mmu_info(struct rga_reg *reg, struct rga_req *req)\r
1347 {    \r
1348     int ret;\r
1349                \r
1350     switch (req->render_mode) {\r
1351         case bitblt_mode :            \r
1352             ret = rga_mmu_info_BitBlt_mode(reg, req);\r
1353             break;\r
1354         case color_palette_mode :\r
1355             ret = rga_mmu_info_color_palette_mode(reg, req);\r
1356             break;\r
1357         case color_fill_mode :\r
1358             ret = rga_mmu_info_color_fill_mode(reg, req);\r
1359             break;\r
1360         case line_point_drawing_mode :\r
1361             ret = rga_mmu_info_line_point_drawing_mode(reg, req);\r
1362             break;\r
1363         case blur_sharp_filter_mode :\r
1364             ret = rga_mmu_info_blur_sharp_filter_mode(reg, req);\r
1365             break;\r
1366         case pre_scaling_mode :\r
1367             ret = rga_mmu_info_pre_scale_mode(reg, req);\r
1368             break;\r
1369         case update_palette_table_mode :\r
1370             ret = rga_mmu_info_update_palette_table_mode(reg, req);\r
1371             break;\r
1372         case update_patten_buff_mode :\r
1373             ret = rga_mmu_info_update_patten_buff_mode(reg, req);\r
1374             break;\r
1375         default :\r
1376             ret = -1;\r
1377             break;\r
1378     }\r
1379 \r
1380     return ret;\r
1381 }\r
1382 \r