LKML Archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/9] drm/mipi-dsi: Reduce bloat and add funcs for cleaner init seqs
@ 2024-05-08 20:51 Douglas Anderson
  2024-05-08 20:51 ` [PATCH v4 1/9] drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_dcs_write_seq() Douglas Anderson
                   ` (8 more replies)
  0 siblings, 9 replies; 14+ messages in thread
From: Douglas Anderson @ 2024-05-08 20:51 UTC (permalink / raw
  To: dri-devel
  Cc: lvzhaoxiong, Jani Nikula, Hsin-Yi Wang, Linus Walleij,
	Javier Martinez Canillas, Neil Armstrong, Cong Yang, Sam Ravnborg,
	Dmitry Baryshkov, Joel Selvaraj, Brian Norris, Douglas Anderson,
	Daniel Vetter, David Airlie, Jessica Zhang, Jonathan Corbet,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, linux-doc,
	linux-kernel

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-204c0800d496@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


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

* [PATCH v4 1/9] drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_dcs_write_seq()
  2024-05-08 20:51 [PATCH v4 0/9] drm/mipi-dsi: Reduce bloat and add funcs for cleaner init seqs Douglas Anderson
@ 2024-05-08 20:51 ` Douglas Anderson
  2024-05-08 20:51 ` [PATCH v4 2/9] drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_generic_write_seq() Douglas Anderson
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Douglas Anderson @ 2024-05-08 20:51 UTC (permalink / raw
  To: dri-devel
  Cc: lvzhaoxiong, Jani Nikula, Hsin-Yi Wang, Linus Walleij,
	Javier Martinez Canillas, Neil Armstrong, Cong Yang, Sam Ravnborg,
	Dmitry Baryshkov, Joel Selvaraj, Brian Norris, Douglas Anderson,
	Daniel Vetter, David Airlie, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, linux-kernel

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 <neil.armstrong@linaro.org>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---

(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 = &dsi->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 = &dsi->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


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

* [PATCH v4 2/9] drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_generic_write_seq()
  2024-05-08 20:51 [PATCH v4 0/9] drm/mipi-dsi: Reduce bloat and add funcs for cleaner init seqs Douglas Anderson
  2024-05-08 20:51 ` [PATCH v4 1/9] drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_dcs_write_seq() Douglas Anderson
@ 2024-05-08 20:51 ` Douglas Anderson
  2024-05-08 20:51 ` [PATCH v4 3/9] drm/mipi-dsi: mipi_dsi_*_write functions don't need to ratelimit prints Douglas Anderson
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Douglas Anderson @ 2024-05-08 20:51 UTC (permalink / raw
  To: dri-devel
  Cc: lvzhaoxiong, Jani Nikula, Hsin-Yi Wang, Linus Walleij,
	Javier Martinez Canillas, Neil Armstrong, Cong Yang, Sam Ravnborg,
	Dmitry Baryshkov, Joel Selvaraj, Brian Norris, Douglas Anderson,
	Daniel Vetter, David Airlie, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, linux-kernel

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 <neil.armstrong@linaro.org>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---

(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 = &dsi->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 = &dsi->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


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

* [PATCH v4 3/9] drm/mipi-dsi: mipi_dsi_*_write functions don't need to ratelimit prints
  2024-05-08 20:51 [PATCH v4 0/9] drm/mipi-dsi: Reduce bloat and add funcs for cleaner init seqs Douglas Anderson
  2024-05-08 20:51 ` [PATCH v4 1/9] drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_dcs_write_seq() Douglas Anderson
  2024-05-08 20:51 ` [PATCH v4 2/9] drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_generic_write_seq() Douglas Anderson
@ 2024-05-08 20:51 ` Douglas Anderson
  2024-05-08 20:51 ` [PATCH v4 4/9] drm/mipi-dsi: Reduce driver bloat of mipi_dsi_*_write_seq() Douglas Anderson
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Douglas Anderson @ 2024-05-08 20:51 UTC (permalink / raw
  To: dri-devel
  Cc: lvzhaoxiong, Jani Nikula, Hsin-Yi Wang, Linus Walleij,
	Javier Martinez Canillas, Neil Armstrong, Cong Yang, Sam Ravnborg,
	Dmitry Baryshkov, Joel Selvaraj, Brian Norris, Douglas Anderson,
	Daniel Vetter, David Airlie, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, linux-kernel

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 <neil.armstrong@linaro.org>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---

(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 = &dsi->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 = &dsi->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


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

* [PATCH v4 4/9] drm/mipi-dsi: Reduce driver bloat of mipi_dsi_*_write_seq()
  2024-05-08 20:51 [PATCH v4 0/9] drm/mipi-dsi: Reduce bloat and add funcs for cleaner init seqs Douglas Anderson
                   ` (2 preceding siblings ...)
  2024-05-08 20:51 ` [PATCH v4 3/9] drm/mipi-dsi: mipi_dsi_*_write functions don't need to ratelimit prints Douglas Anderson
@ 2024-05-08 20:51 ` Douglas Anderson
  2024-05-13  9:29   ` Maxime Ripard
  2024-05-08 20:51 ` [PATCH v4 5/9] drm/mipi-dsi: Introduce mipi_dsi_*_write_seq_multi() Douglas Anderson
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 14+ messages in thread
From: Douglas Anderson @ 2024-05-08 20:51 UTC (permalink / raw
  To: dri-devel
  Cc: lvzhaoxiong, Jani Nikula, Hsin-Yi Wang, Linus Walleij,
	Javier Martinez Canillas, Neil Armstrong, Cong Yang, Sam Ravnborg,
	Dmitry Baryshkov, Joel Selvaraj, Brian Norris, Douglas Anderson,
	Daniel Vetter, David Airlie, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, linux-kernel

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               10640    6236   -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 <dmitry.baryshkov@linaro.org>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---

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 = &dsi->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 = &dsi->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",
+			(int)len, data, ret);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_chatty);
+
 /**
  * mipi_dsi_dcs_write() - send DCS write command
  * @dsi: DSI peripheral device
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 67967be48dbd..6d68d9927f46 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -256,6 +256,8 @@ int mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi,
 
 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,
+				  const void *payload, size_t size);
 ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
 			      size_t num_params, void *data, size_t size);
 
@@ -279,6 +281,8 @@ enum mipi_dsi_dcs_tear_mode {
 
 ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi,
 				  const void *data, size_t len);
+int mipi_dsi_dcs_write_buffer_chatty(struct mipi_dsi_device *dsi,
+				     const void *data, size_t len);
 ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd,
 			   const void *data, size_t len);
 ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data,
@@ -311,38 +315,39 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
 
 /**
  * mipi_dsi_generic_write_seq - transmit data using a generic write packet
+ *
+ * This macro will print errors for you and will RETURN FROM THE CALLING
+ * FUNCTION (yes this is non-intuitive) upon error.
+ *
  * @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 = &dsi->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;                                       \
-		}                                                         \
+#define mipi_dsi_generic_write_seq(dsi, seq...)                                \
+	do {                                                                   \
+		static const u8 d[] = { seq };                                 \
+		int ret;                                                       \
+		ret = mipi_dsi_generic_write_chatty(dsi, d, ARRAY_SIZE(d));    \
+		if (ret < 0)                                                   \
+			return ret;                                            \
 	} while (0)
 
 /**
  * mipi_dsi_dcs_write_seq - transmit a DCS command with payload
+ *
+ * This macro will print errors for you and will RETURN FROM THE CALLING
+ * FUNCTION (yes this is non-intuitive) upon error.
+ *
  * @dsi: DSI peripheral device
  * @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 = &dsi->dev;                             \
-		ssize_t ret;                                                \
-		ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d));     \
-		if (ret < 0) {                                              \
-			dev_err(dev, "sending command %#02x failed: %zd\n", \
-				cmd, ret);                                  \
-			return ret;                                         \
-		}                                                           \
+#define mipi_dsi_dcs_write_seq(dsi, cmd, seq...)                               \
+	do {                                                                   \
+		static const u8 d[] = { cmd, seq };                            \
+		int ret;                                                       \
+		ret = mipi_dsi_dcs_write_buffer_chatty(dsi, d, ARRAY_SIZE(d)); \
+		if (ret < 0)                                                   \
+			return ret;                                            \
 	} while (0)
 
 /**
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog


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

* [PATCH v4 5/9] drm/mipi-dsi: Introduce mipi_dsi_*_write_seq_multi()
  2024-05-08 20:51 [PATCH v4 0/9] drm/mipi-dsi: Reduce bloat and add funcs for cleaner init seqs Douglas Anderson
                   ` (3 preceding siblings ...)
  2024-05-08 20:51 ` [PATCH v4 4/9] drm/mipi-dsi: Reduce driver bloat of mipi_dsi_*_write_seq() Douglas Anderson
@ 2024-05-08 20:51 ` Douglas Anderson
  2024-05-08 20:51 ` [PATCH v4 6/9] drm/panel: novatek-nt36672e: Switch to mipi_dsi_dcs_write_seq_multi() Douglas Anderson
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Douglas Anderson @ 2024-05-08 20:51 UTC (permalink / raw
  To: dri-devel
  Cc: lvzhaoxiong, Jani Nikula, Hsin-Yi Wang, Linus Walleij,
	Javier Martinez Canillas, Neil Armstrong, Cong Yang, Sam Ravnborg,
	Dmitry Baryshkov, Joel Selvaraj, Brian Norris, Douglas Anderson,
	Daniel Vetter, David Airlie, Jonathan Corbet, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, linux-doc, linux-kernel

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_init                6236    5248    -988
Total: Before=10651, After=9663, chg -9.28%

Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---
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 <dianders@chromium.org>
 
 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 <dianders@chromium.org>
+
+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 = &dsi->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 for multiple DSI transactions
+ * @data: buffer containing data to be transmitted
+ * @len: size of transmission buffer
+ *
+ * Like mipi_dsi_dcs_write_buffer_chatty() but deals with errors in a way that
+ * makes it convenient to make several calls in a row.
+ */
+void mipi_dsi_dcs_write_buffer_multi(struct mipi_dsi_multi_context *ctx,
+				     const void *data, size_t len)
+{
+	struct mipi_dsi_device *dsi = ctx->dsi;
+	struct device *dev = &dsi->dev;
+	ssize_t ret;
+
+	if (ctx->accum_err)
+		return;
+
+	ret = mipi_dsi_dcs_write_buffer(dsi, data, len);
+	if (ret < 0) {
+		ctx->accum_err = ret;
+		dev_err(dev, "sending dcs data %*ph failed: %d\n",
+			(int)len, data, ctx->accum_err);
+	}
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_multi);
+
 /**
  * mipi_dsi_dcs_write() - send DCS write command
  * @dsi: DSI peripheral device
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 6d68d9927f46..5e9cad541bd6 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -197,6 +197,27 @@ struct mipi_dsi_device {
 	struct drm_dsc_config *dsc;
 };
 
+/**
+ * struct mipi_dsi_multi_context - Context to call multiple MIPI DSI funcs in a row
+ */
+struct mipi_dsi_multi_context {
+	/**
+	 * @dsi: Pointer to the MIPI DSI device
+	 */
+	struct mipi_dsi_device *dsi;
+
+	/**
+	 * @accum_err: Storage for the accumulated error over the multiple calls
+	 *
+	 * Init to 0. If a function encounters an error then the error code
+	 * will be stored here. If you call a function and this points to a
+	 * non-zero value then the function will be a noop. This allows calling
+	 * a function many times in a row and just checking the error at the
+	 * end to see if any of them failed.
+	 */
+	int accum_err;
+};
+
 #define MIPI_DSI_MODULE_PREFIX "mipi-dsi:"
 
 #define to_mipi_dsi_device(__dev)	container_of_const(__dev, struct mipi_dsi_device, dev)
@@ -258,6 +279,8 @@ 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,
 				  const void *payload, size_t size);
+void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx,
+				  const void *payload, size_t size);
 ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
 			      size_t num_params, void *data, size_t size);
 
@@ -283,6 +306,8 @@ ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi,
 				  const void *data, size_t len);
 int mipi_dsi_dcs_write_buffer_chatty(struct mipi_dsi_device *dsi,
 				     const void *data, size_t len);
+void mipi_dsi_dcs_write_buffer_multi(struct mipi_dsi_multi_context *ctx,
+				     const void *data, size_t len);
 ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd,
 			   const void *data, size_t len);
 ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data,
@@ -319,6 +344,9 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
  * This macro will print errors for you and will RETURN FROM THE CALLING
  * FUNCTION (yes this is non-intuitive) upon error.
  *
+ * Because of the non-intuitive return behavior, THIS MACRO IS DEPRECATED.
+ * Please replace calls of it with mipi_dsi_generic_write_seq_multi().
+ *
  * @dsi: DSI peripheral device
  * @seq: buffer containing the payload
  */
@@ -331,12 +359,30 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
 			return ret;                                            \
 	} while (0)
 
