Re: [Intel-gfx] [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
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 Signed-off-by: Sonika Jindal --- 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.freedeskto
Re: [Intel-gfx] [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
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 > Signed-off-by: Sonika Jindal > --- > > 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
[Intel-gfx] [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
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 Signed-off-by: Sonika Jindal --- 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
[Intel-gfx] [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
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 --- 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
Re: [Intel-gfx] [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
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-boun...@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 > --- > 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: [] intel_display_power_get+0x38/0xcb [i915] [ 3187.647492] [ 3187.647492] but task is already holding lock: [ 3187.661054] (&power_domains->lock){+.+...}, at: [] 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: [] drm_release+0x3b/0x49b [drm] [
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-boun...@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 > --- > 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: [] intel_display_power_get+0x38/0xcb [i915] [ 3187.647492] [ 3187.647492] but task is already holding lock: [ 3187.661054] (&power_domains->lock){+.+...}, at: [] 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: [] drm_release+0x3b/0x49b [drm] [ 3187.785216] #1: (&dev->mode_config.mutex){+.+.+.}, at: [] drm_modeset_lock_all+0x54/0xcd [drm] [ 3187.800437] #2: (crtc_ww_class_acquire){+.+.+.}, at: [] drm_modeset_lock_all+0x5e/0xcd [drm] [ 3187.815488] #3: (crtc_ww_class_mutex){+.+.+.}, at: [] drm_modeset_lock+0x75/0xfc [drm] [ 3187.830094] #4: (&power_domains->lock){+.+...}, at: [] 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] 880175eff8e0 8128d59e 823f5ee0 [ 3187.898904] 880175eff958 810a7a08 000
Re: [Intel-gfx] [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
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ä 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 --- 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: [] intel_display_power_get+0x38/0xcb [i915] [ 3187.647492] [ 3187.647492] but task is already holding lock: [ 3187.661054] (&power_domains->lock){+.+...}, at: [] 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: [] drm_release+0x3b/0x49b [drm] [ 3187.785216] #1: (&dev->mode_config.mutex){+.+.+.}, at: [] drm_modeset_lock_all+0x54/0xcd [drm] [ 3187.800437] #2: (crtc_ww_class_acquire){+.+.+.}, at: [] drm_modeset_lock_all+0x5e/0xcd [drm] [ 3187.815488] #3: (crtc_ww_class_mutex){+.+.+.}, at: [] drm_modeset_lock+0x75/0xfc [drm] [ 3187.830094] #4: (&power_domains->lock){+.+...}, at: [] 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] 880175eff8e0 8128d59e 823f5ee0 [ 3187.898904] 880175eff958 810a7a08 880179d1c5d0 [ 3187.910954] 0004 0006 45422a91588a4c3e 0005 [ 3187.923011] Call Trace: [ 3187.929451] [] dump_stack+0x4e/0x79 [ 3187.938912] [] __lock_acquire+0x7ab/0x12af [ 3187.949027] [] lock_acquire+0x10e/0x1a9 [ 3187.958859] [] ? intel_display_power_get+0x38/0xcb [i915] [ 3187.970476] [] ? intel_display_power_get+0x38/0xcb [i915] [ 3187.982011] [] mutex_lock_nested+0x71/0x346 [ 3187.992167] [] ? intel_display_power_get+0x38/0xcb [i915] [ 3188.003655] [] ? _raw_spin_unlock_irqrestore+0x4b/0x60 [ 3188.014829] [] ? __pm_runtime_resume+0x71/0x7e [ 3188.025269] [] intel_display_power_get+0x38/0xcb [i915] [ 3188.036544] [] ? intel_display_power_get+0x38/0xcb [i915] [ 3188.047968] [] intel_hdmi_set_edid+0x3f/0xd6 [i915] [ 3188.058766] [] intel_hdmi_hot_plug+0xbf/0xfb [i915] [ 3188.069484] [] intel_hpd_init+0xfa/0x10b [i915] [ 3188.079753] [] vlv_display_power_well_init+0xdb/0xe8 [i915] [ 3188.091224] [] chv_pipe_power_well_enable+0x62/0x67 [i915] [ 3188.102594] [] intel_dis
Re: [Intel-gfx] [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
On Thu, Oct 08, 2015 at 05:38:58PM +0300, Jani Nikula wrote: > On Thu, 08 Oct 2015, Ville Syrjälä 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 > >> --- > >> 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: [] > > intel_display_power_get+0x38/0xcb [i915] > > [ 3187.647492] > > [ 3187.647492] but task is already holding lock: > > [ 3187.661054] (&power_domains->lock){+.+...}, at: [] > > 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: [] > > drm_release+0x3b/0x49b [drm] > > [ 3187.785216] #1: (&dev->mode_config.mutex){+.+.+.}, at: > > [] drm_modeset_lock_all+0x54/0xcd [drm] > > [ 3187.800437] #2: (crtc_ww_class_acquire){+.+.+.}, at: > > [] drm_modeset_lock_all+0x5e/0xcd [drm] > > [ 3187.815488] #3: (crtc_ww_class_mutex){+.+.+.}, at: > > [] drm_modeset_lock+0x75/0xfc [drm] > > [ 3187.830094] #4: (&power_domains->lock){+.+...}, at: > > [] 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] 880175eff8e0 8128d59e > > 823f5ee0 > > [ 3187.898904] 880175eff958 810a7a08 > > 880179d1c5d0 > > [ 3187.910954] 0004 0006 45422a91588a4c3e > > 0005 > > [ 3187.923011] Call Trace: > > [ 3187.929451] [] dump_stack+0x4e/0x79 > > [ 3187.938912] [] __lock_acquire+0x7ab/0x12af > > [ 3187.949027] [] lock_acquire+0x10e/0x1a9 > > [ 3187.958859] [] ? intel_display_power_get+0x38/0xcb > > [i915] > > [ 3187.970476] [] ? intel_display_power_get+0x38/0xcb > > [i915] > > [ 3187.982011] [] mutex_lock_nested+0x71/0x346 > > [ 3187.992167] [] ? intel_display_power_get+0x38/0xcb > > [i915] > > [ 3188.003655] [] ? _raw_spin_unlock_irqrestore+0x4b/0x60 > > [ 3188.014829] [] ? __pm_runtime_resume+0x71/0x7e > > [ 3188.025269] [] intel_display_power_get+0x38/0xcb > > [i915] > > [ 3188.036544] [] ? intel_display_power_get+0x38/0xcb > > [i915] > > [ 3188.047968] [] intel
Re: [Intel-gfx] [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
On Thu, 08 Oct 2015, Ville Syrjälä 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 >> --- >> 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: [] > intel_display_power_get+0x38/0xcb [i915] > [ 3187.647492] > [ 3187.647492] but task is already holding lock: > [ 3187.661054] (&power_domains->lock){+.+...}, at: [] > 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: [] > drm_release+0x3b/0x49b [drm] > [ 3187.785216] #1: (&dev->mode_config.mutex){+.+.+.}, at: > [] drm_modeset_lock_all+0x54/0xcd [drm] > [ 3187.800437] #2: (crtc_ww_class_acquire){+.+.+.}, at: > [] drm_modeset_lock_all+0x5e/0xcd [drm] > [ 3187.815488] #3: (crtc_ww_class_mutex){+.+.+.}, at: [] > drm_modeset_lock+0x75/0xfc [drm] > [ 3187.830094] #4: (&power_domains->lock){+.+...}, at: [] > 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] 880175eff8e0 8128d59e > 823f5ee0 > [ 3187.898904] 880175eff958 810a7a08 > 880179d1c5d0 > [ 3187.910954] 0004 0006 45422a91588a4c3e > 0005 > [ 3187.923011] Call Trace: > [ 3187.929451] [] dump_stack+0x4e/0x79 > [ 3187.938912] [] __lock_acquire+0x7ab/0x12af > [ 3187.949027] [] lock_acquire+0x10e/0x1a9 > [ 3187.958859] [] ? intel_display_power_get+0x38/0xcb > [i915] > [ 3187.970476] [] ? intel_display_power_get+0x38/0xcb > [i915] > [ 3187.982011] [] mutex_lock_nested+0x71/0x346 > [ 3187.992167] [] ? intel_display_power_get+0x38/0xcb > [i915] > [ 3188.003655] [] ? _raw_spin_unlock_irqrestore+0x4b/0x60 > [ 3188.014829] [] ? __pm_runtime_resume+0x71/0x7e > [ 3188.025269] [] intel_display_power_get+0x38/0xcb [i915] > [ 3188.036544] [] ? intel_display_power_get+0x38/0xcb > [i915] > [ 3188.047968] [] intel_hdmi_set_edid+0x3f/0xd6 [i915] > [ 3188.058766] [] intel_hdmi_hot_plug+0xbf/0xfb [i915] > [ 3188.069484] [] intel_hpd_init+0xfa/0x10b [i915] > [ 3188.079753] [] vlv_display_power_well_init+0xdb/0xe8 > [i915] > [ 3188.091224] [] chv_pipe_power_well_enable+0x62/0x67 > [i915] > [ 3188.102594] [] intel_display_
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 > --- > 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: [] intel_display_power_get+0x38/0xcb [i915] [ 3187.647492] [ 3187.647492] but task is already holding lock: [ 3187.661054] (&power_domains->lock){+.+...}, at: [] 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: [] drm_release+0x3b/0x49b [drm] [ 3187.785216] #1: (&dev->mode_config.mutex){+.+.+.}, at: [] drm_modeset_lock_all+0x54/0xcd [drm] [ 3187.800437] #2: (crtc_ww_class_acquire){+.+.+.}, at: [] drm_modeset_lock_all+0x5e/0xcd [drm] [ 3187.815488] #3: (crtc_ww_class_mutex){+.+.+.}, at: [] drm_modeset_lock+0x75/0xfc [drm] [ 3187.830094] #4: (&power_domains->lock){+.+...}, at: [] 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] 880175eff8e0 8128d59e 823f5ee0 [ 3187.898904] 880175eff958 810a7a08 880179d1c5d0 [ 3187.910954] 0004 0006 45422a91588a4c3e 0005 [ 3187.923011] Call Trace: [ 3187.929451] [] dump_stack+0x4e/0x79 [ 3187.938912] [] __lock_acquire+0x7ab/0x12af [ 3187.949027] [] lock_acquire+0x10e/0x1a9 [ 3187.958859] [] ? intel_display_power_get+0x38/0xcb [i915] [ 3187.970476] [] ? intel_display_power_get+0x38/0xcb [i915] [ 3187.982011] [] mutex_lock_nested+0x71/0x346 [ 3187.992167] [] ? intel_display_power_get+0x38/0xcb [i915] [ 3188.003655] [] ? _raw_spin_unlock_irqrestore+0x4b/0x60 [ 3188.014829] [] ? __pm_runtime_resume+0x71/0x7e [ 3188.025269] [] intel_display_power_get+0x38/0xcb [i915] [ 3188.036544] [] ? intel_display_power_get+0x38/0xcb [i915] [ 3188.047968] [] intel_hdmi_set_edid+0x3f/0xd6 [i915] [ 3188.058766] [] intel_hdmi_hot_plug+0xbf/0xfb [i915] [ 3188.069484] [] intel_hpd_init+0xfa/0x10b [i915] [ 3188.079753] [] vlv_display_power_well_init+0xdb/0xe8 [i915] [ 3188.091224] [] chv_pipe_power_well_enable+0x62/0x67 [i915] [ 3188.102594] [] intel_display_power_get+0xa0/0xcb [i915] [ 3188.113657] [] modeset_get_crtc_power_domains+0x11d/0x13c [i915] [ 3188.125589] [] intel_atomic_commit+0x228/0xf1b [i915] [ 3188.136522] [] ? drm_atomic_check_only+0x37b/0x4da [drm] [ 3188.147676] [] drm_atomic_commit+0x4d/0x52 [drm] [ 3188.158023] [] restore_fbdev_mode+0x
[Intel-gfx] [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
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 --- 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