summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-10-10 18:28:10 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-10-10 18:28:10 -0700
commitde4737612cca451329416facd4c017b2558b45dd (patch)
tree6f0aa29b591bdb115d069c3c22d18e6acd8918a8
parentcc67ae8322888705ede644102dd9c417049638b2 (diff)
parent2cccedc2effc329cebfd3f98f4e747450b0552c1 (diff)
Merge "msm: mdss: Fix concurrent writeback failures in end-to-end use cases"
-rw-r--r--drivers/video/fbdev/msm/mdss.h1
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.c2
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.h7
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_ctl.c11
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_hwio.h4
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c30
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_layer.c10
7 files changed, 55 insertions, 10 deletions
diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h
index a5368cdf2254..55918d47a21a 100644
--- a/drivers/video/fbdev/msm/mdss.h
+++ b/drivers/video/fbdev/msm/mdss.h
@@ -193,6 +193,7 @@ enum mdss_qos_settings {
MDSS_QOS_REMAPPER,
MDSS_QOS_IB_NOCR,
MDSS_QOS_WB2_WRITE_GATHER_EN,
+ MDSS_QOS_WB_QOS,
MDSS_QOS_MAX,
};
diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c
index 81e3438befca..6845b386807b 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp.c
@@ -1992,6 +1992,8 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata)
set_bit(MDSS_QOS_PER_PIPE_IB, mdata->mdss_qos_map);
set_bit(MDSS_QOS_REMAPPER, mdata->mdss_qos_map);
+ set_bit(MDSS_QOS_TS_PREFILL, mdata->mdss_qos_map);
+ set_bit(MDSS_QOS_WB_QOS, mdata->mdss_qos_map);
set_bit(MDSS_QOS_OVERHEAD_FACTOR, mdata->mdss_qos_map);
set_bit(MDSS_QOS_CDP, mdata->mdss_qos_map); /* cdp supported */
mdata->enable_cdp = false; /* disable cdp */
diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h
index 0085163ada52..8ac63aaaefce 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.h
+++ b/drivers/video/fbdev/msm/mdss_mdp.h
@@ -122,6 +122,11 @@
*/
#define MDSS_MDP_DS_OVERFETCH_SIZE 5
+#define QOS_LUT_NRT_READ 0x0
+#define QOS_LUT_CWB_READ 0xe4000000
+#define PANIC_LUT_NRT_READ 0x0
+#define ROBUST_LUT_NRT_READ 0xFFFF
+
/* hw cursor can only be setup in highest mixer stage */
#define HW_CURSOR_STAGE(mdata) \
(((mdata)->max_target_zorder + MDSS_MDP_STAGE_0) - 1)
@@ -407,7 +412,7 @@ struct mdss_mdp_cwb {
struct list_head data_queue;
int valid;
u32 wb_idx;
- struct mdp_output_layer *layer;
+ struct mdp_output_layer layer;
void *priv_data;
struct msm_sync_pt_data cwb_sync_pt_data;
struct blocking_notifier_head notifier_head;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
index ebc7d2144eb9..eb1e0b5c47a6 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
@@ -3424,6 +3424,7 @@ int mdss_mdp_cwb_setup(struct mdss_mdp_ctl *ctl)
mutex_lock(&cwb->queue_lock);
cwb_data = list_first_entry_or_null(&cwb->data_queue,
struct mdss_mdp_wb_data, next);
+ __list_del_entry(&cwb_data->next);
mutex_unlock(&cwb->queue_lock);
if (cwb_data == NULL) {
pr_err("no output buffer for cwb\n");
@@ -3453,14 +3454,14 @@ int mdss_mdp_cwb_setup(struct mdss_mdp_ctl *ctl)
sctl->opmode |= MDSS_MDP_CTL_OP_WFD_MODE;
/* Select CWB data point */
- data_point = (cwb->layer->flags & MDP_COMMIT_CWB_DSPP) ? 0x4 : 0;
+ data_point = (cwb->layer.flags & MDP_COMMIT_CWB_DSPP) ? 0x4 : 0;
writel_relaxed(data_point, mdata->mdp_base + mdata->ppb_ctl[2]);
if (sctl)
writel_relaxed(data_point + 1,
mdata->mdp_base + mdata->ppb_ctl[3]);
- /* Flush WB */
- ctl->flush_bits |= BIT(16);
+ /* Flush WB and CTL */
+ ctl->flush_bits |= BIT(16) | BIT(17);
opmode = mdss_mdp_ctl_read(ctl, MDSS_MDP_REG_CTL_TOP) | ctl->opmode;
mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_TOP, opmode);
@@ -3469,6 +3470,10 @@ int mdss_mdp_cwb_setup(struct mdss_mdp_ctl *ctl)
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);
+
goto cwb_setup_done;
cwb_setup_fail:
diff --git a/drivers/video/fbdev/msm/mdss_mdp_hwio.h b/drivers/video/fbdev/msm/mdss_mdp_hwio.h
index 76fd2d12ac95..294e05c2fbb0 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_hwio.h
+++ b/drivers/video/fbdev/msm/mdss_mdp_hwio.h
@@ -541,6 +541,10 @@ enum mdss_mdp_writeback_index {
#define MDSS_MDP_REG_WB_N16_INIT_PHASE_Y_C12 0x06C
#define MDSS_MDP_REG_WB_OUT_SIZE 0x074
#define MDSS_MDP_REG_WB_ALPHA_X_VALUE 0x078
+#define MDSS_MDP_REG_WB_DANGER_LUT 0x084
+#define MDSS_MDP_REG_WB_SAFE_LUT 0x088
+#define MDSS_MDP_REG_WB_CREQ_LUT 0x08c
+#define MDSS_MDP_REG_WB_QOS_CTRL 0x090
#define MDSS_MDP_REG_WB_CSC_BASE 0x260
#define MDSS_MDP_REG_WB_DST_ADDR_SW_STATUS 0x2B0
#define MDSS_MDP_REG_WB_CDP_CTRL 0x2B4
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c b/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c
index 40b10e368309..e6e03e7d54b2 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c
@@ -124,6 +124,30 @@ static inline void mdp_wb_write(struct mdss_mdp_writeback_ctx *ctx,
writel_relaxed(val, ctx->base + reg);
}
+static void mdss_mdp_set_qos_wb(struct mdss_mdp_ctl *ctl,
+ struct mdss_mdp_writeback_ctx *ctx)
+{
+ u32 wb_qos_setup = QOS_LUT_NRT_READ;
+ struct mdss_mdp_cwb *cwb = NULL;
+ struct mdss_overlay_private *mdp5_data;
+ struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+
+ if (false == test_bit(MDSS_QOS_WB_QOS, mdata->mdss_qos_map))
+ return;
+
+ mdp5_data = mfd_to_mdp5_data(ctl->mfd);
+ cwb = &mdp5_data->cwb;
+
+ if (cwb->valid)
+ wb_qos_setup = QOS_LUT_CWB_READ;
+ else
+ wb_qos_setup = QOS_LUT_NRT_READ;
+
+ mdp_wb_write(ctx, MDSS_MDP_REG_WB_DANGER_LUT, PANIC_LUT_NRT_READ);
+ mdp_wb_write(ctx, MDSS_MDP_REG_WB_SAFE_LUT, ROBUST_LUT_NRT_READ);
+ mdp_wb_write(ctx, MDSS_MDP_REG_WB_CREQ_LUT, wb_qos_setup);
+}
+
static void mdss_mdp_set_ot_limit_wb(struct mdss_mdp_writeback_ctx *ctx,
int is_wfd)
{
@@ -447,7 +471,7 @@ int mdss_mdp_writeback_prepare_cwb(struct mdss_mdp_ctl *ctl,
cwb = &mdp5_data->cwb;
ctx = (struct mdss_mdp_writeback_ctx *)cwb->priv_data;
- buffer = &cwb->layer->buffer;
+ buffer = &cwb->layer.buffer;
ctx->opmode = 0;
ctx->img_width = buffer->width;
@@ -495,6 +519,8 @@ int mdss_mdp_writeback_prepare_cwb(struct mdss_mdp_ctl *ctl,
if (ctl->mdata->default_ot_wr_limit || ctl->mdata->default_ot_rd_limit)
mdss_mdp_set_ot_limit_wb(ctx, false);
+ mdss_mdp_set_qos_wb(ctl, ctx);
+
return ret;
}
@@ -897,6 +923,8 @@ static int mdss_mdp_writeback_display(struct mdss_mdp_ctl *ctl, void *arg)
ctl->mdata->default_ot_rd_limit)
mdss_mdp_set_ot_limit_wb(ctx, true);
+ mdss_mdp_set_qos_wb(ctl, ctx);
+
wb_args = (struct mdss_mdp_writeback_arg *) arg;
if (!wb_args)
return -ENOENT;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_layer.c b/drivers/video/fbdev/msm/mdss_mdp_layer.c
index 91d4332700b6..0f0df2256f74 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_layer.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_layer.c
@@ -2285,12 +2285,12 @@ end:
return ret;
}
-int __is_cwb_requested(uint32_t output_layer_flags)
+int __is_cwb_requested(uint32_t commit_flags)
{
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
int req = 0;
- req = output_layer_flags & MDP_COMMIT_CWB_EN;
+ req = commit_flags & MDP_COMMIT_CWB_EN;
if (req && !test_bit(MDSS_CAPS_CWB_SUPPORTED, mdata->mdss_caps_map)) {
pr_err("CWB not supported");
return -ENODEV;
@@ -2330,7 +2330,7 @@ int mdss_mdp_layer_pre_commit(struct msm_fb_data_type *mfd,
return -EINVAL;
if (commit->output_layer) {
- ret = __is_cwb_requested(commit->output_layer->flags);
+ ret = __is_cwb_requested(commit->flags);
if (IS_ERR_VALUE(ret)) {
return ret;
} else if (ret) {
@@ -2493,7 +2493,7 @@ int mdss_mdp_layer_atomic_validate(struct msm_fb_data_type *mfd,
}
if (commit->output_layer) {
- rc = __is_cwb_requested(commit->output_layer->flags);
+ rc = __is_cwb_requested(commit->flags);
if (IS_ERR_VALUE(rc)) {
return rc;
} else if (rc) {
@@ -2553,7 +2553,7 @@ int mdss_mdp_layer_pre_commit_cwb(struct msm_fb_data_type *mfd,
return rc;
}
- mdp5_data->cwb.layer = commit->output_layer;
+ mdp5_data->cwb.layer = *commit->output_layer;
mdp5_data->cwb.wb_idx = commit->output_layer->writeback_ndx;
mutex_lock(&mdp5_data->cwb.queue_lock);