[PATCH v2] drm/mediatek: Call drm_atomic_helper_shutdown() at shutdown time

2024-06-11 Thread Douglas Anderson
Based on grepping through the source code this driver appears to be
missing a call to drm_atomic_helper_shutdown() at system shutdown
time. Among other things, this means that if a panel is in use that it
won't be cleanly powered off at system shutdown time.

The fact that we should call drm_atomic_helper_shutdown() in the case
of OS shutdown/restart comes straight out of the kernel doc "driver
instance overview" in drm_drv.c.

This driver users the component model and shutdown happens in the base
driver. The "drvdata" for this driver will always be valid if
shutdown() is called and as of commit 2a073968289d
("drm/atomic-helper: drm_atomic_helper_shutdown(NULL) should be a
noop") we don't need to confirm that "drm" is non-NULL.

Suggested-by: Maxime Ripard 
Reviewed-by: Maxime Ripard 
Reviewed-by: Fei Shao 
Tested-by: Fei Shao 
Signed-off-by: Douglas Anderson 
---
v1 of this patch was part of a series [1]. It got tested and reviewed
but never landed. Reposting separately in the hopes that Mediatek DRM
folks will land it. If, instead, Mediatek DRM folks want to Ack it I'm
happy to land through drm-misc.

I noticed that this was missing when I failed to add "mediatek" to my
patch series IDing which DRM modeset drivers did this properly [2].
Assuming my patch lands, that means that Mediatek devices will start
getting more warnings printed.

[1] 
https://lore.kernel.org/r/20230901164111.RFT.5.I2b014f90afc4729b6ecc7b5ddd1f6dedcea4625b@changeid
[2] 
https://lore.kernel.org/r/20240611074846.1.Ieb287c2c3ee3f6d3b0d5f49b29f746b93621749c@changeid

Changes in v2:
- Removed NULL check since it's not needed since 6.7
- Rebased on ToT.

 drivers/gpu/drm/mediatek/mtk_drm_drv.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index b5f605751b0a..de811e2265da 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -952,6 +952,13 @@ static void mtk_drm_remove(struct platform_device *pdev)
of_node_put(private->comp_node[i]);
 }
 
+static void mtk_drm_shutdown(struct platform_device *pdev)
+{
+   struct mtk_drm_private *private = platform_get_drvdata(pdev);
+
+   drm_atomic_helper_shutdown(private->drm);
+}
+
 static int mtk_drm_sys_prepare(struct device *dev)
 {
struct mtk_drm_private *private = dev_get_drvdata(dev);
@@ -983,6 +990,7 @@ static const struct dev_pm_ops mtk_drm_pm_ops = {
 static struct platform_driver mtk_drm_platform_driver = {
.probe  = mtk_drm_probe,
.remove_new = mtk_drm_remove,
+   .shutdown = mtk_drm_shutdown,
.driver = {
.name   = "mediatek-drm",
.pm = _drm_pm_ops,
-- 
2.45.2.505.gda0bf45e8d-goog



[PATCH] drm/panel: Avoid warnings w/ panel-simple/panel-edp at shutdown

2024-06-11 Thread Douglas Anderson
At shutdown if you've got a _properly_ coded DRM modeset driver then
you'll get these two warnings at shutdown time:

  Skipping disable of already disabled panel
  Skipping unprepare of already unprepared panel

These warnings are ugly and sound concerning, but they're actually a
sign of a properly working system. That's not great.

It's not easy to get rid of these warnings. Until we know that all DRM
modeset drivers used with panel-simple and panel-edp are properly
calling drm_atomic_helper_shutdown() or drm_helper_force_disable_all()
then the panel drivers _need_ to disable/unprepare themselves in order
to power off the panel cleanly. However, there are lots of DRM modeset
drivers used with panel-edp and panel-simple and it's hard to know
when we've got them all. Since the warning happens only on the drivers
that _are_ updated there's nothing to encourage broken DRM modeset
drivers to get fixed.

In order to flip the warning to the proper place, we need to know
which modeset drivers are going to shutdown properly. Though ugly, do
this by creating a list of everyone that shuts down properly. This
allows us to generate a warning for the correct case and also lets us
get rid of the warning for drivers that are shutting down properly.

Maintaining this list is ugly, but the idea is that it's only short
term. Once everyone is converted we can delete the list and call it
done. The list is ugly enough and adding to it is annoying enough that
people should push to make this happen.

Implement this all in a shared "header" file included by the two panel
drivers that need it. This avoids us adding an new exports while still
allowing the panel drivers to be modules. The code waste should be
small and, as per above, the whole solution is temporary.

Signed-off-by: Douglas Anderson 
---
I came up with this idea to help us move forward since otherwise I
couldn't see how we were ever going to fix panel-simple and panel-edp
since they're used by so many DRM Modeset drivers. It's a bit ugly but
I don't hate it. What do others think?

This is at the end of the series so even if folks hate it we could
still land the rest of the series.
This was a "bonus" extra patch I added at the end of v3 of the series
("drm/panel: Remove most store/double-check of prepared/enabled
state") [1]. There, I had the note: "I came up with this idea to help
us move forward since otherwise I couldn't see how we were ever going
to fix panel-simple and panel-edp since they're used by so many DRM
Modeset drivers. It's a bit ugly but I don't hate it. What do others
think?"

As requested by Neil, now that the rest of the series has landed I'm
sending this as a standalone patch so it can get more attention. I'm
starting it back at "v1". There is no change between v1 and the one
sent previously except for a typo fix in an error message: Can't't =>
Can't

[1] https://lore.kernel.org/r/20240605002401.2848541-1-diand...@chromium.org

 drivers/gpu/drm/drm_panel.c   |  12 ++
 .../gpu/drm/panel/panel-drm-shutdown-check.h  | 151 ++
 drivers/gpu/drm/panel/panel-edp.c |  19 +--
 drivers/gpu/drm/panel/panel-simple.c  |  19 +--
 4 files changed, 169 insertions(+), 32 deletions(-)
 create mode 100644 drivers/gpu/drm/panel/panel-drm-shutdown-check.h

diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
index cfbe020de54e..df3f15f4625e 100644
--- a/drivers/gpu/drm/drm_panel.c
+++ b/drivers/gpu/drm/drm_panel.c
@@ -161,6 +161,12 @@ int drm_panel_unprepare(struct drm_panel *panel)
if (!panel)
return -EINVAL;
 
+   /*
+* If you're seeing this warning, you either need to add your driver
+* to "drm_drivers_that_shutdown" (if you're seeing it with panel-edp
+* or panel-simple) or you need to remove the manual call to
+* drm_panel_unprepare() in your panel driver.
+*/
if (!panel->prepared) {
dev_warn(panel->dev, "Skipping unprepare of already unprepared 
panel\n");
return 0;
@@ -245,6 +251,12 @@ int drm_panel_disable(struct drm_panel *panel)
if (!panel)
return -EINVAL;
 
+   /*
+* If you're seeing this warning, you either need to add your driver
+* to "drm_drivers_that_shutdown" (if you're seeing it with panel-edp
+* or panel-simple) or you need to remove the manual call to
+* drm_panel_disable() in your panel driver.
+*/
if (!panel->enabled) {
dev_warn(panel->dev, "Skipping disable of already disabled 
panel\n");
return 0;
diff --git a/drivers/gpu/drm/panel/panel-drm-shutdown-check.h 
b/drivers/gpu/drm/panel/panel-drm-shutdown-check.h
new file mode 100644
index ..dfa8197e09fb
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-drm-shutdown-check.h
@@ -0,0 +1,151 @@
+/* SPDX-Lice

[PATCH v3 21/24] drm/panel: raydium-rm67191: Stop tracking enabled

2024-06-04 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

The conversion of the rm67191 panel driver follows many of the other
panel drivers but has a few differences that need to be called out.

Like in commit 1e0465eb16a4 ("drm/panel: otm8009a: Don't double check
prepared/enabled"), this panel also uses the "prepared" flag to
prevent the backlight functions from running when the panel is powered
off. This is probably not the safest thing to do but the old behavior
was preserved. See the discussion in the otm8009a patch. Because of
this, I've left the driver tracking "prepared" but removed its
tracking of "enabled".

NOTE: as part of this, transition the panel's direct calls to its
disable/unprepare functions in shutdown to call through DRM panel.

Cc: Robert Chiras 
Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---

(no changes since v2)

Changes in v2:
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-raydium-rm67191.c | 21 ++-
 1 file changed, 2 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-raydium-rm67191.c 
b/drivers/gpu/drm/panel/panel-raydium-rm67191.c
index dbb1ed4efbed..fa9bf89d3bb5 100644
--- a/drivers/gpu/drm/panel/panel-raydium-rm67191.c
+++ b/drivers/gpu/drm/panel/panel-raydium-rm67191.c
@@ -205,7 +205,6 @@ struct rad_panel {
unsigned int num_supplies;
 
bool prepared;
-   bool enabled;
 };
 
 static const struct drm_display_mode default_mode = {
@@ -267,9 +266,6 @@ static int rad_panel_prepare(struct drm_panel *panel)
struct rad_panel *rad = to_rad_panel(panel);
int ret;
 
-   if (rad->prepared)
-   return 0;
-
ret = regulator_bulk_enable(rad->num_supplies, rad->supplies);
if (ret)
return ret;
@@ -291,9 +287,6 @@ static int rad_panel_unprepare(struct drm_panel *panel)
struct rad_panel *rad = to_rad_panel(panel);
int ret;
 
-   if (!rad->prepared)
-   return 0;
-
/*
 * Right after asserting the reset, we need to release it, so that the
 * touch driver can have an active connection with the touch controller
@@ -322,9 +315,6 @@ static int rad_panel_enable(struct drm_panel *panel)
int color_format = color_format_from_dsi_format(dsi->format);
int ret;
 
-   if (rad->enabled)
-   return 0;
-
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
 
ret = rad_panel_push_cmd_list(dsi);
@@ -389,8 +379,6 @@ static int rad_panel_enable(struct drm_panel *panel)
 
backlight_enable(rad->backlight);
 
-   rad->enabled = true;
-
return 0;
 
 fail:
@@ -406,9 +394,6 @@ static int rad_panel_disable(struct drm_panel *panel)
struct device *dev = >dev;
int ret;
 
-   if (!rad->enabled)
-   return 0;
-
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
 
backlight_disable(rad->backlight);
@@ -429,8 +414,6 @@ static int rad_panel_disable(struct drm_panel *panel)
return ret;
}
 
-   rad->enabled = false;
-
return 0;
 }
 
@@ -633,8 +616,8 @@ static void rad_panel_shutdown(struct mipi_dsi_device *dsi)
 {
struct rad_panel *rad = mipi_dsi_get_drvdata(dsi);
 
-   rad_panel_disable(>panel);
-   rad_panel_unprepare(>panel);
+   drm_panel_disable(>panel);
+   drm_panel_unprepare(>panel);
 }
 
 static const struct of_device_id rad_of_match[] = {
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 23/24] drm/panel: Update TODO list item for cleaning up prepared/enabled tracking

2024-06-04 Thread Douglas Anderson
Now that most panels have been updated not to track/double-check their
prepared/enabled state update the TODO with next steps.

Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---

(no changes since v1)

 Documentation/gpu/todo.rst | 47 +-
 1 file changed, 26 insertions(+), 21 deletions(-)

diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index 2734b8a34541..2ea6ffc9b22b 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -469,30 +469,35 @@ Contact: Thomas Zimmermann 
 
 Level: Starter
 
-Clean up checks for already prepared/enabled in panels
---
-
-In a whole pile of panel drivers, we have code to make the
-prepare/unprepare/enable/disable callbacks behave as no-ops if they've already
-been called. To get some idea of the duplicated code, try::
-
-  git grep 'if.*>prepared' -- drivers/gpu/drm/panel
-  git grep 'if.*>enabled' -- drivers/gpu/drm/panel
-
-In the patch ("drm/panel: Check for already prepared/enabled in drm_panel")
-we've moved this check to the core. Now we can most definitely remove the
-check from the individual panels and save a pile of code.
-
-In adition to removing the check from the individual panels, it is believed
-that even the core shouldn't need this check and that should be considered
-an error if other code ever relies on this check. The check in the core
-currently prints a warning whenever something is relying on this check with
-dev_warn(). After a little while, we likely want to promote this to a
-WARN(1) to help encourage folks not to rely on this behavior.
+Remove disable/unprepare in remove/shutdown in panel-simple and panel-edp
+-
+
+As of commit d2aacaf07395 ("drm/panel: Check for already prepared/enabled in
+drm_panel"), we have a check in the drm_panel core to make sure nobody
+double-calls prepare/enable/disable/unprepare. Eventually that should probably
+be turned into a WARN_ON() or somehow made louder, but right now we actually
+expect it to trigger and so we don't want it to be too loud.
+
+Specifically, that warning will trigger for panel-edp and panel-simple at
+shutdown time because those panels hardcode a call to drm_panel_disable()
+and drm_panel_unprepare() at shutdown and remove time that they call regardless
+of panel state. On systems with a properly coded DRM modeset driver that
+calls drm_atomic_helper_shutdown() this is pretty much guaranteed to cause
+the warning to fire.
+
+Unfortunately we can't safely remove the calls in panel-edp and panel-simple
+until we're sure that all DRM modeset drivers that are used with those panels
+properly call drm_atomic_helper_shutdown(). This TODO item is to validate
+that all DRM modeset drivers used with panel-edp and panel-simple properly
+call drm_atomic_helper_shutdown() and then remove the calls to
+disable/unprepare from those panels. Alternatively, this TODO item could be
+removed by convincing stakeholders that those calls are fine and downgrading
+the error message in drm_panel_disable() / drm_panel_unprepare() to a
+debug-level message.
 
 Contact: Douglas Anderson 
 
-Level: Starter/Intermediate
+Level: Intermediate
 
 Transition away from using mipi_dsi_*_write_seq()
 -
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 22/24] drm/panel: raydium-rm67191: Don't call unprepare+disable at shutdown

2024-06-04 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

A grep through mainline for compatible strings used by this driver
indicates that it is used by IMX boards. The IMX driver appears to be
correctly calling drm_atomic_helper_shutdown() so we can remove the
calls.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Robert Chiras 
Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---

(no changes since v2)

Changes in v2:
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-raydium-rm67191.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-raydium-rm67191.c 
b/drivers/gpu/drm/panel/panel-raydium-rm67191.c
index fa9bf89d3bb5..b2029e035635 100644
--- a/drivers/gpu/drm/panel/panel-raydium-rm67191.c
+++ b/drivers/gpu/drm/panel/panel-raydium-rm67191.c
@@ -612,14 +612,6 @@ static void rad_panel_remove(struct mipi_dsi_device *dsi)
drm_panel_remove(>panel);
 }
 
-static void rad_panel_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct rad_panel *rad = mipi_dsi_get_drvdata(dsi);
-
-   drm_panel_disable(>panel);
-   drm_panel_unprepare(>panel);
-}
-
 static const struct of_device_id rad_of_match[] = {
{ .compatible = "raydium,rm67191", },
{ /* sentinel */ }
@@ -633,7 +625,6 @@ static struct mipi_dsi_driver rad_panel_driver = {
},
.probe = rad_panel_probe,
.remove = rad_panel_remove,
-   .shutdown = rad_panel_shutdown,
 };
 module_mipi_dsi_driver(rad_panel_driver);
 
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 24/24] drm/panel: Avoid warnings w/ panel-simple/panel-edp at shutdown

2024-06-04 Thread Douglas Anderson
At shutdown if you've got a _properly_ coded DRM modeset driver then
you'll get these two warnings at shutdown time:

  Skipping disable of already disabled panel
  Skipping unprepare of already unprepared panel

These warnings are ugly and sound concerning, but they're actually a
sign of a properly working system. That's not great.

It's not easy to get rid of these warnings. Until we know that all DRM
modeset drivers used with panel-simple and panel-edp are properly
calling drm_atomic_helper_shutdown() or drm_helper_force_disable_all()
then the panel drivers _need_ to disable/unprepare themselves in order
to power off the panel cleanly. However, there are lots of DRM modeset
drivers used with panel-edp and panel-simple and it's hard to know
when we've got them all. Since the warning happens only on the drivers
that _are_ updated there's nothing to encourage broken DRM modeset
drivers to get fixed.

In order to flip the warning to the proper place, we need to know
which modeset drivers are going to shutdown properly. Though ugly, do
this by creating a list of everyone that shuts down properly. This
allows us to generate a warning for the correct case and also lets us
get rid of the warning for drivers that are shutting down properly.

Maintaining this list is ugly, but the idea is that it's only short
term. Once everyone is converted we can delete the list and call it
done. The list is ugly enough and adding to it is annoying enough that
people should push to make this happen.

Implement this all in a shared "header" file included by the two panel
drivers that need it. This avoids us adding an new exports while still
allowing the panel drivers to be modules. The code waste should be
small and, as per above, the whole solution is temporary.

Signed-off-by: Douglas Anderson 
---
I came up with this idea to help us move forward since otherwise I
couldn't see how we were ever going to fix panel-simple and panel-edp
since they're used by so many DRM Modeset drivers. It's a bit ugly but
I don't hate it. What do others think?

This is at the end of the series so even if folks hate it we could
still land the rest of the series.

Changes in v3:
- New

 drivers/gpu/drm/drm_panel.c   |  12 ++
 .../gpu/drm/panel/panel-drm-shutdown-check.h  | 151 ++
 drivers/gpu/drm/panel/panel-edp.c |  19 +--
 drivers/gpu/drm/panel/panel-simple.c  |  19 +--
 4 files changed, 169 insertions(+), 32 deletions(-)
 create mode 100644 drivers/gpu/drm/panel/panel-drm-shutdown-check.h

diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
index cfbe020de54e..df3f15f4625e 100644
--- a/drivers/gpu/drm/drm_panel.c
+++ b/drivers/gpu/drm/drm_panel.c
@@ -161,6 +161,12 @@ int drm_panel_unprepare(struct drm_panel *panel)
if (!panel)
return -EINVAL;
 
+   /*
+* If you're seeing this warning, you either need to add your driver
+* to "drm_drivers_that_shutdown" (if you're seeing it with panel-edp
+* or panel-simple) or you need to remove the manual call to
+* drm_panel_unprepare() in your panel driver.
+*/
if (!panel->prepared) {
dev_warn(panel->dev, "Skipping unprepare of already unprepared 
panel\n");
return 0;
@@ -245,6 +251,12 @@ int drm_panel_disable(struct drm_panel *panel)
if (!panel)
return -EINVAL;
 
+   /*
+* If you're seeing this warning, you either need to add your driver
+* to "drm_drivers_that_shutdown" (if you're seeing it with panel-edp
+* or panel-simple) or you need to remove the manual call to
+* drm_panel_disable() in your panel driver.
+*/
if (!panel->enabled) {
dev_warn(panel->dev, "Skipping disable of already disabled 
panel\n");
return 0;
diff --git a/drivers/gpu/drm/panel/panel-drm-shutdown-check.h 
b/drivers/gpu/drm/panel/panel-drm-shutdown-check.h
new file mode 100644
index ..b5164490d6e7
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-drm-shutdown-check.h
@@ -0,0 +1,151 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2024 Google Inc.
+ *
+ * This header is a temporary solution and is intended to be included
+ * directly by panel-edp.c and panel-simple.c.
+ *
+ * This header is needed because panel-edp and panel-simple are used by a
+ * wide variety of DRM drivers and it's hard to know for sure if all of the
+ * DRM drivers used by those panel drivers are properly calling
+ * drm_atomic_helper_shutdown() or drm_helper_force_disable_all() at
+ * shutdown/remove time.
+ *
+ * The plan for this header file:
+ * - Land it and hope that the warning print will encourage DRM drivers to
+ *   get fixed.
+ * - Eventually move to a WARN() splat for extra encouragement.
+ * - Assume that everyone has been fixed and remove this header file.
+ */
+
+#ifndef __PANEL_

[PATCH v3 20/24] drm/panel: sharp-ls043t1le01: Don't call disable at shutdown/remove

2024-06-04 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

A grep through mainline for compatible strings used by this driver
indicates that it is used by Qualcomm boards. The Qualcomm driver
appears to be correctly calling drm_atomic_helper_shutdown() so we can
remove the calls.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Werner Johansson 
Cc: Dmitry Baryshkov 
Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---

(no changes since v2)

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c 
b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
index c86337954ad7..729cbb0d8403 100644
--- a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
+++ b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
@@ -267,10 +267,6 @@ static void sharp_nt_panel_remove(struct mipi_dsi_device 
*dsi)
struct sharp_nt_panel *sharp_nt = mipi_dsi_get_drvdata(dsi);
int ret;
 
-   ret = drm_panel_disable(_nt->base);
-   if (ret < 0)
-   dev_err(>dev, "failed to disable panel: %d\n", ret);
-
ret = mipi_dsi_detach(dsi);
if (ret < 0)
dev_err(>dev, "failed to detach from DSI host: %d\n", ret);
@@ -278,13 +274,6 @@ static void sharp_nt_panel_remove(struct mipi_dsi_device 
*dsi)
sharp_nt_panel_del(sharp_nt);
 }
 
-static void sharp_nt_panel_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct sharp_nt_panel *sharp_nt = mipi_dsi_get_drvdata(dsi);
-
-   drm_panel_disable(_nt->base);
-}
-
 static const struct of_device_id sharp_nt_of_match[] = {
{ .compatible = "sharp,ls043t1le01-qhd", },
{ }
@@ -298,7 +287,6 @@ static struct mipi_dsi_driver sharp_nt_panel_driver = {
},
.probe = sharp_nt_panel_probe,
.remove = sharp_nt_panel_remove,
-   .shutdown = sharp_nt_panel_shutdown,
 };
 module_mipi_dsi_driver(sharp_nt_panel_driver);
 
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 19/24] drm/panel: sharp-ls043t1le01: Stop tracking prepared

2024-06-04 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Cc: Werner Johansson 
Cc: Dmitry Baryshkov 
Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---

(no changes since v2)

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c 
b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
index 855e6daa..c86337954ad7 100644
--- a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
+++ b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
@@ -26,8 +26,6 @@ struct sharp_nt_panel {
 
struct regulator *supply;
struct gpio_desc *reset_gpio;
-
-   bool prepared;
 };
 
 static inline struct sharp_nt_panel *to_sharp_nt_panel(struct drm_panel *panel)
@@ -99,9 +97,6 @@ static int sharp_nt_panel_unprepare(struct drm_panel *panel)
struct sharp_nt_panel *sharp_nt = to_sharp_nt_panel(panel);
int ret;
 
-   if (!sharp_nt->prepared)
-   return 0;
-
ret = sharp_nt_panel_off(sharp_nt);
if (ret < 0) {
dev_err(panel->dev, "failed to set panel off: %d\n", ret);
@@ -112,8 +107,6 @@ static int sharp_nt_panel_unprepare(struct drm_panel *panel)
if (sharp_nt->reset_gpio)
gpiod_set_value(sharp_nt->reset_gpio, 0);
 
-   sharp_nt->prepared = false;
-
return 0;
 }
 
@@ -122,9 +115,6 @@ static int sharp_nt_panel_prepare(struct drm_panel *panel)
struct sharp_nt_panel *sharp_nt = to_sharp_nt_panel(panel);
int ret;
 
-   if (sharp_nt->prepared)
-   return 0;
-
ret = regulator_enable(sharp_nt->supply);
if (ret < 0)
return ret;
@@ -152,8 +142,6 @@ static int sharp_nt_panel_prepare(struct drm_panel *panel)
goto poweroff;
}
 
-   sharp_nt->prepared = true;
-
return 0;
 
 poweroff:
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 17/24] drm/panel: sharp-lq101r1sx01: Stop tracking prepared/enabled

2024-06-04 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Cc: Thierry Reding 
Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---

(no changes since v2)

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 .../gpu/drm/panel/panel-sharp-lq101r1sx01.c   | 39 ---
 1 file changed, 39 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c 
b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
index 14851408a5e1..8f6c21b99522 100644
--- a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
+++ b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
@@ -24,9 +24,6 @@ struct sharp_panel {
 
struct regulator *supply;
 
-   bool prepared;
-   bool enabled;
-
const struct drm_display_mode *mode;
 };
 
@@ -85,26 +82,11 @@ static __maybe_unused int sharp_panel_read(struct 
sharp_panel *sharp,
return err;
 }
 
-static int sharp_panel_disable(struct drm_panel *panel)
-{
-   struct sharp_panel *sharp = to_sharp_panel(panel);
-
-   if (!sharp->enabled)
-   return 0;
-
-   sharp->enabled = false;
-
-   return 0;
-}
-
 static int sharp_panel_unprepare(struct drm_panel *panel)
 {
struct sharp_panel *sharp = to_sharp_panel(panel);
int err;
 
-   if (!sharp->prepared)
-   return 0;
-
sharp_wait_frames(sharp, 4);
 
err = mipi_dsi_dcs_set_display_off(sharp->link1);
@@ -119,8 +101,6 @@ static int sharp_panel_unprepare(struct drm_panel *panel)
 
regulator_disable(sharp->supply);
 
-   sharp->prepared = false;
-
return 0;
 }
 
@@ -164,9 +144,6 @@ static int sharp_panel_prepare(struct drm_panel *panel)
u8 format = MIPI_DCS_PIXEL_FMT_24BIT;
int err;
 
-   if (sharp->prepared)
-   return 0;
-
err = regulator_enable(sharp->supply);
if (err < 0)
return err;
@@ -235,8 +212,6 @@ static int sharp_panel_prepare(struct drm_panel *panel)
goto poweroff;
}
 
-   sharp->prepared = true;
-
/* wait for 6 frames before continuing */
sharp_wait_frames(sharp, 6);
 
@@ -247,18 +222,6 @@ static int sharp_panel_prepare(struct drm_panel *panel)
return err;
 }
 
-static int sharp_panel_enable(struct drm_panel *panel)
-{
-   struct sharp_panel *sharp = to_sharp_panel(panel);
-
-   if (sharp->enabled)
-   return 0;
-
-   sharp->enabled = true;
-
-   return 0;
-}
-
 static const struct drm_display_mode default_mode = {
.clock = 278000,
.hdisplay = 2560,
@@ -295,10 +258,8 @@ static int sharp_panel_get_modes(struct drm_panel *panel,
 }
 
 static const struct drm_panel_funcs sharp_panel_funcs = {
-   .disable = sharp_panel_disable,
.unprepare = sharp_panel_unprepare,
.prepare = sharp_panel_prepare,
-   .enable = sharp_panel_enable,
.get_modes = sharp_panel_get_modes,
 };
 
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 18/24] drm/panel: sharp-lq101r1sx01: Don't call disable at shutdown/remove

2024-06-04 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

A grep through mainline for compatible strings used by this driver
indicates that it is used by Tegra boards. The Tegra driver appears to
be correctly calling drm_atomic_helper_shutdown() so we can remove the
calls.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Thierry Reding 
Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---

(no changes since v2)

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 .../gpu/drm/panel/panel-sharp-lq101r1sx01.c   | 24 ++-
 1 file changed, 2 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c 
b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
index 8f6c21b99522..edc9425bb143 100644
--- a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
+++ b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
@@ -357,32 +357,13 @@ static void sharp_panel_remove(struct mipi_dsi_device 
*dsi)
struct sharp_panel *sharp = mipi_dsi_get_drvdata(dsi);
int err;
 
-   /* only detach from host for the DSI-LINK2 interface */
-   if (!sharp) {
-   mipi_dsi_detach(dsi);
-   return;
-   }
-
-   err = drm_panel_disable(>base);
-   if (err < 0)
-   dev_err(>dev, "failed to disable panel: %d\n", err);
-
err = mipi_dsi_detach(dsi);
if (err < 0)
dev_err(>dev, "failed to detach from DSI host: %d\n", err);
 
-   sharp_panel_del(sharp);
-}
-
-static void sharp_panel_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct sharp_panel *sharp = mipi_dsi_get_drvdata(dsi);
-
-   /* nothing to do for DSI-LINK2 */
+   /* only detach from host for the DSI-LINK2 interface */
if (!sharp)
-   return;
-
-   drm_panel_disable(>base);
+   sharp_panel_del(sharp);
 }
 
 static struct mipi_dsi_driver sharp_panel_driver = {
@@ -392,7 +373,6 @@ static struct mipi_dsi_driver sharp_panel_driver = {
},
.probe = sharp_panel_probe,
.remove = sharp_panel_remove,
-   .shutdown = sharp_panel_shutdown,
 };
 module_mipi_dsi_driver(sharp_panel_driver);
 
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 13/24] drm/panel: panasonic-vvx10f034n00: Stop tracking prepared/enabled

2024-06-04 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Cc: Werner Johansson 
Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---

