LKML Archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/7] drm/mipi-dsi: simplify MIPI DSI init/cleanup even more
@ 2024-05-11 23:00 Dmitry Baryshkov
  2024-05-11 23:00 ` [PATCH v2 1/7] drm/panel: lg-sw43408: add missing error handling Dmitry Baryshkov
                   ` (7 more replies)
  0 siblings, 8 replies; 11+ messages in thread
From: Dmitry Baryshkov @ 2024-05-11 23:00 UTC (permalink / raw
  To: Douglas Anderson, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Neil Armstrong,
	Jessica Zhang, Sam Ravnborg, Sumit Semwal, Caleb Connolly,
	Marijn Suijten, Vinod Koul
  Cc: Cong Yang, dri-devel, linux-kernel, Dmitry Baryshkov

Follow the example of mipi_dsi_generic_write_multi(),
mipi_dsi_dcs_write_buffer_multi(), mipi_dsi_generic_write_seq_multi()
and mipi_dsi_dcs_write_seq_multi(). Define _multi variants for several
other common MIPI DSI functions and use these functions in the panel
code.

This series also includes a fix for the LG SW43408. If the proposed
approach is declined, the fix will be submitted separately.

Depends:
- https://lore.kernel.org/dri-devel/20240508205222.2251854-1-dianders@chromium.org/
- https://lore.kernel.org/dri-devel/20240511021326.288728-1-yangcong5@huaqin.corp-partner.google.com/

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
Changes in v2:
- Rebased on top of Cong's series
- Fixed mipi_dsi_compression_mode_ext_multi() docs (Doug)
- Added do/while(0) wrapping to mipi_dsi_msleep() macro (Doug)
- Inlined boe_panel_enter_sleep_mode(), ili9882t_enter_sleep_mode()
  (Doug)
- Dropped error prints around nt36672e_on() and nt36672e_off() (Doug)
- Link to v1: https://lore.kernel.org/r/20240510-dsi-panels-upd-api-v1-0-317c78a0dcc8@linaro.org

---
Dmitry Baryshkov (7):
      drm/panel: lg-sw43408: add missing error handling
      drm/mipi-dsi: wrap more functions for streamline handling
      drm/panel: boe-tv101wum-nl6: use wrapped MIPI DCS functions
      drm/panel: ilitek-ili9882t: use wrapped MIPI DCS functions
      drm/panel: innolux-p079zca: use mipi_dsi_dcs_nop_multi()
      drm/panel: novatek-nt36672e: use wrapped MIPI DCS functions
      drm/panel: lg-sw43408: use new streamlined MIPI DSI API

 drivers/gpu/drm/drm_mipi_dsi.c                 | 210 +++++++++
 drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c |  81 +---
 drivers/gpu/drm/panel/panel-ilitek-ili9882t.c  |  48 +-
 drivers/gpu/drm/panel/panel-innolux-p079zca.c  |   9 +-
 drivers/gpu/drm/panel/panel-lg-sw43408.c       |  74 +--
 drivers/gpu/drm/panel/panel-novatek-nt36672e.c | 597 ++++++++++++-------------
 include/drm/drm_mipi_dsi.h                     |  21 +
 7 files changed, 583 insertions(+), 457 deletions(-)
---
base-commit: 7dd7a948b03724e4c63271bd96830059bc62a1ef
change-id: 20240510-dsi-panels-upd-api-479adb2b0e01

Best regards,
-- 
Dmitry Baryshkov <dmitry.baryshkov@linaro.org>


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

* [PATCH v2 1/7] drm/panel: lg-sw43408: add missing error handling
  2024-05-11 23:00 [PATCH v2 0/7] drm/mipi-dsi: simplify MIPI DSI init/cleanup even more Dmitry Baryshkov
@ 2024-05-11 23:00 ` Dmitry Baryshkov
  2024-05-11 23:00 ` [PATCH v2 2/7] drm/mipi-dsi: wrap more functions for streamline handling Dmitry Baryshkov
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Dmitry Baryshkov @ 2024-05-11 23:00 UTC (permalink / raw
  To: Douglas Anderson, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Neil Armstrong,
	Jessica Zhang, Sam Ravnborg, Sumit Semwal, Caleb Connolly,
	Marijn Suijten, Vinod Koul
  Cc: Cong Yang, dri-devel, linux-kernel, Dmitry Baryshkov

Add missing error handling for the mipi_dsi_ functions that actually
return error code instead of silently ignoring it.

Fixes: 069a6c0e94f9 ("drm: panel: Add LG sw43408 panel driver")
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/panel/panel-lg-sw43408.c | 33 ++++++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-lg-sw43408.c b/drivers/gpu/drm/panel/panel-lg-sw43408.c
index 2b3a73696dce..67a98ac508f8 100644
--- a/drivers/gpu/drm/panel/panel-lg-sw43408.c
+++ b/drivers/gpu/drm/panel/panel-lg-sw43408.c
@@ -62,16 +62,25 @@ static int sw43408_program(struct drm_panel *panel)
 {
 	struct sw43408_panel *ctx = to_panel_info(panel);
 	struct drm_dsc_picture_parameter_set pps;
+	int ret;
 
 	mipi_dsi_dcs_write_seq(ctx->link, MIPI_DCS_SET_GAMMA_CURVE, 0x02);
 
-	mipi_dsi_dcs_set_tear_on(ctx->link, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
+	ret = mipi_dsi_dcs_set_tear_on(ctx->link, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
+	if (ret < 0) {
+		dev_err(panel->dev, "Failed to set tearing: %d\n", ret);
+		return ret;
+	}
 
 	mipi_dsi_dcs_write_seq(ctx->link, 0x53, 0x0c, 0x30);
 	mipi_dsi_dcs_write_seq(ctx->link, 0x55, 0x00, 0x70, 0xdf, 0x00, 0x70, 0xdf);
 	mipi_dsi_dcs_write_seq(ctx->link, 0xf7, 0x01, 0x49, 0x0c);
 
-	mipi_dsi_dcs_exit_sleep_mode(ctx->link);
+	ret = mipi_dsi_dcs_exit_sleep_mode(ctx->link);
+	if (ret < 0) {
+		dev_err(panel->dev, "Failed to exit sleep mode: %d\n", ret);
+		return ret;
+	}
 
 	msleep(135);
 
@@ -97,14 +106,22 @@ static int sw43408_program(struct drm_panel *panel)
 	mipi_dsi_dcs_write_seq(ctx->link, 0x55, 0x04, 0x61, 0xdb, 0x04, 0x70, 0xdb);
 	mipi_dsi_dcs_write_seq(ctx->link, 0xb0, 0xca);
 
-	mipi_dsi_dcs_set_display_on(ctx->link);
+	ret = mipi_dsi_dcs_set_display_on(ctx->link);
+	if (ret < 0) {
+		dev_err(panel->dev, "Failed to set display on: %d\n", ret);
+		return ret;
+	}
 
 	msleep(50);
 
 	ctx->link->mode_flags &= ~MIPI_DSI_MODE_LPM;
 
 	drm_dsc_pps_payload_pack(&pps, ctx->link->dsc);
-	mipi_dsi_picture_parameter_set(ctx->link, &pps);
+	ret = mipi_dsi_picture_parameter_set(ctx->link, &pps);
+	if (ret < 0) {
+		dev_err(panel->dev, "Failed to set PPS: %d\n", ret);
+		return ret;
+	}
 
 	ctx->link->mode_flags |= MIPI_DSI_MODE_LPM;
 
@@ -113,8 +130,12 @@ static int sw43408_program(struct drm_panel *panel)
 	 * PPS 1 if pps_identifier is 0
 	 * PPS 2 if pps_identifier is 1
 	 */
-	mipi_dsi_compression_mode_ext(ctx->link, true,
-				      MIPI_DSI_COMPRESSION_DSC, 1);
+	ret = mipi_dsi_compression_mode_ext(ctx->link, true,
+					    MIPI_DSI_COMPRESSION_DSC, 1);
+	if (ret < 0) {
+		dev_err(panel->dev, "Failed to set compression mode: %d\n", ret);
+		return ret;
+	}
 
 	return 0;
 }

-- 
2.39.2


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

* [PATCH v2 2/7] drm/mipi-dsi: wrap more functions for streamline handling
  2024-05-11 23:00 [PATCH v2 0/7] drm/mipi-dsi: simplify MIPI DSI init/cleanup even more Dmitry Baryshkov
  2024-05-11 23:00 ` [PATCH v2 1/7] drm/panel: lg-sw43408: add missing error handling Dmitry Baryshkov
@ 2024-05-11 23:00 ` Dmitry Baryshkov
  2024-05-13 16:49   ` Doug Anderson
  2024-05-17 19:32   ` Neil Armstrong
  2024-05-11 23:00 ` [PATCH v2 3/7] drm/panel: boe-tv101wum-nl6: use wrapped MIPI DCS functions Dmitry Baryshkov
                   ` (5 subsequent siblings)
  7 siblings, 2 replies; 11+ messages in thread
From: Dmitry Baryshkov @ 2024-05-11 23:00 UTC (permalink / raw
  To: Douglas Anderson, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Neil Armstrong,
	Jessica Zhang, Sam Ravnborg, Sumit Semwal, Caleb Connolly,
	Marijn Suijten, Vinod Koul
  Cc: Cong Yang, dri-devel, linux-kernel, Dmitry Baryshkov

Follow the pattern of mipi_dsi_dcs_*_multi() and wrap several existing
MIPI DSI functions to use the context for processing. This simplifies
and streamlines driver code to use simpler code pattern.

Note, msleep function is also wrapped in this way as it is frequently
called inbetween other mipi_dsi_dcs_*() functions.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 210 +++++++++++++++++++++++++++++++++++++++++
 include/drm/drm_mipi_dsi.h     |  21 +++++
 2 files changed, 231 insertions(+)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index d2957cb692d3..8721edd06c06 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -1429,6 +1429,216 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
 }
 EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness_large);
 
+/**
+ * mipi_dsi_picture_parameter_set_multi() - transmit the DSC PPS to the peripheral
+ * @ctx: Context for multiple DSI transactions
+ * @pps: VESA DSC 1.1 Picture Parameter Set
+ *
+ * Like mipi_dsi_picture_parameter_set() but deals with errors in a way that
+ * makes it convenient to make several calls in a row.
+ */
+void mipi_dsi_picture_parameter_set_multi(struct mipi_dsi_multi_context *ctx,
+				   const struct drm_dsc_picture_parameter_set *pps)
+{
+	struct mipi_dsi_device *dsi = ctx->dsi;
+	struct device *dev = &dsi->dev;
+	ssize_t ret;
+
+	if (ctx->accum_err)
+		return;
+
+	ret = mipi_dsi_picture_parameter_set(dsi, pps);
+	if (ret < 0) {
+		ctx->accum_err = ret;
+		dev_err(dev, "sending PPS failed: %d\n",
+			ctx->accum_err);
+	}
+}
+EXPORT_SYMBOL(mipi_dsi_picture_parameter_set_multi);
+
+/**
+ * mipi_dsi_compression_mode_ext_multi() - enable/disable DSC on the peripheral
+ * @ctx: Context for multiple DSI transactions
+ * @enable: Whether to enable or disable the DSC
+ * @algo: Selected compression algorithm
+ * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS entries
+ *
+ * Like mipi_dsi_compression_mode_ext() but deals with errors in a way that
+ * makes it convenient to make several calls in a row.
+ */
+void mipi_dsi_compression_mode_ext_multi(struct mipi_dsi_multi_context *ctx,
+					 bool enable,
+					 enum mipi_dsi_compression_algo algo,
+					 unsigned int pps_selector)
+{
+	struct mipi_dsi_device *dsi = ctx->dsi;
+	struct device *dev = &dsi->dev;
+	ssize_t ret;
+
+	if (ctx->accum_err)
+		return;
+
+	ret = mipi_dsi_compression_mode_ext(dsi, enable, algo, pps_selector);
+	if (ret < 0) {
+		ctx->accum_err = ret;
+		dev_err(dev, "sending COMPRESSION_MODE failed: %d\n",
+			ctx->accum_err);
+	}
+}
+EXPORT_SYMBOL(mipi_dsi_compression_mode_ext_multi);
+
+/**
+ * mipi_dsi_dcs_nop_multi() - send DCS NOP packet
+ * @ctx: Context for multiple DSI transactions
+ *
+ * Like mipi_dsi_dcs_nop() but deals with errors in a way that
+ * makes it convenient to make several calls in a row.
+ */
+void mipi_dsi_dcs_nop_multi(struct mipi_dsi_multi_context *ctx)
+{
+	struct mipi_dsi_device *dsi = ctx->dsi;
+	struct device *dev = &dsi->dev;
+	ssize_t ret;
+
+	if (ctx->accum_err)
+		return;
+
+	ret = mipi_dsi_dcs_nop(dsi);
+	if (ret < 0) {
+		ctx->accum_err = ret;
+		dev_err(dev, "sending DCS NOP failed: %d\n",
+			ctx->accum_err);
+	}
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_nop_multi);
+
+/**
+ * mipi_dsi_dcs_enter_sleep_mode_multi() - send DCS ENTER_SLEEP_MODE  packet
+ * @ctx: Context for multiple DSI transactions
+ *
+ * Like mipi_dsi_dcs_enter_sleep_mode() but deals with errors in a way that
+ * makes it convenient to make several calls in a row.
+ */
+void mipi_dsi_dcs_enter_sleep_mode_multi(struct mipi_dsi_multi_context *ctx)
+{
+	struct mipi_dsi_device *dsi = ctx->dsi;
+	struct device *dev = &dsi->dev;
+	ssize_t ret;
+
+	if (ctx->accum_err)
+		return;
+
+	ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
+	if (ret < 0) {
+		ctx->accum_err = ret;
+		dev_err(dev, "sending DCS ENTER_SLEEP_MODE failed: %d\n",
+			ctx->accum_err);
+	}
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode_multi);
+
+/**
+ * mipi_dsi_dcs_exit_sleep_mode_multi() - send DCS EXIT_SLEEP_MODE packet
+ * @ctx: Context for multiple DSI transactions
+ *
+ * Like mipi_dsi_dcs_exit_sleep_mode() but deals with errors in a way that
+ * makes it convenient to make several calls in a row.
+ */
+void mipi_dsi_dcs_exit_sleep_mode_multi(struct mipi_dsi_multi_context *ctx)
+{
+	struct mipi_dsi_device *dsi = ctx->dsi;
+	struct device *dev = &dsi->dev;
+	ssize_t ret;
+
+	if (ctx->accum_err)
+		return;
+
+	ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
+	if (ret < 0) {
+		ctx->accum_err = ret;
+		dev_err(dev, "sending DCS EXIT_SLEEP_MODE failed: %d\n",
+			ctx->accum_err);
+	}
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode_multi);
+
+/**
+ * mipi_dsi_dcs_set_display_off_multi() - send DCS SET_DISPLAY_OFF packet
+ * @ctx: Context for multiple DSI transactions
+ *
+ * Like mipi_dsi_dcs_set_display_off() but deals with errors in a way that
+ * makes it convenient to make several calls in a row.
+ */
+void mipi_dsi_dcs_set_display_off_multi(struct mipi_dsi_multi_context *ctx)
+{
+	struct mipi_dsi_device *dsi = ctx->dsi;
+	struct device *dev = &dsi->dev;
+	ssize_t ret;
+
+	if (ctx->accum_err)
+		return;
+
+	ret = mipi_dsi_dcs_set_display_off(dsi);
+	if (ret < 0) {
+		ctx->accum_err = ret;
+		dev_err(dev, "sending DCS SET_DISPLAY_OFF failed: %d\n",
+			ctx->accum_err);
+	}
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off_multi);
+
+/**
+ * mipi_dsi_dcs_set_display_on_multi() - send DCS SET_DISPLAY_ON packet
+ * @ctx: Context for multiple DSI transactions
+ *
+ * Like mipi_dsi_dcs_set_display_on() but deals with errors in a way that
+ * makes it convenient to make several calls in a row.
+ */
+void mipi_dsi_dcs_set_display_on_multi(struct mipi_dsi_multi_context *ctx)
+{
+	struct mipi_dsi_device *dsi = ctx->dsi;
+	struct device *dev = &dsi->dev;
+	ssize_t ret;
+
+	if (ctx->accum_err)
+		return;
+
+	ret = mipi_dsi_dcs_set_display_on(dsi);
+	if (ret < 0) {
+		ctx->accum_err = ret;
+		dev_err(dev, "sending DCS SET_DISPLAY_ON failed: %d\n",
+			ctx->accum_err);
+	}
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on_multi);
+
+/**
+ * mipi_dsi_dcs_set_tear_on_multi() - send DCS SET_TEAR_ON packet
+ * @ctx: Context for multiple DSI transactions
+ * @mode: the Tearing Effect Output Line mode
+ *
+ * Like mipi_dsi_dcs_set_tear_on() but deals with errors in a way that
+ * makes it convenient to make several calls in a row.
+ */
+void mipi_dsi_dcs_set_tear_on_multi(struct mipi_dsi_multi_context *ctx,
+				    enum mipi_dsi_dcs_tear_mode mode)
+{
+	struct mipi_dsi_device *dsi = ctx->dsi;
+	struct device *dev = &dsi->dev;
+	ssize_t ret;
+
+	if (ctx->accum_err)
+		return;
+
+	ret = mipi_dsi_dcs_set_tear_on(dsi, mode);
+	if (ret < 0) {
+		ctx->accum_err = ret;
+		dev_err(dev, "sending DCS SET_TEAR_ON failed: %d\n",
+			ctx->accum_err);
+	}
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on_multi);
+
 static int mipi_dsi_drv_probe(struct device *dev)
 {
 	struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 5e9cad541bd6..bd5a0b6d0711 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -275,6 +275,13 @@ int mipi_dsi_compression_mode_ext(struct mipi_dsi_device *dsi, bool enable,
 int mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi,
 				   const struct drm_dsc_picture_parameter_set *pps);
 
+void mipi_dsi_compression_mode_ext_multi(struct mipi_dsi_multi_context *ctx,
+					 bool enable,
+					 enum mipi_dsi_compression_algo algo,
+					 unsigned int pps_selector);
+void mipi_dsi_picture_parameter_set_multi(struct mipi_dsi_multi_context *ctx,
+					  const struct drm_dsc_picture_parameter_set *pps);
+
 ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
 			       size_t size);
 int mipi_dsi_generic_write_chatty(struct mipi_dsi_device *dsi,
@@ -284,6 +291,12 @@ void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx,
 ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
 			      size_t num_params, void *data, size_t size);
 
+#define mipi_dsi_msleep(ctx, delay)	\
+	do {				\
+		if (!ctx.accum_err)	\
+			msleep(delay);	\
+	} while (0)
+
 /**
  * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode
  * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking
@@ -338,6 +351,14 @@ int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi,
 int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
 					     u16 *brightness);
 
+void mipi_dsi_dcs_nop_multi(struct mipi_dsi_multi_context *ctx);
+void mipi_dsi_dcs_enter_sleep_mode_multi(struct mipi_dsi_multi_context *ctx);
+void mipi_dsi_dcs_exit_sleep_mode_multi(struct mipi_dsi_multi_context *ctx);
+void mipi_dsi_dcs_set_display_off_multi(struct mipi_dsi_multi_context *ctx);
+void mipi_dsi_dcs_set_display_on_multi(struct mipi_dsi_multi_context *ctx);
+void mipi_dsi_dcs_set_tear_on_multi(struct mipi_dsi_multi_context *ctx,
+				    enum mipi_dsi_dcs_tear_mode mode);
+
 /**
  * mipi_dsi_generic_write_seq - transmit data using a generic write packet
  *

-- 
2.39.2


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

* [PATCH v2 3/7] drm/panel: boe-tv101wum-nl6: use wrapped MIPI DCS functions
  2024-05-11 23:00 [PATCH v2 0/7] drm/mipi-dsi: simplify MIPI DSI init/cleanup even more Dmitry Baryshkov
  2024-05-11 23:00 ` [PATCH v2 1/7] drm/panel: lg-sw43408: add missing error handling Dmitry Baryshkov
  2024-05-11 23:00 ` [PATCH v2 2/7] drm/mipi-dsi: wrap more functions for streamline handling Dmitry Baryshkov
@ 2024-05-11 23:00 ` Dmitry Baryshkov
  2024-05-11 23:00 ` [PATCH v2 4/7] drm/panel: ilitek-ili9882t: " Dmitry Baryshkov
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Dmitry Baryshkov @ 2024-05-11 23:00 UTC (permalink / raw
  To: Douglas Anderson, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Neil Armstrong,
	Jessica Zhang, Sam Ravnborg, Sumit Semwal, Caleb Connolly,
	Marijn Suijten, Vinod Koul
  Cc: Cong Yang, dri-devel, linux-kernel, Dmitry Baryshkov

Remove conditional code and always use mipi_dsi_dcs_*multi() wrappers to
simplify driver's init/exit code.

Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c | 81 ++++++--------------------
 1 file changed, 19 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
index 4b4b125a6c6b..8e839a1749e4 100644
--- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
+++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
@@ -448,22 +448,16 @@ static int boe_tv110c9m_init(struct boe_panel *boe)
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x55, 0x00);
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0x13);
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3b, 0x03, 0x96, 0x1a, 0x04, 0x04);
-	if (ctx.accum_err)
-		return ctx.accum_err;
 
-	msleep(100);
+	mipi_dsi_msleep(&ctx, 100);
 
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x11);
-	if (ctx.accum_err)
-		return ctx.accum_err;
 
-	msleep(200);
+	mipi_dsi_msleep(&ctx, 200);
 
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x29);
-	if (ctx.accum_err)
-		return ctx.accum_err;
 
-	msleep(100);
+	mipi_dsi_msleep(&ctx, 100);
 
 	return 0;
 };
@@ -893,22 +887,16 @@ static int inx_hj110iz_init(struct boe_panel *boe)
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x01);
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x00);
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3b, 0x03, 0xae, 0x1a, 0x04, 0x04);
-	if (ctx.accum_err)
-		return ctx.accum_err;
 
-	msleep(100);
+	mipi_dsi_msleep(&ctx, 100);
 
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x11);
-	if (ctx.accum_err)
-		return ctx.accum_err;
 
-	msleep(200);
+	mipi_dsi_msleep(&ctx, 200);
 
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x29);
-	if (ctx.accum_err)
-		return ctx.accum_err;
 
-	msleep(100);
+	mipi_dsi_msleep(&ctx, 100);
 
 	return 0;
 };
@@ -1207,10 +1195,8 @@ static int boe_init(struct boe_panel *boe)
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x08);
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x04);
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x68);
-	if (ctx.accum_err)
-		return ctx.accum_err;
 
-	msleep(150);
+	mipi_dsi_msleep(&ctx, 150);
 
 	return 0;
 };
@@ -1222,16 +1208,12 @@ static int auo_kd101n80_45na_init(struct boe_panel *boe)
 	msleep(24);
 
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x11);
-	if (ctx.accum_err)
-		return ctx.accum_err;
 
-	msleep(120);
+	mipi_dsi_msleep(&ctx, 120);
 
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x29);
-	if (ctx.accum_err)
-		return ctx.accum_err;
 
-	msleep(120);
+	mipi_dsi_msleep(&ctx, 120);
 
 	return 0;
 };
@@ -1283,10 +1265,8 @@ static int auo_b101uan08_3_init(struct boe_panel *boe)
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5, 0x4f);
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe6, 0x41);
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe7, 0x41);
-	if (ctx.accum_err)
-		return ctx.accum_err;
 
-	msleep(150);
+	mipi_dsi_msleep(&ctx, 150);
 
 	return 0;
 };
@@ -1385,16 +1365,12 @@ static int starry_qfh032011_53g_init(struct boe_panel *boe)
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe1, 0x23);
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe2, 0x07);
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0X11);
-	if (ctx.accum_err)
-		return ctx.accum_err;
 
-	msleep(120);
+	mipi_dsi_msleep(&ctx, 120);
 
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0X29);
-	if (ctx.accum_err)
-		return ctx.accum_err;
 
-	msleep(80);
+	mipi_dsi_msleep(&ctx, 80);
 
 	return 0;
 };
@@ -1404,38 +1380,19 @@ static inline struct boe_panel *to_boe_panel(struct drm_panel *panel)
 	return container_of(panel, struct boe_panel, base);
 }
 
-static int boe_panel_enter_sleep_mode(struct boe_panel *boe)
-{
-	struct mipi_dsi_device *dsi = boe->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 boe_panel_disable(struct drm_panel *panel)
 {
 	struct boe_panel *boe = to_boe_panel(panel);
-	int ret;
+	struct mipi_dsi_multi_context ctx = { .dsi = boe->dsi };
 
-	ret = boe_panel_enter_sleep_mode(boe);
-	if (ret < 0) {
-		dev_err(panel->dev, "failed to set panel off: %d\n", ret);
-		return ret;
-	}
+	boe->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 ctx.accum_err;
 }
 
 static int boe_panel_unprepare(struct drm_panel *panel)

-- 
2.39.2


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

* [PATCH v2 4/7] drm/panel: ilitek-ili9882t: use wrapped MIPI DCS functions
  2024-05-11 23:00 [PATCH v2 0/7] drm/mipi-dsi: simplify MIPI DSI init/cleanup even more Dmitry Baryshkov
                   ` (2 preceding siblings ...)
  2024-05-11 23:00 ` [PATCH v2 3/7] drm/panel: boe-tv101wum-nl6: use wrapped MIPI DCS functions Dmitry Baryshkov
@ 2024-05-11 23:00 ` Dmitry Baryshkov
  2024-05-11 23:00 ` [PATCH v2 5/7] drm/panel: innolux-p079zca: use mipi_dsi_dcs_nop_multi() Dmitry Baryshkov
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Dmitry Baryshkov @ 2024-05-11 23:00 UTC (permalink / raw
  To: Douglas Anderson, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Neil Armstrong,
	Jessica Zhang, Sam Ravnborg, Sumit Semwal, Caleb Connolly,
	Marijn Suijten, Vinod Koul
  Cc: Cong Yang, dri-devel, linux-kernel, Dmitry Baryshkov

Remove conditional code and always use mipi_dsi_dcs_*multi() wrappers to
simplify driver's init/exit code.

Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/panel/panel-ilitek-ili9882t.c | 48 ++++++---------------------
 1 file changed, 11 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
index 58fc1d799371..830d7cfbe857 100644
--- a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
@@ -402,19 +402,15 @@ static int starry_ili9882t_init(struct ili9882t *ili)
 	mipi_dsi_dcs_write_seq_multi(&ctx, 0x92, 0x22);
 
 	ili9882t_switch_page(&ctx, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, MIPI_DCS_EXIT_SLEEP_MODE);
-	if (ctx.accum_err)
-		return ctx.accum_err;
+	mipi_dsi_dcs_exit_sleep_mode_multi(&ctx);
 
-	msleep(120);
+	mipi_dsi_msleep(&ctx, 120);
 
-	mipi_dsi_dcs_write_seq_multi(&ctx, MIPI_DCS_SET_DISPLAY_ON);
-	if (ctx.accum_err)
-		return ctx.accum_err;
+	mipi_dsi_dcs_set_display_on_multi(&ctx);
 
-	msleep(20);
+	mipi_dsi_msleep(&ctx, 20);
 
-	return 0;
+	return ctx.accum_err;
 };
 
 static inline struct ili9882t *to_ili9882t(struct drm_panel *panel)
@@ -422,43 +418,21 @@ static inline struct ili9882t *to_ili9882t(struct drm_panel *panel)
 	return container_of(panel, struct ili9882t, base);
 }
 
-static int ili9882t_enter_sleep_mode(struct ili9882t *ili)
-{
-	struct mipi_dsi_device *dsi = ili->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 ili9882t_disable(struct drm_panel *panel)
 {
 	struct ili9882t *ili = to_ili9882t(panel);
 	struct mipi_dsi_multi_context ctx = { .dsi = ili->dsi };
-	int ret;
 
 	ili9882t_switch_page(&ctx, 0x00);
-	if (ctx.accum_err)
-		return ctx.accum_err;
 
-	ret = ili9882t_enter_sleep_mode(ili);
-	if (ret < 0) {
-		dev_err(panel->dev, "failed to set panel off: %d\n", ret);
-		return ret;
-	}
+	ili->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 ctx.accum_err;
 }
 
 static int ili9882t_unprepare(struct drm_panel *panel)

-- 
2.39.2


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

* [PATCH v2 5/7] drm/panel: innolux-p079zca: use mipi_dsi_dcs_nop_multi()
  2024-05-11 23:00 [PATCH v2 0/7] drm/mipi-dsi: simplify MIPI DSI init/cleanup even more Dmitry Baryshkov
                   ` (3 preceding siblings ...)
  2024-05-11 23:00 ` [PATCH v2 4/7] drm/panel: ilitek-ili9882t: " Dmitry Baryshkov
@ 2024-05-11 23:00 ` Dmitry Baryshkov
  2024-05-11 23:00 ` [PATCH v2 6/7] drm/panel: novatek-nt36672e: use wrapped MIPI DCS functions Dmitry Baryshkov
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Dmitry Baryshkov @ 2024-05-11 23:00 UTC (permalink / raw
  To: Douglas Anderson, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Neil Armstrong,
	Jessica Zhang, Sam Ravnborg, Sumit Semwal, Caleb Connolly,
	Marijn Suijten, Vinod Koul
  Cc: Cong Yang, dri-devel, linux-kernel, Dmitry Baryshkov

Remove conditional code and use mipi_dsi_dcs_nop_multi() wrapper to
simplify driver code.

Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/panel/panel-innolux-p079zca.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-innolux-p079zca.c b/drivers/gpu/drm/panel/panel-innolux-p079zca.c
index ade8bf7491ee..0691a27a0daa 100644
--- a/drivers/gpu/drm/panel/panel-innolux-p079zca.c
+++ b/drivers/gpu/drm/panel/panel-innolux-p079zca.c
@@ -224,21 +224,14 @@ static const struct drm_display_mode innolux_p097pfg_mode = {
 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 = &dsi->dev;
-
 	mipi_dsi_generic_write_multi(ctx, payload, size);
-	if (ctx->accum_err)
-		return;
 
 	/*
 	 * Included by random guessing, because without this
 	 * (or at least, some delay), the panel sometimes
 	 * didn't appear to pick up the command sequence.
 	 */
-	ctx->accum_err = mipi_dsi_dcs_nop(ctx->dsi);
-	if (ctx->accum_err)
-		dev_err(dev, "failed to send DCS nop: %d\n", ctx->accum_err);
+	mipi_dsi_dcs_nop_multi(ctx);
 }
 
 #define innolux_panel_init_cmd_multi(ctx, seq...)                 \

-- 
2.39.2


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

* [PATCH v2 6/7] drm/panel: novatek-nt36672e: use wrapped MIPI DCS functions
  2024-05-11 23:00 [PATCH v2 0/7] drm/mipi-dsi: simplify MIPI DSI init/cleanup even more Dmitry Baryshkov
                   ` (4 preceding siblings ...)
  2024-05-11 23:00 ` [PATCH v2 5/7] drm/panel: innolux-p079zca: use mipi_dsi_dcs_nop_multi() Dmitry Baryshkov
@ 2024-05-11 23:00 ` Dmitry Baryshkov
  2024-05-11 23:00 ` [PATCH v2 7/7] drm/panel: lg-sw43408: use new streamlined MIPI DSI API Dmitry Baryshkov
  2024-05-17 19:39 ` [PATCH v2 0/7] drm/mipi-dsi: simplify MIPI DSI init/cleanup even more Neil Armstrong
  7 siblings, 0 replies; 11+ messages in thread
From: Dmitry Baryshkov @ 2024-05-11 23:00 UTC (permalink / raw
  To: Douglas Anderson, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Neil Armstrong,
	Jessica Zhang, Sam Ravnborg, Sumit Semwal, Caleb Connolly,
	Marijn Suijten, Vinod Koul
  Cc: Cong Yang, dri-devel, linux-kernel, Dmitry Baryshkov

Remove conditional code and always use mipi_dsi_dcs_*multi() wrappers to
simplify driver's init/exit code. This also includes passing context to
the init_sequence() function instead of passing the DSI device.

Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/panel/panel-novatek-nt36672e.c | 597 ++++++++++++-------------
 1 file changed, 284 insertions(+), 313 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36672e.c b/drivers/gpu/drm/panel/panel-novatek-nt36672e.c
index 9ce8df455232..e81a70147259 100644
--- a/drivers/gpu/drm/panel/panel-novatek-nt36672e.c
+++ b/drivers/gpu/drm/panel/panel-novatek-nt36672e.c
@@ -33,7 +33,7 @@ struct panel_desc {
 	enum mipi_dsi_pixel_format format;
 	unsigned int lanes;
 	const char *panel_name;
-	int (*init_sequence)(struct mipi_dsi_device *dsi);
+	void (*init_sequence)(struct mipi_dsi_multi_context *ctx);
 };
 
 struct nt36672e_panel {
@@ -49,297 +49,293 @@ static inline struct nt36672e_panel *to_nt36672e_panel(struct drm_panel *panel)
 	return container_of(panel, struct nt36672e_panel, panel);
 }
 
-static int nt36672e_1080x2408_60hz_init(struct mipi_dsi_device *dsi)
+static void nt36672e_1080x2408_60hz_init(struct mipi_dsi_multi_context *ctx)
 {
-	struct mipi_dsi_multi_context ctx = { .dsi = dsi };
-
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x10);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x89, 0x28, 0x00, 0x08, 0x00, 0xaa, 0x02,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0x10);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xb0, 0x00);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xc0, 0x00);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xc1, 0x89, 0x28, 0x00, 0x08, 0x00, 0xaa, 0x02,
 				     0x0e, 0x00, 0x2b, 0x00, 0x07, 0x0d, 0xb7, 0x0c, 0xb7);
 
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0x1b, 0xa0);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x20);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x01, 0x66);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0x40);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x38);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2f, 0x83);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x69, 0x91);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x95, 0xd1);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x96, 0xd1);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xf2, 0x64);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xf3, 0x54);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xf4, 0x64);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xf5, 0x54);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xf6, 0x64);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xf7, 0x54);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xf8, 0x64);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xf9, 0x54);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x24);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x01, 0x0f);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x03, 0x0c);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x05, 0x1d);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x2f);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x09, 0x2e);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0a, 0x2d);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0b, 0x2c);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x11, 0x17);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x12, 0x13);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x13, 0x15);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x15, 0x14);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x16, 0x16);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x17, 0x18);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1b, 0x01);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1d, 0x1d);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x2f);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x21, 0x2e);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x22, 0x2d);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x23, 0x2c);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x29, 0x17);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x13);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2b, 0x15);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2f, 0x14);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x30, 0x16);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x31, 0x18);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x32, 0x04);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x34, 0x10);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x1f);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x36, 0x1f);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4d, 0x14);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4e, 0x36);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4f, 0x36);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x53, 0x36);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x71, 0x30);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x79, 0x11);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7a, 0x82);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7b, 0x8f);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7d, 0x04);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x80, 0x04);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x81, 0x04);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x82, 0x13);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x84, 0x31);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x85, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x86, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x87, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x90, 0x13);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x92, 0x31);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x93, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x94, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x95, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x9c, 0xf4);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x9d, 0x01);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa0, 0x0f);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa2, 0x0f);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa3, 0x02);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa4, 0x04);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa5, 0x04);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0xc0);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd9, 0x80);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe9, 0x02);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x25);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x18, 0x22);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x19, 0xe4);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x21, 0x40);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x66, 0xd8);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x68, 0x50);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x69, 0x10);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6b, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6d, 0x0d);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6e, 0x48);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x72, 0x41);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x73, 0x4a);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x74, 0xd0);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x77, 0x62);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x79, 0x7e);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7d, 0x03);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7e, 0x15);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7f, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x84, 0x4d);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcf, 0x80);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd6, 0x80);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd7, 0x80);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xef, 0x20);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xf0, 0x84);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x26);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x81, 0x0f);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x83, 0x01);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x84, 0x03);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x85, 0x01);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x86, 0x03);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x87, 0x01);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x88, 0x05);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x8a, 0x1a);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x8b, 0x11);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x8c, 0x24);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x8e, 0x42);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x8f, 0x11);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x90, 0x11);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x91, 0x11);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x9a, 0x80);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x9b, 0x04);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x9c, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x9d, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x9e, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x27);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x01, 0x68);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x81);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x21, 0x6a);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x81);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0x94);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6e, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6f, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x70, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x71, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x72, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x75, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x76, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x77, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7d, 0x09);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7e, 0x67);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x80, 0x23);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x82, 0x09);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x83, 0x67);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x88, 0x01);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x89, 0x10);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa5, 0x10);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa6, 0x23);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa7, 0x01);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x40);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5, 0x02);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe6, 0xd3);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xeb, 0x03);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xec, 0x28);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x2a);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x91);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x03, 0x20);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x50);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0a, 0x70);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0c, 0x04);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0d, 0x40);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0f, 0x01);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x11, 0xe0);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x15, 0x0f);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x16, 0xa4);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x19, 0x0f);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1a, 0x78);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1b, 0x23);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1d, 0x36);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1e, 0x3e);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1f, 0x3e);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x3e);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x28, 0xfd);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x29, 0x12);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0xe1);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2d, 0x0a);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x30, 0x49);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x33, 0x96);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x34, 0xff);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x40);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x36, 0xde);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x37, 0xf9);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x38, 0x45);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x39, 0xd9);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x49);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4a, 0xf0);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7a, 0x09);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7b, 0x40);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7f, 0xf0);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x83, 0x0f);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x84, 0xa4);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x87, 0x0f);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x88, 0x78);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x89, 0x23);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x8b, 0x36);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x8c, 0x7d);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x8d, 0x7d);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x8e, 0x7d);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x20);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x00, 0x00, 0x00, 0x17, 0x00, 0x49, 0x00,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xc2, 0x1b, 0xa0);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0x20);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x01, 0x66);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x06, 0x40);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x07, 0x38);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x2f, 0x83);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x69, 0x91);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x95, 0xd1);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x96, 0xd1);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xf2, 0x64);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xf3, 0x54);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xf4, 0x64);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xf5, 0x54);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xf6, 0x64);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xf7, 0x54);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xf8, 0x64);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xf9, 0x54);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0x24);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x01, 0x0f);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x03, 0x0c);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x05, 0x1d);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x08, 0x2f);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x09, 0x2e);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x0a, 0x2d);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x0b, 0x2c);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x11, 0x17);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x12, 0x13);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x13, 0x15);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x15, 0x14);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x16, 0x16);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x17, 0x18);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x1b, 0x01);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x1d, 0x1d);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x20, 0x2f);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x21, 0x2e);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x22, 0x2d);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x23, 0x2c);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x29, 0x17);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x2a, 0x13);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x2b, 0x15);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x2f, 0x14);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x30, 0x16);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x31, 0x18);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x32, 0x04);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x34, 0x10);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x35, 0x1f);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x36, 0x1f);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x4d, 0x14);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x4e, 0x36);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x4f, 0x36);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x53, 0x36);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x71, 0x30);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x79, 0x11);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x7a, 0x82);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x7b, 0x8f);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x7d, 0x04);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x80, 0x04);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x81, 0x04);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x82, 0x13);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x84, 0x31);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x85, 0x00);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x86, 0x00);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x87, 0x00);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x90, 0x13);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x92, 0x31);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x93, 0x00);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x94, 0x00);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x95, 0x00);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x9c, 0xf4);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x9d, 0x01);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xa0, 0x0f);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xa2, 0x0f);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xa3, 0x02);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xa4, 0x04);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xa5, 0x04);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xc6, 0xc0);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xc9, 0x00);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xd9, 0x80);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xe9, 0x02);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0x25);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x18, 0x22);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x19, 0xe4);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x21, 0x40);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x66, 0xd8);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x68, 0x50);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x69, 0x10);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x6b, 0x00);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x6d, 0x0d);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x6e, 0x48);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x72, 0x41);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x73, 0x4a);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x74, 0xd0);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x77, 0x62);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x79, 0x7e);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x7d, 0x03);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x7e, 0x15);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x7f, 0x00);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x84, 0x4d);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xcf, 0x80);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xd6, 0x80);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xd7, 0x80);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xef, 0x20);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xf0, 0x84);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0x26);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x81, 0x0f);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x83, 0x01);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x84, 0x03);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x85, 0x01);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x86, 0x03);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x87, 0x01);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x88, 0x05);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x8a, 0x1a);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x8b, 0x11);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x8c, 0x24);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x8e, 0x42);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x8f, 0x11);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x90, 0x11);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x91, 0x11);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x9a, 0x80);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x9b, 0x04);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x9c, 0x00);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x9d, 0x00);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x9e, 0x00);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0x27);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x01, 0x68);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x20, 0x81);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x21, 0x6a);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x25, 0x81);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x26, 0x94);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x6e, 0x00);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x6f, 0x00);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x70, 0x00);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x71, 0x00);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x72, 0x00);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x75, 0x00);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x76, 0x00);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x77, 0x00);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x7d, 0x09);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x7e, 0x67);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x80, 0x23);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x82, 0x09);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x83, 0x67);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x88, 0x01);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x89, 0x10);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xa5, 0x10);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xa6, 0x23);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xa7, 0x01);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xb6, 0x40);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xe5, 0x02);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xe6, 0xd3);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xeb, 0x03);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xec, 0x28);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0x2a);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x00, 0x91);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x03, 0x20);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x07, 0x50);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x0a, 0x70);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x0c, 0x04);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x0d, 0x40);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x0f, 0x01);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x11, 0xe0);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x15, 0x0f);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x16, 0xa4);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x19, 0x0f);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x1a, 0x78);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x1b, 0x23);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x1d, 0x36);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x1e, 0x3e);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x1f, 0x3e);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x20, 0x3e);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x28, 0xfd);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x29, 0x12);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x2a, 0xe1);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x2d, 0x0a);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x30, 0x49);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x33, 0x96);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x34, 0xff);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x35, 0x40);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x36, 0xde);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x37, 0xf9);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x38, 0x45);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x39, 0xd9);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x3a, 0x49);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x4a, 0xf0);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x7a, 0x09);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x7b, 0x40);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x7f, 0xf0);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x83, 0x0f);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x84, 0xa4);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x87, 0x0f);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x88, 0x78);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x89, 0x23);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x8b, 0x36);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x8c, 0x7d);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x8d, 0x7d);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x8e, 0x7d);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0x20);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xb0, 0x00, 0x00, 0x00, 0x17, 0x00, 0x49, 0x00,
 				     0x6a, 0x00, 0x89, 0x00, 0x9f, 0x00, 0xb6, 0x00, 0xc8);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x00, 0xd9, 0x01, 0x10, 0x01, 0x3a, 0x01,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xb1, 0x00, 0xd9, 0x01, 0x10, 0x01, 0x3a, 0x01,
 				     0x7a, 0x01, 0xa9, 0x01, 0xf2, 0x02, 0x2d, 0x02, 0x2e);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x02, 0x64, 0x02, 0xa3, 0x02, 0xca, 0x03,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xb2, 0x02, 0x64, 0x02, 0xa3, 0x02, 0xca, 0x03,
 				     0x00, 0x03, 0x1e, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xb3, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
 				     0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xb4, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
 				     0x71, 0x00, 0x90, 0x00, 0xa7, 0x00, 0xbf, 0x00, 0xd1);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x00, 0xe2, 0x01, 0x1a, 0x01, 0x43, 0x01,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xb5, 0x00, 0xe2, 0x01, 0x1a, 0x01, 0x43, 0x01,
 				     0x83, 0x01, 0xb2, 0x01, 0xfa, 0x02, 0x34, 0x02, 0x36);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x02, 0x6b, 0x02, 0xa8, 0x02, 0xd0, 0x03,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xb6, 0x02, 0x6b, 0x02, 0xa8, 0x02, 0xd0, 0x03,
 				     0x03, 0x03, 0x21, 0x03, 0x4d, 0x03, 0x5b, 0x03, 0x6b);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x03, 0x7e, 0x03, 0x94, 0x03, 0xac, 0x03,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xb7, 0x03, 0x7e, 0x03, 0x94, 0x03, 0xac, 0x03,
 				     0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xb8, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
 				     0x72, 0x00, 0x92, 0x00, 0xa8, 0x00, 0xbf, 0x00, 0xd1);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0x00, 0xe2, 0x01, 0x18, 0x01, 0x42, 0x01,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xb9, 0x00, 0xe2, 0x01, 0x18, 0x01, 0x42, 0x01,
 				     0x81, 0x01, 0xaf, 0x01, 0xf5, 0x02, 0x2f, 0x02, 0x31);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x02, 0x68, 0x02, 0xa6, 0x02, 0xcd, 0x03,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xba, 0x02, 0x68, 0x02, 0xa6, 0x02, 0xcd, 0x03,
 				     0x01, 0x03, 0x1f, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xbb, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
 				     0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x21);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x00, 0x00, 0x00, 0x17, 0x00, 0x49, 0x00,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0x21);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xb0, 0x00, 0x00, 0x00, 0x17, 0x00, 0x49, 0x00,
 				     0x6a, 0x00, 0x89, 0x00, 0x9f, 0x00, 0xb6, 0x00, 0xc8);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x00, 0xd9, 0x01, 0x10, 0x01, 0x3a, 0x01,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xb1, 0x00, 0xd9, 0x01, 0x10, 0x01, 0x3a, 0x01,
 				     0x7a, 0x01, 0xa9, 0x01, 0xf2, 0x02, 0x2d, 0x02, 0x2e);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x02, 0x64, 0x02, 0xa3, 0x02, 0xca, 0x03,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xb2, 0x02, 0x64, 0x02, 0xa3, 0x02, 0xca, 0x03,
 				     0x00, 0x03, 0x1e, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xb3, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
 				     0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xb4, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
 				     0x71, 0x00, 0x90, 0x00, 0xa7, 0x00, 0xbf, 0x00, 0xd1);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x00, 0xe2, 0x01, 0x1a, 0x01, 0x43, 0x01,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xb5, 0x00, 0xe2, 0x01, 0x1a, 0x01, 0x43, 0x01,
 				     0x83, 0x01, 0xb2, 0x01, 0xfa, 0x02, 0x34, 0x02, 0x36);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x02, 0x6b, 0x02, 0xa8, 0x02, 0xd0, 0x03,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xb6, 0x02, 0x6b, 0x02, 0xa8, 0x02, 0xd0, 0x03,
 				     0x03, 0x03, 0x21, 0x03, 0x4d, 0x03, 0x5b, 0x03, 0x6b);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x03, 0x7e, 0x03, 0x94, 0x03, 0xac, 0x03,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xb7, 0x03, 0x7e, 0x03, 0x94, 0x03, 0xac, 0x03,
 				     0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xb8, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
 				     0x72, 0x00, 0x92, 0x00, 0xa8, 0x00, 0xbf, 0x00, 0xd1);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0x00, 0xe2, 0x01, 0x18, 0x01, 0x42, 0x01,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xb9, 0x00, 0xe2, 0x01, 0x18, 0x01, 0x42, 0x01,
 				     0x81, 0x01, 0xaf, 0x01, 0xf5, 0x02, 0x2f, 0x02, 0x31);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x02, 0x68, 0x02, 0xa6, 0x02, 0xcd, 0x03,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xba, 0x02, 0x68, 0x02, 0xa6, 0x02, 0xcd, 0x03,
 				     0x01, 0x03, 0x1f, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xbb, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
 				     0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x2c);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x61, 0x1f);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x62, 0x1f);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7e, 0x03);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6a, 0x14);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6b, 0x36);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6c, 0x36);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6d, 0x36);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x53, 0x04);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x54, 0x04);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x55, 0x04);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x56, 0x0f);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x58, 0x0f);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x59, 0x0f);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0xf0);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5a, 0x00);
-
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x10);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x51, 0xff);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x53, 0x24);
-	mipi_dsi_dcs_write_seq_multi(&ctx, 0x55, 0x01);
-
-	return ctx.accum_err;
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0x2c);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x61, 0x1f);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x62, 0x1f);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x7e, 0x03);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x6a, 0x14);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x6b, 0x36);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x6c, 0x36);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x6d, 0x36);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x53, 0x04);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x54, 0x04);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x55, 0x04);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x56, 0x0f);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x58, 0x0f);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x59, 0x0f);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0xf0);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x5a, 0x00);
+
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0x10);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x51, 0xff);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x53, 0x24);
+	mipi_dsi_dcs_write_seq_multi(ctx, 0x55, 0x01);
 }
 
 static int nt36672e_power_on(struct nt36672e_panel *ctx)
@@ -381,68 +377,46 @@ static int nt36672e_power_off(struct nt36672e_panel *ctx)
 	return ret;
 }
 
-static int nt36672e_on(struct nt36672e_panel *ctx)
+static int nt36672e_on(struct nt36672e_panel *nt36672e)
 {
-	struct mipi_dsi_device *dsi = ctx->dsi;
-	const struct panel_desc *desc = ctx->desc;
-	int ret = 0;
+	struct mipi_dsi_multi_context ctx = { .dsi = nt36672e->dsi };
+	const struct panel_desc *desc = nt36672e->desc;
 
-	dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+	nt36672e->dsi->mode_flags |= MIPI_DSI_MODE_LPM;
 
-	if (desc->init_sequence) {
-		ret = desc->init_sequence(dsi);
-		if (ret < 0) {
-			dev_err(&dsi->dev, "panel init sequence failed: %d\n", ret);
-			return ret;
-		}
-	}
+	if (desc->init_sequence)
+		desc->init_sequence(&ctx);
 
-	ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
-	if (ret < 0) {
-		dev_err(&dsi->dev, "Failed to exit sleep mode: %d\n", ret);
-		return ret;
-	}
-	msleep(120);
+	mipi_dsi_dcs_exit_sleep_mode_multi(&ctx);
+	mipi_dsi_msleep(&ctx, 120);
 
-	ret = mipi_dsi_dcs_set_display_on(dsi);
-	if (ret < 0) {
-		dev_err(&dsi->dev, "Failed to set display on: %d\n", ret);
-		return ret;
-	}
-	msleep(100);
+	mipi_dsi_dcs_set_display_on_multi(&ctx);
 
-	return 0;
+	mipi_dsi_msleep(&ctx, 100);
+
+	return ctx.accum_err;
 }
 
-static int nt36672e_off(struct nt36672e_panel *ctx)
+static int nt36672e_off(struct nt36672e_panel *panel)
 {
-	struct mipi_dsi_device *dsi = ctx->dsi;
-	int ret = 0;
+	struct mipi_dsi_multi_context ctx = { .dsi = panel->dsi };
 
-	dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
+	panel->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
 
-	ret = mipi_dsi_dcs_set_display_off(dsi);
-	if (ret < 0) {
-		dev_err(&dsi->dev, "Failed to set display off: %d\n", ret);
-		return ret;
-	}
-	msleep(20);
+	mipi_dsi_dcs_set_display_off_multi(&ctx);
+	mipi_dsi_msleep(&ctx, 20);
 
-	ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
-	if (ret < 0) {
-		dev_err(&dsi->dev, "Failed to enter sleep mode: %d\n", ret);
-		return ret;
-	}
-	msleep(60);
+	mipi_dsi_dcs_enter_sleep_mode_multi(&ctx);
+	mipi_dsi_msleep(&ctx, 60);
 
-	return 0;
+	return ctx.accum_err;
 }
 
 static int nt36672e_panel_prepare(struct drm_panel *panel)
 {
 	struct nt36672e_panel *ctx = to_nt36672e_panel(panel);
 	struct mipi_dsi_device *dsi = ctx->dsi;
-	int ret = 0;
+	int ret;
 
 	ret = nt36672e_power_on(ctx);
 	if (ret < 0)
@@ -450,7 +424,6 @@ static int nt36672e_panel_prepare(struct drm_panel *panel)
 
 	ret = nt36672e_on(ctx);
 	if (ret < 0) {
-		dev_err(&dsi->dev, "Failed to initialize panel: %d\n", ret);
 		if (nt36672e_power_off(ctx))
 			dev_err(&dsi->dev, "power off failed\n");
 		return ret;
@@ -463,11 +436,9 @@ static int nt36672e_panel_unprepare(struct drm_panel *panel)
 {
 	struct nt36672e_panel *ctx = to_nt36672e_panel(panel);
 	struct mipi_dsi_device *dsi = ctx->dsi;
-	int ret = 0;
+	int ret;
 
-	ret = nt36672e_off(ctx);
-	if (ret < 0)
-		dev_err(&dsi->dev, "Failed to un-initialize panel: %d\n", ret);
+	nt36672e_off(ctx);
 
 	ret = nt36672e_power_off(ctx);
 	if (ret < 0)

-- 
2.39.2


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

* [PATCH v2 7/7] drm/panel: lg-sw43408: use new streamlined MIPI DSI API
  2024-05-11 23:00 [PATCH v2 0/7] drm/mipi-dsi: simplify MIPI DSI init/cleanup even more Dmitry Baryshkov
                   ` (5 preceding siblings ...)
  2024-05-11 23:00 ` [PATCH v2 6/7] drm/panel: novatek-nt36672e: use wrapped MIPI DCS functions Dmitry Baryshkov
@ 2024-05-11 23:00 ` Dmitry Baryshkov
  2024-05-17 19:39 ` [PATCH v2 0/7] drm/mipi-dsi: simplify MIPI DSI init/cleanup even more Neil Armstrong
  7 siblings, 0 replies; 11+ messages in thread
From: Dmitry Baryshkov @ 2024-05-11 23:00 UTC (permalink / raw
  To: Douglas Anderson, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Neil Armstrong,
	Jessica Zhang, Sam Ravnborg, Sumit Semwal, Caleb Connolly,
	Marijn Suijten, Vinod Koul
  Cc: Cong Yang, dri-devel, linux-kernel, Dmitry Baryshkov

Use newer mipi_dsi_*_multi() functions in order to simplify and cleanup
panel's prepare() and unprepare() functions.

Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/panel/panel-lg-sw43408.c | 95 +++++++++++++-------------------
 1 file changed, 37 insertions(+), 58 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-lg-sw43408.c b/drivers/gpu/drm/panel/panel-lg-sw43408.c
index 67a98ac508f8..f3dcc39670ea 100644
--- a/drivers/gpu/drm/panel/panel-lg-sw43408.c
+++ b/drivers/gpu/drm/panel/panel-lg-sw43408.c
@@ -40,104 +40,83 @@ static inline struct sw43408_panel *to_panel_info(struct drm_panel *panel)
 
 static int sw43408_unprepare(struct drm_panel *panel)
 {
-	struct sw43408_panel *ctx = to_panel_info(panel);
+	struct sw43408_panel *sw43408 = to_panel_info(panel);
+	struct mipi_dsi_multi_context ctx = { .dsi = sw43408->link };
 	int ret;
 
-	ret = mipi_dsi_dcs_set_display_off(ctx->link);
-	if (ret < 0)
-		dev_err(panel->dev, "set_display_off cmd failed ret = %d\n", ret);
+	mipi_dsi_dcs_set_display_off_multi(&ctx);
 
-	ret = mipi_dsi_dcs_enter_sleep_mode(ctx->link);
-	if (ret < 0)
-		dev_err(panel->dev, "enter_sleep cmd failed ret = %d\n", ret);
+	mipi_dsi_dcs_enter_sleep_mode_multi(&ctx);
 
-	msleep(100);
+	mipi_dsi_msleep(&ctx, 100);
 
-	gpiod_set_value(ctx->reset_gpio, 1);
+	gpiod_set_value(sw43408->reset_gpio, 1);
+
+	ret = regulator_bulk_disable(ARRAY_SIZE(sw43408->supplies), sw43408->supplies);
 
-	return regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+	return ret ? : ctx.accum_err;
 }
 
 static int sw43408_program(struct drm_panel *panel)
 {
-	struct sw43408_panel *ctx = to_panel_info(panel);
+	struct sw43408_panel *sw43408 = to_panel_info(panel);
+	struct mipi_dsi_multi_context ctx = { .dsi = sw43408->link };
 	struct drm_dsc_picture_parameter_set pps;
-	int ret;
 
-	mipi_dsi_dcs_write_seq(ctx->link, MIPI_DCS_SET_GAMMA_CURVE, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, MIPI_DCS_SET_GAMMA_CURVE, 0x02);
 
-	ret = mipi_dsi_dcs_set_tear_on(ctx->link, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
-	if (ret < 0) {
-		dev_err(panel->dev, "Failed to set tearing: %d\n", ret);
-		return ret;
-	}
+	mipi_dsi_dcs_set_tear_on_multi(&ctx, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
 
-	mipi_dsi_dcs_write_seq(ctx->link, 0x53, 0x0c, 0x30);
-	mipi_dsi_dcs_write_seq(ctx->link, 0x55, 0x00, 0x70, 0xdf, 0x00, 0x70, 0xdf);
-	mipi_dsi_dcs_write_seq(ctx->link, 0xf7, 0x01, 0x49, 0x0c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x53, 0x0c, 0x30);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x55, 0x00, 0x70, 0xdf, 0x00, 0x70, 0xdf);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xf7, 0x01, 0x49, 0x0c);
 
-	ret = mipi_dsi_dcs_exit_sleep_mode(ctx->link);
-	if (ret < 0) {
-		dev_err(panel->dev, "Failed to exit sleep mode: %d\n", ret);
-		return ret;
-	}
+	mipi_dsi_dcs_exit_sleep_mode_multi(&ctx);
 
-	msleep(135);
+	mipi_dsi_msleep(&ctx, 135);
 
 	/* COMPRESSION_MODE moved after setting the PPS */
 
-	mipi_dsi_dcs_write_seq(ctx->link, 0xb0, 0xac);
-	mipi_dsi_dcs_write_seq(ctx->link, 0xe5,
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0xac);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5,
 			       0x00, 0x3a, 0x00, 0x3a, 0x00, 0x0e, 0x10);
-	mipi_dsi_dcs_write_seq(ctx->link, 0xb5,
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5,
 			       0x75, 0x60, 0x2d, 0x5d, 0x80, 0x00, 0x0a, 0x0b,
 			       0x00, 0x05, 0x0b, 0x00, 0x80, 0x0d, 0x0e, 0x40,
 			       0x00, 0x0c, 0x00, 0x16, 0x00, 0xb8, 0x00, 0x80,
 			       0x0d, 0x0e, 0x40, 0x00, 0x0c, 0x00, 0x16, 0x00,
 			       0xb8, 0x00, 0x81, 0x00, 0x03, 0x03, 0x03, 0x01,
 			       0x01);
-	msleep(85);
-	mipi_dsi_dcs_write_seq(ctx->link, 0xcd,
+	mipi_dsi_msleep(&ctx, 85);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd,
 			       0x00, 0x00, 0x00, 0x19, 0x19, 0x19, 0x19, 0x19,
 			       0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
 			       0x16, 0x16);
-	mipi_dsi_dcs_write_seq(ctx->link, 0xcb, 0x80, 0x5c, 0x07, 0x03, 0x28);
-	mipi_dsi_dcs_write_seq(ctx->link, 0xc0, 0x02, 0x02, 0x0f);
-	mipi_dsi_dcs_write_seq(ctx->link, 0x55, 0x04, 0x61, 0xdb, 0x04, 0x70, 0xdb);
-	mipi_dsi_dcs_write_seq(ctx->link, 0xb0, 0xca);
-
-	ret = mipi_dsi_dcs_set_display_on(ctx->link);
-	if (ret < 0) {
-		dev_err(panel->dev, "Failed to set display on: %d\n", ret);
-		return ret;
-	}
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x80, 0x5c, 0x07, 0x03, 0x28);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x02, 0x02, 0x0f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x55, 0x04, 0x61, 0xdb, 0x04, 0x70, 0xdb);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0xca);
 
-	msleep(50);
+	mipi_dsi_dcs_set_display_on_multi(&ctx);
 
-	ctx->link->mode_flags &= ~MIPI_DSI_MODE_LPM;
+	mipi_dsi_msleep(&ctx, 50);
 
-	drm_dsc_pps_payload_pack(&pps, ctx->link->dsc);
-	ret = mipi_dsi_picture_parameter_set(ctx->link, &pps);
-	if (ret < 0) {
-		dev_err(panel->dev, "Failed to set PPS: %d\n", ret);
-		return ret;
-	}
+	sw43408->link->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+	drm_dsc_pps_payload_pack(&pps, sw43408->link->dsc);
 
-	ctx->link->mode_flags |= MIPI_DSI_MODE_LPM;
+	mipi_dsi_picture_parameter_set_multi(&ctx, &pps);
+
+	sw43408->link->mode_flags |= MIPI_DSI_MODE_LPM;
 
 	/*
 	 * This panel uses PPS selectors with offset:
 	 * PPS 1 if pps_identifier is 0
 	 * PPS 2 if pps_identifier is 1
 	 */
-	ret = mipi_dsi_compression_mode_ext(ctx->link, true,
+	mipi_dsi_compression_mode_ext_multi(&ctx, true,
 					    MIPI_DSI_COMPRESSION_DSC, 1);
-	if (ret < 0) {
-		dev_err(panel->dev, "Failed to set compression mode: %d\n", ret);
-		return ret;
-	}
-
-	return 0;
+	return ctx.accum_err;
 }
 
 static int sw43408_prepare(struct drm_panel *panel)

-- 
2.39.2


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

* Re: [PATCH v2 2/7] drm/mipi-dsi: wrap more functions for streamline handling
  2024-05-11 23:00 ` [PATCH v2 2/7] drm/mipi-dsi: wrap more functions for streamline handling Dmitry Baryshkov
@ 2024-05-13 16:49   ` Doug Anderson
  2024-05-17 19:32   ` Neil Armstrong
  1 sibling, 0 replies; 11+ messages in thread
From: Doug Anderson @ 2024-05-13 16:49 UTC (permalink / raw
  To: Dmitry Baryshkov
  Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Daniel Vetter, Neil Armstrong, Jessica Zhang, Sam Ravnborg,
	Sumit Semwal, Caleb Connolly, Marijn Suijten, Vinod Koul,
	Cong Yang, dri-devel, linux-kernel

Hi,

On Sat, May 11, 2024 at 4:00 PM Dmitry Baryshkov
<dmitry.baryshkov@linaro.org> wrote:
>
> Follow the pattern of mipi_dsi_dcs_*_multi() and wrap several existing
> MIPI DSI functions to use the context for processing. This simplifies
> and streamlines driver code to use simpler code pattern.
>
> Note, msleep function is also wrapped in this way as it is frequently
> called inbetween other mipi_dsi_dcs_*() functions.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>  drivers/gpu/drm/drm_mipi_dsi.c | 210 +++++++++++++++++++++++++++++++++++++++++
>  include/drm/drm_mipi_dsi.h     |  21 +++++
>  2 files changed, 231 insertions(+)

Reviewed-by: Douglas Anderson <dianders@chromium.org>

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

* Re: [PATCH v2 2/7] drm/mipi-dsi: wrap more functions for streamline handling
  2024-05-11 23:00 ` [PATCH v2 2/7] drm/mipi-dsi: wrap more functions for streamline handling Dmitry Baryshkov
  2024-05-13 16:49   ` Doug Anderson
@ 2024-05-17 19:32   ` Neil Armstrong
  1 sibling, 0 replies; 11+ messages in thread
From: Neil Armstrong @ 2024-05-17 19:32 UTC (permalink / raw
  To: Dmitry Baryshkov, Douglas Anderson, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Daniel Vetter,
	Jessica Zhang, Sam Ravnborg, Sumit Semwal, Caleb Connolly,
	Marijn Suijten, Vinod Koul
  Cc: Cong Yang, dri-devel, linux-kernel

On 12/05/2024 01:00, Dmitry Baryshkov wrote:
> Follow the pattern of mipi_dsi_dcs_*_multi() and wrap several existing
> MIPI DSI functions to use the context for processing. This simplifies
> and streamlines driver code to use simpler code pattern.
> 
> Note, msleep function is also wrapped in this way as it is frequently
> called inbetween other mipi_dsi_dcs_*() functions.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/drm_mipi_dsi.c | 210 +++++++++++++++++++++++++++++++++++++++++
>   include/drm/drm_mipi_dsi.h     |  21 +++++
>   2 files changed, 231 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
> index d2957cb692d3..8721edd06c06 100644
> --- a/drivers/gpu/drm/drm_mipi_dsi.c
> +++ b/drivers/gpu/drm/drm_mipi_dsi.c
> @@ -1429,6 +1429,216 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
>   }
>   EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness_large);
>   
> +/**
> + * mipi_dsi_picture_parameter_set_multi() - transmit the DSC PPS to the peripheral
> + * @ctx: Context for multiple DSI transactions
> + * @pps: VESA DSC 1.1 Picture Parameter Set
> + *
> + * Like mipi_dsi_picture_parameter_set() but deals with errors in a way that
> + * makes it convenient to make several calls in a row.
> + */
> +void mipi_dsi_picture_parameter_set_multi(struct mipi_dsi_multi_context *ctx,
> +				   const struct drm_dsc_picture_parameter_set *pps)
> +{
> +	struct mipi_dsi_device *dsi = ctx->dsi;
> +	struct device *dev = &dsi->dev;
> +	ssize_t ret;
> +
> +	if (ctx->accum_err)
> +		return;
> +
> +	ret = mipi_dsi_picture_parameter_set(dsi, pps);
> +	if (ret < 0) {
> +		ctx->accum_err = ret;
> +		dev_err(dev, "sending PPS failed: %d\n",
> +			ctx->accum_err);
> +	}
> +}
> +EXPORT_SYMBOL(mipi_dsi_picture_parameter_set_multi);
> +
> +/**
> + * mipi_dsi_compression_mode_ext_multi() - enable/disable DSC on the peripheral
> + * @ctx: Context for multiple DSI transactions
> + * @enable: Whether to enable or disable the DSC
> + * @algo: Selected compression algorithm
> + * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS entries
> + *
> + * Like mipi_dsi_compression_mode_ext() but deals with errors in a way that
> + * makes it convenient to make several calls in a row.
> + */
> +void mipi_dsi_compression_mode_ext_multi(struct mipi_dsi_multi_context *ctx,
> +					 bool enable,
> +					 enum mipi_dsi_compression_algo algo,
> +					 unsigned int pps_selector)
> +{
> +	struct mipi_dsi_device *dsi = ctx->dsi;
> +	struct device *dev = &dsi->dev;
> +	ssize_t ret;
> +
> +	if (ctx->accum_err)
> +		return;
> +
> +	ret = mipi_dsi_compression_mode_ext(dsi, enable, algo, pps_selector);
> +	if (ret < 0) {
> +		ctx->accum_err = ret;
> +		dev_err(dev, "sending COMPRESSION_MODE failed: %d\n",
> +			ctx->accum_err);
> +	}
> +}
> +EXPORT_SYMBOL(mipi_dsi_compression_mode_ext_multi);
> +
> +/**
> + * mipi_dsi_dcs_nop_multi() - send DCS NOP packet
> + * @ctx: Context for multiple DSI transactions
> + *
> + * Like mipi_dsi_dcs_nop() but deals with errors in a way that
> + * makes it convenient to make several calls in a row.
> + */
> +void mipi_dsi_dcs_nop_multi(struct mipi_dsi_multi_context *ctx)
> +{
> +	struct mipi_dsi_device *dsi = ctx->dsi;
> +	struct device *dev = &dsi->dev;
> +	ssize_t ret;
> +
> +	if (ctx->accum_err)
> +		return;
> +
> +	ret = mipi_dsi_dcs_nop(dsi);
> +	if (ret < 0) {
> +		ctx->accum_err = ret;
> +		dev_err(dev, "sending DCS NOP failed: %d\n",
> +			ctx->accum_err);
> +	}
> +}
> +EXPORT_SYMBOL(mipi_dsi_dcs_nop_multi);
> +
> +/**
> + * mipi_dsi_dcs_enter_sleep_mode_multi() - send DCS ENTER_SLEEP_MODE  packet
> + * @ctx: Context for multiple DSI transactions
> + *
> + * Like mipi_dsi_dcs_enter_sleep_mode() but deals with errors in a way that
> + * makes it convenient to make several calls in a row.
> + */
> +void mipi_dsi_dcs_enter_sleep_mode_multi(struct mipi_dsi_multi_context *ctx)
> +{
> +	struct mipi_dsi_device *dsi = ctx->dsi;
> +	struct device *dev = &dsi->dev;
> +	ssize_t ret;
> +
> +	if (ctx->accum_err)
> +		return;
> +
> +	ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
> +	if (ret < 0) {
> +		ctx->accum_err = ret;
> +		dev_err(dev, "sending DCS ENTER_SLEEP_MODE failed: %d\n",
> +			ctx->accum_err);
> +	}
> +}
> +EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode_multi);
> +
> +/**
> + * mipi_dsi_dcs_exit_sleep_mode_multi() - send DCS EXIT_SLEEP_MODE packet
> + * @ctx: Context for multiple DSI transactions
> + *
> + * Like mipi_dsi_dcs_exit_sleep_mode() but deals with errors in a way that
> + * makes it convenient to make several calls in a row.
> + */
> +void mipi_dsi_dcs_exit_sleep_mode_multi(struct mipi_dsi_multi_context *ctx)
> +{
> +	struct mipi_dsi_device *dsi = ctx->dsi;
> +	struct device *dev = &dsi->dev;
> +	ssize_t ret;
> +
> +	if (ctx->accum_err)
> +		return;
> +
> +	ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
> +	if (ret < 0) {
> +		ctx->accum_err = ret;
> +		dev_err(dev, "sending DCS EXIT_SLEEP_MODE failed: %d\n",
> +			ctx->accum_err);
> +	}
> +}
> +EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode_multi);
> +
> +/**
> + * mipi_dsi_dcs_set_display_off_multi() - send DCS SET_DISPLAY_OFF packet
> + * @ctx: Context for multiple DSI transactions
> + *
> + * Like mipi_dsi_dcs_set_display_off() but deals with errors in a way that
> + * makes it convenient to make several calls in a row.
> + */
> +void mipi_dsi_dcs_set_display_off_multi(struct mipi_dsi_multi_context *ctx)
> +{
> +	struct mipi_dsi_device *dsi = ctx->dsi;
> +	struct device *dev = &dsi->dev;
> +	ssize_t ret;
> +
> +	if (ctx->accum_err)
> +		return;
> +
> +	ret = mipi_dsi_dcs_set_display_off(dsi);
> +	if (ret < 0) {
> +		ctx->accum_err = ret;
> +		dev_err(dev, "sending DCS SET_DISPLAY_OFF failed: %d\n",
> +			ctx->accum_err);
> +	}
> +}
> +EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off_multi);
> +
> +/**
> + * mipi_dsi_dcs_set_display_on_multi() - send DCS SET_DISPLAY_ON packet
> + * @ctx: Context for multiple DSI transactions
> + *
> + * Like mipi_dsi_dcs_set_display_on() but deals with errors in a way that
> + * makes it convenient to make several calls in a row.
> + */
> +void mipi_dsi_dcs_set_display_on_multi(struct mipi_dsi_multi_context *ctx)
> +{
> +	struct mipi_dsi_device *dsi = ctx->dsi;
> +	struct device *dev = &dsi->dev;
> +	ssize_t ret;
> +
> +	if (ctx->accum_err)
> +		return;
> +
> +	ret = mipi_dsi_dcs_set_display_on(dsi);
> +	if (ret < 0) {
> +		ctx->accum_err = ret;
> +		dev_err(dev, "sending DCS SET_DISPLAY_ON failed: %d\n",
> +			ctx->accum_err);
> +	}
> +}
> +EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on_multi);
> +
> +/**
> + * mipi_dsi_dcs_set_tear_on_multi() - send DCS SET_TEAR_ON packet
> + * @ctx: Context for multiple DSI transactions
> + * @mode: the Tearing Effect Output Line mode
> + *
> + * Like mipi_dsi_dcs_set_tear_on() but deals with errors in a way that
> + * makes it convenient to make several calls in a row.
> + */
> +void mipi_dsi_dcs_set_tear_on_multi(struct mipi_dsi_multi_context *ctx,
> +				    enum mipi_dsi_dcs_tear_mode mode)
> +{
> +	struct mipi_dsi_device *dsi = ctx->dsi;
> +	struct device *dev = &dsi->dev;
> +	ssize_t ret;
> +
> +	if (ctx->accum_err)
> +		return;
> +
> +	ret = mipi_dsi_dcs_set_tear_on(dsi, mode);
> +	if (ret < 0) {
> +		ctx->accum_err = ret;
> +		dev_err(dev, "sending DCS SET_TEAR_ON failed: %d\n",
> +			ctx->accum_err);
> +	}
> +}
> +EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on_multi);
> +
>   static int mipi_dsi_drv_probe(struct device *dev)
>   {
>   	struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
> index 5e9cad541bd6..bd5a0b6d0711 100644
> --- a/include/drm/drm_mipi_dsi.h
> +++ b/include/drm/drm_mipi_dsi.h
> @@ -275,6 +275,13 @@ int mipi_dsi_compression_mode_ext(struct mipi_dsi_device *dsi, bool enable,
>   int mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi,
>   				   const struct drm_dsc_picture_parameter_set *pps);
>   
> +void mipi_dsi_compression_mode_ext_multi(struct mipi_dsi_multi_context *ctx,
> +					 bool enable,
> +					 enum mipi_dsi_compression_algo algo,
> +					 unsigned int pps_selector);
> +void mipi_dsi_picture_parameter_set_multi(struct mipi_dsi_multi_context *ctx,
> +					  const struct drm_dsc_picture_parameter_set *pps);
> +
>   ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
>   			       size_t size);
>   int mipi_dsi_generic_write_chatty(struct mipi_dsi_device *dsi,
> @@ -284,6 +291,12 @@ void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx,
>   ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
>   			      size_t num_params, void *data, size_t size);
>   
> +#define mipi_dsi_msleep(ctx, delay)	\
> +	do {				\
> +		if (!ctx.accum_err)	\
> +			msleep(delay);	\
> +	} while (0)
> +
>   /**
>    * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode
>    * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking
> @@ -338,6 +351,14 @@ int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi,
>   int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
>   					     u16 *brightness);
>   
> +void mipi_dsi_dcs_nop_multi(struct mipi_dsi_multi_context *ctx);
> +void mipi_dsi_dcs_enter_sleep_mode_multi(struct mipi_dsi_multi_context *ctx);
> +void mipi_dsi_dcs_exit_sleep_mode_multi(struct mipi_dsi_multi_context *ctx);
> +void mipi_dsi_dcs_set_display_off_multi(struct mipi_dsi_multi_context *ctx);
> +void mipi_dsi_dcs_set_display_on_multi(struct mipi_dsi_multi_context *ctx);
> +void mipi_dsi_dcs_set_tear_on_multi(struct mipi_dsi_multi_context *ctx,
> +				    enum mipi_dsi_dcs_tear_mode mode);
> +
>   /**
>    * mipi_dsi_generic_write_seq - transmit data using a generic write packet
>    *
> 

The mipi_dsi_msleep() seems a little bit over-enginerred for me, but it serves
the purpose so:

Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>

Thanks,
Neil

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

* Re: [PATCH v2 0/7] drm/mipi-dsi: simplify MIPI DSI init/cleanup even more
  2024-05-11 23:00 [PATCH v2 0/7] drm/mipi-dsi: simplify MIPI DSI init/cleanup even more Dmitry Baryshkov
                   ` (6 preceding siblings ...)
  2024-05-11 23:00 ` [PATCH v2 7/7] drm/panel: lg-sw43408: use new streamlined MIPI DSI API Dmitry Baryshkov
@ 2024-05-17 19:39 ` Neil Armstrong
  7 siblings, 0 replies; 11+ messages in thread
From: Neil Armstrong @ 2024-05-17 19:39 UTC (permalink / raw
  To: Douglas Anderson, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Jessica Zhang,
	Sam Ravnborg, Sumit Semwal, Caleb Connolly, Marijn Suijten,
	Vinod Koul, Dmitry Baryshkov
  Cc: Cong Yang, dri-devel, linux-kernel

Hi,

On Sun, 12 May 2024 02:00:17 +0300, Dmitry Baryshkov wrote:
> Follow the example of mipi_dsi_generic_write_multi(),
> mipi_dsi_dcs_write_buffer_multi(), mipi_dsi_generic_write_seq_multi()
> and mipi_dsi_dcs_write_seq_multi(). Define _multi variants for several
> other common MIPI DSI functions and use these functions in the panel
> code.
> 
> This series also includes a fix for the LG SW43408. If the proposed
> approach is declined, the fix will be submitted separately.
> 
> [...]

Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next)

[1/7] drm/panel: lg-sw43408: add missing error handling
      https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/51f9183e4af8c7f00e81180cbb9ee4a98a0f0aa1
[2/7] drm/mipi-dsi: wrap more functions for streamline handling
      https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/f79d6d28d8fe77b14beeaebe5393d9f294f8d09d
[3/7] drm/panel: boe-tv101wum-nl6: use wrapped MIPI DCS functions
      https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/91329f921283b995ac125a0c6e61be0c1399f66f
[4/7] drm/panel: ilitek-ili9882t: use wrapped MIPI DCS functions
      https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/510ba36e86eeb3ca89326dd51da32806e1ede693
[5/7] drm/panel: innolux-p079zca: use mipi_dsi_dcs_nop_multi()
      https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/0f43988fb9c1c0a0c2f5ccf2d1bdb914f6e4e79b
[6/7] drm/panel: novatek-nt36672e: use wrapped MIPI DCS functions
      https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/67ba7a82d99a8a8b4bcc1b8124b5640c63dd51bf
[7/7] drm/panel: lg-sw43408: use new streamlined MIPI DSI API
      https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/85cb9d603953d77de5cb311d229a79c439ff6bfb

-- 
Neil


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

end of thread, other threads:[~2024-05-17 19:39 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-11 23:00 [PATCH v2 0/7] drm/mipi-dsi: simplify MIPI DSI init/cleanup even more Dmitry Baryshkov
2024-05-11 23:00 ` [PATCH v2 1/7] drm/panel: lg-sw43408: add missing error handling Dmitry Baryshkov
2024-05-11 23:00 ` [PATCH v2 2/7] drm/mipi-dsi: wrap more functions for streamline handling Dmitry Baryshkov
2024-05-13 16:49   ` Doug Anderson
2024-05-17 19:32   ` Neil Armstrong
2024-05-11 23:00 ` [PATCH v2 3/7] drm/panel: boe-tv101wum-nl6: use wrapped MIPI DCS functions Dmitry Baryshkov
2024-05-11 23:00 ` [PATCH v2 4/7] drm/panel: ilitek-ili9882t: " Dmitry Baryshkov
2024-05-11 23:00 ` [PATCH v2 5/7] drm/panel: innolux-p079zca: use mipi_dsi_dcs_nop_multi() Dmitry Baryshkov
2024-05-11 23:00 ` [PATCH v2 6/7] drm/panel: novatek-nt36672e: use wrapped MIPI DCS functions Dmitry Baryshkov
2024-05-11 23:00 ` [PATCH v2 7/7] drm/panel: lg-sw43408: use new streamlined MIPI DSI API Dmitry Baryshkov
2024-05-17 19:39 ` [PATCH v2 0/7] drm/mipi-dsi: simplify MIPI DSI init/cleanup even more Neil Armstrong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).