mirror of
https://github.com/torvalds/linux.git
synced 2026-06-08 14:42:37 +02:00
fix rga copy read bug
This commit is contained in:
parent
f5dcca1cf4
commit
afe98d59c3
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -243,9 +243,9 @@ static int rga_MapUserMemory(struct page **pages,
|
|||
|
||||
for(i=0; i<pageCount; i++)
|
||||
{
|
||||
t_mem = Memory + i;
|
||||
t_mem = (Memory + i) << PAGE_SHIFT;
|
||||
|
||||
vma = find_vma(current->mm, (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; i<SrcMemSize; i++)
|
||||
{
|
||||
MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((SrcStart + i) << PAGE_SHIFT));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (req->dst.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; i<DstMemSize; i++)
|
||||
{
|
||||
MMU_p[i] = (uint32_t)virt_to_phys((uint32_t *)((DstStart + i) << PAGE_SHIFT));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* zsq
|
||||
|
|
@ -511,13 +508,13 @@ static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req)
|
|||
|
||||
/*record the malloc buf for the cmd end to release*/
|
||||
reg->MMU_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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user