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