mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/5] Provide HDMI VSI & SPD InfoFrames to DW HDMI QP TX
@ 2026-01-25  0:22 Cristian Ciocaltea
  2026-01-25  0:22 ` [PATCH 1/5] drm/bridge: dw-hdmi-qp: Provide HDMI Vendor Specific InfoFrame Cristian Ciocaltea
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Cristian Ciocaltea @ 2026-01-25  0:22 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter
  Cc: kernel, dri-devel, linux-kernel

This patch series provides the missing support for sending HDMI
Vendor-Specific Infoframes and Source Product Description InfoFrames in
dw-hdmi-qp library.

Additionally, it improves the existing AVI, DRM and Audio infoframes
handling by getting rid of some boilerplate and/or redundant code.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
Cristian Ciocaltea (5):
      drm/bridge: dw-hdmi-qp: Provide HDMI Vendor Specific InfoFrame
      drm/bridge: dw-hdmi-qp: Provide SPD InfoFrame
      drm/bridge: dw-hdmi-qp: Rework AVI InfoFrame handler
      drm/bridge: dw-hdmi-qp: Rework DRM InfoFrame handler
      drm/bridge: dw-hdmi-qp: Rework Audio InfoFrame handler

 drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 247 ++++++++++++++-------------
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h |   3 +
 2 files changed, 129 insertions(+), 121 deletions(-)
---
base-commit: 2cb217301e0df17f7107a1b0941b28d4053eae8b
change-id: 20260125-dw-hdmi-qp-iframe-9c581e69ffde


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/5] drm/bridge: dw-hdmi-qp: Provide HDMI Vendor Specific InfoFrame
  2026-01-25  0:22 [PATCH 0/5] Provide HDMI VSI & SPD InfoFrames to DW HDMI QP TX Cristian Ciocaltea
@ 2026-01-25  0:22 ` Cristian Ciocaltea
  2026-01-28 12:11   ` Daniel Stone
  2026-01-25  0:23 ` [PATCH 2/5] drm/bridge: dw-hdmi-qp: Provide SPD InfoFrame Cristian Ciocaltea
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 8+ messages in thread
From: Cristian Ciocaltea @ 2026-01-25  0:22 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter
  Cc: kernel, dri-devel, linux-kernel

Since commit b626b1a1c9cc ("drm/bridge: refactor HDMI InfoFrame
callbacks"), the following warning is generated:

  [   13.654149] rockchip-drm display-subsystem: [drm] HDMI VSI not supported

Add the missing support for sending HDMI Vendor-Specific Infoframes.

Additionally, introduce the dw_hdmi_qp_write_pkt() utility function, as
a prerequisite to rework the *_write_*_infoframe() callbacks and get rid
of some boilerplate code.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 32 +++++++++++++++++++++++++---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h |  2 ++
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
index 036316e2b60d..b37af6a7e194 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
@@ -11,6 +11,7 @@
 #include <linux/export.h>
 #include <linux/i2c.h>
 #include <linux/irq.h>
+#include <linux/minmax.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/of.h>
@@ -969,9 +970,9 @@ static int dw_hdmi_qp_bridge_clear_avi_infoframe(struct drm_bridge *bridge)
 
 static int dw_hdmi_qp_bridge_clear_hdmi_infoframe(struct drm_bridge *bridge)
 {
-	/* FIXME: add support for this InfoFrame */
+	struct dw_hdmi_qp *hdmi = bridge->driver_private;
 
-	drm_warn_once(bridge->encoder->dev, "HDMI VSI not supported\n");
+	dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_VSI_TX_EN, PKTSCHED_PKT_EN);
 
 	return 0;
 }
@@ -998,6 +999,18 @@ static int dw_hdmi_qp_bridge_clear_audio_infoframe(struct drm_bridge *bridge)
 	return 0;
 }
 
+static void dw_hdmi_qp_write_pkt(struct dw_hdmi_qp *hdmi, const u8 *buffer,
+				 size_t start, size_t len, unsigned int reg)
+{
+	u32 val = 0;
+	size_t i;
+
+	for (i = start; i < start + len; i++)
+		val |= buffer[i] << ((i % 4) * 8);
+
+	dw_hdmi_qp_write(hdmi, val, reg);
+}
+
 static int dw_hdmi_qp_bridge_write_avi_infoframe(struct drm_bridge *bridge,
 						 const u8 *buffer, size_t len)
 {
@@ -1011,9 +1024,22 @@ static int dw_hdmi_qp_bridge_write_avi_infoframe(struct drm_bridge *bridge,
 static int dw_hdmi_qp_bridge_write_hdmi_infoframe(struct drm_bridge *bridge,
 						  const u8 *buffer, size_t len)
 {
+	struct dw_hdmi_qp *hdmi = bridge->driver_private;
+	size_t i;
+
 	dw_hdmi_qp_bridge_clear_hdmi_infoframe(bridge);
 
-	/* FIXME: add support for the HDMI VSI */
+	/* VSI packet header */
+	dw_hdmi_qp_write_pkt(hdmi, buffer, 1, 2, PKT_VSI_CONTENTS0);
+
+	/* VSI packet body */
+	for (i = 0; i < len - 3; i += 4)
+		dw_hdmi_qp_write_pkt(hdmi, buffer + 3, i, min(len - i - 3, 4),
+				     PKT_VSI_CONTENTS1 + i);
+
+	dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_VSI_FIELDRATE, PKTSCHED_PKT_CONFIG1);
+	dw_hdmi_qp_mod(hdmi, PKTSCHED_VSI_TX_EN, PKTSCHED_VSI_TX_EN,
+		       PKTSCHED_PKT_EN);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h
index 91a15f82e32a..53688eae8dba 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h
@@ -198,6 +198,7 @@
 #define PKTSCHED_PRQUEUE2_CONFIG2			0xa94
 #define PKTSCHED_PKT_CONFIG0				0xa98
 #define PKTSCHED_PKT_CONFIG1				0xa9c
+#define PKTSCHED_VSI_FIELDRATE				BIT(14)
 #define PKTSCHED_DRMI_FIELDRATE				BIT(13)
 #define PKTSCHED_AVI_FIELDRATE				BIT(12)
 #define PKTSCHED_PKT_CONFIG2				0xaa0
@@ -206,6 +207,7 @@
 #define PKTSCHED_DRMI_TX_EN				BIT(17)
 #define PKTSCHED_AUDI_TX_EN				BIT(15)
 #define PKTSCHED_AVI_TX_EN				BIT(13)
+#define PKTSCHED_VSI_TX_EN				BIT(12)
 #define PKTSCHED_EMP_CVTEM_TX_EN			BIT(10)
 #define PKTSCHED_AMD_TX_EN				BIT(8)
 #define PKTSCHED_GCP_TX_EN				BIT(3)

-- 
2.52.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 2/5] drm/bridge: dw-hdmi-qp: Provide SPD InfoFrame
  2026-01-25  0:22 [PATCH 0/5] Provide HDMI VSI & SPD InfoFrames to DW HDMI QP TX Cristian Ciocaltea
  2026-01-25  0:22 ` [PATCH 1/5] drm/bridge: dw-hdmi-qp: Provide HDMI Vendor Specific InfoFrame Cristian Ciocaltea
@ 2026-01-25  0:23 ` Cristian Ciocaltea
  2026-01-25  0:23 ` [PATCH 3/5] drm/bridge: dw-hdmi-qp: Rework AVI InfoFrame handler Cristian Ciocaltea
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Cristian Ciocaltea @ 2026-01-25  0:23 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter
  Cc: kernel, dri-devel, linux-kernel

The hardware is capable of sending Source Product Description (SPD)
InfoFrames, hence enable the missing support.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 36 +++++++++++++++++++++++++++-
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h |  1 +
 2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
index b37af6a7e194..429736486d85 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
@@ -986,6 +986,15 @@ static int dw_hdmi_qp_bridge_clear_hdr_drm_infoframe(struct drm_bridge *bridge)
 	return 0;
 }
 
+static int dw_hdmi_qp_bridge_clear_spd_infoframe(struct drm_bridge *bridge)
+{
+	struct dw_hdmi_qp *hdmi = bridge->driver_private;
+
+	dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_SPDI_TX_EN, PKTSCHED_PKT_EN);
+
+	return 0;
+}
+
 static int dw_hdmi_qp_bridge_clear_audio_infoframe(struct drm_bridge *bridge)
 {
 	struct dw_hdmi_qp *hdmi = bridge->driver_private;
@@ -1054,6 +1063,28 @@ static int dw_hdmi_qp_bridge_write_hdr_drm_infoframe(struct drm_bridge *bridge,
 	return dw_hdmi_qp_config_drm_infoframe(hdmi, buffer, len);
 }
 
+static int dw_hdmi_qp_bridge_write_spd_infoframe(struct drm_bridge *bridge,
+						 const u8 *buffer, size_t len)
+{
+	struct dw_hdmi_qp *hdmi = bridge->driver_private;
+	size_t i;
+
+	dw_hdmi_qp_bridge_clear_spd_infoframe(bridge);
+
+	/* SPD packet header */
+	dw_hdmi_qp_write_pkt(hdmi, buffer, 1, 2, PKT_SPDI_CONTENTS0);
+
+	/* SPD packet body */
+	for (i = 0; i < len - 3; i += 4)
+		dw_hdmi_qp_write_pkt(hdmi, buffer + 3, i, min(len - i - 3, 4),
+				     PKT_SPDI_CONTENTS1 + i);
+
+	dw_hdmi_qp_mod(hdmi, PKTSCHED_SPDI_TX_EN, PKTSCHED_SPDI_TX_EN,
+		       PKTSCHED_PKT_EN);
+
+	return 0;
+}
+
 static int dw_hdmi_qp_bridge_write_audio_infoframe(struct drm_bridge *bridge,
 						   const u8 *buffer, size_t len)
 {
@@ -1252,6 +1283,8 @@ static const struct drm_bridge_funcs dw_hdmi_qp_bridge_funcs = {
 	.hdmi_write_hdmi_infoframe = dw_hdmi_qp_bridge_write_hdmi_infoframe,
 	.hdmi_clear_hdr_drm_infoframe = dw_hdmi_qp_bridge_clear_hdr_drm_infoframe,
 	.hdmi_write_hdr_drm_infoframe = dw_hdmi_qp_bridge_write_hdr_drm_infoframe,
+	.hdmi_clear_spd_infoframe = dw_hdmi_qp_bridge_clear_spd_infoframe,
+	.hdmi_write_spd_infoframe = dw_hdmi_qp_bridge_write_spd_infoframe,
 	.hdmi_clear_audio_infoframe = dw_hdmi_qp_bridge_clear_audio_infoframe,
 	.hdmi_write_audio_infoframe = dw_hdmi_qp_bridge_write_audio_infoframe,
 	.hdmi_audio_startup = dw_hdmi_qp_audio_enable,
@@ -1368,7 +1401,8 @@ struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
 			   DRM_BRIDGE_OP_EDID |
 			   DRM_BRIDGE_OP_HDMI |
 			   DRM_BRIDGE_OP_HDMI_AUDIO |
-			   DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME;
+			   DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME |
+			   DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME;
 	if (!hdmi->no_hpd)
 		hdmi->bridge.ops |= DRM_BRIDGE_OP_HPD;
 	hdmi->bridge.of_node = pdev->dev.of_node;
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h
index 53688eae8dba..c07847e8d7dd 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.h
@@ -206,6 +206,7 @@
 #define PKTSCHED_PKT_EN					0xaa8
 #define PKTSCHED_DRMI_TX_EN				BIT(17)
 #define PKTSCHED_AUDI_TX_EN				BIT(15)
+#define PKTSCHED_SPDI_TX_EN				BIT(14)
 #define PKTSCHED_AVI_TX_EN				BIT(13)
 #define PKTSCHED_VSI_TX_EN				BIT(12)
 #define PKTSCHED_EMP_CVTEM_TX_EN			BIT(10)

-- 
2.52.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 3/5] drm/bridge: dw-hdmi-qp: Rework AVI InfoFrame handler
  2026-01-25  0:22 [PATCH 0/5] Provide HDMI VSI & SPD InfoFrames to DW HDMI QP TX Cristian Ciocaltea
  2026-01-25  0:22 ` [PATCH 1/5] drm/bridge: dw-hdmi-qp: Provide HDMI Vendor Specific InfoFrame Cristian Ciocaltea
  2026-01-25  0:23 ` [PATCH 2/5] drm/bridge: dw-hdmi-qp: Provide SPD InfoFrame Cristian Ciocaltea
@ 2026-01-25  0:23 ` Cristian Ciocaltea
  2026-01-25  0:23 ` [PATCH 4/5] drm/bridge: dw-hdmi-qp: Rework DRM " Cristian Ciocaltea
  2026-01-25  0:23 ` [PATCH 5/5] drm/bridge: dw-hdmi-qp: Rework Audio " Cristian Ciocaltea
  4 siblings, 0 replies; 8+ messages in thread
From: Cristian Ciocaltea @ 2026-01-25  0:23 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter
  Cc: kernel, dri-devel, linux-kernel

Make use of the recently introduced dw_hdmi_qp_write_pkt() helper to
simplify the writing of the Auxiliary Video InfoFrame (AVI) packet
header and body registers.

Moreover, since now having dedicated callbacks per InfoFrame type, move
the implementation to dw_hdmi_qp_bridge_write_avi_infoframe() and drop
dw_hdmi_qp_config_avi_infoframe().

While at it, also discard the superfluous infoframe size verification.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 52 ++++++++--------------------
 1 file changed, 14 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
index 429736486d85..ff856f8bd53b 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
@@ -748,43 +748,6 @@ static struct i2c_adapter *dw_hdmi_qp_i2c_adapter(struct dw_hdmi_qp *hdmi)
 	return adap;
 }
 
-static int dw_hdmi_qp_config_avi_infoframe(struct dw_hdmi_qp *hdmi,
-					   const u8 *buffer, size_t len)
-{
-	u32 val, i, j;
-
-	if (len != HDMI_INFOFRAME_SIZE(AVI)) {
-		dev_err(hdmi->dev, "failed to configure avi infoframe\n");
-		return -EINVAL;
-	}
-
-	/*
-	 * DW HDMI QP IP uses a different byte format from standard AVI info
-	 * frames, though generally the bits are in the correct bytes.
-	 */
-	val = buffer[1] << 8 | buffer[2] << 16;
-	dw_hdmi_qp_write(hdmi, val, PKT_AVI_CONTENTS0);
-
-	for (i = 0; i < 4; i++) {
-		for (j = 0; j < 4; j++) {
-			if (i * 4 + j >= 14)
-				break;
-			if (!j)
-				val = buffer[i * 4 + j + 3];
-			val |= buffer[i * 4 + j + 3] << (8 * j);
-		}
-
-		dw_hdmi_qp_write(hdmi, val, PKT_AVI_CONTENTS1 + i * 4);
-	}
-
-	dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_AVI_FIELDRATE, PKTSCHED_PKT_CONFIG1);
-
-	dw_hdmi_qp_mod(hdmi, PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN,
-		       PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN, PKTSCHED_PKT_EN);
-
-	return 0;
-}
-
 static int dw_hdmi_qp_config_drm_infoframe(struct dw_hdmi_qp *hdmi,
 					   const u8 *buffer, size_t len)
 {
@@ -1024,10 +987,23 @@ static int dw_hdmi_qp_bridge_write_avi_infoframe(struct drm_bridge *bridge,
 						 const u8 *buffer, size_t len)
 {
 	struct dw_hdmi_qp *hdmi = bridge->driver_private;
+	size_t i;
 
 	dw_hdmi_qp_bridge_clear_avi_infoframe(bridge);
 
-	return dw_hdmi_qp_config_avi_infoframe(hdmi, buffer, len);
+	/* AVI packet header */
+	dw_hdmi_qp_write_pkt(hdmi, buffer, 1, 2, PKT_AVI_CONTENTS0);
+
+	/* AVI packet body */
+	for (i = 0; i < len - 3; i += 4)
+		dw_hdmi_qp_write_pkt(hdmi, buffer + 3, i, min(len - i - 3, 4),
+				     PKT_AVI_CONTENTS1 + i);
+
+	dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_AVI_FIELDRATE, PKTSCHED_PKT_CONFIG1);
+	dw_hdmi_qp_mod(hdmi, PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN,
+		       PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN, PKTSCHED_PKT_EN);
+
+	return 0;
 }
 
 static int dw_hdmi_qp_bridge_write_hdmi_infoframe(struct drm_bridge *bridge,

-- 
2.52.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 4/5] drm/bridge: dw-hdmi-qp: Rework DRM InfoFrame handler
  2026-01-25  0:22 [PATCH 0/5] Provide HDMI VSI & SPD InfoFrames to DW HDMI QP TX Cristian Ciocaltea
                   ` (2 preceding siblings ...)
  2026-01-25  0:23 ` [PATCH 3/5] drm/bridge: dw-hdmi-qp: Rework AVI InfoFrame handler Cristian Ciocaltea
@ 2026-01-25  0:23 ` Cristian Ciocaltea
  2026-01-25  0:23 ` [PATCH 5/5] drm/bridge: dw-hdmi-qp: Rework Audio " Cristian Ciocaltea
  4 siblings, 0 replies; 8+ messages in thread
From: Cristian Ciocaltea @ 2026-01-25  0:23 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter
  Cc: kernel, dri-devel, linux-kernel

Make use of the recently introduced dw_hdmi_qp_write_pkt() helper to
simplify the writing of the Dynamic Range and Mastering (DRM) InfoFrame
packet header and body registers.

Moreover, since now having dedicated callbacks per InfoFrame type, move
the implementation to dw_hdmi_qp_bridge_write_hdr_drm_infoframe() and
drop dw_hdmi_qp_config_drm_infoframe().

While at it, also discard the unnecessary infoframe size verification,
as well as the redundant disabling of the packet transmission (already
done by the explicit call to the clear callback).

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 47 +++++++++-------------------
 1 file changed, 14 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
index ff856f8bd53b..178d95a8ecbb 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
@@ -748,38 +748,6 @@ static struct i2c_adapter *dw_hdmi_qp_i2c_adapter(struct dw_hdmi_qp *hdmi)
 	return adap;
 }
 
-static int dw_hdmi_qp_config_drm_infoframe(struct dw_hdmi_qp *hdmi,
-					   const u8 *buffer, size_t len)
-{
-	u32 val, i;
-
-	if (len != HDMI_INFOFRAME_SIZE(DRM)) {
-		dev_err(hdmi->dev, "failed to configure drm infoframe\n");
-		return -EINVAL;
-	}
-
-	dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_TX_EN, PKTSCHED_PKT_EN);
-
-	val = buffer[1] << 8 | buffer[2] << 16;
-	dw_hdmi_qp_write(hdmi, val, PKT_DRMI_CONTENTS0);
-
-	for (i = 0; i <= buffer[2]; i++) {
-		if (i % 4 == 0)
-			val = buffer[3 + i];
-		val |= buffer[3 + i] << ((i % 4) * 8);
-
-		if ((i % 4 == 3) || i == buffer[2])
-			dw_hdmi_qp_write(hdmi, val,
-					 PKT_DRMI_CONTENTS1 + ((i / 4) * 4));
-	}
-
-	dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_FIELDRATE, PKTSCHED_PKT_CONFIG1);
-	dw_hdmi_qp_mod(hdmi, PKTSCHED_DRMI_TX_EN, PKTSCHED_DRMI_TX_EN,
-		       PKTSCHED_PKT_EN);
-
-	return 0;
-}
-
 /*
  * Static values documented in the TRM
  * Different values are only used for debug purposes
@@ -1033,10 +1001,23 @@ static int dw_hdmi_qp_bridge_write_hdr_drm_infoframe(struct drm_bridge *bridge,
 						     const u8 *buffer, size_t len)
 {
 	struct dw_hdmi_qp *hdmi = bridge->driver_private;
+	size_t i;
 
 	dw_hdmi_qp_bridge_clear_hdr_drm_infoframe(bridge);
 
-	return dw_hdmi_qp_config_drm_infoframe(hdmi, buffer, len);
+	/* DRM packet header */
+	dw_hdmi_qp_write_pkt(hdmi, buffer, 1, 2, PKT_DRMI_CONTENTS0);
+
+	/* DRM packet body */
+	for (i = 0; i < len - 3; i += 4)
+		dw_hdmi_qp_write_pkt(hdmi, buffer + 3, i, min(len - i - 3, 4),
+				     PKT_DRMI_CONTENTS1 + i);
+
+	dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_FIELDRATE, PKTSCHED_PKT_CONFIG1);
+	dw_hdmi_qp_mod(hdmi, PKTSCHED_DRMI_TX_EN, PKTSCHED_DRMI_TX_EN,
+		       PKTSCHED_PKT_EN);
+
+	return 0;
 }
 
 static int dw_hdmi_qp_bridge_write_spd_infoframe(struct drm_bridge *bridge,

-- 
2.52.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 5/5] drm/bridge: dw-hdmi-qp: Rework Audio InfoFrame handler
  2026-01-25  0:22 [PATCH 0/5] Provide HDMI VSI & SPD InfoFrames to DW HDMI QP TX Cristian Ciocaltea
                   ` (3 preceding siblings ...)
  2026-01-25  0:23 ` [PATCH 4/5] drm/bridge: dw-hdmi-qp: Rework DRM " Cristian Ciocaltea
@ 2026-01-25  0:23 ` Cristian Ciocaltea
  4 siblings, 0 replies; 8+ messages in thread
From: Cristian Ciocaltea @ 2026-01-25  0:23 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter
  Cc: kernel, dri-devel, linux-kernel

Make use of the recently introduced dw_hdmi_qp_write_pkt() helper to
simplify the writing of the Audio InfoFrame packet header and body
registers.

Additionally, discard the redundant static values identifying the frame
version and length.

Moreover, since now having dedicated callbacks per InfoFrame type, move
the implementation to dw_hdmi_qp_bridge_write_audio_infoframe() and
drop dw_hdmi_qp_config_audio_infoframe().

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 80 ++++++++++++----------------
 1 file changed, 34 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
index 178d95a8ecbb..3e612f82c303 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
@@ -748,51 +748,6 @@ static struct i2c_adapter *dw_hdmi_qp_i2c_adapter(struct dw_hdmi_qp *hdmi)
 	return adap;
 }
 
-/*
- * Static values documented in the TRM
- * Different values are only used for debug purposes
- */
-#define DW_HDMI_QP_AUDIO_INFOFRAME_HB1	0x1
-#define DW_HDMI_QP_AUDIO_INFOFRAME_HB2	0xa
-
-static int dw_hdmi_qp_config_audio_infoframe(struct dw_hdmi_qp *hdmi,
-					     const u8 *buffer, size_t len)
-{
-	/*
-	 * AUDI_CONTENTS0: { RSV, HB2, HB1, RSV }
-	 * AUDI_CONTENTS1: { PB3, PB2, PB1, PB0 }
-	 * AUDI_CONTENTS2: { PB7, PB6, PB5, PB4 }
-	 *
-	 * PB0: CheckSum
-	 * PB1: | CT3    | CT2  | CT1  | CT0  | F13  | CC2 | CC1 | CC0 |
-	 * PB2: | F27    | F26  | F25  | SF2  | SF1  | SF0 | SS1 | SS0 |
-	 * PB3: | F37    | F36  | F35  | F34  | F33  | F32 | F31 | F30 |
-	 * PB4: | CA7    | CA6  | CA5  | CA4  | CA3  | CA2 | CA1 | CA0 |
-	 * PB5: | DM_INH | LSV3 | LSV2 | LSV1 | LSV0 | F52 | F51 | F50 |
-	 * PB6~PB10: Reserved
-	 *
-	 * AUDI_CONTENTS0 default value defined by HDMI specification,
-	 * and shall only be changed for debug purposes.
-	 */
-	u32 header_bytes = (DW_HDMI_QP_AUDIO_INFOFRAME_HB1 << 8) |
-			  (DW_HDMI_QP_AUDIO_INFOFRAME_HB2 << 16);
-
-	regmap_bulk_write(hdmi->regm, PKT_AUDI_CONTENTS0, &header_bytes, 1);
-	regmap_bulk_write(hdmi->regm, PKT_AUDI_CONTENTS1, &buffer[3], 1);
-	regmap_bulk_write(hdmi->regm, PKT_AUDI_CONTENTS2, &buffer[4], 1);
-
-	/* Enable ACR, AUDI, AMD */
-	dw_hdmi_qp_mod(hdmi,
-		       PKTSCHED_ACR_TX_EN | PKTSCHED_AUDI_TX_EN | PKTSCHED_AMD_TX_EN,
-		       PKTSCHED_ACR_TX_EN | PKTSCHED_AUDI_TX_EN | PKTSCHED_AMD_TX_EN,
-		       PKTSCHED_PKT_EN);
-
-	/* Enable AUDS */
-	dw_hdmi_qp_mod(hdmi, PKTSCHED_AUDS_TX_EN, PKTSCHED_AUDS_TX_EN, PKTSCHED_PKT_EN);
-
-	return 0;
-}
-
 static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge,
 					    struct drm_atomic_state *state)
 {
@@ -1046,10 +1001,43 @@ static int dw_hdmi_qp_bridge_write_audio_infoframe(struct drm_bridge *bridge,
 						   const u8 *buffer, size_t len)
 {
 	struct dw_hdmi_qp *hdmi = bridge->driver_private;
+	size_t i;
 
 	dw_hdmi_qp_bridge_clear_audio_infoframe(bridge);
 
-	return dw_hdmi_qp_config_audio_infoframe(hdmi, buffer, len);
+	/*
+	 * Audio packet header
+	 * AUDI_CONTENTS0: { RSV, HB2, HB1, RSV }
+	 */
+	dw_hdmi_qp_write_pkt(hdmi, buffer, 1, 2, PKT_AUDI_CONTENTS0);
+
+	/*
+	 * Audio packet body
+	 * AUDI_CONTENTS1: { PB3, PB2, PB1, PB0 }
+	 * AUDI_CONTENTS2: { PB7, PB6, PB5, PB4 }
+	 *
+	 * PB0: CheckSum
+	 * PB1: | CT3    | CT2  | CT1  | CT0  | F13  | CC2 | CC1 | CC0 |
+	 * PB2: | F27    | F26  | F25  | SF2  | SF1  | SF0 | SS1 | SS0 |
+	 * PB3: | F37    | F36  | F35  | F34  | F33  | F32 | F31 | F30 |
+	 * PB4: | CA7    | CA6  | CA5  | CA4  | CA3  | CA2 | CA1 | CA0 |
+	 * PB5: | DM_INH | LSV3 | LSV2 | LSV1 | LSV0 | F52 | F51 | F50 |
+	 * PB6~PB10: Reserved
+	 */
+	for (i = 0; i < len - 3; i += 4)
+		dw_hdmi_qp_write_pkt(hdmi, buffer + 3, i, min(len - i - 3, 4),
+				     PKT_AUDI_CONTENTS1 + i);
+
+	/* Enable ACR, AUDI, AMD */
+	dw_hdmi_qp_mod(hdmi,
+		       PKTSCHED_ACR_TX_EN | PKTSCHED_AUDI_TX_EN | PKTSCHED_AMD_TX_EN,
+		       PKTSCHED_ACR_TX_EN | PKTSCHED_AUDI_TX_EN | PKTSCHED_AMD_TX_EN,
+		       PKTSCHED_PKT_EN);
+
+	/* Enable AUDS */
+	dw_hdmi_qp_mod(hdmi, PKTSCHED_AUDS_TX_EN, PKTSCHED_AUDS_TX_EN, PKTSCHED_PKT_EN);
+
+	return 0;
 }
 
 #ifdef CONFIG_DRM_DW_HDMI_QP_CEC

-- 
2.52.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/5] drm/bridge: dw-hdmi-qp: Provide HDMI Vendor Specific InfoFrame
  2026-01-25  0:22 ` [PATCH 1/5] drm/bridge: dw-hdmi-qp: Provide HDMI Vendor Specific InfoFrame Cristian Ciocaltea
@ 2026-01-28 12:11   ` Daniel Stone
  2026-01-28 12:54     ` Cristian Ciocaltea
  0 siblings, 1 reply; 8+ messages in thread
From: Daniel Stone @ 2026-01-28 12:11 UTC (permalink / raw)
  To: Cristian Ciocaltea
  Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, kernel,
	dri-devel, linux-kernel

Hi Cristian,

On Sun, 25 Jan 2026 at 00:23, Cristian Ciocaltea
<cristian.ciocaltea@collabora.com> wrote:
> +       /* VSI packet body */
> +       for (i = 0; i < len - 3; i += 4)
> +               dw_hdmi_qp_write_pkt(hdmi, buffer + 3, i, min(len - i - 3, 4),
> +                                    PKT_VSI_CONTENTS1 + i);

Given that this for loop occurs in all the users (other than when len
< 4 where it's not required), why not move it into the
dw_hdmi_qp_write_pkt() helper itself, such that the calls for each
infoframe could be dw_hdmi_qp_write_pkt(hdmi, buffer + 3, len,
PKT_VSI_CONTENTS1 /* base reg, incremented by helper */)?

Cheers,
Daniel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/5] drm/bridge: dw-hdmi-qp: Provide HDMI Vendor Specific InfoFrame
  2026-01-28 12:11   ` Daniel Stone
@ 2026-01-28 12:54     ` Cristian Ciocaltea
  0 siblings, 0 replies; 8+ messages in thread
From: Cristian Ciocaltea @ 2026-01-28 12:54 UTC (permalink / raw)
  To: Daniel Stone
  Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, kernel,
	dri-devel, linux-kernel

Hi Daniel,

On 1/28/26 2:11 PM, Daniel Stone wrote:
> Hi Cristian,
> 
> On Sun, 25 Jan 2026 at 00:23, Cristian Ciocaltea
> <cristian.ciocaltea@collabora.com> wrote:
>> +       /* VSI packet body */
>> +       for (i = 0; i < len - 3; i += 4)
>> +               dw_hdmi_qp_write_pkt(hdmi, buffer + 3, i, min(len - i - 3, 4),
>> +                                    PKT_VSI_CONTENTS1 + i);
> 
> Given that this for loop occurs in all the users (other than when len
> < 4 where it's not required), why not move it into the
> dw_hdmi_qp_write_pkt() helper itself, such that the calls for each
> infoframe could be dw_hdmi_qp_write_pkt(hdmi, buffer + 3, len,
> PKT_VSI_CONTENTS1 /* base reg, incremented by helper */)?

Yeah, initially planned to keep the helper simple and allow more flexibility in
the callbacks.  Probably now it makes sense to also write the packet header via
the helper, not just the body, since this is also handled similarly in all
cases.

Thanks,
Cristian

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-01-28 12:55 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-01-25  0:22 [PATCH 0/5] Provide HDMI VSI & SPD InfoFrames to DW HDMI QP TX Cristian Ciocaltea
2026-01-25  0:22 ` [PATCH 1/5] drm/bridge: dw-hdmi-qp: Provide HDMI Vendor Specific InfoFrame Cristian Ciocaltea
2026-01-28 12:11   ` Daniel Stone
2026-01-28 12:54     ` Cristian Ciocaltea
2026-01-25  0:23 ` [PATCH 2/5] drm/bridge: dw-hdmi-qp: Provide SPD InfoFrame Cristian Ciocaltea
2026-01-25  0:23 ` [PATCH 3/5] drm/bridge: dw-hdmi-qp: Rework AVI InfoFrame handler Cristian Ciocaltea
2026-01-25  0:23 ` [PATCH 4/5] drm/bridge: dw-hdmi-qp: Rework DRM " Cristian Ciocaltea
2026-01-25  0:23 ` [PATCH 5/5] drm/bridge: dw-hdmi-qp: Rework Audio " Cristian Ciocaltea

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®