aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-08-04 02:15:09 -0400
committerDave Airlie <airlied@redhat.com>2014-08-04 02:31:29 -0400
commitf68d697eaf3278200a7fc3c8b1d95d72837b84d8 (patch)
tree3a792d4a40cd3e5c784fca55a66bff31065dca04
parent1fae6dfeb63cddea9b9cd19f236c40f73c72f61d (diff)
drm/i915: only hook up hpd pulse for DP outputs
On HSW+, the digital encoders are shared between HDMI and DP outputs, with one encoder masquerading as both. The VBT should tell us if we need to have DP or HDMI support on a particular port, but if we don't have DP support and we enable the DP hpd pulse handler then we cause an oops. Don't hook up the DP hpd handling if we don't have a DP port. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=81856 Reported-by: Intel QA Team. Signed-off-by: Dave Airlie <airlied@redhat.com> # v1 [ickle: Fix the error handling after a malloc failure] Reviewed-by: Dave Airlie <airlied@redhat.com> Cc: Paulo Zanoni <przanoni@gmail.com> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 9b1542f1cf01..2d73430a0d27 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1515,15 +1515,13 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
1515 struct intel_digital_port *intel_dig_port; 1515 struct intel_digital_port *intel_dig_port;
1516 struct intel_encoder *intel_encoder; 1516 struct intel_encoder *intel_encoder;
1517 struct drm_encoder *encoder; 1517 struct drm_encoder *encoder;
1518 struct intel_connector *hdmi_connector = NULL;
1519 struct intel_connector *dp_connector = NULL;
1520 bool init_hdmi, init_dp; 1518 bool init_hdmi, init_dp;
1521 1519
1522 init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi || 1520 init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
1523 dev_priv->vbt.ddi_port_info[port].supports_hdmi); 1521 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
1524 init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp; 1522 init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
1525 if (!init_dp && !init_hdmi) { 1523 if (!init_dp && !init_hdmi) {
1526 DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible\n", 1524 DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, assuming it is\n",
1527 port_name(port)); 1525 port_name(port));
1528 init_hdmi = true; 1526 init_hdmi = true;
1529 init_dp = true; 1527 init_dp = true;
@@ -1553,23 +1551,28 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
1553 DDI_A_4_LANES); 1551 DDI_A_4_LANES);
1554 1552
1555 intel_encoder->type = INTEL_OUTPUT_UNKNOWN; 1553 intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
1556 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); 1554 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
1557 intel_encoder->cloneable = 0; 1555 intel_encoder->cloneable = 0;
1558 intel_encoder->hot_plug = intel_ddi_hot_plug; 1556 intel_encoder->hot_plug = intel_ddi_hot_plug;
1559 1557
1560 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse; 1558 if (init_dp) {
1561 dev_priv->hpd_irq_port[port] = intel_dig_port; 1559 if (!intel_ddi_init_dp_connector(intel_dig_port))
1560 goto err;
1562 1561
1563 if (init_dp) 1562 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
1564 dp_connector = intel_ddi_init_dp_connector(intel_dig_port); 1563 dev_priv->hpd_irq_port[port] = intel_dig_port;
1564 }
1565 1565
1566 /* In theory we don't need the encoder->type check, but leave it just in 1566 /* In theory we don't need the encoder->type check, but leave it just in
1567 * case we have some really bad VBTs... */ 1567 * case we have some really bad VBTs... */
1568 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) 1568 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
1569 hdmi_connector = intel_ddi_init_hdmi_connector(intel_dig_port); 1569 if (!intel_ddi_init_hdmi_connector(intel_dig_port))
1570 1570 goto err;
1571 if (!dp_connector && !hdmi_connector) {
1572 drm_encoder_cleanup(encoder);
1573 kfree(intel_dig_port);
1574 } 1571 }
1572
1573 return;
1574
1575err:
1576 drm_encoder_cleanup(encoder);
1577 kfree(intel_dig_port);
1575} 1578}