aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2016-06-03 05:17:43 -0400
committerJani Nikula <jani.nikula@intel.com>2016-06-10 03:40:54 -0400
commita5aac5ab876ad95b7f5e8d862afb07248ee9cae2 (patch)
tree928d1dff1a59bf4eaf6d43f057a49e1d0cd5002b
parentfff7660d1e4f47dc6372ce2bd31a7b8cba0da340 (diff)
drm/i915: Check VBT for port presence in addition to the strap on VLV/CHV
Apparently some CHV boards failed to hook up the port presence straps for HDMI ports as well (earlier we assumed this problem only affected eDP ports). So let's check the VBT in addition to the strap, and if either one claims that the port is present go ahead and register the relevant connector. While at it, change port D to register DP before HDMI as we do for ports B and C since commit 457c52d87e5d ("drm/i915: Only ignore eDP ports that are connected") Also print a debug message when we register a HDMI connector to aid in diagnosing missing/incorrect ports. We already had such a print for DP/eDP. v2: Improve the comment in the code a bit, note the port D change in the commit message Cc: Radoslav Duda <radosd@radosd.com> Tested-by: Radoslav Duda <radosd@radosd.com> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96321 Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1464945463-14364-1-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> (cherry picked from commit 22f35042593c2b369861f0b9740efb8065a42db0) Signed-off-by: Jani Nikula <jani.nikula@intel.com>
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h1
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c39
-rw-r--r--drivers/gpu/drm/i915/intel_display.c30
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c3
4 files changed, 64 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 5faacc6e548d..7c334e902266 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3481,6 +3481,7 @@ int intel_bios_init(struct drm_i915_private *dev_priv);
3481bool intel_bios_is_valid_vbt(const void *buf, size_t size); 3481bool intel_bios_is_valid_vbt(const void *buf, size_t size);
3482bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv); 3482bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv);
3483bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin); 3483bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin);
3484bool intel_bios_is_port_present(struct drm_i915_private *dev_priv, enum port port);
3484bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port); 3485bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port);
3485bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *dev_priv, enum port port); 3486bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *dev_priv, enum port port);
3486bool intel_bios_is_dsi_present(struct drm_i915_private *dev_priv, enum port *port); 3487bool intel_bios_is_dsi_present(struct drm_i915_private *dev_priv, enum port *port);
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 051b0db07efb..519818596e2a 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -1546,6 +1546,45 @@ bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin)
1546} 1546}
1547 1547
1548/** 1548/**
1549 * intel_bios_is_port_present - is the specified digital port present
1550 * @dev_priv: i915 device instance
1551 * @port: port to check
1552 *
1553 * Return true if the device in %port is present.
1554 */
1555bool intel_bios_is_port_present(struct drm_i915_private *dev_priv, enum port port)
1556{
1557 static const struct {
1558 u16 dp, hdmi;
1559 } port_mapping[] = {
1560 [PORT_B] = { DVO_PORT_DPB, DVO_PORT_HDMIB, },
1561 [PORT_C] = { DVO_PORT_DPC, DVO_PORT_HDMIC, },
1562 [PORT_D] = { DVO_PORT_DPD, DVO_PORT_HDMID, },
1563 [PORT_E] = { DVO_PORT_DPE, DVO_PORT_HDMIE, },
1564 };
1565 int i;
1566
1567 /* FIXME maybe deal with port A as well? */
1568 if (WARN_ON(port == PORT_A) || port >= ARRAY_SIZE(port_mapping))
1569 return false;
1570
1571 if (!dev_priv->vbt.child_dev_num)
1572 return false;
1573
1574 for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
1575 const union child_device_config *p_child =
1576 &dev_priv->vbt.child_dev[i];
1577 if ((p_child->common.dvo_port == port_mapping[port].dp ||
1578 p_child->common.dvo_port == port_mapping[port].hdmi) &&
1579 (p_child->common.device_type & (DEVICE_TYPE_TMDS_DVI_SIGNALING |
1580 DEVICE_TYPE_DISPLAYPORT_OUTPUT)))
1581 return true;
1582 }
1583
1584 return false;
1585}
1586
1587/**
1549 * intel_bios_is_port_edp - is the device in given port eDP 1588 * intel_bios_is_port_edp - is the device in given port eDP
1550 * @dev_priv: i915 device instance 1589 * @dev_priv: i915 device instance
1551 * @port: port to check 1590 * @port: port to check
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 996e0c37293c..718f56525b96 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14554,7 +14554,7 @@ static void intel_setup_outputs(struct drm_device *dev)
14554 if (I915_READ(PCH_DP_D) & DP_DETECTED) 14554 if (I915_READ(PCH_DP_D) & DP_DETECTED)
14555 intel_dp_init(dev, PCH_DP_D, PORT_D); 14555 intel_dp_init(dev, PCH_DP_D, PORT_D);
14556 } else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) { 14556 } else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
14557 bool has_edp; 14557 bool has_edp, has_port;
14558 14558
14559 /* 14559 /*
14560 * The DP_DETECTED bit is the latched state of the DDC 14560 * The DP_DETECTED bit is the latched state of the DDC
@@ -14564,25 +14564,37 @@ static void intel_setup_outputs(struct drm_device *dev)
14564 * Thus we can't rely on the DP_DETECTED bit alone to detect 14564 * Thus we can't rely on the DP_DETECTED bit alone to detect
14565 * eDP ports. Consult the VBT as well as DP_DETECTED to 14565 * eDP ports. Consult the VBT as well as DP_DETECTED to
14566 * detect eDP ports. 14566 * detect eDP ports.
14567 *
14568 * Sadly the straps seem to be missing sometimes even for HDMI
14569 * ports (eg. on Voyo V3 - CHT x7-Z8700), so check both strap
14570 * and VBT for the presence of the port. Additionally we can't
14571 * trust the port type the VBT declares as we've seen at least
14572 * HDMI ports that the VBT claim are DP or eDP.
14567 */ 14573 */
14568 has_edp = intel_dp_is_edp(dev, PORT_B); 14574 has_edp = intel_dp_is_edp(dev, PORT_B);
14569 if (I915_READ(VLV_DP_B) & DP_DETECTED || has_edp) 14575 has_port = intel_bios_is_port_present(dev_priv, PORT_B);
14576 if (I915_READ(VLV_DP_B) & DP_DETECTED || has_port)
14570 has_edp &= intel_dp_init(dev, VLV_DP_B, PORT_B); 14577 has_edp &= intel_dp_init(dev, VLV_DP_B, PORT_B);
14571 if (I915_READ(VLV_HDMIB) & SDVO_DETECTED && !has_edp) 14578 if ((I915_READ(VLV_HDMIB) & SDVO_DETECTED || has_port) && !has_edp)
14572 intel_hdmi_init(dev, VLV_HDMIB, PORT_B); 14579 intel_hdmi_init(dev, VLV_HDMIB, PORT_B);
14573 14580
14574 has_edp = intel_dp_is_edp(dev, PORT_C); 14581 has_edp = intel_dp_is_edp(dev, PORT_C);
14575 if (I915_READ(VLV_DP_C) & DP_DETECTED || has_edp) 14582 has_port = intel_bios_is_port_present(dev_priv, PORT_C);
14583 if (I915_READ(VLV_DP_C) & DP_DETECTED || has_port)
14576 has_edp &= intel_dp_init(dev, VLV_DP_C, PORT_C); 14584 has_edp &= intel_dp_init(dev, VLV_DP_C, PORT_C);
14577 if (I915_READ(VLV_HDMIC) & SDVO_DETECTED && !has_edp) 14585 if ((I915_READ(VLV_HDMIC) & SDVO_DETECTED || has_port) && !has_edp)
14578 intel_hdmi_init(dev, VLV_HDMIC, PORT_C); 14586 intel_hdmi_init(dev, VLV_HDMIC, PORT_C);
14579 14587
14580 if (IS_CHERRYVIEW(dev)) { 14588 if (IS_CHERRYVIEW(dev)) {
14581 /* eDP not supported on port D, so don't check VBT */ 14589 /*
14582 if (I915_READ(CHV_HDMID) & SDVO_DETECTED) 14590 * eDP not supported on port D,
14583 intel_hdmi_init(dev, CHV_HDMID, PORT_D); 14591 * so no need to worry about it
14584 if (I915_READ(CHV_DP_D) & DP_DETECTED) 14592 */
14593 has_port = intel_bios_is_port_present(dev_priv, PORT_D);
14594 if (I915_READ(CHV_DP_D) & DP_DETECTED || has_port)
14585 intel_dp_init(dev, CHV_DP_D, PORT_D); 14595 intel_dp_init(dev, CHV_DP_D, PORT_D);
14596 if (I915_READ(CHV_HDMID) & SDVO_DETECTED || has_port)
14597 intel_hdmi_init(dev, CHV_HDMID, PORT_D);
14586 } 14598 }
14587 14599
14588 intel_dsi_init(dev); 14600 intel_dsi_init(dev);
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 2c3bd9c2573e..a8844702d11b 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -2142,6 +2142,9 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
2142 enum port port = intel_dig_port->port; 2142 enum port port = intel_dig_port->port;
2143 uint8_t alternate_ddc_pin; 2143 uint8_t alternate_ddc_pin;
2144 2144
2145 DRM_DEBUG_KMS("Adding HDMI connector on port %c\n",
2146 port_name(port));
2147
2145 if (WARN(intel_dig_port->max_lanes < 4, 2148 if (WARN(intel_dig_port->max_lanes < 4,
2146 "Not enough lanes (%d) for HDMI on port %c\n", 2149 "Not enough lanes (%d) for HDMI on port %c\n",
2147 intel_dig_port->max_lanes, port_name(port))) 2150 intel_dig_port->max_lanes, port_name(port)))