+/**
+ * mipi_dsi_generic_write_seq_multi - transmit data using a generic write packet
+ *
+ * This macro will print errors for you and error handling is optimized for
+ * callers that call this multiple times in a row.
+ *
+ * @ctx: Context for multiple DSI transactions
+ * @seq: buffer containing the payload
+ */
+#define mipi_dsi_generic_write_seq_multi(ctx, seq...)                \
+	do {                                                         \
+		static const u8 d[] = { seq };                       \
+		mipi_dsi_generic_write_multi(ctx, d, ARRAY_SIZE(d)); \
+	} while (0)
+
 /**
  * mipi_dsi_dcs_write_seq - transmit a DCS command with payload
  *
  * This macro will print errors for you and will RETURN FROM THE CALLING
  * FUNCTION (yes this is non-intuitive) upon error.
  *
+ * Because of the non-intuitive return behavior, THIS MACRO IS DEPRECATED.
+ * Please replace calls of it with mipi_dsi_dcs_write_seq_multi().
+ *
  * @dsi: DSI peripheral device
  * @cmd: Command
  * @seq: buffer containing data to be transmitted
@@ -350,6 +396,22 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
 			return ret;                                            \
 	} while (0)
 
+/**
+ * mipi_dsi_dcs_write_seq_multi - transmit a DCS command with payload
+ *
+ * This macro will print errors for you and error handling is optimized for
+ * callers that call this multiple times in a row.
+ *
+ * @ctx: Context for multiple DSI transactions
+ * @cmd: Command
+ * @seq: buffer containing data to be transmitted
+ */
+#define mipi_dsi_dcs_write_seq_multi(ctx, cmd, seq...)                  \
+	do {                                                            \
+		static const u8 d[] = { cmd, seq };                     \
+		mipi_dsi_dcs_write_buffer_multi(ctx, d, ARRAY_SIZE(d)); \
+	} while (0)
+
 /**
  * struct mipi_dsi_driver - DSI driver
  * @driver: device driver model driver
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog


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

* [PATCH v4 6/9] drm/panel: novatek-nt36672e: Switch to mipi_dsi_dcs_write_seq_multi()
  2024-05-08 20:51 [PATCH v4 0/9] drm/mipi-dsi: Reduce bloat and add funcs for cleaner init seqs Douglas Anderson
                   ` (4 preceding siblings ...)
  2024-05-08 20:51 ` [PATCH v4 5/9] drm/mipi-dsi: Introduce mipi_dsi_*_write_seq_multi() Douglas Anderson
@ 2024-05-08 20:51 ` Douglas Anderson
  2024-05-13 17:00   ` Dmitry Baryshkov
  2024-05-13 19:46   ` Linus Walleij
  2024-05-08 20:51 ` [PATCH v4 7/9] drm/panel: boe-tv101wum-nl6: Don't use a table for initting panels Douglas Anderson
                   ` (2 subsequent siblings)
  8 siblings, 2 replies; 14+ messages in thread
From: Douglas Anderson @ 2024-05-08 20:51 UTC (permalink / raw
  To: dri-devel
  Cc: lvzhaoxiong, Jani Nikula, Hsin-Yi Wang, Linus Walleij,
	Javier Martinez Canillas, Neil Armstrong, Cong Yang, Sam Ravnborg,
	Dmitry Baryshkov, Joel Selvaraj, Brian Norris, Douglas Anderson,
	Ritesh Kumar, Daniel Vetter, David Airlie, Jessica Zhang,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, linux-kernel

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_init                6236    5248    -988
Total: Before=10651, After=9663, chg -9.28%

Cc: Ritesh Kumar <quic_riteshk@quicinc.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---
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);
-	mipi_dsi_dcs_write_seq(dsi, 0x84, 0x31);
-	mipi_dsi_dcs_write_seq(dsi, 0x85, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0x86, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0x87, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0x90, 0x13);
-	mipi_dsi_dcs_write_seq(dsi, 0x92, 0x31);
-	mipi_dsi_dcs_write_seq(dsi, 0x93, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0x94, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0x95, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0x9c, 0xf4);
-	mipi_dsi_dcs_write_seq(dsi, 0x9d, 0x01);
-	mipi_dsi_dcs_write_seq(dsi, 0xa0, 0x0f);
-	mipi_dsi_dcs_write_seq(dsi, 0xa2, 0x0f);
-	mipi_dsi_dcs_write_seq(dsi, 0xa3, 0x02);
-	mipi_dsi_dcs_write_seq(dsi, 0xa4, 0x04);
-	mipi_dsi_dcs_write_seq(dsi, 0xa5, 0x04);
-	mipi_dsi_dcs_write_seq(dsi, 0xc6, 0xc0);
-	mipi_dsi_dcs_write_seq(dsi, 0xc9, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0xd9, 0x80);
-	mipi_dsi_dcs_write_seq(dsi, 0xe9, 0x02);
-	mipi_dsi_dcs_write_seq(dsi, 0xff, 0x25);
-	mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
-	mipi_dsi_dcs_write_seq(dsi, 0x18, 0x22);
-	mipi_dsi_dcs_write_seq(dsi, 0x19, 0xe4);
-	mipi_dsi_dcs_write_seq(dsi, 0x21, 0x40);
-	mipi_dsi_dcs_write_seq(dsi, 0x66, 0xd8);
-	mipi_dsi_dcs_write_seq(dsi, 0x68, 0x50);
-	mipi_dsi_dcs_write_seq(dsi, 0x69, 0x10);
-	mipi_dsi_dcs_write_seq(dsi, 0x6b, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0x6d, 0x0d);
-	mipi_dsi_dcs_write_seq(dsi, 0x6e, 0x48);
-	mipi_dsi_dcs_write_seq(dsi, 0x72, 0x41);
-	mipi_dsi_dcs_write_seq(dsi, 0x73, 0x4a);
-	mipi_dsi_dcs_write_seq(dsi, 0x74, 0xd0);
-	mipi_dsi_dcs_write_seq(dsi, 0x77, 0x62);
-	mipi_dsi_dcs_write_seq(dsi, 0x79, 0x7e);
-	mipi_dsi_dcs_write_seq(dsi, 0x7d, 0x03);
-	mipi_dsi_dcs_write_seq(dsi, 0x7e, 0x15);
-	mipi_dsi_dcs_write_seq(dsi, 0x7f, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0x84, 0x4d);
-	mipi_dsi_dcs_write_seq(dsi, 0xcf, 0x80);
-	mipi_dsi_dcs_write_seq(dsi, 0xd6, 0x80);
-	mipi_dsi_dcs_write_seq(dsi, 0xd7, 0x80);
-	mipi_dsi_dcs_write_seq(dsi, 0xef, 0x20);
-	mipi_dsi_dcs_write_seq(dsi, 0xf0, 0x84);
-	mipi_dsi_dcs_write_seq(dsi, 0xff, 0x26);
-	mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
-	mipi_dsi_dcs_write_seq(dsi, 0x81, 0x0f);
-	mipi_dsi_dcs_write_seq(dsi, 0x83, 0x01);
-	mipi_dsi_dcs_write_seq(dsi, 0x84, 0x03);
-	mipi_dsi_dcs_write_seq(dsi, 0x85, 0x01);
-	mipi_dsi_dcs_write_seq(dsi, 0x86, 0x03);
-	mipi_dsi_dcs_write_seq(dsi, 0x87, 0x01);
-	mipi_dsi_dcs_write_seq(dsi, 0x88, 0x05);
-	mipi_dsi_dcs_write_seq(dsi, 0x8a, 0x1a);
-	mipi_dsi_dcs_write_seq(dsi, 0x8b, 0x11);
-	mipi_dsi_dcs_write_seq(dsi, 0x8c, 0x24);
-	mipi_dsi_dcs_write_seq(dsi, 0x8e, 0x42);
-	mipi_dsi_dcs_write_seq(dsi, 0x8f, 0x11);
-	mipi_dsi_dcs_write_seq(dsi, 0x90, 0x11);
-	mipi_dsi_dcs_write_seq(dsi, 0x91, 0x11);
-	mipi_dsi_dcs_write_seq(dsi, 0x9a, 0x80);
-	mipi_dsi_dcs_write_seq(dsi, 0x9b, 0x04);
-	mipi_dsi_dcs_write_seq(dsi, 0x9c, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0x9d, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0x9e, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0xff, 0x27);
-	mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
-	mipi_dsi_dcs_write_seq(dsi, 0x01, 0x68);
-	mipi_dsi_dcs_write_seq(dsi, 0x20, 0x81);
-	mipi_dsi_dcs_write_seq(dsi, 0x21, 0x6a);
-	mipi_dsi_dcs_write_seq(dsi, 0x25, 0x81);
-	mipi_dsi_dcs_write_seq(dsi, 0x26, 0x94);
-	mipi_dsi_dcs_write_seq(dsi, 0x6e, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0x6f, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0x70, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0x71, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0x72, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0x75, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0x76, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0x77, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0x7d, 0x09);
-	mipi_dsi_dcs_write_seq(dsi, 0x7e, 0x67);
-	mipi_dsi_dcs_write_seq(dsi, 0x80, 0x23);
-	mipi_dsi_dcs_write_seq(dsi, 0x82, 0x09);
-	mipi_dsi_dcs_write_seq(dsi, 0x83, 0x67);
-	mipi_dsi_dcs_write_seq(dsi, 0x88, 0x01);
-	mipi_dsi_dcs_write_seq(dsi, 0x89, 0x10);
-	mipi_dsi_dcs_write_seq(dsi, 0xa5, 0x10);
-	mipi_dsi_dcs_write_seq(dsi, 0xa6, 0x23);
-	mipi_dsi_dcs_write_seq(dsi, 0xa7, 0x01);
-	mipi_dsi_dcs_write_seq(dsi, 0xb6, 0x40);
-	mipi_dsi_dcs_write_seq(dsi, 0xe5, 0x02);
-	mipi_dsi_dcs_write_seq(dsi, 0xe6, 0xd3);
-	mipi_dsi_dcs_write_seq(dsi, 0xeb, 0x03);
-	mipi_dsi_dcs_write_seq(dsi, 0xec, 0x28);
-	mipi_dsi_dcs_write_seq(dsi, 0xff, 0x2a);
-	mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
-	mipi_dsi_dcs_write_seq(dsi, 0x00, 0x91);
-	mipi_dsi_dcs_write_seq(dsi, 0x03, 0x20);
-	mipi_dsi_dcs_write_seq(dsi, 0x07, 0x50);
-	mipi_dsi_dcs_write_seq(dsi, 0x0a, 0x70);
-	mipi_dsi_dcs_write_seq(dsi, 0x0c, 0x04);
-	mipi_dsi_dcs_write_seq(dsi, 0x0d, 0x40);
-	mipi_dsi_dcs_write_seq(dsi, 0x0f, 0x01);
-	mipi_dsi_dcs_write_seq(dsi, 0x11, 0xe0);
-	mipi_dsi_dcs_write_seq(dsi, 0x15, 0x0f);
-	mipi_dsi_dcs_write_seq(dsi, 0x16, 0xa4);
-	mipi_dsi_dcs_write_seq(dsi, 0x19, 0x0f);
-	mipi_dsi_dcs_write_seq(dsi, 0x1a, 0x78);
-	mipi_dsi_dcs_write_seq(dsi, 0x1b, 0x23);
-	mipi_dsi_dcs_write_seq(dsi, 0x1d, 0x36);
-	mipi_dsi_dcs_write_seq(dsi, 0x1e, 0x3e);
-	mipi_dsi_dcs_write_seq(dsi, 0x1f, 0x3e);
-	mipi_dsi_dcs_write_seq(dsi, 0x20, 0x3e);
-	mipi_dsi_dcs_write_seq(dsi, 0x28, 0xfd);
-	mipi_dsi_dcs_write_seq(dsi, 0x29, 0x12);
-	mipi_dsi_dcs_write_seq(dsi, 0x2a, 0xe1);
-	mipi_dsi_dcs_write_seq(dsi, 0x2d, 0x0a);
-	mipi_dsi_dcs_write_seq(dsi, 0x30, 0x49);
-	mipi_dsi_dcs_write_seq(dsi, 0x33, 0x96);
-	mipi_dsi_dcs_write_seq(dsi, 0x34, 0xff);
-	mipi_dsi_dcs_write_seq(dsi, 0x35, 0x40);
-	mipi_dsi_dcs_write_seq(dsi, 0x36, 0xde);
-	mipi_dsi_dcs_write_seq(dsi, 0x37, 0xf9);
-	mipi_dsi_dcs_write_seq(dsi, 0x38, 0x45);
-	mipi_dsi_dcs_write_seq(dsi, 0x39, 0xd9);
-	mipi_dsi_dcs_write_seq(dsi, 0x3a, 0x49);
-	mipi_dsi_dcs_write_seq(dsi, 0x4a, 0xf0);
-	mipi_dsi_dcs_write_seq(dsi, 0x7a, 0x09);
-	mipi_dsi_dcs_write_seq(dsi, 0x7b, 0x40);
-	mipi_dsi_dcs_write_seq(dsi, 0x7f, 0xf0);
-	mipi_dsi_dcs_write_seq(dsi, 0x83, 0x0f);
-	mipi_dsi_dcs_write_seq(dsi, 0x84, 0xa4);
-	mipi_dsi_dcs_write_seq(dsi, 0x87, 0x0f);
-	mipi_dsi_dcs_write_seq(dsi, 0x88, 0x78);
-	mipi_dsi_dcs_write_seq(dsi, 0x89, 0x23);
-	mipi_dsi_dcs_write_seq(dsi, 0x8b, 0x36);
-	mipi_dsi_dcs_write_seq(dsi, 0x8c, 0x7d);
-	mipi_dsi_dcs_write_seq(dsi, 0x8d, 0x7d);
-	mipi_dsi_dcs_write_seq(dsi, 0x8e, 0x7d);
-	mipi_dsi_dcs_write_seq(dsi, 0xff, 0x20);
-	mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
-	mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x00, 0x00, 0x00, 0x17, 0x00, 0x49, 0x00,
-				0x6a, 0x00, 0x89, 0x00, 0x9f, 0x00, 0xb6, 0x00, 0xc8);
-	mipi_dsi_dcs_write_seq(dsi, 0xb1, 0x00, 0xd9, 0x01, 0x10, 0x01, 0x3a, 0x01,
-				0x7a, 0x01, 0xa9, 0x01, 0xf2, 0x02, 0x2d, 0x02, 0x2e);
-	mipi_dsi_dcs_write_seq(dsi, 0xb2, 0x02, 0x64, 0x02, 0xa3, 0x02, 0xca, 0x03,
-				0x00, 0x03, 0x1e, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
-	mipi_dsi_dcs_write_seq(dsi, 0xb3, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
-				0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0xb4, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
-				0x71, 0x00, 0x90, 0x00, 0xa7, 0x00, 0xbf, 0x00, 0xd1);
-	mipi_dsi_dcs_write_seq(dsi, 0xb5, 0x00, 0xe2, 0x01, 0x1a, 0x01, 0x43, 0x01,
-				0x83, 0x01, 0xb2, 0x01, 0xfa, 0x02, 0x34, 0x02, 0x36);
-	mipi_dsi_dcs_write_seq(dsi, 0xb6, 0x02, 0x6b, 0x02, 0xa8, 0x02, 0xd0, 0x03,
-				0x03, 0x03, 0x21, 0x03, 0x4d, 0x03, 0x5b, 0x03, 0x6b);
-	mipi_dsi_dcs_write_seq(dsi, 0xb7, 0x03, 0x7e, 0x03, 0x94, 0x03, 0xac, 0x03,
-				0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0xb8, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
-				0x72, 0x00, 0x92, 0x00, 0xa8, 0x00, 0xbf, 0x00, 0xd1);
-	mipi_dsi_dcs_write_seq(dsi, 0xb9, 0x00, 0xe2, 0x01, 0x18, 0x01, 0x42, 0x01,
-				0x81, 0x01, 0xaf, 0x01, 0xf5, 0x02, 0x2f, 0x02, 0x31);
-	mipi_dsi_dcs_write_seq(dsi, 0xba, 0x02, 0x68, 0x02, 0xa6, 0x02, 0xcd, 0x03,
-				0x01, 0x03, 0x1f, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
-	mipi_dsi_dcs_write_seq(dsi, 0xbb, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
-				0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0xff, 0x21);
-	mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
-	mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x00, 0x00, 0x00, 0x17, 0x00, 0x49, 0x00,
-				0x6a, 0x00, 0x89, 0x00, 0x9f, 0x00, 0xb6, 0x00, 0xc8);
-	mipi_dsi_dcs_write_seq(dsi, 0xb1, 0x00, 0xd9, 0x01, 0x10, 0x01, 0x3a, 0x01,
-				0x7a, 0x01, 0xa9, 0x01, 0xf2, 0x02, 0x2d, 0x02, 0x2e);
-	mipi_dsi_dcs_write_seq(dsi, 0xb2, 0x02, 0x64, 0x02, 0xa3, 0x02, 0xca, 0x03,
-				0x00, 0x03, 0x1e, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
-	mipi_dsi_dcs_write_seq(dsi, 0xb3, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
-				0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0xb4, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
-				0x71, 0x00, 0x90, 0x00, 0xa7, 0x00, 0xbf, 0x00, 0xd1);
-	mipi_dsi_dcs_write_seq(dsi, 0xb5, 0x00, 0xe2, 0x01, 0x1a, 0x01, 0x43, 0x01,
-				0x83, 0x01, 0xb2, 0x01, 0xfa, 0x02, 0x34, 0x02, 0x36);
-	mipi_dsi_dcs_write_seq(dsi, 0xb6, 0x02, 0x6b, 0x02, 0xa8, 0x02, 0xd0, 0x03,
-				0x03, 0x03, 0x21, 0x03, 0x4d, 0x03, 0x5b, 0x03, 0x6b);
-	mipi_dsi_dcs_write_seq(dsi, 0xb7, 0x03, 0x7e, 0x03, 0x94, 0x03, 0xac, 0x03,
-				0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0xb8, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
-				0x72, 0x00, 0x92, 0x00, 0xa8, 0x00, 0xbf, 0x00, 0xd1);
-	mipi_dsi_dcs_write_seq(dsi, 0xb9, 0x00, 0xe2, 0x01, 0x18, 0x01, 0x42, 0x01,
-				0x81, 0x01, 0xaf, 0x01, 0xf5, 0x02, 0x2f, 0x02, 0x31);
-	mipi_dsi_dcs_write_seq(dsi, 0xba, 0x02, 0x68, 0x02, 0xa6, 0x02, 0xcd, 0x03,
-				0x01, 0x03, 0x1f, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
-	mipi_dsi_dcs_write_seq(dsi, 0xbb, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
-				0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
-	mipi_dsi_dcs_write_seq(dsi, 0xff, 0x2c);
-	mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
-	mipi_dsi_dcs_write_seq(dsi, 0x61, 0x1f);
-	mipi_dsi_dcs_write_seq(dsi, 0x62, 0x1f);
-	mipi_dsi_dcs_write_seq(dsi, 0x7e, 0x03);
-	mipi_dsi_dcs_write_seq(dsi, 0x6a, 0x14);
-	mipi_dsi_dcs_write_seq(dsi, 0x6b, 0x36);
-	mipi_dsi_dcs_write_seq(dsi, 0x6c, 0x36);
-	mipi_dsi_dcs_write_seq(dsi, 0x6d, 0x36);
-	mipi_dsi_dcs_write_seq(dsi, 0x53, 0x04);
-	mipi_dsi_dcs_write_seq(dsi, 0x54, 0x04);
-	mipi_dsi_dcs_write_seq(dsi, 0x55, 0x04);
-	mipi_dsi_dcs_write_seq(dsi, 0x56, 0x0f);
-	mipi_dsi_dcs_write_seq(dsi, 0x58, 0x0f);
-	mipi_dsi_dcs_write_seq(dsi, 0x59, 0x0f);
-	mipi_dsi_dcs_write_seq(dsi, 0xff, 0xf0);
-	mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
-	mipi_dsi_dcs_write_seq(dsi, 0x5a, 0x00);
-
-	mipi_dsi_dcs_write_seq(dsi, 0xff, 0x10);
-	mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
-	mipi_dsi_dcs_write_seq(dsi, 0x51, 0xff);
-	mipi_dsi_dcs_write_seq(dsi, 0x53, 0x24);
-	mipi_dsi_dcs_write_seq(dsi, 0x55, 0x01);
-
-	return 0;
+	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,
+				     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,
+				     0x6a, 0x00, 0x89, 0x00, 0x9f, 0x00, 0xb6, 0x00, 0xc8);
+	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,
+				     0x00, 0x03, 0x1e, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
+	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,
+				     0x71, 0x00, 0x90, 0x00, 0xa7, 0x00, 0xbf, 0x00, 0xd1);
+	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,
+				     0x03, 0x03, 0x21, 0x03, 0x4d, 0x03, 0x5b, 0x03, 0x6b);
+	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,
+				     0x72, 0x00, 0x92, 0x00, 0xa8, 0x00, 0xbf, 0x00, 0xd1);
+	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,
+				     0x01, 0x03, 0x1f, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
+	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,
+				     0x6a, 0x00, 0x89, 0x00, 0x9f, 0x00, 0xb6, 0x00, 0xc8);
+	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,
+				     0x00, 0x03, 0x1e, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
+	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,
+				     0x71, 0x00, 0x90, 0x00, 0xa7, 0x00, 0xbf, 0x00, 0xd1);
+	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,
+				     0x03, 0x03, 0x21, 0x03, 0x4d, 0x03, 0x5b, 0x03, 0x6b);
+	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,
+				     0x72, 0x00, 0x92, 0x00, 0xa8, 0x00, 0xbf, 0x00, 0xd1);
+	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,
+				     0x01, 0x03, 0x1f, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
+	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;
 }
 
 static int nt36672e_power_on(struct nt36672e_panel *ctx)
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog


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

* [PATCH v4 7/9] drm/panel: boe-tv101wum-nl6: Don't use a table for initting panels
  2024-05-08 20:51 [PATCH v4 0/9] drm/mipi-dsi: Reduce bloat and add funcs for cleaner init seqs Douglas Anderson
                   ` (5 preceding siblings ...)
  2024-05-08 20:51 ` [PATCH v4 6/9] drm/panel: novatek-nt36672e: Switch to mipi_dsi_dcs_write_seq_multi() Douglas Anderson
@ 2024-05-08 20:51 ` Douglas Anderson
  2024-05-08 20:51 ` [PATCH v4 8/9] drm/panel: ili9882t: " Douglas Anderson
  2024-05-08 20:51 ` [PATCH v4 9/9] drm/panel: innolux-p079zca: " Douglas Anderson
  8 siblings, 0 replies; 14+ messages in thread
From: Douglas Anderson @ 2024-05-08 20:51 UTC (permalink / raw
  To: dri-devel
  Cc: lvzhaoxiong, Jani Nikula, Hsin-Yi Wang, Linus Walleij,
	Javier Martinez Canillas, Neil Armstrong, Cong Yang, Sam Ravnborg,
	Dmitry Baryshkov, Joel Selvaraj, Brian Norris, Douglas Anderson,
	Daniel Vetter, David Airlie, Jessica Zhang, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, linux-kernel

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_prepare                            592     440    -152
auo_b101uan08_3_init_cmd                    1056       -   -1056
starry_himax83102_j02_init_cmd              1392       -   -1392
starry_qfh032011_53g_init_cmd               2256       -   -2256
.compoundliteral                            3393       -   -3393
boe_init_cmd                                7008       -   -7008
boe_tv110c9m_init_cmd                       7656       -   -7656
inx_hj110iz_init_cmd                        8376       -   -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 <linus.walleij@linaro.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---

(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 <video/mipi_display.h>
 
+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(&ctx, 0xff, 0x20);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x05, 0xd9);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x78);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x5a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0d, 0x63);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0e, 0x91);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0f, 0x73);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x95, 0xe6);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x96, 0xf0);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x30, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6d, 0x66);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x75, 0xa2);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x77, 0x3b);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x00, 0x08, 0x00, 0x23, 0x00, 0x4d, 0x00, 0x6d,
+				     0x00, 0x89, 0x00, 0xa1, 0x00, 0xb6, 0x00, 0xc9);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x00, 0xda, 0x01, 0x13, 0x01, 0x3c, 0x01, 0x7e,
+				     0x01, 0xab, 0x01, 0xf7, 0x02, 0x2f, 0x02, 0x31);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x02, 0x67, 0x02, 0xa6, 0x02, 0xd1, 0x03, 0x08,
+				     0x03, 0x2e, 0x03, 0x5b, 0x03, 0x6b, 0x03, 0x7b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x03, 0x8e, 0x03, 0xa2, 0x03, 0xb7, 0x03, 0xe7,
+				     0x03, 0xfd, 0x03, 0xff);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x00, 0x08, 0x00, 0x23, 0x00, 0x4d, 0x00, 0x6d,
+				     0x00, 0x89, 0x00, 0xa1, 0x00, 0xb6, 0x00, 0xc9);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x00, 0xda, 0x01, 0x13, 0x01, 0x3c, 0x01, 0x7e,
+				     0x01, 0xab, 0x01, 0xf7, 0x02, 0x2f, 0x02, 0x31);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x02, 0x67, 0x02, 0xa6, 0x02, 0xd1, 0x03, 0x08,
+				     0x03, 0x2e, 0x03, 0x5b, 0x03, 0x6b, 0x03, 0x7b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x03, 0x8e, 0x03, 0xa2, 0x03, 0xb7, 0x03, 0xe7,
+				     0x03, 0xfd, 0x03, 0xff);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x00, 0x08, 0x00, 0x23, 0x00, 0x4d, 0x00, 0x6d,
+				     0x00, 0x89, 0x00, 0xa1, 0x00, 0xb6, 0x00, 0xc9);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0x00, 0xda, 0x01, 0x13, 0x01, 0x3c, 0x01, 0x7e,
+				     0x01, 0xab, 0x01, 0xf7, 0x02, 0x2f, 0x02, 0x31);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x02, 0x67, 0x02, 0xa6, 0x02, 0xd1, 0x03, 0x08,
+				     0x03, 0x2e, 0x03, 0x5b, 0x03, 0x6b, 0x03, 0x7b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0x03, 0x8e, 0x03, 0xa2, 0x03, 0xb7, 0x03, 0xe7,
+				     0x03, 0xfd, 0x03, 0xff);
+
+	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, 0x1b, 0x00, 0x45, 0x00, 0x65,
+				     0x00, 0x81, 0x00, 0x99, 0x00, 0xae, 0x00, 0xc1);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x00, 0xd2, 0x01, 0x0b, 0x01, 0x34, 0x01, 0x76,
+				     0x01, 0xa3, 0x01, 0xef, 0x02, 0x27, 0x02, 0x29);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x02, 0x5f, 0x02, 0x9e, 0x02, 0xc9, 0x03, 0x00,
+				     0x03, 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x03, 0x86, 0x03, 0x9a, 0x03, 0xaf, 0x03, 0xdf,
+				     0x03, 0xf5, 0x03, 0xe0);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x45, 0x00, 0x65,
+				     0x00, 0x81, 0x00, 0x99, 0x00, 0xae, 0x00, 0xc1);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x00, 0xd2, 0x01, 0x0b, 0x01, 0x34, 0x01, 0x76,
+				     0x01, 0xa3, 0x01, 0xef, 0x02, 0x27, 0x02, 0x29);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x02, 0x5f, 0x02, 0x9e, 0x02, 0xc9, 0x03, 0x00,
+				     0x03, 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x03, 0x86, 0x03, 0x9a, 0x03, 0xaf, 0x03, 0xdf,
+				     0x03, 0xf5, 0x03, 0xe0);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x45, 0x00, 0x65,
+				     0x00, 0x81, 0x00, 0x99, 0x00, 0xae, 0x00, 0xc1);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0x00, 0xd2, 0x01, 0x0b, 0x01, 0x34, 0x01, 0x76,
+				     0x01, 0xa3, 0x01, 0xef, 0x02, 0x27, 0x02, 0x29);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x02, 0x5f, 0x02, 0x9e, 0x02, 0xc9, 0x03, 0x00,
+				     0x03, 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0x03, 0x86, 0x03, 0x9a, 0x03, 0xaf, 0x03, 0xdf,
+				     0x03, 0xf5, 0x03, 0xe0);
+	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, 0x00, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x01, 0x00);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x02, 0x1c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x03, 0x1c);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x1d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x05, 0x1d);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x04);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x0f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x09, 0x0f);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0a, 0x0e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0b, 0x0e);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0c, 0x0d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0d, 0x0d);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0e, 0x0c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0f, 0x0c);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x10, 0x08);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x11, 0x08);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x12, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x13, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x14, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x15, 0x00);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x16, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x17, 0x00);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x18, 0x1c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x19, 0x1c);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1a, 0x1d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1b, 0x1d);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1c, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1d, 0x04);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1e, 0x0f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1f, 0x0f);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x0e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x21, 0x0e);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x22, 0x0d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x23, 0x0d);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x24, 0x0c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x0c);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0x08);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x08);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x28, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x29, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2b, 0x00);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2d, 0x20);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2f, 0x0a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x30, 0x44);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x33, 0x0c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x34, 0x32);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x37, 0x44);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x38, 0x40);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x39, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x5d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3b, 0x60);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3d, 0x42);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3f, 0x06);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x43, 0x06);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x47, 0x66);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4a, 0x5d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4b, 0x60);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4c, 0x91);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4d, 0x21);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4e, 0x43);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x51, 0x12);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x52, 0x34);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x55, 0x82, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x56, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x58, 0x21);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x59, 0x30);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5a, 0x60);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5b, 0x50);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5e, 0x00, 0x06);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5f, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x65, 0x82);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7e, 0x20);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7f, 0x3c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x82, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x97, 0xc0);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
+				     0x05, 0x05, 0x00, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x91, 0x44);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x92, 0xa9);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x93, 0x1a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x94, 0x96);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd7, 0x55);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xda, 0x0a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xde, 0x08);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdb, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdc, 0xa9);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdd, 0x22);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdf, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe0, 0xa9);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe1, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe2, 0xa9);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe3, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe4, 0xa9);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe6, 0xa9);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5c, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5d, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x8d, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x8e, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x90);
+	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, 0x05, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x19, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1f, 0x60);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x50);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0x60);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x50);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x33, 0x60);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x34, 0x50);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3f, 0xe0);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x40, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x44, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x45, 0x40);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x48, 0x60);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x49, 0x50);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5b, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5c, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5d, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5e, 0xd0);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x61, 0x60);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x62, 0x50);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xf1, 0x10);
+	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, 0x64, 0x16);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x67, 0x16);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6a, 0x16);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x70, 0x30);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa2, 0xf3);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa3, 0xff);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa4, 0xff);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa5, 0xff);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd6, 0x08);
+
+	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, 0x00, 0xa1);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x02, 0x31);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x28);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0x30);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0c, 0x16);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0d, 0x0d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0f, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x11, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x12, 0x50);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x13, 0x56);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x14, 0x57);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x15, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x16, 0x10);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x17, 0xa0);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x18, 0x86);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x19, 0x0d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1a, 0x7f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1b, 0x0c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1c, 0xbf);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x22, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x23, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x0d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2b, 0x7f);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1d, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1e, 0x65);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1f, 0x65);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x24, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x65);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2f, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x30, 0x65);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x31, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x32, 0x7d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x39, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x65);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x33, 0x11);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x34, 0x78);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x16);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x9e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x4e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x00);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa9, 0x49);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xaa, 0x4b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xab, 0x48);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xac, 0x43);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xad, 0x40);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xae, 0x50);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xaf, 0x44);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x54);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x4e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x4d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x4c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x41);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x47);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x53);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x3e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x51);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0x3c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x3b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0x46);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbc, 0x45);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x55);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbe, 0x3d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbf, 0x3f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x52);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x4a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0x39);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0x4f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0x3a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0x42);
+	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, 0x56, 0x06);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x58, 0x80);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x59, 0x75);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5a, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5b, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5c, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5d, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5e, 0x20);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5f, 0x10);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x60, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x61, 0x2e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x62, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x63, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x64, 0x43);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x65, 0x2d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x66, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x67, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x68, 0x44);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x78, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0x00);
+
+	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, 0x22, 0x2f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x23, 0x08);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x24, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x65);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0xf8);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x28, 0x1a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x29, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x1a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2b, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2d, 0x1a);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x23);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x80);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x00);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0xe0);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x14, 0x60);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x16, 0xc0);
+
+	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, 0x3a, 0x08);
+
+	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, 0xb9, 0x01);
+	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, 0x18, 0x40);
+
+	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, 0xb9, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x51, 0x00, 0xff);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x53, 0x24);
+	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_dcs_write_seq_multi(&ctx, 0x11);
+	if (ctx.accum_err)
+		return ctx.accum_err;
+
+	msleep(200);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x29);
+	if (ctx.accum_err)
+		return ctx.accum_err;
+
+	msleep(100);
 
-struct panel_init_cmd {
-	enum dsi_cmd_type type;
-	size_t len;
-	const char *data;
+	return 0;
 };
 
-#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__} }
-
-static const struct panel_init_cmd boe_tv110c9m_init_cmd[] = {
-	_INIT_DCS_CMD(0xFF, 0x20),
-	_INIT_DCS_CMD(0xFB, 0x01),
-	_INIT_DCS_CMD(0x05, 0xD9),
-	_INIT_DCS_CMD(0x07, 0x78),
-	_INIT_DCS_CMD(0x08, 0x5A),
-	_INIT_DCS_CMD(0x0D, 0x63),
-	_INIT_DCS_CMD(0x0E, 0x91),
-	_INIT_DCS_CMD(0x0F, 0x73),
-	_INIT_DCS_CMD(0x95, 0xE6),
-	_INIT_DCS_CMD(0x96, 0xF0),
-	_INIT_DCS_CMD(0x30, 0x00),
-	_INIT_DCS_CMD(0x6D, 0x66),
-	_INIT_DCS_CMD(0x75, 0xA2),
-	_INIT_DCS_CMD(0x77, 0x3B),
+static int inx_hj110iz_init(struct boe_panel *boe)
+{
+	struct mipi_dsi_multi_context ctx = { .dsi = boe->dsi };
+
+	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, 0x05, 0xd1);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0xc0);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x87);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x4b);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0d, 0x63);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0e, 0x91);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0f, 0x69);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x94, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x95, 0xf5);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x96, 0xf5);
+	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, 0x69, 0x98);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x75, 0xa2);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x77, 0xb3);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x58, 0x43);
+	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, 0x91, 0x44);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x92, 0x4c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x94, 0x86);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x60, 0x96);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x61, 0xd0);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x63, 0x70);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0xca);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x01, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x02, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x03, 0x29);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x22);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x05, 0x22);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0x0b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x1d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x1c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x09, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0a, 0x08);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0b, 0x09);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0c, 0x0a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0d, 0x0c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0e, 0x0d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0f, 0x0e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x10, 0x0f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x11, 0x10);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x12, 0x11);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x13, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x14, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x15, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x16, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x17, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x18, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x19, 0x29);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1a, 0x22);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1b, 0x22);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1c, 0x0b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1d, 0x1d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1e, 0x1c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1f, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x08);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x21, 0x09);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x22, 0x0a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x23, 0x0c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x24, 0x0d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x0e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0x0f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x10);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x28, 0x11);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x29, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2b, 0x03);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2f, 0x0a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x30, 0x35);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x37, 0xa7);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x39, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x46);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3b, 0x32);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3d, 0x12);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3f, 0x33);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x40, 0x31);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x41, 0x40);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x42, 0x42);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x47, 0x77);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x48, 0x77);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4a, 0x45);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4b, 0x45);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4c, 0x14);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4d, 0x21);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4e, 0x43);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4f, 0x65);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x55, 0x06);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x56, 0x06);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x58, 0x21);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x59, 0x70);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5a, 0x46);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5b, 0x32);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5c, 0x88);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5e, 0x00, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5f, 0x00);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7a, 0xff);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7b, 0xff);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7c, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7d, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7e, 0x20);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7f, 0x3c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x80, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x81, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x82, 0x08);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x97, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0x10);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd7, 0x55);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd8, 0x55);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd9, 0x23);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xda, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdb, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdc, 0x65);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdd, 0x55);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xde, 0x27);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdf, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe0, 0x65);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe1, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe2, 0x65);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe3, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe4, 0x65);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe6, 0x65);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe7, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe8, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe9, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xea, 0x65);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xeb, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xee, 0x65);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xef, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xf0, 0x65);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
+				     0x05, 0x05, 0x00, 0x00);
+
+	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, 0x05, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xf1, 0x10);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1e, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1f, 0x46);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x32);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0x46);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x32);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3f, 0x80);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x40, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x43, 0x00);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x44, 0x46);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x45, 0x46);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x48, 0x46);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x49, 0x32);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5b, 0x80);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5c, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5d, 0x46);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5e, 0x32);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5f, 0x46);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x60, 0x32);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x61, 0x46);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x62, 0x32);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x68, 0x0c);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6c, 0x0d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6e, 0x0d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x78, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x79, 0xc5);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7a, 0x0c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7b, 0xb0);
+
+	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, 0x00, 0xa1);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x02, 0x31);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0a, 0xf4);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x50);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0x30);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0c, 0x16);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0d, 0x0d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0f, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x11, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x12, 0x50);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x13, 0x40);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x14, 0x58);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x15, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x16, 0x10);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x17, 0xa0);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x18, 0x86);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x22, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x23, 0x00);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x19, 0x0e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1a, 0x31);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1b, 0x0d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1c, 0x29);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x0e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2b, 0x31);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1d, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1e, 0x62);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1f, 0x62);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2f, 0x06);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x30, 0x62);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x31, 0x06);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x32, 0x7f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x33, 0x11);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x34, 0x89);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x67);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x39, 0x0b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x62);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3b, 0x06);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x89);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x4e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa9, 0x3f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xaa, 0x3e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xab, 0x3d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xac, 0x3c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xad, 0x3b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xae, 0x3a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xaf, 0x39);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x38);
+
+	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, 0xd0, 0x11);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd1, 0x54);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xde, 0x43);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdf, 0x02);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x18);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x56, 0x06);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x58, 0x80);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x59, 0x78);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5a, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5b, 0x18);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5c, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5d, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5e, 0x20);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5f, 0x10);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x60, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x61, 0x1c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x62, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x63, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x64, 0x44);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x65, 0x1b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x66, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x67, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x68, 0x44);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x98, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x9b, 0xbe);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xab, 0x14);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbc, 0x08);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 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, 0x22, 0x2f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x23, 0x08);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x24, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x62);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0xf8);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x28, 0x1a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x29, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x1a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2b, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2d, 0x1a);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x64, 0x96);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x65, 0x10);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x66, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x67, 0x96);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x68, 0x10);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x69, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6a, 0x96);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6b, 0x10);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6c, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x70, 0x92);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x71, 0x10);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x72, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x79, 0x96);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7a, 0x10);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x88, 0x96);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x89, 0x10);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa2, 0x3f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa3, 0x30);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa4, 0xc0);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa5, 0x03);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe8, 0x00);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x97, 0x3c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x98, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x99, 0x95);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x9a, 0x06);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x9b, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x9c, 0x0b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x9d, 0x0a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x9e, 0x90);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x25);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x13, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x14, 0xd7);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdb, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdc, 0xd7);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x17, 0xcf);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x19, 0x0f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1b, 0x5b);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x20);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x24, 0x00, 0x38,
+				     0x00, 0x4c, 0x00, 0x5e, 0x00, 0x6f, 0x00, 0x7e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x00, 0x8c, 0x00, 0xbe, 0x00, 0xe5, 0x01, 0x27,
+				     0x01, 0x58, 0x01, 0xa8, 0x01, 0xe8, 0x01, 0xea);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x02, 0x28, 0x02, 0x71, 0x02, 0x9e, 0x02, 0xda,
+				     0x03, 0x00, 0x03, 0x31, 0x03, 0x40, 0x03, 0x51);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x03, 0x62, 0x03, 0x75, 0x03, 0x89, 0x03, 0x9c,
+				     0x03, 0xaa, 0x03, 0xb2);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x27, 0x00, 0x3d,
+				     0x00, 0x52, 0x00, 0x64, 0x00, 0x75, 0x00, 0x84);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x00, 0x93, 0x00, 0xc5, 0x00, 0xec, 0x01, 0x2c,
+				     0x01, 0x5d, 0x01, 0xac, 0x01, 0xec, 0x01, 0xee);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x02, 0x2b, 0x02, 0x73, 0x02, 0xa0, 0x02, 0xdb,
+				     0x03, 0x01, 0x03, 0x31, 0x03, 0x41, 0x03, 0x51);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x03, 0x63, 0x03, 0x75, 0x03, 0x89, 0x03, 0x9c,
+				     0x03, 0xaa, 0x03, 0xb2);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x2a, 0x00, 0x40,
+				     0x00, 0x56, 0x00, 0x68, 0x00, 0x7a, 0x00, 0x89);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0x00, 0x98, 0x00, 0xc9, 0x00, 0xf1, 0x01, 0x30,
+				     0x01, 0x61, 0x01, 0xb0, 0x01, 0xef, 0x01, 0xf1);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x02, 0x2e, 0x02, 0x76, 0x02, 0xa3, 0x02, 0xdd,
+				     0x03, 0x02, 0x03, 0x32, 0x03, 0x42, 0x03, 0x53);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0x03, 0x66, 0x03, 0x75, 0x03, 0x89, 0x03, 0x9c,
+				     0x03, 0xaa, 0x03, 0xb2);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x21);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x24, 0x00, 0x38,
+				     0x00, 0x4c, 0x00, 0x5e, 0x00, 0x6f, 0x00, 0x7e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x00, 0x8c, 0x00, 0xbe, 0x00, 0xe5, 0x01, 0x27,
+				     0x01, 0x58, 0x01, 0xa8, 0x01, 0xe8, 0x01, 0xea);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x02, 0x28, 0x02, 0x71, 0x02, 0x9e, 0x02, 0xda,
+				     0x03, 0x00, 0x03, 0x31, 0x03, 0x40, 0x03, 0x51);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x03, 0x62, 0x03, 0x77, 0x03, 0x90, 0x03, 0xac,
+				     0x03, 0xca, 0x03, 0xda);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x27, 0x00, 0x3d,
+				     0x00, 0x52, 0x00, 0x64, 0x00, 0x75, 0x00, 0x84);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x00, 0x93, 0x00, 0xc5, 0x00, 0xec, 0x01, 0x2c,
+				     0x01, 0x5d, 0x01, 0xac, 0x01, 0xec, 0x01, 0xee);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x02, 0x2b, 0x02, 0x73, 0x02, 0xa0, 0x02, 0xdb,
+				     0x03, 0x01, 0x03, 0x31, 0x03, 0x41, 0x03, 0x51);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x03, 0x63, 0x03, 0x77, 0x03, 0x90, 0x03, 0xac,
+				     0x03, 0xca, 0x03, 0xda);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x2a, 0x00, 0x40,
+				     0x00, 0x56, 0x00, 0x68, 0x00, 0x7a, 0x00, 0x89);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0x00, 0x98, 0x00, 0xc9, 0x00, 0xf1, 0x01, 0x30,
+				     0x01, 0x61, 0x01, 0xb0, 0x01, 0xef, 0x01, 0xf1);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x02, 0x2e, 0x02, 0x76, 0x02, 0xa3, 0x02, 0xdd,
+				     0x03, 0x02, 0x03, 0x32, 0x03, 0x42, 0x03, 0x53);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0x03, 0x66, 0x03, 0x77, 0x03, 0x90, 0x03, 0xac,
+				     0x03, 0xca, 0x03, 0xda);
+
+	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, 0x3a, 0x08);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x10);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0x01);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x20);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x18, 0x40);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x10);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 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, 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_dcs_write_seq_multi(&ctx, 0x11);
+	if (ctx.accum_err)
+		return ctx.accum_err;
+
+	msleep(200);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x29);
+	if (ctx.accum_err)
+		return ctx.accum_err;
+
+	msleep(100);
 
-	_INIT_DCS_CMD(0xB0, 0x00, 0x08, 0x00, 0x23, 0x00, 0x4D, 0x00, 0x6D, 0x00, 0x89, 0x00, 0xA1, 0x00, 0xB6, 0x00, 0xC9),
-	_INIT_DCS_CMD(0xB1, 0x00, 0xDA, 0x01, 0x13, 0x01, 0x3C, 0x01, 0x7E, 0x01, 0xAB, 0x01, 0xF7, 0x02, 0x2F, 0x02, 0x31),
-	_INIT_DCS_CMD(0xB2, 0x02, 0x67, 0x02, 0xA6, 0x02, 0xD1, 0x03, 0x08, 0x03, 0x2E, 0x03, 0x5B, 0x03, 0x6B, 0x03, 0x7B),
-	_INIT_DCS_CMD(0xB3, 0x03, 0x8E, 0x03, 0xA2, 0x03, 0xB7, 0x03, 0xE7, 0x03, 0xFD, 0x03, 0xFF),
-
-	_INIT_DCS_CMD(0xB4, 0x00, 0x08, 0x00, 0x23, 0x00, 0x4D, 0x00, 0x6D, 0x00, 0x89, 0x00, 0xA1, 0x00, 0xB6, 0x00, 0xC9),
-	_INIT_DCS_CMD(0xB5, 0x00, 0xDA, 0x01, 0x13, 0x01, 0x3C, 0x01, 0x7E, 0x01, 0xAB, 0x01, 0xF7, 0x02, 0x2F, 0x02, 0x31),
-	_INIT_DCS_CMD(0xB6, 0x02, 0x67, 0x02, 0xA6, 0x02, 0xD1, 0x03, 0x08, 0x03, 0x2E, 0x03, 0x5B, 0x03, 0x6B, 0x03, 0x7B),
-	_INIT_DCS_CMD(0xB7, 0x03, 0x8E, 0x03, 0xA2, 0x03, 0xB7, 0x03, 0xE7, 0x03, 0xFD, 0x03, 0xFF),
-	_INIT_DCS_CMD(0xB8, 0x00, 0x08, 0x00, 0x23, 0x00, 0x4D, 0x00, 0x6D, 0x00, 0x89, 0x00, 0xA1, 0x00, 0xB6, 0x00, 0xC9),
-	_INIT_DCS_CMD(0xB9, 0x00, 0xDA, 0x01, 0x13, 0x01, 0x3C, 0x01, 0x7E, 0x01, 0xAB, 0x01, 0xF7, 0x02, 0x2F, 0x02, 0x31),
-	_INIT_DCS_CMD(0xBA, 0x02, 0x67, 0x02, 0xA6, 0x02, 0xD1, 0x03, 0x08, 0x03, 0x2E, 0x03, 0x5B, 0x03, 0x6B, 0x03, 0x7B),
-	_INIT_DCS_CMD(0xBB, 0x03, 0x8E, 0x03, 0xA2, 0x03, 0xB7, 0x03, 0xE7, 0x03, 0xFD, 0x03, 0xFF),
-
-	_INIT_DCS_CMD(0xFF, 0x21),
-	_INIT_DCS_CMD(0xFB, 0x01),
-
-	_INIT_DCS_CMD(0xB0, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x45, 0x00, 0x65, 0x00, 0x81, 0x00, 0x99, 0x00, 0xAE, 0x00, 0xC1),
-	_INIT_DCS_CMD(0xB1, 0x00, 0xD2, 0x01, 0x0B, 0x01, 0x34, 0x01, 0x76, 0x01, 0xA3, 0x01, 0xEF, 0x02, 0x27, 0x02, 0x29),
-	_INIT_DCS_CMD(0xB2, 0x02, 0x5F, 0x02, 0x9E, 0x02, 0xC9, 0x03, 0x00, 0x03, 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73),
-
-	_INIT_DCS_CMD(0xB3, 0x03, 0x86, 0x03, 0x9A, 0x03, 0xAF, 0x03, 0xDF, 0x03, 0xF5, 0x03, 0xE0),
-	_INIT_DCS_CMD(0xB4, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x45, 0x00, 0x65, 0x00, 0x81, 0x00, 0x99, 0x00, 0xAE, 0x00, 0xC1),
-	_INIT_DCS_CMD(0xB5, 0x00, 0xD2, 0x01, 0x0B, 0x01, 0x34, 0x01, 0x76, 0x01, 0xA3, 0x01, 0xEF, 0x02, 0x27, 0x02, 0x29),
-	_INIT_DCS_CMD(0xB6, 0x02, 0x5F, 0x02, 0x9E, 0x02, 0xC9, 0x03, 0x00, 0x03, 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73),
-	_INIT_DCS_CMD(0xB7, 0x03, 0x86, 0x03, 0x9A, 0x03, 0xAF, 0x03, 0xDF, 0x03, 0xF5, 0x03, 0xE0),
-
-	_INIT_DCS_CMD(0xB8, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x45, 0x00, 0x65, 0x00, 0x81, 0x00, 0x99, 0x00, 0xAE, 0x00, 0xC1),
-	_INIT_DCS_CMD(0xB9, 0x00, 0xD2, 0x01, 0x0B, 0x01, 0x34, 0x01, 0x76, 0x01, 0xA3, 0x01, 0xEF, 0x02, 0x27, 0x02, 0x29),
-	_INIT_DCS_CMD(0xBA, 0x02, 0x5F, 0x02, 0x9E, 0x02, 0xC9, 0x03, 0x00, 0x03, 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73),
-
-	_INIT_DCS_CMD(0xBB, 0x03, 0x86, 0x03, 0x9A, 0x03, 0xAF, 0x03, 0xDF, 0x03, 0xF5, 0x03, 0xE0),
-	_INIT_DCS_CMD(0xFF, 0x24),
-	_INIT_DCS_CMD(0xFB, 0x01),
-
-	_INIT_DCS_CMD(0x00, 0x00),
-	_INIT_DCS_CMD(0x01, 0x00),
-
-	_INIT_DCS_CMD(0x02, 0x1C),
-	_INIT_DCS_CMD(0x03, 0x1C),
-
-	_INIT_DCS_CMD(0x04, 0x1D),
-	_INIT_DCS_CMD(0x05, 0x1D),
-
-	_INIT_DCS_CMD(0x06, 0x04),
-	_INIT_DCS_CMD(0x07, 0x04),
-
-	_INIT_DCS_CMD(0x08, 0x0F),
-	_INIT_DCS_CMD(0x09, 0x0F),
-
-	_INIT_DCS_CMD(0x0A, 0x0E),
-	_INIT_DCS_CMD(0x0B, 0x0E),
-
-	_INIT_DCS_CMD(0x0C, 0x0D),
-	_INIT_DCS_CMD(0x0D, 0x0D),
-
-	_INIT_DCS_CMD(0x0E, 0x0C),
-	_INIT_DCS_CMD(0x0F, 0x0C),
-
-	_INIT_DCS_CMD(0x10, 0x08),
-	_INIT_DCS_CMD(0x11, 0x08),
-
-	_INIT_DCS_CMD(0x12, 0x00),
-	_INIT_DCS_CMD(0x13, 0x00),
-	_INIT_DCS_CMD(0x14, 0x00),
-	_INIT_DCS_CMD(0x15, 0x00),
-
-	_INIT_DCS_CMD(0x16, 0x00),
-	_INIT_DCS_CMD(0x17, 0x00),
-
-	_INIT_DCS_CMD(0x18, 0x1C),
-	_INIT_DCS_CMD(0x19, 0x1C),
-
-	_INIT_DCS_CMD(0x1A, 0x1D),
-	_INIT_DCS_CMD(0x1B, 0x1D),
-
-	_INIT_DCS_CMD(0x1C, 0x04),
-	_INIT_DCS_CMD(0x1D, 0x04),
-
-	_INIT_DCS_CMD(0x1E, 0x0F),
-	_INIT_DCS_CMD(0x1F, 0x0F),
-
-	_INIT_DCS_CMD(0x20, 0x0E),
-	_INIT_DCS_CMD(0x21, 0x0E),
-
-	_INIT_DCS_CMD(0x22, 0x0D),
-	_INIT_DCS_CMD(0x23, 0x0D),
-
-	_INIT_DCS_CMD(0x24, 0x0C),
-	_INIT_DCS_CMD(0x25, 0x0C),
-
-	_INIT_DCS_CMD(0x26, 0x08),
-	_INIT_DCS_CMD(0x27, 0x08),
-
-	_INIT_DCS_CMD(0x28, 0x00),
-	_INIT_DCS_CMD(0x29, 0x00),
-	_INIT_DCS_CMD(0x2A, 0x00),
-	_INIT_DCS_CMD(0x2B, 0x00),
-
-	_INIT_DCS_CMD(0x2D, 0x20),
-	_INIT_DCS_CMD(0x2F, 0x0A),
-	_INIT_DCS_CMD(0x30, 0x44),
-	_INIT_DCS_CMD(0x33, 0x0C),
-	_INIT_DCS_CMD(0x34, 0x32),
-
-	_INIT_DCS_CMD(0x37, 0x44),
-	_INIT_DCS_CMD(0x38, 0x40),
-	_INIT_DCS_CMD(0x39, 0x00),
-	_INIT_DCS_CMD(0x3A, 0x5D),
-	_INIT_DCS_CMD(0x3B, 0x60),
-	_INIT_DCS_CMD(0x3D, 0x42),
-	_INIT_DCS_CMD(0x3F, 0x06),
-	_INIT_DCS_CMD(0x43, 0x06),
-	_INIT_DCS_CMD(0x47, 0x66),
-	_INIT_DCS_CMD(0x4A, 0x5D),
-	_INIT_DCS_CMD(0x4B, 0x60),
-	_INIT_DCS_CMD(0x4C, 0x91),
-	_INIT_DCS_CMD(0x4D, 0x21),
-	_INIT_DCS_CMD(0x4E, 0x43),
-	_INIT_DCS_CMD(0x51, 0x12),
-	_INIT_DCS_CMD(0x52, 0x34),
-	_INIT_DCS_CMD(0x55, 0x82, 0x02),
-	_INIT_DCS_CMD(0x56, 0x04),
-	_INIT_DCS_CMD(0x58, 0x21),
-	_INIT_DCS_CMD(0x59, 0x30),
-	_INIT_DCS_CMD(0x5A, 0x60),
-	_INIT_DCS_CMD(0x5B, 0x50),
-	_INIT_DCS_CMD(0x5E, 0x00, 0x06),
-	_INIT_DCS_CMD(0x5F, 0x00),
-	_INIT_DCS_CMD(0x65, 0x82),
-	_INIT_DCS_CMD(0x7E, 0x20),
-	_INIT_DCS_CMD(0x7F, 0x3C),
-	_INIT_DCS_CMD(0x82, 0x04),
-	_INIT_DCS_CMD(0x97, 0xC0),
-
-	_INIT_DCS_CMD(0xB6, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00),
-	_INIT_DCS_CMD(0x91, 0x44),
-	_INIT_DCS_CMD(0x92, 0xA9),
-	_INIT_DCS_CMD(0x93, 0x1A),
-	_INIT_DCS_CMD(0x94, 0x96),
-	_INIT_DCS_CMD(0xD7, 0x55),
-	_INIT_DCS_CMD(0xDA, 0x0A),
-	_INIT_DCS_CMD(0xDE, 0x08),
-	_INIT_DCS_CMD(0xDB, 0x05),
-	_INIT_DCS_CMD(0xDC, 0xA9),
-	_INIT_DCS_CMD(0xDD, 0x22),
-
-	_INIT_DCS_CMD(0xDF, 0x05),
-	_INIT_DCS_CMD(0xE0, 0xA9),
-	_INIT_DCS_CMD(0xE1, 0x05),
-	_INIT_DCS_CMD(0xE2, 0xA9),
-	_INIT_DCS_CMD(0xE3, 0x05),
-	_INIT_DCS_CMD(0xE4, 0xA9),
-	_INIT_DCS_CMD(0xE5, 0x05),
-	_INIT_DCS_CMD(0xE6, 0xA9),
-	_INIT_DCS_CMD(0x5C, 0x00),
-	_INIT_DCS_CMD(0x5D, 0x00),
-	_INIT_DCS_CMD(0x8D, 0x00),
-	_INIT_DCS_CMD(0x8E, 0x00),
-	_INIT_DCS_CMD(0xB5, 0x90),
-	_INIT_DCS_CMD(0xFF, 0x25),
-	_INIT_DCS_CMD(0xFB, 0x01),
-	_INIT_DCS_CMD(0x05, 0x00),
-	_INIT_DCS_CMD(0x19, 0x07),
-	_INIT_DCS_CMD(0x1F, 0x60),
-	_INIT_DCS_CMD(0x20, 0x50),
-	_INIT_DCS_CMD(0x26, 0x60),
-	_INIT_DCS_CMD(0x27, 0x50),
-	_INIT_DCS_CMD(0x33, 0x60),
-	_INIT_DCS_CMD(0x34, 0x50),
-	_INIT_DCS_CMD(0x3F, 0xE0),
-	_INIT_DCS_CMD(0x40, 0x00),
-	_INIT_DCS_CMD(0x44, 0x00),
-	_INIT_DCS_CMD(0x45, 0x40),
-	_INIT_DCS_CMD(0x48, 0x60),
-	_INIT_DCS_CMD(0x49, 0x50),
-	_INIT_DCS_CMD(0x5B, 0x00),
-	_INIT_DCS_CMD(0x5C, 0x00),
-	_INIT_DCS_CMD(0x5D, 0x00),
-	_INIT_DCS_CMD(0x5E, 0xD0),
-	_INIT_DCS_CMD(0x61, 0x60),
-	_INIT_DCS_CMD(0x62, 0x50),
-	_INIT_DCS_CMD(0xF1, 0x10),
-	_INIT_DCS_CMD(0xFF, 0x2A),
-	_INIT_DCS_CMD(0xFB, 0x01),
-
-	_INIT_DCS_CMD(0x64, 0x16),
-	_INIT_DCS_CMD(0x67, 0x16),
-	_INIT_DCS_CMD(0x6A, 0x16),
-
-	_INIT_DCS_CMD(0x70, 0x30),
-
-	_INIT_DCS_CMD(0xA2, 0xF3),
-	_INIT_DCS_CMD(0xA3, 0xFF),
-	_INIT_DCS_CMD(0xA4, 0xFF),
-	_INIT_DCS_CMD(0xA5, 0xFF),
-
-	_INIT_DCS_CMD(0xD6, 0x08),
-
-	_INIT_DCS_CMD(0xFF, 0x26),
-	_INIT_DCS_CMD(0xFB, 0x01),
-	_INIT_DCS_CMD(0x00, 0xA1),
-
-	_INIT_DCS_CMD(0x02, 0x31),
-	_INIT_DCS_CMD(0x04, 0x28),
-	_INIT_DCS_CMD(0x06, 0x30),
-	_INIT_DCS_CMD(0x0C, 0x16),
-	_INIT_DCS_CMD(0x0D, 0x0D),
-	_INIT_DCS_CMD(0x0F, 0x00),
-	_INIT_DCS_CMD(0x11, 0x00),
-	_INIT_DCS_CMD(0x12, 0x50),
-	_INIT_DCS_CMD(0x13, 0x56),
-	_INIT_DCS_CMD(0x14, 0x57),
-	_INIT_DCS_CMD(0x15, 0x00),
-	_INIT_DCS_CMD(0x16, 0x10),
-	_INIT_DCS_CMD(0x17, 0xA0),
-	_INIT_DCS_CMD(0x18, 0x86),
-	_INIT_DCS_CMD(0x19, 0x0D),
-	_INIT_DCS_CMD(0x1A, 0x7F),
-	_INIT_DCS_CMD(0x1B, 0x0C),
-	_INIT_DCS_CMD(0x1C, 0xBF),
-	_INIT_DCS_CMD(0x22, 0x00),
-	_INIT_DCS_CMD(0x23, 0x00),
-	_INIT_DCS_CMD(0x2A, 0x0D),
-	_INIT_DCS_CMD(0x2B, 0x7F),
-
-	_INIT_DCS_CMD(0x1D, 0x00),
-	_INIT_DCS_CMD(0x1E, 0x65),
-	_INIT_DCS_CMD(0x1F, 0x65),
-	_INIT_DCS_CMD(0x24, 0x00),
-	_INIT_DCS_CMD(0x25, 0x65),
-	_INIT_DCS_CMD(0x2F, 0x05),
-	_INIT_DCS_CMD(0x30, 0x65),
-	_INIT_DCS_CMD(0x31, 0x05),
-	_INIT_DCS_CMD(0x32, 0x7D),
-	_INIT_DCS_CMD(0x39, 0x00),
-	_INIT_DCS_CMD(0x3A, 0x65),
-	_INIT_DCS_CMD(0x20, 0x01),
-	_INIT_DCS_CMD(0x33, 0x11),
-	_INIT_DCS_CMD(0x34, 0x78),
-	_INIT_DCS_CMD(0x35, 0x16),
-	_INIT_DCS_CMD(0xC8, 0x04),
-	_INIT_DCS_CMD(0xC9, 0x9E),
-	_INIT_DCS_CMD(0xCA, 0x4E),
-	_INIT_DCS_CMD(0xCB, 0x00),
-
-	_INIT_DCS_CMD(0xA9, 0x49),
-	_INIT_DCS_CMD(0xAA, 0x4B),
-	_INIT_DCS_CMD(0xAB, 0x48),
-	_INIT_DCS_CMD(0xAC, 0x43),
-	_INIT_DCS_CMD(0xAD, 0x40),
-	_INIT_DCS_CMD(0xAE, 0x50),
-	_INIT_DCS_CMD(0xAF, 0x44),
-	_INIT_DCS_CMD(0xB0, 0x54),
-	_INIT_DCS_CMD(0xB1, 0x4E),
-	_INIT_DCS_CMD(0xB2, 0x4D),
-	_INIT_DCS_CMD(0xB3, 0x4C),
-	_INIT_DCS_CMD(0xB4, 0x41),
-	_INIT_DCS_CMD(0xB5, 0x47),
-	_INIT_DCS_CMD(0xB6, 0x53),
-	_INIT_DCS_CMD(0xB7, 0x3E),
-	_INIT_DCS_CMD(0xB8, 0x51),
-	_INIT_DCS_CMD(0xB9, 0x3C),
-	_INIT_DCS_CMD(0xBA, 0x3B),
-	_INIT_DCS_CMD(0xBB, 0x46),
-	_INIT_DCS_CMD(0xBC, 0x45),
-	_INIT_DCS_CMD(0xBD, 0x55),
-	_INIT_DCS_CMD(0xBE, 0x3D),
-	_INIT_DCS_CMD(0xBF, 0x3F),
-	_INIT_DCS_CMD(0xC0, 0x52),
-	_INIT_DCS_CMD(0xC1, 0x4A),
-	_INIT_DCS_CMD(0xC2, 0x39),
-	_INIT_DCS_CMD(0xC3, 0x4F),
-	_INIT_DCS_CMD(0xC4, 0x3A),
-	_INIT_DCS_CMD(0xC5, 0x42),
-	_INIT_DCS_CMD(0xFF, 0x27),
-	_INIT_DCS_CMD(0xFB, 0x01),
-
-	_INIT_DCS_CMD(0x56, 0x06),
-	_INIT_DCS_CMD(0x58, 0x80),
-	_INIT_DCS_CMD(0x59, 0x75),
-	_INIT_DCS_CMD(0x5A, 0x00),
-	_INIT_DCS_CMD(0x5B, 0x02),
-	_INIT_DCS_CMD(0x5C, 0x00),
-	_INIT_DCS_CMD(0x5D, 0x00),
-	_INIT_DCS_CMD(0x5E, 0x20),
-	_INIT_DCS_CMD(0x5F, 0x10),
-	_INIT_DCS_CMD(0x60, 0x00),
-	_INIT_DCS_CMD(0x61, 0x2E),
-	_INIT_DCS_CMD(0x62, 0x00),
-	_INIT_DCS_CMD(0x63, 0x01),
-	_INIT_DCS_CMD(0x64, 0x43),
-	_INIT_DCS_CMD(0x65, 0x2D),
-	_INIT_DCS_CMD(0x66, 0x00),
-	_INIT_DCS_CMD(0x67, 0x01),
-	_INIT_DCS_CMD(0x68, 0x44),
-
-	_INIT_DCS_CMD(0x00, 0x00),
-	_INIT_DCS_CMD(0x78, 0x00),
-	_INIT_DCS_CMD(0xC3, 0x00),
-
-	_INIT_DCS_CMD(0xFF, 0x2A),
-	_INIT_DCS_CMD(0xFB, 0x01),
-
-	_INIT_DCS_CMD(0x22, 0x2F),
-	_INIT_DCS_CMD(0x23, 0x08),
-
-	_INIT_DCS_CMD(0x24, 0x00),
-	_INIT_DCS_CMD(0x25, 0x65),
-	_INIT_DCS_CMD(0x26, 0xF8),
-	_INIT_DCS_CMD(0x27, 0x00),
-	_INIT_DCS_CMD(0x28, 0x1A),
-	_INIT_DCS_CMD(0x29, 0x00),
-	_INIT_DCS_CMD(0x2A, 0x1A),
-	_INIT_DCS_CMD(0x2B, 0x00),
-	_INIT_DCS_CMD(0x2D, 0x1A),
-
-	_INIT_DCS_CMD(0xFF, 0x23),
-	_INIT_DCS_CMD(0xFB, 0x01),
-
-	_INIT_DCS_CMD(0x00, 0x80),
-	_INIT_DCS_CMD(0x07, 0x00),
-
-	_INIT_DCS_CMD(0xFF, 0xE0),
-	_INIT_DCS_CMD(0xFB, 0x01),
-	_INIT_DCS_CMD(0x14, 0x60),
-	_INIT_DCS_CMD(0x16, 0xC0),
-
-	_INIT_DCS_CMD(0xFF, 0xF0),
-	_INIT_DCS_CMD(0xFB, 0x01),
-	_INIT_DCS_CMD(0x3A, 0x08),
-
-	_INIT_DCS_CMD(0xFF, 0x10),
-	_INIT_DCS_CMD(0xFB, 0x01),
-	_INIT_DCS_CMD(0xB9, 0x01),
-	_INIT_DCS_CMD(0xFF, 0x20),
-	_INIT_DCS_CMD(0xFB, 0x01),
-	_INIT_DCS_CMD(0x18, 0x40),
-
-	_INIT_DCS_CMD(0xFF, 0x10),
-	_INIT_DCS_CMD(0xFB, 0x01),
-	_INIT_DCS_CMD(0xB9, 0x02),
-	_INIT_DCS_CMD(0x35, 0x00),
-	_INIT_DCS_CMD(0x51, 0x00, 0xFF),
-	_INIT_DCS_CMD(0x53, 0x24),
-	_INIT_DCS_CMD(0x55, 0x00),
-	_INIT_DCS_CMD(0xBB, 0x13),
-	_INIT_DCS_CMD(0x3B, 0x03, 0x96, 0x1A, 0x04, 0x04),
-	_INIT_DELAY_CMD(100),
-	_INIT_DCS_CMD(0x11),
-	_INIT_DELAY_CMD(200),
-	_INIT_DCS_CMD(0x29),
-	_INIT_DELAY_CMD(100),
-	{},
+	return 0;
 };
 
-static const struct panel_init_cmd inx_hj110iz_init_cmd[] = {
-	_INIT_DCS_CMD(0xFF, 0x20),
-	_INIT_DCS_CMD(0xFB, 0x01),
-	_INIT_DCS_CMD(0x05, 0xD1),
-	_INIT_DCS_CMD(0x06, 0xC0),
-	_INIT_DCS_CMD(0x07, 0x87),
-	_INIT_DCS_CMD(0x08, 0x4B),
-
-	_INIT_DCS_CMD(0x0D, 0x63),
-	_INIT_DCS_CMD(0x0E, 0x91),
-	_INIT_DCS_CMD(0x0F, 0x69),
-	_INIT_DCS_CMD(0x94, 0x00),
-	_INIT_DCS_CMD(0x95, 0xF5),
-	_INIT_DCS_CMD(0x96, 0xF5),
-	_INIT_DCS_CMD(0x9D, 0x00),
-	_INIT_DCS_CMD(0x9E, 0x00),
-	_INIT_DCS_CMD(0x69, 0x98),
-	_INIT_DCS_CMD(0x75, 0xA2),
-	_INIT_DCS_CMD(0x77, 0xB3),
-
-	_INIT_DCS_CMD(0x58, 0x43),
-	_INIT_DCS_CMD(0xFF, 0x24),
-	_INIT_DCS_CMD(0xFB, 0x01),
-	_INIT_DCS_CMD(0x91, 0x44),
-	_INIT_DCS_CMD(0x92, 0x4C),
-	_INIT_DCS_CMD(0x94, 0x86),
-	_INIT_DCS_CMD(0x60, 0x96),
-	_INIT_DCS_CMD(0x61, 0xD0),
-	_INIT_DCS_CMD(0x63, 0x70),
-	_INIT_DCS_CMD(0xC2, 0xCA),
-
-	_INIT_DCS_CMD(0x00, 0x03),
-	_INIT_DCS_CMD(0x01, 0x03),
-	_INIT_DCS_CMD(0x02, 0x03),
-	_INIT_DCS_CMD(0x03, 0x29),
-	_INIT_DCS_CMD(0x04, 0x22),
-	_INIT_DCS_CMD(0x05, 0x22),
-	_INIT_DCS_CMD(0x06, 0x0B),
-	_INIT_DCS_CMD(0x07, 0x1D),
-	_INIT_DCS_CMD(0x08, 0x1C),
-	_INIT_DCS_CMD(0x09, 0x05),
-	_INIT_DCS_CMD(0x0A, 0x08),
-	_INIT_DCS_CMD(0x0B, 0x09),
-	_INIT_DCS_CMD(0x0C, 0x0A),
-	_INIT_DCS_CMD(0x0D, 0x0C),
-	_INIT_DCS_CMD(0x0E, 0x0D),
-	_INIT_DCS_CMD(0x0F, 0x0E),
-	_INIT_DCS_CMD(0x10, 0x0F),
-	_INIT_DCS_CMD(0x11, 0x10),
-	_INIT_DCS_CMD(0x12, 0x11),
-	_INIT_DCS_CMD(0x13, 0x04),
-	_INIT_DCS_CMD(0x14, 0x00),
-	_INIT_DCS_CMD(0x15, 0x03),
-	_INIT_DCS_CMD(0x16, 0x03),
-	_INIT_DCS_CMD(0x17, 0x03),
-	_INIT_DCS_CMD(0x18, 0x03),
-	_INIT_DCS_CMD(0x19, 0x29),
-	_INIT_DCS_CMD(0x1A, 0x22),
-	_INIT_DCS_CMD(0x1B, 0x22),
-	_INIT_DCS_CMD(0x1C, 0x0B),
-	_INIT_DCS_CMD(0x1D, 0x1D),
-	_INIT_DCS_CMD(0x1E, 0x1C),
-	_INIT_DCS_CMD(0x1F, 0x05),
-	_INIT_DCS_CMD(0x20, 0x08),
-	_INIT_DCS_CMD(0x21, 0x09),
-	_INIT_DCS_CMD(0x22, 0x0A),
-	_INIT_DCS_CMD(0x23, 0x0C),
-	_INIT_DCS_CMD(0x24, 0x0D),
-	_INIT_DCS_CMD(0x25, 0x0E),
-	_INIT_DCS_CMD(0x26, 0x0F),
-	_INIT_DCS_CMD(0x27, 0x10),
-	_INIT_DCS_CMD(0x28, 0x11),
-	_INIT_DCS_CMD(0x29, 0x04),
-	_INIT_DCS_CMD(0x2A, 0x00),
-	_INIT_DCS_CMD(0x2B, 0x03),
-
-	_INIT_DCS_CMD(0x2F, 0x0A),
-	_INIT_DCS_CMD(0x30, 0x35),
-	_INIT_DCS_CMD(0x37, 0xA7),
-	_INIT_DCS_CMD(0x39, 0x00),
-	_INIT_DCS_CMD(0x3A, 0x46),
-	_INIT_DCS_CMD(0x3B, 0x32),
-	_INIT_DCS_CMD(0x3D, 0x12),
-
-	_INIT_DCS_CMD(0x3F, 0x33),
-	_INIT_DCS_CMD(0x40, 0x31),
-	_INIT_DCS_CMD(0x41, 0x40),
-	_INIT_DCS_CMD(0x42, 0x42),
-	_INIT_DCS_CMD(0x47, 0x77),
-	_INIT_DCS_CMD(0x48, 0x77),
-	_INIT_DCS_CMD(0x4A, 0x45),
-	_INIT_DCS_CMD(0x4B, 0x45),
-	_INIT_DCS_CMD(0x4C, 0x14),
-
-	_INIT_DCS_CMD(0x4D, 0x21),
-	_INIT_DCS_CMD(0x4E, 0x43),
-	_INIT_DCS_CMD(0x4F, 0x65),
-	_INIT_DCS_CMD(0x55, 0x06),
-	_INIT_DCS_CMD(0x56, 0x06),
-	_INIT_DCS_CMD(0x58, 0x21),
-	_INIT_DCS_CMD(0x59, 0x70),
-	_INIT_DCS_CMD(0x5A, 0x46),
-	_INIT_DCS_CMD(0x5B, 0x32),
-	_INIT_DCS_CMD(0x5C, 0x88),
-	_INIT_DCS_CMD(0x5E, 0x00, 0x00),
-	_INIT_DCS_CMD(0x5F, 0x00),
-
-	_INIT_DCS_CMD(0x7A, 0xFF),
-	_INIT_DCS_CMD(0x7B, 0xFF),
-	_INIT_DCS_CMD(0x7C, 0x00),
-	_INIT_DCS_CMD(0x7D, 0x00),
-	_INIT_DCS_CMD(0x7E, 0x20),
-	_INIT_DCS_CMD(0x7F, 0x3C),
-	_INIT_DCS_CMD(0x80, 0x00),
-	_INIT_DCS_CMD(0x81, 0x00),
-	_INIT_DCS_CMD(0x82, 0x08),
-	_INIT_DCS_CMD(0x97, 0x02),
-	_INIT_DCS_CMD(0xC5, 0x10),
-
-	_INIT_DCS_CMD(0xD7, 0x55),
-	_INIT_DCS_CMD(0xD8, 0x55),
-	_INIT_DCS_CMD(0xD9, 0x23),
-	_INIT_DCS_CMD(0xDA, 0x05),
-	_INIT_DCS_CMD(0xDB, 0x01),
-	_INIT_DCS_CMD(0xDC, 0x65),
-	_INIT_DCS_CMD(0xDD, 0x55),
-	_INIT_DCS_CMD(0xDE, 0x27),
-	_INIT_DCS_CMD(0xDF, 0x01),
-	_INIT_DCS_CMD(0xE0, 0x65),
-	_INIT_DCS_CMD(0xE1, 0x01),
-	_INIT_DCS_CMD(0xE2, 0x65),
-	_INIT_DCS_CMD(0xE3, 0x01),
-	_INIT_DCS_CMD(0xE4, 0x65),
-	_INIT_DCS_CMD(0xE5, 0x01),
-	_INIT_DCS_CMD(0xE6, 0x65),
-	_INIT_DCS_CMD(0xE7, 0x00),
-	_INIT_DCS_CMD(0xE8, 0x00),
-	_INIT_DCS_CMD(0xE9, 0x01),
-	_INIT_DCS_CMD(0xEA, 0x65),
-	_INIT_DCS_CMD(0xEB, 0x01),
-	_INIT_DCS_CMD(0xEE, 0x65),
-	_INIT_DCS_CMD(0xEF, 0x01),
-	_INIT_DCS_CMD(0xF0, 0x65),
-	_INIT_DCS_CMD(0xB6, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00),
-
-	_INIT_DCS_CMD(0xFF, 0x25),
-
-	_INIT_DCS_CMD(0xFB, 0x01),
-	_INIT_DCS_CMD(0x05, 0x00),
-	_INIT_DCS_CMD(0xF1, 0x10),
-
-	_INIT_DCS_CMD(0x1E, 0x00),
-	_INIT_DCS_CMD(0x1F, 0x46),
-	_INIT_DCS_CMD(0x20, 0x32),
-
-	_INIT_DCS_CMD(0x25, 0x00),
-	_INIT_DCS_CMD(0x26, 0x46),
-	_INIT_DCS_CMD(0x27, 0x32),
-
-	_INIT_DCS_CMD(0x3F, 0x80),
-	_INIT_DCS_CMD(0x40, 0x00),
-	_INIT_DCS_CMD(0x43, 0x00),
-
-	_INIT_DCS_CMD(0x44, 0x46),
-	_INIT_DCS_CMD(0x45, 0x46),
-
-	_INIT_DCS_CMD(0x48, 0x46),
-	_INIT_DCS_CMD(0x49, 0x32),
-
-	_INIT_DCS_CMD(0x5B, 0x80),
-
-	_INIT_DCS_CMD(0x5C, 0x00),
-	_INIT_DCS_CMD(0x5D, 0x46),
-	_INIT_DCS_CMD(0x5E, 0x32),
-
-	_INIT_DCS_CMD(0x5F, 0x46),
-	_INIT_DCS_CMD(0x60, 0x32),
-
-	_INIT_DCS_CMD(0x61, 0x46),
-	_INIT_DCS_CMD(0x62, 0x32),
-	_INIT_DCS_CMD(0x68, 0x0C),
-
-	_INIT_DCS_CMD(0x6C, 0x0D),
-	_INIT_DCS_CMD(0x6E, 0x0D),
-	_INIT_DCS_CMD(0x78, 0x00),
-	_INIT_DCS_CMD(0x79, 0xC5),
-	_INIT_DCS_CMD(0x7A, 0x0C),
-	_INIT_DCS_CMD(0x7B, 0xB0),
-
-	_INIT_DCS_CMD(0xFF, 0x26),
-	_INIT_DCS_CMD(0xFB, 0x01),
-
-	_INIT_DCS_CMD(0x00, 0xA1),
-	_INIT_DCS_CMD(0x02, 0x31),
-	_INIT_DCS_CMD(0x0A, 0xF4),
-	_INIT_DCS_CMD(0x04, 0x50),
-	_INIT_DCS_CMD(0x06, 0x30),
-	_INIT_DCS_CMD(0x0C, 0x16),
-	_INIT_DCS_CMD(0x0D, 0x0D),
-	_INIT_DCS_CMD(0x0F, 0x00),
-	_INIT_DCS_CMD(0x11, 0x00),
-	_INIT_DCS_CMD(0x12, 0x50),
-	_INIT_DCS_CMD(0x13, 0x40),
-	_INIT_DCS_CMD(0x14, 0x58),
-	_INIT_DCS_CMD(0x15, 0x00),
-	_INIT_DCS_CMD(0x16, 0x10),
-	_INIT_DCS_CMD(0x17, 0xA0),
-	_INIT_DCS_CMD(0x18, 0x86),
-	_INIT_DCS_CMD(0x22, 0x00),
-	_INIT_DCS_CMD(0x23, 0x00),
-
-	_INIT_DCS_CMD(0x19, 0x0E),
-	_INIT_DCS_CMD(0x1A, 0x31),
-	_INIT_DCS_CMD(0x1B, 0x0D),
-	_INIT_DCS_CMD(0x1C, 0x29),
-	_INIT_DCS_CMD(0x2A, 0x0E),
-	_INIT_DCS_CMD(0x2B, 0x31),
-
-	_INIT_DCS_CMD(0x1D, 0x00),
-	_INIT_DCS_CMD(0x1E, 0x62),
-	_INIT_DCS_CMD(0x1F, 0x62),
-
-	_INIT_DCS_CMD(0x2F, 0x06),
-	_INIT_DCS_CMD(0x30, 0x62),
-	_INIT_DCS_CMD(0x31, 0x06),
-	_INIT_DCS_CMD(0x32, 0x7F),
-	_INIT_DCS_CMD(0x33, 0x11),
-	_INIT_DCS_CMD(0x34, 0x89),
-	_INIT_DCS_CMD(0x35, 0x67),
-
-	_INIT_DCS_CMD(0x39, 0x0B),
-	_INIT_DCS_CMD(0x3A, 0x62),
-	_INIT_DCS_CMD(0x3B, 0x06),
-
-	_INIT_DCS_CMD(0xC8, 0x04),
-	_INIT_DCS_CMD(0xC9, 0x89),
-	_INIT_DCS_CMD(0xCA, 0x4E),
-	_INIT_DCS_CMD(0xCB, 0x00),
-	_INIT_DCS_CMD(0xA9, 0x3F),
-	_INIT_DCS_CMD(0xAA, 0x3E),
-	_INIT_DCS_CMD(0xAB, 0x3D),
-	_INIT_DCS_CMD(0xAC, 0x3C),
-	_INIT_DCS_CMD(0xAD, 0x3B),
-	_INIT_DCS_CMD(0xAE, 0x3A),
-	_INIT_DCS_CMD(0xAF, 0x39),
-	_INIT_DCS_CMD(0xB0, 0x38),
-
-	_INIT_DCS_CMD(0xFF, 0x27),
-	_INIT_DCS_CMD(0xFB, 0x01),
-
-	_INIT_DCS_CMD(0xD0, 0x11),
-	_INIT_DCS_CMD(0xD1, 0x54),
-	_INIT_DCS_CMD(0xDE, 0x43),
-	_INIT_DCS_CMD(0xDF, 0x02),
-
-	_INIT_DCS_CMD(0xC0, 0x18),
-	_INIT_DCS_CMD(0xC1, 0x00),
-	_INIT_DCS_CMD(0xC2, 0x00),
-	_INIT_DCS_CMD(0x00, 0x00),
-	_INIT_DCS_CMD(0xC3, 0x00),
-	_INIT_DCS_CMD(0x56, 0x06),
-
-	_INIT_DCS_CMD(0x58, 0x80),
-	_INIT_DCS_CMD(0x59, 0x78),
-	_INIT_DCS_CMD(0x5A, 0x00),
-	_INIT_DCS_CMD(0x5B, 0x18),
-	_INIT_DCS_CMD(0x5C, 0x00),
-	_INIT_DCS_CMD(0x5D, 0x01),
-	_INIT_DCS_CMD(0x5E, 0x20),
-	_INIT_DCS_CMD(0x5F, 0x10),
-	_INIT_DCS_CMD(0x60, 0x00),
-	_INIT_DCS_CMD(0x61, 0x1C),
-	_INIT_DCS_CMD(0x62, 0x00),
-	_INIT_DCS_CMD(0x63, 0x01),
-	_INIT_DCS_CMD(0x64, 0x44),
-	_INIT_DCS_CMD(0x65, 0x1B),
-	_INIT_DCS_CMD(0x66, 0x00),
-	_INIT_DCS_CMD(0x67, 0x01),
-	_INIT_DCS_CMD(0x68, 0x44),
-
-	_INIT_DCS_CMD(0x98, 0x01),
-	_INIT_DCS_CMD(0xB4, 0x03),
-	_INIT_DCS_CMD(0x9B, 0xBE),
-
-	_INIT_DCS_CMD(0xAB, 0x14),
-	_INIT_DCS_CMD(0xBC, 0x08),
-	_INIT_DCS_CMD(0xBD, 0x28),
-
-	_INIT_DCS_CMD(0xFF, 0x2A),
-	_INIT_DCS_CMD(0xFB, 0x01),
-	_INIT_DCS_CMD(0x22, 0x2F),
-	_INIT_DCS_CMD(0x23, 0x08),
-
-	_INIT_DCS_CMD(0x24, 0x00),
-	_INIT_DCS_CMD(0x25, 0x62),
-	_INIT_DCS_CMD(0x26, 0xF8),
-	_INIT_DCS_CMD(0x27, 0x00),
-	_INIT_DCS_CMD(0x28, 0x1A),
-	_INIT_DCS_CMD(0x29, 0x00),
-	_INIT_DCS_CMD(0x2A, 0x1A),
-	_INIT_DCS_CMD(0x2B, 0x00),
-	_INIT_DCS_CMD(0x2D, 0x1A),
-
-	_INIT_DCS_CMD(0x64, 0x96),
-	_INIT_DCS_CMD(0x65, 0x10),
-	_INIT_DCS_CMD(0x66, 0x00),
-	_INIT_DCS_CMD(0x67, 0x96),
-	_INIT_DCS_CMD(0x68, 0x10),
-	_INIT_DCS_CMD(0x69, 0x00),
-	_INIT_DCS_CMD(0x6A, 0x96),
-	_INIT_DCS_CMD(0x6B, 0x10),
-	_INIT_DCS_CMD(0x6C, 0x00),
-	_INIT_DCS_CMD(0x70, 0x92),
-	_INIT_DCS_CMD(0x71, 0x10),
-	_INIT_DCS_CMD(0x72, 0x00),
-	_INIT_DCS_CMD(0x79, 0x96),
-	_INIT_DCS_CMD(0x7A, 0x10),
-	_INIT_DCS_CMD(0x88, 0x96),
-	_INIT_DCS_CMD(0x89, 0x10),
-
-	_INIT_DCS_CMD(0xA2, 0x3F),
-	_INIT_DCS_CMD(0xA3, 0x30),
-	_INIT_DCS_CMD(0xA4, 0xC0),
-	_INIT_DCS_CMD(0xA5, 0x03),
-
-	_INIT_DCS_CMD(0xE8, 0x00),
-
-	_INIT_DCS_CMD(0x97, 0x3C),
-	_INIT_DCS_CMD(0x98, 0x02),
-	_INIT_DCS_CMD(0x99, 0x95),
-	_INIT_DCS_CMD(0x9A, 0x06),
-	_INIT_DCS_CMD(0x9B, 0x00),
-	_INIT_DCS_CMD(0x9C, 0x0B),
-	_INIT_DCS_CMD(0x9D, 0x0A),
-	_INIT_DCS_CMD(0x9E, 0x90),
-
-	_INIT_DCS_CMD(0xFF, 0x25),
-	_INIT_DCS_CMD(0x13, 0x02),
-	_INIT_DCS_CMD(0x14, 0xD7),
-	_INIT_DCS_CMD(0xDB, 0x02),
-	_INIT_DCS_CMD(0xDC, 0xD7),
-	_INIT_DCS_CMD(0x17, 0xCF),
-	_INIT_DCS_CMD(0x19, 0x0F),
-	_INIT_DCS_CMD(0x1B, 0x5B),
-
-	_INIT_DCS_CMD(0xFF, 0x20),
-
-	_INIT_DCS_CMD(0xB0, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x24, 0x00, 0x38, 0x00, 0x4C, 0x00, 0x5E, 0x00, 0x6F, 0x00, 0x7E),
-	_INIT_DCS_CMD(0xB1, 0x00, 0x8C, 0x00, 0xBE, 0x00, 0xE5, 0x01, 0x27, 0x01, 0x58, 0x01, 0xA8, 0x01, 0xE8, 0x01, 0xEA),
-	_INIT_DCS_CMD(0xB2, 0x02, 0x28, 0x02, 0x71, 0x02, 0x9E, 0x02, 0xDA, 0x03, 0x00, 0x03, 0x31, 0x03, 0x40, 0x03, 0x51),
-	_INIT_DCS_CMD(0xB3, 0x03, 0x62, 0x03, 0x75, 0x03, 0x89, 0x03, 0x9C, 0x03, 0xAA, 0x03, 0xB2),
-
-	_INIT_DCS_CMD(0xB4, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x27, 0x00, 0x3D, 0x00, 0x52, 0x00, 0x64, 0x00, 0x75, 0x00, 0x84),
-	_INIT_DCS_CMD(0xB5, 0x00, 0x93, 0x00, 0xC5, 0x00, 0xEC, 0x01, 0x2C, 0x01, 0x5D, 0x01, 0xAC, 0x01, 0xEC, 0x01, 0xEE),
-	_INIT_DCS_CMD(0xB6, 0x02, 0x2B, 0x02, 0x73, 0x02, 0xA0, 0x02, 0xDB, 0x03, 0x01, 0x03, 0x31, 0x03, 0x41, 0x03, 0x51),
-	_INIT_DCS_CMD(0xB7, 0x03, 0x63, 0x03, 0x75, 0x03, 0x89, 0x03, 0x9C, 0x03, 0xAA, 0x03, 0xB2),
-
-	_INIT_DCS_CMD(0xB8, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x2A, 0x00, 0x40, 0x00, 0x56, 0x00, 0x68, 0x00, 0x7A, 0x00, 0x89),
-	_INIT_DCS_CMD(0xB9, 0x00, 0x98, 0x00, 0xC9, 0x00, 0xF1, 0x01, 0x30, 0x01, 0x61, 0x01, 0xB0, 0x01, 0xEF, 0x01, 0xF1),
-	_INIT_DCS_CMD(0xBA, 0x02, 0x2E, 0x02, 0x76, 0x02, 0xA3, 0x02, 0xDD, 0x03, 0x02, 0x03, 0x32, 0x03, 0x42, 0x03, 0x53),
-	_INIT_DCS_CMD(0xBB, 0x03, 0x66, 0x03, 0x75, 0x03, 0x89, 0x03, 0x9C, 0x03, 0xAA, 0x03, 0xB2),
-
-	_INIT_DCS_CMD(0xFF, 0x21),
-	_INIT_DCS_CMD(0xB0, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x24, 0x00, 0x38, 0x00, 0x4C, 0x00, 0x5E, 0x00, 0x6F, 0x00, 0x7E),
-	_INIT_DCS_CMD(0xB1, 0x00, 0x8C, 0x00, 0xBE, 0x00, 0xE5, 0x01, 0x27, 0x01, 0x58, 0x01, 0xA8, 0x01, 0xE8, 0x01, 0xEA),
-	_INIT_DCS_CMD(0xB2, 0x02, 0x28, 0x02, 0x71, 0x02, 0x9E, 0x02, 0xDA, 0x03, 0x00, 0x03, 0x31, 0x03, 0x40, 0x03, 0x51),
-	_INIT_DCS_CMD(0xB3, 0x03, 0x62, 0x03, 0x77, 0x03, 0x90, 0x03, 0xAC, 0x03, 0xCA, 0x03, 0xDA),
-
-	_INIT_DCS_CMD(0xB4, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x27, 0x00, 0x3D, 0x00, 0x52, 0x00, 0x64, 0x00, 0x75, 0x00, 0x84),
-	_INIT_DCS_CMD(0xB5, 0x00, 0x93, 0x00, 0xC5, 0x00, 0xEC, 0x01, 0x2C, 0x01, 0x5D, 0x01, 0xAC, 0x01, 0xEC, 0x01, 0xEE),
-	_INIT_DCS_CMD(0xB6, 0x02, 0x2B, 0x02, 0x73, 0x02, 0xA0, 0x02, 0xDB, 0x03, 0x01, 0x03, 0x31, 0x03, 0x41, 0x03, 0x51),
-	_INIT_DCS_CMD(0xB7, 0x03, 0x63, 0x03, 0x77, 0x03, 0x90, 0x03, 0xAC, 0x03, 0xCA, 0x03, 0xDA),
-
-	_INIT_DCS_CMD(0xB8, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x2A, 0x00, 0x40, 0x00, 0x56, 0x00, 0x68, 0x00, 0x7A, 0x00, 0x89),
-	_INIT_DCS_CMD(0xB9, 0x00, 0x98, 0x00, 0xC9, 0x00, 0xF1, 0x01, 0x30, 0x01, 0x61, 0x01, 0xB0, 0x01, 0xEF, 0x01, 0xF1),
-	_INIT_DCS_CMD(0xBA, 0x02, 0x2E, 0x02, 0x76, 0x02, 0xA3, 0x02, 0xDD, 0x03, 0x02, 0x03, 0x32, 0x03, 0x42, 0x03, 0x53),
-	_INIT_DCS_CMD(0xBB, 0x03, 0x66, 0x03, 0x77, 0x03, 0x90, 0x03, 0xAC, 0x03, 0xCA, 0x03, 0xDA),
-
-	_INIT_DCS_CMD(0xFF, 0xF0),
-	_INIT_DCS_CMD(0xFB, 0x01),
-	_INIT_DCS_CMD(0x3A, 0x08),
-
-	_INIT_DCS_CMD(0xFF, 0x10),
-	_INIT_DCS_CMD(0xB9, 0x01),
-
-	_INIT_DCS_CMD(0xFF, 0x20),
-
-	_INIT_DCS_CMD(0x18, 0x40),
-	_INIT_DCS_CMD(0xFF, 0x10),
-
-	_INIT_DCS_CMD(0xB9, 0x02),
-	_INIT_DCS_CMD(0xFF, 0x10),
-
-	_INIT_DCS_CMD(0xFB, 0x01),
-	_INIT_DCS_CMD(0xB0, 0x01),
-	_INIT_DCS_CMD(0x35, 0x00),
-	_INIT_DCS_CMD(0x3B, 0x03, 0xAE, 0x1A, 0x04, 0x04),
-	_INIT_DELAY_CMD(100),
-	_INIT_DCS_CMD(0x11),
-	_INIT_DELAY_CMD(200),
-	_INIT_DCS_CMD(0x29),
-	_INIT_DELAY_CMD(100),
-	{},
-};
+static int boe_init(struct boe_panel *boe)
+{
+	struct mipi_dsi_multi_context ctx = { .dsi = boe->dsi };
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0xe5);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x52);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x88);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x8b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbf, 0x1a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x0f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0x0c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0x0c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe0, 0x26);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe1, 0x26);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdc, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdd, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0x26);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0x26);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd2, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd3, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe6, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe7, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0x09);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0x09);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd8, 0x0a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd9, 0x0a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0x0b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0x0b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd6, 0x0c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd7, 0x0c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd4, 0x06);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd5, 0x06);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xde, 0x08);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdf, 0x08);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x0d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0x17);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0x26);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0x31);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0x1c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0x2c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0x33);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0x31);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x37);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x37);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x37);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0x39);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0x2e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0x2f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcf, 0x2f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd0, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd2, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd3, 0x0d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd4, 0x17);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd5, 0x26);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd6, 0x31);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd7, 0x3f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd8, 0x3f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd9, 0x3f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xda, 0x3f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdb, 0x37);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdc, 0x37);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdd, 0x37);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xde, 0x39);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdf, 0x2e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe0, 0x2f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe1, 0x2f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe2, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0x0b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe7, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0x2a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xde, 0x2a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x43);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe4, 0xc0);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5, 0x0d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x06);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0xa5);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0xa5);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0x0f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd5, 0x32);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbc, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x0f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x25);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x39);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x4e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x72);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x97);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0xdc);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x22);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0xa4);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbc, 0x2b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x2f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbe, 0xa9);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbf, 0x25);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x61);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x97);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0xb2);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0xcd);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0xd9);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0xe7);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0xf4);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0xfa);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0xfc);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x16);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0xaf);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0xff);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0xff);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x08);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x11);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x24);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x39);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x4f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x72);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x98);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0xdc);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x23);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0xa6);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbc, 0x2c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x30);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbe, 0xaa);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbf, 0x26);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x62);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x9b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0xb5);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0xcf);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0xdb);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0xe8);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0xf5);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0xfa);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0xfc);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x16);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0xaf);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0xff);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0xff);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x09);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x16);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x24);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x3b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x4f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x73);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x99);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0xe0);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x26);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0xad);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbc, 0x36);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x3a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbe, 0xae);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbf, 0x2a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x66);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x9e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0xb8);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0xd1);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0xdd);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0xe9);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0xf6);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0xfa);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0xfc);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x16);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0xaf);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0xff);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0xff);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x0a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x0f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x25);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x39);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x4e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x72);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x97);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0xdc);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x22);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0xa4);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbc, 0x2b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x2f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbe, 0xa9);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbf, 0x25);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x61);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x97);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0xb2);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0xcd);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0xd9);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0xe7);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0xf4);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0xfa);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0xfc);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x16);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0xaf);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0xff);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0xff);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x0b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x11);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x24);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x39);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x4f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x72);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x98);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0xdc);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x23);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0xa6);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbc, 0x2c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x30);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbe, 0xaa);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbf, 0x26);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x62);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x9b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0xb5);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0xcf);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0xdb);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0xe8);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0xf5);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0xfa);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0xfc);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x16);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0xaf);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0xff);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0xff);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x0c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x16);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x24);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x3b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x4f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x73);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x99);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0xe0);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x26);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0xad);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbc, 0x36);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x3a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbe, 0xae);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbf, 0x2a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x66);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x9e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0xb8);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0xd1);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0xdd);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0xe9);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0xf6);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0xfa);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0xfc);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x16);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0xaf);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0xff);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0xff);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x00);
+	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);
 
-static const struct panel_init_cmd boe_init_cmd[] = {
-	_INIT_DCS_CMD(0xB0, 0x05),
-	_INIT_DCS_CMD(0xB1, 0xE5),
-	_INIT_DCS_CMD(0xB3, 0x52),
-	_INIT_DCS_CMD(0xB0, 0x00),
-	_INIT_DCS_CMD(0xB3, 0x88),
-	_INIT_DCS_CMD(0xB0, 0x04),
-	_INIT_DCS_CMD(0xB8, 0x00),
-	_INIT_DCS_CMD(0xB0, 0x00),
-	_INIT_DCS_CMD(0xB6, 0x03),
-	_INIT_DCS_CMD(0xBA, 0x8B),
-	_INIT_DCS_CMD(0xBF, 0x1A),
-	_INIT_DCS_CMD(0xC0, 0x0F),
-	_INIT_DCS_CMD(0xC2, 0x0C),
-	_INIT_DCS_CMD(0xC3, 0x02),
-	_INIT_DCS_CMD(0xC4, 0x0C),
-	_INIT_DCS_CMD(0xC5, 0x02),
-	_INIT_DCS_CMD(0xB0, 0x01),
-	_INIT_DCS_CMD(0xE0, 0x26),
-	_INIT_DCS_CMD(0xE1, 0x26),
-	_INIT_DCS_CMD(0xDC, 0x00),
-	_INIT_DCS_CMD(0xDD, 0x00),
-	_INIT_DCS_CMD(0xCC, 0x26),
-	_INIT_DCS_CMD(0xCD, 0x26),
-	_INIT_DCS_CMD(0xC8, 0x00),
-	_INIT_DCS_CMD(0xC9, 0x00),
-	_INIT_DCS_CMD(0xD2, 0x03),
-	_INIT_DCS_CMD(0xD3, 0x03),
-	_INIT_DCS_CMD(0xE6, 0x04),
-	_INIT_DCS_CMD(0xE7, 0x04),
-	_INIT_DCS_CMD(0xC4, 0x09),
-	_INIT_DCS_CMD(0xC5, 0x09),
-	_INIT_DCS_CMD(0xD8, 0x0A),
-	_INIT_DCS_CMD(0xD9, 0x0A),
-	_INIT_DCS_CMD(0xC2, 0x0B),
-	_INIT_DCS_CMD(0xC3, 0x0B),
-	_INIT_DCS_CMD(0xD6, 0x0C),
-	_INIT_DCS_CMD(0xD7, 0x0C),
-	_INIT_DCS_CMD(0xC0, 0x05),
-	_INIT_DCS_CMD(0xC1, 0x05),
-	_INIT_DCS_CMD(0xD4, 0x06),
-	_INIT_DCS_CMD(0xD5, 0x06),
-	_INIT_DCS_CMD(0xCA, 0x07),
-	_INIT_DCS_CMD(0xCB, 0x07),
-	_INIT_DCS_CMD(0xDE, 0x08),
-	_INIT_DCS_CMD(0xDF, 0x08),
-	_INIT_DCS_CMD(0xB0, 0x02),
-	_INIT_DCS_CMD(0xC0, 0x00),
-	_INIT_DCS_CMD(0xC1, 0x0D),
-	_INIT_DCS_CMD(0xC2, 0x17),
-	_INIT_DCS_CMD(0xC3, 0x26),
-	_INIT_DCS_CMD(0xC4, 0x31),
-	_INIT_DCS_CMD(0xC5, 0x1C),
-	_INIT_DCS_CMD(0xC6, 0x2C),
-	_INIT_DCS_CMD(0xC7, 0x33),
-	_INIT_DCS_CMD(0xC8, 0x31),
-	_INIT_DCS_CMD(0xC9, 0x37),
-	_INIT_DCS_CMD(0xCA, 0x37),
-	_INIT_DCS_CMD(0xCB, 0x37),
-	_INIT_DCS_CMD(0xCC, 0x39),
-	_INIT_DCS_CMD(0xCD, 0x2E),
-	_INIT_DCS_CMD(0xCE, 0x2F),
-	_INIT_DCS_CMD(0xCF, 0x2F),
-	_INIT_DCS_CMD(0xD0, 0x07),
-	_INIT_DCS_CMD(0xD2, 0x00),
-	_INIT_DCS_CMD(0xD3, 0x0D),
-	_INIT_DCS_CMD(0xD4, 0x17),
-	_INIT_DCS_CMD(0xD5, 0x26),
-	_INIT_DCS_CMD(0xD6, 0x31),
-	_INIT_DCS_CMD(0xD7, 0x3F),
-	_INIT_DCS_CMD(0xD8, 0x3F),
-	_INIT_DCS_CMD(0xD9, 0x3F),
-	_INIT_DCS_CMD(0xDA, 0x3F),
-	_INIT_DCS_CMD(0xDB, 0x37),
-	_INIT_DCS_CMD(0xDC, 0x37),
-	_INIT_DCS_CMD(0xDD, 0x37),
-	_INIT_DCS_CMD(0xDE, 0x39),
-	_INIT_DCS_CMD(0xDF, 0x2E),
-	_INIT_DCS_CMD(0xE0, 0x2F),
-	_INIT_DCS_CMD(0xE1, 0x2F),
-	_INIT_DCS_CMD(0xE2, 0x07),
-	_INIT_DCS_CMD(0xB0, 0x03),
-	_INIT_DCS_CMD(0xC8, 0x0B),
-	_INIT_DCS_CMD(0xC9, 0x07),
-	_INIT_DCS_CMD(0xC3, 0x00),
-	_INIT_DCS_CMD(0xE7, 0x00),
-	_INIT_DCS_CMD(0xC5, 0x2A),
-	_INIT_DCS_CMD(0xDE, 0x2A),
-	_INIT_DCS_CMD(0xCA, 0x43),
-	_INIT_DCS_CMD(0xC9, 0x07),
-	_INIT_DCS_CMD(0xE4, 0xC0),
-	_INIT_DCS_CMD(0xE5, 0x0D),
-	_INIT_DCS_CMD(0xCB, 0x00),
-	_INIT_DCS_CMD(0xB0, 0x06),
-	_INIT_DCS_CMD(0xB8, 0xA5),
-	_INIT_DCS_CMD(0xC0, 0xA5),
-	_INIT_DCS_CMD(0xC7, 0x0F),
-	_INIT_DCS_CMD(0xD5, 0x32),
-	_INIT_DCS_CMD(0xB8, 0x00),
-	_INIT_DCS_CMD(0xC0, 0x00),
-	_INIT_DCS_CMD(0xBC, 0x00),
-	_INIT_DCS_CMD(0xB0, 0x07),
-	_INIT_DCS_CMD(0xB1, 0x00),
-	_INIT_DCS_CMD(0xB2, 0x02),
-	_INIT_DCS_CMD(0xB3, 0x0F),
-	_INIT_DCS_CMD(0xB4, 0x25),
-	_INIT_DCS_CMD(0xB5, 0x39),
-	_INIT_DCS_CMD(0xB6, 0x4E),
-	_INIT_DCS_CMD(0xB7, 0x72),
-	_INIT_DCS_CMD(0xB8, 0x97),
-	_INIT_DCS_CMD(0xB9, 0xDC),
-	_INIT_DCS_CMD(0xBA, 0x22),
-	_INIT_DCS_CMD(0xBB, 0xA4),
-	_INIT_DCS_CMD(0xBC, 0x2B),
-	_INIT_DCS_CMD(0xBD, 0x2F),
-	_INIT_DCS_CMD(0xBE, 0xA9),
-	_INIT_DCS_CMD(0xBF, 0x25),
-	_INIT_DCS_CMD(0xC0, 0x61),
-	_INIT_DCS_CMD(0xC1, 0x97),
-	_INIT_DCS_CMD(0xC2, 0xB2),
-	_INIT_DCS_CMD(0xC3, 0xCD),
-	_INIT_DCS_CMD(0xC4, 0xD9),
-	_INIT_DCS_CMD(0xC5, 0xE7),
-	_INIT_DCS_CMD(0xC6, 0xF4),
-	_INIT_DCS_CMD(0xC7, 0xFA),
-	_INIT_DCS_CMD(0xC8, 0xFC),
-	_INIT_DCS_CMD(0xC9, 0x00),
-	_INIT_DCS_CMD(0xCA, 0x00),
-	_INIT_DCS_CMD(0xCB, 0x16),
-	_INIT_DCS_CMD(0xCC, 0xAF),
-	_INIT_DCS_CMD(0xCD, 0xFF),
-	_INIT_DCS_CMD(0xCE, 0xFF),
-	_INIT_DCS_CMD(0xB0, 0x08),
-	_INIT_DCS_CMD(0xB1, 0x04),
-	_INIT_DCS_CMD(0xB2, 0x05),
-	_INIT_DCS_CMD(0xB3, 0x11),
-	_INIT_DCS_CMD(0xB4, 0x24),
-	_INIT_DCS_CMD(0xB5, 0x39),
-	_INIT_DCS_CMD(0xB6, 0x4F),
-	_INIT_DCS_CMD(0xB7, 0x72),
-	_INIT_DCS_CMD(0xB8, 0x98),
-	_INIT_DCS_CMD(0xB9, 0xDC),
-	_INIT_DCS_CMD(0xBA, 0x23),
-	_INIT_DCS_CMD(0xBB, 0xA6),
-	_INIT_DCS_CMD(0xBC, 0x2C),
-	_INIT_DCS_CMD(0xBD, 0x30),
-	_INIT_DCS_CMD(0xBE, 0xAA),
-	_INIT_DCS_CMD(0xBF, 0x26),
-	_INIT_DCS_CMD(0xC0, 0x62),
-	_INIT_DCS_CMD(0xC1, 0x9B),
-	_INIT_DCS_CMD(0xC2, 0xB5),
-	_INIT_DCS_CMD(0xC3, 0xCF),
-	_INIT_DCS_CMD(0xC4, 0xDB),
-	_INIT_DCS_CMD(0xC5, 0xE8),
-	_INIT_DCS_CMD(0xC6, 0xF5),
-	_INIT_DCS_CMD(0xC7, 0xFA),
-	_INIT_DCS_CMD(0xC8, 0xFC),
-	_INIT_DCS_CMD(0xC9, 0x00),
-	_INIT_DCS_CMD(0xCA, 0x00),
-	_INIT_DCS_CMD(0xCB, 0x16),
-	_INIT_DCS_CMD(0xCC, 0xAF),
-	_INIT_DCS_CMD(0xCD, 0xFF),
-	_INIT_DCS_CMD(0xCE, 0xFF),
-	_INIT_DCS_CMD(0xB0, 0x09),
-	_INIT_DCS_CMD(0xB1, 0x04),
-	_INIT_DCS_CMD(0xB2, 0x02),
-	_INIT_DCS_CMD(0xB3, 0x16),
-	_INIT_DCS_CMD(0xB4, 0x24),
-	_INIT_DCS_CMD(0xB5, 0x3B),
-	_INIT_DCS_CMD(0xB6, 0x4F),
-	_INIT_DCS_CMD(0xB7, 0x73),
-	_INIT_DCS_CMD(0xB8, 0x99),
-	_INIT_DCS_CMD(0xB9, 0xE0),
-	_INIT_DCS_CMD(0xBA, 0x26),
-	_INIT_DCS_CMD(0xBB, 0xAD),
-	_INIT_DCS_CMD(0xBC, 0x36),
-	_INIT_DCS_CMD(0xBD, 0x3A),
-	_INIT_DCS_CMD(0xBE, 0xAE),
-	_INIT_DCS_CMD(0xBF, 0x2A),
-	_INIT_DCS_CMD(0xC0, 0x66),
-	_INIT_DCS_CMD(0xC1, 0x9E),
-	_INIT_DCS_CMD(0xC2, 0xB8),
-	_INIT_DCS_CMD(0xC3, 0xD1),
-	_INIT_DCS_CMD(0xC4, 0xDD),
-	_INIT_DCS_CMD(0xC5, 0xE9),
-	_INIT_DCS_CMD(0xC6, 0xF6),
-	_INIT_DCS_CMD(0xC7, 0xFA),
-	_INIT_DCS_CMD(0xC8, 0xFC),
-	_INIT_DCS_CMD(0xC9, 0x00),
-	_INIT_DCS_CMD(0xCA, 0x00),
-	_INIT_DCS_CMD(0xCB, 0x16),
-	_INIT_DCS_CMD(0xCC, 0xAF),
-	_INIT_DCS_CMD(0xCD, 0xFF),
-	_INIT_DCS_CMD(0xCE, 0xFF),
-	_INIT_DCS_CMD(0xB0, 0x0A),
-	_INIT_DCS_CMD(0xB1, 0x00),
-	_INIT_DCS_CMD(0xB2, 0x02),
-	_INIT_DCS_CMD(0xB3, 0x0F),
-	_INIT_DCS_CMD(0xB4, 0x25),
-	_INIT_DCS_CMD(0xB5, 0x39),
-	_INIT_DCS_CMD(0xB6, 0x4E),
-	_INIT_DCS_CMD(0xB7, 0x72),
-	_INIT_DCS_CMD(0xB8, 0x97),
-	_INIT_DCS_CMD(0xB9, 0xDC),
-	_INIT_DCS_CMD(0xBA, 0x22),
-	_INIT_DCS_CMD(0xBB, 0xA4),
-	_INIT_DCS_CMD(0xBC, 0x2B),
-	_INIT_DCS_CMD(0xBD, 0x2F),
-	_INIT_DCS_CMD(0xBE, 0xA9),
-	_INIT_DCS_CMD(0xBF, 0x25),
-	_INIT_DCS_CMD(0xC0, 0x61),
-	_INIT_DCS_CMD(0xC1, 0x97),
-	_INIT_DCS_CMD(0xC2, 0xB2),
-	_INIT_DCS_CMD(0xC3, 0xCD),
-	_INIT_DCS_CMD(0xC4, 0xD9),
-	_INIT_DCS_CMD(0xC5, 0xE7),
-	_INIT_DCS_CMD(0xC6, 0xF4),
-	_INIT_DCS_CMD(0xC7, 0xFA),
-	_INIT_DCS_CMD(0xC8, 0xFC),
-	_INIT_DCS_CMD(0xC9, 0x00),
-	_INIT_DCS_CMD(0xCA, 0x00),
-	_INIT_DCS_CMD(0xCB, 0x16),
-	_INIT_DCS_CMD(0xCC, 0xAF),
-	_INIT_DCS_CMD(0xCD, 0xFF),
-	_INIT_DCS_CMD(0xCE, 0xFF),
-	_INIT_DCS_CMD(0xB0, 0x0B),
-	_INIT_DCS_CMD(0xB1, 0x04),
-	_INIT_DCS_CMD(0xB2, 0x05),
-	_INIT_DCS_CMD(0xB3, 0x11),
-	_INIT_DCS_CMD(0xB4, 0x24),
-	_INIT_DCS_CMD(0xB5, 0x39),
-	_INIT_DCS_CMD(0xB6, 0x4F),
-	_INIT_DCS_CMD(0xB7, 0x72),
-	_INIT_DCS_CMD(0xB8, 0x98),
-	_INIT_DCS_CMD(0xB9, 0xDC),
-	_INIT_DCS_CMD(0xBA, 0x23),
-	_INIT_DCS_CMD(0xBB, 0xA6),
-	_INIT_DCS_CMD(0xBC, 0x2C),
-	_INIT_DCS_CMD(0xBD, 0x30),
-	_INIT_DCS_CMD(0xBE, 0xAA),
-	_INIT_DCS_CMD(0xBF, 0x26),
-	_INIT_DCS_CMD(0xC0, 0x62),
-	_INIT_DCS_CMD(0xC1, 0x9B),
-	_INIT_DCS_CMD(0xC2, 0xB5),
-	_INIT_DCS_CMD(0xC3, 0xCF),
-	_INIT_DCS_CMD(0xC4, 0xDB),
-	_INIT_DCS_CMD(0xC5, 0xE8),
-	_INIT_DCS_CMD(0xC6, 0xF5),
-	_INIT_DCS_CMD(0xC7, 0xFA),
-	_INIT_DCS_CMD(0xC8, 0xFC),
-	_INIT_DCS_CMD(0xC9, 0x00),
-	_INIT_DCS_CMD(0xCA, 0x00),
-	_INIT_DCS_CMD(0xCB, 0x16),
-	_INIT_DCS_CMD(0xCC, 0xAF),
-	_INIT_DCS_CMD(0xCD, 0xFF),
-	_INIT_DCS_CMD(0xCE, 0xFF),
-	_INIT_DCS_CMD(0xB0, 0x0C),
-	_INIT_DCS_CMD(0xB1, 0x04),
-	_INIT_DCS_CMD(0xB2, 0x02),
-	_INIT_DCS_CMD(0xB3, 0x16),
-	_INIT_DCS_CMD(0xB4, 0x24),
-	_INIT_DCS_CMD(0xB5, 0x3B),
-	_INIT_DCS_CMD(0xB6, 0x4F),
-	_INIT_DCS_CMD(0xB7, 0x73),
-	_INIT_DCS_CMD(0xB8, 0x99),
-	_INIT_DCS_CMD(0xB9, 0xE0),
-	_INIT_DCS_CMD(0xBA, 0x26),
-	_INIT_DCS_CMD(0xBB, 0xAD),
-	_INIT_DCS_CMD(0xBC, 0x36),
-	_INIT_DCS_CMD(0xBD, 0x3A),
-	_INIT_DCS_CMD(0xBE, 0xAE),
-	_INIT_DCS_CMD(0xBF, 0x2A),
-	_INIT_DCS_CMD(0xC0, 0x66),
-	_INIT_DCS_CMD(0xC1, 0x9E),
-	_INIT_DCS_CMD(0xC2, 0xB8),
-	_INIT_DCS_CMD(0xC3, 0xD1),
-	_INIT_DCS_CMD(0xC4, 0xDD),
-	_INIT_DCS_CMD(0xC5, 0xE9),
-	_INIT_DCS_CMD(0xC6, 0xF6),
-	_INIT_DCS_CMD(0xC7, 0xFA),
-	_INIT_DCS_CMD(0xC8, 0xFC),
-	_INIT_DCS_CMD(0xC9, 0x00),
-	_INIT_DCS_CMD(0xCA, 0x00),
-	_INIT_DCS_CMD(0xCB, 0x16),
-	_INIT_DCS_CMD(0xCC, 0xAF),
-	_INIT_DCS_CMD(0xCD, 0xFF),
-	_INIT_DCS_CMD(0xCE, 0xFF),
-	_INIT_DCS_CMD(0xB0, 0x00),
-	_INIT_DCS_CMD(0xB3, 0x08),
-	_INIT_DCS_CMD(0xB0, 0x04),
-	_INIT_DCS_CMD(0xB8, 0x68),
-	_INIT_DELAY_CMD(150),
-	{},
+	return 0;
 };
 
-static const struct panel_init_cmd auo_kd101n80_45na_init_cmd[] = {
-	_INIT_DELAY_CMD(24),
-	_INIT_DCS_CMD(0x11),
-	_INIT_DELAY_CMD(120),
-	_INIT_DCS_CMD(0x29),
-	_INIT_DELAY_CMD(120),
-	{},
+static int auo_kd101n80_45na_init(struct boe_panel *boe)
+{
+	struct mipi_dsi_multi_context ctx = { .dsi = boe->dsi };
+
+	msleep(24);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x11);
+	if (ctx.accum_err)
+		return ctx.accum_err;
+
+	msleep(120);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x29);
+	if (ctx.accum_err)
+		return ctx.accum_err;
+
+	msleep(120);
+
+	return 0;
 };
 
-static const struct panel_init_cmd auo_b101uan08_3_init_cmd[] = {
-	_INIT_DELAY_CMD(24),
-	_INIT_DCS_CMD(0xB0, 0x01),
-	_INIT_DCS_CMD(0xC0, 0x48),
-	_INIT_DCS_CMD(0xC1, 0x48),
-	_INIT_DCS_CMD(0xC2, 0x47),
-	_INIT_DCS_CMD(0xC3, 0x47),
-	_INIT_DCS_CMD(0xC4, 0x46),
-	_INIT_DCS_CMD(0xC5, 0x46),
-	_INIT_DCS_CMD(0xC6, 0x45),
-	_INIT_DCS_CMD(0xC7, 0x45),
-	_INIT_DCS_CMD(0xC8, 0x64),
-	_INIT_DCS_CMD(0xC9, 0x64),
-	_INIT_DCS_CMD(0xCA, 0x4F),
-	_INIT_DCS_CMD(0xCB, 0x4F),
-	_INIT_DCS_CMD(0xCC, 0x40),
-	_INIT_DCS_CMD(0xCD, 0x40),
-	_INIT_DCS_CMD(0xCE, 0x66),
-	_INIT_DCS_CMD(0xCF, 0x66),
-	_INIT_DCS_CMD(0xD0, 0x4F),
-	_INIT_DCS_CMD(0xD1, 0x4F),
-	_INIT_DCS_CMD(0xD2, 0x41),
-	_INIT_DCS_CMD(0xD3, 0x41),
-	_INIT_DCS_CMD(0xD4, 0x48),
-	_INIT_DCS_CMD(0xD5, 0x48),
-	_INIT_DCS_CMD(0xD6, 0x47),
-	_INIT_DCS_CMD(0xD7, 0x47),
-	_INIT_DCS_CMD(0xD8, 0x46),
-	_INIT_DCS_CMD(0xD9, 0x46),
-	_INIT_DCS_CMD(0xDA, 0x45),
-	_INIT_DCS_CMD(0xDB, 0x45),
-	_INIT_DCS_CMD(0xDC, 0x64),
-	_INIT_DCS_CMD(0xDD, 0x64),
-	_INIT_DCS_CMD(0xDE, 0x4F),
-	_INIT_DCS_CMD(0xDF, 0x4F),
-	_INIT_DCS_CMD(0xE0, 0x40),
-	_INIT_DCS_CMD(0xE1, 0x40),
-	_INIT_DCS_CMD(0xE2, 0x66),
-	_INIT_DCS_CMD(0xE3, 0x66),
-	_INIT_DCS_CMD(0xE4, 0x4F),
-	_INIT_DCS_CMD(0xE5, 0x4F),
-	_INIT_DCS_CMD(0xE6, 0x41),
-	_INIT_DCS_CMD(0xE7, 0x41),
-	_INIT_DELAY_CMD(150),
-	{},
+static int auo_b101uan08_3_init(struct boe_panel *boe)
+{
+	struct mipi_dsi_multi_context ctx = { .dsi = boe->dsi };
+
+	msleep(24);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x48);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x48);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0x47);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0x47);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0x46);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0x46);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0x45);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0x45);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0x64);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x64);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x4f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x4f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0x40);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0x40);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0x66);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcf, 0x66);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd0, 0x4f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd1, 0x4f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd2, 0x41);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd3, 0x41);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd4, 0x48);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd5, 0x48);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd6, 0x47);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd7, 0x47);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd8, 0x46);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd9, 0x46);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xda, 0x45);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdb, 0x45);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdc, 0x64);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdd, 0x64);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xde, 0x4f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdf, 0x4f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe0, 0x40);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe1, 0x40);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe2, 0x66);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe3, 0x66);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe4, 0x4f);
+	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);
+
+	return 0;
 };
 
-static const struct panel_init_cmd starry_qfh032011_53g_init_cmd[] = {
-	_INIT_DCS_CMD(0xB0, 0x01),
-	_INIT_DCS_CMD(0xC3, 0x4F),
-	_INIT_DCS_CMD(0xC4, 0x40),
-	_INIT_DCS_CMD(0xC5, 0x40),
-	_INIT_DCS_CMD(0xC6, 0x40),
-	_INIT_DCS_CMD(0xC7, 0x40),
-	_INIT_DCS_CMD(0xC8, 0x4D),
-	_INIT_DCS_CMD(0xC9, 0x52),
-	_INIT_DCS_CMD(0xCA, 0x51),
-	_INIT_DCS_CMD(0xCD, 0x5D),
-	_INIT_DCS_CMD(0xCE, 0x5B),
-	_INIT_DCS_CMD(0xCF, 0x4B),
-	_INIT_DCS_CMD(0xD0, 0x49),
-	_INIT_DCS_CMD(0xD1, 0x47),
-	_INIT_DCS_CMD(0xD2, 0x45),
-	_INIT_DCS_CMD(0xD3, 0x41),
-	_INIT_DCS_CMD(0xD7, 0x50),
-	_INIT_DCS_CMD(0xD8, 0x40),
-	_INIT_DCS_CMD(0xD9, 0x40),
-	_INIT_DCS_CMD(0xDA, 0x40),
-	_INIT_DCS_CMD(0xDB, 0x40),
-	_INIT_DCS_CMD(0xDC, 0x4E),
-	_INIT_DCS_CMD(0xDD, 0x52),
-	_INIT_DCS_CMD(0xDE, 0x51),
-	_INIT_DCS_CMD(0xE1, 0x5E),
-	_INIT_DCS_CMD(0xE2, 0x5C),
-	_INIT_DCS_CMD(0xE3, 0x4C),
-	_INIT_DCS_CMD(0xE4, 0x4A),
-	_INIT_DCS_CMD(0xE5, 0x48),
-	_INIT_DCS_CMD(0xE6, 0x46),
-	_INIT_DCS_CMD(0xE7, 0x42),
-	_INIT_DCS_CMD(0xB0, 0x03),
-	_INIT_DCS_CMD(0xBE, 0x03),
-	_INIT_DCS_CMD(0xCC, 0x44),
-	_INIT_DCS_CMD(0xC8, 0x07),
-	_INIT_DCS_CMD(0xC9, 0x05),
-	_INIT_DCS_CMD(0xCA, 0x42),
-	_INIT_DCS_CMD(0xCD, 0x3E),
-	_INIT_DCS_CMD(0xCF, 0x60),
-	_INIT_DCS_CMD(0xD2, 0x04),
-	_INIT_DCS_CMD(0xD3, 0x04),
-	_INIT_DCS_CMD(0xD4, 0x01),
-	_INIT_DCS_CMD(0xD5, 0x00),
-	_INIT_DCS_CMD(0xD6, 0x03),
-	_INIT_DCS_CMD(0xD7, 0x04),
-	_INIT_DCS_CMD(0xD9, 0x01),
-	_INIT_DCS_CMD(0xDB, 0x01),
-	_INIT_DCS_CMD(0xE4, 0xF0),
-	_INIT_DCS_CMD(0xE5, 0x0A),
-	_INIT_DCS_CMD(0xB0, 0x00),
-	_INIT_DCS_CMD(0xCC, 0x08),
-	_INIT_DCS_CMD(0xC2, 0x08),
-	_INIT_DCS_CMD(0xC4, 0x10),
-	_INIT_DCS_CMD(0xB0, 0x02),
-	_INIT_DCS_CMD(0xC0, 0x00),
-	_INIT_DCS_CMD(0xC1, 0x0A),
-	_INIT_DCS_CMD(0xC2, 0x20),
-	_INIT_DCS_CMD(0xC3, 0x24),
-	_INIT_DCS_CMD(0xC4, 0x23),
-	_INIT_DCS_CMD(0xC5, 0x29),
-	_INIT_DCS_CMD(0xC6, 0x23),
-	_INIT_DCS_CMD(0xC7, 0x1C),
-	_INIT_DCS_CMD(0xC8, 0x19),
-	_INIT_DCS_CMD(0xC9, 0x17),
-	_INIT_DCS_CMD(0xCA, 0x17),
-	_INIT_DCS_CMD(0xCB, 0x18),
-	_INIT_DCS_CMD(0xCC, 0x1A),
-	_INIT_DCS_CMD(0xCD, 0x1E),
-	_INIT_DCS_CMD(0xCE, 0x20),
-	_INIT_DCS_CMD(0xCF, 0x23),
-	_INIT_DCS_CMD(0xD0, 0x07),
-	_INIT_DCS_CMD(0xD1, 0x00),
-	_INIT_DCS_CMD(0xD2, 0x00),
-	_INIT_DCS_CMD(0xD3, 0x0A),
-	_INIT_DCS_CMD(0xD4, 0x13),
-	_INIT_DCS_CMD(0xD5, 0x1C),
-	_INIT_DCS_CMD(0xD6, 0x1A),
-	_INIT_DCS_CMD(0xD7, 0x13),
-	_INIT_DCS_CMD(0xD8, 0x17),
-	_INIT_DCS_CMD(0xD9, 0x1C),
-	_INIT_DCS_CMD(0xDA, 0x19),
-	_INIT_DCS_CMD(0xDB, 0x17),
-	_INIT_DCS_CMD(0xDC, 0x17),
-	_INIT_DCS_CMD(0xDD, 0x18),
-	_INIT_DCS_CMD(0xDE, 0x1A),
-	_INIT_DCS_CMD(0xDF, 0x1E),
-	_INIT_DCS_CMD(0xE0, 0x20),
-	_INIT_DCS_CMD(0xE1, 0x23),
-	_INIT_DCS_CMD(0xE2, 0x07),
-	_INIT_DCS_CMD(0X11),
-	_INIT_DELAY_CMD(120),
-	_INIT_DCS_CMD(0X29),
-	_INIT_DELAY_CMD(80),
-	{},
+static int starry_qfh032011_53g_init(struct boe_panel *boe)
+{
+	struct mipi_dsi_multi_context ctx = { .dsi = boe->dsi };
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0x4f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0x40);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0x40);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0x40);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0x40);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0x4d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x52);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x51);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0x5d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0x5b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcf, 0x4b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd0, 0x49);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd1, 0x47);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd2, 0x45);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd3, 0x41);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd7, 0x50);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd8, 0x40);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd9, 0x40);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xda, 0x40);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdb, 0x40);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdc, 0x4e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdd, 0x52);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xde, 0x51);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe1, 0x5e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe2, 0x5c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe3, 0x4c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe4, 0x4a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5, 0x48);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe6, 0x46);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe7, 0x42);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbe, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0x44);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x42);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0x3e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcf, 0x60);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd2, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd3, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd4, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd5, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd6, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd7, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd9, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdb, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe4, 0xf0);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5, 0x0a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0x08);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0x08);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0x10);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x0a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0x20);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0x24);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0x23);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0x29);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0x23);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0x1c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0x19);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x17);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x17);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x18);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0x1a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0x1e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0x20);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcf, 0x23);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd0, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd1, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd2, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd3, 0x0a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd4, 0x13);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd5, 0x1c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd6, 0x1a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd7, 0x13);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd8, 0x17);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd9, 0x1c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xda, 0x19);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdb, 0x17);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdc, 0x17);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdd, 0x18);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xde, 0x1a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdf, 0x1e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe0, 0x20);
+	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_dcs_write_seq_multi(&ctx, 0X29);
+	if (ctx.accum_err)
+		return ctx.accum_err;
+
+	msleep(80);
+
+	return 0;
 };
 
-static const struct panel_init_cmd starry_himax83102_j02_init_cmd[] = {
-	_INIT_DCS_CMD(0xB9, 0x83, 0x10, 0x21, 0x55, 0x00),
-	_INIT_DCS_CMD(0xB1, 0x2C, 0xB5, 0xB5, 0x31, 0xF1, 0x31, 0xD7, 0x2F, 0x36, 0x36, 0x36, 0x36, 0x1A, 0x8B, 0x11,
-		0x65, 0x00, 0x88, 0xFA, 0xFF, 0xFF, 0x8F, 0xFF, 0x08, 0x74, 0x33),
-	_INIT_DCS_CMD(0xB2, 0x00, 0x47, 0xB0, 0x80, 0x00, 0x12, 0x72, 0x3C, 0xA3, 0x03, 0x03, 0x00, 0x00, 0x88, 0xF5),
-	_INIT_DCS_CMD(0xB4, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x63, 0x5C, 0x63, 0x5C, 0x01, 0x9E),
-	_INIT_DCS_CMD(0xE9, 0xCD),
-	_INIT_DCS_CMD(0xBA, 0x84),
-	_INIT_DCS_CMD(0xE9, 0x3F),
-	_INIT_DCS_CMD(0xBC, 0x1B, 0x04),
-	_INIT_DCS_CMD(0xBE, 0x20),
-	_INIT_DCS_CMD(0xBF, 0xFC, 0xC4),
-	_INIT_DCS_CMD(0xC0, 0x36, 0x36, 0x22, 0x11, 0x22, 0xA0, 0x61, 0x08, 0xF5, 0x03),
-	_INIT_DCS_CMD(0xE9, 0xCC),
-	_INIT_DCS_CMD(0xC7, 0x80),
-	_INIT_DCS_CMD(0xE9, 0x3F),
-	_INIT_DCS_CMD(0xE9, 0xC6),
-	_INIT_DCS_CMD(0xC8, 0x97),
-	_INIT_DCS_CMD(0xE9, 0x3F),
-	_INIT_DCS_CMD(0xC9, 0x00, 0x1E, 0x13, 0x88, 0x01),
-	_INIT_DCS_CMD(0xCB, 0x08, 0x13, 0x07, 0x00, 0x0F, 0x33),
-	_INIT_DCS_CMD(0xCC, 0x02),
-	_INIT_DCS_CMD(0xE9, 0xC4),
-	_INIT_DCS_CMD(0xD0, 0x03),
-	_INIT_DCS_CMD(0xE9, 0x3F),
-	_INIT_DCS_CMD(0xD1, 0x37, 0x06, 0x00, 0x02, 0x04, 0x0C, 0xFF),
-	_INIT_DCS_CMD(0xD2, 0x1F, 0x11, 0x1F),
-	_INIT_DCS_CMD(0xD3, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x37, 0x47, 0x34, 0x3B, 0x12, 0x12, 0x03,
-		0x03, 0x32, 0x10, 0x10, 0x00, 0x10, 0x32, 0x10, 0x08, 0x00, 0x08, 0x32, 0x17, 0x94, 0x07, 0x94, 0x00, 0x00),
-	_INIT_DCS_CMD(0xD5, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x40, 0x40, 0x1A, 0x1A,
-		0x1B, 0x1B, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x20, 0x21, 0x28, 0x29, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18),
-	_INIT_DCS_CMD(0xD6, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x40, 0x40, 0x19, 0x19, 0x1A, 0x1A,
-		0x1B, 0x1B, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x29, 0x28, 0x21, 0x20, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18),
-	_INIT_DCS_CMD(0xD8, 0xAA, 0xBA, 0xEA, 0xAA, 0xAA, 0xA0, 0xAA, 0xBA, 0xEA, 0xAA, 0xAA, 0xA0, 0xAA, 0xBA, 0xEA, 0xAA,
-		0xAA, 0xA0, 0xAA, 0xBA, 0xEA, 0xAA, 0xAA, 0xA0, 0xAA, 0xBA, 0xEA, 0xAA, 0xAA, 0xA0, 0xAA, 0xBA, 0xEA, 0xAA, 0xAA, 0xA0),
-	_INIT_DCS_CMD(0xE0, 0x00, 0x09, 0x14, 0x1E, 0x26, 0x48, 0x61, 0x67, 0x6C, 0x67, 0x7D, 0x7F, 0x80, 0x8B, 0x87, 0x8F, 0x98, 0xAB,
-		0xAB, 0x55, 0x5C, 0x68, 0x73, 0x00, 0x09, 0x14, 0x1E, 0x26, 0x48, 0x61, 0x67, 0x6C, 0x67, 0x7D, 0x7F, 0x80, 0x8B, 0x87, 0x8F, 0x98, 0xAB, 0xAB, 0x55, 0x5C, 0x68, 0x73),
-	_INIT_DCS_CMD(0xE7, 0x0E, 0x10, 0x10, 0x21, 0x2B, 0x9A, 0x02, 0x54, 0x9A, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x12, 0x05, 0x02, 0x02, 0x10),
-	_INIT_DCS_CMD(0xBD, 0x01),
-	_INIT_DCS_CMD(0xB1, 0x01, 0xBF, 0x11),
-	_INIT_DCS_CMD(0xCB, 0x86),
-	_INIT_DCS_CMD(0xD2, 0x3C, 0xFA),
-	_INIT_DCS_CMD(0xD3, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0C, 0x01),
-	_INIT_DCS_CMD(0xE7, 0x02, 0x00, 0x28, 0x01, 0x7E, 0x0F, 0x7E, 0x10, 0xA0, 0x00, 0x00, 0x20, 0x40, 0x50, 0x40),
-	_INIT_DCS_CMD(0xBD, 0x02),
-	_INIT_DCS_CMD(0xD8, 0xFF, 0xFF, 0xBF, 0xFE, 0xAA, 0xA0, 0xFF, 0xFF, 0xBF, 0xFE, 0xAA, 0xA0),
-	_INIT_DCS_CMD(0xE7, 0xFE, 0x04, 0xFE, 0x04, 0xFE, 0x04, 0x03, 0x03, 0x03, 0x26, 0x00, 0x26, 0x81, 0x02, 0x40, 0x00, 0x20, 0x9E, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00),
-	_INIT_DCS_CMD(0xBD, 0x03),
-	_INIT_DCS_CMD(0xE9, 0xC6),
-	_INIT_DCS_CMD(0xB4, 0x03, 0xFF, 0xF8),
-	_INIT_DCS_CMD(0xE9, 0x3F),
-	_INIT_DCS_CMD(0xD8, 0x00, 0x2A, 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xA8,
-		0x00, 0x00, 0x00, 0x2A, 0xAA, 0xA8, 0x00, 0x00),
-	_INIT_DCS_CMD(0xBD, 0x00),
-	_INIT_DCS_CMD(0xE9, 0xC4),
-	_INIT_DCS_CMD(0xBA, 0x96),
-	_INIT_DCS_CMD(0xE9, 0x3F),
-	_INIT_DCS_CMD(0xBD, 0x01),
-	_INIT_DCS_CMD(0xE9, 0xC5),
-	_INIT_DCS_CMD(0xBA, 0x4F),
-	_INIT_DCS_CMD(0xE9, 0x3F),
-	_INIT_DCS_CMD(0xBD, 0x00),
-	_INIT_DCS_CMD(0x11),
-	_INIT_DELAY_CMD(120),
-	_INIT_DCS_CMD(0x29),
-	{},
+static int starry_himax83102_j02_init(struct boe_panel *boe)
+{
+	struct mipi_dsi_multi_context ctx = { .dsi = boe->dsi };
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0x83, 0x10, 0x21, 0x55, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x2c, 0xb5, 0xb5, 0x31, 0xf1, 0x31, 0xd7, 0x2f,
+				     0x36, 0x36, 0x36, 0x36, 0x1a, 0x8b, 0x11, 0x65, 0x00, 0x88,
+				     0xfa, 0xff, 0xff, 0x8f, 0xff, 0x08, 0x74, 0x33);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x00, 0x47, 0xb0, 0x80, 0x00, 0x12, 0x72, 0x3c,
+				     0xa3, 0x03, 0x03, 0x00, 0x00, 0x88, 0xf5);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x63, 0x5c,
+				     0x63, 0x5c, 0x01, 0x9e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe9, 0xcd);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x84);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe9, 0x3f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbc, 0x1b, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbe, 0x20);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbf, 0xfc, 0xc4);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x36, 0x36, 0x22, 0x11, 0x22, 0xa0, 0x61, 0x08,
+				     0xf5, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe9, 0xcc);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0x80);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe9, 0x3f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe9, 0xc6);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0x97);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe9, 0x3f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x00, 0x1e, 0x13, 0x88, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x08, 0x13, 0x07, 0x00, 0x0f, 0x33);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe9, 0xc4);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd0, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe9, 0x3f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd1, 0x37, 0x06, 0x00, 0x02, 0x04, 0x0c, 0xff);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd2, 0x1f, 0x11, 0x1f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd3, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+				     0x08, 0x37, 0x47, 0x34, 0x3b, 0x12, 0x12, 0x03, 0x03, 0x32,
+				     0x10, 0x10, 0x00, 0x10, 0x32, 0x10, 0x08, 0x00, 0x08, 0x32,
+				     0x17, 0x94, 0x07, 0x94, 0x00, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd5, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+				     0x18, 0x18, 0x19, 0x19, 0x40, 0x40, 0x1a, 0x1a, 0x1b, 0x1b,
+				     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x20, 0x21,
+				     0x28, 0x29, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+				     0x18, 0x18, 0x18, 0x18, 0x18, 0x18);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd6, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+				     0x18, 0x18, 0x40, 0x40, 0x19, 0x19, 0x1a, 0x1a, 0x1b, 0x1b,
+				     0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x29, 0x28,
+				     0x21, 0x20, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+				     0x18, 0x18, 0x18, 0x18, 0x18, 0x18);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd8, 0xaa, 0xba, 0xea, 0xaa, 0xaa, 0xa0, 0xaa, 0xba,
+				     0xea, 0xaa, 0xaa, 0xa0, 0xaa, 0xba, 0xea, 0xaa, 0xaa, 0xa0,
+				     0xaa, 0xba, 0xea, 0xaa, 0xaa, 0xa0, 0xaa, 0xba, 0xea, 0xaa,
+				     0xaa, 0xa0, 0xaa, 0xba, 0xea, 0xaa, 0xaa, 0xa0);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe0, 0x00, 0x09, 0x14, 0x1e, 0x26, 0x48, 0x61, 0x67,
+				     0x6c, 0x67, 0x7d, 0x7f, 0x80, 0x8b, 0x87, 0x8f, 0x98, 0xab,
+				     0xab, 0x55, 0x5c, 0x68, 0x73, 0x00, 0x09, 0x14, 0x1e, 0x26,
+				     0x48, 0x61, 0x67, 0x6c, 0x67, 0x7d, 0x7f, 0x80, 0x8b, 0x87,
+				     0x8f, 0x98, 0xab, 0xab, 0x55, 0x5c, 0x68, 0x73);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe7, 0x0e, 0x10, 0x10, 0x21, 0x2b, 0x9a, 0x02, 0x54,
+				     0x9a, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x12, 0x05, 0x02,
+				     0x02, 0x10);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x01, 0xbf, 0x11);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x86);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd2, 0x3c, 0xfa);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd3, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
+				     0x80, 0x0c, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe7, 0x02, 0x00, 0x28, 0x01, 0x7e, 0x0f, 0x7e, 0x10,
+				     0xa0, 0x00, 0x00, 0x20, 0x40, 0x50, 0x40);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd8, 0xff, 0xff, 0xbf, 0xfe, 0xaa, 0xa0, 0xff, 0xff,
+				     0xbf, 0xfe, 0xaa, 0xa0);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe7, 0xfe, 0x04, 0xfe, 0x04, 0xfe, 0x04, 0x03, 0x03,
+				     0x03, 0x26, 0x00, 0x26, 0x81, 0x02, 0x40, 0x00, 0x20, 0x9e,
+				     0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe9, 0xc6);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x03, 0xff, 0xf8);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe9, 0x3f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd8, 0x00, 0x2a, 0xaa, 0xa8, 0x00, 0x00, 0x00, 0x2a,
+				     0xaa, 0xa8, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xfc, 0x00, 0x00,
+				     0x00, 0x3f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x2a, 0xaa, 0xa8,
+				     0x00, 0x00, 0x00, 0x2a, 0xaa, 0xa8, 0x00, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe9, 0xc4);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x96);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe9, 0x3f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe9, 0xc5);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x4f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe9, 0x3f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x11);
+	if (ctx.accum_err)
+		return ctx.accum_err;
+
+	msleep(120);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x29);
+
+	return ctx.accum_err;
 };
 
 static inline struct boe_panel *to_boe_panel(struct drm_panel *panel)
@@ -1373,45 +1506,6 @@ static inline struct boe_panel *to_boe_panel(struct drm_panel *panel)
 	return container_of(panel, struct boe_panel, base);
 }
 
-static int boe_panel_init_dcs_cmd(struct boe_panel *boe)
-{
-	struct mipi_dsi_device *dsi = boe->dsi;
-	struct drm_panel *panel = &boe->base;
-	int i, err = 0;
-
-	if (boe->desc->init_cmds) {
-		const struct panel_init_cmd *init_cmds = boe->desc->init_cmds;
-
-		for (i = 0; init_cmds[i].len != 0; i++) {
-			const struct panel_init_cmd *cmd = &init_cmds[i];
-
-			switch (cmd->type) {
-			case DELAY_CMD:
-				msleep(cmd->data[0]);
-				err = 0;
-				break;
-
-			case INIT_DCS_CMD:
-				err = mipi_dsi_dcs_write(dsi, cmd->data[0],
-							 cmd->len <= 1 ? NULL :
-							 &cmd->data[1],
-							 cmd->len - 1);
-				break;
-
-			default:
-				err = -EINVAL;
-			}
-
-			if (err < 0) {
-				dev_err(panel->dev,
-					"failed to write command %u\n", i);
-				return err;
-			}
-		}
-	}
-	return 0;
-}
-
 static int boe_panel_enter_sleep_mode(struct boe_panel *boe)
 {
 	struct mipi_dsi_device *dsi = boe->dsi;
@@ -1517,11 +1611,9 @@ static int boe_panel_prepare(struct drm_panel *panel)
 	gpiod_set_value(boe->enable_gpio, 1);
 	usleep_range(6000, 10000);
 
-	ret = boe_panel_init_dcs_cmd(boe);
-	if (ret < 0) {
-		dev_err(panel->dev, "failed to init panel: %d\n", ret);
+	ret = boe->desc->init(boe);
+	if (ret < 0)
 		goto poweroff;
-	}
 
 	boe->prepared = true;
 
@@ -1571,7 +1663,7 @@ static const struct panel_desc boe_tv110c9m_desc = {
 			| MIPI_DSI_MODE_VIDEO_HSE
 			| MIPI_DSI_CLOCK_NON_CONTINUOUS
 			| MIPI_DSI_MODE_VIDEO_BURST,
-	.init_cmds = boe_tv110c9m_init_cmd,
+	.init = boe_tv110c9m_init,
 };
 
 static const struct drm_display_mode inx_hj110iz_default_mode = {
@@ -1600,7 +1692,7 @@ static const struct panel_desc inx_hj110iz_desc = {
 			| MIPI_DSI_MODE_VIDEO_HSE
 			| MIPI_DSI_CLOCK_NON_CONTINUOUS
 			| MIPI_DSI_MODE_VIDEO_BURST,
-	.init_cmds = inx_hj110iz_init_cmd,
+	.init = inx_hj110iz_init,
 };
 
 static const struct drm_display_mode boe_tv101wum_nl6_default_mode = {
@@ -1626,7 +1718,7 @@ static const struct panel_desc boe_tv101wum_nl6_desc = {
 	.format = MIPI_DSI_FMT_RGB888,
 	.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
 		      MIPI_DSI_MODE_LPM,
-	.init_cmds = boe_init_cmd,
+	.init = boe_init,
 	.discharge_on_disable = false,
 };
 
@@ -1653,7 +1745,7 @@ static const struct panel_desc auo_kd101n80_45na_desc = {
 	.format = MIPI_DSI_FMT_RGB888,
 	.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
 		      MIPI_DSI_MODE_LPM,
-	.init_cmds = auo_kd101n80_45na_init_cmd,
+	.init = auo_kd101n80_45na_init,
 	.discharge_on_disable = true,
 };
 
@@ -1681,7 +1773,7 @@ static const struct panel_desc boe_tv101wum_n53_desc = {
 	.format = MIPI_DSI_FMT_RGB888,
 	.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
 		      MIPI_DSI_MODE_LPM,
-	.init_cmds = boe_init_cmd,
+	.init = boe_init,
 };
 
 static const struct drm_display_mode auo_b101uan08_3_default_mode = {
@@ -1708,7 +1800,7 @@ static const struct panel_desc auo_b101uan08_3_desc = {
 	.format = MIPI_DSI_FMT_RGB888,
 	.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
 		      MIPI_DSI_MODE_LPM,
-	.init_cmds = auo_b101uan08_3_init_cmd,
+	.init = auo_b101uan08_3_init,
 	.lp11_before_reset = true,
 };
 
@@ -1736,7 +1828,7 @@ static const struct panel_desc boe_tv105wum_nw0_desc = {
 	.format = MIPI_DSI_FMT_RGB888,
 	.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
 		      MIPI_DSI_MODE_LPM,
-	.init_cmds = boe_init_cmd,
+	.init = boe_init,
 	.lp11_before_reset = true,
 };
 
@@ -1763,7 +1855,7 @@ static const struct panel_desc starry_qfh032011_53g_desc = {
 	.format = MIPI_DSI_FMT_RGB888,
 	.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
 		      MIPI_DSI_MODE_LPM,
-	.init_cmds = starry_qfh032011_53g_init_cmd,
+	.init = starry_qfh032011_53g_init,
 	.lp11_before_reset = true,
 };
 
@@ -1791,7 +1883,7 @@ static const struct panel_desc starry_himax83102_j02_desc = {
 	.format = MIPI_DSI_FMT_RGB888,
 	.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
 		      MIPI_DSI_MODE_LPM,
-	.init_cmds = starry_himax83102_j02_init_cmd,
+	.init = starry_himax83102_j02_init,
 	.lp11_before_reset = true,
 };
 
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog


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

* [PATCH v4 8/9] drm/panel: ili9882t: Don't use a table for initting panels
  2024-05-08 20:51 [PATCH v4 0/9] drm/mipi-dsi: Reduce bloat and add funcs for cleaner init seqs Douglas Anderson
                   ` (6 preceding siblings ...)
  2024-05-08 20:51 ` [PATCH v4 7/9] drm/panel: boe-tv101wum-nl6: Don't use a table for initting panels Douglas Anderson
@ 2024-05-08 20:51 ` Douglas Anderson
  2024-05-08 20:51 ` [PATCH v4 9/9] drm/panel: innolux-p079zca: " Douglas Anderson
  8 siblings, 0 replies; 14+ messages in thread
From: Douglas Anderson @ 2024-05-08 20:51 UTC (permalink / raw
  To: dri-devel
  Cc: lvzhaoxiong, Jani Nikula, Hsin-Yi Wang, Linus Walleij,
	Javier Martinez Canillas, Neil Armstrong, Cong Yang, Sam Ravnborg,
	Dmitry Baryshkov, Joel Selvaraj, Brian Norris, Douglas Anderson,
	Daniel Vetter, David Airlie, Jessica Zhang, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, linux-kernel

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_cmd                    7320       -   -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 <linus.walleij@linaro.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---

(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 <video/mipi_display.h>
 
+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),
-	_INIT_DCS_CMD(0x4E, 0x28),
-	_INIT_DCS_CMD(0x4F, 0x29),
-	_INIT_DCS_CMD(0x50, 0x10),
-	_INIT_DCS_CMD(0x51, 0x12),
-	_INIT_DCS_CMD(0x52, 0x14),
-	_INIT_DCS_CMD(0x53, 0x16),
-	_INIT_DCS_CMD(0x54, 0x08),
-	_INIT_DCS_CMD(0x55, 0x0C),
-	_INIT_DCS_CMD(0x56, 0x02),
-	_INIT_DCS_CMD(0x57, 0x02),
-	_INIT_DCS_CMD(0x58, 0x02),
-	_INIT_DCS_CMD(0x59, 0x02),
-	_INIT_DCS_CMD(0x5A, 0x02),
-	_INIT_DCS_CMD(0x5B, 0x02),
-	_INIT_DCS_CMD(0x5C, 0x02),
-
-	_INIT_DCS_CMD(0x61, 0x07),
-	_INIT_DCS_CMD(0x62, 0x07),
-	_INIT_DCS_CMD(0x63, 0x07),
-	_INIT_DCS_CMD(0x64, 0x07),
-	_INIT_DCS_CMD(0x65, 0x07),
-	_INIT_DCS_CMD(0x66, 0x01),
-	_INIT_DCS_CMD(0x67, 0x00),
-	_INIT_DCS_CMD(0x68, 0x28),
-	_INIT_DCS_CMD(0x69, 0x29),
-	_INIT_DCS_CMD(0x6A, 0x16),
-	_INIT_DCS_CMD(0x6B, 0x14),
-	_INIT_DCS_CMD(0x6C, 0x12),
-	_INIT_DCS_CMD(0x6D, 0x10),
-	_INIT_DCS_CMD(0x6E, 0x0C),
-	_INIT_DCS_CMD(0x6F, 0x08),
-	_INIT_DCS_CMD(0x70, 0x02),
-	_INIT_DCS_CMD(0x71, 0x02),
-	_INIT_DCS_CMD(0x72, 0x02),
-	_INIT_DCS_CMD(0x73, 0x02),
-	_INIT_DCS_CMD(0x74, 0x02),
-	_INIT_DCS_CMD(0x75, 0x02),
-	_INIT_DCS_CMD(0x76, 0x02),
-
-	_INIT_DCS_CMD(0x77, 0x07),
-	_INIT_DCS_CMD(0x78, 0x07),
-	_INIT_DCS_CMD(0x79, 0x07),
-	_INIT_DCS_CMD(0x7A, 0x07),
-	_INIT_DCS_CMD(0x7B, 0x07),
-	_INIT_DCS_CMD(0x7C, 0x01),
-	_INIT_DCS_CMD(0x7D, 0x00),
-	_INIT_DCS_CMD(0x7E, 0x28),
-	_INIT_DCS_CMD(0x7F, 0x29),
-	_INIT_DCS_CMD(0x80, 0x17),
-	_INIT_DCS_CMD(0x81, 0x15),
-	_INIT_DCS_CMD(0x82, 0x13),
-	_INIT_DCS_CMD(0x83, 0x11),
-	_INIT_DCS_CMD(0x84, 0x0D),
-	_INIT_DCS_CMD(0x85, 0x09),
-	_INIT_DCS_CMD(0x86, 0x02),
-	_INIT_DCS_CMD(0x87, 0x07),
-	_INIT_DCS_CMD(0x88, 0x07),
-	_INIT_DCS_CMD(0x89, 0x07),
-	_INIT_DCS_CMD(0x8A, 0x07),
-	_INIT_DCS_CMD(0x8B, 0x07),
-	_INIT_DCS_CMD(0x8C, 0x07),
-
-	_INIT_SWITCH_PAGE_CMD(0x02),
-	_INIT_DCS_CMD(0x29, 0x3A),
-	_INIT_DCS_CMD(0x2A, 0x3B),
-
-	_INIT_DCS_CMD(0x06, 0x01),
-	_INIT_DCS_CMD(0x07, 0x01),
-	_INIT_DCS_CMD(0x08, 0x0C),
-	_INIT_DCS_CMD(0x09, 0x44),
-
-	_INIT_DCS_CMD(0x3C, 0x0A),
-	_INIT_DCS_CMD(0x39, 0x11),
-	_INIT_DCS_CMD(0x3D, 0x00),
-	_INIT_DCS_CMD(0x3A, 0x0C),
-	_INIT_DCS_CMD(0x3B, 0x44),
-
-	_INIT_DCS_CMD(0x53, 0x1F),
-	_INIT_DCS_CMD(0x5E, 0x40),
-	_INIT_DCS_CMD(0x84, 0x00),
-
-	_INIT_SWITCH_PAGE_CMD(0x03),
-	_INIT_DCS_CMD(0x20, 0x01),
-	_INIT_DCS_CMD(0x21, 0x3C),
-	_INIT_DCS_CMD(0x22, 0xFA),
-
-	_INIT_SWITCH_PAGE_CMD(0x0A),
-	_INIT_DCS_CMD(0xE0, 0x01),
-	_INIT_DCS_CMD(0xE2, 0x01),
-	_INIT_DCS_CMD(0xE5, 0x91),
-	_INIT_DCS_CMD(0xE6, 0x3C),
-	_INIT_DCS_CMD(0xE7, 0x00),
-	_INIT_DCS_CMD(0xE8, 0xFA),
-
-	_INIT_SWITCH_PAGE_CMD(0x12),
-	_INIT_DCS_CMD(0x87, 0x2C),
-
-	_INIT_SWITCH_PAGE_CMD(0x05),
-	_INIT_DCS_CMD(0x73, 0xE5),
-	_INIT_DCS_CMD(0x7F, 0x6B),
-	_INIT_DCS_CMD(0x6D, 0xA4),
-	_INIT_DCS_CMD(0x79, 0x54),
-	_INIT_DCS_CMD(0x69, 0x97),
-	_INIT_DCS_CMD(0x6A, 0x97),
-	_INIT_DCS_CMD(0xA5, 0x3F),
-	_INIT_DCS_CMD(0x61, 0xDA),
-	_INIT_DCS_CMD(0xA7, 0xF1),
-	_INIT_DCS_CMD(0x5F, 0x01),
-	_INIT_DCS_CMD(0x62, 0x3F),
-	_INIT_DCS_CMD(0x1D, 0x90),
-	_INIT_DCS_CMD(0x86, 0x87),
-
-	_INIT_SWITCH_PAGE_CMD(0x06),
-	_INIT_DCS_CMD(0xC0, 0x80),
-	_INIT_DCS_CMD(0xC1, 0x07),
-	_INIT_DCS_CMD(0xCA, 0x58),
-	_INIT_DCS_CMD(0xCB, 0x02),
-	_INIT_DCS_CMD(0xCE, 0x58),
-	_INIT_DCS_CMD(0xCF, 0x02),
-	_INIT_DCS_CMD(0x67, 0x60),
-	_INIT_DCS_CMD(0x10, 0x00),
-	_INIT_DCS_CMD(0x92, 0x22),
-	_INIT_DCS_CMD(0xD3, 0x08),
-	_INIT_DCS_CMD(0xD6, 0x55),
-	_INIT_DCS_CMD(0xDC, 0x38),
-
-	_INIT_SWITCH_PAGE_CMD(0x08),
-	_INIT_DCS_CMD(0xE0, 0x00, 0x10, 0x2A, 0x4D, 0x61, 0x56, 0x6A, 0x6E, 0x79, 0x76, 0x8F, 0x95, 0x98, 0xAE, 0xAA, 0xB2, 0xBB, 0xCE, 0xC6, 0xBD, 0xD5, 0xE2, 0xE8),
-	_INIT_DCS_CMD(0xE1, 0x00, 0x10, 0x2A, 0x4D, 0x61, 0x56, 0x6A, 0x6E, 0x79, 0x76, 0x8F, 0x95, 0x98, 0xAE, 0xAA, 0xB2, 0xBB, 0xCE, 0xC6, 0xBD, 0xD5, 0xE2, 0xE8),
-
-	_INIT_SWITCH_PAGE_CMD(0x04),
-	_INIT_DCS_CMD(0xBA, 0x81),
-
-	_INIT_SWITCH_PAGE_CMD(0x0C),
-	_INIT_DCS_CMD(0x00, 0x02),
-	_INIT_DCS_CMD(0x01, 0x00),
-	_INIT_DCS_CMD(0x02, 0x03),
-	_INIT_DCS_CMD(0x03, 0x01),
-	_INIT_DCS_CMD(0x04, 0x03),
-	_INIT_DCS_CMD(0x05, 0x02),
-	_INIT_DCS_CMD(0x06, 0x04),
-	_INIT_DCS_CMD(0x07, 0x03),
-	_INIT_DCS_CMD(0x08, 0x03),
-	_INIT_DCS_CMD(0x09, 0x04),
-	_INIT_DCS_CMD(0x0A, 0x04),
-	_INIT_DCS_CMD(0x0B, 0x05),
-	_INIT_DCS_CMD(0x0C, 0x04),
-	_INIT_DCS_CMD(0x0D, 0x06),
-	_INIT_DCS_CMD(0x0E, 0x05),
-	_INIT_DCS_CMD(0x0F, 0x07),
-	_INIT_DCS_CMD(0x10, 0x04),
-	_INIT_DCS_CMD(0x11, 0x08),
-	_INIT_DCS_CMD(0x12, 0x05),
-	_INIT_DCS_CMD(0x13, 0x09),
-	_INIT_DCS_CMD(0x14, 0x05),
-	_INIT_DCS_CMD(0x15, 0x0A),
-	_INIT_DCS_CMD(0x16, 0x06),
-	_INIT_DCS_CMD(0x17, 0x0B),
-	_INIT_DCS_CMD(0x18, 0x05),
-	_INIT_DCS_CMD(0x19, 0x0C),
-	_INIT_DCS_CMD(0x1A, 0x06),
-	_INIT_DCS_CMD(0x1B, 0x0D),
-	_INIT_DCS_CMD(0x1C, 0x06),
-	_INIT_DCS_CMD(0x1D, 0x0E),
-	_INIT_DCS_CMD(0x1E, 0x07),
-	_INIT_DCS_CMD(0x1F, 0x0F),
-	_INIT_DCS_CMD(0x20, 0x06),
-	_INIT_DCS_CMD(0x21, 0x10),
-	_INIT_DCS_CMD(0x22, 0x07),
-	_INIT_DCS_CMD(0x23, 0x11),
-	_INIT_DCS_CMD(0x24, 0x07),
-	_INIT_DCS_CMD(0x25, 0x12),
-	_INIT_DCS_CMD(0x26, 0x08),
-	_INIT_DCS_CMD(0x27, 0x13),
-	_INIT_DCS_CMD(0x28, 0x07),
-	_INIT_DCS_CMD(0x29, 0x14),
-	_INIT_DCS_CMD(0x2A, 0x08),
-	_INIT_DCS_CMD(0x2B, 0x15),
-	_INIT_DCS_CMD(0x2C, 0x08),
-	_INIT_DCS_CMD(0x2D, 0x16),
-	_INIT_DCS_CMD(0x2E, 0x09),
-	_INIT_DCS_CMD(0x2F, 0x17),
-	_INIT_DCS_CMD(0x30, 0x08),
-	_INIT_DCS_CMD(0x31, 0x18),
-	_INIT_DCS_CMD(0x32, 0x09),
-	_INIT_DCS_CMD(0x33, 0x19),
-	_INIT_DCS_CMD(0x34, 0x09),
-	_INIT_DCS_CMD(0x35, 0x1A),
-	_INIT_DCS_CMD(0x36, 0x0A),
-	_INIT_DCS_CMD(0x37, 0x1B),
-	_INIT_DCS_CMD(0x38, 0x0A),
-	_INIT_DCS_CMD(0x39, 0x1C),
-	_INIT_DCS_CMD(0x3A, 0x0A),
-	_INIT_DCS_CMD(0x3B, 0x1D),
-	_INIT_DCS_CMD(0x3C, 0x0A),
-	_INIT_DCS_CMD(0x3D, 0x1E),
-	_INIT_DCS_CMD(0x3E, 0x0A),
-	_INIT_DCS_CMD(0x3F, 0x1F),
-
-	_INIT_SWITCH_PAGE_CMD(0x04),
-	_INIT_DCS_CMD(0xBA, 0x01),
-
-	_INIT_SWITCH_PAGE_CMD(0x0E),
-	_INIT_DCS_CMD(0x02, 0x0C),
-	_INIT_DCS_CMD(0x20, 0x10),
-	_INIT_DCS_CMD(0x25, 0x16),
-	_INIT_DCS_CMD(0x26, 0xE0),
-	_INIT_DCS_CMD(0x27, 0x00),
-	_INIT_DCS_CMD(0x29, 0x71),
-	_INIT_DCS_CMD(0x2A, 0x46),
-	_INIT_DCS_CMD(0x2B, 0x1F),
-	_INIT_DCS_CMD(0x2D, 0xC7),
-	_INIT_DCS_CMD(0x31, 0x02),
-	_INIT_DCS_CMD(0x32, 0xDF),
-	_INIT_DCS_CMD(0x33, 0x5A),
-	_INIT_DCS_CMD(0x34, 0xC0),
-	_INIT_DCS_CMD(0x35, 0x5A),
-	_INIT_DCS_CMD(0x36, 0xC0),
-	_INIT_DCS_CMD(0x38, 0x65),
-	_INIT_DCS_CMD(0x80, 0x3E),
-	_INIT_DCS_CMD(0x81, 0xA0),
-	_INIT_DCS_CMD(0xB0, 0x01),
-	_INIT_DCS_CMD(0xB1, 0xCC),
-	_INIT_DCS_CMD(0xC0, 0x12),
-	_INIT_DCS_CMD(0xC2, 0xCC),
-	_INIT_DCS_CMD(0xC3, 0xCC),
-	_INIT_DCS_CMD(0xC4, 0xCC),
-	_INIT_DCS_CMD(0xC5, 0xCC),
-	_INIT_DCS_CMD(0xC6, 0xCC),
-	_INIT_DCS_CMD(0xC7, 0xCC),
-	_INIT_DCS_CMD(0xC8, 0xCC),
-	_INIT_DCS_CMD(0xC9, 0xCC),
-	_INIT_DCS_CMD(0x30, 0x00),
-	_INIT_DCS_CMD(0x00, 0x81),
-	_INIT_DCS_CMD(0x08, 0x02),
-	_INIT_DCS_CMD(0x09, 0x00),
-	_INIT_DCS_CMD(0x07, 0x21),
-	_INIT_DCS_CMD(0x04, 0x10),
-
-	_INIT_SWITCH_PAGE_CMD(0x1E),
-	_INIT_DCS_CMD(0x60, 0x00),
-	_INIT_DCS_CMD(0x64, 0x00),
-	_INIT_DCS_CMD(0x6D, 0x00),
-
-	_INIT_SWITCH_PAGE_CMD(0x0B),
-	_INIT_DCS_CMD(0xA6, 0x44),
-	_INIT_DCS_CMD(0xA7, 0xB6),
-	_INIT_DCS_CMD(0xA8, 0x03),
-	_INIT_DCS_CMD(0xA9, 0x03),
-	_INIT_DCS_CMD(0xAA, 0x51),
-	_INIT_DCS_CMD(0xAB, 0x51),
-	_INIT_DCS_CMD(0xAC, 0x04),
-	_INIT_DCS_CMD(0xBD, 0x92),
-	_INIT_DCS_CMD(0xBE, 0xA1),
-
-	_INIT_SWITCH_PAGE_CMD(0x05),
-	_INIT_DCS_CMD(0x86, 0x87),
-
-	_INIT_SWITCH_PAGE_CMD(0x06),
-	_INIT_DCS_CMD(0x92, 0x22),
-
-	_INIT_SWITCH_PAGE_CMD(0x00),
-	_INIT_DCS_CMD(MIPI_DCS_EXIT_SLEEP_MODE),
-	_INIT_DELAY_CMD(120),
-	_INIT_DCS_CMD(MIPI_DCS_SET_DISPLAY_ON),
-	_INIT_DELAY_CMD(20),
-	{},
-};
+#define ili9882t_switch_page(ctx, page) \
+	mipi_dsi_dcs_write_seq_multi(ctx, ILI9882T_DCS_SWITCH_PAGE, \
+				     0x98, 0x82, (page))
 
-static inline struct ili9882t *to_ili9882t(struct drm_panel *panel)
+static int starry_ili9882t_init(struct ili9882t *ili)
 {
-	return container_of(panel, struct ili9882t, base);
-}
+	struct mipi_dsi_multi_context ctx = { .dsi = ili->dsi };
+
+	usleep_range(5000, 5100);
+
+	ili9882t_switch_page(&ctx, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x42);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x01, 0x11);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x02, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x03, 0x00);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x05, 0x11);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x00);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x80);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x09, 0x81);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0a, 0x71);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0b, 0x00);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0c, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0e, 0x1a);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x24, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x00);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2c, 0xd4);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0x40);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x11);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe6, 0x32);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd1, 0x30);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd6, 0x55);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd0, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe3, 0x93);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe4, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5, 0x80);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x31, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x32, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x33, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x34, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x36, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x37, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x38, 0x28);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x39, 0x29);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x11);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3b, 0x13);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3c, 0x15);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3d, 0x17);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3e, 0x09);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3f, 0x0d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x40, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x41, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x42, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x43, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x44, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x45, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x46, 0x02);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x47, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x48, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x49, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4a, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4b, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4c, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4d, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4e, 0x28);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x4f, 0x29);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x50, 0x10);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x51, 0x12);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x52, 0x14);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x53, 0x16);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x54, 0x08);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x55, 0x0c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x56, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x57, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x58, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x59, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5a, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5b, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5c, 0x02);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x61, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x62, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x63, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x64, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x65, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x66, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x67, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x68, 0x28);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x69, 0x29);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6a, 0x16);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6b, 0x14);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6c, 0x12);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6d, 0x10);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6e, 0x0c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6f, 0x08);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x70, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x71, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x72, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x73, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x74, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x75, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x76, 0x02);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x77, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x78, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x79, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7a, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7b, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7c, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7d, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7e, 0x28);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7f, 0x29);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x80, 0x17);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x81, 0x15);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x82, 0x13);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x83, 0x11);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x84, 0x0d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x85, 0x09);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x86, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x87, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x88, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x89, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x8a, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x8b, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x8c, 0x07);
+
+	ili9882t_switch_page(&ctx, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x29, 0x3a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x3b);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x0c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x09, 0x44);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3c, 0x0a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x39, 0x11);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3d, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x0c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3b, 0x44);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x53, 0x1f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5e, 0x40);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x84, 0x00);
+
+	ili9882t_switch_page(&ctx, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x21, 0x3c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x22, 0xfa);
+
+	ili9882t_switch_page(&ctx, 0x0a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe0, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe2, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5, 0x91);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe6, 0x3c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe7, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe8, 0xfa);
+
+	ili9882t_switch_page(&ctx, 0x12);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x87, 0x2c);
+
+	ili9882t_switch_page(&ctx, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x73, 0xe5);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x7f, 0x6b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6d, 0xa4);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x79, 0x54);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x69, 0x97);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6a, 0x97);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa5, 0x3f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x61, 0xda);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa7, 0xf1);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x5f, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x62, 0x3f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1d, 0x90);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x86, 0x87);
+
+	ili9882t_switch_page(&ctx, 0x06);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x80);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x58);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0x58);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xcf, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x67, 0x60);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x10, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x92, 0x22);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd3, 0x08);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xd6, 0x55);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xdc, 0x38);
+
+	ili9882t_switch_page(&ctx, 0x08);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe0, 0x00, 0x10, 0x2a, 0x4d, 0x61, 0x56, 0x6a, 0x6e,
+				     0x79, 0x76, 0x8f, 0x95, 0x98, 0xae, 0xaa, 0xb2, 0xbb, 0xce,
+				     0xc6, 0xbd, 0xd5, 0xe2, 0xe8);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xe1, 0x00, 0x10, 0x2a, 0x4d, 0x61, 0x56, 0x6a, 0x6e,
+				     0x79, 0x76, 0x8f, 0x95, 0x98, 0xae, 0xaa, 0xb2, 0xbb, 0xce,
+				     0xc6, 0xbd, 0xd5, 0xe2, 0xe8);
+
+	ili9882t_switch_page(&ctx, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x81);
+
+	ili9882t_switch_page(&ctx, 0x0c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x01, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x02, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x03, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x05, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x09, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0a, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0b, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0c, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0d, 0x06);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0e, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x0f, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x10, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x11, 0x08);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x12, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x13, 0x09);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x14, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x15, 0x0a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x16, 0x06);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x17, 0x0b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x18, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x19, 0x0c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1a, 0x06);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1b, 0x0d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1c, 0x06);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1d, 0x0e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1e, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x1f, 0x0f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x06);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x21, 0x10);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x22, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x23, 0x11);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x24, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x12);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0x08);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x13);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x28, 0x07);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x29, 0x14);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x08);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2b, 0x15);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2c, 0x08);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2d, 0x16);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2e, 0x09);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2f, 0x17);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x30, 0x08);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x31, 0x18);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x32, 0x09);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x33, 0x19);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x34, 0x09);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x1a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x36, 0x0a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x37, 0x1b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x38, 0x0a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x39, 0x1c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x0a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3b, 0x1d);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3c, 0x0a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3d, 0x1e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3e, 0x0a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x3f, 0x1f);
+
+	ili9882t_switch_page(&ctx, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x01);
+
+	ili9882t_switch_page(&ctx, 0x0e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x02, 0x0c);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x10);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x16);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0xe0);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x29, 0x71);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x46);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2b, 0x1f);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x2d, 0xc7);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x31, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x32, 0xdf);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x33, 0x5a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x34, 0xc0);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x5a);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x36, 0xc0);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x38, 0x65);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x80, 0x3e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x81, 0xa0);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x01);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0xcc);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x12);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0xcc);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0xcc);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0xcc);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0xcc);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0xcc);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0xcc);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0xcc);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0xcc);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x30, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x81);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x02);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x09, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x21);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x10);
+
+	ili9882t_switch_page(&ctx, 0x1e);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x60, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x64, 0x00);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x6d, 0x00);
+
+	ili9882t_switch_page(&ctx, 0x0b);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa6, 0x44);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa7, 0xb6);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa8, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xa9, 0x03);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xaa, 0x51);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xab, 0x51);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xac, 0x04);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x92);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0xbe, 0xa1);
+
+	ili9882t_switch_page(&ctx, 0x05);
+	mipi_dsi_dcs_write_seq_multi(&ctx, 0x86, 0x87);
+
+	ili9882t_switch_page(&ctx, 0x06);
+	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;
+
+	msleep(120);
+
+	mipi_dsi_dcs_write_seq_multi(&ctx, MIPI_DCS_SET_DISPLAY_ON);
+	if (ctx.accum_err)
+		return ctx.accum_err;
+
+	msleep(20);
 
-static int ili9882t_init_dcs_cmd(struct ili9882t *ili)
-{
-	struct mipi_dsi_device *dsi = ili->dsi;
-	struct drm_panel *panel = &ili->base;
-	int i, err = 0;
-
-	if (ili->desc->init_cmds) {
-		const struct panel_init_cmd *init_cmds = ili->desc->init_cmds;
-
-		for (i = 0; init_cmds[i].len != 0; i++) {
-			const struct panel_init_cmd *cmd = &init_cmds[i];
-
-			switch (cmd->type) {
-			case DELAY_CMD:
-				msleep(cmd->data[0]);
-				err = 0;
-				break;
-
-			case INIT_DCS_CMD:
-				err = mipi_dsi_dcs_write(dsi, cmd->data[0],
-							 cmd->len <= 1 ? NULL :
-							 &cmd->data[1],
-							 cmd->len - 1);
-				break;
-
-			default:
-				err = -EINVAL;
-			}
-
-			if (err < 0) {
-				dev_err(panel->dev,
-					"failed to write command %u\n", i);
-				return err;
-			}
-		}
-	}
 	return 0;
-}
+};
 
-static int ili9882t_switch_page(struct mipi_dsi_device *dsi, u8 page)
+static inline struct ili9882t *to_ili9882t(struct drm_panel *panel)
 {
-	int ret;
-	const struct panel_init_cmd cmd = _INIT_SWITCH_PAGE_CMD(page);
-
-	ret = mipi_dsi_dcs_write(dsi, cmd.data[0],
-				 cmd.len <= 1 ? NULL :
-				 &cmd.data[1],
-				 cmd.len - 1);
-	if (ret) {
-		dev_err(&dsi->dev,
-			"error switching panel controller page (%d)\n", ret);
-		return ret;
-	}
-
-	return 0;
+	return container_of(panel, struct ili9882t, base);
 }
 
 static int ili9882t_enter_sleep_mode(struct ili9882t *ili)
@@ -502,10 +443,13 @@ static int ili9882t_enter_sleep_mode(struct ili9882t *ili)
 static int ili9882t_disable(struct drm_panel *panel)
 {
 	struct ili9882t *ili = to_ili9882t(panel);
-	struct mipi_dsi_device *dsi = ili->dsi;
+	struct mipi_dsi_multi_context ctx = { .dsi = ili->dsi };
 	int ret;
 
-	ili9882t_switch_page(dsi, 0x00);
+	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);
@@ -570,11 +514,9 @@ static int ili9882t_prepare(struct drm_panel *panel)
 	gpiod_set_value(ili->enable_gpio, 1);
 	usleep_range(6000, 10000);
 
-	ret = ili9882t_init_dcs_cmd(ili);
-	if (ret < 0) {
-		dev_err(panel->dev, "failed to init panel: %d\n", ret);
+	ret = ili->desc->init(ili);
+	if (ret < 0)
 		goto poweroff;
-	}
 
 	return 0;
 
@@ -620,7 +562,7 @@ static const struct panel_desc starry_ili9882t_desc = {
 	.format = MIPI_DSI_FMT_RGB888,
 	.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
 		      MIPI_DSI_MODE_LPM,
-	.init_cmds = starry_ili9882t_init_cmd,
+	.init = starry_ili9882t_init,
 };
 
 static int ili9882t_get_modes(struct drm_panel *panel,
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog


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

* [PATCH v4 9/9] drm/panel: innolux-p079zca: Don't use a table for initting panels
  2024-05-08 20:51 [PATCH v4 0/9] drm/mipi-dsi: Reduce bloat and add funcs for cleaner init seqs Douglas Anderson
                   ` (7 preceding siblings ...)
  2024-05-08 20:51 ` [PATCH v4 8/9] drm/panel: ili9882t: " Douglas Anderson
@ 2024-05-08 20:51 ` Douglas Anderson
  8 siblings, 0 replies; 14+ messages in thread
From: Douglas Anderson @ 2024-05-08 20:51 UTC (permalink / raw
  To: dri-devel
  Cc: lvzhaoxiong, Jani Nikula, Hsin-Yi Wang, Linus Walleij,
	Javier Martinez Canillas, Neil Armstrong, Cong Yang, Sam Ravnborg,
	Dmitry Baryshkov, Joel Selvaraj, Brian Norris, Douglas Anderson,
	Daniel Vetter, David Airlie, Jessica Zhang, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, linux-kernel

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_prepare                        412     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 <linus.walleij@linaro.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---

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 <drm/drm_modes.h>
 #include <drm/drm_panel.h>
 
-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(20000, 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 = &cmds[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 = &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);
+}
+
+#define innolux_panel_init_cmd_multi(ctx, seq...)                 \
+	do {                                                      \
+		static const u8 d[] = { seq };                    \
+		innolux_panel_write_multi(ctx, d, ARRAY_SIZE(d)); \
+	} while (0)
+
+#define innolux_panel_switch_page(ctx, page) \
+	innolux_panel_init_cmd_multi(ctx, 0xf0, 0x55, 0xaa, 0x52, 0x08, (page))
+
 /*
  * Display manufacturer failed to provide init sequencing according to
  * https://chromium-review.googlesource.com/c/chromiumos/third_party/coreboot/+/892065/
  * so the init sequence stems from a register dump of a working panel.
  */
