rk30: add RGA driver
[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 <asm/atomic.h>\r
16 \r
17 \r
18 #include "rga_mmu_info.h"\r
19 \r
20 \r
21 extern rga_service_info rga_service;\r
22 \r
23 #define KERNEL_SPACE_VALID    0xc0000000\r
24 \r
25 static int rga_mem_size_cal(uint32_t Mem, uint32_t MemSize, uint32_t *StartAddr) \r
26 {\r
27     uint32_t start, end;\r
28     uint32_t pageCount;\r
29 \r
30     end = (Mem + (MemSize + PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
31     start = Mem >> PAGE_SHIFT;\r
32     pageCount = end - start;\r
33     *StartAddr = start;\r
34     return pageCount;    \r
35 }\r
36 \r
37 static int rga_buf_size_cal(uint32_t yrgb_addr, uint32_t uv_addr, uint32_t v_addr, \r
38                                         int format, uint32_t w, uint32_t h, uint32_t *StartAddr ) \r
39 {\r
40     uint32_t size_yrgb = 0;\r
41     uint32_t size_uv = 0;\r
42     uint32_t size_v = 0;\r
43     uint32_t stride = 0;\r
44     uint32_t start, end;\r
45     uint32_t pageCount;\r
46        \r
47     switch(format)\r
48     {\r
49         case RK_FORMAT_RGBA_8888 :\r
50             stride = (w * 4 + 3) & (~3);\r
51             size_yrgb = stride*h;\r
52             end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
53             start = yrgb_addr >> PAGE_SHIFT;\r
54             pageCount = end - start;            \r
55             break;\r
56         case RK_FORMAT_RGBX_8888 :\r
57             stride = (w * 4 + 3) & (~3);\r
58             size_yrgb = stride*h;\r
59             end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
60             start = yrgb_addr >> PAGE_SHIFT;\r
61             pageCount = end - start;\r
62             break;\r
63         case RK_FORMAT_RGB_888 :\r
64             stride = (w * 3 + 3) & (~3);\r
65             size_yrgb = stride*h;\r
66             end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
67             start = yrgb_addr >> PAGE_SHIFT;\r
68             pageCount = end - start;\r
69             break;\r
70         case RK_FORMAT_BGRA_8888 :\r
71             size_yrgb = w*h*4;\r
72             end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
73             start = yrgb_addr >> PAGE_SHIFT;\r
74             pageCount = end - start;\r
75             *StartAddr = start;\r
76             break;\r
77         case RK_FORMAT_RGB_565 :\r
78             stride = (w*2 + 3) & (~3);            \r
79             size_yrgb = stride * h;\r
80             end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
81             start = yrgb_addr >> PAGE_SHIFT;\r
82             pageCount = end - start;\r
83             break;\r
84         case RK_FORMAT_RGBA_5551 :\r
85             stride = (w*2 + 3) & (~3);            \r
86             size_yrgb = stride * h;\r
87             end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
88             start = yrgb_addr >> PAGE_SHIFT;\r
89             pageCount = end - start;\r
90             break;\r
91         case RK_FORMAT_RGBA_4444 :\r
92             stride = (w*2 + 3) & (~3);            \r
93             size_yrgb = stride * h;\r
94             end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
95             start = yrgb_addr >> PAGE_SHIFT;\r
96             pageCount = end - start;\r
97             break;\r
98         case RK_FORMAT_BGR_888 :\r
99             stride = (w*3 + 3) & (~3);            \r
100             size_yrgb = stride * h;\r
101             end = (yrgb_addr + (size_yrgb + PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
102             start = yrgb_addr >> PAGE_SHIFT;\r
103             pageCount = end - start;\r
104             break;\r
105 \r
106         /* YUV FORMAT */\r
107         case RK_FORMAT_YCbCr_422_SP :\r
108             stride = (w + 3) & (~3);\r
109             size_yrgb = stride * h;\r
110             size_uv = stride * h;\r
111             start = MIN(yrgb_addr, uv_addr);\r
112             start >>= PAGE_SHIFT; \r
113             end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv));\r
114             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
115             pageCount = end - start;            \r
116             break;\r
117         case RK_FORMAT_YCbCr_422_P :\r
118             stride = (w + 3) & (~3);\r
119             size_yrgb = stride * h;\r
120             size_uv = ((stride >> 1) * h);\r
121             size_v = ((stride >> 1) * h);\r
122             start = MIN(MIN(yrgb_addr, uv_addr), v_addr);\r
123             start = start >> PAGE_SHIFT; \r
124             end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v));\r
125             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
126             pageCount = end - start;            \r
127             break;\r
128         case RK_FORMAT_YCbCr_420_SP :\r
129             stride = (w + 3) & (~3);\r
130             size_yrgb = stride * h;\r
131             size_uv = (stride * (h >> 1));            \r
132             start = MIN(yrgb_addr, uv_addr);\r
133             start >>= PAGE_SHIFT; \r
134             end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv));\r
135             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
136             pageCount = end - start;\r
137             break;\r
138         case RK_FORMAT_YCbCr_420_P :\r
139             stride = (w + 3) & (~3);\r
140             size_yrgb = stride * h;\r
141             size_uv = ((stride >> 1) * (h >> 1));\r
142             size_v = ((stride >> 1) * (h >> 1));\r
143             start = MIN(MIN(yrgb_addr, uv_addr), v_addr);\r
144             start >>= PAGE_SHIFT; \r
145             end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v));\r
146             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
147             pageCount = end - start;            \r
148             break;\r
149 \r
150         case RK_FORMAT_YCrCb_422_SP :\r
151             stride = (w + 3) & (~3);\r
152             size_yrgb = stride * h;\r
153             size_uv = stride * h;\r
154             start = MIN(yrgb_addr, uv_addr);\r
155             start >>= PAGE_SHIFT; \r
156             end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv));\r
157             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
158             pageCount = end - start;\r
159             break;\r
160         case RK_FORMAT_YCrCb_422_P :\r
161             stride = (w + 3) & (~3);\r
162             size_yrgb = stride * h;\r
163             size_uv = ((stride >> 1) * h);\r
164             size_v = ((stride >> 1) * h);\r
165             start = MIN(MIN(yrgb_addr, uv_addr), v_addr);\r
166             start >>= PAGE_SHIFT; \r
167             end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v));\r
168             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
169             pageCount = end - start;\r
170             break;\r
171             \r
172         case RK_FORMAT_YCrCb_420_SP :\r
173             stride = (w + 3) & (~3);\r
174             size_yrgb = stride * h;\r
175             size_uv = (stride * (h >> 1));            \r
176             start = MIN(yrgb_addr, uv_addr);\r
177             start >>= PAGE_SHIFT; \r
178             end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv));\r
179             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
180             pageCount = end - start;\r
181             break;\r
182         case RK_FORMAT_YCrCb_420_P :\r
183             stride = (w + 3) & (~3);\r
184             size_yrgb = stride * h;\r
185             size_uv = ((stride >> 1) * (h >> 1));\r
186             size_v = ((stride >> 1) * (h >> 1));\r
187             start = MIN(MIN(yrgb_addr, uv_addr), v_addr);\r
188             start >>= PAGE_SHIFT; \r
189             end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v));\r
190             end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT;\r
191             pageCount = end - start;\r
192             break;\r
193         #if 0    \r
194         case RK_FORMAT_BPP1 :            \r
195             break;\r
196         case RK_FORMAT_BPP2 :\r
197             break;\r
198         case RK_FORMAT_BPP4 :\r
199             break;\r
200         case RK_FORMAT_BPP8 :\r
201             break;\r
202         #endif    \r
203         default :\r
204             pageCount = 0;\r
205             start = 0;\r
206             break;\r
207     }\r
208 \r
209     *StartAddr = start;\r
210     return pageCount;    \r
211 }\r
212 \r
213 static int rga_MapUserMemory(struct page **pages, \r
214                                             uint32_t *pageTable, \r
215                                             uint32_t Memory, \r
216                                             uint32_t pageCount)\r
217 {\r
218     int32_t result;\r
219     uint32_t i;\r
220     \r
221     down_read(&current->mm->mmap_sem);\r
222     result = get_user_pages(current,\r
223             current->mm,\r
224             Memory << PAGE_SHIFT,\r
225             pageCount,\r
226             1,\r
227             0,\r
228             pages,\r
229             NULL\r
230             );\r
231     up_read(&current->mm->mmap_sem);\r
232     \r
233     if(result <= 0 || result < pageCount) \r
234     {\r
235         return -EINVAL;                \r
236     }\r
237 \r
238     for (i = 0; i < pageCount; i++)\r
239     {\r
240         /* Flush the data cache. */\r
241 #ifdef ANDROID\r
242         dma_sync_single_for_device(\r
243                     gcvNULL,\r
244                     page_to_phys(pages[i]),\r
245                     PAGE_SIZE,\r
246                     DMA_TO_DEVICE);\r
247 #else\r
248         flush_dcache_page(pages[i]);\r
249 #endif\r
250     }\r
251 \r
252     /* Fill the page table. */\r
253     for(i=0; i<pageCount; i++) {\r
254 \r
255         /* Get the physical address from page struct. */\r
256         pageTable[i * (PAGE_SIZE/4096)] = page_to_phys(pages[i]);\r
257     }    \r
258 \r
259     return 0;\r
260 }\r
261 \r
262 static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req)\r
263 {    \r
264     int SrcMemSize, DstMemSize, CMDMemSize;\r
265     uint32_t SrcStart, DstStart, CMDStart;   \r
266     uint32_t i;\r
267     uint32_t AllSize;\r
268     uint32_t *MMU_Base, *MMU_p;\r
269     int ret;\r
270 \r
271     struct page **pages = NULL;\r
272 \r
273     /* cal src buf mmu info */                     \r
274     SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr,\r
275                                     req->src.format, req->src.vir_w, req->src.vir_h,\r
276                                     &SrcStart);\r
277     if(SrcMemSize == 0) {\r
278         return -EINVAL;                \r
279     }\r
280 \r
281     /* cal dst buf mmu info */    \r
282     DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
283                                     req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
284                                     &DstStart);\r
285     if(DstMemSize == 0) {\r
286         return -EINVAL; \r
287     }\r
288 \r
289     /* cal cmd buf mmu info */\r
290     CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);\r
291     if(CMDMemSize == 0) {\r
292         return -EINVAL; \r
293     }\r
294 \r
295     AllSize = SrcMemSize + DstMemSize + CMDMemSize;\r
296                \r
297     pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
298     if(pages == NULL) {\r
299         pr_err("RGA MMU malloc pages mem failed");\r
300         return -EINVAL;                \r
301     }\r
302     \r
303     MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL);\r
304     if(pages == NULL) {\r
305         pr_err("RGA MMU malloc MMU_Base point failed");\r
306         return -EINVAL;                \r
307     }\r
308 \r
309     for(i=0; i<CMDMemSize; i++) {\r
310         MMU_Base[i] = (uint32_t)virt_to_phys((uint32_t *)((CMDStart + i)<< PAGE_SHIFT));\r
311     }\r
312 \r
313     if(req->src.yrgb_addr < KERNEL_SPACE_VALID)\r
314     {\r
315         ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
316         if (ret < 0) {\r
317             pr_err("rga map src memory failed");\r
318             return -EINVAL;\r
319         }\r
320     }\r
321     else\r
322     {\r
323         MMU_p = MMU_Base + CMDMemSize;\r
324         \r
325         for(i=0; i<SrcMemSize; i++)\r
326         {\r
327             MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));\r
328         }\r
329     }\r
330     \r
331     if(req->dst.yrgb_addr < KERNEL_SPACE_VALID)\r
332     {\r
333         ret = rga_MapUserMemory(&pages[CMDMemSize + SrcMemSize], &MMU_Base[CMDMemSize + SrcMemSize], DstStart, DstMemSize);\r
334         if (ret < 0) {\r
335             pr_err("rga map dst memory failed");\r
336             return -EINVAL;\r
337         }\r
338     }\r
339     else\r
340     {\r
341         MMU_p = MMU_Base + CMDMemSize + SrcMemSize;\r
342         \r
343         for(i=0; i<DstMemSize; i++)\r
344         {\r
345             MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT));\r
346         }       \r
347     }\r
348 \r
349     /* zsq \r
350      * change the buf address in req struct\r
351      * for the reason of lie to MMU \r
352      */\r
353     req->mmu_info.base_addr = virt_to_phys(MMU_Base);\r
354     \r
355     req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
356     req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
357     req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
358 \r
359     req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((CMDMemSize + SrcMemSize) << PAGE_SHIFT);\r
360     \r
361     /*record the malloc buf for the cmd end to release*/\r
362     reg->MMU_base = MMU_Base;\r
363 \r
364     if (pages != NULL) {\r
365         /* Free the page table */\r
366         kfree(pages);\r
367     }        \r
368 \r
369     return 0;\r
370 }\r
371 \r
372 static int rga_mmu_info_color_palette_mode(struct rga_reg *reg, struct rga_req *req)\r
373 {\r
374     int SrcMemSize, DstMemSize, CMDMemSize;\r
375     uint32_t SrcStart, DstStart, CMDStart;\r
376     struct page **pages = NULL;\r
377     uint32_t i;\r
378     uint32_t AllSize;\r
379     uint32_t *MMU_Base;\r
380     int ret;\r
381     uint32_t stride;\r
382 \r
383     uint8_t shift;\r
384     uint16_t sw, byte_num;\r
385     \r
386     shift = 3 - (req->palette_mode & 3);\r
387     sw = req->src.vir_w;\r
388     byte_num = sw >> shift;\r
389     stride = (byte_num + 3) & (~3);\r
390                          \r
391     SrcMemSize = rga_mem_size_cal(req->src.yrgb_addr, stride, &SrcStart);\r
392     if(SrcMemSize == 0) {\r
393         return -EINVAL;                \r
394     }\r
395 \r
396     DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
397                                     req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
398                                     &DstStart);\r
399     if(DstMemSize == 0) {\r
400         return -EINVAL; \r
401     }\r
402 \r
403     CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);\r
404     if(CMDMemSize == 0) {\r
405         return -EINVAL; \r
406     }\r
407 \r
408     AllSize = SrcMemSize + DstMemSize + CMDMemSize;\r
409                \r
410     pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
411     if(pages == NULL) {\r
412         pr_err("RGA MMU malloc pages mem failed");\r
413         return -EINVAL;                \r
414     }\r
415     \r
416     MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL);\r
417     if(pages == NULL) {\r
418         pr_err("RGA MMU malloc MMU_Base point failed");\r
419         return -EINVAL;                \r
420     }\r
421 \r
422     for(i=0; i<CMDMemSize; i++) {\r
423         MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i)<<PAGE_SHIFT));\r
424     }\r
425                 \r
426     ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
427     if (ret < 0) {\r
428         pr_err("rga map src memory failed");\r
429         return -EINVAL;\r
430     }\r
431 \r
432     ret = rga_MapUserMemory(&pages[CMDMemSize + SrcMemSize], &MMU_Base[CMDMemSize + SrcMemSize], DstStart, DstMemSize);\r
433     if (ret < 0) {\r
434         pr_err("rga map dst memory failed");\r
435         return -EINVAL;\r
436     }\r
437 \r
438     /* zsq \r
439      * change the buf address in req struct\r
440      * for the reason of lie to MMU \r
441      */\r
442     req->mmu_info.base_addr = virt_to_phys(MMU_Base);    \r
443     req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
444     req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((CMDMemSize + SrcMemSize) << PAGE_SHIFT);\r
445 \r
446     \r
447     /*record the malloc buf for the cmd end to release*/\r
448     reg->MMU_base = MMU_Base;\r
449 \r
450     if (pages != NULL) {\r
451         /* Free the page table */\r
452         kfree(pages);\r
453     }        \r
454 \r
455     return 0;\r
456 }\r
457 \r
458 static int rga_mmu_info_color_fill_mode(struct rga_reg *reg, struct rga_req *req)\r
459 {\r
460     int DstMemSize, CMDMemSize;\r
461     uint32_t DstStart, CMDStart;\r
462     struct page **pages = NULL;\r
463     uint32_t i;\r
464     uint32_t AllSize;\r
465     uint32_t *MMU_Base;\r
466     int ret;\r
467                          \r
468     DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
469                                     req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
470                                     &DstStart);\r
471     if(DstMemSize == 0) {\r
472         return -EINVAL; \r
473     }\r
474 \r
475     CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);\r
476     if(CMDMemSize == 0) {\r
477         return -EINVAL; \r
478     }\r
479 \r
480     AllSize = DstMemSize + CMDMemSize;\r
481                \r
482     pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
483     if(pages == NULL) {\r
484         pr_err("RGA MMU malloc pages mem failed");\r
485         return -EINVAL;                \r
486     }\r
487     \r
488     MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL);\r
489     if(pages == NULL) {\r
490         pr_err("RGA MMU malloc MMU_Base point failed");\r
491         return -EINVAL;                \r
492     }\r
493 \r
494     for(i=0; i<CMDMemSize; i++) {\r
495         MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart+i)<<PAGE_SHIFT));\r
496     }\r
497                 \r
498     ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], DstStart, DstMemSize);\r
499     if (ret < 0) {\r
500         pr_err("rga map dst memory failed");\r
501         return -EINVAL;\r
502     }\r
503 \r
504     /* zsq \r
505      * change the buf address in req struct\r
506      * for the reason of lie to MMU \r
507      */\r
508     req->mmu_info.base_addr = virt_to_phys(MMU_Base);    \r
509     req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((CMDMemSize) << PAGE_SHIFT);\r
510    \r
511     \r
512     /*record the malloc buf for the cmd end to release*/\r
513     reg->MMU_base = MMU_Base;\r
514 \r
515     if (pages != NULL) {\r
516         /* Free the page table */\r
517         kfree(pages);\r
518     }       \r
519 \r
520     return 0;\r
521 }\r
522 \r
523 \r
524 static int rga_mmu_info_line_point_drawing_mode(struct rga_reg *reg, struct rga_req *req)\r
525 {\r
526     int DstMemSize, CMDMemSize;\r
527     uint32_t DstStart, CMDStart;\r
528     struct page **pages = NULL;\r
529     uint32_t i;\r
530     uint32_t AllSize;\r
531     uint32_t *MMU_Base;\r
532     int ret;\r
533 \r
534     /* cal dst buf mmu info */                     \r
535     DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
536                                     req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
537                                     &DstStart);\r
538     if(DstMemSize == 0) {\r
539         return -EINVAL; \r
540     }\r
541 \r
542     CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);\r
543     if(CMDMemSize == 0) {\r
544         return -EINVAL; \r
545     }\r
546 \r
547     AllSize = DstMemSize + CMDMemSize;\r
548                \r
549     pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
550     if(pages == NULL) {\r
551         pr_err("RGA MMU malloc pages mem failed");\r
552         return -EINVAL;                \r
553     }\r
554     \r
555     MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL);\r
556     if(pages == NULL) {\r
557         pr_err("RGA MMU malloc MMU_Base point failed");\r
558         return -EINVAL;                \r
559     }\r
560 \r
561     for(i=0; i<CMDMemSize; i++) {\r
562         MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart+i)<<PAGE_SHIFT));\r
563     }\r
564                 \r
565     ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], DstStart, DstMemSize);\r
566     if (ret < 0) {\r
567         pr_err("rga map dst memory failed");\r
568         return -EINVAL;\r
569     }\r
570 \r
571     /* zsq \r
572      * change the buf address in req struct\r
573      * for the reason of lie to MMU \r
574      */\r
575     req->mmu_info.base_addr = virt_to_phys(MMU_Base);    \r
576     req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((CMDMemSize) << PAGE_SHIFT);\r
577    \r
578     \r
579     /*record the malloc buf for the cmd end to release*/\r
580     reg->MMU_base = MMU_Base;\r
581 \r
582     if (pages != NULL) {\r
583         /* Free the page table */\r
584         kfree(pages);\r
585     } \r
586 \r
587     return 0;\r
588 }\r
589 \r
590 static int rga_mmu_info_blur_sharp_filter_mode(struct rga_reg *reg, struct rga_req *req)\r
591 {\r
592     int SrcMemSize, DstMemSize, CMDMemSize;\r
593     uint32_t SrcStart, DstStart, CMDStart;\r
594     struct page **pages = NULL;\r
595     uint32_t i;\r
596     uint32_t AllSize;\r
597     uint32_t *MMU_Base;\r
598     int ret;\r
599 \r
600     /* cal src buf mmu info */                     \r
601     SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr,\r
602                                     req->src.format, req->src.vir_w, req->src.vir_h,\r
603                                     &SrcStart);\r
604     if(SrcMemSize == 0) {\r
605         return -EINVAL;                \r
606     }\r
607 \r
608     /* cal dst buf mmu info */    \r
609     DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
610                                     req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
611                                     &DstStart);\r
612     if(DstMemSize == 0) {\r
613         return -EINVAL; \r
614     }\r
615 \r
616     /* cal cmd buf mmu info */\r
617     CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);\r
618     if(CMDMemSize == 0) {\r
619         return -EINVAL; \r
620     }\r
621 \r
622     AllSize = SrcMemSize + DstMemSize + CMDMemSize;\r
623                \r
624     pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
625     if(pages == NULL) {\r
626         pr_err("RGA MMU malloc pages mem failed");\r
627         return -EINVAL;                \r
628     }\r
629     \r
630     MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL);\r
631     if(pages == NULL) {\r
632         pr_err("RGA MMU malloc MMU_Base point failed");\r
633         return -EINVAL;                \r
634     }\r
635 \r
636     for(i=0; i<CMDMemSize; i++) {\r
637         MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i)<< PAGE_SHIFT));\r
638     }\r
639                 \r
640     ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
641     if (ret < 0) {\r
642         pr_err("rga map src memory failed");\r
643         return -EINVAL;\r
644     }\r
645 \r
646     ret = rga_MapUserMemory(&pages[CMDMemSize + SrcMemSize], &MMU_Base[CMDMemSize + SrcMemSize], DstStart, DstMemSize);\r
647     if (ret < 0) {\r
648         pr_err("rga map dst memory failed");\r
649         return -EINVAL;\r
650     }\r
651 \r
652     /* zsq \r
653      * change the buf address in req struct\r
654      * for the reason of lie to MMU \r
655      */\r
656     req->mmu_info.base_addr = virt_to_phys(MMU_Base);\r
657     \r
658     req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
659     req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
660     req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
661 \r
662     req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((CMDMemSize + SrcMemSize) << PAGE_SHIFT);\r
663     \r
664     /*record the malloc buf for the cmd end to release*/\r
665     reg->MMU_base = MMU_Base;\r
666 \r
667     if (pages != NULL) {\r
668         /* Free the page table */\r
669         kfree(pages);\r
670     }  \r
671 \r
672     return 0;\r
673 }\r
674 \r
675 \r
676 \r
677 static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req)\r
678 {\r
679     int SrcMemSize, DstMemSize, CMDMemSize;\r
680     uint32_t SrcStart, DstStart, CMDStart;\r
681     struct page **pages = NULL;\r
682     uint32_t i;\r
683     uint32_t AllSize;\r
684     uint32_t *MMU_Base, *MMU_p;\r
685     int ret;\r
686 \r
687     /* cal src buf mmu info */                     \r
688     SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr,\r
689                                     req->src.format, req->src.vir_w, req->src.vir_h,\r
690                                     &SrcStart);\r
691     if(SrcMemSize == 0) {\r
692         return -EINVAL;                \r
693     }\r
694 \r
695     /* cal dst buf mmu info */    \r
696     DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr,\r
697                                     req->dst.format, req->dst.vir_w, req->dst.vir_h,\r
698                                     &DstStart);\r
699     if(DstMemSize == 0) {\r
700         return -EINVAL; \r
701     }\r
702 \r
703     /* cal cmd buf mmu info */\r
704     CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);\r
705     if(CMDMemSize == 0) {\r
706         return -EINVAL; \r
707     }\r
708 \r
709     AllSize = SrcMemSize + DstMemSize + CMDMemSize;\r
710                \r
711     pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
712     if(pages == NULL) {\r
713         pr_err("RGA MMU malloc pages mem failed");\r
714         return -EINVAL;                \r
715     }\r
716 \r
717     /* \r
718      * Allocate MMU Index mem\r
719      * This mem release in run_to_done fun \r
720      */\r
721     MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL);\r
722     if(pages == NULL) {\r
723         pr_err("RGA MMU malloc MMU_Base point failed");\r
724         return -EINVAL;                \r
725     }\r
726 \r
727     for(i=0; i<CMDMemSize; i++) {\r
728         MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i) << PAGE_SHIFT));\r
729     }\r
730 \r
731 \r
732     /* map src pages */\r
733     ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
734     if (ret < 0) {\r
735         pr_err("rga map src memory failed");\r
736         return -EINVAL;\r
737     }\r
738 \r
739     \r
740     if(req->dst.yrgb_addr >= 0xc0000000) \r
741     {   \r
742         /* kernel space */\r
743         MMU_p = MMU_Base + CMDMemSize + SrcMemSize;\r
744         for(i=0; i<DstMemSize; i++) \r
745         {\r
746             MMU_p[i] = virt_to_phys((uint32_t *)((DstStart + i)<< PAGE_SHIFT));        \r
747         }\r
748     }\r
749     else \r
750     {\r
751         /* user space */\r
752         ret = rga_MapUserMemory(&pages[CMDMemSize + SrcMemSize], &MMU_Base[CMDMemSize + SrcMemSize], DstStart, DstMemSize);\r
753         if (ret < 0) \r
754         {\r
755             pr_err("rga map dst memory failed");\r
756             return -EINVAL;\r
757         }        \r
758     }\r
759 \r
760     /* zsq \r
761      * change the buf address in req struct\r
762      * for the reason of lie to MMU \r
763      */\r
764     req->mmu_info.base_addr = virt_to_phys(MMU_Base);\r
765     \r
766     req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
767     req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
768     req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);\r
769 \r
770     req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((CMDMemSize + SrcMemSize) << PAGE_SHIFT);\r
771     \r
772     /*record the malloc buf for the cmd end to release*/\r
773     reg->MMU_base = MMU_Base;\r
774 \r
775     if (pages != NULL) {\r
776         /* Free the page table */\r
777         kfree(pages);\r
778     }  \r
779 \r
780     return 0;\r
781 }\r
782 \r
783 \r
784 static int rga_mmu_info_update_palette_table_mode(struct rga_reg *reg, struct rga_req *req)\r
785 {\r
786     int SrcMemSize, DstMemSize, CMDMemSize;\r
787     uint32_t SrcStart, CMDStart;\r
788     struct page **pages = NULL;\r
789     uint32_t i;\r
790     uint32_t AllSize;\r
791     uint32_t *MMU_Base;\r
792     int ret;\r
793 \r
794     /* cal src buf mmu info */                     \r
795     SrcMemSize = rga_mem_size_cal(req->src.yrgb_addr, req->src.vir_w * req->src.vir_h, &SrcStart);\r
796     if(SrcMemSize == 0) {\r
797         return -EINVAL;                \r
798     }\r
799 \r
800     /* cal cmd buf mmu info */\r
801     CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);\r
802     if(CMDMemSize == 0) {\r
803         return -EINVAL; \r
804     }\r
805 \r
806     AllSize = SrcMemSize + DstMemSize + CMDMemSize;\r
807                \r
808     pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
809     if(pages == NULL) {\r
810         pr_err("RGA MMU malloc pages mem failed");\r
811         return -EINVAL;                \r
812     }\r
813     \r
814     MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL);\r
815     if(pages == NULL) {\r
816         pr_err("RGA MMU malloc MMU_Base point failed");\r
817         return -EINVAL;                \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     ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
825     if (ret < 0) {\r
826         pr_err("rga map src memory failed");\r
827         return -EINVAL;\r
828     }\r
829 \r
830     /* zsq \r
831      * change the buf address in req struct\r
832      * for the reason of lie to MMU \r
833      */\r
834     req->mmu_info.base_addr = virt_to_phys(MMU_Base);\r
835     \r
836     req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);    \r
837     \r
838     /*record the malloc buf for the cmd end to release*/\r
839     reg->MMU_base = MMU_Base;\r
840 \r
841     if (pages != NULL) {\r
842         /* Free the page table */\r
843         kfree(pages);\r
844     }  \r
845 \r
846     return 0;\r
847 }\r
848 \r
849 static int rga_mmu_info_update_patten_buff_mode(struct rga_reg *reg, struct rga_req *req)\r
850 {\r
851     int SrcMemSize, DstMemSize, CMDMemSize;\r
852     uint32_t SrcStart, CMDStart;\r
853     struct page **pages = NULL;\r
854     uint32_t i;\r
855     uint32_t AllSize;\r
856     uint32_t *MMU_Base;\r
857     int ret;\r
858 \r
859     /* cal src buf mmu info */                     \r
860     SrcMemSize = rga_mem_size_cal(req->pat.yrgb_addr, req->pat.vir_w * req->pat.vir_h * 4, &SrcStart);\r
861     if(SrcMemSize == 0) {\r
862         return -EINVAL;                \r
863     }\r
864 \r
865     /* cal cmd buf mmu info */\r
866     CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);\r
867     if(CMDMemSize == 0) {\r
868         return -EINVAL; \r
869     }\r
870 \r
871     AllSize = SrcMemSize + DstMemSize + CMDMemSize;\r
872                \r
873     pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL);\r
874     if(pages == NULL) {\r
875         pr_err("RGA MMU malloc pages mem failed");\r
876         return -EINVAL;                \r
877     }\r
878     \r
879     MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL);\r
880     if(pages == NULL) {\r
881         pr_err("RGA MMU malloc MMU_Base point failed");\r
882         return -EINVAL;                \r
883     }\r
884 \r
885     for(i=0; i<CMDMemSize; i++) {\r
886         MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i) << PAGE_SHIFT));\r
887     }\r
888                 \r
889     ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);\r
890     if (ret < 0) {\r
891         pr_err("rga map src memory failed");\r
892         return -EINVAL;\r
893     }\r
894 \r
895     /* zsq \r
896      * change the buf address in req struct\r
897      * for the reason of lie to MMU \r
898      */\r
899     req->mmu_info.base_addr = virt_to_phys(MMU_Base);\r
900     \r
901     req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);    \r
902     \r
903     /*record the malloc buf for the cmd end to release*/\r
904     reg->MMU_base = MMU_Base;\r
905 \r
906     if (pages != NULL) {\r
907         /* Free the page table */\r
908         kfree(pages);\r
909     }\r
910 \r
911     return 0;\r
912 }\r
913 \r
914 int rga_set_mmu_info(struct rga_reg *reg, struct rga_req *req)\r
915 {    \r
916     int ret;\r
917                \r
918     switch (req->render_mode) {\r
919         case bitblt_mode :            \r
920             ret = rga_mmu_info_BitBlt_mode(reg, req);\r
921             break;\r
922         case color_palette_mode :\r
923             ret = rga_mmu_info_color_palette_mode(reg, req);\r
924             break;\r
925         case color_fill_mode :\r
926             ret = rga_mmu_info_color_fill_mode(reg, req);\r
927             break;\r
928         case line_point_drawing_mode :\r
929             ret = rga_mmu_info_line_point_drawing_mode(reg, req);\r
930             break;\r
931         case blur_sharp_filter_mode :\r
932             ret = rga_mmu_info_blur_sharp_filter_mode(reg, req);\r
933             break;\r
934         case pre_scaling_mode :\r
935             ret = rga_mmu_info_pre_scale_mode(reg, req);\r
936             break;\r
937         case update_palette_table_mode :\r
938             ret = rga_mmu_info_update_palette_table_mode(reg, req);\r
939             break;\r
940         case update_patten_buff_mode :\r
941             ret = rga_mmu_info_update_patten_buff_mode(reg, req);\r
942             break;\r
943         default :\r
944             ret = -1;\r
945             break;\r
946     }\r
947 \r
948     return ret;\r
949 }\r
950 \r