From cb26849c51a2206934f5473102dce67b1724dd10 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 18 Sep 2024 16:09:28 +0100 Subject: [PATCH] drm: panel: ili9881: Add option to reconfigure setup commands The driver is typically asking for LP commands, but then tries to send set_display_[on|off] from enable/disable when the host will be in HS mode. It also sends shutdown commands just before it asserts reset and disables the regulator, which is rather redundant. Add an option to configure these two choices from the panel_desc. Signed-off-by: Dave Stevenson --- drivers/gpu/drm/panel/panel-ilitek-ili9881c.c | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c index b5966617541e49..a77ce9f7db9ddc 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c @@ -40,12 +40,19 @@ struct ili9881c_instr { } arg; }; +enum ili9881_desc_flags { + ILI9881_FLAGS_NO_SHUTDOWN_CMDS = BIT(0), + ILI9881_FLAGS_PANEL_ON_IN_PREPARE = BIT(1), + ILI9881_FLAGS_MAX = BIT(31), +}; + struct ili9881c_desc { const struct ili9881c_instr *init; const size_t init_length; const struct drm_display_mode *mode; const unsigned long mode_flags; unsigned int lanes; + enum ili9881_desc_flags flags; }; struct ili9881c { @@ -1727,6 +1734,12 @@ static int ili9881c_prepare(struct drm_panel *panel) if (ret) return ret; + if (ctx->desc->flags & ILI9881_FLAGS_PANEL_ON_IN_PREPARE) { + msleep(120); + + ret = mipi_dsi_dcs_set_display_on(ctx->dsi); + } + return 0; } @@ -1734,9 +1747,11 @@ static int ili9881c_enable(struct drm_panel *panel) { struct ili9881c *ctx = panel_to_ili9881c(panel); - msleep(120); + if (!(ctx->desc->flags & ILI9881_FLAGS_PANEL_ON_IN_PREPARE)) { + msleep(120); - mipi_dsi_dcs_set_display_on(ctx->dsi); + mipi_dsi_dcs_set_display_on(ctx->dsi); + } return 0; } @@ -1745,7 +1760,8 @@ static int ili9881c_disable(struct drm_panel *panel) { struct ili9881c *ctx = panel_to_ili9881c(panel); - mipi_dsi_dcs_set_display_off(ctx->dsi); + if (!(ctx->desc->flags & ILI9881_FLAGS_PANEL_ON_IN_PREPARE)) + mipi_dsi_dcs_set_display_off(ctx->dsi); return 0; } @@ -1754,7 +1770,13 @@ static int ili9881c_unprepare(struct drm_panel *panel) { struct ili9881c *ctx = panel_to_ili9881c(panel); - mipi_dsi_dcs_enter_sleep_mode(ctx->dsi); + if (!(ctx->desc->flags & ILI9881_FLAGS_NO_SHUTDOWN_CMDS)) { + if (ctx->desc->flags & ILI9881_FLAGS_PANEL_ON_IN_PREPARE) + mipi_dsi_dcs_set_display_off(ctx->dsi); + + mipi_dsi_dcs_enter_sleep_mode(ctx->dsi); + } + regulator_disable(ctx->power); gpiod_set_value_cansleep(ctx->reset, 1); @@ -2066,6 +2088,8 @@ static const struct ili9881c_desc rpi_7inch_desc = { .mode = &rpi_7inch_default_mode, .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM, .lanes = 2, + .flags = ILI9881_FLAGS_NO_SHUTDOWN_CMDS | + ILI9881_FLAGS_PANEL_ON_IN_PREPARE, }; static const struct of_device_id ili9881c_of_match[] = {