-static const struct panel_init_cmd innolux_p097pfg_init_cmds[] = {
-	/* page 0 */
-	_INIT_CMD(0xF0, 0x55, 0xAA, 0x52, 0x08, 0x00),
-	_INIT_CMD(0xB1, 0xE8, 0x11),
-	_INIT_CMD(0xB2, 0x25, 0x02),
-	_INIT_CMD(0xB5, 0x08, 0x00),
-	_INIT_CMD(0xBC, 0x0F, 0x00),
-	_INIT_CMD(0xB8, 0x03, 0x06, 0x00, 0x00),
-	_INIT_CMD(0xBD, 0x01, 0x90, 0x14, 0x14),
-	_INIT_CMD(0x6F, 0x01),
-	_INIT_CMD(0xC0, 0x03),
-	_INIT_CMD(0x6F, 0x02),
-	_INIT_CMD(0xC1, 0x0D),
-	_INIT_CMD(0xD9, 0x01, 0x09, 0x70),
-	_INIT_CMD(0xC5, 0x12, 0x21, 0x00),
-	_INIT_CMD(0xBB, 0x93, 0x93),
-
-	/* page 1 */
-	_INIT_CMD(0xF0, 0x55, 0xAA, 0x52, 0x08, 0x01),
-	_INIT_CMD(0xB3, 0x3C, 0x3C),
-	_INIT_CMD(0xB4, 0x0F, 0x0F),
-	_INIT_CMD(0xB9, 0x45, 0x45),
-	_INIT_CMD(0xBA, 0x14, 0x14),
-	_INIT_CMD(0xCA, 0x02),
-	_INIT_CMD(0xCE, 0x04),
-	_INIT_CMD(0xC3, 0x9B, 0x9B),
-	_INIT_CMD(0xD8, 0xC0, 0x03),
-	_INIT_CMD(0xBC, 0x82, 0x01),
-	_INIT_CMD(0xBD, 0x9E, 0x01),
-
-	/* page 2 */
-	_INIT_CMD(0xF0, 0x55, 0xAA, 0x52, 0x08, 0x02),
-	_INIT_CMD(0xB0, 0x82),
-	_INIT_CMD(0xD1, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x82, 0x00, 0xA5,
-		  0x00, 0xC1, 0x00, 0xEA, 0x01, 0x0D, 0x01, 0x40),
-	_INIT_CMD(0xD2, 0x01, 0x6A, 0x01, 0xA8, 0x01, 0xDC, 0x02, 0x29,
-		  0x02, 0x67, 0x02, 0x68, 0x02, 0xA8, 0x02, 0xF0),
-	_INIT_CMD(0xD3, 0x03, 0x19, 0x03, 0x49, 0x03, 0x67, 0x03, 0x8C,
-		  0x03, 0xA6, 0x03, 0xC7, 0x03, 0xDE, 0x03, 0xEC),
-	_INIT_CMD(0xD4, 0x03, 0xFF, 0x03, 0xFF),
-	_INIT_CMD(0xE0, 0x00, 0x00, 0x00, 0x86, 0x00, 0xC5, 0x00, 0xE5,
-		  0x00, 0xFF, 0x01, 0x26, 0x01, 0x45, 0x01, 0x75),
-	_INIT_CMD(0xE1, 0x01, 0x9C, 0x01, 0xD5, 0x02, 0x05, 0x02, 0x4D,
-		  0x02, 0x86, 0x02, 0x87, 0x02, 0xC3, 0x03, 0x03),
-	_INIT_CMD(0xE2, 0x03, 0x2A, 0x03, 0x56, 0x03, 0x72, 0x03, 0x94,
-		  0x03, 0xAC, 0x03, 0xCB, 0x03, 0xE0, 0x03, 0xED),
-	_INIT_CMD(0xE3, 0x03, 0xFF, 0x03, 0xFF),
-
-	/* page 3 */
-	_INIT_CMD(0xF0, 0x55, 0xAA, 0x52, 0x08, 0x03),
-	_INIT_CMD(0xB0, 0x00, 0x00, 0x00, 0x00),
-	_INIT_CMD(0xB1, 0x00, 0x00, 0x00, 0x00),
-	_INIT_CMD(0xB2, 0x00, 0x00, 0x06, 0x04, 0x01, 0x40, 0x85),
-	_INIT_CMD(0xB3, 0x10, 0x07, 0xFC, 0x04, 0x01, 0x40, 0x80),
-	_INIT_CMD(0xB6, 0xF0, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
-		  0x40, 0x80),
-	_INIT_CMD(0xBA, 0xC5, 0x07, 0x00, 0x04, 0x11, 0x25, 0x8C),
-	_INIT_CMD(0xBB, 0xC5, 0x07, 0x00, 0x03, 0x11, 0x25, 0x8C),
-	_INIT_CMD(0xC0, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x80, 0x80),
-	_INIT_CMD(0xC1, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x80, 0x80),
-	_INIT_CMD(0xC4, 0x00, 0x00),
-	_INIT_CMD(0xEF, 0x41),
-
-	/* page 4 */
-	_INIT_CMD(0xF0, 0x55, 0xAA, 0x52, 0x08, 0x04),
-	_INIT_CMD(0xEC, 0x4C),
-
-	/* page 5 */
-	_INIT_CMD(0xF0, 0x55, 0xAA, 0x52, 0x08, 0x05),
-	_INIT_CMD(0xB0, 0x13, 0x03, 0x03, 0x01),
-	_INIT_CMD(0xB1, 0x30, 0x00),
-	_INIT_CMD(0xB2, 0x02, 0x02, 0x00),
-	_INIT_CMD(0xB3, 0x82, 0x23, 0x82, 0x9D),
-	_INIT_CMD(0xB4, 0xC5, 0x75, 0x24, 0x57),
-	_INIT_CMD(0xB5, 0x00, 0xD4, 0x72, 0x11, 0x11, 0xAB, 0x0A),
-	_INIT_CMD(0xB6, 0x00, 0x00, 0xD5, 0x72, 0x24, 0x56),
-	_INIT_CMD(0xB7, 0x5C, 0xDC, 0x5C, 0x5C),
-	_INIT_CMD(0xB9, 0x0C, 0x00, 0x00, 0x01, 0x00),
-	_INIT_CMD(0xC0, 0x75, 0x11, 0x11, 0x54, 0x05),
-	_INIT_CMD(0xC6, 0x00, 0x00, 0x00, 0x00),
-	_INIT_CMD(0xD0, 0x00, 0x48, 0x08, 0x00, 0x00),
-	_INIT_CMD(0xD1, 0x00, 0x48, 0x09, 0x00, 0x00),
-
-	/* page 6 */
-	_INIT_CMD(0xF0, 0x55, 0xAA, 0x52, 0x08, 0x06),
-	_INIT_CMD(0xB0, 0x02, 0x32, 0x32, 0x08, 0x2F),
-	_INIT_CMD(0xB1, 0x2E, 0x15, 0x14, 0x13, 0x12),
-	_INIT_CMD(0xB2, 0x11, 0x10, 0x00, 0x3D, 0x3D),
-	_INIT_CMD(0xB3, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D),
-	_INIT_CMD(0xB4, 0x3D, 0x32),
-	_INIT_CMD(0xB5, 0x03, 0x32, 0x32, 0x09, 0x2F),
-	_INIT_CMD(0xB6, 0x2E, 0x1B, 0x1A, 0x19, 0x18),
-	_INIT_CMD(0xB7, 0x17, 0x16, 0x01, 0x3D, 0x3D),
-	_INIT_CMD(0xB8, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D),
-	_INIT_CMD(0xB9, 0x3D, 0x32),
-	_INIT_CMD(0xC0, 0x01, 0x32, 0x32, 0x09, 0x2F),
-	_INIT_CMD(0xC1, 0x2E, 0x1A, 0x1B, 0x16, 0x17),
-	_INIT_CMD(0xC2, 0x18, 0x19, 0x03, 0x3D, 0x3D),
-	_INIT_CMD(0xC3, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D),
-	_INIT_CMD(0xC4, 0x3D, 0x32),
-	_INIT_CMD(0xC5, 0x00, 0x32, 0x32, 0x08, 0x2F),
-	_INIT_CMD(0xC6, 0x2E, 0x14, 0x15, 0x10, 0x11),
-	_INIT_CMD(0xC7, 0x12, 0x13, 0x02, 0x3D, 0x3D),
-	_INIT_CMD(0xC8, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D),
-	_INIT_CMD(0xC9, 0x3D, 0x32),
-
-	{},
-};
+static int innolux_p097pfg_init(struct innolux_panel *innolux)
+{
+	struct mipi_dsi_multi_context ctx = { .dsi = innolux->link };
+
+	innolux_panel_switch_page(&ctx, 0x00);
+	innolux_panel_init_cmd_multi(&ctx, 0xb1, 0xe8, 0x11);
+	innolux_panel_init_cmd_multi(&ctx, 0xb2, 0x25, 0x02);
+	innolux_panel_init_cmd_multi(&ctx, 0xb5, 0x08, 0x00);
+	innolux_panel_init_cmd_multi(&ctx, 0xbc, 0x0f, 0x00);
+	innolux_panel_init_cmd_multi(&ctx, 0xb8, 0x03, 0x06, 0x00, 0x00);
+	innolux_panel_init_cmd_multi(&ctx, 0xbd, 0x01, 0x90, 0x14, 0x14);
+	innolux_panel_init_cmd_multi(&ctx, 0x6f, 0x01);
+	innolux_panel_init_cmd_multi(&ctx, 0xc0, 0x03);
+	innolux_panel_init_cmd_multi(&ctx, 0x6f, 0x02);
+	innolux_panel_init_cmd_multi(&ctx, 0xc1, 0x0d);
+	innolux_panel_init_cmd_multi(&ctx, 0xd9, 0x01, 0x09, 0x70);
+	innolux_panel_init_cmd_multi(&ctx, 0xc5, 0x12, 0x21, 0x00);
+	innolux_panel_init_cmd_multi(&ctx, 0xbb, 0x93, 0x93);
+
+	innolux_panel_switch_page(&ctx, 0x01);
+	innolux_panel_init_cmd_multi(&ctx, 0xb3, 0x3c, 0x3c);
+	innolux_panel_init_cmd_multi(&ctx, 0xb4, 0x0f, 0x0f);
+	innolux_panel_init_cmd_multi(&ctx, 0xb9, 0x45, 0x45);
+	innolux_panel_init_cmd_multi(&ctx, 0xba, 0x14, 0x14);
+	innolux_panel_init_cmd_multi(&ctx, 0xca, 0x02);
+	innolux_panel_init_cmd_multi(&ctx, 0xce, 0x04);
+	innolux_panel_init_cmd_multi(&ctx, 0xc3, 0x9b, 0x9b);
+	innolux_panel_init_cmd_multi(&ctx, 0xd8, 0xc0, 0x03);
+	innolux_panel_init_cmd_multi(&ctx, 0xbc, 0x82, 0x01);
+	innolux_panel_init_cmd_multi(&ctx, 0xbd, 0x9e, 0x01);
+
+	innolux_panel_switch_page(&ctx, 0x02);
+	innolux_panel_init_cmd_multi(&ctx, 0xb0, 0x82);
+	innolux_panel_init_cmd_multi(&ctx, 0xd1, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x82, 0x00, 0xa5,
+				     0x00, 0xc1, 0x00, 0xea, 0x01, 0x0d, 0x01, 0x40);
+	innolux_panel_init_cmd_multi(&ctx, 0xd2, 0x01, 0x6a, 0x01, 0xa8, 0x01, 0xdc, 0x02, 0x29,
+				     0x02, 0x67, 0x02, 0x68, 0x02, 0xa8, 0x02, 0xf0);
+	innolux_panel_init_cmd_multi(&ctx, 0xd3, 0x03, 0x19, 0x03, 0x49, 0x03, 0x67, 0x03, 0x8c,
+				     0x03, 0xa6, 0x03, 0xc7, 0x03, 0xde, 0x03, 0xec);
+	innolux_panel_init_cmd_multi(&ctx, 0xd4, 0x03, 0xff, 0x03, 0xff);
+	innolux_panel_init_cmd_multi(&ctx, 0xe0, 0x00, 0x00, 0x00, 0x86, 0x00, 0xc5, 0x00, 0xe5,
+				     0x00, 0xff, 0x01, 0x26, 0x01, 0x45, 0x01, 0x75);
+	innolux_panel_init_cmd_multi(&ctx, 0xe1, 0x01, 0x9c, 0x01, 0xd5, 0x02, 0x05, 0x02, 0x4d,
+				     0x02, 0x86, 0x02, 0x87, 0x02, 0xc3, 0x03, 0x03);
+	innolux_panel_init_cmd_multi(&ctx, 0xe2, 0x03, 0x2a, 0x03, 0x56, 0x03, 0x72, 0x03, 0x94,
+				     0x03, 0xac, 0x03, 0xcb, 0x03, 0xe0, 0x03, 0xed);
+	innolux_panel_init_cmd_multi(&ctx, 0xe3, 0x03, 0xff, 0x03, 0xff);
+
+	innolux_panel_switch_page(&ctx, 0x03);
+	innolux_panel_init_cmd_multi(&ctx, 0xb0, 0x00, 0x00, 0x00, 0x00);
+	innolux_panel_init_cmd_multi(&ctx, 0xb1, 0x00, 0x00, 0x00, 0x00);
+	innolux_panel_init_cmd_multi(&ctx, 0xb2, 0x00, 0x00, 0x06, 0x04, 0x01, 0x40, 0x85);
+	innolux_panel_init_cmd_multi(&ctx, 0xb3, 0x10, 0x07, 0xfc, 0x04, 0x01, 0x40, 0x80);
+	innolux_panel_init_cmd_multi(&ctx, 0xb6, 0xf0, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
+				     0x40, 0x80);
+	innolux_panel_init_cmd_multi(&ctx, 0xba, 0xc5, 0x07, 0x00, 0x04, 0x11, 0x25, 0x8c);
+	innolux_panel_init_cmd_multi(&ctx, 0xbb, 0xc5, 0x07, 0x00, 0x03, 0x11, 0x25, 0x8c);
+	innolux_panel_init_cmd_multi(&ctx, 0xc0, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x80, 0x80);
+	innolux_panel_init_cmd_multi(&ctx, 0xc1, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x80, 0x80);
+	innolux_panel_init_cmd_multi(&ctx, 0xc4, 0x00, 0x00);
+	innolux_panel_init_cmd_multi(&ctx, 0xef, 0x41);
+
+	innolux_panel_switch_page(&ctx, 0x04);
+	innolux_panel_init_cmd_multi(&ctx, 0xec, 0x4c);
+
+	innolux_panel_switch_page(&ctx, 0x05);
+	innolux_panel_init_cmd_multi(&ctx, 0xb0, 0x13, 0x03, 0x03, 0x01);
+	innolux_panel_init_cmd_multi(&ctx, 0xb1, 0x30, 0x00);
+	innolux_panel_init_cmd_multi(&ctx, 0xb2, 0x02, 0x02, 0x00);
+	innolux_panel_init_cmd_multi(&ctx, 0xb3, 0x82, 0x23, 0x82, 0x9d);
+	innolux_panel_init_cmd_multi(&ctx, 0xb4, 0xc5, 0x75, 0x24, 0x57);
+	innolux_panel_init_cmd_multi(&ctx, 0xb5, 0x00, 0xd4, 0x72, 0x11, 0x11, 0xab, 0x0a);
+	innolux_panel_init_cmd_multi(&ctx, 0xb6, 0x00, 0x00, 0xd5, 0x72, 0x24, 0x56);
+	innolux_panel_init_cmd_multi(&ctx, 0xb7, 0x5c, 0xdc, 0x5c, 0x5c);
+	innolux_panel_init_cmd_multi(&ctx, 0xb9, 0x0c, 0x00, 0x00, 0x01, 0x00);
+	innolux_panel_init_cmd_multi(&ctx, 0xc0, 0x75, 0x11, 0x11, 0x54, 0x05);
+	innolux_panel_init_cmd_multi(&ctx, 0xc6, 0x00, 0x00, 0x00, 0x00);
+	innolux_panel_init_cmd_multi(&ctx, 0xd0, 0x00, 0x48, 0x08, 0x00, 0x00);
+	innolux_panel_init_cmd_multi(&ctx, 0xd1, 0x00, 0x48, 0x09, 0x00, 0x00);
+
+	innolux_panel_switch_page(&ctx, 0x06);
+	innolux_panel_init_cmd_multi(&ctx, 0xb0, 0x02, 0x32, 0x32, 0x08, 0x2f);
+	innolux_panel_init_cmd_multi(&ctx, 0xb1, 0x2e, 0x15, 0x14, 0x13, 0x12);
+	innolux_panel_init_cmd_multi(&ctx, 0xb2, 0x11, 0x10, 0x00, 0x3d, 0x3d);
+	innolux_panel_init_cmd_multi(&ctx, 0xb3, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d);
+	innolux_panel_init_cmd_multi(&ctx, 0xb4, 0x3d, 0x32);
+	innolux_panel_init_cmd_multi(&ctx, 0xb5, 0x03, 0x32, 0x32, 0x09, 0x2f);
+	innolux_panel_init_cmd_multi(&ctx, 0xb6, 0x2e, 0x1b, 0x1a, 0x19, 0x18);
+	innolux_panel_init_cmd_multi(&ctx, 0xb7, 0x17, 0x16, 0x01, 0x3d, 0x3d);
+	innolux_panel_init_cmd_multi(&ctx, 0xb8, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d);
+	innolux_panel_init_cmd_multi(&ctx, 0xb9, 0x3d, 0x32);
+	innolux_panel_init_cmd_multi(&ctx, 0xc0, 0x01, 0x32, 0x32, 0x09, 0x2f);
+	innolux_panel_init_cmd_multi(&ctx, 0xc1, 0x2e, 0x1a, 0x1b, 0x16, 0x17);
+	innolux_panel_init_cmd_multi(&ctx, 0xc2, 0x18, 0x19, 0x03, 0x3d, 0x3d);
+	innolux_panel_init_cmd_multi(&ctx, 0xc3, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d);
+	innolux_panel_init_cmd_multi(&ctx, 0xc4, 0x3d, 0x32);
+	innolux_panel_init_cmd_multi(&ctx, 0xc5, 0x00, 0x32, 0x32, 0x08, 0x2f);
+	innolux_panel_init_cmd_multi(&ctx, 0xc6, 0x2e, 0x14, 0x15, 0x10, 0x11);
+	innolux_panel_init_cmd_multi(&ctx, 0xc7, 0x12, 0x13, 0x02, 0x3d, 0x3d);
+	innolux_panel_init_cmd_multi(&ctx, 0xc8, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d);
+	innolux_panel_init_cmd_multi(&ctx, 0xc9, 0x3d, 0x32);
+
+	return ctx.accum_err;
+}
 
 static const struct panel_desc innolux_p097pfg_panel_desc = {
 	.mode = &innolux_p097pfg_mode,
@@ -374,7 +370,7 @@ static const struct panel_desc innolux_p097pfg_panel_desc = {
 	.flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
 		 MIPI_DSI_MODE_LPM,
 	.format = MIPI_DSI_FMT_RGB888,
-	.init_cmds = innolux_p097pfg_init_cmds,
+	.init = innolux_p097pfg_init,
 	.lanes = 4,
 	.supply_names = innolux_p097pfg_supply_names,
 	.num_supplies = ARRAY_SIZE(innolux_p097pfg_supply_names),
-- 
2.45.0.rc1.225.g2a3ae87e7f-goog


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

* Re: [PATCH v4 4/9] drm/mipi-dsi: Reduce driver bloat of mipi_dsi_*_write_seq()
  2024-05-08 20:51 ` [PATCH v4 4/9] drm/mipi-dsi: Reduce driver bloat of mipi_dsi_*_write_seq() Douglas Anderson
@ 2024-05-13  9:29   ` Maxime Ripard
  2024-05-13 15:48     ` Doug Anderson
  0 siblings, 1 reply; 14+ messages in thread
From: Maxime Ripard @ 2024-05-13  9:29 UTC (permalink / raw
  To: Douglas Anderson
  Cc: dri-devel, lvzhaoxiong, Jani Nikula, Hsin-Yi Wang, Linus Walleij,
	Javier Martinez Canillas, Neil Armstrong, Cong Yang, Sam Ravnborg,
	Dmitry Baryshkov, Joel Selvaraj, Brian Norris, Daniel Vetter,
	David Airlie, Maarten Lankhorst, Thomas Zimmermann, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 4273 bytes --]

Hi,

On Wed, May 08, 2024 at 01:51:46PM -0700, Douglas Anderson wrote:
> 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               10640    6236   -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 <dmitry.baryshkov@linaro.org>
> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> ---
> 
> 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()

You mention in both functions that it's calling 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 = &dsi->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);

... but it doesn't.

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]

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

* Re: [PATCH v4 4/9] drm/mipi-dsi: Reduce driver bloat of mipi_dsi_*_write_seq()
  2024-05-13  9:29   ` Maxime Ripard
@ 2024-05-13 15:48     ` Doug Anderson
  0 siblings, 0 replies; 14+ messages in thread
From: Doug Anderson @ 2024-05-13 15:48 UTC (permalink / raw
  To: Maxime Ripard
  Cc: dri-devel, lvzhaoxiong, Jani Nikula, Hsin-Yi Wang, Linus Walleij,
	Javier Martinez Canillas, Neil Armstrong, Cong Yang, Sam Ravnborg,
	Dmitry Baryshkov, Joel Selvaraj, Brian Norris, Daniel Vetter,
	David Airlie, Maarten Lankhorst, Thomas Zimmermann, linux-kernel

Hi,

On Mon, May 13, 2024 at 2:30 AM Maxime Ripard <mripard@kernel.org> wrote:
>
> Hi,
>
> On Wed, May 08, 2024 at 01:51:46PM -0700, Douglas Anderson wrote:
> > 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               10640    6236   -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 <dmitry.baryshkov@linaro.org>
> > Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
> > Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> > Signed-off-by: Douglas Anderson <dianders@chromium.org>
> > ---
> >
> > 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()
>
> You mention in both functions that it's calling 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 = &dsi->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);
>
> ... but it doesn't.

Whoops, thanks for catching this! I'll plan to send a v5 tomorrow to
fix this and then I'll still plan to land the series on Thursday
unless anything major comes up.

-Doug

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

* Re: [PATCH v4 6/9] drm/panel: novatek-nt36672e: Switch to mipi_dsi_dcs_write_seq_multi()
  2024-05-08 20:51 ` [PATCH v4 6/9] drm/panel: novatek-nt36672e: Switch to mipi_dsi_dcs_write_seq_multi() Douglas Anderson
@ 2024-05-13 17:00   ` Dmitry Baryshkov
  2024-05-13 19:46   ` Linus Walleij
  1 sibling, 0 replies; 14+ messages in thread
From: Dmitry Baryshkov @ 2024-05-13 17:00 UTC (permalink / raw
  To: Douglas Anderson
  Cc: dri-devel, lvzhaoxiong, Jani Nikula, Hsin-Yi Wang, Linus Walleij,
	Javier Martinez Canillas, Neil Armstrong, Cong Yang, Sam Ravnborg,
	Joel Selvaraj, Brian Norris, Ritesh Kumar, Daniel Vetter,
	David Airlie, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, linux-kernel

On Wed, May 08, 2024 at 01:51:48PM -0700, Douglas Anderson wrote:
> 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_init                6236    5248    -988
> Total: Before=10651, After=9663, chg -9.28%
> 
> Cc: Ritesh Kumar <quic_riteshk@quicinc.com>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> ---
> 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(-)

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

-- 
With best wishes
Dmitry

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

* Re: [PATCH v4 6/9] drm/panel: novatek-nt36672e: Switch to mipi_dsi_dcs_write_seq_multi()
  2024-05-08 20:51 ` [PATCH v4 6/9] drm/panel: novatek-nt36672e: Switch to mipi_dsi_dcs_write_seq_multi() Douglas Anderson
  2024-05-13 17:00   ` Dmitry Baryshkov
@ 2024-05-13 19:46   ` Linus Walleij
  1 sibling, 0 replies; 14+ messages in thread
From: Linus Walleij @ 2024-05-13 19:46 UTC (permalink / raw
  To: Douglas Anderson
  Cc: dri-devel, lvzhaoxiong, Jani Nikula, Hsin-Yi Wang,
	Javier Martinez Canillas, Neil Armstrong, Cong Yang, Sam Ravnborg,
	Dmitry Baryshkov, Joel Selvaraj, Brian Norris, Ritesh Kumar,
	Daniel Vetter, David Airlie, Jessica Zhang, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, linux-kernel

On Wed, May 8, 2024 at 10:53 PM Douglas Anderson <dianders@chromium.org> wrote:

> 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_init                6236    5248    -988
> Total: Before=10651, After=9663, chg -9.28%
>
> Cc: Ritesh Kumar <quic_riteshk@quicinc.com>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

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

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

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-08 20:51 [PATCH v4 0/9] drm/mipi-dsi: Reduce bloat and add funcs for cleaner init seqs Douglas Anderson
2024-05-08 20:51 ` [PATCH v4 1/9] drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_dcs_write_seq() Douglas Anderson
2024-05-08 20:51 ` [PATCH v4 2/9] drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_generic_write_seq() Douglas Anderson
2024-05-08 20:51 ` [PATCH v4 3/9] drm/mipi-dsi: mipi_dsi_*_write functions don't need to ratelimit prints Douglas Anderson
2024-05-08 20:51 ` [PATCH v4 4/9] drm/mipi-dsi: Reduce driver bloat of mipi_dsi_*_write_seq() Douglas Anderson
2024-05-13  9:29   ` Maxime Ripard
2024-05-13 15:48     ` Doug Anderson
2024-05-08 20:51 ` [PATCH v4 5/9] drm/mipi-dsi: Introduce mipi_dsi_*_write_seq_multi() Douglas Anderson
2024-05-08 20:51 ` [PATCH v4 6/9] drm/panel: novatek-nt36672e: Switch to mipi_dsi_dcs_write_seq_multi() Douglas Anderson
2024-05-13 17:00   ` Dmitry Baryshkov
2024-05-13 19:46   ` Linus Walleij
2024-05-08 20:51 ` [PATCH v4 7/9] drm/panel: boe-tv101wum-nl6: Don't use a table for initting panels Douglas Anderson
2024-05-08 20:51 ` [PATCH v4 8/9] drm/panel: ili9882t: " Douglas Anderson
2024-05-08 20:51 ` [PATCH v4 9/9] drm/panel: innolux-p079zca: " Douglas Anderson

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).