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 <dkumarre@codeaurora.org>
This commit is contained in:
Dileep Kumar Reddi 2014-09-30 10:47:43 +05:30 committed by David Keitel
parent 949ef0c029
commit 1a365f9ac8
3 changed files with 84 additions and 9 deletions

View file

@ -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,

View file

@ -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;

View file

@ -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);