[PATCH 25/29] drm/i915: detect digital outputs on Haswell

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Digital port detection on Haswell is indicated by the presence of a bit in
DDI_BUF_CTL for port A, and by a different register for ports B, C and D.
So we check for those bits during the initialization time and let the hdmi
function know about those.

Note that this bit does not indicates whether the output is DP or HDMI.
However, the DDI buffers can be programmed in a way that is shared between
DP/HDMI and FDI/HDMI except for PORT E.

So for now, we detect those digital outputs as being HDMI, but proper DP
support is still pending.

Note that DDI A can only drive eDP, so we do not handle it here for hdmi
initialization.

Signed-off-by: Eugeni Dodonov <eugeni.dodonov at intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |   51 +++++++++++++++++++++++-----------
 1 file changed, 35 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index bdc22f5..1524966 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8743,26 +8743,45 @@ static void intel_setup_outputs(struct drm_device *dev)
 	if (HAS_PCH_SPLIT(dev)) {
 		int found;
 
-		if (I915_READ(HDMIB) & PORT_DETECTED) {
-			/* PCH SDVOB multiplex with HDMIB */
-			found = intel_sdvo_init(dev, PCH_SDVOB, true);
-			if (!found)
-				intel_hdmi_init(dev, HDMIB);
-			if (!found && (I915_READ(PCH_DP_B) & DP_DETECTED))
-				intel_dp_init(dev, PCH_DP_B);
-		}
+		if (IS_HASWELL(dev)) {
+			/* Haswell uses DDI functions to detect digital outputs */
+			found = I915_READ(DDI_BUF_CTL_A) & DDI_INIT_DISPLAY_DETECTED;
+			/* DDI A only supports eDP */
+			if (found)
+				DRM_INFO("Found digital output on DDI port A\n");
+
+			/* DDI B, C and D detection is indicated by the SFUSE_STRAP
+			 * register */
+			found = I915_READ(SFUSE_STRAP);
+
+			if (found & SFUSE_STRAP_DDIB_DETECTED)
+				intel_hdmi_init(dev, DDI_BUF_CTL(PORT_B));
+			if (found & SFUSE_STRAP_DDIC_DETECTED)
+				intel_hdmi_init(dev, DDI_BUF_CTL(PORT_C));
+			if (found & SFUSE_STRAP_DDID_DETECTED)
+				intel_hdmi_init(dev, DDI_BUF_CTL(PORT_D));
+		} else {
+			if (I915_READ(HDMIB) & PORT_DETECTED) {
+				/* PCH SDVOB multiplex with HDMIB */
+				found = intel_sdvo_init(dev, PCH_SDVOB, true);
+				if (!found)
+					intel_hdmi_init(dev, HDMIB);
+				if (!found && (I915_READ(PCH_DP_B) & DP_DETECTED))
+					intel_dp_init(dev, PCH_DP_B);
+			}
 
-		if (I915_READ(HDMIC) & PORT_DETECTED)
-			intel_hdmi_init(dev, HDMIC);
+			if (I915_READ(HDMIC) & PORT_DETECTED)
+				intel_hdmi_init(dev, HDMIC);
 
-		if (I915_READ(HDMID) & PORT_DETECTED)
-			intel_hdmi_init(dev, HDMID);
+			if (I915_READ(HDMID) & PORT_DETECTED)
+				intel_hdmi_init(dev, HDMID);
 
-		if (I915_READ(PCH_DP_C) & DP_DETECTED)
-			intel_dp_init(dev, PCH_DP_C);
+			if (I915_READ(PCH_DP_C) & DP_DETECTED)
+				intel_dp_init(dev, PCH_DP_C);
 
-		if (!dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED))
-			intel_dp_init(dev, PCH_DP_D);
+			if (!dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED))
+				intel_dp_init(dev, PCH_DP_D);
+		}
 
 	} else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) {
 		bool found = false;
-- 
1.7.10



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux