add prescale mode | dim mode support
[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     uint32_t Address;\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                 vma = find_vma(current->mm, (Memory + i) << PAGE_SHIFT);\r
245 \r
246                 if (vma && (vma->vm_flags & VM_PFNMAP) )\r
247                 {\r
248                     do\r
249                     {\r
250                         pte_t       * pte;\r
251                         spinlock_t  * ptl;\r
252                         unsigned long pfn;\r
253 \r
254                         pgd_t * pgd = pgd_offset(current->mm, ((Memory + i)<< PAGE_SHIFT));\r
255                         pud_t * pud = pud_offset(pgd, ((Memory + i) << PAGE_SHIFT));\r
256                         if (pud)\r
257                         {\r
258                             pmd_t * pmd = pmd_offset(pud, ((Memory + i) << PAGE_SHIFT));\r
259                             if (pmd)\r
260                             {\r
261                                 pte = pte_offset_map_lock(current->mm, pmd, ((Memory + i)<< PAGE_SHIFT), &ptl);\r
262                                 if (!pte)\r
263                                 {\r
264                                     break;\r
265                                 }\r
266                             }\r
267                             else\r
268                             {\r
269                                 break;\r
270                             }\r
271                         }\r
272                         else\r
273                         {\r
274                             break;\r
275                         }\r
276 \r
277                         pfn      = pte_pfn(*pte);\r
278 \r
279                         Address = ((pfn << PAGE_SHIFT) | (((unsigned long)((Memory + i) << PAGE_SHIFT)) & ~PAGE_MASK));\r
280                         \r
281                         pte_unmap_unlock(pte, ptl);\r
282 \r
283                         /* Free the page table. */\r
284                         if (pages != NULL)\r
285                         {\r
286                             /* Release the pages if any. */\r
287                             if (result > 0)\r
288                             {\r
289                                 for (i = 0; i < result; i++)\r
290                                 {\r
291                                     if (pages[i] == NULL)\r
292                                     {\r
293                                         break;\r
294                                     }\r
295 \r
296                                     page_cache_release(pages[i]);\r
297                                 }\r
298                             }\r
299                         }\r
300                         \r
301                         pageTable[i] = Address;\r
302                     }\r
303                     while (0);\r
304                 }\r
305                 else\r
306                 {\r
307                     status = RGA_OUT_OF_RESOURCES;\r
308                     break;\r
309                 }     \r
310             }\r
311 \r
312             return 0;\r
313         }\r
314 \r
315         for (i = 0; i < pageCount; i++)\r
316         {\r
317             /* Flush the data cache. */\r
318 #ifdef ANDROID\r
319             dma_sync_single_for_device(\r
320                         NULL,\r
321                         page_to_phys(pages[i]),\r
322                         PAGE_SIZE,\r
323                         DMA_TO_DEVICE);\r
324 #else\r
325             flush_dcache_page(pages[i]);\r
326 #endif\r
327         }\r
328 \r
329         /* Fill the page table. */\r
330         for(i=0; i<pageCount; i++) \r
331         {\r
332             /* Get the physical address from page struct. */\r
333             pageTable[i] = page_to_phys(pages[i]);\r
334         }    \r
335     }\r
336     while(0);\r
337 \r
338     if (rgaIS_ERROR(status))\r
339     {\r
340         /* Release page array. */\r
341         if (result > 0 && pages != NULL)\r
342         {\r
343             for (i = 0; i < result; i++)\r
344             {\r
345                 if (pages[i] == NULL)\r
346                 {\r
347                     break;\r
348                 }\r
349 #ifdef ANDROID\r
350                 dma_sync_single_for_device(\r
351                             NULL,\r
352                             page_to_phys(pages[i]),\r
353                             PAGE_SIZE,\r
354                             DMA_FROM_DEVICE);\r
355 #endif\r
356                 page_cache_release(pages[i]);\r
357             }\r
358         }\r
359     }\r
360 \r
361     return status;\r
362 }\r
363 \r
364 static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req)\r
365 {    \r
366     int SrcMemSize, DstMemSize, CMDMemSize;\r
367     uint32_t SrcStart, DstStart, CMDStart;   \r
368     uint32_t i;\r
369     uint32_t AllSize;\r
370     uint32_t *MMU_Base, *MMU_p;\r
371     int ret;\r
372     int status;\r
373 \r
374     struct page **pages = NULL;\r
375 \r
376     MMU_Base = NULL;\r
377 \r
378     do\r
379     {               \r
380         /* cal src buf mmu info */                     \r
381         SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr,\r
382                                         req->src.format, req->src.vir_w, req->src.vir_h,\r
383                                         &SrcStart);\r
384         if(SrcMemSize == 0) {\r
385             return -EINVAL;                \r
386         }\r
387         \r
388 \r
389         /* cal dst buf mmu info */    \r
390         DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
391                                         req->dst.format, req->dst.vir_w, (req->dst.act_h + req->dst.y_offset),\r
392                                         &DstStart);\r
393         if(DstMemSize == 0) {\r
394             return -EINVAL; \r
395         }\r
396 \r
397         /* cal cmd buf mmu info */\r
398         CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);\r
399         if(CMDMemSize == 0) {\r
400             return -EINVAL; \r
401         }\r
402 \r
403         \r
404         /* Cal out the needed mem size */\r
405         AllSize = SrcMemSize + DstMemSize + CMDMemSize;\r
406                    \r
407         pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
408         if(pages == NULL) {\r
409             pr_err("RGA MMU malloc pages mem failed\n");\r
410             status = RGA_MALLOC_ERROR;\r
411             break;                \r
412         }\r
413         \r
414         MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL);\r
415         if(MMU_Base == NULL) {\r
416             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
417             status = RGA_MALLOC_ERROR;\r
418             break;                \r
419         }\r
420 \r
421         for(i=0; i<CMDMemSize; i++) {\r
422             MMU_Base[i] = (uint32_t)virt_to_phys((uint32_t *)((CMDStart + i) << PAGE_SHIFT));            \r
423         }\r
424 \r
425         if(req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
426         {\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\n");\r
431                 status = ret;\r
432                 break;\r
433             }\r
434             \r
435         }\r
436         else\r
437         {\r
438             MMU_p = MMU_Base + CMDMemSize;\r
439             \r
440             if(req->src.yrgb_addr == (uint32_t)rga_service.pre_scale_buf)\r
441             {\r
442                 /* Down scale ratio over 2, Last prc    */\r
443                 /* MMU table copy from pre scale table  */\r
444                 \r
445                 for(i=0; i<SrcMemSize; i++)\r
446                 {\r
447                     MMU_p[i] = rga_service.pre_scale_buf[i];\r
448                 }                \r
449             }\r
450             else\r
451             {                           \r
452                 for(i=0; i<SrcMemSize; i++)\r
453                 {\r
454                     MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
455                 }\r
456             }            \r
457         }\r
458         \r
459         if (req->dst.yrgb_addr < KERNEL_SPACE_VALID)\r
460         {\r
461             #if 0\r
462             ktime_t start, end;\r
463             start = ktime_get();\r
464             #endif\r
465             ret = rga_MapUserMemory(&pages[CMDMemSize + SrcMemSize], &MMU_Base[CMDMemSize + SrcMemSize], DstStart, DstMemSize);\r
466             if (ret < 0) {\r
467                 pr_err("rga map dst memory failed\n");\r
468                 status = ret;\r
469                 break;\r
470             }\r
471 \r
472             #if 0\r
473             end = ktime_get();\r
474             end = ktime_sub(end, start);\r
475             printk("dst mmu map time = %d\n", (int)ktime_to_us(end));\r
476             #endif\r
477         }\r
478         else\r
479         {\r
480             MMU_p = MMU_Base + CMDMemSize + SrcMemSize;\r
481             \r
482             for(i=0; i<DstMemSize; i++)\r
483             {\r
484                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT));\r
485             }       \r
486         }\r
487 \r
488         /* zsq \r
489          * change the buf address in req struct     \r
490          */\r
491         #if 0 \r
492         printk("CMDMemSize is %.8x\n", CMDMemSize);\r
493         printk("SrcMemSize is %.8x\n", SrcMemSize);\r
494         printk("DstMemSize is %.8x\n", DstMemSize);\r
495         printk("CMDStart is %.8x\n", CMDStart);\r
496         printk("SrcStart is %.8x\n", SrcStart);\r
497         printk("DstStart is %.8x\n", DstStart);\r
498         #endif\r
499         \r
500         req->mmu_info.base_addr = (virt_to_phys(MMU_Base)>>2);        \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 << PAGE_SHIFT);\r
504         req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (CMDMemSize << 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");\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");\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");\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");\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");\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");\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");\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 \r
891     MMU_Base = NULL;\r
892     \r
893     do\r
894     {\r
895         /* cal src buf mmu info */                     \r
896         SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr,\r
897                                         req->src.format, req->src.vir_w, req->src.vir_h,\r
898                                         &SrcStart);\r
899         if(SrcMemSize == 0) {\r
900             return -EINVAL;                \r
901         }\r
902 \r
903         /* cal dst buf mmu info */    \r
904         DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
905                                         req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
906                                         &DstStart);\r
907         if(DstMemSize == 0) {\r
908             return -EINVAL; \r
909         }\r
910 \r
911         /* cal cmd buf mmu info */\r
912         CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);\r
913         if(CMDMemSize == 0) {\r
914             return -EINVAL; \r
915         }\r
916 \r
917         AllSize = SrcMemSize + DstMemSize + CMDMemSize;\r
918                    \r
919         pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
920         if(pages == NULL) {\r
921             pr_err("RGA MMU malloc pages mem failed\n");\r
922             status = RGA_MALLOC_ERROR;\r
923             break;    \r
924         }\r
925         \r
926         MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL);\r
927         if(pages == NULL) {\r
928             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
929             status = RGA_MALLOC_ERROR;\r
930             break;   \r
931         }\r
932 \r
933         for(i=0; i<CMDMemSize; i++) {\r
934             MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i)<< PAGE_SHIFT));\r
935         }\r
936 \r
937         if (req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
938         {\r
939             ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
940             if (ret < 0) \r
941             {\r
942                 pr_err("rga map src memory failed\n");\r
943                 status = ret;\r
944                 break;\r
945             }\r
946         }\r
947         else\r
948         {\r
949             MMU_p = MMU_Base + CMDMemSize;\r
950             \r
951             for(i=0; i<SrcMemSize; i++)\r
952             {\r
953                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
954             }            \r
955         }\r
956 \r
957         \r
958         if (req->dst.yrgb_addr < KERNEL_SPACE_VALID)\r
959         {\r
960             ret = rga_MapUserMemory(&pages[CMDMemSize + SrcMemSize], &MMU_Base[CMDMemSize + SrcMemSize], DstStart, DstMemSize);\r
961             if (ret < 0) \r
962             {\r
963                 pr_err("rga map dst memory failed\n");\r
964                 status = ret;\r
965                 break;\r
966             }\r
967         }\r
968         else\r
969         {\r
970             MMU_p = MMU_Base + CMDMemSize + SrcMemSize;\r
971             \r
972             for(i=0; i<DstMemSize; i++)\r
973             {\r
974                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT));\r
975             }\r
976         }\r
977 \r
978         /* zsq \r
979          * change the buf address in req struct\r
980          * for the reason of lie to MMU \r
981          */\r
982         req->mmu_info.base_addr = (virt_to_phys(MMU_Base) >> 2);\r
983         \r
984         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
985         req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
986         req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
987 \r
988         req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((CMDMemSize + SrcMemSize) << PAGE_SHIFT);\r
989         \r
990         /*record the malloc buf for the cmd end to release*/\r
991         reg->MMU_base = MMU_Base;\r
992 \r
993         /* flush data to DDR */\r
994         dmac_flush_range(MMU_Base, (MMU_Base + AllSize));\r
995         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize));\r
996 \r
997         /* Free the page table */\r
998         if (pages != NULL) {        \r
999             kfree(pages);\r
1000         }  \r
1001 \r
1002         return 0;\r
1003     }\r
1004     while(0);\r
1005 \r
1006     if (pages != NULL)\r
1007         kfree(pages);\r
1008 \r
1009     if (MMU_Base != NULL)\r
1010         kfree(MMU_Base);\r
1011 \r
1012     return status;\r
1013 }\r
1014 \r
1015 \r
1016 \r
1017 static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req)\r
1018 {\r
1019     int SrcMemSize, DstMemSize, CMDMemSize;\r
1020     uint32_t SrcStart, DstStart, CMDStart;\r
1021     struct page **pages = NULL;\r
1022     uint32_t i;\r
1023     uint32_t AllSize;\r
1024     uint32_t *MMU_Base, *MMU_p;\r
1025     int ret;\r
1026     int status;\r
1027 \r
1028     MMU_Base = NULL;\r
1029 \r
1030     do\r
1031     {\r
1032         /* cal src buf mmu info */                     \r
1033         SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr,\r
1034                                         req->src.format, req->src.vir_w, req->src.vir_h,\r
1035                                         &SrcStart);\r
1036         if(SrcMemSize == 0) {\r
1037             return -EINVAL;                \r
1038         }\r
1039 \r
1040         /* cal dst buf mmu info */    \r
1041         DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
1042                                         req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
1043                                         &DstStart);\r
1044         if(DstMemSize == 0) {\r
1045             return -EINVAL; \r
1046         }\r
1047 \r
1048         /* cal cmd buf mmu info */\r
1049         CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);\r
1050         if(CMDMemSize == 0) {\r
1051             return -EINVAL; \r
1052         }\r
1053 \r
1054         AllSize = SrcMemSize + DstMemSize + CMDMemSize;\r
1055 \r
1056         \r
1057         #if 0\r
1058         printk("AllSize = %d\n", AllSize);\r
1059         printk("SrcSize = %d\n", SrcMemSize);\r
1060         printk("CMDSize = %d\n", CMDMemSize);\r
1061         printk("DstSize = %d\n", DstMemSize);\r
1062         printk("DstStart = %d\n", DstStart);\r
1063         #endif\r
1064                    \r
1065         pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
1066         if(pages == NULL) \r
1067         {\r
1068             pr_err("RGA MMU malloc pages mem failed\n");\r
1069             status = RGA_MALLOC_ERROR;\r
1070             break;                \r
1071         }\r
1072 \r
1073         /* \r
1074          * Allocate MMU Index mem\r
1075          * This mem release in run_to_done fun \r
1076          */\r
1077         MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL);\r
1078         if(pages == NULL) {\r
1079             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
1080             status = RGA_MALLOC_ERROR;            \r
1081             break;                \r
1082         }\r
1083 \r
1084         for(i=0; i<CMDMemSize; i++) {\r
1085             MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i) << PAGE_SHIFT));\r
1086         }\r
1087 \r
1088 \r
1089         /* map src pages */\r
1090         if (req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
1091         {\r
1092             ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
1093             if (ret < 0) {\r
1094                 pr_err("rga map src memory failed\n");\r
1095                 status = ret;\r
1096                 break;\r
1097             }\r
1098         }\r
1099         else\r
1100         {\r
1101             MMU_p = MMU_Base + CMDMemSize;\r
1102             \r
1103             for(i=0; i<SrcMemSize; i++)\r
1104             {\r
1105                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
1106             } \r
1107         }\r
1108 \r
1109         \r
1110         if(req->dst.yrgb_addr >= KERNEL_SPACE_VALID) \r
1111         {   \r
1112             /* kernel space */\r
1113             MMU_p = MMU_Base + CMDMemSize + SrcMemSize;\r
1114 \r
1115             if(req->dst.yrgb_addr == (uint32_t)rga_service.pre_scale_buf)\r
1116             {\r
1117                 for(i=0; i<DstMemSize; i++)\r
1118                 {\r
1119                     MMU_p[i] = rga_service.pre_scale_buf[i];\r
1120                 }\r
1121             }\r
1122             else\r
1123             {\r
1124                 for(i=0; i<DstMemSize; i++) \r
1125                 {\r
1126                     MMU_p[i] = virt_to_phys((uint32_t *)((DstStart + i)<< PAGE_SHIFT));        \r
1127                 }    \r
1128             }                                    \r
1129         }\r
1130         else \r
1131         {\r
1132             /* user space */\r
1133             ret = rga_MapUserMemory(&pages[CMDMemSize + SrcMemSize], &MMU_Base[CMDMemSize + SrcMemSize], DstStart, DstMemSize);\r
1134             if (ret < 0) \r
1135             {\r
1136                 pr_err("rga map dst memory failed\n");\r
1137                 status = ret;\r
1138                 break;\r
1139             }        \r
1140         }\r
1141 \r
1142         /* zsq \r
1143          * change the buf address in req struct\r
1144          * for the reason of lie to MMU \r
1145          */\r
1146         \r
1147         req->mmu_info.base_addr = (virt_to_phys(MMU_Base)>>2);\r
1148 \r
1149         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
1150         req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
1151         req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
1152 \r
1153         req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((CMDMemSize + SrcMemSize) << PAGE_SHIFT);\r
1154 \r
1155         /*record the malloc buf for the cmd end to release*/\r
1156         reg->MMU_base = MMU_Base;\r
1157 \r
1158         /* flush data to DDR */\r
1159         dmac_flush_range(MMU_Base, (MMU_Base + AllSize));\r
1160         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize));\r
1161 \r
1162         /* Free the page table */\r
1163         if (pages != NULL) \r
1164         {            \r
1165             kfree(pages);\r
1166         }  \r
1167 \r
1168         return 0;\r
1169     }\r
1170     while(0);\r
1171 \r
1172     if (pages != NULL)\r
1173         kfree(pages);\r
1174 \r
1175     if (MMU_Base != NULL)\r
1176         kfree(MMU_Base);\r
1177 \r
1178     return status;\r
1179 }\r
1180 \r
1181 \r
1182 static int rga_mmu_info_update_palette_table_mode(struct rga_reg *reg, struct rga_req *req)\r
1183 {\r
1184     int SrcMemSize, CMDMemSize;\r
1185     uint32_t SrcStart, CMDStart;\r
1186     struct page **pages = NULL;\r
1187     uint32_t i;\r
1188     uint32_t AllSize;\r
1189     uint32_t *MMU_Base, *MMU_p;\r
1190     int ret, status;\r
1191 \r
1192     MMU_Base = NULL;\r
1193 \r
1194     do\r
1195     {    \r
1196         /* cal src buf mmu info */                     \r
1197         SrcMemSize = rga_mem_size_cal(req->src.yrgb_addr, req->src.vir_w * req->src.vir_h, &SrcStart);\r
1198         if(SrcMemSize == 0) {\r
1199             return -EINVAL;                \r
1200         }\r
1201 \r
1202         /* cal cmd buf mmu info */\r
1203         CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);\r
1204         if(CMDMemSize == 0) {\r
1205             return -EINVAL; \r
1206         }\r
1207 \r
1208         AllSize = SrcMemSize + CMDMemSize;\r
1209                    \r
1210         pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
1211         if(pages == NULL) {\r
1212             pr_err("RGA MMU malloc pages mem failed\n");\r
1213             status = RGA_MALLOC_ERROR;\r
1214             break;    \r
1215         }\r
1216         \r
1217         MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL);\r
1218         if(pages == NULL) {\r
1219             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
1220             status = RGA_MALLOC_ERROR;\r
1221             break;                \r
1222         }\r
1223 \r
1224         for(i=0; i<CMDMemSize; i++) {\r
1225             MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i) << PAGE_SHIFT));\r
1226         }\r
1227 \r
1228         if (req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
1229         {\r
1230             ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
1231             if (ret < 0) {\r
1232                 pr_err("rga map src memory failed\n");\r
1233                 return -EINVAL;\r
1234             }\r
1235         }\r
1236         else\r
1237         {\r
1238             MMU_p = MMU_Base + CMDMemSize;\r
1239                 \r
1240                 for(i=0; i<SrcMemSize; i++)\r
1241                 {\r
1242                     MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
1243                 } \r
1244         }\r
1245 \r
1246         /* zsq \r
1247          * change the buf address in req struct\r
1248          * for the reason of lie to MMU \r
1249          */\r
1250         req->mmu_info.base_addr = (virt_to_phys(MMU_Base) >> 2);\r
1251         \r
1252         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);    \r
1253         \r
1254         /*record the malloc buf for the cmd end to release*/\r
1255         reg->MMU_base = MMU_Base;\r
1256 \r
1257         /* flush data to DDR */\r
1258         dmac_flush_range(MMU_Base, (MMU_Base + AllSize));\r
1259         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize));\r
1260 \r
1261         if (pages != NULL) {\r
1262             /* Free the page table */\r
1263             kfree(pages);\r
1264         }  \r
1265 \r
1266         return 0;\r
1267     }\r
1268     while(0);\r
1269 \r
1270     if (pages != NULL)\r
1271         kfree(pages);\r
1272 \r
1273     if (MMU_Base != NULL)\r
1274         kfree(MMU_Base);\r
1275 \r
1276     return status;\r
1277 }\r
1278 \r
1279 static int rga_mmu_info_update_patten_buff_mode(struct rga_reg *reg, struct rga_req *req)\r
1280 {\r
1281     int SrcMemSize, DstMemSize, CMDMemSize;\r
1282     uint32_t SrcStart, CMDStart;\r
1283     struct page **pages = NULL;\r
1284     uint32_t i;\r
1285     uint32_t AllSize;\r
1286     uint32_t *MMU_Base, *MMU_p;\r
1287     int ret, status;\r
1288 \r
1289     do\r
1290     {\r
1291 \r
1292         /* cal src buf mmu info */                     \r
1293         SrcMemSize = rga_mem_size_cal(req->pat.yrgb_addr, req->pat.vir_w * req->pat.vir_h * 4, &SrcStart);\r
1294         if(SrcMemSize == 0) {\r
1295             return -EINVAL;                \r
1296         }\r
1297 \r
1298         /* cal cmd buf mmu info */\r
1299         CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);\r
1300         if(CMDMemSize == 0) {\r
1301             return -EINVAL; \r
1302         }\r
1303 \r
1304         AllSize = SrcMemSize + DstMemSize + CMDMemSize;\r
1305                    \r
1306         pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
1307         if(pages == NULL) {\r
1308             pr_err("RGA MMU malloc pages mem failed\n");\r
1309             status = RGA_MALLOC_ERROR;\r
1310             break;                \r
1311         }\r
1312         \r
1313         MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL);\r
1314         if(pages == NULL) {\r
1315             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
1316             status = RGA_MALLOC_ERROR;\r
1317             break;                \r
1318         }\r
1319 \r
1320         for(i=0; i<CMDMemSize; i++) {\r
1321             MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i) << PAGE_SHIFT));\r
1322         }\r
1323 \r
1324         if (req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
1325         {\r
1326             ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
1327             if (ret < 0) {\r
1328                 pr_err("rga map src memory failed\n");\r
1329                 status = ret;\r
1330                 break;\r
1331             }\r
1332         }\r
1333         else\r
1334         {\r
1335             MMU_p = MMU_Base + CMDMemSize;\r
1336                 \r
1337             for(i=0; i<SrcMemSize; i++)\r
1338             {\r
1339                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
1340             } \r
1341         }\r
1342 \r
1343         /* zsq \r
1344          * change the buf address in req struct\r
1345          * for the reason of lie to MMU \r
1346          */\r
1347         req->mmu_info.base_addr = (virt_to_phys(MMU_Base) >> 2);\r
1348         \r
1349         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);    \r
1350         \r
1351         /*record the malloc buf for the cmd end to release*/\r
1352         reg->MMU_base = MMU_Base;\r
1353 \r
1354         /* flush data to DDR */\r
1355         dmac_flush_range(MMU_Base, (MMU_Base + AllSize));\r
1356         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize));\r
1357 \r
1358         if (pages != NULL) {\r
1359             /* Free the page table */\r
1360             kfree(pages);\r
1361         }\r
1362 \r
1363         return 0;\r
1364 \r
1365     }\r
1366     while(0);\r
1367 \r
1368     if (pages != NULL)\r
1369         kfree(pages);\r
1370 \r
1371     if (MMU_Base != NULL)\r
1372         kfree(MMU_Base);\r
1373 \r
1374     return status;\r
1375 }\r
1376 \r
1377 int rga_set_mmu_info(struct rga_reg *reg, struct rga_req *req)\r
1378 {    \r
1379     int ret;\r
1380                \r
1381     switch (req->render_mode) {\r
1382         case bitblt_mode :            \r
1383             ret = rga_mmu_info_BitBlt_mode(reg, req);\r
1384             break;\r
1385         case color_palette_mode :\r
1386             ret = rga_mmu_info_color_palette_mode(reg, req);\r
1387             break;\r
1388         case color_fill_mode :\r
1389             ret = rga_mmu_info_color_fill_mode(reg, req);\r
1390             break;\r
1391         case line_point_drawing_mode :\r
1392             ret = rga_mmu_info_line_point_drawing_mode(reg, req);\r
1393             break;\r
1394         case blur_sharp_filter_mode :\r
1395             ret = rga_mmu_info_blur_sharp_filter_mode(reg, req);\r
1396             break;\r
1397         case pre_scaling_mode :\r
1398             ret = rga_mmu_info_pre_scale_mode(reg, req);\r
1399             break;\r
1400         case update_palette_table_mode :\r
1401             ret = rga_mmu_info_update_palette_table_mode(reg, req);\r
1402             break;\r
1403         case update_patten_buff_mode :\r
1404             ret = rga_mmu_info_update_patten_buff_mode(reg, req);\r
1405             break;\r
1406         default :\r
1407             ret = -1;\r
1408             break;\r
1409     }\r
1410 \r
1411     return ret;\r
1412 }\r
1413 \r