HDMI: Not filter the input 3dmode with EDID information.
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / rga / rga_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 "rga_mmu_info.h"\r
21 #include <linux/delay.h>\r
22 \r
23 extern rga_service_info rga_service;\r
24 extern struct rga_mmu_buf_t rga_mmu_buf;\r
25 \r
26 #define KERNEL_SPACE_VALID    0xc0000000\r
27 \r
28 static int rga_mmu_buf_get(struct rga_mmu_buf_t *t, uint32_t size)\r
29 {\r
30     mutex_lock(&rga_service.lock);\r
31     t->front += size;\r
32     mutex_unlock(&rga_service.lock);\r
33 \r
34     return 0;\r
35 }\r
36 \r
37 static int rga_mmu_buf_get_try(struct rga_mmu_buf_t *t, uint32_t size)\r
38 {\r
39     mutex_lock(&rga_service.lock);\r
40     if((t->back - t->front) > t->size) {\r
41         if(t->front + size > t->back - t->size)\r
42             return -1;\r
43     }\r
44     else {\r
45         if((t->front + size) > t->back)\r
46             return -1;\r
47 \r
48         if(t->front + size > t->size) {\r
49             if (size > (t->back - t->size)) {\r
50                 return -1;\r
51             }\r
52             t->front = 0;\r
53         }\r
54     }\r
55     mutex_unlock(&rga_service.lock);\r
56 \r
57     return 0;\r
58 }\r
59 \r
60 static int rga_mem_size_cal(uint32_t Mem, uint32_t MemSize, uint32_t *StartAddr)\r
61 {\r
62     uint32_t start, end;\r
63     uint32_t pageCount;\r
64 \r
65     end = (Mem + (MemSize + PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
66     start = Mem >> PAGE_SHIFT;\r
67     pageCount = end - start;\r
68     *StartAddr = start;\r
69     return pageCount;\r
70 }\r
71 \r
72 static int rga_buf_size_cal(uint32_t yrgb_addr, uint32_t uv_addr, uint32_t v_addr,\r
73                                         int format, uint32_t w, uint32_t h, uint32_t *StartAddr )\r
74 {\r
75     uint32_t size_yrgb = 0;\r
76     uint32_t size_uv = 0;\r
77     uint32_t size_v = 0;\r
78     uint32_t stride = 0;\r
79     uint32_t start, end;\r
80     uint32_t pageCount;\r
81 \r
82     switch(format)\r
83     {\r
84         case RK_FORMAT_RGBA_8888 :\r
85             stride = (w * 4 + 3) & (~3);\r
86             size_yrgb = stride*h;\r
87             start = yrgb_addr >> PAGE_SHIFT;\r
88             pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT;\r
89             break;\r
90         case RK_FORMAT_RGBX_8888 :\r
91             stride = (w * 4 + 3) & (~3);\r
92             size_yrgb = stride*h;\r
93             start = yrgb_addr >> PAGE_SHIFT;\r
94             pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT;\r
95             break;\r
96         case RK_FORMAT_RGB_888 :\r
97             stride = (w * 3 + 3) & (~3);\r
98             size_yrgb = stride*h;\r
99             start = yrgb_addr >> PAGE_SHIFT;\r
100             pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT;\r
101             break;\r
102         case RK_FORMAT_BGRA_8888 :\r
103             size_yrgb = w*h*4;\r
104             start = yrgb_addr >> PAGE_SHIFT;\r
105             pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT;\r
106             break;\r
107         case RK_FORMAT_RGB_565 :\r
108             stride = (w*2 + 3) & (~3);\r
109             size_yrgb = stride * h;\r
110             start = yrgb_addr >> PAGE_SHIFT;\r
111             pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT;\r
112             break;\r
113         case RK_FORMAT_RGBA_5551 :\r
114             stride = (w*2 + 3) & (~3);\r
115             size_yrgb = stride * h;\r
116             start = yrgb_addr >> PAGE_SHIFT;\r
117             pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT;\r
118             break;\r
119         case RK_FORMAT_RGBA_4444 :\r
120             stride = (w*2 + 3) & (~3);\r
121             size_yrgb = stride * h;\r
122             start = yrgb_addr >> PAGE_SHIFT;\r
123             pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT;\r
124             break;\r
125         case RK_FORMAT_BGR_888 :\r
126             stride = (w*3 + 3) & (~3);\r
127             size_yrgb = stride * h;\r
128             start = yrgb_addr >> PAGE_SHIFT;\r
129             pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT;\r
130             break;\r
131 \r
132         /* YUV FORMAT */\r
133         case RK_FORMAT_YCbCr_422_SP :\r
134             stride = (w + 3) & (~3);\r
135             size_yrgb = stride * h;\r
136             size_uv = stride * h;\r
137             start = MIN(yrgb_addr, uv_addr);\r
138 \r
139             start >>= PAGE_SHIFT;\r
140             end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv));\r
141             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
142             pageCount = end - start;\r
143             break;\r
144         case RK_FORMAT_YCbCr_422_P :\r
145             stride = (w + 3) & (~3);\r
146             size_yrgb = stride * h;\r
147             size_uv = ((stride >> 1) * h);\r
148             size_v = ((stride >> 1) * h);\r
149             start = MIN(MIN(yrgb_addr, uv_addr), v_addr);\r
150             start = start >> PAGE_SHIFT;\r
151             end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v));\r
152             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
153             pageCount = end - start;\r
154             break;\r
155         case RK_FORMAT_YCbCr_420_SP :\r
156             stride = (w + 3) & (~3);\r
157             size_yrgb = stride * h;\r
158             size_uv = (stride * (h >> 1));\r
159             start = MIN(yrgb_addr, uv_addr);\r
160             start >>= PAGE_SHIFT;\r
161             end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv));\r
162             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
163             pageCount = end - start;\r
164             break;\r
165         case RK_FORMAT_YCbCr_420_P :\r
166             stride = (w + 3) & (~3);\r
167             size_yrgb = stride * h;\r
168             size_uv = ((stride >> 1) * (h >> 1));\r
169             size_v = ((stride >> 1) * (h >> 1));\r
170             start = MIN(MIN(yrgb_addr, uv_addr), v_addr);\r
171             start >>= PAGE_SHIFT;\r
172             end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v));\r
173             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
174             pageCount = end - start;\r
175             break;\r
176 \r
177         case RK_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 RK_FORMAT_YCrCb_422_P :\r
188             stride = (w + 3) & (~3);\r
189             size_yrgb = stride * h;\r
190             size_uv = ((stride >> 1) * h);\r
191             size_v = ((stride >> 1) * h);\r
192             start = MIN(MIN(yrgb_addr, uv_addr), v_addr);\r
193             start >>= PAGE_SHIFT;\r
194             end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v));\r
195             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
196             pageCount = end - start;\r
197             break;\r
198 \r
199         case RK_FORMAT_YCrCb_420_SP :\r
200             stride = (w + 3) & (~3);\r
201             size_yrgb = stride * h;\r
202             size_uv = (stride * (h >> 1));\r
203             start = MIN(yrgb_addr, uv_addr);\r
204             start >>= PAGE_SHIFT;\r
205             end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv));\r
206             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
207             pageCount = end - start;\r
208             break;\r
209         case RK_FORMAT_YCrCb_420_P :\r
210             stride = (w + 3) & (~3);\r
211             size_yrgb = stride * h;\r
212             size_uv = ((stride >> 1) * (h >> 1));\r
213             size_v = ((stride >> 1) * (h >> 1));\r
214             start = MIN(MIN(yrgb_addr, uv_addr), v_addr);\r
215             start >>= PAGE_SHIFT;\r
216             end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v));\r
217             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
218             pageCount = end - start;\r
219             break;\r
220         #if 0\r
221         case RK_FORMAT_BPP1 :\r
222             break;\r
223         case RK_FORMAT_BPP2 :\r
224             break;\r
225         case RK_FORMAT_BPP4 :\r
226             break;\r
227         case RK_FORMAT_BPP8 :\r
228             break;\r
229         #endif\r
230         default :\r
231             pageCount = 0;\r
232             start = 0;\r
233             break;\r
234     }\r
235 \r
236     *StartAddr = start;\r
237     return pageCount;\r
238 }\r
239 \r
240 static int rga_MapUserMemory(struct page **pages,\r
241                                             uint32_t *pageTable,\r
242                                             uint32_t Memory,\r
243                                             uint32_t pageCount)\r
244 {\r
245     int32_t result;\r
246     uint32_t i;\r
247     uint32_t status;\r
248     uint32_t Address;\r
249     //uint32_t temp;\r
250 \r
251     status = 0;\r
252     Address = 0;\r
253 \r
254     do\r
255     {\r
256         down_read(&current->mm->mmap_sem);\r
257         result = get_user_pages(current,\r
258                 current->mm,\r
259                 Memory << PAGE_SHIFT,\r
260                 pageCount,\r
261                 1,\r
262                 0,\r
263                 pages,\r
264                 NULL\r
265                 );\r
266         up_read(&current->mm->mmap_sem);\r
267 \r
268         #if 0\r
269         if(result <= 0 || result < pageCount)\r
270         {\r
271             status = 0;\r
272 \r
273             for(i=0; i<pageCount; i++)\r
274             {\r
275                 temp = armv7_va_to_pa((Memory + i) << PAGE_SHIFT);\r
276                 if (temp == 0xffffffff)\r
277                 {\r
278                     printk("rga find mmu phy ddr error\n ");\r
279                     status = RGA_OUT_OF_RESOURCES;\r
280                     break;\r
281                 }\r
282 \r
283                 pageTable[i] = temp;\r
284             }\r
285 \r
286             return status;\r
287         }\r
288         #else\r
289         if(result <= 0 || result < pageCount)\r
290         {\r
291             struct vm_area_struct *vma;\r
292 \r
293             if (result>0) {\r
294                             down_read(&current->mm->mmap_sem);\r
295                             for (i = 0; i < result; i++)\r
296                                     put_page(pages[i]);\r
297                             up_read(&current->mm->mmap_sem);\r
298                     }\r
299 \r
300             for(i=0; i<pageCount; i++)\r
301             {\r
302                 vma = find_vma(current->mm, (Memory + i) << PAGE_SHIFT);\r
303 \r
304                 if (vma)//&& (vma->vm_flags & VM_PFNMAP) )\r
305                 {\r
306                     do\r
307                     {\r
308                         pte_t       * pte;\r
309                         spinlock_t  * ptl;\r
310                         unsigned long pfn;\r
311                         pgd_t * pgd;\r
312                         pud_t * pud;\r
313 \r
314                         pgd = pgd_offset(current->mm, (Memory + i) << PAGE_SHIFT);\r
315 \r
316                         if(pgd_val(*pgd) == 0)\r
317                         {\r
318                             //printk("rga pgd value is zero \n");\r
319                             break;\r
320                         }\r
321 \r
322                         pud = pud_offset(pgd, (Memory + i) << PAGE_SHIFT);\r
323                         if (pud)\r
324                         {\r
325                             pmd_t * pmd = pmd_offset(pud, (Memory + i) << PAGE_SHIFT);\r
326                             if (pmd)\r
327                             {\r
328                                 pte = pte_offset_map_lock(current->mm, pmd, (Memory + i) << PAGE_SHIFT, &ptl);\r
329                                 if (!pte)\r
330                                 {\r
331                                     pte_unmap_unlock(pte, ptl);\r
332                                     break;\r
333                                 }\r
334                             }\r
335                             else\r
336                             {\r
337                                 break;\r
338                             }\r
339                         }\r
340                         else\r
341                         {\r
342                             break;\r
343                         }\r
344 \r
345                         pfn = pte_pfn(*pte);\r
346                         Address = ((pfn << PAGE_SHIFT) | (((unsigned long)((Memory + i) << PAGE_SHIFT)) & ~PAGE_MASK));\r
347                         pte_unmap_unlock(pte, ptl);\r
348                     }\r
349                     while (0);\r
350 \r
351                     pageTable[i] = Address;\r
352                 }\r
353                 else\r
354                 {\r
355                     status = RGA_OUT_OF_RESOURCES;\r
356                     break;\r
357                 }\r
358             }\r
359 \r
360             return status;\r
361         }\r
362         #endif\r
363 \r
364         /* Fill the page table. */\r
365         for(i=0; i<pageCount; i++)\r
366         {\r
367             /* Get the physical address from page struct. */\r
368             pageTable[i] = page_to_phys(pages[i]);\r
369         }\r
370 \r
371         down_read(&current->mm->mmap_sem);\r
372                 for (i = 0; i < result; i++)\r
373                         put_page(pages[i]);\r
374                 up_read(&current->mm->mmap_sem);\r
375 \r
376         return 0;\r
377     }\r
378     while(0);\r
379 \r
380     return status;\r
381 }\r
382 \r
383 static int rga_MapION(struct sg_table *sg,\r
384                                uint32_t *Memory,\r
385                                int32_t  pageCount,\r
386                                uint32_t offset)\r
387 {\r
388     uint32_t i;\r
389     uint32_t status;\r
390     uint32_t Address;\r
391     uint32_t mapped_size = 0;\r
392     uint32_t len = 0;\r
393     struct scatterlist *sgl = sg->sgl;\r
394     uint32_t sg_num = 0;\r
395 \r
396     status = 0;\r
397     Address = 0;\r
398     offset = offset >> PAGE_SHIFT;\r
399     if (offset != 0) {\r
400         do {\r
401             len += (sg_dma_len(sgl) >> PAGE_SHIFT);\r
402                 if (len == offset) {\r
403                     sg_num += 1;\r
404                     break;\r
405             }\r
406             else {\r
407                 if (len > offset)\r
408                      break;\r
409             }\r
410                 sg_num += 1;\r
411         }\r
412         while((sgl = sg_next(sgl)) && (mapped_size < pageCount) && (sg_num < sg->nents));\r
413 \r
414         sgl = sg->sgl;\r
415         len = 0;\r
416         do {\r
417             len += (sg_dma_len(sgl) >> PAGE_SHIFT);\r
418             sgl = sg_next(sgl);\r
419         }\r
420         while(--sg_num);\r
421 \r
422         offset -= len;\r
423 \r
424         len = sg_dma_len(sgl) >> PAGE_SHIFT;\r
425         Address = sg_phys(sgl);\r
426         Address += offset;\r
427 \r
428         for(i=offset; i<len; i++) {\r
429              Memory[i - offset] = Address + (i << PAGE_SHIFT);\r
430         }\r
431         mapped_size += (len - offset);\r
432         sg_num = 1;\r
433         sgl = sg_next(sgl);\r
434         do {\r
435             len = sg_dma_len(sgl) >> PAGE_SHIFT;\r
436             Address = sg_phys(sgl);\r
437 \r
438             for(i=0; i<len; i++) {\r
439                 Memory[mapped_size + i] = Address + (i << PAGE_SHIFT);\r
440             }\r
441 \r
442             mapped_size += len;\r
443             sg_num += 1;\r
444         }\r
445         while((sgl = sg_next(sgl)) && (mapped_size < pageCount) && (sg_num < sg->nents));\r
446     }\r
447     else {\r
448         do {\r
449             len = sg_dma_len(sgl) >> PAGE_SHIFT;\r
450             Address = sg_phys(sgl);\r
451             for(i=0; i<len; i++) {\r
452                 Memory[mapped_size + i] = Address + (i << PAGE_SHIFT);\r
453             }\r
454             mapped_size += len;\r
455             sg_num += 1;\r
456         }\r
457         while((sgl = sg_next(sgl)) && (mapped_size < pageCount) && (sg_num < sg->nents));\r
458     }\r
459     return 0;\r
460 }\r
461 \r
462 \r
463 static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req)\r
464 {\r
465     int SrcMemSize, DstMemSize;\r
466     uint32_t SrcStart, DstStart;\r
467     uint32_t i;\r
468     uint32_t AllSize;\r
469     uint32_t *MMU_Base, *MMU_p, *MMU_Base_phys;\r
470     int ret;\r
471     int status;\r
472     uint32_t uv_size, v_size;\r
473 \r
474     struct page **pages = NULL;\r
475 \r
476     MMU_Base = NULL;\r
477 \r
478     SrcMemSize = 0;\r
479     DstMemSize = 0;\r
480 \r
481     do {\r
482         /* cal src buf mmu info */\r
483         SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr,\r
484                                         req->src.format, req->src.vir_w, req->src.act_h + req->src.y_offset,\r
485                                         &SrcStart);\r
486         if(SrcMemSize == 0) {\r
487             return -EINVAL;\r
488         }\r
489 \r
490         /* cal dst buf mmu info */\r
491 \r
492         DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
493                                         req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
494                                         &DstStart);\r
495         if(DstMemSize == 0)\r
496             return -EINVAL;\r
497 \r
498         /* Cal out the needed mem size */\r
499         SrcMemSize = (SrcMemSize + 15) & (~15);\r
500         DstMemSize = (DstMemSize + 15) & (~15);\r
501         AllSize = SrcMemSize + DstMemSize;\r
502 \r
503         if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) {\r
504             pr_err("RGA Get MMU mem failed\n");\r
505             status = RGA_MALLOC_ERROR;\r
506             break;\r
507         }\r
508 \r
509         mutex_lock(&rga_service.lock);\r
510         MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1));\r
511         MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1));\r
512         mutex_unlock(&rga_service.lock);\r
513 \r
514         pages = rga_mmu_buf.pages;\r
515 \r
516         if((req->mmu_info.mmu_flag >> 8) & 1) {\r
517             if (req->sg_src) {\r
518                 ret = rga_MapION(req->sg_src, &MMU_Base[0], SrcMemSize, req->line_draw_info.flag);\r
519             }\r
520             else {\r
521                 ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize);\r
522                 if (ret < 0) {\r
523                     pr_err("rga map src memory failed\n");\r
524                     status = ret;\r
525                     break;\r
526                 }\r
527             }\r
528         }\r
529         else {\r
530             MMU_p = MMU_Base;\r
531 \r
532             if(req->src.yrgb_addr == (uint32_t)rga_service.pre_scale_buf) {\r
533                 for(i=0; i<SrcMemSize; i++)\r
534                     MMU_p[i] = rga_service.pre_scale_buf[i];\r
535             }\r
536             else {\r
537                 for(i=0; i<SrcMemSize; i++)\r
538                     MMU_p[i] = (uint32_t)((SrcStart + i) << PAGE_SHIFT);\r
539             }\r
540         }\r
541 \r
542         if ((req->mmu_info.mmu_flag >> 10) & 1) {\r
543             if (req->sg_dst) {\r
544                 ret = rga_MapION(req->sg_dst, &MMU_Base[SrcMemSize], DstMemSize, req->line_draw_info.line_width);\r
545             }\r
546             else {\r
547                 ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize);\r
548                 if (ret < 0) {\r
549                     pr_err("rga map dst memory failed\n");\r
550                     status = ret;\r
551                     break;\r
552                 }\r
553             }\r
554         }\r
555         else {\r
556             MMU_p = MMU_Base + SrcMemSize;\r
557             for(i=0; i<DstMemSize; i++)\r
558                 MMU_p[i] = (uint32_t)((DstStart + i) << PAGE_SHIFT);\r
559         }\r
560 \r
561         MMU_Base[AllSize] = MMU_Base[AllSize-1];\r
562 \r
563         /* zsq\r
564          * change the buf address in req struct\r
565          */\r
566 \r
567         req->mmu_info.base_addr = (uint32_t)MMU_Base_phys >> 2;\r
568 \r
569         uv_size = (req->src.uv_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
570         v_size = (req->src.v_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
571 \r
572         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK));\r
573         req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (uv_size << PAGE_SHIFT);\r
574         req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (v_size << PAGE_SHIFT);\r
575 \r
576         uv_size = (req->dst.uv_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
577 \r
578         req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | (SrcMemSize << PAGE_SHIFT);\r
579         req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((SrcMemSize + uv_size) << PAGE_SHIFT);\r
580 \r
581         /* flush data to DDR */\r
582         dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
583         outer_flush_range(virt_to_phys(MMU_Base), virt_to_phys(MMU_Base + AllSize + 1));\r
584 \r
585         rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16);\r
586         reg->MMU_len = AllSize + 16;\r
587 \r
588         status = 0;\r
589 \r
590         return status;\r
591     }\r
592     while(0);\r
593 \r
594     return status;\r
595 }\r
596 \r
597 static int rga_mmu_info_color_palette_mode(struct rga_reg *reg, struct rga_req *req)\r
598 {\r
599     int SrcMemSize, DstMemSize, CMDMemSize;\r
600     uint32_t SrcStart, DstStart, CMDStart;\r
601     struct page **pages = NULL;\r
602     uint32_t i;\r
603     uint32_t AllSize;\r
604     uint32_t *MMU_Base = NULL, *MMU_Base_phys = NULL;\r
605     uint32_t *MMU_p;\r
606     int ret, status;\r
607     uint32_t stride;\r
608 \r
609     uint8_t shift;\r
610     uint16_t sw, byte_num;\r
611 \r
612     shift = 3 - (req->palette_mode & 3);\r
613     sw = req->src.vir_w;\r
614     byte_num = sw >> shift;\r
615     stride = (byte_num + 3) & (~3);\r
616 \r
617     do {\r
618         SrcMemSize = rga_mem_size_cal(req->src.yrgb_addr, stride, &SrcStart);\r
619         if(SrcMemSize == 0) {\r
620             return -EINVAL;\r
621         }\r
622 \r
623         DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
624                                         req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
625                                         &DstStart);\r
626         if(DstMemSize == 0) {\r
627             return -EINVAL;\r
628         }\r
629 \r
630         CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);\r
631         if(CMDMemSize == 0) {\r
632             return -EINVAL;\r
633         }\r
634 \r
635         SrcMemSize = (SrcMemSize + 15) & (~15);\r
636         DstMemSize = (DstMemSize + 15) & (~15);\r
637         CMDMemSize = (CMDMemSize + 15) & (~15);\r
638 \r
639         AllSize = SrcMemSize + DstMemSize + CMDMemSize;\r
640 \r
641         if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) {\r
642             pr_err("RGA Get MMU mem failed\n");\r
643             status = RGA_MALLOC_ERROR;\r
644             break;\r
645         }\r
646 \r
647         mutex_lock(&rga_service.lock);\r
648         MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1));\r
649         MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1));\r
650         mutex_unlock(&rga_service.lock);\r
651 \r
652         pages = rga_mmu_buf.pages;\r
653 \r
654         /* map CMD addr */\r
655         for(i=0; i<CMDMemSize; i++) {\r
656             MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i)<<PAGE_SHIFT));\r
657         }\r
658 \r
659         /* map src addr */\r
660         if (req->src.yrgb_addr < KERNEL_SPACE_VALID) {\r
661             ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
662             if (ret < 0) {\r
663                 pr_err("rga map src memory failed\n");\r
664                 status = ret;\r
665                 break;\r
666             }\r
667         }\r
668         else {\r
669             MMU_p = MMU_Base + CMDMemSize;\r
670 \r
671             for(i=0; i<SrcMemSize; i++)\r
672             {\r
673                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
674             }\r
675         }\r
676 \r
677         /* map dst addr */\r
678         if (req->src.yrgb_addr < KERNEL_SPACE_VALID) {\r
679             ret = rga_MapUserMemory(&pages[CMDMemSize + SrcMemSize], &MMU_Base[CMDMemSize + SrcMemSize], DstStart, DstMemSize);\r
680             if (ret < 0) {\r
681                 pr_err("rga map dst memory failed\n");\r
682                 status = ret;\r
683                 break;\r
684             }\r
685         }\r
686         else {\r
687             MMU_p = MMU_Base + CMDMemSize + SrcMemSize;\r
688             for(i=0; i<DstMemSize; i++)\r
689                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT));\r
690         }\r
691 \r
692 \r
693         /* zsq\r
694          * change the buf address in req struct\r
695          * for the reason of lie to MMU\r
696          */\r
697         req->mmu_info.base_addr = (virt_to_phys(MMU_Base)>>2);\r
698         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
699         req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((CMDMemSize + SrcMemSize) << PAGE_SHIFT);\r
700 \r
701         /*record the malloc buf for the cmd end to release*/\r
702         reg->MMU_base = MMU_Base;\r
703 \r
704         /* flush data to DDR */\r
705         dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
706         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));\r
707 \r
708         rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16);\r
709         reg->MMU_len = AllSize + 16;\r
710 \r
711         return status;\r
712 \r
713     }\r
714     while(0);\r
715 \r
716     return 0;\r
717 }\r
718 \r
719 static int rga_mmu_info_color_fill_mode(struct rga_reg *reg, struct rga_req *req)\r
720 {\r
721     int DstMemSize;\r
722     uint32_t DstStart;\r
723     struct page **pages = NULL;\r
724     uint32_t i;\r
725     uint32_t AllSize;\r
726     uint32_t *MMU_Base, *MMU_p, *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         DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
735                                         req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
736                                         &DstStart);\r
737         if(DstMemSize == 0) {\r
738             return -EINVAL;\r
739         }\r
740 \r
741         AllSize = (DstMemSize + 15) & (~15);\r
742 \r
743         pages = rga_mmu_buf.pages;\r
744 \r
745         if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) {\r
746             pr_err("RGA Get MMU mem failed\n");\r
747             status = RGA_MALLOC_ERROR;\r
748             break;\r
749         }\r
750 \r
751         mutex_lock(&rga_service.lock);\r
752         MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1));\r
753         MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1));\r
754         mutex_unlock(&rga_service.lock);\r
755 \r
756         if (req->dst.yrgb_addr < KERNEL_SPACE_VALID) {\r
757             if (req->sg_dst) {\r
758                 ret = rga_MapION(req->sg_dst, &MMU_Base[0], DstMemSize, req->line_draw_info.line_width);\r
759             }\r
760             else {\r
761                 ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], DstStart, DstMemSize);\r
762                 if (ret < 0) {\r
763                     pr_err("rga map dst memory failed\n");\r
764                     status = ret;\r
765                     break;\r
766                 }\r
767             }\r
768         }\r
769         else {\r
770             MMU_p = MMU_Base;\r
771             for(i=0; i<DstMemSize; i++)\r
772                 MMU_p[i] = (uint32_t)((DstStart + i) << PAGE_SHIFT);\r
773         }\r
774 \r
775         MMU_Base[AllSize] = MMU_Base[AllSize - 1];\r
776 \r
777         /* zsq\r
778          * change the buf address in req struct\r
779          */\r
780 \r
781         req->mmu_info.base_addr = ((uint32_t)(MMU_Base_phys)>>2);\r
782         req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK));\r
783 \r
784         /*record the malloc buf for the cmd end to release*/\r
785         reg->MMU_base = MMU_Base;\r
786 \r
787         /* flush data to DDR */\r
788         dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
789         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));\r
790 \r
791         rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16);\r
792         reg->MMU_len = AllSize + 16;\r
793 \r
794         return 0;\r
795     }\r
796     while(0);\r
797 \r
798     return status;\r
799 }\r
800 \r
801 \r
802 static int rga_mmu_info_line_point_drawing_mode(struct rga_reg *reg, struct rga_req *req)\r
803 {\r
804     int DstMemSize;\r
805     uint32_t DstStart;\r
806     struct page **pages = NULL;\r
807     uint32_t i;\r
808     uint32_t AllSize;\r
809     uint32_t *MMU_Base, *MMU_p;\r
810     int ret, status;\r
811 \r
812     MMU_Base = NULL;\r
813 \r
814     do\r
815     {\r
816         /* cal dst buf mmu info */\r
817         DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
818                                         req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
819                                         &DstStart);\r
820         if(DstMemSize == 0) {\r
821             return -EINVAL;\r
822         }\r
823 \r
824         AllSize = DstMemSize;\r
825 \r
826         pages = kzalloc((AllSize + 1) * sizeof(struct page *), GFP_KERNEL);\r
827         if(pages == NULL) {\r
828             pr_err("RGA MMU malloc pages mem failed\n");\r
829             status = RGA_MALLOC_ERROR;\r
830             break;\r
831         }\r
832 \r
833         MMU_Base = kzalloc((AllSize + 1) * sizeof(uint32_t), GFP_KERNEL);\r
834         if(pages == NULL) {\r
835             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
836             status = RGA_MALLOC_ERROR;\r
837             break;\r
838         }\r
839 \r
840         if (req->dst.yrgb_addr < KERNEL_SPACE_VALID)\r
841         {\r
842             ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], DstStart, DstMemSize);\r
843             if (ret < 0) {\r
844                 pr_err("rga map dst memory failed\n");\r
845                 status = ret;\r
846                 break;\r
847             }\r
848         }\r
849         else\r
850         {\r
851             MMU_p = MMU_Base;\r
852 \r
853             for(i=0; i<DstMemSize; i++)\r
854             {\r
855                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT));\r
856             }\r
857         }\r
858 \r
859         /* zsq\r
860          * change the buf address in req struct\r
861          * for the reason of lie to MMU\r
862          */\r
863         req->mmu_info.base_addr = (virt_to_phys(MMU_Base) >> 2);\r
864         req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK));\r
865 \r
866 \r
867         /*record the malloc buf for the cmd end to release*/\r
868         reg->MMU_base = MMU_Base;\r
869 \r
870         /* flush data to DDR */\r
871         dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
872         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));\r
873 \r
874         /* Free the page table */\r
875         if (pages != NULL) {\r
876             kfree(pages);\r
877         }\r
878 \r
879         return 0;\r
880 \r
881     }\r
882     while(0);\r
883 \r
884     if (pages != NULL)\r
885         kfree(pages);\r
886 \r
887     if (MMU_Base != NULL)\r
888         kfree(MMU_Base);\r
889 \r
890     return status;\r
891 }\r
892 \r
893 static int rga_mmu_info_blur_sharp_filter_mode(struct rga_reg *reg, struct rga_req *req)\r
894 {\r
895     int SrcMemSize, DstMemSize;\r
896     uint32_t SrcStart, DstStart;\r
897     struct page **pages = NULL;\r
898     uint32_t i;\r
899     uint32_t AllSize;\r
900     uint32_t *MMU_Base, *MMU_p;\r
901     int ret, status;\r
902     uint32_t uv_size, v_size;\r
903 \r
904     MMU_Base = NULL;\r
905 \r
906     do\r
907     {\r
908         /* cal src buf mmu info */\r
909         SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr,\r
910                                         req->src.format, req->src.vir_w, req->src.vir_h,\r
911                                         &SrcStart);\r
912         if(SrcMemSize == 0) {\r
913             return -EINVAL;\r
914         }\r
915 \r
916         /* cal dst buf mmu info */\r
917         DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
918                                         req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
919                                         &DstStart);\r
920         if(DstMemSize == 0) {\r
921             return -EINVAL;\r
922         }\r
923 \r
924         AllSize = SrcMemSize + DstMemSize;\r
925 \r
926         pages = kzalloc((AllSize + 1) * sizeof(struct page *), GFP_KERNEL);\r
927         if(pages == NULL) {\r
928             pr_err("RGA MMU malloc pages mem failed\n");\r
929             status = RGA_MALLOC_ERROR;\r
930             break;\r
931         }\r
932 \r
933         MMU_Base = kzalloc((AllSize + 1)* sizeof(uint32_t), GFP_KERNEL);\r
934         if(pages == NULL) {\r
935             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
936             status = RGA_MALLOC_ERROR;\r
937             break;\r
938         }\r
939 \r
940         if (req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
941         {\r
942             ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize);\r
943             if (ret < 0)\r
944             {\r
945                 pr_err("rga map src memory failed\n");\r
946                 status = ret;\r
947                 break;\r
948             }\r
949         }\r
950         else\r
951         {\r
952             MMU_p = MMU_Base;\r
953 \r
954             for(i=0; i<SrcMemSize; i++)\r
955             {\r
956                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
957             }\r
958         }\r
959 \r
960 \r
961         if (req->dst.yrgb_addr < KERNEL_SPACE_VALID)\r
962         {\r
963             ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize);\r
964             if (ret < 0)\r
965             {\r
966                 pr_err("rga map dst memory failed\n");\r
967                 status = ret;\r
968                 break;\r
969             }\r
970         }\r
971         else\r
972         {\r
973             MMU_p = MMU_Base + SrcMemSize;\r
974 \r
975             for(i=0; i<DstMemSize; i++)\r
976             {\r
977                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT));\r
978             }\r
979         }\r
980 \r
981         MMU_Base[AllSize] = MMU_Base[AllSize - 1];\r
982 \r
983         /* zsq\r
984          * change the buf address in req struct\r
985          * for the reason of lie to MMU\r
986          */\r
987         req->mmu_info.base_addr = (virt_to_phys(MMU_Base) >> 2);\r
988 \r
989         uv_size = (req->src.uv_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
990         v_size = (req->src.v_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
991 \r
992         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK));\r
993         req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (uv_size << PAGE_SHIFT);\r
994         req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (v_size << PAGE_SHIFT);\r
995 \r
996         uv_size = (req->dst.uv_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
997         v_size = (req->dst.v_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
998 \r
999         req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | (SrcMemSize << PAGE_SHIFT);\r
1000         req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((SrcMemSize + uv_size) << PAGE_SHIFT);\r
1001         req->dst.v_addr = (req->dst.v_addr & (~PAGE_MASK)) | ((SrcMemSize + v_size) << PAGE_SHIFT);\r
1002 \r
1003 \r
1004         /*record the malloc buf for the cmd end to release*/\r
1005         reg->MMU_base = MMU_Base;\r
1006 \r
1007         /* flush data to DDR */\r
1008         dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
1009         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));\r
1010 \r
1011         /* Free the page table */\r
1012         if (pages != NULL) {\r
1013             kfree(pages);\r
1014         }\r
1015 \r
1016         return 0;\r
1017     }\r
1018     while(0);\r
1019 \r
1020     if (pages != NULL)\r
1021         kfree(pages);\r
1022 \r
1023     if (MMU_Base != NULL)\r
1024         kfree(MMU_Base);\r
1025 \r
1026     return status;\r
1027 }\r
1028 \r
1029 \r
1030 \r
1031 static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req)\r
1032 {\r
1033     int SrcMemSize, DstMemSize;\r
1034     uint32_t SrcStart, DstStart;\r
1035     struct page **pages = NULL;\r
1036     uint32_t i;\r
1037     uint32_t AllSize;\r
1038     uint32_t *MMU_Base, *MMU_p, *MMU_Base_phys;\r
1039     int ret;\r
1040     int status;\r
1041     uint32_t uv_size, v_size;\r
1042 \r
1043     MMU_Base = NULL;\r
1044 \r
1045     do {\r
1046         /* cal src buf mmu info */\r
1047         SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr,\r
1048                                         req->src.format, req->src.vir_w, req->src.vir_h,\r
1049                                         &SrcStart);\r
1050         if(SrcMemSize == 0) {\r
1051             return -EINVAL;\r
1052         }\r
1053 \r
1054         /* cal dst buf mmu info */\r
1055         DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
1056                                         req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
1057                                         &DstStart);\r
1058         if(DstMemSize == 0) {\r
1059             return -EINVAL;\r
1060         }\r
1061 \r
1062             SrcMemSize = (SrcMemSize + 15) & (~15);\r
1063             DstMemSize = (DstMemSize + 15) & (~15);\r
1064 \r
1065         AllSize = SrcMemSize + DstMemSize;\r
1066 \r
1067         pages = rga_mmu_buf.pages;\r
1068 \r
1069         if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) {\r
1070             pr_err("RGA Get MMU mem failed\n");\r
1071             status = RGA_MALLOC_ERROR;\r
1072             break;\r
1073         }\r
1074 \r
1075         mutex_lock(&rga_service.lock);\r
1076         MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1));\r
1077         MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1));\r
1078         mutex_unlock(&rga_service.lock);\r
1079 \r
1080         /* map src pages */\r
1081         if ((req->mmu_info.mmu_flag >> 8) & 1) {\r
1082             if (req->sg_src) {\r
1083                 ret = rga_MapION(req->sg_src, &MMU_Base[0], SrcMemSize,req->line_draw_info.flag);\r
1084             }\r
1085             else {\r
1086                 ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize);\r
1087                 if (ret < 0) {\r
1088                     pr_err("rga map src memory failed\n");\r
1089                     status = ret;\r
1090                     break;\r
1091                 }\r
1092             }\r
1093         }\r
1094         else {\r
1095             MMU_p = MMU_Base;\r
1096 \r
1097             for(i=0; i<SrcMemSize; i++)\r
1098                 MMU_p[i] = (uint32_t)((SrcStart + i) << PAGE_SHIFT);\r
1099         }\r
1100 \r
1101         if((req->mmu_info.mmu_flag >> 10) & 1) {\r
1102             if (req->sg_dst) {\r
1103                 ret = rga_MapION(req->sg_dst, &MMU_Base[SrcMemSize], DstMemSize, req->line_draw_info.line_width);\r
1104             }\r
1105             else {\r
1106                 ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize);\r
1107                 if (ret < 0) {\r
1108                     pr_err("rga map dst memory failed\n");\r
1109                     status = ret;\r
1110                     break;\r
1111                 }\r
1112             }\r
1113         }\r
1114         else\r
1115         {\r
1116             /* kernel space */\r
1117             MMU_p = MMU_Base + SrcMemSize;\r
1118 \r
1119             if(req->dst.yrgb_addr == (uint32_t)rga_service.pre_scale_buf) {\r
1120                 for(i=0; i<DstMemSize; i++)\r
1121                     MMU_p[i] = rga_service.pre_scale_buf[i];\r
1122             }\r
1123             else {\r
1124                 for(i=0; i<DstMemSize; i++)\r
1125                     MMU_p[i] = (uint32_t)((DstStart + i) << PAGE_SHIFT);\r
1126             }\r
1127         }\r
1128 \r
1129         MMU_Base[AllSize] = MMU_Base[AllSize];\r
1130 \r
1131         /* zsq\r
1132          * change the buf address in req struct\r
1133          * for the reason of lie to MMU\r
1134          */\r
1135 \r
1136         req->mmu_info.base_addr = ((uint32_t)(MMU_Base_phys)>>2);\r
1137 \r
1138         uv_size = (req->src.uv_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
1139         v_size = (req->src.v_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
1140 \r
1141         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK));\r
1142         req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (uv_size << PAGE_SHIFT);\r
1143         req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (v_size << PAGE_SHIFT);\r
1144 \r
1145         uv_size = (req->dst.uv_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
1146         v_size = (req->dst.v_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT;\r
1147 \r
1148         req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((SrcMemSize) << PAGE_SHIFT);\r
1149         req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((SrcMemSize + uv_size) << PAGE_SHIFT);\r
1150         req->dst.v_addr = (req->dst.v_addr & (~PAGE_MASK)) | ((SrcMemSize + v_size) << PAGE_SHIFT);\r
1151 \r
1152         /*record the malloc buf for the cmd end to release*/\r
1153         reg->MMU_base = MMU_Base;\r
1154 \r
1155         /* flush data to DDR */\r
1156         dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));\r
1157         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));\r
1158 \r
1159             rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16);\r
1160         reg->MMU_len = AllSize + 16;\r
1161 \r
1162         return 0;\r
1163     }\r
1164     while(0);\r
1165 \r
1166     return status;\r
1167 }\r
1168 \r
1169 \r
1170 static int rga_mmu_info_update_palette_table_mode(struct rga_reg *reg, struct rga_req *req)\r
1171 {\r
1172     int SrcMemSize, CMDMemSize;\r
1173     uint32_t SrcStart, CMDStart;\r
1174     struct page **pages = NULL;\r
1175     uint32_t i;\r
1176     uint32_t AllSize;\r
1177     uint32_t *MMU_Base, *MMU_p;\r
1178     int ret, status;\r
1179 \r
1180     MMU_Base = NULL;\r
1181 \r
1182     do\r
1183     {\r
1184         /* cal src buf mmu info */\r
1185         SrcMemSize = rga_mem_size_cal(req->src.yrgb_addr, req->src.vir_w * req->src.vir_h, &SrcStart);\r
1186         if(SrcMemSize == 0) {\r
1187             return -EINVAL;\r
1188         }\r
1189 \r
1190         /* cal cmd buf mmu info */\r
1191         CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);\r
1192         if(CMDMemSize == 0) {\r
1193             return -EINVAL;\r
1194         }\r
1195 \r
1196         AllSize = SrcMemSize + CMDMemSize;\r
1197 \r
1198         pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
1199         if(pages == NULL) {\r
1200             pr_err("RGA MMU malloc pages mem failed\n");\r
1201             status = RGA_MALLOC_ERROR;\r
1202             break;\r
1203         }\r
1204 \r
1205         MMU_Base = kzalloc((AllSize + 1)* sizeof(uint32_t), GFP_KERNEL);\r
1206         if(pages == NULL) {\r
1207             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
1208             status = RGA_MALLOC_ERROR;\r
1209             break;\r
1210         }\r
1211 \r
1212         for(i=0; i<CMDMemSize; i++) {\r
1213             MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i) << PAGE_SHIFT));\r
1214         }\r
1215 \r
1216         if (req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
1217         {\r
1218             ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
1219             if (ret < 0) {\r
1220                 pr_err("rga map src memory failed\n");\r
1221                 return -EINVAL;\r
1222             }\r
1223         }\r
1224         else\r
1225         {\r
1226             MMU_p = MMU_Base + CMDMemSize;\r
1227 \r
1228                 for(i=0; i<SrcMemSize; i++)\r
1229                 {\r
1230                     MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
1231                 }\r
1232         }\r
1233 \r
1234         /* zsq\r
1235          * change the buf address in req struct\r
1236          * for the reason of lie to MMU\r
1237          */\r
1238         req->mmu_info.base_addr = (virt_to_phys(MMU_Base) >> 2);\r
1239 \r
1240         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
1241 \r
1242         /*record the malloc buf for the cmd end to release*/\r
1243         reg->MMU_base = MMU_Base;\r
1244 \r
1245         /* flush data to DDR */\r
1246         dmac_flush_range(MMU_Base, (MMU_Base + AllSize));\r
1247         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize));\r
1248 \r
1249         if (pages != NULL) {\r
1250             /* Free the page table */\r
1251             kfree(pages);\r
1252         }\r
1253 \r
1254         return 0;\r
1255     }\r
1256     while(0);\r
1257 \r
1258     if (pages != NULL)\r
1259         kfree(pages);\r
1260 \r
1261     if (MMU_Base != NULL)\r
1262         kfree(MMU_Base);\r
1263 \r
1264     return status;\r
1265 }\r
1266 \r
1267 static int rga_mmu_info_update_patten_buff_mode(struct rga_reg *reg, struct rga_req *req)\r
1268 {\r
1269     int SrcMemSize, CMDMemSize;\r
1270     uint32_t SrcStart, CMDStart;\r
1271     struct page **pages = NULL;\r
1272     uint32_t i;\r
1273     uint32_t AllSize;\r
1274     uint32_t *MMU_Base, *MMU_p;\r
1275     int ret, status;\r
1276 \r
1277     MMU_Base = MMU_p = 0;\r
1278 \r
1279     do\r
1280     {\r
1281 \r
1282         /* cal src buf mmu info */\r
1283         SrcMemSize = rga_mem_size_cal(req->pat.yrgb_addr, req->pat.vir_w * req->pat.vir_h * 4, &SrcStart);\r
1284         if(SrcMemSize == 0) {\r
1285             return -EINVAL;\r
1286         }\r
1287 \r
1288         /* cal cmd buf mmu info */\r
1289         CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);\r
1290         if(CMDMemSize == 0) {\r
1291             return -EINVAL;\r
1292         }\r
1293 \r
1294         AllSize = SrcMemSize + CMDMemSize;\r
1295 \r
1296         pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
1297         if(pages == NULL) {\r
1298             pr_err("RGA MMU malloc pages mem failed\n");\r
1299             status = RGA_MALLOC_ERROR;\r
1300             break;\r
1301         }\r
1302 \r
1303         MMU_Base = kzalloc(AllSize * sizeof(uint32_t), GFP_KERNEL);\r
1304         if(pages == NULL) {\r
1305             pr_err("RGA MMU malloc MMU_Base point failed\n");\r
1306             status = RGA_MALLOC_ERROR;\r
1307             break;\r
1308         }\r
1309 \r
1310         for(i=0; i<CMDMemSize; i++) {\r
1311             MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i) << PAGE_SHIFT));\r
1312         }\r
1313 \r
1314         if (req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
1315         {\r
1316             ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
1317             if (ret < 0) {\r
1318                 pr_err("rga map src memory failed\n");\r
1319                 status = ret;\r
1320                 break;\r
1321             }\r
1322         }\r
1323         else\r
1324         {\r
1325             MMU_p = MMU_Base + CMDMemSize;\r
1326 \r
1327             for(i=0; i<SrcMemSize; i++)\r
1328             {\r
1329                 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
1330             }\r
1331         }\r
1332 \r
1333         /* zsq\r
1334          * change the buf address in req struct\r
1335          * for the reason of lie to MMU\r
1336          */\r
1337         req->mmu_info.base_addr = (virt_to_phys(MMU_Base) >> 2);\r
1338 \r
1339         req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
1340 \r
1341         /*record the malloc buf for the cmd end to release*/\r
1342         reg->MMU_base = MMU_Base;\r
1343 \r
1344         /* flush data to DDR */\r
1345         dmac_flush_range(MMU_Base, (MMU_Base + AllSize));\r
1346         outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize));\r
1347 \r
1348         if (pages != NULL) {\r
1349             /* Free the page table */\r
1350             kfree(pages);\r
1351         }\r
1352 \r
1353         return 0;\r
1354 \r
1355     }\r
1356     while(0);\r
1357 \r
1358     if (pages != NULL)\r
1359         kfree(pages);\r
1360 \r
1361     if (MMU_Base != NULL)\r
1362         kfree(MMU_Base);\r
1363 \r
1364     return status;\r
1365 }\r
1366 \r
1367 int rga_set_mmu_info(struct rga_reg *reg, struct rga_req *req)\r
1368 {\r
1369     int ret;\r
1370 \r
1371     switch (req->render_mode) {\r
1372         case bitblt_mode :\r
1373             ret = rga_mmu_info_BitBlt_mode(reg, req);\r
1374             break;\r
1375         case color_palette_mode :\r
1376             ret = rga_mmu_info_color_palette_mode(reg, req);\r
1377             break;\r
1378         case color_fill_mode :\r
1379             ret = rga_mmu_info_color_fill_mode(reg, req);\r
1380             break;\r
1381         case line_point_drawing_mode :\r
1382             ret = rga_mmu_info_line_point_drawing_mode(reg, req);\r
1383             break;\r
1384         case blur_sharp_filter_mode :\r
1385             ret = rga_mmu_info_blur_sharp_filter_mode(reg, req);\r
1386             break;\r
1387         case pre_scaling_mode :\r
1388             ret = rga_mmu_info_pre_scale_mode(reg, req);\r
1389             break;\r
1390         case update_palette_table_mode :\r
1391             ret = rga_mmu_info_update_palette_table_mode(reg, req);\r
1392             break;\r
1393         case update_patten_buff_mode :\r
1394             ret = rga_mmu_info_update_patten_buff_mode(reg, req);\r
1395             break;\r
1396         default :\r
1397             ret = -1;\r
1398             break;\r
1399     }\r
1400 \r
1401     return ret;\r
1402 }\r
1403 \r