/* * Algorithm gets a little messy: * * - if the connector already has an assigned crtc, use it (but make * sure it's on first) * * - try to find the first unused crtc that can drive this connector, * and use that if we find one
*/
/* See if we already have a CRTC for this connector */ if (connector->state->crtc) {
crtc = to_intel_crtc(connector->state->crtc);
ret = drm_modeset_lock(&crtc->base.mutex, ctx); if (ret) goto fail;
/* Make sure the crtc and connector are running */ goto found;
}
/* Find an unused one (if possible) */
for_each_intel_crtc(display->drm, possible_crtc) { if (!(encoder->base.possible_crtcs &
drm_crtc_mask(&possible_crtc->base))) continue;
ret = drm_modeset_lock(&possible_crtc->base.mutex, ctx); if (ret) goto fail;
if (possible_crtc->base.state->enable) {
drm_modeset_unlock(&possible_crtc->base.mutex); continue;
}
crtc = possible_crtc; break;
}
/* * If we didn't find an unused CRTC, don't use any.
*/ if (!crtc) {
drm_dbg_kms(display->drm, "no pipe available for load-detect\n");
ret = -ENODEV; goto fail;
}
found:
state = drm_atomic_state_alloc(display->drm);
restore_state = drm_atomic_state_alloc(display->drm); if (!state || !restore_state) {
ret = -ENOMEM; goto fail;
}
connector_state = drm_atomic_get_connector_state(state, connector); if (IS_ERR(connector_state)) {
ret = PTR_ERR(connector_state); goto fail;
}
ret = drm_atomic_set_crtc_for_connector(connector_state, &crtc->base); if (ret) goto fail;
crtc_state = intel_atomic_get_crtc_state(state, crtc); if (IS_ERR(crtc_state)) {
ret = PTR_ERR(crtc_state); goto fail;
}
crtc_state->uapi.active = true;
ret = drm_atomic_set_mode_for_crtc(&crtc_state->uapi,
&load_detect_mode); if (ret) goto fail;
ret = intel_modeset_disable_planes(state, &crtc->base); if (ret) goto fail;
ret = PTR_ERR_OR_ZERO(drm_atomic_get_connector_state(restore_state, connector)); if (!ret)
ret = PTR_ERR_OR_ZERO(drm_atomic_get_crtc_state(restore_state, &crtc->base)); if (!ret)
ret = drm_atomic_add_affected_planes(restore_state, &crtc->base); if (ret) {
drm_dbg_kms(display->drm, "Failed to create a copy of old state to restore: %i\n",
ret); goto fail;
}
ret = drm_atomic_commit(state); if (ret) {
drm_dbg_kms(display->drm, "failed to set mode on load-detect pipe\n"); goto fail;
}
drm_atomic_state_put(state);
/* let the connector get through one full cycle before testing */
intel_crtc_wait_for_next_vblank(crtc);
return restore_state;
fail: if (state) {
drm_atomic_state_put(state);
state = NULL;
} if (restore_state) {
drm_atomic_state_put(restore_state);
restore_state = NULL;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.