[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260119011146.62302-17-tomasz.pakula.oficjalny@gmail.com>
Date: Mon, 19 Jan 2026 02:11:45 +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 16/17] drm/amd/display: Reintroduce VTEM info frame
[Why]
VTEM info fram building was removed back in: commit a9f54ce3c603
("drm/amd/display: Refactoring VTEM"), but it's needed to support
HDMI VRR signalling.
[How]
Build completely new and more robust functions to build out the VTEM
infopacket. Many values are defined but could have added logic in the
future, that's shy they are not static values but already value + bit
position in it's byte.
Reduced blanking detection was previously missing. The standards for
RB and RBv2 use a fixed 160 or 80 lines for the horizontal blank period.
RB v3 can use either 160 or 80. Use this to detect if the current timing
mode uses reduced blankinig.
It doesn't hurt that the new functions look better and cleaner
Signed-off-by: Tomasz Pakuła <tomasz.pakula.oficjalny@...il.com>
---
.../amd/display/modules/inc/mod_info_packet.h | 4 +
.../display/modules/info_packet/info_packet.c | 173 ++++++++++++------
2 files changed, 116 insertions(+), 61 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h b/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h
index 67274ce129bd..7bca0541443c 100644
--- a/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h
+++ b/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h
@@ -49,6 +49,10 @@ 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);
+void mod_build_vtem_infopacket(const struct dc_stream_state *stream,
+ const struct mod_vrr_params *vrr,
+ struct dc_info_packet *infopacket);
+
enum adaptive_sync_type {
ADAPTIVE_SYNC_TYPE_NONE = 0,
ADAPTIVE_SYNC_TYPE_DP = 1,
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 0db2db7a197f..42a736a5509a 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
@@ -48,80 +48,59 @@ enum vsc_packet_revision {
vsc_packet_rev7 = 7,
};
+#define HDMI_INFOFRAME_TYPE_EMP 0x7F
#define HDMI_INFOFRAME_TYPE_VENDOR 0x81
#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
-#define VTEM_PB1 1
-#define VTEM_PB2 2
-#define VTEM_PB3 3
-#define VTEM_PB4 4
-#define VTEM_PB5 5
-#define VTEM_PB6 6
+#define VTEM_ORG_ID 1
+#define VTEM_DATA_SET_TAG 1
+#define VTEM_DATA_SET_LENGTH 4
-#define VTEM_MD0 7
-#define VTEM_MD1 8
-#define VTEM_MD2 9
-#define VTEM_MD3 10
+#define VTEM_M_CONST 0
+#define VTEM_FVA_FACTOR 0
+#define VTEM_BRR_MASK_UPPER 0x03
+#define VTEM_BRR_MASK_LOWER 0xFF
-// VTEM Byte Masks
-//PB0
-#define MASK_VTEM_PB0__RESERVED0 0x01
-#define MASK_VTEM_PB0__SYNC 0x02
-#define MASK_VTEM_PB0__VFR 0x04
-#define MASK_VTEM_PB0__AFR 0x08
-#define MASK_VTEM_PB0__DS_TYPE 0x30
- //0: Periodic pseudo-static EM Data Set
- //1: Periodic dynamic EM Data Set
- //2: Unique EM Data Set
- //3: Reserved
-#define MASK_VTEM_PB0__END 0x40
-#define MASK_VTEM_PB0__NEW 0x80
+/* VTEM Byte Offset */
+#define VTEM_PB0 0
+#define VTEM_PB1 1
+#define VTEM_PB2 2
+#define VTEM_PB3 3
+#define VTEM_PB4 4
+#define VTEM_PB5 5
+#define VTEM_PB6 6
-//PB1
-#define MASK_VTEM_PB1__RESERVED1 0xFF
+#define VTEM_MD0 7
+#define VTEM_MD1 8
+#define VTEM_MD2 9
+#define VTEM_MD3 10
-//PB2
-#define MASK_VTEM_PB2__ORGANIZATION_ID 0xFF
- //0: This is a Vendor Specific EM Data Set
- //1: This EM Data Set is defined by This Specification (HDMI 2.1 r102.clean)
- //2: This EM Data Set is defined by CTA-861-G
- //3: This EM Data Set is defined by VESA
-//PB3
-#define MASK_VTEM_PB3__DATA_SET_TAG_MSB 0xFF
-//PB4
-#define MASK_VTEM_PB4__DATA_SET_TAG_LSB 0xFF
-//PB5
-#define MASK_VTEM_PB5__DATA_SET_LENGTH_MSB 0xFF
-//PB6
-#define MASK_VTEM_PB6__DATA_SET_LENGTH_LSB 0xFF
+/* Extended Metadata Packet */
+/* Header */
+#define EMP_LAST_BIT 6
+#define EMP_FIRST_BIT 7
+/* PB0 */
+#define EMP_SNC_BIT 1
+#define EMP_VFR_BIT 2
+#define EMP_AFR_BIT 3
+#define EMP_DST_BIT 4
+#define EMP_END_BIT 6
+#define EMP_NEW_BIT 7
+/* PB7 = MD0 */
+#define VTEM_VRR_BIT 0
+#define VTEM_M_CONST_BIT 1
+#define VTEM_FVA_BIT 4
+/* MD1 Base_Vfront */
+/* MD2 */
+#define VTEM_BRR_UPPER_BIT 0
+#define VTEM_RB_BIT 2
+/* MD3 BRR Lower */
-
-//PB7-27 (20 bytes):
-//PB7 = MD0
-#define MASK_VTEM_MD0__VRR_EN 0x01
-#define MASK_VTEM_MD0__M_CONST 0x02
-#define MASK_VTEM_MD0__QMS_EN 0x04
-#define MASK_VTEM_MD0__RESERVED2 0x08
-#define MASK_VTEM_MD0__FVA_FACTOR_M1 0xF0
-
-//MD1
-#define MASK_VTEM_MD1__BASE_VFRONT 0xFF
-
-//MD2
-#define MASK_VTEM_MD2__BASE_REFRESH_RATE_98 0x03
-#define MASK_VTEM_MD2__RB 0x04
-#define MASK_VTEM_MD2__NEXT_TFR 0xF8
-
-//MD3
-#define MASK_VTEM_MD3__BASE_REFRESH_RATE_07 0xFF
-
enum ColorimetryRGBDP {
ColorimetryRGB_DP_sRGB = 0,
ColorimetryRGB_DP_AdobeRGB = 3,
@@ -611,6 +590,78 @@ void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream,
info_packet->valid = true;
}
+static void build_vtem_infopacket_header(struct dc_info_packet *infopacket)
+{
+ uint8_t pb0 = 0;
+
+ /* might need logic in the future */
+ pb0 |= 0 << EMP_SNC_BIT;
+ pb0 |= 1 << EMP_VFR_BIT;
+ pb0 |= 0 << EMP_AFR_BIT;
+ pb0 |= 0 << EMP_DST_BIT;
+ pb0 |= 0 << EMP_END_BIT;
+ pb0 |= 1 << EMP_NEW_BIT;
+
+ infopacket->hb0 = HDMI_INFOFRAME_TYPE_EMP;
+ infopacket->hb1 = (1 << EMP_FIRST_BIT) | (1 << EMP_LAST_BIT);
+ infopacket->hb2 = 0; // sequence
+
+ infopacket->sb[VTEM_PB0] = pb0;
+ infopacket->sb[VTEM_PB2] = VTEM_ORG_ID;
+ infopacket->sb[VTEM_PB4] = VTEM_DATA_SET_TAG;
+ infopacket->sb[VTEM_PB6] = VTEM_DATA_SET_LENGTH;
+}
+
+static void build_vtem_infopacket_data(const struct dc_stream_state *stream,
+ const struct mod_vrr_params *vrr,
+ struct dc_info_packet *infopacket)
+{
+ unsigned int brr = 0;
+ bool hdmi_vic_mode = false;
+ bool vrr_active = false;
+ bool rb = false;
+
+ hdmi_vic_mode = is_hdmi_vic_mode(stream);
+ vrr_active = vrr->state == VRR_STATE_ACTIVE_VARIABLE ||
+ vrr->state == VRR_STATE_ACTIVE_FIXED;
+
+ infopacket->sb[VTEM_MD0] = VTEM_M_CONST << VTEM_M_CONST_BIT;
+ infopacket->sb[VTEM_MD0] |= VTEM_FVA_FACTOR << VTEM_FVA_BIT;
+ infopacket->sb[VTEM_MD0] |= vrr_active << VTEM_VRR_BIT;
+
+ infopacket->sb[VTEM_MD1] = 0;
+ infopacket->sb[VTEM_MD2] = 0;
+ infopacket->sb[VTEM_MD3] = 0;
+
+ if (hdmi_vic_mode || !vrr_active)
+ return;
+ /*
+ * Reduced Blanking standard defines a fixed value of
+ * 160 for hblank, further reduced to 80 in RB2
+ */
+ rb = (stream->timing.h_total - stream->timing.h_addressable) <= 160;
+ brr = mod_freesync_calc_nominal_field_rate(stream) / 1000000;
+
+ if (brr > VTEM_BRR_MAX) {
+ infopacket->valid = false;
+ return;
+ }
+
+ infopacket->sb[VTEM_MD1] = (uint8_t) stream->timing.v_front_porch;
+ infopacket->sb[VTEM_MD2] = rb << VTEM_RB_BIT;
+ infopacket->sb[VTEM_MD2] |= (brr & VTEM_BRR_MASK_UPPER) >> 8;
+ infopacket->sb[VTEM_MD3] = brr & VTEM_BRR_MASK_LOWER;
+}
+
+void mod_build_vtem_infopacket(const struct dc_stream_state *stream,
+ const struct mod_vrr_params *vrr,
+ struct dc_info_packet *infopacket)
+{
+ infopacket->valid = true;
+ build_vtem_infopacket_header(infopacket);
+ build_vtem_infopacket_data(stream, vrr, infopacket);
+}
+
void mod_build_adaptive_sync_infopacket(const struct dc_stream_state *stream,
enum adaptive_sync_type asType,
const struct AS_Df_params *param,
--
2.52.0
Powered by blists - more mailing lists