(no changes since v2)

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 .../drm/panel/panel-panasonic-vvx10f034n00.c  | 35 +--
 1 file changed, 1 insertion(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c 
b/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c
index 8ba6d8287938..822ca2f971eb 100644
--- a/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c
+++ b/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c
@@ -32,9 +32,6 @@ struct wuxga_nt_panel {
 
struct regulator *supply;
 
-   bool prepared;
-   bool enabled;
-
ktime_t earliest_wake;
 
const struct drm_display_mode *mode;
@@ -53,28 +50,16 @@ static int wuxga_nt_panel_on(struct wuxga_nt_panel 
*wuxga_nt)
 static int wuxga_nt_panel_disable(struct drm_panel *panel)
 {
struct wuxga_nt_panel *wuxga_nt = to_wuxga_nt_panel(panel);
-   int mipi_ret, bl_ret = 0;
-
-   if (!wuxga_nt->enabled)
-   return 0;
-
-   mipi_ret = mipi_dsi_shutdown_peripheral(wuxga_nt->dsi);
-
-   wuxga_nt->enabled = false;
 
-   return mipi_ret ? mipi_ret : bl_ret;
+   return mipi_dsi_shutdown_peripheral(wuxga_nt->dsi);
 }
 
 static int wuxga_nt_panel_unprepare(struct drm_panel *panel)
 {
struct wuxga_nt_panel *wuxga_nt = to_wuxga_nt_panel(panel);
 
-   if (!wuxga_nt->prepared)
-   return 0;
-
regulator_disable(wuxga_nt->supply);
wuxga_nt->earliest_wake = ktime_add_ms(ktime_get_real(), MIN_POFF_MS);
-   wuxga_nt->prepared = false;
 
return 0;
 }
@@ -85,9 +70,6 @@ static int wuxga_nt_panel_prepare(struct drm_panel *panel)
int ret;
s64 enablewait;
 
-   if (wuxga_nt->prepared)
-   return 0;
-
/*
 * If the user re-enabled the panel before the required off-time then
 * we need to wait the remaining period before re-enabling regulator
@@ -117,8 +99,6 @@ static int wuxga_nt_panel_prepare(struct drm_panel *panel)
goto poweroff;
}
 
-   wuxga_nt->prepared = true;
-
return 0;
 
 poweroff:
@@ -127,18 +107,6 @@ static int wuxga_nt_panel_prepare(struct drm_panel *panel)
return ret;
 }
 
-static int wuxga_nt_panel_enable(struct drm_panel *panel)
-{
-   struct wuxga_nt_panel *wuxga_nt = to_wuxga_nt_panel(panel);
-
-   if (wuxga_nt->enabled)
-   return 0;
-
-   wuxga_nt->enabled = true;
-
-   return 0;
-}
-
 static const struct drm_display_mode default_mode = {
.clock = 164402,
.hdisplay = 1920,
@@ -178,7 +146,6 @@ static const struct drm_panel_funcs wuxga_nt_panel_funcs = {
.disable = wuxga_nt_panel_disable,
.unprepare = wuxga_nt_panel_unprepare,
.prepare = wuxga_nt_panel_prepare,
-   .enable = wuxga_nt_panel_enable,
.get_modes = wuxga_nt_panel_get_modes,
 };
 
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 16/24] drm/panel: seiko-43wvf1g: Don't call disable at shutdown/remove

2024-06-04 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

A grep through mainline for compatible strings used by this driver
indicates that it is used by IMX boards. As far as I can tell, all IMX
boards are now correctly calling drm_atomic_helper_shutdown() so we
can remove the calls.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Marco Franchi 
Cc: Fabio Estevam 
Cc: Laurentiu Palcu 
Cc: Pengutronix Kernel Team 
Cc: i...@lists.linux.dev
Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---

(no changes since v2)

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-seiko-43wvf1g.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c 
b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c
index 98480904126c..8a3fe531c641 100644
--- a/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c
+++ b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c
@@ -243,14 +243,6 @@ static void seiko_panel_remove(struct platform_device 
*pdev)
struct seiko_panel *panel = platform_get_drvdata(pdev);
 
drm_panel_remove(>base);
-   drm_panel_disable(>base);
-}
-
-static void seiko_panel_shutdown(struct platform_device *pdev)
-{
-   struct seiko_panel *panel = platform_get_drvdata(pdev);
-
-   drm_panel_disable(>base);
 }
 
 static const struct display_timing seiko_43wvf1g_timing = {
@@ -306,7 +298,6 @@ static struct platform_driver seiko_panel_platform_driver = 
{
},
.probe = seiko_panel_platform_probe,
.remove_new = seiko_panel_remove,
-   .shutdown = seiko_panel_shutdown,
 };
 module_platform_driver(seiko_panel_platform_driver);
 
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 14/24] drm/panel: panasonic-vvx10f034n00: Don't call disable at shutdown/remove

2024-06-04 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

Unfortunately, grepping mainline for this panel's compatible string
shows no hits, so we can't be 100% sure if the DRM modeset driver used
with this panel has been fixed. If it is found that the DRM modeset
driver hasn't been fixed then this patch could be temporarily reverted
until it is.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Werner Johansson 
Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---

(no changes since v2)

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c 
b/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c
index 822ca2f971eb..d1c5c9bc3c56 100644
--- a/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c
+++ b/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c
@@ -222,10 +222,6 @@ static void wuxga_nt_panel_remove(struct mipi_dsi_device 
*dsi)
struct wuxga_nt_panel *wuxga_nt = mipi_dsi_get_drvdata(dsi);
int ret;
 
-   ret = drm_panel_disable(_nt->base);
-   if (ret < 0)
-   dev_err(>dev, "failed to disable panel: %d\n", ret);
-
ret = mipi_dsi_detach(dsi);
if (ret < 0)
dev_err(>dev, "failed to detach from DSI host: %d\n", ret);
@@ -233,13 +229,6 @@ static void wuxga_nt_panel_remove(struct mipi_dsi_device 
*dsi)
wuxga_nt_panel_del(wuxga_nt);
 }
 
-static void wuxga_nt_panel_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct wuxga_nt_panel *wuxga_nt = mipi_dsi_get_drvdata(dsi);
-
-   drm_panel_disable(_nt->base);
-}
-
 static struct mipi_dsi_driver wuxga_nt_panel_driver = {
.driver = {
.name = "panel-panasonic-vvx10f034n00",
@@ -247,7 +236,6 @@ static struct mipi_dsi_driver wuxga_nt_panel_driver = {
},
.probe = wuxga_nt_panel_probe,
.remove = wuxga_nt_panel_remove,
-   .shutdown = wuxga_nt_panel_shutdown,
 };
 module_mipi_dsi_driver(wuxga_nt_panel_driver);
 
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 12/24] drm/panel: jdi-lt070me05000: Don't call disable at shutdown/remove

2024-06-04 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

A grep through mainline for compatible strings used by this driver
indicates that it is used by Qualcomm boards. The Qualcomm driver
appears to be correctly calling drm_atomic_helper_shutdown() so we can
remove the calls.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Vinay Simha BN 
Cc: Sumit Semwal 
Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---

(no changes since v2)

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-jdi-lt070me05000.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c 
b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
index 4ee6fa1e..b1ce186de261 100644
--- a/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
+++ b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
@@ -452,10 +452,6 @@ static void jdi_panel_remove(struct mipi_dsi_device *dsi)
struct jdi_panel *jdi = mipi_dsi_get_drvdata(dsi);
int ret;
 
-   ret = drm_panel_disable(>base);
-   if (ret < 0)
-   dev_err(>dev, "failed to disable panel: %d\n", ret);
-
ret = mipi_dsi_detach(dsi);
if (ret < 0)
dev_err(>dev, "failed to detach from DSI host: %d\n",
@@ -464,13 +460,6 @@ static void jdi_panel_remove(struct mipi_dsi_device *dsi)
jdi_panel_del(jdi);
 }
 
-static void jdi_panel_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct jdi_panel *jdi = mipi_dsi_get_drvdata(dsi);
-
-   drm_panel_disable(>base);
-}
-
 static struct mipi_dsi_driver jdi_panel_driver = {
.driver = {
.name = "panel-jdi-lt070me05000",
@@ -478,7 +467,6 @@ static struct mipi_dsi_driver jdi_panel_driver = {
},
.probe = jdi_panel_probe,
.remove = jdi_panel_remove,
-   .shutdown = jdi_panel_shutdown,
 };
 module_mipi_dsi_driver(jdi_panel_driver);
 
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 15/24] drm/panel: seiko-43wvf1g: Stop tracking prepared/enabled

2024-06-04 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Cc: Marco Franchi 
Cc: Fabio Estevam 
Cc: Laurentiu Palcu 
Cc: Pengutronix Kernel Team 
Cc: i...@lists.linux.dev
Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---

(no changes since v2)

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-seiko-43wvf1g.c | 40 -
 1 file changed, 40 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c 
b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c
index 658c7c040570..98480904126c 100644
--- a/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c
+++ b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c
@@ -44,8 +44,6 @@ struct seiko_panel_desc {
 
 struct seiko_panel {
struct drm_panel base;
-   bool prepared;
-   bool enabled;
const struct seiko_panel_desc *desc;
struct regulator *dvdd;
struct regulator *avdd;
@@ -122,25 +120,10 @@ static int seiko_panel_get_fixed_modes(struct seiko_panel 
*panel,
return num;
 }
 
-static int seiko_panel_disable(struct drm_panel *panel)
-{
-   struct seiko_panel *p = to_seiko_panel(panel);
-
-   if (!p->enabled)
-   return 0;
-
-   p->enabled = false;
-
-   return 0;
-}
-
 static int seiko_panel_unprepare(struct drm_panel *panel)
 {
struct seiko_panel *p = to_seiko_panel(panel);
 
-   if (!p->prepared)
-   return 0;
-
gpiod_set_value_cansleep(p->enable_gpio, 0);
 
regulator_disable(p->avdd);
@@ -150,8 +133,6 @@ static int seiko_panel_unprepare(struct drm_panel *panel)
 
regulator_disable(p->dvdd);
 
-   p->prepared = false;
-
return 0;
 }
 
@@ -160,9 +141,6 @@ static int seiko_panel_prepare(struct drm_panel *panel)
struct seiko_panel *p = to_seiko_panel(panel);
int err;
 
-   if (p->prepared)
-   return 0;
-
err = regulator_enable(p->dvdd);
if (err < 0) {
dev_err(panel->dev, "failed to enable dvdd: %d\n", err);
@@ -180,8 +158,6 @@ static int seiko_panel_prepare(struct drm_panel *panel)
 
gpiod_set_value_cansleep(p->enable_gpio, 1);
 
-   p->prepared = true;
-
return 0;
 
 disable_dvdd:
@@ -189,18 +165,6 @@ static int seiko_panel_prepare(struct drm_panel *panel)
return err;
 }
 
-static int seiko_panel_enable(struct drm_panel *panel)
-{
-   struct seiko_panel *p = to_seiko_panel(panel);
-
-   if (p->enabled)
-   return 0;
-
-   p->enabled = true;
-
-   return 0;
-}
-
 static int seiko_panel_get_modes(struct drm_panel *panel,
 struct drm_connector *connector)
 {
@@ -228,10 +192,8 @@ static int seiko_panel_get_timings(struct drm_panel *panel,
 }
 
 static const struct drm_panel_funcs seiko_panel_funcs = {
-   .disable = seiko_panel_disable,
.unprepare = seiko_panel_unprepare,
.prepare = seiko_panel_prepare,
-   .enable = seiko_panel_enable,
.get_modes = seiko_panel_get_modes,
.get_timings = seiko_panel_get_timings,
 };
@@ -246,8 +208,6 @@ static int seiko_panel_probe(struct device *dev,
if (!panel)
return -ENOMEM;
 
-   panel->enabled = false;
-   panel->prepared = false;
panel->desc = desc;
 
panel->dvdd = devm_regulator_get(dev, "dvdd");
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 09/24] drm/panel: tdo-tl070wsh30: Stop tracking prepared

2024-06-04 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Cc: Neil Armstrong 
Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---

(no changes since v2)

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c 
b/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c
index d8487bc6d611..36f27c664b69 100644
--- a/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c
+++ b/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c
@@ -24,8 +24,6 @@ struct tdo_tl070wsh30_panel {
 
struct regulator *supply;
struct gpio_desc *reset_gpio;
-
-   bool prepared;
 };
 
 static inline
@@ -39,9 +37,6 @@ static int tdo_tl070wsh30_panel_prepare(struct drm_panel 
*panel)
struct tdo_tl070wsh30_panel *tdo_tl070wsh30 = 
to_tdo_tl070wsh30_panel(panel);
int err;
 
-   if (tdo_tl070wsh30->prepared)
-   return 0;
-
err = regulator_enable(tdo_tl070wsh30->supply);
if (err < 0)
return err;
@@ -74,8 +69,6 @@ static int tdo_tl070wsh30_panel_prepare(struct drm_panel 
*panel)
 
msleep(20);
 
-   tdo_tl070wsh30->prepared = true;
-
return 0;
 }
 
@@ -84,9 +77,6 @@ static int tdo_tl070wsh30_panel_unprepare(struct drm_panel 
*panel)
struct tdo_tl070wsh30_panel *tdo_tl070wsh30 = 
to_tdo_tl070wsh30_panel(panel);
int err;
 
-   if (!tdo_tl070wsh30->prepared)
-   return 0;
-
err = mipi_dsi_dcs_set_display_off(tdo_tl070wsh30->link);
if (err < 0)
dev_err(panel->dev, "failed to set display off: %d\n", err);
@@ -103,8 +93,6 @@ static int tdo_tl070wsh30_panel_unprepare(struct drm_panel 
*panel)
 
regulator_disable(tdo_tl070wsh30->supply);
 
-   tdo_tl070wsh30->prepared = false;
-
return 0;
 }
 
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 11/24] drm/panel: jdi-lt070me05000: Stop tracking prepared/enabled

2024-06-04 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

NOTE: as part of this, transition the panel's direct calls to its
disable function in shutdown/remove to call through DRM panel.

Cc: Vinay Simha BN 
Cc: Sumit Semwal 
Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---
Note: since we are able to identify that this panel only appears to be
used on Qualcomm boards and we have to touch the shutdown/remove path
in this patch anyway, we could possibly squash this with the next
patch that removes the disable call in shutdown/remove. For now I'm
keeping them separate just to keep the concepts separate.

(no changes since v2)

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 .../gpu/drm/panel/panel-jdi-lt070me05000.c| 27 ++-
 1 file changed, 2 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c 
b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
index f9a69f347068..4ee6fa1e 100644
--- a/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
+++ b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
@@ -37,9 +37,6 @@ struct jdi_panel {
struct gpio_desc *dcdc_en_gpio;
struct backlight_device *backlight;
 
-   bool prepared;
-   bool enabled;
-
const struct drm_display_mode *mode;
 };
 
@@ -176,13 +173,8 @@ static int jdi_panel_disable(struct drm_panel *panel)
 {
struct jdi_panel *jdi = to_jdi_panel(panel);
 
-   if (!jdi->enabled)
-   return 0;
-
backlight_disable(jdi->backlight);
 
-   jdi->enabled = false;
-
return 0;
 }
 
@@ -192,9 +184,6 @@ static int jdi_panel_unprepare(struct drm_panel *panel)
struct device *dev = >dsi->dev;
int ret;
 
-   if (!jdi->prepared)
-   return 0;
-
jdi_panel_off(jdi);
 
ret = regulator_bulk_disable(ARRAY_SIZE(jdi->supplies), jdi->supplies);
@@ -207,8 +196,6 @@ static int jdi_panel_unprepare(struct drm_panel *panel)
 
gpiod_set_value(jdi->dcdc_en_gpio, 0);
 
-   jdi->prepared = false;
-
return 0;
 }
 
@@ -218,9 +205,6 @@ static int jdi_panel_prepare(struct drm_panel *panel)
struct device *dev = >dsi->dev;
int ret;
 
-   if (jdi->prepared)
-   return 0;
-
ret = regulator_bulk_enable(ARRAY_SIZE(jdi->supplies), jdi->supplies);
if (ret < 0) {
dev_err(dev, "regulator enable failed, %d\n", ret);
@@ -250,8 +234,6 @@ static int jdi_panel_prepare(struct drm_panel *panel)
goto poweroff;
}
 
-   jdi->prepared = true;
-
return 0;
 
 poweroff:
@@ -272,13 +254,8 @@ static int jdi_panel_enable(struct drm_panel *panel)
 {
struct jdi_panel *jdi = to_jdi_panel(panel);
 
-   if (jdi->enabled)
-   return 0;
-
backlight_enable(jdi->backlight);
 
-   jdi->enabled = true;
-
return 0;
 }
 
@@ -475,7 +452,7 @@ static void jdi_panel_remove(struct mipi_dsi_device *dsi)
struct jdi_panel *jdi = mipi_dsi_get_drvdata(dsi);
int ret;
 
-   ret = jdi_panel_disable(>base);
+   ret = drm_panel_disable(>base);
if (ret < 0)
dev_err(>dev, "failed to disable panel: %d\n", ret);
 
@@ -491,7 +468,7 @@ static void jdi_panel_shutdown(struct mipi_dsi_device *dsi)
 {
struct jdi_panel *jdi = mipi_dsi_get_drvdata(dsi);
 
-   jdi_panel_disable(>base);
+   drm_panel_disable(>base);
 }
 
 static struct mipi_dsi_driver jdi_panel_driver = {
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 08/24] drm/panel: osd-osd101t2587-53ts: Don't call unprepare+disable at shutdown/remove

2024-06-04 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

A grep through mainline for compatible strings used by this driver
indicates that it is used by TI OMAP boards. The OMAP driver appears
to be correctly calling drm_atomic_helper_shutdown() so we can remove
the calls.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Peter Ujfalusi 
Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---

(no changes since v2)

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c | 14 --
 1 file changed, 14 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c 
b/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c
index c0da7d9512e8..dbea84f51514 100644
--- a/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c
+++ b/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c
@@ -186,11 +186,6 @@ static void osd101t2587_panel_remove(struct 
mipi_dsi_device *dsi)
struct osd101t2587_panel *osd101t2587 = mipi_dsi_get_drvdata(dsi);
int ret;
 
-   ret = drm_panel_disable(>base);
-   if (ret < 0)
-   dev_warn(>dev, "failed to disable panel: %d\n", ret);
-
-   drm_panel_unprepare(>base);
drm_panel_remove(>base);
 
ret = mipi_dsi_detach(dsi);
@@ -198,14 +193,6 @@ static void osd101t2587_panel_remove(struct 
mipi_dsi_device *dsi)
dev_err(>dev, "failed to detach from DSI host: %d\n", ret);
 }
 
-static void osd101t2587_panel_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct osd101t2587_panel *osd101t2587 = mipi_dsi_get_drvdata(dsi);
-
-   drm_panel_disable(>base);
-   drm_panel_unprepare(>base);
-}
-
 static struct mipi_dsi_driver osd101t2587_panel_driver = {
.driver = {
.name = "panel-osd-osd101t2587-53ts",
@@ -213,7 +200,6 @@ static struct mipi_dsi_driver osd101t2587_panel_driver = {
},
.probe = osd101t2587_panel_probe,
.remove = osd101t2587_panel_remove,
-   .shutdown = osd101t2587_panel_shutdown,
 };
 module_mipi_dsi_driver(osd101t2587_panel_driver);
 
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 10/24] drm/panel: tdo-tl070wsh30: Don't call unprepare+disable at shutdown/remove

2024-06-04 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

Unfortunately, grepping mainline for this panel's compatible string
shows no hits, so we can't be 100% sure if the DRM modeset driver used
with this panel has been fixed. If it is found that the DRM modeset
driver hasn't been fixed then this patch could be temporarily reverted
until it is.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Neil Armstrong 
Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---

(no changes since v2)

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c 
b/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c
index 36f27c664b69..227f97f9b136 100644
--- a/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c
+++ b/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c
@@ -208,16 +208,6 @@ static void tdo_tl070wsh30_panel_remove(struct 
mipi_dsi_device *dsi)
dev_err(>dev, "failed to detach from DSI host: %d\n", err);
 
drm_panel_remove(_tl070wsh30->base);
-   drm_panel_disable(_tl070wsh30->base);
-   drm_panel_unprepare(_tl070wsh30->base);
-}
-
-static void tdo_tl070wsh30_panel_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct tdo_tl070wsh30_panel *tdo_tl070wsh30 = mipi_dsi_get_drvdata(dsi);
-
-   drm_panel_disable(_tl070wsh30->base);
-   drm_panel_unprepare(_tl070wsh30->base);
 }
 
 static struct mipi_dsi_driver tdo_tl070wsh30_panel_driver = {
@@ -227,7 +217,6 @@ static struct mipi_dsi_driver tdo_tl070wsh30_panel_driver = 
{
},
.probe = tdo_tl070wsh30_panel_probe,
.remove = tdo_tl070wsh30_panel_remove,
-   .shutdown = tdo_tl070wsh30_panel_shutdown,
 };
 module_mipi_dsi_driver(tdo_tl070wsh30_panel_driver);
 
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 07/24] drm/panel: osd-osd101t2587-53ts: Stop tracking prepared/enabled

2024-06-04 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Cc: Peter Ujfalusi 
Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---

(no changes since v2)

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 .../drm/panel/panel-osd-osd101t2587-53ts.c| 27 +--
 1 file changed, 1 insertion(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c 
b/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c
index 493e0504f6f7..c0da7d9512e8 100644
--- a/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c
+++ b/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c
@@ -21,9 +21,6 @@ struct osd101t2587_panel {
 
struct regulator *supply;
 
-   bool prepared;
-   bool enabled;
-
const struct drm_display_mode *default_mode;
 };
 
@@ -37,13 +34,8 @@ static int osd101t2587_panel_disable(struct drm_panel *panel)
struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
int ret;
 
-   if (!osd101t2587->enabled)
-   return 0;
-
ret = mipi_dsi_shutdown_peripheral(osd101t2587->dsi);
 
-   osd101t2587->enabled = false;
-
return ret;
 }
 
@@ -51,11 +43,7 @@ static int osd101t2587_panel_unprepare(struct drm_panel 
*panel)
 {
struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
 
-   if (!osd101t2587->prepared)
-   return 0;
-
regulator_disable(osd101t2587->supply);
-   osd101t2587->prepared = false;
 
return 0;
 }
@@ -63,16 +51,8 @@ static int osd101t2587_panel_unprepare(struct drm_panel 
*panel)
 static int osd101t2587_panel_prepare(struct drm_panel *panel)
 {
struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
-   int ret;
 
-   if (osd101t2587->prepared)
-   return 0;
-
-   ret = regulator_enable(osd101t2587->supply);
-   if (!ret)
-   osd101t2587->prepared = true;
-
-   return ret;
+   return regulator_enable(osd101t2587->supply);
 }
 
 static int osd101t2587_panel_enable(struct drm_panel *panel)
@@ -80,15 +60,10 @@ static int osd101t2587_panel_enable(struct drm_panel *panel)
struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
int ret;
 
-   if (osd101t2587->enabled)
-   return 0;
-
ret = mipi_dsi_turn_on_peripheral(osd101t2587->dsi);
if (ret)
return ret;
 
-   osd101t2587->enabled = true;
-
return ret;
 }
 
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 06/24] drm/panel: olimex-lcd-olinuxino: Don't call unprepare+disable at remove

2024-06-04 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

Unfortunately, grepping mainline for this panel's compatible string
shows no hits, so we can't be 100% sure if the DRM modeset driver used
with this panel has been fixed. If it is found that the DRM modeset
driver hasn't been fixed then this patch could be temporarily reverted
until it is.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---

(no changes since v2)

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c 
b/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c
index 8a687d3ba236..94ae8c8270b8 100644
--- a/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c
+++ b/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c
@@ -251,9 +251,6 @@ static void lcd_olinuxino_remove(struct i2c_client *client)
struct lcd_olinuxino *panel = i2c_get_clientdata(client);
 
drm_panel_remove(>panel);
-
-   drm_panel_disable(>panel);
-   drm_panel_unprepare(>panel);
 }
 
 static const struct of_device_id lcd_olinuxino_of_ids[] = {
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 05/24] drm/panel: olimex-lcd-olinuxino: Stop tracking prepared/enabled

2024-06-04 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---

(no changes since v2)

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 .../drm/panel/panel-olimex-lcd-olinuxino.c| 41 ---
 1 file changed, 41 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c 
b/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c
index 4819ada69482..8a687d3ba236 100644
--- a/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c
+++ b/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c
@@ -64,9 +64,6 @@ struct lcd_olinuxino {
struct i2c_client *client;
struct mutex mutex;
 
-   bool prepared;
-   bool enabled;
-
struct regulator *supply;
struct gpio_desc *enable_gpio;
 
@@ -78,30 +75,13 @@ static inline struct lcd_olinuxino *to_lcd_olinuxino(struct 
drm_panel *panel)
return container_of(panel, struct lcd_olinuxino, panel);
 }
 
-static int lcd_olinuxino_disable(struct drm_panel *panel)
-{
-   struct lcd_olinuxino *lcd = to_lcd_olinuxino(panel);
-
-   if (!lcd->enabled)
-   return 0;
-
-   lcd->enabled = false;
-
-   return 0;
-}
-
 static int lcd_olinuxino_unprepare(struct drm_panel *panel)
 {
struct lcd_olinuxino *lcd = to_lcd_olinuxino(panel);
 
-   if (!lcd->prepared)
-   return 0;
-
gpiod_set_value_cansleep(lcd->enable_gpio, 0);
regulator_disable(lcd->supply);
 
-   lcd->prepared = false;
-
return 0;
 }
 
@@ -110,27 +90,11 @@ static int lcd_olinuxino_prepare(struct drm_panel *panel)
struct lcd_olinuxino *lcd = to_lcd_olinuxino(panel);
int ret;
 
-   if (lcd->prepared)
-   return 0;
-
ret = regulator_enable(lcd->supply);
if (ret < 0)
return ret;
 
gpiod_set_value_cansleep(lcd->enable_gpio, 1);
-   lcd->prepared = true;
-
-   return 0;
-}
-
-static int lcd_olinuxino_enable(struct drm_panel *panel)
-{
-   struct lcd_olinuxino *lcd = to_lcd_olinuxino(panel);
-
-   if (lcd->enabled)
-   return 0;
-
-   lcd->enabled = true;
 
return 0;
 }
@@ -195,10 +159,8 @@ static int lcd_olinuxino_get_modes(struct drm_panel *panel,
 }
 
 static const struct drm_panel_funcs lcd_olinuxino_funcs = {
-   .disable = lcd_olinuxino_disable,
.unprepare = lcd_olinuxino_unprepare,
.prepare = lcd_olinuxino_prepare,
-   .enable = lcd_olinuxino_enable,
.get_modes = lcd_olinuxino_get_modes,
 };
 
@@ -264,9 +226,6 @@ static int lcd_olinuxino_probe(struct i2c_client *client)
lcd->eeprom.num_modes = 4;
}
 
-   lcd->enabled = false;
-   lcd->prepared = false;
-
lcd->supply = devm_regulator_get(dev, "power");
if (IS_ERR(lcd->supply))
return PTR_ERR(lcd->supply);
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 03/24] drm/panel: khadas-ts050: Stop tracking prepared/enabled

2024-06-04 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Cc: Jacobe Zang 
Cc: Nicolas Belin 
Cc: Neil Armstrong 
Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---

(no changes since v2)

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-khadas-ts050.c | 28 --
 1 file changed, 28 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-khadas-ts050.c 
b/drivers/gpu/drm/panel/panel-khadas-ts050.c
index c54be0cc3f08..e35762ebdbd1 100644
--- a/drivers/gpu/drm/panel/panel-khadas-ts050.c
+++ b/drivers/gpu/drm/panel/panel-khadas-ts050.c
@@ -26,9 +26,6 @@ struct khadas_ts050_panel {
struct gpio_desc *reset_gpio;
struct gpio_desc *enable_gpio;
struct khadas_ts050_panel_data *panel_data;
-
-   bool prepared;
-   bool enabled;
 };
 
 struct khadas_ts050_panel_cmd {
@@ -642,9 +639,6 @@ static int khadas_ts050_panel_prepare(struct drm_panel 
*panel)
unsigned int i;
int err;
 
-   if (khadas_ts050->prepared)
-   return 0;
-
gpiod_set_value_cansleep(khadas_ts050->enable_gpio, 0);
 
err = regulator_enable(khadas_ts050->supply);
@@ -708,8 +702,6 @@ static int khadas_ts050_panel_prepare(struct drm_panel 
*panel)
 
usleep_range(1, 11000);
 
-   khadas_ts050->prepared = true;
-
return 0;
 
 poweroff:
@@ -726,11 +718,6 @@ static int khadas_ts050_panel_unprepare(struct drm_panel 
*panel)
struct khadas_ts050_panel *khadas_ts050 = to_khadas_ts050_panel(panel);
int err;
 
-   if (!khadas_ts050->prepared)
-   return 0;
-
-   khadas_ts050->prepared = false;
-
err = mipi_dsi_dcs_enter_sleep_mode(khadas_ts050->link);
if (err < 0)
dev_err(panel->dev, "failed to enter sleep mode: %d\n", err);
@@ -747,31 +734,17 @@ static int khadas_ts050_panel_unprepare(struct drm_panel 
*panel)
return 0;
 }
 
-static int khadas_ts050_panel_enable(struct drm_panel *panel)
-{
-   struct khadas_ts050_panel *khadas_ts050 = to_khadas_ts050_panel(panel);
-
-   khadas_ts050->enabled = true;
-
-   return 0;
-}
-
 static int khadas_ts050_panel_disable(struct drm_panel *panel)
 {
struct khadas_ts050_panel *khadas_ts050 = to_khadas_ts050_panel(panel);
int err;
 
-   if (!khadas_ts050->enabled)
-   return 0;
-
err = mipi_dsi_dcs_set_display_off(khadas_ts050->link);
if (err < 0)
dev_err(panel->dev, "failed to set display off: %d\n", err);
 
usleep_range(1, 11000);
 
-   khadas_ts050->enabled = false;
-
return 0;
 }
 
@@ -815,7 +788,6 @@ static int khadas_ts050_panel_get_modes(struct drm_panel 
*panel,
 static const struct drm_panel_funcs khadas_ts050_panel_funcs = {
.prepare = khadas_ts050_panel_prepare,
.unprepare = khadas_ts050_panel_unprepare,
-   .enable = khadas_ts050_panel_enable,
.disable = khadas_ts050_panel_disable,
.get_modes = khadas_ts050_panel_get_modes,
 };
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 04/24] drm/panel: khadas-ts050: Don't call unprepare+disable at shutdown/remove

2024-06-04 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

Unfortunately, grepping mainline for this panel's compatible string
shows no hits, so we can't be 100% sure if the DRM modeset driver used
with this panel has been fixed. If it is found that the DRM modeset
driver hasn't been fixed then this patch could be temporarily reverted
until it is.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Jacobe Zang 
Cc: Nicolas Belin 
Cc: Neil Armstrong 
Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---

(no changes since v2)

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-khadas-ts050.c | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-khadas-ts050.c 
b/drivers/gpu/drm/panel/panel-khadas-ts050.c
index e35762ebdbd1..14932cb3defc 100644
--- a/drivers/gpu/drm/panel/panel-khadas-ts050.c
+++ b/drivers/gpu/drm/panel/panel-khadas-ts050.c
@@ -880,16 +880,6 @@ static void khadas_ts050_panel_remove(struct 
mipi_dsi_device *dsi)
dev_err(>dev, "failed to detach from DSI host: %d\n", err);
 
drm_panel_remove(_ts050->base);
-   drm_panel_disable(_ts050->base);
-   drm_panel_unprepare(_ts050->base);
-}
-
-static void khadas_ts050_panel_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct khadas_ts050_panel *khadas_ts050 = mipi_dsi_get_drvdata(dsi);
-
-   drm_panel_disable(_ts050->base);
-   drm_panel_unprepare(_ts050->base);
 }
 
 static struct mipi_dsi_driver khadas_ts050_panel_driver = {
@@ -899,7 +889,6 @@ static struct mipi_dsi_driver khadas_ts050_panel_driver = {
},
.probe = khadas_ts050_panel_probe,
.remove = khadas_ts050_panel_remove,
-   .shutdown = khadas_ts050_panel_shutdown,
 };
 module_mipi_dsi_driver(khadas_ts050_panel_driver);
 
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 02/24] drm/panel: boe-himax8279d: Don't call unprepare+disable at shutdown/remove

2024-06-04 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

Unfortunately, grepping mainline for this panel's compatible string
shows no hits, so we can't be 100% sure if the DRM modeset driver used
with this panel has been fixed. If it is found that the DRM modeset
driver hasn't been fixed then this patch could be temporarily reverted
until it is.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Jerry Han 
Cc: Jitao Shi 
Cc: Rock Wang 
Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---

(no changes since v2)

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-boe-himax8279d.c | 17 -
 1 file changed, 17 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-boe-himax8279d.c 
b/drivers/gpu/drm/panel/panel-boe-himax8279d.c
index 12e14615298b..df746baae301 100644
--- a/drivers/gpu/drm/panel/panel-boe-himax8279d.c
+++ b/drivers/gpu/drm/panel/panel-boe-himax8279d.c
@@ -894,14 +894,6 @@ static void panel_remove(struct mipi_dsi_device *dsi)
struct panel_info *pinfo = mipi_dsi_get_drvdata(dsi);
int err;
 
-   err = drm_panel_disable(>base);
-   if (err < 0)
-   dev_err(>dev, "failed to disable panel: %d\n", err);
-
-   err = drm_panel_unprepare(>base);
-   if (err < 0)
-   dev_err(>dev, "failed to unprepare panel: %d\n", err);
-
err = mipi_dsi_detach(dsi);
if (err < 0)
dev_err(>dev, "failed to detach from DSI host: %d\n", err);
@@ -909,14 +901,6 @@ static void panel_remove(struct mipi_dsi_device *dsi)
drm_panel_remove(>base);
 }
 
-static void panel_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct panel_info *pinfo = mipi_dsi_get_drvdata(dsi);
-
-   drm_panel_disable(>base);
-   drm_panel_unprepare(>base);
-}
-
 static struct mipi_dsi_driver panel_driver = {
.driver = {
.name = "panel-boe-himax8279d",
@@ -924,7 +908,6 @@ static struct mipi_dsi_driver panel_driver = {
},
.probe = panel_probe,
.remove = panel_remove,
-   .shutdown = panel_shutdown,
 };
 module_mipi_dsi_driver(panel_driver);
 
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 01/24] drm/panel: boe-himax8279d: Stop tracking prepared/enabled

2024-06-04 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

NOTE: as part of this, transition the panel's direct calls to its
disable/unprepare functions in shutdown/remove to call through DRM
panel.

Cc: Jerry Han 
Cc: Jitao Shi 
Cc: Rock Wang 
Acked-by: Linus Walleij 
Acked-by: Maxime Ripard 
Signed-off-by: Douglas Anderson 
---

(no changes since v2)

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-boe-himax8279d.c | 31 +++-
 1 file changed, 4 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-boe-himax8279d.c 
b/drivers/gpu/drm/panel/panel-boe-himax8279d.c
index e225840b0d67..12e14615298b 100644
--- a/drivers/gpu/drm/panel/panel-boe-himax8279d.c
+++ b/drivers/gpu/drm/panel/panel-boe-himax8279d.c
@@ -47,9 +47,6 @@ struct panel_info {
struct gpio_desc *enable_gpio;
struct gpio_desc *pp33_gpio;
struct gpio_desc *pp18_gpio;
-
-   bool prepared;
-   bool enabled;
 };
 
 static inline struct panel_info *to_panel_info(struct drm_panel *panel)
@@ -86,17 +83,12 @@ static int boe_panel_disable(struct drm_panel *panel)
struct panel_info *pinfo = to_panel_info(panel);
int err;
 
-   if (!pinfo->enabled)
-   return 0;
-
err = mipi_dsi_dcs_set_display_off(pinfo->link);
if (err < 0) {
dev_err(panel->dev, "failed to set display off: %d\n", err);
return err;
}
 
-   pinfo->enabled = false;
-
return 0;
 }
 
@@ -105,9 +97,6 @@ static int boe_panel_unprepare(struct drm_panel *panel)
struct panel_info *pinfo = to_panel_info(panel);
int err;
 
-   if (!pinfo->prepared)
-   return 0;
-
err = mipi_dsi_dcs_set_display_off(pinfo->link);
if (err < 0)
dev_err(panel->dev, "failed to set display off: %d\n", err);
@@ -121,8 +110,6 @@ static int boe_panel_unprepare(struct drm_panel *panel)
 
disable_gpios(pinfo);
 
-   pinfo->prepared = false;
-
return 0;
 }
 
@@ -131,9 +118,6 @@ static int boe_panel_prepare(struct drm_panel *panel)
struct panel_info *pinfo = to_panel_info(panel);
int err;
 
-   if (pinfo->prepared)
-   return 0;
-
gpiod_set_value(pinfo->pp18_gpio, 1);
/* T1: 5ms - 6ms */
usleep_range(5000, 6000);
@@ -180,8 +164,6 @@ static int boe_panel_prepare(struct drm_panel *panel)
/* T7: 20ms - 21ms */
usleep_range(2, 21000);
 
-   pinfo->prepared = true;
-
return 0;
 
 poweroff:
@@ -194,9 +176,6 @@ static int boe_panel_enable(struct drm_panel *panel)
struct panel_info *pinfo = to_panel_info(panel);
int ret;
 
-   if (pinfo->enabled)
-   return 0;
-
usleep_range(12, 121000);
 
ret = mipi_dsi_dcs_set_display_on(pinfo->link);
@@ -205,8 +184,6 @@ static int boe_panel_enable(struct drm_panel *panel)
return ret;
}
 
-   pinfo->enabled = true;
-
return 0;
 }
 
@@ -917,11 +894,11 @@ static void panel_remove(struct mipi_dsi_device *dsi)
struct panel_info *pinfo = mipi_dsi_get_drvdata(dsi);
int err;
 
-   err = boe_panel_disable(>base);
+   err = drm_panel_disable(>base);
if (err < 0)
dev_err(>dev, "failed to disable panel: %d\n", err);
 
-   err = boe_panel_unprepare(>base);
+   err = drm_panel_unprepare(>base);
if (err < 0)
dev_err(>dev, "failed to unprepare panel: %d\n", err);
 
