On Fri, 04 Sep 2026, Thomas Zimmermann <[email protected]> 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 <[email protected]> > Acked-by: Ard Biesheuvel <[email protected]>
Acked-by: Jani Nikula <[email protected]> > --- > 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
