drm_mode_config_create_initial_state() tries to read out the current
hardware state to build the initial atomic state. If state readout is
disabled or fails, it falls back to creating pristine software state
using the objects' atomic_create_state callbacks.

However, creating pristine state without resetting the hardware leaves
the hardware and software states out of sync. The legacy
drm_mode_config_reset() handles this by calling per-object .reset
callbacks that both reset the hardware and allocate new state, but these
two concerns are intertwined and cannot be reused independently.

Introduce a new hw_reset hook in drm_mode_config_funcs that only
performs the hardware reset, without allocating any software state. Call
it in drm_mode_config_create_initial_state() after state readout fails,
right before falling back to drm_mode_config_create_state(). This
separates the hardware reset from state creation, allowing drivers that
implement state readout to share their reset logic with the fallback
path.

Signed-off-by: Maxime Ripard <[email protected]>
---
 drivers/gpu/drm/drm_mode_config.c | 12 ++++++++----
 include/drm/drm_mode_config.h     | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_mode_config.c 
b/drivers/gpu/drm/drm_mode_config.c
index 7c351c6f34a4..1581378a1419 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -397,17 +397,18 @@ static int drm_mode_config_create_state(struct drm_device 
*dev)
  *
  * 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
+ * read out the initial state from the hardware for all objects if state
+ * readout is enabled and the driver supports it. Then, if state
+ * readout isn't supported or fails, it resets the hardware using
+ * &drm_mode_config_funcs.hw_reset() and 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.
+ * doesn't support state readout, and will always reset the hardware.
  * It will also ignore all &drm_private_obj.
  *
  * Returns: 0 on success, negative error value on failure.
  */
 int drm_mode_config_create_initial_state(struct drm_device *dev)
@@ -416,10 +417,13 @@ int drm_mode_config_create_initial_state(struct 
drm_device *dev)
 
        ret = dev->mode_config.funcs->atomic_sro_readout_state(dev);
        if (!ret)
                return 0;
 
+       if (dev->mode_config.funcs->hw_reset)
+               dev->mode_config.funcs->hw_reset(dev);
+
        return drm_mode_config_create_state(dev);
 }
 EXPORT_SYMBOL(drm_mode_config_create_initial_state);
 
 /*
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 14eab7b126ea..5b3c194c72ca 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -107,10 +107,42 @@ struct drm_mode_config_funcs {
         * should be checked in the .mode_valid() hook for each specific object.
         */
        enum drm_mode_status (*mode_valid)(struct drm_device *dev,
                                           const struct drm_display_mode *mode);
 
+       /**
+        * @hw_reset:
+        *
+        * Optional hook for device-specific hardware reset.
+        *
+        * Unlike drm_mode_config_reset(), which both resets hardware
+        * and creates new software state through per-object .reset
+        * callbacks, this hook only resets the hardware to a known good
+        * state without touching the software state at all.
+        *
+        * This hook is called by
+        * drm_mode_config_create_initial_state() when the hardware
+        * state readout (atomic_sro_readout_state) is not supported
+        * or fails. The call sequence is:
+        *
+        * 1. Try atomic_sro_readout_state() to read the hardware state
+        * 2. If that fails, call hw_reset() to put the hardware in a
+        *    known state
+        * 3. Create pristine software state via atomic_create_state
+        *    callbacks
+        *
+        * Drivers that implement state readout and need a hardware
+        * reset on the fallback path should implement this hook.
+        * Drivers that don't implement state readout at all can keep
+        * using drm_mode_config_reset() instead.
+        *
+        * This hook is optional. If not provided, the fallback path
+        * will create software state without resetting the hardware
+        * first.
+        */
+       void (*hw_reset)(struct drm_device *dev);
+
        /**
         * @atomic_check:
         *
         * This is the only hook to validate an atomic modeset update. This
         * function must reject any modeset and state changes which the hardware

-- 
2.54.0

Reply via email to