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                     #if 1\r
301                     do\r
302                     {\r
303                         pte_t       * pte;\r
304                         spinlock_t  * ptl;\r
305                         unsigned long pfn;                                                                        \r
306                         pgd_t * pgd;\r
307                         pud_t * pud;\r
308                         \r
309                         pgd = pgd_offset(current->mm, (Memory + i) << PAGE_SHIFT);\r
310 \r
311                         if(pgd_val(*pgd) == 0)\r
312                         {\r
313                             //printk("rga pgd value is zero \n");\r
314                             break;\r
315                         }\r
316                         \r
317                         pud = pud_offset(pgd, (Memory + i) << PAGE_SHIFT);\r
318                         if (pud)\r
319                         {\r
320                             pmd_t * pmd = pmd_offset(pud, (Memory + i) << PAGE_SHIFT);\r
321                             if (pmd)\r
322                             {\r
323                                 pte = pte_offset_map_lock(current->mm, pmd, (Memory + i) << PAGE_SHIFT, &ptl);\r
324                                 if (!pte)\r
325                                 {\r
326                                     break;\r
327                                 }\r
328                             }\r
329                             else\r
330                             {\r
331                                 break;\r
332                             }\r
333                         }\r
334                         else\r
335                         {\r
336                             break;\r
337                         }\r
338 \r
339                         pfn = pte_pfn(*pte);\r
340                         Address = ((pfn << PAGE_SHIFT) | (((unsigned long)((Memory + i) << PAGE_SHIFT)) & ~PAGE_MASK));                        \r
341                         pte_unmap_unlock(pte, ptl);                                                                        \r
342                     }\r
343                     while (0);\r
344                     \r
345                     #else\r
346                     \r
347                     do\r
348                     {\r
349                         pte_t       * pte;\r
350                         spinlock_t  * ptl;\r
351                         unsigned long pfn;                                                                        \r
352                         pgd_t * pgd;\r
353                         pud_t * pud;\r
354                         pmd_t * pmd;\r
355                         \r
356                         pgd = pgd_offset(current->mm, (Memory + i) << PAGE_SHIFT);                        \r
357                         pud = pud_offset(pgd, (Memory + i) << PAGE_SHIFT);\r
358                         pmd = pmd_offset(pud, (Memory + i) << PAGE_SHIFT);\r
359                         pte = pte_offset_map_lock(current->mm, pmd, (Memory + i) << PAGE_SHIFT, &ptl);\r
360                                                 \r
361                         pfn = pte_pfn(*pte);\r
362                         Address = ((pfn << PAGE_SHIFT) | (((unsigned long)((Memory + i) << PAGE_SHIFT)) & ~PAGE_MASK));                        \r
363                         pte_unmap_unlock(pte, ptl);                                                                        \r
364                     }\r
365                     while (0);\r
366                     #endif\r
367 \r
368                     pageTable[i] = Address;\r
369                 }\r
370                 else\r
371                 {\r
372                     status = RGA_OUT_OF_RESOURCES;\r
373                     break;\r
374                 }     \r
375             }\r
376             \r
377             return status;\r
378         }\r
379         #endif\r
380 \r
381         /* Fill the page table. */\r
382         for(i=0; i<pageCount; i++) \r
383         {\r
384             /* Get the physical address from page struct. */\r
385             pageTable[i] = page_to_phys(pages[i]);\r
386         }\r
387 \r
388         return 0;\r
389     }\r
390     while(0);\r
391     \r
392     return status;\r
393 }\r
394 \r
395 static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req)\r
396 {    \r
397     int SrcMemSize, DstMemSize;\r
398     uint32_t SrcStart, DstStart;   \r
399     uint32_t i;\r
400     uint32_t AllSize;\r
401     uint32_t *MMU_Base, *MMU_p;\r
402     int ret;\r
403     int status;\r
404     uint32_t uv_size, v_size;\r
405 \r
406     struct page **pages = NULL;\r
407 \r
408     MMU_Base = NULL;\r
409     \r
410     do\r
411     {               \r
412         /* cal src buf mmu info */                     \r
413         SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr,\r
414                                         req->src.format, req->src.vir_w, req->src.act_h + req->src.y_offset,\r
415                                         &SrcStart);\r
416         if(SrcMemSize == 0) {\r
417             return -EINVAL;                \r
418         }\r
419       \r
420         /* cal dst buf mmu info */    \r
421         DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
422                                         req->dst.format, req->dst.vir_w, req->dst.act_h + req->dst.y_offset,\r
423                                         &DstStart);        \r
424         if(DstMemSize == 0) {\r
425             return -EINVAL; \r
426         }\r
427                 \r
428         /* Cal out the needed mem size */\r
429         AllSize = SrcMemSize + DstMemSize;\r
430                            \r
431         pages = kzalloc((AllSize + 1)* sizeof(struct page *), GFP_KERNEL);\r
432         if(pages == NULL) {\r
433             pr_err("RGA MMU malloc pages mem failed\n");\r
434             status = RGA_MALLOC_ERROR;\r
435             break;                \r
436         }\r
437         \r
438         MMU_Base = kzalloc((AllSize + 1) * sizeof(uint32_t), GFP_KERNEL);\r
439         if(MMU_Base == NULL) {\r
440             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
441             status = RGA_MALLOC_ERROR;\r
442             break;                \r
443         }\r
444 \r
445         if(req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
446         {               \r
447             ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize);\r
448             if (ret < 0) {\r
449                 pr_err("rga map src memory failed\n");\r
450                 status = ret;\r
451                 break;\r
452             }            \r
453         }\r
454         else\r
455         {\r
456             MMU_p = MMU_Base;\r
457             \r
458             if(req->src.yrgb_addr == (uint32_t)rga_service.pre_scale_buf)\r
459             {\r
460                 /* Down scale ratio over 2, Last prc    */\r
461                 /* MMU table copy from pre scale table  */\r
462                 \r
463                 for(i=0; i<SrcMemSize; i++)\r
464                 {\r
465                     MMU_p[i] = rga_service.pre_scale_buf[i];\r
466                 }                \r
467             }\r
468             else\r
469             {                      \r
470                 for(i=0; i<SrcMemSize; i++)\r
471                 {\r
472                     MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
473                 }                \r
474             }            \r
475         }\r
476         \r
477         if (req->dst.yrgb_addr < KERNEL_SPACE_VALID)\r
478         {     \r
479             #if 0\r
480             ktime_t start, end;\r
481             start = ktime_get();\r
482             #endif            \r
483             ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize);\r
484             if (ret < 0) {\r
485                 pr_err("rga map dst memory failed\n");\r
486                 status = ret;\r
487                 break;\r
488             }\r
489 \r
490             #if 0\r
491             end = ktime_get();\r
492             end = ktime_sub(end, start);\r
493             printk("dst mmu map time = %d\n", (int)ktime_to_us(end));\r
494             #endif\r
495         }\r
496         else\r
497         {\r
498             MMU_p = MMU_Base + SrcMemSize;\r
499             \r
500             for(i=0; i<DstMemSize; i++)\r
501             {\r
502                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT));\r
503             }                   \r
504         }\r
505 \r
506         MMU_Base[AllSize] = MMU_Base[AllSize - 1];\r
507 \r
508         /* zsq \r
509          * change the buf address in req struct     \r
510          */\r
511         \r
512         req->mmu_info.base_addr = (virt_to_phys(MMU_Base)>>2);\r
513 \r
514         uv_size = (req->src.uv_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
515         v_size = (req->src.v_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
516         \r
517         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK));\r
518         req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (uv_size << PAGE_SHIFT);\r
519         req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (v_size << PAGE_SHIFT);\r
520 \r
521         req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | (SrcMemSize << PAGE_SHIFT);\r
522                 \r
523         /*record the malloc buf for the cmd end to release*/\r
524         reg->MMU_base = MMU_Base;\r
525         \r
526         /* flush data to DDR */\r
527         dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
528         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));\r
529 \r
530         status = 0;\r
531                \r
532         /* Free the page table */        \r
533         if (pages != NULL) {\r
534             kfree(pages);\r
535         }\r
536 \r
537         return status;\r
538     }\r
539     while(0);\r
540 \r
541     \r
542     /* Free the page table */        \r
543     if (pages != NULL) {\r
544         kfree(pages);\r
545     }\r
546 \r
547     /* Free MMU table */\r
548     if(MMU_Base != NULL) {\r
549         kfree(MMU_Base);\r
550     }\r
551 \r
552     return status;\r
553 }\r
554 \r
555 static int rga_mmu_info_color_palette_mode(struct rga_reg *reg, struct rga_req *req)\r
556 {\r
557     int SrcMemSize, DstMemSize, CMDMemSize;\r
558     uint32_t SrcStart, DstStart, CMDStart;\r
559     struct page **pages = NULL;\r
560     uint32_t i;\r
561     uint32_t AllSize;\r
562     uint32_t *MMU_Base = NULL;\r
563     uint32_t *MMU_p;\r
564     int ret, status;\r
565     uint32_t stride;\r
566 \r
567     uint8_t shift;\r
568     uint16_t sw, byte_num;\r
569     \r
570     shift = 3 - (req->palette_mode & 3);\r
571     sw = req->src.vir_w;\r
572     byte_num = sw >> shift;\r
573     stride = (byte_num + 3) & (~3);\r
574 \r
575     do\r
576     {\r
577                          \r
578         SrcMemSize = rga_mem_size_cal(req->src.yrgb_addr, stride, &SrcStart);\r
579         if(SrcMemSize == 0) {\r
580             return -EINVAL;                \r
581         }\r
582 \r
583         DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
584                                         req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
585                                         &DstStart);\r
586         if(DstMemSize == 0) {\r
587             return -EINVAL; \r
588         }\r
589 \r
590         CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);\r
591         if(CMDMemSize == 0) {\r
592             return -EINVAL; \r
593         }\r
594 \r
595         AllSize = SrcMemSize + DstMemSize + CMDMemSize;\r
596                    \r
597         pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
598         if(pages == NULL) {\r
599             pr_err("RGA MMU malloc pages mem failed\n");\r
600             return -EINVAL;                \r
601         }\r
602 \r
603         MMU_Base = kzalloc(AllSize * sizeof(uint32_t), GFP_KERNEL);\r
604         if(MMU_Base == NULL) {\r
605             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
606             break;            \r
607         }\r
608 \r
609         /* map CMD addr */\r
610         for(i=0; i<CMDMemSize; i++) \r
611         {\r
612             MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i)<<PAGE_SHIFT));\r
613         }\r
614 \r
615         /* map src addr */\r
616         if (req->src.yrgb_addr < KERNEL_SPACE_VALID) \r
617         {            \r
618             ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
619             if (ret < 0) \r
620             {\r
621                 pr_err("rga map src memory failed\n");\r
622                 status = ret;\r
623                 break;            \r
624             }\r
625         }\r
626         else\r
627         {\r
628             MMU_p = MMU_Base + CMDMemSize;\r
629             \r
630             for(i=0; i<SrcMemSize; i++)\r
631             {\r
632                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
633             }\r
634         }\r
635 \r
636         /* map dst addr */\r
637         if (req->src.yrgb_addr < KERNEL_SPACE_VALID) \r
638         {\r
639             ret = rga_MapUserMemory(&pages[CMDMemSize + SrcMemSize], &MMU_Base[CMDMemSize + SrcMemSize], DstStart, DstMemSize);\r
640             if (ret < 0) \r
641             {\r
642                 pr_err("rga map dst memory failed\n");\r
643                 status = ret;\r
644                 break;\r
645             }\r
646         }\r
647         else\r
648         {\r
649             MMU_p = MMU_Base + CMDMemSize + SrcMemSize;\r
650             \r
651             for(i=0; i<DstMemSize; i++)\r
652             {\r
653                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT));\r
654             }\r
655         }\r
656         \r
657 \r
658         /* zsq \r
659          * change the buf address in req struct\r
660          * for the reason of lie to MMU \r
661          */\r
662         req->mmu_info.base_addr = (virt_to_phys(MMU_Base)>>2);    \r
663         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
664         req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((CMDMemSize + SrcMemSize) << PAGE_SHIFT);\r
665 \r
666 \r
667         /*record the malloc buf for the cmd end to release*/\r
668         reg->MMU_base = MMU_Base;\r
669 \r
670         /* flush data to DDR */\r
671         dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
672         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));\r
673 \r
674         /* Free the page table */\r
675         if (pages != NULL) {            \r
676             kfree(pages);\r
677         }\r
678 \r
679         return status;\r
680 \r
681     }\r
682     while(0);\r
683 \r
684     /* Free the page table */\r
685     if (pages != NULL) {            \r
686         kfree(pages);\r
687     }\r
688 \r
689     /* Free mmu table */\r
690     if (MMU_Base != NULL) {\r
691         kfree(MMU_Base);\r
692     }\r
693 \r
694     return 0;\r
695 }\r
696 \r
697 static int rga_mmu_info_color_fill_mode(struct rga_reg *reg, struct rga_req *req)\r
698 {\r
699     int DstMemSize;\r
700     uint32_t DstStart;\r
701     struct page **pages = NULL;\r
702     uint32_t i;\r
703     uint32_t AllSize;\r
704     uint32_t *MMU_Base, *MMU_p;\r
705     int ret;\r
706     int status;\r
707 \r
708     MMU_Base = NULL;\r
709 \r
710     do\r
711     {                         \r
712         DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
713                                         req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
714                                         &DstStart);\r
715         if(DstMemSize == 0) {\r
716             return -EINVAL; \r
717         }\r
718 \r
719         AllSize = DstMemSize;\r
720                    \r
721         pages = kzalloc((AllSize + 1)* sizeof(struct page *), GFP_KERNEL);\r
722         if(pages == NULL) {\r
723             pr_err("RGA MMU malloc pages mem failed\n");\r
724             status = RGA_MALLOC_ERROR; \r
725             break;\r
726         }\r
727         \r
728         MMU_Base = kzalloc((AllSize + 1) * sizeof(uint32_t), GFP_KERNEL);\r
729         if(pages == NULL) {\r
730             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
731             status = RGA_MALLOC_ERROR;\r
732             break;                \r
733         }\r
734 \r
735         if (req->dst.yrgb_addr < KERNEL_SPACE_VALID) \r
736         {\r
737             ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], DstStart, DstMemSize);\r
738             if (ret < 0) {\r
739                 pr_err("rga map dst memory failed\n");\r
740                 status = ret;\r
741                 break;\r
742             }\r
743         }\r
744         else\r
745         {\r
746             MMU_p = MMU_Base;\r
747             \r
748             for(i=0; i<DstMemSize; i++)\r
749             {\r
750                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT));\r
751             }\r
752         }\r
753 \r
754         MMU_Base[AllSize] = MMU_Base[AllSize - 1];        \r
755                             \r
756         /* zsq \r
757          * change the buf address in req struct \r
758          */\r
759          \r
760         req->mmu_info.base_addr = (virt_to_phys(MMU_Base)>>2);    \r
761         req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK));\r
762                \r
763         /*record the malloc buf for the cmd end to release*/\r
764         reg->MMU_base = MMU_Base;\r
765 \r
766         /* flush data to DDR */\r
767         dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
768         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));\r
769 \r
770         /* Free the page table */\r
771         if (pages != NULL)             \r
772             kfree(pages);\r
773 \r
774         return 0;\r
775     }\r
776     while(0);\r
777 \r
778     if (pages != NULL)    \r
779         kfree(pages);\r
780 \r
781     if (MMU_Base != NULL)\r
782         kfree(MMU_Base);\r
783     \r
784     return status;\r
785 }\r
786 \r
787 \r
788 static int rga_mmu_info_line_point_drawing_mode(struct rga_reg *reg, struct rga_req *req)\r
789 {\r
790     int DstMemSize;\r
791     uint32_t DstStart;\r
792     struct page **pages = NULL;\r
793     uint32_t i;\r
794     uint32_t AllSize;\r
795     uint32_t *MMU_Base, *MMU_p;\r
796     int ret, status;\r
797 \r
798     MMU_Base = NULL;\r
799 \r
800     do\r
801     {    \r
802         /* cal dst buf mmu info */                     \r
803         DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
804                                         req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
805                                         &DstStart);\r
806         if(DstMemSize == 0) {\r
807             return -EINVAL; \r
808         }\r
809 \r
810         AllSize = DstMemSize;\r
811                    \r
812         pages = kzalloc((AllSize + 1) * sizeof(struct page *), GFP_KERNEL);\r
813         if(pages == NULL) {\r
814             pr_err("RGA MMU malloc pages mem failed\n");\r
815             status = RGA_MALLOC_ERROR;\r
816             break;\r
817         }\r
818         \r
819         MMU_Base = kzalloc((AllSize + 1) * sizeof(uint32_t), GFP_KERNEL);\r
820         if(pages == NULL) {\r
821             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
822             status = RGA_MALLOC_ERROR;\r
823             break;\r
824         }\r
825 \r
826         if (req->dst.yrgb_addr < KERNEL_SPACE_VALID)\r
827         {\r
828             ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], DstStart, DstMemSize);\r
829             if (ret < 0) {\r
830                 pr_err("rga map dst memory failed\n");\r
831                 status = ret;\r
832                 break;\r
833             }\r
834         }\r
835         else\r
836         {\r
837             MMU_p = MMU_Base;\r
838             \r
839             for(i=0; i<DstMemSize; i++)\r
840             {\r
841                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT));\r
842             }\r
843         }\r
844 \r
845         /* zsq \r
846          * change the buf address in req struct\r
847          * for the reason of lie to MMU \r
848          */\r
849         req->mmu_info.base_addr = (virt_to_phys(MMU_Base) >> 2);    \r
850         req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK));\r
851        \r
852         \r
853         /*record the malloc buf for the cmd end to release*/\r
854         reg->MMU_base = MMU_Base;\r
855 \r
856         /* flush data to DDR */\r
857         dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
858         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));\r
859 \r
860         /* Free the page table */\r
861         if (pages != NULL) {            \r
862             kfree(pages);\r
863         } \r
864 \r
865         return 0;\r
866 \r
867     }\r
868     while(0);\r
869 \r
870     if (pages != NULL)\r
871         kfree(pages);\r
872 \r
873     if (MMU_Base != NULL)\r
874         kfree(MMU_Base);\r
875 \r
876     return status;\r
877 }\r
878 \r
879 static int rga_mmu_info_blur_sharp_filter_mode(struct rga_reg *reg, struct rga_req *req)\r
880 {\r
881     int SrcMemSize, DstMemSize;\r
882     uint32_t SrcStart, DstStart;\r
883     struct page **pages = NULL;\r
884     uint32_t i;\r
885     uint32_t AllSize;\r
886     uint32_t *MMU_Base, *MMU_p;\r
887     int ret, status;\r
888     uint32_t uv_size, v_size;\r
889 \r
890     MMU_Base = NULL;\r
891     \r
892     do\r
893     {\r
894         /* cal src buf mmu info */                     \r
895         SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr,\r
896                                         req->src.format, req->src.vir_w, req->src.vir_h,\r
897                                         &SrcStart);\r
898         if(SrcMemSize == 0) {\r
899             return -EINVAL;                \r
900         }\r
901 \r
902         /* cal dst buf mmu info */    \r
903         DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
904                                         req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
905                                         &DstStart);\r
906         if(DstMemSize == 0) {\r
907             return -EINVAL; \r
908         }\r
909 \r
910         AllSize = SrcMemSize + DstMemSize;\r
911                    \r
912         pages = kzalloc((AllSize + 1) * sizeof(struct page *), GFP_KERNEL);\r
913         if(pages == NULL) {\r
914             pr_err("RGA MMU malloc pages mem failed\n");\r
915             status = RGA_MALLOC_ERROR;\r
916             break;    \r
917         }\r
918         \r
919         MMU_Base = kzalloc((AllSize + 1)* sizeof(uint32_t), GFP_KERNEL);\r
920         if(pages == NULL) {\r
921             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
922             status = RGA_MALLOC_ERROR;\r
923             break;   \r
924         }\r
925 \r
926         if (req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
927         {\r
928             ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize);\r
929             if (ret < 0) \r
930             {\r
931                 pr_err("rga map src memory failed\n");\r
932                 status = ret;\r
933                 break;\r
934             }\r
935         }\r
936         else\r
937         {\r
938             MMU_p = MMU_Base;\r
939             \r
940             for(i=0; i<SrcMemSize; i++)\r
941             {\r
942                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
943             }            \r
944         }\r
945 \r
946         \r
947         if (req->dst.yrgb_addr < KERNEL_SPACE_VALID)\r
948         {\r
949             ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize);\r
950             if (ret < 0) \r
951             {\r
952                 pr_err("rga map dst memory failed\n");\r
953                 status = ret;\r
954                 break;\r
955             }\r
956         }\r
957         else\r
958         {\r
959             MMU_p = MMU_Base + SrcMemSize;\r
960             \r
961             for(i=0; i<DstMemSize; i++)\r
962             {\r
963                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT));\r
964             }\r
965         }\r
966 \r
967         MMU_Base[AllSize] = MMU_Base[AllSize - 1];\r
968 \r
969         /* zsq \r
970          * change the buf address in req struct\r
971          * for the reason of lie to MMU \r
972          */\r
973         req->mmu_info.base_addr = (virt_to_phys(MMU_Base) >> 2);\r
974 \r
975         uv_size = (req->src.uv_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
976         v_size = (req->src.v_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
977         \r
978         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK));\r
979         req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (uv_size << PAGE_SHIFT);\r
980         req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (v_size << PAGE_SHIFT);\r
981 \r
982         uv_size = (req->dst.uv_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
983         v_size = (req->dst.v_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
984 \r
985         req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | (SrcMemSize << PAGE_SHIFT);\r
986         req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((SrcMemSize + uv_size) << PAGE_SHIFT);\r
987         req->dst.v_addr = (req->dst.v_addr & (~PAGE_MASK)) | ((SrcMemSize + v_size) << PAGE_SHIFT);\r
988         \r
989         \r
990         /*record the malloc buf for the cmd end to release*/\r
991         reg->MMU_base = MMU_Base;\r
992 \r
993         /* flush data to DDR */\r
994         dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
995         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));\r
996 \r
997         /* Free the page table */\r
998         if (pages != NULL) {        \r
999             kfree(pages);\r
1000         }  \r
1001 \r
1002         return 0;\r
1003     }\r
1004     while(0);\r
1005 \r
1006     if (pages != NULL)\r
1007         kfree(pages);\r
1008 \r
1009     if (MMU_Base != NULL)\r
1010         kfree(MMU_Base);\r
1011 \r
1012     return status;\r
1013 }\r
1014 \r
1015 \r
1016 \r
1017 static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req)\r
1018 {\r
1019     int SrcMemSize, DstMemSize;\r
1020     uint32_t SrcStart, DstStart;\r
1021     struct page **pages = NULL;\r
1022     uint32_t i;\r
1023     uint32_t AllSize;\r
1024     uint32_t *MMU_Base, *MMU_p;\r
1025     int ret;\r
1026     int status;\r
1027     uint32_t uv_size, v_size;\r
1028 \r
1029     MMU_Base = NULL;\r
1030 \r
1031     do\r
1032     {\r
1033         /* cal src buf mmu info */                     \r
1034         SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr,\r
1035                                         req->src.format, req->src.vir_w, req->src.vir_h,\r
1036                                         &SrcStart);\r
1037         if(SrcMemSize == 0) {\r
1038             return -EINVAL;                \r
1039         }\r
1040 \r
1041         /* cal dst buf mmu info */    \r
1042         DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
1043                                         req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
1044                                         &DstStart);\r
1045         if(DstMemSize == 0) {\r
1046             return -EINVAL; \r
1047         }\r
1048 \r
1049         AllSize = SrcMemSize + DstMemSize;\r
1050                    \r
1051         pages = kzalloc((AllSize)* sizeof(struct page *), GFP_KERNEL);\r
1052         if(pages == NULL) \r
1053         {\r
1054             pr_err("RGA MMU malloc pages mem failed\n");\r
1055             status = RGA_MALLOC_ERROR;\r
1056             break;                \r
1057         }\r
1058 \r
1059         /* \r
1060          * Allocate MMU Index mem\r
1061          * This mem release in run_to_done fun \r
1062          */\r
1063         MMU_Base = kzalloc((AllSize + 1) * sizeof(uint32_t), GFP_KERNEL);\r
1064         if(pages == NULL) {\r
1065             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
1066             status = RGA_MALLOC_ERROR;            \r
1067             break;                \r
1068         }\r
1069 \r
1070         /* map src pages */\r
1071         if (req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
1072         {\r
1073             ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize);\r
1074             if (ret < 0) {\r
1075                 pr_err("rga map src memory failed\n");\r
1076                 status = ret;\r
1077                 break;\r
1078             }\r
1079         }\r
1080         else\r
1081         {\r
1082             MMU_p = MMU_Base;\r
1083             \r
1084             for(i=0; i<SrcMemSize; i++)\r
1085             {\r
1086                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
1087             } \r
1088         }\r
1089 \r
1090         \r
1091         if(req->dst.yrgb_addr >= KERNEL_SPACE_VALID) \r
1092         {   \r
1093             /* kernel space */\r
1094             MMU_p = MMU_Base + SrcMemSize;\r
1095 \r
1096             if(req->dst.yrgb_addr == (uint32_t)rga_service.pre_scale_buf)\r
1097             {\r
1098                 for(i=0; i<DstMemSize; i++)\r
1099                 {\r
1100                     MMU_p[i] = rga_service.pre_scale_buf[i];\r
1101                 }\r
1102             }\r
1103             else\r
1104             {\r
1105                 for(i=0; i<DstMemSize; i++) \r
1106                 {\r
1107                     MMU_p[i] = virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT));        \r
1108                 }    \r
1109             }                                    \r
1110         }\r
1111         else \r
1112         {\r
1113             /* user space */\r
1114             ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize);\r
1115             if (ret < 0) \r
1116             {\r
1117                 pr_err("rga map dst memory failed\n");\r
1118                 status = ret;\r
1119                 break;\r
1120             }        \r
1121         }\r
1122 \r
1123         MMU_Base[AllSize] = MMU_Base[AllSize - 1];\r
1124 \r
1125         /* zsq \r
1126          * change the buf address in req struct\r
1127          * for the reason of lie to MMU \r
1128          */\r
1129         \r
1130         req->mmu_info.base_addr = (virt_to_phys(MMU_Base)>>2);\r
1131 \r
1132         uv_size = (req->src.uv_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
1133         v_size = (req->src.v_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
1134 \r
1135         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK));\r
1136         req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (uv_size << PAGE_SHIFT);\r
1137         req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (v_size << PAGE_SHIFT);\r
1138 \r
1139         uv_size = (req->dst.uv_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
1140         v_size = (req->dst.v_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
1141 \r
1142         req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((SrcMemSize) << PAGE_SHIFT);\r
1143         req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((SrcMemSize + uv_size) << PAGE_SHIFT);\r
1144         req->dst.v_addr = (req->dst.v_addr & (~PAGE_MASK)) | ((SrcMemSize + v_size) << PAGE_SHIFT);\r
1145 \r
1146         /*record the malloc buf for the cmd end to release*/\r
1147         reg->MMU_base = MMU_Base;\r
1148 \r
1149         /* flush data to DDR */\r
1150         dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
1151         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));\r
1152 \r
1153         /* Free the page table */\r
1154         if (pages != NULL) \r
1155         {            \r
1156             kfree(pages);\r
1157         }  \r
1158 \r
1159         return 0;\r
1160     }\r
1161     while(0);\r
1162 \r
1163     if (pages != NULL)\r
1164         kfree(pages);\r
1165 \r
1166     if (MMU_Base != NULL)\r
1167         kfree(MMU_Base);\r
1168 \r
1169     return status;\r
1170 }\r
1171 \r
1172 \r
1173 static int rga_mmu_info_update_palette_table_mode(struct rga_reg *reg, struct rga_req *req)\r
1174 {\r
1175     int SrcMemSize, CMDMemSize;\r
1176     uint32_t SrcStart, CMDStart;\r
1177     struct page **pages = NULL;\r
1178     uint32_t i;\r
1179     uint32_t AllSize;\r
1180     uint32_t *MMU_Base, *MMU_p;\r
1181     int ret, status;\r
1182 \r
1183     MMU_Base = NULL;\r
1184 \r
1185     do\r
1186     {    \r
1187         /* cal src buf mmu info */                     \r
1188         SrcMemSize = rga_mem_size_cal(req->src.yrgb_addr, req->src.vir_w * req->src.vir_h, &SrcStart);\r
1189         if(SrcMemSize == 0) {\r
1190             return -EINVAL;                \r
1191         }\r
1192 \r
1193         /* cal cmd buf mmu info */\r
1194         CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);\r
1195         if(CMDMemSize == 0) {\r
1196             return -EINVAL; \r
1197         }\r
1198 \r
1199         AllSize = SrcMemSize + CMDMemSize;\r
1200                    \r
1201         pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
1202         if(pages == NULL) {\r
1203             pr_err("RGA MMU malloc pages mem failed\n");\r
1204             status = RGA_MALLOC_ERROR;\r
1205             break;    \r
1206         }\r
1207         \r
1208         MMU_Base = kzalloc((AllSize + 1)* sizeof(uint32_t), GFP_KERNEL);\r
1209         if(pages == NULL) {\r
1210             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
1211             status = RGA_MALLOC_ERROR;\r
1212             break;                \r
1213         }\r
1214 \r
1215         for(i=0; i<CMDMemSize; i++) {\r
1216             MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i) << PAGE_SHIFT));\r
1217         }\r
1218 \r
1219         if (req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
1220         {\r
1221             ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
1222             if (ret < 0) {\r
1223                 pr_err("rga map src memory failed\n");\r
1224                 return -EINVAL;\r
1225             }\r
1226         }\r
1227         else\r
1228         {\r
1229             MMU_p = MMU_Base + CMDMemSize;\r
1230                 \r
1231                 for(i=0; i<SrcMemSize; i++)\r
1232                 {\r
1233                     MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
1234                 } \r
1235         }\r
1236 \r
1237         /* zsq \r
1238          * change the buf address in req struct\r
1239          * for the reason of lie to MMU \r
1240          */\r
1241         req->mmu_info.base_addr = (virt_to_phys(MMU_Base) >> 2);\r
1242         \r
1243         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);    \r
1244         \r
1245         /*record the malloc buf for the cmd end to release*/\r
1246         reg->MMU_base = MMU_Base;\r
1247 \r
1248         /* flush data to DDR */\r
1249         dmac_flush_range(MMU_Base, (MMU_Base + AllSize));\r
1250         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize));\r
1251 \r
1252         if (pages != NULL) {\r
1253             /* Free the page table */\r
1254             kfree(pages);\r
1255         }  \r
1256 \r
1257         return 0;\r
1258     }\r
1259     while(0);\r
1260 \r
1261     if (pages != NULL)\r
1262         kfree(pages);\r
1263 \r
1264     if (MMU_Base != NULL)\r
1265         kfree(MMU_Base);\r
1266 \r
1267     return status;\r
1268 }\r
1269 \r
1270 static int rga_mmu_info_update_patten_buff_mode(struct rga_reg *reg, struct rga_req *req)\r
1271 {\r
1272     int SrcMemSize, CMDMemSize;\r
1273     uint32_t SrcStart, CMDStart;\r
1274     struct page **pages = NULL;\r
1275     uint32_t i;\r
1276     uint32_t AllSize;\r
1277     uint32_t *MMU_Base, *MMU_p;\r
1278     int ret, status;\r
1279 \r
1280     MMU_Base = MMU_p = 0;\r
1281 \r
1282     do\r
1283     {\r
1284 \r
1285         /* cal src buf mmu info */                     \r
1286         SrcMemSize = rga_mem_size_cal(req->pat.yrgb_addr, req->pat.vir_w * req->pat.vir_h * 4, &SrcStart);\r
1287         if(SrcMemSize == 0) {\r
1288             return -EINVAL;                \r
1289         }\r
1290 \r
1291         /* cal cmd buf mmu info */\r
1292         CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);\r
1293         if(CMDMemSize == 0) {\r
1294             return -EINVAL; \r
1295         }\r
1296 \r
1297         AllSize = SrcMemSize + CMDMemSize;\r
1298                    \r
1299         pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
1300         if(pages == NULL) {\r
1301             pr_err("RGA MMU malloc pages mem failed\n");\r
1302             status = RGA_MALLOC_ERROR;\r
1303             break;                \r
1304         }\r
1305         \r
1306         MMU_Base = kzalloc(AllSize * sizeof(uint32_t), GFP_KERNEL);\r
1307         if(pages == NULL) {\r
1308             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
1309             status = RGA_MALLOC_ERROR;\r
1310             break;                \r
1311         }\r
1312 \r
1313         for(i=0; i<CMDMemSize; i++) {\r
1314             MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i) << PAGE_SHIFT));\r
1315         }\r
1316 \r
1317         if (req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
1318         {\r
1319             ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
1320             if (ret < 0) {\r
1321                 pr_err("rga map src memory failed\n");\r
1322                 status = ret;\r
1323                 break;\r
1324             }\r
1325         }\r
1326         else\r
1327         {\r
1328             MMU_p = MMU_Base + CMDMemSize;\r
1329                 \r
1330             for(i=0; i<SrcMemSize; i++)\r
1331             {\r
1332                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
1333             } \r
1334         }\r
1335 \r
1336         /* zsq \r
1337          * change the buf address in req struct\r
1338          * for the reason of lie to MMU \r
1339          */\r
1340         req->mmu_info.base_addr = (virt_to_phys(MMU_Base) >> 2);\r
1341         \r
1342         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);    \r
1343         \r
1344         /*record the malloc buf for the cmd end to release*/\r
1345         reg->MMU_base = MMU_Base;\r
1346 \r
1347         /* flush data to DDR */\r
1348         dmac_flush_range(MMU_Base, (MMU_Base + AllSize));\r
1349         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize));\r
1350 \r
1351         if (pages != NULL) {\r
1352             /* Free the page table */\r
1353             kfree(pages);\r
1354         }\r
1355 \r
1356         return 0;\r
1357 \r
1358     }\r
1359     while(0);\r
1360 \r
1361     if (pages != NULL)\r
1362         kfree(pages);\r
1363 \r
1364     if (MMU_Base != NULL)\r
1365         kfree(MMU_Base);\r
1366 \r
1367     return status;\r
1368 }\r
1369 \r
1370 int rga_set_mmu_info(struct rga_reg *reg, struct rga_req *req)\r
1371 {    \r
1372     int ret;\r
1373                \r
1374     switch (req->render_mode) {\r
1375         case bitblt_mode :            \r
1376             ret = rga_mmu_info_BitBlt_mode(reg, req);\r
1377             break;\r
1378         case color_palette_mode :\r
1379             ret = rga_mmu_info_color_palette_mode(reg, req);\r
1380             break;\r
1381         case color_fill_mode :\r
1382             ret = rga_mmu_info_color_fill_mode(reg, req);\r
1383             break;\r
1384         case line_point_drawing_mode :\r
1385             ret = rga_mmu_info_line_point_drawing_mode(reg, req);\r
1386             break;\r
1387         case blur_sharp_filter_mode :\r
1388             ret = rga_mmu_info_blur_sharp_filter_mode(reg, req);\r
1389             break;\r
1390         case pre_scaling_mode :\r
1391             ret = rga_mmu_info_pre_scale_mode(reg, req);\r
1392             break;\r
1393         case update_palette_table_mode :\r
1394             ret = rga_mmu_info_update_palette_table_mode(reg, req);\r
1395             break;\r
1396         case update_patten_buff_mode :\r
1397             ret = rga_mmu_info_update_patten_buff_mode(reg, req);\r
1398             break;\r
1399         default :\r
1400             ret = -1;\r
1401             break;\r
1402     }\r
1403 \r
1404     return ret;\r
1405 }\r
1406 \r