From 57cd27a7f8e411a6230b8fe5b4491db18ddeaf83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Jirman?= Date: Sun, 17 Oct 2021 18:03:05 +0200 Subject: [PATCH 301/389] drm: panel: hx8394: Improve the panel driver (make it work with DSI fixes) Powerup/down should be done in prepare/unprepare. Enable/disable is just for initialization. Fix timings and reset order according to datasheet. Reset panel on probe. Signed-off-by: Ondrej Jirman --- drivers/gpu/drm/panel/panel-himax-hx8394.c | 84 +++++++++++++--------- 1 file changed, 52 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-himax-hx8394.c b/drivers/gpu/drm/panel/panel-himax-hx8394.c index 2ce121a6a7b6..1f23190a3ec0 100644 --- a/drivers/gpu/drm/panel/panel-himax-hx8394.c +++ b/drivers/gpu/drm/panel/panel-himax-hx8394.c @@ -89,11 +89,6 @@ static int hsd060bhw4_init_sequence(struct hx8394 *ctx) dsi_dcs_write_seq(dsi, 0xbd, 0x00); dsi_dcs_write_seq(dsi, 0xc6, 0xed); - // msleep(0xfa); - // dsi_dcs_write_seq(dsi, 0x11); - // msleep(0x32); - // dsi_dcs_write_seq(dsi, 0x29); - return 0; } @@ -141,30 +136,38 @@ static int hx8394_enable(struct drm_panel *panel) struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); int ret; + dev_info(ctx->dev, "enable\n"); + ret = ctx->desc->init_sequence(ctx); - if (ret < 0) { + if (ret) { dev_err(ctx->dev, "Panel init sequence failed: %d\n", ret); return ret; } - msleep(20); - ret = mipi_dsi_dcs_exit_sleep_mode(dsi); - if (ret < 0) { + if (ret) { dev_err(ctx->dev, "Failed to exit sleep mode: %d\n", ret); return ret; } /* Panel is operational 120 msec after reset */ - msleep(60); + msleep(120); ret = mipi_dsi_dcs_set_display_on(dsi); - if (ret) - return ret; - - dev_dbg(ctx->dev, "Panel init sequence done\n"); + if (ret) { + dev_err(ctx->dev, "Failed to turn on the display: %d\n", ret); + goto sleep_in; + } return 0; + +sleep_in: + /* This will probably fail, but let's try orderly power off anyway. */ + ret = mipi_dsi_dcs_enter_sleep_mode(dsi); + if (!ret) + msleep(50); + + return ret; } static int hx8394_disable(struct drm_panel *panel) @@ -173,13 +176,15 @@ static int hx8394_disable(struct drm_panel *panel) struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); int ret; - ret = mipi_dsi_dcs_set_display_off(dsi); - if (ret < 0) - dev_err(ctx->dev, "Failed to turn off the display: %d\n", ret); + dev_info(ctx->dev, "disable\n"); ret = mipi_dsi_dcs_enter_sleep_mode(dsi); - if (ret < 0) + if (ret) { dev_err(ctx->dev, "Failed to enter sleep mode: %d\n", ret); + return ret; + } + + msleep(50); /* about 3 frames */ return 0; } @@ -187,13 +192,19 @@ static int hx8394_disable(struct drm_panel *panel) static int hx8394_unprepare(struct drm_panel *panel) { struct hx8394 *ctx = panel_to_hx8394(panel); + //struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); + //int ret; if (!ctx->prepared) return 0; + dev_info(ctx->dev, "unprepare\n"); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + regulator_disable(ctx->iovcc); regulator_disable(ctx->vcc); + ctx->prepared = false; return 0; @@ -202,33 +213,38 @@ static int hx8394_unprepare(struct drm_panel *panel) static int hx8394_prepare(struct drm_panel *panel) { struct hx8394 *ctx = panel_to_hx8394(panel); + //struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); int ret; if (ctx->prepared) return 0; - dev_dbg(ctx->dev, "Resetting the panel\n"); + dev_info(ctx->dev, "prepare\n"); + + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + ret = regulator_enable(ctx->vcc); - if (ret < 0) { + if (ret) { dev_err(ctx->dev, "Failed to enable vcc supply: %d\n", ret); return ret; } + ret = regulator_enable(ctx->iovcc); - if (ret < 0) { + if (ret) { dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret); goto disable_vcc; } - gpiod_set_value_cansleep(ctx->reset_gpio, 1); - mdelay(0x32); gpiod_set_value_cansleep(ctx->reset_gpio, 0); - msleep(0x64); + + msleep(180); ctx->prepared = true; return 0; disable_vcc: + gpiod_set_value_cansleep(ctx->reset_gpio, 1); regulator_disable(ctx->vcc); return ret; } @@ -273,9 +289,11 @@ static int allpixelson_set(void *data, u64 val) dev_dbg(ctx->dev, "Setting all pixels on\n"); dsi_generic_write_seq(dsi, 0x23); msleep(val * 1000); + /* Reset the panel to get video back */ drm_panel_disable(&ctx->panel); drm_panel_unprepare(&ctx->panel); + drm_panel_prepare(&ctx->panel); drm_panel_enable(&ctx->panel); @@ -309,9 +327,10 @@ static int hx8394_probe(struct mipi_dsi_device *dsi) if (!ctx) return -ENOMEM; - ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(ctx->reset_gpio)) - return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), "Failed to get reset gpio\n"); + return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), + "Failed to get reset gpio\n"); mipi_dsi_set_drvdata(dsi, ctx); @@ -324,7 +343,8 @@ static int hx8394_probe(struct mipi_dsi_device *dsi) ctx->vcc = devm_regulator_get(dev, "vcc"); if (IS_ERR(ctx->vcc)) - return dev_err_probe(dev, PTR_ERR(ctx->vcc), "Failed to request vcc regulator\n"); + return dev_err_probe(dev, PTR_ERR(ctx->vcc), + "Failed to request vcc regulator\n"); ctx->iovcc = devm_regulator_get(dev, "iovcc"); if (IS_ERR(ctx->iovcc)) @@ -342,7 +362,7 @@ static int hx8394_probe(struct mipi_dsi_device *dsi) ret = mipi_dsi_attach(dsi); if (ret < 0) { - dev_err(dev, "mipi_dsi_attach failed (%d). Is host ready?\n", ret); + dev_err_probe(dev, ret, "mipi_dsi_attach failed\n"); drm_panel_remove(&ctx->panel); return ret; } @@ -361,13 +381,13 @@ static void hx8394_shutdown(struct mipi_dsi_device *dsi) struct hx8394 *ctx = mipi_dsi_get_drvdata(dsi); int ret; - ret = drm_panel_unprepare(&ctx->panel); - if (ret < 0) - dev_err(&dsi->dev, "Failed to unprepare panel: %d\n", ret); - ret = drm_panel_disable(&ctx->panel); if (ret < 0) dev_err(&dsi->dev, "Failed to disable panel: %d\n", ret); + + ret = drm_panel_unprepare(&ctx->panel); + if (ret < 0) + dev_err(&dsi->dev, "Failed to unprepare panel: %d\n", ret); } static void hx8394_remove(struct mipi_dsi_device *dsi) -- 2.35.3