Thomas Zimmermann <[email protected]> writes:

> 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]>
> ---
>  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 */
> +

I saw that Jani and you discussed this logic in v3. I originally thought that
your v3 was correct and this one was wrong, but I noticed now that this flag
changed its semantic between 1.3 and 1.4.

So I think that this latest version is correct indeed, 1.3 didn't include the
native pixel format and 1.4 does not either if DRM_EDID_FEATURE_PREFERRED_TIMING
flag is not set.

Reviewed-by: Javier Martinez Canillas <[email protected]>

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat

Reply via email to