@@ -936,8 +913,8 @@ static void panel_shutdown(struct mipi_dsi_device *dsi)
 {
struct panel_info *pinfo = mipi_dsi_get_drvdata(dsi);
 
-   boe_panel_disable(>base);
-   boe_panel_unprepare(>base);
+   drm_panel_disable(>base);
+   drm_panel_unprepare(>base);
 }
 
 static struct mipi_dsi_driver panel_driver = {
-- 
2.45.1.288.g0e0cd299f1-goog



[PATCH v3 00/24] drm/panel: Remove most store/double-check of prepared/enabled state

2024-06-04 Thread Douglas Anderson


As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

This series attempts to do just that. While the original grep, AKA:
  git grep 'if.*>prepared' -- drivers/gpu/drm/panel
  git grep 'if.*>enabled' -- drivers/gpu/drm/panel
...still produces a few hits after my series, they are _mostly_ all
gone. The ones that are left are less trivial to fix.

One of the main reasons that many panels probably needed to store and
double-check their prepared/enabled appears to have been to handle
shutdown and/or remove. Panels drivers often wanted to force the power
off for panels in these cases and this was a good reason for the
double-check.

In response to my V1 series [1] we had much discussion of what to
do. The conclusion was that as long as DRM modeset drivers properly
called drm_atomic_helper_shutdown() that we should be able to remove
the explicit shutdown/remove handling in the panel drivers. Most of
the patches to improve DRM modeset drivers [2] [3] [4] have now
landed.

In contrast to my V1 series, I broke the V2 series up a lot
more. Since a few of the panel drivers in V1 already landed, we had
fewer total drivers and so we could devote a patch to each panel.
Also, since we were now relying on DRM modeset drivers I felt like we
should split the patches for each panel into two: one that's
definitely safe and one that could be reverted if we found a
problematic DRM modeset driver that we couldn't fix.

Many of the patches in the V2 series [5] landed, so this V3 series is
the patches that are left plus one new bonus patch. At this point, we
may want to just land the patches that are left since it seems like
nobody is going to test/review them and they've all been Acked by
Linus and Maxime.

NOTE: this touches _a lot_ of drivers, is repetitive, and is not
really possible to generate automatically. That means it's entirely
possible that my eyes glazed over and I did something wrong. Please
double-check me and don't assume that I got everything perfect, though
I did my best. I have at least confirmed that "allmodconfig" for arm64
doesn't fall on its face with this series. I haven't done a ton of
other testing.

[1] 
https://lore.kernel.org/r/20230804140605.RFC.4.I930069a32baab6faf46d6b234f89613b5cec0f14@changeid
[2] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[4] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org
[5] https://lore.kernel.org/r/20240503213441.177109-1-diand...@chromium.org/

Changes in v3:
- drm/panel: Avoid warnings w/ panel-simple/panel-edp at shutdown

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

Douglas Anderson (24):
  drm/panel: boe-himax8279d: Stop tracking prepared/enabled
  drm/panel: boe-himax8279d: Don't call unprepare+disable at
shutdown/remove
  drm/panel: khadas-ts050: Stop tracking prepared/enabled
  drm/panel: khadas-ts050: Don't call unprepare+disable at
shutdown/remove
  drm/panel: olimex-lcd-olinuxino: Stop tracking prepared/enabled
  drm/panel: olimex-lcd-olinuxino: Don't call unprepare+disable at
remove
  drm/panel: osd-osd101t2587-53ts: Stop tracking prepared/enabled
  drm/panel: osd-osd101t2587-53ts: Don't call unprepare+disable at
shutdown/remove
  drm/panel: tdo-tl070wsh30: Stop tracking prepared
  drm/panel: tdo-tl070wsh30: Don't call unprepare+disable at
shutdown/remove
  drm/panel: jdi-lt070me05000: Stop tracking prepared/enabled
  drm/panel: jdi-lt070me05000: Don't call disable at shutdown/remove
  drm/panel: panasonic-vvx10f034n00: Stop tracking prepared/enabled
  drm/panel: panasonic-vvx10f034n00: Don't call disable at
shutdown/remove
  drm/panel: seiko-43wvf1g: Stop tracking prepared/enabled
  drm/panel: seiko-43wvf1g: Don't call disable at shutdown/remove
  drm/panel: sharp-lq101r1sx01: Stop tracking prepared/enabled
  drm/panel: sharp-lq101r1sx01: Don't call disable at shutdown/remove
  drm/panel: sharp-ls043t1le01: Stop tracking prepared
  drm/panel: sharp-ls043t1le01: Don't call disable at shutdown/remove
  drm/panel: raydium-rm67191: Stop tracking enabled
  drm/panel: raydium-rm67191: Don't call unprepare+disable at shutdown
  drm/panel: Update TODO list item for cleaning up prepared/enabled
tracking
  drm/panel: Avoid warnings w/ panel-simple/panel-edp at shutdown

 Documentation/gpu/todo.rst|  47 +++---
 drivers/gpu/drm/drm_panel.c   |  12 ++
 drivers/gpu/drm/panel/panel-boe-himax8279d.c  |  40 -
 .../gpu/drm/panel/panel-drm-shutdown-check.h  | 151 ++
 drivers

Re: (subset) [PATCH 2/2] drm/panel-edp: Add more panels with conservative timings

2024-05-28 Thread Douglas Anderson


On Mon, 27 May 2024 17:54:50 +0800, Pin-yen Lin wrote:
> Same as commit 7c8690d8fc80 ("drm/panel-edp: Add some panels with
> conservative timings"), the 3 panels added in this patch are used by
> Mediatek MT8173 Chromebooks and they used to work with the downstream
> v4.19 kernel without any specified delay.
> 
> These panel IDs were found from in-field reports, but their datahseets
> are not available. For BOE 0x0623 and SHP 0x153a, their product names
> are retrieved from the EDIDs. The EDID of AUO 0x1999 does not contain
> such information, so list as "Unknown" in this patch.
> 
> [...]

Applied, thanks!

[2/2] drm/panel-edp: Add more panels with conservative timings
  commit: 336dca397dcefc5d7436be1fee3c814ed6512996

Best regards,
-- 
Douglas Anderson 



Re: (subset) [PATCH 1/2] drm/panel-edp: Add support for several panels

2024-05-28 Thread Douglas Anderson


On Mon, 27 May 2024 17:54:49 +0800, Pin-yen Lin wrote:
> Add support for the following models:
> AUO B140HTN02.0
> BOE NT116WHM-N21 V4.1
> BOE NT116WHM-N21
> 
> 

Applied, thanks!

[1/2] drm/panel-edp: Add support for several panels
  commit: e4f9fd9edbc22faceb4c9c57242440bb9e17924b

Best regards,
-- 
Douglas Anderson 



Re: [PATCH] drm/dp: Fix documentation warning

2024-05-28 Thread Douglas Anderson


On Sun, 19 May 2024 00:10:27 -0300, MarileneGarcia wrote:
> It fixes the following warnings when
> the kernel documentation is generated:
> 
> ./include/drm/display/drm_dp_helper.h:126:
> warning: Function parameter or struct member
> 'mode' not described in 'drm_dp_as_sdp'
> 
> [...]

Applied, thanks!

[1/1] drm/dp: Fix documentation warning
  commit: c7ce956bb6d0f32ab921b6ffba1a6a834df96f21

Best regards,
-- 
Douglas Anderson 



Re: [PATCH] drm/panel-edp: Add CMN N116BCJ-EAK

2024-05-22 Thread Douglas Anderson


On Wed, 22 May 2024 19:39:24 +0800, Haikun Zhou wrote:
> Add support for the CMN N116BCJ-EAK, place the raw EDID here for
> subsequent reference.
> 00 ff ff ff ff ff ff 00 0d ae 60 11 00 00 00 00
> 04 22 01 04 95 1a 0e 78 02 67 75 98 59 53 90 27
> 1c 50 54 00 00 00 01 01 01 01 01 01 01 01 01 01
> 01 01 01 01 01 01 da 1d 56 e2 50 00 20 30 30 20
> a6 00 00 90 10 00 00 18 00 00 00 fe 00 4e 31 31
> 36 42 43 4a 2d 45 41 4b 0a 20 00 00 00 fe 00 43
> 4d 4e 0a 20 20 20 20 20 20 20 20 20 00 00 00 fe
> 00 4e 31 31 36 42 43 4a 2d 45 41 4b 0a 20 00 98
> 
> [...]

Applied, thanks!

[1/1] drm/panel-edp: Add CMN N116BCJ-EAK
  commit: 7acacca1b157fcb258cfd781603425f73bc7370b

Best regards,
-- 
Douglas Anderson 



[PATCH] dt-bindings: display: Reorganize legacy eDP panel bindings

2024-05-20 Thread Douglas Anderson
Back in the day, we used to need to list the exact panel in dts for
eDP panels. This led to all sorts of problems including a large number
of cases where people listed a bogus panel in their device tree
because of the needs of second sourcing (and third sourcing, and
fourth sourcing, ...). Back when we needed to add eDP panels to dts
files we used to list them in "panel-simple.yaml".

These days we have the new way of doing things as documented in
"panel-edp.yaml". We can just list the compatible "edp-panel", add
some timing info to the source code, and we're good to go. There's not
really good reasons not to use this new method.

To try to make it obvious that we shouldn't add new compatible strings
for eDP panels, let's move them all out of the old "panel-simple.yaml"
file to their own file: "panel-edp-legacy.yaml". This new file will
have a description that makes it obvious that we shouldn't use it for
new panels.

While we're doing this:
- We can remove eDP-specific properties from panel-simple.yaml since
  there are no more panels there.
- We don't need to copy non-eDP properties to the
  "panel-edp-legacy.yaml".
- We'll fork off a separate yaml file for "samsung,atna33xc20.yaml".
  This is an eDP panel which isn't _quite_ handled by the generic
  "edp-panel" compatible since it's not allowed to have an external
  backlight (it has one builtin) and it absolutely requires an
  "enable" GPIO.
- We'll un-fork the "sharp,ld-d5116z01b.yaml" and put it in
  "panel-edp-legacy.yaml" since there doesn't appear to be any reason
  for it to be separate.

Suggested-by: Dmitry Baryshkov 
Signed-off-by: Douglas Anderson 
---

 .../display/panel/panel-edp-legacy.yaml   | 127 ++
 .../bindings/display/panel/panel-simple.yaml  |  58 
 .../display/panel/samsung,atna33xc20.yaml |  95 +
 .../display/panel/sharp,ld-d5116z01b.yaml |  30 -
 4 files changed, 222 insertions(+), 88 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/display/panel/panel-edp-legacy.yaml
 create mode 100644 
Documentation/devicetree/bindings/display/panel/samsung,atna33xc20.yaml
 delete mode 100644 
Documentation/devicetree/bindings/display/panel/sharp,ld-d5116z01b.yaml

diff --git 
a/Documentation/devicetree/bindings/display/panel/panel-edp-legacy.yaml 
b/Documentation/devicetree/bindings/display/panel/panel-edp-legacy.yaml
new file mode 100644
index ..9e5864de49e7
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/panel-edp-legacy.yaml
@@ -0,0 +1,127 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/panel-edp-legacy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Legacy eDP panels from before the "edp-panel" compatible
+
+maintainers:
+  - Douglas Anderson 
+
+description: |
+  This binding file is a collection of eDP panels from before the generic
+  "edp-panel" compatible was introduced. It is kept around to support old
+  dts files. The only reason one might add a new panel here instead of using
+  the generic "edp-panel" is if it needed to be used on an eDP controller
+  that doesn't support the generic "edp-panel" compatible, but it should be
+  a strong preference to add the generic "edp-panel" compatible instead.
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+enum:
+# compatible must be listed in alphabetical order, ordered by compatible.
+# The description in the comment is mandatory for each compatible.
+
+# AU Optronics Corporation 10.1" WSVGA TFT LCD panel
+  - auo,b101ean01
+# AUO B116XAK01 eDP TFT LCD panel
+  - auo,b116xa01
+# AU Optronics Corporation 13.3" FHD (1920x1080) color TFT-LCD panel
+  - auo,b133han05
+# AU Optronics Corporation 13.3" FHD (1920x1080) color TFT-LCD panel
+  - auo,b133htn01
+# AU Optronics Corporation 13.3" WXGA (1366x768) TFT LCD panel
+  - auo,b133xtn01
+# AU Optronics Corporation 14.0" FHD (1920x1080) color TFT-LCD panel
+  - auo,b140han06
+# BOE OPTOELECTRONICS TECHNOLOGY 10.1" WXGA TFT LCD panel
+  - boe,nv101wxmn51
+# BOE NV133FHM-N61 13.3" FHD (1920x1080) TFT LCD Panel
+  - boe,nv110wtm-n61
+# BOE NV110WTM-N61 11.0" 2160x1440 TFT LCD Panel
+  - boe,nv133fhm-n61
+# BOE NV133FHM-N62 13.3" FHD (1920x1080) TFT LCD Panel
+  - boe,nv133fhm-n62
+# BOE NV140FHM-N49 14.0" FHD a-Si FT panel
+  - boe,nv140fhmn49
+# Innolux Corporation 11.6" WXGA (1366x768) TFT LCD panel
+  - innolux,n116bca-ea1
+# Innolux Corporation 11.6" WXGA (1366x768) TFT LCD panel
+  - innolux,n116bge
+# InnoLux 13.3" FHD (

[PATCH 6/8] drm/panel: himax-hx83102: If prepare fails, disable GPIO before regulators

2024-05-17 Thread Douglas Anderson
The enable GPIO should clearly be set low before turning off
regulators. That matches both the inverse order that things were
enabled and also the order in unprepare().

Fixes: 0ef94554dc40 ("drm/panel: himax-hx83102: Break out as separate driver")
Signed-off-by: Douglas Anderson 
---

 drivers/gpu/drm/panel/panel-himax-hx83102.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panel/panel-himax-hx83102.c 
b/drivers/gpu/drm/panel/panel-himax-hx83102.c
index 1a6975937f30..4ac7f9d8b232 100644
--- a/drivers/gpu/drm/panel/panel-himax-hx83102.c
+++ b/drivers/gpu/drm/panel/panel-himax-hx83102.c
@@ -578,13 +578,13 @@ static int hx83102_prepare(struct drm_panel *panel)
return 0;
 
 poweroff:
+   gpiod_set_value(ctx->enable_gpio, 0);
regulator_disable(ctx->avee);
 poweroffavdd:
regulator_disable(ctx->avdd);
 poweroff1v8:
usleep_range(5000, 7000);
regulator_disable(ctx->pp1800);
-   gpiod_set_value(ctx->enable_gpio, 0);
 
return ret;
 }
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[PATCH 7/8] drm/panel: himax-hx83102: Check for errors on the NOP in prepare()

2024-05-17 Thread Douglas Anderson
The mipi_dsi_dcs_nop() function returns an error but we weren't
checking it in hx83102_prepare(). Add a check. This is highly unlikely
to matter in practice. If the NOP failed then likely later MIPI
commands would fail too.

Found by code inspection.

Fixes: 0ef94554dc40 ("drm/panel: himax-hx83102: Break out as separate driver")
Signed-off-by: Douglas Anderson 
---

 drivers/gpu/drm/panel/panel-himax-hx83102.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panel/panel-himax-hx83102.c 
b/drivers/gpu/drm/panel/panel-himax-hx83102.c
index 4ac7f9d8b232..1ba623e41924 100644
--- a/drivers/gpu/drm/panel/panel-himax-hx83102.c
+++ b/drivers/gpu/drm/panel/panel-himax-hx83102.c
@@ -547,7 +547,11 @@ static int hx83102_prepare(struct drm_panel *panel)
 
usleep_range(1, 11000);
 
-   mipi_dsi_dcs_nop(ctx->dsi);
+   ret = mipi_dsi_dcs_nop(ctx->dsi);
+   if (ret < 0) {
+   dev_err(dev, "Failed to send NOP: %d\n", ret);
+   goto poweroff;
+   }
usleep_range(1000, 2000);
 
gpiod_set_value(ctx->enable_gpio, 1);
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[PATCH 8/8] drm/panel: himax-hx83102: use wrapped MIPI DCS functions

2024-05-17 Thread Douglas Anderson
Take advantage of some of the new wrapped routines introduced by
commit f79d6d28d8fe ("drm/mipi-dsi: wrap more functions for streamline
handling") to simplify the himax-hx83102 driver a bit more. This gets
rid of some extra error prints (since the _multi functions all print
errors for you) and simplifies the code a bit.

One thing here that isn't just refactoring is that in a few places we
now check with errors with "if (err)" instead of "if (err < 0)". All
errors are expected to be negative so this is not expected to have any
impact. The _multi code internally considers anything non-zero to be
an error so this just makes things consistent.

It can also be noted that hx83102_prepare() has a mix of things that
can take advantage of _multi calls and things that can't. The cleanest
seemed to be to use the multi_ctx still but consistently use the
"accum_err" variable for error returns, though that's definitely a
style decision with pros and cons.

Signed-off-by: Douglas Anderson 
---

 drivers/gpu/drm/panel/panel-himax-hx83102.c | 92 +++--
 1 file changed, 28 insertions(+), 64 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-himax-hx83102.c 
b/drivers/gpu/drm/panel/panel-himax-hx83102.c
index 1ba623e41924..6009a3fe1b8f 100644
--- a/drivers/gpu/drm/panel/panel-himax-hx83102.c
+++ b/drivers/gpu/drm/panel/panel-himax-hx83102.c
@@ -285,12 +285,10 @@ static int boe_nv110wum_init(struct hx83102 *ctx)
mipi_dsi_dcs_write_seq_multi(_ctx, HX83102_SETSPCCMD, 0x3f);
mipi_dsi_dcs_write_seq_multi(_ctx, HX83102_SETBANK, 0x00);
hx83102_enable_extended_cmds(_ctx, false);
-   if (dsi_ctx.accum_err)
-   return dsi_ctx.accum_err;
 
-   msleep(50);
+   mipi_dsi_msleep(dsi_ctx, 50);
 
-   return 0;
+   return dsi_ctx.accum_err;
 };
 
 static int ivo_t109nw41_init(struct hx83102 *ctx)
@@ -392,12 +390,10 @@ static int ivo_t109nw41_init(struct hx83102 *ctx)
mipi_dsi_dcs_write_seq_multi(_ctx, HX83102_SETSPCCMD, 0x3f);
mipi_dsi_dcs_write_seq_multi(_ctx, HX83102_SETBANK, 0x00);
hx83102_enable_extended_cmds(_ctx, false);
-   if (dsi_ctx.accum_err)
-   return dsi_ctx.accum_err;
 
-   msleep(60);
+   mipi_dsi_msleep(dsi_ctx, 60);
 
-   return 0;
+   return dsi_ctx.accum_err;
 };
 
 static const struct drm_display_mode starry_mode = {
@@ -472,40 +468,20 @@ static int hx83102_enable(struct drm_panel *panel)
return 0;
 }
 
-static int hx83102_panel_enter_sleep_mode(struct hx83102 *ctx)
-{
-   struct mipi_dsi_device *dsi = ctx->dsi;
-   int ret;
-
-   dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
-
-   ret = mipi_dsi_dcs_set_display_off(dsi);
-   if (ret < 0)
-   return ret;
-
-   ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
-   if (ret < 0)
-   return ret;
-
-   return 0;
-}
-
 static int hx83102_disable(struct drm_panel *panel)
 {
struct hx83102 *ctx = panel_to_hx83102(panel);
struct mipi_dsi_device *dsi = ctx->dsi;
-   struct device *dev = >dev;
-   int ret;
+   struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi };
 
-   ret = hx83102_panel_enter_sleep_mode(ctx);
-   if (ret < 0) {
-   dev_err(dev, "failed to set panel off: %d\n", ret);
-   return ret;
-   }
+   dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
 
-   msleep(150);
+   mipi_dsi_dcs_set_display_off_multi(_ctx);
+   mipi_dsi_dcs_enter_sleep_mode_multi(_ctx);
 
-   return 0;
+   mipi_dsi_msleep(_ctx, 150);
+
+   return dsi_ctx.accum_err;
 }
 
 static int hx83102_unprepare(struct drm_panel *panel)
@@ -526,32 +502,30 @@ static int hx83102_prepare(struct drm_panel *panel)
 {
struct hx83102 *ctx = panel_to_hx83102(panel);
struct mipi_dsi_device *dsi = ctx->dsi;
-   struct device *dev = >dev;
-   int ret;
+   struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi };
 
gpiod_set_value(ctx->enable_gpio, 0);
usleep_range(1000, 1500);
 
-   ret = regulator_enable(ctx->pp1800);
-   if (ret < 0)
-   return ret;
+   dsi_ctx.accum_err = regulator_enable(ctx->pp1800);
+   if (dsi_ctx.accum_err)
+   return dsi_ctx.accum_err;
 
usleep_range(3000, 5000);
 
-   ret = regulator_enable(ctx->avdd);
-   if (ret < 0)
+   dsi_ctx.accum_err = regulator_enable(ctx->avdd);
+   if (dsi_ctx.accum_err)
goto poweroff1v8;
-   ret = regulator_enable(ctx->avee);
-   if (ret < 0)
+   dsi_ctx.accum_err = regulator_enable(ctx->avee);
+   if (dsi_ctx.accum_err)
goto poweroffavdd;
 
usleep_range(1, 11000);
 
-   ret = mipi_dsi_dcs_nop(ctx->dsi);
-   if (ret < 0) {
-   dev_err(dev, "Failed to send NOP: %d\n", ret);
+ 

[PATCH 3/8] drm/panel: boe-tv101wum-nl6: Check for errors on the NOP in prepare()

2024-05-17 Thread Douglas Anderson
The mipi_dsi_dcs_nop() function returns an error but we weren't
checking it in boe_panel_prepare(). Add a check. This is highly
unlikely to matter in practice. If the NOP failed then likely later
MIPI commands would fail too.

Found by code inspection.

Fixes: 812562b8d881 ("drm/panel: boe-tv101wum-nl6: Fine tune the panel power 
sequence")
Signed-off-by: Douglas Anderson 
---

 drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c 
b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
index 028625d2d37d..f7beace455c3 100644
--- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
+++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
@@ -1456,7 +1456,11 @@ static int boe_panel_prepare(struct drm_panel *panel)
usleep_range(1, 11000);
 
if (boe->desc->lp11_before_reset) {
-   mipi_dsi_dcs_nop(boe->dsi);
+   ret = mipi_dsi_dcs_nop(boe->dsi);
+   if (ret < 0) {
+   dev_err(>dsi->dev, "Failed to send NOP: %d\n", 
ret);
+   goto poweroff;
+   }
usleep_range(1000, 2000);
}
gpiod_set_value(boe->enable_gpio, 1);
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[PATCH 5/8] drm/panel: ilitek-ili9882t: Check for errors on the NOP in prepare()

2024-05-17 Thread Douglas Anderson
The mipi_dsi_dcs_nop() function returns an error but we weren't
checking it in ili9882t_prepare(). Add a check. This is highly
unlikely to matter in practice. If the NOP failed then likely later
MIPI commands would fail too.

Found by code inspection.

Fixes: e2450d32e5fb ("drm/panel: ili9882t: Break out as separate driver")
Signed-off-by: Douglas Anderson 
---

 drivers/gpu/drm/panel/panel-ilitek-ili9882t.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c 
b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
index a2ea25bb6624..266a087fe14c 100644
--- a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
@@ -478,7 +478,11 @@ static int ili9882t_prepare(struct drm_panel *panel)
usleep_range(1, 11000);
 
// MIPI needs to keep the LP11 state before the lcm_reset pin is pulled 
high
-   mipi_dsi_dcs_nop(ili->dsi);
+   ret = mipi_dsi_dcs_nop(ili->dsi);
+   if (ret < 0) {
+   dev_err(>dsi->dev, "Failed to send NOP: %d\n", ret);
+   goto poweroff;
+   }
usleep_range(1000, 2000);
 
gpiod_set_value(ili->enable_gpio, 1);
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[PATCH 4/8] drm/panel: ilitek-ili9882t: If prepare fails, disable GPIO before regulators

2024-05-17 Thread Douglas Anderson
The enable GPIO should clearly be set low before turning off
regulators. That matches both the inverse order that things were
enabled and also the order in unprepare().

Fixes: e2450d32e5fb ("drm/panel: ili9882t: Break out as separate driver")
Signed-off-by: Douglas Anderson 
---

 drivers/gpu/drm/panel/panel-ilitek-ili9882t.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c 
b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
index 830d7cfbe857..a2ea25bb6624 100644
--- a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
@@ -495,13 +495,13 @@ static int ili9882t_prepare(struct drm_panel *panel)
return 0;
 
 poweroff:
+   gpiod_set_value(ili->enable_gpio, 0);
regulator_disable(ili->avee);
 poweroffavdd:
regulator_disable(ili->avdd);
 poweroff1v8:
usleep_range(5000, 7000);
regulator_disable(ili->pp1800);
-   gpiod_set_value(ili->enable_gpio, 0);
 
return ret;
 }
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[PATCH 2/8] drm/panel: boe-tv101wum-nl6: If prepare fails, disable GPIO before regulators

2024-05-17 Thread Douglas Anderson
The enable GPIO should clearly be set low before turning off
regulators. That matches both the inverse order that things were
enabled and also the order in unprepare().

Fixes: a869b9db7adf ("drm/panel: support for boe tv101wum-nl6 wuxga dsi video 
mode panel")
Signed-off-by: Douglas Anderson 
---

 drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c 
b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
index 8e839a1749e4..028625d2d37d 100644
--- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
+++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
@@ -1475,13 +1475,13 @@ static int boe_panel_prepare(struct drm_panel *panel)
return 0;
 
 poweroff:
+   gpiod_set_value(boe->enable_gpio, 0);
regulator_disable(boe->avee);
 poweroffavdd:
regulator_disable(boe->avdd);
 poweroff1v8:
usleep_range(5000, 7000);
regulator_disable(boe->pp1800);
-   gpiod_set_value(boe->enable_gpio, 0);
 
return ret;
 }
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[PATCH 1/8] drm/panel: himax-hx8394: Handle errors from mipi_dsi_dcs_set_display_on() better

2024-05-17 Thread Douglas Anderson
If mipi_dsi_dcs_set_display_on() returned an error then we'd store
that in the "ret" variable and jump to error handling. We'd then
attempt an orderly poweroff. Unfortunately we then blew away the value
stored in "ret". That means that if the orderly poweroff actually
worked then we're return 0 (no error) from hx8394_enable() even though
the panel wasn't enabled.

Fix this by not blowing away "ret".

Found by code inspection.

Fixes: 65dc9360f741 ("drm: panel: Add Himax HX8394 panel controller driver")
Signed-off-by: Douglas Anderson 
---

 drivers/gpu/drm/panel/panel-himax-hx8394.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-himax-hx8394.c 
b/drivers/gpu/drm/panel/panel-himax-hx8394.c
index ff0dc08b9829..cb9f46e853de 100644
--- a/drivers/gpu/drm/panel/panel-himax-hx8394.c
+++ b/drivers/gpu/drm/panel/panel-himax-hx8394.c
@@ -370,8 +370,7 @@ static int hx8394_enable(struct drm_panel *panel)
 
 sleep_in:
/* This will probably fail, but let's try orderly power off anyway. */
-   ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
-   if (!ret)
+   if (!mipi_dsi_dcs_enter_sleep_mode(dsi))
msleep(50);
 
return ret;
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[PATCH 0/8] drm/panel: Some very minor err handling fixes + more _multi

2024-05-17 Thread Douglas Anderson


This series is pretty much just addressing a few minor error handling
bugs that I noticed recently while reviewing some panel patches. For
the most part these are all old issues.

This also adjusts the new himax-hx83102 in a similar way that Dmitry
did in his recent series that included commit f79d6d28d8fe
("drm/mipi-dsi: wrap more functions for streamline handling"). His
series handled the panel driver that himax-hx83102 forked from but not
himax-hx83102.


Douglas Anderson (8):
  drm/panel: himax-hx8394: Handle errors from
mipi_dsi_dcs_set_display_on() better
  drm/panel: boe-tv101wum-nl6: If prepare fails, disable GPIO before
regulators
  drm/panel: boe-tv101wum-nl6: Check for errors on the NOP in prepare()
  drm/panel: ilitek-ili9882t: If prepare fails, disable GPIO before
regulators
  drm/panel: ilitek-ili9882t: Check for errors on the NOP in prepare()
  drm/panel: himax-hx83102: If prepare fails, disable GPIO before
regulators
  drm/panel: himax-hx83102: Check for errors on the NOP in prepare()
  drm/panel: himax-hx83102: use wrapped MIPI DCS functions

 .../gpu/drm/panel/panel-boe-tv101wum-nl6.c|  8 +-
 drivers/gpu/drm/panel/panel-himax-hx83102.c   | 92 ++-
 drivers/gpu/drm/panel/panel-himax-hx8394.c|  3 +-
 drivers/gpu/drm/panel/panel-ilitek-ili9882t.c |  8 +-
 4 files changed, 43 insertions(+), 68 deletions(-)

-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[PATCH v5 7/9] drm/panel: boe-tv101wum-nl6: Don't use a table for initting panels

2024-05-14 Thread Douglas Anderson
Consensus on the mailing lists is that panels shouldn't use a table of
init commands but should instead use init functions. With the recently
introduced mipi_dsi_dcs_write_seq_multi() this is not only clean/easy
but also saves space. Measuring before/after this change:

$ scripts/bloat-o-meter \
  .../before/panel-boe-tv101wum-nl6.ko \
  .../after/panel-boe-tv101wum-nl6.ko
add/remove: 14/8 grow/shrink: 0/1 up/down: 27062/-31433 (-4371)
Function old new   delta
inx_hj110iz_init   -7040   +7040
boe_tv110c9m_init  -6440   +6440
boe_init   -5916   +5916
starry_qfh032011_53g_init  -1944   +1944
starry_himax83102_j02_init -1228   +1228
inx_hj110iz_init.d -1040   +1040
boe_tv110c9m_init.d- 982+982
auo_b101uan08_3_init   - 944+944
boe_init.d - 580+580
starry_himax83102_j02_init.d   - 512+512
starry_qfh032011_53g_init.d- 180+180
auo_kd101n80_45na_init - 172+172
auo_b101uan08_3_init.d -  82 +82
auo_kd101n80_45na_init.d   -   2  +2
auo_kd101n80_45na_init_cmd   144   --144
boe_panel_prepare592 440-152
auo_b101uan08_3_init_cmd1056   -   -1056
starry_himax83102_j02_init_cmd  1392   -   -1392
starry_qfh032011_53g_init_cmd   2256   -   -2256
.compoundliteral3393   -   -3393
boe_init_cmd7008   -   -7008
boe_tv110c9m_init_cmd   7656   -   -7656
inx_hj110iz_init_cmd8376   -   -8376
Total: Before=37297, After=32926, chg -11.72%

Let's do the conversion.

Since we're touching all the tables, let's also convert hex numbers to
lower case as per kernel conventions.

Reviewed-by: Linus Walleij 
Signed-off-by: Douglas Anderson 
---

(no changes since v3)

Changes in v3:
- Fix spacing of init function.
- Remove an unneeded error print.
- Squash boe-tv101wum-nl6 lowercase patch into main patch

Changes in v2:
- New

 .../gpu/drm/panel/panel-boe-tv101wum-nl6.c| 2792 +
 1 file changed, 1442 insertions(+), 1350 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c 
b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
index 0ffe8f8c01de..aab60cec0603 100644
--- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
+++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
@@ -17,6 +17,8 @@
 
 #include 
 
+struct boe_panel;
+
 struct panel_desc {
const struct drm_display_mode *modes;
unsigned int bpc;
@@ -32,7 +34,7 @@ struct panel_desc {
 
unsigned long mode_flags;
enum mipi_dsi_pixel_format format;
-   const struct panel_init_cmd *init_cmds;
+   int (*init)(struct boe_panel *boe);
unsigned int lanes;
bool discharge_on_disable;
bool lp11_before_reset;
@@ -54,1318 +56,1449 @@ struct boe_panel {
bool prepared;
 };
 
-enum dsi_cmd_type {
-   INIT_DCS_CMD,
-   DELAY_CMD,
-};
+static int boe_tv110c9m_init(struct boe_panel *boe)
+{
+   struct mipi_dsi_multi_context ctx = { .dsi = boe->dsi };
+
+   mipi_dsi_dcs_write_seq_multi(, 0xff, 0x20);
+   mipi_dsi_dcs_write_seq_multi(, 0xfb, 0x01);
+   mipi_dsi_dcs_write_seq_multi(, 0x05, 0xd9);
+   mipi_dsi_dcs_write_seq_multi(, 0x07, 0x78);
+   mipi_dsi_dcs_write_seq_multi(, 0x08, 0x5a);
+   mipi_dsi_dcs_write_seq_multi(, 0x0d, 0x63);
+   mipi_dsi_dcs_write_seq_multi(, 0x0e, 0x91);
+   mipi_dsi_dcs_write_seq_multi(, 0x0f, 0x73);
+   mipi_dsi_dcs_write_seq_multi(, 0x95, 0xe6);
+   mipi_dsi_dcs_write_seq_multi(, 0x96, 0xf0);
+   mipi_dsi_dcs_write_seq_multi(, 0x30, 0x00);
+   mipi_dsi_dcs_write_seq_multi(, 0x6d, 0x66);
+   mipi_dsi_dcs_write_seq_multi(, 0x75, 0xa2);
+   mipi_dsi_dcs_write_seq_multi(, 0x77, 0x3b);
+
+   mipi_dsi_dcs_write_seq_multi(, 0xb0, 0x00, 0x08, 0x00, 0x23, 0x00, 
0x4d, 0x00, 0x6d,
+0x00, 0x89, 0x00, 0xa1, 0x00, 0xb6, 0x00, 
0xc9);
+   mipi_dsi_dcs_write_seq_multi(, 0xb1, 0x00, 0xda, 0x01, 0x13, 0x01, 
0x3c, 0x01, 0x7e,
+0x01, 0xab, 0x01, 0xf7, 0x02, 0x2f, 0x02, 
0x31);
+   mipi_dsi_dcs_write_seq_multi(, 0xb2, 0x02, 0x67, 0x02, 0xa6, 0x02, 
0xd1, 0x03, 0x08,
+0x03, 0x2e, 0x03, 0x5b, 0x03, 0x6b, 0x03, 
0x7b);
+   mipi_dsi_dcs_write_seq_multi(, 0xb3, 0x03, 0x8e, 0x03, 0xa2, 0x03, 
0xb7, 0x03, 0xe7,
+0x03, 0xfd, 0x03, 0xff);
+
+   mipi_dsi_dcs_write_seq_mu

[PATCH v5 9/9] drm/panel: innolux-p079zca: Don't use a table for initting panels

2024-05-14 Thread Douglas Anderson
Consensus on the mailing lists is that panels shouldn't use a table of
init commands but should instead use init functions. We'll use the
same concepts as the recently introduced
mipi_dsi_generic_write_seq_multi() to make this clean/easy and also
not bloat the driver too much. Measuring before/after this change:

$ scripts/bloat-o-meter \
  .../before/panel-innolux-p079zca.ko \
  .../after/panel-innolux-p079zca.ko
add/remove: 3/2 grow/shrink: 0/1 up/down: 2356/-1944 (412)
Function old new   delta
innolux_p097pfg_init   -1772   +1772
innolux_p097pfg_init.d - 480+480
innolux_panel_write_multi  - 104+104
innolux_panel_prepare412 308-104
.compoundliteral 480   --480
innolux_p097pfg_init_cmds   1360   -   -1360
Total: Before=5802, After=6214, chg +7.10%

Note that, unlike some other drivers, we actually make this panel
driver _bigger_ by using the new functions. This is because the
innolux-p079zca panel driver didn't have as complex of a table and
thus the old table was more efficient than the code. The bloat is
still not giant (only 412 bytes).

Also note that we can't direclty use
mipi_dsi_generic_write_seq_multi() here because we need to deal with
the crazy "nop" that this driver sends after all commands. This means
that we have to write code that is "inspired" by the new macros.

Since we're touching all the tables, let's also convert hex numbers to
lower case as per kernel conventions.

Reviewed-by: Linus Walleij 
Signed-off-by: Douglas Anderson 
---

(no changes since v4)

Changes in v4:
- Test to see if init is non-NULL before using it.

Changes in v3:
- New

 drivers/gpu/drm/panel/panel-innolux-p079zca.c | 284 +-
 1 file changed, 140 insertions(+), 144 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-innolux-p079zca.c 
b/drivers/gpu/drm/panel/panel-innolux-p079zca.c
index 485178a99910..ade8bf7491ee 100644
--- a/drivers/gpu/drm/panel/panel-innolux-p079zca.c
+++ b/drivers/gpu/drm/panel/panel-innolux-p079zca.c
@@ -17,14 +17,7 @@
 #include 
 #include 
 
-struct panel_init_cmd {
-   size_t len;
-   const char *data;
-};
-
-#define _INIT_CMD(...) { \
-   .len = sizeof((char[]){__VA_ARGS__}), \
-   .data = (char[]){__VA_ARGS__} }
+struct innolux_panel;
 
 struct panel_desc {
const struct drm_display_mode *mode;
@@ -36,7 +29,7 @@ struct panel_desc {
 
unsigned long flags;
enum mipi_dsi_pixel_format format;
-   const struct panel_init_cmd *init_cmds;
+   int (*init)(struct innolux_panel *innolux);
unsigned int lanes;
const char * const *supply_names;
unsigned int num_supplies;
@@ -132,32 +125,10 @@ static int innolux_panel_prepare(struct drm_panel *panel)
/* p079zca: t4, p097pfg: t5 */
usleep_range(2, 21000);
 
-   if (innolux->desc->init_cmds) {
-   const struct panel_init_cmd *cmds =
-   innolux->desc->init_cmds;
-   unsigned int i;
-
-   for (i = 0; cmds[i].len != 0; i++) {
-   const struct panel_init_cmd *cmd = [i];
-
-   err = mipi_dsi_generic_write(innolux->link, cmd->data,
-cmd->len);
-   if (err < 0) {
-   dev_err(panel->dev, "failed to write command 
%u\n", i);
-   goto poweroff;
-   }
-
-   /*
-* Included by random guessing, because without this
-* (or at least, some delay), the panel sometimes
-* didn't appear to pick up the command sequence.
-*/
-   err = mipi_dsi_dcs_nop(innolux->link);
-   if (err < 0) {
-   dev_err(panel->dev, "failed to send DCS nop: 
%d\n", err);
-   goto poweroff;
-   }
-   }
+   if (innolux->desc->init) {
+   err = innolux->desc->init(innolux);
+   if (err < 0)
+   goto poweroff;
}
 
err = mipi_dsi_dcs_exit_sleep_mode(innolux->link);
@@ -250,119 +221,144 @@ static const struct drm_display_mode 
innolux_p097pfg_mode = {
.vtotal = 2048 + 100 + 2 + 18,
 };
 
+static void innolux_panel_write_multi(struct mipi_dsi_multi_context *ctx,
+ const void *payload, size_t size)
+{
+   struct mipi_dsi_device *dsi = ctx->dsi;
+   struct device *dev = >dev;
+
+   mipi_dsi_generic_write_multi(ctx, payload, size);
+   if (ctx->

[PATCH v5 8/9] drm/panel: ili9882t: Don't use a table for initting panels

2024-05-14 Thread Douglas Anderson
Consensus on the mailing lists is that panels shouldn't use a table of
init commands but should instead use init functions. With the recently
introduced mipi_dsi_dcs_write_seq_multi() this is not only clean/easy
but also saves space. Measuring before/after this change:

$ scripts/bloat-o-meter \
  .../before/panel-ilitek-ili9882t.ko \
  .../after/panel-ilitek-ili9882t.ko
add/remove: 3/2 grow/shrink: 0/2 up/down: 6834/-8177 (-1343)
Function old new   delta
starry_ili9882t_init   -6152   +6152
starry_ili9882t_init.d - 678+678
ili9882t_disable.d -   4  +4
ili9882t_disable 260 228 -32
ili9882t_prepare 540 396-144
.compoundliteral 681   --681
starry_ili9882t_init_cmd7320   -   -7320
Total: Before=11928, After=10585, chg -11.26%

Let's do the conversion.

Since we're touching all the tables, let's also convert hex numbers to
lower case as per kernel conventions.

Reviewed-by: Linus Walleij 
Signed-off-by: Douglas Anderson 
---

(no changes since v3)

Changes in v3:
- New

 drivers/gpu/drm/panel/panel-ilitek-ili9882t.c | 794 --
 1 file changed, 368 insertions(+), 426 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c 
b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
index 267a5307041c..58fc1d799371 100644
--- a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
@@ -15,6 +15,8 @@
 
 #include 
 
+struct ili9882t;
+
 /*
  * Use this descriptor struct to describe different panels using the
  * Ilitek ILI9882T display controller.
@@ -34,7 +36,7 @@ struct panel_desc {
 
unsigned long mode_flags;
enum mipi_dsi_pixel_format format;
-   const struct panel_init_cmd *init_cmds;
+   int (*init)(struct ili9882t *boe);
unsigned int lanes;
 };
 
@@ -52,433 +54,372 @@ struct ili9882t {
struct gpio_desc *enable_gpio;
 };
 
-enum dsi_cmd_type {
-   INIT_DCS_CMD,
-   DELAY_CMD,
-};
-
-struct panel_init_cmd {
-   enum dsi_cmd_type type;
-   size_t len;
-   const char *data;
-};
-
-#define _INIT_DCS_CMD(...) { \
-   .type = INIT_DCS_CMD, \
-   .len = sizeof((char[]){__VA_ARGS__}), \
-   .data = (char[]){__VA_ARGS__} }
-
-#define _INIT_DELAY_CMD(...) { \
-   .type = DELAY_CMD,\
-   .len = sizeof((char[]){__VA_ARGS__}), \
-   .data = (char[]){__VA_ARGS__} }
-
 /* ILI9882-specific commands, add new commands as you decode them */
 #define ILI9882T_DCS_SWITCH_PAGE   0xFF
 
-#define _INIT_SWITCH_PAGE_CMD(page) \
-   _INIT_DCS_CMD(ILI9882T_DCS_SWITCH_PAGE, 0x98, 0x82, (page))
-
-static const struct panel_init_cmd starry_ili9882t_init_cmd[] = {
-   _INIT_DELAY_CMD(5),
-   _INIT_SWITCH_PAGE_CMD(0x01),
-   _INIT_DCS_CMD(0x00, 0x42),
-   _INIT_DCS_CMD(0x01, 0x11),
-   _INIT_DCS_CMD(0x02, 0x00),
-   _INIT_DCS_CMD(0x03, 0x00),
-
-   _INIT_DCS_CMD(0x04, 0x01),
-   _INIT_DCS_CMD(0x05, 0x11),
-   _INIT_DCS_CMD(0x06, 0x00),
-   _INIT_DCS_CMD(0x07, 0x00),
-
-   _INIT_DCS_CMD(0x08, 0x80),
-   _INIT_DCS_CMD(0x09, 0x81),
-   _INIT_DCS_CMD(0x0A, 0x71),
-   _INIT_DCS_CMD(0x0B, 0x00),
-
-   _INIT_DCS_CMD(0x0C, 0x00),
-   _INIT_DCS_CMD(0x0E, 0x1A),
-
-   _INIT_DCS_CMD(0x24, 0x00),
-   _INIT_DCS_CMD(0x25, 0x00),
-   _INIT_DCS_CMD(0x26, 0x00),
-   _INIT_DCS_CMD(0x27, 0x00),
-
-   _INIT_DCS_CMD(0x2C, 0xD4),
-   _INIT_DCS_CMD(0xB9, 0x40),
-
-   _INIT_DCS_CMD(0xB0, 0x11),
-
-   _INIT_DCS_CMD(0xE6, 0x32),
-   _INIT_DCS_CMD(0xD1, 0x30),
-
-   _INIT_DCS_CMD(0xD6, 0x55),
-
-   _INIT_DCS_CMD(0xD0, 0x01),
-   _INIT_DCS_CMD(0xE3, 0x93),
-   _INIT_DCS_CMD(0xE4, 0x00),
-   _INIT_DCS_CMD(0xE5, 0x80),
-
-   _INIT_DCS_CMD(0x31, 0x07),
-   _INIT_DCS_CMD(0x32, 0x07),
-   _INIT_DCS_CMD(0x33, 0x07),
-   _INIT_DCS_CMD(0x34, 0x07),
-   _INIT_DCS_CMD(0x35, 0x07),
-   _INIT_DCS_CMD(0x36, 0x01),
-   _INIT_DCS_CMD(0x37, 0x00),
-   _INIT_DCS_CMD(0x38, 0x28),
-   _INIT_DCS_CMD(0x39, 0x29),
-   _INIT_DCS_CMD(0x3A, 0x11),
-   _INIT_DCS_CMD(0x3B, 0x13),
-   _INIT_DCS_CMD(0x3C, 0x15),
-   _INIT_DCS_CMD(0x3D, 0x17),
-   _INIT_DCS_CMD(0x3E, 0x09),
-   _INIT_DCS_CMD(0x3F, 0x0D),
-   _INIT_DCS_CMD(0x40, 0x02),
-   _INIT_DCS_CMD(0x41, 0x02),
-   _INIT_DCS_CMD(0x42, 0x02),
-   _INIT_DCS_CMD(0x43, 0x02),
-   _INIT_DCS_CMD(0x44, 0x02),
-   _INIT_DCS_CMD(0x45, 0x02),
-   _INIT_DCS_CMD(0x46, 0x02),
-
-   _INIT_DCS_CMD(0x47, 0x07),
-   _INIT_DCS_CMD(0x48, 0x07),
-   _INIT_DCS_CMD(0x49, 0x07),
-   _INIT_DCS_CMD(0x4A, 0x07),
-   _INIT_DCS_CMD(0x4B, 0x07),
-   _INIT_DCS_CMD(0x4C, 0x01),
-   _INIT_DCS_CMD(0x4D, 0x00

[PATCH v5 6/9] drm/panel: novatek-nt36672e: Switch to mipi_dsi_dcs_write_seq_multi()

2024-05-14 Thread Douglas Anderson
This is a mechanical conversion of the novatek-nt36672e driver to use
the new mipi_dsi_dcs_write_seq_multi(). The new function is easier for
clients to understand and using it also causes smaller code to be
generated. Specifically:

$ scripts/bloat-o-meter \
  ...after/panel-novatek-nt36672e.ko \
  ...ctx/panel-novatek-nt36672e.ko
add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-988 (-988)
Function old new   delta
nt36672e_1080x2408_60hz_init62365248-988
Total: Before=10651, After=9663, chg -9.28%

Cc: Ritesh Kumar 
Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Linus Walleij 
Signed-off-by: Douglas Anderson 
---
This change is only compile tested. I don't use this panel myself but
arbitrarily picked it as an example to look at when working on the
MIPI DSI macros.

(no changes since v3)

Changes in v3:
- Fix spacing of init function.

Changes in v2:
- New

 .../gpu/drm/panel/panel-novatek-nt36672e.c| 576 +-
 1 file changed, 289 insertions(+), 287 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36672e.c 
b/drivers/gpu/drm/panel/panel-novatek-nt36672e.c
index 20b7bfe4aa12..9ce8df455232 100644
--- a/drivers/gpu/drm/panel/panel-novatek-nt36672e.c
+++ b/drivers/gpu/drm/panel/panel-novatek-nt36672e.c
@@ -51,293 +51,295 @@ static inline struct nt36672e_panel 
*to_nt36672e_panel(struct drm_panel *panel)
 
 static int nt36672e_1080x2408_60hz_init(struct mipi_dsi_device *dsi)
 {
-   mipi_dsi_dcs_write_seq(dsi, 0xff, 0x10);
-   mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
-   mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x00);
-   mipi_dsi_dcs_write_seq(dsi, 0xc0, 0x00);
-   mipi_dsi_dcs_write_seq(dsi, 0xc1, 0x89, 0x28, 0x00, 0x08, 0x00, 0xaa, 
0x02,
-   0x0e, 0x00, 0x2b, 0x00, 0x07, 0x0d, 0xb7, 0x0c, 
0xb7);
-
-   mipi_dsi_dcs_write_seq(dsi, 0xc2, 0x1b, 0xa0);
-   mipi_dsi_dcs_write_seq(dsi, 0xff, 0x20);
-   mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
-   mipi_dsi_dcs_write_seq(dsi, 0x01, 0x66);
-   mipi_dsi_dcs_write_seq(dsi, 0x06, 0x40);
-   mipi_dsi_dcs_write_seq(dsi, 0x07, 0x38);
-   mipi_dsi_dcs_write_seq(dsi, 0x2f, 0x83);
-   mipi_dsi_dcs_write_seq(dsi, 0x69, 0x91);
-   mipi_dsi_dcs_write_seq(dsi, 0x95, 0xd1);
-   mipi_dsi_dcs_write_seq(dsi, 0x96, 0xd1);
-   mipi_dsi_dcs_write_seq(dsi, 0xf2, 0x64);
-   mipi_dsi_dcs_write_seq(dsi, 0xf3, 0x54);
-   mipi_dsi_dcs_write_seq(dsi, 0xf4, 0x64);
-   mipi_dsi_dcs_write_seq(dsi, 0xf5, 0x54);
-   mipi_dsi_dcs_write_seq(dsi, 0xf6, 0x64);
-   mipi_dsi_dcs_write_seq(dsi, 0xf7, 0x54);
-   mipi_dsi_dcs_write_seq(dsi, 0xf8, 0x64);
-   mipi_dsi_dcs_write_seq(dsi, 0xf9, 0x54);
-   mipi_dsi_dcs_write_seq(dsi, 0xff, 0x24);
-   mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
-   mipi_dsi_dcs_write_seq(dsi, 0x01, 0x0f);
-   mipi_dsi_dcs_write_seq(dsi, 0x03, 0x0c);
-   mipi_dsi_dcs_write_seq(dsi, 0x05, 0x1d);
-   mipi_dsi_dcs_write_seq(dsi, 0x08, 0x2f);
-   mipi_dsi_dcs_write_seq(dsi, 0x09, 0x2e);
-   mipi_dsi_dcs_write_seq(dsi, 0x0a, 0x2d);
-   mipi_dsi_dcs_write_seq(dsi, 0x0b, 0x2c);
-   mipi_dsi_dcs_write_seq(dsi, 0x11, 0x17);
-   mipi_dsi_dcs_write_seq(dsi, 0x12, 0x13);
-   mipi_dsi_dcs_write_seq(dsi, 0x13, 0x15);
-   mipi_dsi_dcs_write_seq(dsi, 0x15, 0x14);
-   mipi_dsi_dcs_write_seq(dsi, 0x16, 0x16);
-   mipi_dsi_dcs_write_seq(dsi, 0x17, 0x18);
-   mipi_dsi_dcs_write_seq(dsi, 0x1b, 0x01);
-   mipi_dsi_dcs_write_seq(dsi, 0x1d, 0x1d);
-   mipi_dsi_dcs_write_seq(dsi, 0x20, 0x2f);
-   mipi_dsi_dcs_write_seq(dsi, 0x21, 0x2e);
-   mipi_dsi_dcs_write_seq(dsi, 0x22, 0x2d);
-   mipi_dsi_dcs_write_seq(dsi, 0x23, 0x2c);
-   mipi_dsi_dcs_write_seq(dsi, 0x29, 0x17);
-   mipi_dsi_dcs_write_seq(dsi, 0x2a, 0x13);
-   mipi_dsi_dcs_write_seq(dsi, 0x2b, 0x15);
-   mipi_dsi_dcs_write_seq(dsi, 0x2f, 0x14);
-   mipi_dsi_dcs_write_seq(dsi, 0x30, 0x16);
-   mipi_dsi_dcs_write_seq(dsi, 0x31, 0x18);
-   mipi_dsi_dcs_write_seq(dsi, 0x32, 0x04);
-   mipi_dsi_dcs_write_seq(dsi, 0x34, 0x10);
-   mipi_dsi_dcs_write_seq(dsi, 0x35, 0x1f);
-   mipi_dsi_dcs_write_seq(dsi, 0x36, 0x1f);
-   mipi_dsi_dcs_write_seq(dsi, 0x4d, 0x14);
-   mipi_dsi_dcs_write_seq(dsi, 0x4e, 0x36);
-   mipi_dsi_dcs_write_seq(dsi, 0x4f, 0x36);
-   mipi_dsi_dcs_write_seq(dsi, 0x53, 0x36);
-   mipi_dsi_dcs_write_seq(dsi, 0x71, 0x30);
-   mipi_dsi_dcs_write_seq(dsi, 0x79, 0x11);
-   mipi_dsi_dcs_write_seq(dsi, 0x7a, 0x82);
-   mipi_dsi_dcs_write_seq(dsi, 0x7b, 0x8f);
-   mipi_dsi_dcs_write_seq(dsi, 0x7d, 0x04);
-   mipi_dsi_dcs_write_seq(dsi, 0x80, 0x04);
-   mipi_dsi_dcs_write_seq(dsi, 0x81, 0x04);
-   mipi_dsi_dcs_write_seq(dsi, 0x82, 0x13);
-   mipi_dsi_dcs_write_seq(dsi, 0x84, 0x31);
-   mipi_dsi_dcs_write_seq(dsi, 0x85, 0x00);
-   mipi_dsi_dcs_write_seq(dsi, 0x86, 0x00

[PATCH v5 5/9] drm/mipi-dsi: Introduce mipi_dsi_*_write_seq_multi()

2024-05-14 Thread Douglas Anderson
The current mipi_dsi_*_write_seq() macros are non-intutitive because
they contain a hidden "return" statement that will return out of the
_caller_ of the macro. Let's mark them as deprecated and instead
introduce some new macros that are more intuitive.

These new macros are less optimal when an error occurs but should
behave more optimally when there is no error. Specifically these new
macros cause smaller code to get generated and the code size savings
(less to fetch from RAM, less cache space used, less RAM used) are
important. Since the error case isn't something we need to optimize
for and these new macros are easier to understand and more flexible,
they should be used.

After converting to use these new functions, one example shows some
nice savings while also being easier to understand.

$ scripts/bloat-o-meter \
  ...after/panel-novatek-nt36672e.ko \
  ...ctx/panel-novatek-nt36672e.ko
add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-988 (-988)
Function old new   delta
nt36672e_1080x2408_60hz_init62365248-988
Total: Before=10651, After=9663, chg -9.28%

Reviewed-by: Neil Armstrong 
Reviewed-by: Linus Walleij 
Signed-off-by: Douglas Anderson 
---
Right now this patch introduces two new functions in drm_mipi_dsi.c.
Alternatively we could have changed the prototype of the "chatty"
functions and made the deprecated macros adapt to the new prototype.
While this sounds nice, it bloated callers of the deprecated functioin
a bit because it caused the compiler to emit less optimal code. It
doesn't seem terrible to add two more functions, so I went that
way. There may be cases where callers who aren't writing many
sequences prefer to use the "chatty" versions anyway.

(no changes since v3)

Changes in v3:
- Add a TODO item for cleaning up the deprecated macros/functions.
- Inline kerneldoc comments for struct mipi_dsi_multi_context.

Changes in v2:
- New

 Documentation/gpu/todo.rst | 18 ++
 drivers/gpu/drm/drm_mipi_dsi.c | 56 ++
 include/drm/drm_mipi_dsi.h | 62 ++
 3 files changed, 136 insertions(+)

diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index e2a0585915b3..2734b8a34541 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -494,6 +494,24 @@ Contact: Douglas Anderson 
 
 Level: Starter/Intermediate
 
+Transition away from using mipi_dsi_*_write_seq()
+-
+
+The macros mipi_dsi_generic_write_seq() and mipi_dsi_dcs_write_seq() are
+non-intuitive because, if there are errors, they return out of the *caller's*
+function. We should move all callers to use mipi_dsi_generic_write_seq_multi()
+and mipi_dsi_dcs_write_seq_multi() macros instead.
+
+Once all callers are transitioned, the macros and the functions that they call,
+mipi_dsi_generic_write_chatty() and mipi_dsi_dcs_write_buffer_chatty(), can
+probably be removed. Alternatively, if people feel like the _multi() variants
+are overkill for some use cases, we could keep the mipi_dsi_*_write_seq()
+variants but change them not to return out of the caller.
+
+Contact: Douglas Anderson 
+
+Level: Starter
+
 
 Core refactorings
 =
diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 4d2685d5a6e0..26c7383406c1 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -792,6 +792,34 @@ int mipi_dsi_generic_write_chatty(struct mipi_dsi_device 
*dsi,
 }
 EXPORT_SYMBOL(mipi_dsi_generic_write_chatty);
 
+/**
+ * mipi_dsi_generic_write_multi() - mipi_dsi_generic_write_chatty() w/ 
accum_err
+ * @ctx: Context for multiple DSI transactions
+ * @payload: buffer containing the payload
+ * @size: size of payload buffer
+ *
+ * Like mipi_dsi_generic_write_chatty() but deals with errors in a way that
+ * makes it convenient to make several calls in a row.
+ */
+void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx,
+ const void *payload, size_t size)
+{
+   struct mipi_dsi_device *dsi = ctx->dsi;
+   struct device *dev = >dev;
+   ssize_t ret;
+
+   if (ctx->accum_err)
+   return;
+
+   ret = mipi_dsi_generic_write(dsi, payload, size);
+   if (ret < 0) {
+   ctx->accum_err = ret;
+   dev_err(dev, "sending generic data %*ph failed: %d\n",
+   (int)size, payload, ctx->accum_err);
+   }
+}
+EXPORT_SYMBOL(mipi_dsi_generic_write_multi);
+
 /**
  * mipi_dsi_generic_read() - receive data using a generic read packet
  * @dsi: DSI peripheral device
@@ -908,6 +936,34 @@ int mipi_dsi_dcs_write_buffer_chatty(struct 
mipi_dsi_device *dsi,
 }
 EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_chatty);
 
+/**
+ * mipi_dsi_dcs_write_buffer_multi - mipi_dsi_dcs_write_buffer_chatty() w/ 
accum_err
+ * @ctx: Context 

[PATCH v5 3/9] drm/mipi-dsi: mipi_dsi_*_write functions don't need to ratelimit prints

2024-05-14 Thread Douglas Anderson
We really don't expect these errors to be printed over and over
again. When a driver hits the error it should bail out. Just use a
normal error print.

This gives a nice space savings for users of these functions:

$ scripts/bloat-o-meter \
  .../before/panel-novatek-nt36672e.ko \
  .../after/panel-novatek-nt36672e.ko
add/remove: 0/1 grow/shrink: 0/1 up/down: 0/-16760 (-16760)
Function old new   delta
nt36672e_1080x2408_60hz_init   17080   10640   -6440
nt36672e_1080x2408_60hz_init._rs   10320   -  -10320
Total: Before=31815, After=15055, chg -52.68%

Reviewed-by: Neil Armstrong 
Reviewed-by: Linus Walleij 
Signed-off-by: Douglas Anderson 
---

(no changes since v3)

Changes in v3:
- ("mipi_dsi_*_write functions don't need to ratelimit...") moved earlier.

Changes in v2:
- New

 include/drm/drm_mipi_dsi.h | 24 +++-
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index e0f56564bf97..67967be48dbd 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -314,17 +314,16 @@ int mipi_dsi_dcs_get_display_brightness_large(struct 
mipi_dsi_device *dsi,
  * @dsi: DSI peripheral device
  * @seq: buffer containing the payload
  */
-#define mipi_dsi_generic_write_seq(dsi, seq...)
 \
-   do {
\
-   static const u8 d[] = { seq };  
\
-   struct device *dev = >dev; 
\
-   ssize_t ret;
\
-   ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d));
\
-   if (ret < 0) {  
\
-   dev_err_ratelimited(dev, "transmit data failed: %zd\n", 
\
-   ret);   
\
-   return ret; 
\
-   }   
\
+#define mipi_dsi_generic_write_seq(dsi, seq...)   \
+   do {  \
+   static const u8 d[] = { seq };\
+   struct device *dev = >dev;   \
+   ssize_t ret;  \
+   ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d));  \
+   if (ret < 0) {\
+   dev_err(dev, "transmit data failed: %zd\n", ret); \
+   return ret;   \
+   } \
} while (0)
 
 /**
@@ -340,8 +339,7 @@ int mipi_dsi_dcs_get_display_brightness_large(struct 
mipi_dsi_device *dsi,
ssize_t ret;\
ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \
if (ret < 0) {  \
-   dev_err_ratelimited(\
-   dev, "sending command %#02x failed: %zd\n", \
+   dev_err(dev, "sending command %#02x failed: %zd\n", \
cmd, ret);  \
return ret; \
}   \
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[PATCH v5 4/9] drm/mipi-dsi: Reduce driver bloat of mipi_dsi_*_write_seq()

2024-05-14 Thread Douglas Anderson
Through a cooperative effort between Hsin-Yi Wang and Dmitry
Baryshkov, we have realized the dev_err() in the
mipi_dsi_*_write_seq() macros was causing quite a bit of bloat to the
kernel. Let's hoist this call into drm_mipi_dsi.c by adding a "chatty"
version of the functions that includes the print. While doing this,
add a bit more comments to these macros making it clear that they
print errors and also that they return out of _the caller's_ function.

Without any changes to clients this gives a nice savings. Specifically
the macro was inlined and thus the error report call was inlined into
every call to mipi_dsi_dcs_write_seq() and
mipi_dsi_generic_write_seq(). By using a call to a "chatty" function,
the usage is reduced to one call in the chatty function and a function
call at the invoking site.

Building with my build system shows one example:

$ scripts/bloat-o-meter \
  .../before/panel-novatek-nt36672e.ko \
  .../after/panel-novatek-nt36672e.ko
add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-4404 (-4404)
Function old new   delta
nt36672e_1080x2408_60hz_init   106406236   -4404
Total: Before=15055, After=10651, chg -29.25%

Note that given the change in location of the print it's harder to
include the "cmd" in the printout for mipi_dsi_dcs_write_seq() since,
theoretically, someone could call the new chatty function with a
zero-size array and it would be illegal to dereference data[0].
There's a printk format to print the whole buffer and this is probably
more useful for debugging anyway. Given that we're doing this for
mipi_dsi_dcs_write_seq(), let's also print the buffer for
mipi_dsi_generic_write_seq() in the error case.

It should be noted that the current consensus of DRM folks is that the
mipi_dsi_*_write_seq() should be deprecated due to the non-intuitive
return behavior. A future patch will formally mark them as deprecated
and provide an alternative.

Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Neil Armstrong 
Reviewed-by: Linus Walleij 
Signed-off-by: Douglas Anderson 
---

Changes in v5:
- Fix comment dev_err_ratelimited() => dev_err().

Changes in v4:
- Update wording as per Linus W.

Changes in v3:
- Rebased upon patch to remove ratelimit of prints.

Changes in v2:
- Add some comments to the macros about printing and returning.
- Change the way err value is handled in prep for next patch.
- Modify commit message now that this is part of a series.
- Rebased upon patches to avoid theoretical int overflow.

 drivers/gpu/drm/drm_mipi_dsi.c | 56 ++
 include/drm/drm_mipi_dsi.h | 47 +++-
 2 files changed, 82 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 795001bb7ff1..4d2685d5a6e0 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -764,6 +764,34 @@ ssize_t mipi_dsi_generic_write(struct mipi_dsi_device 
*dsi, const void *payload,
 }
 EXPORT_SYMBOL(mipi_dsi_generic_write);
 
+/**
+ * mipi_dsi_generic_write_chatty() - mipi_dsi_generic_write() w/ an error log
+ * @dsi: DSI peripheral device
+ * @payload: buffer containing the payload
+ * @size: size of payload buffer
+ *
+ * Like mipi_dsi_generic_write() but includes a dev_err()
+ * call for you and returns 0 upon success, not the number of bytes sent.
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_generic_write_chatty(struct mipi_dsi_device *dsi,
+ const void *payload, size_t size)
+{
+   struct device *dev = >dev;
+   ssize_t ret;
+
+   ret = mipi_dsi_generic_write(dsi, payload, size);
+   if (ret < 0) {
+   dev_err(dev, "sending generic data %*ph failed: %zd\n",
+   (int)size, payload, ret);
+   return ret;
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_generic_write_chatty);
+
 /**
  * mipi_dsi_generic_read() - receive data using a generic read packet
  * @dsi: DSI peripheral device
@@ -852,6 +880,34 @@ ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device 
*dsi,
 }
 EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer);
 
+/**
+ * mipi_dsi_dcs_write_buffer_chatty - mipi_dsi_dcs_write_buffer() w/ an error 
log
+ * @dsi: DSI peripheral device
+ * @data: buffer containing data to be transmitted
+ * @len: size of transmission buffer
+ *
+ * Like mipi_dsi_dcs_write_buffer() but includes a dev_err()
+ * call for you and returns 0 upon success, not the number of bytes sent.
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_dcs_write_buffer_chatty(struct mipi_dsi_device *dsi,
+const void *data, size_t len)
+{
+   struct device *dev = >dev;
+   ssize_t ret;
+
+   ret = mipi_dsi_dcs_write_buffer(dsi, data, len);
+   if (ret < 0) {
+   dev_err(dev, "sending dc

[PATCH v5 2/9] drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_generic_write_seq()

2024-05-14 Thread Douglas Anderson
The mipi_dsi_generic_write_seq() macro makes a call to
mipi_dsi_generic_write() which returns a type ssize_t. The macro then
stores it in an int and checks to see if it's negative. This could
theoretically be a problem if "ssize_t" is larger than "int".

To see the issue, imagine that "ssize_t" is 32-bits and "int" is
16-bits, you could see a problem if there was some code out there that
looked like:

  mipi_dsi_generic_write_seq(dsi, <32768 bytes as arguments>);

...since we'd get back that 32768 bytes were transferred and 32768
stored in a 16-bit int would look negative.

Though there are no callsites where we'd actually hit this (even if
"int" was only 16-bit), it's cleaner to make the types match so let's
fix it.

Fixes: a9015ce59320 ("drm/mipi-dsi: Add a mipi_dsi_dcs_write_seq() macro")
Reviewed-by: Neil Armstrong 
Reviewed-by: Linus Walleij 
Signed-off-by: Douglas Anderson 
---

(no changes since v3)

Changes in v3:
- Use %zd in print instead of casting errors to int.

Changes in v2:
- New

 include/drm/drm_mipi_dsi.h | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 70ce0b8cbc68..e0f56564bf97 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -314,17 +314,17 @@ int mipi_dsi_dcs_get_display_brightness_large(struct 
mipi_dsi_device *dsi,
  * @dsi: DSI peripheral device
  * @seq: buffer containing the payload
  */
-#define mipi_dsi_generic_write_seq(dsi, seq...)
\
-   do {   \
-   static const u8 d[] = { seq }; \
-   struct device *dev = >dev;\
-   int ret;   \
-   ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d));   \
-   if (ret < 0) { \
-   dev_err_ratelimited(dev, "transmit data failed: %d\n", \
-   ret);  \
-   return ret;\
-   }  \
+#define mipi_dsi_generic_write_seq(dsi, seq...)
 \
+   do {
\
+   static const u8 d[] = { seq };  
\
+   struct device *dev = >dev; 
\
+   ssize_t ret;
\
+   ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d));
\
+   if (ret < 0) {  
\
+   dev_err_ratelimited(dev, "transmit data failed: %zd\n", 
\
+   ret);   
\
+   return ret; 
\
+   }   
\
} while (0)
 
 /**
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[PATCH v5 1/9] drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_dcs_write_seq()

2024-05-14 Thread Douglas Anderson
The mipi_dsi_dcs_write_seq() macro makes a call to
mipi_dsi_dcs_write_buffer() which returns a type ssize_t. The macro
then stores it in an int and checks to see if it's negative. This
could theoretically be a problem if "ssize_t" is larger than "int".

To see the issue, imagine that "ssize_t" is 32-bits and "int" is
16-bits, you could see a problem if there was some code out there that
looked like:

  mipi_dsi_dcs_write_seq(dsi, cmd, <32767 bytes as arguments>);

...since we'd get back that 32768 bytes were transferred and 32768
stored in a 16-bit int would look negative.

Though there are no callsites where we'd actually hit this (even if
"int" was only 16-bit), it's cleaner to make the types match so let's
fix it.

Fixes: 2a9e9daf7523 ("drm/mipi-dsi: Introduce mipi_dsi_dcs_write_seq macro")
Reviewed-by: Neil Armstrong 
Reviewed-by: Linus Walleij 
Signed-off-by: Douglas Anderson 
---

(no changes since v3)

Changes in v3:
- Use %zd in print instead of casting errors to int.

Changes in v2:
- New

 include/drm/drm_mipi_dsi.h | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 82b1cc434ea3..70ce0b8cbc68 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -333,18 +333,18 @@ int mipi_dsi_dcs_get_display_brightness_large(struct 
mipi_dsi_device *dsi,
  * @cmd: Command
  * @seq: buffer containing data to be transmitted
  */
-#define mipi_dsi_dcs_write_seq(dsi, cmd, seq...)   \
-   do {   \
-   static const u8 d[] = { cmd, seq };\
-   struct device *dev = >dev;\
-   int ret;   \
-   ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d));\
-   if (ret < 0) { \
-   dev_err_ratelimited(   \
-   dev, "sending command %#02x failed: %d\n", \
-   cmd, ret); \
-   return ret;\
-   }  \
+#define mipi_dsi_dcs_write_seq(dsi, cmd, seq...)\
+   do {\
+   static const u8 d[] = { cmd, seq }; \
+   struct device *dev = >dev; \
+   ssize_t ret;\
+   ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \
+   if (ret < 0) {  \
+   dev_err_ratelimited(\
+   dev, "sending command %#02x failed: %zd\n", \
+   cmd, ret);  \
+   return ret; \
+   }   \
} while (0)
 
 /**
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[PATCH v5 0/9] drm/mipi-dsi: Reduce bloat and add funcs for cleaner init seqs

2024-05-14 Thread Douglas Anderson
The consensus of many DRM folks is that we want to move away from DSI
drivers defining tables of init commands. Instead, we want to move to
init functions that can use common DRM functions. The issue thus far
has been that using the macros mipi_dsi_generic_write_seq() and
mipi_dsi_dcs_write_seq() bloats the driver using them.

While trying to solve bloat, we realized that the majority of the it
was easy to solve. This series solves the bloat for existing drivers
by moving the printout outside of the macro.

During discussion of my v1 patch to fix the bloat [1], we also decided
that we really want to change the way that drivers deal with init
sequences to make it clearer. In addition to being cleaner, a side
effect of moving drivers to the new style reduces bloat _even more_.

This series also contains a few minor fixes / cleanups that I found
along the way.

This series converts four drivers over to the new
mipi_dsi_dcs_write_seq_multi() function. Not all conversions have been
tested, but hopefully they are straightforward enough. I'd appreciate
testing.

NOTE: In v3 I tried to incorporate the feedback from v2. I also
converted the other two panels I could find that used table-based
initialization.

v4 just has a tiny bugfix and collects tags. v5 has another tiny
bugfix. Assuming no other problems are found the plan is to land this
series sometime roughly around May 16 [2].

[1] 
https://lore.kernel.org/r/20240424172017.1.Id15fae80582bc74a0d4f1338987fa375738f45b9@changeid
[2] https://lore.kernel.org/r/35b899d2-fb47-403a-83d2-204c0800d...@linaro.org

Changes in v5:
- Fix comment dev_err_ratelimited() => dev_err().

Changes in v4:
- Test to see if init is non-NULL before using it.
- Update wording as per Linus W.

Changes in v3:
- ("mipi_dsi_*_write functions don't need to ratelimit...") moved earlier.
- Add a TODO item for cleaning up the deprecated macros/functions.
- Fix spacing of init function.
- Inline kerneldoc comments for struct mipi_dsi_multi_context.
- Rebased upon patch to remove ratelimit of prints.
- Remove an unneeded error print.
- Squash boe-tv101wum-nl6 lowercase patch into main patch
- Use %zd in print instead of casting errors to int.
- drm/panel: ili9882t: Don't use a table for initting panels
- drm/panel: innolux-p079zca: Don't use a table for initting panels

Changes in v2:
- Add some comments to the macros about printing and returning.
- Change the way err value is handled in prep for next patch.
- Modify commit message now that this is part of a series.
- Rebased upon patches to avoid theoretical int overflow.
- drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_dcs_write_seq()
- drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_generic_write_seq()
- drm/mipi-dsi: Introduce mipi_dsi_*_write_seq_multi()
- drm/mipi-dsi: mipi_dsi_*_write functions don't need to ratelimit prints
- drm/panel: boe-tv101wum-nl6: Convert hex to lowercase
- drm/panel: boe-tv101wum-nl6: Don't use a table for initting commands
- drm/panel: novatek-nt36672e: Switch to mipi_dsi_dcs_write_seq_multi()

Douglas Anderson (9):
  drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_dcs_write_seq()
  drm/mipi-dsi: Fix theoretical int overflow in
mipi_dsi_generic_write_seq()
  drm/mipi-dsi: mipi_dsi_*_write functions don't need to ratelimit
prints
  drm/mipi-dsi: Reduce driver bloat of mipi_dsi_*_write_seq()
  drm/mipi-dsi: Introduce mipi_dsi_*_write_seq_multi()
  drm/panel: novatek-nt36672e: Switch to mipi_dsi_dcs_write_seq_multi()
  drm/panel: boe-tv101wum-nl6: Don't use a table for initting panels
  drm/panel: ili9882t: Don't use a table for initting panels
  drm/panel: innolux-p079zca: Don't use a table for initting panels

 Documentation/gpu/todo.rst|   18 +
 drivers/gpu/drm/drm_mipi_dsi.c|  112 +
 .../gpu/drm/panel/panel-boe-tv101wum-nl6.c| 2792 +
 drivers/gpu/drm/panel/panel-ilitek-ili9882t.c |  794 +++--
 drivers/gpu/drm/panel/panel-innolux-p079zca.c |  284 +-
 .../gpu/drm/panel/panel-novatek-nt36672e.c|  576 ++--
 include/drm/drm_mipi_dsi.h|  101 +-
 7 files changed, 2452 insertions(+), 2225 deletions(-)

-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[PATCH v4 8/9] drm/panel: ili9882t: Don't use a table for initting panels

2024-05-08 Thread Douglas Anderson
Consensus on the mailing lists is that panels shouldn't use a table of
init commands but should instead use init functions. With the recently
introduced mipi_dsi_dcs_write_seq_multi() this is not only clean/easy
but also saves space. Measuring before/after this change:

$ scripts/bloat-o-meter \
  .../before/panel-ilitek-ili9882t.ko \
  .../after/panel-ilitek-ili9882t.ko
add/remove: 3/2 grow/shrink: 0/2 up/down: 6834/-8177 (-1343)
Function old new   delta
starry_ili9882t_init   -6152   +6152
starry_ili9882t_init.d - 678+678
ili9882t_disable.d -   4  +4
ili9882t_disable 260 228 -32
ili9882t_prepare 540 396-144
.compoundliteral 681   --681
starry_ili9882t_init_cmd7320   -   -7320
Total: Before=11928, After=10585, chg -11.26%

Let's do the conversion.

Since we're touching all the tables, let's also convert hex numbers to
lower case as per kernel conventions.

Reviewed-by: Linus Walleij 
Signed-off-by: Douglas Anderson 
---

(no changes since v3)

Changes in v3:
- New

 drivers/gpu/drm/panel/panel-ilitek-ili9882t.c | 794 --
 1 file changed, 368 insertions(+), 426 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c 
b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
index 267a5307041c..58fc1d799371 100644
--- a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
@@ -15,6 +15,8 @@
 
 #include 
 
+struct ili9882t;
+
 /*
  * Use this descriptor struct to describe different panels using the
  * Ilitek ILI9882T display controller.
@@ -34,7 +36,7 @@ struct panel_desc {
 
unsigned long mode_flags;
enum mipi_dsi_pixel_format format;
-   const struct panel_init_cmd *init_cmds;
+   int (*init)(struct ili9882t *boe);
unsigned int lanes;
 };
 
@@ -52,433 +54,372 @@ struct ili9882t {
struct gpio_desc *enable_gpio;
 };
 
-enum dsi_cmd_type {
-   INIT_DCS_CMD,
-   DELAY_CMD,
-};
-
-struct panel_init_cmd {
-   enum dsi_cmd_type type;
-   size_t len;
-   const char *data;
-};
-
-#define _INIT_DCS_CMD(...) { \
-   .type = INIT_DCS_CMD, \
-   .len = sizeof((char[]){__VA_ARGS__}), \
-   .data = (char[]){__VA_ARGS__} }
-
-#define _INIT_DELAY_CMD(...) { \
-   .type = DELAY_CMD,\
-   .len = sizeof((char[]){__VA_ARGS__}), \
-   .data = (char[]){__VA_ARGS__} }
-
 /* ILI9882-specific commands, add new commands as you decode them */
 #define ILI9882T_DCS_SWITCH_PAGE   0xFF
 
-#define _INIT_SWITCH_PAGE_CMD(page) \
-   _INIT_DCS_CMD(ILI9882T_DCS_SWITCH_PAGE, 0x98, 0x82, (page))
-
-static const struct panel_init_cmd starry_ili9882t_init_cmd[] = {
-   _INIT_DELAY_CMD(5),
-   _INIT_SWITCH_PAGE_CMD(0x01),
-   _INIT_DCS_CMD(0x00, 0x42),
-   _INIT_DCS_CMD(0x01, 0x11),
-   _INIT_DCS_CMD(0x02, 0x00),
-   _INIT_DCS_CMD(0x03, 0x00),
-
-   _INIT_DCS_CMD(0x04, 0x01),
-   _INIT_DCS_CMD(0x05, 0x11),
-   _INIT_DCS_CMD(0x06, 0x00),
-   _INIT_DCS_CMD(0x07, 0x00),
-
-   _INIT_DCS_CMD(0x08, 0x80),
-   _INIT_DCS_CMD(0x09, 0x81),
-   _INIT_DCS_CMD(0x0A, 0x71),
-   _INIT_DCS_CMD(0x0B, 0x00),
-
-   _INIT_DCS_CMD(0x0C, 0x00),
-   _INIT_DCS_CMD(0x0E, 0x1A),
-
-   _INIT_DCS_CMD(0x24, 0x00),
-   _INIT_DCS_CMD(0x25, 0x00),
-   _INIT_DCS_CMD(0x26, 0x00),
-   _INIT_DCS_CMD(0x27, 0x00),
-
-   _INIT_DCS_CMD(0x2C, 0xD4),
-   _INIT_DCS_CMD(0xB9, 0x40),
-
-   _INIT_DCS_CMD(0xB0, 0x11),
-
-   _INIT_DCS_CMD(0xE6, 0x32),
-   _INIT_DCS_CMD(0xD1, 0x30),
-
-   _INIT_DCS_CMD(0xD6, 0x55),
-
-   _INIT_DCS_CMD(0xD0, 0x01),
-   _INIT_DCS_CMD(0xE3, 0x93),
-   _INIT_DCS_CMD(0xE4, 0x00),
-   _INIT_DCS_CMD(0xE5, 0x80),
-
-   _INIT_DCS_CMD(0x31, 0x07),
-   _INIT_DCS_CMD(0x32, 0x07),
-   _INIT_DCS_CMD(0x33, 0x07),
-   _INIT_DCS_CMD(0x34, 0x07),
-   _INIT_DCS_CMD(0x35, 0x07),
-   _INIT_DCS_CMD(0x36, 0x01),
-   _INIT_DCS_CMD(0x37, 0x00),
-   _INIT_DCS_CMD(0x38, 0x28),
-   _INIT_DCS_CMD(0x39, 0x29),
-   _INIT_DCS_CMD(0x3A, 0x11),
-   _INIT_DCS_CMD(0x3B, 0x13),
-   _INIT_DCS_CMD(0x3C, 0x15),
-   _INIT_DCS_CMD(0x3D, 0x17),
-   _INIT_DCS_CMD(0x3E, 0x09),
-   _INIT_DCS_CMD(0x3F, 0x0D),
-   _INIT_DCS_CMD(0x40, 0x02),
-   _INIT_DCS_CMD(0x41, 0x02),
-   _INIT_DCS_CMD(0x42, 0x02),
-   _INIT_DCS_CMD(0x43, 0x02),
-   _INIT_DCS_CMD(0x44, 0x02),
-   _INIT_DCS_CMD(0x45, 0x02),
-   _INIT_DCS_CMD(0x46, 0x02),
-
-   _INIT_DCS_CMD(0x47, 0x07),
-   _INIT_DCS_CMD(0x48, 0x07),
-   _INIT_DCS_CMD(0x49, 0x07),
-   _INIT_DCS_CMD(0x4A, 0x07),
-   _INIT_DCS_CMD(0x4B, 0x07),
-   _INIT_DCS_CMD(0x4C, 0x01),
-   _INIT_DCS_CMD(0x4D, 0x00

[PATCH v4 9/9] drm/panel: innolux-p079zca: Don't use a table for initting panels

2024-05-08 Thread Douglas Anderson
Consensus on the mailing lists is that panels shouldn't use a table of
init commands but should instead use init functions. We'll use the
same concepts as the recently introduced
mipi_dsi_generic_write_seq_multi() to make this clean/easy and also
not bloat the driver too much. Measuring before/after this change:

$ scripts/bloat-o-meter \
  .../before/panel-innolux-p079zca.ko \
  .../after/panel-innolux-p079zca.ko
add/remove: 3/2 grow/shrink: 0/1 up/down: 2356/-1944 (412)
Function old new   delta
innolux_p097pfg_init   -1772   +1772
innolux_p097pfg_init.d - 480+480
innolux_panel_write_multi  - 104+104
innolux_panel_prepare412 308-104
.compoundliteral 480   --480
innolux_p097pfg_init_cmds   1360   -   -1360
Total: Before=5802, After=6214, chg +7.10%

Note that, unlike some other drivers, we actually make this panel
driver _bigger_ by using the new functions. This is because the
innolux-p079zca panel driver didn't have as complex of a table and
thus the old table was more efficient than the code. The bloat is
still not giant (only 412 bytes).

Also note that we can't direclty use
mipi_dsi_generic_write_seq_multi() here because we need to deal with
the crazy "nop" that this driver sends after all commands. This means
that we have to write code that is "inspired" by the new macros.

Since we're touching all the tables, let's also convert hex numbers to
lower case as per kernel conventions.

Reviewed-by: Linus Walleij 
Signed-off-by: Douglas Anderson 
---

Changes in v4:
- Test to see if init is non-NULL before using it.

Changes in v3:
- New

 drivers/gpu/drm/panel/panel-innolux-p079zca.c | 284 +-
 1 file changed, 140 insertions(+), 144 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-innolux-p079zca.c 
b/drivers/gpu/drm/panel/panel-innolux-p079zca.c
index 485178a99910..ade8bf7491ee 100644
--- a/drivers/gpu/drm/panel/panel-innolux-p079zca.c
+++ b/drivers/gpu/drm/panel/panel-innolux-p079zca.c
@@ -17,14 +17,7 @@
 #include 
 #include 
 
-struct panel_init_cmd {
-   size_t len;
-   const char *data;
-};
-
-#define _INIT_CMD(...) { \
-   .len = sizeof((char[]){__VA_ARGS__}), \
-   .data = (char[]){__VA_ARGS__} }
+struct innolux_panel;
 
 struct panel_desc {
const struct drm_display_mode *mode;
@@ -36,7 +29,7 @@ struct panel_desc {
 
unsigned long flags;
enum mipi_dsi_pixel_format format;
-   const struct panel_init_cmd *init_cmds;
+   int (*init)(struct innolux_panel *innolux);
unsigned int lanes;
const char * const *supply_names;
unsigned int num_supplies;
@@ -132,32 +125,10 @@ static int innolux_panel_prepare(struct drm_panel *panel)
/* p079zca: t4, p097pfg: t5 */
usleep_range(2, 21000);
 
-   if (innolux->desc->init_cmds) {
-   const struct panel_init_cmd *cmds =
-   innolux->desc->init_cmds;
-   unsigned int i;
-
-   for (i = 0; cmds[i].len != 0; i++) {
-   const struct panel_init_cmd *cmd = [i];
-
-   err = mipi_dsi_generic_write(innolux->link, cmd->data,
-cmd->len);
-   if (err < 0) {
-   dev_err(panel->dev, "failed to write command 
%u\n", i);
-   goto poweroff;
-   }
-
-   /*
-* Included by random guessing, because without this
-* (or at least, some delay), the panel sometimes
-* didn't appear to pick up the command sequence.
-*/
-   err = mipi_dsi_dcs_nop(innolux->link);
-   if (err < 0) {
-   dev_err(panel->dev, "failed to send DCS nop: 
%d\n", err);
-   goto poweroff;
-   }
-   }
+   if (innolux->desc->init) {
+   err = innolux->desc->init(innolux);
+   if (err < 0)
+   goto poweroff;
}
 
err = mipi_dsi_dcs_exit_sleep_mode(innolux->link);
@@ -250,119 +221,144 @@ static const struct drm_display_mode 
innolux_p097pfg_mode = {
.vtotal = 2048 + 100 + 2 + 18,
 };
 
+static void innolux_panel_write_multi(struct mipi_dsi_multi_context *ctx,
+ const void *payload, size_t size)
+{
+   struct mipi_dsi_device *dsi = ctx->dsi;
+   struct device *dev = >dev;
+
+   mipi_dsi_generic_write_multi(ctx, payload, size);
+   if (ctx->accum_err)
+   return;
+
+   

[PATCH v4 7/9] drm/panel: boe-tv101wum-nl6: Don't use a table for initting panels

2024-05-08 Thread Douglas Anderson
Consensus on the mailing lists is that panels shouldn't use a table of
init commands but should instead use init functions. With the recently
introduced mipi_dsi_dcs_write_seq_multi() this is not only clean/easy
but also saves space. Measuring before/after this change:

$ scripts/bloat-o-meter \
  .../before/panel-boe-tv101wum-nl6.ko \
  .../after/panel-boe-tv101wum-nl6.ko
add/remove: 14/8 grow/shrink: 0/1 up/down: 27062/-31433 (-4371)
Function old new   delta
inx_hj110iz_init   -7040   +7040
boe_tv110c9m_init  -6440   +6440
boe_init   -5916   +5916
starry_qfh032011_53g_init  -1944   +1944
starry_himax83102_j02_init -1228   +1228
inx_hj110iz_init.d -1040   +1040
boe_tv110c9m_init.d- 982+982
auo_b101uan08_3_init   - 944+944
boe_init.d - 580+580
starry_himax83102_j02_init.d   - 512+512
starry_qfh032011_53g_init.d- 180+180
auo_kd101n80_45na_init - 172+172
auo_b101uan08_3_init.d -  82 +82
auo_kd101n80_45na_init.d   -   2  +2
auo_kd101n80_45na_init_cmd   144   --144
boe_panel_prepare592 440-152
auo_b101uan08_3_init_cmd1056   -   -1056
starry_himax83102_j02_init_cmd  1392   -   -1392
starry_qfh032011_53g_init_cmd   2256   -   -2256
.compoundliteral3393   -   -3393
boe_init_cmd7008   -   -7008
boe_tv110c9m_init_cmd   7656   -   -7656
inx_hj110iz_init_cmd8376   -   -8376
Total: Before=37297, After=32926, chg -11.72%

Let's do the conversion.

Since we're touching all the tables, let's also convert hex numbers to
lower case as per kernel conventions.

Reviewed-by: Linus Walleij 
Signed-off-by: Douglas Anderson 
---

(no changes since v3)

Changes in v3:
- Fix spacing of init function.
- Remove an unneeded error print.
- Squash boe-tv101wum-nl6 lowercase patch into main patch

Changes in v2:
- New

 .../gpu/drm/panel/panel-boe-tv101wum-nl6.c| 2792 +
 1 file changed, 1442 insertions(+), 1350 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c 
b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
index 0ffe8f8c01de..aab60cec0603 100644
--- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
+++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
@@ -17,6 +17,8 @@
 
 #include 
 
+struct boe_panel;
+
 struct panel_desc {
const struct drm_display_mode *modes;
unsigned int bpc;
@@ -32,7 +34,7 @@ struct panel_desc {
 
unsigned long mode_flags;
enum mipi_dsi_pixel_format format;
-   const struct panel_init_cmd *init_cmds;
+   int (*init)(struct boe_panel *boe);
unsigned int lanes;
bool discharge_on_disable;
bool lp11_before_reset;
@@ -54,1318 +56,1449 @@ struct boe_panel {
bool prepared;
 };
 
-enum dsi_cmd_type {
-   INIT_DCS_CMD,
-   DELAY_CMD,
-};
+static int boe_tv110c9m_init(struct boe_panel *boe)
+{
+   struct mipi_dsi_multi_context ctx = { .dsi = boe->dsi };
+
+   mipi_dsi_dcs_write_seq_multi(, 0xff, 0x20);
+   mipi_dsi_dcs_write_seq_multi(, 0xfb, 0x01);
+   mipi_dsi_dcs_write_seq_multi(, 0x05, 0xd9);
+   mipi_dsi_dcs_write_seq_multi(, 0x07, 0x78);
+   mipi_dsi_dcs_write_seq_multi(, 0x08, 0x5a);
+   mipi_dsi_dcs_write_seq_multi(, 0x0d, 0x63);
+   mipi_dsi_dcs_write_seq_multi(, 0x0e, 0x91);
+   mipi_dsi_dcs_write_seq_multi(, 0x0f, 0x73);
+   mipi_dsi_dcs_write_seq_multi(, 0x95, 0xe6);
+   mipi_dsi_dcs_write_seq_multi(, 0x96, 0xf0);
+   mipi_dsi_dcs_write_seq_multi(, 0x30, 0x00);
+   mipi_dsi_dcs_write_seq_multi(, 0x6d, 0x66);
+   mipi_dsi_dcs_write_seq_multi(, 0x75, 0xa2);
+   mipi_dsi_dcs_write_seq_multi(, 0x77, 0x3b);
+
+   mipi_dsi_dcs_write_seq_multi(, 0xb0, 0x00, 0x08, 0x00, 0x23, 0x00, 
0x4d, 0x00, 0x6d,
+0x00, 0x89, 0x00, 0xa1, 0x00, 0xb6, 0x00, 
0xc9);
+   mipi_dsi_dcs_write_seq_multi(, 0xb1, 0x00, 0xda, 0x01, 0x13, 0x01, 
0x3c, 0x01, 0x7e,
+0x01, 0xab, 0x01, 0xf7, 0x02, 0x2f, 0x02, 
0x31);
+   mipi_dsi_dcs_write_seq_multi(, 0xb2, 0x02, 0x67, 0x02, 0xa6, 0x02, 
0xd1, 0x03, 0x08,
+0x03, 0x2e, 0x03, 0x5b, 0x03, 0x6b, 0x03, 
0x7b);
+   mipi_dsi_dcs_write_seq_multi(, 0xb3, 0x03, 0x8e, 0x03, 0xa2, 0x03, 
0xb7, 0x03, 0xe7,
+0x03, 0xfd, 0x03, 0xff);
+
+   mipi_dsi_dcs_write_seq_mu

[PATCH v4 6/9] drm/panel: novatek-nt36672e: Switch to mipi_dsi_dcs_write_seq_multi()

2024-05-08 Thread Douglas Anderson
This is a mechanical conversion of the novatek-nt36672e driver to use
the new mipi_dsi_dcs_write_seq_multi(). The new function is easier for
clients to understand and using it also causes smaller code to be
generated. Specifically:

$ scripts/bloat-o-meter \
  ...after/panel-novatek-nt36672e.ko \
  ...ctx/panel-novatek-nt36672e.ko
add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-988 (-988)
Function old new   delta
nt36672e_1080x2408_60hz_init62365248-988
Total: Before=10651, After=9663, chg -9.28%

Cc: Ritesh Kumar 
Signed-off-by: Douglas Anderson 
---
This change is only compile tested. I don't use this panel myself but
arbitrarily picked it as an example to look at when working on the
MIPI DSI macros.

NOTE: as of the posting of v4 this change still has no tags. Without
any tags (Reviewed-by/Tested-by/Acked-by) I won't actually land this
change even if the rest of the series lands.

(no changes since v3)

Changes in v3:
- Fix spacing of init function.

Changes in v2:
- New

 .../gpu/drm/panel/panel-novatek-nt36672e.c| 576 +-
 1 file changed, 289 insertions(+), 287 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36672e.c 
b/drivers/gpu/drm/panel/panel-novatek-nt36672e.c
index 20b7bfe4aa12..9ce8df455232 100644
--- a/drivers/gpu/drm/panel/panel-novatek-nt36672e.c
+++ b/drivers/gpu/drm/panel/panel-novatek-nt36672e.c
@@ -51,293 +51,295 @@ static inline struct nt36672e_panel 
*to_nt36672e_panel(struct drm_panel *panel)
 
 static int nt36672e_1080x2408_60hz_init(struct mipi_dsi_device *dsi)
 {
-   mipi_dsi_dcs_write_seq(dsi, 0xff, 0x10);
-   mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
-   mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x00);
-   mipi_dsi_dcs_write_seq(dsi, 0xc0, 0x00);
-   mipi_dsi_dcs_write_seq(dsi, 0xc1, 0x89, 0x28, 0x00, 0x08, 0x00, 0xaa, 
0x02,
-   0x0e, 0x00, 0x2b, 0x00, 0x07, 0x0d, 0xb7, 0x0c, 
0xb7);
-
-   mipi_dsi_dcs_write_seq(dsi, 0xc2, 0x1b, 0xa0);
-   mipi_dsi_dcs_write_seq(dsi, 0xff, 0x20);
-   mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
-   mipi_dsi_dcs_write_seq(dsi, 0x01, 0x66);
-   mipi_dsi_dcs_write_seq(dsi, 0x06, 0x40);
-   mipi_dsi_dcs_write_seq(dsi, 0x07, 0x38);
-   mipi_dsi_dcs_write_seq(dsi, 0x2f, 0x83);
-   mipi_dsi_dcs_write_seq(dsi, 0x69, 0x91);
-   mipi_dsi_dcs_write_seq(dsi, 0x95, 0xd1);
-   mipi_dsi_dcs_write_seq(dsi, 0x96, 0xd1);
-   mipi_dsi_dcs_write_seq(dsi, 0xf2, 0x64);
-   mipi_dsi_dcs_write_seq(dsi, 0xf3, 0x54);
-   mipi_dsi_dcs_write_seq(dsi, 0xf4, 0x64);
-   mipi_dsi_dcs_write_seq(dsi, 0xf5, 0x54);
-   mipi_dsi_dcs_write_seq(dsi, 0xf6, 0x64);
-   mipi_dsi_dcs_write_seq(dsi, 0xf7, 0x54);
-   mipi_dsi_dcs_write_seq(dsi, 0xf8, 0x64);
-   mipi_dsi_dcs_write_seq(dsi, 0xf9, 0x54);
-   mipi_dsi_dcs_write_seq(dsi, 0xff, 0x24);
-   mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
-   mipi_dsi_dcs_write_seq(dsi, 0x01, 0x0f);
-   mipi_dsi_dcs_write_seq(dsi, 0x03, 0x0c);
-   mipi_dsi_dcs_write_seq(dsi, 0x05, 0x1d);
-   mipi_dsi_dcs_write_seq(dsi, 0x08, 0x2f);
-   mipi_dsi_dcs_write_seq(dsi, 0x09, 0x2e);
-   mipi_dsi_dcs_write_seq(dsi, 0x0a, 0x2d);
-   mipi_dsi_dcs_write_seq(dsi, 0x0b, 0x2c);
-   mipi_dsi_dcs_write_seq(dsi, 0x11, 0x17);
-   mipi_dsi_dcs_write_seq(dsi, 0x12, 0x13);
-   mipi_dsi_dcs_write_seq(dsi, 0x13, 0x15);
-   mipi_dsi_dcs_write_seq(dsi, 0x15, 0x14);
-   mipi_dsi_dcs_write_seq(dsi, 0x16, 0x16);
-   mipi_dsi_dcs_write_seq(dsi, 0x17, 0x18);
-   mipi_dsi_dcs_write_seq(dsi, 0x1b, 0x01);
-   mipi_dsi_dcs_write_seq(dsi, 0x1d, 0x1d);
-   mipi_dsi_dcs_write_seq(dsi, 0x20, 0x2f);
-   mipi_dsi_dcs_write_seq(dsi, 0x21, 0x2e);
-   mipi_dsi_dcs_write_seq(dsi, 0x22, 0x2d);
-   mipi_dsi_dcs_write_seq(dsi, 0x23, 0x2c);
-   mipi_dsi_dcs_write_seq(dsi, 0x29, 0x17);
-   mipi_dsi_dcs_write_seq(dsi, 0x2a, 0x13);
-   mipi_dsi_dcs_write_seq(dsi, 0x2b, 0x15);
-   mipi_dsi_dcs_write_seq(dsi, 0x2f, 0x14);
-   mipi_dsi_dcs_write_seq(dsi, 0x30, 0x16);
-   mipi_dsi_dcs_write_seq(dsi, 0x31, 0x18);
-   mipi_dsi_dcs_write_seq(dsi, 0x32, 0x04);
-   mipi_dsi_dcs_write_seq(dsi, 0x34, 0x10);
-   mipi_dsi_dcs_write_seq(dsi, 0x35, 0x1f);
-   mipi_dsi_dcs_write_seq(dsi, 0x36, 0x1f);
-   mipi_dsi_dcs_write_seq(dsi, 0x4d, 0x14);
-   mipi_dsi_dcs_write_seq(dsi, 0x4e, 0x36);
-   mipi_dsi_dcs_write_seq(dsi, 0x4f, 0x36);
-   mipi_dsi_dcs_write_seq(dsi, 0x53, 0x36);
-   mipi_dsi_dcs_write_seq(dsi, 0x71, 0x30);
-   mipi_dsi_dcs_write_seq(dsi, 0x79, 0x11);
-   mipi_dsi_dcs_write_seq(dsi, 0x7a, 0x82);
-   mipi_dsi_dcs_write_seq(dsi, 0x7b, 0x8f);
-   mipi_dsi_dcs_write_seq(dsi, 0x7d, 0x04);
-   mipi_dsi_dcs_write_seq(dsi, 0x80, 0x04);
-   mipi_dsi_dcs_write_seq(dsi, 0x81, 0x04);
-   mipi_dsi_dcs_write_seq(dsi, 0x82, 0x13

[PATCH v4 5/9] drm/mipi-dsi: Introduce mipi_dsi_*_write_seq_multi()

2024-05-08 Thread Douglas Anderson
The current mipi_dsi_*_write_seq() macros are non-intutitive because
they contain a hidden "return" statement that will return out of the
_caller_ of the macro. Let's mark them as deprecated and instead
introduce some new macros that are more intuitive.

These new macros are less optimal when an error occurs but should
behave more optimally when there is no error. Specifically these new
macros cause smaller code to get generated and the code size savings
(less to fetch from RAM, less cache space used, less RAM used) are
important. Since the error case isn't something we need to optimize
for and these new macros are easier to understand and more flexible,
they should be used.

After converting to use these new functions, one example shows some
nice savings while also being easier to understand.

$ scripts/bloat-o-meter \
  ...after/panel-novatek-nt36672e.ko \
  ...ctx/panel-novatek-nt36672e.ko
add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-988 (-988)
Function old new   delta
nt36672e_1080x2408_60hz_init62365248-988
Total: Before=10651, After=9663, chg -9.28%

Reviewed-by: Neil Armstrong 
Reviewed-by: Linus Walleij 
Signed-off-by: Douglas Anderson 
---
Right now this patch introduces two new functions in drm_mipi_dsi.c.
Alternatively we could have changed the prototype of the "chatty"
functions and made the deprecated macros adapt to the new prototype.
While this sounds nice, it bloated callers of the deprecated functioin
a bit because it caused the compiler to emit less optimal code. It
doesn't seem terrible to add two more functions, so I went that
way. There may be cases where callers who aren't writing many
sequences prefer to use the "chatty" versions anyway.

(no changes since v3)

Changes in v3:
- Add a TODO item for cleaning up the deprecated macros/functions.
- Inline kerneldoc comments for struct mipi_dsi_multi_context.

Changes in v2:
- New

 Documentation/gpu/todo.rst | 18 ++
 drivers/gpu/drm/drm_mipi_dsi.c | 56 ++
 include/drm/drm_mipi_dsi.h | 62 ++
 3 files changed, 136 insertions(+)

diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index e2a0585915b3..2734b8a34541 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -494,6 +494,24 @@ Contact: Douglas Anderson 
 
 Level: Starter/Intermediate
 
+Transition away from using mipi_dsi_*_write_seq()
+-
+
+The macros mipi_dsi_generic_write_seq() and mipi_dsi_dcs_write_seq() are
+non-intuitive because, if there are errors, they return out of the *caller's*
+function. We should move all callers to use mipi_dsi_generic_write_seq_multi()
+and mipi_dsi_dcs_write_seq_multi() macros instead.
+
+Once all callers are transitioned, the macros and the functions that they call,
+mipi_dsi_generic_write_chatty() and mipi_dsi_dcs_write_buffer_chatty(), can
+probably be removed. Alternatively, if people feel like the _multi() variants
+are overkill for some use cases, we could keep the mipi_dsi_*_write_seq()
+variants but change them not to return out of the caller.
+
+Contact: Douglas Anderson 
+
+Level: Starter
+
 
 Core refactorings
 =
diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 8593d9ed5891..d2957cb692d3 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -792,6 +792,34 @@ int mipi_dsi_generic_write_chatty(struct mipi_dsi_device 
*dsi,
 }
 EXPORT_SYMBOL(mipi_dsi_generic_write_chatty);
 
+/**
+ * mipi_dsi_generic_write_multi() - mipi_dsi_generic_write_chatty() w/ 
accum_err
+ * @ctx: Context for multiple DSI transactions
+ * @payload: buffer containing the payload
+ * @size: size of payload buffer
+ *
+ * Like mipi_dsi_generic_write_chatty() but deals with errors in a way that
+ * makes it convenient to make several calls in a row.
+ */
+void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx,
+ const void *payload, size_t size)
+{
+   struct mipi_dsi_device *dsi = ctx->dsi;
+   struct device *dev = >dev;
+   ssize_t ret;
+
+   if (ctx->accum_err)
+   return;
+
+   ret = mipi_dsi_generic_write(dsi, payload, size);
+   if (ret < 0) {
+   ctx->accum_err = ret;
+   dev_err(dev, "sending generic data %*ph failed: %d\n",
+   (int)size, payload, ctx->accum_err);
+   }
+}
+EXPORT_SYMBOL(mipi_dsi_generic_write_multi);
+
 /**
  * mipi_dsi_generic_read() - receive data using a generic read packet
  * @dsi: DSI peripheral device
@@ -908,6 +936,34 @@ int mipi_dsi_dcs_write_buffer_chatty(struct 
mipi_dsi_device *dsi,
 }
 EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_chatty);
 
+/**
+ * mipi_dsi_dcs_write_buffer_multi - mipi_dsi_dcs_write_buffer_chatty() w/ 
accum_err
+ * @ctx: Context 

[PATCH v4 4/9] drm/mipi-dsi: Reduce driver bloat of mipi_dsi_*_write_seq()

2024-05-08 Thread Douglas Anderson
Through a cooperative effort between Hsin-Yi Wang and Dmitry
Baryshkov, we have realized the dev_err() in the
mipi_dsi_*_write_seq() macros was causing quite a bit of bloat to the
kernel. Let's hoist this call into drm_mipi_dsi.c by adding a "chatty"
version of the functions that includes the print. While doing this,
add a bit more comments to these macros making it clear that they
print errors and also that they return out of _the caller's_ function.

Without any changes to clients this gives a nice savings. Specifically
the macro was inlined and thus the error report call was inlined into
every call to mipi_dsi_dcs_write_seq() and
mipi_dsi_generic_write_seq(). By using a call to a "chatty" function,
the usage is reduced to one call in the chatty function and a function
call at the invoking site.

Building with my build system shows one example:

$ scripts/bloat-o-meter \
  .../before/panel-novatek-nt36672e.ko \
  .../after/panel-novatek-nt36672e.ko
add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-4404 (-4404)
Function old new   delta
nt36672e_1080x2408_60hz_init   106406236   -4404
Total: Before=15055, After=10651, chg -29.25%

Note that given the change in location of the print it's harder to
include the "cmd" in the printout for mipi_dsi_dcs_write_seq() since,
theoretically, someone could call the new chatty function with a
zero-size array and it would be illegal to dereference data[0].
There's a printk format to print the whole buffer and this is probably
more useful for debugging anyway. Given that we're doing this for
mipi_dsi_dcs_write_seq(), let's also print the buffer for
mipi_dsi_generic_write_seq() in the error case.

It should be noted that the current consensus of DRM folks is that the
mipi_dsi_*_write_seq() should be deprecated due to the non-intuitive
return behavior. A future patch will formally mark them as deprecated
and provide an alternative.

Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Neil Armstrong 
Reviewed-by: Linus Walleij 
Signed-off-by: Douglas Anderson 
---

Changes in v4:
- Update wording as per Linus W.

Changes in v3:
- Rebased upon patch to remove ratelimit of prints.

Changes in v2:
- Add some comments to the macros about printing and returning.
- Change the way err value is handled in prep for next patch.
- Modify commit message now that this is part of a series.
- Rebased upon patches to avoid theoretical int overflow.

 drivers/gpu/drm/drm_mipi_dsi.c | 56 ++
 include/drm/drm_mipi_dsi.h | 47 +++-
 2 files changed, 82 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 795001bb7ff1..8593d9ed5891 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -764,6 +764,34 @@ ssize_t mipi_dsi_generic_write(struct mipi_dsi_device 
*dsi, const void *payload,
 }
 EXPORT_SYMBOL(mipi_dsi_generic_write);
 
+/**
+ * mipi_dsi_generic_write_chatty() - mipi_dsi_generic_write() w/ an error log
+ * @dsi: DSI peripheral device
+ * @payload: buffer containing the payload
+ * @size: size of payload buffer
+ *
+ * Like mipi_dsi_generic_write() but includes a dev_err_ratelimited()
+ * call for you and returns 0 upon success, not the number of bytes sent.
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_generic_write_chatty(struct mipi_dsi_device *dsi,
+ const void *payload, size_t size)
+{
+   struct device *dev = >dev;
+   ssize_t ret;
+
+   ret = mipi_dsi_generic_write(dsi, payload, size);
+   if (ret < 0) {
+   dev_err(dev, "sending generic data %*ph failed: %zd\n",
+   (int)size, payload, ret);
+   return ret;
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_generic_write_chatty);
+
 /**
  * mipi_dsi_generic_read() - receive data using a generic read packet
  * @dsi: DSI peripheral device
@@ -852,6 +880,34 @@ ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device 
*dsi,
 }
 EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer);
 
+/**
+ * mipi_dsi_dcs_write_buffer_chatty - mipi_dsi_dcs_write_buffer() w/ an error 
log
+ * @dsi: DSI peripheral device
+ * @data: buffer containing data to be transmitted
+ * @len: size of transmission buffer
+ *
+ * Like mipi_dsi_dcs_write_buffer() but includes a dev_err_ratelimited()
+ * call for you and returns 0 upon success, not the number of bytes sent.
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_dcs_write_buffer_chatty(struct mipi_dsi_device *dsi,
+const void *data, size_t len)
+{
+   struct device *dev = >dev;
+   ssize_t ret;
+
+   ret = mipi_dsi_dcs_write_buffer(dsi, data, len);
+   if (ret < 0) {
+   dev_err(dev, "sending dcs data %*ph failed: %zd\n",
+ 

[PATCH v4 3/9] drm/mipi-dsi: mipi_dsi_*_write functions don't need to ratelimit prints

2024-05-08 Thread Douglas Anderson
We really don't expect these errors to be printed over and over
again. When a driver hits the error it should bail out. Just use a
normal error print.

This gives a nice space savings for users of these functions:

$ scripts/bloat-o-meter \
  .../before/panel-novatek-nt36672e.ko \
  .../after/panel-novatek-nt36672e.ko
add/remove: 0/1 grow/shrink: 0/1 up/down: 0/-16760 (-16760)
Function old new   delta
nt36672e_1080x2408_60hz_init   17080   10640   -6440
nt36672e_1080x2408_60hz_init._rs   10320   -  -10320
Total: Before=31815, After=15055, chg -52.68%

Reviewed-by: Neil Armstrong 
Reviewed-by: Linus Walleij 
Signed-off-by: Douglas Anderson 
---

(no changes since v3)

Changes in v3:
- ("mipi_dsi_*_write functions don't need to ratelimit...") moved earlier.

Changes in v2:
- New

 include/drm/drm_mipi_dsi.h | 24 +++-
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index e0f56564bf97..67967be48dbd 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -314,17 +314,16 @@ int mipi_dsi_dcs_get_display_brightness_large(struct 
mipi_dsi_device *dsi,
  * @dsi: DSI peripheral device
  * @seq: buffer containing the payload
  */
-#define mipi_dsi_generic_write_seq(dsi, seq...)
 \
-   do {
\
-   static const u8 d[] = { seq };  
\
-   struct device *dev = >dev; 
\
-   ssize_t ret;
\
-   ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d));
\
-   if (ret < 0) {  
\
-   dev_err_ratelimited(dev, "transmit data failed: %zd\n", 
\
-   ret);   
\
-   return ret; 
\
-   }   
\
+#define mipi_dsi_generic_write_seq(dsi, seq...)   \
+   do {  \
+   static const u8 d[] = { seq };\
+   struct device *dev = >dev;   \
+   ssize_t ret;  \
+   ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d));  \
+   if (ret < 0) {\
+   dev_err(dev, "transmit data failed: %zd\n", ret); \
+   return ret;   \
+   } \
} while (0)
 
 /**
@@ -340,8 +339,7 @@ int mipi_dsi_dcs_get_display_brightness_large(struct 
mipi_dsi_device *dsi,
ssize_t ret;\
ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \
if (ret < 0) {  \
-   dev_err_ratelimited(\
-   dev, "sending command %#02x failed: %zd\n", \
+   dev_err(dev, "sending command %#02x failed: %zd\n", \
cmd, ret);  \
return ret; \
}   \
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[PATCH v4 2/9] drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_generic_write_seq()

2024-05-08 Thread Douglas Anderson
The mipi_dsi_generic_write_seq() macro makes a call to
mipi_dsi_generic_write() which returns a type ssize_t. The macro then
stores it in an int and checks to see if it's negative. This could
theoretically be a problem if "ssize_t" is larger than "int".

To see the issue, imagine that "ssize_t" is 32-bits and "int" is
16-bits, you could see a problem if there was some code out there that
looked like:

  mipi_dsi_generic_write_seq(dsi, <32768 bytes as arguments>);

...since we'd get back that 32768 bytes were transferred and 32768
stored in a 16-bit int would look negative.

Though there are no callsites where we'd actually hit this (even if
"int" was only 16-bit), it's cleaner to make the types match so let's
fix it.

Fixes: a9015ce59320 ("drm/mipi-dsi: Add a mipi_dsi_dcs_write_seq() macro")
Reviewed-by: Neil Armstrong 
Reviewed-by: Linus Walleij 
Signed-off-by: Douglas Anderson 
---

(no changes since v3)

Changes in v3:
- Use %zd in print instead of casting errors to int.

Changes in v2:
- New

 include/drm/drm_mipi_dsi.h | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 70ce0b8cbc68..e0f56564bf97 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -314,17 +314,17 @@ int mipi_dsi_dcs_get_display_brightness_large(struct 
mipi_dsi_device *dsi,
  * @dsi: DSI peripheral device
  * @seq: buffer containing the payload
  */
-#define mipi_dsi_generic_write_seq(dsi, seq...)
\
-   do {   \
-   static const u8 d[] = { seq }; \
-   struct device *dev = >dev;\
-   int ret;   \
-   ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d));   \
-   if (ret < 0) { \
-   dev_err_ratelimited(dev, "transmit data failed: %d\n", \
-   ret);  \
-   return ret;\
-   }  \
+#define mipi_dsi_generic_write_seq(dsi, seq...)
 \
+   do {
\
+   static const u8 d[] = { seq };  
\
+   struct device *dev = >dev; 
\
+   ssize_t ret;
\
+   ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d));
\
+   if (ret < 0) {  
\
+   dev_err_ratelimited(dev, "transmit data failed: %zd\n", 
\
+   ret);   
\
+   return ret; 
\
+   }   
\
} while (0)
 
 /**
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[PATCH v4 1/9] drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_dcs_write_seq()

2024-05-08 Thread Douglas Anderson
The mipi_dsi_dcs_write_seq() macro makes a call to
mipi_dsi_dcs_write_buffer() which returns a type ssize_t. The macro
then stores it in an int and checks to see if it's negative. This
could theoretically be a problem if "ssize_t" is larger than "int".

To see the issue, imagine that "ssize_t" is 32-bits and "int" is
16-bits, you could see a problem if there was some code out there that
looked like:

  mipi_dsi_dcs_write_seq(dsi, cmd, <32767 bytes as arguments>);

...since we'd get back that 32768 bytes were transferred and 32768
stored in a 16-bit int would look negative.

Though there are no callsites where we'd actually hit this (even if
"int" was only 16-bit), it's cleaner to make the types match so let's
fix it.

Fixes: 2a9e9daf7523 ("drm/mipi-dsi: Introduce mipi_dsi_dcs_write_seq macro")
Reviewed-by: Neil Armstrong 
Reviewed-by: Linus Walleij 
Signed-off-by: Douglas Anderson 
---

(no changes since v3)

Changes in v3:
- Use %zd in print instead of casting errors to int.

Changes in v2:
- New

 include/drm/drm_mipi_dsi.h | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 82b1cc434ea3..70ce0b8cbc68 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -333,18 +333,18 @@ int mipi_dsi_dcs_get_display_brightness_large(struct 
mipi_dsi_device *dsi,
  * @cmd: Command
  * @seq: buffer containing data to be transmitted
  */
-#define mipi_dsi_dcs_write_seq(dsi, cmd, seq...)   \
-   do {   \
-   static const u8 d[] = { cmd, seq };\
-   struct device *dev = >dev;\
-   int ret;   \
-   ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d));\
-   if (ret < 0) { \
-   dev_err_ratelimited(   \
-   dev, "sending command %#02x failed: %d\n", \
-   cmd, ret); \
-   return ret;\
-   }  \
+#define mipi_dsi_dcs_write_seq(dsi, cmd, seq...)\
+   do {\
+   static const u8 d[] = { cmd, seq }; \
+   struct device *dev = >dev; \
+   ssize_t ret;\
+   ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \
+   if (ret < 0) {  \
+   dev_err_ratelimited(\
+   dev, "sending command %#02x failed: %zd\n", \
+   cmd, ret);  \
+   return ret; \
+   }   \
} while (0)
 
 /**
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[PATCH v4 0/9] drm/mipi-dsi: Reduce bloat and add funcs for cleaner init seqs

2024-05-08 Thread Douglas Anderson
The consensus of many DRM folks is that we want to move away from DSI
drivers defining tables of init commands. Instead, we want to move to
init functions that can use common DRM functions. The issue thus far
has been that using the macros mipi_dsi_generic_write_seq() and
mipi_dsi_dcs_write_seq() bloats the driver using them.

While trying to solve bloat, we realized that the majority of the it
was easy to solve. This series solves the bloat for existing drivers
by moving the printout outside of the macro.

During discussion of my v1 patch to fix the bloat [1], we also decided
that we really want to change the way that drivers deal with init
sequences to make it clearer. In addition to being cleaner, a side
effect of moving drivers to the new style reduces bloat _even more_.

This series also contains a few minor fixes / cleanups that I found
along the way.

This series converts four drivers over to the new
mipi_dsi_dcs_write_seq_multi() function. Not all conversions have been
tested, but hopefully they are straightforward enough. I'd appreciate
testing.

NOTE: In v3 I tried to incorporate the feedback from v2. I also
converted the other two panels I could find that used table-based
initialization.

v4 just has a tiny bugfix and collects tags. Assuming no other
problems are found the plan is to land this series sometime roughly
around May 16 [2]. Note that unless I get a review/Ack for the patch
("drm/panel: novatek-nt36672e: Switch to
mipi_dsi_dcs_write_seq_multi()") then I'll land the series without
that patch.

[1] 
https://lore.kernel.org/r/20240424172017.1.Id15fae80582bc74a0d4f1338987fa375738f45b9@changeid
[2] https://lore.kernel.org/r/35b899d2-fb47-403a-83d2-204c0800d...@linaro.org

Changes in v4:
- Test to see if init is non-NULL before using it.
- Update wording as per Linus W.

Changes in v3:
- ("mipi_dsi_*_write functions don't need to ratelimit...") moved earlier.
- Add a TODO item for cleaning up the deprecated macros/functions.
- Fix spacing of init function.
- Inline kerneldoc comments for struct mipi_dsi_multi_context.
- Rebased upon patch to remove ratelimit of prints.
- Remove an unneeded error print.
- Squash boe-tv101wum-nl6 lowercase patch into main patch
- Use %zd in print instead of casting errors to int.
- drm/panel: ili9882t: Don't use a table for initting panels
- drm/panel: innolux-p079zca: Don't use a table for initting panels

Changes in v2:
- Add some comments to the macros about printing and returning.
- Change the way err value is handled in prep for next patch.
- Modify commit message now that this is part of a series.
- Rebased upon patches to avoid theoretical int overflow.
- drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_dcs_write_seq()
- drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_generic_write_seq()
- drm/mipi-dsi: Introduce mipi_dsi_*_write_seq_multi()
- drm/mipi-dsi: mipi_dsi_*_write functions don't need to ratelimit prints
- drm/panel: boe-tv101wum-nl6: Convert hex to lowercase
- drm/panel: boe-tv101wum-nl6: Don't use a table for initting commands
- drm/panel: novatek-nt36672e: Switch to mipi_dsi_dcs_write_seq_multi()

Douglas Anderson (9):
  drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_dcs_write_seq()
  drm/mipi-dsi: Fix theoretical int overflow in
mipi_dsi_generic_write_seq()
  drm/mipi-dsi: mipi_dsi_*_write functions don't need to ratelimit
prints
  drm/mipi-dsi: Reduce driver bloat of mipi_dsi_*_write_seq()
  drm/mipi-dsi: Introduce mipi_dsi_*_write_seq_multi()
  drm/panel: novatek-nt36672e: Switch to mipi_dsi_dcs_write_seq_multi()
  drm/panel: boe-tv101wum-nl6: Don't use a table for initting panels
  drm/panel: ili9882t: Don't use a table for initting panels
  drm/panel: innolux-p079zca: Don't use a table for initting panels

 Documentation/gpu/todo.rst|   18 +
 drivers/gpu/drm/drm_mipi_dsi.c|  112 +
 .../gpu/drm/panel/panel-boe-tv101wum-nl6.c| 2792 +
 drivers/gpu/drm/panel/panel-ilitek-ili9882t.c |  794 +++--
 drivers/gpu/drm/panel/panel-innolux-p079zca.c |  284 +-
 .../gpu/drm/panel/panel-novatek-nt36672e.c|  576 ++--
 include/drm/drm_mipi_dsi.h|  101 +-
 7 files changed, 2452 insertions(+), 2225 deletions(-)

-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 48/48] drm/panel: Update TODO list item for cleaning up prepared/enabled tracking

2024-05-03 Thread Douglas Anderson
Now that most panels have been updated not to track/double-check their
prepared/enabled state update the TODO with next steps.

Signed-off-by: Douglas Anderson 
---

(no changes since v1)

 Documentation/gpu/todo.rst | 47 +-
 1 file changed, 26 insertions(+), 21 deletions(-)

diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index e2a0585915b3..4063bc45bbd3 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -469,30 +469,35 @@ Contact: Thomas Zimmermann 
 
 Level: Starter
 
-Clean up checks for already prepared/enabled in panels
---
-
-In a whole pile of panel drivers, we have code to make the
-prepare/unprepare/enable/disable callbacks behave as no-ops if they've already
-been called. To get some idea of the duplicated code, try::
-
-  git grep 'if.*>prepared' -- drivers/gpu/drm/panel
-  git grep 'if.*>enabled' -- drivers/gpu/drm/panel
-
-In the patch ("drm/panel: Check for already prepared/enabled in drm_panel")
-we've moved this check to the core. Now we can most definitely remove the
-check from the individual panels and save a pile of code.
-
-In adition to removing the check from the individual panels, it is believed
-that even the core shouldn't need this check and that should be considered
-an error if other code ever relies on this check. The check in the core
-currently prints a warning whenever something is relying on this check with
-dev_warn(). After a little while, we likely want to promote this to a
-WARN(1) to help encourage folks not to rely on this behavior.
+Remove disable/unprepare in remove/shutdown in panel-simple and panel-edp
+-
+
+As of commit d2aacaf07395 ("drm/panel: Check for already prepared/enabled in
+drm_panel"), we have a check in the drm_panel core to make sure nobody
+double-calls prepare/enable/disable/unprepare. Eventually that should probably
+be turned into a WARN_ON() or somehow made louder, but right now we actually
+expect it to trigger and so we don't want it to be too loud.
+
+Specifically, that warning will trigger for panel-edp and panel-simple at
+shutdown time because those panels hardcode a call to drm_panel_disable()
+and drm_panel_unprepare() at shutdown and remove time that they call regardless
+of panel state. On systems with a properly coded DRM modeset driver that
+calls drm_atomic_helper_shutdown() this is pretty much guaranteed to cause
+the warning to fire.
+
+Unfortunately we can't safely remove the calls in panel-edp and panel-simple
+until we're sure that all DRM modeset drivers that are used with those panels
+properly call drm_atomic_helper_shutdown(). This TODO item is to validate
+that all DRM modeset drivers used with panel-edp and panel-simple properly
+call drm_atomic_helper_shutdown() and then remove the calls to
+disable/unprepare from those panels. Alternatively, this TODO item could be
+removed by convincing stakeholders that those calls are fine and downgrading
+the error message in drm_panel_disable() / drm_panel_unprepare() to a
+debug-level message.
 
 Contact: Douglas Anderson 
 
-Level: Starter/Intermediate
+Level: Intermediate
 
 
 Core refactorings
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 47/48] drm/panel: sony-acx565akm: Don't call disable at remove

2024-05-03 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

A grep through mainline for compatible strings used by this driver
indicates that it is used by TI OMAP boards. The TI OMAP driver
appears to be correctly calling drm_atomic_helper_shutdown() so we can
remove the calls.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Laurent Pinchart 
Cc: Sebastian Reichel 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-sony-acx565akm.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-sony-acx565akm.c 
b/drivers/gpu/drm/panel/panel-sony-acx565akm.c
index a9a545a56404..73ba93ff00fe 100644
--- a/drivers/gpu/drm/panel/panel-sony-acx565akm.c
+++ b/drivers/gpu/drm/panel/panel-sony-acx565akm.c
@@ -652,9 +652,6 @@ static void acx565akm_remove(struct spi_device *spi)
 
if (lcd->has_bc)
acx565akm_backlight_cleanup(lcd);
-
-   drm_panel_disable(>panel);
-   drm_panel_unprepare(>panel);
 }
 
 static const struct of_device_id acx565akm_of_match[] = {
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 46/48] drm/panel: sony-acx565akm: Don't double-check enabled state in disable

2024-05-03 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

The acx565akm seems to do some unique stuff with the "enabled"
state. Specifically:
1. It seems to detect the enabled state based on how the bootloader
   left the panel.
2. It uses the enabled state to prevent certain sysfs files from
   accessing a disabled panel.

We'll leave the "enabled" state tracking for this. However, we can at
least get rid of the double-check when trying to disable.

Cc: Laurent Pinchart 
Cc: Sebastian Reichel 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-sony-acx565akm.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-sony-acx565akm.c 
b/drivers/gpu/drm/panel/panel-sony-acx565akm.c
index 3d6a286056a0..a9a545a56404 100644
--- a/drivers/gpu/drm/panel/panel-sony-acx565akm.c
+++ b/drivers/gpu/drm/panel/panel-sony-acx565akm.c
@@ -454,9 +454,6 @@ static int acx565akm_power_on(struct acx565akm_panel *lcd)
 
 static void acx565akm_power_off(struct acx565akm_panel *lcd)
 {
-   if (!lcd->enabled)
-   return;
-
acx565akm_set_display_state(lcd, 0);
acx565akm_set_sleep_mode(lcd, 1);
lcd->enabled = false;
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 45/48] drm/panel: raydium-rm67191: Don't call unprepare+disable at shutdown

2024-05-03 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

A grep through mainline for compatible strings used by this driver
indicates that it is used by IMX boards. The IMX driver appears to be
correctly calling drm_atomic_helper_shutdown() so we can remove the
calls.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Robert Chiras 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-raydium-rm67191.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-raydium-rm67191.c 
b/drivers/gpu/drm/panel/panel-raydium-rm67191.c
index fa9bf89d3bb5..b2029e035635 100644
--- a/drivers/gpu/drm/panel/panel-raydium-rm67191.c
+++ b/drivers/gpu/drm/panel/panel-raydium-rm67191.c
@@ -612,14 +612,6 @@ static void rad_panel_remove(struct mipi_dsi_device *dsi)
drm_panel_remove(>panel);
 }
 
-static void rad_panel_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct rad_panel *rad = mipi_dsi_get_drvdata(dsi);
-
-   drm_panel_disable(>panel);
-   drm_panel_unprepare(>panel);
-}
-
 static const struct of_device_id rad_of_match[] = {
{ .compatible = "raydium,rm67191", },
{ /* sentinel */ }
@@ -633,7 +625,6 @@ static struct mipi_dsi_driver rad_panel_driver = {
},
.probe = rad_panel_probe,
.remove = rad_panel_remove,
-   .shutdown = rad_panel_shutdown,
 };
 module_mipi_dsi_driver(rad_panel_driver);
 
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 44/48] drm/panel: raydium-rm67191: Stop tracking enabled

2024-05-03 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

The conversion of the rm67191 panel driver follows many of the other
panel drivers but has a few differences that need to be called out.

Like in commit 1e0465eb16a4 ("drm/panel: otm8009a: Don't double check
prepared/enabled"), this panel also uses the "prepared" flag to
prevent the backlight functions from running when the panel is powered
off. This is probably not the safest thing to do but the old behavior
was preserved. See the discussion in the otm8009a patch. Because of
this, I've left the driver tracking "prepared" but removed its
tracking of "enabled".

NOTE: as part of this, transition the panel's direct calls to its
disable/unprepare functions in shutdown to call through DRM panel.

Cc: Robert Chiras 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-raydium-rm67191.c | 21 ++-
 1 file changed, 2 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-raydium-rm67191.c 
b/drivers/gpu/drm/panel/panel-raydium-rm67191.c
index dbb1ed4efbed..fa9bf89d3bb5 100644
--- a/drivers/gpu/drm/panel/panel-raydium-rm67191.c
+++ b/drivers/gpu/drm/panel/panel-raydium-rm67191.c
@@ -205,7 +205,6 @@ struct rad_panel {
unsigned int num_supplies;
 
bool prepared;
-   bool enabled;
 };
 
 static const struct drm_display_mode default_mode = {
@@ -267,9 +266,6 @@ static int rad_panel_prepare(struct drm_panel *panel)
struct rad_panel *rad = to_rad_panel(panel);
int ret;
 
-   if (rad->prepared)
-   return 0;
-
ret = regulator_bulk_enable(rad->num_supplies, rad->supplies);
if (ret)
return ret;
@@ -291,9 +287,6 @@ static int rad_panel_unprepare(struct drm_panel *panel)
struct rad_panel *rad = to_rad_panel(panel);
int ret;
 
-   if (!rad->prepared)
-   return 0;
-
/*
 * Right after asserting the reset, we need to release it, so that the
 * touch driver can have an active connection with the touch controller
@@ -322,9 +315,6 @@ static int rad_panel_enable(struct drm_panel *panel)
int color_format = color_format_from_dsi_format(dsi->format);
int ret;
 
-   if (rad->enabled)
-   return 0;
-
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
 
ret = rad_panel_push_cmd_list(dsi);
@@ -389,8 +379,6 @@ static int rad_panel_enable(struct drm_panel *panel)
 
backlight_enable(rad->backlight);
 
-   rad->enabled = true;
-
return 0;
 
 fail:
@@ -406,9 +394,6 @@ static int rad_panel_disable(struct drm_panel *panel)
struct device *dev = >dev;
int ret;
 
-   if (!rad->enabled)
-   return 0;
-
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
 
backlight_disable(rad->backlight);
@@ -429,8 +414,6 @@ static int rad_panel_disable(struct drm_panel *panel)
return ret;
}
 
-   rad->enabled = false;
-
return 0;
 }
 
@@ -633,8 +616,8 @@ static void rad_panel_shutdown(struct mipi_dsi_device *dsi)
 {
struct rad_panel *rad = mipi_dsi_get_drvdata(dsi);
 
-   rad_panel_disable(>panel);
-   rad_panel_unprepare(>panel);
+   drm_panel_disable(>panel);
+   drm_panel_unprepare(>panel);
 }
 
 static const struct of_device_id rad_of_match[] = {
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 43/48] drm/panel: sitronix-st7703: Don't call disable at shutdown/remove

2024-05-03 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

The compatible strings used by this driver seem to show up across
boards using a variety of DRM drivers. It appears that the relevant
drivers have been converted, but at least one compatible string
doesn't seem to be found in any mainline dts files so we can't be 100%
sure. If it is found that the DRM modeset driver hasn't been fixed
then this patch could be temporarily reverted until it is.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: "Guido Günther" 
Cc: "Ondřej Jirman" 
Cc: Chris Morgan 
Cc: Frank Oltmanns 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-sitronix-st7703.c | 17 -
 1 file changed, 17 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c 
b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
index 6b2d940640ca..77b30e045a57 100644
--- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c
+++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
@@ -937,27 +937,11 @@ static int st7703_probe(struct mipi_dsi_device *dsi)
return 0;
 }
 
-static void st7703_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct st7703 *ctx = mipi_dsi_get_drvdata(dsi);
-   int ret;
-
-   ret = drm_panel_unprepare(>panel);
-   if (ret < 0)
-   dev_err(>dev, "Failed to unprepare panel: %d\n", ret);
-
-   ret = drm_panel_disable(>panel);
-   if (ret < 0)
-   dev_err(>dev, "Failed to disable panel: %d\n", ret);
-}
-
 static void st7703_remove(struct mipi_dsi_device *dsi)
 {
struct st7703 *ctx = mipi_dsi_get_drvdata(dsi);
int ret;
 
-   st7703_shutdown(dsi);
-
ret = mipi_dsi_detach(dsi);
if (ret < 0)
dev_err(>dev, "Failed to detach from DSI host: %d\n", ret);
@@ -981,7 +965,6 @@ MODULE_DEVICE_TABLE(of, st7703_of_match);
 static struct mipi_dsi_driver st7703_driver = {
.probe  = st7703_probe,
.remove = st7703_remove,
-   .shutdown = st7703_shutdown,
.driver = {
.name = DRV_NAME,
.of_match_table = st7703_of_match,
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 42/48] drm/panel: sitronix-st7703: Stop tracking prepared

2024-05-03 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

One thing to note for st7703 is that it has a special "allpixelson"
debugfs file. When this file is written the driver hacks a
disable/unprepare and then a prepare/enable to try to reset the
panel. Potentially that might have been relying on the old booleans we
removed. It'll still "work" because of the checks in the core but it
deserves a comment. This debugfs file didn't appear to be particularly
safe to use even before this patch since it would cause a
disabled/unprepared panel to become prepared/enabled.

Cc: "Guido Günther" 
Cc: "Ondřej Jirman" 
Cc: Chris Morgan 
Cc: Frank Oltmanns 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-sitronix-st7703.c | 18 +++---
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c 
b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
index 7d8302cca091..6b2d940640ca 100644
--- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c
+++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
@@ -58,7 +58,6 @@ struct st7703 {
struct gpio_desc *reset_gpio;
struct regulator *vcc;
struct regulator *iovcc;
-   bool prepared;
 
struct dentry *debugfs;
const struct st7703_panel_desc *desc;
@@ -752,13 +751,9 @@ static int st7703_unprepare(struct drm_panel *panel)
 {
struct st7703 *ctx = panel_to_st7703(panel);
 
-   if (!ctx->prepared)
-   return 0;
-
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
regulator_disable(ctx->iovcc);
regulator_disable(ctx->vcc);
-   ctx->prepared = false;
 
return 0;
 }
@@ -768,9 +763,6 @@ static int st7703_prepare(struct drm_panel *panel)
struct st7703 *ctx = panel_to_st7703(panel);
int ret;
 
-   if (ctx->prepared)
-   return 0;
-
dev_dbg(ctx->dev, "Resetting the panel\n");
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
 
@@ -793,8 +785,6 @@ static int st7703_prepare(struct drm_panel *panel)
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
usleep_range(15000, 2);
 
-   ctx->prepared = true;
-
return 0;
 }
 
@@ -854,7 +844,13 @@ static int allpixelson_set(void *data, u64 val)
dev_dbg(ctx->dev, "Setting all pixels on\n");
mipi_dsi_generic_write_seq(dsi, ST7703_CMD_ALL_PIXEL_ON);
msleep(val * 1000);
-   /* Reset the panel to get video back */
+
+   /*
+* Reset the panel to get video back. NOTE: This isn't a
+* particularly safe thing to do in general because it assumes
+* that the screen was on to begin with, but this is just a
+* debugfs file so it's not a huge deal.
+*/
drm_panel_disable(>panel);
drm_panel_unprepare(>panel);
drm_panel_prepare(>panel);
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 41/48] drm/panel: sharp-ls043t1le01: Don't call disable at shutdown/remove

2024-05-03 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

A grep through mainline for compatible strings used by this driver
indicates that it is used by Qualcomm boards. The Qualcomm driver
appears to be correctly calling drm_atomic_helper_shutdown() so we can
remove the calls.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Werner Johansson 
Cc: Dmitry Baryshkov 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c 
b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
index c86337954ad7..729cbb0d8403 100644
--- a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
+++ b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
@@ -267,10 +267,6 @@ static void sharp_nt_panel_remove(struct mipi_dsi_device 
*dsi)
struct sharp_nt_panel *sharp_nt = mipi_dsi_get_drvdata(dsi);
int ret;
 
-   ret = drm_panel_disable(_nt->base);
-   if (ret < 0)
-   dev_err(>dev, "failed to disable panel: %d\n", ret);
-
ret = mipi_dsi_detach(dsi);
if (ret < 0)
dev_err(>dev, "failed to detach from DSI host: %d\n", ret);
@@ -278,13 +274,6 @@ static void sharp_nt_panel_remove(struct mipi_dsi_device 
*dsi)
sharp_nt_panel_del(sharp_nt);
 }
 
-static void sharp_nt_panel_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct sharp_nt_panel *sharp_nt = mipi_dsi_get_drvdata(dsi);
-
-   drm_panel_disable(_nt->base);
-}
-
 static const struct of_device_id sharp_nt_of_match[] = {
{ .compatible = "sharp,ls043t1le01-qhd", },
{ }
@@ -298,7 +287,6 @@ static struct mipi_dsi_driver sharp_nt_panel_driver = {
},
.probe = sharp_nt_panel_probe,
.remove = sharp_nt_panel_remove,
-   .shutdown = sharp_nt_panel_shutdown,
 };
 module_mipi_dsi_driver(sharp_nt_panel_driver);
 
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 40/48] drm/panel: sharp-ls043t1le01: Stop tracking prepared

2024-05-03 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Cc: Werner Johansson 
Cc: Dmitry Baryshkov 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c 
b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
index 855e6daa..c86337954ad7 100644
--- a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
+++ b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
@@ -26,8 +26,6 @@ struct sharp_nt_panel {
 
struct regulator *supply;
struct gpio_desc *reset_gpio;
-
-   bool prepared;
 };
 
 static inline struct sharp_nt_panel *to_sharp_nt_panel(struct drm_panel *panel)
@@ -99,9 +97,6 @@ static int sharp_nt_panel_unprepare(struct drm_panel *panel)
struct sharp_nt_panel *sharp_nt = to_sharp_nt_panel(panel);
int ret;
 
-   if (!sharp_nt->prepared)
-   return 0;
-
ret = sharp_nt_panel_off(sharp_nt);
if (ret < 0) {
dev_err(panel->dev, "failed to set panel off: %d\n", ret);
@@ -112,8 +107,6 @@ static int sharp_nt_panel_unprepare(struct drm_panel *panel)
if (sharp_nt->reset_gpio)
gpiod_set_value(sharp_nt->reset_gpio, 0);
 
-   sharp_nt->prepared = false;
-
return 0;
 }
 
@@ -122,9 +115,6 @@ static int sharp_nt_panel_prepare(struct drm_panel *panel)
struct sharp_nt_panel *sharp_nt = to_sharp_nt_panel(panel);
int ret;
 
-   if (sharp_nt->prepared)
-   return 0;
-
ret = regulator_enable(sharp_nt->supply);
if (ret < 0)
return ret;
@@ -152,8 +142,6 @@ static int sharp_nt_panel_prepare(struct drm_panel *panel)
goto poweroff;
}
 
-   sharp_nt->prepared = true;
-
return 0;
 
 poweroff:
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 39/48] drm/panel: sharp-lq101r1sx01: Don't call disable at shutdown/remove

2024-05-03 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

A grep through mainline for compatible strings used by this driver
indicates that it is used by Tegra boards. The Tegra driver appears to
be correctly calling drm_atomic_helper_shutdown() so we can remove the
calls.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Thierry Reding 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 .../gpu/drm/panel/panel-sharp-lq101r1sx01.c   | 24 ++-
 1 file changed, 2 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c 
b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
index 8f6c21b99522..edc9425bb143 100644
--- a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
+++ b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
@@ -357,32 +357,13 @@ static void sharp_panel_remove(struct mipi_dsi_device 
*dsi)
struct sharp_panel *sharp = mipi_dsi_get_drvdata(dsi);
int err;
 
-   /* only detach from host for the DSI-LINK2 interface */
-   if (!sharp) {
-   mipi_dsi_detach(dsi);
-   return;
-   }
-
-   err = drm_panel_disable(>base);
-   if (err < 0)
-   dev_err(>dev, "failed to disable panel: %d\n", err);
-
err = mipi_dsi_detach(dsi);
if (err < 0)
dev_err(>dev, "failed to detach from DSI host: %d\n", err);
 
-   sharp_panel_del(sharp);
-}
-
-static void sharp_panel_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct sharp_panel *sharp = mipi_dsi_get_drvdata(dsi);
-
-   /* nothing to do for DSI-LINK2 */
+   /* only detach from host for the DSI-LINK2 interface */
if (!sharp)
-   return;
-
-   drm_panel_disable(>base);
+   sharp_panel_del(sharp);
 }
 
 static struct mipi_dsi_driver sharp_panel_driver = {
@@ -392,7 +373,6 @@ static struct mipi_dsi_driver sharp_panel_driver = {
},
.probe = sharp_panel_probe,
.remove = sharp_panel_remove,
-   .shutdown = sharp_panel_shutdown,
 };
 module_mipi_dsi_driver(sharp_panel_driver);
 
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 38/48] drm/panel: sharp-lq101r1sx01: Stop tracking prepared/enabled

2024-05-03 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Cc: Thierry Reding 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 .../gpu/drm/panel/panel-sharp-lq101r1sx01.c   | 39 ---
 1 file changed, 39 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c 
b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
index 14851408a5e1..8f6c21b99522 100644
--- a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
+++ b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
@@ -24,9 +24,6 @@ struct sharp_panel {
 
struct regulator *supply;
 
-   bool prepared;
-   bool enabled;
-
const struct drm_display_mode *mode;
 };
 
@@ -85,26 +82,11 @@ static __maybe_unused int sharp_panel_read(struct 
sharp_panel *sharp,
return err;
 }
 
-static int sharp_panel_disable(struct drm_panel *panel)
-{
-   struct sharp_panel *sharp = to_sharp_panel(panel);
-
-   if (!sharp->enabled)
-   return 0;
-
-   sharp->enabled = false;
-
-   return 0;
-}
-
 static int sharp_panel_unprepare(struct drm_panel *panel)
 {
struct sharp_panel *sharp = to_sharp_panel(panel);
int err;
 
-   if (!sharp->prepared)
-   return 0;
-
sharp_wait_frames(sharp, 4);
 
err = mipi_dsi_dcs_set_display_off(sharp->link1);
@@ -119,8 +101,6 @@ static int sharp_panel_unprepare(struct drm_panel *panel)
 
regulator_disable(sharp->supply);
 
-   sharp->prepared = false;
-
return 0;
 }
 
@@ -164,9 +144,6 @@ static int sharp_panel_prepare(struct drm_panel *panel)
u8 format = MIPI_DCS_PIXEL_FMT_24BIT;
int err;
 
-   if (sharp->prepared)
-   return 0;
-
err = regulator_enable(sharp->supply);
if (err < 0)
return err;
@@ -235,8 +212,6 @@ static int sharp_panel_prepare(struct drm_panel *panel)
goto poweroff;
}
 
-   sharp->prepared = true;
-
/* wait for 6 frames before continuing */
sharp_wait_frames(sharp, 6);
 
@@ -247,18 +222,6 @@ static int sharp_panel_prepare(struct drm_panel *panel)
return err;
 }
 
-static int sharp_panel_enable(struct drm_panel *panel)
-{
-   struct sharp_panel *sharp = to_sharp_panel(panel);
-
-   if (sharp->enabled)
-   return 0;
-
-   sharp->enabled = true;
-
-   return 0;
-}
-
 static const struct drm_display_mode default_mode = {
.clock = 278000,
.hdisplay = 2560,
@@ -295,10 +258,8 @@ static int sharp_panel_get_modes(struct drm_panel *panel,
 }
 
 static const struct drm_panel_funcs sharp_panel_funcs = {
-   .disable = sharp_panel_disable,
.unprepare = sharp_panel_unprepare,
.prepare = sharp_panel_prepare,
-   .enable = sharp_panel_enable,
.get_modes = sharp_panel_get_modes,
 };
 
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 37/48] drm/panel: seiko-43wvf1g: Don't call disable at shutdown/remove

2024-05-03 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

A grep through mainline for compatible strings used by this driver
indicates that it is used by IMX boards. As far as I can tell, all IMX
boards are now correctly calling drm_atomic_helper_shutdown() so we
can remove the calls.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Marco Franchi 
Cc: Fabio Estevam 
Cc: Laurentiu Palcu 
Cc: Pengutronix Kernel Team 
Cc: i...@lists.linux.dev
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-seiko-43wvf1g.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c 
b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c
index 98480904126c..8a3fe531c641 100644
--- a/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c
+++ b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c
@@ -243,14 +243,6 @@ static void seiko_panel_remove(struct platform_device 
*pdev)
struct seiko_panel *panel = platform_get_drvdata(pdev);
 
drm_panel_remove(>base);
-   drm_panel_disable(>base);
-}
-
-static void seiko_panel_shutdown(struct platform_device *pdev)
-{
-   struct seiko_panel *panel = platform_get_drvdata(pdev);
-
-   drm_panel_disable(>base);
 }
 
 static const struct display_timing seiko_43wvf1g_timing = {
@@ -306,7 +298,6 @@ static struct platform_driver seiko_panel_platform_driver = 
{
},
.probe = seiko_panel_platform_probe,
.remove_new = seiko_panel_remove,
-   .shutdown = seiko_panel_shutdown,
 };
 module_platform_driver(seiko_panel_platform_driver);
 
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 36/48] drm/panel: seiko-43wvf1g: Stop tracking prepared/enabled

2024-05-03 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Cc: Marco Franchi 
Cc: Fabio Estevam 
Cc: Laurentiu Palcu 
Cc: Pengutronix Kernel Team 
Cc: i...@lists.linux.dev
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-seiko-43wvf1g.c | 40 -
 1 file changed, 40 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c 
b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c
index 658c7c040570..98480904126c 100644
--- a/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c
+++ b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c
@@ -44,8 +44,6 @@ struct seiko_panel_desc {
 
 struct seiko_panel {
struct drm_panel base;
-   bool prepared;
-   bool enabled;
const struct seiko_panel_desc *desc;
struct regulator *dvdd;
struct regulator *avdd;
@@ -122,25 +120,10 @@ static int seiko_panel_get_fixed_modes(struct seiko_panel 
*panel,
return num;
 }
 
-static int seiko_panel_disable(struct drm_panel *panel)
-{
-   struct seiko_panel *p = to_seiko_panel(panel);
-
-   if (!p->enabled)
-   return 0;
-
-   p->enabled = false;
-
-   return 0;
-}
-
 static int seiko_panel_unprepare(struct drm_panel *panel)
 {
struct seiko_panel *p = to_seiko_panel(panel);
 
-   if (!p->prepared)
-   return 0;
-
gpiod_set_value_cansleep(p->enable_gpio, 0);
 
regulator_disable(p->avdd);
@@ -150,8 +133,6 @@ static int seiko_panel_unprepare(struct drm_panel *panel)
 
regulator_disable(p->dvdd);
 
-   p->prepared = false;
-
return 0;
 }
 
@@ -160,9 +141,6 @@ static int seiko_panel_prepare(struct drm_panel *panel)
struct seiko_panel *p = to_seiko_panel(panel);
int err;
 
-   if (p->prepared)
-   return 0;
-
err = regulator_enable(p->dvdd);
if (err < 0) {
dev_err(panel->dev, "failed to enable dvdd: %d\n", err);
@@ -180,8 +158,6 @@ static int seiko_panel_prepare(struct drm_panel *panel)
 
gpiod_set_value_cansleep(p->enable_gpio, 1);
 
-   p->prepared = true;
-
return 0;
 
 disable_dvdd:
@@ -189,18 +165,6 @@ static int seiko_panel_prepare(struct drm_panel *panel)
return err;
 }
 
-static int seiko_panel_enable(struct drm_panel *panel)
-{
-   struct seiko_panel *p = to_seiko_panel(panel);
-
-   if (p->enabled)
-   return 0;
-
-   p->enabled = true;
-
-   return 0;
-}
-
 static int seiko_panel_get_modes(struct drm_panel *panel,
 struct drm_connector *connector)
 {
@@ -228,10 +192,8 @@ static int seiko_panel_get_timings(struct drm_panel *panel,
 }
 
 static const struct drm_panel_funcs seiko_panel_funcs = {
-   .disable = seiko_panel_disable,
.unprepare = seiko_panel_unprepare,
.prepare = seiko_panel_prepare,
-   .enable = seiko_panel_enable,
.get_modes = seiko_panel_get_modes,
.get_timings = seiko_panel_get_timings,
 };
@@ -246,8 +208,6 @@ static int seiko_panel_probe(struct device *dev,
if (!panel)
return -ENOMEM;
 
-   panel->enabled = false;
-   panel->prepared = false;
panel->desc = desc;
 
panel->dvdd = devm_regulator_get(dev, "dvdd");
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 35/48] drm/panel: panasonic-vvx10f034n00: Don't call disable at shutdown/remove

2024-05-03 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

Unfortunately, grepping mainline for this panel's compatible string
shows no hits, so we can't be 100% sure if the DRM modeset driver used
with this panel has been fixed. If it is found that the DRM modeset
driver hasn't been fixed then this patch could be temporarily reverted
until it is.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Werner Johansson 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c 
b/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c
index 822ca2f971eb..d1c5c9bc3c56 100644
--- a/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c
+++ b/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c
@@ -222,10 +222,6 @@ static void wuxga_nt_panel_remove(struct mipi_dsi_device 
*dsi)
struct wuxga_nt_panel *wuxga_nt = mipi_dsi_get_drvdata(dsi);
int ret;
 
-   ret = drm_panel_disable(_nt->base);
-   if (ret < 0)
-   dev_err(>dev, "failed to disable panel: %d\n", ret);
-
ret = mipi_dsi_detach(dsi);
if (ret < 0)
dev_err(>dev, "failed to detach from DSI host: %d\n", ret);
@@ -233,13 +229,6 @@ static void wuxga_nt_panel_remove(struct mipi_dsi_device 
*dsi)
wuxga_nt_panel_del(wuxga_nt);
 }
 
-static void wuxga_nt_panel_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct wuxga_nt_panel *wuxga_nt = mipi_dsi_get_drvdata(dsi);
-
-   drm_panel_disable(_nt->base);
-}
-
 static struct mipi_dsi_driver wuxga_nt_panel_driver = {
.driver = {
.name = "panel-panasonic-vvx10f034n00",
@@ -247,7 +236,6 @@ static struct mipi_dsi_driver wuxga_nt_panel_driver = {
},
.probe = wuxga_nt_panel_probe,
.remove = wuxga_nt_panel_remove,
-   .shutdown = wuxga_nt_panel_shutdown,
 };
 module_mipi_dsi_driver(wuxga_nt_panel_driver);
 
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 34/48] drm/panel: panasonic-vvx10f034n00: Stop tracking prepared/enabled

2024-05-03 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Cc: Werner Johansson 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 .../drm/panel/panel-panasonic-vvx10f034n00.c  | 35 +--
 1 file changed, 1 insertion(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c 
b/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c
index 8ba6d8287938..822ca2f971eb 100644
--- a/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c
+++ b/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c
@@ -32,9 +32,6 @@ struct wuxga_nt_panel {
 
struct regulator *supply;
 
-   bool prepared;
-   bool enabled;
-
ktime_t earliest_wake;
 
const struct drm_display_mode *mode;
@@ -53,28 +50,16 @@ static int wuxga_nt_panel_on(struct wuxga_nt_panel 
*wuxga_nt)
 static int wuxga_nt_panel_disable(struct drm_panel *panel)
 {
struct wuxga_nt_panel *wuxga_nt = to_wuxga_nt_panel(panel);
-   int mipi_ret, bl_ret = 0;
-
-   if (!wuxga_nt->enabled)
-   return 0;
-
-   mipi_ret = mipi_dsi_shutdown_peripheral(wuxga_nt->dsi);
-
-   wuxga_nt->enabled = false;
 
-   return mipi_ret ? mipi_ret : bl_ret;
+   return mipi_dsi_shutdown_peripheral(wuxga_nt->dsi);
 }
 
 static int wuxga_nt_panel_unprepare(struct drm_panel *panel)
 {
struct wuxga_nt_panel *wuxga_nt = to_wuxga_nt_panel(panel);
 
-   if (!wuxga_nt->prepared)
-   return 0;
-
regulator_disable(wuxga_nt->supply);
wuxga_nt->earliest_wake = ktime_add_ms(ktime_get_real(), MIN_POFF_MS);
-   wuxga_nt->prepared = false;
 
return 0;
 }
@@ -85,9 +70,6 @@ static int wuxga_nt_panel_prepare(struct drm_panel *panel)
int ret;
s64 enablewait;
 
-   if (wuxga_nt->prepared)
-   return 0;
-
/*
 * If the user re-enabled the panel before the required off-time then
 * we need to wait the remaining period before re-enabling regulator
@@ -117,8 +99,6 @@ static int wuxga_nt_panel_prepare(struct drm_panel *panel)
goto poweroff;
}
 
-   wuxga_nt->prepared = true;
-
return 0;
 
 poweroff:
@@ -127,18 +107,6 @@ static int wuxga_nt_panel_prepare(struct drm_panel *panel)
return ret;
 }
 
-static int wuxga_nt_panel_enable(struct drm_panel *panel)
-{
-   struct wuxga_nt_panel *wuxga_nt = to_wuxga_nt_panel(panel);
-
-   if (wuxga_nt->enabled)
-   return 0;
-
-   wuxga_nt->enabled = true;
-
-   return 0;
-}
-
 static const struct drm_display_mode default_mode = {
.clock = 164402,
.hdisplay = 1920,
@@ -178,7 +146,6 @@ static const struct drm_panel_funcs wuxga_nt_panel_funcs = {
.disable = wuxga_nt_panel_disable,
.unprepare = wuxga_nt_panel_unprepare,
.prepare = wuxga_nt_panel_prepare,
-   .enable = wuxga_nt_panel_enable,
.get_modes = wuxga_nt_panel_get_modes,
 };
 
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 33/48] drm/panel: jdi-lt070me05000: Don't call disable at shutdown/remove

2024-05-03 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

A grep through mainline for compatible strings used by this driver
indicates that it is used by Qualcomm boards. The Qualcomm driver
appears to be correctly calling drm_atomic_helper_shutdown() so we can
remove the calls.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Vinay Simha BN 
Cc: Sumit Semwal 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-jdi-lt070me05000.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c 
b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
index 4ee6fa1e..b1ce186de261 100644
--- a/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
+++ b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
@@ -452,10 +452,6 @@ static void jdi_panel_remove(struct mipi_dsi_device *dsi)
struct jdi_panel *jdi = mipi_dsi_get_drvdata(dsi);
int ret;
 
-   ret = drm_panel_disable(>base);
-   if (ret < 0)
-   dev_err(>dev, "failed to disable panel: %d\n", ret);
-
ret = mipi_dsi_detach(dsi);
if (ret < 0)
dev_err(>dev, "failed to detach from DSI host: %d\n",
@@ -464,13 +460,6 @@ static void jdi_panel_remove(struct mipi_dsi_device *dsi)
jdi_panel_del(jdi);
 }
 
-static void jdi_panel_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct jdi_panel *jdi = mipi_dsi_get_drvdata(dsi);
-
-   drm_panel_disable(>base);
-}
-
 static struct mipi_dsi_driver jdi_panel_driver = {
.driver = {
.name = "panel-jdi-lt070me05000",
@@ -478,7 +467,6 @@ static struct mipi_dsi_driver jdi_panel_driver = {
},
.probe = jdi_panel_probe,
.remove = jdi_panel_remove,
-   .shutdown = jdi_panel_shutdown,
 };
 module_mipi_dsi_driver(jdi_panel_driver);
 
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 32/48] drm/panel: jdi-lt070me05000: Stop tracking prepared/enabled

2024-05-03 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

NOTE: as part of this, transition the panel's direct calls to its
disable function in shutdown/remove to call through DRM panel.

Cc: Vinay Simha BN 
Cc: Sumit Semwal 
Signed-off-by: Douglas Anderson 
---
Note: since we are able to identify that this panel only appears to be
used on Qualcomm boards and we have to touch the shutdown/remove path
in this patch anyway, we could possibly squash this with the next
patch that removes the disable call in shutdown/remove. For now I'm
keeping them separate just to keep the concepts separate.

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 .../gpu/drm/panel/panel-jdi-lt070me05000.c| 27 ++-
 1 file changed, 2 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c 
b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
index f9a69f347068..4ee6fa1e 100644
--- a/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
+++ b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
@@ -37,9 +37,6 @@ struct jdi_panel {
struct gpio_desc *dcdc_en_gpio;
struct backlight_device *backlight;
 
-   bool prepared;
-   bool enabled;
-
const struct drm_display_mode *mode;
 };
 
@@ -176,13 +173,8 @@ static int jdi_panel_disable(struct drm_panel *panel)
 {
struct jdi_panel *jdi = to_jdi_panel(panel);
 
-   if (!jdi->enabled)
-   return 0;
-
backlight_disable(jdi->backlight);
 
-   jdi->enabled = false;
-
return 0;
 }
 
@@ -192,9 +184,6 @@ static int jdi_panel_unprepare(struct drm_panel *panel)
struct device *dev = >dsi->dev;
int ret;
 
-   if (!jdi->prepared)
-   return 0;
-
jdi_panel_off(jdi);
 
ret = regulator_bulk_disable(ARRAY_SIZE(jdi->supplies), jdi->supplies);
@@ -207,8 +196,6 @@ static int jdi_panel_unprepare(struct drm_panel *panel)
 
gpiod_set_value(jdi->dcdc_en_gpio, 0);
 
-   jdi->prepared = false;
-
return 0;
 }
 
@@ -218,9 +205,6 @@ static int jdi_panel_prepare(struct drm_panel *panel)
struct device *dev = >dsi->dev;
int ret;
 
-   if (jdi->prepared)
-   return 0;
-
ret = regulator_bulk_enable(ARRAY_SIZE(jdi->supplies), jdi->supplies);
if (ret < 0) {
dev_err(dev, "regulator enable failed, %d\n", ret);
@@ -250,8 +234,6 @@ static int jdi_panel_prepare(struct drm_panel *panel)
goto poweroff;
}
 
-   jdi->prepared = true;
-
return 0;
 
 poweroff:
@@ -272,13 +254,8 @@ static int jdi_panel_enable(struct drm_panel *panel)
 {
struct jdi_panel *jdi = to_jdi_panel(panel);
 
-   if (jdi->enabled)
-   return 0;
-
backlight_enable(jdi->backlight);
 
-   jdi->enabled = true;
-
return 0;
 }
 
@@ -475,7 +452,7 @@ static void jdi_panel_remove(struct mipi_dsi_device *dsi)
struct jdi_panel *jdi = mipi_dsi_get_drvdata(dsi);
int ret;
 
-   ret = jdi_panel_disable(>base);
+   ret = drm_panel_disable(>base);
if (ret < 0)
dev_err(>dev, "failed to disable panel: %d\n", ret);
 
@@ -491,7 +468,7 @@ static void jdi_panel_shutdown(struct mipi_dsi_device *dsi)
 {
struct jdi_panel *jdi = mipi_dsi_get_drvdata(dsi);
 
-   jdi_panel_disable(>base);
+   drm_panel_disable(>base);
 }
 
 static struct mipi_dsi_driver jdi_panel_driver = {
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 30/48] drm/panel: xinpeng-xpp055c272: Stop tracking prepared

2024-05-03 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Cc: "Heiko Stübner" 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c 
b/drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c
index 8670386498a4..8262c00670cf 100644
--- a/drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c
+++ b/drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c
@@ -52,7 +52,6 @@ struct xpp055c272 {
struct gpio_desc *reset_gpio;
struct regulator *vci;
struct regulator *iovcc;
-   bool prepared;
 };
 
 static inline struct xpp055c272 *panel_to_xpp055c272(struct drm_panel *panel)
@@ -136,9 +135,6 @@ static int xpp055c272_unprepare(struct drm_panel *panel)
struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
int ret;
 
-   if (!ctx->prepared)
-   return 0;
-
ret = mipi_dsi_dcs_set_display_off(dsi);
if (ret < 0)
dev_err(ctx->dev, "failed to set display off: %d\n", ret);
@@ -152,8 +148,6 @@ static int xpp055c272_unprepare(struct drm_panel *panel)
regulator_disable(ctx->iovcc);
regulator_disable(ctx->vci);
 
-   ctx->prepared = false;
-
return 0;
 }
 
@@ -163,9 +157,6 @@ static int xpp055c272_prepare(struct drm_panel *panel)
struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
int ret;
 
-   if (ctx->prepared)
-   return 0;
-
dev_dbg(ctx->dev, "Resetting the panel\n");
ret = regulator_enable(ctx->vci);
if (ret < 0) {
@@ -209,8 +200,6 @@ static int xpp055c272_prepare(struct drm_panel *panel)
 
msleep(50);
 
-   ctx->prepared = true;
-
return 0;
 
 disable_iovcc:
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 31/48] drm/panel: xinpeng-xpp055c272: Don't call unprepare+disable at shutdown/remove

2024-05-03 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

A grep through mainline for compatible strings used by this driver
indicates that it is used by Rockchip boards. The Rockchip driver
appears to be correctly calling drm_atomic_helper_shutdown() so we can
remove the calls.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: "Heiko Stübner" 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 .../gpu/drm/panel/panel-xinpeng-xpp055c272.c| 17 -
 1 file changed, 17 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c 
b/drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c
index 8262c00670cf..22a14006765e 100644
--- a/drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c
+++ b/drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c
@@ -306,27 +306,11 @@ static int xpp055c272_probe(struct mipi_dsi_device *dsi)
return 0;
 }
 
-static void xpp055c272_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct xpp055c272 *ctx = mipi_dsi_get_drvdata(dsi);
-   int ret;
-
-   ret = drm_panel_unprepare(>panel);
-   if (ret < 0)
-   dev_err(>dev, "Failed to unprepare panel: %d\n", ret);
-
-   ret = drm_panel_disable(>panel);
-   if (ret < 0)
-   dev_err(>dev, "Failed to disable panel: %d\n", ret);
-}
-
 static void xpp055c272_remove(struct mipi_dsi_device *dsi)
 {
struct xpp055c272 *ctx = mipi_dsi_get_drvdata(dsi);
int ret;
 
-   xpp055c272_shutdown(dsi);
-
ret = mipi_dsi_detach(dsi);
if (ret < 0)
dev_err(>dev, "Failed to detach from DSI host: %d\n", ret);
@@ -347,7 +331,6 @@ static struct mipi_dsi_driver xpp055c272_driver = {
},
.probe  = xpp055c272_probe,
.remove = xpp055c272_remove,
-   .shutdown = xpp055c272_shutdown,
 };
 module_mipi_dsi_driver(xpp055c272_driver);
 
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 20/48] drm/panel: olimex-lcd-olinuxino: Stop tracking prepared/enabled

2024-05-03 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Cc: Stefan Mavrodiev 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 .../drm/panel/panel-olimex-lcd-olinuxino.c| 41 ---
 1 file changed, 41 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c 
b/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c
index 4819ada69482..8a687d3ba236 100644
--- a/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c
+++ b/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c
@@ -64,9 +64,6 @@ struct lcd_olinuxino {
struct i2c_client *client;
struct mutex mutex;
 
-   bool prepared;
-   bool enabled;
-
struct regulator *supply;
struct gpio_desc *enable_gpio;
 
@@ -78,30 +75,13 @@ static inline struct lcd_olinuxino *to_lcd_olinuxino(struct 
drm_panel *panel)
return container_of(panel, struct lcd_olinuxino, panel);
 }
 
-static int lcd_olinuxino_disable(struct drm_panel *panel)
-{
-   struct lcd_olinuxino *lcd = to_lcd_olinuxino(panel);
-
-   if (!lcd->enabled)
-   return 0;
-
-   lcd->enabled = false;
-
-   return 0;
-}
-
 static int lcd_olinuxino_unprepare(struct drm_panel *panel)
 {
struct lcd_olinuxino *lcd = to_lcd_olinuxino(panel);
 
-   if (!lcd->prepared)
-   return 0;
-
gpiod_set_value_cansleep(lcd->enable_gpio, 0);
regulator_disable(lcd->supply);
 
-   lcd->prepared = false;
-
return 0;
 }
 
@@ -110,27 +90,11 @@ static int lcd_olinuxino_prepare(struct drm_panel *panel)
struct lcd_olinuxino *lcd = to_lcd_olinuxino(panel);
int ret;
 
-   if (lcd->prepared)
-   return 0;
-
ret = regulator_enable(lcd->supply);
if (ret < 0)
return ret;
 
gpiod_set_value_cansleep(lcd->enable_gpio, 1);
-   lcd->prepared = true;
-
-   return 0;
-}
-
-static int lcd_olinuxino_enable(struct drm_panel *panel)
-{
-   struct lcd_olinuxino *lcd = to_lcd_olinuxino(panel);
-
-   if (lcd->enabled)
-   return 0;
-
-   lcd->enabled = true;
 
return 0;
 }
@@ -195,10 +159,8 @@ static int lcd_olinuxino_get_modes(struct drm_panel *panel,
 }
 
 static const struct drm_panel_funcs lcd_olinuxino_funcs = {
-   .disable = lcd_olinuxino_disable,
.unprepare = lcd_olinuxino_unprepare,
.prepare = lcd_olinuxino_prepare,
-   .enable = lcd_olinuxino_enable,
.get_modes = lcd_olinuxino_get_modes,
 };
 
@@ -264,9 +226,6 @@ static int lcd_olinuxino_probe(struct i2c_client *client)
lcd->eeprom.num_modes = 4;
}
 
-   lcd->enabled = false;
-   lcd->prepared = false;
-
lcd->supply = devm_regulator_get(dev, "power");
if (IS_ERR(lcd->supply))
return PTR_ERR(lcd->supply);
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 29/48] drm/panel: tdo-tl070wsh30: Don't call unprepare+disable at shutdown/remove

2024-05-03 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

Unfortunately, grepping mainline for this panel's compatible string
shows no hits, so we can't be 100% sure if the DRM modeset driver used
with this panel has been fixed. If it is found that the DRM modeset
driver hasn't been fixed then this patch could be temporarily reverted
until it is.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Neil Armstrong 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c 
b/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c
index 36f27c664b69..227f97f9b136 100644
--- a/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c
+++ b/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c
@@ -208,16 +208,6 @@ static void tdo_tl070wsh30_panel_remove(struct 
mipi_dsi_device *dsi)
dev_err(>dev, "failed to detach from DSI host: %d\n", err);
 
drm_panel_remove(_tl070wsh30->base);
-   drm_panel_disable(_tl070wsh30->base);
-   drm_panel_unprepare(_tl070wsh30->base);
-}
-
-static void tdo_tl070wsh30_panel_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct tdo_tl070wsh30_panel *tdo_tl070wsh30 = mipi_dsi_get_drvdata(dsi);
-
-   drm_panel_disable(_tl070wsh30->base);
-   drm_panel_unprepare(_tl070wsh30->base);
 }
 
 static struct mipi_dsi_driver tdo_tl070wsh30_panel_driver = {
@@ -227,7 +217,6 @@ static struct mipi_dsi_driver tdo_tl070wsh30_panel_driver = 
{
},
.probe = tdo_tl070wsh30_panel_probe,
.remove = tdo_tl070wsh30_panel_remove,
-   .shutdown = tdo_tl070wsh30_panel_shutdown,
 };
 module_mipi_dsi_driver(tdo_tl070wsh30_panel_driver);
 
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 28/48] drm/panel: tdo-tl070wsh30: Stop tracking prepared

2024-05-03 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Cc: Neil Armstrong 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c 
b/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c
index d8487bc6d611..36f27c664b69 100644
--- a/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c
+++ b/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c
@@ -24,8 +24,6 @@ struct tdo_tl070wsh30_panel {
 
struct regulator *supply;
struct gpio_desc *reset_gpio;
-
-   bool prepared;
 };
 
 static inline
@@ -39,9 +37,6 @@ static int tdo_tl070wsh30_panel_prepare(struct drm_panel 
*panel)
struct tdo_tl070wsh30_panel *tdo_tl070wsh30 = 
to_tdo_tl070wsh30_panel(panel);
int err;
 
-   if (tdo_tl070wsh30->prepared)
-   return 0;
-
err = regulator_enable(tdo_tl070wsh30->supply);
if (err < 0)
return err;
@@ -74,8 +69,6 @@ static int tdo_tl070wsh30_panel_prepare(struct drm_panel 
*panel)
 
msleep(20);
 
-   tdo_tl070wsh30->prepared = true;
-
return 0;
 }
 
@@ -84,9 +77,6 @@ static int tdo_tl070wsh30_panel_unprepare(struct drm_panel 
*panel)
struct tdo_tl070wsh30_panel *tdo_tl070wsh30 = 
to_tdo_tl070wsh30_panel(panel);
int err;
 
-   if (!tdo_tl070wsh30->prepared)
-   return 0;
-
err = mipi_dsi_dcs_set_display_off(tdo_tl070wsh30->link);
if (err < 0)
dev_err(panel->dev, "failed to set display off: %d\n", err);
@@ -103,8 +93,6 @@ static int tdo_tl070wsh30_panel_unprepare(struct drm_panel 
*panel)
 
regulator_disable(tdo_tl070wsh30->supply);
 
-   tdo_tl070wsh30->prepared = false;
-
return 0;
 }
 
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 19/48] drm/panel: novatek-nt36672a: Don't call unprepare+disable at shutdown/remove

2024-05-03 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

A grep through mainline for compatible strings used by this driver
indicates that it is used by Qualcomm boards. The Qualcomm driver
appears to be correctly calling drm_atomic_helper_shutdown() so we can
remove the calls.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Sumit Semwal 
Cc: Benni Steini 
Cc: Joel Selvaraj 
Cc: Marijn Suijten 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-novatek-nt36672a.c | 17 -
 1 file changed, 17 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36672a.c 
b/drivers/gpu/drm/panel/panel-novatek-nt36672a.c
index 35aace79613a..c2abd20e0734 100644
--- a/drivers/gpu/drm/panel/panel-novatek-nt36672a.c
+++ b/drivers/gpu/drm/panel/panel-novatek-nt36672a.c
@@ -656,14 +656,6 @@ static void nt36672a_panel_remove(struct mipi_dsi_device 
*dsi)
struct nt36672a_panel *pinfo = mipi_dsi_get_drvdata(dsi);
int err;
 
-   err = drm_panel_unprepare(>base);
-   if (err < 0)
-   dev_err(>dev, "failed to unprepare panel: %d\n", err);
-
-   err = drm_panel_disable(>base);
-   if (err < 0)
-   dev_err(>dev, "failed to disable panel: %d\n", err);
-
err = mipi_dsi_detach(dsi);
if (err < 0)
dev_err(>dev, "failed to detach from DSI host: %d\n", err);
@@ -671,14 +663,6 @@ static void nt36672a_panel_remove(struct mipi_dsi_device 
*dsi)
drm_panel_remove(>base);
 }
 
-static void nt36672a_panel_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct nt36672a_panel *pinfo = mipi_dsi_get_drvdata(dsi);
-
-   drm_panel_disable(>base);
-   drm_panel_unprepare(>base);
-}
-
 static const struct of_device_id tianma_fhd_video_of_match[] = {
{ .compatible = "tianma,fhd-video", .data = 
_fhd_video_panel_desc },
{ },
@@ -692,7 +676,6 @@ static struct mipi_dsi_driver nt36672a_panel_driver = {
},
.probe = nt36672a_panel_probe,
.remove = nt36672a_panel_remove,
-   .shutdown = nt36672a_panel_shutdown,
 };
 module_mipi_dsi_driver(nt36672a_panel_driver);
 
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 26/48] drm/panel: simple: Stop tracking prepared/enabled

2024-05-03 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-simple.c | 27 ---
 1 file changed, 27 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-simple.c 
b/drivers/gpu/drm/panel/panel-simple.c
index dcb6d0b6ced0..42d902d2bbbe 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -138,9 +138,6 @@ struct panel_desc {
 
 struct panel_simple {
struct drm_panel base;
-   bool enabled;
-
-   bool prepared;
 
ktime_t unprepared_time;
 
@@ -290,14 +287,9 @@ static int panel_simple_disable(struct drm_panel *panel)
 {
struct panel_simple *p = to_panel_simple(panel);
 
-   if (!p->enabled)
-   return 0;
-
if (p->desc->delay.disable)
msleep(p->desc->delay.disable);
 
-   p->enabled = false;
-
return 0;
 }
 
@@ -317,18 +309,12 @@ static int panel_simple_suspend(struct device *dev)
 
 static int panel_simple_unprepare(struct drm_panel *panel)
 {
-   struct panel_simple *p = to_panel_simple(panel);
int ret;
 
-   /* Unpreparing when already unprepared is a no-op */
-   if (!p->prepared)
-   return 0;
-
pm_runtime_mark_last_busy(panel->dev);
ret = pm_runtime_put_autosuspend(panel->dev);
if (ret < 0)
return ret;
-   p->prepared = false;
 
return 0;
 }
@@ -356,21 +342,14 @@ static int panel_simple_resume(struct device *dev)
 
 static int panel_simple_prepare(struct drm_panel *panel)
 {
-   struct panel_simple *p = to_panel_simple(panel);
int ret;
 
-   /* Preparing when already prepared is a no-op */
-   if (p->prepared)
-   return 0;
-
ret = pm_runtime_get_sync(panel->dev);
if (ret < 0) {
pm_runtime_put_autosuspend(panel->dev);
return ret;
}
 
-   p->prepared = true;
-
return 0;
 }
 
@@ -378,14 +357,9 @@ static int panel_simple_enable(struct drm_panel *panel)
 {
struct panel_simple *p = to_panel_simple(panel);
 
-   if (p->enabled)
-   return 0;
-
if (p->desc->delay.enable)
msleep(p->desc->delay.enable);
 
-   p->enabled = true;
-
return 0;
 }
 
@@ -609,7 +583,6 @@ static int panel_simple_probe(struct device *dev, const 
struct panel_desc *desc)
if (!panel)
return -ENOMEM;
 
-   panel->enabled = false;
panel->desc = desc;
 
panel->supply = devm_regulator_get(dev, "power");
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 27/48] drm/panel: simple: Add a comment about unprepare+disable at shutdown/remove

2024-05-03 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

Unfortunately, it's very difficult to know exactly which DRM modeset
drivers are using panel-simple due to the sheer number of panels it
handles. For now, we'll leave the calls and just add a comment to keep
people from copying this code.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.
- panel-edp and panel-simple just get a comment now.

 drivers/gpu/drm/panel/panel-simple.c | 33 +++-
 1 file changed, 23 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-simple.c 
b/drivers/gpu/drm/panel/panel-simple.c
index 42d902d2bbbe..f39122ffdead 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -716,26 +716,39 @@ static int panel_simple_probe(struct device *dev, const 
struct panel_desc *desc)
return err;
 }
 
