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