Merge tag 'lsk-v3.10-15.05-android' into 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     uint32_t break_flag = 0;\r
362 \r
363     status = 0;\r
364     Address = 0;\r
365     do {\r
366         len = sg_dma_len(sgl) >> PAGE_SHIFT;\r
367         Address = sg_phys(sgl);\r
368 \r
369         for(i=0; i<len; i++) {\r
370             if (mapped_size + i >= pageCount) {\r
371                 break_flag = 1;\r
372                 break;\r
373             }\r
374             Memory[mapped_size + i] = (uint32_t)(Address + (i << PAGE_SHIFT));\r
375         }\r
376         if (break_flag)\r
377             break;\r
378         mapped_size += len;\r
379         sg_num += 1;\r
380     }\r
381     while((sgl = sg_next(sgl)) && (mapped_size < pageCount) && (sg_num < sg->nents));\r
382 \r
383     return 0;\r
384 }\r
385 \r
386 \r
387 static int rga2_mmu_info_BitBlt_mode(struct rga2_reg *reg, struct rga2_req *req)\r
388 {\r
389     int Src0MemSize, DstMemSize, Src1MemSize;\r
390     unsigned long Src0Start, Src1Start, DstStart;\r
391     uint32_t AllSize;\r
392     uint32_t *MMU_Base, *MMU_Base_phys;\r
393     int ret;\r
394     int status;\r
395     uint32_t uv_size, v_size;\r
396 \r
397     struct page **pages = NULL;\r
398 \r
399     MMU_Base = NULL;\r
400 \r
401     Src0MemSize = 0;\r
402     Src1MemSize = 0;\r
403     DstMemSize  = 0;\r
404 \r
405     do {\r
406         /* cal src0 buf mmu info */\r
407         if(req->mmu_info.src0_mmu_flag & 1) {\r
408             Src0MemSize = rga2_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr,\r
409                                         req->src.format, req->src.vir_w,\r
410                                         (req->src.vir_h),\r
411                                         &Src0Start);\r
412             if (Src0MemSize == 0) {\r
413                 return -EINVAL;\r
414             }\r
415         }\r
416 \r
417         /* cal src1 buf mmu info */\r
418         if(req->mmu_info.src1_mmu_flag & 1) {\r
419             Src1MemSize = rga2_buf_size_cal(req->src1.yrgb_addr, req->src1.uv_addr, req->src1.v_addr,\r
420                                         req->src1.format, req->src1.vir_w,\r
421                                         (req->src1.vir_h),\r
422                                         &Src1Start);\r
423             Src0MemSize = (Src0MemSize + 3) & (~3);\r
424             if (Src1MemSize == 0) {\r
425                 return -EINVAL;\r
426             }\r
427         }\r
428 \r
429 \r
430         /* cal dst buf mmu info */\r
431         if(req->mmu_info.dst_mmu_flag & 1) {\r
432             DstMemSize = rga2_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
433                                             req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
434                                             &DstStart);\r
435             if(DstMemSize == 0) {\r
436                 return -EINVAL;\r
437             }\r
438         }\r
439 \r
440         /* Cal out the needed mem size */\r
441         Src0MemSize = (Src0MemSize+15)&(~15);\r
442         Src1MemSize = (Src1MemSize+15)&(~15);\r
443         DstMemSize  = (DstMemSize+15)&(~15);\r
444         AllSize = Src0MemSize + Src1MemSize + DstMemSize;\r
445 \r
446         if (rga2_mmu_buf_get_try(&rga2_mmu_buf, AllSize)) {\r
447             pr_err("RGA2 Get MMU mem failed\n");\r
448             status = RGA2_MALLOC_ERROR;\r
449             break;\r
450         }\r
451 \r
452         pages = rga2_mmu_buf.pages;\r
453 \r
454         mutex_lock(&rga2_service.lock);\r
455         MMU_Base = rga2_mmu_buf.buf_virtual + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
456         MMU_Base_phys = rga2_mmu_buf.buf + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
457         mutex_unlock(&rga2_service.lock);\r
458         if(Src0MemSize) {\r
459             if (req->sg_src0) {\r
460                 ret = rga2_MapION(req->sg_src0, &MMU_Base[0], Src0MemSize);\r
461             }\r
462             else {\r
463                 ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0], Src0Start, Src0MemSize);\r
464             }\r
465 \r
466             if (ret < 0) {\r
467                 pr_err("rga2 map src0 memory failed\n");\r
468                 status = ret;\r
469                 break;\r
470             }\r
471 \r
472             /* change the buf address in req struct */\r
473             req->mmu_info.src0_base_addr = (((unsigned long)MMU_Base_phys));\r
474             uv_size = (req->src.uv_addr - (Src0Start << PAGE_SHIFT)) >> PAGE_SHIFT;\r
475             v_size = (req->src.v_addr - (Src0Start << PAGE_SHIFT)) >> PAGE_SHIFT;\r
476 \r
477             req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK));\r
478             req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (uv_size << PAGE_SHIFT);\r
479             req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (v_size << PAGE_SHIFT);\r
480         }\r
481 \r
482         if(Src1MemSize) {\r
483             if (req->sg_src1) {\r
484                 ret = rga2_MapION(req->sg_src1, MMU_Base + Src0MemSize, Src1MemSize);\r
485             }\r
486             else {\r
487                 ret = rga2_MapUserMemory(&pages[0], MMU_Base + Src0MemSize, Src1Start, Src1MemSize);\r
488             }\r
489 \r
490             if (ret < 0) {\r
491                 pr_err("rga2 map src1 memory failed\n");\r
492                 status = ret;\r
493                 break;\r
494             }\r
495 \r
496             /* change the buf address in req struct */\r
497             req->mmu_info.src1_base_addr = ((unsigned long)(MMU_Base_phys + Src0MemSize));\r
498             req->src1.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK));\r
499         }\r
500 \r
501         if(DstMemSize) {\r
502             if (req->sg_dst) {\r
503                 ret = rga2_MapION(req->sg_dst, MMU_Base + Src0MemSize + Src1MemSize, DstMemSize);\r
504             }\r
505             else {\r
506                 ret = rga2_MapUserMemory(&pages[0], MMU_Base + Src0MemSize + Src1MemSize, DstStart, DstMemSize);\r
507             }\r
508             if (ret < 0) {\r
509                 pr_err("rga2 map dst memory failed\n");\r
510                 status = ret;\r
511                 break;\r
512             }\r
513 \r
514             /* change the buf address in req struct */\r
515             req->mmu_info.dst_base_addr  = ((unsigned long)(MMU_Base_phys + Src0MemSize + Src1MemSize));\r
516             req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK));\r
517             uv_size = (req->dst.uv_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
518             v_size = (req->dst.v_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
519             req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((uv_size) << PAGE_SHIFT);\r
520             req->dst.v_addr = (req->dst.v_addr & (~PAGE_MASK)) | ((v_size) << PAGE_SHIFT);\r
521         }\r
522 \r
523         /* flush data to DDR */\r
524         #ifdef CONFIG_ARM\r
525         dmac_flush_range(MMU_Base, (MMU_Base + AllSize));\r
526         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize));\r
527         #elif defined(CONFIG_ARM64)\r
528         __dma_flush_range(MMU_Base, (MMU_Base + AllSize));\r
529         #endif\r
530 \r
531         rga2_mmu_buf_get(&rga2_mmu_buf, AllSize);\r
532         reg->MMU_len = AllSize;\r
533 \r
534         status = 0;\r
535 \r
536         return status;\r
537     }\r
538     while(0);\r
539 \r
540     return status;\r
541 }\r
542 \r
543 static int rga2_mmu_info_color_palette_mode(struct rga2_reg *reg, struct rga2_req *req)\r
544 {\r
545     int SrcMemSize, DstMemSize;\r
546     unsigned long SrcStart, DstStart;\r
547     struct page **pages = NULL;\r
548     uint32_t AllSize;\r
549     uint32_t *MMU_Base = NULL, *MMU_Base_phys;\r
550     int ret, status;\r
551     uint32_t stride;\r
552 \r
553     uint8_t shift;\r
554     uint16_t sw, byte_num;\r
555 \r
556     shift = 3 - (req->palette_mode & 3);\r
557     sw = req->src.vir_w*req->src.vir_h;\r
558     byte_num = sw >> shift;\r
559     stride = (byte_num + 3) & (~3);\r
560 \r
561     SrcMemSize = 0;\r
562     DstMemSize = 0;\r
563 \r
564     do {\r
565         if (req->mmu_info.src0_mmu_flag) {\r
566             SrcMemSize = rga2_mem_size_cal(req->src.yrgb_addr, stride, &SrcStart);\r
567             if(SrcMemSize == 0) {\r
568                 return -EINVAL;\r
569             }\r
570         }\r
571 \r
572         if (req->mmu_info.dst_mmu_flag) {\r
573             DstMemSize = rga2_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
574                                             req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
575                                             &DstStart);\r
576             if(DstMemSize == 0) {\r
577                 return -EINVAL;\r
578             }\r
579         }\r
580 \r
581         SrcMemSize = (SrcMemSize + 15) & (~15);\r
582         DstMemSize = (DstMemSize + 15) & (~15);\r
583 \r
584         AllSize = SrcMemSize + DstMemSize;\r
585 \r
586         if (rga2_mmu_buf_get_try(&rga2_mmu_buf, AllSize)) {\r
587             pr_err("RGA2 Get MMU mem failed\n");\r
588             status = RGA2_MALLOC_ERROR;\r
589             break;\r
590         }\r
591 \r
592         pages = rga2_mmu_buf.pages;\r
593         if(pages == NULL) {\r
594             pr_err("RGA MMU malloc pages mem failed\n");\r
595             return -EINVAL;\r
596         }\r
597 \r
598         mutex_lock(&rga2_service.lock);\r
599         MMU_Base = rga2_mmu_buf.buf_virtual + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
600         MMU_Base_phys = rga2_mmu_buf.buf + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
601         mutex_unlock(&rga2_service.lock);\r
602 \r
603         if(SrcMemSize) {\r
604             ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize);\r
605             if (ret < 0) {\r
606                 pr_err("rga2 map src0 memory failed\n");\r
607                 status = ret;\r
608                 break;\r
609             }\r
610 \r
611             /* change the buf address in req struct */\r
612             req->mmu_info.src0_base_addr = (((unsigned long)MMU_Base_phys));\r
613             req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK));\r
614         }\r
615 \r
616         if(DstMemSize) {\r
617             ret = rga2_MapUserMemory(&pages[0], MMU_Base + SrcMemSize, DstStart, DstMemSize);\r
618             if (ret < 0) {\r
619                 pr_err("rga2 map dst memory failed\n");\r
620                 status = ret;\r
621                 break;\r
622             }\r
623 \r
624             /* change the buf address in req struct */\r
625             req->mmu_info.dst_base_addr  = ((unsigned long)(MMU_Base_phys + SrcMemSize));\r
626             req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK));\r
627         }\r
628 \r
629         /* flush data to DDR */\r
630         #ifdef CONFIG_ARM\r
631         dmac_flush_range(MMU_Base, (MMU_Base + AllSize));\r
632         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize));\r
633         #elif defined(CONFIG_ARM64)\r
634         __dma_flush_range(MMU_Base, (MMU_Base + AllSize));\r
635         #endif\r
636 \r
637         rga2_mmu_buf_get(&rga2_mmu_buf, AllSize);\r
638         reg->MMU_len = AllSize;\r
639 \r
640         return 0;\r
641     }\r
642     while(0);\r
643 \r
644     return 0;\r
645 }\r
646 \r
647 static int rga2_mmu_info_color_fill_mode(struct rga2_reg *reg, struct rga2_req *req)\r
648 {\r
649     int DstMemSize;\r
650     unsigned long DstStart;\r
651     struct page **pages = NULL;\r
652     uint32_t AllSize;\r
653     uint32_t *MMU_Base, *MMU_Base_phys;\r
654     int ret;\r
655     int status;\r
656 \r
657     MMU_Base = NULL;\r
658 \r
659     do {\r
660         if(req->mmu_info.dst_mmu_flag & 1) {\r
661             DstMemSize = rga2_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
662                                         req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
663                                         &DstStart);\r
664             if(DstMemSize == 0) {\r
665                 return -EINVAL;\r
666             }\r
667         }\r
668 \r
669         AllSize = (DstMemSize + 15) & (~15);\r
670 \r
671         pages = rga2_mmu_buf.pages;\r
672 \r
673         if(rga2_mmu_buf_get_try(&rga2_mmu_buf, AllSize)) {\r
674            pr_err("RGA2 Get MMU mem failed\n");\r
675            status = RGA2_MALLOC_ERROR;\r
676            break;\r
677         }\r
678 \r
679         mutex_lock(&rga2_service.lock);\r
680         MMU_Base_phys = rga2_mmu_buf.buf + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
681         MMU_Base = rga2_mmu_buf.buf_virtual + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
682         mutex_unlock(&rga2_service.lock);\r
683 \r
684         if (DstMemSize) {\r
685             if (req->sg_dst) {\r
686                 ret = rga2_MapION(req->sg_dst, &MMU_Base[0], DstMemSize);\r
687             }\r
688             else {\r
689                 ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0], DstStart, DstMemSize);\r
690             }\r
691             if (ret < 0) {\r
692                 pr_err("rga2 map dst memory failed\n");\r
693                 status = ret;\r
694                 break;\r
695             }\r
696 \r
697             /* change the buf address in req struct */\r
698             req->mmu_info.dst_base_addr = ((unsigned long)MMU_Base_phys);\r
699             req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK));\r
700         }\r
701 \r
702         /* flush data to DDR */\r
703         #ifdef CONFIG_ARM\r
704         dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
705         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));\r
706         #elif defined(CONFIG_ARM64)\r
707         __dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
708         #endif\r
709 \r
710         rga2_mmu_buf_get(&rga2_mmu_buf, AllSize);\r
711 \r
712         return 0;\r
713     }\r
714     while(0);\r
715 \r
716     return status;\r
717 }\r
718 \r
719 \r
720 static int rga2_mmu_info_update_palette_table_mode(struct rga2_reg *reg, struct rga2_req *req)\r
721 {\r
722     int SrcMemSize;\r
723     unsigned long SrcStart;\r
724     struct page **pages = NULL;\r
725     uint32_t AllSize;\r
726     uint32_t *MMU_Base, *MMU_Base_phys;\r
727     int ret, status;\r
728 \r
729     MMU_Base = NULL;\r
730 \r
731     do {\r
732         /* cal src buf mmu info */\r
733         SrcMemSize = rga2_mem_size_cal(req->pat.yrgb_addr, req->pat.vir_w * req->pat.vir_h, &SrcStart);\r
734         if(SrcMemSize == 0) {\r
735             return -EINVAL;\r
736         }\r
737 \r
738         SrcMemSize = (SrcMemSize + 15) & (~15);\r
739         AllSize = SrcMemSize;\r
740 \r
741         if (rga2_mmu_buf_get_try(&rga2_mmu_buf, AllSize)) {\r
742             pr_err("RGA2 Get MMU mem failed\n");\r
743             status = RGA2_MALLOC_ERROR;\r
744             break;\r
745         }\r
746 \r
747         mutex_lock(&rga2_service.lock);\r
748         MMU_Base = rga2_mmu_buf.buf_virtual + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
749         MMU_Base_phys = rga2_mmu_buf.buf + (rga2_mmu_buf.front & (rga2_mmu_buf.size - 1));\r
750         mutex_unlock(&rga2_service.lock);\r
751 \r
752         pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
753 \r
754         if(SrcMemSize) {\r
755             ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize);\r
756             if (ret < 0) {\r
757                 pr_err("rga2 map palette memory failed\n");\r
758                 status = ret;\r
759                 break;\r
760             }\r
761 \r
762             /* change the buf address in req struct */\r
763             req->mmu_info.src0_base_addr = (((unsigned long)MMU_Base_phys));\r
764             req->pat.yrgb_addr = (req->pat.yrgb_addr & (~PAGE_MASK));\r
765         }\r
766 \r
767         /* flush data to DDR */\r
768         #ifdef CONFIG_ARM\r
769         dmac_flush_range(MMU_Base, (MMU_Base + AllSize));\r
770         outer_flush_range(virt_to_phys(MMU_Base), virt_to_phys(MMU_Base + AllSize));\r
771         #elif defined(CONFIG_ARM64)\r
772         __dma_flush_range(MMU_Base, (MMU_Base + AllSize));\r
773         #endif\r
774 \r
775         rga2_mmu_buf_get(&rga2_mmu_buf, AllSize);\r
776         reg->MMU_len = AllSize;\r
777 \r
778         return 0;\r
779     }\r
780     while(0);\r
781 \r
782     return status;\r
783 }\r
784 \r
785 static int rga2_mmu_info_update_patten_buff_mode(struct rga2_reg *reg, struct rga2_req *req)\r
786 {\r
787     int SrcMemSize, CMDMemSize;\r
788     unsigned long SrcStart, CMDStart;\r
789     struct page **pages = NULL;\r
790     uint32_t i;\r
791     uint32_t AllSize;\r
792     uint32_t *MMU_Base, *MMU_p;\r
793     int ret, status;\r
794 \r
795     MMU_Base = MMU_p = 0;\r
796 \r
797     do {\r
798         /* cal src buf mmu info */\r
799         SrcMemSize = rga2_mem_size_cal(req->pat.yrgb_addr, req->pat.act_w * req->pat.act_h * 4, &SrcStart);\r
800         if(SrcMemSize == 0) {\r
801             return -EINVAL;\r
802         }\r
803 \r
804         /* cal cmd buf mmu info */\r
805         CMDMemSize = rga2_mem_size_cal((unsigned long)rga2_service.cmd_buff, RGA2_CMD_BUF_SIZE, &CMDStart);\r
806         if(CMDMemSize == 0) {\r
807             return -EINVAL;\r
808         }\r
809 \r
810         AllSize = SrcMemSize + CMDMemSize;\r
811 \r
812         pages = rga2_mmu_buf.pages;\r
813 \r
814         MMU_Base = kzalloc(AllSize * sizeof(uint32_t), GFP_KERNEL);\r
815 \r
816         for(i=0; i<CMDMemSize; i++) {\r
817             MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i) << PAGE_SHIFT));\r
818         }\r
819 \r
820         if (req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
821         {\r
822             ret = rga2_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
823             if (ret < 0) {\r
824                 pr_err("rga map src memory failed\n");\r
825                 status = ret;\r
826                 break;\r
827             }\r
828         }\r
829         else\r
830         {\r
831             MMU_p = MMU_Base + CMDMemSize;\r
832 \r
833             for(i=0; i<SrcMemSize; i++)\r
834             {\r
835                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
836             }\r
837         }\r
838 \r
839         /* zsq\r
840          * change the buf address in req struct\r
841          * for the reason of lie to MMU\r
842          */\r
843         req->mmu_info.src0_base_addr = (virt_to_phys(MMU_Base) >> 2);\r
844 \r
845         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
846 \r
847         /*record the malloc buf for the cmd end to release*/\r
848         reg->MMU_base = MMU_Base;\r
849 \r
850         /* flush data to DDR */\r
851         #ifdef CONFIG_ARM\r
852         dmac_flush_range(MMU_Base, (MMU_Base + AllSize));\r
853         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize));\r
854         #elif defined(CONFIG_ARM64)\r
855         __dma_flush_range(MMU_Base, (MMU_Base + AllSize));\r
856         #endif\r
857 \r
858         return 0;\r
859 \r
860     }\r
861     while(0);\r
862 \r
863     return status;\r
864 }\r
865 \r
866 int rga2_set_mmu_info(struct rga2_reg *reg, struct rga2_req *req)\r
867 {\r
868     int ret;\r
869 \r
870     switch (req->render_mode) {\r
871         case bitblt_mode :\r
872             ret = rga2_mmu_info_BitBlt_mode(reg, req);\r
873             break;\r
874         case color_palette_mode :\r
875             ret = rga2_mmu_info_color_palette_mode(reg, req);\r
876             break;\r
877         case color_fill_mode :\r
878             ret = rga2_mmu_info_color_fill_mode(reg, req);\r
879             break;\r
880         case update_palette_table_mode :\r
881             ret = rga2_mmu_info_update_palette_table_mode(reg, req);\r
882             break;\r
883         case update_patten_buff_mode :\r
884             ret = rga2_mmu_info_update_patten_buff_mode(reg, req);\r
885             break;\r
886         default :\r
887             ret = -1;\r
888             break;\r
889     }\r
890 \r
891     return ret;\r
892 }\r
893 \r