All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Wilson <chris@chris-wilson.co.uk>
To: dri-devel@lists.freedesktop.org
Cc: Takashi Iwai <tiwai@suse.de>
Subject: [PATCH] drm: Recover DPMS properly after XRandr re-enablement
Date: Wed, 22 Dec 2010 12:42:32 +0000	[thread overview]
Message-ID: <1293021752-7604-1-git-send-email-chris@chris-wilson.co.uk> (raw)

From: Takashi Iwai <tiwai@suse.de>

When the output is turned off via "xrandr --off" and re-enabled again
with the same mode, drm doesn't reset DPMS, thus it results in a black
screen.  A typical example is something like:

     % xrandr --output LVDS1 --mode 1024x768
     % xrandr --output VGA1 --mode 1024x768
     % xrandr --output LVDS1 --off
     % xrandr --output LVDS1 --mode 1024x768

Also, there is another problem with DPMS: the sysfs entries don't
match with the actual state.  In the case above, LVDS1 shows always
Off, while VGA1 shows On.

A part of the cause is that there are (still) two places to keep
the actual DPMS values.  In dpms field of drm_connector and in the
device property.  Thus we need to sync between them.

Another problem is that the DPMS state is always set to ON forcibly
in drm_crtc_helper_set_config() (via commit
bf9dc102e284a5aa78c73fc9d72e11d5ccd8669f).  This results in another
inconsistency.  For recovering the DPMS, we need to set DPMS actaully
ON there.

This patch adds a new helper function to manage the drm_connector
DPMS so that it can be called commonly in both places.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 drivers/gpu/drm/drm_crtc.c        |   25 ++++++++++++++++++-------
 drivers/gpu/drm/drm_crtc_helper.c |    7 ++++---
 include/drm/drm_crtc.h            |    1 +
 3 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 2baa670..3a58337 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2383,6 +2383,18 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
 
+int drm_connector_set_dpms(struct drm_connector *connector, int mode)
+{
+	if (connector->funcs->dpms)
+		(*connector->funcs->dpms)(connector, mode);
+	connector->dpms = mode;
+	drm_connector_property_set_value(connector,
+					 connector->dev->mode_config.dpms_property,
+					 mode);
+	return 0;
+}
+EXPORT_SYMBOL(drm_connector_set_dpms);
+
 int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
 				       void *data, struct drm_file *file_priv)
 {
@@ -2440,15 +2452,14 @@ int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
 
 	/* Do DPMS ourselves */
 	if (property == connector->dev->mode_config.dpms_property) {
-		if (connector->funcs->dpms)
-			(*connector->funcs->dpms)(connector, (int) out_resp->value);
+		drm_connector_set_dpms(connector, (int) out_resp->value);
 		ret = 0;
-	} else if (connector->funcs->set_property)
+	} else if (connector->funcs->set_property) {
 		ret = connector->funcs->set_property(connector, property, out_resp->value);
-
-	/* store the property value if successful */
-	if (!ret)
-		drm_connector_property_set_value(connector, property, out_resp->value);
+		/* store the property value if successful */
+		if (!ret)
+			drm_connector_property_set_value(connector, property, out_resp->value);
+	}
 out:
 	mutex_unlock(&dev->mode_config.mutex);
 	return ret;
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index bede10a..fee755d 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -669,9 +669,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 	}
 	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]->dpms = DRM_MODE_DPMS_ON;
+		struct drm_connector *connector = set->connectors[i];
+		DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", connector->base.id,
+			      drm_get_connector_name(connector));
+		drm_connector_set_dpms(connector, DRM_MODE_DPMS_ON);
 	}
 
 	kfree(save_connectors);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 029aa68..c9a5a80 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -676,6 +676,7 @@ extern void drm_mode_set_crtcinfo(struct drm_display_mode *p,
 extern void drm_mode_connector_list_update(struct drm_connector *connector);
 extern int drm_mode_connector_update_edid_property(struct drm_connector *connector,
 						struct edid *edid);
+extern int drm_connector_set_dpms(struct drm_connector *connector, int mode);
 extern int drm_connector_property_set_value(struct drm_connector *connector,
 					 struct drm_property *property,
 					 uint64_t value);
-- 
1.7.3.1

             reply	other threads:[~2010-12-22 12:42 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-12-22 12:42 Chris Wilson [this message]
2010-12-22 12:53 ` [PATCH] drm: Recover DPMS properly after XRandr re-enablement Chris Wilson
2011-04-17 16:26   ` Florian Mickler
2011-04-18  9:06     ` Takashi Iwai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1293021752-7604-1-git-send-email-chris@chris-wilson.co.uk \
    --to=chris@chris-wilson.co.uk \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=tiwai@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.