Skip to content

Commit

Permalink
drm/i915: check connector hw/sw state
Browse files Browse the repository at this point in the history
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).

Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
  • Loading branch information
Daniel Vetter committed Sep 6, 2012
1 parent 2492935 commit 0a91ca2
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 0 deletions.
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/intel_crt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
37 changes: 37 additions & 0 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/intel_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

/*
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/intel_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/intel_dvo.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/intel_sdvo.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 0a91ca2

Please sign in to comment.