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