From: Madhav Chauhan <madhav.chau...@intel.com>

As per BSPEC, driver needs to ensure that all of commands/data
has been dispatched to panel before the transcoder is enabled.
This patch implement those steps i.e. sending NOP DCS command,
wait for header/payload credit to be released etc.

Signed-off-by: Madhav Chauhan <madhav.chau...@intel.com>
Signed-off-by: Jani Nikula <jani.nik...@intel.com>
---
 drivers/gpu/drm/i915/icl_dsi.c | 53 ++++++++++++++++++++++++++++++++++++++----
 1 file changed, 48 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c
index 5fe024dfbdb0..90188ba8a4dc 100644
--- a/drivers/gpu/drm/i915/icl_dsi.c
+++ b/drivers/gpu/drm/i915/icl_dsi.c
@@ -28,9 +28,8 @@
 #include <drm/drm_mipi_dsi.h>
 #include "intel_dsi.h"
 
-static void __attribute__((unused)) wait_for_dsi_hdr_credit_release(
-                                               struct intel_dsi *intel_dsi,
-                                               enum transcoder dsi_trans)
+static void wait_for_dsi_hdr_credit_release(struct intel_dsi *intel_dsi,
+                                           enum transcoder dsi_trans)
 {
        struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
 
@@ -40,8 +39,7 @@ static void __attribute__((unused)) 
wait_for_dsi_hdr_credit_release(
                DRM_ERROR("DSI header credits not released\n");
 }
 
-static void __attribute__((unused)) wait_for_dsi_payload_credit_release(
-                                               struct intel_dsi *intel_dsi,
+static void wait_for_dsi_payload_credit_release(struct intel_dsi *intel_dsi,
                                                enum transcoder dsi_trans)
 {
        struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
@@ -60,6 +58,48 @@ static enum transcoder dsi_port_to_transcoder(enum port port)
                return TRANSCODER_DSI_1;
 }
 
+static void wait_for_cmds_dispatched_to_panel(struct intel_encoder *encoder)
+{
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+       struct mipi_dsi_device *dsi;
+       enum port port;
+       enum transcoder dsi_trans;
+       int ret;
+
+       /* wait for header/payload credits to be released */
+       for_each_dsi_port(port, intel_dsi->ports) {
+               dsi_trans = dsi_port_to_transcoder(port);
+               wait_for_dsi_hdr_credit_release(intel_dsi, dsi_trans);
+               wait_for_dsi_payload_credit_release(intel_dsi, dsi_trans);
+       }
+
+       /* send nop DCS command */
+       for_each_dsi_port(port, intel_dsi->ports) {
+               dsi = intel_dsi->dsi_hosts[port]->device;
+               dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+               dsi->channel = 0;
+               ret = mipi_dsi_dcs_nop(dsi);
+               if (ret < 0)
+                       DRM_ERROR("error sending DCS NOP command\n");
+       }
+
+       /* wait for header credits to be released */
+       for_each_dsi_port(port, intel_dsi->ports) {
+               dsi_trans = dsi_port_to_transcoder(port);
+               wait_for_dsi_hdr_credit_release(intel_dsi, dsi_trans);
+       }
+
+       /* wait for LP TX in progress bit to be cleared */
+       for_each_dsi_port(port, intel_dsi->ports) {
+               dsi_trans = dsi_port_to_transcoder(port);
+               if (wait_for_us(!(I915_READ(DSI_LP_MSG(dsi_trans)) &
+                                 LPTX_IN_PROGRESS),
+                                 20))
+                       DRM_ERROR("LPTX bit not cleared\n");
+       }
+}
+
 static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder)
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
@@ -690,6 +730,9 @@ static void gen11_dsi_powerup_panel(struct intel_encoder 
*encoder)
        intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET);
        intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_INIT_OTP);
        intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DISPLAY_ON);
+
+       /* ensure all panel commands dispatched before enabling transcoder */
+       wait_for_cmds_dispatched_to_panel(encoder);
 }
 
 static void __attribute__((unused))
-- 
2.11.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to