On Mon, 07 Sep 2026, Pranay Samala <[email protected]> wrote:
> i915_display_info currently shows per-connector state but not HDR status,
> making HDR bringup hard to debug without correlating EDID, userspace,
> and driver state.
>
> Print the sink’s HDR capability from the EDID static metadata block,
> whether userspace has set the HDR_OUTPUT_METADATA property, and whether
> the driver is actually transmitting HDR metadata in the CRTC state. This
> distinguishes between a sink advertising HDR support, a property being
> set by userspace, and the actual HDR infoframe being sent on the wire.
>
> Assisted-by: GitHub_Copilot:claude-opus-5
> Signed-off-by: Pranay Samala <[email protected]>
> ---
> .../drm/i915/display/intel_display_debugfs.c | 82 +++++++++++++++++++
> 1 file changed, 82 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> index 3e302f23f247..a24c947c23de 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> @@ -243,6 +243,86 @@ static void intel_hdmi_info(struct seq_file *m,
> seq_printf(m, "\taudio support: %s\n", str_yes_no(has_audio));
> }
>
> +static const char *intel_hdr_eotf_name(enum hdmi_eotf eotf)
> +{
> + switch (eotf) {
> + case HDMI_EOTF_TRADITIONAL_GAMMA_SDR:
> + return "SDR";
> + case HDMI_EOTF_TRADITIONAL_GAMMA_HDR:
> + return "HDR-gamma";
> + case HDMI_EOTF_SMPTE_ST2084:
> + return "SMPTE_ST2084";
> + case HDMI_EOTF_BT_2100_HLG:
> + return "HLG";
> + default:
> + return "unknown";
> + }
> +}
Maybe add that to hdmi.[ch] instead of a local copy? There's nothing
Intel or i915 specific about this.
> +
> +static void intel_hdr_sink_info(struct seq_file *m,
> + struct drm_connector *connector)
> +{
If you did
struct drm_printer p = drm_seq_file_printer(m);
in the caller, and passed struct drm_printer *p here, you could use
drm_printf_indent() and avoid doing that \t stuff everywhere.
Side note, I've got a branch converting the entire file to drm_printer,
but never got around to sending it.
BR,
Jani.
> + const struct hdr_static_metadata *hdr =
> + &connector->display_info.hdr_sink_metadata.hdmi_type1;
> + int i;
> +
> + seq_printf(m, "\tHDR sink capable: %s\n",
> + str_yes_no(hdr->eotf & (BIT(HDMI_EOTF_SMPTE_ST2084) |
> + BIT(HDMI_EOTF_BT_2100_HLG))));
> + if (!hdr->eotf)
> + return;
> +
> + seq_puts(m, "\t\tsupported EOTF:");
> + for (i = HDMI_EOTF_TRADITIONAL_GAMMA_SDR; i <= HDMI_EOTF_BT_2100_HLG;
> i++)
> + if (hdr->eotf & BIT(i))
> + seq_printf(m, " %s", intel_hdr_eotf_name(i));
> + seq_puts(m, "\n");
> +
> + seq_printf(m, "\t\tstatic metadata type1: %s\n",
> + str_yes_no(hdr->metadata_type &
> BIT(HDMI_STATIC_METADATA_TYPE1)));
> + seq_printf(m, "\t\tmax_cll: %u, max_fall: %u, min_cll: %u (EDID
> coded)\n",
> + hdr->max_cll, hdr->max_fall, hdr->min_cll);
> +}
> +
> +static void intel_hdr_output_info(struct seq_file *m,
> + struct drm_connector *connector)
> +{
> + const struct drm_connector_state *conn_state = connector->state;
> + const struct intel_crtc_state *crtc_state;
> + const struct hdmi_drm_infoframe *frame;
> +
> + if (!conn_state || !conn_state->crtc)
> + return;
> +
> + crtc_state = to_intel_crtc_state(conn_state->crtc->state);
> +
> + seq_printf(m, "\tHDR output metadata blob: %s\n",
> + str_yes_no(conn_state->hdr_output_metadata));
> +
> + /* HDMI signals HDR via a DRM InfoFrame, DP via a gamut metadata SDP */
> + if (!(crtc_state->infoframes.enable &
> + (intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_DRM) |
> + intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_METADATA)))) {
> + seq_puts(m, "\tHDR output: off\n");
> + return;
> + }
> +
> + frame = &crtc_state->infoframes.drm.drm;
> +
> + seq_printf(m, "\tHDR output: on, EOTF: %s, metadata type: %d\n",
> + intel_hdr_eotf_name(frame->eotf), frame->metadata_type);
> + seq_printf(m, "\t\tprimaries: r(%u,%u) g(%u,%u) b(%u,%u) wp(%u,%u)\n",
> + frame->display_primaries[0].x, frame->display_primaries[0].y,
> + frame->display_primaries[1].x, frame->display_primaries[1].y,
> + frame->display_primaries[2].x, frame->display_primaries[2].y,
> + frame->white_point.x, frame->white_point.y);
> + seq_printf(m, "\t\tmastering luminance: max %u, min %u\n",
> + frame->max_display_mastering_luminance,
> + frame->min_display_mastering_luminance);
> + seq_printf(m, "\t\tmax_cll: %u, max_fall: %u\n",
> + frame->max_cll, frame->max_fall);
> +}
> +
> static void intel_connector_info(struct seq_file *m,
> struct drm_connector *connector)
> {
> @@ -264,6 +344,7 @@ static void intel_connector_info(struct seq_file *m,
> seq_printf(m, "\tsubpixel order: %s\n",
>
> drm_get_subpixel_order_name(connector->display_info.subpixel_order));
> seq_printf(m, "\tCEA rev: %d\n", connector->display_info.cea_rev);
> + intel_hdr_sink_info(m, connector);
>
> switch (connector->connector_type) {
> case DRM_MODE_CONNECTOR_DisplayPort:
> @@ -288,6 +369,7 @@ static void intel_connector_info(struct seq_file *m,
> intel_hdcp_info(m, intel_connector);
>
> seq_printf(m, "\tmax bpc: %u\n", connector->display_info.bpc);
> + intel_hdr_output_info(m, connector);
>
> intel_panel_info(m, intel_connector);
--
Jani Nikula, Intel