Skip to content

Commit

Permalink
drm/i915: Only ignore eDP ports that are connected
Browse files Browse the repository at this point in the history
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: d2182a6 (drm/i915: Don't register HDMI connectors for eDP ports on VLV/CHV)
References: https://bugs.freedesktop.org/show_bug.cgi?id=96288
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Tested-by: Phidias 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: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1464766070-31623-1-git-send-email-chris@chris-wilson.co.uk
  • Loading branch information
Chris Wilson committed Jun 1, 2016
1 parent 1800ad2 commit 457c52d
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 18 deletions.
20 changes: 10 additions & 10 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -14702,6 +14702,8 @@ static void intel_setup_outputs(struct drm_device *dev)
if (I915_READ(PCH_DP_D) & DP_DETECTED)
intel_dp_init(dev, PCH_DP_D, PORT_D);
} else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
bool has_edp;

/*
* The DP_DETECTED bit is the latched state of the DDC
* SDA pin at boot. However since eDP doesn't require DDC
Expand All @@ -14711,19 +14713,17 @@ static void intel_setup_outputs(struct drm_device *dev)
* eDP ports. Consult the VBT as well as DP_DETECTED to
* detect eDP ports.
*/
if (I915_READ(VLV_HDMIB) & SDVO_DETECTED &&
!intel_dp_is_edp(dev, PORT_B))
has_edp = 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);
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 &&
!intel_dp_is_edp(dev, PORT_C))
has_edp = 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);
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)) {
/* eDP not supported on port D, so don't check VBT */
Expand Down
13 changes: 6 additions & 7 deletions drivers/gpu/drm/i915/intel_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -5568,9 +5568,9 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
return false;
}

void
intel_dp_init(struct drm_device *dev,
i915_reg_t output_reg, enum port port)
bool intel_dp_init(struct drm_device *dev,
i915_reg_t output_reg,
enum port port)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_digital_port *intel_dig_port;
Expand All @@ -5580,7 +5580,7 @@ intel_dp_init(struct drm_device *dev,

intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
if (!intel_dig_port)
return;
return false;

intel_connector = intel_connector_alloc();
if (!intel_connector)
Expand Down Expand Up @@ -5637,16 +5637,15 @@ intel_dp_init(struct drm_device *dev,
if (!intel_dp_init_connector(intel_dig_port, intel_connector))
goto err_init_connector;

return;
return true;

err_init_connector:
drm_encoder_cleanup(encoder);
err_encoder_init:
kfree(intel_connector);
err_connector_alloc:
kfree(intel_dig_port);

return;
return false;
}

void intel_dp_mst_suspend(struct drm_device *dev)
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/intel_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1312,7 +1312,7 @@ void intel_csr_ucode_suspend(struct drm_i915_private *);
void intel_csr_ucode_resume(struct drm_i915_private *);

/* intel_dp.c */
void intel_dp_init(struct drm_device *dev, i915_reg_t output_reg, enum port port);
bool intel_dp_init(struct drm_device *dev, i915_reg_t output_reg, enum port port);
bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
struct intel_connector *intel_connector);
void intel_dp_set_link_params(struct intel_dp *intel_dp,
Expand Down

0 comments on commit 457c52d

Please sign in to comment.