Skip to contentSkip to conversation

drm/i915: rework digital port IRQ handling

PATCH New Dave Airlie 1 participant 1 message Jun 4, 2014

Subsystems (2)
lore
Share & tools
lore

Dave Airlie

author maintainer
#0 lore raw

PATCH 1/1 drm/i915: rework digital port IRQ handling

From: Dave Airlie <[email protected]>

The digital ports from Ironlake and up have the ability to distinguish between long and short HPD pulses. Displayport 1.1 only uses the short form to request link retraining usually, so we haven't really needed support for it until now.

However with DP 1.2 MST we need to handle the short irqs on their own outside the modesetting locking the long hpd's involve. This patch adds the framework to distinguish between short/long to the current code base, to lay the basis for future DP 1.2 MST work.

This should mean we get better bisectability in case of regression due to the new irq handling.

---
 drivers/gpu/drm/i915/i915_drv.h  |   5 ++
 drivers/gpu/drm/i915/i915_irq.c  | 138 ++++++++++++++++++++++++++++++++++++---
 drivers/gpu/drm/i915/intel_ddi.c |   3 +
 drivers/gpu/drm/i915/intel_dp.c  |  22 +++++++
 drivers/gpu/drm/i915/intel_drv.h |   2 +
 5 files changed, 162 insertions(+), 8 deletions(-)
drivers/gpu/drm/i915/i915_drv.h +5 -0
index 8f68678..5fd5bf3 100644
@@ -1551,6 +1551,11 @@ struct drm_i915_private {
 
 	struct i915_runtime_pm pm;
 
+	struct intel_digital_port *hpd_irq_port[I915_MAX_PORTS];
+	u32 long_hpd_port_mask;
+	u32 short_hpd_port_mask;
+	struct work_struct dig_port_work;
+
 	/* Old dri1 support infrastructure, beware the dragons ya fools entering
 	 * here! */
 	struct i915_dri1_state dri1;
drivers/gpu/drm/i915/i915_irq.c +130 -8

206 lines not on this page · raw message

drivers/gpu/drm/i915/intel_ddi.c +3 -0
index b17b9c7..a80cb3e 100644
@@ -1705,6 +1705,9 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
 	intel_encoder->cloneable = 0;
 	intel_encoder->hot_plug = intel_ddi_hot_plug;
 
+	intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
+	dev_priv->hpd_irq_port[port] = intel_dig_port;
+
 	if (init_dp)
 		dp_connector = intel_ddi_init_dp_connector(intel_dig_port);
 
drivers/gpu/drm/i915/intel_dp.c +22 -0
index c4d8839..cacb995 100644
@@ -3699,6 +3699,22 @@ intel_dp_hot_plug(struct intel_encoder *intel_encoder)
 	intel_dp_check_link_status(intel_dp);
 }
 
+bool
+intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
+{
+	struct intel_dp *intel_dp = &intel_dig_port->dp;
+
+	if (long_hpd)
+		return true;
+
+	/*
+	 * we'll check the link status via the normal hot plug path later -
+	 * but for short hpds we should check it now
+	 */
+	intel_dp_check_link_status(intel_dp);
+	return false;
+}
+
 /* Return which DP Port should be selected for Transcoder DP control */
 int
 intel_trans_dp_port_sel(struct drm_crtc *crtc)
@@ -4273,6 +4289,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 void
 intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
 {
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_digital_port *intel_dig_port;
 	struct intel_encoder *intel_encoder;
 	struct drm_encoder *encoder;
@@ -4328,6 +4345,11 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
 	intel_encoder->cloneable = 0;
 	intel_encoder->hot_plug = intel_dp_hot_plug;
 
+	if (HAS_PCH_SPLIT(dev)) {
+		intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
+		dev_priv->hpd_irq_port[port] = intel_dig_port;
+	}
+
 	if (!intel_dp_init_connector(intel_dig_port, intel_connector)) {
 		drm_encoder_cleanup(encoder);
 		kfree(intel_dig_port);
drivers/gpu/drm/i915/intel_drv.h +2 -0
index f1d5897..9666ec3 100644
@@ -563,6 +563,7 @@ struct intel_digital_port {
 	u32 saved_port_bits;
 	struct intel_dp dp;
 	struct intel_hdmi hdmi;
+	bool (*hpd_pulse)(struct intel_digital_port *, bool);
 };
 
 static inline int
@@ -830,6 +831,7 @@ void intel_edp_psr_enable(struct intel_dp *intel_dp);
 void intel_edp_psr_disable(struct intel_dp *intel_dp);
 void intel_edp_psr_update(struct drm_device *dev);
 void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate);
+bool intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd);
 
 /* intel_dsi.c */
 bool intel_dsi_init(struct drm_device *dev);
Signature · 1 line
1.9.3