On Tue, Feb 25, 2025 at 05:43:55PM +0100, Maxime Ripard wrote: > Let's provide an helper to make it easier for bridge drivers to > power-cycle their bridge. > > Co-developed-by: Simona Vetter <[email protected]> > Signed-off-by: Maxime Ripard <[email protected]> > --- > drivers/gpu/drm/drm_bridge.c | 44 > ++++++++++++++++++++++++++++++++++++++++++++ > include/drm/drm_bridge.h | 2 ++ > 2 files changed, 46 insertions(+) > > diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c > index > 8241c00e4506eceeb9bb4ba74a38d8f360c65d38..ca894531a2042fc9296c40a1f51a6cdea6e97ed7 > 100644 > --- a/drivers/gpu/drm/drm_bridge.c > +++ b/drivers/gpu/drm/drm_bridge.c > @@ -24,10 +24,11 @@ > #include <linux/err.h> > #include <linux/media-bus-format.h> > #include <linux/module.h> > #include <linux/mutex.h> > > +#include <drm/drm_atomic_helper.h> > #include <drm/drm_atomic_state_helper.h> > #include <drm/drm_bridge.h> > #include <drm/drm_debugfs.h> > #include <drm/drm_edid.h> > #include <drm/drm_encoder.h> > @@ -1269,10 +1270,53 @@ void drm_bridge_hpd_notify(struct drm_bridge *bridge, > bridge->hpd_cb(bridge->hpd_data, status); > mutex_unlock(&bridge->hpd_mutex); > } > EXPORT_SYMBOL_GPL(drm_bridge_hpd_notify); > > +/** > + * drm_bridge_reset_crtc - Reset the pipeline feeding a bridge > + * @bridge: DRM bridge to reset > + * @ctx: lock acquisition context > + * > + * Reset a @bridge pipeline. It will power-cycle all active components > + * between the CRTC and connector that bridge is connected to. > + * > + * Returns: > + * > + * 0 on success or a negative error code on failure. If the error > + * returned is EDEADLK, the whole atomic sequence must be restarted. > + */ > +int drm_bridge_reset_crtc(struct drm_bridge *bridge, > + struct drm_modeset_acquire_ctx *ctx) > +{ > + struct drm_connector *connector; > + struct drm_encoder *encoder = bridge->encoder; > + struct drm_device *dev = encoder->dev; > + struct drm_crtc *crtc; > + int ret; > + > + ret = drm_modeset_lock(&dev->mode_config.connection_mutex, ctx); > + if (ret) > + return ret; > + > + connector = drm_atomic_get_connector_for_encoder(encoder, ctx); > + if (IS_ERR(connector)) { > + ret = PTR_ERR(connector); > + goto out; > + } > +
Should there be a check for connector->state before accessing connector->state->crtc ? > + crtc = connector->state->crtc; > + ret = drm_atomic_helper_reset_crtc(crtc, ctx); > + if (ret) > + goto out; > + > +out: > + drm_modeset_unlock(&dev->mode_config.connection_mutex); > + return ret; > +} > +EXPORT_SYMBOL(drm_bridge_reset_crtc); > + > #ifdef CONFIG_OF > /** > * of_drm_find_bridge - find the bridge corresponding to the device node in > * the global bridge list > * > diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h > index > 6fb1da7c195e99143a67a999d16fe361c1e3f4ab..32169e62463bb268a281a5903c0c9f448a1042b3 > 100644 > --- a/include/drm/drm_bridge.h > +++ b/include/drm/drm_bridge.h > @@ -1085,10 +1085,12 @@ void drm_bridge_hpd_enable(struct drm_bridge *bridge, > enum drm_connector_status status), > void *data); > void drm_bridge_hpd_disable(struct drm_bridge *bridge); > void drm_bridge_hpd_notify(struct drm_bridge *bridge, > enum drm_connector_status status); > +int drm_bridge_reset_crtc(struct drm_bridge *bridge, > + struct drm_modeset_acquire_ctx *ctx); > > #ifdef CONFIG_DRM_PANEL_BRIDGE > bool drm_bridge_is_panel(const struct drm_bridge *bridge); > struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel); > struct drm_bridge *drm_panel_bridge_add_typed(struct drm_panel *panel, > > -- > 2.48.1 > -- With best wishes Dmitry
