diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index 366f6d821242..f95cd9695b43 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -230,12 +231,22 @@ static int drm_mode_config_crtc_create_state(struct drm_crtc *crtc) static int drm_mode_config_crtc_reset_with_create_state(struct drm_crtc *crtc) { + const struct drm_crtc_helper_funcs *helper_funcs = crtc->helper_private; + int ret; + if (crtc->state) { crtc->funcs->atomic_destroy_state(crtc, crtc->state); crtc->state = NULL; } - return drm_mode_config_crtc_create_state(crtc); + ret = drm_mode_config_crtc_create_state(crtc); + if (ret) + return ret; + + if (helper_funcs && helper_funcs->hw_reset) + helper_funcs->hw_reset(crtc); + + return 0; } static int drm_mode_config_connector_create_state(struct drm_connector *connector) diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index ca6268945c28..4965356a6314 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -281,6 +281,20 @@ struct drm_crtc_helper_funcs { */ void (*disable)(struct drm_crtc *crtc); + /** + * @hw_reset: + * + * Optional hook for CRTC hardware reset. + * + * Unlike @drm_crtc_funcs.reset, which both resets hardware and + * creates new software state, this hook only resets the + * hardware to a known good state without touching the software + * state at all. + * + * This hook is called by drm_mode_config_reset(). + */ + void (*hw_reset)(struct drm_crtc *crtc); + /** * @atomic_check: *