summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSrihitha Tangudu <quic_tangudu@quicinc.com>2022-01-10 18:36:25 +0530
committerSrihitha Tangudu <quic_tangudu@quicinc.com>2022-01-20 18:09:18 +0530
commitd171e18f7cb1a8fc256531edb6492b183993aca3 (patch)
treed13dda823d68532a9b35e7810e9bbd86a7c77812
parentebb58746239f7ec0fab19c1b98950e681ee97ba6 (diff)
downloaddisplay-drivers-d171e18f7cb1a8fc256531edb6492b183993aca3.tar.gz
disp: msm: sde: while timing engine enabling poll for active region
DCS commands triggered right after timing engine enable can conflict with blanking period causing command transfer failures. Right after timing engine enable poll for frame start and line count reaching active region of display before any DCS commands. Change-Id: Ia3967e01c3bb5bc82aa3549c300fa8335e00210c Signed-off-by: Prabhanjan Kandula <quic_pkandula@quicinc.com> Signed-off-by: Srihitha Tangudu <quic_tangudu@quicinc.com>
-rw-r--r--msm/sde/sde_encoder_phys_vid.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/msm/sde/sde_encoder_phys_vid.c b/msm/sde/sde_encoder_phys_vid.c
index 7708cf8f..67e6b068 100644
--- a/msm/sde/sde_encoder_phys_vid.c
+++ b/msm/sde/sde_encoder_phys_vid.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
@@ -1080,12 +1081,47 @@ exit:
phys_enc->enable_state = SDE_ENC_DISABLED;
}
+static int sde_encoder_phys_vid_poll_for_active_region(
+ struct sde_encoder_phys *phys_enc)
+{
+ struct sde_encoder_phys_vid *vid_enc;
+ struct intf_timing_params *timing;
+ struct drm_display_mode mode;
+ u32 line_cnt, v_inactive, poll_time_us, trial = 0;
+
+ if (!phys_enc || !phys_enc->hw_intf ||
+ !phys_enc->hw_intf->ops.get_line_count)
+ return -EINVAL;
+
+ vid_enc = to_sde_encoder_phys_vid(phys_enc);
+ timing = &vid_enc->timing_params;
+ mode = phys_enc->cached_mode;
+
+ /* if programmable fetch is not enabled return early */
+ if (!programmable_fetch_get_num_lines(vid_enc, timing, false))
+ return 0;
+
+ poll_time_us = DIV_ROUND_UP(1000000, mode.vrefresh) / MAX_POLL_CNT;
+ v_inactive = timing->v_front_porch + timing->v_back_porch +
+ timing->vsync_pulse_width;
+
+ do {
+ usleep_range(poll_time_us, poll_time_us + 5);
+ line_cnt = phys_enc->hw_intf->ops.get_line_count(
+ phys_enc->hw_intf);
+ trial++;
+ } while ((trial < MAX_POLL_CNT) || (line_cnt < v_inactive));
+
+ return (trial >= MAX_POLL_CNT) ? -ETIMEDOUT : 0;
+}
+
static void sde_encoder_phys_vid_handle_post_kickoff(
struct sde_encoder_phys *phys_enc)
{
unsigned long lock_flags;
struct sde_encoder_phys_vid *vid_enc;
u32 avr_mode;
+ u32 ret;
if (!phys_enc) {
SDE_ERROR("invalid encoder\n");
@@ -1108,6 +1144,11 @@ static void sde_encoder_phys_vid_handle_post_kickoff(
1);
spin_unlock_irqrestore(phys_enc->enc_spinlock,
lock_flags);
+ ret = sde_encoder_phys_vid_poll_for_active_region(
+ phys_enc);
+ if (ret)
+ SDE_DEBUG_VIDENC(vid_enc,
+ "poll for active failed ret:%d\n", ret);
}
phys_enc->enable_state = SDE_ENC_ENABLED;
}