diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-10-13 12:47:20 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-10-13 12:47:20 +0100 |
commit | 951f969fa63defbe7cfa52ca97c8985b157bbed0 (patch) | |
tree | 27f318c1b87cb73454162e5c61544c2935e2d53c | |
parent | 8e7d6ddb9b485045b4662af83e048b06aab358aa (diff) |
sna: Update DPMS on attached outputs before disabling the CRTC
We may want to take action such as preserving the current user value of
the backlight before disabling it whilst forcing a CRTC off. This
requires us to record that value first.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna_display.c | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index 547ebd8e..48178980 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -760,6 +760,9 @@ sna_crtc_force_outputs_on(xf86CrtcPtr crtc) xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); int i; + DBG(("%s(pipe=%d), currently? %d\n", __FUNCTION__, + to_sna_crtc(crtc)->pipe, to_sna_crtc(crtc)->dpms_mode)); + /* DPMS handling by the kernel is inconsistent, so after setting a * mode on an output presume that we intend for it to be on, or that * the kernel will force it on. @@ -782,6 +785,34 @@ sna_crtc_force_outputs_on(xf86CrtcPtr crtc) #endif } +static void +sna_crtc_force_outputs_off(xf86CrtcPtr crtc) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); + int i; + + DBG(("%s(pipe=%d), currently? %d\n", __FUNCTION__, + to_sna_crtc(crtc)->pipe, to_sna_crtc(crtc)->dpms_mode)); + + /* DPMS handling by the kernel is inconsistent, so after setting a + * mode on an output presume that we intend for it to be on, or that + * the kernel will force it on. + * + * So force DPMS to be on for all connected outputs, and restore + * the backlight. + */ + for (i = 0; i < config->num_output; i++) { + xf86OutputPtr output = config->output[i]; + + if (output->crtc != crtc) + continue; + + output->funcs->dpms(output, DPMSModeOff); + } + + to_sna_crtc(crtc)->dpms_mode = DPMSModeOff; +} + static bool sna_crtc_apply(xf86CrtcPtr crtc) { @@ -934,7 +965,10 @@ sna_crtc_disable(xf86CrtcPtr crtc) if (sna_crtc == NULL) return; - DBG(("%s: disabling crtc [%d]\n", __FUNCTION__, sna_crtc->id)); + DBG(("%s: disabling crtc [%d, pipe=%d]\n", __FUNCTION__, + sna_crtc->id, sna_crtc->pipe)); + + sna_crtc_force_outputs_off(crtc); memset(&arg, 0, sizeof(arg)); arg.crtc_id = sna_crtc->id; @@ -946,15 +980,6 @@ sna_crtc_disable(xf86CrtcPtr crtc) kgem_bo_destroy(&sna->kgem, sna_crtc->bo); sna_crtc->bo = NULL; } - - for (i = 0; i < config->num_output; i++) { - xf86OutputPtr output = config->output[i]; - - if (output->crtc == crtc) - to_sna_output(output)->dpms_mode = DPMSModeOff; - } - - sna_crtc->dpms_mode = DPMSModeOff; } static void update_flush_interval(struct sna *sna) @@ -2176,11 +2201,14 @@ sna_output_dpms(xf86OutputPtr output, int dpms) struct sna *sna = to_sna(output->scrn); struct sna_output *sna_output = output->driver_private; + DBG(("%s(%s): dpms=%d (current: %d), active? %d\n", + __FUNCTION__, output->name, + dpms, sna_output->dpms_mode, + output->crtc != NULL)); + if (sna_output->dpms_mode == dpms) return; - DBG(("%s(%s): dpms=%d\n", __FUNCTION__, output->name, dpms)); - /* Record the value of the backlight before turning * off the display, and reset if after turning it on. * Order is important as the kernel may record and also @@ -2363,6 +2391,8 @@ sna_output_set_property(xf86OutputPtr output, Atom property, } val = *(INT32 *)value->data; + DBG(("%s: setting backlight to %d (max=%d)\n", + ___FUNCTION__, val, sna_output->backlight_max)); if (val < 0 || val > sna_output->backlight_max) return FALSE; |