drm/i915/dsi: Go back to the previous INIT_OTP/DISPLAY_ON order, mostly
authorjsg <jsg@openbsd.org>
Thu, 4 Apr 2024 08:03:27 +0000 (08:03 +0000)
committerjsg <jsg@openbsd.org>
Thu, 4 Apr 2024 08:03:27 +0000 (08:03 +0000)
From Ville Syrjala
69fa0e23a6a3b30dc14b731c7e5818375aaa4da6 in linux-6.6.y/6.6.24
18846627ef1210dcd55d65342b055ea97a46ffff in mainline linux

sys/dev/pci/drm/i915/display/icl_dsi.c
sys/dev/pci/drm/i915/display/intel_bios.c

index 89b7c60..336bc22 100644 (file)
@@ -1155,7 +1155,6 @@ static void gen11_dsi_powerup_panel(struct intel_encoder *encoder)
        }
 
        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);
@@ -1256,6 +1255,8 @@ static void gen11_dsi_enable(struct intel_atomic_state *state,
        /* step6d: enable dsi transcoder */
        gen11_dsi_enable_transcoder(encoder);
 
+       intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DISPLAY_ON);
+
        /* step7: enable backlight */
        intel_backlight_enable(crtc_state, conn_state);
        intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_ON);
index 4be57bc..5694147 100644 (file)
@@ -1945,16 +1945,12 @@ static int get_init_otp_deassert_fragment_len(struct drm_i915_private *i915,
  * these devices we split the init OTP sequence into a deassert sequence and
  * the actual init OTP part.
  */
-static void fixup_mipi_sequences(struct drm_i915_private *i915,
-                                struct intel_panel *panel)
+static void vlv_fixup_mipi_sequences(struct drm_i915_private *i915,
+                                    struct intel_panel *panel)
 {
        u8 *init_otp;
        int len;
 
-       /* Limit this to VLV for now. */
-       if (!IS_VALLEYVIEW(i915))
-               return;
-
        /* Limit this to v1 vid-mode sequences */
        if (panel->vbt.dsi.config->is_cmd_mode ||
            panel->vbt.dsi.seq_version != 1)
@@ -1990,6 +1986,41 @@ static void fixup_mipi_sequences(struct drm_i915_private *i915,
        panel->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP] = init_otp + len - 1;
 }
 
+/*
+ * Some machines (eg. Lenovo 82TQ) appear to have broken
+ * VBT sequences:
+ * - INIT_OTP is not present at all
+ * - what should be in INIT_OTP is in DISPLAY_ON
+ * - what should be in DISPLAY_ON is in BACKLIGHT_ON
+ *   (along with the actual backlight stuff)
+ *
+ * To make those work we simply swap DISPLAY_ON and INIT_OTP.
+ *
+ * TODO: Do we need to limit this to specific machines,
+ *       or examine the contents of the sequences to
+ *       avoid false positives?
+ */
+static void icl_fixup_mipi_sequences(struct drm_i915_private *i915,
+                                    struct intel_panel *panel)
+{
+       if (!panel->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP] &&
+           panel->vbt.dsi.sequence[MIPI_SEQ_DISPLAY_ON]) {
+               drm_dbg_kms(&i915->drm, "Broken VBT: Swapping INIT_OTP and DISPLAY_ON sequences\n");
+
+               swap(panel->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP],
+                    panel->vbt.dsi.sequence[MIPI_SEQ_DISPLAY_ON]);
+       }
+}
+
+static void fixup_mipi_sequences(struct drm_i915_private *i915,
+                                struct intel_panel *panel)
+{
+       if (DISPLAY_VER(i915) >= 11)
+               icl_fixup_mipi_sequences(i915, panel);
+       else if (IS_VALLEYVIEW(i915))
+               vlv_fixup_mipi_sequences(i915, panel);
+}
+
 static void
 parse_mipi_sequence(struct drm_i915_private *i915,
                    struct intel_panel *panel)