From afe98d59c36fe0cf9e0815853c5decdbbb0927f5 Mon Sep 17 00:00:00 2001 From: zsq Date: Sun, 1 Apr 2012 02:03:03 -0800 Subject: [PATCH] fix rga copy read bug --- drivers/video/rockchip/rga/rga.h | 1 - drivers/video/rockchip/rga/rga_drv.c | 105 ++++++---------------- drivers/video/rockchip/rga/rga_mmu_info.c | 53 ++++++----- 3 files changed, 53 insertions(+), 106 deletions(-) diff --git a/drivers/video/rockchip/rga/rga.h b/drivers/video/rockchip/rga/rga.h index 19807abce3bc..e102c7014d63 100755 --- a/drivers/video/rockchip/rga/rga.h +++ b/drivers/video/rockchip/rga/rga.h @@ -374,7 +374,6 @@ typedef struct rga_service_info { atomic_t cmd_num; atomic_t src_format_swt; int last_prc_src_format; - bool enabled; } rga_service_info; diff --git a/drivers/video/rockchip/rga/rga_drv.c b/drivers/video/rockchip/rga/rga_drv.c index cdf4c3480867..2d5995722783 100755 --- a/drivers/video/rockchip/rga/rga_drv.c +++ b/drivers/video/rockchip/rga/rga_drv.c @@ -224,7 +224,7 @@ static void rga_power_off(void) { int total_running; - //printk("rga_power_off\n"); + printk("rga_power_off\n"); if(!drvdata->enable) return; @@ -378,7 +378,7 @@ static struct rga_reg * rga_reg_init(rga_session *session, struct rga_req *req) reg->session = session; INIT_LIST_HEAD(®->session_link); INIT_LIST_HEAD(®->status_link); - + if (req->mmu_info.mmu_en) { ret = rga_set_mmu_info(reg, req); @@ -392,9 +392,18 @@ static struct rga_reg * rga_reg_init(rga_session *session, struct rga_req *req) return NULL; } } - + + #if RGA_TEST_TIME + rga_start = ktime_get(); + #endif RGA_gen_reg_info(req, (uint8_t *)reg->cmd_reg); + #if RGA_TEST_TIME + rga_end = ktime_get(); + rga_end = ktime_sub(rga_end, rga_start); + printk("one cmd end time %d\n", (int)ktime_to_us(rga_end)); + #endif + spin_lock_irqsave(&rga_service.lock, flag); list_add_tail(®->status_link, &rga_service.waiting); list_add_tail(®->session_link, &session->waiting); @@ -533,50 +542,9 @@ static void rga_try_set_reg(uint32_t num) do { struct rga_reg *reg = list_entry(rga_service.waiting.next, struct rga_reg, status_link); - - //if(((reg->cmd_reg[0] & 0xf0) >= 3) && ((reg->cmd_reg[0] & 0xf0) <= 7) && rga_service.last_prc_src_format == 0) - offset = atomic_read(&rga_service.cmd_num); if((rga_read(RGA_STATUS) & 0x1)) - { - #if 0 - #if RGA_TEST - /* RGA is busy */ - printk(" rga try set reg while rga is working \n"); - #endif - - if((atomic_read(&rga_service.cmd_num) <= 0xf) && (atomic_read(&rga_service.int_disable) == 0)) - { - rga_copy_reg(reg, offset); - rga_reg_from_wait_to_run(reg); - - dmac_flush_range(&rga_service.cmd_buff[offset*28], &rga_service.cmd_buff[(offset + 1)*28]); - outer_flush_range(virt_to_phys(&rga_service.cmd_buff[offset*28]), - virt_to_phys(&rga_service.cmd_buff[(offset + 1)*28])); - - rga_write(0x1<<10, RGA_INT); - - #if RGA_TEST - { - uint32_t i; - printk("CMD_REG num is %.8x\n", offset); - for(i=0; i<7; i++) - { - printk("%.8x ", rga_service.cmd_buff[i*4 + 0 + 28*atomic_read(&rga_service.cmd_num)]); - printk("%.8x ", rga_service.cmd_buff[i*4 + 1 + 28*atomic_read(&rga_service.cmd_num)]); - printk("%.8x ", rga_service.cmd_buff[i*4 + 2 + 28*atomic_read(&rga_service.cmd_num)]); - printk("%.8x\n",rga_service.cmd_buff[i*4 + 3 + 28*atomic_read(&rga_service.cmd_num)]); - } - } - #endif - - atomic_set(®->session->done, 0); - rga_write((0x1<<3)|(0x1<<1), RGA_CMD_CTRL); - - if(atomic_read(®->int_enable)) - atomic_set(&rga_service.int_disable, 1); - } - #endif + { break; } else @@ -614,16 +582,11 @@ static void rga_try_set_reg(uint32_t num) /* All CMD finish int */ rga_write(0x1<<10, RGA_INT); - - #if RGA_TEST_TIME - rga_start = ktime_get(); - #endif - + /* Start proc */ atomic_set(®->session->done, 0); rga_write(0x1, RGA_CMD_CTRL); - #if RGA_TEST { uint32_t i; @@ -642,9 +605,9 @@ static void rga_try_set_reg(uint32_t num) } +#if RGA_TEST static void print_info(struct rga_req *req) -{ - #if RGA_TEST +{ printk("src.yrgb_addr = %.8x, src.uv_addr = %.8x, src.v_addr = %.8x\n", req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr); printk("src : act_w = %d, act_h = %d, vir_w = %d, vir_h = %d\n", @@ -658,9 +621,9 @@ static void print_info(struct rga_req *req) req->dst.act_w, req->dst.act_h, req->dst.vir_w, req->dst.vir_h); printk("clip.xmin = %d, clip.xmax = %d. clip.ymin = %d, clip.ymax = %d\n", - req->clip.xmin, req->clip.xmax, req->clip.ymin, req->clip.ymax); - #endif + req->clip.xmin, req->clip.xmax, req->clip.ymin, req->clip.ymax); } +#endif static int rga_blit_async(rga_session *session, struct rga_req *req) @@ -678,16 +641,12 @@ static int rga_blit_async(rga_session *session, struct rga_req *req) printk("*** rga_blit_async proc ***\n"); print_info(req); #endif - + saw = req->src.act_w; sah = req->src.act_h; daw = req->dst.act_w; dah = req->dst.act_h; - /* special case proc */ - if(req->src.act_w == 360 && req->src.act_h == 64 && req->rotate_mode == 0) - req->rotate_mode = 1; - do { if((req->render_mode == bitblt_mode) && (((saw>>1) >= daw) || ((sah>>1) >= dah))) @@ -734,8 +693,8 @@ static int rga_blit_async(rga_session *session, struct rga_req *req) //rga_power_on(); atomic_set(®->int_enable, 1); rga_try_set_reg(num); - - return 0; + + return 0; } while(0); @@ -766,12 +725,7 @@ static int rga_blit_sync(rga_session *session, struct rga_req *req) printk("*** rga_blit_sync proc ***\n"); print_info(req); #endif - - /* special case proc*/ - if(req->src.act_w == 360 && req->src.act_h == 64 && req->rotate_mode == 0) - req->rotate_mode = 1; - - + do { if((req->render_mode == bitblt_mode) && (((saw>>1) >= daw) || ((sah>>1) >= dah))) @@ -897,7 +851,7 @@ static long rga_ioctl(struct file *file, uint32_t cmd, unsigned long arg) if(req != NULL) { kfree(req); } - + return ret; } @@ -959,8 +913,6 @@ static irqreturn_t rga_irq(int irq, void *dev_id) uint32_t num = 0; struct list_head *next; int int_enable = 0; - - //DBG("rga_irq %d \n", irq); #if RGA_TEST printk("rga_irq is valid\n"); @@ -1009,15 +961,16 @@ static irqreturn_t rga_irq(int irq, void *dev_id) next = &rga_service.waiting; /* add cmd to cmd buf */ + /* while((!list_empty(next)) && ((int_enable) == 0) && (num <= 0xf)) { num += 1; reg = list_entry(next->next, struct rga_reg, status_link); int_enable = atomic_read(®->int_enable); next = next->next; - } - - rga_try_set_reg(num); + } + */ + rga_try_set_reg(1); return IRQ_HANDLED; } @@ -1046,8 +999,6 @@ static void rga_shutdown(struct platform_device *pdev) pr_cont("done\n"); } - - struct file_operations rga_fops = { .owner = THIS_MODULE, .open = rga_open, @@ -1078,7 +1029,7 @@ static int __devinit rga_drv_probe(struct platform_device *pdev) atomic_set(&rga_service.total_running, 0); atomic_set(&rga_service.src_format_swt, 0); rga_service.last_prc_src_format = 1; /* default is yuv first*/ - rga_service.enabled = false; + data->enable = 0; if(NULL == data) { diff --git a/drivers/video/rockchip/rga/rga_mmu_info.c b/drivers/video/rockchip/rga/rga_mmu_info.c index aa4c373d2860..e598fb041e21 100755 --- a/drivers/video/rockchip/rga/rga_mmu_info.c +++ b/drivers/video/rockchip/rga/rga_mmu_info.c @@ -243,9 +243,9 @@ static int rga_MapUserMemory(struct page **pages, for(i=0; imm, (t_mem) << PAGE_SHIFT); + vma = find_vma(current->mm, t_mem); if (vma && (vma->vm_flags & VM_PFNMAP) ) { @@ -255,14 +255,14 @@ static int rga_MapUserMemory(struct page **pages, spinlock_t * ptl; unsigned long pfn; - pgd_t * pgd = pgd_offset(current->mm, ((t_mem)<< PAGE_SHIFT)); - pud_t * pud = pud_offset(pgd, ((t_mem) << PAGE_SHIFT)); + pgd_t * pgd = pgd_offset(current->mm, t_mem); + pud_t * pud = pud_offset(pgd, t_mem); if (pud) { - pmd_t * pmd = pmd_offset(pud, ((t_mem) << PAGE_SHIFT)); + pmd_t * pmd = pmd_offset(pud, t_mem); if (pmd) { - pte = pte_offset_map_lock(current->mm, pmd, ((t_mem)<< PAGE_SHIFT), &ptl); + pte = pte_offset_map_lock(current->mm, pmd, t_mem, &ptl); if (!pte) { break; @@ -279,7 +279,7 @@ static int rga_MapUserMemory(struct page **pages, } pfn = pte_pfn(*pte); - Address = ((pfn << PAGE_SHIFT) | (((unsigned long)((t_mem) << PAGE_SHIFT)) & ~PAGE_MASK)); + Address = ((pfn << PAGE_SHIFT) | (((unsigned long)t_mem) & ~PAGE_MASK)); pte_unmap_unlock(pte, ptl); #if 0 @@ -381,17 +381,12 @@ static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req) struct page **pages = NULL; MMU_Base = NULL; - - if(req->src.act_w == 360 && req->src.act_h == 64) - mmu_flag = 1; - else - mmu_flag = 0; - + do { /* cal src buf mmu info */ SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr, - req->src.format, req->src.vir_w, req->src.vir_h, + req->src.format, req->src.vir_w, (req->src.act_h + req->src.y_offset), &SrcStart); if(SrcMemSize == 0) { return -EINVAL; @@ -400,12 +395,14 @@ static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req) /* cal dst buf mmu info */ DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, - req->dst.format, req->dst.vir_w, req->dst.vir_h, + req->dst.format, req->dst.vir_w, (req->dst.act_h + req->dst.y_offset), &DstStart); if(DstMemSize == 0) { return -EINVAL; } + //DstMemSize += 1; + /* cal cmd buf mmu info */ CMDMemSize = rga_mem_size_cal((uint32_t)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); if(CMDMemSize == 0) { @@ -414,15 +411,15 @@ static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req) /* Cal out the needed mem size */ AllSize = SrcMemSize + DstMemSize + CMDMemSize; - - pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL); + + pages = (struct page **)kmalloc((AllSize + 1)* sizeof(struct page *), GFP_KERNEL); if(pages == NULL) { pr_err("RGA MMU malloc pages mem failed\n"); status = RGA_MALLOC_ERROR; break; } - MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL); + MMU_Base = (uint32_t *)kmalloc((AllSize + 1)* sizeof(uint32_t), GFP_KERNEL); if(MMU_Base == NULL) { pr_err("RGA MMU malloc MMU_Base point failed\n"); status = RGA_MALLOC_ERROR; @@ -457,16 +454,16 @@ static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req) } } else - { + { for(i=0; idst.yrgb_addr < KERNEL_SPACE_VALID) - { + { #if 0 ktime_t start, end; start = ktime_get(); @@ -491,7 +488,7 @@ static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req) for(i=0; iMMU_base = MMU_Base; - + /* flush data to DDR */ dmac_flush_range(MMU_Base, (MMU_Base + AllSize)); outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize)); - - status = 0; + status = 0; + /* Free the page table */ if (pages != NULL) { kfree(pages); @@ -1068,7 +1065,7 @@ static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req) AllSize = SrcMemSize + DstMemSize + CMDMemSize; - pages = (struct page **)kmalloc(AllSize * sizeof(struct page *), GFP_KERNEL); + pages = (struct page **)kmalloc((AllSize)* sizeof(struct page *), GFP_KERNEL); if(pages == NULL) { pr_err("RGA MMU malloc pages mem failed\n"); @@ -1080,7 +1077,7 @@ static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req) * Allocate MMU Index mem * This mem release in run_to_done fun */ - MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL); + MMU_Base = (uint32_t *)kmalloc((AllSize + 1) * sizeof(uint32_t), GFP_KERNEL); if(pages == NULL) { pr_err("RGA MMU malloc MMU_Base point failed\n"); status = RGA_MALLOC_ERROR; @@ -1228,7 +1225,7 @@ static int rga_mmu_info_update_palette_table_mode(struct rga_reg *reg, struct rg break; } - MMU_Base = (uint32_t *)kmalloc(AllSize * sizeof(uint32_t), GFP_KERNEL); + MMU_Base = (uint32_t *)kmalloc((AllSize + 1)* sizeof(uint32_t), GFP_KERNEL); if(pages == NULL) { pr_err("RGA MMU malloc MMU_Base point failed\n"); status = RGA_MALLOC_ERROR; -- 2.34.1