On Thu, Nov 29, 2018 at 10:18:40PM +0200, Souza, Jose wrote: > On Thu, 2018-11-29 at 15:52 +0200, Imre Deak wrote: > > On Wed, Nov 28, 2018 at 11:54:21PM +0200, Souza, Jose wrote: > > > On Wed, 2018-11-28 at 13:34 +0200, Imre Deak wrote: > > > > On Wed, Nov 07, 2018 at 04:05:52PM -0800, José Roberto de Souza > > > > wrote: > > > > > When suspending or unloading the driver, it needs to release > > > > > the > > > > > TC ports so HW can change it state without wait for driver > > > > > handshake. > > > > > > > > According to > > > > https://bugs.freedesktop.org/show_bug.cgi?id=108070#c26 > > > > > > > > this patch should fix the bug reported at > > > > https://bugs.freedesktop.org/show_bug.cgi?id=108070#c17 > > > > > > > > but, I can't see how the change here would fix the corresponding > > > > problem > > > > described in > > > > https://bugs.freedesktop.org/show_bug.cgi?id=108070#c18 > > > > > > > > Would you explain? > > > > > > > > I think there are more fundamental problems in TypeC HPD handling > > > > as > > > > we > > > > discussed earlier here on the list, which should be fixed first: > > > > > > > > - Switching to/from type C mode from the interrupt handler > > > > without > > > > considering if we have an active mode or an ongoing AUX > > > > transfer. > > > > > > Yes that is still missing, I plan to work on that after I deliver a > > > few > > > tasks. Also I read the emails in discussion that you started about > > > that. > > > > The point is that imo those fundamental problems should be fixed > > first. > > > > > > - Not having any way for handling the case where we'd do a > > > > modeset > > > > after > > > > an HPD disconnect interrupt, like in the case of > > > > common-hpd-after-suspend in the bug report. > > > > > > For what I understood about this test it will suspend, disconnect > > > chamelium board from source, wakeup and check if connector state > > > match, > > > as we did not marked port as safe before suspending we are left in > > > a > > > invalid state where PD firmware do not trigger a interruption after > > > wakeup. > > > > No, it's not about the lack of HPD interrupts. What happens is that > > the > > sink disappears during system suspend/resume, but we still have an > > active mode enabled on the corresponding port. We try to restore this > > mode during resume but that modeset will fail. > > Before suspend, all display output is disabled so there is no active > modeset. Yes, there is: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_5129/fi-icl-u2/dmesg0.log : <7>[ 204.806237] [drm:intel_atomic_check [i915]] [CONNECTOR:209:HDMI-A-2] Limiting display bpp to 24 instead of EDID bpp 24, requested bpp 36, max platform bpp 36 ... <7>[ 204.806411] [drm:intel_dump_pipe_config [i915]] [CRTC:80:pipe A][modeset] ... <7>[ 204.809132] [drm:intel_enable_pipe [i915]] enabling pipe A ... <7>[ 204.909519] [IGT] kms_chamelium: executing ... <7>[ 204.947440] [IGT] kms_chamelium: starting subtest common-hpd-after-suspend ... <6>[ 205.936472] PM: suspend entry (deep) After which we will try to restore this active mode during resume. > > > > > > > More comments below: > > > > > > > > > Cc: Imre Deak <imre.deak@xxxxxxxxx> > > > > > Cc: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> > > > > > Signed-off-by: José Roberto de Souza <jose.souza@xxxxxxxxx> > > > > > --- > > > > > drivers/gpu/drm/i915/i915_drv.c | 1 + > > > > > drivers/gpu/drm/i915/i915_drv.h | 1 + > > > > > drivers/gpu/drm/i915/i915_irq.c | 1 + > > > > > drivers/gpu/drm/i915/intel_dp.c | 19 +++++++++++++++++++ > > > > > drivers/gpu/drm/i915/intel_drv.h | 1 + > > > > > drivers/gpu/drm/i915/intel_hotplug.c | 9 +++++++++ > > > > > 6 files changed, 32 insertions(+) > > > > > > > > > > diff --git a/drivers/gpu/drm/i915/i915_drv.c > > > > > b/drivers/gpu/drm/i915/i915_drv.c > > > > > index acb516308262..14331c396278 100644 > > > > > --- a/drivers/gpu/drm/i915/i915_drv.c > > > > > +++ b/drivers/gpu/drm/i915/i915_drv.c > > > > > @@ -1911,6 +1911,7 @@ static int i915_drm_suspend(struct > > > > > drm_device > > > > > *dev) > > > > > > > > > > intel_runtime_pm_disable_interrupts(dev_priv); > > > > > intel_hpd_cancel_work(dev_priv); > > > > > + intel_hpd_suspend(dev_priv); > > > > > > > > What about runtime suspend? We won't receive HPD interrupts after > > > > that > > > > either, so we'd need to disconnect in that case too according to > > > > the > > > > spec. > > > > > > Oh my bad I was thinking that the regular suspend would handle this > > > too > > > but I was wrong. > > > > > > So I will add a intel_hpd_suspend() call to intel_runtime_suspend() > > > leaving the i915_drv.c changes as this. > > > > > > diff --git a/drivers/gpu/drm/i915/i915_drv.c > > > b/drivers/gpu/drm/i915/i915_drv.c > > > index b1d23c73c147..948914a79c67 100644 > > > --- a/drivers/gpu/drm/i915/i915_drv.c > > > +++ b/drivers/gpu/drm/i915/i915_drv.c > > > @@ -1905,6 +1905,7 @@ static int i915_drm_suspend(struct drm_device > > > *dev) > > > > > > intel_runtime_pm_disable_interrupts(dev_priv); > > > intel_hpd_cancel_work(dev_priv); > > > + intel_hpd_suspend(dev_priv); > > > > > > intel_suspend_encoders(dev_priv); > > > > > > @@ -2909,6 +2910,7 @@ static int intel_runtime_suspend(struct > > > device > > > *kdev) > > > intel_uc_suspend(dev_priv); > > > > > > intel_runtime_pm_disable_interrupts(dev_priv); > > > + intel_hpd_suspend(dev_priv); > > > > > > intel_uncore_suspend(dev_priv); > > > > > > Also I will drop the next patch as we don't call > > > intel_hpd_cancel_work() in intel_runtime_suspend() path. > > > > > > > > > > And how are we handling resume then where we'll be in a > > > > disconnected > > > > state due to the change in this patch and would continue to do a > > > > modeset (to restore the mode we had before suspend). > > > > > > The drm_kms_helper_poll_enable() calls will trigger the call to the > > > detection function of the connectors that will call > > > intel_digital_port_connected() thal will call ICL TC functions that > > > will take care of update everything. > > > > No detection will be triggered, since we're not polling this port > > (and > > polling can be disabled as a whole). In any case that would be too > > late, > > since we're trying to restore the mode before we call > > drm_kms_helper_poll_enable(). Also doing a detection is not enough > > here, since if detection fails (as it would in our case) we still > > have a > > mode that we need to restore. The corresponding modeset would fail, > > but > > we don't have a way to fail it gracefully as I wrote above. > > > For the regular suspend it will run the connector detection functions > for sure when trying to restore the previous modeset. Not sure what you mean. >From drm_kms_helper_poll_enable(): if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll) return; so we won't do anything in this function if polling is globally disabled. if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT)) poll = true; so we won't do anything if we haven't enabled polling for the connector. Generally we don't enable polling for connectors which provide HPD interrupts. There is actually a detection work scheduled from intel_hpd_init(), but again that will run only after we tried to restore the pre-suspend mode. Also note what I wrote about detection being not enough for us. The sink can be gone by the time we resume and we will still try to restore the mode. > About the runtime resume I need to check if with the polling disabled > it will still update the connector state. > > > > > > > > > > > > > > intel_suspend_encoders(dev_priv); > > > > > > > > > > diff --git a/drivers/gpu/drm/i915/i915_drv.h > > > > > b/drivers/gpu/drm/i915/i915_drv.h > > > > > index 0c8438de3c1b..96d5ddc36f4e 100644 > > > > > --- a/drivers/gpu/drm/i915/i915_drv.h > > > > > +++ b/drivers/gpu/drm/i915/i915_drv.h > > > > > @@ -2792,6 +2792,7 @@ enum hpd_pin intel_hpd_pin_default(struct > > > > > drm_i915_private *dev_priv, > > > > > enum port port); > > > > > bool intel_hpd_disable(struct drm_i915_private *dev_priv, enum > > > > > hpd_pin pin); > > > > > void intel_hpd_enable(struct drm_i915_private *dev_priv, enum > > > > > hpd_pin pin); > > > > > +void intel_hpd_suspend(struct drm_i915_private *dev_priv); > > > > > > > > > > /* i915_irq.c */ > > > > > static inline void i915_queue_hangcheck(struct > > > > > drm_i915_private > > > > > *dev_priv) > > > > > diff --git a/drivers/gpu/drm/i915/i915_irq.c > > > > > b/drivers/gpu/drm/i915/i915_irq.c > > > > > index d7e47d6082de..23084d227e2a 100644 > > > > > --- a/drivers/gpu/drm/i915/i915_irq.c > > > > > +++ b/drivers/gpu/drm/i915/i915_irq.c > > > > > @@ -4996,6 +4996,7 @@ void intel_irq_uninstall(struct > > > > > drm_i915_private *dev_priv) > > > > > { > > > > > drm_irq_uninstall(&dev_priv->drm); > > > > > intel_hpd_cancel_work(dev_priv); > > > > > + intel_hpd_suspend(dev_priv); > > > > > dev_priv->runtime_pm.irqs_enabled = false; > > > > > } > > > > > > > > > > diff --git a/drivers/gpu/drm/i915/intel_dp.c > > > > > b/drivers/gpu/drm/i915/intel_dp.c > > > > > index 5258c9d654f4..27c6163426d6 100644 > > > > > --- a/drivers/gpu/drm/i915/intel_dp.c > > > > > +++ b/drivers/gpu/drm/i915/intel_dp.c > > > > > @@ -5043,6 +5043,25 @@ bool intel_digital_port_connected(struct > > > > > intel_encoder *encoder) > > > > > return false; > > > > > } > > > > > > > > > > +/* > > > > > + * intel_digital_port_force_disconnection - Used to force port > > > > > disconnection or > > > > > + * release any control from display driver before going to a > > > > > state > > > > > that driver > > > > > + * will not handle interruptions. > > > > > + */ > > > > > +void intel_digital_port_force_disconnection(struct > > > > > intel_encoder > > > > > *encoder) > > > > > +{ > > > > > + struct drm_i915_private *dev_priv = to_i915(encoder- > > > > > >base.dev); > > > > > + struct intel_digital_port *dig_port; > > > > > + > > > > > + dig_port = enc_to_dig_port(&encoder->base); > > > > > + /* Skip fake MST ports */ > > > > > + if (!dig_port) > > > > > + return; > > > > > + > > > > > + if (INTEL_GEN(dev_priv) >= 11) > > > > > + icl_tc_phy_disconnect(dev_priv, dig_port); > > > > > +} > > > > > + > > > > > static struct edid * > > > > > intel_dp_get_edid(struct intel_dp *intel_dp) > > > > > { > > > > > diff --git a/drivers/gpu/drm/i915/intel_drv.h > > > > > b/drivers/gpu/drm/i915/intel_drv.h > > > > > index 6772e9974751..bc30f107b430 100644 > > > > > --- a/drivers/gpu/drm/i915/intel_drv.h > > > > > +++ b/drivers/gpu/drm/i915/intel_drv.h > > > > > @@ -1851,6 +1851,7 @@ bool intel_dp_read_dpcd(struct intel_dp > > > > > *intel_dp); > > > > > int intel_dp_link_required(int pixel_clock, int bpp); > > > > > int intel_dp_max_data_rate(int max_link_clock, int max_lanes); > > > > > bool intel_digital_port_connected(struct intel_encoder > > > > > *encoder); > > > > > +void intel_digital_port_force_disconnection(struct > > > > > intel_encoder > > > > > *encoder); > > > > > > > > > > /* intel_dp_aux_backlight.c */ > > > > > int intel_dp_aux_init_backlight_funcs(struct intel_connector > > > > > *intel_connector); > > > > > diff --git a/drivers/gpu/drm/i915/intel_hotplug.c > > > > > b/drivers/gpu/drm/i915/intel_hotplug.c > > > > > index 42e61e10f517..d6745b7b79d5 100644 > > > > > --- a/drivers/gpu/drm/i915/intel_hotplug.c > > > > > +++ b/drivers/gpu/drm/i915/intel_hotplug.c > > > > > @@ -655,3 +655,12 @@ void intel_hpd_enable(struct > > > > > drm_i915_private > > > > > *dev_priv, enum hpd_pin pin) > > > > > dev_priv->hotplug.stats[pin].state = HPD_ENABLED; > > > > > spin_unlock_irq(&dev_priv->irq_lock); > > > > > } > > > > > + > > > > > +void intel_hpd_suspend(struct drm_i915_private *dev_priv) > > > > > +{ > > > > > + struct drm_device *dev = &dev_priv->drm; > > > > > + struct intel_encoder *encoder; > > > > > + > > > > > + for_each_intel_encoder(dev, encoder) > > > > > + intel_digital_port_force_disconnection(encoder) > > > > > ; > > > > > +} > > > > > -- > > > > > 2.19.1 > > > > > > > > > _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx