public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] drm/panel: Add atomic versions of panel ops
@ 2026-04-24 23:49 Val Packett
  2026-04-24 23:49 ` [PATCH 2/2] drm/bridge: panel: call the new atomic " Val Packett
  2026-04-25 12:08 ` [PATCH 1/2] drm/panel: Add atomic versions of " Dmitry Baryshkov
  0 siblings, 2 replies; 3+ messages in thread
From: Val Packett @ 2026-04-24 23:49 UTC (permalink / raw)
  To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter
  Cc: Val Packett, Dmitry Baryshkov, Marijn Suijten, dri-devel,
	~postmarketos/upstreaming, phone-devel, linux-kernel

Modern DSI panels support various modes (resolutions and refresh rates),
which usually requires sending mode-specific DCS commands to configure the
DDIC during operations like prepare(). However existing drm_panel_funcs
only take the panel itself as an argument, so there's no way to access
relevant state (such as the mode being set) inside of these functions.

To allow panel drivers access to the state, introduce new atomic_*
versions of the prepare/enable/disable/unprepare ops, and make the
corresponding drm_panel_* functions call them if available, falling back
to the original ops otherwise. To avoid the need to modify all consumers
at once, the original single-argument drm_panel_* functions are redefined
as aliases to the new ones, passing NULLs for the new extra arguments.

The atomic ops pass the CRTC as well as the atomic state because getting
the mode being set is part of per-CRTC state.

Signed-off-by: Val Packett <val@packett.cool>
---

As discussed in my recent RFC [1] and an older thread I was pointed to
there [2], the right way to expose the mode to panel drivers is to expose
the entire atomic state and let them find the mode there. (Turns out,
the drm_crtc must also be passed along with the state as it's necessary
for drm_atomic_get_new_crtc_state).

Hopefully this first "real" attempt is close enough! :)

I have tested this with the WIP nt37701 driver from the linked RFC,
only slightly updated to receive the new args and not directly the mode.

[1]: https://lore.kernel.org/all/20260412113851.355944-1-val@packett.cool/
[2]: https://lore.kernel.org/dri-devel/nfc6ih43gjpi5u67fpkkxgwwygv53grdldq7tfp5iiukrkiy2u@53fsrtezzkyt/

Thanks,
~val

---
 drivers/gpu/drm/drm_panel.c |  88 +++++++++++++++--------
 include/drm/drm_panel.h     | 137 ++++++++++++++++++++++++++++++++++--
 2 files changed, 193 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
index d1e6598ea3bc..48fce5e89bca 100644
--- a/drivers/gpu/drm/drm_panel.c
+++ b/drivers/gpu/drm/drm_panel.c
@@ -102,16 +102,20 @@ void drm_panel_remove(struct drm_panel *panel)
 EXPORT_SYMBOL(drm_panel_remove);
 
 /**
- * drm_panel_prepare - power on a panel
+ * drm_panel_atomic_prepare - power on a panel
  * @panel: DRM panel
+ * @crtc: the CRTC used to drive the panel, may be NULL
+ * @state: current atomic commit state, may be NULL
  *
  * Calling this function will enable power and deassert any reset signals to
  * the panel. After this has completed it is possible to communicate with any
  * integrated circuitry via a command bus. This function cannot fail (as it is
  * called from the pre_enable call chain). There will always be a call to
- * drm_panel_disable() afterwards.
+ * drm_panel_atomic_disable() afterwards.
  */
