gjdwebserver-overlay/sys-kernel/pinephone-pro-sources/files/0031-drm-panel-hx8394-Impro...

227 lines
6.1 KiB
Diff

From: Ondrej Jirman <megous@megous.com>
Date: Sun, 17 Oct 2021 18:03:05 +0200
Subject: [PATCH 06/36] 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 <megous@megous.com>
---
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 14659cb..2f69b94 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 int hx8394_remove(struct mipi_dsi_device *dsi)