All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] HDMI optimization series
@ 2015-09-04 13:26 Sonika Jindal
  2015-09-04 13:26 ` [PATCH 1/6] drm/i915: add attached connector to hdmi container Sonika Jindal
                   ` (5 more replies)
  0 siblings, 6 replies; 77+ messages in thread
From: Sonika Jindal @ 2015-09-04 13:26 UTC (permalink / raw)
  To: intel-gfx

This series adds changes in HDMI detection methods and also afew
optimization. The overview of changes are:
1. HDMI EDID is read only at the hot-plug time.
2. EDID is cached in connectoer on hotplug,and released from cache only
   on the hot-unplug.
3. In between, for all detetct calls, only cached EDID is used.
4. HDMI EDID is read, only when live status is up.
5. HDMI is force probed during the connector init time, for connected boot
   scenarios.

v2:
   Some refactoring is with this series.

   Also, right now this is done for platforms gen7 and above because we
   couldn't test with older platforms. For newer platforms it works
   reliably.

   For HPD and live status to work on SKL, following patch is required:
   "drm/i915: Handle HPD when it has actually occurred"

v3:
   Added retrial for live_status.
   Relying on HPD fpr edid detection onlyfrom gen 8 onwards and VLV

v4:
   *Also, including durga's patch for fixing irq_port for edp.
   Without this fix, hdmi hpd breaks with hdmi and edp connected on bxt.
   *Taking off the check for older platforms and now rely on init and 
   hotplug to get the edid updated
   *Some other cleanups.

Durgadoss R (1):
  drm/i915/bxt: Fix irq_port for eDP

Shashank Sharma (2):
  drm/i915: add attached connector to hdmi container
  drm/i915: Add HDMI probe function

Sonika Jindal (3):
  drm/i915: Make intel_digital_port_connected global
  drm/i915: drm/i915: Check live status before reading edid
  drm/i915: drm/i915: Process hpd only for hdmi inside
    hotplug_work_func

 drivers/gpu/drm/i915/intel_ddi.c     |   15 ++++---
 drivers/gpu/drm/i915/intel_dp.c      |   11 +++--
 drivers/gpu/drm/i915/intel_drv.h     |    3 ++
 drivers/gpu/drm/i915/intel_hdmi.c    |   80 +++++++++++++++++++++++++++++-----
 drivers/gpu/drm/i915/intel_hotplug.c |    3 +-
 5 files changed, 90 insertions(+), 22 deletions(-)

-- 
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [PATCH 1/6] drm/i915: add attached connector to hdmi container
  2015-09-04 13:26 [PATCH 0/6] HDMI optimization series Sonika Jindal
@ 2015-09-04 13:26 ` Sonika Jindal
  2015-09-09 18:54   ` Rodrigo Vivi
  2015-09-04 13:26 ` [PATCH 2/6] drm/i915: Add HDMI probe function Sonika Jindal
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 77+ messages in thread
From: Sonika Jindal @ 2015-09-04 13:26 UTC (permalink / raw)
  To: intel-gfx

From: Shashank Sharma <shashank.sharma@intel.com>

This patch adds the intel_connector initialized to intel_hdmi
display, during the init phase, just like the other encoders do.
This attachment is very useful when we need to extract the connector
pointer during the hotplug handler function

Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
---
 drivers/gpu/drm/i915/intel_drv.h  |    1 +
 drivers/gpu/drm/i915/intel_hdmi.c |    1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index c61ba47..b6c2c20 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -667,6 +667,7 @@ struct intel_hdmi {
 	enum hdmi_force_audio force_audio;
 	bool rgb_quant_range_selectable;
 	enum hdmi_picture_aspect aspect_ratio;
+	struct intel_connector *attached_connector;
 	void (*write_infoframe)(struct drm_encoder *encoder,
 				enum hdmi_infoframe_type type,
 				const void *frame, ssize_t len);
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index ed25f64..5bdb386 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -2107,6 +2107,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 
 	intel_connector_attach_encoder(intel_connector, intel_encoder);
 	drm_connector_register(connector);
+	intel_hdmi->attached_connector = intel_connector;
 
 	/* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
 	 * 0xd.  Failure to do so will result in spurious interrupts being
-- 
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 2/6] drm/i915: Add HDMI probe function
  2015-09-04 13:26 [PATCH 0/6] HDMI optimization series Sonika Jindal
  2015-09-04 13:26 ` [PATCH 1/6] drm/i915: add attached connector to hdmi container Sonika Jindal
@ 2015-09-04 13:26 ` Sonika Jindal
  2015-09-04 14:48   ` Daniel Vetter
  2015-09-04 13:26 ` [PATCH 3/6] drm/i915: Make intel_digital_port_connected global Sonika Jindal
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 77+ messages in thread
From: Sonika Jindal @ 2015-09-04 13:26 UTC (permalink / raw)
  To: intel-gfx

From: Shashank Sharma <shashank.sharma@intel.com>

This patch adds a separate probe function for HDMI
EDID read over DDC channel. This function has been
registered as a .hot_plug handler for HDMI encoder.

The current implementation of hdmi_detect()
function re-sets the cached HDMI edid (in connector->detect_edid) in
every detect call.This function gets called many times, sometimes
directly from userspace probes, forcing drivers to read EDID every
detect function call.This causes several problems like:

1. Race conditions in multiple hot_plug / unplug cases, between
   interrupts bottom halves and userspace detections.
2. Many Un-necessary EDID reads for single hotplug/unplug
3. HDMI complaince failures which expects only one EDID read per hotplug

This function will be serving the purpose of really reading the EDID
by really probing the DDC channel, and updating the cached EDID.

The plan is to:
1. i915 IRQ handler bottom half function already calls
   intel_encoder->hotplug() function. Adding This probe function which
   will read the EDID only in case of a hotplug / unplug.
2. During init_connector his probe will be called to read the edid
3. Reuse the cached EDID in hdmi_detect() function.

The "< gen7" check is there because this was tested only for >=gen7
platforms. For older platforms the hotplug/reading edid path remains same.

v2: Calling set_edid instead of hdmi_probe during init.
Also, for platforms having DDI, intel_encoder for DP and HDMI is same
(taken from intel_dig_port), so for DP also, hot_plug function gets called
which is not intended here. So, check for HDMI in intel_hdmi_probe
Rely on HPD for updating edid only for platforms gen > 8 and also for VLV.

v3: Dropping the gen < 8 || !VLV  check. Now all platforms should rely on
hotplug or init for updating the edid.(Daniel)
Also, calling hdmi_probe in init instead of set_edid

Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/i915/intel_hdmi.c |   46 ++++++++++++++++++++++++++++++++-----
 1 file changed, 40 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 5bdb386..1eda71a 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1368,23 +1368,53 @@ intel_hdmi_set_edid(struct drm_connector *connector)
 	return connected;
 }
 
+void intel_hdmi_probe(struct intel_encoder *intel_encoder)
+{
+	struct intel_hdmi *intel_hdmi =
+			enc_to_intel_hdmi(&intel_encoder->base);
+	struct intel_connector *intel_connector =
+				intel_hdmi->attached_connector;
+
+	/*
+	 * We are here, means there is a hotplug or a force
+	 * detection. Clear the cached EDID and probe the
+	 * DDC bus to check the current status of HDMI.
+	 */
+	intel_hdmi_unset_edid(&intel_connector->base);
+	if (intel_hdmi_set_edid(&intel_connector->base))
+		DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
+	else
+		DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
+}
+
 static enum drm_connector_status
 intel_hdmi_detect(struct drm_connector *connector, bool force)
 {
 	enum drm_connector_status status;
+	struct intel_connector *intel_connector =
+				to_intel_connector(connector);
 
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
 		      connector->base.id, connector->name);
+	/*
+	 * There are many userspace calls which probe EDID from
+	 * detect path. In case of multiple hotplug/unplug, these
+	 * can cause race conditions while probing EDID. Also its
+	 * waste of CPU cycles to read the EDID again and again
+	 * unless there is a real hotplug.
+	 * So, rely on hotplugs and init to read edid.
+	 * Check connector status based on availability of cached EDID.
+	 */
 
-	intel_hdmi_unset_edid(connector);
-
-	if (intel_hdmi_set_edid(connector)) {
+	if (intel_connector->detect_edid) {
 		struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
-
-		hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
 		status = connector_status_connected;
-	} else
+		hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
+		DRM_DEBUG_DRIVER("hdmi status = connected\n");
+	} else {
 		status = connector_status_disconnected;
+		DRM_DEBUG_DRIVER("hdmi status = disconnected\n");
+	}
 
 	return status;
 }
@@ -2104,11 +2134,15 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 	intel_connector->unregister = intel_connector_unregister;
 
 	intel_hdmi_add_properties(intel_hdmi, connector);
+	intel_encoder->hot_plug = intel_hdmi_probe;
 
 	intel_connector_attach_encoder(intel_connector, intel_encoder);
 	drm_connector_register(connector);
 	intel_hdmi->attached_connector = intel_connector;
 
+	/* Set edid during init */
+	intel_hdmi_probe(intel_encoder);
+
 	/* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
 	 * 0xd.  Failure to do so will result in spurious interrupts being
 	 * generated on the port when a cable is not attached.
-- 
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 3/6] drm/i915: Make intel_digital_port_connected global
  2015-09-04 13:26 [PATCH 0/6] HDMI optimization series Sonika Jindal
  2015-09-04 13:26 ` [PATCH 1/6] drm/i915: add attached connector to hdmi container Sonika Jindal
  2015-09-04 13:26 ` [PATCH 2/6] drm/i915: Add HDMI probe function Sonika Jindal
@ 2015-09-04 13:26 ` Sonika Jindal
  2015-09-09 18:57   ` Rodrigo Vivi
  2015-09-04 13:26 ` [PATCH 4/6] drm/i915: drm/i915: Check live status before reading edid Sonika Jindal
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 77+ messages in thread
From: Sonika Jindal @ 2015-09-04 13:26 UTC (permalink / raw)
  To: intel-gfx

This is to allow live status check for HDMI as well.
Also, using intel_encoder->hpd_pin to check the live status
for bxt because of BXT A0/A1 WA for HPD pins.

Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c  |   11 +++++++----
 drivers/gpu/drm/i915/intel_drv.h |    2 ++
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 796f930..fedf6d1 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -4663,11 +4663,14 @@ static bool vlv_digital_port_connected(struct drm_i915_private *dev_priv,
 }
 
 static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
-				       struct intel_digital_port *port)
+				       struct intel_digital_port *intel_dig_port)
 {
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
+	enum port port;
 	u32 bit;
 
-	switch (port->port) {
+	intel_hpd_pin_to_port(intel_encoder->hpd_pin, &port);
+	switch (port) {
 	case PORT_A:
 		bit = BXT_DE_PORT_HP_DDIA;
 		break;
@@ -4678,7 +4681,7 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
 		bit = BXT_DE_PORT_HP_DDIC;
 		break;
 	default:
-		MISSING_CASE(port->port);
+		MISSING_CASE(port);
 		return false;
 	}
 
@@ -4692,7 +4695,7 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
  *
  * Return %true if @port is connected, %false otherwise.
  */
-static bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
+bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
 					 struct intel_digital_port *port)
 {
 	if (HAS_PCH_IBX(dev_priv))
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index b6c2c20..ac6d748 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1210,6 +1210,8 @@ void intel_edp_drrs_disable(struct intel_dp *intel_dp);
 void intel_edp_drrs_invalidate(struct drm_device *dev,
 		unsigned frontbuffer_bits);
 void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits);
+bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
+					 struct intel_digital_port *port);
 
 /* intel_dp_mst.c */
 int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
-- 
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 4/6] drm/i915: drm/i915: Check live status before reading edid
  2015-09-04 13:26 [PATCH 0/6] HDMI optimization series Sonika Jindal
                   ` (2 preceding siblings ...)
  2015-09-04 13:26 ` [PATCH 3/6] drm/i915: Make intel_digital_port_connected global Sonika Jindal
@ 2015-09-04 13:26 ` Sonika Jindal
  2015-09-04 14:49   ` Daniel Vetter
  2015-09-04 13:26 ` [PATCH 5/6] drm/i915: drm/i915: Process hpd only for hdmi inside hotplug_work_func Sonika Jindal
  2015-09-04 13:26 ` [PATCH 6/6] drm/i915/bxt: Fix irq_port for eDP Sonika Jindal
  5 siblings, 1 reply; 77+ messages in thread
From: Sonika Jindal @ 2015-09-04 13:26 UTC (permalink / raw)
  To: intel-gfx

The Bspec is very clear that Live status must be checked about before
trying to read EDID over DDC channel. This patch makes sure that HDMI
EDID is read only when live status us up.

The live status doesn't seem to perform very consistent across various
platforms when tested with different monitors. The reason behind that is
some monitors are late to provide right voltage to set live_status up.
So, after getting the interrupt, for a small duration, live status reg
fluctuates, and then settles down showing the correct staus.

This is explained here in, in a rough way:
HPD line  ________________
			 |\ T1 = Monitor Hotplug causing IRQ
			 | \______________________________________
			 | |
                         | |
			 | |   T2 = Live status is stable 
			 | |  _____________________________________
			 | | /|
Live status _____________|_|/ |
			 | |  |
			 | |  |
			 | |  |
			T0 T1  T2

(Between T1 and T2 Live status fluctuates or can be even low, depending on
 the monitor)

After several experiments, we have concluded that a max delay
of 30ms is enough to allow the live status to settle down with
most of the monitors. This total delay of 30ms has been split into
a resolution of 3 retries of 10ms each, for the better cases.

This delay is kept at 30ms, keeping in consideration that, HDCP compliance
expect the HPD handler to respond a plug out in 100ms, by disabling the port.

v2: Adding checks for VLV/CHV as well. Reusing old ibx and g4x functions
to check digital port status. Adding a separate function to get bxt live
status (Daniel)
v3: Using intel_encoder->hpd_pin to check the live status (Siva)
Moving the live status read to intel_hdmi_probe and passing parameter
to read/not to read the edid. (me)
v4:
* Added live status check for all platforms using
intel_digital_port_connected.
* Rebased on top of Jani's DP cleanup series
* Some monitors take time in setting the live status. So retry for few
times if this is a connect HPD

Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/i915/intel_hdmi.c |   35 ++++++++++++++++++++++++++++-------
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 1eda71a..d82887b 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1329,22 +1329,23 @@ intel_hdmi_unset_edid(struct drm_connector *connector)
 }
 
 static bool
-intel_hdmi_set_edid(struct drm_connector *connector)
+intel_hdmi_set_edid(struct drm_connector *connector, bool force)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
 	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 	struct intel_encoder *intel_encoder =
 		&hdmi_to_dig_port(intel_hdmi)->base;
 	enum intel_display_power_domain power_domain;
-	struct edid *edid;
+	struct edid *edid = NULL;
 	bool connected = false;
 
 	power_domain = intel_display_port_power_domain(intel_encoder);
 	intel_display_power_get(dev_priv, power_domain);
 
-	edid = drm_get_edid(connector,
-			    intel_gmbus_get_adapter(dev_priv,
-						    intel_hdmi->ddc_bus));
+	if (force)
+		edid = drm_get_edid(connector,
+				    intel_gmbus_get_adapter(dev_priv,
+				    intel_hdmi->ddc_bus));
 
 	intel_display_power_put(dev_priv, power_domain);
 
@@ -1374,6 +1375,26 @@ void intel_hdmi_probe(struct intel_encoder *intel_encoder)
 			enc_to_intel_hdmi(&intel_encoder->base);
 	struct intel_connector *intel_connector =
 				intel_hdmi->attached_connector;
+	struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
+	bool live_status = false;
+	unsigned int retry = 3;
+
+	live_status = intel_digital_port_connected(dev_priv,
+						   hdmi_to_dig_port(intel_hdmi));
+	if (!intel_connector->detect_edid && live_status == false) {
+		/*
+		 * Hotplug had occurred and old status was disconnected,
+		 * so it might be possible that live status is not set,
+		 * so retry for few times
+		 */
+		do {
+			mdelay(10);
+			live_status = intel_digital_port_connected(dev_priv,
+						hdmi_to_dig_port(intel_hdmi));
+			if (live_status)
+				break;
+		} while (retry--);
+	}
 
 	/*
 	 * We are here, means there is a hotplug or a force
@@ -1381,7 +1402,7 @@ void intel_hdmi_probe(struct intel_encoder *intel_encoder)
 	 * DDC bus to check the current status of HDMI.
 	 */
 	intel_hdmi_unset_edid(&intel_connector->base);
-	if (intel_hdmi_set_edid(&intel_connector->base))
+	if (intel_hdmi_set_edid(&intel_connector->base, live_status))
 		DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
 	else
 		DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
@@ -1432,7 +1453,7 @@ intel_hdmi_force(struct drm_connector *connector)
 	if (connector->status != connector_status_connected)
 		return;
 
-	intel_hdmi_set_edid(connector);
+	intel_hdmi_set_edid(connector, true);
 	hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
 }
 
-- 
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 5/6] drm/i915: drm/i915: Process hpd only for hdmi inside hotplug_work_func
  2015-09-04 13:26 [PATCH 0/6] HDMI optimization series Sonika Jindal
                   ` (3 preceding siblings ...)
  2015-09-04 13:26 ` [PATCH 4/6] drm/i915: drm/i915: Check live status before reading edid Sonika Jindal
@ 2015-09-04 13:26 ` Sonika Jindal
  2015-09-04 14:47   ` Daniel Vetter
  2015-09-04 13:26 ` [PATCH 6/6] drm/i915/bxt: Fix irq_port for eDP Sonika Jindal
  5 siblings, 1 reply; 77+ messages in thread
From: Sonika Jindal @ 2015-09-04 13:26 UTC (permalink / raw)
  To: intel-gfx

If the same port is enumerated as hdmi as well as DP, this will get
called for DP connector as well which is not required because
i915_hotplug_work_func is solely to handle hdmi HPD.

Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/i915/intel_hotplug.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
index 53c0173..8e1c43e 100644
--- a/drivers/gpu/drm/i915/intel_hotplug.c
+++ b/drivers/gpu/drm/i915/intel_hotplug.c
@@ -325,7 +325,8 @@ static void i915_hotplug_work_func(struct work_struct *work)
 
 	list_for_each_entry(connector, &mode_config->connector_list, head) {
 		intel_connector = to_intel_connector(connector);
-		if (!intel_connector->encoder)
+		if (!intel_connector->encoder
+			&& connector->connector_type != DRM_MODE_CONNECTOR_HDMIA)
 			continue;
 		intel_encoder = intel_connector->encoder;
 		if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) {
-- 
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 6/6] drm/i915/bxt: Fix irq_port for eDP
  2015-09-04 13:26 [PATCH 0/6] HDMI optimization series Sonika Jindal
                   ` (4 preceding siblings ...)
  2015-09-04 13:26 ` [PATCH 5/6] drm/i915: drm/i915: Process hpd only for hdmi inside hotplug_work_func Sonika Jindal
@ 2015-09-04 13:26 ` Sonika Jindal
  2015-09-09 19:24   ` Rodrigo Vivi
  5 siblings, 1 reply; 77+ messages in thread
From: Sonika Jindal @ 2015-09-04 13:26 UTC (permalink / raw)
  To: intel-gfx

From: Durgadoss R <durgadoss.r@intel.com>

Currently, HDMI hotplug with eDP as local panel is failing
because the HDMI hpd is detected as a long hpd for eDP; and is
thus rightfully ignored. But, it should really be handled as
an interrupt on port B for HDMI (due to BXT A1 platform having
HPD pins A and B swapped). This patch sets the irq_port[PORT_A]
to NULL in case eDP is on port A so that irq handler does not
treat it as a 'dig_port' interrupt.

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c |   15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 4823184..fec51df 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -3218,15 +3218,20 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
 			goto err;
 
 		intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
+		dev_priv->hotplug.irq_port[port] = intel_dig_port;
 		/*
 		 * On BXT A0/A1, sw needs to activate DDIA HPD logic and
 		 * interrupts to check the external panel connection.
+		 * If eDP is connected on port A, set irq_port to NULL
+		 * so that we do not assume an interrupt here as a
+		 * 'dig_port' interrupt.
 		 */
-		if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)
-					 && port == PORT_B)
-			dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
-		else
-			dev_priv->hotplug.irq_port[port] = intel_dig_port;
+		if (IS_BROXTON(dev) && (INTEL_REVID(dev) < BXT_REVID_B0)) {
+			if (port == PORT_B)
+				dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
+			else if (intel_encoder->type == INTEL_OUTPUT_EDP)
+				dev_priv->hotplug.irq_port[port] = NULL;
+		}
 	}
 
 	/* In theory we don't need the encoder->type check, but leave it just in
-- 
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [PATCH 5/6] drm/i915: drm/i915: Process hpd only for hdmi inside hotplug_work_func
  2015-09-04 13:26 ` [PATCH 5/6] drm/i915: drm/i915: Process hpd only for hdmi inside hotplug_work_func Sonika Jindal
@ 2015-09-04 14:47   ` Daniel Vetter
  2015-09-06  4:31     ` Jindal, Sonika
  0 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2015-09-04 14:47 UTC (permalink / raw)
  To: Sonika Jindal; +Cc: intel-gfx

On Fri, Sep 04, 2015 at 06:56:15PM +0530, Sonika Jindal wrote:
> If the same port is enumerated as hdmi as well as DP, this will get
> called for DP connector as well which is not required because
> i915_hotplug_work_func is solely to handle hdmi HPD.
> 
> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_hotplug.c |    3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
> index 53c0173..8e1c43e 100644
> --- a/drivers/gpu/drm/i915/intel_hotplug.c
> +++ b/drivers/gpu/drm/i915/intel_hotplug.c
> @@ -325,7 +325,8 @@ static void i915_hotplug_work_func(struct work_struct *work)
>  
>  	list_for_each_entry(connector, &mode_config->connector_list, head) {
>  		intel_connector = to_intel_connector(connector);
> -		if (!intel_connector->encoder)
> +		if (!intel_connector->encoder
> +			&& connector->connector_type != DRM_MODE_CONNECTOR_HDMIA)
>  			continue;

Pretty sure this breaks hotplug detection for everything but HDMI (since
now nothing but hdmi gets called it's ->detect function, and only if that
signals a status change will we send out an uevent to userspace). Does
this really not break DP hotplug?

Yes we probe both hdmi and DP always, and probably we could be more
intelligent with the fallback between the too. But this here doesn't seem
to be the right solution.
-Daniel

>  		intel_encoder = intel_connector->encoder;
>  		if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) {
> -- 
> 1.7.10.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 2/6] drm/i915: Add HDMI probe function
  2015-09-04 13:26 ` [PATCH 2/6] drm/i915: Add HDMI probe function Sonika Jindal
@ 2015-09-04 14:48   ` Daniel Vetter
  2015-09-09 18:55     ` Rodrigo Vivi
  0 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2015-09-04 14:48 UTC (permalink / raw)
  To: Sonika Jindal; +Cc: intel-gfx

On Fri, Sep 04, 2015 at 06:56:12PM +0530, Sonika Jindal wrote:
> From: Shashank Sharma <shashank.sharma@intel.com>
> 
> This patch adds a separate probe function for HDMI
> EDID read over DDC channel. This function has been
> registered as a .hot_plug handler for HDMI encoder.
> 
> The current implementation of hdmi_detect()
> function re-sets the cached HDMI edid (in connector->detect_edid) in
> every detect call.This function gets called many times, sometimes
> directly from userspace probes, forcing drivers to read EDID every
> detect function call.This causes several problems like:
> 
> 1. Race conditions in multiple hot_plug / unplug cases, between
>    interrupts bottom halves and userspace detections.
> 2. Many Un-necessary EDID reads for single hotplug/unplug
> 3. HDMI complaince failures which expects only one EDID read per hotplug
> 
> This function will be serving the purpose of really reading the EDID
> by really probing the DDC channel, and updating the cached EDID.
> 
> The plan is to:
> 1. i915 IRQ handler bottom half function already calls
>    intel_encoder->hotplug() function. Adding This probe function which
>    will read the EDID only in case of a hotplug / unplug.
> 2. During init_connector his probe will be called to read the edid
> 3. Reuse the cached EDID in hdmi_detect() function.
> 
> The "< gen7" check is there because this was tested only for >=gen7
> platforms. For older platforms the hotplug/reading edid path remains same.
> 
> v2: Calling set_edid instead of hdmi_probe during init.
> Also, for platforms having DDI, intel_encoder for DP and HDMI is same
> (taken from intel_dig_port), so for DP also, hot_plug function gets called
> which is not intended here. So, check for HDMI in intel_hdmi_probe
> Rely on HPD for updating edid only for platforms gen > 8 and also for VLV.
> 
> v3: Dropping the gen < 8 || !VLV  check. Now all platforms should rely on
> hotplug or init for updating the edid.(Daniel)
> Also, calling hdmi_probe in init instead of set_edid
> 
> Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_hdmi.c |   46 ++++++++++++++++++++++++++++++++-----
>  1 file changed, 40 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index 5bdb386..1eda71a 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -1368,23 +1368,53 @@ intel_hdmi_set_edid(struct drm_connector *connector)
>  	return connected;
>  }
>  
> +void intel_hdmi_probe(struct intel_encoder *intel_encoder)

Please call it _hot_plug if it's for the _hot_plug path.

> +{
> +	struct intel_hdmi *intel_hdmi =
> +			enc_to_intel_hdmi(&intel_encoder->base);
> +	struct intel_connector *intel_connector =
> +				intel_hdmi->attached_connector;
> +
> +	/*
> +	 * We are here, means there is a hotplug or a force
> +	 * detection. Clear the cached EDID and probe the
> +	 * DDC bus to check the current status of HDMI.
> +	 */
> +	intel_hdmi_unset_edid(&intel_connector->base);
> +	if (intel_hdmi_set_edid(&intel_connector->base))
> +		DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
> +	else
> +		DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
> +}
> +
>  static enum drm_connector_status
>  intel_hdmi_detect(struct drm_connector *connector, bool force)
>  {
>  	enum drm_connector_status status;
> +	struct intel_connector *intel_connector =
> +				to_intel_connector(connector);
>  
>  	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
>  		      connector->base.id, connector->name);
> +	/*
> +	 * There are many userspace calls which probe EDID from
> +	 * detect path. In case of multiple hotplug/unplug, these
> +	 * can cause race conditions while probing EDID. Also its
> +	 * waste of CPU cycles to read the EDID again and again
> +	 * unless there is a real hotplug.
> +	 * So, rely on hotplugs and init to read edid.
> +	 * Check connector status based on availability of cached EDID.
> +	 */
>  
> -	intel_hdmi_unset_edid(connector);
> -
> -	if (intel_hdmi_set_edid(connector)) {
> +	if (intel_connector->detect_edid) {
>  		struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
> -
> -		hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
>  		status = connector_status_connected;
> -	} else
> +		hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
> +		DRM_DEBUG_DRIVER("hdmi status = connected\n");
> +	} else {
>  		status = connector_status_disconnected;
> +		DRM_DEBUG_DRIVER("hdmi status = disconnected\n");
> +	}
>  
>  	return status;
>  }
> @@ -2104,11 +2134,15 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
>  	intel_connector->unregister = intel_connector_unregister;
>  
>  	intel_hdmi_add_properties(intel_hdmi, connector);
> +	intel_encoder->hot_plug = intel_hdmi_probe;
>  
>  	intel_connector_attach_encoder(intel_connector, intel_encoder);
>  	drm_connector_register(connector);
>  	intel_hdmi->attached_connector = intel_connector;
>  
> +	/* Set edid during init */
> +	intel_hdmi_probe(intel_encoder);

Separate patch, but we really don't want this, initial probe should be
done async to avoid stalling the driver.
-Daniel

> +
>  	/* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
>  	 * 0xd.  Failure to do so will result in spurious interrupts being
>  	 * generated on the port when a cable is not attached.
> -- 
> 1.7.10.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 4/6] drm/i915: drm/i915: Check live status before reading edid
  2015-09-04 13:26 ` [PATCH 4/6] drm/i915: drm/i915: Check live status before reading edid Sonika Jindal
@ 2015-09-04 14:49   ` Daniel Vetter
  2015-09-07  5:02     ` [PATCH] " Sonika Jindal
  2015-09-09 19:11     ` [PATCH 4/6] drm/i915: " Rodrigo Vivi
  0 siblings, 2 replies; 77+ messages in thread
From: Daniel Vetter @ 2015-09-04 14:49 UTC (permalink / raw)
  To: Sonika Jindal; +Cc: intel-gfx

On Fri, Sep 04, 2015 at 06:56:14PM +0530, Sonika Jindal wrote:
> The Bspec is very clear that Live status must be checked about before
> trying to read EDID over DDC channel. This patch makes sure that HDMI
> EDID is read only when live status us up.
> 
> The live status doesn't seem to perform very consistent across various
> platforms when tested with different monitors. The reason behind that is
> some monitors are late to provide right voltage to set live_status up.
> So, after getting the interrupt, for a small duration, live status reg
> fluctuates, and then settles down showing the correct staus.
> 
> This is explained here in, in a rough way:
> HPD line  ________________
> 			 |\ T1 = Monitor Hotplug causing IRQ
> 			 | \______________________________________
> 			 | |
>                          | |
> 			 | |   T2 = Live status is stable 
> 			 | |  _____________________________________
> 			 | | /|
> Live status _____________|_|/ |
> 			 | |  |
> 			 | |  |
> 			 | |  |
> 			T0 T1  T2
> 
> (Between T1 and T2 Live status fluctuates or can be even low, depending on
>  the monitor)
> 
> After several experiments, we have concluded that a max delay
> of 30ms is enough to allow the live status to settle down with
> most of the monitors. This total delay of 30ms has been split into
> a resolution of 3 retries of 10ms each, for the better cases.
> 
> This delay is kept at 30ms, keeping in consideration that, HDCP compliance
> expect the HPD handler to respond a plug out in 100ms, by disabling the port.
> 
> v2: Adding checks for VLV/CHV as well. Reusing old ibx and g4x functions
> to check digital port status. Adding a separate function to get bxt live
> status (Daniel)
> v3: Using intel_encoder->hpd_pin to check the live status (Siva)
> Moving the live status read to intel_hdmi_probe and passing parameter
> to read/not to read the edid. (me)
> v4:
> * Added live status check for all platforms using
> intel_digital_port_connected.
> * Rebased on top of Jani's DP cleanup series
> * Some monitors take time in setting the live status. So retry for few
> times if this is a connect HPD
> 
> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>

Really pretty commit message! Had some minor comments on two other patches
in this series while reading through them, but looks good otherwise.
Please sign up someone for final review of the details and I'll pull in
the patches once that's done.
-Daniel

> ---
>  drivers/gpu/drm/i915/intel_hdmi.c |   35 ++++++++++++++++++++++++++++-------
>  1 file changed, 28 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index 1eda71a..d82887b 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -1329,22 +1329,23 @@ intel_hdmi_unset_edid(struct drm_connector *connector)
>  }
>  
>  static bool
> -intel_hdmi_set_edid(struct drm_connector *connector)
> +intel_hdmi_set_edid(struct drm_connector *connector, bool force)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(connector->dev);
>  	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
>  	struct intel_encoder *intel_encoder =
>  		&hdmi_to_dig_port(intel_hdmi)->base;
>  	enum intel_display_power_domain power_domain;
> -	struct edid *edid;
> +	struct edid *edid = NULL;
>  	bool connected = false;
>  
>  	power_domain = intel_display_port_power_domain(intel_encoder);
>  	intel_display_power_get(dev_priv, power_domain);
>  
> -	edid = drm_get_edid(connector,
> -			    intel_gmbus_get_adapter(dev_priv,
> -						    intel_hdmi->ddc_bus));
> +	if (force)
> +		edid = drm_get_edid(connector,
> +				    intel_gmbus_get_adapter(dev_priv,
> +				    intel_hdmi->ddc_bus));
>  
>  	intel_display_power_put(dev_priv, power_domain);
>  
> @@ -1374,6 +1375,26 @@ void intel_hdmi_probe(struct intel_encoder *intel_encoder)
>  			enc_to_intel_hdmi(&intel_encoder->base);
>  	struct intel_connector *intel_connector =
>  				intel_hdmi->attached_connector;
> +	struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
> +	bool live_status = false;
> +	unsigned int retry = 3;
> +
> +	live_status = intel_digital_port_connected(dev_priv,
> +						   hdmi_to_dig_port(intel_hdmi));
> +	if (!intel_connector->detect_edid && live_status == false) {
> +		/*
> +		 * Hotplug had occurred and old status was disconnected,
> +		 * so it might be possible that live status is not set,
> +		 * so retry for few times
> +		 */
> +		do {
> +			mdelay(10);
> +			live_status = intel_digital_port_connected(dev_priv,
> +						hdmi_to_dig_port(intel_hdmi));
> +			if (live_status)
> +				break;
> +		} while (retry--);
> +	}
>  
>  	/*
>  	 * We are here, means there is a hotplug or a force
> @@ -1381,7 +1402,7 @@ void intel_hdmi_probe(struct intel_encoder *intel_encoder)
>  	 * DDC bus to check the current status of HDMI.
>  	 */
>  	intel_hdmi_unset_edid(&intel_connector->base);
> -	if (intel_hdmi_set_edid(&intel_connector->base))
> +	if (intel_hdmi_set_edid(&intel_connector->base, live_status))
>  		DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
>  	else
>  		DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
> @@ -1432,7 +1453,7 @@ intel_hdmi_force(struct drm_connector *connector)
>  	if (connector->status != connector_status_connected)
>  		return;
>  
> -	intel_hdmi_set_edid(connector);
> +	intel_hdmi_set_edid(connector, true);
>  	hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
>  }
>  
> -- 
> 1.7.10.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 5/6] drm/i915: drm/i915: Process hpd only for hdmi inside hotplug_work_func
  2015-09-04 14:47   ` Daniel Vetter
@ 2015-09-06  4:31     ` Jindal, Sonika
  2015-09-07  5:04       ` [PATCH] drm/i915: Call encoder hot_plug hook only for hdmi Sonika Jindal
  2015-09-09 19:20       ` [PATCH 5/6] drm/i915: drm/i915: Process hpd only for hdmi inside hotplug_work_func Rodrigo Vivi
  0 siblings, 2 replies; 77+ messages in thread
From: Jindal, Sonika @ 2015-09-06  4:31 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx



On 9/4/2015 8:17 PM, Daniel Vetter wrote:
> On Fri, Sep 04, 2015 at 06:56:15PM +0530, Sonika Jindal wrote:
>> If the same port is enumerated as hdmi as well as DP, this will get
>> called for DP connector as well which is not required because
>> i915_hotplug_work_func is solely to handle hdmi HPD.
>>
>> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
>> ---
>>   drivers/gpu/drm/i915/intel_hotplug.c |    3 ++-
>>   1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
>> index 53c0173..8e1c43e 100644
>> --- a/drivers/gpu/drm/i915/intel_hotplug.c
>> +++ b/drivers/gpu/drm/i915/intel_hotplug.c
>> @@ -325,7 +325,8 @@ static void i915_hotplug_work_func(struct work_struct *work)
>>
>>   	list_for_each_entry(connector, &mode_config->connector_list, head) {
>>   		intel_connector = to_intel_connector(connector);
>> -		if (!intel_connector->encoder)
>> +		if (!intel_connector->encoder
>> +			&& connector->connector_type != DRM_MODE_CONNECTOR_HDMIA)
>>   			continue;
>
> Pretty sure this breaks hotplug detection for everything but HDMI (since
> now nothing but hdmi gets called it's ->detect function, and only if that
> signals a status change will we send out an uevent to userspace). Does
> this really not break DP hotplug?
>
> Yes we probe both hdmi and DP always, and probably we could be more
> intelligent with the fallback between the too. But this here doesn't seem
> to be the right solution.
> -Daniel

Hmm :(
This doesn't allow detect to be called for dp. I missed the part that 
hpd_pulse only handles mst. From the name and comments it looks like it 
should handle hpd for dp completely. I think this this code needs some 
refactoring.

For now, I think I better move this check to intel_encoder->hot_plug 
function because for the connectors with dp and hdmi both, this hot_plug 
hook gets called twice.

>
>>   		intel_encoder = intel_connector->encoder;
>>   		if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) {
>> --
>> 1.7.10.4
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [PATCH] drm/i915: Check live status before reading edid
  2015-09-04 14:49   ` Daniel Vetter
@ 2015-09-07  5:02     ` Sonika Jindal
  2015-09-08 11:21       ` Sonika Jindal
  2015-09-09 19:11     ` [PATCH 4/6] drm/i915: " Rodrigo Vivi
  1 sibling, 1 reply; 77+ messages in thread
From: Sonika Jindal @ 2015-09-07  5:02 UTC (permalink / raw)
  To: intel-gfx

Adding this for SKL onwards.

v2: Adding checks for VLV/CHV as well. Reusing old ibx and g4x functions
to check digital port status. Adding a separate function to get bxt live
status (Daniel)
v3: Using intel_encoder->hpd_pin to check the live status (Siva)
Moving the live status read to intel_hdmi_probe and passing parameter
to read/not to read the edid. (me)
v4:
* Added live status check for all platforms using
intel_digital_port_connected.
* Rebased on top of Jani's DP cleanup series
* Some monitors take time in setting the live status. So retry for few
times if this is a connect HPD
v5: Removed extra "drm/i915" from commit message. Adding Shashank's sob
which was missed.

Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/i915/intel_hdmi.c |   35 ++++++++++++++++++++++++++++-------
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 1eda71a..d82887b 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1329,22 +1329,23 @@ intel_hdmi_unset_edid(struct drm_connector *connector)
 }
 
 static bool
-intel_hdmi_set_edid(struct drm_connector *connector)
+intel_hdmi_set_edid(struct drm_connector *connector, bool force)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
 	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 	struct intel_encoder *intel_encoder =
 		&hdmi_to_dig_port(intel_hdmi)->base;
 	enum intel_display_power_domain power_domain;
-	struct edid *edid;
+	struct edid *edid = NULL;
 	bool connected = false;
 
 	power_domain = intel_display_port_power_domain(intel_encoder);
 	intel_display_power_get(dev_priv, power_domain);
 
-	edid = drm_get_edid(connector,
-			    intel_gmbus_get_adapter(dev_priv,
-						    intel_hdmi->ddc_bus));
+	if (force)
+		edid = drm_get_edid(connector,
+				    intel_gmbus_get_adapter(dev_priv,
+				    intel_hdmi->ddc_bus));
 
 	intel_display_power_put(dev_priv, power_domain);
 
@@ -1374,6 +1375,26 @@ void intel_hdmi_probe(struct intel_encoder *intel_encoder)
 			enc_to_intel_hdmi(&intel_encoder->base);
 	struct intel_connector *intel_connector =
 				intel_hdmi->attached_connector;
+	struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
+	bool live_status = false;
+	unsigned int retry = 3;
+
+	live_status = intel_digital_port_connected(dev_priv,
+						   hdmi_to_dig_port(intel_hdmi));
+	if (!intel_connector->detect_edid && live_status == false) {
+		/*
+		 * Hotplug had occurred and old status was disconnected,
+		 * so it might be possible that live status is not set,
+		 * so retry for few times
+		 */
+		do {
+			mdelay(10);
+			live_status = intel_digital_port_connected(dev_priv,
+						hdmi_to_dig_port(intel_hdmi));
+			if (live_status)
+				break;
+		} while (retry--);
+	}
 
 	/*
 	 * We are here, means there is a hotplug or a force
@@ -1381,7 +1402,7 @@ void intel_hdmi_probe(struct intel_encoder *intel_encoder)
 	 * DDC bus to check the current status of HDMI.
 	 */
 	intel_hdmi_unset_edid(&intel_connector->base);
-	if (intel_hdmi_set_edid(&intel_connector->base))
+	if (intel_hdmi_set_edid(&intel_connector->base, live_status))
 		DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
 	else
 		DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
@@ -1432,7 +1453,7 @@ intel_hdmi_force(struct drm_connector *connector)
 	if (connector->status != connector_status_connected)
 		return;
 
-	intel_hdmi_set_edid(connector);
+	intel_hdmi_set_edid(connector, true);
 	hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
 }
 
-- 
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH] drm/i915: Call encoder hot_plug hook only for hdmi
  2015-09-06  4:31     ` Jindal, Sonika
@ 2015-09-07  5:04       ` Sonika Jindal
  2015-09-07 16:26         ` Daniel Vetter
  2015-09-09 19:20       ` [PATCH 5/6] drm/i915: drm/i915: Process hpd only for hdmi inside hotplug_work_func Rodrigo Vivi
  1 sibling, 1 reply; 77+ messages in thread
From: Sonika Jindal @ 2015-09-07  5:04 UTC (permalink / raw)
  To: intel-gfx

If the same port is enumerated as hdmi as well as DP, this will call
hot_plug hook for DP as well which is not required here.
This splitting of edid read and detect is done only for HDMI with this
series.

v2: Avoid breaking DP hpd. Also corrected the commit message and
description accordingly. (Daniel)

Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/i915/intel_hotplug.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
index 53c0173..ff4692a 100644
--- a/drivers/gpu/drm/i915/intel_hotplug.c
+++ b/drivers/gpu/drm/i915/intel_hotplug.c
@@ -331,7 +331,8 @@ static void i915_hotplug_work_func(struct work_struct *work)
 		if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) {
 			DRM_DEBUG_KMS("Connector %s (pin %i) received hotplug event.\n",
 				      connector->name, intel_encoder->hpd_pin);
-			if (intel_encoder->hot_plug)
+			if (intel_encoder->hot_plug
+				&& connector->connector_type == DRM_MODE_CONNECTOR_HDMIA)
 				intel_encoder->hot_plug(intel_encoder);
 			if (intel_hpd_irq_event(dev, connector))
 				changed = true;
-- 
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915: Call encoder hot_plug hook only for hdmi
  2015-09-07  5:04       ` [PATCH] drm/i915: Call encoder hot_plug hook only for hdmi Sonika Jindal
@ 2015-09-07 16:26         ` Daniel Vetter
  2015-09-08  4:42           ` Jindal, Sonika
  0 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2015-09-07 16:26 UTC (permalink / raw)
  To: Sonika Jindal; +Cc: intel-gfx

On Mon, Sep 07, 2015 at 10:34:34AM +0530, Sonika Jindal wrote:
> If the same port is enumerated as hdmi as well as DP, this will call
> hot_plug hook for DP as well which is not required here.
> This splitting of edid read and detect is done only for HDMI with this
> series.
> 
> v2: Avoid breaking DP hpd. Also corrected the commit message and
> description accordingly. (Daniel)
> 
> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_hotplug.c |    3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
> index 53c0173..ff4692a 100644
> --- a/drivers/gpu/drm/i915/intel_hotplug.c
> +++ b/drivers/gpu/drm/i915/intel_hotplug.c
> @@ -331,7 +331,8 @@ static void i915_hotplug_work_func(struct work_struct *work)
>  		if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) {
>  			DRM_DEBUG_KMS("Connector %s (pin %i) received hotplug event.\n",
>  				      connector->name, intel_encoder->hpd_pin);
> -			if (intel_encoder->hot_plug)
> +			if (intel_encoder->hot_plug
> +				&& connector->connector_type == DRM_MODE_CONNECTOR_HDMIA)

Please use something like grep to find all the other ->hot_plug
implementations and then please tell me why you don't break them all.
-Daniel

>  				intel_encoder->hot_plug(intel_encoder);
>  			if (intel_hpd_irq_event(dev, connector))
>  				changed = true;
> -- 
> 1.7.10.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915: Call encoder hot_plug hook only for hdmi
  2015-09-07 16:26         ` Daniel Vetter
@ 2015-09-08  4:42           ` Jindal, Sonika
  2015-09-08 11:38             ` Jindal, Sonika
  0 siblings, 1 reply; 77+ messages in thread
From: Jindal, Sonika @ 2015-09-08  4:42 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx



On 9/7/2015 9:56 PM, Daniel Vetter wrote:
> On Mon, Sep 07, 2015 at 10:34:34AM +0530, Sonika Jindal wrote:
>> If the same port is enumerated as hdmi as well as DP, this will call
>> hot_plug hook for DP as well which is not required here.
>> This splitting of edid read and detect is done only for HDMI with this
>> series.
>>
>> v2: Avoid breaking DP hpd. Also corrected the commit message and
>> description accordingly. (Daniel)
>>
>> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
>> ---
>>   drivers/gpu/drm/i915/intel_hotplug.c |    3 ++-
>>   1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
>> index 53c0173..ff4692a 100644
>> --- a/drivers/gpu/drm/i915/intel_hotplug.c
>> +++ b/drivers/gpu/drm/i915/intel_hotplug.c
>> @@ -331,7 +331,8 @@ static void i915_hotplug_work_func(struct work_struct *work)
>>   		if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) {
>>   			DRM_DEBUG_KMS("Connector %s (pin %i) received hotplug event.\n",
>>   				      connector->name, intel_encoder->hpd_pin);
>> -			if (intel_encoder->hot_plug)
>> +			if (intel_encoder->hot_plug
>> +				&& connector->connector_type == DRM_MODE_CONNECTOR_HDMIA)
>
> Please use something like grep to find all the other ->hot_plug
> implementations and then please tell me why you don't break them all.
> -Daniel
>
Hmm, I only checked for hot_plug for DP/edp which is not there. Failed 
to notice that there is one in intel_sdvo.c.
My mistake. I will place it properly somewhere else.

Regards,
Sonika
>>   				intel_encoder->hot_plug(intel_encoder);
>>   			if (intel_hpd_irq_event(dev, connector))
>>   				changed = true;
>> --
>> 1.7.10.4
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [PATCH] drm/i915: Check live status before reading edid
  2015-09-07  5:02     ` [PATCH] " Sonika Jindal
@ 2015-09-08 11:21       ` Sonika Jindal
  0 siblings, 0 replies; 77+ messages in thread
From: Sonika Jindal @ 2015-09-08 11:21 UTC (permalink / raw)
  To: intel-gfx

The Bspec is very clear that Live status must be checked about before
trying to read EDID over DDC channel. This patch makes sure that HDMI
EDID is read only when live status us up.

The live status doesn't seem to perform very consistent across various
platforms when tested with different monitors. The reason behind that is
some monitors are late to provide right voltage to set live_status up.
So, after getting the interrupt, for a small duration, live status reg
fluctuates, and then settles down showing the correct staus.

This is explained here in, in a rough way:
HPD line  ________________
			 |\ T1 = Monitor Hotplug causing IRQ
			 | \______________________________________
			 | |
                         | |
			 | |   T2 = Live status is stable
			 | |  _____________________________________
			 | | /|
Live status _____________|_|/ |
			 | |  |
			 | |  |
			 | |  |
			T0 T1  T2

(Between T1 and T2 Live status fluctuates or can be even low, depending on
 the monitor)

After several experiments, we have concluded that a max delay
of 30ms is enough to allow the live status to settle down with
most of the monitors. This total delay of 30ms has been split into
a resolution of 3 retries of 10ms each, for the better cases.

This delay is kept at 30ms, keeping in consideration that, HDCP compliance
expect the HPD handler to respond a plug out in 100ms, by disabling port.

v2: Adding checks for VLV/CHV as well. Reusing old ibx and g4x functions
to check digital port status. Adding a separate function to get bxt live
status (Daniel)
v3: Using intel_encoder->hpd_pin to check the live status (Siva)
Moving the live status read to intel_hdmi_probe and passing parameter
to read/not to read the edid. (me)
v4:
* Added live status check for all platforms using
intel_digital_port_connected.
* Rebased on top of Jani's DP cleanup series
* Some monitors take time in setting the live status. So retry for few
times if this is a connect HPD
v5: Removed extra "drm/i915" from commit message. Adding Shashank's sob
    which was missed.
v6: Drop the (!detect_edid && !live_status check) check because for DDI
ports which are enumerated as hdmi as well as DP, we don't have a
mechanism to differentiate between DP and hdmi inside the encoder's
hot_plug. This leads to call to the hdmi's hot_plug hook for DP as well
as hdmi which leads to issues during unplug because of the above check.

Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/i915/intel_hdmi.c |   26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 1eda71a..c6e9156 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1329,22 +1329,23 @@ intel_hdmi_unset_edid(struct drm_connector *connector)
 }
 
 static bool
-intel_hdmi_set_edid(struct drm_connector *connector)
+intel_hdmi_set_edid(struct drm_connector *connector, bool force)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
 	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 	struct intel_encoder *intel_encoder =
 		&hdmi_to_dig_port(intel_hdmi)->base;
 	enum intel_display_power_domain power_domain;
-	struct edid *edid;
+	struct edid *edid = NULL;
 	bool connected = false;
 
 	power_domain = intel_display_port_power_domain(intel_encoder);
 	intel_display_power_get(dev_priv, power_domain);
 
-	edid = drm_get_edid(connector,
-			    intel_gmbus_get_adapter(dev_priv,
-						    intel_hdmi->ddc_bus));
+	if (force)
+		edid = drm_get_edid(connector,
+				    intel_gmbus_get_adapter(dev_priv,
+				    intel_hdmi->ddc_bus));
 
 	intel_display_power_put(dev_priv, power_domain);
 
@@ -1374,6 +1375,17 @@ void intel_hdmi_probe(struct intel_encoder *intel_encoder)
 			enc_to_intel_hdmi(&intel_encoder->base);
 	struct intel_connector *intel_connector =
 				intel_hdmi->attached_connector;
+	struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
+	bool live_status = false;
+	unsigned int retry = 3;
+
+	do {
+		live_status = intel_digital_port_connected(dev_priv,
+				hdmi_to_dig_port(intel_hdmi));
+		if (live_status)
+			break;
+		mdelay(10);
+	} while (retry--);
 
 	/*
 	 * We are here, means there is a hotplug or a force
@@ -1381,7 +1393,7 @@ void intel_hdmi_probe(struct intel_encoder *intel_encoder)
 	 * DDC bus to check the current status of HDMI.
 	 */
 	intel_hdmi_unset_edid(&intel_connector->base);
-	if (intel_hdmi_set_edid(&intel_connector->base))
+	if (intel_hdmi_set_edid(&intel_connector->base, live_status))
 		DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
 	else
 		DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
@@ -1432,7 +1444,7 @@ intel_hdmi_force(struct drm_connector *connector)
 	if (connector->status != connector_status_connected)
 		return;
 
-	intel_hdmi_set_edid(connector);
+	intel_hdmi_set_edid(connector, true);
 	hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
 }
 
-- 
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915: Call encoder hot_plug hook only for hdmi
  2015-09-08  4:42           ` Jindal, Sonika
@ 2015-09-08 11:38             ` Jindal, Sonika
  2015-09-09 15:17               ` Daniel Vetter
  0 siblings, 1 reply; 77+ messages in thread
From: Jindal, Sonika @ 2015-09-08 11:38 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx



On 9/8/2015 10:12 AM, Jindal, Sonika wrote:
>
>
> On 9/7/2015 9:56 PM, Daniel Vetter wrote:
>> On Mon, Sep 07, 2015 at 10:34:34AM +0530, Sonika Jindal wrote:
>>> If the same port is enumerated as hdmi as well as DP, this will call
>>> hot_plug hook for DP as well which is not required here.
>>> This splitting of edid read and detect is done only for HDMI with this
>>> series.
>>>
>>> v2: Avoid breaking DP hpd. Also corrected the commit message and
>>> description accordingly. (Daniel)
>>>
>>> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
>>> ---
>>>   drivers/gpu/drm/i915/intel_hotplug.c |    3 ++-
>>>   1 file changed, 2 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/intel_hotplug.c
>>> b/drivers/gpu/drm/i915/intel_hotplug.c
>>> index 53c0173..ff4692a 100644
>>> --- a/drivers/gpu/drm/i915/intel_hotplug.c
>>> +++ b/drivers/gpu/drm/i915/intel_hotplug.c
>>> @@ -331,7 +331,8 @@ static void i915_hotplug_work_func(struct
>>> work_struct *work)
>>>           if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) {
>>>               DRM_DEBUG_KMS("Connector %s (pin %i) received hotplug
>>> event.\n",
>>>                         connector->name, intel_encoder->hpd_pin);
>>> -            if (intel_encoder->hot_plug)
>>> +            if (intel_encoder->hot_plug
>>> +                && connector->connector_type ==
>>> DRM_MODE_CONNECTOR_HDMIA)
>>
>> Please use something like grep to find all the other ->hot_plug
>> implementations and then please tell me why you don't break them all.
>> -Daniel
>>
> Hmm, I only checked for hot_plug for DP/edp which is not there. Failed
> to notice that there is one in intel_sdvo.c.
> My mistake. I will place it properly somewhere else.
>
> Regards,
> Sonika

Is there any suggestion about how we can differentiate if it is actual 
DP or HDMI hotplug at this point? intel_encoder's type gets updated 
after detect call. So, not sure how to have this kind of check.

For now, I think we can abandon this patch from this series.

Regards,
Sonika
>>>                   intel_encoder->hot_plug(intel_encoder);
>>>               if (intel_hpd_irq_event(dev, connector))
>>>                   changed = true;
>>> --
>>> 1.7.10.4
>>>
>>> _______________________________________________
>>> Intel-gfx mailing list
>>> Intel-gfx@lists.freedesktop.org
>>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915: Call encoder hot_plug hook only for hdmi
  2015-09-08 11:38             ` Jindal, Sonika
@ 2015-09-09 15:17               ` Daniel Vetter
  2015-09-10  1:07                 ` Jindal, Sonika
  0 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2015-09-09 15:17 UTC (permalink / raw)
  To: Jindal, Sonika; +Cc: intel-gfx

On Tue, Sep 08, 2015 at 05:08:02PM +0530, Jindal, Sonika wrote:
> 
> 
> On 9/8/2015 10:12 AM, Jindal, Sonika wrote:
> >
> >
> >On 9/7/2015 9:56 PM, Daniel Vetter wrote:
> >>On Mon, Sep 07, 2015 at 10:34:34AM +0530, Sonika Jindal wrote:
> >>>If the same port is enumerated as hdmi as well as DP, this will call
> >>>hot_plug hook for DP as well which is not required here.
> >>>This splitting of edid read and detect is done only for HDMI with this
> >>>series.
> >>>
> >>>v2: Avoid breaking DP hpd. Also corrected the commit message and
> >>>description accordingly. (Daniel)
> >>>
> >>>Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> >>>---
> >>>  drivers/gpu/drm/i915/intel_hotplug.c |    3 ++-
> >>>  1 file changed, 2 insertions(+), 1 deletion(-)
> >>>
> >>>diff --git a/drivers/gpu/drm/i915/intel_hotplug.c
> >>>b/drivers/gpu/drm/i915/intel_hotplug.c
> >>>index 53c0173..ff4692a 100644
> >>>--- a/drivers/gpu/drm/i915/intel_hotplug.c
> >>>+++ b/drivers/gpu/drm/i915/intel_hotplug.c
> >>>@@ -331,7 +331,8 @@ static void i915_hotplug_work_func(struct
> >>>work_struct *work)
> >>>          if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) {
> >>>              DRM_DEBUG_KMS("Connector %s (pin %i) received hotplug
> >>>event.\n",
> >>>                        connector->name, intel_encoder->hpd_pin);
> >>>-            if (intel_encoder->hot_plug)
> >>>+            if (intel_encoder->hot_plug
> >>>+                && connector->connector_type ==
> >>>DRM_MODE_CONNECTOR_HDMIA)
> >>
> >>Please use something like grep to find all the other ->hot_plug
> >>implementations and then please tell me why you don't break them all.
> >>-Daniel
> >>
> >Hmm, I only checked for hot_plug for DP/edp which is not there. Failed
> >to notice that there is one in intel_sdvo.c.
> >My mistake. I will place it properly somewhere else.
> >
> >Regards,
> >Sonika
> 
> Is there any suggestion about how we can differentiate if it is actual DP or
> HDMI hotplug at this point? intel_encoder's type gets updated after detect
> call. So, not sure how to have this kind of check.
> 
> For now, I think we can abandon this patch from this series.

No, hpd is shared between hdmi and dp at the hw level so we can't
differentiate. Long term my idea would be that we merge together all the
hdmi _and_ dp hpd handling into one overall control-flow. Then we can make
sure to not call anything twice and also have sensible high-level flow
(like first checking for dp vs. hdmi and then taking relevant paths).

For dealing with ->hot_plug a quick fix might be to have a separate loop
going over encoders (to make sure we only call it once per encoder if
there's more than one connector for 1 encoder). That behaviour would also
be ok for sdvo.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 1/6] drm/i915: add attached connector to hdmi container
  2015-09-04 13:26 ` [PATCH 1/6] drm/i915: add attached connector to hdmi container Sonika Jindal
@ 2015-09-09 18:54   ` Rodrigo Vivi
  2015-09-10 15:24     ` Daniel Vetter
  0 siblings, 1 reply; 77+ messages in thread
From: Rodrigo Vivi @ 2015-09-09 18:54 UTC (permalink / raw)
  To: Sonika Jindal, intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 2090 bytes --]

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

On Fri, Sep 4, 2015 at 6:37 AM Sonika Jindal <sonika.jindal@intel.com>
wrote:

> From: Shashank Sharma <shashank.sharma@intel.com>
>
> This patch adds the intel_connector initialized to intel_hdmi
> display, during the init phase, just like the other encoders do.
> This attachment is very useful when we need to extract the connector
> pointer during the hotplug handler function
>
> Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_drv.h  |    1 +
>  drivers/gpu/drm/i915/intel_hdmi.c |    1 +
>  2 files changed, 2 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_drv.h
> b/drivers/gpu/drm/i915/intel_drv.h
> index c61ba47..b6c2c20 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -667,6 +667,7 @@ struct intel_hdmi {
>         enum hdmi_force_audio force_audio;
>         bool rgb_quant_range_selectable;
>         enum hdmi_picture_aspect aspect_ratio;
> +       struct intel_connector *attached_connector;
>         void (*write_infoframe)(struct drm_encoder *encoder,
>                                 enum hdmi_infoframe_type type,
>                                 const void *frame, ssize_t len);
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c
> b/drivers/gpu/drm/i915/intel_hdmi.c
> index ed25f64..5bdb386 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -2107,6 +2107,7 @@ void intel_hdmi_init_connector(struct
> intel_digital_port *intel_dig_port,
>
>         intel_connector_attach_encoder(intel_connector, intel_encoder);
>         drm_connector_register(connector);
> +       intel_hdmi->attached_connector = intel_connector;
>
>         /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be
> written
>          * 0xd.  Failure to do so will result in spurious interrupts being
> --
> 1.7.10.4
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>

[-- Attachment #1.2: Type: text/html, Size: 2908 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 2/6] drm/i915: Add HDMI probe function
  2015-09-04 14:48   ` Daniel Vetter
@ 2015-09-09 18:55     ` Rodrigo Vivi
  2015-09-11 10:45       ` Jindal, Sonika
  0 siblings, 1 reply; 77+ messages in thread
From: Rodrigo Vivi @ 2015-09-09 18:55 UTC (permalink / raw)
  To: Daniel Vetter, Sonika Jindal; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 6711 bytes --]

I liked the approach and agree with Daniel, so with his suggestions feel
free to use:
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

On Fri, Sep 4, 2015 at 7:46 AM Daniel Vetter <daniel@ffwll.ch> wrote:

> On Fri, Sep 04, 2015 at 06:56:12PM +0530, Sonika Jindal wrote:
> > From: Shashank Sharma <shashank.sharma@intel.com>
> >
> > This patch adds a separate probe function for HDMI
> > EDID read over DDC channel. This function has been
> > registered as a .hot_plug handler for HDMI encoder.
> >
> > The current implementation of hdmi_detect()
> > function re-sets the cached HDMI edid (in connector->detect_edid) in
> > every detect call.This function gets called many times, sometimes
> > directly from userspace probes, forcing drivers to read EDID every
> > detect function call.This causes several problems like:
> >
> > 1. Race conditions in multiple hot_plug / unplug cases, between
> >    interrupts bottom halves and userspace detections.
> > 2. Many Un-necessary EDID reads for single hotplug/unplug
> > 3. HDMI complaince failures which expects only one EDID read per hotplug
> >
> > This function will be serving the purpose of really reading the EDID
> > by really probing the DDC channel, and updating the cached EDID.
> >
> > The plan is to:
> > 1. i915 IRQ handler bottom half function already calls
> >    intel_encoder->hotplug() function. Adding This probe function which
> >    will read the EDID only in case of a hotplug / unplug.
> > 2. During init_connector his probe will be called to read the edid
> > 3. Reuse the cached EDID in hdmi_detect() function.
> >
> > The "< gen7" check is there because this was tested only for >=gen7
> > platforms. For older platforms the hotplug/reading edid path remains
> same.
> >
> > v2: Calling set_edid instead of hdmi_probe during init.
> > Also, for platforms having DDI, intel_encoder for DP and HDMI is same
> > (taken from intel_dig_port), so for DP also, hot_plug function gets
> called
> > which is not intended here. So, check for HDMI in intel_hdmi_probe
> > Rely on HPD for updating edid only for platforms gen > 8 and also for
> VLV.
> >
> > v3: Dropping the gen < 8 || !VLV  check. Now all platforms should rely on
> > hotplug or init for updating the edid.(Daniel)
> > Also, calling hdmi_probe in init instead of set_edid
> >
> > Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
> > Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_hdmi.c |   46
> ++++++++++++++++++++++++++++++++-----
> >  1 file changed, 40 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c
> b/drivers/gpu/drm/i915/intel_hdmi.c
> > index 5bdb386..1eda71a 100644
> > --- a/drivers/gpu/drm/i915/intel_hdmi.c
> > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> > @@ -1368,23 +1368,53 @@ intel_hdmi_set_edid(struct drm_connector
> *connector)
> >       return connected;
> >  }
> >
> > +void intel_hdmi_probe(struct intel_encoder *intel_encoder)
>
> Please call it _hot_plug if it's for the _hot_plug path.
>
> > +{
> > +     struct intel_hdmi *intel_hdmi =
> > +                     enc_to_intel_hdmi(&intel_encoder->base);
> > +     struct intel_connector *intel_connector =
> > +                             intel_hdmi->attached_connector;
> > +
> > +     /*
> > +      * We are here, means there is a hotplug or a force
> > +      * detection. Clear the cached EDID and probe the
> > +      * DDC bus to check the current status of HDMI.
> > +      */
> > +     intel_hdmi_unset_edid(&intel_connector->base);
> > +     if (intel_hdmi_set_edid(&intel_connector->base))
> > +             DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
> > +     else
> > +             DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
> > +}
> > +
> >  static enum drm_connector_status
> >  intel_hdmi_detect(struct drm_connector *connector, bool force)
> >  {
> >       enum drm_connector_status status;
> > +     struct intel_connector *intel_connector =
> > +                             to_intel_connector(connector);
> >
> >       DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> >                     connector->base.id, connector->name);
> > +     /*
> > +      * There are many userspace calls which probe EDID from
> > +      * detect path. In case of multiple hotplug/unplug, these
> > +      * can cause race conditions while probing EDID. Also its
> > +      * waste of CPU cycles to read the EDID again and again
> > +      * unless there is a real hotplug.
> > +      * So, rely on hotplugs and init to read edid.
> > +      * Check connector status based on availability of cached EDID.
> > +      */
> >
> > -     intel_hdmi_unset_edid(connector);
> > -
> > -     if (intel_hdmi_set_edid(connector)) {
> > +     if (intel_connector->detect_edid) {
> >               struct intel_hdmi *intel_hdmi =
> intel_attached_hdmi(connector);
> > -
> > -             hdmi_to_dig_port(intel_hdmi)->base.type =
> INTEL_OUTPUT_HDMI;
> >               status = connector_status_connected;
> > -     } else
> > +             hdmi_to_dig_port(intel_hdmi)->base.type =
> INTEL_OUTPUT_HDMI;
> > +             DRM_DEBUG_DRIVER("hdmi status = connected\n");
> > +     } else {
> >               status = connector_status_disconnected;
> > +             DRM_DEBUG_DRIVER("hdmi status = disconnected\n");
> > +     }
> >
> >       return status;
> >  }
> > @@ -2104,11 +2134,15 @@ void intel_hdmi_init_connector(struct
> intel_digital_port *intel_dig_port,
> >       intel_connector->unregister = intel_connector_unregister;
> >
> >       intel_hdmi_add_properties(intel_hdmi, connector);
> > +     intel_encoder->hot_plug = intel_hdmi_probe;
> >
> >       intel_connector_attach_encoder(intel_connector, intel_encoder);
> >       drm_connector_register(connector);
> >       intel_hdmi->attached_connector = intel_connector;
> >
> > +     /* Set edid during init */
> > +     intel_hdmi_probe(intel_encoder);
>
> Separate patch, but we really don't want this, initial probe should be
> done async to avoid stalling the driver.
> -Daniel
>
> > +
> >       /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be
> written
> >        * 0xd.  Failure to do so will result in spurious interrupts being
> >        * generated on the port when a cable is not attached.
> > --
> > 1.7.10.4
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>

[-- Attachment #1.2: Type: text/html, Size: 9009 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 3/6] drm/i915: Make intel_digital_port_connected global
  2015-09-04 13:26 ` [PATCH 3/6] drm/i915: Make intel_digital_port_connected global Sonika Jindal
@ 2015-09-09 18:57   ` Rodrigo Vivi
  2015-09-11 11:28     ` [PATCH] drm/i915/bxt: Use intel_encoder->hpd_pin to check live status Sonika Jindal
  0 siblings, 1 reply; 77+ messages in thread
From: Rodrigo Vivi @ 2015-09-09 18:57 UTC (permalink / raw)
  To: Sonika Jindal, intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 3225 bytes --]

On Fri, Sep 4, 2015 at 6:37 AM Sonika Jindal <sonika.jindal@intel.com>
wrote:

> This is to allow live status check for HDMI as well.
> Also, using intel_encoder->hpd_pin to check the live status
> for bxt because of BXT A0/A1 WA for HPD pins.
>

This is actually the only thing this patch does... So please use separated
patch for this....

But the global intel_digital_port connected can be done in the same patch
that uses it actually...


>
> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_dp.c  |   11 +++++++----
>  drivers/gpu/drm/i915/intel_drv.h |    2 ++
>  2 files changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c
> b/drivers/gpu/drm/i915/intel_dp.c
> index 796f930..fedf6d1 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -4663,11 +4663,14 @@ static bool vlv_digital_port_connected(struct
> drm_i915_private *dev_priv,
>  }
>
>  static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
> -                                      struct intel_digital_port *port)
> +                                      struct intel_digital_port
> *intel_dig_port)
>  {
> +       struct intel_encoder *intel_encoder = &intel_dig_port->base;
> +       enum port port;
>         u32 bit;
>
> -       switch (port->port) {
> +       intel_hpd_pin_to_port(intel_encoder->hpd_pin, &port);
> +       switch (port) {
>         case PORT_A:
>                 bit = BXT_DE_PORT_HP_DDIA;
>                 break;
> @@ -4678,7 +4681,7 @@ static bool bxt_digital_port_connected(struct
> drm_i915_private *dev_priv,
>                 bit = BXT_DE_PORT_HP_DDIC;
>                 break;
>         default:
> -               MISSING_CASE(port->port);
> +               MISSING_CASE(port);
>                 return false;
>         }
>
> @@ -4692,7 +4695,7 @@ static bool bxt_digital_port_connected(struct
> drm_i915_private *dev_priv,
>   *
>   * Return %true if @port is connected, %false otherwise.
>   */
> -static bool intel_digital_port_connected(struct drm_i915_private
> *dev_priv,
> +bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
>                                          struct intel_digital_port *port)
>  {
>         if (HAS_PCH_IBX(dev_priv))
> diff --git a/drivers/gpu/drm/i915/intel_drv.h
> b/drivers/gpu/drm/i915/intel_drv.h
> index b6c2c20..ac6d748 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1210,6 +1210,8 @@ void intel_edp_drrs_disable(struct intel_dp
> *intel_dp);
>  void intel_edp_drrs_invalidate(struct drm_device *dev,
>                 unsigned frontbuffer_bits);
>  void intel_edp_drrs_flush(struct drm_device *dev, unsigned
> frontbuffer_bits);
> +bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
> +                                        struct intel_digital_port *port);
>
>  /* intel_dp_mst.c */
>  int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port,
> int conn_id);
> --
> 1.7.10.4
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>

[-- Attachment #1.2: Type: text/html, Size: 4306 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 4/6] drm/i915: drm/i915: Check live status before reading edid
  2015-09-04 14:49   ` Daniel Vetter
  2015-09-07  5:02     ` [PATCH] " Sonika Jindal
@ 2015-09-09 19:11     ` Rodrigo Vivi
  2015-09-11 11:26       ` [PATCH] " Sonika Jindal
  1 sibling, 1 reply; 77+ messages in thread
From: Rodrigo Vivi @ 2015-09-09 19:11 UTC (permalink / raw)
  To: Daniel Vetter, Sonika Jindal; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 7462 bytes --]

On Fri, Sep 4, 2015 at 7:47 AM Daniel Vetter <daniel@ffwll.ch> wrote:

> On Fri, Sep 04, 2015 at 06:56:14PM +0530, Sonika Jindal wrote:
> > The Bspec is very clear that Live status must be checked about before
> > trying to read EDID over DDC channel. This patch makes sure that HDMI
> > EDID is read only when live status us up.
>

s/us/is


> >
> > The live status doesn't seem to perform very consistent across various
> > platforms when tested with different monitors. The reason behind that is
> > some monitors are late to provide right voltage to set live_status up.
> > So, after getting the interrupt, for a small duration, live status reg
> > fluctuates, and then settles down showing the correct staus.
> >
> > This is explained here in, in a rough way:
> > HPD line  ________________
> >                        |\ T1 = Monitor Hotplug causing IRQ
> >                        | \______________________________________
> >                        | |
> >                          | |
> >                        | |   T2 = Live status is stable
> >                        | |  _____________________________________
> >                        | | /|
> > Live status _____________|_|/ |
> >                        | |  |
> >                        | |  |
> >                        | |  |
> >                       T0 T1  T2
> >
> > (Between T1 and T2 Live status fluctuates or can be even low, depending
> on
> >  the monitor)
> >
> > After several experiments, we have concluded that a max delay
> > of 30ms is enough to allow the live status to settle down with
> > most of the monitors. This total delay of 30ms has been split into
> > a resolution of 3 retries of 10ms each, for the better cases.
> >
> > This delay is kept at 30ms, keeping in consideration that, HDCP
> compliance
> > expect the HPD handler to respond a plug out in 100ms, by disabling the
> port.
> >
> > v2: Adding checks for VLV/CHV as well. Reusing old ibx and g4x functions
> > to check digital port status. Adding a separate function to get bxt live
> > status (Daniel)
> > v3: Using intel_encoder->hpd_pin to check the live status (Siva)
> > Moving the live status read to intel_hdmi_probe and passing parameter
> > to read/not to read the edid. (me)
> > v4:
> > * Added live status check for all platforms using
> > intel_digital_port_connected.
> > * Rebased on top of Jani's DP cleanup series
> > * Some monitors take time in setting the live status. So retry for few
> > times if this is a connect HPD
> >
> > Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
>
> Really pretty commit message! Had some minor comments on two other patches
> in this series while reading through them, but looks good otherwise.
> Please sign up someone for final review of the details and I'll pull in
> the patches once that's done.
> -Daniel
>
> > ---
> >  drivers/gpu/drm/i915/intel_hdmi.c |   35
> ++++++++++++++++++++++++++++-------
> >  1 file changed, 28 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c
> b/drivers/gpu/drm/i915/intel_hdmi.c
> > index 1eda71a..d82887b 100644
> > --- a/drivers/gpu/drm/i915/intel_hdmi.c
> > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> > @@ -1329,22 +1329,23 @@ intel_hdmi_unset_edid(struct drm_connector
> *connector)
> >  }
> >
> >  static bool
> > -intel_hdmi_set_edid(struct drm_connector *connector)
> > +intel_hdmi_set_edid(struct drm_connector *connector, bool force)
> >  {
> >       struct drm_i915_private *dev_priv = to_i915(connector->dev);
> >       struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
> >       struct intel_encoder *intel_encoder =
> >               &hdmi_to_dig_port(intel_hdmi)->base;
> >       enum intel_display_power_domain power_domain;
> > -     struct edid *edid;
> > +     struct edid *edid = NULL;
> >       bool connected = false;
> >
> >       power_domain = intel_display_port_power_domain(intel_encoder);
> >       intel_display_power_get(dev_priv, power_domain);
> >
> > -     edid = drm_get_edid(connector,
> > -                         intel_gmbus_get_adapter(dev_priv,
> > -                                                 intel_hdmi->ddc_bus));
> > +     if (force)
>

The force name is confusing here since you only don't get edid in any other
way when it is false...

But also there is the risk of this function to get called only with this
false and never gets edid..
So I believe we should add a debug message here at least for this case so
if we start getting cases where panel is taking more than 30ms to get live
we will know why we did't actually read the edid....


> > +             edid = drm_get_edid(connector,
> > +                                 intel_gmbus_get_adapter(dev_priv,
> > +                                 intel_hdmi->ddc_bus));
> >
> >       intel_display_power_put(dev_priv, power_domain);
> >
> > @@ -1374,6 +1375,26 @@ void intel_hdmi_probe(struct intel_encoder
> *intel_encoder)
> >                       enc_to_intel_hdmi(&intel_encoder->base);
> >       struct intel_connector *intel_connector =
> >                               intel_hdmi->attached_connector;
> > +     struct drm_i915_private *dev_priv =
> to_i915(intel_encoder->base.dev);
> > +     bool live_status = false;
> > +     unsigned int retry = 3;
> > +
> > +     live_status = intel_digital_port_connected(dev_priv,
> > +
> hdmi_to_dig_port(intel_hdmi));
> > +     if (!intel_connector->detect_edid && live_status == false) {
> > +             /*
> > +              * Hotplug had occurred and old status was disconnected,
> > +              * so it might be possible that live status is not set,
> > +              * so retry for few times
> > +              */
> > +             do {
> > +                     mdelay(10);
> > +                     live_status =
> intel_digital_port_connected(dev_priv,
> > +
>  hdmi_to_dig_port(intel_hdmi));
> > +                     if (live_status)
> > +                             break;
> > +             } while (retry--);
>

small and optional bikesheding here: I'd do:
while(!live_status && --retry) {
 mdelay(10);
live_status = ...
}


> > +     }
> >
> >       /*
> >        * We are here, means there is a hotplug or a force
> > @@ -1381,7 +1402,7 @@ void intel_hdmi_probe(struct intel_encoder
> *intel_encoder)
> >        * DDC bus to check the current status of HDMI.
> >        */
> >       intel_hdmi_unset_edid(&intel_connector->base);
> > -     if (intel_hdmi_set_edid(&intel_connector->base))
> > +     if (intel_hdmi_set_edid(&intel_connector->base, live_status))
> >               DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
> >       else
> >               DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
> > @@ -1432,7 +1453,7 @@ intel_hdmi_force(struct drm_connector *connector)
> >       if (connector->status != connector_status_connected)
> >               return;
> >
> > -     intel_hdmi_set_edid(connector);
> > +     intel_hdmi_set_edid(connector, true);
> >       hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
> >  }
> >
> > --
> > 1.7.10.4
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>

[-- Attachment #1.2: Type: text/html, Size: 10324 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 5/6] drm/i915: drm/i915: Process hpd only for hdmi inside hotplug_work_func
  2015-09-06  4:31     ` Jindal, Sonika
  2015-09-07  5:04       ` [PATCH] drm/i915: Call encoder hot_plug hook only for hdmi Sonika Jindal
@ 2015-09-09 19:20       ` Rodrigo Vivi
  2015-09-09 23:37         ` Jindal, Sonika
  1 sibling, 1 reply; 77+ messages in thread
From: Rodrigo Vivi @ 2015-09-09 19:20 UTC (permalink / raw)
  To: Jindal, Sonika, Daniel Vetter; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 3020 bytes --]

I was also going to say that I believe this breaks DP hotplug, but this was
agreed already...

But I also don't understand how hot_plug is called twice since it calls
encoder->hot_plug...
and dp has no ->hot_plug...
And also if this is happening how this code that checks for connector would
help... there is something else strange happening...



On Sat, Sep 5, 2015 at 9:31 PM Jindal, Sonika <sonika.jindal@intel.com>
wrote:

>
>
> On 9/4/2015 8:17 PM, Daniel Vetter wrote:
> > On Fri, Sep 04, 2015 at 06:56:15PM +0530, Sonika Jindal wrote:
> >> If the same port is enumerated as hdmi as well as DP, this will get
> >> called for DP connector as well which is not required because
> >> i915_hotplug_work_func is solely to handle hdmi HPD.
> >>
> >> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> >> ---
> >>   drivers/gpu/drm/i915/intel_hotplug.c |    3 ++-
> >>   1 file changed, 2 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/intel_hotplug.c
> b/drivers/gpu/drm/i915/intel_hotplug.c
> >> index 53c0173..8e1c43e 100644
> >> --- a/drivers/gpu/drm/i915/intel_hotplug.c
> >> +++ b/drivers/gpu/drm/i915/intel_hotplug.c
> >> @@ -325,7 +325,8 @@ static void i915_hotplug_work_func(struct
> work_struct *work)
> >>
> >>      list_for_each_entry(connector, &mode_config->connector_list, head)
> {
> >>              intel_connector = to_intel_connector(connector);
> >> -            if (!intel_connector->encoder)
> >> +            if (!intel_connector->encoder
> >> +                    && connector->connector_type !=
> DRM_MODE_CONNECTOR_HDMIA)
> >>                      continue;
> >
> > Pretty sure this breaks hotplug detection for everything but HDMI (since
> > now nothing but hdmi gets called it's ->detect function, and only if that
> > signals a status change will we send out an uevent to userspace). Does
> > this really not break DP hotplug?
> >
> > Yes we probe both hdmi and DP always, and probably we could be more
> > intelligent with the fallback between the too. But this here doesn't seem
> > to be the right solution.
> > -Daniel
>
> Hmm :(
> This doesn't allow detect to be called for dp. I missed the part that
> hpd_pulse only handles mst. From the name and comments it looks like it
> should handle hpd for dp completely. I think this this code needs some
> refactoring.
>
> For now, I think I better move this check to intel_encoder->hot_plug
> function because for the connectors with dp and hdmi both, this hot_plug
> hook gets called twice.
>
> >
> >>              intel_encoder = intel_connector->encoder;
> >>              if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) {
> >> --
> >> 1.7.10.4
> >>
> >> _______________________________________________
> >> Intel-gfx mailing list
> >> Intel-gfx@lists.freedesktop.org
> >> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> >
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>

[-- Attachment #1.2: Type: text/html, Size: 4280 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 6/6] drm/i915/bxt: Fix irq_port for eDP
  2015-09-04 13:26 ` [PATCH 6/6] drm/i915/bxt: Fix irq_port for eDP Sonika Jindal
@ 2015-09-09 19:24   ` Rodrigo Vivi
  2015-09-10 10:49     ` Jindal, Sonika
  2015-09-10 13:07     ` R, Durgadoss
  0 siblings, 2 replies; 77+ messages in thread
From: Rodrigo Vivi @ 2015-09-09 19:24 UTC (permalink / raw)
  To: Sonika Jindal, intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 2694 bytes --]

Nak: I don't believe we need this... Actually I believe we need the
opposite... we need to enable HPD on port A for eDP errors handling...




On Fri, Sep 4, 2015 at 6:38 AM Sonika Jindal <sonika.jindal@intel.com>
wrote:

> From: Durgadoss R <durgadoss.r@intel.com>
>
> Currently, HDMI hotplug with eDP as local panel is failing
> because the HDMI hpd is detected as a long hpd for eDP; and is
> thus rightfully ignored. But, it should really be handled as
> an interrupt on port B for HDMI (due to BXT A1 platform having
> HPD pins A and B swapped). This patch sets the irq_port[PORT_A]
> to NULL in case eDP is on port A so that irq handler does not
> treat it as a 'dig_port' interrupt.
>
> Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c |   15 ++++++++++-----
>  1 file changed, 10 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c
> b/drivers/gpu/drm/i915/intel_ddi.c
> index 4823184..fec51df 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -3218,15 +3218,20 @@ void intel_ddi_init(struct drm_device *dev, enum
> port port)
>                         goto err;
>
>                 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
> +               dev_priv->hotplug.irq_port[port] = intel_dig_port;
>                 /*
>                  * On BXT A0/A1, sw needs to activate DDIA HPD logic and
>                  * interrupts to check the external panel connection.
> +                * If eDP is connected on port A, set irq_port to NULL
> +                * so that we do not assume an interrupt here as a
> +                * 'dig_port' interrupt.
>                  */
> -               if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) <
> BXT_REVID_B0)
> -                                        && port == PORT_B)
> -                       dev_priv->hotplug.irq_port[PORT_A] =
> intel_dig_port;
> -               else
> -                       dev_priv->hotplug.irq_port[port] = intel_dig_port;
> +               if (IS_BROXTON(dev) && (INTEL_REVID(dev) < BXT_REVID_B0)) {
> +                       if (port == PORT_B)
> +                               dev_priv->hotplug.irq_port[PORT_A] =
> intel_dig_port;
> +                       else if (intel_encoder->type == INTEL_OUTPUT_EDP)
> +                               dev_priv->hotplug.irq_port[port] = NULL;
> +               }
>         }
>
>         /* In theory we don't need the encoder->type check, but leave it
> just in
> --
> 1.7.10.4
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>

[-- Attachment #1.2: Type: text/html, Size: 3740 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 5/6] drm/i915: drm/i915: Process hpd only for hdmi inside hotplug_work_func
  2015-09-09 19:20       ` [PATCH 5/6] drm/i915: drm/i915: Process hpd only for hdmi inside hotplug_work_func Rodrigo Vivi
@ 2015-09-09 23:37         ` Jindal, Sonika
  0 siblings, 0 replies; 77+ messages in thread
From: Jindal, Sonika @ 2015-09-09 23:37 UTC (permalink / raw)
  To: Rodrigo Vivi, Daniel Vetter; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 4250 bytes --]

Since, the port is enumerated as DP as well as hdmi, the init connector is called for both and the same intel encoder gets attached to both the connectors.
Now the intel_encoder’s type could be a differentiator. But since, hdmi’s detect gets called, the type of the encoder remains hdmi.
When hpd occurs, it checks from the list of connectors whose hpd pin is same as the one asserted.
Since both dp and hdmi are INITed, both the connectors have that pin and since DP’s connector is first in the list, it calls the ->hot_plug once when it finds DP connector matching and then again when HDMI connector is found matching as per the pin.

This code check will avoid calling in the case when we have found the DP connector because we are sure that there is no ->hot_plug hook for DP.
Anyways, that was not a generic implementation.

Regards,
Sonika

From: Rodrigo Vivi [mailto:rodrigo.vivi@gmail.com]
Sent: Thursday, September 10, 2015 12:51 AM
To: Jindal, Sonika; Daniel Vetter
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH 5/6] drm/i915: drm/i915: Process hpd only for hdmi inside hotplug_work_func

I was also going to say that I believe this breaks DP hotplug, but this was agreed already...

But I also don't understand how hot_plug is called twice since it calls encoder->hot_plug...
and dp has no ->hot_plug...
And also if this is happening how this code that checks for connector would help... there is something else strange happening...



On Sat, Sep 5, 2015 at 9:31 PM Jindal, Sonika <sonika.jindal@intel.com<mailto:sonika.jindal@intel.com>> wrote:


On 9/4/2015 8:17 PM, Daniel Vetter wrote:
> On Fri, Sep 04, 2015 at 06:56:15PM +0530, Sonika Jindal wrote:
>> If the same port is enumerated as hdmi as well as DP, this will get
>> called for DP connector as well which is not required because
>> i915_hotplug_work_func is solely to handle hdmi HPD.
>>
>> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com<mailto:sonika.jindal@intel.com>>
>> ---
>>   drivers/gpu/drm/i915/intel_hotplug.c |    3 ++-
>>   1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
>> index 53c0173..8e1c43e 100644
>> --- a/drivers/gpu/drm/i915/intel_hotplug.c
>> +++ b/drivers/gpu/drm/i915/intel_hotplug.c
>> @@ -325,7 +325,8 @@ static void i915_hotplug_work_func(struct work_struct *work)
>>
>>      list_for_each_entry(connector, &mode_config->connector_list, head) {
>>              intel_connector = to_intel_connector(connector);
>> -            if (!intel_connector->encoder)
>> +            if (!intel_connector->encoder
>> +                    && connector->connector_type != DRM_MODE_CONNECTOR_HDMIA)
>>                      continue;
>
> Pretty sure this breaks hotplug detection for everything but HDMI (since
> now nothing but hdmi gets called it's ->detect function, and only if that
> signals a status change will we send out an uevent to userspace). Does
> this really not break DP hotplug?
>
> Yes we probe both hdmi and DP always, and probably we could be more
> intelligent with the fallback between the too. But this here doesn't seem
> to be the right solution.
> -Daniel

Hmm :(
This doesn't allow detect to be called for dp. I missed the part that
hpd_pulse only handles mst. From the name and comments it looks like it
should handle hpd for dp completely. I think this this code needs some
refactoring.

For now, I think I better move this check to intel_encoder->hot_plug
function because for the connectors with dp and hdmi both, this hot_plug
hook gets called twice.

>
>>              intel_encoder = intel_connector->encoder;
>>              if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) {
>> --
>> 1.7.10.4
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org<mailto:Intel-gfx@lists.freedesktop.org>
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org<mailto:Intel-gfx@lists.freedesktop.org>
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

[-- Attachment #1.2: Type: text/html, Size: 9468 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915: Call encoder hot_plug hook only for hdmi
  2015-09-09 15:17               ` Daniel Vetter
@ 2015-09-10  1:07                 ` Jindal, Sonika
  2015-09-10 14:47                   ` Daniel Vetter
  0 siblings, 1 reply; 77+ messages in thread
From: Jindal, Sonika @ 2015-09-10  1:07 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx



-----Original Message-----
From: Daniel Vetter [mailto:daniel.vetter@ffwll.ch] On Behalf Of Daniel Vetter
Sent: Wednesday, September 9, 2015 8:48 PM
To: Jindal, Sonika
Cc: Daniel Vetter; intel-gfx@lists.freedesktop.org; Sharma, Shashank
Subject: Re: [Intel-gfx] [PATCH] drm/i915: Call encoder hot_plug hook only for hdmi

On Tue, Sep 08, 2015 at 05:08:02PM +0530, Jindal, Sonika wrote:
> 
> 
> On 9/8/2015 10:12 AM, Jindal, Sonika wrote:
> >
> >
> >On 9/7/2015 9:56 PM, Daniel Vetter wrote:
> >>On Mon, Sep 07, 2015 at 10:34:34AM +0530, Sonika Jindal wrote:
> >>>If the same port is enumerated as hdmi as well as DP, this will 
> >>>call hot_plug hook for DP as well which is not required here.
> >>>This splitting of edid read and detect is done only for HDMI with 
> >>>this series.
> >>>
> >>>v2: Avoid breaking DP hpd. Also corrected the commit message and 
> >>>description accordingly. (Daniel)
> >>>
> >>>Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> >>>---
> >>>  drivers/gpu/drm/i915/intel_hotplug.c |    3 ++-
> >>>  1 file changed, 2 insertions(+), 1 deletion(-)
> >>>
> >>>diff --git a/drivers/gpu/drm/i915/intel_hotplug.c
> >>>b/drivers/gpu/drm/i915/intel_hotplug.c
> >>>index 53c0173..ff4692a 100644
> >>>--- a/drivers/gpu/drm/i915/intel_hotplug.c
> >>>+++ b/drivers/gpu/drm/i915/intel_hotplug.c
> >>>@@ -331,7 +331,8 @@ static void i915_hotplug_work_func(struct 
> >>>work_struct *work)
> >>>          if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) {
> >>>              DRM_DEBUG_KMS("Connector %s (pin %i) received hotplug 
> >>>event.\n",
> >>>                        connector->name, intel_encoder->hpd_pin);
> >>>-            if (intel_encoder->hot_plug)
> >>>+            if (intel_encoder->hot_plug
> >>>+                && connector->connector_type ==
> >>>DRM_MODE_CONNECTOR_HDMIA)
> >>
> >>Please use something like grep to find all the other ->hot_plug 
> >>implementations and then please tell me why you don't break them all.
> >>-Daniel
> >>
> >Hmm, I only checked for hot_plug for DP/edp which is not there. 
> >Failed to notice that there is one in intel_sdvo.c.
> >My mistake. I will place it properly somewhere else.
> >
> >Regards,
> >Sonika
> 
> Is there any suggestion about how we can differentiate if it is actual 
> DP or HDMI hotplug at this point? intel_encoder's type gets updated 
> after detect call. So, not sure how to have this kind of check.
> 
> For now, I think we can abandon this patch from this series.

No, hpd is shared between hdmi and dp at the hw level so we can't differentiate. Long term my idea would be that we merge together all the hdmi _and_ dp hpd handling into one overall control-flow. Then we can make sure to not call anything twice and also have sensible high-level flow (like first checking for dp vs. hdmi and then taking relevant paths).

For dealing with ->hot_plug a quick fix might be to have a separate loop going over encoders (to make sure we only call it once per encoder if there's more than one connector for 1 encoder). That behaviour would also be ok for sdvo.

<Sonika> Hmm, so instead of relying on connector, we can check for the hpd_pin on encoder and remove the connector loop completely?

-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 6/6] drm/i915/bxt: Fix irq_port for eDP
  2015-09-09 19:24   ` Rodrigo Vivi
@ 2015-09-10 10:49     ` Jindal, Sonika
  2015-09-10 13:07     ` R, Durgadoss
  1 sibling, 0 replies; 77+ messages in thread
From: Jindal, Sonika @ 2015-09-10 10:49 UTC (permalink / raw)
  To: Rodrigo Vivi, intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 3208 bytes --]

All this is because of the BXT A0/A1 workaround for HPD pins.
As you can see, this is only done for BXT A0/A1 and can be removed when we have newer stable steppings.
Durga can add more..

Regards,
Sonika

From: Rodrigo Vivi [mailto:rodrigo.vivi@gmail.com]
Sent: Thursday, September 10, 2015 12:54 AM
To: Jindal, Sonika; intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH 6/6] drm/i915/bxt: Fix irq_port for eDP

Nak: I don't believe we need this... Actually I believe we need the opposite... we need to enable HPD on port A for eDP errors handling...




On Fri, Sep 4, 2015 at 6:38 AM Sonika Jindal <sonika.jindal@intel.com<mailto:sonika.jindal@intel.com>> wrote:
From: Durgadoss R <durgadoss.r@intel.com<mailto:durgadoss.r@intel.com>>

Currently, HDMI hotplug with eDP as local panel is failing
because the HDMI hpd is detected as a long hpd for eDP; and is
thus rightfully ignored. But, it should really be handled as
an interrupt on port B for HDMI (due to BXT A1 platform having
HPD pins A and B swapped). This patch sets the irq_port[PORT_A]
to NULL in case eDP is on port A so that irq handler does not
treat it as a 'dig_port' interrupt.

Signed-off-by: Durgadoss R <durgadoss.r@intel.com<mailto:durgadoss.r@intel.com>>
---
 drivers/gpu/drm/i915/intel_ddi.c |   15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 4823184..fec51df 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -3218,15 +3218,20 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
                        goto err;

                intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
+               dev_priv->hotplug.irq_port[port] = intel_dig_port;
                /*
                 * On BXT A0/A1, sw needs to activate DDIA HPD logic and
                 * interrupts to check the external panel connection.
+                * If eDP is connected on port A, set irq_port to NULL
+                * so that we do not assume an interrupt here as a
+                * 'dig_port' interrupt.
                 */
-               if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)
-                                        && port == PORT_B)
-                       dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
-               else
-                       dev_priv->hotplug.irq_port[port] = intel_dig_port;
+               if (IS_BROXTON(dev) && (INTEL_REVID(dev) < BXT_REVID_B0)) {
+                       if (port == PORT_B)
+                               dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
+                       else if (intel_encoder->type == INTEL_OUTPUT_EDP)
+                               dev_priv->hotplug.irq_port[port] = NULL;
+               }
        }

        /* In theory we don't need the encoder->type check, but leave it just in
--
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org<mailto:Intel-gfx@lists.freedesktop.org>
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

[-- Attachment #1.2: Type: text/html, Size: 8275 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [PATCH 6/6] drm/i915/bxt: Fix irq_port for eDP
  2015-09-09 19:24   ` Rodrigo Vivi
  2015-09-10 10:49     ` Jindal, Sonika
@ 2015-09-10 13:07     ` R, Durgadoss
  2015-09-10 13:35       ` Ville Syrjälä
  1 sibling, 1 reply; 77+ messages in thread
From: R, Durgadoss @ 2015-09-10 13:07 UTC (permalink / raw)
  To: Rodrigo Vivi, Jindal, Sonika, intel-gfx

Hi Rodrigo,

I had to add this to get HDMI hotplug working on BXT.
As you might already know, we have the HPD pins A & B
swapped in BXT. And, we are using HPD_PORT_A as
'intel_encoder->hpd_pin' for HDMI on port B.

Without this, When an HPD on HDMI (port B) happens, the interrupt
is handled as an eDP (port A) interrupt in 'intel_hpd_irq_handler',
since hpd_pin for HDMI port B is set as PIN A.

Snippet:
---
is_dig_port = intel_hpd_pin_to_port(i, &port) &&
                               dev_priv->hotplug.irq_port[port];

---

The issue occurs only when we have eDP + HDMI combination.
MIPI + HDMI works well without this fix also.

And all these workarounds, are due to pin swap in
BXT A0/A1. We have this fix enclosed with that check as well.

I tried to few other changes, but this one was less intrusive
and easy to change (and notice the change).
Kindly let us know if you have better ideas.

Thanks,
Durga

From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of Rodrigo Vivi
Sent: Thursday, September 10, 2015 12:54 AM
To: Jindal, Sonika; intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH 6/6] drm/i915/bxt: Fix irq_port for eDP

Nak: I don't believe we need this... Actually I believe we need the opposite... we need to enable HPD on port A for eDP errors handling...




On Fri, Sep 4, 2015 at 6:38 AM Sonika Jindal <sonika.jindal@intel.com> wrote:
From: Durgadoss R <durgadoss.r@intel.com>

Currently, HDMI hotplug with eDP as local panel is failing
because the HDMI hpd is detected as a long hpd for eDP; and is
thus rightfully ignored. But, it should really be handled as
an interrupt on port B for HDMI (due to BXT A1 platform having
HPD pins A and B swapped). This patch sets the irq_port[PORT_A]
to NULL in case eDP is on port A so that irq handler does not
treat it as a 'dig_port' interrupt.

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c |   15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 4823184..fec51df 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -3218,15 +3218,20 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
                        goto err;

                intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
+               dev_priv->hotplug.irq_port[port] = intel_dig_port;
                /*
                 * On BXT A0/A1, sw needs to activate DDIA HPD logic and
                 * interrupts to check the external panel connection.
+                * If eDP is connected on port A, set irq_port to NULL
+                * so that we do not assume an interrupt here as a
+                * 'dig_port' interrupt.
                 */
-               if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)
-                                        && port == PORT_B)
-                       dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
-               else
-                       dev_priv->hotplug.irq_port[port] = intel_dig_port;
+               if (IS_BROXTON(dev) && (INTEL_REVID(dev) < BXT_REVID_B0)) {
+                       if (port == PORT_B)
+                               dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
+                       else if (intel_encoder->type == INTEL_OUTPUT_EDP)
+                               dev_priv->hotplug.irq_port[port] = NULL;
+               }
        }

        /* In theory we don't need the encoder->type check, but leave it just in
--
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [PATCH 6/6] drm/i915/bxt: Fix irq_port for eDP
  2015-09-10 13:07     ` R, Durgadoss
@ 2015-09-10 13:35       ` Ville Syrjälä
  2015-09-10 14:51         ` Daniel Vetter
  0 siblings, 1 reply; 77+ messages in thread
From: Ville Syrjälä @ 2015-09-10 13:35 UTC (permalink / raw)
  To: R, Durgadoss; +Cc: intel-gfx

On Thu, Sep 10, 2015 at 01:07:30PM +0000, R, Durgadoss wrote:
> Hi Rodrigo,
> 
> I had to add this to get HDMI hotplug working on BXT.
> As you might already know, we have the HPD pins A & B
> swapped in BXT. And, we are using HPD_PORT_A as
> 'intel_encoder->hpd_pin' for HDMI on port B.

People keep saying that, but according to the spec it's not
even true. A and B are not swapped, but instead all the pins
are sort of shifted by one position.

HPD A = DDI0 / port B
HPD B = DDI1 / port C
HPD C = DDI2 / port A

If the code actually did the remapping in a way that matches
the spec, things would be a lot less confusing.

> 
> Without this, When an HPD on HDMI (port B) happens, the interrupt
> is handled as an eDP (port A) interrupt in 'intel_hpd_irq_handler',
> since hpd_pin for HDMI port B is set as PIN A.
> 
> Snippet:
> ---
> is_dig_port = intel_hpd_pin_to_port(i, &port) &&
>                                dev_priv->hotplug.irq_port[port];
> 
> ---
> 
> The issue occurs only when we have eDP + HDMI combination.
> MIPI + HDMI works well without this fix also.
> 
> And all these workarounds, are due to pin swap in
> BXT A0/A1. We have this fix enclosed with that check as well.
> 
> I tried to few other changes, but this one was less intrusive
> and easy to change (and notice the change).
> Kindly let us know if you have better ideas.
> 
> Thanks,
> Durga
> 
> From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of Rodrigo Vivi
> Sent: Thursday, September 10, 2015 12:54 AM
> To: Jindal, Sonika; intel-gfx@lists.freedesktop.org
> Subject: Re: [Intel-gfx] [PATCH 6/6] drm/i915/bxt: Fix irq_port for eDP
> 
> Nak: I don't believe we need this... Actually I believe we need the opposite... we need to enable HPD on port A for eDP errors handling...
> 
> 
> 
> 
> On Fri, Sep 4, 2015 at 6:38 AM Sonika Jindal <sonika.jindal@intel.com> wrote:
> From: Durgadoss R <durgadoss.r@intel.com>
> 
> Currently, HDMI hotplug with eDP as local panel is failing
> because the HDMI hpd is detected as a long hpd for eDP; and is
> thus rightfully ignored. But, it should really be handled as
> an interrupt on port B for HDMI (due to BXT A1 platform having
> HPD pins A and B swapped). This patch sets the irq_port[PORT_A]
> to NULL in case eDP is on port A so that irq handler does not
> treat it as a 'dig_port' interrupt.
> 
> Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c |   15 ++++++++++-----
>  1 file changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 4823184..fec51df 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -3218,15 +3218,20 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
>                         goto err;
> 
>                 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
> +               dev_priv->hotplug.irq_port[port] = intel_dig_port;
>                 /*
>                  * On BXT A0/A1, sw needs to activate DDIA HPD logic and
>                  * interrupts to check the external panel connection.
> +                * If eDP is connected on port A, set irq_port to NULL
> +                * so that we do not assume an interrupt here as a
> +                * 'dig_port' interrupt.
>                  */
> -               if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)
> -                                        && port == PORT_B)
> -                       dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
> -               else
> -                       dev_priv->hotplug.irq_port[port] = intel_dig_port;
> +               if (IS_BROXTON(dev) && (INTEL_REVID(dev) < BXT_REVID_B0)) {
> +                       if (port == PORT_B)
> +                               dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
> +                       else if (intel_encoder->type == INTEL_OUTPUT_EDP)
> +                               dev_priv->hotplug.irq_port[port] = NULL;
> +               }
>         }
> 
>         /* In theory we don't need the encoder->type check, but leave it just in
> --
> 1.7.10.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915: Call encoder hot_plug hook only for hdmi
  2015-09-10  1:07                 ` Jindal, Sonika
@ 2015-09-10 14:47                   ` Daniel Vetter
  0 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2015-09-10 14:47 UTC (permalink / raw)
  To: Jindal, Sonika; +Cc: intel-gfx

On Thu, Sep 10, 2015 at 01:07:18AM +0000, Jindal, Sonika wrote:
> 
> 
> -----Original Message-----
> From: Daniel Vetter [mailto:daniel.vetter@ffwll.ch] On Behalf Of Daniel Vetter
> Sent: Wednesday, September 9, 2015 8:48 PM
> To: Jindal, Sonika
> Cc: Daniel Vetter; intel-gfx@lists.freedesktop.org; Sharma, Shashank
> Subject: Re: [Intel-gfx] [PATCH] drm/i915: Call encoder hot_plug hook only for hdmi
> 
> On Tue, Sep 08, 2015 at 05:08:02PM +0530, Jindal, Sonika wrote:
> > 
> > 
> > On 9/8/2015 10:12 AM, Jindal, Sonika wrote:
> > >
> > >
> > >On 9/7/2015 9:56 PM, Daniel Vetter wrote:
> > >>On Mon, Sep 07, 2015 at 10:34:34AM +0530, Sonika Jindal wrote:
> > >>>If the same port is enumerated as hdmi as well as DP, this will 
> > >>>call hot_plug hook for DP as well which is not required here.
> > >>>This splitting of edid read and detect is done only for HDMI with 
> > >>>this series.
> > >>>
> > >>>v2: Avoid breaking DP hpd. Also corrected the commit message and 
> > >>>description accordingly. (Daniel)
> > >>>
> > >>>Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> > >>>---
> > >>>  drivers/gpu/drm/i915/intel_hotplug.c |    3 ++-
> > >>>  1 file changed, 2 insertions(+), 1 deletion(-)
> > >>>
> > >>>diff --git a/drivers/gpu/drm/i915/intel_hotplug.c
> > >>>b/drivers/gpu/drm/i915/intel_hotplug.c
> > >>>index 53c0173..ff4692a 100644
> > >>>--- a/drivers/gpu/drm/i915/intel_hotplug.c
> > >>>+++ b/drivers/gpu/drm/i915/intel_hotplug.c
> > >>>@@ -331,7 +331,8 @@ static void i915_hotplug_work_func(struct 
> > >>>work_struct *work)
> > >>>          if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) {
> > >>>              DRM_DEBUG_KMS("Connector %s (pin %i) received hotplug 
> > >>>event.\n",
> > >>>                        connector->name, intel_encoder->hpd_pin);
> > >>>-            if (intel_encoder->hot_plug)
> > >>>+            if (intel_encoder->hot_plug
> > >>>+                && connector->connector_type ==
> > >>>DRM_MODE_CONNECTOR_HDMIA)
> > >>
> > >>Please use something like grep to find all the other ->hot_plug 
> > >>implementations and then please tell me why you don't break them all.
> > >>-Daniel
> > >>
> > >Hmm, I only checked for hot_plug for DP/edp which is not there. 
> > >Failed to notice that there is one in intel_sdvo.c.
> > >My mistake. I will place it properly somewhere else.
> > >
> > >Regards,
> > >Sonika
> > 
> > Is there any suggestion about how we can differentiate if it is actual 
> > DP or HDMI hotplug at this point? intel_encoder's type gets updated 
> > after detect call. So, not sure how to have this kind of check.
> > 
> > For now, I think we can abandon this patch from this series.
> 
> No, hpd is shared between hdmi and dp at the hw level so we can't
> differentiate. Long term my idea would be that we merge together all the
> hdmi _and_ dp hpd handling into one overall control-flow. Then we can
> make sure to not call anything twice and also have sensible high-level
> flow (like first checking for dp vs. hdmi and then taking relevant
> paths).
> 
> For dealing with ->hot_plug a quick fix might be to have a separate loop
> going over encoders (to make sure we only call it once per encoder if
> there's more than one connector for 1 encoder). That behaviour would
> also be ok for sdvo.
> 
> <Sonika> Hmm, so instead of relying on connector, we can check for the
> hpd_pin on encoder and remove the connector loop completely?

That would be my suggestion, but I didn't check the details.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 6/6] drm/i915/bxt: Fix irq_port for eDP
  2015-09-10 13:35       ` Ville Syrjälä
@ 2015-09-10 14:51         ` Daniel Vetter
  0 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2015-09-10 14:51 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Thu, Sep 10, 2015 at 04:35:57PM +0300, Ville Syrjälä wrote:
> On Thu, Sep 10, 2015 at 01:07:30PM +0000, R, Durgadoss wrote:
> > Hi Rodrigo,
> > 
> > I had to add this to get HDMI hotplug working on BXT.
> > As you might already know, we have the HPD pins A & B
> > swapped in BXT. And, we are using HPD_PORT_A as
> > 'intel_encoder->hpd_pin' for HDMI on port B.
> 
> People keep saying that, but according to the spec it's not
> even true. A and B are not swapped, but instead all the pins
> are sort of shifted by one position.
> 
> HPD A = DDI0 / port B
> HPD B = DDI1 / port C
> HPD C = DDI2 / port A
> 
> If the code actually did the remapping in a way that matches
> the spec, things would be a lot less confusing.

And we even have the logic to allow that remapping, so I guess the real
job is to figure out where that's not done correctly. Not throwing more
hacks on top.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 1/6] drm/i915: add attached connector to hdmi container
  2015-09-09 18:54   ` Rodrigo Vivi
@ 2015-09-10 15:24     ` Daniel Vetter
  0 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2015-09-10 15:24 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

On Wed, Sep 09, 2015 at 06:54:17PM +0000, Rodrigo Vivi wrote:
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> 
> On Fri, Sep 4, 2015 at 6:37 AM Sonika Jindal <sonika.jindal@intel.com>
> wrote:
> 
> > From: Shashank Sharma <shashank.sharma@intel.com>
> >
> > This patch adds the intel_connector initialized to intel_hdmi
> > display, during the init phase, just like the other encoders do.
> > This attachment is very useful when we need to extract the connector
> > pointer during the hotplug handler function
> >
> > Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>

Queued for -next, thanks for the patch.
-Daniel

> > ---
> >  drivers/gpu/drm/i915/intel_drv.h  |    1 +
> >  drivers/gpu/drm/i915/intel_hdmi.c |    1 +
> >  2 files changed, 2 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h
> > b/drivers/gpu/drm/i915/intel_drv.h
> > index c61ba47..b6c2c20 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -667,6 +667,7 @@ struct intel_hdmi {
> >         enum hdmi_force_audio force_audio;
> >         bool rgb_quant_range_selectable;
> >         enum hdmi_picture_aspect aspect_ratio;
> > +       struct intel_connector *attached_connector;
> >         void (*write_infoframe)(struct drm_encoder *encoder,
> >                                 enum hdmi_infoframe_type type,
> >                                 const void *frame, ssize_t len);
> > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c
> > b/drivers/gpu/drm/i915/intel_hdmi.c
> > index ed25f64..5bdb386 100644
> > --- a/drivers/gpu/drm/i915/intel_hdmi.c
> > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> > @@ -2107,6 +2107,7 @@ void intel_hdmi_init_connector(struct
> > intel_digital_port *intel_dig_port,
> >
> >         intel_connector_attach_encoder(intel_connector, intel_encoder);
> >         drm_connector_register(connector);
> > +       intel_hdmi->attached_connector = intel_connector;
> >
> >         /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be
> > written
> >          * 0xd.  Failure to do so will result in spurious interrupts being
> > --
> > 1.7.10.4
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> >

> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx


-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 2/6] drm/i915: Add HDMI probe function
  2015-09-09 18:55     ` Rodrigo Vivi
@ 2015-09-11 10:45       ` Jindal, Sonika
  2015-09-14  8:30         ` Daniel Vetter
  0 siblings, 1 reply; 77+ messages in thread
From: Jindal, Sonika @ 2015-09-11 10:45 UTC (permalink / raw)
  To: Rodrigo Vivi, Daniel Vetter; +Cc: intel-gfx



On 9/10/2015 12:25 AM, Rodrigo Vivi wrote:
> I liked the approach and agree with Daniel, so with his suggestions feel
> free to use:
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com
> <mailto:rodrigo.vivi@intel.com>>
>
> On Fri, Sep 4, 2015 at 7:46 AM Daniel Vetter <daniel@ffwll.ch
> <mailto:daniel@ffwll.ch>> wrote:
>
>     On Fri, Sep 04, 2015 at 06:56:12PM +0530, Sonika Jindal wrote:
>      > From: Shashank Sharma <shashank.sharma@intel.com
>     <mailto:shashank.sharma@intel.com>>
>      >
>      > This patch adds a separate probe function for HDMI
>      > EDID read over DDC channel. This function has been
>      > registered as a .hot_plug handler for HDMI encoder.
>      >
>      > The current implementation of hdmi_detect()
>      > function re-sets the cached HDMI edid (in connector->detect_edid) in
>      > every detect call.This function gets called many times, sometimes
>      > directly from userspace probes, forcing drivers to read EDID every
>      > detect function call.This causes several problems like:
>      >
>      > 1. Race conditions in multiple hot_plug / unplug cases, between
>      >    interrupts bottom halves and userspace detections.
>      > 2. Many Un-necessary EDID reads for single hotplug/unplug
>      > 3. HDMI complaince failures which expects only one EDID read per
>     hotplug
>      >
>      > This function will be serving the purpose of really reading the EDID
>      > by really probing the DDC channel, and updating the cached EDID.
>      >
>      > The plan is to:
>      > 1. i915 IRQ handler bottom half function already calls
>      >    intel_encoder->hotplug() function. Adding This probe function
>     which
>      >    will read the EDID only in case of a hotplug / unplug.
>      > 2. During init_connector his probe will be called to read the edid
>      > 3. Reuse the cached EDID in hdmi_detect() function.
>      >
>      > The "< gen7" check is there because this was tested only for >=gen7
>      > platforms. For older platforms the hotplug/reading edid path
>     remains same.
>      >
>      > v2: Calling set_edid instead of hdmi_probe during init.
>      > Also, for platforms having DDI, intel_encoder for DP and HDMI is same
>      > (taken from intel_dig_port), so for DP also, hot_plug function
>     gets called
>      > which is not intended here. So, check for HDMI in intel_hdmi_probe
>      > Rely on HPD for updating edid only for platforms gen > 8 and also
>     for VLV.
>      >
>      > v3: Dropping the gen < 8 || !VLV  check. Now all platforms should
>     rely on
>      > hotplug or init for updating the edid.(Daniel)
>      > Also, calling hdmi_probe in init instead of set_edid
>      >
>      > Signed-off-by: Shashank Sharma <shashank.sharma@intel.com
>     <mailto:shashank.sharma@intel.com>>
>      > Signed-off-by: Sonika Jindal <sonika.jindal@intel.com
>     <mailto:sonika.jindal@intel.com>>
>      > ---
>      >  drivers/gpu/drm/i915/intel_hdmi.c |   46
>     ++++++++++++++++++++++++++++++++-----
>      >  1 file changed, 40 insertions(+), 6 deletions(-)
>      >
>      > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c
>     b/drivers/gpu/drm/i915/intel_hdmi.c
>      > index 5bdb386..1eda71a 100644
>      > --- a/drivers/gpu/drm/i915/intel_hdmi.c
>      > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
>      > @@ -1368,23 +1368,53 @@ intel_hdmi_set_edid(struct drm_connector
>     *connector)
>      >       return connected;
>      >  }
>      >
>      > +void intel_hdmi_probe(struct intel_encoder *intel_encoder)
>
>     Please call it _hot_plug if it's for the _hot_plug path.
>
Hmm, initial plan was to call it from other places if any..
But now it seems more logical to name it _hot_plug.
I will do that.

>      > +{
>      > +     struct intel_hdmi *intel_hdmi =
>      > +                     enc_to_intel_hdmi(&intel_encoder->base);
>      > +     struct intel_connector *intel_connector =
>      > +                             intel_hdmi->attached_connector;
>      > +
>      > +     /*
>      > +      * We are here, means there is a hotplug or a force
>      > +      * detection. Clear the cached EDID and probe the
>      > +      * DDC bus to check the current status of HDMI.
>      > +      */
>      > +     intel_hdmi_unset_edid(&intel_connector->base);
>      > +     if (intel_hdmi_set_edid(&intel_connector->base))
>      > +             DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
>      > +     else
>      > +             DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
>      > +}
>      > +
>      >  static enum drm_connector_status
>      >  intel_hdmi_detect(struct drm_connector *connector, bool force)
>      >  {
>      >       enum drm_connector_status status;
>      > +     struct intel_connector *intel_connector =
>      > +                             to_intel_connector(connector);
>      >
>      >       DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
>      >                     connector->base.id <http://base.id>,
>     connector->name);
>      > +     /*
>      > +      * There are many userspace calls which probe EDID from
>      > +      * detect path. In case of multiple hotplug/unplug, these
>      > +      * can cause race conditions while probing EDID. Also its
>      > +      * waste of CPU cycles to read the EDID again and again
>      > +      * unless there is a real hotplug.
>      > +      * So, rely on hotplugs and init to read edid.
>      > +      * Check connector status based on availability of cached EDID.
>      > +      */
>      >
>      > -     intel_hdmi_unset_edid(connector);
>      > -
>      > -     if (intel_hdmi_set_edid(connector)) {
>      > +     if (intel_connector->detect_edid) {
>      >               struct intel_hdmi *intel_hdmi =
>     intel_attached_hdmi(connector);
>      > -
>      > -             hdmi_to_dig_port(intel_hdmi)->base.type =
>     INTEL_OUTPUT_HDMI;
>      >               status = connector_status_connected;
>      > -     } else
>      > +             hdmi_to_dig_port(intel_hdmi)->base.type =
>     INTEL_OUTPUT_HDMI;
>      > +             DRM_DEBUG_DRIVER("hdmi status = connected\n");
>      > +     } else {
>      >               status = connector_status_disconnected;
>      > +             DRM_DEBUG_DRIVER("hdmi status = disconnected\n");
>      > +     }
>      >
>      >       return status;
>      >  }
>      > @@ -2104,11 +2134,15 @@ void intel_hdmi_init_connector(struct
>     intel_digital_port *intel_dig_port,
>      >       intel_connector->unregister = intel_connector_unregister;
>      >
>      >       intel_hdmi_add_properties(intel_hdmi, connector);
>      > +     intel_encoder->hot_plug = intel_hdmi_probe;
>      >
>      >       intel_connector_attach_encoder(intel_connector, intel_encoder);
>      >       drm_connector_register(connector);
>      >       intel_hdmi->attached_connector = intel_connector;
>      >
>      > +     /* Set edid during init */
>      > +     intel_hdmi_probe(intel_encoder);
>
>     Separate patch, but we really don't want this, initial probe should be
>     done async to avoid stalling the driver.
>     -Daniel

Where else do you suggest to do this? detect call is one place which 
does this for DP and used to do for HDMI also.
But since we need to take the edid reading part out of edid, I dont see 
any other place.
Please suggest.

Thanks,
Sonika
>
>      > +
>      >       /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first
>     be written
>      >        * 0xd.  Failure to do so will result in spurious
>     interrupts being
>      >        * generated on the port when a cable is not attached.
>      > --
>      > 1.7.10.4
>      >
>      > _______________________________________________
>      > Intel-gfx mailing list
>      > Intel-gfx@lists.freedesktop.org
>     <mailto:Intel-gfx@lists.freedesktop.org>
>      > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
>     --
>     Daniel Vetter
>     Software Engineer, Intel Corporation
>     http://blog.ffwll.ch
>     _______________________________________________
>     Intel-gfx mailing list
>     Intel-gfx@lists.freedesktop.org <mailto:Intel-gfx@lists.freedesktop.org>
>     http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [PATCH] drm/i915: Check live status before reading edid
  2015-09-09 19:11     ` [PATCH 4/6] drm/i915: " Rodrigo Vivi
@ 2015-09-11 11:26       ` Sonika Jindal
  2015-09-11 17:56         ` Rodrigo Vivi
  0 siblings, 1 reply; 77+ messages in thread
From: Sonika Jindal @ 2015-09-11 11:26 UTC (permalink / raw)
  To: intel-gfx

The Bspec is very clear that Live status must be checked about before
trying to read EDID over DDC channel. This patch makes sure that HDMI
EDID is read only when live status is up.

The live status doesn't seem to perform very consistent across various
platforms when tested with different monitors. The reason behind that is
some monitors are late to provide right voltage to set live_status up.
So, after getting the interrupt, for a small duration, live status reg
fluctuates, and then settles down showing the correct staus.

This is explained here in, in a rough way:
HPD line  ________________
			 |\ T1 = Monitor Hotplug causing IRQ
			 | \______________________________________
			 | |
                         | |
			 | |   T2 = Live status is stable
			 | |  _____________________________________
			 | | /|
Live status _____________|_|/ |
			 | |  |
			 | |  |
			 | |  |
			T0 T1  T2

(Between T1 and T2 Live status fluctuates or can be even low, depending on
 the monitor)

After several experiments, we have concluded that a max delay
of 30ms is enough to allow the live status to settle down with
most of the monitors. This total delay of 30ms has been split into
a resolution of 3 retries of 10ms each, for the better cases.

This delay is kept at 30ms, keeping in consideration that, HDCP compliance
expect the HPD handler to respond a plug out in 100ms, by disabling port.

v2: Adding checks for VLV/CHV as well. Reusing old ibx and g4x functions
to check digital port status. Adding a separate function to get bxt live
status (Daniel)
v3: Using intel_encoder->hpd_pin to check the live status (Siva)
Moving the live status read to intel_hdmi_probe and passing parameter
to read/not to read the edid. (me)
v4:
* Added live status check for all platforms using
intel_digital_port_connected.
* Rebased on top of Jani's DP cleanup series
* Some monitors take time in setting the live status. So retry for few
times if this is a connect HPD
v5: Removed extra "drm/i915" from commit message. Adding Shashank's sob
    which was missed.
v6: Drop the (!detect_edid && !live_status check) check because for DDI
ports which are enumerated as hdmi as well as DP, we don't have a
mechanism to differentiate between DP and hdmi inside the encoder's
hot_plug. This leads to call to the hdmi's hot_plug hook for DP as well
as hdmi which leads to issues during unplug because of the above check.
v7: Make intel_digital_port_connected global in this patch, some
reformatting of while loop, adding a print when live status is not
up. (Rodrigo)

Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c   |    2 +-
 drivers/gpu/drm/i915/intel_drv.h  |    2 ++
 drivers/gpu/drm/i915/intel_hdmi.c |   26 +++++++++++++++++++-------
 3 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index bf17030..fedf6d1 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -4695,7 +4695,7 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
  *
  * Return %true if @port is connected, %false otherwise.
  */
-static bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
+bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
 					 struct intel_digital_port *port)
 {
 	if (HAS_PCH_IBX(dev_priv))
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index b6c2c20..ac6d748 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1210,6 +1210,8 @@ void intel_edp_drrs_disable(struct intel_dp *intel_dp);
 void intel_edp_drrs_invalidate(struct drm_device *dev,
 		unsigned frontbuffer_bits);
 void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits);
+bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
+					 struct intel_digital_port *port);
 
 /* intel_dp_mst.c */
 int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 1eda71a..d366ca5 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1329,22 +1329,23 @@ intel_hdmi_unset_edid(struct drm_connector *connector)
 }
 
 static bool
-intel_hdmi_set_edid(struct drm_connector *connector)
+intel_hdmi_set_edid(struct drm_connector *connector, bool force)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
 	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 	struct intel_encoder *intel_encoder =
 		&hdmi_to_dig_port(intel_hdmi)->base;
 	enum intel_display_power_domain power_domain;
-	struct edid *edid;
+	struct edid *edid = NULL;
 	bool connected = false;
 
 	power_domain = intel_display_port_power_domain(intel_encoder);
 	intel_display_power_get(dev_priv, power_domain);
 
-	edid = drm_get_edid(connector,
-			    intel_gmbus_get_adapter(dev_priv,
-						    intel_hdmi->ddc_bus));
+	if (force)
+		edid = drm_get_edid(connector,
+				    intel_gmbus_get_adapter(dev_priv,
+				    intel_hdmi->ddc_bus));
 
 	intel_display_power_put(dev_priv, power_domain);
 
@@ -1374,14 +1375,25 @@ void intel_hdmi_probe(struct intel_encoder *intel_encoder)
 			enc_to_intel_hdmi(&intel_encoder->base);
 	struct intel_connector *intel_connector =
 				intel_hdmi->attached_connector;
+	struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
+	bool live_status = false;
+	unsigned int retry = 3;
+
+	while (!live_status && --retry) {
+		live_status = intel_digital_port_connected(dev_priv,
+				hdmi_to_dig_port(intel_hdmi));
+		mdelay(10);
+	}
 
+	if (!live_status)
+		DRM_DEBUG_KMS("Live status not up!");
 	/*
 	 * We are here, means there is a hotplug or a force
 	 * detection. Clear the cached EDID and probe the
 	 * DDC bus to check the current status of HDMI.
 	 */
 	intel_hdmi_unset_edid(&intel_connector->base);
-	if (intel_hdmi_set_edid(&intel_connector->base))
+	if (intel_hdmi_set_edid(&intel_connector->base, live_status))
 		DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
 	else
 		DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
@@ -1432,7 +1444,7 @@ intel_hdmi_force(struct drm_connector *connector)
 	if (connector->status != connector_status_connected)
 		return;
 
-	intel_hdmi_set_edid(connector);
+	intel_hdmi_set_edid(connector, true);
 	hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
 }
 
-- 
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH] drm/i915/bxt: Use intel_encoder->hpd_pin to check live status
  2015-09-09 18:57   ` Rodrigo Vivi
@ 2015-09-11 11:28     ` Sonika Jindal
  2015-09-11 18:00       ` Rodrigo Vivi
  2015-09-14  8:34       ` Daniel Vetter
  0 siblings, 2 replies; 77+ messages in thread
From: Sonika Jindal @ 2015-09-11 11:28 UTC (permalink / raw)
  To: intel-gfx

Using intel_encoder's hpd_pin to check the live status
because of BXT A0/A1 WA for HPD pins and hpd_pin contains the
updated pin for the corresponding port.

Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 796f930..bf17030 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -4663,11 +4663,14 @@ static bool vlv_digital_port_connected(struct drm_i915_private *dev_priv,
 }
 
 static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
-				       struct intel_digital_port *port)
+				       struct intel_digital_port *intel_dig_port)
 {
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
+	enum port port;
 	u32 bit;
 
-	switch (port->port) {
+	intel_hpd_pin_to_port(intel_encoder->hpd_pin, &port);
+	switch (port) {
 	case PORT_A:
 		bit = BXT_DE_PORT_HP_DDIA;
 		break;
@@ -4678,7 +4681,7 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
 		bit = BXT_DE_PORT_HP_DDIC;
 		break;
 	default:
-		MISSING_CASE(port->port);
+		MISSING_CASE(port);
 		return false;
 	}
 
-- 
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915: Check live status before reading edid
  2015-09-11 11:26       ` [PATCH] " Sonika Jindal
@ 2015-09-11 17:56         ` Rodrigo Vivi
  2015-09-14  8:42           ` Daniel Vetter
  0 siblings, 1 reply; 77+ messages in thread
From: Rodrigo Vivi @ 2015-09-11 17:56 UTC (permalink / raw)
  To: Sonika Jindal, intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 7938 bytes --]

Thanks

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>


On Fri, Sep 11, 2015 at 4:38 AM Sonika Jindal <sonika.jindal@intel.com>
wrote:

> The Bspec is very clear that Live status must be checked about before
> trying to read EDID over DDC channel. This patch makes sure that HDMI
> EDID is read only when live status is up.
>
> The live status doesn't seem to perform very consistent across various
> platforms when tested with different monitors. The reason behind that is
> some monitors are late to provide right voltage to set live_status up.
> So, after getting the interrupt, for a small duration, live status reg
> fluctuates, and then settles down showing the correct staus.
>
> This is explained here in, in a rough way:
> HPD line  ________________
>                          |\ T1 = Monitor Hotplug causing IRQ
>                          | \______________________________________
>                          | |
>                          | |
>                          | |   T2 = Live status is stable
>                          | |  _____________________________________
>                          | | /|
> Live status _____________|_|/ |
>                          | |  |
>                          | |  |
>                          | |  |
>                         T0 T1  T2
>
> (Between T1 and T2 Live status fluctuates or can be even low, depending on
>  the monitor)
>
> After several experiments, we have concluded that a max delay
> of 30ms is enough to allow the live status to settle down with
> most of the monitors. This total delay of 30ms has been split into
> a resolution of 3 retries of 10ms each, for the better cases.
>
> This delay is kept at 30ms, keeping in consideration that, HDCP compliance
> expect the HPD handler to respond a plug out in 100ms, by disabling port.
>
> v2: Adding checks for VLV/CHV as well. Reusing old ibx and g4x functions
> to check digital port status. Adding a separate function to get bxt live
> status (Daniel)
> v3: Using intel_encoder->hpd_pin to check the live status (Siva)
> Moving the live status read to intel_hdmi_probe and passing parameter
> to read/not to read the edid. (me)
> v4:
> * Added live status check for all platforms using
> intel_digital_port_connected.
> * Rebased on top of Jani's DP cleanup series
> * Some monitors take time in setting the live status. So retry for few
> times if this is a connect HPD
> v5: Removed extra "drm/i915" from commit message. Adding Shashank's sob
>     which was missed.
> v6: Drop the (!detect_edid && !live_status check) check because for DDI
> ports which are enumerated as hdmi as well as DP, we don't have a
> mechanism to differentiate between DP and hdmi inside the encoder's
> hot_plug. This leads to call to the hdmi's hot_plug hook for DP as well
> as hdmi which leads to issues during unplug because of the above check.
> v7: Make intel_digital_port_connected global in this patch, some
> reformatting of while loop, adding a print when live status is not
> up. (Rodrigo)
>
> Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_dp.c   |    2 +-
>  drivers/gpu/drm/i915/intel_drv.h  |    2 ++
>  drivers/gpu/drm/i915/intel_hdmi.c |   26 +++++++++++++++++++-------
>  3 files changed, 22 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c
> b/drivers/gpu/drm/i915/intel_dp.c
> index bf17030..fedf6d1 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -4695,7 +4695,7 @@ static bool bxt_digital_port_connected(struct
> drm_i915_private *dev_priv,
>   *
>   * Return %true if @port is connected, %false otherwise.
>   */
> -static bool intel_digital_port_connected(struct drm_i915_private
> *dev_priv,
> +bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
>                                          struct intel_digital_port *port)
>  {
>         if (HAS_PCH_IBX(dev_priv))
> diff --git a/drivers/gpu/drm/i915/intel_drv.h
> b/drivers/gpu/drm/i915/intel_drv.h
> index b6c2c20..ac6d748 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1210,6 +1210,8 @@ void intel_edp_drrs_disable(struct intel_dp
> *intel_dp);
>  void intel_edp_drrs_invalidate(struct drm_device *dev,
>                 unsigned frontbuffer_bits);
>  void intel_edp_drrs_flush(struct drm_device *dev, unsigned
> frontbuffer_bits);
> +bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
> +                                        struct intel_digital_port *port);
>
>  /* intel_dp_mst.c */
>  int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port,
> int conn_id);
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c
> b/drivers/gpu/drm/i915/intel_hdmi.c
> index 1eda71a..d366ca5 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -1329,22 +1329,23 @@ intel_hdmi_unset_edid(struct drm_connector
> *connector)
>  }
>
>  static bool
> -intel_hdmi_set_edid(struct drm_connector *connector)
> +intel_hdmi_set_edid(struct drm_connector *connector, bool force)
>  {
>         struct drm_i915_private *dev_priv = to_i915(connector->dev);
>         struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
>         struct intel_encoder *intel_encoder =
>                 &hdmi_to_dig_port(intel_hdmi)->base;
>         enum intel_display_power_domain power_domain;
> -       struct edid *edid;
> +       struct edid *edid = NULL;
>         bool connected = false;
>
>         power_domain = intel_display_port_power_domain(intel_encoder);
>         intel_display_power_get(dev_priv, power_domain);
>
> -       edid = drm_get_edid(connector,
> -                           intel_gmbus_get_adapter(dev_priv,
> -                                                   intel_hdmi->ddc_bus));
> +       if (force)
> +               edid = drm_get_edid(connector,
> +                                   intel_gmbus_get_adapter(dev_priv,
> +                                   intel_hdmi->ddc_bus));
>
>         intel_display_power_put(dev_priv, power_domain);
>
> @@ -1374,14 +1375,25 @@ void intel_hdmi_probe(struct intel_encoder
> *intel_encoder)
>                         enc_to_intel_hdmi(&intel_encoder->base);
>         struct intel_connector *intel_connector =
>                                 intel_hdmi->attached_connector;
> +       struct drm_i915_private *dev_priv =
> to_i915(intel_encoder->base.dev);
> +       bool live_status = false;
> +       unsigned int retry = 3;
> +
> +       while (!live_status && --retry) {
> +               live_status = intel_digital_port_connected(dev_priv,
> +                               hdmi_to_dig_port(intel_hdmi));
> +               mdelay(10);
> +       }
>
> +       if (!live_status)
> +               DRM_DEBUG_KMS("Live status not up!");
>         /*
>          * We are here, means there is a hotplug or a force
>          * detection. Clear the cached EDID and probe the
>          * DDC bus to check the current status of HDMI.
>          */
>         intel_hdmi_unset_edid(&intel_connector->base);
> -       if (intel_hdmi_set_edid(&intel_connector->base))
> +       if (intel_hdmi_set_edid(&intel_connector->base, live_status))
>                 DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
>         else
>                 DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
> @@ -1432,7 +1444,7 @@ intel_hdmi_force(struct drm_connector *connector)
>         if (connector->status != connector_status_connected)
>                 return;
>
> -       intel_hdmi_set_edid(connector);
> +       intel_hdmi_set_edid(connector, true);
>         hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
>  }
>
> --
> 1.7.10.4
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>

[-- Attachment #1.2: Type: text/html, Size: 9766 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915/bxt: Use intel_encoder->hpd_pin to check live status
  2015-09-11 11:28     ` [PATCH] drm/i915/bxt: Use intel_encoder->hpd_pin to check live status Sonika Jindal
@ 2015-09-11 18:00       ` Rodrigo Vivi
  2015-09-12 12:02         ` Jindal, Sonika
  2015-09-14  8:34       ` Daniel Vetter
  1 sibling, 1 reply; 77+ messages in thread
From: Rodrigo Vivi @ 2015-09-11 18:00 UTC (permalink / raw)
  To: Sonika Jindal, intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 2029 bytes --]

On Fri, Sep 11, 2015 at 4:40 AM Sonika Jindal <sonika.jindal@intel.com>
wrote:

> Using intel_encoder's hpd_pin to check the live status
> because of BXT A0/A1 WA for HPD pins and hpd_pin contains the
> updated pin for the corresponding port.
>

It makes sense, but is it always true? or we should have a fallback to
intel_dig_port->port in some case or in some stepping after A0/A1?

With this clarified feel free to use:
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>


>
> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_dp.c |    9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c
> b/drivers/gpu/drm/i915/intel_dp.c
> index 796f930..bf17030 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -4663,11 +4663,14 @@ static bool vlv_digital_port_connected(struct
> drm_i915_private *dev_priv,
>  }
>
>  static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
> -                                      struct intel_digital_port *port)
> +                                      struct intel_digital_port
> *intel_dig_port)
>  {
> +       struct intel_encoder *intel_encoder = &intel_dig_port->base;
> +       enum port port;
>         u32 bit;
>
> -       switch (port->port) {
> +       intel_hpd_pin_to_port(intel_encoder->hpd_pin, &port);
> +       switch (port) {
>         case PORT_A:
>                 bit = BXT_DE_PORT_HP_DDIA;
>                 break;
> @@ -4678,7 +4681,7 @@ static bool bxt_digital_port_connected(struct
> drm_i915_private *dev_priv,
>                 bit = BXT_DE_PORT_HP_DDIC;
>                 break;
>         default:
> -               MISSING_CASE(port->port);
> +               MISSING_CASE(port);
>                 return false;
>         }
>
> --
> 1.7.10.4
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>

[-- Attachment #1.2: Type: text/html, Size: 3045 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915/bxt: Use intel_encoder->hpd_pin to check live status
  2015-09-11 18:00       ` Rodrigo Vivi
@ 2015-09-12 12:02         ` Jindal, Sonika
  0 siblings, 0 replies; 77+ messages in thread
From: Jindal, Sonika @ 2015-09-12 12:02 UTC (permalink / raw)
  To: Rodrigo Vivi, intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 2512 bytes --]

Thanks Rodrigo.
This is always true. The hpd_pin is the right pin which we set for particular port. So no fallback needed.

Regards,
Sonika

From: Rodrigo Vivi [mailto:rodrigo.vivi@gmail.com]
Sent: Friday, September 11, 2015 11:31 PM
To: Jindal, Sonika; intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH] drm/i915/bxt: Use intel_encoder->hpd_pin to check live status


On Fri, Sep 11, 2015 at 4:40 AM Sonika Jindal <sonika.jindal@intel.com<mailto:sonika.jindal@intel.com>> wrote:
Using intel_encoder's hpd_pin to check the live status
because of BXT A0/A1 WA for HPD pins and hpd_pin contains the
updated pin for the corresponding port.

It makes sense, but is it always true? or we should have a fallback to intel_dig_port->port in some case or in some stepping after A0/A1?

With this clarified feel free to use:
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com<mailto:rodrigo.vivi@intel.com>>


Signed-off-by: Sonika Jindal <sonika.jindal@intel.com<mailto:sonika.jindal@intel.com>>
---
 drivers/gpu/drm/i915/intel_dp.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 796f930..bf17030 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -4663,11 +4663,14 @@ static bool vlv_digital_port_connected(struct drm_i915_private *dev_priv,
 }

 static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
-                                      struct intel_digital_port *port)
+                                      struct intel_digital_port *intel_dig_port)
 {
+       struct intel_encoder *intel_encoder = &intel_dig_port->base;
+       enum port port;
        u32 bit;

-       switch (port->port) {
+       intel_hpd_pin_to_port(intel_encoder->hpd_pin, &port);
+       switch (port) {
        case PORT_A:
                bit = BXT_DE_PORT_HP_DDIA;
                break;
@@ -4678,7 +4681,7 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
                bit = BXT_DE_PORT_HP_DDIC;
                break;
        default:
-               MISSING_CASE(port->port);
+               MISSING_CASE(port);
                return false;
        }

--
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org<mailto:Intel-gfx@lists.freedesktop.org>
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

[-- Attachment #1.2: Type: text/html, Size: 7173 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [PATCH 2/6] drm/i915: Add HDMI probe function
  2015-09-11 10:45       ` Jindal, Sonika
@ 2015-09-14  8:30         ` Daniel Vetter
  2015-09-14  9:55           ` Sharma, Shashank
  0 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2015-09-14  8:30 UTC (permalink / raw)
  To: Jindal, Sonika; +Cc: intel-gfx

On Fri, Sep 11, 2015 at 04:15:39PM +0530, Jindal, Sonika wrote:
> 
> 
> On 9/10/2015 12:25 AM, Rodrigo Vivi wrote:
> >I liked the approach and agree with Daniel, so with his suggestions feel
> >free to use:
> >Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com
> ><mailto:rodrigo.vivi@intel.com>>
> >
> >On Fri, Sep 4, 2015 at 7:46 AM Daniel Vetter <daniel@ffwll.ch
> ><mailto:daniel@ffwll.ch>> wrote:
> >
> >    On Fri, Sep 04, 2015 at 06:56:12PM +0530, Sonika Jindal wrote:
> >     > From: Shashank Sharma <shashank.sharma@intel.com
> >    <mailto:shashank.sharma@intel.com>>
> >     >
> >     > This patch adds a separate probe function for HDMI
> >     > EDID read over DDC channel. This function has been
> >     > registered as a .hot_plug handler for HDMI encoder.
> >     >
> >     > The current implementation of hdmi_detect()
> >     > function re-sets the cached HDMI edid (in connector->detect_edid) in
> >     > every detect call.This function gets called many times, sometimes
> >     > directly from userspace probes, forcing drivers to read EDID every
> >     > detect function call.This causes several problems like:
> >     >
> >     > 1. Race conditions in multiple hot_plug / unplug cases, between
> >     >    interrupts bottom halves and userspace detections.
> >     > 2. Many Un-necessary EDID reads for single hotplug/unplug
> >     > 3. HDMI complaince failures which expects only one EDID read per
> >    hotplug
> >     >
> >     > This function will be serving the purpose of really reading the EDID
> >     > by really probing the DDC channel, and updating the cached EDID.
> >     >
> >     > The plan is to:
> >     > 1. i915 IRQ handler bottom half function already calls
> >     >    intel_encoder->hotplug() function. Adding This probe function
> >    which
> >     >    will read the EDID only in case of a hotplug / unplug.
> >     > 2. During init_connector his probe will be called to read the edid
> >     > 3. Reuse the cached EDID in hdmi_detect() function.
> >     >
> >     > The "< gen7" check is there because this was tested only for >=gen7
> >     > platforms. For older platforms the hotplug/reading edid path
> >    remains same.
> >     >
> >     > v2: Calling set_edid instead of hdmi_probe during init.
> >     > Also, for platforms having DDI, intel_encoder for DP and HDMI is same
> >     > (taken from intel_dig_port), so for DP also, hot_plug function
> >    gets called
> >     > which is not intended here. So, check for HDMI in intel_hdmi_probe
> >     > Rely on HPD for updating edid only for platforms gen > 8 and also
> >    for VLV.
> >     >
> >     > v3: Dropping the gen < 8 || !VLV  check. Now all platforms should
> >    rely on
> >     > hotplug or init for updating the edid.(Daniel)
> >     > Also, calling hdmi_probe in init instead of set_edid
> >     >
> >     > Signed-off-by: Shashank Sharma <shashank.sharma@intel.com
> >    <mailto:shashank.sharma@intel.com>>
> >     > Signed-off-by: Sonika Jindal <sonika.jindal@intel.com
> >    <mailto:sonika.jindal@intel.com>>
> >     > ---
> >     >  drivers/gpu/drm/i915/intel_hdmi.c |   46
> >    ++++++++++++++++++++++++++++++++-----
> >     >  1 file changed, 40 insertions(+), 6 deletions(-)
> >     >
> >     > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c
> >    b/drivers/gpu/drm/i915/intel_hdmi.c
> >     > index 5bdb386..1eda71a 100644
> >     > --- a/drivers/gpu/drm/i915/intel_hdmi.c
> >     > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> >     > @@ -1368,23 +1368,53 @@ intel_hdmi_set_edid(struct drm_connector
> >    *connector)
> >     >       return connected;
> >     >  }
> >     >
> >     > +void intel_hdmi_probe(struct intel_encoder *intel_encoder)
> >
> >    Please call it _hot_plug if it's for the _hot_plug path.
> >
> Hmm, initial plan was to call it from other places if any..
> But now it seems more logical to name it _hot_plug.
> I will do that.
> 
> >     > +{
> >     > +     struct intel_hdmi *intel_hdmi =
> >     > +                     enc_to_intel_hdmi(&intel_encoder->base);
> >     > +     struct intel_connector *intel_connector =
> >     > +                             intel_hdmi->attached_connector;
> >     > +
> >     > +     /*
> >     > +      * We are here, means there is a hotplug or a force
> >     > +      * detection. Clear the cached EDID and probe the
> >     > +      * DDC bus to check the current status of HDMI.
> >     > +      */
> >     > +     intel_hdmi_unset_edid(&intel_connector->base);
> >     > +     if (intel_hdmi_set_edid(&intel_connector->base))
> >     > +             DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
> >     > +     else
> >     > +             DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
> >     > +}
> >     > +
> >     >  static enum drm_connector_status
> >     >  intel_hdmi_detect(struct drm_connector *connector, bool force)
> >     >  {
> >     >       enum drm_connector_status status;
> >     > +     struct intel_connector *intel_connector =
> >     > +                             to_intel_connector(connector);
> >     >
> >     >       DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> >     >                     connector->base.id <http://base.id>,
> >    connector->name);
> >     > +     /*
> >     > +      * There are many userspace calls which probe EDID from
> >     > +      * detect path. In case of multiple hotplug/unplug, these
> >     > +      * can cause race conditions while probing EDID. Also its
> >     > +      * waste of CPU cycles to read the EDID again and again
> >     > +      * unless there is a real hotplug.
> >     > +      * So, rely on hotplugs and init to read edid.
> >     > +      * Check connector status based on availability of cached EDID.
> >     > +      */
> >     >
> >     > -     intel_hdmi_unset_edid(connector);
> >     > -
> >     > -     if (intel_hdmi_set_edid(connector)) {
> >     > +     if (intel_connector->detect_edid) {
> >     >               struct intel_hdmi *intel_hdmi =
> >    intel_attached_hdmi(connector);
> >     > -
> >     > -             hdmi_to_dig_port(intel_hdmi)->base.type =
> >    INTEL_OUTPUT_HDMI;
> >     >               status = connector_status_connected;
> >     > -     } else
> >     > +             hdmi_to_dig_port(intel_hdmi)->base.type =
> >    INTEL_OUTPUT_HDMI;
> >     > +             DRM_DEBUG_DRIVER("hdmi status = connected\n");
> >     > +     } else {
> >     >               status = connector_status_disconnected;
> >     > +             DRM_DEBUG_DRIVER("hdmi status = disconnected\n");
> >     > +     }
> >     >
> >     >       return status;
> >     >  }
> >     > @@ -2104,11 +2134,15 @@ void intel_hdmi_init_connector(struct
> >    intel_digital_port *intel_dig_port,
> >     >       intel_connector->unregister = intel_connector_unregister;
> >     >
> >     >       intel_hdmi_add_properties(intel_hdmi, connector);
> >     > +     intel_encoder->hot_plug = intel_hdmi_probe;
> >     >
> >     >       intel_connector_attach_encoder(intel_connector, intel_encoder);
> >     >       drm_connector_register(connector);
> >     >       intel_hdmi->attached_connector = intel_connector;
> >     >
> >     > +     /* Set edid during init */
> >     > +     intel_hdmi_probe(intel_encoder);
> >
> >    Separate patch, but we really don't want this, initial probe should be
> >    done async to avoid stalling the driver.
> >    -Daniel
> 
> Where else do you suggest to do this? detect call is one place which does
> this for DP and used to do for HDMI also.
> But since we need to take the edid reading part out of edid, I dont see any
> other place.
> Please suggest.

You need to inject a fake hpd or similar everytime the world might have
changed from under us, which isn't just init but also system resume.

We do that already, so you just have to make sure that keeps on working.
Probably another reason why it would be better to rework that entire hpd
handling/detection code, to make sure it's clean and can be understood.

Adding hacks like these in the init code is certainly the wrong approach,
since we never done detection this early (so surprising from a high-level
ordering) and it also misses resume (which is why it should be done in
code shared between driver load and resume).
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915/bxt: Use intel_encoder->hpd_pin to check live status
  2015-09-11 11:28     ` [PATCH] drm/i915/bxt: Use intel_encoder->hpd_pin to check live status Sonika Jindal
  2015-09-11 18:00       ` Rodrigo Vivi
@ 2015-09-14  8:34       ` Daniel Vetter
  2015-09-14  8:38         ` Jindal, Sonika
  1 sibling, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2015-09-14  8:34 UTC (permalink / raw)
  To: Sonika Jindal; +Cc: intel-gfx

On Fri, Sep 11, 2015 at 04:58:32PM +0530, Sonika Jindal wrote:
> Using intel_encoder's hpd_pin to check the live status
> because of BXT A0/A1 WA for HPD pins and hpd_pin contains the
> updated pin for the corresponding port.
> 
> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_dp.c |    9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 796f930..bf17030 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -4663,11 +4663,14 @@ static bool vlv_digital_port_connected(struct drm_i915_private *dev_priv,
>  }
>  
>  static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
> -				       struct intel_digital_port *port)
> +				       struct intel_digital_port *intel_dig_port)
>  {
> +	struct intel_encoder *intel_encoder = &intel_dig_port->base;
> +	enum port port;
>  	u32 bit;
>  
> -	switch (port->port) {
> +	intel_hpd_pin_to_port(intel_encoder->hpd_pin, &port);

This looks very wrong - the function you're calling here maps from hpd_pin
to the port, but what you actually want is to map from port to pin. That
mapping is in intel_encoder->hpd_pin.
-Daniel

> +	switch (port) {
>  	case PORT_A:
>  		bit = BXT_DE_PORT_HP_DDIA;
>  		break;
> @@ -4678,7 +4681,7 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
>  		bit = BXT_DE_PORT_HP_DDIC;
>  		break;
>  	default:
> -		MISSING_CASE(port->port);
> +		MISSING_CASE(port);
>  		return false;
>  	}
>  
> -- 
> 1.7.10.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915/bxt: Use intel_encoder->hpd_pin to check live status
  2015-09-14  8:34       ` Daniel Vetter
@ 2015-09-14  8:38         ` Jindal, Sonika
  2015-09-14  9:15           ` Daniel Vetter
  0 siblings, 1 reply; 77+ messages in thread
From: Jindal, Sonika @ 2015-09-14  8:38 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx



On 9/14/2015 2:04 PM, Daniel Vetter wrote:
> On Fri, Sep 11, 2015 at 04:58:32PM +0530, Sonika Jindal wrote:
>> Using intel_encoder's hpd_pin to check the live status
>> because of BXT A0/A1 WA for HPD pins and hpd_pin contains the
>> updated pin for the corresponding port.
>>
>> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
>> ---
>>   drivers/gpu/drm/i915/intel_dp.c |    9 ++++++---
>>   1 file changed, 6 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
>> index 796f930..bf17030 100644
>> --- a/drivers/gpu/drm/i915/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/intel_dp.c
>> @@ -4663,11 +4663,14 @@ static bool vlv_digital_port_connected(struct drm_i915_private *dev_priv,
>>   }
>>
>>   static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
>> -				       struct intel_digital_port *port)
>> +				       struct intel_digital_port *intel_dig_port)
>>   {
>> +	struct intel_encoder *intel_encoder = &intel_dig_port->base;
>> +	enum port port;
>>   	u32 bit;
>>
>> -	switch (port->port) {
>> +	intel_hpd_pin_to_port(intel_encoder->hpd_pin, &port);
>
> This looks very wrong - the function you're calling here maps from hpd_pin
> to the port, but what you actually want is to map from port to pin. That
> mapping is in intel_encoder->hpd_pin.
> -Daniel
No, I want to find out the correct port whose hpd bit we need to check.
That port we are finding based upon the hpd_pin we have set for that 
encoder. This was the whole point of using hpd_pin for the BXT A0/A1 WA.
That instead of checking different HPD bit based upon the port, just 
change the hpd_pin itself in intel_encoder.

Regards,
Sonika
>
>> +	switch (port) {
>>   	case PORT_A:
>>   		bit = BXT_DE_PORT_HP_DDIA;
>>   		break;
>> @@ -4678,7 +4681,7 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
>>   		bit = BXT_DE_PORT_HP_DDIC;
>>   		break;
>>   	default:
>> -		MISSING_CASE(port->port);
>> +		MISSING_CASE(port);
>>   		return false;
>>   	}
>>
>> --
>> 1.7.10.4
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915: Check live status before reading edid
  2015-09-11 17:56         ` Rodrigo Vivi
@ 2015-09-14  8:42           ` Daniel Vetter
  2015-09-14  9:14             ` Jindal, Sonika
  0 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2015-09-14  8:42 UTC (permalink / raw)
  To: Rodrigo Vivi; +Cc: intel-gfx

On Fri, Sep 11, 2015 at 05:56:47PM +0000, Rodrigo Vivi wrote:
> Thanks
> 
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> 
> 
> On Fri, Sep 11, 2015 at 4:38 AM Sonika Jindal <sonika.jindal@intel.com>
> wrote:
> 
> > The Bspec is very clear that Live status must be checked about before
> > trying to read EDID over DDC channel. This patch makes sure that HDMI
> > EDID is read only when live status is up.
> >
> > The live status doesn't seem to perform very consistent across various
> > platforms when tested with different monitors. The reason behind that is
> > some monitors are late to provide right voltage to set live_status up.
> > So, after getting the interrupt, for a small duration, live status reg
> > fluctuates, and then settles down showing the correct staus.
> >
> > This is explained here in, in a rough way:
> > HPD line  ________________
> >                          |\ T1 = Monitor Hotplug causing IRQ
> >                          | \______________________________________
> >                          | |
> >                          | |
> >                          | |   T2 = Live status is stable
> >                          | |  _____________________________________
> >                          | | /|
> > Live status _____________|_|/ |
> >                          | |  |
> >                          | |  |
> >                          | |  |
> >                         T0 T1  T2
> >
> > (Between T1 and T2 Live status fluctuates or can be even low, depending on
> >  the monitor)
> >
> > After several experiments, we have concluded that a max delay
> > of 30ms is enough to allow the live status to settle down with
> > most of the monitors. This total delay of 30ms has been split into
> > a resolution of 3 retries of 10ms each, for the better cases.
> >
> > This delay is kept at 30ms, keeping in consideration that, HDCP compliance
> > expect the HPD handler to respond a plug out in 100ms, by disabling port.
> >
> > v2: Adding checks for VLV/CHV as well. Reusing old ibx and g4x functions
> > to check digital port status. Adding a separate function to get bxt live
> > status (Daniel)
> > v3: Using intel_encoder->hpd_pin to check the live status (Siva)
> > Moving the live status read to intel_hdmi_probe and passing parameter
> > to read/not to read the edid. (me)
> > v4:
> > * Added live status check for all platforms using
> > intel_digital_port_connected.
> > * Rebased on top of Jani's DP cleanup series
> > * Some monitors take time in setting the live status. So retry for few
> > times if this is a connect HPD
> > v5: Removed extra "drm/i915" from commit message. Adding Shashank's sob
> >     which was missed.
> > v6: Drop the (!detect_edid && !live_status check) check because for DDI
> > ports which are enumerated as hdmi as well as DP, we don't have a
> > mechanism to differentiate between DP and hdmi inside the encoder's
> > hot_plug. This leads to call to the hdmi's hot_plug hook for DP as well
> > as hdmi which leads to issues during unplug because of the above check.
> > v7: Make intel_digital_port_connected global in this patch, some
> > reformatting of while loop, adding a print when live status is not
> > up. (Rodrigo)
> >
> > Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
> > Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>

Since this is tricky stuff and other patches in this series are blocked
until we have a clearer picture can you please rebase this to be the first
patch on top of -nightly so that I can pull it in directly?

I tried to do that but proved a bit too messy.
-Daniel

> > ---
> >  drivers/gpu/drm/i915/intel_dp.c   |    2 +-
> >  drivers/gpu/drm/i915/intel_drv.h  |    2 ++
> >  drivers/gpu/drm/i915/intel_hdmi.c |   26 +++++++++++++++++++-------
> >  3 files changed, 22 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c
> > b/drivers/gpu/drm/i915/intel_dp.c
> > index bf17030..fedf6d1 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -4695,7 +4695,7 @@ static bool bxt_digital_port_connected(struct
> > drm_i915_private *dev_priv,
> >   *
> >   * Return %true if @port is connected, %false otherwise.
> >   */
> > -static bool intel_digital_port_connected(struct drm_i915_private
> > *dev_priv,
> > +bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
> >                                          struct intel_digital_port *port)
> >  {
> >         if (HAS_PCH_IBX(dev_priv))
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h
> > b/drivers/gpu/drm/i915/intel_drv.h
> > index b6c2c20..ac6d748 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -1210,6 +1210,8 @@ void intel_edp_drrs_disable(struct intel_dp
> > *intel_dp);
> >  void intel_edp_drrs_invalidate(struct drm_device *dev,
> >                 unsigned frontbuffer_bits);
> >  void intel_edp_drrs_flush(struct drm_device *dev, unsigned
> > frontbuffer_bits);
> > +bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
> > +                                        struct intel_digital_port *port);
>g>
> >  /* intel_dp_mst.c */
> >  int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port,
> > int conn_id);
> > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c
> > b/drivers/gpu/drm/i915/intel_hdmi.c
> > index 1eda71a..d366ca5 100644
> > --- a/drivers/gpu/drm/i915/intel_hdmi.c
> > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> > @@ -1329,22 +1329,23 @@ intel_hdmi_unset_edid(struct drm_connector
> > *connector)
> >  }
> >
> >  static bool
> > -intel_hdmi_set_edid(struct drm_connector *connector)
> > +intel_hdmi_set_edid(struct drm_connector *connector, bool force)
> >  {
> >         struct drm_i915_private *dev_priv = to_i915(connector->dev);
> >         struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
> >         struct intel_encoder *intel_encoder =
> >                 &hdmi_to_dig_port(intel_hdmi)->base;
> >         enum intel_display_power_domain power_domain;
> > -       struct edid *edid;
> > +       struct edid *edid = NULL;
> >         bool connected = false;
> >
> >         power_domain = intel_display_port_power_domain(intel_encoder);
> >         intel_display_power_get(dev_priv, power_domain);
> >
> > -       edid = drm_get_edid(connector,
> > -                           intel_gmbus_get_adapter(dev_priv,
> > -                                                   intel_hdmi->ddc_bus));
> > +       if (force)
> > +               edid = drm_get_edid(connector,
> > +                                   intel_gmbus_get_adapter(dev_priv,
> > +                                   intel_hdmi->ddc_bus));
> >
> >         intel_display_power_put(dev_priv, power_domain);
> >
> > @@ -1374,14 +1375,25 @@ void intel_hdmi_probe(struct intel_encoder
> > *intel_encoder)
> >                         enc_to_intel_hdmi(&intel_encoder->base);
> >         struct intel_connector *intel_connector =
> >                                 intel_hdmi->attached_connector;
> > +       struct drm_i915_private *dev_priv =
> > to_i915(intel_encoder->base.dev);
> > +       bool live_status = false;
> > +       unsigned int retry = 3;
> > +
> > +       while (!live_status && --retry) {
> > +               live_status = intel_digital_port_connected(dev_priv,
> > +                               hdmi_to_dig_port(intel_hdmi));
> > +               mdelay(10);
> > +       }
> >
> > +       if (!live_status)
> > +               DRM_DEBUG_KMS("Live status not up!");
> >         /*
> >          * We are here, means there is a hotplug or a force
> >          * detection. Clear the cached EDID and probe the
> >          * DDC bus to check the current status of HDMI.
> >          */
> >         intel_hdmi_unset_edid(&intel_connector->base);
> > -       if (intel_hdmi_set_edid(&intel_connector->base))
> > +       if (intel_hdmi_set_edid(&intel_connector->base, live_status))
> >                 DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
> >         else
> >                 DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
> > @@ -1432,7 +1444,7 @@ intel_hdmi_force(struct drm_connector *connector)
> >         if (connector->status != connector_status_connected)
> >                 return;
> >
> > -       intel_hdmi_set_edid(connector);
> > +       intel_hdmi_set_edid(connector, true);
> >         hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
> >  }
> >
> > --
> > 1.7.10.4
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> >

> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx


-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915: Check live status before reading edid
  2015-09-14  8:42           ` Daniel Vetter
@ 2015-09-14  9:14             ` Jindal, Sonika
  2015-09-14  9:36               ` Daniel Vetter
  0 siblings, 1 reply; 77+ messages in thread
From: Jindal, Sonika @ 2015-09-14  9:14 UTC (permalink / raw)
  To: Daniel Vetter, Rodrigo Vivi; +Cc: intel-gfx



On 9/14/2015 2:12 PM, Daniel Vetter wrote:
> On Fri, Sep 11, 2015 at 05:56:47PM +0000, Rodrigo Vivi wrote:
>> Thanks
>>
>> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
>>
>>
>> On Fri, Sep 11, 2015 at 4:38 AM Sonika Jindal <sonika.jindal@intel.com>
>> wrote:
>>
>>> The Bspec is very clear that Live status must be checked about before
>>> trying to read EDID over DDC channel. This patch makes sure that HDMI
>>> EDID is read only when live status is up.
>>>
>>> The live status doesn't seem to perform very consistent across various
>>> platforms when tested with different monitors. The reason behind that is
>>> some monitors are late to provide right voltage to set live_status up.
>>> So, after getting the interrupt, for a small duration, live status reg
>>> fluctuates, and then settles down showing the correct staus.
>>>
>>> This is explained here in, in a rough way:
>>> HPD line  ________________
>>>                           |\ T1 = Monitor Hotplug causing IRQ
>>>                           | \______________________________________
>>>                           | |
>>>                           | |
>>>                           | |   T2 = Live status is stable
>>>                           | |  _____________________________________
>>>                           | | /|
>>> Live status _____________|_|/ |
>>>                           | |  |
>>>                           | |  |
>>>                           | |  |
>>>                          T0 T1  T2
>>>
>>> (Between T1 and T2 Live status fluctuates or can be even low, depending on
>>>   the monitor)
>>>
>>> After several experiments, we have concluded that a max delay
>>> of 30ms is enough to allow the live status to settle down with
>>> most of the monitors. This total delay of 30ms has been split into
>>> a resolution of 3 retries of 10ms each, for the better cases.
>>>
>>> This delay is kept at 30ms, keeping in consideration that, HDCP compliance
>>> expect the HPD handler to respond a plug out in 100ms, by disabling port.
>>>
>>> v2: Adding checks for VLV/CHV as well. Reusing old ibx and g4x functions
>>> to check digital port status. Adding a separate function to get bxt live
>>> status (Daniel)
>>> v3: Using intel_encoder->hpd_pin to check the live status (Siva)
>>> Moving the live status read to intel_hdmi_probe and passing parameter
>>> to read/not to read the edid. (me)
>>> v4:
>>> * Added live status check for all platforms using
>>> intel_digital_port_connected.
>>> * Rebased on top of Jani's DP cleanup series
>>> * Some monitors take time in setting the live status. So retry for few
>>> times if this is a connect HPD
>>> v5: Removed extra "drm/i915" from commit message. Adding Shashank's sob
>>>      which was missed.
>>> v6: Drop the (!detect_edid && !live_status check) check because for DDI
>>> ports which are enumerated as hdmi as well as DP, we don't have a
>>> mechanism to differentiate between DP and hdmi inside the encoder's
>>> hot_plug. This leads to call to the hdmi's hot_plug hook for DP as well
>>> as hdmi which leads to issues during unplug because of the above check.
>>> v7: Make intel_digital_port_connected global in this patch, some
>>> reformatting of while loop, adding a print when live status is not
>>> up. (Rodrigo)
>>>
>>> Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
>>> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
>
> Since this is tricky stuff and other patches in this series are blocked
> until we have a clearer picture can you please rebase this to be the first
> patch on top of -nightly so that I can pull it in directly?
>
> I tried to do that but proved a bit too messy.
> -Daniel
>
Hmm, since rebasing this will require these changes (check for live 
status) to go in detect and then later when we reach a conclusion on
hot_plug hook, we would need to move it to that function.
I think lets wait for the conclusion on the placement of that function.
What do you suggest?

Regards,
Sonika
>>> ---
>>>   drivers/gpu/drm/i915/intel_dp.c   |    2 +-
>>>   drivers/gpu/drm/i915/intel_drv.h  |    2 ++
>>>   drivers/gpu/drm/i915/intel_hdmi.c |   26 +++++++++++++++++++-------
>>>   3 files changed, 22 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/intel_dp.c
>>> b/drivers/gpu/drm/i915/intel_dp.c
>>> index bf17030..fedf6d1 100644
>>> --- a/drivers/gpu/drm/i915/intel_dp.c
>>> +++ b/drivers/gpu/drm/i915/intel_dp.c
>>> @@ -4695,7 +4695,7 @@ static bool bxt_digital_port_connected(struct
>>> drm_i915_private *dev_priv,
>>>    *
>>>    * Return %true if @port is connected, %false otherwise.
>>>    */
>>> -static bool intel_digital_port_connected(struct drm_i915_private
>>> *dev_priv,
>>> +bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
>>>                                           struct intel_digital_port *port)
>>>   {
>>>          if (HAS_PCH_IBX(dev_priv))
>>> diff --git a/drivers/gpu/drm/i915/intel_drv.h
>>> b/drivers/gpu/drm/i915/intel_drv.h
>>> index b6c2c20..ac6d748 100644
>>> --- a/drivers/gpu/drm/i915/intel_drv.h
>>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>>> @@ -1210,6 +1210,8 @@ void intel_edp_drrs_disable(struct intel_dp
>>> *intel_dp);
>>>   void intel_edp_drrs_invalidate(struct drm_device *dev,
>>>                  unsigned frontbuffer_bits);
>>>   void intel_edp_drrs_flush(struct drm_device *dev, unsigned
>>> frontbuffer_bits);
>>> +bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
>>> +                                        struct intel_digital_port *port);
>> g>
>>>   /* intel_dp_mst.c */
>>>   int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port,
>>> int conn_id);
>>> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c
>>> b/drivers/gpu/drm/i915/intel_hdmi.c
>>> index 1eda71a..d366ca5 100644
>>> --- a/drivers/gpu/drm/i915/intel_hdmi.c
>>> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
>>> @@ -1329,22 +1329,23 @@ intel_hdmi_unset_edid(struct drm_connector
>>> *connector)
>>>   }
>>>
>>>   static bool
>>> -intel_hdmi_set_edid(struct drm_connector *connector)
>>> +intel_hdmi_set_edid(struct drm_connector *connector, bool force)
>>>   {
>>>          struct drm_i915_private *dev_priv = to_i915(connector->dev);
>>>          struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
>>>          struct intel_encoder *intel_encoder =
>>>                  &hdmi_to_dig_port(intel_hdmi)->base;
>>>          enum intel_display_power_domain power_domain;
>>> -       struct edid *edid;
>>> +       struct edid *edid = NULL;
>>>          bool connected = false;
>>>
>>>          power_domain = intel_display_port_power_domain(intel_encoder);
>>>          intel_display_power_get(dev_priv, power_domain);
>>>
>>> -       edid = drm_get_edid(connector,
>>> -                           intel_gmbus_get_adapter(dev_priv,
>>> -                                                   intel_hdmi->ddc_bus));
>>> +       if (force)
>>> +               edid = drm_get_edid(connector,
>>> +                                   intel_gmbus_get_adapter(dev_priv,
>>> +                                   intel_hdmi->ddc_bus));
>>>
>>>          intel_display_power_put(dev_priv, power_domain);
>>>
>>> @@ -1374,14 +1375,25 @@ void intel_hdmi_probe(struct intel_encoder
>>> *intel_encoder)
>>>                          enc_to_intel_hdmi(&intel_encoder->base);
>>>          struct intel_connector *intel_connector =
>>>                                  intel_hdmi->attached_connector;
>>> +       struct drm_i915_private *dev_priv =
>>> to_i915(intel_encoder->base.dev);
>>> +       bool live_status = false;
>>> +       unsigned int retry = 3;
>>> +
>>> +       while (!live_status && --retry) {
>>> +               live_status = intel_digital_port_connected(dev_priv,
>>> +                               hdmi_to_dig_port(intel_hdmi));
>>> +               mdelay(10);
>>> +       }
>>>
>>> +       if (!live_status)
>>> +               DRM_DEBUG_KMS("Live status not up!");
>>>          /*
>>>           * We are here, means there is a hotplug or a force
>>>           * detection. Clear the cached EDID and probe the
>>>           * DDC bus to check the current status of HDMI.
>>>           */
>>>          intel_hdmi_unset_edid(&intel_connector->base);
>>> -       if (intel_hdmi_set_edid(&intel_connector->base))
>>> +       if (intel_hdmi_set_edid(&intel_connector->base, live_status))
>>>                  DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
>>>          else
>>>                  DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
>>> @@ -1432,7 +1444,7 @@ intel_hdmi_force(struct drm_connector *connector)
>>>          if (connector->status != connector_status_connected)
>>>                  return;
>>>
>>> -       intel_hdmi_set_edid(connector);
>>> +       intel_hdmi_set_edid(connector, true);
>>>          hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
>>>   }
>>>
>>> --
>>> 1.7.10.4
>>>
>>> _______________________________________________
>>> Intel-gfx mailing list
>>> Intel-gfx@lists.freedesktop.org
>>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>>>
>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915/bxt: Use intel_encoder->hpd_pin to check live status
  2015-09-14  8:38         ` Jindal, Sonika
@ 2015-09-14  9:15           ` Daniel Vetter
  0 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2015-09-14  9:15 UTC (permalink / raw)
  To: Jindal, Sonika; +Cc: intel-gfx

On Mon, Sep 14, 2015 at 02:08:41PM +0530, Jindal, Sonika wrote:
> 
> 
> On 9/14/2015 2:04 PM, Daniel Vetter wrote:
> >On Fri, Sep 11, 2015 at 04:58:32PM +0530, Sonika Jindal wrote:
> >>Using intel_encoder's hpd_pin to check the live status
> >>because of BXT A0/A1 WA for HPD pins and hpd_pin contains the
> >>updated pin for the corresponding port.
> >>
> >>Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> >>---
> >>  drivers/gpu/drm/i915/intel_dp.c |    9 ++++++---
> >>  1 file changed, 6 insertions(+), 3 deletions(-)
> >>
> >>diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> >>index 796f930..bf17030 100644
> >>--- a/drivers/gpu/drm/i915/intel_dp.c
> >>+++ b/drivers/gpu/drm/i915/intel_dp.c
> >>@@ -4663,11 +4663,14 @@ static bool vlv_digital_port_connected(struct drm_i915_private *dev_priv,
> >>  }
> >>
> >>  static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
> >>-				       struct intel_digital_port *port)
> >>+				       struct intel_digital_port *intel_dig_port)
> >>  {
> >>+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
> >>+	enum port port;
> >>  	u32 bit;
> >>
> >>-	switch (port->port) {
> >>+	intel_hpd_pin_to_port(intel_encoder->hpd_pin, &port);
> >
> >This looks very wrong - the function you're calling here maps from hpd_pin
> >to the port, but what you actually want is to map from port to pin. That
> >mapping is in intel_encoder->hpd_pin.
> >-Daniel
> No, I want to find out the correct port whose hpd bit we need to check.
> That port we are finding based upon the hpd_pin we have set for that
> encoder. This was the whole point of using hpd_pin for the BXT A0/A1 WA.
> That instead of checking different HPD bit based upon the port, just change
> the hpd_pin itself in intel_encoder.

Ah right I was getting confused. Patch applied now, thanks for clarifying.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915: Check live status before reading edid
  2015-09-14  9:14             ` Jindal, Sonika
@ 2015-09-14  9:36               ` Daniel Vetter
  2015-09-15  4:14                 ` Sonika Jindal
  0 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2015-09-14  9:36 UTC (permalink / raw)
  To: Jindal, Sonika; +Cc: intel-gfx

On Mon, Sep 14, 2015 at 02:44:01PM +0530, Jindal, Sonika wrote:
> 
> 
> On 9/14/2015 2:12 PM, Daniel Vetter wrote:
> >On Fri, Sep 11, 2015 at 05:56:47PM +0000, Rodrigo Vivi wrote:
> >>Thanks
> >>
> >>Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> >>
> >>
> >>On Fri, Sep 11, 2015 at 4:38 AM Sonika Jindal <sonika.jindal@intel.com>
> >>wrote:
> >>
> >>>The Bspec is very clear that Live status must be checked about before
> >>>trying to read EDID over DDC channel. This patch makes sure that HDMI
> >>>EDID is read only when live status is up.
> >>>
> >>>The live status doesn't seem to perform very consistent across various
> >>>platforms when tested with different monitors. The reason behind that is
> >>>some monitors are late to provide right voltage to set live_status up.
> >>>So, after getting the interrupt, for a small duration, live status reg
> >>>fluctuates, and then settles down showing the correct staus.
> >>>
> >>>This is explained here in, in a rough way:
> >>>HPD line  ________________
> >>>                          |\ T1 = Monitor Hotplug causing IRQ
> >>>                          | \______________________________________
> >>>                          | |
> >>>                          | |
> >>>                          | |   T2 = Live status is stable
> >>>                          | |  _____________________________________
> >>>                          | | /|
> >>>Live status _____________|_|/ |
> >>>                          | |  |
> >>>                          | |  |
> >>>                          | |  |
> >>>                         T0 T1  T2
> >>>
> >>>(Between T1 and T2 Live status fluctuates or can be even low, depending on
> >>>  the monitor)
> >>>
> >>>After several experiments, we have concluded that a max delay
> >>>of 30ms is enough to allow the live status to settle down with
> >>>most of the monitors. This total delay of 30ms has been split into
> >>>a resolution of 3 retries of 10ms each, for the better cases.
> >>>
> >>>This delay is kept at 30ms, keeping in consideration that, HDCP compliance
> >>>expect the HPD handler to respond a plug out in 100ms, by disabling port.
> >>>
> >>>v2: Adding checks for VLV/CHV as well. Reusing old ibx and g4x functions
> >>>to check digital port status. Adding a separate function to get bxt live
> >>>status (Daniel)
> >>>v3: Using intel_encoder->hpd_pin to check the live status (Siva)
> >>>Moving the live status read to intel_hdmi_probe and passing parameter
> >>>to read/not to read the edid. (me)
> >>>v4:
> >>>* Added live status check for all platforms using
> >>>intel_digital_port_connected.
> >>>* Rebased on top of Jani's DP cleanup series
> >>>* Some monitors take time in setting the live status. So retry for few
> >>>times if this is a connect HPD
> >>>v5: Removed extra "drm/i915" from commit message. Adding Shashank's sob
> >>>     which was missed.
> >>>v6: Drop the (!detect_edid && !live_status check) check because for DDI
> >>>ports which are enumerated as hdmi as well as DP, we don't have a
> >>>mechanism to differentiate between DP and hdmi inside the encoder's
> >>>hot_plug. This leads to call to the hdmi's hot_plug hook for DP as well
> >>>as hdmi which leads to issues during unplug because of the above check.
> >>>v7: Make intel_digital_port_connected global in this patch, some
> >>>reformatting of while loop, adding a print when live status is not
> >>>up. (Rodrigo)
> >>>
> >>>Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
> >>>Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> >
> >Since this is tricky stuff and other patches in this series are blocked
> >until we have a clearer picture can you please rebase this to be the first
> >patch on top of -nightly so that I can pull it in directly?
> >
> >I tried to do that but proved a bit too messy.
> >-Daniel
> >
> Hmm, since rebasing this will require these changes (check for live status)
> to go in detect and then later when we reach a conclusion on
> hot_plug hook, we would need to move it to that function.
> I think lets wait for the conclusion on the placement of that function.
> What do you suggest?

I think given how tricky this patch here is with testing it's preferably
to get it int as soon as possible. Yes that means shuffling things around
twice. But since the structure of how we'll handle hpd isn't clear yet at
all there's a really high chance that you need to rework this patch
anyway. So I don't expect doing this rebase right now will be more work.
And it will give us better testing coverage, which is always good to have.

Thanks, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 2/6] drm/i915: Add HDMI probe function
  2015-09-14  8:30         ` Daniel Vetter
@ 2015-09-14  9:55           ` Sharma, Shashank
  2015-09-14 13:07             ` Daniel Vetter
  0 siblings, 1 reply; 77+ messages in thread
From: Sharma, Shashank @ 2015-09-14  9:55 UTC (permalink / raw)
  To: Daniel Vetter, Jindal, Sonika; +Cc: intel-gfx

> You need to inject a fake hpd or similar everytime the world might have changed from under us, which isn't just init but also system resume.
This is a fake hpd only, just without wrapper, if you want, we can create a wrapper function like (intel_hdmi_insert_fake_hpd), and call this function from init()
And call HDMI probe(hot_plug) function from here. This would be just adding some CPU cycles in the code. 

> Adding hacks like these in the init code is certainly the wrong approach, since we never done detection this early (so surprising from a high-level
> ordering) and it also misses resume (which is why it should be done in code shared between driver load and resume).
During the ADF code development, we saw that fb_console comes up very soon, as soon as the intel_fbdev is ready, causing a detect() on a connected HDMI. 
Do you think intel_hpd_init() would be the right place to probe, coz as you rightly mentioned, we will need this on suspend/resume also. 

Regards
Shashank
-----Original Message-----
From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of Daniel Vetter
Sent: Monday, September 14, 2015 2:00 PM
To: Jindal, Sonika
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH 2/6] drm/i915: Add HDMI probe function

On Fri, Sep 11, 2015 at 04:15:39PM +0530, Jindal, Sonika wrote:
> 
> 
> On 9/10/2015 12:25 AM, Rodrigo Vivi wrote:
> >I liked the approach and agree with Daniel, so with his suggestions 
> >feel free to use:
> >Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com 
> ><mailto:rodrigo.vivi@intel.com>>
> >
> >On Fri, Sep 4, 2015 at 7:46 AM Daniel Vetter <daniel@ffwll.ch 
> ><mailto:daniel@ffwll.ch>> wrote:
> >
> >    On Fri, Sep 04, 2015 at 06:56:12PM +0530, Sonika Jindal wrote:
> >     > From: Shashank Sharma <shashank.sharma@intel.com
> >    <mailto:shashank.sharma@intel.com>>
> >     >
> >     > This patch adds a separate probe function for HDMI
> >     > EDID read over DDC channel. This function has been
> >     > registered as a .hot_plug handler for HDMI encoder.
> >     >
> >     > The current implementation of hdmi_detect()
> >     > function re-sets the cached HDMI edid (in connector->detect_edid) in
> >     > every detect call.This function gets called many times, sometimes
> >     > directly from userspace probes, forcing drivers to read EDID every
> >     > detect function call.This causes several problems like:
> >     >
> >     > 1. Race conditions in multiple hot_plug / unplug cases, between
> >     >    interrupts bottom halves and userspace detections.
> >     > 2. Many Un-necessary EDID reads for single hotplug/unplug
> >     > 3. HDMI complaince failures which expects only one EDID read per
> >    hotplug
> >     >
> >     > This function will be serving the purpose of really reading the EDID
> >     > by really probing the DDC channel, and updating the cached EDID.
> >     >
> >     > The plan is to:
> >     > 1. i915 IRQ handler bottom half function already calls
> >     >    intel_encoder->hotplug() function. Adding This probe function
> >    which
> >     >    will read the EDID only in case of a hotplug / unplug.
> >     > 2. During init_connector his probe will be called to read the edid
> >     > 3. Reuse the cached EDID in hdmi_detect() function.
> >     >
> >     > The "< gen7" check is there because this was tested only for >=gen7
> >     > platforms. For older platforms the hotplug/reading edid path
> >    remains same.
> >     >
> >     > v2: Calling set_edid instead of hdmi_probe during init.
> >     > Also, for platforms having DDI, intel_encoder for DP and HDMI is same
> >     > (taken from intel_dig_port), so for DP also, hot_plug function
> >    gets called
> >     > which is not intended here. So, check for HDMI in intel_hdmi_probe
> >     > Rely on HPD for updating edid only for platforms gen > 8 and also
> >    for VLV.
> >     >
> >     > v3: Dropping the gen < 8 || !VLV  check. Now all platforms should
> >    rely on
> >     > hotplug or init for updating the edid.(Daniel)
> >     > Also, calling hdmi_probe in init instead of set_edid
> >     >
> >     > Signed-off-by: Shashank Sharma <shashank.sharma@intel.com
> >    <mailto:shashank.sharma@intel.com>>
> >     > Signed-off-by: Sonika Jindal <sonika.jindal@intel.com
> >    <mailto:sonika.jindal@intel.com>>
> >     > ---
> >     >  drivers/gpu/drm/i915/intel_hdmi.c |   46
> >    ++++++++++++++++++++++++++++++++-----
> >     >  1 file changed, 40 insertions(+), 6 deletions(-)
> >     >
> >     > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c
> >    b/drivers/gpu/drm/i915/intel_hdmi.c
> >     > index 5bdb386..1eda71a 100644
> >     > --- a/drivers/gpu/drm/i915/intel_hdmi.c
> >     > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> >     > @@ -1368,23 +1368,53 @@ intel_hdmi_set_edid(struct drm_connector
> >    *connector)
> >     >       return connected;
> >     >  }
> >     >
> >     > +void intel_hdmi_probe(struct intel_encoder *intel_encoder)
> >
> >    Please call it _hot_plug if it's for the _hot_plug path.
> >
> Hmm, initial plan was to call it from other places if any..
> But now it seems more logical to name it _hot_plug.
> I will do that.
> 
> >     > +{
> >     > +     struct intel_hdmi *intel_hdmi =
> >     > +                     enc_to_intel_hdmi(&intel_encoder->base);
> >     > +     struct intel_connector *intel_connector =
> >     > +                             intel_hdmi->attached_connector;
> >     > +
> >     > +     /*
> >     > +      * We are here, means there is a hotplug or a force
> >     > +      * detection. Clear the cached EDID and probe the
> >     > +      * DDC bus to check the current status of HDMI.
> >     > +      */
> >     > +     intel_hdmi_unset_edid(&intel_connector->base);
> >     > +     if (intel_hdmi_set_edid(&intel_connector->base))
> >     > +             DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
> >     > +     else
> >     > +             DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
> >     > +}
> >     > +
> >     >  static enum drm_connector_status
> >     >  intel_hdmi_detect(struct drm_connector *connector, bool force)
> >     >  {
> >     >       enum drm_connector_status status;
> >     > +     struct intel_connector *intel_connector =
> >     > +                             to_intel_connector(connector);
> >     >
> >     >       DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> >     >                     connector->base.id <http://base.id>,
> >    connector->name);
> >     > +     /*
> >     > +      * There are many userspace calls which probe EDID from
> >     > +      * detect path. In case of multiple hotplug/unplug, these
> >     > +      * can cause race conditions while probing EDID. Also its
> >     > +      * waste of CPU cycles to read the EDID again and again
> >     > +      * unless there is a real hotplug.
> >     > +      * So, rely on hotplugs and init to read edid.
> >     > +      * Check connector status based on availability of cached EDID.
> >     > +      */
> >     >
> >     > -     intel_hdmi_unset_edid(connector);
> >     > -
> >     > -     if (intel_hdmi_set_edid(connector)) {
> >     > +     if (intel_connector->detect_edid) {
> >     >               struct intel_hdmi *intel_hdmi =
> >    intel_attached_hdmi(connector);
> >     > -
> >     > -             hdmi_to_dig_port(intel_hdmi)->base.type =
> >    INTEL_OUTPUT_HDMI;
> >     >               status = connector_status_connected;
> >     > -     } else
> >     > +             hdmi_to_dig_port(intel_hdmi)->base.type =
> >    INTEL_OUTPUT_HDMI;
> >     > +             DRM_DEBUG_DRIVER("hdmi status = connected\n");
> >     > +     } else {
> >     >               status = connector_status_disconnected;
> >     > +             DRM_DEBUG_DRIVER("hdmi status = disconnected\n");
> >     > +     }
> >     >
> >     >       return status;
> >     >  }
> >     > @@ -2104,11 +2134,15 @@ void intel_hdmi_init_connector(struct
> >    intel_digital_port *intel_dig_port,
> >     >       intel_connector->unregister = intel_connector_unregister;
> >     >
> >     >       intel_hdmi_add_properties(intel_hdmi, connector);
> >     > +     intel_encoder->hot_plug = intel_hdmi_probe;
> >     >
> >     >       intel_connector_attach_encoder(intel_connector, intel_encoder);
> >     >       drm_connector_register(connector);
> >     >       intel_hdmi->attached_connector = intel_connector;
> >     >
> >     > +     /* Set edid during init */
> >     > +     intel_hdmi_probe(intel_encoder);
> >
> >    Separate patch, but we really don't want this, initial probe should be
> >    done async to avoid stalling the driver.
> >    -Daniel
> 
> Where else do you suggest to do this? detect call is one place which 
> does this for DP and used to do for HDMI also.
> But since we need to take the edid reading part out of edid, I dont 
> see any other place.
> Please suggest.

You need to inject a fake hpd or similar everytime the world might have changed from under us, which isn't just init but also system resume.

We do that already, so you just have to make sure that keeps on working.
Probably another reason why it would be better to rework that entire hpd handling/detection code, to make sure it's clean and can be understood.

Adding hacks like these in the init code is certainly the wrong approach, since we never done detection this early (so surprising from a high-level
ordering) and it also misses resume (which is why it should be done in code shared between driver load and resume).
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 2/6] drm/i915: Add HDMI probe function
  2015-09-14  9:55           ` Sharma, Shashank
@ 2015-09-14 13:07             ` Daniel Vetter
  2015-09-14 13:45               ` Sharma, Shashank
  0 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2015-09-14 13:07 UTC (permalink / raw)
  To: Sharma, Shashank; +Cc: intel-gfx

On Mon, Sep 14, 2015 at 09:55:33AM +0000, Sharma, Shashank wrote:
> > You need to inject a fake hpd or similar everytime the world might have changed from under us, which isn't just init but also system resume.
> This is a fake hpd only, just without wrapper, if you want, we can
> create a wrapper function like (intel_hdmi_insert_fake_hpd), and call
> this function from init() And call HDMI probe(hot_plug) function from
> here. This would be just adding some CPU cycles in the code. 

We already have fake hpd handling, and it's done at a higher level (and in
all the correct places) using drm_helper_hpd_irq_event.

Your patch here breaks that, but then only partially fixes things up again
(you're missing system resume). That's not a good design, since it means
we need bandaids all over also in the future for anything else (like DP).

Hence imo why we should create a new overall design with how this is
supposed to be handled, and then change the core bits (so probably we need
an intel version of drm_helper_hpd_irq_event and use that instead of the
current calls). Eventually we want to make that async to speed up resume.

> > Adding hacks like these in the init code is certainly the wrong approach, since we never done detection this early (so surprising from a high-level
> > ordering) and it also misses resume (which is why it should be done in code shared between driver load and resume).
> During the ADF code development, we saw that fb_console comes up very
> soon, as soon as the intel_fbdev is ready, causing a detect() on a
> connected HDMI.  Do you think intel_hpd_init() would be the right place
> to probe, coz as you rightly mentioned, we will need this on
> suspend/resume also. 

Nope. fbdev is optional and you can't rely upon that, or write the code
assuming it's there. The initial probing at driver load time is atm not
done at all, we rely upon fbdev or early userspace to do the probing.

What you probably want to do instead is reset the edid cache on driver
load and on resume to make sure we don't cache a potentially bogus edid.
We have the encoder->reset hook for that kind of work. That might be
another approach.

But doing probe in _init for dynamic ports isnt' the right approach imo.
-Daniel

> 
> Regards
> Shashank
> -----Original Message-----
> From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of Daniel Vetter
> Sent: Monday, September 14, 2015 2:00 PM
> To: Jindal, Sonika
> Cc: intel-gfx@lists.freedesktop.org
> Subject: Re: [Intel-gfx] [PATCH 2/6] drm/i915: Add HDMI probe function
> 
> On Fri, Sep 11, 2015 at 04:15:39PM +0530, Jindal, Sonika wrote:
> > 
> > 
> > On 9/10/2015 12:25 AM, Rodrigo Vivi wrote:
> > >I liked the approach and agree with Daniel, so with his suggestions 
> > >feel free to use:
> > >Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com 
> > ><mailto:rodrigo.vivi@intel.com>>
> > >
> > >On Fri, Sep 4, 2015 at 7:46 AM Daniel Vetter <daniel@ffwll.ch 
> > ><mailto:daniel@ffwll.ch>> wrote:
> > >
> > >    On Fri, Sep 04, 2015 at 06:56:12PM +0530, Sonika Jindal wrote:
> > >     > From: Shashank Sharma <shashank.sharma@intel.com
> > >    <mailto:shashank.sharma@intel.com>>
> > >     >
> > >     > This patch adds a separate probe function for HDMI
> > >     > EDID read over DDC channel. This function has been
> > >     > registered as a .hot_plug handler for HDMI encoder.
> > >     >
> > >     > The current implementation of hdmi_detect()
> > >     > function re-sets the cached HDMI edid (in connector->detect_edid) in
> > >     > every detect call.This function gets called many times, sometimes
> > >     > directly from userspace probes, forcing drivers to read EDID every
> > >     > detect function call.This causes several problems like:
> > >     >
> > >     > 1. Race conditions in multiple hot_plug / unplug cases, between
> > >     >    interrupts bottom halves and userspace detections.
> > >     > 2. Many Un-necessary EDID reads for single hotplug/unplug
> > >     > 3. HDMI complaince failures which expects only one EDID read per
> > >    hotplug
> > >     >
> > >     > This function will be serving the purpose of really reading the EDID
> > >     > by really probing the DDC channel, and updating the cached EDID.
> > >     >
> > >     > The plan is to:
> > >     > 1. i915 IRQ handler bottom half function already calls
> > >     >    intel_encoder->hotplug() function. Adding This probe function
> > >    which
> > >     >    will read the EDID only in case of a hotplug / unplug.
> > >     > 2. During init_connector his probe will be called to read the edid
> > >     > 3. Reuse the cached EDID in hdmi_detect() function.
> > >     >
> > >     > The "< gen7" check is there because this was tested only for >=gen7
> > >     > platforms. For older platforms the hotplug/reading edid path
> > >    remains same.
> > >     >
> > >     > v2: Calling set_edid instead of hdmi_probe during init.
> > >     > Also, for platforms having DDI, intel_encoder for DP and HDMI is same
> > >     > (taken from intel_dig_port), so for DP also, hot_plug function
> > >    gets called
> > >     > which is not intended here. So, check for HDMI in intel_hdmi_probe
> > >     > Rely on HPD for updating edid only for platforms gen > 8 and also
> > >    for VLV.
> > >     >
> > >     > v3: Dropping the gen < 8 || !VLV  check. Now all platforms should
> > >    rely on
> > >     > hotplug or init for updating the edid.(Daniel)
> > >     > Also, calling hdmi_probe in init instead of set_edid
> > >     >
> > >     > Signed-off-by: Shashank Sharma <shashank.sharma@intel.com
> > >    <mailto:shashank.sharma@intel.com>>
> > >     > Signed-off-by: Sonika Jindal <sonika.jindal@intel.com
> > >    <mailto:sonika.jindal@intel.com>>
> > >     > ---
> > >     >  drivers/gpu/drm/i915/intel_hdmi.c |   46
> > >    ++++++++++++++++++++++++++++++++-----
> > >     >  1 file changed, 40 insertions(+), 6 deletions(-)
> > >     >
> > >     > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c
> > >    b/drivers/gpu/drm/i915/intel_hdmi.c
> > >     > index 5bdb386..1eda71a 100644
> > >     > --- a/drivers/gpu/drm/i915/intel_hdmi.c
> > >     > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> > >     > @@ -1368,23 +1368,53 @@ intel_hdmi_set_edid(struct drm_connector
> > >    *connector)
> > >     >       return connected;
> > >     >  }
> > >     >
> > >     > +void intel_hdmi_probe(struct intel_encoder *intel_encoder)
> > >
> > >    Please call it _hot_plug if it's for the _hot_plug path.
> > >
> > Hmm, initial plan was to call it from other places if any..
> > But now it seems more logical to name it _hot_plug.
> > I will do that.
> > 
> > >     > +{
> > >     > +     struct intel_hdmi *intel_hdmi =
> > >     > +                     enc_to_intel_hdmi(&intel_encoder->base);
> > >     > +     struct intel_connector *intel_connector =
> > >     > +                             intel_hdmi->attached_connector;
> > >     > +
> > >     > +     /*
> > >     > +      * We are here, means there is a hotplug or a force
> > >     > +      * detection. Clear the cached EDID and probe the
> > >     > +      * DDC bus to check the current status of HDMI.
> > >     > +      */
> > >     > +     intel_hdmi_unset_edid(&intel_connector->base);
> > >     > +     if (intel_hdmi_set_edid(&intel_connector->base))
> > >     > +             DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
> > >     > +     else
> > >     > +             DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
> > >     > +}
> > >     > +
> > >     >  static enum drm_connector_status
> > >     >  intel_hdmi_detect(struct drm_connector *connector, bool force)
> > >     >  {
> > >     >       enum drm_connector_status status;
> > >     > +     struct intel_connector *intel_connector =
> > >     > +                             to_intel_connector(connector);
> > >     >
> > >     >       DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> > >     >                     connector->base.id <http://base.id>,
> > >    connector->name);
> > >     > +     /*
> > >     > +      * There are many userspace calls which probe EDID from
> > >     > +      * detect path. In case of multiple hotplug/unplug, these
> > >     > +      * can cause race conditions while probing EDID. Also its
> > >     > +      * waste of CPU cycles to read the EDID again and again
> > >     > +      * unless there is a real hotplug.
> > >     > +      * So, rely on hotplugs and init to read edid.
> > >     > +      * Check connector status based on availability of cached EDID.
> > >     > +      */
> > >     >
> > >     > -     intel_hdmi_unset_edid(connector);
> > >     > -
> > >     > -     if (intel_hdmi_set_edid(connector)) {
> > >     > +     if (intel_connector->detect_edid) {
> > >     >               struct intel_hdmi *intel_hdmi =
> > >    intel_attached_hdmi(connector);
> > >     > -
> > >     > -             hdmi_to_dig_port(intel_hdmi)->base.type =
> > >    INTEL_OUTPUT_HDMI;
> > >     >               status = connector_status_connected;
> > >     > -     } else
> > >     > +             hdmi_to_dig_port(intel_hdmi)->base.type =
> > >    INTEL_OUTPUT_HDMI;
> > >     > +             DRM_DEBUG_DRIVER("hdmi status = connected\n");
> > >     > +     } else {
> > >     >               status = connector_status_disconnected;
> > >     > +             DRM_DEBUG_DRIVER("hdmi status = disconnected\n");
> > >     > +     }
> > >     >
> > >     >       return status;
> > >     >  }
> > >     > @@ -2104,11 +2134,15 @@ void intel_hdmi_init_connector(struct
> > >    intel_digital_port *intel_dig_port,
> > >     >       intel_connector->unregister = intel_connector_unregister;
> > >     >
> > >     >       intel_hdmi_add_properties(intel_hdmi, connector);
> > >     > +     intel_encoder->hot_plug = intel_hdmi_probe;
> > >     >
> > >     >       intel_connector_attach_encoder(intel_connector, intel_encoder);
> > >     >       drm_connector_register(connector);
> > >     >       intel_hdmi->attached_connector = intel_connector;
> > >     >
> > >     > +     /* Set edid during init */
> > >     > +     intel_hdmi_probe(intel_encoder);
> > >
> > >    Separate patch, but we really don't want this, initial probe should be
> > >    done async to avoid stalling the driver.
> > >    -Daniel
> > 
> > Where else do you suggest to do this? detect call is one place which 
> > does this for DP and used to do for HDMI also.
> > But since we need to take the edid reading part out of edid, I dont 
> > see any other place.
> > Please suggest.
> 
> You need to inject a fake hpd or similar everytime the world might have changed from under us, which isn't just init but also system resume.
> 
> We do that already, so you just have to make sure that keeps on working.
> Probably another reason why it would be better to rework that entire hpd handling/detection code, to make sure it's clean and can be understood.
> 
> Adding hacks like these in the init code is certainly the wrong approach, since we never done detection this early (so surprising from a high-level
> ordering) and it also misses resume (which is why it should be done in code shared between driver load and resume).
> -Daniel
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 2/6] drm/i915: Add HDMI probe function
  2015-09-14 13:07             ` Daniel Vetter
@ 2015-09-14 13:45               ` Sharma, Shashank
  2015-09-28  8:56                 ` [PATCH] drm/i915: Add hot_plug hook for hdmi encoder Sonika Jindal
  0 siblings, 1 reply; 77+ messages in thread
From: Sharma, Shashank @ 2015-09-14 13:45 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

Regards
Shashank

On 9/14/2015 6:37 PM, Daniel Vetter wrote:
> On Mon, Sep 14, 2015 at 09:55:33AM +0000, Sharma, Shashank wrote:
>>> You need to inject a fake hpd or similar everytime the world might have changed from under us, which isn't just init but also system resume.
>> This is a fake hpd only, just without wrapper, if you want, we can
>> create a wrapper function like (intel_hdmi_insert_fake_hpd), and call
>> this function from init() And call HDMI probe(hot_plug) function from
>> here. This would be just adding some CPU cycles in the code.
>
> We already have fake hpd handling, and it's done at a higher level (and in
> all the correct places) using drm_helper_hpd_irq_event.
>
Thanks, this sounds like a good suggestion here.
We can call the hot_plug() from drm_helper_hpd_irq_event, just before it 
calls the detect(), and our state machine is still intact.
> Your patch here breaks that, but then only partially fixes things up again
> (you're missing system resume). That's not a good design, since it means
> we need bandaids all over also in the future for anything else (like DP).
>
I guess, in this was we wont break anything existing.
> Hence imo why we should create a new overall design with how this is
> supposed to be handled, and then change the core bits (so probably we need
> an intel version of drm_helper_hpd_irq_event and use that instead of the
> current calls). Eventually we want to make that async to speed up resume.
>
>>> Adding hacks like these in the init code is certainly the wrong approach, since we never done detection this early (so surprising from a high-level
>>> ordering) and it also misses resume (which is why it should be done in code shared between driver load and resume).
>> During the ADF code development, we saw that fb_console comes up very
>> soon, as soon as the intel_fbdev is ready, causing a detect() on a
>> connected HDMI.  Do you think intel_hpd_init() would be the right place
>> to probe, coz as you rightly mentioned, we will need this on
>> suspend/resume also.
>
> Nope. fbdev is optional and you can't rely upon that, or write the code
> assuming it's there. The initial probing at driver load time is atm not
> done at all, we rely upon fbdev or early userspace to do the probing.
>
> What you probably want to do instead is reset the edid cache on driver
> load and on resume to make sure we don't cache a potentially bogus edid.
> We have the encoder->reset hook for that kind of work. That might be
> another approach.
>
Yes, thats exactly what hot_plug function does. It checks the live 
status and if we have cached EDID, it releases the EDID. Now its just 
matter of calling this from the right place, in the right way.
> But doing probe in _init for dynamic ports isnt' the right approach imo.
> -Daniel
>
Yep, agree. Let us work on this part.
>>
>> Regards
>> Shashank
>> -----Original Message-----
>> From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of Daniel Vetter
>> Sent: Monday, September 14, 2015 2:00 PM
>> To: Jindal, Sonika
>> Cc: intel-gfx@lists.freedesktop.org
>> Subject: Re: [Intel-gfx] [PATCH 2/6] drm/i915: Add HDMI probe function
>>
>> On Fri, Sep 11, 2015 at 04:15:39PM +0530, Jindal, Sonika wrote:
>>>
>>>
>>> On 9/10/2015 12:25 AM, Rodrigo Vivi wrote:
>>>> I liked the approach and agree with Daniel, so with his suggestions
>>>> feel free to use:
>>>> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com
>>>> <mailto:rodrigo.vivi@intel.com>>
>>>>
>>>> On Fri, Sep 4, 2015 at 7:46 AM Daniel Vetter <daniel@ffwll.ch
>>>> <mailto:daniel@ffwll.ch>> wrote:
>>>>
>>>>     On Fri, Sep 04, 2015 at 06:56:12PM +0530, Sonika Jindal wrote:
>>>>      > From: Shashank Sharma <shashank.sharma@intel.com
>>>>     <mailto:shashank.sharma@intel.com>>
>>>>      >
>>>>      > This patch adds a separate probe function for HDMI
>>>>      > EDID read over DDC channel. This function has been
>>>>      > registered as a .hot_plug handler for HDMI encoder.
>>>>      >
>>>>      > The current implementation of hdmi_detect()
>>>>      > function re-sets the cached HDMI edid (in connector->detect_edid) in
>>>>      > every detect call.This function gets called many times, sometimes
>>>>      > directly from userspace probes, forcing drivers to read EDID every
>>>>      > detect function call.This causes several problems like:
>>>>      >
>>>>      > 1. Race conditions in multiple hot_plug / unplug cases, between
>>>>      >    interrupts bottom halves and userspace detections.
>>>>      > 2. Many Un-necessary EDID reads for single hotplug/unplug
>>>>      > 3. HDMI complaince failures which expects only one EDID read per
>>>>     hotplug
>>>>      >
>>>>      > This function will be serving the purpose of really reading the EDID
>>>>      > by really probing the DDC channel, and updating the cached EDID.
>>>>      >
>>>>      > The plan is to:
>>>>      > 1. i915 IRQ handler bottom half function already calls
>>>>      >    intel_encoder->hotplug() function. Adding This probe function
>>>>     which
>>>>      >    will read the EDID only in case of a hotplug / unplug.
>>>>      > 2. During init_connector his probe will be called to read the edid
>>>>      > 3. Reuse the cached EDID in hdmi_detect() function.
>>>>      >
>>>>      > The "< gen7" check is there because this was tested only for >=gen7
>>>>      > platforms. For older platforms the hotplug/reading edid path
>>>>     remains same.
>>>>      >
>>>>      > v2: Calling set_edid instead of hdmi_probe during init.
>>>>      > Also, for platforms having DDI, intel_encoder for DP and HDMI is same
>>>>      > (taken from intel_dig_port), so for DP also, hot_plug function
>>>>     gets called
>>>>      > which is not intended here. So, check for HDMI in intel_hdmi_probe
>>>>      > Rely on HPD for updating edid only for platforms gen > 8 and also
>>>>     for VLV.
>>>>      >
>>>>      > v3: Dropping the gen < 8 || !VLV  check. Now all platforms should
>>>>     rely on
>>>>      > hotplug or init for updating the edid.(Daniel)
>>>>      > Also, calling hdmi_probe in init instead of set_edid
>>>>      >
>>>>      > Signed-off-by: Shashank Sharma <shashank.sharma@intel.com
>>>>     <mailto:shashank.sharma@intel.com>>
>>>>      > Signed-off-by: Sonika Jindal <sonika.jindal@intel.com
>>>>     <mailto:sonika.jindal@intel.com>>
>>>>      > ---
>>>>      >  drivers/gpu/drm/i915/intel_hdmi.c |   46
>>>>     ++++++++++++++++++++++++++++++++-----
>>>>      >  1 file changed, 40 insertions(+), 6 deletions(-)
>>>>      >
>>>>      > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c
>>>>     b/drivers/gpu/drm/i915/intel_hdmi.c
>>>>      > index 5bdb386..1eda71a 100644
>>>>      > --- a/drivers/gpu/drm/i915/intel_hdmi.c
>>>>      > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
>>>>      > @@ -1368,23 +1368,53 @@ intel_hdmi_set_edid(struct drm_connector
>>>>     *connector)
>>>>      >       return connected;
>>>>      >  }
>>>>      >
>>>>      > +void intel_hdmi_probe(struct intel_encoder *intel_encoder)
>>>>
>>>>     Please call it _hot_plug if it's for the _hot_plug path.
>>>>
>>> Hmm, initial plan was to call it from other places if any..
>>> But now it seems more logical to name it _hot_plug.
>>> I will do that.
>>>
>>>>      > +{
>>>>      > +     struct intel_hdmi *intel_hdmi =
>>>>      > +                     enc_to_intel_hdmi(&intel_encoder->base);
>>>>      > +     struct intel_connector *intel_connector =
>>>>      > +                             intel_hdmi->attached_connector;
>>>>      > +
>>>>      > +     /*
>>>>      > +      * We are here, means there is a hotplug or a force
>>>>      > +      * detection. Clear the cached EDID and probe the
>>>>      > +      * DDC bus to check the current status of HDMI.
>>>>      > +      */
>>>>      > +     intel_hdmi_unset_edid(&intel_connector->base);
>>>>      > +     if (intel_hdmi_set_edid(&intel_connector->base))
>>>>      > +             DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
>>>>      > +     else
>>>>      > +             DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
>>>>      > +}
>>>>      > +
>>>>      >  static enum drm_connector_status
>>>>      >  intel_hdmi_detect(struct drm_connector *connector, bool force)
>>>>      >  {
>>>>      >       enum drm_connector_status status;
>>>>      > +     struct intel_connector *intel_connector =
>>>>      > +                             to_intel_connector(connector);
>>>>      >
>>>>      >       DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
>>>>      >                     connector->base.id <http://base.id>,
>>>>     connector->name);
>>>>      > +     /*
>>>>      > +      * There are many userspace calls which probe EDID from
>>>>      > +      * detect path. In case of multiple hotplug/unplug, these
>>>>      > +      * can cause race conditions while probing EDID. Also its
>>>>      > +      * waste of CPU cycles to read the EDID again and again
>>>>      > +      * unless there is a real hotplug.
>>>>      > +      * So, rely on hotplugs and init to read edid.
>>>>      > +      * Check connector status based on availability of cached EDID.
>>>>      > +      */
>>>>      >
>>>>      > -     intel_hdmi_unset_edid(connector);
>>>>      > -
>>>>      > -     if (intel_hdmi_set_edid(connector)) {
>>>>      > +     if (intel_connector->detect_edid) {
>>>>      >               struct intel_hdmi *intel_hdmi =
>>>>     intel_attached_hdmi(connector);
>>>>      > -
>>>>      > -             hdmi_to_dig_port(intel_hdmi)->base.type =
>>>>     INTEL_OUTPUT_HDMI;
>>>>      >               status = connector_status_connected;
>>>>      > -     } else
>>>>      > +             hdmi_to_dig_port(intel_hdmi)->base.type =
>>>>     INTEL_OUTPUT_HDMI;
>>>>      > +             DRM_DEBUG_DRIVER("hdmi status = connected\n");
>>>>      > +     } else {
>>>>      >               status = connector_status_disconnected;
>>>>      > +             DRM_DEBUG_DRIVER("hdmi status = disconnected\n");
>>>>      > +     }
>>>>      >
>>>>      >       return status;
>>>>      >  }
>>>>      > @@ -2104,11 +2134,15 @@ void intel_hdmi_init_connector(struct
>>>>     intel_digital_port *intel_dig_port,
>>>>      >       intel_connector->unregister = intel_connector_unregister;
>>>>      >
>>>>      >       intel_hdmi_add_properties(intel_hdmi, connector);
>>>>      > +     intel_encoder->hot_plug = intel_hdmi_probe;
>>>>      >
>>>>      >       intel_connector_attach_encoder(intel_connector, intel_encoder);
>>>>      >       drm_connector_register(connector);
>>>>      >       intel_hdmi->attached_connector = intel_connector;
>>>>      >
>>>>      > +     /* Set edid during init */
>>>>      > +     intel_hdmi_probe(intel_encoder);
>>>>
>>>>     Separate patch, but we really don't want this, initial probe should be
>>>>     done async to avoid stalling the driver.
>>>>     -Daniel
>>>
>>> Where else do you suggest to do this? detect call is one place which
>>> does this for DP and used to do for HDMI also.
>>> But since we need to take the edid reading part out of edid, I dont
>>> see any other place.
>>> Please suggest.
>>
>> You need to inject a fake hpd or similar everytime the world might have changed from under us, which isn't just init but also system resume.
>>
>> We do that already, so you just have to make sure that keeps on working.
>> Probably another reason why it would be better to rework that entire hpd handling/detection code, to make sure it's clean and can be understood.
>>
>> Adding hacks like these in the init code is certainly the wrong approach, since we never done detection this early (so surprising from a high-level
>> ordering) and it also misses resume (which is why it should be done in code shared between driver load and resume).
>> -Daniel
>> --
>> Daniel Vetter
>> Software Engineer, Intel Corporation
>> http://blog.ffwll.ch
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [PATCH] drm/i915: Check live status before reading edid
  2015-09-14  9:36               ` Daniel Vetter
@ 2015-09-15  4:14                 ` Sonika Jindal
  2015-09-23  8:18                   ` Daniel Vetter
  2016-03-08 21:03                   ` Chris Wilson
  0 siblings, 2 replies; 77+ messages in thread
From: Sonika Jindal @ 2015-09-15  4:14 UTC (permalink / raw)
  To: intel-gfx

The Bspec is very clear that Live status must be checked about before
trying to read EDID over DDC channel. This patch makes sure that HDMI
EDID is read only when live status is up.

The live status doesn't seem to perform very consistent across various
platforms when tested with different monitors. The reason behind that is
some monitors are late to provide right voltage to set live_status up.
So, after getting the interrupt, for a small duration, live status reg
fluctuates, and then settles down showing the correct staus.

This is explained here in, in a rough way:
HPD line  ________________
			 |\ T1 = Monitor Hotplug causing IRQ
			 | \______________________________________
			 | |
                         | |
			 | |   T2 = Live status is stable
			 | |  _____________________________________
			 | | /|
Live status _____________|_|/ |
			 | |  |
			 | |  |
			 | |  |
			T0 T1  T2

(Between T1 and T2 Live status fluctuates or can be even low, depending on
 the monitor)

After several experiments, we have concluded that a max delay
of 30ms is enough to allow the live status to settle down with
most of the monitors. This total delay of 30ms has been split into
a resolution of 3 retries of 10ms each, for the better cases.

This delay is kept at 30ms, keeping in consideration that, HDCP compliance
expect the HPD handler to respond a plug out in 100ms, by disabling port.

v2: Adding checks for VLV/CHV as well. Reusing old ibx and g4x functions
to check digital port status. Adding a separate function to get bxt live
status (Daniel)
v3: Using intel_encoder->hpd_pin to check the live status (Siva)
Moving the live status read to intel_hdmi_probe and passing parameter
to read/not to read the edid. (me)
v4:
* Added live status check for all platforms using
intel_digital_port_connected.
* Rebased on top of Jani's DP cleanup series
* Some monitors take time in setting the live status. So retry for few
times if this is a connect HPD
v5: Removed extra "drm/i915" from commit message. Adding Shashank's sob
    which was missed.
v6: Drop the (!detect_edid && !live_status check) check because for DDI
ports which are enumerated as hdmi as well as DP, we don't have a
mechanism to differentiate between DP and hdmi inside the encoder's
hot_plug. This leads to call to the hdmi's hot_plug hook for DP as well
as hdmi which leads to issues during unplug because of the above check.
v7: Make intel_digital_port_connected global in this patch, some
reformatting of while loop, adding a print when live status is not
up. (Rodrigo)
v8: Rebase it on nightly which involved skipping the hot_plug hook for now
and letting the live_status check happen in detect until the hpd handling
part is finalized (Daniel)

Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c   |    2 +-
 drivers/gpu/drm/i915/intel_drv.h  |    2 ++
 drivers/gpu/drm/i915/intel_hdmi.c |   28 +++++++++++++++++++++-------
 3 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index a687250..a6e22dd 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -4670,7 +4670,7 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
  *
  * Return %true if @port is connected, %false otherwise.
  */
-static bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
+bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
 					 struct intel_digital_port *port)
 {
 	if (HAS_PCH_IBX(dev_priv))
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 08ba362..1e01350 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1210,6 +1210,8 @@ void intel_edp_drrs_disable(struct intel_dp *intel_dp);
 void intel_edp_drrs_invalidate(struct drm_device *dev,
 		unsigned frontbuffer_bits);
 void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits);
+bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
+					 struct intel_digital_port *port);
 void hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config);
 
 /* intel_dp_mst.c */
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index e978c59..bb33c66 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1329,22 +1329,23 @@ intel_hdmi_unset_edid(struct drm_connector *connector)
 }
 
 static bool
-intel_hdmi_set_edid(struct drm_connector *connector)
+intel_hdmi_set_edid(struct drm_connector *connector, bool force)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
 	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 	struct intel_encoder *intel_encoder =
 		&hdmi_to_dig_port(intel_hdmi)->base;
 	enum intel_display_power_domain power_domain;
-	struct edid *edid;
+	struct edid *edid = NULL;
 	bool connected = false;
 
 	power_domain = intel_display_port_power_domain(intel_encoder);
 	intel_display_power_get(dev_priv, power_domain);
 
-	edid = drm_get_edid(connector,
-			    intel_gmbus_get_adapter(dev_priv,
-						    intel_hdmi->ddc_bus));
+	if (force)
+		edid = drm_get_edid(connector,
+				    intel_gmbus_get_adapter(dev_priv,
+				    intel_hdmi->ddc_bus));
 
 	intel_display_power_put(dev_priv, power_domain);
 
@@ -1372,13 +1373,26 @@ static enum drm_connector_status
 intel_hdmi_detect(struct drm_connector *connector, bool force)
 {
 	enum drm_connector_status status;
+	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
+	struct drm_i915_private *dev_priv = to_i915(connector->dev);
+	bool live_status = false;
+	unsigned int retry = 3;
 
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
 		      connector->base.id, connector->name);
 
+	while (!live_status && --retry) {
+		live_status = intel_digital_port_connected(dev_priv,
+				hdmi_to_dig_port(intel_hdmi));
+		mdelay(10);
+	}
+
+	if (!live_status)
+		DRM_DEBUG_KMS("Live status not up!");
+
 	intel_hdmi_unset_edid(connector);
 
-	if (intel_hdmi_set_edid(connector)) {
+	if (intel_hdmi_set_edid(connector, live_status)) {
 		struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 
 		hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
@@ -1402,7 +1416,7 @@ intel_hdmi_force(struct drm_connector *connector)
 	if (connector->status != connector_status_connected)
 		return;
 
-	intel_hdmi_set_edid(connector);
+	intel_hdmi_set_edid(connector, true);
 	hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
 }
 
-- 
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915: Check live status before reading edid
  2015-09-15  4:14                 ` Sonika Jindal
@ 2015-09-23  8:18                   ` Daniel Vetter
  2016-03-08 21:03                   ` Chris Wilson
  1 sibling, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2015-09-23  8:18 UTC (permalink / raw)
  To: Sonika Jindal; +Cc: intel-gfx

On Tue, Sep 15, 2015 at 09:44:20AM +0530, Sonika Jindal wrote:
> The Bspec is very clear that Live status must be checked about before
> trying to read EDID over DDC channel. This patch makes sure that HDMI
> EDID is read only when live status is up.
> 
> The live status doesn't seem to perform very consistent across various
> platforms when tested with different monitors. The reason behind that is
> some monitors are late to provide right voltage to set live_status up.
> So, after getting the interrupt, for a small duration, live status reg
> fluctuates, and then settles down showing the correct staus.
> 
> This is explained here in, in a rough way:
> HPD line  ________________
> 			 |\ T1 = Monitor Hotplug causing IRQ
> 			 | \______________________________________
> 			 | |
>                          | |
> 			 | |   T2 = Live status is stable
> 			 | |  _____________________________________
> 			 | | /|
> Live status _____________|_|/ |
> 			 | |  |
> 			 | |  |
> 			 | |  |
> 			T0 T1  T2
> 
> (Between T1 and T2 Live status fluctuates or can be even low, depending on
>  the monitor)
> 
> After several experiments, we have concluded that a max delay
> of 30ms is enough to allow the live status to settle down with
> most of the monitors. This total delay of 30ms has been split into
> a resolution of 3 retries of 10ms each, for the better cases.
> 
> This delay is kept at 30ms, keeping in consideration that, HDCP compliance
> expect the HPD handler to respond a plug out in 100ms, by disabling port.
> 
> v2: Adding checks for VLV/CHV as well. Reusing old ibx and g4x functions
> to check digital port status. Adding a separate function to get bxt live
> status (Daniel)
> v3: Using intel_encoder->hpd_pin to check the live status (Siva)
> Moving the live status read to intel_hdmi_probe and passing parameter
> to read/not to read the edid. (me)
> v4:
> * Added live status check for all platforms using
> intel_digital_port_connected.
> * Rebased on top of Jani's DP cleanup series
> * Some monitors take time in setting the live status. So retry for few
> times if this is a connect HPD
> v5: Removed extra "drm/i915" from commit message. Adding Shashank's sob
>     which was missed.
> v6: Drop the (!detect_edid && !live_status check) check because for DDI
> ports which are enumerated as hdmi as well as DP, we don't have a
> mechanism to differentiate between DP and hdmi inside the encoder's
> hot_plug. This leads to call to the hdmi's hot_plug hook for DP as well
> as hdmi which leads to issues during unplug because of the above check.
> v7: Make intel_digital_port_connected global in this patch, some
> reformatting of while loop, adding a print when live status is not
> up. (Rodrigo)
> v8: Rebase it on nightly which involved skipping the hot_plug hook for now
> and letting the live_status check happen in detect until the hpd handling
> part is finalized (Daniel)
> 
> Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

Queued for -next, thanks for the patch.
-Daniel

> ---
>  drivers/gpu/drm/i915/intel_dp.c   |    2 +-
>  drivers/gpu/drm/i915/intel_drv.h  |    2 ++
>  drivers/gpu/drm/i915/intel_hdmi.c |   28 +++++++++++++++++++++-------
>  3 files changed, 24 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index a687250..a6e22dd 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -4670,7 +4670,7 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
>   *
>   * Return %true if @port is connected, %false otherwise.
>   */
> -static bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
> +bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
>  					 struct intel_digital_port *port)
>  {
>  	if (HAS_PCH_IBX(dev_priv))
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 08ba362..1e01350 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1210,6 +1210,8 @@ void intel_edp_drrs_disable(struct intel_dp *intel_dp);
>  void intel_edp_drrs_invalidate(struct drm_device *dev,
>  		unsigned frontbuffer_bits);
>  void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits);
> +bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
> +					 struct intel_digital_port *port);
>  void hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config);
>  
>  /* intel_dp_mst.c */
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index e978c59..bb33c66 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -1329,22 +1329,23 @@ intel_hdmi_unset_edid(struct drm_connector *connector)
>  }
>  
>  static bool
> -intel_hdmi_set_edid(struct drm_connector *connector)
> +intel_hdmi_set_edid(struct drm_connector *connector, bool force)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(connector->dev);
>  	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
>  	struct intel_encoder *intel_encoder =
>  		&hdmi_to_dig_port(intel_hdmi)->base;
>  	enum intel_display_power_domain power_domain;
> -	struct edid *edid;
> +	struct edid *edid = NULL;
>  	bool connected = false;
>  
>  	power_domain = intel_display_port_power_domain(intel_encoder);
>  	intel_display_power_get(dev_priv, power_domain);
>  
> -	edid = drm_get_edid(connector,
> -			    intel_gmbus_get_adapter(dev_priv,
> -						    intel_hdmi->ddc_bus));
> +	if (force)
> +		edid = drm_get_edid(connector,
> +				    intel_gmbus_get_adapter(dev_priv,
> +				    intel_hdmi->ddc_bus));
>  
>  	intel_display_power_put(dev_priv, power_domain);
>  
> @@ -1372,13 +1373,26 @@ static enum drm_connector_status
>  intel_hdmi_detect(struct drm_connector *connector, bool force)
>  {
>  	enum drm_connector_status status;
> +	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
> +	struct drm_i915_private *dev_priv = to_i915(connector->dev);
> +	bool live_status = false;
> +	unsigned int retry = 3;
>  
>  	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
>  		      connector->base.id, connector->name);
>  
> +	while (!live_status && --retry) {
> +		live_status = intel_digital_port_connected(dev_priv,
> +				hdmi_to_dig_port(intel_hdmi));
> +		mdelay(10);
> +	}
> +
> +	if (!live_status)
> +		DRM_DEBUG_KMS("Live status not up!");
> +
>  	intel_hdmi_unset_edid(connector);
>  
> -	if (intel_hdmi_set_edid(connector)) {
> +	if (intel_hdmi_set_edid(connector, live_status)) {
>  		struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
>  
>  		hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
> @@ -1402,7 +1416,7 @@ intel_hdmi_force(struct drm_connector *connector)
>  	if (connector->status != connector_status_connected)
>  		return;
>  
> -	intel_hdmi_set_edid(connector);
> +	intel_hdmi_set_edid(connector, true);
>  	hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
>  }
>  
> -- 
> 1.7.10.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [PATCH] drm/i915: Add hot_plug hook for hdmi encoder
  2015-09-14 13:45               ` Sharma, Shashank
@ 2015-09-28  8:56                 ` Sonika Jindal
  2015-09-28 13:34                   ` Daniel Vetter
  0 siblings, 1 reply; 77+ messages in thread
From: Sonika Jindal @ 2015-09-28  8:56 UTC (permalink / raw)
  To: intel-gfx

This patch adds a separate probe function for HDMI
EDID read over DDC channel. This function has been
registered as a .hot_plug handler for HDMI encoder.

The current implementation of hdmi_detect()
function re-sets the cached HDMI edid (in connector->detect_edid) in
every detect call.This function gets called many times, sometimes
directly from userspace probes, forcing drivers to read EDID every
detect function call.This causes several problems like:

1. Race conditions in multiple hot_plug / unplug cases, between
   interrupts bottom halves and userspace detections.
2. Many Un-necessary EDID reads for single hotplug/unplug
3. HDMI complaince failures which expects only one EDID read per hotplug

This function will be serving the purpose of really reading the EDID
by really probing the DDC channel, and updating the cached EDID.

The plan is to:
1. i915 IRQ handler bottom half function already calls
   intel_encoder->hotplug() function. Adding This probe function which
   will read the EDID only in case of a hotplug / unplug.
2. During init_connector this probe will be called to read the edid
3. Reuse the cached EDID in hdmi_detect() function.

The "< gen7" check is there because this was tested only for >=gen7
platforms. For older platforms the hotplug/reading edid path remains same.

v2: Calling set_edid instead of hdmi_probe during init.
Also, for platforms having DDI, intel_encoder for DP and HDMI is same
(taken from intel_dig_port), so for DP also, hot_plug function gets called
which is not intended here. So, check for HDMI in intel_hdmi_probe
Rely on HPD for updating edid only for platforms gen > 8 and also for VLV.

v3: Dropping the gen < 8 || !VLV  check. Now all platforms should rely on
hotplug or init for updating the edid.(Daniel)
Also, calling hdmi_probe in init instead of set_edid

v4: Renaming intel_hdmi_probe to intel_hdmi_hot_plug and changing the patch
subject. Also calling this hotplug handler from intel_hpd_init to take care
of init resume scenarios.

Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/i915/intel_hdmi.c    |   54 +++++++++++++++++++++++++++-------
 drivers/gpu/drm/i915/intel_hotplug.c |   11 +++++++
 2 files changed, 54 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index bb33c66..9c1a308 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1369,18 +1369,16 @@ intel_hdmi_set_edid(struct drm_connector *connector, bool force)
 	return connected;
 }
 
-static enum drm_connector_status
-intel_hdmi_detect(struct drm_connector *connector, bool force)
+void intel_hdmi_hot_plug(struct intel_encoder *intel_encoder)
 {
-	enum drm_connector_status status;
-	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->dev);
+	struct intel_hdmi *intel_hdmi =
+			enc_to_intel_hdmi(&intel_encoder->base);
+	struct intel_connector *intel_connector =
+				intel_hdmi->attached_connector;
+	struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
 	bool live_status = false;
 	unsigned int retry = 3;
 
-	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
-		      connector->base.id, connector->name);
-
 	while (!live_status && --retry) {
 		live_status = intel_digital_port_connected(dev_priv,
 				hdmi_to_dig_port(intel_hdmi));
@@ -1390,15 +1388,48 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
 	if (!live_status)
 		DRM_DEBUG_KMS("Live status not up!");
 
-	intel_hdmi_unset_edid(connector);
+	/*
+	 * We are here, means there is a hotplug or a force
+	 * detection. Clear the cached EDID and probe the
+	 * DDC bus to check the current status of HDMI.
+	 */
+	intel_hdmi_unset_edid(&intel_connector->base);
+	if (intel_hdmi_set_edid(&intel_connector->base, live_status))
+		DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
+	else
+		DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
+}
 
-	if (intel_hdmi_set_edid(connector, live_status)) {
+static enum drm_connector_status
+intel_hdmi_detect(struct drm_connector *connector, bool force)
+{
+	enum drm_connector_status status;
+	struct intel_connector *intel_connector =
+				to_intel_connector(connector);
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+		      connector->base.id, connector->name);
+
+	/*
+	 * There are many userspace calls which probe EDID from
+	 * detect path. In case of multiple hotplug/unplug, these
+	 * can cause race conditions while probing EDID. Also its
+	 * waste of CPU cycles to read the EDID again and again
+	 * unless there is a real hotplug.
+	 * So, rely on hotplugs and init to read edid.
+	 * Check connector status based on availability of cached EDID.
+	 */
+
+	if (intel_connector->detect_edid) {
 		struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 
 		hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
 		status = connector_status_connected;
-	} else
+		DRM_DEBUG_DRIVER("hdmi status = connected\n");
+	} else {
 		status = connector_status_disconnected;
+		DRM_DEBUG_DRIVER("hdmi status = disconnected\n");
+	}
 
 	return status;
 }
@@ -2131,6 +2162,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 	intel_connector->unregister = intel_connector_unregister;
 
 	intel_hdmi_add_properties(intel_hdmi, connector);
+	intel_encoder->hot_plug = intel_hdmi_hot_plug;
 
 	intel_connector_attach_encoder(intel_connector, intel_encoder);
 	drm_connector_register(connector);
diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
index 53c0173..36e16f6 100644
--- a/drivers/gpu/drm/i915/intel_hotplug.c
+++ b/drivers/gpu/drm/i915/intel_hotplug.c
@@ -459,6 +459,7 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
 	struct drm_device *dev = dev_priv->dev;
 	struct drm_mode_config *mode_config = &dev->mode_config;
 	struct drm_connector *connector;
+	struct intel_encoder *encoder;
 	int i;
 
 	for_each_hpd_pin(i) {
@@ -482,6 +483,16 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
 	if (dev_priv->display.hpd_irq_setup)
 		dev_priv->display.hpd_irq_setup(dev);
 	spin_unlock_irq(&dev_priv->irq_lock);
+
+	/*
+	 * Connected boot / resume scenarios can't generate new hot plug.
+	 * So, probe it manually.
+	 */
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list,
+			    base.head) {
+		if (encoder->hot_plug)
+			encoder->hot_plug(encoder);
+	}
 }
 
 void intel_hpd_init_work(struct drm_i915_private *dev_priv)
-- 
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915: Add hot_plug hook for hdmi encoder
  2015-09-28  8:56                 ` [PATCH] drm/i915: Add hot_plug hook for hdmi encoder Sonika Jindal
@ 2015-09-28 13:34                   ` Daniel Vetter
  2015-09-29  4:13                     ` Jindal, Sonika
  2015-10-05 11:13                     ` [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases Sonika Jindal
  0 siblings, 2 replies; 77+ messages in thread
From: Daniel Vetter @ 2015-09-28 13:34 UTC (permalink / raw)
  To: Sonika Jindal; +Cc: intel-gfx

On Mon, Sep 28, 2015 at 02:26:04PM +0530, Sonika Jindal wrote:
> This patch adds a separate probe function for HDMI
> EDID read over DDC channel. This function has been
> registered as a .hot_plug handler for HDMI encoder.
> 
> The current implementation of hdmi_detect()
> function re-sets the cached HDMI edid (in connector->detect_edid) in
> every detect call.This function gets called many times, sometimes
> directly from userspace probes, forcing drivers to read EDID every
> detect function call.This causes several problems like:
> 
> 1. Race conditions in multiple hot_plug / unplug cases, between
>    interrupts bottom halves and userspace detections.
> 2. Many Un-necessary EDID reads for single hotplug/unplug
> 3. HDMI complaince failures which expects only one EDID read per hotplug
> 
> This function will be serving the purpose of really reading the EDID
> by really probing the DDC channel, and updating the cached EDID.
> 
> The plan is to:
> 1. i915 IRQ handler bottom half function already calls
>    intel_encoder->hotplug() function. Adding This probe function which
>    will read the EDID only in case of a hotplug / unplug.
> 2. During init_connector this probe will be called to read the edid
> 3. Reuse the cached EDID in hdmi_detect() function.
> 
> The "< gen7" check is there because this was tested only for >=gen7
> platforms. For older platforms the hotplug/reading edid path remains same.
> 
> v2: Calling set_edid instead of hdmi_probe during init.
> Also, for platforms having DDI, intel_encoder for DP and HDMI is same
> (taken from intel_dig_port), so for DP also, hot_plug function gets called
> which is not intended here. So, check for HDMI in intel_hdmi_probe
> Rely on HPD for updating edid only for platforms gen > 8 and also for VLV.
> 
> v3: Dropping the gen < 8 || !VLV  check. Now all platforms should rely on
> hotplug or init for updating the edid.(Daniel)
> Also, calling hdmi_probe in init instead of set_edid
> 
> v4: Renaming intel_hdmi_probe to intel_hdmi_hot_plug and changing the patch
> subject. Also calling this hotplug handler from intel_hpd_init to take care
> of init resume scenarios.
> 
> Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_hdmi.c    |   54 +++++++++++++++++++++++++++-------
>  drivers/gpu/drm/i915/intel_hotplug.c |   11 +++++++
>  2 files changed, 54 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index bb33c66..9c1a308 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -1369,18 +1369,16 @@ intel_hdmi_set_edid(struct drm_connector *connector, bool force)
>  	return connected;
>  }
>  
> -static enum drm_connector_status
> -intel_hdmi_detect(struct drm_connector *connector, bool force)
> +void intel_hdmi_hot_plug(struct intel_encoder *intel_encoder)
>  {
> -	enum drm_connector_status status;
> -	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->dev);
> +	struct intel_hdmi *intel_hdmi =
> +			enc_to_intel_hdmi(&intel_encoder->base);
> +	struct intel_connector *intel_connector =
> +				intel_hdmi->attached_connector;
> +	struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
>  	bool live_status = false;
>  	unsigned int retry = 3;
>  
> -	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> -		      connector->base.id, connector->name);
> -
>  	while (!live_status && --retry) {
>  		live_status = intel_digital_port_connected(dev_priv,
>  				hdmi_to_dig_port(intel_hdmi));
> @@ -1390,15 +1388,48 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
>  	if (!live_status)
>  		DRM_DEBUG_KMS("Live status not up!");
>  
> -	intel_hdmi_unset_edid(connector);
> +	/*
> +	 * We are here, means there is a hotplug or a force
> +	 * detection. Clear the cached EDID and probe the
> +	 * DDC bus to check the current status of HDMI.
> +	 */
> +	intel_hdmi_unset_edid(&intel_connector->base);
> +	if (intel_hdmi_set_edid(&intel_connector->base, live_status))
> +		DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
> +	else
> +		DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
> +}
>  
> -	if (intel_hdmi_set_edid(connector, live_status)) {
> +static enum drm_connector_status
> +intel_hdmi_detect(struct drm_connector *connector, bool force)
> +{
> +	enum drm_connector_status status;
> +	struct intel_connector *intel_connector =
> +				to_intel_connector(connector);
> +
> +	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> +		      connector->base.id, connector->name);
> +
> +	/*
> +	 * There are many userspace calls which probe EDID from
> +	 * detect path. In case of multiple hotplug/unplug, these
> +	 * can cause race conditions while probing EDID. Also its
> +	 * waste of CPU cycles to read the EDID again and again
> +	 * unless there is a real hotplug.
> +	 * So, rely on hotplugs and init to read edid.
> +	 * Check connector status based on availability of cached EDID.
> +	 */
> +
> +	if (intel_connector->detect_edid) {
>  		struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
>  
>  		hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
>  		status = connector_status_connected;
> -	} else
> +		DRM_DEBUG_DRIVER("hdmi status = connected\n");
> +	} else {
>  		status = connector_status_disconnected;
> +		DRM_DEBUG_DRIVER("hdmi status = disconnected\n");
> +	}
>  
>  	return status;
>  }
> @@ -2131,6 +2162,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
>  	intel_connector->unregister = intel_connector_unregister;
>  
>  	intel_hdmi_add_properties(intel_hdmi, connector);
> +	intel_encoder->hot_plug = intel_hdmi_hot_plug;
>  
>  	intel_connector_attach_encoder(intel_connector, intel_encoder);
>  	drm_connector_register(connector);
> diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
> index 53c0173..36e16f6 100644
> --- a/drivers/gpu/drm/i915/intel_hotplug.c
> +++ b/drivers/gpu/drm/i915/intel_hotplug.c
> @@ -459,6 +459,7 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
>  	struct drm_device *dev = dev_priv->dev;
>  	struct drm_mode_config *mode_config = &dev->mode_config;
>  	struct drm_connector *connector;
> +	struct intel_encoder *encoder;
>  	int i;
>  
>  	for_each_hpd_pin(i) {
> @@ -482,6 +483,16 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
>  	if (dev_priv->display.hpd_irq_setup)
>  		dev_priv->display.hpd_irq_setup(dev);
>  	spin_unlock_irq(&dev_priv->irq_lock);
> +
> +	/*
> +	 * Connected boot / resume scenarios can't generate new hot plug.
> +	 * So, probe it manually.
> +	 */
> +	list_for_each_entry(encoder, &dev->mode_config.encoder_list,
> +			    base.head) {
> +		if (encoder->hot_plug)
> +			encoder->hot_plug(encoder);
> +	}

Since this doesn't just change hdmi but every encoder I think we should
pull it out into a separate prep patch. Especially interactions with dp
mst handling look tricky, have you tested that nothing blows up with that?
The split-out patch should definitely explain in detail how this interacts
with dp hpd handling.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915: Add hot_plug hook for hdmi encoder
  2015-09-28 13:34                   ` Daniel Vetter
@ 2015-09-29  4:13                     ` Jindal, Sonika
  2015-09-29  9:04                       ` Daniel Vetter
  2015-10-05 11:13                     ` [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases Sonika Jindal
  1 sibling, 1 reply; 77+ messages in thread
From: Jindal, Sonika @ 2015-09-29  4:13 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx



On 9/28/2015 7:04 PM, Daniel Vetter wrote:
> On Mon, Sep 28, 2015 at 02:26:04PM +0530, Sonika Jindal wrote:
>> This patch adds a separate probe function for HDMI
>> EDID read over DDC channel. This function has been
>> registered as a .hot_plug handler for HDMI encoder.
>>
>> The current implementation of hdmi_detect()
>> function re-sets the cached HDMI edid (in connector->detect_edid) in
>> every detect call.This function gets called many times, sometimes
>> directly from userspace probes, forcing drivers to read EDID every
>> detect function call.This causes several problems like:
>>
>> 1. Race conditions in multiple hot_plug / unplug cases, between
>>     interrupts bottom halves and userspace detections.
>> 2. Many Un-necessary EDID reads for single hotplug/unplug
>> 3. HDMI complaince failures which expects only one EDID read per hotplug
>>
>> This function will be serving the purpose of really reading the EDID
>> by really probing the DDC channel, and updating the cached EDID.
>>
>> The plan is to:
>> 1. i915 IRQ handler bottom half function already calls
>>     intel_encoder->hotplug() function. Adding This probe function which
>>     will read the EDID only in case of a hotplug / unplug.
>> 2. During init_connector this probe will be called to read the edid
>> 3. Reuse the cached EDID in hdmi_detect() function.
>>
>> The "< gen7" check is there because this was tested only for >=gen7
>> platforms. For older platforms the hotplug/reading edid path remains same.
>>
>> v2: Calling set_edid instead of hdmi_probe during init.
>> Also, for platforms having DDI, intel_encoder for DP and HDMI is same
>> (taken from intel_dig_port), so for DP also, hot_plug function gets called
>> which is not intended here. So, check for HDMI in intel_hdmi_probe
>> Rely on HPD for updating edid only for platforms gen > 8 and also for VLV.
>>
>> v3: Dropping the gen < 8 || !VLV  check. Now all platforms should rely on
>> hotplug or init for updating the edid.(Daniel)
>> Also, calling hdmi_probe in init instead of set_edid
>>
>> v4: Renaming intel_hdmi_probe to intel_hdmi_hot_plug and changing the patch
>> subject. Also calling this hotplug handler from intel_hpd_init to take care
>> of init resume scenarios.
>>
>> Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
>> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
>> ---
>>   drivers/gpu/drm/i915/intel_hdmi.c    |   54 +++++++++++++++++++++++++++-------
>>   drivers/gpu/drm/i915/intel_hotplug.c |   11 +++++++
>>   2 files changed, 54 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
>> index bb33c66..9c1a308 100644
>> --- a/drivers/gpu/drm/i915/intel_hdmi.c
>> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
>> @@ -1369,18 +1369,16 @@ intel_hdmi_set_edid(struct drm_connector *connector, bool force)
>>   	return connected;
>>   }
>>
>> -static enum drm_connector_status
>> -intel_hdmi_detect(struct drm_connector *connector, bool force)
>> +void intel_hdmi_hot_plug(struct intel_encoder *intel_encoder)
>>   {
>> -	enum drm_connector_status status;
>> -	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
>> -	struct drm_i915_private *dev_priv = to_i915(connector->dev);
>> +	struct intel_hdmi *intel_hdmi =
>> +			enc_to_intel_hdmi(&intel_encoder->base);
>> +	struct intel_connector *intel_connector =
>> +				intel_hdmi->attached_connector;
>> +	struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
>>   	bool live_status = false;
>>   	unsigned int retry = 3;
>>
>> -	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
>> -		      connector->base.id, connector->name);
>> -
>>   	while (!live_status && --retry) {
>>   		live_status = intel_digital_port_connected(dev_priv,
>>   				hdmi_to_dig_port(intel_hdmi));
>> @@ -1390,15 +1388,48 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
>>   	if (!live_status)
>>   		DRM_DEBUG_KMS("Live status not up!");
>>
>> -	intel_hdmi_unset_edid(connector);
>> +	/*
>> +	 * We are here, means there is a hotplug or a force
>> +	 * detection. Clear the cached EDID and probe the
>> +	 * DDC bus to check the current status of HDMI.
>> +	 */
>> +	intel_hdmi_unset_edid(&intel_connector->base);
>> +	if (intel_hdmi_set_edid(&intel_connector->base, live_status))
>> +		DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
>> +	else
>> +		DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
>> +}
>>
>> -	if (intel_hdmi_set_edid(connector, live_status)) {
>> +static enum drm_connector_status
>> +intel_hdmi_detect(struct drm_connector *connector, bool force)
>> +{
>> +	enum drm_connector_status status;
>> +	struct intel_connector *intel_connector =
>> +				to_intel_connector(connector);
>> +
>> +	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
>> +		      connector->base.id, connector->name);
>> +
>> +	/*
>> +	 * There are many userspace calls which probe EDID from
>> +	 * detect path. In case of multiple hotplug/unplug, these
>> +	 * can cause race conditions while probing EDID. Also its
>> +	 * waste of CPU cycles to read the EDID again and again
>> +	 * unless there is a real hotplug.
>> +	 * So, rely on hotplugs and init to read edid.
>> +	 * Check connector status based on availability of cached EDID.
>> +	 */
>> +
>> +	if (intel_connector->detect_edid) {
>>   		struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
>>
>>   		hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
>>   		status = connector_status_connected;
>> -	} else
>> +		DRM_DEBUG_DRIVER("hdmi status = connected\n");
>> +	} else {
>>   		status = connector_status_disconnected;
>> +		DRM_DEBUG_DRIVER("hdmi status = disconnected\n");
>> +	}
>>
>>   	return status;
>>   }
>> @@ -2131,6 +2162,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
>>   	intel_connector->unregister = intel_connector_unregister;
>>
>>   	intel_hdmi_add_properties(intel_hdmi, connector);
>> +	intel_encoder->hot_plug = intel_hdmi_hot_plug;
>>
>>   	intel_connector_attach_encoder(intel_connector, intel_encoder);
>>   	drm_connector_register(connector);
>> diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
>> index 53c0173..36e16f6 100644
>> --- a/drivers/gpu/drm/i915/intel_hotplug.c
>> +++ b/drivers/gpu/drm/i915/intel_hotplug.c
>> @@ -459,6 +459,7 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
>>   	struct drm_device *dev = dev_priv->dev;
>>   	struct drm_mode_config *mode_config = &dev->mode_config;
>>   	struct drm_connector *connector;
>> +	struct intel_encoder *encoder;
>>   	int i;
>>
>>   	for_each_hpd_pin(i) {
>> @@ -482,6 +483,16 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
>>   	if (dev_priv->display.hpd_irq_setup)
>>   		dev_priv->display.hpd_irq_setup(dev);
>>   	spin_unlock_irq(&dev_priv->irq_lock);
>> +
>> +	/*
>> +	 * Connected boot / resume scenarios can't generate new hot plug.
>> +	 * So, probe it manually.
>> +	 */
>> +	list_for_each_entry(encoder, &dev->mode_config.encoder_list,
>> +			    base.head) {
>> +		if (encoder->hot_plug)
>> +			encoder->hot_plug(encoder);
>> +	}
>
> Since this doesn't just change hdmi but every encoder I think we should
> pull it out into a separate prep patch. Especially interactions with dp
> mst handling look tricky, have you tested that nothing blows up with that?
> The split-out patch should definitely explain in detail how this interacts
> with dp hpd handling.
> -Daniel
>
Right now we don't set hot_plug for DP/edp encoder.
It was used only for sdvo and with this patch we add for hdmi.
Also, in sdvo_init right after assigning the hot_plug function pointer, 
we call its hot_plug function for initialization.
Maybe with this patch, we can remove that part also from sdvo_init.

I can split this patch but without this change, it will result in 
regression with just one patch. So I thought it would be better to keep 
them together in one patch.

Regards,
Sonika

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915: Add hot_plug hook for hdmi encoder
  2015-09-29  4:13                     ` Jindal, Sonika
@ 2015-09-29  9:04                       ` Daniel Vetter
  0 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2015-09-29  9:04 UTC (permalink / raw)
  To: Jindal, Sonika; +Cc: intel-gfx

On Tue, Sep 29, 2015 at 09:43:10AM +0530, Jindal, Sonika wrote:
> 
> 
> On 9/28/2015 7:04 PM, Daniel Vetter wrote:
> >On Mon, Sep 28, 2015 at 02:26:04PM +0530, Sonika Jindal wrote:
> >>This patch adds a separate probe function for HDMI
> >>EDID read over DDC channel. This function has been
> >>registered as a .hot_plug handler for HDMI encoder.
> >>
> >>The current implementation of hdmi_detect()
> >>function re-sets the cached HDMI edid (in connector->detect_edid) in
> >>every detect call.This function gets called many times, sometimes
> >>directly from userspace probes, forcing drivers to read EDID every
> >>detect function call.This causes several problems like:
> >>
> >>1. Race conditions in multiple hot_plug / unplug cases, between
> >>    interrupts bottom halves and userspace detections.
> >>2. Many Un-necessary EDID reads for single hotplug/unplug
> >>3. HDMI complaince failures which expects only one EDID read per hotplug
> >>
> >>This function will be serving the purpose of really reading the EDID
> >>by really probing the DDC channel, and updating the cached EDID.
> >>
> >>The plan is to:
> >>1. i915 IRQ handler bottom half function already calls
> >>    intel_encoder->hotplug() function. Adding This probe function which
> >>    will read the EDID only in case of a hotplug / unplug.
> >>2. During init_connector this probe will be called to read the edid
> >>3. Reuse the cached EDID in hdmi_detect() function.
> >>
> >>The "< gen7" check is there because this was tested only for >=gen7
> >>platforms. For older platforms the hotplug/reading edid path remains same.
> >>
> >>v2: Calling set_edid instead of hdmi_probe during init.
> >>Also, for platforms having DDI, intel_encoder for DP and HDMI is same
> >>(taken from intel_dig_port), so for DP also, hot_plug function gets called
> >>which is not intended here. So, check for HDMI in intel_hdmi_probe
> >>Rely on HPD for updating edid only for platforms gen > 8 and also for VLV.
> >>
> >>v3: Dropping the gen < 8 || !VLV  check. Now all platforms should rely on
> >>hotplug or init for updating the edid.(Daniel)
> >>Also, calling hdmi_probe in init instead of set_edid
> >>
> >>v4: Renaming intel_hdmi_probe to intel_hdmi_hot_plug and changing the patch
> >>subject. Also calling this hotplug handler from intel_hpd_init to take care
> >>of init resume scenarios.
> >>
> >>Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
> >>Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> >>---
> >>  drivers/gpu/drm/i915/intel_hdmi.c    |   54 +++++++++++++++++++++++++++-------
> >>  drivers/gpu/drm/i915/intel_hotplug.c |   11 +++++++
> >>  2 files changed, 54 insertions(+), 11 deletions(-)
> >>
> >>diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> >>index bb33c66..9c1a308 100644
> >>--- a/drivers/gpu/drm/i915/intel_hdmi.c
> >>+++ b/drivers/gpu/drm/i915/intel_hdmi.c
> >>@@ -1369,18 +1369,16 @@ intel_hdmi_set_edid(struct drm_connector *connector, bool force)
> >>  	return connected;
> >>  }
> >>
> >>-static enum drm_connector_status
> >>-intel_hdmi_detect(struct drm_connector *connector, bool force)
> >>+void intel_hdmi_hot_plug(struct intel_encoder *intel_encoder)
> >>  {
> >>-	enum drm_connector_status status;
> >>-	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
> >>-	struct drm_i915_private *dev_priv = to_i915(connector->dev);
> >>+	struct intel_hdmi *intel_hdmi =
> >>+			enc_to_intel_hdmi(&intel_encoder->base);
> >>+	struct intel_connector *intel_connector =
> >>+				intel_hdmi->attached_connector;
> >>+	struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
> >>  	bool live_status = false;
> >>  	unsigned int retry = 3;
> >>
> >>-	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> >>-		      connector->base.id, connector->name);
> >>-
> >>  	while (!live_status && --retry) {
> >>  		live_status = intel_digital_port_connected(dev_priv,
> >>  				hdmi_to_dig_port(intel_hdmi));
> >>@@ -1390,15 +1388,48 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
> >>  	if (!live_status)
> >>  		DRM_DEBUG_KMS("Live status not up!");
> >>
> >>-	intel_hdmi_unset_edid(connector);
> >>+	/*
> >>+	 * We are here, means there is a hotplug or a force
> >>+	 * detection. Clear the cached EDID and probe the
> >>+	 * DDC bus to check the current status of HDMI.
> >>+	 */
> >>+	intel_hdmi_unset_edid(&intel_connector->base);
> >>+	if (intel_hdmi_set_edid(&intel_connector->base, live_status))
> >>+		DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
> >>+	else
> >>+		DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
> >>+}
> >>
> >>-	if (intel_hdmi_set_edid(connector, live_status)) {
> >>+static enum drm_connector_status
> >>+intel_hdmi_detect(struct drm_connector *connector, bool force)
> >>+{
> >>+	enum drm_connector_status status;
> >>+	struct intel_connector *intel_connector =
> >>+				to_intel_connector(connector);
> >>+
> >>+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> >>+		      connector->base.id, connector->name);
> >>+
> >>+	/*
> >>+	 * There are many userspace calls which probe EDID from
> >>+	 * detect path. In case of multiple hotplug/unplug, these
> >>+	 * can cause race conditions while probing EDID. Also its
> >>+	 * waste of CPU cycles to read the EDID again and again
> >>+	 * unless there is a real hotplug.
> >>+	 * So, rely on hotplugs and init to read edid.
> >>+	 * Check connector status based on availability of cached EDID.
> >>+	 */
> >>+
> >>+	if (intel_connector->detect_edid) {
> >>  		struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
> >>
> >>  		hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
> >>  		status = connector_status_connected;
> >>-	} else
> >>+		DRM_DEBUG_DRIVER("hdmi status = connected\n");
> >>+	} else {
> >>  		status = connector_status_disconnected;
> >>+		DRM_DEBUG_DRIVER("hdmi status = disconnected\n");
> >>+	}
> >>
> >>  	return status;
> >>  }
> >>@@ -2131,6 +2162,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
> >>  	intel_connector->unregister = intel_connector_unregister;
> >>
> >>  	intel_hdmi_add_properties(intel_hdmi, connector);
> >>+	intel_encoder->hot_plug = intel_hdmi_hot_plug;
> >>
> >>  	intel_connector_attach_encoder(intel_connector, intel_encoder);
> >>  	drm_connector_register(connector);
> >>diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
> >>index 53c0173..36e16f6 100644
> >>--- a/drivers/gpu/drm/i915/intel_hotplug.c
> >>+++ b/drivers/gpu/drm/i915/intel_hotplug.c
> >>@@ -459,6 +459,7 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
> >>  	struct drm_device *dev = dev_priv->dev;
> >>  	struct drm_mode_config *mode_config = &dev->mode_config;
> >>  	struct drm_connector *connector;
> >>+	struct intel_encoder *encoder;
> >>  	int i;
> >>
> >>  	for_each_hpd_pin(i) {
> >>@@ -482,6 +483,16 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
> >>  	if (dev_priv->display.hpd_irq_setup)
> >>  		dev_priv->display.hpd_irq_setup(dev);
> >>  	spin_unlock_irq(&dev_priv->irq_lock);
> >>+
> >>+	/*
> >>+	 * Connected boot / resume scenarios can't generate new hot plug.
> >>+	 * So, probe it manually.
> >>+	 */
> >>+	list_for_each_entry(encoder, &dev->mode_config.encoder_list,
> >>+			    base.head) {
> >>+		if (encoder->hot_plug)
> >>+			encoder->hot_plug(encoder);
> >>+	}
> >
> >Since this doesn't just change hdmi but every encoder I think we should
> >pull it out into a separate prep patch. Especially interactions with dp
> >mst handling look tricky, have you tested that nothing blows up with that?
> >The split-out patch should definitely explain in detail how this interacts
> >with dp hpd handling.
> >-Daniel
> >
> Right now we don't set hot_plug for DP/edp encoder.
> It was used only for sdvo and with this patch we add for hdmi.
> Also, in sdvo_init right after assigning the hot_plug function pointer, we
> call its hot_plug function for initialization.
> Maybe with this patch, we can remove that part also from sdvo_init.

Hm right, I forgot that we have too many hotplug callbacks in our driver
;-)

> I can split this patch but without this change, it will result in regression
> with just one patch. So I thought it would be better to keep them together
> in one patch.

If you split it out and make it patch 1 and then the hdmi changes patch 2
nothing breaks in between.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
  2015-09-28 13:34                   ` Daniel Vetter
  2015-09-29  4:13                     ` Jindal, Sonika
@ 2015-10-05 11:13                     ` Sonika Jindal
  2015-10-05 11:13                       ` [PATCH 2/2] drm/i915: Add hot_plug hook for hdmi encoder Sonika Jindal
  2015-10-08 13:35                       ` [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases Ville Syrjälä
  1 sibling, 2 replies; 77+ messages in thread
From: Sonika Jindal @ 2015-10-05 11:13 UTC (permalink / raw)
  To: intel-gfx

For all the encoders, call the hot_plug if it is registered.
This is required for connected boot and resume cases to generate
fake hpd resulting in reading of edid.
Removing the initial sdvo hot_plug call too so that it will be called
just once from this loop.

Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/i915/intel_hotplug.c |   11 +++++++++++
 drivers/gpu/drm/i915/intel_sdvo.c    |    1 -
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
index 53c0173..eac4757 100644
--- a/drivers/gpu/drm/i915/intel_hotplug.c
+++ b/drivers/gpu/drm/i915/intel_hotplug.c
@@ -458,6 +458,7 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
 {
 	struct drm_device *dev = dev_priv->dev;
 	struct drm_mode_config *mode_config = &dev->mode_config;
+	struct intel_encoder *encoder;
 	struct drm_connector *connector;
 	int i;
 
@@ -482,6 +483,16 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
 	if (dev_priv->display.hpd_irq_setup)
 		dev_priv->display.hpd_irq_setup(dev);
 	spin_unlock_irq(&dev_priv->irq_lock);
+
+	/*
+	 * Connected boot / resume scenarios can't generate new hot plug.
+	 * So, probe it manually.
+	 */
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list,
+			    base.head) {
+		if (encoder->hot_plug)
+			encoder->hot_plug(encoder);
+	}
 }
 
 void intel_hpd_init_work(struct drm_i915_private *dev_priv)
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 05521b5..55859e9 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -2433,7 +2433,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
 		 * Ensure that they get re-enabled when an interrupt happens.
 		 */
 		intel_encoder->hot_plug = intel_sdvo_enable_hotplug;
-		intel_sdvo_enable_hotplug(intel_encoder);
 	} else {
 		intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
 	}
-- 
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 2/2] drm/i915: Add hot_plug hook for hdmi encoder
  2015-10-05 11:13                     ` [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases Sonika Jindal
@ 2015-10-05 11:13                       ` Sonika Jindal
  2015-10-06  8:28                         ` Daniel Vetter
  2015-10-08 13:35                       ` [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases Ville Syrjälä
  1 sibling, 1 reply; 77+ messages in thread
From: Sonika Jindal @ 2015-10-05 11:13 UTC (permalink / raw)
  To: intel-gfx

This patch adds a separate probe function for HDMI
EDID read over DDC channel. This function has been
registered as a .hot_plug handler for HDMI encoder.

The current implementation of hdmi_detect()
function re-sets the cached HDMI edid (in connector->detect_edid) in
every detect call.This function gets called many times, sometimes
directly from userspace probes, forcing drivers to read EDID every
detect function call.This causes several problems like:

1. Race conditions in multiple hot_plug / unplug cases, between
   interrupts bottom halves and userspace detections.
2. Many Un-necessary EDID reads for single hotplug/unplug
3. HDMI complaince failures which expects only one EDID read per hotplug

This function will be serving the purpose of really reading the EDID
by really probing the DDC channel, and updating the cached EDID.

The plan is to:
1. i915 IRQ handler bottom half function already calls
   intel_encoder->hotplug() function. Adding This probe function which
   will read the EDID only in case of a hotplug / unplug.
2. During init_connector this probe will be called to read the edid
3. Reuse the cached EDID in hdmi_detect() function.

The "< gen7" check is there because this was tested only for >=gen7
platforms. For older platforms the hotplug/reading edid path remains same.

v2: Calling set_edid instead of hdmi_probe during init.
Also, for platforms having DDI, intel_encoder for DP and HDMI is same
(taken from intel_dig_port), so for DP also, hot_plug function gets called
which is not intended here. So, check for HDMI in intel_hdmi_probe
Rely on HPD for updating edid only for platforms gen > 8 and also for VLV.

v3: Dropping the gen < 8 || !VLV  check. Now all platforms should rely on
hotplug or init for updating the edid.(Daniel)
Also, calling hdmi_probe in init instead of set_edid

v4: Renaming intel_hdmi_probe to intel_hdmi_hot_plug.
Also calling this hotplug handler from intel_hpd_init to take care of init
resume scenarios.

v5: Moved the call to encoder hotplug during init to separate patch(Daniel)

Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/i915/intel_hdmi.c |   54 +++++++++++++++++++++++++++++--------
 1 file changed, 43 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index bb33c66..9c1a308 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1369,18 +1369,16 @@ intel_hdmi_set_edid(struct drm_connector *connector, bool force)
 	return connected;
 }
 
-static enum drm_connector_status
-intel_hdmi_detect(struct drm_connector *connector, bool force)
+void intel_hdmi_hot_plug(struct intel_encoder *intel_encoder)
 {
-	enum drm_connector_status status;
-	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->dev);
+	struct intel_hdmi *intel_hdmi =
+			enc_to_intel_hdmi(&intel_encoder->base);
+	struct intel_connector *intel_connector =
+				intel_hdmi->attached_connector;
+	struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
 	bool live_status = false;
 	unsigned int retry = 3;
 
-	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
-		      connector->base.id, connector->name);
-
 	while (!live_status && --retry) {
 		live_status = intel_digital_port_connected(dev_priv,
 				hdmi_to_dig_port(intel_hdmi));
@@ -1390,15 +1388,48 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
 	if (!live_status)
 		DRM_DEBUG_KMS("Live status not up!");
 
-	intel_hdmi_unset_edid(connector);
+	/*
+	 * We are here, means there is a hotplug or a force
+	 * detection. Clear the cached EDID and probe the
+	 * DDC bus to check the current status of HDMI.
+	 */
+	intel_hdmi_unset_edid(&intel_connector->base);
+	if (intel_hdmi_set_edid(&intel_connector->base, live_status))
+		DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
+	else
+		DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
+}
 
-	if (intel_hdmi_set_edid(connector, live_status)) {
+static enum drm_connector_status
+intel_hdmi_detect(struct drm_connector *connector, bool force)
+{
+	enum drm_connector_status status;
+	struct intel_connector *intel_connector =
+				to_intel_connector(connector);
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+		      connector->base.id, connector->name);
+
+	/*
+	 * There are many userspace calls which probe EDID from
+	 * detect path. In case of multiple hotplug/unplug, these
+	 * can cause race conditions while probing EDID. Also its
+	 * waste of CPU cycles to read the EDID again and again
+	 * unless there is a real hotplug.
+	 * So, rely on hotplugs and init to read edid.
+	 * Check connector status based on availability of cached EDID.
+	 */
+
+	if (intel_connector->detect_edid) {
 		struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 
 		hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
 		status = connector_status_connected;
-	} else
+		DRM_DEBUG_DRIVER("hdmi status = connected\n");
+	} else {
 		status = connector_status_disconnected;
+		DRM_DEBUG_DRIVER("hdmi status = disconnected\n");
+	}
 
 	return status;
 }
@@ -2131,6 +2162,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 	intel_connector->unregister = intel_connector_unregister;
 
 	intel_hdmi_add_properties(intel_hdmi, connector);
+	intel_encoder->hot_plug = intel_hdmi_hot_plug;
 
 	intel_connector_attach_encoder(intel_connector, intel_encoder);
 	drm_connector_register(connector);
-- 
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [PATCH 2/2] drm/i915: Add hot_plug hook for hdmi encoder
  2015-10-05 11:13                       ` [PATCH 2/2] drm/i915: Add hot_plug hook for hdmi encoder Sonika Jindal
@ 2015-10-06  8:28                         ` Daniel Vetter
  2015-12-10  4:30                           ` Sonika Jindal
  0 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2015-10-06  8:28 UTC (permalink / raw)
  To: Sonika Jindal; +Cc: intel-gfx

On Mon, Oct 05, 2015 at 04:43:15PM +0530, Sonika Jindal wrote:
> This patch adds a separate probe function for HDMI
> EDID read over DDC channel. This function has been
> registered as a .hot_plug handler for HDMI encoder.
> 
> The current implementation of hdmi_detect()
> function re-sets the cached HDMI edid (in connector->detect_edid) in
> every detect call.This function gets called many times, sometimes
> directly from userspace probes, forcing drivers to read EDID every
> detect function call.This causes several problems like:
> 
> 1. Race conditions in multiple hot_plug / unplug cases, between
>    interrupts bottom halves and userspace detections.
> 2. Many Un-necessary EDID reads for single hotplug/unplug
> 3. HDMI complaince failures which expects only one EDID read per hotplug
> 
> This function will be serving the purpose of really reading the EDID
> by really probing the DDC channel, and updating the cached EDID.
> 
> The plan is to:
> 1. i915 IRQ handler bottom half function already calls
>    intel_encoder->hotplug() function. Adding This probe function which
>    will read the EDID only in case of a hotplug / unplug.
> 2. During init_connector this probe will be called to read the edid
> 3. Reuse the cached EDID in hdmi_detect() function.
> 
> The "< gen7" check is there because this was tested only for >=gen7
> platforms. For older platforms the hotplug/reading edid path remains same.
> 
> v2: Calling set_edid instead of hdmi_probe during init.
> Also, for platforms having DDI, intel_encoder for DP and HDMI is same
> (taken from intel_dig_port), so for DP also, hot_plug function gets called
> which is not intended here. So, check for HDMI in intel_hdmi_probe
> Rely on HPD for updating edid only for platforms gen > 8 and also for VLV.
> 
> v3: Dropping the gen < 8 || !VLV  check. Now all platforms should rely on
> hotplug or init for updating the edid.(Daniel)
> Also, calling hdmi_probe in init instead of set_edid
> 
> v4: Renaming intel_hdmi_probe to intel_hdmi_hot_plug.
> Also calling this hotplug handler from intel_hpd_init to take care of init
> resume scenarios.
> 
> v5: Moved the call to encoder hotplug during init to separate patch(Daniel)
> 
> Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>

I merged the first patch in this series, but I have a quick question on
this one here. Can you pls ping me on irc?

Thanks, Daniel
> ---
>  drivers/gpu/drm/i915/intel_hdmi.c |   54 +++++++++++++++++++++++++++++--------
>  1 file changed, 43 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index bb33c66..9c1a308 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -1369,18 +1369,16 @@ intel_hdmi_set_edid(struct drm_connector *connector, bool force)
>  	return connected;
>  }
>  
> -static enum drm_connector_status
> -intel_hdmi_detect(struct drm_connector *connector, bool force)
> +void intel_hdmi_hot_plug(struct intel_encoder *intel_encoder)
>  {
> -	enum drm_connector_status status;
> -	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->dev);
> +	struct intel_hdmi *intel_hdmi =
> +			enc_to_intel_hdmi(&intel_encoder->base);
> +	struct intel_connector *intel_connector =
> +				intel_hdmi->attached_connector;
> +	struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
>  	bool live_status = false;
>  	unsigned int retry = 3;
>  
> -	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> -		      connector->base.id, connector->name);
> -
>  	while (!live_status && --retry) {
>  		live_status = intel_digital_port_connected(dev_priv,
>  				hdmi_to_dig_port(intel_hdmi));
> @@ -1390,15 +1388,48 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
>  	if (!live_status)
>  		DRM_DEBUG_KMS("Live status not up!");
>  
> -	intel_hdmi_unset_edid(connector);
> +	/*
> +	 * We are here, means there is a hotplug or a force
> +	 * detection. Clear the cached EDID and probe the
> +	 * DDC bus to check the current status of HDMI.
> +	 */
> +	intel_hdmi_unset_edid(&intel_connector->base);
> +	if (intel_hdmi_set_edid(&intel_connector->base, live_status))
> +		DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
> +	else
> +		DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
> +}
>  
> -	if (intel_hdmi_set_edid(connector, live_status)) {
> +static enum drm_connector_status
> +intel_hdmi_detect(struct drm_connector *connector, bool force)
> +{
> +	enum drm_connector_status status;
> +	struct intel_connector *intel_connector =
> +				to_intel_connector(connector);
> +
> +	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> +		      connector->base.id, connector->name);
> +
> +	/*
> +	 * There are many userspace calls which probe EDID from
> +	 * detect path. In case of multiple hotplug/unplug, these
> +	 * can cause race conditions while probing EDID. Also its
> +	 * waste of CPU cycles to read the EDID again and again
> +	 * unless there is a real hotplug.
> +	 * So, rely on hotplugs and init to read edid.
> +	 * Check connector status based on availability of cached EDID.
> +	 */
> +
> +	if (intel_connector->detect_edid) {
>  		struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
>  
>  		hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
>  		status = connector_status_connected;
> -	} else
> +		DRM_DEBUG_DRIVER("hdmi status = connected\n");
> +	} else {
>  		status = connector_status_disconnected;
> +		DRM_DEBUG_DRIVER("hdmi status = disconnected\n");
> +	}
>  
>  	return status;
>  }
> @@ -2131,6 +2162,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
>  	intel_connector->unregister = intel_connector_unregister;
>  
>  	intel_hdmi_add_properties(intel_hdmi, connector);
> +	intel_encoder->hot_plug = intel_hdmi_hot_plug;
>  
>  	intel_connector_attach_encoder(intel_connector, intel_encoder);
>  	drm_connector_register(connector);
> -- 
> 1.7.10.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
  2015-10-05 11:13                     ` [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases Sonika Jindal
  2015-10-05 11:13                       ` [PATCH 2/2] drm/i915: Add hot_plug hook for hdmi encoder Sonika Jindal
@ 2015-10-08 13:35                       ` Ville Syrjälä
  2015-10-08 14:38                         ` Jani Nikula
  2015-10-12 12:24                         ` Sharma, Shashank
  1 sibling, 2 replies; 77+ messages in thread
From: Ville Syrjälä @ 2015-10-08 13:35 UTC (permalink / raw)
  To: Sonika Jindal; +Cc: intel-gfx

On Mon, Oct 05, 2015 at 04:43:14PM +0530, Sonika Jindal wrote:
> For all the encoders, call the hot_plug if it is registered.
> This is required for connected boot and resume cases to generate
> fake hpd resulting in reading of edid.
> Removing the initial sdvo hot_plug call too so that it will be called
> just once from this loop.
> 
> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_hotplug.c |   11 +++++++++++
>  drivers/gpu/drm/i915/intel_sdvo.c    |    1 -
>  2 files changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
> index 53c0173..eac4757 100644
> --- a/drivers/gpu/drm/i915/intel_hotplug.c
> +++ b/drivers/gpu/drm/i915/intel_hotplug.c
> @@ -458,6 +458,7 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
>  {
>  	struct drm_device *dev = dev_priv->dev;
>  	struct drm_mode_config *mode_config = &dev->mode_config;
> +	struct intel_encoder *encoder;
>  	struct drm_connector *connector;
>  	int i;
>  
> @@ -482,6 +483,16 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
>  	if (dev_priv->display.hpd_irq_setup)
>  		dev_priv->display.hpd_irq_setup(dev);
>  	spin_unlock_irq(&dev_priv->irq_lock);
> +
> +	/*
> +	 * Connected boot / resume scenarios can't generate new hot plug.
> +	 * So, probe it manually.
> +	 */
> +	list_for_each_entry(encoder, &dev->mode_config.encoder_list,
> +			    base.head) {
> +		if (encoder->hot_plug)
> +			encoder->hot_plug(encoder);
> +	}


This breaks the world on CHV

[ 3187.575198] [drm:intel_hdmi_hot_plug] Live status not up!
[ 3187.585154] =============================================
[ 3187.595010] [ INFO: possible recursive locking detected ]
[ 3187.604685] 4.3.0-rc4-bsw+ #2488 Tainted: G     U  W      
[ 3187.614366] ---------------------------------------------
[ 3187.623892] Xorg/32212 is trying to acquire lock:
[ 3187.632635]  (&power_domains->lock){+.+...}, at: [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915]
[ 3187.647492] 
[ 3187.647492] but task is already holding lock:
[ 3187.661054]  (&power_domains->lock){+.+...}, at: [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915]
[ 3187.675960] 
[ 3187.675960] other info that might help us debug this:
[ 3187.690459]  Possible unsafe locking scenario:
[ 3187.690459] 
[ 3187.704224]        CPU0
[ 3187.710485]        ----
[ 3187.716711]   lock(&power_domains->lock);
[ 3187.724718]   lock(&power_domains->lock);
[ 3187.732663] 
[ 3187.732663]  *** DEADLOCK ***
[ 3187.732663] 
[ 3187.749460]  May be due to missing lock nesting notation
[ 3187.749460] 
[ 3187.763833] 5 locks held by Xorg/32212:
[ 3187.771523]  #0:  (drm_global_mutex){+.+.+.}, at: [<ffffffffa02ad5c8>] drm_release+0x3b/0x49b [drm]
[ 3187.785216]  #1:  (&dev->mode_config.mutex){+.+.+.}, at: [<ffffffffa02c4d85>] drm_modeset_lock_all+0x54/0xcd [drm]
[ 3187.800437]  #2:  (crtc_ww_class_acquire){+.+.+.}, at: [<ffffffffa02c4d8f>] drm_modeset_lock_all+0x5e/0xcd [drm]
[ 3187.815488]  #3:  (crtc_ww_class_mutex){+.+.+.}, at: [<ffffffffa02c46b0>] drm_modeset_lock+0x75/0xfc [drm]
[ 3187.830094]  #4:  (&power_domains->lock){+.+...}, at: [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915]
[ 3187.845534] 
[ 3187.845534] stack backtrace:
[ 3187.857685] CPU: 2 PID: 32212 Comm: Xorg Tainted: G     U  W       4.3.0-rc4-bsw+ #2488
[ 3187.870331] Hardware name: Intel Corporation CHERRYVIEW C0 PLATFORM/Braswell CRB, BIOS BRAS.X64.B085.R00.1509110553 09/11/2015
[ 3187.886827]  0000000000000000 ffff880175eff8e0 ffffffff8128d59e ffffffff823f5ee0
[ 3187.898904]  ffff880175eff958 ffffffff810a7a08 0000000000000000 ffff880179d1c5d0
[ 3187.910954]  0000000000000004 0000000000000006 45422a91588a4c3e 0000000000000005
[ 3187.923011] Call Trace:
[ 3187.929451]  [<ffffffff8128d59e>] dump_stack+0x4e/0x79
[ 3187.938912]  [<ffffffff810a7a08>] __lock_acquire+0x7ab/0x12af
[ 3187.949027]  [<ffffffff810a8d04>] lock_acquire+0x10e/0x1a9
[ 3187.958859]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915]
[ 3187.970476]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915]
[ 3187.982011]  [<ffffffff814df4a3>] mutex_lock_nested+0x71/0x346
[ 3187.992167]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915]
[ 3188.003655]  [<ffffffff814e20ee>] ? _raw_spin_unlock_irqrestore+0x4b/0x60
[ 3188.014829]  [<ffffffff81364565>] ? __pm_runtime_resume+0x71/0x7e
[ 3188.025269]  [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915]
[ 3188.036544]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915]
[ 3188.047968]  [<ffffffffa03e8cc4>] intel_hdmi_set_edid+0x3f/0xd6 [i915]
[ 3188.058766]  [<ffffffffa03e8e1a>] intel_hdmi_hot_plug+0xbf/0xfb [i915]
[ 3188.069484]  [<ffffffffa03c9e78>] intel_hpd_init+0xfa/0x10b [i915]
[ 3188.079753]  [<ffffffffa036968d>] vlv_display_power_well_init+0xdb/0xe8 [i915]
[ 3188.091224]  [<ffffffffa0369763>] chv_pipe_power_well_enable+0x62/0x67 [i915]
[ 3188.102594]  [<ffffffffa036ad55>] intel_display_power_get+0xa0/0xcb [i915]
[ 3188.113657]  [<ffffffffa03bdd7a>] modeset_get_crtc_power_domains+0x11d/0x13c [i915]
[ 3188.125589]  [<ffffffffa03bdfc1>] intel_atomic_commit+0x228/0xf1b [i915]
[ 3188.136522]  [<ffffffffa02c586c>] ? drm_atomic_check_only+0x37b/0x4da [drm]
[ 3188.147676]  [<ffffffffa02c5a18>] drm_atomic_commit+0x4d/0x52 [drm]
[ 3188.158023]  [<ffffffffa032fa25>] restore_fbdev_mode+0x11e/0x286 [drm_kms_helper]
[ 3188.169734]  [<ffffffffa0331443>] drm_fb_helper_restore_fbdev_mode_unlocked+0x36/0x6d [drm_kms_helper]
[ 3188.183557]  [<ffffffffa03d270f>] intel_fbdev_restore_mode+0x22/0x7a [i915]
[ 3188.194701]  [<ffffffffa03f70b8>] i915_driver_lastclose+0xe/0x15 [i915]
[ 3188.205361]  [<ffffffffa02ad4c2>] drm_lastclose+0x3f/0x10a [drm]
[ 3188.215323]  [<ffffffffa02ad9ee>] drm_release+0x461/0x49b [drm]
[ 3188.225195]  [<ffffffff8118577c>] __fput+0x100/0x1b3
[ 3188.233956]  [<ffffffff81185865>] ____fput+0xe/0x10
[ 3188.242594]  [<ffffffff81084540>] task_work_run+0x6a/0x93
[ 3188.251816]  [<ffffffff810015d6>] prepare_exit_to_usermode+0x9e/0xaf
[ 3188.262111]  [<ffffffff810017d6>] syscall_return_slowpath+0x1ef/0x264
[ 3188.272486]  [<ffffffff81084462>] ? task_work_add+0x44/0x53
[ 3188.281885]  [<ffffffff811858e3>] ? fput+0x7c/0x83
[ 3188.290389]  [<ffffffff810a6e52>] ? trace_hardirqs_on_caller+0x16/0x196
[ 3188.300941]  [<ffffffff81000c87>] ? trace_hardirqs_on_thunk+0x17/0x19
[ 3188.311245]  [<ffffffff814e2ab1>] int_ret_from_sys_call+0x25/0x9f


>  }
>  
>  void intel_hpd_init_work(struct drm_i915_private *dev_priv)
> diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
> index 05521b5..55859e9 100644
> --- a/drivers/gpu/drm/i915/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> @@ -2433,7 +2433,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
>  		 * Ensure that they get re-enabled when an interrupt happens.
>  		 */
>  		intel_encoder->hot_plug = intel_sdvo_enable_hotplug;
> -		intel_sdvo_enable_hotplug(intel_encoder);
>  	} else {
>  		intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
>  	}
> -- 
> 1.7.10.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
  2015-10-08 13:35                       ` [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases Ville Syrjälä
@ 2015-10-08 14:38                         ` Jani Nikula
  2015-10-08 19:54                           ` Daniel Vetter
  2015-10-12 12:24                         ` Sharma, Shashank
  1 sibling, 1 reply; 77+ messages in thread
From: Jani Nikula @ 2015-10-08 14:38 UTC (permalink / raw)
  To: Ville Syrjälä, Sonika Jindal; +Cc: intel-gfx

On Thu, 08 Oct 2015, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> On Mon, Oct 05, 2015 at 04:43:14PM +0530, Sonika Jindal wrote:
>> For all the encoders, call the hot_plug if it is registered.
>> This is required for connected boot and resume cases to generate
>> fake hpd resulting in reading of edid.
>> Removing the initial sdvo hot_plug call too so that it will be called
>> just once from this loop.
>> 
>> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_hotplug.c |   11 +++++++++++
>>  drivers/gpu/drm/i915/intel_sdvo.c    |    1 -
>>  2 files changed, 11 insertions(+), 1 deletion(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
>> index 53c0173..eac4757 100644
>> --- a/drivers/gpu/drm/i915/intel_hotplug.c
>> +++ b/drivers/gpu/drm/i915/intel_hotplug.c
>> @@ -458,6 +458,7 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
>>  {
>>  	struct drm_device *dev = dev_priv->dev;
>>  	struct drm_mode_config *mode_config = &dev->mode_config;
>> +	struct intel_encoder *encoder;
>>  	struct drm_connector *connector;
>>  	int i;
>>  
>> @@ -482,6 +483,16 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
>>  	if (dev_priv->display.hpd_irq_setup)
>>  		dev_priv->display.hpd_irq_setup(dev);
>>  	spin_unlock_irq(&dev_priv->irq_lock);
>> +
>> +	/*
>> +	 * Connected boot / resume scenarios can't generate new hot plug.
>> +	 * So, probe it manually.
>> +	 */
>> +	list_for_each_entry(encoder, &dev->mode_config.encoder_list,
>> +			    base.head) {
>> +		if (encoder->hot_plug)
>> +			encoder->hot_plug(encoder);
>> +	}
>
>
> This breaks the world on CHV

Also patch 2/2 breaks: https://bugs.freedesktop.org/show_bug.cgi?id=88081

BR,
Jani.


>
> [ 3187.575198] [drm:intel_hdmi_hot_plug] Live status not up!
> [ 3187.585154] =============================================
> [ 3187.595010] [ INFO: possible recursive locking detected ]
> [ 3187.604685] 4.3.0-rc4-bsw+ #2488 Tainted: G     U  W      
> [ 3187.614366] ---------------------------------------------
> [ 3187.623892] Xorg/32212 is trying to acquire lock:
> [ 3187.632635]  (&power_domains->lock){+.+...}, at: [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915]
> [ 3187.647492] 
> [ 3187.647492] but task is already holding lock:
> [ 3187.661054]  (&power_domains->lock){+.+...}, at: [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915]
> [ 3187.675960] 
> [ 3187.675960] other info that might help us debug this:
> [ 3187.690459]  Possible unsafe locking scenario:
> [ 3187.690459] 
> [ 3187.704224]        CPU0
> [ 3187.710485]        ----
> [ 3187.716711]   lock(&power_domains->lock);
> [ 3187.724718]   lock(&power_domains->lock);
> [ 3187.732663] 
> [ 3187.732663]  *** DEADLOCK ***
> [ 3187.732663] 
> [ 3187.749460]  May be due to missing lock nesting notation
> [ 3187.749460] 
> [ 3187.763833] 5 locks held by Xorg/32212:
> [ 3187.771523]  #0:  (drm_global_mutex){+.+.+.}, at: [<ffffffffa02ad5c8>] drm_release+0x3b/0x49b [drm]
> [ 3187.785216]  #1:  (&dev->mode_config.mutex){+.+.+.}, at: [<ffffffffa02c4d85>] drm_modeset_lock_all+0x54/0xcd [drm]
> [ 3187.800437]  #2:  (crtc_ww_class_acquire){+.+.+.}, at: [<ffffffffa02c4d8f>] drm_modeset_lock_all+0x5e/0xcd [drm]
> [ 3187.815488]  #3:  (crtc_ww_class_mutex){+.+.+.}, at: [<ffffffffa02c46b0>] drm_modeset_lock+0x75/0xfc [drm]
> [ 3187.830094]  #4:  (&power_domains->lock){+.+...}, at: [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915]
> [ 3187.845534] 
> [ 3187.845534] stack backtrace:
> [ 3187.857685] CPU: 2 PID: 32212 Comm: Xorg Tainted: G     U  W       4.3.0-rc4-bsw+ #2488
> [ 3187.870331] Hardware name: Intel Corporation CHERRYVIEW C0 PLATFORM/Braswell CRB, BIOS BRAS.X64.B085.R00.1509110553 09/11/2015
> [ 3187.886827]  0000000000000000 ffff880175eff8e0 ffffffff8128d59e ffffffff823f5ee0
> [ 3187.898904]  ffff880175eff958 ffffffff810a7a08 0000000000000000 ffff880179d1c5d0
> [ 3187.910954]  0000000000000004 0000000000000006 45422a91588a4c3e 0000000000000005
> [ 3187.923011] Call Trace:
> [ 3187.929451]  [<ffffffff8128d59e>] dump_stack+0x4e/0x79
> [ 3187.938912]  [<ffffffff810a7a08>] __lock_acquire+0x7ab/0x12af
> [ 3187.949027]  [<ffffffff810a8d04>] lock_acquire+0x10e/0x1a9
> [ 3187.958859]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915]
> [ 3187.970476]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915]
> [ 3187.982011]  [<ffffffff814df4a3>] mutex_lock_nested+0x71/0x346
> [ 3187.992167]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915]
> [ 3188.003655]  [<ffffffff814e20ee>] ? _raw_spin_unlock_irqrestore+0x4b/0x60
> [ 3188.014829]  [<ffffffff81364565>] ? __pm_runtime_resume+0x71/0x7e
> [ 3188.025269]  [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915]
> [ 3188.036544]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915]
> [ 3188.047968]  [<ffffffffa03e8cc4>] intel_hdmi_set_edid+0x3f/0xd6 [i915]
> [ 3188.058766]  [<ffffffffa03e8e1a>] intel_hdmi_hot_plug+0xbf/0xfb [i915]
> [ 3188.069484]  [<ffffffffa03c9e78>] intel_hpd_init+0xfa/0x10b [i915]
> [ 3188.079753]  [<ffffffffa036968d>] vlv_display_power_well_init+0xdb/0xe8 [i915]
> [ 3188.091224]  [<ffffffffa0369763>] chv_pipe_power_well_enable+0x62/0x67 [i915]
> [ 3188.102594]  [<ffffffffa036ad55>] intel_display_power_get+0xa0/0xcb [i915]
> [ 3188.113657]  [<ffffffffa03bdd7a>] modeset_get_crtc_power_domains+0x11d/0x13c [i915]
> [ 3188.125589]  [<ffffffffa03bdfc1>] intel_atomic_commit+0x228/0xf1b [i915]
> [ 3188.136522]  [<ffffffffa02c586c>] ? drm_atomic_check_only+0x37b/0x4da [drm]
> [ 3188.147676]  [<ffffffffa02c5a18>] drm_atomic_commit+0x4d/0x52 [drm]
> [ 3188.158023]  [<ffffffffa032fa25>] restore_fbdev_mode+0x11e/0x286 [drm_kms_helper]
> [ 3188.169734]  [<ffffffffa0331443>] drm_fb_helper_restore_fbdev_mode_unlocked+0x36/0x6d [drm_kms_helper]
> [ 3188.183557]  [<ffffffffa03d270f>] intel_fbdev_restore_mode+0x22/0x7a [i915]
> [ 3188.194701]  [<ffffffffa03f70b8>] i915_driver_lastclose+0xe/0x15 [i915]
> [ 3188.205361]  [<ffffffffa02ad4c2>] drm_lastclose+0x3f/0x10a [drm]
> [ 3188.215323]  [<ffffffffa02ad9ee>] drm_release+0x461/0x49b [drm]
> [ 3188.225195]  [<ffffffff8118577c>] __fput+0x100/0x1b3
> [ 3188.233956]  [<ffffffff81185865>] ____fput+0xe/0x10
> [ 3188.242594]  [<ffffffff81084540>] task_work_run+0x6a/0x93
> [ 3188.251816]  [<ffffffff810015d6>] prepare_exit_to_usermode+0x9e/0xaf
> [ 3188.262111]  [<ffffffff810017d6>] syscall_return_slowpath+0x1ef/0x264
> [ 3188.272486]  [<ffffffff81084462>] ? task_work_add+0x44/0x53
> [ 3188.281885]  [<ffffffff811858e3>] ? fput+0x7c/0x83
> [ 3188.290389]  [<ffffffff810a6e52>] ? trace_hardirqs_on_caller+0x16/0x196
> [ 3188.300941]  [<ffffffff81000c87>] ? trace_hardirqs_on_thunk+0x17/0x19
> [ 3188.311245]  [<ffffffff814e2ab1>] int_ret_from_sys_call+0x25/0x9f
>
>
>>  }
>>  
>>  void intel_hpd_init_work(struct drm_i915_private *dev_priv)
>> diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
>> index 05521b5..55859e9 100644
>> --- a/drivers/gpu/drm/i915/intel_sdvo.c
>> +++ b/drivers/gpu/drm/i915/intel_sdvo.c
>> @@ -2433,7 +2433,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
>>  		 * Ensure that they get re-enabled when an interrupt happens.
>>  		 */
>>  		intel_encoder->hot_plug = intel_sdvo_enable_hotplug;
>> -		intel_sdvo_enable_hotplug(intel_encoder);
>>  	} else {
>>  		intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
>>  	}
>> -- 
>> 1.7.10.4
>> 
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> -- 
> Ville Syrjälä
> Intel OTC
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
  2015-10-08 14:38                         ` Jani Nikula
@ 2015-10-08 19:54                           ` Daniel Vetter
  2015-10-09  4:31                             ` Jindal, Sonika
  2015-12-10  4:27                             ` Sonika Jindal
  0 siblings, 2 replies; 77+ messages in thread
From: Daniel Vetter @ 2015-10-08 19:54 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Thu, Oct 08, 2015 at 05:38:58PM +0300, Jani Nikula wrote:
> On Thu, 08 Oct 2015, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> > On Mon, Oct 05, 2015 at 04:43:14PM +0530, Sonika Jindal wrote:
> >> For all the encoders, call the hot_plug if it is registered.
> >> This is required for connected boot and resume cases to generate
> >> fake hpd resulting in reading of edid.
> >> Removing the initial sdvo hot_plug call too so that it will be called
> >> just once from this loop.
> >> 
> >> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/intel_hotplug.c |   11 +++++++++++
> >>  drivers/gpu/drm/i915/intel_sdvo.c    |    1 -
> >>  2 files changed, 11 insertions(+), 1 deletion(-)
> >> 
> >> diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
> >> index 53c0173..eac4757 100644
> >> --- a/drivers/gpu/drm/i915/intel_hotplug.c
> >> +++ b/drivers/gpu/drm/i915/intel_hotplug.c
> >> @@ -458,6 +458,7 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
> >>  {
> >>  	struct drm_device *dev = dev_priv->dev;
> >>  	struct drm_mode_config *mode_config = &dev->mode_config;
> >> +	struct intel_encoder *encoder;
> >>  	struct drm_connector *connector;
> >>  	int i;
> >>  
> >> @@ -482,6 +483,16 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
> >>  	if (dev_priv->display.hpd_irq_setup)
> >>  		dev_priv->display.hpd_irq_setup(dev);
> >>  	spin_unlock_irq(&dev_priv->irq_lock);
> >> +
> >> +	/*
> >> +	 * Connected boot / resume scenarios can't generate new hot plug.
> >> +	 * So, probe it manually.
> >> +	 */
> >> +	list_for_each_entry(encoder, &dev->mode_config.encoder_list,
> >> +			    base.head) {
> >> +		if (encoder->hot_plug)
> >> +			encoder->hot_plug(encoder);
> >> +	}
> >
> >
> > This breaks the world on CHV
> 
> Also patch 2/2 breaks: https://bugs.freedesktop.org/show_bug.cgi?id=88081

Both reverted, thanks for the reveport.
-Daniel

> 
> BR,
> Jani.
> 
> 
> >
> > [ 3187.575198] [drm:intel_hdmi_hot_plug] Live status not up!
> > [ 3187.585154] =============================================
> > [ 3187.595010] [ INFO: possible recursive locking detected ]
> > [ 3187.604685] 4.3.0-rc4-bsw+ #2488 Tainted: G     U  W      
> > [ 3187.614366] ---------------------------------------------
> > [ 3187.623892] Xorg/32212 is trying to acquire lock:
> > [ 3187.632635]  (&power_domains->lock){+.+...}, at: [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915]
> > [ 3187.647492] 
> > [ 3187.647492] but task is already holding lock:
> > [ 3187.661054]  (&power_domains->lock){+.+...}, at: [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915]
> > [ 3187.675960] 
> > [ 3187.675960] other info that might help us debug this:
> > [ 3187.690459]  Possible unsafe locking scenario:
> > [ 3187.690459] 
> > [ 3187.704224]        CPU0
> > [ 3187.710485]        ----
> > [ 3187.716711]   lock(&power_domains->lock);
> > [ 3187.724718]   lock(&power_domains->lock);
> > [ 3187.732663] 
> > [ 3187.732663]  *** DEADLOCK ***
> > [ 3187.732663] 
> > [ 3187.749460]  May be due to missing lock nesting notation
> > [ 3187.749460] 
> > [ 3187.763833] 5 locks held by Xorg/32212:
> > [ 3187.771523]  #0:  (drm_global_mutex){+.+.+.}, at: [<ffffffffa02ad5c8>] drm_release+0x3b/0x49b [drm]
> > [ 3187.785216]  #1:  (&dev->mode_config.mutex){+.+.+.}, at: [<ffffffffa02c4d85>] drm_modeset_lock_all+0x54/0xcd [drm]
> > [ 3187.800437]  #2:  (crtc_ww_class_acquire){+.+.+.}, at: [<ffffffffa02c4d8f>] drm_modeset_lock_all+0x5e/0xcd [drm]
> > [ 3187.815488]  #3:  (crtc_ww_class_mutex){+.+.+.}, at: [<ffffffffa02c46b0>] drm_modeset_lock+0x75/0xfc [drm]
> > [ 3187.830094]  #4:  (&power_domains->lock){+.+...}, at: [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915]
> > [ 3187.845534] 
> > [ 3187.845534] stack backtrace:
> > [ 3187.857685] CPU: 2 PID: 32212 Comm: Xorg Tainted: G     U  W       4.3.0-rc4-bsw+ #2488
> > [ 3187.870331] Hardware name: Intel Corporation CHERRYVIEW C0 PLATFORM/Braswell CRB, BIOS BRAS.X64.B085.R00.1509110553 09/11/2015
> > [ 3187.886827]  0000000000000000 ffff880175eff8e0 ffffffff8128d59e ffffffff823f5ee0
> > [ 3187.898904]  ffff880175eff958 ffffffff810a7a08 0000000000000000 ffff880179d1c5d0
> > [ 3187.910954]  0000000000000004 0000000000000006 45422a91588a4c3e 0000000000000005
> > [ 3187.923011] Call Trace:
> > [ 3187.929451]  [<ffffffff8128d59e>] dump_stack+0x4e/0x79
> > [ 3187.938912]  [<ffffffff810a7a08>] __lock_acquire+0x7ab/0x12af
> > [ 3187.949027]  [<ffffffff810a8d04>] lock_acquire+0x10e/0x1a9
> > [ 3187.958859]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915]
> > [ 3187.970476]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915]
> > [ 3187.982011]  [<ffffffff814df4a3>] mutex_lock_nested+0x71/0x346
> > [ 3187.992167]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915]
> > [ 3188.003655]  [<ffffffff814e20ee>] ? _raw_spin_unlock_irqrestore+0x4b/0x60
> > [ 3188.014829]  [<ffffffff81364565>] ? __pm_runtime_resume+0x71/0x7e
> > [ 3188.025269]  [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915]
> > [ 3188.036544]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915]
> > [ 3188.047968]  [<ffffffffa03e8cc4>] intel_hdmi_set_edid+0x3f/0xd6 [i915]
> > [ 3188.058766]  [<ffffffffa03e8e1a>] intel_hdmi_hot_plug+0xbf/0xfb [i915]
> > [ 3188.069484]  [<ffffffffa03c9e78>] intel_hpd_init+0xfa/0x10b [i915]
> > [ 3188.079753]  [<ffffffffa036968d>] vlv_display_power_well_init+0xdb/0xe8 [i915]
> > [ 3188.091224]  [<ffffffffa0369763>] chv_pipe_power_well_enable+0x62/0x67 [i915]
> > [ 3188.102594]  [<ffffffffa036ad55>] intel_display_power_get+0xa0/0xcb [i915]
> > [ 3188.113657]  [<ffffffffa03bdd7a>] modeset_get_crtc_power_domains+0x11d/0x13c [i915]
> > [ 3188.125589]  [<ffffffffa03bdfc1>] intel_atomic_commit+0x228/0xf1b [i915]
> > [ 3188.136522]  [<ffffffffa02c586c>] ? drm_atomic_check_only+0x37b/0x4da [drm]
> > [ 3188.147676]  [<ffffffffa02c5a18>] drm_atomic_commit+0x4d/0x52 [drm]
> > [ 3188.158023]  [<ffffffffa032fa25>] restore_fbdev_mode+0x11e/0x286 [drm_kms_helper]
> > [ 3188.169734]  [<ffffffffa0331443>] drm_fb_helper_restore_fbdev_mode_unlocked+0x36/0x6d [drm_kms_helper]
> > [ 3188.183557]  [<ffffffffa03d270f>] intel_fbdev_restore_mode+0x22/0x7a [i915]
> > [ 3188.194701]  [<ffffffffa03f70b8>] i915_driver_lastclose+0xe/0x15 [i915]
> > [ 3188.205361]  [<ffffffffa02ad4c2>] drm_lastclose+0x3f/0x10a [drm]
> > [ 3188.215323]  [<ffffffffa02ad9ee>] drm_release+0x461/0x49b [drm]
> > [ 3188.225195]  [<ffffffff8118577c>] __fput+0x100/0x1b3
> > [ 3188.233956]  [<ffffffff81185865>] ____fput+0xe/0x10
> > [ 3188.242594]  [<ffffffff81084540>] task_work_run+0x6a/0x93
> > [ 3188.251816]  [<ffffffff810015d6>] prepare_exit_to_usermode+0x9e/0xaf
> > [ 3188.262111]  [<ffffffff810017d6>] syscall_return_slowpath+0x1ef/0x264
> > [ 3188.272486]  [<ffffffff81084462>] ? task_work_add+0x44/0x53
> > [ 3188.281885]  [<ffffffff811858e3>] ? fput+0x7c/0x83
> > [ 3188.290389]  [<ffffffff810a6e52>] ? trace_hardirqs_on_caller+0x16/0x196
> > [ 3188.300941]  [<ffffffff81000c87>] ? trace_hardirqs_on_thunk+0x17/0x19
> > [ 3188.311245]  [<ffffffff814e2ab1>] int_ret_from_sys_call+0x25/0x9f
> >
> >
> >>  }
> >>  
> >>  void intel_hpd_init_work(struct drm_i915_private *dev_priv)
> >> diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
> >> index 05521b5..55859e9 100644
> >> --- a/drivers/gpu/drm/i915/intel_sdvo.c
> >> +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> >> @@ -2433,7 +2433,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
> >>  		 * Ensure that they get re-enabled when an interrupt happens.
> >>  		 */
> >>  		intel_encoder->hot_plug = intel_sdvo_enable_hotplug;
> >> -		intel_sdvo_enable_hotplug(intel_encoder);
> >>  	} else {
> >>  		intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
> >>  	}
> >> -- 
> >> 1.7.10.4
> >> 
> >> _______________________________________________
> >> Intel-gfx mailing list
> >> Intel-gfx@lists.freedesktop.org
> >> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> >
> > -- 
> > Ville Syrjälä
> > Intel OTC
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Jani Nikula, Intel Open Source Technology Center
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
  2015-10-08 19:54                           ` Daniel Vetter
@ 2015-10-09  4:31                             ` Jindal, Sonika
  2015-12-10  4:27                             ` Sonika Jindal
  1 sibling, 0 replies; 77+ messages in thread
From: Jindal, Sonika @ 2015-10-09  4:31 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula; +Cc: intel-gfx



On 10/9/2015 1:24 AM, Daniel Vetter wrote:
> On Thu, Oct 08, 2015 at 05:38:58PM +0300, Jani Nikula wrote:
>> On Thu, 08 Oct 2015, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
>>> On Mon, Oct 05, 2015 at 04:43:14PM +0530, Sonika Jindal wrote:
>>>> For all the encoders, call the hot_plug if it is registered.
>>>> This is required for connected boot and resume cases to generate
>>>> fake hpd resulting in reading of edid.
>>>> Removing the initial sdvo hot_plug call too so that it will be called
>>>> just once from this loop.
>>>>
>>>> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
>>>> ---
>>>>   drivers/gpu/drm/i915/intel_hotplug.c |   11 +++++++++++
>>>>   drivers/gpu/drm/i915/intel_sdvo.c    |    1 -
>>>>   2 files changed, 11 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
>>>> index 53c0173..eac4757 100644
>>>> --- a/drivers/gpu/drm/i915/intel_hotplug.c
>>>> +++ b/drivers/gpu/drm/i915/intel_hotplug.c
>>>> @@ -458,6 +458,7 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
>>>>   {
>>>>   	struct drm_device *dev = dev_priv->dev;
>>>>   	struct drm_mode_config *mode_config = &dev->mode_config;
>>>> +	struct intel_encoder *encoder;
>>>>   	struct drm_connector *connector;
>>>>   	int i;
>>>>
>>>> @@ -482,6 +483,16 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
>>>>   	if (dev_priv->display.hpd_irq_setup)
>>>>   		dev_priv->display.hpd_irq_setup(dev);
>>>>   	spin_unlock_irq(&dev_priv->irq_lock);
>>>> +
>>>> +	/*
>>>> +	 * Connected boot / resume scenarios can't generate new hot plug.
>>>> +	 * So, probe it manually.
>>>> +	 */
>>>> +	list_for_each_entry(encoder, &dev->mode_config.encoder_list,
>>>> +			    base.head) {
>>>> +		if (encoder->hot_plug)
>>>> +			encoder->hot_plug(encoder);
>>>> +	}
>>>
>>>
>>> This breaks the world on CHV
>>
>> Also patch 2/2 breaks: https://bugs.freedesktop.org/show_bug.cgi?id=88081
>
Hmm, will check why live status is not up for chv..

Regards,
Sonika
> Both reverted, thanks for the reveport.
> -Daniel
>
>>
>> BR,
>> Jani.
>>
>>
>>>
>>> [ 3187.575198] [drm:intel_hdmi_hot_plug] Live status not up!
>>> [ 3187.585154] =============================================
>>> [ 3187.595010] [ INFO: possible recursive locking detected ]
>>> [ 3187.604685] 4.3.0-rc4-bsw+ #2488 Tainted: G     U  W
>>> [ 3187.614366] ---------------------------------------------
>>> [ 3187.623892] Xorg/32212 is trying to acquire lock:
>>> [ 3187.632635]  (&power_domains->lock){+.+...}, at: [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915]
>>> [ 3187.647492]
>>> [ 3187.647492] but task is already holding lock:
>>> [ 3187.661054]  (&power_domains->lock){+.+...}, at: [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915]
>>> [ 3187.675960]
>>> [ 3187.675960] other info that might help us debug this:
>>> [ 3187.690459]  Possible unsafe locking scenario:
>>> [ 3187.690459]
>>> [ 3187.704224]        CPU0
>>> [ 3187.710485]        ----
>>> [ 3187.716711]   lock(&power_domains->lock);
>>> [ 3187.724718]   lock(&power_domains->lock);
>>> [ 3187.732663]
>>> [ 3187.732663]  *** DEADLOCK ***
>>> [ 3187.732663]
>>> [ 3187.749460]  May be due to missing lock nesting notation
>>> [ 3187.749460]
>>> [ 3187.763833] 5 locks held by Xorg/32212:
>>> [ 3187.771523]  #0:  (drm_global_mutex){+.+.+.}, at: [<ffffffffa02ad5c8>] drm_release+0x3b/0x49b [drm]
>>> [ 3187.785216]  #1:  (&dev->mode_config.mutex){+.+.+.}, at: [<ffffffffa02c4d85>] drm_modeset_lock_all+0x54/0xcd [drm]
>>> [ 3187.800437]  #2:  (crtc_ww_class_acquire){+.+.+.}, at: [<ffffffffa02c4d8f>] drm_modeset_lock_all+0x5e/0xcd [drm]
>>> [ 3187.815488]  #3:  (crtc_ww_class_mutex){+.+.+.}, at: [<ffffffffa02c46b0>] drm_modeset_lock+0x75/0xfc [drm]
>>> [ 3187.830094]  #4:  (&power_domains->lock){+.+...}, at: [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915]
>>> [ 3187.845534]
>>> [ 3187.845534] stack backtrace:
>>> [ 3187.857685] CPU: 2 PID: 32212 Comm: Xorg Tainted: G     U  W       4.3.0-rc4-bsw+ #2488
>>> [ 3187.870331] Hardware name: Intel Corporation CHERRYVIEW C0 PLATFORM/Braswell CRB, BIOS BRAS.X64.B085.R00.1509110553 09/11/2015
>>> [ 3187.886827]  0000000000000000 ffff880175eff8e0 ffffffff8128d59e ffffffff823f5ee0
>>> [ 3187.898904]  ffff880175eff958 ffffffff810a7a08 0000000000000000 ffff880179d1c5d0
>>> [ 3187.910954]  0000000000000004 0000000000000006 45422a91588a4c3e 0000000000000005
>>> [ 3187.923011] Call Trace:
>>> [ 3187.929451]  [<ffffffff8128d59e>] dump_stack+0x4e/0x79
>>> [ 3187.938912]  [<ffffffff810a7a08>] __lock_acquire+0x7ab/0x12af
>>> [ 3187.949027]  [<ffffffff810a8d04>] lock_acquire+0x10e/0x1a9
>>> [ 3187.958859]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915]
>>> [ 3187.970476]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915]
>>> [ 3187.982011]  [<ffffffff814df4a3>] mutex_lock_nested+0x71/0x346
>>> [ 3187.992167]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915]
>>> [ 3188.003655]  [<ffffffff814e20ee>] ? _raw_spin_unlock_irqrestore+0x4b/0x60
>>> [ 3188.014829]  [<ffffffff81364565>] ? __pm_runtime_resume+0x71/0x7e
>>> [ 3188.025269]  [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915]
>>> [ 3188.036544]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915]
>>> [ 3188.047968]  [<ffffffffa03e8cc4>] intel_hdmi_set_edid+0x3f/0xd6 [i915]
>>> [ 3188.058766]  [<ffffffffa03e8e1a>] intel_hdmi_hot_plug+0xbf/0xfb [i915]
>>> [ 3188.069484]  [<ffffffffa03c9e78>] intel_hpd_init+0xfa/0x10b [i915]
>>> [ 3188.079753]  [<ffffffffa036968d>] vlv_display_power_well_init+0xdb/0xe8 [i915]
>>> [ 3188.091224]  [<ffffffffa0369763>] chv_pipe_power_well_enable+0x62/0x67 [i915]
>>> [ 3188.102594]  [<ffffffffa036ad55>] intel_display_power_get+0xa0/0xcb [i915]
>>> [ 3188.113657]  [<ffffffffa03bdd7a>] modeset_get_crtc_power_domains+0x11d/0x13c [i915]
>>> [ 3188.125589]  [<ffffffffa03bdfc1>] intel_atomic_commit+0x228/0xf1b [i915]
>>> [ 3188.136522]  [<ffffffffa02c586c>] ? drm_atomic_check_only+0x37b/0x4da [drm]
>>> [ 3188.147676]  [<ffffffffa02c5a18>] drm_atomic_commit+0x4d/0x52 [drm]
>>> [ 3188.158023]  [<ffffffffa032fa25>] restore_fbdev_mode+0x11e/0x286 [drm_kms_helper]
>>> [ 3188.169734]  [<ffffffffa0331443>] drm_fb_helper_restore_fbdev_mode_unlocked+0x36/0x6d [drm_kms_helper]
>>> [ 3188.183557]  [<ffffffffa03d270f>] intel_fbdev_restore_mode+0x22/0x7a [i915]
>>> [ 3188.194701]  [<ffffffffa03f70b8>] i915_driver_lastclose+0xe/0x15 [i915]
>>> [ 3188.205361]  [<ffffffffa02ad4c2>] drm_lastclose+0x3f/0x10a [drm]
>>> [ 3188.215323]  [<ffffffffa02ad9ee>] drm_release+0x461/0x49b [drm]
>>> [ 3188.225195]  [<ffffffff8118577c>] __fput+0x100/0x1b3
>>> [ 3188.233956]  [<ffffffff81185865>] ____fput+0xe/0x10
>>> [ 3188.242594]  [<ffffffff81084540>] task_work_run+0x6a/0x93
>>> [ 3188.251816]  [<ffffffff810015d6>] prepare_exit_to_usermode+0x9e/0xaf
>>> [ 3188.262111]  [<ffffffff810017d6>] syscall_return_slowpath+0x1ef/0x264
>>> [ 3188.272486]  [<ffffffff81084462>] ? task_work_add+0x44/0x53
>>> [ 3188.281885]  [<ffffffff811858e3>] ? fput+0x7c/0x83
>>> [ 3188.290389]  [<ffffffff810a6e52>] ? trace_hardirqs_on_caller+0x16/0x196
>>> [ 3188.300941]  [<ffffffff81000c87>] ? trace_hardirqs_on_thunk+0x17/0x19
>>> [ 3188.311245]  [<ffffffff814e2ab1>] int_ret_from_sys_call+0x25/0x9f
>>>
>>>
>>>>   }
>>>>
>>>>   void intel_hpd_init_work(struct drm_i915_private *dev_priv)
>>>> diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
>>>> index 05521b5..55859e9 100644
>>>> --- a/drivers/gpu/drm/i915/intel_sdvo.c
>>>> +++ b/drivers/gpu/drm/i915/intel_sdvo.c
>>>> @@ -2433,7 +2433,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
>>>>   		 * Ensure that they get re-enabled when an interrupt happens.
>>>>   		 */
>>>>   		intel_encoder->hot_plug = intel_sdvo_enable_hotplug;
>>>> -		intel_sdvo_enable_hotplug(intel_encoder);
>>>>   	} else {
>>>>   		intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
>>>>   	}
>>>> --
>>>> 1.7.10.4
>>>>
>>>> _______________________________________________
>>>> Intel-gfx mailing list
>>>> Intel-gfx@lists.freedesktop.org
>>>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>>>
>>> --
>>> Ville Syrjälä
>>> Intel OTC
>>> _______________________________________________
>>> Intel-gfx mailing list
>>> Intel-gfx@lists.freedesktop.org
>>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>>
>> --
>> Jani Nikula, Intel Open Source Technology Center
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
  2015-10-08 13:35                       ` [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases Ville Syrjälä
  2015-10-08 14:38                         ` Jani Nikula
@ 2015-10-12 12:24                         ` Sharma, Shashank
  2015-10-15  1:32                           ` Jindal, Sonika
  1 sibling, 1 reply; 77+ messages in thread
From: Sharma, Shashank @ 2015-10-12 12:24 UTC (permalink / raw)
  To: Ville Syrjälä, Vetter, Daniel; +Cc: intel-gfx

We were debugging this issue, and we could find the root cause:
In function:
Intel_hpd_init()
	|
encoder->hotplug()
	|
display_power_get()
	|
Intel_powe_well_enable()
	|
power_well->ops->enable()
	|
chv_pipe_power_well_enable()
	|
vlv_display_power_well_init()
	|
intel_hdp_init()

This function ends up calling intel_hpd_init, Which is causing the mutex deadlock due to recursion, as we are calling encoder->hotplug() from hpd_init().

Intel_hpd_init()
	|
encoder->hotplug()
	|
display_power_get()

There are two solutions here:
- remove hpd_init() from get_calls 
- remove encoder->hotplug() function call from hpd_init() and put it in some other place. We have added this function from encoder_init() for android trees, and it works well there. 

Regards
Shashank
-----Original Message-----
From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of Ville Syrjälä
Sent: Thursday, October 08, 2015 7:06 PM
To: Jindal, Sonika
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases

On Mon, Oct 05, 2015 at 04:43:14PM +0530, Sonika Jindal wrote:
> For all the encoders, call the hot_plug if it is registered.
> This is required for connected boot and resume cases to generate fake 
> hpd resulting in reading of edid.
> Removing the initial sdvo hot_plug call too so that it will be called 
> just once from this loop.
> 
> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_hotplug.c |   11 +++++++++++
>  drivers/gpu/drm/i915/intel_sdvo.c    |    1 -
>  2 files changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_hotplug.c 
> b/drivers/gpu/drm/i915/intel_hotplug.c
> index 53c0173..eac4757 100644
> --- a/drivers/gpu/drm/i915/intel_hotplug.c
> +++ b/drivers/gpu/drm/i915/intel_hotplug.c
> @@ -458,6 +458,7 @@ void intel_hpd_init(struct drm_i915_private 
> *dev_priv)  {
>  	struct drm_device *dev = dev_priv->dev;
>  	struct drm_mode_config *mode_config = &dev->mode_config;
> +	struct intel_encoder *encoder;
>  	struct drm_connector *connector;
>  	int i;
>  
> @@ -482,6 +483,16 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
>  	if (dev_priv->display.hpd_irq_setup)
>  		dev_priv->display.hpd_irq_setup(dev);
>  	spin_unlock_irq(&dev_priv->irq_lock);
> +
> +	/*
> +	 * Connected boot / resume scenarios can't generate new hot plug.
> +	 * So, probe it manually.
> +	 */
> +	list_for_each_entry(encoder, &dev->mode_config.encoder_list,
> +			    base.head) {
> +		if (encoder->hot_plug)
> +			encoder->hot_plug(encoder);
> +	}


This breaks the world on CHV

[ 3187.575198] [drm:intel_hdmi_hot_plug] Live status not up!
[ 3187.585154] =============================================
[ 3187.595010] [ INFO: possible recursive locking detected ]
[ 3187.604685] 4.3.0-rc4-bsw+ #2488 Tainted: G     U  W      
[ 3187.614366] ---------------------------------------------
[ 3187.623892] Xorg/32212 is trying to acquire lock:
[ 3187.632635]  (&power_domains->lock){+.+...}, at: [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915] [ 3187.647492] [ 3187.647492] but task is already holding lock:
[ 3187.661054]  (&power_domains->lock){+.+...}, at: [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915] [ 3187.675960] [ 3187.675960] other info that might help us debug this:
[ 3187.690459]  Possible unsafe locking scenario:
[ 3187.690459] 
[ 3187.704224]        CPU0
[ 3187.710485]        ----
[ 3187.716711]   lock(&power_domains->lock);
[ 3187.724718]   lock(&power_domains->lock);
[ 3187.732663]
[ 3187.732663]  *** DEADLOCK ***
[ 3187.732663]
[ 3187.749460]  May be due to missing lock nesting notation [ 3187.749460] [ 3187.763833] 5 locks held by Xorg/32212:
[ 3187.771523]  #0:  (drm_global_mutex){+.+.+.}, at: [<ffffffffa02ad5c8>] drm_release+0x3b/0x49b [drm] [ 3187.785216]  #1:  (&dev->mode_config.mutex){+.+.+.}, at: [<ffffffffa02c4d85>] drm_modeset_lock_all+0x54/0xcd [drm] [ 3187.800437]  #2:  (crtc_ww_class_acquire){+.+.+.}, at: [<ffffffffa02c4d8f>] drm_modeset_lock_all+0x5e/0xcd [drm] [ 3187.815488]  #3:  (crtc_ww_class_mutex){+.+.+.}, at: [<ffffffffa02c46b0>] drm_modeset_lock+0x75/0xfc [drm] [ 3187.830094]  #4:  (&power_domains->lock){+.+...}, at: [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915] [ 3187.845534] [ 3187.845534] stack backtrace:
[ 3187.857685] CPU: 2 PID: 32212 Comm: Xorg Tainted: G     U  W       4.3.0-rc4-bsw+ #2488
[ 3187.870331] Hardware name: Intel Corporation CHERRYVIEW C0 PLATFORM/Braswell CRB, BIOS BRAS.X64.B085.R00.1509110553 09/11/2015 [ 3187.886827]  0000000000000000 ffff880175eff8e0 ffffffff8128d59e ffffffff823f5ee0 [ 3187.898904]  ffff880175eff958 ffffffff810a7a08 0000000000000000 ffff880179d1c5d0 [ 3187.910954]  0000000000000004 0000000000000006 45422a91588a4c3e 0000000000000005 [ 3187.923011] Call Trace:
[ 3187.929451]  [<ffffffff8128d59e>] dump_stack+0x4e/0x79 [ 3187.938912]  [<ffffffff810a7a08>] __lock_acquire+0x7ab/0x12af [ 3187.949027]  [<ffffffff810a8d04>] lock_acquire+0x10e/0x1a9 [ 3187.958859]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915] [ 3187.970476]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915] [ 3187.982011]  [<ffffffff814df4a3>] mutex_lock_nested+0x71/0x346 [ 3187.992167]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915] [ 3188.003655]  [<ffffffff814e20ee>] ? _raw_spin_unlock_irqrestore+0x4b/0x60
[ 3188.014829]  [<ffffffff81364565>] ? __pm_runtime_resume+0x71/0x7e [ 3188.025269]  [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915] [ 3188.036544]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915] [ 3188.047968]  [<ffffffffa03e8cc4>] intel_hdmi_set_edid+0x3f/0xd6 [i915] [ 3188.058766]  [<ffffffffa03e8e1a>] intel_hdmi_hot_plug+0xbf/0xfb [i915] [ 3188.069484]  [<ffffffffa03c9e78>] intel_hpd_init+0xfa/0x10b [i915] [ 3188.079753]  [<ffffffffa036968d>] vlv_display_power_well_init+0xdb/0xe8 [i915] [ 3188.091224]  [<ffffffffa0369763>] chv_pipe_power_well_enable+0x62/0x67 [i915] [ 3188.102594]  [<ffffffffa036ad55>] intel_display_power_get+0xa0/0xcb [i915] [ 3188.113657]  [<ffffffffa03bdd7a>] modeset_get_crtc_power_domains+0x11d/0x13c [i915] [ 3188.125589]  [<ffffffffa03bdfc1>] intel_atomic_commit+0x228/0xf1b [i915] [ 3188.136522]  [<ffffffffa02c586c>] ? drm_atomic_check_only+0x37b/0x4da [drm] [ 3188.147676]  [<ffffffffa02c5a18>] drm_atomic_commit+0x4d/0x52 [drm] [ 3188.158023]  [<ffffffffa032fa25>] restore_fbdev_mode+0x11e/0x286 [drm_kms_helper] [ 3188.169734]  [<ffffffffa0331443>] drm_fb_helper_restore_fbdev_mode_unlocked+0x36/0x6d [drm_kms_helper] [ 3188.183557]  [<ffffffffa03d270f>] intel_fbdev_restore_mode+0x22/0x7a [i915] [ 3188.194701]  [<ffffffffa03f70b8>] i915_driver_lastclose+0xe/0x15 [i915] [ 3188.205361]  [<ffffffffa02ad4c2>] drm_lastclose+0x3f/0x10a [drm] [ 3188.215323]  [<ffffffffa02ad9ee>] drm_release+0x461/0x49b [drm] [ 3188.225195]  [<ffffffff8118577c>] __fput+0x100/0x1b3 [ 3188.233956]  [<ffffffff81185865>] ____fput+0xe/0x10 [ 3188.242594]  [<ffffffff81084540>] task_work_run+0x6a/0x93 [ 3188.251816]  [<ffffffff810015d6>] prepare_exit_to_usermode+0x9e/0xaf
[ 3188.262111]  [<ffffffff810017d6>] syscall_return_slowpath+0x1ef/0x264
[ 3188.272486]  [<ffffffff81084462>] ? task_work_add+0x44/0x53 [ 3188.281885]  [<ffffffff811858e3>] ? fput+0x7c/0x83 [ 3188.290389]  [<ffffffff810a6e52>] ? trace_hardirqs_on_caller+0x16/0x196
[ 3188.300941]  [<ffffffff81000c87>] ? trace_hardirqs_on_thunk+0x17/0x19 [ 3188.311245]  [<ffffffff814e2ab1>] int_ret_from_sys_call+0x25/0x9f


>  }
>  
>  void intel_hpd_init_work(struct drm_i915_private *dev_priv) diff 
> --git a/drivers/gpu/drm/i915/intel_sdvo.c 
> b/drivers/gpu/drm/i915/intel_sdvo.c
> index 05521b5..55859e9 100644
> --- a/drivers/gpu/drm/i915/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> @@ -2433,7 +2433,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
>  		 * Ensure that they get re-enabled when an interrupt happens.
>  		 */
>  		intel_encoder->hot_plug = intel_sdvo_enable_hotplug;
> -		intel_sdvo_enable_hotplug(intel_encoder);
>  	} else {
>  		intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
>  	}
> --
> 1.7.10.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

--
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
  2015-10-12 12:24                         ` Sharma, Shashank
@ 2015-10-15  1:32                           ` Jindal, Sonika
  0 siblings, 0 replies; 77+ messages in thread
From: Jindal, Sonika @ 2015-10-15  1:32 UTC (permalink / raw)
  To: Sharma, Shashank, Ville Syrjälä, Vetter, Daniel; +Cc: intel-gfx

Had some discussion with Daniel on IRC about how we can fix the deadlock.
We couldn't decide upon any solution but I can give it a try.
He suggested to have a work function for ->hot_plug which will get the power domain lock and not allow ->hot_plug if the power_domain is shut.
Then when it calls hpt_init again from power_domain get, ->hot_plug gets called.
But this looks racy, we can try this out.
If there are any other suggestions, please let me know.
I will work on this after 26th Oct.

Regards,
Sonika

-----Original Message-----
From: Sharma, Shashank 
Sent: Monday, October 12, 2015 5:54 PM
To: Ville Syrjälä; Vetter, Daniel
Cc: intel-gfx@lists.freedesktop.org; Mukherjee, Indranil; Jindal, Sonika
Subject: RE: [Intel-gfx] [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases

We were debugging this issue, and we could find the root cause:
In function:
Intel_hpd_init()
	|
encoder->hotplug()
	|
display_power_get()
	|
Intel_powe_well_enable()
	|
power_well->ops->enable()
	|
chv_pipe_power_well_enable()
	|
vlv_display_power_well_init()
	|
intel_hdp_init()

This function ends up calling intel_hpd_init, Which is causing the mutex deadlock due to recursion, as we are calling encoder->hotplug() from hpd_init().

Intel_hpd_init()
	|
encoder->hotplug()
	|
display_power_get()

There are two solutions here:
- remove hpd_init() from get_calls
- remove encoder->hotplug() function call from hpd_init() and put it in some other place. We have added this function from encoder_init() for android trees, and it works well there. 

Regards
Shashank
-----Original Message-----
From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of Ville Syrjälä
Sent: Thursday, October 08, 2015 7:06 PM
To: Jindal, Sonika
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases

On Mon, Oct 05, 2015 at 04:43:14PM +0530, Sonika Jindal wrote:
> For all the encoders, call the hot_plug if it is registered.
> This is required for connected boot and resume cases to generate fake 
> hpd resulting in reading of edid.
> Removing the initial sdvo hot_plug call too so that it will be called 
> just once from this loop.
> 
> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_hotplug.c |   11 +++++++++++
>  drivers/gpu/drm/i915/intel_sdvo.c    |    1 -
>  2 files changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_hotplug.c
> b/drivers/gpu/drm/i915/intel_hotplug.c
> index 53c0173..eac4757 100644
> --- a/drivers/gpu/drm/i915/intel_hotplug.c
> +++ b/drivers/gpu/drm/i915/intel_hotplug.c
> @@ -458,6 +458,7 @@ void intel_hpd_init(struct drm_i915_private
> *dev_priv)  {
>  	struct drm_device *dev = dev_priv->dev;
>  	struct drm_mode_config *mode_config = &dev->mode_config;
> +	struct intel_encoder *encoder;
>  	struct drm_connector *connector;
>  	int i;
>  
> @@ -482,6 +483,16 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
>  	if (dev_priv->display.hpd_irq_setup)
>  		dev_priv->display.hpd_irq_setup(dev);
>  	spin_unlock_irq(&dev_priv->irq_lock);
> +
> +	/*
> +	 * Connected boot / resume scenarios can't generate new hot plug.
> +	 * So, probe it manually.
> +	 */
> +	list_for_each_entry(encoder, &dev->mode_config.encoder_list,
> +			    base.head) {
> +		if (encoder->hot_plug)
> +			encoder->hot_plug(encoder);
> +	}


This breaks the world on CHV

[ 3187.575198] [drm:intel_hdmi_hot_plug] Live status not up!
[ 3187.585154] =============================================
[ 3187.595010] [ INFO: possible recursive locking detected ]
[ 3187.604685] 4.3.0-rc4-bsw+ #2488 Tainted: G     U  W      
[ 3187.614366] ---------------------------------------------
[ 3187.623892] Xorg/32212 is trying to acquire lock:
[ 3187.632635]  (&power_domains->lock){+.+...}, at: [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915] [ 3187.647492] [ 3187.647492] but task is already holding lock:
[ 3187.661054]  (&power_domains->lock){+.+...}, at: [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915] [ 3187.675960] [ 3187.675960] other info that might help us debug this:
[ 3187.690459]  Possible unsafe locking scenario:
[ 3187.690459] 
[ 3187.704224]        CPU0
[ 3187.710485]        ----
[ 3187.716711]   lock(&power_domains->lock);
[ 3187.724718]   lock(&power_domains->lock);
[ 3187.732663]
[ 3187.732663]  *** DEADLOCK ***
[ 3187.732663]
[ 3187.749460]  May be due to missing lock nesting notation [ 3187.749460] [ 3187.763833] 5 locks held by Xorg/32212:
[ 3187.771523]  #0:  (drm_global_mutex){+.+.+.}, at: [<ffffffffa02ad5c8>] drm_release+0x3b/0x49b [drm] [ 3187.785216]  #1:  (&dev->mode_config.mutex){+.+.+.}, at: [<ffffffffa02c4d85>] drm_modeset_lock_all+0x54/0xcd [drm] [ 3187.800437]  #2:  (crtc_ww_class_acquire){+.+.+.}, at: [<ffffffffa02c4d8f>] drm_modeset_lock_all+0x5e/0xcd [drm] [ 3187.815488]  #3:  (crtc_ww_class_mutex){+.+.+.}, at: [<ffffffffa02c46b0>] drm_modeset_lock+0x75/0xfc [drm] [ 3187.830094]  #4:  (&power_domains->lock){+.+...}, at: [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915] [ 3187.845534] [ 3187.845534] stack backtrace:
[ 3187.857685] CPU: 2 PID: 32212 Comm: Xorg Tainted: G     U  W       4.3.0-rc4-bsw+ #2488
[ 3187.870331] Hardware name: Intel Corporation CHERRYVIEW C0 PLATFORM/Braswell CRB, BIOS BRAS.X64.B085.R00.1509110553 09/11/2015 [ 3187.886827]  0000000000000000 ffff880175eff8e0 ffffffff8128d59e ffffffff823f5ee0 [ 3187.898904]  ffff880175eff958 ffffffff810a7a08 0000000000000000 ffff880179d1c5d0 [ 3187.910954]  0000000000000004 0000000000000006 45422a91588a4c3e 0000000000000005 [ 3187.923011] Call Trace:
[ 3187.929451]  [<ffffffff8128d59e>] dump_stack+0x4e/0x79 [ 3187.938912]  [<ffffffff810a7a08>] __lock_acquire+0x7ab/0x12af [ 3187.949027]  [<ffffffff810a8d04>] lock_acquire+0x10e/0x1a9 [ 3187.958859]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915] [ 3187.970476]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915] [ 3187.982011]  [<ffffffff814df4a3>] mutex_lock_nested+0x71/0x346 [ 3187.992167]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915] [ 3188.003655]  [<ffffffff814e20ee>] ? _raw_spin_unlock_irqrestore+0x4b/0x60
[ 3188.014829]  [<ffffffff81364565>] ? __pm_runtime_resume+0x71/0x7e [ 3188.025269]  [<ffffffffa036aced>] intel_display_power_get+0x38/0xcb [i915] [ 3188.036544]  [<ffffffffa036aced>] ? intel_display_power_get+0x38/0xcb [i915] [ 3188.047968]  [<ffffffffa03e8cc4>] intel_hdmi_set_edid+0x3f/0xd6 [i915] [ 3188.058766]  [<ffffffffa03e8e1a>] intel_hdmi_hot_plug+0xbf/0xfb [i915] [ 3188.069484]  [<ffffffffa03c9e78>] intel_hpd_init+0xfa/0x10b [i915] [ 3188.079753]  [<ffffffffa036968d>] vlv_display_power_well_init+0xdb/0xe8 [i915] [ 3188.091224]  [<ffffffffa0369763>] chv_pipe_power_well_enable+0x62/0x67 [i915] [ 3188.102594]  [<ffffffffa036ad55>] intel_display_power_get+0xa0/0xcb [i915] [ 3188.113657]  [<ffffffffa03bdd7a>] modeset_get_crtc_power_domains+0x11d/0x13c [i915] [ 3188.125589]  [<ffffffffa03bdfc1>] intel_atomic_commit+0x228/0xf1b [i915] [ 3188.136522]  [<ffffffffa02c586c>] ? drm_atomic_check_only+0x37b/0x4da [drm] [ 3188.147676]  [<ffffffffa02c5a18>] drm_atomic_commit+0x4d/0x52 [drm] [ 3188.158023]  [<ffffffffa032fa25>] restore_fbdev_mode+0x11e/0x286 [drm_kms_helper] [ 3188.169734]  [<ffffffffa0331443>] drm_fb_helper_restore_fbdev_mode_unlocked+0x36/0x6d [drm_kms_helper] [ 3188.183557]  [<ffffffffa03d270f>] intel_fbdev_restore_mode+0x22/0x7a [i915] [ 3188.194701]  [<ffffffffa03f70b8>] i915_driver_lastclose+0xe/0x15 [i915] [ 3188.205361]  [<ffffffffa02ad4c2>] drm_lastclose+0x3f/0x10a [drm] [ 3188.215323]  [<ffffffffa02ad9ee>] drm_release+0x461/0x49b [drm] [ 3188.225195]  [<ffffffff8118577c>] __fput+0x100/0x1b3 [ 3188.233956]  [<ffffffff81185865>] ____fput+0xe/0x10 [ 3188.242594]  [<ffffffff81084540>] task_work_run+0x6a/0x93 [ 3188.251816]  [<ffffffff810015d6>] prepare_exit_to_usermode+0x9e/0xaf
[ 3188.262111]  [<ffffffff810017d6>] syscall_return_slowpath+0x1ef/0x264
[ 3188.272486]  [<ffffffff81084462>] ? task_work_add+0x44/0x53 [ 3188.281885]  [<ffffffff811858e3>] ? fput+0x7c/0x83 [ 3188.290389]  [<ffffffff810a6e52>] ? trace_hardirqs_on_caller+0x16/0x196
[ 3188.300941]  [<ffffffff81000c87>] ? trace_hardirqs_on_thunk+0x17/0x19 [ 3188.311245]  [<ffffffff814e2ab1>] int_ret_from_sys_call+0x25/0x9f


>  }
>  
>  void intel_hpd_init_work(struct drm_i915_private *dev_priv) diff 
> --git a/drivers/gpu/drm/i915/intel_sdvo.c
> b/drivers/gpu/drm/i915/intel_sdvo.c
> index 05521b5..55859e9 100644
> --- a/drivers/gpu/drm/i915/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> @@ -2433,7 +2433,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
>  		 * Ensure that they get re-enabled when an interrupt happens.
>  		 */
>  		intel_encoder->hot_plug = intel_sdvo_enable_hotplug;
> -		intel_sdvo_enable_hotplug(intel_encoder);
>  	} else {
>  		intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
>  	}
> --
> 1.7.10.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

--
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
  2015-10-08 19:54                           ` Daniel Vetter
  2015-10-09  4:31                             ` Jindal, Sonika
@ 2015-12-10  4:27                             ` Sonika Jindal
  1 sibling, 0 replies; 77+ messages in thread
From: Sonika Jindal @ 2015-12-10  4:27 UTC (permalink / raw)
  To: intel-gfx

Call the encoders, call the hot_plug if it is registered.
This is required for connected boot and resume cases to generate
fake hpd resulting in reading of edid.
Removing the initial sdvo hot_plug call too so that it will be called
just once from this loop.

v2: Schedule a work function to call hot_plug

Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |  1 +
 drivers/gpu/drm/i915/intel_hotplug.c | 26 ++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_sdvo.c    |  1 -
 3 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index bc865e23..4f037b9 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -228,6 +228,7 @@ enum hpd_pin {
 
 struct i915_hotplug {
 	struct work_struct hotplug_work;
+	struct work_struct edid_work;
 
 	struct {
 		unsigned long last_jiffies;
diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
index b177857..72d8fe8 100644
--- a/drivers/gpu/drm/i915/intel_hotplug.c
+++ b/drivers/gpu/drm/i915/intel_hotplug.c
@@ -442,6 +442,24 @@ void intel_hpd_irq_handler(struct drm_device *dev,
 		schedule_work(&dev_priv->hotplug.hotplug_work);
 }
 
+static void i915_edid_work_func(struct work_struct *work)
+{
+	struct drm_i915_private *dev_priv =
+		container_of(work, struct drm_i915_private, hotplug.edid_work);
+	struct drm_device *dev = dev_priv->dev;
+	struct drm_mode_config *mode_config = &dev->mode_config;
+	struct intel_encoder *encoder;
+
+	mutex_lock(&mode_config->mutex);
+	list_for_each_entry(encoder, &mode_config->encoder_list,
+			base.head) {
+		if (encoder->hot_plug)
+			encoder->hot_plug(encoder);
+	}
+	mutex_unlock(&mode_config->mutex);
+	drm_helper_hpd_irq_event(dev);
+}
+
 /**
  * intel_hpd_init - initializes and enables hpd support
  * @dev_priv: i915 device instance
@@ -482,12 +500,19 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
 	if (dev_priv->display.hpd_irq_setup)
 		dev_priv->display.hpd_irq_setup(dev);
 	spin_unlock_irq(&dev_priv->irq_lock);
+
+	/*
+	 * Connected boot / resume scenarios can't generate new hot plug.
+	 * So, probe it manually.
+	 */
+	schedule_work(&dev_priv->hotplug.edid_work);
 }
 
 void intel_hpd_init_work(struct drm_i915_private *dev_priv)
 {
 	INIT_WORK(&dev_priv->hotplug.hotplug_work, i915_hotplug_work_func);
 	INIT_WORK(&dev_priv->hotplug.dig_port_work, i915_digport_work_func);
+	INIT_WORK(&dev_priv->hotplug.edid_work, i915_edid_work_func);
 	INIT_DELAYED_WORK(&dev_priv->hotplug.reenable_work,
 			  intel_hpd_irq_storm_reenable_work);
 }
@@ -504,5 +529,6 @@ void intel_hpd_cancel_work(struct drm_i915_private *dev_priv)
 
 	cancel_work_sync(&dev_priv->hotplug.dig_port_work);
 	cancel_work_sync(&dev_priv->hotplug.hotplug_work);
+	cancel_work_sync(&dev_priv->hotplug.edid_work);
 	cancel_delayed_work_sync(&dev_priv->hotplug.reenable_work);
 }
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 06679f1..4238a02 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -2466,7 +2466,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
 		 * Ensure that they get re-enabled when an interrupt happens.
 		 */
 		intel_encoder->hot_plug = intel_sdvo_enable_hotplug;
-		intel_sdvo_enable_hotplug(intel_encoder);
 	} else {
 		intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
 	}
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 2/2] drm/i915: Add hot_plug hook for hdmi encoder
  2015-10-06  8:28                         ` Daniel Vetter
@ 2015-12-10  4:30                           ` Sonika Jindal
  2015-12-10  4:45                             ` [PATCH] " Sonika Jindal
  0 siblings, 1 reply; 77+ messages in thread
From: Sonika Jindal @ 2015-12-10  4:30 UTC (permalink / raw)
  To: intel-gfx

This patch adds a separate probe function for HDMI
EDID read over DDC channel. This function has been
registered as a .hot_plug handler for HDMI encoder.

The current implementation of hdmi_detect()
function re-sets the cached HDMI edid (in connector->detect_edid) in
every detect call.This function gets called many times, sometimes
directly from userspace probes, forcing drivers to read EDID every
detect function call.This causes several problems like:

1. Race conditions in multiple hot_plug / unplug cases, between
   interrupts bottom halves and userspace detections.
2. Many Un-necessary EDID reads for single hotplug/unplug
3. HDMI complaince failures which expects only one EDID read per hotplug

This function will be serving the purpose of really reading the EDID
by really probing the DDC channel, and updating the cached EDID.

The plan is to:
1. i915 IRQ handler bottom half function already calls
   intel_encoder->hotplug() function. Adding This probe function which
   will read the EDID only in case of a hotplug / unplug.
2. During init_connector this probe will be called to read the edid
3. Reuse the cached EDID in hdmi_detect() function.

The "< gen7" check is there because this was tested only for >=gen7
platforms. For older platforms the hotplug/reading edid path remains same.

v2: Calling set_edid instead of hdmi_probe during init.
Also, for platforms having DDI, intel_encoder for DP and HDMI is same
(taken from intel_dig_port), so for DP also, hot_plug function gets called
which is not intended here. So, check for HDMI in intel_hdmi_probe
Rely on HPD for updating edid only for platforms gen > 8 and also for VLV.

v3: Dropping the gen < 8 || !VLV  check. Now all platforms should rely on
hotplug or init for updating the edid.(Daniel)
Also, calling hdmi_probe in init instead of set_edid

v4: Renaming intel_hdmi_probe to intel_hdmi_hot_plug.
Also calling this hotplug handler from intel_hpd_init to take care of init
resume scenarios.

v5: Moved the call to encoder hotplug during init to separate patch(Daniel)
v6: Rebased.

Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/i915/intel_hdmi.c | 58 ++++++++++++++++++++++++++++++---------
 1 file changed, 45 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index bdd462e..16dd2a7 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1381,18 +1381,16 @@ intel_hdmi_set_edid(struct drm_connector *connector, bool force)
 	return connected;
 }
 
-static enum drm_connector_status
-intel_hdmi_detect(struct drm_connector *connector, bool force)
+void intel_hdmi_hot_plug(struct intel_encoder *intel_encoder)
 {
-	enum drm_connector_status status;
-	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->dev);
+	struct intel_hdmi *intel_hdmi =
+			enc_to_intel_hdmi(&intel_encoder->base);
+	struct intel_connector *intel_connector =
+				intel_hdmi->attached_connector;
+	struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
 	bool live_status = false;
 	unsigned int retry = 3;
 
-	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
-		      connector->base.id, connector->name);
-
 	intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
 
 	while (!live_status && --retry) {
@@ -1400,21 +1398,53 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
 				hdmi_to_dig_port(intel_hdmi));
 		mdelay(10);
 	}
+	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
 
 	if (!live_status)
 		DRM_DEBUG_KMS("Live status not up!");
 
-	intel_hdmi_unset_edid(connector);
+	/*
+	 * We are here, means there is a hotplug or a force
+	 * detection. Clear the cached EDID and probe the
+	 * DDC bus to check the current status of HDMI.
+	 */
+	intel_hdmi_unset_edid(&intel_connector->base);
+	if (intel_hdmi_set_edid(&intel_connector->base, live_status))
+		DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
+	else
+		DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
+}
+
+static enum drm_connector_status
+intel_hdmi_detect(struct drm_connector *connector, bool force)
+{
+	enum drm_connector_status status;
+	struct intel_connector *intel_connector =
+				to_intel_connector(connector);
 
-	if (intel_hdmi_set_edid(connector, live_status)) {
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+		      connector->base.id, connector->name);
+
+	/*
+	 * There are many userspace calls which probe EDID from
+	 * detect path. In case of multiple hotplug/unplug, these
+	 * can cause race conditions while probing EDID. Also its
+	 * waste of CPU cycles to read the EDID again and again
+	 * unless there is a real hotplug.
+	 * So, rely on hotplugs and init to read edid.
+	 * Check connector status based on availability of cached EDID.
+	 */
+
+	if (intel_connector->detect_edid) {
 		struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 
 		hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
 		status = connector_status_connected;
-	} else
+		DRM_DEBUG_DRIVER("hdmi status = connected\n");
+	} else {
 		status = connector_status_disconnected;
-
-	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
+		DRM_DEBUG_DRIVER("hdmi status = disconnected\n");
+	}
 
 	return status;
 }
@@ -2131,6 +2161,8 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 
 	intel_hdmi_add_properties(intel_hdmi, connector);
 
+	intel_encoder->hot_plug = intel_hdmi_hot_plug;
+
 	intel_connector_attach_encoder(intel_connector, intel_encoder);
 	drm_connector_register(connector);
 	intel_hdmi->attached_connector = intel_connector;
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH] drm/i915: Add hot_plug hook for hdmi encoder
  2015-12-10  4:30                           ` Sonika Jindal
@ 2015-12-10  4:45                             ` Sonika Jindal
  2015-12-10  8:29                               ` Daniel Vetter
  0 siblings, 1 reply; 77+ messages in thread
From: Sonika Jindal @ 2015-12-10  4:45 UTC (permalink / raw)
  To: intel-gfx

From: Shashank Sharma <shashank.sharma@intel.com>

This patch adds a separate probe function for HDMI
EDID read over DDC channel. This function has been
registered as a .hot_plug handler for HDMI encoder.

The current implementation of hdmi_detect()
function re-sets the cached HDMI edid (in connector->detect_edid) in
every detect call.This function gets called many times, sometimes
directly from userspace probes, forcing drivers to read EDID every
detect function call.This causes several problems like:

1. Race conditions in multiple hot_plug / unplug cases, between
   interrupts bottom halves and userspace detections.
2. Many Un-necessary EDID reads for single hotplug/unplug
3. HDMI complaince failures which expects only one EDID read per hotplug

This function will be serving the purpose of really reading the EDID
by really probing the DDC channel, and updating the cached EDID.

The plan is to:
1. i915 IRQ handler bottom half function already calls
   intel_encoder->hotplug() function. Adding This probe function which
   will read the EDID only in case of a hotplug / unplug.
2. During init_connector this probe will be called to read the edid
3. Reuse the cached EDID in hdmi_detect() function.

The "< gen7" check is there because this was tested only for >=gen7
platforms. For older platforms the hotplug/reading edid path remains same.

v2: Calling set_edid instead of hdmi_probe during init.
Also, for platforms having DDI, intel_encoder for DP and HDMI is same
(taken from intel_dig_port), so for DP also, hot_plug function gets called
which is not intended here. So, check for HDMI in intel_hdmi_probe
Rely on HPD for updating edid only for platforms gen > 8 and also for VLV.

v3: Dropping the gen < 8 || !VLV  check. Now all platforms should rely on
hotplug or init for updating the edid.(Daniel)
Also, calling hdmi_probe in init instead of set_edid

v4: Renaming intel_hdmi_probe to intel_hdmi_hot_plug.
Also calling this hotplug handler from intel_hpd_init to take care of init
resume scenarios.

v5: Moved the call to encoder hotplug during init to separate patch(Daniel)
v6: Rebased and maintaining authorship.

Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/i915/intel_hdmi.c | 58 ++++++++++++++++++++++++++++++---------
 1 file changed, 45 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index bdd462e..16dd2a7 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1381,18 +1381,16 @@ intel_hdmi_set_edid(struct drm_connector *connector, bool force)
 	return connected;
 }
 
-static enum drm_connector_status
-intel_hdmi_detect(struct drm_connector *connector, bool force)
+void intel_hdmi_hot_plug(struct intel_encoder *intel_encoder)
 {
-	enum drm_connector_status status;
-	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
-	struct drm_i915_private *dev_priv = to_i915(connector->dev);
+	struct intel_hdmi *intel_hdmi =
+			enc_to_intel_hdmi(&intel_encoder->base);
+	struct intel_connector *intel_connector =
+				intel_hdmi->attached_connector;
+	struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
 	bool live_status = false;
 	unsigned int retry = 3;
 
-	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
-		      connector->base.id, connector->name);
-
 	intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
 
 	while (!live_status && --retry) {
@@ -1400,21 +1398,53 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
 				hdmi_to_dig_port(intel_hdmi));
 		mdelay(10);
 	}
+	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
 
 	if (!live_status)
 		DRM_DEBUG_KMS("Live status not up!");
 
-	intel_hdmi_unset_edid(connector);
+	/*
+	 * We are here, means there is a hotplug or a force
+	 * detection. Clear the cached EDID and probe the
+	 * DDC bus to check the current status of HDMI.
+	 */
+	intel_hdmi_unset_edid(&intel_connector->base);
+	if (intel_hdmi_set_edid(&intel_connector->base, live_status))
+		DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
+	else
+		DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
+}
+
+static enum drm_connector_status
+intel_hdmi_detect(struct drm_connector *connector, bool force)
+{
+	enum drm_connector_status status;
+	struct intel_connector *intel_connector =
+				to_intel_connector(connector);
 
-	if (intel_hdmi_set_edid(connector, live_status)) {
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+		      connector->base.id, connector->name);
+
+	/*
+	 * There are many userspace calls which probe EDID from
+	 * detect path. In case of multiple hotplug/unplug, these
+	 * can cause race conditions while probing EDID. Also its
+	 * waste of CPU cycles to read the EDID again and again
+	 * unless there is a real hotplug.
+	 * So, rely on hotplugs and init to read edid.
+	 * Check connector status based on availability of cached EDID.
+	 */
+
+	if (intel_connector->detect_edid) {
 		struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 
 		hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
 		status = connector_status_connected;
-	} else
+		DRM_DEBUG_DRIVER("hdmi status = connected\n");
+	} else {
 		status = connector_status_disconnected;
-
-	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
+		DRM_DEBUG_DRIVER("hdmi status = disconnected\n");
+	}
 
 	return status;
 }
@@ -2131,6 +2161,8 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 
 	intel_hdmi_add_properties(intel_hdmi, connector);
 
+	intel_encoder->hot_plug = intel_hdmi_hot_plug;
+
 	intel_connector_attach_encoder(intel_connector, intel_encoder);
 	drm_connector_register(connector);
 	intel_hdmi->attached_connector = intel_connector;
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915: Add hot_plug hook for hdmi encoder
  2015-12-10  4:45                             ` [PATCH] " Sonika Jindal
@ 2015-12-10  8:29                               ` Daniel Vetter
  2015-12-10  8:35                                 ` Jindal, Sonika
  0 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2015-12-10  8:29 UTC (permalink / raw)
  To: Sonika Jindal; +Cc: intel-gfx

On Thu, Dec 10, 2015 at 10:15:41AM +0530, Sonika Jindal wrote:
> From: Shashank Sharma <shashank.sharma@intel.com>
> 
> This patch adds a separate probe function for HDMI
> EDID read over DDC channel. This function has been
> registered as a .hot_plug handler for HDMI encoder.
> 
> The current implementation of hdmi_detect()
> function re-sets the cached HDMI edid (in connector->detect_edid) in
> every detect call.This function gets called many times, sometimes
> directly from userspace probes, forcing drivers to read EDID every
> detect function call.This causes several problems like:
> 
> 1. Race conditions in multiple hot_plug / unplug cases, between
>    interrupts bottom halves and userspace detections.
> 2. Many Un-necessary EDID reads for single hotplug/unplug
> 3. HDMI complaince failures which expects only one EDID read per hotplug
> 
> This function will be serving the purpose of really reading the EDID
> by really probing the DDC channel, and updating the cached EDID.
> 
> The plan is to:
> 1. i915 IRQ handler bottom half function already calls
>    intel_encoder->hotplug() function. Adding This probe function which
>    will read the EDID only in case of a hotplug / unplug.
> 2. During init_connector this probe will be called to read the edid
> 3. Reuse the cached EDID in hdmi_detect() function.
> 
> The "< gen7" check is there because this was tested only for >=gen7
> platforms. For older platforms the hotplug/reading edid path remains same.
> 
> v2: Calling set_edid instead of hdmi_probe during init.
> Also, for platforms having DDI, intel_encoder for DP and HDMI is same
> (taken from intel_dig_port), so for DP also, hot_plug function gets called
> which is not intended here. So, check for HDMI in intel_hdmi_probe
> Rely on HPD for updating edid only for platforms gen > 8 and also for VLV.
> 
> v3: Dropping the gen < 8 || !VLV  check. Now all platforms should rely on
> hotplug or init for updating the edid.(Daniel)
> Also, calling hdmi_probe in init instead of set_edid
> 
> v4: Renaming intel_hdmi_probe to intel_hdmi_hot_plug.
> Also calling this hotplug handler from intel_hpd_init to take care of init
> resume scenarios.
> 
> v5: Moved the call to encoder hotplug during init to separate patch(Daniel)
> v6: Rebased and maintaining authorship.
> 
> Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>

Iirc we had to revert an earlier version of this. Commit message should
cite that revert and explain why this version is better.

Also after a few days please start a new thread when resubmitting a patch
series. The idea behind in-reply-to is to keep the discussion together
while it's still ongoing. That's not the case when the discussion has died
down since weeks.

Also, your patch to take hpd sense into account for hdmi detection has
causes a regression. Your on the cc. Handling that regression needs to be
absolute top priority (otherwise I need to revert that patch too).

Thanks, Daniel

> ---
>  drivers/gpu/drm/i915/intel_hdmi.c | 58 ++++++++++++++++++++++++++++++---------
>  1 file changed, 45 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index bdd462e..16dd2a7 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -1381,18 +1381,16 @@ intel_hdmi_set_edid(struct drm_connector *connector, bool force)
>  	return connected;
>  }
>  
> -static enum drm_connector_status
> -intel_hdmi_detect(struct drm_connector *connector, bool force)
> +void intel_hdmi_hot_plug(struct intel_encoder *intel_encoder)
>  {
> -	enum drm_connector_status status;
> -	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->dev);
> +	struct intel_hdmi *intel_hdmi =
> +			enc_to_intel_hdmi(&intel_encoder->base);
> +	struct intel_connector *intel_connector =
> +				intel_hdmi->attached_connector;
> +	struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
>  	bool live_status = false;
>  	unsigned int retry = 3;
>  
> -	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> -		      connector->base.id, connector->name);
> -
>  	intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
>  
>  	while (!live_status && --retry) {
> @@ -1400,21 +1398,53 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
>  				hdmi_to_dig_port(intel_hdmi));
>  		mdelay(10);
>  	}
> +	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
>  
>  	if (!live_status)
>  		DRM_DEBUG_KMS("Live status not up!");
>  
> -	intel_hdmi_unset_edid(connector);
> +	/*
> +	 * We are here, means there is a hotplug or a force
> +	 * detection. Clear the cached EDID and probe the
> +	 * DDC bus to check the current status of HDMI.
> +	 */
> +	intel_hdmi_unset_edid(&intel_connector->base);
> +	if (intel_hdmi_set_edid(&intel_connector->base, live_status))
> +		DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
> +	else
> +		DRM_DEBUG_DRIVER("DDC probe: no EDID\n");
> +}
> +
> +static enum drm_connector_status
> +intel_hdmi_detect(struct drm_connector *connector, bool force)
> +{
> +	enum drm_connector_status status;
> +	struct intel_connector *intel_connector =
> +				to_intel_connector(connector);
>  
> -	if (intel_hdmi_set_edid(connector, live_status)) {
> +	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> +		      connector->base.id, connector->name);
> +
> +	/*
> +	 * There are many userspace calls which probe EDID from
> +	 * detect path. In case of multiple hotplug/unplug, these
> +	 * can cause race conditions while probing EDID. Also its
> +	 * waste of CPU cycles to read the EDID again and again
> +	 * unless there is a real hotplug.
> +	 * So, rely on hotplugs and init to read edid.
> +	 * Check connector status based on availability of cached EDID.
> +	 */
> +
> +	if (intel_connector->detect_edid) {
>  		struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
>  
>  		hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
>  		status = connector_status_connected;
> -	} else
> +		DRM_DEBUG_DRIVER("hdmi status = connected\n");
> +	} else {
>  		status = connector_status_disconnected;
> -
> -	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
> +		DRM_DEBUG_DRIVER("hdmi status = disconnected\n");
> +	}
>  
>  	return status;
>  }
> @@ -2131,6 +2161,8 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
>  
>  	intel_hdmi_add_properties(intel_hdmi, connector);
>  
> +	intel_encoder->hot_plug = intel_hdmi_hot_plug;
> +
>  	intel_connector_attach_encoder(intel_connector, intel_encoder);
>  	drm_connector_register(connector);
>  	intel_hdmi->attached_connector = intel_connector;
> -- 
> 1.9.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915: Add hot_plug hook for hdmi encoder
  2015-12-10  8:29                               ` Daniel Vetter
@ 2015-12-10  8:35                                 ` Jindal, Sonika
  2015-12-10  8:53                                   ` Daniel Vetter
  0 siblings, 1 reply; 77+ messages in thread
From: Jindal, Sonika @ 2015-12-10  8:35 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

Sure, I will start a new thread for this.

Regarding the regression, since it is a sandybridge system, I am not sure if I can debug it anyhow because of the unavailability of the system.
For the live status check, we earlier suggested to use platforms gen8 and above.
But for wider testing, we removed the check.
If required we can add a check there.

Regards,
Sonika

-----Original Message-----
From: Daniel Vetter [mailto:daniel.vetter@ffwll.ch] On Behalf Of Daniel Vetter
Sent: Thursday, December 10, 2015 2:00 PM
To: Jindal, Sonika <sonika.jindal@intel.com>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH] drm/i915: Add hot_plug hook for hdmi encoder

On Thu, Dec 10, 2015 at 10:15:41AM +0530, Sonika Jindal wrote:
> From: Shashank Sharma <shashank.sharma@intel.com>
> 
> This patch adds a separate probe function for HDMI EDID read over DDC 
> channel. This function has been registered as a .hot_plug handler for 
> HDMI encoder.
> 
> The current implementation of hdmi_detect() function re-sets the 
> cached HDMI edid (in connector->detect_edid) in every detect call.This 
> function gets called many times, sometimes directly from userspace 
> probes, forcing drivers to read EDID every detect function call.This 
> causes several problems like:
> 
> 1. Race conditions in multiple hot_plug / unplug cases, between
>    interrupts bottom halves and userspace detections.
> 2. Many Un-necessary EDID reads for single hotplug/unplug 3. HDMI 
> complaince failures which expects only one EDID read per hotplug
> 
> This function will be serving the purpose of really reading the EDID 
> by really probing the DDC channel, and updating the cached EDID.
> 
> The plan is to:
> 1. i915 IRQ handler bottom half function already calls
>    intel_encoder->hotplug() function. Adding This probe function which
>    will read the EDID only in case of a hotplug / unplug.
> 2. During init_connector this probe will be called to read the edid 3. 
> Reuse the cached EDID in hdmi_detect() function.
> 
> The "< gen7" check is there because this was tested only for >=gen7 
> platforms. For older platforms the hotplug/reading edid path remains same.
> 
> v2: Calling set_edid instead of hdmi_probe during init.
> Also, for platforms having DDI, intel_encoder for DP and HDMI is same 
> (taken from intel_dig_port), so for DP also, hot_plug function gets 
> called which is not intended here. So, check for HDMI in 
> intel_hdmi_probe Rely on HPD for updating edid only for platforms gen > 8 and also for VLV.
> 
> v3: Dropping the gen < 8 || !VLV  check. Now all platforms should rely 
> on hotplug or init for updating the edid.(Daniel) Also, calling 
> hdmi_probe in init instead of set_edid
> 
> v4: Renaming intel_hdmi_probe to intel_hdmi_hot_plug.
> Also calling this hotplug handler from intel_hpd_init to take care of 
> init resume scenarios.
> 
> v5: Moved the call to encoder hotplug during init to separate 
> patch(Daniel)
> v6: Rebased and maintaining authorship.
> 
> Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>

Iirc we had to revert an earlier version of this. Commit message should cite that revert and explain why this version is better.

Also after a few days please start a new thread when resubmitting a patch series. The idea behind in-reply-to is to keep the discussion together while it's still ongoing. That's not the case when the discussion has died down since weeks.

Also, your patch to take hpd sense into account for hdmi detection has causes a regression. Your on the cc. Handling that regression needs to be absolute top priority (otherwise I need to revert that patch too).

Thanks, Daniel

> ---
>  drivers/gpu/drm/i915/intel_hdmi.c | 58 
> ++++++++++++++++++++++++++++++---------
>  1 file changed, 45 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
> b/drivers/gpu/drm/i915/intel_hdmi.c
> index bdd462e..16dd2a7 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -1381,18 +1381,16 @@ intel_hdmi_set_edid(struct drm_connector *connector, bool force)
>  	return connected;
>  }
>  
> -static enum drm_connector_status
> -intel_hdmi_detect(struct drm_connector *connector, bool force)
> +void intel_hdmi_hot_plug(struct intel_encoder *intel_encoder)
>  {
> -	enum drm_connector_status status;
> -	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
> -	struct drm_i915_private *dev_priv = to_i915(connector->dev);
> +	struct intel_hdmi *intel_hdmi =
> +			enc_to_intel_hdmi(&intel_encoder->base);
> +	struct intel_connector *intel_connector =
> +				intel_hdmi->attached_connector;
> +	struct drm_i915_private *dev_priv = 
> +to_i915(intel_encoder->base.dev);
>  	bool live_status = false;
>  	unsigned int retry = 3;
>  
> -	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> -		      connector->base.id, connector->name);
> -
>  	intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
>  
>  	while (!live_status && --retry) {
> @@ -1400,21 +1398,53 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
>  				hdmi_to_dig_port(intel_hdmi));
>  		mdelay(10);
>  	}
> +	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
>  
>  	if (!live_status)
>  		DRM_DEBUG_KMS("Live status not up!");
>  
> -	intel_hdmi_unset_edid(connector);
> +	/*
> +	 * We are here, means there is a hotplug or a force
> +	 * detection. Clear the cached EDID and probe the
> +	 * DDC bus to check the current status of HDMI.
> +	 */
> +	intel_hdmi_unset_edid(&intel_connector->base);
> +	if (intel_hdmi_set_edid(&intel_connector->base, live_status))
> +		DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
> +	else
> +		DRM_DEBUG_DRIVER("DDC probe: no EDID\n"); }
> +
> +static enum drm_connector_status
> +intel_hdmi_detect(struct drm_connector *connector, bool force) {
> +	enum drm_connector_status status;
> +	struct intel_connector *intel_connector =
> +				to_intel_connector(connector);
>  
> -	if (intel_hdmi_set_edid(connector, live_status)) {
> +	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> +		      connector->base.id, connector->name);
> +
> +	/*
> +	 * There are many userspace calls which probe EDID from
> +	 * detect path. In case of multiple hotplug/unplug, these
> +	 * can cause race conditions while probing EDID. Also its
> +	 * waste of CPU cycles to read the EDID again and again
> +	 * unless there is a real hotplug.
> +	 * So, rely on hotplugs and init to read edid.
> +	 * Check connector status based on availability of cached EDID.
> +	 */
> +
> +	if (intel_connector->detect_edid) {
>  		struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
>  
>  		hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
>  		status = connector_status_connected;
> -	} else
> +		DRM_DEBUG_DRIVER("hdmi status = connected\n");
> +	} else {
>  		status = connector_status_disconnected;
> -
> -	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
> +		DRM_DEBUG_DRIVER("hdmi status = disconnected\n");
> +	}
>  
>  	return status;
>  }
> @@ -2131,6 +2161,8 @@ void intel_hdmi_init_connector(struct 
> intel_digital_port *intel_dig_port,
>  
>  	intel_hdmi_add_properties(intel_hdmi, connector);
>  
> +	intel_encoder->hot_plug = intel_hdmi_hot_plug;
> +
>  	intel_connector_attach_encoder(intel_connector, intel_encoder);
>  	drm_connector_register(connector);
>  	intel_hdmi->attached_connector = intel_connector;
> --
> 1.9.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915: Add hot_plug hook for hdmi encoder
  2015-12-10  8:35                                 ` Jindal, Sonika
@ 2015-12-10  8:53                                   ` Daniel Vetter
  2015-12-10  9:04                                     ` Jindal, Sonika
  0 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2015-12-10  8:53 UTC (permalink / raw)
  To: Jindal, Sonika; +Cc: intel-gfx

On Thu, Dec 10, 2015 at 08:35:30AM +0000, Jindal, Sonika wrote:
> Sure, I will start a new thread for this.
> 
> Regarding the regression, since it is a sandybridge system, I am not
> sure if I can debug it anyhow because of the unavailability of the
> system.  For the live status check, we earlier suggested to use
> platforms gen8 and above.
> But for wider testing, we removed the check.
> If required we can add a check there.

It's your patch, you need to own this. And until we've confirmed that it's
a source issue I won't add a genAnything check but instead just revert the
patch.

I hope expectations from my side here are clear.

Thanks, Daniel

> 
> Regards,
> Sonika
> 
> -----Original Message-----
> From: Daniel Vetter [mailto:daniel.vetter@ffwll.ch] On Behalf Of Daniel Vetter
> Sent: Thursday, December 10, 2015 2:00 PM
> To: Jindal, Sonika <sonika.jindal@intel.com>
> Cc: intel-gfx@lists.freedesktop.org
> Subject: Re: [Intel-gfx] [PATCH] drm/i915: Add hot_plug hook for hdmi encoder
> 
> On Thu, Dec 10, 2015 at 10:15:41AM +0530, Sonika Jindal wrote:
> > From: Shashank Sharma <shashank.sharma@intel.com>
> > 
> > This patch adds a separate probe function for HDMI EDID read over DDC 
> > channel. This function has been registered as a .hot_plug handler for 
> > HDMI encoder.
> > 
> > The current implementation of hdmi_detect() function re-sets the 
> > cached HDMI edid (in connector->detect_edid) in every detect call.This 
> > function gets called many times, sometimes directly from userspace 
> > probes, forcing drivers to read EDID every detect function call.This 
> > causes several problems like:
> > 
> > 1. Race conditions in multiple hot_plug / unplug cases, between
> >    interrupts bottom halves and userspace detections.
> > 2. Many Un-necessary EDID reads for single hotplug/unplug 3. HDMI 
> > complaince failures which expects only one EDID read per hotplug
> > 
> > This function will be serving the purpose of really reading the EDID 
> > by really probing the DDC channel, and updating the cached EDID.
> > 
> > The plan is to:
> > 1. i915 IRQ handler bottom half function already calls
> >    intel_encoder->hotplug() function. Adding This probe function which
> >    will read the EDID only in case of a hotplug / unplug.
> > 2. During init_connector this probe will be called to read the edid 3. 
> > Reuse the cached EDID in hdmi_detect() function.
> > 
> > The "< gen7" check is there because this was tested only for >=gen7 
> > platforms. For older platforms the hotplug/reading edid path remains same.
> > 
> > v2: Calling set_edid instead of hdmi_probe during init.
> > Also, for platforms having DDI, intel_encoder for DP and HDMI is same 
> > (taken from intel_dig_port), so for DP also, hot_plug function gets 
> > called which is not intended here. So, check for HDMI in 
> > intel_hdmi_probe Rely on HPD for updating edid only for platforms gen > 8 and also for VLV.
> > 
> > v3: Dropping the gen < 8 || !VLV  check. Now all platforms should rely 
> > on hotplug or init for updating the edid.(Daniel) Also, calling 
> > hdmi_probe in init instead of set_edid
> > 
> > v4: Renaming intel_hdmi_probe to intel_hdmi_hot_plug.
> > Also calling this hotplug handler from intel_hpd_init to take care of 
> > init resume scenarios.
> > 
> > v5: Moved the call to encoder hotplug during init to separate 
> > patch(Daniel)
> > v6: Rebased and maintaining authorship.
> > 
> > Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
> > Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> 
> Iirc we had to revert an earlier version of this. Commit message should cite that revert and explain why this version is better.
> 
> Also after a few days please start a new thread when resubmitting a patch series. The idea behind in-reply-to is to keep the discussion together while it's still ongoing. That's not the case when the discussion has died down since weeks.
> 
> Also, your patch to take hpd sense into account for hdmi detection has causes a regression. Your on the cc. Handling that regression needs to be absolute top priority (otherwise I need to revert that patch too).
> 
> Thanks, Daniel
> 
> > ---
> >  drivers/gpu/drm/i915/intel_hdmi.c | 58 
> > ++++++++++++++++++++++++++++++---------
> >  1 file changed, 45 insertions(+), 13 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
> > b/drivers/gpu/drm/i915/intel_hdmi.c
> > index bdd462e..16dd2a7 100644
> > --- a/drivers/gpu/drm/i915/intel_hdmi.c
> > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> > @@ -1381,18 +1381,16 @@ intel_hdmi_set_edid(struct drm_connector *connector, bool force)
> >  	return connected;
> >  }
> >  
> > -static enum drm_connector_status
> > -intel_hdmi_detect(struct drm_connector *connector, bool force)
> > +void intel_hdmi_hot_plug(struct intel_encoder *intel_encoder)
> >  {
> > -	enum drm_connector_status status;
> > -	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
> > -	struct drm_i915_private *dev_priv = to_i915(connector->dev);
> > +	struct intel_hdmi *intel_hdmi =
> > +			enc_to_intel_hdmi(&intel_encoder->base);
> > +	struct intel_connector *intel_connector =
> > +				intel_hdmi->attached_connector;
> > +	struct drm_i915_private *dev_priv = 
> > +to_i915(intel_encoder->base.dev);
> >  	bool live_status = false;
> >  	unsigned int retry = 3;
> >  
> > -	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> > -		      connector->base.id, connector->name);
> > -
> >  	intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
> >  
> >  	while (!live_status && --retry) {
> > @@ -1400,21 +1398,53 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
> >  				hdmi_to_dig_port(intel_hdmi));
> >  		mdelay(10);
> >  	}
> > +	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
> >  
> >  	if (!live_status)
> >  		DRM_DEBUG_KMS("Live status not up!");
> >  
> > -	intel_hdmi_unset_edid(connector);
> > +	/*
> > +	 * We are here, means there is a hotplug or a force
> > +	 * detection. Clear the cached EDID and probe the
> > +	 * DDC bus to check the current status of HDMI.
> > +	 */
> > +	intel_hdmi_unset_edid(&intel_connector->base);
> > +	if (intel_hdmi_set_edid(&intel_connector->base, live_status))
> > +		DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
> > +	else
> > +		DRM_DEBUG_DRIVER("DDC probe: no EDID\n"); }
> > +
> > +static enum drm_connector_status
> > +intel_hdmi_detect(struct drm_connector *connector, bool force) {
> > +	enum drm_connector_status status;
> > +	struct intel_connector *intel_connector =
> > +				to_intel_connector(connector);
> >  
> > -	if (intel_hdmi_set_edid(connector, live_status)) {
> > +	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> > +		      connector->base.id, connector->name);
> > +
> > +	/*
> > +	 * There are many userspace calls which probe EDID from
> > +	 * detect path. In case of multiple hotplug/unplug, these
> > +	 * can cause race conditions while probing EDID. Also its
> > +	 * waste of CPU cycles to read the EDID again and again
> > +	 * unless there is a real hotplug.
> > +	 * So, rely on hotplugs and init to read edid.
> > +	 * Check connector status based on availability of cached EDID.
> > +	 */
> > +
> > +	if (intel_connector->detect_edid) {
> >  		struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
> >  
> >  		hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
> >  		status = connector_status_connected;
> > -	} else
> > +		DRM_DEBUG_DRIVER("hdmi status = connected\n");
> > +	} else {
> >  		status = connector_status_disconnected;
> > -
> > -	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
> > +		DRM_DEBUG_DRIVER("hdmi status = disconnected\n");
> > +	}
> >  
> >  	return status;
> >  }
> > @@ -2131,6 +2161,8 @@ void intel_hdmi_init_connector(struct 
> > intel_digital_port *intel_dig_port,
> >  
> >  	intel_hdmi_add_properties(intel_hdmi, connector);
> >  
> > +	intel_encoder->hot_plug = intel_hdmi_hot_plug;
> > +
> >  	intel_connector_attach_encoder(intel_connector, intel_encoder);
> >  	drm_connector_register(connector);
> >  	intel_hdmi->attached_connector = intel_connector;
> > --
> > 1.9.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915: Add hot_plug hook for hdmi encoder
  2015-12-10  8:53                                   ` Daniel Vetter
@ 2015-12-10  9:04                                     ` Jindal, Sonika
  0 siblings, 0 replies; 77+ messages in thread
From: Jindal, Sonika @ 2015-12-10  9:04 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

By "we" I meant me :)
Also, since it isn't possible to check all the platforms for live status, it is safer to put a gen check to platforms which we are sure.
Anyways, lets see if increasing the delay helps there, then you can take a call.

Regards,
Sonika

-----Original Message-----
From: Daniel Vetter [mailto:daniel.vetter@ffwll.ch] On Behalf Of Daniel Vetter
Sent: Thursday, December 10, 2015 2:24 PM
To: Jindal, Sonika <sonika.jindal@intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>; intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH] drm/i915: Add hot_plug hook for hdmi encoder

On Thu, Dec 10, 2015 at 08:35:30AM +0000, Jindal, Sonika wrote:
> Sure, I will start a new thread for this.
> 
> Regarding the regression, since it is a sandybridge system, I am not 
> sure if I can debug it anyhow because of the unavailability of the 
> system.  For the live status check, we earlier suggested to use 
> platforms gen8 and above.
> But for wider testing, we removed the check.
> If required we can add a check there.

It's your patch, you need to own this. And until we've confirmed that it's a source issue I won't add a genAnything check but instead just revert the patch.

I hope expectations from my side here are clear.

Thanks, Daniel

> 
> Regards,
> Sonika
> 
> -----Original Message-----
> From: Daniel Vetter [mailto:daniel.vetter@ffwll.ch] On Behalf Of 
> Daniel Vetter
> Sent: Thursday, December 10, 2015 2:00 PM
> To: Jindal, Sonika <sonika.jindal@intel.com>
> Cc: intel-gfx@lists.freedesktop.org
> Subject: Re: [Intel-gfx] [PATCH] drm/i915: Add hot_plug hook for hdmi 
> encoder
> 
> On Thu, Dec 10, 2015 at 10:15:41AM +0530, Sonika Jindal wrote:
> > From: Shashank Sharma <shashank.sharma@intel.com>
> > 
> > This patch adds a separate probe function for HDMI EDID read over 
> > DDC channel. This function has been registered as a .hot_plug 
> > handler for HDMI encoder.
> > 
> > The current implementation of hdmi_detect() function re-sets the 
> > cached HDMI edid (in connector->detect_edid) in every detect 
> > call.This function gets called many times, sometimes directly from 
> > userspace probes, forcing drivers to read EDID every detect function 
> > call.This causes several problems like:
> > 
> > 1. Race conditions in multiple hot_plug / unplug cases, between
> >    interrupts bottom halves and userspace detections.
> > 2. Many Un-necessary EDID reads for single hotplug/unplug 3. HDMI 
> > complaince failures which expects only one EDID read per hotplug
> > 
> > This function will be serving the purpose of really reading the EDID 
> > by really probing the DDC channel, and updating the cached EDID.
> > 
> > The plan is to:
> > 1. i915 IRQ handler bottom half function already calls
> >    intel_encoder->hotplug() function. Adding This probe function which
> >    will read the EDID only in case of a hotplug / unplug.
> > 2. During init_connector this probe will be called to read the edid 3. 
> > Reuse the cached EDID in hdmi_detect() function.
> > 
> > The "< gen7" check is there because this was tested only for >=gen7 
> > platforms. For older platforms the hotplug/reading edid path remains same.
> > 
> > v2: Calling set_edid instead of hdmi_probe during init.
> > Also, for platforms having DDI, intel_encoder for DP and HDMI is 
> > same (taken from intel_dig_port), so for DP also, hot_plug function 
> > gets called which is not intended here. So, check for HDMI in 
> > intel_hdmi_probe Rely on HPD for updating edid only for platforms gen > 8 and also for VLV.
> > 
> > v3: Dropping the gen < 8 || !VLV  check. Now all platforms should 
> > rely on hotplug or init for updating the edid.(Daniel) Also, calling 
> > hdmi_probe in init instead of set_edid
> > 
> > v4: Renaming intel_hdmi_probe to intel_hdmi_hot_plug.
> > Also calling this hotplug handler from intel_hpd_init to take care 
> > of init resume scenarios.
> > 
> > v5: Moved the call to encoder hotplug during init to separate
> > patch(Daniel)
> > v6: Rebased and maintaining authorship.
> > 
> > Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
> > Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> 
> Iirc we had to revert an earlier version of this. Commit message should cite that revert and explain why this version is better.
> 
> Also after a few days please start a new thread when resubmitting a patch series. The idea behind in-reply-to is to keep the discussion together while it's still ongoing. That's not the case when the discussion has died down since weeks.
> 
> Also, your patch to take hpd sense into account for hdmi detection has causes a regression. Your on the cc. Handling that regression needs to be absolute top priority (otherwise I need to revert that patch too).
> 
> Thanks, Daniel
> 
> > ---
> >  drivers/gpu/drm/i915/intel_hdmi.c | 58
> > ++++++++++++++++++++++++++++++---------
> >  1 file changed, 45 insertions(+), 13 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c
> > b/drivers/gpu/drm/i915/intel_hdmi.c
> > index bdd462e..16dd2a7 100644
> > --- a/drivers/gpu/drm/i915/intel_hdmi.c
> > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> > @@ -1381,18 +1381,16 @@ intel_hdmi_set_edid(struct drm_connector *connector, bool force)
> >  	return connected;
> >  }
> >  
> > -static enum drm_connector_status
> > -intel_hdmi_detect(struct drm_connector *connector, bool force)
> > +void intel_hdmi_hot_plug(struct intel_encoder *intel_encoder)
> >  {
> > -	enum drm_connector_status status;
> > -	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
> > -	struct drm_i915_private *dev_priv = to_i915(connector->dev);
> > +	struct intel_hdmi *intel_hdmi =
> > +			enc_to_intel_hdmi(&intel_encoder->base);
> > +	struct intel_connector *intel_connector =
> > +				intel_hdmi->attached_connector;
> > +	struct drm_i915_private *dev_priv = 
> > +to_i915(intel_encoder->base.dev);
> >  	bool live_status = false;
> >  	unsigned int retry = 3;
> >  
> > -	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> > -		      connector->base.id, connector->name);
> > -
> >  	intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
> >  
> >  	while (!live_status && --retry) {
> > @@ -1400,21 +1398,53 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
> >  				hdmi_to_dig_port(intel_hdmi));
> >  		mdelay(10);
> >  	}
> > +	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
> >  
> >  	if (!live_status)
> >  		DRM_DEBUG_KMS("Live status not up!");
> >  
> > -	intel_hdmi_unset_edid(connector);
> > +	/*
> > +	 * We are here, means there is a hotplug or a force
> > +	 * detection. Clear the cached EDID and probe the
> > +	 * DDC bus to check the current status of HDMI.
> > +	 */
> > +	intel_hdmi_unset_edid(&intel_connector->base);
> > +	if (intel_hdmi_set_edid(&intel_connector->base, live_status))
> > +		DRM_DEBUG_DRIVER("DDC probe: got EDID\n");
> > +	else
> > +		DRM_DEBUG_DRIVER("DDC probe: no EDID\n"); }
> > +
> > +static enum drm_connector_status
> > +intel_hdmi_detect(struct drm_connector *connector, bool force) {
> > +	enum drm_connector_status status;
> > +	struct intel_connector *intel_connector =
> > +				to_intel_connector(connector);
> >  
> > -	if (intel_hdmi_set_edid(connector, live_status)) {
> > +	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> > +		      connector->base.id, connector->name);
> > +
> > +	/*
> > +	 * There are many userspace calls which probe EDID from
> > +	 * detect path. In case of multiple hotplug/unplug, these
> > +	 * can cause race conditions while probing EDID. Also its
> > +	 * waste of CPU cycles to read the EDID again and again
> > +	 * unless there is a real hotplug.
> > +	 * So, rely on hotplugs and init to read edid.
> > +	 * Check connector status based on availability of cached EDID.
> > +	 */
> > +
> > +	if (intel_connector->detect_edid) {
> >  		struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
> >  
> >  		hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
> >  		status = connector_status_connected;
> > -	} else
> > +		DRM_DEBUG_DRIVER("hdmi status = connected\n");
> > +	} else {
> >  		status = connector_status_disconnected;
> > -
> > -	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
> > +		DRM_DEBUG_DRIVER("hdmi status = disconnected\n");
> > +	}
> >  
> >  	return status;
> >  }
> > @@ -2131,6 +2161,8 @@ void intel_hdmi_init_connector(struct 
> > intel_digital_port *intel_dig_port,
> >  
> >  	intel_hdmi_add_properties(intel_hdmi, connector);
> >  
> > +	intel_encoder->hot_plug = intel_hdmi_hot_plug;
> > +
> >  	intel_connector_attach_encoder(intel_connector, intel_encoder);
> >  	drm_connector_register(connector);
> >  	intel_hdmi->attached_connector = intel_connector;
> > --
> > 1.9.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915: Check live status before reading edid
  2015-09-15  4:14                 ` Sonika Jindal
  2015-09-23  8:18                   ` Daniel Vetter
@ 2016-03-08 21:03                   ` Chris Wilson
  2016-03-09  5:52                     ` Jindal, Sonika
  1 sibling, 1 reply; 77+ messages in thread
From: Chris Wilson @ 2016-03-08 21:03 UTC (permalink / raw)
  To: Sonika Jindal; +Cc: intel-gfx

On Tue, Sep 15, 2015 at 09:44:20AM +0530, Sonika Jindal wrote:
> The Bspec is very clear that Live status must be checked about before
> trying to read EDID over DDC channel. This patch makes sure that HDMI
> EDID is read only when live status is up.
> 
> The live status doesn't seem to perform very consistent across various
> platforms when tested with different monitors. The reason behind that is
> some monitors are late to provide right voltage to set live_status up.
> So, after getting the interrupt, for a small duration, live status reg
> fluctuates, and then settles down showing the correct staus.
> 
> This is explained here in, in a rough way:
> HPD line  ________________
> 			 |\ T1 = Monitor Hotplug causing IRQ
> 			 | \______________________________________
> 			 | |
>                          | |
> 			 | |   T2 = Live status is stable
> 			 | |  _____________________________________
> 			 | | /|
> Live status _____________|_|/ |
> 			 | |  |
> 			 | |  |
> 			 | |  |
> 			T0 T1  T2
> 
> (Between T1 and T2 Live status fluctuates or can be even low, depending on
>  the monitor)
> 
> After several experiments, we have concluded that a max delay
> of 30ms is enough to allow the live status to settle down with
> most of the monitors. This total delay of 30ms has been split into
> a resolution of 3 retries of 10ms each, for the better cases.
> 
> This delay is kept at 30ms, keeping in consideration that, HDCP compliance
> expect the HPD handler to respond a plug out in 100ms, by disabling port.

This is a regression-fest. Revert with stable@?
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915: Check live status before reading edid
  2016-03-08 21:03                   ` Chris Wilson
@ 2016-03-09  5:52                     ` Jindal, Sonika
  2016-03-09  5:55                       ` Sharma, Shashank
  0 siblings, 1 reply; 77+ messages in thread
From: Jindal, Sonika @ 2016-03-09  5:52 UTC (permalink / raw)
  To: Chris Wilson, Sharma, Shashank; +Cc: intel-gfx

+Shashank

Shashank was planning to give a patch to bypass live status checks for older platforms.

Regards,
Sonika

-----Original Message-----
From: Chris Wilson [mailto:chris@chris-wilson.co.uk] 
Sent: Wednesday, March 9, 2016 2:34 AM
To: Jindal, Sonika <sonika.jindal@intel.com>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH] drm/i915: Check live status before reading edid

On Tue, Sep 15, 2015 at 09:44:20AM +0530, Sonika Jindal wrote:
> The Bspec is very clear that Live status must be checked about before 
> trying to read EDID over DDC channel. This patch makes sure that HDMI 
> EDID is read only when live status is up.
> 
> The live status doesn't seem to perform very consistent across various 
> platforms when tested with different monitors. The reason behind that 
> is some monitors are late to provide right voltage to set live_status up.
> So, after getting the interrupt, for a small duration, live status reg 
> fluctuates, and then settles down showing the correct staus.
> 
> This is explained here in, in a rough way:
> HPD line  ________________
> 			 |\ T1 = Monitor Hotplug causing IRQ
> 			 | \______________________________________
> 			 | |
>                          | |
> 			 | |   T2 = Live status is stable
> 			 | |  _____________________________________
> 			 | | /|
> Live status _____________|_|/ |
> 			 | |  |
> 			 | |  |
> 			 | |  |
> 			T0 T1  T2
> 
> (Between T1 and T2 Live status fluctuates or can be even low, 
> depending on  the monitor)
> 
> After several experiments, we have concluded that a max delay of 30ms 
> is enough to allow the live status to settle down with most of the 
> monitors. This total delay of 30ms has been split into a resolution of 
> 3 retries of 10ms each, for the better cases.
> 
> This delay is kept at 30ms, keeping in consideration that, HDCP 
> compliance expect the HPD handler to respond a plug out in 100ms, by disabling port.

This is a regression-fest. Revert with stable@?
-Chris

--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915: Check live status before reading edid
  2016-03-09  5:52                     ` Jindal, Sonika
@ 2016-03-09  5:55                       ` Sharma, Shashank
  2016-03-10 11:37                         ` Sharma, Shashank
  0 siblings, 1 reply; 77+ messages in thread
From: Sharma, Shashank @ 2016-03-09  5:55 UTC (permalink / raw)
  To: Jindal, Sonika, Chris Wilson; +Cc: intel-gfx

We are procuring the DVI-single-link cable, as we don't have one with us. 
Sonika tested the Dual link cable, and that was working well. 

We can do two things here: 
- Add the gen check, which will allow the live_status check only for VLV and + platforms, others will go as it is. 
- Wait for some more time, get the cable and try to rep and fix the issue. 

Regards
Shashank
-----Original Message-----
From: Jindal, Sonika 
Sent: Wednesday, March 09, 2016 11:23 AM
To: Chris Wilson; Sharma, Shashank
Cc: intel-gfx@lists.freedesktop.org
Subject: RE: [Intel-gfx] [PATCH] drm/i915: Check live status before reading edid

+Shashank

Shashank was planning to give a patch to bypass live status checks for older platforms.

Regards,
Sonika

-----Original Message-----
From: Chris Wilson [mailto:chris@chris-wilson.co.uk]
Sent: Wednesday, March 9, 2016 2:34 AM
To: Jindal, Sonika <sonika.jindal@intel.com>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH] drm/i915: Check live status before reading edid

On Tue, Sep 15, 2015 at 09:44:20AM +0530, Sonika Jindal wrote:
> The Bspec is very clear that Live status must be checked about before 
> trying to read EDID over DDC channel. This patch makes sure that HDMI 
> EDID is read only when live status is up.
> 
> The live status doesn't seem to perform very consistent across various 
> platforms when tested with different monitors. The reason behind that 
> is some monitors are late to provide right voltage to set live_status up.
> So, after getting the interrupt, for a small duration, live status reg 
> fluctuates, and then settles down showing the correct staus.
> 
> This is explained here in, in a rough way:
> HPD line  ________________
> 			 |\ T1 = Monitor Hotplug causing IRQ
> 			 | \______________________________________
> 			 | |
>                          | |
> 			 | |   T2 = Live status is stable
> 			 | |  _____________________________________
> 			 | | /|
> Live status _____________|_|/ |
> 			 | |  |
> 			 | |  |
> 			 | |  |
> 			T0 T1  T2
> 
> (Between T1 and T2 Live status fluctuates or can be even low, 
> depending on  the monitor)
> 
> After several experiments, we have concluded that a max delay of 30ms 
> is enough to allow the live status to settle down with most of the 
> monitors. This total delay of 30ms has been split into a resolution of
> 3 retries of 10ms each, for the better cases.
> 
> This delay is kept at 30ms, keeping in consideration that, HDCP 
> compliance expect the HPD handler to respond a plug out in 100ms, by disabling port.

This is a regression-fest. Revert with stable@?
-Chris

--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/i915: Check live status before reading edid
  2016-03-09  5:55                       ` Sharma, Shashank
@ 2016-03-10 11:37                         ` Sharma, Shashank
  0 siblings, 0 replies; 77+ messages in thread
From: Sharma, Shashank @ 2016-03-10 11:37 UTC (permalink / raw)
  To: Jindal, Sonika, 'Chris Wilson'
  Cc: 'intel-gfx@lists.freedesktop.org'

Hi all, 

I have sent one patch with live_status check restricted to gen7 and +, for this regression.
drm/i915: Restrict usage of live status check
Please help in review. 

Regards
Shashank
-----Original Message-----
From: Sharma, Shashank 
Sent: Wednesday, March 09, 2016 11:25 AM
To: Jindal, Sonika; Chris Wilson
Cc: intel-gfx@lists.freedesktop.org; Mukherjee, Indranil
Subject: RE: [Intel-gfx] [PATCH] drm/i915: Check live status before reading edid

We are procuring the DVI-single-link cable, as we don't have one with us. 
Sonika tested the Dual link cable, and that was working well. 

We can do two things here: 
- Add the gen check, which will allow the live_status check only for VLV and + platforms, others will go as it is. 
- Wait for some more time, get the cable and try to rep and fix the issue. 

Regards
Shashank
-----Original Message-----
From: Jindal, Sonika
Sent: Wednesday, March 09, 2016 11:23 AM
To: Chris Wilson; Sharma, Shashank
Cc: intel-gfx@lists.freedesktop.org
Subject: RE: [Intel-gfx] [PATCH] drm/i915: Check live status before reading edid

+Shashank

Shashank was planning to give a patch to bypass live status checks for older platforms.

Regards,
Sonika

-----Original Message-----
From: Chris Wilson [mailto:chris@chris-wilson.co.uk]
Sent: Wednesday, March 9, 2016 2:34 AM
To: Jindal, Sonika <sonika.jindal@intel.com>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH] drm/i915: Check live status before reading edid

On Tue, Sep 15, 2015 at 09:44:20AM +0530, Sonika Jindal wrote:
> The Bspec is very clear that Live status must be checked about before 
> trying to read EDID over DDC channel. This patch makes sure that HDMI 
> EDID is read only when live status is up.
> 
> The live status doesn't seem to perform very consistent across various 
> platforms when tested with different monitors. The reason behind that 
> is some monitors are late to provide right voltage to set live_status up.
> So, after getting the interrupt, for a small duration, live status reg 
> fluctuates, and then settles down showing the correct staus.
> 
> This is explained here in, in a rough way:
> HPD line  ________________
> 			 |\ T1 = Monitor Hotplug causing IRQ
> 			 | \______________________________________
> 			 | |
>                          | |
> 			 | |   T2 = Live status is stable
> 			 | |  _____________________________________
> 			 | | /|
> Live status _____________|_|/ |
> 			 | |  |
> 			 | |  |
> 			 | |  |
> 			T0 T1  T2
> 
> (Between T1 and T2 Live status fluctuates or can be even low, 
> depending on  the monitor)
> 
> After several experiments, we have concluded that a max delay of 30ms 
> is enough to allow the live status to settle down with most of the 
> monitors. This total delay of 30ms has been split into a resolution of
> 3 retries of 10ms each, for the better cases.
> 
> This delay is kept at 30ms, keeping in consideration that, HDCP 
> compliance expect the HPD handler to respond a plug out in 100ms, by disabling port.

This is a regression-fest. Revert with stable@?
-Chris

--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
  2015-12-16 13:46 ` Daniel Vetter
@ 2015-12-17  4:23   ` Jindal, Sonika
  0 siblings, 0 replies; 77+ messages in thread
From: Jindal, Sonika @ 2015-12-17  4:23 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx



On 12/16/2015 7:16 PM, Daniel Vetter wrote:
> On Wed, Dec 16, 2015 at 04:18:05PM +0530, Sonika Jindal wrote:
>> Call the encoders, call the hot_plug if it is registered.
>> This is required for connected boot and resume cases to generate
>> fake hpd resulting in reading of edid.
>> Removing the initial sdvo hot_plug call too so that it will be called
>> just once from this loop.
>>
>> v2: Schedule a work function to call hot_plug. On CHT, it runs into a
>> deadlock if we call ->hot_plug inside hpd_init. This is because, hot_plug
>> calls set_edid which tries to acquire the power domain and if power
>> well is disabled, we enable power well and call hpd_init again.
>> So, schedule a work function from here to call hot_plug and run a
>> detect cycle.
>>
>> Cc: Shashank Sharma <shashank.sharma@intel.com>
>> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
>> ---
>>
>>   drivers/gpu/drm/i915/i915_drv.h      |  1 +
>>   drivers/gpu/drm/i915/intel_hotplug.c | 26 ++++++++++++++++++++++++++
>>   drivers/gpu/drm/i915/intel_sdvo.c    |  1 -
>>   3 files changed, 27 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>> index bc865e23..4f037b9 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -228,6 +228,7 @@ enum hpd_pin {
>>   
>>   struct i915_hotplug {
>>   	struct work_struct hotplug_work;
>> +	struct work_struct edid_work;
>>   
>>   	struct {
>>   		unsigned long last_jiffies;
>> diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
>> index b177857..72d8fe8 100644
>> --- a/drivers/gpu/drm/i915/intel_hotplug.c
>> +++ b/drivers/gpu/drm/i915/intel_hotplug.c
>> @@ -442,6 +442,24 @@ void intel_hpd_irq_handler(struct drm_device *dev,
>>   		schedule_work(&dev_priv->hotplug.hotplug_work);
>>   }
>>   
>> +static void i915_edid_work_func(struct work_struct *work)
>> +{
>> +	struct drm_i915_private *dev_priv =
>> +		container_of(work, struct drm_i915_private, hotplug.edid_work);
>> +	struct drm_device *dev = dev_priv->dev;
>> +	struct drm_mode_config *mode_config = &dev->mode_config;
>> +	struct intel_encoder *encoder;
>> +
>> +	mutex_lock(&mode_config->mutex);
>> +	list_for_each_entry(encoder, &mode_config->encoder_list,
>> +			base.head) {
>> +		if (encoder->hot_plug)
>> +			encoder->hot_plug(encoder);
>> +	}
>> +	mutex_unlock(&mode_config->mutex);
>> +	drm_helper_hpd_irq_event(dev);
>> +}
> Why do we need a completely new hand-rolled work? My idea was to reuse the
> existing hpd irq handler, but instead of just scheduling that (which won't
> do anything) fake-inject a full set of hpd interrupts into it. Well, we
> need to inject short-pulse ones to avoid upsetting dp mst.
> -Daniel
Hmm, this suggestion came from Siva as well to just set the event_bits. 
Let me try that.

Thanks,
Sonika
>> +
>>   /**
>>    * intel_hpd_init - initializes and enables hpd support
>>    * @dev_priv: i915 device instance
>> @@ -482,12 +500,19 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
>>   	if (dev_priv->display.hpd_irq_setup)
>>   		dev_priv->display.hpd_irq_setup(dev);
>>   	spin_unlock_irq(&dev_priv->irq_lock);
>> +
>> +	/*
>> +	 * Connected boot / resume scenarios can't generate new hot plug.
>> +	 * So, probe it manually.
>> +	 */
>> +	schedule_work(&dev_priv->hotplug.edid_work);
>>   }
>>   
>>   void intel_hpd_init_work(struct drm_i915_private *dev_priv)
>>   {
>>   	INIT_WORK(&dev_priv->hotplug.hotplug_work, i915_hotplug_work_func);
>>   	INIT_WORK(&dev_priv->hotplug.dig_port_work, i915_digport_work_func);
>> +	INIT_WORK(&dev_priv->hotplug.edid_work, i915_edid_work_func);
>>   	INIT_DELAYED_WORK(&dev_priv->hotplug.reenable_work,
>>   			  intel_hpd_irq_storm_reenable_work);
>>   }
>> @@ -504,5 +529,6 @@ void intel_hpd_cancel_work(struct drm_i915_private *dev_priv)
>>   
>>   	cancel_work_sync(&dev_priv->hotplug.dig_port_work);
>>   	cancel_work_sync(&dev_priv->hotplug.hotplug_work);
>> +	cancel_work_sync(&dev_priv->hotplug.edid_work);
>>   	cancel_delayed_work_sync(&dev_priv->hotplug.reenable_work);
>>   }
>> diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
>> index 06679f1..4238a02 100644
>> --- a/drivers/gpu/drm/i915/intel_sdvo.c
>> +++ b/drivers/gpu/drm/i915/intel_sdvo.c
>> @@ -2466,7 +2466,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
>>   		 * Ensure that they get re-enabled when an interrupt happens.
>>   		 */
>>   		intel_encoder->hot_plug = intel_sdvo_enable_hotplug;
>> -		intel_sdvo_enable_hotplug(intel_encoder);
>>   	} else {
>>   		intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
>>   	}
>> -- 
>> 1.9.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
  2015-12-16 10:48 [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases Sonika Jindal
@ 2015-12-16 13:46 ` Daniel Vetter
  2015-12-17  4:23   ` Jindal, Sonika
  0 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2015-12-16 13:46 UTC (permalink / raw)
  To: Sonika Jindal; +Cc: intel-gfx

On Wed, Dec 16, 2015 at 04:18:05PM +0530, Sonika Jindal wrote:
> Call the encoders, call the hot_plug if it is registered.
> This is required for connected boot and resume cases to generate
> fake hpd resulting in reading of edid.
> Removing the initial sdvo hot_plug call too so that it will be called
> just once from this loop.
> 
> v2: Schedule a work function to call hot_plug. On CHT, it runs into a
> deadlock if we call ->hot_plug inside hpd_init. This is because, hot_plug
> calls set_edid which tries to acquire the power domain and if power
> well is disabled, we enable power well and call hpd_init again.
> So, schedule a work function from here to call hot_plug and run a
> detect cycle.
> 
> Cc: Shashank Sharma <shashank.sharma@intel.com>
> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> ---
> 
>  drivers/gpu/drm/i915/i915_drv.h      |  1 +
>  drivers/gpu/drm/i915/intel_hotplug.c | 26 ++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_sdvo.c    |  1 -
>  3 files changed, 27 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index bc865e23..4f037b9 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -228,6 +228,7 @@ enum hpd_pin {
>  
>  struct i915_hotplug {
>  	struct work_struct hotplug_work;
> +	struct work_struct edid_work;
>  
>  	struct {
>  		unsigned long last_jiffies;
> diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
> index b177857..72d8fe8 100644
> --- a/drivers/gpu/drm/i915/intel_hotplug.c
> +++ b/drivers/gpu/drm/i915/intel_hotplug.c
> @@ -442,6 +442,24 @@ void intel_hpd_irq_handler(struct drm_device *dev,
>  		schedule_work(&dev_priv->hotplug.hotplug_work);
>  }
>  
> +static void i915_edid_work_func(struct work_struct *work)
> +{
> +	struct drm_i915_private *dev_priv =
> +		container_of(work, struct drm_i915_private, hotplug.edid_work);
> +	struct drm_device *dev = dev_priv->dev;
> +	struct drm_mode_config *mode_config = &dev->mode_config;
> +	struct intel_encoder *encoder;
> +
> +	mutex_lock(&mode_config->mutex);
> +	list_for_each_entry(encoder, &mode_config->encoder_list,
> +			base.head) {
> +		if (encoder->hot_plug)
> +			encoder->hot_plug(encoder);
> +	}
> +	mutex_unlock(&mode_config->mutex);
> +	drm_helper_hpd_irq_event(dev);
> +}

Why do we need a completely new hand-rolled work? My idea was to reuse the
existing hpd irq handler, but instead of just scheduling that (which won't
do anything) fake-inject a full set of hpd interrupts into it. Well, we
need to inject short-pulse ones to avoid upsetting dp mst.
-Daniel

> +
>  /**
>   * intel_hpd_init - initializes and enables hpd support
>   * @dev_priv: i915 device instance
> @@ -482,12 +500,19 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
>  	if (dev_priv->display.hpd_irq_setup)
>  		dev_priv->display.hpd_irq_setup(dev);
>  	spin_unlock_irq(&dev_priv->irq_lock);
> +
> +	/*
> +	 * Connected boot / resume scenarios can't generate new hot plug.
> +	 * So, probe it manually.
> +	 */
> +	schedule_work(&dev_priv->hotplug.edid_work);
>  }
>  
>  void intel_hpd_init_work(struct drm_i915_private *dev_priv)
>  {
>  	INIT_WORK(&dev_priv->hotplug.hotplug_work, i915_hotplug_work_func);
>  	INIT_WORK(&dev_priv->hotplug.dig_port_work, i915_digport_work_func);
> +	INIT_WORK(&dev_priv->hotplug.edid_work, i915_edid_work_func);
>  	INIT_DELAYED_WORK(&dev_priv->hotplug.reenable_work,
>  			  intel_hpd_irq_storm_reenable_work);
>  }
> @@ -504,5 +529,6 @@ void intel_hpd_cancel_work(struct drm_i915_private *dev_priv)
>  
>  	cancel_work_sync(&dev_priv->hotplug.dig_port_work);
>  	cancel_work_sync(&dev_priv->hotplug.hotplug_work);
> +	cancel_work_sync(&dev_priv->hotplug.edid_work);
>  	cancel_delayed_work_sync(&dev_priv->hotplug.reenable_work);
>  }
> diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
> index 06679f1..4238a02 100644
> --- a/drivers/gpu/drm/i915/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> @@ -2466,7 +2466,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
>  		 * Ensure that they get re-enabled when an interrupt happens.
>  		 */
>  		intel_encoder->hot_plug = intel_sdvo_enable_hotplug;
> -		intel_sdvo_enable_hotplug(intel_encoder);
>  	} else {
>  		intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
>  	}
> -- 
> 1.9.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
@ 2015-12-16 10:48 Sonika Jindal
  2015-12-16 13:46 ` Daniel Vetter
  0 siblings, 1 reply; 77+ messages in thread
From: Sonika Jindal @ 2015-12-16 10:48 UTC (permalink / raw)
  To: intel-gfx

Call the encoders, call the hot_plug if it is registered.
This is required for connected boot and resume cases to generate
fake hpd resulting in reading of edid.
Removing the initial sdvo hot_plug call too so that it will be called
just once from this loop.

v2: Schedule a work function to call hot_plug. On CHT, it runs into a
deadlock if we call ->hot_plug inside hpd_init. This is because, hot_plug
calls set_edid which tries to acquire the power domain and if power
well is disabled, we enable power well and call hpd_init again.
So, schedule a work function from here to call hot_plug and run a
detect cycle.

Cc: Shashank Sharma <shashank.sharma@intel.com>
Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---

 drivers/gpu/drm/i915/i915_drv.h      |  1 +
 drivers/gpu/drm/i915/intel_hotplug.c | 26 ++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_sdvo.c    |  1 -
 3 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index bc865e23..4f037b9 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -228,6 +228,7 @@ enum hpd_pin {
 
 struct i915_hotplug {
 	struct work_struct hotplug_work;
+	struct work_struct edid_work;
 
 	struct {
 		unsigned long last_jiffies;
diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
index b177857..72d8fe8 100644
--- a/drivers/gpu/drm/i915/intel_hotplug.c
+++ b/drivers/gpu/drm/i915/intel_hotplug.c
@@ -442,6 +442,24 @@ void intel_hpd_irq_handler(struct drm_device *dev,
 		schedule_work(&dev_priv->hotplug.hotplug_work);
 }
 
+static void i915_edid_work_func(struct work_struct *work)
+{
+	struct drm_i915_private *dev_priv =
+		container_of(work, struct drm_i915_private, hotplug.edid_work);
+	struct drm_device *dev = dev_priv->dev;
+	struct drm_mode_config *mode_config = &dev->mode_config;
+	struct intel_encoder *encoder;
+
+	mutex_lock(&mode_config->mutex);
+	list_for_each_entry(encoder, &mode_config->encoder_list,
+			base.head) {
+		if (encoder->hot_plug)
+			encoder->hot_plug(encoder);
+	}
+	mutex_unlock(&mode_config->mutex);
+	drm_helper_hpd_irq_event(dev);
+}
+
 /**
  * intel_hpd_init - initializes and enables hpd support
  * @dev_priv: i915 device instance
@@ -482,12 +500,19 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
 	if (dev_priv->display.hpd_irq_setup)
 		dev_priv->display.hpd_irq_setup(dev);
 	spin_unlock_irq(&dev_priv->irq_lock);
+
+	/*
+	 * Connected boot / resume scenarios can't generate new hot plug.
+	 * So, probe it manually.
+	 */
+	schedule_work(&dev_priv->hotplug.edid_work);
 }
 
 void intel_hpd_init_work(struct drm_i915_private *dev_priv)
 {
 	INIT_WORK(&dev_priv->hotplug.hotplug_work, i915_hotplug_work_func);
 	INIT_WORK(&dev_priv->hotplug.dig_port_work, i915_digport_work_func);
+	INIT_WORK(&dev_priv->hotplug.edid_work, i915_edid_work_func);
 	INIT_DELAYED_WORK(&dev_priv->hotplug.reenable_work,
 			  intel_hpd_irq_storm_reenable_work);
 }
@@ -504,5 +529,6 @@ void intel_hpd_cancel_work(struct drm_i915_private *dev_priv)
 
 	cancel_work_sync(&dev_priv->hotplug.dig_port_work);
 	cancel_work_sync(&dev_priv->hotplug.hotplug_work);
+	cancel_work_sync(&dev_priv->hotplug.edid_work);
 	cancel_delayed_work_sync(&dev_priv->hotplug.reenable_work);
 }
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 06679f1..4238a02 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -2466,7 +2466,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
 		 * Ensure that they get re-enabled when an interrupt happens.
 		 */
 		intel_encoder->hot_plug = intel_sdvo_enable_hotplug;
-		intel_sdvo_enable_hotplug(intel_encoder);
 	} else {
 		intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
 	}
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

end of thread, other threads:[~2016-03-10 11:38 UTC | newest]

Thread overview: 77+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-04 13:26 [PATCH 0/6] HDMI optimization series Sonika Jindal
2015-09-04 13:26 ` [PATCH 1/6] drm/i915: add attached connector to hdmi container Sonika Jindal
2015-09-09 18:54   ` Rodrigo Vivi
2015-09-10 15:24     ` Daniel Vetter
2015-09-04 13:26 ` [PATCH 2/6] drm/i915: Add HDMI probe function Sonika Jindal
2015-09-04 14:48   ` Daniel Vetter
2015-09-09 18:55     ` Rodrigo Vivi
2015-09-11 10:45       ` Jindal, Sonika
2015-09-14  8:30         ` Daniel Vetter
2015-09-14  9:55           ` Sharma, Shashank
2015-09-14 13:07             ` Daniel Vetter
2015-09-14 13:45               ` Sharma, Shashank
2015-09-28  8:56                 ` [PATCH] drm/i915: Add hot_plug hook for hdmi encoder Sonika Jindal
2015-09-28 13:34                   ` Daniel Vetter
2015-09-29  4:13                     ` Jindal, Sonika
2015-09-29  9:04                       ` Daniel Vetter
2015-10-05 11:13                     ` [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases Sonika Jindal
2015-10-05 11:13                       ` [PATCH 2/2] drm/i915: Add hot_plug hook for hdmi encoder Sonika Jindal
2015-10-06  8:28                         ` Daniel Vetter
2015-12-10  4:30                           ` Sonika Jindal
2015-12-10  4:45                             ` [PATCH] " Sonika Jindal
2015-12-10  8:29                               ` Daniel Vetter
2015-12-10  8:35                                 ` Jindal, Sonika
2015-12-10  8:53                                   ` Daniel Vetter
2015-12-10  9:04                                     ` Jindal, Sonika
2015-10-08 13:35                       ` [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases Ville Syrjälä
2015-10-08 14:38                         ` Jani Nikula
2015-10-08 19:54                           ` Daniel Vetter
2015-10-09  4:31                             ` Jindal, Sonika
2015-12-10  4:27                             ` Sonika Jindal
2015-10-12 12:24                         ` Sharma, Shashank
2015-10-15  1:32                           ` Jindal, Sonika
2015-09-04 13:26 ` [PATCH 3/6] drm/i915: Make intel_digital_port_connected global Sonika Jindal
2015-09-09 18:57   ` Rodrigo Vivi
2015-09-11 11:28     ` [PATCH] drm/i915/bxt: Use intel_encoder->hpd_pin to check live status Sonika Jindal
2015-09-11 18:00       ` Rodrigo Vivi
2015-09-12 12:02         ` Jindal, Sonika
2015-09-14  8:34       ` Daniel Vetter
2015-09-14  8:38         ` Jindal, Sonika
2015-09-14  9:15           ` Daniel Vetter
2015-09-04 13:26 ` [PATCH 4/6] drm/i915: drm/i915: Check live status before reading edid Sonika Jindal
2015-09-04 14:49   ` Daniel Vetter
2015-09-07  5:02     ` [PATCH] " Sonika Jindal
2015-09-08 11:21       ` Sonika Jindal
2015-09-09 19:11     ` [PATCH 4/6] drm/i915: " Rodrigo Vivi
2015-09-11 11:26       ` [PATCH] " Sonika Jindal
2015-09-11 17:56         ` Rodrigo Vivi
2015-09-14  8:42           ` Daniel Vetter
2015-09-14  9:14             ` Jindal, Sonika
2015-09-14  9:36               ` Daniel Vetter
2015-09-15  4:14                 ` Sonika Jindal
2015-09-23  8:18                   ` Daniel Vetter
2016-03-08 21:03                   ` Chris Wilson
2016-03-09  5:52                     ` Jindal, Sonika
2016-03-09  5:55                       ` Sharma, Shashank
2016-03-10 11:37                         ` Sharma, Shashank
2015-09-04 13:26 ` [PATCH 5/6] drm/i915: drm/i915: Process hpd only for hdmi inside hotplug_work_func Sonika Jindal
2015-09-04 14:47   ` Daniel Vetter
2015-09-06  4:31     ` Jindal, Sonika
2015-09-07  5:04       ` [PATCH] drm/i915: Call encoder hot_plug hook only for hdmi Sonika Jindal
2015-09-07 16:26         ` Daniel Vetter
2015-09-08  4:42           ` Jindal, Sonika
2015-09-08 11:38             ` Jindal, Sonika
2015-09-09 15:17               ` Daniel Vetter
2015-09-10  1:07                 ` Jindal, Sonika
2015-09-10 14:47                   ` Daniel Vetter
2015-09-09 19:20       ` [PATCH 5/6] drm/i915: drm/i915: Process hpd only for hdmi inside hotplug_work_func Rodrigo Vivi
2015-09-09 23:37         ` Jindal, Sonika
2015-09-04 13:26 ` [PATCH 6/6] drm/i915/bxt: Fix irq_port for eDP Sonika Jindal
2015-09-09 19:24   ` Rodrigo Vivi
2015-09-10 10:49     ` Jindal, Sonika
2015-09-10 13:07     ` R, Durgadoss
2015-09-10 13:35       ` Ville Syrjälä
2015-09-10 14:51         ` Daniel Vetter
2015-12-16 10:48 [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases Sonika Jindal
2015-12-16 13:46 ` Daniel Vetter
2015-12-17  4:23   ` Jindal, Sonika

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.