diff mbox

[31/58] drm/i915: check connector hw/sw state

Message ID 1345403595-9678-32-git-send-email-daniel.vetter@ffwll.ch (mailing list archive)
State Accepted
Headers show

Commit Message

Daniel Vetter Aug. 19, 2012, 7:12 p.m. UTC
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.

v2: Fix dpms check and don't presume that if the hw isn't on that it
must not be linked up with an encoder (it could simply be switched off
with the dpms state).

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/intel_crt.c     |  2 ++
 drivers/gpu/drm/i915/intel_display.c | 37 ++++++++++++++++++++++++++++++++++++
 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, 46 insertions(+)

Comments

Jesse Barnes Sept. 5, 2012, 4:26 p.m. UTC | #1
On Sun, 19 Aug 2012 21:12:48 +0200
Daniel Vetter <daniel.vetter@ffwll.ch> wrote:

> 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.
> 
> v2: Fix dpms check and don't presume that if the hw isn't on that it
> must not be linked up with an encoder (it could simply be switched off
> with the dpms state).

Nice.  Only comment is that we may want to call it assert_state() to
match our other assertions.  But no biggie.

Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Daniel Vetter Sept. 5, 2012, 7:10 p.m. UTC | #2
On Wed, Sep 5, 2012 at 6:26 PM, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> On Sun, 19 Aug 2012 21:12:48 +0200
> Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
>
>> 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.
>>
>> v2: Fix dpms check and don't presume that if the hw isn't on that it
>> must not be linked up with an encoder (it could simply be switched off
>> with the dpms state).
>
> Nice.  Only comment is that we may want to call it assert_state() to
> match our other assertions.  But no biggie.

All the other assertions (mostly) check whether we get the modeset
_sequence_ right, i.e. whether A is in the right state once we get
around to frob B. This stuff here mostly checks whether our own state
tracking somewhat resembles the actual hw state after the entire dance
is completed. This is especially important to give the fastboot stuff
better coverage: We use the same functions to read the intial modeset
state from the as we use to check the modeset state after any state
changes.

So I think the concepts are sufficiently different to get away with
different names ;-)
-Daniel
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index fab54ed..2855eb7 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -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,
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index c258bbc..6d74e6f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3562,6 +3562,41 @@  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;
+
+		DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+			      connector->base.base.id,
+			      drm_get_connector_name(&connector->base));
+
+		WARN(connector->base.dpms == DRM_MODE_DPMS_OFF,
+		     "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");
+		WARN(pipe != to_intel_crtc(crtc)->pipe,
+		     "encoder active on the wrong pipe\n");
+	}
+}
+
 /* Even simpler default implementation, if there's really no special case to
  * consider. */
 void intel_connector_dpms(struct drm_connector *connector, int mode)
@@ -3582,6 +3617,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
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index e3928b9..96fd1e7 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1367,6 +1367,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));
 }
 
 /*
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 4daa7e6..e2116d9 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -434,6 +434,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)
 {
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index e9397b7..17dc8be 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -188,6 +188,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,
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 4a735a5..198bb89 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1274,6 +1274,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,