diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index c22062cc9992..eb96098481f3 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -921,6 +921,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) for_each_oldnew_connector_in_state(old_state, connector, old_conn_state, new_conn_state, i) { const struct drm_encoder_helper_funcs *funcs; + const struct drm_connector_helper_funcs *conn_funcs; struct drm_encoder *encoder; /* Shut down everything that's in the changeset and currently @@ -947,12 +948,32 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) DRM_DEBUG_ATOMIC("disabling [ENCODER:%d:%s]\n", encoder->base.id, encoder->name); + conn_funcs = connector->helper_private; + if (connector->loader_protect) { + drm_bridge_pre_enable(encoder->bridge); + + if (funcs->enable) + funcs->enable(encoder); + else + funcs->commit(encoder); + + drm_bridge_enable(encoder->bridge); + + if (conn_funcs->loader_protect) + conn_funcs->loader_protect(connector, false); + connector->loader_protect = false; + } /* * Each encoder has at most one connector (since we always steal * it away), so we won't call disable hooks twice. */ drm_bridge_disable(encoder->bridge); + if (encoder->loader_protect) { + if (funcs->loader_protect) + funcs->loader_protect(encoder, false); + encoder->loader_protect = false; + } /* Right function depends upon target state. */ if (funcs) { if (new_conn_state->crtc && funcs->prepare) diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 7b33fe6a2768..4c4f00898aed 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -984,6 +984,11 @@ struct drm_connector { * need the CRTC driving this output, &drm_connector_state.crtc. */ struct drm_encoder *encoder; + /** + * @loader_protect: + * connector loader logo protect state. + */ + bool loader_protect; #define MAX_ELD_BYTES 128 /** @eld: EDID-like data, if present */ diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h index 30a7beca3e4e..ef5afe402e79 100644 --- a/include/drm/drm_encoder.h +++ b/include/drm/drm_encoder.h @@ -166,6 +166,11 @@ struct drm_encoder { */ uint32_t possible_clones; + /** + * @loader_protect: + * encoder loader logo protect state. + */ + bool loader_protect; /** * @crtc: Currently bound CRTC, only really meaningful for non-atomic * drivers. Atomic drivers should instead check diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index 0eb3372d0311..d5bb53855539 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -464,6 +464,11 @@ static inline void drm_crtc_helper_add(struct drm_crtc *crtc, * helpers and the new atomic modesetting helpers. */ struct drm_encoder_helper_funcs { + /** + * @loader_protect: + * protect loader logo encoder's power. + */ + int (*loader_protect)(struct drm_encoder *encoder, bool on); /** * @dpms: * @@ -780,6 +785,12 @@ static inline void drm_encoder_helper_add(struct drm_encoder *encoder, * probe helpers. */ struct drm_connector_helper_funcs { + /** + * @loader_protect: + * + * protect loader logo connector's power + */ + int (*loader_protect)(struct drm_connector *connector, bool on); /** * @get_modes: *