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