* [PATCH v4 0/3] sysfb: Fix display output on Lenovo D330 (and others)
@ 2026-09-04 9:06 Thomas Zimmermann
2026-09-04 9:07 ` [PATCH v4 1/3] firmware/sysfb: Remove rotation quirk for Lenovo D330 Thomas Zimmermann
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Thomas Zimmermann @ 2026-09-04 9:06 UTC (permalink / raw)
To: javierm, ardb, ilias.apalodimas, jani.nikula, maarten.lankhorst,
mripard, simona, airlied
Cc: dri-devel, linux-efi, sashiko-reviews, Thomas Zimmermann
The kernel mis-interprets the display geometry given by the Lenovo
D330 as incorrect. The values are correct, but the display output is
rotated by 90°. With the kernel's firmware quirk applied, the output
is garbled.
Remove the firmware quirk for the Lenovo D330 and let DRM's sysfb
drivers set the correct panel orientation instead. To make this work
for any display mode, use the panel size for looking up the correct
orientation.
Tested on a Lenovo D330-10IGM IdeaPad.
v4:
- fix test for EDID PTD (Jani)
v3:
- rename EDID helper to drm_edid_detect_panel_size()
- clean up EDID code (Jani)
- mention possible dependency on device firmware version
v2:
- reorder patches to have the immediate fix first
- detect and handle broken EDID better (Sashiko)
- fix width/height pointer check (Sashiko)
Thomas Zimmermann (3):
firmware/sysfb: Remove rotation quirk for Lenovo D330
drm/edid: Add drm_edid_detect_panel_size()
drm/sysfb: Use preferred panel size for panel orientation quirks
drivers/firmware/efi/sysfb_efi.c | 9 ------
drivers/gpu/drm/drm_edid.c | 47 ++++++++++++++++++++++++++++++++
drivers/gpu/drm/sysfb/efidrm.c | 17 +++++++++++-
drivers/gpu/drm/sysfb/ofdrm.c | 18 ++++++++++--
drivers/gpu/drm/sysfb/vesadrm.c | 17 +++++++++++-
include/drm/drm_edid.h | 2 ++
6 files changed, 97 insertions(+), 13 deletions(-)
base-commit: aa389a514292b196ae89c6515568b3329abeec63
--
2.55.0
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH v4 1/3] firmware/sysfb: Remove rotation quirk for Lenovo D330 2026-09-04 9:06 [PATCH v4 0/3] sysfb: Fix display output on Lenovo D330 (and others) Thomas Zimmermann @ 2026-09-04 9:07 ` Thomas Zimmermann 2026-09-04 9:07 ` [PATCH v4 2/3] drm/edid: Add drm_edid_detect_panel_size() Thomas Zimmermann 2026-09-04 9:07 ` [PATCH v4 3/3] drm/sysfb: Use preferred panel size for panel orientation quirks Thomas Zimmermann 2 siblings, 0 replies; 6+ messages in thread From: Thomas Zimmermann @ 2026-09-04 9:07 UTC (permalink / raw) To: javierm, ardb, ilias.apalodimas, jani.nikula, maarten.lankhorst, mripard, simona, airlied Cc: dri-devel, linux-efi, sashiko-reviews, Thomas Zimmermann The Lenovo D330 is a notebook with detachable display. The display is installed in landscape orientation, but the display mode is in portrait orientation. By default, the display output is rotated to the left by 90°. The sysfb quirk breaks the display by swapping display width and height; and thus mixing up the display geometry. Fix this by keeping the display as-is. The sysfb DRM drivers, usually efidrm, will pick the correct panel orientation for the display. The exact behavior might depend on the version of the BIOS release, but the exact version numbers of broken and good releases are unknown. Users are advised to update to the latest firmware. Tested on a Lenovo D330-10IGM IdeaPad with firmware 8NCN43WW. v3: - mention possible dependency on BIOS release in commit description Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Ard Biesheuvel <ardb@kernel.org> --- drivers/firmware/efi/sysfb_efi.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/firmware/efi/sysfb_efi.c b/drivers/firmware/efi/sysfb_efi.c index 685283bb7327..2338de73c62c 100644 --- a/drivers/firmware/efi/sysfb_efi.c +++ b/drivers/firmware/efi/sysfb_efi.c @@ -301,15 +301,6 @@ static const struct dmi_system_id efifb_dmi_swap_width_height[] __initconst = { }, .callback = efifb_swap_width_height, }, - { - /* Lenovo D330 with 800x1280 or 1200x1920 portrait screen */ - .matches = { - DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, - "Lenovo ideapad D330-10IGM"), - }, - .callback = efifb_swap_width_height, - }, { /* * Lenovo IdeaPad Duet 3 10IGL5 and 10IGL5-LTE with -- 2.55.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v4 2/3] drm/edid: Add drm_edid_detect_panel_size() 2026-09-04 9:06 [PATCH v4 0/3] sysfb: Fix display output on Lenovo D330 (and others) Thomas Zimmermann 2026-09-04 9:07 ` [PATCH v4 1/3] firmware/sysfb: Remove rotation quirk for Lenovo D330 Thomas Zimmermann @ 2026-09-04 9:07 ` Thomas Zimmermann 2026-09-04 9:28 ` Jani Nikula 2026-09-04 9:07 ` [PATCH v4 3/3] drm/sysfb: Use preferred panel size for panel orientation quirks Thomas Zimmermann 2 siblings, 1 reply; 6+ messages in thread From: Thomas Zimmermann @ 2026-09-04 9:07 UTC (permalink / raw) To: javierm, ardb, ilias.apalodimas, jani.nikula, maarten.lankhorst, mripard, simona, airlied Cc: dri-devel, linux-efi, sashiko-reviews, Thomas Zimmermann Add drm_edid_detect_panel_size() to extract the panel's preferred display resolution from a given EDID. Required for setting up DRM's panel orientation quirks in sysfb drivers. v4: - fix test for EDID PTD (Jani) v3: - mention use case in documentation (Jani) - use is_detailed_timing_descriptor() (Jani) - rename helper to drm_edid_detect_panel_size() v2: - handle EDID without pixel timing descriptor (Sashiko) - fix checks for width and height pointers Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Ard Biesheuvel <ardb@kernel.org> --- drivers/gpu/drm/drm_edid.c | 47 ++++++++++++++++++++++++++++++++++++++ include/drm/drm_edid.h | 2 ++ 2 files changed, 49 insertions(+) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 9990a836d0b6..1331efb4876c 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -7852,3 +7852,50 @@ bool drm_edid_is_digital(const struct drm_edid *drm_edid) drm_edid->edid->input & DRM_EDID_INPUT_DIGITAL; } EXPORT_SYMBOL(drm_edid_is_digital); + +/** + * drm_edid_detect_panel_size - Get a panel's size from EDID + * @drm_edid: EDID of the panel. + * @width: Returns the panel's width in pixels per scanline, if given + * @height: Returns the panel's height in scanlines, if given + * + * This function detects the preferred size of a panel from the given + * EDID. There is no such information stored in the EDID block directly, + * but the preferred mode often corresponds to the panel's native geometry. + * + * This helper should only be used during initialization before the + * connector is available. For regular use, retrieve the available display + * modes with the connector functions. + * + * Return: Zero on success, or a negative errno code otherwise. + */ +int drm_edid_detect_panel_size(const struct drm_edid *drm_edid, + unsigned int *width, unsigned int *height) +{ + const struct edid *edid = drm_edid->edid; + const struct detailed_timing *dt; + const struct detailed_pixel_timing *pt; + + /* + * Use display mode from the Preferred Timing Descriptor. For old + * and obscure displays, we might need better heuristics. + */ + + if (edid->revision < 4 || !(edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING)) + return -EINVAL; /* no Preferred Timing Descriptor */ + + dt = &edid->detailed_timings[0]; + + if (!is_detailed_timing_descriptor(dt)) + return -EINVAL; + + pt = &dt->data.pixel_data; + + if (width) + *width = (pt->hactive_hblank_hi & 0xf0) << 4 | pt->hactive_lo; + if (height) + *height = (pt->vactive_vblank_hi & 0xf0) << 4 | pt->vactive_lo; + + return 0; +} +EXPORT_SYMBOL(drm_edid_detect_panel_size); diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index 04f7a7f1f108..a2617aa34edf 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -490,5 +490,7 @@ u32 drm_edid_get_panel_id(const struct drm_edid *drm_edid); bool drm_edid_match(const struct drm_edid *drm_edid, const struct drm_edid_ident *ident); bool drm_edid_has_quirk(struct drm_connector *connector, enum drm_edid_quirk quirk); +int drm_edid_detect_panel_size(const struct drm_edid *drm_edid, + unsigned int *width, unsigned int *height); #endif /* __DRM_EDID_H__ */ -- 2.55.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v4 2/3] drm/edid: Add drm_edid_detect_panel_size() 2026-09-04 9:07 ` [PATCH v4 2/3] drm/edid: Add drm_edid_detect_panel_size() Thomas Zimmermann @ 2026-09-04 9:28 ` Jani Nikula 0 siblings, 0 replies; 6+ messages in thread From: Jani Nikula @ 2026-09-04 9:28 UTC (permalink / raw) To: Thomas Zimmermann, javierm, ardb, ilias.apalodimas, maarten.lankhorst, mripard, simona, airlied Cc: dri-devel, linux-efi, sashiko-reviews, Thomas Zimmermann On Fri, 04 Sep 2026, Thomas Zimmermann <tzimmermann@suse.de> wrote: > Add drm_edid_detect_panel_size() to extract the panel's preferred > display resolution from a given EDID. Required for setting up DRM's > panel orientation quirks in sysfb drivers. > > v4: > - fix test for EDID PTD (Jani) > v3: > - mention use case in documentation (Jani) > - use is_detailed_timing_descriptor() (Jani) > - rename helper to drm_edid_detect_panel_size() > v2: > - handle EDID without pixel timing descriptor (Sashiko) > - fix checks for width and height pointers > > Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> > Acked-by: Ard Biesheuvel <ardb@kernel.org> Given my shoddy comments before, not sure what it's worth, but, Reviewed-by: Jani Nikula <jani.nikula@intel.com> > --- > drivers/gpu/drm/drm_edid.c | 47 ++++++++++++++++++++++++++++++++++++++ > include/drm/drm_edid.h | 2 ++ > 2 files changed, 49 insertions(+) > > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c > index 9990a836d0b6..1331efb4876c 100644 > --- a/drivers/gpu/drm/drm_edid.c > +++ b/drivers/gpu/drm/drm_edid.c > @@ -7852,3 +7852,50 @@ bool drm_edid_is_digital(const struct drm_edid *drm_edid) > drm_edid->edid->input & DRM_EDID_INPUT_DIGITAL; > } > EXPORT_SYMBOL(drm_edid_is_digital); > + > +/** > + * drm_edid_detect_panel_size - Get a panel's size from EDID > + * @drm_edid: EDID of the panel. > + * @width: Returns the panel's width in pixels per scanline, if given > + * @height: Returns the panel's height in scanlines, if given > + * > + * This function detects the preferred size of a panel from the given > + * EDID. There is no such information stored in the EDID block directly, > + * but the preferred mode often corresponds to the panel's native geometry. > + * > + * This helper should only be used during initialization before the > + * connector is available. For regular use, retrieve the available display > + * modes with the connector functions. > + * > + * Return: Zero on success, or a negative errno code otherwise. > + */ > +int drm_edid_detect_panel_size(const struct drm_edid *drm_edid, > + unsigned int *width, unsigned int *height) > +{ > + const struct edid *edid = drm_edid->edid; > + const struct detailed_timing *dt; > + const struct detailed_pixel_timing *pt; > + > + /* > + * Use display mode from the Preferred Timing Descriptor. For old > + * and obscure displays, we might need better heuristics. > + */ > + > + if (edid->revision < 4 || !(edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING)) > + return -EINVAL; /* no Preferred Timing Descriptor */ > + > + dt = &edid->detailed_timings[0]; > + > + if (!is_detailed_timing_descriptor(dt)) > + return -EINVAL; > + > + pt = &dt->data.pixel_data; > + > + if (width) > + *width = (pt->hactive_hblank_hi & 0xf0) << 4 | pt->hactive_lo; > + if (height) > + *height = (pt->vactive_vblank_hi & 0xf0) << 4 | pt->vactive_lo; > + > + return 0; > +} > +EXPORT_SYMBOL(drm_edid_detect_panel_size); > diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h > index 04f7a7f1f108..a2617aa34edf 100644 > --- a/include/drm/drm_edid.h > +++ b/include/drm/drm_edid.h > @@ -490,5 +490,7 @@ u32 drm_edid_get_panel_id(const struct drm_edid *drm_edid); > bool drm_edid_match(const struct drm_edid *drm_edid, > const struct drm_edid_ident *ident); > bool drm_edid_has_quirk(struct drm_connector *connector, enum drm_edid_quirk quirk); > +int drm_edid_detect_panel_size(const struct drm_edid *drm_edid, > + unsigned int *width, unsigned int *height); > > #endif /* __DRM_EDID_H__ */ -- Jani Nikula, Intel ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v4 3/3] drm/sysfb: Use preferred panel size for panel orientation quirks 2026-09-04 9:06 [PATCH v4 0/3] sysfb: Fix display output on Lenovo D330 (and others) Thomas Zimmermann 2026-09-04 9:07 ` [PATCH v4 1/3] firmware/sysfb: Remove rotation quirk for Lenovo D330 Thomas Zimmermann 2026-09-04 9:07 ` [PATCH v4 2/3] drm/edid: Add drm_edid_detect_panel_size() Thomas Zimmermann @ 2026-09-04 9:07 ` Thomas Zimmermann 2026-09-04 9:41 ` Jani Nikula 2 siblings, 1 reply; 6+ messages in thread From: Thomas Zimmermann @ 2026-09-04 9:07 UTC (permalink / raw) To: javierm, ardb, ilias.apalodimas, jani.nikula, maarten.lankhorst, mripard, simona, airlied Cc: dri-devel, linux-efi, sashiko-reviews, Thomas Zimmermann Sysfb drivers currently use the given display mode for looking up the panel orientation. But the look-up table stores the native geometry of the panels, so the lookup fails if the current mode sizes differs. Get the panel's native geometry with drm_edid_detect_panel_size() from the EDID and use it for looking up the panel orientation. v2: - ofdrm: validate EDID header before using it (Sashiko) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Ard Biesheuvel <ardb@kernel.org> --- drivers/gpu/drm/sysfb/efidrm.c | 17 ++++++++++++++++- drivers/gpu/drm/sysfb/ofdrm.c | 18 ++++++++++++++++-- drivers/gpu/drm/sysfb/vesadrm.c | 17 ++++++++++++++++- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/sysfb/efidrm.c b/drivers/gpu/drm/sysfb/efidrm.c index 3f9cd5d03efb..8b19f437308e 100644 --- a/drivers/gpu/drm/sysfb/efidrm.c +++ b/drivers/gpu/drm/sysfb/efidrm.c @@ -152,6 +152,7 @@ static struct efidrm_device *efidrm_device_create(struct drm_driver *drv, const struct screen_info *si; const struct drm_format_info *format; int width, height, stride; + unsigned int panel_width, panel_height; s64 vsize; u64 mem_flags; struct resource resbuf; @@ -217,6 +218,20 @@ static struct efidrm_device *efidrm_device_create(struct drm_driver *drv, if (drm_edid_header_is_valid(dpy->edid.dummy) == 8) sysfb->edid = dpy->edid.dummy; #endif + + panel_width = width; + panel_height = height; + + if (sysfb->edid) { + const struct drm_edid *drm_edid; + + drm_edid = drm_edid_alloc(sysfb->edid, EDID_LENGTH); + if (drm_edid) { + drm_edid_detect_panel_size(drm_edid, &panel_width, &panel_height); + drm_edid_free(drm_edid); + } + } + sysfb->fb_mode = drm_sysfb_mode(width, height, 0, 0); sysfb->fb_format = format; sysfb->fb_pitch = stride; @@ -340,7 +355,7 @@ static struct efidrm_device *efidrm_device_create(struct drm_driver *drv, drm_connector_helper_add(connector, &efidrm_connector_helper_funcs); drm_connector_set_panel_orientation_with_quirk(connector, DRM_MODE_PANEL_ORIENTATION_UNKNOWN, - width, height); + panel_width, panel_height); if (sysfb->edid) drm_connector_attach_edid_property(connector); diff --git a/drivers/gpu/drm/sysfb/ofdrm.c b/drivers/gpu/drm/sysfb/ofdrm.c index 9d60db45139c..c41255569854 100644 --- a/drivers/gpu/drm/sysfb/ofdrm.c +++ b/drivers/gpu/drm/sysfb/ofdrm.c @@ -229,7 +229,7 @@ static const u8 *display_get_edid_of(struct drm_device *dev, struct device_node { int ret = of_property_read_u8_array(of_node, "EDID", buf, EDID_LENGTH); - if (ret) + if (ret || drm_edid_header_is_valid(buf) != 8) return NULL; return buf; } @@ -828,6 +828,7 @@ static struct ofdrm_device *ofdrm_device_create(struct drm_driver *drv, enum ofdrm_model model; bool big_endian; int width, height, depth, linebytes; + unsigned int panel_width, panel_height; const struct drm_format_info *format; u64 address; const u8 *edid; @@ -998,6 +999,19 @@ static struct ofdrm_device *ofdrm_device_create(struct drm_driver *drv, sysfb->fb_gamma_lut_size = OFDRM_GAMMA_LUT_SIZE; sysfb->edid = edid; + panel_width = width; + panel_height = height; + + if (sysfb->edid) { + const struct drm_edid *drm_edid; + + drm_edid = drm_edid_alloc(sysfb->edid, EDID_LENGTH); + if (drm_edid) { + drm_edid_detect_panel_size(drm_edid, &panel_width, &panel_height); + drm_edid_free(drm_edid); + } + } + drm_dbg(dev, "display mode={" DRM_MODE_FMT "}\n", DRM_MODE_ARG(&sysfb->fb_mode)); drm_dbg(dev, "framebuffer format=%p4cc, size=%dx%d, linebytes=%d byte\n", &format->format, width, height, linebytes); @@ -1069,7 +1083,7 @@ static struct ofdrm_device *ofdrm_device_create(struct drm_driver *drv, drm_connector_helper_add(connector, &ofdrm_connector_helper_funcs); drm_connector_set_panel_orientation_with_quirk(connector, DRM_MODE_PANEL_ORIENTATION_UNKNOWN, - width, height); + panel_width, panel_height); if (edid) drm_connector_attach_edid_property(connector); diff --git a/drivers/gpu/drm/sysfb/vesadrm.c b/drivers/gpu/drm/sysfb/vesadrm.c index 6a67b2d2e451..f6358a0a68bd 100644 --- a/drivers/gpu/drm/sysfb/vesadrm.c +++ b/drivers/gpu/drm/sysfb/vesadrm.c @@ -402,6 +402,7 @@ static struct vesadrm_device *vesadrm_device_create(struct drm_driver *drv, const struct screen_info *si; const struct drm_format_info *format; int width, height, stride; + unsigned int panel_width, panel_height; s64 vsize; struct resource resbuf; struct resource *res; @@ -484,6 +485,20 @@ static struct vesadrm_device *vesadrm_device_create(struct drm_driver *drv, if (drm_edid_header_is_valid(dpy->edid.dummy) == 8) sysfb->edid = dpy->edid.dummy; #endif + + panel_width = width; + panel_height = height; + + if (sysfb->edid) { + const struct drm_edid *drm_edid; + + drm_edid = drm_edid_alloc(sysfb->edid, EDID_LENGTH); + if (drm_edid) { + drm_edid_detect_panel_size(drm_edid, &panel_width, &panel_height); + drm_edid_free(drm_edid); + } + } + sysfb->fb_mode = drm_sysfb_mode(width, height, 0, 0); sysfb->fb_format = format; sysfb->fb_pitch = stride; @@ -585,7 +600,7 @@ static struct vesadrm_device *vesadrm_device_create(struct drm_driver *drv, drm_connector_helper_add(connector, &vesadrm_connector_helper_funcs); drm_connector_set_panel_orientation_with_quirk(connector, DRM_MODE_PANEL_ORIENTATION_UNKNOWN, - width, height); + panel_width, panel_height); if (sysfb->edid) drm_connector_attach_edid_property(connector); -- 2.55.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v4 3/3] drm/sysfb: Use preferred panel size for panel orientation quirks 2026-09-04 9:07 ` [PATCH v4 3/3] drm/sysfb: Use preferred panel size for panel orientation quirks Thomas Zimmermann @ 2026-09-04 9:41 ` Jani Nikula 0 siblings, 0 replies; 6+ messages in thread From: Jani Nikula @ 2026-09-04 9:41 UTC (permalink / raw) To: Thomas Zimmermann, javierm, ardb, ilias.apalodimas, maarten.lankhorst, mripard, simona, airlied Cc: dri-devel, linux-efi, sashiko-reviews, Thomas Zimmermann On Fri, 04 Sep 2026, Thomas Zimmermann <tzimmermann@suse.de> wrote: > Sysfb drivers currently use the given display mode for looking up the > panel orientation. But the look-up table stores the native geometry of > the panels, so the lookup fails if the current mode sizes differs. > > Get the panel's native geometry with drm_edid_detect_panel_size() from > the EDID and use it for looking up the panel orientation. > > v2: > - ofdrm: validate EDID header before using it (Sashiko) > > Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> > Acked-by: Ard Biesheuvel <ardb@kernel.org> Acked-by: Jani Nikula <jani.nikula@intel.com> > --- > drivers/gpu/drm/sysfb/efidrm.c | 17 ++++++++++++++++- > drivers/gpu/drm/sysfb/ofdrm.c | 18 ++++++++++++++++-- > drivers/gpu/drm/sysfb/vesadrm.c | 17 ++++++++++++++++- > 3 files changed, 48 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/sysfb/efidrm.c b/drivers/gpu/drm/sysfb/efidrm.c > index 3f9cd5d03efb..8b19f437308e 100644 > --- a/drivers/gpu/drm/sysfb/efidrm.c > +++ b/drivers/gpu/drm/sysfb/efidrm.c > @@ -152,6 +152,7 @@ static struct efidrm_device *efidrm_device_create(struct drm_driver *drv, > const struct screen_info *si; > const struct drm_format_info *format; > int width, height, stride; > + unsigned int panel_width, panel_height; > s64 vsize; > u64 mem_flags; > struct resource resbuf; > @@ -217,6 +218,20 @@ static struct efidrm_device *efidrm_device_create(struct drm_driver *drv, > if (drm_edid_header_is_valid(dpy->edid.dummy) == 8) > sysfb->edid = dpy->edid.dummy; > #endif > + > + panel_width = width; > + panel_height = height; > + > + if (sysfb->edid) { > + const struct drm_edid *drm_edid; > + > + drm_edid = drm_edid_alloc(sysfb->edid, EDID_LENGTH); > + if (drm_edid) { > + drm_edid_detect_panel_size(drm_edid, &panel_width, &panel_height); > + drm_edid_free(drm_edid); > + } > + } > + > sysfb->fb_mode = drm_sysfb_mode(width, height, 0, 0); > sysfb->fb_format = format; > sysfb->fb_pitch = stride; > @@ -340,7 +355,7 @@ static struct efidrm_device *efidrm_device_create(struct drm_driver *drv, > drm_connector_helper_add(connector, &efidrm_connector_helper_funcs); > drm_connector_set_panel_orientation_with_quirk(connector, > DRM_MODE_PANEL_ORIENTATION_UNKNOWN, > - width, height); > + panel_width, panel_height); > if (sysfb->edid) > drm_connector_attach_edid_property(connector); > > diff --git a/drivers/gpu/drm/sysfb/ofdrm.c b/drivers/gpu/drm/sysfb/ofdrm.c > index 9d60db45139c..c41255569854 100644 > --- a/drivers/gpu/drm/sysfb/ofdrm.c > +++ b/drivers/gpu/drm/sysfb/ofdrm.c > @@ -229,7 +229,7 @@ static const u8 *display_get_edid_of(struct drm_device *dev, struct device_node > { > int ret = of_property_read_u8_array(of_node, "EDID", buf, EDID_LENGTH); > > - if (ret) > + if (ret || drm_edid_header_is_valid(buf) != 8) > return NULL; > return buf; > } > @@ -828,6 +828,7 @@ static struct ofdrm_device *ofdrm_device_create(struct drm_driver *drv, > enum ofdrm_model model; > bool big_endian; > int width, height, depth, linebytes; > + unsigned int panel_width, panel_height; > const struct drm_format_info *format; > u64 address; > const u8 *edid; > @@ -998,6 +999,19 @@ static struct ofdrm_device *ofdrm_device_create(struct drm_driver *drv, > sysfb->fb_gamma_lut_size = OFDRM_GAMMA_LUT_SIZE; > sysfb->edid = edid; > > + panel_width = width; > + panel_height = height; > + > + if (sysfb->edid) { > + const struct drm_edid *drm_edid; > + > + drm_edid = drm_edid_alloc(sysfb->edid, EDID_LENGTH); > + if (drm_edid) { > + drm_edid_detect_panel_size(drm_edid, &panel_width, &panel_height); > + drm_edid_free(drm_edid); > + } > + } > + > drm_dbg(dev, "display mode={" DRM_MODE_FMT "}\n", DRM_MODE_ARG(&sysfb->fb_mode)); > drm_dbg(dev, "framebuffer format=%p4cc, size=%dx%d, linebytes=%d byte\n", > &format->format, width, height, linebytes); > @@ -1069,7 +1083,7 @@ static struct ofdrm_device *ofdrm_device_create(struct drm_driver *drv, > drm_connector_helper_add(connector, &ofdrm_connector_helper_funcs); > drm_connector_set_panel_orientation_with_quirk(connector, > DRM_MODE_PANEL_ORIENTATION_UNKNOWN, > - width, height); > + panel_width, panel_height); > if (edid) > drm_connector_attach_edid_property(connector); > > diff --git a/drivers/gpu/drm/sysfb/vesadrm.c b/drivers/gpu/drm/sysfb/vesadrm.c > index 6a67b2d2e451..f6358a0a68bd 100644 > --- a/drivers/gpu/drm/sysfb/vesadrm.c > +++ b/drivers/gpu/drm/sysfb/vesadrm.c > @@ -402,6 +402,7 @@ static struct vesadrm_device *vesadrm_device_create(struct drm_driver *drv, > const struct screen_info *si; > const struct drm_format_info *format; > int width, height, stride; > + unsigned int panel_width, panel_height; > s64 vsize; > struct resource resbuf; > struct resource *res; > @@ -484,6 +485,20 @@ static struct vesadrm_device *vesadrm_device_create(struct drm_driver *drv, > if (drm_edid_header_is_valid(dpy->edid.dummy) == 8) > sysfb->edid = dpy->edid.dummy; > #endif > + > + panel_width = width; > + panel_height = height; > + > + if (sysfb->edid) { > + const struct drm_edid *drm_edid; > + > + drm_edid = drm_edid_alloc(sysfb->edid, EDID_LENGTH); > + if (drm_edid) { > + drm_edid_detect_panel_size(drm_edid, &panel_width, &panel_height); > + drm_edid_free(drm_edid); > + } > + } > + > sysfb->fb_mode = drm_sysfb_mode(width, height, 0, 0); > sysfb->fb_format = format; > sysfb->fb_pitch = stride; > @@ -585,7 +600,7 @@ static struct vesadrm_device *vesadrm_device_create(struct drm_driver *drv, > drm_connector_helper_add(connector, &vesadrm_connector_helper_funcs); > drm_connector_set_panel_orientation_with_quirk(connector, > DRM_MODE_PANEL_ORIENTATION_UNKNOWN, > - width, height); > + panel_width, panel_height); > if (sysfb->edid) > drm_connector_attach_edid_property(connector); -- Jani Nikula, Intel ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-09-04 9:41 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-04 9:06 [PATCH v4 0/3] sysfb: Fix display output on Lenovo D330 (and others) Thomas Zimmermann 2026-09-04 9:07 ` [PATCH v4 1/3] firmware/sysfb: Remove rotation quirk for Lenovo D330 Thomas Zimmermann 2026-09-04 9:07 ` [PATCH v4 2/3] drm/edid: Add drm_edid_detect_panel_size() Thomas Zimmermann 2026-09-04 9:28 ` Jani Nikula 2026-09-04 9:07 ` [PATCH v4 3/3] drm/sysfb: Use preferred panel size for panel orientation quirks Thomas Zimmermann 2026-09-04 9:41 ` Jani Nikula
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox