On Fri, Jun 07, 2013 at 01:47:41PM +0100, Chris Wilson wrote: > On random machines, the BIOS changes the hardware state of the display > when it detects a lid event. In return, we have to then do a forced > restore of the users requested configuration as soon as we handle the > lid event. Currently, this is done by calling the lowlevel CRTC > configuration functions directly with the old state. This results in > a flash on all connected displays. However, since we probe the state of > the hardware left by the BIOS, we can instead hook into the higher level > modeset code which evaluates the minimum changes required to setup the > requested state. This converts the modeset back into a no-op on sane > machines, and eliminates the screen blanking. > > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=65486 > Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk> > --- > drivers/gpu/drm/i915/intel_display.c | 26 ++++++++++++++++++++++++-- > drivers/gpu/drm/i915/intel_drv.h | 5 +++++ > 2 files changed, 29 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > index ba7e311..5b727a3b2 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -9632,11 +9632,33 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, > * checking (bogus) intermediate states. > */ > for_each_pipe(pipe) { > + struct drm_mode_set set; > + struct drm_connector *connector, *connectors[16]; > struct drm_crtc *crtc = > dev_priv->pipe_to_crtc_mapping[pipe]; > > - __intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, > - crtc->fb); > + set.crtc = crtc; > + set.x = crtc->x; > + set.y = crtc->y; > + set.mode = crtc->fb ? &crtc->mode : NULL; > + set.fb = crtc->fb; > + set.connectors = connectors; > + set.num_connectors = 0; > + > + list_for_each_entry(connector, > + &dev->mode_config.connector_list, > + head) { > + if (&intel_attached_crtc(connector)->base != crtc) > + continue; > + > + connectors[set.num_connectors++] = connector; > + if (set.num_connectors == ARRAY_SIZE(connectors)) > + break; > + } > + > + if (intel_crtc_set_config(&set)) > + __intel_set_mode(crtc, &crtc->mode, > + crtc->x, crtc->y, crtc->fb); Won't this horribly scream in the modeset state checker again if we've only partially restored the output state (in case the bios was really seriuos about killing our config)? -Daniel > } > list_for_each_entry(plane, &dev->mode_config.plane_list, head) > intel_plane_restore(plane); > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index 1f04b7f..ef3f809 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -648,6 +648,11 @@ static inline struct intel_encoder *intel_attached_encoder(struct drm_connector > return to_intel_connector(connector)->encoder; > } > > +static inline struct intel_crtc *intel_attached_crtc(struct drm_connector *connector) > +{ > + return to_intel_crtc(to_intel_connector(connector)->encoder->base.crtc); > +} > + > static inline struct intel_digital_port * > enc_to_dig_port(struct drm_encoder *encoder) > { > -- > 1.7.10.4 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch