From 1a365f9ac8dc08340e8bb18da5e1a932e31a76df Mon Sep 17 00:00:00 2001 From: Dileep Kumar Reddi Date: Tue, 30 Sep 2014 10:47:43 +0530 Subject: [PATCH] msm: mdss: partial update support for MDP3 targets Enable partial update for MDP3. Use ROI provided by HAL and program the DMA pipe accordingly. Change-Id: I2dd2d59bf178383b6139a1432274efa516e21fcc Signed-off-by: Dileep Kumar Reddi --- drivers/video/fbdev/msm/mdp3_ctrl.c | 42 ++++++++++++++++++++++++++--- drivers/video/fbdev/msm/mdp3_dma.c | 40 ++++++++++++++++++++++++--- drivers/video/fbdev/msm/mdp3_dma.h | 11 +++++++- 3 files changed, 84 insertions(+), 9 deletions(-) diff --git a/drivers/video/fbdev/msm/mdp3_ctrl.c b/drivers/video/fbdev/msm/mdp3_ctrl.c index 092677b5596e..1be8bb94a615 100644 --- a/drivers/video/fbdev/msm/mdp3_ctrl.c +++ b/drivers/video/fbdev/msm/mdp3_ctrl.c @@ -994,6 +994,20 @@ static int mdp3_overlay_play(struct msm_fb_data_type *mfd, return rc; } +bool update_roi(struct mdp3_rect oldROI, struct mdp_rect newROI) +{ + return ((newROI.x != oldROI.x) || (newROI.y != oldROI.y) || + (newROI.w != oldROI.w) || (newROI.h != oldROI.h)); +} + +bool is_roi_valid(struct mdp3_dma_source source_config, struct mdp_rect roi) +{ + return ((roi.x >= source_config.x) && + ((roi.x + roi.w) <= source_config.width) && + (roi.y >= source_config.y) && + ((roi.y + roi.h) <= source_config.height)); +} + static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd, struct mdp_display_commit *cmt_data) { @@ -1016,6 +1030,15 @@ static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd, pr_debug("no buffer in queue yet\n"); return -EPERM; } + if (panel_info->partial_update_enabled && + is_roi_valid(mdp3_session->dma->source_config, cmt_data->l_roi) + && update_roi(mdp3_session->dma->roi, cmt_data->l_roi)) { + mdp3_session->dma->roi.x = cmt_data->l_roi.x; + mdp3_session->dma->roi.y = cmt_data->l_roi.y; + mdp3_session->dma->roi.w = cmt_data->l_roi.w; + mdp3_session->dma->roi.h = cmt_data->l_roi.h; + mdp3_session->dma->update_src_cfg = true; + } panel = mdp3_session->panel; if (mdp3_session->in_splash_screen) { @@ -1041,9 +1064,20 @@ static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd, if (data) { mdp3_ctrl_reset_countdown(mdp3_session, mfd); mdp3_ctrl_clk_enable(mfd, 1); - rc = mdp3_session->dma->update(mdp3_session->dma, - (void *)(int)data->addr, - mdp3_session->intf); + if (mdp3_session->dma->update_src_cfg && + panel_info->partial_update_enabled) { + panel->panel_info.roi.x = mdp3_session->dma->roi.x; + panel->panel_info.roi.y = mdp3_session->dma->roi.y; + panel->panel_info.roi.w = mdp3_session->dma->roi.w; + panel->panel_info.roi.h = mdp3_session->dma->roi.h; + rc = mdp3_session->dma->update(mdp3_session->dma, + (void *)(int)data->addr, + mdp3_session->intf, (void *)panel); + } else { + rc = mdp3_session->dma->update(mdp3_session->dma, + (void *)(int)data->addr, + mdp3_session->intf, NULL); + } /* This is for the previous frame */ if (rc < 0) { mdp3_ctrl_notify(mdp3_session, @@ -1137,7 +1171,7 @@ static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd) mdp3_ctrl_clk_enable(mfd, 1); rc = mdp3_session->dma->update(mdp3_session->dma, (void *)(int)(mfd->iova + offset), - mdp3_session->intf); + mdp3_session->intf, NULL); /* This is for the previous frame */ if (rc < 0) { mdp3_ctrl_notify(mdp3_session, diff --git a/drivers/video/fbdev/msm/mdp3_dma.c b/drivers/video/fbdev/msm/mdp3_dma.c index 102c5c8738ae..3a3a00a723cf 100644 --- a/drivers/video/fbdev/msm/mdp3_dma.c +++ b/drivers/video/fbdev/msm/mdp3_dma.c @@ -345,6 +345,10 @@ static int mdp3_dmap_config(struct mdp3_dma *dma, dma->source_config = *source_config; dma->output_config = *output_config; + dma->roi.w = dma->source_config.width; + dma->roi.h = dma->source_config.height; + dma->roi.x = dma->source_config.x; + dma->roi.y = dma->source_config.y; mdp3_irq_enable(MDP3_INTR_LCDC_UNDERFLOW); mdp3_dma_callback_setup(dma); return 0; @@ -361,7 +365,7 @@ static void mdp3_dmap_config_source(struct mdp3_dma *dma) dma_p_cfg_reg &= ~MDP3_DMA_PACK_PATTERN_MASK; dma_p_cfg_reg |= dma->output_config.pack_pattern << 8; - dma_p_size = source_config->width | (source_config->height << 16); + dma_p_size = dma->roi.w | (dma->roi.h << 16); MDP3_REG_WRITE(MDP3_REG_DMA_P_CONFIG, dma_p_cfg_reg); MDP3_REG_WRITE(MDP3_REG_DMA_P_SIZE, dma_p_size); @@ -603,11 +607,31 @@ static int mdp3_dmap_histo_config(struct mdp3_dma *dma, return 0; } +int dma_bpp(int format) +{ + int bpp; + switch (format) { + case MDP3_DMA_IBUF_FORMAT_RGB888: + bpp = 3; + break; + case MDP3_DMA_IBUF_FORMAT_RGB565: + bpp = 2; + break; + case MDP3_DMA_IBUF_FORMAT_XRGB8888: + bpp = 4; + break; + default: + bpp = 0; + } + return bpp; +} + static int mdp3_dmap_update(struct mdp3_dma *dma, void *buf, - struct mdp3_intf *intf) + struct mdp3_intf *intf, void *data) { unsigned long flag; int cb_type = MDP3_DMA_CALLBACK_TYPE_VSYNC; + struct mdss_panel_data *panel; int rc = 0; pr_debug("mdp3_dmap_update\n"); @@ -628,10 +652,18 @@ static int mdp3_dmap_update(struct mdp3_dma *dma, void *buf, MDP3_DMA_OUTPUT_SEL_DSI_VIDEO && intf->active) pr_err("configuring dma source while dma is active\n"); dma->dma_config_source(dma); + if (data) { + panel = (struct mdss_panel_data *)data; + if (panel->event_handler) + panel->event_handler(panel, + MDSS_EVENT_ENABLE_PARTIAL_ROI, NULL); + } dma->update_src_cfg = false; } spin_lock_irqsave(&dma->dma_lock, flag); - MDP3_REG_WRITE(MDP3_REG_DMA_P_IBUF_ADDR, (u32)buf); + MDP3_REG_WRITE(MDP3_REG_DMA_P_IBUF_ADDR, (u32)(buf + + dma->roi.y * dma->source_config.stride + + dma->roi.x * dma_bpp(dma->source_config.format))); dma->source_config.buf = (int)buf; if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) { mdp3_ccs_update(dma); @@ -662,7 +694,7 @@ static int mdp3_dmap_update(struct mdp3_dma *dma, void *buf, } static int mdp3_dmas_update(struct mdp3_dma *dma, void *buf, - struct mdp3_intf *intf) + struct mdp3_intf *intf, void *data) { unsigned long flag; int cb_type = MDP3_DMA_CALLBACK_TYPE_VSYNC; diff --git a/drivers/video/fbdev/msm/mdp3_dma.h b/drivers/video/fbdev/msm/mdp3_dma.h index 5e5321b3ca91..65a0b4e229fe 100644 --- a/drivers/video/fbdev/msm/mdp3_dma.h +++ b/drivers/video/fbdev/msm/mdp3_dma.h @@ -246,6 +246,13 @@ struct mdp3_tear_check { u32 refx100; }; +struct mdp3_rect { + u32 x; + u32 y; + u32 w; + u32 h; +}; + struct mdp3_intf; struct mdp3_dma { @@ -274,6 +281,7 @@ struct mdp3_dma { unsigned int vsync_status; bool update_src_cfg; bool has_panic_ctrl; + struct mdp3_rect roi; int (*dma_config)(struct mdp3_dma *dma, struct mdp3_dma_source *source_config, @@ -299,7 +307,8 @@ struct mdp3_dma { struct mdp3_dma_lut_config *config, struct mdp3_dma_lut *lut); - int (*update)(struct mdp3_dma *dma, void *buf, struct mdp3_intf *intf); + int (*update)(struct mdp3_dma *dma, + void *buf, struct mdp3_intf *intf, void *data); int (*update_cursor)(struct mdp3_dma *dma, int x, int y);