On Mon, Sep 15, 2025 at 10:42:22AM +0200, Maxime Ripard wrote: > Hi Tohmas, > > On Tue, Sep 02, 2025 at 03:44:54PM +0200, Thomas Zimmermann wrote: > > > +/** > > > + * drm_atomic_build_readout_state - Creates an initial state from the > > > hardware > > > + * @dev: DRM device to build the state for > > > + * > > > + * This function allocates a &struct drm_atomic_state, calls the > > > + * atomic_readout_state callbacks, and fills the global state old states > > > + * by what the callbacks returned. > > > + * > > > + * Returns: > > > + * > > > + * A partially initialized &struct drm_atomic_state on success, an error > > > + * pointer otherwise. > > > + */ > > > +static struct drm_atomic_state * > > > +drm_atomic_build_readout_state(struct drm_device *dev) > > > +{ > > > + struct drm_connector_list_iter conn_iter; > > > + struct drm_atomic_state *state; > > > + struct drm_mode_config *config = > > > + &dev->mode_config; > > > + struct drm_connector *connector; > > > + struct drm_printer p = > > > + drm_info_printer(dev->dev); > > > + struct drm_encoder *encoder; > > > + struct drm_plane *plane; > > > + struct drm_crtc *crtc; > > > + int ret; > > > + > > > + drm_dbg_kms(dev, "Starting to build atomic state from hardware > > > state.\n"); > > > + > > > + state = drm_atomic_state_alloc(dev); > > > + if (WARN_ON(!state)) > > > + return ERR_PTR(-ENOMEM); > > > + > > > + state->connectors = kcalloc(config->num_connector, > > > sizeof(*state->connectors), GFP_KERNEL); > > > + if (WARN_ON(!state->connectors)) { > > > + ret = -ENOMEM; > > > + goto err_state_put; > > > + } > > > + > > > + state->private_objs = kcalloc(count_private_obj(dev), > > > sizeof(*state->private_objs), GFP_KERNEL); > > > + if (WARN_ON(!state->private_objs)) { > > > + ret = -ENOMEM; > > > + goto err_state_put; > > > + } > > > + > > > + drm_for_each_crtc(crtc, dev) { > > > + const struct drm_crtc_funcs *crtc_funcs = > > > + crtc->funcs; > > > + struct drm_crtc_state *crtc_state; > > > + > > > + drm_dbg_kms(dev, "Initializing CRTC %s state.\n", crtc->name); > > > + > > > + if (crtc_funcs->atomic_readout_state) { > > > + crtc_state = crtc_funcs->atomic_readout_state(crtc); > > > + } else if (crtc_funcs->reset) { > > > + crtc_funcs->reset(crtc); > > > + > > > + /* > > > + * We don't want to set crtc->state field yet. Let's > > > save and clear it up. > > > + */ > > > + crtc_state = crtc->state; > > > + crtc->state = NULL; > > > > Chancing the crtc->state pointer behind the back of the reset callback seems > > fragile. We never how if some other piece of the driver refers to it > > (although illegally). > > I agree that it's clunky. I'm not sure who would use it at this point > though: we're in the middle of the drm_mode_config_reset(), so the > drivers' involvement is pretty minimal. > > I did wonder if changing reset to return the object instead of setting > $OBJECT->state would be a better interface? > > > For now, wouldn't it be better to require a read-out helper for all elements > > of the driver's mode-setting pipeline? The trivial implementation would > > copy the existing reset function and keep crtc->state to NULL. > > I also considered that, but I'm not sure we can expect bridges to have > readout hooks filled for every configuration in the wild. > > But maybe we can look during drm_mode_config_reset() at whether all the > objects have their hook filled, and if not fall back on reset for > everything. > > It would make the implementation easier, but missing bridges > implementations would trigger a mode change when it might actually work > just fine since bridge state is pretty minimal.
DP bridge drivers have a pretty big state (DPCD and all the features). Other bridge drivers randomly leak state to the non-state structs. > > Idk. > > > > --- a/include/drm/drm_bridge.h > > > +++ b/include/drm/drm_bridge.h > > > @@ -490,10 +490,31 @@ struct drm_bridge_funcs { > > > * The @atomic_post_disable callback is optional. > > > */ > > > void (*atomic_post_disable)(struct drm_bridge *bridge, > > > struct drm_atomic_state *state); > > > + /** > > > + * @atomic_readout_state: > > > + * > > > + * Initializes,this bridge atomic state. > > > + * > > > + * It's meant to be used by drivers that wants to implement fast > > > > 'want' > > > > > + * / flicker-free boot and allows to initialize the atomic state > > > > I think we should only call it flicker-free boot. Fast boot is misleading. > > I agree, but it's also how it's been called by the only implementation > of it we have so far (i915), and the name of the module parameter that > controls it. I hope to be able to try implementing this for drm/msm (at least it will allow us to check how does that play with bridges). > > Maxime -- With best wishes Dmitry