From: Zikim,Wei Date: Wed, 19 Oct 2016 08:32:50 +0000 (+0800) Subject: vidro/rockchip: Fix rga2 driver X-Git-Tag: firefly_0821_release~1280 X-Git-Url: http://plrg.eecs.uci.edu/git/?p=firefly-linux-kernel-4.4.55.git;a=commitdiff_plain;h=f5b4aa62066ba2c69063eec213b934406848ef0f vidro/rockchip: Fix rga2 driver 1.If rga get the mmu error, we must unlock the lock or it will lead the next frame timeout. 2.calculate the rga mmu buf back length size in the rga time out handler or it will lead the next frame get mmu lentch wrong. Change-Id: If85751bd292774a1d0ef9693b7f8ad92a4727c07 Signed-off-by: Zikim,Wei --- diff --git a/drivers/video/rockchip/rga2/rga2_drv.c b/drivers/video/rockchip/rga2/rga2_drv.c index 34f0c6085fbc..0e9e427538e6 100644 --- a/drivers/video/rockchip/rga2/rga2_drv.c +++ b/drivers/video/rockchip/rga2/rga2_drv.c @@ -538,21 +538,19 @@ static void rga2_try_set_reg(void) } } -/* Caller must hold rga_service.lock */ static void rga2_del_running_list(void) { + struct rga2_mmu_buf_t *tbuf = &rga2_mmu_buf; struct rga2_reg *reg; - while(!list_empty(&rga2_service.running)) - { - reg = list_entry(rga2_service.running.next, struct rga2_reg, status_link); - - if(reg->MMU_len != 0) - { - if (rga2_mmu_buf.back + reg->MMU_len > 2*rga2_mmu_buf.size) - rga2_mmu_buf.back = reg->MMU_len + rga2_mmu_buf.size; + while (!list_empty(&rga2_service.running)) { + reg = list_entry(rga2_service.running.next, struct rga2_reg, + status_link); + if (reg->MMU_len && tbuf) { + if (tbuf->back + reg->MMU_len > 2 * tbuf->size) + tbuf->back = reg->MMU_len + tbuf->size; else - rga2_mmu_buf.back += reg->MMU_len; + tbuf->back += reg->MMU_len; } atomic_sub(1, ®->session->task_running); atomic_sub(1, &rga2_service.total_running); @@ -567,33 +565,31 @@ static void rga2_del_running_list(void) } } -/* Caller must hold rga_service.lock */ static void rga2_del_running_list_timeout(void) { - struct rga2_reg *reg; - - while(!list_empty(&rga2_service.running)) - { - reg = list_entry(rga2_service.running.next, struct rga2_reg, status_link); - - if(reg->MMU_base != NULL) - { - kfree(reg->MMU_base); - } - - atomic_sub(1, ®->session->task_running); - atomic_sub(1, &rga2_service.total_running); - - rga2_soft_reset(); - - if(list_empty(®->session->waiting)) - { - atomic_set(®->session->done, 1); - wake_up(®->session->wait); - } + struct rga2_mmu_buf_t *tbuf = &rga2_mmu_buf; + struct rga2_reg *reg; - rga2_reg_deinit(reg); - } + while (!list_empty(&rga2_service.running)) { + reg = list_entry(rga2_service.running.next, struct rga2_reg, + status_link); + kfree(reg->MMU_base); + if (reg->MMU_len && tbuf) { + if (tbuf->back + reg->MMU_len > 2 * tbuf->size) + tbuf->back = reg->MMU_len + tbuf->size; + else + tbuf->back += reg->MMU_len; + } + atomic_sub(1, ®->session->task_running); + atomic_sub(1, &rga2_service.total_running); + rga2_soft_reset(); + if (list_empty(®->session->waiting)) { + atomic_set(®->session->done, 1); + wake_up(®->session->wait); + } + rga2_reg_deinit(reg); + } + return; } static int rga2_convert_dma_buf(struct rga2_req *req) diff --git a/drivers/video/rockchip/rga2/rga2_mmu_info.c b/drivers/video/rockchip/rga2/rga2_mmu_info.c index f1e04599ab15..377819210341 100644 --- a/drivers/video/rockchip/rga2/rga2_mmu_info.c +++ b/drivers/video/rockchip/rga2/rga2_mmu_info.c @@ -73,34 +73,41 @@ static int rga2_mmu_buf_get(struct rga2_mmu_buf_t *t, uint32_t size) return 0; } -static int rga2_mmu_buf_get_try(struct rga2_mmu_buf_t *t, uint32_t size) -{ - mutex_lock(&rga2_service.lock); - if((t->back - t->front) > t->size) { - if(t->front + size > t->back - t->size) { - pr_info("front %d, back %d dsize %d size %d", t->front, t->back, t->size, size); - return -1; - } - } - else { - if((t->front + size) > t->back) { - pr_info("front %d, back %d dsize %d size %d", t->front, t->back, t->size, size); - return -1; - } - - if(t->front + size > t->size) { - if (size > (t->back - t->size)) { - pr_info("front %d, back %d dsize %d size %d", t->front, t->back, t->size, size); - return -1; - } - t->front = 0; - } - } - mutex_unlock(&rga2_service.lock); - - return 0; -} - +static int rga2_mmu_buf_get_try(struct rga2_mmu_buf_t *t, uint32_t size) +{ + int ret = 0; + + mutex_lock(&rga2_service.lock); + if ((t->back - t->front) > t->size) { + if (t->front + size > t->back - t->size) { + pr_info("front %d, back %d dsize %d size %d", + t->front, t->back, t->size, size); + ret = -ENOMEM; + goto out; + } + } else { + if ((t->front + size) > t->back) { + pr_info("front %d, back %d dsize %d size %d", + t->front, t->back, t->size, size); + ret = -ENOMEM; + goto out; + } + + if (t->front + size > t->size) { + if (size > (t->back - t->size)) { + pr_info("front %d, back %d dsize %d size %d", + t->front, t->back, t->size, size); + ret = -ENOMEM; + goto out; + } + t->front = 0; + } + } +out: + mutex_unlock(&rga2_service.lock); + return ret; +} + static int rga2_mem_size_cal(unsigned long Mem, uint32_t MemSize, unsigned long *StartAddr) { unsigned long start, end;