diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2016-12-30 06:28:04 -0800 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-12-30 06:28:03 -0800 |
| commit | 1f4589aad399f0e315d2531f67ffe8ebc354dd17 (patch) | |
| tree | dc480d4a5f5d83153bd2d10630845fc22b17fb34 | |
| parent | 8841674585515f25b15274ef5858937d1f7f33a0 (diff) | |
| parent | 3bf774ff8369d2d66d3324ce56e1b56ee1f14c89 (diff) | |
Merge "msm: mdss: fix data path for concurrent writeback"
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_ctl.c | 11 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c | 47 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_layer.c | 2 |
3 files changed, 41 insertions, 19 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index bb8227a74a04..5744f7d037b4 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -3513,7 +3513,6 @@ int mdss_mdp_cwb_setup(struct mdss_mdp_ctl *ctl) struct mdss_overlay_private *mdp5_data = NULL; struct mdss_mdp_wb_data *cwb_data; struct mdss_mdp_writeback_arg wb_args; - struct mdss_mdp_ctl *sctl = NULL; struct mdss_data_type *mdata = mdss_mdp_get_mdata(); u32 opmode, data_point; @@ -3575,14 +3574,11 @@ int mdss_mdp_cwb_setup(struct mdss_mdp_ctl *ctl) /* Select MEM_SEL to WB */ ctl->opmode |= MDSS_MDP_CTL_OP_WFD_MODE; - sctl = mdss_mdp_get_split_ctl(ctl); - if (sctl) - sctl->opmode |= MDSS_MDP_CTL_OP_WFD_MODE; /* Select CWB data point */ data_point = (cwb->layer.flags & MDP_COMMIT_CWB_DSPP) ? 0x4 : 0; writel_relaxed(data_point, mdata->mdp_base + mdata->ppb_ctl[2]); - if (sctl) + if (ctl->mixer_right) writel_relaxed(data_point + 1, mdata->mdp_base + mdata->ppb_ctl[3]); @@ -3591,11 +3587,6 @@ int mdss_mdp_cwb_setup(struct mdss_mdp_ctl *ctl) opmode = mdss_mdp_ctl_read(ctl, MDSS_MDP_REG_CTL_TOP) | ctl->opmode; mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_TOP, opmode); - if (sctl) { - opmode = mdss_mdp_ctl_read(sctl, MDSS_MDP_REG_CTL_TOP) | - sctl->opmode; - mdss_mdp_ctl_write(sctl, MDSS_MDP_REG_CTL_TOP, opmode); - } /* Increase commit count to signal CWB release fence */ atomic_inc(&cwb->cwb_sync_pt_data.commit_cnt); diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c b/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c index 80549908beb6..9bebd72dce61 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c @@ -262,7 +262,7 @@ static void mdss_mdp_writeback_cwb_overflow(void *arg) mdss_mdp_set_intr_callback_nosync(MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW, CWB_PPB_0, NULL, NULL); - if (mdss_mdp_get_split_ctl(ctl)) { + if (ctl->mixer_right) { mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW, CWB_PPB_1); mdss_mdp_set_intr_callback_nosync( @@ -297,7 +297,7 @@ static void mdss_mdp_writeback_cwb_intr_done(void *arg) mdss_mdp_set_intr_callback_nosync(MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW, CWB_PPB_0, NULL, NULL); - if (mdss_mdp_get_split_ctl(ctl)) { + if (ctl->mixer_right) { mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW, CWB_PPB_1); mdss_mdp_set_intr_callback_nosync( @@ -477,21 +477,34 @@ int mdss_mdp_writeback_prepare_cwb(struct mdss_mdp_ctl *ctl, struct mdss_mdp_writeback_ctx *ctx = NULL; struct mdp_layer_buffer *buffer = NULL; struct mdss_mdp_cwb *cwb = NULL; - struct mdss_mdp_ctl *sctl = NULL; - int ret = 0; + int i, ret = 0; + unsigned long total_buf_len = 0; + struct mdss_mdp_data *data = NULL; + struct mdss_mdp_plane_sizes ps; + struct mdss_mdp_format_params *fmt; + + if (!wb_arg->data) + return -EINVAL; mdp5_data = mfd_to_mdp5_data(ctl->mfd); cwb = &mdp5_data->cwb; ctx = (struct mdss_mdp_writeback_ctx *)cwb->priv_data; + data = wb_arg->data; buffer = &cwb->layer.buffer; - ctx->opmode = 0; - ctx->img_width = buffer->width; + /* + * client can program CWB output dimensions as only primary + * resolution, but output buffer allocated can be with bigger stride + * aligned for platform specific reasons & can interpret the output + * buffer in same stride. Program output stride based on client request + */ + ctx->img_width = buffer->planes[0].stride; ctx->img_height = buffer->height; ctx->width = buffer->width; ctx->height = buffer->height; ctx->frame_rate = ctl->frame_rate; + ctx->opmode = 0; ctx->dst_rect.x = 0; ctx->dst_rect.y = 0; ctx->dst_rect.w = ctx->width; @@ -503,6 +516,23 @@ int mdss_mdp_writeback_prepare_cwb(struct mdss_mdp_ctl *ctl, return ret; } + /* + * Need additional buffer size validation as we are + * updating img_width with buffer->planes[0].stride + */ + fmt = mdss_mdp_get_format_params(buffer->format); + mdss_mdp_get_plane_sizes(fmt, ctx->img_width, + buffer->height, &ps, 0, 0); + + for (i = 0; i < buffer->plane_count ; i++) + total_buf_len += data->p[i].len; + + if (total_buf_len < ps.total_size) { + pr_err("Buffer size=%lu, expected size=%d\n", total_buf_len, + ps.total_size); + return -EINVAL; + } + ret = mdss_mdp_writeback_addr_setup(ctx, wb_arg->data); if (ret) { pr_err("cwb writeback data setup error\n"); @@ -516,11 +546,10 @@ int mdss_mdp_writeback_prepare_cwb(struct mdss_mdp_ctl *ctl, CWB_PPB_0, mdss_mdp_writeback_cwb_overflow, ctl); mdss_mdp_irq_enable(MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW, CWB_PPB_0); - sctl = mdss_mdp_get_split_ctl(ctl); - if (sctl) { + if (ctl->mixer_right) { mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW, CWB_PPB_1, mdss_mdp_writeback_cwb_overflow, - sctl); + ctl); mdss_mdp_irq_enable(MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW, CWB_PPB_1); } diff --git a/drivers/video/fbdev/msm/mdss_mdp_layer.c b/drivers/video/fbdev/msm/mdss_mdp_layer.c index 0731cbcafe7c..c53c8d293539 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_layer.c +++ b/drivers/video/fbdev/msm/mdss_mdp_layer.c @@ -2823,6 +2823,8 @@ int mdss_mdp_layer_pre_commit_cwb(struct msm_fb_data_type *mfd, } mdp5_data->cwb.layer = *commit->output_layer; + mdp5_data->cwb.layer.flags |= (commit->flags & MDP_COMMIT_CWB_DSPP) ? + MDP_COMMIT_CWB_DSPP : 0; mdp5_data->cwb.wb_idx = commit->output_layer->writeback_ndx; mutex_lock(&mdp5_data->cwb.queue_lock); |
