@@ -176,6 +176,8 @@ static void intel_crt_dpms(struct drm_connector *connector, int mode)
intel_crtc_update_dpms(crtc);
}
+
+ intel_connector_check_state(to_intel_connector(connector));
}
static int intel_crt_mode_valid(struct drm_connector *connector,
@@ -3519,6 +3519,40 @@ void intel_encoder_dpms(struct intel_encoder *encoder, int mode)
}
}
+/* Cross check the actual hw state with our own modeset state tracking (and it's
+ * internal consistency). */
+void intel_connector_check_state(struct intel_connector *connector)
+{
+ if (connector->get_hw_state(connector)) {
+ struct intel_encoder *encoder = connector->encoder;
+ struct drm_crtc *crtc;
+ bool encoder_enabled;
+ enum pipe pipe;
+
+ WARN(connector->base.dpms != DRM_MODE_DPMS_ON,
+ "wrong connector dpms state\n");
+ WARN(connector->base.encoder != &encoder->base,
+ "active connector not linked to encoder\n");
+ WARN(!encoder->connectors_active,
+ "encoder->connectors_active not set\n");
+
+ encoder_enabled = encoder->get_hw_state(encoder, &pipe);
+ WARN(!encoder_enabled, "encoder not enabled\n");
+ if (WARN_ON(!encoder->base.crtc))
+ return;
+
+ crtc = encoder->base.crtc;
+
+ WARN(!crtc->enabled, "crtc not enabled\n");
+ WARN(!to_intel_crtc(crtc)->active, "crtc not active\n");
+ } else {
+ /* We still allow dpms changes on unused connectors, hence no
+ * check for dpms here. */
+ WARN_ON(!connector->base.encoder);
+ }
+
+}
+
/* Even simpler default implementation, if there's really no special case to
* consider. */
void intel_connector_dpms(struct drm_connector *connector, int mode)
@@ -3539,6 +3573,8 @@ void intel_connector_dpms(struct drm_connector *connector, int mode)
intel_encoder_dpms(encoder, mode);
else
encoder->connectors_active = false;
+
+ intel_connector_check_state(to_intel_connector(connector));
}
/* Simple connector->get_hw_state implementation for encoders that support only
@@ -1394,6 +1394,8 @@ intel_dp_dpms(struct drm_connector *connector, int mode)
intel_encoder_dpms(&intel_dp->base, mode);
WARN_ON(intel_dp->dpms_mode != DRM_MODE_DPMS_ON);
}
+
+ intel_connector_check_state(to_intel_connector(connector));
}
/*
@@ -399,6 +399,7 @@ extern void intel_encoder_destroy(struct drm_encoder *encoder);
extern void intel_encoder_dpms(struct intel_encoder *encoder, int mode);
extern void intel_connector_dpms(struct drm_connector *, int mode);
extern bool intel_connector_get_hw_state(struct intel_connector *connector);
+extern void intel_connector_check_state(struct intel_connector *);
static inline struct intel_encoder *intel_attached_encoder(struct drm_connector *connector)
{
@@ -180,6 +180,8 @@ static void intel_dvo_dpms(struct drm_connector *connector, int mode)
intel_crtc_update_dpms(crtc);
}
+
+ intel_connector_check_state(to_intel_connector(connector));
}
static int intel_dvo_mode_valid(struct drm_connector *connector,
@@ -1271,6 +1271,8 @@ static void intel_sdvo_dpms(struct drm_connector *connector, int mode)
intel_sdvo_set_encoder_power_state(intel_sdvo, mode);
intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output);
}
+
+ intel_connector_check_state(to_intel_connector(connector));
}
static int intel_sdvo_mode_valid(struct drm_connector *connector,
Atm we can only check the connector state after a dpms call - while doing modeset with the copy&pasted crtc helper code things are too ill-defined for proper checking. But the idea is very much to call this check from the modeset code, too. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> --- drivers/gpu/drm/i915/intel_crt.c | 2 + drivers/gpu/drm/i915/intel_display.c | 36 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_dp.c | 2 + drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_dvo.c | 2 + drivers/gpu/drm/i915/intel_sdvo.c | 2 + 6 files changed, 45 insertions(+), 0 deletions(-)