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

Given my shoddy comments before, not sure what it's worth, but,

Reviewed-by: Jani Nikula <[email protected]>

> ---
>  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

Reply via email to