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
23 extern rga_service_info rga_service;
\r
24 extern struct rga_mmu_buf_t rga_mmu_buf;
\r
26 #define KERNEL_SPACE_VALID 0xc0000000
\r
28 static int rga_mmu_buf_get(struct rga_mmu_buf_t *t, uint32_t size)
\r
30 mutex_lock(&rga_service.lock);
\r
32 mutex_unlock(&rga_service.lock);
\r
37 static int rga_mmu_buf_get_try(struct rga_mmu_buf_t *t, uint32_t size)
\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
45 if((t->front + size) > t->back)
\r
48 if(t->front + size > t->size) {
\r
49 if (size > (t->back - t->size)) {
\r
55 mutex_unlock(&rga_service.lock);
\r
60 static int rga_mem_size_cal(uint32_t Mem, uint32_t MemSize, uint32_t *StartAddr)
\r
62 uint32_t start, end;
\r
65 end = (Mem + (MemSize + PAGE_SIZE - 1)) >> PAGE_SHIFT;
\r
66 start = Mem >> PAGE_SHIFT;
\r
67 pageCount = end - start;
\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
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
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
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
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
102 case RK_FORMAT_BGRA_8888 :
\r
104 start = yrgb_addr >> PAGE_SHIFT;
\r
105 pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT;
\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
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
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
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
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
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
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
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
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
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
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
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
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
221 case RK_FORMAT_BPP1 :
\r
223 case RK_FORMAT_BPP2 :
\r
225 case RK_FORMAT_BPP4 :
\r
227 case RK_FORMAT_BPP8 :
\r
236 *StartAddr = start;
\r
240 static int rga_MapUserMemory(struct page **pages,
\r
241 uint32_t *pageTable,
\r
243 uint32_t pageCount)
\r
256 down_read(¤t->mm->mmap_sem);
\r
257 result = get_user_pages(current,
\r
259 Memory << PAGE_SHIFT,
\r
266 up_read(¤t->mm->mmap_sem);
\r
269 if(result <= 0 || result < pageCount)
\r
273 for(i=0; i<pageCount; i++)
\r
275 temp = armv7_va_to_pa((Memory + i) << PAGE_SHIFT);
\r
276 if (temp == 0xffffffff)
\r
278 printk("rga find mmu phy ddr error\n ");
\r
279 status = RGA_OUT_OF_RESOURCES;
\r
283 pageTable[i] = temp;
\r
289 if(result <= 0 || result < pageCount)
\r
291 struct vm_area_struct *vma;
\r
294 down_read(¤t->mm->mmap_sem);
\r
295 for (i = 0; i < result; i++)
\r
296 put_page(pages[i]);
\r
297 up_read(¤t->mm->mmap_sem);
\r
300 for(i=0; i<pageCount; i++)
\r
302 vma = find_vma(current->mm, (Memory + i) << PAGE_SHIFT);
\r
304 if (vma)//&& (vma->vm_flags & VM_PFNMAP) )
\r
314 pgd = pgd_offset(current->mm, (Memory + i) << PAGE_SHIFT);
\r
316 if(pgd_val(*pgd) == 0)
\r
318 //printk("rga pgd value is zero \n");
\r
322 pud = pud_offset(pgd, (Memory + i) << PAGE_SHIFT);
\r
325 pmd_t * pmd = pmd_offset(pud, (Memory + i) << PAGE_SHIFT);
\r
328 pte = pte_offset_map_lock(current->mm, pmd, (Memory + i) << PAGE_SHIFT, &ptl);
\r
331 pte_unmap_unlock(pte, ptl);
\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
351 pageTable[i] = Address;
\r
355 status = RGA_OUT_OF_RESOURCES;
\r
364 /* Fill the page table. */
\r
365 for(i=0; i<pageCount; i++)
\r
367 /* Get the physical address from page struct. */
\r
368 pageTable[i] = page_to_phys(pages[i]);
\r
371 down_read(¤t->mm->mmap_sem);
\r
372 for (i = 0; i < result; i++)
\r
373 put_page(pages[i]);
\r
374 up_read(¤t->mm->mmap_sem);
\r
383 static int rga_MapION(struct sg_table *sg,
\r
391 uint32_t mapped_size = 0;
\r
393 struct scatterlist *sgl = sg->sgl;
\r
394 uint32_t sg_num = 0;
\r
398 offset = offset >> PAGE_SHIFT;
\r
401 len += (sg_dma_len(sgl) >> PAGE_SHIFT);
\r
402 if (len == offset) {
\r
412 while((sgl = sg_next(sgl)) && (mapped_size < pageCount) && (sg_num < sg->nents));
\r
417 len += (sg_dma_len(sgl) >> PAGE_SHIFT);
\r
418 sgl = sg_next(sgl);
\r
424 len = sg_dma_len(sgl) >> PAGE_SHIFT;
\r
425 Address = sg_phys(sgl);
\r
428 for(i=offset; i<len; i++) {
\r
429 Memory[i - offset] = Address + (i << PAGE_SHIFT);
\r
431 mapped_size += (len - offset);
\r
433 sgl = sg_next(sgl);
\r
435 len = sg_dma_len(sgl) >> PAGE_SHIFT;
\r
436 Address = sg_phys(sgl);
\r
438 for(i=0; i<len; i++) {
\r
439 Memory[mapped_size + i] = Address + (i << PAGE_SHIFT);
\r
442 mapped_size += len;
\r
445 while((sgl = sg_next(sgl)) && (mapped_size < pageCount) && (sg_num < sg->nents));
\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
454 mapped_size += len;
\r
457 while((sgl = sg_next(sgl)) && (mapped_size < pageCount) && (sg_num < sg->nents));
\r
463 static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req)
\r
465 int SrcMemSize, DstMemSize;
\r
466 uint32_t SrcStart, DstStart;
\r
469 uint32_t *MMU_Base, *MMU_p, *MMU_Base_phys;
\r
472 uint32_t uv_size, v_size;
\r
474 struct page **pages = NULL;
\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
486 if(SrcMemSize == 0) {
\r
490 /* cal dst buf mmu info */
\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
495 if(DstMemSize == 0)
\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
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
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
514 pages = rga_mmu_buf.pages;
\r
516 if((req->mmu_info.mmu_flag >> 8) & 1) {
\r
518 ret = rga_MapION(req->sg_src, &MMU_Base[0], SrcMemSize, req->line_draw_info.flag);
\r
521 ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize);
\r
523 pr_err("rga map src memory failed\n");
\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
537 for(i=0; i<SrcMemSize; i++)
\r
538 MMU_p[i] = (uint32_t)((SrcStart + i) << PAGE_SHIFT);
\r
542 if ((req->mmu_info.mmu_flag >> 10) & 1) {
\r
544 ret = rga_MapION(req->sg_dst, &MMU_Base[SrcMemSize], DstMemSize, req->line_draw_info.line_width);
\r
547 ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize);
\r
549 pr_err("rga map dst memory failed\n");
\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
561 MMU_Base[AllSize] = MMU_Base[AllSize-1];
\r
564 * change the buf address in req struct
\r
567 req->mmu_info.base_addr = (uint32_t)MMU_Base_phys >> 2;
\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
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
576 uv_size = (req->dst.uv_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT;
\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
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
585 rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16);
\r
586 reg->MMU_len = AllSize + 16;
\r
597 static int rga_mmu_info_color_palette_mode(struct rga_reg *reg, struct rga_req *req)
\r
599 int SrcMemSize, DstMemSize, CMDMemSize;
\r
600 uint32_t SrcStart, DstStart, CMDStart;
\r
601 struct page **pages = NULL;
\r
604 uint32_t *MMU_Base = NULL, *MMU_Base_phys = NULL;
\r
610 uint16_t sw, byte_num;
\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
618 SrcMemSize = rga_mem_size_cal(req->src.yrgb_addr, stride, &SrcStart);
\r
619 if(SrcMemSize == 0) {
\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
626 if(DstMemSize == 0) {
\r
630 CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart);
\r
631 if(CMDMemSize == 0) {
\r
635 SrcMemSize = (SrcMemSize + 15) & (~15);
\r
636 DstMemSize = (DstMemSize + 15) & (~15);
\r
637 CMDMemSize = (CMDMemSize + 15) & (~15);
\r
639 AllSize = SrcMemSize + DstMemSize + CMDMemSize;
\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
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
652 pages = rga_mmu_buf.pages;
\r
655 for(i=0; i<CMDMemSize; i++) {
\r
656 MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i)<<PAGE_SHIFT));
\r
660 if (req->src.yrgb_addr < KERNEL_SPACE_VALID) {
\r
661 ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);
\r
663 pr_err("rga map src memory failed\n");
\r
669 MMU_p = MMU_Base + CMDMemSize;
\r
671 for(i=0; i<SrcMemSize; i++)
\r
673 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));
\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
681 pr_err("rga map dst memory failed\n");
\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
694 * change the buf address in req struct
\r
695 * for the reason of lie to MMU
\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
701 /*record the malloc buf for the cmd end to release*/
\r
702 reg->MMU_base = MMU_Base;
\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
708 rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16);
\r
709 reg->MMU_len = AllSize + 16;
\r
719 static int rga_mmu_info_color_fill_mode(struct rga_reg *reg, struct rga_req *req)
\r
723 struct page **pages = NULL;
\r
726 uint32_t *MMU_Base, *MMU_p, *MMU_Base_phys;
\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
737 if(DstMemSize == 0) {
\r
741 AllSize = (DstMemSize + 15) & (~15);
\r
743 pages = rga_mmu_buf.pages;
\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
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
756 if (req->dst.yrgb_addr < KERNEL_SPACE_VALID) {
\r
758 ret = rga_MapION(req->sg_dst, &MMU_Base[0], DstMemSize, req->line_draw_info.line_width);
\r
761 ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], DstStart, DstMemSize);
\r
763 pr_err("rga map dst memory failed\n");
\r
771 for(i=0; i<DstMemSize; i++)
\r
772 MMU_p[i] = (uint32_t)((DstStart + i) << PAGE_SHIFT);
\r
775 MMU_Base[AllSize] = MMU_Base[AllSize - 1];
\r
778 * change the buf address in req struct
\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
784 /*record the malloc buf for the cmd end to release*/
\r
785 reg->MMU_base = MMU_Base;
\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
791 rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16);
\r
792 reg->MMU_len = AllSize + 16;
\r
802 static int rga_mmu_info_line_point_drawing_mode(struct rga_reg *reg, struct rga_req *req)
\r
806 struct page **pages = NULL;
\r
809 uint32_t *MMU_Base, *MMU_p;
\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
820 if(DstMemSize == 0) {
\r
824 AllSize = DstMemSize;
\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
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
840 if (req->dst.yrgb_addr < KERNEL_SPACE_VALID)
\r
842 ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], DstStart, DstMemSize);
\r
844 pr_err("rga map dst memory failed\n");
\r
853 for(i=0; i<DstMemSize; i++)
\r
855 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT));
\r
860 * change the buf address in req struct
\r
861 * for the reason of lie to MMU
\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
867 /*record the malloc buf for the cmd end to release*/
\r
868 reg->MMU_base = MMU_Base;
\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
874 /* Free the page table */
\r
875 if (pages != NULL) {
\r
887 if (MMU_Base != NULL)
\r
893 static int rga_mmu_info_blur_sharp_filter_mode(struct rga_reg *reg, struct rga_req *req)
\r
895 int SrcMemSize, DstMemSize;
\r
896 uint32_t SrcStart, DstStart;
\r
897 struct page **pages = NULL;
\r
900 uint32_t *MMU_Base, *MMU_p;
\r
902 uint32_t uv_size, v_size;
\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
912 if(SrcMemSize == 0) {
\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
920 if(DstMemSize == 0) {
\r
924 AllSize = SrcMemSize + DstMemSize;
\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
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
940 if (req->src.yrgb_addr < KERNEL_SPACE_VALID)
\r
942 ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize);
\r
945 pr_err("rga map src memory failed\n");
\r
954 for(i=0; i<SrcMemSize; i++)
\r
956 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));
\r
961 if (req->dst.yrgb_addr < KERNEL_SPACE_VALID)
\r
963 ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize);
\r
966 pr_err("rga map dst memory failed\n");
\r
973 MMU_p = MMU_Base + SrcMemSize;
\r
975 for(i=0; i<DstMemSize; i++)
\r
977 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT));
\r
981 MMU_Base[AllSize] = MMU_Base[AllSize - 1];
\r
984 * change the buf address in req struct
\r
985 * for the reason of lie to MMU
\r
987 req->mmu_info.base_addr = (virt_to_phys(MMU_Base) >> 2);
\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
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
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
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
1004 /*record the malloc buf for the cmd end to release*/
\r
1005 reg->MMU_base = MMU_Base;
\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
1011 /* Free the page table */
\r
1012 if (pages != NULL) {
\r
1020 if (pages != NULL)
\r
1023 if (MMU_Base != NULL)
\r
1031 static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req)
\r
1033 int SrcMemSize, DstMemSize;
\r
1034 uint32_t SrcStart, DstStart;
\r
1035 struct page **pages = NULL;
\r
1038 uint32_t *MMU_Base, *MMU_p, *MMU_Base_phys;
\r
1041 uint32_t uv_size, v_size;
\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
1050 if(SrcMemSize == 0) {
\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
1058 if(DstMemSize == 0) {
\r
1062 SrcMemSize = (SrcMemSize + 15) & (~15);
\r
1063 DstMemSize = (DstMemSize + 15) & (~15);
\r
1065 AllSize = SrcMemSize + DstMemSize;
\r
1067 pages = rga_mmu_buf.pages;
\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
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
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
1086 ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize);
\r
1088 pr_err("rga map src memory failed\n");
\r
1097 for(i=0; i<SrcMemSize; i++)
\r
1098 MMU_p[i] = (uint32_t)((SrcStart + i) << PAGE_SHIFT);
\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
1106 ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize);
\r
1108 pr_err("rga map dst memory failed\n");
\r
1116 /* kernel space */
\r
1117 MMU_p = MMU_Base + SrcMemSize;
\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
1124 for(i=0; i<DstMemSize; i++)
\r
1125 MMU_p[i] = (uint32_t)((DstStart + i) << PAGE_SHIFT);
\r
1129 MMU_Base[AllSize] = MMU_Base[AllSize];
\r
1132 * change the buf address in req struct
\r
1133 * for the reason of lie to MMU
\r
1136 req->mmu_info.base_addr = ((uint32_t)(MMU_Base_phys)>>2);
\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
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
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
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
1152 /*record the malloc buf for the cmd end to release*/
\r
1153 reg->MMU_base = MMU_Base;
\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
1159 rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16);
\r
1160 reg->MMU_len = AllSize + 16;
\r
1170 static int rga_mmu_info_update_palette_table_mode(struct rga_reg *reg, struct rga_req *req)
\r
1172 int SrcMemSize, CMDMemSize;
\r
1173 uint32_t SrcStart, CMDStart;
\r
1174 struct page **pages = NULL;
\r
1177 uint32_t *MMU_Base, *MMU_p;
\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
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
1196 AllSize = SrcMemSize + CMDMemSize;
\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
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
1212 for(i=0; i<CMDMemSize; i++) {
\r
1213 MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i) << PAGE_SHIFT));
\r
1216 if (req->src.yrgb_addr < KERNEL_SPACE_VALID)
\r
1218 ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);
\r
1220 pr_err("rga map src memory failed\n");
\r
1226 MMU_p = MMU_Base + CMDMemSize;
\r
1228 for(i=0; i<SrcMemSize; i++)
\r
1230 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));
\r
1235 * change the buf address in req struct
\r
1236 * for the reason of lie to MMU
\r
1238 req->mmu_info.base_addr = (virt_to_phys(MMU_Base) >> 2);
\r
1240 req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);
\r
1242 /*record the malloc buf for the cmd end to release*/
\r
1243 reg->MMU_base = MMU_Base;
\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
1249 if (pages != NULL) {
\r
1250 /* Free the page table */
\r
1258 if (pages != NULL)
\r
1261 if (MMU_Base != NULL)
\r
1267 static int rga_mmu_info_update_patten_buff_mode(struct rga_reg *reg, struct rga_req *req)
\r
1269 int SrcMemSize, CMDMemSize;
\r
1270 uint32_t SrcStart, CMDStart;
\r
1271 struct page **pages = NULL;
\r
1274 uint32_t *MMU_Base, *MMU_p;
\r
1277 MMU_Base = MMU_p = 0;
\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
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
1294 AllSize = SrcMemSize + CMDMemSize;
\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
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
1310 for(i=0; i<CMDMemSize; i++) {
\r
1311 MMU_Base[i] = virt_to_phys((uint32_t *)((CMDStart + i) << PAGE_SHIFT));
\r
1314 if (req->src.yrgb_addr < KERNEL_SPACE_VALID)
\r
1316 ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize);
\r
1318 pr_err("rga map src memory failed\n");
\r
1325 MMU_p = MMU_Base + CMDMemSize;
\r
1327 for(i=0; i<SrcMemSize; i++)
\r
1329 MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));
\r
1334 * change the buf address in req struct
\r
1335 * for the reason of lie to MMU
\r
1337 req->mmu_info.base_addr = (virt_to_phys(MMU_Base) >> 2);
\r
1339 req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT);
\r
1341 /*record the malloc buf for the cmd end to release*/
\r
1342 reg->MMU_base = MMU_Base;
\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
1348 if (pages != NULL) {
\r
1349 /* Free the page table */
\r
1358 if (pages != NULL)
\r
1361 if (MMU_Base != NULL)
\r
1367 int rga_set_mmu_info(struct rga_reg *reg, struct rga_req *req)
\r
1371 switch (req->render_mode) {
\r
1372 case bitblt_mode :
\r
1373 ret = rga_mmu_info_BitBlt_mode(reg, req);
\r
1375 case color_palette_mode :
\r
1376 ret = rga_mmu_info_color_palette_mode(reg, req);
\r
1378 case color_fill_mode :
\r
1379 ret = rga_mmu_info_color_fill_mode(reg, req);
\r
1381 case line_point_drawing_mode :
\r
1382 ret = rga_mmu_info_line_point_drawing_mode(reg, req);
\r
1384 case blur_sharp_filter_mode :
\r
1385 ret = rga_mmu_info_blur_sharp_filter_mode(reg, req);
\r
1387 case pre_scaling_mode :
\r
1388 ret = rga_mmu_info_pre_scale_mode(reg, req);
\r
1390 case update_palette_table_mode :
\r
1391 ret = rga_mmu_info_update_palette_table_mode(reg, req);
\r
1393 case update_patten_buff_mode :
\r
1394 ret = rga_mmu_info_update_patten_buff_mode(reg, req);
\r