-static void panel_simple_remove(struct device *dev)
+static void panel_simple_shutdown(struct device *dev)
 {
struct panel_simple *panel = dev_get_drvdata(dev);
 
-   drm_panel_remove(>base);
+   /*
+* NOTE: the following two calls don't really belong here. It is the
+* responsibility of a correctly written DRM modeset driver to call
+* drm_atomic_helper_shutdown() at shutdown time and that should
+* cause the panel to be disabled / unprepared if needed. For now,
+* however, we'll keep these calls due to the sheer number of
+* different DRM modeset drivers used with panel-simple. The fact that
+* we're calling these and _also_ the drm_atomic_helper_shutdown()
+* will try to disable/unprepare means that we can get a warning about
+* trying to disable/unprepare an already disabled/unprepared panel,
+* but that's something we'll have to live with until we've confirmed
+* that all DRM modeset drivers are properly calling
+* drm_atomic_helper_shutdown().
+*/
drm_panel_disable(>base);
drm_panel_unprepare(>base);
-
-   pm_runtime_dont_use_autosuspend(dev);
-   pm_runtime_disable(dev);
-   if (panel->ddc)
-   put_device(>ddc->dev);
 }
 
-static void panel_simple_shutdown(struct device *dev)
+static void panel_simple_remove(struct device *dev)
 {
struct panel_simple *panel = dev_get_drvdata(dev);
 
-   drm_panel_disable(>base);
-   drm_panel_unprepare(>base);
+   drm_panel_remove(>base);
+   panel_simple_shutdown(dev);
+
+   pm_runtime_dont_use_autosuspend(dev);
+   pm_runtime_disable(dev);
+   if (panel->ddc)
+   put_device(>ddc->dev);
 }
 
 static const struct drm_display_mode ampire_am_1280800n3tzqw_t00h_mode = {
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 25/48] drm/panel: samsung-atna33xc20: Don't call unprepare+disable at shutdown/remove

2024-05-03 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

A grep through mainline for compatible strings used by this driver
indicates that it is used by Qualcomm boards. The Qualcomm driver
appears to be correctly calling drm_atomic_helper_shutdown() so we can
remove the calls.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-samsung-atna33xc20.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c 
b/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
index a322dd0a532f..9a482a744b8c 100644
--- a/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
+++ b/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
@@ -327,21 +327,10 @@ static void atana33xc20_remove(struct dp_aux_ep_device 
*aux_ep)
struct atana33xc20_panel *panel = dev_get_drvdata(dev);
 
drm_panel_remove(>base);
-   drm_panel_disable(>base);
-   drm_panel_unprepare(>base);
 
drm_edid_free(panel->drm_edid);
 }
 
-static void atana33xc20_shutdown(struct dp_aux_ep_device *aux_ep)
-{
-   struct device *dev = _ep->dev;
-   struct atana33xc20_panel *panel = dev_get_drvdata(dev);
-
-   drm_panel_disable(>base);
-   drm_panel_unprepare(>base);
-}
-
 static const struct of_device_id atana33xc20_dt_match[] = {
{ .compatible = "samsung,atna33xc20", },
{ /* sentinal */ }
@@ -362,7 +351,6 @@ static struct dp_aux_ep_driver atana33xc20_driver = {
},
.probe = atana33xc20_probe,
.remove = atana33xc20_remove,
-   .shutdown = atana33xc20_shutdown,
 };
 
 static int __init atana33xc20_init(void)
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 24/48] drm/panel: samsung-atna33xc20: Stop tracking prepared/enabled

2024-05-03 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 .../gpu/drm/panel/panel-samsung-atna33xc20.c  | 24 ---
 1 file changed, 24 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c 
b/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
index a9f0d214a900..a322dd0a532f 100644
--- a/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
+++ b/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
@@ -25,8 +25,6 @@
 
 struct atana33xc20_panel {
struct drm_panel base;
-   bool prepared;
-   bool enabled;
bool el3_was_on;
 
bool no_hpd;
@@ -143,13 +141,8 @@ static int atana33xc20_disable(struct drm_panel *panel)
 {
struct atana33xc20_panel *p = to_atana33xc20(panel);
 
-   /* Disabling when already disabled is a no-op */
-   if (!p->enabled)
-   return 0;
-
gpiod_set_value_cansleep(p->el_on3_gpio, 0);
p->el_on3_off_time = ktime_get_boottime();
-   p->enabled = false;
 
/*
 * Keep track of the fact that EL_ON3 was on but we haven't power
@@ -173,10 +166,6 @@ static int atana33xc20_enable(struct drm_panel *panel)
 {
struct atana33xc20_panel *p = to_atana33xc20(panel);
 
-   /* Enabling when already enabled is a no-op */
-   if (p->enabled)
-   return 0;
-
/*
 * Once EL_ON3 drops we absolutely need a power cycle before the next
 * enable or the backlight will never come on again. The code ensures
@@ -195,20 +184,14 @@ static int atana33xc20_enable(struct drm_panel *panel)
atana33xc20_wait(p->powered_on_time, 400);
 
gpiod_set_value_cansleep(p->el_on3_gpio, 1);
-   p->enabled = true;
 
return 0;
 }
 
 static int atana33xc20_unprepare(struct drm_panel *panel)
 {
-   struct atana33xc20_panel *p = to_atana33xc20(panel);
int ret;
 
-   /* Unpreparing when already unprepared is a no-op */
-   if (!p->prepared)
-   return 0;
-
/*
 * Purposely do a put_sync, don't use autosuspend. The panel's tcon
 * seems to sometimes crash when you stop giving it data and this is
@@ -220,26 +203,19 @@ static int atana33xc20_unprepare(struct drm_panel *panel)
ret = pm_runtime_put_sync_suspend(panel->dev);
if (ret < 0)
return ret;
-   p->prepared = false;
 
return 0;
 }
 
 static int atana33xc20_prepare(struct drm_panel *panel)
 {
-   struct atana33xc20_panel *p = to_atana33xc20(panel);
int ret;
 
-   /* Preparing when already prepared is a no-op */
-   if (p->prepared)
-   return 0;
-
ret = pm_runtime_get_sync(panel->dev);
if (ret < 0) {
pm_runtime_put_autosuspend(panel->dev);
return ret;
}
-   p->prepared = true;
 
return 0;
 }
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 23/48] drm/panel: osd-osd101t2587-53ts: Don't call unprepare+disable at shutdown/remove

2024-05-03 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

A grep through mainline for compatible strings used by this driver
indicates that it is used by TI OMAP boards. The OMAP driver appears
to be correctly calling drm_atomic_helper_shutdown() so we can remove
the calls.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Peter Ujfalusi 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c | 14 --
 1 file changed, 14 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c 
b/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c
index c0da7d9512e8..dbea84f51514 100644
--- a/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c
+++ b/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c
@@ -186,11 +186,6 @@ static void osd101t2587_panel_remove(struct 
mipi_dsi_device *dsi)
struct osd101t2587_panel *osd101t2587 = mipi_dsi_get_drvdata(dsi);
int ret;
 
-   ret = drm_panel_disable(>base);
-   if (ret < 0)
-   dev_warn(>dev, "failed to disable panel: %d\n", ret);
-
-   drm_panel_unprepare(>base);
drm_panel_remove(>base);
 
ret = mipi_dsi_detach(dsi);
@@ -198,14 +193,6 @@ static void osd101t2587_panel_remove(struct 
mipi_dsi_device *dsi)
dev_err(>dev, "failed to detach from DSI host: %d\n", ret);
 }
 
-static void osd101t2587_panel_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct osd101t2587_panel *osd101t2587 = mipi_dsi_get_drvdata(dsi);
-
-   drm_panel_disable(>base);
-   drm_panel_unprepare(>base);
-}
-
 static struct mipi_dsi_driver osd101t2587_panel_driver = {
.driver = {
.name = "panel-osd-osd101t2587-53ts",
@@ -213,7 +200,6 @@ static struct mipi_dsi_driver osd101t2587_panel_driver = {
},
.probe = osd101t2587_panel_probe,
.remove = osd101t2587_panel_remove,
-   .shutdown = osd101t2587_panel_shutdown,
 };
 module_mipi_dsi_driver(osd101t2587_panel_driver);
 
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 22/48] drm/panel: osd-osd101t2587-53ts: Stop tracking prepared/enabled

2024-05-03 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Cc: Peter Ujfalusi 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 .../drm/panel/panel-osd-osd101t2587-53ts.c| 27 +--
 1 file changed, 1 insertion(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c 
b/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c
index 493e0504f6f7..c0da7d9512e8 100644
--- a/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c
+++ b/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c
@@ -21,9 +21,6 @@ struct osd101t2587_panel {
 
struct regulator *supply;
 
-   bool prepared;
-   bool enabled;
-
const struct drm_display_mode *default_mode;
 };
 
@@ -37,13 +34,8 @@ static int osd101t2587_panel_disable(struct drm_panel *panel)
struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
int ret;
 
-   if (!osd101t2587->enabled)
-   return 0;
-
ret = mipi_dsi_shutdown_peripheral(osd101t2587->dsi);
 
-   osd101t2587->enabled = false;
-
return ret;
 }
 
@@ -51,11 +43,7 @@ static int osd101t2587_panel_unprepare(struct drm_panel 
*panel)
 {
struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
 
-   if (!osd101t2587->prepared)
-   return 0;
-
regulator_disable(osd101t2587->supply);
-   osd101t2587->prepared = false;
 
return 0;
 }
@@ -63,16 +51,8 @@ static int osd101t2587_panel_unprepare(struct drm_panel 
*panel)
 static int osd101t2587_panel_prepare(struct drm_panel *panel)
 {
struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
-   int ret;
 
-   if (osd101t2587->prepared)
-   return 0;
-
-   ret = regulator_enable(osd101t2587->supply);
-   if (!ret)
-   osd101t2587->prepared = true;
-
-   return ret;
+   return regulator_enable(osd101t2587->supply);
 }
 
 static int osd101t2587_panel_enable(struct drm_panel *panel)
@@ -80,15 +60,10 @@ static int osd101t2587_panel_enable(struct drm_panel *panel)
struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
int ret;
 
-   if (osd101t2587->enabled)
-   return 0;
-
ret = mipi_dsi_turn_on_peripheral(osd101t2587->dsi);
if (ret)
return ret;
 
-   osd101t2587->enabled = true;
-
return ret;
 }
 
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 21/48] drm/panel: olimex-lcd-olinuxino: Don't call unprepare+disable at remove

2024-05-03 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

Unfortunately, grepping mainline for this panel's compatible string
shows no hits, so we can't be 100% sure if the DRM modeset driver used
with this panel has been fixed. If it is found that the DRM modeset
driver hasn't been fixed then this patch could be temporarily reverted
until it is.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Stefan Mavrodiev 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c 
b/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c
index 8a687d3ba236..94ae8c8270b8 100644
--- a/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c
+++ b/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c
@@ -251,9 +251,6 @@ static void lcd_olinuxino_remove(struct i2c_client *client)
struct lcd_olinuxino *panel = i2c_get_clientdata(client);
 
drm_panel_remove(>panel);
-
-   drm_panel_disable(>panel);
-   drm_panel_unprepare(>panel);
 }
 
 static const struct of_device_id lcd_olinuxino_of_ids[] = {
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 18/48] drm/panel: novatek-nt36672a: Stop tracking prepared

2024-05-03 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Cc: Sumit Semwal 
Cc: Benni Steini 
Cc: Joel Selvaraj 
Cc: Marijn Suijten 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-novatek-nt36672a.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36672a.c 
b/drivers/gpu/drm/panel/panel-novatek-nt36672a.c
index 3886372415c2..35aace79613a 100644
--- a/drivers/gpu/drm/panel/panel-novatek-nt36672a.c
+++ b/drivers/gpu/drm/panel/panel-novatek-nt36672a.c
@@ -72,8 +72,6 @@ struct nt36672a_panel {
struct regulator_bulk_data 
supplies[ARRAY_SIZE(nt36672a_regulator_names)];
 
struct gpio_desc *reset_gpio;
-
-   bool prepared;
 };
 
 static inline struct nt36672a_panel *to_nt36672a_panel(struct drm_panel *panel)
@@ -119,9 +117,6 @@ static int nt36672a_panel_unprepare(struct drm_panel *panel)
struct nt36672a_panel *pinfo = to_nt36672a_panel(panel);
int ret;
 
-   if (!pinfo->prepared)
-   return 0;
-
/* send off cmds */
ret = nt36672a_send_cmds(panel, pinfo->desc->off_cmds,
 pinfo->desc->num_off_cmds);
@@ -147,8 +142,6 @@ static int nt36672a_panel_unprepare(struct drm_panel *panel)
if (ret < 0)
dev_err(panel->dev, "power_off failed ret = %d\n", ret);
 
-   pinfo->prepared = false;
-
return ret;
 }
 
@@ -179,9 +172,6 @@ static int nt36672a_panel_prepare(struct drm_panel *panel)
struct nt36672a_panel *pinfo = to_nt36672a_panel(panel);
int err;
 
-   if (pinfo->prepared)
-   return 0;
-
err = nt36672a_panel_power_on(pinfo);
if (err < 0)
goto poweroff;
@@ -221,8 +211,6 @@ static int nt36672a_panel_prepare(struct drm_panel *panel)
 
msleep(120);
 
-   pinfo->prepared = true;
-
return 0;
 
 poweroff:
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 17/48] drm/panel: ltk500hd1829: Don't call unprepare+disable at shutdown/remove

2024-05-03 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

Unfortunately, grepping mainline for this panel's compatible string
shows no hits, so we can't be 100% sure if the DRM modeset driver used
with this panel has been fixed. If it is found that the DRM modeset
driver hasn't been fixed then this patch could be temporarily reverted
until it is.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: "Heiko Stübner" 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 .../gpu/drm/panel/panel-leadtek-ltk500hd1829.c  | 17 -
 1 file changed, 17 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c 
b/drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c
index ef27cab08f1d..6b18cf00fd4a 100644
--- a/drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c
+++ b/drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c
@@ -662,27 +662,11 @@ static int ltk500hd1829_probe(struct mipi_dsi_device *dsi)
return 0;
 }
 
-static void ltk500hd1829_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct ltk500hd1829 *ctx = mipi_dsi_get_drvdata(dsi);
-   int ret;
-
-   ret = drm_panel_unprepare(>panel);
-   if (ret < 0)
-   dev_err(>dev, "Failed to unprepare panel: %d\n", ret);
-
-   ret = drm_panel_disable(>panel);
-   if (ret < 0)
-   dev_err(>dev, "Failed to disable panel: %d\n", ret);
-}
-
 static void ltk500hd1829_remove(struct mipi_dsi_device *dsi)
 {
struct ltk500hd1829 *ctx = mipi_dsi_get_drvdata(dsi);
int ret;
 
-   ltk500hd1829_shutdown(dsi);
-
ret = mipi_dsi_detach(dsi);
if (ret < 0)
dev_err(>dev, "failed to detach from DSI host: %d\n", ret);
@@ -710,7 +694,6 @@ static struct mipi_dsi_driver ltk500hd1829_driver = {
},
.probe = ltk500hd1829_probe,
.remove = ltk500hd1829_remove,
-   .shutdown = ltk500hd1829_shutdown,
 };
 module_mipi_dsi_driver(ltk500hd1829_driver);
 
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 16/48] drm/panel: ltk500hd1829: Stop tracking prepared

2024-05-03 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Cc: "Heiko Stübner" 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c 
b/drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c
index a4c9a5cb9811..ef27cab08f1d 100644
--- a/drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c
+++ b/drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c
@@ -40,7 +40,6 @@ struct ltk500hd1829 {
struct regulator *vcc;
struct regulator *iovcc;
const struct ltk500hd1829_desc *panel_desc;
-   bool prepared;
 };
 
 static const struct ltk500hd1829_cmd ltk101b4029w_init[] = {
@@ -492,9 +491,6 @@ static int ltk500hd1829_unprepare(struct drm_panel *panel)
struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
int ret;
 
-   if (!ctx->prepared)
-   return 0;
-
ret = mipi_dsi_dcs_set_display_off(dsi);
if (ret < 0)
dev_err(panel->dev, "failed to set display off: %d\n", ret);
@@ -510,8 +506,6 @@ static int ltk500hd1829_unprepare(struct drm_panel *panel)
regulator_disable(ctx->iovcc);
regulator_disable(ctx->vcc);
 
-   ctx->prepared = false;
-
return 0;
 }
 
@@ -522,9 +516,6 @@ static int ltk500hd1829_prepare(struct drm_panel *panel)
unsigned int i;
int ret;
 
-   if (ctx->prepared)
-   return 0;
-
ret = regulator_enable(ctx->vcc);
if (ret < 0) {
dev_err(ctx->dev, "Failed to enable vci supply: %d\n", ret);
@@ -568,8 +559,6 @@ static int ltk500hd1829_prepare(struct drm_panel *panel)
goto disable_iovcc;
}
 
-   ctx->prepared = true;
-
return 0;
 
 disable_iovcc:
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 15/48] drm/panel: ltk050h3146w: Don't call unprepare+disable at shutdown/remove

2024-05-03 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

Unfortunately, grepping mainline for this panel's compatible string
shows no hits, so we can't be 100% sure if the DRM modeset driver used
with this panel has been fixed. If it is found that the DRM modeset
driver hasn't been fixed then this patch could be temporarily reverted
until it is.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: "Heiko Stübner" 
Cc: Quentin Schulz 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 .../gpu/drm/panel/panel-leadtek-ltk050h3146w.c  | 17 -
 1 file changed, 17 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c 
b/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c
index 5894bf30524a..292aa26a456d 100644
--- a/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c
+++ b/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c
@@ -673,27 +673,11 @@ static int ltk050h3146w_probe(struct mipi_dsi_device *dsi)
return 0;
 }
 
-static void ltk050h3146w_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct ltk050h3146w *ctx = mipi_dsi_get_drvdata(dsi);
-   int ret;
-
-   ret = drm_panel_unprepare(>panel);
-   if (ret < 0)
-   dev_err(>dev, "Failed to unprepare panel: %d\n", ret);
-
-   ret = drm_panel_disable(>panel);
-   if (ret < 0)
-   dev_err(>dev, "Failed to disable panel: %d\n", ret);
-}
-
 static void ltk050h3146w_remove(struct mipi_dsi_device *dsi)
 {
struct ltk050h3146w *ctx = mipi_dsi_get_drvdata(dsi);
int ret;
 
-   ltk050h3146w_shutdown(dsi);
-
ret = mipi_dsi_detach(dsi);
if (ret < 0)
dev_err(>dev, "Failed to detach from DSI host: %d\n", ret);
@@ -725,7 +709,6 @@ static struct mipi_dsi_driver ltk050h3146w_driver = {
},
.probe  = ltk050h3146w_probe,
.remove = ltk050h3146w_remove,
-   .shutdown = ltk050h3146w_shutdown,
 };
 module_mipi_dsi_driver(ltk050h3146w_driver);
 
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 14/48] drm/panel: ltk050h3146w: Stop tracking prepared

2024-05-03 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Cc: "Heiko Stübner" 
Cc: Quentin Schulz 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c 
b/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c
index 1a26205701b5..5894bf30524a 100644
--- a/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c
+++ b/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c
@@ -36,7 +36,6 @@ struct ltk050h3146w {
struct regulator *vci;
struct regulator *iovcc;
const struct ltk050h3146w_desc *panel_desc;
-   bool prepared;
 };
 
 static const struct ltk050h3146w_cmd page1_cmds[] = {
@@ -521,9 +520,6 @@ static int ltk050h3146w_unprepare(struct drm_panel *panel)
struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
int ret;
 
-   if (!ctx->prepared)
-   return 0;
-
ret = mipi_dsi_dcs_set_display_off(dsi);
if (ret < 0) {
dev_err(ctx->dev, "failed to set display off: %d\n", ret);
@@ -539,8 +535,6 @@ static int ltk050h3146w_unprepare(struct drm_panel *panel)
regulator_disable(ctx->iovcc);
regulator_disable(ctx->vci);
 
-   ctx->prepared = false;
-
return 0;
 }
 
@@ -550,9 +544,6 @@ static int ltk050h3146w_prepare(struct drm_panel *panel)
struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
int ret;
 
-   if (ctx->prepared)
-   return 0;
-
dev_dbg(ctx->dev, "Resetting the panel\n");
ret = regulator_enable(ctx->vci);
if (ret < 0) {
@@ -593,8 +584,6 @@ static int ltk050h3146w_prepare(struct drm_panel *panel)
 
msleep(50);
 
-   ctx->prepared = true;
-
return 0;
 
 disable_iovcc:
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 13/48] drm/panel: kingdisplay-kd097d04: Don't call unprepare+disable at shutdown/remove

2024-05-03 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

A grep through mainline for compatible strings used by this driver
indicates that it is used by Rockchip boards. The Rockchip driver
appear to be correctly calling drm_atomic_helper_shutdown() so we can
remove the calls.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Brian Norris 
Cc: Chris Zhong 
Cc: Nickey Yang 
Cc: "Heiko Stübner" 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 .../gpu/drm/panel/panel-kingdisplay-kd097d04.c  | 17 -
 1 file changed, 17 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c 
b/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c
index 88d775e000d4..d6b912277196 100644
--- a/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c
+++ b/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c
@@ -389,14 +389,6 @@ static void kingdisplay_panel_remove(struct 
mipi_dsi_device *dsi)
struct kingdisplay_panel *kingdisplay = mipi_dsi_get_drvdata(dsi);
int err;
 
-   err = drm_panel_unprepare(>base);
-   if (err < 0)
-   dev_err(>dev, "failed to unprepare panel: %d\n", err);
-
-   err = drm_panel_disable(>base);
-   if (err < 0)
-   dev_err(>dev, "failed to disable panel: %d\n", err);
-
err = mipi_dsi_detach(dsi);
if (err < 0)
dev_err(>dev, "failed to detach from DSI host: %d\n", err);
@@ -404,14 +396,6 @@ static void kingdisplay_panel_remove(struct 
mipi_dsi_device *dsi)
kingdisplay_panel_del(kingdisplay);
 }
 
-static void kingdisplay_panel_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct kingdisplay_panel *kingdisplay = mipi_dsi_get_drvdata(dsi);
-
-   drm_panel_unprepare(>base);
-   drm_panel_disable(>base);
-}
-
 static struct mipi_dsi_driver kingdisplay_panel_driver = {
.driver = {
.name = "panel-kingdisplay-kd097d04",
@@ -419,7 +403,6 @@ static struct mipi_dsi_driver kingdisplay_panel_driver = {
},
.probe = kingdisplay_panel_probe,
.remove = kingdisplay_panel_remove,
-   .shutdown = kingdisplay_panel_shutdown,
 };
 module_mipi_dsi_driver(kingdisplay_panel_driver);
 
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 12/48] drm/panel: kingdisplay-kd097d04: Stop tracking prepared/enabled

2024-05-03 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Cc: Brian Norris 
Cc: Chris Zhong 
Cc: Nickey Yang 
Cc: "Heiko Stübner" 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 .../drm/panel/panel-kingdisplay-kd097d04.c| 31 ---
 1 file changed, 31 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c 
b/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c
index 17f8d80cf2b3..88d775e000d4 100644
--- a/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c
+++ b/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c
@@ -23,9 +23,6 @@ struct kingdisplay_panel {
 
struct regulator *supply;
struct gpio_desc *enable_gpio;
-
-   bool prepared;
-   bool enabled;
 };
 
 struct kingdisplay_panel_cmd {
@@ -185,15 +182,10 @@ static int kingdisplay_panel_disable(struct drm_panel 
*panel)
struct kingdisplay_panel *kingdisplay = to_kingdisplay_panel(panel);
int err;
 
-   if (!kingdisplay->enabled)
-   return 0;
-
err = mipi_dsi_dcs_set_display_off(kingdisplay->link);
if (err < 0)
dev_err(panel->dev, "failed to set display off: %d\n", err);
 
-   kingdisplay->enabled = false;
-
return 0;
 }
 
@@ -202,9 +194,6 @@ static int kingdisplay_panel_unprepare(struct drm_panel 
*panel)
struct kingdisplay_panel *kingdisplay = to_kingdisplay_panel(panel);
int err;
 
-   if (!kingdisplay->prepared)
-   return 0;
-
err = mipi_dsi_dcs_enter_sleep_mode(kingdisplay->link);
if (err < 0) {
dev_err(panel->dev, "failed to enter sleep mode: %d\n", err);
@@ -220,8 +209,6 @@ static int kingdisplay_panel_unprepare(struct drm_panel 
*panel)
if (err < 0)
return err;
 
-   kingdisplay->prepared = false;
-
return 0;
 }
 
@@ -231,9 +218,6 @@ static int kingdisplay_panel_prepare(struct drm_panel 
*panel)
int err, regulator_err;
unsigned int i;
 
-   if (kingdisplay->prepared)
-   return 0;
-
gpiod_set_value_cansleep(kingdisplay->enable_gpio, 0);
 
err = regulator_enable(kingdisplay->supply);
@@ -275,8 +259,6 @@ static int kingdisplay_panel_prepare(struct drm_panel 
*panel)
/* T7: 10ms */
usleep_range(1, 11000);
 
-   kingdisplay->prepared = true;
-
return 0;
 
 poweroff:
@@ -289,18 +271,6 @@ static int kingdisplay_panel_prepare(struct drm_panel 
*panel)
return err;
 }
 
-static int kingdisplay_panel_enable(struct drm_panel *panel)
-{
-   struct kingdisplay_panel *kingdisplay = to_kingdisplay_panel(panel);
-
-   if (kingdisplay->enabled)
-   return 0;
-
-   kingdisplay->enabled = true;
-
-   return 0;
-}
-
 static const struct drm_display_mode default_mode = {
.clock = 229000,
.hdisplay = 1536,
@@ -341,7 +311,6 @@ static const struct drm_panel_funcs kingdisplay_panel_funcs 
= {
.disable = kingdisplay_panel_disable,
.unprepare = kingdisplay_panel_unprepare,
.prepare = kingdisplay_panel_prepare,
-   .enable = kingdisplay_panel_enable,
.get_modes = kingdisplay_panel_get_modes,
 };
 
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 11/48] drm/panel: khadas-ts050: Don't call unprepare+disable at shutdown/remove

2024-05-03 Thread Douglas Anderson
It's the responsibility of a correctly written DRM modeset driver to
call drm_atomic_helper_shutdown() at shutdown time and that should be
disabling / unpreparing the panel if needed. Panel drivers shouldn't
be calling these functions themselves.

A recent effort was made to fix as many DRM modeset drivers as
possible [1] [2] [3] and most drivers are fixed now.

Unfortunately, grepping mainline for this panel's compatible string
shows no hits, so we can't be 100% sure if the DRM modeset driver used
with this panel has been fixed. If it is found that the DRM modeset
driver hasn't been fixed then this patch could be temporarily reverted
until it is.

[1] https://lore.kernel.org/r/20230901234015.566018-1-diand...@chromium.org
[2] https://lore.kernel.org/r/20230901234202.566951-1-diand...@chromium.org
[3] https://lore.kernel.org/r/20230921192749.1542462-1-diand...@chromium.org

Cc: Jacobe Zang 
Cc: Nicolas Belin 
Cc: Neil Armstrong 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-khadas-ts050.c | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-khadas-ts050.c 
b/drivers/gpu/drm/panel/panel-khadas-ts050.c
index e35762ebdbd1..14932cb3defc 100644
--- a/drivers/gpu/drm/panel/panel-khadas-ts050.c
+++ b/drivers/gpu/drm/panel/panel-khadas-ts050.c
@@ -880,16 +880,6 @@ static void khadas_ts050_panel_remove(struct 
mipi_dsi_device *dsi)
dev_err(>dev, "failed to detach from DSI host: %d\n", err);
 
drm_panel_remove(_ts050->base);
-   drm_panel_disable(_ts050->base);
-   drm_panel_unprepare(_ts050->base);
-}
-
-static void khadas_ts050_panel_shutdown(struct mipi_dsi_device *dsi)
-{
-   struct khadas_ts050_panel *khadas_ts050 = mipi_dsi_get_drvdata(dsi);
-
-   drm_panel_disable(_ts050->base);
-   drm_panel_unprepare(_ts050->base);
 }
 
 static struct mipi_dsi_driver khadas_ts050_panel_driver = {
@@ -899,7 +889,6 @@ static struct mipi_dsi_driver khadas_ts050_panel_driver = {
},
.probe = khadas_ts050_panel_probe,
.remove = khadas_ts050_panel_remove,
-   .shutdown = khadas_ts050_panel_shutdown,
 };
 module_mipi_dsi_driver(khadas_ts050_panel_driver);
 
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



[RFT PATCH v2 10/48] drm/panel: khadas-ts050: Stop tracking prepared/enabled

2024-05-03 Thread Douglas Anderson
As talked about in commit d2aacaf07395 ("drm/panel: Check for already
prepared/enabled in drm_panel"), we want to remove needless code from
panel drivers that was storing and double-checking the
prepared/enabled state. Even if someone was relying on the
double-check before, that double-check is now in the core and not
needed in individual drivers.

Cc: Jacobe Zang 
Cc: Nicolas Belin 
Cc: Neil Armstrong 
Signed-off-by: Douglas Anderson 
---

Changes in v2:
- Only handle 1 panel per patch.
- Split removal of prepared/enabled from handling of remove/shutdown.

 drivers/gpu/drm/panel/panel-khadas-ts050.c | 28 --
 1 file changed, 28 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-khadas-ts050.c 
b/drivers/gpu/drm/panel/panel-khadas-ts050.c
index c54be0cc3f08..e35762ebdbd1 100644
--- a/drivers/gpu/drm/panel/panel-khadas-ts050.c
+++ b/drivers/gpu/drm/panel/panel-khadas-ts050.c
@@ -26,9 +26,6 @@ struct khadas_ts050_panel {
struct gpio_desc *reset_gpio;
struct gpio_desc *enable_gpio;
struct khadas_ts050_panel_data *panel_data;
-
-   bool prepared;
-   bool enabled;
 };
 
 struct khadas_ts050_panel_cmd {
@@ -642,9 +639,6 @@ static int khadas_ts050_panel_prepare(struct drm_panel 
*panel)
unsigned int i;
int err;
 
-   if (khadas_ts050->prepared)
-   return 0;
-
gpiod_set_value_cansleep(khadas_ts050->enable_gpio, 0);
 
err = regulator_enable(khadas_ts050->supply);
@@ -708,8 +702,6 @@ static int khadas_ts050_panel_prepare(struct drm_panel 
*panel)
 
usleep_range(1, 11000);
 
-   khadas_ts050->prepared = true;
-
return 0;
 
 poweroff:
@@ -726,11 +718,6 @@ static int khadas_ts050_panel_unprepare(struct drm_panel 
*panel)
struct khadas_ts050_panel *khadas_ts050 = to_khadas_ts050_panel(panel);
int err;
 
-   if (!khadas_ts050->prepared)
-   return 0;
-
-   khadas_ts050->prepared = false;
-
err = mipi_dsi_dcs_enter_sleep_mode(khadas_ts050->link);
if (err < 0)
dev_err(panel->dev, "failed to enter sleep mode: %d\n", err);
@@ -747,31 +734,17 @@ static int khadas_ts050_panel_unprepare(struct drm_panel 
*panel)
return 0;
 }
 
-static int khadas_ts050_panel_enable(struct drm_panel *panel)
-{
-   struct khadas_ts050_panel *khadas_ts050 = to_khadas_ts050_panel(panel);
-
-   khadas_ts050->enabled = true;
-
-   return 0;
-}
-
 static int khadas_ts050_panel_disable(struct drm_panel *panel)
 {
struct khadas_ts050_panel *khadas_ts050 = to_khadas_ts050_panel(panel);
int err;
 
-   if (!khadas_ts050->enabled)
-   return 0;
-
err = mipi_dsi_dcs_set_display_off(khadas_ts050->link);
if (err < 0)
dev_err(panel->dev, "failed to set display off: %d\n", err);
 
usleep_range(1, 11000);
 
-   khadas_ts050->enabled = false;
-
return 0;
 }
 
@@ -815,7 +788,6 @@ static int khadas_ts050_panel_get_modes(struct drm_panel 
*panel,
 static const struct drm_panel_funcs khadas_ts050_panel_funcs = {
.prepare = khadas_ts050_panel_prepare,
.unprepare = khadas_ts050_panel_unprepare,
-   .enable = khadas_ts050_panel_enable,
.disable = khadas_ts050_panel_disable,
.get_modes = khadas_ts050_panel_get_modes,
 };
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog



  1   2   3   4   5   6   7   8   9   >