* [PATCH 1/2] drm/panel: lg-sw43408: do not assert reset across unprepare
2026-08-09 0:04 [PATCH 0/2] Pixel 3 display fixes David Heidelberg via B4 Relay
@ 2026-08-09 0:04 ` David Heidelberg via B4 Relay
2026-08-10 9:52 ` Neil Armstrong
2026-08-09 0:04 ` [PATCH 2/2] drm/panel: lg-sw43408: use the full DCS brightness range David Heidelberg via B4 Relay
2026-08-09 0:15 ` [PATCH 0/2] Pixel 3 display fixes David Heidelberg
2 siblings, 1 reply; 6+ messages in thread
From: David Heidelberg via B4 Relay @ 2026-08-09 0: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, 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")
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 1/2] drm/panel: lg-sw43408: do not assert reset across unprepare
2026-08-09 0:04 ` [PATCH 1/2] drm/panel: lg-sw43408: do not assert reset across unprepare David Heidelberg via B4 Relay
@ 2026-08-10 9:52 ` Neil Armstrong
0 siblings, 0 replies; 6+ messages in thread
From: Neil Armstrong @ 2026-08-10 9:52 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/9/26 02:04, 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")
> 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);
Asserting the reset then shutting down half the rails up may force the DDIC to enter
a special low power mode with a bad sequence and then would not come out.
But anyway reset has a sense only if all rails are up and we want to get a proper
initial state, if somehow we want to handle those special low power mode to speed
up suspend and resume we will need to understand how to get in and get out.
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
>
> 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 2/2] drm/panel: lg-sw43408: use the full DCS brightness range
2026-08-09 0:04 [PATCH 0/2] Pixel 3 display fixes David Heidelberg via B4 Relay
2026-08-09 0:04 ` [PATCH 1/2] drm/panel: lg-sw43408: do not assert reset across unprepare David Heidelberg via B4 Relay
@ 2026-08-09 0:04 ` David Heidelberg via B4 Relay
2026-08-10 9:47 ` Neil Armstrong
2026-08-09 0:15 ` [PATCH 0/2] Pixel 3 display fixes David Heidelberg
2 siblings, 1 reply; 6+ messages in thread
From: David Heidelberg via B4 Relay @ 2026-08-09 0: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, 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 | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/panel/panel-lg-sw43408.c b/drivers/gpu/drm/panel/panel-lg-sw43408.c
index 0bf8e08f10b9c..332b15b6a4c94 100644
--- a/drivers/gpu/drm/panel/panel-lg-sw43408.c
+++ b/drivers/gpu/drm/panel/panel-lg-sw43408.c
@@ -202,18 +202,18 @@ static const struct backlight_ops sw43408_backlight_ops = {
.update_status = sw43408_backlight_update_status,
};
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,
+ .brightness = 256,
+ .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 2/2] drm/panel: lg-sw43408: use the full DCS brightness range
2026-08-09 0:04 ` [PATCH 2/2] drm/panel: lg-sw43408: use the full DCS brightness range David Heidelberg via B4 Relay
@ 2026-08-10 9:47 ` Neil Armstrong
0 siblings, 0 replies; 6+ messages in thread
From: Neil Armstrong @ 2026-08-10 9:47 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/9/26 02:04, 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 | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/panel/panel-lg-sw43408.c b/drivers/gpu/drm/panel/panel-lg-sw43408.c
> index 0bf8e08f10b9c..332b15b6a4c94 100644
> --- a/drivers/gpu/drm/panel/panel-lg-sw43408.c
> +++ b/drivers/gpu/drm/panel/panel-lg-sw43408.c
> @@ -202,18 +202,18 @@ static const struct backlight_ops sw43408_backlight_ops = {
> .update_status = sw43408_backlight_update_status,
> };
>
> 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,
> + .brightness = 256,
> + .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
* Re: [PATCH 0/2] Pixel 3 display fixes
2026-08-09 0:04 [PATCH 0/2] Pixel 3 display fixes David Heidelberg via B4 Relay
2026-08-09 0:04 ` [PATCH 1/2] drm/panel: lg-sw43408: do not assert reset across unprepare David Heidelberg via B4 Relay
2026-08-09 0:04 ` [PATCH 2/2] drm/panel: lg-sw43408: use the full DCS brightness range David Heidelberg via B4 Relay
@ 2026-08-09 0:15 ` David Heidelberg
2 siblings, 0 replies; 6+ messages in thread
From: David Heidelberg @ 2026-08-09 0:15 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, Konrad Dybcio
Cc: dri-devel, linux-kernel, phone-devel
Would make sense implement SWIRE "support" (which is here NO-OP)?
I guess device-tree should document that SWIRE is used, even when kernel doesn't
have to do anything?
e.g. something like - into the device DT?
&pmi8998_labibb {
qcom,swire-control;
};
David
On 09/08/2026 02:04, David Heidelberg via B4 Relay wrote:
> 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>
> ---
> 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 | 14 ++++++++++----
> 1 file changed, 10 insertions(+), 4 deletions(-)
> ---
> base-commit: 95d6a9ccef99117115e41e9adb271243bd5e985b
> change-id: 20260809-fix-blueline-panel-af2b7c967f2d
>
> Best regards,
> --
> David Heidelberg <david@ixit.cz>
>
>
--
David Heidelberg
^ permalink raw reply [flat|nested] 6+ messages in thread