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