On Fri, Jul 19, 2013 at 12:57 PM, Daniel Vetter <daniel.vetter at ffwll.ch> wrote: > Atm the crtc helper implementation of set_config has really > inconsisten semantics: If just an fb update is good enough, dpms state > will be left as-is, but if we do a full modeset we force everything to > dpms on. > > This change has already been applied to the i915 modeset code in > > commit e3de42b68478a8c95dd27520e9adead2af9477a5 > Author: Imre Deak <imre.deak at intel.com> > Date: Fri May 3 19:44:07 2013 +0200 > > drm/i915: force full modeset if the connector is in DPMS OFF mode > > which according to Greg KH seems to aim for a new record in most > Bugzilla: links in a commit message. > > The history of this dpms forcing is pretty interesting. This patch > here is an almost-revert of > > commit 811aaa55ba21ab37407018cfc01770d6b037d3fb > Author: Keith Packard <keithp at keithp.com> > Date: Thu Feb 3 16:57:28 2011 -0800 > > drm: Only set DPMS ON when actually configuring a mode > > which fixed the bug of trying to dpms on disabled outputs, but > introduced the new discrepancy between an fb update only and full > modesets. The actual introduction of this goes back to > > commit bf9dc102e284a5aa78c73fc9d72e11d5ccd8669f > Author: Keith Packard <keithp at keithp.com> > Date: Fri Nov 26 10:45:58 2010 -0800 > > drm: Set connector DPMS status to ON in drm_crtc_helper_set_config > > And if you'd dig around in the i915 driver code there's even more fun > around forcing dpms on and losing our heads and temper of the > resulting inconsistencies. Especially the DP re-training code had tons > of funny stuff in it. > > v2: So v1 totally blew up on resume on my radeon system here. After > much head-scraching I've figured out that the radeon resume functions > resumes the console system _before_ it actually restores all the > modeset state. And resuming the console systems means that fbdev doeas > an immediate ->set_par call. > > Now up to this patch that ->set_par did absolutely nothing: All the > old sw state from pre-suspend was still around (since the modeset > reset wasn't done yet), which means that the set_config calls done as > a result of the ->set_par where all treated as no-ops (despite that > the real hw state was obviously something completely different). > > Since v1 of this patch just added a bunch of ->dpms calls if the crtc > was enabled, those set_config calls suddenly stopped being no-ops. But > because the hw state wasn't restored the ->dpms callbacks resulted in > decent amounts of hilarity and eventual full hangs. > > Since I can't review all kms drivers for such tricky ordering > constraints v2 opts for a different approach and forces a full modeset > if the connector dpms state isnt' DPMS_ON. Since the ->dpms callbacks > implemented by the modeset helpers update the connector->dpms property > we have the same effect of ensuring that the pipe is ultimately turned > on, even if we just end up updating the fb. This is the same approac > we ended up using in the intel driver. > > Note that besides i915.ko only all other drivers eventually call > drm_helper_connector_dpms with the exception of vmwgfx, which does not > support dmps at all. > > v3: Dave Airlie merged the broken first version of this patch, so > squash in the revert of > > commit 372835a8527f85b3eff20a18c2c339e827dfd4e4 > Author: Daniel Vetter <daniel.vetter at ffwll.ch> > Date: Sat Jun 15 00:13:13 2013 +0200 > > drm/crtc-helper: explicit DPMS on after modeset > > Also fix up the spelling fail a bit in the commit message while at it. > > Cc: Dave Airlie <airlied at redhat.com> > Cc: Alex Deucher <alexdeucher at gmail.com> > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67043 > Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
Reviewed-by: Alex Deucher <alexander.deucher at amd.com> Confirmed to fix bug 67043. > --- > drivers/gpu/drm/drm_crtc_helper.c | 27 +++++++++++---------------- > 1 file changed, 11 insertions(+), 16 deletions(-) > > diff --git a/drivers/gpu/drm/drm_crtc_helper.c > b/drivers/gpu/drm/drm_crtc_helper.c > index edb0de5..eb51dc4 100644 > --- a/drivers/gpu/drm/drm_crtc_helper.c > +++ b/drivers/gpu/drm/drm_crtc_helper.c > @@ -669,6 +669,11 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) > /* don't break so fail path works > correct */ > fail = 1; > break; > + > + if (connector->dpms != DRM_MODE_DPMS_ON) { > + DRM_DEBUG_KMS("connector dpms not on, > full mode switch\n"); > + mode_changed = true; > + } > } > } > > @@ -746,6 +751,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) > ret = -EINVAL; > goto fail; > } > + DRM_DEBUG_KMS("Setting connector DPMS state to on\n"); > + for (i = 0; i < set->num_connectors; i++) { > + DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS > on\n", set->connectors[i]->base.id, > + > drm_get_connector_name(set->connectors[i])); > + > set->connectors[i]->funcs->dpms(set->connectors[i], DRM_MODE_DPMS_ON); > + } > } > drm_helper_disable_unused_functions(dev); > } else if (fb_changed) { > @@ -763,22 +774,6 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) > } > } > > - /* > - * crtc set_config helpers implicit set the crtc and all connected > - * encoders to DPMS on for a full mode set. But for just an fb update > it > - * doesn't do that. To not confuse userspace, do an explicit DPMS_ON > - * unconditionally. This will also ensure driver internal dpms state > is > - * consistent again. > - */ > - if (set->crtc->enabled) { > - DRM_DEBUG_KMS("Setting connector DPMS state to on\n"); > - for (i = 0; i < set->num_connectors; i++) { > - DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", > set->connectors[i]->base.id, > - > drm_get_connector_name(set->connectors[i])); > - set->connectors[i]->funcs->dpms(set->connectors[i], > DRM_MODE_DPMS_ON); > - } > - } > - > kfree(save_connectors); > kfree(save_encoders); > kfree(save_crtcs); > -- > 1.8.3.2 >