[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260119011146.62302-15-tomasz.pakula.oficjalny@gmail.com>
Date: Mon, 19 Jan 2026 02:11:43 +0100
From: Tomasz Pakuła <tomasz.pakula.oficjalny@...il.com>
To: alexander.deucher@....com,
harry.wentland@....com,
sunpeng.li@....com
Cc: maarten.lankhorst@...ux.intel.com,
mripard@...nel.org,
tzimmermann@...e.de,
airlied@...il.com,
simona@...ll.ch,
siqueira@...lia.com,
dri-devel@...ts.freedesktop.org,
amd-gfx@...ts.freedesktop.org,
linux-kernel@...r.kernel.org,
tomasz.pakula.oficjalny@...il.com,
bernhard.berger@...il.com
Subject: [PATCH 14/17] drm/amd/display: Restore ALLM support in HDMI vsif
[Why]
Support for triggering ALLM in modern TVs is missing.
When HDMI vsif was added in 2019:
commit 3c2381b92cba ("drm/amd/display: add support for VSIP info packet")
it was improperly handeled as HDMI actually has two separate vsifs. The
implementation was based on H14b-vsif and ALLM bit was messing it up
because H14b-vsif doesn't support ALLM. It was later removed in:
commit 75f77aafe281 ("drm/amd/display: Send H14b-VSIF specified in HDMI")
ALLM is supported by hf-vsif (HDMI Forum) instead.
[How]
Add proper logic to construct either h14b-vsif or hf-vsif based on
required capabilities. Currently, only ALLM from hf-vsif is supported.
Turns out, hf-vsif is almost identical to h14b-vsif, BUT has additional
two bytes of data after OUI. First byte is static and seems like
a version supported by leftover define. Second byte consists of 3D and
ALLM bits.
Implement logic to offset 3D data if building hf-vsif.
Signed-off-by: Tomasz Pakuła <tomasz.pakula.oficjalny@...il.com>
---
.../display/modules/info_packet/info_packet.c | 112 ++++++++++++------
1 file changed, 73 insertions(+), 39 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c
index 294f56d20062..1a1ddcdb4362 100644
--- a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c
+++ b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c
@@ -49,7 +49,10 @@ enum vsc_packet_revision {
};
#define HDMI_INFOFRAME_TYPE_VENDOR 0x81
-#define HF_VSIF_VERSION 1
+#define HDMI_INFOFRAME_LENGTH_MASK 0x1F
+#define HF_VSIF_VERSION 1
+#define HF_VSIF_3D_BIT 0
+#define HF_VSIF_ALLM_BIT 1
// VTEM Byte Offset
#define VTEM_PB0 0
@@ -496,9 +499,28 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream,
}
}
+static bool is_hdmi_vic_mode(const struct dc_stream_state *stream)
+{
+ bool allm = stream->link->local_sink->edid_caps.allm;
+ bool stereo = stream->view_format != VIEW_3D_FORMAT_NONE;
+
+ if (stream->timing.hdmi_vic == 0)
+ return false;
+
+ if (stream->timing.h_total < 3840 ||
+ stream->timing.v_total < 2160)
+ return false;
+
+ if (stereo || allm)
+ return false;
+
+ return true;
+}
+
/**
* mod_build_hf_vsif_infopacket - Prepare HDMI Vendor Specific info frame.
* Follows HDMI Spec to build up Vendor Specific info frame
+ * Conforms to h14b-vsif or hf-vsif based on the capabilities
*
* @stream: contains data we may need to construct VSIF (i.e. timing_3d_format, etc.)
* @info_packet: output structure where to store VSIF
@@ -506,63 +528,75 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream,
void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream,
struct dc_info_packet *info_packet)
{
- unsigned int length = 5;
bool hdmi_vic_mode = false;
+ bool allm = false;
+ bool stereo = false;
uint8_t checksum = 0;
- uint32_t i = 0;
+ uint8_t offset = 0;
+ uint8_t i = 0;
+ uint8_t length = 5;
+ uint32_t oui = HDMI_IEEE_OUI;
enum dc_timing_3d_format format;
info_packet->valid = false;
+
format = stream->timing.timing_3d_format;
if (stream->view_format == VIEW_3D_FORMAT_NONE)
format = TIMING_3D_FORMAT_NONE;
+ stereo = format != TIMING_3D_FORMAT_NONE;
+ hdmi_vic_mode = is_hdmi_vic_mode(stream);
- if (stream->timing.hdmi_vic != 0
- && stream->timing.h_total >= 3840
- && stream->timing.v_total >= 2160
- && format == TIMING_3D_FORMAT_NONE)
- hdmi_vic_mode = true;
-
- if ((format == TIMING_3D_FORMAT_NONE) && !hdmi_vic_mode)
+ if (!stereo && !hdmi_vic_mode && !allm)
return;
- info_packet->sb[1] = 0x03;
- info_packet->sb[2] = 0x0C;
- info_packet->sb[3] = 0x00;
+ if (allm)
+ oui = HDMI_FORUM_IEEE_OUI;
- if (format != TIMING_3D_FORMAT_NONE)
- info_packet->sb[4] = (2 << 5);
+ info_packet->sb[1] = oui & 0xff;
+ info_packet->sb[2] = (oui >> 8) & 0xff;
+ info_packet->sb[3] = (oui >> 16) & 0xff;
- else if (hdmi_vic_mode)
- info_packet->sb[4] = (1 << 5);
-
- switch (format) {
- case TIMING_3D_FORMAT_HW_FRAME_PACKING:
- case TIMING_3D_FORMAT_SW_FRAME_PACKING:
- info_packet->sb[5] = (0x0 << 4);
- break;
-
- case TIMING_3D_FORMAT_SIDE_BY_SIDE:
- case TIMING_3D_FORMAT_SBS_SW_PACKED:
- info_packet->sb[5] = (0x8 << 4);
- length = 6;
- break;
-
- case TIMING_3D_FORMAT_TOP_AND_BOTTOM:
- case TIMING_3D_FORMAT_TB_SW_PACKED:
- info_packet->sb[5] = (0x6 << 4);
- break;
-
- default:
- break;
+ if (oui == HDMI_FORUM_IEEE_OUI) {
+ offset = 2;
+ length += 2;
+ info_packet->sb[4] = HF_VSIF_VERSION;
+ info_packet->sb[5] = stereo << HF_VSIF_3D_BIT;
+ info_packet->sb[5] = allm << HF_VSIF_ALLM_BIT;
}
- if (hdmi_vic_mode)
+ if (stereo) {
+ info_packet->sb[4 + offset] = (2 << 5);
+
+ switch (format) {
+ case TIMING_3D_FORMAT_HW_FRAME_PACKING:
+ case TIMING_3D_FORMAT_SW_FRAME_PACKING:
+ info_packet->sb[5 + offset] = (0x0 << 4);
+ break;
+
+ case TIMING_3D_FORMAT_SIDE_BY_SIDE:
+ case TIMING_3D_FORMAT_SBS_SW_PACKED:
+ info_packet->sb[5 + offset] = (0x8 << 4);
+ ++length;
+ break;
+
+ case TIMING_3D_FORMAT_TOP_AND_BOTTOM:
+ case TIMING_3D_FORMAT_TB_SW_PACKED:
+ info_packet->sb[5 + offset] = (0x6 << 4);
+ break;
+
+ default:
+ break;
+ }
+
+ /* Doesn't need the offset as it can't be used with hf-vsif */
+ } else if (hdmi_vic_mode) {
+ info_packet->sb[4] = (1 << 5);
info_packet->sb[5] = stream->timing.hdmi_vic;
+ }
info_packet->hb0 = HDMI_INFOFRAME_TYPE_VENDOR;
info_packet->hb1 = 0x01;
- info_packet->hb2 = (uint8_t) (length);
+ info_packet->hb2 = length & HDMI_INFOFRAME_LENGTH_MASK;
checksum += info_packet->hb0;
checksum += info_packet->hb1;
--
2.52.0
Powered by blists - more mailing lists