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