-void drm_panel_prepare(struct drm_panel *panel)
+void drm_panel_atomic_prepare(struct drm_panel *panel,
+			      struct drm_crtc *crtc,
+			      struct drm_atomic_state *state)
 {
 	struct drm_panel_follower *follower;
 	int ret;
@@ -126,11 +130,15 @@ void drm_panel_prepare(struct drm_panel *panel)
 
 	mutex_lock(&panel->follower_lock);
 
-	if (panel->funcs && panel->funcs->prepare) {
+	if (panel->funcs && panel->funcs->atomic_prepare) {
+		ret = panel->funcs->atomic_prepare(panel, crtc, state);
+	} else if (panel->funcs && panel->funcs->prepare) {
 		ret = panel->funcs->prepare(panel);
-		if (ret < 0)
-			goto exit;
+	} else {
+		ret = 0;
 	}
+	if (ret < 0)
+		goto exit;
 	panel->prepared = true;
 
 	list_for_each_entry(follower, &panel->followers, list) {
@@ -146,18 +154,22 @@ void drm_panel_prepare(struct drm_panel *panel)
 exit:
 	mutex_unlock(&panel->follower_lock);
 }
-EXPORT_SYMBOL(drm_panel_prepare);
+EXPORT_SYMBOL(drm_panel_atomic_prepare);
 
 /**
- * drm_panel_unprepare - power off a panel
+ * drm_panel_atomic_unprepare - power off a panel
  * @panel: DRM panel
+ * @crtc: the CRTC used to drive the panel, may be NULL
+ * @state: current atomic commit state, may be NULL
  *
  * Calling this function will completely power off a panel (assert the panel's
  * reset, turn off power supplies, ...). After this function has completed, it
  * is usually no longer possible to communicate with the panel until another
- * call to drm_panel_prepare().
+ * call to drm_panel_atomic_prepare().
  */
-void drm_panel_unprepare(struct drm_panel *panel)
+void drm_panel_atomic_unprepare(struct drm_panel *panel,
+				struct drm_crtc *crtc,
+				struct drm_atomic_state *state)
 {
 	struct drm_panel_follower *follower;
 	int ret;
@@ -191,29 +203,37 @@ void drm_panel_unprepare(struct drm_panel *panel)
 				 follower->funcs->panel_unpreparing, ret);
 	}
 
-	if (panel->funcs && panel->funcs->unprepare) {
+	if (panel->funcs && panel->funcs->atomic_unprepare) {
+		ret = panel->funcs->atomic_unprepare(panel, crtc, state);
+	} else if (panel->funcs && panel->funcs->unprepare) {
 		ret = panel->funcs->unprepare(panel);
-		if (ret < 0)
-			goto exit;
+	} else {
+		ret = 0;
 	}
+	if (ret < 0)
+		goto exit;
 	panel->prepared = false;
 
 exit:
 	mutex_unlock(&panel->follower_lock);
 }
-EXPORT_SYMBOL(drm_panel_unprepare);
+EXPORT_SYMBOL(drm_panel_atomic_unprepare);
 
 /**
- * drm_panel_enable - enable a panel
+ * drm_panel_atomic_enable - enable a panel
  * @panel: DRM panel
+ * @crtc: the CRTC used to drive the panel, may be NULL
+ * @state: current atomic commit state, may be NULL
  *
  * Calling this function will cause the panel display drivers to be turned on
  * and the backlight to be enabled. Content will be visible on screen after
  * this call completes. This function cannot fail (as it is called from the
- * enable call chain). There will always be a call to drm_panel_disable()
- * afterwards.
+ * enable call chain). There will always be a call to
+ * drm_panel_atomic_disable() afterwards.
  */
-void drm_panel_enable(struct drm_panel *panel)
+void drm_panel_atomic_enable(struct drm_panel *panel,
+			     struct drm_crtc *crtc,
+			     struct drm_atomic_state *state)
 {
 	struct drm_panel_follower *follower;
 	int ret;
@@ -228,11 +248,15 @@ void drm_panel_enable(struct drm_panel *panel)
 
 	mutex_lock(&panel->follower_lock);
 
-	if (panel->funcs && panel->funcs->enable) {
+	if (panel->funcs && panel->funcs->atomic_enable) {
+		ret = panel->funcs->atomic_enable(panel, crtc, state);
+	} else if (panel->funcs && panel->funcs->enable) {
 		ret = panel->funcs->enable(panel);
-		if (ret < 0)
-			goto exit;
+	} else {
+		ret = 0;
 	}
+	if (ret < 0)
+		goto exit;
 	panel->enabled = true;
 
 	ret = backlight_enable(panel->backlight);
@@ -253,17 +277,21 @@ void drm_panel_enable(struct drm_panel *panel)
 exit:
 	mutex_unlock(&panel->follower_lock);
 }
-EXPORT_SYMBOL(drm_panel_enable);
+EXPORT_SYMBOL(drm_panel_atomic_enable);
 
 /**
- * drm_panel_disable - disable a panel
+ * drm_panel_atomic_disable - disable a panel
  * @panel: DRM panel
+ * @crtc: the CRTC used to drive the panel, may be NULL
+ * @state: current atomic commit state, may be NULL
  *
  * This will typically turn off the panel's backlight or disable the display
  * drivers. For smart panels it should still be possible to communicate with
  * the integrated circuitry via any command bus after this call.
  */
-void drm_panel_disable(struct drm_panel *panel)
+void drm_panel_atomic_disable(struct drm_panel *panel,
+			      struct drm_crtc *crtc,
+			      struct drm_atomic_state *state)
 {
 	struct drm_panel_follower *follower;
 	int ret;
@@ -302,17 +330,21 @@ void drm_panel_disable(struct drm_panel *panel)
 		DRM_DEV_INFO(panel->dev, "failed to disable backlight: %d\n",
 			     ret);
 
-	if (panel->funcs && panel->funcs->disable) {
+	if (panel->funcs && panel->funcs->atomic_disable) {
+		ret = panel->funcs->atomic_disable(panel, crtc, state);
+	} else if (panel->funcs && panel->funcs->disable) {
 		ret = panel->funcs->disable(panel);
-		if (ret < 0)
-			goto exit;
+	} else {
+		ret = 0;
 	}
+	if (ret < 0)
+		goto exit;
 	panel->enabled = false;
 
 exit:
 	mutex_unlock(&panel->follower_lock);
 }
-EXPORT_SYMBOL(drm_panel_disable);
+EXPORT_SYMBOL(drm_panel_atomic_disable);
 
 /**
  * drm_panel_get_modes - probe the available display modes of a panel
diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
index 2407bfa60236..696df57cdd37 100644
--- a/include/drm/drm_panel.h
+++ b/include/drm/drm_panel.h
@@ -33,7 +33,9 @@
 struct backlight_device;
 struct dentry;
 struct device_node;
+struct drm_atomic_state;
 struct drm_connector;
+struct drm_crtc;
 struct drm_panel_follower;
 struct drm_panel;
 struct display_timing;
@@ -80,6 +82,19 @@ struct drm_panel_funcs {
 	 */
 	int (*prepare)(struct drm_panel *panel);
 
+	/**
+	 * @atomic_prepare:
+	 *
+	 * Turn on panel and perform setup with access to atomic commit state.
+	 * Consumers will prefer this function over @prepare if both are provided.
+	 * The state may be NULL due to the caller not being aware of it.
+	 *
+	 * This function is optional.
+	 */
+	int (*atomic_prepare)(struct drm_panel *panel,
+			      struct drm_crtc *crtc,
+			      struct drm_atomic_state *state);
+
 	/**
 	 * @enable:
 	 *
@@ -89,6 +104,19 @@ struct drm_panel_funcs {
 	 */
 	int (*enable)(struct drm_panel *panel);
 
+	/**
+	 * @atomic_enable:
+	 *
+	 * Enable panel (turn on backlight, etc.) with access to atomic commit state.
+	 * Consumers will prefer this function over @enable if both are provided.
+	 * The state may be NULL due to the caller not being aware of it.
+	 *
+	 * This function is optional.
+	 */
+	int (*atomic_enable)(struct drm_panel *panel,
+			     struct drm_crtc *crtc,
+			     struct drm_atomic_state *state);
+
 	/**
 	 * @disable:
 	 *
@@ -98,6 +126,19 @@ struct drm_panel_funcs {
 	 */
 	int (*disable)(struct drm_panel *panel);
 
+	/**
+	 * @atomic_disable:
+	 *
+	 * Disable panel (turn off backlight, etc.) with access to atomic commit state.
+	 * Consumers will prefer this function over @disable if both are provided.
+	 * The state may be NULL due to the caller not being aware of it.
+	 *
+	 * This function is optional.
+	 */
+	int (*atomic_disable)(struct drm_panel *panel,
+			      struct drm_crtc *crtc,
+			      struct drm_atomic_state *state);
+
 	/**
 	 * @unprepare:
 	 *
@@ -107,6 +148,19 @@ struct drm_panel_funcs {
 	 */
 	int (*unprepare)(struct drm_panel *panel);
 
+	/**
+	 * @atomic_unprepare:
+	 *
+	 * Turn off panel with access to atomic commit state.
+	 * Consumers will prefer this function over @unprepare if both are provided.
+	 * The state may be NULL due to the caller not being aware of it.
+	 *
+	 * This function is optional.
+	 */
+	int (*atomic_unprepare)(struct drm_panel *panel,
+			        struct drm_crtc *crtc,
+			        struct drm_atomic_state *state);
+
 	/**
 	 * @get_modes:
 	 *
@@ -330,11 +384,86 @@ void drm_panel_put(struct drm_panel *panel);
 void drm_panel_add(struct drm_panel *panel);
 void drm_panel_remove(struct drm_panel *panel);
 
-void drm_panel_prepare(struct drm_panel *panel);
-void drm_panel_unprepare(struct drm_panel *panel);
+void drm_panel_atomic_prepare(struct drm_panel *panel,
+			      struct drm_crtc *crtc,
+			      struct drm_atomic_state *state);
 
-void drm_panel_enable(struct drm_panel *panel);
-void drm_panel_disable(struct drm_panel *panel);
+/**
+ * drm_panel_prepare - power on a panel
+ * @panel: DRM panel
+ *
+ * Calling this function will enable power and deassert any reset signals to
+ * the panel. After this has completed it is possible to communicate with any
+ * integrated circuitry via a command bus. This function cannot fail (as it is
+ * called from the pre_enable call chain). There will always be a call to
+ * drm_panel_disable() afterwards.
+ *
+ * If atomic commit state is available, call drm_panel_atomic_prepare instead.
+ */
+static inline void drm_panel_prepare(struct drm_panel *panel)
+{
+	drm_panel_atomic_prepare(panel, NULL, NULL);
+}
+
+void drm_panel_atomic_unprepare(struct drm_panel *panel,
+				struct drm_crtc *crtc,
+				struct drm_atomic_state *state);
+
+/**
+ * drm_panel_unprepare - power off a panel
+ * @panel: DRM panel
+ *
+ * Calling this function will completely power off a panel (assert the panel's
+ * reset, turn off power supplies, ...). After this function has completed, it
+ * is usually no longer possible to communicate with the panel until another
+ * call to drm_panel_prepare().
+ *
+ * If atomic commit state is available, call drm_panel_atomic_unprepare instead.
+ */
+static inline void drm_panel_unprepare(struct drm_panel *panel)
+{
+	drm_panel_atomic_unprepare(panel, NULL, NULL);
+}
+
+void drm_panel_atomic_enable(struct drm_panel *panel,
+			     struct drm_crtc *crtc,
+			     struct drm_atomic_state *state);
+
+/**
+ * drm_panel_enable - enable a panel
+ * @panel: DRM panel
+ *
+ * Calling this function will cause the panel display drivers to be turned on
+ * and the backlight to be enabled. Content will be visible on screen after
+ * this call completes. This function cannot fail (as it is called from the
+ * enable call chain). There will always be a call to drm_panel_disable()
+ * afterwards.
+ *
+ * If atomic commit state is available, call drm_panel_atomic_enable instead.
+ */
+static inline void drm_panel_enable(struct drm_panel *panel)
+{
+	drm_panel_atomic_enable(panel, NULL, NULL);
+}
+
+void drm_panel_atomic_disable(struct drm_panel *panel,
+			      struct drm_crtc *crtc,
+			      struct drm_atomic_state *state);
+
+/**
+ * drm_panel_disable - disable a panel
+ * @panel: DRM panel
+ *
+ * This will typically turn off the panel's backlight or disable the display
+ * drivers. For smart panels it should still be possible to communicate with
+ * the integrated circuitry via any command bus after this call.
+ *
+ * If atomic commit state is available, call drm_panel_atomic_disable instead.
+ */
+static inline void drm_panel_disable(struct drm_panel *panel)
+{
+	drm_panel_atomic_disable(panel, NULL, NULL);
+}
 
 int drm_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector);
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] drm/bridge: panel: call the new atomic panel ops
  2026-04-24 23:49 [PATCH 1/2] drm/panel: Add atomic versions of panel ops Val Packett
@ 2026-04-24 23:49 ` Val Packett
  2026-04-25 12:08 ` [PATCH 1/2] drm/panel: Add atomic versions of " Dmitry Baryshkov
  1 sibling, 0 replies; 3+ messages in thread
From: Val Packett @ 2026-04-24 23:49 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter
  Cc: Val Packett, Dmitry Baryshkov, Marijn Suijten, dri-devel,
	~postmarketos/upstreaming, phone-devel, linux-kernel

As the panel API now includes atomic versions of the power ops, call the
new atomic wrappers in order to allow panel drivers to access CRTC state
like the mode being set.

Signed-off-by: Val Packett <val@packett.cool>
---
 drivers/gpu/drm/bridge/panel.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c
index 184a8b7049a7..3d3aca6416d2 100644
--- a/drivers/gpu/drm/bridge/panel.c
+++ b/drivers/gpu/drm/bridge/panel.c
@@ -126,7 +126,7 @@ static void panel_bridge_atomic_pre_enable(struct drm_bridge *bridge,
 	if (old_crtc_state && old_crtc_state->self_refresh_active)
 		return;
 
-	drm_panel_prepare(panel_bridge->panel);
+	drm_panel_atomic_prepare(panel_bridge->panel, crtc, atomic_state);
 }
 
 static void panel_bridge_atomic_enable(struct drm_bridge *bridge,
@@ -145,7 +145,7 @@ static void panel_bridge_atomic_enable(struct drm_bridge *bridge,
 	if (old_crtc_state && old_crtc_state->self_refresh_active)
 		return;
 
-	drm_panel_enable(panel_bridge->panel);
+	drm_panel_atomic_enable(panel_bridge->panel, crtc, atomic_state);
 }
 
 static void panel_bridge_atomic_disable(struct drm_bridge *bridge,
@@ -164,7 +164,7 @@ static void panel_bridge_atomic_disable(struct drm_bridge *bridge,
 	if (new_crtc_state && new_crtc_state->self_refresh_active)
 		return;
 
-	drm_panel_disable(panel_bridge->panel);
+	drm_panel_atomic_disable(panel_bridge->panel, crtc, atomic_state);
 }
 
 static void panel_bridge_atomic_post_disable(struct drm_bridge *bridge,
@@ -183,7 +183,7 @@ static void panel_bridge_atomic_post_disable(struct drm_bridge *bridge,
 	if (new_crtc_state && new_crtc_state->self_refresh_active)
 		return;
 
-	drm_panel_unprepare(panel_bridge->panel);
+	drm_panel_atomic_unprepare(panel_bridge->panel, crtc, atomic_state);
 }
 
 static int panel_bridge_get_modes(struct drm_bridge *bridge,
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/2] drm/panel: Add atomic versions of panel ops
  2026-04-24 23:49 [PATCH 1/2] drm/panel: Add atomic versions of panel ops Val Packett
  2026-04-24 23:49 ` [PATCH 2/2] drm/bridge: panel: call the new atomic " Val Packett
@ 2026-04-25 12:08 ` Dmitry Baryshkov
  1 sibling, 0 replies; 3+ messages in thread
From: Dmitry Baryshkov @ 2026-04-25 12:08 UTC (permalink / raw)
  To: Val Packett
  Cc: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Marijn Suijten,
	dri-devel, ~postmarketos/upstreaming, phone-devel, linux-kernel

On Fri, Apr 24, 2026 at 08:49:50PM -0300, Val Packett wrote:
> Modern DSI panels support various modes (resolutions and refresh rates),
> which usually requires sending mode-specific DCS commands to configure the
> DDIC during operations like prepare(). However existing drm_panel_funcs
> only take the panel itself as an argument, so there's no way to access
> relevant state (such as the mode being set) inside of these functions.
> 
> To allow panel drivers access to the state, introduce new atomic_*
> versions of the prepare/enable/disable/unprepare ops, and make the
> corresponding drm_panel_* functions call them if available, falling back
> to the original ops otherwise. To avoid the need to modify all consumers
> at once, the original single-argument drm_panel_* functions are redefined
> as aliases to the new ones, passing NULLs for the new extra arguments.
> 
> The atomic ops pass the CRTC as well as the atomic state because getting
> the mode being set is part of per-CRTC state.
> 
> Signed-off-by: Val Packett <val@packett.cool>
> ---
> 
> As discussed in my recent RFC [1] and an older thread I was pointed to
> there [2], the right way to expose the mode to panel drivers is to expose
> the entire atomic state and let them find the mode there. (Turns out,
> the drm_crtc must also be passed along with the state as it's necessary
> for drm_atomic_get_new_crtc_state).
> 
> Hopefully this first "real" attempt is close enough! :)
> 
> I have tested this with the WIP nt37701 driver from the linked RFC,
> only slightly updated to receive the new args and not directly the mode.
> 
> [1]: https://lore.kernel.org/all/20260412113851.355944-1-val@packett.cool/
> [2]: https://lore.kernel.org/dri-devel/nfc6ih43gjpi5u67fpkkxgwwygv53grdldq7tfp5iiukrkiy2u@53fsrtezzkyt/
> 
> Thanks,
> ~val
> 
> ---
>  drivers/gpu/drm/drm_panel.c |  88 +++++++++++++++--------
>  include/drm/drm_panel.h     | 137 ++++++++++++++++++++++++++++++++++--
>  2 files changed, 193 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
> index d1e6598ea3bc..48fce5e89bca 100644
> --- a/drivers/gpu/drm/drm_panel.c
> +++ b/drivers/gpu/drm/drm_panel.c
> @@ -102,16 +102,20 @@ void drm_panel_remove(struct drm_panel *panel)
>  EXPORT_SYMBOL(drm_panel_remove);
>  
>  /**
> - * drm_panel_prepare - power on a panel
> + * drm_panel_atomic_prepare - power on a panel
>   * @panel: DRM panel
> + * @crtc: the CRTC used to drive the panel, may be NULL

What does NULL mean here? How would panel's atomic helpers behave if
they receive NULL?

If you want to see a nicer way to migrate to atomic funcs, see
5ade071ba13e ("drm: Add atomic variants for bridge enable/disable").

So, you can't replace drm_panel_foo() with a stub calling
drm_atomic_panel_foo().

> + * @state: current atomic commit state, may be NULL
>   *
>   * Calling this function will enable power and deassert any reset signals to
>   * the panel. After this has completed it is possible to communicate with any
>   * integrated circuitry via a command bus. This function cannot fail (as it is
>   * called from the pre_enable call chain). There will always be a call to
> - * drm_panel_disable() afterwards.
> + * drm_panel_atomic_disable() afterwards.
>   */
> -void drm_panel_prepare(struct drm_panel *panel)
> +void drm_panel_atomic_prepare(struct drm_panel *panel,
> +			      struct drm_crtc *crtc,

Thinking about it... We can have several panels being driven by the same
CRTC. Likewise there can be a lot going on between the CRTC and the
panel. After looking at the code actually calling drm_panel functions,
the only thing that we can easily pass here is the encoder. But then,
there also might be bridges between encoder and the panel. Encoders
don't have state per se.

If the panel needs to identify something, it should be getting the
connector. It might be a more cumbersome, but it sounds like a more
logical option here.

Maxime suggested passing drm_connector_state here instead of the
complete state + connector. I don't have a strong preference here, but I
think that the latter might be slighly more idiomatic nowadays.


> +			      struct drm_atomic_state *state)
>  {
>  	struct drm_panel_follower *follower;
>  	int ret;

[...]

> @@ -330,11 +384,86 @@ void drm_panel_put(struct drm_panel *panel);
>  void drm_panel_add(struct drm_panel *panel);
>  void drm_panel_remove(struct drm_panel *panel);
>  
> -void drm_panel_prepare(struct drm_panel *panel);
> -void drm_panel_unprepare(struct drm_panel *panel);
> +void drm_panel_atomic_prepare(struct drm_panel *panel,
> +			      struct drm_crtc *crtc,
> +			      struct drm_atomic_state *state);
>  
> -void drm_panel_enable(struct drm_panel *panel);
> -void drm_panel_disable(struct drm_panel *panel);
> +/**
> + * drm_panel_prepare - power on a panel
> + * @panel: DRM panel
> + *
> + * Calling this function will enable power and deassert any reset signals to
> + * the panel. After this has completed it is possible to communicate with any
> + * integrated circuitry via a command bus. This function cannot fail (as it is
> + * called from the pre_enable call chain). There will always be a call to
> + * drm_panel_disable() afterwards.
> + *
> + * If atomic commit state is available, call drm_panel_atomic_prepare instead.
> + */
> +static inline void drm_panel_prepare(struct drm_panel *panel)
> +{
> +	drm_panel_atomic_prepare(panel, NULL, NULL);
> +}
> +
> +void drm_panel_atomic_unprepare(struct drm_panel *panel,
> +				struct drm_crtc *crtc,
> +				struct drm_atomic_state *state);
> +
> +/**
> + * drm_panel_unprepare - power off a panel
> + * @panel: DRM panel
> + *
> + * Calling this function will completely power off a panel (assert the panel's
> + * reset, turn off power supplies, ...). After this function has completed, it
> + * is usually no longer possible to communicate with the panel until another
> + * call to drm_panel_prepare().
> + *
> + * If atomic commit state is available, call drm_panel_atomic_unprepare instead.
> + */
> +static inline void drm_panel_unprepare(struct drm_panel *panel)
> +{
> +	drm_panel_atomic_unprepare(panel, NULL, NULL);
> +}
> +
> +void drm_panel_atomic_enable(struct drm_panel *panel,
> +			     struct drm_crtc *crtc,
> +			     struct drm_atomic_state *state);
> +
> +/**
> + * drm_panel_enable - enable a panel
> + * @panel: DRM panel
> + *
> + * Calling this function will cause the panel display drivers to be turned on
> + * and the backlight to be enabled. Content will be visible on screen after
> + * this call completes. This function cannot fail (as it is called from the
> + * enable call chain). There will always be a call to drm_panel_disable()
> + * afterwards.
> + *
> + * If atomic commit state is available, call drm_panel_atomic_enable instead.
> + */
> +static inline void drm_panel_enable(struct drm_panel *panel)
> +{
> +	drm_panel_atomic_enable(panel, NULL, NULL);
> +}
> +
> +void drm_panel_atomic_disable(struct drm_panel *panel,
> +			      struct drm_crtc *crtc,
> +			      struct drm_atomic_state *state);
> +
> +/**
> + * drm_panel_disable - disable a panel
> + * @panel: DRM panel
> + *
> + * This will typically turn off the panel's backlight or disable the display
> + * drivers. For smart panels it should still be possible to communicate with
> + * the integrated circuitry via any command bus after this call.
> + *
> + * If atomic commit state is available, call drm_panel_atomic_disable instead.
> + */
> +static inline void drm_panel_disable(struct drm_panel *panel)
> +{
> +	drm_panel_atomic_disable(panel, NULL, NULL);
> +}
>  
>  int drm_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector);
>  
> -- 
> 2.53.0
> 

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-04-25 12:08 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-24 23:49 [PATCH 1/2] drm/panel: Add atomic versions of panel ops Val Packett
2026-04-24 23:49 ` [PATCH 2/2] drm/bridge: panel: call the new atomic " Val Packett
2026-04-25 12:08 ` [PATCH 1/2] drm/panel: Add atomic versions of " Dmitry Baryshkov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox