Merge branch develop-3.10
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / rga2 / rga2_mmu_info.c
1 \r
2 \r
3 #include <linux/version.h>\r
4 #include <linux/init.h>\r
5 #include <linux/module.h>\r
6 #include <linux/fs.h>\r
7 #include <linux/sched.h>\r
8 #include <linux/signal.h>\r
9 #include <linux/pagemap.h>\r
10 #include <linux/seq_file.h>\r
11 #include <linux/mm.h>\r
12 #include <linux/mman.h>\r
13 #include <linux/sched.h>\r
14 #include <linux/slab.h>\r
15 #include <linux/memory.h>\r
16 #include <linux/dma-mapping.h>\r
17 #include <linux/scatterlist.h>\r
18 #include <asm/memory.h>\r
19 #include <asm/atomic.h>\r
20 #include <asm/cacheflush.h>\r
21 #include "rga2_mmu_info.h"\r
22 \r
23 extern struct rga2_service_info rga2_service;\r
24 extern struct rga2_mmu_buf_t rga2_mmu_buf;\r
25 \r
26 //extern int mmu_buff_temp[1024];\r
27 \r
28 #define KERNEL_SPACE_VALID    0xc0000000\r
29 \r
30 #define V7_VATOPA_SUCESS_MASK   (0x1)\r
31 #define V7_VATOPA_GET_PADDR(X)  (X & 0xFFFFF000)\r
32 #define V7_VATOPA_GET_INER(X)           ((X>>4) & 7)\r
33 #define V7_VATOPA_GET_OUTER(X)          ((X>>2) & 3)\r
34 #define V7_VATOPA_GET_SH(X)             ((X>>7) & 1)\r
35 #define V7_VATOPA_GET_NS(X)             ((X>>9) & 1)\r
36 #define V7_VATOPA_GET_SS(X)             ((X>>1) & 1)\r
37 \r
38 #if 0\r
39 static unsigned int armv7_va_to_pa(unsigned int v_addr)\r
40 {\r
41         unsigned int p_addr;\r
42         __asm__ volatile (      "mcr p15, 0, %1, c7, c8, 0\n"\r
43                                                 "isb\n"\r
44                                                 "dsb\n"\r
45                                                 "mrc p15, 0, %0, c7, c4, 0\n"\r
46                                                 : "=r" (p_addr)\r
47                                                 : "r" (v_addr)\r
48                                                 : "cc");\r
49 \r
50         if (p_addr & V7_VATOPA_SUCESS_MASK)\r
51                 return 0xFFFFFFFF;\r
52         else\r
53                 return (V7_VATOPA_GET_SS(p_addr) ? 0xFFFFFFFF : V7_VATOPA_GET_PADDR(p_addr));\r
54 }\r
55 #endif\r
56 \r
57 static int rga2_mmu_buf_get(struct rga2_mmu_buf_t *t, uint32_t size)\r
58 {\r
59     mutex_lock(&rga2_service.lock);\r
60     t->front += size;\r
61     mutex_unlock(&rga2_service.lock);\r
62 \r
63     return 0;\r
64 }\r
65 \r
66 static int rga2_mmu_buf_get_try(struct rga2_mmu_buf_t *t, uint32_t size)\r
67 {\r
68     mutex_lock(&rga2_service.lock);\r
69     if((t->back - t->front) > t->size) {\r
70         if(t->front + size > t->back - t->size)\r
71             return -1;\r
72     }\r
73     else {\r
74         if((t->front + size) > t->back)\r
75             return -1;\r
76 \r
77         if(t->front + size > t->size) {\r
78             if (size > (t->back - t->size)) {\r
79                 return -1;\r
80             }\r
81             t->front = 0;\r
82         }\r
83     }\r
84     mutex_unlock(&rga2_service.lock);\r
85 \r
86     return 0;\r
87 }\r
88 \r
89 static int rga2_mem_size_cal(unsigned long Mem, uint32_t MemSize, unsigned long *StartAddr)\r
90 {\r
91     unsigned long start, end;\r
92     uint32_t pageCount;\r
93 \r
94     end = (Mem + (MemSize + PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
95     start = Mem >> PAGE_SHIFT;\r
96     pageCount = end - start;\r
97     *StartAddr = start;\r
98     return pageCount;\r
99 }\r
100 \r
101 static int rga2_buf_size_cal(unsigned long yrgb_addr, unsigned long uv_addr, unsigned long v_addr,\r
102                                         int format, uint32_t w, uint32_t h, unsigned long *StartAddr )\r
103 {\r
104     uint32_t size_yrgb = 0;\r
105     uint32_t size_uv = 0;\r
106     uint32_t size_v = 0;\r
107     uint32_t stride = 0;\r
108     unsigned long start, end;\r
109     uint32_t pageCount;\r
110 \r
111     switch(format)\r
112     {\r
113         case RGA2_FORMAT_RGBA_8888 :\r
114             stride = (w * 4 + 3) & (~3);\r
115             size_yrgb = stride*h;\r
116             start = yrgb_addr >> PAGE_SHIFT;\r
117             pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT;\r
118             break;\r
119         case RGA2_FORMAT_RGBX_8888 :\r
120             stride = (w * 4 + 3) & (~3);\r
121             size_yrgb = stride*h;\r
122             start = yrgb_addr >> PAGE_SHIFT;\r
123             pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT;\r
124             break;\r
125         case RGA2_FORMAT_RGB_888 :\r
126             stride = (w * 3 + 3) & (~3);\r
127             size_yrgb = stride*h;\r
128             start = yrgb_addr >> PAGE_SHIFT;\r
129             pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT;\r
130             break;\r
131         case RGA2_FORMAT_BGRA_8888 :\r
132             size_yrgb = w*h*4;\r
133             start = yrgb_addr >> PAGE_SHIFT;\r
134             pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT;\r
135             break;\r
136         case RGA2_FORMAT_RGB_565 :\r
137             stride = (w*2 + 3) & (~3);\r
138             size_yrgb = stride * h;\r
139             start = yrgb_addr >> PAGE_SHIFT;\r
140             pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT;\r
141             break;\r
142         case RGA2_FORMAT_RGBA_5551 :\r
143             stride = (w*2 + 3) & (~3);\r
144             size_yrgb = stride * h;\r
145             start = yrgb_addr >> PAGE_SHIFT;\r
146             pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT;\r
147             break;\r
148         case RGA2_FORMAT_RGBA_4444 :\r
149             stride = (w*2 + 3) & (~3);\r
150             size_yrgb = stride * h;\r
151             start = yrgb_addr >> PAGE_SHIFT;\r
152             pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT;\r
153             break;\r
154         case RGA2_FORMAT_BGR_888 :\r
155             stride = (w*3 + 3) & (~3);\r
156             size_yrgb = stride * h;\r
157             start = yrgb_addr >> PAGE_SHIFT;\r
158             pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT;\r
159             break;\r
160 \r
161         /* YUV FORMAT */\r
162         case RGA2_FORMAT_YCbCr_422_SP :\r
163         case RGA2_FORMAT_YCrCb_422_SP :\r
164             stride = (w + 3) & (~3);\r
165             size_yrgb = stride * h;\r
166             size_uv = stride * h;\r
167             start = MIN(yrgb_addr, uv_addr);\r
168             start >>= PAGE_SHIFT;\r
169             end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv));\r
170             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
171             pageCount = end - start;\r
172             break;\r
173         case RGA2_FORMAT_YCbCr_422_P :\r
174         case RGA2_FORMAT_YCrCb_422_P :\r
175             stride = (w + 3) & (~3);\r
176             size_yrgb = stride * h;\r
177             size_uv = ((stride >> 1) * h);\r
178             size_v = ((stride >> 1) * h);\r
179             start = MIN(MIN(yrgb_addr, uv_addr), v_addr);\r
180             start = start >> PAGE_SHIFT;\r
181             end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v));\r
182             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
183             pageCount = end - start;\r
184             break;\r
185         case RGA2_FORMAT_YCbCr_420_SP :\r
186         case RGA2_FORMAT_YCrCb_420_SP :\r
187             stride = (w + 3) & (~3);\r
188             size_yrgb = stride * h;\r
189             size_uv = (stride * (h >> 1));\r
190             start = MIN(yrgb_addr, uv_addr);\r
191             start >>= PAGE_SHIFT;\r
192             end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv));\r
193             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
194             pageCount = end - start;\r
195             //printk("yrgb_addr = %.8x\n", yrgb_addr);\r
196             //printk("uv_addr = %.8x\n", uv_addr);\r
197             break;\r
198         case RGA2_FORMAT_YCbCr_420_P :\r
199         case RGA2_FORMAT_YCrCb_420_P :\r
200             stride = (w + 3) & (~3);\r
201             size_yrgb = stride * h;\r
202             size_uv = ((stride >> 1) * (h >> 1));\r
203             size_v = ((stride >> 1) * (h >> 1));\r
204             start = MIN(MIN(yrgb_addr, uv_addr), v_addr);\r
205             start >>= PAGE_SHIFT;\r
206             end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v));\r
207             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
208             pageCount = end - start;\r
209             break;\r
210         #if 0\r
211         case RK_FORMAT_BPP1 :\r
212             break;\r
213         case RK_FORMAT_BPP2 :\r
214             break;\r
215         case RK_FORMAT_BPP4 :\r
216             break;\r
217         case RK_FORMAT_BPP8 :\r
218             break;\r
219         #endif\r
220         default :\r
221             pageCount = 0;\r
222             start = 0;\r
223             break;\r
224     }\r
225 \r
226     *StartAddr = start;\r
227     return pageCount;\r
228 }\r
229 \r
230 static int rga2_MapUserMemory(struct page **pages,\r
231                                             uint32_t *pageTable,\r
232                                             unsigned long Memory,\r
233                                             uint32_t pageCount)\r
234 {\r
235     int32_t result;\r
236     uint32_t i;\r
237     uint32_t status;\r
238     unsigned long Address;\r
239 \r
240     status = 0;\r
241     Address = 0;\r
242 \r
243     do\r
244     {\r
245         down_read(&current->mm->mmap_sem);\r
246         result = get_user_pages(current,\r
247                 current->mm,\r
248                 Memory << PAGE_SHIFT,\r
249                 pageCount,\r
250                 1,\r
251                 0,\r
252                 pages,\r
253                 NULL\r
254                 );\r
255         up_read(&current->mm->mmap_sem);\r
256 \r
257         if(result <= 0 || result < pageCount)\r
258         {\r
259             struct vm_area_struct *vma;\r
260 \r
261             if (result>0) {\r
262                             down_read(&current->mm->mmap_sem);\r
263                             for (i = 0; i < result; i++)\r
264                                     put_page(pages[i]);\r
265                             up_read(&current->mm->mmap_sem);\r
266                     }\r
267 \r
268             for(i=0; i<pageCount; i++)\r
269             {\r
270                 vma = find_vma(current->mm, (Memory + i) << PAGE_SHIFT);\r
271 \r
272                 if (vma)//&& (vma->vm_flags & VM_PFNMAP) )\r
273                 {\r
274                     do\r
275                     {\r
276                         pte_t       * pte;\r
277                         spinlock_t  * ptl;\r
278                         unsigned long pfn;\r
279                         pgd_t * pgd;\r
280                         pud_t * pud;\r
281 \r
282                         pgd = pgd_offset(current->mm, (Memory + i) << PAGE_SHIFT);\r
283 \r
284                         if(pgd_val(*pgd) == 0)\r
285                         {\r
286                             //printk("rga pgd value is zero \n");\r
287                             break;\r
288                         }\r
289 \r
290                         pud = pud_offset(pgd, (Memory + i) << PAGE_SHIFT);\r
291                         if (pud)\r
292                         {\r
293                             pmd_t * pmd = pmd_offset(pud, (Memory + i) << PAGE_SHIFT);\r
294                             if (pmd)\r
295                             {\r
296                                 pte = pte_offset_map_lock(current->mm, pmd, (Memory + i) << PAGE_SHIFT, &ptl);\r
297                                 if (!pte)\r
298                                 {\r
299                                     pte_unmap_unlock(pte, ptl);\r
300                                     break;\r
301                                 }\r
302                             }\r
303                             else\r
304                             {\r
305                                 break;\r
306                             }\r
307                         }\r
308                         else\r
309                         {\r
310                             break;\r
311                         }\r
312 \r
313                         pfn = pte_pfn(*pte);\r
314                         Address = ((pfn << PAGE_SHIFT) | (((unsigned long)((Memory + i) << PAGE_SHIFT)) & ~PAGE_MASK));\r
315                         pte_unmap_unlock(pte, ptl);\r
316                     }\r
317                     while (0);\r
318 \r
319                     pageTable[i] = (uint32_t)Address;\r
320                 }\r
321                 else\r
322                 {\r
323                     status = RGA2_OUT_OF_RESOURCES;\r
324                     break;\r
325                 }\r
326             }\r
327 \r
328             return status;\r
329         }\r
330 \r
331         /* Fill the page table. */\r
332         for(i=0; i<pageCount; i++)\r
333         {\r
334             /* Get the physical address from page struct. */\r
335             pageTable[i] = page_to_phys(pages[i]);\r
336         }\r
337 \r
338         down_read(&current->mm->mmap_sem);\r
339                 for (i = 0; i < result; i++)\r
340                         put_page(pages[i]);\r
341                 up_read(&current->mm->mmap_sem);\r
342 \r
343         return 0;\r
344     }\r
345     while(0);\r
346 \r
347     return status;\r
348 }\r
349 \r
350 static int rga2_MapION(struct sg_table *sg,\r
351                                uint32_t *Memory,\r
352                                int32_t  pageCount)\r
353 {\r
354     uint32_t i;\r
355     uint32_t status;\r
356     unsigned long Address;\r
357     uint32_t mapped_size = 0;\r
358     uint32_t len;\r
359     struct scatterlist *sgl = sg->sgl;\r
360     uint32_t sg_num = 0;\r
361 \r
362     status = 0;\r
363     Address = 0;\r
364     do {\r
365         len = sg_dma_len(sgl) >> PAGE_SHIFT;\r
366         Address = sg_phys(sgl);\r
367 \r
368         for(i=0; i<len; i++) {\r
369             Memory[mapped_size + i] = (uint32_t)(Address + (i << PAGE_SHIFT));\r
370         }\r
371 \r
372         mapped_size += len;\r
373         sg_num += 1;\r
374     }\r
375     while((sgl = sg_next(sgl)) && (mapped_size < pageCount) && (sg_num < sg->nents));\r
376 \r
377     return 0;\r
378 }\r
379 \r
380 \r
381 static int rga2_mmu_info_BitBlt_mode(struct rga2_reg *reg, struct rga2_req *req)\r
382 {\r
383     int Src0MemSize, DstMemSize, Src1MemSize;\r
384     unsigned long Src0Start, Src1Start, DstStart;\r
385     uint32_t AllSize;\r
386     uint32_t *MMU_Base, *MMU_Base_phys;\r
387     int ret;\r
388     int status;\r
389     uint32_t uv_size, v_size;\r
390 \r
391     struct page **pages = NULL;\r
392 \r
393     MMU_Base = NULL;\r
394 \r
395     Src0MemSize = 0;\r
396     Src1MemSize = 0;\r
397     DstMemSize  = 0;\r
398 \r
399     do {\r
400         /* cal src0 buf mmu info */\r
401         if(req->mmu_info.src0_mmu_flag & 1) {\r
402             Src0MemSize = rga2_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr,\r
403                                         req->src.format, req->src.vir_w,\r
404                                         (req->src.vir_h),\r
405                                         &Src0Start);\r
406             if (Src0MemSize == 0) {\r
407                 return -EINVAL;\r
408             }\r
409         }\r
410 \r
411         /* cal src1 buf mmu info */\r
412         if(req->mmu_info.src1_mmu_flag & 1) {\r
413             Src1MemSize = rga2_buf_size_cal(req->src1.yrgb_addr, req->src1.uv_addr, req->src1.v_addr,\r
414                                         req->src1.format, req->src1.vir_w,\r
415                                         (req->src1.vir_h),\r
416                                         &Src1Start);\r
417             Src0MemSize = (Src0MemSize + 3) & (~3);\r
418             if (Src1MemSize == 0) {\r
419                 return -EINVAL;\r
420             }\r
421         }\r
422 \r
423 \r
424         /* cal dst buf mmu info */\r
425         if(req->mmu_info.dst_mmu_flag & 1) {\r
426             DstMemSize = rga2_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
427                                             req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
428                                             &DstStart);\r
429             if(DstMemSize == 0) {\r
430                 return -EINVAL;\r
431             }\r
432         }\r
433 \r
434         /* Cal out the needed mem size */\r
435         Src0MemSize = (Src0MemSize+15)&(~15);\r
436         Src1MemSize = (Src1MemSize+15)&(~15);\r
437         DstMemSize  = (DstMemSize+15)&(~15);\r
438         AllSize = Src0MemSize + Src1MemSize + DstMemSize;\r
439 \r
440         if (rga2_mmu_buf_get_try(&rga2_mmu_buf, AllSize)) {\r
441             pr_err("RGA2 Get MMU mem failed\n");\r
442             status = RGA2_MALLOC_ERROR;\r
443             break;\r
444         }\r
445 \r
446         pages = rga2_mmu_buf.pages;\r
447 \r
448         mutex_lock(&rga2_service.lock);\r
449         MMU_Base = rga2_mmu_buf.buf_virtual + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
450         MMU_Base_phys = rga2_mmu_buf.buf + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
451         mutex_unlock(&rga2_service.lock);\r
452         if(Src0MemSize) {\r
453             if (req->sg_src0) {\r
454                 ret = rga2_MapION(req->sg_src0, &MMU_Base[0], Src0MemSize);\r
455             }\r
456             else {\r
457                 ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0], Src0Start, Src0MemSize);\r
458             }\r
459 \r
460             if (ret < 0) {\r
461                 pr_err("rga2 map src0 memory failed\n");\r
462                 status = ret;\r
463                 break;\r
464             }\r
465 \r
466             /* change the buf address in req struct */\r
467             req->mmu_info.src0_base_addr = (((unsigned long)MMU_Base_phys));\r
468             uv_size = (req->src.uv_addr - (Src0Start << PAGE_SHIFT)) >> PAGE_SHIFT;\r
469             v_size = (req->src.v_addr - (Src0Start << PAGE_SHIFT)) >> PAGE_SHIFT;\r
470 \r
471             req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK));\r
472             req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (uv_size << PAGE_SHIFT);\r
473             req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (v_size << PAGE_SHIFT);\r
474         }\r
475 \r
476         if(Src1MemSize) {\r
477             if (req->sg_src1) {\r
478                 ret = rga2_MapION(req->sg_src1, MMU_Base + Src0MemSize, Src1MemSize);\r
479             }\r
480             else {\r
481                 ret = rga2_MapUserMemory(&pages[0], MMU_Base + Src0MemSize, Src1Start, Src1MemSize);\r
482             }\r
483 \r
484             if (ret < 0) {\r
485                 pr_err("rga2 map src1 memory failed\n");\r
486                 status = ret;\r
487                 break;\r
488             }\r
489 \r
490             /* change the buf address in req struct */\r
491             req->mmu_info.src1_base_addr = ((unsigned long)(MMU_Base_phys + Src0MemSize));\r
492             req->src1.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK));\r
493         }\r
494 \r
495         if(DstMemSize) {\r
496             if (req->sg_dst) {\r
497                 ret = rga2_MapION(req->sg_dst, MMU_Base + Src0MemSize + Src1MemSize, DstMemSize);\r
498             }\r
499             else {\r
500                 ret = rga2_MapUserMemory(&pages[0], MMU_Base + Src0MemSize + Src1MemSize, DstStart, DstMemSize);\r
501             }\r
502             if (ret < 0) {\r
503                 pr_err("rga2 map dst memory failed\n");\r
504                 status = ret;\r
505                 break;\r
506             }\r
507 \r
508             /* change the buf address in req struct */\r
509             req->mmu_info.dst_base_addr  = ((unsigned long)(MMU_Base_phys + Src0MemSize + Src1MemSize));\r
510             req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK));\r
511             uv_size = (req->dst.uv_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
512             v_size = (req->dst.v_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
513             req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((uv_size) << PAGE_SHIFT);\r
514             req->dst.v_addr = (req->dst.v_addr & (~PAGE_MASK)) | ((v_size) << PAGE_SHIFT);\r
515         }\r
516 \r
517         /* flush data to DDR */\r
518         #ifdef CONFIG_ARM\r
519         dmac_flush_range(MMU_Base, (MMU_Base + AllSize));\r
520         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize));\r
521         #elif defined(CONFIG_ARM64)\r
522         __dma_flush_range(MMU_Base, (MMU_Base + AllSize));\r
523         #endif\r
524 \r
525         rga2_mmu_buf_get(&rga2_mmu_buf, AllSize);\r
526         reg->MMU_len = AllSize;\r
527 \r
528         status = 0;\r
529 \r
530         return status;\r
531     }\r
532     while(0);\r
533 \r
534     return status;\r
535 }\r
536 \r
537 static int rga2_mmu_info_color_palette_mode(struct rga2_reg *reg, struct rga2_req *req)\r
538 {\r
539     int SrcMemSize, DstMemSize;\r
540     unsigned long SrcStart, DstStart;\r
541     struct page **pages = NULL;\r
542     uint32_t AllSize;\r
543     uint32_t *MMU_Base = NULL, *MMU_Base_phys;\r
544     int ret, status;\r
545     uint32_t stride;\r
546 \r
547     uint8_t shift;\r
548     uint16_t sw, byte_num;\r
549 \r
550     shift = 3 - (req->palette_mode & 3);\r
551     sw = req->src.vir_w*req->src.vir_h;\r
552     byte_num = sw >> shift;\r
553     stride = (byte_num + 3) & (~3);\r
554 \r
555     SrcMemSize = 0;\r
556     DstMemSize = 0;\r
557 \r
558     do {\r
559         if (req->mmu_info.src0_mmu_flag) {\r
560             SrcMemSize = rga2_mem_size_cal(req->src.yrgb_addr, stride, &SrcStart);\r
561             if(SrcMemSize == 0) {\r
562                 return -EINVAL;\r
563             }\r
564         }\r
565 \r
566         if (req->mmu_info.dst_mmu_flag) {\r
567             DstMemSize = rga2_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
568                                             req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
569                                             &DstStart);\r
570             if(DstMemSize == 0) {\r
571                 return -EINVAL;\r
572             }\r
573         }\r
574 \r
575         SrcMemSize = (SrcMemSize + 15) & (~15);\r
576         DstMemSize = (DstMemSize + 15) & (~15);\r
577 \r
578         AllSize = SrcMemSize + DstMemSize;\r
579 \r
580         if (rga2_mmu_buf_get_try(&rga2_mmu_buf, AllSize)) {\r
581             pr_err("RGA2 Get MMU mem failed\n");\r
582             status = RGA2_MALLOC_ERROR;\r
583             break;\r
584         }\r
585 \r
586         pages = rga2_mmu_buf.pages;\r
587         if(pages == NULL) {\r
588             pr_err("RGA MMU malloc pages mem failed\n");\r
589             return -EINVAL;\r
590         }\r
591 \r
592         mutex_lock(&rga2_service.lock);\r
593         MMU_Base = rga2_mmu_buf.buf_virtual + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
594         MMU_Base_phys = rga2_mmu_buf.buf + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
595         mutex_unlock(&rga2_service.lock);\r
596 \r
597         if(SrcMemSize) {\r
598             ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize);\r
599             if (ret < 0) {\r
600                 pr_err("rga2 map src0 memory failed\n");\r
601                 status = ret;\r
602                 break;\r
603             }\r
604 \r
605             /* change the buf address in req struct */\r
606             req->mmu_info.src0_base_addr = (((unsigned long)MMU_Base_phys));\r
607             req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK));\r
608         }\r
609 \r
610         if(DstMemSize) {\r
611             ret = rga2_MapUserMemory(&pages[0], MMU_Base + SrcMemSize, DstStart, DstMemSize);\r
612             if (ret < 0) {\r
613                 pr_err("rga2 map dst memory failed\n");\r
614                 status = ret;\r
615                 break;\r
616             }\r
617 \r
618             /* change the buf address in req struct */\r
619             req->mmu_info.dst_base_addr  = ((unsigned long)(MMU_Base_phys + SrcMemSize));\r
620             req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK));\r
621         }\r
622 \r
623         /* flush data to DDR */\r
624         #ifdef CONFIG_ARM\r
625         dmac_flush_range(MMU_Base, (MMU_Base + AllSize));\r
626         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize));\r
627         #elif defined(CONFIG_ARM64)\r
628         __dma_flush_range(MMU_Base, (MMU_Base + AllSize));\r
629         #endif\r
630 \r
631         rga2_mmu_buf_get(&rga2_mmu_buf, AllSize);\r
632         reg->MMU_len = AllSize;\r
633 \r
634         return 0;\r
635     }\r
636     while(0);\r
637 \r
638     return 0;\r
639 }\r
640 \r
641 static int rga2_mmu_info_color_fill_mode(struct rga2_reg *reg, struct rga2_req *req)\r
642 {\r
643     int DstMemSize;\r
644     unsigned long DstStart;\r
645     struct page **pages = NULL;\r
646     uint32_t AllSize;\r
647     uint32_t *MMU_Base, *MMU_Base_phys;\r
648     int ret;\r
649     int status;\r
650 \r
651     MMU_Base = NULL;\r
652 \r
653     do {\r
654         if(req->mmu_info.dst_mmu_flag & 1) {\r
655             DstMemSize = rga2_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
656                                         req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
657                                         &DstStart);\r
658             if(DstMemSize == 0) {\r
659                 return -EINVAL;\r
660             }\r
661         }\r
662 \r
663         AllSize = (DstMemSize + 15) & (~15);\r
664 \r
665         pages = rga2_mmu_buf.pages;\r
666 \r
667         if(rga2_mmu_buf_get_try(&rga2_mmu_buf, AllSize)) {\r
668            pr_err("RGA2 Get MMU mem failed\n");\r
669            status = RGA2_MALLOC_ERROR;\r
670            break;\r
671         }\r
672 \r
673         mutex_lock(&rga2_service.lock);\r
674         MMU_Base_phys = rga2_mmu_buf.buf + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
675         MMU_Base = rga2_mmu_buf.buf_virtual + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
676         mutex_unlock(&rga2_service.lock);\r
677 \r
678         if (DstMemSize) {\r
679             if (req->sg_dst) {\r
680                 ret = rga2_MapION(req->sg_dst, &MMU_Base[0], DstMemSize);\r
681             }\r
682             else {\r
683                 ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0], DstStart, DstMemSize);\r
684             }\r
685             if (ret < 0) {\r
686                 pr_err("rga2 map dst memory failed\n");\r
687                 status = ret;\r
688                 break;\r
689             }\r
690 \r
691             /* change the buf address in req struct */\r
692             req->mmu_info.dst_base_addr = ((unsigned long)MMU_Base_phys);\r
693             req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK));\r
694         }\r
695 \r
696         /* flush data to DDR */\r
697         #ifdef CONFIG_ARM\r
698         dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
699         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));\r
700         #elif defined(CONFIG_ARM64)\r
701         __dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
702         #endif\r
703 \r
704         rga2_mmu_buf_get(&rga2_mmu_buf, AllSize);\r
705 \r
706         return 0;\r
707     }\r
708     while(0);\r
709 \r
710     return status;\r
711 }\r
712 \r
713 \r
714 static int rga2_mmu_info_update_palette_table_mode(struct rga2_reg *reg, struct rga2_req *req)\r
715 {\r
716     int SrcMemSize;\r
717     unsigned long SrcStart;\r
718     struct page **pages = NULL;\r
719     uint32_t AllSize;\r
720     uint32_t *MMU_Base, *MMU_Base_phys;\r
721     int ret, status;\r
722 \r
723     MMU_Base = NULL;\r
724 \r
725     do {\r
726         /* cal src buf mmu info */\r
727         SrcMemSize = rga2_mem_size_cal(req->pat.yrgb_addr, req->pat.vir_w * req->pat.vir_h, &SrcStart);\r
728         if(SrcMemSize == 0) {\r
729             return -EINVAL;\r
730         }\r
731 \r
732         SrcMemSize = (SrcMemSize + 15) & (~15);\r
733         AllSize = SrcMemSize;\r
734 \r
735         if (rga2_mmu_buf_get_try(&rga2_mmu_buf, AllSize)) {\r
736             pr_err("RGA2 Get MMU mem failed\n");\r
737             status = RGA2_MALLOC_ERROR;\r
738             break;\r
739         }\r
740 \r
741         mutex_lock(&rga2_service.lock);\r
742         MMU_Base = rga2_mmu_buf.buf_virtual + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
743         MMU_Base_phys = rga2_mmu_buf.buf + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
744         mutex_unlock(&rga2_service.lock);\r
745 \r
746         pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
747 \r
748         if(SrcMemSize) {\r
749             ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize);\r
750             if (ret < 0) {\r
751                 pr_err("rga2 map palette memory failed\n");\r
752                 status = ret;\r
753                 break;\r
754             }\r
755 \r
756             /* change the buf address in req struct */\r
757             req->mmu_info.src0_base_addr = (((unsigned long)MMU_Base_phys));\r
758             req->pat.yrgb_addr = (req->pat.yrgb_addr & (~PAGE_MASK));\r
759         }\r
760 \r
761         /* flush data to DDR */\r
762         #ifdef CONFIG_ARM\r
763         dmac_flush_range(MMU_Base, (MMU_Base + AllSize));\r
764         outer_flush_range(virt_to_phys(MMU_Base), virt_to_phys(MMU_Base + AllSize));\r
765         #elif defined(CONFIG_ARM64)\r
766         __dma_flush_range(MMU_Base, (MMU_Base + AllSize));\r
767         #endif\r
768 \r
769         rga2_mmu_buf_get(&rga2_mmu_buf, AllSize);\r
770         reg->MMU_len = AllSize;\r
771 \r
772         return 0;\r
773     }\r
774     while(0);\r
775 \r
776     return status;\r
777 }\r
778 \r
779 static int rga2_mmu_info_update_patten_buff_mode(struct rga2_reg *reg, struct rga2_req *req)\r
780 {\r
781     int SrcMemSize, CMDMemSize;\r
782     unsigned long SrcStart, CMDStart;\r
783     struct page **pages = NULL;\r
784     uint32_t i;\r
785     uint32_t AllSize;\r
786     uint32_t *MMU_Base, *MMU_p;\r
787     int ret, status;\r
788 \r
789     MMU_Base = MMU_p = 0;\r
790 \r
791     do {\r
792         /* cal src buf mmu info */\r
793         SrcMemSize = rga2_mem_size_cal(req->pat.yrgb_addr, req->pat.act_w * req->pat.act_h * 4, &SrcStart);\r
794         if(SrcMemSize == 0) {\r
795             return -EINVAL;\r
796         }\r
797 \r
798         /* cal cmd buf mmu info */\r
799         CMDMemSize = rga2_mem_size_cal((unsigned long)rga2_service.cmd_buff, RGA2_CMD_BUF_SIZE, &CMDStart);\r
800         if(CMDMemSize == 0) {\r
801             return -EINVAL;\r
802         }\r
803 \r
804         AllSize = SrcMemSize + CMDMemSize;\r
805 \r
806         pages = rga2_mmu_buf.pages;\r
807 \r
808         MMU_Base = kzalloc(AllSize * sizeof(uint32_t), GFP_KERNEL);\r
809 \r
810         for(i=0; i<CMDMemSize; i++) {\r
811             MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i) << PAGE_SHIFT));\r
812         }\r
813 \r
814         if (req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
815         {\r
816             ret = rga2_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
817             if (ret < 0) {\r
818                 pr_err("rga map src memory failed\n");\r
819                 status = ret;\r
820                 break;\r
821             }\r
822         }\r
823         else\r
824         {\r
825             MMU_p = MMU_Base + CMDMemSize;\r
826 \r
827             for(i=0; i<SrcMemSize; i++)\r
828             {\r
829                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
830             }\r
831         }\r
832 \r
833         /* zsq\r
834          * change the buf address in req struct\r
835          * for the reason of lie to MMU\r
836          */\r
837         req->mmu_info.src0_base_addr = (virt_to_phys(MMU_Base) >> 2);\r
838 \r
839         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
840 \r
841         /*record the malloc buf for the cmd end to release*/\r
842         reg->MMU_base = MMU_Base;\r
843 \r
844         /* flush data to DDR */\r
845         #ifdef CONFIG_ARM\r
846         dmac_flush_range(MMU_Base, (MMU_Base + AllSize));\r
847         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize));\r
848         #elif defined(CONFIG_ARM64)\r
849         __dma_flush_range(MMU_Base, (MMU_Base + AllSize));\r
850         #endif\r
851 \r
852         return 0;\r
853 \r
854     }\r
855     while(0);\r
856 \r
857     return status;\r
858 }\r
859 \r
860 int rga2_set_mmu_info(struct rga2_reg *reg, struct rga2_req *req)\r
861 {\r
862     int ret;\r
863 \r
864     switch (req->render_mode) {\r
865         case bitblt_mode :\r
866             ret = rga2_mmu_info_BitBlt_mode(reg, req);\r
867             break;\r
868         case color_palette_mode :\r
869             ret = rga2_mmu_info_color_palette_mode(reg, req);\r
870             break;\r
871         case color_fill_mode :\r
872             ret = rga2_mmu_info_color_fill_mode(reg, req);\r
873             break;\r
874         case update_palette_table_mode :\r
875             ret = rga2_mmu_info_update_palette_table_mode(reg, req);\r
876             break;\r
877         case update_patten_buff_mode :\r
878             ret = rga2_mmu_info_update_patten_buff_mode(reg, req);\r
879             break;\r
880         default :\r
881             ret = -1;\r
882             break;\r
883     }\r
884 \r
885     return ret;\r
886 }\r
887 \r