drm/i915/dsi: Split icl+ D-PHY vs. DSI timing steps
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Thu, 8 Jun 2023 20:30:48 +0000 (23:30 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Tue, 13 Jun 2023 16:03:35 +0000 (19:03 +0300)
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.

Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230608203057.23759-5-ville.syrjala@linux.intel.com
drivers/gpu/drm/i915/display/icl_dsi.c

index d60cf45..6d60197 100644 (file)
@@ -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,11 +1104,13 @@ gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder,
        /* step 4c: configure voltage swing and skew */
        gen11_dsi_voltage_swing_program_seq(encoder);
 
+       /* setup D-PHY timings */
+       gen11_dsi_setup_dphy_timings(encoder, crtc_state);
+
        /* enable DDI buffer */
        gen11_dsi_enable_ddi_buffer(encoder);
 
-       /* setup D-PHY timings */
-       gen11_dsi_setup_dphy_timings(encoder, crtc_state);
+       gen11_dsi_setup_timings(encoder, crtc_state);
 
        /* Since transcoder is configured to take events from GPIO */
        gen11_dsi_config_util_pin(encoder, true);