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