On 9/17/26 18:43, Alexey Minnekhanov wrote:
The split between .send_init_cmds_1 and _cmds_2 is completely artificial
and unnecessary. Two command sets are split in between by the sequence:
  - exit_sleep_mode
  - delay
  - set_display_on

But not every panel driver follows this "split" in their init sequence.
Some may have different delay timer, or put exit_sleep_mode/display_on
commands into other places in the sequence.

In order to make this driver more extensible, combine two init functions
into one by puting exit_sleep_mode/delay/display_on in the middle,
followed by commands from cmds_2. As part of this step, also move the
tianma-beryllium specific deinit sequence with its delays from
nt36672a_panel_unprepare() to tianma_fhd_video_send_deinit_cmds(), so
that each panel model can have its deinit sequence with its own delays.

No functional change - full init sequence with all the delays for the
tianma_fhd_video panel is kept the same in the end.

Signed-off-by: Alexey Minnekhanov <[email protected]>

---
v2: move tianma_fhd deinit commands into its own deinit function
     (set_display_off, msleep, enter_sleep_mode, msleep)
---
  drivers/gpu/drm/panel/panel-novatek-nt36672a.c | 61 ++++++++++----------------
  1 file changed, 23 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36672a.c 
b/drivers/gpu/drm/panel/panel-novatek-nt36672a.c
index 73bec4f47ec60..a445c8067aa5f 100644
--- a/drivers/gpu/drm/panel/panel-novatek-nt36672a.c
+++ b/drivers/gpu/drm/panel/panel-novatek-nt36672a.c
@@ -51,8 +51,7 @@ struct nt36672a_panel_desc {
        enum mipi_dsi_pixel_format format;
        unsigned int lanes;
- void (*send_init_cmds_1)(struct mipi_dsi_multi_context *dsi_ctx);
-       void (*send_init_cmds_2)(struct mipi_dsi_multi_context *dsi_ctx);
+       void (*send_init_cmds)(struct mipi_dsi_multi_context *dsi_ctx);
        void (*send_deinit_cmds)(struct mipi_dsi_multi_context *dsi_ctx);
  };
@@ -92,20 +91,6 @@ static int nt36672a_panel_unprepare(struct drm_panel *panel)
        if (pinfo->desc->send_deinit_cmds)
                pinfo->desc->send_deinit_cmds(&dsi_ctx);
- /* Reset error to continue with display off even if send_cmds failed */
-       dsi_ctx.accum_err = 0;
-       mipi_dsi_dcs_set_display_off_multi(&dsi_ctx);
-       /* Reset error to continue power-down even if display off failed */
-       dsi_ctx.accum_err = 0;
-
-       /* 120ms delay required here as per DCS spec */
-       msleep(120);
-
-       mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx);
-
-       /* 0x3C = 60ms delay */
-       msleep(60);
-
        nt36672a_panel_power_off(panel);
return 0;
@@ -140,22 +125,9 @@ static int nt36672a_panel_prepare(struct drm_panel *panel)
dsi_ctx.accum_err = nt36672a_panel_power_on(pinfo); - /* send first part of init cmds */
-       if (pinfo->desc->send_init_cmds_1)
-               pinfo->desc->send_init_cmds_1(&dsi_ctx);
-
-       mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
-
-       /* 0x46 = 70 ms delay */
-       mipi_dsi_msleep(&dsi_ctx, 70);
-
-       mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
-
-       /* Send rest of the init cmds */
-       if (pinfo->desc->send_init_cmds_2)
-               pinfo->desc->send_init_cmds_2(&dsi_ctx);
-
-       mipi_dsi_msleep(&dsi_ctx, 120);
+       /* send init cmds */
+       if (pinfo->desc->send_init_cmds)
+               pinfo->desc->send_init_cmds(&dsi_ctx);
if (dsi_ctx.accum_err < 0)
                gpiod_set_value(pinfo->reset_gpio, 0);
@@ -192,7 +164,7 @@ static const struct drm_panel_funcs panel_funcs = {
        .get_modes = nt36672a_panel_get_modes,
  };
-static void tianma_fhd_video_send_init_cmds_1(struct mipi_dsi_multi_context *dsi_ctx)
+static void tianma_fhd_video_send_init_cmds(struct mipi_dsi_multi_context 
*dsi_ctx)
  {
        u8 reg;
@@ -352,15 +324,19 @@ static void tianma_fhd_video_send_init_cmds_1(struct mipi_dsi_multi_context *dsi
        mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0x51, 0xff);
        mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0x53, 0x24);
        mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0x55, 0x00);
-}
-static void tianma_fhd_video_send_init_cmds_2(struct mipi_dsi_multi_context *dsi_ctx)
-{
+       mipi_dsi_dcs_exit_sleep_mode_multi(dsi_ctx);
+       /* 0x46 = 70 ms delay */
+       mipi_dsi_msleep(dsi_ctx, 70);
+       mipi_dsi_dcs_set_display_on_multi(dsi_ctx);
+
        mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0xff, 0x24);
        mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0xfb, 0x01);
        mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0xc3, 0x01);
        mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0xc4, 0x54);
        mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0xff, 0x10);
+
+       mipi_dsi_msleep(dsi_ctx, 120);
  }
static void tianma_fhd_video_send_deinit_cmds(struct mipi_dsi_multi_context *dsi_ctx)
@@ -369,6 +345,16 @@ static void tianma_fhd_video_send_deinit_cmds(struct 
mipi_dsi_multi_context *dsi
        mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0xfb, 0x01);
        mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0xc3, 0x01);
        mipi_dsi_dcs_write_seq_multi(dsi_ctx, 0xff, 0x10);
+
+       /* Reset error to continue with display off even if send_cmds failed */
+       dsi_ctx->accum_err = 0;
+       mipi_dsi_dcs_set_display_off_multi(dsi_ctx);
+       /* Reset error to continue power-down even if display off failed */
+       dsi_ctx->accum_err = 0;
+       /* 120ms delay required here as per DCS spec */
+       msleep(120);
+       mipi_dsi_dcs_enter_sleep_mode_multi(dsi_ctx);
+       msleep(60); /* 0x3C = 60ms delay */
  }
static const struct drm_display_mode tianma_fhd_video_panel_default_mode = {
@@ -399,8 +385,7 @@ static const struct nt36672a_panel_desc 
tianma_fhd_video_panel_desc = {
                        | MIPI_DSI_MODE_VIDEO_BURST,
        .format = MIPI_DSI_FMT_RGB888,
        .lanes = 4,
-       .send_init_cmds_1 = tianma_fhd_video_send_init_cmds_1,
-       .send_init_cmds_2 = tianma_fhd_video_send_init_cmds_2,
+       .send_init_cmds = tianma_fhd_video_send_init_cmds,
        .send_deinit_cmds = tianma_fhd_video_send_deinit_cmds,
  };

Reviewed-by: Neil Armstrong <[email protected]>

Thanks,
Neil

Reply via email to