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