[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