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