Commit e3de42b6 authored by Imre Deak's avatar Imre Deak Committed by Daniel Vetter

drm/i915: force full modeset if the connector is in DPMS OFF mode

Currently the driver's assumed behavior for a modeset with an attached
FB is that the corresponding connector will be switched to DPMS ON mode
if it happened to be in DPMS OFF (or another power save mode). This
wasn't enforced though if only the FB changed, everything else (format,
connector etc.) remaining the same. In this case we only set the new FB
base and left the connector in the old power save mode.

Fix this by forcing a full modeset whenever there is an attached FB and
any affected connector is in a power save mode.

V_2: Run the test for encoders in power save mode outside the the
test for fb change: user space may have just disabled the encoders
but left everything else in place. Make sure the connector list is
not empty before running this test.
Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Signed-off-by: default avatarEgbert Eich <eich@suse.de>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61642
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=59834
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=59339
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=64178Acked-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
[danvet: Apply Jani's s/connector_off/is_crtc_connector_off bikeshed.]
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 2d05eae1
...@@ -8140,6 +8140,21 @@ static void intel_set_config_restore_state(struct drm_device *dev, ...@@ -8140,6 +8140,21 @@ static void intel_set_config_restore_state(struct drm_device *dev,
} }
} }
static bool
is_crtc_connector_off(struct drm_crtc *crtc, struct drm_connector *connectors,
int num_connectors)
{
int i;
for (i = 0; i < num_connectors; i++)
if (connectors[i].encoder &&
connectors[i].encoder->crtc == crtc &&
connectors[i].dpms != DRM_MODE_DPMS_ON)
return true;
return false;
}
static void static void
intel_set_config_compute_mode_changes(struct drm_mode_set *set, intel_set_config_compute_mode_changes(struct drm_mode_set *set,
struct intel_set_config *config) struct intel_set_config *config)
...@@ -8147,7 +8162,11 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set, ...@@ -8147,7 +8162,11 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set,
/* We should be able to check here if the fb has the same properties /* We should be able to check here if the fb has the same properties
* and then just flip_or_move it */ * and then just flip_or_move it */
if (set->crtc->fb != set->fb) { if (set->connectors != NULL &&
is_crtc_connector_off(set->crtc, *set->connectors,
set->num_connectors)) {
config->mode_changed = true;
} else if (set->crtc->fb != set->fb) {
/* If we have no fb then treat it as a full mode set */ /* If we have no fb then treat it as a full mode set */
if (set->crtc->fb == NULL) { if (set->crtc->fb == NULL) {
DRM_DEBUG_KMS("crtc has no fb, full mode set\n"); DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
...@@ -8157,9 +8176,10 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set, ...@@ -8157,9 +8176,10 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set,
} else if (set->fb->pixel_format != } else if (set->fb->pixel_format !=
set->crtc->fb->pixel_format) { set->crtc->fb->pixel_format) {
config->mode_changed = true; config->mode_changed = true;
} else } else {
config->fb_changed = true; config->fb_changed = true;
} }
}
if (set->fb && (set->x != set->crtc->x || set->y != set->crtc->y)) if (set->fb && (set->x != set->crtc->x || set->y != set->crtc->y))
config->fb_changed = true; config->fb_changed = true;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment