From: Ville Syrjälä <ville.syrj...@linux.intel.com>

The programming of the DPHY vs. DSI _TIMING registers are
two separate steps in the TGL+ bspec sequence, with some
other stuff in between. Implement the same split.
Windows also seems follow the bspec TGL+ sequence, even
on ICL/JSL.

Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
---
 drivers/gpu/drm/i915/display/icl_dsi.c | 70 ++++++++++++++++----------
 1 file changed, 43 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c 
b/drivers/gpu/drm/i915/display/icl_dsi.c
index b35b69227e6f..89d608747fff 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -528,31 +528,16 @@ gen11_dsi_setup_dphy_timings(struct intel_encoder 
*encoder,
        enum port port;
        enum phy phy;
 
-       /* Program T-INIT master registers */
-       for_each_dsi_port(port, intel_dsi->ports)
-               intel_de_rmw(dev_priv, ICL_DSI_T_INIT_MASTER(port),
-                            DSI_T_INIT_MASTER_MASK, intel_dsi->init_count);
-
        /* Program DPHY clock lanes timings */
-       for_each_dsi_port(port, intel_dsi->ports) {
+       for_each_dsi_port(port, intel_dsi->ports)
                intel_de_write(dev_priv, DPHY_CLK_TIMING_PARAM(port),
                               intel_dsi->dphy_reg);
 
-               /* shadow register inside display core */
-               intel_de_write(dev_priv, DSI_CLK_TIMING_PARAM(port),
-                              intel_dsi->dphy_reg);
-       }
-
        /* Program DPHY data lanes timings */
-       for_each_dsi_port(port, intel_dsi->ports) {
+       for_each_dsi_port(port, intel_dsi->ports)
                intel_de_write(dev_priv, DPHY_DATA_TIMING_PARAM(port),
                               intel_dsi->dphy_data_lane_reg);
 
-               /* shadow register inside display core */
-               intel_de_write(dev_priv, DSI_DATA_TIMING_PARAM(port),
-                              intel_dsi->dphy_data_lane_reg);
-       }
-
        /*
         * If DSI link operating at or below an 800 MHz,
         * TA_SURE should be override and programmed to
@@ -561,16 +546,10 @@ gen11_dsi_setup_dphy_timings(struct intel_encoder 
*encoder,
         */
        if (DISPLAY_VER(dev_priv) == 11) {
                if (afe_clk(encoder, crtc_state) <= 800000) {
-                       for_each_dsi_port(port, intel_dsi->ports) {
+                       for_each_dsi_port(port, intel_dsi->ports)
                                intel_de_rmw(dev_priv, 
DPHY_TA_TIMING_PARAM(port),
                                             TA_SURE_MASK,
                                             TA_SURE_OVERRIDE | TA_SURE(0));
-
-                               /* shadow register inside display core */
-                               intel_de_rmw(dev_priv, 
DSI_TA_TIMING_PARAM(port),
-                                            TA_SURE_MASK,
-                                            TA_SURE_OVERRIDE | TA_SURE(0));
-                       }
                }
        }
 
@@ -581,6 +560,41 @@ gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder,
        }
 }
 
+static void
+gen11_dsi_setup_timings(struct intel_encoder *encoder,
+                       const struct intel_crtc_state *crtc_state)
+{
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       enum port port;
+
+       /* Program T-INIT master registers */
+       for_each_dsi_port(port, intel_dsi->ports)
+               intel_de_rmw(dev_priv, ICL_DSI_T_INIT_MASTER(port),
+                            DSI_T_INIT_MASTER_MASK, intel_dsi->init_count);
+
+       /* shadow register inside display core */
+       for_each_dsi_port(port, intel_dsi->ports)
+               intel_de_write(dev_priv, DSI_CLK_TIMING_PARAM(port),
+                              intel_dsi->dphy_reg);
+
+       /* shadow register inside display core */
+       for_each_dsi_port(port, intel_dsi->ports)
+               intel_de_write(dev_priv, DSI_DATA_TIMING_PARAM(port),
+                              intel_dsi->dphy_data_lane_reg);
+
+       /* shadow register inside display core */
+       if (DISPLAY_VER(dev_priv) == 11) {
+               if (afe_clk(encoder, crtc_state) <= 800000) {
+                       for_each_dsi_port(port, intel_dsi->ports) {
+                               intel_de_rmw(dev_priv, 
DSI_TA_TIMING_PARAM(port),
+                                            TA_SURE_MASK,
+                                            TA_SURE_OVERRIDE | TA_SURE(0));
+                       }
+               }
+       }
+}
+
 static void gen11_dsi_gate_clocks(struct intel_encoder *encoder)
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
@@ -1090,12 +1104,14 @@ gen11_dsi_enable_port_and_phy(struct intel_encoder 
*encoder,
        /* step 4c: configure voltage swing and skew */
        gen11_dsi_voltage_swing_program_seq(encoder);
 
-       /* enable DDI buffer */
-       gen11_dsi_enable_ddi_buffer(encoder);
-
        /* setup D-PHY timings */
        gen11_dsi_setup_dphy_timings(encoder, crtc_state);
 
+       /* enable DDI buffer */
+       gen11_dsi_enable_ddi_buffer(encoder);
+
+       gen11_dsi_setup_timings(encoder, crtc_state);
+
        /* Since transcoder is configured to take events from GPIO */
        gen11_dsi_config_util_pin(encoder, true);
 
-- 
2.39.2

Reply via email to