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