From c24aeae6be720c203d5bc797c05f39473c000159 Mon Sep 17 00:00:00 2001 From: Min Ho Kim Date: Wed, 2 May 2018 15:31:38 +0900 Subject: [PATCH] fbdev: dpu20: AFBC debug feature code changed - due to common layer, general concept for AFBC channel has been applied Change-Id: I6a98aa396e02d398b760af7e179ad9fcb89fed13 Signed-off-by: Min Ho Kim Signed-off-by: ChiHun Won --- drivers/video/fbdev/exynos/dpu20/decon.h | 9 +- drivers/video/fbdev/exynos/dpu20/decon_core.c | 140 +++++++----------- drivers/video/fbdev/exynos/dpu20/decon_dsi.c | 4 +- drivers/video/fbdev/exynos/dpu20/dpp.h | 1 + drivers/video/fbdev/exynos/dpu20/dpp_drv.c | 18 +++ drivers/video/fbdev/exynos/dpu20/helper.c | 41 ++--- 6 files changed, 97 insertions(+), 116 deletions(-) diff --git a/drivers/video/fbdev/exynos/dpu20/decon.h b/drivers/video/fbdev/exynos/dpu20/decon.h index b83f35b22e51..b80b4559cb58 100644 --- a/drivers/video/fbdev/exynos/dpu20/decon.h +++ b/drivers/video/fbdev/exynos/dpu20/decon.h @@ -728,9 +728,10 @@ struct decon_user_window { }; struct dpu_afbc_info { - dma_addr_t dma_addr[2]; - struct dma_buf *dma_buf[2]; - bool is_afbc[2]; + dma_addr_t dma_addr[MAX_DECON_WIN]; + void *dma_v_addr[MAX_DECON_WIN]; + struct dma_buf *dma_buf[MAX_DECON_WIN]; + bool is_afbc[MAX_DECON_WIN]; }; struct decon_debug { @@ -760,7 +761,7 @@ struct decon_debug { #else struct dma_buf *dmabuf[MAX_DECON_WIN][MAX_PLANE_CNT]; #endif - int prev_vgf_win_id[2]; + int prev_vgf_win_id[MAX_DECON_WIN]; }; struct decon_update_regs { diff --git a/drivers/video/fbdev/exynos/dpu20/decon_core.c b/drivers/video/fbdev/exynos/dpu20/decon_core.c index 5f63d2023f8b..8c4517b4c89c 100644 --- a/drivers/video/fbdev/exynos/dpu20/decon_core.c +++ b/drivers/video/fbdev/exynos/dpu20/decon_core.c @@ -1593,93 +1593,72 @@ static void decon_save_vgf_connected_win_id(struct decon_device *decon, struct decon_reg_data *regs) { int i; + struct v4l2_subdev *sd; + int afbc_enabled; - decon->d.prev_vgf_win_id[0] = -1; - decon->d.prev_vgf_win_id[1] = -1; + for (i = 0; i < decon->dt.max_win; ++i) + decon->d.prev_vgf_win_id[i] = -1; for (i = 0; i < decon->dt.max_win; ++i) { - if (regs->dpp_config[i].idma_type == IDMA_VGF0) - decon->d.prev_vgf_win_id[0] = i; - if (regs->dpp_config[i].idma_type == IDMA_VGF1) - decon->d.prev_vgf_win_id[1] = i; + if (regs->dpp_config[i].state == DECON_WIN_STATE_BUFFER) { + sd = decon->dpp_sd[DPU_DMA2CH(regs->dpp_config[i].idma_type)]; + afbc_enabled = 0; + v4l2_subdev_call(sd, core, ioctl, + DPP_AFBC_ATTR_ENABLED, &afbc_enabled); + if (regs->dpp_config[i].compression && afbc_enabled) + decon->d.prev_vgf_win_id[DPU_DMA2CH(regs->dpp_config[i].idma_type)] = i; + else + decon->d.prev_vgf_win_id[DPU_DMA2CH(regs->dpp_config[i].idma_type)] = -1; + + decon_dbg("%s:%d win(%d), dma(%d), afbc(%d), save(%d)\n", __func__, __LINE__, + i, regs->dpp_config[i].idma_type, afbc_enabled, + decon->d.prev_vgf_win_id[DPU_DMA2CH(regs->dpp_config[i].idma_type)]); + } } } static void decon_dump_afbc_handle(struct decon_device *decon, struct decon_dma_buf_data (*dma_bufs)[MAX_PLANE_CNT]) { - int size; + int i; int win_id = 0; + int size; void *v_addr; decon_info("%s +\n", __func__); - if (test_bit(DPU_DMA2CH(IDMA_VGF0), &decon->prev_used_dpp)) { - win_id = decon->d.prev_vgf_win_id[0]; - if (win_id < 0) { - decon_err("%s: win_id(%d) is invalid\n", __func__, win_id); - return; - } -#if defined(CONFIG_SUPPORT_LEGACY_ION) - decon->d.handle[win_id][0] = dma_bufs[win_id][0].ion_handle; - decon_info("VGF0(WIN%d): handle=0x%p\n", - win_id, decon->d.handle[win_id][0]); - - v_addr = ion_map_kernel(decon->ion_client, - dma_bufs[win_id][0].ion_handle); - if (IS_ERR_OR_NULL(v_addr)) { - decon_err("%s: failed to map afbc buffer\n", __func__); - return; - } -#else - decon->d.dmabuf[win_id][0] = dma_bufs[win_id][0].dma_buf; - decon_info("VGF0(WIN%d): dmabuf=0x%p\n", - win_id, decon->d.dmabuf[win_id][0]); - v_addr = dma_buf_vmap(dma_bufs[win_id][0].dma_buf); - if (IS_ERR_OR_NULL(v_addr)) { - decon_err("%s: failed to map afbc buffer\n", __func__); - return; - } -#endif - size = dma_bufs[win_id][0].dma_buf->size; - - decon_info("DV(0x%p), KV(0x%p), size(%d)\n", - (void *)dma_bufs[win_id][0].dma_addr, - v_addr, size); - } + for (i = 0; i < decon->dt.max_win; i++) { + if (decon->d.prev_vgf_win_id[i] != -1 + && test_bit(i, &decon->prev_used_dpp)) { + win_id = decon->d.prev_vgf_win_id[i]; - if (test_bit(DPU_DMA2CH(IDMA_VGF1), &decon->prev_used_dpp)) { - win_id = decon->d.prev_vgf_win_id[1]; - if (win_id < 0) { - decon_err("%s: win_id(%d) is invalid\n", __func__, win_id); - return; - } #if defined(CONFIG_SUPPORT_LEGACY_ION) - decon->d.handle[win_id][0] = dma_bufs[win_id][0].ion_handle; - decon_info("VGF1(WIN%d): handle=0x%p\n", - win_id, decon->d.handle[win_id][0]); - - v_addr = ion_map_kernel(decon->ion_client, - dma_bufs[win_id][0].ion_handle); - if (IS_ERR_OR_NULL(v_addr)) { - decon_err("%s: failed to map afbc buffer\n", __func__); - return; - } + decon->d.handle[win_id][0] = dma_bufs[win_id][0].ion_handle; + decon_info("DMA%d(WIN%d): handle=0x%p\n", + i, win_id, decon->d.handle[win_id][0]); + + v_addr = ion_map_kernel(decon->ion_client, + dma_bufs[win_id][0].ion_handle); + if (IS_ERR_OR_NULL(v_addr)) { + decon_err("%s: failed to map afbc buffer\n", __func__); + return; + } #else - decon->d.dmabuf[win_id][0] = dma_bufs[win_id][0].dma_buf; - decon_info("VGF1(WIN%d): dmabuf=0x%p\n", - win_id, decon->d.dmabuf[win_id][0]); - v_addr = dma_buf_vmap(dma_bufs[win_id][0].dma_buf); - if (IS_ERR_OR_NULL(v_addr)) { - decon_err("%s: failed to map afbc buffer\n", __func__); - return; - } + decon->d.dmabuf[win_id][0] = dma_bufs[win_id][0].dma_buf; + decon_info("DMA%d(WIN%d): dmabuf=0x%p\n", + i, win_id, decon->d.dmabuf[win_id][0]); + v_addr = dma_buf_vmap(dma_bufs[win_id][0].dma_buf); + if (IS_ERR_OR_NULL(v_addr)) { + decon_err("%s: failed to map afbc buffer\n", __func__); + return; + } #endif - size = dma_bufs[win_id][0].dma_buf->size; + size = dma_bufs[win_id][0].dma_buf->size; - decon_info("DV(0x%p), KV(0x%p), size(%d)\n", - (void *)dma_bufs[win_id][0].dma_addr, - v_addr, size); + decon_info("DV(0x%p), KV(0x%p), size(%d)\n", + (void *)dma_bufs[win_id][0].dma_addr, + v_addr, size); + } } decon_info("%s -\n", __func__); @@ -2031,28 +2010,21 @@ static void decon_update_vgf_info(struct decon_device *decon, if (!regs->dpp_config[i].compression) continue; - if (test_bit(DPU_DMA2CH(IDMA_VGF0), &decon->cur_using_dpp)) { - afbc_info->is_afbc[0] = true; - - if (regs->dma_buf_data[i][0].dma_buf == NULL) - continue; - - afbc_info->dma_addr[0] = - regs->dma_buf_data[i][0].dma_addr; - afbc_info->dma_buf[0] = - regs->dma_buf_data[i][0].dma_buf; - } - - if (test_bit(DPU_DMA2CH(IDMA_VGF1), &decon->cur_using_dpp)) { - afbc_info->is_afbc[1] = true; + if (test_bit(i, &decon->cur_using_dpp)) { + afbc_info->is_afbc[i] = true; if (regs->dma_buf_data[i][0].dma_buf == NULL) continue; - afbc_info->dma_addr[1] = + afbc_info->dma_addr[i] = regs->dma_buf_data[i][0].dma_addr; - afbc_info->dma_buf[1] = + afbc_info->dma_buf[i] = regs->dma_buf_data[i][0].dma_buf; +#if defined(DPU_DUMP_BUFFER_IRQ) + afbc_info->dma_v_addr[i] = + dma_buf_vmap(afbc_info->dma_buf[i]); + dma_buf_vunmap(afbc_info->dma_buf[i], afbc_info->dma_v_addr[i]); +#endif } } diff --git a/drivers/video/fbdev/exynos/dpu20/decon_dsi.c b/drivers/video/fbdev/exynos/dpu20/decon_dsi.c index ad572985449e..3e42519dbcbb 100644 --- a/drivers/video/fbdev/exynos/dpu20/decon_dsi.c +++ b/drivers/video/fbdev/exynos/dpu20/decon_dsi.c @@ -72,10 +72,10 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_data) if (ext_irq & DPU_TIME_OUT_INT_PEND) { decon_err("%s: DECON%d timeout irq occurs\n", __func__, decon->id); -#if defined(CONFIG_EXYNOS_AFBC_DEBUG) +#if defined(DPU_DUMP_BUFFER_IRQ) dpu_dump_afbc_info(); - BUG(); #endif + BUG(); } irq_end: diff --git a/drivers/video/fbdev/exynos/dpu20/dpp.h b/drivers/video/fbdev/exynos/dpu20/dpp.h index 4aee57114669..2ef9425271e5 100644 --- a/drivers/video/fbdev/exynos/dpu20/dpp.h +++ b/drivers/video/fbdev/exynos/dpu20/dpp.h @@ -328,6 +328,7 @@ void dpp_dump(struct dpp_device *dpp); #define DPP_WB_WAIT_FOR_FRAMEDONE _IOR('P', 3, u32) #define DPP_WAIT_IDLE _IOR('P', 4, unsigned long) #define DPP_SET_RECOVERY_NUM _IOR('P', 5, unsigned long) +#define DPP_AFBC_ATTR_ENABLED _IOR('P', 6, unsigned long) #define DPP_GET_PORT_NUM _IOR('P', 7, unsigned long) #define DPP_GET_RESTRICTION _IOR('P', 8, unsigned long) diff --git a/drivers/video/fbdev/exynos/dpu20/dpp_drv.c b/drivers/video/fbdev/exynos/dpu20/dpp_drv.c index 70a792d4200f..bef7af8f481c 100644 --- a/drivers/video/fbdev/exynos/dpu20/dpp_drv.c +++ b/drivers/video/fbdev/exynos/dpu20/dpp_drv.c @@ -427,6 +427,18 @@ static int dpp_check_limitation(struct dpp_device *dpp, struct dpp_params_info * return 0; } +static int dpp_afbc_enabled(struct dpp_device *dpp, int *afbc_enabled) +{ + int ret = 0; + + if (test_bit(DPP_ATTR_AFBC, &dpp->attr)) + *afbc_enabled = 1; + else + *afbc_enabled = 0; + + return ret; +} + static int dpp_set_config(struct dpp_device *dpp) { struct dpp_params_info params; @@ -500,6 +512,7 @@ static long dpp_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg struct dpp_device *dpp = v4l2_get_subdevdata(sd); bool reset = (bool)arg; int ret = 0; + int *afbc_enabled; switch (cmd) { case DPP_WIN_CONFIG: @@ -523,6 +536,11 @@ static long dpp_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg ret = dpp_wb_wait_for_framedone(dpp); break; + case DPP_AFBC_ATTR_ENABLED: + afbc_enabled = (int *)arg; + ret = dpp_afbc_enabled(dpp, afbc_enabled); + break; + case DPP_GET_PORT_NUM: *(int *)arg = dpp->port; break; diff --git a/drivers/video/fbdev/exynos/dpu20/helper.c b/drivers/video/fbdev/exynos/dpu20/helper.c index a8c1bc26870a..5cab67fe9c37 100644 --- a/drivers/video/fbdev/exynos/dpu20/helper.c +++ b/drivers/video/fbdev/exynos/dpu20/helper.c @@ -574,7 +574,7 @@ void decon_set_protected_content(struct decon_device *decon, } #endif -#if defined(CONFIG_EXYNOS_AFBC_DEBUG) +#if defined(DPU_DUMP_BUFFER_IRQ) /* id : VGF0=0, VGF1=1 */ static void dpu_dump_data_to_console(void *v_addr, int buf_size, int id) { @@ -589,8 +589,8 @@ void dpu_dump_afbc_info(void) int i, j; struct decon_device *decon; struct dpu_afbc_info *afbc_info; - void *v_addr[2]; - int size[2]; + void *v_addr[MAX_DECON_WIN]; + int size[MAX_DECON_WIN]; for (i = 0; i < 3; i++) { decon = get_decon_drvdata(i); @@ -599,30 +599,28 @@ void dpu_dump_afbc_info(void) afbc_info = &decon->d.prev_afbc_info; decon_info("%s: previous AFBC channel information\n", __func__); - for (j = 0; j < 2; ++j) { /* VGF0(0), VGF1(1) */ + for (j = 0; j < MAX_DECON_WIN; ++j) { /* all the dpp that has afbc */ if (!afbc_info->is_afbc[j]) continue; v_addr[j] = dma_buf_vmap(afbc_info->dma_buf[j]); size[j] = afbc_info->dma_buf[j]->size; - decon_info("\t[%s] Base(0x%p), KV(0x%p), size(%d)\n", - j ? "VGF1" : "VGF0", - (void *)afbc_info->dma_addr[j], + decon_info("\t[DMA%d] Base(0x%p), KV(0x%p), size(%d)\n", + j, (void *)afbc_info->dma_addr[j], v_addr[j], size[j]); dma_buf_vunmap(afbc_info->dma_buf[j], v_addr[j]); } afbc_info = &decon->d.cur_afbc_info; decon_info("%s: current AFBC channel information\n", __func__); - for (j = 0; j < 2; ++j) { /* VGF0(0), VGF1(1) */ + for (j = 0; j < MAX_DECON_WIN; ++j) { /* all the dpp that has afbc */ if (!afbc_info->is_afbc[j]) continue; v_addr[j] = dma_buf_vmap(afbc_info->dma_buf[j]); size[j] = afbc_info->dma_buf[j]->size; - decon_info("\t[%s] Base(0x%p), KV(0x%p), size(%d)\n", - j ? "VGF1" : "VGF0", - (void *)afbc_info->dma_addr[j], + decon_info("\t[DMA%d] Base(0x%p), KV(0x%p), size(%d)\n", + j, (void *)afbc_info->dma_addr[j], v_addr[j], size[j]); dma_buf_vunmap(afbc_info->dma_buf[j], v_addr[j]); } @@ -634,22 +632,17 @@ static int dpu_dump_buffer_data(struct dpp_device *dpp) int i; int id_idx = 0; int dump_size = 128; - int decon_cnt; struct decon_device *decon; struct dpu_afbc_info *afbc_info; - void *v_addr; - - decon_cnt = get_decon_drvdata(0)->dt.decon_cnt; if (dpp->state == DPP_STATE_ON) { - for (i = 0; i < decon_cnt; i++) { + for (i = 0; i < MAX_DECON_CNT; i++) { decon = get_decon_drvdata(i); if (decon == NULL) continue; - if (DPU_CH2DMA(dpp->id) == IDMA_GF) - id_idx = 1; + id_idx = dpp->id; afbc_info = &decon->d.cur_afbc_info; if (!afbc_info->is_afbc[id_idx]) @@ -660,16 +653,12 @@ static int dpu_dump_buffer_data(struct dpp_device *dpp) else dump_size = afbc_info->dma_buf[id_idx]->size / 16; - v_addr = dma_buf_vmap(afbc_info->dma_buf[id_idx]); decon_info("Base(0x%p), KV(0x%p), size(%d)\n", (void *)afbc_info->dma_addr[id_idx], - v_addr, dump_size); - - if (IS_ERR_OR_NULL(v_addr)) - continue; + afbc_info->dma_v_addr[id_idx], dump_size); - dpu_dump_data_to_console(v_addr, dump_size, dpp->id); - dma_buf_vunmap(afbc_info->dma_buf[id_idx], v_addr); + dpu_dump_data_to_console(afbc_info->dma_v_addr[id_idx], + dump_size, dpp->id); } } @@ -699,7 +688,7 @@ int dpu_sysmmu_fault_handler(struct iommu_domain *domain, for (i = 0; i < decon->dt.dpp_cnt; i++) { if (test_bit(i, &decon->prev_used_dpp)) { dpp = get_dpp_drvdata(i); -#if defined(CONFIG_EXYNOS_AFBC_DEBUG) +#if defined(DPU_DUMP_BUFFER_IRQ) dpu_dump_buffer_data(dpp); #endif } -- 2.20.1