* [PATCH v2 0/2] Pixel 3 display fixes
@ 2026-08-10 9:55 David Heidelberg via B4 Relay
2026-08-10 9:55 ` [PATCH v2 1/2] drm/panel: lg-sw43408: do not assert reset across unprepare David Heidelberg via B4 Relay
2026-08-10 9:55 ` [PATCH v2 2/2] drm/panel: lg-sw43408: use the full DCS brightness range David Heidelberg via B4 Relay
0 siblings, 2 replies; 6+ messages in thread
From: David Heidelberg via B4 Relay @ 2026-08-10 9:55 UTC (permalink / raw)
To: Sumit Semwal, Casey Connolly, Neil Armstrong, Jessica Zhang,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Dmitry Baryshkov, Marijn Suijten,
Vinod Koul
Cc: dri-devel, linux-kernel, phone-devel, David Heidelberg
Fix panel not recovering after unprepare and backlight intensity.
I extensively reproduced the vendor bootloader sequence, but after the
boot isn't possible to do the full initialization of the display (at
least on Pixel 3, and panel can't be found anywhere else).
The downstream, due to having attached touchscreen reusing same
supplies, never turns the panel off. Let's do the same.
Signed-off-by: David Heidelberg <david@ixit.cz>
---
Changes in v2:
- Unintended change 255 -> 256 for default brigtness. Drop it.
- Added R-bs.
- Link to v1: https://patch.msgid.link/20260809-fix-blueline-panel-v1-0-e7f3a6beb1fa@ixit.cz
---
David Heidelberg (2):
drm/panel: lg-sw43408: do not assert reset across unprepare
drm/panel: lg-sw43408: use the full DCS brightness range
drivers/gpu/drm/panel/panel-lg-sw43408.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
---
base-commit: 95d6a9ccef99117115e41e9adb271243bd5e985b
change-id: 20260809-fix-blueline-panel-af2b7c967f2d
Best regards,
--
David Heidelberg <david@ixit.cz>
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH v2 1/2] drm/panel: lg-sw43408: do not assert reset across unprepare 2026-08-10 9:55 [PATCH v2 0/2] Pixel 3 display fixes David Heidelberg via B4 Relay @ 2026-08-10 9:55 ` David Heidelberg via B4 Relay 2026-09-14 21:04 ` David Heidelberg 2026-08-10 9:55 ` [PATCH v2 2/2] drm/panel: lg-sw43408: use the full DCS brightness range David Heidelberg via B4 Relay 1 sibling, 1 reply; 6+ messages in thread From: David Heidelberg via B4 Relay @ 2026-08-10 9:55 UTC (permalink / raw) To: Sumit Semwal, Casey Connolly, Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter, Dmitry Baryshkov, Marijn Suijten, Vinod Koul Cc: dri-devel, linux-kernel, phone-devel, David Heidelberg From: David Heidelberg <david@ixit.cz> Asserting the reset GPIO in unprepare() and leaving it asserted puts the DDIC into a state it never recovers from: after the following prepare() the panel answers all DCS commands, reports display-on with clean self-diagnostics, and its configuration registers read back identical to a working panel, but it never lights up again. On the Pixel 3, vddi is shared with the touchscreen controller and remains powered while the panel is off, so with this driver the DDIC sits in reset with its logic rail up for the whole blank period - a state the vendor stack never creates: the vendor firmware only toggles reset as part of a full power-on sequence, and the vendor OS never power-cycles the panel at all (LP mode is used instead). Leave reset alone in unprepare(); prepare() performs the regular reset sequence anyway. Without this, the Pixel 3 display never comes back after the first blank/unblank cycle. Since there isn't any other panel or device using this DDIC, this approach seems resoanble to address the issue. Fixes: 069a6c0e94f9 ("drm: panel: Add LG sw43408 panel driver") Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Signed-off-by: David Heidelberg <david@ixit.cz> --- drivers/gpu/drm/panel/panel-lg-sw43408.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-lg-sw43408.c b/drivers/gpu/drm/panel/panel-lg-sw43408.c index 293826c5006b9..0bf8e08f10b9c 100644 --- a/drivers/gpu/drm/panel/panel-lg-sw43408.c +++ b/drivers/gpu/drm/panel/panel-lg-sw43408.c @@ -50,18 +50,24 @@ static int sw43408_unprepare(struct drm_panel *panel) int ret; mipi_dsi_dcs_set_display_off_multi(&ctx); mipi_dsi_dcs_enter_sleep_mode_multi(&ctx); mipi_dsi_msleep(&ctx, 100); - gpiod_set_value(sw43408->reset_gpio, 1); - + /* + * Keep reset deasserted: vddi may stay powered (it is shared with + * the touchscreen on Pixel 3) and holding the DDIC in reset while + * its logic rail is up puts it into a state that no init sequence + * recovers from - the panel keeps answering DCS commands and + * reports display-on, but never lights up again. The vendor stack + * only ever toggles reset as part of a powered-up init sequence. + */ ret = regulator_bulk_disable(ARRAY_SIZE(sw43408_supplies), sw43408->supplies); return ret ? : ctx.accum_err; } static int sw43408_program(struct drm_panel *panel) { struct sw43408_panel *sw43408 = to_panel_info(panel); -- 2.55.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] drm/panel: lg-sw43408: do not assert reset across unprepare 2026-08-10 9:55 ` [PATCH v2 1/2] drm/panel: lg-sw43408: do not assert reset across unprepare David Heidelberg via B4 Relay @ 2026-09-14 21:04 ` David Heidelberg 2026-09-20 12:34 ` David Heidelberg 0 siblings, 1 reply; 6+ messages in thread From: David Heidelberg @ 2026-09-14 21:04 UTC (permalink / raw) To: Sumit Semwal, Casey Connolly, Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter, Dmitry Baryshkov, Marijn Suijten, Vinod Koul Cc: dri-devel, linux-kernel, phone-devel On 10/08/2026 11:55, David Heidelberg via B4 Relay wrote: > From: David Heidelberg <david@ixit.cz> > > Asserting the reset GPIO in unprepare() and leaving it asserted puts > the DDIC into a state it never recovers from: after the following > prepare() the panel answers all DCS commands, reports display-on with > clean self-diagnostics, and its configuration registers read back > identical to a working panel, but it never lights up again. > > On the Pixel 3, vddi is shared with the touchscreen controller and > remains powered while the panel is off, so with this driver the DDIC > sits in reset with its logic rail up for the whole blank period - a > state the vendor stack never creates: the vendor firmware only toggles > reset as part of a full power-on sequence, and the vendor OS never > power-cycles the panel at all (LP mode is used instead). > > Leave reset alone in unprepare(); prepare() performs the regular reset > sequence anyway. > > Without this, the Pixel 3 display never comes back after the first > blank/unblank cycle. > > Since there isn't any other panel or device using this DDIC, this > approach seems resoanble to address the issue. > > Fixes: 069a6c0e94f9 ("drm: panel: Add LG sw43408 panel driver") > Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> > Signed-off-by: David Heidelberg <david@ixit.cz> > --- > drivers/gpu/drm/panel/panel-lg-sw43408.c | 10 ++++++++-- > 1 file changed, 8 insertions(+), 2 deletions(-) > Good news is, that this patch really doesn't make panel power-off fatal for the phone, but recent testing got me into state where I observed: 10 hours, display on, phone operating normally. display on (various time), display off, display on OK, but sometimes display on, display off (for longer time), after pressing power button (to wake up) the phone reboot into bootloader. Nothing printed into dmesg (I'll try enable drm-debug, but not having high hopes. So far, this is still heavy improvement comparing to instant crash, but not the perfect solution either. David > diff --git a/drivers/gpu/drm/panel/panel-lg-sw43408.c b/drivers/gpu/drm/panel/panel-lg-sw43408.c > index 293826c5006b9..0bf8e08f10b9c 100644 > --- a/drivers/gpu/drm/panel/panel-lg-sw43408.c > +++ b/drivers/gpu/drm/panel/panel-lg-sw43408.c > @@ -50,18 +50,24 @@ static int sw43408_unprepare(struct drm_panel *panel) > int ret; > > mipi_dsi_dcs_set_display_off_multi(&ctx); > > mipi_dsi_dcs_enter_sleep_mode_multi(&ctx); > > mipi_dsi_msleep(&ctx, 100); > > - gpiod_set_value(sw43408->reset_gpio, 1); > - > + /* > + * Keep reset deasserted: vddi may stay powered (it is shared with > + * the touchscreen on Pixel 3) and holding the DDIC in reset while > + * its logic rail is up puts it into a state that no init sequence > + * recovers from - the panel keeps answering DCS commands and > + * reports display-on, but never lights up again. The vendor stack > + * only ever toggles reset as part of a powered-up init sequence. > + */ > ret = regulator_bulk_disable(ARRAY_SIZE(sw43408_supplies), sw43408->supplies); > > return ret ? : ctx.accum_err; > } > > static int sw43408_program(struct drm_panel *panel) > { > struct sw43408_panel *sw43408 = to_panel_info(panel); > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] drm/panel: lg-sw43408: do not assert reset across unprepare 2026-09-14 21:04 ` David Heidelberg @ 2026-09-20 12:34 ` David Heidelberg 0 siblings, 0 replies; 6+ messages in thread From: David Heidelberg @ 2026-09-20 12:34 UTC (permalink / raw) To: Sumit Semwal, Casey Connolly, Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter, Dmitry Baryshkov, Marijn Suijten, Vinod Koul Cc: dri-devel, linux-kernel, phone-devel On 14/09/2026 23:04, David Heidelberg wrote: > On 10/08/2026 11:55, David Heidelberg via B4 Relay wrote: >> From: David Heidelberg <david@ixit.cz> >> >> Asserting the reset GPIO in unprepare() and leaving it asserted puts >> the DDIC into a state it never recovers from: after the following >> prepare() the panel answers all DCS commands, reports display-on with >> clean self-diagnostics, and its configuration registers read back >> identical to a working panel, but it never lights up again. >> >> On the Pixel 3, vddi is shared with the touchscreen controller and >> remains powered while the panel is off, so with this driver the DDIC >> sits in reset with its logic rail up for the whole blank period - a >> state the vendor stack never creates: the vendor firmware only toggles >> reset as part of a full power-on sequence, and the vendor OS never >> power-cycles the panel at all (LP mode is used instead). >> >> Leave reset alone in unprepare(); prepare() performs the regular reset >> sequence anyway. >> >> Without this, the Pixel 3 display never comes back after the first >> blank/unblank cycle. >> >> Since there isn't any other panel or device using this DDIC, this >> approach seems resoanble to address the issue. >> >> Fixes: 069a6c0e94f9 ("drm: panel: Add LG sw43408 panel driver") >> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> >> Signed-off-by: David Heidelberg <david@ixit.cz> >> --- >> drivers/gpu/drm/panel/panel-lg-sw43408.c | 10 ++++++++-- >> 1 file changed, 8 insertions(+), 2 deletions(-) >> > > Good news is, that this patch really doesn't make panel power-off fatal for the > phone, but recent testing got me into state where I observed: > > 10 hours, display on, phone operating normally. > > display on (various time), display off, display on OK, but sometimes > > display on, display off (for longer time), after pressing power button (to wake > up) the phone reboot into bootloader. > > Nothing printed into dmesg (I'll try enable drm-debug, but not having high hopes. > > So far, this is still heavy improvement comparing to instant crash, but not the > perfect solution either. Please ignore this email, I debugged the issue and the phone never returned from the suspend due to serial geni bugs. This fixes are good to go. David > > David > >> diff --git a/drivers/gpu/drm/panel/panel-lg-sw43408.c b/drivers/gpu/drm/panel/ >> panel-lg-sw43408.c >> index 293826c5006b9..0bf8e08f10b9c 100644 >> --- a/drivers/gpu/drm/panel/panel-lg-sw43408.c >> +++ b/drivers/gpu/drm/panel/panel-lg-sw43408.c >> @@ -50,18 +50,24 @@ static int sw43408_unprepare(struct drm_panel *panel) >> int ret; >> mipi_dsi_dcs_set_display_off_multi(&ctx); >> mipi_dsi_dcs_enter_sleep_mode_multi(&ctx); >> mipi_dsi_msleep(&ctx, 100); >> - gpiod_set_value(sw43408->reset_gpio, 1); >> - >> + /* >> + * Keep reset deasserted: vddi may stay powered (it is shared with >> + * the touchscreen on Pixel 3) and holding the DDIC in reset while >> + * its logic rail is up puts it into a state that no init sequence >> + * recovers from - the panel keeps answering DCS commands and >> + * reports display-on, but never lights up again. The vendor stack >> + * only ever toggles reset as part of a powered-up init sequence. >> + */ >> ret = regulator_bulk_disable(ARRAY_SIZE(sw43408_supplies), sw43408- >> >supplies); >> return ret ? : ctx.accum_err; >> } >> static int sw43408_program(struct drm_panel *panel) >> { >> struct sw43408_panel *sw43408 = to_panel_info(panel); >> > ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 2/2] drm/panel: lg-sw43408: use the full DCS brightness range 2026-08-10 9:55 [PATCH v2 0/2] Pixel 3 display fixes David Heidelberg via B4 Relay 2026-08-10 9:55 ` [PATCH v2 1/2] drm/panel: lg-sw43408: do not assert reset across unprepare David Heidelberg via B4 Relay @ 2026-08-10 9:55 ` David Heidelberg via B4 Relay 2026-08-10 9:59 ` Neil Armstrong 1 sibling, 1 reply; 6+ messages in thread From: David Heidelberg via B4 Relay @ 2026-08-10 9:55 UTC (permalink / raw) To: Sumit Semwal, Casey Connolly, Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter, Dmitry Baryshkov, Marijn Suijten, Vinod Koul Cc: dri-devel, linux-kernel, phone-devel, David Heidelberg From: David Heidelberg <david@ixit.cz> The vendor firmware panel configuration (XBL DisplayDxe panel XML) declares DCSMaxBrightness 0x332 with a two-byte brightness command, and the driver already sends two bytes via mipi_dsi_dcs_set_display_brightness_large(). Capping max_brightness at 255 therefore limits the panel to ~31% of its real brightness range. Use the firmware maximum. Fixes: 069a6c0e94f9 ("drm: panel: Add LG sw43408 panel driver") Signed-off-by: David Heidelberg <david@ixit.cz> --- drivers/gpu/drm/panel/panel-lg-sw43408.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-lg-sw43408.c b/drivers/gpu/drm/panel/panel-lg-sw43408.c index 0bf8e08f10b9c..be132b65b0c13 100644 --- a/drivers/gpu/drm/panel/panel-lg-sw43408.c +++ b/drivers/gpu/drm/panel/panel-lg-sw43408.c @@ -203,17 +203,17 @@ static const struct backlight_ops sw43408_backlight_ops = { }; static int sw43408_backlight_init(struct sw43408_panel *ctx) { struct device *dev = &ctx->link->dev; const struct backlight_properties props = { .type = BACKLIGHT_PLATFORM, .brightness = 255, - .max_brightness = 255, + .max_brightness = 818, }; ctx->base.backlight = devm_backlight_device_register(dev, dev_name(dev), dev, ctx->link, &sw43408_backlight_ops, &props); if (IS_ERR(ctx->base.backlight)) -- 2.55.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] drm/panel: lg-sw43408: use the full DCS brightness range 2026-08-10 9:55 ` [PATCH v2 2/2] drm/panel: lg-sw43408: use the full DCS brightness range David Heidelberg via B4 Relay @ 2026-08-10 9:59 ` Neil Armstrong 0 siblings, 0 replies; 6+ messages in thread From: Neil Armstrong @ 2026-08-10 9:59 UTC (permalink / raw) To: david, Sumit Semwal, Casey Connolly, Jessica Zhang, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter, Dmitry Baryshkov, Marijn Suijten, Vinod Koul Cc: dri-devel, linux-kernel, phone-devel On 8/10/26 11:55, David Heidelberg via B4 Relay wrote: > From: David Heidelberg <david@ixit.cz> > > The vendor firmware panel configuration (XBL DisplayDxe panel XML) > declares DCSMaxBrightness 0x332 with a two-byte brightness command, > and the driver already sends two bytes via > mipi_dsi_dcs_set_display_brightness_large(). > > Capping max_brightness at 255 therefore limits the panel to ~31% of > its real brightness range. Use the firmware maximum. > > Fixes: 069a6c0e94f9 ("drm: panel: Add LG sw43408 panel driver") > Signed-off-by: David Heidelberg <david@ixit.cz> > --- > drivers/gpu/drm/panel/panel-lg-sw43408.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/panel/panel-lg-sw43408.c b/drivers/gpu/drm/panel/panel-lg-sw43408.c > index 0bf8e08f10b9c..be132b65b0c13 100644 > --- a/drivers/gpu/drm/panel/panel-lg-sw43408.c > +++ b/drivers/gpu/drm/panel/panel-lg-sw43408.c > @@ -203,17 +203,17 @@ static const struct backlight_ops sw43408_backlight_ops = { > }; > > static int sw43408_backlight_init(struct sw43408_panel *ctx) > { > struct device *dev = &ctx->link->dev; > const struct backlight_properties props = { > .type = BACKLIGHT_PLATFORM, > .brightness = 255, > - .max_brightness = 255, > + .max_brightness = 818, > }; > > ctx->base.backlight = devm_backlight_device_register(dev, dev_name(dev), dev, > ctx->link, > &sw43408_backlight_ops, > &props); > > if (IS_ERR(ctx->base.backlight)) > Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Thanks, Neil ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-09-20 12:34 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-08-10 9:55 [PATCH v2 0/2] Pixel 3 display fixes David Heidelberg via B4 Relay 2026-08-10 9:55 ` [PATCH v2 1/2] drm/panel: lg-sw43408: do not assert reset across unprepare David Heidelberg via B4 Relay 2026-09-14 21:04 ` David Heidelberg 2026-09-20 12:34 ` David Heidelberg 2026-08-10 9:55 ` [PATCH v2 2/2] drm/panel: lg-sw43408: use the full DCS brightness range David Heidelberg via B4 Relay 2026-08-10 9:59 ` Neil Armstrong
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®