drm_mode_config_create_state() creates the initial state for all KMS objects at driver registration time.
Call the drm_mode_config_funcs.atomic_sro_readout_state hook from it so that the initial state is populated from the hardware rather than being left as a pristine default. Reviewed-by: Maarten Lankhorst <[email protected]> Signed-off-by: Maxime Ripard <[email protected]> --- drivers/gpu/drm/drm_mode_config.c | 70 ++++++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index c1e993a78702..9f242e2654c8 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -25,4 +25,5 @@ #include <drm/drm_atomic.h> +#include <drm/drm_atomic_state_readout.h> #include <drm/drm_drv.h> #include <drm/drm_encoder.h> @@ -32,4 +33,5 @@ #include <drm/drm_mode_config.h> #include <drm/drm_modeset_helper_vtables.h> +#include <drm/drm_modeset_lock.h> #include <drm/drm_print.h> #include <drm/drm_colorop.h> @@ -323,19 +325,5 @@ void drm_mode_config_reset(struct drm_device *dev) EXPORT_SYMBOL(drm_mode_config_reset); -/** - * drm_mode_config_create_initial_state - Allocates the initial state - * @dev: drm device - * - * This functions creates the initial state for all the objects. Drivers - * can use this in e.g. probe to initialize their software state. - * - * It has two main differences with drm_mode_config_reset(): the reset() - * hooks aren't called and thus the hardware will be left untouched, but - * also the &drm_private_obj structures will be initialized as opposed - * to drm_mode_config_reset() that skips them. - * - * Returns: 0 on success, negative error value on failure. - */ -int drm_mode_config_create_initial_state(struct drm_device *dev) +static int drm_mode_config_create_state(struct drm_device *dev) { struct drm_crtc *crtc; @@ -409,4 +397,56 @@ int drm_mode_config_create_initial_state(struct drm_device *dev) return 0; } + +/** + * drm_mode_config_create_initial_state - Allocates the initial state + * @dev: drm device + * + * This functions creates the initial state for all the objects. Drivers + * can use this in e.g. probe to initialize their state. + * + * It creates the initial state in several steps. It first tries to + * read-out the initial state from the hardware for all objects if state + * read-out is enabled and the driver supports it. Then, if state + * read-out isn't supported or fails, it creates a new, pristine state + * using the objects atomic_create_state callback. + * + * For historical reasons, drm_mode_config_reset() is similar, but + * doesn't support state read-out, and will always reset the hardware. + * It will also ignore all &drm_private_obj. + * + * The function holds all the modeset locks for the duration of the + * readout and the state creation, so drivers don't need to guarantee + * any kind of exclusivity themselves. + * + * Returns: 0 on success, negative error value on failure. + */ +int drm_mode_config_create_initial_state(struct drm_device *dev) +{ + struct drm_modeset_acquire_ctx ctx; + int ret; + + /* + * The initial state is usually created while the device is + * being initialized and nothing can access it concurrently, + * but holding all the modeset locks puts the readout, the + * installation of its result and the creation of the pristine + * states under the same locking contract as the regular + * atomic paths. + */ + DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); + + if (dev->mode_config.funcs->atomic_sro_readout_state) { + ret = dev->mode_config.funcs->atomic_sro_readout_state(dev); + if (!ret) + goto out; + } + + ret = drm_mode_config_create_state(dev); + +out: + DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); + + return ret; +} EXPORT_SYMBOL(drm_mode_config_create_initial_state); -- 2.55.0
