summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-12-30 06:28:04 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2016-12-30 06:28:03 -0800
commit1f4589aad399f0e315d2531f67ffe8ebc354dd17 (patch)
treedc480d4a5f5d83153bd2d10630845fc22b17fb34
parent8841674585515f25b15274ef5858937d1f7f33a0 (diff)
parent3bf774ff8369d2d66d3324ce56e1b56ee1f14c89 (diff)
Merge "msm: mdss: fix data path for concurrent writeback"
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_ctl.c11
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c47
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_layer.c2
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);