diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2016-10-10 18:28:10 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-10-10 18:28:10 -0700 |
commit | de4737612cca451329416facd4c017b2558b45dd (patch) | |
tree | 6f0aa29b591bdb115d069c3c22d18e6acd8918a8 | |
parent | cc67ae8322888705ede644102dd9c417049638b2 (diff) | |
parent | 2cccedc2effc329cebfd3f98f4e747450b0552c1 (diff) |
Merge "msm: mdss: Fix concurrent writeback failures in end-to-end use cases"
-rw-r--r-- | drivers/video/fbdev/msm/mdss.h | 1 | ||||
-rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.c | 2 | ||||
-rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.h | 7 | ||||
-rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_ctl.c | 11 | ||||
-rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_hwio.h | 4 | ||||
-rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c | 30 | ||||
-rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_layer.c | 10 |
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); |