diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_bios.c | 39 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 30 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_hdmi.c | 3 |
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); | |||
3481 | bool intel_bios_is_valid_vbt(const void *buf, size_t size); | 3481 | bool intel_bios_is_valid_vbt(const void *buf, size_t size); |
3482 | bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv); | 3482 | bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv); |
3483 | bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin); | 3483 | bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin); |
3484 | bool intel_bios_is_port_present(struct drm_i915_private *dev_priv, enum port port); | ||
3484 | bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port); | 3485 | bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port); |
3485 | bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *dev_priv, enum port port); | 3486 | bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *dev_priv, enum port port); |
3486 | bool intel_bios_is_dsi_present(struct drm_i915_private *dev_priv, enum port *port); | 3487 | bool 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 | */ | ||
1555 | bool 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))) |