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