This way the drm_bridge_funcs interface is consistent with the rest of the subsystem. The drivers implementing those hooks are patched too. v10: * Add changelog to the commit message v8 -> v9: * No changes v7: * Adjust things to the bridge_state changes v6: * Also fixed rcar-du/rcar_lvds.c same as analogix/analogix_dp_core.c v5: * No changes v4: * Rename func params into old_bridge_state * Add Laurent's Rb v3: * Old state clarification moved to a separate patch v2: * Pass the old bridge state Signed-off-by: Boris Brezillon <boris.brezillon@xxxxxxxxxxxxx> Reviewed-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx> Signed-off-by: Neil Armstrong <narmstrong@xxxxxxxxxxxx> [narmstrong: renamed state as old_bridge_state in rcar_lvds_atomic_disable] Reviewed by: Jernej Skrabec <jernej.skrabec@xxxxxxxx> Tested-by: Jonas Karlman <jonas@xxxxxxxxx> --- --- .../drm/bridge/analogix/analogix_dp_core.c | 41 +++++++------ drivers/gpu/drm/drm_bridge.c | 61 +++++++++++++++---- drivers/gpu/drm/rcar-du/rcar_lvds.c | 8 ++- include/drm/drm_bridge.h | 8 +-- 4 files changed, 82 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index aaaec39ec2a7..dfb59a5fefea 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1289,19 +1289,21 @@ struct drm_crtc *analogix_dp_get_new_crtc(struct analogix_dp_device *dp, return conn_state->crtc; } -static void analogix_dp_bridge_atomic_pre_enable(struct drm_bridge *bridge, - struct drm_atomic_state *state) +static void +analogix_dp_bridge_atomic_pre_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { + struct drm_atomic_state *old_state = old_bridge_state->base.state; struct analogix_dp_device *dp = bridge->driver_private; struct drm_crtc *crtc; struct drm_crtc_state *old_crtc_state; int ret; - crtc = analogix_dp_get_new_crtc(dp, state); + crtc = analogix_dp_get_new_crtc(dp, old_state); if (!crtc) return; - old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); + old_crtc_state = drm_atomic_get_old_crtc_state(old_state, crtc); /* Don't touch the panel if we're coming back from PSR */ if (old_crtc_state && old_crtc_state->self_refresh_active) return; @@ -1366,20 +1368,22 @@ static int analogix_dp_set_bridge(struct analogix_dp_device *dp) return ret; } -static void analogix_dp_bridge_atomic_enable(struct drm_bridge *bridge, - struct drm_atomic_state *state) +static void +analogix_dp_bridge_atomic_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { + struct drm_atomic_state *old_state = old_bridge_state->base.state; struct analogix_dp_device *dp = bridge->driver_private; struct drm_crtc *crtc; struct drm_crtc_state *old_crtc_state; int timeout_loop = 0; int ret; - crtc = analogix_dp_get_new_crtc(dp, state); + crtc = analogix_dp_get_new_crtc(dp, old_state); if (!crtc) return; - old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); + old_crtc_state = drm_atomic_get_old_crtc_state(old_state, crtc); /* Not a full enable, just disable PSR and continue */ if (old_crtc_state && old_crtc_state->self_refresh_active) { ret = analogix_dp_disable_psr(dp); @@ -1440,18 +1444,20 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge) dp->dpms_mode = DRM_MODE_DPMS_OFF; } -static void analogix_dp_bridge_atomic_disable(struct drm_bridge *bridge, - struct drm_atomic_state *state) +static void +analogix_dp_bridge_atomic_disable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { + struct drm_atomic_state *old_state = old_bridge_state->base.state; struct analogix_dp_device *dp = bridge->driver_private; struct drm_crtc *crtc; struct drm_crtc_state *new_crtc_state = NULL; - crtc = analogix_dp_get_new_crtc(dp, state); + crtc = analogix_dp_get_new_crtc(dp, old_state); if (!crtc) goto out; - new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + new_crtc_state = drm_atomic_get_new_crtc_state(old_state, crtc); if (!new_crtc_state) goto out; @@ -1463,20 +1469,21 @@ static void analogix_dp_bridge_atomic_disable(struct drm_bridge *bridge, analogix_dp_bridge_disable(bridge); } -static -void analogix_dp_bridge_atomic_post_disable(struct drm_bridge *bridge, - struct drm_atomic_state *state) +static void +analogix_dp_bridge_atomic_post_disable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { + struct drm_atomic_state *old_state = old_bridge_state->base.state; struct analogix_dp_device *dp = bridge->driver_private; struct drm_crtc *crtc; struct drm_crtc_state *new_crtc_state; int ret; - crtc = analogix_dp_get_new_crtc(dp, state); + crtc = analogix_dp_get_new_crtc(dp, old_state); if (!crtc) return; - new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + new_crtc_state = drm_atomic_get_new_crtc_state(old_state, crtc); if (!new_crtc_state || !new_crtc_state->self_refresh_active) return; diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index 6b08158ebb7e..f6206e655da4 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -458,10 +458,19 @@ void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge, encoder = bridge->encoder; list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { - if (iter->funcs->atomic_disable) - iter->funcs->atomic_disable(iter, old_state); - else if (iter->funcs->disable) + if (iter->funcs->atomic_disable) { + struct drm_bridge_state *old_bridge_state; + + old_bridge_state = + drm_atomic_get_old_bridge_state(old_state, + iter); + if (WARN_ON(!old_bridge_state)) + return; + + iter->funcs->atomic_disable(iter, old_bridge_state); + } else if (iter->funcs->disable) { iter->funcs->disable(iter); + } if (iter == bridge) break; @@ -492,10 +501,20 @@ void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge, encoder = bridge->encoder; list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) { - if (bridge->funcs->atomic_post_disable) - bridge->funcs->atomic_post_disable(bridge, old_state); - else if (bridge->funcs->post_disable) + if (bridge->funcs->atomic_post_disable) { + struct drm_bridge_state *old_bridge_state; + + old_bridge_state = + drm_atomic_get_old_bridge_state(old_state, + bridge); + if (WARN_ON(!old_bridge_state)) + return; + + bridge->funcs->atomic_post_disable(bridge, + old_bridge_state); + } else if (bridge->funcs->post_disable) { bridge->funcs->post_disable(bridge); + } } } EXPORT_SYMBOL(drm_atomic_bridge_chain_post_disable); @@ -524,10 +543,19 @@ void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge, encoder = bridge->encoder; list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { - if (iter->funcs->atomic_pre_enable) - iter->funcs->atomic_pre_enable(iter, old_state); - else if (iter->funcs->pre_enable) + if (iter->funcs->atomic_pre_enable) { + struct drm_bridge_state *old_bridge_state; + + old_bridge_state = + drm_atomic_get_old_bridge_state(old_state, + iter); + if (WARN_ON(!old_bridge_state)) + return; + + iter->funcs->atomic_pre_enable(iter, old_bridge_state); + } else if (iter->funcs->pre_enable) { iter->funcs->pre_enable(iter); + } if (iter == bridge) break; @@ -557,10 +585,19 @@ void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge, encoder = bridge->encoder; list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) { - if (bridge->funcs->atomic_enable) - bridge->funcs->atomic_enable(bridge, old_state); - else if (bridge->funcs->enable) + if (bridge->funcs->atomic_enable) { + struct drm_bridge_state *old_bridge_state; + + old_bridge_state = + drm_atomic_get_old_bridge_state(old_state, + bridge); + if (WARN_ON(!old_bridge_state)) + return; + + bridge->funcs->atomic_enable(bridge, old_bridge_state); + } else if (bridge->funcs->enable) { bridge->funcs->enable(bridge); + } } } EXPORT_SYMBOL(drm_atomic_bridge_chain_enable); diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c index 3a254f1b29fe..06432c881e07 100644 --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c @@ -590,8 +590,9 @@ static void __rcar_lvds_atomic_enable(struct drm_bridge *bridge, } static void rcar_lvds_atomic_enable(struct drm_bridge *bridge, - struct drm_atomic_state *state) + struct drm_bridge_state *old_bridge_state) { + struct drm_atomic_state *state = old_bridge_state->base.state; struct drm_connector *connector; struct drm_crtc *crtc; @@ -603,7 +604,7 @@ static void rcar_lvds_atomic_enable(struct drm_bridge *bridge, } static void rcar_lvds_atomic_disable(struct drm_bridge *bridge, - struct drm_atomic_state *state) + struct drm_bridge_state *old_bridge_state) { struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge); @@ -618,7 +619,8 @@ static void rcar_lvds_atomic_disable(struct drm_bridge *bridge, /* Disable the companion LVDS encoder in dual-link mode. */ if (lvds->link_type != RCAR_LVDS_SINGLE_LINK && lvds->companion) - lvds->companion->funcs->atomic_disable(lvds->companion, state); + lvds->companion->funcs->atomic_disable(lvds->companion, + old_bridge_state); clk_disable_unprepare(lvds->clocks.mod); } diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 8883dcfe63cb..df22f909141f 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -265,7 +265,7 @@ struct drm_bridge_funcs { * The @atomic_pre_enable callback is optional. */ void (*atomic_pre_enable)(struct drm_bridge *bridge, - struct drm_atomic_state *old_state); + struct drm_bridge_state *old_bridge_state); /** * @atomic_enable: @@ -290,7 +290,7 @@ struct drm_bridge_funcs { * The @atomic_enable callback is optional. */ void (*atomic_enable)(struct drm_bridge *bridge, - struct drm_atomic_state *old_state); + struct drm_bridge_state *old_bridge_state); /** * @atomic_disable: * @@ -313,7 +313,7 @@ struct drm_bridge_funcs { * The @atomic_disable callback is optional. */ void (*atomic_disable)(struct drm_bridge *bridge, - struct drm_atomic_state *old_state); + struct drm_bridge_state *old_bridge_state); /** * @atomic_post_disable: @@ -339,7 +339,7 @@ struct drm_bridge_funcs { * The @atomic_post_disable callback is optional. */ void (*atomic_post_disable)(struct drm_bridge *bridge, - struct drm_atomic_state *old_state); + struct drm_bridge_state *old_bridge_state); /** * @atomic_duplicate_state: -- 2.24.1