Commit af115b1a authored by Chris Wilson's avatar Chris Wilson Committed by Greg Kroah-Hartman

drm/i915: Only ignore eDP ports that are connected

[ Upstream commit 457c52d8 ]

If the VBT says that a certain port should be eDP (and hence fused off
from HDMI), but in reality it isn't, we need to try and acquire the HDMI
connection instead. So only trust the VBT edp setting if we can connect
to an eDP device on that port.

Fixes: d2182a66 (drm/i915: Don't register HDMI connectors for eDP ports on VLV/CHV)
References: https://bugs.freedesktop.org/show_bug.cgi?id=96288Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Tested-by: default avatarPhidias Chiang <phidias.chiang@canonical.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1464766070-31623-1-git-send-email-chris@chris-wilson.co.ukSigned-off-by: default avatarSasha Levin <alexander.levin@verizon.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 822480f8
...@@ -14160,6 +14160,8 @@ static void intel_setup_outputs(struct drm_device *dev) ...@@ -14160,6 +14160,8 @@ static void intel_setup_outputs(struct drm_device *dev)
if (I915_READ(PCH_DP_D) & DP_DETECTED) if (I915_READ(PCH_DP_D) & DP_DETECTED)
intel_dp_init(dev, PCH_DP_D, PORT_D); intel_dp_init(dev, PCH_DP_D, PORT_D);
} else if (IS_VALLEYVIEW(dev)) { } else if (IS_VALLEYVIEW(dev)) {
bool has_edp;
/* /*
* The DP_DETECTED bit is the latched state of the DDC * The DP_DETECTED bit is the latched state of the DDC
* SDA pin at boot. However since eDP doesn't require DDC * SDA pin at boot. However since eDP doesn't require DDC
...@@ -14169,19 +14171,17 @@ static void intel_setup_outputs(struct drm_device *dev) ...@@ -14169,19 +14171,17 @@ static void intel_setup_outputs(struct drm_device *dev)
* eDP ports. Consult the VBT as well as DP_DETECTED to * eDP ports. Consult the VBT as well as DP_DETECTED to
* detect eDP ports. * detect eDP ports.
*/ */
if (I915_READ(VLV_HDMIB) & SDVO_DETECTED && has_edp = intel_dp_is_edp(dev, PORT_B);
!intel_dp_is_edp(dev, PORT_B)) if (I915_READ(VLV_DP_B) & DP_DETECTED || has_edp)
has_edp &= intel_dp_init(dev, VLV_DP_B, PORT_B);
if (I915_READ(VLV_HDMIB) & SDVO_DETECTED && !has_edp)
intel_hdmi_init(dev, VLV_HDMIB, PORT_B); intel_hdmi_init(dev, VLV_HDMIB, PORT_B);
if (I915_READ(VLV_DP_B) & DP_DETECTED ||
intel_dp_is_edp(dev, PORT_B))
intel_dp_init(dev, VLV_DP_B, PORT_B);
if (I915_READ(VLV_HDMIC) & SDVO_DETECTED && has_edp = intel_dp_is_edp(dev, PORT_C);
!intel_dp_is_edp(dev, PORT_C)) if (I915_READ(VLV_DP_C) & DP_DETECTED || has_edp)
has_edp &= intel_dp_init(dev, VLV_DP_C, PORT_C);
if (I915_READ(VLV_HDMIC) & SDVO_DETECTED && !has_edp)
intel_hdmi_init(dev, VLV_HDMIC, PORT_C); intel_hdmi_init(dev, VLV_HDMIC, PORT_C);
if (I915_READ(VLV_DP_C) & DP_DETECTED ||
intel_dp_is_edp(dev, PORT_C))
intel_dp_init(dev, VLV_DP_C, PORT_C);
if (IS_CHERRYVIEW(dev)) { if (IS_CHERRYVIEW(dev)) {
/* eDP not supported on port D, so don't check VBT */ /* eDP not supported on port D, so don't check VBT */
......
...@@ -6113,8 +6113,9 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, ...@@ -6113,8 +6113,9 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
return true; return true;
} }
void bool intel_dp_init(struct drm_device *dev,
intel_dp_init(struct drm_device *dev, int output_reg, enum port port) int output_reg,
enum port port)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_digital_port *intel_dig_port; struct intel_digital_port *intel_dig_port;
...@@ -6124,7 +6125,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) ...@@ -6124,7 +6125,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL); intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
if (!intel_dig_port) if (!intel_dig_port)
return; return false;
intel_connector = intel_connector_alloc(); intel_connector = intel_connector_alloc();
if (!intel_connector) if (!intel_connector)
...@@ -6179,15 +6180,14 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) ...@@ -6179,15 +6180,14 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
if (!intel_dp_init_connector(intel_dig_port, intel_connector)) if (!intel_dp_init_connector(intel_dig_port, intel_connector))
goto err_init_connector; goto err_init_connector;
return; return true;
err_init_connector: err_init_connector:
drm_encoder_cleanup(encoder); drm_encoder_cleanup(encoder);
kfree(intel_connector); kfree(intel_connector);
err_connector_alloc: err_connector_alloc:
kfree(intel_dig_port); kfree(intel_dig_port);
return false;
return;
} }
void intel_dp_mst_suspend(struct drm_device *dev) void intel_dp_mst_suspend(struct drm_device *dev)
......
...@@ -1195,7 +1195,7 @@ void intel_csr_ucode_fini(struct drm_device *dev); ...@@ -1195,7 +1195,7 @@ void intel_csr_ucode_fini(struct drm_device *dev);
void assert_csr_loaded(struct drm_i915_private *dev_priv); void assert_csr_loaded(struct drm_i915_private *dev_priv);
/* intel_dp.c */ /* intel_dp.c */
void intel_dp_init(struct drm_device *dev, int output_reg, enum port port); bool intel_dp_init(struct drm_device *dev, int output_reg, enum port port);
bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port, bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
struct intel_connector *intel_connector); struct intel_connector *intel_connector);
void intel_dp_set_link_params(struct intel_dp *intel_dp, void intel_dp_set_link_params(struct intel_dp *intel_dp,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment