public inbox for intel-gfx@lists.freedesktop.org
 help / color / mirror / Atom feed
From: Matt Roper <matthew.d.roper@intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH v3] drm/i915/ehl: Allow combo PHY A to drive a third external display
Date: Tue, 18 Jun 2019 10:51:31 -0700	[thread overview]
Message-ID: <20190618175131.9139-1-matthew.d.roper@intel.com> (raw)
In-Reply-To: <20190618173917.GU5942@intel.com>

EHL has a mux on combo PHY A that allows it to be driven either by an
internal display (DDI-A or DSI DPHY) or by an external display (DDI-D).
This is a motherboard design decision that can not be changed on the
fly.  Unfortunately there are no strap registers that allow us to detect
the board configuration directly, so let's use the VBT to try to figure
it out and program the mux accordingly.

For now if we run across a broken VBT that tries to claim that PHY A
is attached to both internal and external displays at the same time,
we'll resolve the conflict in favor of the internal display.  To help
debug these kind of bad VBT's, let's also add a quick DRM_DEBUG message
during child device parsing so that it's easier to understand these
cases if they show up in bug reports.

v2:
 - Confirmed that VBT's dvo port refers to the DDI and not the PHY.
   Thus we can check more explicitly for (ddi_d && !(ddi_a || dsi)).  If
   a bad VBT contradicts itself, let internal display win.  (Ville)

v3:
 - Switch condition from !IS_ICELAKE to IS_ELKHARTLAKE.  Although the
   convention is usually to assume that future platforms will inherit
   all current platform behavior, this feels more like a one-platform
   quirk.  (Ville)
 - Update commit message to describe what we do if/when we encounter
   broken VBT's, and note that the new debug print during child device
   parsing is intentional.

Cc: Clint Taylor <Clinton.A.Taylor@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_bios.c     |  3 ++
 .../gpu/drm/i915/display/intel_combo_phy.c    | 36 +++++++++++++++++++
 drivers/gpu/drm/i915/i915_reg.h               |  1 +
 3 files changed, 40 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
index c4710889cb32..0c9808132d67 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -1668,6 +1668,9 @@ parse_general_definitions(struct drm_i915_private *dev_priv,
 		if (!child->device_type)
 			continue;
 
+		DRM_DEBUG_KMS("Found VBT child device with type 0x%x\n",
+			      child->device_type);
+
 		/*
 		 * Copy as much as we know (sizeof) and is available
 		 * (child_dev_size) of the child device. Accessing the data must
diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy.c b/drivers/gpu/drm/i915/display/intel_combo_phy.c
index 841708da5a56..075bab2500eb 100644
--- a/drivers/gpu/drm/i915/display/intel_combo_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_combo_phy.c
@@ -260,6 +260,32 @@ void intel_combo_phy_power_up_lanes(struct drm_i915_private *dev_priv,
 	I915_WRITE(ICL_PORT_CL_DW10(port), val);
 }
 
+static u32 ehl_combo_phy_a_mux(struct drm_i915_private *i915, u32 val)
+{
+	bool ddi_a_present = i915->vbt.ddi_port_info[PORT_A].child != NULL;
+	bool ddi_d_present = i915->vbt.ddi_port_info[PORT_D].child != NULL;
+	bool dsi_present = intel_bios_is_dsi_present(i915, NULL);
+
+	/*
+	 * VBT's 'dvo port' field for child devices references the DDI, not
+	 * the PHY.  So if combo PHY A is wired up to drive an external
+	 * display, we should see a child device present on PORT_D and
+	 * nothing on PORT_A and no DSI.
+	 */
+	if (ddi_d_present && !ddi_a_present && !dsi_present)
+		return val | ICL_PHY_MISC_MUX_DDID;
+
+	/*
+	 * If we encounter a VBT that claims to have an external display on
+	 * DDI-D _and_ an internal display on DDI-A/DSI leave an error message
+	 * in the log and let the internal display win.
+	 */
+	if (ddi_d_present)
+		DRM_ERROR("VBT claims to have both internal and external displays on PHY A.  Configuring for internal.\n");
+
+	return val & ~ICL_PHY_MISC_MUX_DDID;
+}
+
 static void icl_combo_phys_init(struct drm_i915_private *dev_priv)
 {
 	enum port port;
@@ -273,7 +299,17 @@ static void icl_combo_phys_init(struct drm_i915_private *dev_priv)
 			continue;
 		}
 
+		/*
+		 * EHL's combo PHY A can be hooked up to either an external
+		 * display (via DDI-D) or an internal display (via DDI-A or
+		 * the DSI DPHY).  This is a motherboard design decision that
+		 * can't be changed on the fly, so initialize the PHY's mux
+		 * based on whether our VBT indicates the presence of any
+		 * "internal" child devices.
+		 */
 		val = I915_READ(ICL_PHY_MISC(port));
+		if (IS_ELKHARTLAKE(dev_priv) && port == PORT_A)
+			val = ehl_combo_phy_a_mux(dev_priv, val);
 		val &= ~ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN;
 		I915_WRITE(ICL_PHY_MISC(port), val);
 
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index d6483b5dc8e5..d98142940c38 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -11145,6 +11145,7 @@ enum skl_power_gate {
 #define _ICL_PHY_MISC_B		0x64C04
 #define ICL_PHY_MISC(port)	_MMIO_PORT(port, _ICL_PHY_MISC_A, \
 						 _ICL_PHY_MISC_B)
+#define  ICL_PHY_MISC_MUX_DDID			(1 << 28)
 #define  ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN	(1 << 23)
 
 /* Icelake Display Stream Compression Registers */
-- 
2.17.2

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

  reply	other threads:[~2019-06-18 17:51 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-14 18:07 [PATCH] drm/i915/ehl: Allow combo PHY A to drive a third external display Matt Roper
2019-06-14 18:32 ` Ville Syrjälä
2019-06-17 23:48   ` [PATCH v2] " Matt Roper
2019-06-18 16:08     ` Ville Syrjälä
2019-06-18 17:30       ` Matt Roper
2019-06-18 17:39         ` Ville Syrjälä
2019-06-18 17:51           ` Matt Roper [this message]
2019-06-15  5:25 ` ✓ Fi.CI.BAT: success for " Patchwork
2019-06-17 10:26 ` ✓ Fi.CI.IGT: " Patchwork
2019-06-18  0:10 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915/ehl: Allow combo PHY A to drive a third external display (rev2) Patchwork
2019-06-18  0:31 ` ✓ Fi.CI.BAT: success " Patchwork
2019-06-18 14:32 ` ✗ Fi.CI.IGT: failure " Patchwork
2019-06-18 18:33 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915/ehl: Allow combo PHY A to drive a third external display (rev3) Patchwork
2019-06-18 18:49 ` ✓ Fi.CI.BAT: success " Patchwork
2019-06-19 13:28 ` ✗ Fi.CI.IGT: failure " Patchwork
2019-06-19 18:31   ` Matt Roper
2019-06-19 19:04     ` Saarinen, Jani

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190618175131.9139-1-matthew.d.roper@intel.com \
    --to=matthew.d.roper@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox