From: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
To: "Borah, Chaitanya Kumar" <chaitanya.kumar.borah@intel.com>,
"Leo Li" <sunpeng.li@amd.com>,
"Daniel Stone" <daniels@collabora.com>,
"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
"Maxime Ripard" <mripard@kernel.org>,
"Thomas Zimmermann" <tzimmermann@suse.de>,
"David Airlie" <airlied@gmail.com>,
"Simona Vetter" <simona@ffwll.ch>, "Helge Deller" <deller@gmx.de>,
"Andrzej Hajda" <andrzej.hajda@intel.com>,
"Neil Armstrong" <neil.armstrong@linaro.org>,
"Robert Foss" <rfoss@kernel.org>,
"Laurent Pinchart" <Laurent.pinchart@ideasonboard.com>,
"Jonas Karlman" <jonas@kwiboo.se>,
"Jernej Skrabec" <jernej.skrabec@gmail.com>,
"Luca Ceresoli" <luca.ceresoli@bootlin.com>,
"Sandy Huang" <hjc@rock-chips.com>,
"Heiko Stübner" <heiko@sntech.de>,
"Andy Yan" <andy.yan@rock-chips.com>
Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
linux-fbdev@vger.kernel.org, linux-rockchip@lists.infradead.org,
linux-arm-kernel@lists.infradead.org, kernel@collabora.com,
Derek Foreman <derek.foreman@collabora.com>,
wayland-devel@lists.freedesktop.org,
Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Subject: [PATCH RFC 04/25] video/hdmi: Add VTEM EMP packing
Date: Mon, 21 Sep 2026 17:51:30 +0200 [thread overview]
Message-ID: <20260921-vrr-limiter-uapi-v1-4-2fcd7d011646@collabora.com> (raw)
In-Reply-To: <20260921-vrr-limiter-uapi-v1-0-2fcd7d011646@collabora.com>
From: Derek Foreman <derek.foreman@collabora.com>
VTEM EMPs are a type of infoframe that is required for Variable Refresh
Rate. Add code to pack them.
Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/video/hdmi.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++-
include/linux/hdmi.h | 19 ++++++++++
2 files changed, 115 insertions(+), 1 deletion(-)
diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
index 45b42f14a750..ed9abc7ad228 100644
--- a/drivers/video/hdmi.c
+++ b/drivers/video/hdmi.c
@@ -983,6 +983,10 @@ hdmi_infoframe_pack(union hdmi_infoframe *frame,
length = hdmi_vendor_any_infoframe_pack(&frame->vendor,
buffer, size);
break;
+ case HDMI_INFOFRAME_TYPE_EMP:
+ length = hdmi_emp_infoframe_vtem_pack(&frame->vtem,
+ buffer, size);
+ break;
default:
WARN(1, "Bad infoframe type %d\n", frame->any.type);
length = -EINVAL;
@@ -994,9 +998,11 @@ EXPORT_SYMBOL(hdmi_infoframe_pack);
static const char *hdmi_infoframe_type_get_name(enum hdmi_infoframe_type type)
{
- if (type < 0x80 || type > 0x9f)
+ if (type < 0x7F || type > 0x9f)
return "Invalid";
switch (type) {
+ case HDMI_INFOFRAME_TYPE_EMP:
+ return "EMP";
case HDMI_INFOFRAME_TYPE_VENDOR:
return "Vendor";
case HDMI_INFOFRAME_TYPE_AVI:
@@ -1516,6 +1522,29 @@ hdmi_vendor_any_infoframe_log(const char *level,
}
}
+static void
+hdmi_emp_infoframe_vtem_log(const char *level,
+ struct device *dev,
+ const struct hdmi_emp_infoframe_vtem *frame)
+{
+ hdmi_infoframe_log_header(level, dev,
+ (const struct hdmi_any_infoframe *)frame);
+
+ hdmi_log(" game vrr enabled: %u\n", frame->game_vrr_en);
+ hdmi_log(" fva factor minus 1: %u\n", frame->fva_factor_m1);
+ hdmi_log(" m_const: %u\n", frame->m_const);
+ hdmi_log(" base vertical front porch: %u\n", frame->base_vfront);
+ hdmi_log(" base refresh rate: %u\n", frame->base_refresh_rate);
+}
+
+static void
+hdmi_emp_infoframe_log(const char *level,
+ struct device *dev,
+ const union hdmi_infoframe *frame)
+{
+ /* Only support VTEM for now */
+ hdmi_emp_infoframe_vtem_log(level, dev, &frame->vtem);
+}
/**
* hdmi_infoframe_log() - log info of HDMI infoframe
* @level: logging level
@@ -1542,6 +1571,9 @@ void hdmi_infoframe_log(const char *level,
case HDMI_INFOFRAME_TYPE_DRM:
hdmi_drm_infoframe_log(level, dev, &frame->drm);
break;
+ case HDMI_INFOFRAME_TYPE_EMP:
+ hdmi_emp_infoframe_log(level, dev, frame);
+ break;
}
}
EXPORT_SYMBOL(hdmi_infoframe_log);
@@ -1919,3 +1951,66 @@ int hdmi_infoframe_unpack(union hdmi_infoframe *frame,
return ret;
}
EXPORT_SYMBOL(hdmi_infoframe_unpack);
+
+/**
+ * hdmi_emp_infoframe_vtem_init() - initialize an HDMI VTEM EMP
+ * @emp: HDMI VTEM EMP
+ */
+void hdmi_emp_infoframe_vtem_init(struct hdmi_emp_infoframe_vtem *emp)
+{
+ memset(emp, 0, sizeof(*emp));
+ emp->type = HDMI_INFOFRAME_TYPE_EMP;
+}
+EXPORT_SYMBOL(hdmi_emp_infoframe_vtem_init);
+
+/**
+ * hdmi_emp_infoframe_vtem_pack() - pack a vtem into a binary buffer
+ * @vtem: pointer to &struct hdmi_emp_infoframe_vtem to pack
+ * @buffer: pointer to pre-allocated output buffer
+ * @size: maximum size in bytes of @buffer
+ *
+ * Pack a VTEM infoframe struct into a binary buffer in a way that's suitable
+ * to be sent out over the wire.
+ *
+ * Returns the number of bytes packed into the binary buffer or a negative
+ * error code on failure.
+ */
+ssize_t hdmi_emp_infoframe_vtem_pack(struct hdmi_emp_infoframe_vtem *vtem,
+ void *buffer, size_t size)
+{
+ u8 *ptr = buffer;
+
+ if (size < HDMI_INFOFRAME_SIZE(VTEM))
+ return -EINVAL;
+
+ /* 4 bits max */
+ if (vtem->fva_factor_m1 > 0xF)
+ return -EINVAL;
+
+ memset(buffer, 0, size);
+
+ /* Header Data */
+ ptr[0] = vtem->type;
+ ptr[1] = BIT(7) | BIT(6);
+ ptr[2] = 0;
+
+ ptr[3] = BIT(7) | BIT(2);
+
+ ptr[4] = 0;
+ ptr[5] = 1;
+ ptr[6] = 0;
+ ptr[7] = 1;
+ ptr[8] = 0;
+ ptr[9] = 4;
+
+ /* This is where the VTEM part starts */
+ ptr[10] = (vtem->fva_factor_m1 << 4) |
+ (vtem->m_const ? BIT(1) : 0) |
+ (vtem->game_vrr_en ? BIT(0) : 0);
+ ptr[11] = vtem->base_vfront;
+ ptr[12] = vtem->base_refresh_rate >> 8 & 0x3;
+ ptr[13] = vtem->base_refresh_rate & 0xFF;
+
+ return 14;
+}
+EXPORT_SYMBOL(hdmi_emp_infoframe_vtem_pack);
diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
index b80a5ee63bb2..71e2b36896af 100644
--- a/include/linux/hdmi.h
+++ b/include/linux/hdmi.h
@@ -55,6 +55,7 @@ enum hdmi_packet_type {
};
enum hdmi_infoframe_type {
+ HDMI_INFOFRAME_TYPE_EMP = 0x7F,
HDMI_INFOFRAME_TYPE_VENDOR = 0x81,
HDMI_INFOFRAME_TYPE_AVI = 0x82,
HDMI_INFOFRAME_TYPE_SPD = 0x83,
@@ -76,6 +77,7 @@ enum hdmi_infoframe_type {
#define HDMI_AUDIO_INFOFRAME_SIZE 10
#define HDMI_DRM_INFOFRAME_SIZE 26
#define HDMI_VENDOR_INFOFRAME_SIZE 4
+#define HDMI_VTEM_INFOFRAME_SIZE 10
/*
* HDMI 1.3a table 5-14 states that the largest InfoFrame_length is 27,
@@ -235,6 +237,18 @@ struct hdmi_drm_infoframe {
u16 max_fall;
};
+struct hdmi_emp_infoframe_vtem {
+ enum hdmi_infoframe_type type;
+ unsigned char version;
+ unsigned char length;
+
+ bool game_vrr_en;
+ bool m_const;
+ unsigned char fva_factor_m1;
+ unsigned char base_vfront;
+ u16 base_refresh_rate;
+};
+
void hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame);
ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
size_t size);
@@ -249,6 +263,10 @@ ssize_t hdmi_drm_infoframe_pack_only(const struct hdmi_drm_infoframe *frame,
int hdmi_drm_infoframe_check(struct hdmi_drm_infoframe *frame);
int hdmi_drm_infoframe_unpack_only(struct hdmi_drm_infoframe *frame,
const void *buffer, size_t size);
+void hdmi_emp_infoframe_vtem_init(struct hdmi_emp_infoframe_vtem *frame);
+ssize_t hdmi_emp_infoframe_vtem_pack(struct hdmi_emp_infoframe_vtem *frame,
+ void *buffer,
+ size_t size);
enum hdmi_spd_sdi {
HDMI_SPD_SDI_UNKNOWN,
@@ -457,6 +475,7 @@ union hdmi_infoframe {
union hdmi_vendor_any_infoframe vendor;
struct hdmi_audio_infoframe audio;
struct hdmi_drm_infoframe drm;
+ struct hdmi_emp_infoframe_vtem vtem;
};
ssize_t hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer,
--
2.55.0
next prev parent reply other threads:[~2026-09-21 15:53 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-21 15:51 [PATCH RFC 00/25] VRR Target Rate Limiter KMS uAPI and Implementation Nicolas Frattaroli
2026-09-21 15:51 ` [PATCH RFC 01/25] drm/edid: Add a query for vrr range Nicolas Frattaroli
2026-09-21 15:51 ` [PATCH RFC 02/25] drm: Add VRR state Nicolas Frattaroli
2026-09-21 15:51 ` [PATCH RFC 03/25] drm/atomic-helper: Set mode_changed on vrr_enabled change Nicolas Frattaroli
2026-09-21 21:59 ` Leo Li
2026-09-21 22:01 ` Leo Li
2026-09-21 15:51 ` Nicolas Frattaroli [this message]
2026-09-21 15:51 ` [PATCH RFC 05/25] drm/bridge: Add VTEM EMP support Nicolas Frattaroli
2026-09-21 15:51 ` [PATCH RFC 06/25] drm/connector: hdmi: Add VTEM EMP generation Nicolas Frattaroli
2026-09-21 15:51 ` [PATCH RFC 07/25] drm/crtc-helper: Add VRR helper functions Nicolas Frattaroli
2026-09-21 15:51 ` [PATCH RFC 08/25] drm/bridge: synopsys: Add VTEM EMP support Nicolas Frattaroli
2026-09-21 15:51 ` [PATCH RFC 09/25] drm/connector: Add drm_display_info_is_vrr_capable Nicolas Frattaroli
2026-09-21 15:51 ` [PATCH RFC 10/25] drm/rockchip: dw_hdmi_qp: Add VRR support Nicolas Frattaroli
2026-09-21 15:51 ` [PATCH RFC 11/25] drm/rockchip: vop2: Enable VRR Nicolas Frattaroli
2026-09-21 15:51 ` [PATCH RFC 12/25] drm/edid: Parse CinemaVRR flag from HDMI SCDS Nicolas Frattaroli
2026-09-21 15:51 ` [PATCH RFC 13/25] drm: Add VRR target frame rate properties Nicolas Frattaroli
2026-09-21 22:23 ` Leo Li
2026-09-21 15:51 ` [PATCH RFC 14/25] drm: Implement VRR rate limiting Nicolas Frattaroli
2026-09-21 15:51 ` [PATCH RFC 15/25] drm/edid: Parse QMS flag from HDMI SCDS Nicolas Frattaroli
2026-09-21 15:51 ` [PATCH RFC 16/25] drm/edid: Parse QMS TFR min/max flags " Nicolas Frattaroli
2026-09-21 15:51 ` [PATCH RFC 17/25] drm/connector: Add "qms_enabled" drm property Nicolas Frattaroli
2026-09-21 15:51 ` [PATCH RFC 18/25] video/hdmi: Add support for QMS in VTEM EMP packing Nicolas Frattaroli
2026-09-21 15:51 ` [PATCH RFC 19/25] drm/connector: hdmi: Add QMS to VTEM EMP generation Nicolas Frattaroli
2026-09-21 15:51 ` [PATCH RFC 20/25] drm/connector: hdmi: Add QMS state validation and computation Nicolas Frattaroli
2026-09-21 15:51 ` [PATCH RFC 21/25] drm/rockchip: dw_hdmi_qp: Add QMS support Nicolas Frattaroli
2026-09-21 15:51 ` [PATCH RFC 22/25] drm/tests: hdmi: Add "Game Mode" VRR tests Nicolas Frattaroli
2026-09-21 15:51 ` [PATCH RFC 23/25] drm/tests: hdmi: Add Fixed/Constrained rate " Nicolas Frattaroli
2026-09-21 15:51 ` [PATCH RFC 24/25] drm/tests: hdmi: Add Quick Media Switching tests Nicolas Frattaroli
2026-09-21 15:51 ` [PATCH RFC 25/25] drm/atomic: Disable VRR in helper_set_config Nicolas Frattaroli
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260921-vrr-limiter-uapi-v1-4-2fcd7d011646@collabora.com \
--to=nicolas.frattaroli@collabora.com \
--cc=Laurent.pinchart@ideasonboard.com \
--cc=airlied@gmail.com \
--cc=andrzej.hajda@intel.com \
--cc=andy.yan@rock-chips.com \
--cc=chaitanya.kumar.borah@intel.com \
--cc=daniels@collabora.com \
--cc=deller@gmx.de \
--cc=derek.foreman@collabora.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=heiko@sntech.de \
--cc=hjc@rock-chips.com \
--cc=jernej.skrabec@gmail.com \
--cc=jonas@kwiboo.se \
--cc=kernel@collabora.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-fbdev@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rockchip@lists.infradead.org \
--cc=luca.ceresoli@bootlin.com \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mripard@kernel.org \
--cc=neil.armstrong@linaro.org \
--cc=rfoss@kernel.org \
--cc=simona@ffwll.ch \
--cc=sunpeng.li@amd.com \
--cc=tzimmermann@suse.de \
--cc=wayland-devel@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®