summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKrishna Chaitanya Parimi <cparimi@codeaurora.org>2014-03-28 19:17:58 +0530
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:29:08 -0700
commit7b23e8979ed1da489f311f658898f85f2135b223 (patch)
treed2baf207ffb29fe901ed6a9381cc01503041d934
parentb501f7f5390d25bc752932b75d1551f16bfa4459 (diff)
mdss: Start wait for hist ready state past first kickoff
When the first histogram kickoff is done past reset, it might be too late into the waiting period of completion. This would cause a timeout even though data for the frame is made available and interrupt is generated after timeout. This causes a histogram read call to return with an error and delay reading the data. Edit to make the wait for ready to start after the first kickoff. Add additional completion to denote first kickoff and start wait after first kickoff wait has completed. Change-Id: Ic9156b4d8852520715324707290287eb09df6195 Signed-off-by: Krishna Chaitanya Parimi <cparimi@codeaurora.org>
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.h1
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pp.c27
2 files changed, 25 insertions, 3 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h
index a3100b9679f3..f4eca405cafe 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.h
+++ b/drivers/video/fbdev/msm/mdss_mdp.h
@@ -283,6 +283,7 @@ struct pp_hist_col_info {
u32 hist_cnt_time;
u32 frame_cnt;
struct completion comp;
+ struct completion first_kick;
u32 data[HIST_V_SIZE];
struct mutex hist_mutex;
spinlock_t hist_lock;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp.c b/drivers/video/fbdev/msm/mdss_mdp_pp.c
index fdbfe7746cec..b46b7f672779 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_pp.c
@@ -85,6 +85,8 @@ struct mdp_csc_cfg mdp_csc_convert[MDSS_MDP_MAX_CSC] = {
#define HIST_V2_INTR_BIT_MASK 0xF33000
#define HIST_V1_INTR_BIT_MASK 0X333333
#define HIST_WAIT_TIMEOUT(frame) ((75 * HZ * (frame)) / 1000)
+#define HIST_KICKOFF_WAIT_FRACTION 4
+
/* hist collect state */
enum {
HIST_UNKNOWN,
@@ -1447,6 +1449,7 @@ static int pp_hist_setup(u32 *op, u32 block, struct mdss_mdp_mixer *mix)
if (is_hist_v1)
writel_relaxed(1, base + kick_base);
hist_info->col_state = HIST_START;
+ complete(&hist_info->first_kick);
}
}
spin_unlock_irqrestore(&hist_info->hist_lock, flag);
@@ -1914,6 +1917,7 @@ int mdss_mdp_pp_init(struct device *dev)
mdss_mdp_get_dspp_addr_off(i) +
MDSS_MDP_REG_DSPP_HIST_CTL_BASE;
init_completion(&hist[i].comp);
+ init_completion(&hist[i].first_kick);
}
if (mdata->nmixers_intf == 4)
hist[3].intr_shift = 22;
@@ -1931,6 +1935,7 @@ int mdss_mdp_pp_init(struct device *dev)
vig[i].pp_res.hist.base = vig[i].base +
MDSS_MDP_REG_VIG_HIST_CTL_BASE;
init_completion(&vig[i].pp_res.hist.comp);
+ init_completion(&vig[i].pp_res.hist.first_kick);
}
if (!mdata->pp_bus_hdl) {
pp_bus_pdata = &mdp_pp_bus_scale_table;
@@ -3160,6 +3165,7 @@ static int pp_hist_enable(struct pp_hist_col_info *hist_info,
spin_unlock_irqrestore(&hist_info->hist_lock, flag);
hist_info->frame_cnt = req->frame_cnt;
INIT_COMPLETION(hist_info->comp);
+ INIT_COMPLETION(hist_info->first_kick);
hist_info->hist_cnt_read = 0;
hist_info->hist_cnt_sent = 0;
hist_info->hist_cnt_time = 0;
@@ -3292,6 +3298,7 @@ static int pp_hist_disable(struct pp_hist_col_info *hist_info)
mdss_mdp_hist_intr_req(&mdata->hist_intr,
intr_mask << hist_info->intr_shift, false);
complete_all(&hist_info->comp);
+ complete_all(&hist_info->first_kick);
/* if hist v2, make sure HW is unlocked */
if (is_hist_v2)
writel_relaxed(0, hist_info->base);
@@ -3523,7 +3530,7 @@ static int pp_hist_collect(struct mdp_histogram_data *hist,
struct pp_hist_col_info *hist_info,
char __iomem *ctl_base, u32 expect_sum)
{
- int wait_ret, ret = 0;
+ int kick_ret, wait_ret, ret = 0;
u32 timeout, sum;
char __iomem *v_base;
unsigned long flag;
@@ -3554,12 +3561,26 @@ static int pp_hist_collect(struct mdp_histogram_data *hist,
pipe = container_of(res, struct mdss_mdp_pipe, pp_res);
pipe->params_changed++;
}
- wait_ret = wait_for_completion_killable_timeout(
+ kick_ret = wait_for_completion_killable_timeout(
+ &(hist_info->first_kick), timeout /
+ HIST_KICKOFF_WAIT_FRACTION);
+ if (kick_ret != 0)
+ wait_ret = wait_for_completion_killable_timeout(
&(hist_info->comp), timeout);
mutex_lock(&hist_info->hist_mutex);
spin_lock_irqsave(&hist_info->hist_lock, flag);
- if (wait_ret == 0) {
+ if (kick_ret == 0) {
+ ret = -ENODATA;
+ pr_debug("histogram kickoff not done yet");
+ spin_unlock_irqrestore(&hist_info->hist_lock, flag);
+ goto hist_collect_exit;
+ } else if (kick_ret < 0) {
+ ret = -EINTR;
+ pr_debug("histogram first kickoff interrupted");
+ spin_unlock_irqrestore(&hist_info->hist_lock, flag);
+ goto hist_collect_exit;
+ } else if (wait_ret == 0) {
ret = -ETIMEDOUT;
pr_debug("bin collection timedout, state %d",
hist_info->col_state);