WARN_ON(!crtc->enabled);
- /* XXX: For compatability with the crtc helper code, call the encoder's
- * enable function unconditionally for now. */
if (intel_crtc->active)
- goto encoders;
+ return;
intel_crtc->active = true;
intel_update_watermarks(dev);
intel_crtc_update_cursor(crtc, true);
-encoders:
for_each_encoder_on_crtc(dev, crtc, encoder)
encoder->enable(encoder);
int plane = intel_crtc->plane;
u32 reg, temp;
- /* XXX: For compatability with the crtc helper code, call the encoder's
- * disable function unconditionally for now. */
- for_each_encoder_on_crtc(dev, crtc, encoder)
- encoder->disable(encoder);
if (!intel_crtc->active)
return;
+ for_each_encoder_on_crtc(dev, crtc, encoder)
+ encoder->disable(encoder);
+
intel_crtc_wait_for_pending_flips(crtc);
drm_vblank_off(dev, pipe);
intel_crtc_update_cursor(crtc, false);
WARN_ON(!crtc->enabled);
- /* XXX: For compatability with the crtc helper code, call the encoder's
- * enable function unconditionally for now. */
if (intel_crtc->active)
- goto encoders;
+ return;
intel_crtc->active = true;
intel_update_watermarks(dev);
intel_crtc_dpms_overlay(intel_crtc, true);
intel_crtc_update_cursor(crtc, true);
-encoders:
for_each_encoder_on_crtc(dev, crtc, encoder)
encoder->enable(encoder);
}
int pipe = intel_crtc->pipe;
int plane = intel_crtc->plane;
- /* XXX: For compatability with the crtc helper code, call the encoder's
- * disable function unconditionally for now. */
- for_each_encoder_on_crtc(dev, crtc, encoder)
- encoder->disable(encoder);
if (!intel_crtc->active)
return;
+ for_each_encoder_on_crtc(dev, crtc, encoder)
+ encoder->disable(encoder);
+
/* Give the overlay scaler a chance to disable if it's on this pipe */
intel_crtc_wait_for_pending_flips(crtc);
drm_vblank_off(dev, pipe);
return false;
}
-static void
-intel_crtc_prepare_encoders(struct drm_device *dev)
-{
- struct intel_encoder *encoder;
-
- list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) {
- /* Disable unused encoders */
- if (encoder->base.crtc == NULL)
- encoder->disable(encoder);
- }
-}
-
/**
* intel_modeset_update_staged_output_state
*
*prepare_pipes &= ~(*disable_pipes);
}
+static bool intel_crtc_in_use(struct drm_crtc *crtc)
+{
+ struct drm_encoder *encoder;
+ struct drm_device *dev = crtc->dev;
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
+ if (encoder->crtc == crtc)
+ return true;
+
+ return false;
+}
+
+static void
+intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes)
+{
+ struct intel_encoder *intel_encoder;
+ struct intel_crtc *intel_crtc;
+ struct drm_connector *connector;
+
+ list_for_each_entry(intel_encoder, &dev->mode_config.encoder_list,
+ base.head) {
+ if (!intel_encoder->base.crtc)
+ continue;
+
+ intel_crtc = to_intel_crtc(intel_encoder->base.crtc);
+
+ if (prepare_pipes & (1 << intel_crtc->pipe))
+ intel_encoder->connectors_active = false;
+ }
+
+ intel_modeset_commit_output_state(dev);
+
+ /* Update computed state. */
+ list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
+ base.head) {
+ intel_crtc->base.enabled = intel_crtc_in_use(&intel_crtc->base);
+ }
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ if (!connector->encoder || !connector->encoder->crtc)
+ continue;
+
+ intel_crtc = to_intel_crtc(connector->encoder->crtc);
+
+ if (prepare_pipes & (1 << intel_crtc->pipe)) {
+ connector->dpms = DRM_MODE_DPMS_ON;
+
+ intel_encoder = to_intel_encoder(connector->encoder);
+ intel_encoder->connectors_active = true;
+ }
+ }
+
+}
+
#define for_each_intel_crtc_masked(dev, mask, intel_crtc) \
list_for_each_entry((intel_crtc), \
&(dev)->mode_config.crtc_list, \
for_each_intel_crtc_masked(dev, disable_pipes, intel_crtc)
intel_crtc_disable(&intel_crtc->base);
- intel_modeset_commit_output_state(dev);
-
- list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
- base.head)
- intel_crtc->base.enabled = drm_helper_crtc_in_use(crtc);
-
saved_hwmode = crtc->hwmode;
saved_mode = crtc->mode;
if (IS_ERR(adjusted_mode)) {
return false;
}
-
- intel_crtc_prepare_encoders(dev);
}
- for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc)
- dev_priv->display.crtc_disable(&intel_crtc->base);
+ for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc) {
+ if (intel_crtc->base.enabled)
+ dev_priv->display.crtc_disable(&intel_crtc->base);
+ }
if (modeset_pipes) {
crtc->mode = *mode;
crtc->y = y;
}
+ /* Only after disabling all output pipelines that will be changed can we
+ * update the the output configuration. */
+ intel_modeset_update_state(dev, prepare_pipes);
+
/* Set up the DPLL and any encoders state that needs to adjust or depend
* on the DPLL.
*/