aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/intel_dvo.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-07-01 22:42:24 +0200
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-09-06 07:55:17 +0200
commitb2cabb0e1d205708dab11bd9e1b97fd080537096 (patch)
treea09f01d1a9eddfe63366e8bd34f4bdc625cca702 /drivers/gpu/drm/i915/intel_dvo.c
parent19c63fa8070b09f409f64c5b3bcd0444e6e67b3b (diff)
drm/i915: convert dpms functions of dvo/sdvo/crt
Yeah, big patch but I couldn't come up with a neat idea of how to split it up further, that wouldn't break dpms on cloned configs somehow. But the changes in dvo/sdvo/crt are all pretty much orthonogal, so it's not too bad a patch. These are the only encoders that support cloning, which requires a few special changes compared to the previous patches. - Compute the desired state of the display pipe by walking all connected encoders and checking whether any has active connectors. To make this clearer, drop the old mode parameter to the crtc dpms function and rename it to intel_crtc_update_dpms. - There's the curious case of intel_crtc->dpms_mode. With the previous patches to remove the overlay pipe A code and to rework the load detect pipe code, the big users are gone. We still keep it to avoid enabling the pipe twice, but we duplicate this logic with crtc->active, too. Still, leave this for now and just push a fake dpms mode into it that reflects the state of the display pipe. Changes in the encoder dpms functions: - We clamp the dpms state to the supported range right away. This is escpecially important for the VGA outputs, where only older hw supports the intermediate states. This (and the crt->adpa_reg patch) allows us to unify the crt dpms code again between all variants (gmch, vlv and pch). - We only enable/disable the output for dvo/sdvo and leave the encoder running. The encoder will be disabled/enabled when we switch the state of the entire output pipeline (which will happen right away for non-cloned setups). This way the duplication is reduced and strange interaction when disabling output ports at the wrong time avoided. The dpms code for all three types of connectors contains a bit of duplicated logic, but I think keeping these special cases separate is simpler: CRT is the only one that hanldes intermediate dpms state (which requires extra logic to enable/disable things in the right order), and introducing some abstraction just to share the code between dvo and sdvo smells like overkill. We can do that once someone bothers to implement cloning for the more modern outputs. But I doubt that this will ever happen. v2: s/crtc/crt/_set_dpms, noticed by Paulo Zanoni. Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dvo.c')
-rw-r--r--drivers/gpu/drm/i915/intel_dvo.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index 4ad988fb868..c55a13ea7ae 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -129,21 +129,39 @@ static void intel_enable_dvo(struct intel_encoder *encoder)
intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true);
}
-static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)
+static void intel_dvo_dpms(struct drm_connector *connector, int mode)
{
- struct drm_i915_private *dev_priv = encoder->dev->dev_private;
- struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
- u32 dvo_reg = intel_dvo->dev.dvo_reg;
- u32 temp = I915_READ(dvo_reg);
+ struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
+ struct drm_crtc *crtc;
+
+ /* dvo supports only 2 dpms states. */
+ if (mode != DRM_MODE_DPMS_ON)
+ mode = DRM_MODE_DPMS_OFF;
+
+ if (mode == connector->dpms)
+ return;
+
+ connector->dpms = mode;
+
+ /* Only need to change hw state when actually enabled */
+ crtc = intel_dvo->base.base.crtc;
+ if (!crtc) {
+ intel_dvo->base.connectors_active = false;
+ return;
+ }
if (mode == DRM_MODE_DPMS_ON) {
- I915_WRITE(dvo_reg, temp | DVO_ENABLE);
- I915_READ(dvo_reg);
+ intel_dvo->base.connectors_active = true;
+
+ intel_crtc_update_dpms(crtc);
+
intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true);
} else {
intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, false);
- I915_WRITE(dvo_reg, temp & ~DVO_ENABLE);
- I915_READ(dvo_reg);
+
+ intel_dvo->base.connectors_active = false;
+
+ intel_crtc_update_dpms(crtc);
}
}
@@ -299,7 +317,6 @@ static void intel_dvo_destroy(struct drm_connector *connector)
}
static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = {
- .dpms = intel_dvo_dpms,
.mode_fixup = intel_dvo_mode_fixup,
.prepare = intel_encoder_noop,
.mode_set = intel_dvo_mode_set,
@@ -308,7 +325,7 @@ static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = {
};
static const struct drm_connector_funcs intel_dvo_connector_funcs = {
- .dpms = drm_helper_connector_dpms,
+ .dpms = intel_dvo_dpms,
.detect = intel_dvo_detect,
.destroy = intel_dvo_destroy,
.fill_modes = drm_helper_probe_single_connector_modes,