summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/panel
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2020-08-17 23:39:06 +0200
committerLinus Walleij <linus.walleij@linaro.org>2020-09-05 01:28:11 +0200
commitec219f1ba23777c84e913b08e192413eea22d220 (patch)
treee7ec115899151c8283cc3bde6ab3b5185eb9e884 /drivers/gpu/drm/panel
parent83ba7a7b3d4a70fe92122f039539566c9526228c (diff)
drm/panel: s6e63m0: Order enable/disable sequence
The upstream S6E63M0 driver has some peculiarities around the prepare/enable disable/unprepare sequence: the screen is taken out of sleep in prepare() as part of s6e63m0_init() the put to on with MIPI_DCS_SET_DISPLAY_ON in enable(). However it is just put into sleep mode directly in disable(). As disable()/enable() can be called without unprepare()/prepare() being called, this is unbalanced, we should take the display out of sleep in enable() then turn it off(). Further MIPI_DCS_SET_DISPLAY_OFF is never called balanced with MIPI_DCS_SET_DISPLAY_ON. The vendor driver for Samsung GT-I8190 (Golden) does all of these things in strict order. Augment the driver to do exit sleep/set display on in enable() and set display off/enter sleep in disable(). Further send an explicit reset pulse in power_on() so we come up in a known state, and issue the MCS_ERROR_CHECK command after setting display on like the vendor driver does. Also use the timings from the vendor driver in the sequence. Doing all of these things makes the display much more stable on the Samsung GT-I8190 when enabling/disabling the display pipeline. Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Sam Ravnborg <sam@ravnborg.org> Cc: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com> Cc: Stephan Gerhold <stephan@gerhold.net> Link: https://patchwork.freedesktop.org/patch/msgid/20200817213906.88207-1-linus.walleij@linaro.org
Diffstat (limited to 'drivers/gpu/drm/panel')
-rw-r--r--drivers/gpu/drm/panel/panel-samsung-s6e63m0.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c
index 842f8221be15..c9472b2ae0cd 100644
--- a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c
+++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c
@@ -25,6 +25,7 @@
#define MCS_ELVSS_ON 0xb1
#define MCS_MIECTL1 0xc0
#define MCS_BCMODE 0xc1
+#define MCS_ERROR_CHECK 0xd5
#define MCS_READ_ID1 0xda
#define MCS_READ_ID2 0xdb
#define MCS_READ_ID3 0xdc
@@ -279,8 +280,6 @@ static void s6e63m0_init(struct s6e63m0 *ctx)
s6e63m0_dcs_write_seq_static(ctx, MCS_ELVSS_ON,
0x0b);
-
- s6e63m0_dcs_write_seq_static(ctx, MIPI_DCS_EXIT_SLEEP_MODE);
}
static int s6e63m0_power_on(struct s6e63m0 *ctx)
@@ -293,6 +292,9 @@ static int s6e63m0_power_on(struct s6e63m0 *ctx)
msleep(25);
+ /* Be sure to send a reset pulse */
+ gpiod_set_value(ctx->reset_gpio, 1);
+ msleep(5);
gpiod_set_value(ctx->reset_gpio, 0);
msleep(120);
@@ -322,8 +324,10 @@ static int s6e63m0_disable(struct drm_panel *panel)
backlight_disable(ctx->bl_dev);
+ s6e63m0_dcs_write_seq_static(ctx, MIPI_DCS_SET_DISPLAY_OFF);
+ msleep(10);
s6e63m0_dcs_write_seq_static(ctx, MIPI_DCS_ENTER_SLEEP_MODE);
- msleep(200);
+ msleep(120);
ctx->enabled = false;
@@ -389,7 +393,15 @@ static int s6e63m0_enable(struct drm_panel *panel)
if (ctx->enabled)
return 0;
+ s6e63m0_dcs_write_seq_static(ctx, MIPI_DCS_EXIT_SLEEP_MODE);
+ msleep(120);
s6e63m0_dcs_write_seq_static(ctx, MIPI_DCS_SET_DISPLAY_ON);
+ msleep(10);
+
+ s6e63m0_dcs_write_seq_static(ctx, MCS_ERROR_CHECK,
+ 0xE7, 0x14, 0x60, 0x17, 0x0A, 0x49, 0xC3,
+ 0x8F, 0x19, 0x64, 0x91, 0x84, 0x76, 0x20,
+ 0x0F, 0x00);
backlight_enable(ctx->bl_dev);