[PATCH 1/5] drm: Add atomic helper to redo a modeset on current mode

Manasi Navare manasi.d.navare at intel.com
Fri Oct 21 23:45:39 UTC 2016


This function provides a way for the driver to redo a
modeset on the current mode and retry the link training
at a lower link rate/lane count/bpp. This will get called
incase the link training fails during the current modeset.

Cc: dri-devel at lists.freedesktop.org
Cc: Jani Nikula <jani.nikula at linux.intel.com>
Cc: Daniel Vetter <daniel.vetter at intel.com>
Cc: Ville Syrjala <ville.syrjala at linux.intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare at intel.com>
---
 drivers/gpu/drm/drm_atomic_helper.c | 58 +++++++++++++++++++++++++++++++++++++
 include/drm/drm_atomic_helper.h     |  1 +
 2 files changed, 59 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index f936276..0c1614e 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -2895,6 +2895,64 @@ int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
 EXPORT_SYMBOL(drm_atomic_helper_connector_dpms);
 
 /**
+ * drm_atomic_helper_connector_modeset - Force a modeset on a connector
+ * @connector: DRM connector
+ *
+ * Provides a way to redo a modeset with the current mode so that it can
+ * drop the bpp, link rate/lane count and retry the link training.
+ *
+ * Returns:
+ * Returns 0 on success, negative errno numbers on failure.
+ */
+int
+drm_atomic_helper_connector_modeset(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_modeset_acquire_ctx ctx;
+	struct drm_atomic_state *state;
+	struct drm_connector_state *connector_state;
+	struct drm_crtc_state *crtc_state;
+	int ret = 0;
+
+	drm_modeset_acquire_init(&ctx, 0);
+	state = drm_atomic_state_alloc(dev);
+	if (!state) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+	state->acquire_ctx = &ctx;
+retry:
+	ret = 0;
+	connector_state = drm_atomic_get_connector_state(state, connector);
+	if (IS_ERR(connector_state)) {
+		ret = PTR_ERR(connector_state);
+		goto fail;
+	}
+	if (!connector_state->crtc)
+		goto fail;
+
+	crtc_state = drm_atomic_get_existing_crtc_state(state,
+							connector_state->crtc);
+	crtc_state->connectors_changed = true;
+	ret = drm_atomic_commit(state);
+fail:
+	if (ret == -EDEADLK) {
+		drm_atomic_state_clear(state);
+		drm_modeset_backoff(&ctx);
+		goto retry;
+	}
+
+	if (state)
+		drm_atomic_state_put(state);
+
+	drm_modeset_drop_locks(&ctx);
+	drm_modeset_acquire_fini(&ctx);
+
+	return ret;
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_modeset);
+
+/**
  * drm_atomic_helper_best_encoder - Helper for &drm_connector_helper_funcs
  *                                  ->best_encoder callback
  * @connector: Connector control structure
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 7ff92b0..8de24dc 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -126,6 +126,7 @@ int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
 				uint32_t flags);
 int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
 				     int mode);
+int drm_atomic_helper_connector_modeset(struct drm_connector *connector);
 struct drm_encoder *
 drm_atomic_helper_best_encoder(struct drm_connector *connector);
 
-- 
1.9.1



More information about the dri-devel mailing list